@sparklingopinions/sparkling-ui 0.4.2 → 0.6.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 +176 -26
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Avatar/Avatar.vue.d.ts +3 -2
- package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +20 -14
- package/dist/components/Avatar/Avatar.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 +6 -2
- package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js +142 -74
- 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.d.ts +1 -1
- package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.js +7 -0
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -0
- package/dist/components/ContextMenu/ContextMenu.vue.d.ts +44 -0
- package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js +84 -0
- package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/ContextMenu/index.d.ts +2 -0
- package/dist/components/DataList/DataList.js.map +1 -1
- package/dist/components/DataList/DataList.vue.d.ts +8 -0
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js +71 -52
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/DataList/types.d.ts +5 -1
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/Dialog/Dialog.vue.d.ts +22 -6
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +174 -72
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Dialog/useSheetDrag.d.ts +16 -0
- package/dist/components/Dialog/useSheetDrag.js +37 -0
- package/dist/components/Dialog/useSheetDrag.js.map +1 -0
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.vue.d.ts +6 -30
- package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +54 -74
- package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.vue.d.ts +9 -3
- package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +35 -7
- 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.d.ts +4 -1
- package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js +29 -24
- package/dist/components/Filters/FilterChip.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.d.ts +20 -1
- package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js +78 -56
- 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.d.ts +21 -1
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js +90 -66
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/index.d.ts +2 -1
- package/dist/components/Filters/trigger.d.ts +17 -0
- package/dist/components/Filters/trigger.js +33 -0
- package/dist/components/Filters/trigger.js.map +1 -0
- package/dist/components/Filters/types.d.ts +8 -0
- package/dist/components/FormField/FormField.js.map +1 -1
- package/dist/components/FormField/FormField.vue.d.ts +10 -0
- package/dist/components/FormField/FormField.vue_vue_type_script_setup_true_lang.js +31 -20
- package/dist/components/FormField/FormField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Icon/iconSet.js +9 -1
- package/dist/components/Icon/iconSet.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.vue.d.ts +6 -3
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +20 -17
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/SegmentedControl/index.d.ts +1 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Table/Table.vue.d.ts +4 -0
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js +66 -56
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Table/types.d.ts +2 -0
- package/dist/components/Tag/Tag.js.map +1 -1
- package/dist/components/Tag/Tag.vue.d.ts +16 -3
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js +42 -19
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Toast/ToastMessage.js.map +1 -1
- package/dist/components/Toast/ToastMessage.vue.d.ts +13 -1
- package/dist/components/Toast/ToastMessage.vue_vue_type_script_setup_true_lang.js +58 -23
- package/dist/components/Toast/ToastMessage.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Toast/Toaster.js.map +1 -1
- package/dist/components/Toast/Toaster.vue.d.ts +7 -3
- package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js +50 -21
- package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/internal/MenuItemContent.js +7 -0
- package/dist/components/internal/MenuItemContent.js.map +1 -0
- package/dist/components/internal/MenuItemContent.vue.d.ts +7 -0
- package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js +26 -0
- package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/internal/menu.d.ts +46 -0
- package/dist/components/internal/menu.js +33 -0
- package/dist/components/internal/menu.js.map +1 -0
- package/dist/composables/toast.d.ts +20 -5
- package/dist/composables/toast.js +28 -20
- package/dist/composables/toast.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +34 -33
- package/package.json +1 -1
- package/src/styles/tailwind.css +29 -0
|
@@ -6,10 +6,13 @@ export interface SegmentedControlOption<T extends string> {
|
|
|
6
6
|
/** An SVG path on a 24px grid. */
|
|
7
7
|
icon?: string;
|
|
8
8
|
}
|
|
9
|
+
export interface SegmentedControlProps<T extends string> {
|
|
10
|
+
options: SegmentedControlOption<T>[];
|
|
11
|
+
/** Fills its row, the segments sharing it evenly with their labels truncated: phone tab bars. */
|
|
12
|
+
block?: boolean;
|
|
13
|
+
}
|
|
9
14
|
declare const __VLS_export: <T extends string>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
10
|
-
props: import("vue").PublicProps & __VLS_PrettifyLocal<({
|
|
11
|
-
options: SegmentedControlOption<T>[];
|
|
12
|
-
} & {
|
|
15
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<(SegmentedControlProps<T> & {
|
|
13
16
|
modelValue: T;
|
|
14
17
|
}) & {
|
|
15
18
|
"onUpdate:modelValue"?: ((value: T) => any) | undefined;
|
package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import e from "../Icon/Icon.js";
|
|
2
|
-
import { Fragment as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a,
|
|
3
|
-
import { RadioGroupItem as
|
|
2
|
+
import { Fragment as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, defineComponent as o, mergeModels as s, normalizeClass as c, openBlock as l, renderList as u, toDisplayString as d, unref as f, useModel as p, withCtx as m } from "vue";
|
|
3
|
+
import { RadioGroupItem as h, RadioGroupRoot as g } from "reka-ui";
|
|
4
4
|
//#region src/components/SegmentedControl/SegmentedControl.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var
|
|
5
|
+
var _ = {
|
|
6
6
|
key: 1,
|
|
7
7
|
"aria-hidden": "true",
|
|
8
8
|
class: "h-3.5 w-3.5",
|
|
@@ -10,36 +10,39 @@ var v = {
|
|
|
10
10
|
stroke: "currentColor",
|
|
11
11
|
"stroke-width": "2",
|
|
12
12
|
viewBox: "0 0 24 24"
|
|
13
|
-
},
|
|
13
|
+
}, v = ["d"], y = { class: "min-w-0 truncate" }, b = /*@__PURE__*/ o({
|
|
14
14
|
__name: "SegmentedControl",
|
|
15
|
-
props: /*@__PURE__*/
|
|
15
|
+
props: /*@__PURE__*/ s({
|
|
16
|
+
options: {},
|
|
17
|
+
block: { type: Boolean }
|
|
18
|
+
}, {
|
|
16
19
|
modelValue: { required: !0 },
|
|
17
20
|
modelModifiers: {}
|
|
18
21
|
}),
|
|
19
22
|
emits: ["update:modelValue"],
|
|
20
|
-
setup(
|
|
21
|
-
let
|
|
22
|
-
return (
|
|
23
|
-
modelValue:
|
|
24
|
-
"onUpdate:modelValue": b[0] ||= (e) =>
|
|
25
|
-
class: "flex
|
|
23
|
+
setup(o) {
|
|
24
|
+
let s = p(o, "modelValue");
|
|
25
|
+
return (p, b) => (l(), n(f(g), {
|
|
26
|
+
modelValue: s.value,
|
|
27
|
+
"onUpdate:modelValue": b[0] ||= (e) => s.value = e,
|
|
28
|
+
class: c(["flex gap-0.5 rounded-lg bg-sui-sunken p-0.75 ring-1 ring-sui-line-subtle ring-inset", o.block ? "w-full" : "w-fit"]),
|
|
26
29
|
orientation: "horizontal"
|
|
27
30
|
}, {
|
|
28
|
-
default:
|
|
31
|
+
default: m(() => [(l(!0), i(t, null, u(o.options, (t) => (l(), n(f(h), {
|
|
29
32
|
key: t.value,
|
|
30
|
-
class:
|
|
33
|
+
class: c(["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]", [o.block ? "min-w-0 flex-1 justify-center px-2" : "pr-3 pl-2.5", t.value === s.value ? "bg-sui-surface text-sui-ink shadow-(--sui-shadow-raised) ring-1 ring-sui-line-subtle" : "text-sui-ink-body hover:text-sui-ink"]]),
|
|
31
34
|
value: t.value
|
|
32
35
|
}, {
|
|
33
|
-
default:
|
|
36
|
+
default: m(() => [t.iconName ? (l(), n(e, {
|
|
34
37
|
key: 0,
|
|
35
38
|
class: "h-4 w-4",
|
|
36
|
-
color: t.value ===
|
|
39
|
+
color: t.value === s.value ? "ink" : "ink-body",
|
|
37
40
|
name: t.iconName
|
|
38
|
-
}, null, 8, ["color", "name"])) : t.icon ? (
|
|
41
|
+
}, null, 8, ["color", "name"])) : t.icon ? (l(), i("svg", _, [a("path", { d: t.icon }, null, 8, v)])) : r("", !0), a("span", y, d(t.label), 1)]),
|
|
39
42
|
_: 2
|
|
40
43
|
}, 1032, ["class", "value"]))), 128))]),
|
|
41
44
|
_: 1
|
|
42
|
-
}, 8, ["modelValue"]));
|
|
45
|
+
}, 8, ["modelValue", "class"]));
|
|
43
46
|
}
|
|
44
47
|
});
|
|
45
48
|
//#endregion
|
package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentedControl.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_withCtx","_createElementBlock","_Fragment","_renderList","
|
|
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,2 +1,2 @@
|
|
|
1
1
|
export { default as SegmentedControl } from './SegmentedControl.vue';
|
|
2
|
-
export type { SegmentedControlOption } from './SegmentedControl.vue';
|
|
2
|
+
export type { SegmentedControlOption, SegmentedControlProps } from './SegmentedControl.vue';
|
|
@@ -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 /** 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 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 th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value ? 'h-9' : 'h-11'\n])\nconst td = computed(() => [\n 'truncate border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-10' : 'h-[3.5625rem]'\n])\nconst pad = computed(() => (sm.value ? 'px-3 py-1.5' : 'px-4 py-3'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\">\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=\"bg-sui-sunken\" :class=\"[th, checkCell]\">\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' : 'bg-sui-sunken 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 v-for=\"column in columns\" :key=\"column.key\" :class=\"[td, pad, alignClass[column.align ?? 'left']]\">\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 /** 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 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(() => (fixed.value ? { '--sui-table-row': `${props.rowHeight}px` } : undefined))\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value ? 'h-[var(--sui-table-row,2.25rem)]' : 'h-[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'\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":""}
|
|
@@ -11,6 +11,10 @@ export interface TableProps<T> {
|
|
|
11
11
|
loadingRows?: number;
|
|
12
12
|
/** md: 57px rows. sm: 40px, for dense lists. */
|
|
13
13
|
size?: 'md' | 'sm';
|
|
14
|
+
/** A row height in px between the sizes, such as 44, for body and header rows; sets `--sui-table-row`. */
|
|
15
|
+
rowHeight?: number;
|
|
16
|
+
/** canvas lays the header on the page colour, for a table directly on the canvas. */
|
|
17
|
+
headerTone?: 'sunken' | 'canvas';
|
|
14
18
|
/** The table's name for screen readers. */
|
|
15
19
|
caption?: string;
|
|
16
20
|
selectAllLabel?: string;
|
|
@@ -2,28 +2,28 @@ import e from "../Skeleton/Skeleton.js";
|
|
|
2
2
|
import t from "../Checkbox/Checkbox.js";
|
|
3
3
|
import { Fragment as n, computed as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, mergeModels as d, normalizeClass as f, normalizeStyle as p, openBlock as m, renderList as h, renderSlot as g, resolveDynamicComponent as _, toDisplayString as v, useModel as y, useSlots as b, withCtx as x, withModifiers as S } from "vue";
|
|
4
4
|
//#region src/components/Table/Table.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var C = { class: "overflow-
|
|
5
|
+
var C = { class: "overflow-x-auto" }, w = { class: "w-full min-w-[var(--sui-table-min,720px)] table-fixed border-collapse" }, T = {
|
|
6
6
|
key: 0,
|
|
7
7
|
class: "sr-only"
|
|
8
|
-
},
|
|
8
|
+
}, E = {
|
|
9
9
|
key: 0,
|
|
10
10
|
class: "w-12"
|
|
11
|
-
},
|
|
11
|
+
}, D = ["onClick"], O = {
|
|
12
12
|
key: 0,
|
|
13
13
|
d: "M3 7.5 6 4.5l3 3"
|
|
14
|
-
},
|
|
14
|
+
}, ee = {
|
|
15
15
|
key: 1,
|
|
16
16
|
d: "M3 4.5 6 7.5l3-3"
|
|
17
|
-
},
|
|
17
|
+
}, te = {
|
|
18
18
|
key: 2,
|
|
19
19
|
d: "M3.5 4.5 6 2l2.5 2.5M3.5 7.5 6 10l2.5-2.5"
|
|
20
|
-
},
|
|
20
|
+
}, ne = ["aria-busy"], re = { key: 0 }, ie = ["colspan"], ae = ["aria-selected", "onClick"], k = {
|
|
21
21
|
key: 1,
|
|
22
22
|
class: "text-sui-ink-muted"
|
|
23
|
-
},
|
|
23
|
+
}, A = {
|
|
24
24
|
key: 0,
|
|
25
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"
|
|
26
|
-
},
|
|
26
|
+
}, j = "w-12 pl-4", M = /*@__PURE__*/ u({
|
|
27
27
|
__name: "Table",
|
|
28
28
|
props: /*@__PURE__*/ d({
|
|
29
29
|
columns: {},
|
|
@@ -33,6 +33,8 @@ var C = { class: "overflow-hidden rounded-xl border border-sui-line-subtle bg-su
|
|
|
33
33
|
loading: { type: Boolean },
|
|
34
34
|
loadingRows: { default: 5 },
|
|
35
35
|
size: { default: "md" },
|
|
36
|
+
rowHeight: { default: void 0 },
|
|
37
|
+
headerTone: { default: "sunken" },
|
|
36
38
|
caption: { default: void 0 },
|
|
37
39
|
selectAllLabel: { default: "Select all rows" },
|
|
38
40
|
selectRowLabel: { default: "Select row" },
|
|
@@ -48,53 +50,60 @@ var C = { class: "overflow-hidden rounded-xl border border-sui-line-subtle bg-su
|
|
|
48
50
|
}),
|
|
49
51
|
emits: ["update:sort", "update:selected"],
|
|
50
52
|
setup(u) {
|
|
51
|
-
let d = u,
|
|
52
|
-
function
|
|
53
|
-
|
|
53
|
+
let d = u, M = y(u, "sort"), N = y(u, "selected"), P = b(), F = (e) => e[d.rowKey ?? "id"], I = r(() => d.rows.map(F)), L = r(() => I.value.length > 0 && I.value.every((e) => N.value.includes(e))), R = r(() => !L.value && I.value.some((e) => N.value.includes(e)));
|
|
54
|
+
function z() {
|
|
55
|
+
N.value = L.value ? N.value.filter((e) => !I.value.includes(e)) : [.../* @__PURE__ */ new Set([...N.value, ...I.value])];
|
|
54
56
|
}
|
|
55
|
-
function
|
|
56
|
-
|
|
57
|
+
function B(e) {
|
|
58
|
+
N.value = N.value.includes(e) ? N.value.filter((t) => t !== e) : [...N.value, e];
|
|
57
59
|
}
|
|
58
|
-
function
|
|
59
|
-
let t =
|
|
60
|
-
|
|
60
|
+
function V(e) {
|
|
61
|
+
let t = M.value?.key === e ? M.value.dir : null, n = t === null ? "asc" : t === "asc" ? "desc" : null;
|
|
62
|
+
M.value = n ? {
|
|
61
63
|
key: e,
|
|
62
64
|
dir: n
|
|
63
65
|
} : null;
|
|
64
66
|
}
|
|
65
|
-
function
|
|
66
|
-
return
|
|
67
|
+
function H(e) {
|
|
68
|
+
return M.value?.key === e ? M.value.dir : null;
|
|
67
69
|
}
|
|
68
|
-
function
|
|
69
|
-
let t =
|
|
70
|
+
function U(e) {
|
|
71
|
+
let t = H(e.key);
|
|
70
72
|
return t ? t === "asc" ? "ascending" : "descending" : e.sortable ? "none" : void 0;
|
|
71
73
|
}
|
|
72
|
-
let
|
|
74
|
+
let W = r(() => P.error ? "error" : d.loading ? "loading" : d.rows.length === 0 && P.empty ? "empty" : "rows"), G = r(() => d.columns.length + +!!d.selectable), K = {
|
|
73
75
|
left: "text-left",
|
|
74
76
|
center: "text-center",
|
|
75
77
|
right: "text-right"
|
|
76
|
-
},
|
|
78
|
+
}, q = [
|
|
77
79
|
"60%",
|
|
78
80
|
"45%",
|
|
79
81
|
"70%",
|
|
80
82
|
"35%",
|
|
81
83
|
"55%"
|
|
82
|
-
],
|
|
83
|
-
return (r, d) => (m(), o("div",
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
], J = r(() => d.size === "sm"), Y = r(() => d.rowHeight !== void 0), oe = r(() => Y.value ? { "--sui-table-row": `${d.rowHeight}px` } : void 0), X = r(() => ["border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap", J.value ? "h-[var(--sui-table-row,2.25rem)]" : "h-[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");
|
|
85
|
+
return (r, d) => (m(), o("div", {
|
|
86
|
+
class: "overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink",
|
|
87
|
+
style: p(oe.value)
|
|
88
|
+
}, [s("div", C, [s("table", w, [
|
|
89
|
+
u.caption ? (m(), o("caption", T, v(u.caption), 1)) : a("", !0),
|
|
90
|
+
s("colgroup", null, [u.selectable ? (m(), o("col", E)) : a("", !0), (m(!0), o(n, null, h(u.columns, (e) => (m(), o("col", {
|
|
86
91
|
key: e.key,
|
|
87
92
|
style: p({ width: typeof e.width == "number" ? `${e.width}px` : e.width })
|
|
88
93
|
}, null, 4))), 128))]),
|
|
89
94
|
s("thead", null, [s("tr", null, [u.selectable ? (m(), o("th", {
|
|
90
95
|
key: 0,
|
|
91
|
-
class: f([
|
|
96
|
+
class: f([
|
|
97
|
+
X.value,
|
|
98
|
+
j,
|
|
99
|
+
$.value
|
|
100
|
+
])
|
|
92
101
|
}, [l(t, {
|
|
93
102
|
"aria-label": u.selectAllLabel,
|
|
94
103
|
disabled: u.loading || u.rows.length === 0,
|
|
95
|
-
indeterminate:
|
|
96
|
-
"model-value":
|
|
97
|
-
"onUpdate:modelValue":
|
|
104
|
+
indeterminate: R.value,
|
|
105
|
+
"model-value": L.value,
|
|
106
|
+
"onUpdate:modelValue": z
|
|
98
107
|
}, null, 8, [
|
|
99
108
|
"aria-label",
|
|
100
109
|
"disabled",
|
|
@@ -102,12 +111,12 @@ var C = { class: "overflow-hidden rounded-xl border border-sui-line-subtle bg-su
|
|
|
102
111
|
"model-value"
|
|
103
112
|
])], 2)) : a("", !0), (m(!0), o(n, null, h(u.columns, (e) => (m(), i(_(e.label ? "th" : "td"), {
|
|
104
113
|
key: e.key,
|
|
105
|
-
"aria-sort":
|
|
114
|
+
"aria-sort": U(e),
|
|
106
115
|
class: f([
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
116
|
+
X.value,
|
|
117
|
+
se.value,
|
|
118
|
+
K[e.align ?? "left"],
|
|
119
|
+
H(e.key) ? "bg-sui-accent-wash text-sui-accent" : [$.value, "text-sui-ink-subtle"]
|
|
111
120
|
]),
|
|
112
121
|
scope: e.label ? "col" : void 0
|
|
113
122
|
}, {
|
|
@@ -116,53 +125,53 @@ var C = { class: "overflow-hidden rounded-xl border border-sui-line-subtle bg-su
|
|
|
116
125
|
class: f(["inline-flex h-full w-full items-center gap-1.5 rounded-md outline-hidden focus-visible:sui-ring-inset", [
|
|
117
126
|
e.align === "right" && "justify-end",
|
|
118
127
|
e.align === "center" && "justify-center",
|
|
119
|
-
!
|
|
128
|
+
!H(e.key) && "hover:text-sui-ink"
|
|
120
129
|
]]),
|
|
121
130
|
type: "button",
|
|
122
|
-
onClick: (t) =>
|
|
131
|
+
onClick: (t) => V(e.key)
|
|
123
132
|
}, [c(v(e.label) + " ", 1), (m(), o("svg", {
|
|
124
133
|
"aria-hidden": "true",
|
|
125
|
-
class: f(["size-3 shrink-0 fill-none stroke-current", !
|
|
134
|
+
class: f(["size-3 shrink-0 fill-none stroke-current", !H(e.key) && "opacity-50"]),
|
|
126
135
|
"stroke-linecap": "round",
|
|
127
136
|
"stroke-linejoin": "round",
|
|
128
137
|
"stroke-width": "1.5",
|
|
129
138
|
viewBox: "0 0 12 12"
|
|
130
|
-
}, [
|
|
139
|
+
}, [H(e.key) === "asc" ? (m(), o("path", O)) : H(e.key) === "desc" ? (m(), o("path", ee)) : (m(), o("path", te))], 2))], 10, D)) : (m(), o(n, { key: 1 }, [c(v(e.label), 1)], 64))]),
|
|
131
140
|
_: 2
|
|
132
141
|
}, 1032, [
|
|
133
142
|
"aria-sort",
|
|
134
143
|
"class",
|
|
135
144
|
"scope"
|
|
136
145
|
]))), 128))])]),
|
|
137
|
-
s("tbody", { "aria-busy": u.loading || void 0 }, [
|
|
146
|
+
s("tbody", { "aria-busy": u.loading || void 0 }, [W.value === "error" || W.value === "empty" ? (m(), o("tr", re, [s("td", {
|
|
138
147
|
class: "p-0",
|
|
139
|
-
colspan:
|
|
140
|
-
}, [g(r.$slots,
|
|
148
|
+
colspan: G.value
|
|
149
|
+
}, [g(r.$slots, W.value)], 8, ie)])) : W.value === "loading" ? (m(!0), o(n, { key: 1 }, h(u.loadingRows, (t) => (m(), o("tr", {
|
|
141
150
|
key: t,
|
|
142
151
|
"aria-hidden": "true",
|
|
143
152
|
class: "group/row"
|
|
144
153
|
}, [u.selectable ? (m(), o("td", {
|
|
145
154
|
key: 0,
|
|
146
|
-
class: f([
|
|
155
|
+
class: f([Z.value, j])
|
|
147
156
|
}, [l(e, { size: "1rem" })], 2)) : a("", !0), (m(!0), o(n, null, h(u.columns, (n, r) => (m(), o("td", {
|
|
148
157
|
key: n.key,
|
|
149
|
-
class: f([
|
|
158
|
+
class: f([Z.value, Q.value])
|
|
150
159
|
}, [l(e, {
|
|
151
160
|
height: "0.75rem",
|
|
152
|
-
width:
|
|
161
|
+
width: q[(t + r) % 5]
|
|
153
162
|
}, null, 8, ["width"])], 2))), 128))]))), 128)) : (m(!0), o(n, { key: 2 }, h(u.rows, (e) => (m(), o("tr", {
|
|
154
|
-
key:
|
|
155
|
-
"aria-selected": u.selectable ?
|
|
156
|
-
class: f(["group/row transition-colors duration-150", [
|
|
163
|
+
key: F(e),
|
|
164
|
+
"aria-selected": u.selectable ? N.value.includes(F(e)) : void 0,
|
|
165
|
+
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"]]),
|
|
157
166
|
onClick: (t) => u.onRowClick?.(e)
|
|
158
167
|
}, [u.selectable ? (m(), o("td", {
|
|
159
168
|
key: 0,
|
|
160
|
-
class: f([
|
|
169
|
+
class: f([Z.value, j]),
|
|
161
170
|
onClick: d[0] ||= S(() => {}, ["stop"])
|
|
162
171
|
}, [l(t, {
|
|
163
172
|
"aria-label": u.selectRowLabel,
|
|
164
|
-
"model-value":
|
|
165
|
-
"onUpdate:modelValue": (t) =>
|
|
173
|
+
"model-value": N.value.includes(F(e)),
|
|
174
|
+
"onUpdate:modelValue": (t) => B(F(e))
|
|
166
175
|
}, null, 8, [
|
|
167
176
|
"aria-label",
|
|
168
177
|
"model-value",
|
|
@@ -170,18 +179,19 @@ var C = { class: "overflow-hidden rounded-xl border border-sui-line-subtle bg-su
|
|
|
170
179
|
])], 2)) : a("", !0), (m(!0), o(n, null, h(u.columns, (t) => (m(), o("td", {
|
|
171
180
|
key: t.key,
|
|
172
181
|
class: f([
|
|
182
|
+
Z.value,
|
|
173
183
|
Q.value,
|
|
174
|
-
|
|
175
|
-
|
|
184
|
+
K[t.align ?? "left"],
|
|
185
|
+
t.wrap ? "break-words whitespace-normal" : "truncate"
|
|
176
186
|
])
|
|
177
187
|
}, [g(r.$slots, `cell-${t.key}`, {
|
|
178
188
|
row: e,
|
|
179
189
|
value: e[t.key]
|
|
180
|
-
}, () => [e[t.key] != null && e[t.key] !== "" ? (m(), o(n, { key: 0 }, [c(v(e[t.key]), 1)], 64)) : (m(), o("span",
|
|
181
|
-
])]), r.$slots.footer ? (m(), o("div",
|
|
190
|
+
}, () => [e[t.key] != null && e[t.key] !== "" ? (m(), o(n, { key: 0 }, [c(v(e[t.key]), 1)], 64)) : (m(), o("span", k, "–"))])], 2))), 128))], 10, ae))), 128))], 8, ne)
|
|
191
|
+
])]), r.$slots.footer ? (m(), o("div", A, [g(r.$slots, "footer")])) : a("", !0)], 4));
|
|
182
192
|
}
|
|
183
193
|
});
|
|
184
194
|
//#endregion
|
|
185
|
-
export {
|
|
195
|
+
export { M as default };
|
|
186
196
|
|
|
187
197
|
//# sourceMappingURL=Table.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","_useSlots","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_normalizeStyle","_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","_hoisted_15","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","th","td","pad","headPad","openBlock","createElementBlock","createElementVNode","toDisplayString","createCommentVNode","Fragment","renderList","normalizeStyle","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 /** 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 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 th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value ? 'h-9' : 'h-11'\n])\nconst td = computed(() => [\n 'truncate border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-10' : 'h-[3.5625rem]'\n])\nconst pad = computed(() => (sm.value ? 'px-3 py-1.5' : 'px-4 py-3'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\">\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=\"bg-sui-sunken\" :class=\"[th, checkCell]\">\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' : 'bg-sui-sunken 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 v-for=\"column in columns\" :key=\"column.key\" :class=\"[td, pad, alignClass[column.align ?? 'left']]\">\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","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 /** 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 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(() => (fixed.value ? { '--sui-table-row': `${props.rowHeight}px` } : undefined))\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value ? 'h-[var(--sui-table-row,2.25rem)]' : 'h-[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'\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":";;;;;;;;;;;;;;;;;;;;;;;;;A,GAoHMqC,IAAY,a;;;;;;;;;;;;;;;;;;;;;;;;;;;EArFlB,IAAMM,IAAQC,GAYRC,IAAO5C,EAA6B2C,GAAC,MAAyB,GAC9DG,IAAW9C,EAAsB2C,GAAC,UAAiC,GAEnEI,IAAQ9C,EAAA,GAaRgD,KAAQ,MAAoBC,EAAIR,EAAM,UAAU,OAChDS,IAAMC,QAAeV,EAAM,KAAK,IAAIO,CAAI,CAAC,GACzCI,IAAcD,QAAeD,EAAI,MAAM,SAAS,KAAKA,EAAI,MAAM,OAAO,MAAOL,EAAS,MAAM,SAASQ,CAAE,CAAC,CAAC,GACzGC,IAAeH,QAAe,CAACC,EAAY,SAASF,EAAI,MAAM,MAAM,MAAOL,EAAS,MAAM,SAASQ,CAAE,CAAC,CAAC;EAE7G,SAASE,IAAY;GACnB,EAAS,QAAQH,EAAY,QACzBP,EAAS,MAAM,QAAQ,MAAO,CAACK,EAAI,MAAM,SAASG,CAAE,CAAC,IACrD,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAGR,EAAS,OAAO,GAAGK,EAAI,KAAK,CAAC,CAAC;EACpD;EAEA,SAASM,EAAO,GAAa;GAC3B,EAAS,QAAQX,EAAS,MAAM,SAASQ,CAAE,IAAIR,EAAS,MAAM,QAAQ,MAAMY,MAAMJ,CAAE,IAAI,CAAC,GAAGR,EAAS,OAAOQ,CAAE;EAChH;EAGA,SAASK,EAAO,GAAa;GAC3B,IAAMC,IAAMhB,EAAK,OAAO,QAAQiB,IAAMjB,EAAK,MAAM,MAAM,MACjDkB,IAAOF,MAAQ,OAAO,QAAQA,MAAQ,QAAQ,SAAS;GAC7D,EAAK,QAAQE,IAAO;IAAE;IAAK,KAAKA;GAAK,IAAI;EAC3C;EAEA,SAASC,EAAM,GAAa;GAC1B,OAAOnB,EAAK,OAAO,QAAQiB,IAAMjB,EAAK,MAAM,MAAM;EACpD;EAEA,SAASoB,EAAS,GAAqB;GACrC,IAAMJ,IAAMG,EAAME,EAAO,GAAG;GAE5B,OADIL,IAAYA,MAAQ,QAAQ,cAAc,eACvCK,EAAO,WAAW,SAAS,KAAA;EACpC;EAEA,IAAMC,IAAQd,QACRL,EAAM,QAAc,UACpBL,EAAM,UAAgB,YACnBA,EAAM,KAAK,WAAW,KAAKK,EAAM,QAAQ,UAAU,MAC3D,GAEKoB,IAAcf,QAAeV,EAAM,QAAQ,SAAU,KAAM,UAAmB,GAC9E0B,IAAa;GAAE,MAAM;GAAa,QAAQ;GAAe,OAAO;EAAa,GAC7EC,IAAiB;GAAC;GAAO;GAAO;GAAO;GAAO;EAAK,GAEnDC,IAAKlB,QAAeV,EAAM,SAAS,IAAI,GACvC6B,IAAQnB,QAAeV,EAAM,cAAc,KAAA,CAAS,GACpD8B,KAAWpB,QAAgBmB,EAAM,QAAQ,EAAE,mBAAmB,GAAG7B,EAAM,UAAU,IAAI,IAAI,KAAA,CAAU,GACnG+B,IAAKrB,QAAe,CACxB,yEACAkB,EAAG,QAAQ,qCAAqC,kCAClD,CAAC,GACKI,IAAKtB,QAAe,CACxB,4FACAkB,EAAG,QAAQ,oCAAoC,oCACjD,CAAC,GAEKK,IAAMvB,QAAe,CAACkB,EAAG,QAAQ,SAAS,QAAQ,CAACC,EAAM,UAAUD,EAAG,QAAQ,WAAW,OAAO,CAAC,GACjGM,IAAWxB,QAAgBV,EAAM,eAAe,WAAW,kBAAkB,eAAgB,GAC7FmC,KAAUzB,QAAgBkB,EAAG,QAAQ,SAAS,MAAO;E,kBAMzDpE,EAAA,GAAAC,EAoIM,OAAA;GAnIJ,OAAM;GACL,OAAKC,EAAEoE,GAAA,KAAQ;E,IAEhBnE,EAyHM,OAzHNiB,GAyHM,CAxHJjB,EAuHQ,SAvHRkB,GAuHQ;GAtHSoB,EAAA,WAAfzC,EAAA,GAAAC,EAIU,WAJVqB,GAIUlB,EAFNqC,EAAA,OAAO,GAAA,CAAA,K;GAGXtC,EAOW,YAAA,MAAA,CANEsC,EAAA,cAAXzC,EAAA,GAAAC,EAAsC,OAAtCsB,CAAsC,K,YACtCvB,EAAA,EAAA,GAAAC,EAIEK,GAAA,MAAAC,EAHiBkC,EAAA,UAAV,OADTzC,EAAA,GAAAC,EAIE,OAAA;IAFC,KAAK8D,EAAO;IACZ,OAAK7D,EAAA,EAAA,OAAA,OAAkB6D,EAAO,SAAK,WAAA,GAAmBA,EAAO,MAAK,MAAOA,EAAO,MAAK,CAAA;;GAG1F5D,EAqDQ,SAAA,MAAA,CApDNA,EAmDK,MAAA,MAAA,CAlDOsC,EAAA,cAAVzC,EAAA,GAAAC,EAQK,MAAA;;IARkB,OAAKO,EAAA;KAAG+D,EAAA;KAAIrC;KAAWwC,EAAA;IAAQ,CAAA;G,IACpDjE,EAMEC,GAAA;IALC,cAAY+B,EAAA;IACZ,UAAUA,EAAA,WAAWA,EAAA,KAAK,WAAM;IAChC,eAAeY,EAAA;IACf,eAAaF,EAAA;IACb,uBAAoBG;;;;;;G,uBAGzBtD,EAAA,EAAA,GAAAC,EAwCYK,GAAA,MAAAC,EAtCOkC,EAAA,UAAV,OAFTzC,EAAA,GAAAW,EAwCYC,EAvCLmD,EAAO,QAAK,OAAA,IAAA,GAAA;IAEhB,KAAKA,EAAO;IACZ,aAAWD,EAASC,CAAM;IAC1B,OAAKvD,EAAA;KAAoB+D,EAAA;KAAoBI,GAAA;KAAyBT,EAAWH,EAAO,SAAK;KAA6BF,EAAME,EAAO,GAAG,IAAA,uCAAA,CAA4CW,EAAA,OAAQ,qBAAA;;IAM9L,OAAOX,EAAO,QAAK,QAAW,KAAA;;IAE/B,SAAAlD,QAyBS,CAxBDkD,EAAO,YADf/D,EAAA,GAAAC,EAyBS,UAAA;;KAvBP,OAAKO,EAAA,CAAC,yGAAuG;MACjFuD,EAAO,UAAK,WAAA;MAAiDA,EAAO,UAAK,YAAA;MAAsD,CAAAF,EAAME,EAAO,GAAG,KAAA;;KAK3K,MAAK;KACJ,UAAK,MAAEN,EAAOM,EAAO,GAAG;I,IAEtBjD,EAAAV,EAAA2D,EAAO,KAAK,IAAG,KAClB,CAAA,IAAA/D,EAAA,GAAAC,EAYM,OAAA;KAXJ,eAAY;KACZ,OAAKO,EAAA,CAAC,4CAA0C,CACvCqD,EAAME,EAAO,GAAG,KAAA,YAAA,CAAA;KACzB,kBAAe;KACf,mBAAgB;KAChB,gBAAa;KACb,SAAQ;I,IAEIF,EAAME,EAAO,GAAG,MAAA,SAA5B/D,EAAA,GAAAC,EAAgE,QAAhEwB,CAAgE,KAC/CoC,EAAME,EAAO,GAAG,MAAA,UAAjC/D,EAAA,GAAAC,EAAsE,QAAtEyB,EAAsE,MACtE1B,EAAA,GAAAC,EAA6D,QAA7D0B,EAA6D,E,oBAGjE3B,EAAA,GAAAC,EAA8CK,GAAA,EAAA,KAAA,EAAA,GAAA,CAA1BQ,EAAAV,EAAA2D,EAAO,KAAK,GAAA,CAAA,C;;;;;;;GAItC5D,EAkDQ,SAAA,EAlDA,aAAWsC,EAAA,WAAW,KAAA,E,IAClBuB,EAAA,UAAK,WAAgBA,EAAA,UAAK,WAApChE,EAAA,GAAAC,EAIK,MAAA4B,IAAA,CAHH1B,EAEK,MAAA;IAFD,OAAM;IAAO,SAAS8D,EAAA;G,IACxBlD,EAAsB4E,EAAA,QAAT3B,EAAA,KAAK,C,eAGDA,EAAA,UAAK,aACxBhE,EAAA,EAAA,GAAAC,EAKKK,GAAA,EAAA,KAAA,EAAA,GAAAC,EALWkC,EAAA,cAAL,OAAXzC,EAAA,GAAAC,EAKK,MAAA;IALyB,KAAK2F;IAAG,eAAY;IAAO,OAAM;G,IACnDnD,EAAA,cAAVzC,EAAA,GAAAC,EAA4E,MAAA;;IAArD,OAAKO,EAAA,CAAGgE,EAAA,OAAItC,CAAS,CAAA;G,IAAGzB,EAAwBO,GAAA,EAAd,MAAK,OAAM,CAAA,C,qBACpEhB,EAAA,EAAA,GAAAC,EAEKK,GAAA,MAAAC,EAFqBkC,EAAA,UAAd,GAAQ,OAApBzC,EAAA,GAAAC,EAEK,MAAA;IAF+B,KAAK8D,EAAO;IAAM,OAAKvD,EAAA,CAAGgE,EAAA,OAAIC,EAAA,KAAG,CAAA;G,IACnEhE,EAAkEO,GAAA;IAAxD,QAAO;IAAW,OAAOmD,GAAgByB,IAAIC,KAAC;G,mDAK5D7F,EAAA,EAAA,GAAAC,EAiCKK,GAAA,EAAA,KAAA,EAAA,GAAAC,EAhCWkC,EAAA,OAAP,OADTzC,EAAA,GAAAC,EAiCK,MAAA;IA/BF,KAAK8C,EAAKC,CAAG;IACb,iBAAeP,EAAA,aAAaG,EAAA,MAAS,SAASG,EAAKC,CAAG,CAAA,IAAK,KAAA;IAC5D,OAAKxC,EAAA,CAAC,4CAA0C,CACtBoC,EAAA,MAAS,SAASG,EAAKC,CAAG,CAAA,IAAA,uBAAA,uBAAmEP,EAAA,cAAU,gB;IAIhI,UAAK,MAAEA,EAAA,aAAaO,CAAG;G,IAEdP,EAAA,cAAVzC,EAAA,GAAAC,EAMK,MAAA;;IANkB,OAAKO,EAAA,CAAGgE,EAAA,OAAItC,CAAS,CAAA;IAAI,SAAK,AAAA4D,EAAA,OAAA7E,QAAN,CAAA,GAAW,CAAA,MAAA,CAAA;G,IACxDR,EAIEC,GAAA;IAHC,cAAY+B,EAAA;IACZ,eAAaG,EAAA,MAAS,SAASG,EAAKC,CAAG,CAAA;IACvC,wBAAkB,MAAEO,EAAOR,EAAKC,CAAG,CAAA;;;;;G,uBAGxChD,EAAA,EAAA,GAAAC,EAcKK,GAAA,MAAAC,EAbckC,EAAA,UAAV,OADTzC,EAAA,GAAAC,EAcK,MAAA;IAZF,KAAK8D,EAAO;IACZ,OAAKvD,EAAA;KAAsBgE,EAAA;KAAsBC,EAAA;KAAuBP,EAAWH,EAAO,SAAK;KAA+BA,EAAO,OAAI,kCAAA;;G,IAO1IhD,EAGO4E,EAAA,QAAA,QAHc5B,EAAO,OAAG;IAAU;IAAM,OAAOf,EAAIe,EAAO;GAAjE,SAGO,CAFWf,EAAIe,EAAO,QAAG,QAAaf,EAAIe,EAAO,SAAG,MAAzD/D,EAAA,GAAAC,EAAmGK,GAAA,EAAA,KAAA,EAAA,GAAA,CAA7BQ,EAAAV,EAAA4C,EAAIe,EAAO,IAAG,GAAA,CAAA,C,WACpF/D,EAAA,GAAAC,EAAgD,QAAhD+B,GAAwC,GAAC,E;E,MAS/CnC,EAAAA,OAAO,UADfG,EAAA,GAAAC,EAKM,OALNgC,GAKM,CADJlB,EAAsB4E,EAAA,QAAA,QAAA,C"}
|
|
@@ -5,6 +5,8 @@ export interface TableColumn {
|
|
|
5
5
|
width?: number | string;
|
|
6
6
|
align?: 'left' | 'center' | 'right';
|
|
7
7
|
sortable?: boolean;
|
|
8
|
+
/** Lets the cell's content wrap onto more lines, e.g. a name over a summary; cells otherwise truncate to one. */
|
|
9
|
+
wrap?: boolean;
|
|
8
10
|
}
|
|
9
11
|
export interface TableSort {
|
|
10
12
|
key: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tag.js","names":["_sfc_main","Tag_vue_vue_type_script_setup_true_lang_default","Tag_default"],"sources":["../../../src/components/Tag/Tag.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Hue } from '../../utils/hues'\nimport CloseSmallIcon from '../internal/CloseSmallIcon.vue'\n\nexport interface TagProps {\n /** The text; or use the default slot. */\n name?: string\n /** soft: a label people create, with an optional hue dot, removable. outline: a value from a fixed set (a stage, a status). */\n variant?: 'soft' | 'outline'\n /** soft only: a dot of the tag's own hue, on a neutral chip. */\n color?: Hue\n /** outline only: the quieter, superseded side, e.g. the \"from\" of a stage change. */\n muted?: boolean\n /** soft only. */\n removable?: boolean\n /** The remove button's accessible name. */\n removeLabel?: string\n}\n\nwithDefaults(defineProps<TagProps>(), {\n name: undefined,\n variant: 'soft',\n color: undefined,\n removeLabel: 'Remove tag'\n})\n\ndefineEmits<{ remove: [] }>()\n\nconst dots: Record<Hue, string> = {\n blue: 'bg-sui-hue-blue-ink',\n green: 'bg-sui-hue-green-ink',\n orange: 'bg-sui-hue-orange-ink',\n pink: 'bg-sui-hue-pink-ink',\n purple: 'bg-sui-hue-purple-ink',\n slate: 'bg-sui-hue-slate-ink',\n red: 'bg-sui-hue-red-ink',\n amber: 'bg-sui-hue-amber-ink',\n gray: 'bg-sui-ink'\n}\n</script>\n\n<!-- A label: soft for the ones people create, outline for a value from a fixed set. -->\n<template>\n <span\n v-if=\"variant === 'outline'\"\n class=\"inline-flex items-center gap-1.5 rounded-md border px-2 py-1 text-xs whitespace-nowrap\"\n :class=\"\n muted ? 'border-sui-line-subtle text-sui-ink-muted' : 'border-sui-line bg-sui-sunken font-medium text-sui-ink'\n \"\n >\n <slot>{{ name }}</slot>\n </span>\n <div\n v-else\n class=\"inline-flex items-center gap-1.5 rounded-md bg-sui-sunken px-2 py-0.5 text-xs font-medium text-sui-ink-body\"\n >\n <span v-if=\"color\" class=\"h-1.5 w-1.5 shrink-0 rounded-full\" :class=\"dots[color]\" />\n <span class=\"truncate\"\n ><slot>{{ name }}</slot></span\n >\n <button\n v-if=\"removable\"\n :aria-label=\"removeLabel\"\n class=\"-mr-0.5 inline-flex h-3.5 w-3.5 items-center justify-center rounded-full transition-colors hover:bg-sui-line focus-visible:sui-ring\"\n type=\"button\"\n @click=\"$emit('remove')\"\n >\n <CloseSmallIcon class=\"fill-sui-ink-muted stroke-sui-ink-muted\" />\n </button>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Tag.js","names":["_sfc_main","Tag_vue_vue_type_script_setup_true_lang_default","Tag_default"],"sources":["../../../src/components/Tag/Tag.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Hue } from '../../utils/hues'\nimport CloseSmallIcon from '../internal/CloseSmallIcon.vue'\n\nexport interface TagProps {\n /** The text; or use the default slot. */\n name?: string\n /** soft: a label people create, with an optional hue dot, removable. outline: a value from a fixed set (a stage, a status). */\n variant?: 'soft' | 'outline'\n /** soft only: a dot of the tag's own hue, on a neutral chip. */\n color?: Hue\n /** outline only: the quieter, superseded side, e.g. the \"from\" of a stage change. */\n muted?: boolean\n /** soft only. */\n removable?: boolean\n /** The remove button's accessible name. */\n removeLabel?: string\n /** A toggle button for quick choices, bound to `v-model:pressed`. Group several in a `role=\"group\"` with a label. */\n pressable?: boolean\n /** pressable only. */\n disabled?: boolean\n}\n\nwithDefaults(defineProps<TagProps>(), {\n name: undefined,\n variant: 'soft',\n color: undefined,\n removeLabel: 'Remove tag'\n})\n\ndefineEmits<{ remove: [] }>()\n\nconst pressed = defineModel<boolean>('pressed', { default: false })\n\nconst dots: Record<Hue, string> = {\n blue: 'bg-sui-hue-blue-ink',\n green: 'bg-sui-hue-green-ink',\n orange: 'bg-sui-hue-orange-ink',\n pink: 'bg-sui-hue-pink-ink',\n purple: 'bg-sui-hue-purple-ink',\n slate: 'bg-sui-hue-slate-ink',\n red: 'bg-sui-hue-red-ink',\n amber: 'bg-sui-hue-amber-ink',\n gray: 'bg-sui-ink'\n}\n</script>\n\n<!-- A label: soft for the ones people create, outline for a value from a fixed set; or, pressable, a toggle chip. -->\n<template>\n <button\n v-if=\"pressable\"\n :aria-pressed=\"pressed\"\n class=\"inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md border px-3 text-13 leading-none font-medium whitespace-nowrap transition-colors duration-150 outline-hidden focus-visible:sui-ring disabled:cursor-default disabled:opacity-50\"\n :class=\"\n pressed\n ? 'border-sui-accent-line bg-sui-accent-wash text-sui-accent enabled:hover:border-sui-accent-bright enabled:hover:bg-sui-accent-soft enabled:active:border-sui-accent-solid enabled:active:bg-sui-accent-soft'\n : 'border-sui-line bg-sui-surface text-sui-ink-body enabled:hover:border-sui-line-strong enabled:hover:bg-sui-canvas enabled:hover:text-sui-ink enabled:active:bg-sui-sunken'\n \"\n :disabled=\"disabled\"\n type=\"button\"\n @click=\"pressed = !pressed\"\n >\n <svg\n v-if=\"pressed\"\n aria-hidden=\"true\"\n class=\"-ml-0.5 size-3 shrink-0 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.75\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M3.5 8.25l3 3 6-6.5\" />\n </svg>\n <slot>{{ name }}</slot>\n </button>\n <span\n v-else-if=\"variant === 'outline'\"\n class=\"inline-flex items-center gap-1.5 rounded-md border px-2 py-1 text-xs whitespace-nowrap\"\n :class=\"\n muted ? 'border-sui-line-subtle text-sui-ink-muted' : 'border-sui-line bg-sui-sunken font-medium text-sui-ink'\n \"\n >\n <slot>{{ name }}</slot>\n </span>\n <div\n v-else\n class=\"inline-flex items-center gap-1.5 rounded-md bg-sui-sunken px-2 py-0.5 text-xs font-medium text-sui-ink-body\"\n >\n <span v-if=\"color\" class=\"h-1.5 w-1.5 shrink-0 rounded-full\" :class=\"dots[color]\" />\n <span class=\"truncate\"\n ><slot>{{ name }}</slot></span\n >\n <button\n v-if=\"removable\"\n :aria-label=\"removeLabel\"\n class=\"-mr-0.5 inline-flex h-3.5 w-3.5 items-center justify-center rounded-full transition-colors hover:bg-sui-line focus-visible:sui-ring\"\n type=\"button\"\n @click=\"$emit('remove')\"\n >\n <CloseSmallIcon class=\"fill-sui-ink-muted stroke-sui-ink-muted\" />\n </button>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -12,17 +12,30 @@ export interface TagProps {
|
|
|
12
12
|
removable?: boolean;
|
|
13
13
|
/** The remove button's accessible name. */
|
|
14
14
|
removeLabel?: string;
|
|
15
|
+
/** A toggle button for quick choices, bound to `v-model:pressed`. Group several in a `role="group"` with a label. */
|
|
16
|
+
pressable?: boolean;
|
|
17
|
+
/** pressable only. */
|
|
18
|
+
disabled?: boolean;
|
|
15
19
|
}
|
|
16
|
-
|
|
20
|
+
type __VLS_Props = TagProps;
|
|
21
|
+
type __VLS_ModelProps = {
|
|
22
|
+
'pressed'?: boolean;
|
|
23
|
+
};
|
|
24
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
25
|
+
declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {};
|
|
17
26
|
type __VLS_Slots = {} & {
|
|
18
27
|
default?: (props: typeof __VLS_1) => any;
|
|
19
28
|
} & {
|
|
20
29
|
default?: (props: typeof __VLS_3) => any;
|
|
30
|
+
} & {
|
|
31
|
+
default?: (props: typeof __VLS_5) => any;
|
|
21
32
|
};
|
|
22
|
-
declare const __VLS_base: import("vue").DefineComponent<
|
|
33
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
23
34
|
remove: () => any;
|
|
24
|
-
|
|
35
|
+
"update:pressed": (value: boolean) => any;
|
|
36
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
25
37
|
onRemove?: (() => any) | undefined;
|
|
38
|
+
"onUpdate:pressed"?: ((value: boolean) => any) | undefined;
|
|
26
39
|
}>, {
|
|
27
40
|
variant: "soft" | "outline";
|
|
28
41
|
name: string;
|