@nascentdigital/funnel-editor 4.5.3 → 4.5.6

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 (62) hide show
  1. package/dist/core/components/feedback/Note.d.ts +3 -1
  2. package/dist/core/components/feedback/Note.js +6 -3
  3. package/dist/core/components/fields/BooleanField.d.ts +3 -1
  4. package/dist/core/components/fields/BooleanField.js +2 -2
  5. package/dist/core/components/fields/DateField.d.ts +3 -1
  6. package/dist/core/components/fields/DateField.js +2 -2
  7. package/dist/core/components/fields/EnumField.d.ts +3 -1
  8. package/dist/core/components/fields/EnumField.js +4 -4
  9. package/dist/core/components/fields/FieldEditor.d.ts +3 -1
  10. package/dist/core/components/fields/FieldEditor.js +7 -7
  11. package/dist/core/components/fields/FieldHeader.d.ts +3 -1
  12. package/dist/core/components/fields/FieldHeader.js +18 -5
  13. package/dist/core/components/fields/FieldLayout.d.ts +3 -1
  14. package/dist/core/components/fields/FieldLayout.js +17 -4
  15. package/dist/core/components/fields/FieldSize.d.ts +1 -0
  16. package/dist/core/components/fields/FieldSize.js +2 -0
  17. package/dist/core/components/fields/FieldsPanel.js +5 -4
  18. package/dist/core/components/fields/RichTextEditor.d.ts +2 -3
  19. package/dist/core/components/fields/RichTextEditor.js +13 -10
  20. package/dist/core/components/fields/RichTextField.d.ts +1 -2
  21. package/dist/core/components/fields/RichTextField.js +4 -16
  22. package/dist/core/components/fields/TextField.d.ts +3 -2
  23. package/dist/core/components/fields/TextField.js +8 -7
  24. package/dist/core/components/fields/TimestampField.d.ts +3 -1
  25. package/dist/core/components/fields/TimestampField.js +2 -2
  26. package/dist/core/components/fields/index.d.ts +2 -0
  27. package/dist/core/components/fields/index.js +2 -0
  28. package/dist/core/components/fields/richtext/Theme.d.ts +1 -2
  29. package/dist/core/components/fields/richtext/Theme.js +2 -2
  30. package/dist/core/components/interaction/Button.js +3 -3
  31. package/dist/core/components/interaction/Combobox.d.ts +8 -1
  32. package/dist/core/components/interaction/Combobox.js +39 -12
  33. package/dist/core/components/interaction/IconButton.d.ts +2 -2
  34. package/dist/core/components/interaction/IconButton.js +2 -1
  35. package/dist/core/components/interaction/QuickEditor.d.ts +11 -0
  36. package/dist/core/components/interaction/QuickEditor.js +33 -0
  37. package/dist/core/components/interaction/QuickInput.js +1 -1
  38. package/dist/core/components/interaction/QuickPicker.js +5 -3
  39. package/dist/core/components/interaction/SegmentedButton.d.ts +3 -1
  40. package/dist/core/components/interaction/SegmentedButton.js +4 -1
  41. package/dist/core/components/interaction/SideSheet.js +1 -1
  42. package/dist/core/components/interaction/index.d.ts +1 -0
  43. package/dist/core/components/interaction/index.js +1 -0
  44. package/dist/core/components/visuals/Icon.d.ts +2 -2
  45. package/dist/core/components/visuals/Icon.js +5 -0
  46. package/dist/core/domain/BlockConfiguration.d.ts +15 -3
  47. package/dist/core/domain/BlockConfiguration.js +94 -27
  48. package/dist/page/components/config/BlockConfig.js +1 -1
  49. package/dist/page/components/config/BlockConfigEditor.js +26 -19
  50. package/dist/page/components/config/BlockPreview.d.ts +1 -1
  51. package/dist/page/components/config/BlockPreview.js +24 -18
  52. package/dist/page/components/config/ListPanelEditor.d.ts +4 -2
  53. package/dist/page/components/config/ListPanelEditor.js +78 -2
  54. package/dist/page/components/config/MessagePanelEditor.d.ts +4 -2
  55. package/dist/page/components/config/MessagePanelEditor.js +6 -2
  56. package/dist/page/components/config/VisualPanelEditor.d.ts +4 -2
  57. package/dist/page/components/config/VisualPanelEditor.js +65 -2
  58. package/dist/styles/index.css +303 -143
  59. package/dist/styles/tailwind.js +2 -0
  60. package/package.json +2 -2
  61. package/dist/page/components/config/ListLayoutPicker.d.ts +0 -6
  62. package/dist/page/components/config/ListLayoutPicker.js +0 -13
@@ -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: RichTextEditor.Variant, options: Schema.RichTextField.Capabilities.Options): EditorThemeClasses;
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 && size !== 'xs' &&
30
- (0, jsx_runtime_1.jsx)(visuals_1.Icon, { variant: iconLeft, size: size === 'md' ? 'md' : 'sm' }), children, iconRight && size !== 'xs' &&
31
- (0, jsx_runtime_1.jsx)(visuals_1.Icon, { variant: iconRight, size: size === 'md' ? 'md' : 'sm' })] })));
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 = 36, disabled = false, options, noSelectionText = 'Make a selection', selectedOption: selectedOptionId, onSelect = funnel_core_1.Fn.NoOp, renderSelection: renderSelectionRaw, renderOption = onRenderOption, }) {
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, 'min-w-[180px] h-40 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', {
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 py-l4 bg-surface2 rounded-lg shadow-popup overflow-y-scroll'), style: {
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 + 16
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 gap-l4 px-l6 appearance-none select-none outline-none interpolate', {
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 body-sm', {
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 label-md', {
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", small: true, autoFocus: true, onKeyDown: onKeyDown }));
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-[420px] max-w-full flex flex-col gap-l8 pt-l8 interpolate', 'border border-solid border-glass-stroke-l1/tint5 rounded-md', {
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 items-center gap-l5 max-h-[240px] px-l8 pb-l8 overflow-y-scroll': variant === 'card'
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-[116px] h-[88px]', {
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-md text-content-primary p-l8", children: title }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 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 &&
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
@@ -22,6 +22,7 @@ export * from './NavButton';
22
22
  export * from './Picker';
23
23
  export * from './Popup';
24
24
  export * from './Profile';
25
+ export * from './QuickEditor';
25
26
  export * from './QuickInput';
26
27
  export * from './QuickPicker';
27
28
  export * from './SegmentedButton';
@@ -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 slotField(): Field<Schema.EnumField<Schema.EnumField.Options<SlotVariation>>> | undefined;
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._editableFields.find(field => field.id === 'contentAlign')
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._editableFields.find(field => field.id === block.nameField.id)
88
+ ? this.getEditableField(block.nameField.id)
89
89
  : undefined;
90
90
  }
91
91
  get themeField() {
92
- return this._editableFields.find(field => field.id === funnel_ui_1.BlockConfig.Presets.ThemeOnly.key);
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 slotField() {
98
- return this._editableFields.find(field => field.id === 'slotVariation');
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
- var _a;
106
- // get the slot field and skip if the field doesn't exist
107
- const slotField = this.slotField;
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
- // get the current slot value and skip if no value found (should not happen)
112
- const currentValue = (_a = slotField.value) === null || _a === void 0 ? void 0 : _a.value;
113
- if (!currentValue) {
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
- slotField.value = funnel_core_1.Schema.EnumField.Value.toData(nextSlot);
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