@danxbot/ui 1.0.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 (183) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -0
  3. package/dist/fonts/bricolage-grotesque-0.woff2 +0 -0
  4. package/dist/fonts/bricolage-grotesque-1.woff2 +0 -0
  5. package/dist/fonts/bricolage-grotesque-2.woff2 +0 -0
  6. package/dist/fonts/figtree-0.woff2 +0 -0
  7. package/dist/fonts/figtree-1.woff2 +0 -0
  8. package/dist/fonts/figtree-2.woff2 +0 -0
  9. package/dist/fonts/figtree-3.woff2 +0 -0
  10. package/dist/fonts/jetbrains-mono-0.woff2 +0 -0
  11. package/dist/fonts/jetbrains-mono-1.woff2 +0 -0
  12. package/dist/fonts/jetbrains-mono-10.woff2 +0 -0
  13. package/dist/fonts/jetbrains-mono-11.woff2 +0 -0
  14. package/dist/fonts/jetbrains-mono-2.woff2 +0 -0
  15. package/dist/fonts/jetbrains-mono-3.woff2 +0 -0
  16. package/dist/fonts/jetbrains-mono-4.woff2 +0 -0
  17. package/dist/fonts/jetbrains-mono-5.woff2 +0 -0
  18. package/dist/fonts/jetbrains-mono-6.woff2 +0 -0
  19. package/dist/fonts/jetbrains-mono-7.woff2 +0 -0
  20. package/dist/fonts/jetbrains-mono-8.woff2 +0 -0
  21. package/dist/fonts/jetbrains-mono-9.woff2 +0 -0
  22. package/dist/fonts.css +187 -0
  23. package/dist/index.js +42425 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/styles.css +190 -0
  26. package/dist/types/components/Accordion.d.ts +15 -0
  27. package/dist/types/components/AppShell.d.ts +58 -0
  28. package/dist/types/components/Avatar.d.ts +154 -0
  29. package/dist/types/components/Badge.d.ts +73 -0
  30. package/dist/types/components/Button.d.ts +103 -0
  31. package/dist/types/components/Card.d.ts +193 -0
  32. package/dist/types/components/Choice.d.ts +112 -0
  33. package/dist/types/components/CodeEditor.d.ts +86 -0
  34. package/dist/types/components/Combobox.d.ts +37 -0
  35. package/dist/types/components/CommandPalette.d.ts +33 -0
  36. package/dist/types/components/DatePicker.d.ts +20 -0
  37. package/dist/types/components/Dialog.d.ts +117 -0
  38. package/dist/types/components/DragDrop.d.ts +60 -0
  39. package/dist/types/components/ErrorBoundary.d.ts +16 -0
  40. package/dist/types/components/Field.d.ts +37 -0
  41. package/dist/types/components/FileUpload.d.ts +22 -0
  42. package/dist/types/components/Icon.d.ts +40 -0
  43. package/dist/types/components/Input.d.ts +120 -0
  44. package/dist/types/components/Loading.d.ts +83 -0
  45. package/dist/types/components/MarkdownEditor.d.ts +24 -0
  46. package/dist/types/components/Menu.d.ts +57 -0
  47. package/dist/types/components/Navigation.d.ts +46 -0
  48. package/dist/types/components/NumberInput.d.ts +88 -0
  49. package/dist/types/components/OTPInput.d.ts +11 -0
  50. package/dist/types/components/Panel.d.ts +94 -0
  51. package/dist/types/components/Popover.d.ts +64 -0
  52. package/dist/types/components/Progress.d.ts +178 -0
  53. package/dist/types/components/Select.d.ts +53 -0
  54. package/dist/types/components/Slider.d.ts +203 -0
  55. package/dist/types/components/Spinner.d.ts +29 -0
  56. package/dist/types/components/Stat.d.ts +98 -0
  57. package/dist/types/components/StatusSelect.d.ts +23 -0
  58. package/dist/types/components/Surface.d.ts +110 -0
  59. package/dist/types/components/Table.d.ts +46 -0
  60. package/dist/types/components/Tabs.d.ts +84 -0
  61. package/dist/types/components/ThemeMenu.d.ts +4 -0
  62. package/dist/types/components/Toast.d.ts +46 -0
  63. package/dist/types/components/Toggle.d.ts +65 -0
  64. package/dist/types/components/Tree.d.ts +20 -0
  65. package/dist/types/components/calendar/CalendarMonth.d.ts +33 -0
  66. package/dist/types/components/calendar/CalendarTimeGrid.d.ts +75 -0
  67. package/dist/types/components/calendar/EventActions.d.ts +17 -0
  68. package/dist/types/components/calendar/format.d.ts +43 -0
  69. package/dist/types/components/calendar/index.d.ts +9 -0
  70. package/dist/types/components/calendar/palette.d.ts +17 -0
  71. package/dist/types/components/calendar/use-calendar-drag.d.ts +54 -0
  72. package/dist/types/components/calendar/use-event-keyboard.d.ts +24 -0
  73. package/dist/types/components/calendar/use-grid-navigation.d.ts +47 -0
  74. package/dist/types/components/calendar/use-now.d.ts +20 -0
  75. package/dist/types/components/chat/Attachment.d.ts +49 -0
  76. package/dist/types/components/chat/Chat.d.ts +60 -0
  77. package/dist/types/components/chat/Composer.d.ts +29 -0
  78. package/dist/types/components/chat/ContextMeter.d.ts +55 -0
  79. package/dist/types/components/chat/EffortControl.d.ts +23 -0
  80. package/dist/types/components/chat/Markdown.d.ts +22 -0
  81. package/dist/types/components/chat/Message.d.ts +59 -0
  82. package/dist/types/components/chat/MessageScroller.d.ts +13 -0
  83. package/dist/types/components/chat/ModelSelector.d.ts +44 -0
  84. package/dist/types/components/chat/types.d.ts +155 -0
  85. package/dist/types/components/code-editor/context.d.ts +32 -0
  86. package/dist/types/components/code-editor/editing.d.ts +39 -0
  87. package/dist/types/components/code-editor/highlight.d.ts +20 -0
  88. package/dist/types/components/code-editor/recipe.d.ts +109 -0
  89. package/dist/types/components/code-editor/state.d.ts +14 -0
  90. package/dist/types/components/drag-drop/context.d.ts +45 -0
  91. package/dist/types/components/drag-drop/recipe.d.ts +121 -0
  92. package/dist/types/components/drag-drop/shift.d.ts +66 -0
  93. package/dist/types/components/markdown/Affordances.d.ts +76 -0
  94. package/dist/types/components/rbac/AccountMenu.d.ts +8 -0
  95. package/dist/types/components/rbac/DevToolsPopover.d.ts +5 -0
  96. package/dist/types/components/rbac/ProfilePage.d.ts +1 -0
  97. package/dist/types/components/rbac/RBACProvider.d.ts +64 -0
  98. package/dist/types/components/rbac/RolePermissionMatrix.d.ts +6 -0
  99. package/dist/types/components/rbac/RolesPermissionsPage.d.ts +1 -0
  100. package/dist/types/components/rbac/index.d.ts +7 -0
  101. package/dist/types/components/rbac/types.d.ts +26 -0
  102. package/dist/types/components/roadmap/PhaseManager.d.ts +19 -0
  103. package/dist/types/components/roadmap/RoadmapItemCard.d.ts +45 -0
  104. package/dist/types/components/roadmap/RoadmapPage.d.ts +9 -0
  105. package/dist/types/components/roadmap/RoadmapSwimlaneBoard.d.ts +9 -0
  106. package/dist/types/components/roadmap/UseCaseCard.d.ts +14 -0
  107. package/dist/types/components/roadmap/UseCaseLedgerPage.d.ts +21 -0
  108. package/dist/types/components/roadmap/chip-tones.d.ts +2 -0
  109. package/dist/types/components/roadmap/derive.d.ts +12 -0
  110. package/dist/types/components/roadmap/index.d.ts +9 -0
  111. package/dist/types/components/roadmap/types.d.ts +54 -0
  112. package/dist/types/icons/data.d.ts +1318 -0
  113. package/dist/types/index.d.ts +97 -0
  114. package/dist/types/lib/calendar/band-packer.d.ts +53 -0
  115. package/dist/types/lib/calendar/drag.d.ts +125 -0
  116. package/dist/types/lib/calendar/index.d.ts +4 -0
  117. package/dist/types/lib/calendar/lane-packer.d.ts +88 -0
  118. package/dist/types/lib/calendar/segments.d.ts +91 -0
  119. package/dist/types/lib/calendar/types.d.ts +166 -0
  120. package/dist/types/lib/cn.d.ts +7 -0
  121. package/dist/types/lib/dnd/announce.d.ts +132 -0
  122. package/dist/types/lib/dnd/autoscroll.d.ts +88 -0
  123. package/dist/types/lib/dnd/geometry.d.ts +78 -0
  124. package/dist/types/lib/dnd/index.d.ts +16 -0
  125. package/dist/types/lib/dnd/sensors/gesture.d.ts +37 -0
  126. package/dist/types/lib/dnd/sensors/keyboard.d.ts +50 -0
  127. package/dist/types/lib/dnd/sensors/pointer.d.ts +59 -0
  128. package/dist/types/lib/dnd/session.d.ts +99 -0
  129. package/dist/types/lib/dnd/types.d.ts +162 -0
  130. package/dist/types/lib/dnd/use-drag.d.ts +56 -0
  131. package/dist/types/lib/icons.d.ts +40 -0
  132. package/dist/types/lib/markdown/caret-map.d.ts +48 -0
  133. package/dist/types/lib/markdown/caret.d.ts +6 -0
  134. package/dist/types/lib/markdown/commands.d.ts +170 -0
  135. package/dist/types/lib/markdown/convert.d.ts +82 -0
  136. package/dist/types/lib/markdown/dom.d.ts +67 -0
  137. package/dist/types/lib/markdown/edit.d.ts +16 -0
  138. package/dist/types/lib/markdown/history.d.ts +47 -0
  139. package/dist/types/lib/markdown/hotkeys.d.ts +39 -0
  140. package/dist/types/lib/markdown/input.d.ts +15 -0
  141. package/dist/types/lib/markdown/keys.d.ts +34 -0
  142. package/dist/types/lib/markdown/paste.d.ts +9 -0
  143. package/dist/types/lib/markdown/position.d.ts +43 -0
  144. package/dist/types/lib/markdown/project.d.ts +88 -0
  145. package/dist/types/lib/markdown/reconcile.d.ts +63 -0
  146. package/dist/types/lib/markdown/surface.d.ts +177 -0
  147. package/dist/types/lib/persist.d.ts +40 -0
  148. package/dist/types/lib/preferences.d.ts +80 -0
  149. package/dist/types/lib/sim/createSimStore.d.ts +18 -0
  150. package/dist/types/lib/sim/index.d.ts +5 -0
  151. package/dist/types/lib/sim/latency.d.ts +10 -0
  152. package/dist/types/lib/sim/registry.d.ts +14 -0
  153. package/dist/types/lib/sim/settings.d.ts +11 -0
  154. package/dist/types/lib/sim/types.d.ts +3 -0
  155. package/dist/types/lib/syntax/index.d.ts +16 -0
  156. package/dist/types/lib/syntax/languages/bash.d.ts +1 -0
  157. package/dist/types/lib/syntax/languages/css.d.ts +1 -0
  158. package/dist/types/lib/syntax/languages/html.d.ts +17 -0
  159. package/dist/types/lib/syntax/languages/index.d.ts +33 -0
  160. package/dist/types/lib/syntax/languages/javascript.d.ts +22 -0
  161. package/dist/types/lib/syntax/languages/json.d.ts +1 -0
  162. package/dist/types/lib/syntax/languages/mongodb.d.ts +1 -0
  163. package/dist/types/lib/syntax/languages/plain.d.ts +9 -0
  164. package/dist/types/lib/syntax/languages/sql.d.ts +4 -0
  165. package/dist/types/lib/syntax/languages/vue.d.ts +1 -0
  166. package/dist/types/lib/syntax/languages/yaml.d.ts +1 -0
  167. package/dist/types/lib/syntax/markdown/frames.d.ts +145 -0
  168. package/dist/types/lib/syntax/markdown/grammar.d.ts +1 -0
  169. package/dist/types/lib/syntax/markdown/index.d.ts +4 -0
  170. package/dist/types/lib/syntax/markdown/inline.d.ts +21 -0
  171. package/dist/types/lib/syntax/markdown/parse.d.ts +11 -0
  172. package/dist/types/lib/syntax/markdown/render.d.ts +19 -0
  173. package/dist/types/lib/syntax/markdown/spans.d.ts +84 -0
  174. package/dist/types/lib/syntax/markdown/types.d.ts +108 -0
  175. package/dist/types/lib/syntax/registry.d.ts +37 -0
  176. package/dist/types/lib/syntax/tokenize.d.ts +17 -0
  177. package/dist/types/lib/syntax/types.d.ts +119 -0
  178. package/dist/types/lib/time/index.d.ts +3 -0
  179. package/dist/types/lib/time/plain.d.ts +61 -0
  180. package/dist/types/lib/time/types.d.ts +87 -0
  181. package/dist/types/lib/time/zone.d.ts +97 -0
  182. package/dist/types/lib/use-media-query.d.ts +29 -0
  183. package/package.json +130 -0
@@ -0,0 +1,66 @@
1
+ import type { ContainerId, DragAxis, DragState, LayoutSnapshot } from "../../lib/dnd";
2
+ export interface ContainerShift {
3
+ axis: DragAxis;
4
+ /** Items in this container with the carried one removed. */
5
+ restCount: number;
6
+ /**
7
+ * The carried item's extent along the axis — the size of the hole that opens.
8
+ * The step neighbours move by is this PLUS the spacing between two items,
9
+ * because the arriving item brings its own gap with it.
10
+ */
11
+ gapSize: number;
12
+ /** `gapSize` plus the measured spacing: how far one neighbour moves. */
13
+ step: number;
14
+ /** Measured spacing between two adjacent items of this container. */
15
+ spacing: number;
16
+ /** Insertion index in this container, or null when it is not the target. */
17
+ markerAt: number | null;
18
+ /** Displacement along the axis, in px, for the rest item at `restIndex`. */
19
+ itemShift: (restIndex: number) => number;
20
+ /**
21
+ * Displacement for the insertion marker rendered before rest item
22
+ * `restIndex` — or at `restCount`, meaning after every item.
23
+ *
24
+ * The marker takes ONLY the home-slot half. It IS the gap, so applying the
25
+ * gap displacement to it would move it out of the space it marks.
26
+ */
27
+ markerShift: (restIndex: number) => number;
28
+ }
29
+ /**
30
+ * Everything one container needs to render the shift, or null when no drag is
31
+ * in flight and nothing should move.
32
+ *
33
+ * `lifted` says whether something else is carrying the card — a
34
+ * `<DragDropOverlay>` is mounted. It decides ONLY whether the home slot closes,
35
+ * and the reason is not cosmetic: with no overlay the card is still sitting in
36
+ * its own slot, so closing that slot slides a neighbour underneath it.
37
+ */
38
+ export declare function containerShift(layout: LayoutSnapshot | null, state: DragState, container: ContainerId, lifted: boolean): ContainerShift | null;
39
+ /** A rect in viewport coordinates. */
40
+ export interface GapRect {
41
+ top: number;
42
+ left: number;
43
+ width: number;
44
+ height: number;
45
+ }
46
+ /**
47
+ * Where the opened gap sits on screen, for a carried card that has no pointer
48
+ * to follow.
49
+ *
50
+ * Viewport coordinates, taken from the same snapshot the shift is computed
51
+ * from, so the two cannot disagree about where the hole is. The snapshot is
52
+ * re-taken whenever the keyboard insertion point moves out of view
53
+ * (`autoscroll.ts#keepKeyboardTargetVisible`), which is the only thing that
54
+ * moves these boxes during a keyboard drag.
55
+ */
56
+ export declare function gapRect(layout: LayoutSnapshot | null, state: DragState, lifted: boolean): GapRect | null;
57
+ /**
58
+ * The shift as an inline style.
59
+ *
60
+ * `translate` rather than `transform`, so a component can still rotate or scale
61
+ * the same element without the two having to be composed into one string — the
62
+ * floating clone does exactly that.
63
+ */
64
+ export declare function shiftStyle(axis: DragAxis, distance: number): {
65
+ translate: string;
66
+ };
@@ -0,0 +1,76 @@
1
+ import { type BlockInfo, type BlockKind, type ConstructInfo } from "../../lib/markdown/convert";
2
+ import { type Command } from "../../lib/markdown/commands";
3
+ import type { MarkdownSurface } from "../../lib/markdown/surface";
4
+ export interface EditorState {
5
+ source: string;
6
+ /** Collapsed caret offset, or null when there is no selection in the host. */
7
+ caret: number | null;
8
+ /** True when the selection covers something. */
9
+ ranged: boolean;
10
+ block: BlockInfo | null;
11
+ construct: ConstructInfo | null;
12
+ }
13
+ /**
14
+ * Tracks source and selection, and derives what is under the caret.
15
+ *
16
+ * `selectionchange` is a DOCUMENT event and the only signal for a caret the
17
+ * browser moved on its own — a click, a drag, an arrow key. It fires for the
18
+ * surface's own restore too, which is harmless here because this only reads.
19
+ */
20
+ export declare function useEditorState(surface: MarkdownSurface | null, version: number): EditorState;
21
+ interface TypeChoice {
22
+ kind: BlockKind;
23
+ level?: number;
24
+ label: string;
25
+ icon: string;
26
+ }
27
+ export interface LineHandleProps {
28
+ surface: MarkdownSurface | null;
29
+ state: EditorState;
30
+ run: (command: Command) => void;
31
+ /** The container the handle is positioned inside. */
32
+ container: HTMLElement | null;
33
+ }
34
+ /**
35
+ * A type control beside the line under the pointer, or under the caret.
36
+ *
37
+ * ON HOVER AND ON THE CARET'S LINE, never on every line at once: a permanent
38
+ * gutter of forty identical buttons is noise, and one that follows the pointer
39
+ * is discoverable the moment a pointer moves. The caret's line is included so
40
+ * the control exists for someone who is not using a pointer at all.
41
+ */
42
+ export declare function LineHandle({ surface, state, run, container }: LineHandleProps): import("react").JSX.Element | null;
43
+ export interface ConstructBarProps {
44
+ surface: MarkdownSurface | null;
45
+ state: EditorState;
46
+ run: (command: Command) => void;
47
+ container: HTMLElement | null;
48
+ }
49
+ /**
50
+ * The controls for whatever the caret is inside — a link, an image, a fence or
51
+ * a table.
52
+ *
53
+ * IT APPEARS BY ITSELF rather than waiting for a click, and that is a decision
54
+ * the always-hidden markup forces. A destination the caret cannot enter and a
55
+ * control that has to be found are the same thing as no control at all; a small
56
+ * bar anchored to the construct you are already standing in is the shortest
57
+ * path from "I want to change this URL" to changing it.
58
+ */
59
+ export declare function ConstructBar({ surface, state, run, container }: ConstructBarProps): import("react").JSX.Element | null;
60
+ export interface ConversionMenuProps {
61
+ surface: MarkdownSurface | null;
62
+ state: EditorState;
63
+ run: (command: Command) => void;
64
+ container: HTMLElement | null;
65
+ }
66
+ /**
67
+ * Right-click conversions for a selection.
68
+ *
69
+ * OURS ONLY WHEN THERE IS SOMETHING TO CONVERT. Swallowing every right-click
70
+ * costs the browser's own spellcheck suggestions, which is a worse trade than
71
+ * this menu is worth — so with no selection and nothing under the pointer, the
72
+ * native menu is left alone.
73
+ */
74
+ export declare function ConversionMenu({ surface, state, run, container }: ConversionMenuProps): import("react").JSX.Element | null;
75
+ export declare const AFFORDANCE_TYPES: TypeChoice[];
76
+ export {};
@@ -0,0 +1,8 @@
1
+ export interface AccountMenuProps {
2
+ onNavigateProfile?: () => void;
3
+ onNavigateRoles?: () => void;
4
+ onSwitchTeam?: (teamId: string) => void;
5
+ onSignOut?: () => void;
6
+ className?: string;
7
+ }
8
+ export declare function AccountMenu({ onNavigateProfile, onNavigateRoles, onSwitchTeam, onSignOut, className, }: AccountMenuProps): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ export interface DevToolsPopoverProps {
2
+ /** Deep link to the dev-only Use Case Ledger. Omit and the row does not render. */
3
+ onOpenUseCaseLedger?: () => void;
4
+ }
5
+ export declare function DevToolsPopover({ onOpenUseCaseLedger }?: DevToolsPopoverProps): import("react").JSX.Element | null;
@@ -0,0 +1 @@
1
+ export declare function ProfilePage(): import("react").JSX.Element;
@@ -0,0 +1,64 @@
1
+ import { type ReactNode } from "react";
2
+ import type { Permission, Role, Team, TeamMembership, User } from "./types";
3
+ export interface RBACProviderProps {
4
+ currentUser: User;
5
+ roles: Role[];
6
+ permissions: Permission[];
7
+ teams: Team[];
8
+ /** All memberships for `currentUser`, across every team — not just the current one. */
9
+ memberships: TeamMembership[];
10
+ currentTeamId: string;
11
+ /**
12
+ * Decides who may open the Dev Tools "view as" escape hatch.
13
+ *
14
+ * Deliberately a predicate over the consumer's OWN data (`user`, `roles`,
15
+ * `memberships`) rather than a boolean prop or a hardcoded role check. The
16
+ * library has no idea what "admin enough to use dev tools" means for any
17
+ * given consumer — one app might key it off a role id, another off a team
18
+ * membership count, another off a flag on `User` this contract doesn't even
19
+ * define. Only the consumer's own data model can answer that, so the
20
+ * decision is handed back to them wholesale.
21
+ */
22
+ canAccessDevTools: (user: User, roles: Role[], memberships: TeamMembership[]) => boolean;
23
+ children: ReactNode;
24
+ }
25
+ export interface RBACHookResult {
26
+ actualUser: User;
27
+ currentTeam: Team | undefined;
28
+ /** The role backing `actualUser`'s own membership in `currentTeamId` — never affected by impersonation. */
29
+ actualRole: Role | undefined;
30
+ /** `null` when not impersonating. */
31
+ viewingAsRoleId: string | null;
32
+ setViewingAsRoleId: (id: string | null) => void;
33
+ /** `actualRole`, unless impersonating — then the impersonated role. */
34
+ effectiveRole: Role | undefined;
35
+ effectivePermissionKeys: Set<string>;
36
+ hasPermission: (key: string) => boolean;
37
+ /**
38
+ * Whether the REAL logged-in user may open Dev Tools.
39
+ *
40
+ * See the block comment above `evaluateCanAccessDevTools` below for why this
41
+ * is computed from `actualUser`/`roles`/`memberships` and can NEVER be
42
+ * re-derived from `effectiveRole` / `viewingAsRoleId` — that is the entire
43
+ * point of this field existing on the hook at all.
44
+ */
45
+ canAccessDevTools: boolean;
46
+ isImpersonating: boolean;
47
+ roles: Role[];
48
+ permissions: Permission[];
49
+ teams: Team[];
50
+ }
51
+ export declare function RBACProvider({ currentUser, roles, permissions, teams, memberships, currentTeamId, canAccessDevTools, children, }: RBACProviderProps): import("react").JSX.Element;
52
+ /**
53
+ * Reads the RBAC context.
54
+ *
55
+ * Throws rather than returning `undefined` — the same shape as
56
+ * `useDragDrop` / `useDragDropContainer` (`drag-drop/context.ts`) and every
57
+ * other multi-part context in this library. A component that silently
58
+ * received `undefined` here would fail wherever it FIRST tries to read a
59
+ * field off the result, several lines and possibly several components away
60
+ * from the actual mistake (forgetting the `<RBACProvider>` wrapper) — a
61
+ * blank permissions list is a much harder bug to trace back than a thrown
62
+ * error naming the missing provider.
63
+ */
64
+ export declare function useRBAC(): RBACHookResult;
@@ -0,0 +1,6 @@
1
+ import type { Permission, Role } from "./types";
2
+ export interface RolePermissionMatrixProps {
3
+ roles: Role[];
4
+ permissions: Permission[];
5
+ }
6
+ export declare function RolePermissionMatrix({ roles, permissions }: RolePermissionMatrixProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare function RolesPermissionsPage(): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ export * from "./types";
2
+ export * from "./RBACProvider";
3
+ export * from "./AccountMenu";
4
+ export * from "./DevToolsPopover";
5
+ export * from "./RolePermissionMatrix";
6
+ export * from "./ProfilePage";
7
+ export * from "./RolesPermissionsPage";
@@ -0,0 +1,26 @@
1
+ export interface Permission {
2
+ /** Arbitrary, consumer-defined. The library only ever compares keys for equality. */
3
+ key: string;
4
+ label: string;
5
+ category?: string;
6
+ }
7
+ export interface Role {
8
+ id: string;
9
+ label: string;
10
+ permissionKeys: string[];
11
+ }
12
+ export interface User {
13
+ id: string;
14
+ name: string;
15
+ email: string;
16
+ avatarUrl?: string;
17
+ }
18
+ export interface Team {
19
+ id: string;
20
+ name: string;
21
+ }
22
+ export interface TeamMembership {
23
+ userId: string;
24
+ teamId: string;
25
+ roleId: string;
26
+ }
@@ -0,0 +1,19 @@
1
+ import type { Phase, RoadmapItem } from "./types";
2
+ export interface PhaseManagerProps {
3
+ phases: Phase[];
4
+ /** Read-only — used only to compute the delete guard below. */
5
+ roadmapItems: RoadmapItem[];
6
+ /** `order` is pre-computed by this component (next after the current max)
7
+ so the caller only has to assign an id and persist. */
8
+ onCreate: (phase: {
9
+ name: string;
10
+ order: number;
11
+ }) => void;
12
+ onRename: (id: string, name: string) => void;
13
+ /** The full phase list, reordered and renumbered (`order` === new index) —
14
+ the caller persists each row's new `order`, e.g. one `update` per id. */
15
+ onReorder: (phases: Phase[]) => void;
16
+ onDelete: (id: string) => void;
17
+ className?: string;
18
+ }
19
+ export declare function PhaseManager({ phases, roadmapItems, onCreate, onRename, onReorder, onDelete, className, }: PhaseManagerProps): import("react").JSX.Element;
@@ -0,0 +1,45 @@
1
+ import { type BadgeProps } from "../Badge";
2
+ import type { Domain, Phase, RoadmapItem, RoadmapItemStatus, UseCase, UseCaseStatus } from "./types";
3
+ export declare const ROADMAP_ITEM_STATUS_BADGE: Record<RoadmapItemStatus, {
4
+ tone: BadgeProps["tone"];
5
+ label: string;
6
+ live?: boolean;
7
+ }>;
8
+ export interface RoadmapItemCardProps {
9
+ item: RoadmapItem;
10
+ domain: Domain;
11
+ /** `domain`'s position in the FULL `domains[]` list the caller was handed —
12
+ computed once by the caller (`domains.findIndex(...)`, or a `.map()`
13
+ index), never re-derived here. Drives the domain Badge's cycling tone
14
+ via `toneForIndex`, the same "the card computes nothing it wasn't
15
+ explicitly handed" pattern already used for `useCases` below. */
16
+ domainIndex: number;
17
+ phase: Phase;
18
+ /** Same pattern as `domainIndex`, for `phase`. */
19
+ phaseIndex: number;
20
+ /** This item's OWN use cases (already filtered by `goalRef === item.ref`) —
21
+ the card computes its status from exactly this list and renders nothing
22
+ more, so a caller handing it the wrong slice silently mis-derives status
23
+ rather than the card silently re-filtering a different assumption. */
24
+ useCases: UseCase[];
25
+ /** Forwarded to each `UseCaseCard`'s `onStatusChange` as
26
+ `onUseCaseStatusChange(useCase.ref, status)`. Omitted (the default,
27
+ `RoadmapSwimlaneBoard`'s customer-facing use) keeps every `UseCaseCard`
28
+ read-only — see `UseCaseCard`'s own `onStatusChange` doc. */
29
+ onUseCaseStatusChange?: (ref: string, status: UseCaseStatus) => void;
30
+ defaultExpanded?: boolean;
31
+ className?: string;
32
+ }
33
+ /**
34
+ * A single roadmap item, expandable to reveal the use cases behind it.
35
+ *
36
+ * COLLAPSED BY DEFAULT, REVEALED BY A CLICK — this is the literal "click a
37
+ * roadmap item to see the use cases inside it" interaction from the product
38
+ * spec, not a static list that happens to render inside a card. A disclosure
39
+ * button (`aria-expanded` + `aria-controls`) rather than making the whole card
40
+ * clickable: a card-sized hit target with no visible affordance is the classic
41
+ * "is this a link or a label" ambiguity, and a card is also where a consumer
42
+ * may reasonably want to add its OWN click behaviour (e.g. deep-linking) later
43
+ * without fighting this one for the same element.
44
+ */
45
+ export declare function RoadmapItemCard({ item, domain, domainIndex, phase, phaseIndex, useCases, onUseCaseStatusChange, defaultExpanded, className, }: RoadmapItemCardProps): import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import type { Domain, Phase, RoadmapItem, UseCase } from "./types";
2
+ export interface RoadmapPageProps {
3
+ domains: Domain[];
4
+ phases: Phase[];
5
+ items: RoadmapItem[];
6
+ useCases: UseCase[];
7
+ className?: string;
8
+ }
9
+ export declare function RoadmapPage({ domains, phases, items, useCases, className }: RoadmapPageProps): import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import type { Domain, Phase, RoadmapItem, UseCase } from "./types";
2
+ export interface RoadmapSwimlaneBoardProps {
3
+ domains: Domain[];
4
+ phases: Phase[];
5
+ items: RoadmapItem[];
6
+ useCases: UseCase[];
7
+ className?: string;
8
+ }
9
+ export declare function RoadmapSwimlaneBoard({ domains, phases, items, useCases, className, }: RoadmapSwimlaneBoardProps): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import type { UseCase, UseCaseStatus } from "./types";
2
+ export interface UseCaseCardProps {
3
+ useCase: UseCase;
4
+ /**
5
+ * Makes `status` user-settable: supplying this swaps the read-only status
6
+ * Badge for a `Select`. Omitted (the default) keeps the Badge — so
7
+ * `RoadmapPage`'s customer-facing rendering of this card, if it ever
8
+ * renders one directly, is never forced into an editable control just
9
+ * because this component knows how to be one.
10
+ */
11
+ onStatusChange?: (status: UseCaseStatus) => void;
12
+ className?: string;
13
+ }
14
+ export declare function UseCaseCard({ useCase, onStatusChange, className }: UseCaseCardProps): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import type { Domain, Phase, RoadmapItem, UseCase, UseCaseStatus } from "./types";
2
+ export interface UseCaseLedgerPageProps {
3
+ domains: Domain[];
4
+ phases: Phase[];
5
+ items: RoadmapItem[];
6
+ useCases: UseCase[];
7
+ /** Forwarded to every `RoadmapItemCard` -> `UseCaseCard` on this page,
8
+ making every use case's status genuinely user-settable here. Omitted
9
+ keeps every status read-only, the same default `UseCaseCard` itself
10
+ carries. */
11
+ onUseCaseStatusChange?: (ref: string, status: UseCaseStatus) => void;
12
+ className?: string;
13
+ }
14
+ /**
15
+ * Dev-facing ledger — the operator's view of EVERYTHING, unlike `RoadmapPage`
16
+ * which filters to `customerVisible` items only. No visibility filtering
17
+ * happens here on purpose: this is the surface where an internal-only item, or
18
+ * one still "unresolved" because a use case needs a human decision, is
19
+ * supposed to be visible.
20
+ */
21
+ export declare function UseCaseLedgerPage({ domains, phases, items, useCases, onUseCaseStatusChange, className, }: UseCaseLedgerPageProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export declare const CATEGORY_TONES: readonly ["accent", "brand", "info", "success", "warning", "neutral"];
2
+ export declare function toneForIndex(i: number): (typeof CATEGORY_TONES)[number];
@@ -0,0 +1,12 @@
1
+ import type { RoadmapItemStatus, UseCase } from "./types";
2
+ /**
3
+ * A RoadmapItem's status is derived from its own UseCases, never hand-set —
4
+ * the same reasoning as any parent whose state depends on its children:
5
+ * hand-set it and it silently drifts the moment a child changes underneath it.
6
+ *
7
+ * Rejected cases fall out of the rollup entirely — dead weight, not a blocker.
8
+ * A goal left with no live cases (everything rejected) is "unresolved" rather
9
+ * than defaulting to "planned", which would misreport a goal that needs a
10
+ * human decision as one that simply hasn't started.
11
+ */
12
+ export declare function deriveRoadmapItemStatus(useCases: UseCase[]): RoadmapItemStatus;
@@ -0,0 +1,9 @@
1
+ export * from "./types";
2
+ export * from "./derive";
3
+ export * from "./chip-tones";
4
+ export * from "./UseCaseCard";
5
+ export * from "./RoadmapItemCard";
6
+ export * from "./RoadmapSwimlaneBoard";
7
+ export * from "./UseCaseLedgerPage";
8
+ export * from "./RoadmapPage";
9
+ export * from "./PhaseManager";
@@ -0,0 +1,54 @@
1
+ export type UseCaseStatus = "pending" | "in-progress" | "verified" | "rejected";
2
+ /** Derived, never stored — see `deriveRoadmapItemStatus` in `derive.ts`. */
3
+ export type RoadmapItemStatus = "planned" | "in-progress" | "shipped" | "unresolved";
4
+ export interface Domain {
5
+ slug: string;
6
+ name: string;
7
+ description?: string;
8
+ }
9
+ /**
10
+ * A user-managed ordering bucket for `RoadmapItem`s — "MVP", "Phase 1",
11
+ * "Backlog" — in the consumer's own words. No fixed vocabulary: this library
12
+ * ships zero opinion about what phases exist, the same as `Domain`. CRUD for
13
+ * this list lives in `PhaseManager`.
14
+ */
15
+ export interface Phase {
16
+ id: string;
17
+ name: string;
18
+ /** Display/sort order — lower sorts first. */
19
+ order: number;
20
+ }
21
+ export interface RoadmapItem {
22
+ /** e.g. "RM-001". Monotonic, never reused — the consumer's concern to assign. */
23
+ ref: string;
24
+ title: string;
25
+ /** One-line, customer-safe summary — what renders on the public Roadmap card. */
26
+ summary?: string;
27
+ domainSlug: string;
28
+ /** The owning `Phase.id`. Required — every roadmap item belongs to exactly
29
+ one phase; there is no "no phase" state, the same as `domainSlug`. */
30
+ phaseId: string;
31
+ /** Gates whether this item (and its rollup status) appears on the public Roadmap. */
32
+ customerVisible: boolean;
33
+ }
34
+ export interface UseCaseDecision {
35
+ timestamp: string;
36
+ note: string;
37
+ }
38
+ export interface UseCase {
39
+ /** e.g. "UC-001". */
40
+ ref: string;
41
+ /** The parent RoadmapItem's `ref`. */
42
+ goalRef: string;
43
+ title: string;
44
+ description: string;
45
+ /** Long-form rationale — rendered collapsed by default. */
46
+ background?: string;
47
+ /** User-managed. Verified and Rejected are the only end states. */
48
+ status: UseCaseStatus;
49
+ /** Claude-managed. */
50
+ implemented: boolean;
51
+ implementedNote?: string;
52
+ /** Append-only decision log — caveats, reversals, "why it landed here". */
53
+ decisions?: UseCaseDecision[];
54
+ }