@nascentdigital/funnel-editor 4.5.0 → 4.5.2
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/components/interaction/SideSheet.d.ts +26 -0
- package/dist/core/components/interaction/SideSheet.js +200 -0
- package/dist/core/components/interaction/index.d.ts +1 -0
- package/dist/core/components/interaction/index.js +1 -0
- package/dist/core/domain/BlockConfiguration.d.ts +3 -1
- package/dist/core/domain/BlockConfiguration.js +29 -25
- package/dist/page/components/config/BlockConfig.js +6 -21
- package/dist/page/components/config/BlockConfigEditor.d.ts +6 -10
- package/dist/page/components/config/BlockConfigEditor.js +30 -37
- package/dist/page/components/config/BlockPreview.d.ts +3 -1
- package/dist/page/components/config/BlockPreview.js +445 -2
- package/dist/page/components/config/LegacyBlockConfigEditor.d.ts +6 -10
- package/dist/page/components/config/LegacyBlockConfigEditor.js +13 -41
- package/dist/styles/index.css +41 -9
- package/package.json +2 -2
|
@@ -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
|
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export declare
|
|
1
|
+
import { Callback } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { BlockConfiguration } from '../../../core';
|
|
3
|
+
export declare function LegacyBlockConfigEditor({ configuration, onClose }: LegacyBlockConfigEditor.Props): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
export declare namespace LegacyBlockConfigEditor {
|
|
5
|
-
type Props = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
type Options = {
|
|
10
|
-
block: Block | SectionBlock;
|
|
11
|
-
anchor: HTMLElement | Rect;
|
|
5
|
+
type Props = {
|
|
6
|
+
configuration?: BlockConfiguration;
|
|
7
|
+
onClose: Callback.Void;
|
|
12
8
|
};
|
|
13
9
|
}
|
|
@@ -1,63 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LegacyBlockConfigEditor =
|
|
3
|
+
exports.LegacyBlockConfigEditor = LegacyBlockConfigEditor;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
6
|
-
const client_1 = require("@nascentdigital/funnel-ui/client");
|
|
7
5
|
const react_1 = require("react");
|
|
8
6
|
const rxjs_1 = require("rxjs");
|
|
9
7
|
const core_1 = require("../../../core");
|
|
10
8
|
const hooks_1 = require("../../hooks");
|
|
11
9
|
// editor
|
|
12
|
-
|
|
10
|
+
function LegacyBlockConfigEditor({ configuration, onClose }) {
|
|
13
11
|
// bind state + hooks
|
|
14
|
-
const [
|
|
15
|
-
const [configuration, setConfiguration] = (0, react_1.useState)();
|
|
16
|
-
const [anchor, setAnchor] = (0, react_1.useState)();
|
|
12
|
+
const [closing, setClosing] = (0, react_1.useState)(false);
|
|
17
13
|
const pageController = (0, hooks_1.usePageController)();
|
|
18
|
-
const touch = (0, client_1.useTouch)();
|
|
19
14
|
const { modified = false, valid = false } = configuration !== null && configuration !== void 0 ? configuration : {};
|
|
20
15
|
// sync w/ configuration
|
|
21
16
|
(0, core_1.useBlockConfiguration)(configuration);
|
|
22
|
-
//
|
|
23
|
-
(0, react_1.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
setConfiguration(block.getConfiguration());
|
|
27
|
-
setAnchor(anchor);
|
|
28
|
-
// create deferral
|
|
29
|
-
const deferral = new funnel_core_1.Deferral();
|
|
30
|
-
setDeferral(deferral);
|
|
31
|
-
// wait until deferral is resolved
|
|
32
|
-
return deferral.promise;
|
|
17
|
+
// reset closing on new open
|
|
18
|
+
(0, react_1.useEffect)(() => {
|
|
19
|
+
if (configuration) {
|
|
20
|
+
setClosing(false);
|
|
33
21
|
}
|
|
34
|
-
}
|
|
22
|
+
}, [configuration]);
|
|
35
23
|
// helpers
|
|
36
24
|
const onSave = async () => {
|
|
37
25
|
// save config
|
|
38
26
|
configuration === null || configuration === void 0 ? void 0 : configuration.save();
|
|
39
27
|
// wait for page to save
|
|
40
28
|
await (0, rxjs_1.firstValueFrom)(pageController.saved$);
|
|
41
|
-
// complete
|
|
42
|
-
|
|
43
|
-
// refresh
|
|
44
|
-
touch();
|
|
29
|
+
// complete
|
|
30
|
+
onClose();
|
|
45
31
|
};
|
|
46
|
-
const onCancel = () => {
|
|
47
|
-
// skip if missing or already completed
|
|
48
|
-
if (!deferral || deferral.isComplete) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
// cancel
|
|
52
|
-
deferral.resolve(undefined);
|
|
53
|
-
// touch
|
|
54
|
-
touch();
|
|
55
|
-
};
|
|
56
|
-
// skip if there's no config
|
|
57
|
-
if (!configuration) {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
32
|
// render
|
|
61
|
-
const { layout } = configuration;
|
|
62
|
-
return ((0, jsx_runtime_1.jsx)(core_1.
|
|
63
|
-
}
|
|
33
|
+
const { layout } = configuration !== null && configuration !== void 0 ? configuration : {};
|
|
34
|
+
return ((0, jsx_runtime_1.jsx)(core_1.SideSheet, { title: "Block Configuration", backdrop: "none", open: !!configuration || closing, onSave: onSave, onClose: onClose, disableSave: !modified || !valid, customActions: (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "sm", disabled: configuration === null || configuration === void 0 ? void 0 : configuration.isConfigInDefault, onClick: () => configuration === null || configuration === void 0 ? void 0 : configuration.reset(), children: "Reset to Default" }), wide: true, children: (0, jsx_runtime_1.jsxs)("div", { className: "h-full flex flex-col gap-l9 p-l8", children: [(0, jsx_runtime_1.jsxs)("section", { className: "flex flex-wrap justify-center items-start gap-l8", children: [(0, jsx_runtime_1.jsx)(core_1.SkeletonLayout, { variant: "desktop", layout: layout }), (0, jsx_runtime_1.jsx)(core_1.SkeletonLayout, { variant: "mobile", layout: layout })] }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-[max-content_1fr] auto-rows-auto items-start gap-l6", children: (0, jsx_runtime_1.jsx)(core_1.FieldErrorController, { children: configuration === null || configuration === void 0 ? void 0 : configuration.editableFields.map(field => (0, jsx_runtime_1.jsx)(core_1.FieldEditor, { className: "col-span-2", field: field, variant: "wide" }, field.id)) }) })] }) }));
|
|
35
|
+
}
|