@webikon/webentor-core 0.9.14 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +41 -0
- package/core-js/_alpine.ts +6 -0
- package/core-js/_slider.ts +22 -11
- package/core-js/blocks-components/button.tsx +17 -2
- package/core-js/blocks-components/custom-image-sizes-panel.tsx +3 -1
- package/core-js/blocks-components/typography-picker-select.tsx +16 -1
- package/core-js/blocks-filters/_filter-core-typography.tsx +11 -1
- package/core-js/blocks-filters/_slider-settings.tsx +1 -1
- package/core-js/blocks-filters/_wrap-with-container.tsx +104 -0
- package/core-js/blocks-filters/responsive-settings/AGENTS.md +255 -0
- package/core-js/blocks-filters/responsive-settings/components/AppliedClassesViewer.tsx +189 -0
- package/core-js/blocks-filters/responsive-settings/components/BoxModelControl.tsx +346 -0
- package/core-js/blocks-filters/responsive-settings/components/BreakpointResetButton.tsx +94 -0
- package/core-js/blocks-filters/responsive-settings/components/DebugPanel.tsx +67 -0
- package/core-js/blocks-filters/responsive-settings/components/InheritedIndicator.tsx +32 -0
- package/core-js/blocks-filters/responsive-settings/components/LinkedValuesControl.tsx +55 -0
- package/core-js/blocks-filters/responsive-settings/components/ResponsiveSelectGroup.tsx +185 -0
- package/core-js/blocks-filters/responsive-settings/components/ResponsiveTabPanel.tsx +106 -0
- package/core-js/blocks-filters/responsive-settings/index.tsx +97 -148
- package/core-js/blocks-filters/responsive-settings/migration.ts +86 -0
- package/core-js/blocks-filters/responsive-settings/panels/BlockLinkPanel.tsx +38 -0
- package/core-js/blocks-filters/responsive-settings/panels/BorderPanel.tsx +61 -0
- package/core-js/blocks-filters/responsive-settings/panels/DisplayLayoutPanel.tsx +92 -0
- package/core-js/blocks-filters/responsive-settings/panels/SpacingPanel.tsx +63 -0
- package/core-js/blocks-filters/responsive-settings/panels/index.ts +4 -0
- package/core-js/blocks-filters/responsive-settings/registry.ts +88 -0
- package/core-js/blocks-filters/responsive-settings/settings/block-link/index.ts +3 -0
- package/core-js/blocks-filters/responsive-settings/settings/block-link/panel.tsx +6 -6
- package/core-js/blocks-filters/responsive-settings/settings/block-link/registration.ts +35 -0
- package/core-js/blocks-filters/responsive-settings/settings/border/border/properties.ts +1 -2
- package/core-js/blocks-filters/responsive-settings/settings/border/border/settings.tsx +21 -3
- package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/index.tsx +2 -1
- package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/properties.ts +6 -29
- package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/settings.tsx +79 -6
- package/core-js/blocks-filters/responsive-settings/settings/border/index.ts +5 -1
- package/core-js/blocks-filters/responsive-settings/settings/border/panel.tsx +5 -54
- package/core-js/blocks-filters/responsive-settings/settings/border/registration.ts +84 -0
- package/core-js/blocks-filters/responsive-settings/settings/border/settings.tsx +21 -0
- package/core-js/blocks-filters/responsive-settings/settings/flex-item/index.ts +4 -0
- package/core-js/blocks-filters/responsive-settings/settings/flex-item/properties.ts +60 -0
- package/core-js/blocks-filters/responsive-settings/settings/flex-item/registration.ts +78 -0
- package/core-js/blocks-filters/responsive-settings/settings/flex-item/settings.tsx +90 -0
- package/core-js/blocks-filters/responsive-settings/settings/flexbox/index.ts +4 -0
- package/core-js/blocks-filters/responsive-settings/settings/flexbox/properties.ts +80 -0
- package/core-js/blocks-filters/responsive-settings/settings/flexbox/registration.ts +66 -0
- package/core-js/blocks-filters/responsive-settings/settings/flexbox/settings.tsx +78 -0
- package/core-js/blocks-filters/responsive-settings/settings/grid/index.ts +4 -0
- package/core-js/blocks-filters/responsive-settings/settings/grid/properties.ts +72 -0
- package/core-js/blocks-filters/responsive-settings/settings/grid/registration.ts +66 -0
- package/core-js/blocks-filters/responsive-settings/settings/grid/settings.tsx +78 -0
- package/core-js/blocks-filters/responsive-settings/settings/grid-item/index.ts +4 -0
- package/core-js/blocks-filters/responsive-settings/settings/grid-item/properties.ts +44 -0
- package/core-js/blocks-filters/responsive-settings/settings/grid-item/registration.ts +74 -0
- package/core-js/blocks-filters/responsive-settings/settings/grid-item/settings.tsx +87 -0
- package/core-js/blocks-filters/responsive-settings/settings/layout/index.ts +4 -0
- package/core-js/blocks-filters/responsive-settings/settings/layout/properties.ts +51 -0
- package/core-js/blocks-filters/responsive-settings/settings/layout/registration.ts +96 -0
- package/core-js/blocks-filters/responsive-settings/settings/layout/settings.tsx +64 -0
- package/core-js/blocks-filters/responsive-settings/settings/presets/index.ts +4 -0
- package/core-js/blocks-filters/responsive-settings/settings/presets/presets.ts +52 -0
- package/core-js/blocks-filters/responsive-settings/settings/presets/registration.ts +53 -0
- package/core-js/blocks-filters/responsive-settings/settings/presets/settings.tsx +100 -0
- package/core-js/blocks-filters/responsive-settings/settings/shared/gap-values.ts +16 -0
- package/core-js/blocks-filters/responsive-settings/settings/shared/layout-values.ts +56 -0
- package/core-js/blocks-filters/responsive-settings/settings/shared/tw-values.ts +107 -0
- package/core-js/blocks-filters/responsive-settings/settings/sizing/index.ts +4 -0
- package/core-js/blocks-filters/responsive-settings/settings/sizing/properties.ts +71 -0
- package/core-js/blocks-filters/responsive-settings/settings/sizing/registration.ts +52 -0
- package/core-js/blocks-filters/responsive-settings/settings/sizing/settings.tsx +96 -0
- package/core-js/blocks-filters/responsive-settings/settings/spacing/index.ts +7 -2
- package/core-js/blocks-filters/responsive-settings/settings/spacing/panel.tsx +5 -45
- package/core-js/blocks-filters/responsive-settings/settings/spacing/properties.ts +51 -29
- package/core-js/blocks-filters/responsive-settings/settings/spacing/registration.ts +53 -0
- package/core-js/blocks-filters/responsive-settings/settings/spacing/settings.tsx +26 -55
- package/core-js/blocks-filters/responsive-settings/types/index.ts +174 -28
- package/core-js/blocks-filters/responsive-settings/utils.ts +247 -216
- package/core-js/config/index.ts +6 -0
- package/core-js/config/webentor-config.ts +44 -2
- package/core-js/index.ts +8 -10
- package/core-js/types/index.ts +6 -0
- package/package.json +116 -6
- package/public/build/assets/_utils-CzK6Vfiv.js +2 -0
- package/public/build/assets/{_utils-PDaZ1Dn1.js.map → _utils-CzK6Vfiv.js.map} +1 -1
- package/public/build/assets/coreAppStyles-CukxHLz7.css +1 -0
- package/public/build/assets/coreEditorJs-DYd3ZopL.js +366 -0
- package/public/build/assets/coreEditorJs-DYd3ZopL.js.map +1 -0
- package/public/build/assets/coreEditorStyles-I9xzOGSX.css +1 -0
- package/public/build/assets/resources/blocks/e-table/{script-BIchbcPK.js → script-C_Z50hjm.js} +2 -2
- package/public/build/assets/resources/blocks/e-table/{script-BIchbcPK.js.map → script-C_Z50hjm.js.map} +1 -1
- package/public/build/assets/{sliderJs-Ch69_tVA.js → sliderJs-CyGnrv0Q.js} +3 -3
- package/public/build/assets/{sliderJs-Ch69_tVA.js.map → sliderJs-CyGnrv0Q.js.map} +1 -1
- package/public/build/manifest.json +10 -10
- package/resources/blocks/e-accordion-group/block.json +6 -4
- package/resources/blocks/e-gallery/block.json +2 -2
- package/resources/blocks/e-gallery/e-gallery.block.tsx +4 -0
- package/resources/blocks/e-image/e-image.block.tsx +4 -0
- package/resources/blocks/e-slider/block.json +3 -2
- package/resources/blocks/e-tab-container/block.json +2 -1
- package/resources/blocks/e-tabs/block.json +2 -1
- package/resources/blocks/l-flexible-container/block.json +3 -2
- package/resources/blocks/l-mobile-nav/block.json +2 -1
- package/resources/blocks/l-nav-menu/block.json +2 -1
- package/resources/blocks/l-nav-menu/l-nav-menu.block.tsx +2 -0
- package/resources/blocks/l-section/block.json +7 -5
- package/resources/blocks/l-section/l-section.block.tsx +40 -31
- package/resources/scripts/editor.ts +2 -0
- package/resources/styles/common/_editor.css +22 -0
- package/resources/styles/common/_utilities.css +210 -0
- package/core-js/blocks-filters/responsive-settings/constants.ts +0 -11
- package/core-js/blocks-filters/responsive-settings/settings/container/display/index.ts +0 -2
- package/core-js/blocks-filters/responsive-settings/settings/container/display/properties.ts +0 -167
- package/core-js/blocks-filters/responsive-settings/settings/container/display/settings.tsx +0 -73
- package/core-js/blocks-filters/responsive-settings/settings/container/flexbox/index.ts +0 -2
- package/core-js/blocks-filters/responsive-settings/settings/container/flexbox/properties.ts +0 -187
- package/core-js/blocks-filters/responsive-settings/settings/container/flexbox/settings.tsx +0 -131
- package/core-js/blocks-filters/responsive-settings/settings/container/grid/index.ts +0 -2
- package/core-js/blocks-filters/responsive-settings/settings/container/grid/properties.ts +0 -187
- package/core-js/blocks-filters/responsive-settings/settings/container/grid/settings.tsx +0 -132
- package/core-js/blocks-filters/responsive-settings/settings/container/index.ts +0 -4
- package/core-js/blocks-filters/responsive-settings/settings/container/panel.tsx +0 -92
- package/public/build/assets/_utils-PDaZ1Dn1.js +0 -2
- package/public/build/assets/coreAppStyles-Dp0WYk4N.css +0 -1
- package/public/build/assets/coreEditorJs-Cyc87wTo.js +0 -366
- package/public/build/assets/coreEditorJs-Cyc87wTo.js.map +0 -1
- package/public/build/assets/coreEditorStyles-D8-nNpQG.css +0 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Display value helpers.
|
|
3
|
+
*
|
|
4
|
+
* Generic (non-display) cascade utilities live in utils.ts.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Resolve the "display" value for a given breakpoint (explicit only, no cascade).
|
|
9
|
+
*
|
|
10
|
+
* This is the canonical way to read the display mode for modules that need it
|
|
11
|
+
* (flexbox, grid, flex-item, grid-item).
|
|
12
|
+
*/
|
|
13
|
+
export const getDisplayValue = (
|
|
14
|
+
attributes: Record<string, any>,
|
|
15
|
+
breakpoint: string,
|
|
16
|
+
): string | undefined => {
|
|
17
|
+
return attributes?.layout?.display?.value?.[breakpoint];
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the parent display value for a given breakpoint (explicit only).
|
|
22
|
+
*/
|
|
23
|
+
export const getParentDisplayValue = (
|
|
24
|
+
parentAttributes: Record<string, any> | undefined,
|
|
25
|
+
breakpoint: string,
|
|
26
|
+
): string | undefined => {
|
|
27
|
+
if (!parentAttributes) return undefined;
|
|
28
|
+
return getDisplayValue(parentAttributes, breakpoint);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// ─── Display-specific cascade ───────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Cascaded display value — walks breakpoints and returns the effective
|
|
35
|
+
* display mode at the given breakpoint.
|
|
36
|
+
*/
|
|
37
|
+
export const getEffectiveDisplayValue = (
|
|
38
|
+
attributes: Record<string, any>,
|
|
39
|
+
breakpoint: string,
|
|
40
|
+
breakpoints: string[],
|
|
41
|
+
): string | undefined => {
|
|
42
|
+
const targetIndex = breakpoints.indexOf(breakpoint);
|
|
43
|
+
if (targetIndex === -1) return undefined;
|
|
44
|
+
let effective: string | undefined;
|
|
45
|
+
for (let i = 0; i <= targetIndex; i++) {
|
|
46
|
+
const val = getDisplayValue(attributes, breakpoints[i]);
|
|
47
|
+
if (val !== undefined && val !== '') effective = val;
|
|
48
|
+
}
|
|
49
|
+
return effective;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Cascaded parent display value — same cascade logic applied to
|
|
54
|
+
* the parent block's attributes.
|
|
55
|
+
*/
|
|
56
|
+
export const getEffectiveParentDisplayValue = (
|
|
57
|
+
parentAttributes: Record<string, any> | undefined,
|
|
58
|
+
breakpoint: string,
|
|
59
|
+
breakpoints: string[],
|
|
60
|
+
): string | undefined => {
|
|
61
|
+
if (!parentAttributes) return undefined;
|
|
62
|
+
return getEffectiveDisplayValue(parentAttributes, breakpoint, breakpoints);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Display-specific inheritance source.
|
|
67
|
+
* Returns the breakpoint name the display value cascades from,
|
|
68
|
+
* or null if explicitly set at the current breakpoint.
|
|
69
|
+
*/
|
|
70
|
+
export const getDisplayInheritedFromBreakpoint = (
|
|
71
|
+
attributes: Record<string, any>,
|
|
72
|
+
breakpoint: string,
|
|
73
|
+
breakpoints: string[],
|
|
74
|
+
): string | null => {
|
|
75
|
+
const targetIndex = breakpoints.indexOf(breakpoint);
|
|
76
|
+
if (targetIndex === -1) return null;
|
|
77
|
+
|
|
78
|
+
const explicitVal = getDisplayValue(attributes, breakpoint);
|
|
79
|
+
if (explicitVal !== undefined && explicitVal !== '') return null;
|
|
80
|
+
|
|
81
|
+
for (let i = targetIndex - 1; i >= 0; i--) {
|
|
82
|
+
const val = getDisplayValue(attributes, breakpoints[i]);
|
|
83
|
+
if (val !== undefined && val !== '') return breakpoints[i];
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BlockLinkPanel — Standalone panel for block link settings.
|
|
3
|
+
*
|
|
4
|
+
* Block link is non-responsive, so this panel renders without
|
|
5
|
+
* breakpoint tabs. Separated from DisplayLayoutPanel to avoid
|
|
6
|
+
* confusion about its scope.
|
|
7
|
+
*/
|
|
8
|
+
import { PanelBody } from '@wordpress/components';
|
|
9
|
+
import { __ } from '@wordpress/i18n';
|
|
10
|
+
|
|
11
|
+
import { registry } from '../registry';
|
|
12
|
+
import { BlockPanelProps } from '../types';
|
|
13
|
+
|
|
14
|
+
export const BlockLinkPanel = (props: BlockPanelProps) => {
|
|
15
|
+
const { attributes } = props;
|
|
16
|
+
const modules = registry.getByPanelGroup('blockLink');
|
|
17
|
+
|
|
18
|
+
const hasAnyAttributes = modules.some((def) =>
|
|
19
|
+
Object.keys(def.attributeSchema).some((key) => !!attributes?.[key]),
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
if (!hasAnyAttributes) return null;
|
|
23
|
+
|
|
24
|
+
const hasNonDefaults = modules.some((def) =>
|
|
25
|
+
def.hasActiveSettings(attributes, 'basic'),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<PanelBody
|
|
30
|
+
title={__('Block Link', 'webentor') + (hasNonDefaults ? ' *' : '')}
|
|
31
|
+
initialOpen={false}
|
|
32
|
+
>
|
|
33
|
+
{modules.map((def) => (
|
|
34
|
+
<def.SettingsComponent key={def.name} {...props} breakpoint="basic" />
|
|
35
|
+
))}
|
|
36
|
+
</PanelBody>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BorderPanel — Thin panel wrapper for panelGroup='border'.
|
|
3
|
+
*
|
|
4
|
+
* Renders border + border-radius settings within a single PanelBody
|
|
5
|
+
* with responsive breakpoint tabs.
|
|
6
|
+
*/
|
|
7
|
+
import { PanelBody } from '@wordpress/components';
|
|
8
|
+
import { __ } from '@wordpress/i18n';
|
|
9
|
+
|
|
10
|
+
import { BreakpointResetButton } from '../components/BreakpointResetButton';
|
|
11
|
+
import { ResponsiveTabPanel } from '../components/ResponsiveTabPanel';
|
|
12
|
+
import { registry } from '../registry';
|
|
13
|
+
import { BlockPanelProps } from '../types';
|
|
14
|
+
|
|
15
|
+
export const BorderPanel = (props: BlockPanelProps) => {
|
|
16
|
+
const { attributes, setAttributes, breakpoints } = props;
|
|
17
|
+
const modules = registry.getByPanelGroup('border');
|
|
18
|
+
|
|
19
|
+
const hasAnyAttributes = modules.some((def) =>
|
|
20
|
+
Object.keys(def.attributeSchema).some((key) => !!attributes?.[key]),
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
if (!hasAnyAttributes) return null;
|
|
24
|
+
|
|
25
|
+
const hasActiveSettings = (breakpoint: string): boolean => {
|
|
26
|
+
return modules.some((def) => def.hasActiveSettings(attributes, breakpoint));
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const hasNonDefaults = breakpoints.some((bp) => hasActiveSettings(bp));
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<PanelBody
|
|
33
|
+
title={__('Border Settings', 'webentor') + (hasNonDefaults ? ' *' : '')}
|
|
34
|
+
initialOpen={false}
|
|
35
|
+
>
|
|
36
|
+
<ResponsiveTabPanel
|
|
37
|
+
breakpoints={breakpoints}
|
|
38
|
+
hasActiveSettings={hasActiveSettings}
|
|
39
|
+
screens={props.twTheme?.screens as Record<string, any>}
|
|
40
|
+
>
|
|
41
|
+
{(breakpoint) => (
|
|
42
|
+
<>
|
|
43
|
+
<BreakpointResetButton
|
|
44
|
+
panelGroup="border"
|
|
45
|
+
breakpoint={breakpoint}
|
|
46
|
+
attributes={attributes}
|
|
47
|
+
setAttributes={setAttributes}
|
|
48
|
+
/>
|
|
49
|
+
{modules.map((def) => (
|
|
50
|
+
<def.SettingsComponent
|
|
51
|
+
key={def.name}
|
|
52
|
+
{...props}
|
|
53
|
+
breakpoint={breakpoint}
|
|
54
|
+
/>
|
|
55
|
+
))}
|
|
56
|
+
</>
|
|
57
|
+
)}
|
|
58
|
+
</ResponsiveTabPanel>
|
|
59
|
+
</PanelBody>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DisplayLayoutPanel — Thin panel wrapper for panelGroup='displayLayout'.
|
|
3
|
+
*
|
|
4
|
+
* Groups presets, layout, sizing, flexbox, grid, flex-item, and grid-item
|
|
5
|
+
* into a single "Display & Layout Settings" panel. Each module renders
|
|
6
|
+
* conditionally (e.g. flexbox only shows when display=flex).
|
|
7
|
+
*
|
|
8
|
+
* The panel also supports a filter hook for injecting content before tabs
|
|
9
|
+
* (e.g. preset buttons or block-specific UI).
|
|
10
|
+
*/
|
|
11
|
+
import { PanelBody } from '@wordpress/components';
|
|
12
|
+
import { applyFilters } from '@wordpress/hooks';
|
|
13
|
+
import { __ } from '@wordpress/i18n';
|
|
14
|
+
|
|
15
|
+
import { useBlockParent } from '../../../blocks-utils/_use-block-parent';
|
|
16
|
+
import { BreakpointResetButton } from '../components/BreakpointResetButton';
|
|
17
|
+
import { ResponsiveTabPanel } from '../components/ResponsiveTabPanel';
|
|
18
|
+
import { registry } from '../registry';
|
|
19
|
+
import { PresetSettings } from '../settings/presets/settings';
|
|
20
|
+
import { BlockPanelProps, ClassGenContext } from '../types';
|
|
21
|
+
|
|
22
|
+
export const DisplayLayoutPanel = (props: BlockPanelProps) => {
|
|
23
|
+
const { attributes, setAttributes, breakpoints } = props;
|
|
24
|
+
const modules = registry.getByPanelGroup('displayLayout');
|
|
25
|
+
|
|
26
|
+
const parentBlock = useBlockParent();
|
|
27
|
+
|
|
28
|
+
const hasAnyAttributes = modules.some((def) =>
|
|
29
|
+
Object.keys(def.attributeSchema).some((key) => !!attributes?.[key]),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
if (!hasAnyAttributes) return null;
|
|
33
|
+
|
|
34
|
+
const context: ClassGenContext = {
|
|
35
|
+
blockName: props.name,
|
|
36
|
+
supports: {},
|
|
37
|
+
parentBlockAttributes: parentBlock?.attributes,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const hasActiveSettings = (breakpoint: string): boolean => {
|
|
41
|
+
return modules.some((def) =>
|
|
42
|
+
def.hasActiveSettings(attributes, breakpoint, context),
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const hasNonDefaults = breakpoints.some((bp) => hasActiveSettings(bp));
|
|
47
|
+
|
|
48
|
+
const beforeTabsContent = applyFilters(
|
|
49
|
+
'webentor.displayLayoutPanel.beforeTabs',
|
|
50
|
+
null,
|
|
51
|
+
props,
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
// Show presets above tabs (they apply globally, not per-breakpoint)
|
|
55
|
+
const showPresets = !!attributes?._preset || attributes?._preset === '';
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<PanelBody
|
|
59
|
+
title={
|
|
60
|
+
__('Display & Layout Settings', 'webentor') +
|
|
61
|
+
(hasNonDefaults ? ' *' : '')
|
|
62
|
+
}
|
|
63
|
+
initialOpen={true}
|
|
64
|
+
>
|
|
65
|
+
{showPresets && <PresetSettings {...props} />}
|
|
66
|
+
{beforeTabsContent}
|
|
67
|
+
<ResponsiveTabPanel
|
|
68
|
+
breakpoints={breakpoints}
|
|
69
|
+
hasActiveSettings={hasActiveSettings}
|
|
70
|
+
screens={props.twTheme?.screens as Record<string, any>}
|
|
71
|
+
>
|
|
72
|
+
{(breakpoint) => (
|
|
73
|
+
<>
|
|
74
|
+
<BreakpointResetButton
|
|
75
|
+
panelGroup="displayLayout"
|
|
76
|
+
breakpoint={breakpoint}
|
|
77
|
+
attributes={attributes}
|
|
78
|
+
setAttributes={setAttributes}
|
|
79
|
+
/>
|
|
80
|
+
{modules.map((def) => (
|
|
81
|
+
<def.SettingsComponent
|
|
82
|
+
key={def.name}
|
|
83
|
+
{...props}
|
|
84
|
+
breakpoint={breakpoint}
|
|
85
|
+
/>
|
|
86
|
+
))}
|
|
87
|
+
</>
|
|
88
|
+
)}
|
|
89
|
+
</ResponsiveTabPanel>
|
|
90
|
+
</PanelBody>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SpacingPanel — Thin panel wrapper for panelGroup='spacing'.
|
|
3
|
+
*
|
|
4
|
+
* Renders a single PanelBody with responsive breakpoint tabs,
|
|
5
|
+
* then loops over all setting modules registered to the 'spacing'
|
|
6
|
+
* panel group and renders each one's SettingsComponent inline.
|
|
7
|
+
*/
|
|
8
|
+
import { PanelBody } from '@wordpress/components';
|
|
9
|
+
import { __ } from '@wordpress/i18n';
|
|
10
|
+
|
|
11
|
+
import { BreakpointResetButton } from '../components/BreakpointResetButton';
|
|
12
|
+
import { ResponsiveTabPanel } from '../components/ResponsiveTabPanel';
|
|
13
|
+
import { registry } from '../registry';
|
|
14
|
+
import { BlockPanelProps } from '../types';
|
|
15
|
+
|
|
16
|
+
export const SpacingPanel = (props: BlockPanelProps) => {
|
|
17
|
+
const { attributes, setAttributes, breakpoints } = props;
|
|
18
|
+
const modules = registry.getByPanelGroup('spacing');
|
|
19
|
+
|
|
20
|
+
const hasAnyAttributes = modules.some((def) =>
|
|
21
|
+
Object.keys(def.attributeSchema).some((key) => !!attributes?.[key]),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
if (!hasAnyAttributes) return null;
|
|
25
|
+
|
|
26
|
+
const hasActiveSettings = (breakpoint: string): boolean => {
|
|
27
|
+
return modules.some((def) => def.hasActiveSettings(attributes, breakpoint));
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Panel-level check: any breakpoint has non-default values
|
|
31
|
+
const hasNonDefaults = breakpoints.some((bp) => hasActiveSettings(bp));
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<PanelBody
|
|
35
|
+
title={__('Spacing Settings', 'webentor') + (hasNonDefaults ? ' *' : '')}
|
|
36
|
+
initialOpen={false}
|
|
37
|
+
>
|
|
38
|
+
<ResponsiveTabPanel
|
|
39
|
+
breakpoints={breakpoints}
|
|
40
|
+
hasActiveSettings={hasActiveSettings}
|
|
41
|
+
screens={props.twTheme?.screens as Record<string, any>}
|
|
42
|
+
>
|
|
43
|
+
{(breakpoint) => (
|
|
44
|
+
<>
|
|
45
|
+
<BreakpointResetButton
|
|
46
|
+
panelGroup="spacing"
|
|
47
|
+
breakpoint={breakpoint}
|
|
48
|
+
attributes={attributes}
|
|
49
|
+
setAttributes={setAttributes}
|
|
50
|
+
/>
|
|
51
|
+
{modules.map((def) => (
|
|
52
|
+
<def.SettingsComponent
|
|
53
|
+
key={def.name}
|
|
54
|
+
{...props}
|
|
55
|
+
breakpoint={breakpoint}
|
|
56
|
+
/>
|
|
57
|
+
))}
|
|
58
|
+
</>
|
|
59
|
+
)}
|
|
60
|
+
</ResponsiveTabPanel>
|
|
61
|
+
</PanelBody>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SettingsRegistry — Central registry for responsive setting modules.
|
|
3
|
+
*
|
|
4
|
+
* Each setting module (layout, sizing, flexbox, etc.) self-registers via
|
|
5
|
+
* its registration.ts side-effect import. The registry provides lookup
|
|
6
|
+
* by name and by panelGroup for panel components to query.
|
|
7
|
+
*
|
|
8
|
+
* Architecture: Setting modules declare a panelGroup ('spacing' | 'displayLayout' | 'border')
|
|
9
|
+
* which determines which panel wrapper renders them. The panel wrapper
|
|
10
|
+
* queries getByPanelGroup() and renders each module's SettingsComponent
|
|
11
|
+
* in order.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { ClassGenContext, PanelGroup, SettingDefinition } from './types';
|
|
15
|
+
|
|
16
|
+
export type { ClassGenContext, PanelGroup, SettingDefinition };
|
|
17
|
+
|
|
18
|
+
// Re-export PropertyDefinition for backward compat with existing imports
|
|
19
|
+
export type { PropertyDefinition } from './types';
|
|
20
|
+
|
|
21
|
+
class SettingsRegistry {
|
|
22
|
+
private settings = new Map<string, SettingDefinition>();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Register a setting module. Called as a side-effect in each module's
|
|
26
|
+
* registration.ts file. Duplicate names will overwrite (useful for
|
|
27
|
+
* theme/plugin overrides).
|
|
28
|
+
*/
|
|
29
|
+
register(def: SettingDefinition): void {
|
|
30
|
+
this.settings.set(def.name, def);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** All registered settings sorted by panelGroup priority then order */
|
|
34
|
+
getAll(): SettingDefinition[] {
|
|
35
|
+
return Array.from(this.settings.values()).sort((a, b) => a.order - b.order);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Get a specific setting by name */
|
|
39
|
+
getByName(name: string): SettingDefinition | undefined {
|
|
40
|
+
return this.settings.get(name);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get all settings for a given panel group, sorted by order.
|
|
45
|
+
* Panel components use this to discover which modules to render.
|
|
46
|
+
*/
|
|
47
|
+
getByPanelGroup(group: PanelGroup): SettingDefinition[] {
|
|
48
|
+
return this.getAll().filter((def) => def.panelGroup === group);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Merge all attribute schemas into a single object */
|
|
52
|
+
getAllAttributeSchemas(): Record<string, any> {
|
|
53
|
+
const schemas: Record<string, any> = {};
|
|
54
|
+
for (const def of this.settings.values()) {
|
|
55
|
+
Object.assign(schemas, def.attributeSchema);
|
|
56
|
+
}
|
|
57
|
+
return schemas;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Check if a block supports a setting by matching its supportKey
|
|
62
|
+
* against the block's supports.webentor config.
|
|
63
|
+
*/
|
|
64
|
+
isSupported(
|
|
65
|
+
supports: Record<string, any> | undefined,
|
|
66
|
+
def: SettingDefinition,
|
|
67
|
+
): boolean {
|
|
68
|
+
const keys = Array.isArray(def.supportKey)
|
|
69
|
+
? def.supportKey
|
|
70
|
+
: [def.supportKey];
|
|
71
|
+
return keys.some((key) => !!supports?.webentor?.[key]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get unique panel groups that have at least one registered setting.
|
|
76
|
+
* Useful for determining which panels to render.
|
|
77
|
+
*/
|
|
78
|
+
getActivePanelGroups(): PanelGroup[] {
|
|
79
|
+
const groups = new Set<PanelGroup>();
|
|
80
|
+
for (const def of this.settings.values()) {
|
|
81
|
+
groups.add(def.panelGroup);
|
|
82
|
+
}
|
|
83
|
+
return Array.from(groups);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Singleton registry instance shared across all modules */
|
|
88
|
+
export const registry = new SettingsRegistry();
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as BlockEditor from '@wordpress/block-editor';
|
|
2
2
|
import { __ } from '@wordpress/i18n';
|
|
3
3
|
|
|
4
|
-
import { setImmutably } from '
|
|
5
|
-
import { BlockPanelProps } from '
|
|
4
|
+
import { setImmutably } from '../../../../_utils';
|
|
5
|
+
import { BlockPanelProps } from '../../types';
|
|
6
|
+
|
|
7
|
+
// WordPress ships this control, but the package typings still expose it as experimental.
|
|
8
|
+
const LinkControl = (BlockEditor as any).__experimentalLinkControl;
|
|
6
9
|
|
|
7
10
|
export const BlockLinkPanel = ({
|
|
8
11
|
attributes,
|
|
@@ -14,9 +17,6 @@ export const BlockLinkPanel = ({
|
|
|
14
17
|
|
|
15
18
|
return (
|
|
16
19
|
<div className="w-link-settings" style={{ marginBottom: '16px' }}>
|
|
17
|
-
<h3 style={{ padding: '16px', paddingBottom: '0px' }}>
|
|
18
|
-
{__('Block Link', 'webentor')}
|
|
19
|
-
</h3>
|
|
20
20
|
<div style={{ padding: '16px', paddingTop: '0px', fontSize: '12px' }}>
|
|
21
21
|
{__('This whole block can act like a link', 'webentor')}
|
|
22
22
|
</div>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block link module registration.
|
|
3
|
+
*
|
|
4
|
+
* Block link is non-responsive and doesn't generate Tailwind classes.
|
|
5
|
+
* Uses its own panelGroup 'blockLink' with a standalone panel wrapper
|
|
6
|
+
* (panels/BlockLinkPanel.tsx) that renders without breakpoint tabs.
|
|
7
|
+
*/
|
|
8
|
+
import { registry } from '../../registry';
|
|
9
|
+
import { ClassGenContext } from '../../types';
|
|
10
|
+
import { BlockLinkPanel } from './panel';
|
|
11
|
+
|
|
12
|
+
registry.register({
|
|
13
|
+
name: 'blockLink',
|
|
14
|
+
panelGroup: 'blockLink',
|
|
15
|
+
order: 100,
|
|
16
|
+
attributeKey: 'blockLink',
|
|
17
|
+
supportKey: 'blockLink',
|
|
18
|
+
attributeSchema: {
|
|
19
|
+
blockLink: { type: 'object', default: {} },
|
|
20
|
+
},
|
|
21
|
+
SettingsComponent: BlockLinkPanel,
|
|
22
|
+
generateClasses: (
|
|
23
|
+
_attributes: Record<string, any>,
|
|
24
|
+
_breakpoint: string,
|
|
25
|
+
_context: ClassGenContext,
|
|
26
|
+
): string[] => {
|
|
27
|
+
return [];
|
|
28
|
+
},
|
|
29
|
+
hasActiveSettings: (
|
|
30
|
+
attributes: Record<string, any>,
|
|
31
|
+
_breakpoint: string,
|
|
32
|
+
): boolean => {
|
|
33
|
+
return !!attributes?.blockLink?.url;
|
|
34
|
+
},
|
|
35
|
+
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
2
|
|
|
3
|
-
import { WebentorConfig } from '
|
|
4
|
-
|
|
3
|
+
import { WebentorConfig } from '../../../../../types/_webentor-config';
|
|
5
4
|
import { getPixelFromRemValue } from '../../../utils';
|
|
6
5
|
|
|
7
6
|
export const getBorderProperties = (twTheme: WebentorConfig['theme']) => [
|
|
@@ -15,10 +15,13 @@ import {
|
|
|
15
15
|
getColorSlugByColor,
|
|
16
16
|
isEmpty,
|
|
17
17
|
setImmutably,
|
|
18
|
-
} from '
|
|
19
|
-
|
|
18
|
+
} from '../../../../../_utils';
|
|
19
|
+
import { InheritedIndicator } from '../../../components/InheritedIndicator';
|
|
20
20
|
import { BlockPanelProps } from '../../../types';
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
getObjectInheritedFromBreakpoint,
|
|
23
|
+
prepareTailwindBorderClassesFromSettings,
|
|
24
|
+
} from '../../../utils';
|
|
22
25
|
import { getBorderProperties } from './properties';
|
|
23
26
|
|
|
24
27
|
interface BorderSettingsProps extends BlockPanelProps {
|
|
@@ -78,6 +81,7 @@ const WebentorBorderControl = ({
|
|
|
78
81
|
label={property.label}
|
|
79
82
|
value={value?.[property.name]}
|
|
80
83
|
options={property.values}
|
|
84
|
+
__nextHasNoMarginBottom
|
|
81
85
|
onChange={(selectValue) =>
|
|
82
86
|
onChange({ ...value, [property.name]: selectValue })
|
|
83
87
|
}
|
|
@@ -111,6 +115,7 @@ export const BorderSettings = ({
|
|
|
111
115
|
setAttributes,
|
|
112
116
|
name,
|
|
113
117
|
breakpoint,
|
|
118
|
+
breakpoints,
|
|
114
119
|
twTheme,
|
|
115
120
|
}: BorderSettingsProps) => {
|
|
116
121
|
if (!attributes?.border) {
|
|
@@ -220,9 +225,22 @@ export const BorderSettings = ({
|
|
|
220
225
|
justifyItems: 'center',
|
|
221
226
|
};
|
|
222
227
|
|
|
228
|
+
const borderInheritedFrom = breakpoints?.length
|
|
229
|
+
? getObjectInheritedFromBreakpoint(
|
|
230
|
+
attributes,
|
|
231
|
+
'border',
|
|
232
|
+
'border',
|
|
233
|
+
breakpoint,
|
|
234
|
+
breakpoints,
|
|
235
|
+
)
|
|
236
|
+
: null;
|
|
237
|
+
|
|
223
238
|
return (
|
|
224
239
|
<div className="wbtr:my-2 wbtr:flex wbtr:flex-col wbtr:gap-2 wbtr:border wbtr:border-editor-border wbtr:p-2">
|
|
225
240
|
<p className="wbtr:text-12 wbtr:uppercase">{__('Border', 'webentor')}</p>
|
|
241
|
+
{borderInheritedFrom && (
|
|
242
|
+
<InheritedIndicator fromBreakpoint={borderInheritedFrom} />
|
|
243
|
+
)}
|
|
226
244
|
|
|
227
245
|
<div style={containerStyle}>
|
|
228
246
|
{isLinked ? (
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { BorderRadiusSettings } from './settings';
|
|
2
|
+
export { getBorderRadiusValues } from './properties';
|
package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/properties.ts
CHANGED
|
@@ -1,31 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { WebentorConfig } from '../../../../../types/_webentor-config';
|
|
2
|
+
import { createTwThemeValues } from '../../shared/tw-values';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
label: `${key} (${twTheme?.borderRadius[key]})`,
|
|
8
|
-
value: key,
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
values.unshift({
|
|
12
|
-
label: __('None selected', 'webentor'),
|
|
13
|
-
value: '',
|
|
4
|
+
export const getBorderRadiusValues = (twTheme: WebentorConfig['theme']) =>
|
|
5
|
+
createTwThemeValues(twTheme, 'borderRadius', '', {
|
|
6
|
+
sort: false,
|
|
7
|
+
labelFormatter: (key, rawValue) => `${key} (${rawValue})`,
|
|
14
8
|
});
|
|
15
|
-
|
|
16
|
-
return values;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
// export const getBorderRadiusProperties = (twTheme: WebentorConfig['theme']) => [
|
|
20
|
-
// {
|
|
21
|
-
// name: 'radius',
|
|
22
|
-
// label: __('Radius', 'webentor'),
|
|
23
|
-
// values: [
|
|
24
|
-
// { label: __('None selected', 'webentor'), value: '' },
|
|
25
|
-
// ...Object.keys(twTheme?.borderRadius || {}).map((key) => ({
|
|
26
|
-
// label: key,
|
|
27
|
-
// value: key,
|
|
28
|
-
// })),
|
|
29
|
-
// ],
|
|
30
|
-
// },
|
|
31
|
-
// ];
|