@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,97 @@
1
+ /**
2
+ * Danxbot — public library surface.
3
+ *
4
+ * This single entry is the contract for BOTH build targets: the ESM package
5
+ * that applications import, and the compiled global bundle that Claude Design
6
+ * loads. A component that is not exported here exists in neither.
7
+ *
8
+ * Every props interface is named `<Name>Props` — the design agent reads those
9
+ * type names directly, and consumers get predictable imports.
10
+ */
11
+ import "./styles/index.css";
12
+ export { Icon, type IconProps, type IconSize, type IconName } from "./components/Icon";
13
+ export { registerIcon, registerIcons, getIcon, hasIcon, iconNames, type IconNode, type IconNodeChild, } from "./lib/icons";
14
+ export { coreIcons, type CoreIconName } from "./icons/data";
15
+ export { Button, buttonVariants, type ButtonProps } from "./components/Button";
16
+ export { Badge, badgeVariants, type BadgeProps } from "./components/Badge";
17
+ export { Spinner, type SpinnerProps } from "./components/Spinner";
18
+ export { Skeleton, SkeletonText, LoadingOverlay, type SkeletonProps, type SkeletonTextProps, type LoadingOverlayProps, } from "./components/Loading";
19
+ export { ErrorBoundary } from "./components/ErrorBoundary";
20
+ export { Field, FieldSet, type FieldProps, type FieldSetProps } from "./components/Field";
21
+ export { Input, Textarea, type InputProps, type TextareaProps } from "./components/Input";
22
+ export { Checkbox, Switch, Radio, RadioGroup, CheckboxField, SwitchField, RadioField, RadioCard, type CheckboxProps, type SwitchProps, type RadioProps, type RadioGroupProps, type CheckboxFieldProps, type SwitchFieldProps, type RadioFieldProps, type RadioCardProps, } from "./components/Choice";
23
+ export { Dialog, DialogClose, AlertDialog, type DialogProps, type AlertDialogProps, } from "./components/Dialog";
24
+ export { Popover, PopoverClose, Tooltip, TooltipProvider, type PopoverProps, type TooltipProps, } from "./components/Popover";
25
+ export { Toaster, ToastProvider, useToast, type ToasterProps, type ToastProviderProps, type ToastOptions, type ToastTone, } from "./components/Toast";
26
+ export { Menu, MenuItem, MenuGroup, MenuRadioGroup, MenuRadioItem, MenuSeparator, type MenuProps, type MenuItemProps, type MenuGroupProps, type MenuRadioGroupProps, type MenuRadioItemProps, } from "./components/Menu";
27
+ export { ThemeMenu, type ThemeMenuProps } from "./components/ThemeMenu";
28
+ export { AppShell, type AppShellProps, type NavItem, type NavSection, } from "./components/AppShell";
29
+ export { FileUpload, type FileUploadProps, type UploadFile } from "./components/FileUpload";
30
+ export { DatePicker, type DatePickerProps, type DateRange } from "./components/DatePicker";
31
+ export { Tree, type TreeProps, type TreeNode } from "./components/Tree";
32
+ export { CommandPalette, useCommandPalette, type CommandPaletteProps, type CommandItem, } from "./components/CommandPalette";
33
+ export { Slider, type SliderProps, type SliderMark } from "./components/Slider";
34
+ export { NumberInput, type NumberInputProps } from "./components/NumberInput";
35
+ export { OTPInput, type OTPInputProps } from "./components/OTPInput";
36
+ export { Combobox, ComboboxItem, ComboboxGroup, MultiCombobox, type ComboboxProps, type ComboboxItemProps, type ComboboxGroupProps, type MultiComboboxProps, } from "./components/Combobox";
37
+ export { Select, SelectItem, SelectGroup, SelectSeparator, type SelectProps, type SelectItemProps, type SelectGroupProps, } from "./components/Select";
38
+ export { StatusSelect, type StatusSelectProps, type StatusOption } from "./components/StatusSelect";
39
+ export { Card, CardHeader, CardFooter, type CardProps, type CardHeaderProps, } from "./components/Card";
40
+ export { Tabs, TabList, Tab, TabPanel, type TabsProps, type TabListProps, type TabProps, type TabPanelProps, } from "./components/Tabs";
41
+ export { Accordion, AccordionItem, type AccordionProps, type AccordionItemProps, } from "./components/Accordion";
42
+ export { Breadcrumb, Pagination, type BreadcrumbProps, type PaginationProps, type Crumb, } from "./components/Navigation";
43
+ export { Toggle, ToggleGroup, Toolbar, ToolbarSeparator, type ToggleProps, type ToggleGroupProps, type ToolbarProps, } from "./components/Toggle";
44
+ export { Separator, ScrollArea, Collapsible, EmptyState, Timeline, type SeparatorProps, type ScrollAreaProps, type CollapsibleProps, type EmptyStateProps, type TimelineProps, type TimelineItem, } from "./components/Surface";
45
+ export { PanelGroup, Panel, PanelResizer, type PanelGroupProps, type PanelProps, type PanelResizerProps, type PanelDirection, type PanelNarrowMode, } from "./components/Panel";
46
+ export { Avatar, AvatarGroup, type AvatarProps, type AvatarGroupProps, type AvatarStatus, } from "./components/Avatar";
47
+ export { Progress, Meter, ProgressRing, type ProgressProps, type MeterProps, type ProgressRingProps, } from "./components/Progress";
48
+ export { Stat, Sparkline, type StatProps, type SparklineProps, type StatTrend, type StatSentiment, } from "./components/Stat";
49
+ export { DataTable, TableEmptyState, CellStack, type DataTableProps, type TableDensity, } from "./components/Table";
50
+ export { CodeEditor, CodeEditorToolbar, CodeEditorCaption, CodeEditorCopyButton, CodeEditorWrapToggle, CodeEditorViewSwitch, type CodeEditorProps, type CodeEditorToolbarProps, type CodeEditorView, } from "./components/CodeEditor";
51
+ export { MarkdownEditor, type MarkdownEditorProps } from "./components/MarkdownEditor";
52
+ export { MarkdownSurface, type SurfaceOptions, type Splice } from "./lib/markdown/surface";
53
+ export { project, projectedText, ProjectionError } from "./lib/markdown/project";
54
+ export type { Projection, PNode, PText, PElement } from "./lib/markdown/project";
55
+ export { attachInput, type InputOptions } from "./lib/markdown/input";
56
+ export { HOTKEYS, hotkeyFor, chordsOf, type Hotkey, type HotkeyGroup } from "./lib/markdown/hotkeys";
57
+ export { htmlFragmentToMarkdown } from "./lib/markdown/paste";
58
+ export { lineAt, stepOffset } from "./lib/markdown/caret";
59
+ export { caretMap, nearestStop, stepStop, graphemeBefore, graphemeAfter, lineStartStop, type CaretMap, } from "./lib/markdown/caret-map";
60
+ export { deleteVisible, deleteVisibleBefore, deleteVisibleAfter } from "./lib/markdown/edit";
61
+ export { resolveKey, type KeyIntent, type KeyContext } from "./lib/markdown/keys";
62
+ export { blockAt, convertBlock, setFenceLanguage, constructAt, editConstruct, unwrapConstruct, type BlockKind, type BlockInfo, type ConstructInfo, } from "./lib/markdown/convert";
63
+ export { readSelection, writeSelection, sourceOffsetAt, domPointAt, type SourceSelection, type DomPoint, type Association, } from "./lib/markdown/position";
64
+ export type { Command, Edit } from "./lib/markdown/commands";
65
+ export { toggleBold, toggleItalic, toggleCode, toggleStrike, toggleInline, setHeading, adjustHeading, headingLevel, toggleList, toggleTask, indentLines, outdentLines, toggleQuote, toggleCodeBlock, fenceAround, insertRule, insertImage, insertLink, insertTable, insertRow, insertColumn, deleteRow, deleteColumn, deleteTable, alignColumn, tableAround, cellsOf, cellAt, tableTab, smartEnter, smartTab, smartShiftTab, } from "./lib/markdown/commands";
66
+ export { tokenize, listLanguages, resolveLanguage, defineGrammar, registerGrammar, checkCoverage, type Token, type TokenType, type Grammar, type Rule, } from "./lib/syntax";
67
+ export { parseMarkdown, MarkdownNodes, sanitizeHref, type MdNode, type MdInline, type MdCodeRenderer, } from "./lib/syntax/markdown";
68
+ export { DragDrop, DragDropContainer, DragDropItem, DragDropHandle, DragDropOverlay, type DragDropProps, type DragDropContainerProps, type DragDropItemProps, type DragDropHandleProps, type DragDropOverlayProps, } from "./components/DragDrop";
69
+ export { DEFAULT_DRAG_STRINGS, DRAG_INSTRUCTIONS_ID, DragInstructions, DragLiveRegion, DragSession, DragSessionProvider, applyMove, attachAutoScroll, attachKeyboardSensor, attachPointerSensor, attachSessionWindowListeners, isNoOp, resolveTarget, sameTarget, scrollVelocity, useCreateDragSession, useDragAnnouncements, useDragSession, useDragState, useDraggable, useDropContainer, type ContainerId, type DragAxis, type DragCancelEvent, type DragEndEvent, type DragId, type DragMode, type DragPhase, type DragSessionCallbacks, type DragStartEvent, type DragState, type AutoScrollOptions, type DragAnnouncementContext, type DragAnnouncementOptions, type DragAnnouncements, type DragInstructionsProps, type DragLiveRegionProps, type DragStrings, type DropTarget, type KeyboardSensorOptions, type PointerActivation, } from "./lib/dnd";
70
+ export type { MessageRole, MessagePart, MessagePartType, TextPart, CodePart, ReasoningPart, ToolPart, ToolStatus, FilePart, ComponentPart, ChatFile, ChatMessage, RenderContext, PartRenderer, PartRenderers, ChatComponentRenderer, ChatComponents, } from "./components/chat/types";
71
+ export { Chat, ChatPopover, type ChatProps, type ChatPopoverProps, type ChatSurface, } from "./components/chat/Chat";
72
+ export { Message, MessagePartView, ToolCall, ChatMarker, type MessageProps, type MessageAction, type MessagePartViewProps, type ToolCallProps, type ChatMarkerProps, } from "./components/chat/Message";
73
+ export { MessageScroller, type MessageScrollerProps, } from "./components/chat/MessageScroller";
74
+ export { Composer, type ComposerProps } from "./components/chat/Composer";
75
+ export { Markdown, CodeBlock, type MarkdownProps, type CodeBlockProps } from "./components/chat/Markdown";
76
+ export { Attachment, AttachmentList, AttachmentPreview, formatBytes, type AttachmentProps, type AttachmentListProps, type AttachmentPreviewProps, type AttachmentLayout, } from "./components/chat/Attachment";
77
+ export { ModelSelector, type ModelSelectorProps, type ChatModel, } from "./components/chat/ModelSelector";
78
+ export { EffortControl, DEFAULT_EFFORT_LEVELS, type EffortControlProps, type EffortLevel, } from "./components/chat/EffortControl";
79
+ export { ContextMeter, ChatStatus, formatTokens, type ContextMeterProps, type ContextSegment, type UsageLimit, type ChatStatusProps, } from "./components/chat/ContextMeter";
80
+ export { cn } from "./lib/cn";
81
+ export { useTheme, useUiScale, useContrast, useMotionPreference, type Theme, type UiScale, type ContrastPreference, type MotionPreference, } from "./lib/preferences";
82
+ export { usePersistedState, readStored, writeStored, clearStored, storageKey, type PersistedStateOptions, } from "./lib/persist";
83
+ export { CalendarMonth, type CalendarMonthProps } from "./components/calendar/CalendarMonth";
84
+ export { CalendarTimeGrid, type CalendarTimeGridProps, } from "./components/calendar/CalendarTimeGrid";
85
+ export { useNow, type UseNowOptions } from "./components/calendar/use-now";
86
+ export { EventActions, type EventActionsProps } from "./components/calendar/EventActions";
87
+ export { useCalendarDrag, type CalendarDragOptions, type CalendarDragState, } from "./components/calendar/use-calendar-drag";
88
+ export { useEventKeyboard, type EventKeyboardOptions, type EventKeyboardState, } from "./components/calendar/use-event-keyboard";
89
+ export { applyCalendarDelta, calendarDragResult, createdEvent, describeTarget, resolveCalendarTarget, snapInstant, MIN_DURATION_MINUTES, type CalendarDragOrigin, type CalendarDragResult, type CalendarTarget, type ColumnRect, } from "./lib/calendar/drag";
90
+ export { EVENT_PALETTE, DEFAULT_PALETTE_KEY, isPaletteKey, paletteFor, } from "./components/calendar/palette";
91
+ export { cellLabel, eventLabel, formatDateRange, longDate, monthTitle, timeOfDay, weekdayName, zoneLabel, } from "./components/calendar/format";
92
+ export { initialFocusDay, isInMonth, nextDayForKey, useGridNavigation, type GridNavigation, type GridNavigationOptions, } from "./components/calendar/use-grid-navigation";
93
+ export { AmbiguousTimeError, addDays, addDuration, addMonths, atMidnight, atTime, comparePlainDate, dayFraction, dayLengthMs, dayOfWeek, daysBetween, daysInMonth, endOfMonth, hoursInDay, instantAtFraction, instantToPlainDate, instantToPlainDateTime, isSameDate, isoDateString, isoDateTimeString, monthGridDays, nextDay, offsetAt, parsePlainDate, plainDateTimeToInstant, startOfDay, startOfMonth, startOfWeek, weekDays, type CalendarDuration, type Disambiguation, type Instant, type PlainDate, type PlainDateTime, type TimeZone, } from "./lib/time";
94
+ export { allDayBandSegment, dayKey, daySlots, isAllDay, packBand, packLanes, snapFractionToInstant, timeSegments, timedBandSegment, type AllDayEvent, type BandInput, type BandOptions, type BandPlacement, type BandResult, type BandSegment, type CalendarEvent, type CalendarEventId, type CalendarView, type DaySlot, type DragKind, type EventDraft, type EventPalette, type LaneInput, type LaneOptions, type LanePlacement, type PaletteEntry, type TimeSegment, type TimedEvent, type VisibleRange, } from "./lib/calendar";
95
+ export { RBACProvider, useRBAC, AccountMenu, DevToolsPopover, RolePermissionMatrix, ProfilePage, RolesPermissionsPage, type RBACProviderProps, type RBACHookResult, type AccountMenuProps, type DevToolsPopoverProps, type RolePermissionMatrixProps, type Permission, type Role, type User, type Team, type TeamMembership, } from "./components/rbac";
96
+ export { UseCaseCard, RoadmapItemCard, RoadmapSwimlaneBoard, UseCaseLedgerPage, RoadmapPage, PhaseManager, deriveRoadmapItemStatus, toneForIndex, CATEGORY_TONES, type Domain, type Phase, type RoadmapItem, type RoadmapItemStatus, type UseCase, type UseCaseStatus, type UseCaseDecision, type UseCaseCardProps, type RoadmapItemCardProps, type RoadmapSwimlaneBoardProps, type UseCaseLedgerPageProps, type RoadmapPageProps, type PhaseManagerProps, } from "./components/roadmap";
97
+ export { createSimStore, resetSimStores, useSimSettings, setSimSettings, getNetworkSpeed, getDataSource, simulateLatency, SimNetworkError, type SimStore, type SimStoreOptions, type SimSettings, type NetworkSpeed, type DataSource, type SimNamespace, } from "./lib/sim";
@@ -0,0 +1,53 @@
1
+ /** A contiguous run of columns within one row of the grid. Both ends inclusive. */
2
+ export interface BandInput {
3
+ readonly key: string;
4
+ readonly startColumn: number;
5
+ readonly endColumn: number;
6
+ /**
7
+ * Ordering weight. Lower sorts earlier, so pinned items keep their place as
8
+ * neighbours come and go. Ties fall through to span length, then key.
9
+ */
10
+ readonly priority?: number;
11
+ }
12
+ export interface BandPlacement extends BandInput {
13
+ /** 0-based row within the band. */
14
+ readonly row: number;
15
+ }
16
+ export interface BandResult {
17
+ /** Everything that fits, in row order. */
18
+ readonly placed: readonly BandPlacement[];
19
+ /** Everything pushed past the limit, in the same order it would have had. */
20
+ readonly hidden: readonly BandInput[];
21
+ /** Per column, how many hidden items cover it — the "+N more" count. */
22
+ readonly overflow: readonly number[];
23
+ /** Rows actually used by `placed`. */
24
+ readonly rows: number;
25
+ }
26
+ export interface BandOptions {
27
+ /** How many columns the row has. Required — it sizes the overflow tally. */
28
+ readonly columns: number;
29
+ /**
30
+ * Most rows the band may occupy, INCLUDING the row the "+N more" affordance
31
+ * takes.
32
+ *
33
+ * Counting the affordance is what stops the classic off-by-one where the
34
+ * overflow link is drawn on top of the last event. When items do not fit,
35
+ * events get `maxRows - 1` rows and the last is reserved — which is
36
+ * FullCalendar's `dayMaxEventRows` semantics, and the only version that
37
+ * leaves room for the thing it just decided to draw.
38
+ *
39
+ * Omit for no limit. The all-day band MUST pass one: an uncapped band eats
40
+ * the container and makes the time grid unreachable — an open FullCalendar
41
+ * bug, and react-big-calendar's default is literally `Infinity`.
42
+ */
43
+ readonly maxRows?: number;
44
+ }
45
+ /**
46
+ * Assign each item the first row where every column it covers is free.
47
+ *
48
+ * Greedy first-fit. Not optimal in the sense of minimising rows — that is
49
+ * NP-hard and nobody wants it anyway, because the optimal packing reshuffles
50
+ * every event's row whenever one is added, and a calendar whose events jump
51
+ * rows as you type is worse than one that uses an extra row.
52
+ */
53
+ export declare function packBand(inputs: readonly BandInput[], options: BandOptions): BandResult;
@@ -0,0 +1,125 @@
1
+ import { type Instant, type PlainDate, type TimeZone } from "@/lib/time";
2
+ import type { CalendarDuration } from "@/lib/time";
3
+ import type { DragKind, TimedEvent } from "./types";
4
+ /** A day column, as the view measured it. */
5
+ export interface ColumnRect {
6
+ readonly day: PlainDate;
7
+ readonly left: number;
8
+ readonly right: number;
9
+ readonly top: number;
10
+ readonly bottom: number;
11
+ }
12
+ /** Where a pointer is, in calendar terms. */
13
+ export interface CalendarTarget {
14
+ readonly dayIndex: number;
15
+ readonly day: PlainDate;
16
+ /** Snapped to `snapMinutes`, measured from that day's own first instant. */
17
+ readonly instant: Instant;
18
+ }
19
+ export interface ResolveOptions {
20
+ readonly zone: TimeZone;
21
+ readonly columns: readonly ColumnRect[];
22
+ readonly snapMinutes: number;
23
+ }
24
+ /**
25
+ * Which day and which time a point is over.
26
+ *
27
+ * `null` outside every column — and the caller KEEPS THE LAST NON-NULL TARGET
28
+ * rather than treating that as "no drop". A pointer leaves the columns
29
+ * constantly while dragging toward the edge of the grid, and an event that
30
+ * snapped back to its origin every time the finger crossed the gutter would be
31
+ * unusable.
32
+ */
33
+ export declare function resolveCalendarTarget(point: {
34
+ x: number;
35
+ y: number;
36
+ }, options: ResolveOptions): CalendarTarget | null;
37
+ /**
38
+ * Snap an instant to the nearest `snapMinutes`, measured from the DAY'S OWN
39
+ * first instant.
40
+ *
41
+ * Not from midnight and not from the epoch. On a day that begins at 01:00 —
42
+ * Havana in March — snapping to the epoch puts every slot boundary an hour away
43
+ * from the rails the grid drew, in exactly the zones where a user is least able
44
+ * to explain what they are seeing.
45
+ */
46
+ export declare function snapInstant(zone: TimeZone, day: PlainDate, instant: Instant, snapMinutes: number): Instant;
47
+ export interface CalendarDragOrigin {
48
+ readonly event: TimedEvent;
49
+ readonly kind: DragKind;
50
+ /** The target under the pointer when the gesture activated. */
51
+ readonly from: CalendarTarget;
52
+ }
53
+ export interface CalendarDragResult {
54
+ /**
55
+ * The change, as a CALENDAR duration — never milliseconds.
56
+ *
57
+ * "One day later" is 23 hours across a spring-forward boundary and 25 across
58
+ * a fall-back. A user dragging an event from Saturday to Sunday expects it to
59
+ * keep its wall-clock time, and a millisecond delta cannot express that. It
60
+ * is the bug in every library surveyed.
61
+ */
62
+ readonly delta: CalendarDuration;
63
+ /** False when the gesture would leave the event exactly where it was. */
64
+ readonly moved: boolean;
65
+ /**
66
+ * Set when a resize would produce a zero or negative duration.
67
+ *
68
+ * REJECTED, NOT CLAMPED. FullCalendar returns no mutation at all;
69
+ * react-big-calendar clamps, and asymmetrically — its bottom-edge rule can
70
+ * produce a ZERO-DURATION event, which then renders as an invisible sliver
71
+ * the user cannot grab to fix. Refusing the gesture leaves the event where it
72
+ * was, which the user can see and try again from.
73
+ */
74
+ readonly invalid?: "too-short";
75
+ }
76
+ /**
77
+ * The minimum an event may be resized to, in minutes.
78
+ *
79
+ * One snap step. Anything smaller cannot be expressed by the gesture that made
80
+ * it, so it could never be undone by the same gesture.
81
+ */
82
+ export declare const MIN_DURATION_MINUTES = 15;
83
+ /**
84
+ * What a gesture from `origin` to `target` means.
85
+ *
86
+ * DAYS AND MINUTES SEPARATELY, and that separation is the whole point. The day
87
+ * component is a CALENDAR move — re-anchored to the same wall-clock time on the
88
+ * new day. The minute component is EXACT elapsed time — dragging down two hours
89
+ * means two hours. Both are true at once, and collapsing them into one number
90
+ * loses whichever property the collapse did not preserve.
91
+ */
92
+ export declare function calendarDragResult(origin: CalendarDragOrigin, target: CalendarTarget, zone: TimeZone, minDurationMinutes?: number): CalendarDragResult;
93
+ /**
94
+ * The event as it would be after `delta`, for the live preview.
95
+ *
96
+ * COMPOSED ONTO THE EVENT AT CALL TIME, never onto a snapshot taken at
97
+ * pointer-down. Two real failures from other calendars' trackers: a re-render
98
+ * replaces the event store mid-drag and the drag is left holding an instance
99
+ * from the dead one; and a concurrent server update during a drag DUPLICATES
100
+ * the times, because a snapshot was composited on top of data that had moved
101
+ * underneath it. Recomputing from whatever the event says now makes a change
102
+ * arriving mid-gesture compose rather than clobber.
103
+ */
104
+ export declare function applyCalendarDelta(event: TimedEvent, kind: DragKind, delta: CalendarDuration, zone: TimeZone): TimedEvent;
105
+ /**
106
+ * The event a drag-to-create gesture would produce.
107
+ *
108
+ * The two ends are ordered, so dragging upward creates the same event as
109
+ * dragging downward across the same span — which is what every calendar does
110
+ * and what a user expects from a rubber-band gesture.
111
+ */
112
+ export declare function createdEvent(anchor: CalendarTarget, target: CalendarTarget, minDurationMinutes?: number): {
113
+ start: Instant;
114
+ endExclusive: Instant;
115
+ day: PlainDate;
116
+ };
117
+ /**
118
+ * A human description of the position, for the live region.
119
+ *
120
+ * "Moved to 2:30 PM, Wednesday" — the SLOT, not the fact that something moved.
121
+ * "Moved" alone tells a screen-reader user nothing they can act on.
122
+ */
123
+ export declare function describeTarget(target: CalendarTarget, zone: TimeZone, locale?: string): string;
124
+ /** Where in the grid a fraction sits, for the preview. Inverse of the resolve. */
125
+ export declare function fractionOf(zone: TimeZone, day: PlainDate, instant: Instant): number;
@@ -0,0 +1,4 @@
1
+ export { isAllDay, type AllDayEvent, type CalendarEvent, type CalendarEventId, type CalendarView, type DragKind, type EventDraft, type EventPalette, type PaletteEntry, type TimedEvent, type VisibleRange, } from "./types";
2
+ export { packLanes, type LaneInput, type LaneOptions, type LanePlacement } from "./lane-packer";
3
+ export { packBand, type BandInput, type BandOptions, type BandPlacement, type BandResult } from "./band-packer";
4
+ export { allDayBandSegment, dayKey, daySlots, snapFractionToInstant, timeSegments, timedBandSegment, type BandSegment, type DaySlot, type TimeSegment, } from "./segments";
@@ -0,0 +1,88 @@
1
+ /** A half-open interval `[start, end)` in column fractions, with an identity. */
2
+ export interface LaneInput {
3
+ readonly key: string;
4
+ readonly start: number;
5
+ readonly end: number;
6
+ }
7
+ export interface LanePlacement {
8
+ readonly key: string;
9
+ /** As laid out — possibly inflated past the input by `minSpan`. */
10
+ readonly start: number;
11
+ readonly end: number;
12
+ /** 0-based lane within this event's collision batch. */
13
+ readonly column: number;
14
+ /** Lanes in that batch. Uniform across every member of it — see below. */
15
+ readonly lanes: number;
16
+ /** Fraction of the container's width, from its leading edge. */
17
+ readonly left: number;
18
+ readonly width: number;
19
+ /** Later columns paint over earlier ones. Equal to `column`. */
20
+ readonly zIndex: number;
21
+ }
22
+ export interface LaneOptions {
23
+ /**
24
+ * `cascade` — every event runs to the container's trailing edge and later
25
+ * columns paint over earlier ones. **This is the Google look and the
26
+ * default.** `split` — the batch divides the width evenly and nothing
27
+ * overlaps.
28
+ *
29
+ * Three products, three different cascade multipliers: Schedule-X runs to the
30
+ * edge, FullCalendar doubles the lane width capped at 1, and
31
+ * react-big-calendar uses 1.7x — arbitrary and unexplained anywhere in its
32
+ * source. Running to the edge is the only one of the three that is a rule
33
+ * rather than a number someone liked.
34
+ */
35
+ readonly mode?: "cascade" | "split";
36
+ /**
37
+ * The smallest span an event may occupy, as a column fraction.
38
+ *
39
+ * A 5-minute event on a 12-hour column is 0.7% of it — unclickable, and
40
+ * unreadable long before that. So it is inflated to a floor.
41
+ *
42
+ * **THE INFLATED SPAN IS WHAT COLLISION USES TOO**, which is the part that is
43
+ * easy to get wrong. Two 5-minute events a minute apart do not overlap as
44
+ * intervals, but they overlap ON SCREEN once both are inflated to a clickable
45
+ * height — so laying them in the same lane stacks one on the other. Detecting
46
+ * collisions on the true interval and drawing the inflated one is how a
47
+ * calendar ends up with events sitting invisibly behind each other.
48
+ */
49
+ readonly minSpan?: number;
50
+ /**
51
+ * Cap on lanes per batch. Beyond it, events STACK in the last lane rather
52
+ * than disappear.
53
+ *
54
+ * A week column is around 120px; a fifth lane in it is 24px and unreadable.
55
+ * But hiding an event in a time grid is worse than overlapping one — the user
56
+ * can see and click something that overlaps, and cannot do either with
57
+ * something that is not there. So the cap limits the DIVISION, not the
58
+ * membership. Day view passes no cap.
59
+ */
60
+ readonly maxLanes?: number;
61
+ /**
62
+ * Floor on the rendered width, as a fraction.
63
+ *
64
+ * Guards the width-0 collapse — an open FullCalendar bug where enough
65
+ * concurrent events divide the column into nothing and the whole batch
66
+ * becomes invisible. A floor makes a crowded column ugly instead of empty.
67
+ */
68
+ readonly minWidth?: number;
69
+ }
70
+ /**
71
+ * Lay out overlapping events across lanes.
72
+ *
73
+ * Four steps, and the third is the colouring:
74
+ *
75
+ * 1. Sort by the total order above.
76
+ * 2. Sweep into COLLISION BATCHES — a batch closes when the next event starts
77
+ * at or after the maximum end of everything accumulated so far. Two events
78
+ * in different batches provably cannot overlap, so lane counts never leak
79
+ * between them and one crowded hour does not narrow the whole day.
80
+ * 3. Within a batch, give each event the SMALLEST lane index not taken by an
81
+ * earlier member it overlaps. That is greedy colouring of an interval
82
+ * graph, and on interval graphs greedy in start order is OPTIMAL — it uses
83
+ * exactly the number of lanes the maximum concurrency requires.
84
+ * 4. `lanes = maxColumn + 1`, computed ONCE PER BATCH and applied uniformly to
85
+ * every member. Per-event lane counts are what make two side-by-side
86
+ * events different widths for no visible reason.
87
+ */
88
+ export declare function packLanes(inputs: readonly LaneInput[], options?: LaneOptions): LanePlacement[];
@@ -0,0 +1,91 @@
1
+ import { isoDateString, type Instant, type PlainDate, type TimeZone } from "@/lib/time";
2
+ import type { AllDayEvent, CalendarEvent, TimedEvent } from "./types";
3
+ /** One day's worth of a timed event, positioned within that day's column. */
4
+ export interface TimeSegment {
5
+ readonly event: TimedEvent;
6
+ readonly day: PlainDate;
7
+ /** Index into the range's `days`, so a view can address a column directly. */
8
+ readonly dayIndex: number;
9
+ /** Fraction down the column, 0 at the day's first instant, 1 at the next day's. */
10
+ readonly top: number;
11
+ readonly bottom: number;
12
+ /** False when the event began before this day — draw the top edge as cut. */
13
+ readonly isStart: boolean;
14
+ /** False when the event continues past this day. */
15
+ readonly isEnd: boolean;
16
+ }
17
+ /** A run of whole days, for the month grid or the all-day band. */
18
+ export interface BandSegment {
19
+ readonly event: CalendarEvent;
20
+ /** Inclusive column index within the row. */
21
+ readonly startColumn: number;
22
+ readonly endColumn: number;
23
+ readonly isStart: boolean;
24
+ readonly isEnd: boolean;
25
+ }
26
+ /**
27
+ * Cut a timed event into one segment per day it touches.
28
+ *
29
+ * `days` is a contiguous run — a week, or a single day. Days the event does not
30
+ * touch produce nothing.
31
+ */
32
+ export declare function timeSegments(zone: TimeZone, days: readonly PlainDate[], event: TimedEvent): TimeSegment[];
33
+ /**
34
+ * Where an all-day event sits within a row of days.
35
+ *
36
+ * `null` when it does not reach this row at all. Both `endColumn` and the
37
+ * event's own end are handled here so no caller ever does the ±1: the model is
38
+ * half-open (`endExclusive` is the first day NOT in the event) and a column
39
+ * index is inclusive, so the conversion happens once, here.
40
+ */
41
+ export declare function allDayBandSegment(rowDays: readonly PlainDate[], event: AllDayEvent): BandSegment | null;
42
+ /**
43
+ * Where a TIMED event sits within a row of days, as whole columns.
44
+ *
45
+ * The month grid draws timed events as chips in a day cell, so a timed event
46
+ * that crosses midnight occupies both cells and needs the same clipping
47
+ * booleans an all-day bar does.
48
+ */
49
+ export declare function timedBandSegment(zone: TimeZone, rowDays: readonly PlainDate[], event: TimedEvent): BandSegment | null;
50
+ /** One horizontal rail in the time grid, and the wall time it is labelled by. */
51
+ export interface DaySlot {
52
+ readonly instant: Instant;
53
+ /** Position down the column, 0–1. */
54
+ readonly fraction: number;
55
+ /** 0–23. On a fall-back day one value appears TWICE — see below. */
56
+ readonly hour: number;
57
+ readonly minute: number;
58
+ /** True for the second of a repeated reading, so a view can mark it. */
59
+ readonly repeated: boolean;
60
+ }
61
+ /**
62
+ * The rails for one day, generated by WALKING WALL-CLOCK TIME through the zone.
63
+ *
64
+ * NOT by dividing the column into 24. That is the difference between a
65
+ * fall-back day showing **25 rails with 1 AM twice** — which is what the clock
66
+ * on the wall actually did — and showing 24 evenly spaced labels that are each
67
+ * an hour wrong after 02:00.
68
+ *
69
+ * Walking forward by real elapsed time and reading the clock at each step is
70
+ * also what makes the 30-minute zone fall out for free: Lord Howe's short day
71
+ * produces 23 hourly rails and a half-hour remainder, with no branch.
72
+ */
73
+ export declare function daySlots(zone: TimeZone, day: PlainDate, slotMinutes?: number): DaySlot[];
74
+ /**
75
+ * The instant a pointer at `fraction` down `day`'s column is over, snapped.
76
+ *
77
+ * SNAP IS A HIT-CHANGE, NOT COORDINATE ROUNDING, and the difference is what the
78
+ * gesture feels like. Resolving which slot the pointer is IN and only reacting
79
+ * when that slot changes makes the preview jump discretely between positions,
80
+ * and **that discreteness IS the feedback** — a preview that tracks the pointer
81
+ * continuously and rounds on drop reads as mushy and imprecise.
82
+ *
83
+ * `snapMinutes` is deliberately independent of the rail spacing. FullCalendar,
84
+ * react-big-calendar and Schedule-X all couple them; Google and Mobiscroll do
85
+ * not, and **Google is 15-minute snap on 60-minute rails**, which is the
86
+ * combination that feels right. Retrofitting the split is a rewrite, so the two
87
+ * are separate values from the first commit.
88
+ */
89
+ export declare function snapFractionToInstant(zone: TimeZone, day: PlainDate, fraction: number, snapMinutes: number): Instant;
90
+ /** Stable key for a day, for maps and React keys. */
91
+ export declare const dayKey: typeof isoDateString;
@@ -0,0 +1,166 @@
1
+ import type { CalendarDuration, Instant, PlainDate, TimeZone } from "@/lib/time/types";
2
+ export type CalendarEventId = string;
3
+ interface EventCommon {
4
+ readonly id: CalendarEventId;
5
+ readonly title: string;
6
+ /**
7
+ * Which series this occurrence belongs to, if any.
8
+ *
9
+ * PRESENT FROM THE FIRST COMMIT ALTHOUGH RECURRENCE SHIPS LATER, because
10
+ * this is the half that cannot be added afterwards. The moment any real data
11
+ * exists, backfilling series identity onto rows that never had it is a
12
+ * migration nobody can write correctly — there is no way to tell, later,
13
+ * which of two identical Tuesday stand-ups belonged to which series.
14
+ */
15
+ readonly seriesId?: string;
16
+ /**
17
+ * A short human label for the calendar this event came from, rendered ON the
18
+ * chip.
19
+ *
20
+ * NOT decoration, and not satisfied by a legend. Colour-coding is only
21
+ * conforming when the information it carries is also available another way,
22
+ * and the remedy has to sit on the coded item itself — a key elsewhere on the
23
+ * page requires the reader to hold a colour in their head and go looking.
24
+ */
25
+ readonly calendarLabel?: string;
26
+ /** A key into the calendar's palette. Never a raw colour — see `EventPalette`. */
27
+ readonly paletteKey?: string;
28
+ /**
29
+ * Whether this event may be dragged, resized, or otherwise moved.
30
+ *
31
+ * Defaults to editable at the calendar level, not here: an undefined value
32
+ * means "ask the calendar", and only an explicit `false` pins one event down
33
+ * while its neighbours stay live.
34
+ */
35
+ readonly editable?: boolean;
36
+ /** Anything the consumer wants back in a render prop or an event handler. */
37
+ readonly data?: unknown;
38
+ }
39
+ /**
40
+ * An event with a time of day, anchored to a real instant.
41
+ *
42
+ * Both ends are `Instant`s, so the event means the same moment regardless of
43
+ * which zone renders it. A meeting at 09:00 in New York is at 14:00 in London
44
+ * and both are the same event; storing wall-clock fields instead makes it two
45
+ * different events that happen to be spelled alike.
46
+ */
47
+ export interface TimedEvent extends EventCommon {
48
+ readonly allDay: false;
49
+ readonly start: Instant;
50
+ /**
51
+ * The first instant NOT in the event. Half-open: `start <= t < endExclusive`.
52
+ *
53
+ * THE NAME IS THE DOCUMENTATION, deliberately. Half-open intervals make
54
+ * `duration = end - start` correct, make adjacent events provably
55
+ * non-overlapping, and make every algorithm in the layout core fall out
56
+ * without a `+1` anywhere — overlap is `aStart < bEnd && bStart < aEnd`, with
57
+ * no special case for two events that merely touch.
58
+ *
59
+ * The cost is the most-reported bug in calendar interoperability: a
60
+ * one-day event stored as 23rd → 24th renders as two days in any consumer
61
+ * that reads the end as inclusive. So the ±1 conversion happens in exactly
62
+ * TWO places — the display formatter and the date-picker binding — and the
63
+ * field is named so that nobody has to remember which convention this is.
64
+ */
65
+ readonly endExclusive: Instant;
66
+ /**
67
+ * The start this occurrence had when the series first produced it.
68
+ *
69
+ * THE PERMANENT JOIN KEY FOR AN OVERRIDE, and the single most common
70
+ * recurrence-model mistake is keying by the CURRENT start instead. Do that
71
+ * and the override becomes unjoinable the moment somebody drags the event:
72
+ * the series still generates an occurrence at the original time, the
73
+ * override now claims a different one, and the calendar shows both.
74
+ *
75
+ * Set once, never updated. Absent on an event that is not part of a series.
76
+ */
77
+ readonly originalStart?: Instant;
78
+ }
79
+ /**
80
+ * An event that occupies whole days.
81
+ *
82
+ * IT CARRIES NO ZONE, AND THAT IS THE POINT. A birthday is on the 4th of March
83
+ * everywhere; model it as an instant and it moves to the 3rd for anyone far
84
+ * enough west. `PlainDate` has no offset to be wrong about.
85
+ */
86
+ export interface AllDayEvent extends EventCommon {
87
+ readonly allDay: true;
88
+ readonly start: PlainDate;
89
+ /** The first day NOT in the event — same half-open rule as `TimedEvent`. */
90
+ readonly endExclusive: PlainDate;
91
+ /** See `TimedEvent.originalStart`. A date, because an all-day event has no time. */
92
+ readonly originalStart?: PlainDate;
93
+ }
94
+ export type CalendarEvent = TimedEvent | AllDayEvent;
95
+ /** Narrowing helper, so consumers never test `allDay` by hand. */
96
+ export declare function isAllDay(event: CalendarEvent): event is AllDayEvent;
97
+ /** Which part of an event a gesture is moving. */
98
+ export type DragKind = "move" | "resize-start" | "resize-end" | "create";
99
+ /**
100
+ * A gesture in progress, as a DELTA against the committed event.
101
+ *
102
+ * NEVER A REWRITTEN COPY OF THE EVENT, and never a reference to one. Two real
103
+ * failures from other calendars' trackers, both of which this shape makes
104
+ * impossible:
105
+ *
106
+ * A re-render replaces the event store mid-drag, and the drag is left holding
107
+ * an instance from the store that no longer exists — so the drop writes stale
108
+ * values over fresh ones.
109
+ *
110
+ * A concurrent update arrives from a server during a drag and the times end
111
+ * up DUPLICATED, because a snapshot taken at pointer-down was composited on
112
+ * top of data that had moved underneath it.
113
+ *
114
+ * A delta keyed by id composes instead of clobbering: whatever the event says
115
+ * at the moment of the drop, the gesture's meaning is "two hours later than
116
+ * that", and a change arriving underneath is respected rather than overwritten.
117
+ *
118
+ * `delta` IS A CALENDAR DURATION, not a number of milliseconds — see
119
+ * `CalendarDuration`. Dragging across a spring-forward boundary must preserve
120
+ * the wall-clock time, and a millisecond delta cannot express that.
121
+ */
122
+ export interface EventDraft {
123
+ readonly id: CalendarEventId;
124
+ readonly kind: DragKind;
125
+ readonly delta: CalendarDuration;
126
+ }
127
+ /**
128
+ * One swatch, with its text colour ALREADY PAIRED and verified.
129
+ *
130
+ * WHY NOT COMPUTE THE TEXT COLOUR. The familiar trick — measure the fill's
131
+ * luminance and flip to black or white — fails in a band in the middle where
132
+ * NEITHER clears AA against the fill. The threshold is also not 0.5: it is
133
+ * around 0.38, and implementations that use 0.5 pick white on colours that
134
+ * needed black. Google ships two entire palettes ("white text" and "black
135
+ * text") rather than compute a flip, which is the same conclusion arrived at
136
+ * from the other direction.
137
+ *
138
+ * So the palette is curated, each pair is measured, and a consumer supplying
139
+ * arbitrary hex gets a documented refusal rather than an unreadable chip.
140
+ */
141
+ export interface PaletteEntry {
142
+ readonly key: string;
143
+ /** Human name, used in the accessible label so colour is never the only cue. */
144
+ readonly label: string;
145
+ readonly fill: string;
146
+ readonly text: string;
147
+ /** Border and left-edge accent; darker than `fill`, still AA against it. */
148
+ readonly edge: string;
149
+ }
150
+ export type EventPalette = readonly PaletteEntry[];
151
+ export type CalendarView = "day" | "week" | "month";
152
+ /**
153
+ * The days a view is currently showing, and the zone it is showing them in.
154
+ *
155
+ * `days` is EXPLICIT rather than a start/end pair, because a month grid's days
156
+ * are not a contiguous range in any useful sense — they cross two month
157
+ * boundaries and the layout core needs to address them positionally.
158
+ */
159
+ export interface VisibleRange {
160
+ readonly view: CalendarView;
161
+ readonly zone: TimeZone;
162
+ readonly days: readonly PlainDate[];
163
+ /** 0 = Sunday. Carried on the range so the packers never have to guess. */
164
+ readonly weekStartsOn: number;
165
+ }
166
+ export {};
@@ -0,0 +1,7 @@
1
+ import { type ClassValue } from "clsx";
2
+ /**
3
+ * Merge conditional class names, resolving Tailwind conflicts last-wins.
4
+ * Every component funnels its class composition through this so a consumer's
5
+ * `className` always beats the component's own defaults.
6
+ */
7
+ export declare function cn(...inputs: ClassValue[]): string;