@chassis-ui/react 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autocomplete.js +1 -1
- package/dist/chunks/{Menu-264aGoBR.js → Menu-BiE9CzNk.js} +2 -2
- package/dist/chunks/{Menu-264aGoBR.js.map → Menu-BiE9CzNk.js.map} +1 -1
- package/dist/chunks/{MenuToggle-DcPEh55c.js → MenuToggle-W-ZSHFwF.js} +2 -2
- package/dist/chunks/{MenuToggle-DcPEh55c.js.map → MenuToggle-W-ZSHFwF.js.map} +1 -1
- package/dist/chunks/{autocomplete-99usnvgh.js → autocomplete-Btcsjrh3.js} +2 -2
- package/dist/chunks/{autocomplete-99usnvgh.js.map → autocomplete-Btcsjrh3.js.map} +1 -1
- package/dist/chunks/{combobox-BQh3uJWB.js → combobox-DNqR4d3V.js} +2 -2
- package/dist/chunks/{combobox-BQh3uJWB.js.map → combobox-DNqR4d3V.js.map} +1 -1
- package/dist/chunks/{context-menu-8KIuH4cJ.js → context-menu-D3DNFN-P.js} +2 -2
- package/dist/chunks/{context-menu-8KIuH4cJ.js.map → context-menu-D3DNFN-P.js.map} +1 -1
- package/dist/chunks/{menu-DEu-Nbv8.js → menu-Bqlhottl.js} +2 -2
- package/dist/chunks/{menu-DEu-Nbv8.js.map → menu-Bqlhottl.js.map} +1 -1
- package/dist/chunks/{nav-overflow-DpX_lRYf.js → nav-overflow-GWARvoQZ.js} +2 -2
- package/dist/chunks/{nav-overflow-DpX_lRYf.js.map → nav-overflow-GWARvoQZ.js.map} +1 -1
- package/dist/chunks/overlayPlacement-Q6bcbXA5.js.map +1 -1
- package/dist/chunks/useOverlayMaxHeight-DTgbr4UQ.js +2 -0
- package/dist/chunks/useOverlayMaxHeight-DTgbr4UQ.js.map +1 -0
- package/dist/combobox.js +1 -1
- package/dist/context-menu.js +1 -1
- package/dist/index.js +1 -1
- package/dist/menu.js +1 -1
- package/dist/nav-overflow.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/useOverlayMaxHeight-8mQL2Q6d.js +0 -2
- package/dist/chunks/useOverlayMaxHeight-8mQL2Q6d.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-overflow-DpX_lRYf.js","names":["HIDDEN_CLASS","devWarning","createPolymorphicComponent","useIsomorphicLayoutEffect","useHydrated","IconSlot","NavOverflowContext","Menu","MenuList","MenuToggle","React","classNames","NavOverflowMoreContext","createContext","lastShownStop","shown","item","stop","NavOverflowMore","state","useContext","visible","setVisible","useState","itemRef","useRef","focusWithinRef","hidden","empty","active","handleFocus","tabs","event","handleBlur","useSyncExternalStore","subscribeToNothing","zero","icon","ICON_STYLE","moreIcon","text","moreText","HIDDEN_CLASS$1","menuContainer","menuPlacement","moreLabel","iconPlacement","link","getLink","id","MenuItem","overflowingIds","movable","items","ids","overflowing","collapseAll","sum","gap","available","used","more","threshold","createRegistry","entries","listeners","version","entry","found","listener","next","value","HIDDEN_ATTRIBUTE","HIDDEN_CLASS","EMPTY","pixels","isHTMLElement","element","sameIds","a","b","index","resolveCollapseBelow","root","wrapper","width","UNMEASURED_STYLE","NavOverflowRender","rest","Component","component","wrapperRef","setWrapper","useCallback","forkedRef","useForkedRef","ref","hydrated","registry","setHidden","hiddenRef","itemCountRef","optionsRef","observersRef","measure","nav","child","children","elements","observe","wereHidden","moreWasHidden","wrapperStyle","navStyle","focused","collapseBelow","update","observers","disconnect","flush","flushSync","created","before","mutation","current","observed","resize","useEffect","reportedRef","onOverflow","registerItem","registerLink","controller","useMemo","className","style","NavOverflow"],"sources":["../../src/components/nav-overflow/more.tsx","../../src/components/nav-overflow/overflow.ts","../../src/components/nav-overflow/NavOverflow.tsx"],"sourcesContent":["import React, {\n createContext,\n CSSProperties,\n FocusEvent,\n ReactNode,\n useContext,\n useRef,\n useState,\n useSyncExternalStore\n} from 'react'\nimport classNames from 'classnames'\n\nimport { useIsomorphicLayoutEffect } from '../../hooks'\nimport { IconValue } from '../../utils/iconConfig'\nimport { IconSlot } from '../icon/iconSlot'\nimport { NavOverflowLinkProps, NavOverflowMoreProps } from '../../utils/navOverflow'\nimport { Placement } from '../../utils/overlayPlacement'\nimport { Menu } from '../menu/Menu'\nimport { MenuItem } from '../menu/MenuItem'\nimport { MenuList } from '../menu/MenuList'\nimport { MenuToggle } from '../menu/MenuToggle'\n\n// From `NavOverflow` to the toggle item, which a list renders for it: the items in the menu, the\n// props their links registered, and how the toggle looks.\nexport interface NavOverflowMoreState {\n getLink: (id: string) => NavOverflowLinkProps | null\n getVersion: () => number\n hidden: readonly string[]\n iconPlacement: 'start' | 'end'\n menuContainer: boolean | Element | undefined\n menuPlacement: Placement\n moreIcon: IconValue | undefined\n moreLabel: string\n moreText: ReactNode | false\n subscribe: (listener: () => void) => () => void\n}\n\nexport const NavOverflowMoreContext = createContext<NavOverflowMoreState | null>(null)\n\n// The nearest item before `item` that is shown and can take focus: its link, or its tab.\nfunction lastShownStop(item: HTMLElement): HTMLElement | null {\n for (let shown = item.previousElementSibling; shown; shown = shown.previousElementSibling) {\n if (shown.hasAttribute('data-cx-nav-overflow')) continue\n const stop = shown.querySelector<HTMLElement>('a[href], button:not(:disabled), [tabindex]')\n if (stop) return stop\n }\n return null\n}\n\n// chassis-css's markup (`nav-overflow.js`): a `.nav-item.nav-overflow-item` holding the\n// `.nav-link.nav-overflow-toggle` button and the `.menu.nav-overflow-menu`. It is in the list at\n// all times, hidden while every item fits, so its width can be measured before it is needed.\nexport function NavOverflowMore({ tabs }: NavOverflowMoreProps) {\n const state = useContext(NavOverflowMoreContext)\n const [visible, setVisible] = useState(false)\n const itemRef = useRef<HTMLLIElement>(null)\n const focusWithinRef = useRef(false)\n const hidden = state?.hidden\n const empty = !hidden?.length\n\n // A resize can take away what has focus here: the toggle, when the last item leaves the menu,\n // or a menu item, when its item is back in the list. Neither blurs first, and focus would fall\n // to the page. It goes to the toggle while there is one, and to the last item otherwise.\n useIsomorphicLayoutEffect(() => {\n const item = itemRef.current\n if (!item || !focusWithinRef.current) return\n const active = item.ownerDocument.activeElement\n const lost = !active || active === item.ownerDocument.body || (empty && item.contains(active))\n if (!lost) return\n focusWithinRef.current = !empty\n const stop = empty\n ? lastShownStop(item)\n : item.querySelector<HTMLElement>('.nav-overflow-toggle')\n stop?.focus()\n }, [hidden, empty])\n\n const handleFocus = (event: FocusEvent) => {\n focusWithinRef.current = true\n // react-aria's tab list takes focus back to the selected tab when focus enters the list from\n // outside, which a click on the toggle does. The toggle is reached with the arrow keys, from\n // a tab (`TabList`), so the list doesn't need to hear of its focus.\n if (tabs) event.stopPropagation()\n }\n const handleBlur = () => {\n focusWithinRef.current = false\n }\n // A hidden item's link re-registers its props on each of its renders.\n useSyncExternalStore(\n state?.subscribe ?? subscribeToNothing,\n state?.getVersion ?? zero,\n state?.getVersion ?? zero\n )\n\n if (!state || !hidden) return null\n\n const { getLink, iconPlacement, menuContainer, menuPlacement, moreIcon, moreLabel, moreText } =\n state\n // The toggle goes when the last item leaves the menu, and an open menu with it.\n if (empty && visible) setVisible(false)\n\n // Keyed, so `iconPlacement` moves the two spans instead of turning one into the other.\n const icon = (\n <span key=\"icon\" className=\"nav-overflow-icon\" style={ICON_STYLE}>\n <IconSlot icon=\"more\" override={moreIcon} />\n </span>\n )\n const text =\n moreText === false ? null : (\n <span key=\"text\" className=\"nav-overflow-text\">\n {moreText}\n </span>\n )\n\n return (\n <Menu\n component=\"li\"\n className={classNames('nav-item nav-overflow-item', { [HIDDEN_CLASS]: empty })}\n // A `tablist` owns tabs only. The toggle is one of them, and the menu is rendered outside.\n // (No `instanceof Element`: a server has no `Element`.)\n container={tabs ? (typeof menuContainer === 'object' ? menuContainer : true) : menuContainer}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onVisibleChange={setVisible}\n placement={menuPlacement}\n visible={visible && !empty}\n {...(tabs && { role: 'presentation' })}\n ref={itemRef}\n >\n <MenuToggle\n aria-label={moreText === false ? moreLabel : undefined}\n caret={false}\n className=\"nav-link nav-overflow-toggle\"\n component=\"button\"\n {...(tabs && { 'aria-selected': false, role: 'tab', tabIndex: -1 })}\n >\n {iconPlacement === 'end' ? [text, icon] : [icon, text]}\n </MenuToggle>\n <MenuList className=\"nav-overflow-menu\">\n {hidden.map((id) => {\n const link = getLink(id)\n return link && <MenuItem key={id} {...link} />\n })}\n </MenuList>\n </Menu>\n )\n}\n\nconst HIDDEN_CLASS = 'd-none'\n// The icon as chassis-css's plugin draws its own: in the color of the toggle's text, and 1rem\n// wide. The default icon size is taller than a link's text, and would make the list a little\n// taller each time the toggle appeared.\nconst ICON_STYLE = { '--cx-icon-color': 'currentcolor', '--cx-icon-size': '1rem' } as CSSProperties\nconst subscribeToNothing = () => () => {}\nconst zero = () => 0\n","// Which items go into the menu, from widths `NavOverflow` has read with every item shown.\n\nexport interface MeasuredItem {\n /**\n * Unset for an item that registered nothing, which can't be moved.\n */\n id?: string\n /**\n * Stays in the list whatever the width: marked to keep, active, focused, or with no link for\n * the menu to show.\n */\n keep: boolean\n width: number\n}\n\nexport interface Measurement {\n /**\n * The width the items have to fit in.\n */\n available: number\n /**\n * The wrapper is narrower than `collapseBelow`.\n */\n collapseAll: boolean\n gap: number\n /**\n * In document order, without the toggle item.\n */\n items: MeasuredItem[]\n /**\n * The width of the toggle item.\n */\n more: number\n /**\n * The fewest items to leave in the list.\n */\n threshold: number\n}\n\n// A pixel of slack for sub-pixel layout: `offsetWidth` is rounded.\nconst SLACK = 1\n\nexport function overflowingIds({\n available,\n collapseAll,\n gap,\n items,\n more,\n threshold\n}: Measurement): string[] {\n const movable = items.filter((item) => !item.keep)\n const ids = (overflowing: MeasuredItem[]) => overflowing.map((item) => item.id as string)\n\n if (collapseAll) return ids(movable)\n\n // Everything fits without the toggle, which then isn't shown. chassis-css's plugin always\n // reserves the toggle's width, and so moves the last item of a list that fits exactly.\n const total = items.reduce((sum, item) => sum + item.width, 0) + gap * (items.length - 1)\n if (total <= available + SLACK) return []\n\n // The toggle and the kept items are shown whatever happens, each with the gap to the next.\n let used = more + items.reduce((sum, item) => (item.keep ? sum + item.width + gap : sum), 0)\n let overflowing = movable.filter((item) => {\n used += item.width + gap\n return used > available + SLACK\n })\n\n // Fewer than `threshold` would be left: the first `threshold` stay whatever the width. A list\n // that has no more than that keeps every item, as `slice` leaves none to move.\n if (items.length - overflowing.length < threshold) {\n overflowing = items.slice(threshold).filter((item) => !item.keep)\n }\n\n return ids(overflowing)\n}\n","import React, {\n CSSProperties,\n ElementType,\n ForwardRefRenderFunction,\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react'\nimport { flushSync } from 'react-dom'\nimport classNames from 'classnames'\n\nimport { useForkedRef, useIsomorphicLayoutEffect } from '../../hooks'\nimport { Breakpoint } from '../../types'\nimport { devWarning } from '../../utils/devWarning'\nimport { IconValue } from '../../utils/iconConfig'\nimport {\n NavOverflowContext,\n NavOverflowController,\n NavOverflowLinkProps\n} from '../../utils/navOverflow'\nimport { Placement } from '../../utils/overlayPlacement'\nimport {\n createPolymorphicComponent,\n PolymorphicComponentProps,\n PolymorphicRef\n} from '../../utils/polymorphic'\nimport { useHydrated } from '../../hooks/useHydrated'\nimport { NavOverflowMore, NavOverflowMoreContext, NavOverflowMoreState } from './more'\nimport { MeasuredItem, overflowingIds } from './overflow'\n\nexport interface NavOverflowDetail {\n /**\n * How many items are in the menu.\n */\n overflowCount: number\n /**\n * How many items are left in the list.\n */\n visibleCount: number\n}\n\ntype NavOverflowOwnProps<C extends ElementType> = {\n /**\n * The list to collapse: a `Nav`, a `NavbarNav` or a `TabList`.\n */\n children?: ReactNode\n /**\n * A string of all className you want applied to the component.\n */\n className?: string\n /**\n * Moves every item into the menu while the component is narrower than this: a width in pixels,\n * or the name of a breakpoint, read from `--cx-breakpoint-{name}`.\n */\n collapseBelow?: number | Breakpoint\n /**\n * Component used for the root node. Either a string to use an HTML element or a component.\n *\n * @default 'div'\n */\n component?: C\n /**\n * Which side of the toggle's text its icon is on.\n *\n * @default 'start'\n */\n iconPlacement?: 'start' | 'end'\n /**\n * Renders the menu in a container element instead of inside the toggle's item, where an\n * ancestor with `overflow` set would clip it: an element, or `true` for `document.body`. The\n * menu of a `TabList` is always rendered outside it.\n */\n menuContainer?: boolean | Element\n /**\n * Where the menu opens, relative to the toggle. It flips to stay in view.\n *\n * @default 'bottom-end'\n * @type 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'\n */\n menuPlacement?: Placement\n /**\n * The toggle's icon: an icon name, or an element of your own icon set. Defaults to\n * `IconProvider`'s `more` icon.\n */\n moreIcon?: IconValue\n /**\n * The accessible name of a toggle without text (`moreText={false}`).\n *\n * @default 'More'\n */\n moreLabel?: string\n /**\n * The toggle's text. `false` leaves the icon alone, named by `moreLabel`.\n *\n * @default 'More'\n */\n moreText?: ReactNode | false\n /**\n * Callback fired when items move into the menu or back out of it, with the number of items in\n * the menu and in the list.\n */\n onOverflow?: (detail: NavOverflowDetail) => void\n /**\n * The fewest items to leave in the list. They stay even when they don't fit.\n *\n * @default 0\n */\n threshold?: number\n}\n\nexport type NavOverflowProps<C extends ElementType = 'div'> = PolymorphicComponentProps<\n C,\n NavOverflowOwnProps<C>\n>\n\ntype NavOverflowComponent = (<C extends ElementType = 'div'>(\n props: NavOverflowProps<C> & { ref?: PolymorphicRef<C> }\n) => ReactElement | null) & { displayName?: string }\n\ninterface Entry {\n element: HTMLElement | null\n link: NavOverflowLinkProps | null\n}\n\ninterface Observers {\n frame: number\n mutation: MutationObserver | null\n nav: Element | null\n observed: Set<Element>\n resize: ResizeObserver | null\n wrapper: HTMLElement\n wrapperFrame: number\n}\n\n// What the items and links registered, and the listeners of the menu that renders from it. Kept\n// outside React state: a link registers new props on every one of its renders.\nfunction createRegistry() {\n const entries = new Map<string, Entry>()\n const listeners = new Set<() => void>()\n let version = 0\n\n const entry = (id: string) => {\n let found = entries.get(id)\n if (!found) {\n found = { element: null, link: null }\n entries.set(id, found)\n }\n return found\n }\n\n return {\n entries,\n getVersion: () => version,\n notify: () => {\n version += 1\n listeners.forEach((listener) => listener())\n },\n set: (id: string, value: Partial<Entry>) => {\n const next = Object.assign(entry(id), value)\n if (!next.element && !next.link) entries.delete(id)\n },\n subscribe: (listener: () => void) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n }\n }\n}\n\n// chassis-css hides an item with this attribute (`_nav-overflow.scss`) and the toggle item with\n// the display utility, as its plugin does.\nconst HIDDEN_ATTRIBUTE = 'data-cx-nav-overflow'\nconst HIDDEN_CLASS = 'd-none'\n\n// What keeps an item in the list by being inside it: the current link, and the tab that is the\n// list's Tab stop. react-aria gives that to the tab focused last, which needn't be the selected\n// one: hidden, it would leave the keyboard no way into the list.\nconst KEPT_CONTENT =\n '.nav-link.active, .nav-link[aria-current]:not([aria-current=\"false\"]), [role=\"tab\"][tabindex=\"0\"]'\n\nconst EMPTY: readonly string[] = []\n\nconst pixels = (value: string) => Number.parseFloat(value) || 0\n\n// Not `instanceof HTMLElement`: a list rendered into another window has that window's classes.\nconst isHTMLElement = (element: Element): element is HTMLElement => 'offsetWidth' in element\n\nconst sameIds = (a: readonly string[], b: readonly string[]) =>\n a.length === b.length && a.every((id, index) => id === b[index])\n\n// `collapseBelow` in pixels. A breakpoint is a custom property of chassis-css, in `rem`.\nfunction resolveCollapseBelow(value: number | Breakpoint | undefined, wrapper: HTMLElement) {\n if (typeof value === 'number') return value\n if (!value) return 0\n const root = getComputedStyle(wrapper.ownerDocument.documentElement)\n const width = root.getPropertyValue(`--cx-breakpoint-${value}`).trim()\n return /r?em$/.test(width) ? pixels(width) * (pixels(root.fontSize) || 16) : pixels(width)\n}\n\n// Until the page has hydrated nothing has been measured, and the server's HTML holds every item\n// on one line (`.nav-overflow > .nav` doesn't wrap). The items that don't fit are clipped at the\n// wrapper's edge and can be scrolled to, instead of running over what is next to the list.\nconst UNMEASURED_STYLE: CSSProperties = { overflowX: 'auto', scrollbarWidth: 'none' }\n\nfunction NavOverflowRender<C extends ElementType = 'div'>(\n {\n children,\n className,\n collapseBelow,\n component,\n iconPlacement = 'start',\n menuContainer,\n menuPlacement = 'bottom-end',\n moreIcon,\n moreLabel = 'More',\n moreText = 'More',\n onOverflow,\n style,\n threshold = 0,\n ...rest\n }: NavOverflowProps<C>,\n ref: PolymorphicRef<C>\n) {\n const Component = component ?? 'div'\n // The wrapper, kept while React re-attaches a ref: a caller's ref that is a new function on\n // each render makes it detach and attach this one too, and in between, where the list's\n // effects run, there would be nothing to measure.\n const wrapperRef = useRef<HTMLElement | null>(null)\n const setWrapper = useCallback((element: HTMLElement | null) => {\n if (element) wrapperRef.current = element\n }, [])\n const forkedRef = useForkedRef(ref, setWrapper)\n const hydrated = useHydrated()\n\n const [registry] = useState(createRegistry)\n const [hidden, setHidden] = useState(EMPTY)\n const hiddenRef = useRef(hidden)\n const itemCountRef = useRef(0)\n const optionsRef = useRef({ collapseBelow, threshold })\n optionsRef.current = { collapseBelow, threshold }\n\n const observersRef = useRef<Observers | null>(null)\n\n // Which items don't fit, or `null` when there is nothing to measure.\n //\n // Widths are read with every item and the toggle shown, so they never depend on what the last\n // pass hid. Showing and hiding again happens in one synchronous block, outside React: the browser\n // paints neither, and the elements are back as React rendered them before it looks again.\n const measure = useCallback((): string[] | null => {\n const wrapper = wrapperRef.current?.isConnected ? wrapperRef.current : null\n const nav = wrapper && Array.from(wrapper.children).find((child) => child.matches('.nav'))\n devWarning(\n !!wrapper && !nav,\n 'NavOverflow: expects a `Nav`, a `NavbarNav` or a `TabList` as its child; found no `.nav` ' +\n 'to collapse.'\n )\n if (!wrapper || !nav) return null\n\n // Every child of the list takes room in the row, a title or a divider too; only registered\n // items can leave it.\n const children = Array.from(nav.children).filter(isHTMLElement)\n const more = children.find((child) => child.classList.contains('nav-overflow-item'))\n const elements = children.filter((child) => child !== more)\n observe(wrapper, nav, children)\n itemCountRef.current = elements.length\n // No toggle: the list is not one that takes part, so nothing can move.\n if (!more) return []\n\n const ids = new Map<Element, string>()\n registry.entries.forEach((entry, id) => {\n if (entry.element) ids.set(entry.element, id)\n })\n\n const wereHidden = elements.filter((element) => element.hasAttribute(HIDDEN_ATTRIBUTE))\n const moreWasHidden = more.classList.contains(HIDDEN_CLASS)\n wereHidden.forEach((element) => element.removeAttribute(HIDDEN_ATTRIBUTE))\n more.classList.remove(HIDDEN_CLASS)\n\n try {\n const wrapperStyle = getComputedStyle(wrapper)\n const navStyle = getComputedStyle(nav)\n // The wrapper's content box, as chassis-css's plugin takes it.\n const width =\n wrapper.clientWidth -\n pixels(wrapperStyle.paddingInlineStart) -\n pixels(wrapperStyle.paddingInlineEnd)\n const focused = wrapper.ownerDocument.activeElement\n\n const items = elements.map((element): MeasuredItem => {\n const id = ids.get(element)\n return {\n id,\n // An item stays in the list when the menu has nothing to show for it, when it is\n // marked to stay, when it is the current one or the list's Tab stop, and while it has\n // focus, which hiding it would drop.\n keep:\n !id ||\n !registry.entries.get(id)?.link ||\n element.classList.contains('nav-overflow-keep') ||\n element.querySelector(KEPT_CONTENT) !== null ||\n element.contains(focused),\n width: element.offsetWidth\n }\n })\n\n const { collapseBelow, threshold } = optionsRef.current\n return overflowingIds({\n available:\n width -\n pixels(navStyle.paddingInlineStart) -\n pixels(navStyle.paddingInlineEnd) -\n pixels(navStyle.borderInlineStartWidth) -\n pixels(navStyle.borderInlineEndWidth),\n collapseAll: width < resolveCollapseBelow(collapseBelow, wrapper),\n gap: pixels(navStyle.columnGap),\n items,\n more: more.offsetWidth,\n threshold\n })\n } finally {\n wereHidden.forEach((element) => element.setAttribute(HIDDEN_ATTRIBUTE, 'true'))\n if (moreWasHidden) more.classList.add(HIDDEN_CLASS)\n // Lay the list out as it was. Without this the layout stays as measured, with everything\n // shown, until the browser next needs it, and a ResizeObserver delivering in the meantime\n // (react-aria's, on the toggle) is told of sizes that were never painted.\n void wrapper.offsetWidth\n // The mutations above are this function's own.\n observersRef.current?.mutation?.takeRecords()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [registry])\n\n const update = useCallback(() => {\n const next = measure()\n if (!next || sameIds(next, hiddenRef.current)) return\n hiddenRef.current = next\n setHidden(next)\n }, [measure])\n\n // What changes the result without a render of the list:\n //\n // - The wrapper's width. The wrapper and not the list, whose width the result itself changes.\n // - An item's width: a font that loads, a label that changes.\n // - A link that becomes the current one by itself, as a router's link does on navigation.\n //\n // An observer's callback runs before the browser paints, and `flushSync` commits the result\n // there, so no frame shows the items of the old width.\n //\n // A ResizeObserver delivers sizes top down, and reports a loop error when a callback changes\n // a size it has already passed. Two things here would: hiding an item's siblings from the\n // callback for that item, so an item's own resize waits a frame; and a toggle taller than the\n // links, which changes the wrapper's height from the wrapper's own callback, so the wrapper is\n // observed again from the next frame once a pass has moved anything.\n function observe(wrapper: HTMLElement, nav: Element, children: HTMLElement[]) {\n let observers = observersRef.current\n if (observers && observers.wrapper !== wrapper) {\n disconnect()\n observers = null\n }\n if (!observers) {\n const flush = () => flushSync(update)\n const created: Observers = {\n frame: 0,\n mutation: typeof MutationObserver === 'undefined' ? null : new MutationObserver(flush),\n nav: null,\n observed: new Set(),\n resize:\n typeof ResizeObserver === 'undefined'\n ? null\n : new ResizeObserver((entries) => {\n if (!entries.some((entry) => entry.target === wrapper)) {\n cancelAnimationFrame(created.frame)\n created.frame = requestAnimationFrame(flush)\n return\n }\n const before = hiddenRef.current\n flush()\n // The pass can have replaced these observers, for a wrapper that is a new element.\n if (hiddenRef.current === before || observersRef.current !== created) return\n created.resize?.unobserve(wrapper)\n cancelAnimationFrame(created.wrapperFrame)\n created.wrapperFrame = requestAnimationFrame(() => created.resize?.observe(wrapper))\n }),\n wrapperFrame: 0,\n wrapper\n }\n observers = observersRef.current = created\n observers.resize?.observe(wrapper)\n }\n const { mutation, observed, resize } = observers\n\n if (observers.nav !== nav) {\n observers.nav = nav\n mutation?.disconnect()\n mutation?.observe(nav, {\n attributeFilter: ['class', 'aria-current'],\n attributes: true,\n childList: true,\n subtree: true\n })\n }\n\n const current = new Set<Element>(children)\n observed.forEach((element) => {\n if (current.has(element)) return\n resize?.unobserve(element)\n observed.delete(element)\n })\n current.forEach((element) => {\n if (observed.has(element)) return\n resize?.observe(element)\n observed.add(element)\n })\n }\n\n function disconnect() {\n const observers = observersRef.current\n if (!observers) return\n cancelAnimationFrame(observers.frame)\n cancelAnimationFrame(observers.wrapperFrame)\n observers.mutation?.disconnect()\n observers.resize?.disconnect()\n observersRef.current = null\n }\n\n useEffect(() => disconnect, [])\n\n // The list measures after each of its commits (`NavOverflowItems`). This covers what it can't:\n // the first commit and a wrapper that becomes another element, where React attaches the\n // wrapper's ref after the list's effects have run, and the options, which can change without\n // the list rendering.\n useIsomorphicLayoutEffect(update, [update, Component, collapseBelow, threshold])\n\n const reportedRef = useRef(hidden)\n useEffect(() => {\n if (reportedRef.current === hidden) return\n reportedRef.current = hidden\n onOverflow?.({\n overflowCount: hidden.length,\n visibleCount: itemCountRef.current - hidden.length\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hidden])\n\n const registerItem = useCallback(\n (id: string, element: HTMLElement | null) => registry.set(id, { element }),\n [registry]\n )\n const registerLink = useCallback(\n (id: string, link: NavOverflowLinkProps | null) => {\n registry.set(id, { link })\n // The menu renders from these props, and only it needs to hear of new ones.\n if (hiddenRef.current.includes(id)) registry.notify()\n },\n [registry]\n )\n\n const controller: NavOverflowController = useMemo(\n () => ({ hidden, More: NavOverflowMore, registerItem, registerLink, update }),\n [hidden, registerItem, registerLink, update]\n )\n\n const more: NavOverflowMoreState = useMemo(\n () => ({\n getLink: (id) => registry.entries.get(id)?.link ?? null,\n getVersion: registry.getVersion,\n hidden,\n iconPlacement,\n menuContainer,\n menuPlacement,\n moreIcon,\n moreLabel,\n moreText,\n subscribe: registry.subscribe\n }),\n [hidden, iconPlacement, menuContainer, menuPlacement, moreIcon, moreLabel, moreText, registry]\n )\n\n return (\n <NavOverflowContext.Provider value={controller}>\n <NavOverflowMoreContext.Provider value={more}>\n <Component\n className={classNames('nav-overflow', className)}\n style={hydrated ? style : { ...UNMEASURED_STYLE, ...style }}\n {...rest}\n ref={forkedRef}\n >\n {children}\n </Component>\n </NavOverflowMoreContext.Provider>\n </NavOverflowContext.Provider>\n )\n}\n\nexport const NavOverflow = createPolymorphicComponent<NavOverflowComponent>(\n NavOverflowRender as ForwardRefRenderFunction<Element, NavOverflowProps<ElementType>>,\n 'NavOverflow'\n)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nav-overflow-GWARvoQZ.js","names":["HIDDEN_CLASS","devWarning","createPolymorphicComponent","useIsomorphicLayoutEffect","useHydrated","IconSlot","NavOverflowContext","Menu","MenuList","MenuToggle","React","classNames","NavOverflowMoreContext","createContext","lastShownStop","shown","item","stop","NavOverflowMore","state","useContext","visible","setVisible","useState","itemRef","useRef","focusWithinRef","hidden","empty","active","handleFocus","tabs","event","handleBlur","useSyncExternalStore","subscribeToNothing","zero","icon","ICON_STYLE","moreIcon","text","moreText","HIDDEN_CLASS$1","menuContainer","menuPlacement","moreLabel","iconPlacement","link","getLink","id","MenuItem","overflowingIds","movable","items","ids","overflowing","collapseAll","sum","gap","available","used","more","threshold","createRegistry","entries","listeners","version","entry","found","listener","next","value","HIDDEN_ATTRIBUTE","HIDDEN_CLASS","EMPTY","pixels","isHTMLElement","element","sameIds","a","b","index","resolveCollapseBelow","root","wrapper","width","UNMEASURED_STYLE","NavOverflowRender","rest","Component","component","wrapperRef","setWrapper","useCallback","forkedRef","useForkedRef","ref","hydrated","registry","setHidden","hiddenRef","itemCountRef","optionsRef","observersRef","measure","nav","child","children","elements","observe","wereHidden","moreWasHidden","wrapperStyle","navStyle","focused","collapseBelow","update","observers","disconnect","flush","flushSync","created","before","mutation","current","observed","resize","useEffect","reportedRef","onOverflow","registerItem","registerLink","controller","useMemo","className","style","NavOverflow"],"sources":["../../src/components/nav-overflow/more.tsx","../../src/components/nav-overflow/overflow.ts","../../src/components/nav-overflow/NavOverflow.tsx"],"sourcesContent":["import React, {\n createContext,\n CSSProperties,\n FocusEvent,\n ReactNode,\n useContext,\n useRef,\n useState,\n useSyncExternalStore\n} from 'react'\nimport classNames from 'classnames'\n\nimport { useIsomorphicLayoutEffect } from '../../hooks'\nimport { IconValue } from '../../utils/iconConfig'\nimport { IconSlot } from '../icon/iconSlot'\nimport { NavOverflowLinkProps, NavOverflowMoreProps } from '../../utils/navOverflow'\nimport { Placement } from '../../utils/overlayPlacement'\nimport { Menu } from '../menu/Menu'\nimport { MenuItem } from '../menu/MenuItem'\nimport { MenuList } from '../menu/MenuList'\nimport { MenuToggle } from '../menu/MenuToggle'\n\n// From `NavOverflow` to the toggle item, which a list renders for it: the items in the menu, the\n// props their links registered, and how the toggle looks.\nexport interface NavOverflowMoreState {\n getLink: (id: string) => NavOverflowLinkProps | null\n getVersion: () => number\n hidden: readonly string[]\n iconPlacement: 'start' | 'end'\n menuContainer: boolean | Element | undefined\n menuPlacement: Placement\n moreIcon: IconValue | undefined\n moreLabel: string\n moreText: ReactNode | false\n subscribe: (listener: () => void) => () => void\n}\n\nexport const NavOverflowMoreContext = createContext<NavOverflowMoreState | null>(null)\n\n// The nearest item before `item` that is shown and can take focus: its link, or its tab.\nfunction lastShownStop(item: HTMLElement): HTMLElement | null {\n for (let shown = item.previousElementSibling; shown; shown = shown.previousElementSibling) {\n if (shown.hasAttribute('data-cx-nav-overflow')) continue\n const stop = shown.querySelector<HTMLElement>('a[href], button:not(:disabled), [tabindex]')\n if (stop) return stop\n }\n return null\n}\n\n// chassis-css's markup (`nav-overflow.js`): a `.nav-item.nav-overflow-item` holding the\n// `.nav-link.nav-overflow-toggle` button and the `.menu.nav-overflow-menu`. It is in the list at\n// all times, hidden while every item fits, so its width can be measured before it is needed.\nexport function NavOverflowMore({ tabs }: NavOverflowMoreProps) {\n const state = useContext(NavOverflowMoreContext)\n const [visible, setVisible] = useState(false)\n const itemRef = useRef<HTMLLIElement>(null)\n const focusWithinRef = useRef(false)\n const hidden = state?.hidden\n const empty = !hidden?.length\n\n // A resize can take away what has focus here: the toggle, when the last item leaves the menu,\n // or a menu item, when its item is back in the list. Neither blurs first, and focus would fall\n // to the page. It goes to the toggle while there is one, and to the last item otherwise.\n useIsomorphicLayoutEffect(() => {\n const item = itemRef.current\n if (!item || !focusWithinRef.current) return\n const active = item.ownerDocument.activeElement\n const lost = !active || active === item.ownerDocument.body || (empty && item.contains(active))\n if (!lost) return\n focusWithinRef.current = !empty\n const stop = empty\n ? lastShownStop(item)\n : item.querySelector<HTMLElement>('.nav-overflow-toggle')\n stop?.focus()\n }, [hidden, empty])\n\n const handleFocus = (event: FocusEvent) => {\n focusWithinRef.current = true\n // react-aria's tab list takes focus back to the selected tab when focus enters the list from\n // outside, which a click on the toggle does. The toggle is reached with the arrow keys, from\n // a tab (`TabList`), so the list doesn't need to hear of its focus.\n if (tabs) event.stopPropagation()\n }\n const handleBlur = () => {\n focusWithinRef.current = false\n }\n // A hidden item's link re-registers its props on each of its renders.\n useSyncExternalStore(\n state?.subscribe ?? subscribeToNothing,\n state?.getVersion ?? zero,\n state?.getVersion ?? zero\n )\n\n if (!state || !hidden) return null\n\n const { getLink, iconPlacement, menuContainer, menuPlacement, moreIcon, moreLabel, moreText } =\n state\n // The toggle goes when the last item leaves the menu, and an open menu with it.\n if (empty && visible) setVisible(false)\n\n // Keyed, so `iconPlacement` moves the two spans instead of turning one into the other.\n const icon = (\n <span key=\"icon\" className=\"nav-overflow-icon\" style={ICON_STYLE}>\n <IconSlot icon=\"more\" override={moreIcon} />\n </span>\n )\n const text =\n moreText === false ? null : (\n <span key=\"text\" className=\"nav-overflow-text\">\n {moreText}\n </span>\n )\n\n return (\n <Menu\n component=\"li\"\n className={classNames('nav-item nav-overflow-item', { [HIDDEN_CLASS]: empty })}\n // A `tablist` owns tabs only. The toggle is one of them, and the menu is rendered outside.\n // (No `instanceof Element`: a server has no `Element`.)\n container={tabs ? (typeof menuContainer === 'object' ? menuContainer : true) : menuContainer}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onVisibleChange={setVisible}\n placement={menuPlacement}\n visible={visible && !empty}\n {...(tabs && { role: 'presentation' })}\n ref={itemRef}\n >\n <MenuToggle\n aria-label={moreText === false ? moreLabel : undefined}\n caret={false}\n className=\"nav-link nav-overflow-toggle\"\n component=\"button\"\n {...(tabs && { 'aria-selected': false, role: 'tab', tabIndex: -1 })}\n >\n {iconPlacement === 'end' ? [text, icon] : [icon, text]}\n </MenuToggle>\n <MenuList className=\"nav-overflow-menu\">\n {hidden.map((id) => {\n const link = getLink(id)\n return link && <MenuItem key={id} {...link} />\n })}\n </MenuList>\n </Menu>\n )\n}\n\nconst HIDDEN_CLASS = 'd-none'\n// The icon as chassis-css's plugin draws its own: in the color of the toggle's text, and 1rem\n// wide. The default icon size is taller than a link's text, and would make the list a little\n// taller each time the toggle appeared.\nconst ICON_STYLE = { '--cx-icon-color': 'currentcolor', '--cx-icon-size': '1rem' } as CSSProperties\nconst subscribeToNothing = () => () => {}\nconst zero = () => 0\n","// Which items go into the menu, from widths `NavOverflow` has read with every item shown.\n\nexport interface MeasuredItem {\n /**\n * Unset for an item that registered nothing, which can't be moved.\n */\n id?: string\n /**\n * Stays in the list whatever the width: marked to keep, active, focused, or with no link for\n * the menu to show.\n */\n keep: boolean\n width: number\n}\n\nexport interface Measurement {\n /**\n * The width the items have to fit in.\n */\n available: number\n /**\n * The wrapper is narrower than `collapseBelow`.\n */\n collapseAll: boolean\n gap: number\n /**\n * In document order, without the toggle item.\n */\n items: MeasuredItem[]\n /**\n * The width of the toggle item.\n */\n more: number\n /**\n * The fewest items to leave in the list.\n */\n threshold: number\n}\n\n// A pixel of slack for sub-pixel layout: `offsetWidth` is rounded.\nconst SLACK = 1\n\nexport function overflowingIds({\n available,\n collapseAll,\n gap,\n items,\n more,\n threshold\n}: Measurement): string[] {\n const movable = items.filter((item) => !item.keep)\n const ids = (overflowing: MeasuredItem[]) => overflowing.map((item) => item.id as string)\n\n if (collapseAll) return ids(movable)\n\n // Everything fits without the toggle, which then isn't shown. chassis-css's plugin always\n // reserves the toggle's width, and so moves the last item of a list that fits exactly.\n const total = items.reduce((sum, item) => sum + item.width, 0) + gap * (items.length - 1)\n if (total <= available + SLACK) return []\n\n // The toggle and the kept items are shown whatever happens, each with the gap to the next.\n let used = more + items.reduce((sum, item) => (item.keep ? sum + item.width + gap : sum), 0)\n let overflowing = movable.filter((item) => {\n used += item.width + gap\n return used > available + SLACK\n })\n\n // Fewer than `threshold` would be left: the first `threshold` stay whatever the width. A list\n // that has no more than that keeps every item, as `slice` leaves none to move.\n if (items.length - overflowing.length < threshold) {\n overflowing = items.slice(threshold).filter((item) => !item.keep)\n }\n\n return ids(overflowing)\n}\n","import React, {\n CSSProperties,\n ElementType,\n ForwardRefRenderFunction,\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react'\nimport { flushSync } from 'react-dom'\nimport classNames from 'classnames'\n\nimport { useForkedRef, useIsomorphicLayoutEffect } from '../../hooks'\nimport { Breakpoint } from '../../types'\nimport { devWarning } from '../../utils/devWarning'\nimport { IconValue } from '../../utils/iconConfig'\nimport {\n NavOverflowContext,\n NavOverflowController,\n NavOverflowLinkProps\n} from '../../utils/navOverflow'\nimport { Placement } from '../../utils/overlayPlacement'\nimport {\n createPolymorphicComponent,\n PolymorphicComponentProps,\n PolymorphicRef\n} from '../../utils/polymorphic'\nimport { useHydrated } from '../../hooks/useHydrated'\nimport { NavOverflowMore, NavOverflowMoreContext, NavOverflowMoreState } from './more'\nimport { MeasuredItem, overflowingIds } from './overflow'\n\nexport interface NavOverflowDetail {\n /**\n * How many items are in the menu.\n */\n overflowCount: number\n /**\n * How many items are left in the list.\n */\n visibleCount: number\n}\n\ntype NavOverflowOwnProps<C extends ElementType> = {\n /**\n * The list to collapse: a `Nav`, a `NavbarNav` or a `TabList`.\n */\n children?: ReactNode\n /**\n * A string of all className you want applied to the component.\n */\n className?: string\n /**\n * Moves every item into the menu while the component is narrower than this: a width in pixels,\n * or the name of a breakpoint, read from `--cx-breakpoint-{name}`.\n */\n collapseBelow?: number | Breakpoint\n /**\n * Component used for the root node. Either a string to use an HTML element or a component.\n *\n * @default 'div'\n */\n component?: C\n /**\n * Which side of the toggle's text its icon is on.\n *\n * @default 'start'\n */\n iconPlacement?: 'start' | 'end'\n /**\n * Renders the menu in a container element instead of inside the toggle's item, where an\n * ancestor with `overflow` set would clip it: an element, or `true` for `document.body`. The\n * menu of a `TabList` is always rendered outside it.\n */\n menuContainer?: boolean | Element\n /**\n * Where the menu opens, relative to the toggle. It flips to stay in view.\n *\n * @default 'bottom-end'\n * @type 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'\n */\n menuPlacement?: Placement\n /**\n * The toggle's icon: an icon name, or an element of your own icon set. Defaults to\n * `IconProvider`'s `more` icon.\n */\n moreIcon?: IconValue\n /**\n * The accessible name of a toggle without text (`moreText={false}`).\n *\n * @default 'More'\n */\n moreLabel?: string\n /**\n * The toggle's text. `false` leaves the icon alone, named by `moreLabel`.\n *\n * @default 'More'\n */\n moreText?: ReactNode | false\n /**\n * Callback fired when items move into the menu or back out of it, with the number of items in\n * the menu and in the list.\n */\n onOverflow?: (detail: NavOverflowDetail) => void\n /**\n * The fewest items to leave in the list. They stay even when they don't fit.\n *\n * @default 0\n */\n threshold?: number\n}\n\nexport type NavOverflowProps<C extends ElementType = 'div'> = PolymorphicComponentProps<\n C,\n NavOverflowOwnProps<C>\n>\n\ntype NavOverflowComponent = (<C extends ElementType = 'div'>(\n props: NavOverflowProps<C> & { ref?: PolymorphicRef<C> }\n) => ReactElement | null) & { displayName?: string }\n\ninterface Entry {\n element: HTMLElement | null\n link: NavOverflowLinkProps | null\n}\n\ninterface Observers {\n frame: number\n mutation: MutationObserver | null\n nav: Element | null\n observed: Set<Element>\n resize: ResizeObserver | null\n wrapper: HTMLElement\n wrapperFrame: number\n}\n\n// What the items and links registered, and the listeners of the menu that renders from it. Kept\n// outside React state: a link registers new props on every one of its renders.\nfunction createRegistry() {\n const entries = new Map<string, Entry>()\n const listeners = new Set<() => void>()\n let version = 0\n\n const entry = (id: string) => {\n let found = entries.get(id)\n if (!found) {\n found = { element: null, link: null }\n entries.set(id, found)\n }\n return found\n }\n\n return {\n entries,\n getVersion: () => version,\n notify: () => {\n version += 1\n listeners.forEach((listener) => listener())\n },\n set: (id: string, value: Partial<Entry>) => {\n const next = Object.assign(entry(id), value)\n if (!next.element && !next.link) entries.delete(id)\n },\n subscribe: (listener: () => void) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n }\n }\n}\n\n// chassis-css hides an item with this attribute (`_nav-overflow.scss`) and the toggle item with\n// the display utility, as its plugin does.\nconst HIDDEN_ATTRIBUTE = 'data-cx-nav-overflow'\nconst HIDDEN_CLASS = 'd-none'\n\n// What keeps an item in the list by being inside it: the current link, and the tab that is the\n// list's Tab stop. react-aria gives that to the tab focused last, which needn't be the selected\n// one: hidden, it would leave the keyboard no way into the list.\nconst KEPT_CONTENT =\n '.nav-link.active, .nav-link[aria-current]:not([aria-current=\"false\"]), [role=\"tab\"][tabindex=\"0\"]'\n\nconst EMPTY: readonly string[] = []\n\nconst pixels = (value: string) => Number.parseFloat(value) || 0\n\n// Not `instanceof HTMLElement`: a list rendered into another window has that window's classes.\nconst isHTMLElement = (element: Element): element is HTMLElement => 'offsetWidth' in element\n\nconst sameIds = (a: readonly string[], b: readonly string[]) =>\n a.length === b.length && a.every((id, index) => id === b[index])\n\n// `collapseBelow` in pixels. A breakpoint is a custom property of chassis-css, in `rem`.\nfunction resolveCollapseBelow(value: number | Breakpoint | undefined, wrapper: HTMLElement) {\n if (typeof value === 'number') return value\n if (!value) return 0\n const root = getComputedStyle(wrapper.ownerDocument.documentElement)\n const width = root.getPropertyValue(`--cx-breakpoint-${value}`).trim()\n return /r?em$/.test(width) ? pixels(width) * (pixels(root.fontSize) || 16) : pixels(width)\n}\n\n// Until the page has hydrated nothing has been measured, and the server's HTML holds every item\n// on one line (`.nav-overflow > .nav` doesn't wrap). The items that don't fit are clipped at the\n// wrapper's edge and can be scrolled to, instead of running over what is next to the list.\nconst UNMEASURED_STYLE: CSSProperties = { overflowX: 'auto', scrollbarWidth: 'none' }\n\nfunction NavOverflowRender<C extends ElementType = 'div'>(\n {\n children,\n className,\n collapseBelow,\n component,\n iconPlacement = 'start',\n menuContainer,\n menuPlacement = 'bottom-end',\n moreIcon,\n moreLabel = 'More',\n moreText = 'More',\n onOverflow,\n style,\n threshold = 0,\n ...rest\n }: NavOverflowProps<C>,\n ref: PolymorphicRef<C>\n) {\n const Component = component ?? 'div'\n // The wrapper, kept while React re-attaches a ref: a caller's ref that is a new function on\n // each render makes it detach and attach this one too, and in between, where the list's\n // effects run, there would be nothing to measure.\n const wrapperRef = useRef<HTMLElement | null>(null)\n const setWrapper = useCallback((element: HTMLElement | null) => {\n if (element) wrapperRef.current = element\n }, [])\n const forkedRef = useForkedRef(ref, setWrapper)\n const hydrated = useHydrated()\n\n const [registry] = useState(createRegistry)\n const [hidden, setHidden] = useState(EMPTY)\n const hiddenRef = useRef(hidden)\n const itemCountRef = useRef(0)\n const optionsRef = useRef({ collapseBelow, threshold })\n optionsRef.current = { collapseBelow, threshold }\n\n const observersRef = useRef<Observers | null>(null)\n\n // Which items don't fit, or `null` when there is nothing to measure.\n //\n // Widths are read with every item and the toggle shown, so they never depend on what the last\n // pass hid. Showing and hiding again happens in one synchronous block, outside React: the browser\n // paints neither, and the elements are back as React rendered them before it looks again.\n const measure = useCallback((): string[] | null => {\n const wrapper = wrapperRef.current?.isConnected ? wrapperRef.current : null\n const nav = wrapper && Array.from(wrapper.children).find((child) => child.matches('.nav'))\n devWarning(\n !!wrapper && !nav,\n 'NavOverflow: expects a `Nav`, a `NavbarNav` or a `TabList` as its child; found no `.nav` ' +\n 'to collapse.'\n )\n if (!wrapper || !nav) return null\n\n // Every child of the list takes room in the row, a title or a divider too; only registered\n // items can leave it.\n const children = Array.from(nav.children).filter(isHTMLElement)\n const more = children.find((child) => child.classList.contains('nav-overflow-item'))\n const elements = children.filter((child) => child !== more)\n observe(wrapper, nav, children)\n itemCountRef.current = elements.length\n // No toggle: the list is not one that takes part, so nothing can move.\n if (!more) return []\n\n const ids = new Map<Element, string>()\n registry.entries.forEach((entry, id) => {\n if (entry.element) ids.set(entry.element, id)\n })\n\n const wereHidden = elements.filter((element) => element.hasAttribute(HIDDEN_ATTRIBUTE))\n const moreWasHidden = more.classList.contains(HIDDEN_CLASS)\n wereHidden.forEach((element) => element.removeAttribute(HIDDEN_ATTRIBUTE))\n more.classList.remove(HIDDEN_CLASS)\n\n try {\n const wrapperStyle = getComputedStyle(wrapper)\n const navStyle = getComputedStyle(nav)\n // The wrapper's content box, as chassis-css's plugin takes it.\n const width =\n wrapper.clientWidth -\n pixels(wrapperStyle.paddingInlineStart) -\n pixels(wrapperStyle.paddingInlineEnd)\n const focused = wrapper.ownerDocument.activeElement\n\n const items = elements.map((element): MeasuredItem => {\n const id = ids.get(element)\n return {\n id,\n // An item stays in the list when the menu has nothing to show for it, when it is\n // marked to stay, when it is the current one or the list's Tab stop, and while it has\n // focus, which hiding it would drop.\n keep:\n !id ||\n !registry.entries.get(id)?.link ||\n element.classList.contains('nav-overflow-keep') ||\n element.querySelector(KEPT_CONTENT) !== null ||\n element.contains(focused),\n width: element.offsetWidth\n }\n })\n\n const { collapseBelow, threshold } = optionsRef.current\n return overflowingIds({\n available:\n width -\n pixels(navStyle.paddingInlineStart) -\n pixels(navStyle.paddingInlineEnd) -\n pixels(navStyle.borderInlineStartWidth) -\n pixels(navStyle.borderInlineEndWidth),\n collapseAll: width < resolveCollapseBelow(collapseBelow, wrapper),\n gap: pixels(navStyle.columnGap),\n items,\n more: more.offsetWidth,\n threshold\n })\n } finally {\n wereHidden.forEach((element) => element.setAttribute(HIDDEN_ATTRIBUTE, 'true'))\n if (moreWasHidden) more.classList.add(HIDDEN_CLASS)\n // Lay the list out as it was. Without this the layout stays as measured, with everything\n // shown, until the browser next needs it, and a ResizeObserver delivering in the meantime\n // (react-aria's, on the toggle) is told of sizes that were never painted.\n void wrapper.offsetWidth\n // The mutations above are this function's own.\n observersRef.current?.mutation?.takeRecords()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [registry])\n\n const update = useCallback(() => {\n const next = measure()\n if (!next || sameIds(next, hiddenRef.current)) return\n hiddenRef.current = next\n setHidden(next)\n }, [measure])\n\n // What changes the result without a render of the list:\n //\n // - The wrapper's width. The wrapper and not the list, whose width the result itself changes.\n // - An item's width: a font that loads, a label that changes.\n // - A link that becomes the current one by itself, as a router's link does on navigation.\n //\n // An observer's callback runs before the browser paints, and `flushSync` commits the result\n // there, so no frame shows the items of the old width.\n //\n // A ResizeObserver delivers sizes top down, and reports a loop error when a callback changes\n // a size it has already passed. Two things here would: hiding an item's siblings from the\n // callback for that item, so an item's own resize waits a frame; and a toggle taller than the\n // links, which changes the wrapper's height from the wrapper's own callback, so the wrapper is\n // observed again from the next frame once a pass has moved anything.\n function observe(wrapper: HTMLElement, nav: Element, children: HTMLElement[]) {\n let observers = observersRef.current\n if (observers && observers.wrapper !== wrapper) {\n disconnect()\n observers = null\n }\n if (!observers) {\n const flush = () => flushSync(update)\n const created: Observers = {\n frame: 0,\n mutation: typeof MutationObserver === 'undefined' ? null : new MutationObserver(flush),\n nav: null,\n observed: new Set(),\n resize:\n typeof ResizeObserver === 'undefined'\n ? null\n : new ResizeObserver((entries) => {\n if (!entries.some((entry) => entry.target === wrapper)) {\n cancelAnimationFrame(created.frame)\n created.frame = requestAnimationFrame(flush)\n return\n }\n const before = hiddenRef.current\n flush()\n // The pass can have replaced these observers, for a wrapper that is a new element.\n if (hiddenRef.current === before || observersRef.current !== created) return\n created.resize?.unobserve(wrapper)\n cancelAnimationFrame(created.wrapperFrame)\n created.wrapperFrame = requestAnimationFrame(() => created.resize?.observe(wrapper))\n }),\n wrapperFrame: 0,\n wrapper\n }\n observers = observersRef.current = created\n observers.resize?.observe(wrapper)\n }\n const { mutation, observed, resize } = observers\n\n if (observers.nav !== nav) {\n observers.nav = nav\n mutation?.disconnect()\n mutation?.observe(nav, {\n attributeFilter: ['class', 'aria-current'],\n attributes: true,\n childList: true,\n subtree: true\n })\n }\n\n const current = new Set<Element>(children)\n observed.forEach((element) => {\n if (current.has(element)) return\n resize?.unobserve(element)\n observed.delete(element)\n })\n current.forEach((element) => {\n if (observed.has(element)) return\n resize?.observe(element)\n observed.add(element)\n })\n }\n\n function disconnect() {\n const observers = observersRef.current\n if (!observers) return\n cancelAnimationFrame(observers.frame)\n cancelAnimationFrame(observers.wrapperFrame)\n observers.mutation?.disconnect()\n observers.resize?.disconnect()\n observersRef.current = null\n }\n\n useEffect(() => disconnect, [])\n\n // The list measures after each of its commits (`NavOverflowItems`). This covers what it can't:\n // the first commit and a wrapper that becomes another element, where React attaches the\n // wrapper's ref after the list's effects have run, and the options, which can change without\n // the list rendering.\n useIsomorphicLayoutEffect(update, [update, Component, collapseBelow, threshold])\n\n const reportedRef = useRef(hidden)\n useEffect(() => {\n if (reportedRef.current === hidden) return\n reportedRef.current = hidden\n onOverflow?.({\n overflowCount: hidden.length,\n visibleCount: itemCountRef.current - hidden.length\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hidden])\n\n const registerItem = useCallback(\n (id: string, element: HTMLElement | null) => registry.set(id, { element }),\n [registry]\n )\n const registerLink = useCallback(\n (id: string, link: NavOverflowLinkProps | null) => {\n registry.set(id, { link })\n // The menu renders from these props, and only it needs to hear of new ones.\n if (hiddenRef.current.includes(id)) registry.notify()\n },\n [registry]\n )\n\n const controller: NavOverflowController = useMemo(\n () => ({ hidden, More: NavOverflowMore, registerItem, registerLink, update }),\n [hidden, registerItem, registerLink, update]\n )\n\n const more: NavOverflowMoreState = useMemo(\n () => ({\n getLink: (id) => registry.entries.get(id)?.link ?? null,\n getVersion: registry.getVersion,\n hidden,\n iconPlacement,\n menuContainer,\n menuPlacement,\n moreIcon,\n moreLabel,\n moreText,\n subscribe: registry.subscribe\n }),\n [hidden, iconPlacement, menuContainer, menuPlacement, moreIcon, moreLabel, moreText, registry]\n )\n\n return (\n <NavOverflowContext.Provider value={controller}>\n <NavOverflowMoreContext.Provider value={more}>\n <Component\n className={classNames('nav-overflow', className)}\n style={hydrated ? style : { ...UNMEASURED_STYLE, ...style }}\n {...rest}\n ref={forkedRef}\n >\n {children}\n </Component>\n </NavOverflowMoreContext.Provider>\n </NavOverflowContext.Provider>\n )\n}\n\nexport const NavOverflow = createPolymorphicComponent<NavOverflowComponent>(\n NavOverflowRender as ForwardRefRenderFunction<Element, NavOverflowProps<ElementType>>,\n 'NavOverflow'\n)\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlayPlacement-Q6bcbXA5.js","names":["ARIA_PLACEMENT","toAriaPlacement","placement","resolveDataPlacement","resolvedMain","requested","cross","resolveMenuOverlayPositioning","overlayStyle","requestedPlacement","resolvedPlacement","COMBOBOX_MENU_OVERLAY_STYLE"],"sources":["../../src/utils/overlayPlacement.ts"],"sourcesContent":["import type { CSSProperties } from 'react'\nimport type { Placement as AriaPlacement, PlacementAxis } from 'react-aria'\n\n// Chassis CSS's floating components (`.menu`, `.tooltip`, `.popover`) read a `data-cx-placement`\n// attribute in this hyphenated, compound form (`\"bottom-end\"`, `\"top-start\"`, ...) to pick the\n// right transform-origin for the open/close animation. React Aria's `useOverlayPosition` speaks a\n// different, space-separated placement vocabulary (`\"bottom end\"`) and only reports back the\n// resolved main axis after flipping, not the full compound value — this module bridges the two.\nexport type Placement =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n\nconst ARIA_PLACEMENT: Record<Placement, AriaPlacement> = {\n top: 'top',\n 'top-start': 'top start',\n 'top-end': 'top end',\n bottom: 'bottom',\n 'bottom-start': 'bottom start',\n 'bottom-end': 'bottom end',\n left: 'left',\n 'left-start': 'left top',\n 'left-end': 'left bottom',\n right: 'right',\n 'right-start': 'right top',\n 'right-end': 'right bottom'\n}\n\n// Translates chassis-react's public `placement` prop values into the strings\n// `useOverlayPosition` expects.\nexport const toAriaPlacement = (placement: Placement): AriaPlacement => ARIA_PLACEMENT[placement]\n\n// `useOverlayPosition`'s own `shouldFlip` only ever swaps the main axis (top<->bottom or\n// left<->right) — it never changes the requested cross-axis alignment — so the resolved compound\n// value is always the requested cross-axis suffix reattached to the (possibly flipped) main axis\n// `useOverlayPosition` reports back.\nexport const resolveDataPlacement = (\n requested: Placement,\n resolvedMain: PlacementAxis | null\n): string => {\n if (!resolvedMain || resolvedMain === 'center') return requested\n const cross = requested.split('-')[1]\n return cross ? `${resolvedMain}-${cross}` : resolvedMain\n}\n\n// Shared between `Menu`/`MenuSubmenu` and `Combobox`/`Autocomplete`, whose floating panels all\n// position via `useOverlayPosition` the same way: only `position`/`top`/`left` are taken from the\n// hook's computed style (`zIndex`/`maxHeight` stay owned by chassis-css's own `--zindex`/\n// `--max-height` tokens, see `_menu.scss`; the inline `max-height` the hook writes on the element\n// itself is
|
|
1
|
+
{"version":3,"file":"overlayPlacement-Q6bcbXA5.js","names":["ARIA_PLACEMENT","toAriaPlacement","placement","resolveDataPlacement","resolvedMain","requested","cross","resolveMenuOverlayPositioning","overlayStyle","requestedPlacement","resolvedPlacement","COMBOBOX_MENU_OVERLAY_STYLE"],"sources":["../../src/utils/overlayPlacement.ts"],"sourcesContent":["import type { CSSProperties } from 'react'\nimport type { Placement as AriaPlacement, PlacementAxis } from 'react-aria'\n\n// Chassis CSS's floating components (`.menu`, `.tooltip`, `.popover`) read a `data-cx-placement`\n// attribute in this hyphenated, compound form (`\"bottom-end\"`, `\"top-start\"`, ...) to pick the\n// right transform-origin for the open/close animation. React Aria's `useOverlayPosition` speaks a\n// different, space-separated placement vocabulary (`\"bottom end\"`) and only reports back the\n// resolved main axis after flipping, not the full compound value — this module bridges the two.\nexport type Placement =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n\nconst ARIA_PLACEMENT: Record<Placement, AriaPlacement> = {\n top: 'top',\n 'top-start': 'top start',\n 'top-end': 'top end',\n bottom: 'bottom',\n 'bottom-start': 'bottom start',\n 'bottom-end': 'bottom end',\n left: 'left',\n 'left-start': 'left top',\n 'left-end': 'left bottom',\n right: 'right',\n 'right-start': 'right top',\n 'right-end': 'right bottom'\n}\n\n// Translates chassis-react's public `placement` prop values into the strings\n// `useOverlayPosition` expects.\nexport const toAriaPlacement = (placement: Placement): AriaPlacement => ARIA_PLACEMENT[placement]\n\n// `useOverlayPosition`'s own `shouldFlip` only ever swaps the main axis (top<->bottom or\n// left<->right) — it never changes the requested cross-axis alignment — so the resolved compound\n// value is always the requested cross-axis suffix reattached to the (possibly flipped) main axis\n// `useOverlayPosition` reports back.\nexport const resolveDataPlacement = (\n requested: Placement,\n resolvedMain: PlacementAxis | null\n): string => {\n if (!resolvedMain || resolvedMain === 'center') return requested\n const cross = requested.split('-')[1]\n return cross ? `${resolvedMain}-${cross}` : resolvedMain\n}\n\n// Shared between `Menu`/`MenuSubmenu` and `Combobox`/`Autocomplete`, whose floating panels all\n// position via `useOverlayPosition` the same way: only `position`/`top`/`left` are taken from the\n// hook's computed style (`zIndex`/`maxHeight` stay owned by chassis-css's own `--zindex`/\n// `--max-height` tokens, see `_menu.scss`; the inline `max-height` the hook writes on the element\n// itself is kept by `useOverlayMaxHeight` only where it is smaller than that cap), and\n// `data-cx-placement` needs the resolved main axis reattached to the originally-requested\n// cross-axis alignment. Pure positioning that renders\n// nothing and belongs to none of the four, so it lives here and not in `components/menu/`.\nexport interface MenuOverlayPositioning {\n menuStyle: CSSProperties\n placementAttr: string\n}\n\nexport const resolveMenuOverlayPositioning = (\n overlayStyle: CSSProperties | undefined,\n requestedPlacement: Placement,\n resolvedPlacement: PlacementAxis | null\n): MenuOverlayPositioning => ({\n menuStyle: {\n position: overlayStyle?.position,\n top: overlayStyle?.top,\n left: overlayStyle?.left\n },\n placementAttr: resolveDataPlacement(requestedPlacement, resolvedPlacement)\n})\n\n// chassis-css's `.combobox + .menu` sibling-selector rule (`_combobox.scss`) sets\n// `--cx-menu-max-height`/`--cx-menu-overflow-y` from `$combobox-menu-max-height`/\n// `$combobox-menu-overflow-y` (320px/auto by default) — but only while the panel is an adjacent\n// DOM sibling of `.combobox`. `Autocomplete`/`Combobox` portal their panel to `document.body` (or\n// an enclosing open `<dialog>`, via `useFloatingOverlay`), breaking that adjacency, so both inline\n// this as a fallback matching the shipped Sass defaults instead of the generic, uncapped `.menu`\n// fallback (`max-height: none`). The names carry the `cx-` prefix of chassis-css's built CSS:\n// unprefixed, as they were, nothing read them, and only the inline `max-height` react-aria wrote\n// (`useOverlayMaxHeight`) capped the list. A consumer who customized either Sass variable needs to\n// re-override `--cx-menu-max-height`/`--cx-menu-overflow-y` on `.menu` directly, since the\n// sibling-selector auto-application can no longer reach a portaled panel.\nexport const COMBOBOX_MENU_OVERLAY_STYLE: CSSProperties = {\n '--cx-menu-max-height': '320px',\n '--cx-menu-overflow-y': 'auto'\n} as CSSProperties\n"],"mappings":"AAsBA,MAAMA,EAAmD,CACvD,IAAK,MACL,YAAa,YACb,UAAW,UACX,OAAQ,SACR,eAAgB,eAChB,aAAc,aACd,KAAM,OACN,aAAc,WACd,WAAY,cACZ,MAAO,QACP,cAAe,YACf,YAAa,cACf,EAIaC,EAAmB,GAAwCD,EAAeE,GAM1EC,GACX,EACA,IACW,CACX,GAAI,CAACC,GAAgBA,IAAiB,SAAU,OAAOC,EACvD,IAAMC,EAAQD,EAAU,MAAM,GAAG,CAAC,CAAC,GACnC,OAAOC,EAAQ,GAAGF,EAAa,GAAGE,IAAUF,CAC9C,EAeaG,GACX,EACA,EACA,KAC4B,CAC5B,UAAW,CACT,SAAUC,GAAc,SACxB,IAAKA,GAAc,IACnB,KAAMA,GAAc,IACtB,EACA,cAAeL,EAAqBM,EAAoBC,CAAiB,CAC3E,GAaaC,EAA6C,CACxD,uBAAwB,QACxB,uBAAwB,MAC1B,E"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./useIsomorphicLayoutEffect-BbqRwuqn.js";import{useEffect as t,useRef as n}from"react";const r=/* @__PURE__ */ new WeakMap,i=e=>{let t=e.style.maxHeight;t!==r.get(e)&&(r.delete(e)&&e.style.removeProperty(`overflow-y`),t&&(e.style.removeProperty(`max-height`),!(Number.parseFloat(t)>=Number.parseFloat(getComputedStyle(e).maxHeight))&&(e.style.maxHeight=t,e.style.overflowY=`auto`,r.set(e,t))))};function a(r,a){let o=n(null);e(()=>{let e=a?r.current:null,t=o.current;if(e&&i(e),t?.node===e||(t?.observer.disconnect(),o.current=null,!e||typeof MutationObserver>`u`))return;let n=new MutationObserver(()=>i(e));n.observe(e,{attributes:!0,attributeFilter:[`style`]}),o.current={node:e,observer:n}}),t(()=>()=>{o.current?.observer.disconnect(),o.current=null},[])}export{a as t};
|
|
2
|
+
//# sourceMappingURL=useOverlayMaxHeight-DTgbr4UQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOverlayMaxHeight-DTgbr4UQ.js","names":["useIsomorphicLayoutEffect","kept","fitToRoom","room","node","useOverlayMaxHeight","observedRef","useRef","isOpen","overlayRef","observed","observer","useEffect"],"sources":["../../src/hooks/useOverlayMaxHeight.ts"],"sourcesContent":["import { RefObject, useEffect, useRef } from 'react'\n\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\n// The room a panel keeps, by panel, so that writing it back isn't read as a new placement.\nconst kept = new WeakMap<HTMLElement, string>()\n\nconst fitToRoom = (node: HTMLElement) => {\n const room = node.style.maxHeight\n if (room === kept.get(node)) return\n if (kept.delete(node)) node.style.removeProperty('overflow-y')\n if (!room) return\n node.style.removeProperty('max-height')\n // `none` parses to NaN, which no room reaches: with no cap, the room is the height.\n if (Number.parseFloat(room) >= Number.parseFloat(getComputedStyle(node).maxHeight)) return\n node.style.maxHeight = room\n node.style.overflowY = 'auto'\n kept.set(node, room)\n}\n\n// Gives a `.menu` panel the smaller of chassis-css's `--cx-menu-max-height` and the room\n// react-aria's `useOverlayPosition` finds for it beside its trigger. The hook writes that room as\n// an inline `max-height`, on the element itself rather than in the style it returns, and again each\n// time it places the overlay (a resize, the overlay's own size changing). Inline, it outranks the\n// theme's cap: a `Combobox` list 360.5px tall against a 320px token. So it is taken off where the\n// cap is smaller, and kept where it is the smaller one, with the list scrolling inside it: a menu\n// taller than the room on either side of its trigger otherwise runs off the viewport. Each write\n// is handled before the paint.\n//\n// For `Menu`, `MenuSubmenu`, `ContextMenu`, `Combobox` and `Autocomplete`, which take only the\n// position from the hook (`resolveMenuOverlayPositioning`). Call it after `useOverlayPosition`, so\n// its layout effect runs after the hook's own.\nexport function useOverlayMaxHeight(overlayRef: RefObject<HTMLElement | null>, isOpen: boolean) {\n const observedRef = useRef<{ node: HTMLElement; observer: MutationObserver } | null>(null)\n\n // Every commit: the panel can be a new element (a list moved into a dialog), and the hook\n // places it again in its own layout effect.\n useIsomorphicLayoutEffect(() => {\n const node = isOpen ? overlayRef.current : null\n const observed = observedRef.current\n if (node) fitToRoom(node)\n if (observed?.node === node) return\n observed?.observer.disconnect()\n observedRef.current = null\n if (!node || typeof MutationObserver === 'undefined') return\n const observer = new MutationObserver(() => fitToRoom(node))\n observer.observe(node, { attributes: true, attributeFilter: ['style'] })\n observedRef.current = { node, observer }\n })\n\n useEffect(\n () => () => {\n observedRef.current?.observer.disconnect()\n observedRef.current = null\n },\n []\n )\n}\n"],"mappings":"A,0GAKA,MAAMC,kBAAO,IAAI,QAEXC,EAAa,GAAsB,CACvC,IAAMC,EAAOC,EAAK,MAAM,UACpBD,IAASF,EAAK,IAAIG,CAAI,IACtBH,EAAK,OAAOG,CAAI,GAAGA,EAAK,MAAM,eAAe,YAAY,EACxDD,IACLC,EAAK,MAAM,eAAe,YAAY,EAElC,SAAO,WAAWD,CAAI,GAAK,OAAO,WAAW,iBAAiBC,CAAI,CAAC,CAAC,SAAS,KACjF,EAAK,MAAM,UAAYD,EACvB,EAAK,MAAM,UAAY,OACvBF,EAAK,IAAIG,EAAMD,CAAI,IACrB,EAcA,SAAgBE,EAAoB,EAA2C,EAAiB,CAC9F,IAAMC,EAAcC,EAAiE,IAAI,EAIzFP,MAAgC,CAC9B,IAAMI,EAAOI,EAASC,EAAW,QAAU,KACrCC,EAAWJ,EAAY,QAK7B,GAJIF,GAAMF,EAAUE,CAAI,EACpBM,GAAU,OAASN,IACvBM,GAAU,SAAS,WAAW,EAC9B,EAAY,QAAU,KAClB,CAACN,GAAQ,OAAO,iBAAqB,KAAa,OACtD,IAAMO,EAAW,IAAI,qBAAuBT,EAAUE,CAAI,CAAC,EAC3DO,EAAS,QAAQP,EAAM,CAAE,WAAY,GAAM,gBAAiB,CAAC,OAAO,CAAE,CAAC,EACvE,EAAY,QAAU,CAAE,OAAM,UAAS,CACzC,CAAC,EAEDQ,UACc,CACVN,EAAY,SAAS,SAAS,WAAW,EACzC,EAAY,QAAU,IACxB,EACA,CAAC,CACH,CACF,C"}
|
package/dist/combobox.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{o as e}from"./chunks/ComboboxListBox-Db0rSM3w.js";import{n as t,t as n}from"./chunks/combobox-
|
|
1
|
+
"use client";import{o as e}from"./chunks/ComboboxListBox-Db0rSM3w.js";import{n as t,t as n}from"./chunks/combobox-DNqR4d3V.js";export{n as Combobox,t as ComboboxGroup,e as ComboboxItem};
|
package/dist/context-menu.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";export{t as ContextMenu}from"./chunks/context-menu-
|
|
1
|
+
"use client";export{t as ContextMenu}from"./chunks/context-menu-D3DNFN-P.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import"./chunks/focus-ring-Bs80iIBN.js";import{i as e,n as t,r as n,t as r}from"./chunks/accordion-BZlX2uk8.js";import{t as i}from"./chunks/useHydrated-Dud4JEwp.js";import{n as a,t as o}from"./chunks/datepicker-DqztYJD6.js";import{n as s,r as c,t as l}from"./chunks/pagination-Dvz8lccd.js";import{o as u}from"./chunks/ComboboxListBox-Db0rSM3w.js";import{t as d}from"./chunks/Icon-Dk5_q79o.js";import{t as f}from"./chunks/Portal-BTDylxAi.js";import{n as p,t as m}from"./chunks/FormHelp-B1eSoack.js";import{t as h}from"./chunks/FormLabel-CpzWYh6U.js";import{n as g,r as _,t as v}from"./chunks/autocomplete-
|
|
1
|
+
"use client";import"./chunks/focus-ring-Bs80iIBN.js";import{i as e,n as t,r as n,t as r}from"./chunks/accordion-BZlX2uk8.js";import{t as i}from"./chunks/useHydrated-Dud4JEwp.js";import{n as a,t as o}from"./chunks/datepicker-DqztYJD6.js";import{n as s,r as c,t as l}from"./chunks/pagination-Dvz8lccd.js";import{o as u}from"./chunks/ComboboxListBox-Db0rSM3w.js";import{t as d}from"./chunks/Icon-Dk5_q79o.js";import{t as f}from"./chunks/Portal-BTDylxAi.js";import{n as p,t as m}from"./chunks/FormHelp-B1eSoack.js";import{t as h}from"./chunks/FormLabel-CpzWYh6U.js";import{n as g,r as _,t as v}from"./chunks/autocomplete-Btcsjrh3.js";import{t as y}from"./chunks/Link-DE8NSAXJ.js";import{t as b}from"./chunks/badge-Ths1Qn1a.js";import{n as x,r as S,t as C}from"./chunks/avatar-BQBbcnk6.js";import{t as w}from"./chunks/VisuallyHidden-CGv-mBuQ.js";import{t as T}from"./chunks/CloseButton-BPUI5iGX.js";import{a as E,c as D,i as O,l as k,n as A,o as j,r as M,s as N,t as P}from"./chunks/notification-oIrUtDhl.js";import{t as F}from"./chunks/stack-DtzW54UK.js";import{n as I,t as L}from"./chunks/breadcrumb-BTiQikk-.js";import{t as R}from"./chunks/Button-ZU-x1uN_.js";import"./button.js";import{n as z,t as B}from"./chunks/button-group-CefkGeYL.js";import{n as V,t as H}from"./chunks/RangeCalendar-mM3OeTlU.js";import"./calendar.js";import{a as U,c as W,i as G,n as K,o as q,r as J,s as Y,t as X}from"./chunks/datagrid-n9vFeXN1.js";import{a as Z,c as Q,d as $,i as ee,l as te,n as ne,o as re,r as ie,s as ae,t as oe,u as se}from"./chunks/card-CEQgHIaL.js";import{a as ce,c as le,i as ue,n as de,o as fe,r as pe,s as me,t as he}from"./chunks/carousel-DC-UGc6W.js";import{t as ge}from"./chunks/collapse-CBi3RWTf.js";import{t as _e}from"./chunks/Chip-C7QlFCvx.js";import{t as ve}from"./chunks/chip-input-CugY8EOc.js";import"./close-button.js";import{t as ye}from"./chunks/color-input-C4zMWlvm.js";import{t as be}from"./chunks/file-input-D_Gl1h-T.js";import{n as xe,t as Se}from"./chunks/combobox-DNqR4d3V.js";import{t as Ce}from"./chunks/otp-input-DUtCMg8P.js";import{t as we}from"./chunks/password-strength-Qg5GHBmu.js";import{t as Te}from"./chunks/Menu-BiE9CzNk.js";import{d as Ee,f as De,n as Oe,t as ke,u as Ae}from"./chunks/MenuToggle-W-ZSHFwF.js";import{n as je,r as Me,t as Ne}from"./chunks/menu-Bqlhottl.js";import{n as Pe,r as Fe,t as Ie}from"./chunks/grid-CkdPftit.js";import{n as Le,t as Re}from"./chunks/checkbox-ko6CdtoT.js";import{t as ze}from"./chunks/flex-C2jV5LyV.js";import{t as Be}from"./chunks/form-CPS2eNw1.js";import{t as Ve}from"./chunks/floating-input-D4gWFfOU.js";import{t as He}from"./chunks/form-field-Bcx96ezd.js";import{n as Ue,t as We}from"./chunks/input-group-YB_zoKud.js";import{t as Ge}from"./chunks/input-adorn-DV9tuWXh.js";import{n as Ke,t as qe}from"./chunks/radio-C42F_5OD.js";import{t as Je}from"./chunks/range-input-DeZq_9S7.js";import{t as Ye}from"./chunks/select-DwyL6aqY.js";import{t as Xe}from"./chunks/switch-cp3IZg3L.js";import{t as Ze}from"./chunks/text-input-CR73x-8D.js";import{t as Qe}from"./chunks/textarea-C-1cMyH4.js";import{t as $e}from"./chunks/icon-CVD3rTr-.js";import{t as et}from"./chunks/placeholder-SPoVRkKE.js";import"./link.js";import{n as tt,t as nt}from"./chunks/list-BPBZR66Y.js";import{a as rt,i as it,n as at,o as ot,r as st,t as ct}from"./chunks/modal-CHvsDTyl.js";import{i as lt,n as ut,r as dt,t as ft}from"./chunks/nav-B4U_Hqs7.js";import{a as pt,i as mt,n as ht,r as gt,t as _t}from"./chunks/navbar-C7dO0YRs.js";import{t as vt}from"./chunks/popover-C_32yD9W.js";import{n as yt,t as bt}from"./chunks/progress-CiSJDNwx.js";import{a as xt,i as St,n as Ct,o as wt,r as Tt,t as Et}from"./chunks/drawer-CRv9jmbp.js";import{n as Dt,t as Ot}from"./chunks/skeleton-B2blJGWj.js";import{t as kt}from"./chunks/spinner-D8lQCW4u.js";import{t as At}from"./chunks/static-table-C7ZtFQ66.js";import{n as jt,t as Mt}from"./chunks/stepper-tSA84huJ.js";import{a as Nt,i as Pt,n as Ft,o as It,r as Lt,t as Rt}from"./chunks/table-CBTg5Yuq.js";import{i as zt,n as Bt,r as Vt,t as Ht}from"./chunks/tabs-DMFSLjnV.js";import{a as Ut,c as Wt,i as Gt,l as Kt,n as qt,o as Jt,r as Yt,s as Xt,t as Zt,u as Qt}from"./chunks/toast-Dd0J2e1z.js";import{t as $t}from"./chunks/tooltip-CmKeQwYw.js";import"./chip.js";import"./portal.js";import"./visually-hidden.js";import{a as en,c as tn,i as nn,n as rn,o as an,r as on,s as sn,t as cn}from"./chunks/alert-DSLg5MBb.js";import{t as ln}from"./chunks/nav-overflow-GWARvoQZ.js";import{n as un,t as dn}from"./chunks/scrollspy-BEZEVyIw.js";import{t as fn}from"./chunks/divider-C1-NoKMV.js";import{t as pn}from"./chunks/number-field-ChPTSBwI.js";import{t as mn}from"./chunks/time-field-CbCfOQZz.js";import{t as hn}from"./chunks/search-field-OFsb3t4L.js";import{t as gn}from"./chunks/context-menu-D3DNFN-P.js";import{n as _n,t as vn}from"./chunks/tree-DNj_EfUl.js";import{I18nProvider as yn}from"react-aria";export{r as Accordion,e as AccordionBody,n as AccordionHeader,t as AccordionItem,tn as Alert,sn as AlertBody,an as AlertCancel,en as AlertCode,nn as AlertFooter,on as AlertIcon,rn as AlertText,cn as AlertTitle,v as Autocomplete,_ as AutocompleteGroup,g as AutocompleteItem,x as Avatar,S as AvatarImage,C as AvatarStack,b as Badge,L as Breadcrumb,I as BreadcrumbItem,R as Button,z as ButtonGroup,B as ButtonToolbar,V as Calendar,Z as Card,$ as CardBody,se as CardFooter,ee as CardGroup,ie as CardHeader,te as CardImage,ne as CardImageOverlay,oe as CardLink,Q as CardSubtitle,ae as CardText,re as CardTitle,fe as Carousel,ce as CarouselControlNext,ue as CarouselControlPrev,pe as CarouselIndicators,me as CarouselInner,le as CarouselItem,de as CarouselOverlay,he as CarouselPlayPause,Le as Checkbox,Re as CheckboxGroup,_e as Chip,ve as ChipInput,T as CloseButton,ge as Collapse,ye as ColorInput,Se as Combobox,xe as ComboboxGroup,u as ComboboxItem,Fe as Container,gn as ContextMenu,W as DataGrid,Y as DataGridBody,q as DataGridCell,U as DataGridColumn,G as DataGridHeader,J as DataGridRow,X as DataGridSelectAllCell,K as DataGridSelectionCell,a as DatePicker,o as DateRangePicker,fn as Divider,wt as Drawer,xt as DrawerBody,St as DrawerFooter,Ct as DrawerHeader,Et as DrawerTitle,be as FileInput,ze as Flex,Ve as FloatingInput,Be as Form,p as FormFeedback,He as FormField,m as FormHelp,h as FormLabel,Pe as Grid,Ie as GridItem,yn as I18nProvider,d as Icon,$e as IconProvider,Ge as InputAdorn,Ue as InputGroup,We as InputGroupAddon,y as Link,nt as List,tt as ListItem,Te as Menu,De as MenuDivider,Ee as MenuHeader,Ae as MenuItem,Oe as MenuList,je as MenuSubmenu,Ne as MenuSubmenuBack,Me as MenuText,ke as MenuToggle,ot as Modal,rt as ModalBody,it as ModalFooter,at as ModalHeader,ct as ModalTitle,ut as Nav,dt as NavItem,lt as NavLink,ln as NavOverflow,ft as NavTitle,pt as Navbar,mt as NavbarBrand,gt as NavbarNav,ht as NavbarText,_t as NavbarToggler,N as Notification,j as NotificationIcon,A as NotificationStack,k as NotificationText,D as NotificationTitle,pn as NumberField,Ce as OtpInput,l as Pagination,s as PaginationItem,we as PasswordStrength,et as Placeholder,vt as Popover,f as Portal,bt as Progress,yt as ProgressBar,Ke as Radio,qe as RadioGroup,H as RangeCalendar,Je as RangeInput,dn as Scrollspy,hn as SearchField,Ye as Select,Dt as Skeleton,Ot as SkeletonLoader,kt as Spinner,F as Stack,At as StaticTable,Mt as Stepper,jt as StepperItem,Xe as Switch,Ht as Tab,zt as TabList,Vt as TabPanel,It as Table,Nt as TableBody,Pt as TableCell,Lt as TableColumn,Ft as TableHeader,Rt as TableRow,Bt as Tabs,Ze as TextInput,Qe as Textarea,mn as TimeField,Jt as Toast,Kt as ToastBody,Wt as ToastFooter,Xt as ToastHeader,Ut as ToastIcon,Zt as Toaster,$t as Tooltip,_n as Tree,vn as TreeItem,w as VisuallyHidden,M as addNotification,qt as addToast,O as closeNotification,Yt as closeToast,E as notificationQueue,Gt as toastQueue,Tt as useDrawer,i as useHydrated,st as useModal,P as useNotification,c as usePagination,un as useScrollspy,Qt as useToast};
|
package/dist/menu.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{t as e}from"./chunks/Menu-
|
|
1
|
+
"use client";import{t as e}from"./chunks/Menu-BiE9CzNk.js";import{d as t,f as n,n as r,t as i,u as a}from"./chunks/MenuToggle-W-ZSHFwF.js";import{n as o,r as s,t as c}from"./chunks/menu-Bqlhottl.js";export{e as Menu,n as MenuDivider,t as MenuHeader,a as MenuItem,r as MenuList,o as MenuSubmenu,c as MenuSubmenuBack,s as MenuText,i as MenuToggle};
|
package/dist/nav-overflow.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";export{t as NavOverflow}from"./chunks/nav-overflow-
|
|
1
|
+
"use client";export{t as NavOverflow}from"./chunks/nav-overflow-GWARvoQZ.js";
|
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./useIsomorphicLayoutEffect-BbqRwuqn.js";import{useEffect as t,useRef as n}from"react";const r=e=>{e.style.maxHeight&&e.style.removeProperty(`max-height`)};function i(i,a){let o=n(null);e(()=>{let e=a?i.current:null,t=o.current;if(e&&r(e),t?.node===e||(t?.observer.disconnect(),o.current=null,!e||typeof MutationObserver>`u`))return;let n=new MutationObserver(()=>r(e));n.observe(e,{attributes:!0,attributeFilter:[`style`]}),o.current={node:e,observer:n}}),t(()=>()=>{o.current?.observer.disconnect(),o.current=null},[])}export{i as t};
|
|
2
|
-
//# sourceMappingURL=useOverlayMaxHeight-8mQL2Q6d.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useOverlayMaxHeight-8mQL2Q6d.js","names":["useIsomorphicLayoutEffect","releaseMaxHeight","node","useOverlayMaxHeight","observedRef","useRef","isOpen","overlayRef","observed","observer","useEffect"],"sources":["../../src/hooks/useOverlayMaxHeight.ts"],"sourcesContent":["import { RefObject, useEffect, useRef } from 'react'\n\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\nconst releaseMaxHeight = (node: HTMLElement) => {\n if (node.style.maxHeight) node.style.removeProperty('max-height')\n}\n\n// Leaves the height of a `.menu` panel to chassis-css's `--cx-menu-max-height`. react-aria's\n// `useOverlayPosition` writes the room it finds for the overlay as an inline `max-height`, on the\n// element itself rather than in the style it returns, and again each time it places the overlay\n// (a resize, the overlay's own size changing). Inline, that outranks the theme's cap: a\n// `Combobox` list 360.5px tall against a 320px token. The value is taken off each time it is\n// written, before the paint.\n//\n// For `Menu`, `MenuSubmenu`, `ContextMenu`, `Combobox` and `Autocomplete`, which take only the\n// position from the hook (`resolveMenuOverlayPositioning`). Call it after `useOverlayPosition`, so\n// its layout effect runs after the hook's own.\nexport function useOverlayMaxHeight(overlayRef: RefObject<HTMLElement | null>, isOpen: boolean) {\n const observedRef = useRef<{ node: HTMLElement; observer: MutationObserver } | null>(null)\n\n // Every commit: the panel can be a new element (a list moved into a dialog), and the hook\n // places it again in its own layout effect.\n useIsomorphicLayoutEffect(() => {\n const node = isOpen ? overlayRef.current : null\n const observed = observedRef.current\n if (node) releaseMaxHeight(node)\n if (observed?.node === node) return\n observed?.observer.disconnect()\n observedRef.current = null\n if (!node || typeof MutationObserver === 'undefined') return\n const observer = new MutationObserver(() => releaseMaxHeight(node))\n observer.observe(node, { attributes: true, attributeFilter: ['style'] })\n observedRef.current = { node, observer }\n })\n\n useEffect(\n () => () => {\n observedRef.current?.observer.disconnect()\n observedRef.current = null\n },\n []\n )\n}\n"],"mappings":"A,0GAIA,MAAMC,EAAoB,GAAsB,CAC1CC,EAAK,MAAM,WAAWA,EAAK,MAAM,eAAe,YAAY,CAClE,EAYA,SAAgBC,EAAoB,EAA2C,EAAiB,CAC9F,IAAMC,EAAcC,EAAiE,IAAI,EAIzFL,MAAgC,CAC9B,IAAME,EAAOI,EAASC,EAAW,QAAU,KACrCC,EAAWJ,EAAY,QAK7B,GAJIF,GAAMD,EAAiBC,CAAI,EAC3BM,GAAU,OAASN,IACvBM,GAAU,SAAS,WAAW,EAC9B,EAAY,QAAU,KAClB,CAACN,GAAQ,OAAO,iBAAqB,KAAa,OACtD,IAAMO,EAAW,IAAI,qBAAuBR,EAAiBC,CAAI,CAAC,EAClEO,EAAS,QAAQP,EAAM,CAAE,WAAY,GAAM,gBAAiB,CAAC,OAAO,CAAE,CAAC,EACvE,EAAY,QAAU,CAAE,OAAM,UAAS,CACzC,CAAC,EAEDQ,UACc,CACVN,EAAY,SAAS,SAAS,WAAW,EACzC,EAAY,QAAU,IACxB,EACA,CAAC,CACH,CACF,C"}
|