@deadragdoll/reactnu 0.1.74 → 0.1.76

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.
@@ -39,6 +39,11 @@ export type NuManagedWindowDefinition = {
39
39
  style?: CSSProperties;
40
40
  titleButtons?: WindowTitleButtonDefinition[];
41
41
  title: string;
42
+ /**
43
+ * Persists this managed window's geometry and minimized/maximized state in
44
+ * localStorage. The key is scoped to `reactnu.window.`.
45
+ */
46
+ windowStoreKey?: string;
42
47
  };
43
48
  export type NuManagedWindowControls = {
44
49
  bringToFront: () => void;
@@ -46,8 +46,11 @@ See: [Slot Customization](./SLOT_CUSTOMIZATION.md)
46
46
  - `useNuIconManager()`
47
47
  manages icons inside a `NuIconProvider`
48
48
  - `useNuDragDrop()`
49
- internal integration hook for custom shared drag sources and targets; most
49
+ returns the underlying react-dnd manager for advanced integration; most
50
50
  applications should use component props from [Shared Drag and Drop](./NuDragDropProvider.md)
51
+ - `useNuDropTarget(element, options)`
52
+ registers a custom target and returns reactive `isOver`, `canDrop`, and item
53
+ state; docs: [NuDragDropProvider](./NuDragDropProvider.md)
51
54
  - `usePopupMenu()`
52
55
  anchor/open helper for `PopupMenu`
53
56
  - `useWindowMenu()`
@@ -96,8 +99,8 @@ See: [Slot Customization](./SLOT_CUSTOMIZATION.md)
96
99
  docs: [ListView](./ListView.md)
97
100
  - `TreeView`
98
101
  docs: [TreeView](./TreeView.md)
99
- - `TreeListView`, `TreeTable`
100
- docs: [TreeListView](./TreeListView.md), [TreeTable](./TreeTable.md)
102
+ - `TreeListView`
103
+ docs: [TreeListView](./TreeListView.md)
101
104
  - Shared drag-and-drop contract
102
105
  docs: [NuDragDropProvider](./NuDragDropProvider.md)
103
106
 
@@ -126,6 +126,8 @@ The host owns:
126
126
 
127
127
  Managed windows can persist geometry with:
128
128
 
129
+ - `windowStoreKey?: string` for automatic browser-local persistence under
130
+ `reactnu.window.<key>`
129
131
  - `onOpen?: () => NuManagedWindowSnapshot | void`
130
132
  - `onClose?: (snapshot) => boolean | void`
131
133
 
@@ -42,7 +42,6 @@
42
42
  - [TickBar](./TickBar.md)
43
43
  - [ToolBar](./ToolBar.md)
44
44
  - [TreeListView](./TreeListView.md)
45
- - [TreeTable](./TreeTable.md)
46
45
  - [TreeView](./TreeView.md)
47
46
  - [NuView](./NuView.md)
48
47
  - [Window](./Window.md)
@@ -49,7 +49,7 @@ export function App() {
49
49
  ## Recommended Order
50
50
 
51
51
  1. `NuThemeProvider`
52
- 2. `NuDragDropProvider` when ListBox, TreeListView, or IconGrid need to exchange items
52
+ 2. `NuDragDropProvider` when ListBox, ListView, TreeListView, or IconGrid need to exchange items
53
53
  3. `NuDesktop`
54
54
  3. host-driven `appBar`
55
55
  4. workspace content
package/docs/IconGrid.md CHANGED
@@ -72,10 +72,10 @@ function Applications() {
72
72
  `onIconMoveOut(icon, context)` runs on the source after a successful transfer.
73
73
  `context` exposes both managers, grids, and the target `position`.
74
74
  - Within `NuDragDropProvider`, use `acceptsDrop(item)` and `onDrop(item,
75
- context)` to accept application-defined items from `ListBox` or
76
- `TreeListView`. `onDragOut(item)` runs when an icon is accepted by one of
77
- those non-icon targets. The existing `accepts(icon)` API remains specific to
78
- icon-to-icon transfers.
75
+ context)` to accept application-defined items from `ListBox`, `ListView`, or
76
+ `TreeListView`. Return `{ action: "copy" }` from that target's `onDrop`, or
77
+ return `false` from `onDragOut(item, result)`, to retain the source icon.
78
+ The existing `accepts(icon)` API remains specific to icon-to-icon transfers.
79
79
 
80
80
  `useNuIconManager()`
81
81
 
package/docs/ListBox.md CHANGED
@@ -22,6 +22,7 @@
22
22
  - `onItemDoubleClick?: (item, group) => void`
23
23
  - `onPopupMenu?: (event, item, group) => void`
24
24
  - `getDragItem?: (item, group) => NuDragDropItem | false`
25
+ - `renderDragPreview?: (item, group) => ReactNode`
25
26
  - `onItemDragOut?: (item, group) => void`
26
27
  - `acceptsDrop?: (item) => boolean`
27
28
  - `onDrop?: (item, context) => boolean | void`
@@ -44,3 +45,5 @@
44
45
  - Inside `NuDragDropProvider`, `getDragItem` makes rows draggable. The
45
46
  application decides accepted data in `acceptsDrop` and updates its collection
46
47
  in `onDrop` / `onItemDragOut`.
48
+ - `renderDragPreview(item, group)` may render a compact React preview instead
49
+ of the full list row while dragging.
package/docs/ListView.md CHANGED
@@ -40,6 +40,11 @@ const columns: ListViewColumn<Row>[] = [
40
40
  - `selectedId`
41
41
  - `onRowSelect`
42
42
  - `onRowDoubleClick`
43
+ - `getDragItem`
44
+ - `onRowDragOut`
45
+ - `acceptsDrop`
46
+ - `onDrop`
47
+ - `renderDragPreview`
43
48
  - `showCheckBox`
44
49
  - `checkedIds`
45
50
  - `onRowCheckChange`
@@ -50,6 +55,11 @@ const columns: ListViewColumn<Row>[] = [
50
55
  - Keyboard navigation follows the same pattern as other list-like controls.
51
56
  - Column titles support `&` mnemonic markup.
52
57
  - A column can use `field` for simple value rendering or `renderCell` for custom content.
58
+ - `getDragItem(row)` makes a row a shared drag source. `onRowDragOut(row)` runs
59
+ after another target accepts it; `acceptsDrop` and `onDrop` make the list a
60
+ target. Wrap related controls in `NuDragDropProvider`.
61
+ - `renderDragPreview(row)` can return a compact React node, rather than using
62
+ the complete report row as the native drag preview.
53
63
 
54
64
  ## Imperative Handle
55
65
 
@@ -1,8 +1,9 @@
1
1
  # NuDragDropProvider
2
2
 
3
- `NuDragDropProvider` coordinates pointer drag-and-drop between `NuIconGrid`,
4
- `ListBox`, and `TreeListView`. It carries an application-defined item; it does
5
- not mutate the host application's list or tree data.
3
+ `NuDragDropProvider` coordinates native HTML5 drag-and-drop between
4
+ `NuIconGrid`, `ListBox`, `ListView`, and `TreeListView`. It is implemented on
5
+ top of `react-dnd`; it carries an application-defined item and does not mutate
6
+ host list or tree data.
6
7
 
7
8
  ```tsx
8
9
  <NuDragDropProvider>
@@ -34,10 +35,42 @@ not mutate the host application's list or tree data.
34
35
  perform its own state update. Returning `false` rejects the transfer.
35
36
  - `onItemDragOut` / `onDragOut` run only after a target accepted the item;
36
37
  remove or update the source data there.
38
+ - A target may return `{ action: "copy" }` from `onDrop`. `NuIconGrid` then
39
+ leaves its source icon in place; `{ action: "move" }` is the default. List
40
+ and tree sources always leave source-data mutation to their host callback.
41
+ - `renderDragPreview` on `ListBox`, `ListView`, and `TreeListView` renders a
42
+ compact React preview instead of the browser's full-row preview.
37
43
  - `NuIconGrid` keeps `accepts(icon)`, `onIconDrop`, and `onIconMoveOut` for
38
44
  its existing icon-to-icon transfer. Its `acceptsDrop` and `onDrop` receive
39
45
  non-icon shared drag items.
40
46
 
41
- Wrap every source and target that should interact in the same provider. A
42
- fallback coordinator preserves existing unwrapped IconGrid transfers, but a
43
- provider gives the application an explicit DnD scope.
47
+ Wrap a workspace once when sources and targets must interact. The controls can
48
+ also mount independently, but one provider gives cross-control dragging and a
49
+ single custom-preview layer an explicit scope.
50
+
51
+ ## Hover feedback
52
+
53
+ `useNuDropTarget(element, options)` returns reactive `{ isOver, canDrop, item
54
+ }` state. Use it in a custom target to render classic accept/reject feedback;
55
+ `onDragEnter(item, canDrop)` and `onDragLeave(item)` are available when a
56
+ callback fits better.
57
+
58
+ ```tsx
59
+ const [element, setElement] = useState<HTMLDivElement | null>(null);
60
+ const dropState = useNuDropTarget(element, {
61
+ accepts: (item) => item.type === "receiver",
62
+ onDrop: (item) => {
63
+ assignReceiver(item.data);
64
+ },
65
+ type: "receiver-group"
66
+ });
67
+
68
+ <div
69
+ className={dropState.isOver && dropState.canDrop ? "group group--accept" : "group"}
70
+ ref={setElement}
71
+ />;
72
+ ```
73
+
74
+ `NuIconGrid dropTarget` additionally registers a bounded desktop fallback, so
75
+ an icon grid behind managed windows can accept an item dropped anywhere inside
76
+ its own bounds without intercepting normal pointer interaction.
@@ -29,7 +29,26 @@ Use `useNuWindowManager()` to access:
29
29
 
30
30
  ## Managed Window Persistence
31
31
 
32
- `NuManagedWindowDefinition` also supports:
32
+ Set `windowStoreKey` to persist a managed window's last position, size, and
33
+ minimized/maximized state automatically. ReactNU stores the snapshot in
34
+ `localStorage` as `reactnu.window.<key>`. Use a stable, unique key for each
35
+ logical window; re-opening that window with the same key restores its saved
36
+ geometry.
37
+
38
+ ```tsx
39
+ windowManager.openWindow({
40
+ content: <Inspector />,
41
+ title: "Inspector",
42
+ windowStoreKey: "workspace.inspector"
43
+ });
44
+ ```
45
+
46
+ Browser storage is optional: malformed or unavailable storage is ignored.
47
+ `onOpen` remains the explicit override for applications that restore state
48
+ from their own storage, and `onClose` still receives the current snapshot.
49
+ Clear `reactnu.window.workspace.inspector` to reset this example.
50
+
51
+ For host-owned persistence, `NuManagedWindowDefinition` also supports:
33
52
 
34
53
  - `onOpen?: () => NuManagedWindowSnapshot | void`
35
54
  - `onClose?: (snapshot: NuManagedWindowSnapshot) => boolean | void`
@@ -58,6 +58,7 @@ const columns: TreeListColumn<Node>[] = [
58
58
  - `onItemDoubleClick`
59
59
  - `onPopupMenu`
60
60
  - `getDragItem`
61
+ - `renderDragPreview`
61
62
  - `onItemDragOut`
62
63
  - `acceptsDrop`
63
64
  - `onDrop`
@@ -99,3 +100,5 @@ const columns: TreeListColumn<Node>[] = [
99
100
  - Inside `NuDragDropProvider`, rows may produce shared drag items through
100
101
  `getDragItem`; the host filters and applies incoming items with
101
102
  `acceptsDrop` and `onDrop`.
103
+ - `renderDragPreview(item, context)` may return a compact React preview, such
104
+ as a name chip, instead of the complete multi-column row.
package/docs/Window.md CHANGED
@@ -56,6 +56,10 @@ to `useNuWindowManager().openWindow(...)`; it is resolved by
56
56
  `NuWindowProvider`, rather than by a standalone `Window` instance. See
57
57
  [NuWindowProvider](./NuWindowProvider.md#linked-activation).
58
58
 
59
+ `windowStoreKey?: string` is also available on a managed window definition.
60
+ It automatically restores and saves that window's geometry in browser storage;
61
+ see [NuWindowProvider](./NuWindowProvider.md#managed-window-persistence).
62
+
59
63
  ## Notes
60
64
 
61
65
  - Drag and resize are implemented with pointer events and local DOM updates for smoother motion.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deadragdoll/reactnu",
3
- "version": "0.1.74",
3
+ "version": "0.1.76",
4
4
  "private": false,
5
5
  "description": "React components with a precise DOS-era utility interface.",
6
6
  "license": "MIT",
@@ -51,5 +51,9 @@
51
51
  "peerDependencies": {
52
52
  "react": "^19.2.0",
53
53
  "react-dom": "^19.2.0"
54
+ },
55
+ "dependencies": {
56
+ "react-dnd": "^16.0.1",
57
+ "react-dnd-html5-backend": "^16.0.1"
54
58
  }
55
59
  }
package/docs/TreeTable.md DELETED
@@ -1,21 +0,0 @@
1
- # TreeTable
2
-
3
- `TreeTable` is the semantic name for `TreeListView` when it is used as a
4
- hierarchical report table. It is the same component and accepts the same props,
5
- including tree navigation, report cells, drag-and-drop, and column resizing.
6
-
7
- ## Usage
8
-
9
- ```tsx
10
- <TreeTable
11
- columnStoreKey="workspace-files"
12
- columns={columns}
13
- data={nodes}
14
- />
15
- ```
16
-
17
- `columnStoreKey="workspace-files"` persists user-resized widths as JSON in
18
- `localStorage` under `reactnu.workspace-files`. Only widths changed by the user
19
- are stored. Invalid or unavailable storage is ignored safely.
20
-
21
- For the full API, see [TreeListView](./TreeListView.md).