@rotki/ui-library 2.25.1 → 2.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker-styles.d.ts +6 -0
- package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/auto-complete-styles.d.ts +6 -0
- package/dist/components/forms/category-picker/category-picker-styles.d.ts +6 -0
- package/dist/components/forms/select/RuiMenuSelect.js.map +1 -1
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/menu-select-styles.d.ts +6 -0
- package/dist/components/forms/text-input-styles.d.ts +3 -0
- package/dist/components/forms/text-input-styles.js +3 -1
- package/dist/components/forms/text-input-styles.js.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/overlays/menu/RuiMenu.js.map +1 -1
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +8 -2
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiDataTable.js.map +1 -1
- package/dist/components/tables/RuiDataTable.vue.d.ts +12 -1
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +71 -17
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tables/RuiTableHead.js.map +1 -1
- package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js +38 -13
- package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTablePagination.js.map +1 -1
- package/dist/components/tables/RuiTablePagination.vue.d.ts +3 -3
- package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js +65 -14
- package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableBody.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableBody.vue.d.ts +7 -1
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js +45 -9
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableCell.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js +13 -2
- package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableErrorRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableErrorRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableErrorRow.vue.d.ts +21 -0
- package/dist/components/tables/data-table/RuiDataTableErrorRow.vue_vue_type_script_setup_true_lang.js +40 -0
- package/dist/components/tables/data-table/RuiDataTableErrorRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js +12 -1
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js +52 -20
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +29 -14
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/context.d.ts +10 -0
- package/dist/components/tables/data-table/context.js +2 -0
- package/dist/components/tables/data-table/context.js.map +1 -1
- package/dist/components/tables/data-table-styles.d.ts +15 -9
- package/dist/components/tables/data-table-styles.js +29 -6
- package/dist/components/tables/data-table-styles.js.map +1 -1
- package/dist/components/tables/table-props.d.ts +1 -2
- package/dist/components/tables/table-props.js +2 -10
- package/dist/components/tables/table-props.js.map +1 -1
- package/dist/components/tables/use-pagination-navigation.js +1 -1
- package/dist/components/tables/use-pagination-navigation.js.map +1 -1
- package/dist/composables/sticky-header.d.ts +0 -1
- package/dist/composables/sticky-header.js +56 -8
- package/dist/composables/sticky-header.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/library-icons.json +1 -1
- package/dist/style.css +115 -38
- package/dist/web-types.json +139 -3
- package/package.json +1 -1
|
@@ -129,20 +129,26 @@ var RuiMenu_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
|
|
|
129
129
|
...get$1(baseMenuAttrs),
|
|
130
130
|
onClick: __props.disabled ? void 0 : checkClick
|
|
131
131
|
}));
|
|
132
|
+
/**
|
|
133
|
+
* Moves focus into the open menu without scrolling the page. A menu taller than the space below its
|
|
134
|
+
* activator would otherwise make the browser scroll the whole document to reveal the focused
|
|
135
|
+
* container, sliding the page out from under the activator.
|
|
136
|
+
*/
|
|
132
137
|
function focusOnContent() {
|
|
133
138
|
const content = get$1(menuContent);
|
|
134
139
|
if (!content) return;
|
|
135
|
-
content.focus();
|
|
140
|
+
content.focus({ preventScroll: true });
|
|
136
141
|
}
|
|
137
142
|
function focusMenu() {
|
|
138
143
|
if (__props.disableAutoFocus) return;
|
|
139
144
|
nextTick(() => focusOnContent());
|
|
140
145
|
}
|
|
146
|
+
/** Hands focus back to the activator on close, likewise without scrolling to it. */
|
|
141
147
|
function focusOnActivator() {
|
|
142
148
|
const activatorEl = get$1(activator);
|
|
143
149
|
if (!activatorEl) return;
|
|
144
150
|
const focusableEl = activatorEl.querySelector(FOCUSABLE_ELEMENTS_SELECTOR);
|
|
145
|
-
if (focusableEl) focusableEl.focus();
|
|
151
|
+
if (focusableEl) focusableEl.focus({ preventScroll: true });
|
|
146
152
|
}
|
|
147
153
|
function onLeave(event) {
|
|
148
154
|
if (!get$1(open)) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiMenu.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../../src/components/overlays/menu/RuiMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { VueClassValue } from '@/types/class-value';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { type FloatingOptions, useFloating } from '@/composables/floating';\nimport { type PopperOptions, toFloatingOptions } from '@/composables/popper';\nimport { useFormTextDetail } from '@/utils/form-text-detail';\nimport { cn, tv } from '@/utils/tv';\n\ninterface BaseMenuAttrs { onMouseover?: () => void; onMouseleave?: () => void }\n\ninterface MenuAttrs extends BaseMenuAttrs { onClick?: () => void }\n\nexport interface RuiMenuClassNames {\n root?: VueClassValue;\n wrapper?: VueClassValue;\n menu?: VueClassValue;\n /** Overrides applied to the popover content box (e.g. to drop its default padding). */\n content?: VueClassValue;\n}\n\n/**\n * Roles a popover container may take. These are the values `aria-haspopup`\n * accepts, which keeps the activator and the popover in agreement.\n */\nexport type RuiMenuRole = 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog';\n\nexport interface MenuProps {\n openOnHover?: boolean;\n fullWidth?: boolean;\n disabled?: boolean;\n openDelay?: number;\n closeDelay?: number;\n options?: FloatingOptions;\n /** @deprecated Use `options` instead */\n popper?: PopperOptions;\n classNames?: RuiMenuClassNames;\n /** @deprecated Use `classNames.wrapper` instead */\n wrapperClass?: string | object | string[];\n /** @deprecated Use `classNames.menu` instead */\n menuClass?: string | object | string[];\n closeOnContentClick?: boolean;\n persistOnActivatorClick?: boolean;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n showDetails?: boolean;\n dense?: boolean;\n /**\n * Keeps the menu open through the interactions that would otherwise dismiss\n * it: a click outside and an Escape press. A programmatic close (`v-model`\n * set to `false`) still applies.\n */\n persistent?: boolean;\n disableAutoFocus?: boolean;\n /**\n * Optional external element to anchor the menu to, instead of the\n * activator slot's wrapper. When set, the menu's position is computed\n * against this element.\n */\n anchorEl?: HTMLElement;\n /**\n * Role of the teleported popover. Defaults to `menu`, which is correct when\n * the content is made of `menuitem`s. Set it to `listbox` (or `tree`, `grid`,\n * `dialog`) when the content follows a different ARIA model, e.g. a selection\n * list opened by a `combobox`. The activator's `aria-haspopup` follows it.\n */\n role?: RuiMenuRole;\n}\n\ndefineOptions({\n name: 'RuiMenu',\n});\n\nconst modelValue = defineModel<boolean>({ default: false });\n\nconst {\n openOnHover = false,\n disabled = false,\n fullWidth = false,\n openDelay = 0,\n closeDelay = 0,\n options,\n popper,\n classNames,\n wrapperClass = '',\n menuClass = '',\n closeOnContentClick = false,\n persistOnActivatorClick = false,\n hint,\n errorMessages = [],\n successMessages = [],\n showDetails = false,\n dense = false,\n persistent = false,\n disableAutoFocus = false,\n anchorEl,\n role = 'menu',\n} = defineProps<MenuProps>();\n\ndefineSlots<{\n activator?: (props: {\n attrs: { onMouseover?: () => void; onMouseleave?: () => void; onClick?: () => void };\n open: boolean;\n disabled: boolean;\n hasError: boolean;\n hasSuccess: boolean;\n }) => any;\n default?: (props: { width: number }) => any;\n}>();\n\nconst click = ref<boolean>(false);\nconst menuContent = useTemplateRef<HTMLElement>('menuContent');\n\nconst FOCUSABLE_ELEMENTS_SELECTOR =\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\nconst {\n reference: activator,\n popover: menu,\n open,\n visible,\n currentPlacement,\n leavePending,\n onLeavePending,\n onOpen,\n onClose,\n onLeaveComplete,\n updatePosition,\n} = useFloating(\n () => popper ? toFloatingOptions(popper) : (options ?? {}),\n () => disabled,\n () => openDelay,\n () => closeDelay,\n () => anchorEl,\n);\n\nconst { width } = useElementSize(activator);\n\nconst { hasError, hasSuccess } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\n\nconst menuStyles = tv({\n slots: {\n wrapper: 'relative inline-flex max-w-full',\n popover: 'w-max z-[9999]',\n content: 'rounded overflow-hidden shadow-8 bg-white dark:bg-[#2E2E2E] text-rui-text focus:outline-none py-2',\n details: 'pt-1',\n },\n variants: {\n fullWidth: {\n true: { wrapper: 'w-full' },\n },\n dense: {\n true: { details: 'px-2' },\n false: { details: 'px-4' },\n },\n },\n defaultVariants: { fullWidth: false, dense: false },\n});\n\nconst ui = computed<ReturnType<typeof menuStyles>>(() => menuStyles({\n fullWidth,\n dense,\n}));\n\n// `aria-haspopup=\"true\"` means `\"menu\"`, and the default keeps emitting `true` for existing callers\nconst ariaHasPopup = computed<RuiMenuRole | 'true'>(() => role === 'menu' ? 'true' : role);\n\n/**\n * The activator attributes.\n *\n * This and the computed below it must return the same object shape from every\n * branch. Otherwise vue-tsc infers the slot's `attrs` type as a discriminated\n * union where each key is either all defined or all undefined, which breaks\n * consumer code typing its own `attrs` handler with individually optional\n * keys.\n */\nconst baseMenuAttrs = computed<BaseMenuAttrs>(() => {\n const clickVal = get(click);\n return {\n onMouseover: disabled\n ? undefined\n : () => {\n if (openOnHover)\n onOpen();\n },\n onMouseleave: disabled\n ? undefined\n : () => {\n if (openOnHover && !clickVal)\n onClose();\n },\n };\n});\n\nconst menuAttrs = computed<MenuAttrs>(() => ({\n ...get(baseMenuAttrs),\n onClick: disabled ? undefined : checkClick,\n}));\n\nfunction focusOnContent() {\n const content = get(menuContent);\n if (!content)\n return;\n\n // Focus on the menu container itself\n content.focus();\n}\n\nfunction focusMenu(): void {\n if (disableAutoFocus)\n return;\n\n nextTick(() => focusOnContent());\n}\n\nfunction focusOnActivator() {\n const activatorEl = get(activator);\n if (!activatorEl) {\n return;\n }\n const focusableEl = activatorEl.querySelector<HTMLElement>(FOCUSABLE_ELEMENTS_SELECTOR);\n if (focusableEl) {\n focusableEl.focus();\n }\n}\n\nfunction onLeave(event?: KeyboardEvent): void {\n if (!get(open))\n return;\n onClose();\n set(click, false);\n event?.stopPropagation();\n\n // Return focus to activator when menu closes\n if (disableAutoFocus) {\n return;\n }\n\n nextTick(() => focusOnActivator());\n}\n\n/**\n * `persistent` blocks the outside interactions that would close the menu, and\n * Escape is one of them, which is how `RuiDialog` and `RuiBottomSheet` already\n * read it. The guard sits here rather than in `onLeave`, because `onLeave`\n * also runs for a programmatic close through `v-model`, which must keep\n * working.\n *\n * A persistent menu leaves the key alone instead of swallowing it, so an inner\n * popover can close on Escape while the menu stays open, and an ancestor still\n * sees a key nothing consumed.\n */\nfunction onEscape(event: KeyboardEvent): void {\n if (persistent)\n return;\n\n onLeave(event);\n}\n\nfunction checkClick(): void {\n if (get(open) && get(click)) {\n if (!persistOnActivatorClick)\n onLeave();\n }\n else {\n onOpen();\n set(click, true);\n }\n}\n\nwatch(modelValue, (value) => {\n if (get(open) === value)\n return;\n\n if (value) {\n onOpen();\n set(click, true);\n }\n else {\n onLeave();\n }\n});\n\nwatch(open, (open) => {\n set(modelValue, open);\n if (open) {\n focusMenu();\n }\n});\n\nonClickOutside(menu, () => {\n if (get(open) && !persistent)\n onLeave();\n}, { ignore: [activator] });\n</script>\n\n<template>\n <!--\n Escape is swallowed only while the menu is open and not persistent\n (`onLeave` stops the event itself); a closed or persistent menu must let it\n through, or a consumer that closes its own editor on Escape never sees the\n key.\n -->\n <div\n :class=\"classNames?.root\"\n @keydown.esc=\"onEscape($event)\"\n >\n <div\n ref=\"activator\"\n :class=\"ui.wrapper({ class: cn(classNames?.wrapper) ?? cn(wrapperClass as VueClassValue) })\"\n :data-menu-disabled=\"disabled\"\n :aria-haspopup=\"ariaHasPopup\"\n :aria-expanded=\"open\"\n >\n <slot\n name=\"activator\"\n v-bind=\"{ attrs: menuAttrs, open, disabled, hasError, hasSuccess }\"\n />\n </div>\n <Teleport\n v-if=\"!disabled\"\n to=\"body\"\n >\n <div\n v-if=\"visible\"\n ref=\"menu\"\n :class=\"ui.popover({ class: cn(classNames?.menu) ?? cn(menuClass as VueClassValue) })\"\n :role=\"role\"\n :data-placement=\"currentPlacement\"\n @click=\"closeOnContentClick ? onLeave() : undefined\"\n @keydown.esc=\"onEscape($event)\"\n >\n <TransitionGroup\n enter-active-class=\"transition ease-out duration-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 @before-enter=\"updatePosition()\"\n @after-leave=\"leavePending ? onLeaveComplete() : undefined\"\n @before-leave=\"onLeavePending()\"\n >\n <div\n v-if=\"open\"\n ref=\"menuContent\"\n key=\"menu\"\n data-id=\"content\"\n :class=\"ui.content({ class: cn(classNames?.content) })\"\n tabindex=\"-1\"\n v-bind=\"baseMenuAttrs\"\n >\n <slot v-bind=\"{ width }\" />\n </div>\n </TransitionGroup>\n </div>\n </Teleport>\n <RuiFormTextDetail\n v-if=\"showDetails\"\n :class=\"ui.details()\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RuiMenu.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../../src/components/overlays/menu/RuiMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { VueClassValue } from '@/types/class-value';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { type FloatingOptions, useFloating } from '@/composables/floating';\nimport { type PopperOptions, toFloatingOptions } from '@/composables/popper';\nimport { useFormTextDetail } from '@/utils/form-text-detail';\nimport { cn, tv } from '@/utils/tv';\n\ninterface BaseMenuAttrs { onMouseover?: () => void; onMouseleave?: () => void }\n\ninterface MenuAttrs extends BaseMenuAttrs { onClick?: () => void }\n\nexport interface RuiMenuClassNames {\n root?: VueClassValue;\n wrapper?: VueClassValue;\n menu?: VueClassValue;\n /** Overrides applied to the popover content box (e.g. to drop its default padding). */\n content?: VueClassValue;\n}\n\n/**\n * Roles a popover container may take. These are the values `aria-haspopup`\n * accepts, which keeps the activator and the popover in agreement.\n */\nexport type RuiMenuRole = 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog';\n\nexport interface MenuProps {\n openOnHover?: boolean;\n fullWidth?: boolean;\n disabled?: boolean;\n openDelay?: number;\n closeDelay?: number;\n options?: FloatingOptions;\n /** @deprecated Use `options` instead */\n popper?: PopperOptions;\n classNames?: RuiMenuClassNames;\n /** @deprecated Use `classNames.wrapper` instead */\n wrapperClass?: string | object | string[];\n /** @deprecated Use `classNames.menu` instead */\n menuClass?: string | object | string[];\n closeOnContentClick?: boolean;\n persistOnActivatorClick?: boolean;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n showDetails?: boolean;\n dense?: boolean;\n /**\n * Keeps the menu open through the interactions that would otherwise dismiss\n * it: a click outside and an Escape press. A programmatic close (`v-model`\n * set to `false`) still applies.\n */\n persistent?: boolean;\n disableAutoFocus?: boolean;\n /**\n * Optional external element to anchor the menu to, instead of the\n * activator slot's wrapper. When set, the menu's position is computed\n * against this element.\n */\n anchorEl?: HTMLElement;\n /**\n * Role of the teleported popover. Defaults to `menu`, which is correct when\n * the content is made of `menuitem`s. Set it to `listbox` (or `tree`, `grid`,\n * `dialog`) when the content follows a different ARIA model, e.g. a selection\n * list opened by a `combobox`. The activator's `aria-haspopup` follows it.\n */\n role?: RuiMenuRole;\n}\n\ndefineOptions({\n name: 'RuiMenu',\n});\n\nconst modelValue = defineModel<boolean>({ default: false });\n\nconst {\n openOnHover = false,\n disabled = false,\n fullWidth = false,\n openDelay = 0,\n closeDelay = 0,\n options,\n popper,\n classNames,\n wrapperClass = '',\n menuClass = '',\n closeOnContentClick = false,\n persistOnActivatorClick = false,\n hint,\n errorMessages = [],\n successMessages = [],\n showDetails = false,\n dense = false,\n persistent = false,\n disableAutoFocus = false,\n anchorEl,\n role = 'menu',\n} = defineProps<MenuProps>();\n\ndefineSlots<{\n activator?: (props: {\n attrs: { onMouseover?: () => void; onMouseleave?: () => void; onClick?: () => void };\n open: boolean;\n disabled: boolean;\n hasError: boolean;\n hasSuccess: boolean;\n }) => any;\n default?: (props: { width: number }) => any;\n}>();\n\nconst click = ref<boolean>(false);\nconst menuContent = useTemplateRef<HTMLElement>('menuContent');\n\nconst FOCUSABLE_ELEMENTS_SELECTOR =\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\nconst {\n reference: activator,\n popover: menu,\n open,\n visible,\n currentPlacement,\n leavePending,\n onLeavePending,\n onOpen,\n onClose,\n onLeaveComplete,\n updatePosition,\n} = useFloating(\n () => popper ? toFloatingOptions(popper) : (options ?? {}),\n () => disabled,\n () => openDelay,\n () => closeDelay,\n () => anchorEl,\n);\n\nconst { width } = useElementSize(activator);\n\nconst { hasError, hasSuccess } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\n\nconst menuStyles = tv({\n slots: {\n wrapper: 'relative inline-flex max-w-full',\n popover: 'w-max z-[9999]',\n content: 'rounded overflow-hidden shadow-8 bg-white dark:bg-[#2E2E2E] text-rui-text focus:outline-none py-2',\n details: 'pt-1',\n },\n variants: {\n fullWidth: {\n true: { wrapper: 'w-full' },\n },\n dense: {\n true: { details: 'px-2' },\n false: { details: 'px-4' },\n },\n },\n defaultVariants: { fullWidth: false, dense: false },\n});\n\nconst ui = computed<ReturnType<typeof menuStyles>>(() => menuStyles({\n fullWidth,\n dense,\n}));\n\n// `aria-haspopup=\"true\"` means `\"menu\"`, and the default keeps emitting `true` for existing callers\nconst ariaHasPopup = computed<RuiMenuRole | 'true'>(() => role === 'menu' ? 'true' : role);\n\n/**\n * The activator attributes.\n *\n * This and the computed below it must return the same object shape from every\n * branch. Otherwise vue-tsc infers the slot's `attrs` type as a discriminated\n * union where each key is either all defined or all undefined, which breaks\n * consumer code typing its own `attrs` handler with individually optional\n * keys.\n */\nconst baseMenuAttrs = computed<BaseMenuAttrs>(() => {\n const clickVal = get(click);\n return {\n onMouseover: disabled\n ? undefined\n : () => {\n if (openOnHover)\n onOpen();\n },\n onMouseleave: disabled\n ? undefined\n : () => {\n if (openOnHover && !clickVal)\n onClose();\n },\n };\n});\n\nconst menuAttrs = computed<MenuAttrs>(() => ({\n ...get(baseMenuAttrs),\n onClick: disabled ? undefined : checkClick,\n}));\n\n/**\n * Moves focus into the open menu without scrolling the page. A menu taller than the space below its\n * activator would otherwise make the browser scroll the whole document to reveal the focused\n * container, sliding the page out from under the activator.\n */\nfunction focusOnContent() {\n const content = get(menuContent);\n if (!content)\n return;\n\n content.focus({ preventScroll: true });\n}\n\nfunction focusMenu(): void {\n if (disableAutoFocus)\n return;\n\n nextTick(() => focusOnContent());\n}\n\n/** Hands focus back to the activator on close, likewise without scrolling to it. */\nfunction focusOnActivator() {\n const activatorEl = get(activator);\n if (!activatorEl) {\n return;\n }\n const focusableEl = activatorEl.querySelector<HTMLElement>(FOCUSABLE_ELEMENTS_SELECTOR);\n if (focusableEl) {\n focusableEl.focus({ preventScroll: true });\n }\n}\n\nfunction onLeave(event?: KeyboardEvent): void {\n if (!get(open))\n return;\n onClose();\n set(click, false);\n event?.stopPropagation();\n\n // Return focus to activator when menu closes\n if (disableAutoFocus) {\n return;\n }\n\n nextTick(() => focusOnActivator());\n}\n\n/**\n * `persistent` blocks the outside interactions that would close the menu, and\n * Escape is one of them, which is how `RuiDialog` and `RuiBottomSheet` already\n * read it. The guard sits here rather than in `onLeave`, because `onLeave`\n * also runs for a programmatic close through `v-model`, which must keep\n * working.\n *\n * A persistent menu leaves the key alone instead of swallowing it, so an inner\n * popover can close on Escape while the menu stays open, and an ancestor still\n * sees a key nothing consumed.\n */\nfunction onEscape(event: KeyboardEvent): void {\n if (persistent)\n return;\n\n onLeave(event);\n}\n\nfunction checkClick(): void {\n if (get(open) && get(click)) {\n if (!persistOnActivatorClick)\n onLeave();\n }\n else {\n onOpen();\n set(click, true);\n }\n}\n\nwatch(modelValue, (value) => {\n if (get(open) === value)\n return;\n\n if (value) {\n onOpen();\n set(click, true);\n }\n else {\n onLeave();\n }\n});\n\nwatch(open, (open) => {\n set(modelValue, open);\n if (open) {\n focusMenu();\n }\n});\n\nonClickOutside(menu, () => {\n if (get(open) && !persistent)\n onLeave();\n}, { ignore: [activator] });\n</script>\n\n<template>\n <!--\n Escape is swallowed only while the menu is open and not persistent\n (`onLeave` stops the event itself); a closed or persistent menu must let it\n through, or a consumer that closes its own editor on Escape never sees the\n key.\n -->\n <div\n :class=\"classNames?.root\"\n @keydown.esc=\"onEscape($event)\"\n >\n <div\n ref=\"activator\"\n :class=\"ui.wrapper({ class: cn(classNames?.wrapper) ?? cn(wrapperClass as VueClassValue) })\"\n :data-menu-disabled=\"disabled\"\n :aria-haspopup=\"ariaHasPopup\"\n :aria-expanded=\"open\"\n >\n <slot\n name=\"activator\"\n v-bind=\"{ attrs: menuAttrs, open, disabled, hasError, hasSuccess }\"\n />\n </div>\n <Teleport\n v-if=\"!disabled\"\n to=\"body\"\n >\n <div\n v-if=\"visible\"\n ref=\"menu\"\n :class=\"ui.popover({ class: cn(classNames?.menu) ?? cn(menuClass as VueClassValue) })\"\n :role=\"role\"\n :data-placement=\"currentPlacement\"\n @click=\"closeOnContentClick ? onLeave() : undefined\"\n @keydown.esc=\"onEscape($event)\"\n >\n <TransitionGroup\n enter-active-class=\"transition ease-out duration-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 @before-enter=\"updatePosition()\"\n @after-leave=\"leavePending ? onLeaveComplete() : undefined\"\n @before-leave=\"onLeavePending()\"\n >\n <div\n v-if=\"open\"\n ref=\"menuContent\"\n key=\"menu\"\n data-id=\"content\"\n :class=\"ui.content({ class: cn(classNames?.content) })\"\n tabindex=\"-1\"\n v-bind=\"baseMenuAttrs\"\n >\n <slot v-bind=\"{ width }\" />\n </div>\n </TransitionGroup>\n </div>\n </Teleport>\n <RuiFormTextDetail\n v-if=\"showDetails\"\n :class=\"ui.details()\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiDataTable.js","names":[],"sources":["../../../src/components/tables/RuiDataTable.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends object, IdType extends keyof T = keyof T\">\nimport type { GroupHeader } from '@/composables/tables/data-table/types';\nimport { dataTableStyles } from '@/components/tables/data-table-styles';\nimport { type DataTableClasses, provideDataTableContext, provideDataTableNested, useDataTableNested } from '@/components/tables/data-table/context';\nimport RuiDataTableBody from '@/components/tables/data-table/RuiDataTableBody.vue';\nimport RuiDataTableMobileSort from '@/components/tables/data-table/RuiDataTableMobileSort.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 { GroupExpandButtonPosition } from '@/components/tables/table-props';\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';\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 * Maximum number of pages before the jump-to-page dropdown is replaced with\n * a numeric input. Defaults to `500`. Forwarded to `RuiTablePagination`.\n */\n rangesThreshold?: number;\n /**\n * The text and icon shown when there are no rows, e.g.\n * `: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?: GroupExpandButtonPosition;\n disabledRows?: readonly T[];\n multiPageSelect?: boolean;\n itemClass?: ((item: T) => string) | string;\n /**\n * Render each row as a stacked card instead of a table row once the measured\n * width is narrower than this width (in pixels). Columns flagged with\n * `mobileHidden` are dropped in this layout. Falls back to the global\n * `mobileBreakpoint` table default; leave both unset to keep the default table\n * layout at every width.\n */\n mobileBreakpoint?: number;\n /**\n * What the `mobileBreakpoint` is measured against: the browser `viewport`\n * (default) or this table's own `container` width. Use `container` when the\n * table lives in a narrow region of a wider window. Falls back to the global\n * `mobileBreakpointBasis` table default.\n */\n mobileBreakpointBasis?: 'viewport' | 'container';\n /**\n * Force the stacked mobile card layout on (`true`) or off (`false`),\n * regardless of `mobileBreakpoint`. Leave unset to derive it from the width.\n */\n mobile?: boolean;\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 rangesThreshold = 500,\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 = GroupExpandButtonPosition.start,\n disabledRows,\n multiPageSelect = false,\n itemClass = '',\n mobileBreakpoint,\n mobileBreakpointBasis,\n mobile,\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 tableWrapper = useTemplateRef<HTMLElement>('tableWrapper');\nconst { width: windowWidth } = useWindowSize();\nconst { width: containerWidth } = useElementSize(tableWrapper);\n\n// Per-table props win, then the global table defaults.\nconst resolvedMobileBreakpoint = computed<number | undefined>(() => {\n if (mobileBreakpoint !== undefined)\n return mobileBreakpoint;\n const globalBreakpoint = tableDefaults.mobileBreakpoint;\n return globalBreakpoint === undefined ? undefined : get(globalBreakpoint);\n});\nconst resolvedMobileBasis = computed<'viewport' | 'container'>(() => {\n if (mobileBreakpointBasis !== undefined)\n return mobileBreakpointBasis;\n const globalBasis = tableDefaults.mobileBreakpointBasis;\n return globalBasis === undefined ? 'viewport' : get(globalBasis);\n});\n\n/**\n * Whether the stacked card layout is showing.\n *\n * Vue coerces an absent Boolean prop to `false`, so `mobile` cannot say\n * \"unset\": with no breakpoint configured it is the manual switch, defaulting\n * to desktop, and with one configured the breakpoint drives the layout while\n * `mobile === true` can still force the stacked layout on.\n */\nconst isMobile = computed<boolean>(() => {\n const breakpoint = get(resolvedMobileBreakpoint);\n if (breakpoint === undefined)\n return mobile;\n if (mobile)\n return true;\n // `containerWidth` is 0 until measured; the viewport keeps the first paint off mobile\n const width = get(resolvedMobileBasis) === 'container'\n ? (get(containerWidth) || get(windowWidth))\n : get(windowWidth);\n return width < breakpoint;\n});\n\nconst stickyHeaderOffset = computed<number | undefined>(() =>\n stickyOffset !== undefined ? stickyOffset : get(tableDefaults.stickyOffset),\n);\n\n/**\n * A table rendered inside an expanded row must not pin its own toolbar: only\n * the outermost table sticks, otherwise the bars stack and collide.\n */\nconst isNestedTable = useDataTableNested();\nprovideDataTableNested();\n\n/**\n * On mobile there is no column header to pin, so `stickyHeader` pins the\n * pagination and sort toolbar instead while the card list scrolls.\n */\nconst stickyMobileToolbar = computed<boolean>(() => stickyHeader && get(isMobile) && !isNestedTable);\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 { expandable, isExpanded, onToggleExpand } = useTableExpansion<T, IdType>(\n { rowAttr, singleExpand },\n { expanded },\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} = useTableGrouping<T, IdType>(\n { rowAttr },\n {\n group,\n collapsed,\n sorted,\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 ui = computed<ReturnType<typeof dataTableStyles>>(() => dataTableStyles({\n outlined,\n rounded,\n dense,\n striped,\n mobile: get(isMobile),\n}));\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 isMobile,\n tdResolver: options => get(ui).td(options),\n});\n\nconst showMobileSort = computed<boolean>(() =>\n get(isMobile) && !!get(sortData) && get(columns).some(column => column.sortable),\n);\n\nconst ITEM_SLOT_PREFIX = 'item.';\n\n// Slot keys are static for the component lifetime — no reactivity needed\nconst itemSlotKeys: Set<string> = new Set(\n Object.keys(slots)\n .filter((key): key is `item.${string}` => key.startsWith(ITEM_SLOT_PREFIX))\n .map(key => key.slice(ITEM_SLOT_PREFIX.length)),\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/**\n * Sorting clears the selection. That lives here rather than in either\n * composable, which would make sort and selection depend on each other.\n */\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 if ((get(expanded)?.length ?? 0) > 0)\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\nconst classes = computed<DataTableClasses>(() => {\n const s = get(ui);\n return {\n td: s.td(),\n tr: s.tr(),\n trSelected: s.tr({ rowVariant: 'selected' }),\n trExpandable: s.tr({ rowVariant: 'expandable' }),\n trGroup: s.tr({ rowVariant: 'group' }),\n trEmpty: s.tr({ rowVariant: 'empty' }),\n checkbox: s.checkbox(),\n tbody: s.tbody(),\n tbodyLoader: s.tbodyLoader(),\n };\n});\n\nprovideDataTableContext<T, IdType>({\n // Reactive (ComputedRef/Ref) — destructuring preserves reactivity via Vue template auto-unwrap\n classes,\n columns,\n colspan,\n expandable,\n groupKey,\n isMobile,\n selectedData,\n // Static values\n cellValue,\n columnAttr,\n dense,\n getRowId: (row: T) => row[rowAttr],\n itemSlotKeys,\n groupExpandButtonPosition,\n isDisabledRow,\n isExpanded,\n isExpandedGroup,\n isSelected,\n itemClass,\n onCheckboxClick,\n onCopyGroup: (header: GroupHeader<T>) => emit('copy:group', { key: get(groupKey) ?? '', value: header.group }),\n onSelect,\n onToggleExpand,\n onToggleExpandGroup,\n onUngroup,\n});\n</script>\n\n<template>\n <div\n ref=\"tableWrapper\"\n :class=\"ui.wrapper()\"\n data-id=\"table-wrapper\"\n >\n <div\n :class=\"stickyMobileToolbar ? 'sticky z-10 bg-white dark:bg-[#121212] pt-2' : 'contents'\"\n :style=\"stickyMobileToolbar ? { top: `${stickyHeaderOffset ?? 0}px` } : undefined\"\n data-id=\"table-mobile-toolbar-sticky\"\n >\n <RuiTablePagination\n v-if=\"paginationData && !hideDefaultHeader\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :mobile=\"isMobile\"\n :disable-per-page=\"disablePerPage\"\n :ranges-threshold=\"rangesThreshold\"\n data-id=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n <div\n v-if=\"showMobileSort\"\n class=\"flex justify-end p-2\"\n data-id=\"table-mobile-toolbar\"\n >\n <RuiDataTableMobileSort\n :columns=\"columns\"\n :column-attr=\"columnAttr\"\n :sorted-map=\"sortedMap\"\n :dense=\"dense\"\n @sort=\"onSort($event)\"\n />\n </div>\n </div>\n <div\n ref=\"tableScroller\"\n :class=\"[ui.scroller(), isMobile && !showMobileSort ? 'pt-2' : '']\"\n data-id=\"table-scroller\"\n >\n <table\n ref=\"table\"\n :class=\"ui.table()\"\n :aria-busy=\"loading\"\n >\n <RuiTableHead\n v-if=\"!isMobile\"\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 :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 && !isMobile\"\n :loading=\"loading\"\n :capitalize-headers=\"!cols\"\n :colspan=\"colspan\"\n :column-attr=\"columnAttr\"\n :columns=\"columns\"\n :dense=\"dense\"\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 <RuiDataTableBody\n :filtered=\"filtered\"\n :loading=\"loading\"\n :no-data=\"noData\"\n :empty=\"empty\"\n >\n <template\n v-if=\"slots['body.prepend']\"\n #body.prepend=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"body.prepend\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['group.header']\"\n #group.header=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['group.header.content']\"\n #group.header.content=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header.content\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-for=\"key in itemSlotKeys\"\n #[`item.${key}`]=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n :name=\"`item.${key}`\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['expanded-item']\"\n #expanded-item=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"expanded-item\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['no-data']\"\n #no-data\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"no-data\" />\n </template>\n <template\n v-if=\"slots['empty-description']\"\n #empty-description\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"empty-description\" />\n </template>\n <template\n v-if=\"slots['body.append']\"\n #body.append=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"body.append\"\n v-bind=\"slotData\"\n />\n </template>\n </RuiDataTableBody>\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 :mobile=\"isMobile\"\n :disable-per-page=\"disablePerPage\"\n :ranges-threshold=\"rangesThreshold\"\n data-id=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"RuiDataTable.js","names":[],"sources":["../../../src/components/tables/RuiDataTable.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends object, IdType extends keyof T = keyof T\">\nimport type { GroupHeader } from '@/composables/tables/data-table/types';\nimport { dataTableStyles } from '@/components/tables/data-table-styles';\nimport { type DataTableClasses, type DataTableGroupLabel, provideDataTableContext, provideDataTableNested, useDataTableNested } from '@/components/tables/data-table/context';\nimport RuiDataTableBody from '@/components/tables/data-table/RuiDataTableBody.vue';\nimport RuiDataTableMobileSort from '@/components/tables/data-table/RuiDataTableMobileSort.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 { GroupExpandButtonPosition } from '@/components/tables/table-props';\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';\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 * Maximum number of pages before the jump-to-page dropdown is replaced with\n * a numeric input. Defaults to `500`. Forwarded to `RuiTablePagination`.\n */\n rangesThreshold?: number;\n /**\n * The text and icon shown when there are no rows, e.g.\n * `:empty=\"\\{ icon: 'transactions-line', label: 'No transactions found' \\}\"`\n */\n empty?: {\n label?: string;\n description?: string;\n };\n /**\n * Why the last read failed. Shown above any rows kept from an earlier read,\n * or in place of the empty state; `loading` still takes precedence.\n */\n error?: string;\n /** Heading for that failure. */\n errorTitle?: string;\n /** Label for the retry control; without one, no control is offered. */\n retryText?: string;\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?: GroupExpandButtonPosition;\n disabledRows?: readonly T[];\n multiPageSelect?: boolean;\n itemClass?: ((item: T) => string) | string;\n /**\n * Render each row as a stacked card instead of a table row once the measured\n * width is narrower than this width (in pixels). Columns flagged with\n * `mobileHidden` are dropped in this layout. Falls back to the global\n * `mobileBreakpoint` table default; leave both unset to keep the default table\n * layout at every width.\n */\n mobileBreakpoint?: number;\n /**\n * What the `mobileBreakpoint` is measured against: the browser `viewport`\n * (default) or this table's own `container` width. Use `container` when the\n * table lives in a narrow region of a wider window. Falls back to the global\n * `mobileBreakpointBasis` table default.\n */\n mobileBreakpointBasis?: 'viewport' | 'container';\n /**\n * Force the stacked mobile card layout on (`true`) or off (`false`),\n * regardless of `mobileBreakpoint`. Leave unset to derive it from the width.\n */\n mobile?: boolean;\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 rangesThreshold = 500,\n empty = { label: 'No item found' },\n error = '',\n errorTitle = '',\n retryText = '',\n hideDefaultHeader = false,\n hideDefaultFooter = false,\n rounded = 'md',\n singleExpand = false,\n stickyHeader = false,\n stickyOffset,\n globalItemsPerPage = undefined,\n groupExpandButtonPosition = GroupExpandButtonPosition.start,\n disabledRows,\n multiPageSelect = false,\n itemClass = '',\n mobileBreakpoint,\n mobileBreakpointBasis,\n mobile,\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 'retry': [];\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 'error': () => any;\n 'tfoot': () => any;\n }\n>>();\n\nconst tableDefaults = useTable();\n\nconst tableWrapper = useTemplateRef<HTMLElement>('tableWrapper');\nconst { width: windowWidth } = useWindowSize();\nconst { width: containerWidth } = useElementSize(tableWrapper);\n\n// Per-table props win, then the global table defaults.\nconst resolvedMobileBreakpoint = computed<number | undefined>(() => {\n if (mobileBreakpoint !== undefined)\n return mobileBreakpoint;\n const globalBreakpoint = tableDefaults.mobileBreakpoint;\n return globalBreakpoint === undefined ? undefined : get(globalBreakpoint);\n});\nconst resolvedMobileBasis = computed<'viewport' | 'container'>(() => {\n if (mobileBreakpointBasis !== undefined)\n return mobileBreakpointBasis;\n const globalBasis = tableDefaults.mobileBreakpointBasis;\n return globalBasis === undefined ? 'viewport' : get(globalBasis);\n});\n\n/**\n * Whether the stacked card layout is showing.\n *\n * Vue coerces an absent Boolean prop to `false`, so `mobile` cannot say\n * \"unset\": with no breakpoint configured it is the manual switch, defaulting\n * to desktop, and with one configured the breakpoint drives the layout while\n * `mobile === true` can still force the stacked layout on.\n */\nconst isMobile = computed<boolean>(() => {\n const breakpoint = get(resolvedMobileBreakpoint);\n if (breakpoint === undefined)\n return mobile;\n if (mobile)\n return true;\n // `containerWidth` is 0 until measured; the viewport keeps the first paint off mobile\n const width = get(resolvedMobileBasis) === 'container'\n ? (get(containerWidth) || get(windowWidth))\n : get(windowWidth);\n return width < breakpoint;\n});\n\nconst stickyHeaderOffset = computed<number | undefined>(() =>\n stickyOffset !== undefined ? stickyOffset : get(tableDefaults.stickyOffset),\n);\n\n/**\n * A table rendered inside an expanded row must not pin its own toolbar: only\n * the outermost table sticks, otherwise the bars stack and collide.\n */\nconst isNestedTable = useDataTableNested();\nprovideDataTableNested();\n\n/**\n * On mobile there is no column header to pin, so `stickyHeader` pins the\n * pagination and sort toolbar instead while the card list scrolls.\n */\nconst stickyMobileToolbar = computed<boolean>(() => stickyHeader && get(isMobile) && !isNestedTable);\n\nconst table = useTemplateRef<HTMLTableElement>('table');\nconst tableScroller = useTemplateRef<HTMLElement>('tableScroller');\n\nconst { stick } = useStickyTableHeader(\n () => stickyHeader,\n stickyHeaderOffset,\n { table },\n);\n\nconst { width: scrollerWidth } = useElementSize(tableScroller);\n\n/**\n * The visible width of the table, which an expanded row caps its content to.\n * Without the cap a wide panel, such as a nested table, sets the minimum width\n * of the whole table and pushes every column past the scroller. `initial`\n * resets the variable, so a nested table never inherits its parent's width.\n */\nconst viewportStyle = computed<Record<string, string>>(() => {\n const width = get(scrollerWidth);\n return { '--rui-table-viewport': width > 0 && !get(isMobile) ? `${width}px` : 'initial' };\n});\n\nconst { expandable, isExpanded, onToggleExpand } = useTableExpansion<T, IdType>(\n { rowAttr, singleExpand },\n { expanded },\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 mappedGroups,\n isExpandedGroup,\n isHiddenRow,\n onToggleExpandGroup,\n onUngroup,\n} = useTableGrouping<T, IdType>(\n { rowAttr },\n {\n group,\n collapsed,\n sorted,\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\n/**\n * With the header bar showing, an empty table drops its footer bar: two rows\n * of disabled controls around an empty state only add noise.\n */\nconst showFooter = computed<boolean>(() => {\n const data = get(paginationData);\n if (!data || hideDefaultFooter)\n return false;\n return data.total > 0 || hideDefaultHeader;\n});\n\n/**\n * Grouped columns leave the column list, so their labels come from `cols`.\n */\nconst groupLabels = computed<DataTableGroupLabel[]>(() => get(groupKeys).map((key) => {\n const label = cols?.find(column => column.key === key)?.[columnAttr];\n return {\n key: String(key),\n label: label === undefined || label === null ? String(key) : String(label),\n };\n}));\n\n/** Each group's list starts with its header entry, which is not a row. */\nfunction getGroupSize(identifier: string): number {\n return Math.max((get(mappedGroups)[identifier]?.length ?? 0) - 1, 0);\n}\n\nconst ui = computed<ReturnType<typeof dataTableStyles>>(() => dataTableStyles({\n outlined,\n rounded,\n dense,\n striped,\n mobile: get(isMobile),\n}));\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 isMobile,\n tdResolver: options => get(ui).td(options),\n});\n\nconst showMobileSort = computed<boolean>(() =>\n get(isMobile) && !!get(sortData) && get(columns).some(column => column.sortable),\n);\n\nconst ITEM_SLOT_PREFIX = 'item.';\n\n// Slot keys are static for the component lifetime — no reactivity needed\nconst itemSlotKeys: Set<string> = new Set(\n Object.keys(slots)\n .filter((key): key is `item.${string}` => key.startsWith(ITEM_SLOT_PREFIX))\n .map(key => key.slice(ITEM_SLOT_PREFIX.length)),\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/**\n * Sorting clears the selection. That lives here rather than in either\n * composable, which would make sort and selection depend on each other.\n */\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 if ((get(expanded)?.length ?? 0) > 0)\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\nconst classes = computed<DataTableClasses>(() => {\n const s = get(ui);\n return {\n td: s.td(),\n tr: s.tr(),\n trSelected: s.tr({ rowVariant: 'selected' }),\n trExpandable: s.tr({ rowVariant: 'expandable' }),\n trExpandedParent: s.tr({ rowVariant: 'expandedParent' }),\n trGroup: s.tr({ rowVariant: 'group' }),\n trEmpty: s.tr({ rowVariant: 'empty' }),\n checkbox: s.checkbox(),\n tbody: s.tbody(),\n tbodyLoader: s.tbodyLoader(),\n };\n});\n\nprovideDataTableContext<T, IdType>({\n // Reactive (ComputedRef/Ref) — destructuring preserves reactivity via Vue template auto-unwrap\n classes,\n columns,\n colspan,\n expandable,\n groupKey,\n groupLabels,\n isMobile,\n selectedData,\n // Static values\n cellValue,\n columnAttr,\n dense,\n getGroupSize,\n getRowId: (row: T) => row[rowAttr],\n itemSlotKeys,\n groupExpandButtonPosition,\n isDisabledRow,\n isExpanded,\n isExpandedGroup,\n isSelected,\n itemClass,\n onCheckboxClick,\n onCopyGroup: (header: GroupHeader<T>) => emit('copy:group', { key: get(groupKey) ?? '', value: header.group }),\n onSelect,\n onToggleExpand,\n onToggleExpandGroup,\n onUngroup,\n});\n</script>\n\n<template>\n <div\n ref=\"tableWrapper\"\n :class=\"ui.wrapper()\"\n data-id=\"table-wrapper\"\n >\n <div\n :class=\"stickyMobileToolbar ? 'sticky z-10 bg-white dark:bg-[#121212] pt-2' : 'contents'\"\n :style=\"stickyMobileToolbar ? { top: `${stickyHeaderOffset ?? 0}px` } : undefined\"\n data-id=\"table-mobile-toolbar-sticky\"\n >\n <RuiTablePagination\n v-if=\"paginationData && !hideDefaultHeader\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :mobile=\"isMobile\"\n :disable-per-page=\"disablePerPage\"\n :ranges-threshold=\"rangesThreshold\"\n data-id=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n <div\n v-if=\"showMobileSort\"\n class=\"flex justify-end p-2\"\n data-id=\"table-mobile-toolbar\"\n >\n <RuiDataTableMobileSort\n :columns=\"columns\"\n :column-attr=\"columnAttr\"\n :sorted-map=\"sortedMap\"\n :dense=\"dense\"\n @sort=\"onSort($event)\"\n />\n </div>\n </div>\n <div\n ref=\"tableScroller\"\n :class=\"[ui.scroller(), isMobile && !showMobileSort ? 'pt-2' : '']\"\n data-id=\"table-scroller\"\n >\n <table\n ref=\"table\"\n :class=\"ui.table()\"\n :style=\"viewportStyle\"\n :aria-busy=\"loading\"\n >\n <RuiTableHead\n v-if=\"!isMobile\"\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 :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 && !isMobile\"\n :loading=\"loading\"\n :capitalize-headers=\"!cols\"\n :colspan=\"colspan\"\n :column-attr=\"columnAttr\"\n :columns=\"columns\"\n :dense=\"dense\"\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 <RuiDataTableBody\n :filtered=\"filtered\"\n :loading=\"loading\"\n :no-data=\"noData\"\n :empty=\"empty\"\n :error=\"error\"\n :error-title=\"errorTitle\"\n :retry-text=\"retryText\"\n @retry=\"emit('retry')\"\n >\n <template\n v-if=\"slots.error\"\n #error\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"error\" />\n </template>\n <template\n v-if=\"slots['body.prepend']\"\n #body.prepend=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"body.prepend\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['group.header']\"\n #group.header=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['group.header.content']\"\n #group.header.content=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header.content\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-for=\"key in itemSlotKeys\"\n #[`item.${key}`]=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n :name=\"`item.${key}`\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['expanded-item']\"\n #expanded-item=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"expanded-item\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['no-data']\"\n #no-data\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"no-data\" />\n </template>\n <template\n v-if=\"slots['empty-description']\"\n #empty-description\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"empty-description\" />\n </template>\n <template\n v-if=\"slots['body.append']\"\n #body.append=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"body.append\"\n v-bind=\"slotData\"\n />\n </template>\n </RuiDataTableBody>\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 && showFooter\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :mobile=\"isMobile\"\n :disable-per-page=\"disablePerPage\"\n :ranges-threshold=\"rangesThreshold\"\n data-id=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -60,6 +60,15 @@ export interface Props<T, K extends keyof T> {
|
|
|
60
60
|
label?: string;
|
|
61
61
|
description?: string;
|
|
62
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Why the last read failed. Shown above any rows kept from an earlier read,
|
|
65
|
+
* or in place of the empty state; `loading` still takes precedence.
|
|
66
|
+
*/
|
|
67
|
+
error?: string;
|
|
68
|
+
/** Heading for that failure. */
|
|
69
|
+
errorTitle?: string;
|
|
70
|
+
/** Label for the retry control; without one, no control is offered. */
|
|
71
|
+
retryText?: string;
|
|
63
72
|
/**
|
|
64
73
|
* should hide the header navigation
|
|
65
74
|
*/
|
|
@@ -120,6 +129,7 @@ declare const __VLS_export: <T extends object, IdType extends keyof T = keyof T>
|
|
|
120
129
|
collapsed?: T[];
|
|
121
130
|
}) & {
|
|
122
131
|
"onUpdate:modelValue"?: ((value: T[IdType][] | undefined) => any) | undefined;
|
|
132
|
+
onRetry?: (() => any) | undefined;
|
|
123
133
|
"onUpdate:options"?: ((value: {
|
|
124
134
|
pagination?: TablePaginationData;
|
|
125
135
|
sort?: TableSortData<T>;
|
|
@@ -164,9 +174,10 @@ declare const __VLS_export: <T extends object, IdType extends keyof T = keyof T>
|
|
|
164
174
|
}) => any;
|
|
165
175
|
'no-data': () => any;
|
|
166
176
|
'empty-description': () => any;
|
|
177
|
+
error: () => any;
|
|
167
178
|
tfoot: () => any;
|
|
168
179
|
}>;
|
|
169
|
-
emit: (((evt: "update:options", value: {
|
|
180
|
+
emit: (((evt: "retry") => void) & ((evt: "update:options", value: {
|
|
170
181
|
pagination?: TablePaginationData;
|
|
171
182
|
sort?: TableSortData<T>;
|
|
172
183
|
}) => void) & ((evt: "copy:group", value: GroupData<T>) => void)) & (((event: "update:modelValue", value: T[IdType][] | undefined) => void) & ((event: "update:expanded", value: T[] | undefined) => void) & ((event: "update:pagination", value: TablePaginationData | undefined) => void) & ((event: "update:sort", value: TableSortData<T>) => void) & ((event: "update:group", value: TableRowKeyData<T>) => void) & ((event: "update:collapsed", value: T[] | undefined) => void));
|
|
@@ -56,6 +56,9 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
56
56
|
},
|
|
57
57
|
rangesThreshold: { default: 500 },
|
|
58
58
|
empty: { default: () => ({ label: "No item found" }) },
|
|
59
|
+
error: { default: "" },
|
|
60
|
+
errorTitle: { default: "" },
|
|
61
|
+
retryText: { default: "" },
|
|
59
62
|
hideDefaultHeader: {
|
|
60
63
|
type: Boolean,
|
|
61
64
|
default: false
|
|
@@ -105,7 +108,11 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
105
108
|
"collapsed": {},
|
|
106
109
|
"collapsedModifiers": {}
|
|
107
110
|
}),
|
|
108
|
-
emits: /*@__PURE__*/ mergeModels([
|
|
111
|
+
emits: /*@__PURE__*/ mergeModels([
|
|
112
|
+
"update:options",
|
|
113
|
+
"copy:group",
|
|
114
|
+
"retry"
|
|
115
|
+
], [
|
|
109
116
|
"update:modelValue",
|
|
110
117
|
"update:expanded",
|
|
111
118
|
"update:pagination",
|
|
@@ -164,9 +171,17 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
164
171
|
const stickyMobileToolbar = computed(() => __props.stickyHeader && get$1(isMobile) && !isNestedTable);
|
|
165
172
|
const table = useTemplateRef("table");
|
|
166
173
|
const tableScroller = useTemplateRef("tableScroller");
|
|
167
|
-
const { stick } = useStickyTableHeader(() => __props.stickyHeader, stickyHeaderOffset, {
|
|
168
|
-
|
|
169
|
-
|
|
174
|
+
const { stick } = useStickyTableHeader(() => __props.stickyHeader, stickyHeaderOffset, { table });
|
|
175
|
+
const { width: scrollerWidth } = useElementSize(tableScroller);
|
|
176
|
+
/**
|
|
177
|
+
* The visible width of the table, which an expanded row caps its content to.
|
|
178
|
+
* Without the cap a wide panel, such as a nested table, sets the minimum width
|
|
179
|
+
* of the whole table and pushes every column past the scroller. `initial`
|
|
180
|
+
* resets the variable, so a nested table never inherits its parent's width.
|
|
181
|
+
*/
|
|
182
|
+
const viewportStyle = computed(() => {
|
|
183
|
+
const width = get$1(scrollerWidth);
|
|
184
|
+
return { "--rui-table-viewport": width > 0 && !get$1(isMobile) ? `${width}px` : "initial" };
|
|
170
185
|
});
|
|
171
186
|
const { expandable, isExpanded, onToggleExpand } = useTableExpansion({
|
|
172
187
|
rowAttr: __props.rowAttr,
|
|
@@ -184,7 +199,7 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
184
199
|
pagination,
|
|
185
200
|
emitUpdateOptions
|
|
186
201
|
});
|
|
187
|
-
const { groupKeys, groupKey, grouped, isExpandedGroup, isHiddenRow, onToggleExpandGroup, onUngroup } = useTableGrouping({ rowAttr: __props.rowAttr }, {
|
|
202
|
+
const { groupKeys, groupKey, grouped, mappedGroups, isExpandedGroup, isHiddenRow, onToggleExpandGroup, onUngroup } = useTableGrouping({ rowAttr: __props.rowAttr }, {
|
|
188
203
|
group,
|
|
189
204
|
collapsed,
|
|
190
205
|
sorted
|
|
@@ -202,6 +217,29 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
202
217
|
tableDefaults
|
|
203
218
|
});
|
|
204
219
|
const noData = computed(() => get$1(filtered).length === 0);
|
|
220
|
+
/**
|
|
221
|
+
* With the header bar showing, an empty table drops its footer bar: two rows
|
|
222
|
+
* of disabled controls around an empty state only add noise.
|
|
223
|
+
*/
|
|
224
|
+
const showFooter = computed(() => {
|
|
225
|
+
const data = get$1(paginationData);
|
|
226
|
+
if (!data || __props.hideDefaultFooter) return false;
|
|
227
|
+
return data.total > 0 || __props.hideDefaultHeader;
|
|
228
|
+
});
|
|
229
|
+
/**
|
|
230
|
+
* Grouped columns leave the column list, so their labels come from `cols`.
|
|
231
|
+
*/
|
|
232
|
+
const groupLabels = computed(() => get$1(groupKeys).map((key) => {
|
|
233
|
+
const label = __props.cols?.find((column) => column.key === key)?.[__props.columnAttr];
|
|
234
|
+
return {
|
|
235
|
+
key: String(key),
|
|
236
|
+
label: label === void 0 || label === null ? String(key) : String(label)
|
|
237
|
+
};
|
|
238
|
+
}));
|
|
239
|
+
/** Each group's list starts with its header entry, which is not a row. */
|
|
240
|
+
function getGroupSize(identifier) {
|
|
241
|
+
return Math.max((get$1(mappedGroups)[identifier]?.length ?? 0) - 1, 0);
|
|
242
|
+
}
|
|
205
243
|
const ui = computed(() => dataTableStyles({
|
|
206
244
|
outlined: __props.outlined,
|
|
207
245
|
rounded: __props.rounded,
|
|
@@ -263,6 +301,7 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
263
301
|
tr: s.tr(),
|
|
264
302
|
trSelected: s.tr({ rowVariant: "selected" }),
|
|
265
303
|
trExpandable: s.tr({ rowVariant: "expandable" }),
|
|
304
|
+
trExpandedParent: s.tr({ rowVariant: "expandedParent" }),
|
|
266
305
|
trGroup: s.tr({ rowVariant: "group" }),
|
|
267
306
|
trEmpty: s.tr({ rowVariant: "empty" }),
|
|
268
307
|
checkbox: s.checkbox(),
|
|
@@ -276,11 +315,13 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
276
315
|
colspan,
|
|
277
316
|
expandable,
|
|
278
317
|
groupKey,
|
|
318
|
+
groupLabels,
|
|
279
319
|
isMobile,
|
|
280
320
|
selectedData,
|
|
281
321
|
cellValue,
|
|
282
322
|
columnAttr: __props.columnAttr,
|
|
283
323
|
dense: __props.dense,
|
|
324
|
+
getGroupSize,
|
|
284
325
|
getRowId: (row) => row[__props.rowAttr],
|
|
285
326
|
itemSlotKeys,
|
|
286
327
|
groupExpandButtonPosition: __props.groupExpandButtonPosition,
|
|
@@ -348,6 +389,7 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
348
389
|
ref_key: "table",
|
|
349
390
|
ref: table,
|
|
350
391
|
class: normalizeClass(unref(ui).table()),
|
|
392
|
+
style: normalizeStyle(unref(viewportStyle)),
|
|
351
393
|
"aria-busy": __props.loading
|
|
352
394
|
}, [
|
|
353
395
|
!unref(isMobile) ? (openBlock(), createBlock(RuiTableHead_default, {
|
|
@@ -422,22 +464,31 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
422
464
|
filtered: unref(filtered),
|
|
423
465
|
loading: __props.loading,
|
|
424
466
|
"no-data": unref(noData),
|
|
425
|
-
empty: __props.empty
|
|
467
|
+
empty: __props.empty,
|
|
468
|
+
error: __props.error,
|
|
469
|
+
"error-title": __props.errorTitle,
|
|
470
|
+
"retry-text": __props.retryText,
|
|
471
|
+
onRetry: _cache[5] || (_cache[5] = ($event) => emit("retry"))
|
|
426
472
|
}, createSlots({ _: 2 }, [
|
|
473
|
+
slots.error ? {
|
|
474
|
+
name: "error",
|
|
475
|
+
fn: withCtx(() => [renderSlot(_ctx.$slots, "error")]),
|
|
476
|
+
key: "0"
|
|
477
|
+
} : void 0,
|
|
427
478
|
slots["body.prepend"] ? {
|
|
428
479
|
name: "body.prepend",
|
|
429
480
|
fn: withCtx((slotData) => [renderSlot(_ctx.$slots, "body.prepend", normalizeProps(guardReactiveProps(slotData)))]),
|
|
430
|
-
key: "
|
|
481
|
+
key: "1"
|
|
431
482
|
} : void 0,
|
|
432
483
|
slots["group.header"] ? {
|
|
433
484
|
name: "group.header",
|
|
434
485
|
fn: withCtx((slotData) => [renderSlot(_ctx.$slots, "group.header", normalizeProps(guardReactiveProps(slotData)))]),
|
|
435
|
-
key: "
|
|
486
|
+
key: "2"
|
|
436
487
|
} : void 0,
|
|
437
488
|
slots["group.header.content"] ? {
|
|
438
489
|
name: "group.header.content",
|
|
439
490
|
fn: withCtx((slotData) => [renderSlot(_ctx.$slots, "group.header.content", normalizeProps(guardReactiveProps(slotData)))]),
|
|
440
|
-
key: "
|
|
491
|
+
key: "3"
|
|
441
492
|
} : void 0,
|
|
442
493
|
renderList(unref(itemSlotKeys), (key) => {
|
|
443
494
|
return {
|
|
@@ -448,35 +499,38 @@ var RuiDataTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
448
499
|
slots["expanded-item"] ? {
|
|
449
500
|
name: "expanded-item",
|
|
450
501
|
fn: withCtx((slotData) => [renderSlot(_ctx.$slots, "expanded-item", normalizeProps(guardReactiveProps(slotData)))]),
|
|
451
|
-
key: "
|
|
502
|
+
key: "4"
|
|
452
503
|
} : void 0,
|
|
453
504
|
slots["no-data"] ? {
|
|
454
505
|
name: "no-data",
|
|
455
506
|
fn: withCtx(() => [renderSlot(_ctx.$slots, "no-data")]),
|
|
456
|
-
key: "
|
|
507
|
+
key: "5"
|
|
457
508
|
} : void 0,
|
|
458
509
|
slots["empty-description"] ? {
|
|
459
510
|
name: "empty-description",
|
|
460
511
|
fn: withCtx(() => [renderSlot(_ctx.$slots, "empty-description")]),
|
|
461
|
-
key: "
|
|
512
|
+
key: "6"
|
|
462
513
|
} : void 0,
|
|
463
514
|
slots["body.append"] ? {
|
|
464
515
|
name: "body.append",
|
|
465
516
|
fn: withCtx((slotData) => [renderSlot(_ctx.$slots, "body.append", normalizeProps(guardReactiveProps(slotData)))]),
|
|
466
|
-
key: "
|
|
517
|
+
key: "7"
|
|
467
518
|
} : void 0
|
|
468
519
|
]), 1032, [
|
|
469
520
|
"filtered",
|
|
470
521
|
"loading",
|
|
471
522
|
"no-data",
|
|
472
|
-
"empty"
|
|
523
|
+
"empty",
|
|
524
|
+
"error",
|
|
525
|
+
"error-title",
|
|
526
|
+
"retry-text"
|
|
473
527
|
]),
|
|
474
528
|
createElementVNode("tfoot", null, [renderSlot(_ctx.$slots, "tfoot")])
|
|
475
|
-
],
|
|
476
|
-
unref(paginationData) &&
|
|
529
|
+
], 14, _hoisted_2)], 2),
|
|
530
|
+
unref(paginationData) && unref(showFooter) ? (openBlock(), createBlock(RuiTablePagination_default, {
|
|
477
531
|
key: 0,
|
|
478
532
|
modelValue: unref(paginationData),
|
|
479
|
-
"onUpdate:modelValue": [_cache[
|
|
533
|
+
"onUpdate:modelValue": [_cache[6] || (_cache[6] = ($event) => isRef(paginationData) ? paginationData.value = $event : null), _cache[7] || (_cache[7] = ($event) => onPaginate())],
|
|
480
534
|
dense: __props.dense,
|
|
481
535
|
loading: __props.loading,
|
|
482
536
|
mobile: unref(isMobile),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiDataTable.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/tables/RuiDataTable.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends object, IdType extends keyof T = keyof T\">\nimport type { GroupHeader } from '@/composables/tables/data-table/types';\nimport { dataTableStyles } from '@/components/tables/data-table-styles';\nimport { type DataTableClasses, provideDataTableContext, provideDataTableNested, useDataTableNested } from '@/components/tables/data-table/context';\nimport RuiDataTableBody from '@/components/tables/data-table/RuiDataTableBody.vue';\nimport RuiDataTableMobileSort from '@/components/tables/data-table/RuiDataTableMobileSort.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 { GroupExpandButtonPosition } from '@/components/tables/table-props';\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';\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 * Maximum number of pages before the jump-to-page dropdown is replaced with\n * a numeric input. Defaults to `500`. Forwarded to `RuiTablePagination`.\n */\n rangesThreshold?: number;\n /**\n * The text and icon shown when there are no rows, e.g.\n * `: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?: GroupExpandButtonPosition;\n disabledRows?: readonly T[];\n multiPageSelect?: boolean;\n itemClass?: ((item: T) => string) | string;\n /**\n * Render each row as a stacked card instead of a table row once the measured\n * width is narrower than this width (in pixels). Columns flagged with\n * `mobileHidden` are dropped in this layout. Falls back to the global\n * `mobileBreakpoint` table default; leave both unset to keep the default table\n * layout at every width.\n */\n mobileBreakpoint?: number;\n /**\n * What the `mobileBreakpoint` is measured against: the browser `viewport`\n * (default) or this table's own `container` width. Use `container` when the\n * table lives in a narrow region of a wider window. Falls back to the global\n * `mobileBreakpointBasis` table default.\n */\n mobileBreakpointBasis?: 'viewport' | 'container';\n /**\n * Force the stacked mobile card layout on (`true`) or off (`false`),\n * regardless of `mobileBreakpoint`. Leave unset to derive it from the width.\n */\n mobile?: boolean;\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 rangesThreshold = 500,\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 = GroupExpandButtonPosition.start,\n disabledRows,\n multiPageSelect = false,\n itemClass = '',\n mobileBreakpoint,\n mobileBreakpointBasis,\n mobile,\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 tableWrapper = useTemplateRef<HTMLElement>('tableWrapper');\nconst { width: windowWidth } = useWindowSize();\nconst { width: containerWidth } = useElementSize(tableWrapper);\n\n// Per-table props win, then the global table defaults.\nconst resolvedMobileBreakpoint = computed<number | undefined>(() => {\n if (mobileBreakpoint !== undefined)\n return mobileBreakpoint;\n const globalBreakpoint = tableDefaults.mobileBreakpoint;\n return globalBreakpoint === undefined ? undefined : get(globalBreakpoint);\n});\nconst resolvedMobileBasis = computed<'viewport' | 'container'>(() => {\n if (mobileBreakpointBasis !== undefined)\n return mobileBreakpointBasis;\n const globalBasis = tableDefaults.mobileBreakpointBasis;\n return globalBasis === undefined ? 'viewport' : get(globalBasis);\n});\n\n/**\n * Whether the stacked card layout is showing.\n *\n * Vue coerces an absent Boolean prop to `false`, so `mobile` cannot say\n * \"unset\": with no breakpoint configured it is the manual switch, defaulting\n * to desktop, and with one configured the breakpoint drives the layout while\n * `mobile === true` can still force the stacked layout on.\n */\nconst isMobile = computed<boolean>(() => {\n const breakpoint = get(resolvedMobileBreakpoint);\n if (breakpoint === undefined)\n return mobile;\n if (mobile)\n return true;\n // `containerWidth` is 0 until measured; the viewport keeps the first paint off mobile\n const width = get(resolvedMobileBasis) === 'container'\n ? (get(containerWidth) || get(windowWidth))\n : get(windowWidth);\n return width < breakpoint;\n});\n\nconst stickyHeaderOffset = computed<number | undefined>(() =>\n stickyOffset !== undefined ? stickyOffset : get(tableDefaults.stickyOffset),\n);\n\n/**\n * A table rendered inside an expanded row must not pin its own toolbar: only\n * the outermost table sticks, otherwise the bars stack and collide.\n */\nconst isNestedTable = useDataTableNested();\nprovideDataTableNested();\n\n/**\n * On mobile there is no column header to pin, so `stickyHeader` pins the\n * pagination and sort toolbar instead while the card list scrolls.\n */\nconst stickyMobileToolbar = computed<boolean>(() => stickyHeader && get(isMobile) && !isNestedTable);\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 { expandable, isExpanded, onToggleExpand } = useTableExpansion<T, IdType>(\n { rowAttr, singleExpand },\n { expanded },\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} = useTableGrouping<T, IdType>(\n { rowAttr },\n {\n group,\n collapsed,\n sorted,\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 ui = computed<ReturnType<typeof dataTableStyles>>(() => dataTableStyles({\n outlined,\n rounded,\n dense,\n striped,\n mobile: get(isMobile),\n}));\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 isMobile,\n tdResolver: options => get(ui).td(options),\n});\n\nconst showMobileSort = computed<boolean>(() =>\n get(isMobile) && !!get(sortData) && get(columns).some(column => column.sortable),\n);\n\nconst ITEM_SLOT_PREFIX = 'item.';\n\n// Slot keys are static for the component lifetime — no reactivity needed\nconst itemSlotKeys: Set<string> = new Set(\n Object.keys(slots)\n .filter((key): key is `item.${string}` => key.startsWith(ITEM_SLOT_PREFIX))\n .map(key => key.slice(ITEM_SLOT_PREFIX.length)),\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/**\n * Sorting clears the selection. That lives here rather than in either\n * composable, which would make sort and selection depend on each other.\n */\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 if ((get(expanded)?.length ?? 0) > 0)\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\nconst classes = computed<DataTableClasses>(() => {\n const s = get(ui);\n return {\n td: s.td(),\n tr: s.tr(),\n trSelected: s.tr({ rowVariant: 'selected' }),\n trExpandable: s.tr({ rowVariant: 'expandable' }),\n trGroup: s.tr({ rowVariant: 'group' }),\n trEmpty: s.tr({ rowVariant: 'empty' }),\n checkbox: s.checkbox(),\n tbody: s.tbody(),\n tbodyLoader: s.tbodyLoader(),\n };\n});\n\nprovideDataTableContext<T, IdType>({\n // Reactive (ComputedRef/Ref) — destructuring preserves reactivity via Vue template auto-unwrap\n classes,\n columns,\n colspan,\n expandable,\n groupKey,\n isMobile,\n selectedData,\n // Static values\n cellValue,\n columnAttr,\n dense,\n getRowId: (row: T) => row[rowAttr],\n itemSlotKeys,\n groupExpandButtonPosition,\n isDisabledRow,\n isExpanded,\n isExpandedGroup,\n isSelected,\n itemClass,\n onCheckboxClick,\n onCopyGroup: (header: GroupHeader<T>) => emit('copy:group', { key: get(groupKey) ?? '', value: header.group }),\n onSelect,\n onToggleExpand,\n onToggleExpandGroup,\n onUngroup,\n});\n</script>\n\n<template>\n <div\n ref=\"tableWrapper\"\n :class=\"ui.wrapper()\"\n data-id=\"table-wrapper\"\n >\n <div\n :class=\"stickyMobileToolbar ? 'sticky z-10 bg-white dark:bg-[#121212] pt-2' : 'contents'\"\n :style=\"stickyMobileToolbar ? { top: `${stickyHeaderOffset ?? 0}px` } : undefined\"\n data-id=\"table-mobile-toolbar-sticky\"\n >\n <RuiTablePagination\n v-if=\"paginationData && !hideDefaultHeader\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :mobile=\"isMobile\"\n :disable-per-page=\"disablePerPage\"\n :ranges-threshold=\"rangesThreshold\"\n data-id=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n <div\n v-if=\"showMobileSort\"\n class=\"flex justify-end p-2\"\n data-id=\"table-mobile-toolbar\"\n >\n <RuiDataTableMobileSort\n :columns=\"columns\"\n :column-attr=\"columnAttr\"\n :sorted-map=\"sortedMap\"\n :dense=\"dense\"\n @sort=\"onSort($event)\"\n />\n </div>\n </div>\n <div\n ref=\"tableScroller\"\n :class=\"[ui.scroller(), isMobile && !showMobileSort ? 'pt-2' : '']\"\n data-id=\"table-scroller\"\n >\n <table\n ref=\"table\"\n :class=\"ui.table()\"\n :aria-busy=\"loading\"\n >\n <RuiTableHead\n v-if=\"!isMobile\"\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 :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 && !isMobile\"\n :loading=\"loading\"\n :capitalize-headers=\"!cols\"\n :colspan=\"colspan\"\n :column-attr=\"columnAttr\"\n :columns=\"columns\"\n :dense=\"dense\"\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 <RuiDataTableBody\n :filtered=\"filtered\"\n :loading=\"loading\"\n :no-data=\"noData\"\n :empty=\"empty\"\n >\n <template\n v-if=\"slots['body.prepend']\"\n #body.prepend=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"body.prepend\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['group.header']\"\n #group.header=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['group.header.content']\"\n #group.header.content=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header.content\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-for=\"key in itemSlotKeys\"\n #[`item.${key}`]=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n :name=\"`item.${key}`\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['expanded-item']\"\n #expanded-item=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"expanded-item\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['no-data']\"\n #no-data\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"no-data\" />\n </template>\n <template\n v-if=\"slots['empty-description']\"\n #empty-description\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"empty-description\" />\n </template>\n <template\n v-if=\"slots['body.append']\"\n #body.append=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"body.append\"\n v-bind=\"slotData\"\n />\n </template>\n </RuiDataTableBody>\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 :mobile=\"isMobile\"\n :disable-per-page=\"disablePerPage\"\n :ranges-threshold=\"rangesThreshold\"\n data-id=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RuiDataTable.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/tables/RuiDataTable.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends object, IdType extends keyof T = keyof T\">\nimport type { GroupHeader } from '@/composables/tables/data-table/types';\nimport { dataTableStyles } from '@/components/tables/data-table-styles';\nimport { type DataTableClasses, type DataTableGroupLabel, provideDataTableContext, provideDataTableNested, useDataTableNested } from '@/components/tables/data-table/context';\nimport RuiDataTableBody from '@/components/tables/data-table/RuiDataTableBody.vue';\nimport RuiDataTableMobileSort from '@/components/tables/data-table/RuiDataTableMobileSort.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 { GroupExpandButtonPosition } from '@/components/tables/table-props';\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';\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 * Maximum number of pages before the jump-to-page dropdown is replaced with\n * a numeric input. Defaults to `500`. Forwarded to `RuiTablePagination`.\n */\n rangesThreshold?: number;\n /**\n * The text and icon shown when there are no rows, e.g.\n * `:empty=\"\\{ icon: 'transactions-line', label: 'No transactions found' \\}\"`\n */\n empty?: {\n label?: string;\n description?: string;\n };\n /**\n * Why the last read failed. Shown above any rows kept from an earlier read,\n * or in place of the empty state; `loading` still takes precedence.\n */\n error?: string;\n /** Heading for that failure. */\n errorTitle?: string;\n /** Label for the retry control; without one, no control is offered. */\n retryText?: string;\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?: GroupExpandButtonPosition;\n disabledRows?: readonly T[];\n multiPageSelect?: boolean;\n itemClass?: ((item: T) => string) | string;\n /**\n * Render each row as a stacked card instead of a table row once the measured\n * width is narrower than this width (in pixels). Columns flagged with\n * `mobileHidden` are dropped in this layout. Falls back to the global\n * `mobileBreakpoint` table default; leave both unset to keep the default table\n * layout at every width.\n */\n mobileBreakpoint?: number;\n /**\n * What the `mobileBreakpoint` is measured against: the browser `viewport`\n * (default) or this table's own `container` width. Use `container` when the\n * table lives in a narrow region of a wider window. Falls back to the global\n * `mobileBreakpointBasis` table default.\n */\n mobileBreakpointBasis?: 'viewport' | 'container';\n /**\n * Force the stacked mobile card layout on (`true`) or off (`false`),\n * regardless of `mobileBreakpoint`. Leave unset to derive it from the width.\n */\n mobile?: boolean;\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 rangesThreshold = 500,\n empty = { label: 'No item found' },\n error = '',\n errorTitle = '',\n retryText = '',\n hideDefaultHeader = false,\n hideDefaultFooter = false,\n rounded = 'md',\n singleExpand = false,\n stickyHeader = false,\n stickyOffset,\n globalItemsPerPage = undefined,\n groupExpandButtonPosition = GroupExpandButtonPosition.start,\n disabledRows,\n multiPageSelect = false,\n itemClass = '',\n mobileBreakpoint,\n mobileBreakpointBasis,\n mobile,\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 'retry': [];\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 'error': () => any;\n 'tfoot': () => any;\n }\n>>();\n\nconst tableDefaults = useTable();\n\nconst tableWrapper = useTemplateRef<HTMLElement>('tableWrapper');\nconst { width: windowWidth } = useWindowSize();\nconst { width: containerWidth } = useElementSize(tableWrapper);\n\n// Per-table props win, then the global table defaults.\nconst resolvedMobileBreakpoint = computed<number | undefined>(() => {\n if (mobileBreakpoint !== undefined)\n return mobileBreakpoint;\n const globalBreakpoint = tableDefaults.mobileBreakpoint;\n return globalBreakpoint === undefined ? undefined : get(globalBreakpoint);\n});\nconst resolvedMobileBasis = computed<'viewport' | 'container'>(() => {\n if (mobileBreakpointBasis !== undefined)\n return mobileBreakpointBasis;\n const globalBasis = tableDefaults.mobileBreakpointBasis;\n return globalBasis === undefined ? 'viewport' : get(globalBasis);\n});\n\n/**\n * Whether the stacked card layout is showing.\n *\n * Vue coerces an absent Boolean prop to `false`, so `mobile` cannot say\n * \"unset\": with no breakpoint configured it is the manual switch, defaulting\n * to desktop, and with one configured the breakpoint drives the layout while\n * `mobile === true` can still force the stacked layout on.\n */\nconst isMobile = computed<boolean>(() => {\n const breakpoint = get(resolvedMobileBreakpoint);\n if (breakpoint === undefined)\n return mobile;\n if (mobile)\n return true;\n // `containerWidth` is 0 until measured; the viewport keeps the first paint off mobile\n const width = get(resolvedMobileBasis) === 'container'\n ? (get(containerWidth) || get(windowWidth))\n : get(windowWidth);\n return width < breakpoint;\n});\n\nconst stickyHeaderOffset = computed<number | undefined>(() =>\n stickyOffset !== undefined ? stickyOffset : get(tableDefaults.stickyOffset),\n);\n\n/**\n * A table rendered inside an expanded row must not pin its own toolbar: only\n * the outermost table sticks, otherwise the bars stack and collide.\n */\nconst isNestedTable = useDataTableNested();\nprovideDataTableNested();\n\n/**\n * On mobile there is no column header to pin, so `stickyHeader` pins the\n * pagination and sort toolbar instead while the card list scrolls.\n */\nconst stickyMobileToolbar = computed<boolean>(() => stickyHeader && get(isMobile) && !isNestedTable);\n\nconst table = useTemplateRef<HTMLTableElement>('table');\nconst tableScroller = useTemplateRef<HTMLElement>('tableScroller');\n\nconst { stick } = useStickyTableHeader(\n () => stickyHeader,\n stickyHeaderOffset,\n { table },\n);\n\nconst { width: scrollerWidth } = useElementSize(tableScroller);\n\n/**\n * The visible width of the table, which an expanded row caps its content to.\n * Without the cap a wide panel, such as a nested table, sets the minimum width\n * of the whole table and pushes every column past the scroller. `initial`\n * resets the variable, so a nested table never inherits its parent's width.\n */\nconst viewportStyle = computed<Record<string, string>>(() => {\n const width = get(scrollerWidth);\n return { '--rui-table-viewport': width > 0 && !get(isMobile) ? `${width}px` : 'initial' };\n});\n\nconst { expandable, isExpanded, onToggleExpand } = useTableExpansion<T, IdType>(\n { rowAttr, singleExpand },\n { expanded },\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 mappedGroups,\n isExpandedGroup,\n isHiddenRow,\n onToggleExpandGroup,\n onUngroup,\n} = useTableGrouping<T, IdType>(\n { rowAttr },\n {\n group,\n collapsed,\n sorted,\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\n/**\n * With the header bar showing, an empty table drops its footer bar: two rows\n * of disabled controls around an empty state only add noise.\n */\nconst showFooter = computed<boolean>(() => {\n const data = get(paginationData);\n if (!data || hideDefaultFooter)\n return false;\n return data.total > 0 || hideDefaultHeader;\n});\n\n/**\n * Grouped columns leave the column list, so their labels come from `cols`.\n */\nconst groupLabels = computed<DataTableGroupLabel[]>(() => get(groupKeys).map((key) => {\n const label = cols?.find(column => column.key === key)?.[columnAttr];\n return {\n key: String(key),\n label: label === undefined || label === null ? String(key) : String(label),\n };\n}));\n\n/** Each group's list starts with its header entry, which is not a row. */\nfunction getGroupSize(identifier: string): number {\n return Math.max((get(mappedGroups)[identifier]?.length ?? 0) - 1, 0);\n}\n\nconst ui = computed<ReturnType<typeof dataTableStyles>>(() => dataTableStyles({\n outlined,\n rounded,\n dense,\n striped,\n mobile: get(isMobile),\n}));\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 isMobile,\n tdResolver: options => get(ui).td(options),\n});\n\nconst showMobileSort = computed<boolean>(() =>\n get(isMobile) && !!get(sortData) && get(columns).some(column => column.sortable),\n);\n\nconst ITEM_SLOT_PREFIX = 'item.';\n\n// Slot keys are static for the component lifetime — no reactivity needed\nconst itemSlotKeys: Set<string> = new Set(\n Object.keys(slots)\n .filter((key): key is `item.${string}` => key.startsWith(ITEM_SLOT_PREFIX))\n .map(key => key.slice(ITEM_SLOT_PREFIX.length)),\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/**\n * Sorting clears the selection. That lives here rather than in either\n * composable, which would make sort and selection depend on each other.\n */\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 if ((get(expanded)?.length ?? 0) > 0)\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\nconst classes = computed<DataTableClasses>(() => {\n const s = get(ui);\n return {\n td: s.td(),\n tr: s.tr(),\n trSelected: s.tr({ rowVariant: 'selected' }),\n trExpandable: s.tr({ rowVariant: 'expandable' }),\n trExpandedParent: s.tr({ rowVariant: 'expandedParent' }),\n trGroup: s.tr({ rowVariant: 'group' }),\n trEmpty: s.tr({ rowVariant: 'empty' }),\n checkbox: s.checkbox(),\n tbody: s.tbody(),\n tbodyLoader: s.tbodyLoader(),\n };\n});\n\nprovideDataTableContext<T, IdType>({\n // Reactive (ComputedRef/Ref) — destructuring preserves reactivity via Vue template auto-unwrap\n classes,\n columns,\n colspan,\n expandable,\n groupKey,\n groupLabels,\n isMobile,\n selectedData,\n // Static values\n cellValue,\n columnAttr,\n dense,\n getGroupSize,\n getRowId: (row: T) => row[rowAttr],\n itemSlotKeys,\n groupExpandButtonPosition,\n isDisabledRow,\n isExpanded,\n isExpandedGroup,\n isSelected,\n itemClass,\n onCheckboxClick,\n onCopyGroup: (header: GroupHeader<T>) => emit('copy:group', { key: get(groupKey) ?? '', value: header.group }),\n onSelect,\n onToggleExpand,\n onToggleExpandGroup,\n onUngroup,\n});\n</script>\n\n<template>\n <div\n ref=\"tableWrapper\"\n :class=\"ui.wrapper()\"\n data-id=\"table-wrapper\"\n >\n <div\n :class=\"stickyMobileToolbar ? 'sticky z-10 bg-white dark:bg-[#121212] pt-2' : 'contents'\"\n :style=\"stickyMobileToolbar ? { top: `${stickyHeaderOffset ?? 0}px` } : undefined\"\n data-id=\"table-mobile-toolbar-sticky\"\n >\n <RuiTablePagination\n v-if=\"paginationData && !hideDefaultHeader\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :mobile=\"isMobile\"\n :disable-per-page=\"disablePerPage\"\n :ranges-threshold=\"rangesThreshold\"\n data-id=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n <div\n v-if=\"showMobileSort\"\n class=\"flex justify-end p-2\"\n data-id=\"table-mobile-toolbar\"\n >\n <RuiDataTableMobileSort\n :columns=\"columns\"\n :column-attr=\"columnAttr\"\n :sorted-map=\"sortedMap\"\n :dense=\"dense\"\n @sort=\"onSort($event)\"\n />\n </div>\n </div>\n <div\n ref=\"tableScroller\"\n :class=\"[ui.scroller(), isMobile && !showMobileSort ? 'pt-2' : '']\"\n data-id=\"table-scroller\"\n >\n <table\n ref=\"table\"\n :class=\"ui.table()\"\n :style=\"viewportStyle\"\n :aria-busy=\"loading\"\n >\n <RuiTableHead\n v-if=\"!isMobile\"\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 :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 && !isMobile\"\n :loading=\"loading\"\n :capitalize-headers=\"!cols\"\n :colspan=\"colspan\"\n :column-attr=\"columnAttr\"\n :columns=\"columns\"\n :dense=\"dense\"\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 <RuiDataTableBody\n :filtered=\"filtered\"\n :loading=\"loading\"\n :no-data=\"noData\"\n :empty=\"empty\"\n :error=\"error\"\n :error-title=\"errorTitle\"\n :retry-text=\"retryText\"\n @retry=\"emit('retry')\"\n >\n <template\n v-if=\"slots.error\"\n #error\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"error\" />\n </template>\n <template\n v-if=\"slots['body.prepend']\"\n #body.prepend=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"body.prepend\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['group.header']\"\n #group.header=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['group.header.content']\"\n #group.header.content=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"group.header.content\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-for=\"key in itemSlotKeys\"\n #[`item.${key}`]=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n :name=\"`item.${key}`\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['expanded-item']\"\n #expanded-item=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"expanded-item\"\n v-bind=\"slotData\"\n />\n </template>\n <template\n v-if=\"slots['no-data']\"\n #no-data\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"no-data\" />\n </template>\n <template\n v-if=\"slots['empty-description']\"\n #empty-description\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot name=\"empty-description\" />\n </template>\n <template\n v-if=\"slots['body.append']\"\n #body.append=\"slotData\"\n >\n <!-- eslint-disable-next-line vue/require-explicit-slots -- defined via Partial<Record<...>> in defineSlots -->\n <slot\n name=\"body.append\"\n v-bind=\"slotData\"\n />\n </template>\n </RuiDataTableBody>\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 && showFooter\"\n v-model=\"paginationData\"\n :dense=\"dense\"\n :loading=\"loading\"\n :mobile=\"isMobile\"\n :disable-per-page=\"disablePerPage\"\n :ranges-threshold=\"rangesThreshold\"\n data-id=\"table-pagination\"\n @update:model-value=\"onPaginate()\"\n />\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { tv } from "../../utils/tv.js";
|
|
2
2
|
import RuiTableEmptyState_default from "./RuiTableEmptyState.js";
|
|
3
|
-
import RuiTableLoadingState_default from "./RuiTableLoadingState.js";
|
|
4
3
|
import RuiTableErrorState_default from "./RuiTableErrorState.js";
|
|
4
|
+
import RuiTableLoadingState_default from "./RuiTableLoadingState.js";
|
|
5
5
|
import { computed, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeProps, normalizeClass, openBlock, renderSlot } from "vue";
|
|
6
6
|
//#region src/components/tables/RuiTable.vue?vue&type=script&setup=true&lang.ts
|
|
7
7
|
var RuiTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|