@ai-matrx/design-system 0.86.356 → 0.86.358
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 +16 -0
- package/dist/auth-gate-dialog.js +2 -2
- package/dist/carousel.js +11 -10
- package/dist/carousel.js.map +1 -1
- package/dist/{chunk-UWTODOMD.js → chunk-2BQAHLU3.js} +4 -4
- package/dist/{chunk-T4D7WAV7.js → chunk-42GFQMLA.js} +2 -2
- package/dist/chunk-5Z5GTXKL.js +79 -0
- package/dist/chunk-5Z5GTXKL.js.map +1 -0
- package/dist/{chunk-POJ3RR3K.js → chunk-B5D3VIMC.js} +1 -1
- package/dist/{chunk-POJ3RR3K.js.map → chunk-B5D3VIMC.js.map} +1 -1
- package/dist/{chunk-4WSXAP24.js → chunk-BB5LA7FQ.js} +3 -1
- package/dist/chunk-BB5LA7FQ.js.map +1 -0
- package/dist/{chunk-FRJ4PPA2.js → chunk-CZGZV35G.js} +2 -2
- package/dist/{chunk-RLM4RSED.js → chunk-GUGBVQ4T.js} +6 -4
- package/dist/{chunk-RLM4RSED.js.map → chunk-GUGBVQ4T.js.map} +1 -1
- package/dist/{chunk-LJKF267O.js → chunk-HS6GMHKZ.js} +18 -76
- package/dist/chunk-HS6GMHKZ.js.map +1 -0
- package/dist/{chunk-2PO3N42Q.js → chunk-K3XWUACX.js} +5 -5
- package/dist/{chunk-ZMUPFGQO.js → chunk-K5ZQROWN.js} +5 -5
- package/dist/{chunk-U46XUQI7.js → chunk-KSCSH7AO.js} +16 -14
- package/dist/chunk-KSCSH7AO.js.map +1 -0
- package/dist/{chunk-MTE6N7XU.js → chunk-NFJ63LIH.js} +2 -2
- package/dist/{chunk-CFUXEGW2.js → chunk-OUQT72UL.js} +4 -4
- package/dist/{chunk-WUD23YTG.js → chunk-P56Y43RL.js} +6 -6
- package/dist/{chunk-GMNROZQJ.js → chunk-QTPW44IJ.js} +2 -2
- package/dist/{chunk-QA7EHFRX.js → chunk-T3FKFPCW.js} +5 -5
- package/dist/{chunk-X6ZRHJQP.js → chunk-T57DLONB.js} +20 -11
- package/dist/chunk-T57DLONB.js.map +1 -0
- package/dist/{chunk-SOCNWQMX.js → chunk-TEMAM5ET.js} +3 -3
- package/dist/{chunk-CH2NWSES.js → chunk-TIV6M7Q7.js} +3 -3
- package/dist/{chunk-6XNYYROM.js → chunk-WVEDW5VO.js} +2 -2
- package/dist/clipboard-fallback-dialog.js +4 -4
- package/dist/controls.cjs +34 -13
- package/dist/controls.cjs.map +1 -1
- package/dist/controls.js +9 -8
- package/dist/data-table/data-row-inspector.cjs +99 -11
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +8 -7
- package/dist/data-table/data-row-window.cjs +99 -11
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +11 -10
- package/dist/data-table/drill-chart.cjs +15 -3
- package/dist/data-table/drill-chart.cjs.map +1 -1
- package/dist/data-table/drill-chart.js +2 -1
- package/dist/data-table/drill-chart.js.map +1 -1
- package/dist/data-table/host.cjs.map +1 -1
- package/dist/data-table/host.d.cts +6 -2
- package/dist/data-table/host.d.ts +6 -2
- package/dist/data-table/host.js +1 -1
- package/dist/data-table/index.cjs +54 -40
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +6 -2
- package/dist/data-table/index.d.ts +6 -2
- package/dist/data-table/index.js +25 -28
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/pagination.cjs +19 -10
- package/dist/data-table/pagination.cjs.map +1 -1
- package/dist/data-table/pagination.js +4 -4
- package/dist/data-table/uuid-cell.cjs +99 -11
- package/dist/data-table/uuid-cell.cjs.map +1 -1
- package/dist/data-table/uuid-cell.js +5 -4
- package/dist/desktop.cjs +45 -15
- package/dist/desktop.cjs.map +1 -1
- package/dist/desktop.js +23 -15
- package/dist/desktop.js.map +1 -1
- package/dist/email-input-dialog.cjs +15 -3
- package/dist/email-input-dialog.cjs.map +1 -1
- package/dist/email-input-dialog.js +4 -3
- package/dist/email-input-dialog.js.map +1 -1
- package/dist/error-sentence.cjs +130 -0
- package/dist/error-sentence.cjs.map +1 -0
- package/dist/error-sentence.d.cts +49 -0
- package/dist/error-sentence.d.ts +49 -0
- package/dist/error-sentence.js +22 -0
- package/dist/error-sentence.js.map +1 -0
- package/dist/index.cjs +47 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -10
- package/dist/index.d.ts +12 -10
- package/dist/index.js +30 -28
- package/dist/index.js.map +1 -1
- package/dist/item.cjs +19 -10
- package/dist/item.cjs.map +1 -1
- package/dist/item.js +7 -7
- package/dist/lite-table.cjs +15 -3
- package/dist/lite-table.cjs.map +1 -1
- package/dist/lite-table.js +5 -4
- package/dist/lite-table.js.map +1 -1
- package/dist/menu-look.cjs +19 -10
- package/dist/menu-look.cjs.map +1 -1
- package/dist/menu-look.js +2 -2
- package/dist/notice-stack.cjs +2 -0
- package/dist/notice-stack.cjs.map +1 -1
- package/dist/notice-stack.d.cts +11 -1
- package/dist/notice-stack.d.ts +11 -1
- package/dist/notice-stack.js +3 -1
- package/dist/record-list.cjs +34 -13
- package/dist/record-list.cjs.map +1 -1
- package/dist/record-list.js +8 -7
- package/dist/record-list.js.map +1 -1
- package/dist/sandbox-gate-dialog.js +2 -2
- package/dist/scope-mismatch-dialog.js +2 -2
- package/dist/settings.js +3 -3
- package/dist/swipe-deck.cjs +15 -3
- package/dist/swipe-deck.cjs.map +1 -1
- package/dist/swipe-deck.js +2 -1
- package/dist/swipe-deck.js.map +1 -1
- package/dist/text-input-dialog.cjs +15 -3
- package/dist/text-input-dialog.cjs.map +1 -1
- package/dist/text-input-dialog.js +4 -3
- package/dist/text-input-dialog.js.map +1 -1
- package/dist/value-prompts-dialog.js +2 -2
- package/dist/writing-field.js +5 -5
- package/package.json +12 -2
- package/dist/chunk-4WSXAP24.js.map +0 -1
- package/dist/chunk-LJKF267O.js.map +0 -1
- package/dist/chunk-U46XUQI7.js.map +0 -1
- package/dist/chunk-X6ZRHJQP.js.map +0 -1
- /package/dist/{chunk-UWTODOMD.js.map → chunk-2BQAHLU3.js.map} +0 -0
- /package/dist/{chunk-T4D7WAV7.js.map → chunk-42GFQMLA.js.map} +0 -0
- /package/dist/{chunk-FRJ4PPA2.js.map → chunk-CZGZV35G.js.map} +0 -0
- /package/dist/{chunk-2PO3N42Q.js.map → chunk-K3XWUACX.js.map} +0 -0
- /package/dist/{chunk-ZMUPFGQO.js.map → chunk-K5ZQROWN.js.map} +0 -0
- /package/dist/{chunk-MTE6N7XU.js.map → chunk-NFJ63LIH.js.map} +0 -0
- /package/dist/{chunk-CFUXEGW2.js.map → chunk-OUQT72UL.js.map} +0 -0
- /package/dist/{chunk-WUD23YTG.js.map → chunk-P56Y43RL.js.map} +0 -0
- /package/dist/{chunk-GMNROZQJ.js.map → chunk-QTPW44IJ.js.map} +0 -0
- /package/dist/{chunk-QA7EHFRX.js.map → chunk-T3FKFPCW.js.map} +0 -0
- /package/dist/{chunk-SOCNWQMX.js.map → chunk-TEMAM5ET.js.map} +0 -0
- /package/dist/{chunk-CH2NWSES.js.map → chunk-TIV6M7Q7.js.map} +0 -0
- /package/dist/{chunk-6XNYYROM.js.map → chunk-WVEDW5VO.js.map} +0 -0
package/dist/lite-table.js
CHANGED
|
@@ -6,22 +6,23 @@ import {
|
|
|
6
6
|
ReadEmpty,
|
|
7
7
|
ReadStaleNotice,
|
|
8
8
|
readOf
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-GUGBVQ4T.js";
|
|
10
10
|
import {
|
|
11
11
|
MAC_TABLE_ATTRIBUTE,
|
|
12
12
|
MAC_TABLE_SLOTS
|
|
13
13
|
} from "./chunk-5JZSBNEY.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-5Z5GTXKL.js";
|
|
15
15
|
import {
|
|
16
16
|
getTapTargetLinkComponent
|
|
17
17
|
} from "./chunk-WFBPCMPF.js";
|
|
18
18
|
import {
|
|
19
19
|
Button
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-WVEDW5VO.js";
|
|
21
21
|
import "./chunk-BD77DHUO.js";
|
|
22
22
|
import "./chunk-BKCJUFD3.js";
|
|
23
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-T57DLONB.js";
|
|
24
24
|
import "./chunk-BNXNIN2S.js";
|
|
25
|
+
import "./chunk-HS6GMHKZ.js";
|
|
25
26
|
import "./chunk-WFITMVDB.js";
|
|
26
27
|
import "./chunk-WAT2XW7L.js";
|
|
27
28
|
import "./chunk-7IOSA55D.js";
|
package/dist/lite-table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lite-table/LiteTable.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * LiteTable — THE LIGHT SORTABLE TABLE (2026-10-17, Arman: \"so there is no\n * excuse for creating hand-rolled versions in the app\").\n *\n * For a small, fully loaded set (up to a few hundred rows) where the full\n * `MatrxDataTable` is more than the page needs: declared columns, click-to-sort\n * headers, the honest read states, a row that opens or links, copy a row, two\n * densities, and a phone layout (each row a labeled record).\n *\n * It takes the SAME `MatrxColumnDef<T>` and the same core props as\n * `MatrxDataTable` (`data`, `columns`, `getRowId`, `read`, `emptyState`,\n * `defaultSort`, `onRowOpen`, `getRowHref`, `density`, `rowClassName`), so a\n * page graduates to the full table by changing one import. Column fields it\n * does not draw (filters, editing, pinning, KPIs …) are ignored, never wrong.\n *\n * It imports only TYPES from the data table: the bundle never carries the grid\n * (guarded by `scripts/section-isolation.json`).\n *\n * THE MAC TABLE (2026-10-17, Arman: \"I love the mac table\"): it draws the desktop app's\n * `DataTable` — NSTableView's 24 pt rows under a 22 pt header, 13 pt, stripes, hairlines, the\n * accent selection — from the same `data-slot` vocabulary and the same values\n * (`../mac-table/tokens.ts`, drawn by `mac-table.css`; `mac-table-parity.test.ts` keeps them equal).\n */\n\nimport {\n useCallback,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n} from \"react\";\nimport { useIsMobile } from \"@ai-matrx/kit/media-query\";\nimport { copyText } from \"@ai-matrx/kit/clipboard\";\nimport { openOutbound } from \"@ai-matrx/kit/outbound\";\nimport type {\n MatrxColumnDef,\n MatrxDataTableDensity,\n MatrxDataTableEmptyState,\n SortState,\n} from \"../data-table/types\";\nimport { ReadEmpty, ReadStaleNotice, type ReadOutcome } from \"../read-state/read-gate\";\nimport { ListEmptyView } from \"../read-state/list-empty-view\";\nimport { getTapTargetLinkComponent } from \"../tap-target/link\";\nimport { cn } from \"../cn\";\nimport { Button } from \"../controls/controls\";\nimport { ChevronDownIcon, CheckIcon, CopyIcon } from \"../icons\";\nimport { MAC_TABLE_ATTRIBUTE, MAC_TABLE_SLOTS } from \"../mac-table/tokens\";\n\nexport interface LiteTableProps<T> {\n data: T[];\n columns: MatrxColumnDef<T>[];\n getRowId: (row: T) => string;\n /** The read behind `data`: the empty view shows only after a read that succeeded. */\n read?: ReadOutcome | undefined;\n /** Shown after a successful read with no rows. The full table's object form, or any node. */\n emptyState?: MatrxDataTableEmptyState | ReactNode;\n /** First sort (uncontrolled). */\n defaultSort?: SortState | null | undefined;\n /** Controlled sort. */\n sort?: SortState | null | undefined;\n onSortChange?: ((sort: SortState | null) => void) | undefined;\n /** Plain row click / Enter. */\n onRowOpen?: ((row: T) => void) | undefined;\n /** The row's page: its first column becomes a real link; a plain row click follows it. */\n getRowHref?: ((row: T) => string | undefined) | undefined;\n /** `condensed` (Finder's 20 pt rows) · `normal` (AppKit's 24 pt, default) · `spacious` (36 pt). */\n density?: MatrxDataTableDensity | undefined;\n /** The current row (drawn selected: gray, the accent while the table has focus). */\n selectedKey?: string | null | undefined;\n /** A copy button on each row (its visible values, one \"Label: value\" per line). Default true. */\n copyRows?: boolean | undefined;\n /** Accessible name of the table. */\n ariaLabel?: string | undefined;\n /** Scroll inside this height with the header held. */\n maxHeight?: number | string | undefined;\n /** Phones: `cards` (default) draws each row as a labeled record; `scroll` keeps the table. */\n mobile?: \"cards\" | \"scroll\" | undefined;\n rowClassName?: ((row: T, index: number) => string | undefined) | undefined;\n className?: string | undefined;\n}\n\n/** A column's stable id: `id`, else `accessorKey`, else its position. */\nexport function liteColumnId<T>(column: MatrxColumnDef<T>, index: number): string {\n return column.id ?? column.accessorKey ?? `col-${index}`;\n}\n\n/** A column's plain-text name. */\nexport function liteColumnLabel<T>(column: MatrxColumnDef<T>, index: number): string {\n if (column.label) return column.label;\n if (typeof column.header === \"string\") return column.header;\n return liteColumnId(column, index);\n}\n\nfunction rawValue<T>(column: MatrxColumnDef<T>, row: T): unknown {\n if (column.accessorFn) return column.accessorFn(row);\n if (column.accessorKey) return (row as Record<string, unknown>)[column.accessorKey];\n return undefined;\n}\n\nfunction hasValue<T>(column: MatrxColumnDef<T>): boolean {\n return Boolean(column.sortValue || column.accessorFn || column.accessorKey);\n}\n\nfunction isSortable<T>(column: MatrxColumnDef<T>): boolean {\n return column.sortable !== false && hasValue(column);\n}\n\nfunction sortKey<T>(column: MatrxColumnDef<T>, row: T): unknown {\n return column.sortValue ? column.sortValue(row) : rawValue(column, row);\n}\n\nfunction asText(value: unknown): string {\n if (value == null) return \"\";\n if (value instanceof Date) return value.toISOString();\n if (Array.isArray(value)) return value.map(asText).filter(Boolean).join(\", \");\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/** Null/empty last in both directions; numbers and dates by value; text naturally (2 before 10). */\nexport function compareLiteValues(a: unknown, b: unknown): number {\n const aEmpty = a == null || a === \"\";\n const bEmpty = b == null || b === \"\";\n if (aEmpty || bEmpty) return aEmpty === bEmpty ? 0 : aEmpty ? 1 : -1;\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n if (typeof a === \"boolean\" && typeof b === \"boolean\") return Number(a) - Number(b);\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();\n return asText(a).localeCompare(asText(b), undefined, { numeric: true, sensitivity: \"base\" });\n}\n\n/** Rows sorted by `sort` (a copy; stable). Unknown ids leave the order alone. */\nexport function sortLiteRows<T>(rows: T[], columns: MatrxColumnDef<T>[], sort: SortState | null | undefined): T[] {\n if (!sort) return rows;\n const index = columns.findIndex((c, i) => liteColumnId(c, i) === sort.id);\n const column = columns[index];\n if (!column || !hasValue(column)) return rows;\n const sign = sort.direction === \"desc\" ? -1 : 1;\n return rows\n .map((row, i) => ({ row, i, key: sortKey(column, row) }))\n .sort((x, y) => {\n const xEmpty = x.key == null || x.key === \"\";\n const yEmpty = y.key == null || y.key === \"\";\n // Empty values stay last whichever way the column runs.\n if (xEmpty || yEmpty) return xEmpty === yEmpty ? x.i - y.i : xEmpty ? 1 : -1;\n return compareLiteValues(x.key, y.key) * sign || x.i - y.i;\n })\n .map((x) => x.row);\n}\n\n/** What Copy puts on the clipboard for one row: \"Label: value\" per column that has a value. */\nexport function liteRowText<T>(row: T, columns: MatrxColumnDef<T>[]): string {\n return columns\n .map((column, i) => {\n if (column.hidden) return null;\n const value = column.copyValue ? column.copyValue(row) : rawValue(column, row);\n if (!column.copyValue && !column.accessorFn && !column.accessorKey) return null;\n return `${liteColumnLabel(column, i)}: ${asText(value)}`;\n })\n .filter((line): line is string => line !== null)\n .join(\"\\n\");\n}\n\nfunction nextSort(current: SortState | null, id: string, first: \"asc\" | \"desc\"): SortState | null {\n if (!current || current.id !== id) return { id, direction: first };\n if (current.direction === first) return { id, direction: first === \"asc\" ? \"desc\" : \"asc\" };\n return null;\n}\n\nfunction CopyRowButton({ text, label }: { text: string; label: string }) {\n const [copied, setCopied] = useState(false);\n return (\n <Button\n type=\"button\"\n variant=\"quiet\"\n aria-label={`Copy ${label}`}\n icon={copied ? <CheckIcon /> : <CopyIcon />}\n title=\"Copy row\"\n data-lite-copy=\"\"\n onClick={(event) => {\n event.stopPropagation();\n void copyText(text).then((ok) => {\n if (!ok) return;\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n });\n }}\n className=\"shrink-0\"\n />\n );\n}\n\nexport function LiteTable<T>({\n data,\n columns,\n getRowId,\n read,\n emptyState = { title: \"Nothing here yet\" },\n defaultSort = null,\n sort: sortProp,\n onSortChange,\n onRowOpen,\n getRowHref,\n density = \"normal\",\n selectedKey,\n copyRows = true,\n ariaLabel,\n maxHeight,\n mobile = \"cards\",\n rowClassName,\n className,\n}: LiteTableProps<T>) {\n const isMobile = useIsMobile();\n const [ownSort, setOwnSort] = useState<SortState | null>(defaultSort ?? null);\n const sort = sortProp !== undefined ? sortProp : ownSort;\n const setSort = useCallback(\n (next: SortState | null) => {\n if (sortProp === undefined) setOwnSort(next);\n onSortChange?.(next);\n },\n [sortProp, onSortChange],\n );\n const visible = useMemo(\n () => columns.map((column, index) => ({ column, index, id: liteColumnId(column, index) })).filter(({ column }) => !column.hidden),\n [columns],\n );\n const rows = useMemo(() => sortLiteRows(data, columns, sort), [data, columns, sort]);\n const bodyRef = useRef<HTMLTableSectionElement | HTMLDivElement | null>(null);\n const Link = (getTapTargetLinkComponent() ?? \"a\") as unknown as React.ComponentType<React.AnchorHTMLAttributes<HTMLAnchorElement> & { href: string; prefetch?: boolean }>;\n const registeredLink = getTapTargetLinkComponent() !== null;\n const opens = Boolean(onRowOpen || getRowHref);\n\n if (rows.length === 0) {\n return (\n <div className={className} data-lite-table=\"\" {...{ [MAC_TABLE_ATTRIBUTE]: \"\" }}>\n <ReadEmpty read={read}>\n <ListEmptyView emptyState={emptyState} />\n </ReadEmpty>\n </div>\n );\n }\n\n const open = (row: T, event: MouseEvent | KeyboardEvent, rowEl: HTMLElement) => {\n const href = getRowHref?.(row);\n const modified = \"metaKey\" in event && (event.metaKey || event.ctrlKey || event.shiftKey);\n if (href && modified) {\n openOutbound(href, \"_blank\", \"noopener\");\n return;\n }\n if (onRowOpen) {\n onRowOpen(row);\n return;\n }\n // The first column's anchor carries the host's router: following it keeps client navigation.\n if (href) rowEl.querySelector<HTMLAnchorElement>(\"a[data-lite-link]\")?.click();\n };\n\n const onRowKeyDown = (row: T) => (event: KeyboardEvent<HTMLElement>) => {\n if (event.target !== event.currentTarget) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n open(row, event, event.currentTarget);\n return;\n }\n if (event.key !== \"ArrowDown\" && event.key !== \"ArrowUp\" && event.key !== \"Home\" && event.key !== \"End\") return;\n const all = Array.from(bodyRef.current?.querySelectorAll<HTMLElement>(\"[data-lite-row]\") ?? []);\n const at = all.indexOf(event.currentTarget);\n const to =\n event.key === \"Home\" ? 0 : event.key === \"End\" ? all.length - 1 : event.key === \"ArrowDown\" ? at + 1 : at - 1;\n const target = all[Math.max(0, Math.min(all.length - 1, to))];\n if (target) {\n event.preventDefault();\n target.focus();\n }\n };\n\n const onRowClick = (row: T) => (event: MouseEvent<HTMLElement>) => {\n // A click on a control or link inside the row is that control's, never the row's.\n if ((event.target as HTMLElement).closest(\"a,button,input,select,textarea,[role=menuitem]\")) return;\n open(row, event, event.currentTarget);\n };\n\n const cellContent = (column: MatrxColumnDef<T>, row: T, rowIndex: number, first: boolean): ReactNode => {\n const content = column.cell ? column.cell(row, rowIndex) : asText(rawValue(column, row));\n const href = column.href?.(row) ?? (first ? getRowHref?.(row) : undefined);\n if (!href) return content;\n return (\n <Link\n href={href}\n data-lite-link=\"\"\n {...(registeredLink ? { prefetch: false } : {})}\n className=\"text-inherit underline-offset-2 hover:underline outline-none focus-visible:underline\"\n >\n {content}\n </Link>\n );\n };\n\n const copyCell = (row: T, rowId: string) =>\n copyRows ? <CopyRowButton text={liteRowText(row, columns)} label={rowId} /> : null;\n\n const macRoot = { [MAC_TABLE_ATTRIBUTE]: \"\", \"data-density\": density };\n\n if (isMobile && mobile === \"cards\") {\n const [titleCol, ...restCols] = visible.filter(({ column }) => !column.mobileHidden);\n return (\n <div className={cn(\"flex flex-col gap-2\", className)} data-lite-table=\"\" data-lite-layout=\"cards\" {...macRoot}>\n <ReadStaleNotice read={read} />\n <div ref={(el) => void (bodyRef.current = el)} role=\"list\" aria-label={ariaLabel} data-mac-cards=\"\" className=\"flex flex-col\">\n {rows.map((row, rowIndex) => {\n const rowId = getRowId(row);\n return (\n <div\n key={rowId}\n role=\"listitem\"\n data-lite-row=\"\"\n data-mac-card=\"\"\n data-opens={opens ? \"\" : undefined}\n data-selected={selectedKey === rowId ? \"\" : undefined}\n tabIndex={opens ? 0 : undefined}\n onClick={opens ? onRowClick(row) : undefined}\n onKeyDown={onRowKeyDown(row)}\n className={cn(\n \"group/lite-row\",\n opens && \"cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring\",\n rowClassName?.(row, rowIndex),\n )}\n >\n <div className=\"flex items-start gap-2\">\n <div className=\"min-w-0 flex-1 font-semibold\">\n {titleCol ? cellContent(titleCol.column, row, rowIndex, true) : null}\n </div>\n {copyCell(row, rowId)}\n </div>\n {restCols.length > 0 ? (\n <dl className=\"mt-1 grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5\">\n {restCols.map(({ column, index, id }) => (\n <div key={id} className=\"contents\">\n <dt data-mac-card-label=\"\">{liteColumnLabel(column, index)}</dt>\n <dd className=\"min-w-0\">{cellContent(column, row, rowIndex, false)}</dd>\n </div>\n ))}\n </dl>\n ) : null}\n </div>\n );\n })}\n </div>\n </div>\n );\n }\n\n let stripe = 0;\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-2\", className)} data-lite-table=\"\" {...macRoot}>\n <ReadStaleNotice read={read} />\n <div\n data-slot={MAC_TABLE_SLOTS.table}\n className={cn(\"min-w-0 overflow-x-auto\", maxHeight !== undefined && \"overflow-y-auto\")}\n style={maxHeight !== undefined ? { maxHeight } : undefined}\n >\n <table aria-label={ariaLabel}>\n <thead>\n <tr data-slot={MAC_TABLE_SLOTS.header}>\n {visible.map(({ column, index, id }) => {\n const sortable = isSortable(column);\n const active = sort?.id === id ? sort.direction : null;\n const label = liteColumnLabel(column, index);\n const align = column.align ?? \"left\";\n return (\n <th\n key={id}\n scope=\"col\"\n aria-sort={active === \"asc\" ? \"ascending\" : active === \"desc\" ? \"descending\" : undefined}\n data-sorted={active ? \"\" : undefined}\n data-align={align}\n title={column.helpText}\n className={cn(\n \"relative\",\n align === \"right\" ? \"text-right\" : align === \"center\" ? \"text-center\" : \"text-left\",\n column.mobileHidden && \"max-sm:hidden\",\n column.headerClassName,\n )}\n style={{\n ...(column.width !== undefined ? { width: column.width } : {}),\n ...(column.minWidth !== undefined ? { minWidth: column.minWidth } : {}),\n }}\n >\n {sortable ? (\n <Button\n type=\"button\"\n variant=\"quiet\"\n data-lite-sort={id}\n data-mac-sort=\"\"\n aria-label={`Sort by ${label}`}\n iconEnd={active ? <ChevronDownIcon aria-hidden data-mac-sort-chevron={active} className={cn(active === \"asc\" && \"rotate-180\")} /> : undefined}\n onClick={() => setSort(nextSort(sort, id, column.defaultSortDirection ?? \"asc\"))}\n className=\"h-full\"\n >\n {column.header}\n </Button>\n ) : (\n column.header\n )}\n </th>\n );\n })}\n {copyRows ? <th aria-label=\"Row actions\" className=\"w-8\" /> : null}\n </tr>\n </thead>\n <tbody ref={(el) => void (bodyRef.current = el)}>\n {rows.map((row, rowIndex) => {\n const rowId = getRowId(row);\n const striped = stripe++ % 2 === 1;\n return (\n <tr\n key={rowId}\n data-lite-row=\"\"\n data-slot={MAC_TABLE_SLOTS.row}\n data-stripe={striped ? \"\" : undefined}\n data-opens={opens ? \"\" : undefined}\n data-selected={selectedKey === rowId ? \"\" : undefined}\n aria-selected={selectedKey !== undefined ? selectedKey === rowId : undefined}\n tabIndex={opens ? 0 : undefined}\n onClick={opens ? onRowClick(row) : undefined}\n onKeyDown={onRowKeyDown(row)}\n className={cn(\"group/lite-row\", opens && \"cursor-pointer\", rowClassName?.(row, rowIndex))}\n >\n {visible.map(({ column, id }, position) => {\n const align = column.align ?? \"left\";\n return (\n <td\n key={id}\n data-mac-numeric={align === \"right\" ? \"\" : undefined}\n className={cn(\n align === \"right\" ? \"text-right\" : align === \"center\" ? \"text-center\" : \"text-left\",\n column.mobileHidden && \"max-sm:hidden\",\n column.className,\n )}\n >\n {cellContent(column, row, rowIndex, position === 0)}\n </td>\n );\n })}\n {copyRows ? <td className=\"w-8 text-right\">{copyCell(row, rowId)}</td> : null}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP,SAAS,mBAAmB;AAC5B,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AA8IR,cAwJL,YAxJK;AA7Fd,SAAS,aAAgB,QAA2B,OAAuB;AAChF,SAAO,OAAO,MAAM,OAAO,eAAe,OAAO,KAAK;AACxD;AAGO,SAAS,gBAAmB,QAA2B,OAAuB;AACnF,MAAI,OAAO,MAAO,QAAO,OAAO;AAChC,MAAI,OAAO,OAAO,WAAW,SAAU,QAAO,OAAO;AACrD,SAAO,aAAa,QAAQ,KAAK;AACnC;AAEA,SAAS,SAAY,QAA2B,KAAiB;AAC/D,MAAI,OAAO,WAAY,QAAO,OAAO,WAAW,GAAG;AACnD,MAAI,OAAO,YAAa,QAAQ,IAAgC,OAAO,WAAW;AAClF,SAAO;AACT;AAEA,SAAS,SAAY,QAAoC;AACvD,SAAO,QAAQ,OAAO,aAAa,OAAO,cAAc,OAAO,WAAW;AAC5E;AAEA,SAAS,WAAc,QAAoC;AACzD,SAAO,OAAO,aAAa,SAAS,SAAS,MAAM;AACrD;AAEA,SAAS,QAAW,QAA2B,KAAiB;AAC9D,SAAO,OAAO,YAAY,OAAO,UAAU,GAAG,IAAI,SAAS,QAAQ,GAAG;AACxE;AAEA,SAAS,OAAO,OAAwB;AACtC,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,iBAAiB,KAAM,QAAO,MAAM,YAAY;AACpD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAC5E,MAAI,OAAO,UAAU,SAAU,QAAO,KAAK,UAAU,KAAK;AAC1D,SAAO,OAAO,KAAK;AACrB;AAGO,SAAS,kBAAkB,GAAY,GAAoB;AAChE,QAAM,SAAS,KAAK,QAAQ,MAAM;AAClC,QAAM,SAAS,KAAK,QAAQ,MAAM;AAClC,MAAI,UAAU,OAAQ,QAAO,WAAW,SAAS,IAAI,SAAS,IAAI;AAClE,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO,IAAI;AAC/D,MAAI,OAAO,MAAM,aAAa,OAAO,MAAM,UAAW,QAAO,OAAO,CAAC,IAAI,OAAO,CAAC;AACjF,MAAI,aAAa,QAAQ,aAAa,KAAM,QAAO,EAAE,QAAQ,IAAI,EAAE,QAAQ;AAC3E,SAAO,OAAO,CAAC,EAAE,cAAc,OAAO,CAAC,GAAG,QAAW,EAAE,SAAS,MAAM,aAAa,OAAO,CAAC;AAC7F;AAGO,SAAS,aAAgB,MAAW,SAA8B,MAAyC;AAChH,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,QAAQ,QAAQ,UAAU,CAAC,GAAG,MAAM,aAAa,GAAG,CAAC,MAAM,KAAK,EAAE;AACxE,QAAM,SAAS,QAAQ,KAAK;AAC5B,MAAI,CAAC,UAAU,CAAC,SAAS,MAAM,EAAG,QAAO;AACzC,QAAM,OAAO,KAAK,cAAc,SAAS,KAAK;AAC9C,SAAO,KACJ,IAAI,CAAC,KAAK,OAAO,EAAE,KAAK,GAAG,KAAK,QAAQ,QAAQ,GAAG,EAAE,EAAE,EACvD,KAAK,CAAC,GAAG,MAAM;AACd,UAAM,SAAS,EAAE,OAAO,QAAQ,EAAE,QAAQ;AAC1C,UAAM,SAAS,EAAE,OAAO,QAAQ,EAAE,QAAQ;AAE1C,QAAI,UAAU,OAAQ,QAAO,WAAW,SAAS,EAAE,IAAI,EAAE,IAAI,SAAS,IAAI;AAC1E,WAAO,kBAAkB,EAAE,KAAK,EAAE,GAAG,IAAI,QAAQ,EAAE,IAAI,EAAE;AAAA,EAC3D,CAAC,EACA,IAAI,CAAC,MAAM,EAAE,GAAG;AACrB;AAGO,SAAS,YAAe,KAAQ,SAAsC;AAC3E,SAAO,QACJ,IAAI,CAAC,QAAQ,MAAM;AAClB,QAAI,OAAO,OAAQ,QAAO;AAC1B,UAAM,QAAQ,OAAO,YAAY,OAAO,UAAU,GAAG,IAAI,SAAS,QAAQ,GAAG;AAC7E,QAAI,CAAC,OAAO,aAAa,CAAC,OAAO,cAAc,CAAC,OAAO,YAAa,QAAO;AAC3E,WAAO,GAAG,gBAAgB,QAAQ,CAAC,CAAC,KAAK,OAAO,KAAK,CAAC;AAAA,EACxD,CAAC,EACA,OAAO,CAAC,SAAyB,SAAS,IAAI,EAC9C,KAAK,IAAI;AACd;AAEA,SAAS,SAAS,SAA2B,IAAY,OAAyC;AAChG,MAAI,CAAC,WAAW,QAAQ,OAAO,GAAI,QAAO,EAAE,IAAI,WAAW,MAAM;AACjE,MAAI,QAAQ,cAAc,MAAO,QAAO,EAAE,IAAI,WAAW,UAAU,QAAQ,SAAS,MAAM;AAC1F,SAAO;AACT;AAEA,SAAS,cAAc,EAAE,MAAM,MAAM,GAAoC;AACvE,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,cAAY,QAAQ,KAAK;AAAA,MACzB,MAAM,SAAS,oBAAC,aAAU,IAAK,oBAAC,YAAS;AAAA,MACzC,OAAM;AAAA,MACN,kBAAe;AAAA,MACf,SAAS,CAAC,UAAU;AAClB,cAAM,gBAAgB;AACtB,aAAK,SAAS,IAAI,EAAE,KAAK,CAAC,OAAO;AAC/B,cAAI,CAAC,GAAI;AACT,oBAAU,IAAI;AACd,qBAAW,MAAM,UAAU,KAAK,GAAG,IAAI;AAAA,QACzC,CAAC;AAAA,MACH;AAAA,MACA,WAAU;AAAA;AAAA,EACZ;AAEJ;AAEO,SAAS,UAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa,EAAE,OAAO,mBAAmB;AAAA,EACzC,cAAc;AAAA,EACd,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,WAAW,YAAY;AAC7B,QAAM,CAAC,SAAS,UAAU,IAAI,SAA2B,eAAe,IAAI;AAC5E,QAAM,OAAO,aAAa,SAAY,WAAW;AACjD,QAAM,UAAU;AAAA,IACd,CAAC,SAA2B;AAC1B,UAAI,aAAa,OAAW,YAAW,IAAI;AAC3C,qBAAe,IAAI;AAAA,IACrB;AAAA,IACA,CAAC,UAAU,YAAY;AAAA,EACzB;AACA,QAAM,UAAU;AAAA,IACd,MAAM,QAAQ,IAAI,CAAC,QAAQ,WAAW,EAAE,QAAQ,OAAO,IAAI,aAAa,QAAQ,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,MAAM,CAAC,OAAO,MAAM;AAAA,IAChI,CAAC,OAAO;AAAA,EACV;AACA,QAAM,OAAO,QAAQ,MAAM,aAAa,MAAM,SAAS,IAAI,GAAG,CAAC,MAAM,SAAS,IAAI,CAAC;AACnF,QAAM,UAAU,OAAwD,IAAI;AAC5E,QAAM,OAAQ,0BAA0B,KAAK;AAC7C,QAAM,iBAAiB,0BAA0B,MAAM;AACvD,QAAM,QAAQ,QAAQ,aAAa,UAAU;AAE7C,MAAI,KAAK,WAAW,GAAG;AACrB,WACE,oBAAC,SAAI,WAAsB,mBAAgB,IAAI,GAAG,EAAE,CAAC,mBAAmB,GAAG,GAAG,GAC5E,8BAAC,aAAU,MACT,8BAAC,iBAAc,YAAwB,GACzC,GACF;AAAA,EAEJ;AAEA,QAAM,OAAO,CAAC,KAAQ,OAAmC,UAAuB;AAC9E,UAAM,OAAO,aAAa,GAAG;AAC7B,UAAM,WAAW,aAAa,UAAU,MAAM,WAAW,MAAM,WAAW,MAAM;AAChF,QAAI,QAAQ,UAAU;AACpB,mBAAa,MAAM,UAAU,UAAU;AACvC;AAAA,IACF;AACA,QAAI,WAAW;AACb,gBAAU,GAAG;AACb;AAAA,IACF;AAEA,QAAI,KAAM,OAAM,cAAiC,mBAAmB,GAAG,MAAM;AAAA,EAC/E;AAEA,QAAM,eAAe,CAAC,QAAW,CAAC,UAAsC;AACtE,QAAI,MAAM,WAAW,MAAM,cAAe;AAC1C,QAAI,MAAM,QAAQ,SAAS;AACzB,YAAM,eAAe;AACrB,WAAK,KAAK,OAAO,MAAM,aAAa;AACpC;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,aAAa,MAAM,QAAQ,UAAU,MAAM,QAAQ,MAAO;AACzG,UAAM,MAAM,MAAM,KAAK,QAAQ,SAAS,iBAA8B,iBAAiB,KAAK,CAAC,CAAC;AAC9F,UAAM,KAAK,IAAI,QAAQ,MAAM,aAAa;AAC1C,UAAM,KACJ,MAAM,QAAQ,SAAS,IAAI,MAAM,QAAQ,QAAQ,IAAI,SAAS,IAAI,MAAM,QAAQ,cAAc,KAAK,IAAI,KAAK;AAC9G,UAAM,SAAS,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,GAAG,EAAE,CAAC,CAAC;AAC5D,QAAI,QAAQ;AACV,YAAM,eAAe;AACrB,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,QAAM,aAAa,CAAC,QAAW,CAAC,UAAmC;AAEjE,QAAK,MAAM,OAAuB,QAAQ,gDAAgD,EAAG;AAC7F,SAAK,KAAK,OAAO,MAAM,aAAa;AAAA,EACtC;AAEA,QAAM,cAAc,CAAC,QAA2B,KAAQ,UAAkB,UAA8B;AACtG,UAAM,UAAU,OAAO,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,SAAS,QAAQ,GAAG,CAAC;AACvF,UAAM,OAAO,OAAO,OAAO,GAAG,MAAM,QAAQ,aAAa,GAAG,IAAI;AAChE,QAAI,CAAC,KAAM,QAAO;AAClB,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,kBAAe;AAAA,QACd,GAAI,iBAAiB,EAAE,UAAU,MAAM,IAAI,CAAC;AAAA,QAC7C,WAAU;AAAA,QAET;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,QAAM,WAAW,CAAC,KAAQ,UACxB,WAAW,oBAAC,iBAAc,MAAM,YAAY,KAAK,OAAO,GAAG,OAAO,OAAO,IAAK;AAEhF,QAAM,UAAU,EAAE,CAAC,mBAAmB,GAAG,IAAI,gBAAgB,QAAQ;AAErE,MAAI,YAAY,WAAW,SAAS;AAClC,UAAM,CAAC,UAAU,GAAG,QAAQ,IAAI,QAAQ,OAAO,CAAC,EAAE,OAAO,MAAM,CAAC,OAAO,YAAY;AACnF,WACE,qBAAC,SAAI,WAAW,GAAG,uBAAuB,SAAS,GAAG,mBAAgB,IAAG,oBAAiB,SAAS,GAAG,SACpG;AAAA,0BAAC,mBAAgB,MAAY;AAAA,MAC7B,oBAAC,SAAI,KAAK,CAAC,OAAO,MAAM,QAAQ,UAAU,KAAK,MAAK,QAAO,cAAY,WAAW,kBAAe,IAAG,WAAU,iBAC3G,eAAK,IAAI,CAAC,KAAK,aAAa;AAC3B,cAAM,QAAQ,SAAS,GAAG;AAC1B,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,iBAAc;AAAA,YACd,iBAAc;AAAA,YACd,cAAY,QAAQ,KAAK;AAAA,YACzB,iBAAe,gBAAgB,QAAQ,KAAK;AAAA,YAC5C,UAAU,QAAQ,IAAI;AAAA,YACtB,SAAS,QAAQ,WAAW,GAAG,IAAI;AAAA,YACnC,WAAW,aAAa,GAAG;AAAA,YAC3B,WAAW;AAAA,cACT;AAAA,cACA,SAAS;AAAA,cACT,eAAe,KAAK,QAAQ;AAAA,YAC9B;AAAA,YAEA;AAAA,mCAAC,SAAI,WAAU,0BACb;AAAA,oCAAC,SAAI,WAAU,gCACZ,qBAAW,YAAY,SAAS,QAAQ,KAAK,UAAU,IAAI,IAAI,MAClE;AAAA,gBACC,SAAS,KAAK,KAAK;AAAA,iBACtB;AAAA,cACC,SAAS,SAAS,IACjB,oBAAC,QAAG,WAAU,oDACX,mBAAS,IAAI,CAAC,EAAE,QAAQ,OAAO,GAAG,MACjC,qBAAC,SAAa,WAAU,YACtB;AAAA,oCAAC,QAAG,uBAAoB,IAAI,0BAAgB,QAAQ,KAAK,GAAE;AAAA,gBAC3D,oBAAC,QAAG,WAAU,WAAW,sBAAY,QAAQ,KAAK,UAAU,KAAK,GAAE;AAAA,mBAF3D,EAGV,CACD,GACH,IACE;AAAA;AAAA;AAAA,UA9BC;AAAA,QA+BP;AAAA,MAEJ,CAAC,GACH;AAAA,OACF;AAAA,EAEJ;AAEA,MAAI,SAAS;AACb,SACE,qBAAC,SAAI,WAAW,GAAG,+BAA+B,SAAS,GAAG,mBAAgB,IAAI,GAAG,SACnF;AAAA,wBAAC,mBAAgB,MAAY;AAAA,IAC7B;AAAA,MAAC;AAAA;AAAA,QACC,aAAW,gBAAgB;AAAA,QAC3B,WAAW,GAAG,2BAA2B,cAAc,UAAa,iBAAiB;AAAA,QACrF,OAAO,cAAc,SAAY,EAAE,UAAU,IAAI;AAAA,QAEjD,+BAAC,WAAM,cAAY,WACjB;AAAA,8BAAC,WACC,+BAAC,QAAG,aAAW,gBAAgB,QAC5B;AAAA,oBAAQ,IAAI,CAAC,EAAE,QAAQ,OAAO,GAAG,MAAM;AACtC,oBAAM,WAAW,WAAW,MAAM;AAClC,oBAAM,SAAS,MAAM,OAAO,KAAK,KAAK,YAAY;AAClD,oBAAM,QAAQ,gBAAgB,QAAQ,KAAK;AAC3C,oBAAM,QAAQ,OAAO,SAAS;AAC9B,qBACE;AAAA,gBAAC;AAAA;AAAA,kBAEC,OAAM;AAAA,kBACN,aAAW,WAAW,QAAQ,cAAc,WAAW,SAAS,eAAe;AAAA,kBAC/E,eAAa,SAAS,KAAK;AAAA,kBAC3B,cAAY;AAAA,kBACZ,OAAO,OAAO;AAAA,kBACd,WAAW;AAAA,oBACT;AAAA,oBACA,UAAU,UAAU,eAAe,UAAU,WAAW,gBAAgB;AAAA,oBACxE,OAAO,gBAAgB;AAAA,oBACvB,OAAO;AAAA,kBACT;AAAA,kBACA,OAAO;AAAA,oBACL,GAAI,OAAO,UAAU,SAAY,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,oBAC5D,GAAI,OAAO,aAAa,SAAY,EAAE,UAAU,OAAO,SAAS,IAAI,CAAC;AAAA,kBACvE;AAAA,kBAEC,qBACC;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,SAAQ;AAAA,sBACR,kBAAgB;AAAA,sBAChB,iBAAc;AAAA,sBACd,cAAY,WAAW,KAAK;AAAA,sBAC5B,SAAS,SAAS,oBAAC,mBAAgB,eAAW,MAAC,yBAAuB,QAAQ,WAAW,GAAG,WAAW,SAAS,YAAY,GAAG,IAAK;AAAA,sBACpI,SAAS,MAAM,QAAQ,SAAS,MAAM,IAAI,OAAO,wBAAwB,KAAK,CAAC;AAAA,sBAC/E,WAAU;AAAA,sBAET,iBAAO;AAAA;AAAA,kBACV,IAEA,OAAO;AAAA;AAAA,gBA/BJ;AAAA,cAiCP;AAAA,YAEJ,CAAC;AAAA,YACA,WAAW,oBAAC,QAAG,cAAW,eAAc,WAAU,OAAM,IAAK;AAAA,aAChE,GACF;AAAA,UACA,oBAAC,WAAM,KAAK,CAAC,OAAO,MAAM,QAAQ,UAAU,KACzC,eAAK,IAAI,CAAC,KAAK,aAAa;AAC3B,kBAAM,QAAQ,SAAS,GAAG;AAC1B,kBAAM,UAAU,WAAW,MAAM;AACjC,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,iBAAc;AAAA,gBACd,aAAW,gBAAgB;AAAA,gBAC3B,eAAa,UAAU,KAAK;AAAA,gBAC5B,cAAY,QAAQ,KAAK;AAAA,gBACzB,iBAAe,gBAAgB,QAAQ,KAAK;AAAA,gBAC5C,iBAAe,gBAAgB,SAAY,gBAAgB,QAAQ;AAAA,gBACnE,UAAU,QAAQ,IAAI;AAAA,gBACtB,SAAS,QAAQ,WAAW,GAAG,IAAI;AAAA,gBACnC,WAAW,aAAa,GAAG;AAAA,gBAC3B,WAAW,GAAG,kBAAkB,SAAS,kBAAkB,eAAe,KAAK,QAAQ,CAAC;AAAA,gBAEvF;AAAA,0BAAQ,IAAI,CAAC,EAAE,QAAQ,GAAG,GAAG,aAAa;AACzC,0BAAM,QAAQ,OAAO,SAAS;AAC9B,2BACE;AAAA,sBAAC;AAAA;AAAA,wBAEC,oBAAkB,UAAU,UAAU,KAAK;AAAA,wBAC3C,WAAW;AAAA,0BACT,UAAU,UAAU,eAAe,UAAU,WAAW,gBAAgB;AAAA,0BACxE,OAAO,gBAAgB;AAAA,0BACvB,OAAO;AAAA,wBACT;AAAA,wBAEC,sBAAY,QAAQ,KAAK,UAAU,aAAa,CAAC;AAAA;AAAA,sBAR7C;AAAA,oBASP;AAAA,kBAEJ,CAAC;AAAA,kBACA,WAAW,oBAAC,QAAG,WAAU,kBAAkB,mBAAS,KAAK,KAAK,GAAE,IAAQ;AAAA;AAAA;AAAA,cA5BpE;AAAA,YA6BP;AAAA,UAEJ,CAAC,GACH;AAAA,WACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/lite-table/LiteTable.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * LiteTable — THE LIGHT SORTABLE TABLE (2026-10-17, Arman: \"so there is no\n * excuse for creating hand-rolled versions in the app\").\n *\n * For a small, fully loaded set (up to a few hundred rows) where the full\n * `MatrxDataTable` is more than the page needs: declared columns, click-to-sort\n * headers, the honest read states, a row that opens or links, copy a row, two\n * densities, and a phone layout (each row a labeled record).\n *\n * It takes the SAME `MatrxColumnDef<T>` and the same core props as\n * `MatrxDataTable` (`data`, `columns`, `getRowId`, `read`, `emptyState`,\n * `defaultSort`, `onRowOpen`, `getRowHref`, `density`, `rowClassName`), so a\n * page graduates to the full table by changing one import. Column fields it\n * does not draw (filters, editing, pinning, KPIs …) are ignored, never wrong.\n *\n * It imports only TYPES from the data table: the bundle never carries the grid\n * (guarded by `scripts/section-isolation.json`).\n *\n * THE MAC TABLE (2026-10-17, Arman: \"I love the mac table\"): it draws the desktop app's\n * `DataTable` — NSTableView's 24 pt rows under a 22 pt header, 13 pt, stripes, hairlines, the\n * accent selection — from the same `data-slot` vocabulary and the same values\n * (`../mac-table/tokens.ts`, drawn by `mac-table.css`; `mac-table-parity.test.ts` keeps them equal).\n */\n\nimport {\n useCallback,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n} from \"react\";\nimport { useIsMobile } from \"@ai-matrx/kit/media-query\";\nimport { copyText } from \"@ai-matrx/kit/clipboard\";\nimport { openOutbound } from \"@ai-matrx/kit/outbound\";\nimport type {\n MatrxColumnDef,\n MatrxDataTableDensity,\n MatrxDataTableEmptyState,\n SortState,\n} from \"../data-table/types\";\nimport { ReadEmpty, ReadStaleNotice, type ReadOutcome } from \"../read-state/read-gate\";\nimport { ListEmptyView } from \"../read-state/list-empty-view\";\nimport { getTapTargetLinkComponent } from \"../tap-target/link\";\nimport { cn } from \"../cn\";\nimport { Button } from \"../controls/controls\";\nimport { ChevronDownIcon, CheckIcon, CopyIcon } from \"../icons\";\nimport { MAC_TABLE_ATTRIBUTE, MAC_TABLE_SLOTS } from \"../mac-table/tokens\";\n\nexport interface LiteTableProps<T> {\n data: T[];\n columns: MatrxColumnDef<T>[];\n getRowId: (row: T) => string;\n /** The read behind `data`: the empty view shows only after a read that succeeded. */\n read?: ReadOutcome | undefined;\n /** Shown after a successful read with no rows. The full table's object form, or any node. */\n emptyState?: MatrxDataTableEmptyState | ReactNode;\n /** First sort (uncontrolled). */\n defaultSort?: SortState | null | undefined;\n /** Controlled sort. */\n sort?: SortState | null | undefined;\n onSortChange?: ((sort: SortState | null) => void) | undefined;\n /** Plain row click / Enter. */\n onRowOpen?: ((row: T) => void) | undefined;\n /** The row's page: its first column becomes a real link; a plain row click follows it. */\n getRowHref?: ((row: T) => string | undefined) | undefined;\n /** `condensed` (Finder's 20 pt rows) · `normal` (AppKit's 24 pt, default) · `spacious` (36 pt). */\n density?: MatrxDataTableDensity | undefined;\n /** The current row (drawn selected: gray, the accent while the table has focus). */\n selectedKey?: string | null | undefined;\n /** A copy button on each row (its visible values, one \"Label: value\" per line). Default true. */\n copyRows?: boolean | undefined;\n /** Accessible name of the table. */\n ariaLabel?: string | undefined;\n /** Scroll inside this height with the header held. */\n maxHeight?: number | string | undefined;\n /** Phones: `cards` (default) draws each row as a labeled record; `scroll` keeps the table. */\n mobile?: \"cards\" | \"scroll\" | undefined;\n rowClassName?: ((row: T, index: number) => string | undefined) | undefined;\n className?: string | undefined;\n}\n\n/** A column's stable id: `id`, else `accessorKey`, else its position. */\nexport function liteColumnId<T>(column: MatrxColumnDef<T>, index: number): string {\n return column.id ?? column.accessorKey ?? `col-${index}`;\n}\n\n/** A column's plain-text name. */\nexport function liteColumnLabel<T>(column: MatrxColumnDef<T>, index: number): string {\n if (column.label) return column.label;\n if (typeof column.header === \"string\") return column.header;\n return liteColumnId(column, index);\n}\n\nfunction rawValue<T>(column: MatrxColumnDef<T>, row: T): unknown {\n if (column.accessorFn) return column.accessorFn(row);\n if (column.accessorKey) return (row as Record<string, unknown>)[column.accessorKey];\n return undefined;\n}\n\nfunction hasValue<T>(column: MatrxColumnDef<T>): boolean {\n return Boolean(column.sortValue || column.accessorFn || column.accessorKey);\n}\n\nfunction isSortable<T>(column: MatrxColumnDef<T>): boolean {\n return column.sortable !== false && hasValue(column);\n}\n\nfunction sortKey<T>(column: MatrxColumnDef<T>, row: T): unknown {\n return column.sortValue ? column.sortValue(row) : rawValue(column, row);\n}\n\nfunction asText(value: unknown): string {\n if (value == null) return \"\";\n if (value instanceof Date) return value.toISOString();\n if (Array.isArray(value)) return value.map(asText).filter(Boolean).join(\", \");\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/** Null/empty last in both directions; numbers and dates by value; text naturally (2 before 10). */\nexport function compareLiteValues(a: unknown, b: unknown): number {\n const aEmpty = a == null || a === \"\";\n const bEmpty = b == null || b === \"\";\n if (aEmpty || bEmpty) return aEmpty === bEmpty ? 0 : aEmpty ? 1 : -1;\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n if (typeof a === \"boolean\" && typeof b === \"boolean\") return Number(a) - Number(b);\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();\n return asText(a).localeCompare(asText(b), undefined, { numeric: true, sensitivity: \"base\" });\n}\n\n/** Rows sorted by `sort` (a copy; stable). Unknown ids leave the order alone. */\nexport function sortLiteRows<T>(rows: T[], columns: MatrxColumnDef<T>[], sort: SortState | null | undefined): T[] {\n if (!sort) return rows;\n const index = columns.findIndex((c, i) => liteColumnId(c, i) === sort.id);\n const column = columns[index];\n if (!column || !hasValue(column)) return rows;\n const sign = sort.direction === \"desc\" ? -1 : 1;\n return rows\n .map((row, i) => ({ row, i, key: sortKey(column, row) }))\n .sort((x, y) => {\n const xEmpty = x.key == null || x.key === \"\";\n const yEmpty = y.key == null || y.key === \"\";\n // Empty values stay last whichever way the column runs.\n if (xEmpty || yEmpty) return xEmpty === yEmpty ? x.i - y.i : xEmpty ? 1 : -1;\n return compareLiteValues(x.key, y.key) * sign || x.i - y.i;\n })\n .map((x) => x.row);\n}\n\n/** What Copy puts on the clipboard for one row: \"Label: value\" per column that has a value. */\nexport function liteRowText<T>(row: T, columns: MatrxColumnDef<T>[]): string {\n return columns\n .map((column, i) => {\n if (column.hidden) return null;\n const value = column.copyValue ? column.copyValue(row) : rawValue(column, row);\n if (!column.copyValue && !column.accessorFn && !column.accessorKey) return null;\n return `${liteColumnLabel(column, i)}: ${asText(value)}`;\n })\n .filter((line): line is string => line !== null)\n .join(\"\\n\");\n}\n\nfunction nextSort(current: SortState | null, id: string, first: \"asc\" | \"desc\"): SortState | null {\n if (!current || current.id !== id) return { id, direction: first };\n if (current.direction === first) return { id, direction: first === \"asc\" ? \"desc\" : \"asc\" };\n return null;\n}\n\nfunction CopyRowButton({ text, label }: { text: string; label: string }) {\n const [copied, setCopied] = useState(false);\n return (\n <Button\n type=\"button\"\n variant=\"quiet\"\n aria-label={`Copy ${label}`}\n icon={copied ? <CheckIcon /> : <CopyIcon />}\n title=\"Copy row\"\n data-lite-copy=\"\"\n onClick={(event) => {\n event.stopPropagation();\n void copyText(text).then((ok) => {\n if (!ok) return;\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n });\n }}\n className=\"shrink-0\"\n />\n );\n}\n\nexport function LiteTable<T>({\n data,\n columns,\n getRowId,\n read,\n emptyState = { title: \"Nothing here yet\" },\n defaultSort = null,\n sort: sortProp,\n onSortChange,\n onRowOpen,\n getRowHref,\n density = \"normal\",\n selectedKey,\n copyRows = true,\n ariaLabel,\n maxHeight,\n mobile = \"cards\",\n rowClassName,\n className,\n}: LiteTableProps<T>) {\n const isMobile = useIsMobile();\n const [ownSort, setOwnSort] = useState<SortState | null>(defaultSort ?? null);\n const sort = sortProp !== undefined ? sortProp : ownSort;\n const setSort = useCallback(\n (next: SortState | null) => {\n if (sortProp === undefined) setOwnSort(next);\n onSortChange?.(next);\n },\n [sortProp, onSortChange],\n );\n const visible = useMemo(\n () => columns.map((column, index) => ({ column, index, id: liteColumnId(column, index) })).filter(({ column }) => !column.hidden),\n [columns],\n );\n const rows = useMemo(() => sortLiteRows(data, columns, sort), [data, columns, sort]);\n const bodyRef = useRef<HTMLTableSectionElement | HTMLDivElement | null>(null);\n const Link = (getTapTargetLinkComponent() ?? \"a\") as unknown as React.ComponentType<React.AnchorHTMLAttributes<HTMLAnchorElement> & { href: string; prefetch?: boolean }>;\n const registeredLink = getTapTargetLinkComponent() !== null;\n const opens = Boolean(onRowOpen || getRowHref);\n\n if (rows.length === 0) {\n return (\n <div className={className} data-lite-table=\"\" {...{ [MAC_TABLE_ATTRIBUTE]: \"\" }}>\n <ReadEmpty read={read}>\n <ListEmptyView emptyState={emptyState} />\n </ReadEmpty>\n </div>\n );\n }\n\n const open = (row: T, event: MouseEvent | KeyboardEvent, rowEl: HTMLElement) => {\n const href = getRowHref?.(row);\n const modified = \"metaKey\" in event && (event.metaKey || event.ctrlKey || event.shiftKey);\n if (href && modified) {\n openOutbound(href, \"_blank\", \"noopener\");\n return;\n }\n if (onRowOpen) {\n onRowOpen(row);\n return;\n }\n // The first column's anchor carries the host's router: following it keeps client navigation.\n if (href) rowEl.querySelector<HTMLAnchorElement>(\"a[data-lite-link]\")?.click();\n };\n\n const onRowKeyDown = (row: T) => (event: KeyboardEvent<HTMLElement>) => {\n if (event.target !== event.currentTarget) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n open(row, event, event.currentTarget);\n return;\n }\n if (event.key !== \"ArrowDown\" && event.key !== \"ArrowUp\" && event.key !== \"Home\" && event.key !== \"End\") return;\n const all = Array.from(bodyRef.current?.querySelectorAll<HTMLElement>(\"[data-lite-row]\") ?? []);\n const at = all.indexOf(event.currentTarget);\n const to =\n event.key === \"Home\" ? 0 : event.key === \"End\" ? all.length - 1 : event.key === \"ArrowDown\" ? at + 1 : at - 1;\n const target = all[Math.max(0, Math.min(all.length - 1, to))];\n if (target) {\n event.preventDefault();\n target.focus();\n }\n };\n\n const onRowClick = (row: T) => (event: MouseEvent<HTMLElement>) => {\n // A click on a control or link inside the row is that control's, never the row's.\n if ((event.target as HTMLElement).closest(\"a,button,input,select,textarea,[role=menuitem]\")) return;\n open(row, event, event.currentTarget);\n };\n\n const cellContent = (column: MatrxColumnDef<T>, row: T, rowIndex: number, first: boolean): ReactNode => {\n const content = column.cell ? column.cell(row, rowIndex) : asText(rawValue(column, row));\n const href = column.href?.(row) ?? (first ? getRowHref?.(row) : undefined);\n if (!href) return content;\n return (\n <Link\n href={href}\n data-lite-link=\"\"\n {...(registeredLink ? { prefetch: false } : {})}\n className=\"text-inherit underline-offset-2 hover:underline outline-none focus-visible:underline\"\n >\n {content}\n </Link>\n );\n };\n\n const copyCell = (row: T, rowId: string) =>\n copyRows ? <CopyRowButton text={liteRowText(row, columns)} label={rowId} /> : null;\n\n const macRoot = { [MAC_TABLE_ATTRIBUTE]: \"\", \"data-density\": density };\n\n if (isMobile && mobile === \"cards\") {\n const [titleCol, ...restCols] = visible.filter(({ column }) => !column.mobileHidden);\n return (\n <div className={cn(\"flex flex-col gap-2\", className)} data-lite-table=\"\" data-lite-layout=\"cards\" {...macRoot}>\n <ReadStaleNotice read={read} />\n <div ref={(el) => void (bodyRef.current = el)} role=\"list\" aria-label={ariaLabel} data-mac-cards=\"\" className=\"flex flex-col\">\n {rows.map((row, rowIndex) => {\n const rowId = getRowId(row);\n return (\n <div\n key={rowId}\n role=\"listitem\"\n data-lite-row=\"\"\n data-mac-card=\"\"\n data-opens={opens ? \"\" : undefined}\n data-selected={selectedKey === rowId ? \"\" : undefined}\n tabIndex={opens ? 0 : undefined}\n onClick={opens ? onRowClick(row) : undefined}\n onKeyDown={onRowKeyDown(row)}\n className={cn(\n \"group/lite-row\",\n opens && \"cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring\",\n rowClassName?.(row, rowIndex),\n )}\n >\n <div className=\"flex items-start gap-2\">\n <div className=\"min-w-0 flex-1 font-semibold\">\n {titleCol ? cellContent(titleCol.column, row, rowIndex, true) : null}\n </div>\n {copyCell(row, rowId)}\n </div>\n {restCols.length > 0 ? (\n <dl className=\"mt-1 grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5\">\n {restCols.map(({ column, index, id }) => (\n <div key={id} className=\"contents\">\n <dt data-mac-card-label=\"\">{liteColumnLabel(column, index)}</dt>\n <dd className=\"min-w-0\">{cellContent(column, row, rowIndex, false)}</dd>\n </div>\n ))}\n </dl>\n ) : null}\n </div>\n );\n })}\n </div>\n </div>\n );\n }\n\n let stripe = 0;\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-2\", className)} data-lite-table=\"\" {...macRoot}>\n <ReadStaleNotice read={read} />\n <div\n data-slot={MAC_TABLE_SLOTS.table}\n className={cn(\"min-w-0 overflow-x-auto\", maxHeight !== undefined && \"overflow-y-auto\")}\n style={maxHeight !== undefined ? { maxHeight } : undefined}\n >\n <table aria-label={ariaLabel}>\n <thead>\n <tr data-slot={MAC_TABLE_SLOTS.header}>\n {visible.map(({ column, index, id }) => {\n const sortable = isSortable(column);\n const active = sort?.id === id ? sort.direction : null;\n const label = liteColumnLabel(column, index);\n const align = column.align ?? \"left\";\n return (\n <th\n key={id}\n scope=\"col\"\n aria-sort={active === \"asc\" ? \"ascending\" : active === \"desc\" ? \"descending\" : undefined}\n data-sorted={active ? \"\" : undefined}\n data-align={align}\n title={column.helpText}\n className={cn(\n \"relative\",\n align === \"right\" ? \"text-right\" : align === \"center\" ? \"text-center\" : \"text-left\",\n column.mobileHidden && \"max-sm:hidden\",\n column.headerClassName,\n )}\n style={{\n ...(column.width !== undefined ? { width: column.width } : {}),\n ...(column.minWidth !== undefined ? { minWidth: column.minWidth } : {}),\n }}\n >\n {sortable ? (\n <Button\n type=\"button\"\n variant=\"quiet\"\n data-lite-sort={id}\n data-mac-sort=\"\"\n aria-label={`Sort by ${label}`}\n iconEnd={active ? <ChevronDownIcon aria-hidden data-mac-sort-chevron={active} className={cn(active === \"asc\" && \"rotate-180\")} /> : undefined}\n onClick={() => setSort(nextSort(sort, id, column.defaultSortDirection ?? \"asc\"))}\n className=\"h-full\"\n >\n {column.header}\n </Button>\n ) : (\n column.header\n )}\n </th>\n );\n })}\n {copyRows ? <th aria-label=\"Row actions\" className=\"w-8\" /> : null}\n </tr>\n </thead>\n <tbody ref={(el) => void (bodyRef.current = el)}>\n {rows.map((row, rowIndex) => {\n const rowId = getRowId(row);\n const striped = stripe++ % 2 === 1;\n return (\n <tr\n key={rowId}\n data-lite-row=\"\"\n data-slot={MAC_TABLE_SLOTS.row}\n data-stripe={striped ? \"\" : undefined}\n data-opens={opens ? \"\" : undefined}\n data-selected={selectedKey === rowId ? \"\" : undefined}\n aria-selected={selectedKey !== undefined ? selectedKey === rowId : undefined}\n tabIndex={opens ? 0 : undefined}\n onClick={opens ? onRowClick(row) : undefined}\n onKeyDown={onRowKeyDown(row)}\n className={cn(\"group/lite-row\", opens && \"cursor-pointer\", rowClassName?.(row, rowIndex))}\n >\n {visible.map(({ column, id }, position) => {\n const align = column.align ?? \"left\";\n return (\n <td\n key={id}\n data-mac-numeric={align === \"right\" ? \"\" : undefined}\n className={cn(\n align === \"right\" ? \"text-right\" : align === \"center\" ? \"text-center\" : \"text-left\",\n column.mobileHidden && \"max-sm:hidden\",\n column.className,\n )}\n >\n {cellContent(column, row, rowIndex, position === 0)}\n </td>\n );\n })}\n {copyRows ? <td className=\"w-8 text-right\">{copyCell(row, rowId)}</td> : null}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/menu-look.cjs
CHANGED
|
@@ -429,7 +429,7 @@ var DropdownMenuSubTrigger = React5.forwardRef(({ className, inset, children, ..
|
|
|
429
429
|
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
430
430
|
var DropdownMenuSubContent = React5.forwardRef(({ className, container, surface = "default", sideOffset = 2, alignOffset = -4, collisionPadding, onFocusOutside, children, ...props }, ref) => {
|
|
431
431
|
const portalContainer = usePortalContainer(container);
|
|
432
|
-
const [bottomClearance] = React5.useState(
|
|
432
|
+
const [bottomClearance] = React5.useState(sharedBottomClearance);
|
|
433
433
|
const padding = menuCollisionPadding(collisionPadding ?? 8, 0, bottomClearance);
|
|
434
434
|
const nested = useNestedSubmenuPlacement(ref, padding);
|
|
435
435
|
const keep = useSubmenuSurvivesParentPanelFocus(nested.ref, onFocusOutside);
|
|
@@ -451,18 +451,27 @@ var DropdownMenuSubContent = React5.forwardRef(({ className, container, surface
|
|
|
451
451
|
) });
|
|
452
452
|
});
|
|
453
453
|
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
454
|
-
function readTopClearance() {
|
|
455
|
-
return readClearance("var(--matrx-floating-top-clearance, var(--shell-header-h, 0px))");
|
|
456
|
-
}
|
|
457
|
-
function readBottomClearance() {
|
|
458
|
-
return readClearance("var(--matrx-floating-clearance, 0px)");
|
|
459
|
-
}
|
|
460
454
|
function menuCollisionPadding(caller, top, bottom, fallback = 0) {
|
|
461
455
|
const side = (key) => typeof caller === "number" ? caller : caller?.[key] ?? fallback;
|
|
462
456
|
return { top: Math.max(side("top"), top), right: side("right"), bottom: Math.max(side("bottom"), bottom), left: side("left") };
|
|
463
457
|
}
|
|
464
|
-
|
|
458
|
+
var CLEARANCE_REUSE_MS = 500;
|
|
459
|
+
var clearanceCache = /* @__PURE__ */ new Map();
|
|
460
|
+
var clock = () => typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
461
|
+
function readClearance(height, shared = false) {
|
|
465
462
|
if (typeof document === "undefined") return 0;
|
|
463
|
+
const now = clock();
|
|
464
|
+
const held = shared ? clearanceCache.get(height) : void 0;
|
|
465
|
+
if (held && now - held.at < CLEARANCE_REUSE_MS) return held.px;
|
|
466
|
+
const px = measureClearance(height);
|
|
467
|
+
clearanceCache.set(height, { px, at: now });
|
|
468
|
+
return px;
|
|
469
|
+
}
|
|
470
|
+
var TOP_CLEARANCE = "var(--matrx-floating-top-clearance, var(--shell-header-h, 0px))";
|
|
471
|
+
var BOTTOM_CLEARANCE = "var(--matrx-floating-clearance, 0px)";
|
|
472
|
+
var sharedTopClearance = () => readClearance(TOP_CLEARANCE, true);
|
|
473
|
+
var sharedBottomClearance = () => readClearance(BOTTOM_CLEARANCE, true);
|
|
474
|
+
function measureClearance(height) {
|
|
466
475
|
const probe = document.createElement("div");
|
|
467
476
|
probe.style.cssText = `position:fixed;top:0;left:0;width:0;visibility:hidden;pointer-events:none;height:${height}`;
|
|
468
477
|
document.body.appendChild(probe);
|
|
@@ -472,8 +481,8 @@ function readClearance(height) {
|
|
|
472
481
|
}
|
|
473
482
|
var DropdownMenuContent = React5.forwardRef(({ className, sideOffset = 4, container, surface = "default", children, onCloseAutoFocus, collisionPadding, ...props }, ref) => {
|
|
474
483
|
const portalContainer = usePortalContainer(container);
|
|
475
|
-
const [topClearance] = React5.useState(
|
|
476
|
-
const [bottomClearance] = React5.useState(
|
|
484
|
+
const [topClearance] = React5.useState(sharedTopClearance);
|
|
485
|
+
const [bottomClearance] = React5.useState(sharedBottomClearance);
|
|
477
486
|
const edges = useMenuScrollEdges(ref);
|
|
478
487
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DropdownMenuPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
479
488
|
DropdownMenuPrimitive.Content,
|