@nurix/etna 0.20.36 → 0.20.38

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 (212) hide show
  1. package/data/catalog/rules/frontend.md +5 -5
  2. package/data/catalog/rules/pnpm.md +2 -2
  3. package/data/catalog/skills/nustack/SKILL.md +2 -2
  4. package/data/catalog/skills/nustack/references/cli-design.md +35 -35
  5. package/data/catalog/skills/nustack/references/monorepo-master-list.md +6 -6
  6. package/data/catalog/skills/nustack/references/monorepo-setup.md +13 -13
  7. package/data/catalog/skills/nustack/references/publishing.md +40 -39
  8. package/data/harness-index.json +1 -1
  9. package/data/harnesses/code/harness.json +2 -2
  10. package/data/harnesses/code/hooks/approved-packages.md +1 -2
  11. package/data/harnesses/code/rules/frontend.md +5 -5
  12. package/data/harnesses/code/rules/pnpm.md +2 -2
  13. package/data/harnesses/code/skills/boundary/SKILL.md +33 -22
  14. package/data/harnesses/code/skills/boundary/references/index.md +2 -4
  15. package/data/harnesses/code/skills/boundary/references/mechanisms.md +3 -10
  16. package/data/harnesses/code/skills/boundary/references/packs/build-config-runtime.md +1 -1
  17. package/data/harnesses/code/skills/boundary/references/packs/frontend.md +17 -17
  18. package/data/harnesses/code/skills/boundary/references/packs/generic-tail.md +1 -1
  19. package/data/harnesses/code/skills/brainstorm/README.md +11 -13
  20. package/data/harnesses/code/skills/brainstorm/SKILL.md +150 -132
  21. package/data/harnesses/code/skills/brainstorm/references/doctrine.md +48 -51
  22. package/data/harnesses/code/skills/brainstorm/references/harvest.md +51 -56
  23. package/data/harnesses/code/skills/brainstorm/references/session-schema.md +48 -42
  24. package/data/harnesses/code/skills/design/SKILL.md +31 -35
  25. package/data/harnesses/code/skills/design/components/charts.md +121 -43
  26. package/data/harnesses/code/skills/design/components/collections.md +209 -41
  27. package/data/harnesses/code/skills/design/components/feedback.md +86 -25
  28. package/data/harnesses/code/skills/design/components/hooks.md +198 -12
  29. package/data/harnesses/code/skills/design/components/index.md +93 -71
  30. package/data/harnesses/code/skills/design/components/inputs.md +249 -157
  31. package/data/harnesses/code/skills/design/components/layout.md +98 -38
  32. package/data/harnesses/code/skills/design/components/media.md +46 -25
  33. package/data/harnesses/code/skills/design/components/motion.md +56 -46
  34. package/data/harnesses/code/skills/design/components/navigation.md +54 -15
  35. package/data/harnesses/code/skills/design/components/overlays.md +51 -41
  36. package/data/harnesses/code/skills/design/components/setup.md +84 -5
  37. package/data/harnesses/code/skills/design/components/typography.md +72 -22
  38. package/data/harnesses/code/skills/design/components/utils.md +47 -13
  39. package/data/harnesses/code/skills/design/data/chrome/board-column.md +12 -12
  40. package/data/harnesses/code/skills/design/data/chrome/data-table.md +6 -6
  41. package/data/harnesses/code/skills/design/data/chrome/side-panel.md +15 -15
  42. package/data/harnesses/code/skills/design/data/chrome/sidebar.md +25 -25
  43. package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +22 -22
  44. package/data/harnesses/code/skills/design/data/chrome/topbar.md +12 -12
  45. package/data/harnesses/code/skills/design/data/iconography.md +2 -2
  46. package/data/harnesses/code/skills/design/references/compose.md +14 -16
  47. package/data/harnesses/code/skills/design/references/emission.md +6 -6
  48. package/data/harnesses/code/skills/design/references/foundations.md +5 -5
  49. package/data/harnesses/code/skills/design/references/intake.md +6 -6
  50. package/data/harnesses/code/skills/design/references/object-pass.md +1 -1
  51. package/data/harnesses/code/skills/design/references/ship-gate.md +5 -5
  52. package/data/harnesses/code/skills/design/references/ux-patterns/Readme.md +4 -4
  53. package/data/harnesses/code/skills/design/references/ux-patterns/ai-layer.md +1 -1
  54. package/data/harnesses/code/skills/design/references/ux-patterns/container-choice.md +1 -1
  55. package/data/harnesses/code/skills/design/references/ux-patterns/dashboards.md +1 -1
  56. package/data/harnesses/code/skills/design/references/ux-patterns/modes.md +1 -1
  57. package/data/harnesses/code/skills/design/references/ux-patterns/object-model.md +2 -2
  58. package/data/harnesses/code/skills/design/references/ux-patterns/promotion-demotion.md +1 -1
  59. package/data/harnesses/code/skills/design/references/ux-patterns/settings.md +1 -1
  60. package/data/harnesses/code/skills/design/references/ux-patterns/standard-pages.md +1 -1
  61. package/data/harnesses/code/skills/design/scripts/README-validator.md +20 -8
  62. package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +15 -10
  63. package/data/harnesses/code/skills/documentation/SKILL.md +5 -5
  64. package/data/harnesses/code/skills/documentation/references/examples.md +22 -22
  65. package/data/harnesses/code/skills/documentation/references/frontmatter.md +3 -3
  66. package/data/harnesses/code/skills/documentation/references/instruction-style.md +3 -3
  67. package/data/harnesses/code/skills/documentation/references/source-comments.md +3 -3
  68. package/data/harnesses/code/skills/documentation/references/style-guide.md +5 -5
  69. package/data/harnesses/code/skills/documentation/references/untemplated.md +8 -8
  70. package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +3 -2
  71. package/data/harnesses/code/skills/documentation/templates/Readme.md +1 -1
  72. package/data/harnesses/code/skills/documentation/templates/acceptance-criteria.md +1 -1
  73. package/data/harnesses/code/skills/documentation/templates/api-reference.md +1 -1
  74. package/data/harnesses/code/skills/documentation/templates/architecture-decision.md +3 -7
  75. package/data/harnesses/code/skills/documentation/templates/behavioral-checklist.md +1 -1
  76. package/data/harnesses/code/skills/documentation/templates/changelog-entry.md +1 -1
  77. package/data/harnesses/code/skills/documentation/templates/changelog-index.md +1 -1
  78. package/data/harnesses/code/skills/documentation/templates/docs-readme.md +3 -3
  79. package/data/harnesses/code/skills/documentation/templates/doctrine.md +1 -1
  80. package/data/harnesses/code/skills/documentation/templates/domain-model.md +1 -1
  81. package/data/harnesses/code/skills/documentation/templates/environment-registry.md +1 -1
  82. package/data/harnesses/code/skills/documentation/templates/feature.md +3 -3
  83. package/data/harnesses/code/skills/documentation/templates/handover.md +2 -2
  84. package/data/harnesses/code/skills/documentation/templates/implementation-map.md +1 -1
  85. package/data/harnesses/code/skills/documentation/templates/migration-runbook.md +1 -1
  86. package/data/harnesses/code/skills/documentation/templates/non-goals.md +1 -1
  87. package/data/harnesses/code/skills/documentation/templates/operations-procedure.md +2 -2
  88. package/data/harnesses/code/skills/documentation/templates/package.md +1 -1
  89. package/data/harnesses/code/skills/documentation/templates/protected-files.md +1 -1
  90. package/data/harnesses/code/skills/documentation/templates/root-readme.md +1 -1
  91. package/data/harnesses/code/skills/documentation/templates/security-overview.md +1 -1
  92. package/data/harnesses/code/skills/documentation/templates/system-overview.md +1 -1
  93. package/data/harnesses/code/skills/documentation/templates/system.md +1 -1
  94. package/data/harnesses/code/skills/documentation/templates/testing-strategy.md +1 -1
  95. package/data/harnesses/code/skills/documentation/templates/ux-behavior.md +3 -5
  96. package/data/harnesses/code/skills/issue-bridge/SKILL.md +51 -16
  97. package/data/harnesses/code/skills/issue-bridge/references/trackers/github.md +5 -5
  98. package/data/harnesses/code/skills/issue-bridge/references/trackers/jira.md +11 -8
  99. package/data/harnesses/code/skills/issue-bridge/references/trackers/linear.md +16 -11
  100. package/data/harnesses/code/skills/nustack-graph/SKILL.md +38 -29
  101. package/data/harnesses/code/skills/polygraph/references/dispatch.md +31 -18
  102. package/data/harnesses/code/skills/polygraph/references/rows.md +11 -6
  103. package/data/harnesses/code/skills/schema-design/SKILL.md +39 -41
  104. package/data/harnesses/code/skills/test/SKILL.md +38 -42
  105. package/data/harnesses/code/skills/testing/SKILL.md +83 -73
  106. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +156 -193
  107. package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +15 -15
  108. package/data/harnesses/delivery/harness.json +2 -2
  109. package/data/harnesses/delivery/skills/brainstorm/README.md +11 -13
  110. package/data/harnesses/delivery/skills/brainstorm/SKILL.md +150 -132
  111. package/data/harnesses/delivery/skills/brainstorm/references/doctrine.md +48 -51
  112. package/data/harnesses/delivery/skills/brainstorm/references/harvest.md +51 -56
  113. package/data/harnesses/delivery/skills/brainstorm/references/session-schema.md +48 -42
  114. package/data/harnesses/delivery/skills/cost-report/SKILL.md +10 -10
  115. package/data/harnesses/delivery/skills/documentation/SKILL.md +5 -5
  116. package/data/harnesses/delivery/skills/documentation/references/examples.md +22 -22
  117. package/data/harnesses/delivery/skills/documentation/references/frontmatter.md +3 -3
  118. package/data/harnesses/delivery/skills/documentation/references/instruction-style.md +3 -3
  119. package/data/harnesses/delivery/skills/documentation/references/source-comments.md +3 -3
  120. package/data/harnesses/delivery/skills/documentation/references/style-guide.md +5 -5
  121. package/data/harnesses/delivery/skills/documentation/references/untemplated.md +8 -8
  122. package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +3 -2
  123. package/data/harnesses/delivery/skills/documentation/templates/Readme.md +1 -1
  124. package/data/harnesses/delivery/skills/documentation/templates/acceptance-criteria.md +1 -1
  125. package/data/harnesses/delivery/skills/documentation/templates/api-reference.md +1 -1
  126. package/data/harnesses/delivery/skills/documentation/templates/architecture-decision.md +3 -7
  127. package/data/harnesses/delivery/skills/documentation/templates/behavioral-checklist.md +1 -1
  128. package/data/harnesses/delivery/skills/documentation/templates/changelog-entry.md +1 -1
  129. package/data/harnesses/delivery/skills/documentation/templates/changelog-index.md +1 -1
  130. package/data/harnesses/delivery/skills/documentation/templates/docs-readme.md +3 -3
  131. package/data/harnesses/delivery/skills/documentation/templates/doctrine.md +1 -1
  132. package/data/harnesses/delivery/skills/documentation/templates/domain-model.md +1 -1
  133. package/data/harnesses/delivery/skills/documentation/templates/environment-registry.md +1 -1
  134. package/data/harnesses/delivery/skills/documentation/templates/feature.md +3 -3
  135. package/data/harnesses/delivery/skills/documentation/templates/handover.md +2 -2
  136. package/data/harnesses/delivery/skills/documentation/templates/implementation-map.md +1 -1
  137. package/data/harnesses/delivery/skills/documentation/templates/migration-runbook.md +1 -1
  138. package/data/harnesses/delivery/skills/documentation/templates/non-goals.md +1 -1
  139. package/data/harnesses/delivery/skills/documentation/templates/operations-procedure.md +2 -2
  140. package/data/harnesses/delivery/skills/documentation/templates/package.md +1 -1
  141. package/data/harnesses/delivery/skills/documentation/templates/protected-files.md +1 -1
  142. package/data/harnesses/delivery/skills/documentation/templates/root-readme.md +1 -1
  143. package/data/harnesses/delivery/skills/documentation/templates/security-overview.md +1 -1
  144. package/data/harnesses/delivery/skills/documentation/templates/system-overview.md +1 -1
  145. package/data/harnesses/delivery/skills/documentation/templates/system.md +1 -1
  146. package/data/harnesses/delivery/skills/documentation/templates/testing-strategy.md +1 -1
  147. package/data/harnesses/delivery/skills/documentation/templates/ux-behavior.md +3 -5
  148. package/data/harnesses/delivery/skills/escalate/SKILL.md +11 -11
  149. package/data/harnesses/delivery/skills/prompt-eval/SKILL.md +8 -8
  150. package/data/harnesses/delivery/skills/prompt-library/SKILL.md +30 -9
  151. package/data/harnesses/delivery/skills/route/SKILL.md +8 -8
  152. package/data/harnesses/etna/harness.json +2 -2
  153. package/data/harnesses/etna/skills/boundary/SKILL.md +33 -22
  154. package/data/harnesses/etna/skills/boundary/references/index.md +2 -4
  155. package/data/harnesses/etna/skills/boundary/references/mechanisms.md +3 -10
  156. package/data/harnesses/etna/skills/boundary/references/packs/build-config-runtime.md +1 -1
  157. package/data/harnesses/etna/skills/boundary/references/packs/frontend.md +17 -17
  158. package/data/harnesses/etna/skills/boundary/references/packs/generic-tail.md +1 -1
  159. package/data/harnesses/etna/skills/brainstorm/README.md +11 -13
  160. package/data/harnesses/etna/skills/brainstorm/SKILL.md +150 -132
  161. package/data/harnesses/etna/skills/brainstorm/references/doctrine.md +48 -51
  162. package/data/harnesses/etna/skills/brainstorm/references/harvest.md +51 -56
  163. package/data/harnesses/etna/skills/brainstorm/references/session-schema.md +48 -42
  164. package/data/harnesses/etna/skills/documentation/SKILL.md +5 -5
  165. package/data/harnesses/etna/skills/documentation/references/examples.md +22 -22
  166. package/data/harnesses/etna/skills/documentation/references/frontmatter.md +3 -3
  167. package/data/harnesses/etna/skills/documentation/references/instruction-style.md +3 -3
  168. package/data/harnesses/etna/skills/documentation/references/source-comments.md +3 -3
  169. package/data/harnesses/etna/skills/documentation/references/style-guide.md +5 -5
  170. package/data/harnesses/etna/skills/documentation/references/untemplated.md +8 -8
  171. package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +3 -2
  172. package/data/harnesses/etna/skills/documentation/templates/Readme.md +1 -1
  173. package/data/harnesses/etna/skills/documentation/templates/acceptance-criteria.md +1 -1
  174. package/data/harnesses/etna/skills/documentation/templates/api-reference.md +1 -1
  175. package/data/harnesses/etna/skills/documentation/templates/architecture-decision.md +3 -7
  176. package/data/harnesses/etna/skills/documentation/templates/behavioral-checklist.md +1 -1
  177. package/data/harnesses/etna/skills/documentation/templates/changelog-entry.md +1 -1
  178. package/data/harnesses/etna/skills/documentation/templates/changelog-index.md +1 -1
  179. package/data/harnesses/etna/skills/documentation/templates/docs-readme.md +3 -3
  180. package/data/harnesses/etna/skills/documentation/templates/doctrine.md +1 -1
  181. package/data/harnesses/etna/skills/documentation/templates/domain-model.md +1 -1
  182. package/data/harnesses/etna/skills/documentation/templates/environment-registry.md +1 -1
  183. package/data/harnesses/etna/skills/documentation/templates/feature.md +3 -3
  184. package/data/harnesses/etna/skills/documentation/templates/handover.md +2 -2
  185. package/data/harnesses/etna/skills/documentation/templates/implementation-map.md +1 -1
  186. package/data/harnesses/etna/skills/documentation/templates/migration-runbook.md +1 -1
  187. package/data/harnesses/etna/skills/documentation/templates/non-goals.md +1 -1
  188. package/data/harnesses/etna/skills/documentation/templates/operations-procedure.md +2 -2
  189. package/data/harnesses/etna/skills/documentation/templates/package.md +1 -1
  190. package/data/harnesses/etna/skills/documentation/templates/protected-files.md +1 -1
  191. package/data/harnesses/etna/skills/documentation/templates/root-readme.md +1 -1
  192. package/data/harnesses/etna/skills/documentation/templates/security-overview.md +1 -1
  193. package/data/harnesses/etna/skills/documentation/templates/system-overview.md +1 -1
  194. package/data/harnesses/etna/skills/documentation/templates/system.md +1 -1
  195. package/data/harnesses/etna/skills/documentation/templates/testing-strategy.md +1 -1
  196. package/data/harnesses/etna/skills/documentation/templates/ux-behavior.md +3 -5
  197. package/data/harnesses/etna/skills/workflow-mapper/SKILL.md +156 -193
  198. package/data/harnesses/etna/skills/workflow-mapper/references/patterns.md +15 -15
  199. package/data/harnesses/hr/harness.json +2 -2
  200. package/data/harnesses/hr/skills/evaluator/SKILL.md +71 -73
  201. package/data/harnesses/hr/skills/evaluator/criteria/code-quality.md +28 -47
  202. package/data/harnesses/hr/skills/evaluator/criteria/deployment-readiness.md +33 -43
  203. package/data/harnesses/hr/skills/evaluator/criteria/maintainability.md +34 -46
  204. package/data/harnesses/hr/skills/evaluator/criteria/mechanical-ambition.md +13 -13
  205. package/data/harnesses/hr/skills/evaluator/criteria/problem-substantiveness.md +7 -7
  206. package/data/harnesses/hr/skills/evaluator/criteria/testing.md +36 -41
  207. package/data/harnesses/hr/skills/evaluator/criteria/ux-mechanics.md +25 -11
  208. package/data/harnesses/hr/skills/evaluator/criteria/value-articulation.md +7 -7
  209. package/data/harnesses/hr/skills/evaluator/preflight.md +27 -46
  210. package/data/harnesses/hr/skills/interview-eval/SKILL.md +37 -42
  211. package/data/harnesses/hr/skills/interview-eval/rubric.md +21 -23
  212. package/package.json +2 -2
@@ -2,46 +2,107 @@
2
2
 
3
3
  > Generated reference (regen-owned; see [index.md](index.md)). Binds only under `primitives: nurix`.
4
4
 
5
- ## EmptyState
5
+ Components: Alert, Empty, ErrorBoundary, ErrorState, IssueReporter, Loader, NotificationBadge, Progress, Skeleton, SystemBanner, Toaster + toast
6
6
 
7
- Placeholder for empty content areas.
7
+ Each imports from its own subpath; a compound is one namespace with its parts as dotted members, e.g. `import { Empty } from "@nurix/components/compound/empty-state"` then `Empty.Header`, `Empty.Title`. Status colour is always `intent` (`neutral` | `info` | `success` | `warning` | `danger`, on the `--intent-*` tokens); a `danger` notice is `role="alert"`, every other intent `role="status"`, and a `role` you pass wins.
8
8
 
9
- **Props:** `icon`, `title`, `description`, `action`
9
+ ## Empty
10
+
11
+ Placeholder for an empty table body, panel, card or page (`compound/empty-state`).
12
+
13
+ **Sub-components:** `Empty.Header`, `Empty.Media` (`variant` [default|icon]), `Empty.Title`, `Empty.Description`, `Empty.Content`
14
+
15
+ - The root is unframed and fills a flex parent (`flex-1`); add `border` for the dashed frame, and a `min-h-*` or `h-full` inside a block-flow parent.
16
+ - `variant="icon"` draws the muted `size-10` tile, sizes an unsized `svg` to `size-6`, and is `aria-hidden`; the bare default stays exposed so an illustration `img` keeps its `alt`.
17
+ - Every part takes `render`; a root given a `role` is labelled by its Title. A 404 page is this composition — `min-h-[60vh]`, `<Empty.Title render={<h1 />}>`, a way back in `Empty.Content`; there is no `NotFound` export.
18
+ - Not for data in flight (`Skeleton`, `Loader`) or a failed load (`ErrorState`); `block/list` renders its own through its `emptyState` prop.
10
19
 
11
20
  ```tsx
12
- <EmptyState
13
- icon={<InboxIcon className="h-12 w-12 text-muted-foreground" />}
14
- title="No messages"
15
- description="Start a conversation to see messages here"
16
- action={<Button>New Message</Button>}
17
- />
21
+ <Empty className="border">
22
+ <Empty.Header>
23
+ <Empty.Media variant="icon"><Inbox /></Empty.Media>
24
+ <Empty.Title>No messages</Empty.Title>
25
+ <Empty.Description>Start a conversation to see messages here.</Empty.Description>
26
+ </Empty.Header>
27
+ <Empty.Content><Button>New message</Button></Empty.Content>
28
+ </Empty>
18
29
  ```
19
30
 
20
31
  ## Alert
21
32
 
22
- Dismissible status block; `Alert` is the container, `AlertTitle`/`AlertDescription` lay out the icon-led grid.
33
+ Inline notice that stays on the page until the user acts or navigates away (`compound/alert`).
23
34
 
24
- **Props:** `variant` [default|destructive], `dismissible`, `onDismiss`, `dismissButton` (custom node, overrides the default X button)
35
+ **Props:** `intent` [neutral|info|success|warning|danger] (default `neutral`, the card surface), `icon` (replaces the intent's glyph; `null` draws none), `onDismiss`, `labels` (`dismiss`), `render`
36
+ **Sub-components:** `Alert.Title`, `Alert.Description`
37
+
38
+ - Each status intent draws its own glyph; `neutral` draws none. Never place an `<svg>` child for the icon — pass `icon`.
39
+ - `onDismiss` draws the X in its own trailing column and never hides the alert — visibility stays in the parent (`{isVisible && <Alert … />}`).
40
+ - `<Alert.Title render={<h3 />}>` makes the title a real heading. A message that should clear itself is a toast.
25
41
 
26
42
  ```tsx
27
- <Alert variant="destructive" dismissible onDismiss={handleDismiss}>
28
- <TriangleAlert />
29
- <AlertTitle>Sync failed</AlertTitle>
30
- <AlertDescription>Retry in a few minutes.</AlertDescription>
43
+ <Alert intent="danger" onDismiss={() => setIsVisible(false)}>
44
+ <Alert.Title>Sync failed</Alert.Title>
45
+ <Alert.Description>Retry in a few minutes.</Alert.Description>
31
46
  </Alert>
32
47
  ```
33
48
 
34
- ## Other Components
49
+ ## Toaster + toast
50
+
51
+ Self-clearing notifications on Base UI Toast (`compound/toast`): mount `<Toaster />` once at the app root, call `toast()` from anywhere, inside or outside React.
52
+
53
+ **`toast` options:** `title`, `description`, `intent` (the only colour route, draws the glyph), `icon` (`null` draws none), `timeout` (ms; defaults to the dwell token, `Infinity` holds), `priority` [high|low] (default assertive for `danger`, polite otherwise), `action` (`{ label, onClick }`), `onDismiss`, `id` (reusing one updates in place)
54
+ **Methods:** `toast.promise(work, { pending, success, error })` (`error` always takes `danger`; a phase may be a function of the result), `toast.update(id, options)` (changes only the named fields), `toast.close(id?)`
55
+ **Toaster props:** `side` [top|bottom] (default `bottom`), `align` [start|center|end] (default `end`, logical), `hasCloseButton` (default `true`), `labels` (`region`, `dismiss`); parts `Toaster.Root`, `.Content`, `.Title`, `.Description`, `.Action`, `.Close`
56
+
57
+ - There are no `toast.success` / `toast.error` shortcuts — pass `intent`. Never mount a second `Toaster`: every one renders the same queue.
58
+
59
+ ```tsx
60
+ toast({ title: "Saved", description: "Your changes are live.", intent: "success" });
61
+ toast.promise(save(), { pending: "Saving…", success: "Saved", error: "Save failed" });
62
+ ```
63
+
64
+ ## SystemBanner
35
65
 
36
- - `loader` — `Loader`: five-dot pulse indicator; `size`, `gap`, `colors` (array, cycles if fewer than `numberOfDots`), `numberOfDots`, `height`
37
- - `progress` — `Progress`: Radix `Progress.Root`/`Indicator` pair; `value` (0–100)
38
- - `skeleton` — `Skeleton`: pulsing placeholder `div`; size it with `className` to match the final layout
39
- - `typing-indicator` — `TypingIndicator`: `users` (`string[]` or `{ id, name, avatar }[]`), `maxVisible` — stacked avatars plus "X and N others are typing…"
40
- - `error-boundary` — `ErrorBoundary`: class component catching render errors; `fallback`, `onError`, `onRetry` (default UI renders a retry link)
41
- - `not-found` — `NotFound`: built on `EmptyState`; `title`, `description`, `showHomeButton`, `onGoBack`
42
- - `sonner` — `Toaster`: theme-synced wrapper over `sonner`'s `Toaster`, watches `document.documentElement`'s `dark` class via a `MutationObserver`
43
- - `braille` — `Braille`: animated unicode-braille spinner; `spinner` (18 named patterns — `braille`, `braillewave`, `dna`, `scan`, `rain`, `scanline`, `pulse`, `snake`, `sparkle`, `cascade`, `columns`, `orbit`, `breathe`, `waverows`, `checkerboard`, `helix`, `fillsweep`, `diagswipe`), `interval` (ms, overrides the spinner's default), `label` (screen-reader text). The `inline-spinner` subpath exports the underlying frame registry and grid utilities: `spinners`, `gridToBraille`, `makeGrid`.
66
+ Shell-chrome banner above the app for environment, impersonation or outage states (`element/system-banner`); also exports `systemBannerVariants`.
67
+
68
+ **Props:** `title` (required), `description`, `intent` [neutral|info|success|warning|danger] (default `neutral`), `icon`, `action`, `onDismiss`, `labels` (`dismiss`, `actions`)
69
+ **Sub-components:** `SystemBanner.Stack` (orders and divides banners; placing it is yours)
70
+
71
+ - The banner stores no visibility: `onDismiss` renders the dismiss button and your callback unmounts it; omit it for a banner that must not be dismissed.
72
+ - `description` wraps on a narrow viewport. A message in content flow is `Alert`.
44
73
 
45
74
  ```tsx
46
- <Braille spinner="dna" label="Loading" />
75
+ <SystemBanner.Stack>
76
+ <SystemBanner intent="warning" title="Sandbox environment" description="Data resets nightly" />
77
+ <SystemBanner title="Viewing as Dana" action={<Button size="sm">Exit view-as</Button>} />
78
+ </SystemBanner.Stack>
47
79
  ```
80
+
81
+ ## IssueReporter
82
+
83
+ Report-a-problem dialog with screenshot capture and an environment snapshot (`block/issue-reporter`). Requires the optional peer `html2canvas-pro` — without it the DOM raster fails on every capture and each one falls back to a `getDisplayMedia` permission prompt.
84
+
85
+ **Props:** `onSubmit(report)` (required; a rejection keeps the dialog open, a resolution closes and resets), `open` / `defaultOpen` / `onOpenChange`, `shortcut` (e.g. `"mod+shift+i"`; default `null`), `shouldCaptureOnOpen` (default `true`), `fields` (default one `textarea` named `text`; types text|textarea|number|select|radio|checkbox), `defaultValue`, `metadata` (value or function, resolved at submit), `maxScreenshots` (default 3), `diagnosticsSections` (default all; `[]` turns collection off), `renderDiagnostics`, `captureOptions` (`ignoreElement`, `maxWidth`, `imageType`…), `onCaptureError`, `labels`
86
+ **Also exports:** `useScreenCapture(options)` → `[state, actions]`, `useDiagnostics({ sections, collectOnMount })` → `{ data, isLoading, error, refresh }`, `DIAGNOSTICS_SECTIONS` (`system`, `capabilities`, `webVitals`, `storage`, `serviceWorkers`), `CaptureError`
87
+
88
+ - `IssueReport` carries `fields`, `screenshots`, `diagnostics`, `metadata`. Submit stays disabled until every `required` field is set **and** a field holds a value or a screenshot is attached.
89
+ - A report needing no screenshot or diagnostics is a plain form over `compound/dialog`, not this.
90
+
91
+ ```tsx
92
+ <IssueReporter
93
+ shortcut="mod+shift+i"
94
+ fields={[{ name: "text", type: "textarea", label: "What went wrong?", required: true }]}
95
+ metadata={() => ({ route: location.pathname })}
96
+ onSubmit={async (report) => sendToTracker(report)}
97
+ />
98
+ ```
99
+
100
+ ## Other Components
101
+
102
+ - `loader` — `Loader` (`element/loader`): em-sized lattice in `currentColor` for open-ended work; `status` [pending|success|error] (default `pending`) settles the same glyph into a check or a cross, `label`, `successLabel`, `errorLabel`, `hasTimer`, `labels`. A "Thinking…" or typing row is `<Loader label="Typing" />` — there is no dots variant.
103
+ - `progress` — `Progress` (`element/progress`): `value` (0–100, clamped; `null` is indeterminate), `label` (the accessible name), `variant` [linear|circular|fill] (default `linear`), `size` [sm|default|lg] (not on `fill`), `format` / `getAriaValueText` to reword the announcement.
104
+ - `skeleton` — `Skeleton` (`element/skeleton`): pulsing `aria-hidden` `div` with no intrinsic size — size it with `className`, mark the container `aria-busy`, and pass `render={<span />}` inside phrasing content.
105
+ - `notification-badge` — `NotificationBadge` (`element/notification-badge`): `value` (pass the real count; renders nothing at zero), `max` (default 99, shows `99+`), `variant` [count|dot], `intent`, `labels` (`dot`); em-sized from the text beside it, positioned by you on a `relative` trigger.
106
+ - `error-state` — `ErrorState` (`compound/error-state`): failed-load block on Empty's geometry; `description` (required), `title`, `icon`, `onRetry` (renders Retry), `labels` (`retry`). Carries no live role; `block/list`, `block/table` and `block/tree` take `error={{ message, onRetry }}` instead.
107
+ - `error-boundary` — `ErrorBoundary` (`lib/error-boundary`): catches render errors in the subtree it wraps; `onError` (its only way out — it logs nothing), `onRetry` (refetch here, or the subtree throws again), `fallback` (replaces the whole card, retry included).
108
+ - No nurix primitive: `text-spinner` — build from the `index.md` fallback spec.
@@ -2,34 +2,220 @@
2
2
 
3
3
  > Generated reference (regen-owned; see [index.md](index.md)). Binds only under `primitives: nurix`.
4
4
 
5
- Standalone React hooks, each imported from its own subpath under `@nurix/components/`.
5
+ Standalone React hooks, each imported from its own `hooks/*` subpath under `@nurix/components/`, plus the Uppy upload adapter at `lib/uppy-adapter`. Every Base UI-backed surface already owns its dismissal, Escape and roving focus — never double-wire a hook onto one.
6
6
 
7
7
  ## useClickOutside
8
8
 
9
- `useClickOutside(ref, callback)` — invokes `callback` on `mousedown`/`touchstart` outside the referenced element.
9
+ `useClickOutside(ref, callback)` (from `hooks/use-click-outside`) — fires `callback` on a `document` `mousedown`/`touchstart` outside `ref.current`. Only for a bespoke floating surface with no dismissal of its own.
10
+
11
+ - Wrap the trigger and the panel in the same ref when the trigger toggles — `mousedown` runs before the trigger's `click`, so an unwrapped trigger closes and reopens the surface.
12
+ - No `enabled` option: listeners live for the component's life, so unmount the surface on close or gate inside the callback. A portalled child reads as an outside press.
13
+
14
+ ```tsx
15
+ const panelRef = useRef<HTMLDivElement>(null);
16
+ useClickOutside(panelRef, () => setOpen(false));
17
+ ```
18
+
19
+ ## useControllableState
20
+
21
+ `useControllableState({ prop, defaultProp, onChange })` (from `hooks/use-controllable-state`) — returns `[value, setValue]`, collapsing controlled and uncontrolled into one code path.
22
+
23
+ - Presence decides the mode: `prop: undefined` is uncontrolled. `onChange(value)` fires only when the value changes (`Object.is`) and takes the value alone — a Base UI `onOpenChange(open, eventDetails)` keeps its own wiring.
24
+ - `defaultProp` is read once at mount; hoist an array or object default to a module constant.
25
+
26
+ ```tsx
27
+ const [value, setValue] = useControllableState({ prop: valueProp, defaultProp: defaultValue ?? "", onChange: onValueChange });
28
+ ```
29
+
30
+ ## useDebounce
31
+
32
+ `useDebounce(value, delayMs)` (from `hooks/use-debounce`) — returns the value, settled `delayMs` after it stops changing. First render returns it as-is; a pending update drops on unmount.
33
+
34
+ - Debounce the state, not the handler: keep the input controlled and immediate, point the expensive effect at the debounced value. A one-shot delayed action is `useTimeout`.
35
+
36
+ ```tsx
37
+ const debouncedQuery = useDebounce(query, 300);
38
+ ```
39
+
40
+ ## useEventListener
41
+
42
+ `useEventListener(eventName, handler, target?, options?)` (from `hooks/use-event-listener`) — `target` defaults to `window`; accepts `document`, a node, a ref, or `null` (subscribes nothing).
43
+
44
+ - The handler is read at fire time, so an inline closure never re-subscribes; `options` is captured at subscribe time. A target that mounts later must be passed as the element via state — a ref's `.current` changing re-renders nothing.
45
+
46
+ ```tsx
47
+ useEventListener("mousemove", (event) => setPointer({ x: event.clientX, y: event.clientY }), panelRef);
48
+ ```
49
+
50
+ ## useFilter
51
+
52
+ `useFilter(options?)` (from `hooks/use-filter`) — returns `{ contains, startsWith, endsWith }`, each `(value, query) => boolean`, locale-aware via `Intl.Collator`. Options: `locale`, any `Intl.CollatorOptions`, `gapMatch` (default `false`).
53
+
54
+ - An empty query matches everything. `gapMatch: true` strips separators so "jsmith" matches "J. Smith", and skips the collator's accent folding. `compound/command` filters its own items — a palette needs no matcher.
55
+
56
+ ```tsx
57
+ const { contains } = useFilter({ sensitivity: "base" });
58
+ const visible = items.filter((item) => contains(item.label, query));
59
+ ```
60
+
61
+ ## useFreshness
62
+
63
+ `useFreshness({ fetchedAt?, onRefresh, staleAfterMs?, tickMs? })` (from `hooks/use-freshness`) — returns `{ refresh, isRefreshing, isStale }` for a refresh control.
64
+
65
+ - `isRefreshing` follows a returned promise (a synchronous `onRefresh` never sets it); a click mid-refresh returns the in-flight promise, no queue. `isStale` needs both `fetchedAt` and `staleAfterMs`, else no clock runs.
66
+
67
+ ```tsx
68
+ const { refresh, isRefreshing } = useFreshness({ fetchedAt, onRefresh: refetch, staleAfterMs: 5 * 60_000 });
69
+ <Button onClick={refresh} disabled={isRefreshing}>Updated <Timestamp value={fetchedAt} relativeThreshold={Infinity} /></Button>
70
+ ```
71
+
72
+ ## useIntersectionObserver
73
+
74
+ `useIntersectionObserver<T>(options?)` (from `hooks/use-intersection-observer`) — returns `[callbackRef, entry]`; options (`root`, `rootMargin`, `threshold`) pass through, and instances with the same root and options share one observer.
75
+
76
+ - `entry` is `null` until the first observation and is not cleared on unmount. For paging a stream use `block/list`'s `onLoadMore` + `hasMore` — it owns the sentinel and its re-entry guard.
77
+
78
+ ```tsx
79
+ const [sentinelRef, entry] = useIntersectionObserver<HTMLDivElement>();
80
+ const isAtTop = entry?.isIntersecting ?? false;
81
+ ```
82
+
83
+ ## useInterval
84
+
85
+ `useInterval(callback, delayMs | null)` (from `hooks/use-interval`) — `null` pauses; changing the delay restarts the cadence; the callback is read at tick time.
86
+
87
+ - Stop by state, not `clearInterval`. Ticks are not a clock (background tabs throttle) — read `Date.now()` per tick for elapsed time.
10
88
 
11
89
  ```tsx
12
- const ref = useRef<HTMLDivElement>(null);
13
- useClickOutside(ref, () => setOpen(false));
90
+ useInterval(tick, isDone ? null : speedMs);
14
91
  ```
15
92
 
16
- ## useFileUpload
93
+ ## useKeyPress
17
94
 
18
- `useFileUpload(options?)` — returns `[state, actions]`.
95
+ `useKeyPress(key, callback, { event?, target? })` (from `hooks/use-key-press`) — matches `event.key` (case-sensitive); `event` is `"keydown"` (default) or `"keyup"`, `target` defaults to `window`.
19
96
 
20
- **Options:** `maxFiles` (multi mode only, default Infinity), `maxSize` (bytes), `accept`, `multiple`, `initialFiles`, `onFilesChange`, `onFilesAdded`
97
+ - A window listener hears keys typed into inputs — require a modifier or check `event.target`. Base UI popups own their Escape.
98
+
99
+ ```tsx
100
+ useKeyPress("b", (event) => { if (event.metaKey || event.ctrlKey) { event.preventDefault(); toggleSidebar(); } });
101
+ ```
21
102
 
22
- **State:** `{ files: FileWithPreview[], isDragging, errors }` **Actions:** `addFiles`, `removeFile`, `clearFiles`, `clearErrors`, `handleDragEnter/Leave/Over/Drop`, `handleFileChange`, `openFileDialog`, `getInputProps()`. Also exports `formatBytes`.
103
+ ## useMeasure
104
+
105
+ `useMeasure<T>()` (from `hooks/use-measure`) — returns `[callbackRef, { width, height }]`, `contentRect` sizes, `{ 0, 0 }` until the first observation.
106
+
107
+ - Reports size only — animating a height change is `useSmoothResize`. Keep your own ref with `useComposedRefs(myRef, measureRef)` from `lib/compose-refs`.
23
108
 
24
109
  ```tsx
25
- const [state, actions] = useFileUpload({ multiple: true, maxFiles: 5 });
26
- <div {...actions.getInputProps()} onDrop={actions.handleDrop} />
110
+ const [measureRef, { width }] = useMeasure<HTMLDivElement>();
27
111
  ```
28
112
 
29
113
  ## useMediaQuery
30
114
 
31
- `useMediaQuery(query)` — reactive boolean for a CSS media query string, updates on `matchMedia` change events.
115
+ `useMediaQuery(query)` (from `hooks/use-media-query`) — reactive boolean; the first client render reports the real match; callers of the same query share one `MediaQueryList`.
116
+
117
+ - Only when the answer changes behaviour — anything visual is a Tailwind breakpoint or container query. The server snapshot is `false`. Pass the full query: a bare `768` becomes the invalid `"768"` and reads `false` forever.
118
+
119
+ ```tsx
120
+ const isCoarsePointer = useMediaQuery("(hover: none)");
121
+ ```
32
122
 
33
123
  ## useIsMobile
34
124
 
35
- `useIsMobile()` (from `hooks/use-mobile`) — reactive boolean, true below the 768px breakpoint.
125
+ `useIsMobile(breakpoint = 768)` (from `hooks/use-mobile`) — true below `breakpoint`, the first non-mobile width (`useIsMobile(768)` asks `(max-width: 767px)`).
126
+
127
+ - Behaviour only (`block/sidebar` swaps its rail for a sheet on it); the server snapshot is `false`. One listener per call — lift it to one owner instead of calling it per row.
128
+
129
+ ```tsx
130
+ const isMobile = useIsMobile();
131
+ ```
132
+
133
+ ## useOverflowCount
134
+
135
+ `useOverflowCount<T>(itemCount, { reserve? })` (from `hooks/use-overflow-count`) — returns `{ containerRef, visibleCount, overflowCount }` for a "+N more" row fitted to rendered widths; `reserve` (px, default `0`) keeps room for the indicator.
136
+
137
+ - The row is `overflow: hidden` and non-wrapping; every item stays mounted, hidden past `visibleCount` with the `hidden` attribute; the indicator comes after the items. A fixed "first three" truncation is a slice, not this hook.
138
+
139
+ ```tsx
140
+ const { containerRef, visibleCount, overflowCount } = useOverflowCount<HTMLDivElement>(tags.length, { reserve: 48 });
141
+ ```
142
+
143
+ ## useRangeSelect
144
+
145
+ `useRangeSelect(orderedIds, selectedIds)` (from `hooks/use-range-select`) — returns `{ select, reset }`; `select(id, event)` returns the next selection array.
146
+
147
+ - A plain click toggles and sets the anchor; shift-click selects anchor-to-click, and the anchor's direction wins. `orderedIds` is display order; call `reset()` when the list identity changes. `block/list` already wires it.
148
+
149
+ ```tsx
150
+ const { select } = useRangeSelect(rows.map((row) => row.id), selectedIds);
151
+ <Row onClick={(event) => setSelectedIds(select(row.id, event))} />
152
+ ```
153
+
154
+ ## useRovingFocus
155
+
156
+ `useRovingFocus<T>({ orientation?, loop?, dir?, itemSelector?, enabled? })` (from `hooks/use-roving-focus`) — returns a callback ref for the group; defaults `orientation: "horizontal"`, `loop: true`, `dir: "ltr"`, `enabled: true`.
157
+
158
+ - Keeps one reachable item (the active one, else the first enabled); Home/End jump; disabled items skip. Focus moves, selection does not.
159
+
160
+ ```tsx
161
+ const rovingRef = useRovingFocus<HTMLDivElement>();
162
+ <div role="tablist" ref={rovingRef}>{tabs}</div>
163
+ ```
164
+
165
+ ## useScrollOverflow
166
+
167
+ `useScrollOverflow<T>({ orientation?, threshold? })` (from `hooks/use-scroll-overflow`) — returns a callback ref that writes `data-overflow-y-start`/`-end` (or `-x-` for `orientation: "horizontal"`, RTL-aware) straight to the DOM, so scrolling never re-renders; `threshold` defaults to `1`px.
168
+
169
+ - Style the fade off the attribute (`[data-overflow-y-start]:before { … }`). Only for a bare scroll container — `element/scroll-area`'s `hasFadeEdges` already reads the same attributes.
170
+
171
+ ```tsx
172
+ const scrollRef = useScrollOverflow<HTMLDivElement>();
173
+ <div ref={scrollRef} className="overflow-y-auto">{rows}</div>
174
+ ```
175
+
176
+ ## useSearchSource · createStaticSource
177
+
178
+ `useSearchSource(source, query)` (from `hooks/use-search-source`) — returns `{ items, status, error?, isBootstrap }` (`status`: `idle | loading | ready | error`). A source is `{ search(query), bootstrap?, debounceMs? }`; `createStaticSource(items, { filter?, bootstrap? })` wraps an in-memory list in the same shape.
179
+
180
+ - Only the newest request writes; a synchronous source never flashes `loading`. An empty query shows `bootstrap()` with `isBootstrap: true`, or nothing without one.
181
+
182
+ ```tsx
183
+ const search = useSearchSource(source, query);
184
+ <Command searchValue={query} onSearchValueChange={setQuery} loading={search.status === "loading"} filter={null}>
185
+ <Command.Results data={search.items} renderItem={(item) => <Command.Item value={item.value}>{item.label}</Command.Item>} />
186
+ </Command>
187
+ ```
188
+
189
+ ## useSmoothResize
190
+
191
+ `useSmoothResize<T>(enabled = true)` (from `hooks/use-smooth-resize`) — returns a callback ref that animates the element's real `height` (slow motion step × 1.2 on `--motion-ease-travel`), so content below reflows with it.
192
+
193
+ - First paint never animates; reduced motion and the still pace turn it off. For a page region prefer `<Block shouldSettle>`; settle the outermost region only. Plural or continuous motion wants a transform technique instead.
194
+
195
+ ```tsx
196
+ const settleRef = useSmoothResize<HTMLDivElement>();
197
+ <div ref={settleRef}>{isExpanded ? <Details /> : <Summary />}</div>
198
+ ```
199
+
200
+ ## useTimeout
201
+
202
+ `useTimeout(callback, delayMs | null)` (from `hooks/use-timeout`) — arms when the delay is a number, `null` disarms; changing the delay restarts; unmount cleans up.
203
+
204
+ - Replaces a bare `setTimeout` resetting a transient flag. A second trigger while armed keeps the first deadline — flip through `null` to restart.
205
+
206
+ ```tsx
207
+ useTimeout(() => setIsCopied(false), isCopied ? 2000 : null);
208
+ ```
209
+
210
+ ## useUppyState · createUppyUploadHandler
211
+
212
+ `createUppyUploadHandler(uppy)` and `useUppyState(uppy, selector)` (from `lib/uppy-adapter`) — bind a caller-owned `@uppy/core` instance to `compound/file-picker`'s `onUpload`. `@uppy/core` is an optional peer (the `file-picker` family); a picker that stages locally or uploads with plain `fetch` passes its own `onUpload` and skips this.
213
+
214
+ - The instance and its transport plugins are the caller's; the library ships no network code. A rejected `upload()` fails every file in the batch; progress needs a numeric `percentage` in Uppy's `upload-progress`.
215
+ - `useUppyState` is a `useSyncExternalStore` read — a selector that derives a new object must be module-scope or `useCallback`'d, or React loops.
216
+
217
+ ```tsx
218
+ const uppy = useMemo(() => new Uppy().use(AwsS3, { endpoint: "/api/s3" }), []);
219
+ const upload = useMemo(() => createUppyUploadHandler(uppy), [uppy]);
220
+ <FilePicker value={files} onValueChange={setFiles} onUpload={upload}>…</FilePicker>
221
+ ```