@treeui/vue 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/TAccordion.cjs.map +1 -1
- package/dist/components/TAccordion.js.map +1 -1
- package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TAccordionItem.cjs.map +1 -1
- package/dist/components/TAccordionItem.js.map +1 -1
- package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TAppShell.cjs.map +1 -1
- package/dist/components/TAppShell.js.map +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TDatePicker.cjs.map +1 -1
- package/dist/components/TDatePicker.js.map +1 -1
- package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TDateTimePicker.cjs.map +1 -1
- package/dist/components/TDateTimePicker.js.map +1 -1
- package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TDrawer.cjs.map +1 -1
- package/dist/components/TDrawer.js.map +1 -1
- package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TDropdown.cjs.map +1 -1
- package/dist/components/TDropdown.js.map +1 -1
- package/dist/components/TDropdown.vue.d.ts +4 -0
- package/dist/components/TDropdown.vue.d.ts.map +1 -1
- package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.js +22 -18
- package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TFlag.cjs +2 -0
- package/dist/components/TFlag.cjs.map +1 -0
- package/dist/components/TFlag.js +7 -0
- package/dist/components/TFlag.js.map +1 -0
- package/dist/components/TFlag.vue.d.ts +20 -0
- package/dist/components/TFlag.vue.d.ts.map +1 -0
- package/dist/components/TFlag.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TFlag.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TFlag.vue_vue_type_script_setup_true_lang.js +58 -0
- package/dist/components/TFlag.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TIcon.cjs.map +1 -1
- package/dist/components/TIcon.js.map +1 -1
- package/dist/components/TIcon.vue.d.ts +1 -1
- package/dist/components/TIcon.vue.d.ts.map +1 -1
- package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.js +18 -17
- package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TLanguageSelect.cjs +2 -0
- package/dist/components/TLanguageSelect.cjs.map +1 -0
- package/dist/components/TLanguageSelect.js +7 -0
- package/dist/components/TLanguageSelect.js.map +1 -0
- package/dist/components/TLanguageSelect.vue.d.ts +103 -0
- package/dist/components/TLanguageSelect.vue.d.ts.map +1 -0
- package/dist/components/TLanguageSelect.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TLanguageSelect.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TLanguageSelect.vue_vue_type_script_setup_true_lang.js +299 -0
- package/dist/components/TLanguageSelect.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TModal.cjs.map +1 -1
- package/dist/components/TModal.js.map +1 -1
- package/dist/components/TModal.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TModal.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TModal.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TModal.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TMultiSelect.cjs.map +1 -1
- package/dist/components/TMultiSelect.js.map +1 -1
- package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TNavMenu.cjs.map +1 -1
- package/dist/components/TNavMenu.js.map +1 -1
- package/dist/components/TNavMenu.vue.d.ts +7 -2
- package/dist/components/TNavMenu.vue.d.ts.map +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js +50 -49
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TPopover.cjs.map +1 -1
- package/dist/components/TPopover.js.map +1 -1
- package/dist/components/TPopover.vue.d.ts +4 -2
- package/dist/components/TPopover.vue.d.ts.map +1 -1
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.js +10 -5
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TPricingCard.vue.d.ts +1 -1
- package/dist/components/TPricingCard.vue.d.ts.map +1 -1
- package/dist/components/TSidebar.cjs.map +1 -1
- package/dist/components/TSidebar.js.map +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TSteps.cjs.map +1 -1
- package/dist/components/TSteps.js.map +1 -1
- package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TToast.cjs.map +1 -1
- package/dist/components/TToast.js.map +1 -1
- package/dist/components/TToast.vue.d.ts.map +1 -1
- package/dist/components/TToast.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TToast.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TToast.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/components/TToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TTreeViewItem.cjs.map +1 -1
- package/dist/components/TTreeViewItem.js.map +1 -1
- package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/accordion.cjs.map +1 -1
- package/dist/components/accordion.d.ts +4 -4
- package/dist/components/accordion.d.ts.map +1 -1
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/index.d.ts +5 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +77 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +81 -78
- package/dist/plugin.cjs +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +146 -142
- package/dist/plugin.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TAppShell.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSidebarSide } from './TSidebar.vue';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = getTreeIcon('x');\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n side?: TSidebarSide;\n sidebarWidth?: string;\n collapsedWidth?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n mobile?: boolean;\n breakpoint?: string;\n sidebarOpen?: boolean;\n defaultSidebarOpen?: boolean;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showMenuButton?: boolean;\n /** Render the built-in collapse toggle in the sidebar footer (desktop). */\n showCollapseButton?: boolean;\n menuLabel?: string;\n closeLabel?: string;\n sidebarLabel?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'div',\n side: 'left',\n sidebarWidth: '17.5rem',\n collapsedWidth: '4.75rem',\n collapsible: false,\n collapsed: undefined,\n defaultCollapsed: false,\n mobile: undefined,\n breakpoint: '768px',\n sidebarOpen: undefined,\n defaultSidebarOpen: false,\n closeOnEscape: true,\n closeOnOverlay: true,\n showMenuButton: true,\n showCollapseButton: true,\n menuLabel: 'Open menu',\n closeLabel: 'Close menu',\n sidebarLabel: 'Sidebar',\n collapseLabel: 'Collapse sidebar',\n expandLabel: 'Expand sidebar',\n },\n);\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean];\n 'collapse-change': [value: boolean];\n 'update:sidebarOpen': [value: boolean];\n 'sidebar-open-change': [value: boolean];\n}>();\n\nexport interface AppShellSlotProps {\n mobile: boolean;\n collapsed: boolean;\n sidebarOpen: boolean;\n toggleSidebar: () => void;\n closeSidebar: () => void;\n toggleCollapsed: () => void;\n}\n\ndefineSlots<{\n header?: (props: AppShellSlotProps) => unknown;\n /** Header region over the sidebar rail; the `header` slot then aligns with the content panel. */\n 'header-start'?: (props: AppShellSlotProps) => unknown;\n /** Pinned above the sidebar body, inset to line up with nav item icons. */\n 'sidebar-header'?: (props: AppShellSlotProps) => unknown;\n sidebar?: (props: AppShellSlotProps) => unknown;\n /** Pinned to the bottom of the sidebar, inset to line up with nav item icons. */\n 'sidebar-footer'?: (props: AppShellSlotProps) => unknown;\n default?: (props: Pick<AppShellSlotProps, 'mobile' | 'collapsed'>) => unknown;\n 'menu-icon'?: (props: { sidebarOpen: boolean }) => unknown;\n 'collapse-icon'?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst sidebarId = createId('t-app-shell-sidebar');\n\nconst { value: isCollapsed, setValue: setCollapsed } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst { value: isSidebarOpen, setValue: setSidebarOpen } = useControllableOpen(\n toRef(props, 'sidebarOpen'),\n props.defaultSidebarOpen,\n (value) => {\n emit('update:sidebarOpen', value);\n emit('sidebar-open-change', value);\n },\n);\n\n// Auto responsive detection when `mobile` is not explicitly controlled.\nconst autoMobile = ref(false);\nlet mediaQuery: MediaQueryList | null = null;\n\nconst onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {\n autoMobile.value = event.matches;\n};\n\nconst setupMediaQuery = () => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n\n teardownMediaQuery();\n mediaQuery = window.matchMedia(`(max-width: ${props.breakpoint})`);\n autoMobile.value = mediaQuery.matches;\n mediaQuery.addEventListener?.('change', onMediaChange);\n};\n\nconst teardownMediaQuery = () => {\n mediaQuery?.removeEventListener?.('change', onMediaChange);\n mediaQuery = null;\n};\n\nconst isMobile = computed(() => props.mobile ?? autoMobile.value);\n\n// Collapsing is desktop-only, so the built-in toggle follows the same rule.\nconst showCollapseToggle = computed(\n () => !isMobile.value && props.collapsible && props.showCollapseButton,\n);\n\n// Collapse is a desktop-only concept; the mobile drawer always shows the\n// expanded sidebar, so descendants and slots see `collapsed: false` there.\nconst effectiveCollapsed = computed(() =>\n isMobile.value ? false : isCollapsed.value,\n);\n\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nlet previousBodyOverflow = '';\nlet bodyLocked = false;\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined' || bodyLocked) {\n return;\n }\n\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n bodyLocked = true;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || !bodyLocked) {\n return;\n }\n\n document.body.style.overflow = previousBodyOverflow;\n bodyLocked = false;\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openSidebar = () => {\n previousFocusedElement.value =\n typeof document === 'undefined'\n ? null\n : (document.activeElement as HTMLElement | null);\n setSidebarOpen(true);\n};\n\nconst closeSidebar = () => {\n setSidebarOpen(false);\n};\n\nconst toggleSidebar = () => {\n if (isSidebarOpen.value) {\n closeSidebar();\n } else {\n openSidebar();\n }\n};\n\nconst toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setCollapsed(!isCollapsed.value);\n};\n\nconst onOverlayClick = () => {\n if (props.closeOnOverlay) {\n closeSidebar();\n }\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeSidebar();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\n// The off-canvas drawer only exists in mobile mode; keep body-scroll lock and\n// focus handling in sync with both the open flag and the responsive mode.\nconst syncOverlayState = (open: boolean, wasOpen: boolean) => {\n if (open && isMobile.value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (wasOpen) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n};\n\nwatch(isSidebarOpen, (value, previousValue) => {\n syncOverlayState(value, Boolean(previousValue));\n});\n\nwatch(isMobile, (mobile) => {\n if (!isSidebarOpen.value) {\n return;\n }\n\n // Leaving mobile removes the drawer from the DOM, so release the lock and\n // restore focus; re-entering mobile while \"open\" re-arms the overlay.\n if (mobile) {\n lockBodyScroll();\n focusSurface();\n } else {\n unlockBodyScroll();\n }\n});\n\nwatch(\n () => props.breakpoint,\n () => {\n if (typeof window !== 'undefined') {\n setupMediaQuery();\n }\n },\n);\n\nonMounted(() => {\n setupMediaQuery();\n});\n\nonBeforeUnmount(() => {\n teardownMediaQuery();\n unlockBodyScroll();\n});\n\nprovide(treeSidebarInjectionKey, {\n collapsed: effectiveCollapsed,\n});\n\nconst rootClasses = computed(() => [\n 't-app-shell',\n `t-app-shell--${props.side}`,\n {\n 'is-mobile': isMobile.value,\n 'is-collapsed':\n !isMobile.value && props.collapsible && isCollapsed.value,\n 'is-sidebar-open': isMobile.value && isSidebarOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-app-shell-sidebar-width': props.sidebarWidth,\n '--tree-app-shell-collapsed-width': props.collapsedWidth,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst slotProps = computed<AppShellSlotProps>(() => ({\n mobile: isMobile.value,\n collapsed: effectiveCollapsed.value,\n sidebarOpen: isSidebarOpen.value,\n toggleSidebar,\n closeSidebar,\n toggleCollapsed,\n}));\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-mobile=\"isMobile ? 'true' : 'false'\"\n >\n <header\n class=\"t-app-shell__header\"\n :class=\"{ 'has-start': Boolean($slots['header-start']) }\"\n >\n <button\n v-if=\"isMobile && showMenuButton\"\n type=\"button\"\n class=\"t-app-shell__menu-button\"\n :aria-label=\"menuLabel\"\n :aria-expanded=\"isSidebarOpen\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleSidebar\"\n >\n <slot\n name=\"menu-icon\"\n :sidebar-open=\"isSidebarOpen\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"6\"\n y2=\"6\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"12\"\n y2=\"12\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </button>\n\n <div\n v-if=\"$slots['header-start']\"\n class=\"t-app-shell__header-start\"\n >\n <slot\n name=\"header-start\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__header-content\">\n <slot\n name=\"header\"\n v-bind=\"slotProps\"\n />\n </div>\n </header>\n\n <aside\n v-if=\"!isMobile\"\n :id=\"sidebarId\"\n class=\"t-app-shell__sidebar\"\n :aria-label=\"sidebarLabel\"\n >\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer'] || showCollapseToggle\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n\n <button\n v-if=\"showCollapseToggle\"\n type=\"button\"\n class=\"t-app-shell__collapse-button\"\n :aria-label=\"isCollapsed ? expandLabel : collapseLabel\"\n :aria-expanded=\"!isCollapsed\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"collapse-icon\"\n :collapsed=\"effectiveCollapsed\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"3\"\n y=\"3\"\n width=\"18\"\n height=\"18\"\n rx=\"2\"\n />\n <path d=\"M9 3v18\" />\n </svg>\n </slot>\n </button>\n </div>\n </aside>\n\n <main class=\"t-app-shell__main\">\n <slot\n :mobile=\"isMobile\"\n :collapsed=\"effectiveCollapsed\"\n />\n </main>\n\n <transition name=\"t-app-shell-fade\">\n <div\n v-if=\"isMobile && isSidebarOpen\"\n class=\"t-app-shell__overlay\"\n >\n <div\n class=\"t-app-shell__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <aside\n :id=\"sidebarId\"\n ref=\"surfaceRef\"\n class=\"t-app-shell__drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"sidebarLabel\"\n tabindex=\"-1\"\n @keydown=\"onKeydown\"\n >\n <div class=\"t-app-shell__drawer-topbar\">\n <button\n type=\"button\"\n class=\"t-app-shell__drawer-close\"\n :aria-label=\"closeLabel\"\n @click=\"closeSidebar\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n <div class=\"t-app-shell__drawer-body\">\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer']\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n </div>\n </div>\n </aside>\n </div>\n </transition>\n </component>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TAppShell.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSidebarSide } from './TSidebar.vue';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = computed(() => getTreeIcon('x'));\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n side?: TSidebarSide;\n sidebarWidth?: string;\n collapsedWidth?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n mobile?: boolean;\n breakpoint?: string;\n sidebarOpen?: boolean;\n defaultSidebarOpen?: boolean;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showMenuButton?: boolean;\n /** Render the built-in collapse toggle in the sidebar footer (desktop). */\n showCollapseButton?: boolean;\n menuLabel?: string;\n closeLabel?: string;\n sidebarLabel?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'div',\n side: 'left',\n sidebarWidth: '17.5rem',\n collapsedWidth: '4.75rem',\n collapsible: false,\n collapsed: undefined,\n defaultCollapsed: false,\n mobile: undefined,\n breakpoint: '768px',\n sidebarOpen: undefined,\n defaultSidebarOpen: false,\n closeOnEscape: true,\n closeOnOverlay: true,\n showMenuButton: true,\n showCollapseButton: true,\n menuLabel: 'Open menu',\n closeLabel: 'Close menu',\n sidebarLabel: 'Sidebar',\n collapseLabel: 'Collapse sidebar',\n expandLabel: 'Expand sidebar',\n },\n);\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean];\n 'collapse-change': [value: boolean];\n 'update:sidebarOpen': [value: boolean];\n 'sidebar-open-change': [value: boolean];\n}>();\n\nexport interface AppShellSlotProps {\n mobile: boolean;\n collapsed: boolean;\n sidebarOpen: boolean;\n toggleSidebar: () => void;\n closeSidebar: () => void;\n toggleCollapsed: () => void;\n}\n\ndefineSlots<{\n header?: (props: AppShellSlotProps) => unknown;\n /** Header region over the sidebar rail; the `header` slot then aligns with the content panel. */\n 'header-start'?: (props: AppShellSlotProps) => unknown;\n /** Pinned above the sidebar body, inset to line up with nav item icons. */\n 'sidebar-header'?: (props: AppShellSlotProps) => unknown;\n sidebar?: (props: AppShellSlotProps) => unknown;\n /** Pinned to the bottom of the sidebar, inset to line up with nav item icons. */\n 'sidebar-footer'?: (props: AppShellSlotProps) => unknown;\n default?: (props: Pick<AppShellSlotProps, 'mobile' | 'collapsed'>) => unknown;\n 'menu-icon'?: (props: { sidebarOpen: boolean }) => unknown;\n 'collapse-icon'?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst sidebarId = createId('t-app-shell-sidebar');\n\nconst { value: isCollapsed, setValue: setCollapsed } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst { value: isSidebarOpen, setValue: setSidebarOpen } = useControllableOpen(\n toRef(props, 'sidebarOpen'),\n props.defaultSidebarOpen,\n (value) => {\n emit('update:sidebarOpen', value);\n emit('sidebar-open-change', value);\n },\n);\n\n// Auto responsive detection when `mobile` is not explicitly controlled.\nconst autoMobile = ref(false);\nlet mediaQuery: MediaQueryList | null = null;\n\nconst onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {\n autoMobile.value = event.matches;\n};\n\nconst setupMediaQuery = () => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n\n teardownMediaQuery();\n mediaQuery = window.matchMedia(`(max-width: ${props.breakpoint})`);\n autoMobile.value = mediaQuery.matches;\n mediaQuery.addEventListener?.('change', onMediaChange);\n};\n\nconst teardownMediaQuery = () => {\n mediaQuery?.removeEventListener?.('change', onMediaChange);\n mediaQuery = null;\n};\n\nconst isMobile = computed(() => props.mobile ?? autoMobile.value);\n\n// Collapsing is desktop-only, so the built-in toggle follows the same rule.\nconst showCollapseToggle = computed(\n () => !isMobile.value && props.collapsible && props.showCollapseButton,\n);\n\n// Collapse is a desktop-only concept; the mobile drawer always shows the\n// expanded sidebar, so descendants and slots see `collapsed: false` there.\nconst effectiveCollapsed = computed(() =>\n isMobile.value ? false : isCollapsed.value,\n);\n\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nlet previousBodyOverflow = '';\nlet bodyLocked = false;\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined' || bodyLocked) {\n return;\n }\n\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n bodyLocked = true;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || !bodyLocked) {\n return;\n }\n\n document.body.style.overflow = previousBodyOverflow;\n bodyLocked = false;\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openSidebar = () => {\n previousFocusedElement.value =\n typeof document === 'undefined'\n ? null\n : (document.activeElement as HTMLElement | null);\n setSidebarOpen(true);\n};\n\nconst closeSidebar = () => {\n setSidebarOpen(false);\n};\n\nconst toggleSidebar = () => {\n if (isSidebarOpen.value) {\n closeSidebar();\n } else {\n openSidebar();\n }\n};\n\nconst toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setCollapsed(!isCollapsed.value);\n};\n\nconst onOverlayClick = () => {\n if (props.closeOnOverlay) {\n closeSidebar();\n }\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeSidebar();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\n// The off-canvas drawer only exists in mobile mode; keep body-scroll lock and\n// focus handling in sync with both the open flag and the responsive mode.\nconst syncOverlayState = (open: boolean, wasOpen: boolean) => {\n if (open && isMobile.value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (wasOpen) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n};\n\nwatch(isSidebarOpen, (value, previousValue) => {\n syncOverlayState(value, Boolean(previousValue));\n});\n\nwatch(isMobile, (mobile) => {\n if (!isSidebarOpen.value) {\n return;\n }\n\n // Leaving mobile removes the drawer from the DOM, so release the lock and\n // restore focus; re-entering mobile while \"open\" re-arms the overlay.\n if (mobile) {\n lockBodyScroll();\n focusSurface();\n } else {\n unlockBodyScroll();\n }\n});\n\nwatch(\n () => props.breakpoint,\n () => {\n if (typeof window !== 'undefined') {\n setupMediaQuery();\n }\n },\n);\n\nonMounted(() => {\n setupMediaQuery();\n});\n\nonBeforeUnmount(() => {\n teardownMediaQuery();\n unlockBodyScroll();\n});\n\nprovide(treeSidebarInjectionKey, {\n collapsed: effectiveCollapsed,\n});\n\nconst rootClasses = computed(() => [\n 't-app-shell',\n `t-app-shell--${props.side}`,\n {\n 'is-mobile': isMobile.value,\n 'is-collapsed':\n !isMobile.value && props.collapsible && isCollapsed.value,\n 'is-sidebar-open': isMobile.value && isSidebarOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-app-shell-sidebar-width': props.sidebarWidth,\n '--tree-app-shell-collapsed-width': props.collapsedWidth,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst slotProps = computed<AppShellSlotProps>(() => ({\n mobile: isMobile.value,\n collapsed: effectiveCollapsed.value,\n sidebarOpen: isSidebarOpen.value,\n toggleSidebar,\n closeSidebar,\n toggleCollapsed,\n}));\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-mobile=\"isMobile ? 'true' : 'false'\"\n >\n <header\n class=\"t-app-shell__header\"\n :class=\"{ 'has-start': Boolean($slots['header-start']) }\"\n >\n <button\n v-if=\"isMobile && showMenuButton\"\n type=\"button\"\n class=\"t-app-shell__menu-button\"\n :aria-label=\"menuLabel\"\n :aria-expanded=\"isSidebarOpen\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleSidebar\"\n >\n <slot\n name=\"menu-icon\"\n :sidebar-open=\"isSidebarOpen\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"6\"\n y2=\"6\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"12\"\n y2=\"12\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </button>\n\n <div\n v-if=\"$slots['header-start']\"\n class=\"t-app-shell__header-start\"\n >\n <slot\n name=\"header-start\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__header-content\">\n <slot\n name=\"header\"\n v-bind=\"slotProps\"\n />\n </div>\n </header>\n\n <aside\n v-if=\"!isMobile\"\n :id=\"sidebarId\"\n class=\"t-app-shell__sidebar\"\n :aria-label=\"sidebarLabel\"\n >\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer'] || showCollapseToggle\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n\n <button\n v-if=\"showCollapseToggle\"\n type=\"button\"\n class=\"t-app-shell__collapse-button\"\n :aria-label=\"isCollapsed ? expandLabel : collapseLabel\"\n :aria-expanded=\"!isCollapsed\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"collapse-icon\"\n :collapsed=\"effectiveCollapsed\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"3\"\n y=\"3\"\n width=\"18\"\n height=\"18\"\n rx=\"2\"\n />\n <path d=\"M9 3v18\" />\n </svg>\n </slot>\n </button>\n </div>\n </aside>\n\n <main class=\"t-app-shell__main\">\n <slot\n :mobile=\"isMobile\"\n :collapsed=\"effectiveCollapsed\"\n />\n </main>\n\n <transition name=\"t-app-shell-fade\">\n <div\n v-if=\"isMobile && isSidebarOpen\"\n class=\"t-app-shell__overlay\"\n >\n <div\n class=\"t-app-shell__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <aside\n :id=\"sidebarId\"\n ref=\"surfaceRef\"\n class=\"t-app-shell__drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"sidebarLabel\"\n tabindex=\"-1\"\n @keydown=\"onKeydown\"\n >\n <div class=\"t-app-shell__drawer-topbar\">\n <button\n type=\"button\"\n class=\"t-app-shell__drawer-close\"\n :aria-label=\"closeLabel\"\n @click=\"closeSidebar\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n <div class=\"t-app-shell__drawer-body\">\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer']\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n </div>\n </div>\n </aside>\n </div>\n </transition>\n </component>\n</template>\n"],"mappings":"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"}
|
|
@@ -92,7 +92,7 @@ var S = [
|
|
|
92
92
|
"sidebar-open-change"
|
|
93
93
|
],
|
|
94
94
|
setup(l, { emit: E }) {
|
|
95
|
-
let D = ue("x"), O = l, k = E, A = ae(), j = oe("t-app-shell-sidebar"), { value: M, setValue: Te } = e(_(O, "collapsed"), O.defaultCollapsed, (e) => {
|
|
95
|
+
let D = r(() => ue("x")), O = l, k = E, A = ae(), j = oe("t-app-shell-sidebar"), { value: M, setValue: Te } = e(_(O, "collapsed"), O.defaultCollapsed, (e) => {
|
|
96
96
|
k("update:collapsed", e), k("collapse-change", e);
|
|
97
97
|
}), { value: N, setValue: P } = e(_(O, "sidebarOpen"), O.defaultSidebarOpen, (e) => {
|
|
98
98
|
k("update:sidebarOpen", e), k("sidebar-open-change", e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TAppShell.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSidebarSide } from './TSidebar.vue';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = getTreeIcon('x');\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n side?: TSidebarSide;\n sidebarWidth?: string;\n collapsedWidth?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n mobile?: boolean;\n breakpoint?: string;\n sidebarOpen?: boolean;\n defaultSidebarOpen?: boolean;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showMenuButton?: boolean;\n /** Render the built-in collapse toggle in the sidebar footer (desktop). */\n showCollapseButton?: boolean;\n menuLabel?: string;\n closeLabel?: string;\n sidebarLabel?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'div',\n side: 'left',\n sidebarWidth: '17.5rem',\n collapsedWidth: '4.75rem',\n collapsible: false,\n collapsed: undefined,\n defaultCollapsed: false,\n mobile: undefined,\n breakpoint: '768px',\n sidebarOpen: undefined,\n defaultSidebarOpen: false,\n closeOnEscape: true,\n closeOnOverlay: true,\n showMenuButton: true,\n showCollapseButton: true,\n menuLabel: 'Open menu',\n closeLabel: 'Close menu',\n sidebarLabel: 'Sidebar',\n collapseLabel: 'Collapse sidebar',\n expandLabel: 'Expand sidebar',\n },\n);\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean];\n 'collapse-change': [value: boolean];\n 'update:sidebarOpen': [value: boolean];\n 'sidebar-open-change': [value: boolean];\n}>();\n\nexport interface AppShellSlotProps {\n mobile: boolean;\n collapsed: boolean;\n sidebarOpen: boolean;\n toggleSidebar: () => void;\n closeSidebar: () => void;\n toggleCollapsed: () => void;\n}\n\ndefineSlots<{\n header?: (props: AppShellSlotProps) => unknown;\n /** Header region over the sidebar rail; the `header` slot then aligns with the content panel. */\n 'header-start'?: (props: AppShellSlotProps) => unknown;\n /** Pinned above the sidebar body, inset to line up with nav item icons. */\n 'sidebar-header'?: (props: AppShellSlotProps) => unknown;\n sidebar?: (props: AppShellSlotProps) => unknown;\n /** Pinned to the bottom of the sidebar, inset to line up with nav item icons. */\n 'sidebar-footer'?: (props: AppShellSlotProps) => unknown;\n default?: (props: Pick<AppShellSlotProps, 'mobile' | 'collapsed'>) => unknown;\n 'menu-icon'?: (props: { sidebarOpen: boolean }) => unknown;\n 'collapse-icon'?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst sidebarId = createId('t-app-shell-sidebar');\n\nconst { value: isCollapsed, setValue: setCollapsed } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst { value: isSidebarOpen, setValue: setSidebarOpen } = useControllableOpen(\n toRef(props, 'sidebarOpen'),\n props.defaultSidebarOpen,\n (value) => {\n emit('update:sidebarOpen', value);\n emit('sidebar-open-change', value);\n },\n);\n\n// Auto responsive detection when `mobile` is not explicitly controlled.\nconst autoMobile = ref(false);\nlet mediaQuery: MediaQueryList | null = null;\n\nconst onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {\n autoMobile.value = event.matches;\n};\n\nconst setupMediaQuery = () => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n\n teardownMediaQuery();\n mediaQuery = window.matchMedia(`(max-width: ${props.breakpoint})`);\n autoMobile.value = mediaQuery.matches;\n mediaQuery.addEventListener?.('change', onMediaChange);\n};\n\nconst teardownMediaQuery = () => {\n mediaQuery?.removeEventListener?.('change', onMediaChange);\n mediaQuery = null;\n};\n\nconst isMobile = computed(() => props.mobile ?? autoMobile.value);\n\n// Collapsing is desktop-only, so the built-in toggle follows the same rule.\nconst showCollapseToggle = computed(\n () => !isMobile.value && props.collapsible && props.showCollapseButton,\n);\n\n// Collapse is a desktop-only concept; the mobile drawer always shows the\n// expanded sidebar, so descendants and slots see `collapsed: false` there.\nconst effectiveCollapsed = computed(() =>\n isMobile.value ? false : isCollapsed.value,\n);\n\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nlet previousBodyOverflow = '';\nlet bodyLocked = false;\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined' || bodyLocked) {\n return;\n }\n\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n bodyLocked = true;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || !bodyLocked) {\n return;\n }\n\n document.body.style.overflow = previousBodyOverflow;\n bodyLocked = false;\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openSidebar = () => {\n previousFocusedElement.value =\n typeof document === 'undefined'\n ? null\n : (document.activeElement as HTMLElement | null);\n setSidebarOpen(true);\n};\n\nconst closeSidebar = () => {\n setSidebarOpen(false);\n};\n\nconst toggleSidebar = () => {\n if (isSidebarOpen.value) {\n closeSidebar();\n } else {\n openSidebar();\n }\n};\n\nconst toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setCollapsed(!isCollapsed.value);\n};\n\nconst onOverlayClick = () => {\n if (props.closeOnOverlay) {\n closeSidebar();\n }\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeSidebar();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\n// The off-canvas drawer only exists in mobile mode; keep body-scroll lock and\n// focus handling in sync with both the open flag and the responsive mode.\nconst syncOverlayState = (open: boolean, wasOpen: boolean) => {\n if (open && isMobile.value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (wasOpen) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n};\n\nwatch(isSidebarOpen, (value, previousValue) => {\n syncOverlayState(value, Boolean(previousValue));\n});\n\nwatch(isMobile, (mobile) => {\n if (!isSidebarOpen.value) {\n return;\n }\n\n // Leaving mobile removes the drawer from the DOM, so release the lock and\n // restore focus; re-entering mobile while \"open\" re-arms the overlay.\n if (mobile) {\n lockBodyScroll();\n focusSurface();\n } else {\n unlockBodyScroll();\n }\n});\n\nwatch(\n () => props.breakpoint,\n () => {\n if (typeof window !== 'undefined') {\n setupMediaQuery();\n }\n },\n);\n\nonMounted(() => {\n setupMediaQuery();\n});\n\nonBeforeUnmount(() => {\n teardownMediaQuery();\n unlockBodyScroll();\n});\n\nprovide(treeSidebarInjectionKey, {\n collapsed: effectiveCollapsed,\n});\n\nconst rootClasses = computed(() => [\n 't-app-shell',\n `t-app-shell--${props.side}`,\n {\n 'is-mobile': isMobile.value,\n 'is-collapsed':\n !isMobile.value && props.collapsible && isCollapsed.value,\n 'is-sidebar-open': isMobile.value && isSidebarOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-app-shell-sidebar-width': props.sidebarWidth,\n '--tree-app-shell-collapsed-width': props.collapsedWidth,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst slotProps = computed<AppShellSlotProps>(() => ({\n mobile: isMobile.value,\n collapsed: effectiveCollapsed.value,\n sidebarOpen: isSidebarOpen.value,\n toggleSidebar,\n closeSidebar,\n toggleCollapsed,\n}));\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-mobile=\"isMobile ? 'true' : 'false'\"\n >\n <header\n class=\"t-app-shell__header\"\n :class=\"{ 'has-start': Boolean($slots['header-start']) }\"\n >\n <button\n v-if=\"isMobile && showMenuButton\"\n type=\"button\"\n class=\"t-app-shell__menu-button\"\n :aria-label=\"menuLabel\"\n :aria-expanded=\"isSidebarOpen\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleSidebar\"\n >\n <slot\n name=\"menu-icon\"\n :sidebar-open=\"isSidebarOpen\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"6\"\n y2=\"6\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"12\"\n y2=\"12\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </button>\n\n <div\n v-if=\"$slots['header-start']\"\n class=\"t-app-shell__header-start\"\n >\n <slot\n name=\"header-start\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__header-content\">\n <slot\n name=\"header\"\n v-bind=\"slotProps\"\n />\n </div>\n </header>\n\n <aside\n v-if=\"!isMobile\"\n :id=\"sidebarId\"\n class=\"t-app-shell__sidebar\"\n :aria-label=\"sidebarLabel\"\n >\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer'] || showCollapseToggle\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n\n <button\n v-if=\"showCollapseToggle\"\n type=\"button\"\n class=\"t-app-shell__collapse-button\"\n :aria-label=\"isCollapsed ? expandLabel : collapseLabel\"\n :aria-expanded=\"!isCollapsed\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"collapse-icon\"\n :collapsed=\"effectiveCollapsed\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"3\"\n y=\"3\"\n width=\"18\"\n height=\"18\"\n rx=\"2\"\n />\n <path d=\"M9 3v18\" />\n </svg>\n </slot>\n </button>\n </div>\n </aside>\n\n <main class=\"t-app-shell__main\">\n <slot\n :mobile=\"isMobile\"\n :collapsed=\"effectiveCollapsed\"\n />\n </main>\n\n <transition name=\"t-app-shell-fade\">\n <div\n v-if=\"isMobile && isSidebarOpen\"\n class=\"t-app-shell__overlay\"\n >\n <div\n class=\"t-app-shell__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <aside\n :id=\"sidebarId\"\n ref=\"surfaceRef\"\n class=\"t-app-shell__drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"sidebarLabel\"\n tabindex=\"-1\"\n @keydown=\"onKeydown\"\n >\n <div class=\"t-app-shell__drawer-topbar\">\n <button\n type=\"button\"\n class=\"t-app-shell__drawer-close\"\n :aria-label=\"closeLabel\"\n @click=\"closeSidebar\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n <div class=\"t-app-shell__drawer-body\">\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer']\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n </div>\n </div>\n </aside>\n </div>\n </transition>\n </component>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TAppShell.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../src/components/TAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSidebarSide } from './TSidebar.vue';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = computed(() => getTreeIcon('x'));\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n side?: TSidebarSide;\n sidebarWidth?: string;\n collapsedWidth?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n mobile?: boolean;\n breakpoint?: string;\n sidebarOpen?: boolean;\n defaultSidebarOpen?: boolean;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showMenuButton?: boolean;\n /** Render the built-in collapse toggle in the sidebar footer (desktop). */\n showCollapseButton?: boolean;\n menuLabel?: string;\n closeLabel?: string;\n sidebarLabel?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'div',\n side: 'left',\n sidebarWidth: '17.5rem',\n collapsedWidth: '4.75rem',\n collapsible: false,\n collapsed: undefined,\n defaultCollapsed: false,\n mobile: undefined,\n breakpoint: '768px',\n sidebarOpen: undefined,\n defaultSidebarOpen: false,\n closeOnEscape: true,\n closeOnOverlay: true,\n showMenuButton: true,\n showCollapseButton: true,\n menuLabel: 'Open menu',\n closeLabel: 'Close menu',\n sidebarLabel: 'Sidebar',\n collapseLabel: 'Collapse sidebar',\n expandLabel: 'Expand sidebar',\n },\n);\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean];\n 'collapse-change': [value: boolean];\n 'update:sidebarOpen': [value: boolean];\n 'sidebar-open-change': [value: boolean];\n}>();\n\nexport interface AppShellSlotProps {\n mobile: boolean;\n collapsed: boolean;\n sidebarOpen: boolean;\n toggleSidebar: () => void;\n closeSidebar: () => void;\n toggleCollapsed: () => void;\n}\n\ndefineSlots<{\n header?: (props: AppShellSlotProps) => unknown;\n /** Header region over the sidebar rail; the `header` slot then aligns with the content panel. */\n 'header-start'?: (props: AppShellSlotProps) => unknown;\n /** Pinned above the sidebar body, inset to line up with nav item icons. */\n 'sidebar-header'?: (props: AppShellSlotProps) => unknown;\n sidebar?: (props: AppShellSlotProps) => unknown;\n /** Pinned to the bottom of the sidebar, inset to line up with nav item icons. */\n 'sidebar-footer'?: (props: AppShellSlotProps) => unknown;\n default?: (props: Pick<AppShellSlotProps, 'mobile' | 'collapsed'>) => unknown;\n 'menu-icon'?: (props: { sidebarOpen: boolean }) => unknown;\n 'collapse-icon'?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst sidebarId = createId('t-app-shell-sidebar');\n\nconst { value: isCollapsed, setValue: setCollapsed } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst { value: isSidebarOpen, setValue: setSidebarOpen } = useControllableOpen(\n toRef(props, 'sidebarOpen'),\n props.defaultSidebarOpen,\n (value) => {\n emit('update:sidebarOpen', value);\n emit('sidebar-open-change', value);\n },\n);\n\n// Auto responsive detection when `mobile` is not explicitly controlled.\nconst autoMobile = ref(false);\nlet mediaQuery: MediaQueryList | null = null;\n\nconst onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {\n autoMobile.value = event.matches;\n};\n\nconst setupMediaQuery = () => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n\n teardownMediaQuery();\n mediaQuery = window.matchMedia(`(max-width: ${props.breakpoint})`);\n autoMobile.value = mediaQuery.matches;\n mediaQuery.addEventListener?.('change', onMediaChange);\n};\n\nconst teardownMediaQuery = () => {\n mediaQuery?.removeEventListener?.('change', onMediaChange);\n mediaQuery = null;\n};\n\nconst isMobile = computed(() => props.mobile ?? autoMobile.value);\n\n// Collapsing is desktop-only, so the built-in toggle follows the same rule.\nconst showCollapseToggle = computed(\n () => !isMobile.value && props.collapsible && props.showCollapseButton,\n);\n\n// Collapse is a desktop-only concept; the mobile drawer always shows the\n// expanded sidebar, so descendants and slots see `collapsed: false` there.\nconst effectiveCollapsed = computed(() =>\n isMobile.value ? false : isCollapsed.value,\n);\n\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nlet previousBodyOverflow = '';\nlet bodyLocked = false;\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined' || bodyLocked) {\n return;\n }\n\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n bodyLocked = true;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || !bodyLocked) {\n return;\n }\n\n document.body.style.overflow = previousBodyOverflow;\n bodyLocked = false;\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openSidebar = () => {\n previousFocusedElement.value =\n typeof document === 'undefined'\n ? null\n : (document.activeElement as HTMLElement | null);\n setSidebarOpen(true);\n};\n\nconst closeSidebar = () => {\n setSidebarOpen(false);\n};\n\nconst toggleSidebar = () => {\n if (isSidebarOpen.value) {\n closeSidebar();\n } else {\n openSidebar();\n }\n};\n\nconst toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setCollapsed(!isCollapsed.value);\n};\n\nconst onOverlayClick = () => {\n if (props.closeOnOverlay) {\n closeSidebar();\n }\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeSidebar();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\n// The off-canvas drawer only exists in mobile mode; keep body-scroll lock and\n// focus handling in sync with both the open flag and the responsive mode.\nconst syncOverlayState = (open: boolean, wasOpen: boolean) => {\n if (open && isMobile.value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (wasOpen) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n};\n\nwatch(isSidebarOpen, (value, previousValue) => {\n syncOverlayState(value, Boolean(previousValue));\n});\n\nwatch(isMobile, (mobile) => {\n if (!isSidebarOpen.value) {\n return;\n }\n\n // Leaving mobile removes the drawer from the DOM, so release the lock and\n // restore focus; re-entering mobile while \"open\" re-arms the overlay.\n if (mobile) {\n lockBodyScroll();\n focusSurface();\n } else {\n unlockBodyScroll();\n }\n});\n\nwatch(\n () => props.breakpoint,\n () => {\n if (typeof window !== 'undefined') {\n setupMediaQuery();\n }\n },\n);\n\nonMounted(() => {\n setupMediaQuery();\n});\n\nonBeforeUnmount(() => {\n teardownMediaQuery();\n unlockBodyScroll();\n});\n\nprovide(treeSidebarInjectionKey, {\n collapsed: effectiveCollapsed,\n});\n\nconst rootClasses = computed(() => [\n 't-app-shell',\n `t-app-shell--${props.side}`,\n {\n 'is-mobile': isMobile.value,\n 'is-collapsed':\n !isMobile.value && props.collapsible && isCollapsed.value,\n 'is-sidebar-open': isMobile.value && isSidebarOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-app-shell-sidebar-width': props.sidebarWidth,\n '--tree-app-shell-collapsed-width': props.collapsedWidth,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst slotProps = computed<AppShellSlotProps>(() => ({\n mobile: isMobile.value,\n collapsed: effectiveCollapsed.value,\n sidebarOpen: isSidebarOpen.value,\n toggleSidebar,\n closeSidebar,\n toggleCollapsed,\n}));\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-mobile=\"isMobile ? 'true' : 'false'\"\n >\n <header\n class=\"t-app-shell__header\"\n :class=\"{ 'has-start': Boolean($slots['header-start']) }\"\n >\n <button\n v-if=\"isMobile && showMenuButton\"\n type=\"button\"\n class=\"t-app-shell__menu-button\"\n :aria-label=\"menuLabel\"\n :aria-expanded=\"isSidebarOpen\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleSidebar\"\n >\n <slot\n name=\"menu-icon\"\n :sidebar-open=\"isSidebarOpen\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"6\"\n y2=\"6\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"12\"\n y2=\"12\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </button>\n\n <div\n v-if=\"$slots['header-start']\"\n class=\"t-app-shell__header-start\"\n >\n <slot\n name=\"header-start\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__header-content\">\n <slot\n name=\"header\"\n v-bind=\"slotProps\"\n />\n </div>\n </header>\n\n <aside\n v-if=\"!isMobile\"\n :id=\"sidebarId\"\n class=\"t-app-shell__sidebar\"\n :aria-label=\"sidebarLabel\"\n >\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer'] || showCollapseToggle\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n\n <button\n v-if=\"showCollapseToggle\"\n type=\"button\"\n class=\"t-app-shell__collapse-button\"\n :aria-label=\"isCollapsed ? expandLabel : collapseLabel\"\n :aria-expanded=\"!isCollapsed\"\n :aria-controls=\"sidebarId\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"collapse-icon\"\n :collapsed=\"effectiveCollapsed\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"3\"\n y=\"3\"\n width=\"18\"\n height=\"18\"\n rx=\"2\"\n />\n <path d=\"M9 3v18\" />\n </svg>\n </slot>\n </button>\n </div>\n </aside>\n\n <main class=\"t-app-shell__main\">\n <slot\n :mobile=\"isMobile\"\n :collapsed=\"effectiveCollapsed\"\n />\n </main>\n\n <transition name=\"t-app-shell-fade\">\n <div\n v-if=\"isMobile && isSidebarOpen\"\n class=\"t-app-shell__overlay\"\n >\n <div\n class=\"t-app-shell__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <aside\n :id=\"sidebarId\"\n ref=\"surfaceRef\"\n class=\"t-app-shell__drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"sidebarLabel\"\n tabindex=\"-1\"\n @keydown=\"onKeydown\"\n >\n <div class=\"t-app-shell__drawer-topbar\">\n <button\n type=\"button\"\n class=\"t-app-shell__drawer-close\"\n :aria-label=\"closeLabel\"\n @click=\"closeSidebar\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n <div class=\"t-app-shell__drawer-body\">\n <div\n v-if=\"$slots['sidebar-header']\"\n class=\"t-app-shell__sidebar-header\"\n >\n <slot\n name=\"sidebar-header\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div class=\"t-app-shell__sidebar-body\">\n <slot\n name=\"sidebar\"\n v-bind=\"slotProps\"\n />\n </div>\n\n <div\n v-if=\"$slots['sidebar-footer']\"\n class=\"t-app-shell__sidebar-footer\"\n >\n <slot\n name=\"sidebar-footer\"\n v-bind=\"slotProps\"\n />\n </div>\n </div>\n </aside>\n </div>\n </transition>\n </component>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TDatePicker.cjs","names":[],"sources":["../../src/components/TDatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n parseDateValue,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\nconst CalendarIcon = getTreeIcon('calendar');\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: 'Select date',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst today = startOfDay(new Date());\nconst selectedDate = computed(() => parseDateValue(props.modelValue));\nconst minDate = computed(() => parseDateValue(props.min));\nconst maxDate = computed(() => parseDateValue(props.max));\nconst calendarId = props.id ?? createId('t-date-picker');\nconst captionId = `${calendarId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\nconst viewMonth = ref(startOfMonth(selectedDate.value ?? today));\nconst focusedDate = ref<Date>(selectedDate.value ?? today);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDate.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(selectedDate.value);\n});\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDate.value && date < minDate.value) {\n return true;\n }\n\n if (maxDate.value && date > maxDate.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nwatch(\n selectedDate,\n (value) => {\n if (value) {\n syncCalendarView(value);\n return;\n }\n\n if (!isOpen.value) {\n syncCalendarView(today);\n }\n },\n { immediate: true },\n);\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, selectedDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDate.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDate.value);\n});\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncCalendarView(selectedDate.value ?? focusedDate.value ?? today);\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const normalizedDate = startOfDay(date);\n const value = toDateValue(normalizedDate);\n\n syncCalendarView(normalizedDate);\n emit('update:modelValue', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? calendarId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDate ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <CalendarIcon v-bind=\"treeIconDefaults\" />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"calendarId\"\n class=\"t-date-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :disabled=\"cell.disabled\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.key\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </transition>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"TDatePicker.cjs","names":[],"sources":["../../src/components/TDatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n parseDateValue,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\nconst CalendarIcon = computed(() => getTreeIcon('calendar'));\nconst ChevronLeftIcon = computed(() => getTreeIcon('chevron-left'));\nconst ChevronRightIcon = computed(() => getTreeIcon('chevron-right'));\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: 'Select date',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst today = startOfDay(new Date());\nconst selectedDate = computed(() => parseDateValue(props.modelValue));\nconst minDate = computed(() => parseDateValue(props.min));\nconst maxDate = computed(() => parseDateValue(props.max));\nconst calendarId = props.id ?? createId('t-date-picker');\nconst captionId = `${calendarId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\nconst viewMonth = ref(startOfMonth(selectedDate.value ?? today));\nconst focusedDate = ref<Date>(selectedDate.value ?? today);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDate.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(selectedDate.value);\n});\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDate.value && date < minDate.value) {\n return true;\n }\n\n if (maxDate.value && date > maxDate.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nwatch(\n selectedDate,\n (value) => {\n if (value) {\n syncCalendarView(value);\n return;\n }\n\n if (!isOpen.value) {\n syncCalendarView(today);\n }\n },\n { immediate: true },\n);\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, selectedDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDate.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDate.value);\n});\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncCalendarView(selectedDate.value ?? focusedDate.value ?? today);\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const normalizedDate = startOfDay(date);\n const value = toDateValue(normalizedDate);\n\n syncCalendarView(normalizedDate);\n emit('update:modelValue', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? calendarId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDate ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <CalendarIcon v-bind=\"treeIconDefaults\" />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"calendarId\"\n class=\"t-date-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :disabled=\"cell.disabled\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.key\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </transition>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TDatePicker.js","names":[],"sources":["../../src/components/TDatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n parseDateValue,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\nconst CalendarIcon = getTreeIcon('calendar');\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: 'Select date',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst today = startOfDay(new Date());\nconst selectedDate = computed(() => parseDateValue(props.modelValue));\nconst minDate = computed(() => parseDateValue(props.min));\nconst maxDate = computed(() => parseDateValue(props.max));\nconst calendarId = props.id ?? createId('t-date-picker');\nconst captionId = `${calendarId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\nconst viewMonth = ref(startOfMonth(selectedDate.value ?? today));\nconst focusedDate = ref<Date>(selectedDate.value ?? today);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDate.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(selectedDate.value);\n});\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDate.value && date < minDate.value) {\n return true;\n }\n\n if (maxDate.value && date > maxDate.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nwatch(\n selectedDate,\n (value) => {\n if (value) {\n syncCalendarView(value);\n return;\n }\n\n if (!isOpen.value) {\n syncCalendarView(today);\n }\n },\n { immediate: true },\n);\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, selectedDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDate.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDate.value);\n});\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncCalendarView(selectedDate.value ?? focusedDate.value ?? today);\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const normalizedDate = startOfDay(date);\n const value = toDateValue(normalizedDate);\n\n syncCalendarView(normalizedDate);\n emit('update:modelValue', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? calendarId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDate ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <CalendarIcon v-bind=\"treeIconDefaults\" />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"calendarId\"\n class=\"t-date-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :disabled=\"cell.disabled\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.key\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </transition>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"TDatePicker.js","names":[],"sources":["../../src/components/TDatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n parseDateValue,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\nconst CalendarIcon = computed(() => getTreeIcon('calendar'));\nconst ChevronLeftIcon = computed(() => getTreeIcon('chevron-left'));\nconst ChevronRightIcon = computed(() => getTreeIcon('chevron-right'));\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: 'Select date',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst today = startOfDay(new Date());\nconst selectedDate = computed(() => parseDateValue(props.modelValue));\nconst minDate = computed(() => parseDateValue(props.min));\nconst maxDate = computed(() => parseDateValue(props.max));\nconst calendarId = props.id ?? createId('t-date-picker');\nconst captionId = `${calendarId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\nconst viewMonth = ref(startOfMonth(selectedDate.value ?? today));\nconst focusedDate = ref<Date>(selectedDate.value ?? today);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDate.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(selectedDate.value);\n});\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDate.value && date < minDate.value) {\n return true;\n }\n\n if (maxDate.value && date > maxDate.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nwatch(\n selectedDate,\n (value) => {\n if (value) {\n syncCalendarView(value);\n return;\n }\n\n if (!isOpen.value) {\n syncCalendarView(today);\n }\n },\n { immediate: true },\n);\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, selectedDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDate.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDate.value);\n});\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncCalendarView(selectedDate.value ?? focusedDate.value ?? today);\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const normalizedDate = startOfDay(date);\n const value = toDateValue(normalizedDate);\n\n syncCalendarView(normalizedDate);\n emit('update:modelValue', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? calendarId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDate ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <CalendarIcon v-bind=\"treeIconDefaults\" />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"calendarId\"\n class=\"t-date-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :disabled=\"cell.disabled\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.key\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </transition>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../composables/useControllableOpen.cjs");let t=require("vue"),n=require("@treeui/utils"),r=require("@treeui/icons");var i=[`data-state`],a=[`name`,`value`],o=[`disabled`,`aria-controls`,`aria-expanded`,`aria-invalid`],ee={key:0,class:`t-date-picker__slot t-date-picker__slot--prefix`},te=[`data-placeholder`],s={class:`t-date-picker__slot t-date-picker__slot--suffix`},c=[`id`],ne={class:`t-date-picker__header`},l=[`disabled`],u=[`disabled`],d={class:`t-date-picker__weekdays`,"aria-hidden":`true`},re=[`aria-selected`],f=[`data-date`,`disabled`,`tabindex`,`aria-current`,`aria-label`,`onClick`,`onKeydown`],p=(0,t.defineComponent)({inheritAttrs:!1,__name:`TDatePicker`,props:{modelValue:{default:``},open:{type:Boolean,default:void 0},defaultOpen:{type:Boolean,default:!1},size:{default:`md`},disabled:{type:Boolean,default:!1},invalid:{type:Boolean,default:!1},placeholder:{default:`Select date`},locale:{default:`en-US`},min:{default:``},max:{default:``},weekStartsOn:{default:0},id:{default:void 0}},emits:[`update:modelValue`,`update:open`,`open-change`,`select`],setup(p,{emit:m}){let h=(0,r.getTreeIcon)(`calendar`),g=(0,r.getTreeIcon)(`chevron-left`),_=(0,r.getTreeIcon)(`chevron-right`),v=p,y=m,b=(0,t.useAttrs)(),x=(0,n.startOfDay)(new Date),S=(0,t.computed)(()=>(0,n.parseDateValue)(v.modelValue)),C=(0,t.computed)(()=>(0,n.parseDateValue)(v.min)),w=(0,t.computed)(()=>(0,n.parseDateValue)(v.max)),T=v.id??(0,n.createId)(`t-date-picker`),E=`${T}-caption`,D=(0,t.ref)(null),O=(0,t.ref)(null),k=new Map,A=(0,t.ref)((0,n.startOfMonth)(S.value??x)),j=(0,t.ref)(S.value??x),M=(0,t.computed)(()=>{let{class:e,style:t,name:n,...r}=b;return r}),N=(0,t.computed)(()=>typeof b.name==`string`?b.name:void 0),P=(0,t.computed)(()=>[`t-date-picker`,`t-date-picker--${v.size}`,{"is-disabled":v.disabled,"is-invalid":v.invalid,"is-open":I.value},b.class]),F=(0,t.computed)(()=>b.style),{value:I,setValue:L}=e.useControllableOpen((0,t.toRef)(v,`open`),v.defaultOpen,e=>{y(`update:open`,e),y(`open-change`,e)}),R=(0,t.computed)(()=>S.value?new Intl.DateTimeFormat(v.locale,{day:`numeric`,month:`long`,year:`numeric`}).format(S.value):v.placeholder),z=(0,t.computed)(()=>new Intl.DateTimeFormat(v.locale,{month:`long`,year:`numeric`}).format(A.value)),B=(0,t.computed)(()=>{let e=new Intl.DateTimeFormat(v.locale,{weekday:`short`}),t=(0,n.startOfWeek)(new Date(2024,0,7),v.weekStartsOn);return Array.from({length:7},(r,i)=>e.format((0,n.addDays)(t,i)))}),V=e=>!!(v.disabled||C.value&&e<C.value||w.value&&e>w.value),H=e=>{j.value=(0,n.startOfDay)(e),A.value=(0,n.startOfMonth)(e)};(0,t.watch)(S,e=>{if(e){H(e);return}I.value||H(x)},{immediate:!0});let U=(0,t.computed)(()=>{let e=(0,n.startOfWeek)((0,n.startOfMonth)(A.value),v.weekStartsOn);return Array.from({length:6},(t,r)=>Array.from({length:7},(t,i)=>{let a=(0,n.addDays)(e,r*7+i),o=(0,n.toDateValue)(a);return{date:a,dayLabel:a.getDate(),disabled:V(a),inMonth:a.getMonth()===A.value.getMonth(),isFocused:(0,n.isSameDay)(a,j.value),isSelected:(0,n.isSameDay)(a,S.value),isToday:(0,n.isSameDay)(a,x),key:o}}))}),W=(0,t.computed)(()=>!C.value||(0,n.startOfMonth)(A.value)>(0,n.startOfMonth)(C.value)),G=(0,t.computed)(()=>!w.value||(0,n.startOfMonth)(A.value)<(0,n.startOfMonth)(w.value)),K=()=>{let e=(0,n.toDateValue)(j.value);(0,t.nextTick)(()=>{k.get(e)?.focus()})},q=(e,t)=>{if(e instanceof HTMLButtonElement){k.set(t,e);return}k.delete(t)},J=()=>{v.disabled||(H(S.value??j.value??x),L(!0),K())},Y=(e=!1)=>{L(!1),e&&(0,t.nextTick)(()=>{O.value?.focus()})},ie=()=>{if(I.value){Y();return}J()},X=e=>{let t=(0,n.addMonths)(A.value,e);H(t),K()},Z=e=>{V(e)||(H(e),K())},Q=e=>{if(V(e))return;let t=(0,n.startOfDay)(e),r=(0,n.toDateValue)(t);H(t),y(`update:modelValue`,r),y(`select`,r),Y(!0)},ae=e=>{if(!v.disabled){if((0,n.isEscapeKey)(e)&&I.value){e.preventDefault(),Y();return}((0,n.isActivationKey)(e)||e.key===`ArrowDown`||e.key===`ArrowUp`)&&(e.preventDefault(),J())}},oe=(e,t)=>{if((0,n.isEscapeKey)(e)){e.preventDefault(),Y(!0);return}if((0,n.isActivationKey)(e)){e.preventDefault(),Q(t);return}switch(e.key){case`ArrowLeft`:e.preventDefault(),Z((0,n.addDays)(t,-1));break;case`ArrowRight`:e.preventDefault(),Z((0,n.addDays)(t,1));break;case`ArrowUp`:e.preventDefault(),Z((0,n.addDays)(t,-7));break;case`ArrowDown`:e.preventDefault(),Z((0,n.addDays)(t,7));break;case`Home`:e.preventDefault(),Z((0,n.startOfWeek)(t,v.weekStartsOn));break;case`End`:e.preventDefault(),Z((0,n.addDays)((0,n.startOfWeek)(t,v.weekStartsOn),6));break;case`PageUp`:e.preventDefault(),Z((0,n.addMonths)(t,e.shiftKey?-12:-1));break;case`PageDown`:e.preventDefault(),Z((0,n.addMonths)(t,e.shiftKey?12:1));break;default:break}},$=e=>{if(!I.value)return;let t=e.target;t instanceof Node&&(D.value?.contains(t)||Y())};return(0,t.watch)(I,e=>{if(e){document.addEventListener(`pointerdown`,$);return}document.removeEventListener(`pointerdown`,$)}),(0,t.onBeforeUnmount)(()=>{document.removeEventListener(`pointerdown`,$)}),(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{ref_key:`rootRef`,ref:D,class:(0,t.normalizeClass)(P.value),style:(0,t.normalizeStyle)(F.value),"data-state":(0,t.unref)(I)?`open`:`closed`},[N.value?((0,t.openBlock)(),(0,t.createElementBlock)(`input`,{key:0,type:`hidden`,name:N.value,value:p.modelValue},null,8,a)):(0,t.createCommentVNode)(``,!0),(0,t.createElementVNode)(`button`,(0,t.mergeProps)({ref_key:`triggerRef`,ref:O},M.value,{type:`button`,class:`t-date-picker__trigger`,disabled:p.disabled,"aria-controls":(0,t.unref)(I)?(0,t.unref)(T):void 0,"aria-haspopup":`dialog`,"aria-expanded":(0,t.unref)(I),"aria-invalid":p.invalid||void 0,onClick:ie,onKeydown:ae}),[e.$slots.prefix?((0,t.openBlock)(),(0,t.createElementBlock)(`span`,ee,[(0,t.renderSlot)(e.$slots,`prefix`)])):(0,t.createCommentVNode)(``,!0),(0,t.createElementVNode)(`span`,{class:`t-date-picker__value`,"data-placeholder":!S.value||void 0},(0,t.toDisplayString)(R.value),9,te),(0,t.createElementVNode)(`span`,s,[(0,t.renderSlot)(e.$slots,`suffix`,{},()=>[(0,t.createVNode)((0,t.unref)(h),(0,t.normalizeProps)((0,t.guardReactiveProps)((0,t.unref)(r.treeIconDefaults))),null,16)])])],16,o),(0,t.createVNode)(t.Transition,{name:`t-fade`},{default:(0,t.withCtx)(()=>[(0,t.unref)(I)&&!p.disabled?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:0,id:(0,t.unref)(T),class:`t-date-picker__content`,role:`dialog`,"aria-modal":`false`,"aria-labelledby":E},[(0,t.createElementVNode)(`div`,ne,[(0,t.createElementVNode)(`button`,{type:`button`,class:`t-date-picker__nav`,disabled:!W.value,"aria-label":`Previous month`,onClick:n[0]||=e=>X(-1)},[(0,t.createVNode)((0,t.unref)(g),(0,t.normalizeProps)((0,t.guardReactiveProps)((0,t.unref)(r.treeIconDefaults))),null,16)],8,l),(0,t.createElementVNode)(`p`,{id:E,class:`t-date-picker__month`},(0,t.toDisplayString)(z.value),1),(0,t.createElementVNode)(`button`,{type:`button`,class:`t-date-picker__nav`,disabled:!G.value,"aria-label":`Next month`,onClick:n[1]||=e=>X(1)},[(0,t.createVNode)((0,t.unref)(_),(0,t.normalizeProps)((0,t.guardReactiveProps)((0,t.unref)(r.treeIconDefaults))),null,16)],8,u)]),(0,t.createElementVNode)(`div`,d,[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(B.value,e=>((0,t.openBlock)(),(0,t.createElementBlock)(`span`,{key:e,class:`t-date-picker__weekday`},(0,t.toDisplayString)(e),1))),128))]),(0,t.createElementVNode)(`div`,{class:`t-date-picker__grid`,role:`grid`,"aria-labelledby":E},[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(U.value,(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:n,class:`t-date-picker__row`,role:`row`},[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(e,e=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:e.key,class:`t-date-picker__cell`,role:`gridcell`,"aria-selected":e.isSelected},[(0,t.createElementVNode)(`button`,{ref_for:!0,ref:t=>q(t,e.key),type:`button`,class:(0,t.normalizeClass)([`t-date-picker__day`,{"is-muted":!e.inMonth,"is-selected":e.isSelected,"is-today":e.isToday}]),"data-date":e.key,disabled:e.disabled,tabindex:e.isFocused?0:-1,"aria-current":e.isToday?`date`:void 0,"aria-label":e.key,onClick:t=>Q(e.date),onKeydown:t=>oe(t,e.date)},(0,t.toDisplayString)(e.dayLabel),43,f)],8,re))),128))]))),128))])],8,c)):(0,t.createCommentVNode)(``,!0)]),_:1})],14,i))}});exports.default=p;
|
|
1
|
+
const e=require("../composables/useControllableOpen.cjs");let t=require("vue"),n=require("@treeui/utils"),r=require("@treeui/icons");var i=[`data-state`],a=[`name`,`value`],o=[`disabled`,`aria-controls`,`aria-expanded`,`aria-invalid`],ee={key:0,class:`t-date-picker__slot t-date-picker__slot--prefix`},te=[`data-placeholder`],s={class:`t-date-picker__slot t-date-picker__slot--suffix`},c=[`id`],ne={class:`t-date-picker__header`},l=[`disabled`],u=[`disabled`],d={class:`t-date-picker__weekdays`,"aria-hidden":`true`},re=[`aria-selected`],f=[`data-date`,`disabled`,`tabindex`,`aria-current`,`aria-label`,`onClick`,`onKeydown`],p=(0,t.defineComponent)({inheritAttrs:!1,__name:`TDatePicker`,props:{modelValue:{default:``},open:{type:Boolean,default:void 0},defaultOpen:{type:Boolean,default:!1},size:{default:`md`},disabled:{type:Boolean,default:!1},invalid:{type:Boolean,default:!1},placeholder:{default:`Select date`},locale:{default:`en-US`},min:{default:``},max:{default:``},weekStartsOn:{default:0},id:{default:void 0}},emits:[`update:modelValue`,`update:open`,`open-change`,`select`],setup(p,{emit:m}){let h=(0,t.computed)(()=>(0,r.getTreeIcon)(`calendar`)),g=(0,t.computed)(()=>(0,r.getTreeIcon)(`chevron-left`)),_=(0,t.computed)(()=>(0,r.getTreeIcon)(`chevron-right`)),v=p,y=m,b=(0,t.useAttrs)(),x=(0,n.startOfDay)(new Date),S=(0,t.computed)(()=>(0,n.parseDateValue)(v.modelValue)),C=(0,t.computed)(()=>(0,n.parseDateValue)(v.min)),w=(0,t.computed)(()=>(0,n.parseDateValue)(v.max)),T=v.id??(0,n.createId)(`t-date-picker`),E=`${T}-caption`,D=(0,t.ref)(null),O=(0,t.ref)(null),k=new Map,A=(0,t.ref)((0,n.startOfMonth)(S.value??x)),j=(0,t.ref)(S.value??x),M=(0,t.computed)(()=>{let{class:e,style:t,name:n,...r}=b;return r}),N=(0,t.computed)(()=>typeof b.name==`string`?b.name:void 0),P=(0,t.computed)(()=>[`t-date-picker`,`t-date-picker--${v.size}`,{"is-disabled":v.disabled,"is-invalid":v.invalid,"is-open":I.value},b.class]),F=(0,t.computed)(()=>b.style),{value:I,setValue:L}=e.useControllableOpen((0,t.toRef)(v,`open`),v.defaultOpen,e=>{y(`update:open`,e),y(`open-change`,e)}),R=(0,t.computed)(()=>S.value?new Intl.DateTimeFormat(v.locale,{day:`numeric`,month:`long`,year:`numeric`}).format(S.value):v.placeholder),z=(0,t.computed)(()=>new Intl.DateTimeFormat(v.locale,{month:`long`,year:`numeric`}).format(A.value)),B=(0,t.computed)(()=>{let e=new Intl.DateTimeFormat(v.locale,{weekday:`short`}),t=(0,n.startOfWeek)(new Date(2024,0,7),v.weekStartsOn);return Array.from({length:7},(r,i)=>e.format((0,n.addDays)(t,i)))}),V=e=>!!(v.disabled||C.value&&e<C.value||w.value&&e>w.value),H=e=>{j.value=(0,n.startOfDay)(e),A.value=(0,n.startOfMonth)(e)};(0,t.watch)(S,e=>{if(e){H(e);return}I.value||H(x)},{immediate:!0});let U=(0,t.computed)(()=>{let e=(0,n.startOfWeek)((0,n.startOfMonth)(A.value),v.weekStartsOn);return Array.from({length:6},(t,r)=>Array.from({length:7},(t,i)=>{let a=(0,n.addDays)(e,r*7+i),o=(0,n.toDateValue)(a);return{date:a,dayLabel:a.getDate(),disabled:V(a),inMonth:a.getMonth()===A.value.getMonth(),isFocused:(0,n.isSameDay)(a,j.value),isSelected:(0,n.isSameDay)(a,S.value),isToday:(0,n.isSameDay)(a,x),key:o}}))}),W=(0,t.computed)(()=>!C.value||(0,n.startOfMonth)(A.value)>(0,n.startOfMonth)(C.value)),G=(0,t.computed)(()=>!w.value||(0,n.startOfMonth)(A.value)<(0,n.startOfMonth)(w.value)),K=()=>{let e=(0,n.toDateValue)(j.value);(0,t.nextTick)(()=>{k.get(e)?.focus()})},q=(e,t)=>{if(e instanceof HTMLButtonElement){k.set(t,e);return}k.delete(t)},J=()=>{v.disabled||(H(S.value??j.value??x),L(!0),K())},Y=(e=!1)=>{L(!1),e&&(0,t.nextTick)(()=>{O.value?.focus()})},ie=()=>{if(I.value){Y();return}J()},X=e=>{let t=(0,n.addMonths)(A.value,e);H(t),K()},Z=e=>{V(e)||(H(e),K())},Q=e=>{if(V(e))return;let t=(0,n.startOfDay)(e),r=(0,n.toDateValue)(t);H(t),y(`update:modelValue`,r),y(`select`,r),Y(!0)},ae=e=>{if(!v.disabled){if((0,n.isEscapeKey)(e)&&I.value){e.preventDefault(),Y();return}((0,n.isActivationKey)(e)||e.key===`ArrowDown`||e.key===`ArrowUp`)&&(e.preventDefault(),J())}},oe=(e,t)=>{if((0,n.isEscapeKey)(e)){e.preventDefault(),Y(!0);return}if((0,n.isActivationKey)(e)){e.preventDefault(),Q(t);return}switch(e.key){case`ArrowLeft`:e.preventDefault(),Z((0,n.addDays)(t,-1));break;case`ArrowRight`:e.preventDefault(),Z((0,n.addDays)(t,1));break;case`ArrowUp`:e.preventDefault(),Z((0,n.addDays)(t,-7));break;case`ArrowDown`:e.preventDefault(),Z((0,n.addDays)(t,7));break;case`Home`:e.preventDefault(),Z((0,n.startOfWeek)(t,v.weekStartsOn));break;case`End`:e.preventDefault(),Z((0,n.addDays)((0,n.startOfWeek)(t,v.weekStartsOn),6));break;case`PageUp`:e.preventDefault(),Z((0,n.addMonths)(t,e.shiftKey?-12:-1));break;case`PageDown`:e.preventDefault(),Z((0,n.addMonths)(t,e.shiftKey?12:1));break;default:break}},$=e=>{if(!I.value)return;let t=e.target;t instanceof Node&&(D.value?.contains(t)||Y())};return(0,t.watch)(I,e=>{if(e){document.addEventListener(`pointerdown`,$);return}document.removeEventListener(`pointerdown`,$)}),(0,t.onBeforeUnmount)(()=>{document.removeEventListener(`pointerdown`,$)}),(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{ref_key:`rootRef`,ref:D,class:(0,t.normalizeClass)(P.value),style:(0,t.normalizeStyle)(F.value),"data-state":(0,t.unref)(I)?`open`:`closed`},[N.value?((0,t.openBlock)(),(0,t.createElementBlock)(`input`,{key:0,type:`hidden`,name:N.value,value:p.modelValue},null,8,a)):(0,t.createCommentVNode)(``,!0),(0,t.createElementVNode)(`button`,(0,t.mergeProps)({ref_key:`triggerRef`,ref:O},M.value,{type:`button`,class:`t-date-picker__trigger`,disabled:p.disabled,"aria-controls":(0,t.unref)(I)?(0,t.unref)(T):void 0,"aria-haspopup":`dialog`,"aria-expanded":(0,t.unref)(I),"aria-invalid":p.invalid||void 0,onClick:ie,onKeydown:ae}),[e.$slots.prefix?((0,t.openBlock)(),(0,t.createElementBlock)(`span`,ee,[(0,t.renderSlot)(e.$slots,`prefix`)])):(0,t.createCommentVNode)(``,!0),(0,t.createElementVNode)(`span`,{class:`t-date-picker__value`,"data-placeholder":!S.value||void 0},(0,t.toDisplayString)(R.value),9,te),(0,t.createElementVNode)(`span`,s,[(0,t.renderSlot)(e.$slots,`suffix`,{},()=>[(0,t.createVNode)((0,t.unref)(h),(0,t.normalizeProps)((0,t.guardReactiveProps)((0,t.unref)(r.treeIconDefaults))),null,16)])])],16,o),(0,t.createVNode)(t.Transition,{name:`t-fade`},{default:(0,t.withCtx)(()=>[(0,t.unref)(I)&&!p.disabled?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:0,id:(0,t.unref)(T),class:`t-date-picker__content`,role:`dialog`,"aria-modal":`false`,"aria-labelledby":E},[(0,t.createElementVNode)(`div`,ne,[(0,t.createElementVNode)(`button`,{type:`button`,class:`t-date-picker__nav`,disabled:!W.value,"aria-label":`Previous month`,onClick:n[0]||=e=>X(-1)},[(0,t.createVNode)((0,t.unref)(g),(0,t.normalizeProps)((0,t.guardReactiveProps)((0,t.unref)(r.treeIconDefaults))),null,16)],8,l),(0,t.createElementVNode)(`p`,{id:E,class:`t-date-picker__month`},(0,t.toDisplayString)(z.value),1),(0,t.createElementVNode)(`button`,{type:`button`,class:`t-date-picker__nav`,disabled:!G.value,"aria-label":`Next month`,onClick:n[1]||=e=>X(1)},[(0,t.createVNode)((0,t.unref)(_),(0,t.normalizeProps)((0,t.guardReactiveProps)((0,t.unref)(r.treeIconDefaults))),null,16)],8,u)]),(0,t.createElementVNode)(`div`,d,[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(B.value,e=>((0,t.openBlock)(),(0,t.createElementBlock)(`span`,{key:e,class:`t-date-picker__weekday`},(0,t.toDisplayString)(e),1))),128))]),(0,t.createElementVNode)(`div`,{class:`t-date-picker__grid`,role:`grid`,"aria-labelledby":E},[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(U.value,(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:n,class:`t-date-picker__row`,role:`row`},[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(e,e=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:e.key,class:`t-date-picker__cell`,role:`gridcell`,"aria-selected":e.isSelected},[(0,t.createElementVNode)(`button`,{ref_for:!0,ref:t=>q(t,e.key),type:`button`,class:(0,t.normalizeClass)([`t-date-picker__day`,{"is-muted":!e.inMonth,"is-selected":e.isSelected,"is-today":e.isToday}]),"data-date":e.key,disabled:e.disabled,tabindex:e.isFocused?0:-1,"aria-current":e.isToday?`date`:void 0,"aria-label":e.key,onClick:t=>Q(e.date),onKeydown:t=>oe(t,e.date)},(0,t.toDisplayString)(e.dayLabel),43,f)],8,re))),128))]))),128))])],8,c)):(0,t.createCommentVNode)(``,!0)]),_:1})],14,i))}});exports.default=p;
|
|
2
2
|
//# sourceMappingURL=TDatePicker.vue_vue_type_script_setup_true_lang.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TDatePicker.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TDatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n parseDateValue,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\nconst CalendarIcon = getTreeIcon('calendar');\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: 'Select date',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst today = startOfDay(new Date());\nconst selectedDate = computed(() => parseDateValue(props.modelValue));\nconst minDate = computed(() => parseDateValue(props.min));\nconst maxDate = computed(() => parseDateValue(props.max));\nconst calendarId = props.id ?? createId('t-date-picker');\nconst captionId = `${calendarId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\nconst viewMonth = ref(startOfMonth(selectedDate.value ?? today));\nconst focusedDate = ref<Date>(selectedDate.value ?? today);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDate.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(selectedDate.value);\n});\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDate.value && date < minDate.value) {\n return true;\n }\n\n if (maxDate.value && date > maxDate.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nwatch(\n selectedDate,\n (value) => {\n if (value) {\n syncCalendarView(value);\n return;\n }\n\n if (!isOpen.value) {\n syncCalendarView(today);\n }\n },\n { immediate: true },\n);\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, selectedDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDate.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDate.value);\n});\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncCalendarView(selectedDate.value ?? focusedDate.value ?? today);\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const normalizedDate = startOfDay(date);\n const value = toDateValue(normalizedDate);\n\n syncCalendarView(normalizedDate);\n emit('update:modelValue', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? calendarId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDate ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <CalendarIcon v-bind=\"treeIconDefaults\" />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"calendarId\"\n class=\"t-date-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :disabled=\"cell.disabled\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.key\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </transition>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TDatePicker.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TDatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n parseDateValue,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\nconst CalendarIcon = computed(() => getTreeIcon('calendar'));\nconst ChevronLeftIcon = computed(() => getTreeIcon('chevron-left'));\nconst ChevronRightIcon = computed(() => getTreeIcon('chevron-right'));\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: 'Select date',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst today = startOfDay(new Date());\nconst selectedDate = computed(() => parseDateValue(props.modelValue));\nconst minDate = computed(() => parseDateValue(props.min));\nconst maxDate = computed(() => parseDateValue(props.max));\nconst calendarId = props.id ?? createId('t-date-picker');\nconst captionId = `${calendarId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\nconst viewMonth = ref(startOfMonth(selectedDate.value ?? today));\nconst focusedDate = ref<Date>(selectedDate.value ?? today);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDate.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(selectedDate.value);\n});\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDate.value && date < minDate.value) {\n return true;\n }\n\n if (maxDate.value && date > maxDate.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nwatch(\n selectedDate,\n (value) => {\n if (value) {\n syncCalendarView(value);\n return;\n }\n\n if (!isOpen.value) {\n syncCalendarView(today);\n }\n },\n { immediate: true },\n);\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, selectedDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDate.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDate.value);\n});\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncCalendarView(selectedDate.value ?? focusedDate.value ?? today);\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const normalizedDate = startOfDay(date);\n const value = toDateValue(normalizedDate);\n\n syncCalendarView(normalizedDate);\n emit('update:modelValue', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? calendarId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDate ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <CalendarIcon v-bind=\"treeIconDefaults\" />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"calendarId\"\n class=\"t-date-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :disabled=\"cell.disabled\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.key\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </transition>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -58,7 +58,7 @@ var ce = ["data-state"], le = ["name", "value"], ue = [
|
|
|
58
58
|
"select"
|
|
59
59
|
],
|
|
60
60
|
setup(c, { emit: j }) {
|
|
61
|
-
let xe = k("calendar"), Se = k("chevron-left"), Ce = k("chevron-right"), M = c, N = j, P = ae(), F = T(/* @__PURE__ */ new Date()), I = r(() => w(M.modelValue)), L = r(() => w(M.min)), R = r(() => w(M.max)), z = M.id ?? se("t-date-picker"), B = `${z}-caption`, V = p(null), H = p(null), U = /* @__PURE__ */ new Map(), W = p(E(I.value ?? F)), G = p(I.value ?? F), we = r(() => {
|
|
61
|
+
let xe = r(() => k("calendar")), Se = r(() => k("chevron-left")), Ce = r(() => k("chevron-right")), M = c, N = j, P = ae(), F = T(/* @__PURE__ */ new Date()), I = r(() => w(M.modelValue)), L = r(() => w(M.min)), R = r(() => w(M.max)), z = M.id ?? se("t-date-picker"), B = `${z}-caption`, V = p(null), H = p(null), U = /* @__PURE__ */ new Map(), W = p(E(I.value ?? F)), G = p(I.value ?? F), we = r(() => {
|
|
62
62
|
let { class: e, style: t, name: n, ...r } = P;
|
|
63
63
|
return r;
|
|
64
64
|
}), K = r(() => typeof P.name == "string" ? P.name : void 0), Te = r(() => [
|