@@ -0,0 +1,100 @@
|
||||
import { Meta, StoryObj } from '@storybook/web-components';
|
||||
|
||||
import { html } from 'lit';
|
||||
|
||||
import './bottom-panel.component';
|
||||
import BottomPanel from './bottom-panel.component';
|
||||
|
||||
export default {
|
||||
title: 'Design System/Atoms/Panels/Bottom',
|
||||
component: 'z-panels.bottom',
|
||||
render: (args) => html`
|
||||
<style>
|
||||
html {
|
||||
background-color: #ccc;
|
||||
}
|
||||
</style>
|
||||
|
||||
<z-panels.bottom ?open=${args.open}>
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Esse laborum pariatur irure in consequat deserunt officia. Eu aliquip ad duis. Voluptate velit fugiat ex Lorem et. Ea laborum ut
|
||||
veniam est ad consequat pariatur.
|
||||
</p>
|
||||
</z-panels.bottom>
|
||||
`,
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
},
|
||||
argTypes: {
|
||||
open: {
|
||||
control: 'boolean',
|
||||
},
|
||||
},
|
||||
args: {
|
||||
open: false,
|
||||
},
|
||||
} satisfies Meta<BottomPanel>;
|
||||
|
||||
type Story = StoryObj<BottomPanel>;
|
||||
|
||||
export const Primary: Story = {};
|
||||
58
libs/panels/bottom-panel/src/lib/bottom-panel.component.ts
Normal file
58
libs/panels/bottom-panel/src/lib/bottom-panel.component.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { DestroyController } from '@z-elements/_internal/controllers';
|
||||
|
||||
import { LitElement, PropertyValues, html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
|
||||
import { filter, fromEvent, takeUntil, tap } from 'rxjs';
|
||||
|
||||
import { hostStyles, panelStyles } from './styles';
|
||||
|
||||
@customElement('z-panels.bottom')
|
||||
export default class BottomPanel extends LitElement {
|
||||
static override get styles() {
|
||||
return [hostStyles, panelStyles];
|
||||
}
|
||||
|
||||
/** Private variables */
|
||||
private readonly _destroyController = new DestroyController(this);
|
||||
|
||||
/** Protected variables */
|
||||
|
||||
/** Public variables */
|
||||
@property({ type: Boolean, reflect: true }) public open = false;
|
||||
|
||||
/** constructor & lifecylce */
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
fromEvent<MouseEvent>(this, 'click')
|
||||
.pipe(
|
||||
filter(() => this.open),
|
||||
filter((event: MouseEvent) => event.target === this),
|
||||
tap(() => (this.open = false)),
|
||||
takeUntil(this._destroyController.destroy),
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
override updated(changedProperties: PropertyValues) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
this.shadowRoot?.querySelector('aside')?.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
/** Public methods */
|
||||
|
||||
/** Protected methods */
|
||||
protected override render(): unknown {
|
||||
return html`
|
||||
<aside>
|
||||
<header><slot name="header"></slot></header>
|
||||
|
||||
<slot></slot>
|
||||
</aside>
|
||||
`;
|
||||
}
|
||||
|
||||
/** Private methods */
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { panelsBottomPanel } from './panels-bottom-panel';
|
||||
|
||||
describe('panelsBottomPanel', () => {
|
||||
it('should work', () => {
|
||||
expect(panelsBottomPanel()).toEqual('panels-bottom-panel');
|
||||
});
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
export function panelsBottomPanel(): string {
|
||||
return 'panels-bottom-panel';
|
||||
}
|
||||
51
libs/panels/bottom-panel/src/lib/styles/index.ts
Normal file
51
libs/panels/bottom-panel/src/lib/styles/index.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export const hostStyles = css`
|
||||
:host {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: ${Number.MAX_SAFE_INTEGER};
|
||||
}
|
||||
|
||||
:host([open]) {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
:host(:not([open])) aside {
|
||||
transform: translateY(100vh);
|
||||
}
|
||||
|
||||
:host([open]) aside {
|
||||
transform: translateY(0);
|
||||
transition-timing-function: ease-in;
|
||||
}
|
||||
|
||||
:host(:not([open])) aside::before {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
:host([open]) aside {
|
||||
opacity: 1;
|
||||
transition-timing-function: ease-in;
|
||||
}
|
||||
`;
|
||||
|
||||
export const panelStyles = css`
|
||||
aside {
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 -3px 6px rgba(0, 0, 0, 0.04);
|
||||
border-radius: 12px 12px 0 0;
|
||||
padding: 2rem 1.5rem;
|
||||
inset-inline: 0;
|
||||
bottom: 0;
|
||||
max-height: 60dvh;
|
||||
pointer-events: auto;
|
||||
transition: transform 0.3s ease-out;
|
||||
overflow: scroll;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
`;
|
||||
Reference in New Issue
Block a user