@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,64 @@
1
+ # NuThemeProvider
2
+
3
+ `NuThemeProvider` applies design tokens for the active visual theme.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <NuThemeProvider>
9
+ <NuDesktop appBar={<AppBar />}>
10
+ <App />
11
+ </NuDesktop>
12
+ </NuThemeProvider>
13
+ ```
14
+
15
+ Typography can also be configured at the provider level:
16
+
17
+ ```tsx
18
+ <NuThemeProvider
19
+ defaultFontFamily={'"Comic Sans MS", "Comic Sans", cursive'}
20
+ defaultFontSize={16}
21
+ >
22
+ <App />
23
+ </NuThemeProvider>
24
+ ```
25
+
26
+ ## Related API
27
+
28
+ - `useNuTheme()`
29
+ - `nuThemes`
30
+ - `resolveNuTheme(...)`
31
+ - `isNuThemeName(...)`
32
+
33
+ ## Provider Typography
34
+
35
+ `NuThemeProvider` now owns both theme tokens and base typography for the full UI tree.
36
+
37
+ Supported props:
38
+
39
+ - `desktopPatternMode?: "dot-grid" | "dense-dots" | "coarse-dots" | "grid" | "solid"`
40
+ - `defaultDesktopPatternMode?: ...`
41
+ - `onDesktopPatternModeChange?: (mode) => void`
42
+ - `fontFamily?: string`
43
+ - `defaultFontFamily?: string`
44
+ - `onFontFamilyChange?: (fontFamily) => void`
45
+ - `fontSize?: number`
46
+ - `defaultFontSize?: number`
47
+ - `onFontSizeChange?: (fontSize) => void`
48
+ - `crtGlitch?: boolean | NuCrtGlitchProps`
49
+ enables the ambient CRT-glitch effect (see [CrtGlitch](./CrtGlitch.md)). `true` uses its defaults; pass an options object to tune them. Defaults to `false` — opt-in.
50
+
51
+ `useNuTheme()` exposes:
52
+
53
+ - `desktopPatternMode`
54
+ - `fontFamily`
55
+ - `fontSize`
56
+ - `setDesktopPatternMode(...)`
57
+ - `setFontFamily(...)`
58
+ - `setFontSize(...)`
59
+
60
+ ## Notes
61
+
62
+ - The default theme is the classic DOS/Norton-inspired palette.
63
+ - Theme tokens drive desktop, windowing, controls, selection, and inactive overlays.
64
+ - Provider typography affects preview content, managed windows, dialogs, menus, and popup portals rendered inside the theme scope.
package/docs/NuView.md ADDED
@@ -0,0 +1,58 @@
1
+ # NuView
2
+
3
+ `NuView` is a generic fill-and-scroll container for hosting content inside frames, panes, dialogs, and splitter cells.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <NuView padding="sm">
9
+ <Frame title="Inspector">
10
+ <Stack gap="md">{/* content */}</Stack>
11
+ </Frame>
12
+ </NuView>
13
+ ```
14
+
15
+ ## Key Props
16
+
17
+ - `fill?: boolean`
18
+ - `scroll?: "auto" | "x" | "y" | "both" | "hidden"`
19
+ - `padding?: "none" | "sm" | "md" | "lg"`
20
+
21
+ ## Notes
22
+
23
+ - `fill` defaults to `true`, so `NuView` expands to the available area in common pane/frame layouts.
24
+ - `NuView` is the place where host code should declare scroll behavior, instead of relying on incidental overflow from parent containers.
25
+ - It is intended to simplify content composition inside `Splitter`, `Frame`, `Window`, and similar layout shells.
26
+
27
+ ## Recommended Ownership
28
+
29
+ `NuView` should usually own the viewport area.
30
+
31
+ Good fit:
32
+
33
+ - splitter cells
34
+ - resizable panes
35
+ - frame-like shells inside windows
36
+ - any place where the host wants one explicit scroll/fill container
37
+
38
+ Typical pattern:
39
+
40
+ ```tsx
41
+ <NuView scroll="auto" padding="sm">
42
+ <Frame title="Status">{/* content */}</Frame>
43
+ </NuView>
44
+ ```
45
+
46
+ This is especially important in `Splitter` layouts, where `NuView` should sit directly inside the pane and define how that pane scrolls.
47
+
48
+ ## Protocol Note
49
+
50
+ During splitter integration we hit a concrete bug:
51
+
52
+ - `NuView` was implemented too deep in the tree.
53
+ - It did not own the pane viewport.
54
+ - Scroll behavior looked wrong because the pane owner and the viewport owner were different components.
55
+
56
+ The current rule is:
57
+
58
+ `pane -> NuView -> content`
@@ -0,0 +1,81 @@
1
+ # NuWindowProvider
2
+
3
+ `NuWindowProvider` is the window manager for the desktop shell.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <NuWindowProvider>
9
+ <Workspace />
10
+ </NuWindowProvider>
11
+ ```
12
+
13
+ ## Main API
14
+
15
+ Use `useNuWindowManager()` to access:
16
+
17
+ - `openWindow(definition)`
18
+ - `openDialog(definition)`
19
+ - `showMessageBox(options)`
20
+ - `showInputBox(options)`
21
+ - `closeWindow(id)`
22
+ - `updateWindow(id, patch)`
23
+ - `activateWindow(id)`
24
+ - `bringToFront(id)`
25
+ - `toggleWindowMinimized(id)`
26
+ - `toggleWindowMaximized(id)`
27
+ - `closeAll()`
28
+ - `windows`
29
+
30
+ ## Managed Window Persistence
31
+
32
+ `NuManagedWindowDefinition` also supports:
33
+
34
+ - `onOpen?: () => NuManagedWindowSnapshot | void`
35
+ - `onClose?: (snapshot: NuManagedWindowSnapshot) => boolean | void`
36
+
37
+ This lets the host save and restore window geometry:
38
+
39
+ ```tsx
40
+ let savedWindowState: NuManagedWindowSnapshot | undefined;
41
+
42
+ windowManager.openWindow({
43
+ title: "Inspector",
44
+ content: <Inspector />,
45
+ onOpen: () => savedWindowState,
46
+ onClose: (snapshot) => {
47
+ savedWindowState = snapshot;
48
+ return true;
49
+ }
50
+ });
51
+ ```
52
+
53
+ ## Helper Dialogs
54
+
55
+ The same manager also provides async helper dialogs:
56
+
57
+ ```tsx
58
+ const result = await windowManager.showMessageBox({
59
+ title: "Diagnostics",
60
+ message: "Continue with the maintenance pass?",
61
+ kind: "info",
62
+ yes: true,
63
+ no: true
64
+ });
65
+
66
+ const value = await windowManager.showInputBox({
67
+ title: "Archive Report",
68
+ label: "Target path",
69
+ defaultValue: "C:\\LOGS\\SURFACE.MAP"
70
+ });
71
+ ```
72
+
73
+ See [Dialog Helpers](./DialogHelpers.md) for the full option list.
74
+
75
+ ## Notes
76
+
77
+ - Supports app-modal and owner-modal dialogs.
78
+ - Keeps window list order stable for app-bar display while still maintaining a separate visual z-stack.
79
+ - `onOpen` is applied when the managed window record is created.
80
+ - `onClose` receives the latest saved geometry and `maximized/minimized` state.
81
+ - Returning `false` from `onClose` vetoes the close request.
@@ -0,0 +1,28 @@
1
+ # PageControl
2
+
3
+ `PageControl` is the tabbed page surface for switching between compact tool panels inside the same window.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <PageControl
9
+ pages={[
10
+ { id: "summary", label: "&Summary", content: <SummaryPanel /> },
11
+ { id: "detail", label: "&Detail", content: <DetailPanel /> }
12
+ ]}
13
+ />
14
+ ```
15
+
16
+ ## Key Props
17
+
18
+ - `pages: PageControlPage[]`
19
+ - `activePageId?: string`
20
+ - `defaultActivePageId?: string`
21
+ - `onActivePageChange?: (page) => void`
22
+ - `fill?: boolean`
23
+
24
+ ## Notes
25
+
26
+ - The component supports controlled and uncontrolled page selection.
27
+ - Keyboard navigation includes `Left/Right`, `Up/Down`, `Home`, and `End`.
28
+ - `Tabs` is exported as an alias of `PageControl`.
package/docs/Panel.md ADDED
@@ -0,0 +1,23 @@
1
+ # Panel
2
+
3
+ `Panel` is a heavier container surface for primary application regions.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <Panel title="System Core" footer="F1 Help" inset>
9
+ <Content />
10
+ </Panel>
11
+ ```
12
+
13
+ ## Key Props
14
+
15
+ - `title?: string`
16
+ - `footer?: string`
17
+ - `inset?: boolean`
18
+ - `children`
19
+
20
+ ## Notes
21
+
22
+ - `Panel` is the main raised surface.
23
+ - `inset` is useful for denser workspace-like regions inside a larger shell.
@@ -0,0 +1,42 @@
1
+ # PopupMenu
2
+
3
+ `PopupMenu` is a context-style menu surface built on the same menu item model as `MainMenu`.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ const popupMenu = usePopupMenu();
9
+
10
+ <Button onClick={popupMenu.openFromClick}>Open popup</Button>
11
+ <PopupMenu
12
+ anchor={popupMenu.anchor}
13
+ open={popupMenu.open}
14
+ onOpenChange={popupMenu.setOpen}
15
+ items={items}
16
+ />
17
+ ```
18
+
19
+ ## Key Props
20
+
21
+ - `items: MainMenuNode[]`
22
+ - `anchor: PopupMenuAnchor | null`
23
+ - `open?: boolean`
24
+ - `defaultOpen?: boolean`
25
+ - `onOpenChange?: (open) => void`
26
+ - `onItemSelect?: (item) => void`
27
+
28
+ ## Related Hook
29
+
30
+ - `usePopupMenu()`
31
+ - `anchor`
32
+ - `open`
33
+ - `setOpen`
34
+ - `close()`
35
+ - `openAtPoint(x, y)`
36
+ - `openAtElement(element)`
37
+ - `openFromClick(event)`
38
+ - `openFromContextMenu(event)`
39
+
40
+ ## Notes
41
+
42
+ - Popup menus render through a portal and are not clipped by local overflow containers.
@@ -0,0 +1,33 @@
1
+ # ProgressBar
2
+
3
+ `ProgressBar` renders a DOS-style determinate or indeterminate progress indicator.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <ProgressBar
9
+ label="Surface scan"
10
+ value={42}
11
+ max={100}
12
+ hint="Scanning allocation map"
13
+ />
14
+ ```
15
+
16
+ ## Key Props
17
+
18
+ - `value?: number`
19
+ - `min?: number`
20
+ - `max?: number`
21
+ - `indeterminate?: boolean`
22
+ - `showValue?: boolean`
23
+ - `label?: string`
24
+ - `hint?: string`
25
+ - `trackBackground?: CSSProperties["background"]`
26
+ - `valueRenderer?: (percent, value, min, max) => ReactNode`
27
+
28
+ ## Notes
29
+
30
+ - `value` is clamped to the `min..max` range.
31
+ - `showValue` controls the right-side textual progress output.
32
+ - `indeterminate` ignores `aria-valuenow` and animates the fill instead.
33
+ - `trackBackground` lets the host override the progress track background while keeping the fill white.
@@ -0,0 +1,63 @@
1
+ # PropertyGrid
2
+
3
+ `PropertyGrid` is the hierarchical inspector surface for labeled settings, expandable groups, and embedded editors.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <PropertyGrid
9
+ entries={[
10
+ { id: "general", type: "section", title: "&General" },
11
+ {
12
+ id: "target",
13
+ label: "&Target",
14
+ content: <TextField label="Target" defaultValue="C:\\SYSTEM" />
15
+ },
16
+ {
17
+ id: "rect",
18
+ type: "group",
19
+ label: "&Box",
20
+ summary: <>Rect(0,0,10,20)</>,
21
+ children: [
22
+ {
23
+ id: "top",
24
+ label: "&Top",
25
+ content: <SpinBox label="Top" value={0} />
26
+ }
27
+ ]
28
+ }
29
+ ]}
30
+ />
31
+ ```
32
+
33
+ ## Key Props
34
+
35
+ - `entries: PropertyGridEntry[]`
36
+ - `labelWidth?: string`
37
+ - `fill?: boolean`
38
+ - `bordered?: boolean`
39
+ - `activeId?: string`
40
+ - `defaultActiveId?: string`
41
+ - `onActiveIdChange?: (activeId) => void`
42
+ - `expandedIds?: string[]`
43
+ - `defaultExpandedIds?: string[]`
44
+ - `onExpandedIdsChange?: (expandedIds) => void`
45
+
46
+ ## Notes
47
+
48
+ - Use section rows to break long inspectors into logical blocks.
49
+ - Group rows provide expandable hierarchy with a summary cell on the right.
50
+ - Nested groups can be arbitrarily deep. A common pattern is a collapsed summary row like `Rect(0,0,10,20)` that expands into leaf editors such as `Top`, `Left`, `Width`, and `Height`.
51
+ - Item rows accept arbitrary React content in the value column.
52
+ - Clicking an item key activates the editor in the value column. For checkbox-like editors, the key click also toggles the value.
53
+ - Keyboard navigation now follows inspector-style semantics:
54
+ - `Up` / `Down` move between rows
55
+ - `Home` / `End` jump to the first or last interactive row
56
+ - `Right` expands a group or activates the current item editor
57
+ - `Left` collapses the current group or moves focus to the parent group
58
+ - `Enter` / `Space` toggle a group or activate the current item editor
59
+ - Item keys use the same white-surface / inverse-text treatment as the rest of the library's menu-like key slots.
60
+ - Group keys use the inactive-button surface, so expandable branches are visually distinct from leaf properties.
61
+ - Borders are optional through `bordered`; the default presentation is borderless.
62
+ - Embedded ReactNU field controls have their internal top labels visually suppressed inside the property cell, because the grid already owns the left label column.
63
+ - `PropertyGrid` is already suitable as a practical inspector surface, but it is still not a full schema engine. The next logical expansion would be deeper in-place editing semantics and richer nested property schemas.
@@ -0,0 +1,36 @@
1
+ # RadioGroup
2
+
3
+ `RadioGroup` renders a set of DOS-style radio options with one active value.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <RadioGroup
9
+ label="&Boot mode"
10
+ hint="Choose the recovery startup profile."
11
+ options={[
12
+ { label: "&Safe mode", value: "safe" },
13
+ { label: "&Network mode", value: "network" },
14
+ { label: "&Full diagnostics", value: "full" }
15
+ ]}
16
+ value={bootMode}
17
+ onValueChange={setBootMode}
18
+ />
19
+ ```
20
+
21
+ ## Key Props
22
+
23
+ - `label?: string`
24
+ - `hint?: string`
25
+ - `name?: string`
26
+ - `options: Array<{ label, value, disabled?, hint? }>`
27
+ - `value?: string`
28
+ - `defaultValue?: string`
29
+ - `onValueChange?: (value) => void`
30
+ - `slotClassNames?` / `slotStyles?` for group-level customization
31
+
32
+ ## Notes
33
+
34
+ - Supports controlled and uncontrolled usage.
35
+ - `RadioButton` is also available as a lower-level building block.
36
+ - Mnemonic highlighting follows the `&` marker convention.
@@ -0,0 +1,27 @@
1
+ # ReportCell
2
+
3
+ `ReportCell` is a lightweight helper for report-style table cells.
4
+
5
+ It is intentionally optional. Host code can return plain text or any custom
6
+ `ReactNode`, but `ReportCell` keeps alignment and tone consistent for
7
+ `ListView` and `TreeListView`-style columns.
8
+
9
+ ## Usage
10
+
11
+ ```tsx
12
+ <ReportCell align="end" tone="muted">
13
+ 44 KB
14
+ </ReportCell>
15
+ ```
16
+
17
+ ## Props
18
+
19
+ - `align?: "start" | "center" | "end"`
20
+ - `tone?: "default" | "muted" | "accent" | "danger" | "success"`
21
+
22
+ ## Notes
23
+
24
+ - `ReportCell` does not own column sizing.
25
+ - It is a content helper, not a container control.
26
+ - Use it when host-provided cells should still follow the library's report
27
+ alignment and color language.
@@ -0,0 +1,85 @@
1
+ # Slot Customization
2
+
3
+ ReactNU components are moving to a shared internal customization contract:
4
+
5
+ - `slotStyles`
6
+ - `slotClassNames`
7
+
8
+ This is the preferred way to override internal surfaces without rewriting a component.
9
+
10
+ ## Shape
11
+
12
+ Typical usage:
13
+
14
+ ```tsx
15
+ <Frame
16
+ slotStyles={{
17
+ title: { background: "black", color: "yellow" },
18
+ body: { background: "#6262e3" }
19
+ }}
20
+ slotClassNames={{
21
+ root: "my-frame",
22
+ title: "my-frame-title"
23
+ }}
24
+ title="Target Controls"
25
+ />
26
+ ```
27
+
28
+ ## Rules
29
+
30
+ - `className` and `style` still target the component root.
31
+ - `slotClassNames` and `slotStyles` target internal named slots.
32
+ - Slot names should be literal and structural:
33
+ - `root`
34
+ - `label`
35
+ - `body`
36
+ - `title`
37
+ - `input`
38
+ - `hint`
39
+ - `popup`
40
+ - `listbox`
41
+ - Component-specific legacy props such as `titleStyle` or `contentStyle` may still exist for compatibility, but new work should prefer slot-based customization.
42
+
43
+ ## Internal Primitive Rule
44
+
45
+ Slot customization does not replace shared internal primitives.
46
+
47
+ If two controls share the same internal visual part, prefer:
48
+
49
+ - one shared internal primitive
50
+ - plus slot customization on top of that primitive
51
+
52
+ instead of:
53
+
54
+ - separate duplicated markup
55
+ - separate duplicated LESS
56
+ - followed by two independent slot APIs
57
+
58
+ Example:
59
+
60
+ - `Dropdown` and `ComboBox` share the internal `ControlOpener` primitive
61
+ - each control still exposes its own slot names around that primitive
62
+
63
+ ## Current Direction
64
+
65
+ This contract is now the standard for new and updated controls.
66
+
67
+ The first wave already covers the main surface and control layer:
68
+
69
+ - `Frame`
70
+ - `Panel`
71
+ - `Button`
72
+ - `PageControl`
73
+ - `ToolBar`
74
+ - `ProgressBar`
75
+ - `TickBar`
76
+ - `TextField`
77
+ - `SpinBox`
78
+ - `CheckBox`
79
+
80
+ Additional controls should follow the same pattern as they are touched, instead of inventing one-off prop names.
81
+
82
+ When extending a component:
83
+
84
+ - add slots only for meaningful structural surfaces
85
+ - do not expose every nested implementation detail as a slot unless it is a real customization surface
@@ -0,0 +1,96 @@
1
+ # Storybook
2
+
3
+ ReactNU now ships with a dedicated Storybook layer for component coverage, visual regression review, and API exploration.
4
+
5
+ ## Scripts
6
+
7
+ - `npm run storybook`
8
+ starts Storybook in dev mode
9
+ - `npm run build-storybook`
10
+ produces a static build in `storybook-static/`
11
+
12
+ ## Global Toolbars
13
+
14
+ The Storybook preview exposes provider-level globals for:
15
+
16
+ - theme
17
+ - font family
18
+ - font size
19
+ - desktop pattern mode
20
+
21
+ These are wired through `NuThemeProvider`, so stories can be checked under the same typography and desktop-surface conditions as the sandbox.
22
+
23
+ ## Host Composition Rules
24
+
25
+ Storybook uses more than one kind of host on purpose.
26
+
27
+ Use a bounded surface with direct components when you only need:
28
+
29
+ - isolated control review
30
+ - static window chrome
31
+ - local layout examples
32
+
33
+ Use `NuWindowProvider` in a bounded container when you need:
34
+
35
+ - managed windows
36
+ - helper dialogs
37
+ - modal layering
38
+ - `useNuWindowManager()` flows
39
+
40
+ Use full `NuDesktop` only when the story is explicitly about:
41
+
42
+ - desktop shell composition
43
+ - menu/app-bar integration
44
+ - fixed desktop semantics
45
+
46
+ This distinction matters because `NuDesktop` is intentionally fullscreen/fixed by nature, while many Storybook stories need a bounded preview host.
47
+
48
+ ## Coverage Goals
49
+
50
+ The current Storybook covers the main package surfaces:
51
+
52
+ - theming and slot customization
53
+ - buttons and event feedback
54
+ - input controls
55
+ - selectors and async lookup
56
+ - toolbar and page control navigation
57
+ - list and tree controls
58
+ - property inspector layout
59
+ - surface/layout primitives
60
+ - direct desktop and window chrome
61
+
62
+ ## Why Storybook Exists Alongside Sandbox
63
+
64
+ The sandbox remains the free-form integration lab.
65
+
66
+ Storybook serves a different role:
67
+
68
+ - isolated component review
69
+ - prop and event exploration
70
+ - theme/font regression checks
71
+ - docs-friendly usage examples
72
+ - easier review of slot-level customization
73
+
74
+ ## Current Scope
75
+
76
+ Storybook is intended to show:
77
+
78
+ - how a control behaves on its own
79
+ - how it behaves under different theme and typography settings
80
+ - how slot overrides affect internal surfaces
81
+
82
+ The sandbox still remains the better place for:
83
+
84
+ - long-lived desktop workflows
85
+ - managed window orchestration
86
+ - complex multi-control interaction sequences
87
+
88
+ ## Popup Story Guidance
89
+
90
+ Popup-like controls in Storybook should follow the same contract as the library runtime:
91
+
92
+ - popup rendered into `document.body`
93
+ - popup themed from the nearest `.nu-theme-root`
94
+ - geometry measured from the visible anchor
95
+
96
+ If a popup appears correct in sandbox but drifts in Storybook, treat that first as a host-composition issue rather than immediately changing the control API.
@@ -0,0 +1,41 @@
1
+ # SearchBox
2
+
3
+ `SearchBox` is the async lookup control for remote or database-backed search.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <SearchBox
9
+ dataProvider={(query) => fetchStations(query)}
10
+ getItemId={(item) => item.id}
11
+ getItemText={(item) => item.name}
12
+ label="Station search"
13
+ onItemSelect={(item) => setSelectedStation(item)}
14
+ />
15
+ ```
16
+
17
+ ## Key Props
18
+
19
+ - `dataProvider: (query) => Promise<T[]>`
20
+ - `getItemId: (item, index) => string`
21
+ - `getItemText: (item) => string`
22
+ - `getItemDetails?: (item) => ReactNode`
23
+ - `getItemDisabled?: (item) => boolean`
24
+ - `label: string`
25
+ - `hint?: string`
26
+ - `query?: string`
27
+ - `defaultQuery?: string`
28
+ - `onQueryChange?: (query) => void`
29
+ - `onItemSelect?: (item) => void`
30
+ - `debounceMs?: number`
31
+ - `minQueryLength?: number`
32
+ - `loadingText?: string`
33
+ - `emptyText?: string`
34
+ - `errorText?: string`
35
+
36
+ ## Notes
37
+
38
+ - `SearchBox` is intentionally separate from `ComboBox`.
39
+ - Use `ComboBox` for local editable lists.
40
+ - Use `SearchBox` when results come from an async provider such as a database or remote service.
41
+ - The input remains the focus owner; `Enter` commits the first result when available.