From 139618667a0f48255a89b7f967c344c23d155fc8 Mon Sep 17 00:00:00 2001 From: Jeanne Mas Date: Tue, 16 Apr 2024 15:17:36 -0400 Subject: [PATCH] Add select component and fix typings for some components --- .changeset/sweet-colts-dance.md | 5 + package.json | 6 +- pnpm-lock.yaml | 16 +-- src/lib/components/calendar/NextButton.svelte | 2 +- .../components/calendar/PreviousButton.svelte | 2 +- src/lib/components/calendar/Root.svelte | 5 +- src/lib/components/collapsible/Content.svelte | 3 +- src/lib/components/collapsible/Root.svelte | 2 +- src/lib/components/popover/Content.svelte | 3 +- src/lib/components/popover/Root.svelte | 2 +- src/lib/components/select/Content.svelte | 103 ++++++++++++++++++ src/lib/components/select/Group.svelte | 29 +++++ src/lib/components/select/Input.svelte | 30 +++++ src/lib/components/select/Item.svelte | 63 +++++++++++ src/lib/components/select/Label.svelte | 37 +++++++ src/lib/components/select/Root.svelte | 70 ++++++++++++ src/lib/components/select/Separator.svelte | 36 ++++++ src/lib/components/select/Trigger.svelte | 50 +++++++++ src/lib/components/select/Value.svelte | 37 +++++++ src/lib/components/select/index.ts | 63 +++++++++++ src/lib/utils/internal.ts | 14 +++ src/lib/utils/types.ts | 20 ++-- src/routes/button/+page.svelte | 91 +++++++++++----- src/routes/calendar/+page.svelte | 93 +++++++++++----- src/routes/input/+page.svelte | 46 +++++--- src/routes/select/+page.svelte | 62 +++++++++++ 26 files changed, 798 insertions(+), 92 deletions(-) create mode 100644 .changeset/sweet-colts-dance.md create mode 100644 src/lib/components/select/Content.svelte create mode 100644 src/lib/components/select/Group.svelte create mode 100644 src/lib/components/select/Input.svelte create mode 100644 src/lib/components/select/Item.svelte create mode 100644 src/lib/components/select/Label.svelte create mode 100644 src/lib/components/select/Root.svelte create mode 100644 src/lib/components/select/Separator.svelte create mode 100644 src/lib/components/select/Trigger.svelte create mode 100644 src/lib/components/select/Value.svelte create mode 100644 src/lib/components/select/index.ts create mode 100644 src/lib/utils/internal.ts create mode 100644 src/routes/select/+page.svelte diff --git a/.changeset/sweet-colts-dance.md b/.changeset/sweet-colts-dance.md new file mode 100644 index 0000000..8764f92 --- /dev/null +++ b/.changeset/sweet-colts-dance.md @@ -0,0 +1,5 @@ +--- +'@jeanne-mas/svelte-ui': minor +--- + +Added select component diff --git a/package.json b/package.json index a5a0f65..af28839 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ }, "dependencies": { "@internationalized/date": "^3.5.2", - "bits-ui": "^0.21.2", + "bits-ui": "^0.21.3", "clsx": "^2.1.0", "lucide-svelte": "^0.368.0", "tailwind-merge": "^2.2.2", @@ -71,6 +71,10 @@ "types": "./dist/components/popover/index.d.ts", "svelte": "./dist/components/popover/index.js" }, + "./components/select": { + "types": "./dist/components/select/index.d.ts", + "svelte": "./dist/components/select/index.js" + }, "./package.json": "./package.json", "./transition/flyAndScale": { "types": "./dist/transition/flyAndScale.d.ts", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b76a64..0330711 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ dependencies: specifier: ^3.5.2 version: 3.5.2 bits-ui: - specifier: ^0.21.2 - version: 0.21.2(svelte@4.2.12) + specifier: ^0.21.3 + version: 0.21.3(svelte@4.2.12) clsx: specifier: ^2.1.0 version: 2.1.0 @@ -697,7 +697,7 @@ packages: '@internationalized/date': 3.5.2 dequal: 2.0.3 focus-trap: 7.5.4 - nanoid: 5.0.6 + nanoid: 5.0.7 svelte: 4.2.12 dev: false @@ -1347,14 +1347,14 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - /bits-ui@0.21.2(svelte@4.2.12): - resolution: {integrity: sha512-tDOvNdJ+uC/VWlzCZ6Pwv3enQJBw1D7leUfdIqg8WvqcDHnvn3fk4V3Y9VmpMOPnl+xTaiKxSiVpO/Dh8wD6jA==} + /bits-ui@0.21.3(svelte@4.2.12): + resolution: {integrity: sha512-VMQVXwYIjYmDoudIRm2ZlS2guy97lUQk73DwSfTnaS0dhldImbDFMATNxjLSLsTDj8FqJ8Dv78wSctdxcloIbQ==} peerDependencies: svelte: ^4.0.0 dependencies: '@internationalized/date': 3.5.2 '@melt-ui/svelte': 0.76.2(svelte@4.2.12) - nanoid: 5.0.6 + nanoid: 5.0.7 svelte: 4.2.12 dev: false @@ -3010,8 +3010,8 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - /nanoid@5.0.6: - resolution: {integrity: sha512-rRq0eMHoGZxlvaFOUdK1Ev83Bd1IgzzR+WJ3IbDJ7QOSdAxYjlurSPqFs9s4lJg29RT6nPwizFtJhQS6V5xgiA==} + /nanoid@5.0.7: + resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} engines: {node: ^18 || >=20} hasBin: true dev: false diff --git a/src/lib/components/calendar/NextButton.svelte b/src/lib/components/calendar/NextButton.svelte index 1115510..cddcd1e 100644 --- a/src/lib/components/calendar/NextButton.svelte +++ b/src/lib/components/calendar/NextButton.svelte @@ -1,6 +1,6 @@ diff --git a/src/lib/components/popover/Content.svelte b/src/lib/components/popover/Content.svelte index 5fa143a..d8a384a 100644 --- a/src/lib/components/popover/Content.svelte +++ b/src/lib/components/popover/Content.svelte @@ -33,8 +33,9 @@ > type $$Events = Record; type $$Props = Attributes & Events & TypedProps; - type $$Slots = Slots; + type $$Slots = TypedSlots; type TypedProps = Props; + type TypedSlots = Slots; export let align: TypedProps['align'] = undefined; export let asChild: TypedProps['asChild'] = undefined; diff --git a/src/lib/components/popover/Root.svelte b/src/lib/components/popover/Root.svelte index d4760ad..d076c1e 100644 --- a/src/lib/components/popover/Root.svelte +++ b/src/lib/components/popover/Root.svelte @@ -5,7 +5,7 @@ export type Attributes = Record; export type Events = Pick; - export type Props = Omit; + export type Props = Omit; export type Slots = ComponentSlots; diff --git a/src/lib/components/select/Content.svelte b/src/lib/components/select/Content.svelte new file mode 100644 index 0000000..9c4954e --- /dev/null +++ b/src/lib/components/select/Content.svelte @@ -0,0 +1,103 @@ + + + + + + + +
+ +
+
diff --git a/src/lib/components/select/Group.svelte b/src/lib/components/select/Group.svelte new file mode 100644 index 0000000..1416ce0 --- /dev/null +++ b/src/lib/components/select/Group.svelte @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/src/lib/components/select/Input.svelte b/src/lib/components/select/Input.svelte new file mode 100644 index 0000000..55b0ed8 --- /dev/null +++ b/src/lib/components/select/Input.svelte @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/src/lib/components/select/Item.svelte b/src/lib/components/select/Item.svelte new file mode 100644 index 0000000..e48e873 --- /dev/null +++ b/src/lib/components/select/Item.svelte @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + {label || value} + + diff --git a/src/lib/components/select/Label.svelte b/src/lib/components/select/Label.svelte new file mode 100644 index 0000000..fdbd1ec --- /dev/null +++ b/src/lib/components/select/Label.svelte @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/src/lib/components/select/Root.svelte b/src/lib/components/select/Root.svelte new file mode 100644 index 0000000..78f7b6d --- /dev/null +++ b/src/lib/components/select/Root.svelte @@ -0,0 +1,70 @@ + + + + + + + + + diff --git a/src/lib/components/select/Separator.svelte b/src/lib/components/select/Separator.svelte new file mode 100644 index 0000000..54faa01 --- /dev/null +++ b/src/lib/components/select/Separator.svelte @@ -0,0 +1,36 @@ + + + + + + + + + diff --git a/src/lib/components/select/Trigger.svelte b/src/lib/components/select/Trigger.svelte new file mode 100644 index 0000000..d501514 --- /dev/null +++ b/src/lib/components/select/Trigger.svelte @@ -0,0 +1,50 @@ + + + + + + + + + +
+ +
+
diff --git a/src/lib/components/select/Value.svelte b/src/lib/components/select/Value.svelte new file mode 100644 index 0000000..503f2f7 --- /dev/null +++ b/src/lib/components/select/Value.svelte @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/src/lib/components/select/index.ts b/src/lib/components/select/index.ts new file mode 100644 index 0000000..cc3e8a5 --- /dev/null +++ b/src/lib/components/select/index.ts @@ -0,0 +1,63 @@ +export { + default as Content, + type Attributes as ContentAttributes, + type Events as ContentEvents, + type Props as ContentProps, + type Slots as ContentSlots, +} from './Content.svelte'; +export { + default as Group, + type Attributes as GroupAttributes, + type Events as GroupEvents, + type Props as GroupProps, + type Slots as GroupSlots, +} from './Group.svelte'; +export { + default as Input, + type Attributes as InputAttributes, + type Events as InputEvents, + type Props as InputProps, + type Slots as InputSlots, +} from './Input.svelte'; +export { + default as Item, + type Attributes as ItemAttributes, + type Events as ItemEvents, + type Props as ItemProps, + type Slots as ItemSlots, +} from './Item.svelte'; +export { + default as Label, + type Attributes as LabelAttributes, + type Events as LabelEvents, + type Props as LabelProps, + type Slots as LabelSlots, +} from './Label.svelte'; +export { + default as Root, + type Attributes as RootAttributes, + type Events as RootEvents, + type Props as RootProps, + type Slots as RootSlots, +} from './Root.svelte'; +export { + default as Separator, + type Attributes as SeparatorAttributes, + type Events as SeparatorEvents, + type Props as SeparatorProps, + type Slots as SeparatorSlots, +} from './Separator.svelte'; +export { + default as Trigger, + type Attributes as TriggerAttributes, + type Events as TriggerEvents, + type Props as TriggerProps, + type Slots as TriggerSlots, +} from './Trigger.svelte'; +export { + default as Value, + type Attributes as ValueAttributes, + type Events as ValueEvents, + type Props as ValueProps, + type Slots as ValueSlots, +} from './Value.svelte'; diff --git a/src/lib/utils/internal.ts b/src/lib/utils/internal.ts new file mode 100644 index 0000000..089002d --- /dev/null +++ b/src/lib/utils/internal.ts @@ -0,0 +1,14 @@ +/** + * Casts the given value to any type. + * + * Internal function, do not use. + * + * @param value The value to cast. + * @returns The value casted to any type. + * + * @private + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function castAsAny(value: unknown): any { + return value; +} diff --git a/src/lib/utils/types.ts b/src/lib/utils/types.ts index 55198d1..0ece098 100644 --- a/src/lib/utils/types.ts +++ b/src/lib/utils/types.ts @@ -2,9 +2,11 @@ import type { SvelteComponent } from 'svelte'; import type { Action } from 'svelte/action'; import type { TransitionConfig } from 'svelte/transition'; -export type ComponentSlots = +export type ComponentSlots = TComponent extends SvelteComponent, Record, infer TSlots> - ? PatchSlotsWithBuilderAction + ? true extends TApplyPatch + ? PatchSlotsWithBuilder + : TSlots : never; export type Transition = (node: Element, params?: unknown) => TransitionConfig; export type TransitionParams = Parameters[1]; @@ -20,14 +22,16 @@ type Expand = T extends object ? (T extends infer O ? { [K in keyof O]: O[K] * > This is likely not portable. * > A type annotation is necessary. */ -type PatchSlotsWithBuilderAction>> = { +type PatchSlotsWithBuilder>> = { [TSlotName in keyof TSlots]: TSlots[TSlotName] extends { builder: infer TBuilder } ? Expand> & { - builder: TBuilder extends { action: Action } - ? Expand> & { - action: Action; - } - : TBuilder; + builder: { + [TBuilderKey in keyof TBuilder]: TBuilderKey extends 'action' + ? Action // Prevents importing `import("@melt-ui/svelte/internal/types").MeltActionReturn` + : TBuilderKey extends 'data-orientation' + ? string // Prevents importing `import("@melt-ui/svelte/internal/types").Orientation` + : TBuilder[TBuilderKey]; + }; } : TSlots[TSlotName]; }; diff --git a/src/routes/button/+page.svelte b/src/routes/button/+page.svelte index 279dd7e..6e66789 100644 --- a/src/routes/button/+page.svelte +++ b/src/routes/button/+page.svelte @@ -5,6 +5,7 @@ import { page } from '$app/stores'; import Button, { variants, type Size, type Variant } from '$lib/components/button/index.js'; import Label from '$lib/components/label/index.js'; + import * as Select from '$lib/components/select/index.js'; const disabledKey = 'disabled'; const sizeKey = 'size'; @@ -56,47 +57,85 @@ - + + + + + + + + {#each sizeKeys as sizeKey, index (index)} + + {sizeKey} + + {/each} + + - + + + + + + + + {#each variantKeys as variantKey, index (index)} + + {variantKey} + + {/each} + +
diff --git a/src/routes/calendar/+page.svelte b/src/routes/calendar/+page.svelte index 3ba3919..ca3ca95 100644 --- a/src/routes/calendar/+page.svelte +++ b/src/routes/calendar/+page.svelte @@ -6,6 +6,7 @@ import { page } from '$app/stores'; import * as Calendar from '$lib/components/calendar/index.js'; import Label from '$lib/components/label/index.js'; + import * as Select from '$lib/components/select/index.js'; const calendarLabelKey = 'calendarLabel'; const disabledKey = 'disabled'; @@ -91,49 +92,85 @@ - + + + + + + + + {#each weekdayFormatKeys as weekdayFormatKey, index (index)} + + {weekdayFormatKey} + + {/each} + + - + + + + + + + + {#each weekStartsOnKeys as weekStartsOnKey, index (index)} + + {weekStartsOnKey} + + {/each} + +
diff --git a/src/routes/input/+page.svelte b/src/routes/input/+page.svelte index d072f21..c2e72cd 100644 --- a/src/routes/input/+page.svelte +++ b/src/routes/input/+page.svelte @@ -5,6 +5,7 @@ import { page } from '$app/stores'; import Input, { type Variant } from '$lib/components/input/index.js'; import Label from '$lib/components/label/index.js'; + import * as Select from '$lib/components/select/index.js'; const disabledKey = 'disabled'; const placeholderKey = 'placeholder'; @@ -71,25 +72,44 @@ - + + + + + + + + {#each variantKeys as variantKey, index (index)} + + {variantKey} + + {/each} + +
diff --git a/src/routes/select/+page.svelte b/src/routes/select/+page.svelte new file mode 100644 index 0000000..f0a8ab8 --- /dev/null +++ b/src/routes/select/+page.svelte @@ -0,0 +1,62 @@ + + + + + + +
+ + + + + + + + + + {#each fruitKeys as fruitKey, index (index)} + + {fruitKey} + + {/each} + +