@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.
- package/README.md +1 -1
- package/dist/aliases.d.ts +4 -0
- package/dist/components/ActionBar/ActionBar.js.map +1 -1
- package/dist/components/ActionBar/ActionBar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/ActionBar/ActionBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Alert/Alert.js.map +1 -1
- package/dist/components/Alert/Alert.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Alert/Alert.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/AlertDialog/AlertDialog.js.map +1 -1
- package/dist/components/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Badge/Badge.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Badge/Badge.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Board/Board.js.map +1 -1
- package/dist/components/Board/Board.vue.d.ts +3 -0
- package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js +68 -63
- package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js +23 -22
- package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Calendar/Calendar.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Calendar/Calendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/DataList/DataList.js.map +1 -1
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js +103 -103
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Dialog/ContextSeparator.js +19 -0
- package/dist/components/Dialog/ContextSeparator.js.map +1 -0
- package/dist/components/Dialog/ContextSeparator.vue.d.ts +3 -0
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/Dialog/Dialog.vue.d.ts +16 -11
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +130 -119
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Dialog/focus.d.ts +2 -0
- package/dist/components/Dialog/focus.js +2 -2
- package/dist/components/Dialog/focus.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/FilterChip.js.map +1 -1
- package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/FilterFrame.js.map +1 -1
- package/dist/components/Filters/FilterFrame.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Filters/FilterFrame.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/FilterMenu.js.map +1 -1
- package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/SortMenu.js.map +1 -1
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/Input/Input.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Input/Input.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Kbd/Kbd.js +1 -1
- package/dist/components/Kbd/Kbd.js.map +1 -1
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Popover/Popover.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Popover/Popover.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Popover/PopoverDialog.js.map +1 -1
- package/dist/components/Popover/PopoverDialog.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Popover/PopoverDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/PropertyList/Editable.js.map +1 -1
- package/dist/components/PropertyList/Editable.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/PropertyList/Editable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Select/Select.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/Select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Tag/Tag.js.map +1 -1
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Textarea/Textarea.js.map +1 -1
- package/dist/components/Textarea/Textarea.vue.d.ts +3 -0
- package/dist/components/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js +7 -2
- package/dist/components/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/internal/menu.d.ts +2 -2
- package/dist/components/internal/menu.js +1 -1
- package/dist/components/internal/menu.js.map +1 -1
- package/dist/index.js +15 -15
- package/package.json +1 -1
- package/src/styles/tailwind.css +93 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_createVNode","Tooltip","_withCtx","ChevronIcon","_Fragment","_renderList","_normalizeClass","_createTextVNode","_createCommentVNode","Tooltip_default","ChevronIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","Calendar_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","view","ref","startOfMonth","date","title","computed","dayNames","i","shiftMonth","addMonths","months","cells","first","startOfWeek","last","addDays","count","differenceInDays","today","startOfDay","start","end","ranged","isSameDay","low","high","a","b","isStart","isEnd","selected","inRange","isToday","column","isSameMonth","openBlock","createElementBlock","createElementVNode","toDisplayString","createVNode","withCtx","_cache","Fragment","renderList","day","cell","normalizeClass","createTextVNode","createCommentVNode"],"sources":["../../../src/components/Calendar/Calendar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport {\n addDays,\n addMonths,\n differenceInDays,\n isSameDay,\n isSameMonth,\n startOfDay,\n startOfMonth,\n startOfWeek\n} from '../../utils/dates'\nimport Tooltip from '../Tooltip/Tooltip.vue'\nimport ChevronIcon from '../internal/ChevronIcon.vue'\n\nexport interface CalendarProps {\n /** Selects a day; with `end`, a range. */\n start?: Date | null\n end?: Date | null\n /** For the month's name and the weekdays; the browser's language by default. */\n locale?: string\n /** Monday first; the locale's narrow names by default. */\n weekdays?: string[]\n previousLabel?: string\n nextLabel?: string\n}\n\nconst props = withDefaults(defineProps<CalendarProps>(), {\n start: null,\n end: null,\n locale: undefined,\n weekdays: undefined,\n previousLabel: 'Previous month',\n nextLabel: 'Next month'\n})\n\nconst emit = defineEmits<{ pick: [date: Date] }>()\n\nconst view = ref(startOfMonth(props.end ?? props.start ?? new Date()))\n\n// Follows the selection to its month, when it's picked elsewhere (a shortcut, say).\nwatch(\n () => props.end ?? props.start,\n (date) => {\n if (date) view.value = startOfMonth(date)\n }\n)\n\nconst title = computed(() =>\n new Intl.DateTimeFormat(props.locale, { month: 'long', year: 'numeric' }).format(view.value)\n)\n\n// 1 January 2024 was a Monday.\nconst dayNames = computed(\n () =>\n props.weekdays ??\n Array.from({ length: 7 }, (_, i) =>\n new Intl.DateTimeFormat(props.locale, { weekday: 'narrow' }).format(new Date(2024, 0, 1 + i))\n )\n)\n\nconst shiftMonth = (months: number) => (view.value = addMonths(view.value, months))\n\nconst cells = computed(() => {\n const first = startOfWeek(view.value)\n const last = addDays(addMonths(view.value, 1), -1)\n const count = Math.ceil((differenceInDays(last, first) + 1) / 7) * 7\n const today = startOfDay(new Date())\n const [start, end] = [props.start, props.end].map((date) => (date ? startOfDay(date) : null))\n const ranged = !!start && !!end && !isSameDay(start, end)\n const [low, high] = ranged ? [start!, end!].sort((a, b) => a.getTime() - b.getTime()) : []\n\n return Array.from({ length: count }, (_, i) => {\n const date = addDays(first, i)\n const isStart = !!start && isSameDay(date, start)\n const isEnd = !!end && isSameDay(date, end)\n const selected = isStart || isEnd\n const inRange = ranged && date >= low! && date <= high!\n const isToday = isSameDay(date, today)\n const column = i % 7\n\n return {\n key: date.toISOString(),\n date,\n label: date.getDate(),\n selected,\n isToday,\n // The range is a band behind the days, rounded where it starts, ends or wraps.\n band: inRange\n ? ['bg-sui-accent-wash', (isStart || column === 0) && 'rounded-l-lg', (isEnd || column === 6) && 'rounded-r-lg']\n : '',\n classes: selected\n ? 'bg-sui-accent-solid font-semibold text-sui-on-accent'\n : [\n 'hover:bg-sui-sunken',\n isToday\n ? 'font-semibold text-sui-accent ring-1 ring-sui-accent-line ring-inset'\n : inRange\n ? 'font-medium text-sui-accent'\n : !isSameMonth(date, view.value) || date > today\n ? 'text-sui-ink-muted'\n : 'text-sui-ink'\n ]\n }\n })\n})\n</script>\n\n<!-- A month of days, weeks from Monday: today outlined with a dot, future days and other months muted. Picking a day\n emits it; the host decides what it selects. -->\n<template>\n <div>\n <div class=\"flex h-11 items-center justify-between\">\n <span class=\"pl-1.5 text-13 font-semibold text-sui-ink\">{{ title }}</span>\n <div class=\"flex gap-0.5\">\n <Tooltip :text=\"previousLabel\">\n <button\n :aria-label=\"previousLabel\"\n class=\"flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-sunken focus-visible:sui-ring\"\n type=\"button\"\n @click=\"shiftMonth(-1)\"\n >\n <ChevronIcon class=\"h-4 w-4 fill-sui-ink-body stroke-sui-ink-body\" direction=\"left\" />\n </button>\n </Tooltip>\n <Tooltip :text=\"nextLabel\">\n <button\n :aria-label=\"nextLabel\"\n class=\"flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-sunken focus-visible:sui-ring\"\n type=\"button\"\n @click=\"shiftMonth(1)\"\n >\n <ChevronIcon class=\"h-4 w-4 fill-sui-ink-body stroke-sui-ink-body\" direction=\"right\" />\n </button>\n </Tooltip>\n </div>\n </div>\n <div aria-hidden=\"true\" class=\"grid h-5.5 grid-cols-7 items-center\">\n <span v-for=\"(day, i) in dayNames\" :key=\"i\" class=\"text-center text-11 font-semibold text-sui-ink-muted\">\n {{ day }}\n </span>\n </div>\n <div class=\"mt-0.5 grid grid-cols-7 gap-y-0.5\">\n <button\n v-for=\"cell in cells\"\n :key=\"cell.key\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.date.toLocaleDateString(locale, { dateStyle: 'full' })\"\n :aria-pressed=\"cell.selected\"\n :class=\"['group flex h-9 items-center justify-center outline-hidden', cell.band]\"\n type=\"button\"\n @click=\"emit('pick', cell.date)\"\n >\n <span\n class=\"relative flex h-8.5 w-9 items-center justify-center rounded-lg text-13 tabular-nums transition-colors group-focus-visible:sui-ring\"\n :class=\"cell.classes\"\n >\n {{ cell.label }}\n <span\n v-if=\"cell.isToday\"\n class=\"absolute bottom-1 left-1/2 h-1 w-1 -translate-x-1/2 rounded-full\"\n :class=\"cell.selected ? 'bg-sui-on-accent' : 'bg-sui-accent-solid'\"\n />\n </span>\n </button>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Calendar.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_createVNode","Tooltip","_withCtx","ChevronIcon","_Fragment","_renderList","_normalizeClass","_createTextVNode","_createCommentVNode","Tooltip_default","ChevronIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","Calendar_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","view","ref","startOfMonth","date","title","computed","dayNames","i","shiftMonth","addMonths","months","cells","first","startOfWeek","last","addDays","count","differenceInDays","today","startOfDay","start","end","ranged","isSameDay","low","high","a","b","isStart","isEnd","selected","inRange","isToday","column","isSameMonth","openBlock","createElementBlock","createElementVNode","toDisplayString","createVNode","withCtx","_cache","Fragment","renderList","day","cell","normalizeClass","createTextVNode","createCommentVNode"],"sources":["../../../src/components/Calendar/Calendar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport {\n addDays,\n addMonths,\n differenceInDays,\n isSameDay,\n isSameMonth,\n startOfDay,\n startOfMonth,\n startOfWeek\n} from '../../utils/dates'\nimport Tooltip from '../Tooltip/Tooltip.vue'\nimport ChevronIcon from '../internal/ChevronIcon.vue'\n\nexport interface CalendarProps {\n /** Selects a day; with `end`, a range. */\n start?: Date | null\n end?: Date | null\n /** For the month's name and the weekdays; the browser's language by default. */\n locale?: string\n /** Monday first; the locale's narrow names by default. */\n weekdays?: string[]\n previousLabel?: string\n nextLabel?: string\n}\n\nconst props = withDefaults(defineProps<CalendarProps>(), {\n start: null,\n end: null,\n locale: undefined,\n weekdays: undefined,\n previousLabel: 'Previous month',\n nextLabel: 'Next month'\n})\n\nconst emit = defineEmits<{ pick: [date: Date] }>()\n\nconst view = ref(startOfMonth(props.end ?? props.start ?? new Date()))\n\n// Follows the selection to its month, when it's picked elsewhere (a shortcut, say).\nwatch(\n () => props.end ?? props.start,\n (date) => {\n if (date) view.value = startOfMonth(date)\n }\n)\n\nconst title = computed(() =>\n new Intl.DateTimeFormat(props.locale, { month: 'long', year: 'numeric' }).format(view.value)\n)\n\n// 1 January 2024 was a Monday.\nconst dayNames = computed(\n () =>\n props.weekdays ??\n Array.from({ length: 7 }, (_, i) =>\n new Intl.DateTimeFormat(props.locale, { weekday: 'narrow' }).format(new Date(2024, 0, 1 + i))\n )\n)\n\nconst shiftMonth = (months: number) => (view.value = addMonths(view.value, months))\n\nconst cells = computed(() => {\n const first = startOfWeek(view.value)\n const last = addDays(addMonths(view.value, 1), -1)\n const count = Math.ceil((differenceInDays(last, first) + 1) / 7) * 7\n const today = startOfDay(new Date())\n const [start, end] = [props.start, props.end].map((date) => (date ? startOfDay(date) : null))\n const ranged = !!start && !!end && !isSameDay(start, end)\n const [low, high] = ranged ? [start!, end!].sort((a, b) => a.getTime() - b.getTime()) : []\n\n return Array.from({ length: count }, (_, i) => {\n const date = addDays(first, i)\n const isStart = !!start && isSameDay(date, start)\n const isEnd = !!end && isSameDay(date, end)\n const selected = isStart || isEnd\n const inRange = ranged && date >= low! && date <= high!\n const isToday = isSameDay(date, today)\n const column = i % 7\n\n return {\n key: date.toISOString(),\n date,\n label: date.getDate(),\n selected,\n isToday,\n // The range is a band behind the days, rounded where it starts, ends or wraps.\n band: inRange\n ? ['bg-sui-accent-wash', (isStart || column === 0) && 'rounded-l-lg', (isEnd || column === 6) && 'rounded-r-lg']\n : '',\n classes: selected\n ? 'bg-sui-accent-solid font-semibold text-sui-on-accent'\n : [\n 'hover:bg-sui-fill-hover',\n isToday\n ? 'font-semibold text-sui-accent ring-1 ring-sui-accent-line ring-inset'\n : inRange\n ? 'font-medium text-sui-accent'\n : !isSameMonth(date, view.value) || date > today\n ? 'text-sui-ink-muted'\n : 'text-sui-ink'\n ]\n }\n })\n})\n</script>\n\n<!-- A month of days, weeks from Monday: today outlined with a dot, future days and other months muted. Picking a day\n emits it; the host decides what it selects. -->\n<template>\n <div>\n <div class=\"flex h-11 items-center justify-between\">\n <span class=\"pl-1.5 text-13 font-semibold text-sui-ink\">{{ title }}</span>\n <div class=\"flex gap-0.5\">\n <Tooltip :text=\"previousLabel\">\n <button\n :aria-label=\"previousLabel\"\n class=\"flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-fill-hover focus-visible:sui-ring\"\n type=\"button\"\n @click=\"shiftMonth(-1)\"\n >\n <ChevronIcon class=\"h-4 w-4 fill-sui-ink-body stroke-sui-ink-body\" direction=\"left\" />\n </button>\n </Tooltip>\n <Tooltip :text=\"nextLabel\">\n <button\n :aria-label=\"nextLabel\"\n class=\"flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-fill-hover focus-visible:sui-ring\"\n type=\"button\"\n @click=\"shiftMonth(1)\"\n >\n <ChevronIcon class=\"h-4 w-4 fill-sui-ink-body stroke-sui-ink-body\" direction=\"right\" />\n </button>\n </Tooltip>\n </div>\n </div>\n <div aria-hidden=\"true\" class=\"grid h-5.5 grid-cols-7 items-center\">\n <span v-for=\"(day, i) in dayNames\" :key=\"i\" class=\"text-center text-11 font-semibold text-sui-ink-muted\">\n {{ day }}\n </span>\n </div>\n <div class=\"mt-0.5 grid grid-cols-7 gap-y-0.5\">\n <button\n v-for=\"cell in cells\"\n :key=\"cell.key\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.date.toLocaleDateString(locale, { dateStyle: 'full' })\"\n :aria-pressed=\"cell.selected\"\n :class=\"['group flex h-9 items-center justify-center outline-hidden', cell.band]\"\n type=\"button\"\n @click=\"emit('pick', cell.date)\"\n >\n <span\n class=\"relative flex h-8.5 w-9 items-center justify-center rounded-lg text-13 tabular-nums transition-colors group-focus-visible:sui-ring\"\n :class=\"cell.classes\"\n >\n {{ cell.label }}\n <span\n v-if=\"cell.isToday\"\n class=\"absolute bottom-1 left-1/2 h-1 w-1 -translate-x-1/2 rounded-full\"\n :class=\"cell.selected ? 'bg-sui-on-accent' : 'bg-sui-accent-solid'\"\n />\n </span>\n </button>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EA4BA,IAAMyB,IAAQC,GASRC,IAAOH,GAEPI,IAAOC,EAAIC,EAAaL,EAAM,OAAOA,EAAM,yBAAS,IAAI,KAAK,CAAC,CAAC;EAGrE,QACQA,EAAM,OAAOA,EAAM,QACxB,MAAS;GACR,AAAIM,MAAM,EAAK,QAAQD,EAAaC,CAAI;EAC1C,CACF;EAEA,IAAMC,IAAQC,QACZ,IAAI,KAAK,eAAeR,EAAM,QAAQ;GAAE,OAAO;GAAQ,MAAM;EAAU,CAAC,CAAC,CAAC,OAAOG,EAAK,KAAK,CAC7F,GAGMM,IAAWD,QAEbR,EAAM,YACN,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,GAAG,MAC5B,IAAI,KAAK,eAAeA,EAAM,QAAQ,EAAE,SAAS,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,KAAK,MAAM,GAAG,IAAIU,CAAC,CAAC,CAC9F,CACJ,GAEMC,KAAc,MAAoB,EAAK,QAAQC,EAAUT,EAAK,OAAOU,CAAM,GAE3EC,IAAQN,QAAe;GAC3B,IAAMO,IAAQC,EAAYb,EAAK,KAAK,GAC9Bc,IAAOC,EAAQN,EAAUT,EAAK,OAAO,CAAC,GAAG,EAAE,GAC3CgB,IAAQ,KAAK,MAAMC,EAAiBH,GAAMF,CAAK,IAAI,KAAK,CAAC,IAAI,GAC7DM,IAAQC,kBAAW,IAAI,KAAK,CAAC,GAC7B,CAACC,GAAOC,KAAO,CAACxB,EAAM,OAAOA,EAAM,GAAG,CAAC,CAAC,KAAK,MAAUM,IAAOgB,EAAWhB,CAAI,IAAI,IAAK,GACtFmB,IAAS,CAAC,CAACF,KAAS,CAAC,CAACC,KAAO,CAACE,EAAUH,GAAOC,CAAG,GAClD,CAACG,GAAKC,KAAQH,IAAS,CAACF,GAAQC,CAAI,CAAC,CAAC,MAAM,GAAG,MAAMK,EAAE,QAAQ,IAAIC,EAAE,QAAQ,CAAC,IAAI,CAAC;GAEzF,OAAO,MAAM,KAAK,EAAE,QAAQX,EAAM,IAAI,GAAG,MAAM;IAC7C,IAAMb,IAAOY,EAAQH,GAAOL,CAAC,GACvBqB,IAAU,CAAC,CAACR,KAASG,EAAUpB,GAAMiB,CAAK,GAC1CS,IAAQ,CAAC,CAACR,KAAOE,EAAUpB,GAAMkB,CAAG,GACpCS,IAAWF,KAAWC,GACtBE,IAAUT,KAAUnB,KAAQqB,KAAQrB,KAAQsB,GAC5CO,IAAUT,EAAUpB,GAAMe,CAAK,GAC/Be,IAAS1B,IAAI;IAEnB,OAAO;KACL,KAAKJ,EAAK,YAAY;KACtB;KACA,OAAOA,EAAK,QAAQ;KACpB;KACA;KAEA,MAAM4B,IACF;MAAC;OAAuBH,KAAWK,MAAW,MAAM;OAAiBJ,KAASI,MAAW,MAAM;KAAc,IAC7G;KACJ,SAASH,IACL,yDACA,CACE,2BACAE,IACI,yEACAD,IACE,gCACA,CAACG,EAAY/B,GAAMH,EAAK,KAAK,KAAKG,IAAOe,IACvC,uBACA,cACV;IACN;GACF,CAAC;EACH,CAAC;E,kBAMC9C,EAAA,GAAAC,EAuDM,OAAA,MAAA;GAtDJC,EAwBM,OAxBNa,GAwBM,CAvBJb,EAA0E,QAA1Ec,GAA0Eb,EAAf6B,EAAA,KAAK,GAAA,CAAA,GAChE9B,EAqBM,OArBNe,GAqBM,CApBJb,EASUC,GAAA,EATA,MAAMqB,EAAA,cAAa,GAAA;IAC3B,SAAApB,QAOS,CAPTJ,EAOS,UAAA;KANN,cAAYwB,EAAA;KACb,OAAM;KACN,MAAK;KACJ,SAAK,AAAA2C,EAAA,QAAA,MAAEjC,EAAU,EAAA;I,IAElBhC,EAAsFG,GAAA;KAAzE,OAAM;KAAgD,WAAU;;;G,iBAGjFH,EASUC,GAAA,EATA,MAAMqB,EAAA,UAAS,GAAA;IACvB,SAAApB,QAOS,CAPTJ,EAOS,UAAA;KANN,cAAYwB,EAAA;KACb,OAAM;KACN,MAAK;KACJ,SAAK,AAAA2C,EAAA,QAAA,MAAEjC,EAAU,CAAA;I,IAElBhC,EAAuFG,GAAA;KAA1E,OAAM;KAAgD,WAAU;;;;GAKrFL,EAIM,OAJNkB,GAIM,EAHJpB,EAAA,EAAA,GAAAC,EAEOO,GAAA,MAAAC,EAFkByB,EAAA,QAAX,GAAK,OAAnBlC,EAAA,GAAAC,EAEO,QAAA;IAF6B,KAAKkC;IAAG,OAAM;GAC7C,GAAAhC,EAAAqE,CAAG,GAAA,CAAA,E;GAGVtE,EAuBM,OAvBNmB,GAuBM,EAtBJrB,EAAA,EAAA,GAAAC,EAqBSO,GAAA,MAAAC,EApBQ8B,EAAA,QAAR,OADTvC,EAAA,GAAAC,EAqBS,UAAA;IAnBN,KAAKwE,EAAK;IACV,gBAAcA,EAAK,UAAO,SAAY,KAAA;IACtC,cAAYA,EAAK,KAAK,mBAAmB/C,EAAA,QAAM,EAAA,WAAA,OAAA,CAAA;IAC/C,gBAAc+C,EAAK;IACnB,OAAK/D,EAAA,CAAA,6DAAgE+D,EAAK,IAAI,CAAA;IAC/E,MAAK;IACJ,UAAK,MAAE9C,EAAI,QAAS8C,EAAK,IAAI;G,IAE9BvE,EAUO,QAAA,EATL,OAAKQ,EAAA,CAAC,sIACE+D,EAAK,OAAO,CAAA,E,IAEjB9D,EAAAR,EAAAsE,EAAK,KAAK,IAAG,KAChB,CAAA,GACQA,EAAK,WADbzE,EAAA,GAAAC,EAIE,QAAA;;IAFA,OAAKS,EAAA,CAAC,oEACE+D,EAAK,WAAQ,qBAAA,qBAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.js","names":["_sfc_main","Checkbox_vue_vue_type_script_setup_true_lang_default","Checkbox_default"],"sources":["../../../src/components/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nexport interface CheckboxProps {\n invalid?: boolean\n disabled?: boolean\n /** Some but not all of a group are checked, e.g. a table's select-all. Shows a dash; checking clears it. */\n indeterminate?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = defineProps<CheckboxProps>()\n\nconst model = defineModel<boolean>({ default: false })\n\n// Class and style size the control; everything else (id, name, aria-label) belongs on the input.\nconst attrs = useAttrs()\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n return rest\n})\n\nconst filled = computed(() => model.value || props.indeterminate)\n\nconst box = computed(() => [\n filled.value\n ? 'border-sui-accent-solid bg-sui-accent-solid'\n : props.invalid\n ? 'border-sui-danger-mid'\n : 'border-sui-line-control bg-
|
|
1
|
+
{"version":3,"file":"Checkbox.js","names":["_sfc_main","Checkbox_vue_vue_type_script_setup_true_lang_default","Checkbox_default"],"sources":["../../../src/components/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nexport interface CheckboxProps {\n invalid?: boolean\n disabled?: boolean\n /** Some but not all of a group are checked, e.g. a table's select-all. Shows a dash; checking clears it. */\n indeterminate?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = defineProps<CheckboxProps>()\n\nconst model = defineModel<boolean>({ default: false })\n\n// Class and style size the control; everything else (id, name, aria-label) belongs on the input.\nconst attrs = useAttrs()\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n return rest\n})\n\nconst filled = computed(() => model.value || props.indeterminate)\n\nconst box = computed(() => [\n filled.value\n ? 'border-sui-accent-solid bg-sui-accent-solid'\n : props.invalid\n ? 'border-sui-danger-mid'\n : 'border-sui-line-control bg-transparent',\n props.disabled\n ? 'cursor-default opacity-60'\n : [!filled.value && !props.invalid && 'peer-hover:border-sui-accent-solid', 'peer-focus-visible:sui-ring']\n])\n</script>\n\n<template>\n <div\n class=\"relative inline-flex h-4 w-4 cursor-pointer align-bottom text-sui-on-accent select-none\"\n :class=\"attrs.class\"\n :style=\"attrs.style as string\"\n >\n <input\n v-bind=\"inputAttrs\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n :checked=\"model\"\n class=\"peer absolute top-0 left-0 z-10 m-0 h-full w-full cursor-pointer appearance-none p-0 opacity-0 outline-hidden\"\n :disabled=\"disabled\"\n :indeterminate=\"indeterminate && !model\"\n type=\"checkbox\"\n @change=\"model = ($event.target as HTMLInputElement).checked\"\n />\n <div class=\"flex h-4 w-4 items-center justify-center rounded border transition-colors duration-200\" :class=\"box\">\n <svg\n v-if=\"indeterminate && !model\"\n aria-hidden=\"true\"\n class=\"size-2.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"2\"\n viewBox=\"0 0 10 10\"\n >\n <path d=\"M2 5h6\" />\n </svg>\n <svg\n v-else-if=\"model\"\n aria-hidden=\"true\"\n class=\"h-4 w-4 text-base leading-none text-sui-on-accent transition-all duration-200\"\n fill=\"none\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n width=\"14\"\n >\n <path\n d=\"M4.86199 11.5948C4.78717 11.5923 4.71366 11.5745 4.64596 11.5426C4.57826 11.5107 4.51779 11.4652 4.46827 11.4091L0.753985 7.69483C0.683167 7.64891 0.623706 7.58751 0.580092 7.51525C0.536478 7.44299 0.509851 7.36177 0.502221 7.27771C0.49459 7.19366 0.506156 7.10897 0.536046 7.03004C0.565935 6.95111 0.613367 6.88 0.674759 6.82208C0.736151 6.76416 0.8099 6.72095 0.890436 6.69571C0.970973 6.67046 1.05619 6.66385 1.13966 6.67635C1.22313 6.68886 1.30266 6.72017 1.37226 6.76792C1.44186 6.81567 1.4997 6.8786 1.54141 6.95197L4.86199 10.2503L12.6397 2.49483C12.7444 2.42694 12.8689 2.39617 12.9932 2.40745C13.1174 2.41873 13.2343 2.47141 13.3251 2.55705C13.4159 2.64268 13.4753 2.75632 13.4938 2.87973C13.5123 3.00315 13.4888 3.1292 13.4271 3.23768L5.2557 11.4091C5.20618 11.4652 5.14571 11.5107 5.07801 11.5426C5.01031 11.5745 4.9368 11.5923 4.86199 11.5948Z\"\n fill=\"currentColor\"\n />\n </svg>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -39,7 +39,7 @@ var p = [
|
|
|
39
39
|
let a = i, g = f(i, "modelValue"), _ = d(), v = e(() => {
|
|
40
40
|
let { class: e, style: t, ...n } = _;
|
|
41
41
|
return n;
|
|
42
|
-
}), y = e(() => g.value || a.indeterminate), b = e(() => [y.value ? "border-sui-accent-solid bg-sui-accent-solid" : a.invalid ? "border-sui-danger-mid" : "border-sui-line-control bg-
|
|
42
|
+
}), y = e(() => g.value || a.indeterminate), b = e(() => [y.value ? "border-sui-accent-solid bg-sui-accent-solid" : a.invalid ? "border-sui-danger-mid" : "border-sui-line-control bg-transparent", a.disabled ? "cursor-default opacity-60" : [!y.value && !a.invalid && "peer-hover:border-sui-accent-solid", "peer-focus-visible:sui-ring"]]);
|
|
43
43
|
return (e, a) => (l(), n("div", {
|
|
44
44
|
class: s(["relative inline-flex h-4 w-4 cursor-pointer align-bottom text-sui-on-accent select-none", u(_).class]),
|
|
45
45
|
style: c(u(_).style)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_createElementVNode","_mergeProps","_createCommentVNode","_hoisted_1","_hoisted_2","_hoisted_3","Checkbox_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","props","__props","model","useModel","attrs","useAttrs","inputAttrs","computed","_class","_style","rest","filled","box","openBlock","createElementBlock","normalizeClass","unref","normalizeStyle","createElementVNode","mergeProps","_cache","$event","createCommentVNode"],"sources":["../../../src/components/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nexport interface CheckboxProps {\n invalid?: boolean\n disabled?: boolean\n /** Some but not all of a group are checked, e.g. a table's select-all. Shows a dash; checking clears it. */\n indeterminate?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = defineProps<CheckboxProps>()\n\nconst model = defineModel<boolean>({ default: false })\n\n// Class and style size the control; everything else (id, name, aria-label) belongs on the input.\nconst attrs = useAttrs()\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n return rest\n})\n\nconst filled = computed(() => model.value || props.indeterminate)\n\nconst box = computed(() => [\n filled.value\n ? 'border-sui-accent-solid bg-sui-accent-solid'\n : props.invalid\n ? 'border-sui-danger-mid'\n : 'border-sui-line-control bg-
|
|
1
|
+
{"version":3,"file":"Checkbox.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_createElementVNode","_mergeProps","_createCommentVNode","_hoisted_1","_hoisted_2","_hoisted_3","Checkbox_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","props","__props","model","useModel","attrs","useAttrs","inputAttrs","computed","_class","_style","rest","filled","box","openBlock","createElementBlock","normalizeClass","unref","normalizeStyle","createElementVNode","mergeProps","_cache","$event","createCommentVNode"],"sources":["../../../src/components/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nexport interface CheckboxProps {\n invalid?: boolean\n disabled?: boolean\n /** Some but not all of a group are checked, e.g. a table's select-all. Shows a dash; checking clears it. */\n indeterminate?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = defineProps<CheckboxProps>()\n\nconst model = defineModel<boolean>({ default: false })\n\n// Class and style size the control; everything else (id, name, aria-label) belongs on the input.\nconst attrs = useAttrs()\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n return rest\n})\n\nconst filled = computed(() => model.value || props.indeterminate)\n\nconst box = computed(() => [\n filled.value\n ? 'border-sui-accent-solid bg-sui-accent-solid'\n : props.invalid\n ? 'border-sui-danger-mid'\n : 'border-sui-line-control bg-transparent',\n props.disabled\n ? 'cursor-default opacity-60'\n : [!filled.value && !props.invalid && 'peer-hover:border-sui-accent-solid', 'peer-focus-visible:sui-ring']\n])\n</script>\n\n<template>\n <div\n class=\"relative inline-flex h-4 w-4 cursor-pointer align-bottom text-sui-on-accent select-none\"\n :class=\"attrs.class\"\n :style=\"attrs.style as string\"\n >\n <input\n v-bind=\"inputAttrs\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n :checked=\"model\"\n class=\"peer absolute top-0 left-0 z-10 m-0 h-full w-full cursor-pointer appearance-none p-0 opacity-0 outline-hidden\"\n :disabled=\"disabled\"\n :indeterminate=\"indeterminate && !model\"\n type=\"checkbox\"\n @change=\"model = ($event.target as HTMLInputElement).checked\"\n />\n <div class=\"flex h-4 w-4 items-center justify-center rounded border transition-colors duration-200\" :class=\"box\">\n <svg\n v-if=\"indeterminate && !model\"\n aria-hidden=\"true\"\n class=\"size-2.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"2\"\n viewBox=\"0 0 10 10\"\n >\n <path d=\"M2 5h6\" />\n </svg>\n <svg\n v-else-if=\"model\"\n aria-hidden=\"true\"\n class=\"h-4 w-4 text-base leading-none text-sui-on-accent transition-all duration-200\"\n fill=\"none\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n width=\"14\"\n >\n <path\n d=\"M4.86199 11.5948C4.78717 11.5923 4.71366 11.5745 4.64596 11.5426C4.57826 11.5107 4.51779 11.4652 4.46827 11.4091L0.753985 7.69483C0.683167 7.64891 0.623706 7.58751 0.580092 7.51525C0.536478 7.44299 0.509851 7.36177 0.502221 7.27771C0.49459 7.19366 0.506156 7.10897 0.536046 7.03004C0.565935 6.95111 0.613367 6.88 0.674759 6.82208C0.736151 6.76416 0.8099 6.72095 0.890436 6.69571C0.970973 6.67046 1.05619 6.66385 1.13966 6.67635C1.22313 6.68886 1.30266 6.72017 1.37226 6.76792C1.44186 6.81567 1.4997 6.8786 1.54141 6.95197L4.86199 10.2503L12.6397 2.49483C12.7444 2.42694 12.8689 2.39617 12.9932 2.40745C13.1174 2.41873 13.2343 2.47141 13.3251 2.55705C13.4159 2.64268 13.4753 2.75632 13.4938 2.87973C13.5123 3.00315 13.4888 3.1292 13.4271 3.23768L5.2557 11.4091C5.20618 11.4652 5.14571 11.5107 5.07801 11.5426C5.01031 11.5745 4.9368 11.5923 4.86199 11.5948Z\"\n fill=\"currentColor\"\n />\n </svg>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYA,IAAMe,IAAQC,GAERC,IAAQjB,EAAoBgB,GAAA,YAAmB,GAG/CG,IAAQC,EAAS,GACjBC,IAAaC,QAAe;GAChC,IAAM,EAAE,OAAOC,GAAQ,OAAOC,GAAQ,GAAGC,MAASN;GAClD,OAAOM;EACT,CAAC,GAEKC,IAASJ,QAAeL,EAAM,SAASF,EAAM,aAAa,GAE1DY,IAAML,QAAe,CACzBI,EAAO,QACH,gDACAX,EAAM,UACJ,0BACA,0CACNA,EAAM,WACF,8BACA,CAAC,CAACW,EAAO,SAAS,CAACX,EAAM,WAAW,sCAAsC,6BAA6B,CAC7G,CAAC;E,kBAICd,EAAA,GAAAC,EAyCM,OAAA;GAxCJ,OAAKC,EAAA,CAAC,2FACEC,EAAAe,CAAA,CAAK,CAAC,KAAK,CAAA;GAClB,OAAKd,EAAED,EAAAe,CAAA,CAAK,CAAC,KAAK;E,IAEnBb,EASE,SATFC,EACUc,EAQR,OARkB;GACjB,gBAAcL,EAAA,UAAO,SAAY,KAAA;GACjC,SAASC,EAAA;GACV,OAAM;GACL,UAAUD,EAAA;GACV,eAAeA,EAAA,iBAAa,CAAKC,EAAA;GAClC,MAAK;GACJ,UAAM,AAAAkB,EAAA,QAAA,MAAE,EAAA,QAASC,EAAO,OAA4B;E,kBAEvD9B,EAyBM,OAAA,EAzBD,OAAKH,EAAA,CAAC,0FAAiGwB,EAAA,KAAG,CAAA,E,IAErGX,EAAA,iBAAa,CAAKC,EAAA,SAD1BhB,EAAA,GAAAC,EASM,OATNQ,GASM,CAAA,GAAA,AAAAyB,EAAA,OAAA,CADJ7B,EAAmB,QAAA,EAAb,GAAE,SAAQ,GAAA,MAAA,EAAA,C,OAGLW,EAAA,SADbhB,EAAA,GAAAC,EAaM,OAbNS,GAaM,CAAA,GAAA,AAAAwB,EAAA,OAAA,CAJJ7B,EAGE,QAAA;GAFA,GAAE;GACF,MAAK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataList.js","names":["_sfc_main","DataList_vue_vue_type_script_setup_true_lang_default","DataList_default"],"sources":["../../../src/components/DataList/DataList.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed, useId, useTemplateRef } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport ContextMenu from '../ContextMenu/ContextMenu.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { DropdownMenuAction, DropdownMenuEntry } from '../internal/menu'\nimport type { DataListGroup } from './types'\n\nexport interface DataListProps<T> {\n groups: DataListGroup<T>[]\n /** The item field that identifies it. An item's `depth` indents it as a child. */\n rowKey?: keyof T & string\n /** A checkbox bound to `v-model:selected`: it shows on hover and focus, and on every row once anything is selected.\n * Shift-click (or Shift+Space) selects a range, Cmd or Ctrl-click toggles one row, Shift+↑ ↓ extends. */\n selectable?: boolean\n /** gutter: the checkbox in its own column. leading: it takes the place of the `leading` slot's first mark. */\n checkboxPlacement?: 'gutter' | 'leading'\n loading?: boolean\n /** While loading, the placeholder groups drawn, as each one's number of rows. */\n loadingGroups?: number[]\n /** joined: one frame, sticky sunken group headers. cards: each group its own card, 12px apart, headers not sticky. */\n variant?: 'joined' | 'cards'\n /** The group headings' level, to fit the page's outline. */\n headingLevel?: 2 | 3 | 4 | 5 | 6\n /** The group headers' ground; by default sunken when joined, surface as cards. */\n groupHeaderTone?: 'sunken' | 'surface' | 'canvas'\n /** The group headers' height in px (36 by default); sets `--sui-list-header`. */\n groupHeaderHeight?: number\n /** Groups fold away under a chevron; a group's own `collapsible` wins. */\n collapsible?: boolean\n /** The rows' height in px, such as 44 (40 by default); sets `--sui-list-row`. */\n rowHeight?: number\n /** A hairline between rows. */\n dividers?: boolean\n /** Wraps each row in a ContextMenu of these items (`@context-item`); return [] for none. */\n contextItems?: (item: T) => DropdownMenuEntry[]\n /** The context menu's accessible name. */\n contextLabel?: string\n /** Makes rows open on click and Enter (`@row-click`). */\n onRowClick?: (item: T) => void\n /** Adds a + to each group's header (`@new`). */\n onNew?: (group: DataListGroup<T>) => void\n /** The + button's name; `{group}` is the group's name. */\n newLabel?: string\n collapseLabel?: string\n expandLabel?: string\n selectLabel?: string\n}\n\nconst props = withDefaults(defineProps<DataListProps<T>>(), {\n rowKey: 'id' as never,\n loadingGroups: () => [4, 2],\n variant: 'joined',\n checkboxPlacement: 'gutter',\n headingLevel: 3,\n groupHeaderTone: undefined,\n groupHeaderHeight: undefined,\n collapsible: true,\n rowHeight: undefined,\n dividers: false,\n contextItems: undefined,\n contextLabel: undefined,\n onRowClick: undefined,\n onNew: undefined,\n newLabel: 'New in {group}',\n collapseLabel: 'Collapse group',\n expandLabel: 'Expand group',\n selectLabel: 'Select'\n})\n\nconst emit = defineEmits<{ 'context-item': [action: DropdownMenuAction, item: T] }>()\n\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\nconst collapsed = defineModel<string[]>('collapsed', { default: () => [] })\n\nconst slots = defineSlots<{\n /** Marks before a group's name, e.g. a status icon. */\n 'group-leading'?: (props: { group: DataListGroup<T> }) => unknown\n /** Your own group header in place of the name and count, e.g. a status Badge and a count; inside the heading. */\n 'group-header'?: (props: { group: DataListGroup<T>; count: number; collapsed: boolean }) => unknown\n /** Small marks before an item's title: a status icon, an id, an avatar. With `checkboxPlacement=\"leading\"`, the\n * first mark gives way to the checkbox. */\n leading?: (props: { item: T; selected: boolean; selecting: boolean; toggle: () => void }) => unknown\n /** The item's title; `item.name` by default. */\n title?: (props: { item: T }) => unknown\n /** Right-aligned meta: tags, an avatar, a date. Keep it to three or four things. */\n meta?: (props: { item: T }) => unknown\n /** Controls at the end of a group's header, e.g. Show and Hide. */\n 'group-actions'?: (props: { group: DataListGroup<T> }) => unknown\n /** Shown when every group is empty, e.g. an EmptyState. */\n empty?: () => unknown\n}>()\n\nconst id = useId()\nconst root = useTemplateRef<HTMLElement>('root')\n\nconst idOf = (item: T): unknown => item[props.rowKey ?? 'id']\nconst interactive = computed(() => !!props.onRowClick || props.selectable)\nconst isEmpty = computed(() => !props.loading && props.groups.every((group) => group.items.length === 0))\n\nfunction toggleGroup(groupId: string) {\n collapsed.value = collapsed.value.includes(groupId)\n ? collapsed.value.filter((x) => x !== groupId)\n : [...collapsed.value, groupId]\n}\n\nconst collapsibleGroup = (group: DataListGroup<T>) => group.collapsible ?? props.collapsible\nconst isCollapsed = (group: DataListGroup<T>) => collapsibleGroup(group) && collapsed.value.includes(group.id)\nconst visibleItems = computed(() => props.groups.filter((group) => !isCollapsed(group)).flatMap((group) => group.items))\n\n// Where a range starts: the row last toggled.\nlet anchorKey: unknown = undefined\n\nfunction toggle(item: T) {\n const key = idOf(item)\n anchorKey = key\n selected.value = selected.value.includes(key) ? selected.value.filter((x) => x !== key) : [...selected.value, key]\n}\n\nfunction selectRange(item: T) {\n const keys = visibleItems.value.map(idOf)\n const to = keys.indexOf(idOf(item))\n const from = keys.indexOf(anchorKey)\n const span = from < 0 ? [keys[to]] : keys.slice(Math.min(from, to), Math.max(from, to) + 1)\n if (from < 0) anchorKey = idOf(item)\n selected.value = [...selected.value, ...span.filter((key) => !selected.value.includes(key))]\n}\n\nfunction select(...items: T[]) {\n const keys = items.map(idOf).filter((key) => !selected.value.includes(key))\n if (keys.length) selected.value = [...selected.value, ...new Set(keys)]\n}\n\nfunction clickRow(event: MouseEvent, item: T) {\n if (props.selectable && event.shiftKey) selectRange(item)\n else if (props.selectable && (event.metaKey || event.ctrlKey)) toggle(item)\n // Leading checkboxes stand in for the row's mark, so while selecting a click selects, as in a mail list.\n else if (props.selectable && leading.value && selected.value.length) toggle(item)\n else props.onRowClick?.(item)\n}\n\n// A shift-click selects rather than highlighting the text between.\nfunction onRowMousedown(event: MouseEvent) {\n if (props.selectable && event.shiftKey) event.preventDefault()\n}\n\n// ↑ ↓ or j k move between rows, x selects, Enter and Space open; with Shift, ↑ ↓ extend the selection and Space\n// selects a range.\nfunction onKeydown(event: KeyboardEvent, item: T) {\n if (event.target !== event.currentTarget || event.metaKey || event.ctrlKey || event.altKey) return\n // A collapsed group's rows are still in the DOM, hidden.\n const rows = [...(root.value?.querySelectorAll<HTMLElement>('[data-list-row]') ?? [])].filter(\n (row) => row.closest('ul')?.style.display !== 'none'\n )\n const i = rows.indexOf(event.currentTarget as HTMLElement)\n const down = event.key === 'ArrowDown' || event.key === 'j'\n const up = event.key === 'ArrowUp' || event.key === 'k'\n if ((down || up) && event.shiftKey && props.selectable) {\n const j = down ? Math.min(rows.length - 1, i + 1) : Math.max(0, i - 1)\n const next = visibleItems.value[j]\n select(item, ...(next ? [next] : []))\n rows[j]?.focus()\n } else if (down) rows[Math.min(rows.length - 1, i + 1)]?.focus()\n else if (up) rows[Math.max(0, i - 1)]?.focus()\n else if (event.key === ' ' && event.shiftKey && props.selectable) selectRange(item)\n else if (event.key.toLowerCase() === 'x' && props.selectable) toggle(item)\n else if ((event.key === 'Enter' || event.key === ' ') && props.onRowClick) props.onRowClick(item)\n else return\n event.preventDefault()\n}\n\nconst cards = computed(() => props.variant === 'cards')\nconst leading = computed(() => props.selectable && props.checkboxPlacement === 'leading')\nconst gutter = computed(() => props.selectable && props.checkboxPlacement === 'gutter')\nconst tones = { sunken: 'bg-sui-sunken', surface: 'bg-sui-surface', canvas: 'bg-sui-canvas' }\nconst headerTone = computed(() => tones[props.groupHeaderTone ?? (cards.value ? 'surface' : 'sunken')])\nconst sizes = computed(() => {\n const style: Record<string, string> = {}\n if (props.rowHeight !== undefined) style['--sui-list-row'] = `${props.rowHeight}px`\n if (props.groupHeaderHeight !== undefined) style['--sui-list-header'] = `${props.groupHeaderHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst card = 'overflow-clip rounded-xl border border-sui-line-subtle bg-sui-surface'\nconst custom = (group: DataListGroup<T>) => !!slots['group-header'] || group.header !== undefined\nconst groupName = (group: DataListGroup<T>) => group.label ?? group.name ?? ''\n\nconst skeletonWidths = ['42%', '58%', '35%', '50%', '46%', '38%']\nconst skeletonGroupWidths = ['5.5rem', '4rem', '4.75rem']\n// A Skeleton is sunken, so on a sunken header band its bars go a step darker.\nconst headerBar = computed(() => [\n 'animate-pulse',\n headerTone.value === tones.sunken ? 'bg-sui-line-subtle' : 'bg-sui-sunken'\n])\nconst iconButton =\n 'flex size-6 shrink-0 items-center justify-center rounded-md text-sui-ink-muted outline-hidden transition-colors duration-150 hover:bg-sui-line-subtle hover:text-sui-ink focus-visible:sui-ring-inset'\n</script>\n\n<!-- A grouped list: one dense line per record under sticky, collapsible group headers. -->\n<template>\n <div ref=\"root\" class=\"flex flex-col text-13 text-sui-ink\" :class=\"cards ? 'gap-3' : card\" :style=\"sizes\">\n <div v-if=\"isEmpty && $slots.empty\" :class=\"cards && card\">\n <slot name=\"empty\" />\n </div>\n <!-- Placeholder groups in the list's own shape: its header, rows, leading marks and meta. -->\n <template v-else-if=\"loading\">\n <section\n v-for=\"(rows, g) in loadingGroups\"\n :key=\"g\"\n aria-busy=\"true\"\n :class=\"cards ? card : 'border-t border-sui-line-subtle first:border-t-0'\"\n >\n <div\n aria-hidden=\"true\"\n class=\"flex h-[var(--sui-list-header,2.25rem)] items-center gap-2 border-b border-sui-line-subtle pr-2\"\n :class=\"[headerTone, collapsible ? 'pl-1.5' : 'pl-4']\"\n >\n <span v-if=\"collapsible\" class=\"size-6 shrink-0\" />\n <span\n v-if=\"$slots['group-leading'] || $slots['group-header']\"\n class=\"size-3.5 rounded-full\"\n :class=\"headerBar\"\n />\n <span class=\"h-2.5 rounded-md\" :class=\"headerBar\" :style=\"{ width: skeletonGroupWidths[g % 3] }\" />\n <span class=\"h-2.5 w-3.5 rounded-md\" :class=\"headerBar\" />\n </div>\n <div\n v-for=\"r in rows\"\n :key=\"r\"\n aria-hidden=\"true\"\n class=\"flex h-[var(--sui-list-row,2.5rem)] items-center gap-2.5 pr-4\"\n :class=\"[gutter ? 'pl-9.5' : 'pl-4', dividers && '[&+&]:border-t [&+&]:border-sui-line-subtle']\"\n >\n <Skeleton v-if=\"$slots.leading || leading\" shape=\"circle\" size=\"1.25rem\" />\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(g * 3 + r) % skeletonWidths.length]\" />\n <span class=\"flex-1\" />\n <template v-if=\"$slots.meta\">\n <Skeleton height=\"0.625rem\" width=\"6rem\" />\n <Skeleton height=\"0.625rem\" width=\"3.5rem\" />\n </template>\n </div>\n </section>\n </template>\n <template v-else>\n <section\n v-for=\"group in groups\"\n :key=\"group.id\"\n :aria-label=\"group.label\"\n :aria-labelledby=\"!group.label && (group.name || custom(group)) ? `${id}-${group.id}-name` : undefined\"\n :class=\"cards ? card : 'border-t border-sui-line-subtle first:border-t-0'\"\n >\n <header\n v-if=\"group.name || custom(group)\"\n class=\"flex h-[var(--sui-list-header,2.25rem)] items-center gap-2 border-b border-sui-line-subtle pr-2\"\n :class=\"[headerTone, !cards && 'sticky top-0 z-10', collapsibleGroup(group) ? 'pl-1.5' : 'pl-4']\"\n >\n <button\n v-if=\"collapsibleGroup(group)\"\n :aria-controls=\"`${id}-${group.id}`\"\n :aria-expanded=\"!collapsed.includes(group.id)\"\n :aria-label=\"collapsed.includes(group.id) ? expandLabel : collapseLabel\"\n :class=\"iconButton\"\n type=\"button\"\n @click=\"toggleGroup(group.id)\"\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3 fill-none stroke-current transition-transform duration-150\"\n :class=\"isCollapsed(group) && '-rotate-90'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path d=\"M3 4.5 6 7.5l3-3\" />\n </svg>\n </button>\n <component\n :is=\"`h${headingLevel}`\"\n v-if=\"custom(group)\"\n :id=\"`${id}-${group.id}-name`\"\n class=\"m-0 flex min-w-0 items-center gap-2 text-13 font-medium text-sui-ink\"\n >\n <slot\n :collapsed=\"collapsed.includes(group.id)\"\n :count=\"group.count ?? group.items.length\"\n :group=\"group\"\n name=\"group-header\"\n >{{ group.header }}</slot\n >\n </component>\n <template v-else>\n <slot :group=\"group\" name=\"group-leading\" />\n <component\n :is=\"`h${headingLevel}`\"\n :id=\"`${id}-${group.id}-name`\"\n class=\"m-0 text-13 font-medium text-sui-ink\"\n >\n {{ group.name }}\n </component>\n <span class=\"text-13 text-sui-ink-muted tabular-nums\">{{ group.count ?? group.items.length }}</span>\n </template>\n <span class=\"ml-auto flex items-center gap-1\">\n <slot :group=\"group\" name=\"group-actions\" />\n </span>\n <button\n v-if=\"onNew\"\n :aria-label=\"newLabel.replace('{group}', groupName(group))\"\n :class=\"iconButton\"\n type=\"button\"\n @click=\"onNew(group)\"\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 14 14\"\n >\n <path d=\"M7 2.5v9M2.5 7h9\" />\n </svg>\n </button>\n </header>\n <ul v-show=\"!isCollapsed(group)\" :id=\"`${id}-${group.id}`\" class=\"m-0 list-none p-0\">\n <ContextMenu\n v-for=\"item in group.items\"\n :key=\"idOf(item) as PropertyKey\"\n :disabled=\"!contextItems\"\n :items=\"contextItems?.(item)\"\n :label=\"contextLabel\"\n @click-item=\"emit('context-item', $event, item)\"\n >\n <li\n class=\"group/row relative flex h-[var(--sui-list-row,2.5rem)] items-center transition-colors duration-100 has-focus-visible:sui-ring-inset\"\n :class=\"[\n dividers && '[&+&]:border-t [&+&]:border-sui-line-subtle',\n selected.includes(idOf(item))\n ? 'bg-sui-accent-wash'\n : 'hover:bg-sui-sunken has-focus-visible:bg-sui-sunken'\n ]\"\n :style=\"item.depth ? { paddingLeft: `${item.depth * 22}px` } : undefined\"\n >\n <!-- Outside the row, which is a button, over the leading slot's first mark: 16px in, or more for a child. -->\n <span\n v-if=\"leading\"\n class=\"absolute top-1/2 z-[1] flex size-4 -translate-y-1/2 items-center justify-center\"\n :class=\"!selected.length && 'hidden group-hover/row:flex group-has-focus-visible/row:flex'\"\n data-list-check\n :style=\"{ left: `${16 + (item.depth ?? 0) * 22}px` }\"\n >\n <Checkbox\n :aria-label=\"selectLabel\"\n :model-value=\"selected.includes(idOf(item))\"\n tabindex=\"-1\"\n @update:model-value=\"toggle(item)\"\n />\n </span>\n <span\n v-if=\"gutter\"\n class=\"flex w-7 shrink-0 justify-end transition-opacity duration-100\"\n :class=\"selected.length ? 'opacity-100' : 'opacity-0 group-hover/row:opacity-100'\"\n >\n <Checkbox\n :aria-label=\"selectLabel\"\n :model-value=\"selected.includes(idOf(item))\"\n tabindex=\"-1\"\n @update:model-value=\"toggle(item)\"\n />\n </span>\n <div\n class=\"flex h-full min-w-0 flex-1 items-center gap-2.5 pr-4 outline-hidden\"\n :class=\"[gutter ? 'pl-2.5' : 'pl-4', (onRowClick || selectable) && 'cursor-pointer']\"\n data-list-row\n :role=\"onRowClick ? 'button' : undefined\"\n :tabindex=\"interactive ? 0 : undefined\"\n @click=\"clickRow($event, item)\"\n @keydown=\"onKeydown($event, item)\"\n @mousedown=\"onRowMousedown\"\n >\n <span\n v-if=\"$slots.leading\"\n class=\"flex shrink-0 items-center gap-2 text-sui-ink-muted tabular-nums\"\n :class=\"\n leading &&\n (selected.length\n ? '[&>*:first-child]:invisible'\n : 'group-hover/row:[&>*:first-child]:invisible group-has-focus-visible/row:[&>*:first-child]:invisible')\n \"\n >\n <slot\n :item=\"item\"\n name=\"leading\"\n :selected=\"selected.includes(idOf(item))\"\n :selecting=\"selected.length > 0\"\n :toggle=\"() => toggle(item)\"\n />\n </span>\n <span class=\"min-w-0 flex-1 truncate font-medium text-sui-ink\">\n <slot :item=\"item\" name=\"title\">{{ item.name }}</slot>\n </span>\n <span\n v-if=\"$slots.meta\"\n class=\"flex shrink-0 items-center gap-2 text-xs text-sui-ink-muted tabular-nums\"\n >\n <slot :item=\"item\" name=\"meta\" />\n </span>\n </div>\n </li>\n </ContextMenu>\n </ul>\n </section>\n </template>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"DataList.js","names":["_sfc_main","DataList_vue_vue_type_script_setup_true_lang_default","DataList_default"],"sources":["../../../src/components/DataList/DataList.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed, useId, useTemplateRef } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport ContextMenu from '../ContextMenu/ContextMenu.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { DropdownMenuAction, DropdownMenuEntry } from '../internal/menu'\nimport type { DataListGroup } from './types'\n\nexport interface DataListProps<T> {\n groups: DataListGroup<T>[]\n /** The item field that identifies it. An item's `depth` indents it as a child. */\n rowKey?: keyof T & string\n /** A checkbox bound to `v-model:selected`: it shows on hover and focus, and on every row once anything is selected.\n * Shift-click (or Shift+Space) selects a range, Cmd or Ctrl-click toggles one row, Shift+↑ ↓ extends. */\n selectable?: boolean\n /** gutter: the checkbox in its own column. leading: it takes the place of the `leading` slot's first mark. */\n checkboxPlacement?: 'gutter' | 'leading'\n loading?: boolean\n /** While loading, the placeholder groups drawn, as each one's number of rows. */\n loadingGroups?: number[]\n /** joined: one frame, sticky sunken group headers. cards: each group its own card, 12px apart, headers not sticky. */\n variant?: 'joined' | 'cards'\n /** The group headings' level, to fit the page's outline. */\n headingLevel?: 2 | 3 | 4 | 5 | 6\n /** The group headers' ground; by default sunken when joined, surface as cards. */\n groupHeaderTone?: 'sunken' | 'surface' | 'canvas'\n /** The group headers' height in px (36 by default); sets `--sui-list-header`. */\n groupHeaderHeight?: number\n /** Groups fold away under a chevron; a group's own `collapsible` wins. */\n collapsible?: boolean\n /** The rows' height in px, such as 44 (40 by default); sets `--sui-list-row`. */\n rowHeight?: number\n /** A hairline between rows. */\n dividers?: boolean\n /** Wraps each row in a ContextMenu of these items (`@context-item`); return [] for none. */\n contextItems?: (item: T) => DropdownMenuEntry[]\n /** The context menu's accessible name. */\n contextLabel?: string\n /** Makes rows open on click and Enter (`@row-click`). */\n onRowClick?: (item: T) => void\n /** Adds a + to each group's header (`@new`). */\n onNew?: (group: DataListGroup<T>) => void\n /** The + button's name; `{group}` is the group's name. */\n newLabel?: string\n collapseLabel?: string\n expandLabel?: string\n selectLabel?: string\n}\n\nconst props = withDefaults(defineProps<DataListProps<T>>(), {\n rowKey: 'id' as never,\n loadingGroups: () => [4, 2],\n variant: 'joined',\n checkboxPlacement: 'gutter',\n headingLevel: 3,\n groupHeaderTone: undefined,\n groupHeaderHeight: undefined,\n collapsible: true,\n rowHeight: undefined,\n dividers: false,\n contextItems: undefined,\n contextLabel: undefined,\n onRowClick: undefined,\n onNew: undefined,\n newLabel: 'New in {group}',\n collapseLabel: 'Collapse group',\n expandLabel: 'Expand group',\n selectLabel: 'Select'\n})\n\nconst emit = defineEmits<{ 'context-item': [action: DropdownMenuAction, item: T] }>()\n\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\nconst collapsed = defineModel<string[]>('collapsed', { default: () => [] })\n\nconst slots = defineSlots<{\n /** Marks before a group's name, e.g. a status icon. */\n 'group-leading'?: (props: { group: DataListGroup<T> }) => unknown\n /** Your own group header in place of the name and count, e.g. a status Badge and a count; inside the heading. */\n 'group-header'?: (props: { group: DataListGroup<T>; count: number; collapsed: boolean }) => unknown\n /** Small marks before an item's title: a status icon, an id, an avatar. With `checkboxPlacement=\"leading\"`, the\n * first mark gives way to the checkbox. */\n leading?: (props: { item: T; selected: boolean; selecting: boolean; toggle: () => void }) => unknown\n /** The item's title; `item.name` by default. */\n title?: (props: { item: T }) => unknown\n /** Right-aligned meta: tags, an avatar, a date. Keep it to three or four things. */\n meta?: (props: { item: T }) => unknown\n /** Controls at the end of a group's header, e.g. Show and Hide. */\n 'group-actions'?: (props: { group: DataListGroup<T> }) => unknown\n /** Shown when every group is empty, e.g. an EmptyState. */\n empty?: () => unknown\n}>()\n\nconst id = useId()\nconst root = useTemplateRef<HTMLElement>('root')\n\nconst idOf = (item: T): unknown => item[props.rowKey ?? 'id']\nconst interactive = computed(() => !!props.onRowClick || props.selectable)\nconst isEmpty = computed(() => !props.loading && props.groups.every((group) => group.items.length === 0))\n\nfunction toggleGroup(groupId: string) {\n collapsed.value = collapsed.value.includes(groupId)\n ? collapsed.value.filter((x) => x !== groupId)\n : [...collapsed.value, groupId]\n}\n\nconst collapsibleGroup = (group: DataListGroup<T>) => group.collapsible ?? props.collapsible\nconst isCollapsed = (group: DataListGroup<T>) => collapsibleGroup(group) && collapsed.value.includes(group.id)\nconst visibleItems = computed(() => props.groups.filter((group) => !isCollapsed(group)).flatMap((group) => group.items))\n\n// Where a range starts: the row last toggled.\nlet anchorKey: unknown = undefined\n\nfunction toggle(item: T) {\n const key = idOf(item)\n anchorKey = key\n selected.value = selected.value.includes(key) ? selected.value.filter((x) => x !== key) : [...selected.value, key]\n}\n\nfunction selectRange(item: T) {\n const keys = visibleItems.value.map(idOf)\n const to = keys.indexOf(idOf(item))\n const from = keys.indexOf(anchorKey)\n const span = from < 0 ? [keys[to]] : keys.slice(Math.min(from, to), Math.max(from, to) + 1)\n if (from < 0) anchorKey = idOf(item)\n selected.value = [...selected.value, ...span.filter((key) => !selected.value.includes(key))]\n}\n\nfunction select(...items: T[]) {\n const keys = items.map(idOf).filter((key) => !selected.value.includes(key))\n if (keys.length) selected.value = [...selected.value, ...new Set(keys)]\n}\n\nfunction clickRow(event: MouseEvent, item: T) {\n if (props.selectable && event.shiftKey) selectRange(item)\n else if (props.selectable && (event.metaKey || event.ctrlKey)) toggle(item)\n // Leading checkboxes stand in for the row's mark, so while selecting a click selects, as in a mail list.\n else if (props.selectable && leading.value && selected.value.length) toggle(item)\n else props.onRowClick?.(item)\n}\n\n// A shift-click selects rather than highlighting the text between.\nfunction onRowMousedown(event: MouseEvent) {\n if (props.selectable && event.shiftKey) event.preventDefault()\n}\n\n// ↑ ↓ or j k move between rows, x selects, Enter and Space open; with Shift, ↑ ↓ extend the selection and Space\n// selects a range.\nfunction onKeydown(event: KeyboardEvent, item: T) {\n if (event.target !== event.currentTarget || event.metaKey || event.ctrlKey || event.altKey) return\n // A collapsed group's rows are still in the DOM, hidden.\n const rows = [...(root.value?.querySelectorAll<HTMLElement>('[data-list-row]') ?? [])].filter(\n (row) => row.closest('ul')?.style.display !== 'none'\n )\n const i = rows.indexOf(event.currentTarget as HTMLElement)\n const down = event.key === 'ArrowDown' || event.key === 'j'\n const up = event.key === 'ArrowUp' || event.key === 'k'\n if ((down || up) && event.shiftKey && props.selectable) {\n const j = down ? Math.min(rows.length - 1, i + 1) : Math.max(0, i - 1)\n const next = visibleItems.value[j]\n select(item, ...(next ? [next] : []))\n rows[j]?.focus()\n } else if (down) rows[Math.min(rows.length - 1, i + 1)]?.focus()\n else if (up) rows[Math.max(0, i - 1)]?.focus()\n else if (event.key === ' ' && event.shiftKey && props.selectable) selectRange(item)\n else if (event.key.toLowerCase() === 'x' && props.selectable) toggle(item)\n else if ((event.key === 'Enter' || event.key === ' ') && props.onRowClick) props.onRowClick(item)\n else return\n event.preventDefault()\n}\n\nconst cards = computed(() => props.variant === 'cards')\nconst leading = computed(() => props.selectable && props.checkboxPlacement === 'leading')\nconst gutter = computed(() => props.selectable && props.checkboxPlacement === 'gutter')\nconst tones = { sunken: 'sui-band', surface: 'bg-sui-surface', canvas: 'bg-sui-canvas' }\nconst headerTone = computed(() => tones[props.groupHeaderTone ?? (cards.value ? 'surface' : 'sunken')])\nconst sizes = computed(() => {\n const style: Record<string, string> = {}\n if (props.rowHeight !== undefined) style['--sui-list-row'] = `${props.rowHeight}px`\n if (props.groupHeaderHeight !== undefined) style['--sui-list-header'] = `${props.groupHeaderHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst card = 'overflow-clip rounded-xl border border-sui-line-subtle bg-sui-surface'\nconst custom = (group: DataListGroup<T>) => !!slots['group-header'] || group.header !== undefined\nconst groupName = (group: DataListGroup<T>) => group.label ?? group.name ?? ''\n\nconst skeletonWidths = ['42%', '58%', '35%', '50%', '46%', '38%']\nconst skeletonGroupWidths = ['5.5rem', '4rem', '4.75rem']\nconst headerBar = 'animate-pulse bg-sui-fill-hover'\nconst iconButton =\n 'flex size-6 shrink-0 items-center justify-center rounded-md text-sui-ink-muted outline-hidden transition-colors duration-150 hover:bg-sui-fill-hover hover:text-sui-ink focus-visible:sui-ring-inset'\n</script>\n\n<!-- A grouped list: one dense line per record under sticky, collapsible group headers. -->\n<template>\n <div ref=\"root\" class=\"flex flex-col text-13 text-sui-ink\" :class=\"cards ? 'gap-3' : card\" :style=\"sizes\">\n <div v-if=\"isEmpty && $slots.empty\" :class=\"cards && card\">\n <slot name=\"empty\" />\n </div>\n <!-- Placeholder groups in the list's own shape: its header, rows, leading marks and meta. -->\n <template v-else-if=\"loading\">\n <section\n v-for=\"(rows, g) in loadingGroups\"\n :key=\"g\"\n aria-busy=\"true\"\n :class=\"cards ? card : 'border-t border-sui-line-subtle first:border-t-0'\"\n >\n <div\n aria-hidden=\"true\"\n class=\"flex h-[var(--sui-list-header,2.25rem)] items-center gap-2 border-b border-sui-line-subtle pr-2\"\n :class=\"[headerTone, collapsible ? 'pl-1.5' : 'pl-4']\"\n >\n <span v-if=\"collapsible\" class=\"size-6 shrink-0\" />\n <span\n v-if=\"$slots['group-leading'] || $slots['group-header']\"\n class=\"size-3.5 rounded-full\"\n :class=\"headerBar\"\n />\n <span class=\"h-2.5 rounded-md\" :class=\"headerBar\" :style=\"{ width: skeletonGroupWidths[g % 3] }\" />\n <span class=\"h-2.5 w-3.5 rounded-md\" :class=\"headerBar\" />\n </div>\n <div\n v-for=\"r in rows\"\n :key=\"r\"\n aria-hidden=\"true\"\n class=\"flex h-[var(--sui-list-row,2.5rem)] items-center gap-2.5 pr-4\"\n :class=\"[gutter ? 'pl-9.5' : 'pl-4', dividers && '[&+&]:border-t [&+&]:border-sui-line-subtle']\"\n >\n <Skeleton v-if=\"$slots.leading || leading\" shape=\"circle\" size=\"1.25rem\" />\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(g * 3 + r) % skeletonWidths.length]\" />\n <span class=\"flex-1\" />\n <template v-if=\"$slots.meta\">\n <Skeleton height=\"0.625rem\" width=\"6rem\" />\n <Skeleton height=\"0.625rem\" width=\"3.5rem\" />\n </template>\n </div>\n </section>\n </template>\n <template v-else>\n <section\n v-for=\"group in groups\"\n :key=\"group.id\"\n :aria-label=\"group.label\"\n :aria-labelledby=\"!group.label && (group.name || custom(group)) ? `${id}-${group.id}-name` : undefined\"\n :class=\"cards ? card : 'border-t border-sui-line-subtle first:border-t-0'\"\n >\n <header\n v-if=\"group.name || custom(group)\"\n class=\"flex h-[var(--sui-list-header,2.25rem)] items-center gap-2 border-b border-sui-line-subtle pr-2\"\n :class=\"[headerTone, !cards && 'sticky top-0 z-10', collapsibleGroup(group) ? 'pl-1.5' : 'pl-4']\"\n >\n <button\n v-if=\"collapsibleGroup(group)\"\n :aria-controls=\"`${id}-${group.id}`\"\n :aria-expanded=\"!collapsed.includes(group.id)\"\n :aria-label=\"collapsed.includes(group.id) ? expandLabel : collapseLabel\"\n :class=\"iconButton\"\n type=\"button\"\n @click=\"toggleGroup(group.id)\"\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3 fill-none stroke-current transition-transform duration-150\"\n :class=\"isCollapsed(group) && '-rotate-90'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path d=\"M3 4.5 6 7.5l3-3\" />\n </svg>\n </button>\n <component\n :is=\"`h${headingLevel}`\"\n v-if=\"custom(group)\"\n :id=\"`${id}-${group.id}-name`\"\n class=\"m-0 flex min-w-0 items-center gap-2 text-13 font-medium text-sui-ink\"\n >\n <slot\n :collapsed=\"collapsed.includes(group.id)\"\n :count=\"group.count ?? group.items.length\"\n :group=\"group\"\n name=\"group-header\"\n >{{ group.header }}</slot\n >\n </component>\n <template v-else>\n <slot :group=\"group\" name=\"group-leading\" />\n <component\n :is=\"`h${headingLevel}`\"\n :id=\"`${id}-${group.id}-name`\"\n class=\"m-0 text-13 font-medium text-sui-ink\"\n >\n {{ group.name }}\n </component>\n <span class=\"text-13 text-sui-ink-muted tabular-nums\">{{ group.count ?? group.items.length }}</span>\n </template>\n <span class=\"ml-auto flex items-center gap-1\">\n <slot :group=\"group\" name=\"group-actions\" />\n </span>\n <button\n v-if=\"onNew\"\n :aria-label=\"newLabel.replace('{group}', groupName(group))\"\n :class=\"iconButton\"\n type=\"button\"\n @click=\"onNew(group)\"\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 14 14\"\n >\n <path d=\"M7 2.5v9M2.5 7h9\" />\n </svg>\n </button>\n </header>\n <ul v-show=\"!isCollapsed(group)\" :id=\"`${id}-${group.id}`\" class=\"m-0 list-none p-0\">\n <ContextMenu\n v-for=\"item in group.items\"\n :key=\"idOf(item) as PropertyKey\"\n :disabled=\"!contextItems\"\n :items=\"contextItems?.(item)\"\n :label=\"contextLabel\"\n @click-item=\"emit('context-item', $event, item)\"\n >\n <li\n class=\"group/row relative flex h-[var(--sui-list-row,2.5rem)] items-center transition-colors duration-100 has-focus-visible:sui-ring-inset\"\n :class=\"[\n dividers && '[&+&]:border-t [&+&]:border-sui-line-subtle',\n selected.includes(idOf(item))\n ? 'bg-sui-accent-wash'\n : 'hover:bg-sui-fill-hover has-focus-visible:bg-sui-fill-hover'\n ]\"\n :style=\"item.depth ? { paddingLeft: `${item.depth * 22}px` } : undefined\"\n >\n <!-- Outside the row, which is a button, over the leading slot's first mark: 16px in, or more for a child. -->\n <span\n v-if=\"leading\"\n class=\"absolute top-1/2 z-[1] flex size-4 -translate-y-1/2 items-center justify-center\"\n :class=\"!selected.length && 'hidden group-hover/row:flex group-has-focus-visible/row:flex'\"\n data-list-check\n :style=\"{ left: `${16 + (item.depth ?? 0) * 22}px` }\"\n >\n <Checkbox\n :aria-label=\"selectLabel\"\n :model-value=\"selected.includes(idOf(item))\"\n tabindex=\"-1\"\n @update:model-value=\"toggle(item)\"\n />\n </span>\n <span\n v-if=\"gutter\"\n class=\"flex w-7 shrink-0 justify-end transition-opacity duration-100\"\n :class=\"selected.length ? 'opacity-100' : 'opacity-0 group-hover/row:opacity-100'\"\n >\n <Checkbox\n :aria-label=\"selectLabel\"\n :model-value=\"selected.includes(idOf(item))\"\n tabindex=\"-1\"\n @update:model-value=\"toggle(item)\"\n />\n </span>\n <div\n class=\"flex h-full min-w-0 flex-1 items-center gap-2.5 pr-4 outline-hidden\"\n :class=\"[gutter ? 'pl-2.5' : 'pl-4', (onRowClick || selectable) && 'cursor-pointer']\"\n data-list-row\n :role=\"onRowClick ? 'button' : undefined\"\n :tabindex=\"interactive ? 0 : undefined\"\n @click=\"clickRow($event, item)\"\n @keydown=\"onKeydown($event, item)\"\n @mousedown=\"onRowMousedown\"\n >\n <span\n v-if=\"$slots.leading\"\n class=\"flex shrink-0 items-center gap-2 text-sui-ink-muted tabular-nums\"\n :class=\"\n leading &&\n (selected.length\n ? '[&>*:first-child]:invisible'\n : 'group-hover/row:[&>*:first-child]:invisible group-has-focus-visible/row:[&>*:first-child]:invisible')\n \"\n >\n <slot\n :item=\"item\"\n name=\"leading\"\n :selected=\"selected.includes(idOf(item))\"\n :selecting=\"selected.length > 0\"\n :toggle=\"() => toggle(item)\"\n />\n </span>\n <span class=\"min-w-0 flex-1 truncate font-medium text-sui-ink\">\n <slot :item=\"item\" name=\"title\">{{ item.name }}</slot>\n </span>\n <span\n v-if=\"$slots.meta\"\n class=\"flex shrink-0 items-center gap-2 text-xs text-sui-ink-muted tabular-nums\"\n >\n <slot :item=\"item\" name=\"meta\" />\n </span>\n </div>\n </li>\n </ContextMenu>\n </ul>\n </section>\n </template>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import e from "../Skeleton/Skeleton.js";
|
|
2
2
|
import t from "../Checkbox/Checkbox.js";
|
|
3
3
|
import n from "../ContextMenu/ContextMenu.js";
|
|
4
|
-
import { Fragment as r, computed as i, createBlock as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createTextVNode as l, createVNode as u, defineComponent as d, mergeModels as f, normalizeClass as p, normalizeStyle as m, openBlock as h, renderList as g, renderSlot as _, resolveDynamicComponent as v, toDisplayString as y, unref as b, useId as
|
|
4
|
+
import { Fragment as r, computed as i, createBlock as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createTextVNode as l, createVNode as u, defineComponent as d, mergeModels as f, normalizeClass as p, normalizeStyle as m, openBlock as h, renderList as g, renderSlot as _, resolveDynamicComponent as v, toDisplayString as y, unref as b, useId as x, useModel as S, useSlots as C, useTemplateRef as ee, vShow as te, withCtx as w, withDirectives as T } from "vue";
|
|
5
5
|
//#region src/components/DataList/DataList.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
-
var
|
|
6
|
+
var E = {
|
|
7
7
|
key: 0,
|
|
8
8
|
class: "size-6 shrink-0"
|
|
9
|
-
},
|
|
9
|
+
}, D = ["aria-label", "aria-labelledby"], ne = [
|
|
10
10
|
"aria-controls",
|
|
11
11
|
"aria-expanded",
|
|
12
12
|
"aria-label",
|
|
13
13
|
"onClick"
|
|
14
|
-
],
|
|
14
|
+
], re = { class: "text-13 text-sui-ink-muted tabular-nums" }, ie = { class: "ml-auto flex items-center gap-1" }, ae = ["aria-label", "onClick"], oe = ["id"], se = [
|
|
15
15
|
"role",
|
|
16
16
|
"tabindex",
|
|
17
17
|
"onClick",
|
|
18
18
|
"onKeydown"
|
|
19
|
-
],
|
|
19
|
+
], ce = { class: "min-w-0 flex-1 truncate font-medium text-sui-ink" }, O = {
|
|
20
20
|
key: 1,
|
|
21
21
|
class: "flex shrink-0 items-center gap-2 text-xs text-sui-ink-muted tabular-nums"
|
|
22
|
-
}, k = "overflow-clip rounded-xl border border-sui-line-subtle bg-sui-surface", A = "flex size-6 shrink-0 items-center justify-center rounded-md text-sui-ink-muted outline-hidden transition-colors duration-150 hover:bg-sui-
|
|
22
|
+
}, k = "overflow-clip rounded-xl border border-sui-line-subtle bg-sui-surface", A = "animate-pulse bg-sui-fill-hover", j = "flex size-6 shrink-0 items-center justify-center rounded-md text-sui-ink-muted outline-hidden transition-colors duration-150 hover:bg-sui-fill-hover hover:text-sui-ink focus-visible:sui-ring-inset", M = /*@__PURE__*/ d({
|
|
23
23
|
__name: "DataList",
|
|
24
24
|
props: /*@__PURE__*/ f({
|
|
25
25
|
groups: {},
|
|
@@ -66,51 +66,51 @@ var ie = {
|
|
|
66
66
|
}),
|
|
67
67
|
emits: /*@__PURE__*/ f(["context-item"], ["update:selected", "update:collapsed"]),
|
|
68
68
|
setup(d, { emit: f }) {
|
|
69
|
-
let
|
|
70
|
-
function
|
|
71
|
-
|
|
69
|
+
let M = d, N = f, P = S(d, "selected"), F = S(d, "collapsed"), le = C(), I = x(), L = ee("root"), R = (e) => e[M.rowKey ?? "id"], z = i(() => !!M.onRowClick || M.selectable), B = i(() => !M.loading && M.groups.every((e) => e.items.length === 0));
|
|
70
|
+
function V(e) {
|
|
71
|
+
F.value = F.value.includes(e) ? F.value.filter((t) => t !== e) : [...F.value, e];
|
|
72
72
|
}
|
|
73
|
-
let
|
|
74
|
-
function
|
|
75
|
-
let t =
|
|
76
|
-
|
|
73
|
+
let H = (e) => e.collapsible ?? M.collapsible, U = (e) => H(e) && F.value.includes(e.id), W = i(() => M.groups.filter((e) => !U(e)).flatMap((e) => e.items)), G;
|
|
74
|
+
function K(e) {
|
|
75
|
+
let t = R(e);
|
|
76
|
+
G = t, P.value = P.value.includes(t) ? P.value.filter((e) => e !== t) : [...P.value, t];
|
|
77
77
|
}
|
|
78
|
-
function
|
|
79
|
-
let t =
|
|
80
|
-
r < 0 && (
|
|
78
|
+
function q(e) {
|
|
79
|
+
let t = W.value.map(R), n = t.indexOf(R(e)), r = t.indexOf(G), i = r < 0 ? [t[n]] : t.slice(Math.min(r, n), Math.max(r, n) + 1);
|
|
80
|
+
r < 0 && (G = R(e)), P.value = [...P.value, ...i.filter((e) => !P.value.includes(e))];
|
|
81
81
|
}
|
|
82
|
-
function
|
|
83
|
-
let t = e.map(
|
|
84
|
-
t.length && (
|
|
82
|
+
function ue(...e) {
|
|
83
|
+
let t = e.map(R).filter((e) => !P.value.includes(e));
|
|
84
|
+
t.length && (P.value = [...P.value, ...new Set(t)]);
|
|
85
85
|
}
|
|
86
|
-
function
|
|
87
|
-
|
|
86
|
+
function de(e, t) {
|
|
87
|
+
M.selectable && e.shiftKey ? q(t) : M.selectable && (e.metaKey || e.ctrlKey) || M.selectable && Y.value && P.value.length ? K(t) : M.onRowClick?.(t);
|
|
88
88
|
}
|
|
89
|
-
function
|
|
90
|
-
|
|
89
|
+
function fe(e) {
|
|
90
|
+
M.selectable && e.shiftKey && e.preventDefault();
|
|
91
91
|
}
|
|
92
|
-
function
|
|
92
|
+
function pe(e, t) {
|
|
93
93
|
if (e.target !== e.currentTarget || e.metaKey || e.ctrlKey || e.altKey) return;
|
|
94
|
-
let n = [...
|
|
95
|
-
if ((i || a) && e.shiftKey &&
|
|
96
|
-
let e = i ? Math.min(n.length - 1, r + 1) : Math.max(0, r - 1), a =
|
|
97
|
-
|
|
94
|
+
let n = [...L.value?.querySelectorAll("[data-list-row]") ?? []].filter((e) => e.closest("ul")?.style.display !== "none"), r = n.indexOf(e.currentTarget), i = e.key === "ArrowDown" || e.key === "j", a = e.key === "ArrowUp" || e.key === "k";
|
|
95
|
+
if ((i || a) && e.shiftKey && M.selectable) {
|
|
96
|
+
let e = i ? Math.min(n.length - 1, r + 1) : Math.max(0, r - 1), a = W.value[e];
|
|
97
|
+
ue(t, ...a ? [a] : []), n[e]?.focus();
|
|
98
98
|
} else if (i) n[Math.min(n.length - 1, r + 1)]?.focus();
|
|
99
99
|
else if (a) n[Math.max(0, r - 1)]?.focus();
|
|
100
|
-
else if (e.key === " " && e.shiftKey &&
|
|
101
|
-
else if (e.key.toLowerCase() === "x" &&
|
|
102
|
-
else if ((e.key === "Enter" || e.key === " ") &&
|
|
100
|
+
else if (e.key === " " && e.shiftKey && M.selectable) q(t);
|
|
101
|
+
else if (e.key.toLowerCase() === "x" && M.selectable) K(t);
|
|
102
|
+
else if ((e.key === "Enter" || e.key === " ") && M.onRowClick) M.onRowClick(t);
|
|
103
103
|
else return;
|
|
104
104
|
e.preventDefault();
|
|
105
105
|
}
|
|
106
|
-
let
|
|
107
|
-
sunken: "
|
|
106
|
+
let J = i(() => M.variant === "cards"), Y = i(() => M.selectable && M.checkboxPlacement === "leading"), X = i(() => M.selectable && M.checkboxPlacement === "gutter"), me = {
|
|
107
|
+
sunken: "sui-band",
|
|
108
108
|
surface: "bg-sui-surface",
|
|
109
109
|
canvas: "bg-sui-canvas"
|
|
110
|
-
},
|
|
110
|
+
}, Z = i(() => me[M.groupHeaderTone ?? (J.value ? "surface" : "sunken")]), he = i(() => {
|
|
111
111
|
let e = {};
|
|
112
|
-
return
|
|
113
|
-
}),
|
|
112
|
+
return M.rowHeight !== void 0 && (e["--sui-list-row"] = `${M.rowHeight}px`), M.groupHeaderHeight !== void 0 && (e["--sui-list-header"] = `${M.groupHeaderHeight}px`), Object.keys(e).length ? e : void 0;
|
|
113
|
+
}), Q = (e) => !!le["group-header"] || e.header !== void 0, ge = (e) => e.label ?? e.name ?? "", $ = [
|
|
114
114
|
"42%",
|
|
115
115
|
"58%",
|
|
116
116
|
"35%",
|
|
@@ -121,46 +121,46 @@ var ie = {
|
|
|
121
121
|
"5.5rem",
|
|
122
122
|
"4rem",
|
|
123
123
|
"4.75rem"
|
|
124
|
-
]
|
|
124
|
+
];
|
|
125
125
|
return (i, f) => (h(), s("div", {
|
|
126
126
|
ref_key: "root",
|
|
127
|
-
ref:
|
|
128
|
-
class: p(["flex flex-col text-13 text-sui-ink",
|
|
127
|
+
ref: L,
|
|
128
|
+
class: p(["flex flex-col text-13 text-sui-ink", J.value ? "gap-3" : k]),
|
|
129
129
|
style: m(he.value)
|
|
130
|
-
}, [
|
|
130
|
+
}, [B.value && i.$slots.empty ? (h(), s("div", {
|
|
131
131
|
key: 0,
|
|
132
|
-
class: p(
|
|
132
|
+
class: p(J.value && k)
|
|
133
133
|
}, [_(i.$slots, "empty")], 2)) : d.loading ? (h(!0), s(r, { key: 1 }, g(d.loadingGroups, (t, n) => (h(), s("section", {
|
|
134
134
|
key: n,
|
|
135
135
|
"aria-busy": "true",
|
|
136
|
-
class: p(
|
|
136
|
+
class: p(J.value ? k : "border-t border-sui-line-subtle first:border-t-0")
|
|
137
137
|
}, [c("div", {
|
|
138
138
|
"aria-hidden": "true",
|
|
139
|
-
class: p(["flex h-[var(--sui-list-header,2.25rem)] items-center gap-2 border-b border-sui-line-subtle pr-2", [
|
|
139
|
+
class: p(["flex h-[var(--sui-list-header,2.25rem)] items-center gap-2 border-b border-sui-line-subtle pr-2", [Z.value, d.collapsible ? "pl-1.5" : "pl-4"]])
|
|
140
140
|
}, [
|
|
141
|
-
d.collapsible ? (h(), s("span",
|
|
141
|
+
d.collapsible ? (h(), s("span", E)) : o("", !0),
|
|
142
142
|
i.$slots["group-leading"] || i.$slots["group-header"] ? (h(), s("span", {
|
|
143
143
|
key: 1,
|
|
144
|
-
class: p(["size-3.5 rounded-full",
|
|
145
|
-
}
|
|
144
|
+
class: p(["size-3.5 rounded-full", A])
|
|
145
|
+
})) : o("", !0),
|
|
146
146
|
c("span", {
|
|
147
|
-
class: p(["h-2.5 rounded-md",
|
|
147
|
+
class: p(["h-2.5 rounded-md", A]),
|
|
148
148
|
style: m({ width: _e[n % 3] })
|
|
149
|
-
}, null,
|
|
150
|
-
c("span", { class: p(["h-2.5 w-3.5 rounded-md",
|
|
149
|
+
}, null, 4),
|
|
150
|
+
c("span", { class: p(["h-2.5 w-3.5 rounded-md", A]) })
|
|
151
151
|
], 2), (h(!0), s(r, null, g(t, (t) => (h(), s("div", {
|
|
152
152
|
key: t,
|
|
153
153
|
"aria-hidden": "true",
|
|
154
|
-
class: p(["flex h-[var(--sui-list-row,2.5rem)] items-center gap-2.5 pr-4", [
|
|
154
|
+
class: p(["flex h-[var(--sui-list-row,2.5rem)] items-center gap-2.5 pr-4", [X.value ? "pl-9.5" : "pl-4", d.dividers && "[&+&]:border-t [&+&]:border-sui-line-subtle"]])
|
|
155
155
|
}, [
|
|
156
|
-
i.$slots.leading ||
|
|
156
|
+
i.$slots.leading || Y.value ? (h(), a(e, {
|
|
157
157
|
key: 0,
|
|
158
158
|
shape: "circle",
|
|
159
159
|
size: "1.25rem"
|
|
160
160
|
})) : o("", !0),
|
|
161
161
|
u(e, {
|
|
162
162
|
height: "0.75rem",
|
|
163
|
-
width:
|
|
163
|
+
width: $[(n * 3 + t) % $.length]
|
|
164
164
|
}, null, 8, ["width"]),
|
|
165
165
|
f[0] ||= c("span", { class: "flex-1" }, null, -1),
|
|
166
166
|
i.$slots.meta ? (h(), s(r, { key: 1 }, [u(e, {
|
|
@@ -173,39 +173,39 @@ var ie = {
|
|
|
173
173
|
], 2))), 128))], 2))), 128)) : (h(!0), s(r, { key: 2 }, g(d.groups, (e) => (h(), s("section", {
|
|
174
174
|
key: e.id,
|
|
175
175
|
"aria-label": e.label,
|
|
176
|
-
"aria-labelledby": !e.label && (e.name ||
|
|
177
|
-
class: p(
|
|
178
|
-
}, [e.name ||
|
|
176
|
+
"aria-labelledby": !e.label && (e.name || Q(e)) ? `${b(I)}-${e.id}-name` : void 0,
|
|
177
|
+
class: p(J.value ? k : "border-t border-sui-line-subtle first:border-t-0")
|
|
178
|
+
}, [e.name || Q(e) ? (h(), s("header", {
|
|
179
179
|
key: 0,
|
|
180
180
|
class: p(["flex h-[var(--sui-list-header,2.25rem)] items-center gap-2 border-b border-sui-line-subtle pr-2", [
|
|
181
|
-
|
|
182
|
-
!
|
|
183
|
-
|
|
181
|
+
Z.value,
|
|
182
|
+
!J.value && "sticky top-0 z-10",
|
|
183
|
+
H(e) ? "pl-1.5" : "pl-4"
|
|
184
184
|
]])
|
|
185
185
|
}, [
|
|
186
|
-
|
|
186
|
+
H(e) ? (h(), s("button", {
|
|
187
187
|
key: 0,
|
|
188
|
-
"aria-controls": `${b(
|
|
189
|
-
"aria-expanded": !
|
|
190
|
-
"aria-label":
|
|
191
|
-
class: p(
|
|
188
|
+
"aria-controls": `${b(I)}-${e.id}`,
|
|
189
|
+
"aria-expanded": !F.value.includes(e.id),
|
|
190
|
+
"aria-label": F.value.includes(e.id) ? d.expandLabel : d.collapseLabel,
|
|
191
|
+
class: p(j),
|
|
192
192
|
type: "button",
|
|
193
|
-
onClick: (t) =>
|
|
193
|
+
onClick: (t) => V(e.id)
|
|
194
194
|
}, [(h(), s("svg", {
|
|
195
195
|
"aria-hidden": "true",
|
|
196
|
-
class: p(["size-3 fill-none stroke-current transition-transform duration-150",
|
|
196
|
+
class: p(["size-3 fill-none stroke-current transition-transform duration-150", U(e) && "-rotate-90"]),
|
|
197
197
|
"stroke-linecap": "round",
|
|
198
198
|
"stroke-linejoin": "round",
|
|
199
199
|
"stroke-width": "1.5",
|
|
200
200
|
viewBox: "0 0 12 12"
|
|
201
|
-
}, [...f[1] ||= [c("path", { d: "M3 4.5 6 7.5l3-3" }, null, -1)]], 2))], 8,
|
|
202
|
-
|
|
201
|
+
}, [...f[1] ||= [c("path", { d: "M3 4.5 6 7.5l3-3" }, null, -1)]], 2))], 8, ne)) : o("", !0),
|
|
202
|
+
Q(e) ? (h(), a(v(`h${d.headingLevel}`), {
|
|
203
203
|
key: 1,
|
|
204
|
-
id: `${b(
|
|
204
|
+
id: `${b(I)}-${e.id}-name`,
|
|
205
205
|
class: "m-0 flex min-w-0 items-center gap-2 text-13 font-medium text-sui-ink"
|
|
206
206
|
}, {
|
|
207
|
-
default:
|
|
208
|
-
collapsed:
|
|
207
|
+
default: w(() => [_(i.$slots, "group-header", {
|
|
208
|
+
collapsed: F.value.includes(e.id),
|
|
209
209
|
count: e.count ?? e.items.length,
|
|
210
210
|
group: e
|
|
211
211
|
}, () => [l(y(e.header), 1)])]),
|
|
@@ -213,19 +213,19 @@ var ie = {
|
|
|
213
213
|
}, 1032, ["id"])) : (h(), s(r, { key: 2 }, [
|
|
214
214
|
_(i.$slots, "group-leading", { group: e }),
|
|
215
215
|
(h(), a(v(`h${d.headingLevel}`), {
|
|
216
|
-
id: `${b(
|
|
216
|
+
id: `${b(I)}-${e.id}-name`,
|
|
217
217
|
class: "m-0 text-13 font-medium text-sui-ink"
|
|
218
218
|
}, {
|
|
219
|
-
default:
|
|
219
|
+
default: w(() => [l(y(e.name), 1)]),
|
|
220
220
|
_: 2
|
|
221
221
|
}, 1032, ["id"])),
|
|
222
|
-
c("span",
|
|
222
|
+
c("span", re, y(e.count ?? e.items.length), 1)
|
|
223
223
|
], 64)),
|
|
224
|
-
c("span",
|
|
224
|
+
c("span", ie, [_(i.$slots, "group-actions", { group: e })]),
|
|
225
225
|
d.onNew ? (h(), s("button", {
|
|
226
226
|
key: 3,
|
|
227
227
|
"aria-label": d.newLabel.replace("{group}", ge(e)),
|
|
228
|
-
class: p(
|
|
228
|
+
class: p(j),
|
|
229
229
|
type: "button",
|
|
230
230
|
onClick: (t) => d.onNew(e)
|
|
231
231
|
}, [...f[2] ||= [c("svg", {
|
|
@@ -234,70 +234,70 @@ var ie = {
|
|
|
234
234
|
"stroke-linecap": "round",
|
|
235
235
|
"stroke-width": "1.5",
|
|
236
236
|
viewBox: "0 0 14 14"
|
|
237
|
-
}, [c("path", { d: "M7 2.5v9M2.5 7h9" })], -1)]], 8,
|
|
238
|
-
], 2)) : o("", !0),
|
|
239
|
-
id: `${b(
|
|
237
|
+
}, [c("path", { d: "M7 2.5v9M2.5 7h9" })], -1)]], 8, ae)) : o("", !0)
|
|
238
|
+
], 2)) : o("", !0), T(c("ul", {
|
|
239
|
+
id: `${b(I)}-${e.id}`,
|
|
240
240
|
class: "m-0 list-none p-0"
|
|
241
241
|
}, [(h(!0), s(r, null, g(e.items, (e) => (h(), a(n, {
|
|
242
|
-
key:
|
|
242
|
+
key: R(e),
|
|
243
243
|
disabled: !d.contextItems,
|
|
244
244
|
items: d.contextItems?.(e),
|
|
245
245
|
label: d.contextLabel,
|
|
246
|
-
onClickItem: (t) =>
|
|
246
|
+
onClickItem: (t) => N("context-item", t, e)
|
|
247
247
|
}, {
|
|
248
|
-
default:
|
|
249
|
-
class: p(["group/row relative flex h-[var(--sui-list-row,2.5rem)] items-center transition-colors duration-100 has-focus-visible:sui-ring-inset", [d.dividers && "[&+&]:border-t [&+&]:border-sui-line-subtle",
|
|
248
|
+
default: w(() => [c("li", {
|
|
249
|
+
class: p(["group/row relative flex h-[var(--sui-list-row,2.5rem)] items-center transition-colors duration-100 has-focus-visible:sui-ring-inset", [d.dividers && "[&+&]:border-t [&+&]:border-sui-line-subtle", P.value.includes(R(e)) ? "bg-sui-accent-wash" : "hover:bg-sui-fill-hover has-focus-visible:bg-sui-fill-hover"]]),
|
|
250
250
|
style: m(e.depth ? { paddingLeft: `${e.depth * 22}px` } : void 0)
|
|
251
251
|
}, [
|
|
252
|
-
|
|
252
|
+
Y.value ? (h(), s("span", {
|
|
253
253
|
key: 0,
|
|
254
|
-
class: p(["absolute top-1/2 z-[1] flex size-4 -translate-y-1/2 items-center justify-center", !
|
|
254
|
+
class: p(["absolute top-1/2 z-[1] flex size-4 -translate-y-1/2 items-center justify-center", !P.value.length && "hidden group-hover/row:flex group-has-focus-visible/row:flex"]),
|
|
255
255
|
"data-list-check": "",
|
|
256
256
|
style: m({ left: `${16 + (e.depth ?? 0) * 22}px` })
|
|
257
257
|
}, [u(t, {
|
|
258
258
|
"aria-label": d.selectLabel,
|
|
259
|
-
"model-value":
|
|
259
|
+
"model-value": P.value.includes(R(e)),
|
|
260
260
|
tabindex: "-1",
|
|
261
|
-
"onUpdate:modelValue": (t) =>
|
|
261
|
+
"onUpdate:modelValue": (t) => K(e)
|
|
262
262
|
}, null, 8, [
|
|
263
263
|
"aria-label",
|
|
264
264
|
"model-value",
|
|
265
265
|
"onUpdate:modelValue"
|
|
266
266
|
])], 6)) : o("", !0),
|
|
267
|
-
|
|
267
|
+
X.value ? (h(), s("span", {
|
|
268
268
|
key: 1,
|
|
269
|
-
class: p(["flex w-7 shrink-0 justify-end transition-opacity duration-100",
|
|
269
|
+
class: p(["flex w-7 shrink-0 justify-end transition-opacity duration-100", P.value.length ? "opacity-100" : "opacity-0 group-hover/row:opacity-100"])
|
|
270
270
|
}, [u(t, {
|
|
271
271
|
"aria-label": d.selectLabel,
|
|
272
|
-
"model-value":
|
|
272
|
+
"model-value": P.value.includes(R(e)),
|
|
273
273
|
tabindex: "-1",
|
|
274
|
-
"onUpdate:modelValue": (t) =>
|
|
274
|
+
"onUpdate:modelValue": (t) => K(e)
|
|
275
275
|
}, null, 8, [
|
|
276
276
|
"aria-label",
|
|
277
277
|
"model-value",
|
|
278
278
|
"onUpdate:modelValue"
|
|
279
279
|
])], 2)) : o("", !0),
|
|
280
280
|
c("div", {
|
|
281
|
-
class: p(["flex h-full min-w-0 flex-1 items-center gap-2.5 pr-4 outline-hidden", [
|
|
281
|
+
class: p(["flex h-full min-w-0 flex-1 items-center gap-2.5 pr-4 outline-hidden", [X.value ? "pl-2.5" : "pl-4", (d.onRowClick || d.selectable) && "cursor-pointer"]]),
|
|
282
282
|
"data-list-row": "",
|
|
283
283
|
role: d.onRowClick ? "button" : void 0,
|
|
284
|
-
tabindex:
|
|
285
|
-
onClick: (t) =>
|
|
286
|
-
onKeydown: (t) =>
|
|
287
|
-
onMousedown:
|
|
284
|
+
tabindex: z.value ? 0 : void 0,
|
|
285
|
+
onClick: (t) => de(t, e),
|
|
286
|
+
onKeydown: (t) => pe(t, e),
|
|
287
|
+
onMousedown: fe
|
|
288
288
|
}, [
|
|
289
289
|
i.$slots.leading ? (h(), s("span", {
|
|
290
290
|
key: 0,
|
|
291
|
-
class: p(["flex shrink-0 items-center gap-2 text-sui-ink-muted tabular-nums",
|
|
291
|
+
class: p(["flex shrink-0 items-center gap-2 text-sui-ink-muted tabular-nums", Y.value && (P.value.length ? "[&>*:first-child]:invisible" : "group-hover/row:[&>*:first-child]:invisible group-has-focus-visible/row:[&>*:first-child]:invisible")])
|
|
292
292
|
}, [_(i.$slots, "leading", {
|
|
293
293
|
item: e,
|
|
294
|
-
selected:
|
|
295
|
-
selecting:
|
|
296
|
-
toggle: () =>
|
|
294
|
+
selected: P.value.includes(R(e)),
|
|
295
|
+
selecting: P.value.length > 0,
|
|
296
|
+
toggle: () => K(e)
|
|
297
297
|
})], 2)) : o("", !0),
|
|
298
|
-
c("span",
|
|
298
|
+
c("span", ce, [_(i.$slots, "title", { item: e }, () => [l(y(e.name), 1)])]),
|
|
299
299
|
i.$slots.meta ? (h(), s("span", O, [_(i.$slots, "meta", { item: e })])) : o("", !0)
|
|
300
|
-
], 42,
|
|
300
|
+
], 42, se)
|
|
301
301
|
], 6)]),
|
|
302
302
|
_: 2
|
|
303
303
|
}, 1032, [
|
|
@@ -305,10 +305,10 @@ var ie = {
|
|
|
305
305
|
"items",
|
|
306
306
|
"label",
|
|
307
307
|
"onClickItem"
|
|
308
|
-
]))), 128))], 8,
|
|
308
|
+
]))), 128))], 8, oe), [[te, !U(e)]])], 10, D))), 128))], 6));
|
|
309
309
|
}
|
|
310
310
|
});
|
|
311
311
|
//#endregion
|
|
312
|
-
export {
|
|
312
|
+
export { M as default };
|
|
313
313
|
|
|
314
314
|
//# sourceMappingURL=DataList.vue_vue_type_script_setup_true_lang.js.map
|