@nascentdigital/funnel-editor 4.5.2 → 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/EditorApp.js +1 -1
- package/dist/core/components/ColorModeToggle.d.ts +2 -2
- 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/collection/CollectionPicker.js +3 -4
- package/dist/core/components/fields/index.d.ts +2 -0
- package/dist/core/components/fields/index.js +2 -0
- package/dist/core/components/fields/page/PagePicker.js +2 -3
- 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/Animate.d.ts +1 -1
- package/dist/core/components/interaction/Animate.js +12 -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.d.ts +5 -5
- package/dist/core/components/interaction/SideSheet.js +15 -43
- package/dist/core/components/interaction/centersheet/CenterSheet.js +1 -1
- package/dist/core/components/interaction/centersheet/CenterSheetContainer.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 +16 -1
- package/dist/core/domain/BlockConfiguration.js +109 -5
- package/dist/page/components/config/BlockConfig.js +1 -1
- package/dist/page/components/config/BlockConfigEditor.d.ts +1 -1
- package/dist/page/components/config/BlockConfigEditor.js +40 -13
- package/dist/page/components/config/BlockPreview.js +23 -17
- package/dist/page/components/config/LegacyBlockConfigEditor.js +1 -9
- 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 +367 -193
- package/dist/styles/tailwind.js +11 -16
- package/package.json +2 -2
|
@@ -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 } 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,11 +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;
|
|
27
|
+
get slotState(): Readonly<BlockConfiguration.SlotState>;
|
|
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>;
|
|
26
33
|
get layout(): BlockLayout | undefined;
|
|
27
34
|
get events$(): import("rxjs").Observable<EventBus.Event<string, string>>;
|
|
28
35
|
get valid(): boolean;
|
|
29
36
|
get modified(): boolean;
|
|
30
37
|
getField(fieldId: string): FieldModel;
|
|
38
|
+
getFieldData(fieldId: string): Schema.Field.LinkedData | undefined;
|
|
39
|
+
getEditableField(fieldId: string): FieldModel.Config | undefined;
|
|
31
40
|
save(): void;
|
|
32
41
|
reset(): void;
|
|
33
42
|
get isConfigInDefault(): boolean | undefined;
|
|
@@ -35,6 +44,12 @@ export declare class BlockConfiguration {
|
|
|
35
44
|
private raiseEvent;
|
|
36
45
|
}
|
|
37
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
|
+
};
|
|
38
53
|
type ConstructorArgs = {
|
|
39
54
|
assetStore: IAssetStore;
|
|
40
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,15 +85,75 @@ 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 slotState() {
|
|
98
|
+
return this._slotState;
|
|
99
|
+
}
|
|
100
|
+
gotToNextSlot() {
|
|
101
|
+
// skip if there's no options
|
|
102
|
+
const { field, options, currentIndex } = this._slotState;
|
|
103
|
+
if (!field || options.length < 0 || currentIndex === undefined) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
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) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// update the slot
|
|
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
|
+
};
|
|
156
|
+
}
|
|
97
157
|
get layout() {
|
|
98
158
|
return this._layout;
|
|
99
159
|
}
|
|
@@ -104,7 +164,13 @@ class BlockConfiguration {
|
|
|
104
164
|
return this.editableFields.every(field => field.valid);
|
|
105
165
|
}
|
|
106
166
|
get modified() {
|
|
107
|
-
|
|
167
|
+
const original = this.fields
|
|
168
|
+
.filter(field => field.hasValue)
|
|
169
|
+
.map(field => field.value);
|
|
170
|
+
const updated = this.editableFields
|
|
171
|
+
.filter(field => field.hasValue)
|
|
172
|
+
.map(field => field.value);
|
|
173
|
+
return !funnel_core_1.Value.equals(original, updated);
|
|
108
174
|
}
|
|
109
175
|
getField(fieldId) {
|
|
110
176
|
// return field or throw
|
|
@@ -115,6 +181,32 @@ class BlockConfiguration {
|
|
|
115
181
|
// return field
|
|
116
182
|
return field;
|
|
117
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
|
+
}
|
|
118
210
|
save() {
|
|
119
211
|
// save each modified field
|
|
120
212
|
const { sectionBlock, block, editableFields } = this;
|
|
@@ -196,6 +288,7 @@ class BlockConfiguration {
|
|
|
196
288
|
return this._isConfigInDefault;
|
|
197
289
|
}
|
|
198
290
|
sync() {
|
|
291
|
+
var _a;
|
|
199
292
|
// recompute the editable fields
|
|
200
293
|
const { block, blockFieldData: fieldData, fields, editableFields } = this;
|
|
201
294
|
const configData = editableFields.reduce((data, field) => {
|
|
@@ -236,6 +329,17 @@ class BlockConfiguration {
|
|
|
236
329
|
this._layout = getLayout
|
|
237
330
|
? getLayout({ config: updatedConfig, fields: fieldData })
|
|
238
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
|
+
};
|
|
239
343
|
// assign to editable fields (raised event)
|
|
240
344
|
this.editableFields = configFields;
|
|
241
345
|
// compute the default config
|
|
@@ -20,7 +20,7 @@ function BlockConfig({ className, block: blockOrSectionBlock }) {
|
|
|
20
20
|
}
|
|
21
21
|
// render
|
|
22
22
|
const valid = config.every(field => field.valid);
|
|
23
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.StatusChip, { className: className, variant: valid ? 'success' : 'error', onClick: () => setConfiguration(
|
|
23
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.StatusChip, { className: className, variant: valid ? 'success' : 'error', onClick: () => setConfiguration(blockOrSectionBlock.getConfiguration()), children: "Configure" }), process.env.NEXT_PUBLIC_EDITOR_BLOCK_CONFIG === 'experimental'
|
|
24
24
|
?
|
|
25
25
|
(0, jsx_runtime_1.jsx)(BlockConfigEditor_1.BlockConfigEditor, { configuration: configuration, onClose: () => setConfiguration(undefined) })
|
|
26
26
|
:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Callback } from '@nascentdigital/funnel-core';
|
|
2
2
|
import { BlockConfiguration } from '../../../core';
|
|
3
|
-
export declare function BlockConfigEditor({ configuration, onClose }: BlockConfigEditor.Props): import("react/jsx-runtime").JSX.Element
|
|
3
|
+
export declare function BlockConfigEditor({ configuration, onClose }: BlockConfigEditor.Props): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
export declare namespace BlockConfigEditor {
|
|
5
5
|
type Props = {
|
|
6
6
|
configuration?: BlockConfiguration;
|
|
@@ -3,19 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BlockConfigEditor = BlockConfigEditor;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
6
|
-
const client_1 = require("@nascentdigital/funnel-ui/client");
|
|
7
6
|
const react_1 = require("motion/react");
|
|
8
7
|
const react_2 = require("react");
|
|
9
8
|
const rxjs_1 = require("rxjs");
|
|
10
9
|
const core_1 = require("../../../core");
|
|
10
|
+
const FieldHeader_1 = require("../../../core/components/fields/FieldHeader");
|
|
11
11
|
const hooks_1 = require("../../hooks");
|
|
12
12
|
const BlockPreview_1 = require("./BlockPreview");
|
|
13
13
|
// editor
|
|
14
14
|
function BlockConfigEditor({ configuration, onClose }) {
|
|
15
|
+
var _a;
|
|
15
16
|
// bind state + hooks
|
|
16
17
|
const [blockView, setBlockView] = (0, react_2.useState)('desktop');
|
|
17
18
|
const pageController = (0, hooks_1.usePageController)();
|
|
18
|
-
const touch = (0, client_1.useTouch)();
|
|
19
19
|
const panelLayoutPickerRef = (0, react_2.useRef)(null);
|
|
20
20
|
const { modified = false, valid = false, blocksFields = [], desktopFields = [], mobileFields = [] } = configuration !== null && configuration !== void 0 ? configuration : {};
|
|
21
21
|
const settingsFields = blockView === 'desktop' ? desktopFields : mobileFields;
|
|
@@ -60,23 +60,50 @@ function BlockConfigEditor({ configuration, onClose }) {
|
|
|
60
60
|
layoutField.value = funnel_core_1.Schema.EnumField.Value.toData(selectedLayout);
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
|
-
// skip if there's no config
|
|
64
|
-
if (!configuration) {
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
63
|
// render
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
const { options: slotOptions = [], currentIndex: slotIndex = 0 } = (_a = configuration === null || configuration === void 0 ? void 0 : configuration.slotState) !== null && _a !== void 0 ? _a : {};
|
|
65
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.SideSheet, { title: "Block Configuration", size: "xs", backdrop: "glass", open: !!configuration, onSave: onSave, onClose: onClose, disableDismiss: modified, disableSave: !modified || !valid, customActions: (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "sm", disabled: configuration === null || configuration === void 0 ? void 0 : configuration.isConfigInDefault, onClick: () => configuration === null || configuration === void 0 ? void 0 : configuration.reset(), children: "Reset to Default" }), children: (0, jsx_runtime_1.jsxs)("div", { className: "h-full flex flex-col gap-l6", children: [(0, jsx_runtime_1.jsxs)("section", { className: "grid grid-cols-2 gap-x-l5 gap-y-l4", children: [blocksFields.length > 0 &&
|
|
66
|
+
(0, jsx_runtime_1.jsx)(core_1.FieldErrorController, { children: blocksFields.map(field => (0, jsx_runtime_1.jsx)(core_1.FieldEditor, { className: "col-span-full", field: field, size: "xs" }, field.id)) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-l2", children: [(0, jsx_runtime_1.jsx)(FieldHeader_1.FieldHeader, { label: "Layout", size: "xs" }), (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "xs", iconLeft: "LayoutTemplate", onClick: onChangePanelLayout, children: "Change" })] }), slotOptions.length > 1 &&
|
|
67
|
+
(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-l2", children: [(0, jsx_runtime_1.jsx)(FieldHeader_1.FieldHeader, { label: "Arrangement", size: "xs" }), slotOptions.length === 2
|
|
68
|
+
?
|
|
69
|
+
(0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "xs", iconLeft: "ArrowLeftRight", onClick: () => configuration === null || configuration === void 0 ? void 0 : configuration.gotToNextSlot(), children: "Swap" })
|
|
70
|
+
:
|
|
71
|
+
(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-l4", children: [(0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "xs", onClick: () => configuration === null || configuration === void 0 ? void 0 : configuration.gotToPreviousSlot(), children: (0, jsx_runtime_1.jsx)(core_1.Icon, { variant: "ArrowLeft", size: { size: 16, strokeWidth: 1, absoluteStrokeWidth: true } }) }), (0, jsx_runtime_1.jsxs)("span", { className: "label-xs", children: [slotIndex + 1, " of ", slotOptions.length] }), (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "xs", onClick: () => configuration === null || configuration === void 0 ? void 0 : configuration.gotToNextSlot(), children: (0, jsx_runtime_1.jsx)(core_1.Icon, { variant: "ArrowRight", size: { size: 16, strokeWidth: 1, absoluteStrokeWidth: true } }) })] })] })] }), (0, jsx_runtime_1.jsx)(core_1.Tabs, { items: blockViews, selectedItem: blockView, onSelect: setBlockView }), (0, jsx_runtime_1.jsx)(react_1.motion.section, { className: "p-l6 bg-surface-placeholder-raised rounded-md", layout: true, children: configuration &&
|
|
72
|
+
(0, jsx_runtime_1.jsx)(BlockPreview_1.BlockPreview, { variant: blockView, configuration: configuration }) }), settingsFields.length > 0 &&
|
|
73
|
+
(0, jsx_runtime_1.jsx)("section", { className: "grid grid-cols-2 auto-rows-auto items-start gap-l6", children: (0, jsx_runtime_1.jsx)(core_1.FieldErrorController, { children: settingsFields.map(field => (0, jsx_runtime_1.jsx)(core_1.FieldEditor, { className: "col-span-2", field: field, size: "xs" }, field.id)) }) })] }) }), (0, jsx_runtime_1.jsx)(core_1.QuickPicker, { ref: panelLayoutPickerRef, variant: "card", title: "Pick Block Layout", description: "Select an available layout for this block.", renderItem: (item) => renderPanelLayoutItem(item) })] }));
|
|
71
74
|
}
|
|
72
75
|
function renderPanelLayoutItem(item) {
|
|
73
76
|
switch (item.id) {
|
|
74
|
-
case '
|
|
75
|
-
return ((0, jsx_runtime_1.jsx)("div", { children: "
|
|
77
|
+
case 'solo':
|
|
78
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "p-l4 size-full", children: (0, jsx_runtime_1.jsx)("div", { className: "size-full bg-surface-placeholder" }) }));
|
|
76
79
|
case 'stack.v':
|
|
77
|
-
return ((0, jsx_runtime_1.
|
|
80
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full flex-col p-l4 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" })] }));
|
|
81
|
+
case 'stack.h':
|
|
82
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full p-l4 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" })] }));
|
|
83
|
+
case 'brick.v':
|
|
84
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full flex-col p-l4 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" })] }));
|
|
85
|
+
case 'brick.t':
|
|
86
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full flex-col p-l4 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-full h-[20px] bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-1 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]r" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" })] })] }));
|
|
87
|
+
case 'brick.r':
|
|
88
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full p-l4 gap-l1", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex h-full flex-1 flex-col gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" })] }), (0, jsx_runtime_1.jsx)("div", { className: "h-full w-[30px] bg-surface-placeholder rounded-[2px]" })] }));
|
|
89
|
+
case 'brick.b':
|
|
90
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full flex-col p-l4 gap-l1", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-1 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" })] }), (0, jsx_runtime_1.jsx)("div", { className: "w-full h-[20px] bg-surface-placeholder rounded-[2px]" })] }));
|
|
91
|
+
case 'brick.l':
|
|
92
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full p-l4 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "h-full w-[30px] bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex h-full flex-1 flex-col gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder rounded-[2px]" })] })] }));
|
|
78
93
|
case 'nested':
|
|
79
|
-
return ((0, jsx_runtime_1.jsx)("div", { children: "
|
|
94
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "p-l4 size-full", children: (0, jsx_runtime_1.jsx)("div", { className: "flex h-full px-l5 py-l2 bg-surface-placeholder rounded-[2px]", children: (0, jsx_runtime_1.jsx)("div", { className: "bg-surface-placeholder-raised rounded-[2px]" }) }) }));
|
|
95
|
+
case 'nested.v':
|
|
96
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "h-full w-full p-l4", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex h-full flex-col px-l4 py-l2 gap-l1 bg-surface-placeholder rounded-[2px]", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder-raised rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder-raised rounded-[2px]" })] }) }));
|
|
97
|
+
case 'nested.h':
|
|
98
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "h-full w-full p-l4", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex h-full px-l4 py-l3 gap-l1 bg-surface-placeholder rounded-[2px]", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder-raised rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-surface-placeholder-raised rounded-[2px]" })] }) }));
|
|
99
|
+
case 'nested.t':
|
|
100
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full flex-col p-l4 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l2 bg-surface-placeholder rounded-[2px]", children: (0, jsx_runtime_1.jsx)("div", { className: "h-full w-7/12 bg-surface-placeholder-raised rounded-[2px]" }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l2 bg-surface-placeholder rounded-[2px]" })] }));
|
|
101
|
+
case 'nested.r':
|
|
102
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full p-l4 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l2 bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-1 flex-col p-l2 bg-surface-placeholder rounded-[2px]", children: (0, jsx_runtime_1.jsx)("div", { className: "w-full h-[60%] bg-surface-placeholder-raised rounded-[2px]" }) })] }));
|
|
103
|
+
case 'nested.b':
|
|
104
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full flex-col p-l4 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l2 bg-surface-placeholder rounded-[2px]" }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l2 bg-surface-placeholder rounded-[2px]", children: (0, jsx_runtime_1.jsx)("div", { className: "h-full w-7/12 bg-surface-placeholder-raised rounded-[2px]" }) })] }));
|
|
105
|
+
case 'nested.l':
|
|
106
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full p-l4 gap-l1", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex flex-1 flex-col p-l2 bg-surface-placeholder rounded-[2px]", children: (0, jsx_runtime_1.jsx)("div", { className: "w-full h-[60%] bg-surface-placeholder-raised rounded-[2px]" }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l2 bg-surface-placeholder rounded-[2px]" })] }));
|
|
80
107
|
default:
|
|
81
108
|
return ((0, jsx_runtime_1.jsx)("div", { children: item.id }));
|
|
82
109
|
}
|
|
@@ -20,43 +20,49 @@ const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
|
20
20
|
const classnames_1 = __importDefault(require("classnames"));
|
|
21
21
|
const react_1 = require("react");
|
|
22
22
|
const core_1 = require("../../../core");
|
|
23
|
+
const ListPanelEditor_1 = require("./ListPanelEditor");
|
|
24
|
+
const MessagePanelEditor_1 = require("./MessagePanelEditor");
|
|
25
|
+
const VisualPanelEditor_1 = require("./VisualPanelEditor");
|
|
26
|
+
const react_2 = require("motion/react");
|
|
23
27
|
// component
|
|
24
28
|
function BlockPreview({ className, variant, configuration }) {
|
|
25
|
-
//
|
|
29
|
+
// bind props + state + refs
|
|
26
30
|
const { layout } = configuration;
|
|
31
|
+
const [editingPanel, setEditingPanel] = (0, react_1.useState)();
|
|
32
|
+
const previewRef = (0, react_1.useRef)(null);
|
|
27
33
|
// sync configuration
|
|
28
34
|
(0, core_1.useBlockConfiguration)(configuration);
|
|
29
35
|
// helpers
|
|
30
36
|
const onPanelClick = (panel) => {
|
|
31
|
-
|
|
37
|
+
setEditingPanel(panel.type);
|
|
32
38
|
};
|
|
33
39
|
// render
|
|
34
40
|
const tight = variant === 'mobile'
|
|
35
41
|
? layout === null || layout === void 0 ? void 0 : layout.tight.mobile
|
|
36
42
|
: layout === null || layout === void 0 ? void 0 : layout.tight.desktop;
|
|
37
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(react_2.motion.div, { ref: previewRef, className: (0, classnames_1.default)(className, 'w-full flex justify-center'), layout: true, children: [(0, jsx_runtime_1.jsx)(react_2.motion.div, { className: (0, classnames_1.default)('bg-surface2 rounded-xs', {
|
|
44
|
+
'min-h-[100px]': !layout,
|
|
45
|
+
'w-[120px]': variant === 'desktop',
|
|
46
|
+
'w-[64px]': variant === 'mobile',
|
|
47
|
+
'pb-l4': tight === 'above',
|
|
48
|
+
'pt-l4': tight === 'below',
|
|
49
|
+
'py-l4': tight === 'none'
|
|
50
|
+
}), layoutRoot: true, layout: true, children: renderLayout({ variant, layout, onPanelClick }) }), (0, jsx_runtime_1.jsx)(MessagePanelEditor_1.MessagePanelEditor, { open: editingPanel === 'message', onClose: () => setEditingPanel(panel => panel === 'message' ? undefined : panel), anchor: previewRef.current, configuration: configuration }), (0, jsx_runtime_1.jsx)(ListPanelEditor_1.ListPanelEditor, { open: editingPanel === 'list', onClose: () => setEditingPanel(panel => panel === 'list' ? undefined : panel), anchor: previewRef.current, configuration: configuration }), (0, jsx_runtime_1.jsx)(VisualPanelEditor_1.VisualPanelEditor, { open: editingPanel === 'visual', onClose: () => setEditingPanel(panel => panel === 'visual' ? undefined : panel), anchor: previewRef.current, configuration: configuration })] }) }));
|
|
45
51
|
}
|
|
46
52
|
// helpers
|
|
47
53
|
var Skeleton;
|
|
48
54
|
(function (Skeleton) {
|
|
49
55
|
function HeadlinePart({ className, size }) {
|
|
50
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
56
|
+
return ((0, jsx_runtime_1.jsx)(react_2.motion.div, { className: (0, classnames_1.default)(className, 'bg-ix-primary rounded-xxs overflow-hidden', {
|
|
51
57
|
'h-6 ': size === 'sm',
|
|
52
58
|
'h-8': size === 'md'
|
|
53
|
-
}) }));
|
|
59
|
+
}), layout: true }));
|
|
54
60
|
}
|
|
55
61
|
Skeleton.HeadlinePart = HeadlinePart;
|
|
56
62
|
function CaptionPart({ className, size }) {
|
|
57
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
63
|
+
return ((0, jsx_runtime_1.jsx)(react_2.motion.div, { className: (0, classnames_1.default)(className, 'h-4 bg-draft/tint3 rounded-px overflow-hidden', {
|
|
58
64
|
'': size === 'sm'
|
|
59
|
-
}) }));
|
|
65
|
+
}), layout: true }));
|
|
60
66
|
}
|
|
61
67
|
Skeleton.CaptionPart = CaptionPart;
|
|
62
68
|
function MediaPart({ className, aspect }) {
|
|
@@ -95,7 +101,7 @@ function renderLayout({ className, variant, layout, onPanelClick }) {
|
|
|
95
101
|
}
|
|
96
102
|
// render root layout
|
|
97
103
|
const { type, items } = layout.root;
|
|
98
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
104
|
+
return ((0, jsx_runtime_1.jsx)(react_2.motion.div, { className: getContainerClasses({ className, variant, siblingCount: 1, item: layout.root }), layout: true, children: items.map((item, parentOffset) => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: renderItem({
|
|
99
105
|
className: (0, classnames_1.default)({
|
|
100
106
|
'flex-1': type === 'row' && variant !== 'mobile'
|
|
101
107
|
}),
|
|
@@ -119,7 +125,7 @@ function renderItem({ className, parent, parentNested, siblingCount, variant, it
|
|
|
119
125
|
case 'row':
|
|
120
126
|
case 'column':
|
|
121
127
|
case 'stack':
|
|
122
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
128
|
+
return ((0, jsx_runtime_1.jsx)(react_2.motion.div, { className: getContainerClasses({ className, parent, siblingCount, variant, item }), layout: true, children: item.items.map((item, parentOffset, items) => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: renderItem({
|
|
123
129
|
className: (0, classnames_1.default)({
|
|
124
130
|
'flex-1': itemType === 'row'
|
|
125
131
|
}),
|
|
@@ -437,7 +443,7 @@ function getPanelClasses({ className, variant, parent, parentNested, item: { ali
|
|
|
437
443
|
function EditablePanel(_a) {
|
|
438
444
|
var { panelClassName, children } = _a, args = __rest(_a, ["panelClassName", "children"]);
|
|
439
445
|
// render
|
|
440
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
446
|
+
return ((0, jsx_runtime_1.jsx)(react_2.motion.div, { className: getPanelWrapClasses(args), layout: true, layoutId: args.item.key, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(panelClassName, 'relative'), children: [children, (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('group absolute inset-0 z-overlay cursor-pointer interpolate', 'bg-surface1 border border-solid, border-ix-primary rounded-xxs overflow-hidden', 'opacity-none hover:opacity-full'), onClick: () => args.onPanelClick(args.item), children: (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('w-full h-full interpolate', 'flex flex-col justify-center items-center gap-l6', 'text-ix-primary group-hover:bg-ix-primary/tint1 group-active:bg-ix-primary/tint3'), children: (0, jsx_runtime_1.jsx)("span", { className: "label-xs label-strong", children: "Edit" }) }) })] }) }, args.item.key));
|
|
441
447
|
}
|
|
442
448
|
// TODO: scrap this
|
|
443
449
|
class ItemPosition {
|
|
@@ -2,24 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LegacyBlockConfigEditor = LegacyBlockConfigEditor;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const react_1 = require("react");
|
|
6
5
|
const rxjs_1 = require("rxjs");
|
|
7
6
|
const core_1 = require("../../../core");
|
|
8
7
|
const hooks_1 = require("../../hooks");
|
|
9
8
|
// editor
|
|
10
9
|
function LegacyBlockConfigEditor({ configuration, onClose }) {
|
|
11
10
|
// bind state + hooks
|
|
12
|
-
const [closing, setClosing] = (0, react_1.useState)(false);
|
|
13
11
|
const pageController = (0, hooks_1.usePageController)();
|
|
14
12
|
const { modified = false, valid = false } = configuration !== null && configuration !== void 0 ? configuration : {};
|
|
15
13
|
// sync w/ configuration
|
|
16
14
|
(0, core_1.useBlockConfiguration)(configuration);
|
|
17
|
-
// reset closing on new open
|
|
18
|
-
(0, react_1.useEffect)(() => {
|
|
19
|
-
if (configuration) {
|
|
20
|
-
setClosing(false);
|
|
21
|
-
}
|
|
22
|
-
}, [configuration]);
|
|
23
15
|
// helpers
|
|
24
16
|
const onSave = async () => {
|
|
25
17
|
// save config
|
|
@@ -31,5 +23,5 @@ function LegacyBlockConfigEditor({ configuration, onClose }) {
|
|
|
31
23
|
};
|
|
32
24
|
// render
|
|
33
25
|
const { layout } = configuration !== null && configuration !== void 0 ? configuration : {};
|
|
34
|
-
return ((0, jsx_runtime_1.jsx)(core_1.SideSheet, { title: "Block Configuration", backdrop: "
|
|
26
|
+
return ((0, jsx_runtime_1.jsx)(core_1.SideSheet, { size: "lg", title: "Block Configuration", backdrop: "glass", open: !!configuration, onSave: onSave, onClose: onClose, disableSave: !modified || !valid, customActions: (0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "sm", disabled: configuration === null || configuration === void 0 ? void 0 : configuration.isConfigInDefault, onClick: () => configuration === null || configuration === void 0 ? void 0 : configuration.reset(), children: "Reset to Default" }), children: (0, jsx_runtime_1.jsxs)("div", { className: "h-full flex flex-col gap-l9 p-l8", children: [(0, jsx_runtime_1.jsxs)("section", { className: "flex flex-wrap justify-center items-start gap-l8", children: [(0, jsx_runtime_1.jsx)(core_1.SkeletonLayout, { variant: "desktop", layout: layout }), (0, jsx_runtime_1.jsx)(core_1.SkeletonLayout, { variant: "mobile", layout: layout })] }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-[max-content_1fr] auto-rows-auto items-start gap-l6", children: (0, jsx_runtime_1.jsx)(core_1.FieldErrorController, { children: configuration === null || configuration === void 0 ? void 0 : configuration.editableFields.map(field => (0, jsx_runtime_1.jsx)(core_1.FieldEditor, { className: "col-span-2", field: field, variant: "wide" }, field.id)) }) })] }) }));
|
|
35
27
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { BlockConfiguration, Popup } from '../../../core';
|
|
2
|
+
export declare function ListPanelEditor({ className, anchor, open, onClose, configuration }: ListPanelEditor.Props): import("react/jsx-runtime").JSX.Element;
|
|
2
3
|
export declare namespace ListPanelEditor {
|
|
3
|
-
type Props = {
|
|
4
|
+
type Props = Pick<Popup.Props, 'open' | 'onClose' | 'anchor'> & {
|
|
4
5
|
className?: string;
|
|
6
|
+
configuration: BlockConfiguration;
|
|
5
7
|
};
|
|
6
8
|
}
|
|
@@ -1,13 +1,63 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
15
|
};
|
|
5
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
17
|
exports.ListPanelEditor = ListPanelEditor;
|
|
7
18
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
8
20
|
const classnames_1 = __importDefault(require("classnames"));
|
|
21
|
+
const react_1 = require("react");
|
|
22
|
+
const core_1 = require("../../../core");
|
|
9
23
|
// component
|
|
10
|
-
function ListPanelEditor({ className }) {
|
|
24
|
+
function ListPanelEditor({ className, anchor, open, onClose, configuration }) {
|
|
25
|
+
// bind props + refs
|
|
26
|
+
const _a = configuration.listFields, { layout: layoutField } = _a, listFields = __rest(_a, ["layout"]);
|
|
27
|
+
const layoutPickerRef = (0, react_1.useRef)(null);
|
|
28
|
+
// helpers
|
|
29
|
+
const onChangeLayout = async (e) => {
|
|
30
|
+
var _a;
|
|
31
|
+
// skip if there's no layout field (shouldn't happen)
|
|
32
|
+
const layoutSchema = layoutField === null || layoutField === void 0 ? void 0 : layoutField.schema;
|
|
33
|
+
if (!layoutField || !layoutSchema) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// pick new layout
|
|
37
|
+
const { value: layoutData } = layoutField;
|
|
38
|
+
const selectedLayout = await ((_a = layoutPickerRef.current) === null || _a === void 0 ? void 0 : _a.open({
|
|
39
|
+
anchor: e.currentTarget,
|
|
40
|
+
anchorOffset: 4,
|
|
41
|
+
placement: 'top',
|
|
42
|
+
items: Object.entries(layoutSchema.options).map(([layout, option]) => ({
|
|
43
|
+
id: layout,
|
|
44
|
+
label: option.name
|
|
45
|
+
})),
|
|
46
|
+
selectedItem: layoutData === null || layoutData === void 0 ? void 0 : layoutData.value
|
|
47
|
+
}));
|
|
48
|
+
// update if something was picked
|
|
49
|
+
if (selectedLayout) {
|
|
50
|
+
layoutField.value = funnel_core_1.Schema.EnumField.Value.toData(selectedLayout);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
11
53
|
// render
|
|
12
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
54
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.QuickEditor, { className: (0, classnames_1.default)(className), title: "List Configuration", tip: "Lorem ipsum.", anchor: anchor, placement: "left", anchorOffset: 4, viewportPadding: 4, open: open, onClose: onClose, size: "sm", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-l4", children: [(0, jsx_runtime_1.jsx)(core_1.Button, { variant: "secondary", size: "xs", iconLeft: "LayoutTemplate", onClick: onChangeLayout, children: "Change" }), Object.values(listFields)
|
|
55
|
+
.filter(funnel_core_1.Value.isDefined)
|
|
56
|
+
.map(field => (0, jsx_runtime_1.jsx)(core_1.FieldEditor, { field: field, size: "xs" }, field.id))] }) }), (0, jsx_runtime_1.jsx)(core_1.QuickPicker, { ref: layoutPickerRef, variant: "card", title: "Pick List Layout", description: "Select an available layout for this list.", renderItem: (item) => renderListLayoutItem(item) })] }));
|
|
57
|
+
}
|
|
58
|
+
function renderListLayoutItem(item) {
|
|
59
|
+
switch (item.id) {
|
|
60
|
+
default:
|
|
61
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: item.id }));
|
|
62
|
+
}
|
|
13
63
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { BlockConfiguration, Popup } from '../../../core';
|
|
2
|
+
export declare function MessagePanelEditor({ className, anchor, open, onClose, configuration }: MessagePanelEditor.Props): import("react/jsx-runtime").JSX.Element;
|
|
2
3
|
export declare namespace MessagePanelEditor {
|
|
3
|
-
type Props = {
|
|
4
|
+
type Props = Pick<Popup.Props, 'open' | 'onClose' | 'anchor'> & {
|
|
4
5
|
className?: string;
|
|
6
|
+
configuration: BlockConfiguration;
|
|
5
7
|
};
|
|
6
8
|
}
|