@leaflink/stash 53.4.8 → 53.4.10
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/DataTable/index.js +577 -541
- package/dist/DataTable/index.js.map +1 -1
- package/dist/Modal.js +7 -7
- package/dist/Modal.js.map +1 -1
- package/dist/Table.js +116 -101
- package/dist/Table.js.map +1 -1
- package/dist/Table.vue.d.ts +21 -0
- package/dist/TableHeaderCell.js +43 -39
- package/dist/TableHeaderCell.js.map +1 -1
- package/dist/components.css +1 -1
- package/package.json +1 -1
package/dist/Modal.js
CHANGED
|
@@ -7,7 +7,7 @@ import j from "./Button.js";
|
|
|
7
7
|
import N from "./Icon.js";
|
|
8
8
|
import { _ as J } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
9
9
|
var Q = /* @__PURE__ */ ((a) => (a.Narrow = "narrow", a.Medium = "medium", a.Wide = "wide", a))(Q || {}), X = /* @__PURE__ */ ((a) => (a.Center = "center", a.Left = "left", a.Right = "right", a))(X || {});
|
|
10
|
-
const Y = ["aria-labelledby"], Z = { class: "flex place-items-center" }, ee = ["id"], te = { class: "stash-modal__footer__actions flex
|
|
10
|
+
const Y = ["aria-labelledby"], Z = { class: "flex place-items-center" }, ee = ["id"], te = { class: "stash-modal__footer__actions flex justify-end" }, le = /* @__PURE__ */ R({
|
|
11
11
|
name: "ll-modal",
|
|
12
12
|
__name: "Modal",
|
|
13
13
|
props: {
|
|
@@ -27,7 +27,7 @@ const Y = ["aria-labelledby"], Z = { class: "flex place-items-center" }, ee = ["
|
|
|
27
27
|
},
|
|
28
28
|
emits: ["update:open", "update:is-open", "dismiss"],
|
|
29
29
|
setup(a, { emit: A }) {
|
|
30
|
-
const e = a, w = A, b = V(), r = c(), E = c(null), v = c([]), k = c(),
|
|
30
|
+
const e = a, w = A, b = V(), r = c(), E = c(null), v = c([]), k = c(), B = c(), f = c({ height: "", overflow: "" }), L = U("modal-header-"), O = C(() => !!b.actions || !!b.footer), l = C(() => e.open || e.isOpen), s = C(() => e.position === "left" || e.position === "right");
|
|
31
31
|
let u = !1;
|
|
32
32
|
function g() {
|
|
33
33
|
return document.scrollingElement || document.body;
|
|
@@ -41,7 +41,7 @@ const Y = ["aria-labelledby"], Z = { class: "flex place-items-center" }, ee = ["
|
|
|
41
41
|
const o = document.activeElement;
|
|
42
42
|
E.value = o instanceof HTMLElement ? o : null;
|
|
43
43
|
} else
|
|
44
|
-
u && (document.removeEventListener("keydown",
|
|
44
|
+
u && (document.removeEventListener("keydown", x), u = !1), (t = E.value) == null || t.focus();
|
|
45
45
|
l.value && Object.assign(f.value, {
|
|
46
46
|
height: g().style.height,
|
|
47
47
|
overflow: g().style.overflow
|
|
@@ -59,17 +59,17 @@ const Y = ["aria-labelledby"], Z = { class: "flex place-items-center" }, ee = ["
|
|
|
59
59
|
typeof document > "u" || (S("show"), Object.assign(g().style, {
|
|
60
60
|
overflow: f.value.overflow,
|
|
61
61
|
height: f.value.height
|
|
62
|
-
}), u && (document.removeEventListener("keydown",
|
|
62
|
+
}), u && (document.removeEventListener("keydown", x), u = !1), (t = E.value) == null || t.focus());
|
|
63
63
|
});
|
|
64
64
|
function y() {
|
|
65
65
|
e.preventDismiss || (w("update:open", !1), w("update:is-open", !1), w("dismiss"));
|
|
66
66
|
}
|
|
67
|
-
function
|
|
67
|
+
function x(t) {
|
|
68
68
|
var o, $;
|
|
69
|
-
t.key === "Tab" && (t.shiftKey && document.activeElement === k.value ? ((o =
|
|
69
|
+
t.key === "Tab" && (t.shiftKey && document.activeElement === k.value ? ((o = B.value) == null || o.focus(), t.preventDefault()) : document.activeElement === B.value && (($ = k.value) == null || $.focus(), t.preventDefault()));
|
|
70
70
|
}
|
|
71
71
|
function I() {
|
|
72
|
-
typeof document > "u" || !r.value || !l.value || (r.value.focus(), v.value = Array.from(r.value.querySelectorAll(W)), k.value = v.value[0],
|
|
72
|
+
typeof document > "u" || !r.value || !l.value || (r.value.focus(), v.value = Array.from(r.value.querySelectorAll(W)), k.value = v.value[0], B.value = v.value[v.value.length - 1], u || (document.addEventListener("keydown", x), u = !0));
|
|
73
73
|
}
|
|
74
74
|
F(r, () => {
|
|
75
75
|
!r.value || !l.value || I();
|
package/dist/Modal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.js","sources":["../src/components/Modal/Modal.types.ts","../src/components/Modal/Modal.vue"],"sourcesContent":["export enum ModalSize {\n Narrow = 'narrow',\n Medium = 'medium',\n Wide = 'wide',\n}\n\nexport type ModalSizes = `${ModalSize}`;\n\nexport enum ModalPosition {\n Center = 'center',\n Left = 'left',\n Right = 'right',\n}\n\nexport type ModalPositions = `${ModalPosition}`;\n","<script lang=\"ts\">\n import { ModalPositions, ModalSizes } from './Modal.types';\n\n export * from './Modal.types';\n\n export interface ModalProps {\n /**\n * Hides the \"close\" button\n */\n hideClose?: boolean;\n\n /**\n * Opens the modal when truthy; hides the modal when falsy.\n * @deprecated Use `isOpen` instead\n */\n open?: boolean;\n\n /**\n * Opens the modal when truthy; hides the modal when falsy.\n */\n isOpen?: boolean;\n\n /**\n * Use v-model:is-open or :is-open instead of :model-value and v-model.\n * @deprecated\n */\n modelValue?: boolean;\n\n /**\n * Sets a preset max-width on the modal.\n * Options: default (648px), narrow (360px), wide (960px)\n */\n size?: ModalSizes;\n\n /**\n * Should the modal be scrollable within the content area. This prop is treated as `true` when the `position` prop is set to \"left\" or \"right\".\n */\n scrollable?: boolean;\n\n /**\n * Gives the modal body have a light gray background\n */\n contrast?: boolean;\n\n /**\n * Text to display in the modal header\n */\n title?: string;\n\n /**\n * Disables the default padding in the modal body.\n */\n disableBodyPadding?: boolean;\n\n /**\n * The position on the screen to display the modal.\n */\n position?: ModalPositions;\n\n /**\n * Hide the header. Typically used with the featuredContent slot to display a graphic and create a \"promo\" modal.\n */\n hideHeader?: boolean;\n\n /**\n * Add classes to the close button. This can be used with the hideHeader prop and featuredContent slot to\n * accommodate images with different color backgrounds.\n */\n closeButtonColorClass?: string;\n\n /**\n * Prevents the modal from being dismissed by clicking the backdrop or pressing the escape key.\n * Example: There are in-flight api requests and you do not want the modal to close until they are done.\n */\n preventDismiss?: boolean;\n }\n</script>\n\n<script setup lang=\"ts\">\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, onBeforeUnmount, ref, useSlots, watch } from 'vue';\n\n import { FOCUS_ELEMENTS_SELECTOR } from '../../constants';\n import { t } from '../../locale';\n import Backdrop from '../Backdrop/Backdrop.vue';\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({ name: 'll-modal' });\n\n const props = withDefaults(defineProps<ModalProps>(), {\n hideClose: false,\n open: false,\n isOpen: false,\n modelValue: false,\n size: 'medium',\n scrollable: false,\n contrast: false,\n title: '',\n position: 'center',\n hideHeader: false,\n closeButtonColorClass: 'text-white/50',\n preventDismiss: false,\n });\n\n const emit = defineEmits<{\n /**\n * @deprecated Use the `update:is-open` event instead\n */\n (e: 'update:open', isOpen?: boolean): void;\n (e: 'update:is-open', isOpen?: boolean): void;\n (e: 'dismiss'): void;\n }>();\n\n const slots = useSlots();\n\n const rootRef = ref<HTMLElement>();\n const lastExternalFocusedElement = ref<HTMLElement | null>(null);\n const focusElements = ref<HTMLElement[]>([]);\n const firstFocusElement = ref<HTMLElement>();\n const lastFocusElement = ref<HTMLElement>();\n const initialPageScrollingElementStyle = ref({ height: '', overflow: '' });\n const headerId = uniqueId('modal-header-');\n const hasFooterContent = computed(() => !!slots.actions || !!slots.footer);\n const isModalOpen = computed(() => props.open || props.isOpen);\n const isDrawer = computed(() => props.position === 'left' || props.position === 'right');\n\n let isFocusTrapAttached = false;\n\n function getPageScrollingElement() {\n return (document.scrollingElement || document.body) as HTMLElement;\n }\n\n watch(\n isModalOpen,\n () => {\n if (typeof document === 'undefined') {\n return;\n }\n toggleHelpWidgetLauncher(isModalOpen.value ? 'hide' : 'show');\n\n if (isModalOpen.value) {\n const active = document.activeElement;\n lastExternalFocusedElement.value = active instanceof HTMLElement ? active : null;\n } else {\n if (isFocusTrapAttached) {\n document.removeEventListener('keydown', handleTab);\n isFocusTrapAttached = false;\n }\n\n lastExternalFocusedElement.value?.focus();\n }\n\n if (isModalOpen.value) {\n Object.assign(initialPageScrollingElementStyle.value, {\n height: getPageScrollingElement().style.height,\n overflow: getPageScrollingElement().style.overflow,\n });\n }\n\n Object.assign(getPageScrollingElement().style, {\n overflow: isModalOpen.value ? 'hidden' : initialPageScrollingElementStyle.value.overflow, // Prevents page from scrolling when modal is open\n height: isModalOpen.value ? '100%' : initialPageScrollingElementStyle.value.height, // Ensures the backdrop covers the entire page when modal is open; see https://github.com/LeafLink/stash/pull/713#issuecomment-1184602535\n });\n },\n { immediate: true },\n );\n\n onBeforeUnmount(() => {\n if (typeof document === 'undefined') {\n return;\n }\n toggleHelpWidgetLauncher('show');\n\n // In cases where the watchEffect for isModalOpen isn't triggered while closing/nagivating away from modal, this ensures scrolling returns to normal\n Object.assign(getPageScrollingElement().style, {\n overflow: initialPageScrollingElementStyle.value.overflow,\n height: initialPageScrollingElementStyle.value.height,\n });\n\n // Clear focus trap tab listener\n if (isFocusTrapAttached) {\n document.removeEventListener('keydown', handleTab);\n isFocusTrapAttached = false;\n }\n\n lastExternalFocusedElement.value?.focus();\n });\n\n function dismiss() {\n if (props.preventDismiss) {\n return;\n }\n emit('update:open', false);\n emit('update:is-open', false);\n emit('dismiss');\n }\n\n function handleTab(e: KeyboardEvent) {\n if (e.key === 'Tab') {\n if (e.shiftKey && document.activeElement === firstFocusElement.value) {\n lastFocusElement.value?.focus();\n e.preventDefault();\n } else if (document.activeElement === lastFocusElement.value) {\n firstFocusElement.value?.focus();\n e.preventDefault();\n }\n }\n }\n\n function setupFocusTrap() {\n if (typeof document === 'undefined' || !rootRef.value || !isModalOpen.value) {\n return;\n }\n\n rootRef.value.focus();\n\n focusElements.value = Array.from(rootRef.value.querySelectorAll<HTMLElement>(FOCUS_ELEMENTS_SELECTOR));\n firstFocusElement.value = focusElements.value[0];\n lastFocusElement.value = focusElements.value[focusElements.value.length - 1];\n\n if (!isFocusTrapAttached) {\n document.addEventListener('keydown', handleTab);\n isFocusTrapAttached = true;\n }\n }\n\n // Ensure the Tab key cycles through focusable elements within the modal only while it is open.\n watch(rootRef, () => {\n if (!rootRef.value || !isModalOpen.value) {\n return;\n }\n\n setupFocusTrap();\n });\n\n /**\n * The customer support \"help widget launcher\" covers the action buttons in the Modal when the Modal uses a position value of \"right\" (for drawers).\n */\n function toggleHelpWidgetLauncher(nextState: 'show' | 'hide') {\n if (typeof document === 'undefined') {\n return;\n }\n const launcherElement = document.getElementById('launcher');\n\n if (!launcherElement || !launcherElement.parentElement) {\n return;\n }\n\n launcherElement.parentElement.style.display = nextState === 'show' ? 'block' : 'none';\n }\n</script>\n\n<template>\n <div\n v-if=\"isModalOpen\"\n ref=\"rootRef\"\n class=\"stash-modal fixed inset-0\"\n :class=\"{\n 'invisible z-behind': !isModalOpen,\n 'visible z-modal': isModalOpen,\n 'lg:flex lg:flex-col lg:items-center lg:justify-center': props.position === 'center',\n 'overflow-y-auto': !props.scrollable && !isDrawer,\n 'overflow-y-hidden': isDrawer,\n }\"\n data-test=\"ll-modal\"\n tabindex=\"0\"\n @keydown.esc=\"dismiss\"\n >\n <Backdrop class=\"stash-modal__backdrop\" @click.stop=\"dismiss\" />\n <div\n aria-modal=\"true\"\n role=\"dialog\"\n :aria-labelledby=\"headerId\"\n class=\"stash-modal__dialog relative flex h-screen w-full flex-col lg:shadow-3xl\"\n :class=\"[\n `stash-modal__dialog--size-${props.size}`,\n `stash-modal__dialog--position-${props.position}`,\n {\n 'stash-modal__dialog--is-open': isModalOpen,\n 'stash-modal__dialog--is-drawer': isDrawer,\n 'stash-modal__dialog--is-contrast': props.contrast,\n 'stash-modal__dialog--is-scrollable': props.scrollable,\n 'lg:w-[360px]': props.size === 'narrow',\n 'lg:w-[648px]': props.size === 'medium',\n 'lg:w-[960px]': props.size === 'wide',\n 'lg:my-0 lg:h-auto lg:max-h-[90vh]': props.position === 'center',\n // absolute causing this to break when items in bottom of container get focus\n 'lg:fixed lg:h-screen': isDrawer,\n 'lg:left-0': props.position === 'left',\n 'lg:right-0': props.position === 'right',\n },\n ]\"\n @click.stop\n >\n <header\n v-if=\"!props.hideHeader\"\n data-test=\"stash-modal__header\"\n class=\"stash-modal__header grid h-12 place-items-center bg-purple-500\"\n :class=\"{ 'lg:rounded-t': !isDrawer }\"\n >\n <div class=\"flex place-items-center\">\n <!-- @slot Adds an action to the left side of the header bar. An example usage is a modal with multiple pages and a back button can be inserted here -->\n <slot name=\"headerAction\"></slot>\n </div>\n\n <h3 v-if=\"props.title\" :id=\"headerId\" class=\"m-0 flex-1 leading-6 text-white\">\n {{ props.title }}\n </h3>\n\n <Button\n v-if=\"!props.hideClose\"\n icon\n data-test=\"ll-modal-close\"\n :title=\"t('ll.closeModal')\"\n type=\"button\"\n @click=\"dismiss\"\n >\n <Icon class=\"text-white\" name=\"close\" />\n </Button>\n </header>\n\n <Button\n v-if=\"!props.hideClose && props.hideHeader\"\n class=\"absolute right-0 top-0 z-10\"\n icon\n data-test=\"ll-modal-close\"\n type=\"button\"\n :title=\"t('ll.closeModal')\"\n @click=\"dismiss\"\n >\n <Icon class=\"drop-shadow-md\" name=\"close\" :class=\"[props.closeButtonColorClass]\" />\n </Button>\n\n <div\n v-if=\"!!slots['featured-content']\"\n class=\"stash-modal__featured-content relative\"\n :class=\"{\n 'rounded-t': props.hideHeader,\n }\"\n >\n <slot name=\"featured-content\"></slot>\n </div>\n\n <div\n class=\"stash-modal__body flex-1 overflow-y-auto\"\n :class=\"[\n {\n 'p-3 lg:p-6': !props.disableBodyPadding,\n 'lg:overflow-y-visible': !props.scrollable && !isDrawer,\n 'lg:rounded-b': !hasFooterContent && !isDrawer,\n 'bg-white': !props.contrast,\n 'bg-ice-200': props.contrast,\n },\n ]\"\n data-test=\"stash-modal__body\"\n >\n <slot></slot>\n </div>\n\n <footer\n v-if=\"hasFooterContent\"\n class=\"stash-modal__footer border-t border-ice-500 bg-ice-100 p-3 lg:p-6\"\n :class=\"{ 'lg:rounded-b': !isDrawer }\"\n >\n <!-- @slot Overrides the whole footer section. Used for rendering custom footers with more than 2 actions. If defined, \"actions\" slot will get ignored. -->\n <slot name=\"footer\">\n <div class=\"stash-modal__footer__actions flex flex-col justify-end lg:flex-row\">\n <!-- @slot Modal footer actions, supports rendering up to 2 `<Button>` children -->\n <slot name=\"actions\"></slot>\n </div>\n </slot>\n </footer>\n </div>\n </div>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n :global(:where(.stash-modal) .stash-modal__header) {\n grid-template-columns: 48px 1fr 48px;\n }\n\n /* Prefer gap + column-reverse over child/order selectors so actions can wrap buttons in an inner flex row */\n :global(:where(.stash-modal) .stash-modal__footer__actions) {\n flex-direction: column-reverse;\n gap: --spacing(3);\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n :global(:where(.stash-modal) .stash-modal__footer__actions) {\n flex-direction: row;\n gap: var(--grid-gutter);\n }\n }\n\n :global(:where(.stash-modal) .stash-modal__featured-content > *) {\n border-radius: inherit;\n }\n }\n</style>\n"],"names":["ModalSize","ModalPosition","props","__props","emit","__emit","slots","useSlots","rootRef","ref","lastExternalFocusedElement","focusElements","firstFocusElement","lastFocusElement","initialPageScrollingElementStyle","headerId","uniqueId","hasFooterContent","computed","isModalOpen","isDrawer","isFocusTrapAttached","getPageScrollingElement","watch","toggleHelpWidgetLauncher","active","handleTab","_a","onBeforeUnmount","dismiss","e","_b","setupFocusTrap","FOCUS_ELEMENTS_SELECTOR","nextState","launcherElement","_createElementBlock","_createVNode","Backdrop","_createElementVNode","_unref","_normalizeClass","_hoisted_2","_renderSlot","_ctx","_toDisplayString","_hoisted_3","_createBlock","Button","t","Icon","_hoisted_4"],"mappings":";;;;;;;;AAAO,IAAKA,sBAAAA,OACVA,EAAA,SAAS,UACTA,EAAA,SAAS,UACTA,EAAA,OAAO,QAHGA,IAAAA,KAAA,CAAA,CAAA,GAQAC,sBAAAA,OACVA,EAAA,SAAS,UACTA,EAAA,OAAO,QACPA,EAAA,QAAQ,SAHEA,IAAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;ACkFV,UAAMC,IAAQC,GAeRC,IAAOC,GASPC,IAAQC,EAAA,GAERC,IAAUC,EAAA,GACVC,IAA6BD,EAAwB,IAAI,GACzDE,IAAgBF,EAAmB,EAAE,GACrCG,IAAoBH,EAAA,GACpBI,IAAmBJ,EAAA,GACnBK,IAAmCL,EAAI,EAAE,QAAQ,IAAI,UAAU,IAAI,GACnEM,IAAWC,EAAS,eAAe,GACnCC,IAAmBC,EAAS,MAAM,CAAC,CAACZ,EAAM,WAAW,CAAC,CAACA,EAAM,MAAM,GACnEa,IAAcD,EAAS,MAAMhB,EAAM,QAAQA,EAAM,MAAM,GACvDkB,IAAWF,EAAS,MAAMhB,EAAM,aAAa,UAAUA,EAAM,aAAa,OAAO;AAEvF,QAAImB,IAAsB;AAE1B,aAASC,IAA0B;AACjC,aAAQ,SAAS,oBAAoB,SAAS;AAAA,IAChD;AAEA,IAAAC;AAAA,MACEJ;AAAA,MACA,MAAM;;AACJ,YAAI,SAAO,WAAa,MAKxB;AAAA,cAFAK,EAAyBL,EAAY,QAAQ,SAAS,MAAM,GAExDA,EAAY,OAAO;AACrB,kBAAMM,IAAS,SAAS;AACxB,YAAAf,EAA2B,QAAQe,aAAkB,cAAcA,IAAS;AAAA,UAC9E;AACE,YAAIJ,MACF,SAAS,oBAAoB,WAAWK,CAAS,GACjDL,IAAsB,MAGxBM,IAAAjB,EAA2B,UAA3B,QAAAiB,EAAkC;AAGpC,UAAIR,EAAY,SACd,OAAO,OAAOL,EAAiC,OAAO;AAAA,YACpD,QAAQQ,IAA0B,MAAM;AAAA,YACxC,UAAUA,EAAA,EAA0B,MAAM;AAAA,UAAA,CAC3C,GAGH,OAAO,OAAOA,EAAA,EAA0B,OAAO;AAAA,YAC7C,UAAUH,EAAY,QAAQ,WAAWL,EAAiC,MAAM;AAAA;AAAA,YAChF,QAAQK,EAAY,QAAQ,SAASL,EAAiC,MAAM;AAAA;AAAA,UAAA,CAC7E;AAAA;AAAA,MACH;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK,GAGpBc,EAAgB,MAAM;;AACpB,MAAI,OAAO,WAAa,QAGxBJ,EAAyB,MAAM,GAG/B,OAAO,OAAOF,EAAA,EAA0B,OAAO;AAAA,QAC7C,UAAUR,EAAiC,MAAM;AAAA,QACjD,QAAQA,EAAiC,MAAM;AAAA,MAAA,CAChD,GAGGO,MACF,SAAS,oBAAoB,WAAWK,CAAS,GACjDL,IAAsB,MAGxBM,IAAAjB,EAA2B,UAA3B,QAAAiB,EAAkC;AAAA,IACpC,CAAC;AAED,aAASE,IAAU;AACjB,MAAI3B,EAAM,mBAGVE,EAAK,eAAe,EAAK,GACzBA,EAAK,kBAAkB,EAAK,GAC5BA,EAAK,SAAS;AAAA,IAChB;AAEA,aAASsB,EAAUI,GAAkB;;AACnC,MAAIA,EAAE,QAAQ,UACRA,EAAE,YAAY,SAAS,kBAAkBlB,EAAkB,UAC7De,IAAAd,EAAiB,UAAjB,QAAAc,EAAwB,SACxBG,EAAE,eAAA,KACO,SAAS,kBAAkBjB,EAAiB,WACrDkB,IAAAnB,EAAkB,UAAlB,QAAAmB,EAAyB,SACzBD,EAAE,eAAA;AAAA,IAGR;AAEA,aAASE,IAAiB;AACxB,MAAI,OAAO,WAAa,OAAe,CAACxB,EAAQ,SAAS,CAACW,EAAY,UAItEX,EAAQ,MAAM,MAAA,GAEdG,EAAc,QAAQ,MAAM,KAAKH,EAAQ,MAAM,iBAA8ByB,CAAuB,CAAC,GACrGrB,EAAkB,QAAQD,EAAc,MAAM,CAAC,GAC/CE,EAAiB,QAAQF,EAAc,MAAMA,EAAc,MAAM,SAAS,CAAC,GAEtEU,MACH,SAAS,iBAAiB,WAAWK,CAAS,GAC9CL,IAAsB;AAAA,IAE1B;AAGA,IAAAE,EAAMf,GAAS,MAAM;AACnB,MAAI,CAACA,EAAQ,SAAS,CAACW,EAAY,SAInCa,EAAA;AAAA,IACF,CAAC;AAKD,aAASR,EAAyBU,GAA4B;AAC5D,UAAI,OAAO,WAAa;AACtB;AAEF,YAAMC,IAAkB,SAAS,eAAe,UAAU;AAE1D,MAAI,CAACA,KAAmB,CAACA,EAAgB,kBAIzCA,EAAgB,cAAc,MAAM,UAAUD,MAAc,SAAS,UAAU;AAAA,IACjF;qBAKQf,EAAA,cADRiB,EAwHM,OAAA;AAAA;eAtHA;AAAA,MAAJ,KAAI5B;AAAA,MACJ,UAAM,6BAA2B;AAAA,+BACMW,EAAA;AAAA,2BAAsCA,EAAA;AAAA,QAA4E,yDAAAjB,EAAM,aAAQ;AAAA,4BAAyCA,EAAM,cAAU,CAAKkB,EAAA;AAAA,6BAAqCA,EAAA;AAAA,MAAA;MAO1Q,aAAU;AAAA,MACV,UAAS;AAAA,MACR,aAAaS,GAAO,CAAA,KAAA,CAAA;AAAA,IAAA;MAErBQ,EAAgEC,GAAA;AAAA,QAAtD,OAAM;AAAA,QAAyB,WAAYT,GAAO,CAAA,MAAA,CAAA;AAAA,MAAA;MAC5DU,EAuGM,OAAA;AAAA,QAtGJ,cAAW;AAAA,QACX,MAAK;AAAA,QACJ,mBAAiBC,EAAAzB,CAAA;AAAA,QAClB,UAAM,4EAA0E;AAAA,UACjC,6BAAAb,EAAM,IAAI;AAAA,UAA6C,iCAAAA,EAAM,QAAQ;AAAA;4CAAwDiB,EAAA;AAAA,8CAAyDC,EAAA;AAAA,YAAwD,oCAAAlB,EAAM;AAAA,YAA0D,sCAAAA,EAAM;AAAA,YAAsC,gBAAAA,EAAM,SAAI;AAAA,YAAyC,gBAAAA,EAAM,SAAI;AAAA,YAAyC,gBAAAA,EAAM,SAAI;AAAA,YAA4D,qCAAAA,EAAM,aAAQ;AAAA;AAAA,oCAAyIkB,EAAA;AAAA,YAAiC,aAAAlB,EAAM,aAAQ;AAAA,YAAqC,cAAAA,EAAM,aAAQ;AAAA,UAAA;AAAA;QAkB7yB,2BAAD,MAAA;AAAA,QAAA,GAAW,CAAA,MAAA,CAAA;AAAA,MAAA;QAGFA,EAAM,+BADfkC,EAyBS,UAAA;AAAA;UAvBP,aAAU;AAAA,UACV,OAAKK,EAAA,CAAC,kEAAgE,EAAA,gBAAA,CAC3CrB,EAAA,OAAQ,CAAA;AAAA,QAAA;UAEnCmB,EAGM,OAHNG,GAGM;AAAA,YADJC,EAAiCC,EAAA,QAAA,cAAA;AAAA,UAAA;UAGzB1C,EAAM,cAAhBkC,EAEK,MAAA;AAAA;YAFmB,IAAII,EAAAzB,CAAA;AAAA,YAAU,OAAM;AAAA,UAAA,GACvC8B,EAAA3C,EAAM,KAAK,GAAA,GAAA4C,EAAA;UAIP5C,EAAM,8BADf6C,EASSC,GAAA;AAAA;YAPP,MAAA;AAAA,YACA,aAAU;AAAA,YACT,OAAOR,EAAAS,CAAA,EAAC,eAAA;AAAA,YACT,MAAK;AAAA,YACJ,SAAOpB;AAAA,UAAA;uBAER,MAAwC;AAAA,cAAxCQ,EAAwCa,GAAA;AAAA,gBAAlC,OAAM;AAAA,gBAAa,MAAK;AAAA,cAAA;;;;;QAKzB,CAAAhD,EAAM,aAAaA,EAAM,mBADlC6C,EAUSC,GAAA;AAAA;UARP,OAAM;AAAA,UACN,MAAA;AAAA,UACA,aAAU;AAAA,UACV,MAAK;AAAA,UACJ,OAAOR,EAAAS,CAAA,EAAC,eAAA;AAAA,UACR,SAAOpB;AAAA,QAAA;qBAER,MAAmF;AAAA,YAAnFQ,EAAmFa,GAAA;AAAA,cAA7E,OAAKT,EAAA,CAAC,kBAAgB,CAAuBvC,EAAM,qBAAqB,CAAA,CAAA;AAAA,cAAjD,MAAK;AAAA,YAAA;;;;QAI1BsC,EAAAlC,CAAA,EAAK,kBAAA,UADf8B,EAQM,OAAA;AAAA;UANJ,UAAM,0CAAwC;AAAA,YACb,aAAAlC,EAAM;AAAA,UAAA;;UAIvCyC,EAAqCC,EAAA,QAAA,kBAAA;AAAA,QAAA;QAGvCL,EAcM,OAAA;AAAA,UAbJ,UAAM,4CAA0C;AAAA;cACC,cAAA,CAAArC,EAAM;AAAA,wCAA0DA,EAAM,cAAU,CAAKkB,EAAA;AAAA,cAAuC,gBAAA,CAAAH,EAAA,UAAqBG,EAAA;AAAA,cAAmC,YAAA,CAAAlB,EAAM;AAAA,cAAoC,cAAAA,EAAM;AAAA,YAAA;AAAA;UASrR,aAAU;AAAA,QAAA;UAEVyC,EAAaC,EAAA,QAAA,SAAA;AAAA,QAAA;QAIP3B,EAAA,cADRmB,EAYS,UAAA;AAAA;UAVP,OAAKK,EAAA,CAAC,qEAAmE,EAAA,gBAAA,CAC9CrB,EAAA,OAAQ,CAAA;AAAA,QAAA;UAGnCuB,EAKOC,wBALP,MAKO;AAAA,YAJLL,EAGM,OAHNY,IAGM;AAAA,cADJR,EAA4BC,EAAA,QAAA,SAAA;AAAA,YAAA;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"Modal.js","sources":["../src/components/Modal/Modal.types.ts","../src/components/Modal/Modal.vue"],"sourcesContent":["export enum ModalSize {\n Narrow = 'narrow',\n Medium = 'medium',\n Wide = 'wide',\n}\n\nexport type ModalSizes = `${ModalSize}`;\n\nexport enum ModalPosition {\n Center = 'center',\n Left = 'left',\n Right = 'right',\n}\n\nexport type ModalPositions = `${ModalPosition}`;\n","<script lang=\"ts\">\n import { ModalPositions, ModalSizes } from './Modal.types';\n\n export * from './Modal.types';\n\n export interface ModalProps {\n /**\n * Hides the \"close\" button\n */\n hideClose?: boolean;\n\n /**\n * Opens the modal when truthy; hides the modal when falsy.\n * @deprecated Use `isOpen` instead\n */\n open?: boolean;\n\n /**\n * Opens the modal when truthy; hides the modal when falsy.\n */\n isOpen?: boolean;\n\n /**\n * Use v-model:is-open or :is-open instead of :model-value and v-model.\n * @deprecated\n */\n modelValue?: boolean;\n\n /**\n * Sets a preset max-width on the modal.\n * Options: default (648px), narrow (360px), wide (960px)\n */\n size?: ModalSizes;\n\n /**\n * Should the modal be scrollable within the content area. This prop is treated as `true` when the `position` prop is set to \"left\" or \"right\".\n */\n scrollable?: boolean;\n\n /**\n * Gives the modal body have a light gray background\n */\n contrast?: boolean;\n\n /**\n * Text to display in the modal header\n */\n title?: string;\n\n /**\n * Disables the default padding in the modal body.\n */\n disableBodyPadding?: boolean;\n\n /**\n * The position on the screen to display the modal.\n */\n position?: ModalPositions;\n\n /**\n * Hide the header. Typically used with the featuredContent slot to display a graphic and create a \"promo\" modal.\n */\n hideHeader?: boolean;\n\n /**\n * Add classes to the close button. This can be used with the hideHeader prop and featuredContent slot to\n * accommodate images with different color backgrounds.\n */\n closeButtonColorClass?: string;\n\n /**\n * Prevents the modal from being dismissed by clicking the backdrop or pressing the escape key.\n * Example: There are in-flight api requests and you do not want the modal to close until they are done.\n */\n preventDismiss?: boolean;\n }\n</script>\n\n<script setup lang=\"ts\">\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, onBeforeUnmount, ref, useSlots, watch } from 'vue';\n\n import { FOCUS_ELEMENTS_SELECTOR } from '../../constants';\n import { t } from '../../locale';\n import Backdrop from '../Backdrop/Backdrop.vue';\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({ name: 'll-modal' });\n\n const props = withDefaults(defineProps<ModalProps>(), {\n hideClose: false,\n open: false,\n isOpen: false,\n modelValue: false,\n size: 'medium',\n scrollable: false,\n contrast: false,\n title: '',\n position: 'center',\n hideHeader: false,\n closeButtonColorClass: 'text-white/50',\n preventDismiss: false,\n });\n\n const emit = defineEmits<{\n /**\n * @deprecated Use the `update:is-open` event instead\n */\n (e: 'update:open', isOpen?: boolean): void;\n (e: 'update:is-open', isOpen?: boolean): void;\n (e: 'dismiss'): void;\n }>();\n\n const slots = useSlots();\n\n const rootRef = ref<HTMLElement>();\n const lastExternalFocusedElement = ref<HTMLElement | null>(null);\n const focusElements = ref<HTMLElement[]>([]);\n const firstFocusElement = ref<HTMLElement>();\n const lastFocusElement = ref<HTMLElement>();\n const initialPageScrollingElementStyle = ref({ height: '', overflow: '' });\n const headerId = uniqueId('modal-header-');\n const hasFooterContent = computed(() => !!slots.actions || !!slots.footer);\n const isModalOpen = computed(() => props.open || props.isOpen);\n const isDrawer = computed(() => props.position === 'left' || props.position === 'right');\n\n let isFocusTrapAttached = false;\n\n function getPageScrollingElement() {\n return (document.scrollingElement || document.body) as HTMLElement;\n }\n\n watch(\n isModalOpen,\n () => {\n if (typeof document === 'undefined') {\n return;\n }\n toggleHelpWidgetLauncher(isModalOpen.value ? 'hide' : 'show');\n\n if (isModalOpen.value) {\n const active = document.activeElement;\n lastExternalFocusedElement.value = active instanceof HTMLElement ? active : null;\n } else {\n if (isFocusTrapAttached) {\n document.removeEventListener('keydown', handleTab);\n isFocusTrapAttached = false;\n }\n\n lastExternalFocusedElement.value?.focus();\n }\n\n if (isModalOpen.value) {\n Object.assign(initialPageScrollingElementStyle.value, {\n height: getPageScrollingElement().style.height,\n overflow: getPageScrollingElement().style.overflow,\n });\n }\n\n Object.assign(getPageScrollingElement().style, {\n overflow: isModalOpen.value ? 'hidden' : initialPageScrollingElementStyle.value.overflow, // Prevents page from scrolling when modal is open\n height: isModalOpen.value ? '100%' : initialPageScrollingElementStyle.value.height, // Ensures the backdrop covers the entire page when modal is open; see https://github.com/LeafLink/stash/pull/713#issuecomment-1184602535\n });\n },\n { immediate: true },\n );\n\n onBeforeUnmount(() => {\n if (typeof document === 'undefined') {\n return;\n }\n toggleHelpWidgetLauncher('show');\n\n // In cases where the watchEffect for isModalOpen isn't triggered while closing/nagivating away from modal, this ensures scrolling returns to normal\n Object.assign(getPageScrollingElement().style, {\n overflow: initialPageScrollingElementStyle.value.overflow,\n height: initialPageScrollingElementStyle.value.height,\n });\n\n // Clear focus trap tab listener\n if (isFocusTrapAttached) {\n document.removeEventListener('keydown', handleTab);\n isFocusTrapAttached = false;\n }\n\n lastExternalFocusedElement.value?.focus();\n });\n\n function dismiss() {\n if (props.preventDismiss) {\n return;\n }\n emit('update:open', false);\n emit('update:is-open', false);\n emit('dismiss');\n }\n\n function handleTab(e: KeyboardEvent) {\n if (e.key === 'Tab') {\n if (e.shiftKey && document.activeElement === firstFocusElement.value) {\n lastFocusElement.value?.focus();\n e.preventDefault();\n } else if (document.activeElement === lastFocusElement.value) {\n firstFocusElement.value?.focus();\n e.preventDefault();\n }\n }\n }\n\n function setupFocusTrap() {\n if (typeof document === 'undefined' || !rootRef.value || !isModalOpen.value) {\n return;\n }\n\n rootRef.value.focus();\n\n focusElements.value = Array.from(rootRef.value.querySelectorAll<HTMLElement>(FOCUS_ELEMENTS_SELECTOR));\n firstFocusElement.value = focusElements.value[0];\n lastFocusElement.value = focusElements.value[focusElements.value.length - 1];\n\n if (!isFocusTrapAttached) {\n document.addEventListener('keydown', handleTab);\n isFocusTrapAttached = true;\n }\n }\n\n // Ensure the Tab key cycles through focusable elements within the modal only while it is open.\n watch(rootRef, () => {\n if (!rootRef.value || !isModalOpen.value) {\n return;\n }\n\n setupFocusTrap();\n });\n\n /**\n * The customer support \"help widget launcher\" covers the action buttons in the Modal when the Modal uses a position value of \"right\" (for drawers).\n */\n function toggleHelpWidgetLauncher(nextState: 'show' | 'hide') {\n if (typeof document === 'undefined') {\n return;\n }\n const launcherElement = document.getElementById('launcher');\n\n if (!launcherElement || !launcherElement.parentElement) {\n return;\n }\n\n launcherElement.parentElement.style.display = nextState === 'show' ? 'block' : 'none';\n }\n</script>\n\n<template>\n <div\n v-if=\"isModalOpen\"\n ref=\"rootRef\"\n class=\"stash-modal fixed inset-0\"\n :class=\"{\n 'invisible z-behind': !isModalOpen,\n 'visible z-modal': isModalOpen,\n 'lg:flex lg:flex-col lg:items-center lg:justify-center': props.position === 'center',\n 'overflow-y-auto': !props.scrollable && !isDrawer,\n 'overflow-y-hidden': isDrawer,\n }\"\n data-test=\"ll-modal\"\n tabindex=\"0\"\n @keydown.esc=\"dismiss\"\n >\n <Backdrop class=\"stash-modal__backdrop\" @click.stop=\"dismiss\" />\n <div\n aria-modal=\"true\"\n role=\"dialog\"\n :aria-labelledby=\"headerId\"\n class=\"stash-modal__dialog relative flex h-screen w-full flex-col lg:shadow-3xl\"\n :class=\"[\n `stash-modal__dialog--size-${props.size}`,\n `stash-modal__dialog--position-${props.position}`,\n {\n 'stash-modal__dialog--is-open': isModalOpen,\n 'stash-modal__dialog--is-drawer': isDrawer,\n 'stash-modal__dialog--is-contrast': props.contrast,\n 'stash-modal__dialog--is-scrollable': props.scrollable,\n 'lg:w-[360px]': props.size === 'narrow',\n 'lg:w-[648px]': props.size === 'medium',\n 'lg:w-[960px]': props.size === 'wide',\n 'lg:my-0 lg:h-auto lg:max-h-[90vh]': props.position === 'center',\n // absolute causing this to break when items in bottom of container get focus\n 'lg:fixed lg:h-screen': isDrawer,\n 'lg:left-0': props.position === 'left',\n 'lg:right-0': props.position === 'right',\n },\n ]\"\n @click.stop\n >\n <header\n v-if=\"!props.hideHeader\"\n data-test=\"stash-modal__header\"\n class=\"stash-modal__header grid h-12 place-items-center bg-purple-500\"\n :class=\"{ 'lg:rounded-t': !isDrawer }\"\n >\n <div class=\"flex place-items-center\">\n <!-- @slot Adds an action to the left side of the header bar. An example usage is a modal with multiple pages and a back button can be inserted here -->\n <slot name=\"headerAction\"></slot>\n </div>\n\n <h3 v-if=\"props.title\" :id=\"headerId\" class=\"m-0 flex-1 leading-6 text-white\">\n {{ props.title }}\n </h3>\n\n <Button\n v-if=\"!props.hideClose\"\n icon\n data-test=\"ll-modal-close\"\n :title=\"t('ll.closeModal')\"\n type=\"button\"\n @click=\"dismiss\"\n >\n <Icon class=\"text-white\" name=\"close\" />\n </Button>\n </header>\n\n <Button\n v-if=\"!props.hideClose && props.hideHeader\"\n class=\"absolute right-0 top-0 z-10\"\n icon\n data-test=\"ll-modal-close\"\n type=\"button\"\n :title=\"t('ll.closeModal')\"\n @click=\"dismiss\"\n >\n <Icon class=\"drop-shadow-md\" name=\"close\" :class=\"[props.closeButtonColorClass]\" />\n </Button>\n\n <div\n v-if=\"!!slots['featured-content']\"\n class=\"stash-modal__featured-content relative\"\n :class=\"{\n 'rounded-t': props.hideHeader,\n }\"\n >\n <slot name=\"featured-content\"></slot>\n </div>\n\n <div\n class=\"stash-modal__body flex-1 overflow-y-auto\"\n :class=\"[\n {\n 'p-3 lg:p-6': !props.disableBodyPadding,\n 'lg:overflow-y-visible': !props.scrollable && !isDrawer,\n 'lg:rounded-b': !hasFooterContent && !isDrawer,\n 'bg-white': !props.contrast,\n 'bg-ice-200': props.contrast,\n },\n ]\"\n data-test=\"stash-modal__body\"\n >\n <slot></slot>\n </div>\n\n <footer\n v-if=\"hasFooterContent\"\n class=\"stash-modal__footer border-t border-ice-500 bg-ice-100 p-3 lg:p-6\"\n :class=\"{ 'lg:rounded-b': !isDrawer }\"\n >\n <!-- @slot Overrides the whole footer section. Used for rendering custom footers with more than 2 actions. If defined, \"actions\" slot will get ignored. -->\n <slot name=\"footer\">\n <div class=\"stash-modal__footer__actions flex justify-end\">\n <!-- @slot Modal footer actions, supports rendering up to 2 `<Button>` children -->\n <slot name=\"actions\"></slot>\n </div>\n </slot>\n </footer>\n </div>\n </div>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n :global(:where(.stash-modal) .stash-modal__header) {\n grid-template-columns: 48px 1fr 48px;\n }\n\n /* Direction lives here (not Tailwind flex-col / lg:flex-row on the template) so utilities don’t fight column-reverse */\n :global(:where(.stash-modal) .stash-modal__footer__actions) {\n flex-direction: column-reverse;\n gap: --spacing(3);\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n :global(:where(.stash-modal) .stash-modal__footer__actions) {\n flex-direction: row;\n gap: var(--grid-gutter);\n }\n }\n\n :global(:where(.stash-modal) .stash-modal__featured-content > *) {\n border-radius: inherit;\n }\n }\n</style>\n"],"names":["ModalSize","ModalPosition","props","__props","emit","__emit","slots","useSlots","rootRef","ref","lastExternalFocusedElement","focusElements","firstFocusElement","lastFocusElement","initialPageScrollingElementStyle","headerId","uniqueId","hasFooterContent","computed","isModalOpen","isDrawer","isFocusTrapAttached","getPageScrollingElement","watch","toggleHelpWidgetLauncher","active","handleTab","_a","onBeforeUnmount","dismiss","e","_b","setupFocusTrap","FOCUS_ELEMENTS_SELECTOR","nextState","launcherElement","_createElementBlock","_createVNode","Backdrop","_createElementVNode","_unref","_normalizeClass","_hoisted_2","_renderSlot","_ctx","_toDisplayString","_hoisted_3","_createBlock","Button","t","Icon","_hoisted_4"],"mappings":"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"}
|
package/dist/Table.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { d as
|
|
3
|
-
import
|
|
1
|
+
import { defineComponent as te, useCssModule as le, inject as $, computed as l, useTemplateRef as O, ref as x, provide as ae, watchEffect as se, createElementBlock as p, openBlock as u, createElementVNode as f, createCommentVNode as E, normalizeStyle as r, normalizeClass as i, unref as b, renderSlot as C, createBlock as I, withCtx as h, createVNode as n, Fragment as N } from "vue";
|
|
2
|
+
import { d as oe, e as A, f as re } from "./index-t9tXBnql.js";
|
|
3
|
+
import z from "./Button.js";
|
|
4
4
|
import "lodash-es/cloneDeep";
|
|
5
5
|
import { M as D } from "./Module.keys-DcqBbvvT.js";
|
|
6
6
|
import "lodash-es/get";
|
|
7
|
-
import
|
|
8
|
-
import { D as
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
7
|
+
import M from "./Icon.js";
|
|
8
|
+
import { D as P } from "./DataView.keys-aSOnA4AD.js";
|
|
9
|
+
import ne from "./EmptyState.js";
|
|
10
|
+
import ie from "./Loading.js";
|
|
11
|
+
import j from "./TableCell.js";
|
|
12
12
|
import J from "./TableRow.js";
|
|
13
|
-
import { T as
|
|
14
|
-
import { S as
|
|
15
|
-
import { _ as
|
|
16
|
-
var
|
|
17
|
-
const
|
|
13
|
+
import { T as de } from "./Table.keys-LHQf6FEH.js";
|
|
14
|
+
import { S as ce } from "./misc-CHQs-G03.js";
|
|
15
|
+
import { _ as ue } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
16
|
+
var fe = /* @__PURE__ */ ((o) => (o.Scroll = "scroll", o.Stack = "stack", o))(fe || {}), he = /* @__PURE__ */ ((o) => (o.None = "none", o.Rounded = "rounded", o.RoundedBottom = "rounded-bottom", o))(he || {});
|
|
17
|
+
const be = { class: "stash-table-wrapper relative" }, ve = ["aria-busy"], pe = /* @__PURE__ */ te({
|
|
18
18
|
__name: "Table",
|
|
19
19
|
props: {
|
|
20
20
|
density: { default: void 0 },
|
|
@@ -28,110 +28,118 @@ const de = { class: "stash-table-wrapper relative" }, ue = ["aria-busy"], fe = /
|
|
|
28
28
|
isSelectable: { type: Boolean, default: !1 },
|
|
29
29
|
layout: { default: "scroll" },
|
|
30
30
|
radius: { default: "rounded" },
|
|
31
|
-
stickyHeader: { default: void 0 }
|
|
31
|
+
stickyHeader: { default: void 0 },
|
|
32
|
+
pinnedLeftWidth: { default: 0 },
|
|
33
|
+
pinnedRightWidth: { default: 0 },
|
|
34
|
+
tableMinWidth: { default: void 0 }
|
|
32
35
|
},
|
|
33
36
|
setup(o) {
|
|
34
|
-
const e = o, m =
|
|
35
|
-
density:
|
|
36
|
-
variant:
|
|
37
|
-
isEmpty:
|
|
38
|
-
isLoading:
|
|
39
|
-
isSelectable:
|
|
40
|
-
} =
|
|
37
|
+
const e = o, m = le(), {
|
|
38
|
+
density: V,
|
|
39
|
+
variant: y,
|
|
40
|
+
isEmpty: v,
|
|
41
|
+
isLoading: d,
|
|
42
|
+
isSelectable: L
|
|
43
|
+
} = $(P.key, P.defaults), { variant: g } = $(D.key, D.defaults), R = l(() => (g == null ? void 0 : g.value) === "table" || y.value === "table" ? "rounded-bottom" : e.radius), s = l(() => e.stickyHeader ? "scroll" : e.layout), X = l(() => s.value === "scroll" && y.value === "table"), F = l(() => {
|
|
41
44
|
var t, a;
|
|
42
45
|
return !!((t = e.stickyHeader) != null && t.maxHeight && ((a = e.stickyHeader) == null ? void 0 : a.listLength) > 3);
|
|
43
|
-
}),
|
|
46
|
+
}), U = l(() => {
|
|
44
47
|
var t;
|
|
45
48
|
return {
|
|
46
|
-
maxHeight:
|
|
49
|
+
maxHeight: F.value ? (t = e.stickyHeader) == null ? void 0 : t.maxHeight : ""
|
|
47
50
|
};
|
|
48
|
-
}), w = l(() => !!(e.isLoading ||
|
|
49
|
-
function
|
|
51
|
+
}), w = l(() => !!(e.isLoading || d != null && d.value)), c = O("scrollContainerRef"), T = O("tableRef"), W = x(!1), _ = x(0), S = x(0), { arrivedState: B, measure: q } = oe(c, { behavior: "smooth" });
|
|
52
|
+
function k() {
|
|
50
53
|
const t = c.value;
|
|
51
|
-
!t || s.value !== "scroll" || (
|
|
54
|
+
!t || s.value !== "scroll" || (W.value = t.scrollWidth > t.clientWidth, _.value = t.offsetWidth - t.clientWidth, S.value = t.offsetHeight - t.clientHeight, q());
|
|
52
55
|
}
|
|
53
|
-
|
|
56
|
+
A(c, k), A(T, k), re(
|
|
54
57
|
c,
|
|
55
58
|
(t) => {
|
|
56
59
|
var a;
|
|
57
|
-
(a = t[0]) != null && a.isIntersecting &&
|
|
60
|
+
(a = t[0]) != null && a.isIntersecting && k();
|
|
58
61
|
},
|
|
59
62
|
{ threshold: 0.01 }
|
|
60
63
|
);
|
|
61
|
-
const
|
|
62
|
-
function
|
|
64
|
+
const G = l(() => !B.left), K = l(() => !B.right), Q = l(() => s.value === "scroll" && W.value);
|
|
65
|
+
function H(t) {
|
|
63
66
|
var a;
|
|
64
67
|
(a = c.value) == null || a.scrollBy({ left: t, behavior: "smooth" });
|
|
65
68
|
}
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
const Y = l(() => (e.pinnedLeftWidth ?? 0) > 0 || (e.pinnedRightWidth ?? 0) > 0), Z = l(() => {
|
|
70
|
+
const t = {};
|
|
71
|
+
return e.tableMinWidth != null && (t.minWidth = `${e.tableMinWidth}px`), Y.value && (t.borderSpacing = "0"), Object.keys(t).length ? t : void 0;
|
|
72
|
+
});
|
|
73
|
+
return ae(de.key, {
|
|
74
|
+
density: l(() => e.density || V.value || ce.Comfortable),
|
|
68
75
|
hasCustomExpandToggle: l(() => e.hasCustomExpandToggle),
|
|
69
76
|
hasActions: l(() => e.hasActions),
|
|
70
77
|
isSchemaDriven: l(() => e.isSchemaDriven),
|
|
71
78
|
isExpandable: l(() => e.isExpandable),
|
|
72
79
|
isSelectable: l(
|
|
73
|
-
() => e.isSelectable && !e.isLoading && !(
|
|
80
|
+
() => e.isSelectable && !e.isLoading && !(d != null && d.value) && !e.isEmpty && !(v != null && v.value)
|
|
74
81
|
),
|
|
75
82
|
isLoading: w,
|
|
76
83
|
layout: s
|
|
77
|
-
}),
|
|
78
|
-
|
|
79
|
-
}), (t, a) => (
|
|
80
|
-
|
|
84
|
+
}), se(() => {
|
|
85
|
+
L && (L.value = e.isSelectable);
|
|
86
|
+
}), (t, a) => (u(), p("div", be, [
|
|
87
|
+
f("div", {
|
|
81
88
|
ref_key: "scrollContainerRef",
|
|
82
89
|
ref: c,
|
|
83
|
-
class:
|
|
84
|
-
{ rounded:
|
|
85
|
-
{ "rounded-b":
|
|
86
|
-
{ "border-t border-ice-200": b(
|
|
90
|
+
class: i(["stash-table relative", [
|
|
91
|
+
{ rounded: R.value === "rounded" },
|
|
92
|
+
{ "rounded-b": R.value === "rounded-bottom" },
|
|
93
|
+
{ "border-t border-ice-200": b(y) === "table" },
|
|
87
94
|
{ "overflow-auto scroll-smooth": s.value === "scroll" },
|
|
88
|
-
{ shadow:
|
|
95
|
+
{ shadow: X.value },
|
|
89
96
|
{
|
|
90
97
|
"overflow-visible lg:overflow-auto lg:shadow": s.value === "stack"
|
|
91
98
|
}
|
|
92
99
|
]]),
|
|
93
100
|
"data-test": "stash-table",
|
|
94
101
|
"aria-busy": w.value,
|
|
95
|
-
style:
|
|
102
|
+
style: r(U.value)
|
|
96
103
|
}, [
|
|
97
|
-
|
|
104
|
+
f("table", {
|
|
98
105
|
ref_key: "tableRef",
|
|
99
|
-
ref:
|
|
100
|
-
class: "relative w-full border-separate"
|
|
106
|
+
ref: T,
|
|
107
|
+
class: "relative w-full border-separate",
|
|
108
|
+
style: r(Z.value)
|
|
101
109
|
}, [
|
|
102
|
-
|
|
103
|
-
class:
|
|
110
|
+
f("thead", {
|
|
111
|
+
class: i(["border-b border-ice-200", { "hidden lg:table-header-group": s.value === "stack" }])
|
|
104
112
|
}, [
|
|
105
|
-
|
|
113
|
+
C(t.$slots, "head")
|
|
106
114
|
], 2),
|
|
107
|
-
|
|
108
|
-
w.value ? (
|
|
109
|
-
default:
|
|
110
|
-
|
|
115
|
+
f("tbody", null, [
|
|
116
|
+
w.value ? (u(), I(J, { key: 0 }, {
|
|
117
|
+
default: h(() => [
|
|
118
|
+
n(j, {
|
|
111
119
|
colspan: "100%",
|
|
112
|
-
class:
|
|
120
|
+
class: i({ "relative! col-span-12": s.value === "stack" })
|
|
113
121
|
}, {
|
|
114
|
-
default:
|
|
115
|
-
|
|
116
|
-
style:
|
|
122
|
+
default: h(() => [
|
|
123
|
+
n(ie, {
|
|
124
|
+
style: r([s.value === "scroll" ? { "max-width": "100vw" } : {}])
|
|
117
125
|
}, null, 8, ["style"])
|
|
118
126
|
]),
|
|
119
127
|
_: 1
|
|
120
128
|
}, 8, ["class"])
|
|
121
129
|
]),
|
|
122
130
|
_: 1
|
|
123
|
-
})) : e.isEmpty || b(
|
|
124
|
-
default:
|
|
125
|
-
|
|
131
|
+
})) : e.isEmpty || b(v) ? (u(), I(J, { key: 1 }, {
|
|
132
|
+
default: h(() => [
|
|
133
|
+
n(j, {
|
|
126
134
|
colspan: "100%",
|
|
127
|
-
class:
|
|
135
|
+
class: i({ "relative! col-span-12": s.value === "stack" })
|
|
128
136
|
}, {
|
|
129
|
-
default:
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
default: h(() => [
|
|
138
|
+
C(t.$slots, "empty", {}, () => [
|
|
139
|
+
n(ne, {
|
|
132
140
|
class: "w-full bg-white",
|
|
133
141
|
text: e.emptyStateText,
|
|
134
|
-
style:
|
|
142
|
+
style: r([s.value === "scroll" ? { "max-width": "100vw" } : {}])
|
|
135
143
|
}, null, 8, ["text", "style"])
|
|
136
144
|
])
|
|
137
145
|
]),
|
|
@@ -139,69 +147,76 @@ const de = { class: "stash-table-wrapper relative" }, ue = ["aria-busy"], fe = /
|
|
|
139
147
|
}, 8, ["class"])
|
|
140
148
|
]),
|
|
141
149
|
_: 3
|
|
142
|
-
})) :
|
|
150
|
+
})) : C(t.$slots, "body", { key: 2 })
|
|
143
151
|
])
|
|
144
|
-
],
|
|
145
|
-
], 14,
|
|
146
|
-
|
|
152
|
+
], 4)
|
|
153
|
+
], 14, ve),
|
|
154
|
+
Q.value ? (u(), p("div", {
|
|
147
155
|
key: 0,
|
|
148
|
-
class:
|
|
156
|
+
class: i([b(m)["stash-table-scroll-overlay"], "pointer-events-none absolute inset-0 flex items-center justify-between z-2"])
|
|
149
157
|
}, [
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
class:
|
|
158
|
+
G.value ? (u(), p(N, { key: 0 }, [
|
|
159
|
+
f("div", {
|
|
160
|
+
class: i([b(m)["stash-table-scroll-shadow-left"], "stash-table-scroll-shadow border-l border-ice-100 absolute top-0 w-4"]),
|
|
161
|
+
style: r({ left: `${e.pinnedLeftWidth}px`, bottom: `${S.value}px` }),
|
|
153
162
|
"data-test": "stash-table|scroll-shadow-left"
|
|
154
|
-
}, null,
|
|
155
|
-
|
|
156
|
-
class: "pointer-events-auto absolute
|
|
163
|
+
}, null, 6),
|
|
164
|
+
n(z, {
|
|
165
|
+
class: "pointer-events-auto absolute top-[7px] border border-ice-100 bg-white rounded-full shadow size-6 p-0 min-w-auto",
|
|
166
|
+
style: r({ left: `${(e.pinnedLeftWidth ?? 0) + 12}px` }),
|
|
157
167
|
secondary: "",
|
|
158
168
|
icon: "",
|
|
159
169
|
"aria-label": "Scroll table left",
|
|
160
170
|
"data-test": "stash-table|scroll-left",
|
|
161
|
-
onClick: a[0] || (a[0] = (
|
|
171
|
+
onClick: a[0] || (a[0] = (ee) => H(-200))
|
|
162
172
|
}, {
|
|
163
|
-
default:
|
|
164
|
-
|
|
173
|
+
default: h(() => [
|
|
174
|
+
n(M, { name: "chevron-left" })
|
|
165
175
|
]),
|
|
166
176
|
_: 1
|
|
167
|
-
})
|
|
168
|
-
], 64)) :
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
class:
|
|
177
|
+
}, 8, ["style"])
|
|
178
|
+
], 64)) : E("", !0),
|
|
179
|
+
K.value ? (u(), p(N, { key: 1 }, [
|
|
180
|
+
f("div", {
|
|
181
|
+
class: i([b(m)["stash-table-scroll-shadow-right"], "stash-table-scroll-shadow border-r border-ice-100 absolute top-0 w-4"]),
|
|
182
|
+
style: r({
|
|
183
|
+
right: `${_.value + (e.pinnedRightWidth ?? 0)}px`,
|
|
184
|
+
bottom: `${S.value}px`
|
|
185
|
+
}),
|
|
172
186
|
"data-test": "stash-table|scroll-shadow-right"
|
|
173
|
-
}, null,
|
|
174
|
-
|
|
175
|
-
class: "pointer-events-auto absolute
|
|
187
|
+
}, null, 6),
|
|
188
|
+
n(z, {
|
|
189
|
+
class: "pointer-events-auto absolute top-[7px] border border-ice-100 bg-white rounded-full shadow size-6 p-0 min-w-auto",
|
|
190
|
+
style: r({ right: `${_.value + (e.pinnedRightWidth ?? 0) + 12}px` }),
|
|
176
191
|
secondary: "",
|
|
177
192
|
icon: "",
|
|
178
193
|
"aria-label": "Scroll table right",
|
|
179
194
|
"data-test": "stash-table|scroll-right",
|
|
180
|
-
onClick: a[1] || (a[1] = (
|
|
195
|
+
onClick: a[1] || (a[1] = (ee) => H(200))
|
|
181
196
|
}, {
|
|
182
|
-
default:
|
|
183
|
-
|
|
197
|
+
default: h(() => [
|
|
198
|
+
n(M, {
|
|
184
199
|
name: "chevron-right",
|
|
185
200
|
class: "text-ice-900"
|
|
186
201
|
})
|
|
187
202
|
]),
|
|
188
203
|
_: 1
|
|
189
|
-
})
|
|
190
|
-
], 64)) :
|
|
191
|
-
], 2)) :
|
|
204
|
+
}, 8, ["style"])
|
|
205
|
+
], 64)) : E("", !0)
|
|
206
|
+
], 2)) : E("", !0)
|
|
192
207
|
]));
|
|
193
208
|
}
|
|
194
|
-
}),
|
|
209
|
+
}), me = {
|
|
195
210
|
"stash-table-scroll-shadow-left": "_stash-table-scroll-shadow-left_cuovy_2",
|
|
196
211
|
"stash-table-scroll-shadow-right": "_stash-table-scroll-shadow-right_cuovy_6",
|
|
197
212
|
"stash-table-scroll-overlay": "_stash-table-scroll-overlay_cuovy_11"
|
|
198
|
-
},
|
|
199
|
-
$style:
|
|
200
|
-
},
|
|
213
|
+
}, ye = {
|
|
214
|
+
$style: me
|
|
215
|
+
}, Ie = /* @__PURE__ */ ue(pe, [["__cssModules", ye]]);
|
|
201
216
|
export {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
217
|
+
fe as Layout,
|
|
218
|
+
de as TABLE_INJECTION,
|
|
219
|
+
he as TableRadius,
|
|
220
|
+
Ie as default
|
|
206
221
|
};
|
|
207
222
|
//# sourceMappingURL=Table.js.map
|
package/dist/Table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.js","sources":["../src/components/Table/Table.types.ts","../src/components/Table/Table.vue"],"sourcesContent":["import type { ComputedRef } from 'vue';\n\nimport { SpacingDensities } from '../../../types/misc';\n\nexport enum Layout {\n Scroll = 'scroll',\n Stack = 'stack',\n}\n\nexport type Layouts = `${Layout}`;\n\nexport enum TableRadius {\n None = 'none',\n Rounded = 'rounded',\n RoundedBottom = 'rounded-bottom',\n}\n\nexport type TableRadiuses = `${TableRadius}`;\n\n/**\n * Properties and utilities provided to children of a Table instance\n */\nexport interface TableInjection {\n /**\n * Controls the Table's padding; the default value is \"comfortable\". On small screens, the density will always be \"compact\".\n */\n density: ComputedRef<SpacingDensities>;\n\n /**\n * Styles the last column for \"row actions\"\n */\n hasActions: ComputedRef<boolean>;\n\n /**\n * If true, hides the default expansion toggle column\n */\n hasCustomExpandToggle: ComputedRef<boolean>;\n\n /**\n * When true, the table is schema-driven (e.g. DataTable); selection column is rendered from the schema, not by TableRow/TableHeaderRow.\n */\n isSchemaDriven?: ComputedRef<boolean>;\n\n /**\n * Adds a toggle column for row expansion. This is primarily needed for ensuring the corresponding empty TableHeaderRow is included.\n */\n isExpandable: ComputedRef<boolean>;\n\n /**\n * Adds a checkbox column for selecting rows; intended for use with the `useSelection` composable.\n */\n isSelectable: ComputedRef<boolean>;\n\n /**\n * Sets the table layout; the default value is \"scroll\".\n */\n layout: ComputedRef<Layouts>;\n\n /**\n * Sets the table loading state.\n */\n isLoading: ComputedRef<boolean>;\n}\n","<script lang=\"ts\">\n import { SpacingDensities, SpacingDensity } from '../../../types/misc';\n import { MODULE_INJECTION } from '../Module/Module.keys';\n import { Layouts, TableRadiuses } from './Table.types';\n\n export * from './Table.keys';\n export * from './Table.types';\n\n export interface TableProps {\n /**\n * Controls the Table's padding; the default value is \"comfortable\". On small screens, \"compact\" density is applied regardless of this prop's value.\n */\n density?: SpacingDensities;\n\n /**\n * Sets the text for the empty state; the default value is \"No Results\".\n */\n emptyStateText?: string;\n\n /**\n * Styles the last column for \"row actions\"\n */\n hasActions?: boolean;\n\n /**\n * If true, hides the default expansion toggle column\n */\n hasCustomExpandToggle?: boolean;\n\n /**\n * Shows the empty state\n */\n isEmpty?: boolean;\n\n /**\n * When true, indicates the table is being composed by DataTable (schema-driven mode).\n * TableRow/TableHeaderRow use this to suppress their built-in selection cells.\n */\n isSchemaDriven?: boolean;\n\n /**\n * Shows the loading state\n */\n isLoading?: boolean;\n\n /**\n * Adds a toggle column for row expansion. This is primarily needed for ensuring the corresponding empty TableHeaderRow is included.\n */\n isExpandable?: boolean;\n\n /**\n * Adds a checkbox column for selecting rows; intended for use with the `useSelection` composable.\n */\n isSelectable?: boolean;\n\n /**\n * Sets the table layout; the default value is \"scroll\".\n */\n layout?: Layouts;\n\n /**\n * Controls the corners of the table with the \"border-radius\" CSS property. The default value is \"rounded\".\n */\n radius?: TableRadiuses;\n\n /**\n * Allows the table head to be sticky when scrolling inside the table body\n */\n stickyHeader?: {\n listLength: number;\n maxHeight: string;\n };\n }\n</script>\n\n<script setup lang=\"ts\">\n import { useIntersectionObserver, useResizeObserver, useScroll } from '@vueuse/core';\n import { computed, inject, provide, ref, useCssModule, useTemplateRef, watchEffect } from 'vue';\n\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import EmptyState from '../EmptyState/EmptyState.vue';\n import Icon from '../Icon/Icon.vue';\n import Loading from '../Loading/Loading.vue';\n import TableCell from '../TableCell/TableCell.vue';\n import TableRow from '../TableRow/TableRow.vue';\n import { TABLE_INJECTION } from './Table.keys';\n\n const SCROLL_DELTA_PX = 200;\n\n const props = withDefaults(defineProps<TableProps>(), {\n density: undefined,\n emptyStateText: '',\n hasActions: false,\n hasCustomExpandToggle: false,\n isEmpty: false,\n isSchemaDriven: false,\n isLoading: false,\n isExpandable: false,\n isSelectable: false,\n layout: 'scroll',\n radius: 'rounded',\n stickyHeader: undefined,\n });\n\n const classes = useCssModule();\n\n const {\n density: dataViewDensity,\n variant: dataViewVariant,\n isEmpty: isDataViewEmpty,\n isLoading: isDataViewLoading,\n isSelectable: isDataViewSelectable,\n } = inject(DATA_VIEW_INJECTION.key, DATA_VIEW_INJECTION.defaults);\n\n const { variant: moduleVariant } = inject(MODULE_INJECTION.key, MODULE_INJECTION.defaults);\n\n const computedRadius = computed<TableRadiuses>(() => {\n // Will work for tables when rendered inside of a Module with OR without a DataView.\n if (moduleVariant?.value === 'table') {\n return 'rounded-bottom';\n }\n\n if (dataViewVariant.value === 'table') {\n return 'rounded-bottom';\n }\n\n return props.radius;\n });\n\n const computedLayout = computed<Layouts>(() => {\n if (props.stickyHeader) {\n return 'scroll';\n }\n\n return props.layout;\n });\n\n const isShadowEnabled = computed<boolean>(() => {\n return computedLayout.value === 'scroll' && dataViewVariant.value === 'table';\n });\n\n const isStickyHeaderEnabled = computed<boolean>(() => {\n return !!(\n (props.stickyHeader?.maxHeight && props.stickyHeader?.listLength > 3) // table can't scroll without a max height; sticky headers only needed for a scrollable table\n // scrollable table and sticky headers not needed when list is small\n );\n });\n\n const rootStyle = computed(() => ({\n maxHeight: isStickyHeaderEnabled.value ? props.stickyHeader?.maxHeight : '',\n }));\n\n const isTableLoading = computed(() => Boolean(props.isLoading || isDataViewLoading?.value));\n\n const scrollContainerRef = useTemplateRef<HTMLElement>('scrollContainerRef');\n const tableRef = useTemplateRef<HTMLTableElement>('tableRef');\n const hasHorizontalOverflow = ref(false);\n\n const { arrivedState, measure } = useScroll(scrollContainerRef, { behavior: 'smooth' });\n\n function updateOverflow() {\n const el = scrollContainerRef.value;\n if (!el || computedLayout.value !== 'scroll') return;\n hasHorizontalOverflow.value = el.scrollWidth > el.clientWidth;\n measure();\n }\n\n useResizeObserver(scrollContainerRef, updateOverflow);\n useResizeObserver(tableRef, updateOverflow);\n\n useIntersectionObserver(\n scrollContainerRef,\n (entries) => {\n if (entries[0]?.isIntersecting) updateOverflow();\n },\n { threshold: 0.01 },\n );\n\n const canScrollLeft = computed(() => !arrivedState.left);\n const canScrollRight = computed(() => !arrivedState.right);\n const showScrollButtons = computed(() => computedLayout.value === 'scroll' && hasHorizontalOverflow.value);\n\n function scrollBy(delta: number) {\n scrollContainerRef.value?.scrollBy({ left: delta, behavior: 'smooth' });\n }\n\n provide(TABLE_INJECTION.key, {\n density: computed(() => props.density || dataViewDensity.value || SpacingDensity.Comfortable),\n hasCustomExpandToggle: computed(() => props.hasCustomExpandToggle),\n hasActions: computed(() => props.hasActions),\n isSchemaDriven: computed(() => props.isSchemaDriven),\n isExpandable: computed(() => props.isExpandable),\n isSelectable: computed(\n () =>\n props.isSelectable &&\n !props.isLoading &&\n !isDataViewLoading?.value &&\n !props.isEmpty &&\n !isDataViewEmpty?.value,\n ),\n isLoading: isTableLoading,\n layout: computedLayout,\n });\n\n watchEffect(() => {\n // Table can be both casted within a DataView or standalone. useSelection is still possible to be used on both cases,\n // making it important to have Table to control selection props.\n // To avoid breaking changes and developer experience, a DataView injection is passed down and updated whenever it exists,\n // and move the information up into DataView, that sometimes aren't used.\n if (isDataViewSelectable) {\n isDataViewSelectable.value = props.isSelectable;\n }\n });\n</script>\n\n<template>\n <div class=\"stash-table-wrapper relative\">\n <div\n ref=\"scrollContainerRef\"\n class=\"stash-table relative\"\n :class=\"[\n { rounded: computedRadius === 'rounded' },\n { 'rounded-b': computedRadius === 'rounded-bottom' },\n { 'border-t border-ice-200': dataViewVariant === 'table' },\n { 'overflow-auto scroll-smooth': computedLayout === 'scroll' },\n { shadow: isShadowEnabled },\n {\n 'overflow-visible lg:overflow-auto lg:shadow': computedLayout === 'stack',\n },\n ]\"\n data-test=\"stash-table\"\n :aria-busy=\"isTableLoading\"\n :style=\"rootStyle\"\n >\n <table ref=\"tableRef\" class=\"relative w-full border-separate\">\n <thead class=\"border-b border-ice-200\" :class=\"{ 'hidden lg:table-header-group': computedLayout === 'stack' }\">\n <!-- @slot head -->\n <slot name=\"head\"> </slot>\n </thead>\n <tbody>\n <!--\n col-span-12 makes the td span all columns only when layout === 'stack' and the viewport is below lg (when table elements are using display: grid ).\n The colspan attr does the same in all other cases when the table elements are using their native table styles.\n relative prevents the loading/empty state from overflowing the table whenever the table has actions and the table cell applies position absolute.\n \"max-width: '100vw'\" prevents the loading/empty state from overflowing the table whenever the table is in the scroll layout.\n These are necessary in order to properly horizontally center Loading, and EmptyState\n -->\n <TableRow v-if=\"isTableLoading\">\n <TableCell colspan=\"100%\" :class=\"{ 'relative! col-span-12': computedLayout === 'stack' }\">\n <Loading :style=\"[computedLayout === 'scroll' ? { 'max-width': '100vw' } : {}]\" />\n </TableCell>\n </TableRow>\n <!-- @slot empty -->\n <template v-else-if=\"props.isEmpty || isDataViewEmpty\">\n <TableRow>\n <TableCell colspan=\"100%\" :class=\"{ 'relative! col-span-12': computedLayout === 'stack' }\">\n <slot name=\"empty\">\n <EmptyState\n class=\"w-full bg-white\"\n :text=\"props.emptyStateText\"\n :style=\"[computedLayout === 'scroll' ? { 'max-width': '100vw' } : {}]\"\n />\n </slot>\n </TableCell>\n </TableRow>\n </template>\n <!-- @slot body -->\n <slot v-else name=\"body\"></slot>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"showScrollButtons\"\n :class=\"classes['stash-table-scroll-overlay']\"\n class=\"pointer-events-none absolute inset-0 flex items-center justify-between z-2\"\n >\n <template v-if=\"canScrollLeft\">\n <div\n :class=\"classes['stash-table-scroll-shadow-left']\"\n class=\"stash-table-scroll-shadow border-l border-ice-100 absolute left-0 top-0 bottom-0 w-4\"\n data-test=\"stash-table|scroll-shadow-left\"\n />\n <Button\n class=\"pointer-events-auto absolute left-3 top-[7px] border border-ice-100 bg-white rounded-full shadow size-6 p-0 min-w-auto\"\n secondary\n icon\n :aria-label=\"'Scroll table left'\"\n data-test=\"stash-table|scroll-left\"\n @click=\"scrollBy(-SCROLL_DELTA_PX)\"\n >\n <Icon name=\"chevron-left\" />\n </Button>\n </template>\n <template v-if=\"canScrollRight\">\n <div\n :class=\"classes['stash-table-scroll-shadow-right']\"\n class=\"stash-table-scroll-shadow border-r border-ice-100 absolute right-0 top-0 bottom-0 w-4\"\n data-test=\"stash-table|scroll-shadow-right\"\n />\n\n <Button\n class=\"pointer-events-auto absolute right-3 top-[7px] border border-ice-100 bg-white rounded-full shadow size-6 p-0 min-w-auto\"\n secondary\n icon\n :aria-label=\"'Scroll table right'\"\n data-test=\"stash-table|scroll-right\"\n @click=\"scrollBy(SCROLL_DELTA_PX)\"\n >\n <Icon name=\"chevron-right\" class=\"text-ice-900\" />\n </Button>\n </template>\n </div>\n </div>\n</template>\n\n<style module>\n .stash-table-scroll-shadow-left {\n background: linear-gradient(90deg, rgb(38 38 38 / 10%) 0%, rgb(38 38 38 / 0%) 32.65%);\n }\n\n .stash-table-scroll-shadow-right {\n background: linear-gradient(270deg, rgb(38 38 38 / 10%) 0%, rgb(38 38 38 / 0%) 32.65%);\n }\n\n @media print {\n .stash-table-scroll-overlay {\n display: none !important;\n }\n }\n</style>\n"],"names":["Layout","TableRadius","props","__props","classes","useCssModule","dataViewDensity","dataViewVariant","isDataViewEmpty","isDataViewLoading","isDataViewSelectable","inject","DATA_VIEW_INJECTION","moduleVariant","MODULE_INJECTION","computedRadius","computed","computedLayout","isShadowEnabled","isStickyHeaderEnabled","_a","_b","rootStyle","isTableLoading","scrollContainerRef","useTemplateRef","tableRef","hasHorizontalOverflow","ref","arrivedState","measure","useScroll","updateOverflow","el","useResizeObserver","useIntersectionObserver","entries","canScrollLeft","canScrollRight","showScrollButtons","scrollBy","delta","provide","TABLE_INJECTION","SpacingDensity","watchEffect","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_unref","_normalizeClass","_renderSlot","_ctx","_createBlock","TableRow","_createVNode","TableCell","Loading","EmptyState","_Fragment","Button","_cache","$event","Icon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Table.js","sources":["../src/components/Table/Table.types.ts","../src/components/Table/Table.vue"],"sourcesContent":["import type { ComputedRef } from 'vue';\n\nimport { SpacingDensities } from '../../../types/misc';\n\nexport enum Layout {\n Scroll = 'scroll',\n Stack = 'stack',\n}\n\nexport type Layouts = `${Layout}`;\n\nexport enum TableRadius {\n None = 'none',\n Rounded = 'rounded',\n RoundedBottom = 'rounded-bottom',\n}\n\nexport type TableRadiuses = `${TableRadius}`;\n\n/**\n * Properties and utilities provided to children of a Table instance\n */\nexport interface TableInjection {\n /**\n * Controls the Table's padding; the default value is \"comfortable\". On small screens, the density will always be \"compact\".\n */\n density: ComputedRef<SpacingDensities>;\n\n /**\n * Styles the last column for \"row actions\"\n */\n hasActions: ComputedRef<boolean>;\n\n /**\n * If true, hides the default expansion toggle column\n */\n hasCustomExpandToggle: ComputedRef<boolean>;\n\n /**\n * When true, the table is schema-driven (e.g. DataTable); selection column is rendered from the schema, not by TableRow/TableHeaderRow.\n */\n isSchemaDriven?: ComputedRef<boolean>;\n\n /**\n * Adds a toggle column for row expansion. This is primarily needed for ensuring the corresponding empty TableHeaderRow is included.\n */\n isExpandable: ComputedRef<boolean>;\n\n /**\n * Adds a checkbox column for selecting rows; intended for use with the `useSelection` composable.\n */\n isSelectable: ComputedRef<boolean>;\n\n /**\n * Sets the table layout; the default value is \"scroll\".\n */\n layout: ComputedRef<Layouts>;\n\n /**\n * Sets the table loading state.\n */\n isLoading: ComputedRef<boolean>;\n}\n","<script lang=\"ts\">\n import { SpacingDensities, SpacingDensity } from '../../../types/misc';\n import { MODULE_INJECTION } from '../Module/Module.keys';\n import { Layouts, TableRadiuses } from './Table.types';\n\n export * from './Table.keys';\n export * from './Table.types';\n\n export interface TableProps {\n /**\n * Controls the Table's padding; the default value is \"comfortable\". On small screens, \"compact\" density is applied regardless of this prop's value.\n */\n density?: SpacingDensities;\n\n /**\n * Sets the text for the empty state; the default value is \"No Results\".\n */\n emptyStateText?: string;\n\n /**\n * Styles the last column for \"row actions\"\n */\n hasActions?: boolean;\n\n /**\n * If true, hides the default expansion toggle column\n */\n hasCustomExpandToggle?: boolean;\n\n /**\n * Shows the empty state\n */\n isEmpty?: boolean;\n\n /**\n * When true, indicates the table is being composed by DataTable (schema-driven mode).\n * TableRow/TableHeaderRow use this to suppress their built-in selection cells.\n */\n isSchemaDriven?: boolean;\n\n /**\n * Shows the loading state\n */\n isLoading?: boolean;\n\n /**\n * Adds a toggle column for row expansion. This is primarily needed for ensuring the corresponding empty TableHeaderRow is included.\n */\n isExpandable?: boolean;\n\n /**\n * Adds a checkbox column for selecting rows; intended for use with the `useSelection` composable.\n */\n isSelectable?: boolean;\n\n /**\n * Sets the table layout; the default value is \"scroll\".\n */\n layout?: Layouts;\n\n /**\n * Controls the corners of the table with the \"border-radius\" CSS property. The default value is \"rounded\".\n */\n radius?: TableRadiuses;\n\n /**\n * Allows the table head to be sticky when scrolling inside the table body\n */\n stickyHeader?: {\n listLength: number;\n maxHeight: string;\n };\n\n /**\n * Total width (px) of left-pinned columns. Used to offset scroll overlay elements.\n */\n pinnedLeftWidth?: number;\n\n /**\n * Total width (px) of right-pinned columns. Used to offset scroll overlay elements.\n */\n pinnedRightWidth?: number;\n\n /**\n * When set, applied as min-width on the <table> element so columns don't collapse below their TanStack sizes.\n */\n tableMinWidth?: number;\n }\n</script>\n\n<script setup lang=\"ts\">\n import { useIntersectionObserver, useResizeObserver, useScroll } from '@vueuse/core';\n import { computed, inject, provide, ref, useCssModule, useTemplateRef, watchEffect } from 'vue';\n\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import EmptyState from '../EmptyState/EmptyState.vue';\n import Icon from '../Icon/Icon.vue';\n import Loading from '../Loading/Loading.vue';\n import TableCell from '../TableCell/TableCell.vue';\n import TableRow from '../TableRow/TableRow.vue';\n import { TABLE_INJECTION } from './Table.keys';\n\n const SCROLL_DELTA_PX = 200;\n\n const props = withDefaults(defineProps<TableProps>(), {\n density: undefined,\n emptyStateText: '',\n hasActions: false,\n hasCustomExpandToggle: false,\n isEmpty: false,\n isSchemaDriven: false,\n isLoading: false,\n isExpandable: false,\n isSelectable: false,\n layout: 'scroll',\n radius: 'rounded',\n stickyHeader: undefined,\n pinnedLeftWidth: 0,\n pinnedRightWidth: 0,\n tableMinWidth: undefined,\n });\n\n const classes = useCssModule();\n\n const {\n density: dataViewDensity,\n variant: dataViewVariant,\n isEmpty: isDataViewEmpty,\n isLoading: isDataViewLoading,\n isSelectable: isDataViewSelectable,\n } = inject(DATA_VIEW_INJECTION.key, DATA_VIEW_INJECTION.defaults);\n\n const { variant: moduleVariant } = inject(MODULE_INJECTION.key, MODULE_INJECTION.defaults);\n\n const computedRadius = computed<TableRadiuses>(() => {\n // Will work for tables when rendered inside of a Module with OR without a DataView.\n if (moduleVariant?.value === 'table') {\n return 'rounded-bottom';\n }\n\n if (dataViewVariant.value === 'table') {\n return 'rounded-bottom';\n }\n\n return props.radius;\n });\n\n const computedLayout = computed<Layouts>(() => {\n if (props.stickyHeader) {\n return 'scroll';\n }\n\n return props.layout;\n });\n\n const isShadowEnabled = computed<boolean>(() => {\n return computedLayout.value === 'scroll' && dataViewVariant.value === 'table';\n });\n\n const isStickyHeaderEnabled = computed<boolean>(() => {\n return !!(\n (props.stickyHeader?.maxHeight && props.stickyHeader?.listLength > 3) // table can't scroll without a max height; sticky headers only needed for a scrollable table\n // scrollable table and sticky headers not needed when list is small\n );\n });\n\n const rootStyle = computed(() => ({\n maxHeight: isStickyHeaderEnabled.value ? props.stickyHeader?.maxHeight : '',\n }));\n\n const isTableLoading = computed(() => Boolean(props.isLoading || isDataViewLoading?.value));\n\n const scrollContainerRef = useTemplateRef<HTMLElement>('scrollContainerRef');\n const tableRef = useTemplateRef<HTMLTableElement>('tableRef');\n const hasHorizontalOverflow = ref(false);\n const scrollbarWidth = ref(0);\n const horizontalScrollbarHeight = ref(0);\n\n const { arrivedState, measure } = useScroll(scrollContainerRef, { behavior: 'smooth' });\n\n function updateOverflow() {\n const el = scrollContainerRef.value;\n if (!el || computedLayout.value !== 'scroll') return;\n hasHorizontalOverflow.value = el.scrollWidth > el.clientWidth;\n scrollbarWidth.value = el.offsetWidth - el.clientWidth;\n horizontalScrollbarHeight.value = el.offsetHeight - el.clientHeight;\n measure();\n }\n\n useResizeObserver(scrollContainerRef, updateOverflow);\n useResizeObserver(tableRef, updateOverflow);\n\n useIntersectionObserver(\n scrollContainerRef,\n (entries) => {\n if (entries[0]?.isIntersecting) updateOverflow();\n },\n { threshold: 0.01 },\n );\n\n const canScrollLeft = computed(() => !arrivedState.left);\n const canScrollRight = computed(() => !arrivedState.right);\n const showScrollButtons = computed(() => computedLayout.value === 'scroll' && hasHorizontalOverflow.value);\n\n function scrollBy(delta: number) {\n scrollContainerRef.value?.scrollBy({ left: delta, behavior: 'smooth' });\n }\n\n const hasPinnedColumns = computed(() => (props.pinnedLeftWidth ?? 0) > 0 || (props.pinnedRightWidth ?? 0) > 0);\n\n const tableStyle = computed(() => {\n const style: Record<string, string> = {};\n if (props.tableMinWidth != null) style.minWidth = `${props.tableMinWidth}px`;\n if (hasPinnedColumns.value) style.borderSpacing = '0';\n return Object.keys(style).length ? style : undefined;\n });\n\n provide(TABLE_INJECTION.key, {\n density: computed(() => props.density || dataViewDensity.value || SpacingDensity.Comfortable),\n hasCustomExpandToggle: computed(() => props.hasCustomExpandToggle),\n hasActions: computed(() => props.hasActions),\n isSchemaDriven: computed(() => props.isSchemaDriven),\n isExpandable: computed(() => props.isExpandable),\n isSelectable: computed(\n () =>\n props.isSelectable &&\n !props.isLoading &&\n !isDataViewLoading?.value &&\n !props.isEmpty &&\n !isDataViewEmpty?.value,\n ),\n isLoading: isTableLoading,\n layout: computedLayout,\n });\n\n watchEffect(() => {\n // Table can be both casted within a DataView or standalone. useSelection is still possible to be used on both cases,\n // making it important to have Table to control selection props.\n // To avoid breaking changes and developer experience, a DataView injection is passed down and updated whenever it exists,\n // and move the information up into DataView, that sometimes aren't used.\n if (isDataViewSelectable) {\n isDataViewSelectable.value = props.isSelectable;\n }\n });\n</script>\n\n<template>\n <div class=\"stash-table-wrapper relative\">\n <div\n ref=\"scrollContainerRef\"\n class=\"stash-table relative\"\n :class=\"[\n { rounded: computedRadius === 'rounded' },\n { 'rounded-b': computedRadius === 'rounded-bottom' },\n { 'border-t border-ice-200': dataViewVariant === 'table' },\n { 'overflow-auto scroll-smooth': computedLayout === 'scroll' },\n { shadow: isShadowEnabled },\n {\n 'overflow-visible lg:overflow-auto lg:shadow': computedLayout === 'stack',\n },\n ]\"\n data-test=\"stash-table\"\n :aria-busy=\"isTableLoading\"\n :style=\"rootStyle\"\n >\n <table ref=\"tableRef\" class=\"relative w-full border-separate\" :style=\"tableStyle\">\n <thead class=\"border-b border-ice-200\" :class=\"{ 'hidden lg:table-header-group': computedLayout === 'stack' }\">\n <!-- @slot head -->\n <slot name=\"head\"> </slot>\n </thead>\n <tbody>\n <!--\n col-span-12 makes the td span all columns only when layout === 'stack' and the viewport is below lg (when table elements are using display: grid ).\n The colspan attr does the same in all other cases when the table elements are using their native table styles.\n relative prevents the loading/empty state from overflowing the table whenever the table has actions and the table cell applies position absolute.\n \"max-width: '100vw'\" prevents the loading/empty state from overflowing the table whenever the table is in the scroll layout.\n These are necessary in order to properly horizontally center Loading, and EmptyState\n -->\n <TableRow v-if=\"isTableLoading\">\n <TableCell colspan=\"100%\" :class=\"{ 'relative! col-span-12': computedLayout === 'stack' }\">\n <Loading :style=\"[computedLayout === 'scroll' ? { 'max-width': '100vw' } : {}]\" />\n </TableCell>\n </TableRow>\n <!-- @slot empty -->\n <template v-else-if=\"props.isEmpty || isDataViewEmpty\">\n <TableRow>\n <TableCell colspan=\"100%\" :class=\"{ 'relative! col-span-12': computedLayout === 'stack' }\">\n <slot name=\"empty\">\n <EmptyState\n class=\"w-full bg-white\"\n :text=\"props.emptyStateText\"\n :style=\"[computedLayout === 'scroll' ? { 'max-width': '100vw' } : {}]\"\n />\n </slot>\n </TableCell>\n </TableRow>\n </template>\n <!-- @slot body -->\n <slot v-else name=\"body\"></slot>\n </tbody>\n </table>\n </div>\n <div\n v-if=\"showScrollButtons\"\n :class=\"classes['stash-table-scroll-overlay']\"\n class=\"pointer-events-none absolute inset-0 flex items-center justify-between z-2\"\n >\n <template v-if=\"canScrollLeft\">\n <div\n :class=\"classes['stash-table-scroll-shadow-left']\"\n class=\"stash-table-scroll-shadow border-l border-ice-100 absolute top-0 w-4\"\n :style=\"{ left: `${props.pinnedLeftWidth}px`, bottom: `${horizontalScrollbarHeight}px` }\"\n data-test=\"stash-table|scroll-shadow-left\"\n />\n <Button\n class=\"pointer-events-auto absolute top-[7px] border border-ice-100 bg-white rounded-full shadow size-6 p-0 min-w-auto\"\n :style=\"{ left: `${(props.pinnedLeftWidth ?? 0) + 12}px` }\"\n secondary\n icon\n :aria-label=\"'Scroll table left'\"\n data-test=\"stash-table|scroll-left\"\n @click=\"scrollBy(-SCROLL_DELTA_PX)\"\n >\n <Icon name=\"chevron-left\" />\n </Button>\n </template>\n <template v-if=\"canScrollRight\">\n <div\n :class=\"classes['stash-table-scroll-shadow-right']\"\n class=\"stash-table-scroll-shadow border-r border-ice-100 absolute top-0 w-4\"\n :style=\"{\n right: `${scrollbarWidth + (props.pinnedRightWidth ?? 0)}px`,\n bottom: `${horizontalScrollbarHeight}px`,\n }\"\n data-test=\"stash-table|scroll-shadow-right\"\n />\n\n <Button\n class=\"pointer-events-auto absolute top-[7px] border border-ice-100 bg-white rounded-full shadow size-6 p-0 min-w-auto\"\n :style=\"{ right: `${scrollbarWidth + (props.pinnedRightWidth ?? 0) + 12}px` }\"\n secondary\n icon\n :aria-label=\"'Scroll table right'\"\n data-test=\"stash-table|scroll-right\"\n @click=\"scrollBy(SCROLL_DELTA_PX)\"\n >\n <Icon name=\"chevron-right\" class=\"text-ice-900\" />\n </Button>\n </template>\n </div>\n </div>\n</template>\n\n<style module>\n .stash-table-scroll-shadow-left {\n background: linear-gradient(90deg, rgb(38 38 38 / 10%) 0%, rgb(38 38 38 / 0%) 32.65%);\n }\n\n .stash-table-scroll-shadow-right {\n background: linear-gradient(270deg, rgb(38 38 38 / 10%) 0%, rgb(38 38 38 / 0%) 32.65%);\n }\n\n @media print {\n .stash-table-scroll-overlay {\n display: none !important;\n }\n }\n</style>\n"],"names":["Layout","TableRadius","props","__props","classes","useCssModule","dataViewDensity","dataViewVariant","isDataViewEmpty","isDataViewLoading","isDataViewSelectable","inject","DATA_VIEW_INJECTION","moduleVariant","MODULE_INJECTION","computedRadius","computed","computedLayout","isShadowEnabled","isStickyHeaderEnabled","_a","_b","rootStyle","isTableLoading","scrollContainerRef","useTemplateRef","tableRef","hasHorizontalOverflow","ref","scrollbarWidth","horizontalScrollbarHeight","arrivedState","measure","useScroll","updateOverflow","el","useResizeObserver","useIntersectionObserver","entries","canScrollLeft","canScrollRight","showScrollButtons","scrollBy","delta","hasPinnedColumns","tableStyle","style","provide","TABLE_INJECTION","SpacingDensity","watchEffect","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_unref","_normalizeClass","_renderSlot","_ctx","_createBlock","TableRow","_createVNode","TableCell","Loading","EmptyState","_Fragment","_normalizeStyle","Button","_cache","$event","Icon"],"mappings":"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"}
|