@nascentdigital/funnel-editor 4.5.3 → 4.5.4
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/feedback/Note.d.ts +3 -1
- package/dist/core/components/feedback/Note.js +6 -3
- package/dist/core/components/fields/BooleanField.d.ts +3 -1
- package/dist/core/components/fields/BooleanField.js +2 -2
- package/dist/core/components/fields/DateField.d.ts +3 -1
- package/dist/core/components/fields/DateField.js +2 -2
- package/dist/core/components/fields/EnumField.d.ts +3 -1
- package/dist/core/components/fields/EnumField.js +4 -4
- package/dist/core/components/fields/FieldEditor.d.ts +3 -1
- package/dist/core/components/fields/FieldEditor.js +7 -7
- package/dist/core/components/fields/FieldHeader.d.ts +3 -1
- package/dist/core/components/fields/FieldHeader.js +18 -5
- package/dist/core/components/fields/FieldLayout.d.ts +3 -1
- package/dist/core/components/fields/FieldLayout.js +17 -4
- package/dist/core/components/fields/FieldSize.d.ts +1 -0
- package/dist/core/components/fields/FieldSize.js +2 -0
- package/dist/core/components/fields/FieldsPanel.js +5 -4
- package/dist/core/components/fields/RichTextEditor.d.ts +2 -3
- package/dist/core/components/fields/RichTextEditor.js +13 -10
- package/dist/core/components/fields/RichTextField.d.ts +1 -2
- package/dist/core/components/fields/RichTextField.js +4 -16
- package/dist/core/components/fields/TextField.d.ts +3 -2
- package/dist/core/components/fields/TextField.js +8 -7
- package/dist/core/components/fields/TimestampField.d.ts +3 -1
- package/dist/core/components/fields/TimestampField.js +2 -2
- package/dist/core/components/fields/index.d.ts +2 -0
- package/dist/core/components/fields/index.js +2 -0
- package/dist/core/components/fields/richtext/Theme.d.ts +1 -2
- package/dist/core/components/fields/richtext/Theme.js +2 -2
- package/dist/core/components/interaction/Button.js +3 -3
- package/dist/core/components/interaction/Combobox.d.ts +8 -1
- package/dist/core/components/interaction/Combobox.js +39 -12
- package/dist/core/components/interaction/IconButton.d.ts +2 -2
- package/dist/core/components/interaction/IconButton.js +2 -1
- package/dist/core/components/interaction/QuickEditor.d.ts +11 -0
- package/dist/core/components/interaction/QuickEditor.js +33 -0
- package/dist/core/components/interaction/QuickInput.js +1 -1
- package/dist/core/components/interaction/QuickPicker.js +5 -3
- package/dist/core/components/interaction/SegmentedButton.d.ts +3 -1
- package/dist/core/components/interaction/SegmentedButton.js +4 -1
- package/dist/core/components/interaction/SideSheet.js +1 -1
- package/dist/core/components/interaction/index.d.ts +1 -0
- package/dist/core/components/interaction/index.js +1 -0
- package/dist/core/components/visuals/Icon.d.ts +2 -2
- package/dist/core/components/visuals/Icon.js +5 -0
- package/dist/core/domain/BlockConfiguration.d.ts +15 -3
- package/dist/core/domain/BlockConfiguration.js +94 -27
- package/dist/page/components/config/BlockConfig.js +1 -1
- package/dist/page/components/config/BlockConfigEditor.js +26 -19
- package/dist/page/components/config/BlockPreview.d.ts +1 -1
- package/dist/page/components/config/BlockPreview.js +24 -18
- package/dist/page/components/config/ListPanelEditor.d.ts +4 -2
- package/dist/page/components/config/ListPanelEditor.js +52 -2
- package/dist/page/components/config/MessagePanelEditor.d.ts +4 -2
- package/dist/page/components/config/MessagePanelEditor.js +6 -2
- package/dist/page/components/config/VisualPanelEditor.d.ts +4 -2
- package/dist/page/components/config/VisualPanelEditor.js +65 -2
- package/dist/styles/index.css +256 -143
- package/dist/styles/tailwind.js +2 -0
- package/package.json +2 -2
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Schema } from '@nascentdigital/funnel-core';
|
|
2
2
|
import { EditorThemeClasses } from 'lexical';
|
|
3
|
-
import { RichTextEditor } from '../RichTextEditor';
|
|
4
3
|
export declare const listClassname: string;
|
|
5
4
|
export declare const listItemClassname: string;
|
|
6
|
-
export declare function getTheme(variant:
|
|
5
|
+
export declare function getTheme(variant: Schema.RichTextField.Semantics, options: Schema.RichTextField.Capabilities.Options): EditorThemeClasses;
|
|
@@ -24,8 +24,8 @@ function getTheme(variant, options) {
|
|
|
24
24
|
},
|
|
25
25
|
// text
|
|
26
26
|
paragraph: (0, classnames_1.default)('block min-h-body-sm last:mb-0', {
|
|
27
|
-
'mb-l5': variant === 'area',
|
|
28
|
-
'mb-l8': variant === 'editor',
|
|
27
|
+
'mb-l5': variant === 'area' || variant === 'mini-editor',
|
|
28
|
+
'mb-l8': variant === 'full-editor',
|
|
29
29
|
}),
|
|
30
30
|
quote: 'block pl-l6 mb-l8 last:mb-0 border-l-3 border-solid border-border-l1',
|
|
31
31
|
text: {
|
|
@@ -26,9 +26,9 @@ exports.Button = (0, react_1.forwardRef)(function Button(_a, ref) {
|
|
|
26
26
|
var { className, variant = 'primary', size = 'md', iconLeft, iconRight, loading = false, disabled = false, children } = _a, props = __rest(_a, ["className", "variant", "size", "iconLeft", "iconRight", "loading", "disabled", "children"]);
|
|
27
27
|
// render
|
|
28
28
|
return ((0, jsx_runtime_1.jsxs)("button", Object.assign({ ref: ref, className: (0, classnames_1.default)(className, getButtonClassnames({ variant, size, loading, disabled })), type: "button", disabled: disabled || loading }, props, { children: [loading &&
|
|
29
|
-
(0, jsx_runtime_1.jsx)(Loader_1.Loader, { size: "sm" }), iconLeft && !loading &&
|
|
30
|
-
(0, jsx_runtime_1.jsx)(visuals_1.Icon, { variant: iconLeft, size: size
|
|
31
|
-
(0, jsx_runtime_1.jsx)(visuals_1.Icon, { variant: iconRight, size: size
|
|
29
|
+
(0, jsx_runtime_1.jsx)(Loader_1.Loader, { size: "sm" }), iconLeft && !loading &&
|
|
30
|
+
(0, jsx_runtime_1.jsx)(visuals_1.Icon, { variant: iconLeft, size: size }), children, iconRight &&
|
|
31
|
+
(0, jsx_runtime_1.jsx)(visuals_1.Icon, { variant: iconRight, size: size })] })));
|
|
32
32
|
});
|
|
33
33
|
function getButtonClassnames({ variant, size, loading, disabled }) {
|
|
34
34
|
return (0, classnames_1.default)('button', {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Callback, Transform } from '@nascentdigital/funnel-core';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
+
import { FieldSize } from '../fields';
|
|
3
4
|
import { Icon } from '../visuals';
|
|
4
|
-
export declare function Combobox<TOptionId extends string>({ id: externalId, className, maxRows, rowHeight, disabled, options, noSelectionText, selectedOption: selectedOptionId, onSelect, renderSelection: renderSelectionRaw, renderOption, }: Combobox.Props<TOptionId>): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function Combobox<TOptionId extends string>({ id: externalId, className, size, maxRows, rowHeight: rowHeightRaw, disabled, options, noSelectionText, selectedOption: selectedOptionId, onSelect, renderSelection: renderSelectionRaw, renderOption, }: Combobox.Props<TOptionId>): import("react/jsx-runtime").JSX.Element;
|
|
5
6
|
export declare namespace Combobox {
|
|
6
7
|
type Props<TOptionId extends string> = {
|
|
7
8
|
id?: string;
|
|
8
9
|
className?: string;
|
|
10
|
+
size?: FieldSize;
|
|
9
11
|
maxRows?: number;
|
|
10
12
|
rowHeight?: number;
|
|
11
13
|
disabled?: boolean;
|
|
@@ -16,6 +18,10 @@ export declare namespace Combobox {
|
|
|
16
18
|
renderSelection?: Transform<Option<TOptionId> | undefined, ReactNode>;
|
|
17
19
|
renderOption?: Transform<RenderOptionArgs<TOptionId>, ReactNode>;
|
|
18
20
|
};
|
|
21
|
+
type RenderSelectionArgs<TOptionId extends string> = {
|
|
22
|
+
option?: Option<TOptionId>;
|
|
23
|
+
size: FieldSize;
|
|
24
|
+
};
|
|
19
25
|
type Option<TOptionId extends string = string> = Option.Standard<TOptionId> | Option.WithIcon<TOptionId>;
|
|
20
26
|
namespace Option {
|
|
21
27
|
type Standard<TOptionId extends string> = {
|
|
@@ -30,6 +36,7 @@ export declare namespace Combobox {
|
|
|
30
36
|
type RenderOptionArgs<TOptionId extends string = string> = {
|
|
31
37
|
option: Option<TOptionId>;
|
|
32
38
|
selected: boolean;
|
|
39
|
+
size: FieldSize;
|
|
33
40
|
};
|
|
34
41
|
interface Service {
|
|
35
42
|
}
|
|
@@ -12,7 +12,7 @@ const react_1 = require("react");
|
|
|
12
12
|
const visuals_1 = require("../visuals");
|
|
13
13
|
const Popup_1 = require("./Popup");
|
|
14
14
|
// component
|
|
15
|
-
function Combobox({ id: externalId, className, maxRows = 6, rowHeight
|
|
15
|
+
function Combobox({ id: externalId, className, size = 'md', maxRows = 6, rowHeight: rowHeightRaw, disabled = false, options, noSelectionText = 'Make a selection', selectedOption: selectedOptionId, onSelect = funnel_core_1.Fn.NoOp, renderSelection: renderSelectionRaw, renderOption = onRenderOption, }) {
|
|
16
16
|
// bind state
|
|
17
17
|
const [open, setOpen] = (0, react_1.useState)(false);
|
|
18
18
|
const buttonRef = (0, react_1.useRef)(null);
|
|
@@ -24,7 +24,19 @@ function Combobox({ id: externalId, className, maxRows = 6, rowHeight = 36, disa
|
|
|
24
24
|
&& options.find(option => option.id === selectedOptionId);
|
|
25
25
|
const renderSelection = (0, react_1.useMemo)(() => renderSelectionRaw
|
|
26
26
|
? renderSelectionRaw :
|
|
27
|
-
(option) => onRenderSelection(option, noSelectionText), [renderSelectionRaw, noSelectionText]);
|
|
27
|
+
(option) => onRenderSelection({ option, size }, noSelectionText), [renderSelectionRaw, size, noSelectionText]);
|
|
28
|
+
const rowHeight = rowHeightRaw
|
|
29
|
+
? rowHeightRaw
|
|
30
|
+
: size === 'md'
|
|
31
|
+
? 36
|
|
32
|
+
: size === 'sm'
|
|
33
|
+
? 32
|
|
34
|
+
: 24;
|
|
35
|
+
const rowPaddingY = size === 'md'
|
|
36
|
+
? 8
|
|
37
|
+
: size === 'sm'
|
|
38
|
+
? 6
|
|
39
|
+
: 3;
|
|
28
40
|
// helpers
|
|
29
41
|
const onOpen = (e) => {
|
|
30
42
|
// stop propagation
|
|
@@ -47,21 +59,30 @@ function Combobox({ id: externalId, className, maxRows = 6, rowHeight = 36, disa
|
|
|
47
59
|
setOpen(false);
|
|
48
60
|
};
|
|
49
61
|
// render
|
|
50
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { ref: buttonRef, id: id, className: (0, classnames_1.default)(className, '
|
|
62
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { ref: buttonRef, id: id, className: (0, classnames_1.default)(className, 'flex items-center justify-between gap-l5 px-l5', 'bg-surface1 border border-solid border-border-l1 rounded-full select-none appearance-none', 'disabled:opacity-disabled', {
|
|
63
|
+
'min-w-[200px] h-40': size === 'md',
|
|
64
|
+
'min-w-[180px] h-32': size === 'sm',
|
|
65
|
+
'min-w-[120px] h-24': size === 'xs',
|
|
51
66
|
'pointer-events-none': open
|
|
52
|
-
}), type: "button", disabled: disabled, role: "combobox", "aria-expanded": open, "aria-controls": popupId, "aria-owns": popupId, onClick: onOpen, onKeyDown: client_1.OnKey.enter(onOpen), children: [renderSelection(selectedOption), (0, jsx_runtime_1.jsx)(visuals_1.Icon, { className: "text-content-primary", variant: "ChevronDown" })] }), (0, jsx_runtime_1.jsx)(Popup_1.Popup, { open: open, anchor: button, anchorOffset: 2, placement: "bottom", onClose: onOptionsClose, children: (0, jsx_runtime_1.jsx)("div", { id: popupId, className: (0, classnames_1.default)('flex flex-col
|
|
67
|
+
}), type: "button", disabled: disabled, role: "combobox", "aria-expanded": open, "aria-controls": popupId, "aria-owns": popupId, onClick: onOpen, onKeyDown: client_1.OnKey.enter(onOpen), children: [renderSelection(selectedOption), (0, jsx_runtime_1.jsx)(visuals_1.Icon, { className: "text-content-primary", variant: "ChevronDown" })] }), (0, jsx_runtime_1.jsx)(Popup_1.Popup, { open: open, anchor: button, anchorOffset: 2, placement: "bottom", onClose: onOptionsClose, children: (0, jsx_runtime_1.jsx)("div", { id: popupId, className: (0, classnames_1.default)('flex flex-col bg-surface2 shadow-popup overflow-y-scroll', {
|
|
68
|
+
'py-l4 rounded-lg': size === 'md',
|
|
69
|
+
'py-l3 rounded-md': size !== 'md'
|
|
70
|
+
}), style: {
|
|
53
71
|
minWidth: button ? `${button.offsetWidth}px` : 'auto',
|
|
54
|
-
maxHeight: maxRows * rowHeight +
|
|
72
|
+
maxHeight: maxRows * rowHeight + (rowPaddingY * 2)
|
|
55
73
|
}, role: "listbox", children: options.map((option, index) => {
|
|
56
74
|
// render
|
|
57
75
|
const optionKey = getOptionId(id, option);
|
|
58
76
|
const selected = option.id === selectedOptionId;
|
|
59
|
-
return ((0, jsx_runtime_1.jsx)("button", { id: optionKey, style: { height: `${rowHeight}px` }, role: "option", "aria-selected": selected, autoFocus: (index === 0 && !selected) || (index === 1 && options[0].id === selectedOptionId), disabled: selected, onClick: e => onOptionSelect(e, option), onKeyDown: client_1.OnKey.enter(e => onOptionSelect(e, option)), children: (0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)('h-full flex items-center justify-between
|
|
77
|
+
return ((0, jsx_runtime_1.jsx)("button", { id: optionKey, style: { height: `${rowHeight}px` }, role: "option", "aria-selected": selected, autoFocus: (index === 0 && !selected) || (index === 1 && options[0].id === selectedOptionId), disabled: selected, onClick: e => onOptionSelect(e, option), onKeyDown: client_1.OnKey.enter(e => onOptionSelect(e, option)), children: (0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)('h-full flex items-center justify-between appearance-none select-none outline-none interpolate', {
|
|
78
|
+
'gap-l4 px-l6': size === 'md',
|
|
79
|
+
'gap-l3 px-l5': size === 'sm',
|
|
80
|
+
'gap-l2 px-l4': size === 'xs',
|
|
60
81
|
'text-content-link-highlight': selected,
|
|
61
82
|
'text-content-primary hover:bg-ix-util-hover/tint1 active:bg-ix-util-press/tint2': !selected && !disabled,
|
|
62
83
|
'focus-visible:bg-interactive focus-visible:border-border-l1': !selected && !disabled,
|
|
63
84
|
'text-ix-disabled-content': disabled
|
|
64
|
-
}), children: renderOption({ option, selected }) }) }, optionKey));
|
|
85
|
+
}), children: renderOption({ option, selected, size }) }) }, optionKey));
|
|
65
86
|
}) }) })] }));
|
|
66
87
|
}
|
|
67
88
|
// extension
|
|
@@ -79,16 +100,22 @@ function Combobox({ id: externalId, className, maxRows = 6, rowHeight = 36, disa
|
|
|
79
100
|
function getOptionId(comboboxId, option) {
|
|
80
101
|
return `${comboboxId}::option::${option.id}`;
|
|
81
102
|
}
|
|
82
|
-
function onRenderSelection(option, noSelectionText) {
|
|
103
|
+
function onRenderSelection({ option, size }, noSelectionText) {
|
|
83
104
|
var _a;
|
|
84
|
-
return ((0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)('inline-block
|
|
105
|
+
return ((0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)('inline-block', {
|
|
106
|
+
'body-sm': size === 'md',
|
|
107
|
+
'label-sm': size === 'sm',
|
|
108
|
+
'label-xs': size === 'xs',
|
|
85
109
|
'text-content-primary': !!option,
|
|
86
110
|
'text-ix-disabled-content': !option
|
|
87
111
|
}), children: (_a = option === null || option === void 0 ? void 0 : option.label) !== null && _a !== void 0 ? _a : noSelectionText }));
|
|
88
112
|
}
|
|
89
|
-
function onRenderOption({ option, selected }) {
|
|
90
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)('inline-block
|
|
113
|
+
function onRenderOption({ option, selected, size }) {
|
|
114
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)('inline-block', {
|
|
115
|
+
'label-md': size === 'md',
|
|
116
|
+
'label-sm': size === 'sm',
|
|
117
|
+
'label-xs': size === 'xs',
|
|
91
118
|
'label-strong': selected
|
|
92
119
|
}), children: option.label }), selected &&
|
|
93
|
-
(0, jsx_runtime_1.jsx)(visuals_1.Icon, { variant: "Check" })] }));
|
|
120
|
+
(0, jsx_runtime_1.jsx)(visuals_1.Icon, { variant: "Check", size: size })] }));
|
|
94
121
|
}
|
|
@@ -3,7 +3,7 @@ import { Icon } from '../visuals';
|
|
|
3
3
|
export declare const IconButton: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLButtonElement>, "children"> & {
|
|
4
4
|
variant?: IconButton.Variant;
|
|
5
5
|
icon: Icon.Variant;
|
|
6
|
-
size?: Extract<Icon.Size, "md" | "sm" | "xs">;
|
|
6
|
+
size?: Extract<Icon.Size, "md" | "sm" | "xs" | "xxs">;
|
|
7
7
|
active?: boolean;
|
|
8
8
|
disabled?: boolean;
|
|
9
9
|
} & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -11,7 +11,7 @@ export declare namespace IconButton {
|
|
|
11
11
|
type Props = Omit<HTMLAttributes<HTMLButtonElement>, 'children'> & {
|
|
12
12
|
variant?: Variant;
|
|
13
13
|
icon: Icon.Variant;
|
|
14
|
-
size?: Extract<Icon.Size, 'md' | 'sm' | 'xs'>;
|
|
14
|
+
size?: Extract<Icon.Size, 'md' | 'sm' | 'xs' | 'xxs'>;
|
|
15
15
|
active?: boolean;
|
|
16
16
|
disabled?: boolean;
|
|
17
17
|
};
|
|
@@ -36,6 +36,7 @@ function getIconButtonClassnames({ variant, size, active, disabled }) {
|
|
|
36
36
|
'iconbutton-disabled': disabled,
|
|
37
37
|
'iconbutton-md': size === 'md',
|
|
38
38
|
'iconbutton-sm': size === 'sm',
|
|
39
|
-
'iconbutton-xs': size === 'xs'
|
|
39
|
+
'iconbutton-xs': size === 'xs',
|
|
40
|
+
'iconbutton-xxs': size === 'xxs'
|
|
40
41
|
});
|
|
41
42
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { Popup } from './Popup';
|
|
3
|
+
export declare function QuickEditor({ className, title, tip, size, open, onClose, children, ...props }: QuickEditor.Props): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export declare namespace QuickEditor {
|
|
5
|
+
type Props = Popup.Props & {
|
|
6
|
+
title: ReactNode;
|
|
7
|
+
tip?: string;
|
|
8
|
+
size?: Size;
|
|
9
|
+
};
|
|
10
|
+
type Size = 'md' | 'sm';
|
|
11
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
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.QuickEditor = QuickEditor;
|
|
18
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
|
+
const funnel_ui_1 = require("@nascentdigital/funnel-ui");
|
|
20
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
21
|
+
const feedback_1 = require("../feedback");
|
|
22
|
+
const IconButton_1 = require("./IconButton");
|
|
23
|
+
const Popup_1 = require("./Popup");
|
|
24
|
+
// component
|
|
25
|
+
function QuickEditor(_a) {
|
|
26
|
+
var { className, title, tip, size = 'md', open = false, onClose, children } = _a, props = __rest(_a, ["className", "title", "tip", "size", "open", "onClose", "children"]);
|
|
27
|
+
// render
|
|
28
|
+
return ((0, jsx_runtime_1.jsxs)(Popup_1.Popup, Object.assign({}, props, { className: (0, classnames_1.default)(className, 'flex flex-col', 'bg-surface1 border-solid border-border-l1 shadow-miniEditor', 'border border-solid border-border-l1 rounded-md overflow-hidden', {
|
|
29
|
+
'w-[320px]': size === 'md',
|
|
30
|
+
'w-[288px]': size === 'sm'
|
|
31
|
+
}), open: open, onClose: onClose, children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-content-primary flex justify-between items-center gap-l8 px-l8 pt-l8 pb-l4", children: [(0, jsx_runtime_1.jsx)("h2", { className: "heading-sm text-pretty", children: title }), (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { className: "shrink-0", icon: "X", size: "xs", onClick: onClose })] }), tip &&
|
|
32
|
+
(0, jsx_runtime_1.jsx)(feedback_1.Note, { className: "mt-l2 mb-l4 mx-l8", variant: "tip", size: size === 'md' ? 'sm' : 'xs', children: (0, jsx_runtime_1.jsx)(funnel_ui_1.Markup, { markdown: `**Tip:** ${tip}` }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 px-l8 pt-l4 pb-l8 overflow-y-scroll", children: children })] })));
|
|
33
|
+
}
|
|
@@ -140,7 +140,7 @@ function renderInput({ field, onKeyDown }) {
|
|
|
140
140
|
const { schema } = field;
|
|
141
141
|
switch (schema.type) {
|
|
142
142
|
case 'text':
|
|
143
|
-
return ((0, jsx_runtime_1.jsx)(TextField_1.TextField, { className: "flex-1", field: field, variant: "minimal",
|
|
143
|
+
return ((0, jsx_runtime_1.jsx)(TextField_1.TextField, { className: "flex-1", field: field, variant: "minimal", size: "sm", autoFocus: true, onKeyDown: onKeyDown }));
|
|
144
144
|
case 'richtext':
|
|
145
145
|
return ((0, jsx_runtime_1.jsx)(fields_1.RichTextField, { className: "flex-1", field: field, minimal: true, autoFocus: true }));
|
|
146
146
|
default:
|
|
@@ -88,12 +88,14 @@ exports.QuickPicker = (0, react_1.forwardRef)(function QuickPicker({ variant, ti
|
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
// render
|
|
91
|
-
return ((0, jsx_runtime_1.jsxs)(Popup_1.Popup, Object.assign({}, (popupProps !== null && popupProps !== void 0 ? popupProps : {}), { className: (0, classnames_1.default)('glass-overlay w-[
|
|
91
|
+
return ((0, jsx_runtime_1.jsxs)(Popup_1.Popup, Object.assign({}, (popupProps !== null && popupProps !== void 0 ? popupProps : {}), { className: (0, classnames_1.default)('glass-overlay max-w-[380px] flex flex-col gap-l8 pt-l8 interpolate', 'border border-solid border-glass-stroke-l1/tint5 rounded-md', {
|
|
92
92
|
'opacity-none': !opened,
|
|
93
93
|
'opacity-full': opened
|
|
94
94
|
}), animation: "out", open: !!deferral, onOpened: () => setOpened(true), onClose: onClose, onClosed: () => setOpened(false), children: [(0, jsx_runtime_1.jsxs)("section", { className: "px-l8", children: [(0, jsx_runtime_1.jsx)("h3", { className: "heading-sm text-content-primary", children: title }), description &&
|
|
95
95
|
(0, jsx_runtime_1.jsx)("p", { className: "body-sm text-content-secondary", children: description })] }), (0, jsx_runtime_1.jsx)("section", { className: (0, classnames_1.default)({
|
|
96
|
-
'flex flex-wrap
|
|
96
|
+
'flex flex-wrap gap-l5 items-center px-l8 pb-l8 overflow-y-scroll': variant === 'card',
|
|
97
|
+
'w-[288px]': variant === 'card' && items.length < 4,
|
|
98
|
+
'w-[372px] max-h-[213px]': variant === 'card' && items.length >= 4
|
|
97
99
|
}), children: items.map(item => renderCard({
|
|
98
100
|
item,
|
|
99
101
|
content: renderItem(item),
|
|
@@ -102,7 +104,7 @@ exports.QuickPicker = (0, react_1.forwardRef)(function QuickPicker({ variant, ti
|
|
|
102
104
|
})) })] })));
|
|
103
105
|
});
|
|
104
106
|
function renderCard({ item, content, selected, onSelect }) {
|
|
105
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('FieldCard w-[
|
|
107
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('FieldCard w-[72px] h-[55px]', {
|
|
106
108
|
'FieldCard-selected': selected
|
|
107
109
|
}), onClick: () => onSelect(item.id), children: content }, item.id));
|
|
108
110
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Callback } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { FieldSize } from '../fields';
|
|
2
3
|
import { Icon } from '../visuals';
|
|
3
|
-
export declare function SegmentedButton<TOption extends SegmentedButton.OptionType>({ className, options, selected, allowEmpty, multiSelect, autoFocus, disabled, onSelectionChange, onBlur }: SegmentedButton.Props<TOption>): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export declare function SegmentedButton<TOption extends SegmentedButton.OptionType>({ className, size, options, selected, allowEmpty, multiSelect, autoFocus, disabled, onSelectionChange, onBlur }: SegmentedButton.Props<TOption>): import("react/jsx-runtime").JSX.Element;
|
|
4
5
|
export declare namespace SegmentedButton {
|
|
5
6
|
type OptionType = string | number;
|
|
6
7
|
type Props<TOption extends OptionType> = {
|
|
7
8
|
className?: string;
|
|
9
|
+
size?: FieldSize;
|
|
8
10
|
options: ReadonlyArray<Option<TOption>>;
|
|
9
11
|
selected?: TOption | ReadonlyArray<TOption>;
|
|
10
12
|
allowEmpty?: boolean;
|
|
@@ -11,7 +11,7 @@ const ms_1 = __importDefault(require("ms"));
|
|
|
11
11
|
const react_1 = require("react");
|
|
12
12
|
const visuals_1 = require("../visuals");
|
|
13
13
|
// component
|
|
14
|
-
function SegmentedButton({ className, options, selected = [], allowEmpty = false, multiSelect = false, autoFocus = false, disabled = false, onSelectionChange, onBlur = funnel_core_1.Fn.NoOp }) {
|
|
14
|
+
function SegmentedButton({ className, size = 'md', options, selected = [], allowEmpty = false, multiSelect = false, autoFocus = false, disabled = false, onSelectionChange, onBlur = funnel_core_1.Fn.NoOp }) {
|
|
15
15
|
// bind ref data
|
|
16
16
|
const blurTimeoutRef = (0, react_1.useRef)(undefined);
|
|
17
17
|
const selectedOptions = Array.isArray(selected)
|
|
@@ -68,6 +68,9 @@ function SegmentedButton({ className, options, selected = [], allowEmpty = false
|
|
|
68
68
|
}), children: options.map(({ id, value, label, icon }) => {
|
|
69
69
|
const active = selectedOptions.includes(value);
|
|
70
70
|
return ((0, jsx_runtime_1.jsxs)("button", { type: "button", disabled: disabled, className: (0, classnames_1.default)('segmented-button', {
|
|
71
|
+
'segmented-button-md': size === 'md',
|
|
72
|
+
'segmented-button-sm': size === 'sm',
|
|
73
|
+
'segmented-button-xs': size === 'xs',
|
|
71
74
|
'segmented-button-selected': active
|
|
72
75
|
}), onClick: () => onSelect(value), onFocus: onSegmentFocus, onBlur: onSegmentBlur, children: [icon &&
|
|
73
76
|
(0, jsx_runtime_1.jsx)(visuals_1.Icon, { className: "segmented-button-icon", variant: icon, size: "nav" }), (0, jsx_runtime_1.jsx)("span", { className: "segmented-button-label", children: label })] }, id));
|
|
@@ -154,7 +154,7 @@ function SideSheet(_a) {
|
|
|
154
154
|
'w-full md:w-screen-sm': size === 'lg'
|
|
155
155
|
}), variants: breakpoint === 'xs' || breakpoint === 'sm'
|
|
156
156
|
? Animate_1.Animate.Variants.slideFromBottom
|
|
157
|
-
: Animate_1.Animate.Variants.slideFromLeft, initial: "initial", animate: "animate", exit: "exit", onAnimationComplete: definition => onAnimationComplete(definition), onKeyDown: onKeyDown, tabIndex: -1, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(className, 'w-full h-full max-h-full pointer-events-auto', 'flex flex-col', 'bg-background border-solid border-border-l1', 'max-md:border-t max-md:rounded-tl-md max-md:rounded-tr-md', 'md:border-l md:rounded-tl-md md:rounded-bl-md'), children: [(0, jsx_runtime_1.jsx)("h2", { className: "heading-
|
|
157
|
+
: Animate_1.Animate.Variants.slideFromLeft, initial: "initial", animate: "animate", exit: "exit", onAnimationComplete: definition => onAnimationComplete(definition), onKeyDown: onKeyDown, tabIndex: -1, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(className, 'w-full h-full max-h-full pointer-events-auto', 'flex flex-col', 'bg-background border-solid border-border-l1', 'max-md:border-t max-md:rounded-tl-md max-md:rounded-tr-md', 'md:border-l md:rounded-tl-md md:rounded-bl-md'), children: [(0, jsx_runtime_1.jsx)("h2", { className: "heading-sm text-content-primary px-l8 pt-l8 pb-l4", children: title }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 px-l8 pt-l4 pb-l8 overflow-y-scroll", children: children }), (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('flex justify-end items-center gap-l4 p-l8', 'border-t border-solid border-border-l1'), children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "text", size: "sm", disabled: locked, onClick: onClose, children: "Cancel" }), customActions &&
|
|
158
158
|
(0, jsx_runtime_1.jsx)("div", { className: "flex-1 flex justify-end items-center gap-l4", children: customActions }), (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "primary", size: "sm", loading: state === 'saving', disabled: disableSave || locked, onClick: onSave, children: renderSaveLabel(state) })] })] }) }))] }, id) }), document.body);
|
|
159
159
|
}
|
|
160
160
|
// helpers
|
|
@@ -38,6 +38,7 @@ __exportStar(require("./NavButton"), exports);
|
|
|
38
38
|
__exportStar(require("./Picker"), exports);
|
|
39
39
|
__exportStar(require("./Popup"), exports);
|
|
40
40
|
__exportStar(require("./Profile"), exports);
|
|
41
|
+
__exportStar(require("./QuickEditor"), exports);
|
|
41
42
|
__exportStar(require("./QuickInput"), exports);
|
|
42
43
|
__exportStar(require("./QuickPicker"), exports);
|
|
43
44
|
__exportStar(require("./SegmentedButton"), exports);
|
|
@@ -5,8 +5,8 @@ export declare namespace Icon {
|
|
|
5
5
|
variant: Variant;
|
|
6
6
|
size?: Size;
|
|
7
7
|
};
|
|
8
|
-
type Size = 'xl' | 'lg' | 'md' | 'sm' | 'xs' | 'nav' | 'card' | Sizing;
|
|
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';
|
|
8
|
+
type Size = 'xl' | 'lg' | 'md' | 'sm' | 'xs' | 'xxs' | 'nav' | 'card' | Sizing;
|
|
9
|
+
type Variant = 'Archive' | 'ArrowLeft' | 'ArrowRight' | '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
|
+
'ArrowRight',
|
|
23
24
|
'ArrowLeftRight',
|
|
24
25
|
'Atom',
|
|
25
26
|
'Blocks',
|
|
@@ -112,6 +113,8 @@ function getIcon(variant) {
|
|
|
112
113
|
return lucide_react_1.Archive;
|
|
113
114
|
case 'ArrowLeft':
|
|
114
115
|
return lucide_react_1.ArrowLeft;
|
|
116
|
+
case 'ArrowRight':
|
|
117
|
+
return lucide_react_1.ArrowRight;
|
|
115
118
|
case 'ArrowLeftRight':
|
|
116
119
|
return lucide_react_1.ArrowLeftRight;
|
|
117
120
|
case 'Atom':
|
|
@@ -281,6 +284,8 @@ function getSizing(size) {
|
|
|
281
284
|
return { size: 16, strokeWidth: 2 };
|
|
282
285
|
case 'xs':
|
|
283
286
|
return { size: 14, strokeWidth: 2 };
|
|
287
|
+
case 'xxs':
|
|
288
|
+
return { size: 10, strokeWidth: 1, absoluteStrokeWidth: true };
|
|
284
289
|
default:
|
|
285
290
|
return { size: 20, strokeWidth: 2 };
|
|
286
291
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BlockLayout, EventBus, Field, FieldModel, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
-
import { PanelLayout, SlotVariation } from '@nascentdigital/funnel-ui';
|
|
2
|
+
import { ListPanel, MessagePanel, PanelLayout, SlotVariation, VisualPanel } from '@nascentdigital/funnel-ui';
|
|
3
3
|
import { Block } from './Block';
|
|
4
4
|
import { IAssetStore } from './IAssetStore';
|
|
5
5
|
import { SectionBlock } from './SectionBlock';
|
|
@@ -11,6 +11,7 @@ export declare class BlockConfiguration {
|
|
|
11
11
|
readonly fields: ReadonlyArray<FieldModel.Config>;
|
|
12
12
|
private _editableFields;
|
|
13
13
|
private _layout?;
|
|
14
|
+
private _slotState;
|
|
14
15
|
private _defaultConfig?;
|
|
15
16
|
private _isConfigInDefault?;
|
|
16
17
|
constructor({ block: blockOrSectionBlock, assetStore }: BlockConfiguration.ConstructorArgs);
|
|
@@ -23,14 +24,19 @@ export declare class BlockConfiguration {
|
|
|
23
24
|
get nameField(): FieldModel.Config | undefined;
|
|
24
25
|
get themeField(): FieldModel.Config | undefined;
|
|
25
26
|
get layoutField(): Field<Schema.EnumField<Schema.EnumField.Options<PanelLayout>>> | undefined;
|
|
26
|
-
get
|
|
27
|
-
get slotOptions(): string[];
|
|
27
|
+
get slotState(): Readonly<BlockConfiguration.SlotState>;
|
|
28
28
|
gotToNextSlot(): void;
|
|
29
|
+
gotToPreviousSlot(): void;
|
|
30
|
+
get messageFields(): Record<keyof MessagePanel.Config.Keys<'message'>, FieldModel.Config | undefined>;
|
|
31
|
+
get listFields(): Record<keyof ListPanel.Config.Keys<'list'>, FieldModel.Config | undefined>;
|
|
32
|
+
get visualFields(): Record<keyof VisualPanel.Config.Keys<'visual'>, FieldModel.Config | undefined>;
|
|
29
33
|
get layout(): BlockLayout | undefined;
|
|
30
34
|
get events$(): import("rxjs").Observable<EventBus.Event<string, string>>;
|
|
31
35
|
get valid(): boolean;
|
|
32
36
|
get modified(): boolean;
|
|
33
37
|
getField(fieldId: string): FieldModel;
|
|
38
|
+
getFieldData(fieldId: string): Schema.Field.LinkedData | undefined;
|
|
39
|
+
getEditableField(fieldId: string): FieldModel.Config | undefined;
|
|
34
40
|
save(): void;
|
|
35
41
|
reset(): void;
|
|
36
42
|
get isConfigInDefault(): boolean | undefined;
|
|
@@ -38,6 +44,12 @@ export declare class BlockConfiguration {
|
|
|
38
44
|
private raiseEvent;
|
|
39
45
|
}
|
|
40
46
|
export declare namespace BlockConfiguration {
|
|
47
|
+
type SlotState = {
|
|
48
|
+
field?: Field<Schema.EnumField<Schema.EnumField.Options<SlotVariation>>>;
|
|
49
|
+
options: ReadonlyArray<SlotVariation>;
|
|
50
|
+
currentOption?: SlotVariation | undefined;
|
|
51
|
+
currentIndex?: number;
|
|
52
|
+
};
|
|
41
53
|
type ConstructorArgs = {
|
|
42
54
|
assetStore: IAssetStore;
|
|
43
55
|
block: Block | SectionBlock;
|
|
@@ -16,6 +16,7 @@ class BlockConfiguration {
|
|
|
16
16
|
this.fields = fields;
|
|
17
17
|
this._editableFields = fields;
|
|
18
18
|
this._isConfigInDefault = false;
|
|
19
|
+
this._slotState = { options: [] };
|
|
19
20
|
// initialize section block
|
|
20
21
|
if (blockOrSectionBlock instanceof SectionBlock_1.SectionBlock) {
|
|
21
22
|
// capture parents
|
|
@@ -28,7 +29,6 @@ class BlockConfiguration {
|
|
|
28
29
|
}
|
|
29
30
|
// or regular block
|
|
30
31
|
else {
|
|
31
|
-
// capture parent
|
|
32
32
|
this.block = blockOrSectionBlock;
|
|
33
33
|
}
|
|
34
34
|
// add fields
|
|
@@ -76,7 +76,7 @@ class BlockConfiguration {
|
|
|
76
76
|
}
|
|
77
77
|
get desktopFields() {
|
|
78
78
|
return [
|
|
79
|
-
this.
|
|
79
|
+
this.getEditableField('contentAlign')
|
|
80
80
|
].filter(funnel_core_1.Value.isDefined);
|
|
81
81
|
}
|
|
82
82
|
get mobileFields() {
|
|
@@ -85,45 +85,74 @@ class BlockConfiguration {
|
|
|
85
85
|
get nameField() {
|
|
86
86
|
const { block, sectionBlock } = this;
|
|
87
87
|
return sectionBlock
|
|
88
|
-
? this.
|
|
88
|
+
? this.getEditableField(block.nameField.id)
|
|
89
89
|
: undefined;
|
|
90
90
|
}
|
|
91
91
|
get themeField() {
|
|
92
|
-
return this.
|
|
92
|
+
return this.getEditableField(funnel_ui_1.BlockConfig.Presets.ThemeOnly.key);
|
|
93
93
|
}
|
|
94
94
|
get layoutField() {
|
|
95
95
|
return this._editableFields.find(field => field.id === 'layout');
|
|
96
96
|
}
|
|
97
|
-
get
|
|
98
|
-
return this.
|
|
99
|
-
}
|
|
100
|
-
get slotOptions() {
|
|
101
|
-
const slotField = this.slotField;
|
|
102
|
-
return slotField ? Object.keys(slotField.schema.options) : [];
|
|
97
|
+
get slotState() {
|
|
98
|
+
return this._slotState;
|
|
103
99
|
}
|
|
104
100
|
gotToNextSlot() {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (!slotField) {
|
|
101
|
+
// skip if there's no options
|
|
102
|
+
const { field, options, currentIndex } = this._slotState;
|
|
103
|
+
if (!field || options.length < 0 || currentIndex === undefined) {
|
|
109
104
|
return;
|
|
110
105
|
}
|
|
111
|
-
//
|
|
112
|
-
const
|
|
113
|
-
|
|
106
|
+
// update the slot
|
|
107
|
+
const newIndex = (currentIndex + 1) % options.length;
|
|
108
|
+
const newOption = options[newIndex];
|
|
109
|
+
this._slotState = {
|
|
110
|
+
field, options, currentIndex: newIndex, currentOption: newOption
|
|
111
|
+
};
|
|
112
|
+
field.value = funnel_core_1.Schema.EnumField.Value.toData(newOption);
|
|
113
|
+
}
|
|
114
|
+
gotToPreviousSlot() {
|
|
115
|
+
// skip if there's no options
|
|
116
|
+
const { field, options, currentIndex } = this._slotState;
|
|
117
|
+
if (!field || options.length < 0 || currentIndex === undefined) {
|
|
114
118
|
return;
|
|
115
119
|
}
|
|
116
|
-
// get all the available slot options
|
|
117
|
-
const options = this.slotOptions;
|
|
118
|
-
// compute the next index and account for being out of bound
|
|
119
|
-
let nextIndex = options.indexOf(currentValue) + 1;
|
|
120
|
-
if (nextIndex > options.length - 1) {
|
|
121
|
-
nextIndex = 0;
|
|
122
|
-
}
|
|
123
|
-
// get the next slot value
|
|
124
|
-
const nextSlot = options[nextIndex];
|
|
125
120
|
// update the slot
|
|
126
|
-
|
|
121
|
+
const newIndex = currentIndex === 0
|
|
122
|
+
? options.length - 1
|
|
123
|
+
: currentIndex - 1;
|
|
124
|
+
const newOption = options[newIndex];
|
|
125
|
+
this._slotState = {
|
|
126
|
+
field, options, currentIndex: newIndex, currentOption: newOption
|
|
127
|
+
};
|
|
128
|
+
field.value = funnel_core_1.Schema.EnumField.Value.toData(newOption);
|
|
129
|
+
}
|
|
130
|
+
get messageFields() {
|
|
131
|
+
const keys = funnel_ui_1.MessagePanel.Config.getKeys('message');
|
|
132
|
+
return {
|
|
133
|
+
textAlign: this.getEditableField(keys.textAlign),
|
|
134
|
+
width: this.getEditableField(keys.width),
|
|
135
|
+
horizontalAlign: this.getEditableField(keys.horizontalAlign),
|
|
136
|
+
verticalAlign: this.getEditableField(keys.verticalAlign)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
get listFields() {
|
|
140
|
+
const keys = funnel_ui_1.ListPanel.Config.getKeys('list');
|
|
141
|
+
return {
|
|
142
|
+
layout: this.getEditableField(keys.layout),
|
|
143
|
+
width: this.getEditableField(keys.width),
|
|
144
|
+
horizontalAlign: this.getEditableField(keys.horizontalAlign),
|
|
145
|
+
verticalAlign: this.getEditableField(keys.verticalAlign)
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
get visualFields() {
|
|
149
|
+
const keys = funnel_ui_1.VisualPanel.Config.getKeys('visual');
|
|
150
|
+
return {
|
|
151
|
+
aspect: this.getEditableField(keys.aspect),
|
|
152
|
+
anchor: this.getEditableField(keys.anchor),
|
|
153
|
+
width: this.getEditableField(keys.width),
|
|
154
|
+
horizontalAlign: this.getEditableField(keys.horizontalAlign)
|
|
155
|
+
};
|
|
127
156
|
}
|
|
128
157
|
get layout() {
|
|
129
158
|
return this._layout;
|
|
@@ -152,6 +181,32 @@ class BlockConfiguration {
|
|
|
152
181
|
// return field
|
|
153
182
|
return field;
|
|
154
183
|
}
|
|
184
|
+
getFieldData(fieldId) {
|
|
185
|
+
// skip if it's not there
|
|
186
|
+
const { block, assetStore } = this;
|
|
187
|
+
const field = block.fields.find(field => field.id === fieldId);
|
|
188
|
+
if (!field) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
// link assets
|
|
192
|
+
const fieldValue = field.value;
|
|
193
|
+
if ((fieldValue === null || fieldValue === void 0 ? void 0 : fieldValue.type) === 'asset') {
|
|
194
|
+
const assetData = funnel_core_1.Schema.AssetField.Value.fromData(fieldValue);
|
|
195
|
+
const asset = (assetData === null || assetData === void 0 ? void 0 : assetData.id)
|
|
196
|
+
? assetStore.getAsset(assetData === null || assetData === void 0 ? void 0 : assetData.id)
|
|
197
|
+
: undefined;
|
|
198
|
+
return assetData && asset
|
|
199
|
+
? funnel_core_1.Schema.AssetField.LinkedValue.toData(funnel_core_1.Schema.AssetField.Value.toLinked(assetData, asset))
|
|
200
|
+
: undefined;
|
|
201
|
+
}
|
|
202
|
+
// or return other values as-is
|
|
203
|
+
else {
|
|
204
|
+
return fieldValue;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
getEditableField(fieldId) {
|
|
208
|
+
return this._editableFields.find(field => field.id === fieldId);
|
|
209
|
+
}
|
|
155
210
|
save() {
|
|
156
211
|
// save each modified field
|
|
157
212
|
const { sectionBlock, block, editableFields } = this;
|
|
@@ -233,6 +288,7 @@ class BlockConfiguration {
|
|
|
233
288
|
return this._isConfigInDefault;
|
|
234
289
|
}
|
|
235
290
|
sync() {
|
|
291
|
+
var _a;
|
|
236
292
|
// recompute the editable fields
|
|
237
293
|
const { block, blockFieldData: fieldData, fields, editableFields } = this;
|
|
238
294
|
const configData = editableFields.reduce((data, field) => {
|
|
@@ -273,6 +329,17 @@ class BlockConfiguration {
|
|
|
273
329
|
this._layout = getLayout
|
|
274
330
|
? getLayout({ config: updatedConfig, fields: fieldData })
|
|
275
331
|
: undefined;
|
|
332
|
+
// setup slot
|
|
333
|
+
const slotField = configFields.find(field => field.id === 'slotVariation');
|
|
334
|
+
const slotOptions = (slotField ? Object.keys(slotField.schema.options) : []);
|
|
335
|
+
const slotOption = (_a = slotField === null || slotField === void 0 ? void 0 : slotField.value) === null || _a === void 0 ? void 0 : _a.value;
|
|
336
|
+
const slotOptionIndex = slotOption ? slotOptions.indexOf(slotOption) : -1;
|
|
337
|
+
this._slotState = {
|
|
338
|
+
field: slotField,
|
|
339
|
+
options: slotOptions,
|
|
340
|
+
currentIndex: slotOptionIndex < 0 ? undefined : slotOptionIndex,
|
|
341
|
+
currentOption: slotOption
|
|
342
|
+
};
|
|
276
343
|
// assign to editable fields (raised event)
|
|
277
344
|
this.editableFields = configFields;
|
|
278
345
|
// compute the default config
|