@eightshift/frontend-libs-tailwind 1.2.0 → 1.3.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/.prettierrc +1 -1
- package/CHANGELOG.md +12 -0
- package/blocks/init/assets/scripts/application-admin.js +1 -1
- package/blocks/init/src/Blocks/assets/scripts/link-section-editor.js +5 -1
- package/blocks/init/src/Blocks/assets/scripts/shared.js +3 -1
- package/blocks/init/src/Blocks/components/button/components/button-options.js +20 -2
- package/blocks/init/src/Blocks/components/card/components/card-editor.js +2 -1
- package/blocks/init/src/Blocks/components/icon/icon.php +3 -1
- package/blocks/init/src/Blocks/components/image/components/image-editor.js +7 -1
- package/blocks/init/src/Blocks/components/image/components/image-options.js +17 -3
- package/blocks/init/src/Blocks/components/list/components/list-options.js +3 -1
- package/blocks/init/src/Blocks/components/modal/assets/index.js +9 -7
- package/blocks/init/src/Blocks/components/paragraph/components/paragraph-options.js +3 -1
- package/blocks/init/src/Blocks/components/share/assets/index.js +5 -1
- package/blocks/init/src/Blocks/components/share/components/share-options.js +11 -2
- package/blocks/init/src/Blocks/components/video/components/video-editor.js +4 -2
- package/blocks/init/src/Blocks/components/video/components/video-options.js +24 -3
- package/blocks/init/src/Blocks/components/video/manifest.json +1 -1
- package/blocks/init/src/Blocks/components/video/video.php +0 -2
- package/blocks/init/src/Blocks/custom/carousel/assets/pagination.js +8 -2
- package/blocks/init/src/Blocks/custom/column/components/column-options.js +12 -4
- package/blocks/init/src/Blocks/custom/columns/components/columns-editor.js +6 -2
- package/blocks/init/src/Blocks/custom/featured-content/components/featured-content-options.js +29 -8
- package/blocks/init/src/Blocks/custom/map/components/map-editor.js +12 -2
- package/blocks/init/src/Blocks/custom/map/components/map-options.js +40 -11
- package/blocks/init/src/Blocks/custom/site-footer/components/site-footer-options.js +3 -1
- package/blocks/init/src/Blocks/custom/site-footer/manifest.json +1 -1
- package/blocks/init/src/Blocks/custom/site-navigation/manifest.json +1 -1
- package/blocks/init/src/Blocks/wrapper/components/wrapper-options.js +19 -4
- package/package.json +15 -15
- package/schemas/block.json +16 -16
- package/schemas/component.json +18 -18
- package/scripts/components/block-inserter.js +4 -1
- package/scripts/components/link-section-editor.js +5 -1
- package/scripts/components/media-picker.js +12 -1
- package/scripts/components/picker-placeholder.js +6 -2
- package/scripts/components/server-side-render.js +4 -1
- package/scripts/components/settings/settings.js +8 -2
- package/scripts/editor/attributes.js +33 -3
- package/scripts/editor/editor.js +7 -1
- package/scripts/editor/fetch.js +2 -1
- package/scripts/editor/index.js +8 -1
- package/scripts/editor/options.js +3 -1
- package/scripts/editor/registration.js +87 -17
- package/scripts/editor/tailwindcss.js +96 -58
- package/scripts/helpers/index.js +7 -1
- package/scripts/index.js +15 -2
- package/webpack/base.mjs +3 -1
- package/webpack/helpers.mjs +13 -3
- package/webpack/project.mjs +8 -2
package/.prettierrc
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
This projects adheres to [Semantic Versioning](https://semver.org/) and [Keep a CHANGELOG](https://keepachangelog.com/).
|
|
6
6
|
|
|
7
|
+
## [1.3.1] - 2024-09-13
|
|
8
|
+
- Helper `getFilteredAttributes` used on SSR components to filter out unwanted attributes and optimize the output.
|
|
9
|
+
|
|
10
|
+
## [1.3.0] - 2024-08-08
|
|
11
|
+
- `twClasses` and `twClassesEditor` can now be passed as an array
|
|
12
|
+
- Updated schemas to account for the `twClasses`/`twClassesEditor` changes.
|
|
13
|
+
- Tailwind output functions will now output the custom classes if no Tailwind classes are in the output.
|
|
14
|
+
- Tweaked Prettier config.
|
|
15
|
+
- Updated dependencies.
|
|
16
|
+
|
|
7
17
|
## [1.2.0] - 2024-08-08
|
|
8
18
|
- Fixed default `perPage` param in `wpSearchRoute`.
|
|
9
19
|
- Updated image and file pickers with support for `hidden` prop and accepted types passthrough.
|
|
@@ -33,6 +43,8 @@ This projects adheres to [Semantic Versioning](https://semver.org/) and [Keep a
|
|
|
33
43
|
|
|
34
44
|
[Unreleased]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/master...HEAD
|
|
35
45
|
|
|
46
|
+
[1.3.1]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.3.0...1.3.1
|
|
47
|
+
[1.3.0]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.2.0...1.3.0
|
|
36
48
|
[1.2.0]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.1.1...1.2.0
|
|
37
49
|
[1.1.1]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.1.0...1.1.1
|
|
38
50
|
[1.1.0]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.0.0...1.1.0
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
|
|
5
5
|
import { dynamicImport } from '@eightshift/frontend-libs-tailwind/scripts/helpers';
|
|
6
6
|
|
|
7
|
-
dynamicImport(require.context('./../../src/
|
|
7
|
+
dynamicImport(require.context('./../../src/Blocks/components', true, /assets-admin\/index\.js$/));
|
|
@@ -175,7 +175,11 @@ export const LinkSectionEditor = (props) => {
|
|
|
175
175
|
setTimeout(() => {
|
|
176
176
|
target.parentElement.nextElementSibling?.querySelector('[contenteditable="true"]')?.focus();
|
|
177
177
|
}, 25);
|
|
178
|
-
} else if (
|
|
178
|
+
} else if (
|
|
179
|
+
code === 'Backspace' &&
|
|
180
|
+
header === '' &&
|
|
181
|
+
(items?.length < 1 || items?.every(({ text }) => text === ''))
|
|
182
|
+
) {
|
|
179
183
|
event.preventDefault();
|
|
180
184
|
|
|
181
185
|
// Jump to end of previous input.
|
|
@@ -5,7 +5,9 @@ const colorData = getColorData(themeColors);
|
|
|
5
5
|
|
|
6
6
|
export const getColorOption = (key, manifest) => {
|
|
7
7
|
if (!manifest?.options?.[key]) {
|
|
8
|
-
throw new Error(
|
|
8
|
+
throw new Error(
|
|
9
|
+
`The key ${key} is not defined in the manifest options for ${manifest?.componentName ?? manifest?.title}.`,
|
|
10
|
+
);
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
return colorData?.filter(({ slug }) => manifest?.options?.[key]?.includes(slug)) ?? [];
|
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getOption,
|
|
4
|
+
checkAttr,
|
|
5
|
+
getAttrKey,
|
|
6
|
+
props,
|
|
7
|
+
getOptions,
|
|
8
|
+
wpSearchRoute,
|
|
9
|
+
getHiddenOptions,
|
|
10
|
+
} from '@eightshift/frontend-libs-tailwind/scripts';
|
|
3
11
|
import { IconOptions } from '../../icon/components/icon-options';
|
|
4
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
ButtonGroup,
|
|
14
|
+
ColorPicker,
|
|
15
|
+
ComponentToggle,
|
|
16
|
+
HStack,
|
|
17
|
+
InputField,
|
|
18
|
+
LinkInput,
|
|
19
|
+
OptionSelect,
|
|
20
|
+
Spacer,
|
|
21
|
+
Toggle,
|
|
22
|
+
} from '@eightshift/ui-components';
|
|
5
23
|
import { icons } from '@eightshift/ui-components/icons';
|
|
6
24
|
import { upperFirst } from '@eightshift/ui-components/utilities';
|
|
7
25
|
import manifest from './../manifest.json';
|
|
@@ -15,7 +15,8 @@ export const CardEditor = (attributes) => {
|
|
|
15
15
|
additionalClass: {
|
|
16
16
|
image: getTwPart('image', manifest),
|
|
17
17
|
picture: getTwPart('imagePicture', manifest),
|
|
18
|
-
imagePlaceholder:
|
|
18
|
+
imagePlaceholder:
|
|
19
|
+
'!border-x-0 !border-t-0 !border-solid !w-full !h-auto aspect-3/2 [&_svg]:!size-12 border-b !rounded-none bg-gray-100 !border-b-gray-200',
|
|
19
20
|
},
|
|
20
21
|
})}
|
|
21
22
|
/>
|
|
@@ -28,7 +28,9 @@ $icon = $manifest['icons'][$iconName];
|
|
|
28
28
|
|
|
29
29
|
$className = Helpers::getTwClasses($attributes, $manifest, $additionalClass);
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
if (!empty($className)) {
|
|
32
|
+
$icon = str_replace('<svg ', '<svg class="' . htmlspecialchars($className) . '" ', $icon);
|
|
33
|
+
}
|
|
32
34
|
|
|
33
35
|
// phpcs:ignore Eightshift.Security.HelpersEscape.OutputNotEscaped
|
|
34
36
|
echo $icon;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
checkAttr,
|
|
3
|
+
getBreakpointData,
|
|
4
|
+
getBreakpointNames,
|
|
5
|
+
getTwClasses,
|
|
6
|
+
getTwPart,
|
|
7
|
+
} from '@eightshift/frontend-libs-tailwind/scripts';
|
|
2
8
|
import { ImagePlaceholder } from '@eightshift/ui-components';
|
|
3
9
|
import manifest from './../manifest.json';
|
|
4
10
|
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
checkAttr,
|
|
4
|
+
getAttrKey,
|
|
5
|
+
MediaPicker,
|
|
6
|
+
generateOptionsFromValue,
|
|
7
|
+
getOption,
|
|
8
|
+
getHiddenOptions,
|
|
9
|
+
getResponsiveData,
|
|
10
|
+
} from '@eightshift/frontend-libs-tailwind/scripts';
|
|
3
11
|
import manifest from './../manifest.json';
|
|
4
12
|
import { ComponentToggle, OptionSelect, Responsive, Spacer, Toggle } from '@eightshift/ui-components';
|
|
5
13
|
import { icons } from '@eightshift/ui-components/icons';
|
|
@@ -33,7 +41,11 @@ export const ImageOptions = (attributes) => {
|
|
|
33
41
|
icon={icons.imageFile}
|
|
34
42
|
label={__('Image', 'eightshift-ui-components')}
|
|
35
43
|
options={generateOptionsFromValue(imageData, (v) =>
|
|
36
|
-
truncateMiddle(
|
|
44
|
+
truncateMiddle(
|
|
45
|
+
v?.url?.replace(window.location.origin, '')?.replace(/\/wp-content\/uploads\/\d{4}\/\d{2}\//g, '') ??
|
|
46
|
+
__('Not set', '%g_textdomain%'),
|
|
47
|
+
15,
|
|
48
|
+
),
|
|
37
49
|
)}
|
|
38
50
|
hidden={hiddenOptions?.imagePicker}
|
|
39
51
|
{...responsiveData}
|
|
@@ -86,7 +98,9 @@ export const ImageOptions = (attributes) => {
|
|
|
86
98
|
icon={icons.expandXl}
|
|
87
99
|
label={__('Stretch', '%g_textdomain%')}
|
|
88
100
|
checked={imageSize === 'stretch'}
|
|
89
|
-
onChange={(value) =>
|
|
101
|
+
onChange={(value) =>
|
|
102
|
+
setAttributes({ [getAttrKey('imageSize', attributes, manifest)]: value ? 'stretch' : 'default' })
|
|
103
|
+
}
|
|
90
104
|
hidden={hiddenOptions?.stretch}
|
|
91
105
|
/>
|
|
92
106
|
|
|
@@ -35,7 +35,9 @@ export const ListOptions = (attributes) => {
|
|
|
35
35
|
<ToggleButton
|
|
36
36
|
selected={listFontWeight === '700'}
|
|
37
37
|
icon={icons.bold}
|
|
38
|
-
onChange={(value) =>
|
|
38
|
+
onChange={(value) =>
|
|
39
|
+
setAttributes({ [getAttrKey('listFontWeight', attributes, manifest)]: value ? '700' : '400' })
|
|
40
|
+
}
|
|
39
41
|
tooltip={__('Bold', '%g_textdomain%')}
|
|
40
42
|
hidden={hiddenOptions.weight}
|
|
41
43
|
/>
|
|
@@ -11,15 +11,17 @@ domReady(() => {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
elements.forEach((element) => {
|
|
14
|
-
document
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
document
|
|
15
|
+
.querySelectorAll(`[href=":open-modal-${element.id}:"],[data-micromodal-trigger="${element.id}"]`)
|
|
16
|
+
.forEach((trigger) => {
|
|
17
|
+
trigger.addEventListener('click', (event) => {
|
|
18
|
+
event.preventDefault();
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
MicroModal.show(element.id, {
|
|
21
|
+
disableScroll: true,
|
|
22
|
+
awaitCloseAnimation: true,
|
|
23
|
+
});
|
|
21
24
|
});
|
|
22
25
|
});
|
|
23
|
-
});
|
|
24
26
|
});
|
|
25
27
|
});
|
|
@@ -34,7 +34,9 @@ export const ParagraphOptions = (attributes) => {
|
|
|
34
34
|
<ToggleButton
|
|
35
35
|
selected={paragraphFontWeight === '700'}
|
|
36
36
|
icon={icons.bold}
|
|
37
|
-
onChange={(value) =>
|
|
37
|
+
onChange={(value) =>
|
|
38
|
+
setAttributes({ [getAttrKey('paragraphFontWeight', attributes, manifest)]: value ? '700' : '400' })
|
|
39
|
+
}
|
|
38
40
|
tooltip={__('Bold', '%g_textdomain%')}
|
|
39
41
|
hidden={hiddenOptions.weight}
|
|
40
42
|
/>
|
|
@@ -17,7 +17,11 @@ domReady(async () => {
|
|
|
17
17
|
if ('share' in navigator && navigator?.canShare(navigatorShareData)) {
|
|
18
18
|
await navigator?.share(navigatorShareData);
|
|
19
19
|
} else {
|
|
20
|
-
window.open(
|
|
20
|
+
window.open(
|
|
21
|
+
shareUrl,
|
|
22
|
+
'share-post',
|
|
23
|
+
'height=600,width=800,left=0,top=0,location=0,menubar=0,toolbar=0,status=0,scrollbars=1,resizable=1',
|
|
24
|
+
);
|
|
21
25
|
}
|
|
22
26
|
};
|
|
23
27
|
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
2
|
import { checkAttr, getAttrKey, getHiddenOptions } from '@eightshift/frontend-libs-tailwind/scripts';
|
|
3
3
|
import manifest from '../manifest.json';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ComponentToggle,
|
|
6
|
+
OptionSelect,
|
|
7
|
+
DraggableList,
|
|
8
|
+
DraggableListItem,
|
|
9
|
+
Spacer,
|
|
10
|
+
Switch,
|
|
11
|
+
} from '@eightshift/ui-components';
|
|
5
12
|
import { icons, JsxSvg } from '@eightshift/ui-components/icons';
|
|
6
13
|
|
|
7
14
|
export const ShareOptions = (attributes) => {
|
|
@@ -36,7 +43,9 @@ export const ShareOptions = (attributes) => {
|
|
|
36
43
|
},
|
|
37
44
|
];
|
|
38
45
|
|
|
39
|
-
const pickerSectionTitle = shareMode
|
|
46
|
+
const pickerSectionTitle = shareMode
|
|
47
|
+
? __('Share targets', '%g_textdomain%')
|
|
48
|
+
: __('Social networks', '%g_textdomain%');
|
|
40
49
|
|
|
41
50
|
return (
|
|
42
51
|
<ComponentToggle
|
|
@@ -34,7 +34,8 @@ export const VideoEditor = (attributes) => {
|
|
|
34
34
|
setAttributes({
|
|
35
35
|
[getAttrKey('videoId', attributes, manifest)]: id,
|
|
36
36
|
[getAttrKey('videoUrl', attributes, manifest)]: url,
|
|
37
|
-
[getAttrKey('videoMimeType', attributes, manifest)]:
|
|
37
|
+
[getAttrKey('videoMimeType', attributes, manifest)]:
|
|
38
|
+
typeof mime === 'undefined' ? mime_type : mime,
|
|
38
39
|
})
|
|
39
40
|
}
|
|
40
41
|
allowedTypes={manifest.allowedTypes}
|
|
@@ -47,7 +48,8 @@ export const VideoEditor = (attributes) => {
|
|
|
47
48
|
setAttributes({
|
|
48
49
|
[getAttrKey('videoId', attributes, manifest)]: id,
|
|
49
50
|
[getAttrKey('videoUrl', attributes, manifest)]: url,
|
|
50
|
-
[getAttrKey('videoMimeType', attributes, manifest)]:
|
|
51
|
+
[getAttrKey('videoMimeType', attributes, manifest)]:
|
|
52
|
+
typeof mime === 'undefined' ? mime_type : mime,
|
|
51
53
|
})
|
|
52
54
|
}
|
|
53
55
|
allowedTypes={['video/mp4', 'video/webm']}
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import { __, sprintf } from '@wordpress/i18n';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
getOption,
|
|
4
|
+
checkAttr,
|
|
5
|
+
getAttrKey,
|
|
6
|
+
FileSelector,
|
|
7
|
+
getHiddenOptions,
|
|
8
|
+
MediaPicker,
|
|
9
|
+
} from '@eightshift/frontend-libs-tailwind/scripts';
|
|
10
|
+
import {
|
|
11
|
+
AnimatedVisibility,
|
|
12
|
+
BaseControl,
|
|
13
|
+
Expandable,
|
|
14
|
+
InputField,
|
|
15
|
+
Notice,
|
|
16
|
+
OptionSelect,
|
|
17
|
+
Repeater,
|
|
18
|
+
RepeaterItem,
|
|
19
|
+
Spacer,
|
|
20
|
+
Toggle,
|
|
21
|
+
} from '@eightshift/ui-components';
|
|
4
22
|
import { icons } from '@eightshift/ui-components/icons';
|
|
5
23
|
import manifest from '../manifest.json';
|
|
6
24
|
|
|
@@ -109,7 +127,10 @@ export const VideoOptions = (attributes) => {
|
|
|
109
127
|
<Notice
|
|
110
128
|
type='warning'
|
|
111
129
|
label={__('Video plays automatically, with sound, and without controls', '%g_textdomain%')}
|
|
112
|
-
subtitle={__(
|
|
130
|
+
subtitle={__(
|
|
131
|
+
'This will bother most users and is an accessibility issue. Consider changing some of the options.',
|
|
132
|
+
'%g_textdomain%',
|
|
133
|
+
)}
|
|
113
134
|
icon={icons.a11yWarning}
|
|
114
135
|
alignIconToTitle
|
|
115
136
|
/>
|
|
@@ -26,7 +26,6 @@ if (empty($videoUrl)) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
$videoMimeType = Helpers::checkAttr('videoMimeType', $attributes, $manifest);
|
|
29
|
-
$videoPosterId = Helpers::checkAttr('videoPosterId', $attributes, $manifest);
|
|
30
29
|
$videoPosterUrl = Helpers::checkAttr('videoPosterUrl', $attributes, $manifest);
|
|
31
30
|
$videoLoop = Helpers::checkAttr('videoLoop', $attributes, $manifest);
|
|
32
31
|
$videoAutoplay = Helpers::checkAttr('videoAutoplay', $attributes, $manifest);
|
|
@@ -47,7 +46,6 @@ $additionalAttributes = Helpers::classnames([
|
|
|
47
46
|
class="<?php echo esc_attr(Helpers::getTwPart('video', $manifest)); ?>"
|
|
48
47
|
<?php echo esc_attr($additionalAttributes); ?>
|
|
49
48
|
preload="<?php echo esc_attr($videoPreload); ?>"
|
|
50
|
-
poster="<?php echo esc_attr($videoPosterUrl); ?>"
|
|
51
49
|
<?php if ($videoPosterUrl) { ?>
|
|
52
50
|
poster="<?php echo esc_attr($videoPosterUrl); ?>"
|
|
53
51
|
<?php } ?>
|
|
@@ -8,7 +8,8 @@ export const addPagination = (emblaApi, dotsNode) => {
|
|
|
8
8
|
|
|
9
9
|
dotNodes = emblaApi.scrollSnapList().map((_, index) => {
|
|
10
10
|
const elem = document.createElement('button');
|
|
11
|
-
elem.className =
|
|
11
|
+
elem.className =
|
|
12
|
+
'size-2.5 rounded-full border border-gray-500 transition hover:scale-105 focus:outline-none focus-visible:ring focus-visible:ring-navy-500/30';
|
|
12
13
|
|
|
13
14
|
elem.addEventListener('click', () => emblaApi.scrollTo(index), false);
|
|
14
15
|
dotsNode.appendChild(elem);
|
|
@@ -26,7 +27,12 @@ export const addPagination = (emblaApi, dotsNode) => {
|
|
|
26
27
|
});
|
|
27
28
|
};
|
|
28
29
|
|
|
29
|
-
emblaApi
|
|
30
|
+
emblaApi
|
|
31
|
+
.on('init', addDots)
|
|
32
|
+
.on('reInit', addDots)
|
|
33
|
+
.on('init', toggleDotBtnsActive)
|
|
34
|
+
.on('reInit', toggleDotBtnsActive)
|
|
35
|
+
.on('select', toggleDotBtnsActive);
|
|
30
36
|
|
|
31
37
|
return () => {
|
|
32
38
|
dotsNode.innerHTML = '';
|
|
@@ -209,7 +209,9 @@ export const ColumnOptions = ({ attributes, setAttributes }) => {
|
|
|
209
209
|
}
|
|
210
210
|
icon={icons.gridAutoRows}
|
|
211
211
|
label={__('Row span', '%g_textdomain%')}
|
|
212
|
-
options={generateOptionsFromValue(columnRowSpan, (v) =>
|
|
212
|
+
options={generateOptionsFromValue(columnRowSpan, (v) =>
|
|
213
|
+
!v ? __('Not set', '%g_textdomain%') : sprintf(_n('1 row', '%d rows', v, '%g_textdomain%'), v),
|
|
214
|
+
)}
|
|
213
215
|
noModeSelect
|
|
214
216
|
inline
|
|
215
217
|
{...responsiveData}
|
|
@@ -311,7 +313,9 @@ export const ColumnOptions = ({ attributes, setAttributes }) => {
|
|
|
311
313
|
setAttributes({ [getAttrKey('columnBackground', attributes, manifest)]: undefined });
|
|
312
314
|
} else {
|
|
313
315
|
setAttributes({
|
|
314
|
-
[getAttrKey('columnBackground', attributes, manifest)]: Object.keys(
|
|
316
|
+
[getAttrKey('columnBackground', attributes, manifest)]: Object.keys(
|
|
317
|
+
manifest.tailwind.options.columnBackground.twClasses,
|
|
318
|
+
).find((key) => key.startsWith(value)),
|
|
315
319
|
});
|
|
316
320
|
}
|
|
317
321
|
}}
|
|
@@ -323,7 +327,9 @@ export const ColumnOptions = ({ attributes, setAttributes }) => {
|
|
|
323
327
|
{backgroundType === 'solid' && (
|
|
324
328
|
<ColorPicker
|
|
325
329
|
colors={getColorOption('columnBackgroundSolid', manifest)}
|
|
326
|
-
onChange={(value) =>
|
|
330
|
+
onChange={(value) =>
|
|
331
|
+
setAttributes({ [getAttrKey('columnBackground', attributes, manifest)]: `solid-${value}` })
|
|
332
|
+
}
|
|
327
333
|
value={columnBackground?.replace('solid-', '')}
|
|
328
334
|
aria-label={__('Background color', '%g_textdomain%')}
|
|
329
335
|
/>
|
|
@@ -360,7 +366,9 @@ export const ColumnOptions = ({ attributes, setAttributes }) => {
|
|
|
360
366
|
/>
|
|
361
367
|
<OptionSelect
|
|
362
368
|
value={columnGradientDirection}
|
|
363
|
-
onChange={(value) =>
|
|
369
|
+
onChange={(value) =>
|
|
370
|
+
setAttributes({ [getAttrKey('columnGradientDirection', attributes, manifest)]: value })
|
|
371
|
+
}
|
|
364
372
|
options={getOption('columnGradientDirection', attributes, manifest)}
|
|
365
373
|
wrapperProps={{
|
|
366
374
|
triggerIcon: <div className={rotationClassName[columnGradientDirection]}>{icons.arrowUpCircle}</div>,
|
|
@@ -10,7 +10,9 @@ import manifest from './../manifest.json';
|
|
|
10
10
|
export const ColumnsEditor = ({ attributes, setAttributes, clientId }) => {
|
|
11
11
|
const { title, layoutPresets } = manifest;
|
|
12
12
|
|
|
13
|
-
const innerBlockCount = useSelect(
|
|
13
|
+
const innerBlockCount = useSelect(
|
|
14
|
+
(select) => select('core/block-editor').getBlock(clientId).innerBlocks?.length ?? 0,
|
|
15
|
+
);
|
|
14
16
|
|
|
15
17
|
const blockProps = useBlockProps();
|
|
16
18
|
const innerBlocksProps = useInnerBlocksProps(blockProps, {
|
|
@@ -36,7 +38,9 @@ export const ColumnsEditor = ({ attributes, setAttributes, clientId }) => {
|
|
|
36
38
|
<Button
|
|
37
39
|
key={index}
|
|
38
40
|
onPress={async () => {
|
|
39
|
-
const blocksToInsert = blockData.map(({ name: blockName, attributes: blockAttrs }) =>
|
|
41
|
+
const blocksToInsert = blockData.map(({ name: blockName, attributes: blockAttrs }) =>
|
|
42
|
+
createBlock(blockName, blockAttrs),
|
|
43
|
+
);
|
|
40
44
|
|
|
41
45
|
setAttributes(attrsToSet);
|
|
42
46
|
|
package/blocks/init/src/Blocks/custom/featured-content/components/featured-content-options.js
CHANGED
|
@@ -2,7 +2,14 @@ import { useState } from '@wordpress/element';
|
|
|
2
2
|
import { __ } from '@wordpress/i18n';
|
|
3
3
|
import { getAttrKey, checkAttr, getOption, props, fetchFromWpRest } from '@eightshift/frontend-libs-tailwind/scripts';
|
|
4
4
|
import { LoadMoreOptions } from '../../../components/load-more/components/load-more-options';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AnimatedVisibility,
|
|
7
|
+
AsyncMultiSelect,
|
|
8
|
+
NumberPicker,
|
|
9
|
+
OptionSelect,
|
|
10
|
+
Spacer,
|
|
11
|
+
Toggle,
|
|
12
|
+
} from '@eightshift/ui-components';
|
|
6
13
|
import { icons } from '@eightshift/ui-components/icons';
|
|
7
14
|
import manifest from '../manifest.json';
|
|
8
15
|
|
|
@@ -96,7 +103,9 @@ export const FeaturedContentOptions = ({ attributes, setAttributes }) => {
|
|
|
96
103
|
label: __('Select posts to show', '%g_textdomain%'),
|
|
97
104
|
value: true,
|
|
98
105
|
disabled: featuredContentExcludeCurrentPost || featuredContentTaxonomy,
|
|
99
|
-
subtitle:
|
|
106
|
+
subtitle:
|
|
107
|
+
(featuredContentExcludeCurrentPost || featuredContentTaxonomy) &&
|
|
108
|
+
__('Unavailable when a taxonomy filter is set', '%g_textdomain%'),
|
|
100
109
|
},
|
|
101
110
|
]}
|
|
102
111
|
type='radiosSegmented'
|
|
@@ -112,7 +121,9 @@ export const FeaturedContentOptions = ({ attributes, setAttributes }) => {
|
|
|
112
121
|
label={__('Exclude current', '%g_textdomain%')}
|
|
113
122
|
subtitle={__('Best used with blog posts', '%g_textdomain%')}
|
|
114
123
|
checked={featuredContentExcludeCurrentPost}
|
|
115
|
-
onChange={(value) =>
|
|
124
|
+
onChange={(value) =>
|
|
125
|
+
setAttributes({ [getAttrKey('featuredContentExcludeCurrentPost', attributes, manifest)]: value })
|
|
126
|
+
}
|
|
116
127
|
/>
|
|
117
128
|
</AnimatedVisibility>
|
|
118
129
|
|
|
@@ -122,7 +133,10 @@ export const FeaturedContentOptions = ({ attributes, setAttributes }) => {
|
|
|
122
133
|
>
|
|
123
134
|
<AsyncMultiSelect
|
|
124
135
|
key={featuredContentPostType.value}
|
|
125
|
-
help={__(
|
|
136
|
+
help={__(
|
|
137
|
+
'Newest 30 items are shown, others can be selected by searching. If blank, all items are shown.',
|
|
138
|
+
'%g_textdomain%',
|
|
139
|
+
)}
|
|
126
140
|
value={featuredContentPosts}
|
|
127
141
|
loadOptions={fetchFromWpRest(featuredContentPostType?.api, {
|
|
128
142
|
processLabel: ({ title: { rendered } }) => rendered,
|
|
@@ -153,10 +167,12 @@ export const FeaturedContentOptions = ({ attributes, setAttributes }) => {
|
|
|
153
167
|
setUseSpecificPosts(false);
|
|
154
168
|
setUseSpecificTerms(false);
|
|
155
169
|
|
|
156
|
-
const value =
|
|
170
|
+
const value =
|
|
171
|
+
rawValue === '_all' ? allGenericOption : taxonomyOptions.find((option) => option.value === rawValue);
|
|
157
172
|
|
|
158
173
|
setAttributes({
|
|
159
|
-
[getAttrKey('featuredContentTaxonomy', attributes, manifest)]:
|
|
174
|
+
[getAttrKey('featuredContentTaxonomy', attributes, manifest)]:
|
|
175
|
+
value === allGenericOption ? undefined : value,
|
|
160
176
|
[getAttrKey('featuredContentTerms', attributes, manifest)]: undefined,
|
|
161
177
|
[getAttrKey('featuredContentUseCurrentTerm', attributes, manifest)]: false,
|
|
162
178
|
[getAttrKey('featuredContentPosts', attributes, manifest)]: undefined,
|
|
@@ -183,7 +199,9 @@ export const FeaturedContentOptions = ({ attributes, setAttributes }) => {
|
|
|
183
199
|
label: __('Select terms to show', '%g_textdomain%'),
|
|
184
200
|
value: 'manual',
|
|
185
201
|
disabled: (featuredContentTaxonomy ?? allGenericOption)?.value === '_all',
|
|
186
|
-
subtitle:
|
|
202
|
+
subtitle:
|
|
203
|
+
(featuredContentTaxonomy ?? allGenericOption)?.value === '_all' &&
|
|
204
|
+
__('Select a taxonomy to enable', '%g_textdomain%'),
|
|
187
205
|
},
|
|
188
206
|
{
|
|
189
207
|
label: __('Show same terms as current post', '%g_textdomain%'),
|
|
@@ -200,7 +218,10 @@ export const FeaturedContentOptions = ({ attributes, setAttributes }) => {
|
|
|
200
218
|
>
|
|
201
219
|
<AsyncMultiSelect
|
|
202
220
|
key={featuredContentTaxonomy?.value}
|
|
203
|
-
help={__(
|
|
221
|
+
help={__(
|
|
222
|
+
'Newest 30 items are shown, others can be selected by searching. If blank, all items are shown.',
|
|
223
|
+
'%g_textdomain%',
|
|
224
|
+
)}
|
|
204
225
|
value={featuredContentTerms}
|
|
205
226
|
loadOptions={fetchFromWpRest(featuredContentTaxonomy?.api, {
|
|
206
227
|
fields: 'id,name',
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { checkAttr } from '@eightshift/frontend-libs-tailwind/scripts';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Interactions,
|
|
4
|
+
Layers,
|
|
5
|
+
MapInteraction,
|
|
6
|
+
OpenLayersMap,
|
|
7
|
+
Controls,
|
|
8
|
+
MapControl,
|
|
9
|
+
processMapLayer,
|
|
10
|
+
} from './map-components';
|
|
3
11
|
import manifest from '../manifest.json';
|
|
4
12
|
|
|
5
13
|
export const MapEditor = ({ attributes }) => {
|
|
@@ -17,7 +25,9 @@ export const MapEditor = ({ attributes }) => {
|
|
|
17
25
|
center={[mapCenterLon ?? 16.352532, mapCenterLat ?? 46.314045]}
|
|
18
26
|
zoom={mapZoom}
|
|
19
27
|
>
|
|
20
|
-
<Layers key={mapLayers.map(({ id, type }) => `${id}-${type}`).join(',')}>
|
|
28
|
+
<Layers key={mapLayers.map(({ id, type }) => `${id}-${type}`).join(',')}>
|
|
29
|
+
{[...mapLayers].reverse().map((layer) => processMapLayer(layer))}
|
|
30
|
+
</Layers>
|
|
21
31
|
|
|
22
32
|
<Interactions>
|
|
23
33
|
<MapInteraction
|
|
@@ -111,15 +111,33 @@ export const MapOptions = ({ attributes, setAttributes }) => {
|
|
|
111
111
|
{(layer) => {
|
|
112
112
|
const { type, apiKey, geoJsonUrl, geoJsonId, styleUrl, hidden, updateData } = layer;
|
|
113
113
|
|
|
114
|
-
const needsApiKey = [
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
const needsApiKey = [
|
|
115
|
+
'mapBoxVector',
|
|
116
|
+
'mapBoxRaster',
|
|
117
|
+
'mapTilerVector',
|
|
118
|
+
'vectorJson',
|
|
119
|
+
'mapTilerRasterXyz',
|
|
120
|
+
'mapTilerRasterJson',
|
|
121
|
+
].includes(type);
|
|
122
|
+
|
|
123
|
+
const hasMapStyleOptions = [
|
|
124
|
+
'mapBoxVector',
|
|
125
|
+
'mapBoxRaster',
|
|
126
|
+
'mapTilerVector',
|
|
127
|
+
'vectorJson',
|
|
128
|
+
'mapTilerRasterXyz',
|
|
129
|
+
'mapTilerRasterJson',
|
|
130
|
+
].includes(type);
|
|
117
131
|
|
|
118
132
|
return (
|
|
119
133
|
<RepeaterItem
|
|
120
|
-
icon={layer?.type ? layerTypes?.[layer?.type]?.icon ?? icons.mapLayer : icons.layerOff}
|
|
134
|
+
icon={layer?.type ? (layerTypes?.[layer?.type]?.icon ?? icons.mapLayer) : icons.layerOff}
|
|
121
135
|
label={layerTypes?.[type]?.title ?? __('New layer', '%g_textdomain%')}
|
|
122
|
-
subtitle={
|
|
136
|
+
subtitle={
|
|
137
|
+
type === 'geoJson'
|
|
138
|
+
? truncateMiddle(geoJsonUrl?.slice(geoJsonUrl?.lastIndexOf('/') + 1) ?? '', 20)
|
|
139
|
+
: layerTypes?.[type]?.subtitle
|
|
140
|
+
}
|
|
123
141
|
actions={
|
|
124
142
|
layer?.type?.length < 1 ? (
|
|
125
143
|
icons.dummySpacer
|
|
@@ -160,15 +178,23 @@ export const MapOptions = ({ attributes, setAttributes }) => {
|
|
|
160
178
|
onChange={(value) => updateData({ styleUrl: value })}
|
|
161
179
|
help={
|
|
162
180
|
<>
|
|
163
|
-
{!type?.startsWith('mapBox') &&
|
|
181
|
+
{!type?.startsWith('mapBox') &&
|
|
182
|
+
__('Copy the full style URL from MapTiler. Keep the API key inside the URL.', '%g_textdomain%')}
|
|
164
183
|
{type === 'mapBoxVector' && __('Copy the full style URL from Mapbox.', '%g_textdomain%')}
|
|
165
|
-
{type === 'mapBoxRaster' &&
|
|
184
|
+
{type === 'mapBoxRaster' &&
|
|
185
|
+
__(
|
|
186
|
+
'Copy the full style URL from Mapbox or a Mapbox-compatible source. Keep the access token inside the URL.',
|
|
187
|
+
'%g_textdomain%',
|
|
188
|
+
)}
|
|
166
189
|
<br />
|
|
167
190
|
<br />
|
|
168
191
|
{['mapBoxRaster', 'mapTilerVector', 'mapTilerRasterXyz'].includes(type) && (
|
|
169
192
|
<>
|
|
170
193
|
<code className='es-bg-transparent es-p-0 es-text-3'>{'{z}/{x}/{y}'}</code>
|
|
171
|
-
{__(
|
|
194
|
+
{__(
|
|
195
|
+
"should be left as they are in the URL; they're needed for the map to work properly.",
|
|
196
|
+
'%g_textdomain%',
|
|
197
|
+
)}
|
|
172
198
|
<br />
|
|
173
199
|
<br />
|
|
174
200
|
</>
|
|
@@ -176,7 +202,8 @@ export const MapOptions = ({ attributes, setAttributes }) => {
|
|
|
176
202
|
{__('Example', '%g_textdomain%')}:
|
|
177
203
|
<br />
|
|
178
204
|
<span className='es-word-break-all'>
|
|
179
|
-
{['mapTilerRasterJson', 'vectorJson'].includes(type) &&
|
|
205
|
+
{['mapTilerRasterJson', 'vectorJson'].includes(type) &&
|
|
206
|
+
'https://api.maptiler.com/maps/{styleName}/tiles.json?key={apiKey}'}
|
|
180
207
|
|
|
181
208
|
{type === 'mapTilerVector' && 'https://api.maptiler.com/tiles/v3/{z}/{x}/{y}.pbf?key={apiKey}'}
|
|
182
209
|
|
|
@@ -188,9 +215,11 @@ export const MapOptions = ({ attributes, setAttributes }) => {
|
|
|
188
215
|
</>
|
|
189
216
|
)}
|
|
190
217
|
|
|
191
|
-
{type === 'mapBoxRaster' &&
|
|
218
|
+
{type === 'mapBoxRaster' &&
|
|
219
|
+
'https://api.mapbox.com/v4/{tilesetId}/{z}/{x}/{y}[@2x].{imageFormat}?acess_token={apiKey}'}
|
|
192
220
|
|
|
193
|
-
{type === 'mapTilerRasterXyz' &&
|
|
221
|
+
{type === 'mapTilerRasterXyz' &&
|
|
222
|
+
'https://api.maptiler.com/maps/{styleName}/{z}/{x}/{y}.png?key={apiKey}'}
|
|
194
223
|
</span>
|
|
195
224
|
</>
|
|
196
225
|
}
|