@deadragdoll/reactnu 0.1.9

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 (176) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -0
  3. package/dist/appHost/NuAppHostProvider.d.ts +6 -0
  4. package/dist/appHost/appHostContext.d.ts +26 -0
  5. package/dist/components/Button/Button.d.ts +13 -0
  6. package/dist/components/Button/index.d.ts +1 -0
  7. package/dist/components/CheckBox/CheckBox.d.ts +14 -0
  8. package/dist/components/CheckBox/index.d.ts +1 -0
  9. package/dist/components/ComboBox/ComboBox.d.ts +23 -0
  10. package/dist/components/ComboBox/index.d.ts +1 -0
  11. package/dist/components/CommandButton/CommandButton.d.ts +17 -0
  12. package/dist/components/CommandButton/index.d.ts +1 -0
  13. package/dist/components/CrtGlitch/CrtGlitch.d.ts +23 -0
  14. package/dist/components/CrtGlitch/index.d.ts +1 -0
  15. package/dist/components/Dashboard/Dashboard.d.ts +25 -0
  16. package/dist/components/Dashboard/index.d.ts +1 -0
  17. package/dist/components/Desktop/Desktop.d.ts +6 -0
  18. package/dist/components/Desktop/index.d.ts +1 -0
  19. package/dist/components/Dropdown/Dropdown.d.ts +19 -0
  20. package/dist/components/Dropdown/index.d.ts +1 -0
  21. package/dist/components/Frame/Frame.d.ts +24 -0
  22. package/dist/components/Frame/index.d.ts +1 -0
  23. package/dist/components/Glyph/NuGlyph.d.ts +6 -0
  24. package/dist/components/Glyph/index.d.ts +1 -0
  25. package/dist/components/Info/Info.d.ts +13 -0
  26. package/dist/components/Info/index.d.ts +1 -0
  27. package/dist/components/ListBox/ListBox.d.ts +23 -0
  28. package/dist/components/ListBox/index.d.ts +1 -0
  29. package/dist/components/ListBox/internals/ListBoxCategoryView.d.ts +6 -0
  30. package/dist/components/ListBox/internals/ListBoxCheckControl.d.ts +8 -0
  31. package/dist/components/ListBox/internals/ListBoxGroupView.d.ts +17 -0
  32. package/dist/components/ListBox/internals/ListBoxItemView.d.ts +18 -0
  33. package/dist/components/ListBox/internals/helpers.d.ts +5 -0
  34. package/dist/components/ListBox/internals/renderLabel.d.ts +2 -0
  35. package/dist/components/ListBox/internals/types.d.ts +27 -0
  36. package/dist/components/ListView/ListView.d.ts +27 -0
  37. package/dist/components/ListView/index.d.ts +1 -0
  38. package/dist/components/ListView/internals/ListViewCheckControl.d.ts +8 -0
  39. package/dist/components/ListView/internals/ListViewRow.d.ts +18 -0
  40. package/dist/components/ListView/internals/helpers.d.ts +5 -0
  41. package/dist/components/ListView/internals/types.d.ts +17 -0
  42. package/dist/components/MainMenu/MainMenu.d.ts +8 -0
  43. package/dist/components/MainMenu/MainMenu.types.d.ts +23 -0
  44. package/dist/components/MainMenu/index.d.ts +3 -0
  45. package/dist/components/MainMenu/internals/MainMenuList.d.ts +12 -0
  46. package/dist/components/MainMenu/menuState.d.ts +40 -0
  47. package/dist/components/MaskedField/MaskedField.d.ts +13 -0
  48. package/dist/components/MaskedField/index.d.ts +2 -0
  49. package/dist/components/MaskedField/textMask.d.ts +8 -0
  50. package/dist/components/Memo/Memo.d.ts +14 -0
  51. package/dist/components/Memo/index.d.ts +1 -0
  52. package/dist/components/PageControl/PageControl.d.ts +20 -0
  53. package/dist/components/PageControl/index.d.ts +1 -0
  54. package/dist/components/Panel/Panel.d.ts +11 -0
  55. package/dist/components/Panel/index.d.ts +1 -0
  56. package/dist/components/PopupMenu/PopupMenu.d.ts +22 -0
  57. package/dist/components/PopupMenu/index.d.ts +2 -0
  58. package/dist/components/PopupMenu/usePopupMenu.d.ts +12 -0
  59. package/dist/components/ProgressBar/ProgressBar.d.ts +17 -0
  60. package/dist/components/ProgressBar/index.d.ts +1 -0
  61. package/dist/components/PropertyGrid/PropertyGrid.d.ts +38 -0
  62. package/dist/components/PropertyGrid/index.d.ts +1 -0
  63. package/dist/components/RadioGroup/RadioButton.d.ts +9 -0
  64. package/dist/components/RadioGroup/RadioGroup.d.ts +21 -0
  65. package/dist/components/RadioGroup/index.d.ts +2 -0
  66. package/dist/components/ReportCell/ReportCell.d.ts +6 -0
  67. package/dist/components/ReportCell/index.d.ts +1 -0
  68. package/dist/components/SearchBox/SearchBox.d.ts +23 -0
  69. package/dist/components/SearchBox/index.d.ts +1 -0
  70. package/dist/components/SpinBox/SpinBox.d.ts +16 -0
  71. package/dist/components/SpinBox/index.d.ts +1 -0
  72. package/dist/components/Splitter/Splitter.d.ts +15 -0
  73. package/dist/components/Splitter/index.d.ts +1 -0
  74. package/dist/components/Stack/Stack.d.ts +13 -0
  75. package/dist/components/Stack/index.d.ts +1 -0
  76. package/dist/components/TextField/TextField.d.ts +12 -0
  77. package/dist/components/TextField/index.d.ts +1 -0
  78. package/dist/components/TickBar/TickBar.d.ts +22 -0
  79. package/dist/components/TickBar/index.d.ts +1 -0
  80. package/dist/components/ToolBar/ToolBar.d.ts +25 -0
  81. package/dist/components/ToolBar/index.d.ts +1 -0
  82. package/dist/components/TreeListView/TreeListView.d.ts +33 -0
  83. package/dist/components/TreeListView/index.d.ts +1 -0
  84. package/dist/components/TreeListView/internals/TreeListViewRow.d.ts +28 -0
  85. package/dist/components/TreeListView/internals/helpers.d.ts +14 -0
  86. package/dist/components/TreeListView/internals/types.d.ts +32 -0
  87. package/dist/components/TreeView/TreeView.d.ts +26 -0
  88. package/dist/components/TreeView/index.d.ts +1 -0
  89. package/dist/components/TreeView/internals/TreeViewItem.d.ts +21 -0
  90. package/dist/components/TreeView/internals/helpers.d.ts +5 -0
  91. package/dist/components/TreeView/internals/types.d.ts +10 -0
  92. package/dist/components/View/NuView.d.ts +10 -0
  93. package/dist/components/View/index.d.ts +1 -0
  94. package/dist/components/Window/StatusBarItem.d.ts +7 -0
  95. package/dist/components/Window/Window.d.ts +41 -0
  96. package/dist/components/Window/WindowTitleButton.d.ts +17 -0
  97. package/dist/components/Window/index.d.ts +5 -0
  98. package/dist/components/Window/internals/WindowStatusBar.d.ts +8 -0
  99. package/dist/components/Window/internals/WindowTitleBar.d.ts +10 -0
  100. package/dist/components/Window/useWindowTitleButtons.d.ts +12 -0
  101. package/dist/components/Window/windowMenuContext.d.ts +3 -0
  102. package/dist/components/_shared/ControlOpener.d.ts +18 -0
  103. package/dist/components/_shared/portalPositioning.d.ts +16 -0
  104. package/dist/components/_shared/slotProps.d.ts +867 -0
  105. package/dist/components/_shared/themePortal.d.ts +2 -0
  106. package/dist/components/_shared/treeData.d.ts +19 -0
  107. package/dist/components/_shared/usePopupPosition.d.ts +40 -0
  108. package/dist/index.cjs +9848 -0
  109. package/dist/index.d.ts +45 -0
  110. package/dist/index.js +9885 -0
  111. package/dist/styles.css +3644 -0
  112. package/dist/theme/NuThemeProvider.d.ts +26 -0
  113. package/dist/theme/themeContext.d.ts +15 -0
  114. package/dist/theme/themes.d.ts +49 -0
  115. package/dist/utils/renderMnemonicText.d.ts +10 -0
  116. package/dist/windowing/AppBarHost.d.ts +6 -0
  117. package/dist/windowing/AppBarItem.d.ts +587 -0
  118. package/dist/windowing/NuWindowProvider.d.ts +9 -0
  119. package/dist/windowing/WindowBar.d.ts +13 -0
  120. package/dist/windowing/dialogHelpers.d.ts +1793 -0
  121. package/dist/windowing/internals/MdiWindowPickerDialog.d.ts +10 -0
  122. package/dist/windowing/mdiMenu.d.ts +3 -0
  123. package/dist/windowing/windowContext.d.ts +18 -0
  124. package/dist/windowing/windowing.constants.d.ts +1 -0
  125. package/dist/windowing/windowing.types.d.ts +54 -0
  126. package/docs/API_REFERENCE.md +150 -0
  127. package/docs/ARCHITECTURE.md +170 -0
  128. package/docs/AppBarHost.md +22 -0
  129. package/docs/AppBarItem.md +22 -0
  130. package/docs/Button.md +24 -0
  131. package/docs/COMPONENT_INDEX.md +64 -0
  132. package/docs/CONTRIBUTOR_GUIDE.md +393 -0
  133. package/docs/CheckBox.md +30 -0
  134. package/docs/ComboBox.md +41 -0
  135. package/docs/CommandButton.md +45 -0
  136. package/docs/CrtGlitch.md +49 -0
  137. package/docs/Dashboard.md +73 -0
  138. package/docs/Desktop.md +27 -0
  139. package/docs/DialogHelpers.md +85 -0
  140. package/docs/Dropdown.md +44 -0
  141. package/docs/Frame.md +38 -0
  142. package/docs/GETTING_STARTED.md +110 -0
  143. package/docs/Glyph.md +29 -0
  144. package/docs/Info.md +51 -0
  145. package/docs/ListBox.md +35 -0
  146. package/docs/ListView.md +62 -0
  147. package/docs/MainMenu.md +36 -0
  148. package/docs/MaskedField.md +124 -0
  149. package/docs/Memo.md +32 -0
  150. package/docs/NuAppHostProvider.md +28 -0
  151. package/docs/NuThemeProvider.md +64 -0
  152. package/docs/NuView.md +58 -0
  153. package/docs/NuWindowProvider.md +81 -0
  154. package/docs/PageControl.md +28 -0
  155. package/docs/Panel.md +23 -0
  156. package/docs/PopupMenu.md +42 -0
  157. package/docs/ProgressBar.md +33 -0
  158. package/docs/PropertyGrid.md +63 -0
  159. package/docs/RadioGroup.md +36 -0
  160. package/docs/ReportCell.md +27 -0
  161. package/docs/SLOT_CUSTOMIZATION.md +85 -0
  162. package/docs/STORYBOOK.md +96 -0
  163. package/docs/SearchBox.md +41 -0
  164. package/docs/SpinBox.md +25 -0
  165. package/docs/Splitter.md +91 -0
  166. package/docs/Stack.md +26 -0
  167. package/docs/StatusBarItem.md +31 -0
  168. package/docs/TOKEN_CHECKLIST.md +122 -0
  169. package/docs/TextField.md +27 -0
  170. package/docs/TickBar.md +57 -0
  171. package/docs/ToolBar.md +51 -0
  172. package/docs/TreeListView.md +84 -0
  173. package/docs/TreeView.md +53 -0
  174. package/docs/Window.md +53 -0
  175. package/docs/WindowBar.md +24 -0
  176. package/package.json +47 -0
@@ -0,0 +1,393 @@
1
+ # Contributor Guide
2
+
3
+ This guide is for developers and coding agents who need to extend ReactNU or integrate it into a host application without reverse-engineering the source tree first.
4
+
5
+ It is intentionally practical.
6
+
7
+ ## What ReactNU Is
8
+
9
+ ReactNU is a React + TypeScript component library with a Norton Utilities / DOS-era visual language.
10
+
11
+ The target qualities are:
12
+
13
+ - crisp geometry
14
+ - dense information layout
15
+ - keyboard-first interaction
16
+ - strong visual hierarchy
17
+ - predictable controlled/uncontrolled behavior
18
+ - reusable host shell composition
19
+
20
+ ReactNU is not a novelty retro skin. It is a reusable UI system that happens to use a DOS-style visual grammar.
21
+
22
+ ## Recommended Mental Model
23
+
24
+ Think in layers:
25
+
26
+ 1. Theme and desktop tokens
27
+ 2. Low-level controls
28
+ 3. Composed surfaces
29
+ 4. Window and dialog orchestration
30
+ 5. Host application composition
31
+
32
+ That means:
33
+
34
+ - a control should not guess desktop ownership
35
+ - a dialog should not guess app-shell structure
36
+ - popup geometry should not guess multiple coordinate systems
37
+ - the host should explicitly own workflow composition
38
+
39
+ ## First Files To Read
40
+
41
+ If you are new to the repo, read in this order:
42
+
43
+ 1. [Getting Started](./GETTING_STARTED.md)
44
+ 2. [Architecture](./ARCHITECTURE.md)
45
+ 3. [API Reference](./API_REFERENCE.md)
46
+ 4. [Slot Customization](./SLOT_CUSTOMIZATION.md)
47
+ 5. [Storybook](./STORYBOOK.md)
48
+
49
+ If you are working on windowing or popup behavior, also read:
50
+
51
+ 6. [NuWindowProvider](./NuWindowProvider.md)
52
+ 7. [Dialog Helpers](./DialogHelpers.md)
53
+ 8. [Desktop](./Desktop.md)
54
+
55
+ ## Host Composition Patterns
56
+
57
+ ### Full Desktop Shell
58
+
59
+ Use this when you want:
60
+
61
+ - main menu
62
+ - workspace area
63
+ - app bar
64
+ - managed windows
65
+ - desktop-level modal behavior
66
+
67
+ Recommended ownership:
68
+
69
+ `NuThemeProvider -> NuDesktop -> workspace content -> managed windows`
70
+
71
+ Typical example:
72
+
73
+ ```tsx
74
+ <NuThemeProvider>
75
+ <NuDesktop appBar={<ShellAppBar />}>
76
+ <Dashboard items={...} />
77
+ </NuDesktop>
78
+ </NuThemeProvider>
79
+ ```
80
+
81
+ ### Bounded Window Host
82
+
83
+ Use this when you need:
84
+
85
+ - managed dialogs or windows
86
+ - modal layering
87
+ - `useNuWindowManager()`
88
+ - but not the full desktop shell
89
+
90
+ This is especially useful for:
91
+
92
+ - Storybook stories
93
+ - focused demo surfaces
94
+ - embedded host panels
95
+
96
+ Typical example:
97
+
98
+ ```tsx
99
+ <div style={{ position: "relative", height: "40rem", overflow: "hidden" }}>
100
+ <NuWindowProvider renderAppBar={false}>
101
+ <DialogLauncherSurface />
102
+ </NuWindowProvider>
103
+ </div>
104
+ ```
105
+
106
+ ### Do Not Mix These Accidentally
107
+
108
+ Common mistake:
109
+
110
+ - using `NuDesktop` when a bounded `NuWindowProvider` is enough
111
+
112
+ Symptoms:
113
+
114
+ - content appears to escape the preview region
115
+ - dialogs reposition the whole preview unexpectedly
116
+ - fullscreen/fixed desktop semantics leak into Storybook
117
+
118
+ ## Theme Ownership
119
+
120
+ Theme state belongs to `NuThemeProvider`.
121
+
122
+ Current provider-level host settings include:
123
+
124
+ - theme
125
+ - font family
126
+ - font size
127
+ - desktop pattern mode
128
+
129
+ Prefer changing typography and desktop surface through the provider, not through ad-hoc DOM overrides.
130
+
131
+ ## Popup And Menu Contract
132
+
133
+ Popup-like controls currently follow this contract:
134
+
135
+ - popup renders into `document.body`
136
+ - popup position is measured from `getBoundingClientRect()`
137
+ - popup receives theme vars from the nearest `.nu-theme-root`
138
+
139
+ Why:
140
+
141
+ - viewport coordinates stay stable
142
+ - Storybook and sandbox use the same geometry model
143
+ - popup visuals still inherit theme and typography
144
+
145
+ If a popup appears correct in sandbox but not in Storybook, first suspect host composition or portal assumptions, not the control API.
146
+
147
+ ## Shared Internal Primitive Rule
148
+
149
+ When two controls share the same visual part, do not duplicate the implementation casually.
150
+
151
+ Preferred order:
152
+
153
+ 1. shared LESS primitive if only chrome/geometry is shared
154
+ 2. shared internal JSX primitive if markup/behavior is mostly shared
155
+ 3. public component only if the thing has independent public meaning
156
+
157
+ Current example:
158
+
159
+ - `ControlOpener`
160
+ internal primitive shared by `Dropdown` and `ComboBox`
161
+
162
+ This keeps:
163
+
164
+ - glyph metrics
165
+ - opener width
166
+ - border
167
+ - background
168
+ - browser button reset behavior
169
+
170
+ in one place.
171
+
172
+ ## Slot Customization Contract
173
+
174
+ Preferred internal customization API:
175
+
176
+ - `slotStyles`
177
+ - `slotClassNames`
178
+
179
+ Use:
180
+
181
+ - `className` / `style` for root
182
+ - `slot*` props for meaningful internal surfaces
183
+
184
+ Examples of good slot names:
185
+
186
+ - `root`
187
+ - `label`
188
+ - `title`
189
+ - `body`
190
+ - `popup`
191
+ - `listbox`
192
+ - `input`
193
+ - `field`
194
+ - `hint`
195
+
196
+ Avoid inventing new one-off props for every surface if a control already supports slot customization.
197
+
198
+ ## Controlled / Uncontrolled Guidance
199
+
200
+ Use normal React contracts unless there is a strong reason not to.
201
+
202
+ Prefer:
203
+
204
+ - `value`
205
+ - `defaultValue`
206
+ - `onValueChange`
207
+
208
+ or for stateful booleans:
209
+
210
+ - `open`
211
+ - `defaultOpen`
212
+ - `onOpenChange`
213
+
214
+ For text-like controls:
215
+
216
+ - do not blur or steal focus during normal typing paths
217
+ - especially for editable popup controls like `ComboBox` and `SearchBox`
218
+
219
+ ## Keyboard And Focus Rules
220
+
221
+ ReactNU is intentionally keyboard-forward.
222
+
223
+ Baseline expectations for interactive controls:
224
+
225
+ - visible focus
226
+ - sane tab order
227
+ - escape paths for overlays
228
+ - predictable arrow-key semantics where relevant
229
+
230
+ If a control opens a popup while still being text-editable:
231
+
232
+ - typing must stay on the input
233
+ - popup focus transfer should happen only on explicit navigation behavior
234
+
235
+ ## Window And Dialog Guidance
236
+
237
+ Use `openWindow(...)` for document/tool windows.
238
+
239
+ Use `openDialog(...)` for managed dialogs that still use the normal window manager.
240
+
241
+ Use helper dialogs when you want standard system prompts:
242
+
243
+ - `showMessageBox(...)`
244
+ - `showInputBox(...)`
245
+
246
+ Helper dialogs already own:
247
+
248
+ - centered footer buttons
249
+ - standard sizing
250
+ - title defaults
251
+ - error/info tone behavior
252
+
253
+ If you build a custom dialog manually through `openDialog(...)`, you own its internal layout. That includes button centering.
254
+
255
+ ## Storybook Rules
256
+
257
+ Storybook is not the sandbox.
258
+
259
+ Use Storybook for:
260
+
261
+ - isolated control review
262
+ - prop and slot examples
263
+ - theme/font variation
264
+ - narrow interaction checks
265
+
266
+ Use sandbox for:
267
+
268
+ - free-form desktop workflows
269
+ - multiple windows over time
270
+ - broader integration exercises
271
+
272
+ ### Storybook Window Stories
273
+
274
+ Use:
275
+
276
+ - direct `Window` stories for static shell inspection
277
+ - bounded `NuWindowProvider` stories for managed dialogs/windows
278
+ - full `NuDesktop` only for shell-level stories
279
+
280
+ ### Storybook Layout Density
281
+
282
+ Avoid giant empty canvases for small controls.
283
+
284
+ Preferred:
285
+
286
+ - wrap demos in titled panels
287
+ - keep compact controls content-sized
288
+ - use bounded desktop surfaces for desktop-like stories
289
+
290
+ ## Sandbox Rules
291
+
292
+ Sandbox is allowed to be richer and more workflow-driven than Storybook.
293
+
294
+ But avoid turning sandbox code into hidden library architecture.
295
+
296
+ Good sandbox usage:
297
+
298
+ - realistic host composition
299
+ - test launchers
300
+ - theme switching
301
+ - live windowing flows
302
+
303
+ Bad sandbox usage:
304
+
305
+ - solving library bugs only in sandbox CSS
306
+ - encoding internal library assumptions in demo-only hacks
307
+
308
+ ## Common Pitfalls
309
+
310
+ ### 1. Mixing Portal Roots And Viewport Coordinates
311
+
312
+ If popup position is measured from `getBoundingClientRect()`, do not render the popup into an arbitrary local root unless the whole component is built around local coordinates.
313
+
314
+ ### 2. Browser Button Defaults
315
+
316
+ If a shared primitive can render as a real `button`, neutralize browser defaults explicitly:
317
+
318
+ - `font: inherit`
319
+ - `line-height: 1`
320
+ - `appearance: none`
321
+
322
+ Otherwise glyphs and geometry drift even when the SVG is the same.
323
+
324
+ ### 3. Hidden Stretch From Flex/Grid Parents
325
+
326
+ If shadows or chrome look detached, check whether the parent is stretching the child unexpectedly.
327
+
328
+ ### 4. Storybook Isolates Bugs Differently
329
+
330
+ If behavior differs between sandbox and Storybook:
331
+
332
+ - inspect the host first
333
+ - inspect portal root and positioning rules second
334
+ - only then change the component internals
335
+
336
+ ## Checklist For A New Control
337
+
338
+ Before adding a new control:
339
+
340
+ 1. Decide whether it is a real public component or only an internal primitive.
341
+ 2. Check whether an existing control or shared layer already solves most of it.
342
+ 3. Define the public API in controlled/uncontrolled terms.
343
+ 4. Define keyboard behavior.
344
+ 5. Define focus behavior.
345
+ 6. Define slot surfaces.
346
+ 7. Add Storybook coverage.
347
+ 8. Add sandbox coverage if the control is workflow-heavy.
348
+ 9. Run the narrowest meaningful checks.
349
+
350
+ ## Checklist For Updating An Existing Control
351
+
352
+ 1. Read the current docs page.
353
+ 2. Read the component implementation.
354
+ 3. Check whether Storybook and sandbox both cover the control.
355
+ 4. Prefer a small change.
356
+ 5. If two controls share the same fix, look for a shared primitive/helper.
357
+ 6. Update docs if the rule becomes architectural.
358
+
359
+ ## Checklist For Popup Controls
360
+
361
+ 1. Confirm anchor measurement surface.
362
+ 2. Confirm portal root.
363
+ 3. Confirm theme inheritance in the popup.
364
+ 4. Confirm width contract:
365
+ - whole control
366
+ - field only
367
+ - custom width
368
+ 5. Confirm focus path:
369
+ - editable input stays editable
370
+ - menu/list can still be navigated intentionally
371
+
372
+ ## Checklist For Window/Dialog Stories
373
+
374
+ 1. Decide whether the story needs full `NuDesktop`.
375
+ 2. If not, prefer bounded `NuWindowProvider`.
376
+ 3. Keep the preview area explicitly sized.
377
+ 4. Avoid desktop-only CSS classes on standalone window hosts.
378
+ 5. Test helper dialogs and custom dialogs separately.
379
+
380
+ ## Current Internal Conventions Worth Preserving
381
+
382
+ - body portals for popup-like controls
383
+ - provider-owned typography and desktop pattern
384
+ - slot-based internal customization
385
+ - shared internal primitives for repeated chrome
386
+ - bounded Storybook hosts for dialog/window examples
387
+ - explicit scroll ownership
388
+
389
+ ## If You Are Unsure
390
+
391
+ Choose the smallest rule-preserving change.
392
+
393
+ If a fix only works in sandbox or only works in Storybook, it is probably not finished.
@@ -0,0 +1,30 @@
1
+ # CheckBox
2
+
3
+ `CheckBox` renders a DOS-style checkbox with optional hint text.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <CheckBox
9
+ checked={enabled}
10
+ hint="Verify structure before commit."
11
+ label="&Verify structure"
12
+ onCheckedChange={(nextChecked) => setEnabled(nextChecked)}
13
+ />
14
+ ```
15
+
16
+ ## Key Props
17
+
18
+ - `label: string`
19
+ - `checked?: boolean`
20
+ - `defaultChecked?: boolean`
21
+ - `hint?: string`
22
+ - `disabled?: boolean`
23
+ - `uncheckedShape?: "box" | "none"`
24
+ - `onCheckedChange?: (checked, event) => void`
25
+
26
+ ## Notes
27
+
28
+ - Supports controlled and uncontrolled usage.
29
+ - Label mnemonic highlighting follows the `&` marker convention.
30
+ - `uncheckedShape` controls whether the empty box is shown when unchecked.
@@ -0,0 +1,41 @@
1
+ # ComboBox
2
+
3
+ `ComboBox` is the editable select control. It combines a text input with a filtered list popup.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <ComboBox
9
+ data={[
10
+ {
11
+ category: null,
12
+ items: [
13
+ { id: "default", name: { text: "DEFAULT.NU" } },
14
+ { id: "repair", name: { text: "REPAIR.NU" } }
15
+ ]
16
+ }
17
+ ]}
18
+ label="Run profile"
19
+ />
20
+ ```
21
+
22
+ ## Key Props
23
+
24
+ - `data: ListBoxGroup[]`
25
+ - `label: string`
26
+ - `hint?: string`
27
+ - `value?: string`
28
+ - `defaultValue?: string`
29
+ - `inputValue?: string`
30
+ - `defaultInputValue?: string`
31
+ - `onValueChange?: (value, item, group) => void`
32
+ - `onInputValueChange?: (value) => void`
33
+ - `slotClassNames?` / `slotStyles?` for internal surface customization
34
+
35
+ ## Notes
36
+
37
+ - Typing filters the popup list by item text.
38
+ - `Enter` commits the first filtered match.
39
+ - `ArrowDown` opens the popup.
40
+ - `ComboBox` is intentionally separate from `Dropdown`, which stays non-editable.
41
+ - For async or database-backed lookup, use [SearchBox](./SearchBox.md) instead of overloading `ComboBox`.
@@ -0,0 +1,45 @@
1
+ # CommandButton
2
+
3
+ `CommandButton` is the standalone command-style button that shares the same interaction model and compact chrome as `ToolButton`, but does not require a `ToolBar` container.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <CommandButton icon="gear">&Run</CommandButton>
9
+ ```
10
+
11
+ With popup menu:
12
+
13
+ ```tsx
14
+ <CommandButton
15
+ icon="folder"
16
+ menuItems={[
17
+ { id: "export-map", text: "Export &map" },
18
+ { id: "export-log", text: "Export &log" }
19
+ ]}
20
+ >
21
+ &Export
22
+ </CommandButton>
23
+ ```
24
+
25
+ ## Key Props
26
+
27
+ - `icon?: NuGlyphName | ReactNode`
28
+ - `toggled?: boolean`
29
+ - `pressed?: boolean`
30
+ - `dropdown?: boolean`
31
+ - `menuItems?: MainMenuNode[]`
32
+ - `onMenuItemSelect?: (item: MainMenuItem) => void`
33
+ - `uncheckedShape?: "box" | "none"`
34
+ - `slotStyles`
35
+ - `slotClassNames`
36
+ - normal button props such as `onClick`, `disabled`, `type`
37
+
38
+ ## Notes
39
+
40
+ - if `menuItems` are provided, `CommandButton` opens `PopupMenu` automatically
41
+ - `dropdown` only controls the caret visual
42
+ - `menuItems` controls the actual popup behavior
43
+ - `toggled` is the preferred toggle-state prop name
44
+ - `pressed` remains supported as a legacy alias
45
+ - `ToolButton` and `ToolDropButton` are thin wrappers over the same command-button behavior
@@ -0,0 +1,49 @@
1
+ # CrtGlitch
2
+
3
+ `NuCrtGlitch` is an opt-in ambient effect. It periodically applies a brief RGB-split/warp distortion to a single, randomly chosen control on the page — meant to be caught in peripheral vision, not watched directly.
4
+
5
+ ## Usage
6
+
7
+ Recommended — enable through the theme provider:
8
+
9
+ ```tsx
10
+ <NuThemeProvider crtGlitch>
11
+ <NuDesktop appBar={<AppBar />}>
12
+ <App />
13
+ </NuDesktop>
14
+ </NuThemeProvider>
15
+ ```
16
+
17
+ With options:
18
+
19
+ ```tsx
20
+ <NuThemeProvider crtGlitch={{ intervalMs: 5000, topLevelRatio: 0.5 }}>
21
+ <App />
22
+ </NuThemeProvider>
23
+ ```
24
+
25
+ Standalone, if not using `NuThemeProvider`'s `crtGlitch` prop:
26
+
27
+ ```tsx
28
+ <NuCrtGlitch />
29
+ ```
30
+
31
+ ## Key Props
32
+
33
+ - `enabled?: boolean`
34
+ default `true`. When `false`, the filter definitions stay mounted but inert — no pulses fire.
35
+ - `intervalMs?: number`
36
+ default `3000`. Average gap between pulses. The actual gap is jittered (0.6x-1.6x of this value) so pulses never fall into a detectable fixed cadence.
37
+ - `durationMs?: number`
38
+ default `2500`. Average length of a single pulse. Also jittered per pulse (0.7x-1.4x).
39
+ - `targetSelector?: string`
40
+ CSS selector for the pool of small leaf-control candidates (buttons, checkboxes, glyphs, rows...). Defaults to controls scoped under an open, non-minimized `.nu-window`.
41
+ - `topLevelRatio?: number`
42
+ default `1/3`. Fraction of pulses that target a whole open window instead of a small leaf control. Falls back to whichever pool actually has candidates if the rolled pool is empty (e.g. no windows open yet).
43
+
44
+ ## Notes
45
+
46
+ - Opt-in and silent between pulses — the component only renders a hidden SVG `<filter>` definition, nothing visible on its own.
47
+ - No two pulses share the same noise seed, offsets, duration, or gap, so nothing about the effect repeats often enough to read as decorative.
48
+ - Designed to feel like a real, subtle fault rather than a demo effect: small controls glitch far more often than whole windows (see `topLevelRatio`), and offsets/intensity are re-rolled every pulse.
49
+ - Mount once, anywhere under `NuThemeProvider` (or once via the `crtGlitch` prop). A second instance is wasteful, not harmful.
@@ -0,0 +1,73 @@
1
+ # Dashboard
2
+
3
+ `Dashboard` is a full-workspace static layout surface for persistent desktop content that lives behind managed windows inside `NuDesktop`.
4
+
5
+ It supports two static layout modes:
6
+
7
+ - `grid`: explicit CSS grid placement
8
+ - `lanes`: independent vertical columns
9
+
10
+ ## Usage
11
+
12
+ ```tsx
13
+ <Dashboard
14
+ gap={12}
15
+ laneCount={2}
16
+ items={[
17
+ {
18
+ id: "system",
19
+ lane: 1,
20
+ minHeight: "18rem",
21
+ content: <Panel title="System Core">...</Panel>
22
+ },
23
+ {
24
+ id: "tools",
25
+ lane: 2,
26
+ minHeight: "18rem",
27
+ content: <Panel title="Workspace Tools">...</Panel>
28
+ }
29
+ ]}
30
+ layout="lanes"
31
+ />
32
+ ```
33
+
34
+ ## Key Props
35
+
36
+ - `items: DashboardItem[]`
37
+ - `columnCount?: number`
38
+ - `layout?: "grid" | "lanes"`
39
+ - `laneCount?: number`
40
+ - `gap?: number`
41
+ - `fill?: boolean`
42
+
43
+ ## DashboardItem
44
+
45
+ Each item describes static CSS grid placement plus render content:
46
+
47
+ ```ts
48
+ type DashboardItem = {
49
+ id: string | number;
50
+ lane?: number;
51
+ column?: string;
52
+ row?: string;
53
+ columnSpan?: number;
54
+ rowSpan?: number;
55
+ width?: string;
56
+ maxWidth?: string;
57
+ minWidth?: string;
58
+ minHeight?: string;
59
+ content: ReactNode;
60
+ };
61
+ ```
62
+
63
+ ## Notes
64
+
65
+ - `Dashboard` is a static layout surface, not a drag-and-resize layout engine.
66
+ - Managed `Window` instances still render above it through `NuWindowProvider`.
67
+ - Use it for always-present workspace panels, launch surfaces, inspectors, and dashboard-like control rooms.
68
+ - The control defaults to `fill`, so it is suitable as the direct child of `NuDesktop`.
69
+ - Grid rows use normal CSS content sizing, so panel height follows the child content unless you set explicit `minHeight`.
70
+ - `lanes` mode is useful when each column should stack by its own height, without waiting for taller cells in neighboring columns.
71
+ - In `lanes` mode you can also give an item an explicit `width` or `maxWidth` to avoid stretching it across the full lane.
72
+ - Panel content should usually be another ReactNU surface such as `Panel`, `Frame`, or `NuView`.
73
+ - If a product needs interactive rearrangement, `panelgrid` should be used directly by the host rather than hidden behind `Dashboard`.
@@ -0,0 +1,27 @@
1
+ # Desktop
2
+
3
+ `NuDesktop` is the top-level desktop shell. It renders a fixed full-screen workspace with three rows:
4
+
5
+ 1. top menu area
6
+ 2. central workspace
7
+ 3. bottom app bar area
8
+
9
+ ## Usage
10
+
11
+ ```tsx
12
+ <NuDesktop appBar={<SandboxAppBar />}>
13
+ <App />
14
+ </NuDesktop>
15
+ ```
16
+
17
+ ## Key Props
18
+
19
+ - `children`
20
+ - `appBar?: ReactNode`
21
+ - `appBarContent?: ReactNode`
22
+ - standard `div` props
23
+
24
+ ## Notes
25
+
26
+ - The desktop owns the browser viewport and is intended to behave like a bounded screen.
27
+ - `appBarContent` is kept as a compatibility alias, but `appBar` is the preferred entry point.