@stonecrop/desktop 0.33.0 → 0.34.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.
package/dist/desktop.js CHANGED
@@ -1,109 +1,17 @@
1
- import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, resolveComponent, toDisplayString, unref, useTemplateRef, vModelText, vShow, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
1
+ import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, guardReactiveProps, h, inject, markRaw, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, resolveComponent, resolveDynamicComponent, shallowRef, toDisplayString, unref, useTemplateRef, vModelText, vShow, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
2
2
  import { DRAFT_RECORD_ID, isDraftRecordId, useStonecrop, useValidationStore } from "@stonecrop/stonecrop";
3
3
  import { AForm, resolvedFieldsToColumns } from "@stonecrop/aform";
4
- import './assets/index.css';//#region src/components/ActionSet.vue?vue&type=script&setup=true&lang.ts
5
- var _hoisted_1$3 = { class: "action-menu-icon" };
6
- var _hoisted_2$3 = { class: "action-element-header" };
7
- var _hoisted_3$2 = ["disabled", "onClick"];
8
- var _hoisted_4$2 = { key: 0 };
9
- var _hoisted_5$2 = { class: "dropdown-header" };
10
- var _hoisted_6$1 = ["onClick"];
11
- var _hoisted_7$1 = ["onClick"];
12
- var _hoisted_8 = { class: "dropdown-container" };
13
- var _hoisted_9 = { class: "dropdown" };
14
- var _hoisted_10 = ["onClick"];
15
- var _hoisted_11 = ["href"];
16
- var _hoisted_12 = { class: "dropdown-item" };
17
- var ActionSet_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
18
- __name: "ActionSet",
19
- props: { elements: { default: () => [] } },
20
- emits: ["actionClick"],
21
- setup(__props, { emit: __emit }) {
22
- const emit = __emit;
23
- const dropdownStates = ref({});
24
- const isOpen = ref(true);
25
- const dropdownOpen = ref([]);
26
- onMounted(() => {
27
- closeDropdowns();
28
- });
29
- const closeDropdowns = () => {
30
- dropdownStates.value = {};
31
- dropdownOpen.value = [];
32
- };
33
- const onClick = () => {
34
- isOpen.value = !isOpen.value;
35
- };
36
- const toggleDropdown = (index) => {
37
- const showDropdown = !dropdownStates.value[index];
38
- closeDropdowns();
39
- if (showDropdown) {
40
- dropdownStates.value[index] = true;
41
- dropdownOpen.value[index] = true;
42
- }
43
- };
44
- const handleClick = (action, label) => {
45
- emit("actionClick", label, action);
46
- };
47
- return (_ctx, _cache) => {
48
- return openBlock(), createElementBlock("div", { class: normalizeClass([{ collapsed: !isOpen.value }, "action-set"]) }, [
49
- createElementVNode("div", _hoisted_1$3, [createElementVNode("div", {
50
- id: "cross",
51
- class: normalizeClass({ rotated: isOpen.value }),
52
- onClick
53
- }, "×", 2)]),
54
- _cache[0] || (_cache[0] = createElementVNode("div", { style: { "margin-right": "30px" } }, null, -1)),
55
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.elements, (el, index) => {
56
- return openBlock(), createElementBlock("div", {
57
- key: el.label,
58
- class: "action-element"
59
- }, [createElementVNode("div", _hoisted_2$3, [el.type == "button" ? (openBlock(), createElementBlock("button", {
60
- key: 0,
61
- disabled: el.disabled,
62
- class: "button-default",
63
- onClick: ($event) => handleClick(el.action, el.label)
64
- }, toDisplayString(el.label), 9, _hoisted_3$2)) : createCommentVNode("", true)]), el.type == "dropdown" ? (openBlock(), createElementBlock("div", _hoisted_4$2, [createElementVNode("div", _hoisted_5$2, [createElementVNode("div", {
65
- class: normalizeClass(["cross", { rotated: dropdownOpen.value[index] }]),
66
- onClick: ($event) => toggleDropdown(index)
67
- }, "×", 10, _hoisted_6$1), createElementVNode("button", {
68
- class: "button-default dropdown-title",
69
- onClick: ($event) => toggleDropdown(index)
70
- }, toDisplayString(el.label), 9, _hoisted_7$1)]), withDirectives(createElementVNode("div", _hoisted_8, [createElementVNode("div", _hoisted_9, [(openBlock(true), createElementBlock(Fragment, null, renderList(el.actions, (item) => {
71
- return openBlock(), createElementBlock("div", { key: item.label }, [item.action != null ? (openBlock(), createElementBlock("button", {
72
- key: 0,
73
- class: "dropdown-item",
74
- onClick: ($event) => handleClick(item.action, item.label)
75
- }, toDisplayString(item.label), 9, _hoisted_10)) : item.link != null ? (openBlock(), createElementBlock("a", {
76
- key: 1,
77
- href: item.link
78
- }, [createElementVNode("button", _hoisted_12, toDisplayString(item.label), 1)], 8, _hoisted_11)) : createCommentVNode("", true)]);
79
- }), 128))])], 512), [[vShow, dropdownStates.value[index]]])])) : createCommentVNode("", true)]);
80
- }), 128))
81
- ], 2);
82
- };
83
- }
84
- });
85
- //#endregion
86
- //#region \0plugin-vue:export-helper
87
- var _plugin_vue_export_helper_default = (sfc, props) => {
88
- const target = sfc.__vccOpts || sfc;
89
- for (const [key, val] of props) target[key] = val;
90
- return target;
91
- };
92
- //#endregion
93
- //#region src/components/ActionSet.vue
94
- var ActionSet_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ActionSet_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-8e18f635"]]);
95
- //#endregion
96
- //#region src/components/CommandPalette.vue?vue&type=script&setup=true&lang.ts
97
- var _hoisted_1$2 = { class: "command-palette-header" };
98
- var _hoisted_2$2 = ["placeholder"];
99
- var _hoisted_3$1 = {
4
+ import './assets/index.css';//#region src/components/CommandPalette.vue?vue&type=script&setup=true&lang.ts
5
+ var _hoisted_1$3 = { class: "command-palette-header" };
6
+ var _hoisted_2$3 = ["placeholder"];
7
+ var _hoisted_3$3 = {
100
8
  key: 0,
101
9
  class: "command-palette-results"
102
10
  };
103
- var _hoisted_4$1 = ["onClick", "onMouseover"];
104
- var _hoisted_5$1 = { class: "result-title" };
105
- var _hoisted_6 = { class: "result-content" };
106
- var _hoisted_7 = {
11
+ var _hoisted_4$3 = ["onClick", "onMouseover"];
12
+ var _hoisted_5$3 = { class: "result-title" };
13
+ var _hoisted_6$2 = { class: "result-content" };
14
+ var _hoisted_7$1 = {
107
15
  key: 1,
108
16
  class: "command-palette-no-results"
109
17
  };
@@ -173,7 +81,7 @@ var CommandPalette_default = /* @__PURE__ */ defineComponent({
173
81
  }, [createElementVNode("div", {
174
82
  class: "command-palette",
175
83
  onClick: _cache[1] || (_cache[1] = withModifiers(() => {}, ["stop"]))
176
- }, [createElementVNode("div", _hoisted_1$2, [withDirectives(createElementVNode("input", {
84
+ }, [createElementVNode("div", _hoisted_1$3, [withDirectives(createElementVNode("input", {
177
85
  ref: "input",
178
86
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => query.value = $event),
179
87
  type: "text",
@@ -181,32 +89,341 @@ var CommandPalette_default = /* @__PURE__ */ defineComponent({
181
89
  placeholder: __props.placeholder,
182
90
  autofocus: "",
183
91
  onKeydown: handleKeydown
184
- }, null, 40, _hoisted_2$2), [[vModelText, query.value]])]), results.value.length ? (openBlock(), createElementBlock("div", _hoisted_3$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(results.value, (result, index) => {
92
+ }, null, 40, _hoisted_2$3), [[vModelText, query.value]])]), results.value.length ? (openBlock(), createElementBlock("div", _hoisted_3$3, [(openBlock(true), createElementBlock(Fragment, null, renderList(results.value, (result, index) => {
185
93
  return openBlock(), createElementBlock("div", {
186
94
  key: index,
187
95
  class: normalizeClass(["command-palette-result", { selected: index === selectedIndex.value }]),
188
96
  onClick: ($event) => selectResult(result),
189
97
  onMouseover: ($event) => selectedIndex.value = index
190
- }, [createElementVNode("div", _hoisted_5$1, [renderSlot(_ctx.$slots, "title", { result })]), createElementVNode("div", _hoisted_6, [renderSlot(_ctx.$slots, "content", { result })])], 42, _hoisted_4$1);
191
- }), 128))])) : query.value && !results.value.length ? (openBlock(), createElementBlock("div", _hoisted_7, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode(" No results found for \"" + toDisplayString(query.value) + "\" ", 1)])])) : createCommentVNode("", true)])])) : createCommentVNode("", true)]),
98
+ }, [createElementVNode("div", _hoisted_5$3, [renderSlot(_ctx.$slots, "title", { result })]), createElementVNode("div", _hoisted_6$2, [renderSlot(_ctx.$slots, "content", { result })])], 42, _hoisted_4$3);
99
+ }), 128))])) : query.value && !results.value.length ? (openBlock(), createElementBlock("div", _hoisted_7$1, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode(" No results found for \"" + toDisplayString(query.value) + "\" ", 1)])])) : createCommentVNode("", true)])])) : createCommentVNode("", true)]),
192
100
  _: 3
193
101
  })]);
194
102
  };
195
103
  }
196
104
  });
197
105
  //#endregion
106
+ //#region src/icons/index.ts
107
+ /**
108
+ * Shared 24×24 stroke chrome for ActionSet and shell icons.
109
+ * Paths are Lucide (or a reduced Autoreader tray) so 16px tiles stay a distinct silhouette.
110
+ */
111
+ function actionSetIcon(name, children) {
112
+ return defineComponent({
113
+ name,
114
+ inheritAttrs: false,
115
+ setup(_, { attrs }) {
116
+ return () => h("svg", mergeProps({
117
+ viewBox: "0 0 24 24",
118
+ fill: "none",
119
+ stroke: "currentColor",
120
+ "stroke-width": "2",
121
+ "stroke-linecap": "round",
122
+ "stroke-linejoin": "round",
123
+ "aria-hidden": "true"
124
+ }, attrs), children());
125
+ }
126
+ });
127
+ }
128
+ /** Two flowchart nodes and a connecting elbow — FSM / BPA “move”. @public */
129
+ var ActionSetIconActions = actionSetIcon("ActionSetIconActions", () => [
130
+ h("rect", {
131
+ width: "8",
132
+ height: "8",
133
+ x: "3",
134
+ y: "3",
135
+ rx: "2"
136
+ }),
137
+ h("path", { d: "M7 11v4a2 2 0 0 0 2 2h4" }),
138
+ h("rect", {
139
+ width: "8",
140
+ height: "8",
141
+ x: "13",
142
+ y: "13",
143
+ rx: "2"
144
+ })
145
+ ]);
146
+ /** Magnifier. @public */
147
+ var ActionSetIconSearch = actionSetIcon("ActionSetIconSearch", () => [h("circle", {
148
+ cx: "11",
149
+ cy: "11",
150
+ r: "8"
151
+ }), h("path", { d: "m21 21-4.3-4.3" })]);
152
+ /** Speech bubble with a tail. @public */
153
+ var ActionSetIconChat = actionSetIcon("ActionSetIconChat", () => [h("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" })]);
154
+ /** Autoreader stacked trays, reduced to 24 viewBox. @public */
155
+ var ActionSetIconEmail = actionSetIcon("ActionSetIconEmail", () => [
156
+ h("rect", {
157
+ x: "5",
158
+ y: "3",
159
+ width: "14",
160
+ height: "8",
161
+ rx: "1.5"
162
+ }),
163
+ h("path", { d: "M8 7h8" }),
164
+ h("path", { d: "M3 12h18" }),
165
+ h("rect", {
166
+ x: "5",
167
+ y: "13",
168
+ width: "14",
169
+ height: "8",
170
+ rx: "1.5"
171
+ }),
172
+ h("path", { d: "M8 17h8" })
173
+ ]);
174
+ /** Paperclip — attachments, not another document. @public */
175
+ var ActionSetIconFiles = actionSetIcon("ActionSetIconFiles", () => [h("path", { d: "m16 6-8.414 8.586a2 2 0 0 0 0 2.828 2 2 0 0 0 2.828 0l8.414-8.586a4 4 0 0 0 0-5.656 4 4 0 0 0-5.656 0l-8.415 8.585a6 6 0 1 0 8.486 8.486" })]);
176
+ /** Page with a check — the Approvals stamp, simplified. @public */
177
+ var ActionSetIconApprovals = actionSetIcon("ActionSetIconApprovals", () => [
178
+ h("path", { d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.687.687l3.626 3.626A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" }),
179
+ h("path", { d: "M14 2v5a1 1 0 0 0 1 1h5" }),
180
+ h("path", { d: "m9 15 2 2 4-4" })
181
+ ]);
182
+ /** Three rising bars — reports / BI. @public */
183
+ var ActionSetIconReports = actionSetIcon("ActionSetIconReports", () => [
184
+ h("path", { d: "M5 21v-6" }),
185
+ h("path", { d: "M12 21V3" }),
186
+ h("path", { d: "M19 21V9" })
187
+ ]);
188
+ /** Printer. @public */
189
+ var ActionSetIconPrint = actionSetIcon("ActionSetIconPrint", () => [
190
+ h("path", { d: "M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2" }),
191
+ h("path", { d: "M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6" }),
192
+ h("rect", {
193
+ x: "6",
194
+ y: "14",
195
+ width: "12",
196
+ height: "8",
197
+ rx: "1"
198
+ })
199
+ ]);
200
+ /** Gear. @public */
201
+ var ActionSetIconSettings = actionSetIcon("ActionSetIconSettings", () => [h("path", { d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" }), h("circle", {
202
+ cx: "12",
203
+ cy: "12",
204
+ r: "3"
205
+ })]);
206
+ /** Circled question mark. @public */
207
+ var ActionSetIconHelp = actionSetIcon("ActionSetIconHelp", () => [
208
+ h("circle", {
209
+ cx: "12",
210
+ cy: "12",
211
+ r: "10"
212
+ }),
213
+ h("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
214
+ h("path", { d: "M12 17h.01" })
215
+ ]);
216
+ //#endregion
217
+ //#region src/components/ActionSet.vue?vue&type=script&setup=true&lang.ts
218
+ var _hoisted_1$2 = {
219
+ class: "action-set__tile",
220
+ role: "presentation"
221
+ };
222
+ var _hoisted_2$2 = ["aria-expanded"];
223
+ var _hoisted_3$2 = [
224
+ "aria-label",
225
+ "aria-current",
226
+ "title",
227
+ "onClick"
228
+ ];
229
+ var _hoisted_4$2 = {
230
+ key: 1,
231
+ class: "action-set__item-fallback",
232
+ "aria-hidden": "true"
233
+ };
234
+ var _hoisted_5$2 = {
235
+ key: 2,
236
+ class: "action-set__item-badge"
237
+ };
238
+ var _hoisted_6$1 = { class: "action-set__drawer-header" };
239
+ var _hoisted_7 = { class: "action-set__drawer-body" };
240
+ var _hoisted_8 = {
241
+ key: 0,
242
+ class: "action-set__actions-list"
243
+ };
244
+ var _hoisted_9 = ["aria-label"];
245
+ var _hoisted_10 = {
246
+ class: "action-set__actions-group-label",
247
+ "aria-hidden": "true"
248
+ };
249
+ var _hoisted_11 = ["onClick"];
250
+ var _hoisted_12 = ["href"];
251
+ var _hoisted_13 = ["href"];
252
+ var _hoisted_14 = ["disabled", "onClick"];
253
+ var _hoisted_15 = {
254
+ key: 0,
255
+ class: "action-set__actions-empty"
256
+ };
257
+ var _hoisted_16 = {
258
+ key: 1,
259
+ class: "action-set__drawer-empty"
260
+ };
261
+ var ACTIONS_TAB_ID = "__actions__";
262
+ var SEARCH_TAB_ID = "__search__";
263
+ var ActionSet_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
264
+ __name: "ActionSet",
265
+ props: {
266
+ slots: { default: () => [] },
267
+ elements: { default: () => [] },
268
+ controller: {}
269
+ },
270
+ emits: ["actionClick", "search"],
271
+ setup(__props, { emit: __emit }) {
272
+ const emit = __emit;
273
+ const isExpanded = ref(true);
274
+ const drawerEl = ref(null);
275
+ const lastFocusedBeforeDrawer = ref(null);
276
+ const activeSlot = computed(() => __props.slots.find((slot) => slot.id === __props.controller.activeSlotId.value) ?? null);
277
+ const hasActions = computed(() => __props.elements.length > 0);
278
+ const activeTabId = computed(() => __props.controller.isActionsOpen.value ? ACTIONS_TAB_ID : __props.controller.activeSlotId.value);
279
+ const drawerOpen = computed(() => __props.controller.isDrawerOpen.value);
280
+ const allTabs = computed(() => {
281
+ const tabs = [{
282
+ id: SEARCH_TAB_ID,
283
+ label: "Search",
284
+ icon: markRaw(ActionSetIconSearch)
285
+ }];
286
+ for (const slot of __props.slots) tabs.push({
287
+ id: slot.id,
288
+ label: slot.label,
289
+ icon: slot.icon,
290
+ badge: slot.badge !== void 0 ? unref(slot.badge) : void 0
291
+ });
292
+ if (hasActions.value) tabs.push({
293
+ id: ACTIONS_TAB_ID,
294
+ label: "Actions",
295
+ icon: markRaw(ActionSetIconActions)
296
+ });
297
+ return tabs;
298
+ });
299
+ function slotFallback(label) {
300
+ return label.trim().charAt(0).toUpperCase() || "?";
301
+ }
302
+ function tabBadge(tab) {
303
+ const count = tab.badge;
304
+ return typeof count === "number" && count > 0 ? count : 0;
305
+ }
306
+ function onDrawerKeydown(event) {
307
+ if (event.key !== "Escape") return;
308
+ event.preventDefault();
309
+ event.stopPropagation();
310
+ __props.controller.close();
311
+ }
312
+ function onToggle() {
313
+ isExpanded.value = !isExpanded.value;
314
+ }
315
+ function onTileClick(tabId) {
316
+ if (tabId === SEARCH_TAB_ID) emit("search");
317
+ else if (drawerOpen.value && activeTabId.value === tabId) __props.controller.close();
318
+ else if (tabId === ACTIONS_TAB_ID) __props.controller.openActions();
319
+ else __props.controller.openSlot(tabId);
320
+ }
321
+ function onActionClick(label, action) {
322
+ if (action) emit("actionClick", label, action);
323
+ }
324
+ watch(drawerOpen, async (open) => {
325
+ if (open) {
326
+ lastFocusedBeforeDrawer.value = document.activeElement instanceof HTMLElement ? document.activeElement : null;
327
+ await nextTick();
328
+ drawerEl.value?.querySelector("button:not([disabled]), [href], input, select, textarea")?.focus();
329
+ return;
330
+ }
331
+ lastFocusedBeforeDrawer.value?.focus();
332
+ lastFocusedBeforeDrawer.value = null;
333
+ });
334
+ return (_ctx, _cache) => {
335
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["action-set", {
336
+ "action-set--expanded": isExpanded.value,
337
+ "action-set--drawer-open": drawerOpen.value
338
+ }]) }, [createElementVNode("div", _hoisted_1$2, [createElementVNode("button", {
339
+ type: "button",
340
+ class: normalizeClass(["action-set__toggle", { "action-set__toggle--expanded": isExpanded.value }]),
341
+ "aria-label": "Toggle menu",
342
+ "aria-expanded": isExpanded.value,
343
+ onClick: onToggle
344
+ }, " + ", 10, _hoisted_2$2), isExpanded.value ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(allTabs.value, (tab) => {
345
+ return openBlock(), createElementBlock("button", {
346
+ key: tab.id,
347
+ type: "button",
348
+ class: normalizeClass(["action-set__item", { "action-set__item--active": drawerOpen.value && activeTabId.value === tab.id }]),
349
+ "aria-label": tab.label,
350
+ "aria-current": drawerOpen.value && activeTabId.value === tab.id ? "page" : void 0,
351
+ title: tab.label,
352
+ onClick: ($event) => onTileClick(tab.id)
353
+ }, [tab.icon ? (openBlock(), createBlock(resolveDynamicComponent(tab.icon), {
354
+ key: 0,
355
+ class: "action-set__item-icon"
356
+ })) : (openBlock(), createElementBlock("span", _hoisted_4$2, toDisplayString(slotFallback(tab.label)), 1)), tabBadge(tab) > 0 ? (openBlock(), createElementBlock("span", _hoisted_5$2, toDisplayString(tabBadge(tab)), 1)) : createCommentVNode("", true)], 10, _hoisted_3$2);
357
+ }), 128)) : createCommentVNode("", true)]), drawerOpen.value ? (openBlock(), createElementBlock("aside", {
358
+ key: 0,
359
+ ref_key: "drawerEl",
360
+ ref: drawerEl,
361
+ class: "action-set__drawer",
362
+ "aria-label": "Side panel",
363
+ onKeydown: onDrawerKeydown
364
+ }, [createElementVNode("header", _hoisted_6$1, [createElementVNode("button", {
365
+ type: "button",
366
+ class: "action-set__drawer-close",
367
+ "aria-label": "Close panel",
368
+ onClick: _cache[0] || (_cache[0] = ($event) => __props.controller.close())
369
+ }, " × ")]), createElementVNode("div", _hoisted_7, [activeTabId.value === ACTIONS_TAB_ID ? (openBlock(), createElementBlock("div", _hoisted_8, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.elements, (el) => {
370
+ return openBlock(), createElementBlock(Fragment, { key: el.label }, [el.type === "dropdown" ? (openBlock(), createElementBlock("div", {
371
+ key: 0,
372
+ class: "action-set__actions-group",
373
+ role: "group",
374
+ "aria-label": el.label
375
+ }, [createElementVNode("p", _hoisted_10, toDisplayString(el.label), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(el.actions, (item) => {
376
+ return openBlock(), createElementBlock(Fragment, { key: item.label }, [item.action ? (openBlock(), createElementBlock("button", {
377
+ key: 0,
378
+ type: "button",
379
+ class: "action-set__actions-list-item action-set__actions-list-item--nested",
380
+ onClick: ($event) => onActionClick(item.label, item.action)
381
+ }, toDisplayString(item.label), 9, _hoisted_11)) : item.link ? (openBlock(), createElementBlock("a", {
382
+ key: 1,
383
+ href: item.link,
384
+ class: "action-set__actions-list-item action-set__actions-list-item--nested"
385
+ }, toDisplayString(item.label), 9, _hoisted_12)) : createCommentVNode("", true)], 64);
386
+ }), 128))], 8, _hoisted_9)) : !el.action && el.link ? (openBlock(), createElementBlock("a", {
387
+ key: 1,
388
+ href: el.link,
389
+ class: "action-set__actions-list-item"
390
+ }, toDisplayString(el.label), 9, _hoisted_13)) : (openBlock(), createElementBlock("button", {
391
+ key: 2,
392
+ type: "button",
393
+ class: "action-set__actions-list-item",
394
+ disabled: el.disabled,
395
+ onClick: ($event) => onActionClick(el.label, el.action)
396
+ }, toDisplayString(el.label), 9, _hoisted_14))], 64);
397
+ }), 128)), __props.elements.length === 0 ? (openBlock(), createElementBlock("p", _hoisted_15, "No actions available")) : createCommentVNode("", true)])) : activeSlot.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [activeSlot.value.component ? (openBlock(), createBlock(resolveDynamicComponent(activeSlot.value.component), { key: activeSlot.value.id })) : (openBlock(), createElementBlock("p", _hoisted_16, "No content"))], 64)) : createCommentVNode("", true)])], 544)) : createCommentVNode("", true)], 2);
398
+ };
399
+ }
400
+ });
401
+ //#endregion
402
+ //#region \0plugin-vue:export-helper
403
+ var _plugin_vue_export_helper_default = (sfc, props) => {
404
+ const target = sfc.__vccOpts || sfc;
405
+ for (const [key, val] of props) target[key] = val;
406
+ return target;
407
+ };
408
+ //#endregion
409
+ //#region src/components/ActionSet.vue
410
+ var ActionSet_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ActionSet_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-40295597"]]);
411
+ //#endregion
198
412
  //#region src/sheet-nav-toolbar.ts
199
413
  /** The id of the element SheetNav renders for footer controls, left of its tabs. */
200
414
  var SHEET_NAV_TOOLBAR_ID = "sheetnav-toolbar";
201
- /** Teleport target for footer controls rendered anywhere on the page: `<Teleport :to="SHEET_NAV_TOOLBAR_SELECTOR">`. */
415
+ /**
416
+ * Teleport target for footer controls rendered anywhere on the page: `<Teleport :to="SHEET_NAV_TOOLBAR_SELECTOR">`.
417
+ * @public
418
+ */
202
419
  var SHEET_NAV_TOOLBAR_SELECTOR = `#${SHEET_NAV_TOOLBAR_ID}`;
203
420
  //#endregion
204
421
  //#region src/components/SheetNav.vue?vue&type=script&setup=true&lang.ts
205
422
  var _hoisted_1$1 = { class: "sheetnav-footer-cluster" };
206
423
  var _hoisted_2$1 = ["id"];
207
- var _hoisted_3 = { class: "tabs" };
208
- var _hoisted_4 = { tabindex: "0" };
209
- var _hoisted_5 = { tabindex: "0" };
424
+ var _hoisted_3$1 = { class: "tabs" };
425
+ var _hoisted_4$1 = { tabindex: "0" };
426
+ var _hoisted_5$1 = { tabindex: "0" };
210
427
  //#endregion
211
428
  //#region src/components/SheetNav.vue
212
429
  var SheetNav_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -247,12 +464,12 @@ var SheetNav_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
247
464
  return openBlock(), createElementBlock("footer", null, [createElementVNode("div", _hoisted_1$1, [createElementVNode("div", {
248
465
  id: unref(SHEET_NAV_TOOLBAR_ID),
249
466
  class: "sheetnav-toolbar"
250
- }, [renderSlot(_ctx.$slots, "toolbar", {}, void 0, true)], 8, _hoisted_2$1), createElementVNode("ul", _hoisted_3, [
467
+ }, [renderSlot(_ctx.$slots, "toolbar", {}, void 0, true)], 8, _hoisted_2$1), createElementVNode("ul", _hoisted_3$1, [
251
468
  createElementVNode("li", {
252
469
  class: "hidebreadcrumbs",
253
470
  onClick: toggleBreadcrumbs,
254
471
  onKeydown: withKeys(toggleBreadcrumbs, ["enter"])
255
- }, [createElementVNode("a", _hoisted_4, [createElementVNode("div", { class: normalizeClass(rotateHideTabIcon.value) }, "×", 2)])], 32),
472
+ }, [createElementVNode("a", _hoisted_4$1, [createElementVNode("div", { class: normalizeClass(rotateHideTabIcon.value) }, "×", 2)])], 32),
256
473
  createElementVNode("li", {
257
474
  class: "hometab",
258
475
  style: normalizeStyle({ display: breadcrumbsVisibile.value ? "flex" : "none" }),
@@ -275,7 +492,7 @@ var SheetNav_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
275
492
  createElementVNode("li", {
276
493
  class: normalizeClass(["searchtab", { "search-active": searchVisible.value }]),
277
494
  style: normalizeStyle({ display: breadcrumbsVisibile.value ? "flex" : "none" })
278
- }, [createElementVNode("a", _hoisted_5, [withDirectives((openBlock(), createElementBlock("svg", {
495
+ }, [createElementVNode("a", _hoisted_5$1, [withDirectives((openBlock(), createElementBlock("svg", {
279
496
  class: "icon search-icon",
280
497
  role: "button",
281
498
  "aria-label": "Search",
@@ -316,22 +533,88 @@ var SheetNav_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
316
533
  }
317
534
  }), [["__scopeId", "data-v-7c905747"]]);
318
535
  //#endregion
536
+ //#region src/composables/useActionSet.ts
537
+ var actionSetKey = Symbol("actionSet");
538
+ function createActionSet(options) {
539
+ const activeSlotId = ref(null);
540
+ const actionsOpen = ref(false);
541
+ const previewSubject = shallowRef(null);
542
+ const previewId = ref(void 0);
543
+ function openActions() {
544
+ activeSlotId.value = null;
545
+ closePreview();
546
+ actionsOpen.value = true;
547
+ }
548
+ function openSlot(slotId) {
549
+ actionsOpen.value = false;
550
+ if (activeSlotId.value === slotId) return;
551
+ activeSlotId.value = slotId;
552
+ closePreview();
553
+ }
554
+ function present(subject) {
555
+ if (subject.id !== void 0 && subject.id === previewId.value) return;
556
+ previewId.value = subject.id;
557
+ previewSubject.value = {
558
+ ...subject,
559
+ view: markRaw(subject.view)
560
+ };
561
+ }
562
+ function closePreview() {
563
+ previewSubject.value = null;
564
+ previewId.value = void 0;
565
+ }
566
+ function close() {
567
+ activeSlotId.value = null;
568
+ actionsOpen.value = false;
569
+ closePreview();
570
+ }
571
+ return {
572
+ doctype: options.doctype,
573
+ recordId: options.recordId,
574
+ activeSlotId: computed(() => activeSlotId.value),
575
+ previewSubject: computed(() => previewSubject.value),
576
+ isPreviewOpen: computed(() => previewSubject.value !== null),
577
+ isActionsOpen: computed(() => actionsOpen.value),
578
+ isDrawerOpen: computed(() => actionsOpen.value || activeSlotId.value !== null),
579
+ present,
580
+ closePreview,
581
+ close,
582
+ openActions,
583
+ openSlot
584
+ };
585
+ }
586
+ /** @public */
587
+ function useActionSet() {
588
+ const actionSet = inject(actionSetKey, null);
589
+ if (!actionSet) throw new Error("useActionSet() must be called inside a component rendered by Desktop");
590
+ return actionSet;
591
+ }
592
+ //#endregion
319
593
  //#region src/components/Desktop.vue?vue&type=script&setup=true&lang.ts
320
- var _hoisted_1 = {
321
- key: 1,
594
+ var _hoisted_1 = { class: "desktop__workspace" };
595
+ var _hoisted_2 = { class: "desktop__main" };
596
+ var _hoisted_3 = {
597
+ key: 2,
322
598
  class: "loading"
323
599
  };
324
- var _hoisted_2 = {
325
- key: 2,
600
+ var _hoisted_4 = {
601
+ key: 3,
326
602
  class: "loading"
327
603
  };
604
+ var _hoisted_5 = {
605
+ key: 0,
606
+ class: "desktop__preview"
607
+ };
608
+ var _hoisted_6 = { class: "desktop__preview-body" };
328
609
  //#endregion
329
610
  //#region src/components/Desktop.vue
330
- var Desktop_default = /* @__PURE__ */ defineComponent({
611
+ var Desktop_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
331
612
  __name: "Desktop",
332
613
  props: {
333
614
  availableDoctypes: { default: () => [] },
334
- routeAdapter: {}
615
+ routeAdapter: {},
616
+ actionSetSlots: {},
617
+ hostActions: {}
335
618
  },
336
619
  emits: [
337
620
  "action",
@@ -521,6 +804,7 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
521
804
  }
522
805
  };
523
806
  const actionElements = computed(() => {
807
+ if (__props.hostActions) return __props.hostActions;
524
808
  const elements = [];
525
809
  switch (currentView.value) {
526
810
  case "records":
@@ -887,8 +1171,36 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
887
1171
  event.preventDefault();
888
1172
  commandPaletteOpen.value = true;
889
1173
  }
890
- if (event.key === "Escape" && commandPaletteOpen.value) commandPaletteOpen.value = false;
1174
+ if (event.key === "Escape") {
1175
+ if (commandPaletteOpen.value) {
1176
+ commandPaletteOpen.value = false;
1177
+ return;
1178
+ }
1179
+ if (actionSetController.isPreviewOpen.value) {
1180
+ actionSetController.closePreview();
1181
+ return;
1182
+ }
1183
+ if (actionSetController.isDrawerOpen.value) actionSetController.close();
1184
+ }
891
1185
  };
1186
+ const visibleActionSetSlots = computed(() => (__props.actionSetSlots ?? []).filter((slot) => slot.show !== false).map((slot) => Object.assign({}, slot, {
1187
+ icon: slot.icon ? markRaw(slot.icon) : void 0,
1188
+ component: slot.component ? markRaw(slot.component) : void 0
1189
+ })));
1190
+ const actionSetController = createActionSet({
1191
+ doctype: currentDoctype,
1192
+ recordId: currentRecordId
1193
+ });
1194
+ provide(actionSetKey, actionSetController);
1195
+ const actionSetDrawerOpen = computed(() => actionSetController.isDrawerOpen.value);
1196
+ const actionSetPreviewOpen = computed(() => actionSetController.isPreviewOpen.value);
1197
+ const actionSetPreviewSubject = computed(() => actionSetController.previewSubject.value);
1198
+ watch([currentDoctype, currentRecordId], () => {
1199
+ actionSetController.close();
1200
+ });
1201
+ function closeActionSetPreview() {
1202
+ actionSetController.closePreview();
1203
+ }
892
1204
  onMounted(() => {
893
1205
  document.addEventListener("keydown", handleKeydown);
894
1206
  });
@@ -897,15 +1209,14 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
897
1209
  });
898
1210
  return (_ctx, _cache) => {
899
1211
  return openBlock(), createElementBlock("div", {
900
- class: "desktop",
1212
+ class: normalizeClass(["desktop", {
1213
+ "desktop--action-set-open": actionSetDrawerOpen.value,
1214
+ "desktop--preview-open": actionSetPreviewOpen.value
1215
+ }]),
901
1216
  onClick: handleClick
902
1217
  }, [
903
- createVNode(ActionSet_default, {
904
- elements: actionElements.value,
905
- onActionClick: handleActionClick
906
- }, null, 8, ["elements"]),
907
- currentViewSchema.value.length > 0 ? (openBlock(), createBlock(unref(AForm), {
908
- key: 0,
1218
+ createElementVNode("div", _hoisted_1, [createElementVNode("div", _hoisted_2, [_ctx.$slots.default ? renderSlot(_ctx.$slots, "default", {}, void 0, true, 0) : currentViewSchema.value.length > 0 ? (openBlock(), createBlock(unref(AForm), {
1219
+ key: 1,
909
1220
  data: currentViewData.value,
910
1221
  "onUpdate:data": _cache[0] || (_cache[0] = ($event) => currentViewData.value = $event),
911
1222
  schema: currentViewSchema.value,
@@ -914,9 +1225,28 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
914
1225
  "data",
915
1226
  "schema",
916
1227
  "errors"
917
- ])) : !unref(stonecrop) ? (openBlock(), createElementBlock("div", _hoisted_1, [..._cache[2] || (_cache[2] = [createElementVNode("p", null, "Initializing Stonecrop...", -1)])])) : (openBlock(), createElementBlock("div", _hoisted_2, [createElementVNode("p", null, "Loading " + toDisplayString(currentView.value) + " data...", 1)])),
918
- createVNode(SheetNav_default, { breadcrumbs: navigationBreadcrumbs.value }, {
919
- toolbar: withCtx(() => [renderSlot(_ctx.$slots, "sheetnav-toolbar")]),
1228
+ ])) : !unref(stonecrop) ? (openBlock(), createElementBlock("div", _hoisted_3, [..._cache[3] || (_cache[3] = [createElementVNode("p", null, "Initializing Stonecrop...", -1)])])) : (openBlock(), createElementBlock("div", _hoisted_4, [createElementVNode("p", null, "Loading " + toDisplayString(currentView.value) + " data...", 1)]))]), actionSetPreviewSubject.value ? (openBlock(), createElementBlock("aside", _hoisted_5, [createElementVNode("header", { class: "desktop__preview-header" }, [createElementVNode("button", {
1229
+ type: "button",
1230
+ class: "desktop__preview-close",
1231
+ "aria-label": "Close preview",
1232
+ onClick: closeActionSetPreview
1233
+ }, " × ")]), createElementVNode("div", _hoisted_6, [(openBlock(), createBlock(resolveDynamicComponent(actionSetPreviewSubject.value.view), normalizeProps(guardReactiveProps(actionSetPreviewSubject.value.props ?? {})), null, 16))])])) : createCommentVNode("", true)]),
1234
+ createVNode(ActionSet_default, {
1235
+ slots: visibleActionSetSlots.value,
1236
+ elements: actionElements.value,
1237
+ controller: unref(actionSetController),
1238
+ onActionClick: handleActionClick,
1239
+ onSearch: _cache[1] || (_cache[1] = ($event) => commandPaletteOpen.value = true)
1240
+ }, null, 8, [
1241
+ "slots",
1242
+ "elements",
1243
+ "controller"
1244
+ ]),
1245
+ createVNode(SheetNav_default, {
1246
+ class: "desktop__sheetnav",
1247
+ breadcrumbs: navigationBreadcrumbs.value
1248
+ }, {
1249
+ toolbar: withCtx(() => [renderSlot(_ctx.$slots, "sheetnav-toolbar", {}, void 0, true)]),
920
1250
  _: 3
921
1251
  }, 8, ["breadcrumbs"]),
922
1252
  createVNode(CommandPalette_default, {
@@ -924,16 +1254,16 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
924
1254
  search: searchCommands,
925
1255
  placeholder: "Type a command or search...",
926
1256
  onSelect: executeCommand,
927
- onClose: _cache[1] || (_cache[1] = ($event) => commandPaletteOpen.value = false)
1257
+ onClose: _cache[2] || (_cache[2] = ($event) => commandPaletteOpen.value = false)
928
1258
  }, {
929
1259
  title: withCtx(({ result }) => [createTextVNode(toDisplayString(result.title), 1)]),
930
1260
  content: withCtx(({ result }) => [createTextVNode(toDisplayString(result.description), 1)]),
931
1261
  _: 1
932
1262
  }, 8, ["is-open"])
933
- ]);
1263
+ ], 2);
934
1264
  };
935
1265
  }
936
- });
1266
+ }), [["__scopeId", "data-v-378bae6b"]]);
937
1267
  //#endregion
938
1268
  //#region src/plugins/index.ts
939
1269
  /**
@@ -941,12 +1271,11 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
941
1271
  * @public
942
1272
  */
943
1273
  var plugin = { install: (app) => {
944
- app.component("ActionSet", ActionSet_default);
945
1274
  app.component("CommandPalette", CommandPalette_default);
946
1275
  app.component("Desktop", Desktop_default);
947
1276
  app.component("SheetNav", SheetNav_default);
948
1277
  } };
949
1278
  //#endregion
950
- export { ActionSet_default as ActionSet, CommandPalette_default as CommandPalette, Desktop_default as Desktop, SHEET_NAV_TOOLBAR_SELECTOR, SheetNav_default as SheetNav, plugin as StonecropDesktop };
1279
+ export { ActionSetIconActions, ActionSetIconApprovals, ActionSetIconChat, ActionSetIconEmail, ActionSetIconFiles, ActionSetIconHelp, ActionSetIconPrint, ActionSetIconReports, ActionSetIconSearch, ActionSetIconSettings, CommandPalette_default as CommandPalette, Desktop_default as Desktop, SHEET_NAV_TOOLBAR_SELECTOR, SheetNav_default as SheetNav, plugin as StonecropDesktop, useActionSet };
951
1280
 
952
1281
  //# sourceMappingURL=desktop.js.map