@ahrowe/ui 0.39.1 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -14
- package/dist/cjs-types/common/ahroweProvider/ahroweProvider.d.ts +4 -0
- package/dist/cjs-types/common/ahroweProvider/ahroweProvider.types.d.ts +12 -0
- package/dist/cjs-types/common/ahroweProvider/index.d.ts +2 -0
- package/dist/cjs-types/common/bodyEnd/portalHostContext.d.ts +6 -0
- package/dist/cjs-types/common/calendar/calendar.d.ts +4 -0
- package/dist/cjs-types/common/calendar/calendar.types.d.ts +141 -0
- package/dist/cjs-types/common/calendar/components/agendaList/agendaList.d.ts +5 -0
- package/dist/cjs-types/common/calendar/components/agendaList/agendaList.types.d.ts +23 -0
- package/dist/cjs-types/common/calendar/components/agendaList/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.d.ts +4 -0
- package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +17 -0
- package/dist/cjs-types/common/calendar/components/calendarHeader/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/compactMonth/compactMonth.d.ts +9 -0
- package/dist/cjs-types/common/calendar/components/compactMonth/compactMonth.types.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/compactMonth/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/monthView/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/monthView/monthView.d.ts +5 -0
- package/dist/cjs-types/common/calendar/components/monthView/monthView.types.d.ts +10 -0
- package/dist/cjs-types/common/calendar/components/timeGrid/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.d.ts +5 -0
- package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.types.d.ts +40 -0
- package/dist/cjs-types/common/calendar/dates.d.ts +50 -0
- package/dist/cjs-types/common/calendar/format.d.ts +32 -0
- package/dist/cjs-types/common/calendar/gesture.d.ts +32 -0
- package/dist/cjs-types/common/calendar/index.d.ts +2 -0
- package/dist/cjs-types/common/calendar/layout.d.ts +74 -0
- package/dist/cjs-types/common/calendar/useGestures.d.ts +37 -0
- package/dist/cjs-types/common/calendar/usePager.d.ts +20 -0
- package/dist/cjs-types/common/calendar/view.types.d.ts +26 -0
- package/dist/cjs-types/common/configProvider/configProvider.types.d.ts +3 -0
- package/dist/cjs-types/common/confirmModal/confirmModal.types.d.ts +1 -1
- package/dist/cjs-types/common/datePicker/index.d.ts +1 -1
- package/dist/cjs-types/common/errorBoundary/errorBoundary.types.d.ts +2 -2
- package/dist/cjs-types/common/modal/modal.types.d.ts +4 -3
- package/dist/cjs-types/common/themeProvider/index.d.ts +1 -1
- package/dist/cjs-types/common/themeProvider/theme.types.d.ts +16 -0
- package/dist/cjs-types/common/themeProvider/themeProvider.d.ts +7 -9
- package/dist/cjs-types/common/themeProvider/themeVariablesContext.d.ts +2 -2
- package/dist/cjs-types/common/toast/index.d.ts +1 -2
- package/dist/cjs-types/common/toast/toast.types.d.ts +4 -4
- package/dist/cjs-types/common/toast/toastHost.d.ts +4 -0
- package/dist/cjs-types/common/toast/toastService.d.ts +1 -1
- package/dist/cjs-types/common/utils/day.d.ts +8 -0
- package/dist/cjs-types/common/virtualList/useColumns.d.ts +3 -1
- package/dist/cjs-types/index.d.ts +4 -1
- package/dist/esm/common/ahroweProvider/ahroweProvider.mjs +2 -0
- package/dist/esm/common/ahroweProvider/ahroweProvider.mjs.map +1 -0
- package/dist/esm/common/bodyEnd/bodyEnd.mjs +1 -1
- package/dist/esm/common/bodyEnd/bodyEnd.mjs.map +1 -1
- package/dist/esm/common/bodyEnd/portalHostContext.mjs +2 -0
- package/dist/esm/common/bodyEnd/portalHostContext.mjs.map +1 -0
- package/dist/esm/common/calendar/calendar.mjs +2 -0
- package/dist/esm/common/calendar/calendar.mjs.map +1 -0
- package/dist/esm/common/calendar/calendar.module.mjs +2 -0
- package/dist/esm/common/calendar/calendar.module.mjs.map +1 -0
- package/dist/esm/common/calendar/calendar.types.mjs +2 -0
- package/dist/esm/common/calendar/calendar.types.mjs.map +1 -0
- package/dist/esm/common/calendar/components/agendaList/agendaList.mjs +2 -0
- package/dist/esm/common/calendar/components/agendaList/agendaList.mjs.map +1 -0
- package/dist/esm/common/calendar/components/agendaList/agendaList.module.mjs +2 -0
- package/dist/esm/common/calendar/components/agendaList/agendaList.module.mjs.map +1 -0
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs +2 -0
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs.map +1 -0
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs +2 -0
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs.map +1 -0
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs +2 -0
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs.map +1 -0
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs +2 -0
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs.map +1 -0
- package/dist/esm/common/calendar/components/monthView/monthView.mjs +2 -0
- package/dist/esm/common/calendar/components/monthView/monthView.mjs.map +1 -0
- package/dist/esm/common/calendar/components/monthView/monthView.module.mjs +2 -0
- package/dist/esm/common/calendar/components/monthView/monthView.module.mjs.map +1 -0
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs +2 -0
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs.map +1 -0
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs +2 -0
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs.map +1 -0
- package/dist/esm/common/calendar/dates.mjs +2 -0
- package/dist/esm/common/calendar/dates.mjs.map +1 -0
- package/dist/esm/common/calendar/format.mjs +2 -0
- package/dist/esm/common/calendar/format.mjs.map +1 -0
- package/dist/esm/common/calendar/gesture.mjs +2 -0
- package/dist/esm/common/calendar/gesture.mjs.map +1 -0
- package/dist/esm/common/calendar/layout.mjs +2 -0
- package/dist/esm/common/calendar/layout.mjs.map +1 -0
- package/dist/esm/common/calendar/pager.module.mjs +2 -0
- package/dist/esm/common/calendar/pager.module.mjs.map +1 -0
- package/dist/esm/common/calendar/useGestures.mjs +2 -0
- package/dist/esm/common/calendar/useGestures.mjs.map +1 -0
- package/dist/esm/common/calendar/usePager.mjs +2 -0
- package/dist/esm/common/calendar/usePager.mjs.map +1 -0
- package/dist/esm/common/carousel/carousel.module.mjs.map +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
- package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs +1 -1
- package/dist/esm/common/datePicker/dateFunctions.mjs +1 -1
- package/dist/esm/common/datePicker/datePicker.mjs +1 -1
- package/dist/esm/common/errorBoundary/errorBoundary.mjs +2 -2
- package/dist/esm/common/hooks/useAnchorTracking.mjs.map +1 -1
- package/dist/esm/common/input/input.mjs +1 -1
- package/dist/esm/common/input/input.mjs.map +1 -1
- package/dist/esm/common/modal/modal.mjs +1 -1
- package/dist/esm/common/modal/modal.mjs.map +1 -1
- package/dist/esm/common/popover/popover.mjs +1 -1
- package/dist/esm/common/popover/popover.mjs.map +1 -1
- package/dist/esm/common/scrollFade/scrollFade.mjs +1 -1
- package/dist/esm/common/scrollbarProvider/scrollbarProvider.module.mjs.map +1 -1
- package/dist/esm/common/tabHeader/tabHeader.module.mjs.map +1 -1
- package/dist/esm/common/themeProvider/themeProvider.mjs +1 -1
- package/dist/esm/common/themeProvider/themeProvider.mjs.map +1 -1
- package/dist/esm/common/themeProvider/themeVariablesContext.mjs.map +1 -1
- package/dist/esm/common/toast/toastHost.mjs +2 -0
- package/dist/esm/common/toast/toastHost.mjs.map +1 -0
- package/dist/esm/common/toast/toastService.mjs +1 -1
- package/dist/esm/common/toast/toastService.mjs.map +1 -1
- package/dist/esm/common/tooltip/tooltip.module.mjs.map +1 -1
- package/dist/esm/common/utils/day.mjs +1 -1
- package/dist/esm/common/utils/day.mjs.map +1 -1
- package/dist/esm/common/virtualList/useColumns.mjs +1 -1
- package/dist/esm/common/virtualList/useColumns.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/mcp.js +2 -2
- package/dist/style.css +1 -1
- package/dist/types/common/ahroweProvider/ahroweProvider.d.ts +4 -0
- package/dist/types/common/ahroweProvider/ahroweProvider.types.d.ts +12 -0
- package/dist/types/common/ahroweProvider/index.d.ts +2 -0
- package/dist/types/common/bodyEnd/portalHostContext.d.ts +6 -0
- package/dist/types/common/calendar/calendar.d.ts +4 -0
- package/dist/types/common/calendar/calendar.types.d.ts +141 -0
- package/dist/types/common/calendar/components/agendaList/agendaList.d.ts +5 -0
- package/dist/types/common/calendar/components/agendaList/agendaList.types.d.ts +23 -0
- package/dist/types/common/calendar/components/agendaList/index.d.ts +1 -0
- package/dist/types/common/calendar/components/calendarHeader/calendarHeader.d.ts +4 -0
- package/dist/types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +17 -0
- package/dist/types/common/calendar/components/calendarHeader/index.d.ts +1 -0
- package/dist/types/common/calendar/components/compactMonth/compactMonth.d.ts +9 -0
- package/dist/types/common/calendar/components/compactMonth/compactMonth.types.d.ts +1 -0
- package/dist/types/common/calendar/components/compactMonth/index.d.ts +1 -0
- package/dist/types/common/calendar/components/monthView/index.d.ts +1 -0
- package/dist/types/common/calendar/components/monthView/monthView.d.ts +5 -0
- package/dist/types/common/calendar/components/monthView/monthView.types.d.ts +10 -0
- package/dist/types/common/calendar/components/timeGrid/index.d.ts +1 -0
- package/dist/types/common/calendar/components/timeGrid/timeGrid.d.ts +5 -0
- package/dist/types/common/calendar/components/timeGrid/timeGrid.types.d.ts +40 -0
- package/dist/types/common/calendar/dates.d.ts +50 -0
- package/dist/types/common/calendar/format.d.ts +32 -0
- package/dist/types/common/calendar/gesture.d.ts +32 -0
- package/dist/types/common/calendar/index.d.ts +2 -0
- package/dist/types/common/calendar/layout.d.ts +74 -0
- package/dist/types/common/calendar/useGestures.d.ts +37 -0
- package/dist/types/common/calendar/usePager.d.ts +20 -0
- package/dist/types/common/calendar/view.types.d.ts +26 -0
- package/dist/types/common/configProvider/configProvider.types.d.ts +3 -0
- package/dist/types/common/confirmModal/confirmModal.types.d.ts +1 -1
- package/dist/types/common/datePicker/index.d.ts +1 -1
- package/dist/types/common/errorBoundary/errorBoundary.types.d.ts +2 -2
- package/dist/types/common/modal/modal.types.d.ts +4 -3
- package/dist/types/common/themeProvider/index.d.ts +1 -1
- package/dist/types/common/themeProvider/theme.types.d.ts +16 -0
- package/dist/types/common/themeProvider/themeProvider.d.ts +7 -9
- package/dist/types/common/themeProvider/themeVariablesContext.d.ts +2 -2
- package/dist/types/common/toast/index.d.ts +1 -2
- package/dist/types/common/toast/toast.types.d.ts +4 -4
- package/dist/types/common/toast/toastHost.d.ts +4 -0
- package/dist/types/common/toast/toastService.d.ts +1 -1
- package/dist/types/common/utils/day.d.ts +8 -0
- package/dist/types/common/virtualList/useColumns.d.ts +3 -1
- package/dist/types/index.d.ts +4 -1
- package/docs/AhroweProvider.md +90 -0
- package/docs/BodyEnd.md +5 -12
- package/docs/Breadcrumb.md +0 -2
- package/docs/CLAUDE.md +21 -16
- package/docs/Calendar.md +184 -0
- package/docs/CommandPalette.md +0 -2
- package/docs/ConfigProvider.md +12 -8
- package/docs/ConfirmModal.md +1 -3
- package/docs/DatePicker.md +9 -2
- package/docs/ErrorBoundary.md +5 -3
- package/docs/FormValidatorGroup.md +1 -1
- package/docs/KlipyPicker.md +1 -1
- package/docs/Menu.md +0 -2
- package/docs/Modal.md +2 -4
- package/docs/MultiSelect.md +0 -2
- package/docs/OtpInput.md +0 -2
- package/docs/Popover.md +0 -2
- package/docs/RadioGroup.md +1 -1
- package/docs/ScrollbarProvider.md +4 -0
- package/docs/SplitButton.md +0 -2
- package/docs/ThemeProvider.md +13 -10
- package/docs/TimeInput.md +2 -0
- package/docs/Toast.md +18 -17
- package/docs/Tooltip.md +1 -1
- package/docs/VirtualList.md +0 -2
- package/package.json +1 -1
- package/dist/cjs-types/common/toast/toastProvider.d.ts +0 -8
- package/dist/esm/common/toast/toastProvider.mjs +0 -2
- package/dist/esm/common/toast/toastProvider.mjs.map +0 -1
- package/dist/types/common/toast/toastProvider.d.ts +0 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePager.mjs","names":[],"sources":["../../../../package/common/calendar/usePager.ts"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef } from 'react';\nimport { flushSync } from 'react-dom';\n\nimport { useMediaQuery } from '../hooks/useMediaQuery';\n\nconst SETTLE_MS = 240;\n\nexport interface Pager {\n /** Ref for each element that slides. The time grid has two, its head and its body. */\n trackRef: (element: HTMLElement | null) => void;\n /** Width of one pane. */\n width: () => number;\n /** Offset every track by `dx` px, following the finger. */\n move: (dx: number) => void;\n /** Animate to the next (`1`) or previous (`-1`) pane and page, or back (`0`). */\n settle: (step: -1 | 0 | 1) => void;\n /** Jump to the end of a running settle: a new press arrived before it finished. */\n finish: () => void;\n}\n\n/**\n * Drives the three panes a pageable view renders: previous, current and next, keyed by period, so\n * after paging the pane that slid in is the same DOM node as the one now current. The track is\n * reset in the same commit that swaps them, which is why nothing flashes.\n *\n * `focusFallback` receives focus when it would otherwise be left inside a pane that just went inert.\n */\nexport function usePager(\n periodKey: string,\n onPage: (step: 1 | -1) => void,\n focusFallback: () => HTMLElement | null,\n): Pager {\n const tracks = useRef(new Set<HTMLElement>());\n const offset = useRef(0);\n const animations = useRef<Animation[]>([]);\n const pendingStep = useRef<-1 | 0 | 1>(0);\n const keyRef = useRef(periodKey);\n const reducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');\n\n const latest = useRef({ onPage, focusFallback, reducedMotion });\n useLayoutEffect(() => {\n latest.current = { onPage, focusFallback, reducedMotion };\n });\n\n const write = useCallback((dx: number) => {\n offset.current = dx;\n for (const track of tracks.current) track.style.transform = dx === 0 ? '' : `translateX(${dx}px)`;\n }, []);\n\n useLayoutEffect(() => {\n keyRef.current = periodKey;\n write(0);\n const active = document.activeElement;\n if (active instanceof HTMLElement && active.closest('[inert]')) {\n const inPager = [...tracks.current].some((track) => track.contains(active));\n if (inPager) latest.current.focusFallback()?.focus();\n }\n }, [periodKey, write]);\n\n const trackRef = useCallback((element: HTMLElement | null) => {\n if (!element) return;\n tracks.current.add(element);\n return () => {\n tracks.current.delete(element);\n };\n }, []);\n\n const width = useCallback(() => {\n const [first] = tracks.current;\n return first?.parentElement?.clientWidth ?? 0;\n }, []);\n\n const complete = useCallback(\n (step: -1 | 0 | 1) => {\n animations.current = [];\n if (step === 0) {\n write(0);\n return;\n }\n const before = keyRef.current;\n flushSync(() => latest.current.onPage(step));\n // A controlled parent that did not take the new date leaves the old panes in place.\n if (keyRef.current === before) write(0);\n },\n [write],\n );\n\n const settle = useCallback(\n (step: -1 | 0 | 1) => {\n const paneWidth = width();\n const from = offset.current;\n const to = step === 0 ? 0 : -step * paneWidth;\n const elements = [...tracks.current];\n write(to);\n const canAnimate = typeof elements[0]?.animate === 'function';\n if (latest.current.reducedMotion || from === to || !canAnimate) {\n complete(step);\n return;\n }\n // Shorter the less of the way is left, so a flick that has almost arrived does not crawl.\n const duration = Math.max(120, SETTLE_MS * Math.min(1, Math.abs(to - from) / Math.max(paneWidth, 1)));\n const keyframes = [{ transform: `translateX(${from}px)` }, { transform: `translateX(${to}px)` }];\n pendingStep.current = step;\n animations.current = elements.map((element) =>\n element.animate(keyframes, { duration, easing: 'cubic-bezier(0.25, 1, 0.5, 1)' }),\n );\n animations.current[0].onfinish = () => complete(step);\n },\n [complete, width, write],\n );\n\n const finish = useCallback(() => {\n if (animations.current.length === 0) return;\n // Not `Animation#finish()`: it queues the finish event for a later frame, and the new press\n // has to start from the paged state now.\n for (const animation of animations.current) {\n animation.onfinish = null;\n animation.cancel();\n }\n complete(pendingStep.current);\n }, [complete]);\n\n useEffect(() => {\n const running = animations;\n return () => {\n for (const animation of running.current) {\n animation.onfinish = null;\n animation.cancel();\n }\n };\n }, []);\n\n const move = useCallback((dx: number) => write(dx), [write]);\n\n return { trackRef, width, move, settle, finish };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carousel.module.mjs","names":[],"sources":["../../../../package/common/carousel/carousel.module.pcss"],"sourcesContent":[".carousel {\n position: relative;\n overflow: hidden;\n border-radius: var(--default-border-radius);\n\n &-adaptive {\n transition: height 0.4s ease;\n }\n\n &-track {\n display: flex;\n align-items: stretch;\n transition: transform 0.4s ease;\n touch-action: pan-y;\n user-select: none;\n }\n\n &-trackAdaptive {\n align-items: flex-start;\n }\n\n &-slide {\n flex-shrink: 0;\n box-sizing: border-box;\n }\n\n &-prevButton,\n &-nextButton {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n background: var(--background-accent);\n color: var(--text-color);\n box-shadow: var(--card-shadow);\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition:\n opacity 0.15s,\n background 0.15s;\n\n &:hover {\n background: var(--background-accent-light);\n }\n\n &:focus-visible {\n outline: none;\n box-shadow:\n var(--card-shadow),\n 0 0 0 2px var(--primary-lighter);\n }\n }\n\n &-buttonDisabled {\n opacity: 0.35;\n pointer-events: none;\n }\n\n &-prevButton {\n left: 12px;\n }\n\n &-nextButton {\n right: 12px;\n }\n\n /* A scroll strip rather than a row that shrinks, so the dots keep their size at any slide count.\n The padding holds the outer dots clear of the fade until the strip has somewhere to scroll. */\n &-dots {\n position: absolute;\n bottom: 4px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 1;\n display: flex;\n box-sizing: border-box;\n width: max-content;\n max-width: 100%;\n padding-inline: 16px;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n scroll-behavior: smooth;\n\n /* Matches the strip's own `padding-inline`, so the first and last dot start out clear of the\n fade. The shared sheet's private length, not `--scroll-fade-length`, which would inherit. */\n --custom-scroll-fade-length: 16px;\n\n
|
|
1
|
+
{"version":3,"file":"carousel.module.mjs","names":[],"sources":["../../../../package/common/carousel/carousel.module.pcss"],"sourcesContent":[".carousel {\n position: relative;\n overflow: hidden;\n border-radius: var(--default-border-radius);\n\n &-adaptive {\n transition: height 0.4s ease;\n }\n\n &-track {\n display: flex;\n align-items: stretch;\n transition: transform 0.4s ease;\n touch-action: pan-y;\n user-select: none;\n }\n\n &-trackAdaptive {\n align-items: flex-start;\n }\n\n &-slide {\n flex-shrink: 0;\n box-sizing: border-box;\n }\n\n &-prevButton,\n &-nextButton {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n background: var(--background-accent);\n color: var(--text-color);\n box-shadow: var(--card-shadow);\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition:\n opacity 0.15s,\n background 0.15s;\n\n &:hover {\n background: var(--background-accent-light);\n }\n\n &:focus-visible {\n outline: none;\n box-shadow:\n var(--card-shadow),\n 0 0 0 2px var(--primary-lighter);\n }\n }\n\n &-buttonDisabled {\n opacity: 0.35;\n pointer-events: none;\n }\n\n &-prevButton {\n left: 12px;\n }\n\n &-nextButton {\n right: 12px;\n }\n\n /* A scroll strip rather than a row that shrinks, so the dots keep their size at any slide count.\n The padding holds the outer dots clear of the fade until the strip has somewhere to scroll. */\n &-dots {\n position: absolute;\n bottom: 4px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 1;\n display: flex;\n box-sizing: border-box;\n width: max-content;\n max-width: 100%;\n padding-inline: 16px;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n scroll-behavior: smooth;\n\n /* Matches the strip's own `padding-inline`, so the first and last dot start out clear of the\n fade. The shared sheet's private length, not `--scroll-fade-length`, which would inherit. */\n --custom-scroll-fade-length: 16px;\n\n scrollbar-width: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n scroll-behavior: auto;\n }\n }\n\n /* The dot stays 8px, its padding carries the hit area out to the 24px minimum. */\n &-dot {\n box-sizing: content-box;\n\n /* The strip is width-capped, and shrinking would pull the content box, the only part\n `background-clip` paints, down to nothing. */\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n padding: 8px;\n border-radius: 2000px;\n background: var(--background-accent);\n background-clip: content-box;\n opacity: 0.6;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition:\n opacity 0.15s,\n background 0.15s,\n width 0.15s;\n\n &:hover {\n opacity: 0.85;\n }\n\n &:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--primary-lighter);\n }\n\n &-active {\n background: var(--primary-color);\n background-clip: content-box;\n opacity: 1;\n width: 20px;\n }\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonStyleType as n}from"../button/button.types.mjs";import r from"../actionButtons/actionButtons.mjs";import i from"../modal/modal.mjs";import{useState as a}from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";var c={submit:`Confirm`,cancel:`Cancel`};function l(l){let{children:u=null,className:d=``,onClose:f=()=>{},onConfirm:p=()=>{},title:m
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonStyleType as n}from"../button/button.types.mjs";import r from"../actionButtons/actionButtons.mjs";import i from"../modal/modal.mjs";import{useState as a}from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";var c={submit:`Confirm`,cancel:`Cancel`};function l(l){let{children:u=null,className:d=``,onClose:f=()=>{},onConfirm:p=()=>{},title:m,content:h=null,isOpen:g=void 0,labels:_,isDelete:v=!1,actionButtonsProps:y={},style:b,...x}=e(`ConfirmModal`,l),S=t(`ConfirmModal`,_,c),[C,w]=a(!1),[T,E]=a(!1);function D(e=!1){w(!1),f(e)}async function O(){E(!0);try{await p(),D(!0)}catch{}finally{E(!1)}}let k=o(i,{title:m,isOpen:g===void 0?C:g,onClose:()=>D(),className:u?void 0:d,footer:o(r,{onClose:()=>D(),onSubmit:O,labels:{submit:S.submit,cancel:S.cancel},submitButtonStyle:v?n.Delete:void 0,isSubmitButtonLoading:T,noMargin:!0,...y}),children:h});return u?s(`div`,{...x,className:d,style:b,children:[o(`span`,{onClick:()=>w(!0),children:u}),k]}):k}export{l as default};
|
|
2
2
|
//# sourceMappingURL=confirmModal.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirmModal.mjs","names":[],"sources":["../../../../package/common/confirmModal/confirmModal.tsx"],"sourcesContent":["import { useState, type ReactElement } from 'react';\n\nimport Modal from '../modal';\nimport { ActionButtons } from '../actionButtons';\nimport { ButtonStyleType } from '../button';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport type { ConfirmModalLabels, ConfirmModalProps } from './confirmModal.types';\n\nconst DEFAULT_LABELS: Required<ConfirmModalLabels> = {\n submit: 'Confirm',\n cancel: 'Cancel',\n};\n\nfunction ConfirmModal(props: ConfirmModalProps): ReactElement {\n const {\n children = null,\n className = '',\n onClose = () => {},\n onConfirm = () => {},\n title
|
|
1
|
+
{"version":3,"file":"confirmModal.mjs","names":[],"sources":["../../../../package/common/confirmModal/confirmModal.tsx"],"sourcesContent":["import { useState, type ReactElement } from 'react';\n\nimport Modal from '../modal';\nimport { ActionButtons } from '../actionButtons';\nimport { ButtonStyleType } from '../button';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport type { ConfirmModalLabels, ConfirmModalProps } from './confirmModal.types';\n\nconst DEFAULT_LABELS: Required<ConfirmModalLabels> = {\n submit: 'Confirm',\n cancel: 'Cancel',\n};\n\nfunction ConfirmModal(props: ConfirmModalProps): ReactElement {\n const {\n children = null,\n className = '',\n onClose = () => {},\n onConfirm = () => {},\n title,\n content = null,\n isOpen: propIsOpen = undefined,\n labels,\n isDelete = false,\n actionButtonsProps = {},\n style,\n ...rest\n } = useComponentDefaults('ConfirmModal', props);\n const text = useLabels('ConfirmModal', labels, DEFAULT_LABELS);\n const [internalOpen, setInternalOpen] = useState(false);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n function handleClose(didSubmit = false) {\n setInternalOpen(false);\n onClose(didSubmit);\n }\n\n async function handleConfirm() {\n setIsSubmitting(true);\n try {\n await onConfirm();\n handleClose(true);\n } catch {\n // Nothing is awaiting this handler, so a rejection would surface as an unhandled one.\n // The dialog staying open is the signal that the action did not go through; reporting\n // the failure itself belongs to whoever wrote `onConfirm`.\n } finally {\n setIsSubmitting(false);\n }\n }\n\n const isOpen = propIsOpen === undefined ? internalOpen : propIsOpen;\n\n const modal = (\n <Modal\n title={title}\n isOpen={isOpen}\n onClose={() => handleClose()}\n className={children ? undefined : className}\n footer={\n <ActionButtons\n onClose={() => handleClose()}\n onSubmit={handleConfirm}\n labels={{ submit: text.submit, cancel: text.cancel }}\n submitButtonStyle={isDelete ? ButtonStyleType.Delete : undefined}\n isSubmitButtonLoading={isSubmitting}\n // The footer slot already supplies the gap above the buttons.\n noMargin\n {...actionButtonsProps}\n />\n }\n >\n {content}\n </Modal>\n );\n\n if (!children) return modal;\n\n return (\n <div {...rest} className={className} style={style}>\n <span onClick={() => setInternalOpen(true)}>{children}</span>\n {modal}\n </div>\n );\n}\n\nexport default ConfirmModal;\n"],"mappings":"+XAQA,IAAM,EAA+C,CACnD,OAAQ,UACR,OAAQ,QACV,EAEA,SAAS,EAAa,EAAwC,CAC5D,GAAM,CACJ,WAAW,KACX,YAAY,GACZ,cAAgB,CAAC,EACjB,gBAAkB,CAAC,EACnB,QACA,UAAU,KACV,OAAQ,EAAa,IAAA,GACrB,SACA,WAAW,GACX,qBAAqB,CAAC,EACtB,QACA,GAAG,GACD,EAAqB,eAAgB,CAAK,EACxC,EAAO,EAAU,eAAgB,EAAQ,CAAc,EACvD,CAAC,EAAc,GAAmB,EAAS,EAAK,EAChD,CAAC,EAAc,GAAmB,EAAS,EAAK,EAEtD,SAAS,EAAY,EAAY,GAAO,CACtC,EAAgB,EAAK,EACrB,EAAQ,CAAS,CACnB,CAEA,eAAe,GAAgB,CAC7B,EAAgB,EAAI,EACpB,GAAI,CACF,MAAM,EAAU,EAChB,EAAY,EAAI,CAClB,MAAQ,CAIR,QAAU,CACR,EAAgB,EAAK,CACvB,CACF,CAIA,IAAM,EACJ,EAAC,EAAD,CACS,QACC,OALG,IAAe,IAAA,GAAY,EAAe,EAMrD,YAAe,EAAY,EAC3B,UAAW,EAAW,IAAA,GAAY,EAClC,OACE,EAAC,EAAD,CACE,YAAe,EAAY,EAC3B,SAAU,EACV,OAAQ,CAAE,OAAQ,EAAK,OAAQ,OAAQ,EAAK,MAAO,EACnD,kBAAmB,EAAW,EAAgB,OAAS,IAAA,GACvD,sBAAuB,EAEvB,SAAA,GACA,GAAI,CACL,CAAA,EAGF,SAAA,CACI,CAAA,EAKT,OAFK,EAGH,EAAC,MAAD,CAAK,GAAI,EAAiB,YAAkB,QAA5C,SAAA,CACE,EAAC,OAAD,CAAM,YAAe,EAAgB,EAAI,EAAI,UAAe,CAAA,EAC3D,CACE,IANe,CAQxB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import e from"../../../interactableDiv/index.mjs";import t from"
|
|
1
|
+
"use client";import e from"../../../interactableDiv/index.mjs";import{dateToDay as t,daysInMonth as n,formatDay as r,parseDay as i}from"../../../utils/day.mjs";import a from"./datePickerMonth.module.mjs";import{getLocale as o}from"../../../../services/localization.mjs";import{addDays as s,getStartWeekDayOfMonth as c,getToday as l,getWeekDays as u}from"../../dateFunctions.mjs";import{useEffect as d,useRef as f,useState as p}from"react";import m from"classnames";import{jsx as h,jsxs as g}from"react/jsx-runtime";function _(e,t,n){let r=i(n);if(r&&r.month===e&&r.year===t)return r.day;let a=l();return a.month===e&&a.year===t?a.day:1}function v(e,t,n){return{isStartDate:e===t,isEndDate:e===n,isInRange:!!t&&!!n&&e>=t&&e<=n}}function y(e,t,n){return!!t&&e<t||!!n&&e>n}function b({style:i,className:b=``,month:x=l().month,year:S=l().year,onSelect:C=()=>null,selectionStart:w,selectionEnd:T,minDate:E=null,maxDate:D=null,onNavigateMonth:O}){let k=o(`-`),A=n({year:S,month:x}),j=c(x,S),M=t(new Date),N=f({}),[P,F]=p(()=>_(x,S,w)),I=f(null);d(()=>{if(I.current!=null){let e=I.current;I.current=null,F(e),N.current[e]?.focus()}else F(_(x,S,w))},[x,S]);function L(e,t){let n=0;if(e.key===`ArrowRight`)n=1;else if(e.key===`ArrowLeft`)n=-1;else if(e.key===`ArrowDown`)n=7;else if(e.key===`ArrowUp`)n=-7;else return;e.preventDefault();let r=s(t,x,S,n);r.month!==x||r.year!==S?(I.current=r.day,O?.(r.month>x||r.year>S?1:-1)):(F(r.day),N.current[r.day]?.focus())}return h(`div`,{className:m(a.datePickerMonth,b),style:i,children:g(`div`,{className:m(a.datePickerMonthContent),children:[u(k).map((e,t)=>h(`div`,{children:e},t)),Array.from(Array(j-1).keys()).map(e=>h(`div`,{className:m(a.datePickerMonthItem,a.datePickerMonthPlaceholder)},e)),Array.from(Array(A).keys()).map(t=>{let n=t+1,i=r({day:n,month:x,year:S}),o=v(i,w,T),s=y(i,E,D),c=i===M;return h(e,{ref:e=>{N.current[n]=e},tabIndex:n===P?0:-1,onKeyDown:e=>L(e,n),onClick:()=>s?null:C(i),className:m(a.datePickerMonthDay,a.datePickerMonthItem,{[a.datePickerMonthDaySelected]:o.isInRange,[a.datePickerMonthDaySelectedStart]:o.isStartDate,[a.datePickerMonthDaySelectedEnd]:o.isEndDate,[a.datePickerMonthDayDisabled]:s,[a.datePickerMonthDayToday]:c}),children:n},n)}),Array.from(Array(42-(j+A-1)).keys()).map(e=>h(`div`,{className:m(a.datePickerMonthItem,a.datePickerMonthPlaceholder),children:`\xA0`},e))]})})}export{b as default};
|
|
2
2
|
//# sourceMappingURL=datePickerMonth.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{
|
|
1
|
+
"use client";import{dateToDay as e,daysInMonth as t,formatDay as n,parseDay as r}from"../utils/day.mjs";import{getLocale as i}from"../../services/localization.mjs";function a(e,t,n){let r=new Date(0);return r.setUTCFullYear(e,t-1,n),r}function o(e,t,n,r,i=!1){return a(t,n,r).toLocaleDateString(e,{month:i?`short`:`long`,timeZone:`UTC`})}function s(e=i(`-`)){return Array.from(Array(12).keys()).map(t=>o(e,2023,t+1,1))}function c(e,t=!0){return Array.from(Array(7).keys()).map(n=>a(2023,4,10+n).toLocaleDateString(e,{weekday:t?`short`:`long`,timeZone:`UTC`}))}function l(e,t){return a(t,e,1).getUTCDay()||7}function u(e,n,r,i){let a=e+i,o=n,s=r;for(;a<1;)--o,o<1&&(o=12,--s),a+=t({year:s,month:o});for(;a>t({year:s,month:o});)a-=t({year:s,month:o}),o+=1,o>12&&(o=1,s+=1);return{day:a,month:o,year:s}}function d(){return r(e(new Date))}function f(e){let t=r(e);return t?`${String(t.day).padStart(2,`0`)}.${String(t.month).padStart(2,`0`)}.${String(t.year).padStart(4,`0`)}`:``}function p(e){let t=/^(\d{2})\.(\d{2})\.(\d{4})$/.exec(e);if(!t)return null;let i=n({day:Number(t[1]),month:Number(t[2]),year:Number(t[3])});return r(i)?i:null}function m(e,t,n){let r=e,i=n;return r[0]!==`_`&&(r[0]>`3`?(r=`0${r[0]}${t.substring(2)}`,i={start:3,end:3}):r[0]===`3`&&r[1]!==`_`&&r[1]>`1`&&(r=`0${r[1]}${t.substring(2)}`,i={start:3,end:3})),r[3]!==`_`&&r[3]>`1`&&(r=`${r.substring(0,3)}0${r[3]}${t.substring(5)}`,i={start:6,end:6}),r[3]===`1`&&r[4]!==`_`&&r[4]>`2`&&(r=`${r.substring(0,3)}${r[3]}2${t.substring(5)}`),{value:r,selection:i}}export{u as addDays,m as correctDateMaskValue,f as getDateString,o as getMonthName,s as getMonthNames,l as getStartWeekDayOfMonth,d as getToday,c as getWeekDays,p as parseDateString};
|
|
2
2
|
//# sourceMappingURL=dateFunctions.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../button/button.mjs";import n from"../actionIcon/actionIcon.mjs";import{PopoverAlign as r,PopoverPlacement as ee}from"../popover/popover.types.mjs";import te from"../popover/popover.mjs";import ne from"../tooltip/tooltip.mjs";import re from"../input/input.mjs";import ie from"../modal/modal.mjs";import{getLocale as ae}from"../../services/localization.mjs";import{
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../button/button.mjs";import n from"../actionIcon/actionIcon.mjs";import{PopoverAlign as r,PopoverPlacement as ee}from"../popover/popover.types.mjs";import te from"../popover/popover.mjs";import{asDay as i,parseDay as a}from"../utils/day.mjs";import ne from"../tooltip/tooltip.mjs";import re from"../input/input.mjs";import ie from"../modal/modal.mjs";import{getLocale as ae}from"../../services/localization.mjs";import{correctDateMaskValue as oe,getDateString as o,getMonthName as se,getMonthNames as ce,getToday as s,parseDateString as le}from"./dateFunctions.mjs";import ue from"./components/datePickerMonth/datePickerMonth.mjs";import c from"../dropdown/dropdown.mjs";import de from"../maskedInput/maskedInput.mjs";import l from"./datePicker.module.mjs";import{useEffect as u,useRef as d,useState as f}from"react";import p from"classnames";import{faChevronLeft as fe,faChevronRight as pe}from"@fortawesome/free-solid-svg-icons";import{Fragment as me,jsx as m,jsxs as h}from"react/jsx-runtime";function he(e){return e==null||e===``||i(e)?null:Object.prototype.toString.call(e)===`[object Date]`?`a Date. Convert it with dateToDay()`:`${JSON.stringify(e)}, which is not a day`}function g(g){let{className:ge=``,selected:_,onSelect:_e=()=>null,formValidator:v=null,noInput:ve=!1,noHeader:ye=!1,isModal:y=!1,isInline:b=!1,onChange:be=()=>null,minDate:x=null,maxDate:S=null,children:xe=null,showClearButton:Se=!1,label:C=``,isValid:Ce=!0,errorMessage:w=``,isRequired:we=!1,startDate:T,endDate:E,style:Te,classNames:D,styles:O,...Ee}=e(`DatePicker`,g),k=()=>i(v?v.value:_),A=i(x),j=i(S),M=k(),N=a(M)??s(),[P,F]=f(N.month),[I,L]=f(N.year),[R,z]=f(!1),[B,V]=f(()=>o(M)),[De,H]=f(!1),[Oe,U]=f(!1),[,ke]=f(0),[Ae,je]=f(_),W=d(v);if(Ae!==_){je(_);let e=a(_)??s();F(e.month),L(e.year),V(o(_))}let G=d(new Set),K=v?.value;u(()=>{let e={selected:_,formValidator:K,minDate:x,maxDate:S,startDate:T,endDate:E};for(let[t,n]of Object.entries(e)){let e=he(n);e&&!G.current.has(t)&&(G.current.add(t),console.warn(`DatePicker: \`${t}\` takes a day as a 'YYYY-MM-DD' string, and got ${e}. See "Migration from Date values" in docs/DatePicker.md.`))}},[_,K,x,S,T,E]),u(()=>{if(W.current=v,!v)return;v.label=C,v.validate();let e=()=>{let e=a(v.value);e&&(F(e.month),L(e.year)),V(o(v.value)),ke(e=>e+1)};return v.registerOnUpdateListener(e),()=>v.removeOnUpdateListener(e)},[v,C]);let Me=()=>v?v.touched&&v.hasError():!Ce||!!w,Ne=()=>!!(we||v?.validators.find(e=>e.validatorId===`required`)),q=e=>{V(o(e)),v&&v.set(e),be(e)},J=e=>{q(e),_e(e),z(!1)},Y=e=>{let t=I*12+P-1+e,n=Math.floor(t/12);n<0||n>9999||(L(n),F(t%12+1))},X=e=>{let t=le(e);return!t||A&&t<A||j&&t>j?null:t},Pe=({previousState:e,nextState:t})=>{if(t.value===e.value)return t;let n=oe(t.value,e.value,t.selection??null),r=X(n.value);return r&&q(r),n},Fe=()=>{let e=400,t=s().year-200,n=a(A),r=a(j);return n&&(t=n.year),r&&(e=Math.max(0,r.year-t+1)),Array.from(Array(e).keys()).map(e=>({key:e+t,label:e+t}))},Z=k(),Ie=Me(),Le=ye?null:h(`div`,{className:p(l.datePickerHeader,D?.header),style:O?.header,children:[m(n,{icon:fe,onClick:()=>Y(-1)}),m(`div`,{className:l.datePickerHeaderMonthAndYearContainer,children:h(`div`,{className:l.datePickerHeaderMonthAndYear,children:[m(c,{plainStyle:!0,scrollToSelected:!0,onChange:e=>F(e),className:p(l.datePickerHeaderMonth,D?.monthDropdown),style:O?.monthDropdown,value:se(ae(`-`),I,P,1),items:ce().map((e,t)=>({key:t+1,label:e}))}),m(c,{plainStyle:!0,scrollToSelected:!0,useMatLabelStyle:!1,className:p(l.datePickerHeaderYear,D?.yearDropdown),style:O?.yearDropdown,onChange:e=>L(e),value:I,items:Fe()})]})}),m(n,{icon:pe,onClick:()=>Y(1)})]}),Q=h(me,{children:[Le,m(ue,{className:p(l.datePickerMonth,D?.calendar),style:O?.calendar,month:P,year:I,onSelect:J,selectionStart:i(T)??Z,selectionEnd:i(E)??Z,minDate:A,maxDate:j,onNavigateMonth:Y}),Se&&m(t,{onClick:()=>J(null),className:D?.clearButton,style:O?.clearButton,children:`Clear`}),xe]}),$=ve?null:m(re,{autoComplete:`off`,className:D?.input,style:O?.input,readOnly:y,classNames:y?{input:l.datePickerModalInput}:void 0,label:`${C}${Ne()?` *`:``}`,value:B,onChange:e=>V(e),onClick:()=>z(!0),customInput:m(de,{mask:`99.99.9999`,beforeMaskedStateChange:Pe}),onBlur:()=>{W.current&&(W.current.touched=!0),H(!1),B!==o(k())&&q(X(B))},onFocus:()=>H(!0),onMouseEnter:()=>U(!0),onMouseLeave:()=>U(!1),isValid:!Ie}),Re=b?Q:y?m(ie,{hideHeader:!0,isOpen:R,onClose:()=>z(!1),children:Q}):m(te,{isOpen:R,onOpenChange:e=>z(e),content:Q,placement:ee.Bottom,align:r.Start,closeOnTriggerClick:!1,constrainWidth:!1,children:$});return h(`div`,{...Ee,className:p(l.datePicker,ge,D?.root),style:{...Te,...O?.root},children:[(y||b)&&$,Re,m(ne,{variant:`error`,message:v?v.getCurrentErrorMessage():w||``,isVisible:Ie&&(De||Oe)})]})}export{g as default};
|
|
2
2
|
//# sourceMappingURL=datePicker.mjs.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use client";import e from"../accordion/accordion.mjs";import t from"../button/button.mjs";import n
|
|
1
|
+
"use client";import e from"../accordion/accordion.mjs";import t from"../button/button.mjs";import{showToast as n}from"../toast/toastService.mjs";import r from"../copyButton/copyButton.mjs";import i from"./errorBoundary.module.mjs";import a from"react";import o from"classnames";import{FontAwesomeIcon as s}from"@fortawesome/react-fontawesome";import{faArrowRotateRight as c,faTriangleExclamation as l}from"@fortawesome/free-solid-svg-icons";import{jsx as u,jsxs as d}from"react/jsx-runtime";var f={stackTrace:`Stack trace`,copy:`Copy`,copied:`Copied`,reset:`Try again`,copySuccessToast:`Stack trace copied to clipboard`,copyErrorToast:`Could not copy stack trace`};function p(e,t){let n=[e.stack??`${e.name}: ${e.message}`];return t?.componentStack&&n.push(`Component stack:${t.componentStack}`),n.join(`
|
|
2
2
|
|
|
3
|
-
`)}var m=class extends a.Component{constructor(...e){super(...e),this.state={error:null,errorInfo:null},this.reset=()=>{this.setState({error:null,errorInfo:null}),this.props.onReset?.()}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){this.setState({errorInfo:t}),this.props.onError?.(e,t)}componentDidUpdate(e){if(!this.state.error)return;let t=e.resetKeys??[],n=this.props.resetKeys??[];(n.length!==t.length||n.some((e,n)=>e!==t[n]))&&this.reset()}render(){let{error:a,errorInfo:m}=this.state,{children:h=null,title:g=`Something went wrong`,description:_,labels:v,fallback:y,hideStack:b=!1,className:x,style:S,classNames:C,styles:w,onError:T,onReset:E,resetKeys:D,role:O=`alert`,...k}=this.props;if(!a)return h;let A={...f,...v};return y?typeof y==`function`?y({error:a,errorInfo:m,resetErrorBoundary:this.reset}):y:d(`div`,{...k,role:O,className:o(i.errorBoundary,x,C?.root),style:{...S,...w?.root},children:[d(`div`,{className:o(i.errorBoundaryHeader,C?.header),style:w?.header,children:[u(`div`,{className:o(i.errorBoundaryBadge,C?.badge),style:w?.badge,children:u(s,{icon:l,className:o(i.errorBoundaryIcon,C?.icon),style:w?.icon})}),u(`div`,{className:o(i.errorBoundaryTitle,C?.title),style:w?.title,children:g}),u(`div`,{className:o(i.errorBoundaryDescription,C?.description),style:w?.description,children:_??a.message})]}),!b&&d(e,{title:A.stackTrace,className:o(i.errorBoundaryStack,C?.stack),style:w?.stack,children:[d(`div`,{className:o(i.errorBoundaryStackHeader,C?.stackHeader),style:w?.stackHeader,children:[u(`span`,{className:o(i.errorBoundaryStackLabel,C?.stackLabel),style:w?.stackLabel,children:a.name||`Error`}),u(
|
|
3
|
+
`)}var m=class extends a.Component{constructor(...e){super(...e),this.state={error:null,errorInfo:null},this.reset=()=>{this.setState({error:null,errorInfo:null}),this.props.onReset?.()}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){this.setState({errorInfo:t}),this.props.onError?.(e,t)}componentDidUpdate(e){if(!this.state.error)return;let t=e.resetKeys??[],n=this.props.resetKeys??[];(n.length!==t.length||n.some((e,n)=>e!==t[n]))&&this.reset()}render(){let{error:a,errorInfo:m}=this.state,{children:h=null,title:g=`Something went wrong`,description:_,labels:v,fallback:y,hideStack:b=!1,className:x,style:S,classNames:C,styles:w,onError:T,onReset:E,resetKeys:D,role:O=`alert`,...k}=this.props;if(!a)return h;let A={...f,...v};return y?typeof y==`function`?y({error:a,errorInfo:m,resetErrorBoundary:this.reset}):y:d(`div`,{...k,role:O,className:o(i.errorBoundary,x,C?.root),style:{...S,...w?.root},children:[d(`div`,{className:o(i.errorBoundaryHeader,C?.header),style:w?.header,children:[u(`div`,{className:o(i.errorBoundaryBadge,C?.badge),style:w?.badge,children:u(s,{icon:l,className:o(i.errorBoundaryIcon,C?.icon),style:w?.icon})}),u(`div`,{className:o(i.errorBoundaryTitle,C?.title),style:w?.title,children:g}),u(`div`,{className:o(i.errorBoundaryDescription,C?.description),style:w?.description,children:_??a.message})]}),!b&&d(e,{title:A.stackTrace,className:o(i.errorBoundaryStack,C?.stack),style:w?.stack,children:[d(`div`,{className:o(i.errorBoundaryStackHeader,C?.stackHeader),style:w?.stackHeader,children:[u(`span`,{className:o(i.errorBoundaryStackLabel,C?.stackLabel),style:w?.stackLabel,children:a.name||`Error`}),u(r,{value:p(a,m),labels:{copy:A.copy,copied:A.copied},onCopy:()=>n(A.copySuccessToast,{type:`success`}),onError:()=>n(A.copyErrorToast,{type:`error`}),className:o(i.errorBoundaryCopyButton,C?.copyButton),style:w?.copyButton})]}),u(`pre`,{className:o(i.errorBoundaryStackTrace,C?.stackTrace),style:w?.stackTrace,children:p(a,m)})]}),u(`div`,{className:o(i.errorBoundaryActions,C?.actions),style:w?.actions,children:u(t,{onClick:this.reset,icon:c,className:o(i.errorBoundaryResetButton,C?.resetButton),style:w?.resetButton,children:A.reset})})]})}};export{m as default};
|
|
4
4
|
//# sourceMappingURL=errorBoundary.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAnchorTracking.mjs","names":[],"sources":["../../../../package/common/hooks/useAnchorTracking.ts"],"sourcesContent":["import { useLayoutEffect, useRef, type RefObject } from 'react';\nimport { getScrollableAncestors } from 'components/common/utils/scrollAncestors';\n\nexport interface UseAnchorTrackingArgs {\n isOpen: boolean;\n /** The element the popup is anchored to. Its scrollable ancestors are what get tracked. */\n triggerRef: RefObject<HTMLElement | null>;\n /**\n * Every element the positioning maths needs. Tracking starts only once all of them, plus the\n * trigger, are mounted. Read fresh on each setup, so an inline array literal is fine.\n */\n elementRefs: RefObject<HTMLElement | null>[];\n /**\n * Positions the popup. Called once on setup and then on every scroll, resize and tracked size\n * change. Reads the caller's own refs for everything beyond the two arguments.\n */\n update: (trigger: HTMLElement, ancestors: HTMLElement[]) => void;\n /**\n * Elements whose own size changes must re-run `update`: a popup whose content changes size\n * while open (a filtered list shrinking, an async list loading in) otherwise keeps coordinates\n * computed for its old height and ends up detached from the trigger. Re-read on every update,\n * since a panel can mount a commit later than the element it hangs off.\n */\n resizeRefs?: RefObject<HTMLElement | null>[];\n /** Hands the popup's elements back as they were found. Runs when tracking stops. */\n teardown?: () => void;\n /** Values that must restart tracking, and so re-run `update`, when they change. */\n deps?: readonly unknown[];\n}\n\n/**\n * The lifecycle half of anchoring a portaled, `position: fixed` popup to a trigger: waits for the\n * elements to mount, resolves the trigger's scrolling ancestors once, and re-runs the caller's\n * positioning on every scroll, viewport resize and tracked size change until it closes.\n *\n * Callers supply only the geometry (`update`) and the inline styles to clear again (`teardown`);\n * `usePopoverPosition` is built on this.\n *\n * Position is deliberately written straight to the DOM by the caller rather than through React\n * state: going through setState -> re-render -> commit adds a round-trip that lags behind the\n * browser's own scroll painting by at least a frame.\n */\nexport function useAnchorTracking({\n isOpen,\n triggerRef,\n elementRefs,\n update,\n resizeRefs,\n teardown,\n deps = [],\n}: UseAnchorTrackingArgs) {\n // Latest-value refs, so the effect restarts only for `deps` the caller names, never merely\n // because these were passed as fresh array/function literals this render.\n const latest = useRef({ elementRefs, update, resizeRefs, teardown });\n latest.current = { elementRefs, update, resizeRefs, teardown };\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n\n let rafId: number | undefined;\n let stop: (() => void) | undefined;\n\n // The elements may not be mounted yet on the very first invocation of this effect: a portal\n // target
|
|
1
|
+
{"version":3,"file":"useAnchorTracking.mjs","names":[],"sources":["../../../../package/common/hooks/useAnchorTracking.ts"],"sourcesContent":["import { useLayoutEffect, useRef, type RefObject } from 'react';\nimport { getScrollableAncestors } from 'components/common/utils/scrollAncestors';\n\nexport interface UseAnchorTrackingArgs {\n isOpen: boolean;\n /** The element the popup is anchored to. Its scrollable ancestors are what get tracked. */\n triggerRef: RefObject<HTMLElement | null>;\n /**\n * Every element the positioning maths needs. Tracking starts only once all of them, plus the\n * trigger, are mounted. Read fresh on each setup, so an inline array literal is fine.\n */\n elementRefs: RefObject<HTMLElement | null>[];\n /**\n * Positions the popup. Called once on setup and then on every scroll, resize and tracked size\n * change. Reads the caller's own refs for everything beyond the two arguments.\n */\n update: (trigger: HTMLElement, ancestors: HTMLElement[]) => void;\n /**\n * Elements whose own size changes must re-run `update`: a popup whose content changes size\n * while open (a filtered list shrinking, an async list loading in) otherwise keeps coordinates\n * computed for its old height and ends up detached from the trigger. Re-read on every update,\n * since a panel can mount a commit later than the element it hangs off.\n */\n resizeRefs?: RefObject<HTMLElement | null>[];\n /** Hands the popup's elements back as they were found. Runs when tracking stops. */\n teardown?: () => void;\n /** Values that must restart tracking, and so re-run `update`, when they change. */\n deps?: readonly unknown[];\n}\n\n/**\n * The lifecycle half of anchoring a portaled, `position: fixed` popup to a trigger: waits for the\n * elements to mount, resolves the trigger's scrolling ancestors once, and re-runs the caller's\n * positioning on every scroll, viewport resize and tracked size change until it closes.\n *\n * Callers supply only the geometry (`update`) and the inline styles to clear again (`teardown`);\n * `usePopoverPosition` is built on this.\n *\n * Position is deliberately written straight to the DOM by the caller rather than through React\n * state: going through setState -> re-render -> commit adds a round-trip that lags behind the\n * browser's own scroll painting by at least a frame.\n */\nexport function useAnchorTracking({\n isOpen,\n triggerRef,\n elementRefs,\n update,\n resizeRefs,\n teardown,\n deps = [],\n}: UseAnchorTrackingArgs) {\n // Latest-value refs, so the effect restarts only for `deps` the caller names, never merely\n // because these were passed as fresh array/function literals this render.\n const latest = useRef({ elementRefs, update, resizeRefs, teardown });\n latest.current = { elementRefs, update, resizeRefs, teardown };\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n\n let rafId: number | undefined;\n let stop: (() => void) | undefined;\n\n // The elements may not be mounted yet on the very first invocation of this effect: a portal\n // target can still be missing (a `#bodyEnd` the app renders, or any while hydrating), and then\n // the portaled content and its ref commits one render later. Since refs never change\n // identity, that later commit doesn't re-trigger this effect on its own, so retry each frame.\n function trySetup() {\n const trigger = triggerRef.current;\n const elements = latest.current.elementRefs;\n if (!trigger || elements.some((ref) => !ref.current)) {\n rafId = requestAnimationFrame(trySetup);\n return;\n }\n const ancestors = getScrollableAncestors(trigger);\n\n const resizeObserver = new ResizeObserver(() => runUpdate());\n const observed = new Set<Element>();\n\n function runUpdate() {\n latest.current.update(trigger!, ancestors);\n // After the update, so an element that only mounts during it is picked up too. Once\n // observed this is a handful of Set lookups, so it costs nothing on the scroll path.\n latest.current.resizeRefs?.forEach(({ current }) => {\n if (!current || observed.has(current)) return;\n observed.add(current);\n resizeObserver.observe(current);\n });\n }\n\n runUpdate();\n\n const scrollTargets: (Window | HTMLElement)[] = [window, ...ancestors];\n scrollTargets.forEach((t) => t.addEventListener('scroll', runUpdate, { passive: true }));\n window.addEventListener('resize', runUpdate);\n // `window.resize` doesn't reliably fire when a mobile keyboard opens/closes — visualViewport\n // does, and is what the callers' flip/clamp maths is measured against.\n window.visualViewport?.addEventListener('resize', runUpdate);\n window.visualViewport?.addEventListener('scroll', runUpdate);\n\n stop = () => {\n scrollTargets.forEach((t) => t.removeEventListener('scroll', runUpdate));\n window.removeEventListener('resize', runUpdate);\n window.visualViewport?.removeEventListener('resize', runUpdate);\n window.visualViewport?.removeEventListener('scroll', runUpdate);\n resizeObserver.disconnect();\n latest.current.teardown?.();\n };\n }\n\n trySetup();\n\n return () => {\n if (rafId !== undefined) cancelAnimationFrame(rafId);\n stop?.();\n };\n // Spread rather than listed: `deps` is the caller's own set of geometry inputs, and changing\n // any of them has to restart tracking so the new values get applied immediately.\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, triggerRef, ...deps]);\n}\n"],"mappings":"uIA0CA,SAAgB,EAAkB,CAChC,SACA,aACA,cACA,SACA,aACA,WACA,OAAO,CAAC,GACgB,CAGxB,IAAM,EAAS,EAAO,CAAE,cAAa,SAAQ,aAAY,UAAS,CAAC,EACnE,EAAO,QAAU,CAAE,cAAa,SAAQ,aAAY,UAAS,EAE7D,MAAsB,CACpB,GAAI,CAAC,EAAQ,OAEb,IAAI,EACA,EAMJ,SAAS,GAAW,CAClB,IAAM,EAAU,EAAW,QACrB,EAAW,EAAO,QAAQ,YAChC,GAAI,CAAC,GAAW,EAAS,KAAM,GAAQ,CAAC,EAAI,OAAO,EAAG,CACpD,EAAQ,sBAAsB,CAAQ,EACtC,MACF,CACA,IAAM,EAAY,EAAuB,CAAO,EAE1C,EAAiB,IAAI,mBAAqB,EAAU,CAAC,EACrD,EAAW,IAAI,IAErB,SAAS,GAAY,CACnB,EAAO,QAAQ,OAAO,EAAU,CAAS,EAGzC,EAAO,QAAQ,YAAY,SAAS,CAAE,aAAc,CAC7C,GAAW,GAAS,IAAI,CAAO,IACpC,EAAS,IAAI,CAAO,EACpB,EAAe,QAAQ,CAAO,EAChC,CAAC,CACH,CAEA,EAAU,EAEV,IAAM,EAA0C,CAAC,OAAQ,GAAG,CAAS,EACrE,EAAc,QAAS,GAAM,EAAE,iBAAiB,SAAU,EAAW,CAAE,QAAS,EAAK,CAAC,CAAC,EACvF,OAAO,iBAAiB,SAAU,CAAS,EAG3C,OAAO,gBAAgB,iBAAiB,SAAU,CAAS,EAC3D,OAAO,gBAAgB,iBAAiB,SAAU,CAAS,EAE3D,MAAa,CACX,EAAc,QAAS,GAAM,EAAE,oBAAoB,SAAU,CAAS,CAAC,EACvE,OAAO,oBAAoB,SAAU,CAAS,EAC9C,OAAO,gBAAgB,oBAAoB,SAAU,CAAS,EAC9D,OAAO,gBAAgB,oBAAoB,SAAU,CAAS,EAC9D,EAAe,WAAW,EAC1B,EAAO,QAAQ,WAAW,CAC5B,CACF,CAIA,OAFA,EAAS,MAEI,CACP,IAAU,IAAA,IAAW,qBAAqB,CAAK,EACnD,IAAO,CACT,CAIF,EAAG,CAAC,EAAQ,EAAY,GAAG,CAAI,CAAC,CAClC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import n from"../tooltip/tooltip.mjs";import
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{mergeRefs as n}from"../utils/mergeRefs.mjs";import ee from"../tooltip/tooltip.mjs";import te from"../animatedIcon/animatedIcon.mjs";import r from"./input.module.mjs";import{InputIconPosition as i,InputType as a}from"./input.types.mjs";import ne,{useCallback as re,useEffect as o,useId as ie,useRef as s,useState as c}from"react";import l from"classnames";import{FontAwesomeIcon as u}from"@fortawesome/react-fontawesome";import{faEnvelope as ae,faEye as oe,faEyeSlash as se,faPen as ce,faPhone as le,faSearch as ue,faXmark as de}from"@fortawesome/free-solid-svg-icons";import{jsx as d,jsxs as f}from"react/jsx-runtime";var fe={clear:`Clear`,showPassword:`Show password`,hidePassword:`Hide password`,clearSearch:`Clear search`};function p(e){if(e)return{role:`button`,tabIndex:0,onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),e(t))}}}function pe(pe){let{name:me=``,id:he,label:m=``,errorMessage:h=``,isValid:ge=!0,className:_e=``,style:ve,value:ye=``,icon:g=null,iconPosition:be,onChange:_=()=>{},onFocus:xe=null,onBlur:Se=null,onMouseEnter:Ce=null,onMouseLeave:we=null,isUppercase:Te=!1,isRequired:Ee=!1,tabIndex:De=0,type:v=void 0,isRow:Oe=!1,onIconClick:y=null,parse:ke=null,formValidator:b=null,autoFocus:Ae=!1,suffix:je=null,upperRightLabel:x=null,labelInBorder:Me=!1,showCancel:Ne=!1,onClearClicked:Pe,min:Fe=null,max:Ie=null,placeholder:S=``,useMatLabelStyle:C=!0,alwaysFloatLabel:Le=!1,autoComplete:Re=null,onClick:ze=()=>null,readOnly:w=!1,customInput:T,alwaysShowCancel:Be=!1,multiline:E=!1,rows:Ve,autoResize:D=!1,classNames:O,styles:k,disabled:He=!1,labels:Ue,ref:We,...A}=e(`Input`,pe),j=t(`Input`,Ue,fe),[M,Ge]=c(!1),[Ke,N]=c(!1),[P,F]=c(!1),[I,L]=c(!1),[,qe]=c(0),R=s(null),z=s(b),Je=ie(),Ye=he||me||Je,B=b?b.value:ye,Xe=s(!1),V=re(()=>{let e=R.current;if(e){if(!D){Xe.current&&=(e.style.height=``,!1);return}e.style.height=`auto`,e.style.height=`${e.scrollHeight}px`,Xe.current=!0}},[D]);o(()=>{V()},[V,B]),o(()=>{Ae&&R.current&&setTimeout(()=>{R.current?.focus()},1)},[Ae]),o(()=>{z.current=b;let e=z.current;if(!e)return;e.label=m??``,e.validate();let t=()=>qe(e=>e+1);return e.registerOnUpdateListener(t),()=>{e.removeOnUpdateListener(t)}},[b,m]);let Ze=()=>b?b.touched&&b.hasError():!ge||!!h,Qe=()=>!!(Ee||b&&b.validators.find(e=>e.validatorId===`required`)),$e=e=>{F(!0),Ce&&Ce(e)},et=e=>{F(!1),we&&we(e)},tt=e=>{Ge(!0),xe&&xe(e)},nt=e=>{z.current&&(z.current.touched=!0),Ge(!1),Se&&Se(e)},rt=e=>{let t,n;typeof e==`string`?n=e:(t=e,n=e.target.value),ke&&(n=ke(n)),b&&b.set(n),_&&_(n,t),V()},it=()=>{if(v!==a.Email)return v===a.Phone?`tel`:v===a.Search?`search`:v===`password`&&I?`text`:v},at=()=>{if(v===a.Email)return`email`;if(v===a.Phone)return`tel`;if(v===a.Search)return`search`},ot=v&&v!==a.Date&&v!==a.Iban&&v!==a.HasNoIcon,st=v===a.Search||v===a.Password,H=!!g,ct=H&&!st,lt=v===a.Email||v===a.Phone||v===a.Search,U=(be??(!C&<?i.Left:i.Right))===i.Left,W={className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!y,[r.inputFieldIconLeft]:U}),onClick:y??void 0,...p(y)},G=g,K=y??G?.props.onClick,ut=ct&&G?ne.cloneElement(G,{className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!K,[r.inputFieldIconLeft]:U},G.props.className),onClick:K,...p(K)}):null,dt=(ot||H)&&U,ft={className:l(r.inputFieldIcon,r.inputFieldIconPassword,{[r.inputFieldIconLeft]:U}),onClick:()=>L(!I),...p(()=>L(!I)),"aria-label":I?j.hidePassword:j.showPassword},q=Ze(),J=m;J&&Qe()&&(J=`${J} *`);let pt=Qe()?d(`span`,{className:r.requiredMark,children:`*`}):null,Y=M&&!w,X=C&&(Le||Y||B||Ke||v===a.Date),mt=e=>{let{animationName:t}=e;if(t===r.inputAutofillStart){N(!0);let t=e.currentTarget.value;t&&t!==String(B??``)&&rt(t);return}if(t===r.inputAutofillEnd){N(!1);return}A.onAnimationStart?.(e)},Z=v===a.Search&&!!B,Q=T?.props;function $(){b&&b.set(``),_?.(``),Pe?.()}return f(`div`,{className:l(r.input,{[r.inputIconLeft]:dt},_e),style:ve,children:[f(`label`,{htmlFor:Ye,className:l(r.inputLabel,O?.label,{[r.inputLabelColumn]:!Oe,[r.inputLabelInBorder]:Me}),style:k?.label,children:[m&&!C?f(`span`,{className:r.inputLabelText,children:[m,pt]}):null,x&&d(`div`,{className:l(r.inputUpperRightLabel,O?.upperRightLabel),style:k?.upperRightLabel,children:x}),f(`div`,{className:l(r.inputContainer,{[r.inputContainerMultiline]:E},O?.container),style:k?.container,onMouseEnter:$e,onMouseLeave:et,children:[ut,ne.cloneElement(T||d(E?`textarea`:`input`,{}),{...A,className:l(r.inputField,{[r.inputFieldUppercase]:Te,[r.inputFieldDate]:v===a.Date,[r.inputFieldDefault]:v!==a.Date,[r.inputFieldWithIcon]:ot||H,[r.inputFieldWithIconLeft]:dt,[r.inputFieldMultiline]:E,[r.inputFieldMultilineAutoResize]:E&&D,[r.inputFieldReadOnly]:w&&!He},O?.input,Q?.className),style:Q?.style||k?.input?{...Q?.style,...k?.input}:void 0,name:me,id:Ye,value:B,tabIndex:De,ref:T?void 0:n(R,We),onChange:rt,onAnimationStart:mt,onFocus:tt,onBlur:nt,placeholder:C?``:S,autoComplete:Re,onClick:ze,readOnly:w,disabled:He,...!E&&{type:it(),inputMode:A.inputMode??at(),min:Fe,max:Ie},...E&&Ve!==void 0&&{rows:Ve}}),je&&d(`div`,{className:l(r.inputFieldSuffix,O?.suffix),style:k?.suffix,children:je})]}),d(`fieldset`,{className:l(r.inputFieldset,O?.fieldset,{[r.inputContainerBorderFocused]:Y,[r.inputContainerBorderSearchFocused]:v===a.Search&&(Y||!!B),[r.inputContainerBorderInvalid]:q,[r.inputContainerBorderError]:q}),style:k?.fieldset,children:d(`legend`,{className:l(r.inputFieldsetLegend,{[r.inputFieldsetLegendActive]:X}),children:d(`span`,{children:J})})}),C&&m&&f(`div`,{className:l(r.inputMatLabel,{[r.inputMatLabelFloating]:X,[r.inputMatLabelMultiline]:E&&!X}),children:[m,pt]}),C&&S&&d(`div`,{className:l(r.inputPlaceholder,Y&&!B&&!Ke&&r.inputPlaceholderShown,E&&r.inputPlaceholderMultiline),children:S}),d(ee,{variant:`error`,message:b?b.getCurrentErrorMessage():h||``,isVisible:q&&(M||P)})]}),v===a.Phone&&!H&&d(u,{icon:le,...W}),v===a.Email&&!H&&d(u,{icon:ae,...W}),v===a.Edit&&!H&&d(u,{icon:ce,...W}),v===a.Search&&d(te,{icon:Z?de:ue,className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!Z,[r.inputFieldIconLeft]:U}),onClick:Z?$:void 0,...p(Z?$:void 0),"aria-label":Z?j.clearSearch:void 0}),v===a.Password&&d(u,{icon:I?se:oe,...ft}),(Ne&&B&&(M||P)||Be)&&v!==a.Search&&d(u,{icon:de,className:r.inputFieldIcon,onClick:$,onMouseEnter:()=>F(!0),onMouseLeave:()=>F(!1),...p($),"aria-label":j.clear})]})}export{pe as default};
|
|
2
2
|
//# sourceMappingURL=input.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.mjs","names":[],"sources":["../../../../package/common/input/input.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useId } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n faPhone,\n faPen,\n faEnvelope,\n faSearch,\n faXmark,\n faEye as passwordHiddenIcon,\n faEyeSlash as passwordShownIcon,\n} from '@fortawesome/free-solid-svg-icons';\nimport Tooltip from 'components/common/tooltip';\nimport AnimatedIcon from 'components/common/animatedIcon';\nimport { useComponentDefaults, useLabels } from 'components/common/configProvider';\nimport styles from './input.module.pcss';\nimport { mergeRefs } from '../utils/mergeRefs';\nimport type { InputLabels, InputProps } from './input.types';\nimport { InputType, InputIconPosition } from './input.types';\n\nconst DEFAULT_LABELS: Required<InputLabels> = {\n clear: 'Clear',\n showPassword: 'Show password',\n hidePassword: 'Hide password',\n clearSearch: 'Clear search',\n};\n\nfunction keyboardActivationProps(onActivate?: ((event: React.SyntheticEvent) => void) | null) {\n if (!onActivate) return undefined;\n return {\n role: 'button' as const,\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n onActivate(event);\n },\n };\n}\n\nfunction Input(props: InputProps) {\n const {\n name = '',\n id,\n label = '',\n errorMessage = '',\n isValid = true,\n className = '',\n style,\n value = '',\n icon = null,\n iconPosition,\n onChange = () => {},\n onFocus: onFocusProp = null,\n onBlur: onBlurProp = null,\n onMouseEnter: onMouseEnterProp = null,\n onMouseLeave: onMouseLeaveProp = null,\n isUppercase = false,\n isRequired = false,\n tabIndex = 0,\n type = undefined,\n isRow = false,\n onIconClick = null,\n parse = null,\n formValidator = null,\n autoFocus = false,\n suffix = null,\n upperRightLabel = null,\n labelInBorder = false,\n showCancel = false,\n onClearClicked,\n min = null,\n max = null,\n placeholder = '',\n useMatLabelStyle = true,\n alwaysFloatLabel = false,\n autoComplete = null,\n onClick = () => null,\n readOnly = false,\n customInput,\n alwaysShowCancel = false,\n multiline = false,\n rows,\n autoResize = false,\n classNames,\n styles: slotStyles,\n disabled = false,\n labels,\n ref,\n ...rest\n } = useComponentDefaults('Input', props);\n const text = useLabels('Input', labels, DEFAULT_LABELS);\n const [isFocused, setIsFocused] = useState(false);\n // Chrome fills a field on page load without firing anything React sees. The animation the\n // stylesheet binds to :-webkit-autofill is the only notification it gives.\n const [isAutofilled, setIsAutofilled] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [isPasswordShown, setIsPasswordShown] = useState(false);\n const [, forceUpdate] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);\n const fvRef = useRef(formValidator);\n\n const generatedId = useId();\n const inputId = id || name || generatedId;\n\n const currVal = formValidator ? formValidator.value : value;\n const didSetAutoHeightRef = useRef(false);\n\n const resizeTextarea = useCallback(() => {\n const el = inputRef.current;\n if (!el) return;\n if (!autoResize) {\n // Only undo a height this set, so an explicit one from `styles.input` survives.\n if (didSetAutoHeightRef.current) {\n el.style.height = '';\n didSetAutoHeightRef.current = false;\n }\n return;\n }\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n didSetAutoHeightRef.current = true;\n }, [autoResize]);\n\n // `currVal` is a dependency because the value can change without passing through\n // `onChangeHandler`: the clear button, a parent resetting it, or `formValidator.set` elsewhere.\n useEffect(() => {\n resizeTextarea();\n }, [resizeTextarea, currVal]);\n\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n setTimeout(() => {\n inputRef.current?.focus();\n }, 1);\n }\n }, [autoFocus]);\n\n useEffect(() => {\n fvRef.current = formValidator;\n const fv = fvRef.current;\n if (!fv) return;\n fv.label = label ?? '';\n fv.validate();\n const listener = () => forceUpdate((n) => n + 1);\n fv.registerOnUpdateListener(listener);\n return () => {\n fv.removeOnUpdateListener(listener);\n };\n }, [formValidator, label]);\n\n const hasError = (): boolean => {\n return formValidator ? formValidator.touched && formValidator.hasError() : !isValid || !!errorMessage;\n };\n\n const computedIsRequired = (): boolean => {\n return !!(\n isRequired ||\n (formValidator &&\n formValidator.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required'))\n );\n };\n\n const onMouseEnterHandler = (event: React.MouseEvent) => {\n setIsHovered(true);\n if (onMouseEnterProp) onMouseEnterProp(event);\n };\n\n const onMouseLeaveHandler = (event: React.MouseEvent) => {\n setIsHovered(false);\n if (onMouseLeaveProp) onMouseLeaveProp(event);\n };\n\n const onFocusHandler = (event: React.FocusEvent) => {\n setIsFocused(true);\n if (onFocusProp) onFocusProp(event);\n };\n\n const onBlurHandler = (event: React.FocusEvent) => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n if (onBlurProp) onBlurProp(event);\n };\n\n const onChangeHandler = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string): void => {\n let parsedEvent: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | undefined;\n let val: string;\n\n if (typeof event !== 'string') {\n parsedEvent = event;\n val = event.target.value;\n } else {\n val = event;\n }\n\n if (parse) val = parse(val);\n if (formValidator) formValidator.set(val);\n if (onChange) onChange(val, parsedEvent);\n resizeTextarea();\n };\n\n const getInputType = (): string | undefined => {\n if (type === InputType.Email) return undefined;\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n if (type === 'password' && isPasswordShown) return 'text';\n return type;\n };\n\n const getInputMode = (): React.HTMLAttributes<HTMLInputElement>['inputMode'] => {\n if (type === InputType.Email) return 'email';\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n return undefined;\n };\n\n const hasIcon = type && type !== InputType.Date && type !== InputType.Iban && type !== InputType.HasNoIcon;\n\n const isFunctionalIconType = type === InputType.Search || type === InputType.Password;\n const hasCustomIcon = !!icon;\n const customIconApplies = hasCustomIcon && !isFunctionalIconType;\n\n const defaultsLeftWithoutMatLabel = type === InputType.Email || type === InputType.Phone || type === InputType.Search;\n const resolvedIconPosition =\n iconPosition ??\n (!useMatLabelStyle && defaultsLeftWithoutMatLabel ? InputIconPosition.Left : InputIconPosition.Right);\n const iconIsLeft = resolvedIconPosition === InputIconPosition.Left;\n\n const iconProps = {\n className: cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !onIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n }),\n onClick: onIconClick ?? undefined,\n ...keyboardActivationProps(onIconClick),\n };\n\n const customIcon = icon as React.ReactElement<{ className?: string; onClick?: React.MouseEventHandler }> | null;\n const resolvedCustomIconClick = onIconClick ?? customIcon?.props.onClick;\n const renderedIcon =\n customIconApplies && customIcon\n ? React.cloneElement(customIcon, {\n className: cx(\n styles.inputFieldIcon,\n {\n [styles.inputFieldIconNotClickable]: !resolvedCustomIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n },\n customIcon.props.className,\n ),\n onClick: resolvedCustomIconClick,\n ...keyboardActivationProps(resolvedCustomIconClick as ((event: React.SyntheticEvent) => void) | undefined),\n })\n : null;\n\n const hasLeftIcon = (hasIcon || hasCustomIcon) && iconIsLeft;\n\n const passwordIconProps = {\n className: cx(styles.inputFieldIcon, styles.inputFieldIconPassword, { [styles.inputFieldIconLeft]: iconIsLeft }),\n onClick: () => setIsPasswordShown(!isPasswordShown),\n ...keyboardActivationProps(() => setIsPasswordShown(!isPasswordShown)),\n 'aria-label': isPasswordShown ? text.hidePassword : text.showPassword,\n };\n\n const hasErr = hasError();\n\n let editedLabel = label;\n if (editedLabel && computedIsRequired()) editedLabel = `${editedLabel} *`;\n const requiredMark = computedIsRequired() ? <span className={styles.requiredMark}>*</span> : null;\n\n const showFocus = isFocused && !readOnly;\n const shouldFloatLabel =\n useMatLabelStyle && (alwaysFloatLabel || showFocus || currVal || isAutofilled || type === InputType.Date);\n\n const handleAutofillAnimation = (event: React.AnimationEvent) => {\n const { animationName } = event;\n if (animationName === styles.inputAutofillStart) {\n setIsAutofilled(true);\n // The field is controlled, so the commit this triggers would write `value` back over\n // what the browser just put there and blank it. Replay it as an ordinary change first.\n const filled = (event.currentTarget as HTMLInputElement).value;\n if (filled && filled !== String(currVal ?? '')) onChangeHandler(filled);\n return;\n }\n if (animationName === styles.inputAutofillEnd) {\n setIsAutofilled(false);\n return;\n }\n // Not ours. `onAnimationStart` arrives through `rest`, and the consumer must not receive\n // the two above: the `:not()` rule fires one of them on every mount.\n rest.onAnimationStart?.(event as React.AnimationEvent<HTMLInputElement>);\n };\n\n const isSearchCleared = type === InputType.Search && !!currVal;\n\n const customInputProps = customInput?.props as { className?: string; style?: React.CSSProperties } | undefined;\n\n function handleClear() {\n if (formValidator) formValidator.set('');\n onChange?.('');\n onClearClicked?.();\n }\n\n return (\n <div className={cx(styles.input, { [styles.inputIconLeft]: hasLeftIcon }, className)} style={style}>\n <label\n htmlFor={inputId}\n className={cx(styles.inputLabel, classNames?.label, {\n [styles.inputLabelColumn]: !isRow,\n [styles.inputLabelInBorder]: labelInBorder,\n })}\n style={slotStyles?.label}\n >\n {label && !useMatLabelStyle ? (\n <span className={styles.inputLabelText}>\n {label}\n {requiredMark}\n </span>\n ) : null}\n {upperRightLabel && (\n <div\n className={cx(styles.inputUpperRightLabel, classNames?.upperRightLabel)}\n style={slotStyles?.upperRightLabel}\n >\n {upperRightLabel}\n </div>\n )}\n <div\n className={cx(styles.inputContainer, { [styles.inputContainerMultiline]: multiline }, classNames?.container)}\n style={slotStyles?.container}\n onMouseEnter={onMouseEnterHandler}\n onMouseLeave={onMouseLeaveHandler}\n >\n {renderedIcon}\n {React.cloneElement(customInput || (multiline ? <textarea /> : <input />), {\n ...rest,\n className: cx(\n styles.inputField,\n {\n [styles.inputFieldUppercase]: isUppercase,\n [styles.inputFieldDate]: type === InputType.Date,\n [styles.inputFieldDefault]: type !== InputType.Date,\n [styles.inputFieldWithIcon]: hasIcon || hasCustomIcon,\n [styles.inputFieldWithIconLeft]: hasLeftIcon,\n [styles.inputFieldMultiline]: multiline,\n [styles.inputFieldMultilineAutoResize]: multiline && autoResize,\n [styles.inputFieldReadOnly]: readOnly && !disabled,\n },\n classNames?.input,\n customInputProps?.className,\n ),\n style:\n customInputProps?.style || slotStyles?.input\n ? { ...customInputProps?.style, ...slotStyles?.input }\n : undefined,\n name,\n id: inputId,\n value: currVal,\n tabIndex,\n ref: customInput ? undefined : mergeRefs(inputRef, ref),\n onChange: onChangeHandler,\n onAnimationStart: handleAutofillAnimation,\n onFocus: onFocusHandler,\n onBlur: onBlurHandler,\n placeholder: !useMatLabelStyle ? placeholder : '',\n autoComplete,\n onClick,\n readOnly,\n disabled,\n ...(!multiline && { type: getInputType(), inputMode: rest.inputMode ?? getInputMode(), min, max }),\n ...(multiline && rows !== undefined && { rows }),\n })}\n {suffix && (\n <div className={cx(styles.inputFieldSuffix, classNames?.suffix)} style={slotStyles?.suffix}>\n {suffix}\n </div>\n )}\n </div>\n <fieldset\n className={cx(styles.inputFieldset, classNames?.fieldset, {\n [styles.inputContainerBorderFocused]: showFocus,\n [styles.inputContainerBorderSearchFocused]: type === InputType.Search && (showFocus || !!currVal),\n [styles.inputContainerBorderInvalid]: hasErr,\n [styles.inputContainerBorderError]: hasErr,\n })}\n style={slotStyles?.fieldset}\n >\n <legend\n className={cx(styles.inputFieldsetLegend, {\n [styles.inputFieldsetLegendActive]: shouldFloatLabel,\n })}\n >\n <span>{editedLabel}</span>\n </legend>\n </fieldset>\n {useMatLabelStyle && label && (\n <div\n className={cx(styles.inputMatLabel, {\n [styles.inputMatLabelFloating]: shouldFloatLabel,\n [styles.inputMatLabelMultiline]: multiline && !shouldFloatLabel,\n })}\n >\n {label}\n {requiredMark}\n </div>\n )}\n {useMatLabelStyle && placeholder && (\n <div\n className={cx(\n styles.inputPlaceholder,\n showFocus && !currVal && !isAutofilled && styles.inputPlaceholderShown,\n multiline && styles.inputPlaceholderMultiline,\n )}\n >\n {placeholder}\n </div>\n )}\n <Tooltip\n variant='error'\n message={formValidator ? formValidator.getCurrentErrorMessage() : errorMessage || ''}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </label>\n\n {type === InputType.Phone && !hasCustomIcon && <FontAwesomeIcon icon={faPhone} {...iconProps} />}\n {type === InputType.Email && !hasCustomIcon && <FontAwesomeIcon icon={faEnvelope} {...iconProps} />}\n {type === InputType.Edit && !hasCustomIcon && <FontAwesomeIcon icon={faPen} {...iconProps} />}\n {type === InputType.Search && (\n <AnimatedIcon\n icon={isSearchCleared ? faXmark : faSearch}\n className={cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !isSearchCleared,\n [styles.inputFieldIconLeft]: iconIsLeft,\n })}\n onClick={isSearchCleared ? handleClear : undefined}\n {...keyboardActivationProps(isSearchCleared ? handleClear : undefined)}\n aria-label={isSearchCleared ? text.clearSearch : undefined}\n />\n )}\n {type === InputType.Password && (\n <FontAwesomeIcon icon={isPasswordShown ? passwordShownIcon : passwordHiddenIcon} {...passwordIconProps} />\n )}\n\n {((showCancel && currVal && (isFocused || isHovered)) || alwaysShowCancel) && type !== InputType.Search && (\n <FontAwesomeIcon\n icon={faXmark}\n className={styles.inputFieldIcon}\n onClick={handleClear}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n {...keyboardActivationProps(handleClear)}\n aria-label={text.clear}\n />\n )}\n </div>\n );\n}\n\nexport default Input;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"input.mjs","names":[],"sources":["../../../../package/common/input/input.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useId } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n faPhone,\n faPen,\n faEnvelope,\n faSearch,\n faXmark,\n faEye as passwordHiddenIcon,\n faEyeSlash as passwordShownIcon,\n} from '@fortawesome/free-solid-svg-icons';\nimport Tooltip from 'components/common/tooltip';\nimport AnimatedIcon from 'components/common/animatedIcon';\nimport { useComponentDefaults, useLabels } from 'components/common/configProvider';\nimport styles from './input.module.pcss';\nimport { mergeRefs } from '../utils/mergeRefs';\nimport type { InputLabels, InputProps } from './input.types';\nimport { InputType, InputIconPosition } from './input.types';\n\nconst DEFAULT_LABELS: Required<InputLabels> = {\n clear: 'Clear',\n showPassword: 'Show password',\n hidePassword: 'Hide password',\n clearSearch: 'Clear search',\n};\n\nfunction keyboardActivationProps(onActivate?: ((event: React.SyntheticEvent) => void) | null) {\n if (!onActivate) return undefined;\n return {\n role: 'button' as const,\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n onActivate(event);\n },\n };\n}\n\nfunction Input(props: InputProps) {\n const {\n name = '',\n id,\n label = '',\n errorMessage = '',\n isValid = true,\n className = '',\n style,\n value = '',\n icon = null,\n iconPosition,\n onChange = () => {},\n onFocus: onFocusProp = null,\n onBlur: onBlurProp = null,\n onMouseEnter: onMouseEnterProp = null,\n onMouseLeave: onMouseLeaveProp = null,\n isUppercase = false,\n isRequired = false,\n tabIndex = 0,\n type = undefined,\n isRow = false,\n onIconClick = null,\n parse = null,\n formValidator = null,\n autoFocus = false,\n suffix = null,\n upperRightLabel = null,\n labelInBorder = false,\n showCancel = false,\n onClearClicked,\n min = null,\n max = null,\n placeholder = '',\n useMatLabelStyle = true,\n alwaysFloatLabel = false,\n autoComplete = null,\n onClick = () => null,\n readOnly = false,\n customInput,\n alwaysShowCancel = false,\n multiline = false,\n rows,\n autoResize = false,\n classNames,\n styles: slotStyles,\n disabled = false,\n labels,\n ref,\n ...rest\n } = useComponentDefaults('Input', props);\n const text = useLabels('Input', labels, DEFAULT_LABELS);\n const [isFocused, setIsFocused] = useState(false);\n // Chrome fills a field on page load without firing anything React sees. The animation the\n // stylesheet binds to :-webkit-autofill is the only notification it gives.\n const [isAutofilled, setIsAutofilled] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [isPasswordShown, setIsPasswordShown] = useState(false);\n const [, forceUpdate] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);\n const fvRef = useRef(formValidator);\n\n const generatedId = useId();\n const inputId = id || name || generatedId;\n\n const currVal = formValidator ? formValidator.value : value;\n const didSetAutoHeightRef = useRef(false);\n\n const resizeTextarea = useCallback(() => {\n const el = inputRef.current;\n if (!el) return;\n if (!autoResize) {\n // Only undo a height this set, so an explicit one from `styles.input` survives.\n if (didSetAutoHeightRef.current) {\n el.style.height = '';\n didSetAutoHeightRef.current = false;\n }\n return;\n }\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n didSetAutoHeightRef.current = true;\n }, [autoResize]);\n\n // `currVal` is a dependency because the value can change without passing through\n // `onChangeHandler`: the clear button, a parent resetting it, or `formValidator.set` elsewhere.\n useEffect(() => {\n resizeTextarea();\n }, [resizeTextarea, currVal]);\n\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n setTimeout(() => {\n inputRef.current?.focus();\n }, 1);\n }\n }, [autoFocus]);\n\n useEffect(() => {\n fvRef.current = formValidator;\n const fv = fvRef.current;\n if (!fv) return;\n fv.label = label ?? '';\n fv.validate();\n const listener = () => forceUpdate((n) => n + 1);\n fv.registerOnUpdateListener(listener);\n return () => {\n fv.removeOnUpdateListener(listener);\n };\n }, [formValidator, label]);\n\n const hasError = (): boolean => {\n return formValidator ? formValidator.touched && formValidator.hasError() : !isValid || !!errorMessage;\n };\n\n const computedIsRequired = (): boolean => {\n return !!(\n isRequired ||\n (formValidator &&\n formValidator.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required'))\n );\n };\n\n const onMouseEnterHandler = (event: React.MouseEvent) => {\n setIsHovered(true);\n if (onMouseEnterProp) onMouseEnterProp(event);\n };\n\n const onMouseLeaveHandler = (event: React.MouseEvent) => {\n setIsHovered(false);\n if (onMouseLeaveProp) onMouseLeaveProp(event);\n };\n\n const onFocusHandler = (event: React.FocusEvent) => {\n setIsFocused(true);\n if (onFocusProp) onFocusProp(event);\n };\n\n const onBlurHandler = (event: React.FocusEvent) => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n if (onBlurProp) onBlurProp(event);\n };\n\n const onChangeHandler = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string): void => {\n let parsedEvent: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | undefined;\n let val: string;\n\n if (typeof event !== 'string') {\n parsedEvent = event;\n val = event.target.value;\n } else {\n val = event;\n }\n\n if (parse) val = parse(val);\n if (formValidator) formValidator.set(val);\n if (onChange) onChange(val, parsedEvent);\n resizeTextarea();\n };\n\n const getInputType = (): string | undefined => {\n if (type === InputType.Email) return undefined;\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n if (type === 'password' && isPasswordShown) return 'text';\n return type;\n };\n\n const getInputMode = (): React.HTMLAttributes<HTMLInputElement>['inputMode'] => {\n if (type === InputType.Email) return 'email';\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n return undefined;\n };\n\n const hasIcon = type && type !== InputType.Date && type !== InputType.Iban && type !== InputType.HasNoIcon;\n\n const isFunctionalIconType = type === InputType.Search || type === InputType.Password;\n const hasCustomIcon = !!icon;\n const customIconApplies = hasCustomIcon && !isFunctionalIconType;\n\n const defaultsLeftWithoutMatLabel = type === InputType.Email || type === InputType.Phone || type === InputType.Search;\n const resolvedIconPosition =\n iconPosition ??\n (!useMatLabelStyle && defaultsLeftWithoutMatLabel ? InputIconPosition.Left : InputIconPosition.Right);\n const iconIsLeft = resolvedIconPosition === InputIconPosition.Left;\n\n const iconProps = {\n className: cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !onIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n }),\n onClick: onIconClick ?? undefined,\n ...keyboardActivationProps(onIconClick),\n };\n\n const customIcon = icon as React.ReactElement<{ className?: string; onClick?: React.MouseEventHandler }> | null;\n const resolvedCustomIconClick = onIconClick ?? customIcon?.props.onClick;\n const renderedIcon =\n customIconApplies && customIcon\n ? React.cloneElement(customIcon, {\n className: cx(\n styles.inputFieldIcon,\n {\n [styles.inputFieldIconNotClickable]: !resolvedCustomIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n },\n customIcon.props.className,\n ),\n onClick: resolvedCustomIconClick,\n ...keyboardActivationProps(resolvedCustomIconClick as ((event: React.SyntheticEvent) => void) | undefined),\n })\n : null;\n\n const hasLeftIcon = (hasIcon || hasCustomIcon) && iconIsLeft;\n\n const passwordIconProps = {\n className: cx(styles.inputFieldIcon, styles.inputFieldIconPassword, { [styles.inputFieldIconLeft]: iconIsLeft }),\n onClick: () => setIsPasswordShown(!isPasswordShown),\n ...keyboardActivationProps(() => setIsPasswordShown(!isPasswordShown)),\n 'aria-label': isPasswordShown ? text.hidePassword : text.showPassword,\n };\n\n const hasErr = hasError();\n\n let editedLabel = label;\n if (editedLabel && computedIsRequired()) editedLabel = `${editedLabel} *`;\n const requiredMark = computedIsRequired() ? <span className={styles.requiredMark}>*</span> : null;\n\n const showFocus = isFocused && !readOnly;\n const shouldFloatLabel =\n useMatLabelStyle && (alwaysFloatLabel || showFocus || currVal || isAutofilled || type === InputType.Date);\n\n const handleAutofillAnimation = (event: React.AnimationEvent) => {\n const { animationName } = event;\n if (animationName === styles.inputAutofillStart) {\n setIsAutofilled(true);\n // The field is controlled, so the commit this triggers would write `value` back over\n // what the browser just put there and blank it. Replay it as an ordinary change first.\n const filled = (event.currentTarget as HTMLInputElement).value;\n if (filled && filled !== String(currVal ?? '')) onChangeHandler(filled);\n return;\n }\n if (animationName === styles.inputAutofillEnd) {\n setIsAutofilled(false);\n return;\n }\n // Not ours. `onAnimationStart` arrives through `rest`, and the consumer must not receive\n // the two above: the `:not()` rule fires one of them on every mount.\n rest.onAnimationStart?.(event as React.AnimationEvent<HTMLInputElement>);\n };\n\n const isSearchCleared = type === InputType.Search && !!currVal;\n\n const customInputProps = customInput?.props as { className?: string; style?: React.CSSProperties } | undefined;\n\n function handleClear() {\n if (formValidator) formValidator.set('');\n onChange?.('');\n onClearClicked?.();\n }\n\n return (\n <div className={cx(styles.input, { [styles.inputIconLeft]: hasLeftIcon }, className)} style={style}>\n <label\n htmlFor={inputId}\n className={cx(styles.inputLabel, classNames?.label, {\n [styles.inputLabelColumn]: !isRow,\n [styles.inputLabelInBorder]: labelInBorder,\n })}\n style={slotStyles?.label}\n >\n {label && !useMatLabelStyle ? (\n <span className={styles.inputLabelText}>\n {label}\n {requiredMark}\n </span>\n ) : null}\n {upperRightLabel && (\n <div\n className={cx(styles.inputUpperRightLabel, classNames?.upperRightLabel)}\n style={slotStyles?.upperRightLabel}\n >\n {upperRightLabel}\n </div>\n )}\n <div\n className={cx(styles.inputContainer, { [styles.inputContainerMultiline]: multiline }, classNames?.container)}\n style={slotStyles?.container}\n onMouseEnter={onMouseEnterHandler}\n onMouseLeave={onMouseLeaveHandler}\n >\n {renderedIcon}\n {React.cloneElement(customInput || (multiline ? <textarea /> : <input />), {\n ...rest,\n className: cx(\n styles.inputField,\n {\n [styles.inputFieldUppercase]: isUppercase,\n [styles.inputFieldDate]: type === InputType.Date,\n [styles.inputFieldDefault]: type !== InputType.Date,\n [styles.inputFieldWithIcon]: hasIcon || hasCustomIcon,\n [styles.inputFieldWithIconLeft]: hasLeftIcon,\n [styles.inputFieldMultiline]: multiline,\n [styles.inputFieldMultilineAutoResize]: multiline && autoResize,\n [styles.inputFieldReadOnly]: readOnly && !disabled,\n },\n classNames?.input,\n customInputProps?.className,\n ),\n style:\n customInputProps?.style || slotStyles?.input\n ? { ...customInputProps?.style, ...slotStyles?.input }\n : undefined,\n name,\n id: inputId,\n value: currVal,\n tabIndex,\n ref: customInput ? undefined : mergeRefs(inputRef, ref),\n onChange: onChangeHandler,\n onAnimationStart: handleAutofillAnimation,\n onFocus: onFocusHandler,\n onBlur: onBlurHandler,\n placeholder: !useMatLabelStyle ? placeholder : '',\n autoComplete,\n onClick,\n readOnly,\n disabled,\n ...(!multiline && { type: getInputType(), inputMode: rest.inputMode ?? getInputMode(), min, max }),\n ...(multiline && rows !== undefined && { rows }),\n })}\n {suffix && (\n <div className={cx(styles.inputFieldSuffix, classNames?.suffix)} style={slotStyles?.suffix}>\n {suffix}\n </div>\n )}\n </div>\n <fieldset\n className={cx(styles.inputFieldset, classNames?.fieldset, {\n [styles.inputContainerBorderFocused]: showFocus,\n [styles.inputContainerBorderSearchFocused]: type === InputType.Search && (showFocus || !!currVal),\n [styles.inputContainerBorderInvalid]: hasErr,\n [styles.inputContainerBorderError]: hasErr,\n })}\n style={slotStyles?.fieldset}\n >\n <legend\n className={cx(styles.inputFieldsetLegend, {\n [styles.inputFieldsetLegendActive]: shouldFloatLabel,\n })}\n >\n <span>{editedLabel}</span>\n </legend>\n </fieldset>\n {useMatLabelStyle && label && (\n <div\n className={cx(styles.inputMatLabel, {\n [styles.inputMatLabelFloating]: shouldFloatLabel,\n [styles.inputMatLabelMultiline]: multiline && !shouldFloatLabel,\n })}\n >\n {label}\n {requiredMark}\n </div>\n )}\n {useMatLabelStyle && placeholder && (\n <div\n className={cx(\n styles.inputPlaceholder,\n showFocus && !currVal && !isAutofilled && styles.inputPlaceholderShown,\n multiline && styles.inputPlaceholderMultiline,\n )}\n >\n {placeholder}\n </div>\n )}\n <Tooltip\n variant='error'\n message={formValidator ? formValidator.getCurrentErrorMessage() : errorMessage || ''}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </label>\n\n {type === InputType.Phone && !hasCustomIcon && <FontAwesomeIcon icon={faPhone} {...iconProps} />}\n {type === InputType.Email && !hasCustomIcon && <FontAwesomeIcon icon={faEnvelope} {...iconProps} />}\n {type === InputType.Edit && !hasCustomIcon && <FontAwesomeIcon icon={faPen} {...iconProps} />}\n {type === InputType.Search && (\n <AnimatedIcon\n icon={isSearchCleared ? faXmark : faSearch}\n className={cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !isSearchCleared,\n [styles.inputFieldIconLeft]: iconIsLeft,\n })}\n onClick={isSearchCleared ? handleClear : undefined}\n {...keyboardActivationProps(isSearchCleared ? handleClear : undefined)}\n aria-label={isSearchCleared ? text.clearSearch : undefined}\n />\n )}\n {type === InputType.Password && (\n <FontAwesomeIcon icon={isPasswordShown ? passwordShownIcon : passwordHiddenIcon} {...passwordIconProps} />\n )}\n\n {((showCancel && currVal && (isFocused || isHovered)) || alwaysShowCancel) && type !== InputType.Search && (\n <FontAwesomeIcon\n icon={faXmark}\n className={styles.inputFieldIcon}\n onClick={handleClear}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n {...keyboardActivationProps(handleClear)}\n aria-label={text.clear}\n />\n )}\n </div>\n );\n}\n\nexport default Input;\n"],"mappings":"4wBAoBA,IAAM,GAAwC,CAC5C,MAAO,QACP,aAAc,gBACd,aAAc,gBACd,YAAa,cACf,EAEA,SAAS,EAAwB,EAA6D,CACvF,KACL,MAAO,CACL,KAAM,SACN,SAAU,EACV,UAAY,GAA+B,EACrC,EAAM,MAAQ,SAAW,EAAM,MAAQ,OAC3C,EAAM,eAAe,EACrB,EAAW,CAAK,EAClB,CACF,CACF,CAEA,SAAS,GAAM,GAAmB,CAChC,GAAM,CACJ,QAAO,GACP,MACA,QAAQ,GACR,eAAe,GACf,WAAU,GACV,aAAY,GACZ,SACA,SAAQ,GACR,OAAO,KACP,gBACA,eAAiB,CAAC,EAClB,QAAS,GAAc,KACvB,OAAQ,GAAa,KACrB,aAAc,GAAmB,KACjC,aAAc,GAAmB,KACjC,eAAc,GACd,cAAa,GACb,YAAW,EACX,OAAO,IAAA,GACP,SAAQ,GACR,cAAc,KACd,SAAQ,KACR,gBAAgB,KAChB,aAAY,GACZ,UAAS,KACT,kBAAkB,KAClB,iBAAgB,GAChB,cAAa,GACb,kBACA,OAAM,KACN,OAAM,KACN,cAAc,GACd,mBAAmB,GACnB,oBAAmB,GACnB,gBAAe,KACf,eAAgB,KAChB,WAAW,GACX,cACA,oBAAmB,GACnB,YAAY,GACZ,QACA,aAAa,GACb,aACA,OAAQ,EACR,YAAW,GACX,UACA,OACA,GAAG,GACD,EAAqB,QAAS,EAAK,EACjC,EAAO,EAAU,QAAS,GAAQ,EAAc,EAChD,CAAC,EAAW,IAAgB,EAAS,EAAK,EAG1C,CAAC,GAAc,GAAmB,EAAS,EAAK,EAChD,CAAC,EAAW,GAAgB,EAAS,EAAK,EAC1C,CAAC,EAAiB,GAAsB,EAAS,EAAK,EACtD,EAAG,IAAe,EAAS,CAAC,EAE5B,EAAW,EAA+C,IAAI,EAC9D,EAAQ,EAAO,CAAa,EAE5B,GAAc,GAAM,EACpB,GAAU,IAAM,IAAQ,GAExB,EAAU,EAAgB,EAAc,MAAQ,GAChD,GAAsB,EAAO,EAAK,EAElC,EAAiB,OAAkB,CACvC,IAAM,EAAK,EAAS,QACf,KACL,IAAI,CAAC,EAAY,CAEf,AAEE,GAAoB,WADpB,EAAG,MAAM,OAAS,GACY,IAEhC,MACF,CACA,EAAG,MAAM,OAAS,OAClB,EAAG,MAAM,OAAS,GAAG,EAAG,aAAa,IACrC,GAAoB,QAAU,EAH9B,CAIF,EAAG,CAAC,CAAU,CAAC,EAIf,MAAgB,CACd,EAAe,CACjB,EAAG,CAAC,EAAgB,CAAO,CAAC,EAE5B,MAAgB,CACV,IAAa,EAAS,SACxB,eAAiB,CACf,EAAS,SAAS,MAAM,CAC1B,EAAG,CAAC,CAER,EAAG,CAAC,EAAS,CAAC,EAEd,MAAgB,CACd,EAAM,QAAU,EAChB,IAAM,EAAK,EAAM,QACjB,GAAI,CAAC,EAAI,OACT,EAAG,MAAQ,GAAS,GACpB,EAAG,SAAS,EACZ,IAAM,MAAiB,GAAa,GAAM,EAAI,CAAC,EAE/C,OADA,EAAG,yBAAyB,CAAQ,MACvB,CACX,EAAG,uBAAuB,CAAQ,CACpC,CACF,EAAG,CAAC,EAAe,CAAK,CAAC,EAEzB,IAAM,OACG,EAAgB,EAAc,SAAW,EAAc,SAAS,EAAI,CAAC,IAAW,CAAC,CAAC,EAGrF,OACG,CAAC,EACN,IACC,GACC,EAAc,WAAW,KAAM,GAAO,EAA+B,cAAgB,UAAU,GAI/F,GAAuB,GAA4B,CACvD,EAAa,EAAI,EACb,IAAkB,GAAiB,CAAK,CAC9C,EAEM,GAAuB,GAA4B,CACvD,EAAa,EAAK,EACd,IAAkB,GAAiB,CAAK,CAC9C,EAEM,GAAkB,GAA4B,CAClD,GAAa,EAAI,EACb,IAAa,GAAY,CAAK,CACpC,EAEM,GAAiB,GAA4B,CAC7C,EAAM,UAAS,EAAM,QAAQ,QAAU,IAC3C,GAAa,EAAK,EACd,IAAY,GAAW,CAAK,CAClC,EAEM,GAAmB,GAAoF,CAC3G,IAAI,EACA,EAEA,OAAO,GAAU,SAInB,EAAM,GAHN,EAAc,EACd,EAAM,EAAM,OAAO,OAKjB,KAAO,EAAM,GAAM,CAAG,GACtB,GAAe,EAAc,IAAI,CAAG,EACpC,GAAU,EAAS,EAAK,CAAW,EACvC,EAAe,CACjB,EAEM,OAAyC,CACzC,OAAS,EAAU,MAIvB,OAHI,IAAS,EAAU,MAAc,MACjC,IAAS,EAAU,OAAe,SAClC,IAAS,YAAc,EAAwB,OAC5C,CACT,EAEM,OAA0E,CAC9E,GAAI,IAAS,EAAU,MAAO,MAAO,QACrC,GAAI,IAAS,EAAU,MAAO,MAAO,MACrC,GAAI,IAAS,EAAU,OAAQ,MAAO,QAExC,EAEM,GAAU,GAAQ,IAAS,EAAU,MAAQ,IAAS,EAAU,MAAQ,IAAS,EAAU,UAE3F,GAAuB,IAAS,EAAU,QAAU,IAAS,EAAU,SACvE,EAAgB,CAAC,CAAC,EAClB,GAAoB,GAAiB,CAAC,GAEtC,GAA8B,IAAS,EAAU,OAAS,IAAS,EAAU,OAAS,IAAS,EAAU,OAIzG,GAFJ,KACC,CAAC,GAAoB,GAA8B,EAAkB,KAAO,EAAkB,UACrD,EAAkB,KAExD,EAAY,CAChB,UAAW,EAAG,EAAO,eAAgB,EAClC,EAAO,4BAA6B,CAAC,GACrC,EAAO,oBAAqB,CAC/B,CAAC,EACD,QAAS,GAAe,IAAA,GACxB,GAAG,EAAwB,CAAW,CACxC,EAEM,EAAa,EACb,EAA0B,GAAe,GAAY,MAAM,QAC3D,GACJ,IAAqB,EACjB,GAAM,aAAa,EAAY,CAC7B,UAAW,EACT,EAAO,eACP,EACG,EAAO,4BAA6B,CAAC,GACrC,EAAO,oBAAqB,CAC/B,EACA,EAAW,MAAM,SACnB,EACA,QAAS,EACT,GAAG,EAAwB,CAA8E,CAC3G,CAAC,EACD,KAEA,IAAe,IAAW,IAAkB,EAE5C,GAAoB,CACxB,UAAW,EAAG,EAAO,eAAgB,EAAO,uBAAwB,EAAG,EAAO,oBAAqB,CAAW,CAAC,EAC/G,YAAe,EAAmB,CAAC,CAAe,EAClD,GAAG,MAA8B,EAAmB,CAAC,CAAe,CAAC,EACrE,aAAc,EAAkB,EAAK,aAAe,EAAK,YAC3D,EAEM,EAAS,GAAS,EAEpB,EAAc,EACd,GAAe,GAAmB,IAAG,EAAc,GAAG,EAAY,KACtE,IAAM,GAAe,GAAmB,EAAI,EAAC,OAAD,CAAM,UAAW,EAAO,aAAc,SAAA,GAAO,CAAA,EAAI,KAEvF,EAAY,GAAa,CAAC,EAC1B,EACJ,IAAqB,IAAoB,GAAa,GAAW,IAAgB,IAAS,EAAU,MAEhG,GAA2B,GAAgC,CAC/D,GAAM,CAAE,iBAAkB,EAC1B,GAAI,IAAkB,EAAO,mBAAoB,CAC/C,EAAgB,EAAI,EAGpB,IAAM,EAAU,EAAM,cAAmC,MACrD,GAAU,IAAW,OAAO,GAAW,EAAE,GAAG,GAAgB,CAAM,EACtE,MACF,CACA,GAAI,IAAkB,EAAO,iBAAkB,CAC7C,EAAgB,EAAK,EACrB,MACF,CAGA,EAAK,mBAAmB,CAA+C,CACzE,EAEM,EAAkB,IAAS,EAAU,QAAU,CAAC,CAAC,EAEjD,EAAmB,GAAa,MAEtC,SAAS,GAAc,CACjB,GAAe,EAAc,IAAI,EAAE,EACvC,IAAW,EAAE,EACb,KAAiB,CACnB,CAEA,OACE,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,MAAO,EAAG,EAAO,eAAgB,EAAY,EAAG,EAAS,EAAU,SAA7F,SAAA,CACE,EAAC,QAAD,CACE,QAAS,GACT,UAAW,EAAG,EAAO,WAAY,GAAY,MAAO,EACjD,EAAO,kBAAmB,CAAC,IAC3B,EAAO,oBAAqB,EAC/B,CAAC,EACD,MAAO,GAAY,MANrB,SAAA,CAQG,GAAS,CAAC,EACT,EAAC,OAAD,CAAM,UAAW,EAAO,eAAxB,SAAA,CACG,EACA,EACG,CACJ,CAAA,EAAA,KACH,GACC,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,qBAAsB,GAAY,eAAe,EACtE,MAAO,GAAY,gBAElB,SAAA,CACE,CAAA,EAEP,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,eAAgB,EAAG,EAAO,yBAA0B,CAAU,EAAG,GAAY,SAAS,EAC3G,MAAO,GAAY,UACnB,aAAc,GACd,aAAc,GAJhB,SAAA,CAMG,GACA,GAAM,aAAa,GAA4B,EAAZ,EAAa,WAAe,QAAhB,CAAW,CAAY,EAAI,CACzE,GAAG,EACH,UAAW,EACT,EAAO,WACP,EACG,EAAO,qBAAsB,IAC7B,EAAO,gBAAiB,IAAS,EAAU,MAC3C,EAAO,mBAAoB,IAAS,EAAU,MAC9C,EAAO,oBAAqB,IAAW,GACvC,EAAO,wBAAyB,IAChC,EAAO,qBAAsB,GAC7B,EAAO,+BAAgC,GAAa,GACpD,EAAO,oBAAqB,GAAY,CAAC,EAC5C,EACA,GAAY,MACZ,GAAkB,SACpB,EACA,MACE,GAAkB,OAAS,GAAY,MACnC,CAAE,GAAG,GAAkB,MAAO,GAAG,GAAY,KAAM,EACnD,IAAA,GACN,QACA,GAAI,GACJ,MAAO,EACP,YACA,IAAK,EAAc,IAAA,GAAY,EAAU,EAAU,EAAG,EACtD,SAAU,GACV,iBAAkB,GAClB,QAAS,GACT,OAAQ,GACR,YAAc,EAAiC,GAAd,EACjC,gBACA,WACA,WACA,YACA,GAAI,CAAC,GAAa,CAAE,KAAM,GAAa,EAAG,UAAW,EAAK,WAAa,GAAa,EAAG,OAAK,MAAI,EAChG,GAAI,GAAa,KAAS,IAAA,IAAa,CAAE,OAAK,CAChD,CAAC,EACA,IACC,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,iBAAkB,GAAY,MAAM,EAAG,MAAO,GAAY,OACjF,SAAA,EACE,CAAA,CAEJ,IACL,EAAC,WAAD,CACE,UAAW,EAAG,EAAO,cAAe,GAAY,SAAU,EACvD,EAAO,6BAA8B,GACrC,EAAO,mCAAoC,IAAS,EAAU,SAAW,GAAa,CAAC,CAAC,IACxF,EAAO,6BAA8B,GACrC,EAAO,2BAA4B,CACtC,CAAC,EACD,MAAO,GAAY,SAEnB,SAAA,EAAC,SAAD,CACE,UAAW,EAAG,EAAO,oBAAqB,EACvC,EAAO,2BAA4B,CACtC,CAAC,EAED,SAAA,EAAC,OAAD,CAAA,SAAO,CAAkB,CAAA,CACnB,CAAA,CACA,CAAA,EACT,GAAoB,GACnB,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,cAAe,EACjC,EAAO,uBAAwB,GAC/B,EAAO,wBAAyB,GAAa,CAAC,CACjD,CAAC,EAJH,SAAA,CAMG,EACA,EACE,IAEN,GAAoB,GACnB,EAAC,MAAD,CACE,UAAW,EACT,EAAO,iBACP,GAAa,CAAC,GAAW,CAAC,IAAgB,EAAO,sBACjD,GAAa,EAAO,yBACtB,EAEC,SAAA,CACE,CAAA,EAEP,EAAC,GAAD,CACE,QAAQ,QACR,QAAS,EAAgB,EAAc,uBAAuB,EAAI,GAAgB,GAClF,UAAW,IAAW,GAAa,EACpC,CAAA,CACI,IAEN,IAAS,EAAU,OAAS,CAAC,GAAiB,EAAC,EAAD,CAAiB,KAAM,GAAS,GAAI,CAAY,CAAA,EAC9F,IAAS,EAAU,OAAS,CAAC,GAAiB,EAAC,EAAD,CAAiB,KAAM,GAAY,GAAI,CAAY,CAAA,EACjG,IAAS,EAAU,MAAQ,CAAC,GAAiB,EAAC,EAAD,CAAiB,KAAM,GAAO,GAAI,CAAY,CAAA,EAC3F,IAAS,EAAU,QAClB,EAAC,GAAD,CACE,KAAM,EAAkB,GAAU,GAClC,UAAW,EAAG,EAAO,eAAgB,EAClC,EAAO,4BAA6B,CAAC,GACrC,EAAO,oBAAqB,CAC/B,CAAC,EACD,QAAS,EAAkB,EAAc,IAAA,GACzC,GAAI,EAAwB,EAAkB,EAAc,IAAA,EAAS,EACrE,aAAY,EAAkB,EAAK,YAAc,IAAA,EAClD,CAAA,EAEF,IAAS,EAAU,UAClB,EAAC,EAAD,CAAiB,KAAM,EAAkB,GAAoB,GAAoB,GAAI,EAAoB,CAAA,GAGxG,IAAc,IAAY,GAAa,IAAe,KAAqB,IAAS,EAAU,QAC/F,EAAC,EAAD,CACE,KAAM,GACN,UAAW,EAAO,eAClB,QAAS,EACT,iBAAoB,EAAa,EAAI,EACrC,iBAAoB,EAAa,EAAK,EACtC,GAAI,EAAwB,CAAW,EACvC,aAAY,EAAK,KAClB,CAAA,CAEA,GAET"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{usePresentationDefault as n}from"../configProvider/usePresentationDefault.mjs";import r from"../bodyEnd/bodyEnd.mjs";import i from"../styles/sheet.module.mjs";import{useVisualViewportSize as a}from"../hooks/useVisualViewportSize.mjs";import o from"../hooks/useSheet.mjs";import{useOverlay as s}from"../hooks/useOverlay.mjs";import c from"../styles/scrollFade.module.mjs";import l from"./modal.module.mjs";import{useScrollEdges as u}from"../hooks/useScrollEdges.mjs";import{useEffect as d,useId as f,useRef as p,useState as m}from"react";import h from"classnames";import{FontAwesomeIcon as g}from"@fortawesome/react-fontawesome";import{faXmark as _}from"@fortawesome/free-solid-svg-icons";import{jsx as v,jsxs as y}from"react/jsx-runtime";var b={close:`Close`};function x(x){let{children:S=null,title:C
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{usePresentationDefault as n}from"../configProvider/usePresentationDefault.mjs";import r from"../bodyEnd/bodyEnd.mjs";import i from"../styles/sheet.module.mjs";import{useVisualViewportSize as a}from"../hooks/useVisualViewportSize.mjs";import o from"../hooks/useSheet.mjs";import{useOverlay as s}from"../hooks/useOverlay.mjs";import c from"../styles/scrollFade.module.mjs";import l from"./modal.module.mjs";import{useScrollEdges as u}from"../hooks/useScrollEdges.mjs";import{useEffect as d,useId as f,useRef as p,useState as m}from"react";import h from"classnames";import{FontAwesomeIcon as g}from"@fortawesome/react-fontawesome";import{faXmark as _}from"@fortawesome/free-solid-svg-icons";import{jsx as v,jsxs as y}from"react/jsx-runtime";var b={close:`Close`};function x(x){let{children:S=null,title:C,isOpen:w=!1,onClose:T=()=>null,footer:E=null,className:D=``,style:O,hideHeader:k=!1,closeOnEscape:A=!0,presentation:j,classNames:M,styles:N,labels:P,...F}=e(`Modal`,x),I=t(`Modal`,P,b),[L,R]=m(w),[z,B]=m(w),V=p(null),H=p(null),U=f(),{height:W,offsetTop:G}=a(),K=n(),{isSheet:q,sheetStyle:J}=o(j??K);d(()=>{w?(R(w),setTimeout(()=>B(!0),1)):(B(!1),setTimeout(()=>R(w),300))},[w]),s({isActive:L&&z,containerRef:V,onEscape:A?T:void 0});let{hasStart:Y,hasEnd:X}=u(H,{isEnabled:L&&z});if(!L)return null;let Z=!k&&!!C;return v(r,{children:y(`div`,{className:h(l.modalContainer,M?.container),style:{height:W,top:G,...N?.container},children:[v(`div`,{className:h(l.modalWrapper,z&&l.modalWrapperShown,M?.backdrop),style:N?.backdrop,onClick:T}),z&&y(`div`,{...F,ref:V,role:`dialog`,"aria-modal":`true`,"aria-labelledby":Z&&!F[`aria-label`]?U:void 0,tabIndex:-1,className:h(l.modal,z&&l.modalShown,q&&[i.sheet,i.sheetSurface,l.modalSheet],D,M?.modal),style:{...q?J:void 0,...O,...N?.modal},onClick:e=>e.stopPropagation(),children:[!k&&y(`div`,{className:h(l.modalHeader,M?.header),style:N?.header,children:[v(`div`,{id:U,className:M?.title,style:N?.title,children:C}),v(`button`,{type:`button`,onClick:T,"aria-label":I.close,className:h(l.modalCloseButton,M?.closeButton),style:N?.closeButton,children:v(g,{icon:_})})]}),v(`div`,{ref:H,className:h(l.modalBody,c.scrollFade,c.scrollFadeY,Y&&c.scrollFadeFadedStart,X&&c.scrollFadeFadedEnd,M?.body),style:N?.body,children:S}),E&&v(`div`,{className:h(l.modalFooter,M?.footer),style:N?.footer,children:E})]})]})})}export{x as default};
|
|
2
2
|
//# sourceMappingURL=modal.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.mjs","names":[],"sources":["../../../../package/common/modal/modal.tsx"],"sourcesContent":["import cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './modal.module.pcss';\nimport sheetStyles from 'components/common/styles/sheet.module.pcss';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faXmark as closeIcon } from '@fortawesome/free-solid-svg-icons';\nimport { ModalProps } from './modal.types';\nimport type { ModalLabels } from './modal.types';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport { useVisualViewportSize } from 'components/common/hooks/useVisualViewportSize';\nimport { useOverlay } from 'components/common/hooks/useOverlay';\nimport { useSheet } from 'components/common/hooks/useSheet';\nimport { useScrollEdges } from 'components/common/hooks/useScrollEdges';\nimport fadeStyles from 'components/common/styles/scrollFade.module.pcss';\nimport { useComponentDefaults, useLabels, usePresentationDefault } from 'components/common/configProvider';\n\nconst DEFAULT_LABELS: Required<ModalLabels> = {\n close: 'Close',\n};\n\nfunction Modal(props: ModalProps) {\n const {\n children = null,\n title
|
|
1
|
+
{"version":3,"file":"modal.mjs","names":[],"sources":["../../../../package/common/modal/modal.tsx"],"sourcesContent":["import cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './modal.module.pcss';\nimport sheetStyles from 'components/common/styles/sheet.module.pcss';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faXmark as closeIcon } from '@fortawesome/free-solid-svg-icons';\nimport { ModalProps } from './modal.types';\nimport type { ModalLabels } from './modal.types';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport { useVisualViewportSize } from 'components/common/hooks/useVisualViewportSize';\nimport { useOverlay } from 'components/common/hooks/useOverlay';\nimport { useSheet } from 'components/common/hooks/useSheet';\nimport { useScrollEdges } from 'components/common/hooks/useScrollEdges';\nimport fadeStyles from 'components/common/styles/scrollFade.module.pcss';\nimport { useComponentDefaults, useLabels, usePresentationDefault } from 'components/common/configProvider';\n\nconst DEFAULT_LABELS: Required<ModalLabels> = {\n close: 'Close',\n};\n\nfunction Modal(props: ModalProps) {\n const {\n children = null,\n title,\n isOpen = false,\n onClose = () => null,\n footer = null,\n className = '',\n style,\n hideHeader = false,\n closeOnEscape = true,\n presentation: presentationProp,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n } = useComponentDefaults('Modal', props);\n const text = useLabels('Modal', labels, DEFAULT_LABELS);\n const [isRendered, setIsRendered] = useState(isOpen);\n const [animateIn, setAnimateIn] = useState(isOpen);\n const modalRef = useRef<HTMLDivElement>(null);\n const bodyRef = useRef<HTMLDivElement>(null);\n const titleId = useId();\n // Centering/sizing against the actually-visible viewport (not the full layout viewport) keeps\n // the modal — and whatever's focused inside it — from ending up under a mobile keyboard.\n const { height: viewportHeight, offsetTop: viewportOffsetTop } = useVisualViewportSize();\n // Explicit prop → this component's global default → the app-wide one. There's no built-in\n // fallback to add: `Default` and no presentation at all both mean the ordinary centred dialog.\n const appPresentation = usePresentationDefault();\n const presentation = presentationProp ?? appPresentation;\n const { isSheet, sheetStyle } = useSheet(presentation);\n\n useEffect(() => {\n if (isOpen) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsRendered(isOpen);\n setTimeout(() => setAnimateIn(true), 1);\n } else {\n setAnimateIn(false);\n setTimeout(() => setIsRendered(isOpen), 300);\n }\n }, [isOpen]);\n\n // Keyed on `animateIn` rather than `isOpen`, because the panel this needs to focus and trap\n // focus inside of only mounts once that flips.\n useOverlay({\n isActive: isRendered && animateIn,\n containerRef: modalRef,\n onEscape: closeOnEscape ? onClose : undefined,\n });\n\n const { hasStart, hasEnd } = useScrollEdges(bodyRef, { isEnabled: isRendered && animateIn });\n\n if (!isRendered) return null;\n\n const hasHeaderTitle = !hideHeader && !!title;\n\n return (\n <BodyEnd>\n <div\n className={cx(styles.modalContainer, classNames?.container)}\n style={{ height: viewportHeight, top: viewportOffsetTop, ...slotStyles?.container }}\n >\n <div\n className={cx(styles.modalWrapper, animateIn && styles.modalWrapperShown, classNames?.backdrop)}\n style={slotStyles?.backdrop}\n onClick={onClose}\n />\n {animateIn && (\n <div\n {...rest}\n ref={modalRef}\n role='dialog'\n aria-modal='true'\n // aria-labelledby would outrank aria-label, which is the only way to name a title with no text.\n aria-labelledby={hasHeaderTitle && !rest['aria-label'] ? titleId : undefined}\n // Focusable so the trap has somewhere to put focus when the content has no tabbables.\n tabIndex={-1}\n className={cx(\n styles.modal,\n animateIn && styles.modalShown,\n // The panel is its own sheet surface here: there's no inner panel to fill, since\n // Modal already splits itself into a fixed header and a scrolling body.\n isSheet && [sheetStyles.sheet, sheetStyles.sheetSurface, styles.modalSheet],\n className,\n classNames?.modal,\n )}\n style={{ ...(isSheet ? sheetStyle : undefined), ...style, ...slotStyles?.modal }}\n onClick={(e) => e.stopPropagation()}\n >\n {!hideHeader && (\n <div className={cx(styles.modalHeader, classNames?.header)} style={slotStyles?.header}>\n <div id={titleId} className={classNames?.title} style={slotStyles?.title}>\n {title}\n </div>\n <button\n type='button'\n onClick={onClose}\n aria-label={text.close}\n className={cx(styles.modalCloseButton, classNames?.closeButton)}\n style={slotStyles?.closeButton}\n >\n <FontAwesomeIcon icon={closeIcon} />\n </button>\n </div>\n )}\n <div\n ref={bodyRef}\n className={cx(\n styles.modalBody,\n fadeStyles.scrollFade,\n fadeStyles.scrollFadeY,\n hasStart && fadeStyles.scrollFadeFadedStart,\n hasEnd && fadeStyles.scrollFadeFadedEnd,\n classNames?.body,\n )}\n style={slotStyles?.body}\n >\n {children}\n </div>\n {footer && (\n <div className={cx(styles.modalFooter, classNames?.footer)} style={slotStyles?.footer}>\n {footer}\n </div>\n )}\n </div>\n )}\n </div>\n </BodyEnd>\n );\n}\n\nexport default Modal;\n"],"mappings":"o4BAiBA,IAAM,EAAwC,CAC5C,MAAO,OACT,EAEA,SAAS,EAAM,EAAmB,CAChC,GAAM,CACJ,WAAW,KACX,QACA,SAAS,GACT,cAAgB,KAChB,SAAS,KACT,YAAY,GACZ,QACA,aAAa,GACb,gBAAgB,GAChB,aAAc,EACd,aACA,OAAQ,EACR,SACA,GAAG,GACD,EAAqB,QAAS,CAAK,EACjC,EAAO,EAAU,QAAS,EAAQ,CAAc,EAChD,CAAC,EAAY,GAAiB,EAAS,CAAM,EAC7C,CAAC,EAAW,GAAgB,EAAS,CAAM,EAC3C,EAAW,EAAuB,IAAI,EACtC,EAAU,EAAuB,IAAI,EACrC,EAAU,EAAM,EAGhB,CAAE,OAAQ,EAAgB,UAAW,GAAsB,EAAsB,EAGjF,EAAkB,EAAuB,EAEzC,CAAE,UAAS,cAAe,EADX,GAAoB,CACY,EAErD,MAAgB,CACV,GAEF,EAAc,CAAM,EACpB,eAAiB,EAAa,EAAI,EAAG,CAAC,IAEtC,EAAa,EAAK,EAClB,eAAiB,EAAc,CAAM,EAAG,GAAG,EAE/C,EAAG,CAAC,CAAM,CAAC,EAIX,EAAW,CACT,SAAU,GAAc,EACxB,aAAc,EACd,SAAU,EAAgB,EAAU,IAAA,EACtC,CAAC,EAED,GAAM,CAAE,WAAU,UAAW,EAAe,EAAS,CAAE,UAAW,GAAc,CAAU,CAAC,EAE3F,GAAI,CAAC,EAAY,OAAO,KAExB,IAAM,EAAiB,CAAC,GAAc,CAAC,CAAC,EAExC,OACE,EAAC,EAAD,CAAA,SACE,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,eAAgB,GAAY,SAAS,EAC1D,MAAO,CAAE,OAAQ,EAAgB,IAAK,EAAmB,GAAG,GAAY,SAAU,EAFpF,SAAA,CAIE,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,aAAc,GAAa,EAAO,kBAAmB,GAAY,QAAQ,EAC9F,MAAO,GAAY,SACnB,QAAS,CACV,CAAA,EACA,GACC,EAAC,MAAD,CACE,GAAI,EACJ,IAAK,EACL,KAAK,SACL,aAAW,OAEX,kBAAiB,GAAkB,CAAC,EAAK,cAAgB,EAAU,IAAA,GAEnE,SAAU,GACV,UAAW,EACT,EAAO,MACP,GAAa,EAAO,WAGpB,GAAW,CAAC,EAAY,MAAO,EAAY,aAAc,EAAO,UAAU,EAC1E,EACA,GAAY,KACd,EACA,MAAO,CAAE,GAAI,EAAU,EAAa,IAAA,GAAY,GAAG,EAAO,GAAG,GAAY,KAAM,EAC/E,QAAU,GAAM,EAAE,gBAAgB,EAnBpC,SAAA,CAqBG,CAAC,GACA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,YAAa,GAAY,MAAM,EAAG,MAAO,GAAY,OAA/E,SAAA,CACE,EAAC,MAAD,CAAK,GAAI,EAAS,UAAW,GAAY,MAAO,MAAO,GAAY,MAChE,SAAA,CACE,CAAA,EACL,EAAC,SAAD,CACE,KAAK,SACL,QAAS,EACT,aAAY,EAAK,MACjB,UAAW,EAAG,EAAO,iBAAkB,GAAY,WAAW,EAC9D,MAAO,GAAY,YAEnB,SAAA,EAAC,EAAD,CAAiB,KAAM,CAAY,CAAA,CAC7B,CAAA,CACL,IAEP,EAAC,MAAD,CACE,IAAK,EACL,UAAW,EACT,EAAO,UACP,EAAW,WACX,EAAW,YACX,GAAY,EAAW,qBACvB,GAAU,EAAW,mBACrB,GAAY,IACd,EACA,MAAO,GAAY,KAElB,UACE,CAAA,EACJ,GACC,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,YAAa,GAAY,MAAM,EAAG,MAAO,GAAY,OAC5E,SAAA,CACE,CAAA,CAEJ,CAEJ,CAAA,CAAA,CACE,CAAA,CAAA,CAAA,CAEb"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{usePresentationDefault as t}from"../configProvider/usePresentationDefault.mjs";import{Presentation as n}from"../configProvider/presentation.types.mjs";import r from"../bodyEnd/bodyEnd.mjs";import i from"./popover.module.mjs";import a from"../styles/sheet.module.mjs";import o from"../sheetBackdrop/sheetBackdrop.mjs";import{PopoverAlign as ee,PopoverPlacement as s,PopoverTrigger as c}from"./popover.types.mjs";import{usePopoverPosition as l}from"./usePopoverPosition.mjs";import{tabbablesIn as u,useFocusBoundary as te}from"../hooks/useFocusBoundary.mjs";import ne from"../hooks/useSheet.mjs";import{useOverlay as re}from"../hooks/useOverlay.mjs";import{useCallback as ie,useEffect as d,useRef as f,useState as p}from"react";import m from"classnames";import{jsx as h,jsxs as g}from"react/jsx-runtime";var ae=1e3;function _(e,t){return e?{current:e}:t}function v(v){let{children:oe=null,anchor:y,content:b=null,placement:x=s.Bottom,align:S=ee.Center,trigger:C=c.Click,isOpen:w,defaultOpen:se=!1,onOpenChange:T=()=>{},offset:ce=10,withArrow:E=!0,closeOnOutsideClick:D=!0,closeOnEscape:le=!0,openDelay:ue=100,closeDelay:de=120,disabled:O=!1,focusOnOpen:k=`keyboard`,closeOnTriggerClick:fe=!0,width:pe=`auto`,constrainWidth:me=!0,presentation:he,className:ge,style:_e,classNames:A,styles:j,...M}=e(`Popover`,v),N=f(null),P=f(null),F=f(null),I=f(null),L=f(void 0),R=f(!1),z=f(!1),B=f(!1);function V(){R.current=!0}let[H,ve]=p(()=>({anchor:y,ref:_(y,N)}));H.anchor!==y&&ve({anchor:y,ref:_(y,N)});let U=H.ref,W=f(null),G=y!==void 0;d(()=>{if(!G)return;function e(e){W.current={target:e.target,keyboard:e.detail===0,time:performance.now()}}return document.addEventListener(`click`,e,!0),()=>document.removeEventListener(`click`,e,!0)},[G]);let K=w!==void 0,[ye,be]=p(se),q=K?w:ye,J=f(T);d(()=>{J.current=T});let Y=ie((e,t=!1)=>{O&&e||(e&&(B.current=t),K||be(e),J.current(e,{fromKeyboard:t}))},[O,K]),xe=t(),Se=he??xe??n.Default,{isSheet:Ce,sheetStyle:we}=ne(Se),X=Ce&&C===c.Click;l({isOpen:!!q&&!X,placement:x,align:S,offset:ce,triggerRef:U,floatingRef:P,panelRef:F,arrowRef:E?I:{current:null},matchTriggerWidth:pe===`trigger`});let{restoreFocusToTrigger:Z,focusAfterTrigger:Q}=te({triggerRef:U,contentRef:P});re({isActive:!!q,containerRef:F,onEscape:le?()=>{P.current?.contains(document.activeElement)&&Z(),Y(!1,!0)}:void 0,trapFocus:!1,lockScroll:X}),d(()=>{if(!q){B.current=!1;return}let e=W.current;W.current=null;let t=!!y&&!!e?.keyboard&&y.contains(e.target)&&performance.now()-e.time<ae;if(!(k===!0||k===`keyboard`&&(B.current||t))||C!==c.Click)return;let n=u(F.current);n.length!==0&&(P.current?.setAttribute(`role`,`dialog`),n[0].focus())},[q,C,k,y]);function Te(e){if(e.key!==`Tab`||C!==c.Click)return;let t=u(F.current);if(t.length===0)return;let n=document.activeElement;!e.shiftKey&&n===t[t.length-1]?(e.preventDefault(),Q(),Y(!1,!0)):e.shiftKey&&n===t[0]&&(e.preventDefault(),Z(),Y(!1,!0))}d(()=>{if(!q)return;R.current=!1,z.current=!1;function e(e){let t=R.current;R.current=!1;let n=e.target,r=P.current?.contains(n),i=N.current?.contains(n)||U.current?.contains(n);return!!(t||r||i)}function t(t){z.current
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{usePresentationDefault as t}from"../configProvider/usePresentationDefault.mjs";import{Presentation as n}from"../configProvider/presentation.types.mjs";import r from"../bodyEnd/bodyEnd.mjs";import i from"./popover.module.mjs";import a from"../styles/sheet.module.mjs";import o from"../sheetBackdrop/sheetBackdrop.mjs";import{PopoverAlign as ee,PopoverPlacement as s,PopoverTrigger as c}from"./popover.types.mjs";import{usePopoverPosition as l}from"./usePopoverPosition.mjs";import{tabbablesIn as u,useFocusBoundary as te}from"../hooks/useFocusBoundary.mjs";import ne from"../hooks/useSheet.mjs";import{useOverlay as re}from"../hooks/useOverlay.mjs";import{useCallback as ie,useEffect as d,useRef as f,useState as p}from"react";import m from"classnames";import{jsx as h,jsxs as g}from"react/jsx-runtime";var ae=1e3;function _(e,t){return e?{current:e}:t}function v(v){let{children:oe=null,anchor:y,content:b=null,placement:x=s.Bottom,align:S=ee.Center,trigger:C=c.Click,isOpen:w,defaultOpen:se=!1,onOpenChange:T=()=>{},offset:ce=10,withArrow:E=!0,closeOnOutsideClick:D=!0,closeOnEscape:le=!0,openDelay:ue=100,closeDelay:de=120,disabled:O=!1,focusOnOpen:k=`keyboard`,closeOnTriggerClick:fe=!0,width:pe=`auto`,constrainWidth:me=!0,presentation:he,className:ge,style:_e,classNames:A,styles:j,...M}=e(`Popover`,v),N=f(null),P=f(null),F=f(null),I=f(null),L=f(void 0),R=f(!1),z=f(!1),B=f(!1);function V(){R.current=!0}let[H,ve]=p(()=>({anchor:y,ref:_(y,N)}));H.anchor!==y&&ve({anchor:y,ref:_(y,N)});let U=H.ref,W=f(null),G=y!==void 0;d(()=>{if(!G)return;function e(e){W.current={target:e.target,keyboard:e.detail===0,time:performance.now()}}return document.addEventListener(`click`,e,!0),()=>document.removeEventListener(`click`,e,!0)},[G]);let K=w!==void 0,[ye,be]=p(se),q=K?w:ye,J=f(T);d(()=>{J.current=T});let Y=ie((e,t=!1)=>{O&&e||(e&&(B.current=t),K||be(e),J.current(e,{fromKeyboard:t}))},[O,K]),xe=t(),Se=he??xe??n.Default,{isSheet:Ce,sheetStyle:we}=ne(Se),X=Ce&&C===c.Click;l({isOpen:!!q&&!X,placement:x,align:S,offset:ce,triggerRef:U,floatingRef:P,panelRef:F,arrowRef:E?I:{current:null},matchTriggerWidth:pe===`trigger`});let{restoreFocusToTrigger:Z,focusAfterTrigger:Q}=te({triggerRef:U,contentRef:P});re({isActive:!!q,containerRef:F,onEscape:le?()=>{P.current?.contains(document.activeElement)&&Z(),Y(!1,!0)}:void 0,trapFocus:!1,lockScroll:X}),d(()=>{if(!q){B.current=!1;return}let e=W.current;W.current=null;let t=!!y&&!!e?.keyboard&&y.contains(e.target)&&performance.now()-e.time<ae;if(!(k===!0||k===`keyboard`&&(B.current||t))||C!==c.Click)return;let n=u(F.current);n.length!==0&&(P.current?.setAttribute(`role`,`dialog`),n[0].focus())},[q,C,k,y]);function Te(e){if(e.key!==`Tab`||C!==c.Click)return;let t=u(F.current);if(t.length===0)return;let n=document.activeElement;!e.shiftKey&&n===t[t.length-1]?(e.preventDefault(),Q(),Y(!1,!0)):e.shiftKey&&n===t[0]&&(e.preventDefault(),Z(),Y(!1,!0))}d(()=>{if(!q)return;R.current=!1,z.current=!1;function e(e){let t=R.current;R.current=!1;let n=e.target,r=P.current?.contains(n),i=N.current?.contains(n)||U.current?.contains(n);return!!(t||r||i)}function t(t){z.current=!e(t)}function n(t){let n=z.current;z.current=!1,!e(t)&&n&&Y(!1)}function r(t){e(t)||Y(!1,!0)}return D&&C!==c.Hover&&(window.addEventListener(`mousedown`,t),window.addEventListener(`mouseup`,n),document.addEventListener(`focusin`,r)),()=>{window.removeEventListener(`mousedown`,t),window.removeEventListener(`mouseup`,n),document.removeEventListener(`focusin`,r)}},[q,D,C,Y,U]),d(()=>()=>clearTimeout(L.current),[]);function $(e){clearTimeout(L.current),L.current=setTimeout(()=>Y(e),e?ue:de)}function Ee(e){q||e.key!==`ArrowDown`&&e.key!==`ArrowUp`||(e.preventDefault(),Y(!0,!0))}let De=C===c.Click?{onClick:e=>{(!q||fe)&&Y(!q,e.detail===0)},onKeyDown:Ee}:C===c.Hover?{onMouseEnter:()=>$(!0),onMouseLeave:()=>$(!1)}:{onFocus:()=>Y(!0),onBlur:()=>Y(!1)},Oe=C===c.Hover?{onMouseEnter:()=>$(!0),onMouseLeave:()=>$(!1)}:{};return g(`div`,{...M,className:m(i.popover,ge,A?.root),style:{..._e,...j?.root},children:[h(`div`,{ref:N,className:m(i.popoverTrigger,A?.trigger),style:j?.trigger,...De,children:oe}),q&&g(r,{children:[X&&h(o,{onClose:()=>{D&&Y(!1)},className:A?.backdrop,style:j?.backdrop}),g(`div`,{ref:P,className:m(X?a.sheet:i.popoverFloating,A?.floating),style:{...X?we:void 0,...j?.floating},"data-placement":x,onKeyDown:Te,onMouseDownCapture:V,onMouseUpCapture:V,onFocusCapture:V,...Oe,children:[h(`div`,{ref:F,className:m(i.popoverPanel,me&&i.popoverPanelConstrained,X&&a.sheetPanel,A?.panel),style:j?.panel,children:b}),E&&!X&&h(`div`,{ref:I,className:m(i.popoverArrow,A?.arrow),style:j?.arrow})]})]})]})}export{v as default};
|
|
2
2
|
//# sourceMappingURL=popover.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popover.mjs","names":[],"sources":["../../../../package/common/popover/popover.tsx"],"sourcesContent":["import { useRef, useEffect, useState, useCallback, type RefObject } from 'react';\nimport cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './popover.module.pcss';\nimport sheetStyles from '../styles/sheet.module.pcss';\nimport SheetBackdrop from '../sheetBackdrop';\nimport { usePopoverPosition } from './usePopoverPosition';\nimport { useFocusBoundary, tabbablesIn } from '../hooks/useFocusBoundary';\nimport { useSheet } from '../hooks/useSheet';\nimport { useOverlay } from '../hooks/useOverlay';\nimport { useComponentDefaults, usePresentationDefault } from '../configProvider';\nimport { Presentation } from '../configProvider/presentation.types';\nimport { PopoverPlacement, PopoverAlign, PopoverTrigger, type PopoverProps } from './popover.types';\n\n/**\n * How long after its click an anchored popover still counts as opened by it: long enough for the\n * render the click causes, short enough that an old keypress does not decide a later open.\n */\nconst ACTIVATION_WINDOW_MS = 1000;\n\nfunction toReference(\n anchor: HTMLElement | null | undefined,\n triggerRef: RefObject<HTMLElement | null>,\n): RefObject<HTMLElement | null> {\n return anchor ? { current: anchor } : triggerRef;\n}\n\nfunction Popover(props: PopoverProps) {\n const {\n children = null,\n anchor,\n content = null,\n placement = PopoverPlacement.Bottom,\n align = PopoverAlign.Center,\n trigger = PopoverTrigger.Click,\n isOpen,\n defaultOpen = false,\n onOpenChange = () => {},\n offset = 10,\n withArrow = true,\n closeOnOutsideClick = true,\n closeOnEscape = true,\n openDelay = 100,\n closeDelay = 120,\n disabled = false,\n focusOnOpen = 'keyboard',\n closeOnTriggerClick = true,\n width = 'auto',\n constrainWidth = true,\n presentation: presentationProp,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Popover', props);\n const triggerRef = useRef<HTMLDivElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const arrowRef = useRef<HTMLDivElement>(null);\n const hoverTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n // Set from a capture handler on the panel, which React fires for its whole\n // React subtree — including children that portal elsewhere in the DOM, such as\n // a Dropdown's list inside a DatePicker's calendar. A DOM `contains` check\n // cannot see those, and without this the panel closes when one is used.\n const panelInteractedRef = useRef(false);\n // A press that starts inside and is released outside is a drag, such as selecting the text of\n // a field, not an outside click. Chromium and WebKit send its `mouseup` to wherever it ends.\n const pressStartedInsideRef = useRef(false);\n // Whether the open that is running came from the keyboard, which is what the\n // default `focusOnOpen` follows and what `onOpenChange` reports. A click raised\n // by Enter or Space reports `detail === 0`, where a pointer press counts the\n // clicks; an open with no trigger event at all, such as a panel that appears\n // while the user types, leaves this false.\n const openedByKeyboardRef = useRef(false);\n function markPanelInteraction() {\n panelInteractedRef.current = true;\n }\n\n // What the panel is placed against, and where the focus goes back to. A new object exactly when\n // `anchor` changes, which is what restarts the position tracking for the new element: state, not\n // a memo, because a memo React chose to drop would restart it for no reason.\n const [reference, setReference] = useState(() => ({ anchor, ref: toReference(anchor, triggerRef) }));\n if (reference.anchor !== anchor) setReference({ anchor, ref: toReference(anchor, triggerRef) });\n const referenceRef = reference.ref;\n\n // An anchored popover is opened by its consumer through `isOpen`, so none of the key handling\n // below sees how. The click that caused it does: Enter and Space raise one with `detail === 0`,\n // the same test the trigger uses. Not `:focus-visible`, which a text field matches after a\n // mouse click too, and which stays on a keyboard-focused button that is then clicked.\n const activationRef = useRef<{ target: Node; keyboard: boolean; time: number } | null>(null);\n const anchored = anchor !== undefined;\n useEffect(() => {\n if (!anchored) return;\n function onClick(event: MouseEvent) {\n activationRef.current = { target: event.target as Node, keyboard: event.detail === 0, time: performance.now() };\n }\n // Capturing, so it is recorded before the consumer's own handler opens the panel.\n document.addEventListener('click', onClick, true);\n return () => document.removeEventListener('click', onClick, true);\n }, [anchored]);\n\n const isControlled = isOpen !== undefined;\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const open = isControlled ? isOpen : internalOpen;\n\n // Keep the outside-click/Escape listeners pointed at the latest setter without re-subscribing.\n const onOpenChangeRef = useRef(onOpenChange);\n useEffect(() => {\n onOpenChangeRef.current = onOpenChange;\n });\n\n const setOpen = useCallback(\n (next: boolean, fromKeyboard = false) => {\n if (disabled && next) return;\n if (next) openedByKeyboardRef.current = fromKeyboard;\n if (!isControlled) setInternalOpen(next);\n onOpenChangeRef.current(next, { fromKeyboard });\n },\n [disabled, isControlled],\n );\n\n // Explicit prop → this component's global default → the app-wide one → anchored.\n const appPresentation = usePresentationDefault();\n const presentation = presentationProp ?? appPresentation ?? Presentation.Default;\n const { isSheet: sheetPresentation, sheetStyle } = useSheet(presentation);\n // Hover and focus are pointer affordances that open something small next to what caused them;\n // a sheet is a deliberate, screen-owning open. Only a click asks for one.\n const isSheet = sheetPresentation && trigger === PopoverTrigger.Click;\n\n // A sheet isn't anchored to anything, so there's nothing to track, flip or clamp.\n usePopoverPosition({\n isOpen: !!open && !isSheet,\n placement,\n align,\n offset,\n triggerRef: referenceRef,\n floatingRef,\n panelRef,\n arrowRef: withArrow ? arrowRef : { current: null },\n matchTriggerWidth: width === 'trigger',\n });\n\n // Registered for as long as it's open, not just as a sheet: this is what puts the popover on\n // the overlay stack, so an enclosing Modal knows something sits above it and neither drags\n // focus out of this (portaled, so outside the modal's panel) panel nor closes itself on the\n // Escape meant for this. Focus isn't trapped: a Popover is deliberately non-modal, and it\n // already moves focus into the panel on open by itself.\n const { restoreFocusToTrigger, focusAfterTrigger } = useFocusBoundary({\n triggerRef: referenceRef,\n contentRef: floatingRef,\n });\n\n useOverlay({\n isActive: !!open,\n containerRef: panelRef,\n onEscape: closeOnEscape\n ? () => {\n // Hand focus back to the trigger when it currently sits inside the panel.\n if (floatingRef.current?.contains(document.activeElement)) restoreFocusToTrigger();\n setOpen(false, true);\n }\n : undefined,\n trapFocus: false,\n lockScroll: isSheet,\n });\n\n // The panel is portaled to the end of the DOM, so Tab never flows into it naturally. When we\n // manage focus (click trigger + focusable content), move focus in on open and, on Tab out of\n // either end, close and continue focus as if the panel sat right after the trigger.\n useEffect(() => {\n if (!open) {\n openedByKeyboardRef.current = false;\n return;\n }\n const activation = activationRef.current;\n activationRef.current = null;\n const anchorKeyed =\n !!anchor &&\n !!activation?.keyboard &&\n anchor.contains(activation.target) &&\n performance.now() - activation.time < ACTIVATION_WINDOW_MS;\n const takeFocus =\n focusOnOpen === true || (focusOnOpen === 'keyboard' && (openedByKeyboardRef.current || anchorKeyed));\n if (!takeFocus || trigger !== PopoverTrigger.Click) return;\n const focusables = tabbablesIn(panelRef.current);\n if (focusables.length === 0) return;\n // Only claim the dialog role when we're actually managing focus for real content.\n floatingRef.current?.setAttribute('role', 'dialog');\n focusables[0].focus();\n }, [open, trigger, focusOnOpen, anchor]);\n\n function handleFloatingKeyDown(event: React.KeyboardEvent) {\n if (event.key !== 'Tab' || trigger !== PopoverTrigger.Click) return;\n const focusables = tabbablesIn(panelRef.current);\n if (focusables.length === 0) return;\n const active = document.activeElement;\n if (!event.shiftKey && active === focusables[focusables.length - 1]) {\n event.preventDefault();\n focusAfterTrigger();\n setOpen(false, true);\n } else if (event.shiftKey && active === focusables[0]) {\n event.preventDefault();\n restoreFocusToTrigger();\n setOpen(false, true);\n }\n }\n\n // Outside click. Registered only while open and only for the relevant trigger mode; Escape is\n // handled by `useOverlay` above, which scopes it to the innermost open layer.\n useEffect(() => {\n if (!open) return;\n // Focus that landed in the panel before these listeners existed (ours on open, or content\n // that focuses itself on mount) set the flag with nothing to clear it, and the first\n // click outside was swallowed.\n panelInteractedRef.current = false;\n pressStartedInsideRef.current = false;\n\n function isInside(event: Event) {\n // Read and clear: the flag describes this one event, and the panel's React\n // handler has already run by the time this does.\n const inPanelSubtree = panelInteractedRef.current;\n panelInteractedRef.current = false;\n const target = event.target as Node;\n const inPanel = floatingRef.current?.contains(target);\n // Both: with an anchor, `children` still toggle the panel, and a press on them is theirs.\n const inTrigger = triggerRef.current?.contains(target) || referenceRef.current?.contains(target);\n return Boolean(inPanelSubtree || inPanel || inTrigger);\n }\n function onMouseDown(event: MouseEvent) {\n pressStartedInsideRef.current = isInside(event);\n }\n function onMouseUp(event: MouseEvent) {\n const pressStartedInside = pressStartedInsideRef.current;\n pressStartedInsideRef.current = false;\n if (!isInside(event) && !pressStartedInside) setOpen(false);\n }\n // Keyboard counterpart to the outside click: once focus leaves both the trigger\n // and the (portaled) panel — e.g. tabbing on to the next element — close.\n function onFocusIn(event: FocusEvent) {\n if (!isInside(event)) setOpen(false, true);\n }\n\n if (closeOnOutsideClick && trigger !== PopoverTrigger.Hover) {\n window.addEventListener('mousedown', onMouseDown);\n window.addEventListener('mouseup', onMouseUp);\n document.addEventListener('focusin', onFocusIn);\n }\n return () => {\n window.removeEventListener('mousedown', onMouseDown);\n window.removeEventListener('mouseup', onMouseUp);\n document.removeEventListener('focusin', onFocusIn);\n };\n }, [open, closeOnOutsideClick, trigger, setOpen, referenceRef]);\n\n useEffect(() => () => clearTimeout(hoverTimer.current), []);\n\n function scheduleHover(next: boolean) {\n clearTimeout(hoverTimer.current);\n hoverTimer.current = setTimeout(() => setOpen(next), next ? openDelay : closeDelay);\n }\n\n // Opening from the keyboard without the trigger having to be a button that\n // happens to toggle on Enter: the arrow keys are what the menu-button pattern\n // asks for, and what a consumer reaches for first.\n function handleTriggerKeyDown(event: React.KeyboardEvent) {\n if (open || (event.key !== 'ArrowDown' && event.key !== 'ArrowUp')) return;\n event.preventDefault();\n setOpen(true, true);\n }\n\n const triggerHandlers =\n trigger === PopoverTrigger.Click\n ? {\n onClick: (event: React.MouseEvent) => {\n // A field that opens a picker keeps it open when clicked again, so\n // that placing the caret in the field does not close the panel.\n if (open && !closeOnTriggerClick) return;\n setOpen(!open, event.detail === 0);\n },\n onKeyDown: handleTriggerKeyDown,\n }\n : trigger === PopoverTrigger.Hover\n ? { onMouseEnter: () => scheduleHover(true), onMouseLeave: () => scheduleHover(false) }\n : { onFocus: () => setOpen(true), onBlur: () => setOpen(false) };\n\n const floatingHoverHandlers =\n trigger === PopoverTrigger.Hover\n ? { onMouseEnter: () => scheduleHover(true), onMouseLeave: () => scheduleHover(false) }\n : {};\n\n return (\n <div\n {...rest}\n className={cx(styles.popover, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <div\n ref={triggerRef}\n className={cx(styles.popoverTrigger, classNames?.trigger)}\n style={slotStyles?.trigger}\n {...triggerHandlers}\n >\n {children}\n </div>\n {open && (\n <BodyEnd>\n {isSheet && (\n <SheetBackdrop\n onClose={() => {\n if (closeOnOutsideClick) setOpen(false);\n }}\n className={classNames?.backdrop}\n style={slotStyles?.backdrop}\n />\n )}\n <div\n ref={floatingRef}\n className={cx(isSheet ? sheetStyles.sheet : styles.popoverFloating, classNames?.floating)}\n style={{ ...(isSheet ? sheetStyle : undefined), ...slotStyles?.floating }}\n data-placement={placement}\n onKeyDown={handleFloatingKeyDown}\n onMouseDownCapture={markPanelInteraction}\n onMouseUpCapture={markPanelInteraction}\n onFocusCapture={markPanelInteraction}\n {...floatingHoverHandlers}\n >\n <div\n ref={panelRef}\n className={cx(\n styles.popoverPanel,\n constrainWidth && styles.popoverPanelConstrained,\n isSheet && sheetStyles.sheetPanel,\n classNames?.panel,\n )}\n style={slotStyles?.panel}\n >\n {content}\n </div>\n {withArrow && !isSheet && (\n <div ref={arrowRef} className={cx(styles.popoverArrow, classNames?.arrow)} style={slotStyles?.arrow} />\n )}\n </div>\n </BodyEnd>\n )}\n </div>\n );\n}\n\nexport default Popover;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"popover.mjs","names":[],"sources":["../../../../package/common/popover/popover.tsx"],"sourcesContent":["import { useRef, useEffect, useState, useCallback, type RefObject } from 'react';\nimport cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './popover.module.pcss';\nimport sheetStyles from '../styles/sheet.module.pcss';\nimport SheetBackdrop from '../sheetBackdrop';\nimport { usePopoverPosition } from './usePopoverPosition';\nimport { useFocusBoundary, tabbablesIn } from '../hooks/useFocusBoundary';\nimport { useSheet } from '../hooks/useSheet';\nimport { useOverlay } from '../hooks/useOverlay';\nimport { useComponentDefaults, usePresentationDefault } from '../configProvider';\nimport { Presentation } from '../configProvider/presentation.types';\nimport { PopoverPlacement, PopoverAlign, PopoverTrigger, type PopoverProps } from './popover.types';\n\n/**\n * How long after its click an anchored popover still counts as opened by it: long enough for the\n * render the click causes, short enough that an old keypress does not decide a later open.\n */\nconst ACTIVATION_WINDOW_MS = 1000;\n\nfunction toReference(\n anchor: HTMLElement | null | undefined,\n triggerRef: RefObject<HTMLElement | null>,\n): RefObject<HTMLElement | null> {\n return anchor ? { current: anchor } : triggerRef;\n}\n\nfunction Popover(props: PopoverProps) {\n const {\n children = null,\n anchor,\n content = null,\n placement = PopoverPlacement.Bottom,\n align = PopoverAlign.Center,\n trigger = PopoverTrigger.Click,\n isOpen,\n defaultOpen = false,\n onOpenChange = () => {},\n offset = 10,\n withArrow = true,\n closeOnOutsideClick = true,\n closeOnEscape = true,\n openDelay = 100,\n closeDelay = 120,\n disabled = false,\n focusOnOpen = 'keyboard',\n closeOnTriggerClick = true,\n width = 'auto',\n constrainWidth = true,\n presentation: presentationProp,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Popover', props);\n const triggerRef = useRef<HTMLDivElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const arrowRef = useRef<HTMLDivElement>(null);\n const hoverTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n // Set from a capture handler on the panel, which React fires for its whole\n // React subtree — including children that portal elsewhere in the DOM, such as\n // a Dropdown's list inside a DatePicker's calendar. A DOM `contains` check\n // cannot see those, and without this the panel closes when one is used.\n const panelInteractedRef = useRef(false);\n // An outside click is a press that starts and ends outside while the panel is open. One that\n // starts inside is a drag, such as selecting a field's text, and Chromium and WebKit send its\n // `mouseup` to wherever it ends. One that started before the panel opened is the gesture that\n // opened it, such as Calendar's drag to create, which opens an editor on `pointerup`.\n const pressStartedOutsideRef = useRef(false);\n // Whether the open that is running came from the keyboard, which is what the\n // default `focusOnOpen` follows and what `onOpenChange` reports. A click raised\n // by Enter or Space reports `detail === 0`, where a pointer press counts the\n // clicks; an open with no trigger event at all, such as a panel that appears\n // while the user types, leaves this false.\n const openedByKeyboardRef = useRef(false);\n function markPanelInteraction() {\n panelInteractedRef.current = true;\n }\n\n // What the panel is placed against, and where the focus goes back to. A new object exactly when\n // `anchor` changes, which is what restarts the position tracking for the new element: state, not\n // a memo, because a memo React chose to drop would restart it for no reason.\n const [reference, setReference] = useState(() => ({ anchor, ref: toReference(anchor, triggerRef) }));\n if (reference.anchor !== anchor) setReference({ anchor, ref: toReference(anchor, triggerRef) });\n const referenceRef = reference.ref;\n\n // An anchored popover is opened by its consumer through `isOpen`, so none of the key handling\n // below sees how. The click that caused it does: Enter and Space raise one with `detail === 0`,\n // the same test the trigger uses. Not `:focus-visible`, which a text field matches after a\n // mouse click too, and which stays on a keyboard-focused button that is then clicked.\n const activationRef = useRef<{ target: Node; keyboard: boolean; time: number } | null>(null);\n const anchored = anchor !== undefined;\n useEffect(() => {\n if (!anchored) return;\n function onClick(event: MouseEvent) {\n activationRef.current = { target: event.target as Node, keyboard: event.detail === 0, time: performance.now() };\n }\n // Capturing, so it is recorded before the consumer's own handler opens the panel.\n document.addEventListener('click', onClick, true);\n return () => document.removeEventListener('click', onClick, true);\n }, [anchored]);\n\n const isControlled = isOpen !== undefined;\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const open = isControlled ? isOpen : internalOpen;\n\n // Keep the outside-click/Escape listeners pointed at the latest setter without re-subscribing.\n const onOpenChangeRef = useRef(onOpenChange);\n useEffect(() => {\n onOpenChangeRef.current = onOpenChange;\n });\n\n const setOpen = useCallback(\n (next: boolean, fromKeyboard = false) => {\n if (disabled && next) return;\n if (next) openedByKeyboardRef.current = fromKeyboard;\n if (!isControlled) setInternalOpen(next);\n onOpenChangeRef.current(next, { fromKeyboard });\n },\n [disabled, isControlled],\n );\n\n // Explicit prop → this component's global default → the app-wide one → anchored.\n const appPresentation = usePresentationDefault();\n const presentation = presentationProp ?? appPresentation ?? Presentation.Default;\n const { isSheet: sheetPresentation, sheetStyle } = useSheet(presentation);\n // Hover and focus are pointer affordances that open something small next to what caused them;\n // a sheet is a deliberate, screen-owning open. Only a click asks for one.\n const isSheet = sheetPresentation && trigger === PopoverTrigger.Click;\n\n // A sheet isn't anchored to anything, so there's nothing to track, flip or clamp.\n usePopoverPosition({\n isOpen: !!open && !isSheet,\n placement,\n align,\n offset,\n triggerRef: referenceRef,\n floatingRef,\n panelRef,\n arrowRef: withArrow ? arrowRef : { current: null },\n matchTriggerWidth: width === 'trigger',\n });\n\n // Registered for as long as it's open, not just as a sheet: this is what puts the popover on\n // the overlay stack, so an enclosing Modal knows something sits above it and neither drags\n // focus out of this (portaled, so outside the modal's panel) panel nor closes itself on the\n // Escape meant for this. Focus isn't trapped: a Popover is deliberately non-modal, and it\n // already moves focus into the panel on open by itself.\n const { restoreFocusToTrigger, focusAfterTrigger } = useFocusBoundary({\n triggerRef: referenceRef,\n contentRef: floatingRef,\n });\n\n useOverlay({\n isActive: !!open,\n containerRef: panelRef,\n onEscape: closeOnEscape\n ? () => {\n // Hand focus back to the trigger when it currently sits inside the panel.\n if (floatingRef.current?.contains(document.activeElement)) restoreFocusToTrigger();\n setOpen(false, true);\n }\n : undefined,\n trapFocus: false,\n lockScroll: isSheet,\n });\n\n // The panel is portaled to the end of the DOM, so Tab never flows into it naturally. When we\n // manage focus (click trigger + focusable content), move focus in on open and, on Tab out of\n // either end, close and continue focus as if the panel sat right after the trigger.\n useEffect(() => {\n if (!open) {\n openedByKeyboardRef.current = false;\n return;\n }\n const activation = activationRef.current;\n activationRef.current = null;\n const anchorKeyed =\n !!anchor &&\n !!activation?.keyboard &&\n anchor.contains(activation.target) &&\n performance.now() - activation.time < ACTIVATION_WINDOW_MS;\n const takeFocus =\n focusOnOpen === true || (focusOnOpen === 'keyboard' && (openedByKeyboardRef.current || anchorKeyed));\n if (!takeFocus || trigger !== PopoverTrigger.Click) return;\n const focusables = tabbablesIn(panelRef.current);\n if (focusables.length === 0) return;\n // Only claim the dialog role when we're actually managing focus for real content.\n floatingRef.current?.setAttribute('role', 'dialog');\n focusables[0].focus();\n }, [open, trigger, focusOnOpen, anchor]);\n\n function handleFloatingKeyDown(event: React.KeyboardEvent) {\n if (event.key !== 'Tab' || trigger !== PopoverTrigger.Click) return;\n const focusables = tabbablesIn(panelRef.current);\n if (focusables.length === 0) return;\n const active = document.activeElement;\n if (!event.shiftKey && active === focusables[focusables.length - 1]) {\n event.preventDefault();\n focusAfterTrigger();\n setOpen(false, true);\n } else if (event.shiftKey && active === focusables[0]) {\n event.preventDefault();\n restoreFocusToTrigger();\n setOpen(false, true);\n }\n }\n\n // Outside click. Registered only while open and only for the relevant trigger mode; Escape is\n // handled by `useOverlay` above, which scopes it to the innermost open layer.\n useEffect(() => {\n if (!open) return;\n // Focus that landed in the panel before these listeners existed (ours on open, or content\n // that focuses itself on mount) set the flag with nothing to clear it, and the first\n // click outside was swallowed.\n panelInteractedRef.current = false;\n pressStartedOutsideRef.current = false;\n\n function isInside(event: Event) {\n // Read and clear: the flag describes this one event, and the panel's React\n // handler has already run by the time this does.\n const inPanelSubtree = panelInteractedRef.current;\n panelInteractedRef.current = false;\n const target = event.target as Node;\n const inPanel = floatingRef.current?.contains(target);\n // Both: with an anchor, `children` still toggle the panel, and a press on them is theirs.\n const inTrigger = triggerRef.current?.contains(target) || referenceRef.current?.contains(target);\n return Boolean(inPanelSubtree || inPanel || inTrigger);\n }\n function onMouseDown(event: MouseEvent) {\n pressStartedOutsideRef.current = !isInside(event);\n }\n function onMouseUp(event: MouseEvent) {\n const pressStartedOutside = pressStartedOutsideRef.current;\n pressStartedOutsideRef.current = false;\n if (!isInside(event) && pressStartedOutside) setOpen(false);\n }\n // Keyboard counterpart to the outside click: once focus leaves both the trigger\n // and the (portaled) panel — e.g. tabbing on to the next element — close.\n function onFocusIn(event: FocusEvent) {\n if (!isInside(event)) setOpen(false, true);\n }\n\n if (closeOnOutsideClick && trigger !== PopoverTrigger.Hover) {\n window.addEventListener('mousedown', onMouseDown);\n window.addEventListener('mouseup', onMouseUp);\n document.addEventListener('focusin', onFocusIn);\n }\n return () => {\n window.removeEventListener('mousedown', onMouseDown);\n window.removeEventListener('mouseup', onMouseUp);\n document.removeEventListener('focusin', onFocusIn);\n };\n }, [open, closeOnOutsideClick, trigger, setOpen, referenceRef]);\n\n useEffect(() => () => clearTimeout(hoverTimer.current), []);\n\n function scheduleHover(next: boolean) {\n clearTimeout(hoverTimer.current);\n hoverTimer.current = setTimeout(() => setOpen(next), next ? openDelay : closeDelay);\n }\n\n // Opening from the keyboard without the trigger having to be a button that\n // happens to toggle on Enter: the arrow keys are what the menu-button pattern\n // asks for, and what a consumer reaches for first.\n function handleTriggerKeyDown(event: React.KeyboardEvent) {\n if (open || (event.key !== 'ArrowDown' && event.key !== 'ArrowUp')) return;\n event.preventDefault();\n setOpen(true, true);\n }\n\n const triggerHandlers =\n trigger === PopoverTrigger.Click\n ? {\n onClick: (event: React.MouseEvent) => {\n // A field that opens a picker keeps it open when clicked again, so\n // that placing the caret in the field does not close the panel.\n if (open && !closeOnTriggerClick) return;\n setOpen(!open, event.detail === 0);\n },\n onKeyDown: handleTriggerKeyDown,\n }\n : trigger === PopoverTrigger.Hover\n ? { onMouseEnter: () => scheduleHover(true), onMouseLeave: () => scheduleHover(false) }\n : { onFocus: () => setOpen(true), onBlur: () => setOpen(false) };\n\n const floatingHoverHandlers =\n trigger === PopoverTrigger.Hover\n ? { onMouseEnter: () => scheduleHover(true), onMouseLeave: () => scheduleHover(false) }\n : {};\n\n return (\n <div\n {...rest}\n className={cx(styles.popover, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <div\n ref={triggerRef}\n className={cx(styles.popoverTrigger, classNames?.trigger)}\n style={slotStyles?.trigger}\n {...triggerHandlers}\n >\n {children}\n </div>\n {open && (\n <BodyEnd>\n {isSheet && (\n <SheetBackdrop\n onClose={() => {\n if (closeOnOutsideClick) setOpen(false);\n }}\n className={classNames?.backdrop}\n style={slotStyles?.backdrop}\n />\n )}\n <div\n ref={floatingRef}\n className={cx(isSheet ? sheetStyles.sheet : styles.popoverFloating, classNames?.floating)}\n style={{ ...(isSheet ? sheetStyle : undefined), ...slotStyles?.floating }}\n data-placement={placement}\n onKeyDown={handleFloatingKeyDown}\n onMouseDownCapture={markPanelInteraction}\n onMouseUpCapture={markPanelInteraction}\n onFocusCapture={markPanelInteraction}\n {...floatingHoverHandlers}\n >\n <div\n ref={panelRef}\n className={cx(\n styles.popoverPanel,\n constrainWidth && styles.popoverPanelConstrained,\n isSheet && sheetStyles.sheetPanel,\n classNames?.panel,\n )}\n style={slotStyles?.panel}\n >\n {content}\n </div>\n {withArrow && !isSheet && (\n <div ref={arrowRef} className={cx(styles.popoverArrow, classNames?.arrow)} style={slotStyles?.arrow} />\n )}\n </div>\n </BodyEnd>\n )}\n </div>\n );\n}\n\nexport default Popover;\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import e
|
|
1
|
+
"use client";import{mergeRefs as e}from"../utils/mergeRefs.mjs";import t from"../styles/scrollFade.module.mjs";import{useScrollEdges as n}from"../hooks/useScrollEdges.mjs";import{ScrollFadeAxis as r}from"./scrollFade.types.mjs";import i from"./scrollFade.module.mjs";import{useRef as a}from"react";import o from"classnames";import{jsx as s}from"react/jsx-runtime";function c({children:c=null,axis:l=r.Vertical,fadeLength:u,isAlwaysFaded:d=!1,className:f,style:p,ref:m,...h}){let g=a(null),_=l===r.Horizontal,{hasStart:v,hasEnd:y}=n(g,{axis:l,isEnabled:!d});return s(`div`,{...h,ref:e(g,m),className:o(_?i.scrollFadeHorizontal:i.scrollFadeVertical,t.scrollFade,_?t.scrollFadeX:t.scrollFadeY,(d||v)&&t.scrollFadeFadedStart,(d||y)&&t.scrollFadeFadedEnd,f),style:{...u?{"--custom-scroll-fade-length":u}:void 0,...p},children:c})}export{c as default};
|
|
2
2
|
//# sourceMappingURL=scrollFade.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scrollbarProvider.module.mjs","names":[],"sources":["../../../../package/common/scrollbarProvider/scrollbarProvider.module.pcss"],"sourcesContent":[".scrollbarProvider {\n display: contents;\n\n
|
|
1
|
+
{"version":3,"file":"scrollbarProvider.module.mjs","names":[],"sources":["../../../../package/common/scrollbarProvider/scrollbarProvider.module.pcss"],"sourcesContent":[".scrollbarProvider {\n display: contents;\n}\n\n/* Zero specificity, so any scrollbar rule of a component's or the app's own wins. As\n `.scrollbarProvider *` these tied with a single class and won or lost on stylesheet order. */\n\n/* Firefox */\n:where(.scrollbarProvider *) {\n scrollbar-width: thin;\n scrollbar-color: var(--background-accent-light) transparent;\n}\n\n/* Chrome, Edge, and Safari */\n:where(.scrollbarProvider *)::-webkit-scrollbar {\n width: 12px;\n}\n\n:where(.scrollbarProvider *)::-webkit-scrollbar-track {\n background: transparent;\n}\n\n:where(.scrollbarProvider *)::-webkit-scrollbar-thumb {\n background-color: var(--background-accent-light);\n border-radius: 10px;\n border: 3px solid transparent;\n background-clip: padding-box;\n}\n\n/* The page's own scrollbar: <html> is outside every provider, so AhroweProvider sets the thumb\n colour on it. Without that property the value is invalid, and the browser's own stays. */\n:where(html) {\n scrollbar-color: var(--ahrowe-page-scrollbar-thumb) transparent;\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabHeader.module.mjs","names":[],"sources":["../../../../package/common/tabHeader/tabHeader.module.pcss"],"sourcesContent":[".tabHeader {\n display: flex;\n align-items: stretch;\n gap: 4px;\n border-bottom: 1px solid var(--border-color);\n user-select: none;\n overflow-x: auto;\n\n &-tab {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n color: var(--text-dark);\n border-bottom: 2px solid transparent;\n border-radius: var(--default-border-radius) var(--default-border-radius) 0 0;\n transition:\n color 0.2s,\n background 0.2s,\n border-color 0.2s;\n white-space: nowrap;\n\n &:hover {\n /* Longhand, not the shorthand: hover beats -active on specificity, and the shorthand\n would reset the active tab's gradient indicator away while the pointer is over it. */\n background-color: var(--background-accent-light);\n color: var(--text-color);\n }\n\n &-active {\n color: var(--primary-color);\n border-bottom-color: var(--primary-color);\n\n /* Paints the gradient exactly over border-bottom, which a background layer only reaches\n because its origin is the border box. The border stays as the no-gradient fallback. */\n background-image: var(--primary-gradient, none);\n background-repeat: no-repeat;\n background-size: 100% 2px;\n background-position: bottom;\n background-origin: border-box;\n\n &:hover {\n color: var(--primary-color);\n }\n }\n\n &-disabled {\n opacity: 0.5;\n pointer-events: none;\n cursor: default;\n }\n }\n\n &-icon {\n font-size: 18px;\n flex-shrink: 0;\n }\n\n &-labels {\n display: flex;\n flex-direction: column;\n text-align: left;\n line-height: 1.25;\n }\n\n &-title {\n font-weight: var(--header-font-weight, 600);\n font-size: var(--default-font-size);\n }\n\n &-subtitle {\n font-size: var(--text-small-font-size);\n color: var(--text-dark);\n }\n}\n\n@media (width <= 640px) {\n .tabHeader-tab:not(.tabHeader-tab-active) .tabHeader-labels {\n display: none;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"tabHeader.module.mjs","names":[],"sources":["../../../../package/common/tabHeader/tabHeader.module.pcss"],"sourcesContent":[".tabHeader {\n display: flex;\n align-items: stretch;\n gap: 4px;\n border-bottom: 1px solid var(--border-color);\n user-select: none;\n\n /* The y value is not redundant: overflow-x: auto alone computes overflow-y to auto, so any\n vertical overflow, such as a flex column squeezing the strip, let the tabs scroll up and down. */\n overflow: auto hidden;\n\n &-tab {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n color: var(--text-dark);\n border-bottom: 2px solid transparent;\n border-radius: var(--default-border-radius) var(--default-border-radius) 0 0;\n transition:\n color 0.2s,\n background 0.2s,\n border-color 0.2s;\n white-space: nowrap;\n\n &:hover {\n /* Longhand, not the shorthand: hover beats -active on specificity, and the shorthand\n would reset the active tab's gradient indicator away while the pointer is over it. */\n background-color: var(--background-accent-light);\n color: var(--text-color);\n }\n\n &-active {\n color: var(--primary-color);\n border-bottom-color: var(--primary-color);\n\n /* Paints the gradient exactly over border-bottom, which a background layer only reaches\n because its origin is the border box. The border stays as the no-gradient fallback. */\n background-image: var(--primary-gradient, none);\n background-repeat: no-repeat;\n background-size: 100% 2px;\n background-position: bottom;\n background-origin: border-box;\n\n &:hover {\n color: var(--primary-color);\n }\n }\n\n &-disabled {\n opacity: 0.5;\n pointer-events: none;\n cursor: default;\n }\n }\n\n &-icon {\n font-size: 18px;\n flex-shrink: 0;\n }\n\n &-labels {\n display: flex;\n flex-direction: column;\n text-align: left;\n line-height: 1.25;\n }\n\n &-title {\n font-weight: var(--header-font-weight, 600);\n font-size: var(--default-font-size);\n }\n\n &-subtitle {\n font-size: var(--text-small-font-size);\n color: var(--text-dark);\n }\n}\n\n@media (width <= 640px) {\n .tabHeader-tab:not(.tabHeader-tab-active) .tabHeader-labels {\n display: none;\n }\n}\n"],"mappings":""}
|