@eightshift/frontend-libs-tailwind 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ 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.2.0] - 2024-08-08
8
+ - Fixed default `perPage` param in `wpSearchRoute`.
9
+ - Updated image and file pickers with support for `hidden` prop and accepted types passthrough.
10
+ - Fixed some reported bugs in a couple of built-in blocks.
11
+ - Updated dependencies.
12
+
7
13
  ## [1.1.1] - 2024-07-11
8
14
  - Fixed default global manifest.
9
15
  - Removed erroneous styles.
@@ -22,11 +28,12 @@ This projects adheres to [Semantic Versioning](https://semver.org/) and [Keep a
22
28
  - Added `PickerPlaceholder` component.
23
29
  - Added option for dynamic parts and the `getTwDynamicPart` helper.
24
30
 
25
- ## [1.0.0] - 2024-06
31
+ ## [1.0.0] - 2024-06-17
26
32
  - Initial release.
27
33
 
28
34
  [Unreleased]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/master...HEAD
29
35
 
36
+ [1.2.0]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.1.1...1.2.0
30
37
  [1.1.1]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.1.0...1.1.1
31
38
  [1.1.0]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.0.0...1.1.0
32
39
  [1.0.0]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/0.0.1...1.0.0
@@ -0,0 +1 @@
1
+ @import './fonts.css';
@@ -27,8 +27,14 @@ $buttonContent = Helpers::checkAttr('buttonContent', $attributes, $manifest);
27
27
 
28
28
  $buttonAriaLabel = Helpers::checkAttr('buttonAriaLabel', $attributes, $manifest);
29
29
 
30
+ $buttonIconUse = Helpers::checkAttr('buttonIconUse', $attributes, $manifest);
31
+
30
32
  $buttonAttrs = [];
31
33
 
34
+ if (!$buttonIconUse && empty($buttonContent)) {
35
+ return;
36
+ }
37
+
32
38
  if (!empty($additionalAttributes)) {
33
39
  $buttonAttrs = $additionalAttributes;
34
40
  }
@@ -91,7 +91,7 @@
91
91
  },
92
92
  "tailwind": {
93
93
  "base": {
94
- "twClasses": "font-sans [&>a]:underline font-synthesis-none",
94
+ "twClasses": "font-sans [&_a]:underline font-synthesis-none",
95
95
  "twClassesEditor": "font-sans [&>a]:underline font-synthesis-none"
96
96
  },
97
97
  "options": {
@@ -34,7 +34,7 @@ export const ParagraphEditor = (attributes) => {
34
34
  onMerge={mergeBlocks}
35
35
  onReplace={onReplace}
36
36
  onRemove={onRemove}
37
- deleteEnter={true}
37
+ deleteEnter
38
38
  />
39
39
  );
40
40
  };
@@ -2,7 +2,7 @@ import domReady from '@wordpress/dom-ready';
2
2
  import manifest from '../manifest.json';
3
3
 
4
4
  domReady(async () => {
5
- const shareTargets = document.querySelectorAll(`.${manifest.componentJsClass}`);
5
+ const shareTargets = document.querySelectorAll(`.${manifest.componentJsClass}[data-mode='share']`);
6
6
 
7
7
  if (shareTargets.length < 1) {
8
8
  return;
@@ -22,9 +22,12 @@ $shareMode = Helpers::checkAttr('shareMode', $attributes, $manifest);
22
22
  $additionalClass = $attributes['additionalClass'] ?? '';
23
23
 
24
24
  ?>
25
- <div class="<?php echo esc_attr(Helpers::getTwPart('container', $manifest, $additionalClass)); ?>">
25
+ <div
26
+ class="<?php echo esc_attr(Helpers::getTwPart('container', $manifest, $additionalClass, $manifest['componentJsClass'])); ?>"
27
+ data-mode="<?php echo esc_attr($shareMode); ?>"
28
+ >
26
29
  <?php
27
- if ($shareMode) {
30
+ if ($shareMode === 'share') {
28
31
  foreach ($shareTargets as $networkName) {
29
32
  $shareUrl = $manifest['networks'][$networkName]['shareUrl'] ?? '';
30
33
  $shareUrl = str_replace('POST_TITLE', get_the_title(), $shareUrl);
@@ -32,7 +35,7 @@ $additionalClass = $attributes['additionalClass'] ?? '';
32
35
  $shareUrl = str_replace('POST_FEATURED_IMAGE', get_the_post_thumbnail_url(get_the_ID(), 'large'), $shareUrl);
33
36
  ?>
34
37
  <button
35
- class="<?php echo esc_attr(Helpers::getTwPart('icon', $manifest)); ?>"
38
+ class="<?php echo esc_attr(Helpers::getTwPart('icon', $manifest, "{$manifest['componentJsClass']}-link")); ?>"
36
39
  data-network="<?php echo esc_attr($networkName); ?>"
37
40
  data-share-url="<?php echo esc_url($shareUrl); ?>"
38
41
  data-page-title="<?php echo esc_attr(get_the_title()); ?>"
@@ -44,7 +47,7 @@ $additionalClass = $attributes['additionalClass'] ?? '';
44
47
  ?>
45
48
  </button>
46
49
  <?php }
47
- } else {
50
+ } elseif ($shareMode === 'links') {
48
51
  foreach ($shareTargets as $networkName) {
49
52
  ?>
50
53
  <a
@@ -37,7 +37,7 @@ export const VideoEditor = (attributes) => {
37
37
  [getAttrKey('videoMimeType', attributes, manifest)]: typeof mime === 'undefined' ? mime_type : mime,
38
38
  })
39
39
  }
40
- allowedTypes={['video/mp4', 'video/webm']}
40
+ allowedTypes={manifest.allowedTypes}
41
41
  kind='video'
42
42
  />
43
43
 
@@ -58,7 +58,7 @@ export const VideoOptions = (attributes) => {
58
58
  }
59
59
  fileId={videoId}
60
60
  fileName={videoUrl?.slice(videoUrl?.lastIndexOf('/') + 1)}
61
- allowedTypes={['video/mp4', 'video/webm']}
61
+ allowedTypes={manifest.allowedTypes}
62
62
  kind='video'
63
63
  />
64
64
 
@@ -112,5 +112,9 @@
112
112
  "twClasses": "aspect-video w-full rounded-xl border border-gray-800 bg-gradient-to-br from-gray-800 to-black shadow-md"
113
113
  }
114
114
  }
115
- }
115
+ },
116
+ "allowedTypes": [
117
+ "video/mp4",
118
+ "video/webm"
119
+ ]
116
120
  }
@@ -12,46 +12,57 @@
12
12
  ],
13
13
  "example": {
14
14
  "attributes": {
15
- "columnsColumnGapLarge": 30,
16
- "columnsRowGapLarge": 30
15
+ "columnsNumOfColumns": {
16
+ "_default": "2",
17
+ "_desktopFirst": true,
18
+ "max-sm": "1"
19
+ },
20
+ "wrapperBackground": "solid-gray-50",
21
+ "wrapperBorderRadius": "lg",
22
+ "wrapperPaddingTop": {
23
+ "_default": "md",
24
+ "_desktopFirst": true
25
+ },
26
+ "wrapperPaddingBottom": {
27
+ "_default": "md",
28
+ "_desktopFirst": true
29
+ }
17
30
  },
18
31
  "innerBlocks": [
19
32
  {
20
33
  "name": "eightshift-boilerplate/column",
21
34
  "attributes": {
22
- "columnWidthLarge": 4
35
+ "columnOffset": {
36
+ "_default": "1",
37
+ "_desktopFirst": true,
38
+ "max-sm": "1"
39
+ },
40
+ "columnWidth": {
41
+ "_default": "1",
42
+ "_desktopFirst": true,
43
+ "max-sm": "1"
44
+ },
45
+ "columnVerticalAlign": {
46
+ "_default": "center",
47
+ "_desktopFirst": true
48
+ }
23
49
  },
24
50
  "innerBlocks": [
25
51
  {
26
- "name": "eightshift-boilerplate/card",
52
+ "name": "eightshift-boilerplate/heading",
27
53
  "attributes": {
28
- "cardCardImageUrl": "https://picsum.photos/400/400",
29
- "cardCardIntroContent": "Intro",
30
- "cardCardIntroSize": "small",
31
- "cardCardIntroColor": "light",
32
- "cardCardHeadingContent": "Heading",
33
- "cardCardParagraphContent": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam aliquam est id semper aliquet.",
34
- "cardCardButtonUse": false
54
+ "wrapperNoWidthControls": true,
55
+ "wrapperWidth": "none",
56
+ "headingHeadingContent": "Lorem ipsum",
57
+ "headingHeadingSize": "xl"
35
58
  }
36
- }
37
- ]
38
- },
39
- {
40
- "name": "eightshift-boilerplate/column",
41
- "attributes": {
42
- "columnWidthLarge": 4
43
- },
44
- "innerBlocks": [
59
+ },
45
60
  {
46
- "name": "eightshift-boilerplate/card",
61
+ "name": "eightshift-boilerplate/paragraph",
47
62
  "attributes": {
48
- "cardCardImageUrl": "https://picsum.photos/400/400",
49
- "cardCardIntroContent": "Intro",
50
- "cardCardIntroSize": "small",
51
- "cardCardIntroColor": "light",
52
- "cardCardHeadingContent": "Heading",
53
- "cardCardParagraphContent": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam aliquam est id semper aliquet.",
54
- "cardCardButtonUse": false
63
+ "wrapperNoWidthControls": true,
64
+ "wrapperWidth": "none",
65
+ "paragraphParagraphContent": "Dolor sit amet"
55
66
  }
56
67
  }
57
68
  ]
@@ -59,19 +70,34 @@
59
70
  {
60
71
  "name": "eightshift-boilerplate/column",
61
72
  "attributes": {
62
- "columnWidthLarge": 4
73
+ "columnOffset": {
74
+ "_default": "2",
75
+ "_desktopFirst": true,
76
+ "max-sm": "1"
77
+ },
78
+ "columnWidth": {
79
+ "_default": "1",
80
+ "_desktopFirst": true,
81
+ "max-sm": "1"
82
+ },
83
+ "columnHorizontalAlign": {
84
+ "_default": "end",
85
+ "_desktopFirst": true
86
+ }
63
87
  },
64
88
  "innerBlocks": [
65
89
  {
66
- "name": "eightshift-boilerplate/card",
90
+ "name": "eightshift-boilerplate/image",
67
91
  "attributes": {
68
- "cardCardImageUrl": "https://picsum.photos/400/400",
69
- "cardCardIntroContent": "Intro",
70
- "cardCardIntroSize": "small",
71
- "cardCardIntroColor": "light",
72
- "cardCardHeadingContent": "Heading",
73
- "cardCardParagraphContent": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam aliquam est id semper aliquet.",
74
- "cardCardButtonUse": false
92
+ "wrapperNoWidthControls": true,
93
+ "wrapperWidth": "none",
94
+ "imageImageData": {
95
+ "_desktopFirst": false,
96
+ "_default": {
97
+ "id": 245,
98
+ "url": "https://picsum.photos/id/17/400/400"
99
+ }
100
+ }
75
101
  }
76
102
  }
77
103
  ]
@@ -21,85 +21,13 @@
21
21
  "imageAlign": {
22
22
  "type": "string",
23
23
  "default": "center center"
24
+ },
25
+ "wrapperDisabledOptions": {
26
+ "type": "string",
27
+ "default": "roundedCorners"
24
28
  }
25
29
  },
26
30
  "components": {
27
31
  "image": "image"
28
- },
29
- "variables": {
30
- "imageAlign": {
31
- "top left": [
32
- {
33
- "variable": {
34
- "block-image-align-horizontal": "flex-start",
35
- "block-image-align-vertical": "flex-start"
36
- }
37
- }
38
- ],
39
- "top center": [
40
- {
41
- "variable": {
42
- "block-image-align-horizontal": "center",
43
- "block-image-align-vertical": "flex-start"
44
- }
45
- }
46
- ],
47
- "top right": [
48
- {
49
- "variable": {
50
- "block-image-align-horizontal": "flex-end",
51
- "block-image-align-vertical": "flex-start"
52
- }
53
- }
54
- ],
55
- "center left": [
56
- {
57
- "variable": {
58
- "block-image-align-horizontal": "flex-start",
59
- "block-image-align-vertical": "center"
60
- }
61
- }
62
- ],
63
- "center center": [
64
- {
65
- "variable": {
66
- "block-image-align-horizontal": "center",
67
- "block-image-align-vertical": "center"
68
- }
69
- }
70
- ],
71
- "center right": [
72
- {
73
- "variable": {
74
- "block-image-align-horizontal": "flex-end",
75
- "block-image-align-vertical": "center"
76
- }
77
- }
78
- ],
79
- "bottom left": [
80
- {
81
- "variable": {
82
- "block-image-align-horizontal": "flex-start",
83
- "block-image-align-vertical": "flex-end"
84
- }
85
- }
86
- ],
87
- "bottom center": [
88
- {
89
- "variable": {
90
- "block-image-align-horizontal": "center",
91
- "block-image-align-vertical": "flex-end"
92
- }
93
- }
94
- ],
95
- "bottom right": [
96
- {
97
- "variable": {
98
- "block-image-align-horizontal": "flex-end",
99
- "block-image-align-vertical": "flex-end"
100
- }
101
- }
102
- ]
103
- }
104
32
  }
105
33
  }
@@ -61,9 +61,11 @@ $logoAlt = get_post_meta($siteFooterLogoId, '_wp_attachment_image_alt', true) ??
61
61
  </div>
62
62
 
63
63
  <div class="<?php echo esc_attr(Helpers::getTwPart('bottomContainer', $manifest)); ?>">
64
- <span class="<?php echo esc_attr(Helpers::getTwPart('copyright', $manifest)); ?>">
65
- &copy; <?php echo esc_attr($siteFooterCopyright); ?>
66
- </span>
64
+ <?php if (!empty($siteFooterCopyright)) { ?>
65
+ <span class="<?php echo esc_attr(Helpers::getTwPart('copyright', $manifest)); ?>">
66
+ &copy; <?php echo esc_attr($siteFooterCopyright); ?>
67
+ </span>
68
+ <?php } ?>
67
69
 
68
70
  <?php
69
71
  echo Helpers::render('share', Helpers::props('share', $attributes));
@@ -25,81 +25,5 @@
25
25
  "type": "string",
26
26
  "default": "center center"
27
27
  }
28
- },
29
- "variables": {
30
- "videoAlign": {
31
- "top left": [
32
- {
33
- "variable": {
34
- "block-video-align-horizontal": "flex-start",
35
- "block-video-align-vertical": "flex-start"
36
- }
37
- }
38
- ],
39
- "top center": [
40
- {
41
- "variable": {
42
- "block-video-align-horizontal": "center",
43
- "block-video-align-vertical": "flex-start"
44
- }
45
- }
46
- ],
47
- "top right": [
48
- {
49
- "variable": {
50
- "block-video-align-horizontal": "flex-end",
51
- "block-video-align-vertical": "flex-start"
52
- }
53
- }
54
- ],
55
- "center left": [
56
- {
57
- "variable": {
58
- "block-video-align-horizontal": "flex-start",
59
- "block-video-align-vertical": "center"
60
- }
61
- }
62
- ],
63
- "center center": [
64
- {
65
- "variable": {
66
- "block-video-align-horizontal": "center",
67
- "block-video-align-vertical": "center"
68
- }
69
- }
70
- ],
71
- "center right": [
72
- {
73
- "variable": {
74
- "block-video-align-horizontal": "flex-end",
75
- "block-video-align-vertical": "center"
76
- }
77
- }
78
- ],
79
- "bottom left": [
80
- {
81
- "variable": {
82
- "block-video-align-horizontal": "flex-start",
83
- "block-video-align-vertical": "flex-end"
84
- }
85
- }
86
- ],
87
- "bottom center": [
88
- {
89
- "variable": {
90
- "block-video-align-horizontal": "center",
91
- "block-video-align-vertical": "flex-end"
92
- }
93
- }
94
- ],
95
- "bottom right": [
96
- {
97
- "variable": {
98
- "block-video-align-horizontal": "flex-end",
99
- "block-video-align-vertical": "flex-end"
100
- }
101
- }
102
- ]
103
- }
104
28
  }
105
29
  }
@@ -1,5 +1,5 @@
1
1
  import { __ } from '@wordpress/i18n';
2
- import { checkAttr, getAttrKey, getOption } from '@eightshift/frontend-libs-tailwind/scripts';
2
+ import { checkAttr, getAttrKey, getHiddenOptions, getOption } from '@eightshift/frontend-libs-tailwind/scripts';
3
3
  import { BaseControl, ButtonGroup, ColorPicker, ContainerPanel, OptionSelect, Spacer, Responsive, InputField } from '@eightshift/ui-components';
4
4
  import { icons } from '@eightshift/ui-components/icons';
5
5
  import { clsx } from '@eightshift/ui-components/utilities';
@@ -30,7 +30,11 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
30
30
 
31
31
  const wrapperId = checkAttr('wrapperId', attributes, manifest);
32
32
 
33
- if (wrapperNoControls) {
33
+ const wrapperDisabledOptions = checkAttr('wrapperDisabledOptions', attributes, manifest);
34
+
35
+ const hiddenOptions = getHiddenOptions(wrapperDisabledOptions);
36
+
37
+ if (wrapperNoControls || wrapperDisabledOptions === 'all') {
34
38
  return null;
35
39
  }
36
40
 
@@ -79,7 +83,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
79
83
  icon={icons.containerWidth}
80
84
  label={__('Width', '%g_textdomain%')}
81
85
  options={getOption('wrapperContentWidth', attributes, manifest)}
82
- hidden={wrapperNoWidthControls}
86
+ hidden={wrapperNoWidthControls || hiddenOptions?.width}
83
87
  noModeSelect
84
88
  inline
85
89
  {...responsiveData}
@@ -97,6 +101,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
97
101
  <BaseControl
98
102
  icon={icons.backgroundType}
99
103
  label={__('Background', '%g_textdomain%')}
104
+ hidden={hiddenOptions?.background}
100
105
  inline
101
106
  >
102
107
  <ButtonGroup>
@@ -114,6 +119,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
114
119
  }}
115
120
  aria-label={__('Background type', '%g_textdomain%')}
116
121
  type='menu'
122
+ hidden={hiddenOptions?.backgroundType}
117
123
  noItemIcon
118
124
  />
119
125
 
@@ -123,6 +129,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
123
129
  onChange={(value) => setAttributes({ [getAttrKey('wrapperBackground', attributes, manifest)]: `solid-${value}` })}
124
130
  value={wrapperBackground?.replace('solid-', '')}
125
131
  aria-label={__('Background color', '%g_textdomain%')}
132
+ hidden={hiddenOptions?.backgroundType}
126
133
  />
127
134
  )}
128
135
  {backgroundType === 'gradient' && (
@@ -152,6 +159,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
152
159
  ),
153
160
  }}
154
161
  aria-label={__('Gradient style', '%g_textdomain%')}
162
+ hidden={hiddenOptions?.backgroundType}
155
163
  noTriggerLabel
156
164
  type='menu'
157
165
  />
@@ -163,6 +171,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
163
171
  triggerIcon: <div className={rotationClassName[wrapperGradientDirection]}>{icons.arrowUpCircle}</div>,
164
172
  }}
165
173
  aria-label={__('Gradient angle', '%g_textdomain%')}
174
+ hidden={hiddenOptions?.backgroundType}
166
175
  noTriggerLabel
167
176
  type='menu'
168
177
  />
@@ -179,6 +188,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
179
188
  options={getOption('wrapperBorderRadius', attributes, manifest)}
180
189
  aria-label={__('Rounded corners', '%g_textdomain%')}
181
190
  type='menu'
191
+ hidden={hiddenOptions?.roundedCorners}
182
192
  inline
183
193
  />
184
194
 
@@ -199,6 +209,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
199
209
  icon={icons.spacingTop}
200
210
  label={__('Top margin', '%g_textdomain%')}
201
211
  options={getOption('wrapperSpacing', attributes, manifest)}
212
+ hidden={hiddenOptions?.marginTop}
202
213
  noModeSelect
203
214
  inline
204
215
  {...responsiveData}
@@ -223,6 +234,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
223
234
  icon={icons.spacingBottom}
224
235
  label={__('Bottom margin', '%g_textdomain%')}
225
236
  options={getOption('wrapperSpacing', attributes, manifest)}
237
+ hidden={hiddenOptions?.marginBottom}
226
238
  noModeSelect
227
239
  inline
228
240
  {...responsiveData}
@@ -249,6 +261,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
249
261
  icon={icons.spacingTopIn}
250
262
  label={__('Top padding', '%g_textdomain%')}
251
263
  options={getOption('wrapperSpacing', attributes, manifest)}
264
+ hidden={hiddenOptions?.paddingTop}
252
265
  noModeSelect
253
266
  inline
254
267
  {...responsiveData}
@@ -273,6 +286,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
273
286
  icon={icons.spacingBottomIn}
274
287
  label={__('Bottom padding', '%g_textdomain%')}
275
288
  options={getOption('wrapperSpacing', attributes, manifest)}
289
+ hidden={hiddenOptions?.paddingBottom}
276
290
  noModeSelect
277
291
  inline
278
292
  {...responsiveData}
@@ -304,6 +318,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
304
318
  icon={icons.visibility}
305
319
  label={__('Visibility', '%g_textdomain%')}
306
320
  options={getOption('wrapperHide', attributes, manifest)}
321
+ hidden={hiddenOptions?.hide}
307
322
  noModeSelect
308
323
  inline
309
324
  {...responsiveData}
@@ -327,6 +342,7 @@ export const WrapperOptions = ({ attributes, setAttributes }) => {
327
342
  value={wrapperId}
328
343
  onChange={(value) => setAttributes({ [getAttrKey('wrapperId', attributes, manifest)]: value })}
329
344
  className='es-uic-font-mono'
345
+ hidden={hiddenOptions?.id}
330
346
  />
331
347
  </ContainerPanel>
332
348
  );
@@ -96,6 +96,9 @@
96
96
  },
97
97
  "wrapperId": {
98
98
  "type": "string"
99
+ },
100
+ "wrapperDisabledOptions": {
101
+ "type": "string"
99
102
  }
100
103
  },
101
104
  "options": {
@@ -350,7 +353,7 @@
350
353
  },
351
354
  "wrapperGradientDirection": {
352
355
  "twClasses": {
353
- "to-t": "bg-gradient-to-r",
356
+ "to-t": "bg-gradient-to-t",
354
357
  "to-tr": "bg-gradient-to-tr",
355
358
  "to-r": "bg-gradient-to-r",
356
359
  "to-br": "bg-gradient-to-br",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eightshift/frontend-libs-tailwind",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "A framework for creating modern Gutenberg themes with styling provided by Tailwind CSS.",
5
5
  "author": {
6
6
  "name": "Eightshift team",
@@ -34,48 +34,48 @@
34
34
  "homepage": "https://github.com/infinum/eightshift-frontend-libs-tailwind#readme",
35
35
  "license": "MIT",
36
36
  "dependencies": {
37
- "@eightshift/ui-components": "^1.2.2",
38
- "@stylistic/eslint-plugin-js": "^2.3.0",
39
- "@stylistic/stylelint-plugin": "^2.1.2",
40
- "@swc/core": "^1.6.13",
41
- "@wordpress/api-fetch": "^7.2.0",
42
- "@wordpress/block-editor": "^13.2.0",
37
+ "@eightshift/ui-components": "^1.4.6",
38
+ "@stylistic/eslint-plugin-js": "^2.6.1",
39
+ "@stylistic/stylelint-plugin": "^3.0.0",
40
+ "@swc/core": "^1.7.6",
41
+ "@wordpress/api-fetch": "^7.5.0",
42
+ "@wordpress/block-editor": "^13.4.0",
43
43
  "@wordpress/dependency-extraction-webpack-plugin": "^5.9.0",
44
- "@wordpress/dom-ready": "^4.2.0",
45
- "@wordpress/server-side-render": "^5.2.0",
46
- "browserslist": "^4.23.1",
44
+ "@wordpress/dom-ready": "^4.5.0",
45
+ "@wordpress/server-side-render": "^5.5.0",
46
+ "browserslist": "^4.23.3",
47
47
  "css-loader": "^7.1.2",
48
48
  "css-minimizer-webpack-plugin": "^7.0.0",
49
- "eslint": "^9.6.0",
49
+ "eslint": "^9.8.0",
50
50
  "eslint-config-prettier": "^9.1.0",
51
- "eslint-plugin-prettier": "^5.1.3",
51
+ "eslint-plugin-prettier": "^5.2.1",
52
52
  "file-loader": "^6.2.0",
53
- "globals": "^15.8.0",
54
- "husky": "^9.0.11",
55
- "lightningcss": "^1.25.1",
53
+ "globals": "^15.9.0",
54
+ "husky": "^9.1.4",
55
+ "lightningcss": "^1.26.0",
56
56
  "mini-css-extract-plugin": "^2.9.0",
57
- "postcss": "^8.4.39",
57
+ "postcss": "^8.4.41",
58
58
  "postcss-loader": "^8.1.1",
59
- "prettier": "^3.3.2",
59
+ "prettier": "^3.3.3",
60
60
  "prettier-plugin-tailwindcss": "^0.6.5",
61
61
  "sonner": "^1.5.0",
62
- "stylelint": "^16.6.1",
62
+ "stylelint": "^16.8.1",
63
63
  "stylelint-config-standard": "^36.0.1",
64
64
  "swc-loader": "^0.2.6",
65
65
  "terser-webpack-plugin": "^5.3.10",
66
- "webpack": "^5.92.1",
66
+ "webpack": "^5.93.0",
67
67
  "webpack-cli": "^5.1.4",
68
68
  "webpack-manifest-plugin": "^5.0.0",
69
69
  "webpack-merge": "^6.0.1"
70
70
  },
71
71
  "devDependencies": {
72
- "embla-carousel": "^8.1.6",
73
- "fluid-tailwind": "^1.0.2",
74
- "lint-staged": "^15.2.7",
72
+ "embla-carousel": "^8.1.8",
73
+ "fluid-tailwind": "^1.0.3",
74
+ "lint-staged": "^15.2.8",
75
75
  "micromodal": "^0.4.10",
76
- "ol": "^9.2.4",
76
+ "ol": "^10.0.0",
77
77
  "ol-mapbox-style": "^12.3.4",
78
- "tailwindcss": "^3.4.4",
78
+ "tailwindcss": "^3.4.8",
79
79
  "tailwindcss-animate": "^1.0.7"
80
80
  },
81
81
  "sideEffects": false,
@@ -9,18 +9,18 @@ import { icons } from '@eightshift/ui-components/icons';
9
9
  *
10
10
  * @component
11
11
  * @param {Object} props - Component props.
12
- * @property {ManageFileButtonType} [props.type] - The type of the button (browse, upload, replace).
13
- * @property {Function} props.onChange - Function that handles the change event.
14
- * @property {string} [props.currentId] - ID of the currently selected item. Used for the 'replace' type, to mark the currently selected item.
15
- * @property {boolean} [props.compact] - Whether the button is compact (icon-only).
16
- * @property {string[]} props.allowedTypes - Determines types of files which are allowed to be uploaded.
17
- * @property {ManageFileButtonKind} [props.kind] - The kind of file to manage. Controls labels and icons on the buttons.
18
- * @property {Object} [props.labels] - Custom UI labels for the buttons. Applies only if `kind` is set to `custom`.
12
+ * @param {ManageFileButtonType} [props.type] - The type of the button (browse, upload, replace).
13
+ * @param {Function} props.onChange - Function that handles the change event.
14
+ * @param {string} [props.currentId] - ID of the currently selected item. Used for the 'replace' type, to mark the currently selected item.
15
+ * @param {boolean} [props.compact] - Whether the button is compact (icon-only).
16
+ * @param {string[]} props.allowedTypes - Determines types of files which are allowed to be uploaded.
17
+ * @param {ManageFileButtonKind} [props.kind] - The kind of file to manage. Controls labels and icons on the buttons.
18
+ * @param {Object} [props.labels] - Custom UI labels for the buttons. Applies only if `kind` is set to `custom`.
19
19
  *
20
20
  * @returns {JSX.Element} The ManageFileButton component.
21
21
  *
22
22
  * @typedef {'browse' | 'upload' | 'replace'} ManageFileButtonType
23
- * @typedef {'file' | 'image' | 'video' | 'subtitle' | 'geoJson' | 'custom'} ManageFileButtonKind
23
+ * @typedef {'file' | 'image' | 'video' | 'subtitle' | 'geoJson' | 'lottie' | 'custom'} ManageFileButtonKind
24
24
  *
25
25
  * @example
26
26
  * <ManageFileButton />
@@ -111,6 +111,18 @@ export const ManageFileButton = (props) => {
111
111
  replace: __('Select a new GeoJSON file', 'eightshift-frontend-libs-tailwind'),
112
112
  },
113
113
  },
114
+ lottie: {
115
+ buttonTooltip: {
116
+ browse: __('Select a Lottie animation', 'eightshift-frontend-libs-tailwind'),
117
+ upload: __('Upload a Lottie animation', 'eightshift-frontend-libs-tailwind'),
118
+ replace: __('Replace Lottie animation', 'eightshift-frontend-libs-tailwind'),
119
+ },
120
+ modalTitle: {
121
+ browse: __('Select a Lottie animation', 'eightshift-frontend-libs-tailwind'),
122
+ upload: __('Upload a Lottie animation', 'eightshift-frontend-libs-tailwind'),
123
+ replace: __('Select a new Lottie animation', 'eightshift-frontend-libs-tailwind'),
124
+ },
125
+ },
114
126
  custom: {
115
127
  buttonTooltip: labels?.buttonTooltip,
116
128
  buttonLabel: labels?.buttonLabel,
@@ -151,18 +163,18 @@ export const ManageFileButton = (props) => {
151
163
  *
152
164
  * @component
153
165
  * @param {Object} props - Component props.
154
- * @property {Function} props.onChange - The function that handles the change event.
155
- * @property {string} props.fileId - ID of the currently selected file. Used to mark the currently selected item when replacing the file.
156
- * @property {string} props.fileName - URL of the currently selected image.
157
- * @property {boolean} [props.noDelete] - If `true`, the delete button will be hidden.
158
- * @property {boolean} [props.noUpload] - If `true`, the upload button will be hidden.
159
- * @property {string[]} props.allowedTypes - Determines types of files which are allowed to be uploaded.
160
- * @property {FileKind} [props.kind] - The kind of file to manage.
161
- * @property {Object} [props.labels] - Custom UI labels for the buttons. Applies only if `kind` is set to `custom`.
166
+ * @param {Function} props.onChange - The function that handles the change event.
167
+ * @param {string} props.fileId - ID of the currently selected file. Used to mark the currently selected item when replacing the file.
168
+ * @param {string} props.fileName - URL of the currently selected image.
169
+ * @param {boolean} [props.noDelete] - If `true`, the delete button will be hidden.
170
+ * @param {boolean} [props.noUpload] - If `true`, the upload button will be hidden.
171
+ * @param {string[]} props.allowedTypes - Determines types of files which are allowed to be uploaded.
172
+ * @param {FileKind} [props.kind] - The kind of file to manage.
173
+ * @param {Object} [props.labels] - Custom UI labels for the buttons. Applies only if `kind` is set to `custom`.
162
174
  *
163
175
  * @returns {JSX.Element} The FileSelector component.
164
176
  *
165
- * @typedef {'file' | 'image' | 'video' | 'subtitle' | 'geoJson' | 'custom'} FileKind
177
+ * @typedef {'file' | 'image' | 'video' | 'subtitle' | 'geoJson' | 'lottie' | 'custom'} FileKind
166
178
  *
167
179
  * @example
168
180
  * <FileSelector
@@ -189,6 +201,7 @@ export const FileSelector = (props) => {
189
201
  video: __('Remove video', 'eightshift-frontend-libs-tailwind'),
190
202
  subtitle: __('Remove subtitle file', 'eightshift-frontend-libs-tailwind'),
191
203
  geoJson: __('Remove GeoJSON file', 'eightshift-frontend-libs-tailwind'),
204
+ lottie: __('Remove Lottie animation', 'eightshift-frontend-libs-tailwind'),
192
205
  custom: labels?.removeTooltip,
193
206
  };
194
207
 
@@ -197,6 +210,7 @@ export const FileSelector = (props) => {
197
210
  video: icons.videoFile,
198
211
  subtitle: icons.closedCaptions,
199
212
  geoJson: icons.fileMetadata,
213
+ lottie: icons.animationFile,
200
214
  custom: labels?.removeIcon,
201
215
  };
202
216
 
@@ -2,14 +2,13 @@ import React from 'react';
2
2
  import { __ } from '@wordpress/i18n';
3
3
  import { Button, HStack, ImagePlaceholder } from '@eightshift/ui-components';
4
4
  import { icons } from '@eightshift/ui-components/icons';
5
- import { ManageFileButton } from '@eightshift/frontend-libs-tailwind/scripts/components/file-picker';
5
+ import { ManageFileButton } from './file-picker';
6
6
 
7
7
  const MediaButton = (props) => {
8
8
  return (
9
9
  <ManageFileButton
10
10
  {...props}
11
11
  kind='image'
12
- allowedTypes={['image']}
13
12
  />
14
13
  );
15
14
  };
@@ -19,13 +18,16 @@ const MediaButton = (props) => {
19
18
  *
20
19
  * @component
21
20
  * @param {Object} props - Component props.
22
- * @property {Function} props.onChange - The function that handles the change event.
23
- * @property {string} props.imageId - ID of the currently selected image. Used to mark the currently selected item when replacing the image.
24
- * @property {string} props.imageAlt - Alt text of the currently selected image.
25
- * @property {string} props.imageUrl - URL of the currently selected image.
26
- * @property {boolean} [props.noDelete] - If `true`, the delete button will be hidden.
27
- * @property {boolean} [props.noUpload] - If `true`, the upload button will be hidden.
21
+ * @param {Function} props.onChange - The function that handles the change event.
22
+ * @param {string} props.imageId - ID of the currently selected image. Used to mark the currently selected item when replacing the image.
23
+ * @param {string} props.imageAlt - Alt text of the currently selected image.
24
+ * @param {string} props.imageUrl - URL of the currently selected image.
25
+ * @param {boolean} [props.noDelete] - If `true`, the delete button will be hidden.
26
+ * @param {boolean} [props.noUpload] - If `true`, the upload button will be hidden.
28
27
  * @param {ImagePlaceholderImageMode} [props.imageMode='cover'] - Determines inner image display mode.
28
+ * @param {boolean} [props.hidden] - If `true`, the component will be hidden.
29
+ * @param {string[]} [props.allowedTypes=['image']] - Determines types of files which are allowed to be uploaded.
30
+ * @param {string} [props.className] - Classes to add to the button wrapper.
29
31
  *
30
32
  * @returns {JSX.Element} The MediaPicker component.
31
33
  *
@@ -41,10 +43,17 @@ const MediaButton = (props) => {
41
43
  *
42
44
  */
43
45
  export const MediaPicker = (props) => {
44
- const { onChange, imageId, imageAlt, imageUrl, noDelete, noUpload, imageMode } = props;
46
+ const { onChange, imageId, imageAlt, imageUrl, noDelete, noUpload, imageMode, hidden, allowedTypes = ['image'], className } = props;
47
+
48
+ if (hidden) {
49
+ return null;
50
+ }
45
51
 
46
52
  return (
47
- <HStack noWrap>
53
+ <HStack
54
+ className={className}
55
+ noWrap
56
+ >
48
57
  <ImagePlaceholder
49
58
  url={imageUrl}
50
59
  alt={imageAlt}
@@ -53,11 +62,15 @@ export const MediaPicker = (props) => {
53
62
 
54
63
  {!imageUrl && (
55
64
  <>
56
- <MediaButton onChange={onChange} />
65
+ <MediaButton
66
+ onChange={onChange}
67
+ allowedTypes={allowedTypes}
68
+ />
57
69
  {!noUpload && (
58
70
  <MediaButton
59
71
  onChange={onChange}
60
72
  type='upload'
73
+ allowedTypes={allowedTypes}
61
74
  compact
62
75
  />
63
76
  )}
@@ -70,6 +83,7 @@ export const MediaPicker = (props) => {
70
83
  type='replace'
71
84
  onChange={onChange}
72
85
  imageId={imageId}
86
+ allowedTypes={allowedTypes}
73
87
  />
74
88
  {!noDelete && (
75
89
  <Button
@@ -98,10 +98,10 @@ export const wpSearchRoute = fetchFromWpRest('search', {
98
98
  processId: ({ url }) => url,
99
99
  labelProp: 'title',
100
100
  processMetadata: ({ type, subtype }) => ({ type, subtype }),
101
+ perPage: 5,
101
102
  additionalParam: {
102
103
  type: 'post',
103
104
  _locale: 'user',
104
- per_page: 5,
105
105
  },
106
106
  noCache: true,
107
107
  searchColumns: 'post_title',