@estiva-app/ui 0.50.4 → 0.52.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.
Files changed (51) hide show
  1. package/dist/CollapsibleSection.d.ts +7 -1
  2. package/dist/CollapsibleSection.d.ts.map +1 -1
  3. package/dist/ComposerTriggers.d.ts +169 -0
  4. package/dist/ComposerTriggers.d.ts.map +1 -0
  5. package/dist/NavItem.d.ts +23 -3
  6. package/dist/NavItem.d.ts.map +1 -1
  7. package/dist/NavTree.d.ts +49 -0
  8. package/dist/NavTree.d.ts.map +1 -0
  9. package/dist/SectionLabel.d.ts +7 -1
  10. package/dist/SectionLabel.d.ts.map +1 -1
  11. package/dist/editor.d.ts +1 -0
  12. package/dist/editor.d.ts.map +1 -1
  13. package/dist/editor.js +313 -12
  14. package/dist/editor.js.map +4 -4
  15. package/dist/eslint/index.js +1 -1
  16. package/dist/eslint/index.js.map +2 -2
  17. package/dist/eslint/no-native-title.d.ts +1 -1
  18. package/dist/eslint/no-native-title.d.ts.map +1 -1
  19. package/dist/index.d.ts +1 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +332 -212
  22. package/dist/index.js.map +4 -4
  23. package/dist/looks.d.ts +7 -0
  24. package/dist/looks.d.ts.map +1 -1
  25. package/package.json +6 -1
  26. package/registry.json +426 -5
  27. package/src/CollapsibleSection.mdx +6 -0
  28. package/src/CollapsibleSection.stories.tsx +5 -0
  29. package/src/CollapsibleSection.tsx +12 -4
  30. package/src/ComposerTriggers.mdx +108 -0
  31. package/src/ComposerTriggers.stories.tsx +79 -0
  32. package/src/ComposerTriggers.test.tsx +207 -0
  33. package/src/ComposerTriggers.tsx +507 -0
  34. package/src/NavItem.mdx +30 -0
  35. package/src/NavItem.stories.tsx +34 -0
  36. package/src/NavItem.test.tsx +82 -0
  37. package/src/NavItem.tsx +123 -25
  38. package/src/NavTree.mdx +83 -0
  39. package/src/NavTree.stories.tsx +84 -0
  40. package/src/NavTree.test.tsx +54 -0
  41. package/src/NavTree.tsx +112 -0
  42. package/src/SectionHeader.tsx +1 -1
  43. package/src/SectionLabel.mdx +4 -1
  44. package/src/SectionLabel.stories.tsx +3 -0
  45. package/src/SectionLabel.tsx +10 -2
  46. package/src/editor.ts +29 -0
  47. package/src/eslint/no-native-title.ts +1 -1
  48. package/src/index.ts +1 -0
  49. package/src/looks.ts +8 -0
  50. package/src/registry/registry.test.ts +9 -8
  51. package/stories/Choosing.mdx +2 -0
package/dist/looks.d.ts CHANGED
@@ -36,4 +36,11 @@ export declare const BARE_INPUT_CLASSES = "bg-transparent text-text-primary plac
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
37
  export declare const SIDEBAR_ROW_CLASSES = "rounded-md transition-colors";
38
38
  export declare const SIDEBAR_ROW_TEXT_CLASSES = "text-text-secondary hover:text-text-primary";
39
+ /**
40
+ * A panel that slides open and shut on Base UI's Collapsible: Base UI measures
41
+ * it and writes its height to a variable, `auto` again once the slide ends, and
42
+ * the panel is 0 high on its opening and closing frames. None under
43
+ * prefers-reduced-motion. CollapsibleSection's rows, and the rows under a NavItem.
44
+ */
45
+ export declare const COLLAPSIBLE_PANEL_CLASSES = "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0";
39
46
  //# sourceMappingURL=looks.d.ts.map
@@ -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;AAC5I,eAAO,MAAM,mBAAmB,iCAAiC,CAAA;AACjE,eAAO,MAAM,wBAAwB,gDAAgD,CAAA"}
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;AAC5I,eAAO,MAAM,mBAAmB,iCAAiC,CAAA;AACjE,eAAO,MAAM,wBAAwB,gDAAgD,CAAA;AAErF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,kLAAkL,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@estiva-app/ui",
3
- "version": "0.50.4",
3
+ "version": "0.52.0",
4
4
  "description": "Estiva's design tokens (the contract) and a small set of primitives (a convenience) for every Estiva app.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -88,6 +88,7 @@
88
88
  "eslint-plugin-better-tailwindcss": "^4.7.0",
89
89
  "typescript-eslint": "^8.0.0",
90
90
  "@tiptap/core": "^3.22.1",
91
+ "@tiptap/extension-mention": "^3.22.1",
91
92
  "@tiptap/pm": "^3.22.1",
92
93
  "@tiptap/react": "^3.22.1",
93
94
  "@tiptap/suggestion": "^3.22.1"
@@ -105,6 +106,9 @@
105
106
  "@tiptap/core": {
106
107
  "optional": true
107
108
  },
109
+ "@tiptap/extension-mention": {
110
+ "optional": true
111
+ },
108
112
  "@tiptap/pm": {
109
113
  "optional": true
110
114
  },
@@ -126,6 +130,7 @@
126
130
  "@testing-library/react": "^16.3.3",
127
131
  "@testing-library/user-event": "^14.6.7",
128
132
  "@tiptap/core": "^3.31.3",
133
+ "@tiptap/extension-mention": "^3.31.3",
129
134
  "@tiptap/pm": "^3.31.3",
130
135
  "@tiptap/react": "^3.31.3",
131
136
  "@tiptap/starter-kit": "^3.31.3",
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.50.4",
8
- "exports": 104,
9
- "typeExports": 113,
7
+ "packageVersion": "0.52.0",
8
+ "exports": 120,
9
+ "typeExports": 128,
10
10
  "files": null
11
11
  },
12
12
  "storybook": {
@@ -15,6 +15,25 @@
15
15
  "devUrl": "http://localhost:6008"
16
16
  },
17
17
  "entries": [
18
+ {
19
+ "name": "applyFormat",
20
+ "repo": "estiva-ui",
21
+ "kind": "helper",
22
+ "importPath": "@estiva-app/ui/editor",
23
+ "sourceFile": "src/ComposerTriggers.tsx",
24
+ "purpose": "Apply one format to the current block. `set*` wherever Tiptap has one: choosing Heading should make a heading, not turn one off.",
25
+ "purposeFrom": "comment",
26
+ "props": [],
27
+ "variants": [],
28
+ "ownsBehaviours": [],
29
+ "status": "stable",
30
+ "migrationStage": null,
31
+ "docsId": "primitives-composertriggers--docs",
32
+ "storyId": "primitives-composertriggers--default",
33
+ "docPage": null,
34
+ "app": null,
35
+ "looks": []
36
+ },
18
37
  {
19
38
  "name": "AppShell",
20
39
  "repo": "estiva-ui",
@@ -583,6 +602,25 @@
583
602
  "signal:bg-transparent signal:border signal:border-border-default signal:text-text-primary signal:shadow-none signal:hover:bg-success-muted signal:hover:border-success-outline signal:hover:text-success-default signal:transition-colors"
584
603
  ]
585
604
  },
605
+ {
606
+ "name": "CaptionedReference",
607
+ "repo": "estiva-ui",
608
+ "kind": "component",
609
+ "importPath": "@estiva-app/ui/editor",
610
+ "sourceFile": "src/ComposerTriggers.tsx",
611
+ "purpose": "A reference mid-sentence, drawn as `label: snippet` and written as its `uri` verbatim (SPEC §13.1).",
612
+ "purposeFrom": "comment",
613
+ "props": [],
614
+ "variants": [],
615
+ "ownsBehaviours": [],
616
+ "status": "stable",
617
+ "migrationStage": null,
618
+ "docsId": "primitives-composertriggers--docs",
619
+ "storyId": "primitives-composertriggers--default",
620
+ "docPage": null,
621
+ "app": null,
622
+ "looks": []
623
+ },
586
624
  {
587
625
  "name": "Card",
588
626
  "repo": "estiva-ui",
@@ -1089,6 +1127,12 @@
1089
1127
  "required": false,
1090
1128
  "note": "`heading` (default): the title is a section heading."
1091
1129
  },
1130
+ {
1131
+ "name": "indent",
1132
+ "takes": "true/false",
1133
+ "required": false,
1134
+ "note": "With the `heading` look: the rows start under the title, past the chevron — a folder in a sidebar, its files lightly indented under its name (Katerina, 2 October)."
1135
+ },
1092
1136
  {
1093
1137
  "name": "children",
1094
1138
  "takes": "anything",
@@ -2170,6 +2214,63 @@
2170
2214
  "app": null,
2171
2215
  "looks": []
2172
2216
  },
2217
+ {
2218
+ "name": "filterPeople",
2219
+ "repo": "estiva-ui",
2220
+ "kind": "helper",
2221
+ "importPath": "@estiva-app/ui/editor",
2222
+ "sourceFile": "src/ComposerTriggers.tsx",
2223
+ "purpose": "The people whose name holds the query, the first {@link PEOPLE_LIMIT} of them.",
2224
+ "purposeFrom": "comment",
2225
+ "props": [],
2226
+ "variants": [],
2227
+ "ownsBehaviours": [],
2228
+ "status": "stable",
2229
+ "migrationStage": null,
2230
+ "docsId": "primitives-composertriggers--docs",
2231
+ "storyId": "primitives-composertriggers--default",
2232
+ "docPage": null,
2233
+ "app": null,
2234
+ "looks": []
2235
+ },
2236
+ {
2237
+ "name": "filterReferences",
2238
+ "repo": "estiva-ui",
2239
+ "kind": "helper",
2240
+ "importPath": "@estiva-app/ui/editor",
2241
+ "sourceFile": "src/ComposerTriggers.tsx",
2242
+ "purpose": "The references whose label or text holds the query — the last {@link REFERENCE_LIMIT}, in the order given: a thread is unbounded, and a list that grew with it would be a hundred rows of prose.",
2243
+ "purposeFrom": "comment",
2244
+ "props": [],
2245
+ "variants": [],
2246
+ "ownsBehaviours": [],
2247
+ "status": "stable",
2248
+ "migrationStage": null,
2249
+ "docsId": "primitives-composertriggers--docs",
2250
+ "storyId": "primitives-composertriggers--default",
2251
+ "docPage": null,
2252
+ "app": null,
2253
+ "looks": []
2254
+ },
2255
+ {
2256
+ "name": "filterSlashSections",
2257
+ "repo": "estiva-ui",
2258
+ "kind": "helper",
2259
+ "importPath": "@estiva-app/ui/editor",
2260
+ "sourceFile": "src/ComposerTriggers.tsx",
2261
+ "purpose": "The sections narrowed to a query — the text typed after the `/`.",
2262
+ "purposeFrom": "comment",
2263
+ "props": [],
2264
+ "variants": [],
2265
+ "ownsBehaviours": [],
2266
+ "status": "stable",
2267
+ "migrationStage": null,
2268
+ "docsId": "primitives-composertriggers--docs",
2269
+ "storyId": "primitives-composertriggers--default",
2270
+ "docPage": null,
2271
+ "app": null,
2272
+ "looks": []
2273
+ },
2173
2274
  {
2174
2275
  "name": "Form",
2175
2276
  "repo": "estiva-ui",
@@ -2233,6 +2334,44 @@
2233
2334
  "app": null,
2234
2335
  "looks": []
2235
2336
  },
2337
+ {
2338
+ "name": "FORMATS",
2339
+ "repo": "estiva-ui",
2340
+ "kind": "helper",
2341
+ "importPath": "@estiva-app/ui/editor",
2342
+ "sourceFile": "src/ComposerTriggers.tsx",
2343
+ "purpose": "The formats `/` offers, in order. The hint is what you would type, not a key chord.",
2344
+ "purposeFrom": "comment",
2345
+ "props": [],
2346
+ "variants": [],
2347
+ "ownsBehaviours": [],
2348
+ "status": "stable",
2349
+ "migrationStage": null,
2350
+ "docsId": "primitives-composertriggers--docs",
2351
+ "storyId": "primitives-composertriggers--default",
2352
+ "docPage": null,
2353
+ "app": null,
2354
+ "looks": []
2355
+ },
2356
+ {
2357
+ "name": "formatSection",
2358
+ "repo": "estiva-ui",
2359
+ "kind": "helper",
2360
+ "importPath": "@estiva-app/ui/editor",
2361
+ "sourceFile": "src/ComposerTriggers.tsx",
2362
+ "purpose": "The Format section every app's `/` opens with.",
2363
+ "purposeFrom": "comment",
2364
+ "props": [],
2365
+ "variants": [],
2366
+ "ownsBehaviours": [],
2367
+ "status": "stable",
2368
+ "migrationStage": null,
2369
+ "docsId": "primitives-composertriggers--docs",
2370
+ "storyId": "primitives-composertriggers--default",
2371
+ "docPage": null,
2372
+ "app": null,
2373
+ "looks": []
2374
+ },
2236
2375
  {
2237
2376
  "name": "hueFor",
2238
2377
  "repo": "estiva-ui",
@@ -3512,6 +3651,36 @@
3512
3651
  "required": false,
3513
3652
  "note": "The ⋮'s accessible name and tooltip. Default \"More options for {label}\"."
3514
3653
  },
3654
+ {
3655
+ "name": "hint",
3656
+ "takes": "anything",
3657
+ "required": false,
3658
+ "note": "Shown only while the row is pointed at or focused, left of the count: a neutral `Chip`, typically."
3659
+ },
3660
+ {
3661
+ "name": "children",
3662
+ "takes": "anything",
3663
+ "required": false,
3664
+ "note": "Rows under this one, folding under it: `NavItem`s."
3665
+ },
3666
+ {
3667
+ "name": "defaultOpen",
3668
+ "takes": "true/false",
3669
+ "required": false,
3670
+ "note": "With `children`: open unless told otherwise."
3671
+ },
3672
+ {
3673
+ "name": "open",
3674
+ "takes": "true/false",
3675
+ "required": false,
3676
+ "note": "With `children`: the caller owns the state."
3677
+ },
3678
+ {
3679
+ "name": "onOpenChange",
3680
+ "takes": "a handler",
3681
+ "required": false,
3682
+ "note": null
3683
+ },
3515
3684
  {
3516
3685
  "name": "className",
3517
3686
  "takes": "text",
@@ -3520,7 +3689,12 @@
3520
3689
  }
3521
3690
  ],
3522
3691
  "variants": [],
3523
- "ownsBehaviours": [],
3692
+ "ownsBehaviours": [
3693
+ {
3694
+ "id": "base-ui",
3695
+ "behaviour": "Is built on Base UI"
3696
+ }
3697
+ ],
3524
3698
  "status": "stable",
3525
3699
  "migrationStage": null,
3526
3700
  "docsId": "frame-navitem--docs",
@@ -3531,9 +3705,66 @@
3531
3705
  "text-body-2 rounded-md transition-colors bg-bg-active text-text-primary",
3532
3706
  "text-body-2 rounded-md transition-colors text-text-secondary hover:text-text-primary hover:bg-bg-hover",
3533
3707
  "text-center font-mono text-caption tabular-nums text-text-muted",
3534
- "text-center font-mono text-caption tabular-nums text-text-muted transition-opacity"
3708
+ "text-center font-mono text-caption tabular-nums text-text-muted transition-opacity",
3709
+ "overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none"
3535
3710
  ]
3536
3711
  },
3712
+ {
3713
+ "name": "NavTree",
3714
+ "repo": "estiva-ui",
3715
+ "kind": "component",
3716
+ "importPath": "@estiva-app/ui",
3717
+ "sourceFile": "src/NavTree.tsx",
3718
+ "purpose": "A sidebar's tree from one nested list: a quiet label, groups that fold under the standard heading with their rows lightly indented, and rows under rows to any depth.",
3719
+ "purposeFrom": "page",
3720
+ "props": [
3721
+ {
3722
+ "name": "title",
3723
+ "takes": "text",
3724
+ "required": false,
3725
+ "note": "The quiet label over the groups. Absent, none is drawn."
3726
+ },
3727
+ {
3728
+ "name": "groups",
3729
+ "takes": "NavTreeGroup[] | null",
3730
+ "required": true,
3731
+ "note": "`null` while the first read is on its way: a skeleton in the rows' place."
3732
+ },
3733
+ {
3734
+ "name": "selected",
3735
+ "takes": "text",
3736
+ "required": false,
3737
+ "note": "The row that is current: `active`, and its group starts open."
3738
+ },
3739
+ {
3740
+ "name": "onSelect",
3741
+ "takes": "a handler",
3742
+ "required": false,
3743
+ "note": "A row was clicked. A router app prevents the default and navigates."
3744
+ },
3745
+ {
3746
+ "name": "emptyMessage",
3747
+ "takes": "text",
3748
+ "required": true,
3749
+ "note": "What to say when there are no groups. The words are the caller's."
3750
+ },
3751
+ {
3752
+ "name": "storageKey",
3753
+ "takes": "text",
3754
+ "required": false,
3755
+ "note": "Remember each group open or closed in this browser, under this key and the group's id."
3756
+ }
3757
+ ],
3758
+ "variants": [],
3759
+ "ownsBehaviours": [],
3760
+ "status": "stable",
3761
+ "migrationStage": null,
3762
+ "docsId": "frame-navtree--docs",
3763
+ "storyId": "frame-navtree--default",
3764
+ "docPage": "src/NavTree.mdx",
3765
+ "app": null,
3766
+ "looks": []
3767
+ },
3537
3768
  {
3538
3769
  "name": "normalizeHref",
3539
3770
  "repo": "estiva-ui",
@@ -3627,6 +3858,25 @@
3627
3858
  "app": null,
3628
3859
  "looks": []
3629
3860
  },
3861
+ {
3862
+ "name": "peopleMenu",
3863
+ "repo": "estiva-ui",
3864
+ "kind": "helper",
3865
+ "importPath": "@estiva-app/ui/editor",
3866
+ "sourceFile": "src/ComposerTriggers.tsx",
3867
+ "purpose": "The people list `@` and `!@` open: the face, the name, the second line, and the Enter hint while highlighted — `MenuItem` at its tall size.",
3868
+ "purposeFrom": "comment",
3869
+ "props": [],
3870
+ "variants": [],
3871
+ "ownsBehaviours": [],
3872
+ "status": "stable",
3873
+ "migrationStage": null,
3874
+ "docsId": "primitives-composertriggers--docs",
3875
+ "storyId": "primitives-composertriggers--default",
3876
+ "docPage": null,
3877
+ "app": null,
3878
+ "looks": []
3879
+ },
3630
3880
  {
3631
3881
  "name": "Person",
3632
3882
  "repo": "estiva-ui",
@@ -3677,6 +3927,25 @@
3677
3927
  "app": null,
3678
3928
  "looks": []
3679
3929
  },
3930
+ {
3931
+ "name": "PersonMention",
3932
+ "repo": "estiva-ui",
3933
+ "kind": "component",
3934
+ "importPath": "@estiva-app/ui/editor",
3935
+ "sourceFile": "src/ComposerTriggers.tsx",
3936
+ "purpose": "`@` — a person, as a chip that writes their key (SPEC §13.1).",
3937
+ "purposeFrom": "comment",
3938
+ "props": [],
3939
+ "variants": [],
3940
+ "ownsBehaviours": [],
3941
+ "status": "stable",
3942
+ "migrationStage": null,
3943
+ "docsId": "primitives-composertriggers--docs",
3944
+ "storyId": "primitives-composertriggers--default",
3945
+ "docPage": null,
3946
+ "app": null,
3947
+ "looks": []
3948
+ },
3680
3949
  {
3681
3950
  "name": "PersonTrigger",
3682
3951
  "repo": "estiva-ui",
@@ -4312,6 +4581,44 @@
4312
4581
  "app": null,
4313
4582
  "looks": []
4314
4583
  },
4584
+ {
4585
+ "name": "referenceMenu",
4586
+ "repo": "estiva-ui",
4587
+ "kind": "helper",
4588
+ "importPath": "@estiva-app/ui/editor",
4589
+ "sourceFile": "src/ComposerTriggers.tsx",
4590
+ "purpose": "The list `[` opens: one section of `label: snippet` rows, the same box as the people list.",
4591
+ "purposeFrom": "comment",
4592
+ "props": [
4593
+ {
4594
+ "name": "ariaLabel",
4595
+ "takes": "text",
4596
+ "required": true,
4597
+ "note": "Names the list, e.g. what can be referenced."
4598
+ },
4599
+ {
4600
+ "name": "sectionLabel",
4601
+ "takes": "text",
4602
+ "required": true,
4603
+ "note": "The section's heading."
4604
+ },
4605
+ {
4606
+ "name": "icon",
4607
+ "takes": "anything",
4608
+ "required": true,
4609
+ "note": "At each row's start: a 16px icon."
4610
+ }
4611
+ ],
4612
+ "variants": [],
4613
+ "ownsBehaviours": [],
4614
+ "status": "stable",
4615
+ "migrationStage": null,
4616
+ "docsId": "primitives-composertriggers--docs",
4617
+ "storyId": "primitives-composertriggers--default",
4618
+ "docPage": null,
4619
+ "app": null,
4620
+ "looks": []
4621
+ },
4315
4622
  {
4316
4623
  "name": "ReferenceNode",
4317
4624
  "repo": "estiva-ui",
@@ -4331,6 +4638,25 @@
4331
4638
  "app": null,
4332
4639
  "looks": []
4333
4640
  },
4641
+ {
4642
+ "name": "ReferenceTrigger",
4643
+ "repo": "estiva-ui",
4644
+ "kind": "component",
4645
+ "importPath": "@estiva-app/ui/editor",
4646
+ "sourceFile": "src/ComposerTriggers.tsx",
4647
+ "purpose": "`[` — reference something, inserted as a {@link CaptionedReference} chip.",
4648
+ "purposeFrom": "comment",
4649
+ "props": [],
4650
+ "variants": [],
4651
+ "ownsBehaviours": [],
4652
+ "status": "stable",
4653
+ "migrationStage": null,
4654
+ "docsId": "primitives-composertriggers--docs",
4655
+ "storyId": "primitives-composertriggers--default",
4656
+ "docPage": null,
4657
+ "app": null,
4658
+ "looks": []
4659
+ },
4334
4660
  {
4335
4661
  "name": "RichText",
4336
4662
  "repo": "estiva-ui",
@@ -4686,6 +5012,12 @@
4686
5012
  "required": false,
4687
5013
  "note": "Cut a long label short with an ellipsis instead of letting it wrap or spill."
4688
5014
  },
5015
+ {
5016
+ "name": "folds",
5017
+ "takes": "true/false",
5018
+ "required": false,
5019
+ "note": "The title of a group that opens and closes."
5020
+ },
4689
5021
  {
4690
5022
  "name": "className",
4691
5023
  "takes": "text",
@@ -4711,6 +5043,12 @@
4711
5043
  "docPage": "src/SectionLabel.mdx",
4712
5044
  "app": null,
4713
5045
  "looks": [
5046
+ "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest text-text-secondary",
5047
+ "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest text-text-secondary truncate",
5048
+ "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest text-text-muted",
5049
+ "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest text-text-muted truncate",
5050
+ "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest text-text-primary",
5051
+ "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest text-text-primary truncate",
4714
5052
  "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest leaf:font-mono leaf:text-small leaf:uppercase leaf:tracking-widest text-text-secondary",
4715
5053
  "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest leaf:font-mono leaf:text-small leaf:uppercase leaf:tracking-widest text-text-secondary truncate",
4716
5054
  "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest leaf:font-mono leaf:text-small leaf:uppercase leaf:tracking-widest text-text-muted",
@@ -5058,6 +5396,25 @@
5058
5396
  "app": null,
5059
5397
  "looks": []
5060
5398
  },
5399
+ {
5400
+ "name": "SlashCommands",
5401
+ "repo": "estiva-ui",
5402
+ "kind": "component",
5403
+ "importPath": "@estiva-app/ui/editor",
5404
+ "sourceFile": "src/ComposerTriggers.tsx",
5405
+ "purpose": "`/` — format the line or insert something, at the caret, mid-sentence too.",
5406
+ "purposeFrom": "comment",
5407
+ "props": [],
5408
+ "variants": [],
5409
+ "ownsBehaviours": [],
5410
+ "status": "stable",
5411
+ "migrationStage": null,
5412
+ "docsId": "primitives-composertriggers--docs",
5413
+ "storyId": "primitives-composertriggers--default",
5414
+ "docPage": null,
5415
+ "app": null,
5416
+ "looks": []
5417
+ },
5061
5418
  {
5062
5419
  "name": "SuggestionMenu",
5063
5420
  "repo": "estiva-ui",
@@ -6065,6 +6422,25 @@
6065
6422
  "app": null,
6066
6423
  "looks": []
6067
6424
  },
6425
+ {
6426
+ "name": "typeTrigger",
6427
+ "repo": "estiva-ui",
6428
+ "kind": "helper",
6429
+ "importPath": "@estiva-app/ui/editor",
6430
+ "sourceFile": "src/ComposerTriggers.tsx",
6431
+ "purpose": "A row that types another trigger, so its own list opens — `@` from `/`.",
6432
+ "purposeFrom": "comment",
6433
+ "props": [],
6434
+ "variants": [],
6435
+ "ownsBehaviours": [],
6436
+ "status": "stable",
6437
+ "migrationStage": null,
6438
+ "docsId": "primitives-composertriggers--docs",
6439
+ "storyId": "primitives-composertriggers--default",
6440
+ "docPage": null,
6441
+ "app": null,
6442
+ "looks": []
6443
+ },
6068
6444
  {
6069
6445
  "name": "UnknownBlock",
6070
6446
  "repo": "estiva-ui",
@@ -6084,6 +6460,51 @@
6084
6460
  "app": null,
6085
6461
  "looks": []
6086
6462
  },
6463
+ {
6464
+ "name": "UrgentPersonMention",
6465
+ "repo": "estiva-ui",
6466
+ "kind": "component",
6467
+ "importPath": "@estiva-app/ui/editor",
6468
+ "sourceFile": "src/ComposerTriggers.tsx",
6469
+ "purpose": "`!@` — a person, urgently: the same chip in the urgent tone.",
6470
+ "purposeFrom": "comment",
6471
+ "props": [],
6472
+ "variants": [],
6473
+ "ownsBehaviours": [],
6474
+ "status": "stable",
6475
+ "migrationStage": null,
6476
+ "docsId": "primitives-composertriggers--docs",
6477
+ "storyId": "primitives-composertriggers--default",
6478
+ "docPage": null,
6479
+ "app": null,
6480
+ "looks": []
6481
+ },
6482
+ {
6483
+ "name": "urgentPubkeys",
6484
+ "repo": "estiva-ui",
6485
+ "kind": "helper",
6486
+ "importPath": "@estiva-app/ui/editor",
6487
+ "sourceFile": "src/ComposerTriggers.tsx",
6488
+ "purpose": "The keys the document's urgent mentions name — what the write turns into `[\"urgent\", <pubkey>]` tags.",
6489
+ "purposeFrom": "comment",
6490
+ "props": [
6491
+ {
6492
+ "name": "state",
6493
+ "takes": "{ doc: Doc }",
6494
+ "required": true,
6495
+ "note": null
6496
+ }
6497
+ ],
6498
+ "variants": [],
6499
+ "ownsBehaviours": [],
6500
+ "status": "stable",
6501
+ "migrationStage": null,
6502
+ "docsId": "primitives-composertriggers--docs",
6503
+ "storyId": "primitives-composertriggers--default",
6504
+ "docPage": null,
6505
+ "app": null,
6506
+ "looks": []
6507
+ },
6087
6508
  {
6088
6509
  "name": "useToast",
6089
6510
  "repo": "estiva-ui",
@@ -28,6 +28,12 @@ toggle, and the rows under it, sliding shut and open.
28
28
 
29
29
  <Canvas of={CollapsibleSectionStories.AsARow} />
30
30
 
31
+ - `indent` with the standard heading: its rows start under its title, past
32
+ the chevron — a group in a sidebar whose rows read as inside it. **NavTree**
33
+ draws its groups this way.
34
+
35
+ <Canvas of={CollapsibleSectionStories.Indented} />
36
+
31
37
  In a sidebar — the Sidebar's own Composed canvas, which is where that
32
38
  composition lives:
33
39
 
@@ -47,3 +47,8 @@ export const Remembered: Story = { args: { storageKey: 'estiva-ui.stories.collap
47
47
  export const AsARow: Story = {
48
48
  args: { title: 'Folder', look: 'row' },
49
49
  }
50
+
51
+ /** `indent`: the heading look, its rows starting under its title, past the chevron — a folder in a sidebar. */
52
+ export const Indented: Story = {
53
+ args: { title: 'Group', indent: true },
54
+ }
@@ -2,6 +2,7 @@ import { useState, type ReactNode } from 'react'
2
2
  import { Collapsible } from '@base-ui/react/collapsible'
3
3
  import { cn } from './cn'
4
4
  import { SectionHeader, type SectionAction } from './SectionHeader'
5
+ import { COLLAPSIBLE_PANEL_CLASSES } from './looks'
5
6
 
6
7
  /**
7
8
  * A section that opens and closes: a `SectionHeader` whose title is the
@@ -42,6 +43,12 @@ export interface CollapsibleSectionProps {
42
43
  * its title, past the chevron (`SectionHeader`'s `look`).
43
44
  */
44
45
  look?: 'heading' | 'row'
46
+ /**
47
+ * With the `heading` look: the rows start under the title, past the
48
+ * chevron — a folder in a sidebar, its files lightly indented under its
49
+ * name (Katerina, 2 October). The `row` look always indents.
50
+ */
51
+ indent?: boolean
45
52
  /** The rows. */
46
53
  children: ReactNode
47
54
  /** On the section's box: `mt-2` between groups, `shrink-0` in a scrolling column. */
@@ -72,7 +79,7 @@ function writeStored(key: string | undefined, open: boolean) {
72
79
  }
73
80
  }
74
81
 
75
- export function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, look = 'heading', children, className, contentClassName }: CollapsibleSectionProps) {
82
+ export function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, look = 'heading', indent = false, children, className, contentClassName }: CollapsibleSectionProps) {
76
83
  const [openState, setOpenState] = useState(() => readStored(storageKey) ?? defaultOpen)
77
84
  const open = openProp ?? openState
78
85
  const setOpen = (next: boolean) => {
@@ -91,10 +98,11 @@ export function CollapsibleSection({ title, defaultOpen = true, open: openProp,
91
98
  prefers-reduced-motion. */}
92
99
  <Collapsible.Panel
93
100
  hiddenUntilFound
94
- className="h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0"
101
+ className={COLLAPSIBLE_PANEL_CLASSES}
95
102
  >
96
- {/* A row's rows start under its title: the 16px chevron and its 8px gap (pl-6). */}
97
- <div className={cn('flex flex-col', look === 'row' && 'pl-6', contentClassName)}>{children}</div>
103
+ {/* A row's rows start under its title: the 16px chevron and its 8px gap
104
+ (pl-6). An indented heading's: its 12px chevron and 4px gap (pl-4). */}
105
+ <div className={cn('flex flex-col', look === 'row' ? 'pl-6' : indent && 'pl-4', contentClassName)}>{children}</div>
98
106
  </Collapsible.Panel>
99
107
  </Collapsible.Root>
100
108
  )