camox 0.13.0 → 0.14.1
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/core/createApp.d.ts +4 -0
- package/dist/core/createBlock.d.ts +32 -5
- package/dist/core/createBlock.js +144 -84
- package/dist/core/lib/contentType.d.ts +46 -10
- package/dist/core/lib/contentType.js +56 -3
- package/dist/features/preview/components/AddBlockSheet.js +8 -5
- package/dist/features/preview/components/AgentChatSheet.js +1 -1
- package/dist/features/preview/components/PageContentSheet.js +91 -3
- package/dist/features/preview/components/PageTree.js +42 -23
- package/dist/features/preview/components/RepeatableItemsList.js +11 -1
- package/dist/lib/queries.js +1 -0
- package/dist/studio-overlays.css +40 -15
- package/dist/studio.css +1 -1
- package/package.json +4 -4
- package/skills/camox-block/SKILL.md +41 -11
|
@@ -57,6 +57,26 @@ const getSchemaForItem = (contentSchema, itemId, itemsMap) => {
|
|
|
57
57
|
return schema;
|
|
58
58
|
};
|
|
59
59
|
/**
|
|
60
|
+
* Like `getSchemaForItem` but returns the **array** schema (one level above
|
|
61
|
+
* the items schema), where per-item settings metadata lives.
|
|
62
|
+
*/
|
|
63
|
+
const getArraySchemaForItem = (contentSchema, itemId, itemsMap) => {
|
|
64
|
+
const path = [];
|
|
65
|
+
let current = itemsMap.get(itemId);
|
|
66
|
+
while (current) {
|
|
67
|
+
path.unshift(current.fieldName);
|
|
68
|
+
current = current.parentItemId ? itemsMap.get(current.parentItemId) : void 0;
|
|
69
|
+
}
|
|
70
|
+
let schema = contentSchema;
|
|
71
|
+
for (let i = 0; i < path.length; i++) {
|
|
72
|
+
const prop = schema?.properties?.[path[i]];
|
|
73
|
+
if (!prop?.items) return null;
|
|
74
|
+
if (i === path.length - 1) return prop;
|
|
75
|
+
schema = prop.items;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
60
80
|
* Builds the ancestor chain from root to this item (inclusive).
|
|
61
81
|
* Returns items in order from root-most ancestor to the item itself.
|
|
62
82
|
*/
|
|
@@ -74,6 +94,7 @@ const PageContentSheet = () => {
|
|
|
74
94
|
const updateContent = useMutation(blockMutations.updateContent());
|
|
75
95
|
const updateSettings = useMutation(blockMutations.updateSettings());
|
|
76
96
|
const updateRepeatableContent = useMutation(repeatableItemMutations.updateContent());
|
|
97
|
+
const updateRepeatableSettings = useMutation(repeatableItemMutations.updateSettings());
|
|
77
98
|
const isOpen = useSelector(previewStore, (state) => state.context.isPageContentSheetOpen);
|
|
78
99
|
const selection = useSelector(previewStore, (state_0) => state_0.context.selection);
|
|
79
100
|
const iframeElement = useSelector(previewStore, (state_1) => state_1.context.iframeElement);
|
|
@@ -109,6 +130,17 @@ const PageContentSheet = () => {
|
|
|
109
130
|
const settingsFields = React.useMemo(() => {
|
|
110
131
|
return blockDef ? getSettingsFields(blockDef._internal.settingsSchema) : [];
|
|
111
132
|
}, [blockDef]);
|
|
133
|
+
const itemArraySchema = React.useMemo(() => {
|
|
134
|
+
if (!blockDef || currentItemId == null) return null;
|
|
135
|
+
return getArraySchemaForItem(blockDef._internal.contentSchema, currentItemId, itemsMap);
|
|
136
|
+
}, [
|
|
137
|
+
blockDef,
|
|
138
|
+
currentItemId,
|
|
139
|
+
itemsMap
|
|
140
|
+
]);
|
|
141
|
+
const itemSettingsFields = React.useMemo(() => {
|
|
142
|
+
return getSettingsFields(itemArraySchema?.itemSettingsSchema);
|
|
143
|
+
}, [itemArraySchema]);
|
|
112
144
|
const currentSchema = React.useMemo(() => {
|
|
113
145
|
if (!blockDef) return null;
|
|
114
146
|
if (currentItemId == null) return blockDef._internal.contentSchema;
|
|
@@ -379,6 +411,62 @@ const PageContentSheet = () => {
|
|
|
379
411
|
return null;
|
|
380
412
|
})]
|
|
381
413
|
}),
|
|
414
|
+
currentItemId != null && !fieldHasOwnView && itemSettingsFields.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
415
|
+
className: "border-border space-y-4 border-b px-4 py-4",
|
|
416
|
+
children: [/* @__PURE__ */ jsx(Label, {
|
|
417
|
+
className: "text-muted-foreground",
|
|
418
|
+
children: "Settings"
|
|
419
|
+
}), itemSettingsFields.map((field_0) => {
|
|
420
|
+
const label_0 = field_0.label ?? formatFieldName(field_0.name);
|
|
421
|
+
const itemSettingsValues = currentItem?.settings ?? {};
|
|
422
|
+
const itemSettingsSchemaProps = itemArraySchema?.itemSettingsSchema?.properties;
|
|
423
|
+
if (field_0.fieldType === "Enum") {
|
|
424
|
+
const value_4 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? "";
|
|
425
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
426
|
+
className: "space-y-2",
|
|
427
|
+
children: [/* @__PURE__ */ jsx(Label, {
|
|
428
|
+
htmlFor: `item-setting-${field_0.name}`,
|
|
429
|
+
children: label_0
|
|
430
|
+
}), /* @__PURE__ */ jsxs(Select, {
|
|
431
|
+
value: value_4,
|
|
432
|
+
onValueChange: (newValue_1) => {
|
|
433
|
+
updateRepeatableSettings.mutate({
|
|
434
|
+
id: currentItemId,
|
|
435
|
+
settings: { [field_0.name]: newValue_1 }
|
|
436
|
+
});
|
|
437
|
+
},
|
|
438
|
+
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
439
|
+
id: `item-setting-${field_0.name}`,
|
|
440
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
441
|
+
}), /* @__PURE__ */ jsx(SelectContent, { children: field_0.enumValues?.map((enumValue_0) => /* @__PURE__ */ jsx(SelectItem, {
|
|
442
|
+
value: enumValue_0,
|
|
443
|
+
children: field_0.enumLabels?.[enumValue_0] ?? enumValue_0
|
|
444
|
+
}, enumValue_0)) })]
|
|
445
|
+
})]
|
|
446
|
+
}, field_0.name);
|
|
447
|
+
}
|
|
448
|
+
if (field_0.fieldType === "Boolean") {
|
|
449
|
+
const checked_0 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? false;
|
|
450
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
451
|
+
className: "flex items-center justify-between",
|
|
452
|
+
children: [/* @__PURE__ */ jsx(Label, {
|
|
453
|
+
htmlFor: `item-setting-${field_0.name}`,
|
|
454
|
+
children: label_0
|
|
455
|
+
}), /* @__PURE__ */ jsx(Switch, {
|
|
456
|
+
id: `item-setting-${field_0.name}`,
|
|
457
|
+
checked: checked_0,
|
|
458
|
+
onCheckedChange: (newValue_2) => {
|
|
459
|
+
updateRepeatableSettings.mutate({
|
|
460
|
+
id: currentItemId,
|
|
461
|
+
settings: { [field_0.name]: newValue_2 }
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
})]
|
|
465
|
+
}, field_0.name);
|
|
466
|
+
}
|
|
467
|
+
return null;
|
|
468
|
+
})]
|
|
469
|
+
}),
|
|
382
470
|
isViewingAsset && assetFieldName && isMultipleAsset && /* @__PURE__ */ jsx(MultipleAssetFieldEditor, {
|
|
383
471
|
fieldName: assetFieldName,
|
|
384
472
|
assetType,
|
|
@@ -401,12 +489,12 @@ const PageContentSheet = () => {
|
|
|
401
489
|
href: "",
|
|
402
490
|
newTab: false
|
|
403
491
|
},
|
|
404
|
-
onSave: (fieldName_1,
|
|
405
|
-
activeFieldChangeHandler(fieldName_1,
|
|
492
|
+
onSave: (fieldName_1, value_5) => {
|
|
493
|
+
activeFieldChangeHandler(fieldName_1, value_5);
|
|
406
494
|
}
|
|
407
495
|
})
|
|
408
496
|
}),
|
|
409
|
-
!isViewingAsset && !isViewingLink && /* @__PURE__ */ jsx(ItemFieldsEditor, {
|
|
497
|
+
!isViewingAsset && !isViewingLink && (currentItemId == null || currentItem) && /* @__PURE__ */ jsx(ItemFieldsEditor, {
|
|
410
498
|
schema: currentSchema,
|
|
411
499
|
data: currentData,
|
|
412
500
|
blockId: block.id,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { previewStore } from "../previewStore.js";
|
|
2
|
+
import { blockQueries } from "../../../lib/queries.js";
|
|
2
3
|
import { cn } from "../../../lib/utils.js";
|
|
3
4
|
import { usePageBlocks } from "../../../lib/normalized-data.js";
|
|
4
5
|
import { useCamoxApp } from "../../provider/components/CamoxAppContext.js";
|
|
@@ -7,6 +8,7 @@ import { useUpdateBlockPosition } from "./useUpdateBlockPosition.js";
|
|
|
7
8
|
import { BlockActionsPopover } from "./BlockActionsPopover.js";
|
|
8
9
|
import { usePreviewedPage } from "../CamoxPreview.js";
|
|
9
10
|
import { c } from "react/compiler-runtime";
|
|
11
|
+
import { useQuery } from "@tanstack/react-query";
|
|
10
12
|
import { useSelector } from "@xstate/store/react";
|
|
11
13
|
import * as React from "react";
|
|
12
14
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -137,12 +139,26 @@ const FieldItem = (t0) => {
|
|
|
137
139
|
return t9;
|
|
138
140
|
};
|
|
139
141
|
const BlockFields = (t0) => {
|
|
140
|
-
const $ = c(
|
|
142
|
+
const $ = c(4);
|
|
141
143
|
const { block } = t0;
|
|
142
144
|
const schemaProperties = useCamoxApp().getBlockById(block.type)?._internal.contentSchema.properties;
|
|
143
145
|
const selection = useSelector(previewStore, _temp3);
|
|
144
146
|
const iframeElement = useSelector(previewStore, _temp4);
|
|
145
|
-
|
|
147
|
+
let t1;
|
|
148
|
+
if ($[0] !== block.id) {
|
|
149
|
+
t1 = blockQueries.get(block.id);
|
|
150
|
+
$[0] = block.id;
|
|
151
|
+
$[1] = t1;
|
|
152
|
+
} else t1 = $[1];
|
|
153
|
+
const { data: blockBundle } = useQuery(t1);
|
|
154
|
+
let selectedFieldName = null;
|
|
155
|
+
if (selection?.type === "block-field" && selection.blockId === block.id) selectedFieldName = selection.fieldName;
|
|
156
|
+
else if ((selection?.type === "item" || selection?.type === "item-field") && selection.blockId === block.id && blockBundle) {
|
|
157
|
+
const itemsById = new Map(blockBundle.repeatableItems.map(_temp5));
|
|
158
|
+
let current = itemsById.get(selection.itemId);
|
|
159
|
+
while (current?.parentItemId != null) current = itemsById.get(current.parentItemId);
|
|
160
|
+
selectedFieldName = current?.fieldName ?? null;
|
|
161
|
+
}
|
|
146
162
|
const handleFieldClick = (fieldName, fieldType) => {
|
|
147
163
|
previewStore.send({
|
|
148
164
|
type: "selectBlockField",
|
|
@@ -191,8 +207,8 @@ const BlockFields = (t0) => {
|
|
|
191
207
|
iframeElement.contentWindow.postMessage(message_2, "*");
|
|
192
208
|
}
|
|
193
209
|
};
|
|
194
|
-
const
|
|
195
|
-
const
|
|
210
|
+
const t2 = "my-1 space-y-1 pl-7";
|
|
211
|
+
const t3 = Object.keys(schemaProperties ?? {}).map((fieldName_3) => {
|
|
196
212
|
const value = block.content[fieldName_3];
|
|
197
213
|
const fieldSchema = schemaProperties?.[fieldName_3];
|
|
198
214
|
if (!fieldSchema) return null;
|
|
@@ -211,23 +227,23 @@ const BlockFields = (t0) => {
|
|
|
211
227
|
onMouseLeave: () => handleFieldMouseLeave(fieldName_3, isRepeatable_1)
|
|
212
228
|
}, fieldName_3);
|
|
213
229
|
});
|
|
214
|
-
let
|
|
215
|
-
if ($[
|
|
216
|
-
|
|
217
|
-
className:
|
|
218
|
-
children:
|
|
230
|
+
let t4;
|
|
231
|
+
if ($[2] !== t3) {
|
|
232
|
+
t4 = /* @__PURE__ */ jsx("ul", {
|
|
233
|
+
className: t2,
|
|
234
|
+
children: t3
|
|
219
235
|
});
|
|
220
|
-
$[
|
|
221
|
-
$[
|
|
222
|
-
} else
|
|
223
|
-
return
|
|
236
|
+
$[2] = t3;
|
|
237
|
+
$[3] = t4;
|
|
238
|
+
} else t4 = $[3];
|
|
239
|
+
return t4;
|
|
224
240
|
};
|
|
225
241
|
function useBlockTreeItem(block, t0) {
|
|
226
242
|
const $ = c(16);
|
|
227
243
|
const isDragging = t0 === void 0 ? false : t0;
|
|
228
244
|
const [ellipsisPopoverOpen, setEllipsisPopoverOpen] = React.useState(false);
|
|
229
|
-
const selection = useSelector(previewStore,
|
|
230
|
-
const iframeElement = useSelector(previewStore,
|
|
245
|
+
const selection = useSelector(previewStore, _temp6);
|
|
246
|
+
const iframeElement = useSelector(previewStore, _temp7);
|
|
231
247
|
const isBlockSelected = selection?.type === "block" && selection.blockId === block.id;
|
|
232
248
|
const shouldShowHover = !isDragging && !isBlockSelected;
|
|
233
249
|
const shouldShowActive = isDragging || isBlockSelected;
|
|
@@ -296,10 +312,10 @@ function useBlockTreeItem(block, t0) {
|
|
|
296
312
|
} else t4 = $[15];
|
|
297
313
|
return t4;
|
|
298
314
|
}
|
|
299
|
-
function
|
|
315
|
+
function _temp7(state_0) {
|
|
300
316
|
return state_0.context.iframeElement;
|
|
301
317
|
}
|
|
302
|
-
function
|
|
318
|
+
function _temp6(state) {
|
|
303
319
|
return state.context.selection;
|
|
304
320
|
}
|
|
305
321
|
const BlockTreeItemHeader = (t0) => {
|
|
@@ -891,13 +907,13 @@ const PageTree = () => {
|
|
|
891
907
|
} else t7 = $[16];
|
|
892
908
|
let t8;
|
|
893
909
|
if ($[17] !== pageBlocks) {
|
|
894
|
-
t8 = pageBlocks.map(
|
|
910
|
+
t8 = pageBlocks.map(_temp8);
|
|
895
911
|
$[17] = pageBlocks;
|
|
896
912
|
$[18] = t8;
|
|
897
913
|
} else t8 = $[18];
|
|
898
914
|
let t9;
|
|
899
915
|
if ($[19] !== pageBlocks) {
|
|
900
|
-
t9 = pageBlocks.map(
|
|
916
|
+
t9 = pageBlocks.map(_temp9);
|
|
901
917
|
$[19] = pageBlocks;
|
|
902
918
|
$[20] = t9;
|
|
903
919
|
} else t9 = $[20];
|
|
@@ -993,7 +1009,7 @@ const PageTree = () => {
|
|
|
993
1009
|
if ($[43] === Symbol.for("react.memo_cache_sentinel")) {
|
|
994
1010
|
t16 = /* @__PURE__ */ jsxs(Button, {
|
|
995
1011
|
variant: "secondary",
|
|
996
|
-
onClick:
|
|
1012
|
+
onClick: _temp0,
|
|
997
1013
|
children: [/* @__PURE__ */ jsx(Plus, {}), "Add block"]
|
|
998
1014
|
});
|
|
999
1015
|
$[43] = t16;
|
|
@@ -1012,13 +1028,16 @@ function _temp3(state) {
|
|
|
1012
1028
|
function _temp4(state_0) {
|
|
1013
1029
|
return state_0.context.iframeElement;
|
|
1014
1030
|
}
|
|
1015
|
-
function
|
|
1031
|
+
function _temp5(i) {
|
|
1032
|
+
return [i.id, i];
|
|
1033
|
+
}
|
|
1034
|
+
function _temp8(block_2) {
|
|
1016
1035
|
return String(block_2.id);
|
|
1017
1036
|
}
|
|
1018
|
-
function
|
|
1037
|
+
function _temp9(block_3) {
|
|
1019
1038
|
return /* @__PURE__ */ jsx(SortableBlock, { block: block_3 }, String(block_3.id));
|
|
1020
1039
|
}
|
|
1021
|
-
function
|
|
1040
|
+
function _temp0() {
|
|
1022
1041
|
return previewStore.send({ type: "openAddBlockSheet" });
|
|
1023
1042
|
}
|
|
1024
1043
|
|
|
@@ -214,6 +214,7 @@ const RepeatableItemsList = ({ items, blockId, fieldName, minItems, maxItems, sc
|
|
|
214
214
|
if (prop.type === "array" && prop.items?.properties) continue;
|
|
215
215
|
if ("default" in prop) defaultContent[key] = prop.default;
|
|
216
216
|
}
|
|
217
|
+
const defaultSettings = schema?.defaultItemSettings;
|
|
217
218
|
const nestedItems = [];
|
|
218
219
|
if (itemsSchema?.properties) {
|
|
219
220
|
let seedCounter = 0;
|
|
@@ -230,6 +231,7 @@ const RepeatableItemsList = ({ items, blockId, fieldName, minItems, maxItems, sc
|
|
|
230
231
|
if (ps.type === "array" && ps.items?.properties) continue;
|
|
231
232
|
if ("default" in ps) nestedContent[propName] = ps.default;
|
|
232
233
|
}
|
|
234
|
+
const nestedSettingsDefaults = fs.defaultItemSettings;
|
|
233
235
|
let prevPos = null;
|
|
234
236
|
for (let i = 0; i < defaultCount; i++) {
|
|
235
237
|
const tempId = `nested_${++seedCounter}`;
|
|
@@ -240,6 +242,7 @@ const RepeatableItemsList = ({ items, blockId, fieldName, minItems, maxItems, sc
|
|
|
240
242
|
parentTempId,
|
|
241
243
|
fieldName: nestedFieldName,
|
|
242
244
|
content: { ...nestedContent },
|
|
245
|
+
settings: nestedSettingsDefaults ? { ...nestedSettingsDefaults } : void 0,
|
|
243
246
|
position
|
|
244
247
|
});
|
|
245
248
|
buildNestedSeeds(nestedItemProps, tempId);
|
|
@@ -252,8 +255,15 @@ const RepeatableItemsList = ({ items, blockId, fieldName, minItems, maxItems, sc
|
|
|
252
255
|
blockId,
|
|
253
256
|
fieldName,
|
|
254
257
|
content: defaultContent,
|
|
258
|
+
settings: defaultSettings ? { ...defaultSettings } : void 0,
|
|
255
259
|
nestedItems: nestedItems.length > 0 ? nestedItems : void 0
|
|
256
|
-
})
|
|
260
|
+
}, { onSuccess: (created) => {
|
|
261
|
+
previewStore.send({
|
|
262
|
+
type: "selectItem",
|
|
263
|
+
blockId,
|
|
264
|
+
itemId: created.id
|
|
265
|
+
});
|
|
266
|
+
} });
|
|
257
267
|
};
|
|
258
268
|
const handleRemoveItem = (itemId) => {
|
|
259
269
|
deleteRepeatableItem.mutate({ id: itemId });
|
package/dist/lib/queries.js
CHANGED
|
@@ -105,6 +105,7 @@ const repeatableItemMutations = {
|
|
|
105
105
|
delete: () => getOrpc().repeatableItems.delete.mutationOptions(),
|
|
106
106
|
duplicate: () => getOrpc().repeatableItems.duplicate.mutationOptions(),
|
|
107
107
|
updateContent: () => getOrpc().repeatableItems.updateContent.mutationOptions(),
|
|
108
|
+
updateSettings: () => getOrpc().repeatableItems.updateSettings.mutationOptions(),
|
|
108
109
|
updatePosition: () => getOrpc().repeatableItems.updatePosition.mutationOptions()
|
|
109
110
|
};
|
|
110
111
|
const pageMutations = {
|
package/dist/studio-overlays.css
CHANGED
|
@@ -25,17 +25,19 @@
|
|
|
25
25
|
--camox-overlay-inset-block-selected: 0px;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
/* Position context for field
|
|
28
|
+
/* Position context for typed-field, repeater, and detached overlays.
|
|
29
29
|
BlockComponent already has position: relative inline.
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
Inline string fields don't use ::after (see box-shadow rules below) so they
|
|
31
|
+
don't need position: relative — adding it to inline elements wouldn't help
|
|
32
|
+
since inline-relative containing blocks collapse to the start fragment. */
|
|
33
|
+
[data-camox-field-id][data-camox-field-type],
|
|
32
34
|
[data-camox-repeater-item-id] {
|
|
33
35
|
position: relative;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
/* ---- Hovered state ---- */
|
|
37
39
|
|
|
38
|
-
[data-camox-field-id][data-camox-hovered]::after,
|
|
40
|
+
[data-camox-field-id][data-camox-field-type][data-camox-hovered]::after,
|
|
39
41
|
[data-camox-block-id][data-camox-hovered]:not([data-camox-detached])::after,
|
|
40
42
|
[data-camox-repeater-item-id][data-camox-hovered]::after {
|
|
41
43
|
content: "";
|
|
@@ -46,14 +48,9 @@
|
|
|
46
48
|
border: var(--camox-overlay-width-hover) solid var(--camox-overlay-color-hover);
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
/* Field-level elements use field-specific inset */
|
|
50
|
-
[data-camox-field-id][data-camox-hovered]:not([data-camox-field-type])::after {
|
|
51
|
-
inset: var(--camox-overlay-inset-field-hover);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
51
|
/* ---- Focused state (overrides hovered via source order) ---- */
|
|
55
52
|
|
|
56
|
-
[data-camox-field-id][data-camox-focused]::after,
|
|
53
|
+
[data-camox-field-id][data-camox-field-type][data-camox-focused]::after,
|
|
57
54
|
[data-camox-block-id][data-camox-focused]:not([data-camox-detached])::after {
|
|
58
55
|
content: "";
|
|
59
56
|
position: absolute;
|
|
@@ -63,14 +60,28 @@
|
|
|
63
60
|
border: var(--camox-overlay-width-selected) solid var(--camox-overlay-color-selected);
|
|
64
61
|
}
|
|
65
62
|
|
|
66
|
-
/*
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
/* ---- Inline string fields ----
|
|
64
|
+
Use box-shadow + box-decoration-break: clone so the outline repeats per line
|
|
65
|
+
fragment when the inline wraps. Applied directly to the element via attribute
|
|
66
|
+
selectors with !important so user-supplied className/style box-shadows can't
|
|
67
|
+
clobber it. */
|
|
68
|
+
[data-camox-field-id]:not([data-camox-field-type])[data-camox-hovered],
|
|
69
|
+
[data-camox-field-id]:not([data-camox-field-type])[data-camox-focused] {
|
|
70
|
+
-webkit-box-decoration-break: clone;
|
|
71
|
+
box-decoration-break: clone;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
[data-camox-field-id]:not([data-camox-field-type])[data-camox-hovered] {
|
|
75
|
+
box-shadow: 0 0 0 var(--camox-overlay-width-hover) var(--camox-overlay-color-hover) !important;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
[data-camox-field-id]:not([data-camox-field-type])[data-camox-focused] {
|
|
79
|
+
box-shadow: 0 0 0 var(--camox-overlay-width-selected) var(--camox-overlay-color-selected) !important;
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
/* ---- Layout mode color overrides ---- */
|
|
72
83
|
|
|
73
|
-
[data-camox-field-id][data-camox-overlay-mode="layout"][data-camox-hovered]::after,
|
|
84
|
+
[data-camox-field-id][data-camox-field-type][data-camox-overlay-mode="layout"][data-camox-hovered]::after,
|
|
74
85
|
[data-camox-block-id][data-camox-overlay-mode="layout"][data-camox-hovered]:not(
|
|
75
86
|
[data-camox-detached]
|
|
76
87
|
)::after,
|
|
@@ -78,13 +89,27 @@
|
|
|
78
89
|
border-color: var(--camox-overlay-layout-color-hover);
|
|
79
90
|
}
|
|
80
91
|
|
|
81
|
-
[data-camox-field-id][data-camox-overlay-mode="layout"][data-camox-focused]::after,
|
|
92
|
+
[data-camox-field-id][data-camox-field-type][data-camox-overlay-mode="layout"][data-camox-focused]::after,
|
|
82
93
|
[data-camox-block-id][data-camox-overlay-mode="layout"][data-camox-focused]:not(
|
|
83
94
|
[data-camox-detached]
|
|
84
95
|
)::after {
|
|
85
96
|
border-color: var(--camox-overlay-layout-color-selected);
|
|
86
97
|
}
|
|
87
98
|
|
|
99
|
+
[data-camox-field-id]:not(
|
|
100
|
+
[data-camox-field-type]
|
|
101
|
+
)[data-camox-overlay-mode="layout"][data-camox-hovered] {
|
|
102
|
+
box-shadow: 0 0 0 var(--camox-overlay-width-hover) var(--camox-overlay-layout-color-hover) !important;
|
|
103
|
+
border-radius: 0 !important;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
[data-camox-field-id]:not(
|
|
107
|
+
[data-camox-field-type]
|
|
108
|
+
)[data-camox-overlay-mode="layout"][data-camox-focused] {
|
|
109
|
+
box-shadow: 0 0 0 var(--camox-overlay-width-selected) var(--camox-overlay-layout-color-selected) !important;
|
|
110
|
+
border-radius: 0 !important;
|
|
111
|
+
}
|
|
112
|
+
|
|
88
113
|
/* ---- Embed: z-index above click-interceptor ---- */
|
|
89
114
|
|
|
90
115
|
[data-camox-field-type="embed"][data-camox-hovered]::after,
|