@ngrok/mantle 0.68.2 → 0.68.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.js","names":["Table","Row"],"sources":["../src/components/data-table/helpers.ts","../src/components/data-table/data-table.tsx"],"sourcesContent":["import type { SortingMode } from \"../../utils/sorting/direction.js\";\nimport type { SortDirection } from \"./types.js\";\n\nconst alphanumericSortingOrder = [\"unsorted\", \"asc\", \"desc\"] as const satisfies SortDirection[];\n\nconst timeSortingOrder = [\"unsorted\", \"desc\", \"asc\"] as const satisfies SortDirection[];\n\n/**\n * Get the next sort direction based on the current sort direction and sorting mode.\n */\nfunction getNextSortDirection(currentSortDirection: SortDirection, sortingMode: SortingMode) {\n\tconst sortOrder = sortingMode === \"alphanumeric\" ? alphanumericSortingOrder : timeSortingOrder;\n\n\treturn getNextInCircularList(sortOrder, currentSortDirection) ?? \"unsorted\";\n}\n\n/**\n * Get the next item in a circular list.\n * If the current item is not found in the list (or it's empty), return the fallback value.\n */\nfunction getNextInCircularList<T>(list: T[], currentItem: T, fallback?: T | undefined) {\n\tif (list.length === 0) {\n\t\treturn fallback;\n\t}\n\n\tconst currentItemIndex = list.findIndex((item) => item === currentItem);\n\tif (currentItemIndex === -1) {\n\t\treturn fallback;\n\t}\n\n\tconst nextIndex = (currentItemIndex + 1) % list.length;\n\treturn list.at(nextIndex) ?? fallback;\n}\n\nexport {\n\t//,\n\tgetNextSortDirection,\n\tgetNextInCircularList,\n};\n","import {\n\ttype Column,\n\ttype HeaderContext,\n\ttype Table as TableInstance,\n\ttype Row as TableRow,\n\tflexRender,\n} from \"@tanstack/react-table\";\nimport {\n\ttype ComponentProps,\n\tFragment,\n\ttype ReactNode,\n\tcreateContext,\n\tuseContext,\n\tuseMemo,\n} from \"react\";\nimport invariant from \"tiny-invariant\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { $timeSortingDirection, type SortingMode } from \"../../utils/sorting/direction.js\";\nimport { Button } from \"../button/button.js\";\nimport type { SvgAttributes } from \"../icon/types.js\";\nimport { SortIcon } from \"../icons/sort.js\";\nimport { Table } from \"../table/table.js\";\nimport { getNextSortDirection } from \"./helpers.js\";\nimport type { SortDirection } from \"./types.js\";\n\ntype DataTableContextShape<TData = unknown> = {\n\ttable: TableInstance<TData>;\n};\n\n// oxlint-disable-next-line typescript/no-explicit-any - known limitation of react context when using generics 😭\nconst DataTableContext = createContext<DataTableContextShape<any> | null>(null);\n\n/**\n * @private\n */\nfunction useDataTableContext<TData>() {\n\tconst context = useContext(DataTableContext);\n\n\tinvariant(context, \"useDataTableContext should only be used within a DataTable child component\");\n\n\treturn context as DataTableContextShape<TData>;\n}\n\ntype DataTableProps<TData> = ComponentProps<typeof Table.Root> & {\n\ttable: TableInstance<TData>;\n};\n\n/**\n * A data table component that provides sorting and other data table functionality.\n * Built on top of TanStack Table for advanced table features.\n *\n * @see https://mantle.ngrok.com/components/data-table#datatableroot\n *\n * @example\n * ```tsx\n * <DataTable table={table}>\n * <DataTable.Head />\n * <DataTable.Body>\n * <DataTable.Rows />\n * </DataTable.Body>\n * </DataTable>\n * ```\n */\nfunction Root<TData>({ children, table, ...props }: DataTableProps<TData>) {\n\tconst context: DataTableContextShape<TData> = useMemo(() => ({ table }), [table]);\n\n\treturn (\n\t\t<DataTableContext.Provider value={context}>\n\t\t\t<Table.Root {...props}>\n\t\t\t\t<Table.Element>{children}</Table.Element>\n\t\t\t</Table.Root>\n\t\t</DataTableContext.Provider>\n\t);\n}\n\ntype DataTableHeaderSortButtonProps<TData, TValue> = Omit<ComponentProps<typeof Button>, \"icon\"> &\n\tPick<HeaderContext<TData, TValue>, \"column\"> &\n\t(\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * Disable sorting for this column.\n\t\t\t\t * It will prevent the sorting direction from being toggled and any icon\n\t\t\t\t * from being shown.\n\t\t\t\t */\n\t\t\t\tdisableSorting: true;\n\t\t\t\t/**\n\t\t\t\t * Use this to render a custom sort icon for the column if it is sortable\n\t\t\t\t * and you want to override the default sort icon\n\t\t\t\t */\n\t\t\t\tsortIcon?: undefined;\n\t\t\t\t/**\n\t\t\t\t * The sorting mode of the column, whether it is alphanumeric or time based.\n\t\t\t\t */\n\t\t\t\tsortingMode?: undefined;\n\t\t }\n\t\t| {\n\t\t\t\tdisableSorting?: false;\n\t\t\t\t/**\n\t\t\t\t * Use this to render a custom sort icon for the column if it is sortable\n\t\t\t\t * and you want to override the default sort icon\n\t\t\t\t */\n\t\t\t\tsortIcon?: (sortDirection: SortDirection) => ReactNode;\n\t\t\t\t/**\n\t\t\t\t * The sorting mode of the column, whether it is alphanumeric or time based.\n\t\t\t\t */\n\t\t\t\tsortingMode: SortingMode;\n\t\t }\n\t);\n\n/**\n * A sortable button toggle for a column header in a data table.\n * If the column is sortable, clicking the button will toggle the sorting\n * direction.\n *\n * @see https://mantle.ngrok.com/components/data-table#datatableheadersortbutton\n *\n * @example\n * ```tsx\n * <DataTable.HeaderSortButton\n * column={column}\n * sortingMode=\"alphanumeric\"\n * >\n * Column Title\n * </DataTable.HeaderSortButton>\n * ```\n *\n * Each click cycles through:\n * - For alphanumeric sorting: unsorted ➡️ ascending ➡️ descending ➡️ unsorted\n * - For time sorting: unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted\n */\nfunction HeaderSortButton<TData, TValue>({\n\tchildren,\n\tclassName,\n\tcolumn,\n\tdisableSorting = false,\n\ticonPlacement = \"end\",\n\tsortingMode,\n\tsortIcon: propSortIcon,\n\tonClick,\n\t...props\n}: DataTableHeaderSortButtonProps<TData, TValue>) {\n\tconst _sortDirection = column.getIsSorted();\n\tconst canSort = !disableSorting && column.getCanSort();\n\n\tconst sortDirection: SortDirection =\n\t\tcanSort && typeof _sortDirection === \"string\" ? _sortDirection : \"unsorted\";\n\n\tconst sortIcon = propSortIcon?.(sortDirection) ?? (\n\t\t<DefaultSortIcon mode={sortingMode} direction={sortDirection} />\n\t);\n\n\treturn (\n\t\t<Button\n\t\t\tappearance=\"ghost\"\n\t\t\tclassName={cx(\n\t\t\t\t\"flex justify-start w-full h-full rounded-none not-disabled:active:scale-none text-muted\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tdata-sort-direction={sortDirection}\n\t\t\tdata-table-header-action\n\t\t\ticon={sortIcon}\n\t\t\ticonPlacement={iconPlacement}\n\t\t\tonClick={(event) => {\n\t\t\t\tonClick?.(event);\n\t\t\t\tif (event.defaultPrevented) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!canSort || disableSorting || typeof sortingMode === \"undefined\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttoggleNextSortingDirection(column, sortingMode);\n\t\t\t}}\n\t\t\tpriority=\"neutral\"\n\t\t\ttype=\"button\"\n\t\t\t{...props}\n\t\t>\n\t\t\t{canSort && sortDirection !== \"unsorted\" && (\n\t\t\t\t<span className=\"sr-only\">\n\t\t\t\t\tColumn sorted in{\" \"}\n\t\t\t\t\t{sortingMode === \"alphanumeric\"\n\t\t\t\t\t\t? sortDirection === \"asc\"\n\t\t\t\t\t\t\t? \"ascending\"\n\t\t\t\t\t\t\t: \"descending\"\n\t\t\t\t\t\t: $timeSortingDirection(sortDirection)}{\" \"}\n\t\t\t\t\torder\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t{children}\n\t\t</Button>\n\t);\n}\n\ntype DataTableHeaderProps = ComponentProps<typeof Table.Header>;\n\n/**\n * A header for a data table.\n * This is typically used to wrap the `DataTable.HeaderSortButton` component.\n *\n * @see https://mantle.ngrok.com/components/data-table#datatableheader\n *\n * @example\n * ```tsx\n * <DataTable.Header>\n * <DataTable.HeaderSortButton column={column} sortingMode=\"alphanumeric\">\n * Column Title\n * </DataTable.HeaderSortButton>\n * </DataTable.Header>\n * ```\n */\nfunction Header({ children, className, ...props }: DataTableHeaderProps) {\n\treturn (\n\t\t<Table.Header className={cx(\"has-data-table-header-action:px-0\", className)} {...props}>\n\t\t\t{children}\n\t\t</Table.Header>\n\t);\n}\n\nconst Body = Table.Body;\nBody.displayName = \"DataTableBody\";\n\ntype DataTableHeadProps = Omit<ComponentProps<typeof Table.Head>, \"children\">;\n\nfunction Head<TData>(props: DataTableHeadProps) {\n\tconst { table } = useDataTableContext<TData>();\n\n\treturn (\n\t\t<Table.Head {...props}>\n\t\t\t{table.getHeaderGroups().map((headerGroup) => (\n\t\t\t\t<Table.Row key={headerGroup.id}>\n\t\t\t\t\t{headerGroup.headers.map((header) => (\n\t\t\t\t\t\t<Fragment key={header.id}>\n\t\t\t\t\t\t\t{header.isPlaceholder ? (\n\t\t\t\t\t\t\t\t<Table.Header key={header.id} />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tflexRender(header.column.columnDef.header, header.getContext())\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t))}\n\t\t\t\t</Table.Row>\n\t\t\t))}\n\t\t</Table.Head>\n\t);\n}\n\ntype DataTableRowProps<TData> = Omit<ComponentProps<typeof Table.Row>, \"children\"> & {\n\trow: TableRow<TData>;\n};\n\nfunction Row<TData>({ row, ...props }: DataTableRowProps<TData>) {\n\treturn (\n\t\t<Table.Row {...props}>\n\t\t\t{row.getVisibleCells().map((cell) => (\n\t\t\t\t<Fragment key={cell.id}>\n\t\t\t\t\t{flexRender(cell.column.columnDef.cell, cell.getContext())}\n\t\t\t\t</Fragment>\n\t\t\t))}\n\t\t</Table.Row>\n\t);\n}\n\ntype DataTableEmptyRowProps = ComponentProps<typeof Table.Row>;\n\nfunction EmptyRow<TData>({ children, ...props }: DataTableEmptyRowProps) {\n\tconst { table } = useDataTableContext<TData>();\n\tconst numberOfColumns = table.getAllColumns().length;\n\n\treturn (\n\t\t<Table.Row {...props}>\n\t\t\t<Table.Cell colSpan={numberOfColumns}>{children}</Table.Cell>\n\t\t</Table.Row>\n\t);\n}\n\ntype DataTableActionCellProps = ComponentProps<typeof Table.Cell>;\n\nfunction ActionCell({ children, className, ...props }: DataTableActionCellProps) {\n\treturn (\n\t\t<Table.Cell\n\t\t\tclassName={cx(\n\t\t\t\t\"sticky z-10 right-0 top-px -bottom-px flex items-center justify-end p-2 group-data-sticky-active/table:[box-shadow:inset_10px_0_8px_-8px_oklch(0_0_0/15%)]\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Table.Cell>\n\t);\n}\n\n// Set display names to preserve original component names for debugging\nRoot.displayName = \"DataTable\";\nActionCell.displayName = \"DataTableActionCell\";\nBody.displayName = \"DataTableBody\";\nEmptyRow.displayName = \"DataTableEmptyRow\";\nHead.displayName = \"DataTableHead\";\nHeader.displayName = \"DataTableHeader\";\nHeaderSortButton.displayName = \"DataTableHeaderSortButton\";\nRow.displayName = \"DataTableRow\";\n\n/**\n * A data table component that provides sorting and other data table functionality.\n * Built on top of TanStack Table for advanced table features.\n *\n * @see https://mantle.ngrok.com/components/data-table\n *\n * @example\n * ```tsx\n * <DataTable table={table}>\n * <DataTable.Head />\n * <DataTable.Body>\n * <DataTable.Rows />\n * </DataTable.Body>\n * </DataTable>\n * ```\n */\nconst DataTable = {\n\t/**\n\t * The root container of the data table component.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableroot\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Root table={table}>\n\t * <DataTable.Head />\n\t * <DataTable.Body>\n\t * <DataTable.Rows />\n\t * </DataTable.Body>\n\t * </DataTable.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * A sticky action cell positioned at the end of each row for action buttons.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableactioncell\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.ActionCell>\n\t * <Button size=\"sm\">Edit</Button>\n\t * <Button size=\"sm\">Delete</Button>\n\t * </DataTable.ActionCell>\n\t * ```\n\t */\n\tActionCell,\n\t/**\n\t * A table cell component for rendering individual data cells.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatablecell\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Cell>\n\t * Cell content\n\t * </DataTable.Cell>\n\t * ```\n\t */\n\tCell: Table.Cell,\n\t/**\n\t * The table body container for rows of data.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatablebody\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Body>\n\t * <DataTable.Rows />\n\t * </DataTable.Body>\n\t * ```\n\t */\n\tBody,\n\t/**\n\t * An empty state row that spans all columns when there's no data to display.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableemptyrow\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.EmptyRow>\n\t * No data available\n\t * </DataTable.EmptyRow>\n\t * ```\n\t */\n\tEmptyRow,\n\t/**\n\t * The table header container that renders column headers automatically.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatablehead\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Head />\n\t * ```\n\t */\n\tHead,\n\t/**\n\t * A header cell component optimized for data table header actions.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableheader\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Header>\n\t * <DataTable.HeaderSortButton column={column} sortingMode=\"alphanumeric\">\n\t * Column Title\n\t * </DataTable.HeaderSortButton>\n\t * </DataTable.Header>\n\t * ```\n\t */\n\tHeader,\n\t/**\n\t * A sortable button toggle for column headers with sorting functionality.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableheadersortbutton\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.HeaderSortButton\n\t * column={column}\n\t * sortingMode=\"alphanumeric\"\n\t * >\n\t * Column Title\n\t * </DataTable.HeaderSortButton>\n\t * ```\n\t */\n\tHeaderSortButton,\n\t/**\n\t * A single data table row component for rendering custom row layouts.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatablerow\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Row row={row} />\n\t * ```\n\t */\n\tRow,\n} as const;\n\nexport {\n\t//,\n\tDataTable,\n};\n\ntype DefaultSortIconProps = SvgAttributes & {\n\tdirection: SortDirection | undefined;\n\tmode: SortingMode | undefined;\n};\n\nfunction DefaultSortIcon({ direction, mode, ...props }: DefaultSortIconProps) {\n\tif (direction === \"unsorted\" || !mode || !direction) {\n\t\treturn <svg aria-hidden {...props} />;\n\t}\n\n\treturn <SortIcon mode={mode} direction={direction} {...props} />;\n}\n\n/**\n * Toggle the sorting direction of a column.\n * This ordering is typically toggled by clicking the column header.\n *\n * @example\n * ```md\n * Each click cycles through...\n *\n * For alphanumeric sorting:\n * unsorted ➡️ ascending ➡️ descending ➡️ unsorted ➡️ ...\n *\n * For time sorting:\n * unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted ➡️ ...\n *\n * this is equivalent to the inverse of alphanumeric sorting, or\n * unsorted ➡️ descending ➡️ ascending ➡️ unsorted ➡️ ...\n * ```\n */\nfunction toggleNextSortingDirection<TData, TValue>(\n\tcolumn: Column<TData, TValue>,\n\tsortingMode: SortingMode,\n) {\n\tif (!column.getCanSort()) {\n\t\treturn;\n\t}\n\n\tconst sortDirection = column.getIsSorted();\n\tconst currentSortDirection: SortDirection =\n\t\ttypeof sortDirection === \"string\" ? sortDirection : \"unsorted\";\n\n\tconst nextSortDirection = getNextSortDirection(currentSortDirection, sortingMode);\n\n\tswitch (nextSortDirection) {\n\t\tcase \"unsorted\":\n\t\t\tcolumn.clearSorting();\n\t\t\treturn;\n\t\tcase \"asc\":\n\t\t\tcolumn.toggleSorting(false);\n\t\t\treturn;\n\t\tcase \"desc\":\n\t\t\tcolumn.toggleSorting(true);\n\t\t\treturn;\n\t\tdefault:\n\t\t\treturn;\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"data-table.js","names":["Table","Row"],"sources":["../src/components/data-table/helpers.ts","../src/components/data-table/data-table.tsx"],"sourcesContent":["import type { SortingMode } from \"../../utils/sorting/direction.js\";\nimport type { SortDirection } from \"./types.js\";\n\nconst alphanumericSortingOrder = [\"unsorted\", \"asc\", \"desc\"] as const satisfies SortDirection[];\n\nconst timeSortingOrder = [\"unsorted\", \"desc\", \"asc\"] as const satisfies SortDirection[];\n\n/**\n * Get the next sort direction based on the current sort direction and sorting mode.\n */\nfunction getNextSortDirection(currentSortDirection: SortDirection, sortingMode: SortingMode) {\n\tconst sortOrder = sortingMode === \"alphanumeric\" ? alphanumericSortingOrder : timeSortingOrder;\n\n\treturn getNextInCircularList(sortOrder, currentSortDirection) ?? \"unsorted\";\n}\n\n/**\n * Get the next item in a circular list.\n * If the current item is not found in the list (or it's empty), return the fallback value.\n */\nfunction getNextInCircularList<T>(list: T[], currentItem: T, fallback?: T | undefined) {\n\tif (list.length === 0) {\n\t\treturn fallback;\n\t}\n\n\tconst currentItemIndex = list.findIndex((item) => item === currentItem);\n\tif (currentItemIndex === -1) {\n\t\treturn fallback;\n\t}\n\n\tconst nextIndex = (currentItemIndex + 1) % list.length;\n\treturn list.at(nextIndex) ?? fallback;\n}\n\nexport {\n\t//,\n\tgetNextSortDirection,\n\tgetNextInCircularList,\n};\n","import {\n\ttype Column,\n\ttype HeaderContext,\n\ttype Table as TableInstance,\n\ttype Row as TableRow,\n\tflexRender,\n} from \"@tanstack/react-table\";\nimport {\n\ttype ComponentProps,\n\tFragment,\n\ttype ReactNode,\n\tcreateContext,\n\tuseContext,\n\tuseMemo,\n} from \"react\";\nimport invariant from \"tiny-invariant\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { $timeSortingDirection, type SortingMode } from \"../../utils/sorting/direction.js\";\nimport { Button } from \"../button/button.js\";\nimport type { SvgAttributes } from \"../icon/types.js\";\nimport { SortIcon } from \"../icons/sort.js\";\nimport { Table } from \"../table/table.js\";\nimport { getNextSortDirection } from \"./helpers.js\";\nimport type { SortDirection } from \"./types.js\";\n\ntype DataTableContextShape<TData = unknown> = {\n\ttable: TableInstance<TData>;\n};\n\n// oxlint-disable-next-line typescript/no-explicit-any - known limitation of react context when using generics 😭\nconst DataTableContext = createContext<DataTableContextShape<any> | null>(null);\n\n/**\n * @private\n */\nfunction useDataTableContext<TData>() {\n\tconst context = useContext(DataTableContext);\n\n\tinvariant(context, \"useDataTableContext should only be used within a DataTable child component\");\n\n\treturn context as DataTableContextShape<TData>;\n}\n\ntype DataTableProps<TData> = ComponentProps<typeof Table.Root> & {\n\ttable: TableInstance<TData>;\n};\n\n/**\n * A data table component that provides sorting and other data table functionality.\n * Built on top of TanStack Table for advanced table features.\n *\n * @see https://mantle.ngrok.com/components/data-table#datatableroot\n *\n * @example\n * ```tsx\n * <DataTable table={table}>\n * <DataTable.Head />\n * <DataTable.Body>\n * <DataTable.Rows />\n * </DataTable.Body>\n * </DataTable>\n * ```\n */\nfunction Root<TData>({ children, table, ...props }: DataTableProps<TData>) {\n\tconst context: DataTableContextShape<TData> = useMemo(() => ({ table }), [table]);\n\n\treturn (\n\t\t<DataTableContext.Provider value={context}>\n\t\t\t<Table.Root {...props}>\n\t\t\t\t<Table.Element>{children}</Table.Element>\n\t\t\t</Table.Root>\n\t\t</DataTableContext.Provider>\n\t);\n}\n\ntype DataTableHeaderSortButtonProps<TData, TValue> = Omit<ComponentProps<typeof Button>, \"icon\"> &\n\tPick<HeaderContext<TData, TValue>, \"column\"> &\n\t(\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * Disable sorting for this column.\n\t\t\t\t * It will prevent the sorting direction from being toggled and any icon\n\t\t\t\t * from being shown.\n\t\t\t\t */\n\t\t\t\tdisableSorting: true;\n\t\t\t\t/**\n\t\t\t\t * Use this to render a custom sort icon for the column if it is sortable\n\t\t\t\t * and you want to override the default sort icon\n\t\t\t\t */\n\t\t\t\tsortIcon?: undefined;\n\t\t\t\t/**\n\t\t\t\t * The sorting mode of the column, whether it is alphanumeric or time based.\n\t\t\t\t */\n\t\t\t\tsortingMode?: undefined;\n\t\t }\n\t\t| {\n\t\t\t\tdisableSorting?: false;\n\t\t\t\t/**\n\t\t\t\t * Use this to render a custom sort icon for the column if it is sortable\n\t\t\t\t * and you want to override the default sort icon\n\t\t\t\t */\n\t\t\t\tsortIcon?: (sortDirection: SortDirection) => ReactNode;\n\t\t\t\t/**\n\t\t\t\t * The sorting mode of the column, whether it is alphanumeric or time based.\n\t\t\t\t */\n\t\t\t\tsortingMode: SortingMode;\n\t\t }\n\t);\n\n/**\n * A sortable button toggle for a column header in a data table.\n * If the column is sortable, clicking the button will toggle the sorting\n * direction.\n *\n * @see https://mantle.ngrok.com/components/data-table#datatableheadersortbutton\n *\n * @example\n * ```tsx\n * <DataTable.HeaderSortButton\n * column={column}\n * sortingMode=\"alphanumeric\"\n * >\n * Column Title\n * </DataTable.HeaderSortButton>\n * ```\n *\n * Each click cycles through:\n * - For alphanumeric sorting: unsorted ➡️ ascending ➡️ descending ➡️ unsorted\n * - For time sorting: unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted\n */\nfunction HeaderSortButton<TData, TValue>({\n\tchildren,\n\tclassName,\n\tcolumn,\n\tdisableSorting = false,\n\ticonPlacement = \"end\",\n\tsortingMode,\n\tsortIcon: propSortIcon,\n\tonClick,\n\t...props\n}: DataTableHeaderSortButtonProps<TData, TValue>) {\n\tconst _sortDirection = column.getIsSorted();\n\tconst canSort = !disableSorting && column.getCanSort();\n\n\tconst sortDirection: SortDirection =\n\t\tcanSort && typeof _sortDirection === \"string\" ? _sortDirection : \"unsorted\";\n\n\tconst sortIcon = propSortIcon?.(sortDirection) ?? (\n\t\t<DefaultSortIcon mode={sortingMode} direction={sortDirection} />\n\t);\n\n\treturn (\n\t\t<Button\n\t\t\tappearance=\"ghost\"\n\t\t\tclassName={cx(\n\t\t\t\t\"flex justify-start w-full h-full rounded-none not-disabled:active:scale-none text-muted\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tdata-sort-direction={sortDirection}\n\t\t\tdata-table-header-action\n\t\t\ticon={sortIcon}\n\t\t\ticonPlacement={iconPlacement}\n\t\t\tonClick={(event) => {\n\t\t\t\tonClick?.(event);\n\t\t\t\tif (event.defaultPrevented) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!canSort || disableSorting || typeof sortingMode === \"undefined\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttoggleNextSortingDirection(column, sortingMode);\n\t\t\t}}\n\t\t\tpriority=\"neutral\"\n\t\t\ttype=\"button\"\n\t\t\t{...props}\n\t\t>\n\t\t\t{canSort && sortDirection !== \"unsorted\" && (\n\t\t\t\t<span className=\"sr-only\">\n\t\t\t\t\tColumn sorted in{\" \"}\n\t\t\t\t\t{sortingMode === \"alphanumeric\"\n\t\t\t\t\t\t? sortDirection === \"asc\"\n\t\t\t\t\t\t\t? \"ascending\"\n\t\t\t\t\t\t\t: \"descending\"\n\t\t\t\t\t\t: $timeSortingDirection(sortDirection)}{\" \"}\n\t\t\t\t\torder\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t{children}\n\t\t</Button>\n\t);\n}\n\ntype DataTableHeaderProps = ComponentProps<typeof Table.Header>;\n\n/**\n * A header for a data table.\n * This is typically used to wrap the `DataTable.HeaderSortButton` component.\n *\n * @see https://mantle.ngrok.com/components/data-table#datatableheader\n *\n * @example\n * ```tsx\n * <DataTable.Header>\n * <DataTable.HeaderSortButton column={column} sortingMode=\"alphanumeric\">\n * Column Title\n * </DataTable.HeaderSortButton>\n * </DataTable.Header>\n * ```\n */\nfunction Header({ children, className, ...props }: DataTableHeaderProps) {\n\treturn (\n\t\t<Table.Header className={cx(\"has-data-table-header-action:px-0\", className)} {...props}>\n\t\t\t{children}\n\t\t</Table.Header>\n\t);\n}\n\nconst Body = Table.Body;\nBody.displayName = \"DataTableBody\";\n\ntype DataTableHeadProps = Omit<ComponentProps<typeof Table.Head>, \"children\">;\n\nfunction Head<TData>(props: DataTableHeadProps) {\n\tconst { table } = useDataTableContext<TData>();\n\n\treturn (\n\t\t<Table.Head {...props}>\n\t\t\t{table.getHeaderGroups().map((headerGroup) => (\n\t\t\t\t<Table.Row key={headerGroup.id}>\n\t\t\t\t\t{headerGroup.headers.map((header) => (\n\t\t\t\t\t\t<Fragment key={header.id}>\n\t\t\t\t\t\t\t{header.isPlaceholder ? (\n\t\t\t\t\t\t\t\t<Table.Header key={header.id} />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tflexRender(header.column.columnDef.header, header.getContext())\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t))}\n\t\t\t\t</Table.Row>\n\t\t\t))}\n\t\t</Table.Head>\n\t);\n}\n\ntype DataTableRowProps<TData> = Omit<ComponentProps<typeof Table.Row>, \"children\"> & {\n\trow: TableRow<TData>;\n};\n\nfunction Row<TData>({ row, ...props }: DataTableRowProps<TData>) {\n\treturn (\n\t\t<Table.Row {...props}>\n\t\t\t{row.getVisibleCells().map((cell) => (\n\t\t\t\t<Fragment key={cell.id}>\n\t\t\t\t\t{flexRender(cell.column.columnDef.cell, cell.getContext())}\n\t\t\t\t</Fragment>\n\t\t\t))}\n\t\t</Table.Row>\n\t);\n}\n\ntype DataTableEmptyRowProps = ComponentProps<typeof Table.Row>;\n\nfunction EmptyRow<TData>({ children, ...props }: DataTableEmptyRowProps) {\n\tconst { table } = useDataTableContext<TData>();\n\tconst numberOfColumns = table.getAllColumns().length;\n\n\treturn (\n\t\t<Table.Row {...props}>\n\t\t\t<Table.Cell colSpan={numberOfColumns}>{children}</Table.Cell>\n\t\t</Table.Row>\n\t);\n}\n\n/**\n * Internal: renders the visual indicator on the left edge of the sticky action\n * column — a 1px divider plus a soft shadow gradient that reads as content\n * sliding under the pinned column. Positioned as a 6px strip sitting\n * immediately to the left of its sticky parent cell; `-inset-y-px` lets\n * adjacent rows' strips overlap at row dividers so the effect reads as one\n * continuous column instead of per-row blobs.\n *\n * Rendered as a child `<span>` because `border-collapse` on the table\n * suppresses box-shadow on `<td>`/`<th>`.\n */\nfunction StickyColIndicator() {\n\treturn (\n\t\t<span\n\t\t\taria-hidden\n\t\t\tclassName={cx(\n\t\t\t\t\"pointer-events-none absolute -inset-y-px -left-1.5 w-1.5\",\n\t\t\t\t\"opacity-0 transition-opacity group-data-sticky-active/table:opacity-100\",\n\t\t\t\t// 1px divider painted at the strip's right edge (= the pinned\n\t\t\t\t// cell's left edge).\n\t\t\t\t\"shadow-[1px_0_0_0_var(--border-color-card-muted)]\",\n\t\t\t\t// Soft shadow gradient fading leftward. Uses mantle's shadow\n\t\t\t\t// tokens so the alpha adapts to light/dark themes.\n\t\t\t\t\"bg-linear-to-l to-transparent\",\n\t\t\t\t\"from-[color-mix(in_oklab,var(--shadow-color)_var(--shadow-second-opacity),transparent)]\",\n\t\t\t)}\n\t\t/>\n\t);\n}\n\ntype DataTableActionCellProps = ComponentProps<typeof Table.Cell>;\n\nfunction ActionCell({ children, className, ...props }: DataTableActionCellProps) {\n\treturn (\n\t\t<Table.Cell\n\t\t\t// Marks this cell as a sticky right-edge column so Table.Root can suppress\n\t\t\t// its container-level right-side scroll fade (keeping this cell opaque).\n\t\t\tdata-mantle-table-sticky-right\n\t\t\tclassName={cx(\n\t\t\t\t// `bg-inherit` keeps the sticky cell opaque with the row's current bg\n\t\t\t\t// (including hover state) so scrolling cells don't show through.\n\t\t\t\t\"sticky z-10 right-0 flex items-center justify-end bg-inherit p-2\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<StickyColIndicator />\n\t\t\t{children}\n\t\t</Table.Cell>\n\t);\n}\n\ntype DataTableActionHeaderProps = ComponentProps<typeof Table.Header>;\n\n/**\n * A sticky header cell that pairs with `DataTable.ActionCell`. Use this as the\n * header for the action column so the pinned column visually aligns across the\n * header and every body row when the table scrolls horizontally.\n *\n * @see https://mantle.ngrok.com/components/data-table#datatableactionheader\n *\n * @example\n * ```tsx\n * columnHelper.display({\n * id: \"actions\",\n * header: () => <DataTable.ActionHeader />,\n * cell: () => <DataTable.ActionCell>{...}</DataTable.ActionCell>,\n * })\n * ```\n */\nfunction ActionHeader({ children, className, ...props }: DataTableActionHeaderProps) {\n\tconst { table } = useDataTableContext();\n\tconst hasRows = table.getRowModel().rows.length > 0;\n\n\treturn (\n\t\t<Table.Header\n\t\t\t// Only mark as sticky-right when body rows exist so the empty state\n\t\t\t// doesn't suppress the container's right-side scroll fade.\n\t\t\t{...(hasRows ? { \"data-mantle-table-sticky-right\": true } : {})}\n\t\t\tclassName={cx(\n\t\t\t\t// `bg-inherit` keeps the sticky header opaque with the thead's current bg.\n\t\t\t\thasRows && \"sticky z-10 right-0 bg-inherit\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{hasRows && <StickyColIndicator />}\n\t\t\t{children}\n\t\t</Table.Header>\n\t);\n}\n\n// Set display names to preserve original component names for debugging\nRoot.displayName = \"DataTable\";\nActionCell.displayName = \"DataTableActionCell\";\nActionHeader.displayName = \"DataTableActionHeader\";\nBody.displayName = \"DataTableBody\";\nEmptyRow.displayName = \"DataTableEmptyRow\";\nHead.displayName = \"DataTableHead\";\nHeader.displayName = \"DataTableHeader\";\nHeaderSortButton.displayName = \"DataTableHeaderSortButton\";\nRow.displayName = \"DataTableRow\";\n\n/**\n * A data table component that provides sorting and other data table functionality.\n * Built on top of TanStack Table for advanced table features.\n *\n * @see https://mantle.ngrok.com/components/data-table\n *\n * @example\n * ```tsx\n * <DataTable table={table}>\n * <DataTable.Head />\n * <DataTable.Body>\n * <DataTable.Rows />\n * </DataTable.Body>\n * </DataTable>\n * ```\n */\nconst DataTable = {\n\t/**\n\t * The root container of the data table component.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableroot\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Root table={table}>\n\t * <DataTable.Head />\n\t * <DataTable.Body>\n\t * <DataTable.Rows />\n\t * </DataTable.Body>\n\t * </DataTable.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * A sticky action cell positioned at the end of each row for action buttons.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableactioncell\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.ActionCell>\n\t * <Button size=\"sm\">Edit</Button>\n\t * <Button size=\"sm\">Delete</Button>\n\t * </DataTable.ActionCell>\n\t * ```\n\t */\n\tActionCell,\n\t/**\n\t * A sticky header cell that pairs with `DataTable.ActionCell`, keeping the\n\t * action column aligned across the header and body when scrolling horizontally.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableactionheader\n\t *\n\t * @example\n\t * ```tsx\n\t * columnHelper.display({\n\t * id: \"actions\",\n\t * header: () => <DataTable.ActionHeader />,\n\t * cell: () => <DataTable.ActionCell>{...}</DataTable.ActionCell>,\n\t * })\n\t * ```\n\t */\n\tActionHeader,\n\t/**\n\t * A table cell component for rendering individual data cells.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatablecell\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Cell>\n\t * Cell content\n\t * </DataTable.Cell>\n\t * ```\n\t */\n\tCell: Table.Cell,\n\t/**\n\t * The table body container for rows of data.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatablebody\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Body>\n\t * <DataTable.Rows />\n\t * </DataTable.Body>\n\t * ```\n\t */\n\tBody,\n\t/**\n\t * An empty state row that spans all columns when there's no data to display.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableemptyrow\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.EmptyRow>\n\t * No data available\n\t * </DataTable.EmptyRow>\n\t * ```\n\t */\n\tEmptyRow,\n\t/**\n\t * The table header container that renders column headers automatically.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatablehead\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Head />\n\t * ```\n\t */\n\tHead,\n\t/**\n\t * A header cell component optimized for data table header actions.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableheader\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Header>\n\t * <DataTable.HeaderSortButton column={column} sortingMode=\"alphanumeric\">\n\t * Column Title\n\t * </DataTable.HeaderSortButton>\n\t * </DataTable.Header>\n\t * ```\n\t */\n\tHeader,\n\t/**\n\t * A sortable button toggle for column headers with sorting functionality.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatableheadersortbutton\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.HeaderSortButton\n\t * column={column}\n\t * sortingMode=\"alphanumeric\"\n\t * >\n\t * Column Title\n\t * </DataTable.HeaderSortButton>\n\t * ```\n\t */\n\tHeaderSortButton,\n\t/**\n\t * A single data table row component for rendering custom row layouts.\n\t *\n\t * @see https://mantle.ngrok.com/components/data-table#datatablerow\n\t *\n\t * @example\n\t * ```tsx\n\t * <DataTable.Row row={row} />\n\t * ```\n\t */\n\tRow,\n} as const;\n\nexport {\n\t//,\n\tDataTable,\n};\n\ntype DefaultSortIconProps = SvgAttributes & {\n\tdirection: SortDirection | undefined;\n\tmode: SortingMode | undefined;\n};\n\nfunction DefaultSortIcon({ direction, mode, ...props }: DefaultSortIconProps) {\n\tif (direction === \"unsorted\" || !mode || !direction) {\n\t\treturn <svg aria-hidden {...props} />;\n\t}\n\n\treturn <SortIcon mode={mode} direction={direction} {...props} />;\n}\n\n/**\n * Toggle the sorting direction of a column.\n * This ordering is typically toggled by clicking the column header.\n *\n * @example\n * ```md\n * Each click cycles through...\n *\n * For alphanumeric sorting:\n * unsorted ➡️ ascending ➡️ descending ➡️ unsorted ➡️ ...\n *\n * For time sorting:\n * unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted ➡️ ...\n *\n * this is equivalent to the inverse of alphanumeric sorting, or\n * unsorted ➡️ descending ➡️ ascending ➡️ unsorted ➡️ ...\n * ```\n */\nfunction toggleNextSortingDirection<TData, TValue>(\n\tcolumn: Column<TData, TValue>,\n\tsortingMode: SortingMode,\n) {\n\tif (!column.getCanSort()) {\n\t\treturn;\n\t}\n\n\tconst sortDirection = column.getIsSorted();\n\tconst currentSortDirection: SortDirection =\n\t\ttypeof sortDirection === \"string\" ? sortDirection : \"unsorted\";\n\n\tconst nextSortDirection = getNextSortDirection(currentSortDirection, sortingMode);\n\n\tswitch (nextSortDirection) {\n\t\tcase \"unsorted\":\n\t\t\tcolumn.clearSorting();\n\t\t\treturn;\n\t\tcase \"asc\":\n\t\t\tcolumn.toggleSorting(false);\n\t\t\treturn;\n\t\tcase \"desc\":\n\t\t\tcolumn.toggleSorting(true);\n\t\t\treturn;\n\t\tdefault:\n\t\t\treturn;\n\t}\n}\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
5
5
 
6
6
  //#region src/components/button/button-group.d.ts
7
7
  declare const buttonGroupVariants: (props?: ({
8
- appearance?: "panel" | "ghost" | "outlined" | null | undefined;
8
+ appearance?: "ghost" | "outlined" | "panel" | null | undefined;
9
9
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
10
10
  type ButtonGroupVariants = VariantProps<typeof buttonGroupVariants>;
11
11
  type ButtonGroupProps = ComponentProps<"div"> & ButtonGroupVariants;
@@ -26,4 +26,4 @@ type ButtonGroupProps = ComponentProps<"div"> & ButtonGroupVariants;
26
26
  declare const ButtonGroup: _$react.ForwardRefExoticComponent<Omit<ButtonGroupProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
27
27
  //#endregion
28
28
  export { ButtonGroupProps as n, ButtonGroup as t };
29
- //# sourceMappingURL=index-BCZ3y0yi.d.ts.map
29
+ //# sourceMappingURL=index-Cj2NX2Dg.d.ts.map
@@ -23,7 +23,7 @@ type InputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "
23
23
  * />
24
24
  * ```
25
25
  */
26
- declare const Input: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "autoComplete"> & WithAutoComplete & WithInputType & WithValidation & {
26
+ declare const Input: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & WithAutoComplete & WithInputType & WithValidation & {
27
27
  children?: _$react.ReactNode | undefined;
28
28
  } & _$react.RefAttributes<HTMLInputElement>>;
29
29
  type InputCaptureProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & BaseProps;
@@ -41,7 +41,7 @@ type InputCaptureProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoComple
41
41
  * </Input>
42
42
  * ```
43
43
  */
44
- declare const InputCapture: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "autoComplete"> & WithAutoComplete & WithInputType & WithValidation & _$react.RefAttributes<HTMLInputElement>>;
44
+ declare const InputCapture: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & WithAutoComplete & WithInputType & WithValidation & _$react.RefAttributes<HTMLInputElement>>;
45
45
  //#endregion
46
46
  //#region src/components/input/password-input.d.ts
47
47
  type PasswordInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & WithValidation & WithAutoComplete & {
@@ -70,7 +70,7 @@ type PasswordInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoCompl
70
70
  * />
71
71
  * ```
72
72
  */
73
- declare const PasswordInput: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "autoComplete"> & WithValidation & WithAutoComplete & {
73
+ declare const PasswordInput: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & WithValidation & WithAutoComplete & {
74
74
  /**
75
75
  * Callback for when the visibility of the password value changes.
76
76
  */
@@ -100,4 +100,4 @@ declare const PasswordInput: _$react.ForwardRefExoticComponent<Omit<InputHTMLAtt
100
100
  declare function isInput(value: unknown): value is HTMLInputElement;
101
101
  //#endregion
102
102
  export { InputCapture as a, Input as i, PasswordInput as n, InputCaptureProps as o, PasswordInputProps as r, InputProps as s, isInput as t };
103
- //# sourceMappingURL=index-Bw97R9Kw.d.ts.map
103
+ //# sourceMappingURL=index-DXuVn00J.d.ts.map
package/dist/input.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { a as WithInputType, i as WithAutoComplete, n as InputType, o as WithValidation, r as Validation, t as AutoComplete } from "./types-Cq6RWU7Q.js";
2
- import { a as InputCapture, i as Input, n as PasswordInput, o as InputCaptureProps, r as PasswordInputProps, s as InputProps, t as isInput } from "./index-Bw97R9Kw.js";
2
+ import { a as InputCapture, i as Input, n as PasswordInput, o as InputCaptureProps, r as PasswordInputProps, s as InputProps, t as isInput } from "./index-DXuVn00J.js";
3
3
  export { AutoComplete, Input, InputCapture, InputCaptureProps, InputProps, InputType, PasswordInput, PasswordInputProps, Validation, WithAutoComplete, WithInputType, WithValidation, isInput };
@@ -1,5 +1,5 @@
1
1
  import { t as WithAsChild } from "./as-child-CRRsxi3Y.js";
2
- import { t as ButtonGroup } from "./index-BCZ3y0yi.js";
2
+ import { t as ButtonGroup } from "./index-Cj2NX2Dg.js";
3
3
  import { t as Select } from "./select-DJmjfGjt.js";
4
4
  import * as _$react from "react";
5
5
  import { ComponentProps } from "react";
@@ -0,0 +1,12 @@
1
+ import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./booleanish-CBGdPL3Q.js";const n=new Set([`bash`,`sh`,`shell`]);function r(e,t){return!(n.has(e)&&!t.trim().includes(`
2
+ `))}const i=Symbol(`MantleCodeBlockValue`);function a({preHtml:e,preValToken:t,preVals:n,highlightLines:r,lineNumberStart:a,showLineNumbers:o,code:s,language:c}){return{[i]:!0,language:c,code:s,"~preHtml":e,"~preValToken":t,"~preVals":n,"~highlightLines":r,"~lineNumberStart":a,"~showLineNumbers":o}}function o(e,t){let n=``;for(let r=0;r<e.length;r+=1)n+=e[r]??``,r<t.length&&(n+=String(t[r]));return n}function s(e,t={}){let{showLineNumbers:n,highlightLines:i,lineNumberStart:s}=t;return(t,...c)=>{let l=o(t,c);return a({language:e,code:l,preHtml:void 0,preVals:c.length>0?c:void 0,highlightLines:i,lineNumberStart:s,showLineNumbers:n??r(e,l)})}}function c(...e){let t=new Set;for(let n of e)if(typeof n==`number`){if(!l(n))continue;let e=Math.floor(n);t.add(e)}else{let e=n.indexOf(`-`),r=n.slice(0,e),i=n.slice(e+1),a=Number.parseInt(r,10),o=Number.parseInt(i,10);if(!l(a)||!l(o)||(a>o&&([a,o]=[o,a]),o-a+1>1e3))continue;for(let e=a;e<=o;e++)t.add(e)}return t}const l=e=>e!=null&&!Number.isNaN(e)&&e>0&&Number.isFinite(e);function u(e){let t=e.length;for(;t>0&&(e.charCodeAt(t-1)===10||e.charCodeAt(t-1)===13);)--t;return t===e.length?e:e.slice(0,t)}function d(e){let t=u(e).replaceAll(`\r
3
+ `,`
4
+ `).replaceAll(`\r`,`
5
+ `).split(`
6
+ `);for(let e=0;e<t.length;e++){let n=t[e]??``;n.startsWith(`<span class="line">`)&&n.endsWith(`</span>`)&&(t[e]=n.slice(19,n.length-7))}return t}function f({highlightLines:t,html:n,lineNumberStart:r=1,showLineNumbers:i=!1}){let a=c(...t??[]),o=d(n),s=``;for(let t=0;t<o.length;t++){let n=o[t]??``,c=r+t,l=e(`mantle-code-line`,a.has(c)&&`mantle-code-line-highlighted`),u=i?`<span class="mantle-code-line-number" data-slot="line-number">${c}</span>`:``;s+=`<span class="${l}" data-line-number="${c}">${u}<span class="mantle-code-line-content" data-slot="line-content">${n===``?` `:n}</span></span>`}return s}const p=[`tabs`,`spaces`];function m(e){return p.includes(e)}function h(e,t){return t||(v(e)?`tabs`:(y(e),`spaces`))}const g=new Set([`csharp`,`css`,`go`,`html`,`java`,`javascript`,`js`,`jsx`,`ts`,`tsx`,`typescript`,`xml`]),_=new Set([`python`,`py`,`yaml`,`yml`,`ruby`,`rb`]);function v(e){return g.has(e)}function y(e){return _.has(e)}function b(e,t){let n=t?.indentation??`spaces`,r=e.replace(/\r\n?/g,`
7
+ `),i=r.trim();if(i===``)return``;let a=C(r),o=i.split(`
8
+ `),s=Array(o.length);for(let e=0;e<o.length;e++){let t=o[e];t!=null&&(s[e]=x(S(t)?t:t.slice(a),n))}return s.join(`
9
+ `)}function x(e,t){let n=0;for(;n<e.length;){let t=e[n];if(t!==` `&&t!==` `)break;n+=1}if(n===0||n===e.length)return e;let r=e.slice(0,n);return(t===`spaces`?r.replace(/\t/g,` `):r.replace(/ {2}/g,` `))+e.slice(n)}function S(e){let t=e[0];return t!=null&&t!==` `&&t!==` `}function C(e){let t=1/0,n=0,r=!0;for(let i=0;i<e.length;i++){let a=e[i];if(r){if(a===` `||a===` `){n+=1;continue}if(a===`
10
+ `||a===`\r`){n=0;continue}if(n<t&&(t=n,t===0))return 0;r=!1;continue}(a===`
11
+ `||a===`\r`)&&(r=!0,n=0)}return t===1/0?0:t}const w=`bash.cs.csharp.css.go.html.java.javascript.js.json.jsx.plain.plaintext.py.python.rb.ruby.rust.sh.shell.text.ts.tsx.txt.typescript.xml.yaml.yml`.split(`.`),T=new Set(w),E=`text`;function D(e){let t=e?.trim()??``;if(!t)return E;let n=t.indexOf(`-`),r=n===-1?t:t.slice(n+1);return O(r)?r:E}const O=e=>typeof e==`string`&&T.has(e);function k(e){if(typeof e==`boolean`)return e;if(typeof e==`string`){if(e===`true`)return!0;if(e===`false`)return!1}}function A(e){if(typeof e==`number`&&Number.isFinite(e)&&e>0)return Math.floor(e);if(typeof e==`string`&&/^\d+$/.test(e)){let t=Number.parseInt(e,10);return t>0?t:void 0}}function j(e){let t=e=>{if(typeof e==`number`)return Number.isFinite(e)&&e>0?Math.floor(e):void 0;if(typeof e==`string`){let t=e.trim();if(/^\d+$/.test(t)){let e=Number.parseInt(t,10);return e>0?e:void 0}if(/^\d+-\d+$/.test(t)){let[e,n]=t.split(`-`);return Number.parseInt(e??``,10)>0&&Number.parseInt(n??``,10)>0?t:void 0}}};if(typeof e==`string`){let n=[],r=e.split(`,`);for(let e of r){let r=t(e);r!=null&&n.push(r)}return n.length>0?n:void 0}if(!Array.isArray(e))return;let n=[];for(let r of e){let e=t(r);e!=null&&n.push(e)}return n.length>0?n:void 0}const M={collapsible:!1,disableCopy:!1,indentation:void 0,mode:void 0,title:void 0};function N(e){let t=e?.trim()??``;if(!t)return M;let n={},r=F(t);for(let e of r){let t=e.indexOf(`=`),r=t===-1?e:e.slice(0,t),i=t===-1?void 0:e.slice(t+1);r&&(n[r]=P(i)??!0)}return L(n)}function P(e){if(e==null)return;let t=e.trim(),n=t.length-1;return n>=1&&t.charCodeAt(0)===34&&t.charCodeAt(n)===34?t.slice(1,n):t}function F(e){let t=e?.trim()??``,n=[],r=``,i=!1;for(let e=0;e<t.length;e++){let a=t[e]??``;a===` `&&!i?r&&=(n.push(r),``):(a===`"`&&(i=!i),r+=a)}return r&&n.push(r),n}function I(e){return e===`cli`||e===`file`||e===`traffic-policy`}function L(e){let{collapsible:n=M.collapsible,disableCopy:r=M.disableCopy,indentation:i=M.indentation,mode:a=M.mode,title:o=M.title}=e;return{collapsible:typeof n==`string`||typeof n==`boolean`?t(n):M.collapsible,disableCopy:typeof r==`string`||typeof r==`boolean`?t(r):M.disableCopy,indentation:m(i)?i:M.indentation,mode:I(a)?a:M.mode,title:typeof o==`string`?o.trim():M.title}}function R(e){let{collapsible:n,disableCopy:r,mantleCode:i,mantleCollapsible:a,mantleDisableCopy:o,mantleHighlightLines:s,mantleLanguage:c,mantleLineNumberStart:l,mantleMode:u,mantlePreHtml:d,mantleShowLineNumbers:f,mantleTitle:p,mode:m,title:h,...g}=e;return c!=null||i!=null||d!=null||f!=null||s!=null||l!=null||a!=null||o!=null||u!=null||p!=null?{mantleCode:{code:typeof i==`string`?i:void 0,collapsible:(typeof a==`string`||typeof a==`boolean`?t(a):void 0)??(typeof n==`string`||typeof n==`boolean`?t(n):void 0),disableCopy:typeof o==`string`||typeof o==`boolean`?t(o):typeof r==`string`||typeof r==`boolean`?t(r):void 0,highlightLines:j(s),language:typeof c==`string`&&O(c)?c:void 0,lineNumberStart:A(l),mode:I(u)?u:I(m)?m:void 0,preHtml:typeof d==`string`?d:void 0,rawLanguage:c,showLineNumbers:k(f),title:typeof p==`string`?p.trim():typeof h==`string`?h.trim():void 0},props:g}:{mantleCode:void 0,props:g}}export{r as _,F as a,k as c,w as d,b as f,a as g,f as h,R as i,O as l,m,P as n,j as o,h as p,N as r,A as s,M as t,D as u,s as v};
12
+ //# sourceMappingURL=resolve-pre-rendered-props--3gLTSwE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-pre-rendered-props--3gLTSwE.js","names":[],"sources":["../src/components/code-block/mantle-code.ts","../src/components/code-block/line-numbers.ts","../src/components/code-block/decorate-highlighted-html.ts","../src/components/code-block/indentation.ts","../src/components/code-block/normalize-indentation.ts","../src/components/code-block/supported-languages.ts","../src/components/code-block/parse-line-options.ts","../src/components/code-block/resolve-pre-rendered-props.ts"],"sourcesContent":["import type { SupportedLanguage } from \"../code-block/supported-languages.js\";\nimport type { LineRange } from \"../code-block/line-numbers.js\";\nimport type { Indentation } from \"../code-block/indentation.js\";\n\n/** Languages that represent shell/terminal commands. */\nconst shellLanguages = new Set<SupportedLanguage>([\"bash\", \"sh\", \"shell\"]);\n\n/** Returns the default `showLineNumbers` value for a given language and code string. Single-line shell snippets default to `false`; everything else defaults to `true`. */\nfunction defaultShowLineNumbers(language: SupportedLanguage, code: string): boolean {\n\tif (shellLanguages.has(language) && !code.trim().includes(\"\\n\")) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nconst mantleCodeBlockValueBrand: unique symbol = Symbol(\"MantleCodeBlockValue\");\n\n/**\n * The value produced by `mantleCode()`. Contains pre-rendered Shiki HTML (injected\n * by the Vite plugin at build time) and the original code string for the copy button.\n *\n * `~preHtml` is required at render time. Runtime syntax highlighting is intentionally\n * unsupported; only placeholder substitution for interpolated values is performed.\n */\ntype MantleCodeBlockValue = {\n\t/**\n\t * Nominal type brand to prevent accidental use of plain objects.\n\t */\n\t[mantleCodeBlockValueBrand]: true;\n\t/**\n\t * The language used for syntax highlighting.\n\t */\n\tlanguage: SupportedLanguage;\n\t/**\n\t * The original code string (used by the copy button).\n\t */\n\tcode: string;\n\t/**\n\t * Fully pre-rendered Shiki HTML injected by the Vite plugin or server highlighter.\n\t * This must be present for rendering.\n\t *\n\t * **Security:** This HTML is injected via `dangerouslySetInnerHTML`. It must\n\t * come from a trusted source (Shiki output from the Vite plugin or\n\t * `createMantleServerSyntaxHighlighter`). Never pass unsanitized user input.\n\t */\n\t\"~preHtml\"?: string | undefined;\n\t/**\n\t * Runtime values used to replace `SHIKI_VAL_N` placeholders in `~preHtml`.\n\t * This enables interpolated template expressions while preserving build-time highlighting.\n\t */\n\t\"~preVals\"?: unknown[] | undefined;\n\t/**\n\t * Placeholder token prefix used by the Vite transform for interpolated values.\n\t * When omitted, CodeBlock falls back to the legacy `SHIKI_VAL_<n>` format.\n\t */\n\t\"~preValToken\"?: string | undefined;\n\t/**\n\t * Optional default for line-number rendering when this value is displayed.\n\t */\n\t\"~showLineNumbers\"?: boolean | undefined;\n\t/**\n\t * Optional default highlighted line numbers/ranges when this value is displayed.\n\t */\n\t\"~highlightLines\"?: (LineRange | number)[] | undefined;\n\t/**\n\t * Optional default start line number when line numbers are displayed.\n\t * @default 1\n\t */\n\t\"~lineNumberStart\"?: number | undefined;\n};\n\n/** Maps each key starting with `OldPrefix` to `NewPrefix`, leaving other keys unchanged. */\ntype ReplacePrefix<T, OldPrefix extends string, NewPrefix extends string> = {\n\t[K in keyof T as K extends `${OldPrefix}${infer Rest}` ? `${NewPrefix}${Rest}` : K]: T[K];\n};\n\n/** Public input shape for `createMantleCodeBlockValue`, with `~`-prefixed keys renamed to unprefixed. */\ntype MantleCodeBlockValueInput = ReplacePrefix<\n\tOmit<MantleCodeBlockValue, typeof mantleCodeBlockValueBrand>,\n\t\"~\",\n\t\"\"\n>;\n\n/** Options for configuring line numbers, highlights, and indentation in `mantleCode()`. */\ntype MantleCodeOptions = {\n\t/** Line numbers or ranges to visually highlight in the code block. */\n\thighlightLines?: (LineRange | number)[] | undefined;\n\t/** The indentation style to use when normalizing the code string. */\n\tindentation?: Indentation | undefined;\n\t/**\n\t * The starting line number when line numbers are displayed.\n\t * @default 1\n\t */\n\tlineNumberStart?: number | undefined;\n\t/**\n\t * Whether to show line numbers in the code block. Defaults to `true` for most\n\t * languages, but `false` for single-line shell snippets (`bash`, `sh`, `shell`).\n\t */\n\tshowLineNumbers?: boolean | undefined;\n};\n\n/**\n * Creates a `MantleCodeBlockValue` for use with `CodeBlock.Code`.\n *\n * **Security:** The `preHtml` field is rendered via `dangerouslySetInnerHTML`.\n * Only pass HTML produced by Shiki (via the Vite plugin or\n * `createMantleServerSyntaxHighlighter`). Never pass unsanitized user input as `preHtml`.\n */\nfunction createMantleCodeBlockValue({\n\tpreHtml,\n\tpreValToken,\n\tpreVals,\n\thighlightLines,\n\tlineNumberStart,\n\tshowLineNumbers,\n\tcode,\n\tlanguage,\n}: MantleCodeBlockValueInput): MantleCodeBlockValue {\n\treturn {\n\t\t[mantleCodeBlockValueBrand]: true,\n\t\tlanguage,\n\t\tcode,\n\t\t\"~preHtml\": preHtml,\n\t\t\"~preValToken\": preValToken,\n\t\t\"~preVals\": preVals,\n\t\t\"~highlightLines\": highlightLines,\n\t\t\"~lineNumberStart\": lineNumberStart,\n\t\t\"~showLineNumbers\": showLineNumbers,\n\t};\n}\n\n/** Joins a `TemplateStringsArray` and its interpolated values into a single code string. */\nfunction buildCodeFromTemplate(strings: TemplateStringsArray, values: unknown[]): string {\n\tlet code = \"\";\n\tfor (let index = 0; index < strings.length; index += 1) {\n\t\tcode += strings[index] ?? \"\";\n\t\tif (index < values.length) {\n\t\t\tcode += String(values[index]);\n\t\t}\n\t}\n\treturn code;\n}\n\n/**\n * Tagged template literal for Shiki syntax highlighting.\n *\n * Returns a `MantleCodeBlockValue` that `CodeBlock.Code` renders.\n * The Vite transform plugin rewrites calls to this function at build time,\n * inlining pre-rendered Shiki HTML so that no highlighting work happens in the browser.\n * Configure it via `mantleCodeBlockPlugins()` in `vite.config.ts`.\n *\n * Interpolated template expressions are supported via placeholder substitution.\n *\n * Line numbers are shown by default (`showLineNumbers` defaults to `true`),\n * except for single-line shell snippets (`bash`, `sh`, `shell`) where they default to `false`.\n *\n * @example\n * ```tsx\n * // Static string (line numbers shown by default)\n * mantleCode(\"typescript\")`const x: string = \"hello\";`\n * // Interpolated string\n * mantleCode(\"typescript\")`const greeting = \"Hello, ${name}!\";`\n * // Disable line numbers\n * mantleCode(\"typescript\", { showLineNumbers: false })`const x = 1;`\n * // Single-line shell — line numbers hidden by default\n * mantleCode(\"bash\")`npm install @ngrok/mantle`\n * ```\n */\nfunction mantleCode(\n\tlanguage: SupportedLanguage,\n\toptions: MantleCodeOptions = {},\n): (strings: TemplateStringsArray, ...values: unknown[]) => MantleCodeBlockValue {\n\tconst { showLineNumbers, highlightLines, lineNumberStart } = options;\n\n\treturn (strings, ...values) => {\n\t\tconst code = buildCodeFromTemplate(strings, values);\n\n\t\treturn createMantleCodeBlockValue({\n\t\t\tlanguage,\n\t\t\tcode,\n\t\t\tpreHtml: undefined,\n\t\t\tpreVals: values.length > 0 ? values : undefined,\n\t\t\thighlightLines,\n\t\t\tlineNumberStart,\n\t\t\tshowLineNumbers: showLineNumbers ?? defaultShowLineNumbers(language, code),\n\t\t});\n\t};\n}\n\nexport { defaultShowLineNumbers, mantleCode };\nexport { createMantleCodeBlockValue };\nexport type { MantleCodeBlockValue, MantleCodeOptions };\n","/**\n * A line range is a string in the format of `start-end` where `start` and `end` are line numbers.\n */\nexport type LineRange = `${number}-${number}`;\n\nconst MAX_EXPANDED_LINE_RANGE_LENGTH = 1_000;\n\n/**\n * Given a list of line ranges and numbers, resolves them into a unique list of line numbers as a set.\n *\n * @example\n * ```tsx\n * const highlightedLines = resolveLineNumbers(1, \"3-5\", 7, \"10-12\");\n * // Returns: Set {1, 3, 4, 5, 7, 10, 11, 12}\n *\n * const singleLine = resolveLineNumbers(42);\n * // Returns: Set {42}\n * ```\n */\nexport function resolveLineNumbers(...items: (LineRange | number)[]): Set<number> {\n\tconst lineNumberSet = new Set<number>();\n\n\tfor (const item of items) {\n\t\tif (typeof item === \"number\") {\n\t\t\tif (!isPositiveLineNumber(item)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// only support integer line numbers\n\t\t\tconst int = Math.floor(item);\n\t\t\tlineNumberSet.add(int);\n\t\t} else {\n\t\t\tconst separatorIndex = item.indexOf(\"-\");\n\t\t\tconst startPart = item.slice(0, separatorIndex);\n\t\t\tconst endPart = item.slice(separatorIndex + 1);\n\t\t\tlet start = Number.parseInt(startPart, 10);\n\t\t\tlet end = Number.parseInt(endPart, 10);\n\n\t\t\t// ignore invalid ranges that don't contain valid line numbers\n\t\t\tif (!isPositiveLineNumber(start) || !isPositiveLineNumber(end)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// swap start and end if they are backwards\n\t\t\tif (start > end) {\n\t\t\t\t[start, end] = [end, start];\n\t\t\t}\n\n\t\t\tif (end - start + 1 > MAX_EXPANDED_LINE_RANGE_LENGTH) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// add all line numbers in the range, inclusive\n\t\t\tfor (let i = start; i <= end; i++) {\n\t\t\t\tlineNumberSet.add(i);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lineNumberSet;\n}\n\n/**\n * Type Predicate: checks if a value is a positive, finite integer.\n */\nconst isPositiveLineNumber = (value: number | undefined): value is number =>\n\tvalue != null && !Number.isNaN(value) && value > 0 && Number.isFinite(value);\n","import type { LineRange } from \"./line-numbers.js\";\nimport { resolveLineNumbers } from \"./line-numbers.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\n\n/** Removes trailing `\\n` and `\\r` characters from the end of a string. */\nfunction trimTrailingNewlines(input: string): string {\n\tlet end = input.length;\n\twhile (end > 0 && (input.charCodeAt(end - 1) === 10 || input.charCodeAt(end - 1) === 13)) {\n\t\tend -= 1;\n\t}\n\treturn end === input.length ? input : input.slice(0, end);\n}\n\n/** Splits Shiki-highlighted HTML into per-line content, unwrapping `<span class=\"line\">` wrappers. */\nfunction splitHighlightedHtmlIntoLines(html: string): string[] {\n\tconst normalizedHtml = trimTrailingNewlines(html).replaceAll(\"\\r\\n\", \"\\n\").replaceAll(\"\\r\", \"\\n\");\n\tconst shikiLines = normalizedHtml.split(\"\\n\");\n\tconst linePrefix = '<span class=\"line\">';\n\tconst lineSuffix = \"</span>\";\n\n\tfor (let i = 0; i < shikiLines.length; i++) {\n\t\tconst line = shikiLines[i] ?? \"\";\n\t\tif (line.startsWith(linePrefix) && line.endsWith(lineSuffix)) {\n\t\t\tshikiLines[i] = line.slice(linePrefix.length, line.length - lineSuffix.length);\n\t\t}\n\t}\n\n\treturn shikiLines;\n}\n\n/** Input for {@link decorateHighlightedHtml}. */\ntype DecorateHighlightedHtmlInput = {\n\thighlightLines?: (LineRange | number)[] | undefined;\n\thtml: string;\n\tlineNumberStart?: number | undefined;\n\tshowLineNumbers?: boolean | undefined;\n};\n\n/**\n * Wraps each line of Shiki-highlighted HTML in Mantle's line-number and\n * line-highlight markup, producing the final HTML rendered by `CodeBlock.Code`.\n */\nfunction decorateHighlightedHtml({\n\thighlightLines,\n\thtml,\n\tlineNumberStart = 1,\n\tshowLineNumbers = false,\n}: DecorateHighlightedHtmlInput): string {\n\tconst highlightedLineNumbers = resolveLineNumbers(...(highlightLines ?? []));\n\tconst lines = splitHighlightedHtmlIntoLines(html);\n\tlet output = \"\";\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst line = lines[i] ?? \"\";\n\t\tconst lineNumber = lineNumberStart + i;\n\t\tconst lineClassName = cx(\n\t\t\t\"mantle-code-line\",\n\t\t\thighlightedLineNumbers.has(lineNumber) && \"mantle-code-line-highlighted\",\n\t\t);\n\n\t\tconst lineNumberHtml = showLineNumbers\n\t\t\t? `<span class=\"mantle-code-line-number\" data-slot=\"line-number\">${lineNumber}</span>`\n\t\t\t: \"\";\n\n\t\toutput += `<span class=\"${lineClassName}\" data-line-number=\"${lineNumber}\">${lineNumberHtml}<span class=\"mantle-code-line-content\" data-slot=\"line-content\">${line === \"\" ? \" \" : line}</span></span>`;\n\t}\n\treturn output;\n}\n\nexport { decorateHighlightedHtml };\nexport type { DecorateHighlightedHtmlInput };\n","import type { SupportedLanguage } from \"./supported-languages.js\";\n\nconst indentations = [\"tabs\", \"spaces\"] as const;\ntype Indentation = (typeof indentations)[number];\n\n/**\n * Type Predicate: checks if the given value is a valid indentation type.\n */\nfunction isIndentation(input: unknown): input is Indentation {\n\treturn indentations.includes(input as Indentation);\n}\n\n/**\n * Infers the indentation type based on the language and preferred indentation.\n *\n * @param language - The language to check.\n * @param preferredIndentation - The preferred indentation type (overrides what is detected).\n */\nfunction inferIndentation(\n\tlanguage: SupportedLanguage,\n\tpreferredIndentation: Indentation | undefined,\n) {\n\t// if the user has a preferred indentation, use that regardless of the language\n\tif (preferredIndentation) {\n\t\treturn preferredIndentation;\n\t}\n\n\tif (isTabIndentedLanguage(language)) {\n\t\treturn \"tabs\";\n\t}\n\n\tif (isSpaceIndentedLanguage(language)) {\n\t\treturn \"spaces\";\n\t}\n\n\treturn \"spaces\";\n}\n\nexport {\n\t//,\n\tindentations,\n\tinferIndentation,\n\tisIndentation,\n};\n\nexport type {\n\t//,\n\tIndentation,\n};\n\n/**\n * Languages that require or strongly prefer tabs\n */\nconst tabIndentedLanguages = [\n\t\"csharp\",\n\t\"css\",\n\t\"go\",\n\t\"html\",\n\t\"java\",\n\t\"javascript\",\n\t\"js\",\n\t\"jsx\",\n\t\"ts\",\n\t\"tsx\",\n\t\"typescript\",\n\t\"xml\",\n] as const satisfies SupportedLanguage[];\n\nconst tabIndentedLanguageSet = new Set<string>(tabIndentedLanguages);\n\n/**\n * Languages that require or strongly prefer spaces\n */\nconst spaceIndentedLanguages = [\n\t\"python\",\n\t\"py\",\n\t\"yaml\",\n\t\"yml\",\n\t\"ruby\",\n\t\"rb\",\n] as const satisfies SupportedLanguage[];\n\nconst spaceIndentedLanguageSet = new Set<string>(spaceIndentedLanguages);\n\ntype TabIndentedLanguage = (typeof tabIndentedLanguages)[number];\ntype SpaceIndentedLanguage = (typeof spaceIndentedLanguages)[number];\n\n/**\n * Type Predicate: checks if the given value is a required/preferred tab-indented language.\n */\nfunction isTabIndentedLanguage(value: SupportedLanguage): value is TabIndentedLanguage {\n\treturn tabIndentedLanguageSet.has(value);\n}\n\n/**\n * Type Predicate: checks if the given value is a required/preferred space-indented language.\n */\nfunction isSpaceIndentedLanguage(value: SupportedLanguage): value is SpaceIndentedLanguage {\n\treturn spaceIndentedLanguageSet.has(value);\n}\n","import type { Indentation } from \"./indentation.js\";\n\ntype Options = {\n\t/**\n\t * The indentation type to use. Can be either \"tabs\" or \"spaces\".\n\t * @default \"spaces\"\n\t */\n\tindentation?: Indentation;\n};\n\n/**\n * Trim any leading and trailing whitespace/empty lines, convert leading\n * indentation to the given options.indentation\n */\nfunction normalizeIndentation(value: string, options?: Options): string {\n\tconst indentation = options?.indentation ?? \"spaces\";\n\tconst normalizedLineEndings = value.replace(/\\r\\n?/g, \"\\n\");\n\tconst trimmed = normalizedLineEndings.trim();\n\n\tif (trimmed === \"\") {\n\t\treturn \"\";\n\t}\n\n\tconst minIndent = findMinIndent(normalizedLineEndings);\n\tconst lines = trimmed.split(\"\\n\");\n\tconst normalizedLines = new Array<string>(lines.length);\n\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst line = lines[i];\n\t\tif (line == null) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst dedentedLine = startsWithNonWhitespace(line) ? line : line.slice(minIndent);\n\t\tnormalizedLines[i] = normalizeLeadingIndentation(dedentedLine, indentation);\n\t}\n\n\treturn normalizedLines.join(\"\\n\");\n}\n\nexport {\n\t//,\n\tnormalizeIndentation,\n};\n\n/**\n * Rewrites only the leading indentation of a non-empty line into the requested\n * indentation style, leaving the rest of the line untouched.\n */\nfunction normalizeLeadingIndentation(line: string, indentation: Indentation): string {\n\tlet indentEnd = 0;\n\twhile (indentEnd < line.length) {\n\t\tconst character = line[indentEnd];\n\t\tif (character !== \" \" && character !== \"\\t\") {\n\t\t\tbreak;\n\t\t}\n\t\tindentEnd += 1;\n\t}\n\n\tif (indentEnd === 0 || indentEnd === line.length) {\n\t\treturn line;\n\t}\n\n\tconst leadingWhitespace = line.slice(0, indentEnd);\n\tconst normalizedLeadingWhitespace =\n\t\tindentation === \"spaces\"\n\t\t\t? leadingWhitespace.replace(/\\t/g, \" \")\n\t\t\t: leadingWhitespace.replace(/ {2}/g, \"\\t\");\n\n\treturn normalizedLeadingWhitespace + line.slice(indentEnd);\n}\n\n/**\n * Returns true when a line begins with visible content instead of indentation.\n */\nfunction startsWithNonWhitespace(line: string): boolean {\n\tconst firstCharacter = line[0];\n\treturn firstCharacter != null && firstCharacter !== \" \" && firstCharacter !== \"\\t\";\n}\n\n/**\n * Find the shortest indentation of a multiline string.\n */\nfunction findMinIndent(value: string): number {\n\tlet minIndent = Number.POSITIVE_INFINITY;\n\tlet indent = 0;\n\tlet atLineStart = true;\n\n\tfor (let i = 0; i < value.length; i++) {\n\t\tconst char = value[i];\n\n\t\tif (atLineStart) {\n\t\t\tif (char === \" \" || char === \"\\t\") {\n\t\t\t\tindent += 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"\\n\" || char === \"\\r\") {\n\t\t\t\tindent = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (indent < minIndent) {\n\t\t\t\tminIndent = indent;\n\t\t\t\tif (minIndent === 0) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\tatLineStart = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"\\n\" || char === \"\\r\") {\n\t\t\tatLineStart = true;\n\t\t\tindent = 0;\n\t\t}\n\t}\n\n\treturn minIndent === Number.POSITIVE_INFINITY ? 0 : minIndent;\n}\n","/**\n * List of supported languages for syntax highlighting.\n * @private\n */\nexport const supportedLanguages = [\n\t\"bash\",\n\t\"cs\",\n\t\"csharp\",\n\t\"css\",\n\t\"go\",\n\t\"html\",\n\t\"java\",\n\t\"javascript\",\n\t\"js\",\n\t\"json\",\n\t\"jsx\",\n\t\"plain\",\n\t\"plaintext\",\n\t\"py\",\n\t\"python\",\n\t\"rb\",\n\t\"ruby\",\n\t\"rust\",\n\t\"sh\",\n\t\"shell\",\n\t\"text\",\n\t\"ts\",\n\t\"tsx\",\n\t\"txt\",\n\t\"typescript\",\n\t\"xml\",\n\t\"yaml\",\n\t\"yml\",\n] as const;\n\n/**\n * Supported languages for syntax highlighting.\n */\ntype SupportedLanguage = (typeof supportedLanguages)[number];\nconst supportedLanguageSet = new Set<SupportedLanguage>(supportedLanguages);\nconst defaultLanguage = \"text\" satisfies SupportedLanguage;\n\n/**\n * Parses a markdown code block (```) language class into a SupportedLanguage.\n * Defaults to \"text\" if no supported language is found.\n */\nfunction parseLanguage(\n\tvalue: `language-${string}` | `lang-${string}` | (string & {}) | undefined,\n): SupportedLanguage {\n\tconst trimmed = value?.trim() ?? \"\";\n\tif (!trimmed) {\n\t\treturn defaultLanguage;\n\t}\n\n\t// remove leading \"language-\" and \"lang-\" prefixes\n\t// find first '-' and slice from there\n\tconst prefixSeparatorIndex = trimmed.indexOf(\"-\");\n\tconst maybeLanguage =\n\t\tprefixSeparatorIndex === -1 ? trimmed : trimmed.slice(prefixSeparatorIndex + 1);\n\n\treturn isSupportedLanguage(maybeLanguage) ? maybeLanguage : defaultLanguage;\n}\n\n/**\n * Type Predicate: checks if an arbitrary value is a supported syntax highlighting language.\n */\nconst isSupportedLanguage = (value: unknown): value is SupportedLanguage => {\n\treturn typeof value === \"string\" && supportedLanguageSet.has(value as SupportedLanguage);\n};\n\nexport {\n\t//,\n\tisSupportedLanguage,\n\tparseLanguage,\n};\n\nexport type { SupportedLanguage };\n","import type { LineRange } from \"./line-numbers.js\";\n\n/** Parses a boolean or `\"true\"`/`\"false\"` string into a boolean. Returns `undefined` for unrecognized values. */\nfunction parseCodeBlockShowLineNumbers(value: unknown): boolean | undefined {\n\tif (typeof value === \"boolean\") {\n\t\treturn value;\n\t}\n\tif (typeof value === \"string\") {\n\t\tif (value === \"true\") {\n\t\t\treturn true;\n\t\t}\n\t\tif (value === \"false\") {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** Parses a positive integer (or its string representation) for the starting line number. Returns `undefined` for invalid values. */\nfunction parseCodeBlockLineNumberStart(value: unknown): number | undefined {\n\tif (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n\t\treturn Math.floor(value);\n\t}\n\tif (typeof value === \"string\" && /^\\d+$/.test(value)) {\n\t\tconst parsed = Number.parseInt(value, 10);\n\t\treturn parsed > 0 ? parsed : undefined;\n\t}\n\treturn undefined;\n}\n\n/** Parses highlight line specifications from an array or comma-separated string (e.g. `[1, \"3-5\"]` or `\"1,3-5\"`). Returns `undefined` when no valid entries are found. */\nfunction parseCodeBlockHighlightLines(value: unknown): (LineRange | number)[] | undefined {\n\tconst parseSingle = (item: unknown): LineRange | number | undefined => {\n\t\tif (typeof item === \"number\") {\n\t\t\treturn Number.isFinite(item) && item > 0 ? Math.floor(item) : undefined;\n\t\t}\n\t\tif (typeof item === \"string\") {\n\t\t\tconst trimmed = item.trim();\n\t\t\tif (/^\\d+$/.test(trimmed)) {\n\t\t\t\tconst parsed = Number.parseInt(trimmed, 10);\n\t\t\t\treturn parsed > 0 ? parsed : undefined;\n\t\t\t}\n\t\t\tif (/^\\d+-\\d+$/.test(trimmed)) {\n\t\t\t\tconst [startStr, endStr] = trimmed.split(\"-\");\n\t\t\t\tconst start = Number.parseInt(startStr ?? \"\", 10);\n\t\t\t\tconst end = Number.parseInt(endStr ?? \"\", 10);\n\t\t\t\tif (start > 0 && end > 0) {\n\t\t\t\t\treturn trimmed as LineRange;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t};\n\n\tif (typeof value === \"string\") {\n\t\tconst parsed: (LineRange | number)[] = [];\n\t\tconst segments = value.split(\",\");\n\t\tfor (const segment of segments) {\n\t\t\tconst maybe = parseSingle(segment);\n\t\t\tif (maybe != null) {\n\t\t\t\tparsed.push(maybe);\n\t\t\t}\n\t\t}\n\t\treturn parsed.length > 0 ? parsed : undefined;\n\t}\n\n\tif (!Array.isArray(value)) {\n\t\treturn undefined;\n\t}\n\tconst parsed: (LineRange | number)[] = [];\n\tfor (const item of value) {\n\t\tconst maybe = parseSingle(item);\n\t\tif (maybe != null) {\n\t\t\tparsed.push(maybe);\n\t\t}\n\t}\n\treturn parsed.length > 0 ? parsed : undefined;\n}\n\nexport {\n\t//,\n\tparseCodeBlockHighlightLines,\n\tparseCodeBlockLineNumberStart,\n\tparseCodeBlockShowLineNumbers,\n};\n","import type { SupportedLanguage } from \"./supported-languages.js\";\nimport { isSupportedLanguage } from \"./supported-languages.js\";\nimport { parseBooleanish } from \"../../types/booleanish.js\";\nimport { type Indentation, isIndentation } from \"./indentation.js\";\nimport {\n\tparseCodeBlockHighlightLines,\n\tparseCodeBlockLineNumberStart,\n\tparseCodeBlockShowLineNumbers,\n} from \"./parse-line-options.js\";\n\nconst modes = [\n\t//,\n\t\"cli\",\n\t\"file\",\n\t\"traffic-policy\",\n] as const;\n/** The visual mode preset for a code block (determines header icon). */\ntype Mode = (typeof modes)[number];\n\n/** User-facing input shape for code block metadata (metastring key-value pairs). */\ntype MetaInput = {\n\tcollapsible?: boolean | undefined;\n\tdisableCopy?: boolean | undefined;\n\tindentation?: Indentation | undefined;\n\tmode?: Mode | undefined;\n\ttitle?: string | undefined;\n};\n\n/** Resolved code block metadata with defaults applied. */\ntype Meta = {\n\tcollapsible: boolean;\n\tdisableCopy: boolean;\n\tindentation?: Indentation | undefined;\n\tmode?: Mode | undefined;\n\ttitle?: string | undefined;\n};\n\nconst defaultMeta = {\n\tcollapsible: false,\n\tdisableCopy: false,\n\tindentation: undefined,\n\tmode: undefined,\n\ttitle: undefined,\n} as const satisfies Meta;\n\n/** The type of the default metadata constant. */\ntype DefaultMeta = typeof defaultMeta;\n\n/** Parses a code fence metastring (e.g. `title=\"example\" collapsible`) into a structured `Meta` object. */\nfunction parseMetastring(input: string | undefined): Meta {\n\tconst metastring = input?.trim() ?? \"\";\n\tif (!metastring) {\n\t\treturn defaultMeta;\n\t}\n\n\tconst metaJson: Record<string, unknown> = {};\n\tconst tokens = tokenizeMetastring(metastring);\n\tfor (const token of tokens) {\n\t\tconst separatorIndex = token.indexOf(\"=\");\n\t\tconst key = separatorIndex === -1 ? token : token.slice(0, separatorIndex);\n\t\tconst value = separatorIndex === -1 ? undefined : token.slice(separatorIndex + 1);\n\n\t\tif (!key) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst normalized = normalizeValue(value);\n\t\tmetaJson[key] = normalized ?? true;\n\t}\n\n\treturn parseMetaJson(metaJson);\n}\n\n/** Strips surrounding double-quotes and trims whitespace from a metastring value. */\nfunction normalizeValue(value: string | undefined) {\n\tif (value == null) {\n\t\treturn undefined;\n\t}\n\tconst trimmed = value.trim();\n\tconst lastIndex = trimmed.length - 1;\n\tif (lastIndex >= 1 && trimmed.charCodeAt(0) === 34 && trimmed.charCodeAt(lastIndex) === 34) {\n\t\treturn trimmed.slice(1, lastIndex);\n\t}\n\treturn trimmed;\n}\n\n/** Splits a metastring into space-delimited tokens, respecting double-quoted segments. */\nfunction tokenizeMetastring(value: string | undefined): string[] {\n\tconst input = value?.trim() ?? \"\";\n\tconst result: string[] = [];\n\n\tlet current = \"\";\n\tlet inQuotes = false;\n\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst char = input[i] ?? \"\";\n\t\tif (char === \" \" && !inQuotes) {\n\t\t\tif (current) {\n\t\t\t\tresult.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t} else if (char === '\"') {\n\t\t\tinQuotes = !inQuotes;\n\t\t\tcurrent += char;\n\t\t} else {\n\t\t\tcurrent += char;\n\t\t}\n\t}\n\n\tif (current) {\n\t\tresult.push(current);\n\t}\n\n\treturn result;\n}\n\n/** Type predicate: checks if a value is a valid code block `Mode`. */\nfunction isMode(input: unknown): input is Mode {\n\treturn input === \"cli\" || input === \"file\" || input === \"traffic-policy\";\n}\n\n/** Converts a raw key-value record (from tokenized metastring) into a validated `Meta` object. */\nfunction parseMetaJson(input: Record<string, unknown>): Meta {\n\tconst {\n\t\tcollapsible = defaultMeta.collapsible,\n\t\tdisableCopy = defaultMeta.disableCopy,\n\t\tindentation = defaultMeta.indentation,\n\t\tmode = defaultMeta.mode,\n\t\ttitle = defaultMeta.title,\n\t} = input;\n\n\treturn {\n\t\tcollapsible:\n\t\t\ttypeof collapsible === \"string\" || typeof collapsible === \"boolean\"\n\t\t\t\t? parseBooleanish(collapsible)\n\t\t\t\t: defaultMeta.collapsible,\n\t\tdisableCopy:\n\t\t\ttypeof disableCopy === \"string\" || typeof disableCopy === \"boolean\"\n\t\t\t\t? parseBooleanish(disableCopy)\n\t\t\t\t: defaultMeta.disableCopy,\n\t\tindentation: isIndentation(indentation) ? indentation : defaultMeta.indentation,\n\t\tmode: isMode(mode) ? mode : defaultMeta.mode,\n\t\ttitle: typeof title === \"string\" ? title.trim() : defaultMeta.title,\n\t};\n}\n\n/** Props that the rehype plugin attaches to `<pre>` elements for pre-rendered code blocks. */\ntype ResolvePreRenderedCodeBlockPropsInput = {\n\tcollapsible?: unknown;\n\tdisableCopy?: unknown;\n\tmantleCode?: unknown;\n\tmantleCollapsible?: unknown;\n\tmantleDisableCopy?: unknown;\n\tmantleHighlightLines?: unknown;\n\tmantleLanguage?: unknown;\n\tmantleLineNumberStart?: unknown;\n\tmantleMode?: unknown;\n\tmantlePreHtml?: unknown;\n\tmantleShowLineNumbers?: unknown;\n\tmantleTitle?: unknown;\n\tmode?: unknown;\n\ttitle?: unknown;\n};\n\n/** Combined input type for a `<pre>` element that may carry both metastring and pre-rendered props. */\ntype CodeBlockPreElementInput = MetaInput & ResolvePreRenderedCodeBlockPropsInput;\n\ntype PreRenderedCodeBlockPropKey = keyof ResolvePreRenderedCodeBlockPropsInput;\n\n/** Normalized code block props extracted from pre-rendered `<pre>` element attributes. */\ntype ResolvedPreRenderedCodeBlockProps = {\n\tcode: string | undefined;\n\tcollapsible: boolean | undefined;\n\tdisableCopy: boolean | undefined;\n\thighlightLines: (number | `${number}-${number}`)[] | undefined;\n\tlanguage: SupportedLanguage | undefined;\n\tlineNumberStart: number | undefined;\n\tmode: Mode | undefined;\n\tpreHtml: string | undefined;\n\trawLanguage: unknown;\n\tshowLineNumbers: boolean | undefined;\n\ttitle: string | undefined;\n};\n\n/** Result of {@link resolvePreRenderedCodeBlockProps}: extracted Mantle props and remaining pass-through props. */\ntype ResolvePreRenderedCodeBlockPropsResult<T extends Record<string, unknown>> = {\n\tmantleCode: ResolvedPreRenderedCodeBlockProps | undefined;\n\tprops: Omit<T, PreRenderedCodeBlockPropKey>;\n};\n\n/**\n * Extracts and normalizes `mantle*` props from a `<pre>` element's attributes,\n * separating them from pass-through props. Returns `undefined` for the Mantle\n * payload when no pre-rendered attributes are present.\n */\nfunction resolvePreRenderedCodeBlockProps<\n\tT extends ResolvePreRenderedCodeBlockPropsInput & Record<string, unknown>,\n>(input: T): ResolvePreRenderedCodeBlockPropsResult<T> {\n\tconst {\n\t\tcollapsible,\n\t\tdisableCopy,\n\t\tmantleCode,\n\t\tmantleCollapsible,\n\t\tmantleDisableCopy,\n\t\tmantleHighlightLines,\n\t\tmantleLanguage,\n\t\tmantleLineNumberStart,\n\t\tmantleMode,\n\t\tmantlePreHtml,\n\t\tmantleShowLineNumbers,\n\t\tmantleTitle,\n\t\tmode,\n\t\ttitle,\n\t\t...props\n\t} = input;\n\n\tconst hasPayload =\n\t\tmantleLanguage != null ||\n\t\tmantleCode != null ||\n\t\tmantlePreHtml != null ||\n\t\tmantleShowLineNumbers != null ||\n\t\tmantleHighlightLines != null ||\n\t\tmantleLineNumberStart != null ||\n\t\tmantleCollapsible != null ||\n\t\tmantleDisableCopy != null ||\n\t\tmantleMode != null ||\n\t\tmantleTitle != null;\n\n\tif (!hasPayload) {\n\t\treturn {\n\t\t\tmantleCode: undefined,\n\t\t\tprops: props as Omit<T, PreRenderedCodeBlockPropKey>,\n\t\t};\n\t}\n\n\treturn {\n\t\tmantleCode: {\n\t\t\tcode: typeof mantleCode === \"string\" ? mantleCode : undefined,\n\t\t\tcollapsible:\n\t\t\t\t(typeof mantleCollapsible === \"string\" || typeof mantleCollapsible === \"boolean\"\n\t\t\t\t\t? parseBooleanish(mantleCollapsible)\n\t\t\t\t\t: undefined) ??\n\t\t\t\t(typeof collapsible === \"string\" || typeof collapsible === \"boolean\"\n\t\t\t\t\t? parseBooleanish(collapsible)\n\t\t\t\t\t: undefined),\n\t\t\tdisableCopy:\n\t\t\t\ttypeof mantleDisableCopy === \"string\" || typeof mantleDisableCopy === \"boolean\"\n\t\t\t\t\t? parseBooleanish(mantleDisableCopy)\n\t\t\t\t\t: typeof disableCopy === \"string\" || typeof disableCopy === \"boolean\"\n\t\t\t\t\t\t? parseBooleanish(disableCopy)\n\t\t\t\t\t\t: undefined,\n\t\t\thighlightLines: parseCodeBlockHighlightLines(mantleHighlightLines),\n\t\t\tlanguage:\n\t\t\t\ttypeof mantleLanguage === \"string\" && isSupportedLanguage(mantleLanguage)\n\t\t\t\t\t? mantleLanguage\n\t\t\t\t\t: undefined,\n\t\t\tlineNumberStart: parseCodeBlockLineNumberStart(mantleLineNumberStart),\n\t\t\tmode: isMode(mantleMode) ? mantleMode : isMode(mode) ? mode : undefined,\n\t\t\tpreHtml: typeof mantlePreHtml === \"string\" ? mantlePreHtml : undefined,\n\t\t\trawLanguage: mantleLanguage,\n\t\t\tshowLineNumbers: parseCodeBlockShowLineNumbers(mantleShowLineNumbers),\n\t\t\ttitle:\n\t\t\t\ttypeof mantleTitle === \"string\"\n\t\t\t\t\t? mantleTitle.trim()\n\t\t\t\t\t: typeof title === \"string\"\n\t\t\t\t\t\t? title.trim()\n\t\t\t\t\t\t: undefined,\n\t\t},\n\t\tprops: props as Omit<T, PreRenderedCodeBlockPropKey>,\n\t};\n}\n\nexport { resolvePreRenderedCodeBlockProps };\nexport {\n\t//,\n\tdefaultMeta,\n\tnormalizeValue,\n\tparseMetastring,\n\ttokenizeMetastring,\n};\n\nexport type {\n\tCodeBlockPreElementInput,\n\tDefaultMeta,\n\tMeta,\n\tMetaInput,\n\tMode,\n\tResolvePreRenderedCodeBlockPropsInput,\n\tResolvePreRenderedCodeBlockPropsResult,\n\tResolvedPreRenderedCodeBlockProps,\n};\n"],"mappings":"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"}
@@ -72,6 +72,126 @@ type Options = {
72
72
  */
73
73
  declare function normalizeIndentation(value: string, options?: Options): string;
74
74
  //#endregion
75
+ //#region src/components/code-block/mantle-code.d.ts
76
+ /** Returns the default `showLineNumbers` value for a given language and code string. Single-line shell snippets default to `false`; everything else defaults to `true`. */
77
+ declare function defaultShowLineNumbers(language: SupportedLanguage, code: string): boolean;
78
+ declare const mantleCodeBlockValueBrand: unique symbol;
79
+ /**
80
+ * The value produced by `mantleCode()`. Contains pre-rendered Shiki HTML (injected
81
+ * by the Vite plugin at build time) and the original code string for the copy button.
82
+ *
83
+ * `~preHtml` is required at render time. Runtime syntax highlighting is intentionally
84
+ * unsupported; only placeholder substitution for interpolated values is performed.
85
+ */
86
+ type MantleCodeBlockValue = {
87
+ /**
88
+ * Nominal type brand to prevent accidental use of plain objects.
89
+ */
90
+ [mantleCodeBlockValueBrand]: true;
91
+ /**
92
+ * The language used for syntax highlighting.
93
+ */
94
+ language: SupportedLanguage;
95
+ /**
96
+ * The original code string (used by the copy button).
97
+ */
98
+ code: string;
99
+ /**
100
+ * Fully pre-rendered Shiki HTML injected by the Vite plugin or server highlighter.
101
+ * This must be present for rendering.
102
+ *
103
+ * **Security:** This HTML is injected via `dangerouslySetInnerHTML`. It must
104
+ * come from a trusted source (Shiki output from the Vite plugin or
105
+ * `createMantleServerSyntaxHighlighter`). Never pass unsanitized user input.
106
+ */
107
+ "~preHtml"?: string | undefined;
108
+ /**
109
+ * Runtime values used to replace `SHIKI_VAL_N` placeholders in `~preHtml`.
110
+ * This enables interpolated template expressions while preserving build-time highlighting.
111
+ */
112
+ "~preVals"?: unknown[] | undefined;
113
+ /**
114
+ * Placeholder token prefix used by the Vite transform for interpolated values.
115
+ * When omitted, CodeBlock falls back to the legacy `SHIKI_VAL_<n>` format.
116
+ */
117
+ "~preValToken"?: string | undefined;
118
+ /**
119
+ * Optional default for line-number rendering when this value is displayed.
120
+ */
121
+ "~showLineNumbers"?: boolean | undefined;
122
+ /**
123
+ * Optional default highlighted line numbers/ranges when this value is displayed.
124
+ */
125
+ "~highlightLines"?: (LineRange | number)[] | undefined;
126
+ /**
127
+ * Optional default start line number when line numbers are displayed.
128
+ * @default 1
129
+ */
130
+ "~lineNumberStart"?: number | undefined;
131
+ };
132
+ /** Maps each key starting with `OldPrefix` to `NewPrefix`, leaving other keys unchanged. */
133
+ type ReplacePrefix<T, OldPrefix extends string, NewPrefix extends string> = { [K in keyof T as K extends `${OldPrefix}${infer Rest}` ? `${NewPrefix}${Rest}` : K]: T[K] };
134
+ /** Public input shape for `createMantleCodeBlockValue`, with `~`-prefixed keys renamed to unprefixed. */
135
+ type MantleCodeBlockValueInput = ReplacePrefix<Omit<MantleCodeBlockValue, typeof mantleCodeBlockValueBrand>, "~", "">;
136
+ /** Options for configuring line numbers, highlights, and indentation in `mantleCode()`. */
137
+ type MantleCodeOptions = {
138
+ /** Line numbers or ranges to visually highlight in the code block. */highlightLines?: (LineRange | number)[] | undefined; /** The indentation style to use when normalizing the code string. */
139
+ indentation?: Indentation | undefined;
140
+ /**
141
+ * The starting line number when line numbers are displayed.
142
+ * @default 1
143
+ */
144
+ lineNumberStart?: number | undefined;
145
+ /**
146
+ * Whether to show line numbers in the code block. Defaults to `true` for most
147
+ * languages, but `false` for single-line shell snippets (`bash`, `sh`, `shell`).
148
+ */
149
+ showLineNumbers?: boolean | undefined;
150
+ };
151
+ /**
152
+ * Creates a `MantleCodeBlockValue` for use with `CodeBlock.Code`.
153
+ *
154
+ * **Security:** The `preHtml` field is rendered via `dangerouslySetInnerHTML`.
155
+ * Only pass HTML produced by Shiki (via the Vite plugin or
156
+ * `createMantleServerSyntaxHighlighter`). Never pass unsanitized user input as `preHtml`.
157
+ */
158
+ declare function createMantleCodeBlockValue({
159
+ preHtml,
160
+ preValToken,
161
+ preVals,
162
+ highlightLines,
163
+ lineNumberStart,
164
+ showLineNumbers,
165
+ code,
166
+ language
167
+ }: MantleCodeBlockValueInput): MantleCodeBlockValue;
168
+ /**
169
+ * Tagged template literal for Shiki syntax highlighting.
170
+ *
171
+ * Returns a `MantleCodeBlockValue` that `CodeBlock.Code` renders.
172
+ * The Vite transform plugin rewrites calls to this function at build time,
173
+ * inlining pre-rendered Shiki HTML so that no highlighting work happens in the browser.
174
+ * Configure it via `mantleCodeBlockPlugins()` in `vite.config.ts`.
175
+ *
176
+ * Interpolated template expressions are supported via placeholder substitution.
177
+ *
178
+ * Line numbers are shown by default (`showLineNumbers` defaults to `true`),
179
+ * except for single-line shell snippets (`bash`, `sh`, `shell`) where they default to `false`.
180
+ *
181
+ * @example
182
+ * ```tsx
183
+ * // Static string (line numbers shown by default)
184
+ * mantleCode("typescript")`const x: string = "hello";`
185
+ * // Interpolated string
186
+ * mantleCode("typescript")`const greeting = "Hello, ${name}!";`
187
+ * // Disable line numbers
188
+ * mantleCode("typescript", { showLineNumbers: false })`const x = 1;`
189
+ * // Single-line shell — line numbers hidden by default
190
+ * mantleCode("bash")`npm install @ngrok/mantle`
191
+ * ```
192
+ */
193
+ declare function mantleCode(language: SupportedLanguage, options?: MantleCodeOptions): (strings: TemplateStringsArray, ...values: unknown[]) => MantleCodeBlockValue;
194
+ //#endregion
75
195
  //#region src/components/code-block/parse-line-options.d.ts
76
196
  /** Parses a boolean or `"true"`/`"false"` string into a boolean. Returns `undefined` for unrecognized values. */
77
197
  declare function parseCodeBlockShowLineNumbers(value: unknown): boolean | undefined;
@@ -161,5 +281,5 @@ type ResolvePreRenderedCodeBlockPropsResult<T extends Record<string, unknown>> =
161
281
  */
162
282
  declare function resolvePreRenderedCodeBlockProps<T extends ResolvePreRenderedCodeBlockPropsInput & Record<string, unknown>>(input: T): ResolvePreRenderedCodeBlockPropsResult<T>;
163
283
  //#endregion
164
- export { parseLanguage as C, LineRange as D, decorateHighlightedHtml as E, isSupportedLanguage as S, DecorateHighlightedHtmlInput as T, normalizeIndentation as _, Mode as a, isIndentation as b, ResolvedPreRenderedCodeBlockProps as c, parseMetastring as d, resolvePreRenderedCodeBlockProps as f, parseCodeBlockShowLineNumbers as g, parseCodeBlockLineNumberStart as h, MetaInput as i, defaultMeta as l, parseCodeBlockHighlightLines as m, DefaultMeta as n, ResolvePreRenderedCodeBlockPropsInput as o, tokenizeMetastring as p, Meta as r, ResolvePreRenderedCodeBlockPropsResult as s, CodeBlockPreElementInput as t, normalizeValue as u, Indentation as v, supportedLanguages as w, SupportedLanguage as x, inferIndentation as y };
165
- //# sourceMappingURL=resolve-pre-rendered-props-51i50IL2.d.ts.map
284
+ export { DecorateHighlightedHtmlInput as A, Indentation as C, isSupportedLanguage as D, SupportedLanguage as E, LineRange as M, parseLanguage as O, normalizeIndentation as S, isIndentation as T, MantleCodeBlockValue as _, Mode as a, defaultShowLineNumbers as b, ResolvedPreRenderedCodeBlockProps as c, parseMetastring as d, resolvePreRenderedCodeBlockProps as f, parseCodeBlockShowLineNumbers as g, parseCodeBlockLineNumberStart as h, MetaInput as i, decorateHighlightedHtml as j, supportedLanguages as k, defaultMeta as l, parseCodeBlockHighlightLines as m, DefaultMeta as n, ResolvePreRenderedCodeBlockPropsInput as o, tokenizeMetastring as p, Meta as r, ResolvePreRenderedCodeBlockPropsResult as s, CodeBlockPreElementInput as t, normalizeValue as u, MantleCodeOptions as v, inferIndentation as w, mantleCode as x, createMantleCodeBlockValue as y };
285
+ //# sourceMappingURL=resolve-pre-rendered-props-B3YDbOFZ.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { t as IconButton } from "./icon-button-gO-7F_MZ.js";
2
- import { t as Button } from "./button-BaNwe1ud.js";
2
+ import { t as Button } from "./button-CX98GGHD.js";
3
3
  import { t as DropdownMenu } from "./dropdown-menu-D6MiVSR-.js";
4
4
  import * as _$react from "react";
5
5
  import { ComponentProps, ReactNode } from "react";
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./compose-refs-DeIsFv68.js";import{forwardRef as n,useLayoutEffect as r,useMemo as i,useRef as a,useState as o}from"react";import{jsx as s}from"react/jsx-runtime";const c=n(({children:n,className:r,...i},a)=>{let o=v();return s(`div`,{className:e(`group/table relative w-full overflow-hidden rounded-lg border border-card bg-white dark:bg-gray-100`,r),"data-sticky-active":o.state.hasOverflow&&!o.state.scrolledToEnd||void 0,"data-x-overflow":o.state.hasOverflow,"data-x-scroll-end":o.state.hasOverflow&&o.state.scrolledToEnd,...i,children:s(`div`,{className:e(`scrollbar scroll-fade-x overflow-x-auto overflow-y-clip overscroll-none`,`has-data-mantle-table-sticky-right:[--_fade-right:black]`),"data-scroll-left":o.state.hasOverflow&&!o.state.scrolledToStart||void 0,"data-scroll-right":o.state.hasOverflow&&!o.state.scrolledToEnd||void 0,ref:t(o.ref,a),children:n})})});c.displayName=`TableRoot`;const l=n(({children:t,className:n,...r},i)=>s(`table`,{ref:i,className:e(`table-auto border-collapse caption-bottom w-full min-w-full text-left`,n),...r,children:t}));l.displayName=`TableElement`;const u=n(({children:t,className:n,...r},i)=>s(`thead`,{ref:i,className:e(`border-b border-card-muted`,`divide-y divide-card-muted`,`text-muted bg-base`,`[&>tr]:bg-base`,n),...r,children:t}));u.displayName=`TableHead`;const d=n(({children:t,className:n,...r},i)=>s(`tbody`,{className:e(`divide-y divide-card-muted`,`text-body`,`[thead+&]:border-t [thead+&]:border-card-muted`,`[&>tr]:bg-card [&>tr]:not-only:hover:bg-card-hover`,n),ref:i,...r,children:t}));d.displayName=`TableBody`;const f=n(({children:t,className:n,...r},i)=>s(`tfoot`,{ref:i,className:e(`font-medium text-body`,`border-t border-card-muted`,`divide-y divide-card-muted`,`[&>tr]:bg-gray-50/50 [&>tr]:hover:bg-card-hover`,n),...r,children:t}));f.displayName=`TableFoot`;const p=n(({children:t,className:n,...r},i)=>s(`tr`,{ref:i,className:e(n),...r,children:t}));p.displayName=`TableRow`;const m=n(({children:t,className:n,...r},i)=>s(`th`,{ref:i,className:e(`h-11 px-4 text-left align-middle text-sm font-medium [&:has([role=checkbox])]:pr-0`,n),...r,children:t}));m.displayName=`TableHeader`;const h=n(({children:t,className:n,...r},i)=>s(`td`,{ref:i,className:e(`p-3 align-middle [&:has([role=checkbox])]:pr-0 font-mono text-mono`,n),...r,children:t}));h.displayName=`TableCell`;const g=n(({children:t,className:n,...r},i)=>s(`caption`,{ref:i,className:e(`py-4 text-sm text-gray-500`,`border-t border-card-muted`,n),...r,children:t}));g.displayName=`TableCaption`;const _={Body:d,Caption:g,Cell:h,Element:l,Foot:f,Head:u,Header:m,Root:c,Row:p};function v(){let e=a(null),[t,n]=o({hasOverflow:!1,scrolledToStart:!0,scrolledToEnd:!1});return r(()=>{let t=e.current;if(!t)return;let r=0,i=()=>{let e=t.scrollWidth>t.clientWidth,r=t.scrollLeft<1,i=Math.abs(t.scrollWidth-t.scrollLeft-t.clientWidth)<1;n(t=>t.hasOverflow!==e||t.scrolledToStart!==r||t.scrolledToEnd!==i?{hasOverflow:e,scrolledToStart:r,scrolledToEnd:i}:t)},a=()=>{r===0&&(r=requestAnimationFrame(()=>{r=0,i()}))},o=new ResizeObserver(a);o.observe(t);let s=new MutationObserver(a);return s.observe(t,{childList:!0,subtree:!0}),t.addEventListener(`scroll`,a,{passive:!0}),i(),()=>{cancelAnimationFrame(r),o.disconnect(),s.disconnect(),t.removeEventListener(`scroll`,a)}},[]),i(()=>({ref:e,state:t}),[t])}export{_ as t};
2
+ //# sourceMappingURL=table-DDeUXBex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-DDeUXBex.js","names":[],"sources":["../src/components/table/table.tsx"],"sourcesContent":["import type { ComponentProps, ComponentRef } from \"react\";\nimport { forwardRef, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { composeRefs } from \"../../utils/compose-refs/compose-refs.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\n\n/**\n * The `<Table.Root>` is the root container element for all `Table`s.\n * It provides styling and additional functionality, such as horizontal overflow\n * detection.\n *\n * Must be used as the parent of a `<Table.Element>`.\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#tableroot\n */\nconst Root = forwardRef<ComponentRef<\"div\">, ComponentProps<\"div\">>(\n\t({ children, className, ...props }, ref) => {\n\t\tconst horizontalOverflow = useHorizontalOverflowObserver<ComponentRef<\"div\">>();\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"group/table relative w-full overflow-hidden rounded-lg border border-card bg-white dark:bg-gray-100\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tdata-sticky-active={\n\t\t\t\t\t(horizontalOverflow.state.hasOverflow && !horizontalOverflow.state.scrolledToEnd) ||\n\t\t\t\t\tundefined\n\t\t\t\t}\n\t\t\t\tdata-x-overflow={horizontalOverflow.state.hasOverflow}\n\t\t\t\tdata-x-scroll-end={\n\t\t\t\t\thorizontalOverflow.state.hasOverflow && horizontalOverflow.state.scrolledToEnd\n\t\t\t\t}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={cx(\n\t\t\t\t\t\t\"scrollbar scroll-fade-x overflow-x-auto overflow-y-clip overscroll-none\",\n\t\t\t\t\t\t// When the table contains a sticky right column (e.g., DataTable.ActionCell\n\t\t\t\t\t\t// / DataTable.ActionHeader), suppress the container's right-side fade so the\n\t\t\t\t\t\t// pinned column stays fully opaque. The pinned column provides its own\n\t\t\t\t\t\t// left-side gradient for the scroll-under effect.\n\t\t\t\t\t\t\"has-data-mantle-table-sticky-right:[--_fade-right:black]\",\n\t\t\t\t\t)}\n\t\t\t\t\tdata-scroll-left={\n\t\t\t\t\t\t(horizontalOverflow.state.hasOverflow && !horizontalOverflow.state.scrolledToStart) ||\n\t\t\t\t\t\tundefined\n\t\t\t\t\t}\n\t\t\t\t\tdata-scroll-right={\n\t\t\t\t\t\t(horizontalOverflow.state.hasOverflow && !horizontalOverflow.state.scrolledToEnd) ||\n\t\t\t\t\t\tundefined\n\t\t\t\t\t}\n\t\t\t\t\tref={composeRefs(horizontalOverflow.ref, ref)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t},\n);\nRoot.displayName = \"TableRoot\";\n\n/**\n * The `<Table.Element>` is a structured way to display data in rows and columns. The API\n * matches the HTML `<table>` element 1:1.\n *\n * Permitted content in this order:\n * 1. optional: `<Table.Caption>`\n * 2. 0 or more: `<colgroup>` elements\n * 3. optional: `<Table.Head>`\n * 4. either one of the following:\n * - 0 or more: `<Table.Body>`\n * - 0 or more: `<Table.Row>`\n * 5. optional: `<Table.Foot>`\n *\n * @description\n * Establishes a table formatting context. Elements inside the `<Table.Element>`\n * generate rectangular boxes. Each box occupies a number of table cells\n * according to the following rules:\n * 1. The row boxes fill the table in the source code order from top to bottom.\n * Each row box occupies one row of cells.\n * 2. A row group box occupies one or more row boxes.\n * 3. Column boxes are placed next to each other in source code order.\n * Depending on the value of the dir attribute, the columns are laid in\n * left-to-right or right-to-left direction. A column box occupies one or\n * more columns of table cells.\n * 4. A column group box occupies one or more column boxes.\n * 5. A cell box may span over multiple rows and columns. User agents trim\n * cells to fit in the available number of rows and columns.\n * Table cells do have padding. Boxes that make up a table do not have margins.\n * For more in depth information, see the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table).\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#tableelement\n */\nconst Element = forwardRef<ComponentRef<\"table\">, ComponentProps<\"table\">>(\n\t({ children, className, ...props }, ref) => {\n\t\treturn (\n\t\t\t<table\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"table-auto border-collapse caption-bottom w-full min-w-full text-left\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</table>\n\t\t);\n\t},\n);\nElement.displayName = \"TableElement\";\n\n/**\n * The `<Table.Head>` is a container for the table's column headers.\n * Encapsulates a set of `<Table.Row>`s, indicating that they comprise the head\n * of a table with information about the table's columns. This is usually in the\n * form of column headers (`<Table.Header>`).\n *\n * Must be used as a child of a `<Table.Element>`. It should only come after any\n * `<Table.Caption>` or `<colgroup>` and before any `<Table.Body>` or `<Table.Foot>`.\n *\n * Permitted Content:\n * 1. 0 or more: `<Table.Row>`\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#tableheader\n */\nconst Head = forwardRef<ComponentRef<\"thead\">, ComponentProps<\"thead\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<thead\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t//,\n\t\t\t\t\"border-b border-card-muted\",\n\t\t\t\t\"divide-y divide-card-muted\",\n\t\t\t\t\"text-muted bg-base\",\n\t\t\t\t\"[&>tr]:bg-base\", // Row styling\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</thead>\n\t),\n);\nHead.displayName = \"TableHead\";\n\n/**\n * The `<Table.Body>` encapsulates a set of `<Table.Row>`s, indicating that they\n * comprise the body of a table's (main) data.\n *\n * Must be used as a child of a `<Table.Element>` and only come after any\n * `<Table.Caption>`, `<colgroup>`, or `<Table.Head>`.\n *\n * Permitted Content:\n * 1. 0 or more: `<Table.Row>`\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#tablebody\n */\nconst Body = forwardRef<ComponentRef<\"tbody\">, ComponentProps<\"tbody\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<tbody\n\t\t\tclassName={cx(\n\t\t\t\t//,\n\t\t\t\t\"divide-y divide-card-muted\",\n\t\t\t\t\"text-body\",\n\t\t\t\t\"[thead+&]:border-t [thead+&]:border-card-muted\",\n\t\t\t\t\"[&>tr]:bg-card [&>tr]:not-only:hover:bg-card-hover\", // Body row styling\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</tbody>\n\t),\n);\nBody.displayName = \"TableBody\";\n\n/**\n * The `<Table.Foot>` encapsulates a set of `<Table.Row>`s, indicating that they\n * comprise the foot of a table with information about the table's columns. This\n * is usually a summary of the columns, e.g., a sum of the given numbers in a\n * column.\n *\n * Must be used as a child of a `<Table.Element>` and only come after any\n * `<Table.Caption>`, `<colgroup>`, `<Table.Head>`, and `<Table.Body>`.\n *\n * Permitted Content:\n * 1. 0 or more: `<Table.Row>` elements\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#tablefoot\n */\nconst Foot = forwardRef<ComponentRef<\"tfoot\">, ComponentProps<\"tfoot\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<tfoot\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t//,\n\t\t\t\t\"font-medium text-body\",\n\t\t\t\t\"border-t border-card-muted\",\n\t\t\t\t\"divide-y divide-card-muted\",\n\t\t\t\t\"[&>tr]:bg-gray-50/50 [&>tr]:hover:bg-card-hover\", // Row styling\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</tfoot>\n\t),\n);\nFoot.displayName = \"TableFoot\";\n\n/**\n * The `<Table.Row>` defines a row of cells in a table. The row's cells can then\n * be established using a mix of `<Table.Cell>` and `<Table.Header>` components.\n *\n * Must be used as a child of a `<Table.Head>`, `<Table.Body>`, or `<Table.Foot>`.\n *\n * Permitted Content:\n * 1. 0 or more: `<Table.Header>` or `<Table.Cell>`\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#tablerow\n */\nconst Row = forwardRef<ComponentRef<\"tr\">, ComponentProps<\"tr\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<tr\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t// This could be removed, or simplified\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</tr>\n\t),\n);\nRow.displayName = \"TableRow\";\n\n/**\n * The `<Table.Header>` defines a cell as the header of a group of table cells\n * and may be used as a child of a `<Table.Row>`. The exact nature of this group\n * is defined by the scope and headers attributes.\n *\n * Must be used as a child of a `<Table.Row>`.\n *\n * Permitted Content:\n * 1. Flow content, but with no header, footer, sectioning content, or heading\n * content descendants.\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#tableheader\n */\nconst Header = forwardRef<ComponentRef<\"th\">, ComponentProps<\"th\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<th\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t\"h-11 px-4 text-left align-middle text-sm font-medium [&:has([role=checkbox])]:pr-0\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</th>\n\t),\n);\nHeader.displayName = \"TableHeader\";\n\n/**\n * The `<Table.Cell>` defines a cell of a table that contains data and may be\n * used as a child of a `<Table.Row>`.\n *\n * Must be used as a child of a `<Table.Row>`.\n *\n * Permitted Content:\n * 1. Flow content\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#tablecell\n */\nconst Cell = forwardRef<ComponentRef<\"td\">, ComponentProps<\"td\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<td\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t\"p-3 align-middle [&:has([role=checkbox])]:pr-0 font-mono text-mono\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</td>\n\t),\n);\nCell.displayName = \"TableCell\";\n\n/**\n * The optional `<Table.Caption>` specifies the caption (or title) of a table,\n * providing the table an accessible description.\n *\n * If used, must be the first child of a `<Table.Element>`.\n *\n * Permitted Content:\n * 1. Flow content\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#tablecaption\n */\nconst Caption = forwardRef<ComponentRef<\"caption\">, ComponentProps<\"caption\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<caption\n\t\t\tref={ref}\n\t\t\tclassName={cx(\"py-4 text-sm text-gray-500\", \"border-t border-card-muted\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</caption>\n\t),\n);\nCaption.displayName = \"TableCaption\";\n\n/**\n * A structured way to display data in rows and columns. The API matches the\n * HTML table element 1:1.\n *\n * @see https://mantle.ngrok.com/components/table\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-25\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n */\nconst Table = {\n\t/**\n\t * The body section of the table. Encapsulates a set of table rows comprising the body of a table's main data.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#tablebody\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-25\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tBody,\n\t/**\n\t * An optional caption that specifies the caption (or title) of a table, providing an accessible description.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#tablecaption\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-25\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tCaption,\n\t/**\n\t * A cell that contains data and may be used as a child of a table row.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#tablecell\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-25\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tCell,\n\t/**\n\t * A structured way to display data in rows and columns. The API matches the HTML table element 1:1.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#tableelement\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-25\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tElement,\n\t/**\n\t * The foot section of a table. Encapsulates a set of table rows comprising the foot with summary information.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#tablefoot\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-25\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tFoot,\n\t/**\n\t * The head section of a table. Contains the table's column headers information.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#tableheader\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-25\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tHead,\n\t/**\n\t * A cell that defines the header of a group of table cells as a child of a table row.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#tableheader\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-25\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tHeader,\n\t/**\n\t * The root container element for all tables. Provides styling and additional functionality like horizontal overflow detection.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#tableroot\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-25\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * Defines a row of cells in a table. Contains a mix of table cells and table headers.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#tablerow\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-25\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tRow,\n} as const;\n\nexport {\n\t//,\n\tTable,\n};\n\n/**\n * A custom hook that observes the horizontal overflow of an element and determines\n * if it has overflow and if it is scrolled to the end.\n *\n * @private\n */\nfunction useHorizontalOverflowObserver<T extends HTMLElement>() {\n\tconst ref = useRef<T | null>(null);\n\tconst [state, setState] = useState({\n\t\thasOverflow: false,\n\t\tscrolledToStart: true,\n\t\tscrolledToEnd: false,\n\t});\n\n\tuseLayoutEffect(() => {\n\t\tconst element = ref.current;\n\t\tif (!element) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet frameId = 0;\n\n\t\tconst checkState = () => {\n\t\t\tconst hasOverflow = element.scrollWidth > element.clientWidth;\n\t\t\tconst scrolledToStart = element.scrollLeft < 1;\n\t\t\tconst scrolledToEnd =\n\t\t\t\tMath.abs(element.scrollWidth - element.scrollLeft - element.clientWidth) < 1;\n\n\t\t\tsetState((previous) => {\n\t\t\t\tif (\n\t\t\t\t\tprevious.hasOverflow !== hasOverflow ||\n\t\t\t\t\tprevious.scrolledToStart !== scrolledToStart ||\n\t\t\t\t\tprevious.scrolledToEnd !== scrolledToEnd\n\t\t\t\t) {\n\t\t\t\t\treturn { hasOverflow, scrolledToStart, scrolledToEnd };\n\t\t\t\t}\n\t\t\t\treturn previous; // No state change\n\t\t\t});\n\t\t};\n\n\t\t// Coalesce rapid-fire events (scroll, mutation, resize) into a single\n\t\t// layout read per animation frame to avoid redundant work.\n\t\tconst scheduleCheck = () => {\n\t\t\tif (frameId === 0) {\n\t\t\t\tframeId = requestAnimationFrame(() => {\n\t\t\t\t\tframeId = 0;\n\t\t\t\t\tcheckState();\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tconst resizeObserver = new ResizeObserver(scheduleCheck);\n\t\tresizeObserver.observe(element);\n\n\t\tconst mutationObserver = new MutationObserver(scheduleCheck);\n\t\tmutationObserver.observe(element, { childList: true, subtree: true });\n\n\t\telement.addEventListener(\"scroll\", scheduleCheck, { passive: true });\n\n\t\tcheckState();\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(frameId);\n\t\t\tresizeObserver.disconnect();\n\t\t\tmutationObserver.disconnect();\n\t\t\telement.removeEventListener(\"scroll\", scheduleCheck);\n\t\t};\n\t}, []);\n\n\treturn useMemo(() => ({ ref, state }), [state]);\n}\n"],"mappings":"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"}
package/dist/table.js CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./table-CnYWz6IT.js";export{e as Table};
1
+ import{t as e}from"./table-DDeUXBex.js";export{e as Table};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngrok/mantle",
3
- "version": "0.68.2",
3
+ "version": "0.68.4",
4
4
  "description": "mantle is ngrok's UI library and design system.",
5
5
  "homepage": "https://mantle.ngrok.com",
6
6
  "license": "MIT",