@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,310 @@
1
+ import { store as blockEditorStore } from '@wordpress/block-editor';
2
+ import { getBlockType } from '@wordpress/blocks';
3
+ import {
4
+ Button,
5
+ ColorPalette,
6
+ Dropdown,
7
+ SelectControl,
8
+ } from '@wordpress/components';
9
+ import { useSelect } from '@wordpress/data';
10
+ import { __ } from '@wordpress/i18n';
11
+ import { link, linkOff } from '@wordpress/icons';
12
+
13
+ import {
14
+ getColorBySlug,
15
+ getColorSlugByColor,
16
+ isEmpty,
17
+ setImmutably,
18
+ } from '@webentorCore/_utils';
19
+
20
+ import { BlockPanelProps } from '../../../types';
21
+ import { prepareTailwindBorderClassesFromSettings } from '../../../utils';
22
+ import { getBorderProperties } from './properties';
23
+
24
+ interface BorderSettingsProps extends BlockPanelProps {
25
+ breakpoint: string;
26
+ }
27
+
28
+ interface BorderSide {
29
+ width?: string; // E.g. '1', '2', '4',...
30
+ style?: string; // E.g. 'solid', 'dashed',...
31
+ color?: string; // E.g. 'black', 'red',...
32
+ }
33
+
34
+ interface BorderValue {
35
+ top?: BorderSide;
36
+ right?: BorderSide;
37
+ bottom?: BorderSide;
38
+ left?: BorderSide;
39
+ linked?: boolean;
40
+ }
41
+
42
+ const WebentorBorderControl = ({
43
+ label,
44
+ value,
45
+ onChange,
46
+ colors,
47
+ borderClasses,
48
+ twTheme,
49
+ }: {
50
+ label: string;
51
+ value?: BorderSide;
52
+ onChange: (value: BorderSide) => void;
53
+ colors: any;
54
+ borderClasses: string[];
55
+ twTheme: any;
56
+ }) => {
57
+ const properties = getBorderProperties(twTheme);
58
+
59
+ return (
60
+ <div className="wbtr:flex wbtr:items-center wbtr:gap-2">
61
+ <Dropdown
62
+ className="wbtr:border-control-dropdown"
63
+ contentClassName="wbtr:p-4"
64
+ renderToggle={({ isOpen, onToggle }) => (
65
+ <Button
66
+ onClick={onToggle}
67
+ aria-expanded={isOpen}
68
+ className={borderClasses.join(' ')}
69
+ >
70
+ {label}
71
+ </Button>
72
+ )}
73
+ renderContent={() => (
74
+ <div className="wbtr:flex wbtr:flex-col wbtr:gap-4">
75
+ {properties.map((property) => (
76
+ <SelectControl
77
+ key={property.name}
78
+ label={property.label}
79
+ value={value?.[property.name]}
80
+ options={property.values}
81
+ onChange={(selectValue) =>
82
+ onChange({ ...value, [property.name]: selectValue })
83
+ }
84
+ className="wbtr:w-24"
85
+ />
86
+ ))}
87
+
88
+ <div>
89
+ <p className="wbtr:uppercase">{__('Color', 'webentor')}</p>
90
+ <ColorPalette
91
+ colors={colors}
92
+ value={getColorBySlug(colors, value?.color)} // Get as hex value
93
+ onChange={(color) =>
94
+ onChange({
95
+ ...value,
96
+ color: getColorSlugByColor(colors, color), // Save as slug
97
+ })
98
+ }
99
+ disableCustomColors
100
+ />
101
+ </div>
102
+ </div>
103
+ )}
104
+ />
105
+ </div>
106
+ );
107
+ };
108
+
109
+ export const BorderSettings = ({
110
+ attributes,
111
+ setAttributes,
112
+ name,
113
+ breakpoint,
114
+ twTheme,
115
+ }: BorderSettingsProps) => {
116
+ if (!attributes?.border) {
117
+ return null;
118
+ }
119
+
120
+ const currentBorder: BorderValue = {
121
+ ...(attributes.border.border?.value?.[breakpoint] || {}),
122
+ };
123
+
124
+ const blockSettings = getBlockType(name)?.attributes;
125
+ const defaultBorderValue = blockSettings?.border?.default;
126
+
127
+ const isLinked = currentBorder.linked ?? true;
128
+
129
+ const borderTopClasses = prepareTailwindBorderClassesFromSettings(
130
+ attributes,
131
+ 'border',
132
+ 'top',
133
+ );
134
+
135
+ const borderRightClasses = prepareTailwindBorderClassesFromSettings(
136
+ attributes,
137
+ 'border',
138
+ 'right',
139
+ );
140
+
141
+ const borderBottomClasses = prepareTailwindBorderClassesFromSettings(
142
+ attributes,
143
+ 'border',
144
+ 'bottom',
145
+ );
146
+
147
+ const borderLeftClasses = prepareTailwindBorderClassesFromSettings(
148
+ attributes,
149
+ 'border',
150
+ 'left',
151
+ );
152
+
153
+ const borderClasses = [
154
+ ...borderTopClasses,
155
+ ...borderRightClasses,
156
+ ...borderBottomClasses,
157
+ ...borderLeftClasses,
158
+ ];
159
+
160
+ const colors = useSelect((select) => {
161
+ return select(blockEditorStore).getSettings().colors;
162
+ }, []);
163
+
164
+ const onChange = (
165
+ value: BorderSide,
166
+ side?: 'top' | 'right' | 'bottom' | 'left',
167
+ ) => {
168
+ if (!side) return;
169
+
170
+ if (isLinked) {
171
+ // When linked, update all sides with the same value
172
+ setAttributes(
173
+ setImmutably(attributes, ['border', 'border', 'value', breakpoint], {
174
+ ...currentBorder,
175
+ top: value,
176
+ right: value,
177
+ bottom: value,
178
+ left: value,
179
+ linked: isLinked,
180
+ }),
181
+ );
182
+ } else {
183
+ // When not linked, update only the specified side
184
+ setAttributes(
185
+ setImmutably(attributes, ['border', 'border', 'value', breakpoint], {
186
+ ...currentBorder,
187
+ [side]: value,
188
+ linked: isLinked,
189
+ }),
190
+ );
191
+ }
192
+ };
193
+
194
+ const toggleLinked = () => {
195
+ setAttributes(
196
+ setImmutably(
197
+ attributes,
198
+ ['border', 'border', 'value', breakpoint, 'linked'],
199
+ !isLinked,
200
+ ),
201
+ );
202
+ };
203
+
204
+ const resetBorder = () => {
205
+ setAttributes(
206
+ setImmutably(
207
+ attributes,
208
+ ['border', 'border', 'value'],
209
+ defaultBorderValue?.border?.value,
210
+ ),
211
+ );
212
+ };
213
+
214
+ const containerStyle = {
215
+ display: 'grid',
216
+ gridTemplateColumns: 'repeat(3, 1fr)',
217
+ gridTemplateRows: 'repeat(3, 1fr)',
218
+ gap: '8px',
219
+ alignItems: 'center',
220
+ justifyItems: 'center',
221
+ };
222
+
223
+ return (
224
+ <div className="wbtr:my-2 wbtr:flex wbtr:flex-col wbtr:gap-2 wbtr:border wbtr:border-editor-border wbtr:p-2">
225
+ <p className="wbtr:text-12 wbtr:uppercase">{__('Border', 'webentor')}</p>
226
+
227
+ <div style={containerStyle}>
228
+ {isLinked ? (
229
+ <>
230
+ <div style={{ gridColumn: 'span 3', gridRow: 'span 3' }}>
231
+ <WebentorBorderControl
232
+ label={__('All Borders', 'webentor')}
233
+ value={currentBorder.top}
234
+ onChange={(value) => onChange(value, 'top')}
235
+ colors={colors}
236
+ borderClasses={borderClasses}
237
+ twTheme={twTheme}
238
+ />
239
+ </div>
240
+ </>
241
+ ) : (
242
+ <>
243
+ <div style={{ gridColumn: '2', gridRow: '1' }}>
244
+ <WebentorBorderControl
245
+ label={__('Top', 'webentor')}
246
+ value={currentBorder.top}
247
+ onChange={(value) => onChange(value, 'top')}
248
+ colors={colors}
249
+ borderClasses={borderTopClasses}
250
+ twTheme={twTheme}
251
+ />
252
+ </div>
253
+ <div style={{ gridColumn: '3', gridRow: '2' }}>
254
+ <WebentorBorderControl
255
+ label={__('Right', 'webentor')}
256
+ value={currentBorder.right}
257
+ onChange={(value) => onChange(value, 'right')}
258
+ colors={colors}
259
+ borderClasses={borderRightClasses}
260
+ twTheme={twTheme}
261
+ />
262
+ </div>
263
+ <div style={{ gridColumn: '2', gridRow: '3' }}>
264
+ <WebentorBorderControl
265
+ label={__('Bottom', 'webentor')}
266
+ value={currentBorder.bottom}
267
+ onChange={(value) => onChange(value, 'bottom')}
268
+ colors={colors}
269
+ borderClasses={borderBottomClasses}
270
+ twTheme={twTheme}
271
+ />
272
+ </div>
273
+ <div style={{ gridColumn: '1', gridRow: '2' }}>
274
+ <WebentorBorderControl
275
+ label={__('Left', 'webentor')}
276
+ value={currentBorder.left}
277
+ onChange={(value) => onChange(value, 'left')}
278
+ colors={colors}
279
+ borderClasses={borderLeftClasses}
280
+ twTheme={twTheme}
281
+ />
282
+ </div>
283
+ </>
284
+ )}
285
+ </div>
286
+
287
+ <div className="wbtr:flex wbtr:justify-between">
288
+ <Button
289
+ icon={isLinked ? link : linkOff}
290
+ onClick={toggleLinked}
291
+ label={
292
+ isLinked
293
+ ? __('Unlink sides', 'webentor')
294
+ : __('Link sides', 'webentor')
295
+ }
296
+ />
297
+
298
+ <Button
299
+ variant="tertiary"
300
+ onClick={resetBorder}
301
+ disabled={isEmpty(currentBorder)}
302
+ label={__('Reset to defaults', 'webentor')}
303
+ showTooltip
304
+ >
305
+ {__('Reset', 'webentor')}
306
+ </Button>
307
+ </div>
308
+ </div>
309
+ );
310
+ };
@@ -0,0 +1 @@
1
+ export { BorderRadiusPanel } from './panel';
@@ -0,0 +1,31 @@
1
+ import { __ } from '@wordpress/i18n';
2
+
3
+ import { WebentorConfig } from '@webentorCore/types/_webentor-config';
4
+
5
+ export const getBorderRadiusValues = (twTheme: WebentorConfig['theme']) => {
6
+ const values = Object.keys(twTheme?.borderRadius).map((key) => ({
7
+ label: `${key} (${twTheme?.borderRadius[key]})`,
8
+ value: key,
9
+ }));
10
+
11
+ values.unshift({
12
+ label: __('None selected', 'webentor'),
13
+ value: '',
14
+ });
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
+ // ];
@@ -0,0 +1,211 @@
1
+ import { getBlockType } from '@wordpress/blocks';
2
+ import { Button, SelectControl } from '@wordpress/components';
3
+ import { __ } from '@wordpress/i18n';
4
+ import { link, linkOff } from '@wordpress/icons';
5
+
6
+ import { isEmpty, setImmutably } from '@webentorCore/_utils';
7
+
8
+ import { BlockPanelProps } from '../../../types';
9
+ import { getBorderRadiusValues } from './properties';
10
+
11
+ interface BorderRadiusSettingsProps extends BlockPanelProps {
12
+ breakpoint: string;
13
+ }
14
+
15
+ interface BorderRadiusValue {
16
+ topLeft?: string;
17
+ topRight?: string;
18
+ bottomRight?: string;
19
+ bottomLeft?: string;
20
+ linked?: boolean;
21
+ }
22
+
23
+ const WebentorBorderRadiusControl = ({
24
+ label,
25
+ value,
26
+ onChange,
27
+ twTheme,
28
+ }: {
29
+ label?: string;
30
+ value?: string;
31
+ onChange: (value: string) => void;
32
+ twTheme: any;
33
+ }) => {
34
+ const values = getBorderRadiusValues(twTheme);
35
+
36
+ return (
37
+ <SelectControl
38
+ label={label}
39
+ value={value ?? ''}
40
+ options={values}
41
+ onChange={onChange}
42
+ className="wbtr:w-24"
43
+ />
44
+ );
45
+ };
46
+
47
+ export const BorderRadiusSettings = ({
48
+ attributes,
49
+ setAttributes,
50
+ name,
51
+ breakpoint,
52
+ twTheme,
53
+ }: BorderRadiusSettingsProps) => {
54
+ if (!attributes?.border) {
55
+ return null;
56
+ }
57
+
58
+ const currentBorderRadius: BorderRadiusValue = {
59
+ ...(attributes.border.borderRadius?.value?.[breakpoint] || {}),
60
+ };
61
+
62
+ const blockSettings = getBlockType(name)?.attributes;
63
+ const defaultBorderRadius = blockSettings?.border?.default;
64
+
65
+ const isLinked = currentBorderRadius.linked ?? true;
66
+
67
+ const onChange = (
68
+ value: string,
69
+ corner?: 'topLeft' | 'topRight' | 'bottomRight' | 'bottomLeft',
70
+ ) => {
71
+ if (!corner) return;
72
+
73
+ if (isLinked) {
74
+ setAttributes(
75
+ setImmutably(
76
+ attributes,
77
+ ['border', 'borderRadius', 'value', breakpoint],
78
+ {
79
+ ...currentBorderRadius,
80
+ topLeft: value,
81
+ topRight: value,
82
+ bottomRight: value,
83
+ bottomLeft: value,
84
+ linked: isLinked,
85
+ },
86
+ ),
87
+ );
88
+ } else {
89
+ setAttributes(
90
+ setImmutably(
91
+ attributes,
92
+ ['border', 'borderRadius', 'value', breakpoint],
93
+ {
94
+ ...currentBorderRadius,
95
+ [corner]: value,
96
+ linked: isLinked,
97
+ },
98
+ ),
99
+ );
100
+ }
101
+ };
102
+
103
+ const toggleLinked = () => {
104
+ setAttributes(
105
+ setImmutably(
106
+ attributes,
107
+ ['border', 'borderRadius', 'value', breakpoint, 'linked'],
108
+ !isLinked,
109
+ ),
110
+ );
111
+ };
112
+
113
+ const resetBorderRadius = () => {
114
+ setAttributes(
115
+ setImmutably(
116
+ attributes,
117
+ ['border', 'borderRadius', 'value'],
118
+ defaultBorderRadius?.borderRadius?.value, // Reset to defaults
119
+ ),
120
+ );
121
+ };
122
+
123
+ const containerStyle = {
124
+ display: 'grid',
125
+ gridTemplateColumns: 'repeat(2, 1fr)',
126
+ gridTemplateRows: 'repeat(2, 1fr)',
127
+ gap: '8px',
128
+ alignItems: 'center',
129
+ justifyItems: 'center',
130
+ };
131
+
132
+ return (
133
+ <div className="wbtr:my-2 wbtr:flex wbtr:flex-col wbtr:gap-2 wbtr:border wbtr:border-editor-border wbtr:p-2">
134
+ <p className="wbtr:text-12 wbtr:uppercase">
135
+ {__('Border Radius', 'webentor')}
136
+ </p>
137
+
138
+ <div style={containerStyle}>
139
+ {isLinked ? (
140
+ <>
141
+ <div style={{ gridColumn: 'span 2', gridRow: 'span 2' }}>
142
+ <WebentorBorderRadiusControl
143
+ label={__('All Corners', 'webentor')}
144
+ value={currentBorderRadius?.topLeft}
145
+ onChange={(value) => onChange(value, 'topLeft')}
146
+ twTheme={twTheme}
147
+ />
148
+ </div>
149
+ </>
150
+ ) : (
151
+ <>
152
+ <div style={{ gridColumn: '1', gridRow: '1' }}>
153
+ <WebentorBorderRadiusControl
154
+ label={__('Top Left', 'webentor')}
155
+ value={currentBorderRadius?.topLeft}
156
+ onChange={(value) => onChange(value, 'topLeft')}
157
+ twTheme={twTheme}
158
+ />
159
+ </div>
160
+ <div style={{ gridColumn: '2', gridRow: '1' }}>
161
+ <WebentorBorderRadiusControl
162
+ label={__('Top Right', 'webentor')}
163
+ value={currentBorderRadius?.topRight}
164
+ onChange={(value) => onChange(value, 'topRight')}
165
+ twTheme={twTheme}
166
+ />
167
+ </div>
168
+ <div style={{ gridColumn: '2', gridRow: '2' }}>
169
+ <WebentorBorderRadiusControl
170
+ label={__('Bottom Right', 'webentor')}
171
+ value={currentBorderRadius?.bottomRight}
172
+ onChange={(value) => onChange(value, 'bottomRight')}
173
+ twTheme={twTheme}
174
+ />
175
+ </div>
176
+ <div style={{ gridColumn: '1', gridRow: '2' }}>
177
+ <WebentorBorderRadiusControl
178
+ label={__('Bottom Left', 'webentor')}
179
+ value={currentBorderRadius?.bottomLeft}
180
+ onChange={(value) => onChange(value, 'bottomLeft')}
181
+ twTheme={twTheme}
182
+ />
183
+ </div>
184
+ </>
185
+ )}
186
+ </div>
187
+
188
+ <div className="wbtr:flex wbtr:justify-between">
189
+ <Button
190
+ icon={isLinked ? link : linkOff}
191
+ onClick={toggleLinked}
192
+ label={
193
+ isLinked
194
+ ? __('Unlink corners', 'webentor')
195
+ : __('Link corners', 'webentor')
196
+ }
197
+ />
198
+
199
+ <Button
200
+ variant="tertiary"
201
+ onClick={resetBorderRadius}
202
+ disabled={isEmpty(currentBorderRadius)}
203
+ label={__('Reset to defaults', 'webentor')}
204
+ showTooltip
205
+ >
206
+ {__('Reset', 'webentor')}
207
+ </Button>
208
+ </div>
209
+ </div>
210
+ );
211
+ };
@@ -0,0 +1 @@
1
+ export { BorderPanel } from './panel';
@@ -0,0 +1,54 @@
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
+ };
@@ -0,0 +1,2 @@
1
+ export { DisplaySettings } from './settings';
2
+ export { getDisplayProperties } from './properties';