@eos-ui/vue 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/component-names.js +1 -1
- package/dist/component-names.js.map +1 -1
- package/dist/components/Actions/EActions.js.map +1 -1
- package/dist/components/Actions/EActions.vue.d.ts +1 -1
- package/dist/components/Actions/EActions.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.d.ts +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.d.ts +2 -0
- package/dist/components/Button/EButton.vue_vue_type_script_setup_true_lang.js +64 -29
- package/dist/components/Button/EButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Calendar/ECalendar.js.map +1 -1
- package/dist/components/Calendar/ECalendar.vue.d.ts +1 -1
- package/dist/components/Calendar/ECalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Checkbox/ECheckbox.js.map +1 -1
- package/dist/components/Checkbox/ECheckbox.vue.d.ts +1 -1
- package/dist/components/Checkbox/ECheckbox.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 +4 -8
- package/dist/components/Combobox/EComboboxBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Combobox/types.d.ts +2 -2
- package/dist/components/DataGrid/EDataGrid.js.map +1 -1
- package/dist/components/DataGrid/EDataGrid.vue.d.ts +1 -1
- package/dist/components/DataGrid/EDataGrid.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/DataGrid/EDataGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/DescriptionList/EDescriptionList.js.map +1 -1
- package/dist/components/DescriptionList/EDescriptionList.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/DescriptionList/EDescriptionList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Dialog/EDialog.js.map +1 -1
- package/dist/components/Dialog/EDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Drawer/EDrawer.js.map +1 -1
- package/dist/components/Drawer/EDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/EmptyState/EEmptyState.js.map +1 -1
- package/dist/components/EmptyState/EEmptyState.vue.d.ts +1 -1
- package/dist/components/EmptyState/EEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Grid/EGrid.js.map +1 -1
- package/dist/components/Grid/EGrid.vue.d.ts +1 -1
- package/dist/components/Grid/EGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/IconButton/EIconButton.js.map +1 -1
- package/dist/components/IconButton/EIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Inline/EInline.js.map +1 -1
- package/dist/components/Inline/EInline.vue.d.ts +1 -1
- package/dist/components/Inline/EInline.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Kbd/EKbd.js.map +1 -1
- package/dist/components/Kbd/EKbd.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/OtpField/EOtpField.js.map +1 -1
- package/dist/components/OtpField/EOtpField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Pagination/EPagination.js.map +1 -1
- package/dist/components/Pagination/EPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/PasswordField/EPasswordField.js.map +1 -1
- package/dist/components/PasswordField/EPasswordField.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.d.ts +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/Stack/EStack.js.map +1 -1
- package/dist/components/Stack/EStack.vue.d.ts +1 -1
- package/dist/components/Stack/EStack.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Stamp/EStamp.js.map +1 -1
- package/dist/components/Stamp/EStamp.vue.d.ts +2 -2
- package/dist/components/Stamp/EStamp.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Stamp/EStamp.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/Surface/ESurface.js.map +1 -1
- package/dist/components/Surface/ESurface.vue.d.ts +1 -1
- package/dist/components/Surface/ESurface.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/Table/ETable.js +8 -0
- package/dist/components/Table/ETable.js.map +1 -0
- package/dist/components/Table/ETable.vue.d.ts +25 -0
- package/dist/components/Table/ETable.vue_vue_type_script_setup_true_lang.js +28 -0
- package/dist/components/Table/ETable.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/Table/index.d.ts +1 -0
- package/dist/components/Tabs/ETabs.js.map +1 -1
- package/dist/components/Tabs/ETabs.vue.d.ts +10 -2
- package/dist/components/Tabs/ETabs.vue_vue_type_script_setup_true_lang.js +11 -3
- package/dist/components/Tabs/ETabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Upload/EUpload.js.map +1 -1
- package/dist/components/Upload/EUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10 -9
- package/dist/style.css +553 -174
- package/package.json +3 -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 \"../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. On by default; `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-table {\n width: 100%;\n border-collapse: collapse;\n font: 400 var(--e-text-md) / 1.4 var(--e-font-sans);\n }\n\n .e-table th {\n padding: var(--e-space-3) var(--e-space-4);\n border-bottom: var(--e-stroke-card) solid var(--e-border-strong);\n background: var(--e-surface-tint);\n text-align: start;\n white-space: nowrap;\n font: 600 var(--e-text-xs) / 1.2 var(--e-font-mono);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--e-muted);\n }\n\n .e-table td {\n padding: var(--e-space-3) var(--e-space-4);\n border-top: var(--e-stroke-hair) solid var(--e-border);\n vertical-align: middle;\n }\n\n .e-table tbody tr:first-child td {\n border-top: 0;\n }\n\n .e-table tbody tr:hover td {\n background: var(--e-surface-hover);\n }\n\n .e-table .e-num {\n text-align: end;\n font-family: var(--e-font-mono);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n\n .e-table th.e-num {\n font-family: var(--e-font-mono);\n }\n\n .e-table .e-center {\n text-align: center;\n }\n\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 border-bottom: var(--e-stroke-card) solid 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: 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":""}
|
|
@@ -28,7 +28,7 @@ declare const __VLS_export: <Row extends DataGridRow>(__VLS_props: NonNullable<A
|
|
|
28
28
|
maxHeight?: string;
|
|
29
29
|
/** Renders only the rows in view, for thousands of rows. Replaces paging. `true` or `{ rowHeight = 48, height = 440, overscan = 8 }`. */
|
|
30
30
|
virtual?: boolean | DataGridVirtual;
|
|
31
|
-
/** Turns rows into cards below 40rem of the grid's own width.
|
|
31
|
+
/** Turns rows into cards below 40rem of the grid's own width. `virtual` and `resizable` grids keep the table. */
|
|
32
32
|
cards?: boolean;
|
|
33
33
|
/** Data lives on a server: show the rows given, in the order given, and report every change through `queryChange`. */
|
|
34
34
|
manual?: boolean;
|
|
@@ -14,6 +14,7 @@ import ae from "../Select/ESelect.js";
|
|
|
14
14
|
import a from "../TextField/ETextField.js";
|
|
15
15
|
import oe from "./EDataGridResizer.js";
|
|
16
16
|
import { cellValue as se, compareValues as ce, filterActive as le, parsePx as ue, passesFilter as de } from "./grid.js";
|
|
17
|
+
/* empty css */
|
|
17
18
|
import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createSlots as fe, createTextVNode as f, createVNode as p, defineComponent as m, mergeModels as pe, mergeProps as me, nextTick as he, normalizeClass as h, normalizeStyle as g, openBlock as _, ref as v, renderList as y, renderSlot as b, toDisplayString as x, unref as S, useModel as C, useSlots as ge, watch as _e, withCtx as w } from "vue";
|
|
18
19
|
import { PopoverClose as ve, PopoverContent as ye, PopoverPortal as be, PopoverRoot as xe, PopoverTrigger as Se } from "reka-ui";
|
|
19
20
|
import { columnFilteringFeature as Ce, columnSizingFeature as we, columnVisibilityFeature as Te, createFilteredRowModel as Ee, createPaginatedRowModel as De, createSortedRowModel as Oe, functionalUpdate as T, globalFilteringFeature as ke, rowPaginationFeature as Ae, rowSelectionFeature as je, rowSortingFeature as Me, tableFeatures as Ne, useTable as Pe } from "@tanstack/vue-table";
|
|
@@ -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 \"../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. On by default; `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-table {\n width: 100%;\n border-collapse: collapse;\n font: 400 var(--e-text-md) / 1.4 var(--e-font-sans);\n }\n\n .e-table th {\n padding: var(--e-space-3) var(--e-space-4);\n border-bottom: var(--e-stroke-card) solid var(--e-border-strong);\n background: var(--e-surface-tint);\n text-align: start;\n white-space: nowrap;\n font: 600 var(--e-text-xs) / 1.2 var(--e-font-mono);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--e-muted);\n }\n\n .e-table td {\n padding: var(--e-space-3) var(--e-space-4);\n border-top: var(--e-stroke-hair) solid var(--e-border);\n vertical-align: middle;\n }\n\n .e-table tbody tr:first-child td {\n border-top: 0;\n }\n\n .e-table tbody tr:hover td {\n background: var(--e-surface-hover);\n }\n\n .e-table .e-num {\n text-align: end;\n font-family: var(--e-font-mono);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n\n .e-table th.e-num {\n font-family: var(--e-font-mono);\n }\n\n .e-table .e-center {\n text-align: center;\n }\n\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 border-bottom: var(--e-stroke-card) solid 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: 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EDescriptionList.js","names":["_sfc_main","EDescriptionList_vue_vue_type_script_setup_true_lang_default","EDescriptionList_default"],"sources":["../../../src/components/DescriptionList/EDescriptionList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, type VNodeChild } from \"vue\";\nimport EButton from \"../Button/EButton.vue\";\nimport EStamp from \"../Stamp/EStamp.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport type { StampTone } from \"../Stamp/EStamp.vue\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport { useMessages } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nexport interface DescriptionItem {\n /** The label, shown as a small uppercase kicker. Leave it out on every row for a plain list of facts. */\n label?: string;\n /** The text beside it. A string, or a rendered VNode for rich text. */\n text: string | VNodeChild;\n /** A decorative icon before the label (or before the text in a plain list). */\n icon?: IconProp;\n /** A word in a stamp after the text, such as \"Verified\". */\n badge?: string;\n /** The badge's tone. */\n badgeTone?: StampTone;\n /** Shows an Edit button at the end of the row. Pressing it emits `edit`. */\n editable?: boolean;\n}\n\nconst props = defineProps<{\n /** Label and text rows, ruled apart: `{ label: string, text: string | VNode }`. Labels are keys, so keep them unique. `null` items are skipped. */\n items: (DescriptionItem | null | undefined)[];\n}>();\n\nconst emit = defineEmits<{\n /** An item's Edit button was pressed. */\n edit: [item: DescriptionItem, index: number];\n}>();\n\ndefineSlots<{\n /** Replaces the end of a row (after the text and badge), such as a Button or IconButton. */\n action?(props: { item: DescriptionItem; index: number }): unknown;\n}>();\n\nconst t = useMessages();\nconst shown = computed(() => props.items.filter((it): it is DescriptionItem => Boolean(it)));\n/** No labels anywhere: render a plain list of facts instead of term/description pairs. */\nconst plain = computed(() => shown.value.length > 0 && shown.value.every((it) => !it.label));\n\nconst Render = Object.assign((p: { value: VNodeChild }) => p.value, { props: [\"value\"] });\n\nfunction say(key: string, fallback: string, vars?: Record<string, string>) {\n const text = t(key, vars);\n return text === key ? fallback.replace(/\\{(\\w+)\\}/g, (m, k: string) => vars?.[k] ?? m) : text;\n}\n</script>\n\n<template>\n <ul v-if=\"plain\" class=\"e-facts e-facts--plain\">\n <li v-for=\"(item, i) in shown\" :key=\"i\" class=\"e-fact\">\n <EIcon v-if=\"item.icon\" :name=\"item.icon\" />\n <span class=\"e-fact-text\"><Render :value=\"item.text\" /></span>\n <EStamp v-if=\"item.badge\" :tone=\"item.badgeTone\"
|
|
1
|
+
{"version":3,"file":"EDescriptionList.js","names":["_sfc_main","EDescriptionList_vue_vue_type_script_setup_true_lang_default","EDescriptionList_default"],"sources":["../../../src/components/DescriptionList/EDescriptionList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, type VNodeChild } from \"vue\";\nimport EButton from \"../Button/EButton.vue\";\nimport EStamp from \"../Stamp/EStamp.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport type { StampTone } from \"../Stamp/EStamp.vue\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport { useMessages } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nexport interface DescriptionItem {\n /** The label, shown as a small uppercase kicker. Leave it out on every row for a plain list of facts. */\n label?: string;\n /** The text beside it. A string, or a rendered VNode for rich text. */\n text: string | VNodeChild;\n /** A decorative icon before the label (or before the text in a plain list). */\n icon?: IconProp;\n /** A word in a stamp after the text, such as \"Verified\". */\n badge?: string;\n /** The badge's tone. */\n badgeTone?: StampTone;\n /** Shows an Edit button at the end of the row. Pressing it emits `edit`. */\n editable?: boolean;\n}\n\nconst props = defineProps<{\n /** Label and text rows, ruled apart: `{ label: string, text: string | VNode }`. Labels are keys, so keep them unique. `null` items are skipped. */\n items: (DescriptionItem | null | undefined)[];\n}>();\n\nconst emit = defineEmits<{\n /** An item's Edit button was pressed. */\n edit: [item: DescriptionItem, index: number];\n}>();\n\ndefineSlots<{\n /** Replaces the end of a row (after the text and badge), such as a Button or IconButton. */\n action?(props: { item: DescriptionItem; index: number }): unknown;\n}>();\n\nconst t = useMessages();\nconst shown = computed(() => props.items.filter((it): it is DescriptionItem => Boolean(it)));\n/** No labels anywhere: render a plain list of facts instead of term/description pairs. */\nconst plain = computed(() => shown.value.length > 0 && shown.value.every((it) => !it.label));\n\nconst Render = Object.assign((p: { value: VNodeChild }) => p.value, { props: [\"value\"] });\n\nfunction say(key: string, fallback: string, vars?: Record<string, string>) {\n const text = t(key, vars);\n return text === key ? fallback.replace(/\\{(\\w+)\\}/g, (m, k: string) => vars?.[k] ?? m) : text;\n}\n</script>\n\n<template>\n <ul v-if=\"plain\" class=\"e-facts e-facts--plain\">\n <li v-for=\"(item, i) in shown\" :key=\"i\" class=\"e-fact\">\n <EIcon v-if=\"item.icon\" :name=\"item.icon\" />\n <span class=\"e-fact-text\"><Render :value=\"item.text\" /></span>\n <EStamp v-if=\"item.badge\" :tone=\"item.badgeTone\" small>{{ item.badge }}</EStamp>\n <slot name=\"action\" :item=\"item\" :index=\"i\" />\n </li>\n </ul>\n <dl v-else class=\"e-facts\">\n <div v-for=\"(item, i) in shown\" :key=\"i\" class=\"e-fact\">\n <dt class=\"e-kicker\">\n <EIcon v-if=\"item.icon\" :name=\"item.icon\" />{{ item.label }}\n </dt>\n <dd class=\"e-fact-text\">\n <span class=\"e-fact-value\"><Render :value=\"item.text\" /></span>\n <EStamp v-if=\"item.badge\" :tone=\"item.badgeTone\" small>{{ item.badge }}</EStamp>\n <slot name=\"action\" :item=\"item\" :index=\"i\" />\n <EButton\n v-if=\"item.editable\"\n variant=\"quiet\"\n :aria-label=\"say('editItem', 'Edit {label}', { label: item.label ?? '' })\"\n @click=\"emit('edit', item, i)\"\n >\n {{ say(\"edit\", \"Edit\") }}\n </EButton>\n </dd>\n </div>\n </dl>\n</template>\n\n<style>\n@layer e.blocks {\n .e-facts {\n display: grid;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .e-fact {\n display: grid;\n grid-template-columns: 8rem minmax(0, 1fr);\n gap: var(--e-space-1) var(--e-space-4);\n align-items: baseline;\n padding: var(--e-space-3) 0;\n border-top: var(--e-stroke-hair) solid var(--e-border);\n min-width: 0;\n }\n\n .e-fact:first-child {\n border-top: 0;\n }\n\n .e-fact > .e-kicker {\n display: flex;\n align-items: center;\n gap: var(--e-space-2);\n }\n\n .e-fact > .e-kicker .e-icon {\n flex: none;\n width: 1.125rem;\n height: 1.125rem;\n }\n\n .e-fact-text {\n display: flex;\n align-items: center;\n gap: var(--e-space-3);\n margin: 0;\n min-width: 0;\n font: 400 var(--e-text-md) / 1.45 var(--e-font-sans);\n }\n\n .e-fact-value {\n flex: 1;\n min-width: 0;\n overflow-wrap: anywhere;\n }\n\n .e-fact-text > :not(.e-fact-value) {\n flex: none;\n }\n\n /* Plain list: icon, text, then the end. */\n .e-facts--plain {\n gap: var(--e-space-2);\n }\n\n .e-facts--plain > .e-fact {\n display: flex;\n align-items: flex-start;\n gap: var(--e-space-2);\n padding: 0;\n border-top: 0;\n }\n\n .e-facts--plain > .e-fact > .e-icon {\n flex: none;\n width: 1.125rem;\n height: 1.125rem;\n margin-top: var(--e-space-1);\n }\n\n .e-facts--plain > .e-fact > .e-fact-text {\n flex: 1;\n display: block;\n line-height: 1.4;\n }\n\n @media (max-width: 26rem) {\n .e-fact {\n grid-template-columns: minmax(0, 1fr);\n }\n }\n\n @media print {\n .e-fact {\n box-shadow: none;\n outline: 0;\n border: 0 solid var(--e-print-ink);\n border-width: 0 0 var(--e-stroke-hair);\n break-inside: avoid;\n }\n\n .e-fact .e-btn {\n display: none;\n }\n }\n}\n</style>\n"],"mappings":""}
|