From 6ecef7adca8d4ef75e158a883151a8055a1c51fc Mon Sep 17 00:00:00 2001 From: jp calvo Date: Fri, 11 Oct 2024 17:48:32 +0800 Subject: [PATCH] feat: new components --- README.md | 4 + docs/alert-dialog.md | 23 ++++ docs/alert.md | 20 ++++ docs/breadcrumbs.md | 34 ++++++ docs/drawer.md | 29 +++++ docs/field.md | 15 ++- packages/ui-ingredients/README.md | 4 + .../lib/accordion/avatar-context.svelte.ts | 2 +- .../src/lib/alert/alert-anatomy.ts | 10 ++ .../src/lib/alert/alert-context.ts | 5 + .../src/lib/alert/alert-description.svelte | 25 +++++ .../src/lib/alert/alert-indicator.svelte | 25 +++++ .../src/lib/alert/alert-root.svelte | 29 +++++ .../src/lib/alert/alert-title.svelte | 25 +++++ .../ui-ingredients/src/lib/alert/alert.ts | 4 + .../src/lib/alert/create-alert.svelte.ts | 44 ++++++++ .../ui-ingredients/src/lib/alert/index.ts | 9 ++ .../lib/breadcrumbs/breadcrumbs-anatomy.ts | 11 ++ .../breadcrumbs/breadcrumbs-context.svelte.ts | 5 + .../lib/breadcrumbs/breadcrumbs-item.svelte | 25 +++++ .../lib/breadcrumbs/breadcrumbs-link.svelte | 33 ++++++ .../lib/breadcrumbs/breadcrumbs-list.svelte | 25 +++++ .../lib/breadcrumbs/breadcrumbs-root.svelte | 29 +++++ .../breadcrumbs/breadcrumbs-separator.svelte | 25 +++++ .../src/lib/breadcrumbs/breadcrumbs.ts | 5 + .../src/lib/breadcrumbs/create-breadcrumbs.ts | 72 +++++++++++++ .../src/lib/breadcrumbs/index.ts | 10 ++ .../color-picker-context.svelte.ts | 8 +- .../lib/combobox/combobox-context.svelte.ts | 4 +- .../date-picker/date-picker-context.svelte.ts | 8 +- .../src/lib/drawer/create-drawer.svelte.ts | 79 ++++++++++++++ .../src/lib/drawer/drawer-anatomy.ts | 9 ++ .../src/lib/drawer/drawer-backdrop.svelte | 45 ++++++++ .../src/lib/drawer/drawer-body.svelte | 30 ++++++ .../lib/drawer/drawer-close-trigger.svelte | 30 ++++++ .../src/lib/drawer/drawer-content.svelte | 37 +++++++ .../src/lib/drawer/drawer-context.svelte.ts | 5 + .../src/lib/drawer/drawer-description.svelte | 30 ++++++ .../src/lib/drawer/drawer-footer.svelte | 30 ++++++ .../src/lib/drawer/drawer-header.svelte | 30 ++++++ .../src/lib/drawer/drawer-positioner.svelte | 36 +++++++ .../src/lib/drawer/drawer-root.svelte | 48 +++++++++ .../src/lib/drawer/drawer-title.svelte | 30 ++++++ .../src/lib/drawer/drawer-trigger.svelte | 30 ++++++ .../ui-ingredients/src/lib/drawer/drawer.ts | 11 ++ .../ui-ingredients/src/lib/drawer/index.ts | 16 +++ .../enviroment-provider-context.svelte.ts | 6 +- .../src/lib/field/create-field.svelte.ts | 27 +++-- .../src/lib/field/field-anatomy.ts | 1 + .../lib/field/field-required-indicator.svelte | 36 +++++++ .../ui-ingredients/src/lib/field/field.ts | 1 + .../ui-ingredients/src/lib/field/index.ts | 1 + .../file-upload/file-upload-context.svelte.ts | 2 +- packages/ui-ingredients/src/lib/index.ts | 3 + .../src/lib/menu/menu-context.svelte.ts | 4 +- .../segment-group-context.svelte.ts | 2 +- .../src/lib/select/select-context.svelte.ts | 4 +- .../src/lib/slider/slider-context.svelte.ts | 2 +- .../src/lib/steps/steps-context.svelte.ts | 2 +- .../tags-input/tags-input-context.svelte.ts | 2 +- .../src/lib/timer/timer-context.svelte.ts | 2 +- .../src/lib/toggle/create-toggle.svelte.ts | 6 +- .../lib/tree-view/tree-view-context.svelte.ts | 6 +- .../src/routes/alert-dialog/+page.svelte | 30 +++--- .../src/routes/alert/+page.svelte | 18 ++++ .../src/routes/breadcrumbs/+page.svelte | 29 +++++ .../src/routes/combobox/+page.svelte | 2 +- .../src/routes/date-picker/+page.svelte | 2 +- .../src/routes/date-picker/range/+page.svelte | 2 +- .../src/routes/dialog/+page.svelte | 100 +++++++++++++----- .../src/routes/drawer/+page.svelte | 91 ++++++++++++++++ .../src/routes/field/+page.svelte | 8 +- .../src/routes/hover-card/+page.svelte | 2 +- .../src/routes/menu/+page.svelte | 4 +- .../src/routes/popover/+page.svelte | 2 +- .../src/routes/segment-group/+page.svelte | 14 ++- .../src/routes/select/+page.svelte | 2 +- .../ui-ingredients/src/routes/sidebar.svelte | 72 +++++++------ .../src/routes/tabs/+page.svelte | 4 +- .../src/routes/tooltip/+page.svelte | 2 +- packages/ui-ingredients/src/routes/utils.ts | 12 +++ .../tests/alert-dialog/alert-dialog.svelte | 15 +++ .../tests/alert-dialog/alert-dialog.test.ts | 21 ++++ .../src/tests/alert/alert.svelte | 9 ++ .../src/tests/alert/alert.test.ts | 18 ++++ .../src/tests/breadcrumbs/breadcrumbs.svelte | 21 ++++ .../src/tests/breadcrumbs/breadcrumbs.test.ts | 21 ++++ .../src/tests/dialog/dialog.svelte | 8 +- .../src/tests/drawer/drawer.svelte | 20 ++++ .../src/tests/drawer/drawer.test.ts | 18 ++++ .../src/tests/field/field.svelte | 6 +- packages/ui-ingredients/tailwind.config.js | 18 ++++ 92 files changed, 1601 insertions(+), 140 deletions(-) create mode 100644 docs/alert-dialog.md create mode 100644 docs/alert.md create mode 100644 docs/breadcrumbs.md create mode 100644 docs/drawer.md create mode 100644 packages/ui-ingredients/src/lib/alert/alert-anatomy.ts create mode 100644 packages/ui-ingredients/src/lib/alert/alert-context.ts create mode 100644 packages/ui-ingredients/src/lib/alert/alert-description.svelte create mode 100644 packages/ui-ingredients/src/lib/alert/alert-indicator.svelte create mode 100644 packages/ui-ingredients/src/lib/alert/alert-root.svelte create mode 100644 packages/ui-ingredients/src/lib/alert/alert-title.svelte create mode 100644 packages/ui-ingredients/src/lib/alert/alert.ts create mode 100644 packages/ui-ingredients/src/lib/alert/create-alert.svelte.ts create mode 100644 packages/ui-ingredients/src/lib/alert/index.ts create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-anatomy.ts create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-context.svelte.ts create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-item.svelte create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-link.svelte create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-list.svelte create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-root.svelte create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-separator.svelte create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs.ts create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/create-breadcrumbs.ts create mode 100644 packages/ui-ingredients/src/lib/breadcrumbs/index.ts create mode 100644 packages/ui-ingredients/src/lib/drawer/create-drawer.svelte.ts create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-anatomy.ts create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-backdrop.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-body.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-close-trigger.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-content.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-context.svelte.ts create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-description.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-footer.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-header.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-positioner.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-root.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-title.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer-trigger.svelte create mode 100644 packages/ui-ingredients/src/lib/drawer/drawer.ts create mode 100644 packages/ui-ingredients/src/lib/drawer/index.ts create mode 100644 packages/ui-ingredients/src/lib/field/field-required-indicator.svelte create mode 100644 packages/ui-ingredients/src/routes/alert/+page.svelte create mode 100644 packages/ui-ingredients/src/routes/breadcrumbs/+page.svelte create mode 100644 packages/ui-ingredients/src/routes/drawer/+page.svelte create mode 100644 packages/ui-ingredients/src/tests/alert-dialog/alert-dialog.svelte create mode 100644 packages/ui-ingredients/src/tests/alert-dialog/alert-dialog.test.ts create mode 100644 packages/ui-ingredients/src/tests/alert/alert.svelte create mode 100644 packages/ui-ingredients/src/tests/alert/alert.test.ts create mode 100644 packages/ui-ingredients/src/tests/breadcrumbs/breadcrumbs.svelte create mode 100644 packages/ui-ingredients/src/tests/breadcrumbs/breadcrumbs.test.ts create mode 100644 packages/ui-ingredients/src/tests/drawer/drawer.svelte create mode 100644 packages/ui-ingredients/src/tests/drawer/drawer.test.ts diff --git a/README.md b/README.md index 75bc55e2..68dcab75 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,10 @@ npm install ui-ingredients ## Documentation - [Accordion](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/accordion.md) +- [Alert](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/alert.md) +- [AlertDialog](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/alert-dialog.md) - [Avatar](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/avatar.md) +- [Breadcrumbs](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/breadcrumbs.md) - [Carousel](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/carousel.md) - [Checkbox](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/checkbox.md) - [Clipboard](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/clipboard.md) @@ -52,6 +55,7 @@ npm install ui-ingredients - [Combobox](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/combobox.md) - [DatePicker](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/date-picker.md) - [Dialog](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/dialog.md) +- [Drawer](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/drawer.md) - [Editable](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/editable.md) - [Field](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/field.md) - [FileUpload](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/file-upload.md) diff --git a/docs/alert-dialog.md b/docs/alert-dialog.md new file mode 100644 index 00000000..097a591c --- /dev/null +++ b/docs/alert-dialog.md @@ -0,0 +1,23 @@ +# AlertDialog + +A component for displaying a modal dialog that requires user attention or confirmation. + +## Usage + +```svelte + + + + Trigger + + + + Title + Description + Close + + + +``` diff --git a/docs/alert.md b/docs/alert.md new file mode 100644 index 00000000..e8ba1ba9 --- /dev/null +++ b/docs/alert.md @@ -0,0 +1,20 @@ +# Alert + +A component for displaying important messages or notifications. + +## Usage + +```svelte + + + + + + + Title + Description + +``` diff --git a/docs/breadcrumbs.md b/docs/breadcrumbs.md new file mode 100644 index 00000000..ccd4e4ce --- /dev/null +++ b/docs/breadcrumbs.md @@ -0,0 +1,34 @@ +# Breadcrumbs + +A component for displaying the navigation path or hierarchy of a user's location within a site. + +## Usage + +```svelte + + + + + + Home + + + + + + Components + + + + + + + Breadcrumbs + + + + +``` diff --git a/docs/drawer.md b/docs/drawer.md new file mode 100644 index 00000000..ae2ddb8a --- /dev/null +++ b/docs/drawer.md @@ -0,0 +1,29 @@ +# Drawer + +A component that slides in from the edge of the screen to display additional content or navigation options. + +## Usage + +```svelte + + + + Trigger + + + + + Title + Description + + Body Content + + Close + + + + +``` diff --git a/docs/field.md b/docs/field.md index 549828f0..feeab3fe 100644 --- a/docs/field.md +++ b/docs/field.md @@ -8,7 +8,10 @@ A component for organizing related form elements into a cohesive unit. ```svelte - Label + + Label + + This is a helper text This is an error text @@ -19,7 +22,10 @@ A component for organizing related form elements into a cohesive unit. ```svelte - Label + + Label + + This is a helper text This is an error text @@ -30,7 +36,10 @@ A component for organizing related form elements into a cohesive unit. ```svelte - Label + + Label + + This is a helper text This is an error text diff --git a/packages/ui-ingredients/README.md b/packages/ui-ingredients/README.md index 75bc55e2..68dcab75 100644 --- a/packages/ui-ingredients/README.md +++ b/packages/ui-ingredients/README.md @@ -43,7 +43,10 @@ npm install ui-ingredients ## Documentation - [Accordion](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/accordion.md) +- [Alert](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/alert.md) +- [AlertDialog](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/alert-dialog.md) - [Avatar](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/avatar.md) +- [Breadcrumbs](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/breadcrumbs.md) - [Carousel](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/carousel.md) - [Checkbox](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/checkbox.md) - [Clipboard](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/clipboard.md) @@ -52,6 +55,7 @@ npm install ui-ingredients - [Combobox](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/combobox.md) - [DatePicker](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/date-picker.md) - [Dialog](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/dialog.md) +- [Drawer](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/drawer.md) - [Editable](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/editable.md) - [Field](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/field.md) - [FileUpload](https://github.com/calvo-jp/ui-ingredients/blob/main/docs/file-upload.md) diff --git a/packages/ui-ingredients/src/lib/accordion/avatar-context.svelte.ts b/packages/ui-ingredients/src/lib/accordion/avatar-context.svelte.ts index b57d763f..f623e0c5 100644 --- a/packages/ui-ingredients/src/lib/accordion/avatar-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/accordion/avatar-context.svelte.ts @@ -6,4 +6,4 @@ export const [getAccordionContext, setAccordionContext] = createContext('Accordion'); export const [getAccordionItemPropsContext, setAccordionItemPropsContext] = - createContext('AccordionItem'); + createContext('AccordionItem [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/alert/alert-anatomy.ts b/packages/ui-ingredients/src/lib/alert/alert-anatomy.ts new file mode 100644 index 00000000..de503a29 --- /dev/null +++ b/packages/ui-ingredients/src/lib/alert/alert-anatomy.ts @@ -0,0 +1,10 @@ +import {createAnatomy} from '@zag-js/anatomy'; + +export const anatomy = createAnatomy('alert').parts( + 'root', + 'title', + 'description', + 'indicator', +); + +export const parts = anatomy.build(); diff --git a/packages/ui-ingredients/src/lib/alert/alert-context.ts b/packages/ui-ingredients/src/lib/alert/alert-context.ts new file mode 100644 index 00000000..b31140ec --- /dev/null +++ b/packages/ui-ingredients/src/lib/alert/alert-context.ts @@ -0,0 +1,5 @@ +import {createContext} from '$lib/create-context.svelte.js'; +import type {CreateAlertReturn} from './create-alert.svelte.js'; + +export const [getAlertContext, setAlertContext] = + createContext('Alert'); diff --git a/packages/ui-ingredients/src/lib/alert/alert-description.svelte b/packages/ui-ingredients/src/lib/alert/alert-description.svelte new file mode 100644 index 00000000..3eb36a94 --- /dev/null +++ b/packages/ui-ingredients/src/lib/alert/alert-description.svelte @@ -0,0 +1,25 @@ + + + + +{#if asChild} + {@render asChild(attrs)} +{:else} +

+ {@render children?.()} +

+{/if} diff --git a/packages/ui-ingredients/src/lib/alert/alert-indicator.svelte b/packages/ui-ingredients/src/lib/alert/alert-indicator.svelte new file mode 100644 index 00000000..e1461f70 --- /dev/null +++ b/packages/ui-ingredients/src/lib/alert/alert-indicator.svelte @@ -0,0 +1,25 @@ + + + + +{#if asChild} + {@render asChild(attrs)} +{:else} + + {@render children?.()} + +{/if} diff --git a/packages/ui-ingredients/src/lib/alert/alert-root.svelte b/packages/ui-ingredients/src/lib/alert/alert-root.svelte new file mode 100644 index 00000000..08648a97 --- /dev/null +++ b/packages/ui-ingredients/src/lib/alert/alert-root.svelte @@ -0,0 +1,29 @@ + + + + +{#if asChild} + {@render asChild(attrs, alert)} +{:else} +
+ {@render children?.(alert)} +
+{/if} diff --git a/packages/ui-ingredients/src/lib/alert/alert-title.svelte b/packages/ui-ingredients/src/lib/alert/alert-title.svelte new file mode 100644 index 00000000..3c3ba3dd --- /dev/null +++ b/packages/ui-ingredients/src/lib/alert/alert-title.svelte @@ -0,0 +1,25 @@ + + + + +{#if asChild} + {@render asChild(attrs)} +{:else} +

+ {@render children?.()} +

+{/if} diff --git a/packages/ui-ingredients/src/lib/alert/alert.ts b/packages/ui-ingredients/src/lib/alert/alert.ts new file mode 100644 index 00000000..6561751d --- /dev/null +++ b/packages/ui-ingredients/src/lib/alert/alert.ts @@ -0,0 +1,4 @@ +export {default as Description} from './alert-description.svelte'; +export {default as Indicator} from './alert-indicator.svelte'; +export {default as Root} from './alert-root.svelte'; +export {default as Title} from './alert-title.svelte'; diff --git a/packages/ui-ingredients/src/lib/alert/create-alert.svelte.ts b/packages/ui-ingredients/src/lib/alert/create-alert.svelte.ts new file mode 100644 index 00000000..cc84432b --- /dev/null +++ b/packages/ui-ingredients/src/lib/alert/create-alert.svelte.ts @@ -0,0 +1,44 @@ +import type {HTMLAttributes} from 'svelte/elements'; +import {parts} from './alert-anatomy.js'; + +export interface CreateAlertReturn { + getRootProps(): HTMLAttributes; + getTitleProps(): HTMLAttributes; + getDescriptionProps(): HTMLAttributes; + getIndicatorProps(): HTMLAttributes; +} + +export function createAlert(): CreateAlertReturn { + function getRootProps(): HTMLAttributes { + return { + role: 'alert', + ...parts.root.attrs, + }; + } + + function getTitleProps(): HTMLAttributes { + return { + ...parts.title.attrs, + }; + } + + function getDescriptionProps(): HTMLAttributes { + return { + ...parts.description.attrs, + }; + } + + function getIndicatorProps(): HTMLAttributes { + return { + 'aria-hidden': true, + ...parts.indicator.attrs, + }; + } + + return { + getRootProps, + getTitleProps, + getDescriptionProps, + getIndicatorProps, + }; +} diff --git a/packages/ui-ingredients/src/lib/alert/index.ts b/packages/ui-ingredients/src/lib/alert/index.ts new file mode 100644 index 00000000..1a9f4b2e --- /dev/null +++ b/packages/ui-ingredients/src/lib/alert/index.ts @@ -0,0 +1,9 @@ +export * as Alert from './alert.js'; + +export type {AlertDescriptionProps} from './alert-description.svelte'; +export type {AlertIndicatorProps} from './alert-indicator.svelte'; +export type {AlertProps} from './alert-root.svelte'; +export type {AlertTitleProps} from './alert-title.svelte'; + +export {anatomy as alertAnatomy} from './alert-anatomy.js'; +export {getAlertContext} from './alert-context.js'; diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-anatomy.ts b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-anatomy.ts new file mode 100644 index 00000000..c634d8c4 --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-anatomy.ts @@ -0,0 +1,11 @@ +import {createAnatomy} from '@zag-js/anatomy'; + +export const anatomy = createAnatomy('breadcrumbs').parts( + 'root', + 'list', + 'item', + 'link', + 'separator', +); + +export const parts = anatomy.build(); diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-context.svelte.ts b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-context.svelte.ts new file mode 100644 index 00000000..8ce4f8b4 --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-context.svelte.ts @@ -0,0 +1,5 @@ +import {createContext} from '$lib/create-context.svelte.js'; +import type {CreateBreadcrumbsReturn} from './create-breadcrumbs.js'; + +export const [getBreadcrumbsContext, setBreadcrumbsContext] = + createContext('Breadcrumbs'); diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-item.svelte b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-item.svelte new file mode 100644 index 00000000..1ddfe127 --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-item.svelte @@ -0,0 +1,25 @@ + + + + +{#if asChild} + {@render asChild(attrs)} +{:else} +
  • + {@render children?.()} +
  • +{/if} diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-link.svelte b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-link.svelte new file mode 100644 index 00000000..30148bea --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-link.svelte @@ -0,0 +1,33 @@ + + + + +{#if asChild} + {@render asChild(attrs)} +{:else} + + {@render children?.()} + +{/if} diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-list.svelte b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-list.svelte new file mode 100644 index 00000000..453afbf5 --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-list.svelte @@ -0,0 +1,25 @@ + + + + +{#if asChild} + {@render asChild(attrs)} +{:else} +
      + {@render children?.()} +
    +{/if} diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-root.svelte b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-root.svelte new file mode 100644 index 00000000..1bab337d --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-root.svelte @@ -0,0 +1,29 @@ + + + + +{#if asChild} + {@render asChild(attrs, breadcrumbs)} +{:else} + +{/if} diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-separator.svelte b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-separator.svelte new file mode 100644 index 00000000..cbd57da5 --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs-separator.svelte @@ -0,0 +1,25 @@ + + + + +{#if asChild} + {@render asChild(attrs)} +{:else} + + {@render children?.()} + +{/if} diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs.ts b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs.ts new file mode 100644 index 00000000..13730ec5 --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/breadcrumbs.ts @@ -0,0 +1,5 @@ +export {default as Item} from './breadcrumbs-item.svelte'; +export {default as Link} from './breadcrumbs-link.svelte'; +export {default as List} from './breadcrumbs-list.svelte'; +export {default as Root} from './breadcrumbs-root.svelte'; +export {default as Separator} from './breadcrumbs-separator.svelte'; diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/create-breadcrumbs.ts b/packages/ui-ingredients/src/lib/breadcrumbs/create-breadcrumbs.ts new file mode 100644 index 00000000..9f06dd6e --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/create-breadcrumbs.ts @@ -0,0 +1,72 @@ +import {ariaAttr, dataAttr} from '@zag-js/dom-query'; +import type { + HTMLAnchorAttributes, + HTMLAttributes, + HTMLLiAttributes, + HTMLOlAttributes, +} from 'svelte/elements'; +import {parts} from './breadcrumbs-anatomy.js'; + +export interface LinkProps { + href: string; + current?: boolean; +} + +export interface CreateBreadcrumbsReturn { + getRootProps(): HTMLAttributes; + getListProps(): HTMLOlAttributes; + getItemProps(): HTMLLiAttributes; + getLinkProps(props: LinkProps): HTMLAnchorAttributes; + getSeparatorProps(): HTMLAttributes; +} + +export function createBreadcrumbs(): CreateBreadcrumbsReturn { + function getRootProps(): HTMLAttributes { + return { + role: 'navigation', + 'aria-label': 'Breadcrumb', + ...parts.root.attrs, + }; + } + + function getListProps(): HTMLOlAttributes { + return { + role: 'list', + ...parts.list.attrs, + }; + } + + function getItemProps(): HTMLLiAttributes { + return { + role: 'listitem', + ...parts.item.attrs, + }; + } + + function getLinkProps(props: LinkProps): HTMLAnchorAttributes { + return { + role: 'link', + href: props.current ? undefined : props.href, + 'aria-current': props.current ? 'page' : undefined, + 'data-current': dataAttr(props.current), + 'aria-disabled': ariaAttr(props.current), + 'data-disabled': dataAttr(props.current), + ...parts.link.attrs, + }; + } + + function getSeparatorProps(): HTMLAttributes { + return { + 'aria-hidden': true, + ...parts.separator.attrs, + }; + } + + return { + getRootProps, + getListProps, + getItemProps, + getLinkProps, + getSeparatorProps, + }; +} diff --git a/packages/ui-ingredients/src/lib/breadcrumbs/index.ts b/packages/ui-ingredients/src/lib/breadcrumbs/index.ts new file mode 100644 index 00000000..d8ef5aa8 --- /dev/null +++ b/packages/ui-ingredients/src/lib/breadcrumbs/index.ts @@ -0,0 +1,10 @@ +export * as Breadcrumbs from './breadcrumbs.js'; + +export type {BreadcrumbsItemProps} from './breadcrumbs-item.svelte'; +export type {BreadcrumbsLinkProps} from './breadcrumbs-link.svelte'; +export type {BreadcrumbsListProps} from './breadcrumbs-list.svelte'; +export type {BreadcrumbsProps} from './breadcrumbs-root.svelte'; +export type {BreadcrumbsSeparatorProps} from './breadcrumbs-separator.svelte'; + +export {anatomy as breadcrumbsAnatomy} from './breadcrumbs-anatomy.js'; +export {getBreadcrumbsContext as getBreadcrumbContext} from './breadcrumbs-context.svelte.js'; diff --git a/packages/ui-ingredients/src/lib/color-picker/color-picker-context.svelte.ts b/packages/ui-ingredients/src/lib/color-picker/color-picker-context.svelte.ts index 90ad6fe1..47616e64 100644 --- a/packages/ui-ingredients/src/lib/color-picker/color-picker-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/color-picker/color-picker-context.svelte.ts @@ -11,19 +11,19 @@ export const [getColorPickerContext, setColorPickerContext] = createContext('ColorPicker'); export const [getColorPickerAreaPropsContext, setColorPickerAreaPropsContext] = - createContext('ColorPickerArea'); + createContext('ColorPickerArea [PROPS]'); export const [ getColorPickerSwatchPropsContext, setColorPickerSwatchPropsContext, -] = createContext('ColorPickerSwatch'); +] = createContext('ColorPickerSwatch [PROPS]'); export const [ getColorPickerFormatPropsContext, setColorPickerFormatPropsContext, -] = createContext<{format: ColorFormat}>('ColorPicker__format', false); +] = createContext<{format: ColorFormat}>('ColorPickerFormat [PROPS]', false); export const [ getColorPickerChannelPropsContext, setColorPickerChannelPropsContext, -] = createContext('ColorPickerChannel'); +] = createContext('ColorPickerChannel [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/combobox/combobox-context.svelte.ts b/packages/ui-ingredients/src/lib/combobox/combobox-context.svelte.ts index 235547b2..50aaf8ca 100644 --- a/packages/ui-ingredients/src/lib/combobox/combobox-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/combobox/combobox-context.svelte.ts @@ -6,9 +6,9 @@ export const [getComboboxContext, setComboboxContext] = createContext('Combobox'); export const [getComboboxItemPropsContext, setComboboxItemPropsContext] = - createContext('ComboboxItem'); + createContext('ComboboxItem [PROPS]'); export const [ getComboboxItemGroupPropsContext, setComboboxItemGroupPropsContext, -] = createContext('ComboboxItemGroup'); +] = createContext('ComboboxItemGroup [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/date-picker/date-picker-context.svelte.ts b/packages/ui-ingredients/src/lib/date-picker/date-picker-context.svelte.ts index e48dfedf..66059034 100644 --- a/packages/ui-ingredients/src/lib/date-picker/date-picker-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/date-picker/date-picker-context.svelte.ts @@ -11,17 +11,17 @@ export const [getDatePickerContext, setDatePickerContext] = createContext('DatePicker'); export const [getDatePickerViewPropsContext, setDatePickerViewPropsContext] = - createContext('DatePickerView'); + createContext('DatePickerView [PROPS]'); export const [getDatePickerTablePropsContext, setDatePickerTablePropsContext] = - createContext('DatePickerTable'); + createContext('DatePickerTable [PROPS]'); export const [ getDatePickerTableCellPropsContext, setDatePickerTableCellPropsContext, -] = createContext('DatePickerTableCell'); +] = createContext('DatePickerTableCell [PROPS]'); export const [ getDatePickerDayTableCellPropsContext, setDatePickerDayTableCellPropsContext, -] = createContext('DatePickerDayTableCell'); +] = createContext('DatePickerDayTableCell [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/drawer/create-drawer.svelte.ts b/packages/ui-ingredients/src/lib/drawer/create-drawer.svelte.ts new file mode 100644 index 00000000..a025a286 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/create-drawer.svelte.ts @@ -0,0 +1,79 @@ +import {getEnvironmentContext} from '$lib/environment-provider/enviroment-provider-context.svelte.js'; +import {getLocaleContext} from '$lib/locale-provider/local-provider-context.svelte.js'; +import {mergeProps} from '$lib/merge-props.js'; +import * as dialog from '@zag-js/dialog'; +import {normalizeProps, reflect, useMachine} from '@zag-js/svelte'; +import type {HTMLAttributes} from 'svelte/elements'; +import {uid} from 'uid'; +import {parts} from './drawer-anatomy.js'; + +export interface CreateDrawerProps + extends Omit< + dialog.Context, + 'id' | 'dir' | 'role' | 'getRootNode' | 'open.controlled' + > { + id?: string; + openControlled?: boolean; +} + +export interface CreateDrawerReturn extends dialog.Api { + getBodyProps(): HTMLAttributes; + getFooterProps(): HTMLAttributes; + getHeaderProps(): HTMLAttributes; +} + +export function createDrawer(props: CreateDrawerProps): CreateDrawerReturn { + const locale = getLocaleContext(); + const environment = getEnvironmentContext(); + + const id = uid(); + + const context: dialog.Context = reflect(() => ({ + id, + dir: locale?.dir, + role: 'dialog', + ...props, + getRootNode: environment?.getRootNode, + 'open.controlled': props.openControlled, + })); + + const [state, send] = useMachine(dialog.machine(context), {context}); + + return reflect(() => { + const o = dialog.connect(state, send, normalizeProps); + + return { + ...o, + getBackdropProps() { + return mergeProps(o.getBackdropProps(), parts.backdrop.attrs); + }, + getCloseTriggerProps() { + return mergeProps(o.getCloseTriggerProps(), parts.closeTrigger.attrs); + }, + getContentProps() { + return mergeProps(o.getContentProps(), parts.content.attrs); + }, + getDescriptionProps() { + return mergeProps(o.getDescriptionProps(), parts.description.attrs); + }, + getPositionerProps() { + return mergeProps(o.getPositionerProps(), parts.positioner.attrs); + }, + getTitleProps() { + return mergeProps(o.getTitleProps(), parts.title.attrs); + }, + getTriggerProps() { + return mergeProps(o.getTriggerProps(), parts.trigger.attrs); + }, + getBodyProps() { + return {...parts.body.attrs}; + }, + getFooterProps() { + return {...parts.footer.attrs}; + }, + getHeaderProps() { + return {...parts.header.attrs}; + }, + }; + }); +} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-anatomy.ts b/packages/ui-ingredients/src/lib/drawer/drawer-anatomy.ts new file mode 100644 index 00000000..81a4d495 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-anatomy.ts @@ -0,0 +1,9 @@ +import {anatomy as _} from '@zag-js/dialog'; + +export const anatomy = _.rename('drawer').extendWith( + 'body', + 'footer', + 'header', +); + +export const parts = anatomy.build(); diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-backdrop.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-backdrop.svelte new file mode 100644 index 00000000..b475b9d9 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-backdrop.svelte @@ -0,0 +1,45 @@ + + + + +{#if presence.mounted} + {#if asChild} + {@render asChild(presence.setReference, mergedProps)} + {:else} +
    + {@render children?.()} +
    + {/if} +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-body.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-body.svelte new file mode 100644 index 00000000..f883e79a --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-body.svelte @@ -0,0 +1,30 @@ + + + + +{#if asChild} + {@render asChild(mergedProps)} +{:else} +
    + {@render children?.()} +
    +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-close-trigger.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-close-trigger.svelte new file mode 100644 index 00000000..03527251 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-close-trigger.svelte @@ -0,0 +1,30 @@ + + + + +{#if asChild} + {@render asChild(mergedProps)} +{:else} + +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-content.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-content.svelte new file mode 100644 index 00000000..d666aae3 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-content.svelte @@ -0,0 +1,37 @@ + + + + +{#if presence.mounted} + {#if asChild} + {@render asChild(presence.setReference, mergedProps)} + {:else} +
    + {@render children?.()} +
    + {/if} +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-context.svelte.ts b/packages/ui-ingredients/src/lib/drawer/drawer-context.svelte.ts new file mode 100644 index 00000000..e861d909 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-context.svelte.ts @@ -0,0 +1,5 @@ +import {createContext} from '$lib/create-context.svelte.js'; +import type {CreateDrawerReturn} from './create-drawer.svelte.js'; + +export const [getDrawerContext, setDrawerContext] = + createContext('Drawer'); diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-description.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-description.svelte new file mode 100644 index 00000000..3582cd20 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-description.svelte @@ -0,0 +1,30 @@ + + + + +{#if asChild} + {@render asChild(mergedProps)} +{:else} +

    + {@render children?.()} +

    +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-footer.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-footer.svelte new file mode 100644 index 00000000..a89ff6ba --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-footer.svelte @@ -0,0 +1,30 @@ + + + + +{#if asChild} + {@render asChild(mergedProps)} +{:else} +
    + {@render children?.()} +
    +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-header.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-header.svelte new file mode 100644 index 00000000..f01d51ba --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-header.svelte @@ -0,0 +1,30 @@ + + + + +{#if asChild} + {@render asChild(mergedProps)} +{:else} +
    + {@render children?.()} +
    +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-positioner.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-positioner.svelte new file mode 100644 index 00000000..a28a1ac7 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-positioner.svelte @@ -0,0 +1,36 @@ + + + + +{#if presence.mounted} + {#if asChild} + {@render asChild(mergedProps)} + {:else} +
    + {@render children?.()} +
    + {/if} +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-root.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-root.svelte new file mode 100644 index 00000000..e3886caa --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-root.svelte @@ -0,0 +1,48 @@ + + + + +{@render children?.(drawer)} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-title.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-title.svelte new file mode 100644 index 00000000..1131d4bf --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-title.svelte @@ -0,0 +1,30 @@ + + + + +{#if asChild} + {@render asChild(mergedProps)} +{:else} +

    + {@render children?.()} +

    +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer-trigger.svelte b/packages/ui-ingredients/src/lib/drawer/drawer-trigger.svelte new file mode 100644 index 00000000..f63713ec --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer-trigger.svelte @@ -0,0 +1,30 @@ + + + + +{#if asChild} + {@render asChild(mergedProps)} +{:else} + +{/if} diff --git a/packages/ui-ingredients/src/lib/drawer/drawer.ts b/packages/ui-ingredients/src/lib/drawer/drawer.ts new file mode 100644 index 00000000..7b6ba876 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/drawer.ts @@ -0,0 +1,11 @@ +export {default as Backdrop} from './drawer-backdrop.svelte'; +export {default as Body} from './drawer-body.svelte'; +export {default as CloseTrigger} from './drawer-close-trigger.svelte'; +export {default as Content} from './drawer-content.svelte'; +export {default as Description} from './drawer-description.svelte'; +export {default as Footer} from './drawer-footer.svelte'; +export {default as Header} from './drawer-header.svelte'; +export {default as Positioner} from './drawer-positioner.svelte'; +export {default as Root} from './drawer-root.svelte'; +export {default as Title} from './drawer-title.svelte'; +export {default as Trigger} from './drawer-trigger.svelte'; diff --git a/packages/ui-ingredients/src/lib/drawer/index.ts b/packages/ui-ingredients/src/lib/drawer/index.ts new file mode 100644 index 00000000..a2113155 --- /dev/null +++ b/packages/ui-ingredients/src/lib/drawer/index.ts @@ -0,0 +1,16 @@ +export * as Drawer from './drawer.js'; + +export type {DrawerBackdropProps} from './drawer-backdrop.svelte'; +export type {DrawerBodyProps} from './drawer-body.svelte'; +export type {DrawerCloseTriggerProps} from './drawer-close-trigger.svelte'; +export type {DrawerContentProps} from './drawer-content.svelte'; +export type {DrawerDescriptionProps} from './drawer-description.svelte'; +export type {DrawerFooterProps} from './drawer-footer.svelte'; +export type {DrawerHeaderProps} from './drawer-header.svelte'; +export type {DrawerPositionerProps} from './drawer-positioner.svelte'; +export type {DrawerProps} from './drawer-root.svelte'; +export type {DrawerTitleProps} from './drawer-title.svelte'; +export type {DrawerTriggerProps} from './drawer-trigger.svelte'; + +export {anatomy as drawerAnatomy} from './drawer-anatomy.js'; +export {getDrawerContext} from './drawer-context.svelte.js'; diff --git a/packages/ui-ingredients/src/lib/environment-provider/enviroment-provider-context.svelte.ts b/packages/ui-ingredients/src/lib/environment-provider/enviroment-provider-context.svelte.ts index 4e823946..72d0efa0 100644 --- a/packages/ui-ingredients/src/lib/environment-provider/enviroment-provider-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/environment-provider/enviroment-provider-context.svelte.ts @@ -1,9 +1,9 @@ import {createContext} from '$lib/create-context.svelte.js'; export interface Environment { - getRootNode: () => ShadowRoot | Document | Node; - getDocument: () => Document; - getWindow: () => Window & typeof globalThis; + getRootNode(): ShadowRoot | Document | Node; + getDocument(): Document; + getWindow(): Window & typeof globalThis; } export const [getEnvironmentContext, setEnvironmentContext] = diff --git a/packages/ui-ingredients/src/lib/field/create-field.svelte.ts b/packages/ui-ingredients/src/lib/field/create-field.svelte.ts index a7749548..8c637042 100644 --- a/packages/ui-ingredients/src/lib/field/create-field.svelte.ts +++ b/packages/ui-ingredients/src/lib/field/create-field.svelte.ts @@ -35,13 +35,14 @@ export interface CreateFieldReturn { readOnly: boolean; invalid: boolean; 'aria-describedby': string; - getRootProps: () => HTMLAttributes; - getLabelProps: () => HTMLLabelAttributes; - getErrorTextProps: () => HTMLAttributes; - getHelperTextProps: () => HTMLAttributes; - getInputProps: () => HTMLInputAttributes; - getSelectProps: () => HTMLSelectAttributes; - getTextareaProps: () => HTMLTextareaAttributes; + getRootProps(): HTMLAttributes; + getLabelProps(): HTMLLabelAttributes; + getErrorTextProps(): HTMLAttributes; + getHelperTextProps(): HTMLAttributes; + getInputProps(): HTMLInputAttributes; + getSelectProps(): HTMLSelectAttributes; + getTextareaProps(): HTMLTextareaAttributes; + getRequiredIndicatorProps(): HTMLAttributes; } export function createField(props: CreateFieldProps): CreateFieldReturn { @@ -207,6 +208,17 @@ export function createField(props: CreateFieldProps): CreateFieldReturn { }; } + function getRequiredIndicatorProps(): HTMLAttributes { + return { + ...parts.requiredIndicator.attrs, + hidden: !required, + 'aria-hidden': true, + 'data-invalid': dataAttr(invalid), + 'data-disabled': dataAttr(disabled), + 'data-readonly': dataAttr(readOnly), + }; + } + return reflect(() => ({ ids, disabled, @@ -221,5 +233,6 @@ export function createField(props: CreateFieldProps): CreateFieldReturn { getInputProps, getSelectProps, getTextareaProps, + getRequiredIndicatorProps, })); } diff --git a/packages/ui-ingredients/src/lib/field/field-anatomy.ts b/packages/ui-ingredients/src/lib/field/field-anatomy.ts index e5d890d5..0c73a8f8 100644 --- a/packages/ui-ingredients/src/lib/field/field-anatomy.ts +++ b/packages/ui-ingredients/src/lib/field/field-anatomy.ts @@ -8,6 +8,7 @@ export const anatomy = createAnatomy('field').parts( 'textarea', 'errorText', 'helperText', + 'requiredIndicator', ); export const parts = anatomy.build(); diff --git a/packages/ui-ingredients/src/lib/field/field-required-indicator.svelte b/packages/ui-ingredients/src/lib/field/field-required-indicator.svelte new file mode 100644 index 00000000..599cb43e --- /dev/null +++ b/packages/ui-ingredients/src/lib/field/field-required-indicator.svelte @@ -0,0 +1,36 @@ + + + + +{#if asChild} + {@render asChild(mergedProps)} +{:else} + + {#if children} + {@render children?.()} + {:else} + * + {/if} + +{/if} diff --git a/packages/ui-ingredients/src/lib/field/field.ts b/packages/ui-ingredients/src/lib/field/field.ts index 39d505be..9a3645e3 100644 --- a/packages/ui-ingredients/src/lib/field/field.ts +++ b/packages/ui-ingredients/src/lib/field/field.ts @@ -2,6 +2,7 @@ export {default as ErrorText} from './field-error-text.svelte'; export {default as HelperText} from './field-helper-text.svelte'; export {default as Input} from './field-input.svelte'; export {default as Label} from './field-label.svelte'; +export {default as RequiredIndicator} from './field-required-indicator.svelte'; export {default as Root} from './field-root.svelte'; export {default as Select} from './field-select.svelte'; export {default as Textarea} from './field-textarea.svelte'; diff --git a/packages/ui-ingredients/src/lib/field/index.ts b/packages/ui-ingredients/src/lib/field/index.ts index 935b1e90..719266a4 100644 --- a/packages/ui-ingredients/src/lib/field/index.ts +++ b/packages/ui-ingredients/src/lib/field/index.ts @@ -4,6 +4,7 @@ export type {FieldErrorTextProps} from './field-error-text.svelte'; export type {FieldHelperTextProps} from './field-helper-text.svelte'; export type {FieldInputProps} from './field-input.svelte'; export type {FieldLabelProps} from './field-label.svelte'; +export type {FieldRequiredIndicatorProps} from './field-required-indicator.svelte'; export type {FieldProps} from './field-root.svelte'; export type {FieldSelectProps} from './field-select.svelte'; export type {FieldTextareaProps} from './field-textarea.svelte'; diff --git a/packages/ui-ingredients/src/lib/file-upload/file-upload-context.svelte.ts b/packages/ui-ingredients/src/lib/file-upload/file-upload-context.svelte.ts index 4edd9dd8..7871519b 100644 --- a/packages/ui-ingredients/src/lib/file-upload/file-upload-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/file-upload/file-upload-context.svelte.ts @@ -6,4 +6,4 @@ export const [getFileUploadContext, setFileUploadContext] = createContext('FileUpload'); export const [getFileUploadItemPropsContext, setFileUploadItemPropsContext] = - createContext('FileUploadItem'); + createContext('FileUploadItem [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/index.ts b/packages/ui-ingredients/src/lib/index.ts index 5443c0f3..34ae8d39 100644 --- a/packages/ui-ingredients/src/lib/index.ts +++ b/packages/ui-ingredients/src/lib/index.ts @@ -1,6 +1,8 @@ export * from './accordion/index.js'; export * from './alert-dialog/index.js'; +export * from './alert/index.js'; export * from './avatar/index.js'; +export * from './breadcrumbs/index.js'; export * from './carousel/index.js'; export * from './checkbox/index.js'; export * from './clipboard/index.js'; @@ -9,6 +11,7 @@ export * from './color-picker/index.js'; export * from './combobox/index.js'; export * from './date-picker/index.js'; export * from './dialog/index.js'; +export * from './drawer/index.js'; export * from './editable/index.js'; export * from './environment-provider/index.js'; export * from './field/index.js'; diff --git a/packages/ui-ingredients/src/lib/menu/menu-context.svelte.ts b/packages/ui-ingredients/src/lib/menu/menu-context.svelte.ts index 310a0828..7cb7b25a 100644 --- a/packages/ui-ingredients/src/lib/menu/menu-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/menu/menu-context.svelte.ts @@ -9,10 +9,10 @@ export const [getMenuContext, setMenuContext] = createContext( ); export const [getMenuItemGroupPropsContext, setMenuItemGroupPropsContext] = - createContext('MenuItemGroup'); + createContext('MenuItemGroup [PROPS]'); export const [getMenuOptionItemPropsContext, setMenuOptionItemPropsContext] = - createContext('MenuOptionItem'); + createContext('MenuOptionItem [PROPS]'); export const [getMenuTriggerItemContext, setMenuTriggerItemContext] = createContext('MenuTriggerItem'); diff --git a/packages/ui-ingredients/src/lib/segment-group/segment-group-context.svelte.ts b/packages/ui-ingredients/src/lib/segment-group/segment-group-context.svelte.ts index d5ae0346..02368b0a 100644 --- a/packages/ui-ingredients/src/lib/segment-group/segment-group-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/segment-group/segment-group-context.svelte.ts @@ -8,4 +8,4 @@ export const [getSegmentGroupContext, setSegmentGroupContext] = export const [ getSegmentGroupItemPropsContext, setSegmentGroupItemPropsContext, -] = createContext('SegmentGroupItem'); +] = createContext('SegmentGroupItem [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/select/select-context.svelte.ts b/packages/ui-ingredients/src/lib/select/select-context.svelte.ts index 92e66b90..4ce9c018 100644 --- a/packages/ui-ingredients/src/lib/select/select-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/select/select-context.svelte.ts @@ -6,7 +6,7 @@ export const [getSelectContext, setSelectContext] = createContext('Select'); export const [getSelectItemPropsContext, setSelectItemPropsContext] = - createContext('SelectItem'); + createContext('SelectItem [PROPS]'); export const [getSelectItemGroupPropsContext, setSelectItemGroupPropsContext] = - createContext('SelectItemGroup'); + createContext('SelectItemGroup [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/slider/slider-context.svelte.ts b/packages/ui-ingredients/src/lib/slider/slider-context.svelte.ts index 0cb46b9e..0bc88378 100644 --- a/packages/ui-ingredients/src/lib/slider/slider-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/slider/slider-context.svelte.ts @@ -6,4 +6,4 @@ export const [getSliderContext, setSliderContext] = createContext('Slider'); export const [getSliderThumbPropsContext, setSliderThumbPropsContext] = - createContext('SliderThumb'); + createContext('SliderThumb [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/steps/steps-context.svelte.ts b/packages/ui-ingredients/src/lib/steps/steps-context.svelte.ts index 27689c69..3611067a 100644 --- a/packages/ui-ingredients/src/lib/steps/steps-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/steps/steps-context.svelte.ts @@ -6,4 +6,4 @@ export const [getStepsContext, setStepsContext] = createContext('Steps'); export const [getStepsItemPropsContext, setStepsItemPropsContext] = - createContext('StepsItem'); + createContext('StepsItem [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/tags-input/tags-input-context.svelte.ts b/packages/ui-ingredients/src/lib/tags-input/tags-input-context.svelte.ts index 2f3743bf..03f6d149 100644 --- a/packages/ui-ingredients/src/lib/tags-input/tags-input-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/tags-input/tags-input-context.svelte.ts @@ -6,4 +6,4 @@ export const [getTagsInputContext, setTagsInputContext] = createContext('TagsInput'); export const [getTagsInputItemPropsContext, setTagsInputItemPropsContext] = - createContext('TagsInputItem'); + createContext('TagsInputItem [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/timer/timer-context.svelte.ts b/packages/ui-ingredients/src/lib/timer/timer-context.svelte.ts index a0fe681b..59dfdd0b 100644 --- a/packages/ui-ingredients/src/lib/timer/timer-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/timer/timer-context.svelte.ts @@ -6,4 +6,4 @@ export const [getTimerContext, setTimerContext] = createContext('Timer'); export const [getTimerItemPropsContext, setTimerItemPropsContext] = - createContext('TimerItem'); + createContext('TimerItem [PROPS]'); diff --git a/packages/ui-ingredients/src/lib/toggle/create-toggle.svelte.ts b/packages/ui-ingredients/src/lib/toggle/create-toggle.svelte.ts index c7b0c688..cd2d07fc 100644 --- a/packages/ui-ingredients/src/lib/toggle/create-toggle.svelte.ts +++ b/packages/ui-ingredients/src/lib/toggle/create-toggle.svelte.ts @@ -16,7 +16,7 @@ export interface CreateToggleProps { export interface CreateToggleReturn { pressed: boolean; setPressed: (pressed: boolean) => void; - getRootProps: () => HTMLButtonAttributes; + getRootProps(): HTMLButtonAttributes; } export function createToggle(props: CreateToggleProps) { @@ -42,6 +42,10 @@ export function createToggle(props: CreateToggleProps) { }; } + $effect(() => { + pressed = props.pressed ?? false; + }); + return reflect(() => ({ pressed, setPressed, diff --git a/packages/ui-ingredients/src/lib/tree-view/tree-view-context.svelte.ts b/packages/ui-ingredients/src/lib/tree-view/tree-view-context.svelte.ts index effb1b91..24bd4c60 100644 --- a/packages/ui-ingredients/src/lib/tree-view/tree-view-context.svelte.ts +++ b/packages/ui-ingredients/src/lib/tree-view/tree-view-context.svelte.ts @@ -6,10 +6,10 @@ export const [getTreeViewContext, setTreeViewContext] = createContext('TreeView'); export const [getTreeViewItemPropsContext, setTreeViewItemPropsContext] = - createContext('TreeViewItem'); + createContext('TreeViewItem [PROPS]'); export const [getTreeViewBranchPropsContext, setTreeViewBranchPropsContext] = - createContext('TreeViewBranch'); + createContext('TreeViewBranch [PROPS]'); export const [getTreeViewTreePropsContext, setTreeViewTreePropsContext] = - createContext<{depth: number}>('TreeViewTree'); + createContext<{depth: number}>('TreeViewTree [PROPS]'); diff --git a/packages/ui-ingredients/src/routes/alert-dialog/+page.svelte b/packages/ui-ingredients/src/routes/alert-dialog/+page.svelte index b1f985f4..3495c5ba 100644 --- a/packages/ui-ingredients/src/routes/alert-dialog/+page.svelte +++ b/packages/ui-ingredients/src/routes/alert-dialog/+page.svelte @@ -19,19 +19,19 @@ {/snippet} - + + - + import {Alert} from '$lib/index.js'; + import {AlertCircleIcon} from '@untitled-theme/icons-svelte'; + + + + + + +
    + Title + + Description + +
    +
    diff --git a/packages/ui-ingredients/src/routes/breadcrumbs/+page.svelte b/packages/ui-ingredients/src/routes/breadcrumbs/+page.svelte new file mode 100644 index 00000000..b39b5489 --- /dev/null +++ b/packages/ui-ingredients/src/routes/breadcrumbs/+page.svelte @@ -0,0 +1,29 @@ + + + + + + + Home + + / + + + + Components + + / + + + + Breadcrumbs + + + + diff --git a/packages/ui-ingredients/src/routes/combobox/+page.svelte b/packages/ui-ingredients/src/routes/combobox/+page.svelte index 99ef1246..ad1997c1 100644 --- a/packages/ui-ingredients/src/routes/combobox/+page.svelte +++ b/packages/ui-ingredients/src/routes/combobox/+page.svelte @@ -80,7 +80,7 @@ - + - + - + - import {Dialog, Portal} from '$lib/index.js'; + import {Dialog, Field, Portal} from '$lib/index.js'; + import {XCloseIcon} from '@untitled-theme/icons-svelte'; import {twMerge} from 'tailwind-merge'; - import {Button} from '../shared/index.js'; + import {Button, Input, Label, toaster} from '../shared/index.js'; let open = $state(false); @@ -19,43 +20,88 @@ {/snippet} - - - + + + - Title - Description - - Close + + + +

    Sign In

    +

    Sign in to continue using the app

    + +
    { + e.preventDefault(); + + toaster.success({ + title: 'Success', + description: 'Signed in successfully!', + }); + + open = false; + }} + class="mt-8" + > + + + {#snippet asChild(attrs)} + + {/snippet} + + + {#snippet asChild(attrs)} + + {/snippet} + + + + + {#snippet asChild(attrs)} + + {/snippet} + + + {#snippet asChild(attrs)} + + {/snippet} + + + + +
    diff --git a/packages/ui-ingredients/src/routes/drawer/+page.svelte b/packages/ui-ingredients/src/routes/drawer/+page.svelte new file mode 100644 index 00000000..5dfbec15 --- /dev/null +++ b/packages/ui-ingredients/src/routes/drawer/+page.svelte @@ -0,0 +1,91 @@ + + + { + open = detail.open; + }} + lazyMount +> + + {#snippet asChild(attrs)} + + {/snippet} + + + + + + + + +
    + + Title + + + Description + +
    + + + + +
    + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Pariatur + delectus, excepturi est inventore magnam at id tempora doloremque + perferendis odit tenetur recusandae cumque nihil! + + + + {#snippet asChild(attrs)} + + {/snippet} + + +
    +
    +
    +
    diff --git a/packages/ui-ingredients/src/routes/field/+page.svelte b/packages/ui-ingredients/src/routes/field/+page.svelte index f8e298a0..6ccdad55 100644 --- a/packages/ui-ingredients/src/routes/field/+page.svelte +++ b/packages/ui-ingredients/src/routes/field/+page.svelte @@ -11,12 +11,16 @@ e.preventDefault(); error = 'This is an error text'; }} + novalidate > - +
    {#snippet asChild(attrs)} - + {/snippet} diff --git a/packages/ui-ingredients/src/routes/hover-card/+page.svelte b/packages/ui-ingredients/src/routes/hover-card/+page.svelte index 40d00025..e962c020 100644 --- a/packages/ui-ingredients/src/routes/hover-card/+page.svelte +++ b/packages/ui-ingredients/src/routes/hover-card/+page.svelte @@ -15,7 +15,7 @@ {/snippet} - + - + - + - + diff --git a/packages/ui-ingredients/src/routes/select/+page.svelte b/packages/ui-ingredients/src/routes/select/+page.svelte index b65c4061..4ece6c0a 100644 --- a/packages/ui-ingredients/src/routes/select/+page.svelte +++ b/packages/ui-ingredients/src/routes/select/+page.svelte @@ -60,7 +60,7 @@
    - + import {page} from '$app/stores'; - import {Dialog, Portal} from '$lib/index.js'; + import {Drawer, Portal} from '$lib/index.js'; import {twMerge} from 'tailwind-merge'; import {store} from './shared/index.js'; import {links} from './utils.js'; @@ -54,7 +54,7 @@ - - - - + + - - - + + + + + - + diff --git a/packages/ui-ingredients/src/routes/tabs/+page.svelte b/packages/ui-ingredients/src/routes/tabs/+page.svelte index 265b2df0..f633df79 100644 --- a/packages/ui-ingredients/src/routes/tabs/+page.svelte +++ b/packages/ui-ingredients/src/routes/tabs/+page.svelte @@ -42,6 +42,8 @@ {/each} {#each items as { value, content }} - {content} + {content} {/each} diff --git a/packages/ui-ingredients/src/routes/tooltip/+page.svelte b/packages/ui-ingredients/src/routes/tooltip/+page.svelte index a02d0dcc..73c482dc 100644 --- a/packages/ui-ingredients/src/routes/tooltip/+page.svelte +++ b/packages/ui-ingredients/src/routes/tooltip/+page.svelte @@ -10,7 +10,7 @@ {/snippet} - + arr.findIndex((t) => t.label === o.label) === i) .toSorted((i, j) => i.label.localeCompare(j.label)); diff --git a/packages/ui-ingredients/src/tests/alert-dialog/alert-dialog.svelte b/packages/ui-ingredients/src/tests/alert-dialog/alert-dialog.svelte new file mode 100644 index 00000000..8793b5de --- /dev/null +++ b/packages/ui-ingredients/src/tests/alert-dialog/alert-dialog.svelte @@ -0,0 +1,15 @@ + + + + Trigger + + + + Title + Description + Close + + + diff --git a/packages/ui-ingredients/src/tests/alert-dialog/alert-dialog.test.ts b/packages/ui-ingredients/src/tests/alert-dialog/alert-dialog.test.ts new file mode 100644 index 00000000..6fbe4322 --- /dev/null +++ b/packages/ui-ingredients/src/tests/alert-dialog/alert-dialog.test.ts @@ -0,0 +1,21 @@ +import {alertDialogAnatomy} from '$lib/index.js'; +import {render} from '@testing-library/svelte'; +import {axe} from 'vitest-axe'; +import {getAnatomySelector} from '../utils.js'; +import AlertDialog from './alert-dialog.svelte'; + +describe('AlertDialog', () => { + it.each(getAnatomySelector(alertDialogAnatomy))( + 'should render %s', + (selector) => { + render(AlertDialog); + expect(document.querySelector(selector)).toBeInTheDocument(); + }, + ); + + it('should have no a11y violations', async () => { + const {container} = render(AlertDialog); + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); +}); diff --git a/packages/ui-ingredients/src/tests/alert/alert.svelte b/packages/ui-ingredients/src/tests/alert/alert.svelte new file mode 100644 index 00000000..e20e5eb4 --- /dev/null +++ b/packages/ui-ingredients/src/tests/alert/alert.svelte @@ -0,0 +1,9 @@ + + + + + Title + Description + diff --git a/packages/ui-ingredients/src/tests/alert/alert.test.ts b/packages/ui-ingredients/src/tests/alert/alert.test.ts new file mode 100644 index 00000000..2a818400 --- /dev/null +++ b/packages/ui-ingredients/src/tests/alert/alert.test.ts @@ -0,0 +1,18 @@ +import {alertAnatomy} from '$lib/index.js'; +import {render} from '@testing-library/svelte'; +import {axe} from 'vitest-axe'; +import {getAnatomySelector} from '../utils.js'; +import Alert from './alert.svelte'; + +describe('Alert', () => { + it.each(getAnatomySelector(alertAnatomy))('should render %s', (selector) => { + render(Alert); + expect(document.querySelector(selector)).toBeInTheDocument(); + }); + + it('should have no a11y violations', async () => { + const {container} = render(Alert); + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); +}); diff --git a/packages/ui-ingredients/src/tests/breadcrumbs/breadcrumbs.svelte b/packages/ui-ingredients/src/tests/breadcrumbs/breadcrumbs.svelte new file mode 100644 index 00000000..bda7ba62 --- /dev/null +++ b/packages/ui-ingredients/src/tests/breadcrumbs/breadcrumbs.svelte @@ -0,0 +1,21 @@ + + + + + + Home + / + + + Components + / + + + + Breadcrumbs + + + + diff --git a/packages/ui-ingredients/src/tests/breadcrumbs/breadcrumbs.test.ts b/packages/ui-ingredients/src/tests/breadcrumbs/breadcrumbs.test.ts new file mode 100644 index 00000000..c813431b --- /dev/null +++ b/packages/ui-ingredients/src/tests/breadcrumbs/breadcrumbs.test.ts @@ -0,0 +1,21 @@ +import {breadcrumbsAnatomy} from '$lib/index.js'; +import {render} from '@testing-library/svelte'; +import {axe} from 'vitest-axe'; +import {getAnatomySelector} from '../utils.js'; +import Breadcrumbs from './breadcrumbs.svelte'; + +describe('Breadcrumbs', () => { + it.each(getAnatomySelector(breadcrumbsAnatomy))( + 'should render %s', + (selector) => { + render(Breadcrumbs); + expect(document.querySelector(selector)).toBeInTheDocument(); + }, + ); + + it('should have no a11y violations', async () => { + const {container} = render(Breadcrumbs); + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); +}); diff --git a/packages/ui-ingredients/src/tests/dialog/dialog.svelte b/packages/ui-ingredients/src/tests/dialog/dialog.svelte index 6fb9ab3c..fdad9a14 100644 --- a/packages/ui-ingredients/src/tests/dialog/dialog.svelte +++ b/packages/ui-ingredients/src/tests/dialog/dialog.svelte @@ -7,13 +7,9 @@ - Title + Title Description - - Close - + Close diff --git a/packages/ui-ingredients/src/tests/drawer/drawer.svelte b/packages/ui-ingredients/src/tests/drawer/drawer.svelte new file mode 100644 index 00000000..1a64b6af --- /dev/null +++ b/packages/ui-ingredients/src/tests/drawer/drawer.svelte @@ -0,0 +1,20 @@ + + + + Trigger + + + + + Title + Description + + + + Close + + + + diff --git a/packages/ui-ingredients/src/tests/drawer/drawer.test.ts b/packages/ui-ingredients/src/tests/drawer/drawer.test.ts new file mode 100644 index 00000000..f03912c1 --- /dev/null +++ b/packages/ui-ingredients/src/tests/drawer/drawer.test.ts @@ -0,0 +1,18 @@ +import {drawerAnatomy} from '$lib/index.js'; +import {render} from '@testing-library/svelte'; +import {axe} from 'vitest-axe'; +import {getAnatomySelector} from '../utils.js'; +import Drawer from './drawer.svelte'; + +describe('Drawer', () => { + it.each(getAnatomySelector(drawerAnatomy))('should render %s', (selector) => { + render(Drawer); + expect(document.querySelector(selector)).toBeInTheDocument(); + }); + + it('should have no a11y violations', async () => { + const {container} = render(Drawer); + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); +}); diff --git a/packages/ui-ingredients/src/tests/field/field.svelte b/packages/ui-ingredients/src/tests/field/field.svelte index 47c46014..5948bfde 100644 --- a/packages/ui-ingredients/src/tests/field/field.svelte +++ b/packages/ui-ingredients/src/tests/field/field.svelte @@ -3,21 +3,21 @@ - Label + Label This is an error text This is a helper text - Label + Label This is an error text This is a helper text - Label + Label This is an error text This is a helper text diff --git a/packages/ui-ingredients/tailwind.config.js b/packages/ui-ingredients/tailwind.config.js index 523119a5..3bcec573 100644 --- a/packages/ui-ingredients/tailwind.config.js +++ b/packages/ui-ingredients/tailwind.config.js @@ -126,6 +126,22 @@ export default withTV({ transform: 'translateX(-100%)', }, }, + 'slide-in-right': { + '0%': { + transform: 'translateX(100%)', + }, + '100%': { + transform: 'translateX(0)', + }, + }, + 'slide-out-right': { + '0%': { + transform: 'translateX(0)', + }, + '100%': { + transform: 'translateX(100%)', + }, + }, }, animation: { 'collapse-in': 'collapse-in 200ms ease-in-out', @@ -134,6 +150,8 @@ export default withTV({ 'fade-out': 'fade-out 200ms ease-in-out', 'slide-in-left': 'slide-in-left 200ms ease-in-out', 'slide-out-left': 'slide-out-left 200ms ease-in-out', + 'slide-in-right': 'slide-in-right 200ms ease-in-out', + 'slide-out-right': 'slide-out-right 200ms ease-in-out', }, }, },