@nascentdigital/funnel-editor 4.4.21 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/components/interaction/Animate.d.ts +2 -2
- package/dist/core/components/interaction/Animate.js +12 -10
- package/dist/core/components/interaction/QuickPicker.d.ts +23 -0
- package/dist/core/components/interaction/QuickPicker.js +95 -0
- package/dist/core/components/interaction/Tabs.d.ts +16 -0
- package/dist/core/components/interaction/Tabs.js +24 -0
- package/dist/core/components/interaction/index.d.ts +2 -0
- package/dist/core/components/interaction/index.js +2 -0
- package/dist/core/components/visuals/Icon.d.ts +1 -1
- package/dist/core/components/visuals/Icon.js +3 -0
- package/dist/core/components/visuals/SkeletonLayout.js +226 -33
- package/dist/core/domain/BlockConfiguration.d.ts +7 -1
- package/dist/core/domain/BlockConfiguration.js +27 -1
- package/dist/core/domain/Section.js +1 -1
- package/dist/page/components/BlockEditor.js +3 -3
- package/dist/page/components/{BlockConfig.d.ts → config/BlockConfig.d.ts} +1 -1
- package/dist/page/components/config/BlockConfig.js +43 -0
- package/dist/page/components/config/BlockConfigEditor.d.ts +13 -0
- package/dist/page/components/config/BlockConfigEditor.js +94 -0
- package/dist/page/components/config/BlockPreview.d.ts +8 -0
- package/dist/page/components/config/BlockPreview.js +13 -0
- package/dist/page/components/config/BlockView.d.ts +4 -0
- package/dist/page/components/config/BlockView.js +9 -0
- package/dist/page/components/config/LegacyBlockConfigEditor.d.ts +13 -0
- package/dist/page/components/{BlockConfig.js → config/LegacyBlockConfigEditor.js} +4 -29
- package/dist/page/components/config/ListLayoutPicker.d.ts +6 -0
- package/dist/page/components/config/ListLayoutPicker.js +13 -0
- package/dist/page/components/config/ListPanelEditor.d.ts +6 -0
- package/dist/page/components/config/ListPanelEditor.js +13 -0
- package/dist/page/components/config/MessagePanelEditor.d.ts +6 -0
- package/dist/page/components/config/MessagePanelEditor.js +13 -0
- package/dist/page/components/config/VisualPanelEditor.d.ts +6 -0
- package/dist/page/components/config/VisualPanelEditor.js +13 -0
- package/dist/page/components/config/index.d.ts +1 -0
- package/dist/page/components/config/index.js +17 -0
- package/dist/page/hooks/PageController.js +1 -1
- package/dist/styles/index.css +90 -3
- package/package.json +2 -2
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Variants } from 'motion/react';
|
|
1
|
+
import { Variants as MotionVariants } from 'motion/react';
|
|
2
2
|
import { PropsWithChildren } from 'react';
|
|
3
3
|
export declare function Animate({ className, present, layout, effect, children }: Animate.Props): import("react/jsx-runtime").JSX.Element | undefined;
|
|
4
4
|
export declare namespace Animate {
|
|
5
|
+
const Variants: Readonly<Record<Animate.Effect, MotionVariants>>;
|
|
5
6
|
type Props = PropsWithChildren & {
|
|
6
7
|
className?: string;
|
|
7
8
|
present?: boolean;
|
|
@@ -10,4 +11,3 @@ export declare namespace Animate {
|
|
|
10
11
|
};
|
|
11
12
|
type Effect = 'fade';
|
|
12
13
|
}
|
|
13
|
-
export declare const variants: Readonly<Record<Animate.Effect, Variants>>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.variants = void 0;
|
|
4
3
|
exports.Animate = Animate;
|
|
5
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
5
|
const react_1 = require("motion/react");
|
|
@@ -11,13 +10,16 @@ function Animate({ className, present = false, layout = false, effect = 'fade',
|
|
|
11
10
|
return undefined;
|
|
12
11
|
}
|
|
13
12
|
// render
|
|
14
|
-
return ((0, jsx_runtime_1.jsx)(react_1.motion.div, { className: className, variants:
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)(react_1.motion.div, { className: className, variants: Animate.Variants[effect], initial: "initial", animate: "animate", exit: "exit", layout: layout, children: children }));
|
|
15
14
|
}
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
15
|
+
// extension
|
|
16
|
+
(function (Animate) {
|
|
17
|
+
// variants
|
|
18
|
+
Animate.Variants = {
|
|
19
|
+
fade: {
|
|
20
|
+
initial: { opacity: 0, transition: { when: 'beforeChildren' } },
|
|
21
|
+
animate: { opacity: 1, transition: { ease: "easeIn", when: 'beforeChildren' } },
|
|
22
|
+
exit: { opacity: 0, transition: { ease: "easeOut", when: 'afterChildren' } }
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
})(Animate || (exports.Animate = Animate = {}));
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RequiredBy } from '@nascentdigital/funnel-core';
|
|
2
|
+
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 namespace QuickPicker {
|
|
5
|
+
type Item<TId extends string = string> = {
|
|
6
|
+
id: TId;
|
|
7
|
+
};
|
|
8
|
+
type Props = {
|
|
9
|
+
title: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
};
|
|
12
|
+
interface Ref<TId extends string, TItem extends Item<TId>> {
|
|
13
|
+
readonly isOpen: boolean;
|
|
14
|
+
open(args: CaptureArgs<TId, TItem>): Promise<TId | undefined>;
|
|
15
|
+
close(): void;
|
|
16
|
+
}
|
|
17
|
+
type CaptureArgs<TId extends string, TItem extends Item<TId>> = PopupProps & {
|
|
18
|
+
items: ReadonlyArray<TItem>;
|
|
19
|
+
selectedItem?: TId;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
type PopupProps = RequiredBy<Omit<Popup.Props, 'className' | 'animation' | 'disableClickDismiss' | 'open' | 'onOpened' | 'onClose' | 'onClosed' | 'children'>, 'anchor' | 'placement'>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
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.QuickPicker = void 0;
|
|
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 Popup_1 = require("./Popup");
|
|
23
|
+
// component
|
|
24
|
+
exports.QuickPicker = (0, react_1.forwardRef)(function QuickPicker({ title, description }, ref) {
|
|
25
|
+
// bind state
|
|
26
|
+
const [opened, setOpened] = (0, react_1.useState)(false);
|
|
27
|
+
const [deferral, setDeferral] = (0, react_1.useState)();
|
|
28
|
+
const deferralRef = (0, react_1.useRef)(deferral);
|
|
29
|
+
deferralRef.current = deferral;
|
|
30
|
+
const [items, setItems] = (0, react_1.useState)([]);
|
|
31
|
+
const [selectedItem, setSelectedItem] = (0, react_1.useState)();
|
|
32
|
+
const [popupProps, setPopupProps] = (0, react_1.useState)();
|
|
33
|
+
// expose interface
|
|
34
|
+
(0, react_1.useImperativeHandle)(ref, () => ({
|
|
35
|
+
get isOpen() {
|
|
36
|
+
const deferral = deferralRef.current;
|
|
37
|
+
return !!deferral && !deferral.isComplete;
|
|
38
|
+
},
|
|
39
|
+
open: async (_a) => {
|
|
40
|
+
var { items, selectedItem } = _a, popupProps = __rest(_a, ["items", "selectedItem"]);
|
|
41
|
+
// reset
|
|
42
|
+
setItems(items);
|
|
43
|
+
setSelectedItem(selectedItem);
|
|
44
|
+
setPopupProps(popupProps);
|
|
45
|
+
// create/set deferral
|
|
46
|
+
const deferral = new funnel_core_1.Deferral();
|
|
47
|
+
setDeferral(deferral);
|
|
48
|
+
// await result
|
|
49
|
+
const result = await deferral.promise;
|
|
50
|
+
// clear deferral
|
|
51
|
+
setDeferral(undefined);
|
|
52
|
+
// return deferral
|
|
53
|
+
return result;
|
|
54
|
+
},
|
|
55
|
+
close: () => { var _a; return (_a = deferralRef.current) === null || _a === void 0 ? void 0 : _a.resolve(undefined); }
|
|
56
|
+
}), []);
|
|
57
|
+
// helpers
|
|
58
|
+
const onPick = (e) => {
|
|
59
|
+
// stop propagation
|
|
60
|
+
e.preventDefault();
|
|
61
|
+
e.stopPropagation();
|
|
62
|
+
// resolve
|
|
63
|
+
deferral === null || deferral === void 0 ? void 0 : deferral.resolve(selectedItem);
|
|
64
|
+
};
|
|
65
|
+
const onClose = (e) => {
|
|
66
|
+
// stop propagation
|
|
67
|
+
if (e) {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
e.stopPropagation();
|
|
70
|
+
}
|
|
71
|
+
// ignore if already complete
|
|
72
|
+
if (deferral === null || deferral === void 0 ? void 0 : deferral.isComplete) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// complete
|
|
76
|
+
deferral === null || deferral === void 0 ? void 0 : deferral.resolve(undefined);
|
|
77
|
+
};
|
|
78
|
+
const onKeyDown = (e) => {
|
|
79
|
+
// handle keys
|
|
80
|
+
switch (e.key) {
|
|
81
|
+
case 'Enter':
|
|
82
|
+
onPick(e);
|
|
83
|
+
break;
|
|
84
|
+
case 'Escape':
|
|
85
|
+
onClose(e);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
// 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-[372px] flex flex-col gap-l8 p-l8 interpolate', 'border-t border-solid border-glass-stroke-l1 rounded-md', {
|
|
91
|
+
'opacity-none': !opened,
|
|
92
|
+
'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", { children: "Items" })] })));
|
|
95
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Callback } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { Icon } from '../visuals';
|
|
3
|
+
export declare function Tabs<TId extends string>({ className, items, selectedItem, onSelect }: Tabs.Props<TId>): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export declare namespace Tabs {
|
|
5
|
+
type Item<TId extends string = string> = {
|
|
6
|
+
id: TId;
|
|
7
|
+
label: string;
|
|
8
|
+
icon?: Icon.Variant;
|
|
9
|
+
};
|
|
10
|
+
type Props<TId extends string = string> = {
|
|
11
|
+
className?: string;
|
|
12
|
+
items: ReadonlyArray<Item<TId>>;
|
|
13
|
+
selectedItem: TId;
|
|
14
|
+
onSelect?: Callback<TId>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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.Tabs = Tabs;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
9
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
10
|
+
const framer_motion_1 = require("framer-motion");
|
|
11
|
+
const visuals_1 = require("../visuals");
|
|
12
|
+
// component
|
|
13
|
+
function Tabs({ className, items, selectedItem, onSelect = funnel_core_1.Fn.NoOp }) {
|
|
14
|
+
// render
|
|
15
|
+
return ((0, jsx_runtime_1.jsx)("nav", { className: (0, classnames_1.default)(className), children: (0, jsx_runtime_1.jsx)("ul", { className: "grid auto-cols-fr grid-flow-col items-center", children: items.map(item => (0, jsx_runtime_1.jsxs)("li", { className: (0, classnames_1.default)('group relative border-b border-solid border-content-tertiary cursor-pointer interpolate', {
|
|
16
|
+
'pointer-events-none': item.id === selectedItem,
|
|
17
|
+
'hover:border-content-secondary active:border-content-tertiary': item.id !== selectedItem
|
|
18
|
+
}), onClick: () => onSelect(item.id), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-center items-center gap-l6", children: [item.icon &&
|
|
19
|
+
(0, jsx_runtime_1.jsx)(visuals_1.Icon, { variant: item.icon, size: "nav" }), (0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)('inline-block label-sm py-l6 interpolate', {
|
|
20
|
+
'text-content-primary': item.id === selectedItem,
|
|
21
|
+
'text-content-secondary group-hover:text-content-primary group-active:text-content-tertiary': item.id !== selectedItem
|
|
22
|
+
}), children: item.label })] }), item.id === selectedItem &&
|
|
23
|
+
(0, jsx_runtime_1.jsx)(framer_motion_1.motion.span, { id: "underline", layoutId: "underline", className: "absolute inset-x-0 -bottom-px block divider border-b-2 border-ix-primary -mb-px z-supersurface" })] }, item.id)) }) }));
|
|
24
|
+
}
|
|
@@ -23,7 +23,9 @@ export * from './Picker';
|
|
|
23
23
|
export * from './Popup';
|
|
24
24
|
export * from './Profile';
|
|
25
25
|
export * from './QuickInput';
|
|
26
|
+
export * from './QuickPicker';
|
|
26
27
|
export * from './SegmentedButton';
|
|
27
28
|
export * from './Sortable';
|
|
29
|
+
export * from './Tabs';
|
|
28
30
|
export * from './Toggle';
|
|
29
31
|
export * from './Touchable';
|
|
@@ -39,7 +39,9 @@ __exportStar(require("./Picker"), exports);
|
|
|
39
39
|
__exportStar(require("./Popup"), exports);
|
|
40
40
|
__exportStar(require("./Profile"), exports);
|
|
41
41
|
__exportStar(require("./QuickInput"), exports);
|
|
42
|
+
__exportStar(require("./QuickPicker"), exports);
|
|
42
43
|
__exportStar(require("./SegmentedButton"), exports);
|
|
43
44
|
__exportStar(require("./Sortable"), exports);
|
|
45
|
+
__exportStar(require("./Tabs"), exports);
|
|
44
46
|
__exportStar(require("./Toggle"), exports);
|
|
45
47
|
__exportStar(require("./Touchable"), exports);
|
|
@@ -6,7 +6,7 @@ export declare namespace Icon {
|
|
|
6
6
|
size?: Size;
|
|
7
7
|
};
|
|
8
8
|
type Size = 'xl' | 'lg' | 'md' | 'sm' | 'xs' | 'nav' | 'card' | Sizing;
|
|
9
|
-
type Variant = 'Archive' | 'ArrowLeft' | 'Atom' | 'Blocks' | 'Bold' | 'Check' | 'ChevronDown' | 'ChevronRight' | 'ChevronUp' | 'Circle' | 'CircleAlert' | 'CircleCheck' | 'CircleCheckBig' | 'CirclePlus' | 'CircleQuestionMark' | 'CloudCheck' | 'CloudUpload' | 'CornerDownRight' | 'EllipsisVertical' | 'Eye' | 'EyeOff' | 'File' | 'FileDown' | 'FilePlusCorner' | 'FileSearchCorner' | 'Goal' | 'Globe' | 'GripVertical' | 'HatGlasses' | 'History' | 'Highlighter' | 'Image' | 'ImageDown' | 'Info' | 'Italic' | 'Layers' | 'LayoutTemplate' | 'Link' | 'Link2' | 'List' | 'ListChecks' | 'ListIndentDecrease' | 'ListIndentIncrease' | 'ListOrdered' | 'Lock' | 'LockOpen' | 'Mail' | 'MessageSquareQuote' | 'Minus' | 'MonitorCog' | 'Moon' | 'NotebookPen' | 'Pencil' | 'Pin' | 'Plus' | 'Redo' | 'RefreshCw' | 'RotateCcw' | 'RotateCw' | 'SearchCode' | 'Settings' | 'SquarePlay' | 'Star' | 'Strikethrough' | 'Subscript' | 'Sun' | 'Superscript' | 'TextAlignStart' | 'Trash' | 'TriangleAlert' | 'Trophy' | 'Underline' | 'Undo' | 'Upload' | 'UserRound' | 'X';
|
|
9
|
+
type Variant = 'Archive' | 'ArrowLeft' | 'ArrowLeftRight' | 'Atom' | 'Blocks' | 'Bold' | 'Check' | 'ChevronDown' | 'ChevronRight' | 'ChevronUp' | 'Circle' | 'CircleAlert' | 'CircleCheck' | 'CircleCheckBig' | 'CirclePlus' | 'CircleQuestionMark' | 'CloudCheck' | 'CloudUpload' | 'CornerDownRight' | 'EllipsisVertical' | 'Eye' | 'EyeOff' | 'File' | 'FileDown' | 'FilePlusCorner' | 'FileSearchCorner' | 'Goal' | 'Globe' | 'GripVertical' | 'HatGlasses' | 'History' | 'Highlighter' | 'Image' | 'ImageDown' | 'Info' | 'Italic' | 'Layers' | 'LayoutTemplate' | 'Link' | 'Link2' | 'List' | 'ListChecks' | 'ListIndentDecrease' | 'ListIndentIncrease' | 'ListOrdered' | 'Lock' | 'LockOpen' | 'Mail' | 'MessageSquareQuote' | 'Minus' | 'MonitorCog' | 'Moon' | 'NotebookPen' | 'Pencil' | 'Pin' | 'Plus' | 'Redo' | 'RefreshCw' | 'RotateCcw' | 'RotateCw' | 'SearchCode' | 'Settings' | 'SquarePlay' | 'Star' | 'Strikethrough' | 'Subscript' | 'Sun' | 'Superscript' | 'TextAlignStart' | 'Trash' | 'TriangleAlert' | 'Trophy' | 'Underline' | 'Undo' | 'Upload' | 'UserRound' | 'X';
|
|
10
10
|
namespace Variant {
|
|
11
11
|
function filter(value: any): value is Variant;
|
|
12
12
|
}
|
|
@@ -20,6 +20,7 @@ function Icon({ className, variant, size: sizing = 'md' }) {
|
|
|
20
20
|
const values = [
|
|
21
21
|
'Archive',
|
|
22
22
|
'ArrowLeft',
|
|
23
|
+
'ArrowLeftRight',
|
|
23
24
|
'Atom',
|
|
24
25
|
'Blocks',
|
|
25
26
|
'Bold',
|
|
@@ -111,6 +112,8 @@ function getIcon(variant) {
|
|
|
111
112
|
return lucide_react_1.Archive;
|
|
112
113
|
case 'ArrowLeft':
|
|
113
114
|
return lucide_react_1.ArrowLeft;
|
|
115
|
+
case 'ArrowLeftRight':
|
|
116
|
+
return lucide_react_1.ArrowLeftRight;
|
|
114
117
|
case 'Atom':
|
|
115
118
|
return lucide_react_1.Atom;
|
|
116
119
|
case 'Blocks':
|
|
@@ -27,17 +27,20 @@ function SkeletonLayout({ variant, layout }) {
|
|
|
27
27
|
// helpers
|
|
28
28
|
var Skeleton;
|
|
29
29
|
(function (Skeleton) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
function HeadlinePart({ className, size }) {
|
|
31
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'bg-ix-primary rounded-xxs overflow-hidden', {
|
|
32
|
+
'h-6 ': size === 'sm',
|
|
33
|
+
'h-8': size === 'md'
|
|
34
|
+
}) }));
|
|
35
|
+
}
|
|
36
|
+
Skeleton.HeadlinePart = HeadlinePart;
|
|
37
|
+
function CaptionPart({ className, size }) {
|
|
38
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'h-4 bg-draft/tint3 rounded-px overflow-hidden', {
|
|
39
|
+
'': size === 'sm'
|
|
40
|
+
}) }));
|
|
41
|
+
}
|
|
42
|
+
Skeleton.CaptionPart = CaptionPart;
|
|
43
|
+
function MediaPart({ className, aspect }) {
|
|
41
44
|
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', {
|
|
42
45
|
'aspect-square': aspect === 'square' || aspect === 'auto',
|
|
43
46
|
'aspect-phone': aspect === 'phone',
|
|
@@ -50,7 +53,21 @@ var Skeleton;
|
|
|
50
53
|
absoluteStrokeWidth: false
|
|
51
54
|
} }) }));
|
|
52
55
|
}
|
|
53
|
-
Skeleton.
|
|
56
|
+
Skeleton.MediaPart = MediaPart;
|
|
57
|
+
function IconPart({ className, size }) {
|
|
58
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'bg-draft/tint3 rounded-full overflow-hidden', {
|
|
59
|
+
'w-10 h-10': size === 'sm',
|
|
60
|
+
'w-14 h-14': size === 'md'
|
|
61
|
+
}) }));
|
|
62
|
+
}
|
|
63
|
+
Skeleton.IconPart = IconPart;
|
|
64
|
+
function LogoPart({ className, size }) {
|
|
65
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'bg-draft/tint3 rounded-px overflow-hidden', {
|
|
66
|
+
'w-14 h-6': size === 'sm',
|
|
67
|
+
'w-20 h-9': size === 'md'
|
|
68
|
+
}) }));
|
|
69
|
+
}
|
|
70
|
+
Skeleton.LogoPart = LogoPart;
|
|
54
71
|
})(Skeleton || (Skeleton = {}));
|
|
55
72
|
function renderLayout({ className, variant, layout }) {
|
|
56
73
|
// TODO: render empty state if there's no layout
|
|
@@ -58,55 +75,57 @@ function renderLayout({ className, variant, layout }) {
|
|
|
58
75
|
return null;
|
|
59
76
|
}
|
|
60
77
|
// render root layout
|
|
61
|
-
const { type, items
|
|
78
|
+
const { type, items } = layout.root;
|
|
62
79
|
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({
|
|
63
80
|
className: (0, classnames_1.default)({
|
|
64
81
|
'flex-1': type === 'row' && variant !== 'mobile'
|
|
65
82
|
}),
|
|
66
83
|
variant,
|
|
67
84
|
parent: type,
|
|
85
|
+
parentNested: false,
|
|
68
86
|
siblingCount: items.length,
|
|
69
87
|
item,
|
|
70
88
|
itemPosition: new ItemPosition({
|
|
71
89
|
parent: type,
|
|
72
90
|
parentOffset,
|
|
73
|
-
parentSize: items.length
|
|
91
|
+
parentSize: items.length
|
|
74
92
|
})
|
|
75
93
|
}) }, `${item.type}.${parentOffset}`)) }));
|
|
76
94
|
}
|
|
77
|
-
function renderItem({ className, parent, siblingCount, variant, item, itemPosition }) {
|
|
95
|
+
function renderItem({ className, parent, parentNested, siblingCount, variant, item, itemPosition }) {
|
|
78
96
|
// render item
|
|
79
97
|
const { type: itemType } = item;
|
|
80
98
|
switch (itemType) {
|
|
81
99
|
case 'row':
|
|
82
100
|
case 'column':
|
|
83
101
|
case 'stack':
|
|
84
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: getContainerClasses({ className, siblingCount, variant, item }), children: item.items.map((item, parentOffset, items) => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: renderItem({
|
|
102
|
+
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({
|
|
85
103
|
className: (0, classnames_1.default)({
|
|
86
104
|
'flex-1': itemType === 'row'
|
|
87
105
|
}),
|
|
88
106
|
variant,
|
|
89
107
|
parent: itemType,
|
|
108
|
+
parentNested: true,
|
|
90
109
|
siblingCount: items.length,
|
|
91
110
|
item: item,
|
|
92
111
|
itemPosition: new ItemPosition({
|
|
93
112
|
parent: itemType,
|
|
94
113
|
parentOffset,
|
|
95
|
-
parentSize: items.length
|
|
114
|
+
parentSize: items.length
|
|
96
115
|
})
|
|
97
116
|
}) }, `${item.type}.${parentOffset}`)) }));
|
|
98
117
|
case 'message':
|
|
99
|
-
return renderMessage({ className, parent, siblingCount, variant, item, itemPosition });
|
|
118
|
+
return renderMessage({ className, parent, parentNested, siblingCount, variant, item, itemPosition });
|
|
100
119
|
case 'visual':
|
|
101
|
-
return renderVisual({ className, parent, siblingCount, variant, item, itemPosition });
|
|
120
|
+
return renderVisual({ className, parent, parentNested, siblingCount, variant, item, itemPosition });
|
|
102
121
|
case 'list':
|
|
103
|
-
return renderList({ className, parent, siblingCount, variant, item, itemPosition });
|
|
122
|
+
return renderList({ className, parent, parentNested, siblingCount, variant, item, itemPosition });
|
|
104
123
|
default:
|
|
105
124
|
console.error('[SkeletonLayout] no support for BlockLayout item', item);
|
|
106
125
|
return null;
|
|
107
126
|
}
|
|
108
127
|
}
|
|
109
|
-
function getContainerClasses({ className, variant, item }) {
|
|
128
|
+
function getContainerClasses({ className, variant, parent, item }) {
|
|
110
129
|
const { type, alignY } = item;
|
|
111
130
|
// row style
|
|
112
131
|
if (type === 'row' && variant !== 'mobile') {
|
|
@@ -120,7 +139,7 @@ function getContainerClasses({ className, variant, item }) {
|
|
|
120
139
|
'grid-cols-[2fr,1fr]': item.ratio.desktop === '2/1',
|
|
121
140
|
'grid-cols-[2fr,3fr]': item.ratio.desktop === '2/3',
|
|
122
141
|
'grid-cols-[3fr,1fr]': item.ratio.desktop === '3/1',
|
|
123
|
-
'grid-cols-[3fr,2fr]': item.ratio.desktop === '3/2'
|
|
142
|
+
'grid-cols-[3fr,2fr]': item.ratio.desktop === '3/2'
|
|
124
143
|
});
|
|
125
144
|
}
|
|
126
145
|
// or stack
|
|
@@ -147,24 +166,198 @@ function renderMessage(args) {
|
|
|
147
166
|
'items-end': textAlign.desktop === 'right'
|
|
148
167
|
});
|
|
149
168
|
// render
|
|
150
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: getPanelWrapClasses(args), children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(messageClasses, getPanelClasses(Object.assign(Object.assign({}, args), { className: 'flex flex-col' }))), children: [(0, jsx_runtime_1.jsx)(
|
|
169
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: getPanelWrapClasses(args), children: (0, jsx_runtime_1.jsxs)("div", { className: (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" })] }) }));
|
|
151
170
|
}
|
|
152
171
|
function renderVisual(args) {
|
|
153
172
|
// resolve props
|
|
154
173
|
const { variant, item: { aspectRatio }, parent } = args;
|
|
155
174
|
const aspect = variant === 'mobile' ? aspectRatio.mobile : aspectRatio.desktop;
|
|
156
175
|
// render
|
|
157
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: getPanelWrapClasses(args), children: (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(getPanelClasses(Object.assign(Object.assign({}, args), { className: '' }))), children: (0, jsx_runtime_1.jsx)(Skeleton.
|
|
176
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: getPanelWrapClasses(args), children: (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(getPanelClasses(Object.assign(Object.assign({}, args), { className: '' }))), children: (0, jsx_runtime_1.jsx)(Skeleton.MediaPart, { className: "w-full", aspect: aspect }) }) }));
|
|
158
177
|
}
|
|
159
178
|
function renderList(args) {
|
|
160
179
|
// resolve props
|
|
161
|
-
const { item: { itemType } } = args;
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
180
|
+
const { variant, parent, parentNested, item: { layout: layoutRaw, itemType, itemCount: itemCountRaw } } = args;
|
|
181
|
+
const layout = variant === 'mobile'
|
|
182
|
+
? layoutRaw.mobile
|
|
183
|
+
: layoutRaw.desktop;
|
|
184
|
+
// render a grid
|
|
185
|
+
if (layout === 'grid') {
|
|
186
|
+
return renderGrid(args);
|
|
187
|
+
}
|
|
188
|
+
// or render row/column
|
|
189
|
+
const itemCount = variant === 'mobile'
|
|
190
|
+
? itemCountRaw.mobile
|
|
191
|
+
: itemCountRaw.desktop;
|
|
192
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: getPanelWrapClasses(args), children: (0, jsx_runtime_1.jsx)("div", { className: 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}`)) }) }));
|
|
193
|
+
}
|
|
194
|
+
function getListPanelClasses(args) {
|
|
195
|
+
// resolve props
|
|
196
|
+
const { variant, item: { layout: layoutRaw } } = args;
|
|
197
|
+
const layout = variant === 'mobile'
|
|
198
|
+
? layoutRaw.mobile
|
|
199
|
+
: layoutRaw.desktop;
|
|
200
|
+
// determine list classes
|
|
201
|
+
let listClasses = '';
|
|
202
|
+
switch (layout) {
|
|
203
|
+
case 'row':
|
|
204
|
+
listClasses = 'grid grid-rows-1 auto-cols-auto grid-flow-col gap-l2';
|
|
205
|
+
break;
|
|
206
|
+
case 'column':
|
|
207
|
+
listClasses = 'flex flex-col gap-l2';
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
// return completed classes
|
|
211
|
+
return getPanelClasses(Object.assign(Object.assign({}, args), { className: listClasses }));
|
|
212
|
+
}
|
|
213
|
+
function renderGrid(args) {
|
|
214
|
+
// determine props
|
|
215
|
+
const { variant, parent, parentNested, item: { itemType, itemCount: itemCountRaw } } = args;
|
|
216
|
+
const itemCount = variant === 'mobile'
|
|
217
|
+
? itemCountRaw.mobile
|
|
218
|
+
: itemCountRaw.desktop;
|
|
219
|
+
const { panelClassName, panelItemClassName } = getGridPanelClasses(args);
|
|
220
|
+
// render grid (really a flexbox layout with controlled item widths)
|
|
221
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: getPanelWrapClasses(args), children: (0, jsx_runtime_1.jsx)("div", { className: panelClassName, children: funnel_core_1.ArrayUtils.series(itemCount, 1).map(row => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: renderListItem({
|
|
222
|
+
className: panelItemClassName,
|
|
223
|
+
variant,
|
|
224
|
+
parent,
|
|
225
|
+
parentNested,
|
|
226
|
+
layout: 'grid',
|
|
227
|
+
itemType, index: row,
|
|
228
|
+
count: itemCount
|
|
229
|
+
}) }, `list.${row}`)) }) }));
|
|
230
|
+
}
|
|
231
|
+
function getGridPanelClasses(args) {
|
|
232
|
+
// resolve props
|
|
233
|
+
const { variant, parent, parentNested, item: { itemType, itemCount: itemCountRaw, itemAlign: itemAlignRaw } } = args;
|
|
234
|
+
const itemAlign = variant === 'mobile'
|
|
235
|
+
? itemAlignRaw.mobile
|
|
236
|
+
: itemAlignRaw.desktop;
|
|
237
|
+
// determine list classes
|
|
238
|
+
const panelClasses = (0, classnames_1.default)('flex flex-wrap gap-l2', {
|
|
239
|
+
'justify-center': itemAlign === 'center',
|
|
240
|
+
'justify-end': itemAlign === 'end'
|
|
241
|
+
});
|
|
242
|
+
let panelItemClasses = '';
|
|
243
|
+
switch (itemType) {
|
|
244
|
+
case 'message':
|
|
245
|
+
case 'message+visual':
|
|
246
|
+
panelItemClasses = (0, classnames_1.default)({
|
|
247
|
+
'w-full': variant === 'mobile' || (variant === 'desktop' && (parent === 'row' || parentNested)),
|
|
248
|
+
'w-[50px]': variant === 'desktop' && parent !== 'row' && !parentNested
|
|
249
|
+
});
|
|
250
|
+
break;
|
|
251
|
+
case 'visual':
|
|
252
|
+
panelItemClasses = (0, classnames_1.default)({
|
|
253
|
+
'': variant === 'mobile' || (variant === 'desktop' && (parent === 'row' || parentNested)),
|
|
254
|
+
'flex-1': variant === 'desktop' && parent !== 'row' && !parentNested
|
|
255
|
+
});
|
|
256
|
+
break;
|
|
257
|
+
case 'icon':
|
|
258
|
+
panelItemClasses = (0, classnames_1.default)({});
|
|
259
|
+
break;
|
|
260
|
+
case 'logo':
|
|
261
|
+
panelItemClasses = (0, classnames_1.default)({
|
|
262
|
+
'': variant === 'desktop',
|
|
263
|
+
'': variant === 'mobile'
|
|
264
|
+
});
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
// return completed classes
|
|
268
|
+
return {
|
|
269
|
+
panelClassName: getPanelClasses(Object.assign(Object.assign({}, args), { className: panelClasses })),
|
|
270
|
+
panelItemClassName: panelItemClasses
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function renderListItem({ className, variant, parent, parentNested, layout, itemType, index, count }) {
|
|
274
|
+
let itemClassName = '';
|
|
275
|
+
switch (itemType) {
|
|
276
|
+
case 'message':
|
|
277
|
+
case 'message+visual':
|
|
278
|
+
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' &&
|
|
279
|
+
(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" })] })] }));
|
|
280
|
+
case 'visual': {
|
|
281
|
+
// determine aspect
|
|
282
|
+
let aspect;
|
|
283
|
+
switch (layout) {
|
|
284
|
+
case 'column':
|
|
285
|
+
aspect = parent === 'row' || parentNested
|
|
286
|
+
? 'widescreen'
|
|
287
|
+
: variant === 'mobile'
|
|
288
|
+
? 'widescreen'
|
|
289
|
+
: 'cinema';
|
|
290
|
+
break;
|
|
291
|
+
case 'row':
|
|
292
|
+
aspect = parent === 'row' || parentNested
|
|
293
|
+
? 'square'
|
|
294
|
+
: 'widescreen';
|
|
295
|
+
break;
|
|
296
|
+
case 'grid': {
|
|
297
|
+
// aspect for mobile/nested
|
|
298
|
+
if (variant === 'mobile' || parent === 'row' || parentNested) {
|
|
299
|
+
itemClassName = 'w-full';
|
|
300
|
+
aspect = count === 1
|
|
301
|
+
? 'square'
|
|
302
|
+
: count <= 3
|
|
303
|
+
? 'tv'
|
|
304
|
+
: 'widescreen';
|
|
305
|
+
}
|
|
306
|
+
// adjust aspect based on layout (if it's a grid)
|
|
307
|
+
else if (layout === 'grid') {
|
|
308
|
+
// set base class
|
|
309
|
+
itemClassName = 'min-w-[50px]';
|
|
310
|
+
// override base + pick aspect
|
|
311
|
+
switch (count) {
|
|
312
|
+
case 1:
|
|
313
|
+
aspect = 'widescreen';
|
|
314
|
+
break;
|
|
315
|
+
case 2:
|
|
316
|
+
aspect = 'widescreen';
|
|
317
|
+
break;
|
|
318
|
+
case 3:
|
|
319
|
+
itemClassName = index === 1
|
|
320
|
+
? 'min-w-full'
|
|
321
|
+
: 'min-w-[50px]';
|
|
322
|
+
aspect = index === 1
|
|
323
|
+
? 'cinema'
|
|
324
|
+
: 'tv';
|
|
325
|
+
break;
|
|
326
|
+
case 4:
|
|
327
|
+
aspect = 'tv';
|
|
328
|
+
break;
|
|
329
|
+
case 5:
|
|
330
|
+
itemClassName = index === 3
|
|
331
|
+
? 'min-w-full'
|
|
332
|
+
: 'min-w-[50px]';
|
|
333
|
+
aspect = index === 3
|
|
334
|
+
? 'cinema'
|
|
335
|
+
: 'tv';
|
|
336
|
+
break;
|
|
337
|
+
default:
|
|
338
|
+
aspect = 'widescreen';
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// otherwise standard
|
|
343
|
+
else {
|
|
344
|
+
aspect = 'widescreen';
|
|
345
|
+
}
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
// create visual
|
|
350
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, itemClassName), children: (0, jsx_runtime_1.jsx)(Skeleton.MediaPart, { aspect: aspect }) }));
|
|
351
|
+
}
|
|
352
|
+
case 'icon':
|
|
353
|
+
return ((0, jsx_runtime_1.jsx)(Skeleton.IconPart, { className: (0, classnames_1.default)(className, itemClassName), size: variant === 'mobile' ? 'md' : 'sm' }));
|
|
354
|
+
case 'logo':
|
|
355
|
+
return ((0, jsx_runtime_1.jsx)(Skeleton.LogoPart, { className: (0, classnames_1.default)(className, itemClassName), size: variant === 'mobile' ? 'md' : 'sm' }));
|
|
356
|
+
default:
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
166
359
|
}
|
|
167
|
-
function getPanelWrapClasses({ className, variant, parent, item: { mobileOrder, alignY, fullBleed }, itemPosition }) {
|
|
360
|
+
function getPanelWrapClasses({ className, variant, parent, parentNested, item: { mobileOrder, alignY, fullBleed }, itemPosition }) {
|
|
168
361
|
return variant === 'mobile'
|
|
169
362
|
? (0, classnames_1.default)(className, 'w-full flex flex-col', {
|
|
170
363
|
'justify-start': alignY === 'start',
|
|
@@ -178,18 +371,18 @@ function getPanelWrapClasses({ className, variant, parent, item: { mobileOrder,
|
|
|
178
371
|
'items-start': alignY === 'start',
|
|
179
372
|
'items-center': alignY === 'center',
|
|
180
373
|
'items-end': alignY === 'end',
|
|
181
|
-
'px-l4': parent !== 'row' && !fullBleed.desktop,
|
|
374
|
+
'px-l4': parent !== 'row' && !fullBleed.desktop && !parentNested,
|
|
182
375
|
'-ml-l4': itemPosition.left && fullBleed.desktop,
|
|
183
376
|
'-mr-l4': itemPosition.right && fullBleed.desktop
|
|
184
377
|
});
|
|
185
378
|
}
|
|
186
|
-
function getPanelClasses({ className, variant, parent, item: {
|
|
379
|
+
function getPanelClasses({ className, variant, parent, parentNested, item: { alignX, size } }) {
|
|
187
380
|
// force full width for mobile
|
|
188
381
|
if (variant === 'mobile') {
|
|
189
382
|
return (0, classnames_1.default)(className);
|
|
190
383
|
}
|
|
191
384
|
// or size for desktop
|
|
192
|
-
switch (size) {
|
|
385
|
+
switch (parent === 'row' || parentNested ? 'full' : size) {
|
|
193
386
|
case 'xs':
|
|
194
387
|
return (0, classnames_1.default)(className, 'col-span-4', {
|
|
195
388
|
'col-start-1': alignX === 'start',
|