stimeo-ui 0.7.0 → 0.9.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 (77) hide show
  1. package/CHANGELOG.md +151 -0
  2. package/dist/controllers/auto_submit_controller.d.ts +14 -3
  3. package/dist/controllers/auto_submit_controller.js +94 -16
  4. package/dist/controllers/auto_submit_controller.js.map +1 -1
  5. package/dist/controllers/bulk_select_controller.d.ts +62 -15
  6. package/dist/controllers/bulk_select_controller.js +139 -28
  7. package/dist/controllers/bulk_select_controller.js.map +1 -1
  8. package/dist/controllers/carousel_controller.d.ts +81 -47
  9. package/dist/controllers/carousel_controller.js +451 -100
  10. package/dist/controllers/carousel_controller.js.map +1 -1
  11. package/dist/controllers/clipboard_controller.d.ts +48 -15
  12. package/dist/controllers/clipboard_controller.js +102 -20
  13. package/dist/controllers/clipboard_controller.js.map +1 -1
  14. package/dist/controllers/color_picker_controller.d.ts +37 -6
  15. package/dist/controllers/color_picker_controller.js +180 -43
  16. package/dist/controllers/color_picker_controller.js.map +1 -1
  17. package/dist/controllers/currency_input_controller.d.ts +39 -5
  18. package/dist/controllers/currency_input_controller.js +305 -74
  19. package/dist/controllers/currency_input_controller.js.map +1 -1
  20. package/dist/controllers/data_grid_controller.d.ts +25 -9
  21. package/dist/controllers/data_grid_controller.js +150 -24
  22. package/dist/controllers/data_grid_controller.js.map +1 -1
  23. package/dist/controllers/direct_upload_controller.d.ts +3 -1
  24. package/dist/controllers/direct_upload_controller.js +12 -2
  25. package/dist/controllers/direct_upload_controller.js.map +1 -1
  26. package/dist/controllers/editable_controller.d.ts +34 -9
  27. package/dist/controllers/editable_controller.js +83 -30
  28. package/dist/controllers/editable_controller.js.map +1 -1
  29. package/dist/controllers/file_dropzone_controller.d.ts +123 -29
  30. package/dist/controllers/file_dropzone_controller.js +386 -63
  31. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  32. package/dist/controllers/filter_controller.d.ts +15 -3
  33. package/dist/controllers/filter_controller.js +32 -1
  34. package/dist/controllers/filter_controller.js.map +1 -1
  35. package/dist/controllers/flash_controller.d.ts +3 -1
  36. package/dist/controllers/flash_controller.js +3 -1
  37. package/dist/controllers/flash_controller.js.map +1 -1
  38. package/dist/controllers/frame_loading_controller.d.ts +4 -2
  39. package/dist/controllers/frame_loading_controller.js +2 -1
  40. package/dist/controllers/frame_loading_controller.js.map +1 -1
  41. package/dist/controllers/input_mask_controller.d.ts +42 -16
  42. package/dist/controllers/input_mask_controller.js +251 -76
  43. package/dist/controllers/input_mask_controller.js.map +1 -1
  44. package/dist/controllers/masonry_controller.d.ts +34 -5
  45. package/dist/controllers/masonry_controller.js +129 -17
  46. package/dist/controllers/masonry_controller.js.map +1 -1
  47. package/dist/controllers/nested_form_controller.d.ts +51 -14
  48. package/dist/controllers/nested_form_controller.js +450 -42
  49. package/dist/controllers/nested_form_controller.js.map +1 -1
  50. package/dist/controllers/otp_controller.d.ts +64 -25
  51. package/dist/controllers/otp_controller.js +485 -114
  52. package/dist/controllers/otp_controller.js.map +1 -1
  53. package/dist/controllers/reset_before_cache_controller.d.ts +25 -2
  54. package/dist/controllers/reset_before_cache_controller.js +51 -5
  55. package/dist/controllers/reset_before_cache_controller.js.map +1 -1
  56. package/dist/controllers/resizable_controller.d.ts +23 -7
  57. package/dist/controllers/resizable_controller.js +128 -55
  58. package/dist/controllers/resizable_controller.js.map +1 -1
  59. package/dist/controllers/spinner_controller.d.ts +3 -2
  60. package/dist/controllers/spinner_controller.js +7 -5
  61. package/dist/controllers/spinner_controller.js.map +1 -1
  62. package/dist/controllers/submit_once_controller.d.ts +4 -1
  63. package/dist/controllers/submit_once_controller.js +3 -1
  64. package/dist/controllers/submit_once_controller.js.map +1 -1
  65. package/dist/controllers/textarea_autosize_controller.d.ts +30 -10
  66. package/dist/controllers/textarea_autosize_controller.js +131 -3
  67. package/dist/controllers/textarea_autosize_controller.js.map +1 -1
  68. package/dist/index.js +2764 -923
  69. package/dist/index.js.map +1 -1
  70. package/dist/inspector/cli.d.ts +8 -1
  71. package/dist/inspector/cli.js +5 -1
  72. package/dist/inspector/cli.js.map +1 -1
  73. package/dist/inspector/cli_bin.js +5 -1
  74. package/dist/inspector/cli_bin.js.map +1 -1
  75. package/dist/inspector/examples.json +24 -24
  76. package/dist/inspector/manifest.json +193 -30
  77. package/package.json +2 -2
@@ -5,7 +5,8 @@ import { Controller } from '@hotwired/stimulus';
5
5
  *
6
6
  * Markup contract (identifier: `stimeo--file-dropzone`):
7
7
  * <div data-controller="stimeo--file-dropzone"
8
- * data-stimeo--file-dropzone-max-size-value="5242880">
8
+ * data-stimeo--file-dropzone-max-size-value="5242880"
9
+ * data-stimeo--file-dropzone-announce-added-text-value="{name} added; {total} selected">
9
10
  * <div data-stimeo--file-dropzone-target="zone"
10
11
  * data-action="dragover->stimeo--file-dropzone#onDragOver
11
12
  * dragleave->stimeo--file-dropzone#onDragLeave
@@ -17,9 +18,14 @@ import { Controller } from '@hotwired/stimulus';
17
18
  * data-action="change->stimeo--file-dropzone#onChange" />
18
19
  * </div>
19
20
  * <ul data-stimeo--file-dropzone-target="list" aria-label="Selected files"></ul>
20
- * <span role="status" aria-live="polite" class="visually-hidden"
21
- * data-stimeo--file-dropzone-target="status"></span>
22
- * <template data-stimeo--file-dropzone-target="itemTemplate">…</template>
21
+ * <template data-stimeo--file-dropzone-target="itemTemplate">
22
+ * <li data-stimeo--file-dropzone-target="item">
23
+ * <img data-stimeo--file-dropzone-target="thumb" alt="" hidden />
24
+ * <span data-stimeo--file-dropzone-target="name"></span>
25
+ * <button type="button" aria-label="Remove {name}"
26
+ * data-stimeo--file-dropzone-target="remove">×</button>
27
+ * </li>
28
+ * </template>
23
29
  * </div>
24
30
  *
25
31
  * There is no single APG pattern; the native `<input type="file">` stays the
@@ -29,19 +35,50 @@ import { Controller } from '@hotwired/stimulus';
29
35
  *
30
36
  * Behavior provided:
31
37
  * - Click / keyboard via the `trigger` opens the native file dialog; drag-and-drop
32
- * over the `zone` adds files (with a `data-dragover` flag and a spoken hint).
33
- * - Each file is validated against `accept`, `maxSize`, and the file count
34
- * (`maxFiles`, or 1 when the input is not `multiple`); rejects fire
35
- * `stimeo--file-dropzone:reject` and set `data-…-invalid`.
36
- * - Accepted files render from `itemTemplate` with a `Remove {name}` button and an
37
- * image thumbnail (`objectURL`); every change dispatches
38
- * `stimeo--file-dropzone:change` with the current `File[]`.
38
+ * over the `zone` adds files. The zone carries `data-dragover` for as long as the
39
+ * pointer is anywhere inside it, descendants included — a `dragleave` whose
40
+ * `relatedTarget` is still in the zone is the pointer crossing an inner element,
41
+ * not leaving.
42
+ * - Each file is validated in order against `accept`, `maxSize`, duplication, and
43
+ * the file count (`maxFiles`, or 1 when the input is not `multiple`). The reason
44
+ * is therefore the most specific one: a file the zone would refuse whatever the
45
+ * count says reports its own defect rather than `count`. Rejects fire
46
+ * `stimeo--file-dropzone:reject` and set `data-…-invalid`, which the next batch
47
+ * clears.
48
+ * - Two files count as the same when name, size, and last-modified time all match;
49
+ * `allowDuplicates` turns the check off.
50
+ * - Accepted files render from `itemTemplate`; the template's own remove-button
51
+ * `aria-label` is kept and its `{name}` expanded, so the accessible name stays in
52
+ * the consumer's language. A template missing a part renders nothing, changes no
53
+ * state, and reports itself once per connection.
54
+ * - The accepted set is mirrored onto the native input, so a plain form submit
55
+ * carries the dropped files with no JavaScript from the consumer. Where
56
+ * `DataTransfer` cannot be constructed the previews and events still work and the
57
+ * input keeps whatever the native dialog last put there.
39
58
  * - Removing a file revokes its `objectURL` and moves focus to the next (else
40
- * previous) remove button, falling back to the trigger; `disconnect()` revokes
41
- * every outstanding `objectURL`. Replacing the `list` target rebinds delegated
42
- * removal and moves the client-only previews into the replacement.
43
- * `reject` dispatches `{ file: File, reason: "type" | "size" | "count" }`.
44
- * `change` dispatches `{ files: File[] }`.
59
+ * previous) remove button, falling back to the trigger.
60
+ * - Additions, rejections, removals, and the drag affordance are handed to the
61
+ * page's shared `stimeo--announcer` as one polite message each, worded by the
62
+ * consumer (`{name}` is the file this message is about, `{count}` how many files
63
+ * it covers, `{total}` how many are selected afterwards). Empty templates stay
64
+ * silent, keeping announcements opt-in and i18n-neutral. One batch produces at
65
+ * most one message per outcome, so dropping twenty files never reads twenty lines.
66
+ * - A drop into a disabled field is refused: with the input `disabled` or inside a
67
+ * disabled `fieldset` the zone never becomes a drop target, matching what the
68
+ * native click and keyboard paths already do.
69
+ * - Replacing the `list` target rebinds delegated removal and moves the
70
+ * client-only previews into the replacement; a morph that empties the list in
71
+ * place moves them back on the next interaction.
72
+ * `reject` dispatches `{ file: File, reason: "type" | "size" | "duplicate" | "count" }`.
73
+ * `change` and `reconcile` dispatch `{ files: File[] }`.
74
+ *
75
+ * @remarks
76
+ * Previews are client-only state that no restored snapshot can revive — the `File`
77
+ * objects and their `blob:` URLs die with the page. Just before Turbo caches the
78
+ * page the generated items are removed, every `objectURL` revoked, and both state
79
+ * attributes withdrawn, so a restored snapshot starts pristine instead of showing
80
+ * rows that cannot be removed and do not count towards `maxFiles`. A `disconnect()`
81
+ * that turns out to be an in-page move keeps the selection intact.
45
82
  */
46
83
  declare class FileDropzoneController extends Controller<HTMLElement> {
47
84
  #private;
@@ -55,45 +92,102 @@ declare class FileDropzoneController extends Controller<HTMLElement> {
55
92
  type: NumberConstructor;
56
93
  default: number;
57
94
  };
58
- dragLabel: {
95
+ allowDuplicates: {
96
+ type: BooleanConstructor;
97
+ default: boolean;
98
+ };
99
+ announceDragText: {
100
+ type: StringConstructor;
101
+ default: string;
102
+ };
103
+ announceAddedText: {
104
+ type: StringConstructor;
105
+ default: string;
106
+ };
107
+ announceRemovedText: {
108
+ type: StringConstructor;
109
+ default: string;
110
+ };
111
+ announceRejectedTypeText: {
112
+ type: StringConstructor;
113
+ default: string;
114
+ };
115
+ announceRejectedSizeText: {
116
+ type: StringConstructor;
117
+ default: string;
118
+ };
119
+ announceRejectedDuplicateText: {
120
+ type: StringConstructor;
121
+ default: string;
122
+ };
123
+ announceRejectedCountText: {
59
124
  type: StringConstructor;
60
125
  default: string;
61
126
  };
62
127
  };
63
128
  static actions: readonly ["onChange", "onDragLeave", "onDragOver", "onDrop", "openDialog"];
64
- static events: readonly ["change", "reject"];
129
+ static events: readonly ["change", "reject", "reconcile"];
65
130
  readonly inputTarget: HTMLInputElement;
66
131
  readonly listTarget: HTMLElement;
67
132
  readonly listTargets: HTMLElement[];
68
133
  readonly triggerTarget: HTMLElement;
69
134
  readonly itemTemplateTarget: HTMLTemplateElement;
70
- readonly statusTarget: HTMLElement;
135
+ readonly hasInputTarget: boolean;
71
136
  readonly hasListTarget: boolean;
72
137
  readonly hasTriggerTarget: boolean;
73
138
  readonly hasItemTemplateTarget: boolean;
74
- readonly hasStatusTarget: boolean;
75
139
  readonly hasZoneTarget: boolean;
76
140
  readonly zoneTarget: HTMLElement;
77
141
  maxSizeValue: number;
78
142
  maxFilesValue: number;
79
- dragLabelValue: string;
80
- /** Wires file removal as a delegated listener on the list container. */
143
+ allowDuplicatesValue: boolean;
144
+ announceDragTextValue: string;
145
+ announceAddedTextValue: string;
146
+ announceRemovedTextValue: string;
147
+ announceRejectedTypeTextValue: string;
148
+ announceRejectedSizeTextValue: string;
149
+ announceRejectedDuplicateTextValue: string;
150
+ announceRejectedCountTextValue: string;
151
+ /** Subscribes to the Turbo cache rewind and re-arms the template diagnostic. */
81
152
  connect(): void;
82
- /** Revokes any outstanding preview URLs so none leaks across navigations. */
153
+ /**
154
+ * Releases the delegated listeners. The selection itself survives an in-page
155
+ * move and is released only once the gate proves a real detach — revoking a
156
+ * preview URL on a move would leave a live item pointing at a dead `blob:`.
157
+ */
83
158
  disconnect(): void;
84
- /** Rebinds removal and restores client-only previews when Turbo replaces the list target. */
159
+ /**
160
+ * Binds removal and restores client-only previews for every list this controller
161
+ * renders into — the one present at connect and any Turbo puts in its place.
162
+ * This is the only place the listener is attached, so the pair with
163
+ * {@link listTargetDisconnected} keeps it from outliving the element it is on.
164
+ */
85
165
  listTargetConnected(list: HTMLElement): void;
86
166
  /** Releases only the list target that actually disconnected. */
87
167
  listTargetDisconnected(list: HTMLElement): void;
88
168
  /** Opens the native file dialog. Bound via `data-action` (trigger click). */
89
169
  openDialog(): void;
90
- /** Adds the files chosen through the native dialog. */
170
+ /**
171
+ * Adds the files chosen through the native dialog. The input holds only what
172
+ * the dialog just returned, so the accepted set is written back over it once
173
+ * the batch is validated.
174
+ */
91
175
  onChange(): void;
92
- /** Marks the zone as a drop target and announces the affordance in words. */
176
+ /**
177
+ * Marks the zone as a drop target and announces the affordance once per drag.
178
+ * Bound via `data-action` (dragover). Leaving the default alone is what refuses
179
+ * the drop, so a disabled field and a drag an inner dropzone already claimed
180
+ * both fall through untouched.
181
+ */
93
182
  onDragOver(event: DragEvent): void;
94
- /** Clears the drag-over flag when the pointer leaves the zone. */
95
- onDragLeave(): void;
96
- /** Accepts dropped files, clearing the drag-over state. */
183
+ /**
184
+ * Clears the drag-over flag when the pointer leaves the zone. Bound via
185
+ * `data-action` (dragleave). `dragleave` bubbles from every descendant the
186
+ * pointer crosses, so the flag only drops when the element being entered is
187
+ * outside the zone (or there is none, the pointer having left the window).
188
+ */
189
+ onDragLeave(event: DragEvent): void;
190
+ /** Accepts dropped files, clearing the drag-over state. Bound via `data-action` (drop). */
97
191
  onDrop(event: DragEvent): void;
98
192
  }
99
193