@nascentdigital/funnel-editor 4.5.0 → 4.5.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/components/interaction/QuickPicker.d.ts +8 -4
- package/dist/core/components/interaction/QuickPicker.js +30 -17
- package/dist/core/domain/BlockConfiguration.d.ts +3 -1
- package/dist/core/domain/BlockConfiguration.js +29 -25
- package/dist/page/components/config/BlockConfigEditor.js +21 -5
- package/dist/page/components/config/BlockPreview.d.ts +3 -1
- package/dist/page/components/config/BlockPreview.js +445 -2
- package/dist/styles/index.css +24 -6
- package/package.json +2 -2
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { RequiredBy } from '@nascentdigital/funnel-core';
|
|
1
|
+
import { RequiredBy, Transform } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
2
3
|
import { Popup } from './Popup';
|
|
3
|
-
export declare const QuickPicker: import("react").ForwardRefExoticComponent<QuickPicker.Props & import("react").RefAttributes<QuickPicker.Ref<string, QuickPicker.Item<string>>>>;
|
|
4
|
+
export declare const QuickPicker: import("react").ForwardRefExoticComponent<QuickPicker.Props<string, QuickPicker.Item<string>> & import("react").RefAttributes<QuickPicker.Ref<string, QuickPicker.Item<string>>>>;
|
|
4
5
|
export declare namespace QuickPicker {
|
|
5
|
-
type Item<TId extends string
|
|
6
|
+
type Item<TId extends string> = {
|
|
6
7
|
id: TId;
|
|
7
8
|
};
|
|
8
|
-
type
|
|
9
|
+
type ItemVariant = 'card';
|
|
10
|
+
type Props<TId extends string, TItem extends Item<TId>> = {
|
|
11
|
+
variant: ItemVariant;
|
|
9
12
|
title: string;
|
|
10
13
|
description?: string;
|
|
14
|
+
renderItem: Transform<TItem, ReactNode>;
|
|
11
15
|
};
|
|
12
16
|
interface Ref<TId extends string, TItem extends Item<TId>> {
|
|
13
17
|
readonly isOpen: boolean;
|
|
@@ -21,7 +21,7 @@ const classnames_1 = __importDefault(require("classnames"));
|
|
|
21
21
|
const react_1 = require("react");
|
|
22
22
|
const Popup_1 = require("./Popup");
|
|
23
23
|
// component
|
|
24
|
-
exports.QuickPicker = (0, react_1.forwardRef)(function QuickPicker({ title, description }, ref) {
|
|
24
|
+
exports.QuickPicker = (0, react_1.forwardRef)(function QuickPicker({ variant, title, description, renderItem }, ref) {
|
|
25
25
|
// bind state
|
|
26
26
|
const [opened, setOpened] = (0, react_1.useState)(false);
|
|
27
27
|
const [deferral, setDeferral] = (0, react_1.useState)();
|
|
@@ -38,6 +38,7 @@ exports.QuickPicker = (0, react_1.forwardRef)(function QuickPicker({ title, desc
|
|
|
38
38
|
},
|
|
39
39
|
open: async (_a) => {
|
|
40
40
|
var { items, selectedItem } = _a, popupProps = __rest(_a, ["items", "selectedItem"]);
|
|
41
|
+
console.debug('[QuickPicker] opening with', { items, selectedItem });
|
|
41
42
|
// reset
|
|
42
43
|
setItems(items);
|
|
43
44
|
setSelectedItem(selectedItem);
|
|
@@ -55,19 +56,11 @@ exports.QuickPicker = (0, react_1.forwardRef)(function QuickPicker({ title, desc
|
|
|
55
56
|
close: () => { var _a; return (_a = deferralRef.current) === null || _a === void 0 ? void 0 : _a.resolve(undefined); }
|
|
56
57
|
}), []);
|
|
57
58
|
// helpers
|
|
58
|
-
const onPick = (
|
|
59
|
-
// stop propagation
|
|
60
|
-
e.preventDefault();
|
|
61
|
-
e.stopPropagation();
|
|
59
|
+
const onPick = (item) => {
|
|
62
60
|
// resolve
|
|
63
|
-
deferral === null || deferral === void 0 ? void 0 : deferral.resolve(
|
|
61
|
+
deferral === null || deferral === void 0 ? void 0 : deferral.resolve(item);
|
|
64
62
|
};
|
|
65
|
-
const onClose = (
|
|
66
|
-
// stop propagation
|
|
67
|
-
if (e) {
|
|
68
|
-
e.preventDefault();
|
|
69
|
-
e.stopPropagation();
|
|
70
|
-
}
|
|
63
|
+
const onClose = () => {
|
|
71
64
|
// ignore if already complete
|
|
72
65
|
if (deferral === null || deferral === void 0 ? void 0 : deferral.isComplete) {
|
|
73
66
|
return;
|
|
@@ -79,17 +72,37 @@ exports.QuickPicker = (0, react_1.forwardRef)(function QuickPicker({ title, desc
|
|
|
79
72
|
// handle keys
|
|
80
73
|
switch (e.key) {
|
|
81
74
|
case 'Enter':
|
|
82
|
-
|
|
75
|
+
// stop propagation
|
|
76
|
+
e.preventDefault();
|
|
77
|
+
e.stopPropagation();
|
|
78
|
+
// pick
|
|
79
|
+
onPick(selectedItem);
|
|
83
80
|
break;
|
|
84
81
|
case 'Escape':
|
|
85
|
-
|
|
82
|
+
// stop propagation
|
|
83
|
+
e.preventDefault();
|
|
84
|
+
e.stopPropagation();
|
|
85
|
+
// close
|
|
86
|
+
onClose();
|
|
86
87
|
break;
|
|
87
88
|
}
|
|
88
89
|
};
|
|
89
90
|
// render
|
|
90
|
-
return ((0, jsx_runtime_1.jsxs)(Popup_1.Popup, Object.assign({}, (popupProps !== null && popupProps !== void 0 ? popupProps : {}), { className: (0, classnames_1.default)('glass-overlay w-[
|
|
91
|
+
return ((0, jsx_runtime_1.jsxs)(Popup_1.Popup, Object.assign({}, (popupProps !== null && popupProps !== void 0 ? popupProps : {}), { className: (0, classnames_1.default)('glass-overlay w-[420px] max-w-full flex flex-col gap-l8 pt-l8 interpolate', 'border-t border-solid border-glass-stroke-l1 rounded-md', {
|
|
91
92
|
'opacity-none': !opened,
|
|
92
93
|
'opacity-full': opened
|
|
93
|
-
}), animation: "out", open: !!deferral, onOpened: () => setOpened(true), onClose: onClose, onClosed: () => setOpened(false), children: [(0, jsx_runtime_1.jsxs)("section", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "heading-sm text-content-primary", children: title }), description &&
|
|
94
|
-
(0, jsx_runtime_1.jsx)("p", { className: "body-sm text-content-secondary", children: description })] }), (0, jsx_runtime_1.jsx)("section", {
|
|
94
|
+
}), animation: "out", open: !!deferral, onOpened: () => setOpened(true), onClose: onClose, onClosed: () => setOpened(false), children: [(0, jsx_runtime_1.jsxs)("section", { className: "px-l8", children: [(0, jsx_runtime_1.jsx)("h3", { className: "heading-sm text-content-primary", children: title }), description &&
|
|
95
|
+
(0, jsx_runtime_1.jsx)("p", { className: "body-sm text-content-secondary", children: description })] }), (0, jsx_runtime_1.jsx)("section", { className: (0, classnames_1.default)({
|
|
96
|
+
'flex flex-wrap items-center gap-l5 max-h-[240px] px-l8 pb-l8 overflow-y-scroll': variant === 'card'
|
|
97
|
+
}), children: items.map(item => renderCard({
|
|
98
|
+
item,
|
|
99
|
+
content: renderItem(item),
|
|
100
|
+
selected: item.id === selectedItem,
|
|
101
|
+
onSelect: itemId => onPick(itemId)
|
|
102
|
+
})) })] })));
|
|
95
103
|
});
|
|
104
|
+
function renderCard({ item, content, selected, onSelect }) {
|
|
105
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('FieldCard w-[116px] h-[88px]', {
|
|
106
|
+
'FieldCard-selected': selected
|
|
107
|
+
}), onClick: () => onSelect(item.id), children: content }, item.id));
|
|
108
|
+
}
|
|
@@ -16,8 +16,10 @@ export declare class BlockConfiguration {
|
|
|
16
16
|
constructor({ block: blockOrSectionBlock, assetStore }: BlockConfiguration.ConstructorArgs);
|
|
17
17
|
get editableFields(): ReadonlyArray<FieldModel.Config>;
|
|
18
18
|
set editableFields(fields: ReadonlyArray<FieldModel.Config>);
|
|
19
|
+
get blocksFields(): FieldModel.Config[];
|
|
20
|
+
get blockFieldData(): Schema.Block.Data.ForFields<Schema.Fields>;
|
|
19
21
|
get desktopFields(): FieldModel.Config[];
|
|
20
|
-
get mobileFields():
|
|
22
|
+
get mobileFields(): never[];
|
|
21
23
|
get nameField(): FieldModel.Config | undefined;
|
|
22
24
|
get themeField(): FieldModel.Config | undefined;
|
|
23
25
|
get layoutField(): Field<Schema.EnumField<Schema.EnumField.Options<PanelLayout>>> | undefined;
|
|
@@ -47,19 +47,41 @@ class BlockConfiguration {
|
|
|
47
47
|
this._editableFields = fields;
|
|
48
48
|
this.raiseEvent('changed');
|
|
49
49
|
}
|
|
50
|
-
get
|
|
50
|
+
get blocksFields() {
|
|
51
51
|
return [
|
|
52
52
|
this.nameField,
|
|
53
|
-
this.themeField
|
|
54
|
-
this._editableFields.find(field => field.id === 'contentAlign')
|
|
53
|
+
this.themeField
|
|
55
54
|
].filter(funnel_core_1.Value.isDefined);
|
|
56
55
|
}
|
|
57
|
-
get
|
|
56
|
+
get blockFieldData() {
|
|
57
|
+
const { assetStore, block } = this;
|
|
58
|
+
return block.fields.reduce((data, field) => {
|
|
59
|
+
// link assets
|
|
60
|
+
const fieldValue = field.value;
|
|
61
|
+
if ((fieldValue === null || fieldValue === void 0 ? void 0 : fieldValue.type) === 'asset') {
|
|
62
|
+
const assetData = funnel_core_1.Schema.AssetField.Value.fromData(fieldValue);
|
|
63
|
+
const asset = (assetData === null || assetData === void 0 ? void 0 : assetData.id)
|
|
64
|
+
? assetStore.getAsset(assetData === null || assetData === void 0 ? void 0 : assetData.id)
|
|
65
|
+
: undefined;
|
|
66
|
+
data[field.id] = assetData && asset
|
|
67
|
+
? funnel_core_1.Schema.AssetField.LinkedValue.toData(funnel_core_1.Schema.AssetField.Value.toLinked(assetData, asset))
|
|
68
|
+
: fieldValue;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
data[field.id] = field.value;
|
|
72
|
+
}
|
|
73
|
+
// keep reducing
|
|
74
|
+
return data;
|
|
75
|
+
}, {});
|
|
76
|
+
}
|
|
77
|
+
get desktopFields() {
|
|
58
78
|
return [
|
|
59
|
-
this.
|
|
60
|
-
this.themeField
|
|
79
|
+
this._editableFields.find(field => field.id === 'contentAlign')
|
|
61
80
|
].filter(funnel_core_1.Value.isDefined);
|
|
62
81
|
}
|
|
82
|
+
get mobileFields() {
|
|
83
|
+
return [].filter(funnel_core_1.Value.isDefined);
|
|
84
|
+
}
|
|
63
85
|
get nameField() {
|
|
64
86
|
const { block, sectionBlock } = this;
|
|
65
87
|
return sectionBlock
|
|
@@ -175,30 +197,12 @@ class BlockConfiguration {
|
|
|
175
197
|
}
|
|
176
198
|
sync() {
|
|
177
199
|
// recompute the editable fields
|
|
178
|
-
const {
|
|
200
|
+
const { block, blockFieldData: fieldData, fields, editableFields } = this;
|
|
179
201
|
const configData = editableFields.reduce((data, field) => {
|
|
180
202
|
data[field.id] = field.value;
|
|
181
203
|
// keep reducing
|
|
182
204
|
return data;
|
|
183
205
|
}, {});
|
|
184
|
-
const fieldData = block.fields.reduce((data, field) => {
|
|
185
|
-
// link assets
|
|
186
|
-
const fieldValue = field.value;
|
|
187
|
-
if ((fieldValue === null || fieldValue === void 0 ? void 0 : fieldValue.type) === 'asset') {
|
|
188
|
-
const assetData = funnel_core_1.Schema.AssetField.Value.fromData(fieldValue);
|
|
189
|
-
const asset = (assetData === null || assetData === void 0 ? void 0 : assetData.id)
|
|
190
|
-
? assetStore.getAsset(assetData === null || assetData === void 0 ? void 0 : assetData.id)
|
|
191
|
-
: undefined;
|
|
192
|
-
data[field.id] = assetData && asset
|
|
193
|
-
? funnel_core_1.Schema.AssetField.LinkedValue.toData(funnel_core_1.Schema.AssetField.Value.toLinked(assetData, asset))
|
|
194
|
-
: fieldValue;
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
data[field.id] = field.value;
|
|
198
|
-
}
|
|
199
|
-
// keep reducing
|
|
200
|
-
return data;
|
|
201
|
-
}, {});
|
|
202
206
|
// get customized schema (if there are effects)
|
|
203
207
|
const blockSchema = block.schema;
|
|
204
208
|
const { getConfig, getLayout } = blockSchema;
|
|
@@ -20,7 +20,8 @@ exports.BlockConfigEditor = (0, react_2.forwardRef)(function BlockConfigEditor(_
|
|
|
20
20
|
const pageController = (0, hooks_1.usePageController)();
|
|
21
21
|
const touch = (0, client_1.useTouch)();
|
|
22
22
|
const panelLayoutPickerRef = (0, react_2.useRef)(null);
|
|
23
|
-
const { modified = false, valid = false } = configuration !== null && configuration !== void 0 ? configuration : {};
|
|
23
|
+
const { modified = false, valid = false, blocksFields = [], desktopFields = [], mobileFields = [] } = configuration !== null && configuration !== void 0 ? configuration : {};
|
|
24
|
+
const settingsFields = blockView === 'desktop' ? desktopFields : mobileFields;
|
|
24
25
|
// sync w/ configuration
|
|
25
26
|
(0, core_1.useBlockConfiguration)(configuration);
|
|
26
27
|
// bind ref
|
|
@@ -65,7 +66,7 @@ exports.BlockConfigEditor = (0, react_2.forwardRef)(function BlockConfigEditor(_
|
|
|
65
66
|
if (!layoutField) {
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
68
|
-
// pick new layout
|
|
69
|
+
// pick new layout
|
|
69
70
|
const { schema: layoutSchema, value: layoutData } = layoutField;
|
|
70
71
|
const selectedLayout = await ((_a = panelLayoutPickerRef.current) === null || _a === void 0 ? void 0 : _a.open({
|
|
71
72
|
anchor: e.currentTarget,
|
|
@@ -77,8 +78,9 @@ exports.BlockConfigEditor = (0, react_2.forwardRef)(function BlockConfigEditor(_
|
|
|
77
78
|
})),
|
|
78
79
|
selectedItem: layoutData === null || layoutData === void 0 ? void 0 : layoutData.value
|
|
79
80
|
}));
|
|
80
|
-
if
|
|
81
|
-
|
|
81
|
+
// update if something was picked
|
|
82
|
+
if (selectedLayout) {
|
|
83
|
+
layoutField.value = funnel_core_1.Schema.EnumField.Value.toData(selectedLayout);
|
|
82
84
|
}
|
|
83
85
|
};
|
|
84
86
|
// skip if there's no config
|
|
@@ -86,8 +88,22 @@ exports.BlockConfigEditor = (0, react_2.forwardRef)(function BlockConfigEditor(_
|
|
|
86
88
|
return null;
|
|
87
89
|
}
|
|
88
90
|
// render
|
|
89
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(core_1.MiniEditor, { className: "w-[550px] max-w-full", title: "Block Configuration", open: !!deferral && !deferral.isComplete, anchor: anchor, anchorOffset: 4, onSave: onSave, onClose: onCancel, disableSave: !modified || !valid, customActions: (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "sm", disabled: configuration.isConfigInDefault, onClick: () => configuration.reset(), children: "Reset to Default" }), wide: true, children: [(0, jsx_runtime_1.jsxs)("section", { className: "flex items-center gap-l4", children: [(0, jsx_runtime_1.jsx)("span", { className: "label-sm text-content-primary flex-1", children: "Layout" }), (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "sm", iconLeft: "ArrowLeftRight", children: "Rearrange" }), (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "sm", iconLeft: "LayoutTemplate", onClick: onChangePanelLayout, children: "Change" })] }),
|
|
91
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(core_1.MiniEditor, { className: "w-[550px] max-w-full", title: "Block Configuration", open: !!deferral && !deferral.isComplete, anchor: anchor, anchorOffset: 4, onSave: onSave, onClose: onCancel, disableSave: !modified || !valid, customActions: (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "sm", disabled: configuration.isConfigInDefault, onClick: () => configuration.reset(), children: "Reset to Default" }), wide: true, children: [(0, jsx_runtime_1.jsxs)("section", { className: "flex items-center gap-l4", children: [(0, jsx_runtime_1.jsx)("span", { className: "label-sm text-content-primary flex-1", children: "Layout" }), (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "sm", iconLeft: "ArrowLeftRight", children: "Rearrange" }), (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "sm", iconLeft: "LayoutTemplate", onClick: onChangePanelLayout, children: "Change" })] }), blocksFields.length > 0 &&
|
|
92
|
+
(0, jsx_runtime_1.jsx)("section", { className: "grid grid-cols-2 auto-rows-auto items-start gap-l6", children: (0, jsx_runtime_1.jsx)(core_1.FieldErrorController, { children: blocksFields.map(field => (0, jsx_runtime_1.jsx)(core_1.FieldEditor, { className: "col-span-2", field: field, variant: "wide" }, field.id)) }) }), (0, jsx_runtime_1.jsx)(core_1.Tabs, { items: blockViews, selectedItem: blockView, onSelect: setBlockView }), (0, jsx_runtime_1.jsx)("section", { className: "stacked p-l6 bg-surface1 rounded-md", children: (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { children: (0, jsx_runtime_1.jsx)(core_1.Animate, { effect: "fade", present: true, children: (0, jsx_runtime_1.jsx)(BlockPreview_1.BlockPreview, { variant: blockView, configuration: configuration }) }, blockView) }) }), settingsFields.length > 0 &&
|
|
93
|
+
(0, jsx_runtime_1.jsx)("section", { className: "grid grid-cols-2 auto-rows-auto items-start gap-l6", children: (0, jsx_runtime_1.jsx)(core_1.FieldErrorController, { children: settingsFields.map(field => (0, jsx_runtime_1.jsx)(core_1.FieldEditor, { className: "col-span-2", field: field, variant: "wide" }, field.id)) }) }), (0, jsx_runtime_1.jsx)("hr", { className: "divider border-border-l1" })] }), (0, jsx_runtime_1.jsx)(core_1.QuickPicker, { ref: panelLayoutPickerRef, variant: "card", title: "Pick Block Layout", description: "Select an available layout for this block.", renderItem: (item) => renderPanelLayoutItem(item) })] }));
|
|
90
94
|
});
|
|
95
|
+
function renderPanelLayoutItem(item) {
|
|
96
|
+
switch (item.id) {
|
|
97
|
+
case 'stack.h':
|
|
98
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: "Stack H" }));
|
|
99
|
+
case 'stack.v':
|
|
100
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: "Stack V" }));
|
|
101
|
+
case 'nested':
|
|
102
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: "Nested" }));
|
|
103
|
+
default:
|
|
104
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: item.id }));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
91
107
|
const blockViews = [
|
|
92
108
|
{ id: 'desktop', label: 'Desktop' },
|
|
93
109
|
{ id: 'mobile', label: 'Mobile' },
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { BlockConfiguration } from '../../../core';
|
|
2
|
+
export declare function BlockPreview({ className, variant, configuration }: BlockPreview.Props): import("react/jsx-runtime").JSX.Element;
|
|
2
3
|
export declare namespace BlockPreview {
|
|
3
4
|
type Variant = 'desktop' | 'mobile';
|
|
4
5
|
type Props = {
|
|
5
6
|
className?: string;
|
|
6
7
|
variant: Variant;
|
|
8
|
+
configuration: BlockConfiguration;
|
|
7
9
|
};
|
|
8
10
|
}
|
|
@@ -1,13 +1,456 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
15
|
};
|
|
5
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
17
|
exports.BlockPreview = BlockPreview;
|
|
7
18
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
8
20
|
const classnames_1 = __importDefault(require("classnames"));
|
|
21
|
+
const react_1 = require("react");
|
|
22
|
+
const core_1 = require("../../../core");
|
|
9
23
|
// component
|
|
10
|
-
function BlockPreview({ className, variant }) {
|
|
24
|
+
function BlockPreview({ className, variant, configuration }) {
|
|
25
|
+
// determine active panels
|
|
26
|
+
const { layout } = configuration;
|
|
27
|
+
// sync configuration
|
|
28
|
+
(0, core_1.useBlockConfiguration)(configuration);
|
|
29
|
+
// helpers
|
|
30
|
+
const onPanelClick = (panel) => {
|
|
31
|
+
console.debug('[BlockPreview] opening panel editor', panel);
|
|
32
|
+
};
|
|
33
|
+
// render
|
|
34
|
+
const tight = variant === 'mobile'
|
|
35
|
+
? layout === null || layout === void 0 ? void 0 : layout.tight.mobile
|
|
36
|
+
: layout === null || layout === void 0 ? void 0 : layout.tight.desktop;
|
|
37
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'w-full flex justify-center'), children: (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('bg-surface2 rounded-xs', {
|
|
38
|
+
'min-h-[100px]': !layout,
|
|
39
|
+
'w-[120px]': variant === 'desktop',
|
|
40
|
+
'w-[64px]': variant === 'mobile',
|
|
41
|
+
'pb-l4': tight === 'above',
|
|
42
|
+
'pt-l4': tight === 'below',
|
|
43
|
+
'py-l4': tight === 'none'
|
|
44
|
+
}), children: renderLayout({ variant, layout, onPanelClick }) }) }));
|
|
45
|
+
}
|
|
46
|
+
// helpers
|
|
47
|
+
var Skeleton;
|
|
48
|
+
(function (Skeleton) {
|
|
49
|
+
function HeadlinePart({ className, size }) {
|
|
50
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'bg-ix-primary rounded-xxs overflow-hidden', {
|
|
51
|
+
'h-6 ': size === 'sm',
|
|
52
|
+
'h-8': size === 'md'
|
|
53
|
+
}) }));
|
|
54
|
+
}
|
|
55
|
+
Skeleton.HeadlinePart = HeadlinePart;
|
|
56
|
+
function CaptionPart({ className, size }) {
|
|
57
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'h-4 bg-draft/tint3 rounded-px overflow-hidden', {
|
|
58
|
+
'': size === 'sm'
|
|
59
|
+
}) }));
|
|
60
|
+
}
|
|
61
|
+
Skeleton.CaptionPart = CaptionPart;
|
|
62
|
+
function MediaPart({ className, aspect }) {
|
|
63
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'flex justify-center items-center bg-draft/tint3 rounded-xxs overflow-hidden', {
|
|
64
|
+
'aspect-square': aspect === 'square' || aspect === 'auto',
|
|
65
|
+
'aspect-phone': aspect === 'phone',
|
|
66
|
+
'aspect-tv': aspect === 'tv',
|
|
67
|
+
'aspect-widescreen': aspect === 'widescreen',
|
|
68
|
+
'aspect-cinema': aspect === 'cinema'
|
|
69
|
+
}), children: (0, jsx_runtime_1.jsx)(core_1.Icon, { className: "text-content-tertiary", variant: "Image", size: {
|
|
70
|
+
size: 20,
|
|
71
|
+
strokeWidth: 1.5,
|
|
72
|
+
absoluteStrokeWidth: false
|
|
73
|
+
} }) }));
|
|
74
|
+
}
|
|
75
|
+
Skeleton.MediaPart = MediaPart;
|
|
76
|
+
function IconPart({ className, size }) {
|
|
77
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'bg-draft/tint3 rounded-full overflow-hidden', {
|
|
78
|
+
'w-10 h-10': size === 'sm',
|
|
79
|
+
'w-14 h-14': size === 'md'
|
|
80
|
+
}) }));
|
|
81
|
+
}
|
|
82
|
+
Skeleton.IconPart = IconPart;
|
|
83
|
+
function LogoPart({ className, size }) {
|
|
84
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'bg-draft/tint3 rounded-px overflow-hidden', {
|
|
85
|
+
'w-14 h-6': size === 'sm',
|
|
86
|
+
'w-20 h-9': size === 'md'
|
|
87
|
+
}) }));
|
|
88
|
+
}
|
|
89
|
+
Skeleton.LogoPart = LogoPart;
|
|
90
|
+
})(Skeleton || (Skeleton = {}));
|
|
91
|
+
function renderLayout({ className, variant, layout, onPanelClick }) {
|
|
92
|
+
// TODO: render empty state if there's no layout
|
|
93
|
+
if (!layout) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
// render root layout
|
|
97
|
+
const { type, items } = layout.root;
|
|
98
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: getContainerClasses({ className, variant, siblingCount: 1, item: layout.root }), children: items.map((item, parentOffset) => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: renderItem({
|
|
99
|
+
className: (0, classnames_1.default)({
|
|
100
|
+
'flex-1': type === 'row' && variant !== 'mobile'
|
|
101
|
+
}),
|
|
102
|
+
variant,
|
|
103
|
+
parent: type,
|
|
104
|
+
parentNested: false,
|
|
105
|
+
siblingCount: items.length,
|
|
106
|
+
item,
|
|
107
|
+
itemPosition: new ItemPosition({
|
|
108
|
+
parent: type,
|
|
109
|
+
parentOffset,
|
|
110
|
+
parentSize: items.length
|
|
111
|
+
}),
|
|
112
|
+
onPanelClick
|
|
113
|
+
}) }, `${item.type}.${parentOffset}`)) }));
|
|
114
|
+
}
|
|
115
|
+
function renderItem({ className, parent, parentNested, siblingCount, variant, item, itemPosition, onPanelClick }) {
|
|
116
|
+
// render item
|
|
117
|
+
const { type: itemType } = item;
|
|
118
|
+
switch (itemType) {
|
|
119
|
+
case 'row':
|
|
120
|
+
case 'column':
|
|
121
|
+
case 'stack':
|
|
122
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: getContainerClasses({ className, parent, siblingCount, variant, item }), children: item.items.map((item, parentOffset, items) => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: renderItem({
|
|
123
|
+
className: (0, classnames_1.default)({
|
|
124
|
+
'flex-1': itemType === 'row'
|
|
125
|
+
}),
|
|
126
|
+
variant,
|
|
127
|
+
parent: itemType,
|
|
128
|
+
parentNested: true,
|
|
129
|
+
siblingCount: items.length,
|
|
130
|
+
item: item,
|
|
131
|
+
itemPosition: new ItemPosition({
|
|
132
|
+
parent: itemType,
|
|
133
|
+
parentOffset,
|
|
134
|
+
parentSize: items.length
|
|
135
|
+
}),
|
|
136
|
+
onPanelClick
|
|
137
|
+
}) }, `${item.type}.${parentOffset}`)) }));
|
|
138
|
+
case 'message':
|
|
139
|
+
return renderMessage({ className, parent, parentNested, siblingCount, variant, item, itemPosition, onPanelClick });
|
|
140
|
+
case 'visual':
|
|
141
|
+
return renderVisual({ className, parent, parentNested, siblingCount, variant, item, itemPosition, onPanelClick });
|
|
142
|
+
case 'list':
|
|
143
|
+
return renderList({ className, parent, parentNested, siblingCount, variant, item, itemPosition, onPanelClick });
|
|
144
|
+
default:
|
|
145
|
+
console.error('[SkeletonLayout] no support for BlockLayout item', item);
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function getContainerClasses({ className, variant, parent, item }) {
|
|
150
|
+
const { type, alignY } = item;
|
|
151
|
+
// row style
|
|
152
|
+
if (type === 'row' && variant !== 'mobile') {
|
|
153
|
+
return (0, classnames_1.default)(className, 'grid gap-l3 px-l4', {
|
|
154
|
+
'items-start': alignY === 'start',
|
|
155
|
+
'items-center': alignY === 'center',
|
|
156
|
+
'items-end': alignY === 'end',
|
|
157
|
+
'grid-cols-[1fr,1fr]': item.ratio.desktop === '1/1',
|
|
158
|
+
'grid-cols-[1fr,2fr]': item.ratio.desktop === '1/2',
|
|
159
|
+
'grid-cols-[1fr,3fr]': item.ratio.desktop === '1/3',
|
|
160
|
+
'grid-cols-[2fr,1fr]': item.ratio.desktop === '2/1',
|
|
161
|
+
'grid-cols-[2fr,3fr]': item.ratio.desktop === '2/3',
|
|
162
|
+
'grid-cols-[3fr,1fr]': item.ratio.desktop === '3/1',
|
|
163
|
+
'grid-cols-[3fr,2fr]': item.ratio.desktop === '3/2'
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
// or stack
|
|
167
|
+
else if (type === 'stack') {
|
|
168
|
+
return (0, classnames_1.default)(className, 'stacked-stretch');
|
|
169
|
+
}
|
|
170
|
+
// or column
|
|
171
|
+
else {
|
|
172
|
+
return (0, classnames_1.default)(className, 'flex flex-col gap-l4');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function renderMessage(args) {
|
|
176
|
+
// resolve props
|
|
177
|
+
const { variant, item: { textAlign } } = args;
|
|
178
|
+
const messageClasses = variant === 'mobile'
|
|
179
|
+
? (0, classnames_1.default)({
|
|
180
|
+
'items-start': textAlign.mobile === 'left',
|
|
181
|
+
'items-center': textAlign.mobile === 'center',
|
|
182
|
+
'items-end': textAlign.mobile === 'right'
|
|
183
|
+
})
|
|
184
|
+
: (0, classnames_1.default)({
|
|
185
|
+
'items-start': textAlign.desktop === 'left',
|
|
186
|
+
'items-center': textAlign.desktop === 'center',
|
|
187
|
+
'items-end': textAlign.desktop === 'right'
|
|
188
|
+
});
|
|
189
|
+
// render
|
|
190
|
+
return ((0, jsx_runtime_1.jsxs)(EditablePanel, Object.assign({}, args, { panelClassName: (0, classnames_1.default)(messageClasses, getPanelClasses(Object.assign(Object.assign({}, args), { className: 'flex flex-col' }))), children: [(0, jsx_runtime_1.jsx)(Skeleton.HeadlinePart, { className: "w-full mb-l2", size: "md" }), (0, jsx_runtime_1.jsx)(Skeleton.CaptionPart, { className: "w-full mb-px", size: "md" }), (0, jsx_runtime_1.jsx)(Skeleton.CaptionPart, { className: "w-full mb-px", size: "md" }), (0, jsx_runtime_1.jsx)(Skeleton.CaptionPart, { className: "w-20", size: "md" })] })));
|
|
191
|
+
}
|
|
192
|
+
function renderVisual(args) {
|
|
193
|
+
// resolve props
|
|
194
|
+
const { variant, item: { aspectRatio }, parent } = args;
|
|
195
|
+
const aspect = variant === 'mobile' ? aspectRatio.mobile : aspectRatio.desktop;
|
|
196
|
+
// render
|
|
197
|
+
return ((0, jsx_runtime_1.jsx)(EditablePanel, Object.assign({}, args, { panelClassName: (0, classnames_1.default)(getPanelClasses(Object.assign(Object.assign({}, args), { className: '' }))), children: (0, jsx_runtime_1.jsx)(Skeleton.MediaPart, { className: "w-full", aspect: aspect }) })));
|
|
198
|
+
}
|
|
199
|
+
function renderList(args) {
|
|
200
|
+
// resolve props
|
|
201
|
+
const { variant, parent, parentNested, item: { layout: layoutRaw, itemType, itemCount: itemCountRaw } } = args;
|
|
202
|
+
const layout = variant === 'mobile'
|
|
203
|
+
? layoutRaw.mobile
|
|
204
|
+
: layoutRaw.desktop;
|
|
205
|
+
// render a grid
|
|
206
|
+
if (layout === 'grid') {
|
|
207
|
+
return renderGrid(args);
|
|
208
|
+
}
|
|
209
|
+
// or render row/column
|
|
210
|
+
const itemCount = variant === 'mobile'
|
|
211
|
+
? itemCountRaw.mobile
|
|
212
|
+
: itemCountRaw.desktop;
|
|
213
|
+
return ((0, jsx_runtime_1.jsx)(EditablePanel, Object.assign({}, args, { panelClassName: getListPanelClasses(args), children: funnel_core_1.ArrayUtils.series(itemCount, 1).map(row => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: renderListItem({ variant, parent, parentNested, layout, itemType, index: row, count: itemCount }) }, `list.${row}`)) })));
|
|
214
|
+
}
|
|
215
|
+
function getListPanelClasses(args) {
|
|
216
|
+
// resolve props
|
|
217
|
+
const { variant, item: { layout: layoutRaw } } = args;
|
|
218
|
+
const layout = variant === 'mobile'
|
|
219
|
+
? layoutRaw.mobile
|
|
220
|
+
: layoutRaw.desktop;
|
|
221
|
+
// determine list classes
|
|
222
|
+
let listClasses = '';
|
|
223
|
+
switch (layout) {
|
|
224
|
+
case 'row':
|
|
225
|
+
listClasses = 'grid grid-rows-1 auto-cols-auto grid-flow-col gap-l2';
|
|
226
|
+
break;
|
|
227
|
+
case 'column':
|
|
228
|
+
listClasses = 'flex flex-col gap-l2';
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
// return completed classes
|
|
232
|
+
return getPanelClasses(Object.assign(Object.assign({}, args), { className: listClasses }));
|
|
233
|
+
}
|
|
234
|
+
function renderListItem({ className, variant, parent, parentNested, layout, itemType, index, count }) {
|
|
235
|
+
let itemClassName = '';
|
|
236
|
+
switch (itemType) {
|
|
237
|
+
case 'message':
|
|
238
|
+
case 'message+visual':
|
|
239
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(className, 'flex flex-row p-3 bg-background rounded-xxs'), children: [itemType === 'message+visual' &&
|
|
240
|
+
(0, jsx_runtime_1.jsx)("div", { className: "flex justify-center items-center", children: (0, jsx_runtime_1.jsx)("div", { className: "bg-content-tertiary rounded-full w-4 h-4" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 flex flex-col", children: [(0, jsx_runtime_1.jsx)(Skeleton.HeadlinePart, { className: "w-11/12 mb-l1", size: "sm" }), (0, jsx_runtime_1.jsx)(Skeleton.CaptionPart, { className: "w-full mb-px", size: "sm" }), (0, jsx_runtime_1.jsx)(Skeleton.CaptionPart, { className: "w-8/12", size: "sm" })] })] }));
|
|
241
|
+
case 'visual': {
|
|
242
|
+
// determine aspect
|
|
243
|
+
let aspect;
|
|
244
|
+
switch (layout) {
|
|
245
|
+
case 'column':
|
|
246
|
+
aspect = parent === 'row' || parentNested
|
|
247
|
+
? 'widescreen'
|
|
248
|
+
: variant === 'mobile'
|
|
249
|
+
? 'widescreen'
|
|
250
|
+
: 'cinema';
|
|
251
|
+
break;
|
|
252
|
+
case 'row':
|
|
253
|
+
aspect = parent === 'row' || parentNested
|
|
254
|
+
? 'square'
|
|
255
|
+
: 'widescreen';
|
|
256
|
+
break;
|
|
257
|
+
case 'grid': {
|
|
258
|
+
// aspect for mobile/nested
|
|
259
|
+
if (variant === 'mobile' || parent === 'row' || parentNested) {
|
|
260
|
+
itemClassName = 'w-full';
|
|
261
|
+
aspect = count === 1
|
|
262
|
+
? 'square'
|
|
263
|
+
: count <= 3
|
|
264
|
+
? 'tv'
|
|
265
|
+
: 'widescreen';
|
|
266
|
+
}
|
|
267
|
+
// adjust aspect based on layout (if it's a grid)
|
|
268
|
+
else if (layout === 'grid') {
|
|
269
|
+
// set base class
|
|
270
|
+
itemClassName = 'min-w-[50px]';
|
|
271
|
+
// override base + pick aspect
|
|
272
|
+
switch (count) {
|
|
273
|
+
case 1:
|
|
274
|
+
aspect = 'widescreen';
|
|
275
|
+
break;
|
|
276
|
+
case 2:
|
|
277
|
+
aspect = 'widescreen';
|
|
278
|
+
break;
|
|
279
|
+
case 3:
|
|
280
|
+
itemClassName = index === 1
|
|
281
|
+
? 'min-w-full'
|
|
282
|
+
: 'min-w-[50px]';
|
|
283
|
+
aspect = index === 1
|
|
284
|
+
? 'cinema'
|
|
285
|
+
: 'tv';
|
|
286
|
+
break;
|
|
287
|
+
case 4:
|
|
288
|
+
aspect = 'tv';
|
|
289
|
+
break;
|
|
290
|
+
case 5:
|
|
291
|
+
itemClassName = index === 3
|
|
292
|
+
? 'min-w-full'
|
|
293
|
+
: 'min-w-[50px]';
|
|
294
|
+
aspect = index === 3
|
|
295
|
+
? 'cinema'
|
|
296
|
+
: 'tv';
|
|
297
|
+
break;
|
|
298
|
+
default:
|
|
299
|
+
aspect = 'widescreen';
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// otherwise standard
|
|
304
|
+
else {
|
|
305
|
+
aspect = 'widescreen';
|
|
306
|
+
}
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// create visual
|
|
311
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, itemClassName), children: (0, jsx_runtime_1.jsx)(Skeleton.MediaPart, { aspect: aspect }) }));
|
|
312
|
+
}
|
|
313
|
+
case 'icon':
|
|
314
|
+
return ((0, jsx_runtime_1.jsx)(Skeleton.IconPart, { className: (0, classnames_1.default)(className, itemClassName), size: variant === 'mobile' ? 'md' : 'sm' }));
|
|
315
|
+
case 'logo':
|
|
316
|
+
return ((0, jsx_runtime_1.jsx)(Skeleton.LogoPart, { className: (0, classnames_1.default)(className, itemClassName), size: variant === 'mobile' ? 'md' : 'sm' }));
|
|
317
|
+
default:
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function renderGrid(args) {
|
|
322
|
+
// determine props
|
|
323
|
+
const { variant, parent, parentNested, item: { itemType, itemCount: itemCountRaw } } = args;
|
|
324
|
+
const itemCount = variant === 'mobile'
|
|
325
|
+
? itemCountRaw.mobile
|
|
326
|
+
: itemCountRaw.desktop;
|
|
327
|
+
const { panelClassName, panelItemClassName } = getGridPanelClasses(args);
|
|
328
|
+
// render grid (really a flexbox layout with controlled item widths)
|
|
329
|
+
return ((0, jsx_runtime_1.jsx)(EditablePanel, Object.assign({}, args, { panelClassName: panelClassName, children: funnel_core_1.ArrayUtils.series(itemCount, 1).map(row => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: renderListItem({
|
|
330
|
+
className: panelItemClassName,
|
|
331
|
+
variant,
|
|
332
|
+
parent,
|
|
333
|
+
parentNested,
|
|
334
|
+
layout: 'grid',
|
|
335
|
+
itemType, index: row,
|
|
336
|
+
count: itemCount
|
|
337
|
+
}) }, `list.${row}`)) })));
|
|
338
|
+
}
|
|
339
|
+
function getGridPanelClasses(args) {
|
|
340
|
+
// resolve props
|
|
341
|
+
const { variant, parent, parentNested, item: { itemType, itemCount: itemCountRaw, itemAlign: itemAlignRaw } } = args;
|
|
342
|
+
const itemAlign = variant === 'mobile'
|
|
343
|
+
? itemAlignRaw.mobile
|
|
344
|
+
: itemAlignRaw.desktop;
|
|
345
|
+
// determine list classes
|
|
346
|
+
const panelClasses = (0, classnames_1.default)('flex flex-wrap gap-l2', {
|
|
347
|
+
'justify-center': itemAlign === 'center',
|
|
348
|
+
'justify-end': itemAlign === 'end'
|
|
349
|
+
});
|
|
350
|
+
let panelItemClasses = '';
|
|
351
|
+
switch (itemType) {
|
|
352
|
+
case 'message':
|
|
353
|
+
case 'message+visual':
|
|
354
|
+
panelItemClasses = (0, classnames_1.default)({
|
|
355
|
+
'w-full': variant === 'mobile' || (variant === 'desktop' && (parent === 'row' || parentNested)),
|
|
356
|
+
'w-[50px]': variant === 'desktop' && parent !== 'row' && !parentNested
|
|
357
|
+
});
|
|
358
|
+
break;
|
|
359
|
+
case 'visual':
|
|
360
|
+
panelItemClasses = (0, classnames_1.default)({
|
|
361
|
+
'': variant === 'mobile' || (variant === 'desktop' && (parent === 'row' || parentNested)),
|
|
362
|
+
'flex-1': variant === 'desktop' && parent !== 'row' && !parentNested
|
|
363
|
+
});
|
|
364
|
+
break;
|
|
365
|
+
case 'icon':
|
|
366
|
+
panelItemClasses = (0, classnames_1.default)({});
|
|
367
|
+
break;
|
|
368
|
+
case 'logo':
|
|
369
|
+
panelItemClasses = (0, classnames_1.default)({
|
|
370
|
+
'': variant === 'desktop',
|
|
371
|
+
'': variant === 'mobile'
|
|
372
|
+
});
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
// return completed classes
|
|
376
|
+
return {
|
|
377
|
+
panelClassName: getPanelClasses(Object.assign(Object.assign({}, args), { className: panelClasses })),
|
|
378
|
+
panelItemClassName: panelItemClasses
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
function getPanelWrapClasses({ className, variant, parent, parentNested, item: { mobileOrder, alignY, fullBleed }, itemPosition }) {
|
|
382
|
+
return variant === 'mobile'
|
|
383
|
+
? (0, classnames_1.default)(className, 'relative w-full flex flex-col', {
|
|
384
|
+
'justify-start': alignY === 'start',
|
|
385
|
+
'justify-center': alignY === 'center',
|
|
386
|
+
'justify-end': alignY === 'end',
|
|
387
|
+
'order-first': mobileOrder === 'first',
|
|
388
|
+
'order-last': mobileOrder === 'last',
|
|
389
|
+
'px-l4': !fullBleed.mobile
|
|
390
|
+
})
|
|
391
|
+
: (0, classnames_1.default)(className, 'relative grid grid-cols-12', {
|
|
392
|
+
'items-start': alignY === 'start',
|
|
393
|
+
'items-center': alignY === 'center',
|
|
394
|
+
'items-end': alignY === 'end',
|
|
395
|
+
'px-l4': parent !== 'row' && !fullBleed.desktop && !parentNested,
|
|
396
|
+
'-ml-l4': itemPosition.left && fullBleed.desktop,
|
|
397
|
+
'-mr-l4': itemPosition.right && fullBleed.desktop
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
function getPanelClasses({ className, variant, parent, parentNested, item: { alignX, size } }) {
|
|
401
|
+
// force full width for mobile
|
|
402
|
+
if (variant === 'mobile') {
|
|
403
|
+
return (0, classnames_1.default)(className);
|
|
404
|
+
}
|
|
405
|
+
// or size for desktop
|
|
406
|
+
switch (parent === 'row' || parentNested ? 'full' : size) {
|
|
407
|
+
case 'xs':
|
|
408
|
+
return (0, classnames_1.default)(className, 'col-span-4', {
|
|
409
|
+
'col-start-1': alignX === 'start',
|
|
410
|
+
'col-start-5': alignX === 'center',
|
|
411
|
+
'col-end-13': alignX === 'end'
|
|
412
|
+
});
|
|
413
|
+
case 'sm':
|
|
414
|
+
return (0, classnames_1.default)(className, 'col-span-6', {
|
|
415
|
+
'col-start-1': alignX === 'start',
|
|
416
|
+
'col-start-4': alignX === 'center',
|
|
417
|
+
'col-end-13': alignX === 'end'
|
|
418
|
+
});
|
|
419
|
+
case 'md':
|
|
420
|
+
return (0, classnames_1.default)(className, 'col-span-8', {
|
|
421
|
+
'col-start-1': alignX === 'start',
|
|
422
|
+
'col-start-3': alignX === 'center',
|
|
423
|
+
'col-end-13': alignX === 'end'
|
|
424
|
+
});
|
|
425
|
+
case 'lg':
|
|
426
|
+
return (0, classnames_1.default)(className, 'col-span-10', {
|
|
427
|
+
'col-start-1': alignX === 'start',
|
|
428
|
+
'col-start-2': alignX === 'center',
|
|
429
|
+
'col-end-13': alignX === 'end'
|
|
430
|
+
});
|
|
431
|
+
case 'full':
|
|
432
|
+
return (0, classnames_1.default)(className, 'col-span-full');
|
|
433
|
+
default:
|
|
434
|
+
return className;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function EditablePanel(_a) {
|
|
438
|
+
var { panelClassName, children } = _a, args = __rest(_a, ["panelClassName", "children"]);
|
|
11
439
|
// render
|
|
12
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'w-full flex justify-center items-center text-
|
|
440
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: getPanelWrapClasses(args), children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(panelClassName, 'relative'), children: [children, (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('group absolute inset-0 z-overlay cursor-pointer interpolate', 'bg-surface1 border border-solid, border-ix-primary rounded-xxs overflow-hidden', 'opacity-none hover:opacity-full'), onClick: () => args.onPanelClick(args.item), children: (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('w-full h-full interpolate', 'flex flex-col justify-center items-center gap-l6', 'text-ix-primary group-hover:bg-ix-primary/tint1 group-active:bg-ix-primary/tint3'), children: (0, jsx_runtime_1.jsx)("span", { className: "label-xs label-strong", children: "Edit" }) }) })] }) }));
|
|
441
|
+
}
|
|
442
|
+
// TODO: scrap this
|
|
443
|
+
class ItemPosition {
|
|
444
|
+
constructor(args) {
|
|
445
|
+
// initialize instance variables
|
|
446
|
+
this.parent = args.parent;
|
|
447
|
+
this.parentOffset = args.parentOffset;
|
|
448
|
+
this.parentSize = args.parentSize;
|
|
449
|
+
}
|
|
450
|
+
get left() {
|
|
451
|
+
return this.parent === 'row' && this.parentOffset === 0;
|
|
452
|
+
}
|
|
453
|
+
get right() {
|
|
454
|
+
return this.parent === 'row' && this.parentOffset === 1;
|
|
455
|
+
}
|
|
13
456
|
}
|
package/dist/styles/index.css
CHANGED
|
@@ -2724,6 +2724,12 @@ video {
|
|
|
2724
2724
|
--tw-border-opacity: 1;
|
|
2725
2725
|
border-color: rgb(var(--color-destructive) / var(--tw-border-opacity, 1));
|
|
2726
2726
|
}
|
|
2727
|
+
.FieldCard.FieldCard-selected{
|
|
2728
|
+
pointer-events: none;
|
|
2729
|
+
cursor: default;
|
|
2730
|
+
--tw-border-opacity: 1;
|
|
2731
|
+
border-color: rgb(var(--color-ix-primary) / var(--tw-border-opacity, 1));
|
|
2732
|
+
}
|
|
2727
2733
|
.FieldCard.FieldCard-disabled{
|
|
2728
2734
|
cursor: default;
|
|
2729
2735
|
opacity: .38;
|
|
@@ -4564,6 +4570,9 @@ video {
|
|
|
4564
4570
|
.h-\[80px\]{
|
|
4565
4571
|
height: 80px;
|
|
4566
4572
|
}
|
|
4573
|
+
.h-\[88px\]{
|
|
4574
|
+
height: 88px;
|
|
4575
|
+
}
|
|
4567
4576
|
.h-dvh{
|
|
4568
4577
|
height: 100dvh;
|
|
4569
4578
|
}
|
|
@@ -4579,6 +4588,9 @@ video {
|
|
|
4579
4588
|
.h-screen{
|
|
4580
4589
|
height: 100vh;
|
|
4581
4590
|
}
|
|
4591
|
+
.max-h-\[240px\]{
|
|
4592
|
+
max-height: 240px;
|
|
4593
|
+
}
|
|
4582
4594
|
.max-h-\[400px\]{
|
|
4583
4595
|
max-height: 400px;
|
|
4584
4596
|
}
|
|
@@ -4669,6 +4681,9 @@ video {
|
|
|
4669
4681
|
.w-\[100px\]{
|
|
4670
4682
|
width: 100px;
|
|
4671
4683
|
}
|
|
4684
|
+
.w-\[116px\]{
|
|
4685
|
+
width: 116px;
|
|
4686
|
+
}
|
|
4672
4687
|
.w-\[120px\]{
|
|
4673
4688
|
width: 120px;
|
|
4674
4689
|
}
|
|
@@ -4690,9 +4705,6 @@ video {
|
|
|
4690
4705
|
.w-\[330px\]{
|
|
4691
4706
|
width: 330px;
|
|
4692
4707
|
}
|
|
4693
|
-
.w-\[372px\]{
|
|
4694
|
-
width: 372px;
|
|
4695
|
-
}
|
|
4696
4708
|
.w-\[420px\]{
|
|
4697
4709
|
width: 420px;
|
|
4698
4710
|
}
|
|
@@ -5332,9 +5344,6 @@ video {
|
|
|
5332
5344
|
.p-3{
|
|
5333
5345
|
padding: 3px;
|
|
5334
5346
|
}
|
|
5335
|
-
.p-l10{
|
|
5336
|
-
padding: 40px;
|
|
5337
|
-
}
|
|
5338
5347
|
.p-l2{
|
|
5339
5348
|
padding: 4px;
|
|
5340
5349
|
}
|
|
@@ -6005,6 +6014,9 @@ video {
|
|
|
6005
6014
|
.hover\:underline:hover{
|
|
6006
6015
|
text-decoration-line: underline;
|
|
6007
6016
|
}
|
|
6017
|
+
.hover\:opacity-full:hover{
|
|
6018
|
+
opacity: 1;
|
|
6019
|
+
}
|
|
6008
6020
|
.hover\:outline-ix-primary\/\[\.35\]:hover{
|
|
6009
6021
|
outline-color: rgb(var(--color-ix-primary) / .35);
|
|
6010
6022
|
}
|
|
@@ -6113,6 +6125,9 @@ video {
|
|
|
6113
6125
|
--tw-bg-opacity: 1;
|
|
6114
6126
|
background-color: rgb(var(--color-ix-primary-hover) / var(--tw-bg-opacity, 1));
|
|
6115
6127
|
}
|
|
6128
|
+
.group:hover .group-hover\:bg-ix-primary\/tint1{
|
|
6129
|
+
background-color: rgb(var(--color-ix-primary) / .1);
|
|
6130
|
+
}
|
|
6116
6131
|
.group:hover .group-hover\:bg-ix-util-hover\/tint1{
|
|
6117
6132
|
background-color: rgb(var(--color-ix-util-hover) / .1);
|
|
6118
6133
|
}
|
|
@@ -6136,6 +6151,9 @@ video {
|
|
|
6136
6151
|
--tw-bg-opacity: 1;
|
|
6137
6152
|
background-color: rgb(var(--color-ix-primary-press) / var(--tw-bg-opacity, 1));
|
|
6138
6153
|
}
|
|
6154
|
+
.group:active .group-active\:bg-ix-primary\/tint3{
|
|
6155
|
+
background-color: rgb(var(--color-ix-primary) / .3);
|
|
6156
|
+
}
|
|
6139
6157
|
.group:active .group-active\:bg-ix-util-press\/tint2{
|
|
6140
6158
|
background-color: rgb(var(--color-ix-util-press) / .2);
|
|
6141
6159
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nascentdigital/funnel-editor",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "restricted"
|
|
@@ -89,5 +89,5 @@
|
|
|
89
89
|
"ts-jest": "^29",
|
|
90
90
|
"type-fest": "^4"
|
|
91
91
|
},
|
|
92
|
-
"gitHead": "
|
|
92
|
+
"gitHead": "3348c90ff56f3dd931ab564f8a6ad13d454a4ca1"
|
|
93
93
|
}
|