@nascentdigital/funnel-editor 4.4.21 → 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.
Files changed (38) hide show
  1. package/dist/core/components/interaction/Animate.d.ts +2 -2
  2. package/dist/core/components/interaction/Animate.js +12 -10
  3. package/dist/core/components/interaction/QuickPicker.d.ts +27 -0
  4. package/dist/core/components/interaction/QuickPicker.js +108 -0
  5. package/dist/core/components/interaction/Tabs.d.ts +16 -0
  6. package/dist/core/components/interaction/Tabs.js +24 -0
  7. package/dist/core/components/interaction/index.d.ts +2 -0
  8. package/dist/core/components/interaction/index.js +2 -0
  9. package/dist/core/components/visuals/Icon.d.ts +1 -1
  10. package/dist/core/components/visuals/Icon.js +3 -0
  11. package/dist/core/components/visuals/SkeletonLayout.js +226 -33
  12. package/dist/core/domain/BlockConfiguration.d.ts +9 -1
  13. package/dist/core/domain/BlockConfiguration.js +50 -20
  14. package/dist/core/domain/Section.js +1 -1
  15. package/dist/page/components/BlockEditor.js +3 -3
  16. package/dist/page/components/{BlockConfig.d.ts → config/BlockConfig.d.ts} +1 -1
  17. package/dist/page/components/config/BlockConfig.js +43 -0
  18. package/dist/page/components/config/BlockConfigEditor.d.ts +13 -0
  19. package/dist/page/components/config/BlockConfigEditor.js +110 -0
  20. package/dist/page/components/config/BlockPreview.d.ts +10 -0
  21. package/dist/page/components/config/BlockPreview.js +456 -0
  22. package/dist/page/components/config/BlockView.d.ts +4 -0
  23. package/dist/page/components/config/BlockView.js +9 -0
  24. package/dist/page/components/config/LegacyBlockConfigEditor.d.ts +13 -0
  25. package/dist/page/components/{BlockConfig.js → config/LegacyBlockConfigEditor.js} +4 -29
  26. package/dist/page/components/config/ListLayoutPicker.d.ts +6 -0
  27. package/dist/page/components/config/ListLayoutPicker.js +13 -0
  28. package/dist/page/components/config/ListPanelEditor.d.ts +6 -0
  29. package/dist/page/components/config/ListPanelEditor.js +13 -0
  30. package/dist/page/components/config/MessagePanelEditor.d.ts +6 -0
  31. package/dist/page/components/config/MessagePanelEditor.js +13 -0
  32. package/dist/page/components/config/VisualPanelEditor.d.ts +6 -0
  33. package/dist/page/components/config/VisualPanelEditor.js +13 -0
  34. package/dist/page/components/config/index.d.ts +1 -0
  35. package/dist/page/components/config/index.js +17 -0
  36. package/dist/page/hooks/PageController.js +1 -1
  37. package/dist/styles/index.css +108 -3
  38. package/package.json +2 -2
@@ -0,0 +1,456 @@
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
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.BlockPreview = BlockPreview;
18
+ const jsx_runtime_1 = require("react/jsx-runtime");
19
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
20
+ const classnames_1 = __importDefault(require("classnames"));
21
+ const react_1 = require("react");
22
+ const core_1 = require("../../../core");
23
+ // component
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"]);
439
+ // render
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
+ }
456
+ }
@@ -0,0 +1,4 @@
1
+ export type BlockView = 'desktop' | 'mobile';
2
+ export declare namespace BlockView {
3
+ const values: ReadonlyArray<BlockView>;
4
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BlockView = void 0;
4
+ // extension
5
+ var BlockView;
6
+ (function (BlockView) {
7
+ // values
8
+ BlockView.values = ['desktop', 'mobile'];
9
+ })(BlockView || (exports.BlockView = BlockView = {}));
@@ -0,0 +1,13 @@
1
+ import { Rect } from '@nascentdigital/funnel-core';
2
+ import { Block, SectionBlock } from '../../../core';
3
+ export declare const LegacyBlockConfigEditor: import("react").ForwardRefExoticComponent<import("react").RefAttributes<LegacyBlockConfigEditor.Ref>>;
4
+ export declare namespace LegacyBlockConfigEditor {
5
+ type Props = {};
6
+ interface Ref {
7
+ edit(options: Options): Promise<void>;
8
+ }
9
+ type Options = {
10
+ block: Block | SectionBlock;
11
+ anchor: HTMLElement | Rect;
12
+ };
13
+ }
@@ -1,40 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BlockConfig = BlockConfig;
3
+ exports.LegacyBlockConfigEditor = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const funnel_core_1 = require("@nascentdigital/funnel-core");
6
6
  const client_1 = require("@nascentdigital/funnel-ui/client");
7
7
  const react_1 = require("react");
8
8
  const rxjs_1 = require("rxjs");
9
- const core_1 = require("../../core");
10
- const hooks_1 = require("../hooks");
11
- // component
12
- function BlockConfig({ className, block: blockOrSectionBlock }) {
13
- // bind ref
14
- const editorRef = (0, react_1.useRef)(null);
15
- // skip if there's no config
16
- const block = blockOrSectionBlock instanceof core_1.SectionBlock
17
- ? blockOrSectionBlock.block
18
- : blockOrSectionBlock;
19
- const { config } = block;
20
- if (config.length === 0) {
21
- return undefined;
22
- }
23
- // helpers
24
- const onEdit = async (event) => {
25
- var _a;
26
- // edit configuration
27
- await ((_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.edit({
28
- block: blockOrSectionBlock,
29
- anchor: event.currentTarget
30
- }));
31
- };
32
- // render
33
- const valid = config.every(field => field.valid);
34
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.StatusChip, { className: className, variant: valid ? 'success' : 'error', onClick: onEdit, children: "Configure" }), (0, jsx_runtime_1.jsx)(BlockConfigEditor, { ref: editorRef })] }));
35
- }
9
+ const core_1 = require("../../../core");
10
+ const hooks_1 = require("../../hooks");
36
11
  // editor
37
- const BlockConfigEditor = (0, react_1.forwardRef)(function BlockConfigEditor(_, ref) {
12
+ exports.LegacyBlockConfigEditor = (0, react_1.forwardRef)(function LegacyBlockConfigEditor(_, ref) {
38
13
  // bind state + hooks
39
14
  const [deferral, setDeferral] = (0, react_1.useState)(undefined);
40
15
  const [configuration, setConfiguration] = (0, react_1.useState)();
@@ -0,0 +1,6 @@
1
+ export declare function ListLayoutPicker({ className }: ListLayoutPicker.Props): import("react/jsx-runtime").JSX.Element;
2
+ export declare namespace ListLayoutPicker {
3
+ type Props = {
4
+ className?: string;
5
+ };
6
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ListLayoutPicker = ListLayoutPicker;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const classnames_1 = __importDefault(require("classnames"));
9
+ // component
10
+ function ListLayoutPicker({ className }) {
11
+ // render
12
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className), children: "ListLayoutPicker" }));
13
+ }
@@ -0,0 +1,6 @@
1
+ export declare function ListPanelEditor({ className }: ListPanelEditor.Props): import("react/jsx-runtime").JSX.Element;
2
+ export declare namespace ListPanelEditor {
3
+ type Props = {
4
+ className?: string;
5
+ };
6
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ListPanelEditor = ListPanelEditor;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const classnames_1 = __importDefault(require("classnames"));
9
+ // component
10
+ function ListPanelEditor({ className }) {
11
+ // render
12
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className), children: "ListPanelEditor" }));
13
+ }
@@ -0,0 +1,6 @@
1
+ export declare function MessagePanelEditor({ className }: MessagePanelEditor.Props): import("react/jsx-runtime").JSX.Element;
2
+ export declare namespace MessagePanelEditor {
3
+ type Props = {
4
+ className?: string;
5
+ };
6
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MessagePanelEditor = MessagePanelEditor;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const classnames_1 = __importDefault(require("classnames"));
9
+ // component
10
+ function MessagePanelEditor({ className }) {
11
+ // render
12
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className), children: "MessagePanelEditor" }));
13
+ }
@@ -0,0 +1,6 @@
1
+ export declare function VisualPanelEditor({ className }: VisualPanelEditor.Props): import("react/jsx-runtime").JSX.Element;
2
+ export declare namespace VisualPanelEditor {
3
+ type Props = {
4
+ className?: string;
5
+ };
6
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VisualPanelEditor = VisualPanelEditor;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const classnames_1 = __importDefault(require("classnames"));
9
+ // component
10
+ function VisualPanelEditor({ className }) {
11
+ // render
12
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className), children: "MessagePanelEditor" }));
13
+ }
@@ -0,0 +1 @@
1
+ export * from './BlockConfig';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./BlockConfig"), exports);
@@ -146,7 +146,7 @@ class PageController {
146
146
  });
147
147
  // save page immediately if modified (this is a re-entrant call, so we can't await it - trust me)
148
148
  if (page.modified) {
149
- console.trace('[PageController/setPage] save triggered by page modification', page);
149
+ console.debug('[PageController/setPage] save triggered by page modification', page);
150
150
  this.save().catch(console.error);
151
151
  }
152
152
  }