@sewadah/selaras 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +4 -1
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +7 -5
  4. package/dist/runtime/components/AlertDialog.d.vue.ts +5 -3
  5. package/dist/runtime/components/AlertDialog.vue +17 -9
  6. package/dist/runtime/components/AlertDialog.vue.d.ts +5 -3
  7. package/dist/runtime/components/App.vue +2 -0
  8. package/dist/runtime/components/Autocomplete.d.vue.ts +2 -2
  9. package/dist/runtime/components/Autocomplete.vue +1 -1
  10. package/dist/runtime/components/Autocomplete.vue.d.ts +2 -2
  11. package/dist/runtime/components/Button.d.vue.ts +7 -5
  12. package/dist/runtime/components/Button.vue +14 -3
  13. package/dist/runtime/components/Button.vue.d.ts +7 -5
  14. package/dist/runtime/components/ColorModeSwitch.d.vue.ts +18 -0
  15. package/dist/runtime/components/ColorModeSwitch.vue +59 -0
  16. package/dist/runtime/components/ColorModeSwitch.vue.d.ts +18 -0
  17. package/dist/runtime/components/ConfirmRenderer.d.vue.ts +3 -0
  18. package/dist/runtime/components/ConfirmRenderer.vue +39 -0
  19. package/dist/runtime/components/ConfirmRenderer.vue.d.ts +3 -0
  20. package/dist/runtime/components/ContextMenu.vue +4 -2
  21. package/dist/runtime/components/Drawer.vue +3 -2
  22. package/dist/runtime/components/Dropdown.vue +4 -2
  23. package/dist/runtime/components/Modal.vue +3 -2
  24. package/dist/runtime/components/Popover.vue +4 -2
  25. package/dist/runtime/components/Select.d.vue.ts +8 -4
  26. package/dist/runtime/components/Select.vue +1 -1
  27. package/dist/runtime/components/Select.vue.d.ts +8 -4
  28. package/dist/runtime/components/Slideover.vue +3 -2
  29. package/dist/runtime/components/Tooltip.vue +4 -2
  30. package/dist/runtime/composables/use-confirm.d.ts +14 -0
  31. package/dist/runtime/composables/use-confirm.js +28 -0
  32. package/dist/runtime/internal/ComboboxSelectBase.d.vue.ts +12 -11
  33. package/dist/runtime/internal/ComboboxSelectBase.vue +16 -7
  34. package/dist/runtime/internal/ComboboxSelectBase.vue.d.ts +12 -11
  35. package/dist/runtime/internal/ComboboxSelectBody.d.vue.ts +8 -7
  36. package/dist/runtime/internal/ComboboxSelectBody.vue +4 -4
  37. package/dist/runtime/internal/ComboboxSelectBody.vue.d.ts +8 -7
  38. package/dist/runtime/internal/combobox-select.d.ts +19 -18
  39. package/dist/runtime/internal/combobox-select.js +36 -14
  40. package/dist/runtime/internal/programmatic-services.d.ts +11 -0
  41. package/dist/runtime/internal/programmatic-services.js +1 -0
  42. package/dist/runtime/theme/badge.d.ts +9 -0
  43. package/dist/runtime/theme/badge.js +2 -1
  44. package/dist/runtime/theme/button.d.ts +18 -0
  45. package/dist/runtime/theme/button.js +4 -1
  46. package/dist/runtime/theme/toast.js +1 -1
  47. package/dist/runtime/theme-config.d.ts +1 -1
  48. package/dist/runtime/types/index.d.ts +4 -1
  49. package/dist/runtime/utils/autocomplete-contracts.d.ts +4 -4
  50. package/dist/runtime/utils/file-icons.js +1 -0
  51. package/dist/runtime/utils/messages.d.ts +1 -0
  52. package/dist/runtime/utils/messages.js +1 -0
  53. package/dist/runtime/utils/select-contracts.d.ts +18 -10
  54. package/dist/runtime/utils/ui.d.ts +11 -0
  55. package/dist/runtime/utils/ui.js +54 -1
  56. package/package.json +5 -5
@@ -1,8 +1,10 @@
1
- import type { SelectIdentity, SelectModel, SelectProps, SelectSlots } from '../utils/select-contracts.js';
1
+ import type { SelectEntry, SelectEntryItem, SelectModel, SelectProps, SelectSlots } from '../utils/select-contracts.js';
2
2
  export type { SelectEmits, SelectProps, SelectSlots } from '../utils/select-contracts.js';
3
- declare const __VLS_export: <Entry extends object, Key extends string = "value", Multiple extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
+ declare const __VLS_export: <Entry extends SelectEntry, Key extends string = "value", Multiple extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
4
  props: import("vue").PublicProps & __VLS_PrettifyLocal<SelectProps<Entry, Key, Multiple> & {
5
- "onUpdate:modelValue"?: ((value: SelectModel<SelectIdentity<Entry, Key>, Multiple>) => any) | undefined;
5
+ "onUpdate:modelValue"?: ((value: SelectModel<SelectEntryItem<Entry> extends infer T ? T extends SelectEntryItem<Entry> ? T extends import("../utils/select-contracts.js").SelectValue ? T : Key extends "value" ? T extends object ? "value" extends keyof T ? T extends infer T_1 ? T_1 extends T ? T_1 extends {
6
+ value: infer Value;
7
+ } ? Value : T_1 | NonNullable<T_1[keyof T_1 & "value"]> : never : never : T : never : Key extends keyof T ? T[Key] : never : never : never, Multiple>) => any) | undefined;
6
8
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
7
9
  "onUpdate:searchTerm"?: ((value: string) => any) | undefined;
8
10
  }> & (typeof globalThis extends {
@@ -11,7 +13,9 @@ declare const __VLS_export: <Entry extends object, Key extends string = "value",
11
13
  expose: (exposed: {}) => void;
12
14
  attrs: any;
13
15
  slots: SelectSlots<Entry, Key>;
14
- emit: ((evt: "update:modelValue", value: SelectModel<SelectIdentity<Entry, Key>, Multiple>) => void) & ((evt: "update:open", value: boolean) => void) & ((evt: "update:searchTerm", value: string) => void);
16
+ emit: ((evt: "update:modelValue", value: SelectModel<SelectEntryItem<Entry> extends infer T ? T extends SelectEntryItem<Entry> ? T extends import("../utils/select-contracts.js").SelectValue ? T : Key extends "value" ? T extends object ? "value" extends keyof T ? T extends infer T_1 ? T_1 extends T ? T_1 extends {
17
+ value: infer Value;
18
+ } ? Value : T_1 | NonNullable<T_1[keyof T_1 & "value"]> : never : never : T : never : Key extends keyof T ? T[Key] : never : never : never, Multiple>) => void) & ((evt: "update:open", value: boolean) => void) & ((evt: "update:searchTerm", value: string) => void);
15
19
  }>) => import("vue").VNode & {
16
20
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
17
21
  };
@@ -7,7 +7,7 @@ const props = defineProps({
7
7
  name: { type: String, required: false },
8
8
  form: { type: String, required: false },
9
9
  items: { type: Array, required: true },
10
- valueKey: { type: String, required: false },
10
+ valueKey: { type: void 0, required: false },
11
11
  labelKey: { type: String, required: false },
12
12
  open: { type: Boolean, required: false },
13
13
  defaultOpen: { type: Boolean, required: false },
@@ -1,8 +1,10 @@
1
- import type { SelectIdentity, SelectModel, SelectProps, SelectSlots } from '../utils/select-contracts.js';
1
+ import type { SelectEntry, SelectEntryItem, SelectModel, SelectProps, SelectSlots } from '../utils/select-contracts.js';
2
2
  export type { SelectEmits, SelectProps, SelectSlots } from '../utils/select-contracts.js';
3
- declare const __VLS_export: <Entry extends object, Key extends string = "value", Multiple extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
+ declare const __VLS_export: <Entry extends SelectEntry, Key extends string = "value", Multiple extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
4
  props: import("vue").PublicProps & __VLS_PrettifyLocal<SelectProps<Entry, Key, Multiple> & {
5
- "onUpdate:modelValue"?: ((value: SelectModel<SelectIdentity<Entry, Key>, Multiple>) => any) | undefined;
5
+ "onUpdate:modelValue"?: ((value: SelectModel<SelectEntryItem<Entry> extends infer T ? T extends SelectEntryItem<Entry> ? T extends import("../utils/select-contracts.js").SelectValue ? T : Key extends "value" ? T extends object ? "value" extends keyof T ? T extends infer T_1 ? T_1 extends T ? T_1 extends {
6
+ value: infer Value;
7
+ } ? Value : T_1 | NonNullable<T_1[keyof T_1 & "value"]> : never : never : T : never : Key extends keyof T ? T[Key] : never : never : never, Multiple>) => any) | undefined;
6
8
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
7
9
  "onUpdate:searchTerm"?: ((value: string) => any) | undefined;
8
10
  }> & (typeof globalThis extends {
@@ -11,7 +13,9 @@ declare const __VLS_export: <Entry extends object, Key extends string = "value",
11
13
  expose: (exposed: {}) => void;
12
14
  attrs: any;
13
15
  slots: SelectSlots<Entry, Key>;
14
- emit: ((evt: "update:modelValue", value: SelectModel<SelectIdentity<Entry, Key>, Multiple>) => void) & ((evt: "update:open", value: boolean) => void) & ((evt: "update:searchTerm", value: string) => void);
16
+ emit: ((evt: "update:modelValue", value: SelectModel<SelectEntryItem<Entry> extends infer T ? T extends SelectEntryItem<Entry> ? T extends import("../utils/select-contracts.js").SelectValue ? T : Key extends "value" ? T extends object ? "value" extends keyof T ? T extends infer T_1 ? T_1 extends T ? T_1 extends {
17
+ value: infer Value;
18
+ } ? Value : T_1 | NonNullable<T_1[keyof T_1 & "value"]> : never : never : T : never : Key extends keyof T ? T[Key] : never : never : never, Multiple>) => void) & ((evt: "update:open", value: boolean) => void) & ((evt: "update:searchTerm", value: string) => void);
15
19
  }>) => import("vue").VNode & {
16
20
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
17
21
  };
@@ -4,9 +4,10 @@ import { computed, getCurrentInstance, ref, useSlots, watch, watchEffect } from
4
4
  import { useIcons } from "../composables/use-icons";
5
5
  import { useMessages } from "../composables/use-messages";
6
6
  import { slideoverTheme } from "../theme/slideover";
7
- import { resolveSlot, useComponentTheme, useThemeBindings } from "../utils/ui";
7
+ import { resolveSlot, useComponentTheme, useRootProps, useThemeBindings } from "../utils/ui";
8
8
  import Button from "./Button.vue";
9
9
  import Icon from "./Icon.vue";
10
+ defineOptions({ inheritAttrs: false });
10
11
  const props = defineProps({
11
12
  open: { type: Boolean, required: false, default: void 0 },
12
13
  defaultOpen: { type: Boolean, required: false },
@@ -70,8 +71,8 @@ const messages = useMessages();
70
71
  const theme = useComponentTheme("slideover", slideoverTheme);
71
72
  const themeBindings = useThemeBindings();
72
73
  const ui = computed(() => theme.value({ side: props.side, inset: props.inset, transition: props.transition }));
74
+ const contentProps = useRootProps(() => ui.value.content, () => props.ui?.content);
73
75
  const overlayProps = computed(() => resolveSlot(ui.value.overlay, props.ui?.overlay));
74
- const contentProps = computed(() => resolveSlot(ui.value.content, props.ui?.content));
75
76
  const headerProps = computed(() => resolveSlot(ui.value.header, props.ui?.header));
76
77
  const titleProps = computed(() => resolveSlot(ui.value.title, props.ui?.title));
77
78
  const descriptionProps = computed(() => resolveSlot(ui.value.description, props.ui?.description));
@@ -4,7 +4,8 @@ import { computed } from "vue";
4
4
  import { tooltipTheme } from "../theme/tooltip";
5
5
  import { arrowContentProps, arrowElementProps } from "../utils/arrow";
6
6
  import { overlayPortalProps } from "../utils/overlay";
7
- import { resolveSlot, useComponentTheme, useThemeBindings } from "../utils/ui";
7
+ import { resolveSlot, useComponentTheme, useFallthroughProps, useThemeBindings } from "../utils/ui";
8
+ defineOptions({ inheritAttrs: false });
8
9
  const props = defineProps({
9
10
  text: { type: String, required: false },
10
11
  side: { type: String, required: false, default: "top" },
@@ -19,6 +20,7 @@ const props = defineProps({
19
20
  const theme = useComponentTheme("tooltip", tooltipTheme);
20
21
  const themeBindings = useThemeBindings();
21
22
  const ui = computed(() => theme.value());
23
+ const triggerProps = useFallthroughProps();
22
24
  const contentProps = computed(() => ({ ...resolveSlot(ui.value.content, props.ui?.content), ...arrowContentProps(props.arrow), ...props.positioning }));
23
25
  const portalProps = computed(() => overlayPortalProps(props.portal));
24
26
  const arrowProps = computed(() => ({ ...resolveSlot(ui.value.arrow, props.ui?.arrow), ...arrowElementProps(props.arrow) }));
@@ -28,7 +30,7 @@ const kbdProps = computed(() => resolveSlot(ui.value.kbd, props.ui?.kbd));
28
30
 
29
31
  <template>
30
32
  <TooltipRoot :delay-duration="delayDuration" :disabled="disabled">
31
- <TooltipTrigger as-child>
33
+ <TooltipTrigger as-child v-bind="triggerProps">
32
34
  <slot />
33
35
  </TooltipTrigger>
34
36
  <TooltipPortal v-bind="portalProps">
@@ -0,0 +1,14 @@
1
+ import type { ColorRole } from '../utils/color-registry.js';
2
+ export interface UseConfirmOptions {
3
+ title?: string;
4
+ description?: string;
5
+ confirmLabel?: string;
6
+ cancelLabel?: string;
7
+ confirmColor?: ColorRole;
8
+ icon?: string;
9
+ }
10
+ export interface UseConfirmReturn {
11
+ /** Resolves true only for an explicit confirmation; cancel, Escape, and dismissal resolve false. */
12
+ confirm: (options?: UseConfirmOptions) => Promise<boolean>;
13
+ }
14
+ export declare function useConfirm(): UseConfirmReturn;
@@ -0,0 +1,28 @@
1
+ import { useConfirmService } from "../internal/programmatic-services.js";
2
+ import { useProgrammaticThemeSnapshot } from "../utils/programmatic-theme.js";
3
+ import { useMessages } from "./use-messages.js";
4
+ export function useConfirm() {
5
+ const service = useConfirmService();
6
+ const messages = useMessages();
7
+ const snapshotTheme = useProgrammaticThemeSnapshot();
8
+ function confirm(options = {}) {
9
+ if (import.meta.server)
10
+ return Promise.reject(new Error("[useConfirm] confirm() is client-only. Render SAlertDialog declaratively during SSR."));
11
+ return new Promise((resolve) => {
12
+ service.instances.value.push({
13
+ id: service.nextId(),
14
+ isOpen: true,
15
+ _settled: false,
16
+ resolve: (value) => resolve(value === true),
17
+ title: options.title ?? messages.value.confirmation,
18
+ description: options.description,
19
+ confirmLabel: options.confirmLabel,
20
+ cancelLabel: options.cancelLabel,
21
+ confirmColor: options.confirmColor,
22
+ icon: options.icon,
23
+ _theme: snapshotTheme()
24
+ });
25
+ });
26
+ }
27
+ return { confirm };
28
+ }
@@ -3,6 +3,7 @@ import type { SelectThemeSlots } from '../theme/select.js';
3
3
  import type { RoundedArrowConfig } from '../utils/arrow.js';
4
4
  import type { ColorRole } from '../utils/color-registry.js';
5
5
  import type { OverlayPortal, OverlayPositioning } from '../utils/overlay.js';
6
+ import type { SelectModelValue } from '../utils/select-contracts.js';
6
7
  import type { UiProp } from '../utils/ui.js';
7
8
  import type { SelectItems, SelectOption } from './combobox-select.js';
8
9
  import { selectTheme } from '../theme/select.js';
@@ -18,9 +19,9 @@ export interface ComboboxSelectBaseProps {
18
19
  open?: boolean;
19
20
  /** Initial uncontrolled open state. */
20
21
  defaultOpen?: boolean;
21
- modelValue?: string | number | (string | number)[];
22
+ modelValue?: SelectModelValue | SelectModelValue[];
22
23
  /** Initial uncontrolled selection and native form reset target. */
23
- defaultValue?: string | number | (string | number)[];
24
+ defaultValue?: SelectModelValue | SelectModelValue[];
24
25
  multiple?: boolean;
25
26
  searchable?: boolean;
26
27
  virtualize?: boolean | {
@@ -54,23 +55,23 @@ export interface ComboboxSelectBaseProps {
54
55
  }
55
56
  export interface ComboboxSelectBaseEmits {
56
57
  'update:open': [value: boolean];
57
- 'update:modelValue': [value: string | number | (string | number)[] | undefined];
58
+ 'update:modelValue': [value: SelectModelValue | SelectModelValue[] | undefined];
58
59
  'update:searchTerm': [value: string];
59
60
  }
60
61
  declare var __VLS_43: {
61
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
62
+ item: SelectModelValue | SelectOption<SelectModelValue>;
62
63
  }, __VLS_98: {}, __VLS_105: {}, __VLS_120: {}, __VLS_144: {
63
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
64
+ item: SelectModelValue | SelectOption<SelectModelValue>;
64
65
  }, __VLS_164: {
65
66
  selected: import("./combobox-select.js").ResolvedOption | undefined;
66
67
  }, __VLS_175: {}, __VLS_182: {}, __VLS_189: {}, __VLS_219: {}, __VLS_222: {}, __VLS_225: {}, __VLS_228: {}, __VLS_231: {
67
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
68
+ item: SelectModelValue | SelectOption<SelectModelValue>;
68
69
  }, __VLS_234: {
69
- group: import("./combobox-select.js").SelectOptionGroup<import("../utils/select-contracts.js").SelectValue>;
70
+ group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
70
71
  }, __VLS_237: {}, __VLS_273: string, __VLS_274: {}, __VLS_277: {
71
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
72
+ item: SelectModelValue | SelectOption<SelectModelValue>;
72
73
  }, __VLS_280: {
73
- group: import("./combobox-select.js").SelectOptionGroup<import("../utils/select-contracts.js").SelectValue>;
74
+ group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
74
75
  };
75
76
  type __VLS_Slots = {} & {
76
77
  [K in NonNullable<typeof __VLS_273>]?: (props: typeof __VLS_274) => any;
@@ -112,11 +113,11 @@ type __VLS_Slots = {} & {
112
113
  group?: (props: typeof __VLS_280) => any;
113
114
  };
114
115
  declare const __VLS_base: import("vue").DefineComponent<ComboboxSelectBaseProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
115
- "update:modelValue": (value: string | number | (string | number)[] | undefined) => any;
116
+ "update:modelValue": (value: SelectModelValue | SelectModelValue[] | undefined) => any;
116
117
  "update:open": (value: boolean) => any;
117
118
  "update:searchTerm": (value: string) => any;
118
119
  }, string, import("vue").PublicProps, Readonly<ComboboxSelectBaseProps> & Readonly<{
119
- "onUpdate:modelValue"?: ((value: string | number | (string | number)[] | undefined) => any) | undefined;
120
+ "onUpdate:modelValue"?: ((value: SelectModelValue | SelectModelValue[] | undefined) => any) | undefined;
120
121
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
121
122
  "onUpdate:searchTerm"?: ((value: string) => any) | undefined;
122
123
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -44,8 +44,8 @@ const props = defineProps({
44
44
  labelKey: { type: String, required: false },
45
45
  open: { type: Boolean, required: false },
46
46
  defaultOpen: { type: Boolean, required: false },
47
- modelValue: { type: [String, Number, Array], required: false },
48
- defaultValue: { type: [String, Number, Array], required: false },
47
+ modelValue: { type: [String, Number, Object, Array], required: false },
48
+ defaultValue: { type: [String, Number, Object, Array], required: false },
49
49
  multiple: { type: Boolean, required: false },
50
50
  searchable: { type: Boolean, required: false },
51
51
  virtualize: { type: [Boolean, Object], required: false },
@@ -507,6 +507,15 @@ function onModalSelection(value) {
507
507
  if (!props.multiple)
508
508
  updateOpen(false);
509
509
  }
510
+ function serializeFormValue(value) {
511
+ if (typeof value !== "object")
512
+ return String(value);
513
+ try {
514
+ return JSON.stringify(value) ?? "";
515
+ } catch {
516
+ return String(value);
517
+ }
518
+ }
510
519
  const adaptiveUi = computed(() => ({
511
520
  content: {
512
521
  class: "rounded-[var(--selaras-resolved-radius-md)]",
@@ -608,7 +617,7 @@ const bodyProps = computed(() => ({
608
617
  -->
609
618
  <TagsInputItem
610
619
  v-for="option in visibleOptions"
611
- :key="option.value"
620
+ :key="option.key"
612
621
  :value="option.value"
613
622
  as-child
614
623
  >
@@ -620,7 +629,7 @@ const bodyProps = computed(() => ({
620
629
  :ui="{ root: 'data-[state=active]:ring-2 data-[state=active]:ring-[var(--_selaras-color-fill)]' }"
621
630
  >
622
631
  <TagsInputItemText as="span">
623
- <slot v-if="option.raw" name="item" :item="option.raw">
632
+ <slot v-if="option.raw !== void 0" name="item" :item="option.raw">
624
633
  {{ option.label }}
625
634
  </slot>
626
635
  <template v-else>
@@ -736,7 +745,7 @@ const bodyProps = computed(() => ({
736
745
  <div v-if="displayMode === 'chip'" class="flex flex-1 flex-wrap items-center gap-1.5">
737
746
  <Chip
738
747
  v-for="option in visibleOptions"
739
- :key="option.value"
748
+ :key="option.key"
740
749
  size="sm"
741
750
  color="primary"
742
751
  variant="soft"
@@ -745,7 +754,7 @@ const bodyProps = computed(() => ({
745
754
  :aria-current="option.value === selectedChipValue || void 0"
746
755
  :ui="{ root: 'data-[state=active]:ring-2 data-[state=active]:ring-[var(--_selaras-color-fill)]' }"
747
756
  >
748
- <slot v-if="option.raw" name="item" :item="option.raw">
757
+ <slot v-if="option.raw !== void 0" name="item" :item="option.raw">
749
758
  {{ option.label }}
750
759
  </slot>
751
760
  <template v-else>
@@ -913,7 +922,7 @@ const bodyProps = computed(() => ({
913
922
  type="hidden"
914
923
  :name="name ?? field?.name"
915
924
  :form="form"
916
- :value="String(value)"
925
+ :value="serializeFormValue(value)"
917
926
  :disabled="disabled"
918
927
  :required="required && !disabled && index === 0"
919
928
  >
@@ -3,6 +3,7 @@ import type { SelectThemeSlots } from '../theme/select.js';
3
3
  import type { RoundedArrowConfig } from '../utils/arrow.js';
4
4
  import type { ColorRole } from '../utils/color-registry.js';
5
5
  import type { OverlayPortal, OverlayPositioning } from '../utils/overlay.js';
6
+ import type { SelectModelValue } from '../utils/select-contracts.js';
6
7
  import type { UiProp } from '../utils/ui.js';
7
8
  import type { SelectItems, SelectOption } from './combobox-select.js';
8
9
  import { selectTheme } from '../theme/select.js';
@@ -18,9 +19,9 @@ export interface ComboboxSelectBaseProps {
18
19
  open?: boolean;
19
20
  /** Initial uncontrolled open state. */
20
21
  defaultOpen?: boolean;
21
- modelValue?: string | number | (string | number)[];
22
+ modelValue?: SelectModelValue | SelectModelValue[];
22
23
  /** Initial uncontrolled selection and native form reset target. */
23
- defaultValue?: string | number | (string | number)[];
24
+ defaultValue?: SelectModelValue | SelectModelValue[];
24
25
  multiple?: boolean;
25
26
  searchable?: boolean;
26
27
  virtualize?: boolean | {
@@ -54,23 +55,23 @@ export interface ComboboxSelectBaseProps {
54
55
  }
55
56
  export interface ComboboxSelectBaseEmits {
56
57
  'update:open': [value: boolean];
57
- 'update:modelValue': [value: string | number | (string | number)[] | undefined];
58
+ 'update:modelValue': [value: SelectModelValue | SelectModelValue[] | undefined];
58
59
  'update:searchTerm': [value: string];
59
60
  }
60
61
  declare var __VLS_43: {
61
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
62
+ item: SelectModelValue | SelectOption<SelectModelValue>;
62
63
  }, __VLS_98: {}, __VLS_105: {}, __VLS_120: {}, __VLS_144: {
63
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
64
+ item: SelectModelValue | SelectOption<SelectModelValue>;
64
65
  }, __VLS_164: {
65
66
  selected: import("./combobox-select.js").ResolvedOption | undefined;
66
67
  }, __VLS_175: {}, __VLS_182: {}, __VLS_189: {}, __VLS_219: {}, __VLS_222: {}, __VLS_225: {}, __VLS_228: {}, __VLS_231: {
67
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
68
+ item: SelectModelValue | SelectOption<SelectModelValue>;
68
69
  }, __VLS_234: {
69
- group: import("./combobox-select.js").SelectOptionGroup<import("../utils/select-contracts.js").SelectValue>;
70
+ group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
70
71
  }, __VLS_237: {}, __VLS_273: string, __VLS_274: {}, __VLS_277: {
71
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
72
+ item: SelectModelValue | SelectOption<SelectModelValue>;
72
73
  }, __VLS_280: {
73
- group: import("./combobox-select.js").SelectOptionGroup<import("../utils/select-contracts.js").SelectValue>;
74
+ group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
74
75
  };
75
76
  type __VLS_Slots = {} & {
76
77
  [K in NonNullable<typeof __VLS_273>]?: (props: typeof __VLS_274) => any;
@@ -112,11 +113,11 @@ type __VLS_Slots = {} & {
112
113
  group?: (props: typeof __VLS_280) => any;
113
114
  };
114
115
  declare const __VLS_base: import("vue").DefineComponent<ComboboxSelectBaseProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
115
- "update:modelValue": (value: string | number | (string | number)[] | undefined) => any;
116
+ "update:modelValue": (value: SelectModelValue | SelectModelValue[] | undefined) => any;
116
117
  "update:open": (value: boolean) => any;
117
118
  "update:searchTerm": (value: string) => any;
118
119
  }, string, import("vue").PublicProps, Readonly<ComboboxSelectBaseProps> & Readonly<{
119
- "onUpdate:modelValue"?: ((value: string | number | (string | number)[] | undefined) => any) | undefined;
120
+ "onUpdate:modelValue"?: ((value: SelectModelValue | SelectModelValue[] | undefined) => any) | undefined;
120
121
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
121
122
  "onUpdate:searchTerm"?: ((value: string) => any) | undefined;
122
123
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,3 +1,4 @@
1
+ import type { SelectModelValue } from '../utils/select-contracts.js';
1
2
  import type { ResolvedItemOption, SelectItems, SelectOption } from './combobox-select.js';
2
3
  export interface ComboboxSelectBodyProps {
3
4
  listbox?: boolean;
@@ -5,7 +6,7 @@ export interface ComboboxSelectBodyProps {
5
6
  creatable?: boolean;
6
7
  multiple?: boolean;
7
8
  forceSelection?: boolean;
8
- selectedValues?: (string | number)[];
9
+ selectedValues?: SelectModelValue[];
9
10
  searchText: string;
10
11
  displayValue: (value: unknown) => string;
11
12
  items: SelectItems;
@@ -15,9 +16,9 @@ export interface ComboboxSelectBodyProps {
15
16
  overscan: number;
16
17
  } | null;
17
18
  virtualizedOptions: ResolvedItemOption[];
18
- toOption: (entry: SelectOption) => ResolvedItemOption;
19
+ toOption: (entry: SelectOption | SelectModelValue) => ResolvedItemOption;
19
20
  groupOptions: (group: {
20
- items: readonly SelectOption[];
21
+ items: readonly (SelectOption | SelectModelValue)[];
21
22
  }) => ResolvedItemOption[];
22
23
  onSearchKeydown: (event: KeyboardEvent) => void;
23
24
  onSearchBlur: () => void;
@@ -34,13 +35,13 @@ export interface ComboboxSelectBodyEmits {
34
35
  }
35
36
  declare function focusSearch(): boolean;
36
37
  declare var __VLS_1: {}, __VLS_3: {}, __VLS_21: {}, __VLS_29: {}, __VLS_31: {}, __VLS_39: {}, __VLS_61: {
37
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
38
+ item: SelectModelValue | SelectOption<SelectModelValue>;
38
39
  }, __VLS_92: {
39
- group: import("./combobox-select.js").SelectOptionGroup<import("../utils/select-contracts.js").SelectValue>;
40
+ group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
40
41
  }, __VLS_102: {
41
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
42
+ item: SelectModelValue | SelectOption<SelectModelValue>;
42
43
  }, __VLS_123: {
43
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
44
+ item: SelectModelValue | SelectOption<SelectModelValue>;
44
45
  }, __VLS_136: {};
45
46
  type __VLS_Slots = {} & {
46
47
  header?: (props: typeof __VLS_1) => any;
@@ -71,7 +71,7 @@ const createText = computed(() => {
71
71
  });
72
72
  const virtualOptions = computed(() => {
73
73
  const options = props.listbox ? visibleOptions.value : props.virtualizedOptions;
74
- return createText.value ? [{ value: createText.value, label: messages.value.createOption(createText.value), disabled: false, raw: void 0 }, ...options] : options;
74
+ return createText.value ? [{ value: createText.value, key: `create:${createText.value}`, label: messages.value.createOption(createText.value), disabled: false, raw: void 0 }, ...options] : options;
75
75
  });
76
76
  function onItemSelect(event, value) {
77
77
  if (!props.creatable || !props.multiple || !props.selectedValues?.includes(value))
@@ -148,12 +148,12 @@ defineExpose({ focusSearch });
148
148
  :key="String(virtualItem.key)"
149
149
  :value="option.value"
150
150
  :disabled="option.disabled"
151
- :data-selaras-create-option="!option.raw || void 0"
151
+ :data-selaras-create-option="option.raw === void 0 || void 0"
152
152
  :style="{ position: 'absolute', top: 0, left: 0, right: 0, transform: `translateY(${virtualItem.start}px)`, height: `${virtualItem.size}px` }"
153
153
  v-bind="itemProps"
154
154
  @select="onItemSelect($event, option.value)"
155
155
  >
156
- <template v-if="!option.raw">
156
+ <template v-if="option.raw === void 0">
157
157
  {{ option.label }}
158
158
  </template>
159
159
  <template v-else>
@@ -182,7 +182,7 @@ defineExpose({ focusSearch });
182
182
  <component
183
183
  :is="primitives.item"
184
184
  v-for="option in groupOptions(entry).filter(matches)"
185
- :key="option.value"
185
+ :key="option.key"
186
186
  :value="option.value"
187
187
  :disabled="option.disabled"
188
188
  v-bind="itemProps"
@@ -1,3 +1,4 @@
1
+ import type { SelectModelValue } from '../utils/select-contracts.js';
1
2
  import type { ResolvedItemOption, SelectItems, SelectOption } from './combobox-select.js';
2
3
  export interface ComboboxSelectBodyProps {
3
4
  listbox?: boolean;
@@ -5,7 +6,7 @@ export interface ComboboxSelectBodyProps {
5
6
  creatable?: boolean;
6
7
  multiple?: boolean;
7
8
  forceSelection?: boolean;
8
- selectedValues?: (string | number)[];
9
+ selectedValues?: SelectModelValue[];
9
10
  searchText: string;
10
11
  displayValue: (value: unknown) => string;
11
12
  items: SelectItems;
@@ -15,9 +16,9 @@ export interface ComboboxSelectBodyProps {
15
16
  overscan: number;
16
17
  } | null;
17
18
  virtualizedOptions: ResolvedItemOption[];
18
- toOption: (entry: SelectOption) => ResolvedItemOption;
19
+ toOption: (entry: SelectOption | SelectModelValue) => ResolvedItemOption;
19
20
  groupOptions: (group: {
20
- items: readonly SelectOption[];
21
+ items: readonly (SelectOption | SelectModelValue)[];
21
22
  }) => ResolvedItemOption[];
22
23
  onSearchKeydown: (event: KeyboardEvent) => void;
23
24
  onSearchBlur: () => void;
@@ -34,13 +35,13 @@ export interface ComboboxSelectBodyEmits {
34
35
  }
35
36
  declare function focusSearch(): boolean;
36
37
  declare var __VLS_1: {}, __VLS_3: {}, __VLS_21: {}, __VLS_29: {}, __VLS_31: {}, __VLS_39: {}, __VLS_61: {
37
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
38
+ item: SelectModelValue | SelectOption<SelectModelValue>;
38
39
  }, __VLS_92: {
39
- group: import("./combobox-select.js").SelectOptionGroup<import("../utils/select-contracts.js").SelectValue>;
40
+ group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
40
41
  }, __VLS_102: {
41
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
42
+ item: SelectModelValue | SelectOption<SelectModelValue>;
42
43
  }, __VLS_123: {
43
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
44
+ item: SelectModelValue | SelectOption<SelectModelValue>;
44
45
  }, __VLS_136: {};
45
46
  type __VLS_Slots = {} & {
46
47
  header?: (props: typeof __VLS_1) => any;
@@ -1,51 +1,52 @@
1
1
  import type { ComputedRef } from 'vue';
2
- import type { SelectValue } from '../utils/select-contracts.js';
2
+ import type { SelectModelValue } from '../utils/select-contracts.js';
3
3
  /** Erased runtime records for the shared implementation, not authoring types. */
4
- export interface SelectOption<Value extends SelectValue = SelectValue> {
4
+ export interface SelectOption<Value extends SelectModelValue = SelectModelValue> {
5
5
  [key: string]: unknown;
6
- /** The default option key. Custom `valueKey` fields use the same primitive contract. */
6
+ /** The default option key. Custom `valueKey` fields use the same identity contract. */
7
7
  value?: Value;
8
8
  disabled?: boolean;
9
9
  }
10
- export interface SelectOptionGroup<Value extends SelectValue = SelectValue> {
10
+ export interface SelectOptionGroup<Value extends SelectModelValue = SelectModelValue> {
11
11
  label: string;
12
- items: readonly SelectOption<Value>[];
12
+ items: readonly (Value | SelectOption<Value>)[];
13
13
  }
14
- export type SelectItems<Value extends SelectValue = SelectValue> = readonly (SelectOption<Value> | SelectOptionGroup<Value>)[];
15
- export declare function isOptionGroup<Value extends SelectValue = SelectValue>(entry: SelectOption<Value> | SelectOptionGroup<Value>): entry is SelectOptionGroup<Value>;
14
+ export type SelectItems<Value extends SelectModelValue = SelectModelValue> = readonly (Value | SelectOption<Value> | SelectOptionGroup<Value>)[];
15
+ export declare function isOptionGroup(entry: unknown): entry is SelectOptionGroup;
16
16
  /** Flattens groups into a plain option list - groups lose their header when virtualized. */
17
- export declare function flattenItems<Value extends SelectValue = SelectValue>(items: SelectItems<Value>): SelectOption<Value>[];
17
+ export declare function flattenItems(items: SelectItems): (SelectModelValue | SelectOption)[];
18
18
  interface SelectLikeProps {
19
19
  items: SelectItems;
20
20
  valueKey?: string;
21
21
  labelKey?: string;
22
- modelValue?: SelectValue | SelectValue[];
22
+ modelValue?: SelectModelValue | SelectModelValue[];
23
23
  multiple?: boolean;
24
24
  displayMode?: 'comma' | 'chip';
25
25
  maxChips?: number;
26
26
  }
27
27
  export interface ResolvedOption {
28
- value: SelectValue;
28
+ value: SelectModelValue;
29
+ key: string | number;
29
30
  label: string;
30
31
  disabled: boolean;
31
- raw: SelectOption | undefined;
32
+ raw: SelectOption | SelectModelValue | undefined;
32
33
  }
33
34
  export interface ResolvedItemOption extends ResolvedOption {
34
- raw: SelectOption;
35
+ raw: SelectOption | SelectModelValue;
35
36
  }
36
- export declare function useComboboxSelect(props: SelectLikeProps, emit: (event: 'update:modelValue', value: SelectValue | SelectValue[] | undefined) => void, { creatable }?: {
37
+ export declare function useComboboxSelect(props: SelectLikeProps, emit: (event: 'update:modelValue', value: SelectModelValue | SelectModelValue[] | undefined) => void, { creatable }?: {
37
38
  creatable?: boolean;
38
39
  }): {
39
40
  flatOptions: ComputedRef<ResolvedItemOption[]>;
40
- selectedValues: ComputedRef<SelectValue[]>;
41
+ selectedValues: ComputedRef<SelectModelValue[]>;
41
42
  selectedOptions: ComputedRef<ResolvedOption[]>;
42
43
  visibleOptions: ComputedRef<ResolvedOption[]>;
43
44
  overflowOptions: ComputedRef<ResolvedOption[]>;
44
45
  commaText: ComputedRef<string>;
45
- resolveOption: (value: SelectValue) => ResolvedOption;
46
- toOption: (raw: SelectOption) => ResolvedItemOption;
47
- setValue: (value: SelectValue | SelectValue[] | undefined) => void;
48
- removeValue: (value: SelectValue) => void;
46
+ resolveOption: (value: SelectModelValue) => ResolvedOption;
47
+ toOption: (raw: SelectOption | SelectModelValue) => ResolvedItemOption;
48
+ setValue: (value: SelectModelValue | SelectModelValue[] | undefined) => void;
49
+ removeValue: (value: SelectModelValue) => void;
49
50
  hasMatchingOption: (text: string) => boolean;
50
51
  commitCreatableText: (rawText: string) => boolean;
51
52
  };