@sparklingopinions/sparkling-ui 0.14.0 → 0.16.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 (100) hide show
  1. package/README.md +1 -1
  2. package/dist/aliases.d.ts +4 -0
  3. package/dist/components/ActionBar/ActionBar.js.map +1 -1
  4. package/dist/components/ActionBar/ActionBar.vue_vue_type_script_setup_true_lang.js +1 -1
  5. package/dist/components/ActionBar/ActionBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/Alert/Alert.js.map +1 -1
  7. package/dist/components/Alert/Alert.vue_vue_type_script_setup_true_lang.js +1 -1
  8. package/dist/components/Alert/Alert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/AlertDialog/AlertDialog.js.map +1 -1
  10. package/dist/components/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js +5 -5
  11. package/dist/components/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  12. package/dist/components/Avatar/Avatar.js.map +1 -1
  13. package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +1 -1
  14. package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/Badge/Badge.js.map +1 -1
  16. package/dist/components/Badge/Badge.vue_vue_type_script_setup_true_lang.js +1 -1
  17. package/dist/components/Badge/Badge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  18. package/dist/components/Board/Board.js.map +1 -1
  19. package/dist/components/Board/Board.vue.d.ts +3 -0
  20. package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js +68 -63
  21. package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/Button/Button.js.map +1 -1
  23. package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js +23 -22
  24. package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/Calendar/Calendar.js.map +1 -1
  26. package/dist/components/Calendar/Calendar.vue_vue_type_script_setup_true_lang.js +3 -3
  27. package/dist/components/Calendar/Calendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  28. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  29. package/dist/components/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js +1 -1
  30. package/dist/components/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  31. package/dist/components/DataList/DataList.js.map +1 -1
  32. package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js +103 -103
  33. package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/Dialog/ContextSeparator.js +19 -0
  35. package/dist/components/Dialog/ContextSeparator.js.map +1 -0
  36. package/dist/components/Dialog/ContextSeparator.vue.d.ts +3 -0
  37. package/dist/components/Dialog/Dialog.js.map +1 -1
  38. package/dist/components/Dialog/Dialog.vue.d.ts +16 -11
  39. package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +130 -119
  40. package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/Dialog/focus.d.ts +2 -0
  42. package/dist/components/Dialog/focus.js +2 -2
  43. package/dist/components/Dialog/focus.js.map +1 -1
  44. package/dist/components/EmptyState/EmptyState.js.map +1 -1
  45. package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +1 -1
  46. package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  47. package/dist/components/Filters/FilterChip.js.map +1 -1
  48. package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js +7 -7
  49. package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  50. package/dist/components/Filters/FilterFrame.js.map +1 -1
  51. package/dist/components/Filters/FilterFrame.vue_vue_type_script_setup_true_lang.js +1 -1
  52. package/dist/components/Filters/FilterFrame.vue_vue_type_script_setup_true_lang.js.map +1 -1
  53. package/dist/components/Filters/FilterMenu.js.map +1 -1
  54. package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js +3 -3
  55. package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  56. package/dist/components/Filters/SortMenu.js.map +1 -1
  57. package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js +7 -7
  58. package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  59. package/dist/components/Input/Input.js.map +1 -1
  60. package/dist/components/Input/Input.vue_vue_type_script_setup_true_lang.js +1 -1
  61. package/dist/components/Input/Input.vue_vue_type_script_setup_true_lang.js.map +1 -1
  62. package/dist/components/Kbd/Kbd.js +1 -1
  63. package/dist/components/Kbd/Kbd.js.map +1 -1
  64. package/dist/components/Pagination/Pagination.js.map +1 -1
  65. package/dist/components/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js +1 -1
  66. package/dist/components/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  67. package/dist/components/Popover/Popover.js.map +1 -1
  68. package/dist/components/Popover/Popover.vue_vue_type_script_setup_true_lang.js +1 -1
  69. package/dist/components/Popover/Popover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  70. package/dist/components/Popover/PopoverDialog.js.map +1 -1
  71. package/dist/components/Popover/PopoverDialog.vue_vue_type_script_setup_true_lang.js +1 -1
  72. package/dist/components/Popover/PopoverDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  73. package/dist/components/PropertyList/Editable.js.map +1 -1
  74. package/dist/components/PropertyList/Editable.vue_vue_type_script_setup_true_lang.js +2 -2
  75. package/dist/components/PropertyList/Editable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  76. package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
  77. package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +2 -2
  78. package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
  79. package/dist/components/Select/Select.js.map +1 -1
  80. package/dist/components/Select/Select.vue_vue_type_script_setup_true_lang.js +4 -4
  81. package/dist/components/Select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -1
  82. package/dist/components/Skeleton/Skeleton.js.map +1 -1
  83. package/dist/components/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js +1 -1
  84. package/dist/components/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  85. package/dist/components/Table/Table.js.map +1 -1
  86. package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js +3 -3
  87. package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/Tag/Tag.js.map +1 -1
  89. package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js +3 -3
  90. package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/components/Textarea/Textarea.js.map +1 -1
  92. package/dist/components/Textarea/Textarea.vue.d.ts +3 -0
  93. package/dist/components/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js +7 -2
  94. package/dist/components/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/internal/menu.d.ts +2 -2
  96. package/dist/components/internal/menu.js +1 -1
  97. package/dist/components/internal/menu.js.map +1 -1
  98. package/dist/index.js +15 -15
  99. package/package.json +1 -1
  100. package/src/styles/tailwind.css +93 -12
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_normalizeClass","_withCtx","_createElementBlock","_Fragment","_renderList","Icon","_createElementVNode","_createCommentVNode","_toDisplayString","Icon_default","_hoisted_1","_hoisted_2","_hoisted_3","SegmentedControl_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","model","useModel","__props","openBlock","createBlock","unref","RadioGroupRoot","_cache","$event","normalizeClass","withCtx","createElementBlock","Fragment","renderList","RadioGroupItem","option","createElementVNode","createCommentVNode","toDisplayString"],"sources":["../../../src/components/SegmentedControl/SegmentedControl.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends string\">\nimport { RadioGroupItem, RadioGroupRoot } from 'reka-ui'\n\nimport Icon from '../Icon/Icon.vue'\n\nexport interface SegmentedControlOption<T extends string> {\n value: T\n label: string\n /** An Icon name. */\n iconName?: string\n /** An SVG path on a 24px grid. */\n icon?: string\n}\n\nexport interface SegmentedControlProps<T extends string> {\n options: SegmentedControlOption<T>[]\n /** Fills its row, the segments sharing it evenly with their labels truncated: phone tab bars. */\n block?: boolean\n}\n\ndefineProps<SegmentedControlProps<T>>()\n\nconst model = defineModel<T>({ required: true })\n</script>\n\n<!-- A few choices side by side, one picked: the chosen one lifts onto a card. Arrow keys move between them. -->\n<template>\n <RadioGroupRoot\n v-model=\"model\"\n class=\"flex gap-0.5 rounded-lg bg-sui-sunken p-0.75 ring-1 ring-sui-line-subtle ring-inset\"\n :class=\"block ? 'w-full' : 'w-fit'\"\n orientation=\"horizontal\"\n >\n <RadioGroupItem\n v-for=\"option in options\"\n :key=\"option.value\"\n class=\"inline-flex h-7 items-center gap-1.5 rounded-md text-13 font-medium transition-colors focus-visible:sui-ring-inset [&_svg]:shrink-0 [&_svg]:[stroke-linecap:round] [&_svg]:[stroke-linejoin:round]\"\n :class=\"[\n block ? 'min-w-0 flex-1 justify-center px-2' : 'pr-3 pl-2.5',\n option.value === model\n ? 'bg-sui-surface text-sui-ink shadow-(--sui-shadow-raised) ring-1 ring-sui-line-subtle'\n : 'text-sui-ink-body hover:text-sui-ink'\n ]\"\n :value=\"option.value\"\n >\n <Icon\n v-if=\"option.iconName\"\n class=\"h-4 w-4\"\n :color=\"option.value === model ? 'ink' : 'ink-body'\"\n :name=\"option.iconName\"\n />\n <svg\n v-else-if=\"option.icon\"\n aria-hidden=\"true\"\n class=\"h-3.5 w-3.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <path :d=\"option.icon\" />\n </svg>\n <span class=\"min-w-0 truncate\">{{ option.label }}</span>\n </RadioGroupItem>\n </RadioGroupRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;EAsBA,IAAMoB,IAAQpB,EAAcsB,GAAA,YAAmB;E,kBAK7CrB,EAAA,GAAAC,EAqCiBC,EAAAuB,CAAA,GAAA;GApCN,YAAAN,EAAA;GAAA,uBAAA,AAAAO,EAAA,QAAA,MAAA,EAAK,QAAAC;GACd,OAAKxB,EAAA,CAAC,uFACEkB,EAAA,QAAK,WAAA,OAAA,CAAA;GACb,aAAY;;GAGV,SAAAjB,QAAyB,EAD3BJ,EAAA,EAAA,GAAAK,EA8BiBC,GAAA,MAAAC,EA7BEc,EAAA,UAAV,OADTrB,EAAA,GAAAC,EA8BiBC,EAAA+B,CAAA,GAAA;IA5Bd,KAAKC,EAAO;IACb,OAAK/B,EAAA,CAAC,sMAAoM,CACxLkB,EAAA,QAAK,uCAAA,eAAiEa,EAAO,UAAUf,EAAA,Q;IAMxG,OAAOe,EAAO;;IAEf,SAAA9B,QAKE,CAJM8B,EAAO,YADflC,EAAA,GAAAC,EAKEO,GAAA;;KAHA,OAAM;KACL,OAAO0B,EAAO,UAAUf,EAAA,QAAK,QAAA;KAC7B,MAAMe,EAAO;I,kCAGHA,EAAO,QADpBlC,EAAA,GAAAK,EAUM,OAVNQ,GAUM,CADJJ,EAAyB,QAAA,EAAlB,GAAGyB,EAAO,K,+BAEnBzB,EAAwD,QAAxDM,GAAwDJ,EAAtBuB,EAAO,KAAK,GAAA,CAAA,C"}
1
+ {"version":3,"file":"SegmentedControl.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_normalizeClass","_withCtx","_createElementBlock","_Fragment","_renderList","Icon","_createElementVNode","_createCommentVNode","_toDisplayString","Icon_default","_hoisted_1","_hoisted_2","_hoisted_3","SegmentedControl_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","model","useModel","__props","openBlock","createBlock","unref","RadioGroupRoot","_cache","$event","normalizeClass","withCtx","createElementBlock","Fragment","renderList","RadioGroupItem","option","createElementVNode","createCommentVNode","toDisplayString"],"sources":["../../../src/components/SegmentedControl/SegmentedControl.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends string\">\nimport { RadioGroupItem, RadioGroupRoot } from 'reka-ui'\n\nimport Icon from '../Icon/Icon.vue'\n\nexport interface SegmentedControlOption<T extends string> {\n value: T\n label: string\n /** An Icon name. */\n iconName?: string\n /** An SVG path on a 24px grid. */\n icon?: string\n}\n\nexport interface SegmentedControlProps<T extends string> {\n options: SegmentedControlOption<T>[]\n /** Fills its row, the segments sharing it evenly with their labels truncated: phone tab bars. */\n block?: boolean\n}\n\ndefineProps<SegmentedControlProps<T>>()\n\nconst model = defineModel<T>({ required: true })\n</script>\n\n<!-- A few choices side by side, one picked: the chosen one lifts onto a card. Arrow keys move between them. -->\n<template>\n <RadioGroupRoot\n v-model=\"model\"\n class=\"flex gap-0.5 rounded-lg bg-sui-track p-0.75 ring-1 ring-sui-fill-line ring-inset\"\n :class=\"block ? 'w-full' : 'w-fit'\"\n orientation=\"horizontal\"\n >\n <RadioGroupItem\n v-for=\"option in options\"\n :key=\"option.value\"\n class=\"inline-flex h-7 items-center gap-1.5 rounded-md text-13 font-medium transition-colors focus-visible:sui-ring-inset [&_svg]:shrink-0 [&_svg]:[stroke-linecap:round] [&_svg]:[stroke-linejoin:round]\"\n :class=\"[\n block ? 'min-w-0 flex-1 justify-center px-2' : 'pr-3 pl-2.5',\n option.value === model\n ? 'bg-sui-lifted text-sui-ink shadow-(--sui-shadow-lifted)'\n : 'text-sui-ink-body hover:text-sui-ink'\n ]\"\n :value=\"option.value\"\n >\n <Icon\n v-if=\"option.iconName\"\n class=\"h-4 w-4\"\n :color=\"option.value === model ? 'ink' : 'ink-body'\"\n :name=\"option.iconName\"\n />\n <svg\n v-else-if=\"option.icon\"\n aria-hidden=\"true\"\n class=\"h-3.5 w-3.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <path :d=\"option.icon\" />\n </svg>\n <span class=\"min-w-0 truncate\">{{ option.label }}</span>\n </RadioGroupItem>\n </RadioGroupRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;EAsBA,IAAMoB,IAAQpB,EAAcsB,GAAA,YAAmB;E,kBAK7CrB,EAAA,GAAAC,EAqCiBC,EAAAuB,CAAA,GAAA;GApCN,YAAAN,EAAA;GAAA,uBAAA,AAAAO,EAAA,QAAA,MAAA,EAAK,QAAAC;GACd,OAAKxB,EAAA,CAAC,oFACEkB,EAAA,QAAK,WAAA,OAAA,CAAA;GACb,aAAY;;GAGV,SAAAjB,QAAyB,EAD3BJ,EAAA,EAAA,GAAAK,EA8BiBC,GAAA,MAAAC,EA7BEc,EAAA,UAAV,OADTrB,EAAA,GAAAC,EA8BiBC,EAAA+B,CAAA,GAAA;IA5Bd,KAAKC,EAAO;IACb,OAAK/B,EAAA,CAAC,sMAAoM,CACxLkB,EAAA,QAAK,uCAAA,eAAiEa,EAAO,UAAUf,EAAA,Q;IAMxG,OAAOe,EAAO;;IAEf,SAAA9B,QAKE,CAJM8B,EAAO,YADflC,EAAA,GAAAC,EAKEO,GAAA;;KAHA,OAAM;KACL,OAAO0B,EAAO,UAAUf,EAAA,QAAK,QAAA;KAC7B,MAAMe,EAAO;I,kCAGHA,EAAO,QADpBlC,EAAA,GAAAK,EAUM,OAVNQ,GAUM,CADJJ,EAAyB,QAAA,EAAlB,GAAGyB,EAAO,K,+BAEnBzB,EAAwD,QAAxDM,GAAwDJ,EAAtBuB,EAAO,KAAK,GAAA,CAAA,C"}
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","names":["_sfc_main","Select_vue_vue_type_script_setup_true_lang_default","Select_default"],"sources":["../../../src/components/Select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends SelectValue\">\nimport { computed, nextTick, ref, shallowRef, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxItem,\n ListboxRoot,\n ListboxVirtualizer,\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot\n} from 'reka-ui'\n\nimport type { Hue } from '../../utils/hues'\nimport { useFieldControl } from '../FormField/context'\nimport Icon from '../Icon/Icon.vue'\nimport Spinner from '../Spinner/Spinner.vue'\nimport Tag from '../Tag/Tag.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport type { SelectOption, SelectValue } from './types'\n\nexport interface SelectProps<T extends SelectValue> {\n options: SelectOption<T>[]\n /** The options for chosen values that aren't in `options`, such as a saved choice while `options` holds search\n * results. Options picked from the list are remembered without it. */\n selectedOptions?: SelectOption<T>[]\n multiple?: boolean\n /** Lets a single choice be removed, as a tag in the filter row or with Backspace there. */\n clearable?: boolean\n /** A filter row at the top of the list; on by default for `multiple`, `canCreate` or more than 8 options. */\n searchable?: boolean\n /** Narrows `options` to what's typed: by label, or by your function. `false` when `options` are already the results\n * for the query, such as from a server search through `query-change`. */\n filter?: boolean | ((option: SelectOption<T>, query: string) => boolean)\n /** Offers to create what was typed, through `createOption`. */\n canCreate?: boolean\n /** Makes the created option; by default its value is its label. */\n createOption?: (draft: { label: string; color?: Hue }) => SelectOption<T> | Promise<SelectOption<T>>\n /** Creates with a hue, shown as a tag. */\n createColored?: boolean\n loading?: boolean\n /** 36px for forms, 28px for table feet and toolbars. */\n size?: 'md' | 'sm'\n disabled?: boolean\n invalid?: boolean\n placeholder?: string\n searchPlaceholder?: string\n emptyLabel?: string\n createLabel?: string\n removeLabel?: string\n /** Where the list opens; it flips when there's no room. */\n side?: 'bottom' | 'top'\n align?: 'start' | 'end'\n /** The list's width, when it should differ from the trigger's, e.g. `20rem`. */\n panelWidth?: string\n}\n\n// Attributes (aria-label, class for its width) go to the trigger, the one element in the page's flow.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps<T>>(), {\n selectedOptions: () => [],\n searchable: undefined,\n filter: true,\n createOption: undefined,\n createColored: true,\n size: 'md',\n placeholder: 'Select an option',\n searchPlaceholder: 'Type to filter',\n emptyLabel: 'No results found',\n createLabel: 'Create',\n removeLabel: 'Remove',\n side: 'bottom',\n align: 'start',\n panelWidth: undefined\n})\n\nconst emit = defineEmits<{ 'query-change': [query: string]; 'create-error': [error: unknown] }>()\n\n// An aria-label would hide the trigger's visible value from its name; it's said before the value instead.\nconst attrs = useAttrs()\nconst label = computed(() => attrs['aria-label'] as string | undefined)\nconst triggerAttrs = computed(() => Object.fromEntries(Object.entries(attrs).filter(([key]) => key !== 'aria-label')))\n\nconst model = defineModel<T | T[] | null>({ default: null })\n\nconst open = ref(false)\nconst query = ref('')\nconst keyboard = ref(false)\nconst pointer = ref(false)\n\nconst values = computed<T[]>(() =>\n Array.isArray(model.value) ? model.value : model.value === null || model.value === undefined ? [] : [model.value]\n)\n// Options picked from earlier results, which `options` may no longer hold.\nconst picked = shallowRef<SelectOption<T>[]>([])\nconst selected = computed(() =>\n values.value\n .map((value) =>\n [props.options, props.selectedOptions, picked.value]\n .map((list) => list.find((option) => option.value === value))\n .find((option) => !!option)\n )\n .filter((option) => !!option)\n)\nconst search = computed(\n () =>\n props.searchable ??\n (props.multiple || props.canCreate || props.clearable || props.filter === false || props.options.length > 8)\n)\nconst removable = computed(() => props.multiple || props.clearable)\nconst matches = (option: SelectOption<T>, text: string) =>\n typeof props.filter === 'function'\n ? props.filter(option, text)\n : option.label.toLowerCase().includes(text.toLowerCase())\nconst listed = computed(() => {\n const text = query.value.trim()\n return props.options\n .filter((option) => !(props.multiple && search.value && values.value.includes(option.value)))\n .filter((option) => !text || props.filter === false || matches(option, text))\n})\nconst showCreate = computed(() => {\n const text = query.value.trim().toLowerCase()\n return props.canCreate && !!text && !props.options.some((option) => option.label.toLowerCase() === text)\n})\n// More than this and the list renders only the rows in view.\nconst virtual = computed(() => listed.value.length > 20)\n\nconst createHues: Hue[] = ['gray', 'purple', 'red', 'green', 'orange', 'pink', 'blue', 'slate']\nconst newHue = computed(() => createHues[query.value.length % createHues.length])\nconst CREATE = { create: true } as const\n\nconst { attrs: fieldAttrs, invalid: isInvalid } = useFieldControl(\n () => undefined,\n () => props.invalid\n)\n\nfunction setQuery(text: string) {\n query.value = text\n emit('query-change', text)\n}\n\nfunction show(viaKeyboard: boolean) {\n if (props.disabled) return\n keyboard.value = viaKeyboard\n pointer.value = false\n open.value = true\n}\n\nfunction close() {\n open.value = false\n if (query.value) setQuery('')\n}\n\nfunction toggle(event?: Event) {\n if (open.value) close()\n // A click from the keyboard (Enter, Space) has no pointer position.\n else show(!!event && (event as MouseEvent).detail === 0)\n}\n\nfunction choose(option: SelectOption<T>) {\n picked.value = [option, ...picked.value.filter((known) => known.value !== option.value)]\n if (props.multiple) {\n model.value = values.value.includes(option.value)\n ? values.value.filter((value) => value !== option.value)\n : [...values.value, option.value]\n setQuery('')\n } else {\n model.value = option.value\n close()\n }\n}\n\nconst creating = ref(false)\n\n// A failed createOption keeps what was typed, so it can be tried again.\nasync function create() {\n if (creating.value) return\n const label = query.value.trim()\n const draft = props.createColored ? { label, color: newHue.value } : { label }\n creating.value = true\n try {\n const option = props.createOption\n ? await props.createOption(draft)\n : ({ value: label as T, label, color: draft.color } as SelectOption<T>)\n choose(option)\n } catch (error) {\n emit('create-error', error)\n } finally {\n creating.value = false\n }\n}\n\nfunction onSelect(event: CustomEvent, row: SelectOption<T> | typeof CREATE) {\n // What's chosen lives in the model; the listbox keeps no selection of its own.\n event.preventDefault()\n if ('create' in row) create()\n else if (!row.disabled) choose(row)\n}\n\nfunction remove(value: T) {\n model.value = props.multiple ? values.value.filter((chosen) => chosen !== value) : null\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n if (event.key === 'Backspace' && removable.value && !query.value && values.value.length)\n remove(values.value[values.value.length - 1]!)\n}\n\nfunction onTriggerKeydown(event: KeyboardEvent) {\n if (!open.value && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n event.preventDefault()\n show(true)\n }\n}\n\n// The filter takes focus when there is one, or else the list, so the arrow keys work at once.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n nextTick(() =>\n (event.target as HTMLElement | null)?.querySelector<HTMLElement>('[data-select-filter], [role=\"listbox\"]')?.focus()\n )\n}\n\n// Back to the trigger, which Reka can't find: it's our anchor, not its trigger.\nconst anchor = ref<{ $el: HTMLElement }>()\n\n// Nor does Reka know a press on it isn't outside: closing there would let the click reopen the list.\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n const target = event.detail.originalEvent.target\n if (target instanceof Node && anchor.value?.$el?.contains(target)) event.preventDefault()\n}\nfunction returnFocus(event: Event) {\n event.preventDefault()\n anchor.value?.$el?.focus()\n}\n\n// Reka highlights the first option as the list mounts; only the chosen one, the keyboard or the pointer should.\nconst listbox = ref()\nfunction onHighlight(payload: { value: unknown } | undefined) {\n if (keyboard.value || pointer.value || !payload) return\n if (values.value.includes(payload.value as T)) return\n nextTick(() => listbox.value && !keyboard.value && !pointer.value && (listbox.value.highlightedElement = null))\n}\n\nconst triggerSizes = { md: 'min-h-9 pr-2.5 pl-3 text-sm', sm: 'h-7 pr-1.5 pl-2 text-13' }\nconst optionClass =\n 'flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-sunken data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset'\n</script>\n\n<!-- One select for every choice: a short fixed list, a searchable one, several values as tags (`multiple`), or creating\n what was typed (`canCreate`). For a server search, set `:filter=\"false\"` and replace `options` on `query-change`. The `trigger` slot draws your own trigger and gets `open`, `toggle` and `selected`. -->\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"(value) => (value ? show(false) : close())\">\n <PopoverAnchor ref=\"anchor\" as-child>\n <slot name=\"trigger\" :open=\"open\" :selected=\"selected\" :toggle=\"toggle\">\n <button\n v-bind=\"{ ...fieldAttrs, ...triggerAttrs }\"\n :aria-expanded=\"open\"\n aria-haspopup=\"listbox\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n class=\"group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-surface text-left text-sui-ink transition-[border-color,box-shadow] duration-150 focus-visible:border-sui-accent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60\"\n :class=\"[\n triggerSizes[size],\n isInvalid ? 'border-sui-danger-mid' : 'border-sui-line-strong hover:border-sui-ink-muted'\n ]\"\n :disabled=\"disabled\"\n type=\"button\"\n @click=\"toggle\"\n @keydown=\"onTriggerKeydown\"\n >\n <span v-if=\"label\" class=\"sr-only\">{{ label }}: </span>\n <span v-if=\"!selected.length\" class=\"text-sui-ink-faint\">{{ placeholder }}</span>\n <span v-else-if=\"multiple\" class=\"flex flex-wrap gap-1 py-1.25\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n </span>\n <Tag\n v-else-if=\"selected[0]!.color\"\n :color=\"selected[0]!.color\"\n :icon=\"selected[0]!.icon\"\n :icon-color=\"selected[0]!.iconColor\"\n :name=\"selected[0]!.label\"\n />\n <span v-else-if=\"selected[0]!.icon\" class=\"inline-flex min-w-0 items-center gap-1.5\">\n <Icon class=\"shrink-0\" :color=\"selected[0]!.iconColor ?? 'ink-subtle'\" :name=\"selected[0]!.icon\" />\n <span class=\"truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n </span>\n <span v-else class=\"min-w-0 truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n <svg\n aria-hidden=\"true\"\n class=\"size-4 shrink-0 fill-none stroke-sui-ink-muted transition-transform duration-150 group-aria-expanded:rotate-180\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M4.5 6.5 8 10l3.5-3.5\" />\n </svg>\n </button>\n </slot>\n </PopoverAnchor>\n <PopoverPortal>\n <PopoverContent\n :align=\"align\"\n :aria-label=\"label ?? placeholder\"\n class=\"z-[1100] overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in\"\n :class=\"\n search ? 'min-w-[max(var(--reka-popover-trigger-width),15rem)]' : 'min-w-(--reka-popover-trigger-width)'\n \"\n :side=\"side\"\n :side-offset=\"4\"\n :style=\"panelWidth ? { width: panelWidth } : undefined\"\n @close-auto-focus=\"returnFocus\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <ListboxRoot\n ref=\"listbox\"\n :highlight-on-hover=\"true\"\n :model-value=\"multiple ? values : (values[0] ?? undefined)\"\n :multiple=\"multiple\"\n @highlight=\"onHighlight\"\n @keydown=\"onKeydown\"\n @pointermove.capture=\"((keyboard = false), (pointer = true))\"\n >\n <div\n v-if=\"search\"\n class=\"flex min-h-11 flex-wrap items-center gap-1 border-b border-sui-line-subtle px-3 py-2.5\"\n >\n <template v-if=\"removable\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n removable\n :remove-label=\"removeLabel\"\n @remove=\"remove(option.value)\"\n />\n </template>\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <ListboxFilter\n :aria-label=\"label ?? placeholder\"\n class=\"h-5 min-w-16 flex-1 rounded-none border-none bg-transparent p-0 text-13 text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n data-select-filter\n :model-value=\"query\"\n :placeholder=\"removable && selected.length ? '' : searchPlaceholder\"\n @update:model-value=\"setQuery\"\n />\n </div>\n <div v-if=\"loading\" class=\"flex justify-center py-6\"><Spinner size=\"sm\" /></div>\n <ListboxContent\n v-else-if=\"listed.length || showCreate\"\n :aria-label=\"label ?? placeholder\"\n class=\"group/list max-h-60 overflow-auto p-1 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxVirtualizer\n v-if=\"virtual\"\n v-slot=\"{ option }\"\n :estimate-size=\"32\"\n :options=\"listed\"\n :text-content=\"(option) => option.label\"\n >\n <ListboxItem\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option as SelectOption<T>)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option as SelectOption<T>\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </ListboxVirtualizer>\n <template v-else>\n <ListboxItem\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </template>\n <ListboxItem v-if=\"showCreate\" :class=\"optionClass\" :value=\"CREATE\" @select=\"onSelect($event, CREATE)\">\n <span class=\"inline-flex min-w-0 items-center gap-1.5\">\n {{ createLabel }}\n <Tag v-if=\"createColored\" :color=\"newHue\" :name=\"query.trim()\" />\n <strong v-else class=\"font-medium\">“{{ query.trim() }}”</strong>\n </span>\n </ListboxItem>\n </ListboxContent>\n <div v-else class=\"px-3.5 py-3 text-13 text-sui-ink-muted\">{{ emptyLabel }}</div>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Select.js","names":["_sfc_main","Select_vue_vue_type_script_setup_true_lang_default","Select_default"],"sources":["../../../src/components/Select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends SelectValue\">\nimport { computed, nextTick, ref, shallowRef, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxItem,\n ListboxRoot,\n ListboxVirtualizer,\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot\n} from 'reka-ui'\n\nimport type { Hue } from '../../utils/hues'\nimport { useFieldControl } from '../FormField/context'\nimport Icon from '../Icon/Icon.vue'\nimport Spinner from '../Spinner/Spinner.vue'\nimport Tag from '../Tag/Tag.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport type { SelectOption, SelectValue } from './types'\n\nexport interface SelectProps<T extends SelectValue> {\n options: SelectOption<T>[]\n /** The options for chosen values that aren't in `options`, such as a saved choice while `options` holds search\n * results. Options picked from the list are remembered without it. */\n selectedOptions?: SelectOption<T>[]\n multiple?: boolean\n /** Lets a single choice be removed, as a tag in the filter row or with Backspace there. */\n clearable?: boolean\n /** A filter row at the top of the list; on by default for `multiple`, `canCreate` or more than 8 options. */\n searchable?: boolean\n /** Narrows `options` to what's typed: by label, or by your function. `false` when `options` are already the results\n * for the query, such as from a server search through `query-change`. */\n filter?: boolean | ((option: SelectOption<T>, query: string) => boolean)\n /** Offers to create what was typed, through `createOption`. */\n canCreate?: boolean\n /** Makes the created option; by default its value is its label. */\n createOption?: (draft: { label: string; color?: Hue }) => SelectOption<T> | Promise<SelectOption<T>>\n /** Creates with a hue, shown as a tag. */\n createColored?: boolean\n loading?: boolean\n /** 36px for forms, 28px for table feet and toolbars. */\n size?: 'md' | 'sm'\n disabled?: boolean\n invalid?: boolean\n placeholder?: string\n searchPlaceholder?: string\n emptyLabel?: string\n createLabel?: string\n removeLabel?: string\n /** Where the list opens; it flips when there's no room. */\n side?: 'bottom' | 'top'\n align?: 'start' | 'end'\n /** The list's width, when it should differ from the trigger's, e.g. `20rem`. */\n panelWidth?: string\n}\n\n// Attributes (aria-label, class for its width) go to the trigger, the one element in the page's flow.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps<T>>(), {\n selectedOptions: () => [],\n searchable: undefined,\n filter: true,\n createOption: undefined,\n createColored: true,\n size: 'md',\n placeholder: 'Select an option',\n searchPlaceholder: 'Type to filter',\n emptyLabel: 'No results found',\n createLabel: 'Create',\n removeLabel: 'Remove',\n side: 'bottom',\n align: 'start',\n panelWidth: undefined\n})\n\nconst emit = defineEmits<{ 'query-change': [query: string]; 'create-error': [error: unknown] }>()\n\n// An aria-label would hide the trigger's visible value from its name; it's said before the value instead.\nconst attrs = useAttrs()\nconst label = computed(() => attrs['aria-label'] as string | undefined)\nconst triggerAttrs = computed(() => Object.fromEntries(Object.entries(attrs).filter(([key]) => key !== 'aria-label')))\n\nconst model = defineModel<T | T[] | null>({ default: null })\n\nconst open = ref(false)\nconst query = ref('')\nconst keyboard = ref(false)\nconst pointer = ref(false)\n\nconst values = computed<T[]>(() =>\n Array.isArray(model.value) ? model.value : model.value === null || model.value === undefined ? [] : [model.value]\n)\n// Options picked from earlier results, which `options` may no longer hold.\nconst picked = shallowRef<SelectOption<T>[]>([])\nconst selected = computed(() =>\n values.value\n .map((value) =>\n [props.options, props.selectedOptions, picked.value]\n .map((list) => list.find((option) => option.value === value))\n .find((option) => !!option)\n )\n .filter((option) => !!option)\n)\nconst search = computed(\n () =>\n props.searchable ??\n (props.multiple || props.canCreate || props.clearable || props.filter === false || props.options.length > 8)\n)\nconst removable = computed(() => props.multiple || props.clearable)\nconst matches = (option: SelectOption<T>, text: string) =>\n typeof props.filter === 'function'\n ? props.filter(option, text)\n : option.label.toLowerCase().includes(text.toLowerCase())\nconst listed = computed(() => {\n const text = query.value.trim()\n return props.options\n .filter((option) => !(props.multiple && search.value && values.value.includes(option.value)))\n .filter((option) => !text || props.filter === false || matches(option, text))\n})\nconst showCreate = computed(() => {\n const text = query.value.trim().toLowerCase()\n return props.canCreate && !!text && !props.options.some((option) => option.label.toLowerCase() === text)\n})\n// More than this and the list renders only the rows in view.\nconst virtual = computed(() => listed.value.length > 20)\n\nconst createHues: Hue[] = ['gray', 'purple', 'red', 'green', 'orange', 'pink', 'blue', 'slate']\nconst newHue = computed(() => createHues[query.value.length % createHues.length])\nconst CREATE = { create: true } as const\n\nconst { attrs: fieldAttrs, invalid: isInvalid } = useFieldControl(\n () => undefined,\n () => props.invalid\n)\n\nfunction setQuery(text: string) {\n query.value = text\n emit('query-change', text)\n}\n\nfunction show(viaKeyboard: boolean) {\n if (props.disabled) return\n keyboard.value = viaKeyboard\n pointer.value = false\n open.value = true\n}\n\nfunction close() {\n open.value = false\n if (query.value) setQuery('')\n}\n\nfunction toggle(event?: Event) {\n if (open.value) close()\n // A click from the keyboard (Enter, Space) has no pointer position.\n else show(!!event && (event as MouseEvent).detail === 0)\n}\n\nfunction choose(option: SelectOption<T>) {\n picked.value = [option, ...picked.value.filter((known) => known.value !== option.value)]\n if (props.multiple) {\n model.value = values.value.includes(option.value)\n ? values.value.filter((value) => value !== option.value)\n : [...values.value, option.value]\n setQuery('')\n } else {\n model.value = option.value\n close()\n }\n}\n\nconst creating = ref(false)\n\n// A failed createOption keeps what was typed, so it can be tried again.\nasync function create() {\n if (creating.value) return\n const label = query.value.trim()\n const draft = props.createColored ? { label, color: newHue.value } : { label }\n creating.value = true\n try {\n const option = props.createOption\n ? await props.createOption(draft)\n : ({ value: label as T, label, color: draft.color } as SelectOption<T>)\n choose(option)\n } catch (error) {\n emit('create-error', error)\n } finally {\n creating.value = false\n }\n}\n\nfunction onSelect(event: CustomEvent, row: SelectOption<T> | typeof CREATE) {\n // What's chosen lives in the model; the listbox keeps no selection of its own.\n event.preventDefault()\n if ('create' in row) create()\n else if (!row.disabled) choose(row)\n}\n\nfunction remove(value: T) {\n model.value = props.multiple ? values.value.filter((chosen) => chosen !== value) : null\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n if (event.key === 'Backspace' && removable.value && !query.value && values.value.length)\n remove(values.value[values.value.length - 1]!)\n}\n\nfunction onTriggerKeydown(event: KeyboardEvent) {\n if (!open.value && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n event.preventDefault()\n show(true)\n }\n}\n\n// The filter takes focus when there is one, or else the list, so the arrow keys work at once.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n nextTick(() =>\n (event.target as HTMLElement | null)?.querySelector<HTMLElement>('[data-select-filter], [role=\"listbox\"]')?.focus()\n )\n}\n\n// Back to the trigger, which Reka can't find: it's our anchor, not its trigger.\nconst anchor = ref<{ $el: HTMLElement }>()\n\n// Nor does Reka know a press on it isn't outside: closing there would let the click reopen the list.\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n const target = event.detail.originalEvent.target\n if (target instanceof Node && anchor.value?.$el?.contains(target)) event.preventDefault()\n}\nfunction returnFocus(event: Event) {\n event.preventDefault()\n anchor.value?.$el?.focus()\n}\n\n// Reka highlights the first option as the list mounts; only the chosen one, the keyboard or the pointer should.\nconst listbox = ref()\nfunction onHighlight(payload: { value: unknown } | undefined) {\n if (keyboard.value || pointer.value || !payload) return\n if (values.value.includes(payload.value as T)) return\n nextTick(() => listbox.value && !keyboard.value && !pointer.value && (listbox.value.highlightedElement = null))\n}\n\nconst triggerSizes = { md: 'min-h-(--sui-control-height) pr-2.5 pl-3 text-sm', sm: 'h-7 pr-1.5 pl-2 text-13' }\nconst optionClass =\n 'flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-fill-hover data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset'\n</script>\n\n<!-- One select for every choice: a short fixed list, a searchable one, several values as tags (`multiple`), or creating\n what was typed (`canCreate`). For a server search, set `:filter=\"false\"` and replace `options` on `query-change`. The `trigger` slot draws your own trigger and gets `open`, `toggle` and `selected`. -->\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"(value) => (value ? show(false) : close())\">\n <PopoverAnchor ref=\"anchor\" as-child>\n <slot name=\"trigger\" :open=\"open\" :selected=\"selected\" :toggle=\"toggle\">\n <button\n v-bind=\"{ ...fieldAttrs, ...triggerAttrs }\"\n :aria-expanded=\"open\"\n aria-haspopup=\"listbox\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n class=\"group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-fill text-left text-sui-ink transition-[border-color,box-shadow,background-color] duration-150 focus-visible:border-sui-accent focus-visible:bg-transparent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60\"\n :class=\"[\n triggerSizes[size],\n isInvalid ? 'border-sui-danger-mid' : 'border-sui-fill-line hover:bg-sui-fill-hover'\n ]\"\n :disabled=\"disabled\"\n type=\"button\"\n @click=\"toggle\"\n @keydown=\"onTriggerKeydown\"\n >\n <span v-if=\"label\" class=\"sr-only\">{{ label }}: </span>\n <span v-if=\"!selected.length\" class=\"text-sui-ink-faint\">{{ placeholder }}</span>\n <span v-else-if=\"multiple\" class=\"flex flex-wrap gap-1 py-1.25\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n </span>\n <Tag\n v-else-if=\"selected[0]!.color\"\n :color=\"selected[0]!.color\"\n :icon=\"selected[0]!.icon\"\n :icon-color=\"selected[0]!.iconColor\"\n :name=\"selected[0]!.label\"\n />\n <span v-else-if=\"selected[0]!.icon\" class=\"inline-flex min-w-0 items-center gap-1.5\">\n <Icon class=\"shrink-0\" :color=\"selected[0]!.iconColor ?? 'ink-subtle'\" :name=\"selected[0]!.icon\" />\n <span class=\"truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n </span>\n <span v-else class=\"min-w-0 truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n <svg\n aria-hidden=\"true\"\n class=\"size-4 shrink-0 fill-none stroke-sui-ink-muted transition-transform duration-150 group-aria-expanded:rotate-180\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M4.5 6.5 8 10l3.5-3.5\" />\n </svg>\n </button>\n </slot>\n </PopoverAnchor>\n <PopoverPortal>\n <PopoverContent\n :align=\"align\"\n :aria-label=\"label ?? placeholder\"\n class=\"z-[1100] overflow-hidden rounded-xl border border-sui-edge bg-sui-raised text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in\"\n :class=\"\n search ? 'min-w-[max(var(--reka-popover-trigger-width),15rem)]' : 'min-w-(--reka-popover-trigger-width)'\n \"\n :side=\"side\"\n :side-offset=\"4\"\n :style=\"panelWidth ? { width: panelWidth } : undefined\"\n @close-auto-focus=\"returnFocus\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <ListboxRoot\n ref=\"listbox\"\n :highlight-on-hover=\"true\"\n :model-value=\"multiple ? values : (values[0] ?? undefined)\"\n :multiple=\"multiple\"\n @highlight=\"onHighlight\"\n @keydown=\"onKeydown\"\n @pointermove.capture=\"((keyboard = false), (pointer = true))\"\n >\n <div\n v-if=\"search\"\n class=\"flex min-h-11 flex-wrap items-center gap-1 border-b border-sui-line-subtle px-3 py-2.5\"\n >\n <template v-if=\"removable\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n removable\n :remove-label=\"removeLabel\"\n @remove=\"remove(option.value)\"\n />\n </template>\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <ListboxFilter\n :aria-label=\"label ?? placeholder\"\n class=\"h-5 min-w-16 flex-1 rounded-none border-none bg-transparent p-0 text-13 text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n data-select-filter\n :model-value=\"query\"\n :placeholder=\"removable && selected.length ? '' : searchPlaceholder\"\n @update:model-value=\"setQuery\"\n />\n </div>\n <div v-if=\"loading\" class=\"flex justify-center py-6\"><Spinner size=\"sm\" /></div>\n <ListboxContent\n v-else-if=\"listed.length || showCreate\"\n :aria-label=\"label ?? placeholder\"\n class=\"group/list max-h-60 overflow-auto p-1 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxVirtualizer\n v-if=\"virtual\"\n v-slot=\"{ option }\"\n :estimate-size=\"32\"\n :options=\"listed\"\n :text-content=\"(option) => option.label\"\n >\n <ListboxItem\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option as SelectOption<T>)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option as SelectOption<T>\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </ListboxVirtualizer>\n <template v-else>\n <ListboxItem\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </template>\n <ListboxItem v-if=\"showCreate\" :class=\"optionClass\" :value=\"CREATE\" @select=\"onSelect($event, CREATE)\">\n <span class=\"inline-flex min-w-0 items-center gap-1.5\">\n {{ createLabel }}\n <Tag v-if=\"createColored\" :color=\"newHue\" :name=\"query.trim()\" />\n <strong v-else class=\"font-medium\">“{{ query.trim() }}”</strong>\n </span>\n </ListboxItem>\n </ListboxContent>\n <div v-else class=\"px-3.5 py-3 text-13 text-sui-ink-muted\">{{ emptyLabel }}</div>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":""}
@@ -37,7 +37,7 @@ var pe = [
37
37
  }, Ee = {
38
38
  key: 3,
39
39
  class: "px-3.5 py-3 text-13 text-sui-ink-muted"
40
- }, T = "flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-sunken data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset", E = /*@__PURE__*/ p({
40
+ }, T = "flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-fill-hover data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset", E = /*@__PURE__*/ p({
41
41
  inheritAttrs: !1,
42
42
  __name: "Select",
43
43
  props: /*@__PURE__*/ m({
@@ -168,7 +168,7 @@ var pe = [
168
168
  N.value || P.value || !e || F.value.includes(e.value) || h(() => $.value && !N.value && !P.value && ($.value.highlightedElement = null));
169
169
  }
170
170
  let Be = {
171
- md: "min-h-9 pr-2.5 pl-3 text-sm",
171
+ md: "min-h-(--sui-control-height) pr-2.5 pl-3 text-sm",
172
172
  sm: "h-7 pr-1.5 pl-2 text-13"
173
173
  };
174
174
  return (t, o) => (_(), s(S(fe), {
@@ -191,7 +191,7 @@ var pe = [
191
191
  "aria-expanded": j.value,
192
192
  "aria-haspopup": "listbox",
193
193
  "aria-invalid": S(G) ? "true" : void 0,
194
- class: ["group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-surface text-left text-sui-ink transition-[border-color,box-shadow] duration-150 focus-visible:border-sui-accent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60", [Be[p.size], S(G) ? "border-sui-danger-mid" : "border-sui-line-strong hover:border-sui-ink-muted"]],
194
+ class: ["group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-fill text-left text-sui-ink transition-[border-color,box-shadow,background-color] duration-150 focus-visible:border-sui-accent focus-visible:bg-transparent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60", [Be[p.size], S(G) ? "border-sui-danger-mid" : "border-sui-fill-line hover:bg-sui-fill-hover"]],
195
195
  disabled: p.disabled,
196
196
  type: "button",
197
197
  onClick: Y,
@@ -239,7 +239,7 @@ var pe = [
239
239
  default: C(() => [f(S(ue), {
240
240
  align: p.align,
241
241
  "aria-label": k.value ?? p.placeholder,
242
- class: g(["z-[1100] overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in", R.value ? "min-w-[max(var(--reka-popover-trigger-width),15rem)]" : "min-w-(--reka-popover-trigger-width)"]),
242
+ class: g(["z-[1100] overflow-hidden rounded-xl border border-sui-edge bg-sui-raised text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in", R.value ? "min-w-[max(var(--reka-popover-trigger-width),15rem)]" : "min-w-(--reka-popover-trigger-width)"]),
243
243
  side: p.side,
244
244
  "side-offset": 4,
245
245
  style: te(p.panelWidth ? { width: p.panelWidth } : void 0),
@@ -1 +1 @@
1
- {"version":3,"file":"Select.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_renderSlot","_createElementVNode","_mergeProps","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","Tag","Icon","_normalizeClass","_normalizeStyle","Spinner","_createTextVNode","CheckIcon","Icon_default","CheckIcon_default","Spinner_default","Tag_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","optionClass","Select_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","__emit","props","__props","emit","attrs","useAttrs","label","computed","triggerAttrs","key","model","useModel","open","ref","query","keyboard","pointer","values","picked","shallowRef","selected","list","option","value","search","removable","matches","text","listed","showCreate","virtual","createHues","newHue","CREATE","fieldAttrs","isInvalid","useFieldControl","setQuery","show","viaKeyboard","close","toggle","event","choose","known","creating","create","draft","error","onSelect","row","remove","chosen","onKeydown","onTriggerKeydown","onOpenAutoFocus","nextTick","anchor","onPointerDownOutside","target","returnFocus","listbox","onHighlight","payload","triggerSizes","openBlock","createBlock","unref","PopoverRoot","_cache","withCtx","createVNode","PopoverAnchor","renderSlot","_ctx","createElementVNode","mergeProps","createElementBlock","toDisplayString","createCommentVNode","Fragment","renderList","PopoverPortal","PopoverContent","normalizeClass","normalizeStyle","ListboxRoot","ListboxFilter","ListboxContent","ListboxVirtualizer","ListboxItem","$event","createTextVNode"],"sources":["../../../src/components/Select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends SelectValue\">\nimport { computed, nextTick, ref, shallowRef, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxItem,\n ListboxRoot,\n ListboxVirtualizer,\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot\n} from 'reka-ui'\n\nimport type { Hue } from '../../utils/hues'\nimport { useFieldControl } from '../FormField/context'\nimport Icon from '../Icon/Icon.vue'\nimport Spinner from '../Spinner/Spinner.vue'\nimport Tag from '../Tag/Tag.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport type { SelectOption, SelectValue } from './types'\n\nexport interface SelectProps<T extends SelectValue> {\n options: SelectOption<T>[]\n /** The options for chosen values that aren't in `options`, such as a saved choice while `options` holds search\n * results. Options picked from the list are remembered without it. */\n selectedOptions?: SelectOption<T>[]\n multiple?: boolean\n /** Lets a single choice be removed, as a tag in the filter row or with Backspace there. */\n clearable?: boolean\n /** A filter row at the top of the list; on by default for `multiple`, `canCreate` or more than 8 options. */\n searchable?: boolean\n /** Narrows `options` to what's typed: by label, or by your function. `false` when `options` are already the results\n * for the query, such as from a server search through `query-change`. */\n filter?: boolean | ((option: SelectOption<T>, query: string) => boolean)\n /** Offers to create what was typed, through `createOption`. */\n canCreate?: boolean\n /** Makes the created option; by default its value is its label. */\n createOption?: (draft: { label: string; color?: Hue }) => SelectOption<T> | Promise<SelectOption<T>>\n /** Creates with a hue, shown as a tag. */\n createColored?: boolean\n loading?: boolean\n /** 36px for forms, 28px for table feet and toolbars. */\n size?: 'md' | 'sm'\n disabled?: boolean\n invalid?: boolean\n placeholder?: string\n searchPlaceholder?: string\n emptyLabel?: string\n createLabel?: string\n removeLabel?: string\n /** Where the list opens; it flips when there's no room. */\n side?: 'bottom' | 'top'\n align?: 'start' | 'end'\n /** The list's width, when it should differ from the trigger's, e.g. `20rem`. */\n panelWidth?: string\n}\n\n// Attributes (aria-label, class for its width) go to the trigger, the one element in the page's flow.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps<T>>(), {\n selectedOptions: () => [],\n searchable: undefined,\n filter: true,\n createOption: undefined,\n createColored: true,\n size: 'md',\n placeholder: 'Select an option',\n searchPlaceholder: 'Type to filter',\n emptyLabel: 'No results found',\n createLabel: 'Create',\n removeLabel: 'Remove',\n side: 'bottom',\n align: 'start',\n panelWidth: undefined\n})\n\nconst emit = defineEmits<{ 'query-change': [query: string]; 'create-error': [error: unknown] }>()\n\n// An aria-label would hide the trigger's visible value from its name; it's said before the value instead.\nconst attrs = useAttrs()\nconst label = computed(() => attrs['aria-label'] as string | undefined)\nconst triggerAttrs = computed(() => Object.fromEntries(Object.entries(attrs).filter(([key]) => key !== 'aria-label')))\n\nconst model = defineModel<T | T[] | null>({ default: null })\n\nconst open = ref(false)\nconst query = ref('')\nconst keyboard = ref(false)\nconst pointer = ref(false)\n\nconst values = computed<T[]>(() =>\n Array.isArray(model.value) ? model.value : model.value === null || model.value === undefined ? [] : [model.value]\n)\n// Options picked from earlier results, which `options` may no longer hold.\nconst picked = shallowRef<SelectOption<T>[]>([])\nconst selected = computed(() =>\n values.value\n .map((value) =>\n [props.options, props.selectedOptions, picked.value]\n .map((list) => list.find((option) => option.value === value))\n .find((option) => !!option)\n )\n .filter((option) => !!option)\n)\nconst search = computed(\n () =>\n props.searchable ??\n (props.multiple || props.canCreate || props.clearable || props.filter === false || props.options.length > 8)\n)\nconst removable = computed(() => props.multiple || props.clearable)\nconst matches = (option: SelectOption<T>, text: string) =>\n typeof props.filter === 'function'\n ? props.filter(option, text)\n : option.label.toLowerCase().includes(text.toLowerCase())\nconst listed = computed(() => {\n const text = query.value.trim()\n return props.options\n .filter((option) => !(props.multiple && search.value && values.value.includes(option.value)))\n .filter((option) => !text || props.filter === false || matches(option, text))\n})\nconst showCreate = computed(() => {\n const text = query.value.trim().toLowerCase()\n return props.canCreate && !!text && !props.options.some((option) => option.label.toLowerCase() === text)\n})\n// More than this and the list renders only the rows in view.\nconst virtual = computed(() => listed.value.length > 20)\n\nconst createHues: Hue[] = ['gray', 'purple', 'red', 'green', 'orange', 'pink', 'blue', 'slate']\nconst newHue = computed(() => createHues[query.value.length % createHues.length])\nconst CREATE = { create: true } as const\n\nconst { attrs: fieldAttrs, invalid: isInvalid } = useFieldControl(\n () => undefined,\n () => props.invalid\n)\n\nfunction setQuery(text: string) {\n query.value = text\n emit('query-change', text)\n}\n\nfunction show(viaKeyboard: boolean) {\n if (props.disabled) return\n keyboard.value = viaKeyboard\n pointer.value = false\n open.value = true\n}\n\nfunction close() {\n open.value = false\n if (query.value) setQuery('')\n}\n\nfunction toggle(event?: Event) {\n if (open.value) close()\n // A click from the keyboard (Enter, Space) has no pointer position.\n else show(!!event && (event as MouseEvent).detail === 0)\n}\n\nfunction choose(option: SelectOption<T>) {\n picked.value = [option, ...picked.value.filter((known) => known.value !== option.value)]\n if (props.multiple) {\n model.value = values.value.includes(option.value)\n ? values.value.filter((value) => value !== option.value)\n : [...values.value, option.value]\n setQuery('')\n } else {\n model.value = option.value\n close()\n }\n}\n\nconst creating = ref(false)\n\n// A failed createOption keeps what was typed, so it can be tried again.\nasync function create() {\n if (creating.value) return\n const label = query.value.trim()\n const draft = props.createColored ? { label, color: newHue.value } : { label }\n creating.value = true\n try {\n const option = props.createOption\n ? await props.createOption(draft)\n : ({ value: label as T, label, color: draft.color } as SelectOption<T>)\n choose(option)\n } catch (error) {\n emit('create-error', error)\n } finally {\n creating.value = false\n }\n}\n\nfunction onSelect(event: CustomEvent, row: SelectOption<T> | typeof CREATE) {\n // What's chosen lives in the model; the listbox keeps no selection of its own.\n event.preventDefault()\n if ('create' in row) create()\n else if (!row.disabled) choose(row)\n}\n\nfunction remove(value: T) {\n model.value = props.multiple ? values.value.filter((chosen) => chosen !== value) : null\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n if (event.key === 'Backspace' && removable.value && !query.value && values.value.length)\n remove(values.value[values.value.length - 1]!)\n}\n\nfunction onTriggerKeydown(event: KeyboardEvent) {\n if (!open.value && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n event.preventDefault()\n show(true)\n }\n}\n\n// The filter takes focus when there is one, or else the list, so the arrow keys work at once.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n nextTick(() =>\n (event.target as HTMLElement | null)?.querySelector<HTMLElement>('[data-select-filter], [role=\"listbox\"]')?.focus()\n )\n}\n\n// Back to the trigger, which Reka can't find: it's our anchor, not its trigger.\nconst anchor = ref<{ $el: HTMLElement }>()\n\n// Nor does Reka know a press on it isn't outside: closing there would let the click reopen the list.\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n const target = event.detail.originalEvent.target\n if (target instanceof Node && anchor.value?.$el?.contains(target)) event.preventDefault()\n}\nfunction returnFocus(event: Event) {\n event.preventDefault()\n anchor.value?.$el?.focus()\n}\n\n// Reka highlights the first option as the list mounts; only the chosen one, the keyboard or the pointer should.\nconst listbox = ref()\nfunction onHighlight(payload: { value: unknown } | undefined) {\n if (keyboard.value || pointer.value || !payload) return\n if (values.value.includes(payload.value as T)) return\n nextTick(() => listbox.value && !keyboard.value && !pointer.value && (listbox.value.highlightedElement = null))\n}\n\nconst triggerSizes = { md: 'min-h-9 pr-2.5 pl-3 text-sm', sm: 'h-7 pr-1.5 pl-2 text-13' }\nconst optionClass =\n 'flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-sunken data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset'\n</script>\n\n<!-- One select for every choice: a short fixed list, a searchable one, several values as tags (`multiple`), or creating\n what was typed (`canCreate`). For a server search, set `:filter=\"false\"` and replace `options` on `query-change`. The `trigger` slot draws your own trigger and gets `open`, `toggle` and `selected`. -->\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"(value) => (value ? show(false) : close())\">\n <PopoverAnchor ref=\"anchor\" as-child>\n <slot name=\"trigger\" :open=\"open\" :selected=\"selected\" :toggle=\"toggle\">\n <button\n v-bind=\"{ ...fieldAttrs, ...triggerAttrs }\"\n :aria-expanded=\"open\"\n aria-haspopup=\"listbox\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n class=\"group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-surface text-left text-sui-ink transition-[border-color,box-shadow] duration-150 focus-visible:border-sui-accent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60\"\n :class=\"[\n triggerSizes[size],\n isInvalid ? 'border-sui-danger-mid' : 'border-sui-line-strong hover:border-sui-ink-muted'\n ]\"\n :disabled=\"disabled\"\n type=\"button\"\n @click=\"toggle\"\n @keydown=\"onTriggerKeydown\"\n >\n <span v-if=\"label\" class=\"sr-only\">{{ label }}: </span>\n <span v-if=\"!selected.length\" class=\"text-sui-ink-faint\">{{ placeholder }}</span>\n <span v-else-if=\"multiple\" class=\"flex flex-wrap gap-1 py-1.25\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n </span>\n <Tag\n v-else-if=\"selected[0]!.color\"\n :color=\"selected[0]!.color\"\n :icon=\"selected[0]!.icon\"\n :icon-color=\"selected[0]!.iconColor\"\n :name=\"selected[0]!.label\"\n />\n <span v-else-if=\"selected[0]!.icon\" class=\"inline-flex min-w-0 items-center gap-1.5\">\n <Icon class=\"shrink-0\" :color=\"selected[0]!.iconColor ?? 'ink-subtle'\" :name=\"selected[0]!.icon\" />\n <span class=\"truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n </span>\n <span v-else class=\"min-w-0 truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n <svg\n aria-hidden=\"true\"\n class=\"size-4 shrink-0 fill-none stroke-sui-ink-muted transition-transform duration-150 group-aria-expanded:rotate-180\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M4.5 6.5 8 10l3.5-3.5\" />\n </svg>\n </button>\n </slot>\n </PopoverAnchor>\n <PopoverPortal>\n <PopoverContent\n :align=\"align\"\n :aria-label=\"label ?? placeholder\"\n class=\"z-[1100] overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in\"\n :class=\"\n search ? 'min-w-[max(var(--reka-popover-trigger-width),15rem)]' : 'min-w-(--reka-popover-trigger-width)'\n \"\n :side=\"side\"\n :side-offset=\"4\"\n :style=\"panelWidth ? { width: panelWidth } : undefined\"\n @close-auto-focus=\"returnFocus\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <ListboxRoot\n ref=\"listbox\"\n :highlight-on-hover=\"true\"\n :model-value=\"multiple ? values : (values[0] ?? undefined)\"\n :multiple=\"multiple\"\n @highlight=\"onHighlight\"\n @keydown=\"onKeydown\"\n @pointermove.capture=\"((keyboard = false), (pointer = true))\"\n >\n <div\n v-if=\"search\"\n class=\"flex min-h-11 flex-wrap items-center gap-1 border-b border-sui-line-subtle px-3 py-2.5\"\n >\n <template v-if=\"removable\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n removable\n :remove-label=\"removeLabel\"\n @remove=\"remove(option.value)\"\n />\n </template>\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <ListboxFilter\n :aria-label=\"label ?? placeholder\"\n class=\"h-5 min-w-16 flex-1 rounded-none border-none bg-transparent p-0 text-13 text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n data-select-filter\n :model-value=\"query\"\n :placeholder=\"removable && selected.length ? '' : searchPlaceholder\"\n @update:model-value=\"setQuery\"\n />\n </div>\n <div v-if=\"loading\" class=\"flex justify-center py-6\"><Spinner size=\"sm\" /></div>\n <ListboxContent\n v-else-if=\"listed.length || showCreate\"\n :aria-label=\"label ?? placeholder\"\n class=\"group/list max-h-60 overflow-auto p-1 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxVirtualizer\n v-if=\"virtual\"\n v-slot=\"{ option }\"\n :estimate-size=\"32\"\n :options=\"listed\"\n :text-content=\"(option) => option.label\"\n >\n <ListboxItem\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option as SelectOption<T>)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option as SelectOption<T>\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </ListboxVirtualizer>\n <template v-else>\n <ListboxItem\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </template>\n <ListboxItem v-if=\"showCreate\" :class=\"optionClass\" :value=\"CREATE\" @select=\"onSelect($event, CREATE)\">\n <span class=\"inline-flex min-w-0 items-center gap-1.5\">\n {{ createLabel }}\n <Tag v-if=\"createColored\" :color=\"newHue\" :name=\"query.trim()\" />\n <strong v-else class=\"font-medium\">“{{ query.trim() }}”</strong>\n </span>\n </ListboxItem>\n </ListboxContent>\n <div v-else class=\"px-3.5 py-3 text-13 text-sui-ink-muted\">{{ emptyLabel }}</div>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"Select.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_renderSlot","_createElementVNode","_mergeProps","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","Tag","Icon","_normalizeClass","_normalizeStyle","Spinner","_createTextVNode","CheckIcon","Icon_default","CheckIcon_default","Spinner_default","Tag_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","optionClass","Select_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","__emit","props","__props","emit","attrs","useAttrs","label","computed","triggerAttrs","key","model","useModel","open","ref","query","keyboard","pointer","values","picked","shallowRef","selected","list","option","value","search","removable","matches","text","listed","showCreate","virtual","createHues","newHue","CREATE","fieldAttrs","isInvalid","useFieldControl","setQuery","show","viaKeyboard","close","toggle","event","choose","known","creating","create","draft","error","onSelect","row","remove","chosen","onKeydown","onTriggerKeydown","onOpenAutoFocus","nextTick","anchor","onPointerDownOutside","target","returnFocus","listbox","onHighlight","payload","triggerSizes","openBlock","createBlock","unref","PopoverRoot","_cache","withCtx","createVNode","PopoverAnchor","renderSlot","_ctx","createElementVNode","mergeProps","createElementBlock","toDisplayString","createCommentVNode","Fragment","renderList","PopoverPortal","PopoverContent","normalizeClass","normalizeStyle","ListboxRoot","ListboxFilter","ListboxContent","ListboxVirtualizer","ListboxItem","$event","createTextVNode"],"sources":["../../../src/components/Select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends SelectValue\">\nimport { computed, nextTick, ref, shallowRef, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxItem,\n ListboxRoot,\n ListboxVirtualizer,\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot\n} from 'reka-ui'\n\nimport type { Hue } from '../../utils/hues'\nimport { useFieldControl } from '../FormField/context'\nimport Icon from '../Icon/Icon.vue'\nimport Spinner from '../Spinner/Spinner.vue'\nimport Tag from '../Tag/Tag.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport type { SelectOption, SelectValue } from './types'\n\nexport interface SelectProps<T extends SelectValue> {\n options: SelectOption<T>[]\n /** The options for chosen values that aren't in `options`, such as a saved choice while `options` holds search\n * results. Options picked from the list are remembered without it. */\n selectedOptions?: SelectOption<T>[]\n multiple?: boolean\n /** Lets a single choice be removed, as a tag in the filter row or with Backspace there. */\n clearable?: boolean\n /** A filter row at the top of the list; on by default for `multiple`, `canCreate` or more than 8 options. */\n searchable?: boolean\n /** Narrows `options` to what's typed: by label, or by your function. `false` when `options` are already the results\n * for the query, such as from a server search through `query-change`. */\n filter?: boolean | ((option: SelectOption<T>, query: string) => boolean)\n /** Offers to create what was typed, through `createOption`. */\n canCreate?: boolean\n /** Makes the created option; by default its value is its label. */\n createOption?: (draft: { label: string; color?: Hue }) => SelectOption<T> | Promise<SelectOption<T>>\n /** Creates with a hue, shown as a tag. */\n createColored?: boolean\n loading?: boolean\n /** 36px for forms, 28px for table feet and toolbars. */\n size?: 'md' | 'sm'\n disabled?: boolean\n invalid?: boolean\n placeholder?: string\n searchPlaceholder?: string\n emptyLabel?: string\n createLabel?: string\n removeLabel?: string\n /** Where the list opens; it flips when there's no room. */\n side?: 'bottom' | 'top'\n align?: 'start' | 'end'\n /** The list's width, when it should differ from the trigger's, e.g. `20rem`. */\n panelWidth?: string\n}\n\n// Attributes (aria-label, class for its width) go to the trigger, the one element in the page's flow.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps<T>>(), {\n selectedOptions: () => [],\n searchable: undefined,\n filter: true,\n createOption: undefined,\n createColored: true,\n size: 'md',\n placeholder: 'Select an option',\n searchPlaceholder: 'Type to filter',\n emptyLabel: 'No results found',\n createLabel: 'Create',\n removeLabel: 'Remove',\n side: 'bottom',\n align: 'start',\n panelWidth: undefined\n})\n\nconst emit = defineEmits<{ 'query-change': [query: string]; 'create-error': [error: unknown] }>()\n\n// An aria-label would hide the trigger's visible value from its name; it's said before the value instead.\nconst attrs = useAttrs()\nconst label = computed(() => attrs['aria-label'] as string | undefined)\nconst triggerAttrs = computed(() => Object.fromEntries(Object.entries(attrs).filter(([key]) => key !== 'aria-label')))\n\nconst model = defineModel<T | T[] | null>({ default: null })\n\nconst open = ref(false)\nconst query = ref('')\nconst keyboard = ref(false)\nconst pointer = ref(false)\n\nconst values = computed<T[]>(() =>\n Array.isArray(model.value) ? model.value : model.value === null || model.value === undefined ? [] : [model.value]\n)\n// Options picked from earlier results, which `options` may no longer hold.\nconst picked = shallowRef<SelectOption<T>[]>([])\nconst selected = computed(() =>\n values.value\n .map((value) =>\n [props.options, props.selectedOptions, picked.value]\n .map((list) => list.find((option) => option.value === value))\n .find((option) => !!option)\n )\n .filter((option) => !!option)\n)\nconst search = computed(\n () =>\n props.searchable ??\n (props.multiple || props.canCreate || props.clearable || props.filter === false || props.options.length > 8)\n)\nconst removable = computed(() => props.multiple || props.clearable)\nconst matches = (option: SelectOption<T>, text: string) =>\n typeof props.filter === 'function'\n ? props.filter(option, text)\n : option.label.toLowerCase().includes(text.toLowerCase())\nconst listed = computed(() => {\n const text = query.value.trim()\n return props.options\n .filter((option) => !(props.multiple && search.value && values.value.includes(option.value)))\n .filter((option) => !text || props.filter === false || matches(option, text))\n})\nconst showCreate = computed(() => {\n const text = query.value.trim().toLowerCase()\n return props.canCreate && !!text && !props.options.some((option) => option.label.toLowerCase() === text)\n})\n// More than this and the list renders only the rows in view.\nconst virtual = computed(() => listed.value.length > 20)\n\nconst createHues: Hue[] = ['gray', 'purple', 'red', 'green', 'orange', 'pink', 'blue', 'slate']\nconst newHue = computed(() => createHues[query.value.length % createHues.length])\nconst CREATE = { create: true } as const\n\nconst { attrs: fieldAttrs, invalid: isInvalid } = useFieldControl(\n () => undefined,\n () => props.invalid\n)\n\nfunction setQuery(text: string) {\n query.value = text\n emit('query-change', text)\n}\n\nfunction show(viaKeyboard: boolean) {\n if (props.disabled) return\n keyboard.value = viaKeyboard\n pointer.value = false\n open.value = true\n}\n\nfunction close() {\n open.value = false\n if (query.value) setQuery('')\n}\n\nfunction toggle(event?: Event) {\n if (open.value) close()\n // A click from the keyboard (Enter, Space) has no pointer position.\n else show(!!event && (event as MouseEvent).detail === 0)\n}\n\nfunction choose(option: SelectOption<T>) {\n picked.value = [option, ...picked.value.filter((known) => known.value !== option.value)]\n if (props.multiple) {\n model.value = values.value.includes(option.value)\n ? values.value.filter((value) => value !== option.value)\n : [...values.value, option.value]\n setQuery('')\n } else {\n model.value = option.value\n close()\n }\n}\n\nconst creating = ref(false)\n\n// A failed createOption keeps what was typed, so it can be tried again.\nasync function create() {\n if (creating.value) return\n const label = query.value.trim()\n const draft = props.createColored ? { label, color: newHue.value } : { label }\n creating.value = true\n try {\n const option = props.createOption\n ? await props.createOption(draft)\n : ({ value: label as T, label, color: draft.color } as SelectOption<T>)\n choose(option)\n } catch (error) {\n emit('create-error', error)\n } finally {\n creating.value = false\n }\n}\n\nfunction onSelect(event: CustomEvent, row: SelectOption<T> | typeof CREATE) {\n // What's chosen lives in the model; the listbox keeps no selection of its own.\n event.preventDefault()\n if ('create' in row) create()\n else if (!row.disabled) choose(row)\n}\n\nfunction remove(value: T) {\n model.value = props.multiple ? values.value.filter((chosen) => chosen !== value) : null\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n if (event.key === 'Backspace' && removable.value && !query.value && values.value.length)\n remove(values.value[values.value.length - 1]!)\n}\n\nfunction onTriggerKeydown(event: KeyboardEvent) {\n if (!open.value && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n event.preventDefault()\n show(true)\n }\n}\n\n// The filter takes focus when there is one, or else the list, so the arrow keys work at once.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n nextTick(() =>\n (event.target as HTMLElement | null)?.querySelector<HTMLElement>('[data-select-filter], [role=\"listbox\"]')?.focus()\n )\n}\n\n// Back to the trigger, which Reka can't find: it's our anchor, not its trigger.\nconst anchor = ref<{ $el: HTMLElement }>()\n\n// Nor does Reka know a press on it isn't outside: closing there would let the click reopen the list.\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n const target = event.detail.originalEvent.target\n if (target instanceof Node && anchor.value?.$el?.contains(target)) event.preventDefault()\n}\nfunction returnFocus(event: Event) {\n event.preventDefault()\n anchor.value?.$el?.focus()\n}\n\n// Reka highlights the first option as the list mounts; only the chosen one, the keyboard or the pointer should.\nconst listbox = ref()\nfunction onHighlight(payload: { value: unknown } | undefined) {\n if (keyboard.value || pointer.value || !payload) return\n if (values.value.includes(payload.value as T)) return\n nextTick(() => listbox.value && !keyboard.value && !pointer.value && (listbox.value.highlightedElement = null))\n}\n\nconst triggerSizes = { md: 'min-h-(--sui-control-height) pr-2.5 pl-3 text-sm', sm: 'h-7 pr-1.5 pl-2 text-13' }\nconst optionClass =\n 'flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-fill-hover data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset'\n</script>\n\n<!-- One select for every choice: a short fixed list, a searchable one, several values as tags (`multiple`), or creating\n what was typed (`canCreate`). For a server search, set `:filter=\"false\"` and replace `options` on `query-change`. The `trigger` slot draws your own trigger and gets `open`, `toggle` and `selected`. -->\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"(value) => (value ? show(false) : close())\">\n <PopoverAnchor ref=\"anchor\" as-child>\n <slot name=\"trigger\" :open=\"open\" :selected=\"selected\" :toggle=\"toggle\">\n <button\n v-bind=\"{ ...fieldAttrs, ...triggerAttrs }\"\n :aria-expanded=\"open\"\n aria-haspopup=\"listbox\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n class=\"group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-fill text-left text-sui-ink transition-[border-color,box-shadow,background-color] duration-150 focus-visible:border-sui-accent focus-visible:bg-transparent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60\"\n :class=\"[\n triggerSizes[size],\n isInvalid ? 'border-sui-danger-mid' : 'border-sui-fill-line hover:bg-sui-fill-hover'\n ]\"\n :disabled=\"disabled\"\n type=\"button\"\n @click=\"toggle\"\n @keydown=\"onTriggerKeydown\"\n >\n <span v-if=\"label\" class=\"sr-only\">{{ label }}: </span>\n <span v-if=\"!selected.length\" class=\"text-sui-ink-faint\">{{ placeholder }}</span>\n <span v-else-if=\"multiple\" class=\"flex flex-wrap gap-1 py-1.25\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n </span>\n <Tag\n v-else-if=\"selected[0]!.color\"\n :color=\"selected[0]!.color\"\n :icon=\"selected[0]!.icon\"\n :icon-color=\"selected[0]!.iconColor\"\n :name=\"selected[0]!.label\"\n />\n <span v-else-if=\"selected[0]!.icon\" class=\"inline-flex min-w-0 items-center gap-1.5\">\n <Icon class=\"shrink-0\" :color=\"selected[0]!.iconColor ?? 'ink-subtle'\" :name=\"selected[0]!.icon\" />\n <span class=\"truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n </span>\n <span v-else class=\"min-w-0 truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n <svg\n aria-hidden=\"true\"\n class=\"size-4 shrink-0 fill-none stroke-sui-ink-muted transition-transform duration-150 group-aria-expanded:rotate-180\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M4.5 6.5 8 10l3.5-3.5\" />\n </svg>\n </button>\n </slot>\n </PopoverAnchor>\n <PopoverPortal>\n <PopoverContent\n :align=\"align\"\n :aria-label=\"label ?? placeholder\"\n class=\"z-[1100] overflow-hidden rounded-xl border border-sui-edge bg-sui-raised text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in\"\n :class=\"\n search ? 'min-w-[max(var(--reka-popover-trigger-width),15rem)]' : 'min-w-(--reka-popover-trigger-width)'\n \"\n :side=\"side\"\n :side-offset=\"4\"\n :style=\"panelWidth ? { width: panelWidth } : undefined\"\n @close-auto-focus=\"returnFocus\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <ListboxRoot\n ref=\"listbox\"\n :highlight-on-hover=\"true\"\n :model-value=\"multiple ? values : (values[0] ?? undefined)\"\n :multiple=\"multiple\"\n @highlight=\"onHighlight\"\n @keydown=\"onKeydown\"\n @pointermove.capture=\"((keyboard = false), (pointer = true))\"\n >\n <div\n v-if=\"search\"\n class=\"flex min-h-11 flex-wrap items-center gap-1 border-b border-sui-line-subtle px-3 py-2.5\"\n >\n <template v-if=\"removable\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n removable\n :remove-label=\"removeLabel\"\n @remove=\"remove(option.value)\"\n />\n </template>\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <ListboxFilter\n :aria-label=\"label ?? placeholder\"\n class=\"h-5 min-w-16 flex-1 rounded-none border-none bg-transparent p-0 text-13 text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n data-select-filter\n :model-value=\"query\"\n :placeholder=\"removable && selected.length ? '' : searchPlaceholder\"\n @update:model-value=\"setQuery\"\n />\n </div>\n <div v-if=\"loading\" class=\"flex justify-center py-6\"><Spinner size=\"sm\" /></div>\n <ListboxContent\n v-else-if=\"listed.length || showCreate\"\n :aria-label=\"label ?? placeholder\"\n class=\"group/list max-h-60 overflow-auto p-1 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxVirtualizer\n v-if=\"virtual\"\n v-slot=\"{ option }\"\n :estimate-size=\"32\"\n :options=\"listed\"\n :text-content=\"(option) => option.label\"\n >\n <ListboxItem\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option as SelectOption<T>)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option as SelectOption<T>\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </ListboxVirtualizer>\n <template v-else>\n <ListboxItem\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </template>\n <ListboxItem v-if=\"showCreate\" :class=\"optionClass\" :value=\"CREATE\" @select=\"onSelect($event, CREATE)\">\n <span class=\"inline-flex min-w-0 items-center gap-1.5\">\n {{ createLabel }}\n <Tag v-if=\"createColored\" :color=\"newHue\" :name=\"query.trim()\" />\n <strong v-else class=\"font-medium\">“{{ query.trim() }}”</strong>\n </span>\n </ListboxItem>\n </ListboxContent>\n <div v-else class=\"px-3.5 py-3 text-13 text-sui-ink-muted\">{{ emptyLabel }}</div>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Skeleton.js","names":["_sfc_main","Skeleton_vue_vue_type_script_setup_true_lang_default","Skeleton_default"],"sources":["../../../src/components/Skeleton/Skeleton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nexport interface SkeletonProps {\n shape?: 'rectangle' | 'circle'\n /** Width and height together, for a circle or a square; it keeps that size in a flex row. */\n size?: string\n width?: string\n height?: string\n}\n\nconst props = withDefaults(defineProps<SkeletonProps>(), {\n shape: 'rectangle',\n size: undefined,\n width: '100%',\n height: '1rem'\n})\n\nconst style = computed(() => ({ width: props.size ?? props.width, height: props.size ?? props.height }))\n</script>\n\n<template>\n <div\n aria-hidden=\"true\"\n :class=\"[\n 'relative animate-pulse overflow-hidden bg-sui-sunken',\n shape === 'circle' ? 'rounded-full' : 'rounded-md',\n size && 'shrink-0'\n ]\"\n :style=\"style\"\n />\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Skeleton.js","names":["_sfc_main","Skeleton_vue_vue_type_script_setup_true_lang_default","Skeleton_default"],"sources":["../../../src/components/Skeleton/Skeleton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nexport interface SkeletonProps {\n shape?: 'rectangle' | 'circle'\n /** Width and height together, for a circle or a square; it keeps that size in a flex row. */\n size?: string\n width?: string\n height?: string\n}\n\nconst props = withDefaults(defineProps<SkeletonProps>(), {\n shape: 'rectangle',\n size: undefined,\n width: '100%',\n height: '1rem'\n})\n\nconst style = computed(() => ({ width: props.size ?? props.width, height: props.size ?? props.height }))\n</script>\n\n<template>\n <div\n aria-hidden=\"true\"\n :class=\"[\n 'relative animate-pulse overflow-hidden bg-sui-fill-hover',\n shape === 'circle' ? 'rounded-full' : 'rounded-md',\n size && 'shrink-0'\n ]\"\n :style=\"style\"\n />\n</template>\n"],"mappings":""}
@@ -16,7 +16,7 @@ var o = /*@__PURE__*/ n({
16
16
  return (e, o) => (a(), t("div", {
17
17
  "aria-hidden": "true",
18
18
  class: r([
19
- "relative animate-pulse overflow-hidden bg-sui-sunken",
19
+ "relative animate-pulse overflow-hidden bg-sui-fill-hover",
20
20
  n.shape === "circle" ? "rounded-full" : "rounded-md",
21
21
  n.size && "shrink-0"
22
22
  ]),
@@ -1 +1 @@
1
- {"version":3,"file":"Skeleton.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","Skeleton_vue_vue_type_script_setup_true_lang_default","props","__props","style","computed","openBlock","createElementBlock","normalizeClass","normalizeStyle"],"sources":["../../../src/components/Skeleton/Skeleton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nexport interface SkeletonProps {\n shape?: 'rectangle' | 'circle'\n /** Width and height together, for a circle or a square; it keeps that size in a flex row. */\n size?: string\n width?: string\n height?: string\n}\n\nconst props = withDefaults(defineProps<SkeletonProps>(), {\n shape: 'rectangle',\n size: undefined,\n width: '100%',\n height: '1rem'\n})\n\nconst style = computed(() => ({ width: props.size ?? props.width, height: props.size ?? props.height }))\n</script>\n\n<template>\n <div\n aria-hidden=\"true\"\n :class=\"[\n 'relative animate-pulse overflow-hidden bg-sui-sunken',\n shape === 'circle' ? 'rounded-full' : 'rounded-md',\n size && 'shrink-0'\n ]\"\n :style=\"style\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;EAWA,IAAMK,IAAQC,GAORC,IAAQC,SAAgB;GAAE,OAAOH,EAAM,QAAQA,EAAM;GAAO,QAAQA,EAAM,QAAQA,EAAM;EAAO,EAAE;E,kBAIrGL,EAAA,GAAAC,EAQE,OAAA;GAPA,eAAY;GACX,OAAKC,EAAA;;IAAwEI,EAAA,UAAK,WAAA,iBAAA;IAAqDA,EAAA,QAAI;;GAK3I,OAAKH,EAAEI,EAAA,KAAK"}
1
+ {"version":3,"file":"Skeleton.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","Skeleton_vue_vue_type_script_setup_true_lang_default","props","__props","style","computed","openBlock","createElementBlock","normalizeClass","normalizeStyle"],"sources":["../../../src/components/Skeleton/Skeleton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nexport interface SkeletonProps {\n shape?: 'rectangle' | 'circle'\n /** Width and height together, for a circle or a square; it keeps that size in a flex row. */\n size?: string\n width?: string\n height?: string\n}\n\nconst props = withDefaults(defineProps<SkeletonProps>(), {\n shape: 'rectangle',\n size: undefined,\n width: '100%',\n height: '1rem'\n})\n\nconst style = computed(() => ({ width: props.size ?? props.width, height: props.size ?? props.height }))\n</script>\n\n<template>\n <div\n aria-hidden=\"true\"\n :class=\"[\n 'relative animate-pulse overflow-hidden bg-sui-fill-hover',\n shape === 'circle' ? 'rounded-full' : 'rounded-md',\n size && 'shrink-0'\n ]\"\n :style=\"style\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;EAWA,IAAMK,IAAQC,GAORC,IAAQC,SAAgB;GAAE,OAAOH,EAAM,QAAQA,EAAM;GAAO,QAAQA,EAAM,QAAQA,EAAM;EAAO,EAAE;E,kBAIrGL,EAAA,GAAAC,EAQE,OAAA;GAPA,eAAY;GACX,OAAKC,EAAA;;IAA4EI,EAAA,UAAK,WAAA,iBAAA;IAAqDA,EAAA,QAAI;;GAK/I,OAAKH,EAAEI,EAAA,KAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"Table.js","names":["_sfc_main","Table_vue_vue_type_script_setup_true_lang_default","Table_default"],"sources":["../../../src/components/Table/Table.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { TableColumn, TableSort } from './types'\n\nexport interface TableProps<T> {\n columns: TableColumn[]\n rows: T[]\n /** The row field that identifies it. */\n rowKey?: keyof T & string\n /** A checkbox column bound to `v-model:selected`; selected rows tint accent-wash. */\n selectable?: boolean\n /** Skeleton rows in place of the body. */\n loading?: boolean\n loadingRows?: number\n /** md: 57px rows. sm: 40px, for dense lists. */\n size?: 'md' | 'sm'\n /** A row height in px between the sizes, such as 44, for body and header rows; sets `--sui-table-row`. */\n rowHeight?: number\n /** The header row's height in px, e.g. 36 over 44px rows; sets `--sui-table-header`. Defaults to the row height. */\n headerHeight?: number\n /** canvas lays the header on the page colour, for a table directly on the canvas. */\n headerTone?: 'sunken' | 'canvas'\n /** The table's name for screen readers. */\n caption?: string\n selectAllLabel?: string\n selectRowLabel?: string\n /** Makes rows clickable (`@row-click`), e.g. to open the record. */\n onRowClick?: (row: T) => void\n}\n\nconst props = withDefaults(defineProps<TableProps<T>>(), {\n rowKey: 'id' as never,\n loadingRows: 5,\n size: 'md',\n rowHeight: undefined,\n headerHeight: undefined,\n headerTone: 'sunken',\n caption: undefined,\n selectAllLabel: 'Select all rows',\n selectRowLabel: 'Select row',\n onRowClick: undefined\n})\n\nconst sort = defineModel<TableSort | null>('sort', { default: null })\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\n\nconst slots = defineSlots<\n {\n /** Shown in place of the body when there are no rows, e.g. an EmptyState. */\n empty?: () => unknown\n /** Replaces the body when given, e.g. an inset danger Alert with a retry. */\n error?: () => unknown\n /** A canvas strip under the rows: a rows-per-page Select, the range, Pagination. */\n footer?: () => unknown\n } & {\n [K in `cell-${string}`]?: (props: { row: T; value: unknown }) => unknown\n }\n>()\n\nconst idOf = (row: T): unknown => row[props.rowKey ?? 'id']\nconst ids = computed(() => props.rows.map(idOf))\nconst allSelected = computed(() => ids.value.length > 0 && ids.value.every((id) => selected.value.includes(id)))\nconst someSelected = computed(() => !allSelected.value && ids.value.some((id) => selected.value.includes(id)))\n\nfunction toggleAll() {\n selected.value = allSelected.value\n ? selected.value.filter((id) => !ids.value.includes(id))\n : [...new Set([...selected.value, ...ids.value])]\n}\n\nfunction toggle(id: unknown) {\n selected.value = selected.value.includes(id) ? selected.value.filter((x) => x !== id) : [...selected.value, id]\n}\n\n// Sorting a column cycles ascending, descending, unsorted.\nfunction sortBy(key: string) {\n const dir = sort.value?.key === key ? sort.value.dir : null\n const next = dir === null ? 'asc' : dir === 'asc' ? 'desc' : null\n sort.value = next ? { key, dir: next } : null\n}\n\nfunction dirOf(key: string) {\n return sort.value?.key === key ? sort.value.dir : null\n}\n\nfunction ariaSort(column: TableColumn) {\n const dir = dirOf(column.key)\n if (dir) return dir === 'asc' ? 'ascending' : 'descending'\n return column.sortable ? 'none' : undefined\n}\n\nconst state = computed(() => {\n if (slots.error) return 'error'\n if (props.loading) return 'loading'\n return props.rows.length === 0 && slots.empty ? 'empty' : 'rows'\n})\n\nconst columnCount = computed(() => props.columns.length + (props.selectable ? 1 : 0))\nconst alignClass = { left: 'text-left', center: 'text-center', right: 'text-right' }\nconst skeletonWidths = ['60%', '45%', '70%', '35%', '55%']\n\nconst sm = computed(() => props.size === 'sm')\nconst fixed = computed(() => props.rowHeight !== undefined)\nconst rowStyle = computed(() => {\n const style: Record<string, string> = {}\n if (fixed.value) style['--sui-table-row'] = `${props.rowHeight}px`\n if (props.headerHeight !== undefined) style['--sui-table-header'] = `${props.headerHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value\n ? 'h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]'\n : 'h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]'\n])\nconst td = computed(() => [\n 'border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-[var(--sui-table-row,2.5rem)]' : 'h-[var(--sui-table-row,3.5625rem)]'\n])\n// A set row height takes the cells' vertical padding with it.\nconst pad = computed(() => [sm.value ? 'px-3' : 'px-4', !fixed.value && (sm.value ? 'py-1.5' : 'py-3')])\nconst headTone = computed(() => (props.headerTone === 'canvas' ? 'bg-sui-canvas' : 'bg-sui-sunken'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4 text-left'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div\n class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\"\n :style=\"rowStyle\"\n >\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-[var(--sui-table-min,720px)] table-fixed border-collapse\">\n <caption v-if=\"caption\" class=\"sr-only\">\n {{\n caption\n }}\n </caption>\n <colgroup>\n <col v-if=\"selectable\" class=\"w-12\" />\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :style=\"{ width: typeof column.width === 'number' ? `${column.width}px` : column.width }\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-if=\"selectable\" :class=\"[th, checkCell, headTone]\">\n <Checkbox\n :aria-label=\"selectAllLabel\"\n :disabled=\"loading || rows.length === 0\"\n :indeterminate=\"someSelected\"\n :model-value=\"allSelected\"\n @update:model-value=\"toggleAll\"\n />\n </th>\n <component\n :is=\"column.label ? 'th' : 'td'\"\n v-for=\"column in columns\"\n :key=\"column.key\"\n :aria-sort=\"ariaSort(column)\"\n :class=\"[\n th,\n headPad,\n alignClass[column.align ?? 'left'],\n dirOf(column.key) ? 'bg-sui-accent-wash text-sui-accent' : [headTone, 'text-sui-ink-subtle']\n ]\"\n :scope=\"column.label ? 'col' : undefined\"\n >\n <button\n v-if=\"column.sortable\"\n class=\"inline-flex h-full w-full items-center gap-1.5 rounded-md outline-hidden focus-visible:sui-ring-inset\"\n :class=\"[\n column.align === 'right' && 'justify-end',\n column.align === 'center' && 'justify-center',\n !dirOf(column.key) && 'hover:text-sui-ink'\n ]\"\n type=\"button\"\n @click=\"sortBy(column.key)\"\n >\n {{ column.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3 shrink-0 fill-none stroke-current\"\n :class=\"!dirOf(column.key) && 'opacity-50'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path v-if=\"dirOf(column.key) === 'asc'\" d=\"M3 7.5 6 4.5l3 3\" />\n <path v-else-if=\"dirOf(column.key) === 'desc'\" d=\"M3 4.5 6 7.5l3-3\" />\n <path v-else d=\"M3.5 4.5 6 2l2.5 2.5M3.5 7.5 6 10l2.5-2.5\" />\n </svg>\n </button>\n <template v-else>{{ column.label }}</template>\n </component>\n </tr>\n </thead>\n <tbody :aria-busy=\"loading || undefined\">\n <tr v-if=\"state === 'error' || state === 'empty'\">\n <td class=\"p-0\" :colspan=\"columnCount\">\n <slot :name=\"state\" />\n </td>\n </tr>\n <template v-else-if=\"state === 'loading'\">\n <tr v-for=\"i in loadingRows\" :key=\"i\" aria-hidden=\"true\" class=\"group/row\">\n <td v-if=\"selectable\" :class=\"[td, checkCell]\"><Skeleton size=\"1rem\" /></td>\n <td v-for=\"(column, j) in columns\" :key=\"column.key\" :class=\"[td, pad]\">\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(i + j) % 5]\" />\n </td>\n </tr>\n </template>\n <template v-else>\n <tr\n v-for=\"row in rows\"\n :key=\"idOf(row) as PropertyKey\"\n :aria-selected=\"selectable ? selected.includes(idOf(row)) : undefined\"\n class=\"group/row transition-colors duration-150\"\n :class=\"[\n selected.includes(idOf(row)) ? 'bg-sui-accent-wash' : 'hover:bg-sui-sunken',\n onRowClick && 'cursor-pointer'\n ]\"\n @click=\"onRowClick?.(row)\"\n >\n <td v-if=\"selectable\" :class=\"[td, checkCell]\" @click.stop>\n <Checkbox\n :aria-label=\"selectRowLabel\"\n :model-value=\"selected.includes(idOf(row))\"\n @update:model-value=\"toggle(idOf(row))\"\n />\n </td>\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n td,\n pad,\n alignClass[column.align ?? 'left'],\n column.wrap ? 'break-words whitespace-normal' : 'truncate'\n ]\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\" :value=\"row[column.key]\">\n <template v-if=\"row[column.key] != null && row[column.key] !== ''\">{{ row[column.key] }}</template>\n <span v-else class=\"text-sui-ink-muted\">–</span>\n </slot>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"$slots.footer\"\n class=\"flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle bg-sui-canvas py-2 pr-3 pl-4 text-13 text-sui-ink-muted\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Table.js","names":["_sfc_main","Table_vue_vue_type_script_setup_true_lang_default","Table_default"],"sources":["../../../src/components/Table/Table.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { TableColumn, TableSort } from './types'\n\nexport interface TableProps<T> {\n columns: TableColumn[]\n rows: T[]\n /** The row field that identifies it. */\n rowKey?: keyof T & string\n /** A checkbox column bound to `v-model:selected`; selected rows tint accent-wash. */\n selectable?: boolean\n /** Skeleton rows in place of the body. */\n loading?: boolean\n loadingRows?: number\n /** md: 57px rows. sm: 40px, for dense lists. */\n size?: 'md' | 'sm'\n /** A row height in px between the sizes, such as 44, for body and header rows; sets `--sui-table-row`. */\n rowHeight?: number\n /** The header row's height in px, e.g. 36 over 44px rows; sets `--sui-table-header`. Defaults to the row height. */\n headerHeight?: number\n /** canvas lays the header on the page colour, for a table directly on the canvas. */\n headerTone?: 'sunken' | 'canvas'\n /** The table's name for screen readers. */\n caption?: string\n selectAllLabel?: string\n selectRowLabel?: string\n /** Makes rows clickable (`@row-click`), e.g. to open the record. */\n onRowClick?: (row: T) => void\n}\n\nconst props = withDefaults(defineProps<TableProps<T>>(), {\n rowKey: 'id' as never,\n loadingRows: 5,\n size: 'md',\n rowHeight: undefined,\n headerHeight: undefined,\n headerTone: 'sunken',\n caption: undefined,\n selectAllLabel: 'Select all rows',\n selectRowLabel: 'Select row',\n onRowClick: undefined\n})\n\nconst sort = defineModel<TableSort | null>('sort', { default: null })\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\n\nconst slots = defineSlots<\n {\n /** Shown in place of the body when there are no rows, e.g. an EmptyState. */\n empty?: () => unknown\n /** Replaces the body when given, e.g. an inset danger Alert with a retry. */\n error?: () => unknown\n /** A canvas strip under the rows: a rows-per-page Select, the range, Pagination. */\n footer?: () => unknown\n } & {\n [K in `cell-${string}`]?: (props: { row: T; value: unknown }) => unknown\n }\n>()\n\nconst idOf = (row: T): unknown => row[props.rowKey ?? 'id']\nconst ids = computed(() => props.rows.map(idOf))\nconst allSelected = computed(() => ids.value.length > 0 && ids.value.every((id) => selected.value.includes(id)))\nconst someSelected = computed(() => !allSelected.value && ids.value.some((id) => selected.value.includes(id)))\n\nfunction toggleAll() {\n selected.value = allSelected.value\n ? selected.value.filter((id) => !ids.value.includes(id))\n : [...new Set([...selected.value, ...ids.value])]\n}\n\nfunction toggle(id: unknown) {\n selected.value = selected.value.includes(id) ? selected.value.filter((x) => x !== id) : [...selected.value, id]\n}\n\n// Sorting a column cycles ascending, descending, unsorted.\nfunction sortBy(key: string) {\n const dir = sort.value?.key === key ? sort.value.dir : null\n const next = dir === null ? 'asc' : dir === 'asc' ? 'desc' : null\n sort.value = next ? { key, dir: next } : null\n}\n\nfunction dirOf(key: string) {\n return sort.value?.key === key ? sort.value.dir : null\n}\n\nfunction ariaSort(column: TableColumn) {\n const dir = dirOf(column.key)\n if (dir) return dir === 'asc' ? 'ascending' : 'descending'\n return column.sortable ? 'none' : undefined\n}\n\nconst state = computed(() => {\n if (slots.error) return 'error'\n if (props.loading) return 'loading'\n return props.rows.length === 0 && slots.empty ? 'empty' : 'rows'\n})\n\nconst columnCount = computed(() => props.columns.length + (props.selectable ? 1 : 0))\nconst alignClass = { left: 'text-left', center: 'text-center', right: 'text-right' }\nconst skeletonWidths = ['60%', '45%', '70%', '35%', '55%']\n\nconst sm = computed(() => props.size === 'sm')\nconst fixed = computed(() => props.rowHeight !== undefined)\nconst rowStyle = computed(() => {\n const style: Record<string, string> = {}\n if (fixed.value) style['--sui-table-row'] = `${props.rowHeight}px`\n if (props.headerHeight !== undefined) style['--sui-table-header'] = `${props.headerHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value\n ? 'h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]'\n : 'h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]'\n])\nconst td = computed(() => [\n 'border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-[var(--sui-table-row,2.5rem)]' : 'h-[var(--sui-table-row,3.5625rem)]'\n])\n// A set row height takes the cells' vertical padding with it.\nconst pad = computed(() => [sm.value ? 'px-3' : 'px-4', !fixed.value && (sm.value ? 'py-1.5' : 'py-3')])\nconst headTone = computed(() => (props.headerTone === 'canvas' ? 'bg-sui-canvas' : 'sui-band'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4 text-left'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div\n class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\"\n :style=\"rowStyle\"\n >\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-[var(--sui-table-min,720px)] table-fixed border-collapse\">\n <caption v-if=\"caption\" class=\"sr-only\">\n {{\n caption\n }}\n </caption>\n <colgroup>\n <col v-if=\"selectable\" class=\"w-12\" />\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :style=\"{ width: typeof column.width === 'number' ? `${column.width}px` : column.width }\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-if=\"selectable\" :class=\"[th, checkCell, headTone]\">\n <Checkbox\n :aria-label=\"selectAllLabel\"\n :disabled=\"loading || rows.length === 0\"\n :indeterminate=\"someSelected\"\n :model-value=\"allSelected\"\n @update:model-value=\"toggleAll\"\n />\n </th>\n <component\n :is=\"column.label ? 'th' : 'td'\"\n v-for=\"column in columns\"\n :key=\"column.key\"\n :aria-sort=\"ariaSort(column)\"\n :class=\"[\n th,\n headPad,\n alignClass[column.align ?? 'left'],\n dirOf(column.key) ? 'bg-sui-accent-wash text-sui-accent' : [headTone, 'text-sui-ink-subtle']\n ]\"\n :scope=\"column.label ? 'col' : undefined\"\n >\n <button\n v-if=\"column.sortable\"\n class=\"inline-flex h-full w-full items-center gap-1.5 rounded-md outline-hidden focus-visible:sui-ring-inset\"\n :class=\"[\n column.align === 'right' && 'justify-end',\n column.align === 'center' && 'justify-center',\n !dirOf(column.key) && 'hover:text-sui-ink'\n ]\"\n type=\"button\"\n @click=\"sortBy(column.key)\"\n >\n {{ column.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3 shrink-0 fill-none stroke-current\"\n :class=\"!dirOf(column.key) && 'opacity-50'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path v-if=\"dirOf(column.key) === 'asc'\" d=\"M3 7.5 6 4.5l3 3\" />\n <path v-else-if=\"dirOf(column.key) === 'desc'\" d=\"M3 4.5 6 7.5l3-3\" />\n <path v-else d=\"M3.5 4.5 6 2l2.5 2.5M3.5 7.5 6 10l2.5-2.5\" />\n </svg>\n </button>\n <template v-else>{{ column.label }}</template>\n </component>\n </tr>\n </thead>\n <tbody :aria-busy=\"loading || undefined\">\n <tr v-if=\"state === 'error' || state === 'empty'\">\n <td class=\"p-0\" :colspan=\"columnCount\">\n <slot :name=\"state\" />\n </td>\n </tr>\n <template v-else-if=\"state === 'loading'\">\n <tr v-for=\"i in loadingRows\" :key=\"i\" aria-hidden=\"true\" class=\"group/row\">\n <td v-if=\"selectable\" :class=\"[td, checkCell]\"><Skeleton size=\"1rem\" /></td>\n <td v-for=\"(column, j) in columns\" :key=\"column.key\" :class=\"[td, pad]\">\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(i + j) % 5]\" />\n </td>\n </tr>\n </template>\n <template v-else>\n <tr\n v-for=\"row in rows\"\n :key=\"idOf(row) as PropertyKey\"\n :aria-selected=\"selectable ? selected.includes(idOf(row)) : undefined\"\n class=\"group/row transition-colors duration-150\"\n :class=\"[\n selected.includes(idOf(row)) ? 'bg-sui-accent-wash' : 'hover:bg-sui-fill-hover',\n onRowClick && 'cursor-pointer'\n ]\"\n @click=\"onRowClick?.(row)\"\n >\n <td v-if=\"selectable\" :class=\"[td, checkCell]\" @click.stop>\n <Checkbox\n :aria-label=\"selectRowLabel\"\n :model-value=\"selected.includes(idOf(row))\"\n @update:model-value=\"toggle(idOf(row))\"\n />\n </td>\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n td,\n pad,\n alignClass[column.align ?? 'left'],\n column.wrap ? 'break-words whitespace-normal' : 'truncate'\n ]\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\" :value=\"row[column.key]\">\n <template v-if=\"row[column.key] != null && row[column.key] !== ''\">{{ row[column.key] }}</template>\n <span v-else class=\"text-sui-ink-muted\">–</span>\n </slot>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"$slots.footer\"\n class=\"flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle py-2 pr-3 pl-4 text-13 text-sui-ink-muted\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -22,7 +22,7 @@ var C = { class: "overflow-x-auto" }, w = { class: "w-full min-w-[var(--sui-tabl
22
22
  class: "text-sui-ink-muted"
23
23
  }, A = {
24
24
  key: 0,
25
- class: "flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle bg-sui-canvas py-2 pr-3 pl-4 text-13 text-sui-ink-muted"
25
+ class: "flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle py-2 pr-3 pl-4 text-13 text-sui-ink-muted"
26
26
  }, j = "w-12 pl-4 text-left", M = /*@__PURE__*/ u({
27
27
  __name: "Table",
28
28
  props: /*@__PURE__*/ d({
@@ -85,7 +85,7 @@ var C = { class: "overflow-x-auto" }, w = { class: "w-full min-w-[var(--sui-tabl
85
85
  ], J = r(() => d.size === "sm"), Y = r(() => d.rowHeight !== void 0), oe = r(() => {
86
86
  let e = {};
87
87
  return Y.value && (e["--sui-table-row"] = `${d.rowHeight}px`), d.headerHeight !== void 0 && (e["--sui-table-header"] = `${d.headerHeight}px`), Object.keys(e).length ? e : void 0;
88
- }), X = r(() => ["border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap", J.value ? "h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]" : "h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]"]), Z = r(() => ["border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0", J.value ? "h-[var(--sui-table-row,2.5rem)]" : "h-[var(--sui-table-row,3.5625rem)]"]), Q = r(() => [J.value ? "px-3" : "px-4", !Y.value && (J.value ? "py-1.5" : "py-3")]), $ = r(() => d.headerTone === "canvas" ? "bg-sui-canvas" : "bg-sui-sunken"), se = r(() => J.value ? "px-3" : "px-4");
88
+ }), X = r(() => ["border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap", J.value ? "h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]" : "h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]"]), Z = r(() => ["border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0", J.value ? "h-[var(--sui-table-row,2.5rem)]" : "h-[var(--sui-table-row,3.5625rem)]"]), Q = r(() => [J.value ? "px-3" : "px-4", !Y.value && (J.value ? "py-1.5" : "py-3")]), $ = r(() => d.headerTone === "canvas" ? "bg-sui-canvas" : "sui-band"), se = r(() => J.value ? "px-3" : "px-4");
89
89
  return (r, d) => (m(), o("div", {
90
90
  class: "overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink",
91
91
  style: p(oe.value)
@@ -166,7 +166,7 @@ var C = { class: "overflow-x-auto" }, w = { class: "w-full min-w-[var(--sui-tabl
166
166
  }, null, 8, ["width"])], 2))), 128))]))), 128)) : (m(!0), o(n, { key: 2 }, h(u.rows, (e) => (m(), o("tr", {
167
167
  key: F(e),
168
168
  "aria-selected": u.selectable ? N.value.includes(F(e)) : void 0,
169
- class: f(["group/row transition-colors duration-150", [N.value.includes(F(e)) ? "bg-sui-accent-wash" : "hover:bg-sui-sunken", u.onRowClick && "cursor-pointer"]]),
169
+ class: f(["group/row transition-colors duration-150", [N.value.includes(F(e)) ? "bg-sui-accent-wash" : "hover:bg-sui-fill-hover", u.onRowClick && "cursor-pointer"]]),
170
170
  onClick: (t) => u.onRowClick?.(e)
171
171
  }, [u.selectable ? (m(), o("td", {
172
172
  key: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"Table.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","_useSlots","_openBlock","_createElementBlock","_normalizeStyle","_createElementVNode","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_normalizeClass","_createVNode","Checkbox","_createBlock","_resolveDynamicComponent","_withCtx","_createTextVNode","_renderSlot","Skeleton","_withModifiers","Skeleton_default","Checkbox_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","checkCell","Table_vue_vue_type_script_setup_true_lang_default","\"sort\"","\"sortModifiers\"","\"selected\"","\"selectedModifiers\"","props","__props","sort","useModel","selected","slots","useSlots","idOf","row","ids","computed","allSelected","id","someSelected","toggleAll","toggle","x","sortBy","dir","key","next","dirOf","ariaSort","column","state","columnCount","alignClass","skeletonWidths","sm","fixed","rowStyle","style","th","td","pad","headTone","headPad","openBlock","createElementBlock","normalizeStyle","createElementVNode","toDisplayString","createCommentVNode","Fragment","renderList","normalizeClass","createVNode","createBlock","resolveDynamicComponent","withCtx","createTextVNode","renderSlot","_ctx","i","j","_cache","withModifiers"],"sources":["../../../src/components/Table/Table.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { TableColumn, TableSort } from './types'\n\nexport interface TableProps<T> {\n columns: TableColumn[]\n rows: T[]\n /** The row field that identifies it. */\n rowKey?: keyof T & string\n /** A checkbox column bound to `v-model:selected`; selected rows tint accent-wash. */\n selectable?: boolean\n /** Skeleton rows in place of the body. */\n loading?: boolean\n loadingRows?: number\n /** md: 57px rows. sm: 40px, for dense lists. */\n size?: 'md' | 'sm'\n /** A row height in px between the sizes, such as 44, for body and header rows; sets `--sui-table-row`. */\n rowHeight?: number\n /** The header row's height in px, e.g. 36 over 44px rows; sets `--sui-table-header`. Defaults to the row height. */\n headerHeight?: number\n /** canvas lays the header on the page colour, for a table directly on the canvas. */\n headerTone?: 'sunken' | 'canvas'\n /** The table's name for screen readers. */\n caption?: string\n selectAllLabel?: string\n selectRowLabel?: string\n /** Makes rows clickable (`@row-click`), e.g. to open the record. */\n onRowClick?: (row: T) => void\n}\n\nconst props = withDefaults(defineProps<TableProps<T>>(), {\n rowKey: 'id' as never,\n loadingRows: 5,\n size: 'md',\n rowHeight: undefined,\n headerHeight: undefined,\n headerTone: 'sunken',\n caption: undefined,\n selectAllLabel: 'Select all rows',\n selectRowLabel: 'Select row',\n onRowClick: undefined\n})\n\nconst sort = defineModel<TableSort | null>('sort', { default: null })\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\n\nconst slots = defineSlots<\n {\n /** Shown in place of the body when there are no rows, e.g. an EmptyState. */\n empty?: () => unknown\n /** Replaces the body when given, e.g. an inset danger Alert with a retry. */\n error?: () => unknown\n /** A canvas strip under the rows: a rows-per-page Select, the range, Pagination. */\n footer?: () => unknown\n } & {\n [K in `cell-${string}`]?: (props: { row: T; value: unknown }) => unknown\n }\n>()\n\nconst idOf = (row: T): unknown => row[props.rowKey ?? 'id']\nconst ids = computed(() => props.rows.map(idOf))\nconst allSelected = computed(() => ids.value.length > 0 && ids.value.every((id) => selected.value.includes(id)))\nconst someSelected = computed(() => !allSelected.value && ids.value.some((id) => selected.value.includes(id)))\n\nfunction toggleAll() {\n selected.value = allSelected.value\n ? selected.value.filter((id) => !ids.value.includes(id))\n : [...new Set([...selected.value, ...ids.value])]\n}\n\nfunction toggle(id: unknown) {\n selected.value = selected.value.includes(id) ? selected.value.filter((x) => x !== id) : [...selected.value, id]\n}\n\n// Sorting a column cycles ascending, descending, unsorted.\nfunction sortBy(key: string) {\n const dir = sort.value?.key === key ? sort.value.dir : null\n const next = dir === null ? 'asc' : dir === 'asc' ? 'desc' : null\n sort.value = next ? { key, dir: next } : null\n}\n\nfunction dirOf(key: string) {\n return sort.value?.key === key ? sort.value.dir : null\n}\n\nfunction ariaSort(column: TableColumn) {\n const dir = dirOf(column.key)\n if (dir) return dir === 'asc' ? 'ascending' : 'descending'\n return column.sortable ? 'none' : undefined\n}\n\nconst state = computed(() => {\n if (slots.error) return 'error'\n if (props.loading) return 'loading'\n return props.rows.length === 0 && slots.empty ? 'empty' : 'rows'\n})\n\nconst columnCount = computed(() => props.columns.length + (props.selectable ? 1 : 0))\nconst alignClass = { left: 'text-left', center: 'text-center', right: 'text-right' }\nconst skeletonWidths = ['60%', '45%', '70%', '35%', '55%']\n\nconst sm = computed(() => props.size === 'sm')\nconst fixed = computed(() => props.rowHeight !== undefined)\nconst rowStyle = computed(() => {\n const style: Record<string, string> = {}\n if (fixed.value) style['--sui-table-row'] = `${props.rowHeight}px`\n if (props.headerHeight !== undefined) style['--sui-table-header'] = `${props.headerHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value\n ? 'h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]'\n : 'h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]'\n])\nconst td = computed(() => [\n 'border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-[var(--sui-table-row,2.5rem)]' : 'h-[var(--sui-table-row,3.5625rem)]'\n])\n// A set row height takes the cells' vertical padding with it.\nconst pad = computed(() => [sm.value ? 'px-3' : 'px-4', !fixed.value && (sm.value ? 'py-1.5' : 'py-3')])\nconst headTone = computed(() => (props.headerTone === 'canvas' ? 'bg-sui-canvas' : 'bg-sui-sunken'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4 text-left'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div\n class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\"\n :style=\"rowStyle\"\n >\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-[var(--sui-table-min,720px)] table-fixed border-collapse\">\n <caption v-if=\"caption\" class=\"sr-only\">\n {{\n caption\n }}\n </caption>\n <colgroup>\n <col v-if=\"selectable\" class=\"w-12\" />\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :style=\"{ width: typeof column.width === 'number' ? `${column.width}px` : column.width }\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-if=\"selectable\" :class=\"[th, checkCell, headTone]\">\n <Checkbox\n :aria-label=\"selectAllLabel\"\n :disabled=\"loading || rows.length === 0\"\n :indeterminate=\"someSelected\"\n :model-value=\"allSelected\"\n @update:model-value=\"toggleAll\"\n />\n </th>\n <component\n :is=\"column.label ? 'th' : 'td'\"\n v-for=\"column in columns\"\n :key=\"column.key\"\n :aria-sort=\"ariaSort(column)\"\n :class=\"[\n th,\n headPad,\n alignClass[column.align ?? 'left'],\n dirOf(column.key) ? 'bg-sui-accent-wash text-sui-accent' : [headTone, 'text-sui-ink-subtle']\n ]\"\n :scope=\"column.label ? 'col' : undefined\"\n >\n <button\n v-if=\"column.sortable\"\n class=\"inline-flex h-full w-full items-center gap-1.5 rounded-md outline-hidden focus-visible:sui-ring-inset\"\n :class=\"[\n column.align === 'right' && 'justify-end',\n column.align === 'center' && 'justify-center',\n !dirOf(column.key) && 'hover:text-sui-ink'\n ]\"\n type=\"button\"\n @click=\"sortBy(column.key)\"\n >\n {{ column.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3 shrink-0 fill-none stroke-current\"\n :class=\"!dirOf(column.key) && 'opacity-50'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path v-if=\"dirOf(column.key) === 'asc'\" d=\"M3 7.5 6 4.5l3 3\" />\n <path v-else-if=\"dirOf(column.key) === 'desc'\" d=\"M3 4.5 6 7.5l3-3\" />\n <path v-else d=\"M3.5 4.5 6 2l2.5 2.5M3.5 7.5 6 10l2.5-2.5\" />\n </svg>\n </button>\n <template v-else>{{ column.label }}</template>\n </component>\n </tr>\n </thead>\n <tbody :aria-busy=\"loading || undefined\">\n <tr v-if=\"state === 'error' || state === 'empty'\">\n <td class=\"p-0\" :colspan=\"columnCount\">\n <slot :name=\"state\" />\n </td>\n </tr>\n <template v-else-if=\"state === 'loading'\">\n <tr v-for=\"i in loadingRows\" :key=\"i\" aria-hidden=\"true\" class=\"group/row\">\n <td v-if=\"selectable\" :class=\"[td, checkCell]\"><Skeleton size=\"1rem\" /></td>\n <td v-for=\"(column, j) in columns\" :key=\"column.key\" :class=\"[td, pad]\">\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(i + j) % 5]\" />\n </td>\n </tr>\n </template>\n <template v-else>\n <tr\n v-for=\"row in rows\"\n :key=\"idOf(row) as PropertyKey\"\n :aria-selected=\"selectable ? selected.includes(idOf(row)) : undefined\"\n class=\"group/row transition-colors duration-150\"\n :class=\"[\n selected.includes(idOf(row)) ? 'bg-sui-accent-wash' : 'hover:bg-sui-sunken',\n onRowClick && 'cursor-pointer'\n ]\"\n @click=\"onRowClick?.(row)\"\n >\n <td v-if=\"selectable\" :class=\"[td, checkCell]\" @click.stop>\n <Checkbox\n :aria-label=\"selectRowLabel\"\n :model-value=\"selected.includes(idOf(row))\"\n @update:model-value=\"toggle(idOf(row))\"\n />\n </td>\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n td,\n pad,\n alignClass[column.align ?? 'left'],\n column.wrap ? 'break-words whitespace-normal' : 'truncate'\n ]\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\" :value=\"row[column.key]\">\n <template v-if=\"row[column.key] != null && row[column.key] !== ''\">{{ row[column.key] }}</template>\n <span v-else class=\"text-sui-ink-muted\">–</span>\n </slot>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"$slots.footer\"\n class=\"flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle bg-sui-canvas py-2 pr-3 pl-4 text-13 text-sui-ink-muted\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"Table.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","_useSlots","_openBlock","_createElementBlock","_normalizeStyle","_createElementVNode","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_normalizeClass","_createVNode","Checkbox","_createBlock","_resolveDynamicComponent","_withCtx","_createTextVNode","_renderSlot","Skeleton","_withModifiers","Skeleton_default","Checkbox_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","checkCell","Table_vue_vue_type_script_setup_true_lang_default","\"sort\"","\"sortModifiers\"","\"selected\"","\"selectedModifiers\"","props","__props","sort","useModel","selected","slots","useSlots","idOf","row","ids","computed","allSelected","id","someSelected","toggleAll","toggle","x","sortBy","dir","key","next","dirOf","ariaSort","column","state","columnCount","alignClass","skeletonWidths","sm","fixed","rowStyle","style","th","td","pad","headTone","headPad","openBlock","createElementBlock","normalizeStyle","createElementVNode","toDisplayString","createCommentVNode","Fragment","renderList","normalizeClass","createVNode","createBlock","resolveDynamicComponent","withCtx","createTextVNode","renderSlot","_ctx","i","j","_cache","withModifiers"],"sources":["../../../src/components/Table/Table.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { TableColumn, TableSort } from './types'\n\nexport interface TableProps<T> {\n columns: TableColumn[]\n rows: T[]\n /** The row field that identifies it. */\n rowKey?: keyof T & string\n /** A checkbox column bound to `v-model:selected`; selected rows tint accent-wash. */\n selectable?: boolean\n /** Skeleton rows in place of the body. */\n loading?: boolean\n loadingRows?: number\n /** md: 57px rows. sm: 40px, for dense lists. */\n size?: 'md' | 'sm'\n /** A row height in px between the sizes, such as 44, for body and header rows; sets `--sui-table-row`. */\n rowHeight?: number\n /** The header row's height in px, e.g. 36 over 44px rows; sets `--sui-table-header`. Defaults to the row height. */\n headerHeight?: number\n /** canvas lays the header on the page colour, for a table directly on the canvas. */\n headerTone?: 'sunken' | 'canvas'\n /** The table's name for screen readers. */\n caption?: string\n selectAllLabel?: string\n selectRowLabel?: string\n /** Makes rows clickable (`@row-click`), e.g. to open the record. */\n onRowClick?: (row: T) => void\n}\n\nconst props = withDefaults(defineProps<TableProps<T>>(), {\n rowKey: 'id' as never,\n loadingRows: 5,\n size: 'md',\n rowHeight: undefined,\n headerHeight: undefined,\n headerTone: 'sunken',\n caption: undefined,\n selectAllLabel: 'Select all rows',\n selectRowLabel: 'Select row',\n onRowClick: undefined\n})\n\nconst sort = defineModel<TableSort | null>('sort', { default: null })\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\n\nconst slots = defineSlots<\n {\n /** Shown in place of the body when there are no rows, e.g. an EmptyState. */\n empty?: () => unknown\n /** Replaces the body when given, e.g. an inset danger Alert with a retry. */\n error?: () => unknown\n /** A canvas strip under the rows: a rows-per-page Select, the range, Pagination. */\n footer?: () => unknown\n } & {\n [K in `cell-${string}`]?: (props: { row: T; value: unknown }) => unknown\n }\n>()\n\nconst idOf = (row: T): unknown => row[props.rowKey ?? 'id']\nconst ids = computed(() => props.rows.map(idOf))\nconst allSelected = computed(() => ids.value.length > 0 && ids.value.every((id) => selected.value.includes(id)))\nconst someSelected = computed(() => !allSelected.value && ids.value.some((id) => selected.value.includes(id)))\n\nfunction toggleAll() {\n selected.value = allSelected.value\n ? selected.value.filter((id) => !ids.value.includes(id))\n : [...new Set([...selected.value, ...ids.value])]\n}\n\nfunction toggle(id: unknown) {\n selected.value = selected.value.includes(id) ? selected.value.filter((x) => x !== id) : [...selected.value, id]\n}\n\n// Sorting a column cycles ascending, descending, unsorted.\nfunction sortBy(key: string) {\n const dir = sort.value?.key === key ? sort.value.dir : null\n const next = dir === null ? 'asc' : dir === 'asc' ? 'desc' : null\n sort.value = next ? { key, dir: next } : null\n}\n\nfunction dirOf(key: string) {\n return sort.value?.key === key ? sort.value.dir : null\n}\n\nfunction ariaSort(column: TableColumn) {\n const dir = dirOf(column.key)\n if (dir) return dir === 'asc' ? 'ascending' : 'descending'\n return column.sortable ? 'none' : undefined\n}\n\nconst state = computed(() => {\n if (slots.error) return 'error'\n if (props.loading) return 'loading'\n return props.rows.length === 0 && slots.empty ? 'empty' : 'rows'\n})\n\nconst columnCount = computed(() => props.columns.length + (props.selectable ? 1 : 0))\nconst alignClass = { left: 'text-left', center: 'text-center', right: 'text-right' }\nconst skeletonWidths = ['60%', '45%', '70%', '35%', '55%']\n\nconst sm = computed(() => props.size === 'sm')\nconst fixed = computed(() => props.rowHeight !== undefined)\nconst rowStyle = computed(() => {\n const style: Record<string, string> = {}\n if (fixed.value) style['--sui-table-row'] = `${props.rowHeight}px`\n if (props.headerHeight !== undefined) style['--sui-table-header'] = `${props.headerHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value\n ? 'h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]'\n : 'h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]'\n])\nconst td = computed(() => [\n 'border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-[var(--sui-table-row,2.5rem)]' : 'h-[var(--sui-table-row,3.5625rem)]'\n])\n// A set row height takes the cells' vertical padding with it.\nconst pad = computed(() => [sm.value ? 'px-3' : 'px-4', !fixed.value && (sm.value ? 'py-1.5' : 'py-3')])\nconst headTone = computed(() => (props.headerTone === 'canvas' ? 'bg-sui-canvas' : 'sui-band'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4 text-left'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div\n class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\"\n :style=\"rowStyle\"\n >\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-[var(--sui-table-min,720px)] table-fixed border-collapse\">\n <caption v-if=\"caption\" class=\"sr-only\">\n {{\n caption\n }}\n </caption>\n <colgroup>\n <col v-if=\"selectable\" class=\"w-12\" />\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :style=\"{ width: typeof column.width === 'number' ? `${column.width}px` : column.width }\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-if=\"selectable\" :class=\"[th, checkCell, headTone]\">\n <Checkbox\n :aria-label=\"selectAllLabel\"\n :disabled=\"loading || rows.length === 0\"\n :indeterminate=\"someSelected\"\n :model-value=\"allSelected\"\n @update:model-value=\"toggleAll\"\n />\n </th>\n <component\n :is=\"column.label ? 'th' : 'td'\"\n v-for=\"column in columns\"\n :key=\"column.key\"\n :aria-sort=\"ariaSort(column)\"\n :class=\"[\n th,\n headPad,\n alignClass[column.align ?? 'left'],\n dirOf(column.key) ? 'bg-sui-accent-wash text-sui-accent' : [headTone, 'text-sui-ink-subtle']\n ]\"\n :scope=\"column.label ? 'col' : undefined\"\n >\n <button\n v-if=\"column.sortable\"\n class=\"inline-flex h-full w-full items-center gap-1.5 rounded-md outline-hidden focus-visible:sui-ring-inset\"\n :class=\"[\n column.align === 'right' && 'justify-end',\n column.align === 'center' && 'justify-center',\n !dirOf(column.key) && 'hover:text-sui-ink'\n ]\"\n type=\"button\"\n @click=\"sortBy(column.key)\"\n >\n {{ column.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3 shrink-0 fill-none stroke-current\"\n :class=\"!dirOf(column.key) && 'opacity-50'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path v-if=\"dirOf(column.key) === 'asc'\" d=\"M3 7.5 6 4.5l3 3\" />\n <path v-else-if=\"dirOf(column.key) === 'desc'\" d=\"M3 4.5 6 7.5l3-3\" />\n <path v-else d=\"M3.5 4.5 6 2l2.5 2.5M3.5 7.5 6 10l2.5-2.5\" />\n </svg>\n </button>\n <template v-else>{{ column.label }}</template>\n </component>\n </tr>\n </thead>\n <tbody :aria-busy=\"loading || undefined\">\n <tr v-if=\"state === 'error' || state === 'empty'\">\n <td class=\"p-0\" :colspan=\"columnCount\">\n <slot :name=\"state\" />\n </td>\n </tr>\n <template v-else-if=\"state === 'loading'\">\n <tr v-for=\"i in loadingRows\" :key=\"i\" aria-hidden=\"true\" class=\"group/row\">\n <td v-if=\"selectable\" :class=\"[td, checkCell]\"><Skeleton size=\"1rem\" /></td>\n <td v-for=\"(column, j) in columns\" :key=\"column.key\" :class=\"[td, pad]\">\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(i + j) % 5]\" />\n </td>\n </tr>\n </template>\n <template v-else>\n <tr\n v-for=\"row in rows\"\n :key=\"idOf(row) as PropertyKey\"\n :aria-selected=\"selectable ? selected.includes(idOf(row)) : undefined\"\n class=\"group/row transition-colors duration-150\"\n :class=\"[\n selected.includes(idOf(row)) ? 'bg-sui-accent-wash' : 'hover:bg-sui-fill-hover',\n onRowClick && 'cursor-pointer'\n ]\"\n @click=\"onRowClick?.(row)\"\n >\n <td v-if=\"selectable\" :class=\"[td, checkCell]\" @click.stop>\n <Checkbox\n :aria-label=\"selectRowLabel\"\n :model-value=\"selected.includes(idOf(row))\"\n @update:model-value=\"toggle(idOf(row))\"\n />\n </td>\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n td,\n pad,\n alignClass[column.align ?? 'left'],\n column.wrap ? 'break-words whitespace-normal' : 'truncate'\n ]\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\" :value=\"row[column.key]\">\n <template v-if=\"row[column.key] != null && row[column.key] !== ''\">{{ row[column.key] }}</template>\n <span v-else class=\"text-sui-ink-muted\">–</span>\n </slot>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"$slots.footer\"\n class=\"flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle py-2 pr-3 pl-4 text-13 text-sui-ink-muted\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}