@remit/ui 0.0.28 → 0.0.29

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/ui",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src"
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
+ import { FolderInput } from "lucide-react";
2
3
  import { SelectionTopBar } from "./selection-top-bar.js";
3
4
 
4
5
  const meta: Meta<typeof SelectionTopBar> = {
@@ -22,6 +23,18 @@ export default meta;
22
23
 
23
24
  type Story = StoryObj<typeof SelectionTopBar>;
24
25
 
26
+ /** Stand-in for the caller's move-to-folder trigger, which owns its own
27
+ * folder-picker data. The bar only reserves the slot. */
28
+ const MoveSlot = () => (
29
+ <button
30
+ type="button"
31
+ aria-label="Move selected messages"
32
+ className="inline-flex size-11 shrink-0 items-center justify-center rounded text-fg-muted hover:bg-surface-raised"
33
+ >
34
+ <FolderInput className="size-4" />
35
+ </button>
36
+ );
37
+
25
38
  export const One: Story = { args: { count: 1 } };
26
39
 
27
40
  export const Many: Story = { args: { count: 3 } };
@@ -75,7 +88,7 @@ export const AllSelected: Story = {
75
88
  /**
76
89
  * The search has more matches than are loaded: an escalation notice offers a
77
90
  * real button (not prose) naming the scope. Tapping it is what flips the
78
- * selection's identity from an id set to the search query (`useEscalatedDelete`
91
+ * selection's identity from an id set to the search query (`useEscalatedActions`
79
92
  * in web-client). No count in the label yet — the real client's own read path
80
93
  * (`ThreadOperations.searchThreads`) only counts within a capped recency
81
94
  * window short of paging the whole result set, and paging it just to seed a
@@ -107,11 +120,19 @@ export const EscalationAvailable: Story = {
107
120
  * Selection has been escalated to the search query: the count names the
108
121
  * query's total, not a materialized id count, and the notice offers a way
109
122
  * back to the bounded selection.
123
+ *
124
+ * Every verb the bar carries stays available here (#114). An escalated
125
+ * selection is a predicate rather than an id list, so the web-client runs
126
+ * move and mark-read by paging that predicate the same way delete does —
127
+ * from the bar's side nothing changes, which is the point: an escalated
128
+ * selection that could only be deleted forced anyone wanting to file those
129
+ * messages back to the loaded page.
110
130
  */
111
131
  export const Escalated: Story = {
112
132
  args: {
113
133
  count: 3412,
114
134
  statusLabel: 'All 3,412 matching "npm" selected',
135
+ moveSlot: <MoveSlot />,
115
136
  notice: {
116
137
  tone: "info",
117
138
  text: "",
@@ -199,3 +220,44 @@ export const PartialFailure: Story = {
199
220
  export const ZeroSelected: Story = {
200
221
  args: { count: 0 },
201
222
  };
223
+
224
+ /**
225
+ * A move over an escalated selection: same chunked run as a delete, worded for
226
+ * the action that is running and toned as ordinary progress rather than
227
+ * destructive. Mark-read and the move slot are hidden while it runs — nothing
228
+ * here can act mid-run.
229
+ */
230
+ export const MovingWithProgress: Story = {
231
+ args: {
232
+ count: 3412,
233
+ statusLabel: "Moving 1,200 of 3,412…",
234
+ isBusy: true,
235
+ progress: { value: 1200, max: 3412, tone: "info" },
236
+ },
237
+ };
238
+
239
+ /** Mark-read over the same escalated selection. */
240
+ export const MarkingReadWithProgress: Story = {
241
+ args: {
242
+ count: 3412,
243
+ statusLabel: "Marking 1,200 of 3,412 as read…",
244
+ isBusy: true,
245
+ progress: { value: 1200, max: 3412, tone: "info" },
246
+ },
247
+ };
248
+
249
+ /**
250
+ * Partial failure of a move rather than a delete: the notice names the action
251
+ * that ran, and Retry resends that same action against what is still selected.
252
+ */
253
+ export const PartialFailureMove: Story = {
254
+ args: {
255
+ count: 340,
256
+ moveSlot: <MoveSlot />,
257
+ notice: {
258
+ tone: "danger",
259
+ text: "3,072 moved. 340 couldn't be moved.",
260
+ action: { label: "Retry 340", onClick: () => undefined },
261
+ },
262
+ },
263
+ };