@heyramzi/ui 2.11.0 → 2.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/helpers.js +38 -38
- package/dist/agents/page-state.js +49 -50
- package/dist/agents/vendor/color.js +146 -127
- package/dist/agents/vendor/draw.js +617 -508
- package/dist/agents/vendor/engine.js +698 -599
- package/dist/agents/vendor/mesh.js +653 -683
- package/dist/agents/vendor/plastic.js +3913 -3112
- package/dist/agents/vendor/presets.js +163 -164
- package/dist/agents/vendor/shapes.js +21 -20
- package/dist/agents/vendor/ticker.js +41 -42
- package/dist/agents/vendor/types.js +1 -0
- package/dist/agents/vendor/wear.js +1421 -1448
- package/dist/ai/confirmation/confirmation-context.svelte.js +6 -6
- package/dist/ai/confirmation/index.js +3 -1
- package/dist/ai/index.js +33 -0
- package/dist/ai/prompt-input/index.js +3 -1
- package/dist/ai/reasoning/index.js +3 -1
- package/dist/ai/reasoning/reasoning-context.svelte.js +6 -6
- package/dist/ai/suggestion/index.js +3 -1
- package/dist/ai/typing-dots/index.js +3 -1
- package/dist/animations/text-swap.js +24 -24
- package/dist/brand/index.js +54 -48
- package/dist/canvas/card/resize.js +5 -3
- package/dist/canvas/edges/edge-path.js +255 -242
- package/dist/canvas/editor/context-menu.js +39 -36
- package/dist/canvas/editor/dispatch.svelte.js +154 -151
- package/dist/canvas/editor/editor-context.js +7 -2
- package/dist/canvas/editor/editor-mode.js +1 -0
- package/dist/canvas/editor/frame.js +73 -76
- package/dist/canvas/editor/hand-context.js +5 -2
- package/dist/canvas/editor/history-core.js +163 -191
- package/dist/canvas/editor/keymap.js +95 -169
- package/dist/canvas/editor/layout-actions.js +143 -144
- package/dist/canvas/editor/lock.js +52 -51
- package/dist/canvas/editor/rebase.js +217 -240
- package/dist/canvas/editor/style.js +132 -137
- package/dist/canvas/editor/text-field-context.js +7 -2
- package/dist/canvas/editor/z-order.js +65 -70
- package/dist/canvas/headless/alignment.js +22 -16
- package/dist/canvas/headless/break-apart-find.js +286 -279
- package/dist/canvas/headless/break-apart-pieces.js +62 -58
- package/dist/canvas/headless/break-apart-plan.js +299 -325
- package/dist/canvas/headless/break-apart-style.js +75 -70
- package/dist/canvas/headless/break-apart.js +188 -181
- package/dist/canvas/headless/canvas-cleanup.js +78 -58
- package/dist/canvas/headless/edge-anchors.js +115 -116
- package/dist/canvas/headless/edge-memo.js +24 -22
- package/dist/canvas/headless/edge-serialization.js +17 -27
- package/dist/canvas/headless/figure-geometry.js +232 -264
- package/dist/canvas/headless/fit-viewport.js +84 -67
- package/dist/canvas/headless/grid.js +88 -86
- package/dist/canvas/headless/icon-node.js +44 -36
- package/dist/canvas/headless/index.js +1 -0
- package/dist/canvas/headless/linkify.js +17 -19
- package/dist/canvas/headless/pen-marks.js +101 -95
- package/dist/canvas/headless/sketch.js +231 -209
- package/dist/canvas/headless/snap-guides.js +99 -83
- package/dist/canvas/headless/svg-figure.js +133 -117
- package/dist/canvas/headless/table-layout.js +146 -107
- package/dist/canvas/index.js +2 -0
- package/dist/canvas/lod/lod-mode.svelte.js +20 -18
- package/dist/canvas/lod/render-all.svelte.js +36 -39
- package/dist/canvas/ops/arrange.js +78 -71
- package/dist/canvas/ops/ops.js +260 -255
- package/dist/canvas/pen/colors.js +37 -35
- package/dist/canvas/pen/eraser.js +28 -27
- package/dist/canvas/pen/geometry.js +120 -130
- package/dist/canvas/pen/index.js +1 -0
- package/dist/canvas/pen/ops.js +11 -11
- package/dist/canvas/pen/pen-session.js +150 -159
- package/dist/canvas/pen/plugin.js +107 -104
- package/dist/canvas/pen/shapes.js +73 -68
- package/dist/canvas/pen/stroke-path.js +32 -30
- package/dist/canvas/pen/types.js +21 -21
- package/dist/canvas/pen/ui.js +10 -8
- package/dist/canvas/plugin.js +46 -46
- package/dist/canvas/screen/glyphs.js +12 -11
- package/dist/canvas/screen/labels.js +22 -22
- package/dist/canvas/screen/parts.js +98 -111
- package/dist/canvas/screen/plugin.js +47 -56
- package/dist/canvas/screen/types.js +30 -35
- package/dist/canvas/screen/ui.js +7 -7
- package/dist/canvas/test-utils.js +14 -14
- package/dist/canvas/types.js +1 -0
- package/dist/canvas/ui/forward-wheel.js +24 -25
- package/dist/canvas/ui/icons.js +64 -131
- package/dist/canvas/ui/place-panel.js +58 -49
- package/dist/canvas/ui/shortcut-tip.js +14 -12
- package/dist/canvas/ui/tools.js +300 -385
- package/dist/charts/dashboard/chart.js +4 -0
- package/dist/charts/dashboard/data-table.js +11 -0
- package/dist/charts/dashboard/windows.js +8 -3
- package/dist/charts/edge-fade.js +10 -5
- package/dist/charts/hover-band.js +16 -11
- package/dist/charts/index.js +0 -1
- package/dist/charts/motion.js +11 -7
- package/dist/charts/primitives/chart-utils.js +12 -12
- package/dist/components/copy/clipboard.js +32 -32
- package/dist/components/copy/copied.svelte.js +31 -23
- package/dist/components/data-table/data-table.js +39 -39
- package/dist/components/docs/index.js +4 -0
- package/dist/components/docs/scroll-spy.svelte.js +73 -68
- package/dist/components/list-page/filter-section.js +4 -1
- package/dist/components/list-page/index.js +2 -0
- package/dist/components/list-page/list-table.js +7 -2
- package/dist/components/list-page/queue-rail.js +14 -0
- package/dist/components/list-page/section-host.js +4 -2
- package/dist/components/list-page/step.js +4 -3
- package/dist/components/list-page/types.js +1 -0
- package/dist/components/picker/trigger.js +48 -30
- package/dist/components/picker/types.js +1 -0
- package/dist/components/segmented/collapse.js +38 -27
- package/dist/components/segmented/index.js +8 -0
- package/dist/components/segmented/segmented.js +67 -42
- package/dist/components/star-rating-input/index.js +3 -1
- package/dist/components/table-view/types.js +1 -0
- package/dist/components/tags-input/tags.js +81 -69
- package/dist/components/theme/index.js +4 -0
- package/dist/components/toolbar/index.js +4 -0
- package/dist/components/toolbar/toolbar-trigger.js +14 -1
- package/dist/editor/anchors.js +17 -13
- package/dist/editor/block-id.js +52 -51
- package/dist/editor/block-ops.js +108 -80
- package/dist/editor/doc-blocks.js +155 -166
- package/dist/editor/extensions.js +139 -180
- package/dist/editor/index.js +4 -0
- package/dist/editor/markdown-test-helpers.js +4 -2
- package/dist/editor/markdown.js +420 -408
- package/dist/editor/serializer.js +204 -200
- package/dist/editor/slash-items.js +89 -101
- package/dist/editor/youtube-url.js +25 -20
- package/dist/effects/animated-beam/path-calculator.svelte.js +43 -38
- package/dist/effects/animated-beam/types.js +1 -0
- package/dist/effects/border-beam/css.js +92 -78
- package/dist/effects/border-beam/presets.js +1705 -1720
- package/dist/effects/border-beam/register-properties.js +43 -33
- package/dist/effects/border-beam/types.js +1 -0
- package/dist/effects/image-comparison/compare.js +3 -2
- package/dist/effects/image-reveal/types.js +1 -0
- package/dist/effects/magnetic/magnetic.js +58 -52
- package/dist/effects/reveal/observe.js +50 -40
- package/dist/effects/reveal/types.js +1 -0
- package/dist/effects/shader-gradient/color.js +36 -29
- package/dist/effects/shader-gradient/renderer.js +384 -295
- package/dist/effects/shader-gradient/shaders.js +31 -0
- package/dist/effects/shader-gradient/types.js +1 -0
- package/dist/icons/apple-symbol-exports.js +99 -124
- package/dist/icons/sf-symbols.js +357 -461
- package/dist/icons/trades.js +43 -28
- package/dist/inbox/index.js +1 -0
- package/dist/inbox/logic.js +126 -122
- package/dist/inbox/types.js +43 -43
- package/dist/lib/arrive.js +19 -12
- package/dist/lib/icon-types.js +1 -0
- package/dist/lib/initials.js +16 -10
- package/dist/lib/layout.js +5 -0
- package/dist/lib/panel.js +13 -0
- package/dist/lib/result.js +22 -22
- package/dist/lib/sliding-pill.js +59 -44
- package/dist/lib/theme-transition.js +43 -43
- package/dist/lib/tone.js +31 -24
- package/dist/lib/utils.js +3 -1
- package/dist/onboarding/define-tours.js +24 -23
- package/dist/onboarding/onboarding.svelte.js +16 -12
- package/dist/onboarding/pick.js +10 -6
- package/dist/onboarding/stores.js +40 -41
- package/dist/onboarding/wait.js +24 -23
- package/dist/panel/side-panel-types.js +1 -0
- package/dist/record/demo-data.js +459 -486
- package/dist/record/fields.js +129 -131
- package/dist/record/format.js +70 -82
- package/dist/record/gutter.js +1 -0
- package/dist/record/kinds.js +95 -105
- package/dist/record/logic.js +238 -219
- package/dist/record/types.js +49 -48
- package/dist/shadcn/accordion/index.js +3 -1
- package/dist/shadcn/alert/index.js +3 -1
- package/dist/shadcn/alert-dialog/index.js +3 -1
- package/dist/shadcn/attachment/index.js +3 -1
- package/dist/shadcn/avatar/index.js +3 -1
- package/dist/shadcn/breadcrumb/index.js +3 -1
- package/dist/shadcn/bubble/index.js +3 -1
- package/dist/shadcn/button/index.js +3 -1
- package/dist/shadcn/calendar/index.js +3 -1
- package/dist/shadcn/card/index.js +3 -1
- package/dist/shadcn/checkbox/index.js +3 -1
- package/dist/shadcn/code-block/index.js +3 -1
- package/dist/shadcn/collapsible/index.js +3 -1
- package/dist/shadcn/command/index.js +4 -1
- package/dist/shadcn/context-menu/index.js +3 -1
- package/dist/shadcn/dialog/index.js +3 -1
- package/dist/shadcn/dropdown-menu/menu-item.js +40 -20
- package/dist/shadcn/empty/index.js +3 -1
- package/dist/shadcn/field/index.js +3 -1
- package/dist/shadcn/hooks/highlighter.js +77 -75
- package/dist/shadcn/hooks/is-mobile.svelte.js +3 -3
- package/dist/shadcn/hooks/use-highlighted-code.svelte.js +62 -62
- package/dist/shadcn/input/index.js +3 -1
- package/dist/shadcn/kbd/index.js +3 -1
- package/dist/shadcn/label/index.js +3 -1
- package/dist/shadcn/marker/index.js +3 -1
- package/dist/shadcn/message/index.js +3 -1
- package/dist/shadcn/message-scroller/index.js +3 -1
- package/dist/shadcn/popover/index.js +3 -1
- package/dist/shadcn/progress/index.js +3 -1
- package/dist/shadcn/progress/tone.js +8 -7
- package/dist/shadcn/radio-group/index.js +3 -1
- package/dist/shadcn/scroll-area/index.js +3 -1
- package/dist/shadcn/select/index.js +3 -1
- package/dist/shadcn/separator/index.js +3 -1
- package/dist/shadcn/sheet/index.js +3 -1
- package/dist/shadcn/sidebar/context.svelte.js +42 -28
- package/dist/shadcn/sidebar/index.js +3 -1
- package/dist/shadcn/skeleton/index.js +3 -1
- package/dist/shadcn/slider/index.js +3 -1
- package/dist/shadcn/switch/index.js +3 -1
- package/dist/shadcn/table/index.js +3 -1
- package/dist/shadcn/tabs/index.js +3 -1
- package/dist/shadcn/textarea/index.js +3 -1
- package/dist/shadcn/toggle/index.js +3 -1
- package/dist/shadcn/toggle-group/index.js +3 -1
- package/dist/shadcn/tooltip/context.js +7 -2
- package/dist/shadcn/tooltip/index.js +3 -1
- package/dist/shadcn/trace/index.js +3 -1
- package/dist/slides/bridges.js +65 -59
- package/dist/slides/deck-controller.svelte.js +210 -207
- package/dist/slides/export/capture.js +66 -71
- package/dist/slides/export/ffmpeg.js +76 -72
- package/dist/slides/export/index.js +3 -0
- package/dist/slides/export/launch.js +9 -6
- package/dist/slides/export/pdf.js +60 -54
- package/dist/slides/export/types.js +1 -0
- package/dist/slides/labels.js +24 -24
- package/dist/slides/layout.js +39 -41
- package/dist/slides/model.js +9 -7
- package/dist/slides/navigation.js +78 -73
- package/dist/slides/types.js +2 -2
- package/dist/status/define-statuses.js +18 -14
- package/dist/status/status-types.js +1 -0
- package/dist/test-setup.js +24 -20
- package/dist/thread/logic.js +73 -77
- package/dist/thread/types.js +21 -21
- package/dist/work/board-order.js +94 -90
- package/dist/work/dates.js +16 -9
- package/dist/work/detail/detail-types.js +18 -18
- package/dist/work/docs/edited.js +32 -29
- package/dist/work/docs/index.js +4 -0
- package/dist/work/docs/labels.js +34 -34
- package/dist/work/docs/menu.js +113 -106
- package/dist/work/docs/outline.js +39 -29
- package/dist/work/gantt/logic.js +211 -235
- package/dist/work/inbox/inbox-logic.js +71 -75
- package/dist/work/inbox/inbox-statuses.js +75 -72
- package/dist/work/inbox/inbox-types.js +1 -0
- package/dist/work/kanban-drag.js +27 -22
- package/dist/work/kanban-types.js +1 -0
- package/dist/work/presets/sales.js +36 -32
- package/dist/work/reorder.js +9 -8
- package/dist/work/task-types.js +1 -0
- package/dist/work/time/duration.js +51 -46
- package/dist/work/time/time-types.js +23 -23
- package/dist/work/use-kanban-dnd.svelte.js +126 -125
- package/package.json +3 -1
- package/src/components/list-page/master-detail.svelte +3 -1
- package/src/components/list-page/rail-row.svelte +4 -4
- package/src/components/tags-input/tags-input.svelte +2 -0
- package/src/editor/markdown.ts +30 -35
|
@@ -1,89 +1,94 @@
|
|
|
1
|
-
export const visibleIndexes = (slides)=>slides.flatMap((slide, index)=>slide.hidden ? [] : [
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const clamp = (value, min, max)=>Math.min(max, Math.max(min, value));
|
|
1
|
+
export const visibleIndexes = (slides) => slides.flatMap((slide, index) => slide.hidden ? [] : [index]);
|
|
2
|
+
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
3
|
+
/** Snaps a position onto a visible slide and a real step. Empty decks stay at 0, 0. */
|
|
5
4
|
export function settle(slides, position) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
const visible = visibleIndexes(slides);
|
|
6
|
+
if (visible.length === 0) return {
|
|
7
|
+
index: 0,
|
|
8
|
+
step: 0
|
|
9
|
+
};
|
|
10
|
+
const index = visible.find((i) => i >= position.index) ?? visible[visible.length - 1];
|
|
11
|
+
return {
|
|
12
|
+
index,
|
|
13
|
+
step: clamp(position.step, 0, slides[index].steps)
|
|
14
|
+
};
|
|
16
15
|
}
|
|
16
|
+
/** The position after one forward press, or null at the end of a deck that doesn't loop. */
|
|
17
17
|
export function nextPosition(slides, from, loop = false) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
33
|
}
|
|
34
|
+
/** The position after one back press. Landing on an earlier slide shows it fully revealed. */
|
|
34
35
|
export function prevPosition(slides, from, loop = false) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
const visible = visibleIndexes(slides);
|
|
37
|
+
if (visible.length === 0) return null;
|
|
38
|
+
if (from.step > 0) return {
|
|
39
|
+
index: from.index,
|
|
40
|
+
step: from.step - 1
|
|
41
|
+
};
|
|
42
|
+
const before = visible.filter((i) => i < from.index);
|
|
43
|
+
const index = before.length ? before[before.length - 1] : loop ? visible[visible.length - 1] : undefined;
|
|
44
|
+
return index === undefined ? null : {
|
|
45
|
+
index,
|
|
46
|
+
step: slides[index].steps
|
|
47
|
+
};
|
|
47
48
|
}
|
|
49
|
+
/** Where slide `index` sits among the visible ones, 1 based, for "3 of 12". */
|
|
48
50
|
export function ordinalOf(slides, index) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
const visible = visibleIndexes(slides);
|
|
52
|
+
return {
|
|
53
|
+
n: Math.max(0, visible.indexOf(index)) + 1,
|
|
54
|
+
of: visible.length
|
|
55
|
+
};
|
|
54
56
|
}
|
|
57
|
+
/** How far through the deck a position is, 0 to 1. A slide's fragments split its own share. */
|
|
55
58
|
export function progressOf(slides, position) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
const visible = visibleIndexes(slides);
|
|
60
|
+
if (visible.length === 0) return 0;
|
|
61
|
+
const at = Math.max(0, visible.indexOf(position.index));
|
|
62
|
+
const steps = slides[position.index]?.steps ?? 0;
|
|
63
|
+
const share = steps > 0 ? (position.step + 1) / (steps + 1) : 1;
|
|
64
|
+
return (at + share) / visible.length;
|
|
62
65
|
}
|
|
66
|
+
/** Reads `?s=` as a zero based index. Anything that isn't a whole number in range is null. */
|
|
63
67
|
export function parseSlideParam(raw, total) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
if (!raw || !/^\d+$/.test(raw)) return null;
|
|
69
|
+
const index = Number(raw) - 1;
|
|
70
|
+
return index >= 0 && index < total ? index : null;
|
|
67
71
|
}
|
|
68
72
|
const KEYS = {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
73
|
+
ArrowRight: "next",
|
|
74
|
+
PageDown: "next",
|
|
75
|
+
ArrowLeft: "prev",
|
|
76
|
+
PageUp: "prev",
|
|
77
|
+
ArrowUp: "up",
|
|
78
|
+
ArrowDown: "down",
|
|
79
|
+
Home: "first",
|
|
80
|
+
End: "last",
|
|
81
|
+
Enter: "select",
|
|
82
|
+
Escape: "close",
|
|
83
|
+
o: "overview",
|
|
84
|
+
O: "overview",
|
|
85
|
+
f: "fullscreen",
|
|
86
|
+
F: "fullscreen",
|
|
87
|
+
p: "presenter",
|
|
88
|
+
P: "presenter"
|
|
85
89
|
};
|
|
90
|
+
/** Maps a key to what the deck does with it. Space moves forward, Shift+Space back. */
|
|
86
91
|
export function keyAction(key, shift = false) {
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
if (key === " ") return shift ? "prev" : "next";
|
|
93
|
+
return KEYS[key] ?? null;
|
|
89
94
|
}
|
package/dist/slides/types.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a status registry from a map, keeping its keys as a union so lookups stay typed:
|
|
3
|
+
* `defineStatuses({ draft: { label: "Draft", tone: "neutral" } })`.
|
|
4
|
+
*/
|
|
1
5
|
export function defineStatuses(map) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
const lookup = map;
|
|
7
|
+
const find = (id) => lookup[id];
|
|
8
|
+
return {
|
|
9
|
+
map,
|
|
10
|
+
ids: Object.keys(map),
|
|
11
|
+
has: (id) => find(id) !== undefined,
|
|
12
|
+
get: find,
|
|
13
|
+
label: (id) => find(id)?.label ?? id,
|
|
14
|
+
tone: (id) => find(id)?.tone ?? "neutral",
|
|
15
|
+
icon: (id) => find(id)?.icon,
|
|
16
|
+
variant: (id) => find(id)?.variant ?? "open",
|
|
17
|
+
progress: (id) => find(id)?.progress,
|
|
18
|
+
color: (id) => find(id)?.color
|
|
19
|
+
};
|
|
16
20
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/test-setup.js
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
|
+
// WHY a setup file and not a beforeAll: layerchart and svelte/motion call
|
|
2
|
+
// matchMedia while their module evaluates, which happens on import, before any hook runs. jsdom ships none of these, and bits-ui and embla measure with them.
|
|
1
3
|
class ObserverStub {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
observe() {}
|
|
5
|
+
unobserve() {}
|
|
6
|
+
disconnect() {}
|
|
7
|
+
takeRecords() {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
8
10
|
}
|
|
9
11
|
globalThis.ResizeObserver ??= ObserverStub;
|
|
10
12
|
globalThis.IntersectionObserver ??= ObserverStub;
|
|
11
|
-
globalThis.matchMedia ??= (query)=>({
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
globalThis.matchMedia ??= ((query) => ({
|
|
14
|
+
matches: false,
|
|
15
|
+
media: query,
|
|
16
|
+
onchange: null,
|
|
17
|
+
addEventListener() {},
|
|
18
|
+
removeEventListener() {},
|
|
19
|
+
addListener() {},
|
|
20
|
+
removeListener() {},
|
|
21
|
+
dispatchEvent: () => false
|
|
22
|
+
}));
|
|
23
|
+
// jsdom lays out nothing, so an SVG path has no length to give. The success
|
|
24
|
+
// check reads one to set its dash offset.
|
|
21
25
|
if (globalThis.SVGElement && !("getTotalLength" in globalThis.SVGElement.prototype)) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
Object.defineProperty(globalThis.SVGElement.prototype, "getTotalLength", {
|
|
27
|
+
value: () => 100,
|
|
28
|
+
configurable: true
|
|
29
|
+
});
|
|
26
30
|
}
|
package/dist/thread/logic.js
CHANGED
|
@@ -1,94 +1,90 @@
|
|
|
1
1
|
import { DEFAULT_THREAD_LABELS } from "./types.js";
|
|
2
|
+
/** A timestamp as a number, a malformed one last. */
|
|
2
3
|
function at(iso) {
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
const ms = Date.parse(iso);
|
|
5
|
+
return Number.isNaN(ms) ? Number.POSITIVE_INFINITY : ms;
|
|
5
6
|
}
|
|
6
7
|
function time(comment) {
|
|
7
|
-
|
|
8
|
+
return at(comment.createdAt);
|
|
8
9
|
}
|
|
10
|
+
/** Oldest first, a malformed timestamp last, ties in the order they came. */
|
|
9
11
|
function byTime(comments) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
return comments.map((comment, index) => ({
|
|
13
|
+
comment,
|
|
14
|
+
index
|
|
15
|
+
})).toSorted((a, b) => time(a.comment) - time(b.comment) || a.index - b.index).map((row) => row.comment);
|
|
14
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Roots in time order with their replies: a reply to a reply joins the root, an orphan becomes a
|
|
19
|
+
* root, and a parent loop can't hang the walk.
|
|
20
|
+
*/
|
|
15
21
|
export function buildThread(comments) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
}));
|
|
22
|
+
const byId = new Map(comments.map((comment) => [comment.id, comment]));
|
|
23
|
+
function rootOf(comment) {
|
|
24
|
+
const seen = new Set([comment.id]);
|
|
25
|
+
let current = comment;
|
|
26
|
+
for (;;) {
|
|
27
|
+
const parent = current.parentId ? byId.get(current.parentId) : undefined;
|
|
28
|
+
if (!parent) return current;
|
|
29
|
+
if (seen.has(parent.id)) return comment;
|
|
30
|
+
seen.add(parent.id);
|
|
31
|
+
current = parent;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const replies = new Map();
|
|
35
|
+
const roots = [];
|
|
36
|
+
for (const comment of comments) {
|
|
37
|
+
const root = rootOf(comment);
|
|
38
|
+
if (root.id === comment.id) roots.push(comment);
|
|
39
|
+
else replies.set(root.id, [...replies.get(root.id) ?? [], comment]);
|
|
40
|
+
}
|
|
41
|
+
return byTime(roots).map((comment) => ({
|
|
42
|
+
comment,
|
|
43
|
+
replies: byTime(replies.get(comment.id) ?? [])
|
|
44
|
+
}));
|
|
47
45
|
}
|
|
46
|
+
/** How many conversations are resolved. */
|
|
48
47
|
export function resolvedCount(nodes) {
|
|
49
|
-
|
|
48
|
+
return nodes.filter((node) => node.comment.resolved).length;
|
|
50
49
|
}
|
|
51
50
|
export function resolveThreadLabels(overrides) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
return {
|
|
52
|
+
...DEFAULT_THREAD_LABELS,
|
|
53
|
+
...overrides
|
|
54
|
+
};
|
|
56
55
|
}
|
|
56
|
+
/** Fills `{count}` in a label, so a French host writes its own sentence. */
|
|
57
57
|
export function fillCount(label, count) {
|
|
58
|
-
|
|
58
|
+
return label.replaceAll("{count}", String(count));
|
|
59
59
|
}
|
|
60
|
+
/** Conversations and events in time order, each run of events between two conversations as one item. */
|
|
60
61
|
export function interleave(nodes, events) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
row.event
|
|
90
|
-
]
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
return items;
|
|
62
|
+
const timed = [...nodes.map((node, index) => ({
|
|
63
|
+
at: at(node.comment.createdAt),
|
|
64
|
+
index,
|
|
65
|
+
node
|
|
66
|
+
})), ...events.map((event, index) => ({
|
|
67
|
+
at: at(event.at),
|
|
68
|
+
index: nodes.length + index,
|
|
69
|
+
event
|
|
70
|
+
}))].toSorted((a, b) => a.at - b.at || a.index - b.index);
|
|
71
|
+
const items = [];
|
|
72
|
+
for (const row of timed) {
|
|
73
|
+
if ("node" in row) {
|
|
74
|
+
items.push({
|
|
75
|
+
type: "node",
|
|
76
|
+
key: row.node.comment.id,
|
|
77
|
+
node: row.node
|
|
78
|
+
});
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const last = items.at(-1);
|
|
82
|
+
if (last?.type === "events") last.events.push(row.event);
|
|
83
|
+
else items.push({
|
|
84
|
+
type: "events",
|
|
85
|
+
key: row.event.id,
|
|
86
|
+
events: [row.event]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return items;
|
|
94
90
|
}
|
package/dist/thread/types.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
export const DEFAULT_THREAD_LABELS = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
23
|
};
|