@epilot/zenith-react 0.1.0-next.0 → 0.1.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +61 -16
  2. package/dist/components/appearance-boundary/appearance-boundary.js.map +1 -1
  3. package/dist/components/badge/badge.js.map +1 -1
  4. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  5. package/dist/components/button-group/button-group.js.map +1 -1
  6. package/dist/components/callout/callout.js.map +1 -1
  7. package/dist/components/card/card.js.map +1 -1
  8. package/dist/components/code-editor/code-editor.js.map +1 -1
  9. package/dist/components/code-editor/indent.js.map +1 -1
  10. package/dist/components/command/command.js +1 -7
  11. package/dist/components/command/command.js.map +1 -1
  12. package/dist/components/date-range-picker/date-range-picker.js +3 -8
  13. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  14. package/dist/components/date-time-picker/time-picker.js.map +1 -1
  15. package/dist/components/density-provider/density-provider.js.map +1 -1
  16. package/dist/components/field/field.js.map +1 -1
  17. package/dist/components/label/label.js +0 -28
  18. package/dist/components/label/label.js.map +1 -1
  19. package/dist/components/list/list.js +2 -12
  20. package/dist/components/list/list.js.map +1 -1
  21. package/dist/components/pill/pill.js.map +1 -1
  22. package/dist/components/separator/separator.js.map +1 -1
  23. package/dist/components/skeleton/skeleton.js.map +1 -1
  24. package/dist/components/slot/compose-as-child.js.map +1 -1
  25. package/dist/components/spinner/spinner.js.map +1 -1
  26. package/dist/components/switch/switch.js.map +1 -1
  27. package/dist/components/table/table.js.map +1 -1
  28. package/dist/components/text/text.js.map +1 -1
  29. package/dist/components/toast/toast.js +4 -6
  30. package/dist/components/toast/toast.js.map +1 -1
  31. package/dist/delivery/index.d.ts +10 -44
  32. package/dist/delivery/index.js +5 -9
  33. package/dist/index.d.ts +69 -410
  34. package/dist/lib/clear-button.js.map +1 -1
  35. package/dist/lib/code-highlight.js.map +1 -1
  36. package/dist/lib/code-tokens.js.map +1 -1
  37. package/dist/lib/pagination.js.map +1 -1
  38. package/dist/packages/tokens/dist/delivery/index.js +18 -48
  39. package/dist/packages/tokens/dist/delivery/index.js.map +1 -1
  40. package/dist/{token-assets/core/5cd4072decf5df2a664f0b1d5f2ec250a3309101ded3056c1f87c8bbe3738d50.css → packages/tokens/dist/generated/core.generated.js} +8 -3
  41. package/dist/packages/tokens/dist/generated/core.generated.js.map +1 -0
  42. package/dist/packages/tokens/dist/install.js +4 -4
  43. package/dist/packages/tokens/dist/install.js.map +1 -1
  44. package/dist/styles/document-context.js.map +1 -1
  45. package/dist/styles/make-styles.js.map +1 -1
  46. package/dist/tokens/core.meta.generated.js.map +1 -1
  47. package/dist/tokens/use-palette-tokens.js.map +1 -1
  48. package/dist/tokens.json +1 -1
  49. package/package.json +3 -4
  50. package/scripts/migration-diagnostics-core.mjs +19 -90
  51. package/scripts/migration-diagnostics.mjs +1 -16
  52. package/scripts/migration-sweep.mjs +2 -12
  53. package/ADOPTING.md +0 -73
  54. package/dist/packages/tokens/dist/delivery/internal.js +0 -181
  55. package/dist/packages/tokens/dist/delivery/internal.js.map +0 -1
  56. package/dist/packages/tokens/dist/generated/core.meta.generated.js +0 -10
  57. package/dist/packages/tokens/dist/generated/core.meta.generated.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -3771,32 +3771,16 @@ declare const shorthands: {
3771
3771
  };
3772
3772
 
3773
3773
  /**
3774
- * Fed to Griffel as `classNameHashSalt`. Griffel hashes class names from
3775
- * `salt + selector + atRules + property + value`, which makes the two cases exhaustive:
3776
- *
3777
- * same salt -> identical declarations produce identical class names AND identical rules.
3778
- * A "collision" is content identity, so dedup is safe.
3779
- * different salt -> disjoint class namespaces. Collision is impossible, and dedup between those
3780
- * copies is correctly forfeited.
3781
- *
3782
- * It is derived from the pinned `@griffel/core` version and NOTHING else — token isolation is the
3783
- * job of the value-derived property namespaces, not of this salt. Never typed by hand; see
3784
- * DECISIONS.md D4. There used to be a second name for this exact value (`CONTRACT_SALT`, aliasing
3785
- * the generated `CONTRACT_ID`), which is how two documents came to describe a formula the code had
3786
- * stopped using.
3774
+ * Fed to Griffel as `classNameHashSalt`. Griffel hashes class names from `salt + selector +
3775
+ * atRules + property + value`, which makes the two cases exhaustive: same salt -> identical
3776
+ * declarations produce identical class names AND identical rules. A "collision" is content
3777
+ * identity, so dedup is safe.
3787
3778
  */
3788
3779
 
3789
3780
  /**
3790
- * v2-only slot marker, and the reason it has to exist.
3791
- *
3792
- * `data-slot` values are shared with v1 by design, so ANY selector keyed on one also matches
3793
- * v1-rendered DOM — a v1 element nested inside a v2 component included, even though our own rule's
3794
- * root is hash-scoped. The StyleX track hit exactly this: a v1 icon computed to 0x0 and went
3795
- * through a green gate.
3796
- *
3797
- * So every internal descendant selector keys on THIS attribute, which only v2 emits. `data-slot`
3798
- * is still set, but purely as a diagnostic — under content-hashed class names it is the only
3799
- * human-readable identifier left on an element — and is never styled against.
3781
+ * v2-only slot marker, and the reason it has to exist. `data-slot` values are shared with v1 by
3782
+ * design, so ANY selector keyed on one also matches v1-rendered DOM — a v1 element nested inside a
3783
+ * v2 component included, even though our own rule's root is hash-scoped.
3800
3784
  */
3801
3785
  declare const SLOT_ATTR = "data-zenith-slot";
3802
3786
 
@@ -3810,13 +3794,10 @@ declare function assertAnchorIsFirstInHead(doc?: Document): {
3810
3794
  };
3811
3795
 
3812
3796
  /**
3813
- * One class per slot, atoms deduped against whatever is already on the page.
3814
- *
3815
- * **The generic is over the object, not over the key union, and that is load-bearing.** Inferring a
3816
- * type parameter from `Record<Slots, …>` against an object literal widens `Slots` to `string`, so
3817
- * every slot name typechecks including ones that do not exist. OptionCard read `styles.card` in two
3818
- * places with no `card` slot declared and rendered with no card styling at all; tsc was clean and
3819
- * 322 tests passed. Only a pixel diff caught it.
3797
+ * One class per slot, atoms deduped against whatever is already on the page. **The generic is over
3798
+ * the object, not over the key union, and that is load-bearing.** Inferring a type parameter from
3799
+ * `Record<Slots, …>` against an object literal widens `Slots` to `string`, so every slot name
3800
+ * typechecks including ones that do not exist.
3820
3801
  */
3821
3802
  declare function makeZenithStyles<S extends Record<string, GriffelStyle>>(styles: S): () => Record<keyof S & string, string>;
3822
3803
  /**
@@ -3830,26 +3811,6 @@ declare function makeZenithResetStyles(styles: GriffelResetStyle): () => string;
3830
3811
  /**
3831
3812
  * REFERENCE COMPONENT — the colour-matrix collapse. Read this before writing another component
3832
3813
  * that takes a `color` prop.
3833
- *
3834
- * v1 enumerates 20 colours x 3 styles as 60 `compoundVariants`, each a distinct class string like
3835
- * `volt-bg-mint-soft`. Because those names are built by interpolation, Tailwind's scanner cannot
3836
- * see them, which is what `safelist.css` exists to force — 9 lines that emit ~945 rules, 65.6 KB
3837
- * and 59% of v1's entire rule count. The Griffel PoC carried the same shape forward as 60 static
3838
- * style objects.
3839
- *
3840
- * Here the colour is a VALUE, not part of a class name. Three atoms read three custom properties;
3841
- * the component sets those properties inline from the `color` prop. Total rules: one small set per
3842
- * style variant, regardless of how many colours exist. Adding a 22nd palette family costs zero
3843
- * rules.
3844
- *
3845
- * Two consequences worth knowing:
3846
- * - `color` may legitimately arrive from a runtime expression (`getColorForEntityLabel(label)` and
3847
- * `WCAG_BADGE_MAP[level].color` both exist in consumer code today), which no build step can
3848
- * resolve. That is exactly why the palette sheet cannot be statically shaken, and why this
3849
- * component calls `ensurePaletteTokens()`.
3850
- * - Selectors key on SLOT_ATTR, never on `data-slot`. `data-slot` values are shared with v1, so a
3851
- * rule keyed on one also matches v1-rendered DOM — the StyleX track had a v1 icon compute to
3852
- * 0x0 through a green gate this way. `data-slot` is still emitted, purely as a diagnostic.
3853
3814
  */
3854
3815
  declare const COLORS$1: readonly ["accent", "neutral", "gray", "success", "warning", "error", "info", "blue", "sky", "mint", "lime", "green", "teal", "cyan", "indigo", "purple", "pink", "red", "orange", "yellow", "bronze"];
3855
3816
  type BadgeColor = (typeof COLORS$1)[number];
@@ -3867,27 +3828,7 @@ type BadgeProps = Omit<React.ComponentProps<"span">, "color"> & {
3867
3828
  };
3868
3829
  declare const Badge: React.ForwardRefExoticComponent<Omit<BadgeProps, "ref"> & React.RefAttributes<HTMLSpanElement>>;
3869
3830
 
3870
- /**
3871
- * Breadcrumb — Card's compound pattern applied to the nav / ol / li structure.
3872
- *
3873
- * v1's `Breadcrumb` walks its children and interleaves a presentational separator `<li>` between
3874
- * them; `BreadcrumbItem` decides between a link and a plain page by whether a `href` exists. The
3875
- * `nav` / `ol` / `li` semantics and the `aria-current="page"` handling are the real value of this
3876
- * component and are reproduced exactly.
3877
- *
3878
- * v1 renders the link branch through Radix `Slot` when `asChild` is set — dropped here per
3879
- * CONVENTIONS rule 6 (no Radix dependency). There is no `asChild` escape hatch; a consumer wanting
3880
- * a non-`<a>` link anchors it themselves.
3881
- *
3882
- * `BreadcrumbItem` with a `href` renders an `<a>` (slot `breadcrumb-link`); without one, a `<span>`
3883
- * (slot `breadcrumb-page`). Either way the item is wrapped in a `breadcrumb-item` `<li>`. The nav
3884
- * itself has no base styles in v1 — it is left to the caller's className — so it carries only the
3885
- * slot attributes.
3886
- *
3887
- * The link's `transition-colors` expands to Tailwind v4's default property list plus the 150ms
3888
- * `cubic-bezier(0.4, 0, 0.2, 1)` easing — literals from the framework's default theme, which is
3889
- * visible motion and cannot be read from the v1 file (Rule 0: flagged, not approximated away).
3890
- */
3831
+ /** Breadcrumb — Card's compound pattern applied to the nav / ol / li structure. */
3891
3832
  type BreadcrumbProps = React.ComponentProps<"nav"> & {
3892
3833
  separator?: React.ReactNode;
3893
3834
  };
@@ -3965,17 +3906,7 @@ declare const Surface: React.ForwardRefExoticComponent<(Omit<Omit<React.Detailed
3965
3906
  children: React.ReactElement;
3966
3907
  }, "ref">) & React.RefAttributes<HTMLDivElement>>;
3967
3908
 
3968
- /**
3969
- * Pill — same colour-matrix collapse as Badge, plus a hover background.
3970
- *
3971
- * v1 enumerates 19 colours x 3 styles as 57 `compoundVariants`, each a distinct class string
3972
- * built by interpolation (`volt-bg-${color}-soft`), which Tailwind's scanner cannot see and
3973
- * `safelist.css` exists to force into existence. The hover state made that 57 more per-colour
3974
- * rules. Here the colour is a VALUE, not part of a class name: the four atoms below read four
3975
- * custom properties, the component sets those inline from the `color` prop, and a single `:hover`
3976
- * atom reads the hover background. Total rules: one small set per style variant — 9 colours' worth
3977
- * of rules cover all 19 x 3 combinations.
3978
- */
3909
+ /** Pill — same colour-matrix collapse as Badge, plus a hover background. */
3979
3910
  declare const COLORS: readonly ["blue", "sky", "mint", "lime", "green", "teal", "cyan", "indigo", "purple", "pink", "red", "orange", "yellow", "bronze", "gray", "accent", "warning", "success", "error"];
3980
3911
  type PillColor = (typeof COLORS)[number];
3981
3912
  type PillVariant = "soft" | "solid" | "surface";
@@ -3992,22 +3923,8 @@ type PillProps = Omit<React.ComponentProps<"span">, "color"> & {
3992
3923
  declare const Pill: React.ForwardRefExoticComponent<Omit<PillProps, "ref"> & React.RefAttributes<HTMLSpanElement>>;
3993
3924
 
3994
3925
  /**
3995
- * Separator — v1's `@radix-ui/react-separator` ported to Griffel atoms with no Radix dependency.
3996
- *
3997
- * A separator needs no behaviour beyond correct semantics, so it is a plain `<div>`. The two
3998
- * orientation variants are separate style slots selected in JS from the `orientation` prop — we
3999
- * deliberately do NOT style off a `data-[orientation=...]` attribute, like v1 does. v1 keyed its
4000
- * sizing on `data-[orientation=horizontal]`; doing that here would either key on `data-slot`-style
4001
- * selectors (whose values are shared with v1, so the rule also matches v1-rendered DOM) or on the
4002
- * custom-property slot marker. Two slots in the style object is simpler and cheaper. We still emit
4003
- * `data-orientation` as a plain attribute — for diagnostics and for consumers — we just never style
4004
- * off it.
4005
- *
4006
- * The accessibility surface is the whole point of the component, so it gets the full treatment:
4007
- * - `decorative` (default `true`): the divider is purely presentational, so it is hidden from
4008
- * assistive technology with `aria-hidden="true"` and carries no `role`.
4009
- * - `decorative={false}`: a meaningful separator, so it gets `role="separator"` and
4010
- * `aria-orientation` matching the `orientation` prop.
3926
+ * Separator — v1's `@radix-ui/react-separator` ported to Griffel atoms with no Radix dependency. A
3927
+ * separator needs no behaviour beyond correct semantics, so it is a plain `<div>`.
4011
3928
  */
4012
3929
  type SeparatorOrientation = "horizontal" | "vertical";
4013
3930
  type SeparatorProps = React.ComponentProps<"div"> & {
@@ -4022,58 +3939,22 @@ type SeparatorProps = React.ComponentProps<"div"> & {
4022
3939
  declare const Separator$3: React.ForwardRefExoticComponent<Omit<SeparatorProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
4023
3940
 
4024
3941
  /**
4025
- * Skeleton — v1's loading placeholder ported to Griffel atoms.
4026
- *
4027
- * Two variants, `default` and `ai`. `default` is a gray block that pulses; `ai` is a gray field
4028
- * that renders three decorative colour spots drifting behind the content. The spots are ported from
4029
- * v1's global `skeleton-ai-spot-*` classes in `styles/utilities.css`, including their exact
4030
- * gradients, durations (10s / 12s / 14s) and easing.
4031
- *
4032
- * The keyframes are the object form, so Griffel hashes each one from its content — a hand-authored
4033
- * global `@keyframes` would collide across two co-resident copies of this package. The pulse is a
4034
- * single three-stop animation; each spot carries its own.
4035
- *
4036
- * The spots are `purple-a4`, `pink-a4` and `indigo-a4`, none of which is a core token family
4037
- * (accent / gray / error / warning / success / info ship in the core sheet; everything else lives
4038
- * in the palette sheet, which is not loaded by default). `ai` therefore calls
4039
- * `ensurePaletteTokens()` — CONVENTIONS rule 3. There is no `color` prop, so no inline custom
4040
- * properties: the spot colours are constant and live inside the style objects.
3942
+ * Skeleton — v1's loading placeholder ported to Griffel atoms. Two variants, `default` and `ai`.
4041
3943
  */
4042
3944
  type SkeletonVariant = "default" | "ai";
4043
3945
  type SkeletonProps = React.ComponentProps<"div"> & {
4044
3946
  /**
4045
- * `default` is the ordinary loading pulse.
4046
- *
4047
- * `ai` is the placeholder for content being generated, drawn with three
4048
- * drifting colour spots. It is not merely decorative: its spot colours
4049
- * (purple, pink, indigo) are palette families rather than core ones, so `ai`
4050
- * calls `ensurePaletteTokens()` and its colours arrive on a later frame than
4051
- * the rest of the surface.
4052
- *
4053
- * @default "default"
3947
+ * `default` is the ordinary loading pulse. `ai` is the placeholder for content being generated,
3948
+ * drawn with three drifting colour spots.
4054
3949
  */
4055
3950
  variant?: SkeletonVariant;
4056
3951
  };
4057
3952
  declare const Skeleton: React.ForwardRefExoticComponent<Omit<SkeletonProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
4058
3953
 
4059
3954
  /**
4060
- * Spinner — v1's SVG spinner ported to a size-driven style object.
4061
- *
4062
- * v1 sizes this with Tailwind `size-*` utilities and deprecated the `size` prop in favour of a
4063
- * `className` like `size-4`. There is no Tailwind here, so that escape hatch does not exist: `size`
3955
+ * Spinner — v1's SVG spinner ported to a size-driven style object. v1 sizes this with Tailwind
3956
+ * `size-*` utilities and deprecated the `size` prop in favour of a `className` like `size-4`.
4064
3957
  * is the supported API and the `@deprecated` tag is dropped (CONVENTIONS rule 9).
4065
- *
4066
- * The SVG markup, `viewBox` and stroke attributes are copied exactly from v1. Both animations are
4067
- * the object form per CONVENTIONS rule 8: the outer `<g>` spins from a single `100%` stop, and the
4068
- * dash sweep carries all three of v1's keyframe stops (`0%`, `47.5%`, `95%,100%`) from
4069
- * `styles/animations.css`. The only mechanical changes are stylistic: sizes become width/height
4070
- * atoms and the two `animate-*` classes become `animationName` + duration + timing + iteration.
4071
- *
4072
- * The five dimensions (1rem / 1.5rem / 2.5rem / 4rem / 6rem) are v1's Tailwind `size-N` values;
4073
- * the v2 token set has no size or width/height family, so they are literals (CONVENTIONS rule 1).
4074
- *
4075
- * v1 also exposes a `variant` prop (`circle` | `line`) whose branches are both empty strings — it
4076
- * produces no styles at all, so it is omitted here.
4077
3958
  */
4078
3959
  type SpinnerSize = "sm" | "base" | "lg" | "xl" | "2xl";
4079
3960
  type SpinnerProps = React.ComponentProps<"svg"> & {
@@ -4085,60 +3966,11 @@ declare const Spinner: React.ForwardRefExoticComponent<Omit<SpinnerProps, "ref">
4085
3966
  * Table — the primitive set (Table, TableHeader, TableBody, TableFooter, TableRow, TableHead,
4086
3967
  * TableCell, TableCaption) in Card's compound pattern: one `makeZenithStyles` call, one slot per
4087
3968
  * sub-component, each reading its own slot.
4088
- *
4089
- * Density (approved 2026-09-09, replacing the earlier context-only mechanism — and with it the
4090
- * open question of whether Table and List could agree on one, now resolved; corrected in review
4091
- * the same day, see the two notes below):
4092
- * `TableHead`/`TableCell` read `tokens.tableHeadHeight`/`tokens.tableCellPaddingY` directly —
4093
- * generated CSS custom properties that cascade from the nearest `[data-density]` ancestor, exactly
4094
- * like Button/Field/Select. `Table`'s own `density` prop, when explicit, stamps `data-density` on
4095
- * the `<table>` element itself; when omitted, no attribute is stamped and ambient shell density
4096
- * (or an outer `DensityProvider`) inherits through ordinary DOM/CSS with no React involvement — a
4097
- * shell attribute mutation restyles an already-mounted table without a rerender. Per-cell
4098
- * `TableHead`/`TableCell` `density` props stamp their own `data-density` the same way, overriding
4099
- * locally. `TableDensityContext` (below) is a deprecated, now-inert compatibility export — see its
4100
- * own doc comment.
4101
- *
4102
- * Two corrections from that review, both applied identically to `Table`, `DataTable`
4103
- * (`data-table.tsx`), `TableHead` and `TableCell`:
4104
- *
4105
- * 1. An explicit `density` establishes a `DensityContextBoundary`, not just a DOM stamp. A DOM
4106
- * attribute alone reaches ordinary CSS-inheriting descendants, but a Radix `Portal` (a real
4107
- * `Select`/`Popover`/etc. rendered inside a cell) is a DOM sibling, not descendant, of that cell
4108
- * — its own `useDensity()` read needs the REACT context updated too, or it silently reports a
4109
- * stale ancestor value instead of the cell's own override.
4110
- * 2. The DOM stamp and the context value both run through the SAME `canonicalDensity` function
4111
- * (from `density-provider.tsx`, package-internal). Before this fix, `DensityContextBoundary`
4112
- * normalized invalid runtime input (e.g. a bad string bypassing TypeScript) for the context, but
4113
- * the DOM attribute was written raw/unnormalized — an invalid value could stamp `data-density`
4114
- * with something no generated CSS selector matches while `useDensity()` reported the normalized
4115
- * `"normal"`, disagreeing about what density is actually in effect.
4116
- *
4117
- * Selectors carry over untouched where they do not involve `data-slot`: `[&_tr]:border-b`,
4118
- * `[&_tr:last-child]:border-0`, `data-[state=selected]:bg-accent-a3` (Radix selection state) and
4119
- * the `role="checkbox"` column-reflow rules all obey the original attribute.
4120
- *
4121
- * Values explicit where no token exists: `px-3` (0.75rem) on head/cell. The row's
4122
- * `transition-colors` expands to Tailwind v4's default property list plus the 150ms
4123
- * `cubic-bezier(0.4, 0, 0.2, 1)` easing — visible motion from the framework's default theme,
4124
- * which the v1 file does not state (Rule 0: flagged, not approximated away). The checkbox
4125
- * `translate-y-[2px]` maps to the modern `translate` property, which is what Tailwind v4 emits.
4126
3969
  */
4127
3970
  type TableDensity = "compact" | "normal" | "comfortable";
4128
3971
  /**
3972
+ * 2026-09-09).
4129
3973
  * @deprecated No longer a supported way to control Table/DataTable geometry (approved
4130
- * 2026-09-09). `Table`/`DataTable` no longer provide a value into this
4131
- * context, and `TableHead`/`TableCell` no longer read it — density now flows entirely through CSS
4132
- * custom-property inheritance from the nearest `[data-density]` ancestor (ambient shell or
4133
- * `DensityProvider`), plus each component's own `density` prop stamping its own `data-density`
4134
- * when explicit. This context simply no longer controls or reports Table/DataTable geometry —
4135
- * `useContext(TableDensityContext)` still returns whatever a consumer's own raw
4136
- * `TableDensityContext.Provider` sets (or the bare `"normal"` default with no such Provider), it
4137
- * just has no bearing on what actually renders any more. Kept only so existing
4138
- * `import { TableDensityContext }` statements and `useContext(TableDensityContext)` call sites do
4139
- * not hard-error. Use the `density` prop on `Table`/`DataTable`/`TableHead`/`TableCell`, or wrap a
4140
- * subtree in `DensityProvider`, instead. This is a disclosed behavioural change; the context's own
4141
- * type and default value are unchanged.
4142
3974
  */
4143
3975
  declare const TableDensityContext: React.Context<TableDensity>;
4144
3976
  type TableProps = React.ComponentProps<"table"> & {
@@ -4320,23 +4152,8 @@ type ButtonProps = Omit<React.ComponentProps<"button">, "variant" | "size" | "sh
4320
4152
  declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
4321
4153
 
4322
4154
  /**
4323
- * ButtonGroup — compound component family for grouping buttons, text, and separators.
4324
- *
4325
- * One `makeZenithStyles` call for the whole family, one slot per sub-component (following `card.tsx`).
4326
- *
4327
- * No Base UI primitive is needed: v1 only used Radix `Slot` for `asChild` on `ButtonGroupText`,
4328
- * which CONVENTIONS rule 6 drops.
4329
- *
4330
- * `ButtonGroup` handles both `horizontal` and `vertical` orientations, removing adjoining border
4331
- * radius and borders on adjacent children. Sibling focus-visible elements are elevated (`z-index: 10`)
4332
- * and made relative so focus rings are never obscured by subsequent siblings.
4333
- *
4334
- * Nested button groups gain a gap via a `:has()` selector keyed on `SLOT_ATTR` (never on `data-slot`,
4335
- * per CONVENTIONS rule 4).
4336
- *
4337
- * `ButtonGroupText` provides a matching text container (`gray-a4`, subtle border, `shadow-xs`).
4338
- *
4339
- * `ButtonGroupSeparator` composes `Separator` with transparent background and stretch alignment.
4155
+ * ButtonGroup — compound component family for grouping buttons, text, and separators. One
4156
+ * `makeZenithStyles` call for the whole family, one slot per sub-component (following `card.tsx`).
4340
4157
  */
4341
4158
  type ButtonGroupOrientation = "horizontal" | "vertical";
4342
4159
  type ButtonGroupProps = React.ComponentProps<"div"> & {
@@ -4361,19 +4178,7 @@ declare const Checkbox$1: React.ForwardRefExoticComponent<CheckboxProps$1 & Reac
4361
4178
  type CheckboxProps = React.ComponentProps<typeof Checkbox$1>;
4362
4179
  declare const Checkbox: React.ForwardRefExoticComponent<Omit<CheckboxProps$1 & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
4363
4180
 
4364
- /**
4365
- * Label — a native `<label>` element styled with Griffel atoms.
4366
- *
4367
- * Base UI has no Label primitive; v1 wrapped `@radix-ui/react-label`, which only added an
4368
- * `onMouseDown` handler preventing text selection on double click while wrapping a `<label>`
4369
- * to wire `htmlFor`. A native `<label>` natively associates with form controls via `htmlFor` or
4370
- * nesting, so we render a native `<label>` directly with no Base UI or Radix dependency.
4371
- *
4372
- * Variants: `primary` (`gray-a12`) and `destructive` (`error-a12`), both from the core token
4373
- * sheet so no palette install is required.
4374
- *
4375
- * Sizes: `sm` (`text-xs`), `base` (`text-sm`), and `lg` (`text-base`).
4376
- */
4181
+ /** Label — a native `<label>` element styled with Griffel atoms. */
4377
4182
  type LabelVariant = "primary" | "destructive";
4378
4183
  type LabelSize = "sm" | "base" | "lg";
4379
4184
  type LabelProps = React.ComponentProps<"label"> & {
@@ -4471,13 +4276,9 @@ type SwitchVariant = "default" | "destructive" | "primary";
4471
4276
  type SwitchSize = "sm" | "base" | "lg";
4472
4277
  type SwitchProps = React.ComponentProps<typeof Root$b> & {
4473
4278
  /**
4474
- * `default` or `destructive`.
4475
- *
4476
- * `primary` is a **deprecated alias of `default`** with byte-identical styles,
4477
- * kept because v1 had it and consumers still pass it. Choosing it changes
4279
+ * `default` or `destructive`. `primary` is a **deprecated alias of `default`** with byte-
4280
+ * identical styles, kept because v1 had it and consumers still pass it. Choosing it changes
4478
4281
  * nothing; use `default`.
4479
- *
4480
- * @default "default"
4481
4282
  */
4482
4283
  variant?: SwitchVariant;
4483
4284
  /** @default "base" */
@@ -4903,38 +4704,6 @@ declare const AlertDialogCancel: React.ForwardRefExoticComponent<Omit<AlertDialo
4903
4704
  /**
4904
4705
  * A region that carries its own appearance — `packages/tokens/SPEC.md` §2 rule 3's document
4905
4706
  * boundary, as a component instead of two hand-written DOM attributes.
4906
- *
4907
- * **What it is for.** Mode is the page's: the shell stamps `data-theme` on `<html>` and every token
4908
- * resolves from there through ordinary CSS inheritance. The one exception is a region that renders
4909
- * content the page does not own — a variable, email or journey preview, a code editor — which brings
4910
- * its own theme regardless of the shell's. The generated sheet already supports that: it emits every
4911
- * treatment's light values under `.light[data-surface="<t>"], [data-theme="light"][data-surface="<t>"]`
4912
- * after the dark blocks, and the dark compounds `[data-theme="dark"][data-surface="<t>"]` alongside
4913
- * them, so an element carrying BOTH attributes wins over an ancestor's mode on specificity and
4914
- * source order. This component is the supported way to stamp that pair.
4915
- *
4916
- * **Why both props are required.** The two attributes are one boundary, not two independent
4917
- * switches. The role tokens (`surface.*`, `border.*`, `shadow.*`, `blur.*`) resolve through the
4918
- * compound `[data-theme=…][data-surface=…]` selector; stamping only `data-theme` would reset the
4919
- * mode while leaving the treatment to be inherited from whatever ancestor happens to declare one —
4920
- * so a boundary would silently render the page's treatment under the region's mode, which is a
4921
- * combination nobody designed. Requiring `surface` makes the caller say which treatment the region
4922
- * is, rather than having this component fabricate a plausible one.
4923
- *
4924
- * **Without a boundary nothing changes.** No component reads `document.documentElement`, and none
4925
- * of them consults this context for anything except re-stamping portalled content (below). A tree
4926
- * with no `AppearanceBoundary` behaves exactly as it does today: live shell attributes stay
4927
- * authoritative, including when the shell flips them after mount.
4928
- *
4929
- * **Density is a separate axis** and stays that way. `DensityProvider` is independent, its context
4930
- * is a different context, and this component neither reads nor writes `data-density`. A region can
4931
- * be inside both, in either nesting order.
4932
- *
4933
- * **Scope limit, stated plainly.** The React context below is per bundled copy of this package. Two
4934
- * independently bundled micro-frontends do not share it, so a boundary in one does not reach
4935
- * portalled content rendered by the other. The DOM attributes it stamps *are* shared — they are
4936
- * ordinary CSS — so the non-portal case works across copies; it is only the portal re-stamp that is
4937
- * copy-local. Each MFE wraps its own root.
4938
4707
  */
4939
4708
  type AppearanceMode = "light" | "dark";
4940
4709
  type AppearanceSurface = "plain" | "bordered" | "glass" | "tint" | "card";
@@ -4980,20 +4749,9 @@ declare const AppearanceBoundary: React.ForwardRefExoticComponent<(Omit<Omit<Rea
4980
4749
 
4981
4750
  /**
4982
4751
  * DENSITY-SPEC.md §4.4 — the two density mechanisms, and why this component is the only one that
4983
- * does both:
4984
- *
4985
- * - CSS custom-property inheritance (no JavaScript) already delivers the shell's AMBIENT default
4986
- * to every element, portalled or not — a Radix portal root is still an ordinary DOM descendant
4987
- * of `<html>`, so it inherits `<html data-density="...">` with zero wiring. No provider needed
4988
- * for that common case.
4989
- * - A bare `data-density` DOM attribute alone never reaches a portal that ISN'T a DOM descendant of
4990
- * it — setting a DOM attribute runs no React code, so `useDensity()` inside such a subtree (or a
4991
- * sibling-in-DOM, descendant-in-React-tree portal) sees nothing from it.
4992
- *
4993
- * `DensityProvider` sets both at once: a real DOM `data-density` boundary for ordinary (non-portal)
4994
- * CSS inheritance, and a React context value that portal-content components (`SelectContent`,
4995
- * `PopoverContent`, `DialogContent`, etc.) read via `useDensity()` to re-stamp themselves — since
4996
- * portalled content is a React-tree descendant but a DOM sibling, only the context path reaches it.
4752
+ * does both: - CSS custom-property inheritance (no JavaScript) already delivers the shell's
4753
+ * AMBIENT default to every element, portalled or not — a Radix portal root is still an ordinary
4754
+ * DOM descendant of `<html>`, so it inherits `<html data-density="...">` with zero wiring.
4997
4755
  */
4998
4756
  type Density = "compact" | "normal" | "comfortable";
4999
4757
  type DensityProviderProps = React.ComponentProps<"div"> & {
@@ -5637,23 +5395,18 @@ type ToastOffset = string | number | {
5637
5395
  left?: string | number;
5638
5396
  };
5639
5397
  /**
5640
- * @slot-foreign-dom sonner renders and owns this DOM. `Toaster` returns `<Sonner.Toaster>`, whose
5641
5398
  * root element and entire subtree are sonner's; we style it through sonner's own `toastOptions`
5642
5399
  * class hooks rather than by selecting it. There is no element of ours here to put `data-slot` or
5643
- * `SLOT_ATTR` on, and a marker set on sonner's root would name a node we do not control.
5644
- *
5400
+ * `SLOT_ATTR` on, and a marker set on sonner's root would name a node we do not control. knowingly
5401
+ * skipped.
5402
+ * @slot-foreign-dom sonner renders and owns this DOM. `Toaster` returns `<Sonner.Toaster>`, whose
5645
5403
  * This is ownership, not debt — distinct from `@slot-exempt`, which means our element, rule
5646
- * knowingly skipped. See the public-surface audit for the related finding that `toast` itself is
5647
- * re-exported verbatim out of sonner.
5648
5404
  */
5649
5405
  declare const Toaster: React.ForwardRefExoticComponent<ToasterProps & React.RefAttributes<HTMLElement>>;
5650
5406
  /**
5651
- * Zenith's own per-toast options. Previously `Parameters<typeof Sonner.toast>[1]`,
5652
- * which made every option sonner declared part of this package's public API.
5653
- *
5654
- * `onDismiss`/`onAutoClose` receive sonner's internal toast record. It is typed
5655
- * as `unknown` on purpose: re-exporting that record would reintroduce exactly
5656
- * the coupling this type exists to remove.
5407
+ * Zenith's own per-toast options. Previously `Parameters<typeof Sonner.toast>[1]`, which made
5408
+ * every option sonner declared part of this package's public API. `onDismiss`/`onAutoClose`
5409
+ * receive sonner's internal toast record.
5657
5410
  */
5658
5411
  type ToastOptions = {
5659
5412
  id?: string | number;
@@ -5680,17 +5433,9 @@ type ToastOptions = {
5680
5433
  };
5681
5434
  declare function toastFn(message: React.ReactNode, options?: ToastOptions): string | number;
5682
5435
  /**
5683
- * Zenith's toast entry point. Delegates to sonner, but the callable surface is
5684
- * this package's own: a sonner release can no longer add, remove or reshape a
5685
- * method here without a change in this repository.
5686
- *
5687
- * `promise` is the one member passed through rather than re-wrapped. Its generic
5688
- * over the settled value is what callers depend on, and re-declaring it by hand
5689
- * is where a narrowing bug would be introduced. That is a named exception, not
5690
- * the previous situation where the entire object was sonner's.
5691
- *
5692
- * `custom` and `message` are intentionally absent -- neither is used anywhere in
5693
- * this repository or its documentation.
5436
+ * Zenith's toast entry point. Delegates to sonner, but the callable surface is this package's own:
5437
+ * a sonner release can no longer add, remove or reshape a method here without a change in this
5438
+ * repository. `promise` is the one member passed through rather than re-wrapped.
5694
5439
  */
5695
5440
  declare const toast: typeof toastFn & {
5696
5441
  success: (message: React.ReactNode, options?: ToastOptions) => string | number;
@@ -5700,12 +5445,10 @@ declare const toast: typeof toastFn & {
5700
5445
  loading: (message: React.ReactNode, options?: ToastOptions) => string | number;
5701
5446
  dismiss: (id?: string | number) => string | number;
5702
5447
  /**
5703
- * Declared here rather than passed through: sonner's own signature references
5704
- * types its bundle does not name publicly, which makes the emitted `.d.ts`
5705
- * unbuildable (TS4023). The return is `unknown` on purpose -- sonner returns an
5706
- * internally-typed handle, and every use in this repository and its docs
5707
- * ignores it. A caller who needs that handle must cast, which is a narrowing
5708
- * we accept in exchange for owning the type.
5448
+ * Declared here rather than passed through: sonner's own signature references types its bundle
5449
+ * does not name publicly, which makes the emitted `.d.ts` unbuildable (TS4023). The return is
5450
+ * `unknown` on purpose -- sonner returns an internally-typed handle, and every use in this
5451
+ * repository and its docs ignores it.
5709
5452
  */
5710
5453
  promise: <T>(promise: Promise<T> | (() => Promise<T>), data?: {
5711
5454
  loading?: React.ReactNode;
@@ -6194,11 +5937,7 @@ declare const FieldComboboxClearValue: React.ForwardRefExoticComponent<Omit<Reac
6194
5937
 
6195
5938
  /**
6196
5939
  * `relaxed` is a permanent compatibility alias for `normal` (DENSITY-SPEC.md §4.2,
6197
- * WP9B2A-ACCEPTANCE-LIST) — identical geometry, forever, not deprecated. `compact`/`normal`/
6198
- * `comfortable` are the three canonical CSS density tiers (`[data-density]`); `relaxed` never
6199
- * appears as a DOM attribute value — an explicit `density="relaxed"` normalizes to the DOM's
6200
- * canonical `data-density="normal"` (§ List, below), since the generator's three selector blocks
6201
- * only ever match those three literal strings.
5940
+ * WP9B2A-ACCEPTANCE-LIST) — identical geometry, forever, not deprecated.
6202
5941
  */
6203
5942
  type ListDensity = "compact" | "normal" | "comfortable" | "relaxed";
6204
5943
  type ListItemStatus = "default" | "error" | "warning" | "success";
@@ -6393,14 +6132,8 @@ type TimePickerProps = {
6393
6132
  minuteStep?: number;
6394
6133
  className?: string;
6395
6134
  /**
6396
- * Accessible name for the hours column. Pass a translated string.
6397
- *
6398
- * These are ACCESSIBLE NAMES, not visible headers, and the distinction is deliberate. v1 ≤1.3.x
6399
- * had `hoursLabel`/`minutesLabel` that rendered visible "HH"/"MM" headings; v1 deleted them in
6400
- * `138fe05` (2026-06-25) and this package mirrors v1's current output, which Rule 0 makes the
6401
- * fidelity target. But v1 replaced them with nothing, so both libraries now hand a screen reader
6402
- * two unnamed columns of bare numbers. Naming them via `aria-label` closes that without moving a
6403
- * pixel — the VR gate still matches v1 specimen for specimen.
6135
+ * Accessible name for the hours column. Pass a translated string. These are ACCESSIBLE NAMES,
6136
+ * not visible headers, and the distinction is deliberate.
6404
6137
  */
6405
6138
  hoursLabel?: string;
6406
6139
  /** Accessible name for the minutes column. Pass a translated string. See `hoursLabel`. */
@@ -6486,35 +6219,16 @@ type DateRangePickerProps = {
6486
6219
  declare const DateRangePicker: React.ForwardRefExoticComponent<DateRangePickerProps & React.RefAttributes<HTMLDivElement>>;
6487
6220
 
6488
6221
  /**
6489
- * Text — the v1 text scale ported to Griffel atoms.
6490
- *
6491
- * v1 expressed the ten variants as cva classes (`text-3xl tracking-tighter font-bold` etc.), one
6492
- * per variant. Here each variant is a small set of atoms that read design tokens instead of
6493
- * literal values; the variant itself is the whole style, so there is exactly one slot per variant
6494
- * and the caller's `className` is merged on top.
6495
- *
6496
- * Unlike Badge there is no `color` prop, so no palette install and no inline custom properties:
6497
- * the only colour used (the helper variants) is `gray-a11`, a core token that ships in the core
6498
- * sheet.
6499
- *
6500
- * Body and helper variants keep v1's `display: inline-block` — it lets inline text size to its
6501
- * content inside flex/grid parents instead of collapsing to zero width. Titles and headings
6502
- * inherit their display, exactly as v1.
6222
+ * Text — the v1 text scale ported to Griffel atoms. v1 expressed the ten variants as cva classes
6223
+ * (`text-3xl tracking-tighter font-bold` etc.), one per variant.
6503
6224
  */
6504
6225
  type TextVariant = "title3" | "title2" | "title1" | "heading3" | "heading2" | "heading1" | "body2" | "body1" | "helper2" | "helper1";
6505
6226
  type TextProps = React.ComponentProps<"span"> & {
6506
6227
  /**
6507
- * The role and size of the text, as one value.
6508
- *
6509
- * **The number runs opposite to HTML heading convention: 3 is the largest of
6510
- * its group and 1 the smallest.** `title3` is `text3xl` and `title1` is
6511
- * `textXl`; `heading3` is `textLg` and `heading1` is `textSm`. Reading
6512
- * `title1` as "the primary title" gives you the smallest one.
6513
- *
6514
- * The prefix carries the role rather than the size alone: `body1` and
6515
- * `helper1` are both `textXs` and differ in weight and colour.
6516
- *
6517
- * @default "body1"
6228
+ * The role and size of the text, as one value. **The number runs opposite to HTML heading
6229
+ * convention: 3 is the largest of its group and 1 the smallest.** `title3` is `text3xl` and
6230
+ * `title1` is `textXl`; `heading3` is `textLg` and `heading1` is `textSm`. Reading `title1` as
6231
+ * "the primary title" gives you the smallest one.
6518
6232
  */
6519
6233
  variant?: TextVariant;
6520
6234
  };
@@ -6602,38 +6316,22 @@ type CodeEditorProps = Omit<React.ComponentProps<"textarea">, "value" | "default
6602
6316
  /** Marks the control invalid: sets `aria-invalid` and the invalid styling. */
6603
6317
  invalid?: boolean;
6604
6318
  /**
6605
- * Render a line-number gutter, and mark the line the caret is on.
6606
- *
6607
- * Off by default: on the four-line snippets this component is for, numbers are a column of noise
6608
- * that also costs horizontal space. One property rather than two, because a gutter that does not
6609
- * say where you are and a band with nothing to count against are each half an affordance — this
6610
- * is `lineNumbers()`, `highlightActiveLine()` and `highlightActiveLineGutter()` as CodeMirror's
6611
- * own default setup bundles them.
6319
+ * Render a line-number gutter, and mark the line the caret is on. Off by default: on the four-
6320
+ * line snippets this component is for, numbers are a column of noise that also costs horizontal
6321
+ * space.
6612
6322
  */
6613
6323
  showLineNumbers?: boolean;
6614
6324
  /**
6615
- * Problems the CALLER found, one per line. Nothing here computes them.
6616
- *
6617
- * Rendered as a wavy rule under the line and a coloured gutter number, and enumerated in a
6618
- * visually hidden list that is added to the control's `aria-describedby` — so a screen reader
6619
- * gets the text on focus rather than a colour it cannot see. Deliberately NOT announced live:
6620
- * diagnostics normally change on every keystroke, and a live region that fires on every keystroke
6621
- * is noise. A caller who wants an announcement owns the timing, and owns the data already.
6325
+ * Problems the CALLER found, one per line. Nothing here computes them. Rendered as a wavy rule
6326
+ * under the line and a coloured gutter number, and enumerated in a visually hidden list that is
6327
+ * added to the control's `aria-describedby` — so a screen reader gets the text on focus rather
6328
+ * than a colour it cannot see.
6622
6329
  */
6623
6330
  diagnostics?: readonly CodeDiagnostic[];
6624
6331
  /**
6625
6332
  * Reformat the buffer. The caller supplies the formatter; this component supplies the keystroke,
6626
- * the caret, and the announcement.
6627
- *
6628
- * Bound to **Shift+Alt+F**, VS Code's "Format Document", and to a quiet button revealed on hover.
6629
- * May be synchronous or async. While one call is in flight another is dropped rather than queued,
6630
- * a result whose request has been superseded is discarded, and a result that arrives after the
6631
- * author has typed is discarded too and reported through `onFormatError` — applying it would
6632
- * silently delete what they typed. Never runs on a `readOnly` or `disabled` editor.
6633
- *
6634
- * The returned string is committed exactly like a keystroke, through `onValueChange`: a
6635
- * controlled editor that does not accept it does not change, which is the same contract typing
6636
- * already has.
6333
+ * the caret, and the announcement. Bound to **Shift+Alt+F**, VS Code's "Format Document", and to
6334
+ * a quiet button revealed on hover.
6637
6335
  */
6638
6336
  onFormat?: (value: string) => string | Promise<string>;
6639
6337
  /** Called when the formatter threw, rejected, or its result had to be discarded. */
@@ -6660,29 +6358,12 @@ declare const CodeEditor: React.ForwardRefExoticComponent<Omit<CodeEditorProps,
6660
6358
  /**
6661
6359
  * Tokenization for the code surfaces. Prism grammars via refractor, on a registry that starts
6662
6360
  * empty and carries exactly the ten shipped languages.
6663
- *
6664
- * WHY refractor AND WHY ONLY TEN — CODE-HIGHLIGHTING-DECISION.md has the comparison, the measured
6665
- * sizes and the rejected alternatives. The two facts that matter when editing this file:
6666
- *
6667
- * - refractor emits DATA (a hast tree), never HTML, so nothing here needs `innerHTML` and there is
6668
- * no raw-markup entry point to guard. `highlightCode` takes a string and returns plain objects.
6669
- * - `refractor/core` starts with no grammars, and each grammar is its own module. The ten below
6670
- * cost 20,683 B gzip together; the all-languages entry would cost 219,904 B. Adding one here
6671
- * is a measurable decision, which is why `registerCodeLanguage` exists instead — a consumer who
6672
- * needs Python imports that one grammar module and pays for Python.
6673
6361
  */
6674
6362
  /**
6675
- * A Prism grammar, as its own module default-exports it.
6676
- *
6677
- * Described STRUCTURALLY rather than as refractor's own `Syntax` type, and that is load-bearing:
6678
- * this type reaches the published declarations, and a consumer has not installed refractor, so an
6679
- * import of it there would resolve to nothing. TypeScript does not error on an unresolved import
6680
- * inside a `.d.ts` under `skipLibCheck` — it widens the type to `any` and says nothing, which is
6681
- * how a whole package's props once went untyped in two pilot MFEs. `gate:dts-self-contained` is
6682
- * what catches that, and it caught this.
6683
- *
6684
- * A grammar is a function carrying these two properties; the call signature is refractor's
6685
- * business, so only the properties are described here.
6363
+ * A Prism grammar, as its own module default-exports it. Described STRUCTURALLY rather than as
6364
+ * refractor's own `Syntax` type, and that is load-bearing: this type reaches the published
6365
+ * declarations, and a consumer has not installed refractor, so an import of it there would resolve
6366
+ * to nothing.
6686
6367
  */
6687
6368
  type CodeGrammar = {
6688
6369
  displayName: string;
@@ -6697,13 +6378,9 @@ type CodeGrammar = {
6697
6378
  declare const CODE_LANGUAGES: readonly ["bash", "css", "html", "javascript", "json", "jsx", "markdown", "tsx", "typescript", "yaml"];
6698
6379
  type CodeLanguage = (typeof CODE_LANGUAGES)[number];
6699
6380
  /**
6700
- * Teach the code surfaces one more Prism grammar.
6701
- *
6702
- * Import the grammar module for the language you need from refractor and pass its default export;
6703
- * the component docs carry a copyable example. You pay for that grammar and nothing else.
6704
- *
6705
- * Idempotent, synchronous, and safe to call during module initialization — it touches no DOM and
6706
- * reads no browser global, so it is equally valid on a server.
6381
+ * Teach the code surfaces one more Prism grammar. Import the grammar module for the language you
6382
+ * need from refractor and pass its default export; the component docs carry a copyable example.
6383
+ * You pay for that grammar and nothing else.
6707
6384
  */
6708
6385
  declare function registerCodeLanguage(syntax: CodeGrammar): void;
6709
6386
  /** True when `language` (name or alias) has a grammar and will actually be highlighted. */
@@ -9633,13 +9310,9 @@ type PaginationMeta = {
9633
9310
  */
9634
9311
  declare function calculatePagination(params: PaginationParams): PaginationMeta;
9635
9312
  /**
9636
- * Clamp a page number to valid bounds.
9637
- *
9313
+ * Clamp a page number to valid bounds. ```tsx clampPage(5, 3) // Returns 3 (clamped to max)
9314
+ * clampPage(0, 3) // Returns 1 (clamped to min) ```
9638
9315
  * @example
9639
- * ```tsx
9640
- * clampPage(5, 3) // Returns 3 (clamped to max)
9641
- * clampPage(0, 3) // Returns 1 (clamped to min)
9642
- * ```
9643
9316
  */
9644
9317
  declare function clampPage(page: number, totalPages: number): number;
9645
9318
  /** Represents a page number or an ellipsis marker in pagination */
@@ -9652,21 +9325,7 @@ type PageItem = {
9652
9325
  };
9653
9326
  /**
9654
9327
  * Generate page numbers with ellipsis for pagination UI.
9655
- *
9656
- * Pattern rules:
9657
- * - Fixed slot count: always shows TOTAL_SLOTS items (default: 7)
9658
- * - Right ellipsis when not near end: [pages..., ..., lastPage]
9659
- * - Near end: expanded window with no ellipsis
9660
- * - Ellipsis is clickable and jumps to midpoint
9661
- *
9662
9328
  * @example
9663
- * ```tsx
9664
- * getPageNumbers(1, 10) // [1, 2, 3, 4, 5, ellipsis→7, 10] (7 items)
9665
- * getPageNumbers(5, 10) // [3, 4, 5, 6, 7, ellipsis→8, 10] (7 items)
9666
- * getPageNumbers(7, 10) // [4, 5, 6, 7, 8, 9, 10] (7 items - expanded)
9667
- * getPageNumbers(10, 10) // [4, 5, 6, 7, 8, 9, 10] (7 items - expanded)
9668
- * getPageNumbers(2, 5) // [1, 2, 3, 4, 5] (5 items - small table)
9669
- * ```
9670
9329
  */
9671
9330
  declare function getPageNumbers(currentPage: number, totalPages: number, siblingCount?: number): PageItem[];
9672
9331