@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.
Files changed (126) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +41 -0
  3. package/core-js/_alpine.ts +6 -0
  4. package/core-js/_slider.ts +22 -11
  5. package/core-js/blocks-components/button.tsx +17 -2
  6. package/core-js/blocks-components/custom-image-sizes-panel.tsx +3 -1
  7. package/core-js/blocks-components/typography-picker-select.tsx +16 -1
  8. package/core-js/blocks-filters/_filter-core-typography.tsx +11 -1
  9. package/core-js/blocks-filters/_slider-settings.tsx +1 -1
  10. package/core-js/blocks-filters/_wrap-with-container.tsx +104 -0
  11. package/core-js/blocks-filters/responsive-settings/AGENTS.md +255 -0
  12. package/core-js/blocks-filters/responsive-settings/components/AppliedClassesViewer.tsx +189 -0
  13. package/core-js/blocks-filters/responsive-settings/components/BoxModelControl.tsx +346 -0
  14. package/core-js/blocks-filters/responsive-settings/components/BreakpointResetButton.tsx +94 -0
  15. package/core-js/blocks-filters/responsive-settings/components/DebugPanel.tsx +67 -0
  16. package/core-js/blocks-filters/responsive-settings/components/InheritedIndicator.tsx +32 -0
  17. package/core-js/blocks-filters/responsive-settings/components/LinkedValuesControl.tsx +55 -0
  18. package/core-js/blocks-filters/responsive-settings/components/ResponsiveSelectGroup.tsx +185 -0
  19. package/core-js/blocks-filters/responsive-settings/components/ResponsiveTabPanel.tsx +106 -0
  20. package/core-js/blocks-filters/responsive-settings/index.tsx +97 -148
  21. package/core-js/blocks-filters/responsive-settings/migration.ts +86 -0
  22. package/core-js/blocks-filters/responsive-settings/panels/BlockLinkPanel.tsx +38 -0
  23. package/core-js/blocks-filters/responsive-settings/panels/BorderPanel.tsx +61 -0
  24. package/core-js/blocks-filters/responsive-settings/panels/DisplayLayoutPanel.tsx +92 -0
  25. package/core-js/blocks-filters/responsive-settings/panels/SpacingPanel.tsx +63 -0
  26. package/core-js/blocks-filters/responsive-settings/panels/index.ts +4 -0
  27. package/core-js/blocks-filters/responsive-settings/registry.ts +88 -0
  28. package/core-js/blocks-filters/responsive-settings/settings/block-link/index.ts +3 -0
  29. package/core-js/blocks-filters/responsive-settings/settings/block-link/panel.tsx +6 -6
  30. package/core-js/blocks-filters/responsive-settings/settings/block-link/registration.ts +35 -0
  31. package/core-js/blocks-filters/responsive-settings/settings/border/border/properties.ts +1 -2
  32. package/core-js/blocks-filters/responsive-settings/settings/border/border/settings.tsx +21 -3
  33. package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/index.tsx +2 -1
  34. package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/properties.ts +6 -29
  35. package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/settings.tsx +79 -6
  36. package/core-js/blocks-filters/responsive-settings/settings/border/index.ts +5 -1
  37. package/core-js/blocks-filters/responsive-settings/settings/border/panel.tsx +5 -54
  38. package/core-js/blocks-filters/responsive-settings/settings/border/registration.ts +84 -0
  39. package/core-js/blocks-filters/responsive-settings/settings/border/settings.tsx +21 -0
  40. package/core-js/blocks-filters/responsive-settings/settings/flex-item/index.ts +4 -0
  41. package/core-js/blocks-filters/responsive-settings/settings/flex-item/properties.ts +60 -0
  42. package/core-js/blocks-filters/responsive-settings/settings/flex-item/registration.ts +78 -0
  43. package/core-js/blocks-filters/responsive-settings/settings/flex-item/settings.tsx +90 -0
  44. package/core-js/blocks-filters/responsive-settings/settings/flexbox/index.ts +4 -0
  45. package/core-js/blocks-filters/responsive-settings/settings/flexbox/properties.ts +80 -0
  46. package/core-js/blocks-filters/responsive-settings/settings/flexbox/registration.ts +66 -0
  47. package/core-js/blocks-filters/responsive-settings/settings/flexbox/settings.tsx +78 -0
  48. package/core-js/blocks-filters/responsive-settings/settings/grid/index.ts +4 -0
  49. package/core-js/blocks-filters/responsive-settings/settings/grid/properties.ts +72 -0
  50. package/core-js/blocks-filters/responsive-settings/settings/grid/registration.ts +66 -0
  51. package/core-js/blocks-filters/responsive-settings/settings/grid/settings.tsx +78 -0
  52. package/core-js/blocks-filters/responsive-settings/settings/grid-item/index.ts +4 -0
  53. package/core-js/blocks-filters/responsive-settings/settings/grid-item/properties.ts +44 -0
  54. package/core-js/blocks-filters/responsive-settings/settings/grid-item/registration.ts +74 -0
  55. package/core-js/blocks-filters/responsive-settings/settings/grid-item/settings.tsx +87 -0
  56. package/core-js/blocks-filters/responsive-settings/settings/layout/index.ts +4 -0
  57. package/core-js/blocks-filters/responsive-settings/settings/layout/properties.ts +51 -0
  58. package/core-js/blocks-filters/responsive-settings/settings/layout/registration.ts +96 -0
  59. package/core-js/blocks-filters/responsive-settings/settings/layout/settings.tsx +64 -0
  60. package/core-js/blocks-filters/responsive-settings/settings/presets/index.ts +4 -0
  61. package/core-js/blocks-filters/responsive-settings/settings/presets/presets.ts +52 -0
  62. package/core-js/blocks-filters/responsive-settings/settings/presets/registration.ts +53 -0
  63. package/core-js/blocks-filters/responsive-settings/settings/presets/settings.tsx +100 -0
  64. package/core-js/blocks-filters/responsive-settings/settings/shared/gap-values.ts +16 -0
  65. package/core-js/blocks-filters/responsive-settings/settings/shared/layout-values.ts +56 -0
  66. package/core-js/blocks-filters/responsive-settings/settings/shared/tw-values.ts +107 -0
  67. package/core-js/blocks-filters/responsive-settings/settings/sizing/index.ts +4 -0
  68. package/core-js/blocks-filters/responsive-settings/settings/sizing/properties.ts +71 -0
  69. package/core-js/blocks-filters/responsive-settings/settings/sizing/registration.ts +52 -0
  70. package/core-js/blocks-filters/responsive-settings/settings/sizing/settings.tsx +96 -0
  71. package/core-js/blocks-filters/responsive-settings/settings/spacing/index.ts +7 -2
  72. package/core-js/blocks-filters/responsive-settings/settings/spacing/panel.tsx +5 -45
  73. package/core-js/blocks-filters/responsive-settings/settings/spacing/properties.ts +51 -29
  74. package/core-js/blocks-filters/responsive-settings/settings/spacing/registration.ts +53 -0
  75. package/core-js/blocks-filters/responsive-settings/settings/spacing/settings.tsx +26 -55
  76. package/core-js/blocks-filters/responsive-settings/types/index.ts +174 -28
  77. package/core-js/blocks-filters/responsive-settings/utils.ts +247 -216
  78. package/core-js/config/index.ts +6 -0
  79. package/core-js/config/webentor-config.ts +44 -2
  80. package/core-js/index.ts +8 -10
  81. package/core-js/types/index.ts +6 -0
  82. package/package.json +116 -6
  83. package/public/build/assets/_utils-CzK6Vfiv.js +2 -0
  84. package/public/build/assets/{_utils-PDaZ1Dn1.js.map → _utils-CzK6Vfiv.js.map} +1 -1
  85. package/public/build/assets/coreAppStyles-CukxHLz7.css +1 -0
  86. package/public/build/assets/coreEditorJs-DYd3ZopL.js +366 -0
  87. package/public/build/assets/coreEditorJs-DYd3ZopL.js.map +1 -0
  88. package/public/build/assets/coreEditorStyles-I9xzOGSX.css +1 -0
  89. package/public/build/assets/resources/blocks/e-table/{script-BIchbcPK.js → script-C_Z50hjm.js} +2 -2
  90. package/public/build/assets/resources/blocks/e-table/{script-BIchbcPK.js.map → script-C_Z50hjm.js.map} +1 -1
  91. package/public/build/assets/{sliderJs-Ch69_tVA.js → sliderJs-CyGnrv0Q.js} +3 -3
  92. package/public/build/assets/{sliderJs-Ch69_tVA.js.map → sliderJs-CyGnrv0Q.js.map} +1 -1
  93. package/public/build/manifest.json +10 -10
  94. package/resources/blocks/e-accordion-group/block.json +6 -4
  95. package/resources/blocks/e-gallery/block.json +2 -2
  96. package/resources/blocks/e-gallery/e-gallery.block.tsx +4 -0
  97. package/resources/blocks/e-image/e-image.block.tsx +4 -0
  98. package/resources/blocks/e-slider/block.json +3 -2
  99. package/resources/blocks/e-tab-container/block.json +2 -1
  100. package/resources/blocks/e-tabs/block.json +2 -1
  101. package/resources/blocks/l-flexible-container/block.json +3 -2
  102. package/resources/blocks/l-mobile-nav/block.json +2 -1
  103. package/resources/blocks/l-nav-menu/block.json +2 -1
  104. package/resources/blocks/l-nav-menu/l-nav-menu.block.tsx +2 -0
  105. package/resources/blocks/l-section/block.json +7 -5
  106. package/resources/blocks/l-section/l-section.block.tsx +40 -31
  107. package/resources/scripts/editor.ts +2 -0
  108. package/resources/styles/common/_editor.css +22 -0
  109. package/resources/styles/common/_utilities.css +210 -0
  110. package/core-js/blocks-filters/responsive-settings/constants.ts +0 -11
  111. package/core-js/blocks-filters/responsive-settings/settings/container/display/index.ts +0 -2
  112. package/core-js/blocks-filters/responsive-settings/settings/container/display/properties.ts +0 -167
  113. package/core-js/blocks-filters/responsive-settings/settings/container/display/settings.tsx +0 -73
  114. package/core-js/blocks-filters/responsive-settings/settings/container/flexbox/index.ts +0 -2
  115. package/core-js/blocks-filters/responsive-settings/settings/container/flexbox/properties.ts +0 -187
  116. package/core-js/blocks-filters/responsive-settings/settings/container/flexbox/settings.tsx +0 -131
  117. package/core-js/blocks-filters/responsive-settings/settings/container/grid/index.ts +0 -2
  118. package/core-js/blocks-filters/responsive-settings/settings/container/grid/properties.ts +0 -187
  119. package/core-js/blocks-filters/responsive-settings/settings/container/grid/settings.tsx +0 -132
  120. package/core-js/blocks-filters/responsive-settings/settings/container/index.ts +0 -4
  121. package/core-js/blocks-filters/responsive-settings/settings/container/panel.tsx +0 -92
  122. package/public/build/assets/_utils-PDaZ1Dn1.js +0 -2
  123. package/public/build/assets/coreAppStyles-Dp0WYk4N.css +0 -1
  124. package/public/build/assets/coreEditorJs-Cyc87wTo.js +0 -366
  125. package/public/build/assets/coreEditorJs-Cyc87wTo.js.map +0 -1
  126. package/public/build/assets/coreEditorStyles-D8-nNpQG.css +0 -1
@@ -1,11 +1,15 @@
1
1
  import { getBlockType } from '@wordpress/blocks';
2
2
  import { Button, SelectControl } from '@wordpress/components';
3
- import { __ } from '@wordpress/i18n';
3
+ import { __, sprintf } from '@wordpress/i18n';
4
4
  import { link, linkOff } from '@wordpress/icons';
5
5
 
6
- import { isEmpty, setImmutably } from '@webentorCore/_utils';
7
-
6
+ import { isEmpty, setImmutably } from '../../../../../_utils';
7
+ import { InheritedIndicator } from '../../../components/InheritedIndicator';
8
8
  import { BlockPanelProps } from '../../../types';
9
+ import {
10
+ getEffectiveObjectValue,
11
+ getObjectInheritedFromBreakpoint,
12
+ } from '../../../utils';
9
13
  import { getBorderRadiusValues } from './properties';
10
14
 
11
15
  interface BorderRadiusSettingsProps extends BlockPanelProps {
@@ -20,26 +24,53 @@ interface BorderRadiusValue {
20
24
  linked?: boolean;
21
25
  }
22
26
 
27
+ type CornerKey = 'topLeft' | 'topRight' | 'bottomRight' | 'bottomLeft';
28
+
23
29
  const WebentorBorderRadiusControl = ({
24
30
  label,
25
31
  value,
26
32
  onChange,
27
33
  twTheme,
34
+ inheritedValue,
35
+ inheritedFrom,
28
36
  }: {
29
37
  label?: string;
30
38
  value?: string;
31
39
  onChange: (value: string) => void;
32
40
  twTheme: any;
41
+ inheritedValue?: string;
42
+ inheritedFrom?: string | null;
33
43
  }) => {
34
- const values = getBorderRadiusValues(twTheme);
44
+ const allValues = getBorderRadiusValues(twTheme);
45
+ const isInherited = !value && !!inheritedValue && !!inheritedFrom;
46
+ const selectClassName = `wbtr:w-24${isInherited ? ' wbtr-inherited-value' : ''}`;
47
+
48
+ let options = allValues;
49
+ if (isInherited) {
50
+ const inheritedLabel =
51
+ allValues.find((o) => o.value === inheritedValue)?.label ??
52
+ inheritedValue;
53
+ options = [
54
+ {
55
+ label: sprintf(
56
+ __('%s (from %s)', 'webentor'),
57
+ inheritedLabel,
58
+ inheritedFrom,
59
+ ),
60
+ value: '',
61
+ },
62
+ ...allValues.filter((o) => o.value !== ''),
63
+ ];
64
+ }
35
65
 
36
66
  return (
37
67
  <SelectControl
38
68
  label={label}
39
69
  value={value ?? ''}
40
- options={values}
70
+ options={options}
71
+ __nextHasNoMarginBottom
41
72
  onChange={onChange}
42
- className="wbtr:w-24"
73
+ className={selectClassName}
43
74
  />
44
75
  );
45
76
  };
@@ -49,6 +80,7 @@ export const BorderRadiusSettings = ({
49
80
  setAttributes,
50
81
  name,
51
82
  breakpoint,
83
+ breakpoints,
52
84
  twTheme,
53
85
  }: BorderRadiusSettingsProps) => {
54
86
  if (!attributes?.border) {
@@ -129,11 +161,42 @@ export const BorderRadiusSettings = ({
129
161
  justifyItems: 'center',
130
162
  };
131
163
 
164
+ const radiusInheritedFrom = breakpoints?.length
165
+ ? getObjectInheritedFromBreakpoint(
166
+ attributes,
167
+ 'border',
168
+ 'borderRadius',
169
+ breakpoint,
170
+ breakpoints,
171
+ )
172
+ : null;
173
+
174
+ // Resolve inherited per-corner values for placeholder display
175
+ const effectiveRadius = breakpoints?.length
176
+ ? getEffectiveObjectValue<BorderRadiusValue>(
177
+ attributes,
178
+ 'border',
179
+ 'borderRadius',
180
+ breakpoint,
181
+ breakpoints,
182
+ )
183
+ : undefined;
184
+
185
+ const getCornerInherited = (corner: CornerKey) => {
186
+ const explicitVal = currentBorderRadius?.[corner];
187
+ if (explicitVal) return { value: undefined, from: null };
188
+ const inherited = effectiveRadius?.[corner];
189
+ return { value: inherited || undefined, from: radiusInheritedFrom };
190
+ };
191
+
132
192
  return (
133
193
  <div className="wbtr:my-2 wbtr:flex wbtr:flex-col wbtr:gap-2 wbtr:border wbtr:border-editor-border wbtr:p-2">
134
194
  <p className="wbtr:text-12 wbtr:uppercase">
135
195
  {__('Border Radius', 'webentor')}
136
196
  </p>
197
+ {radiusInheritedFrom && (
198
+ <InheritedIndicator fromBreakpoint={radiusInheritedFrom} />
199
+ )}
137
200
 
138
201
  <div style={containerStyle}>
139
202
  {isLinked ? (
@@ -144,6 +207,8 @@ export const BorderRadiusSettings = ({
144
207
  value={currentBorderRadius?.topLeft}
145
208
  onChange={(value) => onChange(value, 'topLeft')}
146
209
  twTheme={twTheme}
210
+ inheritedValue={getCornerInherited('topLeft').value}
211
+ inheritedFrom={getCornerInherited('topLeft').from}
147
212
  />
148
213
  </div>
149
214
  </>
@@ -155,6 +220,8 @@ export const BorderRadiusSettings = ({
155
220
  value={currentBorderRadius?.topLeft}
156
221
  onChange={(value) => onChange(value, 'topLeft')}
157
222
  twTheme={twTheme}
223
+ inheritedValue={getCornerInherited('topLeft').value}
224
+ inheritedFrom={getCornerInherited('topLeft').from}
158
225
  />
159
226
  </div>
160
227
  <div style={{ gridColumn: '2', gridRow: '1' }}>
@@ -163,6 +230,8 @@ export const BorderRadiusSettings = ({
163
230
  value={currentBorderRadius?.topRight}
164
231
  onChange={(value) => onChange(value, 'topRight')}
165
232
  twTheme={twTheme}
233
+ inheritedValue={getCornerInherited('topRight').value}
234
+ inheritedFrom={getCornerInherited('topRight').from}
166
235
  />
167
236
  </div>
168
237
  <div style={{ gridColumn: '2', gridRow: '2' }}>
@@ -171,6 +240,8 @@ export const BorderRadiusSettings = ({
171
240
  value={currentBorderRadius?.bottomRight}
172
241
  onChange={(value) => onChange(value, 'bottomRight')}
173
242
  twTheme={twTheme}
243
+ inheritedValue={getCornerInherited('bottomRight').value}
244
+ inheritedFrom={getCornerInherited('bottomRight').from}
174
245
  />
175
246
  </div>
176
247
  <div style={{ gridColumn: '1', gridRow: '2' }}>
@@ -179,6 +250,8 @@ export const BorderRadiusSettings = ({
179
250
  value={currentBorderRadius?.bottomLeft}
180
251
  onChange={(value) => onChange(value, 'bottomLeft')}
181
252
  twTheme={twTheme}
253
+ inheritedValue={getCornerInherited('bottomLeft').value}
254
+ inheritedFrom={getCornerInherited('bottomLeft').from}
182
255
  />
183
256
  </div>
184
257
  </>
@@ -1 +1,5 @@
1
- export { BorderPanel } from './panel';
1
+ import './registration';
2
+
3
+ export { BorderAndRadiusSettings } from './settings';
4
+ export { BorderSettings } from './border/settings';
5
+ export { BorderRadiusSettings } from './border-radius/settings';
@@ -1,54 +1,5 @@
1
- import { PanelBody, TabPanel } from '@wordpress/components';
2
- import { __ } from '@wordpress/i18n';
3
-
4
- import { isEmpty } from '@webentorCore/_utils';
5
- import { BlockPanelProps } from '@webentorCore/block-filters/responsive-settings/types';
6
-
7
- import { BorderRadiusSettings } from './border-radius/settings';
8
- import { BorderSettings } from './border/settings';
9
-
10
- export const BorderPanel = (props: BlockPanelProps) => {
11
- const { attributes, breakpoints, twTheme } = props;
12
-
13
- if (!attributes?.border) {
14
- return null;
15
- }
16
-
17
- const checkIfHasAnyBorderSettings = (breakpoint: string): boolean => {
18
- const properties = ['border', 'borderRadius'];
19
-
20
- return properties.some((property) => {
21
- return !isEmpty(attributes?.border?.[property]?.value?.[breakpoint]);
22
- });
23
- };
24
-
25
- return (
26
- <PanelBody title={__('Border Settings', 'webentor')} initialOpen={false}>
27
- <TabPanel
28
- activeClass="is-active"
29
- className="w-responsive-settings-tabs"
30
- initialTabName={breakpoints[0]}
31
- tabs={breakpoints.map((breakpoint) => ({
32
- name: breakpoint,
33
- title: `${breakpoint}${checkIfHasAnyBorderSettings(breakpoint) ? '*' : ''}`,
34
- }))}
35
- >
36
- {(tab) => (
37
- <>
38
- <BorderSettings
39
- {...props}
40
- breakpoint={tab.name}
41
- twTheme={twTheme}
42
- />
43
-
44
- <BorderRadiusSettings
45
- {...props}
46
- breakpoint={tab.name}
47
- twTheme={twTheme}
48
- />
49
- </>
50
- )}
51
- </TabPanel>
52
- </PanelBody>
53
- );
54
- };
1
+ /**
2
+ * @deprecated BorderPanel is now provided by panels/BorderPanel.tsx.
3
+ * This file is kept for backward compat with any external imports.
4
+ */
5
+ export { BorderPanel } from '../../panels/BorderPanel';
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Border module registration.
3
+ *
4
+ * panelGroup: border, order: 10
5
+ * Handles both border and borderRadius settings within a single module.
6
+ * Support key: ['border', 'borderRadius']
7
+ */
8
+ import { isEmpty } from '../../../../_utils';
9
+ import { registry } from '../../registry';
10
+ import { ClassGenContext } from '../../types';
11
+ import { prepareTailwindBorderClassesForSide } from '../../utils';
12
+ import { BorderAndRadiusSettings } from './settings';
13
+
14
+ const RADIUS_MAPPING: Record<string, string> = {
15
+ topLeft: 'rounded-tl',
16
+ topRight: 'rounded-tr',
17
+ bottomRight: 'rounded-br',
18
+ bottomLeft: 'rounded-bl',
19
+ };
20
+
21
+ const generateBorderClasses = (
22
+ attributes: Record<string, any>,
23
+ breakpoint: string,
24
+ _context: ClassGenContext,
25
+ ): string[] => {
26
+ const classes: string[] = [];
27
+
28
+ if (!attributes.border) return classes;
29
+
30
+ for (const [propName, prop] of Object.entries(attributes.border)) {
31
+ const propData = prop as any;
32
+ if (!propData?.value) continue;
33
+ const bpValue = propData.value[breakpoint];
34
+ if (!bpValue) continue;
35
+
36
+ const twBreakpoint = breakpoint === 'basic' ? '' : `${breakpoint}:`;
37
+
38
+ for (const [valueSide, value] of Object.entries(bpValue)) {
39
+ if (valueSide === 'linked') continue;
40
+ if (!value) continue;
41
+
42
+ if (propName === 'border') {
43
+ classes.push(
44
+ ...prepareTailwindBorderClassesForSide(
45
+ value,
46
+ valueSide,
47
+ twBreakpoint,
48
+ ),
49
+ );
50
+ } else if (propName === 'borderRadius') {
51
+ const prefix = RADIUS_MAPPING[valueSide];
52
+ if (prefix) {
53
+ classes.push(`${twBreakpoint}${prefix}-${value}`);
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ return classes;
60
+ };
61
+
62
+ const hasBorderActiveSettings = (
63
+ attributes: Record<string, any>,
64
+ breakpoint: string,
65
+ ): boolean => {
66
+ const properties = ['border', 'borderRadius'];
67
+ return properties.some((property) => {
68
+ return !isEmpty(attributes?.border?.[property]?.value?.[breakpoint]);
69
+ });
70
+ };
71
+
72
+ registry.register({
73
+ name: 'border',
74
+ panelGroup: 'border',
75
+ order: 10,
76
+ attributeKey: 'border',
77
+ supportKey: ['border', 'borderRadius'],
78
+ attributeSchema: {
79
+ border: { type: 'object', default: {} },
80
+ },
81
+ SettingsComponent: BorderAndRadiusSettings,
82
+ generateClasses: generateBorderClasses,
83
+ hasActiveSettings: hasBorderActiveSettings,
84
+ });
@@ -0,0 +1,21 @@
1
+ /**
2
+ * BorderAndRadiusSettings — Combined inline settings component
3
+ * for both border and border-radius controls.
4
+ *
5
+ * This is the SettingsComponent for the border module, rendered
6
+ * inside the BorderPanel by the registry pattern.
7
+ */
8
+ import { SettingsComponentProps } from '../../types';
9
+ import { BorderRadiusSettings } from './border-radius/settings';
10
+ import { BorderSettings } from './border/settings';
11
+
12
+ export const BorderAndRadiusSettings = (props: SettingsComponentProps) => {
13
+ if (!props.attributes?.border) return null;
14
+
15
+ return (
16
+ <>
17
+ <BorderSettings {...props} />
18
+ <BorderRadiusSettings {...props} />
19
+ </>
20
+ );
21
+ };
@@ -0,0 +1,4 @@
1
+ import './registration';
2
+
3
+ export { FlexItemSettings } from './settings';
4
+ export { getFlexItemProperties } from './properties';
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Flex-item properties — grow, shrink, basis, order.
3
+ *
4
+ * Extracted from container/flexbox/properties.ts to be its own module.
5
+ * Re-exports getFlexboxItemProperties for backward compat.
6
+ */
7
+ import { __ } from '@wordpress/i18n';
8
+
9
+ import { WebentorConfig } from '../../../../types/_webentor-config';
10
+ import { PropertyDefinition } from '../../types';
11
+ import { getOrderValues } from '../shared/layout-values';
12
+ import { createTwThemeValues } from '../shared/tw-values';
13
+
14
+ const getFlexGrowValues = () => [
15
+ { label: __('None selected', 'webentor'), value: '' },
16
+ { label: __('Grow 0', 'webentor'), value: 'grow-0' },
17
+ { label: __('Grow 1', 'webentor'), value: 'grow' },
18
+ ];
19
+
20
+ const getFlexShrinkValues = () => [
21
+ { label: __('None selected', 'webentor'), value: '' },
22
+ { label: __('Shrink 0', 'webentor'), value: 'shrink-0' },
23
+ { label: __('Shrink 1', 'webentor'), value: 'shrink' },
24
+ ];
25
+
26
+ export const getFlexItemProperties = (
27
+ twTheme: WebentorConfig['theme'],
28
+ ): PropertyDefinition[] => [
29
+ {
30
+ label: __('Flex Grow', 'webentor'),
31
+ name: 'flex-grow',
32
+ help: __('Applicable only on Flexbox child item', 'webentor'),
33
+ values: getFlexGrowValues(),
34
+ },
35
+ {
36
+ label: __('Flex Shrink', 'webentor'),
37
+ name: 'flex-shrink',
38
+ help: __('Applicable only on Flexbox child item', 'webentor'),
39
+ values: getFlexShrinkValues(),
40
+ },
41
+ {
42
+ label: __('Flex Basis', 'webentor'),
43
+ name: 'flex-basis',
44
+ help: __('Applicable only on Flexbox child item', 'webentor'),
45
+ values: createTwThemeValues(twTheme, 'flexBasis', 'basis'),
46
+ },
47
+ {
48
+ label: __('Order', 'webentor'),
49
+ name: 'order',
50
+ help: __('Applicable only on Flexbox child item', 'webentor'),
51
+ values: getOrderValues(),
52
+ },
53
+ ];
54
+
55
+ export const FLEX_ITEM_PROPERTY_NAMES = [
56
+ 'flex-grow',
57
+ 'flex-shrink',
58
+ 'flex-basis',
59
+ 'order',
60
+ ];
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Flex-item module registration.
3
+ *
4
+ * panelGroup: displayLayout, order: 50
5
+ * Contextual: only shows when parent block display=flex.
6
+ * Support key: 'flexItem'
7
+ */
8
+ import { getEffectiveParentDisplayValue } from '../../migration';
9
+ import { registry } from '../../registry';
10
+ import { ClassGenContext } from '../../types';
11
+ import { FLEX_ITEM_PROPERTY_NAMES } from './properties';
12
+ import { FlexItemSettings } from './settings';
13
+
14
+ export const generateFlexItemClasses = (
15
+ attributes: Record<string, any>,
16
+ breakpoint: string,
17
+ context: ClassGenContext,
18
+ ): string[] => {
19
+ const classes: string[] = [];
20
+
21
+ const flexItemAttr = attributes?.flexItem;
22
+ if (!flexItemAttr) return classes;
23
+
24
+ // Cascaded parent display check
25
+ const effectiveParentDisplay = getEffectiveParentDisplayValue(
26
+ context.parentBlockAttributes,
27
+ breakpoint,
28
+ context.breakpoints,
29
+ );
30
+ if (effectiveParentDisplay !== 'flex') return classes;
31
+
32
+ for (const [, prop] of Object.entries(flexItemAttr)) {
33
+ const propData = prop as any;
34
+ if (!propData?.value) continue;
35
+ const bpValue = propData.value[breakpoint];
36
+ if (!bpValue) continue;
37
+ if (attributes?.slider?.enabled?.value?.[breakpoint]) continue;
38
+
39
+ const twBreakpoint = breakpoint === 'basic' ? '' : `${breakpoint}:`;
40
+ classes.push(`${twBreakpoint}${bpValue}`);
41
+ }
42
+
43
+ return classes;
44
+ };
45
+
46
+ const hasFlexItemActiveSettings = (
47
+ attributes: Record<string, any>,
48
+ breakpoint: string,
49
+ context?: ClassGenContext,
50
+ ): boolean => {
51
+ const effectiveParentDisplay = getEffectiveParentDisplayValue(
52
+ context?.parentBlockAttributes,
53
+ breakpoint,
54
+ context?.breakpoints ?? [],
55
+ );
56
+ if (effectiveParentDisplay !== 'flex') return false;
57
+
58
+ const flexItemAttr = attributes?.flexItem;
59
+ if (!flexItemAttr) return false;
60
+
61
+ return FLEX_ITEM_PROPERTY_NAMES.some(
62
+ (prop) => !!flexItemAttr[prop]?.value?.[breakpoint],
63
+ );
64
+ };
65
+
66
+ registry.register({
67
+ name: 'flexItem',
68
+ panelGroup: 'displayLayout',
69
+ order: 50,
70
+ attributeKey: 'flexItem',
71
+ supportKey: 'flexItem',
72
+ attributeSchema: {
73
+ flexItem: { type: 'object', default: {} },
74
+ },
75
+ SettingsComponent: FlexItemSettings,
76
+ generateClasses: generateFlexItemClasses,
77
+ hasActiveSettings: hasFlexItemActiveSettings,
78
+ });
@@ -0,0 +1,90 @@
1
+ /**
2
+ * FlexItemSettings — flex child controls (grow, shrink, basis, order).
3
+ *
4
+ * Contextual: only shows when the parent block's display is 'flex'.
5
+ */
6
+ import { Fragment } from '@wordpress/element';
7
+ import { __ } from '@wordpress/i18n';
8
+
9
+ import { useBlockParent } from '../../../../blocks-utils/_use-block-parent';
10
+ import { DisabledSliderInfo } from '../../components/DisabledSliderInfo';
11
+ import { InheritedIndicator } from '../../components/InheritedIndicator';
12
+ import { ResponsiveSelectGroup } from '../../components/ResponsiveSelectGroup';
13
+ import {
14
+ getDisplayInheritedFromBreakpoint,
15
+ getEffectiveParentDisplayValue,
16
+ } from '../../migration';
17
+ import { SettingsComponentProps } from '../../types';
18
+ import { isSliderEnabledForBreakpoint } from '../../utils';
19
+ import { getFlexItemProperties } from './properties';
20
+
21
+ const SECTION_STYLE = {
22
+ marginTop: '16px',
23
+ border: '1px solid #e0e0e0',
24
+ padding: '8px',
25
+ };
26
+
27
+ export const FlexItemSettings = ({
28
+ attributes,
29
+ setAttributes,
30
+ name,
31
+ breakpoint,
32
+ breakpoints,
33
+ twTheme,
34
+ }: SettingsComponentProps) => {
35
+ const parentBlock = useBlockParent();
36
+ const effectiveParentDisplay = getEffectiveParentDisplayValue(
37
+ parentBlock?.attributes,
38
+ breakpoint,
39
+ breakpoints,
40
+ );
41
+
42
+ if (effectiveParentDisplay !== 'flex') return null;
43
+
44
+ const hasFlexItem = attributes?.flexItem;
45
+ if (!hasFlexItem) return null;
46
+
47
+ const attributeKey = 'flexItem';
48
+ const isSliderEnabled = isSliderEnabledForBreakpoint(
49
+ name,
50
+ attributes,
51
+ breakpoint,
52
+ );
53
+
54
+ const parentInheritedFrom = parentBlock?.attributes
55
+ ? getDisplayInheritedFromBreakpoint(
56
+ parentBlock.attributes,
57
+ breakpoint,
58
+ breakpoints,
59
+ )
60
+ : null;
61
+
62
+ return (
63
+ <Fragment>
64
+ <div style={SECTION_STYLE}>
65
+ <h3 style={{ marginBottom: '8px' }}>
66
+ {__('Flex Item settings', 'webentor')}
67
+ </h3>
68
+ {parentInheritedFrom && (
69
+ <InheritedIndicator fromBreakpoint={parentInheritedFrom} />
70
+ )}
71
+ <div style={{ marginBottom: '8px', fontSize: '12px' }}>
72
+ {__(
73
+ 'Parent block display setting is set to `Flex`, so current block also acts as flex item.',
74
+ 'webentor',
75
+ )}
76
+ </div>
77
+ {isSliderEnabled && <DisabledSliderInfo />}
78
+ <ResponsiveSelectGroup
79
+ attributeKey={attributeKey}
80
+ properties={getFlexItemProperties(twTheme)}
81
+ attributes={attributes}
82
+ setAttributes={setAttributes}
83
+ breakpoint={breakpoint}
84
+ breakpoints={breakpoints}
85
+ disabled={isSliderEnabled}
86
+ />
87
+ </div>
88
+ </Fragment>
89
+ );
90
+ };
@@ -0,0 +1,4 @@
1
+ import './registration';
2
+
3
+ export { FlexboxSettings } from './settings';
4
+ export { getFlexboxProperties } from './properties';
@@ -0,0 +1,80 @@
1
+ import { __ } from '@wordpress/i18n';
2
+
3
+ import { WebentorConfig } from '../../../../types/_webentor-config';
4
+ import { getGapValues } from '../shared/gap-values';
5
+ import {
6
+ getAlignContentValues,
7
+ getAlignItemsValues,
8
+ getJustifyContentValues,
9
+ } from '../shared/layout-values';
10
+
11
+ const getFlexDirectionValues = () => [
12
+ { label: __('None selected', 'webentor'), value: '' },
13
+ { label: __('Row', 'webentor'), value: 'flex-row' },
14
+ { label: __('Row Reverse', 'webentor'), value: 'flex-row-reverse' },
15
+ { label: __('Column', 'webentor'), value: 'flex-col' },
16
+ { label: __('Column Reverse', 'webentor'), value: 'flex-col-reverse' },
17
+ ];
18
+
19
+ const getFlexWrapValues = () => [
20
+ { label: __('None selected', 'webentor'), value: '' },
21
+ { label: __('Wrap', 'webentor'), value: 'flex-wrap' },
22
+ { label: __('Nowrap', 'webentor'), value: 'flex-nowrap' },
23
+ { label: __('Wrap Reverse', 'webentor'), value: 'flex-wrap-reverse' },
24
+ ];
25
+
26
+ export const FLEXBOX_PROPERTY_NAMES = [
27
+ 'gap',
28
+ 'gap-x',
29
+ 'gap-y',
30
+ 'flex-direction',
31
+ 'flex-wrap',
32
+ 'justify-content',
33
+ 'align-items',
34
+ 'align-content',
35
+ ];
36
+
37
+ export const getFlexboxProperties = (twTheme: WebentorConfig['theme']) => [
38
+ {
39
+ label: __('Flex Gap', 'webentor'),
40
+ name: 'gap',
41
+ values: getGapValues('', twTheme),
42
+ },
43
+ {
44
+ label: __('Flex Gap X', 'webentor'),
45
+ name: 'gap-x',
46
+ values: getGapValues('x', twTheme),
47
+ help: __('Overrides Gap value', 'webentor'),
48
+ },
49
+ {
50
+ label: __('Flex Gap Y', 'webentor'),
51
+ name: 'gap-y',
52
+ values: getGapValues('y', twTheme),
53
+ help: __('Overrides Gap value', 'webentor'),
54
+ },
55
+ {
56
+ label: __('Flex Direction', 'webentor'),
57
+ name: 'flex-direction',
58
+ values: getFlexDirectionValues(),
59
+ },
60
+ {
61
+ label: __('Flex Wrap', 'webentor'),
62
+ name: 'flex-wrap',
63
+ values: getFlexWrapValues(),
64
+ },
65
+ {
66
+ label: __('Justify Content', 'webentor'),
67
+ name: 'justify-content',
68
+ values: getJustifyContentValues(),
69
+ },
70
+ {
71
+ label: __('Align Items', 'webentor'),
72
+ name: 'align-items',
73
+ values: getAlignItemsValues(),
74
+ },
75
+ {
76
+ label: __('Align Content', 'webentor'),
77
+ name: 'align-content',
78
+ values: getAlignContentValues(),
79
+ },
80
+ ];