@scalar/components 0.29.2 → 0.30.0

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 (21) hide show
  1. package/dist/components/ScalarCombobox/ScalarCombobox.vue.d.ts +4 -0
  2. package/dist/components/ScalarCombobox/ScalarCombobox.vue.d.ts.map +1 -1
  3. package/dist/components/ScalarCombobox/ScalarCombobox.vue.js.map +1 -1
  4. package/dist/components/ScalarCombobox/ScalarCombobox.vue.script.js +8 -0
  5. package/dist/components/ScalarCombobox/ScalarCombobox.vue.script.js.map +1 -1
  6. package/dist/components/ScalarCombobox/ScalarComboboxOptions.vue.d.ts +6 -0
  7. package/dist/components/ScalarCombobox/ScalarComboboxOptions.vue.d.ts.map +1 -1
  8. package/dist/components/ScalarCombobox/ScalarComboboxOptions.vue.js.map +1 -1
  9. package/dist/components/ScalarCombobox/ScalarComboboxOptions.vue.script.js +67 -49
  10. package/dist/components/ScalarCombobox/ScalarComboboxOptions.vue.script.js.map +1 -1
  11. package/dist/components/ScalarDropdown/ScalarDropdownButton.vue.js +1 -1
  12. package/dist/components/ScalarDropdown/ScalarDropdownButton.vue.js.map +1 -1
  13. package/dist/components/ScalarDropdown/ScalarDropdownButton.vue.script.js +1 -1
  14. package/dist/components/ScalarDropdown/ScalarDropdownButton.vue.script.js.map +1 -1
  15. package/dist/components/ScalarDropdown/ScalarDropdownMenu.vue.d.ts.map +1 -1
  16. package/dist/components/ScalarDropdown/ScalarDropdownMenu.vue.js.map +1 -1
  17. package/dist/components/ScalarDropdown/ScalarDropdownMenu.vue.script.js +1 -1
  18. package/dist/components/ScalarDropdown/ScalarDropdownMenu.vue.script.js.map +1 -1
  19. package/dist/style.css +2 -2
  20. package/dist/vue-styles.css +2 -2
  21. package/package.json +7 -7
@@ -19,6 +19,10 @@ declare const __VLS_export: <O extends Option = Option, G extends OptionGroup<O>
19
19
  options: OptionsOrGroups<O, G>;
20
20
  /** The placeholder text to display in the combobox */
21
21
  placeholder?: string;
22
+ /** An accessible label for the search input */
23
+ inputLabel?: string;
24
+ /** The message to display when filtering returns no options */
25
+ noResults?: string;
22
26
  /** A function to filter the options based on a query,
23
27
  * if not provided, the options will be filtered by option label
24
28
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarCombobox.vue.d.ts","sourceRoot":"","sources":["../../../src/components/ScalarCombobox/ScalarCombobox.vue"],"names":[],"mappings":"AAsGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAG9D,OAAO,KAAK,EAEV,aAAa,EACb,cAAc,EACd,MAAM,EACN,WAAW,EACX,eAAe,EAChB,MAAM,SAAS,CAAA;AAGhB;;;;;;;;;;GAUG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY,GAAK,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAC1F,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,gBAAgB,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAClE;WAkKO,OAAO,KAAK,EAAE,WAAW,GAAG,mBAAmB,CAAC;QAhKpD,6CAA6C;iBACpC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9B,sDAAsD;sBACxC,MAAM;QACpB;;;;WAIG;mBACQ,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;;qBAgBtB,CAAC;;;;KAuI6E,CAAC,GAAG,CAAC,OAAO,UAAU,SAAS;QAAE,oBAAoB,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5J,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI;WACtB,GAAG;;UAEJ,qFAAoC;EAEvC,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;CAAI,CAAC;AACzF,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,CAAC,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"ScalarCombobox.vue.d.ts","sourceRoot":"","sources":["../../../src/components/ScalarCombobox/ScalarCombobox.vue"],"names":[],"mappings":"AA6GA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAG9D,OAAO,KAAK,EAEV,aAAa,EACb,cAAc,EACd,MAAM,EACN,WAAW,EACX,eAAe,EAChB,MAAM,SAAS,CAAA;AAGhB;;;;;;;;;;GAUG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY,GAAK,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAC1F,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,gBAAgB,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAClE;WA4KO,OAAO,KAAK,EAAE,WAAW,GAAG,mBAAmB,CAAC;QA1KpD,6CAA6C;iBACpC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9B,sDAAsD;sBACxC,MAAM;QACpB,+CAA+C;qBAClC,MAAM;QACnB,+DAA+D;oBACnD,MAAM;QAClB;;;;WAIG;mBACQ,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;;qBAgBtB,CAAC;;;;KA6I6E,CAAC,GAAG,CAAC,OAAO,UAAU,SAAS;QAAE,oBAAoB,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5J,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI;WACtB,GAAG;;UAEJ,qFAAoC;EAEvC,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;CAAI,CAAC;AACzF,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,CAAC,GAAG,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarCombobox.vue.js","names":[],"sources":["../../../src/components/ScalarCombobox/ScalarCombobox.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar Combobox component\n *\n * A searchable select input with support for filtering, option groups,\n * and custom option rendering.\n *\n * @example\n * <ScalarCombobox v-model=\"selected\" :options=\"options\">\n * <ScalarButton>{{ selected?.label ?? 'Select' }}</ScalarButton>\n * </ScalarCombobox>\n */\nexport default {}\n</script>\n\n<!-- prettier-ignore-attribute generic -->\n<script\n setup\n lang=\"ts\"\n generic=\"O extends Option = Option, G extends OptionGroup<O> = OptionGroup<O>\">\nimport type { ScalarFloatingOptions } from '../ScalarFloating'\nimport ComboboxOptions from './ScalarComboboxOptions.vue'\nimport ComboboxPopover from './ScalarComboboxPopover.vue'\nimport type {\n ComboboxEmits,\n ComboboxSlots,\n FilterFunction,\n Option,\n OptionGroup,\n OptionsOrGroups,\n} from './types'\n\ndefineProps<\n {\n /** The options to display in the combobox */\n options: OptionsOrGroups<O, G>\n /** The placeholder text to display in the combobox */\n placeholder?: string\n /** A function to filter the options based on a query,\n * if not provided, the options will be filtered by option label\n *\n * @see {@link FilterFunction} for more information\n */\n filterFn?: FilterFunction<O, G>\n } & ScalarFloatingOptions\n>()\n\nconst emit = defineEmits<ComboboxEmits>()\n\nconst model = defineModel<O>()\n\ndefineSlots<ComboboxSlots<O, G>>()\n</script>\n<template>\n <ComboboxPopover\n :middleware\n :offset\n :placement=\"placement ?? 'bottom-start'\"\n :resize\n :target\n :teleport>\n <template #default=\"{ open }\">\n <slot :open />\n </template>\n <template #popover=\"{ open, close }\">\n <ComboboxOptions\n :filterFn\n :modelValue=\"model ? [model] : []\"\n :open\n :options\n :placeholder\n @add=\"() => (close(), emit('add'))\"\n @update:modelValue=\"(v) => (close(), (model = v[0]))\">\n <!-- Pass through the combobox slots -->\n <template\n v-if=\"$slots.option\"\n #option=\"props\">\n <slot\n name=\"option\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"$slots.group\"\n #group=\"props\">\n <slot\n name=\"group\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"$slots.add\"\n #add=\"props\">\n <slot\n name=\"add\"\n v-bind=\"props\" />\n </template>\n </ComboboxOptions>\n </template>\n </ComboboxPopover>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"ScalarCombobox.vue.js","names":[],"sources":["../../../src/components/ScalarCombobox/ScalarCombobox.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar Combobox component\n *\n * A searchable select input with support for filtering, option groups,\n * and custom option rendering.\n *\n * @example\n * <ScalarCombobox v-model=\"selected\" :options=\"options\">\n * <ScalarButton>{{ selected?.label ?? 'Select' }}</ScalarButton>\n * </ScalarCombobox>\n */\nexport default {}\n</script>\n\n<!-- prettier-ignore-attribute generic -->\n<script\n setup\n lang=\"ts\"\n generic=\"O extends Option = Option, G extends OptionGroup<O> = OptionGroup<O>\">\nimport type { ScalarFloatingOptions } from '../ScalarFloating'\nimport ComboboxOptions from './ScalarComboboxOptions.vue'\nimport ComboboxPopover from './ScalarComboboxPopover.vue'\nimport type {\n ComboboxEmits,\n ComboboxSlots,\n FilterFunction,\n Option,\n OptionGroup,\n OptionsOrGroups,\n} from './types'\n\ndefineProps<\n {\n /** The options to display in the combobox */\n options: OptionsOrGroups<O, G>\n /** The placeholder text to display in the combobox */\n placeholder?: string\n /** An accessible label for the search input */\n inputLabel?: string\n /** The message to display when filtering returns no options */\n noResults?: string\n /** A function to filter the options based on a query,\n * if not provided, the options will be filtered by option label\n *\n * @see {@link FilterFunction} for more information\n */\n filterFn?: FilterFunction<O, G>\n } & ScalarFloatingOptions\n>()\n\nconst emit = defineEmits<ComboboxEmits>()\n\nconst model = defineModel<O>()\n\ndefineSlots<ComboboxSlots<O, G>>()\n</script>\n<template>\n <ComboboxPopover\n :middleware\n :offset\n :placement=\"placement ?? 'bottom-start'\"\n :resize\n :target\n :teleport>\n <template #default=\"{ open }\">\n <slot :open />\n </template>\n <template #popover=\"{ open, close }\">\n <ComboboxOptions\n :close\n :filterFn\n :inputLabel\n :modelValue=\"model ? [model] : []\"\n :noResults\n :open\n :options\n :placeholder\n @add=\"() => (close(), emit('add'))\"\n @update:modelValue=\"(v) => (close(), (model = v[0]))\">\n <!-- Pass through the combobox slots -->\n <template\n v-if=\"$slots.option\"\n #option=\"props\">\n <slot\n name=\"option\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"$slots.group\"\n #group=\"props\">\n <slot\n name=\"group\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"$slots.add\"\n #add=\"props\">\n <slot\n name=\"add\"\n v-bind=\"props\" />\n </template>\n </ComboboxOptions>\n </template>\n </ComboboxPopover>\n</template>\n"],"mappings":""}
@@ -6,6 +6,8 @@ var ScalarCombobox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
6
6
  props: /*@__PURE__*/ mergeModels({
7
7
  options: {},
8
8
  placeholder: {},
9
+ inputLabel: {},
10
+ noResults: {},
9
11
  filterFn: { type: Function },
10
12
  placement: {},
11
13
  offset: { type: [
@@ -36,8 +38,11 @@ var ScalarCombobox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
36
38
  }, {
37
39
  default: withCtx(({ open }) => [renderSlot(_ctx.$slots, "default", { open })]),
38
40
  popover: withCtx(({ open, close }) => [createVNode(ScalarComboboxOptions_default, {
41
+ close,
39
42
  filterFn: __props.filterFn,
43
+ inputLabel: __props.inputLabel,
40
44
  modelValue: model.value ? [model.value] : [],
45
+ noResults: __props.noResults,
41
46
  open,
42
47
  options: __props.options,
43
48
  placeholder: __props.placeholder,
@@ -60,8 +65,11 @@ var ScalarCombobox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
60
65
  key: "2"
61
66
  } : void 0
62
67
  ]), 1032, [
68
+ "close",
63
69
  "filterFn",
70
+ "inputLabel",
64
71
  "modelValue",
72
+ "noResults",
65
73
  "open",
66
74
  "options",
67
75
  "placeholder",
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarCombobox.vue.script.js","names":["$slots"],"sources":["../../../src/components/ScalarCombobox/ScalarCombobox.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar Combobox component\n *\n * A searchable select input with support for filtering, option groups,\n * and custom option rendering.\n *\n * @example\n * <ScalarCombobox v-model=\"selected\" :options=\"options\">\n * <ScalarButton>{{ selected?.label ?? 'Select' }}</ScalarButton>\n * </ScalarCombobox>\n */\nexport default {}\n</script>\n\n<!-- prettier-ignore-attribute generic -->\n<script\n setup\n lang=\"ts\"\n generic=\"O extends Option = Option, G extends OptionGroup<O> = OptionGroup<O>\">\nimport type { ScalarFloatingOptions } from '../ScalarFloating'\nimport ComboboxOptions from './ScalarComboboxOptions.vue'\nimport ComboboxPopover from './ScalarComboboxPopover.vue'\nimport type {\n ComboboxEmits,\n ComboboxSlots,\n FilterFunction,\n Option,\n OptionGroup,\n OptionsOrGroups,\n} from './types'\n\ndefineProps<\n {\n /** The options to display in the combobox */\n options: OptionsOrGroups<O, G>\n /** The placeholder text to display in the combobox */\n placeholder?: string\n /** A function to filter the options based on a query,\n * if not provided, the options will be filtered by option label\n *\n * @see {@link FilterFunction} for more information\n */\n filterFn?: FilterFunction<O, G>\n } & ScalarFloatingOptions\n>()\n\nconst emit = defineEmits<ComboboxEmits>()\n\nconst model = defineModel<O>()\n\ndefineSlots<ComboboxSlots<O, G>>()\n</script>\n<template>\n <ComboboxPopover\n :middleware\n :offset\n :placement=\"placement ?? 'bottom-start'\"\n :resize\n :target\n :teleport>\n <template #default=\"{ open }\">\n <slot :open />\n </template>\n <template #popover=\"{ open, close }\">\n <ComboboxOptions\n :filterFn\n :modelValue=\"model ? [model] : []\"\n :open\n :options\n :placeholder\n @add=\"() => (close(), emit('add'))\"\n @update:modelValue=\"(v) => (close(), (model = v[0]))\">\n <!-- Pass through the combobox slots -->\n <template\n v-if=\"$slots.option\"\n #option=\"props\">\n <slot\n name=\"option\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"$slots.group\"\n #group=\"props\">\n <slot\n name=\"group\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"$slots.add\"\n #add=\"props\">\n <slot\n name=\"add\"\n v-bind=\"props\" />\n </template>\n </ComboboxOptions>\n </template>\n </ComboboxPopover>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EA+CA,MAAM,OAAO;EAEb,MAAM,QAAQ,SAAc,SAAA,YAAC;;uBAK3B,YA2CkB,+BAAA;IA1Cf,YAAA,QAAA;IACA,QAAA,QAAA;IACA,WAAW,QAAA,aAAS;IACpB,QAAA,QAAA;IACA,QAAA,QAAA;IACA,UAAA,QAAA;;IACU,SAAO,SACF,EADM,WAAI,CACxB,WAAc,KAAA,QAAA,WAAA,EAAP,KAAI,CAAA,CAAA,CAAA;IAEF,SAAO,SA+BE,EA/BE,MAAM,YAAK,CAC/B,YA8BkB,+BAAA;KA7Bf,UAAA,QAAA;KACA,YAAY,MAAA,QAAK,CAAI,MAAA,KAAK,IAAA,CAAA;KAC1B;KACA,SAAA,QAAA;KACA,aAAA,QAAA;KACA,cAAY,MAAK,GAAI,KAAI,KAAA;KACzB,wBAAoB,OAAO,MAAK,GAAK,MAAA,QAAQ,EAAC;;KAGvCA,KAAAA,OAAO,SAAA;YACZ;mBAAQ,UAAK,CACd,WAEmB,KAAA,QAAA,UAAA,eAAA,mBAAT,KAAK,CAAA,CAAA,CAAA,CAAA;;;KAGTA,KAAAA,OAAO,QAAA;YACZ;mBAAO,UAAK,CACb,WAEmB,KAAA,QAAA,SAAA,eAAA,mBAAT,KAAK,CAAA,CAAA,CAAA,CAAA;;;KAGTA,KAAAA,OAAO,MAAA;YACZ;mBAAK,UAAK,CACX,WAEmB,KAAA,QAAA,OAAA,eAAA,mBAAT,KAAK,CAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"ScalarCombobox.vue.script.js","names":["$slots"],"sources":["../../../src/components/ScalarCombobox/ScalarCombobox.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar Combobox component\n *\n * A searchable select input with support for filtering, option groups,\n * and custom option rendering.\n *\n * @example\n * <ScalarCombobox v-model=\"selected\" :options=\"options\">\n * <ScalarButton>{{ selected?.label ?? 'Select' }}</ScalarButton>\n * </ScalarCombobox>\n */\nexport default {}\n</script>\n\n<!-- prettier-ignore-attribute generic -->\n<script\n setup\n lang=\"ts\"\n generic=\"O extends Option = Option, G extends OptionGroup<O> = OptionGroup<O>\">\nimport type { ScalarFloatingOptions } from '../ScalarFloating'\nimport ComboboxOptions from './ScalarComboboxOptions.vue'\nimport ComboboxPopover from './ScalarComboboxPopover.vue'\nimport type {\n ComboboxEmits,\n ComboboxSlots,\n FilterFunction,\n Option,\n OptionGroup,\n OptionsOrGroups,\n} from './types'\n\ndefineProps<\n {\n /** The options to display in the combobox */\n options: OptionsOrGroups<O, G>\n /** The placeholder text to display in the combobox */\n placeholder?: string\n /** An accessible label for the search input */\n inputLabel?: string\n /** The message to display when filtering returns no options */\n noResults?: string\n /** A function to filter the options based on a query,\n * if not provided, the options will be filtered by option label\n *\n * @see {@link FilterFunction} for more information\n */\n filterFn?: FilterFunction<O, G>\n } & ScalarFloatingOptions\n>()\n\nconst emit = defineEmits<ComboboxEmits>()\n\nconst model = defineModel<O>()\n\ndefineSlots<ComboboxSlots<O, G>>()\n</script>\n<template>\n <ComboboxPopover\n :middleware\n :offset\n :placement=\"placement ?? 'bottom-start'\"\n :resize\n :target\n :teleport>\n <template #default=\"{ open }\">\n <slot :open />\n </template>\n <template #popover=\"{ open, close }\">\n <ComboboxOptions\n :close\n :filterFn\n :inputLabel\n :modelValue=\"model ? [model] : []\"\n :noResults\n :open\n :options\n :placeholder\n @add=\"() => (close(), emit('add'))\"\n @update:modelValue=\"(v) => (close(), (model = v[0]))\">\n <!-- Pass through the combobox slots -->\n <template\n v-if=\"$slots.option\"\n #option=\"props\">\n <slot\n name=\"option\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"$slots.group\"\n #group=\"props\">\n <slot\n name=\"group\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"$slots.add\"\n #add=\"props\">\n <slot\n name=\"add\"\n v-bind=\"props\" />\n </template>\n </ComboboxOptions>\n </template>\n </ComboboxPopover>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;EAmDA,MAAM,OAAO;EAEb,MAAM,QAAQ,SAAc,SAAA,YAAC;;uBAK3B,YA8CkB,+BAAA;IA7Cf,YAAA,QAAA;IACA,QAAA,QAAA;IACA,WAAW,QAAA,aAAS;IACpB,QAAA,QAAA;IACA,QAAA,QAAA;IACA,UAAA,QAAA;;IACU,SAAO,SACF,EADM,WAAI,CACxB,WAAc,KAAA,QAAA,WAAA,EAAP,KAAI,CAAA,CAAA,CAAA;IAEF,SAAO,SAkCE,EAlCE,MAAM,YAAK,CAC/B,YAiCkB,+BAAA;KAhCf;KACA,UAAA,QAAA;KACA,YAAA,QAAA;KACA,YAAY,MAAA,QAAK,CAAI,MAAA,KAAK,IAAA,CAAA;KAC1B,WAAA,QAAA;KACA;KACA,SAAA,QAAA;KACA,aAAA,QAAA;KACA,cAAY,MAAK,GAAI,KAAI,KAAA;KACzB,wBAAoB,OAAO,MAAK,GAAK,MAAA,QAAQ,EAAC;;KAGvCA,KAAAA,OAAO,SAAA;YACZ;mBAAQ,UAAK,CACd,WAEmB,KAAA,QAAA,UAAA,eAAA,mBAAT,KAAK,CAAA,CAAA,CAAA,CAAA;;;KAGTA,KAAAA,OAAO,QAAA;YACZ;mBAAO,UAAK,CACb,WAEmB,KAAA,QAAA,SAAA,eAAA,mBAAT,KAAK,CAAA,CAAA,CAAA,CAAA;;;KAGTA,KAAAA,OAAO,MAAA;YACZ;mBAAK,UAAK,CACX,WAEmB,KAAA,QAAA,OAAA,eAAA,mBAAT,KAAK,CAAA,CAAA,CAAA,CAAA"}
@@ -16,6 +16,12 @@ declare const __VLS_export: <O extends Option = Option, G extends OptionGroup<O>
16
16
  options: OptionsOrGroups<O, G>;
17
17
  /** The placeholder text to display in the combobox */
18
18
  placeholder?: string;
19
+ /** An accessible label for the search input */
20
+ inputLabel?: string;
21
+ /** The message to display when filtering returns no options */
22
+ noResults?: string;
23
+ /** Close the popover without changing the current selection */
24
+ close?: () => void;
19
25
  /**
20
26
  * A function to filter the options based on a query,
21
27
  * if not provided, the options will be filtered by option label
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarComboboxOptions.vue.d.ts","sourceRoot":"","sources":["../../../src/components/ScalarCombobox/ScalarComboboxOptions.vue"],"names":[],"mappings":"AAgTA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,eAAe,EAErB,MAAM,SAAS,CAAA;AAGhB;;;;;;;;GAQG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY,GAAK,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAC1F,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,gBAAgB,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAClE;WAueO,OAAO,KAAK,EAAE,WAAW,GAAG,mBAAmB,CAAC;QAretD,6CAA6C;iBACpC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9B,sDAAsD;sBACxC,MAAM;QACpB;;;;;WAKG;mBACQ,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,qEAAqE;sBACvD,OAAO;;qBAqKV,CAAC,EAAE;;;;KAoT2E,CAAC,GAAG,CAAC,OAAO,UAAU,SAAS;QAAE,oBAAoB,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5J,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI;WACtB,GAAG;;UAEJ,2EAAoC;EAEvC,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;CAAI,CAAC;AACzF,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,CAAC,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"ScalarComboboxOptions.vue.d.ts","sourceRoot":"","sources":["../../../src/components/ScalarCombobox/ScalarComboboxOptions.vue"],"names":[],"mappings":"AAiUA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,eAAe,EAErB,MAAM,SAAS,CAAA;AAGhB;;;;;;;;GAQG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY,GAAK,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAC1F,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,gBAAgB,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAClE;WAggBO,OAAO,KAAK,EAAE,WAAW,GAAG,mBAAmB,CAAC;QA9ftD,6CAA6C;iBACpC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9B,sDAAsD;sBACxC,MAAM;QACpB,+CAA+C;qBAClC,MAAM;QACnB,+DAA+D;oBACnD,MAAM;QAClB,+DAA+D;gBACvD,MAAM,IAAI;QAClB;;;;;WAKG;mBACQ,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,qEAAqE;sBACvD,OAAO;;qBAwKV,CAAC,EAAE;;;;KAoU2E,CAAC,GAAG,CAAC,OAAO,UAAU,SAAS;QAAE,oBAAoB,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5J,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI;WACtB,GAAG;;UAEJ,2EAAoC;EAEvC,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;CAAI,CAAC;AACzF,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,CAAC,GAAG,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarComboboxOptions.vue.js","names":[],"sources":["../../../src/components/ScalarCombobox/ScalarComboboxOptions.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar Combobox Options component\n *\n * Renders the searchable option list for a combobox, including\n * filtering, keyboard navigation, and an optional \"add new\" action.\n *\n * @example\n * <ScalarComboboxOptions v-model=\"selected\" :options=\"options\" />\n */\nexport default {}\n</script>\n\n<!-- prettier-ignore-attribute generic -->\n<script\n setup\n lang=\"ts\"\n generic=\"O extends Option = Option, G extends OptionGroup<O> = OptionGroup<O>\">\nimport { filterByOptionLabel } from '@/components/ScalarCombobox/filter-by-option-label'\nimport { ScalarIconMagnifyingGlass, ScalarIconPlus } from '@scalar/icons'\nimport { computed, onMounted, ref, useId, watch } from 'vue'\n\nimport { ScalarListboxCheckbox } from '../ScalarListbox'\nimport ComboboxOption from './ScalarComboboxOption.vue'\nimport ComboboxOptionGroup from './ScalarComboboxOptionGroup.vue'\nimport {\n type ComboboxEmits,\n type ComboboxSlots,\n type FilterFunction,\n type Option,\n type OptionGroup,\n type OptionsOrGroups,\n isGroups,\n} from './types'\n\nconst {\n options: optionsOrGroups,\n placeholder,\n filterFn = filterByOptionLabel,\n multiselect,\n} = defineProps<{\n /** The options to display in the combobox */\n options: OptionsOrGroups<O, G>\n /** The placeholder text to display in the combobox */\n placeholder?: string\n /**\n * A function to filter the options based on a query,\n * if not provided, the options will be filtered by option label\n *\n * @see {@link FilterFunction} for more information\n */\n filterFn?: FilterFunction<O, G>\n /** Whether the combobox is in multiselect mode, defaults to false */\n multiselect?: boolean\n}>()\n\nconst emit = defineEmits<ComboboxEmits>()\n\nconst model = defineModel<O[]>({ default: () => [] })\n\nconst slots = defineSlots<Omit<ComboboxSlots<O, G>, 'default'>>()\n\ndefineOptions({ inheritAttrs: false })\n\n/** A unique ID for the combobox */\nconst id = `scalar-combobox-items-${useId()}`\n\n/** A static option entry for the \"Add a new option\" option */\nconst addOption: Option = { id: `${useId()}-add`, label: 'Add a new option' }\n\n/** Generate a unique ID for an option */\nfunction getOptionId(option: Option) {\n return `${id}-${option.id}`\n}\n\n/** A flat list of all options */\nconst options = computed<O[]>(() =>\n isGroups(optionsOrGroups)\n ? optionsOrGroups.flatMap((group) => group.options)\n : optionsOrGroups,\n)\n\n/** An list of all groups */\nconst groups = computed<G[]>(\n () =>\n isGroups(optionsOrGroups)\n ? optionsOrGroups // G extends OptionGroup<O>\n : /*\n We know G is an unextended OptionGroup<O> here because of the\n structure of the component props so we can cast it to G\n */\n [{ label: '', options: optionsOrGroups } as G], // G is OptionGroup<O>\n)\n\nconst query = ref<string>('')\nconst activeRef = ref<Option | undefined>(model.value?.[0] ?? options.value[0])\n\n// Clear the query on open and close\nonMounted(() => {\n // Clear the query\n query.value = ''\n\n // Set the active option to the selected option or the first option\n activeRef.value = model.value?.[0] ?? options.value[0]\n\n // Scroll to the selected option\n const selected = model.value[0]\n if (selected) {\n setTimeout(() => {\n const value = model.value[0]\n if (!value) {\n return\n }\n\n document\n ?.getElementById(getOptionId(value))\n ?.scrollIntoView({ block: 'nearest' })\n }, 10)\n }\n})\n\n// Set the top option as active when searching\nwatch(\n () => query.value,\n () => (activeRef.value = withAdd.value[0]),\n)\n\n/** The filtered list of options */\nconst filtered = computed<O[]>(() =>\n filterFn(query.value, options.value, groups.value),\n)\n\n/** The list of filtered options with the \"Add a new option\" option */\nconst withAdd = computed<Option[]>(() =>\n slots.add ? [...filtered.value, addOption] : filtered.value,\n)\n\nfunction toggleSelected(option: Option | undefined) {\n if (!option) {\n return\n }\n\n if (option.id === addOption.id) {\n addNew()\n return\n }\n\n if (multiselect) {\n // Remove from selection list\n if (model.value.some((o) => o.id === option.id)) {\n model.value = model.value.filter((o) => o.id !== option.id)\n }\n // Add to selection list\n else {\n model.value = [\n ...model.value,\n options.value.find((o) => o.id === option.id)!,\n ]\n }\n } else {\n // Set selection for single select mode\n model.value = [options.value.find((o) => o.id === option.id)!]\n }\n}\n\nfunction moveActive(dir: 1 | -1) {\n const list = withAdd.value\n\n // Find active index\n const activeIdx = list.findIndex(\n (option) => option.id === activeRef.value?.id,\n )\n\n // Calculate next index and exit if it's out of bounds\n const nextIdx = activeIdx + dir\n\n if (nextIdx < 0 || nextIdx > list.length - 1) {\n return\n }\n\n activeRef.value = list[nextIdx]! // We know it's in bounds from the check above\n\n if (!activeRef.value) {\n return\n }\n\n // Scroll to the active option\n document?.getElementById(getOptionId(activeRef.value))?.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n })\n}\n\nfunction addNew() {\n emit('add')\n query.value = ''\n}\n\n// Manual autofocus for the input\nconst input = ref<HTMLInputElement | null>(null)\n\n// This must be a setTimeout to ensure there is no scroll jump. nextTick does not work here.\nonMounted(() => setTimeout(() => input.value?.focus(), 0))\n</script>\n<template>\n <div class=\"relative flex\">\n <ScalarIconMagnifyingGlass\n class=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-c-3 size-4\" />\n <input\n ref=\"input\"\n v-model=\"query\"\n :aria-activedescendant=\"activeRef ? getOptionId(activeRef) : undefined\"\n aria-autocomplete=\"list\"\n :aria-controls=\"id\"\n class=\"min-w-0 flex-1 rounded border-0 py-2.5 pl-8 pr-3 leading-none text-c-1 -outline-offset-1\"\n data-1p-ignore\n :placeholder\n role=\"combobox\"\n tabindex=\"0\"\n type=\"text\"\n @keydown.down.prevent=\"moveActive(1)\"\n @keydown.enter.prevent=\"activeRef && toggleSelected(activeRef)\"\n @keydown.up.prevent=\"moveActive(-1)\" />\n </div>\n <ul\n v-show=\"filtered.length || slots.add\"\n :id=\"id\"\n :aria-multiselectable=\"multiselect\"\n class=\"border-t p-0.75 custom-scroll overscroll-contain flex-1 min-h-0\"\n role=\"listbox\"\n tabindex=\"-1\">\n <ComboboxOptionGroup\n v-for=\"(group, i) in groups\"\n :id=\"`${id}-group-${i}`\"\n :key=\"i\"\n :hidden=\"\n // Only show the group label if there are some results\n !group.options.some((o) => filtered.some((f) => f.id === o.id)) ||\n // And it has a label\n !group.label\n \">\n <template #label>\n <slot\n v-if=\"$slots.group\"\n :group\n name=\"group\" />\n <template v-else>\n {{ group.label }}\n </template>\n </template>\n <template\n v-for=\"option in filtered\"\n :key=\"option.id\">\n <ComboboxOption\n v-if=\"group.options.some((o) => o.id === option.id)\"\n :id=\"getOptionId(option)\"\n v-slot=\"{ active, selected }\"\n :active=\"activeRef?.id === option.id\"\n :selected=\"model.some((o) => o.id === option.id)\"\n @click=\"toggleSelected(option)\"\n @mousedown.prevent\n @mouseenter=\"activeRef = option\">\n <slot\n v-if=\"$slots.option\"\n :active\n name=\"option\"\n :option\n :selected />\n <template v-else>\n <ScalarListboxCheckbox\n :multiselect\n :selected=\"model.some((o) => o.id === option.id)\" />\n <span class=\"inline-block min-w-0 flex-1 truncate text-c-1\">\n {{ option.label }}\n </span>\n </template>\n </ComboboxOption>\n </template>\n </ComboboxOptionGroup>\n <ComboboxOption\n v-if=\"slots.add\"\n :id=\"getOptionId(addOption)\"\n v-slot=\"{ active }\"\n :active=\"activeRef?.id === addOption.id\"\n @click=\"addNew\"\n @mousedown.prevent\n @mouseenter=\"activeRef = addOption\">\n <ScalarIconPlus class=\"size-4 p-px\" />\n <slot\n :active\n name=\"add\" />\n </ComboboxOption>\n </ul>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"ScalarComboboxOptions.vue.js","names":[],"sources":["../../../src/components/ScalarCombobox/ScalarComboboxOptions.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar Combobox Options component\n *\n * Renders the searchable option list for a combobox, including\n * filtering, keyboard navigation, and an optional \"add new\" action.\n *\n * @example\n * <ScalarComboboxOptions v-model=\"selected\" :options=\"options\" />\n */\nexport default {}\n</script>\n\n<!-- prettier-ignore-attribute generic -->\n<script\n setup\n lang=\"ts\"\n generic=\"O extends Option = Option, G extends OptionGroup<O> = OptionGroup<O>\">\nimport { filterByOptionLabel } from '@/components/ScalarCombobox/filter-by-option-label'\nimport { ScalarIconMagnifyingGlass, ScalarIconPlus } from '@scalar/icons'\nimport { computed, onMounted, ref, useId, watch } from 'vue'\n\nimport { ScalarListboxCheckbox } from '../ScalarListbox'\nimport ComboboxOption from './ScalarComboboxOption.vue'\nimport ComboboxOptionGroup from './ScalarComboboxOptionGroup.vue'\nimport {\n type ComboboxEmits,\n type ComboboxSlots,\n type FilterFunction,\n type Option,\n type OptionGroup,\n type OptionsOrGroups,\n isGroups,\n} from './types'\n\nconst {\n options: optionsOrGroups,\n placeholder,\n inputLabel,\n noResults,\n close,\n filterFn = filterByOptionLabel,\n multiselect,\n} = defineProps<{\n /** The options to display in the combobox */\n options: OptionsOrGroups<O, G>\n /** The placeholder text to display in the combobox */\n placeholder?: string\n /** An accessible label for the search input */\n inputLabel?: string\n /** The message to display when filtering returns no options */\n noResults?: string\n /** Close the popover without changing the current selection */\n close?: () => void\n /**\n * A function to filter the options based on a query,\n * if not provided, the options will be filtered by option label\n *\n * @see {@link FilterFunction} for more information\n */\n filterFn?: FilterFunction<O, G>\n /** Whether the combobox is in multiselect mode, defaults to false */\n multiselect?: boolean\n}>()\n\nconst emit = defineEmits<ComboboxEmits>()\n\nconst model = defineModel<O[]>({ default: () => [] })\n\nconst slots = defineSlots<Omit<ComboboxSlots<O, G>, 'default'>>()\n\ndefineOptions({ inheritAttrs: false })\n\n/** A unique ID for the combobox */\nconst id = `scalar-combobox-items-${useId()}`\n\n/** A static option entry for the \"Add a new option\" option */\nconst addOption: Option = { id: `${useId()}-add`, label: 'Add a new option' }\n\n/** Generate a unique ID for an option */\nfunction getOptionId(option: Option) {\n return `${id}-${option.id}`\n}\n\n/** A flat list of all options */\nconst options = computed<O[]>(() =>\n isGroups(optionsOrGroups)\n ? optionsOrGroups.flatMap((group) => group.options)\n : optionsOrGroups,\n)\n\n/** An list of all groups */\nconst groups = computed<G[]>(\n () =>\n isGroups(optionsOrGroups)\n ? optionsOrGroups // G extends OptionGroup<O>\n : /*\n We know G is an unextended OptionGroup<O> here because of the\n structure of the component props so we can cast it to G\n */\n [{ label: '', options: optionsOrGroups } as G], // G is OptionGroup<O>\n)\n\nconst query = ref<string>('')\nconst activeRef = ref<Option | undefined>(model.value?.[0] ?? options.value[0])\n\n// Clear the query on open and close\nonMounted(() => {\n // Clear the query\n query.value = ''\n\n // Set the active option to the selected option or the first option\n activeRef.value = model.value?.[0] ?? options.value[0]\n\n // Scroll to the selected option\n const selected = model.value[0]\n if (selected) {\n setTimeout(() => {\n const value = model.value[0]\n if (!value) {\n return\n }\n\n document\n ?.getElementById(getOptionId(value))\n ?.scrollIntoView({ block: 'nearest' })\n }, 10)\n }\n})\n\n// Set the top option as active when searching\nwatch(\n () => query.value,\n () => (activeRef.value = withAdd.value[0]),\n)\n\n/** The filtered list of options */\nconst filtered = computed<O[]>(() =>\n filterFn(query.value, options.value, groups.value),\n)\n\n/** The list of filtered options with the \"Add a new option\" option */\nconst withAdd = computed<Option[]>(() =>\n slots.add ? [...filtered.value, addOption] : filtered.value,\n)\n\nfunction toggleSelected(option: Option | undefined) {\n if (!option) {\n return\n }\n\n if (option.id === addOption.id) {\n addNew()\n return\n }\n\n if (multiselect) {\n // Remove from selection list\n if (model.value.some((o) => o.id === option.id)) {\n model.value = model.value.filter((o) => o.id !== option.id)\n }\n // Add to selection list\n else {\n model.value = [\n ...model.value,\n options.value.find((o) => o.id === option.id)!,\n ]\n }\n } else {\n // Set selection for single select mode\n model.value = [options.value.find((o) => o.id === option.id)!]\n }\n}\n\nfunction moveActive(dir: 1 | -1) {\n const list = withAdd.value\n\n // Find active index\n const activeIdx = list.findIndex(\n (option) => option.id === activeRef.value?.id,\n )\n\n // Calculate next index and exit if it's out of bounds\n const nextIdx = activeIdx + dir\n\n if (nextIdx < 0 || nextIdx > list.length - 1) {\n return\n }\n\n activeRef.value = list[nextIdx]! // We know it's in bounds from the check above\n\n if (!activeRef.value) {\n return\n }\n\n // Scroll to the active option\n document?.getElementById(getOptionId(activeRef.value))?.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n })\n}\n\nfunction addNew() {\n emit('add')\n query.value = ''\n}\n\n// Manual autofocus for the input\nconst input = ref<HTMLInputElement | null>(null)\n\n// This must be a setTimeout to ensure there is no scroll jump. nextTick does not work here.\nonMounted(() => setTimeout(() => input.value?.focus(), 0))\n</script>\n<template>\n <div class=\"relative flex\">\n <ScalarIconMagnifyingGlass\n class=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-c-3 size-4\" />\n <input\n ref=\"input\"\n v-model=\"query\"\n :aria-activedescendant=\"activeRef ? getOptionId(activeRef) : undefined\"\n aria-autocomplete=\"list\"\n :aria-controls=\"id\"\n :aria-label=\"inputLabel\"\n class=\"min-w-0 flex-1 rounded border-0 py-2.5 pl-8 pr-3 leading-none text-c-1 -outline-offset-1\"\n data-1p-ignore\n :placeholder\n role=\"combobox\"\n tabindex=\"0\"\n type=\"text\"\n @keydown.down.prevent=\"moveActive(1)\"\n @keydown.enter.prevent=\"activeRef && toggleSelected(activeRef)\"\n @keydown.esc.prevent=\"close?.()\"\n @keydown.up.prevent=\"moveActive(-1)\" />\n </div>\n <ul\n v-show=\"filtered.length || slots.add || noResults\"\n :id=\"id\"\n :aria-multiselectable=\"multiselect\"\n class=\"border-t p-0.75 custom-scroll overscroll-contain flex-1 min-h-0\"\n role=\"listbox\"\n tabindex=\"-1\">\n <li\n v-if=\"!filtered.length && !slots.add && noResults\"\n class=\"text-c-3 px-2.5 py-2\"\n role=\"status\">\n {{ noResults }}\n </li>\n <ComboboxOptionGroup\n v-for=\"(group, i) in groups\"\n :id=\"`${id}-group-${i}`\"\n :key=\"i\"\n :hidden=\"\n // Only show the group label if there are some results\n !group.options.some((o) => filtered.some((f) => f.id === o.id)) ||\n // And it has a label\n !group.label\n \">\n <template #label>\n <slot\n v-if=\"$slots.group\"\n :group\n name=\"group\" />\n <template v-else>\n {{ group.label }}\n </template>\n </template>\n <template\n v-for=\"option in filtered\"\n :key=\"option.id\">\n <ComboboxOption\n v-if=\"group.options.some((o) => o.id === option.id)\"\n :id=\"getOptionId(option)\"\n v-slot=\"{ active, selected }\"\n :active=\"activeRef?.id === option.id\"\n :selected=\"model.some((o) => o.id === option.id)\"\n @click=\"toggleSelected(option)\"\n @mousedown.prevent\n @mouseenter=\"activeRef = option\">\n <slot\n v-if=\"$slots.option\"\n :active\n name=\"option\"\n :option\n :selected />\n <template v-else>\n <ScalarListboxCheckbox\n :multiselect\n :selected=\"model.some((o) => o.id === option.id)\" />\n <span class=\"inline-block min-w-0 flex-1 truncate text-c-1\">\n {{ option.label }}\n </span>\n </template>\n </ComboboxOption>\n </template>\n </ComboboxOptionGroup>\n <ComboboxOption\n v-if=\"slots.add\"\n :id=\"getOptionId(addOption)\"\n v-slot=\"{ active }\"\n :active=\"activeRef?.id === addOption.id\"\n @click=\"addNew\"\n @mousedown.prevent\n @mouseenter=\"activeRef = addOption\">\n <ScalarIconPlus class=\"size-4 p-px\" />\n <slot\n :active\n name=\"add\" />\n </ComboboxOption>\n </ul>\n</template>\n"],"mappings":""}
@@ -7,15 +7,27 @@ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock
7
7
  import { ScalarIconMagnifyingGlass, ScalarIconPlus } from "@scalar/icons";
8
8
  //#region src/components/ScalarCombobox/ScalarComboboxOptions.vue?vue&type=script&setup=true&lang.ts
9
9
  var _hoisted_1 = { class: "relative flex" };
10
- var _hoisted_2 = ["aria-activedescendant", "placeholder"];
10
+ var _hoisted_2 = [
11
+ "aria-activedescendant",
12
+ "aria-label",
13
+ "placeholder"
14
+ ];
11
15
  var _hoisted_3 = ["aria-multiselectable"];
12
- var _hoisted_4 = { class: "inline-block min-w-0 flex-1 truncate text-c-1" };
16
+ var _hoisted_4 = {
17
+ key: 0,
18
+ class: "text-c-3 px-2.5 py-2",
19
+ role: "status"
20
+ };
21
+ var _hoisted_5 = { class: "inline-block min-w-0 flex-1 truncate text-c-1" };
13
22
  var ScalarComboboxOptions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
14
23
  inheritAttrs: false,
15
24
  __name: "ScalarComboboxOptions",
16
25
  props: /*@__PURE__*/ mergeModels({
17
26
  options: {},
18
27
  placeholder: {},
28
+ inputLabel: {},
29
+ noResults: {},
30
+ close: { type: Function },
19
31
  filterFn: {
20
32
  type: Function,
21
33
  default: filterByOptionLabel
@@ -99,6 +111,7 @@ var ScalarComboboxOptions_vue_vue_type_script_setup_true_lang_default = /*@__PUR
99
111
  "aria-activedescendant": activeRef.value ? getOptionId(activeRef.value) : void 0,
100
112
  "aria-autocomplete": "list",
101
113
  "aria-controls": id,
114
+ "aria-label": __props.inputLabel,
102
115
  class: "min-w-0 flex-1 rounded border-0 py-2.5 pl-8 pr-3 leading-none text-c-1 -outline-offset-1",
103
116
  "data-1p-ignore": "",
104
117
  placeholder: __props.placeholder,
@@ -108,7 +121,8 @@ var ScalarComboboxOptions_vue_vue_type_script_setup_true_lang_default = /*@__PUR
108
121
  onKeydown: [
109
122
  _cache[1] || (_cache[1] = withKeys(withModifiers(($event) => moveActive(1), ["prevent"]), ["down"])),
110
123
  _cache[2] || (_cache[2] = withKeys(withModifiers(($event) => activeRef.value && toggleSelected(activeRef.value), ["prevent"]), ["enter"])),
111
- _cache[3] || (_cache[3] = withKeys(withModifiers(($event) => moveActive(-1), ["prevent"]), ["up"]))
124
+ _cache[3] || (_cache[3] = withKeys(withModifiers(($event) => __props.close?.(), ["prevent"]), ["esc"])),
125
+ _cache[4] || (_cache[4] = withKeys(withModifiers(($event) => moveActive(-1), ["prevent"]), ["up"]))
112
126
  ]
113
127
  }, null, 40, _hoisted_2), [[vModelText, query.value]])]), withDirectives(createElementVNode("ul", {
114
128
  id,
@@ -116,53 +130,57 @@ var ScalarComboboxOptions_vue_vue_type_script_setup_true_lang_default = /*@__PUR
116
130
  class: "border-t p-0.75 custom-scroll overscroll-contain flex-1 min-h-0",
117
131
  role: "listbox",
118
132
  tabindex: "-1"
119
- }, [(openBlock(true), createElementBlock(Fragment, null, renderList(groups.value, (group, i) => {
120
- return openBlock(), createBlock(ScalarComboboxOptionGroup_default, {
121
- id: `${id}-group-${i}`,
122
- key: i,
123
- hidden: !group.options.some((o) => filtered.value.some((f) => f.id === o.id)) || !group.label
133
+ }, [
134
+ !filtered.value.length && !slots.add && __props.noResults ? (openBlock(), createElementBlock("li", _hoisted_4, toDisplayString(__props.noResults), 1)) : createCommentVNode("", true),
135
+ (openBlock(true), createElementBlock(Fragment, null, renderList(groups.value, (group, i) => {
136
+ return openBlock(), createBlock(ScalarComboboxOptionGroup_default, {
137
+ id: `${id}-group-${i}`,
138
+ key: i,
139
+ hidden: !group.options.some((o) => filtered.value.some((f) => f.id === o.id)) || !group.label
140
+ }, {
141
+ label: withCtx(() => [_ctx.$slots.group ? renderSlot(_ctx.$slots, "group", { group }, void 0, void 0, 0) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(group.label), 1)], 64))]),
142
+ default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(filtered.value, (option) => {
143
+ return openBlock(), createElementBlock(Fragment, { key: option.id }, [group.options.some((o) => o.id === option.id) ? (openBlock(), createBlock(ScalarComboboxOption_default, {
144
+ key: 0,
145
+ id: getOptionId(option),
146
+ active: activeRef.value?.id === option.id,
147
+ selected: model.value.some((o) => o.id === option.id),
148
+ onClick: ($event) => toggleSelected(option),
149
+ onMousedown: _cache[5] || (_cache[5] = withModifiers(() => {}, ["prevent"])),
150
+ onMouseenter: ($event) => activeRef.value = option
151
+ }, {
152
+ default: withCtx(({ active, selected }) => [_ctx.$slots.option ? renderSlot(_ctx.$slots, "option", {
153
+ active,
154
+ option,
155
+ selected
156
+ }, void 0, void 0, 0) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createVNode(unref(ScalarListboxCheckbox_default), {
157
+ multiselect: __props.multiselect,
158
+ selected: model.value.some((o) => o.id === option.id)
159
+ }, null, 8, ["multiselect", "selected"]), createElementVNode("span", _hoisted_5, toDisplayString(option.label), 1)], 64))]),
160
+ _: 2
161
+ }, 1032, [
162
+ "id",
163
+ "active",
164
+ "selected",
165
+ "onClick",
166
+ "onMouseenter"
167
+ ])) : createCommentVNode("", true)], 64);
168
+ }), 128))]),
169
+ _: 2
170
+ }, 1032, ["id", "hidden"]);
171
+ }), 128)),
172
+ slots.add ? (openBlock(), createBlock(ScalarComboboxOption_default, {
173
+ key: 1,
174
+ id: getOptionId(addOption),
175
+ active: activeRef.value?.id === addOption.id,
176
+ onClick: addNew,
177
+ onMousedown: _cache[6] || (_cache[6] = withModifiers(() => {}, ["prevent"])),
178
+ onMouseenter: _cache[7] || (_cache[7] = ($event) => activeRef.value = addOption)
124
179
  }, {
125
- label: withCtx(() => [_ctx.$slots.group ? renderSlot(_ctx.$slots, "group", { group }, void 0, void 0, 0) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(group.label), 1)], 64))]),
126
- default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(filtered.value, (option) => {
127
- return openBlock(), createElementBlock(Fragment, { key: option.id }, [group.options.some((o) => o.id === option.id) ? (openBlock(), createBlock(ScalarComboboxOption_default, {
128
- key: 0,
129
- id: getOptionId(option),
130
- active: activeRef.value?.id === option.id,
131
- selected: model.value.some((o) => o.id === option.id),
132
- onClick: ($event) => toggleSelected(option),
133
- onMousedown: _cache[4] || (_cache[4] = withModifiers(() => {}, ["prevent"])),
134
- onMouseenter: ($event) => activeRef.value = option
135
- }, {
136
- default: withCtx(({ active, selected }) => [_ctx.$slots.option ? renderSlot(_ctx.$slots, "option", {
137
- active,
138
- option,
139
- selected
140
- }, void 0, void 0, 0) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createVNode(unref(ScalarListboxCheckbox_default), {
141
- multiselect: __props.multiselect,
142
- selected: model.value.some((o) => o.id === option.id)
143
- }, null, 8, ["multiselect", "selected"]), createElementVNode("span", _hoisted_4, toDisplayString(option.label), 1)], 64))]),
144
- _: 2
145
- }, 1032, [
146
- "id",
147
- "active",
148
- "selected",
149
- "onClick",
150
- "onMouseenter"
151
- ])) : createCommentVNode("", true)], 64);
152
- }), 128))]),
153
- _: 2
154
- }, 1032, ["id", "hidden"]);
155
- }), 128)), slots.add ? (openBlock(), createBlock(ScalarComboboxOption_default, {
156
- key: 0,
157
- id: getOptionId(addOption),
158
- active: activeRef.value?.id === addOption.id,
159
- onClick: addNew,
160
- onMousedown: _cache[5] || (_cache[5] = withModifiers(() => {}, ["prevent"])),
161
- onMouseenter: _cache[6] || (_cache[6] = ($event) => activeRef.value = addOption)
162
- }, {
163
- default: withCtx(({ active }) => [createVNode(unref(ScalarIconPlus), { class: "size-4 p-px" }), renderSlot(_ctx.$slots, "add", { active })]),
164
- _: 3
165
- }, 8, ["id", "active"])) : createCommentVNode("", true)], 8, _hoisted_3), [[vShow, filtered.value.length || slots.add]])], 64);
180
+ default: withCtx(({ active }) => [createVNode(unref(ScalarIconPlus), { class: "size-4 p-px" }), renderSlot(_ctx.$slots, "add", { active })]),
181
+ _: 3
182
+ }, 8, ["id", "active"])) : createCommentVNode("", true)
183
+ ], 8, _hoisted_3), [[vShow, filtered.value.length || slots.add || __props.noResults]])], 64);
166
184
  };
167
185
  }
168
186
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarComboboxOptions.vue.script.js","names":["$slots"],"sources":["../../../src/components/ScalarCombobox/ScalarComboboxOptions.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar Combobox Options component\n *\n * Renders the searchable option list for a combobox, including\n * filtering, keyboard navigation, and an optional \"add new\" action.\n *\n * @example\n * <ScalarComboboxOptions v-model=\"selected\" :options=\"options\" />\n */\nexport default {}\n</script>\n\n<!-- prettier-ignore-attribute generic -->\n<script\n setup\n lang=\"ts\"\n generic=\"O extends Option = Option, G extends OptionGroup<O> = OptionGroup<O>\">\nimport { filterByOptionLabel } from '@/components/ScalarCombobox/filter-by-option-label'\nimport { ScalarIconMagnifyingGlass, ScalarIconPlus } from '@scalar/icons'\nimport { computed, onMounted, ref, useId, watch } from 'vue'\n\nimport { ScalarListboxCheckbox } from '../ScalarListbox'\nimport ComboboxOption from './ScalarComboboxOption.vue'\nimport ComboboxOptionGroup from './ScalarComboboxOptionGroup.vue'\nimport {\n type ComboboxEmits,\n type ComboboxSlots,\n type FilterFunction,\n type Option,\n type OptionGroup,\n type OptionsOrGroups,\n isGroups,\n} from './types'\n\nconst {\n options: optionsOrGroups,\n placeholder,\n filterFn = filterByOptionLabel,\n multiselect,\n} = defineProps<{\n /** The options to display in the combobox */\n options: OptionsOrGroups<O, G>\n /** The placeholder text to display in the combobox */\n placeholder?: string\n /**\n * A function to filter the options based on a query,\n * if not provided, the options will be filtered by option label\n *\n * @see {@link FilterFunction} for more information\n */\n filterFn?: FilterFunction<O, G>\n /** Whether the combobox is in multiselect mode, defaults to false */\n multiselect?: boolean\n}>()\n\nconst emit = defineEmits<ComboboxEmits>()\n\nconst model = defineModel<O[]>({ default: () => [] })\n\nconst slots = defineSlots<Omit<ComboboxSlots<O, G>, 'default'>>()\n\ndefineOptions({ inheritAttrs: false })\n\n/** A unique ID for the combobox */\nconst id = `scalar-combobox-items-${useId()}`\n\n/** A static option entry for the \"Add a new option\" option */\nconst addOption: Option = { id: `${useId()}-add`, label: 'Add a new option' }\n\n/** Generate a unique ID for an option */\nfunction getOptionId(option: Option) {\n return `${id}-${option.id}`\n}\n\n/** A flat list of all options */\nconst options = computed<O[]>(() =>\n isGroups(optionsOrGroups)\n ? optionsOrGroups.flatMap((group) => group.options)\n : optionsOrGroups,\n)\n\n/** An list of all groups */\nconst groups = computed<G[]>(\n () =>\n isGroups(optionsOrGroups)\n ? optionsOrGroups // G extends OptionGroup<O>\n : /*\n We know G is an unextended OptionGroup<O> here because of the\n structure of the component props so we can cast it to G\n */\n [{ label: '', options: optionsOrGroups } as G], // G is OptionGroup<O>\n)\n\nconst query = ref<string>('')\nconst activeRef = ref<Option | undefined>(model.value?.[0] ?? options.value[0])\n\n// Clear the query on open and close\nonMounted(() => {\n // Clear the query\n query.value = ''\n\n // Set the active option to the selected option or the first option\n activeRef.value = model.value?.[0] ?? options.value[0]\n\n // Scroll to the selected option\n const selected = model.value[0]\n if (selected) {\n setTimeout(() => {\n const value = model.value[0]\n if (!value) {\n return\n }\n\n document\n ?.getElementById(getOptionId(value))\n ?.scrollIntoView({ block: 'nearest' })\n }, 10)\n }\n})\n\n// Set the top option as active when searching\nwatch(\n () => query.value,\n () => (activeRef.value = withAdd.value[0]),\n)\n\n/** The filtered list of options */\nconst filtered = computed<O[]>(() =>\n filterFn(query.value, options.value, groups.value),\n)\n\n/** The list of filtered options with the \"Add a new option\" option */\nconst withAdd = computed<Option[]>(() =>\n slots.add ? [...filtered.value, addOption] : filtered.value,\n)\n\nfunction toggleSelected(option: Option | undefined) {\n if (!option) {\n return\n }\n\n if (option.id === addOption.id) {\n addNew()\n return\n }\n\n if (multiselect) {\n // Remove from selection list\n if (model.value.some((o) => o.id === option.id)) {\n model.value = model.value.filter((o) => o.id !== option.id)\n }\n // Add to selection list\n else {\n model.value = [\n ...model.value,\n options.value.find((o) => o.id === option.id)!,\n ]\n }\n } else {\n // Set selection for single select mode\n model.value = [options.value.find((o) => o.id === option.id)!]\n }\n}\n\nfunction moveActive(dir: 1 | -1) {\n const list = withAdd.value\n\n // Find active index\n const activeIdx = list.findIndex(\n (option) => option.id === activeRef.value?.id,\n )\n\n // Calculate next index and exit if it's out of bounds\n const nextIdx = activeIdx + dir\n\n if (nextIdx < 0 || nextIdx > list.length - 1) {\n return\n }\n\n activeRef.value = list[nextIdx]! // We know it's in bounds from the check above\n\n if (!activeRef.value) {\n return\n }\n\n // Scroll to the active option\n document?.getElementById(getOptionId(activeRef.value))?.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n })\n}\n\nfunction addNew() {\n emit('add')\n query.value = ''\n}\n\n// Manual autofocus for the input\nconst input = ref<HTMLInputElement | null>(null)\n\n// This must be a setTimeout to ensure there is no scroll jump. nextTick does not work here.\nonMounted(() => setTimeout(() => input.value?.focus(), 0))\n</script>\n<template>\n <div class=\"relative flex\">\n <ScalarIconMagnifyingGlass\n class=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-c-3 size-4\" />\n <input\n ref=\"input\"\n v-model=\"query\"\n :aria-activedescendant=\"activeRef ? getOptionId(activeRef) : undefined\"\n aria-autocomplete=\"list\"\n :aria-controls=\"id\"\n class=\"min-w-0 flex-1 rounded border-0 py-2.5 pl-8 pr-3 leading-none text-c-1 -outline-offset-1\"\n data-1p-ignore\n :placeholder\n role=\"combobox\"\n tabindex=\"0\"\n type=\"text\"\n @keydown.down.prevent=\"moveActive(1)\"\n @keydown.enter.prevent=\"activeRef && toggleSelected(activeRef)\"\n @keydown.up.prevent=\"moveActive(-1)\" />\n </div>\n <ul\n v-show=\"filtered.length || slots.add\"\n :id=\"id\"\n :aria-multiselectable=\"multiselect\"\n class=\"border-t p-0.75 custom-scroll overscroll-contain flex-1 min-h-0\"\n role=\"listbox\"\n tabindex=\"-1\">\n <ComboboxOptionGroup\n v-for=\"(group, i) in groups\"\n :id=\"`${id}-group-${i}`\"\n :key=\"i\"\n :hidden=\"\n // Only show the group label if there are some results\n !group.options.some((o) => filtered.some((f) => f.id === o.id)) ||\n // And it has a label\n !group.label\n \">\n <template #label>\n <slot\n v-if=\"$slots.group\"\n :group\n name=\"group\" />\n <template v-else>\n {{ group.label }}\n </template>\n </template>\n <template\n v-for=\"option in filtered\"\n :key=\"option.id\">\n <ComboboxOption\n v-if=\"group.options.some((o) => o.id === option.id)\"\n :id=\"getOptionId(option)\"\n v-slot=\"{ active, selected }\"\n :active=\"activeRef?.id === option.id\"\n :selected=\"model.some((o) => o.id === option.id)\"\n @click=\"toggleSelected(option)\"\n @mousedown.prevent\n @mouseenter=\"activeRef = option\">\n <slot\n v-if=\"$slots.option\"\n :active\n name=\"option\"\n :option\n :selected />\n <template v-else>\n <ScalarListboxCheckbox\n :multiselect\n :selected=\"model.some((o) => o.id === option.id)\" />\n <span class=\"inline-block min-w-0 flex-1 truncate text-c-1\">\n {{ option.label }}\n </span>\n </template>\n </ComboboxOption>\n </template>\n </ComboboxOptionGroup>\n <ComboboxOption\n v-if=\"slots.add\"\n :id=\"getOptionId(addOption)\"\n v-slot=\"{ active }\"\n :active=\"activeRef?.id === addOption.id\"\n @click=\"addNew\"\n @mousedown.prevent\n @mouseenter=\"activeRef = addOption\">\n <ScalarIconPlus class=\"size-4 p-px\" />\n <slot\n :active\n name=\"add\" />\n </ComboboxOption>\n </ul>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"ScalarComboboxOptions.vue.script.js","names":["$slots"],"sources":["../../../src/components/ScalarCombobox/ScalarComboboxOptions.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar Combobox Options component\n *\n * Renders the searchable option list for a combobox, including\n * filtering, keyboard navigation, and an optional \"add new\" action.\n *\n * @example\n * <ScalarComboboxOptions v-model=\"selected\" :options=\"options\" />\n */\nexport default {}\n</script>\n\n<!-- prettier-ignore-attribute generic -->\n<script\n setup\n lang=\"ts\"\n generic=\"O extends Option = Option, G extends OptionGroup<O> = OptionGroup<O>\">\nimport { filterByOptionLabel } from '@/components/ScalarCombobox/filter-by-option-label'\nimport { ScalarIconMagnifyingGlass, ScalarIconPlus } from '@scalar/icons'\nimport { computed, onMounted, ref, useId, watch } from 'vue'\n\nimport { ScalarListboxCheckbox } from '../ScalarListbox'\nimport ComboboxOption from './ScalarComboboxOption.vue'\nimport ComboboxOptionGroup from './ScalarComboboxOptionGroup.vue'\nimport {\n type ComboboxEmits,\n type ComboboxSlots,\n type FilterFunction,\n type Option,\n type OptionGroup,\n type OptionsOrGroups,\n isGroups,\n} from './types'\n\nconst {\n options: optionsOrGroups,\n placeholder,\n inputLabel,\n noResults,\n close,\n filterFn = filterByOptionLabel,\n multiselect,\n} = defineProps<{\n /** The options to display in the combobox */\n options: OptionsOrGroups<O, G>\n /** The placeholder text to display in the combobox */\n placeholder?: string\n /** An accessible label for the search input */\n inputLabel?: string\n /** The message to display when filtering returns no options */\n noResults?: string\n /** Close the popover without changing the current selection */\n close?: () => void\n /**\n * A function to filter the options based on a query,\n * if not provided, the options will be filtered by option label\n *\n * @see {@link FilterFunction} for more information\n */\n filterFn?: FilterFunction<O, G>\n /** Whether the combobox is in multiselect mode, defaults to false */\n multiselect?: boolean\n}>()\n\nconst emit = defineEmits<ComboboxEmits>()\n\nconst model = defineModel<O[]>({ default: () => [] })\n\nconst slots = defineSlots<Omit<ComboboxSlots<O, G>, 'default'>>()\n\ndefineOptions({ inheritAttrs: false })\n\n/** A unique ID for the combobox */\nconst id = `scalar-combobox-items-${useId()}`\n\n/** A static option entry for the \"Add a new option\" option */\nconst addOption: Option = { id: `${useId()}-add`, label: 'Add a new option' }\n\n/** Generate a unique ID for an option */\nfunction getOptionId(option: Option) {\n return `${id}-${option.id}`\n}\n\n/** A flat list of all options */\nconst options = computed<O[]>(() =>\n isGroups(optionsOrGroups)\n ? optionsOrGroups.flatMap((group) => group.options)\n : optionsOrGroups,\n)\n\n/** An list of all groups */\nconst groups = computed<G[]>(\n () =>\n isGroups(optionsOrGroups)\n ? optionsOrGroups // G extends OptionGroup<O>\n : /*\n We know G is an unextended OptionGroup<O> here because of the\n structure of the component props so we can cast it to G\n */\n [{ label: '', options: optionsOrGroups } as G], // G is OptionGroup<O>\n)\n\nconst query = ref<string>('')\nconst activeRef = ref<Option | undefined>(model.value?.[0] ?? options.value[0])\n\n// Clear the query on open and close\nonMounted(() => {\n // Clear the query\n query.value = ''\n\n // Set the active option to the selected option or the first option\n activeRef.value = model.value?.[0] ?? options.value[0]\n\n // Scroll to the selected option\n const selected = model.value[0]\n if (selected) {\n setTimeout(() => {\n const value = model.value[0]\n if (!value) {\n return\n }\n\n document\n ?.getElementById(getOptionId(value))\n ?.scrollIntoView({ block: 'nearest' })\n }, 10)\n }\n})\n\n// Set the top option as active when searching\nwatch(\n () => query.value,\n () => (activeRef.value = withAdd.value[0]),\n)\n\n/** The filtered list of options */\nconst filtered = computed<O[]>(() =>\n filterFn(query.value, options.value, groups.value),\n)\n\n/** The list of filtered options with the \"Add a new option\" option */\nconst withAdd = computed<Option[]>(() =>\n slots.add ? [...filtered.value, addOption] : filtered.value,\n)\n\nfunction toggleSelected(option: Option | undefined) {\n if (!option) {\n return\n }\n\n if (option.id === addOption.id) {\n addNew()\n return\n }\n\n if (multiselect) {\n // Remove from selection list\n if (model.value.some((o) => o.id === option.id)) {\n model.value = model.value.filter((o) => o.id !== option.id)\n }\n // Add to selection list\n else {\n model.value = [\n ...model.value,\n options.value.find((o) => o.id === option.id)!,\n ]\n }\n } else {\n // Set selection for single select mode\n model.value = [options.value.find((o) => o.id === option.id)!]\n }\n}\n\nfunction moveActive(dir: 1 | -1) {\n const list = withAdd.value\n\n // Find active index\n const activeIdx = list.findIndex(\n (option) => option.id === activeRef.value?.id,\n )\n\n // Calculate next index and exit if it's out of bounds\n const nextIdx = activeIdx + dir\n\n if (nextIdx < 0 || nextIdx > list.length - 1) {\n return\n }\n\n activeRef.value = list[nextIdx]! // We know it's in bounds from the check above\n\n if (!activeRef.value) {\n return\n }\n\n // Scroll to the active option\n document?.getElementById(getOptionId(activeRef.value))?.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n })\n}\n\nfunction addNew() {\n emit('add')\n query.value = ''\n}\n\n// Manual autofocus for the input\nconst input = ref<HTMLInputElement | null>(null)\n\n// This must be a setTimeout to ensure there is no scroll jump. nextTick does not work here.\nonMounted(() => setTimeout(() => input.value?.focus(), 0))\n</script>\n<template>\n <div class=\"relative flex\">\n <ScalarIconMagnifyingGlass\n class=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-c-3 size-4\" />\n <input\n ref=\"input\"\n v-model=\"query\"\n :aria-activedescendant=\"activeRef ? getOptionId(activeRef) : undefined\"\n aria-autocomplete=\"list\"\n :aria-controls=\"id\"\n :aria-label=\"inputLabel\"\n class=\"min-w-0 flex-1 rounded border-0 py-2.5 pl-8 pr-3 leading-none text-c-1 -outline-offset-1\"\n data-1p-ignore\n :placeholder\n role=\"combobox\"\n tabindex=\"0\"\n type=\"text\"\n @keydown.down.prevent=\"moveActive(1)\"\n @keydown.enter.prevent=\"activeRef && toggleSelected(activeRef)\"\n @keydown.esc.prevent=\"close?.()\"\n @keydown.up.prevent=\"moveActive(-1)\" />\n </div>\n <ul\n v-show=\"filtered.length || slots.add || noResults\"\n :id=\"id\"\n :aria-multiselectable=\"multiselect\"\n class=\"border-t p-0.75 custom-scroll overscroll-contain flex-1 min-h-0\"\n role=\"listbox\"\n tabindex=\"-1\">\n <li\n v-if=\"!filtered.length && !slots.add && noResults\"\n class=\"text-c-3 px-2.5 py-2\"\n role=\"status\">\n {{ noResults }}\n </li>\n <ComboboxOptionGroup\n v-for=\"(group, i) in groups\"\n :id=\"`${id}-group-${i}`\"\n :key=\"i\"\n :hidden=\"\n // Only show the group label if there are some results\n !group.options.some((o) => filtered.some((f) => f.id === o.id)) ||\n // And it has a label\n !group.label\n \">\n <template #label>\n <slot\n v-if=\"$slots.group\"\n :group\n name=\"group\" />\n <template v-else>\n {{ group.label }}\n </template>\n </template>\n <template\n v-for=\"option in filtered\"\n :key=\"option.id\">\n <ComboboxOption\n v-if=\"group.options.some((o) => o.id === option.id)\"\n :id=\"getOptionId(option)\"\n v-slot=\"{ active, selected }\"\n :active=\"activeRef?.id === option.id\"\n :selected=\"model.some((o) => o.id === option.id)\"\n @click=\"toggleSelected(option)\"\n @mousedown.prevent\n @mouseenter=\"activeRef = option\">\n <slot\n v-if=\"$slots.option\"\n :active\n name=\"option\"\n :option\n :selected />\n <template v-else>\n <ScalarListboxCheckbox\n :multiselect\n :selected=\"model.some((o) => o.id === option.id)\" />\n <span class=\"inline-block min-w-0 flex-1 truncate text-c-1\">\n {{ option.label }}\n </span>\n </template>\n </ComboboxOption>\n </template>\n </ComboboxOptionGroup>\n <ComboboxOption\n v-if=\"slots.add\"\n :id=\"getOptionId(addOption)\"\n v-slot=\"{ active }\"\n :active=\"activeRef?.id === addOption.id\"\n @click=\"addNew\"\n @mousedown.prevent\n @mouseenter=\"activeRef = addOption\">\n <ScalarIconPlus class=\"size-4 p-px\" />\n <slot\n :active\n name=\"add\" />\n </ComboboxOption>\n </ul>\n</template>\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../_virtual/_plugin-vue_export
2
2
  import ScalarDropdownButton_vue_vue_type_script_setup_true_lang_default from "./ScalarDropdownButton.vue.script.js";
3
3
  /* empty css */
4
4
  //#region src/components/ScalarDropdown/ScalarDropdownButton.vue
5
- var ScalarDropdownButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ScalarDropdownButton_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-f5e0d3d8"]]);
5
+ var ScalarDropdownButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ScalarDropdownButton_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-128eed00"]]);
6
6
  //#endregion
7
7
  export { ScalarDropdownButton_default as default };
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarDropdownButton.vue.js","names":[],"sources":["../../../src/components/ScalarDropdown/ScalarDropdownButton.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar dropdown button base component\n *\n * Provide a styled button for the ScalarDropdown or similar\n *\n * This is used internally by the ScalarDropdownItem component\n *\n * If you're looking to add items to a dropdown menu you\n * probably want the ScalarDropdownItem component\n *\n * @example\n * <ScalarDropdownButton @click=\"handleClick\">\n * Label\n * </ScalarDropdownButton>\n */\nexport default {}\n</script>\n<script setup lang=\"ts\">\nimport { cva, cx } from '@scalar/use-hooks/useBindCx'\nimport type { Component } from 'vue'\n\nconst { is = 'button' } = defineProps<{\n is?: string | Component\n active?: boolean\n disabled?: boolean\n}>()\n\nconst variants = cva({\n base: [\n // Layout\n 'block h-8 min-w-0 gap-1.5 rounded px-2.5 py-1.5 text-left',\n // Text / background style\n 'truncate no-underline text-sm text-c-1',\n // Interaction — hover:bg-b-2 handles mouse, highlighted:bg-b-2 handles\n // Radix keyboard navigation and mouse-hover within Radix menu items\n 'cursor-pointer hover:bg-b-2 highlighted:bg-b-2',\n ],\n variants: {\n disabled: { true: 'pointer-events-none text-c-3' },\n active: { true: '' },\n },\n compoundVariants: [{ disabled: false, active: true, class: 'bg-b-2' }],\n})\n</script>\n<template>\n <component\n :is=\"is\"\n :aria-disabled=\"disabled\"\n class=\"item\"\n :class=\"cx('scalar-dropdown-item', variants({ active, disabled }))\"\n :type=\"is === 'button' ? 'button' : undefined\">\n <slot />\n </component>\n</template>\n<style scoped>\n.dark-mode .scalar-dropdown-item:hover,\n.dark-mode .scalar-dropdown-item[data-highlighted] {\n filter: brightness(1.1);\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"ScalarDropdownButton.vue.js","names":[],"sources":["../../../src/components/ScalarDropdown/ScalarDropdownButton.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar dropdown button base component\n *\n * Provide a styled button for the ScalarDropdown or similar\n *\n * This is used internally by the ScalarDropdownItem component\n *\n * If you're looking to add items to a dropdown menu you\n * probably want the ScalarDropdownItem component\n *\n * @example\n * <ScalarDropdownButton @click=\"handleClick\">\n * Label\n * </ScalarDropdownButton>\n */\nexport default {}\n</script>\n<script setup lang=\"ts\">\nimport { cva, cx } from '@scalar/use-hooks/useBindCx'\nimport type { Component } from 'vue'\n\nconst { is = 'button' } = defineProps<{\n is?: string | Component\n active?: boolean\n disabled?: boolean\n}>()\n\nconst variants = cva({\n base: [\n // Layout\n 'block h-8 min-w-0 gap-1.5 rounded-md px-2.5 py-1.5 text-left',\n // Text / background style\n 'truncate no-underline text-sm text-c-1',\n // Interaction — hover:bg-b-2 handles mouse, highlighted:bg-b-2 handles\n // Radix keyboard navigation and mouse-hover within Radix menu items\n 'cursor-pointer hover:bg-b-2 highlighted:bg-b-2',\n ],\n variants: {\n disabled: { true: 'pointer-events-none text-c-3' },\n active: { true: '' },\n },\n compoundVariants: [{ disabled: false, active: true, class: 'bg-b-2' }],\n})\n</script>\n<template>\n <component\n :is=\"is\"\n :aria-disabled=\"disabled\"\n class=\"item\"\n :class=\"cx('scalar-dropdown-item', variants({ active, disabled }))\"\n :type=\"is === 'button' ? 'button' : undefined\">\n <slot />\n </component>\n</template>\n<style scoped>\n.dark-mode .scalar-dropdown-item:hover,\n.dark-mode .scalar-dropdown-item[data-highlighted] {\n filter: brightness(1.1);\n}\n</style>\n"],"mappings":""}
@@ -10,7 +10,7 @@ var ScalarDropdownButton_vue_vue_type_script_setup_true_lang_default = /*@__PURE
10
10
  setup(__props) {
11
11
  const variants = cva({
12
12
  base: [
13
- "block h-8 min-w-0 gap-1.5 rounded px-2.5 py-1.5 text-left",
13
+ "block h-8 min-w-0 gap-1.5 rounded-md px-2.5 py-1.5 text-left",
14
14
  "truncate no-underline text-sm text-c-1",
15
15
  "cursor-pointer hover:bg-b-2 highlighted:bg-b-2"
16
16
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarDropdownButton.vue.script.js","names":[],"sources":["../../../src/components/ScalarDropdown/ScalarDropdownButton.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar dropdown button base component\n *\n * Provide a styled button for the ScalarDropdown or similar\n *\n * This is used internally by the ScalarDropdownItem component\n *\n * If you're looking to add items to a dropdown menu you\n * probably want the ScalarDropdownItem component\n *\n * @example\n * <ScalarDropdownButton @click=\"handleClick\">\n * Label\n * </ScalarDropdownButton>\n */\nexport default {}\n</script>\n<script setup lang=\"ts\">\nimport { cva, cx } from '@scalar/use-hooks/useBindCx'\nimport type { Component } from 'vue'\n\nconst { is = 'button' } = defineProps<{\n is?: string | Component\n active?: boolean\n disabled?: boolean\n}>()\n\nconst variants = cva({\n base: [\n // Layout\n 'block h-8 min-w-0 gap-1.5 rounded px-2.5 py-1.5 text-left',\n // Text / background style\n 'truncate no-underline text-sm text-c-1',\n // Interaction — hover:bg-b-2 handles mouse, highlighted:bg-b-2 handles\n // Radix keyboard navigation and mouse-hover within Radix menu items\n 'cursor-pointer hover:bg-b-2 highlighted:bg-b-2',\n ],\n variants: {\n disabled: { true: 'pointer-events-none text-c-3' },\n active: { true: '' },\n },\n compoundVariants: [{ disabled: false, active: true, class: 'bg-b-2' }],\n})\n</script>\n<template>\n <component\n :is=\"is\"\n :aria-disabled=\"disabled\"\n class=\"item\"\n :class=\"cx('scalar-dropdown-item', variants({ active, disabled }))\"\n :type=\"is === 'button' ? 'button' : undefined\">\n <slot />\n </component>\n</template>\n<style scoped>\n.dark-mode .scalar-dropdown-item:hover,\n.dark-mode .scalar-dropdown-item[data-highlighted] {\n filter: brightness(1.1);\n}\n</style>\n"],"mappings":";;;;;;;;;;EA4BA,MAAM,WAAW,IAAI;GACnB,MAAM;IAEJ;IAEA;IAGA;GACF;GACA,UAAU;IACR,UAAU,EAAE,MAAM,+BAA+B;IACjD,QAAQ,EAAE,MAAM,GAAG;GACrB;GACA,kBAAkB,CAAC;IAAE,UAAU;IAAO,QAAQ;IAAM,OAAO;GAAS,CAAC;EACvE,CAAC;;uBAGC,YAOY,wBANL,QAAA,EAAE,GAAA;IACN,iBAAe,QAAA;IAChB,OAAK,eAAA,CAAC,QACE,MAAA,EAAA,CAAE,CAAA,wBAAyB,MAAA,QAAA,CAAQ,CAAA;KAAA,QAAG,QAAA;KAAM,UAAE,QAAA;IAAQ,CAAA,CAAA,CAAA,CAAA;IAC7D,MAAM,QAAA,OAAE,WAAA,WAA2B,KAAA;;2BAC5B,CAAR,WAAQ,KAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,IAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"ScalarDropdownButton.vue.script.js","names":[],"sources":["../../../src/components/ScalarDropdown/ScalarDropdownButton.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar dropdown button base component\n *\n * Provide a styled button for the ScalarDropdown or similar\n *\n * This is used internally by the ScalarDropdownItem component\n *\n * If you're looking to add items to a dropdown menu you\n * probably want the ScalarDropdownItem component\n *\n * @example\n * <ScalarDropdownButton @click=\"handleClick\">\n * Label\n * </ScalarDropdownButton>\n */\nexport default {}\n</script>\n<script setup lang=\"ts\">\nimport { cva, cx } from '@scalar/use-hooks/useBindCx'\nimport type { Component } from 'vue'\n\nconst { is = 'button' } = defineProps<{\n is?: string | Component\n active?: boolean\n disabled?: boolean\n}>()\n\nconst variants = cva({\n base: [\n // Layout\n 'block h-8 min-w-0 gap-1.5 rounded-md px-2.5 py-1.5 text-left',\n // Text / background style\n 'truncate no-underline text-sm text-c-1',\n // Interaction — hover:bg-b-2 handles mouse, highlighted:bg-b-2 handles\n // Radix keyboard navigation and mouse-hover within Radix menu items\n 'cursor-pointer hover:bg-b-2 highlighted:bg-b-2',\n ],\n variants: {\n disabled: { true: 'pointer-events-none text-c-3' },\n active: { true: '' },\n },\n compoundVariants: [{ disabled: false, active: true, class: 'bg-b-2' }],\n})\n</script>\n<template>\n <component\n :is=\"is\"\n :aria-disabled=\"disabled\"\n class=\"item\"\n :class=\"cx('scalar-dropdown-item', variants({ active, disabled }))\"\n :type=\"is === 'button' ? 'button' : undefined\">\n <slot />\n </component>\n</template>\n<style scoped>\n.dark-mode .scalar-dropdown-item:hover,\n.dark-mode .scalar-dropdown-item[data-highlighted] {\n filter: brightness(1.1);\n}\n</style>\n"],"mappings":";;;;;;;;;;EA4BA,MAAM,WAAW,IAAI;GACnB,MAAM;IAEJ;IAEA;IAGA;GACF;GACA,UAAU;IACR,UAAU,EAAE,MAAM,+BAA+B;IACjD,QAAQ,EAAE,MAAM,GAAG;GACrB;GACA,kBAAkB,CAAC;IAAE,UAAU;IAAO,QAAQ;IAAM,OAAO;GAAS,CAAC;EACvE,CAAC;;uBAGC,YAOY,wBANL,QAAA,EAAE,GAAA;IACN,iBAAe,QAAA;IAChB,OAAK,eAAA,CAAC,QACE,MAAA,EAAA,CAAE,CAAA,wBAAyB,MAAA,QAAA,CAAQ,CAAA;KAAA,QAAG,QAAA;KAAM,UAAE,QAAA;IAAQ,CAAA,CAAA,CAAA,CAAA;IAC7D,MAAM,QAAA,OAAE,WAAA,WAA2B,KAAA;;2BAC5B,CAAR,WAAQ,KAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,IAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarDropdownMenu.vue.d.ts","sourceRoot":"","sources":["../../../src/components/ScalarDropdown/ScalarDropdownMenu.vue"],"names":[],"mappings":"AAgEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,KAAK,CAAA;AAKpC;;;;;;;;;;;;;;GAcG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY;IAEhB,8BAA8B;SACzB,MAAM,GAAG,SAAS;;IADvB,8BAA8B;SACzB,MAAM,GAAG,SAAS;;IAKvB,wBAAwB;gBACZ,OAAO;IACnB,6CAA6C;aACpC,OAAO;IAChB,8CAA8C;iBACjC,OAAO;EAwElB,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"ScalarDropdownMenu.vue.d.ts","sourceRoot":"","sources":["../../../src/components/ScalarDropdown/ScalarDropdownMenu.vue"],"names":[],"mappings":"AAgEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,KAAK,CAAA;AAKpC;;;;;;;;;;;;;;GAcG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY;IAEhB,8BAA8B;SACzB,MAAM,GAAG,SAAS;;IADvB,8BAA8B;SACzB,MAAM,GAAG,SAAS;;IAKvB,wBAAwB;gBACZ,OAAO;IACnB,6CAA6C;aACpC,OAAO;IAChB,8CAA8C;iBACjC,OAAO;EA6ElB,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarDropdownMenu.vue.js","names":[],"sources":["../../../src/components/ScalarDropdown/ScalarDropdownMenu.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar dropdown menu component\n *\n * Provides a scrollable container for dropdown items\n * This is used internally by the ScalarDropdown component\n *\n * If you're looking to create a dropdown menu with a trigger\n * button you probably want the ScalarDropdown component\n *\n * @example\n * <ScalarDropdownMenu>\n * <ScalarDropdownItem>Item 1</ScalarDropdownItem>\n * <ScalarDropdownItem>Item 2</ScalarDropdownItem>\n * </ScalarDropdownMenu>\n */\nexport default {}\n</script>\n<script setup lang=\"ts\">\nimport { useBindCx } from '@scalar/use-hooks/useBindCx'\nimport { type Component } from 'vue'\n\nimport { ScalarFloatingBackdrop } from '../ScalarFloating'\n\ndefineProps<{\n /** The component to render */\n is?: string | Component\n}>()\n\ndefineSlots<{\n /** The menu contents */\n default?(): unknown\n /** Overrides the normal menu list element */\n menu?(): unknown\n /** Overrides the backdrop for the dropdown */\n backdrop?(): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\nconst { cx } = useBindCx()\n</script>\n<template>\n <!-- Background container -->\n <component\n :is=\"is ?? 'div'\"\n v-bind=\"cx('relative flex w-56')\">\n <!-- Scroll container -->\n <div class=\"custom-scroll min-h-0 flex-1\">\n <!-- Menu items -->\n <slot name=\"menu\">\n <div class=\"flex flex-col p-0.75\">\n <slot />\n </div>\n </slot>\n <slot name=\"backdrop\">\n <ScalarFloatingBackdrop />\n </slot>\n </div>\n </component>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"ScalarDropdownMenu.vue.js","names":[],"sources":["../../../src/components/ScalarDropdown/ScalarDropdownMenu.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar dropdown menu component\n *\n * Provides a scrollable container for dropdown items\n * This is used internally by the ScalarDropdown component\n *\n * If you're looking to create a dropdown menu with a trigger\n * button you probably want the ScalarDropdown component\n *\n * @example\n * <ScalarDropdownMenu>\n * <ScalarDropdownItem>Item 1</ScalarDropdownItem>\n * <ScalarDropdownItem>Item 2</ScalarDropdownItem>\n * </ScalarDropdownMenu>\n */\nexport default {}\n</script>\n<script setup lang=\"ts\">\nimport { useBindCx } from '@scalar/use-hooks/useBindCx'\nimport { type Component } from 'vue'\n\nimport { ScalarFloatingBackdrop } from '../ScalarFloating'\n\ndefineProps<{\n /** The component to render */\n is?: string | Component\n}>()\n\ndefineSlots<{\n /** The menu contents */\n default?(): unknown\n /** Overrides the normal menu list element */\n menu?(): unknown\n /** Overrides the backdrop for the dropdown */\n backdrop?(): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\nconst { cx } = useBindCx()\n</script>\n<template>\n <!-- Background container -->\n <component\n :is=\"is ?? 'div'\"\n v-bind=\"cx('relative flex w-56')\">\n <!-- Scroll container -->\n <div class=\"custom-scroll min-h-0 flex-1\">\n <!-- Menu items -->\n <slot name=\"menu\">\n <div class=\"flex flex-col p-0.75\">\n <slot />\n </div>\n </slot>\n <slot name=\"backdrop\">\n <ScalarFloatingBackdrop class=\"rounded-xl border shadow-md\" />\n </slot>\n </div>\n </component>\n</template>\n"],"mappings":""}
@@ -12,7 +12,7 @@ var ScalarDropdownMenu_vue_vue_type_script_setup_true_lang_default = /*@__PURE__
12
12
  const { cx } = useBindCx();
13
13
  return (_ctx, _cache) => {
14
14
  return openBlock(), createBlock(resolveDynamicComponent(__props.is ?? "div"), normalizeProps(guardReactiveProps(unref(cx)("relative flex w-56"))), {
15
- default: withCtx(() => [createElementVNode("div", _hoisted_1, [renderSlot(_ctx.$slots, "menu", {}, () => [createElementVNode("div", _hoisted_2, [renderSlot(_ctx.$slots, "default")])]), renderSlot(_ctx.$slots, "backdrop", {}, () => [createVNode(unref(ScalarFloatingBackdrop_default))])])]),
15
+ default: withCtx(() => [createElementVNode("div", _hoisted_1, [renderSlot(_ctx.$slots, "menu", {}, () => [createElementVNode("div", _hoisted_2, [renderSlot(_ctx.$slots, "default")])]), renderSlot(_ctx.$slots, "backdrop", {}, () => [createVNode(unref(ScalarFloatingBackdrop_default), { class: "rounded-xl border shadow-md" })])])]),
16
16
  _: 3
17
17
  }, 16);
18
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ScalarDropdownMenu.vue.script.js","names":[],"sources":["../../../src/components/ScalarDropdown/ScalarDropdownMenu.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar dropdown menu component\n *\n * Provides a scrollable container for dropdown items\n * This is used internally by the ScalarDropdown component\n *\n * If you're looking to create a dropdown menu with a trigger\n * button you probably want the ScalarDropdown component\n *\n * @example\n * <ScalarDropdownMenu>\n * <ScalarDropdownItem>Item 1</ScalarDropdownItem>\n * <ScalarDropdownItem>Item 2</ScalarDropdownItem>\n * </ScalarDropdownMenu>\n */\nexport default {}\n</script>\n<script setup lang=\"ts\">\nimport { useBindCx } from '@scalar/use-hooks/useBindCx'\nimport { type Component } from 'vue'\n\nimport { ScalarFloatingBackdrop } from '../ScalarFloating'\n\ndefineProps<{\n /** The component to render */\n is?: string | Component\n}>()\n\ndefineSlots<{\n /** The menu contents */\n default?(): unknown\n /** Overrides the normal menu list element */\n menu?(): unknown\n /** Overrides the backdrop for the dropdown */\n backdrop?(): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\nconst { cx } = useBindCx()\n</script>\n<template>\n <!-- Background container -->\n <component\n :is=\"is ?? 'div'\"\n v-bind=\"cx('relative flex w-56')\">\n <!-- Scroll container -->\n <div class=\"custom-scroll min-h-0 flex-1\">\n <!-- Menu items -->\n <slot name=\"menu\">\n <div class=\"flex flex-col p-0.75\">\n <slot />\n </div>\n </slot>\n <slot name=\"backdrop\">\n <ScalarFloatingBackdrop />\n </slot>\n </div>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;EAuCA,MAAM,EAAE,OAAO,UAAU;;uBAIvB,YAeY,wBAdL,QAAA,MAAE,KAAA,GAAA,eAAA,mBACC,MAAA,EAAA,CAAE,CAAA,oBAAA,CAAA,CAAA,GAAA;2BAYJ,CAVN,mBAUM,OAVN,YAUM,CARJ,WAIO,KAAA,QAAA,QAAA,CAAA,SAAA,CAHL,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA,CAAA,CAAA,GAGZ,WAEO,KAAA,QAAA,YAAA,CAAA,SAAA,CADL,YAA0B,MAAA,8BAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"ScalarDropdownMenu.vue.script.js","names":[],"sources":["../../../src/components/ScalarDropdown/ScalarDropdownMenu.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Scalar dropdown menu component\n *\n * Provides a scrollable container for dropdown items\n * This is used internally by the ScalarDropdown component\n *\n * If you're looking to create a dropdown menu with a trigger\n * button you probably want the ScalarDropdown component\n *\n * @example\n * <ScalarDropdownMenu>\n * <ScalarDropdownItem>Item 1</ScalarDropdownItem>\n * <ScalarDropdownItem>Item 2</ScalarDropdownItem>\n * </ScalarDropdownMenu>\n */\nexport default {}\n</script>\n<script setup lang=\"ts\">\nimport { useBindCx } from '@scalar/use-hooks/useBindCx'\nimport { type Component } from 'vue'\n\nimport { ScalarFloatingBackdrop } from '../ScalarFloating'\n\ndefineProps<{\n /** The component to render */\n is?: string | Component\n}>()\n\ndefineSlots<{\n /** The menu contents */\n default?(): unknown\n /** Overrides the normal menu list element */\n menu?(): unknown\n /** Overrides the backdrop for the dropdown */\n backdrop?(): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\nconst { cx } = useBindCx()\n</script>\n<template>\n <!-- Background container -->\n <component\n :is=\"is ?? 'div'\"\n v-bind=\"cx('relative flex w-56')\">\n <!-- Scroll container -->\n <div class=\"custom-scroll min-h-0 flex-1\">\n <!-- Menu items -->\n <slot name=\"menu\">\n <div class=\"flex flex-col p-0.75\">\n <slot />\n </div>\n </slot>\n <slot name=\"backdrop\">\n <ScalarFloatingBackdrop class=\"rounded-xl border shadow-md\" />\n </slot>\n </div>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;EAuCA,MAAM,EAAE,OAAO,UAAU;;uBAIvB,YAeY,wBAdL,QAAA,MAAE,KAAA,GAAA,eAAA,mBACC,MAAA,EAAA,CAAE,CAAA,oBAAA,CAAA,CAAA,GAAA;2BAYJ,CAVN,mBAUM,OAVN,YAUM,CARJ,WAIO,KAAA,QAAA,QAAA,CAAA,SAAA,CAHL,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA,CAAA,CAAA,GAGZ,WAEO,KAAA,QAAA,YAAA,CAAA,SAAA,CADL,YAA8D,MAAA,8BAAA,GAAA,EAAtC,OAAM,8BAA6B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA"}
package/dist/style.css CHANGED
@@ -3764,8 +3764,8 @@ to {
3764
3764
  transform: translate3d(0, 0, 0);
3765
3765
  }
3766
3766
 
3767
- .dark-mode .scalar-dropdown-item[data-v-f5e0d3d8]:hover,
3768
- .dark-mode .scalar-dropdown-item[data-highlighted][data-v-f5e0d3d8] {
3767
+ .dark-mode .scalar-dropdown-item[data-v-128eed00]:hover,
3768
+ .dark-mode .scalar-dropdown-item[data-highlighted][data-v-128eed00] {
3769
3769
  filter: brightness(1.1);
3770
3770
  }
3771
3771
 
@@ -270,8 +270,8 @@ to {
270
270
  transform: translate3d(0, 0, 0);
271
271
  }
272
272
 
273
- .dark-mode .scalar-dropdown-item[data-v-f5e0d3d8]:hover,
274
- .dark-mode .scalar-dropdown-item[data-highlighted][data-v-f5e0d3d8] {
273
+ .dark-mode .scalar-dropdown-item[data-v-128eed00]:hover,
274
+ .dark-mode .scalar-dropdown-item[data-highlighted][data-v-128eed00] {
275
275
  filter: brightness(1.1);
276
276
  }
277
277
 
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "git+https://github.com/scalar/scalar.git",
11
11
  "directory": "packages/components"
12
12
  },
13
- "version": "0.29.2",
13
+ "version": "0.30.0",
14
14
  "engines": {
15
15
  "node": ">=22"
16
16
  },
@@ -216,16 +216,16 @@
216
216
  "@floating-ui/vue": "1.1.9",
217
217
  "@headlessui/tailwindcss": "^0.2.2",
218
218
  "@headlessui/vue": "1.7.23",
219
+ "@scalar/code-highlight": "0.4.6",
220
+ "@scalar/helpers": "0.12.0",
221
+ "@scalar/icons": "0.7.6",
222
+ "@scalar/themes": "0.18.0",
223
+ "@scalar/use-hooks": "0.4.12",
219
224
  "@vueuse/core": "13.9.0",
220
225
  "cva": "1.0.0-beta.4",
221
226
  "radix-vue": "^1.9.17",
222
227
  "vue": "^3.5.40",
223
- "vue-component-type-helpers": "^3.2.6",
224
- "@scalar/code-highlight": "0.4.6",
225
- "@scalar/icons": "0.7.6",
226
- "@scalar/helpers": "0.12.0",
227
- "@scalar/themes": "0.18.0",
228
- "@scalar/use-hooks": "0.4.12"
228
+ "vue-component-type-helpers": "^3.2.6"
229
229
  },
230
230
  "devDependencies": {
231
231
  "@playwright/test": "1.62.1",