diff --git a/packages/svelteui-core/src/components/Drawer/Drawer.d.ts b/packages/svelteui-core/src/components/Drawer/Drawer.d.ts new file mode 100644 index 000000000..f549195e5 --- /dev/null +++ b/packages/svelteui-core/src/components/Drawer/Drawer.d.ts @@ -0,0 +1,39 @@ +import { HTMLAttributes } from 'svelte/elements'; +import { LiteralUnion, Transition } from '$lib/internal'; +import { DefaultProps, SvelteUINumberSize, SvelteUIShadow, SvelteUISize } from '$lib/styles'; + +export interface DrawerProps extends DefaultProps, HTMLAttributes { + opened: boolean; + title?: any; + zIndex?: number; + overflow?: 'outside' | 'inside'; + withCloseButton?: boolean; + overlay?: boolean; + overlayOpacity?: number; + overlayColor?: string; + overlayBlur?: number; + position?: DrawerPosition; + size?: LiteralUnion; + transition?: Transition; + transitionDuration?: number; + transitionTimingFunction?: string; + closeButtonLabel?: string; + id?: string; + shadow?: SvelteUIShadow; + padding?: SvelteUINumberSize; + closeOnClickOutside?: boolean; + closeOnEscape?: boolean; + trapFocus?: boolean; + centered?: boolean; + target?: HTMLElement | string; + withinPortal?: boolean; + speed?: number; +} + +export interface DrawerEvents { + close: CustomEvent; + [evt: string]: CustomEvent; +} + + +export type DrawerPosition = 'right' | 'left' | 'top' | 'bottom'; \ No newline at end of file diff --git a/packages/svelteui-core/src/components/Drawer/Drawer.stories.svelte b/packages/svelteui-core/src/components/Drawer/Drawer.stories.svelte new file mode 100644 index 000000000..9fc928876 --- /dev/null +++ b/packages/svelteui-core/src/components/Drawer/Drawer.stories.svelte @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Drawer content
+
+
diff --git a/packages/svelteui-core/src/components/Drawer/Drawer.styles.ts b/packages/svelteui-core/src/components/Drawer/Drawer.styles.ts new file mode 100644 index 000000000..b0f2fa44d --- /dev/null +++ b/packages/svelteui-core/src/components/Drawer/Drawer.styles.ts @@ -0,0 +1,78 @@ +import { createStyles } from '$lib/styles'; + +export interface DrawerStylesParams { + overflow: 'outside' | 'inside'; + size: string | number; + speed: number; + zIndex: number; + position: 'right' | 'left' | 'top' | 'bottom'; +} + +export const sizes = { + xs: 320, + sm: 380, + md: 440, + lg: 620, + xl: 780, + full: '100%' +}; + +export default createStyles((theme, { overflow, size, zIndex, position, speed }: DrawerStylesParams) => { + const customSize = size in sizes === false; + const computedSize = typeof size === 'string' && customSize ? size : theme.fn.size({ sizes, size }); + return { + close: {}, + overlay: {}, + root: { + position: 'fixed', + zIndex, + top: 0, + left: 0, + right: 0, + bottom: 0 + }, + + wrapper: { + backgroundColor: 'white', + zIndex: 1111 + }, + title: { + marginRight: +theme.space.md.value, + textOverflow: 'ellipsis', + display: 'block', + wordBreak: 'break-word' + }, + Drawer: { + [`${theme.dark} &`]: { + backgroundColor: theme.fn.themeColor('dark', 7) + }, + position: 'fixed', + top: `${position === 'top' || position === 'left' || position === 'right' ? (position === 'top' ? ('-' + computedSize) : 0) : 'auto'}`, + bottom: `${position === 'bottom' || position === 'left' || position === 'right' ? (position === 'bottom' ? ('-' + computedSize) : 0) : 'auto'} `, + right: `${position === 'right' || position === 'bottom' || position === 'top' ? (position === 'right' ? ('-' + computedSize) : 0) : 'auto'} `, + left: `${position === 'left' || position === 'bottom' || position === 'top' ? (position === 'left' ? ('-' + computedSize) : 0) : 'auto'} `, + width: position === 'left' || position === 'right' ? computedSize : '100vw', + height: position === 'top' || position === 'bottom' ? computedSize : '100vh', + boxShadow: '-6px 0 16px -8px #00000014, -9px 0 28px #0000000d, -12px 0 48px 16px #00000008;', + transition: `${position} ${speed}ms cubic-bezier(.23,1,.32,1),box-shadow ${speed}ms cubic-bezier(.23,1,.32,1)`, + outline: 0, + backgroundColor: 'white', + zIndex: 1 + + }, + + header: { + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + marginBottom: parseInt(theme.space.md.value), + marginRight: -9 + }, + + body: { + maxHeight: overflow === 'inside' ? 'calc(100vh - 185px)' : null, + overflowY: overflow === 'inside' ? 'auto' : null, + wordBreak: 'break-word' + } + }; +}); diff --git a/packages/svelteui-core/src/components/Drawer/Drawer.svelte b/packages/svelteui-core/src/components/Drawer/Drawer.svelte new file mode 100644 index 000000000..ddb8a35ec --- /dev/null +++ b/packages/svelteui-core/src/components/Drawer/Drawer.svelte @@ -0,0 +1,177 @@ + + +{#if showContent} + + +
{ + const shouldTrigger = + castAny(event.target)?.getAttribute('data-svelteui-stop-propagation') !== 'true'; + shouldTrigger && event.code === 'Escape' && closeOnEscape && onClose(); + }} + > + {#if overlay} +
+ closeOnClickOutside && onClose()} + blur={overlayBlur} + color={overlayColor || '#00000073'} + opacity={_overlayOpacity} + /> +
+ {/if} + +
+ +
+ {#if title || withCloseButton} +
+ + {title} + + + {#if withCloseButton} + + {/if} +
+ {/if} +
+ Place some content +
+
+
+
+
+
+
+{/if} diff --git a/packages/svelteui-core/src/components/Drawer/index.ts b/packages/svelteui-core/src/components/Drawer/index.ts new file mode 100644 index 000000000..2be3f033b --- /dev/null +++ b/packages/svelteui-core/src/components/Drawer/index.ts @@ -0,0 +1,3 @@ +export { default as Drawer } from './Drawer.svelte'; +export type { DrawerStylesParams } from './Drawer.styles'; +export type { DrawerProps, DrawerEvents } from './Drawer'; diff --git a/packages/svelteui-core/src/components/index.ts b/packages/svelteui-core/src/components/index.ts index 76eec3122..e811873ef 100644 --- a/packages/svelteui-core/src/components/index.ts +++ b/packages/svelteui-core/src/components/index.ts @@ -15,6 +15,7 @@ export * from './Chip'; export * from './Code'; export * from './Container'; export * from './Divider'; +export * from './Drawer'; export * from './FileUpload'; export * from './Grid'; export * from './Group';