@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,85 @@
1
+ # Dialog Helpers
2
+
3
+ `useNuWindowManager()` includes two async helper dialogs built on top of the managed window layer:
4
+
5
+ - `showMessageBox(options)`
6
+ - `showInputBox(options)`
7
+
8
+ Both helpers open managed dialogs and resolve through a `Promise`.
9
+
10
+ ## MessageBox
11
+
12
+ ```tsx
13
+ const windowManager = useNuWindowManager();
14
+
15
+ const result = await windowManager.showMessageBox({
16
+ title: "Diagnostics",
17
+ message: "Continue with the maintenance pass?",
18
+ kind: "info",
19
+ preset: "yes-no-cancel"
20
+ });
21
+ ```
22
+
23
+ Supported options:
24
+
25
+ - `title?: string`
26
+ - `message: ReactNode`
27
+ - `kind?: "normal" | "info" | "error"`
28
+ - `preset?: "ok" | "ok-cancel" | "yes-no" | "yes-no-cancel"`
29
+ - `yes?: boolean`
30
+ - `no?: boolean`
31
+ - `cancel?: boolean`
32
+ - `ok?: boolean`
33
+ - `yesLabel?: string`
34
+ - `noLabel?: string`
35
+ - `cancelLabel?: string`
36
+ - `okLabel?: string`
37
+ - `appModal?: boolean`
38
+ - `domain?: string`
39
+ - `style?: CSSProperties`
40
+
41
+ Result type:
42
+
43
+ - `"ok" | "yes" | "no" | "cancel"`
44
+
45
+ Notes:
46
+
47
+ - If no buttons are specified, `MessageBox` falls back to `OK`.
48
+ - `preset` provides the starting button set, but explicit button flags still override it.
49
+ - Button labels can be overridden without changing the result values.
50
+ - If the dialog is closed through the title bar, the helper resolves to the best dismiss result for the configured buttons.
51
+
52
+ ## InputBox
53
+
54
+ ```tsx
55
+ const windowManager = useNuWindowManager();
56
+
57
+ const value = await windowManager.showInputBox({
58
+ title: "Archive Report",
59
+ label: "Target path",
60
+ defaultValue: "C:\\LOGS\\SURFACE.MAP",
61
+ hint: "Type the report path and confirm."
62
+ });
63
+ ```
64
+
65
+ Supported options:
66
+
67
+ - `title?: string`
68
+ - `label: string`
69
+ - `defaultValue?: string`
70
+ - `placeholder?: string`
71
+ - `hint?: string`
72
+ - `okLabel?: string`
73
+ - `cancelLabel?: string`
74
+ - `appModal?: boolean`
75
+ - `domain?: string`
76
+ - `style?: CSSProperties`
77
+
78
+ Result type:
79
+
80
+ - `string | null`
81
+
82
+ Notes:
83
+
84
+ - `null` means the dialog was cancelled or closed.
85
+ - `InputBox` uses the same managed dialog layer as all other windowed UI.
@@ -0,0 +1,44 @@
1
+ # Dropdown
2
+
3
+ `Dropdown` is a select-like control built from a compact DOS-style field and a popup `ListBox`.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <Dropdown
9
+ label="Run profile"
10
+ value={profileId}
11
+ onValueChange={(nextValue) => setProfileId(nextValue)}
12
+ data={[
13
+ {
14
+ category: null,
15
+ items: [
16
+ { id: "default", name: { text: "DEFAULT.NU" } },
17
+ { id: "repair", name: { text: "REPAIR.NU" } }
18
+ ]
19
+ }
20
+ ]}
21
+ />
22
+ ```
23
+
24
+ ## Key Props
25
+
26
+ - `label: string`
27
+ - `data: ListBoxGroup[]`
28
+ - `value?: string`
29
+ - `defaultValue?: string`
30
+ - `onValueChange?: (value, item, group) => void`
31
+ - `placeholder?: string`
32
+ - `hint?: string`
33
+ - `disabled?: boolean`
34
+ - `slotClassNames?` / `slotStyles?` for internal surface customization
35
+
36
+ ## Keyboard
37
+
38
+ - `ArrowUp` / `ArrowDown` change the value while closed
39
+ - `Enter` / `Space` open the list
40
+
41
+ ## Notes
42
+
43
+ - The popup width is clamped to the width of the closed control.
44
+ - This component is intentionally select-like; searchable combo-box behavior should live in a separate component.
package/docs/Frame.md ADDED
@@ -0,0 +1,38 @@
1
+ # Frame
2
+
3
+ `Frame` is a lightweight container with a simple border and optional title.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <Frame title="Commands">
9
+ <ListBox data={groups} />
10
+ </Frame>
11
+ ```
12
+
13
+ ## Key Props
14
+
15
+ - `fill?: boolean`
16
+ - `title?: string`
17
+ - `titleStart?: ReactNode`
18
+ - `titleContent?: ReactNode`
19
+ - `titleEnd?: ReactNode`
20
+ - `titleProps?: { background?: string; color?: string; borderColor?: string }`
21
+ - `titleStyle?: CSSProperties`
22
+ - `contentStyle?: CSSProperties`
23
+ - `variant?: "outline" | "title-bar"`
24
+ - `titleAlign?: "start" | "center" | "end"`
25
+ - `titleBold?: boolean`
26
+ - `children`
27
+
28
+ ## Notes
29
+
30
+ - `fill` defaults to `true`, so `Frame` stretches naturally inside flex/grid parents and also fills block-style hosts such as window bodies.
31
+ - `outline` keeps the title floating over the top border.
32
+ - `title-bar` renders a solid title strip across the full width.
33
+ - `titleProps` controls frame chrome around the title area: title background, title text color, and frame border color.
34
+ - `titleStyle` and `contentStyle` remain available for additional local overrides without creating a separate Frame variant.
35
+ - `title` remains a shorthand for simple text titles.
36
+ - `titleContent` lets you replace the center title payload with custom markup.
37
+ - `titleStart` and `titleEnd` let you place custom controls or indicators on the left and right of the title shell.
38
+ - if only `titleStart` or `titleEnd` is provided, `Frame` renders just that fragment without a default text title.
@@ -0,0 +1,110 @@
1
+ # Getting Started
2
+
3
+ This guide shows the recommended host setup for a ReactNU application.
4
+
5
+ ## Recommended Shell
6
+
7
+ ```tsx
8
+ import {
9
+ AppBarHost,
10
+ AppBarItem,
11
+ NuDesktop,
12
+ NuThemeProvider,
13
+ NuView,
14
+ WindowBar,
15
+ useNuWindowManager
16
+ } from "@deadragdoll/reactnu";
17
+
18
+ function ShellAppBar() {
19
+ const windowManager = useNuWindowManager();
20
+
21
+ return (
22
+ <AppBarHost>
23
+ <WindowBar
24
+ items={windowManager.windows.map((windowEntry) => ({
25
+ active: windowEntry.active,
26
+ domain: windowEntry.domain,
27
+ id: windowEntry.id,
28
+ minimized: windowEntry.minimized,
29
+ title: windowEntry.title
30
+ }))}
31
+ onActivateWindow={windowManager.activateWindow}
32
+ />
33
+ <AppBarItem alignment="end">12:40</AppBarItem>
34
+ </AppBarHost>
35
+ );
36
+ }
37
+
38
+ export function App() {
39
+ return (
40
+ <NuThemeProvider>
41
+ <NuDesktop appBar={<ShellAppBar />}>
42
+ <NuView padding="md">Workspace content</NuView>
43
+ </NuDesktop>
44
+ </NuThemeProvider>
45
+ );
46
+ }
47
+ ```
48
+
49
+ ## Recommended Order
50
+
51
+ 1. `NuThemeProvider`
52
+ 2. `NuDesktop`
53
+ 3. host-driven `appBar`
54
+ 4. workspace content
55
+ 5. open windows through `useNuWindowManager()`
56
+
57
+ ## Opening A Window
58
+
59
+ ```tsx
60
+ import { Button, useNuWindowManager } from "@deadragdoll/reactnu";
61
+
62
+ function Launcher() {
63
+ const windowManager = useNuWindowManager();
64
+
65
+ return (
66
+ <Button
67
+ onClick={() =>
68
+ windowManager.openWindow({
69
+ title: "Inspector",
70
+ content: <div>Window content</div>
71
+ })
72
+ }
73
+ >
74
+ &Open inspector
75
+ </Button>
76
+ );
77
+ }
78
+ ```
79
+
80
+ ## Opening A Dialog
81
+
82
+ ```tsx
83
+ windowManager.openDialog({
84
+ title: "Confirm",
85
+ content: ({ close }) => <Button onClick={close}>&Close</Button>
86
+ });
87
+ ```
88
+
89
+ ## Recommended Folder Shape
90
+
91
+ ```text
92
+ src/
93
+ app/
94
+ App.tsx
95
+ DesktopAppBar.tsx
96
+ DesktopMenu.tsx
97
+ windows/
98
+ InspectorWindow.tsx
99
+ ReportWindow.tsx
100
+ dialogs/
101
+ ConfirmDialog.tsx
102
+ views/
103
+ DashboardView.tsx
104
+ ```
105
+
106
+ ## Notes
107
+
108
+ - `NuDesktop` already creates the app host and window manager layers.
109
+ - `WindowBar` is host-owned. It is not injected automatically.
110
+ - Use `NuView` whenever a pane or cell needs to own scrolling explicitly.
package/docs/Glyph.md ADDED
@@ -0,0 +1,29 @@
1
+ # Glyph
2
+
3
+ `NuGlyph` is the reusable icon primitive for small UI symbols.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <NuGlyph name="window-close" />
9
+ <NuGlyph name="dropdown-arrow" />
10
+ ```
11
+
12
+ ## Key Props
13
+
14
+ - `name: NuGlyphName`
15
+ - standard `span` props such as `className`
16
+
17
+ ## Current Glyph Set
18
+
19
+ - `check-fill`
20
+ - `dropdown-arrow`
21
+ - `window-close`
22
+ - `window-maximize`
23
+ - `window-minimize`
24
+ - `window-resize`
25
+ - `window-restore`
26
+
27
+ ## Notes
28
+
29
+ - New control-specific symbols should be added here instead of being redrawn ad hoc in component styles.
package/docs/Info.md ADDED
@@ -0,0 +1,51 @@
1
+ # Info
2
+
3
+ `Info` is a lightweight fill-container for informational copy. It does not add window chrome or borders; it pairs with `InfoAccent` for inline highlighted fragments.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <Info>
9
+ Hello, you must <InfoAccent>Accept</InfoAccent> the rules before continuing.
10
+ </Info>
11
+ ```
12
+
13
+ Custom accent:
14
+
15
+ ```tsx
16
+ <Info accentColor="#ffffff">
17
+ Current profile: <InfoAccent>DEFAULT.NU</InfoAccent>
18
+ </Info>
19
+ ```
20
+
21
+ Formatting flags:
22
+
23
+ ```tsx
24
+ <Info>
25
+ For bar
26
+ <InfoAccent bold italic underline upper>
27
+ baz
28
+ </InfoAccent>
29
+ HelloWorld
30
+ </Info>
31
+ ```
32
+
33
+ ## Key Props
34
+
35
+ - `fill?: boolean`
36
+ - `accentColor?: CSSProperties["color"]`
37
+ - standard `div` props such as `className`, `style`, `children`
38
+
39
+ `InfoAccent` props:
40
+
41
+ - `bold?: boolean`
42
+ - `italic?: boolean`
43
+ - `underline?: boolean`
44
+ - `upper?: boolean`
45
+ - standard `span` props such as `className`, `style`, `children`
46
+
47
+ ## Notes
48
+
49
+ - `fill` defaults to `true`, so `Info` stretches with its parent container.
50
+ - `InfoAccent` is the intended inline emphasis API for `Info`.
51
+ - `accentColor` is inherited by nested `InfoAccent` fragments.
@@ -0,0 +1,35 @@
1
+ # ListBox
2
+
3
+ `ListBox` is the main scrollable selection surface for grouped or flat item collections.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <ListBox
9
+ data={groups}
10
+ selectedId={selectedId}
11
+ onItemSelect={(item) => setSelectedId(item.id ?? "")}
12
+ />
13
+ ```
14
+
15
+ ## Key Props
16
+
17
+ - `data: ListBoxGroup[]`
18
+ - `selectedId?: string`
19
+ - `onItemSelect?: (item, group) => void`
20
+ - `checkedIds?: string[]`
21
+ - `onItemCheckChange?: (item, group, checked) => void`
22
+ - `onItemDoubleClick?: (item, group) => void`
23
+ - `rightCheckBox?: boolean`
24
+ - `emptyText?: string`
25
+
26
+ ## Keyboard
27
+
28
+ - `ArrowUp` / `ArrowDown`
29
+ - `Home` / `End`
30
+ - `Enter`
31
+ - `Space` for check toggling
32
+
33
+ ## Notes
34
+
35
+ - The same data format supports both grouped and flat lists by using `category: null`.
@@ -0,0 +1,62 @@
1
+ # ListView
2
+
3
+ `ListView` renders a report-style list with columns, row selection, optional checkboxes, and per-column custom cell renderers.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ type Row = ListViewRowBase & {
9
+ name: string;
10
+ size: string;
11
+ type: string;
12
+ };
13
+
14
+ const columns: ListViewColumn<Row>[] = [
15
+ { id: "name", title: "&Name", field: "name", width: "18ch" },
16
+ { id: "type", title: "&Type", field: "type", width: "10ch" },
17
+ { id: "size", title: "&Size", field: "size", align: "end", width: "8ch" }
18
+ ];
19
+
20
+ <ListView
21
+ columns={columns}
22
+ data={rows}
23
+ activeRowId={activeRowId}
24
+ onActiveRowChange={(row) => setActiveRowId(row.id)}
25
+ selectedId={selectedId}
26
+ showCheckBox
27
+ checkedIds={checkedIds}
28
+ onRowSelect={(row) => setSelectedId(row.id)}
29
+ onRowCheckChange={(row, checked) => {}}
30
+ />;
31
+ ```
32
+
33
+ ## Key Props
34
+
35
+ - `columns`
36
+ - `data`
37
+ - `activeRowId`
38
+ - `defaultActiveRowId`
39
+ - `onActiveRowChange`
40
+ - `selectedId`
41
+ - `onRowSelect`
42
+ - `onRowDoubleClick`
43
+ - `showCheckBox`
44
+ - `checkedIds`
45
+ - `onRowCheckChange`
46
+ - `uncheckedShape`
47
+
48
+ ## Notes
49
+
50
+ - Keyboard navigation follows the same pattern as other list-like controls.
51
+ - Column titles support `&` mnemonic markup.
52
+ - A column can use `field` for simple value rendering or `renderCell` for custom content.
53
+
54
+ ## Imperative Handle
55
+
56
+ `ListView` also supports `ref` with:
57
+
58
+ - `focus()`
59
+ - `scrollToRow(rowId)`
60
+ - `activateRow(rowId)`
61
+ - `toggleRowCheck(rowId)`
62
+ - `getActiveRowId()`
@@ -0,0 +1,36 @@
1
+ # MainMenu
2
+
3
+ `MainMenu` is the classic top application menu bar with nested submenus.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <MainMenu items={menuItems} />
9
+ ```
10
+
11
+ ## Key Props
12
+
13
+ - `items: MainMenuNode[]`
14
+ - `onItemSelect?: (item) => void`
15
+
16
+ ## Menu Model
17
+
18
+ - `MainMenuItem`
19
+ - `id`
20
+ - `text`
21
+ - `hotkey?`
22
+ - `shortcut?`
23
+ - `checked?`
24
+ - `disabled?`
25
+ - `hidden?`
26
+ - `items?`
27
+ - `onSelect?`
28
+ - `MainMenuDivider`
29
+ - `id`
30
+ - `type: "divider"`
31
+
32
+ ## Notes
33
+
34
+ - Top-level dropdowns open below their root items.
35
+ - Nested submenus open to the right.
36
+ - Active and hovered items use the same black selection pattern used elsewhere in the library.
@@ -0,0 +1,124 @@
1
+ # MaskedField
2
+
3
+ `MaskedField` is a bracketed single-line input with a readable mask grammar and built-in invalid feedback.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <MaskedField
9
+ label="Dial prefix"
10
+ mask="+(D)"
11
+ defaultValue="7"
12
+ />
13
+
14
+ <MaskedField
15
+ label="Recovery code"
16
+ mask="(D3-D2-D2)"
17
+ defaultValue="1234567"
18
+ hint="Fixed literals stay inline with the mask."
19
+ />
20
+ ```
21
+
22
+ ## Key Props
23
+
24
+ - `label: string`
25
+ - `mask: string`
26
+ - `hint?: string`
27
+ - `debounceMs?: number`
28
+ - `onDebouncedChange?: (value) => void`
29
+ - `slotClassNames?` / `slotStyles?` for internal surface customization
30
+ - standard `input` props such as `value`, `defaultValue`, `onChange`, `disabled`
31
+
32
+ ## Immediate And Debounced Flow
33
+
34
+ - `onChange` stays immediate and should drive live state in the host.
35
+ - `onDebouncedChange` is optional and runs after `debounceMs`.
36
+ - If you need to show current validity right away, use your controlled `value` together with `getMaskedFieldState(mask, value)`.
37
+
38
+ ## Mask Syntax
39
+
40
+ - `D` = one digit
41
+ - `A` = one letter
42
+ - `D*` = zero or more digits
43
+ - `A*` = zero or more letters
44
+ - `D3` = exactly three digits
45
+ - `A2` = exactly two letters
46
+ - `D3+` = three or more digits
47
+ - `A4+` = four or more letters
48
+ - any other character is treated as a literal
49
+
50
+ Examples:
51
+
52
+ - `+(D)`
53
+ - `(D3)`
54
+ - `(D3-D2-D2)`
55
+ - `A3-D3`
56
+
57
+ ## Validation
58
+
59
+ - The field filters incoming text through the mask and auto-inserts literals when enough token content exists.
60
+ - If the current value is incomplete for the mask, the field turns red with yellow text.
61
+ - Empty value stays neutral, so a fresh field does not start in an error state.
62
+
63
+ ## Notes
64
+
65
+ - `MaskedField` is intentionally separate from `TextField`, so plain text inputs stay simple.
66
+ - Unbounded segments such as `D*` and `D3+` are best used as the final variable part of the mask. That keeps formatting deterministic.
67
+
68
+ ## Current Scope
69
+
70
+ For the current library stage, `MaskedField` is considered production-ready for:
71
+
72
+ - fixed masks with literals
73
+ - short operational codes
74
+ - dial prefixes
75
+ - serial-like identifiers
76
+ - numeric masks with immediate invalid feedback
77
+ - host flows where live state and debounced state are both useful
78
+
79
+ The current implementation deliberately stops short of advanced editor-like caret management.
80
+
81
+ ## Final-State Roadmap
82
+
83
+ If we continue this control toward a fuller final state, the main work areas are:
84
+
85
+ 1. Caret and selection behavior.
86
+ File: [packages/ui/src/components/MaskedField/MaskedField.tsx](/home/code4bones/Devs/coding/ReactNU/packages/ui/src/components/MaskedField/MaskedField.tsx)
87
+ This is where cursor preservation, middle-of-string edits, backspace-over-literals, and paste normalization should be finished.
88
+
89
+ 2. Mask grammar and formatting engine.
90
+ File: [packages/ui/src/components/MaskedField/textMask.ts](/home/code4bones/Devs/coding/ReactNU/packages/ui/src/components/MaskedField/textMask.ts)
91
+ This is the place to extend token kinds, add richer rules like hex/alnum/upper/lower, or tighten behavior for unbounded segments.
92
+
93
+ 3. Public state contract.
94
+ Files:
95
+ [packages/ui/src/components/MaskedField/MaskedField.tsx](/home/code4bones/Devs/coding/ReactNU/packages/ui/src/components/MaskedField/MaskedField.tsx)
96
+ [packages/ui/src/components/MaskedField/index.ts](/home/code4bones/Devs/coding/ReactNU/packages/ui/src/components/MaskedField/index.ts)
97
+ If we need a stronger final API, this is where to add explicit exports such as `MaskedFieldState`, `onValidityChange`, or `onMaskComplete`.
98
+
99
+ 4. Visual invalid and pending states.
100
+ File: [packages/ui/src/components/MaskedField/MaskedField.less](/home/code4bones/Devs/coding/ReactNU/packages/ui/src/components/MaskedField/MaskedField.less)
101
+ This is the right place for any future visual split between `pending`, `invalid`, and `complete`, or for adding a dedicated state marker.
102
+
103
+ 5. Real usage regression coverage.
104
+ File: [apps/sandbox/src/DemoApp.tsx](/home/code4bones/Devs/coding/ReactNU/apps/sandbox/src/DemoApp.tsx)
105
+ The dedicated `Masked Field` demo window should stay the proving ground for new mask forms, paste flows, and live host-state scenarios.
106
+
107
+ ## Recommended Next Improvements
108
+
109
+ These are the best-practice upgrades worth doing later, but not required right now:
110
+
111
+ - preserve caret position during reformatting
112
+ - add `onValidityChange`
113
+ - add `onMaskComplete`
114
+ - export a typed `MaskedFieldState`
115
+ - introduce richer token families only when a real use case appears
116
+
117
+ ## Non-Goals For Now
118
+
119
+ These are intentionally out of scope for the current version:
120
+
121
+ - regex-style masks
122
+ - full parser-expression language
123
+ - locale-aware date/number semantics
124
+ - aggressive auto-correction beyond the current readable token model
package/docs/Memo.md ADDED
@@ -0,0 +1,32 @@
1
+ # Memo
2
+
3
+ `Memo` renders an editable multiline text area that fills its parent by default.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <Memo
9
+ content={`Operator note:
10
+ Check drive map before running repair.`}
11
+ />
12
+ ```
13
+
14
+ ## Key Props
15
+
16
+ - `content?: string`
17
+ - `value?: string`
18
+ - `defaultValue?: string`
19
+ - `onValueChange?: (value: string) => void`
20
+ - `fill?: boolean`
21
+ - `scroll?: "auto" | "x" | "y" | "both" | "hidden"`
22
+ - `background?: CSSProperties["background"]`
23
+ - `focusBackground?: CSSProperties["background"]`
24
+ - `focusTextColor?: CSSProperties["color"]`
25
+ - `textColor?: CSSProperties["color"]`
26
+
27
+ ## Notes
28
+
29
+ - `Memo` uses a native `textarea` and preserves line breaks.
30
+ - By default it uses a sand-colored background and black text.
31
+ - `content` works as convenient initial text for uncontrolled usage.
32
+ - Focus colors are configurable and default to the same surface colors unless overridden.
@@ -0,0 +1,28 @@
1
+ # NuAppHostProvider
2
+
3
+ `NuAppHostProvider` owns the application-level main menu state.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <NuAppHostProvider>
9
+ <NuDesktop appBar={<AppBar />}>
10
+ <App />
11
+ </NuDesktop>
12
+ </NuAppHostProvider>
13
+ ```
14
+
15
+ ## Related API
16
+
17
+ Use `useAppHostMenu()` to access:
18
+
19
+ - `mainMenu`
20
+ - `setMainMenu(...)`
21
+ - `setMenuFlags(id, flags)`
22
+ - `setMenuItem(id, patch)`
23
+ - `setSubmenuTree(id, items)`
24
+
25
+ ## Notes
26
+
27
+ - `NuDesktop` expects to live inside this provider.
28
+ - The app host menu layer also receives the MDI bridge used by the `mdi.host` menu slot.