@rotki/ui-library 2.13.2 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/README.md +1 -1
- package/dist/components/logos/use-logo-sources.js +5 -4
- package/dist/components/logos/use-logo-sources.js.map +1 -1
- package/dist/components/tables/RuiDataTable.vue2.js +2 -2
- package/dist/components/tables/RuiDataTable.vue2.js.map +1 -1
- package/dist/composables/sticky-header.d.ts +6 -4
- package/dist/composables/sticky-header.js +127 -79
- package/dist/composables/sticky-header.js.map +1 -1
- package/dist/icons/icons_1.d.ts +1 -1
- package/dist/icons/icons_1.js +5 -5
- package/dist/icons/icons_1.js.map +1 -1
- package/dist/icons/icons_2.d.ts +1 -1
- package/dist/icons/icons_2.js +6 -6
- package/dist/icons/icons_2.js.map +1 -1
- package/dist/icons/icons_3.d.ts +1 -1
- package/dist/icons/icons_3.js +6 -6
- package/dist/icons/icons_3.js.map +1 -1
- package/dist/icons/icons_4.d.ts +1 -0
- package/dist/icons/icons_4.js +5 -0
- package/dist/icons/icons_4.js.map +1 -1
- package/dist/icons/index.d.ts +1 -1
- package/dist/icons/index.js +1 -1
- package/dist/icons/index.js.map +1 -1
- package/dist/index.js +5 -4
- package/dist/web-types.json +1 -1
- package/package.json +1 -1
package/dist/README.md
CHANGED
|
@@ -344,7 +344,7 @@ When the dependency installed on the main project, it will run the `prepare` scr
|
|
|
344
344
|
|
|
345
345
|
### Generating the library icons
|
|
346
346
|
|
|
347
|
-
We use
|
|
347
|
+
We use [Lucide](https://lucide.dev/) icons as the base icon set. Brand icons (Discord, Reddit, X/Twitter, etc.) in the `src/custom-icons/` directory are sourced from [Simple Icons](https://simpleicons.org/). You need to run this script to generate the icon data from SVGs. (This script runs automatically on `prepare`. Run this in case the icons aren't generated properly)
|
|
348
348
|
|
|
349
349
|
```
|
|
350
350
|
pnpm run generate:icons
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { transformCase } from "../../utils/helpers.js";
|
|
2
|
-
import { useFetch } from "@vueuse/core";
|
|
3
|
-
import { get } from "@vueuse/shared";
|
|
4
2
|
const ASSET_MAPPINGS_URL = "https://raw.githubusercontent.com/rotki/data";
|
|
5
3
|
const sourcesCache = /* @__PURE__ */ new Map();
|
|
6
4
|
function isExternalLinks(value) {
|
|
@@ -10,10 +8,13 @@ function isExternalLinks(value) {
|
|
|
10
8
|
}
|
|
11
9
|
async function fetchSourcesFromNetwork(branch) {
|
|
12
10
|
try {
|
|
13
|
-
const
|
|
11
|
+
const response = await fetch(
|
|
14
12
|
`${ASSET_MAPPINGS_URL}/${branch}/constants/asset-mappings.json`
|
|
15
13
|
);
|
|
16
|
-
|
|
14
|
+
if (!response.ok)
|
|
15
|
+
return void 0;
|
|
16
|
+
const json = await response.json();
|
|
17
|
+
const links = transformCase(json?.logo, "camelCase");
|
|
17
18
|
if (isExternalLinks(links))
|
|
18
19
|
return links;
|
|
19
20
|
return void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-logo-sources.js","sources":["../../../src/components/logos/use-logo-sources.ts"],"sourcesContent":["import type { ExternalLinks } from '@/components/logos/RuiLogo.vue';\nimport { transformCase } from '@/utils/helpers';\n\nconst ASSET_MAPPINGS_URL = 'https://raw.githubusercontent.com/rotki/data';\n\n// Module-level cache: deduplicates asset-mappings fetches across all RuiLogo instances.\n// Keyed by branch so different branches don't share stale data.\nconst sourcesCache = new Map<string, Promise<ExternalLinks | undefined>>();\n\nfunction isExternalLinks(value: unknown): value is ExternalLinks {\n if (typeof value !== 'object' || value === null)\n return false;\n\n return Object.values(value).every(v => v === undefined || typeof v === 'string');\n}\n\nasync function fetchSourcesFromNetwork(branch: string): Promise<ExternalLinks | undefined> {\n try {\n const
|
|
1
|
+
{"version":3,"file":"use-logo-sources.js","sources":["../../../src/components/logos/use-logo-sources.ts"],"sourcesContent":["import type { ExternalLinks } from '@/components/logos/RuiLogo.vue';\nimport { transformCase } from '@/utils/helpers';\n\nconst ASSET_MAPPINGS_URL = 'https://raw.githubusercontent.com/rotki/data';\n\n// Module-level cache: deduplicates asset-mappings fetches across all RuiLogo instances.\n// Keyed by branch so different branches don't share stale data.\nconst sourcesCache = new Map<string, Promise<ExternalLinks | undefined>>();\n\nfunction isExternalLinks(value: unknown): value is ExternalLinks {\n if (typeof value !== 'object' || value === null)\n return false;\n\n return Object.values(value).every(v => v === undefined || typeof v === 'string');\n}\n\nasync function fetchSourcesFromNetwork(branch: string): Promise<ExternalLinks | undefined> {\n try {\n const response = await fetch(\n `${ASSET_MAPPINGS_URL}/${branch}/constants/asset-mappings.json`,\n );\n\n if (!response.ok)\n return undefined;\n\n const json = await response.json();\n const links = transformCase(json?.logo, 'camelCase');\n if (isExternalLinks(links))\n return links;\n\n return undefined;\n }\n catch {\n return undefined;\n }\n}\n\n/**\n * Fetches external logo sources for a given branch, deduplicating concurrent requests.\n * Uses a module-level cache so all RuiLogo instances share a single fetch per branch.\n */\nexport function getLogoSources(branch: string): Promise<ExternalLinks | undefined> {\n const cached = sourcesCache.get(branch);\n if (cached)\n return cached;\n\n const promise = fetchSourcesFromNetwork(branch);\n sourcesCache.set(branch, promise);\n return promise;\n}\n\n/**\n * Clears the module-level cache. Exposed for testing only.\n */\nexport function clearLogoSourcesCache(): void {\n sourcesCache.clear();\n}\n"],"names":[],"mappings":";AAGA,MAAM,qBAAqB;AAI3B,MAAM,mCAAmB,IAAA;AAEzB,SAAS,gBAAgB,OAAwC;AAC/D,MAAI,OAAO,UAAU,YAAY,UAAU;AACzC,WAAO;AAET,SAAO,OAAO,OAAO,KAAK,EAAE,MAAM,OAAK,MAAM,UAAa,OAAO,MAAM,QAAQ;AACjF;AAEA,eAAe,wBAAwB,QAAoD;AACzF,MAAI;AACF,UAAM,WAAW,MAAM;AAAA,MACrB,GAAG,kBAAkB,IAAI,MAAM;AAAA,IAAA;AAGjC,QAAI,CAAC,SAAS;AACZ,aAAO;AAET,UAAM,OAAO,MAAM,SAAS,KAAA;AAC5B,UAAM,QAAQ,cAAc,MAAM,MAAM,WAAW;AACnD,QAAI,gBAAgB,KAAK;AACvB,aAAO;AAET,WAAO;AAAA,EACT,QACM;AACJ,WAAO;AAAA,EACT;AACF;AAMO,SAAS,eAAe,QAAoD;AACjF,QAAM,SAAS,aAAa,IAAI,MAAM;AACtC,MAAI;AACF,WAAO;AAET,QAAM,UAAU,wBAAwB,MAAM;AAC9C,eAAa,IAAI,QAAQ,OAAO;AAChC,SAAO;AACT;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, useModel, useSlots, computed, useTemplateRef,
|
|
1
|
+
import { defineComponent, useModel, useSlots, computed, useTemplateRef, watch, onMounted, openBlock, createElementBlock, normalizeClass, unref, createBlock, isRef, createCommentVNode, createElementVNode, createVNode, createSlots, renderList, withCtx, renderSlot, normalizeProps, guardReactiveProps, Fragment, toDisplayString, createTextVNode, Transition, mergeModels } from "vue";
|
|
2
2
|
import RuiButton from "../buttons/button/RuiButton.vue.js";
|
|
3
3
|
import RuiCheckbox from "../forms/checkbox/RuiCheckbox.vue.js";
|
|
4
4
|
import RuiIcon from "../icons/RuiIcon.vue.js";
|
|
@@ -91,7 +91,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
91
91
|
const table = useTemplateRef("table");
|
|
92
92
|
const tableScroller = useTemplateRef("tableScroller");
|
|
93
93
|
const { stick } = useStickyTableHeader(
|
|
94
|
-
|
|
94
|
+
() => __props.stickyHeader,
|
|
95
95
|
stickyHeaderOffset,
|
|
96
96
|
{ table, tableScroller }
|
|
97
97
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiDataTable.vue2.js","sources":["../../../src/components/tables/RuiDataTable.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends object, IdType extends keyof T = keyof T\">\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiCheckbox from '@/components/forms/checkbox/RuiCheckbox.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiTooltip from '@/components/overlays/tooltip/RuiTooltip.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport RuiExpandButton from '@/components/tables/RuiExpandButton.vue';\nimport RuiTableHead, {\n type GroupData,\n type TableColumn,\n type TableRowKeyData,\n type TableSortData,\n} from '@/components/tables/RuiTableHead.vue';\nimport RuiTablePagination, {\n type TablePaginationData,\n} from '@/components/tables/RuiTablePagination.vue';\nimport noDataPlaceholder from '@/components/tables/table_no_data_placeholder.svg';\nimport noDataPlaceholderDark from '@/components/tables/table_no_data_placeholder_dark.svg';\nimport { useTable } from '@/composables/defaults/table';\nimport { useStickyTableHeader } from '@/composables/sticky-header';\nimport { useTableColumns } from '@/composables/tables/data-table/columns';\nimport { useTableExpansion } from '@/composables/tables/data-table/expansion';\nimport { useTableGrouping } from '@/composables/tables/data-table/grouping';\nimport { useTablePagination } from '@/composables/tables/data-table/pagination';\nimport { useTableSelection } from '@/composables/tables/data-table/selection';\nimport { useTableSort } from '@/composables/tables/data-table/sort';\nimport { type GroupHeader, isRow } from '@/composables/tables/data-table/types';\nimport { useRotkiTheme } from '@/composables/theme';\n\nexport type { GroupedTableRow, GroupHeader, TableOptions } from '@/composables/tables/data-table/types';\n\nexport interface Props<T, K extends keyof T> {\n /**\n * list of items for each row\n */\n rows: readonly T[];\n /**\n * the attribute used to identify each row uniquely for selection, usually `id`\n */\n rowAttr: K;\n /**\n * model for internal searching\n */\n search?: string;\n /**\n * model for items per page\n * will be used if the `pagination` model isn't specified\n */\n itemsPerPage?: number;\n /**\n * list of column definitions\n */\n cols?: TableColumn<T>[];\n /**\n * attribute to use from column definitions to display column titles\n */\n columnAttr?: keyof TableColumn<T>;\n /**\n * flag to show a more or less spacious table\n */\n dense?: boolean;\n /**\n * flag to outline the flag with a border\n */\n outlined?: boolean;\n /**\n * should add zebra-striping to the table row\n */\n striped?: boolean;\n /**\n * flag to show loading state of the table\n * triggers indefinite progress at the bottom of the table header\n */\n loading?: boolean;\n disablePerPage?: boolean;\n /**\n * data to display for empty state\n * text and icon\n * @example :empty=\"{ icon: 'transactions-line', label: 'No transactions found' }\"\n */\n empty?: {\n label?: string;\n description?: string;\n };\n /**\n * should hide the header navigation\n */\n hideDefaultHeader?: boolean;\n /**\n * should hide the footer navigation\n */\n hideDefaultFooter?: boolean;\n\n rounded?: 'sm' | 'md' | 'lg';\n /**\n * make expansion work like accordion\n */\n singleExpand?: boolean;\n /**\n * make table head stick to top on scroll\n */\n stickyHeader?: boolean;\n stickyOffset?: number;\n /**\n * Affects how the items per page work across the app.\n * When true, changing the items per page setting in one table will affect other tables.\n */\n globalItemsPerPage?: boolean;\n groupExpandButtonPosition?: 'start' | 'end';\n disabledRows?: readonly T[];\n multiPageSelect?: boolean;\n itemClass?: ((item: T) => string) | string;\n}\n\ndefineOptions({\n name: 'RuiDataTable',\n});\n\nconst selectedData = defineModel<T[IdType][]>();\n\nconst expanded = defineModel<T[]>('expanded');\n\nconst [pagination, paginationModifiers] = defineModel<TablePaginationData, 'external'>('pagination');\n\nconst [sort, sortModifiers] = defineModel<TableSortData<T>, 'external'>('sort');\n\nconst group = defineModel<TableRowKeyData<T>>('group');\n\nconst collapsed = defineModel<T[]>('collapsed');\n\nconst {\n rows,\n rowAttr,\n search = '',\n itemsPerPage = 10,\n cols,\n columnAttr = 'label',\n dense = false,\n outlined = false,\n striped = false,\n loading = false,\n disablePerPage = false,\n empty = { label: 'No item found' },\n hideDefaultHeader = false,\n hideDefaultFooter = false,\n rounded = 'md',\n singleExpand = false,\n stickyHeader = false,\n stickyOffset,\n globalItemsPerPage = undefined,\n groupExpandButtonPosition = 'start',\n disabledRows,\n multiPageSelect = false,\n itemClass = '',\n} = defineProps<Props<T, IdType>>();\n\nconst emit = defineEmits<{\n 'update:options': [value: { pagination?: TablePaginationData; sort?: TableSortData<T> }];\n 'copy:group': [value: GroupData<T>];\n}>();\n\nconst slots = defineSlots<Partial<\n Record<`header.${string}`, (props: { column: TableColumn<T> }) => any> &\n Record<`item.${string}`, (props: { column: TableColumn<T>; row: T; index: number }) => any> & {\n 'body.prepend': (props: { colspan: number }) => any;\n 'body.append': (props: { colspan: number }) => any;\n 'group.header': (props: {\n colspan: number;\n header: GroupHeader<T>;\n isOpen: boolean;\n toggle: () => void;\n }) => any;\n 'group.header.content': (props: { header: GroupHeader<T>; groupKey: string }) => any;\n 'expanded-item': (props: { row: T; index: number }) => any;\n 'no-data': () => any;\n 'empty-description': () => any;\n 'tfoot': () => any;\n }\n>>();\n\nconst tableDefaults = useTable();\n\nconst { isDark } = useRotkiTheme();\n\nconst stickyHeaderOffset = computed<number | undefined>(() =>\n stickyOffset !== undefined ? stickyOffset : get(tableDefaults.stickyOffset),\n);\n\nconst table = useTemplateRef<HTMLTableElement>('table');\nconst tableScroller = useTemplateRef<HTMLElement>('tableScroller');\n\nconst { stick } = useStickyTableHeader(\n toRef(() => stickyHeader),\n stickyHeaderOffset,\n { table, tableScroller },\n);\n\nconst hasExpandedItemSlot = computed<boolean>(() => !!slots['expanded-item']);\n\nconst { expandable, isExpanded, onToggleExpand } = useTableExpansion<T, IdType>(\n { rowAttr, singleExpand },\n { expanded, hasExpandedItemSlot },\n);\n\nfunction emitUpdateOptions(opts: { sort?: TableSortData<T>; pagination?: TablePaginationData }): void {\n emit('update:options', opts);\n}\n\nconst {\n sortData,\n sortedMap,\n sorted,\n onSort: applySort,\n} = useTableSort<T>(\n { rows: () => rows, search: () => search, sortModifiersExternal: sortModifiers.external },\n {\n sort,\n pagination,\n emitUpdateOptions,\n },\n);\n\nconst {\n groupKeys,\n groupKey,\n grouped,\n isExpandedGroup,\n isHiddenRow,\n onToggleExpandGroup,\n onUngroup,\n onCopyGroup,\n} = useTableGrouping<T, IdType>(\n { rowAttr },\n {\n group,\n collapsed,\n sorted,\n emitCopyGroup: (value: GroupData<T>) => emit('copy:group', value),\n },\n);\n\nconst {\n paginationData,\n filtered,\n setInternalTotal,\n resetPagination,\n} = useTablePagination<T>(\n {\n itemsPerPage,\n paginationModifiersExternal: paginationModifiers.external,\n globalItemsPerPage,\n },\n {\n pagination,\n grouped,\n isHiddenRow,\n sort,\n emitUpdateOptions,\n tableDefaults,\n },\n);\n\nconst noData = computed<boolean>(() => get(filtered).length === 0);\n\nconst { columns, colspan, headerSlots, cellValue } = useTableColumns<T, IdType>({\n cols: () => cols,\n columnAttr,\n rows: () => rows,\n expandable,\n groupKeys,\n selectedData,\n slots,\n});\n\nconst {\n isAllSelected,\n indeterminate,\n isSelected,\n isDisabledRow,\n onToggleAll,\n onSelect,\n onCheckboxClick,\n deselectRemovedRows,\n resetCheckboxShiftState,\n} = useTableSelection<T, IdType>(\n { rowAttr, multiPageSelect, disabledRows: () => disabledRows },\n { selectedData, filtered },\n);\n\n// Sort triggers selection reset — handled here to avoid circular dependency between sort and selection\nfunction onSort(payload: Parameters<typeof applySort>[0]): void {\n applySort(payload);\n if (!multiPageSelect)\n onToggleAll(false);\n resetCheckboxShiftState();\n}\n\nfunction onPaginate(): void {\n set(expanded, []);\n if (!multiPageSelect)\n onToggleAll(false);\n resetCheckboxShiftState();\n}\n\n// Reset pagination page to 1 on search query change\nwatch(() => search, () => {\n resetPagination();\n onToggleAll(false);\n resetCheckboxShiftState();\n});\n\nwatch(sorted, (items) => {\n if (!multiPageSelect)\n deselectRemovedRows();\n setInternalTotal(items);\n});\n\nonMounted(() => {\n setInternalTotal(get(sorted));\n});\n</script>\n\n<template>\n <div\n :class=\"[$style.wrapper, $style[`rounded__${rounded}`], { [$style.outlined]: outlined }]\"\n data-id=\"table-wrapper\"\n >\n <RuiTablePagination\n v-if=\"paginationData && !hideDefaultHeader\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :disable-per-page=\"disablePerPage\"\n data-cy=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n <div\n ref=\"tableScroller\"\n :class=\"$style.scroller\"\n data-id=\"table-scroller\"\n >\n <table\n ref=\"table\"\n :class=\"[$style.table, { [$style.dense]: dense }]\"\n :aria-busy=\"loading\"\n >\n <RuiTableHead\n :loading=\"loading\"\n :indeterminate=\"indeterminate\"\n :capitalize-headers=\"!cols\"\n :colspan=\"colspan\"\n :column-attr=\"columnAttr\"\n :columns=\"columns\"\n :dense=\"dense\"\n :disable-check-all=\"!filtered?.length\"\n :is-all-selected=\"isAllSelected\"\n :no-data=\"noData\"\n :selectable=\"!!selectedData\"\n :sort-data=\"sortData\"\n :sorted-map=\"sortedMap\"\n :stick=\"stick\"\n :sticky-header=\"stickyHeader\"\n @sort=\"onSort($event)\"\n @select:all=\"onToggleAll($event)\"\n >\n <template\n v-for=\"headerSlot in headerSlots\"\n #[headerSlot]=\"slotData\"\n >\n <slot\n :name=\"headerSlot\"\n v-bind=\"slotData\"\n />\n </template>\n </RuiTableHead>\n <RuiTableHead\n v-if=\"stickyHeader\"\n :loading=\"loading\"\n :capitalize-headers=\"!cols\"\n :colspan=\"colspan\"\n :column-attr=\"columnAttr\"\n :columns=\"columns\"\n :dense=\"dense\"\n :no-data=\"noData\"\n :selectable=\"!!selectedData\"\n :sort-data=\"sortData\"\n :sorted-map=\"sortedMap\"\n data-id=\"head-clone\"\n class=\"opacity-0 invisible\"\n >\n <template\n v-for=\"headerSlot in headerSlots\"\n #[headerSlot]=\"slotData\"\n >\n <slot\n :name=\"headerSlot\"\n v-bind=\"slotData\"\n />\n </template>\n </RuiTableHead>\n <tbody :class=\"[$style.tbody, { [$style['tbody--striped'] ?? '']: striped }]\">\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n v-if=\"slots['body.prepend']\"\n :colspan=\"colspan\"\n name=\"body.prepend\"\n />\n <template v-for=\"(row, index) in filtered\">\n <tr\n v-if=\"!isRow(row)\"\n :key=\"`row-${index}`\"\n :class=\"[$style.tr, $style.tr__group]\"\n data-id=\"row-group\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header\"\n :colspan=\"colspan\"\n :header=\"row\"\n :is-open=\"isExpandedGroup(row.group)\"\n :toggle=\"() => onToggleExpandGroup(row.group, row.identifier)\"\n >\n <td\n :class=\"[$style.td]\"\n class=\"!p-2\"\n :colspan=\"colspan\"\n >\n <div class=\"flex items-center gap-2\">\n <RuiExpandButton\n v-if=\"groupExpandButtonPosition === 'start'\"\n :expanded=\"isExpandedGroup(row.group)\"\n @click=\"onToggleExpandGroup(row.group, row.identifier)\"\n />\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n :group-key=\"groupKey\"\n name=\"group.header.content\"\n :header=\"row\"\n >\n <span>{{ groupKey }}: {{ row.identifier }}</span>\n <RuiButton\n size=\"sm\"\n variant=\"text\"\n icon\n data-cy=\"group-copy-button\"\n @click=\"onCopyGroup({ key: groupKey, value: row.group })\"\n >\n <RuiIcon\n name=\"lu-copy\"\n size=\"16\"\n />\n </RuiButton>\n </slot>\n <RuiTooltip\n :popper=\"{ placement: 'top' }\"\n class=\"ml-auto mr-2\"\n >\n <template #activator>\n <RuiButton\n size=\"sm\"\n variant=\"text\"\n icon\n data-cy=\"group-ungroup-button\"\n @click=\"onUngroup()\"\n >\n <RuiIcon\n name=\"lu-trash-2\"\n size=\"14\"\n />\n </RuiButton>\n </template>\n Ungroup\n </RuiTooltip>\n <RuiExpandButton\n v-if=\"groupExpandButtonPosition === 'end'\"\n :expanded=\"isExpandedGroup(row.group)\"\n @click=\"onToggleExpandGroup(row.group, row.identifier)\"\n />\n </div>\n </td>\n </slot>\n </tr>\n <template v-else>\n <tr\n :key=\"`row-${index}`\"\n :class=\"[\n $style.tr,\n { [$style.tr__selected ?? '']: isSelected(row[rowAttr]) },\n typeof itemClass === 'string' ? itemClass : itemClass(row),\n ]\"\n :aria-selected=\"selectedData ? isSelected(row[rowAttr]) : undefined\"\n data-id=\"row\"\n >\n <td\n v-if=\"selectedData\"\n :class=\"$style.checkbox\"\n colspan=\"1\"\n rowspan=\"1\"\n >\n <RuiCheckbox\n :data-cy=\"`table-toggle-check-${index}`\"\n :model-value=\"isSelected(row[rowAttr])\"\n :disabled=\"isDisabledRow(row[rowAttr])\"\n :size=\"dense ? 'sm' : undefined\"\n color=\"primary\"\n class=\"select-none\"\n hide-details\n @update:model-value=\"onSelect($event, row[rowAttr], true)\"\n @click=\"onCheckboxClick($event, row[rowAttr], index)\"\n />\n </td>\n\n <td\n v-for=\"(column, subIndex) in columns\"\n :key=\"subIndex\"\n :class=\"[\n $style.td,\n column.cellClass,\n $style[`align__${column.align ?? 'start'}`],\n ]\"\n :colspan=\"column.colspan ?? 1\"\n :rowspan=\"column.rowspan ?? 1\"\n >\n <slot\n v-if=\"column.key === 'expand'\"\n :name=\"`item.${column.key.toString()}`\"\n :column=\"column\"\n :row=\"row\"\n :index=\"index\"\n >\n <RuiExpandButton\n v-if=\"!slots['item.expand']\"\n :expanded=\"isExpanded(row[rowAttr])\"\n @click=\"onToggleExpand(row)\"\n />\n </slot>\n <slot\n v-else\n :column=\"column\"\n :index=\"index\"\n :name=\"`item.${column.key.toString()}`\"\n :row=\"row\"\n >\n {{ cellValue(row, column.key) }}\n </slot>\n </td>\n </tr>\n\n <tr\n v-if=\"expandable && isExpanded(row[rowAttr])\"\n :key=\"`row-expand-${index}`\"\n :class=\"[$style.tr, $style.tr__expandable]\"\n data-id=\"row-expanded\"\n >\n <td\n :colspan=\"colspan\"\n :class=\"[$style.td]\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"expanded-item\"\n :row=\"row\"\n :index=\"index\"\n />\n </td>\n </tr>\n </template>\n </template>\n <tr v-if=\"loading && noData\">\n <td\n :class=\"$style.tbody__loader\"\n :colspan=\"colspan\"\n data-id=\"tbody-loader\"\n >\n <RuiProgress\n color=\"primary\"\n variant=\"indeterminate\"\n circular\n />\n </td>\n </tr>\n <tr\n v-if=\"noData && empty && !loading\"\n :class=\"[$style.tr, $style.tr__empty]\"\n data-id=\"row-empty\"\n >\n <Transition\n appear\n enter-active-class=\"transition ease-out duration-200 delay-200\"\n enter-from-class=\"opacity-0 translate-y-1\"\n enter-to-class=\"opacity-100 translate-y-0\"\n leave-active-class=\"transition ease-in duration-150\"\n leave-from-class=\"opacity-100 translate-y-0\"\n leave-to-class=\"opacity-0 translate-y-1\"\n >\n <td\n :class=\"$style.td\"\n :colspan=\"colspan\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"no-data\">\n <div :class=\"$style.empty\">\n <img\n :src=\"isDark ? noDataPlaceholderDark : noDataPlaceholder\"\n :alt=\"empty.label\"\n class=\"h-32\"\n />\n <p\n v-if=\"empty.label\"\n :class=\"$style.empty__label\"\n data-id=\"empty-label\"\n >\n {{ empty.label }}\n </p>\n\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"empty-description\">\n <p\n v-if=\"empty.description\"\n :class=\"$style.empty__description\"\n data-id=\"empty-description\"\n >\n {{ empty.description }}\n </p>\n </slot>\n </div>\n </slot>\n </td>\n </Transition>\n </tr>\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n v-if=\"slots['body.append']\"\n :colspan=\"colspan\"\n name=\"body.append\"\n />\n </tbody>\n <tfoot>\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"tfoot\" />\n </tfoot>\n </table>\n </div>\n <RuiTablePagination\n v-if=\"paginationData && !hideDefaultFooter\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :disable-per-page=\"disablePerPage\"\n data-cy=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n </div>\n</template>\n\n<style module lang=\"scss\">\n.wrapper {\n @apply relative divide-y divide-black/[0.12] overflow-hidden;\n &.outlined {\n @apply border border-black/[0.12];\n }\n\n &.rounded__sm {\n @apply rounded-[.25rem];\n }\n &.rounded__md {\n @apply rounded-[.75rem];\n }\n &.rounded__lg {\n @apply rounded-[1rem];\n }\n\n .scroller {\n @apply overflow-x-auto overflow-y-hidden;\n clip-path: inset(0 0 0 0);\n }\n\n .table {\n @apply min-w-full table-fixed divide-y divide-black/[0.12] whitespace-nowrap mx-auto my-0 max-w-fit relative border-black/[0.12];\n\n .tbody {\n @apply divide-y divide-black/[0.12];\n\n &--striped {\n > .tr {\n &:nth-child(even) {\n @apply bg-rui-grey-50;\n }\n }\n }\n\n > .tr {\n @apply hover:bg-black/[0.04];\n\n &__selected {\n @apply bg-rui-primary/[0.08];\n }\n\n &__empty {\n @apply hover:bg-transparent;\n }\n\n &__expandable {\n @apply bg-[#f9fafb] hover:bg-[#f9fafb];\n }\n\n &__group {\n @apply bg-black/[0.02];\n }\n\n .td {\n @apply p-4 text-rui-text text-body-2;\n text-wrap: initial;\n\n &.align__start {\n @apply text-left rtl:text-right;\n }\n\n &.align__center {\n @apply text-center;\n }\n\n &.align__end {\n @apply text-right rtl:text-left;\n }\n\n .empty {\n @apply flex flex-col gap-3 items-center justify-center flex-1 min-h-56 my-4;\n\n &__label {\n @apply text-body-1 leading-none font-bold text-center text-current pb-0 mb-0;\n }\n\n &__description {\n @apply text-body-2 text-center text-rui-text-secondary pb-0 mb-0;\n }\n }\n }\n }\n\n &__loader {\n @apply py-8 text-center min-h-56;\n }\n }\n\n .checkbox {\n @apply px-2 w-[3.625rem] max-w-[3.625rem];\n label {\n @apply ml-0;\n }\n }\n\n &.dense {\n .tbody {\n .td {\n @apply py-[0.38rem];\n }\n }\n }\n }\n}\n\n:global(.dark) {\n .wrapper {\n @apply divide-white/[0.12];\n\n &.outlined {\n @apply border-white/[0.12];\n }\n\n .table {\n @apply divide-white/[0.12] border-white/[0.12];\n\n .tbody {\n @apply divide-white/[0.12];\n\n &--striped {\n > .tr {\n &:nth-child(even) {\n @apply bg-rui-grey-900;\n }\n }\n }\n\n > .tr {\n @apply hover:bg-white/[0.04];\n\n &__selected {\n @apply bg-rui-dark-primary/[0.08];\n }\n\n &__expandable {\n @apply bg-[#121212] hover:bg-[#121212];\n }\n\n &__group {\n @apply bg-white/[0.02];\n }\n }\n }\n }\n }\n}\n</style>\n"],"names":["_useModel","_useSlots","_createElementBlock","_normalizeClass","$style","_unref","_createBlock","_createElementVNode","_createVNode","_renderList","_withCtx","_renderSlot","_normalizeProps","_guardReactiveProps","_openBlock","_Fragment","_toDisplayString","_createTextVNode","_Transition"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RuiDataTable.vue2.js","sources":["../../../src/components/tables/RuiDataTable.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends object, IdType extends keyof T = keyof T\">\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiCheckbox from '@/components/forms/checkbox/RuiCheckbox.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiTooltip from '@/components/overlays/tooltip/RuiTooltip.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport RuiExpandButton from '@/components/tables/RuiExpandButton.vue';\nimport RuiTableHead, {\n type GroupData,\n type TableColumn,\n type TableRowKeyData,\n type TableSortData,\n} from '@/components/tables/RuiTableHead.vue';\nimport RuiTablePagination, {\n type TablePaginationData,\n} from '@/components/tables/RuiTablePagination.vue';\nimport noDataPlaceholder from '@/components/tables/table_no_data_placeholder.svg';\nimport noDataPlaceholderDark from '@/components/tables/table_no_data_placeholder_dark.svg';\nimport { useTable } from '@/composables/defaults/table';\nimport { useStickyTableHeader } from '@/composables/sticky-header';\nimport { useTableColumns } from '@/composables/tables/data-table/columns';\nimport { useTableExpansion } from '@/composables/tables/data-table/expansion';\nimport { useTableGrouping } from '@/composables/tables/data-table/grouping';\nimport { useTablePagination } from '@/composables/tables/data-table/pagination';\nimport { useTableSelection } from '@/composables/tables/data-table/selection';\nimport { useTableSort } from '@/composables/tables/data-table/sort';\nimport { type GroupHeader, isRow } from '@/composables/tables/data-table/types';\nimport { useRotkiTheme } from '@/composables/theme';\n\nexport type { GroupedTableRow, GroupHeader, TableOptions } from '@/composables/tables/data-table/types';\n\nexport interface Props<T, K extends keyof T> {\n /**\n * list of items for each row\n */\n rows: readonly T[];\n /**\n * the attribute used to identify each row uniquely for selection, usually `id`\n */\n rowAttr: K;\n /**\n * model for internal searching\n */\n search?: string;\n /**\n * model for items per page\n * will be used if the `pagination` model isn't specified\n */\n itemsPerPage?: number;\n /**\n * list of column definitions\n */\n cols?: TableColumn<T>[];\n /**\n * attribute to use from column definitions to display column titles\n */\n columnAttr?: keyof TableColumn<T>;\n /**\n * flag to show a more or less spacious table\n */\n dense?: boolean;\n /**\n * flag to outline the flag with a border\n */\n outlined?: boolean;\n /**\n * should add zebra-striping to the table row\n */\n striped?: boolean;\n /**\n * flag to show loading state of the table\n * triggers indefinite progress at the bottom of the table header\n */\n loading?: boolean;\n disablePerPage?: boolean;\n /**\n * data to display for empty state\n * text and icon\n * @example :empty=\"{ icon: 'transactions-line', label: 'No transactions found' }\"\n */\n empty?: {\n label?: string;\n description?: string;\n };\n /**\n * should hide the header navigation\n */\n hideDefaultHeader?: boolean;\n /**\n * should hide the footer navigation\n */\n hideDefaultFooter?: boolean;\n\n rounded?: 'sm' | 'md' | 'lg';\n /**\n * make expansion work like accordion\n */\n singleExpand?: boolean;\n /**\n * make table head stick to top on scroll\n */\n stickyHeader?: boolean;\n stickyOffset?: number;\n /**\n * Affects how the items per page work across the app.\n * When true, changing the items per page setting in one table will affect other tables.\n */\n globalItemsPerPage?: boolean;\n groupExpandButtonPosition?: 'start' | 'end';\n disabledRows?: readonly T[];\n multiPageSelect?: boolean;\n itemClass?: ((item: T) => string) | string;\n}\n\ndefineOptions({\n name: 'RuiDataTable',\n});\n\nconst selectedData = defineModel<T[IdType][]>();\n\nconst expanded = defineModel<T[]>('expanded');\n\nconst [pagination, paginationModifiers] = defineModel<TablePaginationData, 'external'>('pagination');\n\nconst [sort, sortModifiers] = defineModel<TableSortData<T>, 'external'>('sort');\n\nconst group = defineModel<TableRowKeyData<T>>('group');\n\nconst collapsed = defineModel<T[]>('collapsed');\n\nconst {\n rows,\n rowAttr,\n search = '',\n itemsPerPage = 10,\n cols,\n columnAttr = 'label',\n dense = false,\n outlined = false,\n striped = false,\n loading = false,\n disablePerPage = false,\n empty = { label: 'No item found' },\n hideDefaultHeader = false,\n hideDefaultFooter = false,\n rounded = 'md',\n singleExpand = false,\n stickyHeader = false,\n stickyOffset,\n globalItemsPerPage = undefined,\n groupExpandButtonPosition = 'start',\n disabledRows,\n multiPageSelect = false,\n itemClass = '',\n} = defineProps<Props<T, IdType>>();\n\nconst emit = defineEmits<{\n 'update:options': [value: { pagination?: TablePaginationData; sort?: TableSortData<T> }];\n 'copy:group': [value: GroupData<T>];\n}>();\n\nconst slots = defineSlots<Partial<\n Record<`header.${string}`, (props: { column: TableColumn<T> }) => any> &\n Record<`item.${string}`, (props: { column: TableColumn<T>; row: T; index: number }) => any> & {\n 'body.prepend': (props: { colspan: number }) => any;\n 'body.append': (props: { colspan: number }) => any;\n 'group.header': (props: {\n colspan: number;\n header: GroupHeader<T>;\n isOpen: boolean;\n toggle: () => void;\n }) => any;\n 'group.header.content': (props: { header: GroupHeader<T>; groupKey: string }) => any;\n 'expanded-item': (props: { row: T; index: number }) => any;\n 'no-data': () => any;\n 'empty-description': () => any;\n 'tfoot': () => any;\n }\n>>();\n\nconst tableDefaults = useTable();\n\nconst { isDark } = useRotkiTheme();\n\nconst stickyHeaderOffset = computed<number | undefined>(() =>\n stickyOffset !== undefined ? stickyOffset : get(tableDefaults.stickyOffset),\n);\n\nconst table = useTemplateRef<HTMLTableElement>('table');\nconst tableScroller = useTemplateRef<HTMLElement>('tableScroller');\n\nconst { stick } = useStickyTableHeader(\n () => stickyHeader,\n stickyHeaderOffset,\n { table, tableScroller },\n);\n\nconst hasExpandedItemSlot = computed<boolean>(() => !!slots['expanded-item']);\n\nconst { expandable, isExpanded, onToggleExpand } = useTableExpansion<T, IdType>(\n { rowAttr, singleExpand },\n { expanded, hasExpandedItemSlot },\n);\n\nfunction emitUpdateOptions(opts: { sort?: TableSortData<T>; pagination?: TablePaginationData }): void {\n emit('update:options', opts);\n}\n\nconst {\n sortData,\n sortedMap,\n sorted,\n onSort: applySort,\n} = useTableSort<T>(\n { rows: () => rows, search: () => search, sortModifiersExternal: sortModifiers.external },\n {\n sort,\n pagination,\n emitUpdateOptions,\n },\n);\n\nconst {\n groupKeys,\n groupKey,\n grouped,\n isExpandedGroup,\n isHiddenRow,\n onToggleExpandGroup,\n onUngroup,\n onCopyGroup,\n} = useTableGrouping<T, IdType>(\n { rowAttr },\n {\n group,\n collapsed,\n sorted,\n emitCopyGroup: (value: GroupData<T>) => emit('copy:group', value),\n },\n);\n\nconst {\n paginationData,\n filtered,\n setInternalTotal,\n resetPagination,\n} = useTablePagination<T>(\n {\n itemsPerPage,\n paginationModifiersExternal: paginationModifiers.external,\n globalItemsPerPage,\n },\n {\n pagination,\n grouped,\n isHiddenRow,\n sort,\n emitUpdateOptions,\n tableDefaults,\n },\n);\n\nconst noData = computed<boolean>(() => get(filtered).length === 0);\n\nconst { columns, colspan, headerSlots, cellValue } = useTableColumns<T, IdType>({\n cols: () => cols,\n columnAttr,\n rows: () => rows,\n expandable,\n groupKeys,\n selectedData,\n slots,\n});\n\nconst {\n isAllSelected,\n indeterminate,\n isSelected,\n isDisabledRow,\n onToggleAll,\n onSelect,\n onCheckboxClick,\n deselectRemovedRows,\n resetCheckboxShiftState,\n} = useTableSelection<T, IdType>(\n { rowAttr, multiPageSelect, disabledRows: () => disabledRows },\n { selectedData, filtered },\n);\n\n// Sort triggers selection reset — handled here to avoid circular dependency between sort and selection\nfunction onSort(payload: Parameters<typeof applySort>[0]): void {\n applySort(payload);\n if (!multiPageSelect)\n onToggleAll(false);\n resetCheckboxShiftState();\n}\n\nfunction onPaginate(): void {\n set(expanded, []);\n if (!multiPageSelect)\n onToggleAll(false);\n resetCheckboxShiftState();\n}\n\n// Reset pagination page to 1 on search query change\nwatch(() => search, () => {\n resetPagination();\n onToggleAll(false);\n resetCheckboxShiftState();\n});\n\nwatch(sorted, (items) => {\n if (!multiPageSelect)\n deselectRemovedRows();\n setInternalTotal(items);\n});\n\nonMounted(() => {\n setInternalTotal(get(sorted));\n});\n</script>\n\n<template>\n <div\n :class=\"[$style.wrapper, $style[`rounded__${rounded}`], { [$style.outlined]: outlined }]\"\n data-id=\"table-wrapper\"\n >\n <RuiTablePagination\n v-if=\"paginationData && !hideDefaultHeader\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :disable-per-page=\"disablePerPage\"\n data-cy=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n <div\n ref=\"tableScroller\"\n :class=\"$style.scroller\"\n data-id=\"table-scroller\"\n >\n <table\n ref=\"table\"\n :class=\"[$style.table, { [$style.dense]: dense }]\"\n :aria-busy=\"loading\"\n >\n <RuiTableHead\n :loading=\"loading\"\n :indeterminate=\"indeterminate\"\n :capitalize-headers=\"!cols\"\n :colspan=\"colspan\"\n :column-attr=\"columnAttr\"\n :columns=\"columns\"\n :dense=\"dense\"\n :disable-check-all=\"!filtered?.length\"\n :is-all-selected=\"isAllSelected\"\n :no-data=\"noData\"\n :selectable=\"!!selectedData\"\n :sort-data=\"sortData\"\n :sorted-map=\"sortedMap\"\n :stick=\"stick\"\n :sticky-header=\"stickyHeader\"\n @sort=\"onSort($event)\"\n @select:all=\"onToggleAll($event)\"\n >\n <template\n v-for=\"headerSlot in headerSlots\"\n #[headerSlot]=\"slotData\"\n >\n <slot\n :name=\"headerSlot\"\n v-bind=\"slotData\"\n />\n </template>\n </RuiTableHead>\n <RuiTableHead\n v-if=\"stickyHeader\"\n :loading=\"loading\"\n :capitalize-headers=\"!cols\"\n :colspan=\"colspan\"\n :column-attr=\"columnAttr\"\n :columns=\"columns\"\n :dense=\"dense\"\n :no-data=\"noData\"\n :selectable=\"!!selectedData\"\n :sort-data=\"sortData\"\n :sorted-map=\"sortedMap\"\n data-id=\"head-clone\"\n class=\"opacity-0 invisible\"\n >\n <template\n v-for=\"headerSlot in headerSlots\"\n #[headerSlot]=\"slotData\"\n >\n <slot\n :name=\"headerSlot\"\n v-bind=\"slotData\"\n />\n </template>\n </RuiTableHead>\n <tbody :class=\"[$style.tbody, { [$style['tbody--striped'] ?? '']: striped }]\">\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n v-if=\"slots['body.prepend']\"\n :colspan=\"colspan\"\n name=\"body.prepend\"\n />\n <template v-for=\"(row, index) in filtered\">\n <tr\n v-if=\"!isRow(row)\"\n :key=\"`row-${index}`\"\n :class=\"[$style.tr, $style.tr__group]\"\n data-id=\"row-group\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header\"\n :colspan=\"colspan\"\n :header=\"row\"\n :is-open=\"isExpandedGroup(row.group)\"\n :toggle=\"() => onToggleExpandGroup(row.group, row.identifier)\"\n >\n <td\n :class=\"[$style.td]\"\n class=\"!p-2\"\n :colspan=\"colspan\"\n >\n <div class=\"flex items-center gap-2\">\n <RuiExpandButton\n v-if=\"groupExpandButtonPosition === 'start'\"\n :expanded=\"isExpandedGroup(row.group)\"\n @click=\"onToggleExpandGroup(row.group, row.identifier)\"\n />\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n :group-key=\"groupKey\"\n name=\"group.header.content\"\n :header=\"row\"\n >\n <span>{{ groupKey }}: {{ row.identifier }}</span>\n <RuiButton\n size=\"sm\"\n variant=\"text\"\n icon\n data-cy=\"group-copy-button\"\n @click=\"onCopyGroup({ key: groupKey, value: row.group })\"\n >\n <RuiIcon\n name=\"lu-copy\"\n size=\"16\"\n />\n </RuiButton>\n </slot>\n <RuiTooltip\n :popper=\"{ placement: 'top' }\"\n class=\"ml-auto mr-2\"\n >\n <template #activator>\n <RuiButton\n size=\"sm\"\n variant=\"text\"\n icon\n data-cy=\"group-ungroup-button\"\n @click=\"onUngroup()\"\n >\n <RuiIcon\n name=\"lu-trash-2\"\n size=\"14\"\n />\n </RuiButton>\n </template>\n Ungroup\n </RuiTooltip>\n <RuiExpandButton\n v-if=\"groupExpandButtonPosition === 'end'\"\n :expanded=\"isExpandedGroup(row.group)\"\n @click=\"onToggleExpandGroup(row.group, row.identifier)\"\n />\n </div>\n </td>\n </slot>\n </tr>\n <template v-else>\n <tr\n :key=\"`row-${index}`\"\n :class=\"[\n $style.tr,\n { [$style.tr__selected ?? '']: isSelected(row[rowAttr]) },\n typeof itemClass === 'string' ? itemClass : itemClass(row),\n ]\"\n :aria-selected=\"selectedData ? isSelected(row[rowAttr]) : undefined\"\n data-id=\"row\"\n >\n <td\n v-if=\"selectedData\"\n :class=\"$style.checkbox\"\n colspan=\"1\"\n rowspan=\"1\"\n >\n <RuiCheckbox\n :data-cy=\"`table-toggle-check-${index}`\"\n :model-value=\"isSelected(row[rowAttr])\"\n :disabled=\"isDisabledRow(row[rowAttr])\"\n :size=\"dense ? 'sm' : undefined\"\n color=\"primary\"\n class=\"select-none\"\n hide-details\n @update:model-value=\"onSelect($event, row[rowAttr], true)\"\n @click=\"onCheckboxClick($event, row[rowAttr], index)\"\n />\n </td>\n\n <td\n v-for=\"(column, subIndex) in columns\"\n :key=\"subIndex\"\n :class=\"[\n $style.td,\n column.cellClass,\n $style[`align__${column.align ?? 'start'}`],\n ]\"\n :colspan=\"column.colspan ?? 1\"\n :rowspan=\"column.rowspan ?? 1\"\n >\n <slot\n v-if=\"column.key === 'expand'\"\n :name=\"`item.${column.key.toString()}`\"\n :column=\"column\"\n :row=\"row\"\n :index=\"index\"\n >\n <RuiExpandButton\n v-if=\"!slots['item.expand']\"\n :expanded=\"isExpanded(row[rowAttr])\"\n @click=\"onToggleExpand(row)\"\n />\n </slot>\n <slot\n v-else\n :column=\"column\"\n :index=\"index\"\n :name=\"`item.${column.key.toString()}`\"\n :row=\"row\"\n >\n {{ cellValue(row, column.key) }}\n </slot>\n </td>\n </tr>\n\n <tr\n v-if=\"expandable && isExpanded(row[rowAttr])\"\n :key=\"`row-expand-${index}`\"\n :class=\"[$style.tr, $style.tr__expandable]\"\n data-id=\"row-expanded\"\n >\n <td\n :colspan=\"colspan\"\n :class=\"[$style.td]\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"expanded-item\"\n :row=\"row\"\n :index=\"index\"\n />\n </td>\n </tr>\n </template>\n </template>\n <tr v-if=\"loading && noData\">\n <td\n :class=\"$style.tbody__loader\"\n :colspan=\"colspan\"\n data-id=\"tbody-loader\"\n >\n <RuiProgress\n color=\"primary\"\n variant=\"indeterminate\"\n circular\n />\n </td>\n </tr>\n <tr\n v-if=\"noData && empty && !loading\"\n :class=\"[$style.tr, $style.tr__empty]\"\n data-id=\"row-empty\"\n >\n <Transition\n appear\n enter-active-class=\"transition ease-out duration-200 delay-200\"\n enter-from-class=\"opacity-0 translate-y-1\"\n enter-to-class=\"opacity-100 translate-y-0\"\n leave-active-class=\"transition ease-in duration-150\"\n leave-from-class=\"opacity-100 translate-y-0\"\n leave-to-class=\"opacity-0 translate-y-1\"\n >\n <td\n :class=\"$style.td\"\n :colspan=\"colspan\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"no-data\">\n <div :class=\"$style.empty\">\n <img\n :src=\"isDark ? noDataPlaceholderDark : noDataPlaceholder\"\n :alt=\"empty.label\"\n class=\"h-32\"\n />\n <p\n v-if=\"empty.label\"\n :class=\"$style.empty__label\"\n data-id=\"empty-label\"\n >\n {{ empty.label }}\n </p>\n\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"empty-description\">\n <p\n v-if=\"empty.description\"\n :class=\"$style.empty__description\"\n data-id=\"empty-description\"\n >\n {{ empty.description }}\n </p>\n </slot>\n </div>\n </slot>\n </td>\n </Transition>\n </tr>\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n v-if=\"slots['body.append']\"\n :colspan=\"colspan\"\n name=\"body.append\"\n />\n </tbody>\n <tfoot>\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"tfoot\" />\n </tfoot>\n </table>\n </div>\n <RuiTablePagination\n v-if=\"paginationData && !hideDefaultFooter\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :disable-per-page=\"disablePerPage\"\n data-cy=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n </div>\n</template>\n\n<style module lang=\"scss\">\n.wrapper {\n @apply relative divide-y divide-black/[0.12] overflow-hidden;\n &.outlined {\n @apply border border-black/[0.12];\n }\n\n &.rounded__sm {\n @apply rounded-[.25rem];\n }\n &.rounded__md {\n @apply rounded-[.75rem];\n }\n &.rounded__lg {\n @apply rounded-[1rem];\n }\n\n .scroller {\n @apply overflow-x-auto overflow-y-hidden;\n clip-path: inset(0 0 0 0);\n }\n\n .table {\n @apply min-w-full table-fixed divide-y divide-black/[0.12] whitespace-nowrap mx-auto my-0 max-w-fit relative border-black/[0.12];\n\n .tbody {\n @apply divide-y divide-black/[0.12];\n\n &--striped {\n > .tr {\n &:nth-child(even) {\n @apply bg-rui-grey-50;\n }\n }\n }\n\n > .tr {\n @apply hover:bg-black/[0.04];\n\n &__selected {\n @apply bg-rui-primary/[0.08];\n }\n\n &__empty {\n @apply hover:bg-transparent;\n }\n\n &__expandable {\n @apply bg-[#f9fafb] hover:bg-[#f9fafb];\n }\n\n &__group {\n @apply bg-black/[0.02];\n }\n\n .td {\n @apply p-4 text-rui-text text-body-2;\n text-wrap: initial;\n\n &.align__start {\n @apply text-left rtl:text-right;\n }\n\n &.align__center {\n @apply text-center;\n }\n\n &.align__end {\n @apply text-right rtl:text-left;\n }\n\n .empty {\n @apply flex flex-col gap-3 items-center justify-center flex-1 min-h-56 my-4;\n\n &__label {\n @apply text-body-1 leading-none font-bold text-center text-current pb-0 mb-0;\n }\n\n &__description {\n @apply text-body-2 text-center text-rui-text-secondary pb-0 mb-0;\n }\n }\n }\n }\n\n &__loader {\n @apply py-8 text-center min-h-56;\n }\n }\n\n .checkbox {\n @apply px-2 w-[3.625rem] max-w-[3.625rem];\n label {\n @apply ml-0;\n }\n }\n\n &.dense {\n .tbody {\n .td {\n @apply py-[0.38rem];\n }\n }\n }\n }\n}\n\n:global(.dark) {\n .wrapper {\n @apply divide-white/[0.12];\n\n &.outlined {\n @apply border-white/[0.12];\n }\n\n .table {\n @apply divide-white/[0.12] border-white/[0.12];\n\n .tbody {\n @apply divide-white/[0.12];\n\n &--striped {\n > .tr {\n &:nth-child(even) {\n @apply bg-rui-grey-900;\n }\n }\n }\n\n > .tr {\n @apply hover:bg-white/[0.04];\n\n &__selected {\n @apply bg-rui-dark-primary/[0.08];\n }\n\n &__expandable {\n @apply bg-[#121212] hover:bg-[#121212];\n }\n\n &__group {\n @apply bg-white/[0.02];\n }\n }\n }\n }\n }\n}\n</style>\n"],"names":["_useModel","_useSlots","_createElementBlock","_normalizeClass","$style","_unref","_createBlock","_createElementVNode","_createVNode","_renderList","_withCtx","_renderSlot","_normalizeProps","_guardReactiveProps","_openBlock","_Fragment","_toDisplayString","_createTextVNode","_Transition"],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MaybeRefOrGetter, Ref, ShallowRef } from 'vue';
|
|
2
2
|
export interface UseStickyTableHeaderRefs {
|
|
3
3
|
table: Readonly<ShallowRef<HTMLTableElement | null>>;
|
|
4
4
|
tableScroller: Readonly<ShallowRef<HTMLElement | null>>;
|
|
5
5
|
}
|
|
6
|
+
interface UseStickyTableHeaderReturn {
|
|
7
|
+
stick: Readonly<Ref<boolean>>;
|
|
8
|
+
}
|
|
6
9
|
/**
|
|
7
10
|
* Setup sticky table header
|
|
8
11
|
*/
|
|
9
|
-
export declare function useStickyTableHeader(sticky:
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
+
export declare function useStickyTableHeader(sticky: MaybeRefOrGetter<boolean> | undefined, offsetTop: MaybeRefOrGetter<number | undefined>, tableRefs: UseStickyTableHeaderRefs): UseStickyTableHeaderReturn;
|
|
13
|
+
export {};
|
|
@@ -1,95 +1,143 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { shallowRef, onMounted } from "vue";
|
|
3
|
-
import { get, set } from "@vueuse/shared";
|
|
1
|
+
import { shallowRef, onMounted, readonly, toValue } from "vue";
|
|
4
2
|
import { useEventListener, useMutationObserver, useResizeObserver } from "@vueuse/core";
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import { set, get } from "@vueuse/shared";
|
|
4
|
+
const SELECTORS = {
|
|
5
|
+
head: ":scope > thead[data-id=head-main]",
|
|
6
|
+
headClone: ":scope > thead[data-id=head-clone]",
|
|
7
|
+
row: ":scope > tbody > tr:not([hidden])",
|
|
8
|
+
th: ":scope > th"
|
|
9
|
+
};
|
|
10
|
+
const BORDER_PRECISION = -0.5;
|
|
11
|
+
function queryHeadRow(root, selector) {
|
|
12
|
+
return root.querySelector(`${selector} > tr`);
|
|
13
|
+
}
|
|
14
|
+
function queryColumns(row) {
|
|
15
|
+
if (!row)
|
|
16
|
+
return [];
|
|
17
|
+
return Array.from(row.querySelectorAll(SELECTORS.th));
|
|
18
|
+
}
|
|
19
|
+
function clearColumnWidths(columns) {
|
|
20
|
+
for (const column of columns)
|
|
21
|
+
column.style.width = "";
|
|
22
|
+
}
|
|
23
|
+
function readColumnWidths(columns) {
|
|
24
|
+
return columns.map((col) => col.getBoundingClientRect().width);
|
|
25
|
+
}
|
|
26
|
+
function applyColumnWidths(columns, widths) {
|
|
27
|
+
for (const [i, column] of columns.entries()) {
|
|
28
|
+
const width = widths[i];
|
|
29
|
+
if (width !== void 0)
|
|
30
|
+
column.style.width = `${width}px`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function positionHeadAtRest(head) {
|
|
34
|
+
head.style.left = `${BORDER_PRECISION}px`;
|
|
35
|
+
head.style.top = "0";
|
|
36
|
+
}
|
|
37
|
+
function positionHeadStuck(head, { clonedRect, lastRowHeight, tableRect, top }) {
|
|
38
|
+
head.style.left = `${clonedRect.left + BORDER_PRECISION}px`;
|
|
39
|
+
const isNearBottom = tableRect.bottom <= lastRowHeight + clonedRect.height + top;
|
|
40
|
+
head.style.top = isNearBottom ? `${tableRect.bottom - lastRowHeight - clonedRect.height}px` : `${top}px`;
|
|
41
|
+
}
|
|
42
|
+
function isInStickyRange(tableRect, top) {
|
|
43
|
+
return tableRect.top <= top && tableRect.bottom > top;
|
|
44
|
+
}
|
|
45
|
+
function getLastRowHeight(root) {
|
|
46
|
+
const rows = root.querySelectorAll(SELECTORS.row);
|
|
47
|
+
if (rows.length <= 1)
|
|
48
|
+
return void 0;
|
|
49
|
+
return rows.item(rows.length - 1)?.getBoundingClientRect().height ?? 0;
|
|
50
|
+
}
|
|
51
|
+
function useStickyTableHeader(sticky = shallowRef(false), offsetTop, tableRefs) {
|
|
52
|
+
const { table, tableScroller } = tableRefs;
|
|
7
53
|
const stick = shallowRef(false);
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
54
|
+
let resizeCleanups = [];
|
|
55
|
+
let syncOuterRafId = null;
|
|
56
|
+
let syncInnerRafId = null;
|
|
57
|
+
let rafId = null;
|
|
58
|
+
function cleanupResizeObservers() {
|
|
59
|
+
for (const cleanup of resizeCleanups)
|
|
60
|
+
cleanup();
|
|
61
|
+
resizeCleanups = [];
|
|
62
|
+
}
|
|
63
|
+
function cancelPendingSync() {
|
|
64
|
+
if (syncOuterRafId !== null)
|
|
65
|
+
cancelAnimationFrame(syncOuterRafId);
|
|
66
|
+
if (syncInnerRafId !== null)
|
|
67
|
+
cancelAnimationFrame(syncInnerRafId);
|
|
68
|
+
syncOuterRafId = null;
|
|
69
|
+
syncInnerRafId = null;
|
|
70
|
+
}
|
|
71
|
+
function scheduleSyncWidths(cloneColumns, mainColumns) {
|
|
72
|
+
cancelPendingSync();
|
|
73
|
+
syncOuterRafId = requestAnimationFrame(() => {
|
|
74
|
+
syncOuterRafId = null;
|
|
75
|
+
clearColumnWidths(mainColumns);
|
|
76
|
+
syncInnerRafId = requestAnimationFrame(() => {
|
|
77
|
+
syncInnerRafId = null;
|
|
78
|
+
applyColumnWidths(mainColumns, readColumnWidths(cloneColumns));
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function observeColumnResizes(cloneColumns, mainColumns) {
|
|
83
|
+
cleanupResizeObservers();
|
|
84
|
+
for (const th of cloneColumns) {
|
|
85
|
+
const { stop } = useResizeObserver(th, () => {
|
|
86
|
+
scheduleSyncWidths(cloneColumns, mainColumns);
|
|
87
|
+
});
|
|
88
|
+
resizeCleanups.push(stop);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function watchCellWidth() {
|
|
16
92
|
const root = get(table);
|
|
17
|
-
if (!
|
|
93
|
+
if (!toValue(sticky) || !root)
|
|
18
94
|
return;
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const clonedColumns = theadClone?.querySelectorAll(
|
|
27
|
-
selectors.th
|
|
95
|
+
const cloneRow = queryHeadRow(root, SELECTORS.headClone);
|
|
96
|
+
const mainRow = queryHeadRow(root, SELECTORS.head);
|
|
97
|
+
const cloneColumns = queryColumns(cloneRow);
|
|
98
|
+
const mainColumns = queryColumns(mainRow);
|
|
99
|
+
useMutationObserver(cloneRow, (mutations) => {
|
|
100
|
+
const hasRelevantMutation = mutations.some(
|
|
101
|
+
(m) => m.type === "childList" || m.type === "attributes"
|
|
28
102
|
);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (column)
|
|
36
|
-
column.style.width = `${cellRect.width}px`;
|
|
37
|
-
});
|
|
38
|
-
resizeCleanups.push(stop);
|
|
39
|
-
});
|
|
40
|
-
};
|
|
41
|
-
useMutationObserver(
|
|
42
|
-
theadClone,
|
|
43
|
-
(mutationsList) => {
|
|
44
|
-
for (const mutation of mutationsList) {
|
|
45
|
-
if (mutation.type === "childList" || mutation.type === "attributes")
|
|
46
|
-
observeChildTh();
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
attributes: true,
|
|
51
|
-
childList: true,
|
|
52
|
-
subtree: true
|
|
53
|
-
}
|
|
54
|
-
);
|
|
55
|
-
observeChildTh();
|
|
56
|
-
};
|
|
57
|
-
const toggleStickyClass = () => {
|
|
103
|
+
if (hasRelevantMutation)
|
|
104
|
+
observeColumnResizes(queryColumns(cloneRow), queryColumns(mainRow));
|
|
105
|
+
}, { attributes: true, childList: true, subtree: true });
|
|
106
|
+
observeColumnResizes(cloneColumns, mainColumns);
|
|
107
|
+
}
|
|
108
|
+
function queryStickyElements() {
|
|
58
109
|
const root = get(table);
|
|
59
|
-
if (!
|
|
60
|
-
return;
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
110
|
+
if (!toValue(sticky) || !root)
|
|
111
|
+
return void 0;
|
|
112
|
+
const theadClone = root.querySelector(SELECTORS.headClone);
|
|
113
|
+
const head = root.querySelector(SELECTORS.head);
|
|
114
|
+
if (!theadClone || !head)
|
|
115
|
+
return void 0;
|
|
116
|
+
return { head, root, theadClone };
|
|
117
|
+
}
|
|
118
|
+
function toggleStickyClass() {
|
|
119
|
+
const elements = queryStickyElements();
|
|
120
|
+
if (!elements)
|
|
66
121
|
return;
|
|
67
|
-
const {
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
122
|
+
const { head, root, theadClone } = elements;
|
|
123
|
+
const clonedRect = theadClone.getBoundingClientRect();
|
|
124
|
+
const tableRect = root.getBoundingClientRect();
|
|
125
|
+
const top = toValue(offsetTop) ?? 0;
|
|
126
|
+
head.style.width = `${clonedRect.width}px`;
|
|
127
|
+
const lastRowHeight = getLastRowHeight(root);
|
|
128
|
+
if (lastRowHeight === void 0) {
|
|
73
129
|
set(stick, false);
|
|
74
|
-
head
|
|
75
|
-
head.style.top = "0";
|
|
130
|
+
positionHeadAtRest(head);
|
|
76
131
|
return;
|
|
77
132
|
}
|
|
78
|
-
|
|
79
|
-
if (tableTop <= top && tableBottom > top) {
|
|
133
|
+
if (isInStickyRange(tableRect, top)) {
|
|
80
134
|
set(stick, true);
|
|
81
|
-
head
|
|
82
|
-
const lastRowHeight = lastRowRect?.height ?? 0;
|
|
83
|
-
if (tableBottom <= lastRowHeight + theadHeight + top)
|
|
84
|
-
head.style.top = `${tableBottom - lastRowHeight - theadHeight}px`;
|
|
85
|
-
else head.style.top = `${top}px`;
|
|
135
|
+
positionHeadStuck(head, { clonedRect, lastRowHeight, tableRect, top });
|
|
86
136
|
} else {
|
|
87
137
|
set(stick, false);
|
|
88
|
-
head
|
|
89
|
-
head.style.top = "0";
|
|
138
|
+
positionHeadAtRest(head);
|
|
90
139
|
}
|
|
91
|
-
}
|
|
92
|
-
let rafId = null;
|
|
140
|
+
}
|
|
93
141
|
function throttledToggleStickyClass() {
|
|
94
142
|
if (rafId !== null)
|
|
95
143
|
return;
|
|
@@ -106,7 +154,7 @@ function useStickyTableHeader(sticky = shallowRef(false), offsetTop, refs) {
|
|
|
106
154
|
watchCellWidth();
|
|
107
155
|
});
|
|
108
156
|
return {
|
|
109
|
-
stick
|
|
157
|
+
stick: readonly(stick)
|
|
110
158
|
};
|
|
111
159
|
}
|
|
112
160
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sticky-header.js","sources":["../../src/composables/sticky-header.ts"],"sourcesContent":["import type { MaybeRef, ShallowRef } from 'vue';\nimport { assert } from '@/utils/assert';\n\nexport interface UseStickyTableHeaderRefs {\n table: Readonly<ShallowRef<HTMLTableElement | null>>;\n tableScroller: Readonly<ShallowRef<HTMLElement | null>>;\n}\n\n/**\n * Setup sticky table header\n */\nexport function useStickyTableHeader(\n sticky: MaybeRef<boolean> = shallowRef(false),\n offsetTop: MaybeRef<number | undefined>,\n refs: UseStickyTableHeaderRefs,\n) {\n const { table, tableScroller } = refs;\n const stick = shallowRef<boolean>(false);\n const borderPrecision = -0.5;\n const selectors = {\n head: ':scope > thead[data-id=head-main]',\n headClone: ':scope > thead[data-id=head-clone]',\n row: ':scope > tbody > tr:not([hidden])',\n th: ':scope > th',\n };\n\n const watchCellWidth = (): void => {\n const root = get(table);\n\n if (!get(sticky) || !root)\n return;\n\n const theadClone: HTMLHeadElement | null = root.querySelector(`${selectors.headClone} > tr`);\n\n const head: HTMLHeadElement | null = root.querySelector(`${selectors.head} > tr`);\n\n let resizeCleanups: (() => void)[] = [];\n\n const observeChildTh = (): void => {\n resizeCleanups.forEach(cleanup => cleanup());\n resizeCleanups = [];\n\n const columns: NodeListOf<HTMLElement> | undefined = head?.querySelectorAll(selectors.th);\n\n const clonedColumns: NodeListOf<HTMLElement> | undefined = theadClone?.querySelectorAll(\n selectors.th,\n );\n\n clonedColumns?.forEach((th: HTMLElement, i: number) => {\n const { stop } = useResizeObserver(th, (entries) => {\n const entry = entries[0];\n assert(entry);\n const cellRect = entry.target.getBoundingClientRect();\n const column = columns?.item(i);\n if (column)\n column.style.width = `${cellRect.width}px`;\n });\n resizeCleanups.push(stop);\n });\n };\n\n useMutationObserver(\n theadClone,\n (mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === 'childList' || mutation.type === 'attributes')\n observeChildTh();\n }\n },\n {\n attributes: true,\n childList: true,\n subtree: true,\n },\n );\n\n observeChildTh();\n };\n\n const toggleStickyClass = (): void => {\n const root = get(table);\n\n if (!get(sticky) || !root)\n return;\n\n const rect = root.getBoundingClientRect();\n const theadClone: HTMLHeadElement | null = root.querySelector(selectors.headClone);\n\n const clonedRect: DOMRect | undefined = theadClone?.getBoundingClientRect();\n\n const head: HTMLHeadElement | null = root.querySelector(selectors.head);\n\n if (!clonedRect || !head || !theadClone)\n return;\n\n const { height: theadHeight, left: theadLeft, width: theadWidth } = clonedRect;\n\n const { bottom: tableBottom, top: tableTop } = rect;\n const top = get(offsetTop) ?? 0;\n\n head.style.width = `${theadWidth}px`;\n\n const rows = root.querySelectorAll(selectors.row);\n if (rows.length <= 1) {\n set(stick, false);\n head.style.left = `${borderPrecision}px`;\n head.style.top = '0';\n return;\n }\n\n const lastRowRect: DOMRect | undefined = rows.item(rows.length - 1)?.getBoundingClientRect();\n\n if (tableTop <= top && tableBottom > top) {\n set(stick, true);\n head.style.left = `${theadLeft + borderPrecision}px`;\n\n const lastRowHeight = lastRowRect?.height ?? 0;\n if (tableBottom <= lastRowHeight + theadHeight + top)\n head.style.top = `${tableBottom - lastRowHeight - theadHeight}px`;\n else head.style.top = `${top}px`;\n }\n else {\n set(stick, false);\n head.style.left = `${borderPrecision}px`;\n head.style.top = '0';\n }\n };\n\n let rafId: number | null = null;\n\n function throttledToggleStickyClass(): void {\n if (rafId !== null)\n return;\n rafId = requestAnimationFrame(() => {\n toggleStickyClass();\n rafId = null;\n });\n }\n\n onMounted(() => {\n toggleStickyClass();\n useEventListener(tableScroller, 'scroll', throttledToggleStickyClass);\n useEventListener(document.body, 'scroll', throttledToggleStickyClass);\n useEventListener(window, 'resize', throttledToggleStickyClass);\n watchCellWidth();\n });\n\n return {\n stick,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sticky-header.js","sources":["../../src/composables/sticky-header.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, ShallowRef } from 'vue';\n\nexport interface UseStickyTableHeaderRefs {\n table: Readonly<ShallowRef<HTMLTableElement | null>>;\n tableScroller: Readonly<ShallowRef<HTMLElement | null>>;\n}\n\ninterface StickyElements {\n head: HTMLElement;\n theadClone: HTMLElement;\n root: HTMLTableElement;\n}\n\ninterface UseStickyTableHeaderReturn {\n stick: Readonly<Ref<boolean>>;\n}\n\nconst SELECTORS = {\n head: ':scope > thead[data-id=head-main]',\n headClone: ':scope > thead[data-id=head-clone]',\n row: ':scope > tbody > tr:not([hidden])',\n th: ':scope > th',\n} as const;\n\nconst BORDER_PRECISION = -0.5;\n\nfunction queryHeadRow(root: HTMLTableElement, selector: string): HTMLTableRowElement | null {\n return root.querySelector(`${selector} > tr`);\n}\n\nfunction queryColumns(row: HTMLTableRowElement | null): HTMLElement[] {\n if (!row)\n return [];\n return Array.from(row.querySelectorAll<HTMLElement>(SELECTORS.th));\n}\n\nfunction clearColumnWidths(columns: HTMLElement[]): void {\n for (const column of columns)\n column.style.width = '';\n}\n\nfunction readColumnWidths(columns: HTMLElement[]): number[] {\n return columns.map(col => col.getBoundingClientRect().width);\n}\n\nfunction applyColumnWidths(columns: HTMLElement[], widths: number[]): void {\n for (const [i, column] of columns.entries()) {\n const width = widths[i];\n if (width !== undefined)\n column.style.width = `${width}px`;\n }\n}\n\nfunction positionHeadAtRest(head: HTMLElement): void {\n head.style.left = `${BORDER_PRECISION}px`;\n head.style.top = '0';\n}\n\ninterface StuckPosition {\n clonedRect: DOMRect;\n tableRect: DOMRect;\n lastRowHeight: number;\n top: number;\n}\n\nfunction positionHeadStuck(head: HTMLElement, { clonedRect, lastRowHeight, tableRect, top }: StuckPosition): void {\n head.style.left = `${clonedRect.left + BORDER_PRECISION}px`;\n\n const isNearBottom = tableRect.bottom <= lastRowHeight + clonedRect.height + top;\n head.style.top = isNearBottom\n ? `${tableRect.bottom - lastRowHeight - clonedRect.height}px`\n : `${top}px`;\n}\n\nfunction isInStickyRange(tableRect: DOMRect, top: number): boolean {\n return tableRect.top <= top && tableRect.bottom > top;\n}\n\nfunction getLastRowHeight(root: HTMLTableElement): number | undefined {\n const rows = root.querySelectorAll(SELECTORS.row);\n if (rows.length <= 1)\n return undefined;\n return rows.item(rows.length - 1)?.getBoundingClientRect().height ?? 0;\n}\n\n/**\n * Setup sticky table header\n */\nexport function useStickyTableHeader(\n sticky: MaybeRefOrGetter<boolean> = shallowRef(false),\n offsetTop: MaybeRefOrGetter<number | undefined>,\n tableRefs: UseStickyTableHeaderRefs,\n): UseStickyTableHeaderReturn {\n const { table, tableScroller } = tableRefs;\n const stick = shallowRef<boolean>(false);\n\n let resizeCleanups: (() => void)[] = [];\n let syncOuterRafId: number | null = null;\n let syncInnerRafId: number | null = null;\n let rafId: number | null = null;\n\n function cleanupResizeObservers(): void {\n for (const cleanup of resizeCleanups)\n cleanup();\n resizeCleanups = [];\n }\n\n function cancelPendingSync(): void {\n if (syncOuterRafId !== null)\n cancelAnimationFrame(syncOuterRafId);\n if (syncInnerRafId !== null)\n cancelAnimationFrame(syncInnerRafId);\n syncOuterRafId = null;\n syncInnerRafId = null;\n }\n\n function scheduleSyncWidths(cloneColumns: HTMLElement[], mainColumns: HTMLElement[]): void {\n cancelPendingSync();\n\n syncOuterRafId = requestAnimationFrame(() => {\n syncOuterRafId = null;\n clearColumnWidths(mainColumns);\n\n // Wait one frame for the clone to settle to its natural width after clearing\n syncInnerRafId = requestAnimationFrame(() => {\n syncInnerRafId = null;\n applyColumnWidths(mainColumns, readColumnWidths(cloneColumns));\n });\n });\n }\n\n function observeColumnResizes(cloneColumns: HTMLElement[], mainColumns: HTMLElement[]): void {\n cleanupResizeObservers();\n\n for (const th of cloneColumns) {\n const { stop } = useResizeObserver(th, () => {\n scheduleSyncWidths(cloneColumns, mainColumns);\n });\n resizeCleanups.push(stop);\n }\n }\n\n function watchCellWidth(): void {\n const root = get(table);\n if (!toValue(sticky) || !root)\n return;\n\n const cloneRow = queryHeadRow(root, SELECTORS.headClone);\n const mainRow = queryHeadRow(root, SELECTORS.head);\n const cloneColumns = queryColumns(cloneRow);\n const mainColumns = queryColumns(mainRow);\n\n useMutationObserver(cloneRow, (mutations) => {\n const hasRelevantMutation = mutations.some(\n m => m.type === 'childList' || m.type === 'attributes',\n );\n if (hasRelevantMutation)\n observeColumnResizes(queryColumns(cloneRow), queryColumns(mainRow));\n }, { attributes: true, childList: true, subtree: true });\n\n observeColumnResizes(cloneColumns, mainColumns);\n }\n\n function queryStickyElements(): StickyElements | undefined {\n const root = get(table);\n if (!toValue(sticky) || !root)\n return undefined;\n\n const theadClone = root.querySelector<HTMLElement>(SELECTORS.headClone);\n const head = root.querySelector<HTMLElement>(SELECTORS.head);\n if (!theadClone || !head)\n return undefined;\n\n return { head, root, theadClone };\n }\n\n function toggleStickyClass(): void {\n const elements = queryStickyElements();\n if (!elements)\n return;\n\n const { head, root, theadClone } = elements;\n const clonedRect = theadClone.getBoundingClientRect();\n const tableRect = root.getBoundingClientRect();\n const top = toValue(offsetTop) ?? 0;\n\n head.style.width = `${clonedRect.width}px`;\n\n const lastRowHeight = getLastRowHeight(root);\n if (lastRowHeight === undefined) {\n set(stick, false);\n positionHeadAtRest(head);\n return;\n }\n\n if (isInStickyRange(tableRect, top)) {\n set(stick, true);\n positionHeadStuck(head, { clonedRect, lastRowHeight, tableRect, top });\n }\n else {\n set(stick, false);\n positionHeadAtRest(head);\n }\n }\n\n function throttledToggleStickyClass(): void {\n if (rafId !== null)\n return;\n rafId = requestAnimationFrame(() => {\n toggleStickyClass();\n rafId = null;\n });\n }\n\n onMounted(() => {\n toggleStickyClass();\n useEventListener(tableScroller, 'scroll', throttledToggleStickyClass);\n useEventListener(document.body, 'scroll', throttledToggleStickyClass);\n useEventListener(window, 'resize', throttledToggleStickyClass);\n watchCellWidth();\n });\n\n return {\n stick: readonly(stick),\n };\n}\n"],"names":[],"mappings":";;;AAiBA,MAAM,YAAY;AAAA,EAChB,MAAM;AAAA,EACN,WAAW;AAAA,EACX,KAAK;AAAA,EACL,IAAI;AACN;AAEA,MAAM,mBAAmB;AAEzB,SAAS,aAAa,MAAwB,UAA8C;AAC1F,SAAO,KAAK,cAAc,GAAG,QAAQ,OAAO;AAC9C;AAEA,SAAS,aAAa,KAAgD;AACpE,MAAI,CAAC;AACH,WAAO,CAAA;AACT,SAAO,MAAM,KAAK,IAAI,iBAA8B,UAAU,EAAE,CAAC;AACnE;AAEA,SAAS,kBAAkB,SAA8B;AACvD,aAAW,UAAU;AACnB,WAAO,MAAM,QAAQ;AACzB;AAEA,SAAS,iBAAiB,SAAkC;AAC1D,SAAO,QAAQ,IAAI,CAAA,QAAO,IAAI,sBAAA,EAAwB,KAAK;AAC7D;AAEA,SAAS,kBAAkB,SAAwB,QAAwB;AACzE,aAAW,CAAC,GAAG,MAAM,KAAK,QAAQ,WAAW;AAC3C,UAAM,QAAQ,OAAO,CAAC;AACtB,QAAI,UAAU;AACZ,aAAO,MAAM,QAAQ,GAAG,KAAK;AAAA,EACjC;AACF;AAEA,SAAS,mBAAmB,MAAyB;AACnD,OAAK,MAAM,OAAO,GAAG,gBAAgB;AACrC,OAAK,MAAM,MAAM;AACnB;AASA,SAAS,kBAAkB,MAAmB,EAAE,YAAY,eAAe,WAAW,OAA4B;AAChH,OAAK,MAAM,OAAO,GAAG,WAAW,OAAO,gBAAgB;AAEvD,QAAM,eAAe,UAAU,UAAU,gBAAgB,WAAW,SAAS;AAC7E,OAAK,MAAM,MAAM,eACb,GAAG,UAAU,SAAS,gBAAgB,WAAW,MAAM,OACvD,GAAG,GAAG;AACZ;AAEA,SAAS,gBAAgB,WAAoB,KAAsB;AACjE,SAAO,UAAU,OAAO,OAAO,UAAU,SAAS;AACpD;AAEA,SAAS,iBAAiB,MAA4C;AACpE,QAAM,OAAO,KAAK,iBAAiB,UAAU,GAAG;AAChD,MAAI,KAAK,UAAU;AACjB,WAAO;AACT,SAAO,KAAK,KAAK,KAAK,SAAS,CAAC,GAAG,wBAAwB,UAAU;AACvE;AAKO,SAAS,qBACd,SAAoC,WAAW,KAAK,GACpD,WACA,WAC4B;AAC5B,QAAM,EAAE,OAAO,cAAA,IAAkB;AACjC,QAAM,QAAQ,WAAoB,KAAK;AAEvC,MAAI,iBAAiC,CAAA;AACrC,MAAI,iBAAgC;AACpC,MAAI,iBAAgC;AACpC,MAAI,QAAuB;AAE3B,WAAS,yBAA+B;AACtC,eAAW,WAAW;AACpB,cAAA;AACF,qBAAiB,CAAA;AAAA,EACnB;AAEA,WAAS,oBAA0B;AACjC,QAAI,mBAAmB;AACrB,2BAAqB,cAAc;AACrC,QAAI,mBAAmB;AACrB,2BAAqB,cAAc;AACrC,qBAAiB;AACjB,qBAAiB;AAAA,EACnB;AAEA,WAAS,mBAAmB,cAA6B,aAAkC;AACzF,sBAAA;AAEA,qBAAiB,sBAAsB,MAAM;AAC3C,uBAAiB;AACjB,wBAAkB,WAAW;AAG7B,uBAAiB,sBAAsB,MAAM;AAC3C,yBAAiB;AACjB,0BAAkB,aAAa,iBAAiB,YAAY,CAAC;AAAA,MAC/D,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,WAAS,qBAAqB,cAA6B,aAAkC;AAC3F,2BAAA;AAEA,eAAW,MAAM,cAAc;AAC7B,YAAM,EAAE,KAAA,IAAS,kBAAkB,IAAI,MAAM;AAC3C,2BAAmB,cAAc,WAAW;AAAA,MAC9C,CAAC;AACD,qBAAe,KAAK,IAAI;AAAA,IAC1B;AAAA,EACF;AAEA,WAAS,iBAAuB;AAC9B,UAAM,OAAO,IAAI,KAAK;AACtB,QAAI,CAAC,QAAQ,MAAM,KAAK,CAAC;AACvB;AAEF,UAAM,WAAW,aAAa,MAAM,UAAU,SAAS;AACvD,UAAM,UAAU,aAAa,MAAM,UAAU,IAAI;AACjD,UAAM,eAAe,aAAa,QAAQ;AAC1C,UAAM,cAAc,aAAa,OAAO;AAExC,wBAAoB,UAAU,CAAC,cAAc;AAC3C,YAAM,sBAAsB,UAAU;AAAA,QACpC,CAAA,MAAK,EAAE,SAAS,eAAe,EAAE,SAAS;AAAA,MAAA;AAE5C,UAAI;AACF,6BAAqB,aAAa,QAAQ,GAAG,aAAa,OAAO,CAAC;AAAA,IACtE,GAAG,EAAE,YAAY,MAAM,WAAW,MAAM,SAAS,MAAM;AAEvD,yBAAqB,cAAc,WAAW;AAAA,EAChD;AAEA,WAAS,sBAAkD;AACzD,UAAM,OAAO,IAAI,KAAK;AACtB,QAAI,CAAC,QAAQ,MAAM,KAAK,CAAC;AACvB,aAAO;AAET,UAAM,aAAa,KAAK,cAA2B,UAAU,SAAS;AACtE,UAAM,OAAO,KAAK,cAA2B,UAAU,IAAI;AAC3D,QAAI,CAAC,cAAc,CAAC;AAClB,aAAO;AAET,WAAO,EAAE,MAAM,MAAM,WAAA;AAAA,EACvB;AAEA,WAAS,oBAA0B;AACjC,UAAM,WAAW,oBAAA;AACjB,QAAI,CAAC;AACH;AAEF,UAAM,EAAE,MAAM,MAAM,WAAA,IAAe;AACnC,UAAM,aAAa,WAAW,sBAAA;AAC9B,UAAM,YAAY,KAAK,sBAAA;AACvB,UAAM,MAAM,QAAQ,SAAS,KAAK;AAElC,SAAK,MAAM,QAAQ,GAAG,WAAW,KAAK;AAEtC,UAAM,gBAAgB,iBAAiB,IAAI;AAC3C,QAAI,kBAAkB,QAAW;AAC/B,UAAI,OAAO,KAAK;AAChB,yBAAmB,IAAI;AACvB;AAAA,IACF;AAEA,QAAI,gBAAgB,WAAW,GAAG,GAAG;AACnC,UAAI,OAAO,IAAI;AACf,wBAAkB,MAAM,EAAE,YAAY,eAAe,WAAW,KAAK;AAAA,IACvE,OACK;AACH,UAAI,OAAO,KAAK;AAChB,yBAAmB,IAAI;AAAA,IACzB;AAAA,EACF;AAEA,WAAS,6BAAmC;AAC1C,QAAI,UAAU;AACZ;AACF,YAAQ,sBAAsB,MAAM;AAClC,wBAAA;AACA,cAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,YAAU,MAAM;AACd,sBAAA;AACA,qBAAiB,eAAe,UAAU,0BAA0B;AACpE,qBAAiB,SAAS,MAAM,UAAU,0BAA0B;AACpE,qBAAiB,QAAQ,UAAU,0BAA0B;AAC7D,mBAAA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,OAAO,SAAS,KAAK;AAAA,EAAA;AAEzB;"}
|
package/dist/icons/icons_1.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ export declare const LuOsWindows: GeneratedIcon;
|
|
|
44
44
|
export declare const LuPaypal: GeneratedIcon;
|
|
45
45
|
export declare const LuRadioButtonFill: GeneratedIcon;
|
|
46
46
|
export declare const LuReceiveDonationFill: GeneratedIcon;
|
|
47
|
+
export declare const LuReddit: GeneratedIcon;
|
|
47
48
|
export declare const LuRefund: GeneratedIcon;
|
|
48
49
|
export declare const LuSlashDivider: GeneratedIcon;
|
|
49
50
|
export declare const LuSolanaAccountsFill: GeneratedIcon;
|
|
@@ -498,4 +499,3 @@ export declare const LuCloudSunRain: GeneratedIcon;
|
|
|
498
499
|
export declare const LuCloudSun: GeneratedIcon;
|
|
499
500
|
export declare const LuCloudSync: GeneratedIcon;
|
|
500
501
|
export declare const LuCloudUpload: GeneratedIcon;
|
|
501
|
-
export declare const LuCloud: GeneratedIcon;
|
package/dist/icons/icons_1.js
CHANGED
|
@@ -178,6 +178,10 @@ const LuReceiveDonationFill = {
|
|
|
178
178
|
name: "lu-receive-donation-fill",
|
|
179
179
|
components: [["path", { "d": "M20.2426 4.75736C22.5053 7.02472 22.583 10.637 20.4786 12.993L11.9999 21.485L3.52138 12.993C1.41705 10.637 1.49571 7.01901 3.75736 4.75736C6.02157 2.49315 9.64519 2.41687 12.001 4.52853C14.35 2.42 17.98 2.49 20.2426 4.75736ZM5.17157 6.17157C3.68183 7.66131 3.60704 10.0473 4.97993 11.6232L11.9999 18.6543L19.0201 11.6232C20.3935 10.0467 20.319 7.66525 18.827 6.1701C17.3397 4.67979 14.9458 4.60806 13.3743 5.98376L9.17157 10.1869L7.75736 8.77264L10.582 5.946L10.5002 5.87701C8.92545 4.61197 6.62322 4.71993 5.17157 6.17157Z" }]]
|
|
180
180
|
};
|
|
181
|
+
const LuReddit = {
|
|
182
|
+
name: "lu-reddit",
|
|
183
|
+
components: [["path", { "d": "M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z" }]]
|
|
184
|
+
};
|
|
181
185
|
const LuRefund = {
|
|
182
186
|
name: "lu-refund",
|
|
183
187
|
components: [["path", { "d": "M3 12C3 13.78 3.52784 15.5201 4.51677 17.0001C5.50571 18.4802 6.91131 19.6337 8.55585 20.3149C10.2004 20.9961 12.01 21.1743 13.7558 20.8271C15.5016 20.4798 17.1053 19.6226 18.364 18.364C19.6226 17.1053 20.4798 15.5016 20.8271 13.7558C21.1743 12.01 20.9961 10.2004 20.3149 8.55585C19.6337 6.91131 18.4802 5.50571 17.0001 4.51677C15.5201 3.52784 13.78 3 12 3C9.48395 3.00947 7.06897 3.99122 5.26 5.74L3 8 M3 5V8H6 M15 9.125H10.5C10.1022 9.125 9.72064 9.28304 9.43934 9.56434C9.15804 9.84564 9 10.2272 9 10.625C9 11.0228 9.15804 11.4044 9.43934 11.6857C9.72064 11.967 10.1022 12.125 10.5 12.125H13.5C13.8978 12.125 14.2794 12.283 14.5607 12.5643C14.842 12.8456 15 13.2272 15 13.625C15 14.0228 14.842 14.4044 14.5607 14.6857C14.2794 14.967 13.8978 15.125 13.5 15.125H9 M12 16.25V8" }]]
|
|
@@ -1994,10 +1998,6 @@ const LuCloudUpload = {
|
|
|
1994
1998
|
name: "lu-cloud-upload",
|
|
1995
1999
|
components: [["path", { "d": "M12 13v8 M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242 M8 17 L12 13 L16 17" }]]
|
|
1996
2000
|
};
|
|
1997
|
-
const LuCloud = {
|
|
1998
|
-
name: "lu-cloud",
|
|
1999
|
-
components: [["path", { "d": "M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z" }]]
|
|
2000
|
-
};
|
|
2001
2001
|
export {
|
|
2002
2002
|
LuAArrowDown,
|
|
2003
2003
|
LuAArrowUp,
|
|
@@ -2437,7 +2437,6 @@ export {
|
|
|
2437
2437
|
LuClockFading,
|
|
2438
2438
|
LuClockPlus,
|
|
2439
2439
|
LuClosedCaption,
|
|
2440
|
-
LuCloud,
|
|
2441
2440
|
LuCloudAlert,
|
|
2442
2441
|
LuCloudBackup,
|
|
2443
2442
|
LuCloudCheck,
|
|
@@ -2493,6 +2492,7 @@ export {
|
|
|
2493
2492
|
LuPaypal,
|
|
2494
2493
|
LuRadioButtonFill,
|
|
2495
2494
|
LuReceiveDonationFill,
|
|
2495
|
+
LuReddit,
|
|
2496
2496
|
LuRefund,
|
|
2497
2497
|
LuSlashDivider,
|
|
2498
2498
|
LuSolanaAccountsFill,
|