@ahrowe/ui 0.48.0 → 0.50.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/CHANGELOG.md +25 -0
- package/README.md +3 -0
- package/dist/cjs-types/common/actionIcon/actionIcon.types.d.ts +1 -1
- package/dist/cjs-types/common/button/button.types.d.ts +6 -1
- package/dist/cjs-types/common/chatComposer/chatComposer.d.ts +4 -0
- package/dist/cjs-types/common/chatComposer/chatComposer.types.d.ts +40 -0
- package/dist/cjs-types/common/chatComposer/index.d.ts +2 -0
- package/dist/cjs-types/common/chatMessage/chatMessage.d.ts +4 -0
- package/dist/cjs-types/common/chatMessage/chatMessage.types.d.ts +60 -0
- package/dist/cjs-types/common/chatMessage/index.d.ts +2 -0
- package/dist/cjs-types/common/chatMessageList/chatMessageList.d.ts +4 -0
- package/dist/cjs-types/common/chatMessageList/chatMessageList.types.d.ts +27 -0
- package/dist/cjs-types/common/chatMessageList/index.d.ts +2 -0
- package/dist/cjs-types/common/configProvider/configProvider.types.d.ts +6 -0
- package/dist/cjs-types/common/hooks/useAutoGrow.d.ts +12 -0
- package/dist/cjs-types/common/hooks/useHotkeys.d.ts +11 -0
- package/dist/cjs-types/common/tabHeader/tabHeader.types.d.ts +5 -3
- package/dist/cjs-types/index.d.ts +6 -0
- package/dist/esm/common/button/button.mjs +1 -1
- package/dist/esm/common/button/button.mjs.map +1 -1
- package/dist/esm/common/button/button.module.mjs +1 -1
- package/dist/esm/common/button/button.module.mjs.map +1 -1
- package/dist/esm/common/button/button.types.mjs.map +1 -1
- package/dist/esm/common/chatComposer/chatComposer.mjs +2 -0
- package/dist/esm/common/chatComposer/chatComposer.mjs.map +1 -0
- package/dist/esm/common/chatComposer/chatComposer.module.mjs +2 -0
- package/dist/esm/common/chatComposer/chatComposer.module.mjs.map +1 -0
- package/dist/esm/common/chatMessage/chatMessage.mjs +2 -0
- package/dist/esm/common/chatMessage/chatMessage.mjs.map +1 -0
- package/dist/esm/common/chatMessage/chatMessage.module.mjs +2 -0
- package/dist/esm/common/chatMessage/chatMessage.module.mjs.map +1 -0
- package/dist/esm/common/chatMessage/chatMessage.types.mjs +2 -0
- package/dist/esm/common/chatMessage/chatMessage.types.mjs.map +1 -0
- package/dist/esm/common/chatMessageList/chatMessageList.mjs +2 -0
- package/dist/esm/common/chatMessageList/chatMessageList.mjs.map +1 -0
- package/dist/esm/common/chatMessageList/chatMessageList.module.mjs +2 -0
- package/dist/esm/common/chatMessageList/chatMessageList.module.mjs.map +1 -0
- package/dist/esm/common/commandPalette/commandPalette.mjs +1 -1
- package/dist/esm/common/commandPalette/commandPalette.mjs.map +1 -1
- package/dist/esm/common/dropdown/dropdown.mjs +1 -1
- package/dist/esm/common/hooks/useAutoGrow.mjs +2 -0
- package/dist/esm/common/hooks/useAutoGrow.mjs.map +1 -0
- package/dist/esm/common/hooks/useHotkeys.mjs +1 -1
- package/dist/esm/common/hooks/useHotkeys.mjs.map +1 -1
- package/dist/esm/common/infiniteBlock/useInfiniteScroll.mjs +1 -1
- package/dist/esm/common/infiniteBlock/useInfiniteScroll.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/menu/menu.mjs +1 -1
- package/dist/esm/common/menu/menu.mjs.map +1 -1
- package/dist/esm/common/tabHeader/tabHeader.mjs +1 -1
- package/dist/esm/common/tabHeader/tabHeader.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/style.css +1 -1
- package/dist/types/common/actionIcon/actionIcon.types.d.ts +1 -1
- package/dist/types/common/button/button.types.d.ts +6 -1
- package/dist/types/common/chatComposer/chatComposer.d.ts +4 -0
- package/dist/types/common/chatComposer/chatComposer.types.d.ts +40 -0
- package/dist/types/common/chatComposer/index.d.ts +2 -0
- package/dist/types/common/chatMessage/chatMessage.d.ts +4 -0
- package/dist/types/common/chatMessage/chatMessage.types.d.ts +60 -0
- package/dist/types/common/chatMessage/index.d.ts +2 -0
- package/dist/types/common/chatMessageList/chatMessageList.d.ts +4 -0
- package/dist/types/common/chatMessageList/chatMessageList.types.d.ts +27 -0
- package/dist/types/common/chatMessageList/index.d.ts +2 -0
- package/dist/types/common/configProvider/configProvider.types.d.ts +6 -0
- package/dist/types/common/hooks/useAutoGrow.d.ts +12 -0
- package/dist/types/common/hooks/useHotkeys.d.ts +11 -0
- package/dist/types/common/tabHeader/tabHeader.types.d.ts +5 -3
- package/dist/types/index.d.ts +6 -0
- package/docs/ActionIcon.md +2 -2
- package/docs/Button.md +18 -2
- package/docs/CLAUDE.md +6 -3
- package/docs/ChatComposer.md +100 -0
- package/docs/ChatMessage.md +88 -0
- package/docs/ChatMessageList.md +113 -0
- package/docs/ConfigProvider.md +1 -0
- package/docs/Hooks.md +23 -4
- package/docs/Menu.md +1 -1
- package/docs/TabHeader.md +19 -8
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.mjs","names":[],"sources":["../../../../package/common/menu/menu.tsx"],"sourcesContent":["import { cloneElement, isValidElement, useEffect, useId, useRef, useState, type ReactElement } from 'react';\nimport cx from 'classnames';\n\nimport styles from './menu.module.pcss';\nimport Popover from '../popover';\nimport { PopoverAlign, PopoverPlacement } from '../popover/popover.types';\nimport { isSelfActivation } from '../utils/activationKey';\nimport { useFocusBoundary } from '../hooks/useFocusBoundary';\nimport { formatHotkey } from '../hooks/useHotkeys';\nimport { isMenuAction, isMenuHeading, isMenuSeparator, type MenuEntry, type MenuProps } from './menu.types';\nimport { hasAnyIcon, renderItemIcon } from './menuItem';\n\n/** How long a typed run stays one search before it starts over. */\nconst TYPEAHEAD_RESET_MS = 600;\n\n/** Index of the next action that can be focused, wrapping, or -1 if there is none. */\nfunction nextEnabled(items: MenuEntry[], from: number, step: 1 | -1): number {\n for (let i = 1; i <= items.length; i++) {\n // The `items.length * i` term only keeps the value positive for a backwards\n // step; JavaScript's `%` would otherwise return a negative index.\n const index = (from + step * i + items.length * i) % items.length;\n const entry = items[index];\n if (isMenuAction(entry) && !entry.disabled) return index;\n }\n return -1;\n}\n\nfunction firstEnabled(items: MenuEntry[]): number {\n return items.findIndex((entry) => isMenuAction(entry) && !entry.disabled);\n}\n\nfunction lastEnabled(items: MenuEntry[]): number {\n for (let i = items.length - 1; i >= 0; i--) {\n const entry = items[i];\n if (isMenuAction(entry) && !entry.disabled) return i;\n }\n return -1;\n}\n\n/**\n * A menu of actions on a trigger of your choosing.\n *\n * `Popover` does the anchoring, portalling and outside-click work but takes\n * arbitrary `content`, which leaves every consumer to write their own `ul`/`li`\n * and, in practice, to leave out the roles and the arrow keys. This is that list,\n * done once: `role=\"menu\"`, a roving focus that skips disabled entries, Escape\n * back to the trigger, and separators and headings that stay out of the keyboard\n * order.\n */\nfunction Menu({\n items,\n children,\n onAction,\n isOpen: controlledOpen,\n onOpenChange,\n placement = PopoverPlacement.Bottom,\n align = PopoverAlign.Start,\n presentation,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: MenuProps): ReactElement {\n const isControlled = controlledOpen !== undefined;\n const [internalOpen, setInternalOpen] = useState(false);\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const [activeIndex, setActiveIndex] = useState(-1);\n const itemRefs = useRef<(HTMLElement | null)[]>([]);\n const triggerRef = useRef<HTMLSpanElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n // Tab leaves the panel in both directions, so the menu needs the same boundary\n // Popover uses: back to the trigger, or on to whatever follows it.\n const { restoreFocusToTrigger, focusAfterTrigger } = useFocusBoundary({ triggerRef, contentRef: menuRef });\n const menuId = useId();\n // Which end to land on when the menu opens: `ArrowUp` on the trigger opens at\n // the bottom, everything else at the top.\n const openAtRef = useRef<'first' | 'last'>('first');\n const typeahead = useRef<{ query: string; timer: ReturnType<typeof setTimeout> | undefined }>({\n query: '',\n timer: undefined,\n });\n\n // Whether a key opened the menu, which decides between landing the focus on an\n // entry and leaving it on the trigger. Set from Popover, which is what sees the\n // trigger's events, or here when an arrow key did the opening.\n const openedByKeyboardRef = useRef(false);\n\n function setOpen(next: boolean, fromKeyboard = false) {\n if (next) openedByKeyboardRef.current = fromKeyboard;\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n }\n\n // The effect below needs the entries, but must not re-run when the array is rebuilt. A consumer\n // writes `items={[…]}` inline, so it is a new identity on every render of *their* component:\n // keyed off it, any parent re-render while the menu was open threw the focus back to the first\n // entry, mid-navigation. Declared above the effect that reads it, so it has already run.\n const itemsRef = useRef(items);\n useEffect(() => {\n itemsRef.current = items;\n });\n\n // Focus follows the active entry rather than the menu keeping focus and\n // pointing at it: the items are real buttons, so Enter and Space are theirs.\n // Popover's own `focusOnOpen` would take the first focusable and stop there;\n // the active index has to move with it, so the menu does it itself.\n useEffect(() => {\n if (!isOpen) return;\n // A pointer open leaves the focus where the pointer put it. A highlight on an\n // entry nobody pointed at reads as a selection, and the mouse is about to land\n // somewhere else anyway; the first arrow key moves in, see the trigger's keys.\n if (!openedByKeyboardRef.current) {\n setActiveIndex(-1);\n return;\n }\n const entries = itemsRef.current;\n const target = openAtRef.current === 'last' ? lastEnabled(entries) : firstEnabled(entries);\n setActiveIndex(target);\n // The panel is portalled and animated in, so its buttons exist a frame later.\n const frame = requestAnimationFrame(() => {\n itemRefs.current[target]?.focus();\n });\n return () => {\n cancelAnimationFrame(frame);\n openAtRef.current = 'first';\n };\n }, [isOpen]);\n\n useEffect(() => () => clearTimeout(typeahead.current.timer), []);\n\n function moveTo(index: number) {\n if (index < 0) return;\n setActiveIndex(index);\n itemRefs.current[index]?.focus();\n }\n\n function close(returnFocus: boolean) {\n setOpen(false);\n if (returnFocus) restoreFocusToTrigger();\n }\n\n /**\n * Jumps to the next entry whose label starts with what has been typed. The\n * text comes off the rendered button rather than the `label` prop, which is a\n * `ReactNode` and may be an icon, a badge or anything else.\n */\n function handleTypeahead(key: string): boolean {\n if (key.length !== 1 || !key.trim()) return false;\n clearTimeout(typeahead.current.timer);\n typeahead.current.query += key.toLowerCase();\n typeahead.current.timer = setTimeout(() => {\n typeahead.current.query = '';\n }, TYPEAHEAD_RESET_MS);\n\n const query = typeahead.current.query;\n // A repeated single character walks through the entries starting with it,\n // rather than sticking to the first one.\n const repeated = query.length > 1 && [...query].every((c) => c === query[0]);\n const needle = repeated ? query[0] : query;\n const from = repeated || query.length === 1 ? activeIndex : activeIndex - 1;\n\n for (let i = 1; i <= items.length; i++) {\n const index = (from + i + items.length) % items.length;\n const entry = items[index];\n if (!isMenuAction(entry) || entry.disabled) continue;\n const text = itemRefs.current[index]?.textContent?.trim().toLowerCase() ?? '';\n if (text.startsWith(needle)) {\n moveTo(index);\n return true;\n }\n }\n return false;\n }\n\n /** The trigger's own keys, which decide where the menu opens. */\n function handleTriggerKeyDown(event: React.KeyboardEvent) {\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;\n // Popover opens on these keys too; letting both act would be harmless but\n // this keeps the decision about where to land in one place.\n event.preventDefault();\n event.stopPropagation();\n // Already open means a pointer opened it and the focus never left the trigger,\n // since an entry's own keys never reach here. This is the key that moves in.\n if (isOpen) {\n moveTo(event.key === 'ArrowUp' ? lastEnabled(items) : firstEnabled(items));\n return;\n }\n openAtRef.current = event.key === 'ArrowUp' ? 'last' : 'first';\n setOpen(true, true);\n }\n\n function handleKeyDown(event: React.KeyboardEvent) {\n switch (event.key) {\n case 'ArrowDown':\n moveTo(nextEnabled(items, activeIndex, 1));\n break;\n case 'ArrowUp':\n // Stepping back from \"nothing active\" lands two short of the end, so the end is named.\n moveTo(activeIndex < 0 ? lastEnabled(items) : nextEnabled(items, activeIndex, -1));\n break;\n case 'Home':\n moveTo(firstEnabled(items));\n break;\n case 'End':\n moveTo(lastEnabled(items));\n break;\n // Popover handles both of these too, but only once the focus has actually\n // reached the panel: its Escape restores focus on that condition, and its\n // Tab handling acts at the first and last focusable. A menu focuses its\n // first entry a frame after opening, so a key pressed in between would\n // fall through. Here they are unconditional, which is also what a menu\n // wants from Tab: leave, whatever is focused.\n case 'Escape':\n close(true);\n break;\n case 'Tab':\n // Carry on from the trigger, as if the panel had never been in the tab\n // order. Closing and letting the browser take it from here would move on\n // from an entry that is about to be removed, which lands at the top of\n // the document.\n close(false);\n if (event.shiftKey) restoreFocusToTrigger();\n else focusAfterTrigger();\n break;\n default:\n if (!handleTypeahead(event.key)) return;\n }\n event.preventDefault();\n event.stopPropagation();\n }\n\n function handleAction(index: number) {\n const entry = items[index];\n if (!isMenuAction(entry) || entry.disabled) return;\n // Not runMenuAction: a link entry is an <a>, which the browser follows by itself.\n entry.onClick?.();\n onAction?.(entry.id);\n close(true);\n }\n\n // A screen reader has no way to tell that this button opens a menu unless the\n // button itself says so. Only filled in where the consumer has not, so a\n // trigger that describes itself keeps doing that.\n const triggerWithMenuSemantics = isValidElement<Record<string, unknown>>(children)\n ? cloneElement(children, {\n 'aria-haspopup': children.props['aria-haspopup'] ?? 'menu',\n 'aria-expanded': children.props['aria-expanded'] ?? isOpen,\n 'aria-controls': isOpen ? (children.props['aria-controls'] ?? menuId) : children.props['aria-controls'],\n })\n : children;\n\n const hasIcons = hasAnyIcon(items);\n\n const content = (\n <div\n ref={menuRef}\n id={menuId}\n role='menu'\n className={cx(styles.menu, classNames?.menu)}\n style={slotStyles?.menu}\n onKeyDown={handleKeyDown}\n >\n {items.map((entry, index) => {\n if (isMenuSeparator(entry))\n return (\n <div\n // Separators and headings carry no id of their own, and reordering\n // the list re-renders it wholesale anyway.\n key={`separator-${index}`}\n role='separator'\n className={cx(styles.menuSeparator, classNames?.separator)}\n style={slotStyles?.separator}\n />\n );\n\n if (isMenuHeading(entry))\n return (\n <div\n key={`heading-${index}`}\n role='presentation'\n className={cx(styles.menuHeading, classNames?.heading)}\n style={slotStyles?.heading}\n >\n {entry.heading}\n </div>\n );\n\n const itemProps = {\n ref: (el: HTMLElement | null) => {\n itemRefs.current[index] = el;\n },\n role: 'menuitem',\n // One tab stop for the whole menu: the arrow keys move between items.\n tabIndex: index === activeIndex ? 0 : -1,\n className: cx(styles.menuItem, entry.danger && styles.menuItemDanger, classNames?.item),\n style: slotStyles?.item,\n onClick: () => handleAction(index),\n onMouseEnter: () => setActiveIndex(index),\n };\n const itemContent = (\n <>\n {renderItemIcon(entry.icon, hasIcons, {\n className: cx(styles.menuItemIcon, classNames?.itemIcon),\n style: slotStyles?.itemIcon,\n })}\n <span className={cx(styles.menuItemLabel, classNames?.itemLabel)} style={slotStyles?.itemLabel}>\n {entry.label}\n </span>\n {entry.shortcut != null && (\n <span className={cx(styles.menuItemShortcut, classNames?.itemShortcut)} style={slotStyles?.itemShortcut}>\n {formatHotkey(entry.shortcut)}\n </span>\n )}\n </>\n );\n\n // An <a> cannot be disabled, so a disabled link is a disabled button.\n return entry.href && !entry.disabled ? (\n <a\n key={entry.id}\n href={entry.href}\n {...itemProps}\n // A link takes Enter but not Space, which every other entry answers to.\n onKeyDown={(event) => {\n if (event.key !== ' ' || !isSelfActivation(event)) return;\n event.preventDefault();\n event.currentTarget.click();\n }}\n >\n {itemContent}\n </a>\n ) : (\n <button key={entry.id} type='button' disabled={entry.disabled} {...itemProps}>\n {itemContent}\n </button>\n );\n })}\n </div>\n );\n\n return (\n <Popover\n {...rest}\n isOpen={isOpen}\n onOpenChange={(next, { fromKeyboard }) => setOpen(next, fromKeyboard)}\n placement={placement}\n align={align}\n presentation={presentation}\n content={content}\n // The list pads its own rows, so a hover highlight reaches the panel edge,\n // and it sizes itself. Focus is the menu's own business, see above.\n focusOnOpen={false}\n constrainWidth={false}\n classNames={{ panel: styles.menuPanel }}\n className={cx(className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <span\n ref={triggerRef}\n className={cx(styles.menuTrigger, classNames?.trigger)}\n style={slotStyles?.trigger}\n onKeyDown={handleTriggerKeyDown}\n >\n {triggerWithMenuSemantics}\n </span>\n </Popover>\n );\n}\n\nexport default Menu;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"menu.mjs","names":[],"sources":["../../../../package/common/menu/menu.tsx"],"sourcesContent":["import { cloneElement, isValidElement, useEffect, useId, useRef, useState, type ReactElement } from 'react';\nimport cx from 'classnames';\n\nimport styles from './menu.module.pcss';\nimport Popover from '../popover';\nimport { PopoverAlign, PopoverPlacement } from '../popover/popover.types';\nimport { isSelfActivation } from '../utils/activationKey';\nimport { useFocusBoundary } from '../hooks/useFocusBoundary';\nimport { ariaKeyshortcuts, formatHotkey } from '../hooks/useHotkeys';\nimport { isMenuAction, isMenuHeading, isMenuSeparator, type MenuEntry, type MenuProps } from './menu.types';\nimport { hasAnyIcon, renderItemIcon } from './menuItem';\n\n/** How long a typed run stays one search before it starts over. */\nconst TYPEAHEAD_RESET_MS = 600;\n\n/** Index of the next action that can be focused, wrapping, or -1 if there is none. */\nfunction nextEnabled(items: MenuEntry[], from: number, step: 1 | -1): number {\n for (let i = 1; i <= items.length; i++) {\n // The `items.length * i` term only keeps the value positive for a backwards\n // step; JavaScript's `%` would otherwise return a negative index.\n const index = (from + step * i + items.length * i) % items.length;\n const entry = items[index];\n if (isMenuAction(entry) && !entry.disabled) return index;\n }\n return -1;\n}\n\nfunction firstEnabled(items: MenuEntry[]): number {\n return items.findIndex((entry) => isMenuAction(entry) && !entry.disabled);\n}\n\nfunction lastEnabled(items: MenuEntry[]): number {\n for (let i = items.length - 1; i >= 0; i--) {\n const entry = items[i];\n if (isMenuAction(entry) && !entry.disabled) return i;\n }\n return -1;\n}\n\n/**\n * A menu of actions on a trigger of your choosing.\n *\n * `Popover` does the anchoring, portalling and outside-click work but takes\n * arbitrary `content`, which leaves every consumer to write their own `ul`/`li`\n * and, in practice, to leave out the roles and the arrow keys. This is that list,\n * done once: `role=\"menu\"`, a roving focus that skips disabled entries, Escape\n * back to the trigger, and separators and headings that stay out of the keyboard\n * order.\n */\nfunction Menu({\n items,\n children,\n onAction,\n isOpen: controlledOpen,\n onOpenChange,\n placement = PopoverPlacement.Bottom,\n align = PopoverAlign.Start,\n presentation,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: MenuProps): ReactElement {\n const isControlled = controlledOpen !== undefined;\n const [internalOpen, setInternalOpen] = useState(false);\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const [activeIndex, setActiveIndex] = useState(-1);\n const itemRefs = useRef<(HTMLElement | null)[]>([]);\n const triggerRef = useRef<HTMLSpanElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n // Tab leaves the panel in both directions, so the menu needs the same boundary\n // Popover uses: back to the trigger, or on to whatever follows it.\n const { restoreFocusToTrigger, focusAfterTrigger } = useFocusBoundary({ triggerRef, contentRef: menuRef });\n const menuId = useId();\n // Which end to land on when the menu opens: `ArrowUp` on the trigger opens at\n // the bottom, everything else at the top.\n const openAtRef = useRef<'first' | 'last'>('first');\n const typeahead = useRef<{ query: string; timer: ReturnType<typeof setTimeout> | undefined }>({\n query: '',\n timer: undefined,\n });\n\n // Whether a key opened the menu, which decides between landing the focus on an\n // entry and leaving it on the trigger. Set from Popover, which is what sees the\n // trigger's events, or here when an arrow key did the opening.\n const openedByKeyboardRef = useRef(false);\n\n function setOpen(next: boolean, fromKeyboard = false) {\n if (next) openedByKeyboardRef.current = fromKeyboard;\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n }\n\n // The effect below needs the entries, but must not re-run when the array is rebuilt. A consumer\n // writes `items={[…]}` inline, so it is a new identity on every render of *their* component:\n // keyed off it, any parent re-render while the menu was open threw the focus back to the first\n // entry, mid-navigation. Declared above the effect that reads it, so it has already run.\n const itemsRef = useRef(items);\n useEffect(() => {\n itemsRef.current = items;\n });\n\n // Focus follows the active entry rather than the menu keeping focus and\n // pointing at it: the items are real buttons, so Enter and Space are theirs.\n // Popover's own `focusOnOpen` would take the first focusable and stop there;\n // the active index has to move with it, so the menu does it itself.\n useEffect(() => {\n if (!isOpen) return;\n // A pointer open leaves the focus where the pointer put it. A highlight on an\n // entry nobody pointed at reads as a selection, and the mouse is about to land\n // somewhere else anyway; the first arrow key moves in, see the trigger's keys.\n if (!openedByKeyboardRef.current) {\n setActiveIndex(-1);\n return;\n }\n const entries = itemsRef.current;\n const target = openAtRef.current === 'last' ? lastEnabled(entries) : firstEnabled(entries);\n setActiveIndex(target);\n // The panel is portalled and animated in, so its buttons exist a frame later.\n const frame = requestAnimationFrame(() => {\n itemRefs.current[target]?.focus();\n });\n return () => {\n cancelAnimationFrame(frame);\n openAtRef.current = 'first';\n };\n }, [isOpen]);\n\n useEffect(() => () => clearTimeout(typeahead.current.timer), []);\n\n function moveTo(index: number) {\n if (index < 0) return;\n setActiveIndex(index);\n itemRefs.current[index]?.focus();\n }\n\n function close(returnFocus: boolean) {\n setOpen(false);\n if (returnFocus) restoreFocusToTrigger();\n }\n\n /**\n * Jumps to the next entry whose label starts with what has been typed. The\n * text comes off the rendered button rather than the `label` prop, which is a\n * `ReactNode` and may be an icon, a badge or anything else.\n */\n function handleTypeahead(key: string): boolean {\n if (key.length !== 1 || !key.trim()) return false;\n clearTimeout(typeahead.current.timer);\n typeahead.current.query += key.toLowerCase();\n typeahead.current.timer = setTimeout(() => {\n typeahead.current.query = '';\n }, TYPEAHEAD_RESET_MS);\n\n const query = typeahead.current.query;\n // A repeated single character walks through the entries starting with it,\n // rather than sticking to the first one.\n const repeated = query.length > 1 && [...query].every((c) => c === query[0]);\n const needle = repeated ? query[0] : query;\n const from = repeated || query.length === 1 ? activeIndex : activeIndex - 1;\n\n for (let i = 1; i <= items.length; i++) {\n const index = (from + i + items.length) % items.length;\n const entry = items[index];\n if (!isMenuAction(entry) || entry.disabled) continue;\n const text = itemRefs.current[index]?.textContent?.trim().toLowerCase() ?? '';\n if (text.startsWith(needle)) {\n moveTo(index);\n return true;\n }\n }\n return false;\n }\n\n /** The trigger's own keys, which decide where the menu opens. */\n function handleTriggerKeyDown(event: React.KeyboardEvent) {\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;\n // Popover opens on these keys too; letting both act would be harmless but\n // this keeps the decision about where to land in one place.\n event.preventDefault();\n event.stopPropagation();\n // Already open means a pointer opened it and the focus never left the trigger,\n // since an entry's own keys never reach here. This is the key that moves in.\n if (isOpen) {\n moveTo(event.key === 'ArrowUp' ? lastEnabled(items) : firstEnabled(items));\n return;\n }\n openAtRef.current = event.key === 'ArrowUp' ? 'last' : 'first';\n setOpen(true, true);\n }\n\n function handleKeyDown(event: React.KeyboardEvent) {\n switch (event.key) {\n case 'ArrowDown':\n moveTo(nextEnabled(items, activeIndex, 1));\n break;\n case 'ArrowUp':\n // Stepping back from \"nothing active\" lands two short of the end, so the end is named.\n moveTo(activeIndex < 0 ? lastEnabled(items) : nextEnabled(items, activeIndex, -1));\n break;\n case 'Home':\n moveTo(firstEnabled(items));\n break;\n case 'End':\n moveTo(lastEnabled(items));\n break;\n // Popover handles both of these too, but only once the focus has actually\n // reached the panel: its Escape restores focus on that condition, and its\n // Tab handling acts at the first and last focusable. A menu focuses its\n // first entry a frame after opening, so a key pressed in between would\n // fall through. Here they are unconditional, which is also what a menu\n // wants from Tab: leave, whatever is focused.\n case 'Escape':\n close(true);\n break;\n case 'Tab':\n // Carry on from the trigger, as if the panel had never been in the tab\n // order. Closing and letting the browser take it from here would move on\n // from an entry that is about to be removed, which lands at the top of\n // the document.\n close(false);\n if (event.shiftKey) restoreFocusToTrigger();\n else focusAfterTrigger();\n break;\n default:\n if (!handleTypeahead(event.key)) return;\n }\n event.preventDefault();\n event.stopPropagation();\n }\n\n function handleAction(index: number) {\n const entry = items[index];\n if (!isMenuAction(entry) || entry.disabled) return;\n // Not runMenuAction: a link entry is an <a>, which the browser follows by itself.\n entry.onClick?.();\n onAction?.(entry.id);\n close(true);\n }\n\n // A screen reader has no way to tell that this button opens a menu unless the\n // button itself says so. Only filled in where the consumer has not, so a\n // trigger that describes itself keeps doing that.\n const triggerWithMenuSemantics = isValidElement<Record<string, unknown>>(children)\n ? cloneElement(children, {\n 'aria-haspopup': children.props['aria-haspopup'] ?? 'menu',\n 'aria-expanded': children.props['aria-expanded'] ?? isOpen,\n 'aria-controls': isOpen ? (children.props['aria-controls'] ?? menuId) : children.props['aria-controls'],\n })\n : children;\n\n const hasIcons = hasAnyIcon(items);\n\n const content = (\n <div\n ref={menuRef}\n id={menuId}\n role='menu'\n className={cx(styles.menu, classNames?.menu)}\n style={slotStyles?.menu}\n onKeyDown={handleKeyDown}\n >\n {items.map((entry, index) => {\n if (isMenuSeparator(entry))\n return (\n <div\n // Separators and headings carry no id of their own, and reordering\n // the list re-renders it wholesale anyway.\n key={`separator-${index}`}\n role='separator'\n className={cx(styles.menuSeparator, classNames?.separator)}\n style={slotStyles?.separator}\n />\n );\n\n if (isMenuHeading(entry))\n return (\n <div\n key={`heading-${index}`}\n role='presentation'\n className={cx(styles.menuHeading, classNames?.heading)}\n style={slotStyles?.heading}\n >\n {entry.heading}\n </div>\n );\n\n const itemProps = {\n ref: (el: HTMLElement | null) => {\n itemRefs.current[index] = el;\n },\n role: 'menuitem',\n 'aria-keyshortcuts': ariaKeyshortcuts(entry.shortcut),\n // One tab stop for the whole menu: the arrow keys move between items.\n tabIndex: index === activeIndex ? 0 : -1,\n className: cx(styles.menuItem, entry.danger && styles.menuItemDanger, classNames?.item),\n style: slotStyles?.item,\n onClick: () => handleAction(index),\n onMouseEnter: () => setActiveIndex(index),\n };\n const itemContent = (\n <>\n {renderItemIcon(entry.icon, hasIcons, {\n className: cx(styles.menuItemIcon, classNames?.itemIcon),\n style: slotStyles?.itemIcon,\n })}\n <span className={cx(styles.menuItemLabel, classNames?.itemLabel)} style={slotStyles?.itemLabel}>\n {entry.label}\n </span>\n {entry.shortcut != null && (\n <span\n aria-hidden\n className={cx(styles.menuItemShortcut, classNames?.itemShortcut)}\n style={slotStyles?.itemShortcut}\n >\n {formatHotkey(entry.shortcut)}\n </span>\n )}\n </>\n );\n\n // An <a> cannot be disabled, so a disabled link is a disabled button.\n return entry.href && !entry.disabled ? (\n <a\n key={entry.id}\n href={entry.href}\n {...itemProps}\n // A link takes Enter but not Space, which every other entry answers to.\n onKeyDown={(event) => {\n if (event.key !== ' ' || !isSelfActivation(event)) return;\n event.preventDefault();\n event.currentTarget.click();\n }}\n >\n {itemContent}\n </a>\n ) : (\n <button key={entry.id} type='button' disabled={entry.disabled} {...itemProps}>\n {itemContent}\n </button>\n );\n })}\n </div>\n );\n\n return (\n <Popover\n {...rest}\n isOpen={isOpen}\n onOpenChange={(next, { fromKeyboard }) => setOpen(next, fromKeyboard)}\n placement={placement}\n align={align}\n presentation={presentation}\n content={content}\n // The list pads its own rows, so a hover highlight reaches the panel edge,\n // and it sizes itself. Focus is the menu's own business, see above.\n focusOnOpen={false}\n constrainWidth={false}\n classNames={{ panel: styles.menuPanel }}\n className={cx(className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <span\n ref={triggerRef}\n className={cx(styles.menuTrigger, classNames?.trigger)}\n style={slotStyles?.trigger}\n onKeyDown={handleTriggerKeyDown}\n >\n {triggerWithMenuSemantics}\n </span>\n </Popover>\n );\n}\n\nexport default Menu;\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{renderIcon as e}from"../utils/renderIcon.mjs";import t from"../interactableDiv/index.mjs";import n from"./tabHeader.module.mjs";import"react";import r from"classnames";import{jsx as i,jsxs as a}from"react/jsx-runtime";function o({tabs:
|
|
1
|
+
"use client";import{renderIcon as e}from"../utils/renderIcon.mjs";import t from"../interactableDiv/index.mjs";import n from"./tabHeader.module.mjs";import"react";import r from"classnames";import{jsx as i,jsxs as a}from"react/jsx-runtime";function o(e){return e!=null&&e!==!1&&e!==``}function s({tabs:s=[],currentTab:c,onChange:l,className:u,style:d,classNames:f,styles:p,...m}){return i(`div`,{...m,role:`tablist`,className:r(n.tabHeader,f?.root,u),style:{...p?.root,...d},children:s.map(s=>{let u=s.id===c,d=o(s.title),m=o(s.subtitle),h=d||m;return a(t,{role:`tab`,"aria-selected":u,"aria-disabled":s.disabled||void 0,tabIndex:s.disabled?-1:0,className:r(n.tabHeaderTab,{[n.tabHeaderTabActive]:u},{[n.tabHeaderTabDisabled]:s.disabled},f?.tab),style:p?.tab,onClick:()=>{s.disabled||u||l(s.id)},children:[e(s.icon,{className:r(n.tabHeaderIcon,f?.icon),style:p?.icon}),h&&a(`div`,{className:r(n.tabHeaderLabels,f?.labels),style:p?.labels,children:[d&&i(`div`,{className:r(n.tabHeaderTitle,f?.title),style:p?.title,children:s.title}),m&&i(`div`,{className:r(n.tabHeaderSubtitle,f?.subtitle),style:p?.subtitle,children:s.subtitle})]}),o(s.endContent)&&i(`span`,{className:f?.endContent,style:p?.endContent,children:s.endContent})]},s.id)})})}export{s as default};
|
|
2
2
|
//# sourceMappingURL=tabHeader.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabHeader.mjs","names":[],"sources":["../../../../package/common/tabHeader/tabHeader.tsx"],"sourcesContent":["import React from 'react';\nimport cx from 'classnames';\n\nimport InteractableDiv from '../interactableDiv';\nimport type { TabHeaderProps, TabHeaderTab } from './tabHeader.types';\n\nimport styles from './tabHeader.module.pcss';\nimport { renderIcon } from '../utils/renderIcon';\n\nfunction TabHeader({\n tabs = [],\n currentTab,\n onChange,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: TabHeaderProps) {\n return (\n <div\n {...rest}\n role='tablist'\n className={cx(styles.tabHeader, classNames?.root, className)}\n style={{ ...slotStyles?.root, ...style }}\n >\n {tabs.map((tab: TabHeaderTab) => {\n const isActive = tab.id === currentTab;\n const
|
|
1
|
+
{"version":3,"file":"tabHeader.mjs","names":[],"sources":["../../../../package/common/tabHeader/tabHeader.tsx"],"sourcesContent":["import React from 'react';\nimport cx from 'classnames';\n\nimport InteractableDiv from '../interactableDiv';\nimport type { TabHeaderProps, TabHeaderTab } from './tabHeader.types';\n\nimport styles from './tabHeader.module.pcss';\nimport { renderIcon } from '../utils/renderIcon';\n\n// Not a truthiness test: a count of 0 is content.\nfunction hasContent(node: React.ReactNode) {\n return node != null && node !== false && node !== '';\n}\n\nfunction TabHeader({\n tabs = [],\n currentTab,\n onChange,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: TabHeaderProps) {\n return (\n <div\n {...rest}\n role='tablist'\n className={cx(styles.tabHeader, classNames?.root, className)}\n style={{ ...slotStyles?.root, ...style }}\n >\n {tabs.map((tab: TabHeaderTab) => {\n const isActive = tab.id === currentTab;\n const hasTitle = hasContent(tab.title);\n const hasSubtitle = hasContent(tab.subtitle);\n const hasLabels = hasTitle || hasSubtitle;\n\n return (\n <InteractableDiv\n key={tab.id}\n role='tab'\n aria-selected={isActive}\n aria-disabled={tab.disabled || undefined}\n tabIndex={tab.disabled ? -1 : 0}\n className={cx(\n styles.tabHeaderTab,\n { [styles.tabHeaderTabActive]: isActive },\n { [styles.tabHeaderTabDisabled]: tab.disabled },\n classNames?.tab,\n )}\n style={slotStyles?.tab}\n onClick={() => {\n if (tab.disabled || isActive) return;\n onChange(tab.id);\n }}\n >\n {renderIcon(tab.icon, {\n className: cx(styles.tabHeaderIcon, classNames?.icon),\n style: slotStyles?.icon,\n })}\n {hasLabels && (\n <div className={cx(styles.tabHeaderLabels, classNames?.labels)} style={slotStyles?.labels}>\n {hasTitle && (\n <div className={cx(styles.tabHeaderTitle, classNames?.title)} style={slotStyles?.title}>\n {tab.title}\n </div>\n )}\n {hasSubtitle && (\n <div className={cx(styles.tabHeaderSubtitle, classNames?.subtitle)} style={slotStyles?.subtitle}>\n {tab.subtitle}\n </div>\n )}\n </div>\n )}\n {/* Outside the labels, which a narrow screen hides on every inactive tab. */}\n {hasContent(tab.endContent) && (\n <span className={classNames?.endContent} style={slotStyles?.endContent}>\n {tab.endContent}\n </span>\n )}\n </InteractableDiv>\n );\n })}\n </div>\n );\n}\n\nexport default TabHeader;\n"],"mappings":"8OAUA,SAAS,EAAW,EAAuB,CACzC,OAAO,GAAQ,MAAQ,IAAS,IAAS,IAAS,EACpD,CAEA,SAAS,EAAU,CACjB,OAAO,CAAC,EACR,aACA,WACA,YACA,QACA,aACA,OAAQ,EACR,GAAG,GACc,CACjB,OACE,EAAC,MAAD,CACE,GAAI,EACJ,KAAK,UACL,UAAW,EAAG,EAAO,UAAW,GAAY,KAAM,CAAS,EAC3D,MAAO,CAAE,GAAG,GAAY,KAAM,GAAG,CAAM,EAEtC,SAAA,EAAK,IAAK,GAAsB,CAC/B,IAAM,EAAW,EAAI,KAAO,EACtB,EAAW,EAAW,EAAI,KAAK,EAC/B,EAAc,EAAW,EAAI,QAAQ,EACrC,EAAY,GAAY,EAE9B,OACE,EAAC,EAAD,CAEE,KAAK,MACL,gBAAe,EACf,gBAAe,EAAI,UAAY,IAAA,GAC/B,SAAU,EAAI,SAAW,GAAK,EAC9B,UAAW,EACT,EAAO,aACP,EAAG,EAAO,oBAAqB,CAAS,EACxC,EAAG,EAAO,sBAAuB,EAAI,QAAS,EAC9C,GAAY,GACd,EACA,MAAO,GAAY,IACnB,YAAe,CACT,EAAI,UAAY,GACpB,EAAS,EAAI,EAAE,CACjB,EAhBF,SAAA,CAkBG,EAAW,EAAI,KAAM,CACpB,UAAW,EAAG,EAAO,cAAe,GAAY,IAAI,EACpD,MAAO,GAAY,IACrB,CAAC,EACA,GACC,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,gBAAiB,GAAY,MAAM,EAAG,MAAO,GAAY,OAAnF,SAAA,CACG,GACC,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,eAAgB,GAAY,KAAK,EAAG,MAAO,GAAY,MAC9E,SAAA,EAAI,KACF,CAAA,EAEN,GACC,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,kBAAmB,GAAY,QAAQ,EAAG,MAAO,GAAY,SACpF,SAAA,EAAI,QACF,CAAA,CAEJ,IAGN,EAAW,EAAI,UAAU,GACxB,EAAC,OAAD,CAAM,UAAW,GAAY,WAAY,MAAO,GAAY,WACzD,SAAA,EAAI,UACD,CAAA,CAEO,CAzCV,EAAA,EAAI,EAyCM,CAErB,CAAC,CACE,CAAA,CAET"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{AccordionStyleType as e}from"./common/accordion/accordion.types.mjs";import t from"./common/configProvider/configProvider.mjs";import{useComponentDefaults as n}from"./common/configProvider/useComponentDefaults.mjs";import{useLabels as r}from"./common/configProvider/useLabels.mjs";import{usePresentationDefault as i}from"./common/configProvider/usePresentationDefault.mjs";import{Presentation as a}from"./common/configProvider/presentation.types.mjs";import{ThemeColor as o}from"./common/themeProvider/color.types.mjs";import s from"./common/accordion/accordion.mjs";import{LoaderType as c}from"./common/loader/loader.types.mjs";import l from"./common/loader/loader.mjs";import{ButtonSize as u,ButtonStyleType as d,ButtonType as f}from"./common/button/button.types.mjs";import p from"./common/ripple/ripple.mjs";import m from"./common/button/button.mjs";import h from"./common/actionButtons/actionButtons.mjs";import g from"./common/actionIcon/actionIcon.mjs";import _ from"./common/scrollbarProvider/index.mjs";import{defaultTheme as v}from"./common/themeProvider/defaultTheme.mjs";import y from"./common/themeProvider/themeProvider.mjs";import{lightTheme as b}from"./common/themeProvider/lightTheme.mjs";import x from"./common/bodyEnd/bodyEnd.mjs";import S from"./common/hooks/useMediaQuery.mjs";import C from"./common/hooks/useCoarsePointer.mjs";import{useSwipeDismiss as w}from"./common/hooks/useSwipeDismiss.mjs";import{showToast as T}from"./common/toast/toastService.mjs";import E from"./common/ahroweProvider/ahroweProvider.mjs";import D from"./common/alert/alert.mjs";import O from"./common/animatedLogo/animatedLogo.mjs";import{AnimatedTextUnit as k,AnimatedTextVariant as A}from"./common/animatedText/animatedText.types.mjs";import j from"./common/animatedText/animatedText.mjs";import{BadgePosition as M,BadgeStyleType as N}from"./common/badge/badge.types.mjs";import P from"./common/badge/badge.mjs";import F from"./common/avatar/avatar.mjs";import I from"./common/avatar/avatarGroup.mjs";import L from"./common/interactableDiv/index.mjs";import{PopoverAlign as R,PopoverPlacement as z,PopoverTrigger as B}from"./common/popover/popover.types.mjs";import{tabbablesIn as V}from"./common/hooks/useFocusBoundary.mjs";import{useVisualViewportSize as H}from"./common/hooks/useVisualViewportSize.mjs";import{useOverlay as U}from"./common/hooks/useOverlay.mjs";import W from"./common/popover/popover.mjs";import G from"./common/breadcrumb/breadcrumb.mjs";import{ButtonGroupOrientation as K}from"./common/buttonGroup/buttonGroup.types.mjs";import q from"./common/buttonGroup/buttonGroup.mjs";import{dateToDay as J,dateToTime as Y,dayTimeToDate as X,dayToDate as Z}from"./common/utils/day.mjs";import{CalendarView as Q}from"./common/calendar/calendar.types.mjs";import $ from"./common/emptyState/emptyState.mjs";import ee from"./common/optionPicker/optionPicker.mjs";import te from"./common/calendar/calendar.mjs";import{CardStyleType as ne}from"./common/card/card.types.mjs";import re from"./common/card/Card.mjs";import ie from"./common/card/CardHeader.mjs";import ae from"./common/card/CardMedia.mjs";import oe from"./common/card/CardContent.mjs";import se from"./common/card/CardActions.mjs";import ce from"./common/carousel/carousel.mjs";import le from"./common/checkbox/checkbox.mjs";import{ChipStyleType as ue}from"./common/chip/chip.types.mjs";import de from"./common/chip/chip.mjs";import fe from"./common/chip/chipContainer.mjs";import pe from"./common/tooltip/tooltip.mjs";import{InputIconPosition as me,InputType as he}from"./common/input/input.types.mjs";import ge from"./common/input/input.mjs";import _e from"./common/colorPicker/colorPicker.mjs";import{useScrollEdges as ve}from"./common/hooks/useScrollEdges.mjs";import ye from"./common/modal/modal.mjs";import be,{formatHotkey as xe}from"./common/hooks/useHotkeys.mjs";import{isMenuAction as Se,isMenuHeading as Ce,isMenuSeparator as we}from"./common/menu/menu.types.mjs";import Te from"./common/commandPalette/commandPalette.mjs";import Ee from"./common/confirmModal/confirmModal.mjs";import De from"./common/hooks/useClipboard.mjs";import Oe from"./common/copyButton/copyButton.mjs";import{getLocale as ke,mapLocale as Ae,setLocale as je}from"./services/localization.mjs";import Me from"./common/dropdown/dropdown.mjs";import Ne from"./common/datePicker/datePicker.mjs";import{DividerOrientation as Pe,DividerTextPosition as Fe}from"./common/divider/divider.types.mjs";import Ie from"./common/divider/divider.mjs";import Le from"./common/drawer/drawer.mjs";import{DropZoneReturnType as Re,DropZoneStatus as ze}from"./common/dropZone/dropZone.types.mjs";import Be from"./common/dropZone/dropZone.mjs";import Ve from"./common/errorBoundary/errorBoundary.mjs";import He from"./common/fab/fab.mjs";import Ue from"./common/flip/flip.mjs";import{DoorSwing as We,OpeningKind as Ge,PlanIssueKind as Ke,PlanUnitSystem as qe,WallType as Je}from"./common/floorPlan/floorPlan.types.mjs";import{MIN_OPENING_WIDTH as Ye,MIN_WALL_LENGTH as Xe}from"./common/floorPlan/floorPlan.geometry.mjs";import{DEFAULT_WALL_ATTRS as Ze,addOpening as Qe,addRect as $e,addWall as et,cleanupPlan as tt,detachWall as nt,dissolveNode as rt,mergeNodes as it,moveNode as at,removeOpening as ot,removeWall as st,scalePlan as ct,splitWall as lt,transformPlan as ut,updateOpening as dt,validatePlan as ft,wallLength as pt,weldShortWalls as mt}from"./common/floorPlan/floorPlan.graph.mjs";import{MIN_FLOOR_HEIGHT as ht,addFloor as gt,duplicateFloor as _t,emptyFloor as vt,emptyFloorPlan as yt,floorBelow as bt,floorBounds as xt,floorIndex as St,getFloor as Ct,moveFloor as wt,removeFloor as Tt,renameFloor as Et,setFloor as Dt,setFloorHeight as Ot,updateFloor as kt}from"./common/floorPlan/floorPlan.plan.mjs";import{deriveFaces as At,nodeDegrees as jt}from"./common/floorPlan/floorPlan.faces.mjs";import{commitDerivation as Mt,derivePlan as Nt,pruneUnmatchedRooms as Pt,roomAtPoint as Ft}from"./common/floorPlan/floorPlan.rooms.mjs";import{buildWallPaths as It,openingGeometry as Lt,wallCentrelineSpans as Rt}from"./common/floorPlan/floorPlan.path.mjs";import{HIT_PX as zt,HIT_PX_COARSE as Bt,hitTest as Vt,selectionsEqual as Ht,worldTolerances as Ut}from"./common/floorPlan/floorPlan.hit.mjs";import{DEFAULT_SNAP_OPTIONS as Wt,SnapKind as Gt,clientToWorld as Kt,resolveSnap as qt}from"./common/floorPlan/floorPlan.snap.mjs";import{PLAN_FORMAT_VERSION as Jt,planFromJson as Yt,planToJson as Xt}from"./common/floorPlan/floorPlan.json.mjs";import{buildPlanMesh as Zt}from"./common/floorPlan/floorPlan.mesh.mjs";import Qt from"./common/iconPicker/iconPicker.mjs";import $t from"./common/idleManager/idleManager.mjs";import en from"./common/inputDropdown/inputDropdown.mjs";import tn from"./common/kanbanBoard/KanbanColumn.mjs";import nn from"./common/kanbanBoard/KanbanBoard.mjs";import rn from"./common/searchInput/searchInput.mjs";import an from"./common/klipyPicker/klipyPicker.mjs";import on from"./common/loadingOverlay/loadingOverlay.mjs";import sn from"./common/menu/menu.mjs";import{menuHotkeys as cn}from"./common/menu/menuHotkeys.mjs";import ln from"./common/multiSelect/multiSelect.mjs";import un from"./common/numberInput/index.mjs";import{OtpInputCharset as dn}from"./common/otpInput/otpInput.types.mjs";import fn from"./common/otpInput/otpInput.mjs";import pn from"./common/overscroll/overscroll.mjs";import mn from"./common/pagination/pagination.mjs";import hn from"./common/progressBar/progressBar.mjs";import{RadioGroupOrientation as gn}from"./common/radioGroup/radioGroup.types.mjs";import _n from"./common/radioGroup/radioGroup.mjs";import vn from"./common/rating/rating.mjs";import yn from"./common/revealLens/revealLens.mjs";import bn from"./common/roomDrawer/roomDrawer.mjs";import xn from"./common/roomViewer/roomViewer.mjs";import{ScrollFadeAxis as Sn}from"./common/scrollFade/scrollFade.types.mjs";import Cn from"./common/scrollFade/scrollFade.mjs";import{SectionHeaderSize as wn}from"./common/sectionHeader/sectionHeader.types.mjs";import Tn from"./common/sectionHeader/sectionHeader.mjs";import{SkeletonAnimation as En,SkeletonVariant as Dn}from"./common/skeleton/skeleton.types.mjs";import On from"./common/skeleton/skeleton.mjs";import kn from"./common/slider/slider.mjs";import An from"./common/splitButton/splitButton.mjs";import{StepperCollapse as jn,StepperLabelPlacement as Mn,StepperOrientation as Nn,StepperStyleType as Pn}from"./common/stepper/stepper.types.mjs";import Fn from"./common/stepper/stepper.mjs";import In from"./common/sticky/sticky.mjs";import Ln from"./common/switch/switch.mjs";import Rn from"./common/tabHeader/tabHeader.mjs";import zn from"./common/textarea/textarea.mjs";import{useTheme as Bn}from"./common/themeProvider/useTheme.mjs";import Vn,{TiltGroupContext as Hn,useTiltGroup as Un}from"./common/tiltGroup/tiltGroup.mjs";import{defaultTiltEasing as Wn}from"./common/tilt/tiltMath.mjs";import Gn from"./common/tilt/tilt.mjs";import Kn from"./common/timeInput/timeInput.mjs";import{TimelineAlignment as qn}from"./common/timeline/timeline.types.mjs";import Jn from"./common/timeline/timeline.mjs";import Yn from"./common/timer/timer.mjs";import Xn from"./common/virtualList/virtualList.mjs";import{flattenTree as Zn}from"./common/tree/flattenTree.mjs";import Qn from"./common/tree/tree.mjs";import{WeatherType as $n}from"./common/weatherIcon/weatherIcon.types.mjs";import er from"./common/weatherIcon/weatherIcon.mjs";import tr from"./common/wizard/wizard.mjs";import nr from"./services/formValidation/FormValidatorGroupWithForm.mjs";import rr from"./services/formValidation/validatableComponent.mjs";import{useFormValidatorGroup as ir}from"./services/formValidation/useFormValidatorGroup.mjs";import{FormValidator as ar,Validators as or,useFormValidator as sr}from"./services/formValidation/index.mjs";import{hasEightPasswordChars as cr,hasOnePasswordDigit as lr,hasOnePasswordLetter as ur,isBic as dr,isDate as fr,isDay as pr,isEmail as mr,isISODate as hr,isNumber as gr,isPassword as _r,isURL as vr}from"@ahrowe/form-validation";export{s as Accordion,e as AccordionStyleType,h as ActionButtons,g as ActionIcon,E as AhroweProvider,D as Alert,O as AnimatedLogo,j as AnimatedText,k as AnimatedTextUnit,A as AnimatedTextVariant,F as Avatar,I as AvatarGroup,P as Badge,M as BadgePosition,N as BadgeStyleType,x as BodyEnd,G as Breadcrumb,m as Button,q as ButtonGroup,K as ButtonGroupOrientation,u as ButtonSize,d as ButtonStyleType,f as ButtonType,te as Calendar,Q as CalendarView,re as Card,se as CardActions,oe as CardContent,ie as CardHeader,ae as CardMedia,ne as CardStyleType,ce as Carousel,le as Checkbox,de as Chip,fe as ChipContainer,ue as ChipStyleType,_e as ColorPicker,Te as CommandPalette,t as ConfigProvider,Ee as ConfirmModal,Oe as CopyButton,Wt as DEFAULT_SNAP_OPTIONS,Ze as DEFAULT_WALL_ATTRS,Ne as DatePicker,Ie as Divider,Pe as DividerOrientation,Fe as DividerTextPosition,We as DoorSwing,Le as Drawer,Be as DropZone,Re as DropZoneReturnType,ze as DropZoneStatus,Me as Dropdown,$ as EmptyState,Ve as ErrorBoundary,He as Fab,Ue as Flip,ar as FormValidator,nr as FormValidatorGroup,zt as HIT_PX,Bt as HIT_PX_COARSE,Qt as IconPicker,$t as IdleManager,ge as Input,en as InputDropdown,me as InputIconPosition,he as InputType,L as InteractableDiv,nn as KanbanBoard,tn as KanbanColumn,an as KlipyPicker,l as Loader,c as LoaderType,on as LoadingOverlay,ht as MIN_FLOOR_HEIGHT,Ye as MIN_OPENING_WIDTH,Xe as MIN_WALL_LENGTH,sn as Menu,ye as Modal,ln as MultiSelect,un as NumberInput,Ge as OpeningKind,ee as OptionPicker,fn as OtpInput,dn as OtpInputCharset,pn as Overscroll,Jt as PLAN_FORMAT_VERSION,mn as Pagination,Ke as PlanIssueKind,qe as PlanUnitSystem,W as Popover,R as PopoverAlign,z as PopoverPlacement,B as PopoverTrigger,a as Presentation,hn as ProgressBar,_n as RadioGroup,gn as RadioGroupOrientation,vn as Rating,yn as RevealLens,p as Ripple,bn as RoomDrawer,xn as RoomViewer,Cn as ScrollFade,Sn as ScrollFadeAxis,_ as ScrollbarProvider,rn as SearchInput,Tn as SectionHeader,wn as SectionHeaderSize,On as Skeleton,En as SkeletonAnimation,Dn as SkeletonVariant,kn as Slider,Gt as SnapKind,An as SplitButton,Fn as Stepper,jn as StepperCollapse,Mn as StepperLabelPlacement,Nn as StepperOrientation,Pn as StepperStyleType,In as Sticky,Ln as Switch,Rn as TabHeader,zn as Textarea,o as ThemeColor,y as ThemeProvider,Gn as Tilt,Vn as TiltGroup,Hn as TiltGroupContext,Kn as TimeInput,Jn as Timeline,qn as TimelineAlignment,Yn as Timer,pe as Tooltip,Qn as Tree,rr as ValidatableComponent,or as Validators,Xn as VirtualList,Je as WallType,er as WeatherIcon,$n as WeatherType,tr as Wizard,gt as addFloor,Qe as addOpening,$e as addRect,et as addWall,Zt as buildPlanMesh,It as buildWallPaths,tt as cleanupPlan,Kt as clientToWorld,Mt as commitDerivation,J as dateToDay,Y as dateToTime,X as dayTimeToDate,Z as dayToDate,v as defaultTheme,Wn as defaultTiltEasing,At as deriveFaces,Nt as derivePlan,nt as detachWall,rt as dissolveNode,_t as duplicateFloor,vt as emptyFloor,yt as emptyFloorPlan,Zn as flattenTree,bt as floorBelow,xt as floorBounds,St as floorIndex,xe as formatHotkey,Ct as getFloor,ke as getLocale,cr as hasEightPasswordChars,lr as hasOnePasswordDigit,ur as hasOnePasswordLetter,Vt as hitTest,dr as isBic,fr as isDate,pr as isDay,mr as isEmail,hr as isISODate,Se as isMenuAction,Ce as isMenuHeading,we as isMenuSeparator,gr as isNumber,_r as isPassword,vr as isURL,b as lightTheme,Ae as mapLocale,cn as menuHotkeys,it as mergeNodes,wt as moveFloor,at as moveNode,jt as nodeDegrees,Lt as openingGeometry,Yt as planFromJson,Xt as planToJson,Pt as pruneUnmatchedRooms,Tt as removeFloor,ot as removeOpening,st as removeWall,Et as renameFloor,qt as resolveSnap,Ft as roomAtPoint,ct as scalePlan,Ht as selectionsEqual,Dt as setFloor,Ot as setFloorHeight,je as setLocale,T as showToast,lt as splitWall,V as tabbablesIn,ut as transformPlan,kt as updateFloor,dt as updateOpening,De as useClipboard,C as useCoarsePointer,n as useComponentDefaults,sr as useFormValidator,ir as useFormValidatorGroup,be as useHotkeys,r as useLabels,S as useMediaQuery,U as useOverlay,i as usePresentationDefault,ve as useScrollEdges,w as useSwipeDismiss,Bn as useTheme,Un as useTiltGroup,H as useVisualViewportSize,ft as validatePlan,Rt as wallCentrelineSpans,pt as wallLength,mt as weldShortWalls,Ut as worldTolerances};
|
|
1
|
+
"use client";import{AccordionStyleType as e}from"./common/accordion/accordion.types.mjs";import t from"./common/configProvider/configProvider.mjs";import{useComponentDefaults as n}from"./common/configProvider/useComponentDefaults.mjs";import{useLabels as r}from"./common/configProvider/useLabels.mjs";import{usePresentationDefault as i}from"./common/configProvider/usePresentationDefault.mjs";import{Presentation as a}from"./common/configProvider/presentation.types.mjs";import{ThemeColor as o}from"./common/themeProvider/color.types.mjs";import s from"./common/accordion/accordion.mjs";import{LoaderType as c}from"./common/loader/loader.types.mjs";import l from"./common/loader/loader.mjs";import{ButtonSize as u,ButtonStyleType as d,ButtonType as f}from"./common/button/button.types.mjs";import p from"./common/ripple/ripple.mjs";import m,{formatHotkey as h}from"./common/hooks/useHotkeys.mjs";import g from"./common/button/button.mjs";import _ from"./common/actionButtons/actionButtons.mjs";import v from"./common/actionIcon/actionIcon.mjs";import y from"./common/scrollbarProvider/index.mjs";import{defaultTheme as b}from"./common/themeProvider/defaultTheme.mjs";import x from"./common/themeProvider/themeProvider.mjs";import{lightTheme as S}from"./common/themeProvider/lightTheme.mjs";import C from"./common/bodyEnd/bodyEnd.mjs";import w from"./common/hooks/useMediaQuery.mjs";import T from"./common/hooks/useCoarsePointer.mjs";import{useSwipeDismiss as E}from"./common/hooks/useSwipeDismiss.mjs";import{showToast as D}from"./common/toast/toastService.mjs";import O from"./common/ahroweProvider/ahroweProvider.mjs";import k from"./common/alert/alert.mjs";import A from"./common/animatedLogo/animatedLogo.mjs";import{AnimatedTextUnit as j,AnimatedTextVariant as M}from"./common/animatedText/animatedText.types.mjs";import N from"./common/animatedText/animatedText.mjs";import{BadgePosition as P,BadgeStyleType as F}from"./common/badge/badge.types.mjs";import I from"./common/badge/badge.mjs";import L from"./common/avatar/avatar.mjs";import R from"./common/avatar/avatarGroup.mjs";import z from"./common/interactableDiv/index.mjs";import{PopoverAlign as B,PopoverPlacement as V,PopoverTrigger as H}from"./common/popover/popover.types.mjs";import{tabbablesIn as U}from"./common/hooks/useFocusBoundary.mjs";import{useVisualViewportSize as W}from"./common/hooks/useVisualViewportSize.mjs";import{useOverlay as G}from"./common/hooks/useOverlay.mjs";import K from"./common/popover/popover.mjs";import q from"./common/breadcrumb/breadcrumb.mjs";import{ButtonGroupOrientation as J}from"./common/buttonGroup/buttonGroup.types.mjs";import Y from"./common/buttonGroup/buttonGroup.mjs";import{dateToDay as X,dateToTime as Z,dayTimeToDate as Q,dayToDate as $}from"./common/utils/day.mjs";import{CalendarView as ee}from"./common/calendar/calendar.types.mjs";import te from"./common/emptyState/emptyState.mjs";import ne from"./common/optionPicker/optionPicker.mjs";import re from"./common/calendar/calendar.mjs";import{CardStyleType as ie}from"./common/card/card.types.mjs";import ae from"./common/card/Card.mjs";import oe from"./common/card/CardHeader.mjs";import se from"./common/card/CardMedia.mjs";import ce from"./common/card/CardContent.mjs";import le from"./common/card/CardActions.mjs";import ue from"./common/carousel/carousel.mjs";import de from"./common/chatComposer/chatComposer.mjs";import{ChatMessageStatus as fe,ChatMessageStyleType as pe}from"./common/chatMessage/chatMessage.types.mjs";import me from"./common/chatMessage/chatMessage.mjs";import he from"./common/chatMessageList/chatMessageList.mjs";import ge from"./common/checkbox/checkbox.mjs";import{ChipStyleType as _e}from"./common/chip/chip.types.mjs";import ve from"./common/chip/chip.mjs";import ye from"./common/chip/chipContainer.mjs";import be from"./common/tooltip/tooltip.mjs";import{InputIconPosition as xe,InputType as Se}from"./common/input/input.types.mjs";import Ce from"./common/input/input.mjs";import we from"./common/colorPicker/colorPicker.mjs";import{useScrollEdges as Te}from"./common/hooks/useScrollEdges.mjs";import Ee from"./common/modal/modal.mjs";import{isMenuAction as De,isMenuHeading as Oe,isMenuSeparator as ke}from"./common/menu/menu.types.mjs";import Ae from"./common/commandPalette/commandPalette.mjs";import je from"./common/confirmModal/confirmModal.mjs";import Me from"./common/hooks/useClipboard.mjs";import Ne from"./common/copyButton/copyButton.mjs";import{getLocale as Pe,mapLocale as Fe,setLocale as Ie}from"./services/localization.mjs";import Le from"./common/dropdown/dropdown.mjs";import Re from"./common/datePicker/datePicker.mjs";import{DividerOrientation as ze,DividerTextPosition as Be}from"./common/divider/divider.types.mjs";import Ve from"./common/divider/divider.mjs";import He from"./common/drawer/drawer.mjs";import{DropZoneReturnType as Ue,DropZoneStatus as We}from"./common/dropZone/dropZone.types.mjs";import Ge from"./common/dropZone/dropZone.mjs";import Ke from"./common/errorBoundary/errorBoundary.mjs";import qe from"./common/fab/fab.mjs";import Je from"./common/flip/flip.mjs";import{DoorSwing as Ye,OpeningKind as Xe,PlanIssueKind as Ze,PlanUnitSystem as Qe,WallType as $e}from"./common/floorPlan/floorPlan.types.mjs";import{MIN_OPENING_WIDTH as et,MIN_WALL_LENGTH as tt}from"./common/floorPlan/floorPlan.geometry.mjs";import{DEFAULT_WALL_ATTRS as nt,addOpening as rt,addRect as it,addWall as at,cleanupPlan as ot,detachWall as st,dissolveNode as ct,mergeNodes as lt,moveNode as ut,removeOpening as dt,removeWall as ft,scalePlan as pt,splitWall as mt,transformPlan as ht,updateOpening as gt,validatePlan as _t,wallLength as vt,weldShortWalls as yt}from"./common/floorPlan/floorPlan.graph.mjs";import{MIN_FLOOR_HEIGHT as bt,addFloor as xt,duplicateFloor as St,emptyFloor as Ct,emptyFloorPlan as wt,floorBelow as Tt,floorBounds as Et,floorIndex as Dt,getFloor as Ot,moveFloor as kt,removeFloor as At,renameFloor as jt,setFloor as Mt,setFloorHeight as Nt,updateFloor as Pt}from"./common/floorPlan/floorPlan.plan.mjs";import{deriveFaces as Ft,nodeDegrees as It}from"./common/floorPlan/floorPlan.faces.mjs";import{commitDerivation as Lt,derivePlan as Rt,pruneUnmatchedRooms as zt,roomAtPoint as Bt}from"./common/floorPlan/floorPlan.rooms.mjs";import{buildWallPaths as Vt,openingGeometry as Ht,wallCentrelineSpans as Ut}from"./common/floorPlan/floorPlan.path.mjs";import{HIT_PX as Wt,HIT_PX_COARSE as Gt,hitTest as Kt,selectionsEqual as qt,worldTolerances as Jt}from"./common/floorPlan/floorPlan.hit.mjs";import{DEFAULT_SNAP_OPTIONS as Yt,SnapKind as Xt,clientToWorld as Zt,resolveSnap as Qt}from"./common/floorPlan/floorPlan.snap.mjs";import{PLAN_FORMAT_VERSION as $t,planFromJson as en,planToJson as tn}from"./common/floorPlan/floorPlan.json.mjs";import{buildPlanMesh as nn}from"./common/floorPlan/floorPlan.mesh.mjs";import rn from"./common/iconPicker/iconPicker.mjs";import an from"./common/idleManager/idleManager.mjs";import on from"./common/inputDropdown/inputDropdown.mjs";import sn from"./common/kanbanBoard/KanbanColumn.mjs";import cn from"./common/kanbanBoard/KanbanBoard.mjs";import ln from"./common/searchInput/searchInput.mjs";import un from"./common/klipyPicker/klipyPicker.mjs";import dn from"./common/loadingOverlay/loadingOverlay.mjs";import fn from"./common/menu/menu.mjs";import{menuHotkeys as pn}from"./common/menu/menuHotkeys.mjs";import mn from"./common/multiSelect/multiSelect.mjs";import hn from"./common/numberInput/index.mjs";import{OtpInputCharset as gn}from"./common/otpInput/otpInput.types.mjs";import _n from"./common/otpInput/otpInput.mjs";import vn from"./common/overscroll/overscroll.mjs";import yn from"./common/pagination/pagination.mjs";import bn from"./common/progressBar/progressBar.mjs";import{RadioGroupOrientation as xn}from"./common/radioGroup/radioGroup.types.mjs";import Sn from"./common/radioGroup/radioGroup.mjs";import Cn from"./common/rating/rating.mjs";import wn from"./common/revealLens/revealLens.mjs";import Tn from"./common/roomDrawer/roomDrawer.mjs";import En from"./common/roomViewer/roomViewer.mjs";import{ScrollFadeAxis as Dn}from"./common/scrollFade/scrollFade.types.mjs";import On from"./common/scrollFade/scrollFade.mjs";import{SectionHeaderSize as kn}from"./common/sectionHeader/sectionHeader.types.mjs";import An from"./common/sectionHeader/sectionHeader.mjs";import{SkeletonAnimation as jn,SkeletonVariant as Mn}from"./common/skeleton/skeleton.types.mjs";import Nn from"./common/skeleton/skeleton.mjs";import Pn from"./common/slider/slider.mjs";import Fn from"./common/splitButton/splitButton.mjs";import{StepperCollapse as In,StepperLabelPlacement as Ln,StepperOrientation as Rn,StepperStyleType as zn}from"./common/stepper/stepper.types.mjs";import Bn from"./common/stepper/stepper.mjs";import Vn from"./common/sticky/sticky.mjs";import Hn from"./common/switch/switch.mjs";import Un from"./common/tabHeader/tabHeader.mjs";import Wn from"./common/textarea/textarea.mjs";import{useTheme as Gn}from"./common/themeProvider/useTheme.mjs";import Kn,{TiltGroupContext as qn,useTiltGroup as Jn}from"./common/tiltGroup/tiltGroup.mjs";import{defaultTiltEasing as Yn}from"./common/tilt/tiltMath.mjs";import Xn from"./common/tilt/tilt.mjs";import Zn from"./common/timeInput/timeInput.mjs";import{TimelineAlignment as Qn}from"./common/timeline/timeline.types.mjs";import $n from"./common/timeline/timeline.mjs";import er from"./common/timer/timer.mjs";import tr from"./common/virtualList/virtualList.mjs";import{flattenTree as nr}from"./common/tree/flattenTree.mjs";import rr from"./common/tree/tree.mjs";import{WeatherType as ir}from"./common/weatherIcon/weatherIcon.types.mjs";import ar from"./common/weatherIcon/weatherIcon.mjs";import or from"./common/wizard/wizard.mjs";import sr from"./services/formValidation/FormValidatorGroupWithForm.mjs";import cr from"./services/formValidation/validatableComponent.mjs";import{useFormValidatorGroup as lr}from"./services/formValidation/useFormValidatorGroup.mjs";import{FormValidator as ur,Validators as dr,useFormValidator as fr}from"./services/formValidation/index.mjs";import{hasEightPasswordChars as pr,hasOnePasswordDigit as mr,hasOnePasswordLetter as hr,isBic as gr,isDate as _r,isDay as vr,isEmail as yr,isISODate as br,isNumber as xr,isPassword as Sr,isURL as Cr}from"@ahrowe/form-validation";export{s as Accordion,e as AccordionStyleType,_ as ActionButtons,v as ActionIcon,O as AhroweProvider,k as Alert,A as AnimatedLogo,N as AnimatedText,j as AnimatedTextUnit,M as AnimatedTextVariant,L as Avatar,R as AvatarGroup,I as Badge,P as BadgePosition,F as BadgeStyleType,C as BodyEnd,q as Breadcrumb,g as Button,Y as ButtonGroup,J as ButtonGroupOrientation,u as ButtonSize,d as ButtonStyleType,f as ButtonType,re as Calendar,ee as CalendarView,ae as Card,le as CardActions,ce as CardContent,oe as CardHeader,se as CardMedia,ie as CardStyleType,ue as Carousel,de as ChatComposer,me as ChatMessage,he as ChatMessageList,fe as ChatMessageStatus,pe as ChatMessageStyleType,ge as Checkbox,ve as Chip,ye as ChipContainer,_e as ChipStyleType,we as ColorPicker,Ae as CommandPalette,t as ConfigProvider,je as ConfirmModal,Ne as CopyButton,Yt as DEFAULT_SNAP_OPTIONS,nt as DEFAULT_WALL_ATTRS,Re as DatePicker,Ve as Divider,ze as DividerOrientation,Be as DividerTextPosition,Ye as DoorSwing,He as Drawer,Ge as DropZone,Ue as DropZoneReturnType,We as DropZoneStatus,Le as Dropdown,te as EmptyState,Ke as ErrorBoundary,qe as Fab,Je as Flip,ur as FormValidator,sr as FormValidatorGroup,Wt as HIT_PX,Gt as HIT_PX_COARSE,rn as IconPicker,an as IdleManager,Ce as Input,on as InputDropdown,xe as InputIconPosition,Se as InputType,z as InteractableDiv,cn as KanbanBoard,sn as KanbanColumn,un as KlipyPicker,l as Loader,c as LoaderType,dn as LoadingOverlay,bt as MIN_FLOOR_HEIGHT,et as MIN_OPENING_WIDTH,tt as MIN_WALL_LENGTH,fn as Menu,Ee as Modal,mn as MultiSelect,hn as NumberInput,Xe as OpeningKind,ne as OptionPicker,_n as OtpInput,gn as OtpInputCharset,vn as Overscroll,$t as PLAN_FORMAT_VERSION,yn as Pagination,Ze as PlanIssueKind,Qe as PlanUnitSystem,K as Popover,B as PopoverAlign,V as PopoverPlacement,H as PopoverTrigger,a as Presentation,bn as ProgressBar,Sn as RadioGroup,xn as RadioGroupOrientation,Cn as Rating,wn as RevealLens,p as Ripple,Tn as RoomDrawer,En as RoomViewer,On as ScrollFade,Dn as ScrollFadeAxis,y as ScrollbarProvider,ln as SearchInput,An as SectionHeader,kn as SectionHeaderSize,Nn as Skeleton,jn as SkeletonAnimation,Mn as SkeletonVariant,Pn as Slider,Xt as SnapKind,Fn as SplitButton,Bn as Stepper,In as StepperCollapse,Ln as StepperLabelPlacement,Rn as StepperOrientation,zn as StepperStyleType,Vn as Sticky,Hn as Switch,Un as TabHeader,Wn as Textarea,o as ThemeColor,x as ThemeProvider,Xn as Tilt,Kn as TiltGroup,qn as TiltGroupContext,Zn as TimeInput,$n as Timeline,Qn as TimelineAlignment,er as Timer,be as Tooltip,rr as Tree,cr as ValidatableComponent,dr as Validators,tr as VirtualList,$e as WallType,ar as WeatherIcon,ir as WeatherType,or as Wizard,xt as addFloor,rt as addOpening,it as addRect,at as addWall,nn as buildPlanMesh,Vt as buildWallPaths,ot as cleanupPlan,Zt as clientToWorld,Lt as commitDerivation,X as dateToDay,Z as dateToTime,Q as dayTimeToDate,$ as dayToDate,b as defaultTheme,Yn as defaultTiltEasing,Ft as deriveFaces,Rt as derivePlan,st as detachWall,ct as dissolveNode,St as duplicateFloor,Ct as emptyFloor,wt as emptyFloorPlan,nr as flattenTree,Tt as floorBelow,Et as floorBounds,Dt as floorIndex,h as formatHotkey,Ot as getFloor,Pe as getLocale,pr as hasEightPasswordChars,mr as hasOnePasswordDigit,hr as hasOnePasswordLetter,Kt as hitTest,gr as isBic,_r as isDate,vr as isDay,yr as isEmail,br as isISODate,De as isMenuAction,Oe as isMenuHeading,ke as isMenuSeparator,xr as isNumber,Sr as isPassword,Cr as isURL,S as lightTheme,Fe as mapLocale,pn as menuHotkeys,lt as mergeNodes,kt as moveFloor,ut as moveNode,It as nodeDegrees,Ht as openingGeometry,en as planFromJson,tn as planToJson,zt as pruneUnmatchedRooms,At as removeFloor,dt as removeOpening,ft as removeWall,jt as renameFloor,Qt as resolveSnap,Bt as roomAtPoint,pt as scalePlan,qt as selectionsEqual,Mt as setFloor,Nt as setFloorHeight,Ie as setLocale,D as showToast,mt as splitWall,U as tabbablesIn,ht as transformPlan,Pt as updateFloor,gt as updateOpening,Me as useClipboard,T as useCoarsePointer,n as useComponentDefaults,fr as useFormValidator,lr as useFormValidatorGroup,m as useHotkeys,r as useLabels,w as useMediaQuery,G as useOverlay,i as usePresentationDefault,Te as useScrollEdges,E as useSwipeDismiss,Gn as useTheme,Jn as useTiltGroup,W as useVisualViewportSize,_t as validatePlan,Ut as wallCentrelineSpans,vt as wallLength,yt as weldShortWalls,Jt as worldTolerances};
|