@heyramzi/ui 2.22.0 → 2.23.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 (48) hide show
  1. package/dist/canvas/editor/rebase.js +26 -2
  2. package/dist/editor/safe-url.js +26 -0
  3. package/dist/editor/serializer.js +10 -4
  4. package/dist/editor/slash-query.js +10 -0
  5. package/dist/triage/index.js +4 -0
  6. package/dist/triage/types.js +12 -0
  7. package/package.json +7 -1
  8. package/scripts/sync-shadcn.mjs +4 -6
  9. package/src/animations/modal.css +4 -1
  10. package/src/canvas/editor/rebase.test.ts +37 -0
  11. package/src/canvas/editor/rebase.ts +33 -1
  12. package/src/canvas/ui/canvas-grid.svelte +72 -12
  13. package/src/canvas/ui/canvas-ui.css +32 -1
  14. package/src/charts/area-chart.svelte +2 -2
  15. package/src/charts/bar-chart.svelte +2 -2
  16. package/src/charts/chart-tokens.css +19 -0
  17. package/src/charts/dashboard/stat-tile.svelte +1 -1
  18. package/src/charts/donut-chart.svelte +1 -1
  19. package/src/charts/gauge-chart.svelte +1 -1
  20. package/src/charts/line-chart.svelte +2 -2
  21. package/src/charts/number-chart.svelte +1 -1
  22. package/src/charts/ring-chart.svelte +2 -2
  23. package/src/charts/sparkline.svelte +1 -1
  24. package/src/charts/stat-card.svelte +1 -1
  25. package/src/charts/time-series-chart.svelte +1 -1
  26. package/src/editor/editor.svelte +7 -5
  27. package/src/editor/safe-url.ts +32 -0
  28. package/src/editor/serializer.test.ts +58 -0
  29. package/src/editor/serializer.ts +9 -6
  30. package/src/editor/slash-query.test.ts +19 -0
  31. package/src/editor/slash-query.ts +11 -0
  32. package/src/modules.test.ts +13 -1
  33. package/src/shadcn/alert-dialog/alert-dialog-overlay.svelte +1 -1
  34. package/src/shadcn/button/button.svelte +1 -1
  35. package/src/shadcn/button/button.test.ts +2 -2
  36. package/src/shadcn/command/command-dialog.svelte +5 -10
  37. package/src/shadcn/dialog/dialog-overlay.svelte +1 -1
  38. package/src/shadcn/input/input.svelte +2 -2
  39. package/src/shadcn/sheet/sheet-overlay.svelte +1 -1
  40. package/src/tokens/craft.css +30 -0
  41. package/src/triage/README.md +28 -0
  42. package/src/triage/index.ts +10 -0
  43. package/src/triage/triage-plan.svelte +132 -0
  44. package/src/triage/triage-queue.svelte +48 -0
  45. package/src/triage/triage-task.svelte +95 -0
  46. package/src/triage/types.ts +35 -0
  47. package/src/work/kanban-column.svelte +5 -3
  48. package/src/work/time/time-chip.svelte +1 -3
@@ -0,0 +1,95 @@
1
+ <script lang="ts">
2
+ import { Button } from "../shadcn/button/index.js";
3
+ import StatusBadge from "../status/status-badge.svelte";
4
+ import { cn } from "../lib/utils.js";
5
+ import {
6
+ DEFAULT_TRIAGE_TASK_LABELS,
7
+ type TriageOutcome,
8
+ type TriageTaskLabels,
9
+ type TriageTaskLink,
10
+ } from "./types.js";
11
+
12
+ interface Props {
13
+ sender: string;
14
+ subject: string;
15
+ /** What happened to the email. */
16
+ outcome: TriageOutcome;
17
+ /** The task it became. */
18
+ task?: TriageTaskLink | null;
19
+ /** When it settled, as text the host already formatted. */
20
+ when: string;
21
+ whenAt?: string | null;
22
+ /** Why it failed. */
23
+ detail?: string | null;
24
+ error?: string | null;
25
+ labels?: Partial<TriageTaskLabels>;
26
+ /** Takes the change back. The button shows only when this is passed. */
27
+ onUndo?: () => void | Promise<void>;
28
+ class?: string;
29
+ }
30
+
31
+ let {
32
+ sender,
33
+ subject,
34
+ outcome,
35
+ task,
36
+ when,
37
+ whenAt,
38
+ detail,
39
+ error,
40
+ labels,
41
+ onUndo,
42
+ class: className,
43
+ }: Props = $props();
44
+
45
+ let words = $derived({ ...DEFAULT_TRIAGE_TASK_LABELS, ...labels });
46
+ let busy = $state(false);
47
+
48
+ async function undo() {
49
+ busy = true;
50
+ try {
51
+ await onUndo?.();
52
+ } finally {
53
+ busy = false;
54
+ }
55
+ }
56
+ </script>
57
+
58
+ <li
59
+ class={cn(
60
+ "flex flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between",
61
+ className,
62
+ )}
63
+ >
64
+ <div class="min-w-0 space-y-1">
65
+ <p class="text-foreground text-sm font-medium [overflow-wrap:anywhere]">
66
+ {sender}: {subject}
67
+ </p>
68
+ <div class="flex flex-wrap items-center gap-x-3 gap-y-1">
69
+ <StatusBadge tone={outcome.tone} capitalize={false}>{outcome.label}</StatusBadge>
70
+ {#if task}
71
+ <a
72
+ href={task.url}
73
+ target="_blank"
74
+ rel="noreferrer"
75
+ class="text-primary min-w-0 text-xs [overflow-wrap:anywhere] hover:underline"
76
+ >
77
+ {task.name ?? words.openTask}
78
+ </a>
79
+ {/if}
80
+ <time class="text-muted-foreground text-xs" datetime={whenAt ?? undefined}>{when}</time>
81
+ </div>
82
+ {#if detail}
83
+ <p class="text-muted-foreground text-xs [overflow-wrap:anywhere]">{detail}</p>
84
+ {/if}
85
+ {#if error}
86
+ <p class="text-destructive text-xs [overflow-wrap:anywhere]" role="alert">{error}</p>
87
+ {/if}
88
+ </div>
89
+
90
+ {#if onUndo}
91
+ <Button variant="outline" class="shrink-0" disabled={busy} onclick={undo}>
92
+ {words.undo}
93
+ </Button>
94
+ {/if}
95
+ </li>
@@ -0,0 +1,35 @@
1
+ import type { Tone } from "../lib/tone.js";
2
+
3
+ /** The words a plan card shows. Pass a partial to translate or reword. */
4
+ export type TriagePlanLabels = {
5
+ approve: string;
6
+ pick: string;
7
+ dismiss: string;
8
+ /** The label over the field where the person types the task to use instead. */
9
+ taskLabel: string;
10
+ useTask: string;
11
+ cancel: string;
12
+ };
13
+
14
+ export const DEFAULT_TRIAGE_PLAN_LABELS: TriagePlanLabels = {
15
+ approve: "Approve",
16
+ pick: "Pick another task",
17
+ dismiss: "Dismiss",
18
+ taskLabel: "Task",
19
+ useTask: "Use this task",
20
+ cancel: "Cancel",
21
+ };
22
+
23
+ /** The words a task row shows. */
24
+ export type TriageTaskLabels = { undo: string; openTask: string };
25
+
26
+ export const DEFAULT_TRIAGE_TASK_LABELS: TriageTaskLabels = {
27
+ undo: "Undo",
28
+ openTask: "Open task",
29
+ };
30
+
31
+ /** What happened to a settled email: the chip's words and its tone. */
32
+ export type TriageOutcome = { label: string; tone: Tone };
33
+
34
+ /** The task the email ended up as, when there is one. */
35
+ export type TriageTaskLink = { name?: string | null; url: string };
@@ -65,11 +65,13 @@
65
65
  </div>
66
66
 
67
67
  <style>
68
- /* Columns split the board's width equally, never under 280px (the board scrolls instead)
69
- nor over 420px (a 2-line card title stays near 55 characters a line). */
68
+ /* Columns split the board's width equally, never under 240px (the board scrolls instead)
69
+ nor over 420px (a 2-line card title stays near 55 characters a line). At 280px four
70
+ columns needed 1168px, so a docs page at 1440 cut the Done column off; 240px fits four
71
+ in the 1008px a 1440 page leaves, and a card's meta row still fits on one line. */
70
72
  .kanban-column {
71
73
  flex: 1 1 0;
72
- min-width: var(--kanban-column-min, 280px);
74
+ min-width: var(--kanban-column-min, 240px);
73
75
  max-width: var(--kanban-column-max, 420px);
74
76
  transition: opacity var(--duration-quick) var(--ease-smooth-out);
75
77
  }
@@ -57,9 +57,7 @@
57
57
  class={cn(
58
58
  "font-normal",
59
59
  tone === "neutral" ? "text-muted-foreground/70" : TONE_TEXT[tone],
60
- )}
61
- >
62
- / {formatMinutes(estimate)}</span
60
+ )}>{`\u2009/\u2009${formatMinutes(estimate)}`}</span
63
61
  >{/if}
64
62
  </span>
65
63
  </StatusPill>