@stonecrop/desktop 0.32.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$1 = { key: 0 };
9
- var _hoisted_5$1 = { 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$1, [createElementVNode("div", _hoisted_5$1, [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 = ["onClick", "onMouseover"];
104
- var _hoisted_5 = { 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,30 +89,350 @@ 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, [renderSlot(_ctx.$slots, "title", { result })]), createElementVNode("div", _hoisted_6, [renderSlot(_ctx.$slots, "content", { result })])], 42, _hoisted_4);
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
412
+ //#region src/sheet-nav-toolbar.ts
413
+ /** The id of the element SheetNav renders for footer controls, left of its tabs. */
414
+ var SHEET_NAV_TOOLBAR_ID = "sheetnav-toolbar";
415
+ /**
416
+ * Teleport target for footer controls rendered anywhere on the page: `<Teleport :to="SHEET_NAV_TOOLBAR_SELECTOR">`.
417
+ * @public
418
+ */
419
+ var SHEET_NAV_TOOLBAR_SELECTOR = `#${SHEET_NAV_TOOLBAR_ID}`;
420
+ //#endregion
198
421
  //#region src/components/SheetNav.vue?vue&type=script&setup=true&lang.ts
199
- var _hoisted_1$1 = { class: "tabs" };
200
- var _hoisted_2$1 = { tabindex: "0" };
201
- var _hoisted_3 = { tabindex: "0" };
422
+ var _hoisted_1$1 = { class: "sheetnav-footer-cluster" };
423
+ var _hoisted_2$1 = ["id"];
424
+ var _hoisted_3$1 = { class: "tabs" };
425
+ var _hoisted_4$1 = { tabindex: "0" };
426
+ var _hoisted_5$1 = { tabindex: "0" };
202
427
  //#endregion
203
428
  //#region src/components/SheetNav.vue
204
429
  var SheetNav_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
205
430
  __name: "SheetNav",
206
431
  props: { breadcrumbs: { default: () => [] } },
207
432
  setup(__props) {
433
+ onMounted(() => {
434
+ if (document.querySelectorAll(SHEET_NAV_TOOLBAR_SELECTOR).length > 1) console.warn(`More than one SheetNav is mounted: content teleported to ${SHEET_NAV_TOOLBAR_SELECTOR} lands in the first one only.`);
435
+ });
208
436
  const breadcrumbsVisibile = ref(true);
209
437
  const searchVisible = ref(false);
210
438
  const searchText = ref("");
@@ -233,15 +461,18 @@ var SheetNav_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
233
461
  const navigateHome = () => {};
234
462
  return (_ctx, _cache) => {
235
463
  const _component_router_link = resolveComponent("router-link");
236
- return openBlock(), createElementBlock("footer", null, [createElementVNode("ul", _hoisted_1$1, [
464
+ return openBlock(), createElementBlock("footer", null, [createElementVNode("div", _hoisted_1$1, [createElementVNode("div", {
465
+ id: unref(SHEET_NAV_TOOLBAR_ID),
466
+ class: "sheetnav-toolbar"
467
+ }, [renderSlot(_ctx.$slots, "toolbar", {}, void 0, true)], 8, _hoisted_2$1), createElementVNode("ul", _hoisted_3$1, [
237
468
  createElementVNode("li", {
238
469
  class: "hidebreadcrumbs",
239
470
  onClick: toggleBreadcrumbs,
240
471
  onKeydown: withKeys(toggleBreadcrumbs, ["enter"])
241
- }, [createElementVNode("a", _hoisted_2$1, [createElementVNode("div", { class: normalizeClass(rotateHideTabIcon.value) }, "×", 2)])], 32),
472
+ }, [createElementVNode("a", _hoisted_4$1, [createElementVNode("div", { class: normalizeClass(rotateHideTabIcon.value) }, "×", 2)])], 32),
242
473
  createElementVNode("li", {
243
474
  class: "hometab",
244
- style: normalizeStyle({ display: breadcrumbsVisibile.value ? "block" : "none" }),
475
+ style: normalizeStyle({ display: breadcrumbsVisibile.value ? "flex" : "none" }),
245
476
  onClick: navigateHome,
246
477
  onKeydown: withKeys(navigateHome, ["enter"])
247
478
  }, [createVNode(_component_router_link, {
@@ -260,8 +491,8 @@ var SheetNav_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
260
491
  })], 36),
261
492
  createElementVNode("li", {
262
493
  class: normalizeClass(["searchtab", { "search-active": searchVisible.value }]),
263
- style: normalizeStyle({ display: breadcrumbsVisibile.value ? "block" : "none" })
264
- }, [createElementVNode("a", _hoisted_3, [withDirectives((openBlock(), createElementBlock("svg", {
494
+ style: normalizeStyle({ display: breadcrumbsVisibile.value ? "flex" : "none" })
495
+ }, [createElementVNode("a", _hoisted_5$1, [withDirectives((openBlock(), createElementBlock("svg", {
265
496
  class: "icon search-icon",
266
497
  role: "button",
267
498
  "aria-label": "Search",
@@ -288,7 +519,7 @@ var SheetNav_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
288
519
  (openBlock(true), createElementBlock(Fragment, null, renderList(__props.breadcrumbs, (breadcrumb) => {
289
520
  return openBlock(), createElementBlock("li", {
290
521
  key: breadcrumb.title,
291
- style: normalizeStyle({ display: breadcrumbsVisibile.value ? "block" : "none" })
522
+ style: normalizeStyle({ display: breadcrumbsVisibile.value ? "flex" : "none" })
292
523
  }, [createVNode(_component_router_link, {
293
524
  tabindex: "0",
294
525
  to: breadcrumb.to
@@ -297,27 +528,93 @@ var SheetNav_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
297
528
  _: 2
298
529
  }, 1032, ["to"])], 4);
299
530
  }), 128))
300
- ])]);
531
+ ])])]);
532
+ };
533
+ }
534
+ }), [["__scopeId", "data-v-7c905747"]]);
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)
301
560
  };
302
561
  }
303
- }), [["__scopeId", "data-v-cd118b06"]]);
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
+ }
304
592
  //#endregion
305
593
  //#region src/components/Desktop.vue?vue&type=script&setup=true&lang.ts
306
- var _hoisted_1 = {
307
- key: 1,
594
+ var _hoisted_1 = { class: "desktop__workspace" };
595
+ var _hoisted_2 = { class: "desktop__main" };
596
+ var _hoisted_3 = {
597
+ key: 2,
308
598
  class: "loading"
309
599
  };
310
- var _hoisted_2 = {
311
- key: 2,
600
+ var _hoisted_4 = {
601
+ key: 3,
312
602
  class: "loading"
313
603
  };
604
+ var _hoisted_5 = {
605
+ key: 0,
606
+ class: "desktop__preview"
607
+ };
608
+ var _hoisted_6 = { class: "desktop__preview-body" };
314
609
  //#endregion
315
610
  //#region src/components/Desktop.vue
316
- var Desktop_default = /* @__PURE__ */ defineComponent({
611
+ var Desktop_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
317
612
  __name: "Desktop",
318
613
  props: {
319
614
  availableDoctypes: { default: () => [] },
320
- routeAdapter: {}
615
+ routeAdapter: {},
616
+ actionSetSlots: {},
617
+ hostActions: {}
321
618
  },
322
619
  emits: [
323
620
  "action",
@@ -507,6 +804,7 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
507
804
  }
508
805
  };
509
806
  const actionElements = computed(() => {
807
+ if (__props.hostActions) return __props.hostActions;
510
808
  const elements = [];
511
809
  switch (currentView.value) {
512
810
  case "records":
@@ -873,8 +1171,36 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
873
1171
  event.preventDefault();
874
1172
  commandPaletteOpen.value = true;
875
1173
  }
876
- 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
+ }
877
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
+ }
878
1204
  onMounted(() => {
879
1205
  document.addEventListener("keydown", handleKeydown);
880
1206
  });
@@ -883,15 +1209,14 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
883
1209
  });
884
1210
  return (_ctx, _cache) => {
885
1211
  return openBlock(), createElementBlock("div", {
886
- class: "desktop",
1212
+ class: normalizeClass(["desktop", {
1213
+ "desktop--action-set-open": actionSetDrawerOpen.value,
1214
+ "desktop--preview-open": actionSetPreviewOpen.value
1215
+ }]),
887
1216
  onClick: handleClick
888
1217
  }, [
889
- createVNode(ActionSet_default, {
890
- elements: actionElements.value,
891
- onActionClick: handleActionClick
892
- }, null, 8, ["elements"]),
893
- currentViewSchema.value.length > 0 ? (openBlock(), createBlock(unref(AForm), {
894
- 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,
895
1220
  data: currentViewData.value,
896
1221
  "onUpdate:data": _cache[0] || (_cache[0] = ($event) => currentViewData.value = $event),
897
1222
  schema: currentViewSchema.value,
@@ -900,23 +1225,45 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
900
1225
  "data",
901
1226
  "schema",
902
1227
  "errors"
903
- ])) : !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)])),
904
- createVNode(SheetNav_default, { breadcrumbs: navigationBreadcrumbs.value }, null, 8, ["breadcrumbs"]),
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)]),
1250
+ _: 3
1251
+ }, 8, ["breadcrumbs"]),
905
1252
  createVNode(CommandPalette_default, {
906
1253
  "is-open": commandPaletteOpen.value,
907
1254
  search: searchCommands,
908
1255
  placeholder: "Type a command or search...",
909
1256
  onSelect: executeCommand,
910
- onClose: _cache[1] || (_cache[1] = ($event) => commandPaletteOpen.value = false)
1257
+ onClose: _cache[2] || (_cache[2] = ($event) => commandPaletteOpen.value = false)
911
1258
  }, {
912
1259
  title: withCtx(({ result }) => [createTextVNode(toDisplayString(result.title), 1)]),
913
1260
  content: withCtx(({ result }) => [createTextVNode(toDisplayString(result.description), 1)]),
914
1261
  _: 1
915
1262
  }, 8, ["is-open"])
916
- ]);
1263
+ ], 2);
917
1264
  };
918
1265
  }
919
- });
1266
+ }), [["__scopeId", "data-v-378bae6b"]]);
920
1267
  //#endregion
921
1268
  //#region src/plugins/index.ts
922
1269
  /**
@@ -924,12 +1271,11 @@ var Desktop_default = /* @__PURE__ */ defineComponent({
924
1271
  * @public
925
1272
  */
926
1273
  var plugin = { install: (app) => {
927
- app.component("ActionSet", ActionSet_default);
928
1274
  app.component("CommandPalette", CommandPalette_default);
929
1275
  app.component("Desktop", Desktop_default);
930
1276
  app.component("SheetNav", SheetNav_default);
931
1277
  } };
932
1278
  //#endregion
933
- export { ActionSet_default as ActionSet, CommandPalette_default as CommandPalette, Desktop_default as Desktop, 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 };
934
1280
 
935
1281
  //# sourceMappingURL=desktop.js.map