@estiva-app/ui 0.53.1 → 0.55.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/dist/BlockHandle.d.ts +47 -0
- package/dist/BlockHandle.d.ts.map +1 -0
- package/dist/EditorBlockHandle.d.ts +57 -0
- package/dist/EditorBlockHandle.d.ts.map +1 -0
- package/dist/NavItem.d.ts +14 -1
- package/dist/NavItem.d.ts.map +1 -1
- package/dist/NavTree.d.ts +93 -13
- package/dist/NavTree.d.ts.map +1 -1
- package/dist/UnreadDot.d.ts +12 -0
- package/dist/UnreadDot.d.ts.map +1 -0
- package/dist/editor.d.ts +1 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +127 -11
- package/dist/editor.js.map +4 -4
- package/dist/eslint/index.js +1 -1
- package/dist/eslint/index.js.map +2 -2
- package/dist/eslint/no-native-title.d.ts +1 -1
- package/dist/eslint/no-native-title.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +801 -584
- package/dist/index.js.map +4 -4
- package/dist/looks.d.ts +1 -1
- package/dist/looks.d.ts.map +1 -1
- package/package.json +1 -1
- package/registry.json +362 -11
- package/src/BlockHandle.mdx +58 -0
- package/src/BlockHandle.stories.tsx +44 -0
- package/src/BlockHandle.test.tsx +216 -0
- package/src/BlockHandle.tsx +220 -0
- package/src/EditorBlockHandle.mdx +65 -0
- package/src/EditorBlockHandle.stories.tsx +81 -0
- package/src/EditorBlockHandle.tsx +181 -0
- package/src/NavItem.mdx +14 -1
- package/src/NavItem.stories.tsx +15 -0
- package/src/NavItem.test.tsx +31 -0
- package/src/NavItem.tsx +49 -12
- package/src/NavTree.mdx +25 -0
- package/src/NavTree.stories.tsx +57 -1
- package/src/NavTree.test.tsx +78 -1
- package/src/NavTree.tsx +175 -40
- package/src/SectionLabel.stories.tsx +2 -3
- package/src/UnreadDot.mdx +57 -0
- package/src/UnreadDot.stories.tsx +22 -0
- package/src/UnreadDot.test.tsx +17 -0
- package/src/UnreadDot.tsx +17 -0
- package/src/editor.ts +1 -0
- package/src/eslint/no-native-title.ts +1 -1
- package/src/index.ts +3 -1
- package/src/looks.ts +2 -1
- package/src/registry/registry.test.ts +5 -5
- package/stories/Choosing.mdx +3 -0
- package/tailwind-preset.js +1 -0
- package/tokens.css +5 -0
package/dist/looks.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export declare const CHIP_TEXT_CLASSES = "text-chip signal:font-mono signal:text
|
|
|
34
34
|
/** Words typed straight into an input with no box of its own: SearchInput and ChipInput. */
|
|
35
35
|
export declare const BARE_INPUT_CLASSES = "bg-transparent text-text-primary placeholder:text-text-muted outline-none";
|
|
36
36
|
/** A sidebar row's shape and its words at rest, brightening under the pointer: NavItem, and SectionHeader's `row` (a folder among rows). */
|
|
37
|
-
export declare const SIDEBAR_ROW_CLASSES = "rounded-
|
|
37
|
+
export declare const SIDEBAR_ROW_CLASSES = "rounded-lg transition-colors";
|
|
38
38
|
export declare const SIDEBAR_ROW_TEXT_CLASSES = "text-text-secondary hover:text-text-primary";
|
|
39
39
|
/**
|
|
40
40
|
* A panel that slides open and shut on Base UI's Collapsible: Base UI measures
|
package/dist/looks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"looks.d.ts","sourceRoot":"","sources":["../src/looks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,2MAA2M,CAAA;AAEzO,wFAAwF;AACxF,eAAO,MAAM,kBAAkB,kDAAkD,CAAA;AAEjF,mEAAmE;AACnE,eAAO,MAAM,sBAAsB,iKAAiK,CAAA;AAEpM,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,4DAA4D,CAAA;AAEjG,kJAAkJ;AAClJ,eAAO,MAAM,kBAAkB;;;CAGrB,CAAA;AAEV,qGAAqG;AACrG,eAAO,MAAM,mBAAmB,uJAAuJ,CAAA;AAEvL,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,qEAAqE,CAAA;AAE1G,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,0FAA0F,CAAA;AAExH,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,8EAA8E,CAAA;AAE7G,4IAA4I;
|
|
1
|
+
{"version":3,"file":"looks.d.ts","sourceRoot":"","sources":["../src/looks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,2MAA2M,CAAA;AAEzO,wFAAwF;AACxF,eAAO,MAAM,kBAAkB,kDAAkD,CAAA;AAEjF,mEAAmE;AACnE,eAAO,MAAM,sBAAsB,iKAAiK,CAAA;AAEpM,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,4DAA4D,CAAA;AAEjG,kJAAkJ;AAClJ,eAAO,MAAM,kBAAkB;;;CAGrB,CAAA;AAEV,qGAAqG;AACrG,eAAO,MAAM,mBAAmB,uJAAuJ,CAAA;AAEvL,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,qEAAqE,CAAA;AAE1G,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,0FAA0F,CAAA;AAExH,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,8EAA8E,CAAA;AAE7G,4IAA4I;AAE5I,eAAO,MAAM,mBAAmB,iCAAiC,CAAA;AACjE,eAAO,MAAM,wBAAwB,gDAAgD,CAAA;AAErF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,kLAAkL,CAAA"}
|
package/package.json
CHANGED
package/registry.json
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
"kind": "package",
|
|
5
5
|
"repo": "estiva-ui",
|
|
6
6
|
"package": "@estiva-app/ui",
|
|
7
|
-
"packageVersion": "0.
|
|
8
|
-
"exports":
|
|
9
|
-
"typeExports":
|
|
7
|
+
"packageVersion": "0.55.0",
|
|
8
|
+
"exports": 130,
|
|
9
|
+
"typeExports": 134,
|
|
10
10
|
"files": null
|
|
11
11
|
},
|
|
12
12
|
"storybook": {
|
|
@@ -458,6 +458,88 @@
|
|
|
458
458
|
"app": null,
|
|
459
459
|
"looks": []
|
|
460
460
|
},
|
|
461
|
+
{
|
|
462
|
+
"name": "blockAtY",
|
|
463
|
+
"repo": "estiva-ui",
|
|
464
|
+
"kind": "helper",
|
|
465
|
+
"importPath": "@estiva-app/ui",
|
|
466
|
+
"sourceFile": "src/BlockHandle.tsx",
|
|
467
|
+
"purpose": "The last of `blocks` whose top is at or above `y` — the gap between two blocks belongs to the one before.",
|
|
468
|
+
"purposeFrom": "comment",
|
|
469
|
+
"props": [],
|
|
470
|
+
"variants": [],
|
|
471
|
+
"ownsBehaviours": [],
|
|
472
|
+
"status": "stable",
|
|
473
|
+
"migrationStage": null,
|
|
474
|
+
"docsId": "primitives-blockhandle--docs",
|
|
475
|
+
"storyId": "primitives-blockhandle--default",
|
|
476
|
+
"docPage": null,
|
|
477
|
+
"app": null,
|
|
478
|
+
"looks": []
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
"name": "blockDropCursor",
|
|
482
|
+
"repo": "estiva-ui",
|
|
483
|
+
"kind": "helper",
|
|
484
|
+
"importPath": "@estiva-app/ui/editor",
|
|
485
|
+
"sourceFile": "src/EditorBlockHandle.tsx",
|
|
486
|
+
"purpose": "The drop line a dragged block shows, in the package's accent instead of the editor's default (the text's colour).",
|
|
487
|
+
"purposeFrom": "comment",
|
|
488
|
+
"props": [],
|
|
489
|
+
"variants": [],
|
|
490
|
+
"ownsBehaviours": [],
|
|
491
|
+
"status": "stable",
|
|
492
|
+
"migrationStage": null,
|
|
493
|
+
"docsId": "primitives-editorblockhandle--docs",
|
|
494
|
+
"storyId": "primitives-editorblockhandle--default",
|
|
495
|
+
"docPage": null,
|
|
496
|
+
"app": null,
|
|
497
|
+
"looks": []
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"name": "BlockHandle",
|
|
501
|
+
"repo": "estiva-ui",
|
|
502
|
+
"kind": "component",
|
|
503
|
+
"importPath": "@estiva-app/ui",
|
|
504
|
+
"sourceFile": "src/BlockHandle.tsx",
|
|
505
|
+
"purpose": "The handle left of the block under the pointer, as a block-document page has it, and the block's menu behind it.",
|
|
506
|
+
"purposeFrom": "page",
|
|
507
|
+
"props": [
|
|
508
|
+
{
|
|
509
|
+
"name": "actions",
|
|
510
|
+
"takes": "a handler",
|
|
511
|
+
"required": false,
|
|
512
|
+
"note": "The caller's own rows — a link to the block, a comment on it."
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
"name": "editing",
|
|
516
|
+
"takes": "BlockHandleEditing",
|
|
517
|
+
"required": false,
|
|
518
|
+
"note": "Given by `EditorBlockHandle` (from `@estiva-app/ui/editor`)."
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
"name": "children",
|
|
522
|
+
"takes": "anything",
|
|
523
|
+
"required": true,
|
|
524
|
+
"note": "What the blocks are drawn in. Reading: a surface whose top-level elements carry `data-block-id`, as `RichText` draws."
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
"name": "className",
|
|
528
|
+
"takes": "text",
|
|
529
|
+
"required": false,
|
|
530
|
+
"note": null
|
|
531
|
+
}
|
|
532
|
+
],
|
|
533
|
+
"variants": [],
|
|
534
|
+
"ownsBehaviours": [],
|
|
535
|
+
"status": "stable",
|
|
536
|
+
"migrationStage": null,
|
|
537
|
+
"docsId": "primitives-blockhandle--docs",
|
|
538
|
+
"storyId": "primitives-blockhandle--default",
|
|
539
|
+
"docPage": "src/BlockHandle.mdx",
|
|
540
|
+
"app": null,
|
|
541
|
+
"looks": []
|
|
542
|
+
},
|
|
461
543
|
{
|
|
462
544
|
"name": "BlockId",
|
|
463
545
|
"repo": "estiva-ui",
|
|
@@ -1691,6 +1773,25 @@
|
|
|
1691
1773
|
"app": null,
|
|
1692
1774
|
"looks": []
|
|
1693
1775
|
},
|
|
1776
|
+
{
|
|
1777
|
+
"name": "deleteBlock",
|
|
1778
|
+
"repo": "estiva-ui",
|
|
1779
|
+
"kind": "helper",
|
|
1780
|
+
"importPath": "@estiva-app/ui/editor",
|
|
1781
|
+
"sourceFile": "src/EditorBlockHandle.tsx",
|
|
1782
|
+
"purpose": "Removes the block, the caret where it was.",
|
|
1783
|
+
"purposeFrom": "comment",
|
|
1784
|
+
"props": [],
|
|
1785
|
+
"variants": [],
|
|
1786
|
+
"ownsBehaviours": [],
|
|
1787
|
+
"status": "stable",
|
|
1788
|
+
"migrationStage": null,
|
|
1789
|
+
"docsId": "primitives-editorblockhandle--docs",
|
|
1790
|
+
"storyId": "primitives-editorblockhandle--default",
|
|
1791
|
+
"docPage": null,
|
|
1792
|
+
"app": null,
|
|
1793
|
+
"looks": []
|
|
1794
|
+
},
|
|
1694
1795
|
{
|
|
1695
1796
|
"name": "DialogShell",
|
|
1696
1797
|
"repo": "estiva-ui",
|
|
@@ -1864,6 +1965,25 @@
|
|
|
1864
1965
|
"app": null,
|
|
1865
1966
|
"looks": []
|
|
1866
1967
|
},
|
|
1968
|
+
{
|
|
1969
|
+
"name": "duplicateBlock",
|
|
1970
|
+
"repo": "estiva-ui",
|
|
1971
|
+
"kind": "helper",
|
|
1972
|
+
"importPath": "@estiva-app/ui/editor",
|
|
1973
|
+
"sourceFile": "src/EditorBlockHandle.tsx",
|
|
1974
|
+
"purpose": "A copy of the block straight after it, the caret in the copy.",
|
|
1975
|
+
"purposeFrom": "comment",
|
|
1976
|
+
"props": [],
|
|
1977
|
+
"variants": [],
|
|
1978
|
+
"ownsBehaviours": [],
|
|
1979
|
+
"status": "stable",
|
|
1980
|
+
"migrationStage": null,
|
|
1981
|
+
"docsId": "primitives-editorblockhandle--docs",
|
|
1982
|
+
"storyId": "primitives-editorblockhandle--default",
|
|
1983
|
+
"docPage": null,
|
|
1984
|
+
"app": null,
|
|
1985
|
+
"looks": []
|
|
1986
|
+
},
|
|
1867
1987
|
{
|
|
1868
1988
|
"name": "EditableText",
|
|
1869
1989
|
"repo": "estiva-ui",
|
|
@@ -1951,6 +2071,56 @@
|
|
|
1951
2071
|
"rounded-md border border-transparent text-left transition-colors hover:border-border-default"
|
|
1952
2072
|
]
|
|
1953
2073
|
},
|
|
2074
|
+
{
|
|
2075
|
+
"name": "EditorBlockHandle",
|
|
2076
|
+
"repo": "estiva-ui",
|
|
2077
|
+
"kind": "component",
|
|
2078
|
+
"importPath": "@estiva-app/ui/editor",
|
|
2079
|
+
"sourceFile": "src/EditorBlockHandle.tsx",
|
|
2080
|
+
"purpose": "`BlockHandle` in a Tiptap editor: drag the handle to move the block, press it for Turn into, Duplicate and Delete, then the app's rows.",
|
|
2081
|
+
"purposeFrom": "page",
|
|
2082
|
+
"props": [
|
|
2083
|
+
{
|
|
2084
|
+
"name": "editor",
|
|
2085
|
+
"takes": "Editor | null",
|
|
2086
|
+
"required": true,
|
|
2087
|
+
"note": "The editor. Not editable, or not there yet, and the handle reads: the caller's rows only."
|
|
2088
|
+
},
|
|
2089
|
+
{
|
|
2090
|
+
"name": "turnInto",
|
|
2091
|
+
"takes": "readonly BlockTurnInto[]",
|
|
2092
|
+
"required": false,
|
|
2093
|
+
"note": "Turn into's rows. Offered for a block of text — a paragraph, a heading, code."
|
|
2094
|
+
},
|
|
2095
|
+
{
|
|
2096
|
+
"name": "actions",
|
|
2097
|
+
"takes": "a handler",
|
|
2098
|
+
"required": false,
|
|
2099
|
+
"note": "The caller's own rows, after the editing ones."
|
|
2100
|
+
},
|
|
2101
|
+
{
|
|
2102
|
+
"name": "children",
|
|
2103
|
+
"takes": "anything",
|
|
2104
|
+
"required": true,
|
|
2105
|
+
"note": "The `EditorContent`."
|
|
2106
|
+
},
|
|
2107
|
+
{
|
|
2108
|
+
"name": "className",
|
|
2109
|
+
"takes": "text",
|
|
2110
|
+
"required": false,
|
|
2111
|
+
"note": null
|
|
2112
|
+
}
|
|
2113
|
+
],
|
|
2114
|
+
"variants": [],
|
|
2115
|
+
"ownsBehaviours": [],
|
|
2116
|
+
"status": "stable",
|
|
2117
|
+
"migrationStage": null,
|
|
2118
|
+
"docsId": "primitives-editorblockhandle--docs",
|
|
2119
|
+
"storyId": "primitives-editorblockhandle--default",
|
|
2120
|
+
"docPage": "src/EditorBlockHandle.mdx",
|
|
2121
|
+
"app": null,
|
|
2122
|
+
"looks": []
|
|
2123
|
+
},
|
|
1954
2124
|
{
|
|
1955
2125
|
"name": "EmptyState",
|
|
1956
2126
|
"repo": "estiva-ui",
|
|
@@ -3594,6 +3764,25 @@
|
|
|
3594
3764
|
"app": null,
|
|
3595
3765
|
"looks": []
|
|
3596
3766
|
},
|
|
3767
|
+
{
|
|
3768
|
+
"name": "moveBlock",
|
|
3769
|
+
"repo": "estiva-ui",
|
|
3770
|
+
"kind": "helper",
|
|
3771
|
+
"importPath": "@estiva-app/ui/editor",
|
|
3772
|
+
"sourceFile": "src/EditorBlockHandle.tsx",
|
|
3773
|
+
"purpose": "Moves the block at `from` to `to` (a position between top-level blocks), the caret in it: what a drop in the gutter does, where the editor has no drop of its own.",
|
|
3774
|
+
"purposeFrom": "comment",
|
|
3775
|
+
"props": [],
|
|
3776
|
+
"variants": [],
|
|
3777
|
+
"ownsBehaviours": [],
|
|
3778
|
+
"status": "stable",
|
|
3779
|
+
"migrationStage": null,
|
|
3780
|
+
"docsId": "primitives-editorblockhandle--docs",
|
|
3781
|
+
"storyId": "primitives-editorblockhandle--default",
|
|
3782
|
+
"docPage": null,
|
|
3783
|
+
"app": null,
|
|
3784
|
+
"looks": []
|
|
3785
|
+
},
|
|
3597
3786
|
{
|
|
3598
3787
|
"name": "NavItem",
|
|
3599
3788
|
"repo": "estiva-ui",
|
|
@@ -3657,6 +3846,18 @@
|
|
|
3657
3846
|
"required": false,
|
|
3658
3847
|
"note": "Shown only while the row is pointed at or focused, left of the count: a neutral `Chip`, typically."
|
|
3659
3848
|
},
|
|
3849
|
+
{
|
|
3850
|
+
"name": "unread",
|
|
3851
|
+
"takes": "true/false",
|
|
3852
|
+
"required": false,
|
|
3853
|
+
"note": "Something new here: brighter words, the label in medium, and the `UnreadDot` at the right."
|
|
3854
|
+
},
|
|
3855
|
+
{
|
|
3856
|
+
"name": "urgent",
|
|
3857
|
+
"takes": "true/false",
|
|
3858
|
+
"required": false,
|
|
3859
|
+
"note": "With `unread`: the warning badge in the dot's place."
|
|
3860
|
+
},
|
|
3660
3861
|
{
|
|
3661
3862
|
"name": "children",
|
|
3662
3863
|
"takes": "anything",
|
|
@@ -3702,8 +3903,9 @@
|
|
|
3702
3903
|
"docPage": "src/NavItem.mdx",
|
|
3703
3904
|
"app": null,
|
|
3704
3905
|
"looks": [
|
|
3705
|
-
"text-body-2 rounded-
|
|
3706
|
-
"text-body-2 rounded-
|
|
3906
|
+
"text-body-2 rounded-lg transition-colors bg-bg-nav-active text-text-primary",
|
|
3907
|
+
"text-body-2 rounded-lg transition-colors text-text-primary hover:bg-bg-hover",
|
|
3908
|
+
"text-body-2 rounded-lg transition-colors text-text-secondary hover:text-text-primary hover:bg-bg-hover",
|
|
3707
3909
|
"text-center font-mono text-caption tabular-nums text-text-muted",
|
|
3708
3910
|
"text-center font-mono text-caption tabular-nums text-text-muted transition-opacity",
|
|
3709
3911
|
"overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none"
|
|
@@ -3724,11 +3926,23 @@
|
|
|
3724
3926
|
"required": false,
|
|
3725
3927
|
"note": "The quiet label over the groups. Absent, none is drawn."
|
|
3726
3928
|
},
|
|
3929
|
+
{
|
|
3930
|
+
"name": "titleActions",
|
|
3931
|
+
"takes": "SectionAction[]",
|
|
3932
|
+
"required": false,
|
|
3933
|
+
"note": "Beside the label, always shown: \"New\", typically."
|
|
3934
|
+
},
|
|
3727
3935
|
{
|
|
3728
3936
|
"name": "groups",
|
|
3729
3937
|
"takes": "NavTreeGroup[] | null",
|
|
3730
|
-
"required":
|
|
3731
|
-
"note": "`null` while the first read is on its way: a skeleton in the
|
|
3938
|
+
"required": false,
|
|
3939
|
+
"note": "`null` while the first read is on its way: a skeleton in the groups' place."
|
|
3940
|
+
},
|
|
3941
|
+
{
|
|
3942
|
+
"name": "children",
|
|
3943
|
+
"takes": "anything",
|
|
3944
|
+
"required": false,
|
|
3945
|
+
"note": "The groups, drawn by the app: `NavTreeSection`s with `NavItem` rows — for an app whose groups and rows each read their own data."
|
|
3732
3946
|
},
|
|
3733
3947
|
{
|
|
3734
3948
|
"name": "selected",
|
|
@@ -3745,8 +3959,8 @@
|
|
|
3745
3959
|
{
|
|
3746
3960
|
"name": "emptyMessage",
|
|
3747
3961
|
"takes": "text",
|
|
3748
|
-
"required":
|
|
3749
|
-
"note": "What to say when
|
|
3962
|
+
"required": false,
|
|
3963
|
+
"note": "What to say when `groups` is empty. The words are the caller's; absent, nothing is said."
|
|
3750
3964
|
},
|
|
3751
3965
|
{
|
|
3752
3966
|
"name": "storageKey",
|
|
@@ -3765,6 +3979,98 @@
|
|
|
3765
3979
|
"app": null,
|
|
3766
3980
|
"looks": []
|
|
3767
3981
|
},
|
|
3982
|
+
{
|
|
3983
|
+
"name": "NavTreeSection",
|
|
3984
|
+
"repo": "estiva-ui",
|
|
3985
|
+
"kind": "component",
|
|
3986
|
+
"importPath": "@estiva-app/ui",
|
|
3987
|
+
"sourceFile": "src/NavTree.tsx",
|
|
3988
|
+
"purpose": "One group of a `NavTree`, for an app that draws its own: the standard heading folding its rows, lightly indented under its title, with the group's line, skeleton, actions and `onIntent`.",
|
|
3989
|
+
"purposeFrom": "comment",
|
|
3990
|
+
"props": [
|
|
3991
|
+
{
|
|
3992
|
+
"name": "title",
|
|
3993
|
+
"takes": "text",
|
|
3994
|
+
"required": true,
|
|
3995
|
+
"note": null
|
|
3996
|
+
},
|
|
3997
|
+
{
|
|
3998
|
+
"name": "id",
|
|
3999
|
+
"takes": "text",
|
|
4000
|
+
"required": false,
|
|
4001
|
+
"note": "Marks the group's box as `data-nav-group`, for tests and photo runs to find it."
|
|
4002
|
+
},
|
|
4003
|
+
{
|
|
4004
|
+
"name": "message",
|
|
4005
|
+
"takes": "text",
|
|
4006
|
+
"required": false,
|
|
4007
|
+
"note": "Said in the rows' place, level with them."
|
|
4008
|
+
},
|
|
4009
|
+
{
|
|
4010
|
+
"name": "trailing",
|
|
4011
|
+
"takes": "anything",
|
|
4012
|
+
"required": false,
|
|
4013
|
+
"note": "Beside the title, always shown: an `UnreadDot`, typically."
|
|
4014
|
+
},
|
|
4015
|
+
{
|
|
4016
|
+
"name": "actions",
|
|
4017
|
+
"takes": "SectionAction[]",
|
|
4018
|
+
"required": false,
|
|
4019
|
+
"note": "Beside the title, shown on hover or focus: \"Open\", typically."
|
|
4020
|
+
},
|
|
4021
|
+
{
|
|
4022
|
+
"name": "defaultOpen",
|
|
4023
|
+
"takes": "true/false",
|
|
4024
|
+
"required": false,
|
|
4025
|
+
"note": "Open unless told otherwise."
|
|
4026
|
+
},
|
|
4027
|
+
{
|
|
4028
|
+
"name": "open",
|
|
4029
|
+
"takes": "true/false",
|
|
4030
|
+
"required": false,
|
|
4031
|
+
"note": "The caller owns whether the group is open."
|
|
4032
|
+
},
|
|
4033
|
+
{
|
|
4034
|
+
"name": "onOpenChange",
|
|
4035
|
+
"takes": "a handler",
|
|
4036
|
+
"required": false,
|
|
4037
|
+
"note": null
|
|
4038
|
+
},
|
|
4039
|
+
{
|
|
4040
|
+
"name": "onIntent",
|
|
4041
|
+
"takes": "a handler",
|
|
4042
|
+
"required": false,
|
|
4043
|
+
"note": "The pointer rests on the group, or the keyboard reaches it: read its rows now."
|
|
4044
|
+
},
|
|
4045
|
+
{
|
|
4046
|
+
"name": "loading",
|
|
4047
|
+
"takes": "true/false",
|
|
4048
|
+
"required": false,
|
|
4049
|
+
"note": "Its rows are being read: a skeleton in their place."
|
|
4050
|
+
},
|
|
4051
|
+
{
|
|
4052
|
+
"name": "storageKey",
|
|
4053
|
+
"takes": "text",
|
|
4054
|
+
"required": false,
|
|
4055
|
+
"note": "Remember it open or closed in this browser, under this key."
|
|
4056
|
+
},
|
|
4057
|
+
{
|
|
4058
|
+
"name": "children",
|
|
4059
|
+
"takes": "anything",
|
|
4060
|
+
"required": false,
|
|
4061
|
+
"note": "The rows: `NavItem`s."
|
|
4062
|
+
}
|
|
4063
|
+
],
|
|
4064
|
+
"variants": [],
|
|
4065
|
+
"ownsBehaviours": [],
|
|
4066
|
+
"status": "stable",
|
|
4067
|
+
"migrationStage": null,
|
|
4068
|
+
"docsId": "frame-navtree--docs",
|
|
4069
|
+
"storyId": "frame-navtree--default",
|
|
4070
|
+
"docPage": null,
|
|
4071
|
+
"app": null,
|
|
4072
|
+
"looks": []
|
|
4073
|
+
},
|
|
3768
4074
|
{
|
|
3769
4075
|
"name": "normalizeHref",
|
|
3770
4076
|
"repo": "estiva-ui",
|
|
@@ -4979,8 +5285,8 @@
|
|
|
4979
5285
|
"app": null,
|
|
4980
5286
|
"looks": [
|
|
4981
5287
|
"transition-transform duration-150 text-text-secondary rotate-90",
|
|
4982
|
-
"rounded-
|
|
4983
|
-
"rounded-
|
|
5288
|
+
"rounded-lg transition-colors text-text-secondary hover:text-text-primary",
|
|
5289
|
+
"rounded-lg transition-colors text-text-secondary hover:text-text-primary hover:bg-bg-hover",
|
|
4984
5290
|
"-mr-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100",
|
|
4985
5291
|
"opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
|
|
4986
5292
|
]
|
|
@@ -5415,6 +5721,25 @@
|
|
|
5415
5721
|
"app": null,
|
|
5416
5722
|
"looks": []
|
|
5417
5723
|
},
|
|
5724
|
+
{
|
|
5725
|
+
"name": "startBlockDrag",
|
|
5726
|
+
"repo": "estiva-ui",
|
|
5727
|
+
"kind": "helper",
|
|
5728
|
+
"importPath": "@estiva-app/ui/editor",
|
|
5729
|
+
"sourceFile": "src/EditorBlockHandle.tsx",
|
|
5730
|
+
"purpose": "Starts the browser's own drag of the block, as ProseMirror starts one of a selected node: the block selected, its slice on `view.dragging` with `move`, and its HTML on the transfer.",
|
|
5731
|
+
"purposeFrom": "comment",
|
|
5732
|
+
"props": [],
|
|
5733
|
+
"variants": [],
|
|
5734
|
+
"ownsBehaviours": [],
|
|
5735
|
+
"status": "stable",
|
|
5736
|
+
"migrationStage": null,
|
|
5737
|
+
"docsId": "primitives-editorblockhandle--docs",
|
|
5738
|
+
"storyId": "primitives-editorblockhandle--default",
|
|
5739
|
+
"docPage": null,
|
|
5740
|
+
"app": null,
|
|
5741
|
+
"looks": []
|
|
5742
|
+
},
|
|
5418
5743
|
{
|
|
5419
5744
|
"name": "SuggestionMenu",
|
|
5420
5745
|
"repo": "estiva-ui",
|
|
@@ -6472,6 +6797,32 @@
|
|
|
6472
6797
|
"app": null,
|
|
6473
6798
|
"looks": []
|
|
6474
6799
|
},
|
|
6800
|
+
{
|
|
6801
|
+
"name": "UnreadDot",
|
|
6802
|
+
"repo": "estiva-ui",
|
|
6803
|
+
"kind": "component",
|
|
6804
|
+
"importPath": "@estiva-app/ui",
|
|
6805
|
+
"sourceFile": "src/UnreadDot.tsx",
|
|
6806
|
+
"purpose": "The accent dot that says \"something new here\": a 6px disc centred in a 24px slot, so it sits exactly where a control would and the row does not shift when one replaces the other.",
|
|
6807
|
+
"purposeFrom": "page",
|
|
6808
|
+
"props": [
|
|
6809
|
+
{
|
|
6810
|
+
"name": "className",
|
|
6811
|
+
"takes": "text",
|
|
6812
|
+
"required": false,
|
|
6813
|
+
"note": null
|
|
6814
|
+
}
|
|
6815
|
+
],
|
|
6816
|
+
"variants": [],
|
|
6817
|
+
"ownsBehaviours": [],
|
|
6818
|
+
"status": "stable",
|
|
6819
|
+
"migrationStage": null,
|
|
6820
|
+
"docsId": "primitives-unreaddot--docs",
|
|
6821
|
+
"storyId": "primitives-unreaddot--default",
|
|
6822
|
+
"docPage": "src/UnreadDot.mdx",
|
|
6823
|
+
"app": null,
|
|
6824
|
+
"looks": []
|
|
6825
|
+
},
|
|
6475
6826
|
{
|
|
6476
6827
|
"name": "UrgentPersonMention",
|
|
6477
6828
|
"repo": "estiva-ui",
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Meta, Canvas } from '@storybook/addon-docs/blocks'
|
|
2
|
+
import * as BlockHandleStories from './BlockHandle.stories'
|
|
3
|
+
|
|
4
|
+
<Meta of={BlockHandleStories} />
|
|
5
|
+
|
|
6
|
+
# BlockHandle
|
|
7
|
+
|
|
8
|
+
The handle left of the block under the pointer, as a block-document page has
|
|
9
|
+
it, and the block's menu behind it. Over a document being read, the menu is
|
|
10
|
+
the app's rows only — a link to the block, a comment on it.
|
|
11
|
+
|
|
12
|
+
<Canvas of={BlockHandleStories.Default} />
|
|
13
|
+
|
|
14
|
+
## When
|
|
15
|
+
|
|
16
|
+
- **A document made of blocks, read by someone who cannot edit it**, when the
|
|
17
|
+
app has something to offer on one block: a link to it, a comment on it.
|
|
18
|
+
|
|
19
|
+
## When not
|
|
20
|
+
|
|
21
|
+
- The same document being edited → **EditorBlockHandle**, from
|
|
22
|
+
`@estiva-app/ui/editor`: the same handle, which also drags and has Turn
|
|
23
|
+
into, Duplicate and Delete.
|
|
24
|
+
- Reading a document with nothing to offer on one block → **RichText** alone.
|
|
25
|
+
|
|
26
|
+
## How
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { BlockHandle, MenuItem, RichText, type HandleBlock, type RichTextBlock } from '@estiva-app/ui'
|
|
30
|
+
|
|
31
|
+
const blocks: RichTextBlock[] = [{ type: 'paragraph', id: 'b1', inline: [{ text: 'Label', marks: [] }] }]
|
|
32
|
+
const rows = (block: HandleBlock) => <MenuItem label="Copy link" onClick={() => navigator.clipboard.writeText(`#${block.id}`)} />
|
|
33
|
+
|
|
34
|
+
<BlockHandle actions={rows}>
|
|
35
|
+
<RichText blocks={blocks} />
|
|
36
|
+
</BlockHandle>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- **Leave room on the left.** The handle sits 28px left of the content, in
|
|
40
|
+
the page's margin, so wrapping the content moves nothing. A surface flush
|
|
41
|
+
with its container's left edge clips it.
|
|
42
|
+
- `children` is a surface whose top-level elements carry `data-block-id`, as
|
|
43
|
+
`RichText` draws them. `HandleBlock.id` is that §13.3 id: what a link or a
|
|
44
|
+
comment addresses.
|
|
45
|
+
- With no `actions`, or `actions` that return nothing for a block, no handle
|
|
46
|
+
is drawn.
|
|
47
|
+
- **In the main entry on purpose**: a reader must not download an editor.
|
|
48
|
+
`editing` is how `EditorBlockHandle` makes this part edit, not a prop to
|
|
49
|
+
fill by hand.
|
|
50
|
+
|
|
51
|
+
## What it owns
|
|
52
|
+
|
|
53
|
+
It does these by itself. Write none of them around it.
|
|
54
|
+
|
|
55
|
+
| It does | So you never write | Refused when written by hand |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| Finds the block under the pointer, by height: the gap between two blocks belongs to the one above | a pointer handler on each block | |
|
|
58
|
+
| Centres the handle on the block's first line, a heading's or a paragraph's | a position for the handle | |
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
|
+
import { IconLink, IconMessage } from '@tabler/icons-react'
|
|
3
|
+
import { BlockHandle, type HandleBlock } from './BlockHandle'
|
|
4
|
+
import { MenuItem } from './Menu'
|
|
5
|
+
import { RichText, type RichTextBlock } from './RichText'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The handle left of the block under the pointer, over a document being read:
|
|
9
|
+
* press it for the app's rows. In an editor, `EditorBlockHandle` adds the drag
|
|
10
|
+
* and the editing rows.
|
|
11
|
+
*/
|
|
12
|
+
const meta = {
|
|
13
|
+
title: 'Primitives/BlockHandle',
|
|
14
|
+
// The handle sits 28px left of the content, in the page's margin.
|
|
15
|
+
parameters: { layout: 'padded' },
|
|
16
|
+
} satisfies Meta
|
|
17
|
+
|
|
18
|
+
export default meta
|
|
19
|
+
type Story = StoryObj
|
|
20
|
+
|
|
21
|
+
/** The rows an app adds: here they only say which block they were pressed on. */
|
|
22
|
+
function rows(block: HandleBlock) {
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<MenuItem label="Copy link" leading={<IconLink size={16} stroke={1.5} className="text-text-secondary" />} onClick={() => console.info('copy link', block.id)} />
|
|
26
|
+
<MenuItem label="Comment" leading={<IconMessage size={16} stroke={1.5} className="text-text-secondary" />} onClick={() => console.info('comment', block.id)} />
|
|
27
|
+
</>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const READING: RichTextBlock[] = [
|
|
32
|
+
{ type: 'heading', level: 1, id: 'b1', inline: [{ text: 'A heading', marks: [] }] },
|
|
33
|
+
{ type: 'paragraph', id: 'b2', inline: [{ text: 'Someone who cannot edit this still gets the handle, with the app’s rows only.', marks: [] }] },
|
|
34
|
+
{ type: 'paragraph', id: 'b3', inline: [{ text: 'The second paragraph.', marks: [] }] },
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
/** Reading: no drag and no editing rows — only what the app adds. */
|
|
38
|
+
export const Default: Story = {
|
|
39
|
+
render: () => (
|
|
40
|
+
<BlockHandle actions={rows} className="ml-8 max-w-[560px]">
|
|
41
|
+
<RichText blocks={READING} />
|
|
42
|
+
</BlockHandle>
|
|
43
|
+
),
|
|
44
|
+
}
|