@remit/web-client 0.0.79 → 0.0.80

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/web-client",
3
- "version": "0.0.79",
3
+ "version": "0.0.80",
4
4
  "type": "module",
5
5
  "description": "Remit web client, published as composable primitives — the app shell, auth shells, and runtime config. A distributor imports what it composes and bundles it.",
6
6
  "exports": {
@@ -0,0 +1,134 @@
1
+ import type { RemitImapLabelResponse } from "@remit/api-http-client/types.gen.ts";
2
+ import type { Meta, StoryObj } from "@storybook/react-vite";
3
+ import { LabelsList } from "./LabelsList";
4
+
5
+ const meta: Meta<typeof LabelsList> = {
6
+ title: "Flows/Settings Labels/LabelsList",
7
+ component: LabelsList,
8
+ parameters: { layout: "padded" },
9
+ decorators: [
10
+ (Story) => (
11
+ <div className="mx-auto max-w-md">
12
+ <Story />
13
+ </div>
14
+ ),
15
+ ],
16
+ args: {
17
+ onRename: () => undefined,
18
+ onRecolor: () => undefined,
19
+ onDelete: () => undefined,
20
+ },
21
+ };
22
+ export default meta;
23
+
24
+ type Story = StoryObj<typeof LabelsList>;
25
+
26
+ const makeLabel = (
27
+ overrides: Partial<RemitImapLabelResponse>,
28
+ ): RemitImapLabelResponse => ({
29
+ labelId: "lbl-1",
30
+ accountConfigId: "acc-1",
31
+ name: "Receipts",
32
+ color: "Blue",
33
+ createdAt: 0,
34
+ updatedAt: 0,
35
+ filterCount: 0,
36
+ ...overrides,
37
+ });
38
+
39
+ const fewLabels: RemitImapLabelResponse[] = [
40
+ makeLabel({
41
+ labelId: "lbl-1",
42
+ name: "Receipts",
43
+ color: "Blue",
44
+ filterCount: 0,
45
+ }),
46
+ makeLabel({
47
+ labelId: "lbl-2",
48
+ name: "Travel",
49
+ color: "Green",
50
+ filterCount: 1,
51
+ }),
52
+ makeLabel({ labelId: "lbl-3", name: "Urgent", color: "Red", filterCount: 3 }),
53
+ ];
54
+
55
+ const manyLabels: RemitImapLabelResponse[] = [
56
+ ...fewLabels,
57
+ makeLabel({
58
+ labelId: "lbl-4",
59
+ name: "Newsletters",
60
+ color: "Yellow",
61
+ filterCount: 2,
62
+ }),
63
+ makeLabel({
64
+ labelId: "lbl-5",
65
+ name: "Work",
66
+ color: "Purple",
67
+ filterCount: 0,
68
+ }),
69
+ makeLabel({
70
+ labelId: "lbl-6",
71
+ name: "Family",
72
+ color: "Teal",
73
+ filterCount: 0,
74
+ }),
75
+ makeLabel({
76
+ labelId: "lbl-7",
77
+ name: "Finance",
78
+ color: "Orange",
79
+ filterCount: 4,
80
+ }),
81
+ makeLabel({
82
+ labelId: "lbl-8",
83
+ name: "Recruiting",
84
+ color: "Gray",
85
+ filterCount: 1,
86
+ }),
87
+ makeLabel({
88
+ labelId: "lbl-9",
89
+ name: "Quarterly compliance filings that need a second look",
90
+ color: "Default",
91
+ filterCount: 1,
92
+ }),
93
+ ];
94
+
95
+ /** No labels yet — the empty-state copy points at the create form below. */
96
+ export const Empty: Story = {
97
+ args: { labels: [] },
98
+ };
99
+
100
+ /** A few labels, each showing its filter-usage line. */
101
+ export const Few: Story = {
102
+ args: { labels: fewLabels },
103
+ };
104
+
105
+ /** The same few labels, on the dark theme. */
106
+ export const FewDark: Story = {
107
+ name: "Few (dark)",
108
+ parameters: { theme: "dark" },
109
+ args: { labels: fewLabels },
110
+ };
111
+
112
+ /** Many labels, including one with a long name that truncates in its chip. */
113
+ export const Many: Story = {
114
+ args: { labels: manyLabels },
115
+ };
116
+
117
+ /**
118
+ * Renaming inline: clicking a label's chip swaps it for a focused text input.
119
+ * Driven here rather than passed as a prop — `editingId` is internal state.
120
+ */
121
+ export const Renaming: Story = {
122
+ args: { labels: fewLabels },
123
+ play: async ({ canvasElement }) => {
124
+ const renameButton = canvasElement.querySelector<HTMLButtonElement>(
125
+ 'button[aria-label="Rename label Receipts"]',
126
+ );
127
+ renameButton?.click();
128
+ },
129
+ };
130
+
131
+ /** A delete in flight — the row's delete button disables. */
132
+ export const Deleting: Story = {
133
+ args: { labels: fewLabels, deletingLabelId: "lbl-2" },
134
+ };
@@ -0,0 +1,83 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { ConfirmDialog } from "@/components/ui/ConfirmDialog";
3
+ import { deleteLabelConfirmCopy } from "@/lib/organize/label-delete-copy";
4
+
5
+ /**
6
+ * The cascade-aware label delete confirmation (issue #26, #335) — the generic
7
+ * `ConfirmDialog` driven by `deleteLabelConfirmCopy`'s computed title and
8
+ * description, exactly as `AccountLabels` in the labels settings route wires
9
+ * it. No dedicated component exists for this; reusing `ConfirmDialog` is the
10
+ * approved surface, not a placeholder for one.
11
+ */
12
+ const meta: Meta<typeof ConfirmDialog> = {
13
+ title: "Flows/Settings Labels/Delete Confirmation",
14
+ component: ConfirmDialog,
15
+ parameters: { layout: "centered" },
16
+ };
17
+ export default meta;
18
+
19
+ type Story = StoryObj<typeof ConfirmDialog>;
20
+
21
+ /** Nothing references the label — no blast-radius line under the title. */
22
+ export const Unused: Story = {
23
+ args: {
24
+ isOpen: true,
25
+ ...deleteLabelConfirmCopy("Receipts", 0),
26
+ confirmLabel: "Delete label",
27
+ destructive: true,
28
+ onConfirm: () => undefined,
29
+ onCancel: () => undefined,
30
+ },
31
+ };
32
+
33
+ /** Exactly one filter applies the label — singular wording. */
34
+ export const OneFilter: Story = {
35
+ args: {
36
+ isOpen: true,
37
+ ...deleteLabelConfirmCopy("Receipts", 1),
38
+ confirmLabel: "Delete label",
39
+ destructive: true,
40
+ onConfirm: () => undefined,
41
+ onCancel: () => undefined,
42
+ },
43
+ };
44
+
45
+ /** Several filters apply the label — the cascade warning names the count. */
46
+ export const SeveralFilters: Story = {
47
+ args: {
48
+ isOpen: true,
49
+ ...deleteLabelConfirmCopy("Receipts", 5),
50
+ confirmLabel: "Delete label",
51
+ destructive: true,
52
+ onConfirm: () => undefined,
53
+ onCancel: () => undefined,
54
+ },
55
+ };
56
+
57
+ /** Several filters, on the dark theme. */
58
+ export const SeveralFiltersDark: Story = {
59
+ name: "Several Filters (dark)",
60
+ parameters: { theme: "dark" },
61
+ args: {
62
+ isOpen: true,
63
+ ...deleteLabelConfirmCopy("Receipts", 5),
64
+ confirmLabel: "Delete label",
65
+ destructive: true,
66
+ onConfirm: () => undefined,
67
+ onCancel: () => undefined,
68
+ },
69
+ };
70
+
71
+ /** The delete is in flight — confirm disables rather than allowing a second
72
+ * concurrent delete. */
73
+ export const Busy: Story = {
74
+ args: {
75
+ isOpen: true,
76
+ ...deleteLabelConfirmCopy("Receipts", 5),
77
+ confirmLabel: "Delete label",
78
+ destructive: true,
79
+ isBusy: true,
80
+ onConfirm: () => undefined,
81
+ onCancel: () => undefined,
82
+ },
83
+ };