@eightshift/frontend-libs-tailwind 1.4.4 → 1.4.6

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
@@ -6,6 +6,23 @@ This projects adheres to [Semantic Versioning](https://semver.org/) and [Keep a
6
6
 
7
7
  ---
8
8
 
9
+ ## [1.4.6]
10
+
11
+ ### Changed
12
+ - Tweaked webpack config to properly include font files from `@eightshfit` packages from `node_modules`.
13
+ - Added a new `buildWpRestUrl` helper for easily fetching WP REST URLs. (Similar to `fetchFromWpRest`, but allows you control over how you fetch).
14
+ - Updated dependencies.
15
+
16
+ ## [1.4.5]
17
+
18
+ ### Changed
19
+
20
+ - `BlockInserter` is now only visible when the block it's assigned to is selected. This behavior can be changed by setting `alwaysVisible`.
21
+
22
+ ### Fixed
23
+
24
+ - Image responsive breakpoints render order in the frontend.
25
+
9
26
  ## [1.4.4]
10
27
 
11
28
  ### Added
@@ -142,6 +159,8 @@ This projects adheres to [Semantic Versioning](https://semver.org/) and [Keep a
142
159
  - Initial release.
143
160
 
144
161
  [Unreleased]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/master...HEAD
162
+ [1.4.6]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.4.5...1.4.6
163
+ [1.4.5]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.4.4...1.4.5
145
164
  [1.4.4]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.4.3...1.4.4
146
165
  [1.4.3]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.4.2...1.4.3
147
166
  [1.4.2]: https://github.com/infinum/eightshift-frontend-libs-tailwind/compare/1.4.1...1.4.2
@@ -22,10 +22,10 @@ if (!$imageUse || empty($imageData['_default']['url'])) {
22
22
 
23
23
  $imageAlt = get_post_meta($imageData['_default']['id'], '_wp_attachment_image_alt', true) ?? '';
24
24
 
25
- $isMobileFirst = $imageData['_desktopFirst'] ?? false;
25
+ $isDesktopFirst = $imageData['_desktopFirst'] ?? false;
26
26
 
27
27
  $breakpointData = Helpers::getSettingsGlobalVariablesBreakpoints();
28
- $breakpoints = Helpers::getTwBreakpoints($isMobileFirst);
28
+ $breakpoints = Helpers::getTwBreakpoints();
29
29
  ?>
30
30
 
31
31
  <picture
@@ -45,12 +45,12 @@ $breakpoints = Helpers::getTwBreakpoints($isMobileFirst);
45
45
  continue;
46
46
  }
47
47
 
48
- $breakpointWidth = $breakpointData[str_replace('max-', '', $breakpoint)];
48
+ $breakpointWidth = $breakpointData[$breakpoint];
49
49
 
50
- $widthMode = $isMobileFirst ? 'min-width' : 'max-width';
50
+ $widthMode = $isDesktopFirst ? 'max-width' : 'min-width';
51
51
 
52
52
  // phpcs:ignore Eightshift.Security.HelpersEscape.OutputNotEscaped
53
- echo '<source srcset="' . esc_url($value) . '" media="(' . $widthMode . ': ' . $breakpointWidth . 'rem)" />';
53
+ echo '<source srcset="' . esc_url($value) . '" media="(' . $widthMode . ': ' . $breakpointWidth . 'em)" />';
54
54
  ?>
55
55
  <?php } ?>
56
56
 
@@ -60,3 +60,4 @@ $breakpoints = Helpers::getTwBreakpoints($isMobileFirst);
60
60
  class="<?php echo esc_attr(Helpers::tailwindClasses('base', $attributes, $manifest, $additionalClass['image'] ?? $additionalClass)); ?>"
61
61
  />
62
62
  </picture>
63
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eightshift/frontend-libs-tailwind",
3
- "version": "1.4.4",
3
+ "version": "1.4.6",
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,31 +34,31 @@
34
34
  "homepage": "https://github.com/infinum/eightshift-frontend-libs-tailwind#readme",
35
35
  "license": "MIT",
36
36
  "dependencies": {
37
- "@eightshift/ui-components": "^1.7.0",
38
- "@stylistic/eslint-plugin-js": "^2.10.1",
37
+ "@eightshift/ui-components": "^1.8.0",
38
+ "@stylistic/eslint-plugin-js": "^2.11.0",
39
39
  "@stylistic/stylelint-plugin": "^3.1.1",
40
- "@swc/core": "^1.8.0",
41
- "@wordpress/api-fetch": "^7.11.0",
42
- "@wordpress/block-editor": "^14.6.0",
40
+ "@swc/core": "^1.9.3",
41
+ "@wordpress/api-fetch": "^7.13.0",
42
+ "@wordpress/block-editor": "^14.8.0",
43
43
  "@wordpress/dependency-extraction-webpack-plugin": "^5.9.0",
44
- "@wordpress/dom-ready": "^4.11.0",
45
- "@wordpress/server-side-render": "^5.11.0",
44
+ "@wordpress/dom-ready": "^4.13.0",
45
+ "@wordpress/server-side-render": "^5.13.0",
46
46
  "browserslist": "^4.24.2",
47
47
  "css-loader": "^7.1.2",
48
48
  "css-minimizer-webpack-plugin": "^7.0.0",
49
- "eslint": "^9.14.0",
49
+ "eslint": "^9.15.0",
50
50
  "eslint-config-prettier": "^9.1.0",
51
51
  "eslint-plugin-prettier": "^5.2.1",
52
52
  "globals": "^15.12.0",
53
- "husky": "^9.1.6",
54
- "lightningcss": "^1.28.1",
53
+ "husky": "^9.1.7",
54
+ "lightningcss": "^1.28.2",
55
55
  "mini-css-extract-plugin": "^2.9.2",
56
- "postcss": "^8.4.47",
56
+ "postcss": "^8.4.49",
57
57
  "postcss-loader": "^8.1.1",
58
- "prettier": "^3.3.3",
59
- "prettier-plugin-tailwindcss": "^0.6.8",
58
+ "prettier": "^3.4.1",
59
+ "prettier-plugin-tailwindcss": "^0.6.9",
60
60
  "sonner": "^1.7.0",
61
- "stylelint": "^16.10.0",
61
+ "stylelint": "^16.11.0",
62
62
  "stylelint-config-standard": "^36.0.1",
63
63
  "swc-loader": "^0.2.6",
64
64
  "terser-webpack-plugin": "^5.3.10",
@@ -68,13 +68,13 @@
68
68
  "webpack-merge": "^6.0.1"
69
69
  },
70
70
  "devDependencies": {
71
- "embla-carousel": "^8.3.1",
72
- "fluid-tailwind": "^1.0.3",
71
+ "embla-carousel": "^8.5.1",
72
+ "fluid-tailwind": "^1.0.4",
73
73
  "lint-staged": "^15.2.10",
74
74
  "micromodal": "^0.4.10",
75
75
  "ol": "^10.2.1",
76
76
  "ol-mapbox-style": "^12.3.5",
77
- "tailwindcss": "^3.4.14",
77
+ "tailwindcss": "^3.4.15",
78
78
  "tailwindcss-animate": "^1.0.7"
79
79
  },
80
80
  "sideEffects": false,
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { __, sprintf } from '@wordpress/i18n';
3
3
  import { Inserter } from '@wordpress/block-editor';
4
+ import { useSuspenseSelect } from '@wordpress/data';
4
5
  import { Button } from '@eightshift/ui-components';
5
6
  import { icons } from '@eightshift/ui-components/icons';
6
7
  import { clsx } from '@eightshift/ui-components/utilities';
@@ -15,6 +16,7 @@ import { clsx } from '@eightshift/ui-components/utilities';
15
16
  * @param {boolean} [props.small] - If `true`, the button's size is reduced, perfect for added visual separation in hierarchical InnerBlocks.
16
17
  * @param {string} [props.className] - Additional classes to add to the control base.
17
18
  * @param {boolean} [props.prioritizePatterns] - Whether to show patterns before blocks in the inserter.
19
+ * @param {boolean} [props.alwaysVisible=false] - If `true`, the inserter is always visible, regardless of whether the block is selected.
18
20
  * @param {boolean} [props.hidden] - If `true`, the component is not rendered.
19
21
  *
20
22
  * @returns {JSX.Element} The BlockInserter component.
@@ -25,12 +27,26 @@ import { clsx } from '@eightshift/ui-components/utilities';
25
27
  * @preserve
26
28
  */
27
29
  export const BlockInserter = (props) => {
28
- const { clientId, label, small = false, className, prioritizePatterns = false, hidden } = props;
30
+ const {
31
+ clientId,
32
+ label,
33
+ small = false,
34
+ className,
35
+ prioritizePatterns = false,
36
+ alwaysVisible = false,
37
+ hidden,
38
+ } = props;
39
+
40
+ const currentBlockClientId = useSuspenseSelect((select) => select('core/block-editor')?.getSelectedBlockClientId());
29
41
 
30
42
  if (hidden) {
31
43
  return null;
32
44
  }
33
45
 
46
+ if (!alwaysVisible && currentBlockClientId !== clientId) {
47
+ return null;
48
+ }
49
+
34
50
  return (
35
51
  <Inserter
36
52
  rootClientId={clientId}
@@ -108,3 +108,74 @@ export const wpSearchRoute = fetchFromWpRest('search', {
108
108
  searchColumns: 'post_title',
109
109
  fields: 'id,title,type,subtype,url',
110
110
  });
111
+
112
+ /**
113
+ * Returns a function that fetches data from WordPress REST API.
114
+ *
115
+ * @param {string} endpoint - Endpoint to fetch from.
116
+ * @param {Object} options - Additional options.
117
+ * @param {number} [options.perPage=30] - Number of items to fetch per page.
118
+ * @param {string} [options.routePrefix='wp/v2'] - Route prefix for the API.
119
+ * @param {string} [options.fields='id,title'] - A comma-separated list of field names to fetch from the API. Good to include as it makes the query faster and the output terser.
120
+ * @param {string} [options.noSearch=false] - If `true`, only the URL will be returned, without the search query support.
121
+ * @param {SearchColumnsConfig} [options.searchColumns] - Allows narrowing the search scope.
122
+ *
123
+ * @returns {Function} The `(searchText) => url: string` function, or URL as `string` if `noSearch` is set.
124
+ *
125
+ * @typedef {'post_title' | 'post_excerpt' | 'post_content'} SearchColumnsConfig
126
+ *
127
+ * @example
128
+ * const data = await fetch(buildWpRestUrl('pages'));
129
+ * const json = await data.json();
130
+ *
131
+ * console.log(json);
132
+ *
133
+ * @example
134
+ * <AsyncSelect
135
+ * value={loremIpsum}
136
+ * onChange={(value) => setAttributes({ [getAttrKey('loremIpsum', attributes, manifest)]: value })}
137
+ * fetchUrl={buildWpRestUrl('pages')}
138
+ * />
139
+ *
140
+ */
141
+ export function buildWpRestUrl(endpoint, options = {}) {
142
+ const {
143
+ perPage = 30,
144
+ routePrefix = 'wp/v2',
145
+ fields = 'id,title',
146
+ searchColumns,
147
+ noSearch,
148
+ ...additionalParams
149
+ } = options;
150
+
151
+ let params = {
152
+ per_page: perPage,
153
+ };
154
+
155
+ if (fields?.length > 0) {
156
+ params['_fields'] = fields;
157
+ }
158
+
159
+ if (searchColumns?.length > 0) {
160
+ params.search_columns = Array.isArray(searchColumns) ? searchColumns.join(',') : searchColumns;
161
+ }
162
+
163
+ if (Object.keys(params).length > 0) {
164
+ params = {
165
+ ...params,
166
+ ...additionalParams,
167
+ };
168
+ }
169
+
170
+ if (noSearch) {
171
+ return addQueryArgs(`${routePrefix}/${endpoint}/`, params);
172
+ }
173
+
174
+ return (searchText) => {
175
+ if (searchText?.length > 0) {
176
+ params.search = searchText;
177
+ }
178
+
179
+ return addQueryArgs(`${routePrefix}/${endpoint}/`, params);
180
+ };
181
+ }
package/webpack/base.mjs CHANGED
@@ -34,7 +34,7 @@ export default (options) => {
34
34
  );
35
35
  }
36
36
 
37
- // Output css from Js.
37
+ // Output CSS from JS.
38
38
  if (!options.overrides.includes('miniCssExtractPlugin')) {
39
39
  plugins.push(
40
40
  new MiniCssExtractPlugin({
@@ -94,6 +94,7 @@ export default (options) => {
94
94
  ],
95
95
  });
96
96
 
97
+ // Node modules - CSS.
97
98
  module.rules.push({
98
99
  test: /\.css$/,
99
100
  include: /node_modules/,
@@ -103,6 +104,13 @@ export default (options) => {
103
104
  },
104
105
  ],
105
106
  });
107
+
108
+ // Node modules - Eightshift package fonts.
109
+ module.rules.push({
110
+ test: /\.(woff2|ttf|otf)$/i,
111
+ type: 'asset/resource',
112
+ include: /node_modules\/@eightshift/,
113
+ });
106
114
  }
107
115
 
108
116
  // Module for Images.