docblocks-react-ui 0.1.1 → 0.2.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,175 @@
1
1
  # docblocks-react-ui
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - bcc306e: The `Editor`'s page view is now the motion row layer (the former
8
+ `MotionEditor`'s merge): every page block is its own `Reorder.Item` row —
9
+ the drag-reorder (one drag = one range move of the dragged block's
10
+ derived subtree), the insert/remove's layout animation, the rendered
11
+ list marker per row. Consumers rendering `<Editor>` get the animated,
12
+ draggable page without a code change; the `view` / `formatPalette` props
13
+ stand. The `MotionEditor` export and the `./motion` subpath are removed
14
+ (the base `Editor` is the motion editor — the previous split stood the
15
+ base entry without any reorder path, so a consumer taking it got a
16
+ non-reorderable editor).
17
+
18
+ The three peers are now REQUIRED (pre-1.0 breaking): `framer-motion`
19
+ (the page view's row layer), `mermaid` (the `./mermaid` subpath), and
20
+ `pdfjs-dist` (the `./pdf` subpath) lose their `optional: true` — the
21
+ install must carry all of them. The `./mermaid` and `./pdf` subpaths'
22
+ wiring stays opt-in (the `pdfPreview` prop / the `code` block renderer);
23
+ the required peers guarantee availability only. The static row rendering
24
+ stands for the table cells and the canvas's page miniature (the
25
+ `BlockGroups`'s stand); the `BlockView`/`BlockNodeView` renderers are
26
+ unchanged.
27
+ - d62b662: The editor's UI strings stand localized (en + ru). The language is
28
+ consumer-driven: the package reads the `<html lang>` attribute (the `ru*`
29
+ prefix stands the Russian stand; the absent or unknown language falls
30
+ back to English) and follows the attribute's change at runtime. There is
31
+ no `locale` prop.
32
+
33
+ The package runs its own `i18next` instance over the shipped catalogs —
34
+ `i18next` and `react-i18next` are new runtime dependencies — under the
35
+ `EditorProvider`'s subtree (and the consumer-placed `DocHeader`): the
36
+ consumer's global `i18next` singleton stands untouched, and the editor's
37
+ `useTranslation` never conflicts with it. The English's values keep the
38
+ former's literals as-is (the zero visual diff over the English's
39
+ language).
40
+
41
+ Not localized (the technical stand): the code language's names, the font
42
+ family's and weight's names, the avatar emoji picker's accessible names,
43
+ and the technical glyphs. Parameterized strings use the `{param}`
44
+ interpolation (the single braces' stand).
45
+ - 0e798be: The page row's delete affordance: the hover's trash icon at the row's
46
+ right edge (every page type — the text rows' own wrapper, the non-text
47
+ rows' row-level stand over the motion view; the edit's mode only).
48
+ The deletion was previously discoverable only through the less obvious
49
+ path (the gutter's select + the Delete key). The click is a true
50
+ deletion (the Delete key's image special case — the in-place conversion
51
+ to an empty paragraph — stands for the key gesture only), the row's
52
+ whole blocks selection is deleted when the row is part of one (the
53
+ Delete key's gesture parity), and the gesture stands the document
54
+ root's trailing-paragraph guarantee + the focus's parking as the Delete
55
+ key's path (the focus never drops to the document).
56
+ - 74e0abd: Add the standalone's database's surface (the consumer's own page, not a
57
+ document block): the `DatabaseTable` component (the live grid over the
58
+ bridge's table id — the same `useDatabaseTable`'s data stand as the
59
+ document block) + the `useTableList` hook (the `listTables`'s catalog
60
+ read + the `createTable` / `renameTable` mutations over the fresh's
61
+ `operationId` per op; the catalog's auto-refresh stands over the own's
62
+ successful mutations + the manual's `refresh`). The `DatabaseTable`'s
63
+ view's settings (`filter`, the `columnOrder`, the `hiddenColumns`, the
64
+ `columnWidths`) stand the internal's state seeded from the optional
65
+ `view` prop + persisted over the `onViewChange`'s patch callback (the
66
+ controlled's mode stands absent — one patch per change, as the block's
67
+ `updateBlock` stand). The `readOnly`'s stand gates the editing's paths
68
+ (the block's read-only's parity). The grid's `GridBody` stands extracted
69
+ from the document's context (the view's attrs' write is the callback's
70
+ stand — the block's wrapper keeps one `updateBlock` per change, no
71
+ behavior's diff).
72
+
73
+ ### Patch Changes
74
+
75
+ - a89733e: The external-form database's history and boundary stands:
76
+
77
+ - the undo / redo's in-flight window — a forward write that commits while
78
+ the undo's inverse (or the redo's forward) is in flight stands the
79
+ history's invariants: the undo's path consumes the undone op (popped from
80
+ the undo stack, not moved to the redo stack — the fresh write cleared the
81
+ redo side, and the re-commit over the newer entry would clobber it), and
82
+ the redo's path re-enters the op on the undo stack at the call's position
83
+ (below the window's writes, not on top — the undo order's inversion is
84
+ closed, the first undo reverts the newest write).
85
+ - the operation's rejections stand the structured `BridgeError` (the code's
86
+ retry / the clear's decision stands the first-class property, not the
87
+ `cause`'s dig): a rejection that carries no machine code stands the
88
+ transport-level `unavailable` (the safe recovery is the same-operationId's
89
+ reconciliation, not a blind new operation).
90
+ - the cell-value equality stands the element-wise comparison over the
91
+ composite value (the multi-select's array) — the identity stand committed
92
+ the no-op over the same content and pushed the undo entry.
93
+ - the enum's options catalog stands the full page set (the cursor's
94
+ continuation to the tail) over the single page's `limit: 200` — the
95
+ truncated catalog over 200 options stood the silent-ignored delete of the
96
+ truncated option over the commit's diff.
97
+ - the column form's commit failures stand the logged error + the catalog's
98
+ re-read (the partial stand over the move's second commit), the silent
99
+ catches are gone.
100
+ - ff90f80: The external-form database stand's hardening: the bridge tables' picker
101
+ guards the `listTables` rejection (the unhandled rejection stands the
102
+ logged error + the empty list stand), and the hook's undo / redo drops
103
+ the replaced entry by identity (the in-flight inverse over the history's
104
+ mutation no longer drops the fresh entry — the double-apply and the
105
+ stale restore are closed). The database JSDoc stands the actual
106
+ contract: the mixed paste's description is self-contained, and the lost
107
+ response's reconciliation is the consumer's stand over the bridge's
108
+ `getOperationStatus` (the UI's convergence is the rebaseline).
109
+ - 590f5e7: The editor root's focus-ring stand: the root is a focus park (the
110
+ drag's release and the gutter's delete park the focus there so the
111
+ keyboard's input stays scoped over the editor) and is reached
112
+ programmatically only (tabIndex -1) — the browser's default focus ring
113
+ stood the visible ring over the whole document after a drag's release.
114
+ The ring is suppressed (`outline: none` on the focused root); the focus
115
+ itself stays, and the individual controls keep their own focus styles.
116
+ - a1564a2: The embed and frame's render stands:
117
+
118
+ - the sync-embed's stale's dynamic stand — the ref's block removed from the
119
+ master over the embed's mount now stands the broken's transition (the
120
+ master's change re-stands the block to the render-time's check; the
121
+ master's undo of the removal stands the resolved's back stand).
122
+ - the canvas frame's window references stand memoized (the frame's drag
123
+ re-renders the frame on every pointermove — the fresh array / Set
124
+ references broke the window's copies' memo and re-rendered every copy
125
+ over the drag's pass; the page-frame block's window stands the same
126
+ stand).
127
+ - the pdf worker's asset stands the degradation's signal: the unreachable
128
+ worker's asset (the bundler's rewritten reference, the hosting's dropped
129
+ asset) stands the logged warning over the silent native-viewer's
130
+ fallback.
131
+ - the `docblocks-core`'s peer range stands `^0.1.0` (the required peer's
132
+ version stand over the `*` — the packages stand lockstep over the 0.x
133
+ case, the breaking core's minor stands the range's bump over the same
134
+ release).
135
+ - ecb2a91: The paste's markdown link re-gate stands the mid-string control's
136
+ degrade: an href with a tab / LF / CR between the scheme's letters
137
+ (`java<tab>script:…`) no longer passes the gate — the check runs over
138
+ the WHATWG URL parser's full input normalization (the control is
139
+ removed from any position before the scheme detection, the browser's
140
+ parity). The run degrades to plain text over the unsafe href (the core's
141
+ gate is the single stand; this package's mirror passes it through).
142
+ - d162a1a: The paste surface's hardening: the markdown paste's link stand re-checks
143
+ the href over the core's public `isSafeLinkHref` itself at both the raw
144
+ parse and the entity-decode pass (the trimmed form — the browser trims
145
+ the leading C0 controls before the scheme detection, so the parser's
146
+ mirror stands the writer's contract: the `<a href>` tag, the exposed
147
+ entity's scheme, and the entity-hidden leading C0 degrade the run to
148
+ plain text instead of aborting the multi-block paste over the core's
149
+ strict mark rejection); and the clipboard's HTML serializes the mark
150
+ values escaped (the hostile remote data's stand — the attribute break
151
+ over the third-party paste target is closed).
152
+ - f907ee1: The editor store and the flat page derivation stand the registry's
153
+ own-property lookups (the `constructor`, `toString`, ... names are
154
+ unknown types, not the inherited `Object.prototype` members): a hostile
155
+ type named by a prototype key stands absent in the page sequence (the
156
+ cross-minor's stand — no renderer lookup over the inherited member, no
157
+ render-error stand, the data preserved in the export), and the seed and
158
+ the diff share one reader's posture (the store's filter and the
159
+ `getBlock`'s own-property stand agree on the block's presence).
160
+ - ab836e5: The selector's escape stand: the three block-content lookups (the range
161
+ extend's target, the gesture's stale-restore focus, the format
162
+ toolbar's type-change exclude) build the `data-block-id` selector over
163
+ `CSS.escape` — the full parity with the package's other lookup points,
164
+ where a crafted block id (a quote / bracket) would otherwise stand a
165
+ `SyntaxError` from `querySelector` in the keyboard / gesture handlers.
166
+ - Updated dependencies [bf92634]
167
+ - Updated dependencies [b66e45e]
168
+ - Updated dependencies [c5a38d2]
169
+ - Updated dependencies [769c12a]
170
+ - Updated dependencies [72fdfd3]
171
+ - docblocks-core@0.1.2
172
+
3
173
  ## 0.1.1
4
174
 
5
175
  ### Patch Changes
package/README.md CHANGED
@@ -12,11 +12,14 @@ package renders the document and provides the editing surface
12
12
  npm i docblocks-react-ui docblocks-core
13
13
  ```
14
14
 
15
- Peer dependencies: `docblocks-core`, `react` (19), `react-dom`. Optional
16
- peers, used only by their subpaths: `framer-motion` (`./motion`), `mermaid`
17
- (`./mermaid`), `pdfjs-dist` (`./pdf`). The package's own runtime dependencies
18
- (zustand, the Radix primitives, the shared ui runtime set) are declared, so
19
- a plain `npm i` is the whole install.
15
+ Peer dependencies: `docblocks-core`, `react` (19), `react-dom`, and the
16
+ required peers `framer-motion` (the Editor's page view is the motion row
17
+ layer — the drag-reorder + the layout animations), `mermaid` (the
18
+ `./mermaid` subpath's renderer), and `pdfjs-dist` (the `./pdf` subpath's
19
+ preview) — the install must carry all of them (npm enforces the required
20
+ peers). The package's own runtime dependencies (zustand, the Radix
21
+ primitives, the shared ui runtime set) are declared, so a plain `npm i`
22
+ is the whole install.
20
23
 
21
24
  The package is ESM-only (`import`, not `require`); it stands Node
22
25
  `^22.22.2 || ^24.15.0 || >=26.0.0` (the `engines` field).
@@ -334,6 +337,49 @@ package root: `BridgeError` (the structured error type) with
334
337
  `isDatabaseBridge`, and `useDatabaseTable(bridge, tableId, filter?)` — the
335
338
  grid controller for a consumer-owned grid over the bridge.
336
339
 
340
+ ### Standalone database table
341
+
342
+ The database's UI stands outside any document as well — the
343
+ consumer-owned "tables section" (the user's tables management, not a
344
+ document block). The package ships the composable primitives; the
345
+ consumer assembles its own section (the list / the UX) over
346
+ `useTableList` and embeds the ready grid over the picked table:
347
+
348
+ ```tsx
349
+ import { DatabaseTable, useTableList } from "docblocks-react-ui";
350
+
351
+ function TablesSection({ bridge }: { bridge: DatabaseBridge }) {
352
+ const list = useTableList(bridge);
353
+ const [selectedId, setSelectedId] = useState<string | null>(null);
354
+ return (
355
+ <div>
356
+ {list.tables?.map((table) => (
357
+ <button key={table.id} onClick={() => setSelectedId(table.id)}>
358
+ {table.name}
359
+ </button>
360
+ ))}
361
+ {selectedId !== null && <DatabaseTable bridge={bridge} tableId={selectedId} />}
362
+ </div>
363
+ );
364
+ }
365
+ ```
366
+
367
+ - `DatabaseTable({ bridge, tableId, readOnly?, view?, onViewChange? })` —
368
+ the live grid over the bridge's table id (the same data stand as the
369
+ document block: the schema, the rows, the live events, the optimistic
370
+ cell layer). The view's settings (`filter`, `columnOrder`,
371
+ `hiddenColumns`, `columnWidths`) stand the internal state (seeded from
372
+ the optional `view` prop at mount); `onViewChange(patch)` receives one
373
+ patch per change for the consumer's persistence (the controlled mode
374
+ stands absent — the state is never external). `readOnly` gates the
375
+ editing's paths (the read-only block's parity).
376
+ - `useTableList(bridge)` — `{ tables, loading, error, refresh, create,
377
+ rename }`: the `listTables` catalog (the system tables stand out), the
378
+ `createTable` / `renameTable` mutations (the fresh `operationId` per op;
379
+ they reject with the `BridgeError`), and the catalog's re-read —
380
+ automatic over the hook's own successful mutations + manual over
381
+ `refresh` (the contract's catalog stands no push channel).
382
+
337
383
  ### Sync-embed
338
384
 
339
385
  A `sync-embed` block references another document by an opaque ref. The
@@ -382,7 +428,7 @@ const blockRenderers: BlockRendererMap = {
382
428
 
383
429
  `pdfPreview` is a component that renders a `pdf`-subtype image block's
384
430
  resolved blob as a client-side first-page preview. The `./pdf` subpath
385
- provides one over `pdfjs-dist` (an optional peer):
431
+ provides one over `pdfjs-dist` (a required peer):
386
432
 
387
433
  ```tsx
388
434
  import { PdfFirstPage } from "docblocks-react-ui/pdf";
@@ -432,6 +478,25 @@ insert menu, the drag / resize / nudge / fit / draw sessions) or
432
478
  programmatically through the core's block commands. The viewport's zoom
433
479
  and pan are view state — they never reach the document.
434
480
 
481
+ ### Localization
482
+
483
+ The editor's UI strings ship localized (en + ru). The language is
484
+ consumer-driven — the package reads the `<html lang>` attribute (the `ru*`
485
+ prefix stands the Russian stand; the absent / unknown language falls back
486
+ to English) and follows the attribute's change at runtime (the editor
487
+ re-renders over the flip). There is no `locale` prop — the document's
488
+ language is the consumer's, set on `<html>`.
489
+
490
+ The package runs its **own** `i18next` instance (the shipped catalogs,
491
+ `i18next` + `react-i18next` are runtime dependencies) under the
492
+ `EditorProvider`'s subtree — a consumer's global `i18next` singleton stands
493
+ untouched, and the editor's `useTranslation` never leaks into (or out of)
494
+ the consumer's setup.
495
+
496
+ Not localized (the technical stand): the code language names, the font
497
+ family / weight names, the avatar emoji picker's accessible names, and the
498
+ technical glyphs.
499
+
435
500
  ### Subtree view
436
501
 
437
502
  `rootBlockId` renders the entry list of one block instead of the document
@@ -474,8 +539,10 @@ value actually changes (the store's reference-stability contract):
474
539
  | `view` | `"page"` (default) or `"canvas"` — the rendering the consumer switches |
475
540
  | `formatPalette` | The format toolbar's color swatches (default `FORMAT_PALETTE`, exported) |
476
541
 
477
- `MotionEditor` (the `./motion` subpath) accepts the same props and adds the
478
- layout animations and drag-reorder (requires `framer-motion`).
542
+ The page view renders the flat page sequence — every page block is its
543
+ own row (the drag-reorder's pure framer `Reorder`, the insert/remove's
544
+ layout animation, the rendered list marker per row) — over the required
545
+ `framer-motion` peer.
479
546
 
480
547
  ## Subpath exports
481
548
 
@@ -484,12 +551,13 @@ layout animations and drag-reorder (requires `framer-motion`).
484
551
  | `docblocks-react-ui` | The editor, the provider, the hooks, the primitives (the entry) |
485
552
  | `docblocks-react-ui/styles.css` | The compiled stylesheet: the utility layer + the token seed + the `--docblocks-*` mapping + the structural rules |
486
553
  | `docblocks-react-ui/theme.css` | The pure token seed (standard tokens + the radius scale), no utility layer |
487
- | `docblocks-react-ui/motion` | `MotionEditor` (layout animations, insert/remove, drag-reorder; peer: `framer-motion`) |
488
554
  | `docblocks-react-ui/mermaid` | The `mermaid` renderer above `code { language: "mermaid" }` blocks (peer: `mermaid`) |
489
555
  | `docblocks-react-ui/pdf` | `PdfFirstPage` (the first-page preview over `pdfjs-dist`; the worker is copied to `dist/pdf/` at build time) |
490
556
 
491
- The base entry imports none of the optional peers, so consumers who skip a
492
- subpath ship no extra weight.
557
+ The `./mermaid` and `./pdf` subpaths' wiring is opt-in (the `pdfPreview`
558
+ prop / the `code` block renderer): a consumer who skips a subpath imports
559
+ nothing of its module. The peers themselves are required installs (the
560
+ page view's framer import included).
493
561
 
494
562
  ## Theming
495
563