@alfakit/core 0.1.1 → 0.1.6

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 (78) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/components.css +347 -0
  3. package/dist/actions.d.ts +9 -0
  4. package/dist/actions.d.ts.map +1 -1
  5. package/dist/actions.js +31 -5
  6. package/dist/actions.js.map +1 -1
  7. package/dist/advanced-fields.js +2 -2
  8. package/dist/advanced-fields.js.map +1 -1
  9. package/dist/assets.d.ts.map +1 -1
  10. package/dist/assets.js +2 -1
  11. package/dist/assets.js.map +1 -1
  12. package/dist/cms-live-preview.d.ts.map +1 -1
  13. package/dist/cms-live-preview.js +7 -1
  14. package/dist/cms-live-preview.js.map +1 -1
  15. package/dist/csp.d.ts +11 -0
  16. package/dist/csp.d.ts.map +1 -0
  17. package/dist/csp.js +16 -0
  18. package/dist/csp.js.map +1 -0
  19. package/dist/file-size.js +1 -1
  20. package/dist/file-size.js.map +1 -1
  21. package/dist/form.d.ts +53 -1
  22. package/dist/form.d.ts.map +1 -1
  23. package/dist/form.js +96 -4
  24. package/dist/form.js.map +1 -1
  25. package/dist/icons.d.ts +6 -0
  26. package/dist/icons.d.ts.map +1 -1
  27. package/dist/icons.js +9 -1
  28. package/dist/icons.js.map +1 -1
  29. package/dist/image-editor.d.ts +2 -2
  30. package/dist/image-editor.js +2 -2
  31. package/dist/image-files.d.ts +8 -0
  32. package/dist/image-files.d.ts.map +1 -1
  33. package/dist/image-files.js +11 -1
  34. package/dist/image-files.js.map +1 -1
  35. package/dist/index.d.ts +12 -11
  36. package/dist/index.js +10 -9
  37. package/dist/kanban.d.ts.map +1 -1
  38. package/dist/kanban.js +1 -1
  39. package/dist/kanban.js.map +1 -1
  40. package/dist/page-actions.d.ts +10 -2
  41. package/dist/page-actions.d.ts.map +1 -1
  42. package/dist/page-actions.js +15 -5
  43. package/dist/page-actions.js.map +1 -1
  44. package/dist/schema/advanced-fields.d.ts +5 -0
  45. package/dist/schema/advanced-fields.d.ts.map +1 -1
  46. package/dist/schema/cms.d.ts +4 -0
  47. package/dist/schema/cms.d.ts.map +1 -1
  48. package/dist/schema/components.d.ts +5 -0
  49. package/dist/schema/components.d.ts.map +1 -1
  50. package/dist/schema/components.js.map +1 -1
  51. package/dist/schema/index.d.ts +3 -3
  52. package/dist/schema/panel.d.ts +31 -0
  53. package/dist/schema/panel.d.ts.map +1 -1
  54. package/dist/schema/panel.js.map +1 -1
  55. package/dist/schema/table-grouping.d.ts +5 -1
  56. package/dist/schema/table-grouping.d.ts.map +1 -1
  57. package/dist/standalone.d.ts +10 -3
  58. package/dist/standalone.d.ts.map +1 -1
  59. package/dist/standalone.js +12 -2
  60. package/dist/standalone.js.map +1 -1
  61. package/dist/starter-kit-widgets.d.ts +40 -7
  62. package/dist/starter-kit-widgets.d.ts.map +1 -1
  63. package/dist/starter-kit-widgets.js +71 -7
  64. package/dist/starter-kit-widgets.js.map +1 -1
  65. package/dist/starter-kit.d.ts +24 -1
  66. package/dist/starter-kit.d.ts.map +1 -1
  67. package/dist/starter-kit.js +33 -3
  68. package/dist/starter-kit.js.map +1 -1
  69. package/dist/utils/debounce.d.ts +2 -0
  70. package/dist/utils/debounce.d.ts.map +1 -1
  71. package/dist/utils/debounce.js +1 -0
  72. package/dist/utils/debounce.js.map +1 -1
  73. package/dist/utils/path.d.ts +11 -1
  74. package/dist/utils/path.d.ts.map +1 -1
  75. package/dist/utils/path.js +30 -3
  76. package/dist/utils/path.js.map +1 -1
  77. package/package.json +5 -3
  78. package/themes.css +8 -335
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @alfakit/core
2
2
 
3
+ ## 0.1.6
4
+
5
+ ### Patch Changes
6
+
7
+ - Released with AlfaKit 0.1.6 (the npm and PHP versions now match). Fixes from the full verification in React, Vue and Svelte: starter-kit copilot, dashboard widgets and discovered components, per-item form errors, stable template schemas in new blocks, CSP nonces, WCAG AA badge contrast, plural kanban counts and more (see the AlfaKit changelog for 0.1.6).
8
+
9
+ ## 0.1.2
10
+
11
+ ### Patch Changes
12
+
13
+ - Fixes from end-to-end QA in React, Vue and Svelte: modal field ids, errors in hidden tabs, per-row action spinners, one-time-code paste, RTL fixes (colours, key bindings, calendar), localised file sizes and named upload buttons, select placeholders, single toasts in starter kits, readable tab query values, enum group titles, tenant menu labels, Svelte hydration gate, plugin styles in starter-kit mode, and more (see the AlfaKit changelog for 0.1.2).
14
+
3
15
  ## 0.1.1
4
16
 
5
17
  ### Patch Changes
package/components.css ADDED
@@ -0,0 +1,347 @@
1
+ /*
2
+ * Component styles shared by panels (themes.css) and by Alfakit outside panels
3
+ * (standalone.css, starter-kit panels): chart colours, RichEditor columns, the calendar,
4
+ * tree and Kanban plugins, and field positioning. They read the theme tokens (`--primary`,
5
+ * `--border`…), whichever stylesheet defines them. Copied into each renderer's dist.
6
+ */
7
+
8
+ /* ------------------------------------------------------------------ Charts */
9
+
10
+ /*
11
+ * Chart.js paints axes, legends and tooltips on the canvas, so chart widgets read these
12
+ * properties from <html> (re-read when the theme or dark mode changes). Colours take any
13
+ * CSS colour; the widths and radius are unitless numbers. Override them in a theme:
14
+ * :root[data-alfakit-theme~='acme'] { --chart-tooltip-bg: oklch(0.2 0 0); }
15
+ * Stat sparklines (`[data-slot='stat-chart']`) use the `--stat-chart-*` properties.
16
+ */
17
+ :root {
18
+ --chart-text: var(--muted-foreground);
19
+ --chart-grid: var(--border);
20
+ --chart-legend-foreground: var(--muted-foreground);
21
+ --chart-tooltip-bg: var(--popover);
22
+ --chart-tooltip-foreground: var(--popover-foreground);
23
+ --chart-tooltip-border: var(--border);
24
+ --chart-tooltip-border-width: 1;
25
+ --chart-tooltip-radius: 6;
26
+ --stat-chart-stroke-width: 2;
27
+ --stat-chart-fill-opacity: 0.12;
28
+ }
29
+
30
+ /*
31
+ * RichEditor `grid` column blocks and `lead` / `small` text, in the editor and in rendered
32
+ * content (`RichContentRenderer`). Columns stack on small screens. Stored as
33
+ * `<div data-type="grid" class="alfakit-grid alfakit-grid-cols-2"><div data-type="gridColumn">`
34
+ * and `<p class="alfakit-lead">`; copy these rules when showing content outside a panel.
35
+ */
36
+ :where(.alfakit-grid) {
37
+ display: grid;
38
+ gap: 1rem;
39
+ grid-template-columns: minmax(0, 1fr);
40
+ margin-block: 0.5rem;
41
+ }
42
+ :where(.alfakit-grid-column) {
43
+ min-width: 0;
44
+ }
45
+ :where(.alfakit-grid-column) > :first-child {
46
+ margin-block-start: 0;
47
+ }
48
+ @media (min-width: 768px) {
49
+ :where(.alfakit-grid-cols-2) {
50
+ grid-template-columns: repeat(2, minmax(0, 1fr));
51
+ }
52
+ :where(.alfakit-grid-cols-3) {
53
+ grid-template-columns: repeat(3, minmax(0, 1fr));
54
+ }
55
+ :where(.alfakit-grid-cols-4) {
56
+ grid-template-columns: repeat(4, minmax(0, 1fr));
57
+ }
58
+ :where(.alfakit-grid-cols-5) {
59
+ grid-template-columns: repeat(5, minmax(0, 1fr));
60
+ }
61
+ :where(.alfakit-grid-cols-6) {
62
+ grid-template-columns: repeat(6, minmax(0, 1fr));
63
+ }
64
+ }
65
+ :where([contenteditable] .alfakit-grid-column) {
66
+ border: 1px dashed var(--border);
67
+ border-radius: 0.375rem;
68
+ padding: 0.25rem 0.5rem;
69
+ }
70
+ :where(.alfakit-lead) {
71
+ font-size: 1.125em;
72
+ line-height: 1.6;
73
+ }
74
+ :where(.alfakit-prose small) {
75
+ font-size: 0.8125em;
76
+ }
77
+
78
+ /* ---------------------------------------------------------- Calendar and tree */
79
+
80
+ /*
81
+ * The calendar widget (alfasix/alfakit-calendar) draws FullCalendar inside
82
+ * `[data-slot="calendar"]`; FullCalendar reads these `--fc-*` variables, so every theme's
83
+ * tokens (and dark mode) apply. Override them on the slot to restyle one calendar.
84
+ */
85
+ :where(.fc[data-slot='calendar']) {
86
+ --fc-small-font-size: 0.75rem;
87
+ --fc-page-bg-color: var(--card);
88
+ --fc-neutral-bg-color: var(--muted);
89
+ --fc-neutral-text-color: var(--muted-foreground);
90
+ --fc-border-color: var(--border);
91
+ --fc-button-text-color: var(--foreground);
92
+ --fc-button-bg-color: var(--background);
93
+ --fc-button-border-color: var(--border);
94
+ --fc-button-hover-bg-color: var(--accent);
95
+ --fc-button-hover-border-color: var(--border);
96
+ --fc-button-active-bg-color: var(--secondary);
97
+ --fc-button-active-border-color: var(--border);
98
+ --fc-event-bg-color: var(--primary);
99
+ --fc-event-border-color: var(--primary);
100
+ --fc-event-text-color: var(--primary-foreground);
101
+ --fc-event-selected-overlay-color: color-mix(in oklab, var(--foreground) 25%, transparent);
102
+ --fc-more-link-bg-color: var(--muted);
103
+ --fc-more-link-text-color: var(--foreground);
104
+ --fc-non-business-color: color-mix(in oklab, var(--muted) 60%, transparent);
105
+ --fc-bg-event-color: var(--primary);
106
+ --fc-bg-event-opacity: 0.2;
107
+ --fc-highlight-color: color-mix(in oklab, var(--primary) 15%, transparent);
108
+ --fc-today-bg-color: color-mix(in oklab, var(--primary) 6%, transparent);
109
+ --fc-now-indicator-color: var(--destructive);
110
+ --fc-list-event-hover-bg-color: var(--accent);
111
+ color: var(--card-foreground);
112
+ }
113
+ /*
114
+ * FullCalendar puts its `fc` class on the slot element itself and injects its own CSS
115
+ * (`.fc .fc-button`, two classes), so these rules are plain selectors anchored on
116
+ * `.fc[data-slot='calendar']` (three) rather than `:where()`, which would always lose.
117
+ * Restyle one calendar with a more specific selector or with the `--fc-*` variables.
118
+ */
119
+ .fc[data-slot='calendar'] .fc-toolbar-title {
120
+ font-size: 1.125rem;
121
+ font-weight: 600;
122
+ line-height: 1.75rem;
123
+ color: var(--foreground);
124
+ }
125
+ .fc[data-slot='calendar'] .fc-button {
126
+ display: inline-flex;
127
+ align-items: center;
128
+ justify-content: center;
129
+ min-height: 2.25rem;
130
+ padding: 0.375rem 0.75rem;
131
+ border-radius: var(--radius);
132
+ font-size: 0.875rem;
133
+ font-weight: 500;
134
+ line-height: 1.25rem;
135
+ box-shadow: none;
136
+ text-transform: capitalize;
137
+ }
138
+ .fc[data-slot='calendar'] .fc-button .fc-icon {
139
+ font-size: 1.125rem;
140
+ }
141
+ .fc[data-slot='calendar'] .fc-button-group > .fc-button:not(:first-child) {
142
+ border-start-start-radius: 0;
143
+ border-end-start-radius: 0;
144
+ }
145
+ .fc[data-slot='calendar'] .fc-button-group > .fc-button:not(:last-child) {
146
+ border-start-end-radius: 0;
147
+ border-end-end-radius: 0;
148
+ }
149
+ .fc[data-slot='calendar'] .fc-button-primary:disabled {
150
+ opacity: 0.5;
151
+ }
152
+ .fc[data-slot='calendar'] .fc-button-primary:not(:disabled).fc-button-active,
153
+ .fc[data-slot='calendar'] .fc-button-primary:not(:disabled):active {
154
+ color: var(--secondary-foreground);
155
+ }
156
+ .fc[data-slot='calendar'] .fc-button-primary:focus,
157
+ .fc[data-slot='calendar'] .fc-button-primary:not(:disabled).fc-button-active:focus,
158
+ .fc[data-slot='calendar'] .fc-button-primary:not(:disabled):active:focus {
159
+ box-shadow: none;
160
+ }
161
+ .fc[data-slot='calendar'] .fc-button:focus-visible {
162
+ outline: 2px solid var(--ring);
163
+ outline-offset: 2px;
164
+ z-index: 2;
165
+ }
166
+ .fc[data-slot='calendar'] a {
167
+ color: inherit;
168
+ }
169
+ .fc[data-slot='calendar'] .fc-daygrid-day-number,
170
+ .fc[data-slot='calendar'] .fc-col-header-cell-cushion {
171
+ text-decoration: none;
172
+ }
173
+ .fc[data-slot='calendar'] .fc-col-header-cell-cushion {
174
+ padding-block: 0.375rem;
175
+ font-size: 0.75rem;
176
+ font-weight: 500;
177
+ color: var(--muted-foreground);
178
+ }
179
+ .fc[data-slot='calendar'] .fc-daygrid-day-number {
180
+ font-size: 0.875rem;
181
+ }
182
+ .fc[data-slot='calendar'] .fc-day-other .fc-daygrid-day-number {
183
+ color: var(--muted-foreground);
184
+ }
185
+ /* Today: a tinted cell (`--fc-today-bg-color`) and the date in a primary pill. */
186
+ .fc[data-slot='calendar'] .fc-daygrid-day.fc-day-today .fc-daygrid-day-number {
187
+ display: inline-flex;
188
+ align-items: center;
189
+ justify-content: center;
190
+ min-width: 1.75rem;
191
+ height: 1.75rem;
192
+ margin: 0.25rem;
193
+ padding: 0 0.375rem;
194
+ border-radius: 9999px;
195
+ background: var(--primary);
196
+ color: var(--primary-foreground);
197
+ font-weight: 600;
198
+ }
199
+ .fc[data-slot='calendar'] .fc-col-header-cell.fc-day-today .fc-col-header-cell-cushion {
200
+ color: var(--primary);
201
+ font-weight: 600;
202
+ }
203
+ .fc[data-slot='calendar'] .fc-event {
204
+ border-radius: min(var(--radius), 0.375rem);
205
+ }
206
+ .fc[data-slot='calendar'] .fc-daygrid-event,
207
+ .fc[data-slot='calendar'] .fc-timegrid-event .fc-event-main,
208
+ .fc[data-slot='calendar'] .fc-list-event td {
209
+ font-size: 0.75rem;
210
+ }
211
+ /* Clipped titles keep their beginning and end with an ellipsis, also a Latin title in a
212
+ right-to-left calendar (its direction follows its own text). */
213
+ .fc[data-slot='calendar'] .fc-event-title {
214
+ text-overflow: ellipsis;
215
+ unicode-bidi: plaintext;
216
+ text-align: start;
217
+ }
218
+ .fc[data-slot='calendar'] .fc-daygrid-dot-event:hover,
219
+ .fc[data-slot='calendar'] .fc-daygrid-dot-event.fc-event-mirror {
220
+ background: var(--accent);
221
+ }
222
+ .fc[data-slot='calendar'] .fc-list-day-cushion,
223
+ .fc[data-slot='calendar'] .fc-popover-header {
224
+ color: var(--foreground);
225
+ }
226
+ .fc[data-slot='calendar'] .fc-popover {
227
+ border-radius: var(--radius);
228
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);
229
+ overflow: hidden;
230
+ }
231
+ .fc[data-slot='calendar'] .fc-timegrid-slot-label,
232
+ .fc[data-slot='calendar'] .fc-timegrid-axis,
233
+ .fc[data-slot='calendar'] .fc-list-event-time {
234
+ color: var(--muted-foreground);
235
+ font-size: 0.75rem;
236
+ }
237
+ /*
238
+ * The list view hides its column headers for screen readers with `left: -10000px`. Right to
239
+ * left that is scrollable overflow: the whole page gains a 10 000 px horizontal scroll and the
240
+ * top bar slides under the sidebar. Clip it in place instead (still read by screen readers).
241
+ */
242
+ .fc[data-slot='calendar'] .fc-list-table thead {
243
+ left: auto;
244
+ inset-inline-start: 0;
245
+ width: 1px;
246
+ height: 1px;
247
+ overflow: hidden;
248
+ clip-path: inset(50%);
249
+ white-space: nowrap;
250
+ }
251
+
252
+ /*
253
+ * Fields contain what they position. Headless switches, checkboxes and radios render a
254
+ * visually hidden native input beside the control, absolutely positioned (and shifted by
255
+ * -100%); without a positioned field it lands at the page edge and, right to left, widens
256
+ * the page on phones.
257
+ */
258
+ :where([data-slot='field']) {
259
+ position: relative;
260
+ }
261
+
262
+ /*
263
+ * Narrow screens: FullCalendar keeps its header toolbar on one row, wider than a phone.
264
+ * Its chunks (navigation, title, views) wrap instead, and the title shrinks. Flex gaps and
265
+ * `justify-content` follow the writing direction, so this works right to left too. (Plain
266
+ * selectors: FullCalendar injects its own CSS, which would beat `:where()`; the slot is
267
+ * the `.fc` element itself.)
268
+ */
269
+ @media (max-width: 39.99rem) {
270
+ [data-slot='calendar'] .fc-toolbar.fc-header-toolbar {
271
+ flex-wrap: wrap;
272
+ gap: 0.5rem;
273
+ }
274
+ [data-slot='calendar'] .fc-toolbar .fc-toolbar-chunk {
275
+ display: flex;
276
+ flex-wrap: wrap;
277
+ align-items: center;
278
+ gap: 0.25rem;
279
+ min-width: 0;
280
+ }
281
+ [data-slot='calendar'] .fc-toolbar .fc-toolbar-title {
282
+ font-size: 1rem;
283
+ overflow-wrap: anywhere;
284
+ }
285
+ [data-slot='calendar'] .fc-toolbar .fc-button {
286
+ font-size: 0.8125rem;
287
+ }
288
+ }
289
+
290
+ /*
291
+ * The tree (alfasix/alfakit-tree): the drop indicator while dragging. Rows carry
292
+ * `data-drop="before|after|inside"`; lines are drawn above or below the row, so they
293
+ * need no direction.
294
+ */
295
+ :where([data-slot='tree-item'][data-drop='before']) {
296
+ box-shadow: inset 0 2px 0 0 var(--primary);
297
+ }
298
+ :where([data-slot='tree-item'][data-drop='after']) {
299
+ box-shadow: inset 0 -2px 0 0 var(--primary);
300
+ }
301
+ :where([data-slot='tree-item'][data-drop='inside']) {
302
+ background-color: color-mix(in oklab, var(--primary) 10%, transparent);
303
+ outline: 1px dashed var(--primary);
304
+ outline-offset: -1px;
305
+ }
306
+
307
+ /*
308
+ * The Kanban board (alfasix/alfakit-kanban). A card being dragged leaves a dashed
309
+ * placeholder (`data-picked="pointer"`) while a copy follows the pointer
310
+ * (`data-slot="kanban-ghost"`); a card picked up with the keyboard is lifted
311
+ * (`data-picked="keyboard"`). A list the picked card may not enter has `data-refused`.
312
+ */
313
+ :where([data-slot='kanban-card'][data-picked='pointer']) {
314
+ opacity: 0.45;
315
+ }
316
+ :where([data-slot='kanban-card'][data-picked='pointer'] > [data-slot='kanban-card-body']) {
317
+ border-style: dashed;
318
+ box-shadow: none;
319
+ }
320
+ :where([data-slot='kanban-card'][data-picked='keyboard'] > [data-slot='kanban-card-body']) {
321
+ outline: 2px solid var(--primary);
322
+ outline-offset: 2px;
323
+ box-shadow: 0 10px 24px -12px color-mix(in oklab, var(--foreground) 45%, transparent);
324
+ }
325
+ :where([data-slot='kanban-card'][data-saving]) {
326
+ opacity: 0.7;
327
+ }
328
+ :where([data-slot='kanban-ghost']) {
329
+ cursor: grabbing;
330
+ list-style: none;
331
+ box-shadow: 0 18px 40px -16px color-mix(in oklab, var(--foreground) 55%, transparent);
332
+ }
333
+ :where([data-slot='kanban-dropzone'][data-refused]) {
334
+ background-color: color-mix(in oklab, var(--destructive) 8%, transparent);
335
+ outline: 1px dashed var(--destructive);
336
+ outline-offset: -1px;
337
+ }
338
+ :where(body[data-kanban-dragging]) {
339
+ cursor: grabbing;
340
+ user-select: none;
341
+ -webkit-user-select: none;
342
+ }
343
+ @media (prefers-reduced-motion: reduce) {
344
+ :where([data-slot='kanban-card'] > [data-slot='kanban-card-body']) {
345
+ transition: none;
346
+ }
347
+ }
package/dist/actions.d.ts CHANGED
@@ -62,6 +62,11 @@ export interface ActionRunnerState {
62
62
  modals: OpenModal[];
63
63
  /** Name of the action currently loading its modal. */
64
64
  loading: string | null;
65
+ /**
66
+ * Which run of it (component, action path and record): a table renders the same action
67
+ * once per row, and only the clicked row's button is loading (`isActionLoading()`).
68
+ */
69
+ loadingKey?: string | null;
65
70
  }
66
71
  export interface ActionRunnerOptions {
67
72
  endpoints: {
@@ -222,6 +227,10 @@ export declare function menuActionContext(token: string, menu: 'userMenu' | 'ten
222
227
  export declare function groupMenuItems<T extends {
223
228
  group?: number;
224
229
  }>(items: T[]): T[][];
230
+ /** Whether this button's run (this action for this record) is fetching its modal. */
231
+ export declare function isActionLoading(state: ActionRunnerState, action: ActionSchema, context: ActionContext): boolean;
232
+ /** Whether this button's run (this action for this record) has a modal that is submitting. */
233
+ export declare function isActionProcessing(state: ActionRunnerState, action: ActionSchema, context: ActionContext): boolean;
225
234
  /**
226
235
  * The action endpoint for a run. "All records" bulk actions carry the page's query string
227
236
  * (filters, search, list tab), so the server selects exactly the records the table shows.
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","names":[],"sources":["../src/actions.ts"],"mappings":";;;;;;iBA6BiB;;EAEf;;EAEA;EACA,SAAS;;EAET,UAAU;;EAEV;EACA,YAAY;;;;;EAKZ;;;;;EAKA,OAAO;;iBAGQ;;EAEf;;;;;EAKA;;;qBAIW;;;;;wBAMG,mBACd,OAAO,yBACP,UAAU,yBACV,2CACC;iBAiBc;EACf,QAAQ;EACR,SAAS;EACT,OAAO;;EAEP,QAAQ;EACR;;EAEA,WAAW;;;;;EAKX;;iBAGe;;EAEf,QAAQ;;EAER;;iBAGe;EACf;IAAa;IAAgB;;EAC7B,WAAW;;EAEX,aAAa,QAAQ,cAAc,SAAS;;;;;EAK5C,mBAAmB,eAAe;;;;;;qBAOvB;mBASkB;WARb,OAAO,MAAM;;mBAGZ;;mBAGA;EAEY,YAAA,SAAS;MAIlC,SAAS;;EAKb,uBACE,WAAW,eAAe;UAKpB;;EAOR,aAAa,WAAW,QAAQ;;;;;;EAShC,kBAAkB,QAAQ,cAAc,SAAS,eAAe,MAAM;;EAUtE,aAAa,SAAS,gBAAgB,MAAM;;;;;EAkB5C,YAAY,SAAS,gBAAgB,MAAM;;EAoBrC,QAAQ,QAAQ,cAAc,SAAS,gBAAgB;;;;;EA8DvD,SAAS,QAAQ,cAAc,SAAS,gBAAgB;;;;;EAkB9D,kBAAkB,QAAQ,cAAc,SAAS;;;;;EAqBjD,YAAY;;EAYZ,aAAa,SAAS,eAAe;EAY/B,UACJ,QAAQ,cACR,SAAS,eACT,WAAW,2BACV;UAwCK;;;;;EAgCF,WAAW,cAAc,WAAU,0BAA+B;;EAwCxE,UAAU,QAAQ,cAAc,SAAS;EAIzC,WAAW;;EAeX,QACE,QAAQ,cACR,SAAS,eACT,OAAM,yBACN,UAAS;;;;;EAmIL,YAAY,aAChB,QAAQ,cACR,SAAS,eACT,OAAM,0BACL,QAAQ;;;;;EAwCL,aACJ,QAAQ,cACR,SAAS,eACT,OAAM,0BACL;UAgFK;UAWA;;;;;;;wBAqBM,iBACd,QAAQ,KAAK,2CACb,SAAS,KAAK;;YAMJ;;;;;wBAMI,kBACd,MAAM,yBACN,WAAU,mBACT;;wBAiBa,eAAe,MAAM;iBAIpB;EACf;EACA;;;;;;wBAOc,uBAAuB,uCAAuC;;wBAa9D,mBAAmB,SAAS,oBAAoB;;;;;;wBAWhD,qBAAqB,QAAQ,aAAa;;wBAqB1C,qBACd,OAAO,KAAK;;;;;wBAkBE,cACd,8CACA;;;;;wBAiBc,wBACd,OAAO,KAAK,2CACZ;EAAQ;;;;;;wBASM,kBACd,OAAO,KAAK,2CACZ;EAAQ;sBACR;;;;;;wBAcc,iBACd,OAAO,KAAK,2CACZ;EAAQ;sBACR;;wBA8Bc,kBAAkB,eAAe,kCAAkC;;;;;wBAQnE,eAAe;EAAY;GAAkB,OAAO,MAAM;;;;;wBA4B1D,eACd,kBACA,SAAS,KAAK,8BACd"}
1
+ {"version":3,"file":"actions.d.ts","names":[],"sources":["../src/actions.ts"],"mappings":";;;;;;iBA6BiB;;EAEf;;EAEA;EACA,SAAS;;EAET,UAAU;;EAEV;EACA,YAAY;;;;;EAKZ;;;;;EAKA,OAAO;;iBAGQ;;EAEf;;;;;EAKA;;;qBAIW;;;;;wBAMG,mBACd,OAAO,yBACP,UAAU,yBACV,2CACC;iBAiBc;EACf,QAAQ;EACR,SAAS;EACT,OAAO;;EAEP,QAAQ;EACR;;EAEA,WAAW;;;;;EAKX;;iBAGe;;EAEf,QAAQ;;EAER;;;;;EAKA;;iBAGe;EACf;IAAa;IAAgB;;EAC7B,WAAW;;EAEX,aAAa,QAAQ,cAAc,SAAS;;;;;EAK5C,mBAAmB,eAAe;;;;;;qBAOvB;mBASkB;WARb,OAAO,MAAM;;mBAGZ;;mBAGA;EAEY,YAAA,SAAS;MAIlC,SAAS;;EAKb,uBACE,WAAW,eAAe;UAKpB;;EAOR,aAAa,WAAW,QAAQ;;;;;;EAShC,kBAAkB,QAAQ,cAAc,SAAS,eAAe,MAAM;;EAUtE,aAAa,SAAS,gBAAgB,MAAM;;;;;EAkB5C,YAAY,SAAS,gBAAgB,MAAM;;EAoBrC,QAAQ,QAAQ,cAAc,SAAS,gBAAgB;;;;;EA8DvD,SAAS,QAAQ,cAAc,SAAS,gBAAgB;;;;;EAkB9D,kBAAkB,QAAQ,cAAc,SAAS;;;;;EAqBjD,YAAY;;EAYZ,aAAa,SAAS,eAAe;EAY/B,UACJ,QAAQ,cACR,SAAS,eACT,WAAW,2BACV;UAyCK;;;;;EAwCF,WAAW,cAAc,WAAU,0BAA+B;;EAwCxE,UAAU,QAAQ,cAAc,SAAS;EAIzC,WAAW;;EAeX,QACE,QAAQ,cACR,SAAS,eACT,OAAM,yBACN,UAAS;;;;;EAmIL,YAAY,aAChB,QAAQ,cACR,SAAS,eACT,OAAM,0BACL,QAAQ;;;;;EAwCL,aACJ,QAAQ,cACR,SAAS,eACT,OAAM,0BACL;UAgFK;UAWA;;;;;;;wBAqBM,iBACd,QAAQ,KAAK,2CACb,SAAS,KAAK;;YAMJ;;;;;wBAMI,kBACd,MAAM,yBACN,WAAU,mBACT;;wBAiBa,eAAe,MAAM;iBAIpB;EACf;EACA;;;;;;wBAOc,uBAAuB,uCAAuC;;wBAa9D,mBAAmB,SAAS,oBAAoB;;;;;;wBAWhD,qBAAqB,QAAQ,aAAa;;wBAqB1C,qBACd,OAAO,KAAK;;;;;wBAkBE,cACd,8CACA;;;;;wBAiBc,wBACd,OAAO,KAAK,2CACZ;EAAQ;;;;;;wBASM,kBACd,OAAO,KAAK,2CACZ;EAAQ;sBACR;;;;;;wBAcc,iBACd,OAAO,KAAK,2CACZ;EAAQ;sBACR;;wBA8Bc,kBAAkB,eAAe,kCAAkC;;;;;wBAQnE,eAAe;EAAY;GAAkB,OAAO,MAAM;;wBAmB1D,gBACd,OAAO,mBACP,QAAQ,cACR,SAAS;;wBAMK,mBACd,OAAO,mBACP,QAAQ,cACR,SAAS;;;;;wBAmBK,eACd,kBACA,SAAS,KAAK,8BACd"}
package/dist/actions.js CHANGED
@@ -39,7 +39,8 @@ var ActionRunner = class {
39
39
  this.options = options;
40
40
  this.store = createStore({
41
41
  modals: [],
42
- loading: null
42
+ loading: null,
43
+ loadingKey: null
43
44
  });
44
45
  }
45
46
  get state() {
@@ -175,17 +176,24 @@ var ActionRunner = class {
175
176
  return;
176
177
  }
177
178
  this.running.add(key);
178
- this.store.update({ loading: action.name });
179
+ this.store.update({
180
+ loading: action.name,
181
+ loadingKey: runKey(action, context)
182
+ });
179
183
  try {
180
184
  const modal = await this.fetchModal(action, context);
181
185
  if (isCancelledModal(modal)) {
182
- this.store.update({ loading: null });
186
+ this.store.update({
187
+ loading: null,
188
+ loadingKey: null
189
+ });
183
190
  this.notify(modal.notifications);
184
191
  resolve?.(void 0);
185
192
  return;
186
193
  }
187
194
  this.store.set((state) => ({
188
195
  loading: null,
196
+ loadingKey: null,
189
197
  modals: [...state.modals, {
190
198
  action,
191
199
  context,
@@ -196,7 +204,10 @@ var ActionRunner = class {
196
204
  }]
197
205
  }));
198
206
  } catch (error) {
199
- this.store.update({ loading: null });
207
+ this.store.update({
208
+ loading: null,
209
+ loadingKey: null
210
+ });
200
211
  resolve?.(void 0);
201
212
  this.options.onError?.(error);
202
213
  } finally {
@@ -204,11 +215,17 @@ var ActionRunner = class {
204
215
  }
205
216
  }
206
217
  fetchModal(action, context) {
218
+ const records = context.records;
219
+ const isBulk = records !== void 0;
207
220
  const params = {
208
221
  token: context.token,
209
222
  component: context.component,
210
223
  action: actionPath(action, context),
211
224
  record: context.record ?? void 0,
225
+ records: records !== void 0 && records.length > 0 ? records : void 0,
226
+ allRecords: context.allRecords ? 1 : void 0,
227
+ bulk: isBulk ? 1 : void 0,
228
+ tableQuery: isBulk ? currentPageQuery() : void 0,
212
229
  arguments: context.arguments
213
230
  };
214
231
  const mountedData = this.mountedData(context);
@@ -586,6 +603,15 @@ function groupMenuItems(items) {
586
603
  }
587
604
  return groups;
588
605
  }
606
+ /** Whether this button's run (this action for this record) is fetching its modal. */
607
+ function isActionLoading(state, action, context) {
608
+ return state.loadingKey === runKey(action, context);
609
+ }
610
+ /** Whether this button's run (this action for this record) has a modal that is submitting. */
611
+ function isActionProcessing(state, action, context) {
612
+ const key = runKey(action, context);
613
+ return state.modals.some((modal) => modal.processing && runKey(modal.action, modal.context) === key);
614
+ }
589
615
  function runKey(action, context) {
590
616
  return [
591
617
  context.component ?? "page",
@@ -602,6 +628,6 @@ function actionEndpoint(endpoint, context, search = typeof window !== "undefined
602
628
  return endpoint + (endpoint.includes("?") ? "&" : "?") + search.replace(/^\?/, "");
603
629
  }
604
630
  //#endregion
605
- export { ActionRunner, CREATE_ANOTHER_ARGUMENT, actionEndpoint, bindsKeyBindings, confirmModalClose, createAnotherState, flattenActionGroup, groupMenuItems, guardModalUnload, iconButtonSize, isModalHiddenByChild, menuActionContext, modalFooterAlignment, parseDropdownPlacement, resolveActionSize, shouldConfirmModalClose, slideOverSide };
631
+ export { ActionRunner, CREATE_ANOTHER_ARGUMENT, actionEndpoint, bindsKeyBindings, confirmModalClose, createAnotherState, flattenActionGroup, groupMenuItems, guardModalUnload, iconButtonSize, isActionLoading, isActionProcessing, isModalHiddenByChild, menuActionContext, modalFooterAlignment, parseDropdownPlacement, resolveActionSize, shouldConfirmModalClose, slideOverSide };
606
632
 
607
633
  //# sourceMappingURL=actions.js.map