@webikon/webentor-core 0.9.12

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 (132) hide show
  1. package/.husky/pre-commit +40 -0
  2. package/.prettierrc.js +5 -0
  3. package/CHANGELOG.md +88 -0
  4. package/LICENCE.md +7 -0
  5. package/README.md +26 -0
  6. package/core-js/_alpine.ts +20 -0
  7. package/core-js/_slider.ts +232 -0
  8. package/core-js/_utils.ts +126 -0
  9. package/core-js/blocks-components/block-appender.tsx +36 -0
  10. package/core-js/blocks-components/button.tsx +424 -0
  11. package/core-js/blocks-components/custom-image-sizes-panel.tsx +197 -0
  12. package/core-js/blocks-components/index.ts +4 -0
  13. package/core-js/blocks-components/typography-picker-select.tsx +31 -0
  14. package/core-js/blocks-filters/_filter-core-typography.tsx +108 -0
  15. package/core-js/blocks-filters/_slider-settings.tsx +283 -0
  16. package/core-js/blocks-filters/index.ts +3 -0
  17. package/core-js/blocks-filters/responsive-settings/components/DisabledSliderInfo.tsx +10 -0
  18. package/core-js/blocks-filters/responsive-settings/constants.ts +11 -0
  19. package/core-js/blocks-filters/responsive-settings/index.tsx +196 -0
  20. package/core-js/blocks-filters/responsive-settings/settings/block-link/index.ts +1 -0
  21. package/core-js/blocks-filters/responsive-settings/settings/block-link/panel.tsx +47 -0
  22. package/core-js/blocks-filters/responsive-settings/settings/border/border/index.tsx +1 -0
  23. package/core-js/blocks-filters/responsive-settings/settings/border/border/properties.ts +27 -0
  24. package/core-js/blocks-filters/responsive-settings/settings/border/border/settings.tsx +310 -0
  25. package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/index.tsx +1 -0
  26. package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/properties.ts +31 -0
  27. package/core-js/blocks-filters/responsive-settings/settings/border/border-radius/settings.tsx +211 -0
  28. package/core-js/blocks-filters/responsive-settings/settings/border/index.ts +1 -0
  29. package/core-js/blocks-filters/responsive-settings/settings/border/panel.tsx +54 -0
  30. package/core-js/blocks-filters/responsive-settings/settings/container/display/index.ts +2 -0
  31. package/core-js/blocks-filters/responsive-settings/settings/container/display/properties.ts +167 -0
  32. package/core-js/blocks-filters/responsive-settings/settings/container/display/settings.tsx +73 -0
  33. package/core-js/blocks-filters/responsive-settings/settings/container/flexbox/index.ts +2 -0
  34. package/core-js/blocks-filters/responsive-settings/settings/container/flexbox/properties.ts +187 -0
  35. package/core-js/blocks-filters/responsive-settings/settings/container/flexbox/settings.tsx +131 -0
  36. package/core-js/blocks-filters/responsive-settings/settings/container/grid/index.ts +2 -0
  37. package/core-js/blocks-filters/responsive-settings/settings/container/grid/properties.ts +187 -0
  38. package/core-js/blocks-filters/responsive-settings/settings/container/grid/settings.tsx +132 -0
  39. package/core-js/blocks-filters/responsive-settings/settings/container/index.ts +4 -0
  40. package/core-js/blocks-filters/responsive-settings/settings/container/panel.tsx +92 -0
  41. package/core-js/blocks-filters/responsive-settings/settings/spacing/index.ts +3 -0
  42. package/core-js/blocks-filters/responsive-settings/settings/spacing/panel.tsx +45 -0
  43. package/core-js/blocks-filters/responsive-settings/settings/spacing/properties.ts +74 -0
  44. package/core-js/blocks-filters/responsive-settings/settings/spacing/settings.tsx +85 -0
  45. package/core-js/blocks-filters/responsive-settings/types/index.ts +68 -0
  46. package/core-js/blocks-filters/responsive-settings/utils.ts +321 -0
  47. package/core-js/blocks-utils/_use-block-parent.ts +27 -0
  48. package/core-js/blocks-utils/_use-post-types.ts +43 -0
  49. package/core-js/blocks-utils/_use-taxonomies.ts +29 -0
  50. package/core-js/blocks-utils/index.ts +3 -0
  51. package/core-js/config/webentor-config.ts +718 -0
  52. package/core-js/index.ts +14 -0
  53. package/core-js/types/_block-components.ts +7 -0
  54. package/core-js/types/_webentor-config.ts +182 -0
  55. package/package.json +98 -0
  56. package/resources/blocks/e-accordion/block.json +34 -0
  57. package/resources/blocks/e-accordion/e-accordion.block.tsx +125 -0
  58. package/resources/blocks/e-accordion/script.ts +1 -0
  59. package/resources/blocks/e-accordion/style.css +8 -0
  60. package/resources/blocks/e-accordion-group/block.json +56 -0
  61. package/resources/blocks/e-accordion-group/e-accordion-group.block.tsx +99 -0
  62. package/resources/blocks/e-breadcrumbs/block.json +41 -0
  63. package/resources/blocks/e-breadcrumbs/e-breadcrumbs.block.tsx +53 -0
  64. package/resources/blocks/e-button/block.json +32 -0
  65. package/resources/blocks/e-button/e-button.block.tsx +55 -0
  66. package/resources/blocks/e-gallery/block.json +90 -0
  67. package/resources/blocks/e-gallery/e-gallery.block.tsx +316 -0
  68. package/resources/blocks/e-icon-picker/block.json +37 -0
  69. package/resources/blocks/e-icon-picker/e-icon-picker.block.tsx +230 -0
  70. package/resources/blocks/e-icon-picker/style.css +17 -0
  71. package/resources/blocks/e-image/block.json +78 -0
  72. package/resources/blocks/e-image/e-image.block.tsx +331 -0
  73. package/resources/blocks/e-picker-query-loop/block.json +25 -0
  74. package/resources/blocks/e-picker-query-loop/e-picker-query-loop.block.tsx +189 -0
  75. package/resources/blocks/e-post-template/block.json +25 -0
  76. package/resources/blocks/e-post-template/e-post-template.block.tsx +100 -0
  77. package/resources/blocks/e-query-loop/block.json +36 -0
  78. package/resources/blocks/e-query-loop/constants.tsx +8 -0
  79. package/resources/blocks/e-query-loop/e-query-loop.block.tsx +270 -0
  80. package/resources/blocks/e-query-loop/taxonomy-controls.tsx +184 -0
  81. package/resources/blocks/e-slider/block.json +42 -0
  82. package/resources/blocks/e-slider/e-slider.block.tsx +100 -0
  83. package/resources/blocks/e-svg/block.json +37 -0
  84. package/resources/blocks/e-svg/e-svg.block.tsx +156 -0
  85. package/resources/blocks/e-tab-container/block.json +49 -0
  86. package/resources/blocks/e-tab-container/e-tab-container.block.tsx +123 -0
  87. package/resources/blocks/e-table/block.json +30 -0
  88. package/resources/blocks/e-table/e-table.block.tsx +120 -0
  89. package/resources/blocks/e-table/script.ts +48 -0
  90. package/resources/blocks/e-table-cell/block.json +40 -0
  91. package/resources/blocks/e-table-cell/e-table-cell.block.tsx +180 -0
  92. package/resources/blocks/e-table-row/block.json +28 -0
  93. package/resources/blocks/e-table-row/e-table-row.block.tsx +118 -0
  94. package/resources/blocks/e-tabs/block.json +27 -0
  95. package/resources/blocks/e-tabs/e-tabs.block.tsx +90 -0
  96. package/resources/blocks/l-404/block.json +51 -0
  97. package/resources/blocks/l-404/l-404.block.tsx +75 -0
  98. package/resources/blocks/l-flexible-container/block.json +34 -0
  99. package/resources/blocks/l-flexible-container/l-flexible-container.block.tsx +97 -0
  100. package/resources/blocks/l-footer/block.json +23 -0
  101. package/resources/blocks/l-footer/l-footer.block.tsx +51 -0
  102. package/resources/blocks/l-formatted-content/block.json +28 -0
  103. package/resources/blocks/l-formatted-content/l-formatted-content.block.tsx +97 -0
  104. package/resources/blocks/l-header/block.json +26 -0
  105. package/resources/blocks/l-header/l-header.block.tsx +100 -0
  106. package/resources/blocks/l-mobile-nav/block.json +15 -0
  107. package/resources/blocks/l-mobile-nav/l-mobile-nav.block.tsx +56 -0
  108. package/resources/blocks/l-mobile-nav/style.css +54 -0
  109. package/resources/blocks/l-nav-menu/block.json +27 -0
  110. package/resources/blocks/l-nav-menu/l-nav-menu.block.tsx +109 -0
  111. package/resources/blocks/l-nav-menu/style.css +134 -0
  112. package/resources/blocks/l-post-card/block.json +13 -0
  113. package/resources/blocks/l-post-card/l-post-card.block.tsx +52 -0
  114. package/resources/blocks/l-section/block.json +89 -0
  115. package/resources/blocks/l-section/l-section.block.tsx +316 -0
  116. package/resources/blocks/l-site-logo/block.json +15 -0
  117. package/resources/blocks/l-site-logo/l-site-logo.block.tsx +54 -0
  118. package/resources/core-components/slider/slider.script.ts +11 -0
  119. package/resources/core-components/slider/slider.style.css +134 -0
  120. package/resources/scripts/editor.ts +29 -0
  121. package/resources/styles/app.css +21 -0
  122. package/resources/styles/common/_editor.css +86 -0
  123. package/resources/styles/common/_form.css +83 -0
  124. package/resources/styles/common/_global.css +73 -0
  125. package/resources/styles/common/_theme.css +75 -0
  126. package/resources/styles/common/_utilities.css +33 -0
  127. package/resources/styles/common/_wordpress.css +110 -0
  128. package/resources/styles/components/_table.css +102 -0
  129. package/resources/styles/editor.css +16 -0
  130. package/resources/styles/partials/.gitkeep +0 -0
  131. package/resources/styles/partials/_header.css +21 -0
  132. package/resources/styles/partials/_pagination.css +35 -0
@@ -0,0 +1,187 @@
1
+ import { __ } from '@wordpress/i18n';
2
+
3
+ import { WebentorConfig } from '@webentorCore/types/_webentor-config';
4
+
5
+ const getGridTemplateColumnsValues = (twTheme: WebentorConfig['theme']) => {
6
+ const values = Object.keys(twTheme?.gridTemplateColumns).map((key) => ({
7
+ label: __('Columns: %s', 'webentor').replace('%s', key),
8
+ value: `grid-cols-${key}`,
9
+ }));
10
+
11
+ // Add none selected option as first item
12
+ values.unshift({
13
+ label: __('None selected', 'webentor'),
14
+ value: '',
15
+ });
16
+
17
+ return values;
18
+ };
19
+
20
+ const getGridTemplateRowsValues = (twTheme: WebentorConfig['theme']) => {
21
+ const values = Object.keys(twTheme?.gridTemplateRows).map((key) => ({
22
+ label: __('Rows: %s', 'webentor').replace('%s', key),
23
+ value: `grid-rows-${key}`,
24
+ }));
25
+
26
+ // Add none selected option as first item
27
+ values.unshift({
28
+ label: __('None selected', 'webentor'),
29
+ value: '',
30
+ });
31
+
32
+ return values;
33
+ };
34
+
35
+ const getGapValues = (axis = '', twTheme: WebentorConfig['theme']) => {
36
+ const values = Object.keys(twTheme?.gap)
37
+ .sort((a, b) => Number(a) - Number(b))
38
+ .map((key) => ({
39
+ label: `${Number(key) * 4}px`,
40
+ value: `gap-${axis === 'x' ? 'x-' : axis === 'y' ? 'y-' : ''}${key}`,
41
+ }));
42
+
43
+ values.unshift({
44
+ label: __('None selected', 'webentor'),
45
+ value: '',
46
+ });
47
+
48
+ return values;
49
+ };
50
+
51
+ const getJustifyContentValues = () => [
52
+ { label: __('None selected', 'webentor'), value: '' },
53
+ { label: __('Normal', 'webentor'), value: 'justify-normal' },
54
+ { label: __('Flex Start', 'webentor'), value: 'justify-start' },
55
+ { label: __('Flex End', 'webentor'), value: 'justify-end' },
56
+ { label: __('Center', 'webentor'), value: 'justify-center' },
57
+ { label: __('Space Between', 'webentor'), value: 'justify-between' },
58
+ { label: __('Space Around', 'webentor'), value: 'justify-around' },
59
+ { label: __('Space Evenly', 'webentor'), value: 'justify-evenly' },
60
+ { label: __('Stretch', 'webentor'), value: 'justify-stretch' },
61
+ ];
62
+
63
+ const getAlignItemsValues = () => [
64
+ { label: __('None selected', 'webentor'), value: '' },
65
+ { label: __('Flex Start', 'webentor'), value: 'items-start' },
66
+ { label: __('Flex End', 'webentor'), value: 'items-end' },
67
+ { label: __('Center', 'webentor'), value: 'items-center' },
68
+ { label: __('Baseline', 'webentor'), value: 'items-baseline' },
69
+ { label: __('Stretch', 'webentor'), value: 'items-stretch' },
70
+ ];
71
+
72
+ const getAlignContentValues = () => [
73
+ { label: __('None selected', 'webentor'), value: '' },
74
+ { label: __('Normal', 'webentor'), value: 'content-normal' },
75
+ { label: __('Flex Start', 'webentor'), value: 'content-start' },
76
+ { label: __('Flex End', 'webentor'), value: 'content-end' },
77
+ { label: __('Center', 'webentor'), value: 'content-center' },
78
+ { label: __('Space Between', 'webentor'), value: 'content-between' },
79
+ { label: __('Space Around', 'webentor'), value: 'content-around' },
80
+ { label: __('Space Evenly', 'webentor'), value: 'content-evenly' },
81
+ { label: __('Baseline', 'webentor'), value: 'content-baseline' },
82
+ { label: __('Stretch', 'webentor'), value: 'content-stretch' },
83
+ ];
84
+
85
+ const getOrderValues = () => [
86
+ { label: __('None selected', 'webentor'), value: '' },
87
+ { label: __('Order First', 'webentor'), value: 'order-first' },
88
+ { label: __('Order Last', 'webentor'), value: 'order-last' },
89
+ { label: __('Order None', 'webentor'), value: 'order-none' },
90
+ { label: __('Order 0', 'webentor'), value: 'order-0' },
91
+ { label: __('Order 1', 'webentor'), value: 'order-1' },
92
+ { label: __('Order 2', 'webentor'), value: 'order-2' },
93
+ { label: __('Order 3', 'webentor'), value: 'order-3' },
94
+ { label: __('Order 4', 'webentor'), value: 'order-4' },
95
+ { label: __('Order 5', 'webentor'), value: 'order-5' },
96
+ ];
97
+
98
+ const getGridColumnSpanValues = (twTheme: WebentorConfig['theme']) => {
99
+ const values = Object.keys(twTheme?.gridColumn).map((key) => ({
100
+ label: key,
101
+ value: `col-${key}`,
102
+ }));
103
+
104
+ values.unshift({
105
+ label: __('None selected', 'webentor'),
106
+ value: '',
107
+ });
108
+
109
+ return values;
110
+ };
111
+
112
+ const getGridRowSpanValues = (twTheme: WebentorConfig['theme']) => {
113
+ const values = Object.keys(twTheme?.gridRow).map((key) => ({
114
+ label: key,
115
+ value: `row-${key}`,
116
+ }));
117
+
118
+ values.unshift({
119
+ label: __('None selected', 'webentor'),
120
+ value: '',
121
+ });
122
+
123
+ return values;
124
+ };
125
+
126
+ export const getGridProperties = (twTheme: WebentorConfig['theme']) => [
127
+ {
128
+ label: __('Grid Template Columns', 'webentor'),
129
+ name: 'grid-cols',
130
+ values: getGridTemplateColumnsValues(twTheme),
131
+ },
132
+ {
133
+ label: __('Grid Template Rows', 'webentor'),
134
+ name: 'grid-rows',
135
+ values: getGridTemplateRowsValues(twTheme),
136
+ },
137
+ {
138
+ label: __('Gap', 'webentor'),
139
+ name: 'gap',
140
+ values: getGapValues('', twTheme),
141
+ },
142
+ {
143
+ label: __('Gap X', 'webentor'),
144
+ name: 'gap-x',
145
+ values: getGapValues('x', twTheme),
146
+ help: __('Overrides Gap value', 'webentor'),
147
+ },
148
+ {
149
+ label: __('Gap Y', 'webentor'),
150
+ name: 'gap-y',
151
+ values: getGapValues('y', twTheme),
152
+ help: __('Overrides Gap value', 'webentor'),
153
+ },
154
+ {
155
+ label: __('Justify Content', 'webentor'),
156
+ name: 'justify-content',
157
+ values: getJustifyContentValues(),
158
+ },
159
+ {
160
+ label: __('Align Items', 'webentor'),
161
+ name: 'align-items',
162
+ values: getAlignItemsValues(),
163
+ },
164
+ {
165
+ label: __('Align Content', 'webentor'),
166
+ name: 'align-content',
167
+ values: getAlignContentValues(),
168
+ },
169
+ ];
170
+
171
+ export const getGridItemProperties = (twTheme: WebentorConfig['theme']) => [
172
+ {
173
+ label: __('Grid Column Span', 'webentor'),
174
+ name: 'grid-col-span',
175
+ values: getGridColumnSpanValues(twTheme),
176
+ },
177
+ {
178
+ label: __('Grid Row Span', 'webentor'),
179
+ name: 'grid-row-span',
180
+ values: getGridRowSpanValues(twTheme),
181
+ },
182
+ {
183
+ label: __('Order', 'webentor'),
184
+ name: 'order',
185
+ values: getOrderValues(),
186
+ },
187
+ ];
@@ -0,0 +1,132 @@
1
+ import { SelectControl } from '@wordpress/components';
2
+ import { Fragment } from '@wordpress/element';
3
+ import { __ } from '@wordpress/i18n';
4
+
5
+ import { setImmutably } from '@webentorCore/_utils';
6
+ import { BlockPanelProps } from '@webentorCore/block-filters/responsive-settings/types';
7
+ import { useBlockParent } from '@webentorCore/blocks-utils/_use-block-parent';
8
+
9
+ import { DisabledSliderInfo } from '../../../components/DisabledSliderInfo';
10
+ import { isSliderEnabledForBreakpoint } from '../../../utils';
11
+ import { getGridItemProperties, getGridProperties } from './properties';
12
+
13
+ interface GridSettingsProps extends BlockPanelProps {
14
+ breakpoint: string;
15
+ twTheme: any;
16
+ }
17
+
18
+ export const GridSettings = ({
19
+ attributes,
20
+ setAttributes,
21
+ name,
22
+ breakpoint,
23
+ twTheme,
24
+ }: GridSettingsProps) => {
25
+ const isSliderEnabled = isSliderEnabledForBreakpoint(
26
+ name,
27
+ attributes,
28
+ breakpoint,
29
+ );
30
+
31
+ // Get parent block data
32
+ const parentBlock = useBlockParent();
33
+
34
+ // TODO: how to check all previous breakpoints and determine if any of them is grid so we can display the settings?
35
+ const isParentGrid =
36
+ parentBlock?.attributes?.display?.display?.value?.[breakpoint] === 'grid';
37
+ const isCurrentGrid =
38
+ attributes?.display?.display?.value?.[breakpoint] === 'grid';
39
+
40
+ if (!isCurrentGrid && !isParentGrid) {
41
+ return null;
42
+ }
43
+
44
+ const gridProperties = getGridProperties(twTheme);
45
+ const gridItemProperties = getGridItemProperties(twTheme);
46
+
47
+ return (
48
+ <>
49
+ {isCurrentGrid && attributes?.grid && (
50
+ <div
51
+ style={{
52
+ marginTop: '16px',
53
+ border: '1px solid #e0e0e0',
54
+ padding: '8px',
55
+ }}
56
+ >
57
+ <h3 style={{ marginBottom: '8px' }}>
58
+ {__('Grid settings', 'webentor')}
59
+ </h3>
60
+
61
+ {isSliderEnabled && <DisabledSliderInfo />}
62
+
63
+ {gridProperties.map((property) => (
64
+ <Fragment key={property.name + breakpoint}>
65
+ <SelectControl
66
+ label={property.label}
67
+ value={attributes.grid?.[property.name]?.value?.[breakpoint]}
68
+ disabled={isSliderEnabled}
69
+ help={property?.help}
70
+ options={property.values}
71
+ onChange={(selected) =>
72
+ setAttributes(
73
+ setImmutably(
74
+ attributes,
75
+ ['grid', property.name, 'value', breakpoint],
76
+ selected,
77
+ ),
78
+ )
79
+ }
80
+ />
81
+ </Fragment>
82
+ ))}
83
+ </div>
84
+ )}
85
+
86
+ {isParentGrid && attributes?.gridItem && (
87
+ <div
88
+ style={{
89
+ marginTop: '16px',
90
+ border: '1px solid #e0e0e0',
91
+ padding: '8px',
92
+ }}
93
+ >
94
+ <h3 style={{ marginBottom: '8px' }}>
95
+ {__('Grid Item settings', 'webentor')}
96
+ </h3>
97
+ <div style={{ marginBottom: '8px', fontSize: '12px' }}>
98
+ {__(
99
+ 'Parent block display setting is set to `Grid`, so current block also acts as grid item.',
100
+ 'webentor',
101
+ )}
102
+ </div>
103
+
104
+ {isSliderEnabled && <DisabledSliderInfo />}
105
+
106
+ {gridItemProperties.map((property) => (
107
+ <Fragment key={property.name + breakpoint}>
108
+ <SelectControl
109
+ label={property.label}
110
+ value={
111
+ attributes.gridItem?.[property.name]?.value?.[breakpoint]
112
+ }
113
+ disabled={isSliderEnabled}
114
+ help={property?.help}
115
+ options={property.values}
116
+ onChange={(selected) =>
117
+ setAttributes(
118
+ setImmutably(
119
+ attributes,
120
+ ['gridItem', property.name, 'value', breakpoint],
121
+ selected,
122
+ ),
123
+ )
124
+ }
125
+ />
126
+ </Fragment>
127
+ ))}
128
+ </div>
129
+ )}
130
+ </>
131
+ );
132
+ };
@@ -0,0 +1,4 @@
1
+ export { ContainerPanel } from './panel';
2
+ export { DisplaySettings } from './display';
3
+ export { GridSettings } from './grid';
4
+ export { FlexboxSettings } from './flexbox';
@@ -0,0 +1,92 @@
1
+ import { PanelBody, TabPanel } from '@wordpress/components';
2
+ import { applyFilters } from '@wordpress/hooks';
3
+ import { __ } from '@wordpress/i18n';
4
+
5
+ import { BlockPanelProps } from '@webentorCore/block-filters/responsive-settings/types';
6
+ import { useBlockParent } from '@webentorCore/blocks-utils/_use-block-parent';
7
+
8
+ import { DisplaySettings, getDisplayProperties } from './display';
9
+ import { FlexboxSettings, getFlexboxItemProperties } from './flexbox';
10
+ import { getGridItemProperties, GridSettings } from './grid';
11
+
12
+ export const ContainerPanel = (props: BlockPanelProps) => {
13
+ const { attributes, breakpoints, twTheme } = props;
14
+
15
+ if (
16
+ !attributes?.display &&
17
+ !attributes?.grid &&
18
+ !attributes?.gridItem &&
19
+ !attributes?.flexbox &&
20
+ !attributes?.flexboxItem
21
+ ) {
22
+ return null;
23
+ }
24
+
25
+ const checkIfHasAnyActiveSettings = (breakpoint: string): boolean => {
26
+ const parentBlock = useBlockParent();
27
+ const displayProperties = getDisplayProperties(props.name, twTheme);
28
+ const flexboxItemProperties = getFlexboxItemProperties(twTheme);
29
+ const gridItemProperties = getGridItemProperties(twTheme);
30
+
31
+ const hasDisplaySettings = displayProperties.some((property) => {
32
+ return !!attributes?.display?.[property.name]?.value?.[breakpoint];
33
+ });
34
+
35
+ const isParentFlexbox =
36
+ parentBlock?.attributes?.display?.display?.value?.[breakpoint] === 'flex';
37
+ const isParentGrid =
38
+ parentBlock?.attributes?.display?.display?.value?.[breakpoint] === 'grid';
39
+
40
+ const hasFlexboxItemSettings =
41
+ isParentFlexbox &&
42
+ flexboxItemProperties.some((property) => {
43
+ return !!attributes?.flexboxItem?.[property.name]?.value?.[breakpoint];
44
+ });
45
+
46
+ const hasGridItemSettings =
47
+ isParentGrid &&
48
+ gridItemProperties.some((property) => {
49
+ return !!attributes?.gridItem?.[property.name]?.value?.[breakpoint];
50
+ });
51
+
52
+ return hasDisplaySettings || hasFlexboxItemSettings || hasGridItemSettings;
53
+ };
54
+
55
+ const hasContainerSettings = (breakpoint: string): boolean => {
56
+ return checkIfHasAnyActiveSettings(breakpoint);
57
+ };
58
+
59
+ // Allow themes/plugins to add custom content before responsive tabs
60
+ const beforeTabsContent = applyFilters(
61
+ 'webentor.containerPanel.beforeTabs',
62
+ null,
63
+ props,
64
+ );
65
+
66
+ return (
67
+ <PanelBody title={__('Container Settings', 'webentor')} initialOpen={true}>
68
+ {beforeTabsContent}
69
+ <TabPanel
70
+ activeClass="is-active"
71
+ className="w-responsive-settings-tabs"
72
+ initialTabName={breakpoints[0]}
73
+ tabs={breakpoints.map((breakpoint) => ({
74
+ name: breakpoint,
75
+ title: `${breakpoint}${hasContainerSettings(breakpoint) ? '*' : ''}`,
76
+ }))}
77
+ >
78
+ {(tab) => (
79
+ <>
80
+ <DisplaySettings
81
+ {...props}
82
+ breakpoint={tab.name}
83
+ twTheme={twTheme}
84
+ />
85
+ <GridSettings {...props} breakpoint={tab.name} />
86
+ <FlexboxSettings {...props} breakpoint={tab.name} />
87
+ </>
88
+ )}
89
+ </TabPanel>
90
+ </PanelBody>
91
+ );
92
+ };
@@ -0,0 +1,3 @@
1
+ export { SpacingPanel } from './panel';
2
+ export { SpacingSettings } from './settings';
3
+ export { getSpacingProperties } from './properties';
@@ -0,0 +1,45 @@
1
+ import { PanelBody, TabPanel } from '@wordpress/components';
2
+ import { __ } from '@wordpress/i18n';
3
+
4
+ import { BlockPanelProps } from '@webentorCore/block-filters/responsive-settings/types';
5
+
6
+ import { SpacingSettings } from './settings';
7
+
8
+ export const SpacingPanel = (props: BlockPanelProps) => {
9
+ const { attributes, breakpoints, twTheme } = props;
10
+
11
+ if (!attributes?.spacing) {
12
+ return null;
13
+ }
14
+
15
+ const hasSpacingSettingsForBreakpoint = (breakpoint: string): boolean => {
16
+ return !!(
17
+ attributes?.spacing?.['margin-top']?.value?.[breakpoint] ||
18
+ attributes?.spacing?.['margin-bottom']?.value?.[breakpoint] ||
19
+ attributes?.spacing?.['margin-left']?.value?.[breakpoint] ||
20
+ attributes?.spacing?.['margin-right']?.value?.[breakpoint] ||
21
+ attributes?.spacing?.['padding-top']?.value?.[breakpoint] ||
22
+ attributes?.spacing?.['padding-bottom']?.value?.[breakpoint] ||
23
+ attributes?.spacing?.['padding-left']?.value?.[breakpoint] ||
24
+ attributes?.spacing?.['padding-right']?.value?.[breakpoint]
25
+ );
26
+ };
27
+
28
+ return (
29
+ <PanelBody title={__('Spacing Settings', 'webentor')} initialOpen={false}>
30
+ <TabPanel
31
+ activeClass="is-active"
32
+ className="w-responsive-settings-tabs"
33
+ initialTabName={breakpoints[0]}
34
+ tabs={breakpoints.map((breakpoint) => ({
35
+ name: breakpoint,
36
+ title: `${breakpoint}${hasSpacingSettingsForBreakpoint(breakpoint) ? '*' : ''}`, // Add * if spacing is set on this breakpoint
37
+ }))}
38
+ >
39
+ {(tab) => (
40
+ <SpacingSettings {...props} breakpoint={tab.name} twTheme={twTheme} />
41
+ )}
42
+ </TabPanel>
43
+ </PanelBody>
44
+ );
45
+ };
@@ -0,0 +1,74 @@
1
+ import { __ } from '@wordpress/i18n';
2
+
3
+ import { WebentorConfig } from '@webentorCore/types/_webentor-config';
4
+
5
+ const getSpacingValues = (property = '', twTheme: WebentorConfig['theme']) => {
6
+ const values = Object.keys(twTheme?.spacing)
7
+ .sort((a, b) => Number(a) - Number(b))
8
+ .map((key) => ({
9
+ label: `${Number(key) * 4}px`,
10
+ value: `${property}-${key}`,
11
+ }));
12
+
13
+ values.unshift({
14
+ label: __('None selected', 'webentor'),
15
+ value: '',
16
+ });
17
+
18
+ return values;
19
+ };
20
+
21
+ export const getSpacingProperties = (twTheme: WebentorConfig['theme']) => [
22
+ {
23
+ label: __('Margin Top', 'webentor'),
24
+ name: 'margin-top',
25
+ values: [
26
+ ...getSpacingValues('mt', twTheme),
27
+ { label: 'Auto', value: 'mt-auto' },
28
+ ],
29
+ },
30
+ {
31
+ label: __('Margin Left', 'webentor'),
32
+ name: 'margin-left',
33
+ values: [
34
+ ...getSpacingValues('ml', twTheme),
35
+ { label: 'Auto', value: 'ml-auto' },
36
+ ],
37
+ },
38
+ {
39
+ label: __('Margin Right', 'webentor'),
40
+ name: 'margin-right',
41
+ values: [
42
+ ...getSpacingValues('mr', twTheme),
43
+ { label: 'Auto', value: 'mr-auto' },
44
+ ],
45
+ },
46
+ {
47
+ label: __('Margin Bottom', 'webentor'),
48
+ name: 'margin-bottom',
49
+ values: [
50
+ ...getSpacingValues('mb', twTheme),
51
+ { label: 'Auto', value: 'mb-auto' },
52
+ ],
53
+ },
54
+ {
55
+ label: __('Padding Top', 'webentor'),
56
+ name: 'padding-top',
57
+ values: getSpacingValues('pt', twTheme),
58
+ },
59
+ {
60
+ label: __('Padding Left', 'webentor'),
61
+ name: 'padding-left',
62
+ values: getSpacingValues('pl', twTheme),
63
+ },
64
+ {
65
+ label: __('Padding Right', 'webentor'),
66
+ name: 'padding-right',
67
+ values: getSpacingValues('pr', twTheme),
68
+ },
69
+ {
70
+ label: __('Padding Bottom', 'webentor'),
71
+ name: 'padding-bottom',
72
+ values: getSpacingValues('pb', twTheme),
73
+ },
74
+ ];
@@ -0,0 +1,85 @@
1
+ import { SelectControl } from '@wordpress/components';
2
+
3
+ import { setImmutably } from '@webentorCore/_utils';
4
+ import { BlockPanelProps } from '@webentorCore/block-filters/responsive-settings/types';
5
+
6
+ import { DisabledSliderInfo } from '../../components/DisabledSliderInfo';
7
+ import { isSliderEnabledForBreakpoint } from '../../utils';
8
+ import { getSpacingProperties } from './properties';
9
+
10
+ interface SpacingSettingsProps extends BlockPanelProps {
11
+ breakpoint: string;
12
+ }
13
+
14
+ export const SpacingSettings = ({
15
+ attributes,
16
+ setAttributes,
17
+ name,
18
+ breakpoint,
19
+ twTheme,
20
+ }: SpacingSettingsProps) => {
21
+ if (!attributes?.spacing) {
22
+ return null;
23
+ }
24
+
25
+ const isSliderEnabled = isSliderEnabledForBreakpoint(
26
+ name,
27
+ attributes,
28
+ breakpoint,
29
+ );
30
+
31
+ const spacingProperties = getSpacingProperties(twTheme);
32
+
33
+ return (
34
+ <div
35
+ style={{
36
+ marginTop: '16px',
37
+ display: 'flex',
38
+ flexWrap: 'wrap',
39
+ justifyContent: 'center',
40
+ gap: '16px',
41
+ }}
42
+ >
43
+ {isSliderEnabled && <DisabledSliderInfo />}
44
+
45
+ {spacingProperties.map((property) => (
46
+ <div
47
+ key={property.name + breakpoint}
48
+ style={{
49
+ margin:
50
+ property.name.includes('top') || property.name.includes('bottom')
51
+ ? '0 auto'
52
+ : undefined,
53
+ width:
54
+ property.name.includes('top') || property.name.includes('bottom')
55
+ ? '75%'
56
+ : property.name.includes('left') ||
57
+ property.name.includes('right')
58
+ ? '40%'
59
+ : undefined,
60
+ }}
61
+ >
62
+ <SelectControl
63
+ label={property.label}
64
+ value={attributes.spacing?.[property.name]?.value?.[breakpoint]}
65
+ help={property?.help}
66
+ disabled={isSliderEnabled}
67
+ options={property.values}
68
+ onChange={(selected) =>
69
+ setAttributes(
70
+ setImmutably(
71
+ attributes,
72
+ ['spacing', property.name, 'value', breakpoint],
73
+ selected,
74
+ ),
75
+ )
76
+ }
77
+ />
78
+
79
+ {/* Horizontal line between margin & padding settings */}
80
+ {property.name.includes('margin-bottom') && <hr />}
81
+ </div>
82
+ ))}
83
+ </div>
84
+ );
85
+ };
@@ -0,0 +1,68 @@
1
+ import { WebentorConfig } from '@webentorCore/types/_webentor-config';
2
+
3
+ export interface SelectOption {
4
+ label: string;
5
+ value: string;
6
+ }
7
+
8
+ export interface ResponsiveValue {
9
+ value: {
10
+ [key: string]: string;
11
+ };
12
+ }
13
+
14
+ export interface ResponsiveAttribute {
15
+ [key: string]: ResponsiveValue;
16
+ }
17
+
18
+ export interface BorderValue {
19
+ top: {
20
+ width: string;
21
+ color: string;
22
+ style: string;
23
+ };
24
+ right: {
25
+ width: string;
26
+ color: string;
27
+ style: string;
28
+ };
29
+ bottom: {
30
+ width: string;
31
+ color: string;
32
+ style: string;
33
+ };
34
+ left: {
35
+ width: string;
36
+ color: string;
37
+ style: string;
38
+ };
39
+ }
40
+
41
+ export interface ResponsiveBorderValue {
42
+ value: {
43
+ [key: string]: BorderValue;
44
+ };
45
+ }
46
+
47
+ export interface BlockAttributes {
48
+ blockLink?: any;
49
+ spacing?: ResponsiveAttribute;
50
+ display?: ResponsiveAttribute;
51
+ grid?: ResponsiveAttribute;
52
+ gridItem?: ResponsiveAttribute;
53
+ flexbox?: ResponsiveAttribute;
54
+ flexboxItem?: ResponsiveAttribute;
55
+ border?: ResponsiveBorderValue;
56
+ slider?: {
57
+ enabled?: ResponsiveValue;
58
+ };
59
+ }
60
+
61
+ export interface BlockPanelProps {
62
+ attributes: BlockAttributes;
63
+ setAttributes: (attributes: BlockAttributes) => void;
64
+ name: string;
65
+ clientId: string;
66
+ breakpoints: string[];
67
+ twTheme: WebentorConfig['theme'];
68
+ }