@sparklingopinions/sparkling-ui 0.9.2 → 0.10.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/dist/aliases.d.ts +3 -3
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Badge/Badge.vue.d.ts +6 -3
- package/dist/components/Badge/Badge.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Badge/Badge.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 +1 -1
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/package.json +1 -1
package/dist/aliases.d.ts
CHANGED
|
@@ -126,7 +126,7 @@ export type ConfirmDialogProps = AlertDialogProps;
|
|
|
126
126
|
/** @deprecated Renamed to Badge. */
|
|
127
127
|
export declare const Pill: {
|
|
128
128
|
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<Readonly<BadgeProps> & Readonly<{}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, import("vue").PublicProps, {
|
|
129
|
-
variant: "text" | "soft";
|
|
129
|
+
variant: "text" | "soft" | "outline";
|
|
130
130
|
label: string;
|
|
131
131
|
tone: BadgeTone;
|
|
132
132
|
dot: boolean;
|
|
@@ -138,7 +138,7 @@ export declare const Pill: {
|
|
|
138
138
|
M: {};
|
|
139
139
|
Defaults: {};
|
|
140
140
|
}, Readonly<BadgeProps> & Readonly<{}>, {}, {}, {}, {}, {
|
|
141
|
-
variant: "text" | "soft";
|
|
141
|
+
variant: "text" | "soft" | "outline";
|
|
142
142
|
label: string;
|
|
143
143
|
tone: BadgeTone;
|
|
144
144
|
dot: boolean;
|
|
@@ -147,7 +147,7 @@ export declare const Pill: {
|
|
|
147
147
|
__isTeleport?: never;
|
|
148
148
|
__isSuspense?: never;
|
|
149
149
|
} & import("vue").ComponentOptionsBase<Readonly<BadgeProps> & Readonly<{}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, {
|
|
150
|
-
variant: "text" | "soft";
|
|
150
|
+
variant: "text" | "soft" | "outline";
|
|
151
151
|
label: string;
|
|
152
152
|
tone: BadgeTone;
|
|
153
153
|
dot: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.js","names":["_sfc_main","Badge_vue_vue_type_script_setup_true_lang_default","Badge_default"],"sources":["../../../src/components/Badge/Badge.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nexport type BadgeTone = 'neutral' | 'accent' | 'success' | 'warning' | 'info' | 'danger'\n\nexport interface BadgeProps {\n tone?: BadgeTone\n
|
|
1
|
+
{"version":3,"file":"Badge.js","names":["_sfc_main","Badge_vue_vue_type_script_setup_true_lang_default","Badge_default"],"sources":["../../../src/components/Badge/Badge.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nexport type BadgeTone = 'neutral' | 'accent' | 'success' | 'warning' | 'info' | 'danger'\n\nexport interface BadgeProps {\n tone?: BadgeTone\n /**\n * `soft` is a tinted chip; `text` is a dot and a coloured label, lighter; `outline` is a small\n * neutral pill (the dot carries the tone) for a count that isn't the page's own.\n */\n variant?: 'soft' | 'text' | 'outline'\n dot?: boolean\n label?: string\n}\n\nconst props = withDefaults(defineProps<BadgeProps>(), { tone: 'neutral', variant: 'soft', dot: true, label: undefined })\n\nconst tones: Record<BadgeTone, { chip: string; text: string; dot: string }> = {\n neutral: { chip: 'bg-sui-sunken text-sui-ink-subtle', text: 'text-sui-ink-muted', dot: 'bg-sui-mark-faint' },\n accent: { chip: 'bg-sui-accent-wash text-sui-accent', text: 'text-sui-accent', dot: 'bg-sui-accent-solid' },\n success: {\n chip: 'bg-sui-success-soft text-sui-success',\n text: 'text-sui-success',\n dot: 'bg-sui-success-mid'\n },\n warning: {\n chip: 'bg-sui-warning-soft text-sui-warning',\n text: 'text-sui-warning',\n dot: 'bg-sui-warning-bright'\n },\n info: { chip: 'bg-sui-info-soft text-sui-info', text: 'text-sui-info', dot: 'bg-sui-info-mid' },\n danger: { chip: 'bg-sui-danger-soft text-sui-danger', text: 'text-sui-danger', dot: 'bg-sui-danger-solid' }\n}\n\nconst tone = computed(() => tones[props.tone])\n\nconst shape = computed(() => {\n if (props.variant === 'soft') return ['h-6 gap-1.5 rounded-md px-2.5 text-xs font-medium', tone.value.chip]\n if (props.variant === 'outline')\n return 'h-5 gap-1.25 rounded-full border border-sui-line bg-sui-surface pr-1.75 pl-1.5 text-11.5 leading-none font-semibold text-sui-ink-emphasis tabular-nums'\n return ['gap-1.5 text-xs font-medium', tone.value.text]\n})\n</script>\n\n<template>\n <span class=\"inline-flex items-center whitespace-nowrap\" :class=\"shape\">\n <span v-if=\"dot\" class=\"h-1.5 w-1.5 shrink-0 rounded-full\" :class=\"tone.dot\" />\n <slot>{{ label }}</slot>\n </span>\n</template>\n"],"mappings":""}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export type BadgeTone = 'neutral' | 'accent' | 'success' | 'warning' | 'info' | 'danger';
|
|
2
2
|
export interface BadgeProps {
|
|
3
3
|
tone?: BadgeTone;
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* `soft` is a tinted chip; `text` is a dot and a coloured label, lighter; `outline` is a small
|
|
6
|
+
* neutral pill (the dot carries the tone) for a count that isn't the page's own.
|
|
7
|
+
*/
|
|
8
|
+
variant?: 'soft' | 'text' | 'outline';
|
|
6
9
|
dot?: boolean;
|
|
7
10
|
label?: string;
|
|
8
11
|
}
|
|
@@ -11,7 +14,7 @@ type __VLS_Slots = {} & {
|
|
|
11
14
|
default?: (props: typeof __VLS_1) => any;
|
|
12
15
|
};
|
|
13
16
|
declare const __VLS_base: import("vue").DefineComponent<BadgeProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<BadgeProps> & Readonly<{}>, {
|
|
14
|
-
variant: "text" | "soft";
|
|
17
|
+
variant: "text" | "soft" | "outline";
|
|
15
18
|
label: string;
|
|
16
19
|
tone: BadgeTone;
|
|
17
20
|
dot: boolean;
|
|
@@ -43,8 +43,8 @@ var l = /*@__PURE__*/ i({
|
|
|
43
43
|
text: "text-sui-danger",
|
|
44
44
|
dot: "bg-sui-danger-solid"
|
|
45
45
|
}
|
|
46
|
-
}, d = e(() => u[l.tone]);
|
|
47
|
-
return (e, l) => (o(), n("span", { class: a(["inline-flex items-center
|
|
46
|
+
}, d = e(() => u[l.tone]), f = e(() => l.variant === "soft" ? ["h-6 gap-1.5 rounded-md px-2.5 text-xs font-medium", d.value.chip] : l.variant === "outline" ? "h-5 gap-1.25 rounded-full border border-sui-line bg-sui-surface pr-1.75 pl-1.5 text-11.5 leading-none font-semibold text-sui-ink-emphasis tabular-nums" : ["gap-1.5 text-xs font-medium", d.value.text]);
|
|
47
|
+
return (e, l) => (o(), n("span", { class: a(["inline-flex items-center whitespace-nowrap", f.value]) }, [i.dot ? (o(), n("span", {
|
|
48
48
|
key: 0,
|
|
49
49
|
class: a(["h-1.5 w-1.5 shrink-0 rounded-full", d.value.dot])
|
|
50
50
|
}, null, 2)) : t("", !0), s(e.$slots, "default", {}, () => [r(c(i.label), 1)])], 2));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_createCommentVNode","_renderSlot","_createTextVNode","_toDisplayString","Badge_vue_vue_type_script_setup_true_lang_default","props","__props","tones","tone","computed","openBlock","createElementBlock","normalizeClass","createCommentVNode","renderSlot","_ctx","createTextVNode","toDisplayString"],"sources":["../../../src/components/Badge/Badge.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nexport type BadgeTone = 'neutral' | 'accent' | 'success' | 'warning' | 'info' | 'danger'\n\nexport interface BadgeProps {\n tone?: BadgeTone\n
|
|
1
|
+
{"version":3,"file":"Badge.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_createCommentVNode","_renderSlot","_createTextVNode","_toDisplayString","Badge_vue_vue_type_script_setup_true_lang_default","props","__props","tones","tone","computed","shape","openBlock","createElementBlock","normalizeClass","createCommentVNode","renderSlot","_ctx","createTextVNode","toDisplayString"],"sources":["../../../src/components/Badge/Badge.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nexport type BadgeTone = 'neutral' | 'accent' | 'success' | 'warning' | 'info' | 'danger'\n\nexport interface BadgeProps {\n tone?: BadgeTone\n /**\n * `soft` is a tinted chip; `text` is a dot and a coloured label, lighter; `outline` is a small\n * neutral pill (the dot carries the tone) for a count that isn't the page's own.\n */\n variant?: 'soft' | 'text' | 'outline'\n dot?: boolean\n label?: string\n}\n\nconst props = withDefaults(defineProps<BadgeProps>(), { tone: 'neutral', variant: 'soft', dot: true, label: undefined })\n\nconst tones: Record<BadgeTone, { chip: string; text: string; dot: string }> = {\n neutral: { chip: 'bg-sui-sunken text-sui-ink-subtle', text: 'text-sui-ink-muted', dot: 'bg-sui-mark-faint' },\n accent: { chip: 'bg-sui-accent-wash text-sui-accent', text: 'text-sui-accent', dot: 'bg-sui-accent-solid' },\n success: {\n chip: 'bg-sui-success-soft text-sui-success',\n text: 'text-sui-success',\n dot: 'bg-sui-success-mid'\n },\n warning: {\n chip: 'bg-sui-warning-soft text-sui-warning',\n text: 'text-sui-warning',\n dot: 'bg-sui-warning-bright'\n },\n info: { chip: 'bg-sui-info-soft text-sui-info', text: 'text-sui-info', dot: 'bg-sui-info-mid' },\n danger: { chip: 'bg-sui-danger-soft text-sui-danger', text: 'text-sui-danger', dot: 'bg-sui-danger-solid' }\n}\n\nconst tone = computed(() => tones[props.tone])\n\nconst shape = computed(() => {\n if (props.variant === 'soft') return ['h-6 gap-1.5 rounded-md px-2.5 text-xs font-medium', tone.value.chip]\n if (props.variant === 'outline')\n return 'h-5 gap-1.25 rounded-full border border-sui-line bg-sui-surface pr-1.75 pl-1.5 text-11.5 leading-none font-semibold text-sui-ink-emphasis tabular-nums'\n return ['gap-1.5 text-xs font-medium', tone.value.text]\n})\n</script>\n\n<template>\n <span class=\"inline-flex items-center whitespace-nowrap\" :class=\"shape\">\n <span v-if=\"dot\" class=\"h-1.5 w-1.5 shrink-0 rounded-full\" :class=\"tone.dot\" />\n <slot>{{ label }}</slot>\n </span>\n</template>\n"],"mappings":";;;;;;;;;;;;;;EAgBA,IAAMQ,IAAQC,GAERC,IAAwE;GAC5E,SAAS;IAAE,MAAM;IAAqC,MAAM;IAAsB,KAAK;GAAoB;GAC3G,QAAQ;IAAE,MAAM;IAAsC,MAAM;IAAmB,KAAK;GAAsB;GAC1G,SAAS;IACP,MAAM;IACN,MAAM;IACN,KAAK;GACP;GACA,SAAS;IACP,MAAM;IACN,MAAM;IACN,KAAK;GACP;GACA,MAAM;IAAE,MAAM;IAAkC,MAAM;IAAiB,KAAK;GAAkB;GAC9F,QAAQ;IAAE,MAAM;IAAsC,MAAM;IAAmB,KAAK;GAAsB;EAC5G,GAEMC,IAAOC,QAAeF,EAAMF,EAAM,KAAK,GAEvCK,IAAQD,QACRJ,EAAM,YAAY,SAAe,CAAC,qDAAqDG,EAAK,MAAM,IAAI,IACtGH,EAAM,YAAY,YACb,2JACF,CAAC,+BAA+BG,EAAK,MAAM,IAAI,CACvD;E,kBAICX,EAAA,GAAAC,EAGO,QAAA,EAHD,OAAKC,EAAA,CAAC,8CAAqDW,EAAA,KAAK,CAAA,E,IACxDJ,EAAA,OAAZT,EAAA,GAAAC,EAA+E,QAAA;;GAA9D,OAAKC,EAAA,CAAC,qCAA4CS,EAAA,MAAK,GAAG,CAAA;E,0BAC3EP,EAAwBe,EAAA,QAAA,WAAA,CAAA,SAAA,CAAfd,EAAAC,EAAAG,EAAA,KAAK,GAAA,CAAA,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.js","names":["_sfc_main","Table_vue_vue_type_script_setup_true_lang_default","Table_default"],"sources":["../../../src/components/Table/Table.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { TableColumn, TableSort } from './types'\n\nexport interface TableProps<T> {\n columns: TableColumn[]\n rows: T[]\n /** The row field that identifies it. */\n rowKey?: keyof T & string\n /** A checkbox column bound to `v-model:selected`; selected rows tint accent-wash. */\n selectable?: boolean\n /** Skeleton rows in place of the body. */\n loading?: boolean\n loadingRows?: number\n /** md: 57px rows. sm: 40px, for dense lists. */\n size?: 'md' | 'sm'\n /** A row height in px between the sizes, such as 44, for body and header rows; sets `--sui-table-row`. */\n rowHeight?: number\n /** The header row's height in px, e.g. 36 over 44px rows; sets `--sui-table-header`. Defaults to the row height. */\n headerHeight?: number\n /** canvas lays the header on the page colour, for a table directly on the canvas. */\n headerTone?: 'sunken' | 'canvas'\n /** The table's name for screen readers. */\n caption?: string\n selectAllLabel?: string\n selectRowLabel?: string\n /** Makes rows clickable (`@row-click`), e.g. to open the record. */\n onRowClick?: (row: T) => void\n}\n\nconst props = withDefaults(defineProps<TableProps<T>>(), {\n rowKey: 'id' as never,\n loadingRows: 5,\n size: 'md',\n rowHeight: undefined,\n headerHeight: undefined,\n headerTone: 'sunken',\n caption: undefined,\n selectAllLabel: 'Select all rows',\n selectRowLabel: 'Select row',\n onRowClick: undefined\n})\n\nconst sort = defineModel<TableSort | null>('sort', { default: null })\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\n\nconst slots = defineSlots<\n {\n /** Shown in place of the body when there are no rows, e.g. an EmptyState. */\n empty?: () => unknown\n /** Replaces the body when given, e.g. an inset danger Alert with a retry. */\n error?: () => unknown\n /** A canvas strip under the rows: a rows-per-page Select, the range, Pagination. */\n footer?: () => unknown\n } & {\n [K in `cell-${string}`]?: (props: { row: T; value: unknown }) => unknown\n }\n>()\n\nconst idOf = (row: T): unknown => row[props.rowKey ?? 'id']\nconst ids = computed(() => props.rows.map(idOf))\nconst allSelected = computed(() => ids.value.length > 0 && ids.value.every((id) => selected.value.includes(id)))\nconst someSelected = computed(() => !allSelected.value && ids.value.some((id) => selected.value.includes(id)))\n\nfunction toggleAll() {\n selected.value = allSelected.value\n ? selected.value.filter((id) => !ids.value.includes(id))\n : [...new Set([...selected.value, ...ids.value])]\n}\n\nfunction toggle(id: unknown) {\n selected.value = selected.value.includes(id) ? selected.value.filter((x) => x !== id) : [...selected.value, id]\n}\n\n// Sorting a column cycles ascending, descending, unsorted.\nfunction sortBy(key: string) {\n const dir = sort.value?.key === key ? sort.value.dir : null\n const next = dir === null ? 'asc' : dir === 'asc' ? 'desc' : null\n sort.value = next ? { key, dir: next } : null\n}\n\nfunction dirOf(key: string) {\n return sort.value?.key === key ? sort.value.dir : null\n}\n\nfunction ariaSort(column: TableColumn) {\n const dir = dirOf(column.key)\n if (dir) return dir === 'asc' ? 'ascending' : 'descending'\n return column.sortable ? 'none' : undefined\n}\n\nconst state = computed(() => {\n if (slots.error) return 'error'\n if (props.loading) return 'loading'\n return props.rows.length === 0 && slots.empty ? 'empty' : 'rows'\n})\n\nconst columnCount = computed(() => props.columns.length + (props.selectable ? 1 : 0))\nconst alignClass = { left: 'text-left', center: 'text-center', right: 'text-right' }\nconst skeletonWidths = ['60%', '45%', '70%', '35%', '55%']\n\nconst sm = computed(() => props.size === 'sm')\nconst fixed = computed(() => props.rowHeight !== undefined)\nconst rowStyle = computed(() => {\n const style: Record<string, string> = {}\n if (fixed.value) style['--sui-table-row'] = `${props.rowHeight}px`\n if (props.headerHeight !== undefined) style['--sui-table-header'] = `${props.headerHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value\n ? 'h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]'\n : 'h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]'\n])\nconst td = computed(() => [\n 'border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-[var(--sui-table-row,2.5rem)]' : 'h-[var(--sui-table-row,3.5625rem)]'\n])\n// A set row height takes the cells' vertical padding with it.\nconst pad = computed(() => [sm.value ? 'px-3' : 'px-4', !fixed.value && (sm.value ? 'py-1.5' : 'py-3')])\nconst headTone = computed(() => (props.headerTone === 'canvas' ? 'bg-sui-canvas' : 'bg-sui-sunken'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div\n class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\"\n :style=\"rowStyle\"\n >\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-[var(--sui-table-min,720px)] table-fixed border-collapse\">\n <caption v-if=\"caption\" class=\"sr-only\">\n {{\n caption\n }}\n </caption>\n <colgroup>\n <col v-if=\"selectable\" class=\"w-12\" />\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :style=\"{ width: typeof column.width === 'number' ? `${column.width}px` : column.width }\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-if=\"selectable\" :class=\"[th, checkCell, headTone]\">\n <Checkbox\n :aria-label=\"selectAllLabel\"\n :disabled=\"loading || rows.length === 0\"\n :indeterminate=\"someSelected\"\n :model-value=\"allSelected\"\n @update:model-value=\"toggleAll\"\n />\n </th>\n <component\n :is=\"column.label ? 'th' : 'td'\"\n v-for=\"column in columns\"\n :key=\"column.key\"\n :aria-sort=\"ariaSort(column)\"\n :class=\"[\n th,\n headPad,\n alignClass[column.align ?? 'left'],\n dirOf(column.key) ? 'bg-sui-accent-wash text-sui-accent' : [headTone, 'text-sui-ink-subtle']\n ]\"\n :scope=\"column.label ? 'col' : undefined\"\n >\n <button\n v-if=\"column.sortable\"\n class=\"inline-flex h-full w-full items-center gap-1.5 rounded-md outline-hidden focus-visible:sui-ring-inset\"\n :class=\"[\n column.align === 'right' && 'justify-end',\n column.align === 'center' && 'justify-center',\n !dirOf(column.key) && 'hover:text-sui-ink'\n ]\"\n type=\"button\"\n @click=\"sortBy(column.key)\"\n >\n {{ column.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3 shrink-0 fill-none stroke-current\"\n :class=\"!dirOf(column.key) && 'opacity-50'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path v-if=\"dirOf(column.key) === 'asc'\" d=\"M3 7.5 6 4.5l3 3\" />\n <path v-else-if=\"dirOf(column.key) === 'desc'\" d=\"M3 4.5 6 7.5l3-3\" />\n <path v-else d=\"M3.5 4.5 6 2l2.5 2.5M3.5 7.5 6 10l2.5-2.5\" />\n </svg>\n </button>\n <template v-else>{{ column.label }}</template>\n </component>\n </tr>\n </thead>\n <tbody :aria-busy=\"loading || undefined\">\n <tr v-if=\"state === 'error' || state === 'empty'\">\n <td class=\"p-0\" :colspan=\"columnCount\">\n <slot :name=\"state\" />\n </td>\n </tr>\n <template v-else-if=\"state === 'loading'\">\n <tr v-for=\"i in loadingRows\" :key=\"i\" aria-hidden=\"true\" class=\"group/row\">\n <td v-if=\"selectable\" :class=\"[td, checkCell]\"><Skeleton size=\"1rem\" /></td>\n <td v-for=\"(column, j) in columns\" :key=\"column.key\" :class=\"[td, pad]\">\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(i + j) % 5]\" />\n </td>\n </tr>\n </template>\n <template v-else>\n <tr\n v-for=\"row in rows\"\n :key=\"idOf(row) as PropertyKey\"\n :aria-selected=\"selectable ? selected.includes(idOf(row)) : undefined\"\n class=\"group/row transition-colors duration-150\"\n :class=\"[\n selected.includes(idOf(row)) ? 'bg-sui-accent-wash' : 'hover:bg-sui-sunken',\n onRowClick && 'cursor-pointer'\n ]\"\n @click=\"onRowClick?.(row)\"\n >\n <td v-if=\"selectable\" :class=\"[td, checkCell]\" @click.stop>\n <Checkbox\n :aria-label=\"selectRowLabel\"\n :model-value=\"selected.includes(idOf(row))\"\n @update:model-value=\"toggle(idOf(row))\"\n />\n </td>\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n td,\n pad,\n alignClass[column.align ?? 'left'],\n column.wrap ? 'break-words whitespace-normal' : 'truncate'\n ]\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\" :value=\"row[column.key]\">\n <template v-if=\"row[column.key] != null && row[column.key] !== ''\">{{ row[column.key] }}</template>\n <span v-else class=\"text-sui-ink-muted\">–</span>\n </slot>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"$slots.footer\"\n class=\"flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle bg-sui-canvas py-2 pr-3 pl-4 text-13 text-sui-ink-muted\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Table.js","names":["_sfc_main","Table_vue_vue_type_script_setup_true_lang_default","Table_default"],"sources":["../../../src/components/Table/Table.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { TableColumn, TableSort } from './types'\n\nexport interface TableProps<T> {\n columns: TableColumn[]\n rows: T[]\n /** The row field that identifies it. */\n rowKey?: keyof T & string\n /** A checkbox column bound to `v-model:selected`; selected rows tint accent-wash. */\n selectable?: boolean\n /** Skeleton rows in place of the body. */\n loading?: boolean\n loadingRows?: number\n /** md: 57px rows. sm: 40px, for dense lists. */\n size?: 'md' | 'sm'\n /** A row height in px between the sizes, such as 44, for body and header rows; sets `--sui-table-row`. */\n rowHeight?: number\n /** The header row's height in px, e.g. 36 over 44px rows; sets `--sui-table-header`. Defaults to the row height. */\n headerHeight?: number\n /** canvas lays the header on the page colour, for a table directly on the canvas. */\n headerTone?: 'sunken' | 'canvas'\n /** The table's name for screen readers. */\n caption?: string\n selectAllLabel?: string\n selectRowLabel?: string\n /** Makes rows clickable (`@row-click`), e.g. to open the record. */\n onRowClick?: (row: T) => void\n}\n\nconst props = withDefaults(defineProps<TableProps<T>>(), {\n rowKey: 'id' as never,\n loadingRows: 5,\n size: 'md',\n rowHeight: undefined,\n headerHeight: undefined,\n headerTone: 'sunken',\n caption: undefined,\n selectAllLabel: 'Select all rows',\n selectRowLabel: 'Select row',\n onRowClick: undefined\n})\n\nconst sort = defineModel<TableSort | null>('sort', { default: null })\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\n\nconst slots = defineSlots<\n {\n /** Shown in place of the body when there are no rows, e.g. an EmptyState. */\n empty?: () => unknown\n /** Replaces the body when given, e.g. an inset danger Alert with a retry. */\n error?: () => unknown\n /** A canvas strip under the rows: a rows-per-page Select, the range, Pagination. */\n footer?: () => unknown\n } & {\n [K in `cell-${string}`]?: (props: { row: T; value: unknown }) => unknown\n }\n>()\n\nconst idOf = (row: T): unknown => row[props.rowKey ?? 'id']\nconst ids = computed(() => props.rows.map(idOf))\nconst allSelected = computed(() => ids.value.length > 0 && ids.value.every((id) => selected.value.includes(id)))\nconst someSelected = computed(() => !allSelected.value && ids.value.some((id) => selected.value.includes(id)))\n\nfunction toggleAll() {\n selected.value = allSelected.value\n ? selected.value.filter((id) => !ids.value.includes(id))\n : [...new Set([...selected.value, ...ids.value])]\n}\n\nfunction toggle(id: unknown) {\n selected.value = selected.value.includes(id) ? selected.value.filter((x) => x !== id) : [...selected.value, id]\n}\n\n// Sorting a column cycles ascending, descending, unsorted.\nfunction sortBy(key: string) {\n const dir = sort.value?.key === key ? sort.value.dir : null\n const next = dir === null ? 'asc' : dir === 'asc' ? 'desc' : null\n sort.value = next ? { key, dir: next } : null\n}\n\nfunction dirOf(key: string) {\n return sort.value?.key === key ? sort.value.dir : null\n}\n\nfunction ariaSort(column: TableColumn) {\n const dir = dirOf(column.key)\n if (dir) return dir === 'asc' ? 'ascending' : 'descending'\n return column.sortable ? 'none' : undefined\n}\n\nconst state = computed(() => {\n if (slots.error) return 'error'\n if (props.loading) return 'loading'\n return props.rows.length === 0 && slots.empty ? 'empty' : 'rows'\n})\n\nconst columnCount = computed(() => props.columns.length + (props.selectable ? 1 : 0))\nconst alignClass = { left: 'text-left', center: 'text-center', right: 'text-right' }\nconst skeletonWidths = ['60%', '45%', '70%', '35%', '55%']\n\nconst sm = computed(() => props.size === 'sm')\nconst fixed = computed(() => props.rowHeight !== undefined)\nconst rowStyle = computed(() => {\n const style: Record<string, string> = {}\n if (fixed.value) style['--sui-table-row'] = `${props.rowHeight}px`\n if (props.headerHeight !== undefined) style['--sui-table-header'] = `${props.headerHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value\n ? 'h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]'\n : 'h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]'\n])\nconst td = computed(() => [\n 'border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-[var(--sui-table-row,2.5rem)]' : 'h-[var(--sui-table-row,3.5625rem)]'\n])\n// A set row height takes the cells' vertical padding with it.\nconst pad = computed(() => [sm.value ? 'px-3' : 'px-4', !fixed.value && (sm.value ? 'py-1.5' : 'py-3')])\nconst headTone = computed(() => (props.headerTone === 'canvas' ? 'bg-sui-canvas' : 'bg-sui-sunken'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4 text-left'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div\n class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\"\n :style=\"rowStyle\"\n >\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-[var(--sui-table-min,720px)] table-fixed border-collapse\">\n <caption v-if=\"caption\" class=\"sr-only\">\n {{\n caption\n }}\n </caption>\n <colgroup>\n <col v-if=\"selectable\" class=\"w-12\" />\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :style=\"{ width: typeof column.width === 'number' ? `${column.width}px` : column.width }\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-if=\"selectable\" :class=\"[th, checkCell, headTone]\">\n <Checkbox\n :aria-label=\"selectAllLabel\"\n :disabled=\"loading || rows.length === 0\"\n :indeterminate=\"someSelected\"\n :model-value=\"allSelected\"\n @update:model-value=\"toggleAll\"\n />\n </th>\n <component\n :is=\"column.label ? 'th' : 'td'\"\n v-for=\"column in columns\"\n :key=\"column.key\"\n :aria-sort=\"ariaSort(column)\"\n :class=\"[\n th,\n headPad,\n alignClass[column.align ?? 'left'],\n dirOf(column.key) ? 'bg-sui-accent-wash text-sui-accent' : [headTone, 'text-sui-ink-subtle']\n ]\"\n :scope=\"column.label ? 'col' : undefined\"\n >\n <button\n v-if=\"column.sortable\"\n class=\"inline-flex h-full w-full items-center gap-1.5 rounded-md outline-hidden focus-visible:sui-ring-inset\"\n :class=\"[\n column.align === 'right' && 'justify-end',\n column.align === 'center' && 'justify-center',\n !dirOf(column.key) && 'hover:text-sui-ink'\n ]\"\n type=\"button\"\n @click=\"sortBy(column.key)\"\n >\n {{ column.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3 shrink-0 fill-none stroke-current\"\n :class=\"!dirOf(column.key) && 'opacity-50'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path v-if=\"dirOf(column.key) === 'asc'\" d=\"M3 7.5 6 4.5l3 3\" />\n <path v-else-if=\"dirOf(column.key) === 'desc'\" d=\"M3 4.5 6 7.5l3-3\" />\n <path v-else d=\"M3.5 4.5 6 2l2.5 2.5M3.5 7.5 6 10l2.5-2.5\" />\n </svg>\n </button>\n <template v-else>{{ column.label }}</template>\n </component>\n </tr>\n </thead>\n <tbody :aria-busy=\"loading || undefined\">\n <tr v-if=\"state === 'error' || state === 'empty'\">\n <td class=\"p-0\" :colspan=\"columnCount\">\n <slot :name=\"state\" />\n </td>\n </tr>\n <template v-else-if=\"state === 'loading'\">\n <tr v-for=\"i in loadingRows\" :key=\"i\" aria-hidden=\"true\" class=\"group/row\">\n <td v-if=\"selectable\" :class=\"[td, checkCell]\"><Skeleton size=\"1rem\" /></td>\n <td v-for=\"(column, j) in columns\" :key=\"column.key\" :class=\"[td, pad]\">\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(i + j) % 5]\" />\n </td>\n </tr>\n </template>\n <template v-else>\n <tr\n v-for=\"row in rows\"\n :key=\"idOf(row) as PropertyKey\"\n :aria-selected=\"selectable ? selected.includes(idOf(row)) : undefined\"\n class=\"group/row transition-colors duration-150\"\n :class=\"[\n selected.includes(idOf(row)) ? 'bg-sui-accent-wash' : 'hover:bg-sui-sunken',\n onRowClick && 'cursor-pointer'\n ]\"\n @click=\"onRowClick?.(row)\"\n >\n <td v-if=\"selectable\" :class=\"[td, checkCell]\" @click.stop>\n <Checkbox\n :aria-label=\"selectRowLabel\"\n :model-value=\"selected.includes(idOf(row))\"\n @update:model-value=\"toggle(idOf(row))\"\n />\n </td>\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n td,\n pad,\n alignClass[column.align ?? 'left'],\n column.wrap ? 'break-words whitespace-normal' : 'truncate'\n ]\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\" :value=\"row[column.key]\">\n <template v-if=\"row[column.key] != null && row[column.key] !== ''\">{{ row[column.key] }}</template>\n <span v-else class=\"text-sui-ink-muted\">–</span>\n </slot>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"$slots.footer\"\n class=\"flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle bg-sui-canvas py-2 pr-3 pl-4 text-13 text-sui-ink-muted\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -23,7 +23,7 @@ var C = { class: "overflow-x-auto" }, w = { class: "w-full min-w-[var(--sui-tabl
|
|
|
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
|
-
}, j = "w-12 pl-4", M = /*@__PURE__*/ u({
|
|
26
|
+
}, j = "w-12 pl-4 text-left", M = /*@__PURE__*/ u({
|
|
27
27
|
__name: "Table",
|
|
28
28
|
props: /*@__PURE__*/ d({
|
|
29
29
|
columns: {},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","_useSlots","_openBlock","_createElementBlock","_normalizeStyle","_createElementVNode","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_normalizeClass","_createVNode","Checkbox","_createBlock","_resolveDynamicComponent","_withCtx","_createTextVNode","_renderSlot","Skeleton","_withModifiers","Skeleton_default","Checkbox_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","checkCell","Table_vue_vue_type_script_setup_true_lang_default","\"sort\"","\"sortModifiers\"","\"selected\"","\"selectedModifiers\"","props","__props","sort","useModel","selected","slots","useSlots","idOf","row","ids","computed","allSelected","id","someSelected","toggleAll","toggle","x","sortBy","dir","key","next","dirOf","ariaSort","column","state","columnCount","alignClass","skeletonWidths","sm","fixed","rowStyle","style","th","td","pad","headTone","headPad","openBlock","createElementBlock","normalizeStyle","createElementVNode","toDisplayString","createCommentVNode","Fragment","renderList","normalizeClass","createVNode","createBlock","resolveDynamicComponent","withCtx","createTextVNode","renderSlot","_ctx","i","j","_cache","withModifiers"],"sources":["../../../src/components/Table/Table.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { TableColumn, TableSort } from './types'\n\nexport interface TableProps<T> {\n columns: TableColumn[]\n rows: T[]\n /** The row field that identifies it. */\n rowKey?: keyof T & string\n /** A checkbox column bound to `v-model:selected`; selected rows tint accent-wash. */\n selectable?: boolean\n /** Skeleton rows in place of the body. */\n loading?: boolean\n loadingRows?: number\n /** md: 57px rows. sm: 40px, for dense lists. */\n size?: 'md' | 'sm'\n /** A row height in px between the sizes, such as 44, for body and header rows; sets `--sui-table-row`. */\n rowHeight?: number\n /** The header row's height in px, e.g. 36 over 44px rows; sets `--sui-table-header`. Defaults to the row height. */\n headerHeight?: number\n /** canvas lays the header on the page colour, for a table directly on the canvas. */\n headerTone?: 'sunken' | 'canvas'\n /** The table's name for screen readers. */\n caption?: string\n selectAllLabel?: string\n selectRowLabel?: string\n /** Makes rows clickable (`@row-click`), e.g. to open the record. */\n onRowClick?: (row: T) => void\n}\n\nconst props = withDefaults(defineProps<TableProps<T>>(), {\n rowKey: 'id' as never,\n loadingRows: 5,\n size: 'md',\n rowHeight: undefined,\n headerHeight: undefined,\n headerTone: 'sunken',\n caption: undefined,\n selectAllLabel: 'Select all rows',\n selectRowLabel: 'Select row',\n onRowClick: undefined\n})\n\nconst sort = defineModel<TableSort | null>('sort', { default: null })\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\n\nconst slots = defineSlots<\n {\n /** Shown in place of the body when there are no rows, e.g. an EmptyState. */\n empty?: () => unknown\n /** Replaces the body when given, e.g. an inset danger Alert with a retry. */\n error?: () => unknown\n /** A canvas strip under the rows: a rows-per-page Select, the range, Pagination. */\n footer?: () => unknown\n } & {\n [K in `cell-${string}`]?: (props: { row: T; value: unknown }) => unknown\n }\n>()\n\nconst idOf = (row: T): unknown => row[props.rowKey ?? 'id']\nconst ids = computed(() => props.rows.map(idOf))\nconst allSelected = computed(() => ids.value.length > 0 && ids.value.every((id) => selected.value.includes(id)))\nconst someSelected = computed(() => !allSelected.value && ids.value.some((id) => selected.value.includes(id)))\n\nfunction toggleAll() {\n selected.value = allSelected.value\n ? selected.value.filter((id) => !ids.value.includes(id))\n : [...new Set([...selected.value, ...ids.value])]\n}\n\nfunction toggle(id: unknown) {\n selected.value = selected.value.includes(id) ? selected.value.filter((x) => x !== id) : [...selected.value, id]\n}\n\n// Sorting a column cycles ascending, descending, unsorted.\nfunction sortBy(key: string) {\n const dir = sort.value?.key === key ? sort.value.dir : null\n const next = dir === null ? 'asc' : dir === 'asc' ? 'desc' : null\n sort.value = next ? { key, dir: next } : null\n}\n\nfunction dirOf(key: string) {\n return sort.value?.key === key ? sort.value.dir : null\n}\n\nfunction ariaSort(column: TableColumn) {\n const dir = dirOf(column.key)\n if (dir) return dir === 'asc' ? 'ascending' : 'descending'\n return column.sortable ? 'none' : undefined\n}\n\nconst state = computed(() => {\n if (slots.error) return 'error'\n if (props.loading) return 'loading'\n return props.rows.length === 0 && slots.empty ? 'empty' : 'rows'\n})\n\nconst columnCount = computed(() => props.columns.length + (props.selectable ? 1 : 0))\nconst alignClass = { left: 'text-left', center: 'text-center', right: 'text-right' }\nconst skeletonWidths = ['60%', '45%', '70%', '35%', '55%']\n\nconst sm = computed(() => props.size === 'sm')\nconst fixed = computed(() => props.rowHeight !== undefined)\nconst rowStyle = computed(() => {\n const style: Record<string, string> = {}\n if (fixed.value) style['--sui-table-row'] = `${props.rowHeight}px`\n if (props.headerHeight !== undefined) style['--sui-table-header'] = `${props.headerHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value\n ? 'h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]'\n : 'h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]'\n])\nconst td = computed(() => [\n 'border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-[var(--sui-table-row,2.5rem)]' : 'h-[var(--sui-table-row,3.5625rem)]'\n])\n// A set row height takes the cells' vertical padding with it.\nconst pad = computed(() => [sm.value ? 'px-3' : 'px-4', !fixed.value && (sm.value ? 'py-1.5' : 'py-3')])\nconst headTone = computed(() => (props.headerTone === 'canvas' ? 'bg-sui-canvas' : 'bg-sui-sunken'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div\n class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\"\n :style=\"rowStyle\"\n >\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-[var(--sui-table-min,720px)] table-fixed border-collapse\">\n <caption v-if=\"caption\" class=\"sr-only\">\n {{\n caption\n }}\n </caption>\n <colgroup>\n <col v-if=\"selectable\" class=\"w-12\" />\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :style=\"{ width: typeof column.width === 'number' ? `${column.width}px` : column.width }\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-if=\"selectable\" :class=\"[th, checkCell, headTone]\">\n <Checkbox\n :aria-label=\"selectAllLabel\"\n :disabled=\"loading || rows.length === 0\"\n :indeterminate=\"someSelected\"\n :model-value=\"allSelected\"\n @update:model-value=\"toggleAll\"\n />\n </th>\n <component\n :is=\"column.label ? 'th' : 'td'\"\n v-for=\"column in columns\"\n :key=\"column.key\"\n :aria-sort=\"ariaSort(column)\"\n :class=\"[\n th,\n headPad,\n alignClass[column.align ?? 'left'],\n dirOf(column.key) ? 'bg-sui-accent-wash text-sui-accent' : [headTone, 'text-sui-ink-subtle']\n ]\"\n :scope=\"column.label ? 'col' : undefined\"\n >\n <button\n v-if=\"column.sortable\"\n class=\"inline-flex h-full w-full items-center gap-1.5 rounded-md outline-hidden focus-visible:sui-ring-inset\"\n :class=\"[\n column.align === 'right' && 'justify-end',\n column.align === 'center' && 'justify-center',\n !dirOf(column.key) && 'hover:text-sui-ink'\n ]\"\n type=\"button\"\n @click=\"sortBy(column.key)\"\n >\n {{ column.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3 shrink-0 fill-none stroke-current\"\n :class=\"!dirOf(column.key) && 'opacity-50'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path v-if=\"dirOf(column.key) === 'asc'\" d=\"M3 7.5 6 4.5l3 3\" />\n <path v-else-if=\"dirOf(column.key) === 'desc'\" d=\"M3 4.5 6 7.5l3-3\" />\n <path v-else d=\"M3.5 4.5 6 2l2.5 2.5M3.5 7.5 6 10l2.5-2.5\" />\n </svg>\n </button>\n <template v-else>{{ column.label }}</template>\n </component>\n </tr>\n </thead>\n <tbody :aria-busy=\"loading || undefined\">\n <tr v-if=\"state === 'error' || state === 'empty'\">\n <td class=\"p-0\" :colspan=\"columnCount\">\n <slot :name=\"state\" />\n </td>\n </tr>\n <template v-else-if=\"state === 'loading'\">\n <tr v-for=\"i in loadingRows\" :key=\"i\" aria-hidden=\"true\" class=\"group/row\">\n <td v-if=\"selectable\" :class=\"[td, checkCell]\"><Skeleton size=\"1rem\" /></td>\n <td v-for=\"(column, j) in columns\" :key=\"column.key\" :class=\"[td, pad]\">\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(i + j) % 5]\" />\n </td>\n </tr>\n </template>\n <template v-else>\n <tr\n v-for=\"row in rows\"\n :key=\"idOf(row) as PropertyKey\"\n :aria-selected=\"selectable ? selected.includes(idOf(row)) : undefined\"\n class=\"group/row transition-colors duration-150\"\n :class=\"[\n selected.includes(idOf(row)) ? 'bg-sui-accent-wash' : 'hover:bg-sui-sunken',\n onRowClick && 'cursor-pointer'\n ]\"\n @click=\"onRowClick?.(row)\"\n >\n <td v-if=\"selectable\" :class=\"[td, checkCell]\" @click.stop>\n <Checkbox\n :aria-label=\"selectRowLabel\"\n :model-value=\"selected.includes(idOf(row))\"\n @update:model-value=\"toggle(idOf(row))\"\n />\n </td>\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n td,\n pad,\n alignClass[column.align ?? 'left'],\n column.wrap ? 'break-words whitespace-normal' : 'truncate'\n ]\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\" :value=\"row[column.key]\">\n <template v-if=\"row[column.key] != null && row[column.key] !== ''\">{{ row[column.key] }}</template>\n <span v-else class=\"text-sui-ink-muted\">–</span>\n </slot>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"$slots.footer\"\n class=\"flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle bg-sui-canvas py-2 pr-3 pl-4 text-13 text-sui-ink-muted\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Table.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","_useSlots","_openBlock","_createElementBlock","_normalizeStyle","_createElementVNode","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_normalizeClass","_createVNode","Checkbox","_createBlock","_resolveDynamicComponent","_withCtx","_createTextVNode","_renderSlot","Skeleton","_withModifiers","Skeleton_default","Checkbox_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","checkCell","Table_vue_vue_type_script_setup_true_lang_default","\"sort\"","\"sortModifiers\"","\"selected\"","\"selectedModifiers\"","props","__props","sort","useModel","selected","slots","useSlots","idOf","row","ids","computed","allSelected","id","someSelected","toggleAll","toggle","x","sortBy","dir","key","next","dirOf","ariaSort","column","state","columnCount","alignClass","skeletonWidths","sm","fixed","rowStyle","style","th","td","pad","headTone","headPad","openBlock","createElementBlock","normalizeStyle","createElementVNode","toDisplayString","createCommentVNode","Fragment","renderList","normalizeClass","createVNode","createBlock","resolveDynamicComponent","withCtx","createTextVNode","renderSlot","_ctx","i","j","_cache","withModifiers"],"sources":["../../../src/components/Table/Table.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { computed } from 'vue'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { TableColumn, TableSort } from './types'\n\nexport interface TableProps<T> {\n columns: TableColumn[]\n rows: T[]\n /** The row field that identifies it. */\n rowKey?: keyof T & string\n /** A checkbox column bound to `v-model:selected`; selected rows tint accent-wash. */\n selectable?: boolean\n /** Skeleton rows in place of the body. */\n loading?: boolean\n loadingRows?: number\n /** md: 57px rows. sm: 40px, for dense lists. */\n size?: 'md' | 'sm'\n /** A row height in px between the sizes, such as 44, for body and header rows; sets `--sui-table-row`. */\n rowHeight?: number\n /** The header row's height in px, e.g. 36 over 44px rows; sets `--sui-table-header`. Defaults to the row height. */\n headerHeight?: number\n /** canvas lays the header on the page colour, for a table directly on the canvas. */\n headerTone?: 'sunken' | 'canvas'\n /** The table's name for screen readers. */\n caption?: string\n selectAllLabel?: string\n selectRowLabel?: string\n /** Makes rows clickable (`@row-click`), e.g. to open the record. */\n onRowClick?: (row: T) => void\n}\n\nconst props = withDefaults(defineProps<TableProps<T>>(), {\n rowKey: 'id' as never,\n loadingRows: 5,\n size: 'md',\n rowHeight: undefined,\n headerHeight: undefined,\n headerTone: 'sunken',\n caption: undefined,\n selectAllLabel: 'Select all rows',\n selectRowLabel: 'Select row',\n onRowClick: undefined\n})\n\nconst sort = defineModel<TableSort | null>('sort', { default: null })\nconst selected = defineModel<unknown[]>('selected', { default: () => [] })\n\nconst slots = defineSlots<\n {\n /** Shown in place of the body when there are no rows, e.g. an EmptyState. */\n empty?: () => unknown\n /** Replaces the body when given, e.g. an inset danger Alert with a retry. */\n error?: () => unknown\n /** A canvas strip under the rows: a rows-per-page Select, the range, Pagination. */\n footer?: () => unknown\n } & {\n [K in `cell-${string}`]?: (props: { row: T; value: unknown }) => unknown\n }\n>()\n\nconst idOf = (row: T): unknown => row[props.rowKey ?? 'id']\nconst ids = computed(() => props.rows.map(idOf))\nconst allSelected = computed(() => ids.value.length > 0 && ids.value.every((id) => selected.value.includes(id)))\nconst someSelected = computed(() => !allSelected.value && ids.value.some((id) => selected.value.includes(id)))\n\nfunction toggleAll() {\n selected.value = allSelected.value\n ? selected.value.filter((id) => !ids.value.includes(id))\n : [...new Set([...selected.value, ...ids.value])]\n}\n\nfunction toggle(id: unknown) {\n selected.value = selected.value.includes(id) ? selected.value.filter((x) => x !== id) : [...selected.value, id]\n}\n\n// Sorting a column cycles ascending, descending, unsorted.\nfunction sortBy(key: string) {\n const dir = sort.value?.key === key ? sort.value.dir : null\n const next = dir === null ? 'asc' : dir === 'asc' ? 'desc' : null\n sort.value = next ? { key, dir: next } : null\n}\n\nfunction dirOf(key: string) {\n return sort.value?.key === key ? sort.value.dir : null\n}\n\nfunction ariaSort(column: TableColumn) {\n const dir = dirOf(column.key)\n if (dir) return dir === 'asc' ? 'ascending' : 'descending'\n return column.sortable ? 'none' : undefined\n}\n\nconst state = computed(() => {\n if (slots.error) return 'error'\n if (props.loading) return 'loading'\n return props.rows.length === 0 && slots.empty ? 'empty' : 'rows'\n})\n\nconst columnCount = computed(() => props.columns.length + (props.selectable ? 1 : 0))\nconst alignClass = { left: 'text-left', center: 'text-center', right: 'text-right' }\nconst skeletonWidths = ['60%', '45%', '70%', '35%', '55%']\n\nconst sm = computed(() => props.size === 'sm')\nconst fixed = computed(() => props.rowHeight !== undefined)\nconst rowStyle = computed(() => {\n const style: Record<string, string> = {}\n if (fixed.value) style['--sui-table-row'] = `${props.rowHeight}px`\n if (props.headerHeight !== undefined) style['--sui-table-header'] = `${props.headerHeight}px`\n return Object.keys(style).length ? style : undefined\n})\nconst th = computed(() => [\n 'border-b border-sui-line-subtle text-13 font-medium whitespace-nowrap',\n sm.value\n ? 'h-[var(--sui-table-header,var(--sui-table-row,2.25rem))]'\n : 'h-[var(--sui-table-header,var(--sui-table-row,2.75rem))]'\n])\nconst td = computed(() => [\n 'border-b border-sui-line-subtle align-middle text-sui-ink-body group-last/row:border-b-0',\n sm.value ? 'h-[var(--sui-table-row,2.5rem)]' : 'h-[var(--sui-table-row,3.5625rem)]'\n])\n// A set row height takes the cells' vertical padding with it.\nconst pad = computed(() => [sm.value ? 'px-3' : 'px-4', !fixed.value && (sm.value ? 'py-1.5' : 'py-3')])\nconst headTone = computed(() => (props.headerTone === 'canvas' ? 'bg-sui-canvas' : 'bg-sui-sunken'))\nconst headPad = computed(() => (sm.value ? 'px-3' : 'px-4'))\nconst checkCell = 'w-12 pl-4 text-left'\n</script>\n\n<!-- A data table: sunken header strip, sortable headers, selection, loading, empty and error states, a footer. -->\n<template>\n <div\n class=\"overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sm text-sui-ink\"\n :style=\"rowStyle\"\n >\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-[var(--sui-table-min,720px)] table-fixed border-collapse\">\n <caption v-if=\"caption\" class=\"sr-only\">\n {{\n caption\n }}\n </caption>\n <colgroup>\n <col v-if=\"selectable\" class=\"w-12\" />\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :style=\"{ width: typeof column.width === 'number' ? `${column.width}px` : column.width }\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-if=\"selectable\" :class=\"[th, checkCell, headTone]\">\n <Checkbox\n :aria-label=\"selectAllLabel\"\n :disabled=\"loading || rows.length === 0\"\n :indeterminate=\"someSelected\"\n :model-value=\"allSelected\"\n @update:model-value=\"toggleAll\"\n />\n </th>\n <component\n :is=\"column.label ? 'th' : 'td'\"\n v-for=\"column in columns\"\n :key=\"column.key\"\n :aria-sort=\"ariaSort(column)\"\n :class=\"[\n th,\n headPad,\n alignClass[column.align ?? 'left'],\n dirOf(column.key) ? 'bg-sui-accent-wash text-sui-accent' : [headTone, 'text-sui-ink-subtle']\n ]\"\n :scope=\"column.label ? 'col' : undefined\"\n >\n <button\n v-if=\"column.sortable\"\n class=\"inline-flex h-full w-full items-center gap-1.5 rounded-md outline-hidden focus-visible:sui-ring-inset\"\n :class=\"[\n column.align === 'right' && 'justify-end',\n column.align === 'center' && 'justify-center',\n !dirOf(column.key) && 'hover:text-sui-ink'\n ]\"\n type=\"button\"\n @click=\"sortBy(column.key)\"\n >\n {{ column.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3 shrink-0 fill-none stroke-current\"\n :class=\"!dirOf(column.key) && 'opacity-50'\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 12 12\"\n >\n <path v-if=\"dirOf(column.key) === 'asc'\" d=\"M3 7.5 6 4.5l3 3\" />\n <path v-else-if=\"dirOf(column.key) === 'desc'\" d=\"M3 4.5 6 7.5l3-3\" />\n <path v-else d=\"M3.5 4.5 6 2l2.5 2.5M3.5 7.5 6 10l2.5-2.5\" />\n </svg>\n </button>\n <template v-else>{{ column.label }}</template>\n </component>\n </tr>\n </thead>\n <tbody :aria-busy=\"loading || undefined\">\n <tr v-if=\"state === 'error' || state === 'empty'\">\n <td class=\"p-0\" :colspan=\"columnCount\">\n <slot :name=\"state\" />\n </td>\n </tr>\n <template v-else-if=\"state === 'loading'\">\n <tr v-for=\"i in loadingRows\" :key=\"i\" aria-hidden=\"true\" class=\"group/row\">\n <td v-if=\"selectable\" :class=\"[td, checkCell]\"><Skeleton size=\"1rem\" /></td>\n <td v-for=\"(column, j) in columns\" :key=\"column.key\" :class=\"[td, pad]\">\n <Skeleton height=\"0.75rem\" :width=\"skeletonWidths[(i + j) % 5]\" />\n </td>\n </tr>\n </template>\n <template v-else>\n <tr\n v-for=\"row in rows\"\n :key=\"idOf(row) as PropertyKey\"\n :aria-selected=\"selectable ? selected.includes(idOf(row)) : undefined\"\n class=\"group/row transition-colors duration-150\"\n :class=\"[\n selected.includes(idOf(row)) ? 'bg-sui-accent-wash' : 'hover:bg-sui-sunken',\n onRowClick && 'cursor-pointer'\n ]\"\n @click=\"onRowClick?.(row)\"\n >\n <td v-if=\"selectable\" :class=\"[td, checkCell]\" @click.stop>\n <Checkbox\n :aria-label=\"selectRowLabel\"\n :model-value=\"selected.includes(idOf(row))\"\n @update:model-value=\"toggle(idOf(row))\"\n />\n </td>\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n td,\n pad,\n alignClass[column.align ?? 'left'],\n column.wrap ? 'break-words whitespace-normal' : 'truncate'\n ]\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\" :value=\"row[column.key]\">\n <template v-if=\"row[column.key] != null && row[column.key] !== ''\">{{ row[column.key] }}</template>\n <span v-else class=\"text-sui-ink-muted\">–</span>\n </slot>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"$slots.footer\"\n class=\"flex flex-wrap items-center justify-between gap-3 border-t border-sui-line-subtle bg-sui-canvas py-2 pr-3 pl-4 text-13 text-sui-ink-muted\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|