@box-kite/react 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/.claude/rules/box-kite-rules.md +43 -0
  2. package/.claude/skills/box-kite/SKILL.md +431 -0
  3. package/BOX_AI_CONTEXT.md +1833 -0
  4. package/BOX_KITE_AI_CONTEXT.md +1833 -0
  5. package/LICENSE +21 -0
  6. package/README.md +710 -7
  7. package/a11y.cjs +1 -0
  8. package/a11y.d.ts +15 -0
  9. package/a11y.mjs +3 -0
  10. package/behavior.cjs +1 -0
  11. package/behavior.mjs +295 -0
  12. package/box.cjs +1 -0
  13. package/box.d.ts +46 -0
  14. package/box.mjs +23 -0
  15. package/client.cjs +1 -0
  16. package/client.mjs +163 -0
  17. package/components/baseSvg.cjs +1 -0
  18. package/components/baseSvg.d.ts +5 -0
  19. package/components/baseSvg.mjs +21 -0
  20. package/components/button.cjs +1 -0
  21. package/components/button.d.ts +16 -0
  22. package/components/button.mjs +19 -0
  23. package/components/chart.cjs +1 -0
  24. package/components/chart.d.ts +82 -0
  25. package/components/chart.mjs +261 -0
  26. package/components/checkbox.cjs +1 -0
  27. package/components/checkbox.d.ts +28 -0
  28. package/components/checkbox.mjs +38 -0
  29. package/components/dataGrid/components/dataGridBody.d.ts +7 -0
  30. package/components/dataGrid/components/dataGridBottomBar.d.ts +6 -0
  31. package/components/dataGrid/components/dataGridCell.d.ts +15 -0
  32. package/components/dataGrid/components/dataGridCellRowDetail.d.ts +6 -0
  33. package/components/dataGrid/components/dataGridCellRowSelection.d.ts +6 -0
  34. package/components/dataGrid/components/dataGridCellText.d.ts +6 -0
  35. package/components/dataGrid/components/dataGridColumnFilter.d.ts +9 -0
  36. package/components/dataGrid/components/dataGridColumnGroups.d.ts +7 -0
  37. package/components/dataGrid/components/dataGridContent.d.ts +6 -0
  38. package/components/dataGrid/components/dataGridDetailRow.d.ts +8 -0
  39. package/components/dataGrid/components/dataGridEmptyColumns.d.ts +6 -0
  40. package/components/dataGrid/components/dataGridFilterCell.d.ts +11 -0
  41. package/components/dataGrid/components/dataGridFilterRow.d.ts +6 -0
  42. package/components/dataGrid/components/dataGridGlobalFilter.d.ts +6 -0
  43. package/components/dataGrid/components/dataGridGroupRow.d.ts +8 -0
  44. package/components/dataGrid/components/dataGridHeader.d.ts +6 -0
  45. package/components/dataGrid/components/dataGridHeaderCell.d.ts +9 -0
  46. package/components/dataGrid/components/dataGridHeaderCellContextMenu.d.ts +11 -0
  47. package/components/dataGrid/components/dataGridHeaderCellResizer.d.ts +14 -0
  48. package/components/dataGrid/components/dataGridLoader.d.ts +11 -0
  49. package/components/dataGrid/components/dataGridPagination.d.ts +6 -0
  50. package/components/dataGrid/components/dataGridRow.d.ts +8 -0
  51. package/components/dataGrid/components/dataGridTopBar.d.ts +6 -0
  52. package/components/dataGrid/components/dataGridTopBarContextMenu.d.ts +6 -0
  53. package/components/dataGrid/contracts/dataGridContract.d.ts +213 -0
  54. package/components/dataGrid/gridNavigationContext.d.ts +24 -0
  55. package/components/dataGrid/models/cellModel.d.ts +18 -0
  56. package/components/dataGrid/models/columnModel.d.ts +150 -0
  57. package/components/dataGrid/models/columnVisibilityModel.d.ts +24 -0
  58. package/components/dataGrid/models/detailRowModel.d.ts +22 -0
  59. package/components/dataGrid/models/filterModel.d.ts +22 -0
  60. package/components/dataGrid/models/gridModel.d.ts +206 -0
  61. package/components/dataGrid/models/groupRowCellModel.d.ts +26 -0
  62. package/components/dataGrid/models/groupRowModel.d.ts +48 -0
  63. package/components/dataGrid/models/headerCellModel.d.ts +83 -0
  64. package/components/dataGrid/models/paginationModel.d.ts +32 -0
  65. package/components/dataGrid/models/rowModel.d.ts +34 -0
  66. package/components/dataGrid/models/viewportModel.d.ts +44 -0
  67. package/components/dataGrid/useGrid.d.ts +8 -0
  68. package/components/dataGrid/useGridNavigation.d.ts +21 -0
  69. package/components/dataGrid.cjs +1 -0
  70. package/components/dataGrid.d.ts +2 -0
  71. package/components/dataGrid.mjs +3178 -0
  72. package/components/dropdown/dropdownContext.d.ts +44 -0
  73. package/components/dropdown/dropdownItems.d.ts +22 -0
  74. package/components/dropdown/dropdownRowRenderer.d.ts +8 -0
  75. package/components/dropdown/dropdownSearch.d.ts +21 -0
  76. package/components/dropdown/utils.d.ts +1 -0
  77. package/components/dropdown.cjs +1 -0
  78. package/components/dropdown.d.ts +47 -0
  79. package/components/dropdown.mjs +479 -0
  80. package/components/flex.cjs +1 -0
  81. package/components/flex.d.ts +6 -0
  82. package/components/flex.mjs +16 -0
  83. package/components/form.cjs +1 -0
  84. package/components/form.d.ts +10 -0
  85. package/components/form.mjs +58 -0
  86. package/components/grid.cjs +1 -0
  87. package/components/grid.d.ts +6 -0
  88. package/components/grid.mjs +16 -0
  89. package/components/icon.cjs +1 -0
  90. package/components/icon.d.ts +36 -0
  91. package/components/icon.mjs +41 -0
  92. package/components/overlay.cjs +1 -0
  93. package/components/overlay.d.ts +43 -0
  94. package/components/overlay.mjs +82 -0
  95. package/components/presence.cjs +1 -0
  96. package/components/presence.d.ts +30 -0
  97. package/components/presence.mjs +11 -0
  98. package/components/radioButton.cjs +1 -0
  99. package/components/radioButton.d.ts +24 -0
  100. package/components/radioButton.mjs +32 -0
  101. package/components/radioGroup.cjs +1 -0
  102. package/components/radioGroup.d.ts +38 -0
  103. package/components/radioGroup.mjs +79 -0
  104. package/components/select.cjs +1 -0
  105. package/components/select.d.ts +42 -0
  106. package/components/select.mjs +36 -0
  107. package/components/semantics.cjs +1 -0
  108. package/components/semantics.d.ts +34 -0
  109. package/components/semantics.mjs +17 -0
  110. package/components/svg.cjs +1 -0
  111. package/components/svg.d.ts +63 -0
  112. package/components/svg.mjs +141 -0
  113. package/components/switch.cjs +1 -0
  114. package/components/switch.d.ts +20 -0
  115. package/components/switch.mjs +25 -0
  116. package/components/textarea.cjs +1 -0
  117. package/components/textarea.d.ts +27 -0
  118. package/components/textarea.mjs +33 -0
  119. package/components/textbox.cjs +1 -0
  120. package/components/textbox.d.ts +26 -0
  121. package/components/textbox.mjs +33 -0
  122. package/components/tooltip.cjs +1 -0
  123. package/components/tooltip.d.ts +63 -0
  124. package/components/tooltip.mjs +108 -0
  125. package/components/visuallyHidden.cjs +1 -0
  126. package/components/visuallyHidden.d.ts +6 -0
  127. package/components/visuallyHidden.mjs +23 -0
  128. package/effects.cjs +1 -0
  129. package/effects.mjs +6 -0
  130. package/forms.cjs +1 -0
  131. package/forms.mjs +21 -0
  132. package/icons/dotsIcon.d.ts +2 -0
  133. package/icons/expandIcon.d.ts +2 -0
  134. package/icons/groupingIcon.d.ts +2 -0
  135. package/icons/pinIcon.d.ts +2 -0
  136. package/icons/searchIcon.d.ts +2 -0
  137. package/icons/sortIcon.d.ts +2 -0
  138. package/motion.cjs +1 -0
  139. package/motion.mjs +66 -0
  140. package/package.json +203 -7
  141. package/platform.cjs +1 -0
  142. package/platform.mjs +32 -0
  143. package/react/a11y/callbacks.d.ts +12 -0
  144. package/react/a11y/useControllableState.d.ts +25 -0
  145. package/react/a11y/useDismiss.d.ts +25 -0
  146. package/react/a11y/useFocusReturn.d.ts +18 -0
  147. package/react/a11y/useIdentifier.d.ts +17 -0
  148. package/react/a11y/useRovingFocus.d.ts +84 -0
  149. package/react/animation/usePresence.d.ts +32 -0
  150. package/react/boxClassNames.d.ts +25 -0
  151. package/react/boxProps.d.ts +49 -0
  152. package/react/boxTagProps.d.ts +7 -0
  153. package/react/clientRuntime.d.ts +11 -0
  154. package/react/effects.d.ts +10 -0
  155. package/react/forms/labelledControl.d.ts +17 -0
  156. package/react/forms/placeholderProp.d.ts +13 -0
  157. package/react/hooks/usePortalContainer.d.ts +1 -0
  158. package/react/hooks/useVirtualization.d.ts +43 -0
  159. package/react/hooks/useVisibility.d.ts +9 -0
  160. package/react/reactTypes.d.ts +10 -0
  161. package/react/resolveStyles.d.ts +18 -0
  162. package/react/styleElements.d.ts +3 -0
  163. package/react/svg/attributesInProps.d.ts +4 -0
  164. package/react/svg/svgNaming.d.ts +15 -0
  165. package/react/theme/theme.d.ts +26 -0
  166. package/react/theme/themeContext.d.ts +7 -0
  167. package/react/useStyles.d.ts +22 -0
  168. package/react-shared.cjs +1 -0
  169. package/react-shared.mjs +105 -0
  170. package/rolldown-runtime.cjs +1 -0
  171. package/rsc.cjs +1 -0
  172. package/rsc.d.ts +27 -0
  173. package/rsc.mjs +18 -0
  174. package/ssg.cjs +1 -0
  175. package/ssg.d.ts +24 -0
  176. package/ssg.mjs +25 -0
  177. package/utils/animation/animationUtils.d.ts +29 -0
  178. package/utils/array/arrayUtils.d.ts +15 -0
  179. package/utils/box/boxUtils.d.ts +5 -0
  180. package/utils/chart/chartUtils.d.ts +98 -0
  181. package/utils/dom/domUtils.d.ts +26 -0
  182. package/utils/environment/environmentUtils.d.ts +18 -0
  183. package/utils/fn/fnUtils.d.ts +4 -0
  184. package/utils/form/formUtils.d.ts +8 -0
  185. package/utils/memo.d.ts +10 -0
  186. package/utils/object/objectUtils.d.ts +13 -0
  187. package/utils/string/fuzzySearch.d.ts +27 -0
  188. package/utils/string/stringUtils.d.ts +4 -0
package/platform.cjs ADDED
@@ -0,0 +1 @@
1
+ function e(e){return e?`current`in e?e.current:e:null}function t(t){let n=e(t);return n instanceof HTMLElement?n:null}function n(t,n){let r=typeof t.composedPath==`function`?t.composedPath():[];return n.some(n=>{let i=e(n);return i?r.includes(i)||t.target instanceof Node&&i.contains(t.target):!1})}function r(t){let n=e(t),r=n?.ownerDocument?.defaultView;return!!n&&!!r&&r.getComputedStyle(n).direction===`rtl`}function i(){return typeof window<`u`&&window.document!==void 0}function a(){return typeof document<`u`}function o(){return a()?document:null}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return o}});
package/platform.mjs ADDED
@@ -0,0 +1,32 @@
1
+ //#region src/utils/dom/domUtils.ts
2
+ function e(e) {
3
+ return e ? "current" in e ? e.current : e : null;
4
+ }
5
+ function t(t) {
6
+ let n = e(t);
7
+ return n instanceof HTMLElement ? n : null;
8
+ }
9
+ function n(t, n) {
10
+ let r = typeof t.composedPath == "function" ? t.composedPath() : [];
11
+ return n.some((n) => {
12
+ let i = e(n);
13
+ return i ? r.includes(i) || t.target instanceof Node && i.contains(t.target) : !1;
14
+ });
15
+ }
16
+ function r(t) {
17
+ let n = e(t), r = n?.ownerDocument?.defaultView;
18
+ return !!n && !!r && r.getComputedStyle(n).direction === "rtl";
19
+ }
20
+ //#endregion
21
+ //#region src/utils/environment/environmentUtils.ts
22
+ function i() {
23
+ return typeof window < "u" && window.document !== void 0;
24
+ }
25
+ function a() {
26
+ return typeof document < "u";
27
+ }
28
+ function o() {
29
+ return a() ? document : null;
30
+ }
31
+ //#endregion
32
+ export { n as a, t as i, i as n, r as o, e as r, o as t };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Handler identity, which every hook here has the same problem with: a document listener must not
3
+ * be torn down and re-registered on every render, but it must still call the consumer's *current*
4
+ * handler — and consumers write handlers inline, so a new one arrives with every render.
5
+ */
6
+ /**
7
+ * The latest value, readable from an event handler that must not be re-registered when it changes. Written
8
+ * from an effect rather than during render, which costs nothing here: it is only read from an event.
9
+ */
10
+ export declare function useLatest<T>(value: T): React.RefObject<T>;
11
+ /** A callback with a stable identity that always calls the *latest* function it was given. */
12
+ export declare function useEventCallback<TArgs extends unknown[], TResult>(fn: ((...args: TArgs) => TResult) | undefined): (...args: TArgs) => TResult | undefined;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Why a change happened, and the event that caused it — the reason being the point. A component that only
3
+ * says `onOpenChange(false)` makes its consumer guess whether the popup closed because the user picked
4
+ * something, pressed Escape or clicked away, and each of those wants different behaviour from the app.
5
+ */
6
+ export interface ChangeDetails<TReason extends string = string> {
7
+ reason: TReason;
8
+ /** The DOM or React event behind the change, when there was one. */
9
+ event?: Event | React.SyntheticEvent;
10
+ }
11
+ export type ChangeHandler<T, TReason extends string = string> = (value: T, details: ChangeDetails<TReason>) => void;
12
+ export interface ControllableStateOptions<T, TReason extends string = string> {
13
+ /** Present (not `undefined`) means the consumer owns the value: state here is ignored. */
14
+ value?: T;
15
+ /** The starting value when the consumer does not own it. A function is called once, lazily. */
16
+ defaultValue: T | (() => T);
17
+ onChange?: ChangeHandler<T, TReason>;
18
+ }
19
+ export type SetControllableState<T, TReason extends string = string> = (next: T | ((current: T) => T), details: ChangeDetails<TReason>) => void;
20
+ /**
21
+ * One state value that works the same whether the consumer controls it or not. The setter is stable, and
22
+ * every call names a reason, which is what reaches `onChange`. A call resolving to the value already held
23
+ * is dropped: two dismissal layers closing the same popup is the normal case, not an error.
24
+ */
25
+ export default function useControllableState<T, TReason extends string = string>(options: ControllableStateOptions<T, TReason>): [T, SetControllableState<T, TReason>];
@@ -0,0 +1,25 @@
1
+ import { ElementLike } from '../../utils/dom/domUtils';
2
+ export type DismissReason = 'escape' | 'outside-pointer';
3
+ export type { ElementLike };
4
+ export interface DismissOptions {
5
+ /** Usually the open state: listeners exist only while this is true. */
6
+ enabled?: boolean;
7
+ onDismiss: (reason: DismissReason, event: Event) => void;
8
+ /**
9
+ * What counts as *inside*: the popup, and the trigger too — a press on the trigger of an open popup must
10
+ * reach its own toggle rather than being dismissed and reopened in one gesture.
11
+ */
12
+ inside?: ReadonlyArray<ElementLike>;
13
+ /** Default true. */
14
+ escapeKey?: boolean;
15
+ /** Default true. */
16
+ outsidePointer?: boolean;
17
+ }
18
+ /**
19
+ * Close on Escape and on a pointer press outside — the two halves of light dismiss, composable across
20
+ * nested layers: Escape reaches the innermost only, while an outside press is judged per layer, so a
21
+ * press in the page closes a menu and its submenu and a press in the menu closes just the submenu.
22
+ * `pointerdown` rather than `click`, because a press that starts inside and ends outside (a drag across a
23
+ * scrollbar, a text selection) is not a dismissal.
24
+ */
25
+ export default function useDismiss(options: DismissOptions): void;
@@ -0,0 +1,18 @@
1
+ import { ElementLike } from '../../utils/dom/domUtils';
2
+ export interface FocusReturnOptions {
3
+ /** Usually the open state. The invoker is remembered the moment this becomes true. */
4
+ enabled?: boolean;
5
+ /** Where focus should land instead of whatever had it when the layer opened. */
6
+ returnTo?: ElementLike;
7
+ /** Passed to `focus()` — keeps a long page from jumping when the invoker is off screen. */
8
+ preventScroll?: boolean;
9
+ }
10
+ /**
11
+ * Put focus back where it came from when a layer closes. Losing it to `<body>` is the commonest keyboard
12
+ * bug in a popup: the next Tab starts again at the top of the page. Skipped when something else already
13
+ * holds focus — a dialog the layer opened, or a user who tabbed away — since taking it back is the same
14
+ * bug pointing the other way.
15
+ */
16
+ export default function useFocusReturn(options?: FocusReturnOptions): {
17
+ returnFocus: () => void;
18
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * A stable, unique id for wiring one element to another — `aria-labelledby`, `aria-controls`,
3
+ * `aria-activedescendant`, `<label for>`.
4
+ *
5
+ * Stable means: the same across renders, the same on the server and on the client (so hydration
6
+ * does not throw the markup away), and different for every instance of a component. Derive related
7
+ * ids from one call rather than calling the hook per element:
8
+ *
9
+ * ```ts
10
+ * const id = useIdentifier('select');
11
+ * // `${id}-trigger`, `${id}-listbox`
12
+ * ```
13
+ *
14
+ * On React 16/17 the fallback is a module counter, which cannot match between a server render and
15
+ * the client one — pass ids in explicitly there if the tree is hydrated.
16
+ */
17
+ export default function useIdentifier(prefix?: string): string;
@@ -0,0 +1,84 @@
1
+ import { ChangeDetails, ChangeHandler } from './useControllableState';
2
+ export type RovingFocusReason = 'keyboard' | 'typeahead' | 'focus' | 'programmatic';
3
+ export type RovingOrientation = 'vertical' | 'horizontal' | 'both';
4
+ /** A position in grid mode. Both are `-1` when nothing is active. */
5
+ export interface RovingCell {
6
+ row: number;
7
+ column: number;
8
+ }
9
+ export interface RovingFocusOptions {
10
+ /** How many items there are right now — rows, in grid mode. A filtered list may change this. */
11
+ count: number;
12
+ /**
13
+ * Turns the list into a grid and `count` into a count of rows: how many cells the row at `row` holds, a
14
+ * function when rows differ. Grid mode moves in two axes and never wraps (APG), Home/End go to the
15
+ * row's ends, Ctrl+Home/End to the grid's corners, PageUp/PageDown by `pageSize` rows.
16
+ */
17
+ columns?: number | ((row: number) => number);
18
+ /**
19
+ * Where a cell starts in column-index space, for rows whose cells do not line up one-to-one with the
20
+ * grid's columns (a grouped header, a spanning group row). Vertical movement is measured in this space,
21
+ * so a move down out of a cell covering columns 4–6 lands under the column it started in. Identity by default.
22
+ */
23
+ columnIndexOf?: (row: number, cell: number) => number;
24
+ /** Rows a PageUp/PageDown moves. Default 10. Grid mode only. */
25
+ pageSize?: number;
26
+ /** The starting column *index*, when the caller wants one other than the first. Grid mode only. */
27
+ defaultActiveColumn?: number;
28
+ /** The active cell moved. Grid mode only — `onActiveIndexChange` still reports the row. */
29
+ onActiveCellChange?: ChangeHandler<RovingCell, RovingFocusReason>;
30
+ /** Which arrow keys navigate. Default `vertical`. Ignored in grid mode, which uses both axes. */
31
+ orientation?: RovingOrientation;
32
+ /** Wrap around at the ends. Default true. */
33
+ loop?: boolean;
34
+ activeIndex?: number;
35
+ defaultActiveIndex?: number;
36
+ onActiveIndexChange?: ChangeHandler<number, RovingFocusReason>;
37
+ /** Disabled items are skipped by every movement, as APG requires. */
38
+ isDisabled?: (index: number) => boolean;
39
+ /** An item's text. Supplying it turns on typeahead. */
40
+ textOf?: (index: number) => string;
41
+ /**
42
+ * Move real DOM focus onto the active item — the roving-tabindex pattern. `false` is the other half of
43
+ * the APG list patterns: focus stays put (a combobox's trigger) and `aria-activedescendant` names the
44
+ * active item instead. The hook still tracks the index; it just does not take focus.
45
+ */
46
+ focusItems?: boolean;
47
+ /** Enter, and Space when no typeahead buffer is open. */
48
+ onSelect?: (index: number, event: React.KeyboardEvent) => void;
49
+ }
50
+ export interface RovingFocusItemProps {
51
+ ref: (element: HTMLElement | null) => void;
52
+ tabIndex?: number;
53
+ onFocus?: () => void;
54
+ }
55
+ export interface RovingFocus {
56
+ /** Clamped to the current `count`; `-1` when nothing is active. The row, in grid mode. */
57
+ activeIndex: number;
58
+ /**
59
+ * The active cell's ordinal in its row — its column index only while no cell spans more than one column.
60
+ * `-1` outside grid mode.
61
+ */
62
+ activeColumn: number;
63
+ setActiveIndex: (index: number, details: ChangeDetails<RovingFocusReason>) => void;
64
+ /** Grid mode: move both axes at once, `column` being a cell ordinal. Out-of-range values are clamped. */
65
+ setActiveCell: (row: number, column: number, details: ChangeDetails<RovingFocusReason>) => void;
66
+ /** Put this on the element that has focus: the list in roving-tabindex, the trigger otherwise. */
67
+ onKeyDown: (event: React.KeyboardEvent) => void;
68
+ itemProps: (index: number) => RovingFocusItemProps;
69
+ /** Grid mode's `itemProps`: the roving tabindex and the ref for one cell. */
70
+ cellProps: (row: number, column: number) => RovingFocusItemProps;
71
+ /**
72
+ * The active item's element, for `aria-activedescendant` or to scroll it into view. `null` in grid mode
73
+ * whenever the active cell is not rendered, which a virtualized grid is full of: bring the row into view
74
+ * first, then read this on the render that follows.
75
+ */
76
+ activeItem: () => HTMLElement | null;
77
+ }
78
+ /**
79
+ * Arrow-key navigation over a list: the movement half of every APG list pattern (listbox, menu, tabs,
80
+ * radio group), with both focus strategies. It owns which item is active and how the keys move it; the
81
+ * caller owns the roles and the ARIA, because a listbox and a menu navigate alike and are named quite
82
+ * differently. `columns` turns the same movement into APG's grid pattern, and may be a function of the row.
83
+ */
84
+ export default function useRovingFocus(options: RovingFocusOptions): RovingFocus;
@@ -0,0 +1,32 @@
1
+ import { RefCallback } from 'react';
2
+ /** The Radix / Base UI attribute value, so a `[data-state]` selector written for either works here too. */
3
+ export type PresenceState = 'open' | 'closed';
4
+ export interface PresenceOptions {
5
+ /** Whether the subtree should be there. The exit starts the moment this goes false. */
6
+ present: boolean;
7
+ }
8
+ export interface Presence {
9
+ /** Whether to render anything at all: true for the whole exit, false once it has finished. */
10
+ mounted: boolean;
11
+ /** False from the first frame of the exit — the flag the leaving styles hang off. */
12
+ present: boolean;
13
+ state: PresenceState;
14
+ /** Goes on the element that carries the transition: its computed style is what the wait is measured from. */
15
+ ref: RefCallback<HTMLElement>;
16
+ /** `{ 'data-state': … }`, ready to spread into a Box's `props`. */
17
+ props: {
18
+ 'data-state': PresenceState;
19
+ };
20
+ }
21
+ /**
22
+ * Holds a subtree long enough for its exit to run, then lets it go. React removes a node the instant it
23
+ * stops rendering it, which is why `startingStyle` can animate an entrance with no JavaScript and nothing
24
+ * can animate an exit: by the time the styles would change, the element is already gone.
25
+ *
26
+ * **The wait is the duration the element's own CSS declares**, read off the node the moment the exit
27
+ * starts. `transitionend` would be more precise but fires once per property with no way to know how many
28
+ * are coming, so the first one cuts a two-property exit short — and a transition that never starts fires
29
+ * nothing at all, so an event-driven wait needs this timer as a backstop anyway. One mechanism, sized from
30
+ * the real CSS: a zero duration (nothing declared, or `prefers-reduced-motion`) unmounts in the same commit.
31
+ */
32
+ export default function usePresence(options: PresenceOptions): Presence;
@@ -0,0 +1,25 @@
1
+ import { ClassNameType } from '@box-kite/core';
2
+ import { ResolvedBoxStyles } from './resolveStyles';
3
+ /**
4
+ * What `useClassNames` hands back: the class attribute for an element this library does not render
5
+ * itself, and — in element mode only — the `<style>` elements those classes need.
6
+ */
7
+ export interface BoxClassNames {
8
+ /** The whole `class` attribute, the engine's classes and the caller's own, already joined. */
9
+ className: string;
10
+ /**
11
+ * Element mode only: the hoistable `<style>` elements the classes need. Render them beside the
12
+ * element (React 19 lifts them into `<head>`). Undefined in every other mode, where the CSS has
13
+ * already gone to a stylesheet and there is nothing left to render.
14
+ */
15
+ styles?: ResolvedBoxStyles['styleElements'];
16
+ }
17
+ /**
18
+ * The resolved styles as a class attribute. Hook-free, so the client entry and the Server-Component
19
+ * one give `useClassNames` the same shape — the only difference between them is whether resolving
20
+ * the styles scheduled a flush effect.
21
+ */
22
+ export default function boxClassNames({ classNames: styleClasses, styleElements }: ResolvedBoxStyles, userClassName?: ClassNameType): {
23
+ className: string;
24
+ styles: import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>[] | undefined;
25
+ };
@@ -0,0 +1,49 @@
1
+ import { default as React } from 'react';
2
+ import { ClassNameType } from '@box-kite/core';
3
+ import { BoxStyleProps, ComponentsAndVariants } from '@box-kite/core/types';
4
+ /**
5
+ * The prop shape of Box, shared by the client component and the Server-Component one so the public
6
+ * surface cannot drift between them.
7
+ */
8
+ type AllProps<TTag extends keyof React.JSX.IntrinsicElements> = React.ComponentProps<TTag>;
9
+ /** `data-*`, which React's own attribute types allow only in JSX position and never in a props bag. */
10
+ type DataAttributes = {
11
+ [attribute: `data-${string}`]: string | number | boolean | undefined;
12
+ };
13
+ type TagProps<TTag extends keyof React.JSX.IntrinsicElements> = Omit<AllProps<TTag>, 'className' | 'style' | 'ref' | 'disabled' | 'required' | 'checked' | 'id'>;
14
+ /**
15
+ * Every attribute the tag takes, plus `data-*` (bug #99: `props={{ 'data-state': 'open' }}` did not
16
+ * typecheck, and `<Box data-state>` did but was dropped, since Box forwards nothing but `props`). A union
17
+ * rather than an intersection: an index signature in the target makes every *interface* passed as a bag
18
+ * unassignable, and `TooltipTrigger.props` is one. Anything else unknown still fails.
19
+ */
20
+ export type TagPropsType<TTag extends keyof React.JSX.IntrinsicElements> = TagProps<TTag> | (TagProps<TTag> & DataAttributes);
21
+ /**
22
+ * `Omit` one union member at a time, for a component claiming attributes of its own. A plain `Omit` over
23
+ * a union keeps only the keys every member shares, so it collapsed the two above into one and dropped
24
+ * `data-*` again — bug #99 one layer up, on every pre-built component.
25
+ */
26
+ export type OmitTagProps<TProps, TKeys extends PropertyKey> = TProps extends unknown ? Omit<TProps, TKeys> : never;
27
+ /**
28
+ * The style props plus the `className` the engine's classes are merged with — everything the
29
+ * resolution needs and nothing about a tag. `useClassNames` takes this, which is why it can style
30
+ * an element this library does not render.
31
+ */
32
+ export interface BoxClassNameProps<TKey extends keyof ComponentsAndVariants = never> extends BoxStyleProps<TKey> {
33
+ /** classNames. supports conditional classNames. */
34
+ className?: ClassNameType;
35
+ }
36
+ export interface BoxCoreProps<TTag extends keyof React.JSX.IntrinsicElements, TKey extends keyof ComponentsAndVariants> extends BoxClassNameProps<TKey> {
37
+ children?: React.ReactNode | ((props: {
38
+ isHover: boolean;
39
+ }) => React.ReactNode);
40
+ /** html tag element */
41
+ tag?: TTag;
42
+ /** props (attributes) related to html tag */
43
+ props?: TagPropsType<TTag>;
44
+ /** CSSProperties */
45
+ style?: React.ComponentProps<TTag>['style'];
46
+ /** The HTML id attribute is used to specify a unique id for an HTML element. */
47
+ id?: string;
48
+ }
49
+ export {};
@@ -0,0 +1,7 @@
1
+ import { BoxStyleProps } from '@box-kite/core/types';
2
+ /**
3
+ * The props that reach the HTML tag: whatever the caller put in `props`, the resolved class list,
4
+ * and the handful of attributes Box lifts to its own top level. Hook-free, so the client Box and
5
+ * the Server-Component Box assemble their markup through the same code.
6
+ */
7
+ export default function buildTagProps(source: BoxStyleProps<any>, styleClasses: string[]): Record<string, any>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The client half of the library needs React APIs the server build does not have. Under the `react-server`
3
+ * condition they are absent, so the first one touched at import time throws `createContext is not a
4
+ * function` — no file, no component, nothing to act on (bug #43). The published build prevents that; this
5
+ * is for the ways around it: a deep import, a bundler with no condition, a framework mixing the graphs.
6
+ */
7
+ export declare const CLIENT_RUNTIME_MESSAGE: string;
8
+ /** Throws with something readable if `react` is the server build. Called where the first one is needed. */
9
+ export default function assertClientRuntime(react: {
10
+ createContext?: unknown;
11
+ }): void;
@@ -0,0 +1,10 @@
1
+ import { default as React, useLayoutEffect } from 'react';
2
+ /** A layout effect on the browser, a passive one everywhere else. */
3
+ export declare const useIsomorphicLayoutEffect: typeof React.useEffect;
4
+ /**
5
+ * An insertion effect on the browser, falling back to a layout effect on React 16/17 — React's own
6
+ * recommendation for injecting CSS-in-JS. Insertion effects run during the commit ahead of *every* layout
7
+ * effect, so a component measuring its DOM already sees the styles. Off the browser nothing paints and
8
+ * `getStyles()` flushes for itself, so `useEffect` keeps React quiet.
9
+ */
10
+ export declare const useIsomorphicInsertionEffect: typeof useLayoutEffect;
@@ -0,0 +1,17 @@
1
+ import { BoxProps } from '../../box';
2
+ export interface LabelledControlProps {
3
+ /** The text beside the control. Nothing is wrapped while this is absent. */
4
+ label?: React.ReactNode;
5
+ /** Styles for the `<label>` that wraps the pair — layout, not the control's own appearance. */
6
+ labelProps?: BoxProps<'label'>;
7
+ /** The control itself: an `<input>` that must end up *inside* the label element. */
8
+ children: React.ReactNode;
9
+ }
10
+ /**
11
+ * A form control and its text inside the one `<label>` that ties them together, implicitly: nothing has to
12
+ * be unique (an explicit `for`/`id` pair needs `useId`, a hook, so `RadioButton` would stop rendering on a
13
+ * server) and there is one element to click, so the whole row is a hit target. The text is a bare child
14
+ * rather than a `<Span>`, because a module several chunks share must not import a component chunk — that
15
+ * cycle left `StringUtils` undefined as soon as `semantics.mjs` loaded.
16
+ */
17
+ export default function LabelledControl({ label, labelProps, children }: LabelledControlProps): React.ReactNode;
@@ -0,0 +1,13 @@
1
+ import { BoxPseudoElementStyles } from '@box-kite/core/types';
2
+ /**
3
+ * `placeholder` is an attribute on an `<input>` and a pseudo-element on a Box, and both readings are
4
+ * right — the same collision `Rect`'s `width` and `Path`'s `d` have, settled per element. A string is the
5
+ * text, an object is the `::placeholder` styles, and both at once means the text goes in `props`, where
6
+ * every other attribute already goes.
7
+ */
8
+ export type PlaceholderProp = string | BoxPseudoElementStyles;
9
+ /** The prop split into the two things it can be: `text` for the attribute, `styles` for the Box prop. */
10
+ export default function splitPlaceholder(placeholder: PlaceholderProp | undefined): {
11
+ text?: string;
12
+ styles?: BoxPseudoElementStyles;
13
+ };
@@ -0,0 +1 @@
1
+ export default function usePortalContainer(): HTMLElement | null;
@@ -0,0 +1,43 @@
1
+ export interface UseVirtualizationOptions {
2
+ /** Total number of items */
3
+ itemCount: number;
4
+ /** Height of each item in pixels */
5
+ itemHeight: number;
6
+ /** Height of the visible container in pixels */
7
+ containerHeight: number;
8
+ /** Number of items to render outside visible area (default: 3) */
9
+ overscan?: number;
10
+ /** Whether virtualization is enabled (default: true when itemCount > threshold) */
11
+ enabled?: boolean;
12
+ /** Threshold for enabling virtualization (default: 50) */
13
+ threshold?: number;
14
+ }
15
+ export interface UseVirtualizationResult {
16
+ /** First item index to render */
17
+ startIndex: number;
18
+ /** Last item index to render (inclusive) */
19
+ endIndex: number;
20
+ /** Total height of all items (for scroll container) */
21
+ totalHeight: number;
22
+ /** Y offset for positioning visible items */
23
+ offsetY: number;
24
+ /** Number of visible items */
25
+ visibleCount: number;
26
+ /** Whether virtualization is active */
27
+ isVirtualized: boolean;
28
+ /** Scroll event handler - attach to container's onScroll */
29
+ handleScroll: (e: React.UIEvent<HTMLElement>) => void;
30
+ /** Current scroll position */
31
+ scrollTop: number;
32
+ /** Container style for the scroll area */
33
+ containerStyle: React.CSSProperties;
34
+ /** Inner wrapper style (total height) */
35
+ innerStyle: React.CSSProperties;
36
+ /** Content style (transform offset) */
37
+ contentStyle: React.CSSProperties;
38
+ }
39
+ /**
40
+ * Hook for virtualizing large lists.
41
+ * Only renders items that are visible in the viewport plus overscan buffer.
42
+ */
43
+ export default function useVirtualization(options: UseVirtualizationOptions): UseVirtualizationResult;
@@ -0,0 +1,9 @@
1
+ interface Props<T extends HTMLElement = HTMLDivElement> {
2
+ node?: T | null;
3
+ event?: 'mousedown' | 'click';
4
+ hideOnScroll?: boolean;
5
+ hideOnResize?: boolean;
6
+ hideOnEscape?: boolean;
7
+ }
8
+ export default function useVisibility<T extends HTMLElement = HTMLDivElement>(props?: Props<T>): [boolean, React.Dispatch<React.SetStateAction<boolean>>, React.RefObject<T | null>];
9
+ export {};
@@ -0,0 +1,10 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * React-only type helpers. These live in the adapter rather than in `src/core/coreTypes.ts`
4
+ * because they are expressed in React's own JSX types — the style definitions themselves stay
5
+ * framework-free so every adapter can share them.
6
+ */
7
+ /** The DOM element type behind a set of React props (`HTMLAttributes<E>` / `SVGProps<E>` → `E`). */
8
+ export type ExtractElementType<T> = T extends React.DetailedHTMLProps<React.HTMLAttributes<infer E>, infer E> ? E : T extends React.SVGProps<infer E> ? E : never;
9
+ /** The DOM element type behind an intrinsic tag name (`'input'` → `HTMLInputElement`). */
10
+ export type ExtractElementFromTag<T extends keyof React.JSX.IntrinsicElements> = ExtractElementType<React.JSX.IntrinsicElements[T]>;
@@ -0,0 +1,18 @@
1
+ import { default as React } from 'react';
2
+ import { BoxStyleProps } from '@box-kite/core/types';
3
+ export interface ResolvedBoxStyles {
4
+ classNames: string[];
5
+ /**
6
+ * Element mode only: the hoistable `<style>` elements this Box's classes need, the engine's base
7
+ * element first. Undefined in every other mode, where the CSS has already gone to a stylesheet.
8
+ */
9
+ styleElements?: React.ReactElement[];
10
+ }
11
+ /**
12
+ * Resolve a Box's classes with no hook at all — the render path a Server Component takes. In element mode
13
+ * what those classes need comes back as elements to render, so there is nothing to flush. Its own module
14
+ * for that reason: the RSC entry must reach this without pulling in `useStyles` and its flush effect.
15
+ */
16
+ export default function resolveStyles(props: BoxStyleProps<any>, isSvg: boolean): ResolvedBoxStyles & {
17
+ signature: string | null;
18
+ };
@@ -0,0 +1,3 @@
1
+ import { default as React } from 'react';
2
+ import { StyleElementDescriptor } from '@box-kite/core';
3
+ export default function styleElementsOf(descriptors: readonly StyleElementDescriptor[] | undefined): React.ReactElement[] | undefined;
@@ -0,0 +1,4 @@
1
+ /** Marks a component of this library's own: its DOM attributes belong in `props`, not on top. */
2
+ export declare function withAttributesInProps<TComponent>(component: TComponent): TComponent;
3
+ /** Whether an element's `type` is one of those components. Anything else takes attributes on top. */
4
+ export declare function hasAttributesInProps(type: unknown): boolean;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * A drawing nobody named is decoration, which `aria-hidden` says and silence leaves ambiguous; `label` is
3
+ * the opt-in that makes it `role="img"`. The same rule for every `<svg>` this library puts on a page,
4
+ * whether it renders the element (`Svg`) or hands the attributes to one somebody else renders (`Icon`).
5
+ * `given` is naming the caller wrote by hand — if there is any, the decision was theirs.
6
+ */
7
+ export default function svgNaming(label: string | undefined, given: object | undefined): {
8
+ role: string;
9
+ 'aria-label': string;
10
+ 'aria-hidden'?: undefined;
11
+ } | {
12
+ 'aria-hidden': boolean;
13
+ role?: undefined;
14
+ 'aria-label'?: undefined;
15
+ } | undefined;
@@ -0,0 +1,26 @@
1
+ import { default as React } from 'react';
2
+ import { BoxStyleProps } from '@box-kite/core/types';
3
+ interface ThemeProps {
4
+ children: React.ReactNode;
5
+ theme?: string;
6
+ use?: 'global' | 'local';
7
+ /** When provided, persists the user-selected theme to localStorage under this key. */
8
+ storageKey?: string;
9
+ /**
10
+ * App-wide Box style props applied to the document root (`<html>`). Only takes effect when `use="global"`.
11
+ * Supports the same shape as Box props, including theme-keyed values:
12
+ * `globalStyles={{ scrollbarColor: ['violet-500', 'transparent'], theme: { dark: { scrollbarColor: [...] } } }}`.
13
+ */
14
+ globalStyles?: BoxStyleProps;
15
+ }
16
+ /**
17
+ * The React binding for the theme system. Everything that actually touches the platform — reading
18
+ * and watching `prefers-color-scheme`, persisting the choice, writing the theme onto an element —
19
+ * lives in the framework-free `core/theme/themeRuntime`; this component only holds the React state
20
+ * and context around it.
21
+ */
22
+ declare function Theme(props: ThemeProps): React.JSX.Element;
23
+ declare namespace Theme {
24
+ function useTheme(): [string, (theme: string | null) => void];
25
+ }
26
+ export default Theme;
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ interface ThemeContextProps {
3
+ theme: string;
4
+ setTheme(theme: string | null): void;
5
+ }
6
+ declare const ThemeContext: React.Context<ThemeContextProps>;
7
+ export default ThemeContext;
@@ -0,0 +1,22 @@
1
+ import { StylesConfiguration } from '@box-kite/core';
2
+ import { BoxStyleProps } from '@box-kite/core/types';
3
+ import { ResolvedBoxStyles } from './resolveStyles';
4
+ export type { StylesConfiguration };
5
+ export default function useStyles(props: BoxStyleProps<any>, isSvg: boolean): ResolvedBoxStyles;
6
+ /**
7
+ * Rules that target a root selector (`html`) instead of a class. Returns their style elements in
8
+ * element mode — global styles belong to no Box, so the caller has to render them itself.
9
+ */
10
+ export declare function useGlobalStyles(props: BoxStyleProps<any> | undefined, selector: string): React.ReactElement[] | undefined;
11
+ /** Engine controls for the default instance. For an isolated engine use `createStyleEngine()`. */
12
+ export declare namespace StylesContext {
13
+ /** Write every pending rule now. The React binding calls this from an insertion effect. */
14
+ function flushSync(): void;
15
+ function clear(): void;
16
+ /** The CSS emitted so far, as text. Flushes first — see `StyleEngine.getStyles`. */
17
+ function getStyles(): string;
18
+ /** The id of the `<style>` element the default engine writes to. */
19
+ function styleElementId(): string;
20
+ /** Apply explicit engine configuration. Call before the first render — cached class names are dropped when the configuration changes. */
21
+ function configure(config: StylesConfiguration): void;
22
+ }
@@ -0,0 +1 @@
1
+ const e=require("./rolldown-runtime.cjs");let t=require("react");t=e.t(t,1);let n=require("@box-kite/core");function r({classNames:e,styleElements:t},r){return{className:(0,n.classNames)(e,r).join(` `),styles:t}}var i={selected:`aria-selected`},a;(function(e){function t(e,t,n){e!==void 0&&e!=null&&(n[i[t]??t]=Array.isArray(e)?e[0]:e)}e.assignBooleanProp=t})(a||={});var o=a;function s(e,t){let r=e,{props:i,className:a,disabled:s,required:c,checked:l,selected:u}=r,d={...i,className:(0,n.classNames)(t,a).join(` `)};return o.assignBooleanProp(s,`disabled`,d),o.assignBooleanProp(c,`required`,d),o.assignBooleanProp(l,`checked`,d),o.assignBooleanProp(u,`selected`,d),`style`in r&&(d.style=r.style),`id`in r&&(d.id=r.id),d}var c=parseInt(t.default.version,10)>=19,l=!1;function u(e){if(e?.length)return!c&&!l&&(l=!0,console.warn(`[box-kite] Box.configure({ sink: 'element' }) needs React 19 to hoist and dedupe its <style> elements; React ${t.default.version} will render them inline. Use the default sink instead.`)),e.map(({href:e,css:n,precedence:r})=>t.default.createElement(`style`,{key:e,href:e,precedence:r,dangerouslySetInnerHTML:{__html:n}}))}function d(e,t){let{classNames:r,signature:i,styleElements:a}=(0,n.getDefaultEngine)().resolveClassNames(e,t);return{classNames:r,signature:i,styleElements:u(a)}}var f=`__boxAttributesInProps`;function p(e){return e[f]=!0,e}function m(e){return typeof e==`function`||typeof e==`object`&&e?e[f]===!0:!1}var h=[`role`,`aria-label`,`aria-labelledby`,`aria-hidden`];function g(e,t){if(e!==void 0)return{role:`img`,"aria-label":e};if(!(t&&h.some(e=>e in t)))return{"aria-hidden":!0}}var _;(function(e){function t(e){return e.charAt(0).toUpperCase()+e.slice(1)}e.capitalize=t})(_||={});var v=_,y;(function(e){function t(e,t,n){let r={...e},i=r.props||{};return t.forEach(e=>{e in r&&(i[e]=r[e],delete r[e])}),n&&Object.entries(n).forEach(([e,t])=>{i[e]=t}),r.props=i,r}e.buildProps=t;function n(e){return!!e&&typeof e==`object`}e.isObject=n;function r(e,t){return e in t}e.isKeyOf=r})(y||={});var b=y;Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return b}});