@eos-ui/vue 0.5.1 → 0.5.3
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/components/AppShell/EAppShell.js.map +1 -1
- package/dist/components/AppShell/EAppShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Avatar/EAvatar.js.map +1 -1
- package/dist/components/Avatar/EAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Button/EButton.js.map +1 -1
- package/dist/components/Button/EButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Combobox/EComboboxBase.js.map +1 -1
- package/dist/components/Combobox/EComboboxBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/DataGrid/EDataGrid.js.map +1 -1
- package/dist/components/DataGrid/EDataGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/NavList/ENavList.js.map +1 -1
- package/dist/components/NavList/ENavList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Notice/ENotice.js.map +1 -1
- package/dist/components/Notice/ENotice.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Progress/EProgress.js.map +1 -1
- package/dist/components/Progress/EProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/SearchBar/ESearchBar.js.map +1 -1
- package/dist/components/SearchBar/ESearchBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Segmented/ESegmented.js.map +1 -1
- package/dist/components/Segmented/ESegmented.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Select/ESelectControl.js.map +1 -1
- package/dist/components/Select/ESelectControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/SignaturePad/ESignaturePad.js.map +1 -1
- package/dist/components/SignaturePad/ESignaturePad.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Stepper/EStepper.js.map +1 -1
- package/dist/components/Stepper/EStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Switch/ESwitch.js.map +1 -1
- package/dist/components/Switch/ESwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Tabs/ETabs.js.map +1 -1
- package/dist/components/Tabs/ETabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Textarea/ETextarea.js.map +1 -1
- package/dist/components/Textarea/ETextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/style.css +179 -156
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EDataGrid.js","names":["_sfc_main","EDataGrid_vue_vue_type_script_setup_true_lang_default","EDataGrid_default"],"sources":["../../../src/components/DataGrid/EDataGrid.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"Row extends DataGridRow\">\nimport { computed, nextTick, ref, watch, type CSSProperties } from \"vue\";\nimport { PopoverClose, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from \"reka-ui\";\nimport {\n columnFilteringFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n createFilteredRowModel,\n createPaginatedRowModel,\n createSortedRowModel,\n functionalUpdate,\n globalFilteringFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n rowSortingFeature,\n tableFeatures,\n useTable,\n type ColumnDef,\n type FilterFn,\n type SortFn,\n} from \"@tanstack/vue-table\";\nimport { useVirtualizer } from \"@tanstack/vue-virtual\";\nimport EButton from \"../Button/EButton.vue\";\nimport ECheckbox from \"../Checkbox/ECheckbox.vue\";\nimport EEmptyState from \"../EmptyState/EEmptyState.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport EIconButton from \"../IconButton/EIconButton.vue\";\nimport EPagination from \"../Pagination/EPagination.vue\";\nimport ESelect from \"../Select/ESelect.vue\";\nimport ETextField from \"../TextField/ETextField.vue\";\nimport EDataGridResizer from \"./EDataGridResizer.vue\";\nimport \"../Definition/EDefinition.vue\";\nimport { normalizeOptions, type EOption } from \"../Select/options.js\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport { useMessages, usePortalTarget } from \"../../config.js\";\nimport { useUid } from \"../../composables/useUid.js\";\nimport { cellValue, compareValues, filterActive, parsePx, passesFilter } from \"./grid.js\";\nimport type {\n DataGridColumn,\n DataGridFilterValue,\n DataGridQuery,\n DataGridRow,\n DataGridSort,\n DataGridVirtual,\n} from \"./types.js\";\nimport \"../../styles/base.css\";\nimport \"../Table/table.css\";\nimport \"../TextField/input.css\";\nimport \"../Select/panel.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** The columns, in order. See `DataGridColumn` below. */\n columns: DataGridColumn<Row>[];\n /** The rows. Each needs a unique `id`; selection is by id. */\n rows: Row[];\n /** Names the table for screen readers, and its scrolling region. */\n caption: string;\n /** One search box over all shown columns. */\n searchable?: boolean;\n /** The search box's placeholder. @default \"Search all columns\" */\n searchPlaceholder?: string;\n /** A filter row under the headings, for columns that define a `filter`. */\n filterable?: boolean;\n /** Column edges can be dragged, or moved with the arrow keys. */\n resizable?: boolean;\n /** Keeps the first column in view while scrolling sideways. */\n stickyFirst?: boolean;\n /** A Columns menu to show and hide columns. */\n columnToggle?: boolean;\n /** A checkbox on each row and a select-all in the heading. */\n selectable?: boolean;\n /** Rows per page; 0 turns paging off. */\n pageSize?: number;\n /** Stops the table growing past this height (any CSS length) and scrolls inside it, with a sticky header. */\n maxHeight?: string;\n /** Renders only the rows in view, for thousands of rows. Replaces paging. `true` or `{ rowHeight = 48, height = 440, overscan = 8 }`. */\n virtual?: boolean | DataGridVirtual;\n /** Turns rows into cards below 40rem of the grid's own width. `virtual` and `resizable` grids keep the table. */\n cards?: boolean;\n /** Data lives on a server: show the rows given, in the order given, and report every change through `queryChange`. */\n manual?: boolean;\n /** With `manual`, how many rows there are in all. */\n total?: number;\n /** Shows placeholder rows while data loads, with `aria-busy`. */\n loading?: boolean;\n /** The title when there are no rows. @default \"No results\" */\n emptyTitle?: string;\n /** The sentence under the empty title, when there are no rows. */\n emptyText?: string;\n /** The icon above the empty title. @default \"search\" */\n emptyIcon?: IconProp;\n /** No chrome: a bare table for a short static list, with no toolbar, filters, paging or footer. */\n bare?: boolean;\n }>(),\n { pageSize: 10, cards: true },\n);\n\nconst emit = defineEmits<{\n /** Sort, page, search or filters changed. With `manual`, fetch the rows this describes. */\n queryChange: [query: DataGridQuery];\n}>();\n\nconst slots = defineSlots<{\n [K: `cell-${string}`]: (props: { row: Row; value: unknown }) => unknown;\n [K: `header-${string}`]: (props: { column: DataGridColumn<Row> }) => unknown;\n /** Buttons that act on the selected rows, shown beside the count. */\n \"bulk-actions\"?: () => unknown;\n /** Anything else for the bar above the table. */\n toolbar?: () => unknown;\n}>();\n\n/** The sort: `{ key, dir: \"asc\" | \"desc\" }`, or `null` for none. */\nconst sort = defineModel<DataGridSort | null>(\"sort\", { default: null });\n/** The current page, from 1. */\nconst page = defineModel<number>(\"page\", { default: 1 });\n/** The text in the search box. */\nconst search = defineModel<string>(\"search\", { default: \"\" });\n/** The column filters, by column `key`: text, or `{ min, max }` strings for `number`. */\nconst filters = defineModel<Record<string, DataGridFilterValue>>(\"filters\", { default: () => ({}) });\n/** The selected row ids, kept across pages and filters. */\nconst selected = defineModel<string[]>(\"selected\", { default: () => [] });\n\nconst t = useMessages();\nconst portal = usePortalTarget();\n\nconst uid = useUid();\nconst menuOpen = ref(false);\nconst menuTrigger = ref<{ $el: HTMLElement } | null>(null);\nwatch(\n menuOpen,\n async (open) => {\n if (!open) return;\n await nextTick();\n const panel = document.getElementById(menuTrigger.value?.$el?.getAttribute(\"aria-controls\") ?? \"\");\n panel?.setAttribute(\"aria-labelledby\", `${uid.value}-columns`);\n },\n { flush: \"post\" },\n);\n\nconst ALL = \"__e-all__\";\nconst NONE = \"__e-none__\";\n\nconst features = tableFeatures({\n rowSortingFeature,\n sortedRowModel: createSortedRowModel(),\n columnFilteringFeature,\n globalFilteringFeature,\n filteredRowModel: createFilteredRowModel(),\n rowPaginationFeature,\n paginatedRowModel: createPaginatedRowModel(),\n rowSelectionFeature,\n columnVisibilityFeature,\n columnSizingFeature,\n});\n\nconst columnVisibility = ref<Record<string, boolean>>({});\nconst columnSizing = ref<Record<string, number>>({});\n\nconst sortFn: SortFn<typeof features, Row> = (a, b, id) => compareValues(a.getValue(id), b.getValue(id));\ntype GlobalFilter = { q: string; cols: string[] };\nconst globalFilterFn: FilterFn<typeof features, Row> = (row, id, f: GlobalFilter) => {\n if (!f.cols.includes(id)) return false;\n const v = row.getValue(id);\n return v != null && String(v).toLowerCase().includes(f.q);\n};\n\nconst colByKey = computed(() => new Map(props.columns.map((c) => [c.key, c])));\nconst columnDefs = computed<ColumnDef<typeof features, Row>[]>(() =>\n props.columns.map((c) => ({\n id: c.key,\n accessorFn: (row: Row) => cellValue(row, c),\n header: c.label,\n enableSorting: !!c.sortable,\n sortDescFirst: false,\n sortFn,\n enableColumnFilter: !!c.filter,\n filterFn: ((row, id, f) => passesFilter(c, row.getValue(id), f)) as FilterFn<typeof features, Row>,\n enableResizing: c.resizable !== false,\n })),\n);\n\nconst vopt = computed(() =>\n props.virtual ? { rowHeight: 48, height: 440, overscan: 8, ...(props.virtual === true ? {} : props.virtual) } : null,\n);\nconst pageSize = computed(() => (vopt.value || props.bare ? 0 : (props.pageSize ?? 10)));\nconst paging = computed(() => pageSize.value > 0 && !props.manual);\nconst resizable = computed(() => !!props.resizable && !props.bare);\nconst cards = computed(() => props.cards !== false && !vopt.value && !resizable.value);\nconst q = computed(() => search.value.trim().toLowerCase());\nconst anyFilter = computed(() => Object.values(filters.value).some(filterActive));\n\nconst table = useTable({\n features,\n columns: columnDefs,\n data: computed(() => props.rows),\n getRowId: (row: Row) => String(row.id),\n enableMultiSort: false,\n enableSubRowSelection: false,\n autoResetPageIndex: false,\n manualSorting: computed(() => !!props.manual),\n manualFiltering: computed(() => !!props.manual),\n manualPagination: computed(() => !paging.value),\n rowCount: computed(() => (props.manual ? (props.total ?? props.rows.length) : undefined)),\n globalFilterFn,\n state: computed(() => ({\n sorting: sort.value ? [{ id: sort.value.key, desc: sort.value.dir === \"desc\" }] : [],\n columnFilters: Object.entries(filters.value)\n .filter(([key, value]) => colByKey.value.has(key) && filterActive(value))\n .map(([id, value]) => ({ id, value })),\n globalFilter: q.value\n ? ({\n q: q.value,\n cols: props.columns.filter((c) => columnVisibility.value[c.key] !== false).map((c) => c.key),\n } satisfies GlobalFilter)\n : undefined,\n rowSelection: Object.fromEntries(selected.value.map((id) => [id, true])),\n columnVisibility: columnVisibility.value,\n columnSizing: columnSizing.value,\n pagination: { pageIndex: Math.max(0, page.value - 1), pageSize: pageSize.value || 1 },\n })),\n onSortingChange: (updater) => {\n const next = functionalUpdate(updater, sort.value ? [{ id: sort.value.key, desc: sort.value.dir === \"desc\" }] : []);\n const first = next[0];\n sort.value = first ? { key: first.id, dir: first.desc ? \"desc\" : \"asc\" } : null;\n page.value = 1;\n },\n onRowSelectionChange: (updater) => {\n const next = functionalUpdate(updater, Object.fromEntries(selected.value.map((id) => [id, true])));\n selected.value = Object.keys(next).filter((k) => next[k]);\n },\n onColumnVisibilityChange: (updater) => {\n columnVisibility.value = functionalUpdate(updater, columnVisibility.value);\n },\n onColumnSizingChange: (updater) => {\n columnSizing.value = functionalUpdate(updater, columnSizing.value);\n },\n});\n\nconst view = computed(() => table.getRowModel().rows);\nconst total = computed(() =>\n props.manual ? (props.total ?? props.rows.length) : table.getPrePaginatedRowModel().rows.length,\n);\nconst pages = computed(() => (pageSize.value > 0 ? Math.max(1, Math.ceil(total.value / pageSize.value)) : 1));\nconst cur = computed(() => Math.min(page.value, pages.value));\nwatch(pages, (n) => {\n if (page.value > n) page.value = n;\n});\nconst cols = computed(() =>\n table\n .getVisibleLeafColumns()\n .map((c) => colByKey.value.get(c.id))\n .filter((c): c is DataGridColumn<Row> => !!c),\n);\nconst hasFilterRow = computed(() => !!props.filterable && !props.bare && cols.value.some((c) => c.filter));\nconst colCount = computed(() => cols.value.length + (props.selectable ? 1 : 0));\nconst from = computed(() =>\n total.value === 0 ? 0 : (cur.value - 1) * (pageSize.value > 0 ? pageSize.value : total.value) + 1,\n);\nconst to = computed(() => (pageSize.value > 0 ? Math.min(total.value, cur.value * pageSize.value) : total.value));\nconst sortedCol = computed(() => (sort.value ? colByKey.value.get(sort.value.key) : undefined));\nconst nPicked = computed(() => selected.value.length);\nconst allOn = computed(() => view.value.length > 0 && view.value.every((r) => r.getIsSelected()));\nconst someOn = computed(() => view.value.some((r) => r.getIsSelected()));\n\nconst scrollEl = ref<HTMLElement | null>(null);\nconst virtualizer = useVirtualizer(\n computed(() => ({\n count: vopt.value ? view.value.length : 0,\n getScrollElement: () => scrollEl.value,\n estimateSize: () => vopt.value?.rowHeight ?? 48,\n overscan: vopt.value?.overscan ?? 8,\n getItemKey: (i: number) => view.value[i]?.id ?? i,\n initialRect: { width: 0, height: vopt.value?.height ?? 0 },\n })),\n);\nconst items = computed(() => (vopt.value ? virtualizer.value.getVirtualItems() : []));\nconst shown = computed(() => (vopt.value ? items.value.flatMap((i) => (view.value[i.index] ? [i] : [])) : []));\nconst spaceTop = computed(() => items.value[0]?.start ?? 0);\nconst spaceBottom = computed(() => {\n const last = items.value[items.value.length - 1];\n return last ? Math.max(0, virtualizer.value.getTotalSize() - last.end) : 0;\n});\nconst rowsToRender = computed(() =>\n vopt.value\n ? shown.value.map((i) => ({ row: view.value[i.index]!, index: i.index }))\n : view.value.map((row, index) => ({ row, index })),\n);\n\nconst cellProps = (row: (typeof view.value)[number], c: DataGridColumn<Row>) => ({\n row: row.original,\n value: row.getValue(c.key),\n});\n\nconst fixedLayout = computed(() => resizable.value || !!vopt.value || cols.value.some((c) => c.width));\nconst stickyLeft = computed(() => (props.selectable ? 52 : 0));\nconst widthOf = (c: DataGridColumn<Row>) => columnSizing.value[c.key] || parsePx(c.width) || undefined;\nconst minTable = computed(\n () => (props.selectable ? 52 : 0) + cols.value.reduce((s, c) => s + (widthOf(c) || c.minWidth || 96), 0),\n);\nconst stick = (i: number) => !!props.stickyFirst && i === 0;\nconst stickStyle = (i: number): CSSProperties | undefined =>\n stick(i) ? { insetInlineStart: `${stickyLeft.value}px` } : undefined;\nconst tableStyle = computed(\n () =>\n ({\n tableLayout: fixedLayout.value ? \"fixed\" : undefined,\n \"--e-grid-min-w\": fixedLayout.value ? `${minTable.value}px` : undefined,\n \"--e-row-h\": vopt.value ? `${vopt.value.rowHeight}px` : undefined,\n }) as CSSProperties,\n);\nconst scrollStyle = computed(\n () =>\n (vopt.value\n ? { height: `${vopt.value.height}px` }\n : props.maxHeight\n ? { \"--e-grid-max-h\": props.maxHeight }\n : undefined) as CSSProperties | undefined,\n);\nconst role = (r: string) => (cards.value ? r : undefined);\n\nconst sortables = computed(() => props.columns.filter((c) => c.sortable));\nconst sortOptions = computed<EOption[]>(() => [\n { value: NONE, label: t(\"sortBy\") },\n ...sortables.value.flatMap((c) =>\n ([\"asc\", \"desc\"] as const).map((d) => ({\n value: `${c.key}:${d}`,\n label: `${c.label}, ${t(d === \"asc\" ? \"ascending\" : \"descending\")}`,\n })),\n ),\n]);\nconst sortSelectValue = computed(() => (sort.value ? `${sort.value.key}:${sort.value.dir}` : NONE));\nconst showSortSelect = computed(() => cards.value && sortables.value.length > 0);\nconst hasToolbar = computed(() => !!slots.toolbar);\nconst barOther = computed(\n () => !!props.searchable || !!props.columnToggle || nPicked.value > 0 || anyFilter.value || hasToolbar.value,\n);\nconst showBar = computed(() => !props.bare && (barOther.value || showSortSelect.value));\n\nfunction onSearch(e: Event) {\n search.value = (e.target as HTMLInputElement).value;\n page.value = 1;\n}\nfunction setFilter(key: string, value: DataGridFilterValue) {\n filters.value = { ...filters.value, [key]: value };\n page.value = 1;\n}\nfunction clearFilters() {\n filters.value = {};\n search.value = \"\";\n page.value = 1;\n}\nfunction chooseSort(v: string) {\n if (v === NONE) sort.value = null;\n else {\n const at = v.lastIndexOf(\":\");\n sort.value = { key: v.slice(0, at), dir: v.slice(at + 1) === \"desc\" ? \"desc\" : \"asc\" };\n }\n page.value = 1;\n}\nfunction setWidth(key: string, px: number) {\n table.setColumnSizing((old) => ({ ...old, [key]: px }));\n}\nfunction resetWidth(key: string) {\n table.setColumnSizing((old) => {\n const next = { ...old };\n delete next[key];\n return next;\n });\n}\nconst numberFilter = (key: string) => {\n const f = filters.value[key];\n return typeof f === \"object\" ? f : { min: \"\", max: \"\" };\n};\nconst textFilter = (key: string) => {\n const f = filters.value[key];\n return typeof f === \"string\" ? f : \"\";\n};\nconst selectOptions = (c: DataGridColumn<Row>): EOption[] => [\n { value: ALL, label: t(\"all\") },\n ...normalizeOptions(c.filter?.type === \"select\" ? c.filter.options : []),\n];\n\nwatch([sort, page, search, filters], () => {\n emit(\"queryChange\", {\n sort: sort.value,\n page: page.value,\n pageSize: pageSize.value,\n search: search.value,\n filters: filters.value,\n });\n});\n</script>\n\n<template>\n <div class=\"e-grid\" :class=\"{ 'e-grid--bare': bare, 'e-grid--cards': cards }\">\n <div class=\"e-grid-frame\">\n <div v-if=\"showBar\" class=\"e-grid-bar\" :class=\"{ 'e-grid-bar--sortonly': !barOther }\">\n <div v-if=\"searchable\" class=\"e-input-wrap e-grid-search\">\n <span class=\"e-affix e-affix--pre\"><EIcon name=\"search\" /></span>\n <input\n class=\"e-input\"\n type=\"search\"\n :placeholder=\"searchPlaceholder || t('searchAll')\"\n :aria-label=\"t('searchAll')\"\n :value=\"search\"\n @input=\"onSearch\"\n />\n </div>\n <div v-if=\"nPicked\" class=\"e-grid-picked\">\n <span class=\"e-grid-count\">{{ t(\"selected\", { n: nPicked }) }}</span>\n <slot name=\"bulk-actions\" />\n </div>\n <div v-if=\"showSortSelect\" class=\"e-grid-sortsel\">\n <ESelect\n bare\n :aria-label=\"t('sortBy')\"\n :placeholder=\"t('sortBy')\"\n :options=\"sortOptions\"\n :model-value=\"sortSelectValue\"\n @update:model-value=\"chooseSort\"\n />\n </div>\n <div class=\"e-grid-tools\">\n <EButton v-if=\"anyFilter || q\" variant=\"quiet\" @click=\"clearFilters\">{{ t(\"clearFilters\") }}</EButton>\n <PopoverRoot v-if=\"columnToggle\" v-model:open=\"menuOpen\">\n <PopoverTrigger as-child>\n <EButton ref=\"menuTrigger\" variant=\"outline\" :aria-label=\"t('chooseColumns')\">{{ t(\"columns\") }}</EButton>\n </PopoverTrigger>\n <PopoverPortal :to=\"portal\">\n <PopoverContent\n class=\"e-popover e-root\"\n side=\"bottom\"\n align=\"start\"\n :side-offset=\"8\"\n :collision-padding=\"16\"\n >\n <header class=\"e-pop-head\">\n <h3 :id=\"`${uid}-columns`\" class=\"e-pop-title\">{{ t(\"showColumns\") }}</h3>\n <PopoverClose as-child>\n <EIconButton icon=\"x\" :label=\"t('close')\" />\n </PopoverClose>\n </header>\n <div class=\"e-pop-body\">\n <ECheckbox\n v-for=\"column in table.getAllLeafColumns()\"\n :key=\"column.id\"\n :label=\"colByKey.get(column.id)?.label ?? column.id\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"column.toggleVisibility($event)\"\n />\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <slot name=\"toolbar\" />\n </div>\n </div>\n <div ref=\"scrollEl\" class=\"e-grid-scroll\" :style=\"scrollStyle\" tabindex=\"0\" role=\"region\" :aria-label=\"caption\">\n <table\n class=\"e-table e-gridtable\"\n :class=\"{ 'e-gridtable--virtual': vopt }\"\n :style=\"tableStyle\"\n :role=\"role('table')\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :aria-rowcount=\"vopt ? total + 1 + (hasFilterRow ? 1 : 0) : undefined\"\n >\n <caption class=\"e-sr\">\n {{\n caption\n }}\n </caption>\n <colgroup v-if=\"fixedLayout\">\n <col v-if=\"selectable\" style=\"width: 52px\" />\n <col v-for=\"c in cols\" :key=\"c.key\" :style=\"widthOf(c) ? { width: `${widthOf(c)}px` } : undefined\" />\n </colgroup>\n <thead :role=\"role('rowgroup')\">\n <tr :role=\"role('row')\">\n <th v-if=\"selectable\" scope=\"col\" class=\"e-cell-check\" :role=\"role('columnheader')\">\n <ECheckbox\n bare\n :label=\"vopt ? t('selectAll') : t('selectAllPage')\"\n :model-value=\"allOn\"\n :indeterminate=\"someOn && !allOn\"\n @update:model-value=\"table.toggleAllPageRowsSelected(!allOn)\"\n />\n </th>\n <th\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n scope=\"col\"\n :role=\"role('columnheader')\"\n :class=\"{ 'e-num': c.numeric, 'e-center': c.align === 'center', 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n :aria-sort=\"\n c.sortable\n ? sort?.key === c.key\n ? sort.dir === 'asc'\n ? 'ascending'\n : 'descending'\n : 'none'\n : undefined\n \"\n >\n <button\n v-if=\"c.sortable\"\n type=\"button\"\n class=\"e-sortbtn\"\n @click=\"table.getColumn(c.key)?.toggleSorting()\"\n >\n <slot :name=\"`header-${c.key}`\" :column=\"c\">{{ c.label }}</slot>\n <EIcon\n :name=\"sort?.key === c.key ? (sort.dir === 'asc' ? 'arrow-up' : 'arrow-down') : 'sort'\"\n small\n />\n </button>\n <slot v-else :name=\"`header-${c.key}`\" :column=\"c\">{{ c.label }}</slot>\n <EDataGridResizer\n v-if=\"resizable && c.resizable !== false\"\n :label=\"c.label\"\n :width=\"widthOf(c)\"\n :min=\"c.minWidth || 72\"\n @resize=\"setWidth(c.key, $event)\"\n @reset=\"resetWidth(c.key)\"\n />\n </th>\n </tr>\n <tr v-if=\"hasFilterRow\" class=\"e-filterrow\" :role=\"role('row')\">\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\" />\n <td\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n :role=\"role('cell')\"\n :class=\"{ 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n >\n <template v-if=\"c.filter\">\n <ESelect\n v-if=\"c.filter.type === 'select'\"\n bare\n :aria-label=\"t('filterColumn', { col: c.label })\"\n :placeholder=\"t('all')\"\n :options=\"selectOptions(c)\"\n :model-value=\"textFilter(c.key) || ALL\"\n @update:model-value=\"setFilter(c.key, $event === ALL ? '' : $event)\"\n />\n <div v-else-if=\"c.filter.type === 'number'\" class=\"e-filter-range\">\n <ETextField\n hide-label\n inputmode=\"decimal\"\n :label=\"t('minOf', { col: t('filterColumn', { col: c.label }) })\"\n :placeholder=\"t('min')\"\n :model-value=\"numberFilter(c.key).min\"\n @update:model-value=\"setFilter(c.key, { min: $event, max: numberFilter(c.key).max })\"\n />\n <ETextField\n hide-label\n inputmode=\"decimal\"\n :label=\"t('maxOf', { col: t('filterColumn', { col: c.label }) })\"\n :placeholder=\"t('max')\"\n :model-value=\"numberFilter(c.key).max\"\n @update:model-value=\"setFilter(c.key, { min: numberFilter(c.key).min, max: $event })\"\n />\n </div>\n <ETextField\n v-else\n hide-label\n type=\"search\"\n :label=\"t('filterColumn', { col: c.label })\"\n :placeholder=\"t('filter')\"\n :model-value=\"textFilter(c.key)\"\n @update:model-value=\"setFilter(c.key, $event)\"\n />\n </template>\n </td>\n </tr>\n </thead>\n <tbody :role=\"role('rowgroup')\">\n <template v-if=\"loading\">\n <tr v-for=\"n in 5\" :key=\"`s${n}`\" :role=\"role('row')\">\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\" />\n <td v-for=\"c in cols\" :key=\"c.key\" :role=\"role('cell')\"><span class=\"e-skel\" /></td>\n </tr>\n </template>\n <tr v-else-if=\"view.length === 0\" :role=\"role('row')\">\n <td :colspan=\"colCount\" class=\"e-grid-empty\" :role=\"role('cell')\">\n <EEmptyState bare :icon=\"emptyIcon || 'search'\" :title=\"emptyTitle || t('noResults')\">\n {{ emptyText || (anyFilter || q ? t(\"noMatchesFilters\") : t(\"nothingYet\")) }}\n <template v-if=\"anyFilter || q\" #action>\n <EButton variant=\"outline\" @click=\"clearFilters\">{{ t(\"clearFilters\") }}</EButton>\n </template>\n </EEmptyState>\n </td>\n </tr>\n <template v-else>\n <tr v-if=\"vopt && spaceTop > 0\" aria-hidden=\"true\" class=\"e-spacer\" :style=\"{ height: `${spaceTop}px` }\">\n <td :colspan=\"colCount\" />\n </tr>\n <tr\n v-for=\"{ row, index } in rowsToRender\"\n :key=\"row.id\"\n :role=\"role('row')\"\n :data-selected=\"row.getIsSelected() ? '' : undefined\"\n :aria-rowindex=\"vopt ? index + 2 + (hasFilterRow ? 1 : 0) : undefined\"\n >\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\">\n <ECheckbox\n bare\n :label=\"t('selectRow')\"\n :model-value=\"row.getIsSelected()\"\n @update:model-value=\"row.toggleSelected($event)\"\n />\n </td>\n <td\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n :role=\"role('cell')\"\n :data-label=\"c.label\"\n :class=\"{ 'e-num': c.numeric, 'e-center': c.align === 'center', 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n >\n <slot :name=\"`cell-${c.key}`\" v-bind=\"cellProps(row, c)\">{{ row.original[c.key] }}</slot>\n </td>\n </tr>\n <tr\n v-if=\"vopt && spaceBottom > 0\"\n aria-hidden=\"true\"\n class=\"e-spacer\"\n :style=\"{ height: `${spaceBottom}px` }\"\n >\n <td :colspan=\"colCount\" />\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div v-if=\"!bare\" class=\"e-grid-foot\">\n <span class=\"e-grid-range\">{{\n total === 0\n ? t(\"rows\", { n: 0 })\n : vopt || pageSize === 0\n ? t(\"rows\", { n: total })\n : t(\"showing\", { from, to, total })\n }}</span>\n <EPagination\n v-if=\"pageSize > 0 && pages > 1\"\n :model-value=\"cur\"\n :page-count=\"pages\"\n @update:model-value=\"page = $event\"\n />\n </div>\n <span class=\"e-sr\" role=\"status\" aria-live=\"polite\">{{\n loading\n ? t(\"loading\")\n : (sortedCol\n ? t(\"sortedBy\", { col: sortedCol.label, dir: t(sort?.dir === \"asc\" ? \"ascending\" : \"descending\") }) + \" \"\n : \"\") + t(\"rowsAnnounce\", { n: total })\n }}</span>\n </div>\n </div>\n</template>\n\n<style>\n@layer e.containers {\n .e-skel {\n display: block;\n height: 14px;\n border-radius: var(--e-radius-sm);\n background: var(--e-surface-tint);\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-border);\n animation: e-pulse 1.4s ease-in-out infinite;\n }\n\n @keyframes e-pulse {\n 50% {\n opacity: 0.5;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-skel {\n animation: none;\n }\n }\n\n .e-grid {\n --e-grid-head-h: 45px;\n\n isolation: isolate;\n border-radius: var(--e-radius-md);\n min-width: 0;\n }\n\n .e-grid-frame::after {\n content: \"\";\n position: absolute;\n inset: 0;\n z-index: var(--e-z-sticky);\n border-radius: inherit;\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-border-strong);\n pointer-events: none;\n }\n\n .e-grid-frame {\n position: relative;\n overflow: hidden;\n border-radius: inherit;\n background: var(--e-surface);\n }\n\n .e-grid-bar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--e-space-3);\n padding: var(--e-space-3) var(--e-space-4);\n border-bottom: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid-search {\n flex: 1 1 10rem;\n max-width: 24rem;\n }\n\n .e-grid-search .e-input {\n padding-inline-start: var(--e-space-2);\n }\n\n .e-grid-picked {\n display: flex;\n align-items: center;\n gap: var(--e-space-3);\n }\n\n .e-grid-count {\n font: 600 var(--e-text-xs) / 1 var(--e-font-mono);\n letter-spacing: 0.04em;\n }\n\n .e-grid-tools {\n margin-inline-start: auto;\n display: flex;\n gap: var(--e-space-2);\n }\n\n .e-grid-scroll {\n overflow: auto;\n max-height: var(--e-grid-max-h, none);\n }\n\n .e-grid-scroll:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n }\n\n .e-gridtable {\n border-radius: 0;\n box-shadow: none;\n min-width: var(--e-grid-min-w, 0);\n }\n\n .e-gridtable thead th {\n position: sticky;\n top: 0;\n z-index: var(--e-z-raised);\n height: var(--e-grid-head-h);\n box-sizing: border-box;\n }\n\n .e-gridtable th[aria-sort=\"ascending\"],\n .e-gridtable th[aria-sort=\"descending\"] {\n color: var(--e-ink);\n }\n\n .e-sortbtn {\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-1);\n min-height: var(--e-control-height);\n padding: var(--e-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n text-transform: inherit;\n cursor: pointer;\n }\n\n .e-sortbtn:hover {\n color: var(--e-ink);\n }\n\n .e-sortbtn:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n border-radius: var(--e-radius-sm);\n }\n\n .e-gridtable .e-cell-check {\n width: 52px;\n padding-inline-end: 0;\n vertical-align: middle;\n }\n\n .e-gridtable tbody tr[data-selected] td {\n background: var(--e-surface-tint);\n }\n\n .e-gridtable tbody tr[data-selected]:hover td {\n background: var(--e-surface-hover);\n box-shadow: inset 0 0 0 0 transparent;\n }\n\n .e-table td.e-grid-empty {\n padding: 0;\n }\n\n .e-grid-foot {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--e-space-3);\n padding: var(--e-space-3) var(--e-space-4);\n border-top: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid-range {\n font: 500 var(--e-text-xs) / 1.2 var(--e-font-mono);\n color: var(--e-muted);\n font-variant-numeric: tabular-nums;\n }\n\n .e-grid-foot .e-pager {\n justify-content: flex-end;\n }\n\n .e-filterrow td {\n padding: var(--e-space-1) var(--e-space-3);\n background: var(--e-surface);\n box-shadow: inset 0 calc(-1 * var(--e-stroke-card)) 0 var(--e-border-strong);\n border-top: 0;\n position: sticky;\n top: var(--e-grid-head-h);\n z-index: var(--e-z-raised);\n }\n\n .e-filterrow .e-input {\n height: var(--e-control-height);\n font-size: var(--e-text-md);\n padding-inline: var(--e-space-3);\n }\n\n .e-filterrow .e-sel-trigger {\n height: var(--e-control-height);\n padding-inline-end: var(--e-space-2);\n }\n\n .e-filter-range {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--e-space-1);\n }\n\n .e-gridtable thead th,\n .e-gridtable thead td {\n white-space: nowrap;\n }\n\n .e-resizer {\n position: absolute;\n top: 0;\n inset-inline-end: calc(var(--e-space-6) / -2);\n z-index: var(--e-z-raised);\n width: var(--e-space-6);\n height: 100%;\n cursor: col-resize;\n touch-action: none;\n }\n\n .e-resizer::before {\n content: \"\";\n position: absolute;\n inset-block: 0;\n inset-inline: -10px;\n }\n\n .e-resizer::after {\n content: \"\";\n position: absolute;\n top: 22%;\n inset-inline-start: 11px;\n width: var(--e-stroke-hair);\n height: 56%;\n background: var(--e-border-strong);\n transition: width var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-resizer:hover::after,\n .e-resizer:focus-visible::after {\n inset-inline-start: 10px;\n width: 3px;\n background: var(--e-primary);\n border-radius: var(--e-radius-sm);\n }\n\n .e-resizer:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n border-radius: var(--e-radius-sm);\n }\n\n .e-gridtable[style*=\"table-layout\"] td,\n .e-gridtable[style*=\"table-layout\"] th {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .e-gridtable .e-sticky {\n position: sticky;\n z-index: var(--e-z-raised);\n box-shadow: inset calc(-1 * var(--e-stroke-hair)) 0 0 var(--e-border);\n }\n\n .e-gridtable thead th.e-sticky {\n z-index: var(--e-z-sticky);\n background: var(--e-surface-tint);\n }\n\n .e-gridtable tbody td.e-sticky {\n background: var(--e-surface);\n }\n\n .e-gridtable tbody tr:hover td.e-sticky {\n background: var(--e-surface-hover);\n }\n\n .e-gridtable tbody tr[data-selected] td.e-sticky {\n background: var(--e-surface-tint);\n }\n\n .e-gridtable--virtual td {\n height: var(--e-row-h);\n padding-block: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .e-spacer td {\n padding: 0;\n border: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-resizer::after {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-gridtable tbody tr[data-selected] td {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .e-resizer::after {\n background: CanvasText;\n }\n\n .e-resizer:hover::after,\n .e-resizer:focus-visible::after {\n background: Highlight;\n }\n\n .e-skel {\n background: GrayText;\n }\n }\n\n @media print {\n .e-grid-scroll {\n overflow: visible;\n max-height: none;\n }\n }\n\n .e-grid--cards {\n container-type: inline-size;\n }\n\n .e-grid-sortsel {\n display: none;\n min-width: 11rem;\n }\n\n .e-grid-bar--sortonly {\n display: none;\n }\n\n @container (max-width: 40rem) {\n .e-grid-sortsel {\n display: block;\n flex: 1 1 11rem;\n }\n\n .e-grid-bar--sortonly {\n display: flex;\n }\n\n .e-grid--cards .e-grid-scroll {\n overflow: visible;\n max-height: none;\n }\n\n .e-grid--cards .e-gridtable,\n .e-grid--cards .e-gridtable tbody {\n display: block;\n min-width: 0;\n width: 100%;\n }\n\n .e-grid--cards .e-gridtable thead {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n /* stylelint-disable-next-line property-no-deprecated -- clip hides text visually */\n clip: rect(0 0 0 0);\n white-space: nowrap;\n }\n\n .e-grid--cards .e-grid-frame {\n overflow: visible;\n background: transparent;\n }\n\n .e-grid--cards .e-grid-frame::after {\n content: none;\n }\n\n .e-grid--cards .e-gridtable tbody tr {\n display: block;\n margin: 0 0 var(--e-space-3);\n padding: var(--e-space-1) var(--e-space-4);\n border-radius: var(--e-radius-md);\n background: var(--e-surface);\n box-shadow: var(--e-edge);\n }\n\n .e-grid--cards .e-gridtable tbody tr:hover td {\n background: transparent;\n }\n\n .e-grid--cards .e-gridtable tbody tr[data-selected] {\n background: var(--e-surface-tint);\n }\n\n .e-grid--cards .e-gridtable tbody tr[data-selected] td {\n background: transparent;\n }\n\n .e-grid--cards .e-gridtable td {\n display: grid;\n grid-template-columns: minmax(5rem, 38%) minmax(0, 1fr);\n gap: var(--e-space-3);\n align-items: baseline;\n padding: var(--e-space-2) 0;\n border-top: var(--e-stroke-hair) solid var(--e-border);\n overflow: visible;\n white-space: normal;\n text-align: start;\n }\n\n .e-grid--cards .e-gridtable tbody tr:first-child td:not(:first-child) {\n border-top: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid--cards .e-gridtable tbody td:first-child {\n border-top: 0;\n }\n\n .e-grid--cards .e-gridtable td::before {\n content: attr(data-label);\n font: 600 var(--e-text-xs) / 1.3 var(--e-font-mono);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--e-muted);\n }\n\n .e-grid--cards .e-gridtable td.e-cell-check {\n display: flex;\n width: auto;\n padding: var(--e-space-2) 0;\n }\n\n .e-grid--cards .e-gridtable td.e-cell-check::before {\n content: none;\n }\n\n .e-grid--cards .e-gridtable .e-sticky {\n position: static;\n box-shadow: none;\n }\n\n .e-grid--cards .e-gridtable .e-num {\n text-align: start;\n }\n\n .e-grid--cards .e-gridtable .e-grid-empty {\n display: block;\n }\n\n .e-grid--cards .e-gridtable .e-grid-empty::before {\n content: none;\n }\n\n .e-grid--cards .e-filterrow {\n display: none;\n }\n\n .e-grid--cards .e-gridtable[style*=\"table-layout\"] td {\n overflow: visible;\n text-overflow: clip;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"EDataGrid.js","names":["_sfc_main","EDataGrid_vue_vue_type_script_setup_true_lang_default","EDataGrid_default"],"sources":["../../../src/components/DataGrid/EDataGrid.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"Row extends DataGridRow\">\nimport { computed, nextTick, ref, watch, type CSSProperties } from \"vue\";\nimport { PopoverClose, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from \"reka-ui\";\nimport {\n columnFilteringFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n createFilteredRowModel,\n createPaginatedRowModel,\n createSortedRowModel,\n functionalUpdate,\n globalFilteringFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n rowSortingFeature,\n tableFeatures,\n useTable,\n type ColumnDef,\n type FilterFn,\n type SortFn,\n} from \"@tanstack/vue-table\";\nimport { useVirtualizer } from \"@tanstack/vue-virtual\";\nimport EButton from \"../Button/EButton.vue\";\nimport ECheckbox from \"../Checkbox/ECheckbox.vue\";\nimport EEmptyState from \"../EmptyState/EEmptyState.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport EIconButton from \"../IconButton/EIconButton.vue\";\nimport EPagination from \"../Pagination/EPagination.vue\";\nimport ESelect from \"../Select/ESelect.vue\";\nimport ETextField from \"../TextField/ETextField.vue\";\nimport EDataGridResizer from \"./EDataGridResizer.vue\";\nimport \"../Definition/EDefinition.vue\";\nimport { normalizeOptions, type EOption } from \"../Select/options.js\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport { useMessages, usePortalTarget } from \"../../config.js\";\nimport { useUid } from \"../../composables/useUid.js\";\nimport { cellValue, compareValues, filterActive, parsePx, passesFilter } from \"./grid.js\";\nimport type {\n DataGridColumn,\n DataGridFilterValue,\n DataGridQuery,\n DataGridRow,\n DataGridSort,\n DataGridVirtual,\n} from \"./types.js\";\nimport \"../../styles/base.css\";\nimport \"../Table/table.css\";\nimport \"../TextField/input.css\";\nimport \"../Select/panel.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** The columns, in order. See `DataGridColumn` below. */\n columns: DataGridColumn<Row>[];\n /** The rows. Each needs a unique `id`; selection is by id. */\n rows: Row[];\n /** Names the table for screen readers, and its scrolling region. */\n caption: string;\n /** One search box over all shown columns. */\n searchable?: boolean;\n /** The search box's placeholder. @default \"Search all columns\" */\n searchPlaceholder?: string;\n /** A filter row under the headings, for columns that define a `filter`. */\n filterable?: boolean;\n /** Column edges can be dragged, or moved with the arrow keys. */\n resizable?: boolean;\n /** Keeps the first column in view while scrolling sideways. */\n stickyFirst?: boolean;\n /** A Columns menu to show and hide columns. */\n columnToggle?: boolean;\n /** A checkbox on each row and a select-all in the heading. */\n selectable?: boolean;\n /** Rows per page; 0 turns paging off. */\n pageSize?: number;\n /** Stops the table growing past this height (any CSS length) and scrolls inside it, with a sticky header. */\n maxHeight?: string;\n /** Renders only the rows in view, for thousands of rows. Replaces paging. `true` or `{ rowHeight = 48, height = 440, overscan = 8 }`. */\n virtual?: boolean | DataGridVirtual;\n /** Turns rows into cards below 40rem of the grid's own width. `virtual` and `resizable` grids keep the table. */\n cards?: boolean;\n /** Data lives on a server: show the rows given, in the order given, and report every change through `queryChange`. */\n manual?: boolean;\n /** With `manual`, how many rows there are in all. */\n total?: number;\n /** Shows placeholder rows while data loads, with `aria-busy`. */\n loading?: boolean;\n /** The title when there are no rows. @default \"No results\" */\n emptyTitle?: string;\n /** The sentence under the empty title, when there are no rows. */\n emptyText?: string;\n /** The icon above the empty title. @default \"search\" */\n emptyIcon?: IconProp;\n /** No chrome: a bare table for a short static list, with no toolbar, filters, paging or footer. */\n bare?: boolean;\n }>(),\n { pageSize: 10, cards: true },\n);\n\nconst emit = defineEmits<{\n /** Sort, page, search or filters changed. With `manual`, fetch the rows this describes. */\n queryChange: [query: DataGridQuery];\n}>();\n\nconst slots = defineSlots<{\n [K: `cell-${string}`]: (props: { row: Row; value: unknown }) => unknown;\n [K: `header-${string}`]: (props: { column: DataGridColumn<Row> }) => unknown;\n /** Buttons that act on the selected rows, shown beside the count. */\n \"bulk-actions\"?: () => unknown;\n /** Anything else for the bar above the table. */\n toolbar?: () => unknown;\n}>();\n\n/** The sort: `{ key, dir: \"asc\" | \"desc\" }`, or `null` for none. */\nconst sort = defineModel<DataGridSort | null>(\"sort\", { default: null });\n/** The current page, from 1. */\nconst page = defineModel<number>(\"page\", { default: 1 });\n/** The text in the search box. */\nconst search = defineModel<string>(\"search\", { default: \"\" });\n/** The column filters, by column `key`: text, or `{ min, max }` strings for `number`. */\nconst filters = defineModel<Record<string, DataGridFilterValue>>(\"filters\", { default: () => ({}) });\n/** The selected row ids, kept across pages and filters. */\nconst selected = defineModel<string[]>(\"selected\", { default: () => [] });\n\nconst t = useMessages();\nconst portal = usePortalTarget();\n\nconst uid = useUid();\nconst menuOpen = ref(false);\nconst menuTrigger = ref<{ $el: HTMLElement } | null>(null);\nwatch(\n menuOpen,\n async (open) => {\n if (!open) return;\n await nextTick();\n const panel = document.getElementById(menuTrigger.value?.$el?.getAttribute(\"aria-controls\") ?? \"\");\n panel?.setAttribute(\"aria-labelledby\", `${uid.value}-columns`);\n },\n { flush: \"post\" },\n);\n\nconst ALL = \"__e-all__\";\nconst NONE = \"__e-none__\";\n\nconst features = tableFeatures({\n rowSortingFeature,\n sortedRowModel: createSortedRowModel(),\n columnFilteringFeature,\n globalFilteringFeature,\n filteredRowModel: createFilteredRowModel(),\n rowPaginationFeature,\n paginatedRowModel: createPaginatedRowModel(),\n rowSelectionFeature,\n columnVisibilityFeature,\n columnSizingFeature,\n});\n\nconst columnVisibility = ref<Record<string, boolean>>({});\nconst columnSizing = ref<Record<string, number>>({});\n\nconst sortFn: SortFn<typeof features, Row> = (a, b, id) => compareValues(a.getValue(id), b.getValue(id));\ntype GlobalFilter = { q: string; cols: string[] };\nconst globalFilterFn: FilterFn<typeof features, Row> = (row, id, f: GlobalFilter) => {\n if (!f.cols.includes(id)) return false;\n const v = row.getValue(id);\n return v != null && String(v).toLowerCase().includes(f.q);\n};\n\nconst colByKey = computed(() => new Map(props.columns.map((c) => [c.key, c])));\nconst columnDefs = computed<ColumnDef<typeof features, Row>[]>(() =>\n props.columns.map((c) => ({\n id: c.key,\n accessorFn: (row: Row) => cellValue(row, c),\n header: c.label,\n enableSorting: !!c.sortable,\n sortDescFirst: false,\n sortFn,\n enableColumnFilter: !!c.filter,\n filterFn: ((row, id, f) => passesFilter(c, row.getValue(id), f)) as FilterFn<typeof features, Row>,\n enableResizing: c.resizable !== false,\n })),\n);\n\nconst vopt = computed(() =>\n props.virtual ? { rowHeight: 48, height: 440, overscan: 8, ...(props.virtual === true ? {} : props.virtual) } : null,\n);\nconst pageSize = computed(() => (vopt.value || props.bare ? 0 : (props.pageSize ?? 10)));\nconst paging = computed(() => pageSize.value > 0 && !props.manual);\nconst resizable = computed(() => !!props.resizable && !props.bare);\nconst cards = computed(() => props.cards !== false && !vopt.value && !resizable.value);\nconst q = computed(() => search.value.trim().toLowerCase());\nconst anyFilter = computed(() => Object.values(filters.value).some(filterActive));\n\nconst table = useTable({\n features,\n columns: columnDefs,\n data: computed(() => props.rows),\n getRowId: (row: Row) => String(row.id),\n enableMultiSort: false,\n enableSubRowSelection: false,\n autoResetPageIndex: false,\n manualSorting: computed(() => !!props.manual),\n manualFiltering: computed(() => !!props.manual),\n manualPagination: computed(() => !paging.value),\n rowCount: computed(() => (props.manual ? (props.total ?? props.rows.length) : undefined)),\n globalFilterFn,\n state: computed(() => ({\n sorting: sort.value ? [{ id: sort.value.key, desc: sort.value.dir === \"desc\" }] : [],\n columnFilters: Object.entries(filters.value)\n .filter(([key, value]) => colByKey.value.has(key) && filterActive(value))\n .map(([id, value]) => ({ id, value })),\n globalFilter: q.value\n ? ({\n q: q.value,\n cols: props.columns.filter((c) => columnVisibility.value[c.key] !== false).map((c) => c.key),\n } satisfies GlobalFilter)\n : undefined,\n rowSelection: Object.fromEntries(selected.value.map((id) => [id, true])),\n columnVisibility: columnVisibility.value,\n columnSizing: columnSizing.value,\n pagination: { pageIndex: Math.max(0, page.value - 1), pageSize: pageSize.value || 1 },\n })),\n onSortingChange: (updater) => {\n const next = functionalUpdate(updater, sort.value ? [{ id: sort.value.key, desc: sort.value.dir === \"desc\" }] : []);\n const first = next[0];\n sort.value = first ? { key: first.id, dir: first.desc ? \"desc\" : \"asc\" } : null;\n page.value = 1;\n },\n onRowSelectionChange: (updater) => {\n const next = functionalUpdate(updater, Object.fromEntries(selected.value.map((id) => [id, true])));\n selected.value = Object.keys(next).filter((k) => next[k]);\n },\n onColumnVisibilityChange: (updater) => {\n columnVisibility.value = functionalUpdate(updater, columnVisibility.value);\n },\n onColumnSizingChange: (updater) => {\n columnSizing.value = functionalUpdate(updater, columnSizing.value);\n },\n});\n\nconst view = computed(() => table.getRowModel().rows);\nconst total = computed(() =>\n props.manual ? (props.total ?? props.rows.length) : table.getPrePaginatedRowModel().rows.length,\n);\nconst pages = computed(() => (pageSize.value > 0 ? Math.max(1, Math.ceil(total.value / pageSize.value)) : 1));\nconst cur = computed(() => Math.min(page.value, pages.value));\nwatch(pages, (n) => {\n if (page.value > n) page.value = n;\n});\nconst cols = computed(() =>\n table\n .getVisibleLeafColumns()\n .map((c) => colByKey.value.get(c.id))\n .filter((c): c is DataGridColumn<Row> => !!c),\n);\nconst hasFilterRow = computed(() => !!props.filterable && !props.bare && cols.value.some((c) => c.filter));\nconst colCount = computed(() => cols.value.length + (props.selectable ? 1 : 0));\nconst from = computed(() =>\n total.value === 0 ? 0 : (cur.value - 1) * (pageSize.value > 0 ? pageSize.value : total.value) + 1,\n);\nconst to = computed(() => (pageSize.value > 0 ? Math.min(total.value, cur.value * pageSize.value) : total.value));\nconst sortedCol = computed(() => (sort.value ? colByKey.value.get(sort.value.key) : undefined));\nconst nPicked = computed(() => selected.value.length);\nconst allOn = computed(() => view.value.length > 0 && view.value.every((r) => r.getIsSelected()));\nconst someOn = computed(() => view.value.some((r) => r.getIsSelected()));\n\nconst scrollEl = ref<HTMLElement | null>(null);\nconst virtualizer = useVirtualizer(\n computed(() => ({\n count: vopt.value ? view.value.length : 0,\n getScrollElement: () => scrollEl.value,\n estimateSize: () => vopt.value?.rowHeight ?? 48,\n overscan: vopt.value?.overscan ?? 8,\n getItemKey: (i: number) => view.value[i]?.id ?? i,\n initialRect: { width: 0, height: vopt.value?.height ?? 0 },\n })),\n);\nconst items = computed(() => (vopt.value ? virtualizer.value.getVirtualItems() : []));\nconst shown = computed(() => (vopt.value ? items.value.flatMap((i) => (view.value[i.index] ? [i] : [])) : []));\nconst spaceTop = computed(() => items.value[0]?.start ?? 0);\nconst spaceBottom = computed(() => {\n const last = items.value[items.value.length - 1];\n return last ? Math.max(0, virtualizer.value.getTotalSize() - last.end) : 0;\n});\nconst rowsToRender = computed(() =>\n vopt.value\n ? shown.value.map((i) => ({ row: view.value[i.index]!, index: i.index }))\n : view.value.map((row, index) => ({ row, index })),\n);\n\nconst cellProps = (row: (typeof view.value)[number], c: DataGridColumn<Row>) => ({\n row: row.original,\n value: row.getValue(c.key),\n});\n\nconst fixedLayout = computed(() => resizable.value || !!vopt.value || cols.value.some((c) => c.width));\nconst stickyLeft = computed(() => (props.selectable ? 52 : 0));\nconst widthOf = (c: DataGridColumn<Row>) => columnSizing.value[c.key] || parsePx(c.width) || undefined;\nconst minTable = computed(\n () => (props.selectable ? 52 : 0) + cols.value.reduce((s, c) => s + (widthOf(c) || c.minWidth || 96), 0),\n);\nconst stick = (i: number) => !!props.stickyFirst && i === 0;\nconst stickStyle = (i: number): CSSProperties | undefined =>\n stick(i) ? { insetInlineStart: `${stickyLeft.value}px` } : undefined;\nconst tableStyle = computed(\n () =>\n ({\n tableLayout: fixedLayout.value ? \"fixed\" : undefined,\n \"--e-grid-min-w\": fixedLayout.value ? `${minTable.value}px` : undefined,\n \"--e-row-h\": vopt.value ? `${vopt.value.rowHeight}px` : undefined,\n }) as CSSProperties,\n);\nconst scrollStyle = computed(\n () =>\n (vopt.value\n ? { height: `${vopt.value.height}px` }\n : props.maxHeight\n ? { \"--e-grid-max-h\": props.maxHeight }\n : undefined) as CSSProperties | undefined,\n);\nconst role = (r: string) => (cards.value ? r : undefined);\n\nconst sortables = computed(() => props.columns.filter((c) => c.sortable));\nconst sortOptions = computed<EOption[]>(() => [\n { value: NONE, label: t(\"sortBy\") },\n ...sortables.value.flatMap((c) =>\n ([\"asc\", \"desc\"] as const).map((d) => ({\n value: `${c.key}:${d}`,\n label: `${c.label}, ${t(d === \"asc\" ? \"ascending\" : \"descending\")}`,\n })),\n ),\n]);\nconst sortSelectValue = computed(() => (sort.value ? `${sort.value.key}:${sort.value.dir}` : NONE));\nconst showSortSelect = computed(() => cards.value && sortables.value.length > 0);\nconst hasToolbar = computed(() => !!slots.toolbar);\nconst barOther = computed(\n () => !!props.searchable || !!props.columnToggle || nPicked.value > 0 || anyFilter.value || hasToolbar.value,\n);\nconst showBar = computed(() => !props.bare && (barOther.value || showSortSelect.value));\n\nfunction onSearch(e: Event) {\n search.value = (e.target as HTMLInputElement).value;\n page.value = 1;\n}\nfunction setFilter(key: string, value: DataGridFilterValue) {\n filters.value = { ...filters.value, [key]: value };\n page.value = 1;\n}\nfunction clearFilters() {\n filters.value = {};\n search.value = \"\";\n page.value = 1;\n}\nfunction chooseSort(v: string) {\n if (v === NONE) sort.value = null;\n else {\n const at = v.lastIndexOf(\":\");\n sort.value = { key: v.slice(0, at), dir: v.slice(at + 1) === \"desc\" ? \"desc\" : \"asc\" };\n }\n page.value = 1;\n}\nfunction setWidth(key: string, px: number) {\n table.setColumnSizing((old) => ({ ...old, [key]: px }));\n}\nfunction resetWidth(key: string) {\n table.setColumnSizing((old) => {\n const next = { ...old };\n delete next[key];\n return next;\n });\n}\nconst numberFilter = (key: string) => {\n const f = filters.value[key];\n return typeof f === \"object\" ? f : { min: \"\", max: \"\" };\n};\nconst textFilter = (key: string) => {\n const f = filters.value[key];\n return typeof f === \"string\" ? f : \"\";\n};\nconst selectOptions = (c: DataGridColumn<Row>): EOption[] => [\n { value: ALL, label: t(\"all\") },\n ...normalizeOptions(c.filter?.type === \"select\" ? c.filter.options : []),\n];\n\nwatch([sort, page, search, filters], () => {\n emit(\"queryChange\", {\n sort: sort.value,\n page: page.value,\n pageSize: pageSize.value,\n search: search.value,\n filters: filters.value,\n });\n});\n</script>\n\n<template>\n <div class=\"e-grid\" :class=\"{ 'e-grid--bare': bare, 'e-grid--cards': cards }\">\n <div class=\"e-grid-frame\">\n <div v-if=\"showBar\" class=\"e-grid-bar\" :class=\"{ 'e-grid-bar--sortonly': !barOther }\">\n <div v-if=\"searchable\" class=\"e-input-wrap e-grid-search\">\n <span class=\"e-affix e-affix--pre\"><EIcon name=\"search\" /></span>\n <input\n class=\"e-input\"\n type=\"search\"\n :placeholder=\"searchPlaceholder || t('searchAll')\"\n :aria-label=\"t('searchAll')\"\n :value=\"search\"\n @input=\"onSearch\"\n />\n </div>\n <div v-if=\"nPicked\" class=\"e-grid-picked\">\n <span class=\"e-grid-count\">{{ t(\"selected\", { n: nPicked }) }}</span>\n <slot name=\"bulk-actions\" />\n </div>\n <div v-if=\"showSortSelect\" class=\"e-grid-sortsel\">\n <ESelect\n bare\n :aria-label=\"t('sortBy')\"\n :placeholder=\"t('sortBy')\"\n :options=\"sortOptions\"\n :model-value=\"sortSelectValue\"\n @update:model-value=\"chooseSort\"\n />\n </div>\n <div class=\"e-grid-tools\">\n <EButton v-if=\"anyFilter || q\" variant=\"quiet\" @click=\"clearFilters\">{{ t(\"clearFilters\") }}</EButton>\n <PopoverRoot v-if=\"columnToggle\" v-model:open=\"menuOpen\">\n <PopoverTrigger as-child>\n <EButton ref=\"menuTrigger\" variant=\"outline\" :aria-label=\"t('chooseColumns')\">{{ t(\"columns\") }}</EButton>\n </PopoverTrigger>\n <PopoverPortal :to=\"portal\">\n <PopoverContent\n class=\"e-popover e-root\"\n side=\"bottom\"\n align=\"start\"\n :side-offset=\"8\"\n :collision-padding=\"16\"\n >\n <header class=\"e-pop-head\">\n <h3 :id=\"`${uid}-columns`\" class=\"e-pop-title\">{{ t(\"showColumns\") }}</h3>\n <PopoverClose as-child>\n <EIconButton icon=\"x\" :label=\"t('close')\" />\n </PopoverClose>\n </header>\n <div class=\"e-pop-body\">\n <ECheckbox\n v-for=\"column in table.getAllLeafColumns()\"\n :key=\"column.id\"\n :label=\"colByKey.get(column.id)?.label ?? column.id\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"column.toggleVisibility($event)\"\n />\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <slot name=\"toolbar\" />\n </div>\n </div>\n <div ref=\"scrollEl\" class=\"e-grid-scroll\" :style=\"scrollStyle\" tabindex=\"0\" role=\"region\" :aria-label=\"caption\">\n <table\n class=\"e-table e-gridtable\"\n :class=\"{ 'e-gridtable--virtual': vopt }\"\n :style=\"tableStyle\"\n :role=\"role('table')\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :aria-rowcount=\"vopt ? total + 1 + (hasFilterRow ? 1 : 0) : undefined\"\n >\n <caption class=\"e-sr\">\n {{\n caption\n }}\n </caption>\n <colgroup v-if=\"fixedLayout\">\n <col v-if=\"selectable\" style=\"width: 52px\" />\n <col v-for=\"c in cols\" :key=\"c.key\" :style=\"widthOf(c) ? { width: `${widthOf(c)}px` } : undefined\" />\n </colgroup>\n <thead :role=\"role('rowgroup')\">\n <tr :role=\"role('row')\">\n <th v-if=\"selectable\" scope=\"col\" class=\"e-cell-check\" :role=\"role('columnheader')\">\n <ECheckbox\n bare\n :label=\"vopt ? t('selectAll') : t('selectAllPage')\"\n :model-value=\"allOn\"\n :indeterminate=\"someOn && !allOn\"\n @update:model-value=\"table.toggleAllPageRowsSelected(!allOn)\"\n />\n </th>\n <th\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n scope=\"col\"\n :role=\"role('columnheader')\"\n :class=\"{ 'e-num': c.numeric, 'e-center': c.align === 'center', 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n :aria-sort=\"\n c.sortable\n ? sort?.key === c.key\n ? sort.dir === 'asc'\n ? 'ascending'\n : 'descending'\n : 'none'\n : undefined\n \"\n >\n <button\n v-if=\"c.sortable\"\n type=\"button\"\n class=\"e-sortbtn\"\n @click=\"table.getColumn(c.key)?.toggleSorting()\"\n >\n <slot :name=\"`header-${c.key}`\" :column=\"c\">{{ c.label }}</slot>\n <EIcon\n :name=\"sort?.key === c.key ? (sort.dir === 'asc' ? 'arrow-up' : 'arrow-down') : 'sort'\"\n small\n />\n </button>\n <slot v-else :name=\"`header-${c.key}`\" :column=\"c\">{{ c.label }}</slot>\n <EDataGridResizer\n v-if=\"resizable && c.resizable !== false\"\n :label=\"c.label\"\n :width=\"widthOf(c)\"\n :min=\"c.minWidth || 72\"\n @resize=\"setWidth(c.key, $event)\"\n @reset=\"resetWidth(c.key)\"\n />\n </th>\n </tr>\n <tr v-if=\"hasFilterRow\" class=\"e-filterrow\" :role=\"role('row')\">\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\" />\n <td\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n :role=\"role('cell')\"\n :class=\"{ 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n >\n <template v-if=\"c.filter\">\n <ESelect\n v-if=\"c.filter.type === 'select'\"\n bare\n :aria-label=\"t('filterColumn', { col: c.label })\"\n :placeholder=\"t('all')\"\n :options=\"selectOptions(c)\"\n :model-value=\"textFilter(c.key) || ALL\"\n @update:model-value=\"setFilter(c.key, $event === ALL ? '' : $event)\"\n />\n <div v-else-if=\"c.filter.type === 'number'\" class=\"e-filter-range\">\n <ETextField\n hide-label\n inputmode=\"decimal\"\n :label=\"t('minOf', { col: t('filterColumn', { col: c.label }) })\"\n :placeholder=\"t('min')\"\n :model-value=\"numberFilter(c.key).min\"\n @update:model-value=\"setFilter(c.key, { min: $event, max: numberFilter(c.key).max })\"\n />\n <ETextField\n hide-label\n inputmode=\"decimal\"\n :label=\"t('maxOf', { col: t('filterColumn', { col: c.label }) })\"\n :placeholder=\"t('max')\"\n :model-value=\"numberFilter(c.key).max\"\n @update:model-value=\"setFilter(c.key, { min: numberFilter(c.key).min, max: $event })\"\n />\n </div>\n <ETextField\n v-else\n hide-label\n type=\"search\"\n :label=\"t('filterColumn', { col: c.label })\"\n :placeholder=\"t('filter')\"\n :model-value=\"textFilter(c.key)\"\n @update:model-value=\"setFilter(c.key, $event)\"\n />\n </template>\n </td>\n </tr>\n </thead>\n <tbody :role=\"role('rowgroup')\">\n <template v-if=\"loading\">\n <tr v-for=\"n in 5\" :key=\"`s${n}`\" :role=\"role('row')\">\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\" />\n <td v-for=\"c in cols\" :key=\"c.key\" :role=\"role('cell')\"><span class=\"e-skel\" /></td>\n </tr>\n </template>\n <tr v-else-if=\"view.length === 0\" :role=\"role('row')\">\n <td :colspan=\"colCount\" class=\"e-grid-empty\" :role=\"role('cell')\">\n <EEmptyState bare :icon=\"emptyIcon || 'search'\" :title=\"emptyTitle || t('noResults')\">\n {{ emptyText || (anyFilter || q ? t(\"noMatchesFilters\") : t(\"nothingYet\")) }}\n <template v-if=\"anyFilter || q\" #action>\n <EButton variant=\"outline\" @click=\"clearFilters\">{{ t(\"clearFilters\") }}</EButton>\n </template>\n </EEmptyState>\n </td>\n </tr>\n <template v-else>\n <tr v-if=\"vopt && spaceTop > 0\" aria-hidden=\"true\" class=\"e-spacer\" :style=\"{ height: `${spaceTop}px` }\">\n <td :colspan=\"colCount\" />\n </tr>\n <tr\n v-for=\"{ row, index } in rowsToRender\"\n :key=\"row.id\"\n :role=\"role('row')\"\n :data-selected=\"row.getIsSelected() ? '' : undefined\"\n :aria-rowindex=\"vopt ? index + 2 + (hasFilterRow ? 1 : 0) : undefined\"\n >\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\">\n <ECheckbox\n bare\n :label=\"t('selectRow')\"\n :model-value=\"row.getIsSelected()\"\n @update:model-value=\"row.toggleSelected($event)\"\n />\n </td>\n <td\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n :role=\"role('cell')\"\n :data-label=\"c.label\"\n :class=\"{ 'e-num': c.numeric, 'e-center': c.align === 'center', 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n >\n <slot :name=\"`cell-${c.key}`\" v-bind=\"cellProps(row, c)\">{{ row.original[c.key] }}</slot>\n </td>\n </tr>\n <tr\n v-if=\"vopt && spaceBottom > 0\"\n aria-hidden=\"true\"\n class=\"e-spacer\"\n :style=\"{ height: `${spaceBottom}px` }\"\n >\n <td :colspan=\"colCount\" />\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div v-if=\"!bare\" class=\"e-grid-foot\">\n <span class=\"e-grid-range\">{{\n total === 0\n ? t(\"rows\", { n: 0 })\n : vopt || pageSize === 0\n ? t(\"rows\", { n: total })\n : t(\"showing\", { from, to, total })\n }}</span>\n <EPagination\n v-if=\"pageSize > 0 && pages > 1\"\n :model-value=\"cur\"\n :page-count=\"pages\"\n @update:model-value=\"page = $event\"\n />\n </div>\n <span class=\"e-sr\" role=\"status\" aria-live=\"polite\">{{\n loading\n ? t(\"loading\")\n : (sortedCol\n ? t(\"sortedBy\", { col: sortedCol.label, dir: t(sort?.dir === \"asc\" ? \"ascending\" : \"descending\") }) + \" \"\n : \"\") + t(\"rowsAnnounce\", { n: total })\n }}</span>\n </div>\n </div>\n</template>\n\n<style>\n@layer e.containers {\n .e-skel {\n display: block;\n height: 14px;\n border-radius: var(--e-radius-sm);\n background: var(--e-surface-tint);\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-border);\n animation: e-pulse 1.4s ease-in-out infinite;\n }\n\n @keyframes e-pulse {\n 50% {\n opacity: 0.5;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-skel {\n animation: none;\n }\n }\n\n .e-grid {\n --e-grid-head-h: 45px;\n\n isolation: isolate;\n border-radius: var(--e-radius-md);\n min-width: 0;\n }\n\n .e-grid-frame::after {\n content: \"\";\n position: absolute;\n inset: 0;\n z-index: var(--e-z-sticky);\n border-radius: inherit;\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-border-strong);\n pointer-events: none;\n }\n\n .e-grid-frame {\n position: relative;\n overflow: hidden;\n border-radius: inherit;\n background: var(--e-surface);\n }\n\n .e-grid-bar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--e-space-3);\n padding: var(--e-space-3) var(--e-space-4);\n border-bottom: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid-search {\n flex: 1 1 10rem;\n max-width: 24rem;\n }\n\n .e-grid-search .e-input {\n padding-inline-start: var(--e-space-2);\n }\n\n .e-grid-picked {\n display: flex;\n align-items: center;\n gap: var(--e-space-3);\n }\n\n .e-grid-count {\n font: 600 var(--e-text-xs) / 1 var(--e-font-mono);\n letter-spacing: 0.04em;\n }\n\n .e-grid-tools {\n margin-inline-start: auto;\n display: flex;\n gap: var(--e-space-2);\n }\n\n .e-grid-scroll {\n overflow: auto;\n max-height: var(--e-grid-max-h, none);\n }\n\n .e-grid-scroll:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n }\n\n .e-gridtable {\n border-radius: 0;\n box-shadow: none;\n min-width: var(--e-grid-min-w, 0);\n }\n\n .e-gridtable thead th {\n position: sticky;\n top: 0;\n z-index: var(--e-z-raised);\n height: var(--e-grid-head-h);\n box-sizing: border-box;\n }\n\n .e-gridtable th[aria-sort=\"ascending\"],\n .e-gridtable th[aria-sort=\"descending\"] {\n color: var(--e-ink);\n }\n\n .e-sortbtn {\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-1);\n min-height: var(--e-control-height);\n padding: var(--e-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n text-transform: inherit;\n cursor: pointer;\n }\n\n .e-sortbtn:hover {\n color: var(--e-ink);\n }\n\n .e-sortbtn:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n border-radius: var(--e-radius-sm);\n }\n\n .e-gridtable .e-cell-check {\n width: 52px;\n padding-inline-end: 0;\n vertical-align: middle;\n }\n\n .e-gridtable tbody tr[data-selected] td {\n background: var(--e-surface-tint);\n }\n\n .e-gridtable tbody tr[data-selected]:hover td {\n background: var(--e-surface-hover);\n box-shadow: inset 0 0 0 0 transparent;\n }\n\n .e-table td.e-grid-empty {\n padding: 0;\n }\n\n .e-grid-foot {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--e-space-3);\n padding: var(--e-space-3) var(--e-space-4);\n border-top: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid-range {\n font: 500 var(--e-text-xs) / 1.2 var(--e-font-mono);\n color: var(--e-muted);\n font-variant-numeric: tabular-nums;\n }\n\n .e-grid-foot .e-pager {\n justify-content: flex-end;\n }\n\n .e-filterrow td {\n padding: var(--e-space-1) var(--e-space-3);\n background: var(--e-surface);\n box-shadow: inset 0 calc(-1 * var(--e-stroke-card)) 0 var(--e-border-strong);\n border-top: 0;\n position: sticky;\n top: var(--e-grid-head-h);\n z-index: var(--e-z-raised);\n }\n\n .e-filterrow .e-input {\n height: var(--e-control-height);\n font-size: var(--e-text-md);\n padding-inline: calc(var(--e-space-3) - var(--e-stroke-edge));\n }\n\n .e-filterrow .e-sel-trigger {\n height: var(--e-control-height);\n padding-inline-end: calc(var(--e-space-2) - var(--e-stroke-edge));\n }\n\n .e-filter-range {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--e-space-1);\n }\n\n .e-gridtable thead th,\n .e-gridtable thead td {\n white-space: nowrap;\n }\n\n .e-resizer {\n position: absolute;\n top: 0;\n inset-inline-end: calc(var(--e-space-6) / -2);\n z-index: var(--e-z-raised);\n width: var(--e-space-6);\n height: 100%;\n cursor: col-resize;\n touch-action: none;\n }\n\n .e-resizer::before {\n content: \"\";\n position: absolute;\n inset-block: 0;\n inset-inline: -10px;\n }\n\n .e-resizer::after {\n content: \"\";\n position: absolute;\n top: 22%;\n inset-inline-start: 11px;\n width: var(--e-stroke-hair);\n height: 56%;\n background: var(--e-border-strong);\n transition: width var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-resizer:hover::after,\n .e-resizer:focus-visible::after {\n inset-inline-start: 10px;\n width: 3px;\n background: var(--e-primary);\n border-radius: var(--e-radius-sm);\n }\n\n .e-resizer:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n border-radius: var(--e-radius-sm);\n }\n\n .e-gridtable[style*=\"table-layout\"] td,\n .e-gridtable[style*=\"table-layout\"] th {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .e-gridtable .e-sticky {\n position: sticky;\n z-index: var(--e-z-raised);\n box-shadow: inset calc(-1 * var(--e-stroke-hair)) 0 0 var(--e-border);\n }\n\n .e-gridtable thead th.e-sticky {\n z-index: var(--e-z-sticky);\n background: var(--e-surface-tint);\n }\n\n .e-gridtable tbody td.e-sticky {\n background: var(--e-surface);\n }\n\n .e-gridtable tbody tr:hover td.e-sticky {\n background: var(--e-surface-hover);\n }\n\n .e-gridtable tbody tr[data-selected] td.e-sticky {\n background: var(--e-surface-tint);\n }\n\n .e-gridtable--virtual td {\n height: var(--e-row-h);\n padding-block: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .e-spacer td {\n padding: 0;\n border: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-resizer::after {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-gridtable tbody tr[data-selected] td {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .e-resizer::after {\n background: CanvasText;\n }\n\n .e-resizer:hover::after,\n .e-resizer:focus-visible::after {\n background: Highlight;\n }\n\n .e-skel {\n background: GrayText;\n }\n }\n\n @media print {\n .e-grid-scroll {\n overflow: visible;\n max-height: none;\n }\n }\n\n .e-grid--cards {\n container-type: inline-size;\n }\n\n .e-grid-sortsel {\n display: none;\n min-width: 11rem;\n }\n\n .e-grid-bar--sortonly {\n display: none;\n }\n\n @container (max-width: 40rem) {\n .e-grid-sortsel {\n display: block;\n flex: 1 1 11rem;\n }\n\n .e-grid-bar--sortonly {\n display: flex;\n }\n\n .e-grid--cards .e-grid-scroll {\n overflow: visible;\n max-height: none;\n }\n\n .e-grid--cards .e-gridtable,\n .e-grid--cards .e-gridtable tbody {\n display: block;\n min-width: 0;\n width: 100%;\n }\n\n .e-grid--cards .e-gridtable thead {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n /* stylelint-disable-next-line property-no-deprecated -- clip hides text visually */\n clip: rect(0 0 0 0);\n white-space: nowrap;\n }\n\n .e-grid--cards .e-grid-frame {\n overflow: visible;\n background: transparent;\n }\n\n .e-grid--cards .e-grid-frame::after {\n content: none;\n }\n\n .e-grid--cards .e-gridtable tbody tr {\n display: block;\n margin: 0 0 var(--e-space-3);\n padding: var(--e-space-1) var(--e-space-4);\n border-radius: var(--e-radius-md);\n background: var(--e-surface);\n box-shadow: var(--e-edge);\n }\n\n .e-grid--cards .e-gridtable tbody tr:hover td {\n background: transparent;\n }\n\n .e-grid--cards .e-gridtable tbody tr[data-selected] {\n background: var(--e-surface-tint);\n }\n\n .e-grid--cards .e-gridtable tbody tr[data-selected] td {\n background: transparent;\n }\n\n .e-grid--cards .e-gridtable td {\n display: grid;\n grid-template-columns: minmax(5rem, 38%) minmax(0, 1fr);\n gap: var(--e-space-3);\n align-items: baseline;\n padding: var(--e-space-2) 0;\n border-top: var(--e-stroke-hair) solid var(--e-border);\n overflow: visible;\n white-space: normal;\n text-align: start;\n }\n\n .e-grid--cards .e-gridtable tbody tr:first-child td:not(:first-child) {\n border-top: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid--cards .e-gridtable tbody td:first-child {\n border-top: 0;\n }\n\n .e-grid--cards .e-gridtable td::before {\n content: attr(data-label);\n font: 600 var(--e-text-xs) / 1.3 var(--e-font-mono);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--e-muted);\n }\n\n .e-grid--cards .e-gridtable td.e-cell-check {\n display: flex;\n width: auto;\n padding: var(--e-space-2) 0;\n }\n\n .e-grid--cards .e-gridtable td.e-cell-check::before {\n content: none;\n }\n\n .e-grid--cards .e-gridtable .e-sticky {\n position: static;\n box-shadow: none;\n }\n\n .e-grid--cards .e-gridtable .e-num {\n text-align: start;\n }\n\n .e-grid--cards .e-gridtable .e-grid-empty {\n display: block;\n }\n\n .e-grid--cards .e-gridtable .e-grid-empty::before {\n content: none;\n }\n\n .e-grid--cards .e-filterrow {\n display: none;\n }\n\n .e-grid--cards .e-gridtable[style*=\"table-layout\"] td {\n overflow: visible;\n text-overflow: clip;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EDataGrid.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_useModel","_openBlock","_createElementBlock","_normalizeClass","_createElementVNode","_createVNode","EIcon","_unref","_createCommentVNode","_toDisplayString","_renderSlot","ESelect","_createBlock","EButton","_withCtx","_createTextVNode","EIconButton","_Fragment","_renderList","ECheckbox","_normalizeStyle","EDataGridResizer","ETextField","EEmptyState","_createSlots","_mergeProps","EPagination","EIcon_default","EButton_default","EIconButton_default","ECheckbox_default","EEmptyState_default","EPagination_default","ESelect_default","ETextField_default","EDataGridResizer_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","_hoisted_16","\"width\"","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","ALL","NONE","EDataGrid_vue_vue_type_script_setup_true_lang_default","\"sort\"","\"sortModifiers\"","\"page\"","\"pageModifiers\"","\"search\"","\"searchModifiers\"","\"filters\"","\"filtersModifiers\"","\"selected\"","\"selectedModifiers\"","__emit","props","__props","emit","slots","useSlots","sort","useModel","page","search","filters","selected","t","useMessages","portal","usePortalTarget","uid","useUid","menuOpen","ref","menuTrigger","open","nextTick","features","tableFeatures","createSortedRowModel","createFilteredRowModel","createPaginatedRowModel","columnVisibility","columnSizing","sortFn","compareValues","a","id","b","globalFilterFn","f","v","row","colByKey","computed","c","columnDefs","cellValue","passesFilter","vopt","pageSize","paging","resizable","cards","q","anyFilter","filterActive","table","useTable","key","value","first","functionalUpdate","updater","next","k","view","total","pages","cur","n","cols","hasFilterRow","colCount","from","to","sortedCol","nPicked","allOn","r","someOn","scrollEl","virtualizer","useVirtualizer","i","items","shown","spaceTop","spaceBottom","last","rowsToRender","cellProps","fixedLayout","stickyLeft","widthOf","parsePx","minTable","s","stick","stickStyle","tableStyle","scrollStyle","role","sortables","sortOptions","d","sortSelectValue","showSortSelect","hasToolbar","barOther","showBar","onSearch","setFilter","clearFilters","chooseSort","at","setWidth","old","px","resetWidth","numberFilter","textFilter","selectOptions","normalizeOptions","watch","openBlock","createElementBlock","normalizeClass","createElementVNode","createVNode","unref","createCommentVNode","toDisplayString","renderSlot","_ctx","createBlock","withCtx","createTextVNode","PopoverRoot","_cache","$event","PopoverTrigger","PopoverPortal","PopoverContent","PopoverClose","Fragment","renderList","column","normalizeStyle","createSlots","index","mergeProps"],"sources":["../../../src/components/DataGrid/EDataGrid.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"Row extends DataGridRow\">\nimport { computed, nextTick, ref, watch, type CSSProperties } from \"vue\";\nimport { PopoverClose, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from \"reka-ui\";\nimport {\n columnFilteringFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n createFilteredRowModel,\n createPaginatedRowModel,\n createSortedRowModel,\n functionalUpdate,\n globalFilteringFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n rowSortingFeature,\n tableFeatures,\n useTable,\n type ColumnDef,\n type FilterFn,\n type SortFn,\n} from \"@tanstack/vue-table\";\nimport { useVirtualizer } from \"@tanstack/vue-virtual\";\nimport EButton from \"../Button/EButton.vue\";\nimport ECheckbox from \"../Checkbox/ECheckbox.vue\";\nimport EEmptyState from \"../EmptyState/EEmptyState.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport EIconButton from \"../IconButton/EIconButton.vue\";\nimport EPagination from \"../Pagination/EPagination.vue\";\nimport ESelect from \"../Select/ESelect.vue\";\nimport ETextField from \"../TextField/ETextField.vue\";\nimport EDataGridResizer from \"./EDataGridResizer.vue\";\nimport \"../Definition/EDefinition.vue\";\nimport { normalizeOptions, type EOption } from \"../Select/options.js\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport { useMessages, usePortalTarget } from \"../../config.js\";\nimport { useUid } from \"../../composables/useUid.js\";\nimport { cellValue, compareValues, filterActive, parsePx, passesFilter } from \"./grid.js\";\nimport type {\n DataGridColumn,\n DataGridFilterValue,\n DataGridQuery,\n DataGridRow,\n DataGridSort,\n DataGridVirtual,\n} from \"./types.js\";\nimport \"../../styles/base.css\";\nimport \"../Table/table.css\";\nimport \"../TextField/input.css\";\nimport \"../Select/panel.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** The columns, in order. See `DataGridColumn` below. */\n columns: DataGridColumn<Row>[];\n /** The rows. Each needs a unique `id`; selection is by id. */\n rows: Row[];\n /** Names the table for screen readers, and its scrolling region. */\n caption: string;\n /** One search box over all shown columns. */\n searchable?: boolean;\n /** The search box's placeholder. @default \"Search all columns\" */\n searchPlaceholder?: string;\n /** A filter row under the headings, for columns that define a `filter`. */\n filterable?: boolean;\n /** Column edges can be dragged, or moved with the arrow keys. */\n resizable?: boolean;\n /** Keeps the first column in view while scrolling sideways. */\n stickyFirst?: boolean;\n /** A Columns menu to show and hide columns. */\n columnToggle?: boolean;\n /** A checkbox on each row and a select-all in the heading. */\n selectable?: boolean;\n /** Rows per page; 0 turns paging off. */\n pageSize?: number;\n /** Stops the table growing past this height (any CSS length) and scrolls inside it, with a sticky header. */\n maxHeight?: string;\n /** Renders only the rows in view, for thousands of rows. Replaces paging. `true` or `{ rowHeight = 48, height = 440, overscan = 8 }`. */\n virtual?: boolean | DataGridVirtual;\n /** Turns rows into cards below 40rem of the grid's own width. `virtual` and `resizable` grids keep the table. */\n cards?: boolean;\n /** Data lives on a server: show the rows given, in the order given, and report every change through `queryChange`. */\n manual?: boolean;\n /** With `manual`, how many rows there are in all. */\n total?: number;\n /** Shows placeholder rows while data loads, with `aria-busy`. */\n loading?: boolean;\n /** The title when there are no rows. @default \"No results\" */\n emptyTitle?: string;\n /** The sentence under the empty title, when there are no rows. */\n emptyText?: string;\n /** The icon above the empty title. @default \"search\" */\n emptyIcon?: IconProp;\n /** No chrome: a bare table for a short static list, with no toolbar, filters, paging or footer. */\n bare?: boolean;\n }>(),\n { pageSize: 10, cards: true },\n);\n\nconst emit = defineEmits<{\n /** Sort, page, search or filters changed. With `manual`, fetch the rows this describes. */\n queryChange: [query: DataGridQuery];\n}>();\n\nconst slots = defineSlots<{\n [K: `cell-${string}`]: (props: { row: Row; value: unknown }) => unknown;\n [K: `header-${string}`]: (props: { column: DataGridColumn<Row> }) => unknown;\n /** Buttons that act on the selected rows, shown beside the count. */\n \"bulk-actions\"?: () => unknown;\n /** Anything else for the bar above the table. */\n toolbar?: () => unknown;\n}>();\n\n/** The sort: `{ key, dir: \"asc\" | \"desc\" }`, or `null` for none. */\nconst sort = defineModel<DataGridSort | null>(\"sort\", { default: null });\n/** The current page, from 1. */\nconst page = defineModel<number>(\"page\", { default: 1 });\n/** The text in the search box. */\nconst search = defineModel<string>(\"search\", { default: \"\" });\n/** The column filters, by column `key`: text, or `{ min, max }` strings for `number`. */\nconst filters = defineModel<Record<string, DataGridFilterValue>>(\"filters\", { default: () => ({}) });\n/** The selected row ids, kept across pages and filters. */\nconst selected = defineModel<string[]>(\"selected\", { default: () => [] });\n\nconst t = useMessages();\nconst portal = usePortalTarget();\n\nconst uid = useUid();\nconst menuOpen = ref(false);\nconst menuTrigger = ref<{ $el: HTMLElement } | null>(null);\nwatch(\n menuOpen,\n async (open) => {\n if (!open) return;\n await nextTick();\n const panel = document.getElementById(menuTrigger.value?.$el?.getAttribute(\"aria-controls\") ?? \"\");\n panel?.setAttribute(\"aria-labelledby\", `${uid.value}-columns`);\n },\n { flush: \"post\" },\n);\n\nconst ALL = \"__e-all__\";\nconst NONE = \"__e-none__\";\n\nconst features = tableFeatures({\n rowSortingFeature,\n sortedRowModel: createSortedRowModel(),\n columnFilteringFeature,\n globalFilteringFeature,\n filteredRowModel: createFilteredRowModel(),\n rowPaginationFeature,\n paginatedRowModel: createPaginatedRowModel(),\n rowSelectionFeature,\n columnVisibilityFeature,\n columnSizingFeature,\n});\n\nconst columnVisibility = ref<Record<string, boolean>>({});\nconst columnSizing = ref<Record<string, number>>({});\n\nconst sortFn: SortFn<typeof features, Row> = (a, b, id) => compareValues(a.getValue(id), b.getValue(id));\ntype GlobalFilter = { q: string; cols: string[] };\nconst globalFilterFn: FilterFn<typeof features, Row> = (row, id, f: GlobalFilter) => {\n if (!f.cols.includes(id)) return false;\n const v = row.getValue(id);\n return v != null && String(v).toLowerCase().includes(f.q);\n};\n\nconst colByKey = computed(() => new Map(props.columns.map((c) => [c.key, c])));\nconst columnDefs = computed<ColumnDef<typeof features, Row>[]>(() =>\n props.columns.map((c) => ({\n id: c.key,\n accessorFn: (row: Row) => cellValue(row, c),\n header: c.label,\n enableSorting: !!c.sortable,\n sortDescFirst: false,\n sortFn,\n enableColumnFilter: !!c.filter,\n filterFn: ((row, id, f) => passesFilter(c, row.getValue(id), f)) as FilterFn<typeof features, Row>,\n enableResizing: c.resizable !== false,\n })),\n);\n\nconst vopt = computed(() =>\n props.virtual ? { rowHeight: 48, height: 440, overscan: 8, ...(props.virtual === true ? {} : props.virtual) } : null,\n);\nconst pageSize = computed(() => (vopt.value || props.bare ? 0 : (props.pageSize ?? 10)));\nconst paging = computed(() => pageSize.value > 0 && !props.manual);\nconst resizable = computed(() => !!props.resizable && !props.bare);\nconst cards = computed(() => props.cards !== false && !vopt.value && !resizable.value);\nconst q = computed(() => search.value.trim().toLowerCase());\nconst anyFilter = computed(() => Object.values(filters.value).some(filterActive));\n\nconst table = useTable({\n features,\n columns: columnDefs,\n data: computed(() => props.rows),\n getRowId: (row: Row) => String(row.id),\n enableMultiSort: false,\n enableSubRowSelection: false,\n autoResetPageIndex: false,\n manualSorting: computed(() => !!props.manual),\n manualFiltering: computed(() => !!props.manual),\n manualPagination: computed(() => !paging.value),\n rowCount: computed(() => (props.manual ? (props.total ?? props.rows.length) : undefined)),\n globalFilterFn,\n state: computed(() => ({\n sorting: sort.value ? [{ id: sort.value.key, desc: sort.value.dir === \"desc\" }] : [],\n columnFilters: Object.entries(filters.value)\n .filter(([key, value]) => colByKey.value.has(key) && filterActive(value))\n .map(([id, value]) => ({ id, value })),\n globalFilter: q.value\n ? ({\n q: q.value,\n cols: props.columns.filter((c) => columnVisibility.value[c.key] !== false).map((c) => c.key),\n } satisfies GlobalFilter)\n : undefined,\n rowSelection: Object.fromEntries(selected.value.map((id) => [id, true])),\n columnVisibility: columnVisibility.value,\n columnSizing: columnSizing.value,\n pagination: { pageIndex: Math.max(0, page.value - 1), pageSize: pageSize.value || 1 },\n })),\n onSortingChange: (updater) => {\n const next = functionalUpdate(updater, sort.value ? [{ id: sort.value.key, desc: sort.value.dir === \"desc\" }] : []);\n const first = next[0];\n sort.value = first ? { key: first.id, dir: first.desc ? \"desc\" : \"asc\" } : null;\n page.value = 1;\n },\n onRowSelectionChange: (updater) => {\n const next = functionalUpdate(updater, Object.fromEntries(selected.value.map((id) => [id, true])));\n selected.value = Object.keys(next).filter((k) => next[k]);\n },\n onColumnVisibilityChange: (updater) => {\n columnVisibility.value = functionalUpdate(updater, columnVisibility.value);\n },\n onColumnSizingChange: (updater) => {\n columnSizing.value = functionalUpdate(updater, columnSizing.value);\n },\n});\n\nconst view = computed(() => table.getRowModel().rows);\nconst total = computed(() =>\n props.manual ? (props.total ?? props.rows.length) : table.getPrePaginatedRowModel().rows.length,\n);\nconst pages = computed(() => (pageSize.value > 0 ? Math.max(1, Math.ceil(total.value / pageSize.value)) : 1));\nconst cur = computed(() => Math.min(page.value, pages.value));\nwatch(pages, (n) => {\n if (page.value > n) page.value = n;\n});\nconst cols = computed(() =>\n table\n .getVisibleLeafColumns()\n .map((c) => colByKey.value.get(c.id))\n .filter((c): c is DataGridColumn<Row> => !!c),\n);\nconst hasFilterRow = computed(() => !!props.filterable && !props.bare && cols.value.some((c) => c.filter));\nconst colCount = computed(() => cols.value.length + (props.selectable ? 1 : 0));\nconst from = computed(() =>\n total.value === 0 ? 0 : (cur.value - 1) * (pageSize.value > 0 ? pageSize.value : total.value) + 1,\n);\nconst to = computed(() => (pageSize.value > 0 ? Math.min(total.value, cur.value * pageSize.value) : total.value));\nconst sortedCol = computed(() => (sort.value ? colByKey.value.get(sort.value.key) : undefined));\nconst nPicked = computed(() => selected.value.length);\nconst allOn = computed(() => view.value.length > 0 && view.value.every((r) => r.getIsSelected()));\nconst someOn = computed(() => view.value.some((r) => r.getIsSelected()));\n\nconst scrollEl = ref<HTMLElement | null>(null);\nconst virtualizer = useVirtualizer(\n computed(() => ({\n count: vopt.value ? view.value.length : 0,\n getScrollElement: () => scrollEl.value,\n estimateSize: () => vopt.value?.rowHeight ?? 48,\n overscan: vopt.value?.overscan ?? 8,\n getItemKey: (i: number) => view.value[i]?.id ?? i,\n initialRect: { width: 0, height: vopt.value?.height ?? 0 },\n })),\n);\nconst items = computed(() => (vopt.value ? virtualizer.value.getVirtualItems() : []));\nconst shown = computed(() => (vopt.value ? items.value.flatMap((i) => (view.value[i.index] ? [i] : [])) : []));\nconst spaceTop = computed(() => items.value[0]?.start ?? 0);\nconst spaceBottom = computed(() => {\n const last = items.value[items.value.length - 1];\n return last ? Math.max(0, virtualizer.value.getTotalSize() - last.end) : 0;\n});\nconst rowsToRender = computed(() =>\n vopt.value\n ? shown.value.map((i) => ({ row: view.value[i.index]!, index: i.index }))\n : view.value.map((row, index) => ({ row, index })),\n);\n\nconst cellProps = (row: (typeof view.value)[number], c: DataGridColumn<Row>) => ({\n row: row.original,\n value: row.getValue(c.key),\n});\n\nconst fixedLayout = computed(() => resizable.value || !!vopt.value || cols.value.some((c) => c.width));\nconst stickyLeft = computed(() => (props.selectable ? 52 : 0));\nconst widthOf = (c: DataGridColumn<Row>) => columnSizing.value[c.key] || parsePx(c.width) || undefined;\nconst minTable = computed(\n () => (props.selectable ? 52 : 0) + cols.value.reduce((s, c) => s + (widthOf(c) || c.minWidth || 96), 0),\n);\nconst stick = (i: number) => !!props.stickyFirst && i === 0;\nconst stickStyle = (i: number): CSSProperties | undefined =>\n stick(i) ? { insetInlineStart: `${stickyLeft.value}px` } : undefined;\nconst tableStyle = computed(\n () =>\n ({\n tableLayout: fixedLayout.value ? \"fixed\" : undefined,\n \"--e-grid-min-w\": fixedLayout.value ? `${minTable.value}px` : undefined,\n \"--e-row-h\": vopt.value ? `${vopt.value.rowHeight}px` : undefined,\n }) as CSSProperties,\n);\nconst scrollStyle = computed(\n () =>\n (vopt.value\n ? { height: `${vopt.value.height}px` }\n : props.maxHeight\n ? { \"--e-grid-max-h\": props.maxHeight }\n : undefined) as CSSProperties | undefined,\n);\nconst role = (r: string) => (cards.value ? r : undefined);\n\nconst sortables = computed(() => props.columns.filter((c) => c.sortable));\nconst sortOptions = computed<EOption[]>(() => [\n { value: NONE, label: t(\"sortBy\") },\n ...sortables.value.flatMap((c) =>\n ([\"asc\", \"desc\"] as const).map((d) => ({\n value: `${c.key}:${d}`,\n label: `${c.label}, ${t(d === \"asc\" ? \"ascending\" : \"descending\")}`,\n })),\n ),\n]);\nconst sortSelectValue = computed(() => (sort.value ? `${sort.value.key}:${sort.value.dir}` : NONE));\nconst showSortSelect = computed(() => cards.value && sortables.value.length > 0);\nconst hasToolbar = computed(() => !!slots.toolbar);\nconst barOther = computed(\n () => !!props.searchable || !!props.columnToggle || nPicked.value > 0 || anyFilter.value || hasToolbar.value,\n);\nconst showBar = computed(() => !props.bare && (barOther.value || showSortSelect.value));\n\nfunction onSearch(e: Event) {\n search.value = (e.target as HTMLInputElement).value;\n page.value = 1;\n}\nfunction setFilter(key: string, value: DataGridFilterValue) {\n filters.value = { ...filters.value, [key]: value };\n page.value = 1;\n}\nfunction clearFilters() {\n filters.value = {};\n search.value = \"\";\n page.value = 1;\n}\nfunction chooseSort(v: string) {\n if (v === NONE) sort.value = null;\n else {\n const at = v.lastIndexOf(\":\");\n sort.value = { key: v.slice(0, at), dir: v.slice(at + 1) === \"desc\" ? \"desc\" : \"asc\" };\n }\n page.value = 1;\n}\nfunction setWidth(key: string, px: number) {\n table.setColumnSizing((old) => ({ ...old, [key]: px }));\n}\nfunction resetWidth(key: string) {\n table.setColumnSizing((old) => {\n const next = { ...old };\n delete next[key];\n return next;\n });\n}\nconst numberFilter = (key: string) => {\n const f = filters.value[key];\n return typeof f === \"object\" ? f : { min: \"\", max: \"\" };\n};\nconst textFilter = (key: string) => {\n const f = filters.value[key];\n return typeof f === \"string\" ? f : \"\";\n};\nconst selectOptions = (c: DataGridColumn<Row>): EOption[] => [\n { value: ALL, label: t(\"all\") },\n ...normalizeOptions(c.filter?.type === \"select\" ? c.filter.options : []),\n];\n\nwatch([sort, page, search, filters], () => {\n emit(\"queryChange\", {\n sort: sort.value,\n page: page.value,\n pageSize: pageSize.value,\n search: search.value,\n filters: filters.value,\n });\n});\n</script>\n\n<template>\n <div class=\"e-grid\" :class=\"{ 'e-grid--bare': bare, 'e-grid--cards': cards }\">\n <div class=\"e-grid-frame\">\n <div v-if=\"showBar\" class=\"e-grid-bar\" :class=\"{ 'e-grid-bar--sortonly': !barOther }\">\n <div v-if=\"searchable\" class=\"e-input-wrap e-grid-search\">\n <span class=\"e-affix e-affix--pre\"><EIcon name=\"search\" /></span>\n <input\n class=\"e-input\"\n type=\"search\"\n :placeholder=\"searchPlaceholder || t('searchAll')\"\n :aria-label=\"t('searchAll')\"\n :value=\"search\"\n @input=\"onSearch\"\n />\n </div>\n <div v-if=\"nPicked\" class=\"e-grid-picked\">\n <span class=\"e-grid-count\">{{ t(\"selected\", { n: nPicked }) }}</span>\n <slot name=\"bulk-actions\" />\n </div>\n <div v-if=\"showSortSelect\" class=\"e-grid-sortsel\">\n <ESelect\n bare\n :aria-label=\"t('sortBy')\"\n :placeholder=\"t('sortBy')\"\n :options=\"sortOptions\"\n :model-value=\"sortSelectValue\"\n @update:model-value=\"chooseSort\"\n />\n </div>\n <div class=\"e-grid-tools\">\n <EButton v-if=\"anyFilter || q\" variant=\"quiet\" @click=\"clearFilters\">{{ t(\"clearFilters\") }}</EButton>\n <PopoverRoot v-if=\"columnToggle\" v-model:open=\"menuOpen\">\n <PopoverTrigger as-child>\n <EButton ref=\"menuTrigger\" variant=\"outline\" :aria-label=\"t('chooseColumns')\">{{ t(\"columns\") }}</EButton>\n </PopoverTrigger>\n <PopoverPortal :to=\"portal\">\n <PopoverContent\n class=\"e-popover e-root\"\n side=\"bottom\"\n align=\"start\"\n :side-offset=\"8\"\n :collision-padding=\"16\"\n >\n <header class=\"e-pop-head\">\n <h3 :id=\"`${uid}-columns`\" class=\"e-pop-title\">{{ t(\"showColumns\") }}</h3>\n <PopoverClose as-child>\n <EIconButton icon=\"x\" :label=\"t('close')\" />\n </PopoverClose>\n </header>\n <div class=\"e-pop-body\">\n <ECheckbox\n v-for=\"column in table.getAllLeafColumns()\"\n :key=\"column.id\"\n :label=\"colByKey.get(column.id)?.label ?? column.id\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"column.toggleVisibility($event)\"\n />\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <slot name=\"toolbar\" />\n </div>\n </div>\n <div ref=\"scrollEl\" class=\"e-grid-scroll\" :style=\"scrollStyle\" tabindex=\"0\" role=\"region\" :aria-label=\"caption\">\n <table\n class=\"e-table e-gridtable\"\n :class=\"{ 'e-gridtable--virtual': vopt }\"\n :style=\"tableStyle\"\n :role=\"role('table')\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :aria-rowcount=\"vopt ? total + 1 + (hasFilterRow ? 1 : 0) : undefined\"\n >\n <caption class=\"e-sr\">\n {{\n caption\n }}\n </caption>\n <colgroup v-if=\"fixedLayout\">\n <col v-if=\"selectable\" style=\"width: 52px\" />\n <col v-for=\"c in cols\" :key=\"c.key\" :style=\"widthOf(c) ? { width: `${widthOf(c)}px` } : undefined\" />\n </colgroup>\n <thead :role=\"role('rowgroup')\">\n <tr :role=\"role('row')\">\n <th v-if=\"selectable\" scope=\"col\" class=\"e-cell-check\" :role=\"role('columnheader')\">\n <ECheckbox\n bare\n :label=\"vopt ? t('selectAll') : t('selectAllPage')\"\n :model-value=\"allOn\"\n :indeterminate=\"someOn && !allOn\"\n @update:model-value=\"table.toggleAllPageRowsSelected(!allOn)\"\n />\n </th>\n <th\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n scope=\"col\"\n :role=\"role('columnheader')\"\n :class=\"{ 'e-num': c.numeric, 'e-center': c.align === 'center', 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n :aria-sort=\"\n c.sortable\n ? sort?.key === c.key\n ? sort.dir === 'asc'\n ? 'ascending'\n : 'descending'\n : 'none'\n : undefined\n \"\n >\n <button\n v-if=\"c.sortable\"\n type=\"button\"\n class=\"e-sortbtn\"\n @click=\"table.getColumn(c.key)?.toggleSorting()\"\n >\n <slot :name=\"`header-${c.key}`\" :column=\"c\">{{ c.label }}</slot>\n <EIcon\n :name=\"sort?.key === c.key ? (sort.dir === 'asc' ? 'arrow-up' : 'arrow-down') : 'sort'\"\n small\n />\n </button>\n <slot v-else :name=\"`header-${c.key}`\" :column=\"c\">{{ c.label }}</slot>\n <EDataGridResizer\n v-if=\"resizable && c.resizable !== false\"\n :label=\"c.label\"\n :width=\"widthOf(c)\"\n :min=\"c.minWidth || 72\"\n @resize=\"setWidth(c.key, $event)\"\n @reset=\"resetWidth(c.key)\"\n />\n </th>\n </tr>\n <tr v-if=\"hasFilterRow\" class=\"e-filterrow\" :role=\"role('row')\">\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\" />\n <td\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n :role=\"role('cell')\"\n :class=\"{ 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n >\n <template v-if=\"c.filter\">\n <ESelect\n v-if=\"c.filter.type === 'select'\"\n bare\n :aria-label=\"t('filterColumn', { col: c.label })\"\n :placeholder=\"t('all')\"\n :options=\"selectOptions(c)\"\n :model-value=\"textFilter(c.key) || ALL\"\n @update:model-value=\"setFilter(c.key, $event === ALL ? '' : $event)\"\n />\n <div v-else-if=\"c.filter.type === 'number'\" class=\"e-filter-range\">\n <ETextField\n hide-label\n inputmode=\"decimal\"\n :label=\"t('minOf', { col: t('filterColumn', { col: c.label }) })\"\n :placeholder=\"t('min')\"\n :model-value=\"numberFilter(c.key).min\"\n @update:model-value=\"setFilter(c.key, { min: $event, max: numberFilter(c.key).max })\"\n />\n <ETextField\n hide-label\n inputmode=\"decimal\"\n :label=\"t('maxOf', { col: t('filterColumn', { col: c.label }) })\"\n :placeholder=\"t('max')\"\n :model-value=\"numberFilter(c.key).max\"\n @update:model-value=\"setFilter(c.key, { min: numberFilter(c.key).min, max: $event })\"\n />\n </div>\n <ETextField\n v-else\n hide-label\n type=\"search\"\n :label=\"t('filterColumn', { col: c.label })\"\n :placeholder=\"t('filter')\"\n :model-value=\"textFilter(c.key)\"\n @update:model-value=\"setFilter(c.key, $event)\"\n />\n </template>\n </td>\n </tr>\n </thead>\n <tbody :role=\"role('rowgroup')\">\n <template v-if=\"loading\">\n <tr v-for=\"n in 5\" :key=\"`s${n}`\" :role=\"role('row')\">\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\" />\n <td v-for=\"c in cols\" :key=\"c.key\" :role=\"role('cell')\"><span class=\"e-skel\" /></td>\n </tr>\n </template>\n <tr v-else-if=\"view.length === 0\" :role=\"role('row')\">\n <td :colspan=\"colCount\" class=\"e-grid-empty\" :role=\"role('cell')\">\n <EEmptyState bare :icon=\"emptyIcon || 'search'\" :title=\"emptyTitle || t('noResults')\">\n {{ emptyText || (anyFilter || q ? t(\"noMatchesFilters\") : t(\"nothingYet\")) }}\n <template v-if=\"anyFilter || q\" #action>\n <EButton variant=\"outline\" @click=\"clearFilters\">{{ t(\"clearFilters\") }}</EButton>\n </template>\n </EEmptyState>\n </td>\n </tr>\n <template v-else>\n <tr v-if=\"vopt && spaceTop > 0\" aria-hidden=\"true\" class=\"e-spacer\" :style=\"{ height: `${spaceTop}px` }\">\n <td :colspan=\"colCount\" />\n </tr>\n <tr\n v-for=\"{ row, index } in rowsToRender\"\n :key=\"row.id\"\n :role=\"role('row')\"\n :data-selected=\"row.getIsSelected() ? '' : undefined\"\n :aria-rowindex=\"vopt ? index + 2 + (hasFilterRow ? 1 : 0) : undefined\"\n >\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\">\n <ECheckbox\n bare\n :label=\"t('selectRow')\"\n :model-value=\"row.getIsSelected()\"\n @update:model-value=\"row.toggleSelected($event)\"\n />\n </td>\n <td\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n :role=\"role('cell')\"\n :data-label=\"c.label\"\n :class=\"{ 'e-num': c.numeric, 'e-center': c.align === 'center', 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n >\n <slot :name=\"`cell-${c.key}`\" v-bind=\"cellProps(row, c)\">{{ row.original[c.key] }}</slot>\n </td>\n </tr>\n <tr\n v-if=\"vopt && spaceBottom > 0\"\n aria-hidden=\"true\"\n class=\"e-spacer\"\n :style=\"{ height: `${spaceBottom}px` }\"\n >\n <td :colspan=\"colCount\" />\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div v-if=\"!bare\" class=\"e-grid-foot\">\n <span class=\"e-grid-range\">{{\n total === 0\n ? t(\"rows\", { n: 0 })\n : vopt || pageSize === 0\n ? t(\"rows\", { n: total })\n : t(\"showing\", { from, to, total })\n }}</span>\n <EPagination\n v-if=\"pageSize > 0 && pages > 1\"\n :model-value=\"cur\"\n :page-count=\"pages\"\n @update:model-value=\"page = $event\"\n />\n </div>\n <span class=\"e-sr\" role=\"status\" aria-live=\"polite\">{{\n loading\n ? t(\"loading\")\n : (sortedCol\n ? t(\"sortedBy\", { col: sortedCol.label, dir: t(sort?.dir === \"asc\" ? \"ascending\" : \"descending\") }) + \" \"\n : \"\") + t(\"rowsAnnounce\", { n: total })\n }}</span>\n </div>\n </div>\n</template>\n\n<style>\n@layer e.containers {\n .e-skel {\n display: block;\n height: 14px;\n border-radius: var(--e-radius-sm);\n background: var(--e-surface-tint);\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-border);\n animation: e-pulse 1.4s ease-in-out infinite;\n }\n\n @keyframes e-pulse {\n 50% {\n opacity: 0.5;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-skel {\n animation: none;\n }\n }\n\n .e-grid {\n --e-grid-head-h: 45px;\n\n isolation: isolate;\n border-radius: var(--e-radius-md);\n min-width: 0;\n }\n\n .e-grid-frame::after {\n content: \"\";\n position: absolute;\n inset: 0;\n z-index: var(--e-z-sticky);\n border-radius: inherit;\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-border-strong);\n pointer-events: none;\n }\n\n .e-grid-frame {\n position: relative;\n overflow: hidden;\n border-radius: inherit;\n background: var(--e-surface);\n }\n\n .e-grid-bar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--e-space-3);\n padding: var(--e-space-3) var(--e-space-4);\n border-bottom: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid-search {\n flex: 1 1 10rem;\n max-width: 24rem;\n }\n\n .e-grid-search .e-input {\n padding-inline-start: var(--e-space-2);\n }\n\n .e-grid-picked {\n display: flex;\n align-items: center;\n gap: var(--e-space-3);\n }\n\n .e-grid-count {\n font: 600 var(--e-text-xs) / 1 var(--e-font-mono);\n letter-spacing: 0.04em;\n }\n\n .e-grid-tools {\n margin-inline-start: auto;\n display: flex;\n gap: var(--e-space-2);\n }\n\n .e-grid-scroll {\n overflow: auto;\n max-height: var(--e-grid-max-h, none);\n }\n\n .e-grid-scroll:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n }\n\n .e-gridtable {\n border-radius: 0;\n box-shadow: none;\n min-width: var(--e-grid-min-w, 0);\n }\n\n .e-gridtable thead th {\n position: sticky;\n top: 0;\n z-index: var(--e-z-raised);\n height: var(--e-grid-head-h);\n box-sizing: border-box;\n }\n\n .e-gridtable th[aria-sort=\"ascending\"],\n .e-gridtable th[aria-sort=\"descending\"] {\n color: var(--e-ink);\n }\n\n .e-sortbtn {\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-1);\n min-height: var(--e-control-height);\n padding: var(--e-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n text-transform: inherit;\n cursor: pointer;\n }\n\n .e-sortbtn:hover {\n color: var(--e-ink);\n }\n\n .e-sortbtn:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n border-radius: var(--e-radius-sm);\n }\n\n .e-gridtable .e-cell-check {\n width: 52px;\n padding-inline-end: 0;\n vertical-align: middle;\n }\n\n .e-gridtable tbody tr[data-selected] td {\n background: var(--e-surface-tint);\n }\n\n .e-gridtable tbody tr[data-selected]:hover td {\n background: var(--e-surface-hover);\n box-shadow: inset 0 0 0 0 transparent;\n }\n\n .e-table td.e-grid-empty {\n padding: 0;\n }\n\n .e-grid-foot {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--e-space-3);\n padding: var(--e-space-3) var(--e-space-4);\n border-top: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid-range {\n font: 500 var(--e-text-xs) / 1.2 var(--e-font-mono);\n color: var(--e-muted);\n font-variant-numeric: tabular-nums;\n }\n\n .e-grid-foot .e-pager {\n justify-content: flex-end;\n }\n\n .e-filterrow td {\n padding: var(--e-space-1) var(--e-space-3);\n background: var(--e-surface);\n box-shadow: inset 0 calc(-1 * var(--e-stroke-card)) 0 var(--e-border-strong);\n border-top: 0;\n position: sticky;\n top: var(--e-grid-head-h);\n z-index: var(--e-z-raised);\n }\n\n .e-filterrow .e-input {\n height: var(--e-control-height);\n font-size: var(--e-text-md);\n padding-inline: var(--e-space-3);\n }\n\n .e-filterrow .e-sel-trigger {\n height: var(--e-control-height);\n padding-inline-end: var(--e-space-2);\n }\n\n .e-filter-range {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--e-space-1);\n }\n\n .e-gridtable thead th,\n .e-gridtable thead td {\n white-space: nowrap;\n }\n\n .e-resizer {\n position: absolute;\n top: 0;\n inset-inline-end: calc(var(--e-space-6) / -2);\n z-index: var(--e-z-raised);\n width: var(--e-space-6);\n height: 100%;\n cursor: col-resize;\n touch-action: none;\n }\n\n .e-resizer::before {\n content: \"\";\n position: absolute;\n inset-block: 0;\n inset-inline: -10px;\n }\n\n .e-resizer::after {\n content: \"\";\n position: absolute;\n top: 22%;\n inset-inline-start: 11px;\n width: var(--e-stroke-hair);\n height: 56%;\n background: var(--e-border-strong);\n transition: width var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-resizer:hover::after,\n .e-resizer:focus-visible::after {\n inset-inline-start: 10px;\n width: 3px;\n background: var(--e-primary);\n border-radius: var(--e-radius-sm);\n }\n\n .e-resizer:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n border-radius: var(--e-radius-sm);\n }\n\n .e-gridtable[style*=\"table-layout\"] td,\n .e-gridtable[style*=\"table-layout\"] th {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .e-gridtable .e-sticky {\n position: sticky;\n z-index: var(--e-z-raised);\n box-shadow: inset calc(-1 * var(--e-stroke-hair)) 0 0 var(--e-border);\n }\n\n .e-gridtable thead th.e-sticky {\n z-index: var(--e-z-sticky);\n background: var(--e-surface-tint);\n }\n\n .e-gridtable tbody td.e-sticky {\n background: var(--e-surface);\n }\n\n .e-gridtable tbody tr:hover td.e-sticky {\n background: var(--e-surface-hover);\n }\n\n .e-gridtable tbody tr[data-selected] td.e-sticky {\n background: var(--e-surface-tint);\n }\n\n .e-gridtable--virtual td {\n height: var(--e-row-h);\n padding-block: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .e-spacer td {\n padding: 0;\n border: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-resizer::after {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-gridtable tbody tr[data-selected] td {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .e-resizer::after {\n background: CanvasText;\n }\n\n .e-resizer:hover::after,\n .e-resizer:focus-visible::after {\n background: Highlight;\n }\n\n .e-skel {\n background: GrayText;\n }\n }\n\n @media print {\n .e-grid-scroll {\n overflow: visible;\n max-height: none;\n }\n }\n\n .e-grid--cards {\n container-type: inline-size;\n }\n\n .e-grid-sortsel {\n display: none;\n min-width: 11rem;\n }\n\n .e-grid-bar--sortonly {\n display: none;\n }\n\n @container (max-width: 40rem) {\n .e-grid-sortsel {\n display: block;\n flex: 1 1 11rem;\n }\n\n .e-grid-bar--sortonly {\n display: flex;\n }\n\n .e-grid--cards .e-grid-scroll {\n overflow: visible;\n max-height: none;\n }\n\n .e-grid--cards .e-gridtable,\n .e-grid--cards .e-gridtable tbody {\n display: block;\n min-width: 0;\n width: 100%;\n }\n\n .e-grid--cards .e-gridtable thead {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n /* stylelint-disable-next-line property-no-deprecated -- clip hides text visually */\n clip: rect(0 0 0 0);\n white-space: nowrap;\n }\n\n .e-grid--cards .e-grid-frame {\n overflow: visible;\n background: transparent;\n }\n\n .e-grid--cards .e-grid-frame::after {\n content: none;\n }\n\n .e-grid--cards .e-gridtable tbody tr {\n display: block;\n margin: 0 0 var(--e-space-3);\n padding: var(--e-space-1) var(--e-space-4);\n border-radius: var(--e-radius-md);\n background: var(--e-surface);\n box-shadow: var(--e-edge);\n }\n\n .e-grid--cards .e-gridtable tbody tr:hover td {\n background: transparent;\n }\n\n .e-grid--cards .e-gridtable tbody tr[data-selected] {\n background: var(--e-surface-tint);\n }\n\n .e-grid--cards .e-gridtable tbody tr[data-selected] td {\n background: transparent;\n }\n\n .e-grid--cards .e-gridtable td {\n display: grid;\n grid-template-columns: minmax(5rem, 38%) minmax(0, 1fr);\n gap: var(--e-space-3);\n align-items: baseline;\n padding: var(--e-space-2) 0;\n border-top: var(--e-stroke-hair) solid var(--e-border);\n overflow: visible;\n white-space: normal;\n text-align: start;\n }\n\n .e-grid--cards .e-gridtable tbody tr:first-child td:not(:first-child) {\n border-top: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid--cards .e-gridtable tbody td:first-child {\n border-top: 0;\n }\n\n .e-grid--cards .e-gridtable td::before {\n content: attr(data-label);\n font: 600 var(--e-text-xs) / 1.3 var(--e-font-mono);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--e-muted);\n }\n\n .e-grid--cards .e-gridtable td.e-cell-check {\n display: flex;\n width: auto;\n padding: var(--e-space-2) 0;\n }\n\n .e-grid--cards .e-gridtable td.e-cell-check::before {\n content: none;\n }\n\n .e-grid--cards .e-gridtable .e-sticky {\n position: static;\n box-shadow: none;\n }\n\n .e-grid--cards .e-gridtable .e-num {\n text-align: start;\n }\n\n .e-grid--cards .e-gridtable .e-grid-empty {\n display: block;\n }\n\n .e-grid--cards .e-gridtable .e-grid-empty::before {\n content: none;\n }\n\n .e-grid--cards .e-filterrow {\n display: none;\n }\n\n .e-grid--cards .e-gridtable[style*=\"table-layout\"] td {\n overflow: visible;\n text-overflow: clip;\n }\n }\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EDataGrid.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_useModel","_openBlock","_createElementBlock","_normalizeClass","_createElementVNode","_createVNode","EIcon","_unref","_createCommentVNode","_toDisplayString","_renderSlot","ESelect","_createBlock","EButton","_withCtx","_createTextVNode","EIconButton","_Fragment","_renderList","ECheckbox","_normalizeStyle","EDataGridResizer","ETextField","EEmptyState","_createSlots","_mergeProps","EPagination","EIcon_default","EButton_default","EIconButton_default","ECheckbox_default","EEmptyState_default","EPagination_default","ESelect_default","ETextField_default","EDataGridResizer_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","_hoisted_16","\"width\"","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","ALL","NONE","EDataGrid_vue_vue_type_script_setup_true_lang_default","\"sort\"","\"sortModifiers\"","\"page\"","\"pageModifiers\"","\"search\"","\"searchModifiers\"","\"filters\"","\"filtersModifiers\"","\"selected\"","\"selectedModifiers\"","__emit","props","__props","emit","slots","useSlots","sort","useModel","page","search","filters","selected","t","useMessages","portal","usePortalTarget","uid","useUid","menuOpen","ref","menuTrigger","open","nextTick","features","tableFeatures","createSortedRowModel","createFilteredRowModel","createPaginatedRowModel","columnVisibility","columnSizing","sortFn","compareValues","a","id","b","globalFilterFn","f","v","row","colByKey","computed","c","columnDefs","cellValue","passesFilter","vopt","pageSize","paging","resizable","cards","q","anyFilter","filterActive","table","useTable","key","value","first","functionalUpdate","updater","next","k","view","total","pages","cur","n","cols","hasFilterRow","colCount","from","to","sortedCol","nPicked","allOn","r","someOn","scrollEl","virtualizer","useVirtualizer","i","items","shown","spaceTop","spaceBottom","last","rowsToRender","cellProps","fixedLayout","stickyLeft","widthOf","parsePx","minTable","s","stick","stickStyle","tableStyle","scrollStyle","role","sortables","sortOptions","d","sortSelectValue","showSortSelect","hasToolbar","barOther","showBar","onSearch","setFilter","clearFilters","chooseSort","at","setWidth","old","px","resetWidth","numberFilter","textFilter","selectOptions","normalizeOptions","watch","openBlock","createElementBlock","normalizeClass","createElementVNode","createVNode","unref","createCommentVNode","toDisplayString","renderSlot","_ctx","createBlock","withCtx","createTextVNode","PopoverRoot","_cache","$event","PopoverTrigger","PopoverPortal","PopoverContent","PopoverClose","Fragment","renderList","column","normalizeStyle","createSlots","index","mergeProps"],"sources":["../../../src/components/DataGrid/EDataGrid.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"Row extends DataGridRow\">\nimport { computed, nextTick, ref, watch, type CSSProperties } from \"vue\";\nimport { PopoverClose, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from \"reka-ui\";\nimport {\n columnFilteringFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n createFilteredRowModel,\n createPaginatedRowModel,\n createSortedRowModel,\n functionalUpdate,\n globalFilteringFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n rowSortingFeature,\n tableFeatures,\n useTable,\n type ColumnDef,\n type FilterFn,\n type SortFn,\n} from \"@tanstack/vue-table\";\nimport { useVirtualizer } from \"@tanstack/vue-virtual\";\nimport EButton from \"../Button/EButton.vue\";\nimport ECheckbox from \"../Checkbox/ECheckbox.vue\";\nimport EEmptyState from \"../EmptyState/EEmptyState.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport EIconButton from \"../IconButton/EIconButton.vue\";\nimport EPagination from \"../Pagination/EPagination.vue\";\nimport ESelect from \"../Select/ESelect.vue\";\nimport ETextField from \"../TextField/ETextField.vue\";\nimport EDataGridResizer from \"./EDataGridResizer.vue\";\nimport \"../Definition/EDefinition.vue\";\nimport { normalizeOptions, type EOption } from \"../Select/options.js\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport { useMessages, usePortalTarget } from \"../../config.js\";\nimport { useUid } from \"../../composables/useUid.js\";\nimport { cellValue, compareValues, filterActive, parsePx, passesFilter } from \"./grid.js\";\nimport type {\n DataGridColumn,\n DataGridFilterValue,\n DataGridQuery,\n DataGridRow,\n DataGridSort,\n DataGridVirtual,\n} from \"./types.js\";\nimport \"../../styles/base.css\";\nimport \"../Table/table.css\";\nimport \"../TextField/input.css\";\nimport \"../Select/panel.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** The columns, in order. See `DataGridColumn` below. */\n columns: DataGridColumn<Row>[];\n /** The rows. Each needs a unique `id`; selection is by id. */\n rows: Row[];\n /** Names the table for screen readers, and its scrolling region. */\n caption: string;\n /** One search box over all shown columns. */\n searchable?: boolean;\n /** The search box's placeholder. @default \"Search all columns\" */\n searchPlaceholder?: string;\n /** A filter row under the headings, for columns that define a `filter`. */\n filterable?: boolean;\n /** Column edges can be dragged, or moved with the arrow keys. */\n resizable?: boolean;\n /** Keeps the first column in view while scrolling sideways. */\n stickyFirst?: boolean;\n /** A Columns menu to show and hide columns. */\n columnToggle?: boolean;\n /** A checkbox on each row and a select-all in the heading. */\n selectable?: boolean;\n /** Rows per page; 0 turns paging off. */\n pageSize?: number;\n /** Stops the table growing past this height (any CSS length) and scrolls inside it, with a sticky header. */\n maxHeight?: string;\n /** Renders only the rows in view, for thousands of rows. Replaces paging. `true` or `{ rowHeight = 48, height = 440, overscan = 8 }`. */\n virtual?: boolean | DataGridVirtual;\n /** Turns rows into cards below 40rem of the grid's own width. `virtual` and `resizable` grids keep the table. */\n cards?: boolean;\n /** Data lives on a server: show the rows given, in the order given, and report every change through `queryChange`. */\n manual?: boolean;\n /** With `manual`, how many rows there are in all. */\n total?: number;\n /** Shows placeholder rows while data loads, with `aria-busy`. */\n loading?: boolean;\n /** The title when there are no rows. @default \"No results\" */\n emptyTitle?: string;\n /** The sentence under the empty title, when there are no rows. */\n emptyText?: string;\n /** The icon above the empty title. @default \"search\" */\n emptyIcon?: IconProp;\n /** No chrome: a bare table for a short static list, with no toolbar, filters, paging or footer. */\n bare?: boolean;\n }>(),\n { pageSize: 10, cards: true },\n);\n\nconst emit = defineEmits<{\n /** Sort, page, search or filters changed. With `manual`, fetch the rows this describes. */\n queryChange: [query: DataGridQuery];\n}>();\n\nconst slots = defineSlots<{\n [K: `cell-${string}`]: (props: { row: Row; value: unknown }) => unknown;\n [K: `header-${string}`]: (props: { column: DataGridColumn<Row> }) => unknown;\n /** Buttons that act on the selected rows, shown beside the count. */\n \"bulk-actions\"?: () => unknown;\n /** Anything else for the bar above the table. */\n toolbar?: () => unknown;\n}>();\n\n/** The sort: `{ key, dir: \"asc\" | \"desc\" }`, or `null` for none. */\nconst sort = defineModel<DataGridSort | null>(\"sort\", { default: null });\n/** The current page, from 1. */\nconst page = defineModel<number>(\"page\", { default: 1 });\n/** The text in the search box. */\nconst search = defineModel<string>(\"search\", { default: \"\" });\n/** The column filters, by column `key`: text, or `{ min, max }` strings for `number`. */\nconst filters = defineModel<Record<string, DataGridFilterValue>>(\"filters\", { default: () => ({}) });\n/** The selected row ids, kept across pages and filters. */\nconst selected = defineModel<string[]>(\"selected\", { default: () => [] });\n\nconst t = useMessages();\nconst portal = usePortalTarget();\n\nconst uid = useUid();\nconst menuOpen = ref(false);\nconst menuTrigger = ref<{ $el: HTMLElement } | null>(null);\nwatch(\n menuOpen,\n async (open) => {\n if (!open) return;\n await nextTick();\n const panel = document.getElementById(menuTrigger.value?.$el?.getAttribute(\"aria-controls\") ?? \"\");\n panel?.setAttribute(\"aria-labelledby\", `${uid.value}-columns`);\n },\n { flush: \"post\" },\n);\n\nconst ALL = \"__e-all__\";\nconst NONE = \"__e-none__\";\n\nconst features = tableFeatures({\n rowSortingFeature,\n sortedRowModel: createSortedRowModel(),\n columnFilteringFeature,\n globalFilteringFeature,\n filteredRowModel: createFilteredRowModel(),\n rowPaginationFeature,\n paginatedRowModel: createPaginatedRowModel(),\n rowSelectionFeature,\n columnVisibilityFeature,\n columnSizingFeature,\n});\n\nconst columnVisibility = ref<Record<string, boolean>>({});\nconst columnSizing = ref<Record<string, number>>({});\n\nconst sortFn: SortFn<typeof features, Row> = (a, b, id) => compareValues(a.getValue(id), b.getValue(id));\ntype GlobalFilter = { q: string; cols: string[] };\nconst globalFilterFn: FilterFn<typeof features, Row> = (row, id, f: GlobalFilter) => {\n if (!f.cols.includes(id)) return false;\n const v = row.getValue(id);\n return v != null && String(v).toLowerCase().includes(f.q);\n};\n\nconst colByKey = computed(() => new Map(props.columns.map((c) => [c.key, c])));\nconst columnDefs = computed<ColumnDef<typeof features, Row>[]>(() =>\n props.columns.map((c) => ({\n id: c.key,\n accessorFn: (row: Row) => cellValue(row, c),\n header: c.label,\n enableSorting: !!c.sortable,\n sortDescFirst: false,\n sortFn,\n enableColumnFilter: !!c.filter,\n filterFn: ((row, id, f) => passesFilter(c, row.getValue(id), f)) as FilterFn<typeof features, Row>,\n enableResizing: c.resizable !== false,\n })),\n);\n\nconst vopt = computed(() =>\n props.virtual ? { rowHeight: 48, height: 440, overscan: 8, ...(props.virtual === true ? {} : props.virtual) } : null,\n);\nconst pageSize = computed(() => (vopt.value || props.bare ? 0 : (props.pageSize ?? 10)));\nconst paging = computed(() => pageSize.value > 0 && !props.manual);\nconst resizable = computed(() => !!props.resizable && !props.bare);\nconst cards = computed(() => props.cards !== false && !vopt.value && !resizable.value);\nconst q = computed(() => search.value.trim().toLowerCase());\nconst anyFilter = computed(() => Object.values(filters.value).some(filterActive));\n\nconst table = useTable({\n features,\n columns: columnDefs,\n data: computed(() => props.rows),\n getRowId: (row: Row) => String(row.id),\n enableMultiSort: false,\n enableSubRowSelection: false,\n autoResetPageIndex: false,\n manualSorting: computed(() => !!props.manual),\n manualFiltering: computed(() => !!props.manual),\n manualPagination: computed(() => !paging.value),\n rowCount: computed(() => (props.manual ? (props.total ?? props.rows.length) : undefined)),\n globalFilterFn,\n state: computed(() => ({\n sorting: sort.value ? [{ id: sort.value.key, desc: sort.value.dir === \"desc\" }] : [],\n columnFilters: Object.entries(filters.value)\n .filter(([key, value]) => colByKey.value.has(key) && filterActive(value))\n .map(([id, value]) => ({ id, value })),\n globalFilter: q.value\n ? ({\n q: q.value,\n cols: props.columns.filter((c) => columnVisibility.value[c.key] !== false).map((c) => c.key),\n } satisfies GlobalFilter)\n : undefined,\n rowSelection: Object.fromEntries(selected.value.map((id) => [id, true])),\n columnVisibility: columnVisibility.value,\n columnSizing: columnSizing.value,\n pagination: { pageIndex: Math.max(0, page.value - 1), pageSize: pageSize.value || 1 },\n })),\n onSortingChange: (updater) => {\n const next = functionalUpdate(updater, sort.value ? [{ id: sort.value.key, desc: sort.value.dir === \"desc\" }] : []);\n const first = next[0];\n sort.value = first ? { key: first.id, dir: first.desc ? \"desc\" : \"asc\" } : null;\n page.value = 1;\n },\n onRowSelectionChange: (updater) => {\n const next = functionalUpdate(updater, Object.fromEntries(selected.value.map((id) => [id, true])));\n selected.value = Object.keys(next).filter((k) => next[k]);\n },\n onColumnVisibilityChange: (updater) => {\n columnVisibility.value = functionalUpdate(updater, columnVisibility.value);\n },\n onColumnSizingChange: (updater) => {\n columnSizing.value = functionalUpdate(updater, columnSizing.value);\n },\n});\n\nconst view = computed(() => table.getRowModel().rows);\nconst total = computed(() =>\n props.manual ? (props.total ?? props.rows.length) : table.getPrePaginatedRowModel().rows.length,\n);\nconst pages = computed(() => (pageSize.value > 0 ? Math.max(1, Math.ceil(total.value / pageSize.value)) : 1));\nconst cur = computed(() => Math.min(page.value, pages.value));\nwatch(pages, (n) => {\n if (page.value > n) page.value = n;\n});\nconst cols = computed(() =>\n table\n .getVisibleLeafColumns()\n .map((c) => colByKey.value.get(c.id))\n .filter((c): c is DataGridColumn<Row> => !!c),\n);\nconst hasFilterRow = computed(() => !!props.filterable && !props.bare && cols.value.some((c) => c.filter));\nconst colCount = computed(() => cols.value.length + (props.selectable ? 1 : 0));\nconst from = computed(() =>\n total.value === 0 ? 0 : (cur.value - 1) * (pageSize.value > 0 ? pageSize.value : total.value) + 1,\n);\nconst to = computed(() => (pageSize.value > 0 ? Math.min(total.value, cur.value * pageSize.value) : total.value));\nconst sortedCol = computed(() => (sort.value ? colByKey.value.get(sort.value.key) : undefined));\nconst nPicked = computed(() => selected.value.length);\nconst allOn = computed(() => view.value.length > 0 && view.value.every((r) => r.getIsSelected()));\nconst someOn = computed(() => view.value.some((r) => r.getIsSelected()));\n\nconst scrollEl = ref<HTMLElement | null>(null);\nconst virtualizer = useVirtualizer(\n computed(() => ({\n count: vopt.value ? view.value.length : 0,\n getScrollElement: () => scrollEl.value,\n estimateSize: () => vopt.value?.rowHeight ?? 48,\n overscan: vopt.value?.overscan ?? 8,\n getItemKey: (i: number) => view.value[i]?.id ?? i,\n initialRect: { width: 0, height: vopt.value?.height ?? 0 },\n })),\n);\nconst items = computed(() => (vopt.value ? virtualizer.value.getVirtualItems() : []));\nconst shown = computed(() => (vopt.value ? items.value.flatMap((i) => (view.value[i.index] ? [i] : [])) : []));\nconst spaceTop = computed(() => items.value[0]?.start ?? 0);\nconst spaceBottom = computed(() => {\n const last = items.value[items.value.length - 1];\n return last ? Math.max(0, virtualizer.value.getTotalSize() - last.end) : 0;\n});\nconst rowsToRender = computed(() =>\n vopt.value\n ? shown.value.map((i) => ({ row: view.value[i.index]!, index: i.index }))\n : view.value.map((row, index) => ({ row, index })),\n);\n\nconst cellProps = (row: (typeof view.value)[number], c: DataGridColumn<Row>) => ({\n row: row.original,\n value: row.getValue(c.key),\n});\n\nconst fixedLayout = computed(() => resizable.value || !!vopt.value || cols.value.some((c) => c.width));\nconst stickyLeft = computed(() => (props.selectable ? 52 : 0));\nconst widthOf = (c: DataGridColumn<Row>) => columnSizing.value[c.key] || parsePx(c.width) || undefined;\nconst minTable = computed(\n () => (props.selectable ? 52 : 0) + cols.value.reduce((s, c) => s + (widthOf(c) || c.minWidth || 96), 0),\n);\nconst stick = (i: number) => !!props.stickyFirst && i === 0;\nconst stickStyle = (i: number): CSSProperties | undefined =>\n stick(i) ? { insetInlineStart: `${stickyLeft.value}px` } : undefined;\nconst tableStyle = computed(\n () =>\n ({\n tableLayout: fixedLayout.value ? \"fixed\" : undefined,\n \"--e-grid-min-w\": fixedLayout.value ? `${minTable.value}px` : undefined,\n \"--e-row-h\": vopt.value ? `${vopt.value.rowHeight}px` : undefined,\n }) as CSSProperties,\n);\nconst scrollStyle = computed(\n () =>\n (vopt.value\n ? { height: `${vopt.value.height}px` }\n : props.maxHeight\n ? { \"--e-grid-max-h\": props.maxHeight }\n : undefined) as CSSProperties | undefined,\n);\nconst role = (r: string) => (cards.value ? r : undefined);\n\nconst sortables = computed(() => props.columns.filter((c) => c.sortable));\nconst sortOptions = computed<EOption[]>(() => [\n { value: NONE, label: t(\"sortBy\") },\n ...sortables.value.flatMap((c) =>\n ([\"asc\", \"desc\"] as const).map((d) => ({\n value: `${c.key}:${d}`,\n label: `${c.label}, ${t(d === \"asc\" ? \"ascending\" : \"descending\")}`,\n })),\n ),\n]);\nconst sortSelectValue = computed(() => (sort.value ? `${sort.value.key}:${sort.value.dir}` : NONE));\nconst showSortSelect = computed(() => cards.value && sortables.value.length > 0);\nconst hasToolbar = computed(() => !!slots.toolbar);\nconst barOther = computed(\n () => !!props.searchable || !!props.columnToggle || nPicked.value > 0 || anyFilter.value || hasToolbar.value,\n);\nconst showBar = computed(() => !props.bare && (barOther.value || showSortSelect.value));\n\nfunction onSearch(e: Event) {\n search.value = (e.target as HTMLInputElement).value;\n page.value = 1;\n}\nfunction setFilter(key: string, value: DataGridFilterValue) {\n filters.value = { ...filters.value, [key]: value };\n page.value = 1;\n}\nfunction clearFilters() {\n filters.value = {};\n search.value = \"\";\n page.value = 1;\n}\nfunction chooseSort(v: string) {\n if (v === NONE) sort.value = null;\n else {\n const at = v.lastIndexOf(\":\");\n sort.value = { key: v.slice(0, at), dir: v.slice(at + 1) === \"desc\" ? \"desc\" : \"asc\" };\n }\n page.value = 1;\n}\nfunction setWidth(key: string, px: number) {\n table.setColumnSizing((old) => ({ ...old, [key]: px }));\n}\nfunction resetWidth(key: string) {\n table.setColumnSizing((old) => {\n const next = { ...old };\n delete next[key];\n return next;\n });\n}\nconst numberFilter = (key: string) => {\n const f = filters.value[key];\n return typeof f === \"object\" ? f : { min: \"\", max: \"\" };\n};\nconst textFilter = (key: string) => {\n const f = filters.value[key];\n return typeof f === \"string\" ? f : \"\";\n};\nconst selectOptions = (c: DataGridColumn<Row>): EOption[] => [\n { value: ALL, label: t(\"all\") },\n ...normalizeOptions(c.filter?.type === \"select\" ? c.filter.options : []),\n];\n\nwatch([sort, page, search, filters], () => {\n emit(\"queryChange\", {\n sort: sort.value,\n page: page.value,\n pageSize: pageSize.value,\n search: search.value,\n filters: filters.value,\n });\n});\n</script>\n\n<template>\n <div class=\"e-grid\" :class=\"{ 'e-grid--bare': bare, 'e-grid--cards': cards }\">\n <div class=\"e-grid-frame\">\n <div v-if=\"showBar\" class=\"e-grid-bar\" :class=\"{ 'e-grid-bar--sortonly': !barOther }\">\n <div v-if=\"searchable\" class=\"e-input-wrap e-grid-search\">\n <span class=\"e-affix e-affix--pre\"><EIcon name=\"search\" /></span>\n <input\n class=\"e-input\"\n type=\"search\"\n :placeholder=\"searchPlaceholder || t('searchAll')\"\n :aria-label=\"t('searchAll')\"\n :value=\"search\"\n @input=\"onSearch\"\n />\n </div>\n <div v-if=\"nPicked\" class=\"e-grid-picked\">\n <span class=\"e-grid-count\">{{ t(\"selected\", { n: nPicked }) }}</span>\n <slot name=\"bulk-actions\" />\n </div>\n <div v-if=\"showSortSelect\" class=\"e-grid-sortsel\">\n <ESelect\n bare\n :aria-label=\"t('sortBy')\"\n :placeholder=\"t('sortBy')\"\n :options=\"sortOptions\"\n :model-value=\"sortSelectValue\"\n @update:model-value=\"chooseSort\"\n />\n </div>\n <div class=\"e-grid-tools\">\n <EButton v-if=\"anyFilter || q\" variant=\"quiet\" @click=\"clearFilters\">{{ t(\"clearFilters\") }}</EButton>\n <PopoverRoot v-if=\"columnToggle\" v-model:open=\"menuOpen\">\n <PopoverTrigger as-child>\n <EButton ref=\"menuTrigger\" variant=\"outline\" :aria-label=\"t('chooseColumns')\">{{ t(\"columns\") }}</EButton>\n </PopoverTrigger>\n <PopoverPortal :to=\"portal\">\n <PopoverContent\n class=\"e-popover e-root\"\n side=\"bottom\"\n align=\"start\"\n :side-offset=\"8\"\n :collision-padding=\"16\"\n >\n <header class=\"e-pop-head\">\n <h3 :id=\"`${uid}-columns`\" class=\"e-pop-title\">{{ t(\"showColumns\") }}</h3>\n <PopoverClose as-child>\n <EIconButton icon=\"x\" :label=\"t('close')\" />\n </PopoverClose>\n </header>\n <div class=\"e-pop-body\">\n <ECheckbox\n v-for=\"column in table.getAllLeafColumns()\"\n :key=\"column.id\"\n :label=\"colByKey.get(column.id)?.label ?? column.id\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"column.toggleVisibility($event)\"\n />\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <slot name=\"toolbar\" />\n </div>\n </div>\n <div ref=\"scrollEl\" class=\"e-grid-scroll\" :style=\"scrollStyle\" tabindex=\"0\" role=\"region\" :aria-label=\"caption\">\n <table\n class=\"e-table e-gridtable\"\n :class=\"{ 'e-gridtable--virtual': vopt }\"\n :style=\"tableStyle\"\n :role=\"role('table')\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :aria-rowcount=\"vopt ? total + 1 + (hasFilterRow ? 1 : 0) : undefined\"\n >\n <caption class=\"e-sr\">\n {{\n caption\n }}\n </caption>\n <colgroup v-if=\"fixedLayout\">\n <col v-if=\"selectable\" style=\"width: 52px\" />\n <col v-for=\"c in cols\" :key=\"c.key\" :style=\"widthOf(c) ? { width: `${widthOf(c)}px` } : undefined\" />\n </colgroup>\n <thead :role=\"role('rowgroup')\">\n <tr :role=\"role('row')\">\n <th v-if=\"selectable\" scope=\"col\" class=\"e-cell-check\" :role=\"role('columnheader')\">\n <ECheckbox\n bare\n :label=\"vopt ? t('selectAll') : t('selectAllPage')\"\n :model-value=\"allOn\"\n :indeterminate=\"someOn && !allOn\"\n @update:model-value=\"table.toggleAllPageRowsSelected(!allOn)\"\n />\n </th>\n <th\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n scope=\"col\"\n :role=\"role('columnheader')\"\n :class=\"{ 'e-num': c.numeric, 'e-center': c.align === 'center', 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n :aria-sort=\"\n c.sortable\n ? sort?.key === c.key\n ? sort.dir === 'asc'\n ? 'ascending'\n : 'descending'\n : 'none'\n : undefined\n \"\n >\n <button\n v-if=\"c.sortable\"\n type=\"button\"\n class=\"e-sortbtn\"\n @click=\"table.getColumn(c.key)?.toggleSorting()\"\n >\n <slot :name=\"`header-${c.key}`\" :column=\"c\">{{ c.label }}</slot>\n <EIcon\n :name=\"sort?.key === c.key ? (sort.dir === 'asc' ? 'arrow-up' : 'arrow-down') : 'sort'\"\n small\n />\n </button>\n <slot v-else :name=\"`header-${c.key}`\" :column=\"c\">{{ c.label }}</slot>\n <EDataGridResizer\n v-if=\"resizable && c.resizable !== false\"\n :label=\"c.label\"\n :width=\"widthOf(c)\"\n :min=\"c.minWidth || 72\"\n @resize=\"setWidth(c.key, $event)\"\n @reset=\"resetWidth(c.key)\"\n />\n </th>\n </tr>\n <tr v-if=\"hasFilterRow\" class=\"e-filterrow\" :role=\"role('row')\">\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\" />\n <td\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n :role=\"role('cell')\"\n :class=\"{ 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n >\n <template v-if=\"c.filter\">\n <ESelect\n v-if=\"c.filter.type === 'select'\"\n bare\n :aria-label=\"t('filterColumn', { col: c.label })\"\n :placeholder=\"t('all')\"\n :options=\"selectOptions(c)\"\n :model-value=\"textFilter(c.key) || ALL\"\n @update:model-value=\"setFilter(c.key, $event === ALL ? '' : $event)\"\n />\n <div v-else-if=\"c.filter.type === 'number'\" class=\"e-filter-range\">\n <ETextField\n hide-label\n inputmode=\"decimal\"\n :label=\"t('minOf', { col: t('filterColumn', { col: c.label }) })\"\n :placeholder=\"t('min')\"\n :model-value=\"numberFilter(c.key).min\"\n @update:model-value=\"setFilter(c.key, { min: $event, max: numberFilter(c.key).max })\"\n />\n <ETextField\n hide-label\n inputmode=\"decimal\"\n :label=\"t('maxOf', { col: t('filterColumn', { col: c.label }) })\"\n :placeholder=\"t('max')\"\n :model-value=\"numberFilter(c.key).max\"\n @update:model-value=\"setFilter(c.key, { min: numberFilter(c.key).min, max: $event })\"\n />\n </div>\n <ETextField\n v-else\n hide-label\n type=\"search\"\n :label=\"t('filterColumn', { col: c.label })\"\n :placeholder=\"t('filter')\"\n :model-value=\"textFilter(c.key)\"\n @update:model-value=\"setFilter(c.key, $event)\"\n />\n </template>\n </td>\n </tr>\n </thead>\n <tbody :role=\"role('rowgroup')\">\n <template v-if=\"loading\">\n <tr v-for=\"n in 5\" :key=\"`s${n}`\" :role=\"role('row')\">\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\" />\n <td v-for=\"c in cols\" :key=\"c.key\" :role=\"role('cell')\"><span class=\"e-skel\" /></td>\n </tr>\n </template>\n <tr v-else-if=\"view.length === 0\" :role=\"role('row')\">\n <td :colspan=\"colCount\" class=\"e-grid-empty\" :role=\"role('cell')\">\n <EEmptyState bare :icon=\"emptyIcon || 'search'\" :title=\"emptyTitle || t('noResults')\">\n {{ emptyText || (anyFilter || q ? t(\"noMatchesFilters\") : t(\"nothingYet\")) }}\n <template v-if=\"anyFilter || q\" #action>\n <EButton variant=\"outline\" @click=\"clearFilters\">{{ t(\"clearFilters\") }}</EButton>\n </template>\n </EEmptyState>\n </td>\n </tr>\n <template v-else>\n <tr v-if=\"vopt && spaceTop > 0\" aria-hidden=\"true\" class=\"e-spacer\" :style=\"{ height: `${spaceTop}px` }\">\n <td :colspan=\"colCount\" />\n </tr>\n <tr\n v-for=\"{ row, index } in rowsToRender\"\n :key=\"row.id\"\n :role=\"role('row')\"\n :data-selected=\"row.getIsSelected() ? '' : undefined\"\n :aria-rowindex=\"vopt ? index + 2 + (hasFilterRow ? 1 : 0) : undefined\"\n >\n <td v-if=\"selectable\" class=\"e-cell-check\" :role=\"role('cell')\">\n <ECheckbox\n bare\n :label=\"t('selectRow')\"\n :model-value=\"row.getIsSelected()\"\n @update:model-value=\"row.toggleSelected($event)\"\n />\n </td>\n <td\n v-for=\"(c, i) in cols\"\n :key=\"c.key\"\n :role=\"role('cell')\"\n :data-label=\"c.label\"\n :class=\"{ 'e-num': c.numeric, 'e-center': c.align === 'center', 'e-sticky': stick(i) }\"\n :style=\"stickStyle(i)\"\n >\n <slot :name=\"`cell-${c.key}`\" v-bind=\"cellProps(row, c)\">{{ row.original[c.key] }}</slot>\n </td>\n </tr>\n <tr\n v-if=\"vopt && spaceBottom > 0\"\n aria-hidden=\"true\"\n class=\"e-spacer\"\n :style=\"{ height: `${spaceBottom}px` }\"\n >\n <td :colspan=\"colCount\" />\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <div v-if=\"!bare\" class=\"e-grid-foot\">\n <span class=\"e-grid-range\">{{\n total === 0\n ? t(\"rows\", { n: 0 })\n : vopt || pageSize === 0\n ? t(\"rows\", { n: total })\n : t(\"showing\", { from, to, total })\n }}</span>\n <EPagination\n v-if=\"pageSize > 0 && pages > 1\"\n :model-value=\"cur\"\n :page-count=\"pages\"\n @update:model-value=\"page = $event\"\n />\n </div>\n <span class=\"e-sr\" role=\"status\" aria-live=\"polite\">{{\n loading\n ? t(\"loading\")\n : (sortedCol\n ? t(\"sortedBy\", { col: sortedCol.label, dir: t(sort?.dir === \"asc\" ? \"ascending\" : \"descending\") }) + \" \"\n : \"\") + t(\"rowsAnnounce\", { n: total })\n }}</span>\n </div>\n </div>\n</template>\n\n<style>\n@layer e.containers {\n .e-skel {\n display: block;\n height: 14px;\n border-radius: var(--e-radius-sm);\n background: var(--e-surface-tint);\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-border);\n animation: e-pulse 1.4s ease-in-out infinite;\n }\n\n @keyframes e-pulse {\n 50% {\n opacity: 0.5;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-skel {\n animation: none;\n }\n }\n\n .e-grid {\n --e-grid-head-h: 45px;\n\n isolation: isolate;\n border-radius: var(--e-radius-md);\n min-width: 0;\n }\n\n .e-grid-frame::after {\n content: \"\";\n position: absolute;\n inset: 0;\n z-index: var(--e-z-sticky);\n border-radius: inherit;\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-border-strong);\n pointer-events: none;\n }\n\n .e-grid-frame {\n position: relative;\n overflow: hidden;\n border-radius: inherit;\n background: var(--e-surface);\n }\n\n .e-grid-bar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--e-space-3);\n padding: var(--e-space-3) var(--e-space-4);\n border-bottom: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid-search {\n flex: 1 1 10rem;\n max-width: 24rem;\n }\n\n .e-grid-search .e-input {\n padding-inline-start: var(--e-space-2);\n }\n\n .e-grid-picked {\n display: flex;\n align-items: center;\n gap: var(--e-space-3);\n }\n\n .e-grid-count {\n font: 600 var(--e-text-xs) / 1 var(--e-font-mono);\n letter-spacing: 0.04em;\n }\n\n .e-grid-tools {\n margin-inline-start: auto;\n display: flex;\n gap: var(--e-space-2);\n }\n\n .e-grid-scroll {\n overflow: auto;\n max-height: var(--e-grid-max-h, none);\n }\n\n .e-grid-scroll:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n }\n\n .e-gridtable {\n border-radius: 0;\n box-shadow: none;\n min-width: var(--e-grid-min-w, 0);\n }\n\n .e-gridtable thead th {\n position: sticky;\n top: 0;\n z-index: var(--e-z-raised);\n height: var(--e-grid-head-h);\n box-sizing: border-box;\n }\n\n .e-gridtable th[aria-sort=\"ascending\"],\n .e-gridtable th[aria-sort=\"descending\"] {\n color: var(--e-ink);\n }\n\n .e-sortbtn {\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-1);\n min-height: var(--e-control-height);\n padding: var(--e-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n text-transform: inherit;\n cursor: pointer;\n }\n\n .e-sortbtn:hover {\n color: var(--e-ink);\n }\n\n .e-sortbtn:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n border-radius: var(--e-radius-sm);\n }\n\n .e-gridtable .e-cell-check {\n width: 52px;\n padding-inline-end: 0;\n vertical-align: middle;\n }\n\n .e-gridtable tbody tr[data-selected] td {\n background: var(--e-surface-tint);\n }\n\n .e-gridtable tbody tr[data-selected]:hover td {\n background: var(--e-surface-hover);\n box-shadow: inset 0 0 0 0 transparent;\n }\n\n .e-table td.e-grid-empty {\n padding: 0;\n }\n\n .e-grid-foot {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--e-space-3);\n padding: var(--e-space-3) var(--e-space-4);\n border-top: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid-range {\n font: 500 var(--e-text-xs) / 1.2 var(--e-font-mono);\n color: var(--e-muted);\n font-variant-numeric: tabular-nums;\n }\n\n .e-grid-foot .e-pager {\n justify-content: flex-end;\n }\n\n .e-filterrow td {\n padding: var(--e-space-1) var(--e-space-3);\n background: var(--e-surface);\n box-shadow: inset 0 calc(-1 * var(--e-stroke-card)) 0 var(--e-border-strong);\n border-top: 0;\n position: sticky;\n top: var(--e-grid-head-h);\n z-index: var(--e-z-raised);\n }\n\n .e-filterrow .e-input {\n height: var(--e-control-height);\n font-size: var(--e-text-md);\n padding-inline: calc(var(--e-space-3) - var(--e-stroke-edge));\n }\n\n .e-filterrow .e-sel-trigger {\n height: var(--e-control-height);\n padding-inline-end: calc(var(--e-space-2) - var(--e-stroke-edge));\n }\n\n .e-filter-range {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--e-space-1);\n }\n\n .e-gridtable thead th,\n .e-gridtable thead td {\n white-space: nowrap;\n }\n\n .e-resizer {\n position: absolute;\n top: 0;\n inset-inline-end: calc(var(--e-space-6) / -2);\n z-index: var(--e-z-raised);\n width: var(--e-space-6);\n height: 100%;\n cursor: col-resize;\n touch-action: none;\n }\n\n .e-resizer::before {\n content: \"\";\n position: absolute;\n inset-block: 0;\n inset-inline: -10px;\n }\n\n .e-resizer::after {\n content: \"\";\n position: absolute;\n top: 22%;\n inset-inline-start: 11px;\n width: var(--e-stroke-hair);\n height: 56%;\n background: var(--e-border-strong);\n transition: width var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-resizer:hover::after,\n .e-resizer:focus-visible::after {\n inset-inline-start: 10px;\n width: 3px;\n background: var(--e-primary);\n border-radius: var(--e-radius-sm);\n }\n\n .e-resizer:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n border-radius: var(--e-radius-sm);\n }\n\n .e-gridtable[style*=\"table-layout\"] td,\n .e-gridtable[style*=\"table-layout\"] th {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .e-gridtable .e-sticky {\n position: sticky;\n z-index: var(--e-z-raised);\n box-shadow: inset calc(-1 * var(--e-stroke-hair)) 0 0 var(--e-border);\n }\n\n .e-gridtable thead th.e-sticky {\n z-index: var(--e-z-sticky);\n background: var(--e-surface-tint);\n }\n\n .e-gridtable tbody td.e-sticky {\n background: var(--e-surface);\n }\n\n .e-gridtable tbody tr:hover td.e-sticky {\n background: var(--e-surface-hover);\n }\n\n .e-gridtable tbody tr[data-selected] td.e-sticky {\n background: var(--e-surface-tint);\n }\n\n .e-gridtable--virtual td {\n height: var(--e-row-h);\n padding-block: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .e-spacer td {\n padding: 0;\n border: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-resizer::after {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-gridtable tbody tr[data-selected] td {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .e-resizer::after {\n background: CanvasText;\n }\n\n .e-resizer:hover::after,\n .e-resizer:focus-visible::after {\n background: Highlight;\n }\n\n .e-skel {\n background: GrayText;\n }\n }\n\n @media print {\n .e-grid-scroll {\n overflow: visible;\n max-height: none;\n }\n }\n\n .e-grid--cards {\n container-type: inline-size;\n }\n\n .e-grid-sortsel {\n display: none;\n min-width: 11rem;\n }\n\n .e-grid-bar--sortonly {\n display: none;\n }\n\n @container (max-width: 40rem) {\n .e-grid-sortsel {\n display: block;\n flex: 1 1 11rem;\n }\n\n .e-grid-bar--sortonly {\n display: flex;\n }\n\n .e-grid--cards .e-grid-scroll {\n overflow: visible;\n max-height: none;\n }\n\n .e-grid--cards .e-gridtable,\n .e-grid--cards .e-gridtable tbody {\n display: block;\n min-width: 0;\n width: 100%;\n }\n\n .e-grid--cards .e-gridtable thead {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n /* stylelint-disable-next-line property-no-deprecated -- clip hides text visually */\n clip: rect(0 0 0 0);\n white-space: nowrap;\n }\n\n .e-grid--cards .e-grid-frame {\n overflow: visible;\n background: transparent;\n }\n\n .e-grid--cards .e-grid-frame::after {\n content: none;\n }\n\n .e-grid--cards .e-gridtable tbody tr {\n display: block;\n margin: 0 0 var(--e-space-3);\n padding: var(--e-space-1) var(--e-space-4);\n border-radius: var(--e-radius-md);\n background: var(--e-surface);\n box-shadow: var(--e-edge);\n }\n\n .e-grid--cards .e-gridtable tbody tr:hover td {\n background: transparent;\n }\n\n .e-grid--cards .e-gridtable tbody tr[data-selected] {\n background: var(--e-surface-tint);\n }\n\n .e-grid--cards .e-gridtable tbody tr[data-selected] td {\n background: transparent;\n }\n\n .e-grid--cards .e-gridtable td {\n display: grid;\n grid-template-columns: minmax(5rem, 38%) minmax(0, 1fr);\n gap: var(--e-space-3);\n align-items: baseline;\n padding: var(--e-space-2) 0;\n border-top: var(--e-stroke-hair) solid var(--e-border);\n overflow: visible;\n white-space: normal;\n text-align: start;\n }\n\n .e-grid--cards .e-gridtable tbody tr:first-child td:not(:first-child) {\n border-top: var(--e-stroke-hair) solid var(--e-border);\n }\n\n .e-grid--cards .e-gridtable tbody td:first-child {\n border-top: 0;\n }\n\n .e-grid--cards .e-gridtable td::before {\n content: attr(data-label);\n font: 600 var(--e-text-xs) / 1.3 var(--e-font-mono);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--e-muted);\n }\n\n .e-grid--cards .e-gridtable td.e-cell-check {\n display: flex;\n width: auto;\n padding: var(--e-space-2) 0;\n }\n\n .e-grid--cards .e-gridtable td.e-cell-check::before {\n content: none;\n }\n\n .e-grid--cards .e-gridtable .e-sticky {\n position: static;\n box-shadow: none;\n }\n\n .e-grid--cards .e-gridtable .e-num {\n text-align: start;\n }\n\n .e-grid--cards .e-gridtable .e-grid-empty {\n display: block;\n }\n\n .e-grid--cards .e-gridtable .e-grid-empty::before {\n content: none;\n }\n\n .e-grid--cards .e-filterrow {\n display: none;\n }\n\n .e-grid--cards .e-gridtable[style*=\"table-layout\"] td {\n overflow: visible;\n text-overflow: clip;\n }\n }\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ENavList.js","names":["_sfc_main","ENavList_vue_vue_type_script_setup_true_lang_default","ENavList_default"],"sources":["../../../src/components/NavList/ENavList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, type Component } from \"vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport LinkNav, { type LinkItem, type LinkSection } from \"./LinkNav.vue\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport \"../../styles/base.css\";\n\nexport interface NavItem extends LinkItem {\n /** An icon before the label. */\n icon?: IconProp;\n /** A count of things waiting on the person (bills to pay, forms to sign). */\n count?: number;\n}\n\nexport type NavSection = LinkSection<NavItem>;\n\nconst props = withDefaults(\n defineProps<{\n /** The destinations, in order: `{ label, href?, to?, icon?, count?, current? }`. With no `href` or `to` a link goes to `#`. Set `current` yourself. */\n items?: NavItem[];\n /** Destinations in labelled groups, instead of `items`: `{ label?, items }`. Give a label only when there is more than one section. */\n sections?: NavSection[];\n /** `vertical` stacks the links, for a sidebar or a menu. `horizontal` lays them in a row, for a header, with a hairline between each. Items look the same as in the vertical list: a tint on hover, and a primary outline with a heavier bottom edge on the current page. */\n orientation?: \"vertical\" | \"horizontal\";\n /** The landmark's name; give each navigation on a page its own. @default \"Main\" */\n label?: string;\n /** What renders each link: `\"a\"` by default, or `RouterLink` (or any component that takes `href` or `to` and a default slot). Give items `to`; it receives `to` or `href`, the class `e-nav-item` and `aria-current`. */\n linkComponent?: string | Component;\n }>(),\n { orientation: \"vertical\", linkComponent: \"a\" },\n);\n\nconst groups = computed<NavSection[]>(() => props.sections ?? [{ items: props.items ?? [] }]);\n</script>\n\n<template>\n <LinkNav\n class=\"e-nav\"\n :class=\"orientation === 'horizontal' && 'e-nav--horizontal'\"\n :groups=\"groups\"\n :label=\"label\"\n :link-component=\"linkComponent\"\n item-class=\"e-nav-item\"\n heading-class=\"e-nav-heading\"\n >\n <template #item=\"{ item }\">\n <EIcon v-if=\"item.icon\" :name=\"item.icon\" />\n <span class=\"e-nav-label\">{{ item.label }}</span>\n <span v-if=\"item.count != null\" class=\"e-nav-count\">{{ item.count }}</span>\n </template>\n </LinkNav>\n</template>\n\n<style>\n@layer e.page {\n .e-nav ul {\n display: grid;\n gap: calc(var(--e-space-1) / 2);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .e-nav:not(.e-nav--horizontal) ul {\n gap: 0;\n }\n\n .e-nav:not(.e-nav--horizontal) li + li::before {\n content: \"\";\n display: block;\n height: var(--e-stroke-hair);\n margin-block: var(--e-space-2);\n background: color-mix(in srgb, var(--e-border) 60%, transparent);\n }\n\n .e-nav-item {\n display: flex;\n align-items: center;\n gap: var(--e-space-3);\n height: var(--e-control-height);\n box-sizing: border-box;\n padding: 0 var(--e-space-3) var(--e-
|
|
1
|
+
{"version":3,"file":"ENavList.js","names":["_sfc_main","ENavList_vue_vue_type_script_setup_true_lang_default","ENavList_default"],"sources":["../../../src/components/NavList/ENavList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, type Component } from \"vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport LinkNav, { type LinkItem, type LinkSection } from \"./LinkNav.vue\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport \"../../styles/base.css\";\n\nexport interface NavItem extends LinkItem {\n /** An icon before the label. */\n icon?: IconProp;\n /** A count of things waiting on the person (bills to pay, forms to sign). */\n count?: number;\n}\n\nexport type NavSection = LinkSection<NavItem>;\n\nconst props = withDefaults(\n defineProps<{\n /** The destinations, in order: `{ label, href?, to?, icon?, count?, current? }`. With no `href` or `to` a link goes to `#`. Set `current` yourself. */\n items?: NavItem[];\n /** Destinations in labelled groups, instead of `items`: `{ label?, items }`. Give a label only when there is more than one section. */\n sections?: NavSection[];\n /** `vertical` stacks the links, for a sidebar or a menu. `horizontal` lays them in a row, for a header, with a hairline between each. Items look the same as in the vertical list: a tint on hover, and a primary outline with a heavier bottom edge on the current page. */\n orientation?: \"vertical\" | \"horizontal\";\n /** The landmark's name; give each navigation on a page its own. @default \"Main\" */\n label?: string;\n /** What renders each link: `\"a\"` by default, or `RouterLink` (or any component that takes `href` or `to` and a default slot). Give items `to`; it receives `to` or `href`, the class `e-nav-item` and `aria-current`. */\n linkComponent?: string | Component;\n }>(),\n { orientation: \"vertical\", linkComponent: \"a\" },\n);\n\nconst groups = computed<NavSection[]>(() => props.sections ?? [{ items: props.items ?? [] }]);\n</script>\n\n<template>\n <LinkNav\n class=\"e-nav\"\n :class=\"orientation === 'horizontal' && 'e-nav--horizontal'\"\n :groups=\"groups\"\n :label=\"label\"\n :link-component=\"linkComponent\"\n item-class=\"e-nav-item\"\n heading-class=\"e-nav-heading\"\n >\n <template #item=\"{ item }\">\n <EIcon v-if=\"item.icon\" :name=\"item.icon\" />\n <span class=\"e-nav-label\">{{ item.label }}</span>\n <span v-if=\"item.count != null\" class=\"e-nav-count\">{{ item.count }}</span>\n </template>\n </LinkNav>\n</template>\n\n<style>\n@layer e.page {\n .e-nav ul {\n display: grid;\n gap: calc(var(--e-space-1) / 2);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .e-nav:not(.e-nav--horizontal) ul {\n gap: 0;\n }\n\n .e-nav:not(.e-nav--horizontal) li + li::before {\n content: \"\";\n display: block;\n height: var(--e-stroke-hair);\n margin-block: var(--e-space-2);\n background: color-mix(in srgb, var(--e-border) 60%, transparent);\n }\n\n .e-nav-item {\n display: flex;\n align-items: center;\n gap: var(--e-space-3);\n height: var(--e-control-height);\n box-sizing: border-box;\n padding: 0 calc(var(--e-space-3) - var(--e-stroke-edge));\n\n --e-lift: 0px;\n\n /* The current page is outlined with a border and its fill stops inside it, so the corner carries the edge colour alone; the other items have no edge and fill to the box. */\n border: var(--e-stroke-edge) solid transparent;\n border-bottom-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-radius: var(--e-radius-md);\n color: var(--e-ink);\n font: 400 var(--e-text-md) / 1 var(--e-font-sans);\n text-decoration: none;\n transition:\n background-color var(--e-duration-tap) var(--e-easing-out),\n border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-nav-item:hover {\n background-color: var(--e-surface-hover);\n }\n\n .e-nav-item:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n .e-nav-item[aria-current=\"page\"] {\n background-color: color-mix(in srgb, var(--e-surface-tint), var(--e-ink) 3%);\n font-weight: 600;\n\n --e-lift: var(--e-depth);\n --e-slab: var(--e-primary);\n\n border-color: var(--e-primary);\n border-bottom-color: var(--e-slab);\n background-clip: padding-box;\n }\n\n .e-nav-item[aria-current=\"page\"]:hover {\n --e-slab: color-mix(in srgb, var(--e-primary), var(--e-shade-slab));\n }\n\n .e-nav-label {\n flex: 1;\n min-width: 0;\n }\n\n .e-nav--horizontal {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--e-space-2) var(--e-space-4);\n }\n\n /* The separator sits inside the next item's li, so the list has no gap of its own: the margins on the separator space both sides equally. */\n .e-nav--horizontal ul {\n display: flex;\n flex-wrap: wrap;\n gap: 0;\n }\n\n .e-nav--horizontal li {\n display: flex;\n align-items: center;\n }\n\n .e-nav--horizontal li + li::before {\n content: \"\";\n width: var(--e-stroke-hair);\n height: 1.75rem;\n margin-inline: var(--e-space-2);\n background: color-mix(in srgb, var(--e-border) 60%, transparent);\n }\n\n .e-nav--horizontal .e-nav-heading {\n margin: 0;\n padding-inline: 0;\n }\n\n .e-nav-count {\n min-width: var(--e-space-6);\n padding: 0 var(--e-space-2);\n border-radius: var(--e-radius-pill);\n background: color-mix(in srgb, var(--e-primary) 12%, var(--e-surface));\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-primary);\n font: 600 var(--e-text-xs) / 20px var(--e-font-mono);\n text-align: center;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-nav-item {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-nav-item[aria-current=\"page\"] {\n border-color: Highlight;\n }\n }\n}\n</style>\n"],"mappings":""}
|