@heyramzi/ui 2.9.0 → 2.10.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 (312) hide show
  1. package/dist/agents/helpers.js +52 -0
  2. package/dist/agents/index.js +3 -0
  3. package/dist/agents/page-state.js +65 -0
  4. package/dist/agents/types.js +1 -0
  5. package/dist/agents/vendor/color.js +149 -0
  6. package/dist/agents/vendor/draw.js +548 -0
  7. package/dist/agents/vendor/engine.js +632 -0
  8. package/dist/agents/vendor/mesh.js +727 -0
  9. package/dist/agents/vendor/plastic.js +3273 -0
  10. package/dist/agents/vendor/presets.js +171 -0
  11. package/dist/agents/vendor/shapes.js +24 -0
  12. package/dist/agents/vendor/ticker.js +56 -0
  13. package/dist/agents/vendor/types.js +0 -0
  14. package/dist/agents/vendor/wear.js +1525 -0
  15. package/dist/ai/ai-button/index.js +2 -0
  16. package/dist/ai/confirmation/confirmation-context.svelte.js +12 -0
  17. package/dist/ai/confirmation/index.js +9 -0
  18. package/dist/ai/generation-progress/index.js +2 -0
  19. package/dist/ai/index.js +11 -0
  20. package/dist/ai/loading-state/index.js +3 -0
  21. package/dist/ai/prompt-input/index.js +6 -0
  22. package/dist/ai/reasoning/index.js +4 -0
  23. package/dist/ai/reasoning/reasoning-context.svelte.js +12 -0
  24. package/dist/ai/response/index.js +3 -0
  25. package/dist/ai/suggestion/index.js +3 -0
  26. package/dist/ai/thinking-dots/index.js +3 -0
  27. package/dist/ai/typing-dots/index.js +2 -0
  28. package/dist/ai/voice-waveform/index.js +3 -0
  29. package/dist/animations/text-swap.js +30 -0
  30. package/dist/brand/index.js +65 -0
  31. package/dist/canvas/card/resize.js +10 -0
  32. package/dist/canvas/edges/edge-path.js +284 -0
  33. package/dist/canvas/editor/context-menu.js +42 -0
  34. package/dist/canvas/editor/dispatch.svelte.js +157 -0
  35. package/dist/canvas/editor/editor-context.js +8 -0
  36. package/dist/canvas/editor/editor-mode.js +0 -0
  37. package/dist/canvas/editor/frame.js +87 -0
  38. package/dist/canvas/editor/hand-context.js +8 -0
  39. package/dist/canvas/editor/history-core.js +221 -0
  40. package/dist/canvas/editor/keymap.js +193 -0
  41. package/dist/canvas/editor/layout-actions.js +170 -0
  42. package/dist/canvas/editor/lock.js +65 -0
  43. package/dist/canvas/editor/rebase.js +279 -0
  44. package/dist/canvas/editor/style.js +174 -0
  45. package/dist/canvas/editor/text-field-context.js +8 -0
  46. package/dist/canvas/editor/z-order.js +82 -0
  47. package/dist/canvas/headless/alignment.js +20 -0
  48. package/dist/canvas/headless/break-apart-find.js +324 -0
  49. package/dist/canvas/headless/break-apart-pieces.js +74 -0
  50. package/dist/canvas/headless/break-apart-plan.js +378 -0
  51. package/dist/canvas/headless/break-apart-style.js +93 -0
  52. package/dist/canvas/headless/break-apart.js +206 -0
  53. package/dist/canvas/headless/canvas-cleanup.js +70 -0
  54. package/dist/canvas/headless/edge-anchors.js +134 -0
  55. package/dist/canvas/headless/edge-memo.js +28 -0
  56. package/dist/canvas/headless/edge-serialization.js +31 -0
  57. package/dist/canvas/headless/figure-geometry.js +331 -0
  58. package/dist/canvas/headless/fit-viewport.js +82 -0
  59. package/dist/canvas/headless/grid.js +96 -0
  60. package/dist/canvas/headless/icon-node.js +45 -0
  61. package/dist/canvas/headless/index.js +1 -0
  62. package/dist/canvas/headless/linkify.js +25 -0
  63. package/dist/canvas/headless/pen-marks.js +115 -0
  64. package/dist/canvas/headless/sketch.js +250 -0
  65. package/dist/canvas/headless/snap-guides.js +100 -0
  66. package/dist/canvas/headless/svg-figure.js +137 -0
  67. package/dist/canvas/headless/table-layout.js +161 -0
  68. package/dist/canvas/index.js +25 -0
  69. package/dist/canvas/lod/lod-mode.svelte.js +22 -0
  70. package/dist/canvas/lod/render-all.svelte.js +45 -0
  71. package/dist/canvas/ops/arrange.js +83 -0
  72. package/dist/canvas/ops/ops.js +318 -0
  73. package/dist/canvas/pen/colors.js +41 -0
  74. package/dist/canvas/pen/eraser.js +35 -0
  75. package/dist/canvas/pen/geometry.js +143 -0
  76. package/dist/canvas/pen/index.js +9 -0
  77. package/dist/canvas/pen/ops.js +15 -0
  78. package/dist/canvas/pen/pen-session.js +171 -0
  79. package/dist/canvas/pen/plugin.js +129 -0
  80. package/dist/canvas/pen/shapes.js +80 -0
  81. package/dist/canvas/pen/stroke-path.js +37 -0
  82. package/dist/canvas/pen/types.js +30 -0
  83. package/dist/canvas/pen/ui.js +20 -0
  84. package/dist/canvas/plugin.js +51 -0
  85. package/dist/canvas/screen/glyphs.js +24 -0
  86. package/dist/canvas/screen/labels.js +24 -0
  87. package/dist/canvas/screen/parts.js +140 -0
  88. package/dist/canvas/screen/plugin.js +71 -0
  89. package/dist/canvas/screen/types.js +44 -0
  90. package/dist/canvas/screen/ui.js +13 -0
  91. package/dist/canvas/test-utils.js +18 -0
  92. package/dist/canvas/types.js +0 -0
  93. package/dist/canvas/ui/forward-wheel.js +27 -0
  94. package/dist/canvas/ui/icons.js +133 -0
  95. package/dist/canvas/ui/place-panel.js +57 -0
  96. package/dist/canvas/ui/shortcut-tip.js +18 -0
  97. package/dist/canvas/ui/tools.js +411 -0
  98. package/dist/charts/dashboard/chart.js +1 -0
  99. package/dist/charts/dashboard/data-table.js +7 -0
  100. package/dist/charts/dashboard/index.js +13 -0
  101. package/dist/charts/dashboard/windows.js +5 -0
  102. package/dist/charts/edge-fade.js +7 -0
  103. package/dist/charts/hover-band.js +13 -0
  104. package/dist/charts/index.js +19 -0
  105. package/dist/charts/motion.js +15 -0
  106. package/dist/charts/primitives/chart-utils.js +22 -0
  107. package/dist/charts/primitives/index.js +4 -0
  108. package/dist/components/copy/clipboard.js +38 -0
  109. package/dist/components/copy/copied.svelte.js +26 -0
  110. package/dist/components/copy/index.js +3 -0
  111. package/dist/components/data-table/data-table.js +55 -0
  112. package/dist/components/data-table/index.js +7 -0
  113. package/dist/components/docs/index.js +3 -0
  114. package/dist/components/docs/scroll-spy.svelte.js +71 -0
  115. package/dist/components/field-row/index.js +1 -0
  116. package/dist/components/hold-to-confirm/index.js +1 -0
  117. package/dist/components/icon/index.js +1 -0
  118. package/dist/components/language-flag/index.js +1 -0
  119. package/dist/components/list-page/filter-section.js +4 -0
  120. package/dist/components/list-page/index.js +25 -0
  121. package/dist/components/list-page/list-table.js +5 -0
  122. package/dist/components/list-page/queue-rail.js +3 -0
  123. package/dist/components/list-page/section-host.js +8 -0
  124. package/dist/components/list-page/step.js +5 -0
  125. package/dist/components/list-page/types.js +0 -0
  126. package/dist/components/locale-switch/index.js +1 -0
  127. package/dist/components/mark/index.js +1 -0
  128. package/dist/components/open-in/index.js +1 -0
  129. package/dist/components/picker/index.js +3 -0
  130. package/dist/components/picker/trigger.js +33 -0
  131. package/dist/components/picker/types.js +0 -0
  132. package/dist/components/section-card/index.js +1 -0
  133. package/dist/components/section-header/index.js +2 -0
  134. package/dist/components/segmented/collapse.js +32 -0
  135. package/dist/components/segmented/index.js +8 -0
  136. package/dist/components/segmented/segmented.js +50 -0
  137. package/dist/components/star-rating-input/index.js +2 -0
  138. package/dist/components/svg/index.js +1 -0
  139. package/dist/components/table-view/index.js +1 -0
  140. package/dist/components/table-view/types.js +0 -0
  141. package/dist/components/tags-input/index.js +2 -0
  142. package/dist/components/tags-input/tags.js +90 -0
  143. package/dist/components/theme/index.js +3 -0
  144. package/dist/components/toolbar/index.js +3 -0
  145. package/dist/components/toolbar/toolbar-trigger.js +4 -0
  146. package/dist/editor/anchors.js +17 -0
  147. package/dist/editor/block-id.js +62 -0
  148. package/dist/editor/block-ops.js +105 -0
  149. package/dist/editor/doc-blocks.js +181 -0
  150. package/dist/editor/extensions.js +200 -0
  151. package/dist/editor/index.js +4 -0
  152. package/dist/editor/markdown-test-helpers.js +6 -0
  153. package/dist/editor/markdown.js +486 -0
  154. package/dist/editor/serializer.js +268 -0
  155. package/dist/editor/slash-items.js +104 -0
  156. package/dist/editor/youtube-url.js +27 -0
  157. package/dist/effects/animated-beam/index.js +1 -0
  158. package/dist/effects/animated-beam/path-calculator.svelte.js +42 -0
  159. package/dist/effects/animated-beam/types.js +0 -0
  160. package/dist/effects/border-beam/css.js +420 -0
  161. package/dist/effects/border-beam/presets.js +1792 -0
  162. package/dist/effects/border-beam/register-properties.js +39 -0
  163. package/dist/effects/border-beam/types.js +0 -0
  164. package/dist/effects/image-comparison/compare.js +4 -0
  165. package/dist/effects/image-reveal/index.js +1 -0
  166. package/dist/effects/image-reveal/types.js +0 -0
  167. package/dist/effects/magnetic/magnetic.js +54 -0
  168. package/dist/effects/reveal/index.js +4 -0
  169. package/dist/effects/reveal/observe.js +43 -0
  170. package/dist/effects/reveal/types.js +0 -0
  171. package/dist/effects/shader-gradient/color.js +34 -0
  172. package/dist/effects/shader-gradient/index.js +1 -0
  173. package/dist/effects/shader-gradient/renderer.js +320 -0
  174. package/dist/effects/shader-gradient/shaders.js +280 -0
  175. package/dist/effects/shader-gradient/types.js +0 -0
  176. package/dist/icons/apple-symbol-exports.js +126 -0
  177. package/dist/icons/sf-symbols.js +465 -0
  178. package/dist/icons/trades.js +34 -0
  179. package/dist/inbox/index.js +4 -0
  180. package/dist/inbox/logic.js +156 -0
  181. package/dist/inbox/types.js +46 -0
  182. package/dist/index.js +18 -0
  183. package/dist/lib/arrive.js +13 -0
  184. package/dist/lib/icon-types.js +0 -0
  185. package/dist/lib/initials.js +17 -0
  186. package/dist/lib/layout.js +1 -0
  187. package/dist/lib/panel.js +3 -0
  188. package/dist/lib/result.js +26 -0
  189. package/dist/lib/sliding-pill.js +45 -0
  190. package/dist/lib/theme-transition.js +53 -0
  191. package/dist/lib/tone.js +32 -0
  192. package/dist/lib/utils.js +5 -0
  193. package/dist/onboarding/define-tours.js +28 -0
  194. package/dist/onboarding/index.js +4 -0
  195. package/dist/onboarding/onboarding.svelte.js +15 -0
  196. package/dist/onboarding/pick.js +16 -0
  197. package/dist/onboarding/stores.js +50 -0
  198. package/dist/onboarding/types.js +1 -0
  199. package/dist/onboarding/wait.js +25 -0
  200. package/dist/panel/index.js +1 -0
  201. package/dist/panel/side-panel-types.js +0 -0
  202. package/dist/record/demo-data.js +512 -0
  203. package/dist/record/fields.js +148 -0
  204. package/dist/record/format.js +97 -0
  205. package/dist/record/gutter.js +1 -0
  206. package/dist/record/index.js +15 -0
  207. package/dist/record/kinds.js +110 -0
  208. package/dist/record/logic.js +255 -0
  209. package/dist/record/types.js +52 -0
  210. package/dist/shadcn/accordion/index.js +5 -0
  211. package/dist/shadcn/alert/index.js +5 -0
  212. package/dist/shadcn/alert-dialog/index.js +12 -0
  213. package/dist/shadcn/attachment/index.js +10 -0
  214. package/dist/shadcn/avatar/index.js +7 -0
  215. package/dist/shadcn/badge/index.js +2 -0
  216. package/dist/shadcn/breadcrumb/index.js +8 -0
  217. package/dist/shadcn/bubble/index.js +5 -0
  218. package/dist/shadcn/button/index.js +2 -0
  219. package/dist/shadcn/calendar/index.js +19 -0
  220. package/dist/shadcn/card/index.js +8 -0
  221. package/dist/shadcn/checkbox/index.js +2 -0
  222. package/dist/shadcn/code-block/index.js +9 -0
  223. package/dist/shadcn/collapsible/index.js +4 -0
  224. package/dist/shadcn/command/index.js +13 -0
  225. package/dist/shadcn/context-menu/index.js +17 -0
  226. package/dist/shadcn/dialog/index.js +11 -0
  227. package/dist/shadcn/dropdown-menu/index.js +19 -0
  228. package/dist/shadcn/dropdown-menu/menu-item.js +23 -0
  229. package/dist/shadcn/empty/index.js +7 -0
  230. package/dist/shadcn/field/index.js +12 -0
  231. package/dist/shadcn/hooks/highlighter.js +92 -0
  232. package/dist/shadcn/hooks/is-mobile.svelte.js +7 -0
  233. package/dist/shadcn/hooks/use-highlighted-code.svelte.js +65 -0
  234. package/dist/shadcn/hover-card/index.js +5 -0
  235. package/dist/shadcn/input/index.js +3 -0
  236. package/dist/shadcn/input-otp/index.js +5 -0
  237. package/dist/shadcn/kbd/index.js +3 -0
  238. package/dist/shadcn/label/index.js +2 -0
  239. package/dist/shadcn/marker/index.js +4 -0
  240. package/dist/shadcn/message/index.js +7 -0
  241. package/dist/shadcn/message-scroller/index.js +8 -0
  242. package/dist/shadcn/popover/index.js +9 -0
  243. package/dist/shadcn/progress/index.js +2 -0
  244. package/dist/shadcn/progress/tone.js +11 -0
  245. package/dist/shadcn/radio-group/index.js +3 -0
  246. package/dist/shadcn/scroll-area/index.js +3 -0
  247. package/dist/shadcn/select/index.js +12 -0
  248. package/dist/shadcn/separator/index.js +2 -0
  249. package/dist/shadcn/sheet/index.js +11 -0
  250. package/dist/shadcn/sidebar/constants.js +6 -0
  251. package/dist/shadcn/sidebar/context.svelte.js +38 -0
  252. package/dist/shadcn/sidebar/index.js +25 -0
  253. package/dist/shadcn/skeleton/index.js +2 -0
  254. package/dist/shadcn/slider/index.js +2 -0
  255. package/dist/shadcn/sonner/index.js +1 -0
  256. package/dist/shadcn/spinner/index.js +1 -0
  257. package/dist/shadcn/switch/index.js +2 -0
  258. package/dist/shadcn/table/index.js +9 -0
  259. package/dist/shadcn/tabs/index.js +5 -0
  260. package/dist/shadcn/textarea/index.js +2 -0
  261. package/dist/shadcn/toggle/index.js +3 -0
  262. package/dist/shadcn/toggle-group/index.js +3 -0
  263. package/dist/shadcn/tooltip/context.js +8 -0
  264. package/dist/shadcn/tooltip/index.js +6 -0
  265. package/dist/shadcn/trace/index.js +9 -0
  266. package/dist/slides/bridges.js +66 -0
  267. package/dist/slides/deck-controller.svelte.js +221 -0
  268. package/dist/slides/export/capture.js +81 -0
  269. package/dist/slides/export/ffmpeg.js +85 -0
  270. package/dist/slides/export/index.js +4 -0
  271. package/dist/slides/export/launch.js +8 -0
  272. package/dist/slides/export/pdf.js +78 -0
  273. package/dist/slides/export/types.js +0 -0
  274. package/dist/slides/index.js +7 -0
  275. package/dist/slides/labels.js +26 -0
  276. package/dist/slides/layout.js +47 -0
  277. package/dist/slides/model.js +9 -0
  278. package/dist/slides/navigation.js +89 -0
  279. package/dist/slides/types.js +6 -0
  280. package/dist/status/define-statuses.js +16 -0
  281. package/dist/status/index.js +4 -0
  282. package/dist/status/status-types.js +0 -0
  283. package/dist/test-setup.js +26 -0
  284. package/dist/thread/index.js +3 -0
  285. package/dist/thread/logic.js +94 -0
  286. package/dist/thread/types.js +23 -0
  287. package/dist/work/board-order.js +109 -0
  288. package/dist/work/dates.js +19 -0
  289. package/dist/work/detail/detail-types.js +20 -0
  290. package/dist/work/docs/edited.js +39 -0
  291. package/dist/work/docs/index.js +7 -0
  292. package/dist/work/docs/labels.js +38 -0
  293. package/dist/work/docs/menu.js +121 -0
  294. package/dist/work/docs/outline.js +39 -0
  295. package/dist/work/gantt/logic.js +260 -0
  296. package/dist/work/inbox/inbox-logic.js +94 -0
  297. package/dist/work/inbox/inbox-statuses.js +86 -0
  298. package/dist/work/inbox/inbox-types.js +0 -0
  299. package/dist/work/inbox/index.js +1 -0
  300. package/dist/work/index.js +21 -0
  301. package/dist/work/kanban-drag.js +25 -0
  302. package/dist/work/kanban-types.js +0 -0
  303. package/dist/work/presets/sales.js +35 -0
  304. package/dist/work/reorder.js +10 -0
  305. package/dist/work/task-types.js +0 -0
  306. package/dist/work/time/duration.js +60 -0
  307. package/dist/work/time/time-types.js +25 -0
  308. package/dist/work/use-kanban-dnd.svelte.js +128 -0
  309. package/package.json +45 -3
  310. package/src/components/toolbar/toolbar-trigger.ts +8 -2
  311. package/src/record/demo-data.ts +4 -4
  312. package/src/record/record-demo.svelte +2 -2
@@ -0,0 +1,89 @@
1
+ export const visibleIndexes = (slides)=>slides.flatMap((slide, index)=>slide.hidden ? [] : [
2
+ index
3
+ ]);
4
+ const clamp = (value, min, max)=>Math.min(max, Math.max(min, value));
5
+ export function settle(slides, position) {
6
+ const visible = visibleIndexes(slides);
7
+ if (visible.length === 0) return {
8
+ index: 0,
9
+ step: 0
10
+ };
11
+ const index = visible.find((i)=>i >= position.index) ?? visible[visible.length - 1];
12
+ return {
13
+ index,
14
+ step: clamp(position.step, 0, slides[index].steps)
15
+ };
16
+ }
17
+ export function nextPosition(slides, from, loop = false) {
18
+ const visible = visibleIndexes(slides);
19
+ if (visible.length === 0) return null;
20
+ if (from.step < slides[from.index].steps) return {
21
+ index: from.index,
22
+ step: from.step + 1
23
+ };
24
+ const next = visible.find((i)=>i > from.index);
25
+ if (next !== undefined) return {
26
+ index: next,
27
+ step: 0
28
+ };
29
+ return loop ? {
30
+ index: visible[0],
31
+ step: 0
32
+ } : null;
33
+ }
34
+ export function prevPosition(slides, from, loop = false) {
35
+ const visible = visibleIndexes(slides);
36
+ if (visible.length === 0) return null;
37
+ if (from.step > 0) return {
38
+ index: from.index,
39
+ step: from.step - 1
40
+ };
41
+ const before = visible.filter((i)=>i < from.index);
42
+ const index = before.length ? before[before.length - 1] : loop ? visible[visible.length - 1] : undefined;
43
+ return index === undefined ? null : {
44
+ index,
45
+ step: slides[index].steps
46
+ };
47
+ }
48
+ export function ordinalOf(slides, index) {
49
+ const visible = visibleIndexes(slides);
50
+ return {
51
+ n: Math.max(0, visible.indexOf(index)) + 1,
52
+ of: visible.length
53
+ };
54
+ }
55
+ export function progressOf(slides, position) {
56
+ const visible = visibleIndexes(slides);
57
+ if (visible.length === 0) return 0;
58
+ const at = Math.max(0, visible.indexOf(position.index));
59
+ const steps = slides[position.index]?.steps ?? 0;
60
+ const share = steps > 0 ? (position.step + 1) / (steps + 1) : 1;
61
+ return (at + share) / visible.length;
62
+ }
63
+ export function parseSlideParam(raw, total) {
64
+ if (!raw || !/^\d+$/.test(raw)) return null;
65
+ const index = Number(raw) - 1;
66
+ return index >= 0 && index < total ? index : null;
67
+ }
68
+ const KEYS = {
69
+ ArrowRight: "next",
70
+ PageDown: "next",
71
+ ArrowLeft: "prev",
72
+ PageUp: "prev",
73
+ ArrowUp: "up",
74
+ ArrowDown: "down",
75
+ Home: "first",
76
+ End: "last",
77
+ Enter: "select",
78
+ Escape: "close",
79
+ o: "overview",
80
+ O: "overview",
81
+ f: "fullscreen",
82
+ F: "fullscreen",
83
+ p: "presenter",
84
+ P: "presenter"
85
+ };
86
+ export function keyAction(key, shift = false) {
87
+ if (key === " ") return shift ? "prev" : "next";
88
+ return KEYS[key] ?? null;
89
+ }
@@ -0,0 +1,6 @@
1
+ export const DECK_KEY = Symbol("heyramzi.deck");
2
+ export const SLIDE_KEY = Symbol("heyramzi.slide");
3
+ export const DEFAULT_CANVAS = {
4
+ w: 960,
5
+ h: 540
6
+ };
@@ -0,0 +1,16 @@
1
+ export function defineStatuses(map) {
2
+ const lookup = map;
3
+ const find = (id)=>lookup[id];
4
+ return {
5
+ map,
6
+ ids: Object.keys(map),
7
+ has: (id)=>find(id) !== undefined,
8
+ get: find,
9
+ label: (id)=>find(id)?.label ?? id,
10
+ tone: (id)=>find(id)?.tone ?? "neutral",
11
+ icon: (id)=>find(id)?.icon,
12
+ variant: (id)=>find(id)?.variant ?? "open",
13
+ progress: (id)=>find(id)?.progress,
14
+ color: (id)=>find(id)?.color
15
+ };
16
+ }
@@ -0,0 +1,4 @@
1
+ export { default as StatusBadge } from "../../src/status/status-badge.svelte";
2
+ export { default as StatusDot } from "../../src/status/status-dot.svelte";
3
+ export { default as StatusIcon } from "../../src/status/status-icon.svelte";
4
+ export { defineStatuses } from "./define-statuses.js";
File without changes
@@ -0,0 +1,26 @@
1
+ class ObserverStub {
2
+ observe() {}
3
+ unobserve() {}
4
+ disconnect() {}
5
+ takeRecords() {
6
+ return [];
7
+ }
8
+ }
9
+ globalThis.ResizeObserver ??= ObserverStub;
10
+ globalThis.IntersectionObserver ??= ObserverStub;
11
+ globalThis.matchMedia ??= (query)=>({
12
+ matches: false,
13
+ media: query,
14
+ onchange: null,
15
+ addEventListener () {},
16
+ removeEventListener () {},
17
+ addListener () {},
18
+ removeListener () {},
19
+ dispatchEvent: ()=>false
20
+ });
21
+ if (globalThis.SVGElement && !("getTotalLength" in globalThis.SVGElement.prototype)) {
22
+ Object.defineProperty(globalThis.SVGElement.prototype, "getTotalLength", {
23
+ value: ()=>100,
24
+ configurable: true
25
+ });
26
+ }
@@ -0,0 +1,3 @@
1
+ export { default as Thread } from "../../src/thread/thread.svelte";
2
+ export { buildThread, fillCount, interleave, resolveThreadLabels, resolvedCount } from "./logic.js";
3
+ export { DEFAULT_THREAD_LABELS } from "./types.js";
@@ -0,0 +1,94 @@
1
+ import { DEFAULT_THREAD_LABELS } from "./types.js";
2
+ function at(iso) {
3
+ const ms = Date.parse(iso);
4
+ return Number.isNaN(ms) ? Number.POSITIVE_INFINITY : ms;
5
+ }
6
+ function time(comment) {
7
+ return at(comment.createdAt);
8
+ }
9
+ function byTime(comments) {
10
+ return comments.map((comment, index)=>({
11
+ comment,
12
+ index
13
+ })).toSorted((a, b)=>time(a.comment) - time(b.comment) || a.index - b.index).map((row)=>row.comment);
14
+ }
15
+ export function buildThread(comments) {
16
+ const byId = new Map(comments.map((comment)=>[
17
+ comment.id,
18
+ comment
19
+ ]));
20
+ function rootOf(comment) {
21
+ const seen = new Set([
22
+ comment.id
23
+ ]);
24
+ let current = comment;
25
+ for(;;){
26
+ const parent = current.parentId ? byId.get(current.parentId) : undefined;
27
+ if (!parent) return current;
28
+ if (seen.has(parent.id)) return comment;
29
+ seen.add(parent.id);
30
+ current = parent;
31
+ }
32
+ }
33
+ const replies = new Map();
34
+ const roots = [];
35
+ for (const comment of comments){
36
+ const root = rootOf(comment);
37
+ if (root.id === comment.id) roots.push(comment);
38
+ else replies.set(root.id, [
39
+ ...replies.get(root.id) ?? [],
40
+ comment
41
+ ]);
42
+ }
43
+ return byTime(roots).map((comment)=>({
44
+ comment,
45
+ replies: byTime(replies.get(comment.id) ?? [])
46
+ }));
47
+ }
48
+ export function resolvedCount(nodes) {
49
+ return nodes.filter((node)=>node.comment.resolved).length;
50
+ }
51
+ export function resolveThreadLabels(overrides) {
52
+ return {
53
+ ...DEFAULT_THREAD_LABELS,
54
+ ...overrides
55
+ };
56
+ }
57
+ export function fillCount(label, count) {
58
+ return label.replaceAll("{count}", String(count));
59
+ }
60
+ export function interleave(nodes, events) {
61
+ const timed = [
62
+ ...nodes.map((node, index)=>({
63
+ at: at(node.comment.createdAt),
64
+ index,
65
+ node
66
+ })),
67
+ ...events.map((event, index)=>({
68
+ at: at(event.at),
69
+ index: nodes.length + index,
70
+ event
71
+ }))
72
+ ].toSorted((a, b)=>a.at - b.at || a.index - b.index);
73
+ const items = [];
74
+ for (const row of timed){
75
+ if ("node" in row) {
76
+ items.push({
77
+ type: "node",
78
+ key: row.node.comment.id,
79
+ node: row.node
80
+ });
81
+ continue;
82
+ }
83
+ const last = items.at(-1);
84
+ if (last?.type === "events") last.events.push(row.event);
85
+ else items.push({
86
+ type: "events",
87
+ key: row.event.id,
88
+ events: [
89
+ row.event
90
+ ]
91
+ });
92
+ }
93
+ return items;
94
+ }
@@ -0,0 +1,23 @@
1
+ export const DEFAULT_THREAD_LABELS = {
2
+ title: "Activity",
3
+ empty: "No comments yet",
4
+ placeholder: "Leave a comment",
5
+ replyPlaceholder: "Reply",
6
+ send: "Comment",
7
+ sending: "Sending",
8
+ reply: "Reply",
9
+ edit: "Edit comment",
10
+ delete: "Delete comment",
11
+ edited: "edited",
12
+ save: "Save",
13
+ cancel: "Cancel",
14
+ resolve: "Resolve",
15
+ unresolve: "Reopen",
16
+ resolved: "Resolved",
17
+ showResolved: "Show {count} resolved",
18
+ hideResolved: "Hide resolved",
19
+ agent: "AI",
20
+ pinned: "Pinned",
21
+ showMore: "Show more",
22
+ showLess: "Show less"
23
+ };
@@ -0,0 +1,109 @@
1
+ const DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2
+ const INT_DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
3
+ const ZERO = DIGITS.charAt(0);
4
+ function integerLength(head) {
5
+ const i = INT_DIGITS.indexOf(head);
6
+ if (i === -1) throw new Error("invalid order key head: " + head);
7
+ const half = INT_DIGITS.length / 2;
8
+ return i < half ? half - i + 1 : i - half + 2;
9
+ }
10
+ function integerPart(key) {
11
+ const length = integerLength(key.charAt(0));
12
+ if (length > key.length) throw new Error("invalid order key: " + key);
13
+ return key.slice(0, length);
14
+ }
15
+ function smallestInteger() {
16
+ return INT_DIGITS.charAt(0) + ZERO.repeat(INT_DIGITS.length / 2);
17
+ }
18
+ function midpoint(a, b) {
19
+ if (b != null && a >= b) throw new Error(a + " >= " + b);
20
+ if (a.slice(-1) === ZERO || b && b.slice(-1) === ZERO) throw new Error("trailing zero");
21
+ if (b) {
22
+ let n = 0;
23
+ while((a[n] ?? ZERO) === b[n])n++;
24
+ if (n > 0) return b.slice(0, n) + midpoint(a.slice(n), b.slice(n));
25
+ }
26
+ const digitA = a ? DIGITS.indexOf(a.charAt(0)) : 0;
27
+ const digitB = b != null ? DIGITS.indexOf(b.charAt(0)) : DIGITS.length;
28
+ if (digitB - digitA > 1) {
29
+ return DIGITS.charAt(Math.round(0.5 * (digitA + digitB)));
30
+ }
31
+ if (b && b.length > 1) return b.slice(0, 1);
32
+ return DIGITS.charAt(digitA) + midpoint(a.slice(1), null);
33
+ }
34
+ function incrementInteger(x) {
35
+ const head = x.charAt(0);
36
+ let trailing = "";
37
+ for(let i = x.length - 1; i >= 1; i--){
38
+ const d = DIGITS.indexOf(x.charAt(i)) + 1;
39
+ if (d === DIGITS.length) trailing = ZERO + trailing;
40
+ else return head + x.slice(1, i) + DIGITS.charAt(d) + trailing;
41
+ }
42
+ const headIndex = INT_DIGITS.indexOf(head);
43
+ if (headIndex === INT_DIGITS.length - 1) return null;
44
+ const h = INT_DIGITS.charAt(headIndex + 1);
45
+ const delta = integerLength(h) - integerLength(head);
46
+ return h + (delta > 0 ? trailing + ZERO : delta < 0 ? trailing.slice(1) : trailing);
47
+ }
48
+ function decrementInteger(x) {
49
+ const head = x.charAt(0);
50
+ const last = DIGITS.charAt(DIGITS.length - 1);
51
+ let trailing = "";
52
+ for(let i = x.length - 1; i >= 1; i--){
53
+ const d = DIGITS.indexOf(x.charAt(i)) - 1;
54
+ if (d === -1) trailing = last + trailing;
55
+ else return head + x.slice(1, i) + DIGITS.charAt(d) + trailing;
56
+ }
57
+ const headIndex = INT_DIGITS.indexOf(head);
58
+ if (headIndex === 0) return null;
59
+ const h = INT_DIGITS.charAt(headIndex - 1);
60
+ const delta = integerLength(h) - integerLength(head);
61
+ return h + (delta > 0 ? trailing + last : delta < 0 ? trailing.slice(1) : trailing);
62
+ }
63
+ export function keyBetween(a, b) {
64
+ if (a != null && b != null && a > b) [a, b] = [
65
+ b,
66
+ a
67
+ ];
68
+ if (a == null) {
69
+ if (b == null) return INT_DIGITS.charAt(INT_DIGITS.length / 2) + ZERO;
70
+ const ib = integerPart(b);
71
+ const fb = b.slice(ib.length);
72
+ if (ib === smallestInteger()) return ib + midpoint("", fb);
73
+ if (ib < b) return ib;
74
+ const res = decrementInteger(ib);
75
+ if (res == null) throw new Error("cannot decrement any more");
76
+ return res;
77
+ }
78
+ if (b == null) {
79
+ const ia = integerPart(a);
80
+ const fa = a.slice(ia.length);
81
+ const i = incrementInteger(ia);
82
+ return i == null ? ia + midpoint(fa, null) : i;
83
+ }
84
+ const ia = integerPart(a);
85
+ const fa = a.slice(ia.length);
86
+ const ib = integerPart(b);
87
+ const fb = b.slice(ib.length);
88
+ if (ia === ib) return ia + midpoint(fa, fb);
89
+ const i = incrementInteger(ia);
90
+ if (i == null) throw new Error("cannot increment any more");
91
+ if (i < b) return i;
92
+ return ia + midpoint(fa, null);
93
+ }
94
+ export function boardOrderAt(column, index, order) {
95
+ let lower = null;
96
+ for (const item of column.slice(0, index)){
97
+ const key = order(item);
98
+ if (key != null && (lower === null || key > lower)) lower = key;
99
+ }
100
+ let upper = null;
101
+ for (const item of column.slice(index)){
102
+ const key = order(item);
103
+ if (key != null && (lower === null || key > lower)) {
104
+ upper = key;
105
+ break;
106
+ }
107
+ }
108
+ return keyBetween(lower, upper);
109
+ }
@@ -0,0 +1,19 @@
1
+ const DAY_MS = 86_400_000;
2
+ export function dayNumber(iso) {
3
+ const [y = 1970, m = 1, d = 1] = iso.slice(0, 10).split("-").map(Number);
4
+ return Math.round(Date.UTC(y, m - 1, d) / DAY_MS);
5
+ }
6
+ export function isoFromDay(day) {
7
+ return new Date(day * DAY_MS).toISOString().slice(0, 10);
8
+ }
9
+ export function addDays(iso, days) {
10
+ return isoFromDay(dayNumber(iso) + days);
11
+ }
12
+ export function todayIso() {
13
+ const now = new Date();
14
+ const local = new Date(now.getTime() - now.getTimezoneOffset() * 60_000);
15
+ return local.toISOString().slice(0, 10);
16
+ }
17
+ export function weekday(day) {
18
+ return new Date(day * DAY_MS).getUTCDay();
19
+ }
@@ -0,0 +1,20 @@
1
+ export const DEFAULT_TASK_DETAIL_LABELS = {
2
+ markComplete: "Mark complete",
3
+ markIncomplete: "Mark incomplete",
4
+ editTitle: "Edit title",
5
+ description: "Description",
6
+ addDescription: "Add a description",
7
+ editDescription: "Edit description",
8
+ save: "Save",
9
+ saving: "Saving",
10
+ cancel: "Cancel",
11
+ comments: "Activity",
12
+ commentPlaceholder: "Leave a comment",
13
+ commentSend: "Comment",
14
+ commentEdit: "Edit comment",
15
+ commentDelete: "Delete comment",
16
+ commentEdited: "edited",
17
+ commentsEmpty: "No comments yet",
18
+ ai: "AI",
19
+ properties: "Properties"
20
+ };
@@ -0,0 +1,39 @@
1
+ export function parseStamp(value) {
2
+ if (value === null || value === undefined || value === "") return null;
3
+ const date = value instanceof Date ? value : new Date(value);
4
+ return Number.isNaN(date.getTime()) ? null : date;
5
+ }
6
+ function yearOf(date, { locale = "en-US", timeZone }) {
7
+ return new Intl.DateTimeFormat(locale, {
8
+ year: "numeric",
9
+ timeZone
10
+ }).format(date);
11
+ }
12
+ export function shortDate(value, options = {}) {
13
+ const date = parseStamp(value);
14
+ if (!date) return "";
15
+ const { locale = "en-US", timeZone, now = new Date() } = options;
16
+ const sameYear = yearOf(date, options) === yearOf(now, options);
17
+ return new Intl.DateTimeFormat(locale, {
18
+ month: "short",
19
+ day: "numeric",
20
+ year: sameYear ? undefined : "numeric",
21
+ timeZone
22
+ }).format(date);
23
+ }
24
+ export function editStamp(value, options = {}) {
25
+ const date = parseStamp(value);
26
+ if (!date) return "";
27
+ const { locale = "en-US", timeZone } = options;
28
+ const time = new Intl.DateTimeFormat(locale, {
29
+ hour: "2-digit",
30
+ minute: "2-digit",
31
+ hour12: false,
32
+ timeZone
33
+ }).format(date);
34
+ return `${shortDate(date, options)}, ${time}`;
35
+ }
36
+ export function editedLabel(value, label = "Edited", options = {}) {
37
+ const day = shortDate(value, options);
38
+ return day ? `${label} ${day}` : label;
39
+ }
@@ -0,0 +1,7 @@
1
+ export { default as DocEditorPage } from "../../../src/work/docs/doc-editor-page.svelte";
2
+ export { default as DocMenu } from "../../../src/work/docs/doc-menu.svelte";
3
+ export { default as EditedChip } from "../../../src/work/docs/edited-chip.svelte";
4
+ export { DEFAULT_DOC_LABELS, docLabels } from "./labels.js";
5
+ export { anchorIds, headingsOf, outlineOf, outlineOfDoc, slugify } from "./outline.js";
6
+ export { editStamp, editedLabel, parseStamp, shortDate } from "./edited.js";
7
+ export { copyOptions, filterMenu, menuItems, shortcutLabel, shortcutTarget } from "./menu.js";
@@ -0,0 +1,38 @@
1
+ export const DEFAULT_DOC_LABELS = {
2
+ titlePlaceholder: "New document",
3
+ untitled: "Untitled",
4
+ edited: "Edited",
5
+ showAuthorNames: "Show author names",
6
+ ownedBy: "Owned by",
7
+ lastEditBy: "Last edit by",
8
+ showHistory: "Show document history",
9
+ menu: "Document actions",
10
+ filter: "Filter…",
11
+ noResults: "Nothing matches",
12
+ moveTo: "Move to",
13
+ duplicate: "Duplicate",
14
+ rename: "Rename",
15
+ template: "New template from document",
16
+ favorite: "Favorite",
17
+ unfavorite: "Remove from favorites",
18
+ copy: "Copy",
19
+ copyUrl: "Copy URL",
20
+ copyTitle: "Copy title",
21
+ copyTitleAsLink: "Copy title as link",
22
+ copyMarkdown: "Copy content as Markdown",
23
+ remind: "Remind me",
24
+ history: "Show document history",
25
+ delete: "Delete",
26
+ deleteTitle: (title)=>`Delete "${title}"`,
27
+ deleteDetail: "This can't be undone.",
28
+ cancel: "Cancel",
29
+ back: "Back",
30
+ outline: "Outline",
31
+ copyLink: "Copy link"
32
+ };
33
+ export function docLabels(partial) {
34
+ return {
35
+ ...DEFAULT_DOC_LABELS,
36
+ ...partial
37
+ };
38
+ }
@@ -0,0 +1,121 @@
1
+ import { tiptapToMarkdown } from "../../editor/markdown.js";
2
+ export const SHORTCUTS = {
3
+ move: {
4
+ key: "P",
5
+ shift: true
6
+ },
7
+ rename: {
8
+ key: "R",
9
+ shift: true
10
+ },
11
+ favorite: {
12
+ key: "F",
13
+ alt: true
14
+ },
15
+ remind: {
16
+ key: "H",
17
+ shift: true
18
+ }
19
+ };
20
+ export function shortcutLabel(shortcut) {
21
+ return `${shortcut.shift ? "⇧" : ""}${shortcut.alt ? "⌥" : ""}${shortcut.key.toUpperCase()}`;
22
+ }
23
+ export function menuItems(available, labels, options = {}) {
24
+ const all = [
25
+ {
26
+ id: "move",
27
+ label: labels.moveTo,
28
+ group: 0
29
+ },
30
+ {
31
+ id: "duplicate",
32
+ label: labels.duplicate,
33
+ group: 0
34
+ },
35
+ {
36
+ id: "rename",
37
+ label: labels.rename,
38
+ group: 0
39
+ },
40
+ {
41
+ id: "template",
42
+ label: labels.template,
43
+ group: 0
44
+ },
45
+ {
46
+ id: "favorite",
47
+ label: options.favorited ? labels.unfavorite : labels.favorite,
48
+ group: 1
49
+ },
50
+ {
51
+ id: "copy",
52
+ label: labels.copy,
53
+ submenu: true,
54
+ group: 1
55
+ },
56
+ {
57
+ id: "remind",
58
+ label: labels.remind,
59
+ group: 1
60
+ },
61
+ {
62
+ id: "history",
63
+ label: labels.history,
64
+ group: 2
65
+ },
66
+ {
67
+ id: "delete",
68
+ label: labels.delete,
69
+ danger: true,
70
+ group: 2
71
+ }
72
+ ];
73
+ return all.filter((item)=>available[item.id]).map((item)=>Object.assign(item, {
74
+ shortcut: SHORTCUTS[item.id]
75
+ }));
76
+ }
77
+ export function filterMenu(items, query) {
78
+ const words = query.toLowerCase().split(/\s+/).filter(Boolean);
79
+ if (words.length === 0) return items;
80
+ return items.filter((item)=>{
81
+ const label = item.label.toLowerCase();
82
+ return words.every((word)=>label.includes(word));
83
+ });
84
+ }
85
+ export function shortcutTarget(event, items) {
86
+ if (event.metaKey || event.ctrlKey) return null;
87
+ const hit = items.find((item)=>item.shortcut && event.code === `Key${item.shortcut.key.toUpperCase()}` && !!item.shortcut.shift === event.shiftKey && !!item.shortcut.alt === event.altKey);
88
+ return hit?.id ?? null;
89
+ }
90
+ export function copyOptions(source, labels) {
91
+ const title = source.title.trim() || labels.untitled;
92
+ const options = [];
93
+ if (source.url) options.push({
94
+ kind: "url",
95
+ label: labels.copyUrl,
96
+ text: source.url
97
+ });
98
+ options.push({
99
+ kind: "title",
100
+ label: labels.copyTitle,
101
+ text: title
102
+ });
103
+ if (source.url) {
104
+ options.push({
105
+ kind: "link",
106
+ label: labels.copyTitleAsLink,
107
+ text: `[${title.replace(/([[\]\\])/g, "\\$1")}](${source.url})`
108
+ });
109
+ }
110
+ if (source.content) {
111
+ options.push({
112
+ kind: "markdown",
113
+ label: labels.copyMarkdown,
114
+ text: tiptapToMarkdown(source.content)
115
+ });
116
+ }
117
+ return options;
118
+ }
119
+ export function deleteName(title, labels) {
120
+ return title.trim() || labels.untitled;
121
+ }
@@ -0,0 +1,39 @@
1
+ import { anchorIds } from "../../editor/anchors.js";
2
+ export { anchorIds, slugify } from "../../editor/anchors.js";
3
+ function textOf(node) {
4
+ if (node.type === "text") return node.text ?? "";
5
+ return (node.content ?? []).map(textOf).join("");
6
+ }
7
+ export function headingsOf(doc) {
8
+ const found = [];
9
+ const walk = (node)=>{
10
+ if (node.type === "heading") {
11
+ const level = typeof node.attrs?.level === "number" ? node.attrs.level : 1;
12
+ found.push({
13
+ label: textOf(node).trim(),
14
+ level
15
+ });
16
+ return;
17
+ }
18
+ for (const child of node.content ?? [])walk(child);
19
+ };
20
+ if (doc && typeof doc === "object") walk(doc);
21
+ const ids = anchorIds(found.map((heading)=>heading.label));
22
+ return found.map((heading, i)=>({
23
+ id: ids[i],
24
+ label: heading.label,
25
+ level: heading.level
26
+ }));
27
+ }
28
+ export function outlineOf(headings) {
29
+ const items = headings.filter((heading)=>(heading.level === 2 || heading.level === 3) && heading.label !== "");
30
+ if (items.length < 2) return [];
31
+ return items.map(({ id, label, level })=>({
32
+ id,
33
+ label,
34
+ level
35
+ }));
36
+ }
37
+ export function outlineOfDoc(doc) {
38
+ return outlineOf(headingsOf(doc));
39
+ }