@eightshift/frontend-libs-tailwind 1.0.0 → 1.1.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.
Files changed (82) hide show
  1. package/.husky/pre-commit +0 -0
  2. package/CHANGELOG.md +15 -1
  3. package/blocks/init/assets/fonts/fraunces-italic-latin-extended.woff2 +0 -0
  4. package/blocks/init/assets/fonts/fraunces-italic-latin.woff2 +0 -0
  5. package/blocks/init/assets/fonts/fraunces-latin-extended.woff2 +0 -0
  6. package/blocks/init/assets/fonts/fraunces-latin.woff2 +0 -0
  7. package/blocks/init/assets/fonts/noto-sans-italic-latin-extended.woff2 +0 -0
  8. package/blocks/init/assets/fonts/noto-sans-italic-latin.woff2 +0 -0
  9. package/blocks/init/assets/fonts/noto-sans-latin-extended.woff2 +0 -0
  10. package/blocks/init/assets/fonts/noto-sans-latin.woff2 +0 -0
  11. package/blocks/init/src/Blocks/assets/scripts/shared.js +1 -3
  12. package/blocks/init/src/Blocks/assets/styles/editor/editor-overrides.css +1 -1
  13. package/blocks/init/src/Blocks/assets/styles/fonts.css +90 -0
  14. package/blocks/init/src/Blocks/assets/styles/tailwind.css +1 -5
  15. package/blocks/init/src/Blocks/components/admin-theme-options/assets-admin/pages/parts.js +1 -0
  16. package/blocks/init/src/Blocks/components/button/components/button-editor.js +1 -5
  17. package/blocks/init/src/Blocks/components/button/components/button-options.js +2 -21
  18. package/blocks/init/src/Blocks/components/button/manifest.json +8 -8
  19. package/blocks/init/src/Blocks/components/card/components/card-editor.js +1 -2
  20. package/blocks/init/src/Blocks/components/card/components/card-options.js +0 -1
  21. package/blocks/init/src/Blocks/components/heading/components/heading-editor.js +1 -5
  22. package/blocks/init/src/Blocks/components/image/components/image-editor.js +1 -7
  23. package/blocks/init/src/Blocks/components/image/components/image-options.js +3 -17
  24. package/blocks/init/src/Blocks/components/list/components/list-options.js +1 -3
  25. package/blocks/init/src/Blocks/components/load-more/assets/load-more.js +1 -2
  26. package/blocks/init/src/Blocks/components/load-more/components/load-more-options.js +1 -0
  27. package/blocks/init/src/Blocks/components/modal/assets/index.js +7 -9
  28. package/blocks/init/src/Blocks/components/paragraph/components/paragraph-options.js +1 -3
  29. package/blocks/init/src/Blocks/components/paragraph/manifest.json +14 -16
  30. package/blocks/init/src/Blocks/components/post-header/post-header.php +1 -1
  31. package/blocks/init/src/Blocks/components/share/assets/index.js +1 -5
  32. package/blocks/init/src/Blocks/components/share/components/share-editor.js +7 -4
  33. package/blocks/init/src/Blocks/components/share/components/share-options.js +2 -11
  34. package/blocks/init/src/Blocks/components/video/components/video-editor.js +2 -4
  35. package/blocks/init/src/Blocks/components/video/components/video-options.js +5 -27
  36. package/blocks/init/src/Blocks/custom/accordion/assets/index.js +1 -1
  37. package/blocks/init/src/Blocks/custom/accordion/components/accordion-editor.js +6 -1
  38. package/blocks/init/src/Blocks/custom/carousel/assets/pagination.js +3 -8
  39. package/blocks/init/src/Blocks/custom/column/components/column-editor.js +4 -1
  40. package/blocks/init/src/Blocks/custom/column/components/column-options.js +5 -12
  41. package/blocks/init/src/Blocks/custom/columns/components/columns-editor.js +2 -6
  42. package/blocks/init/src/Blocks/custom/featured-content/components/featured-content-options.js +18 -30
  43. package/blocks/init/src/Blocks/custom/featured-content/partials/cards.php +5 -5
  44. package/blocks/init/src/Blocks/custom/group/components/group-editor.js +1 -3
  45. package/blocks/init/src/Blocks/custom/heading/heading-transforms.js +1 -0
  46. package/blocks/init/src/Blocks/custom/map/assets/map-controller.js +0 -1
  47. package/blocks/init/src/Blocks/custom/map/components/map-components.js +3 -3
  48. package/blocks/init/src/Blocks/custom/map/components/map-editor.js +2 -12
  49. package/blocks/init/src/Blocks/custom/map/components/map-options.js +10 -46
  50. package/blocks/init/src/Blocks/custom/paragraph/paragraph-transforms.js +1 -0
  51. package/blocks/init/src/Blocks/custom/site-footer/components/site-footer-options.js +1 -3
  52. package/blocks/init/src/Blocks/custom/table-of-contents/components/table-of-contents-editor.js +1 -1
  53. package/blocks/init/src/Blocks/wrapper/components/wrapper-options.js +4 -19
  54. package/blocks/init/src/Blocks/wrapper/wrapper.js +1 -4
  55. package/linters/base.config.mjs +1 -1
  56. package/linters/eslint.config.mjs +1 -2
  57. package/linters/stylelint.config.js +9 -13
  58. package/package.json +92 -92
  59. package/schemas/block.json +4 -0
  60. package/schemas/component.json +4 -0
  61. package/scripts/components/block-inserter.js +8 -14
  62. package/scripts/components/file-picker.js +42 -39
  63. package/scripts/components/index.js +1 -0
  64. package/scripts/components/link-section-editor.js +6 -2
  65. package/scripts/components/picker-placeholder.js +109 -0
  66. package/scripts/components/server-side-render.js +2 -4
  67. package/scripts/components/settings/settings.js +3 -14
  68. package/scripts/components/settings/use-theme-options.js +2 -2
  69. package/scripts/editor/attributes.js +3 -9
  70. package/scripts/editor/colors.js +43 -41
  71. package/scripts/editor/editor.js +9 -16
  72. package/scripts/editor/fetch.js +26 -19
  73. package/scripts/editor/hooks.js +1 -0
  74. package/scripts/editor/options.js +2 -4
  75. package/scripts/editor/registration.js +51 -128
  76. package/scripts/editor/tailwindcss.js +118 -37
  77. package/scripts/helpers/breakpoints.js +3 -8
  78. package/scripts/helpers/cookies.js +2 -1
  79. package/scripts/helpers/index.js +1 -7
  80. package/scripts/index.js +2 -0
  81. package/scripts/plugins/yoast-seo.js +2 -3
  82. package/linters/ignore-gitignored.mjs +0 -9
@@ -34,10 +34,7 @@ export const overrideInnerBlockAttributes = (select, clientId, attributesObject
34
34
  const block = getBlock(clientId);
35
35
 
36
36
  block.innerBlocks.map((item) => {
37
- const {
38
- attributes,
39
- name,
40
- } = item;
37
+ const { attributes, name } = item;
41
38
 
42
39
  if (!exclude.includes(name)) {
43
40
  for (const attribute in attributesObject) {
@@ -78,7 +75,7 @@ export const overrideInnerBlockAttributes = (select, clientId, attributesObject
78
75
  * "type": "boolean"
79
76
  * },
80
77
  * },
81
- * "buttonContent": {
78
+ * "buttonContent": {
82
79
  * "type": "string"
83
80
  * },
84
81
  * }
@@ -226,7 +223,6 @@ export const getAttrKey = (key, attributes, manifest) => {
226
223
  * Additional keys that are passed are defined in the includes array.
227
224
  */
228
225
  export const props = (newName, attributes, manual = {}) => {
229
-
230
226
  const output = {};
231
227
 
232
228
  // Check which attributes we need to include.
@@ -250,7 +246,7 @@ export const props = (newName, attributes, manual = {}) => {
250
246
  const blockName = process.env.NODE_ENV === 'test' ? attributes.blockName.default : attributes.blockName;
251
247
 
252
248
  // Populate prefix key for recursive checks of attribute names.
253
- const prefix = (typeof attributes.prefix === 'undefined') ? camelCase(blockName) : attributes['prefix'];
249
+ const prefix = typeof attributes.prefix === 'undefined' ? camelCase(blockName) : attributes['prefix'];
254
250
 
255
251
  // Set component prefix.
256
252
  if (prefix === '') {
@@ -261,7 +257,6 @@ export const props = (newName, attributes, manual = {}) => {
261
257
 
262
258
  // Iterate over attributes.
263
259
  for (const [key, value] of Object.entries(attributes)) {
264
-
265
260
  // Includes attributes from iteration.
266
261
  if (includes.includes(key)) {
267
262
  Object.assign(output, { [key]: value });
@@ -278,7 +273,6 @@ export const props = (newName, attributes, manual = {}) => {
278
273
  if (!isEmpty(manual)) {
279
274
  // Iterate manual attributes.
280
275
  for (let [key, value] of Object.entries(manual)) {
281
-
282
276
  // Includes attributes from iteration.
283
277
  if (includes.includes(key)) {
284
278
  Object.assign(output, { [key]: value });
@@ -14,51 +14,53 @@ import { upperFirst } from '@eightshift/ui-components/utilities';
14
14
  * getPaletteColors()
15
15
  * ```
16
16
  */
17
- export const getPaletteColors = () => useSelect((select) => {
18
- const colors = select(STORE_NAME).getSettings().globalVariables.colors;
17
+ export const getPaletteColors = () =>
18
+ useSelect((select) => {
19
+ const colors = select(STORE_NAME).getSettings().globalVariables.colors;
19
20
 
20
- return colors.reduce(
21
- (obj, item) => ({
22
- ...obj,
23
- [item.slug]: item,
24
- }),
25
- {}
26
- );
27
- });
21
+ return colors.reduce(
22
+ (obj, item) => ({
23
+ ...obj,
24
+ [item.slug]: item,
25
+ }),
26
+ {},
27
+ );
28
+ });
28
29
 
29
- export const getColorData = (themeColors) => Object.entries(themeColors ?? {})?.reduce((curr, [name, value]) => {
30
- if (name === 'current') {
31
- return curr;
32
- }
30
+ export const getColorData = (themeColors) =>
31
+ Object.entries(themeColors ?? {})?.reduce((curr, [name, value]) => {
32
+ if (name === 'current') {
33
+ return curr;
34
+ }
33
35
 
34
- if (name === 'transparent') {
35
- return [
36
- ...curr,
37
- {
38
- name: 'Transparent',
39
- slug: 'transparent',
40
- color: '#00000000',
41
- }
42
- ];
43
- }
36
+ if (name === 'transparent') {
37
+ return [
38
+ ...curr,
39
+ {
40
+ name: 'Transparent',
41
+ slug: 'transparent',
42
+ color: '#00000000',
43
+ },
44
+ ];
45
+ }
46
+
47
+ if (typeof value === 'string') {
48
+ return [
49
+ ...curr,
50
+ {
51
+ name: upperFirst(name),
52
+ slug: name,
53
+ color: value,
54
+ },
55
+ ];
56
+ }
44
57
 
45
- if (typeof value === 'string') {
46
58
  return [
47
59
  ...curr,
48
- {
49
- name: upperFirst(name),
50
- slug: name,
51
- color: value,
52
- }
60
+ ...Object.entries(value).map(([shade, color]) => ({
61
+ name: `${upperFirst(name)} ${shade}`,
62
+ slug: `${name}-${shade}`,
63
+ color,
64
+ })),
53
65
  ];
54
- }
55
-
56
- return [
57
- ...curr,
58
- ...Object.entries(value).map(([shade, color]) => ({
59
- name: `${upperFirst(name)} ${shade}`,
60
- slug: `${name}-${shade}`,
61
- color,
62
- })),
63
- ];
64
- }, []) ?? [];
66
+ }, []) ?? [];
@@ -74,6 +74,7 @@ export const unlockPostEditing = (blockClientId, attributeKey) => {
74
74
  export const lockIfUndefined = (blockClientId, attributeKey, value) => {
75
75
  if (typeof value === 'undefined' || value === null || value === '') {
76
76
  lockPostEditing(blockClientId, attributeKey);
77
+
77
78
  return;
78
79
  }
79
80
  unlockPostEditing(blockClientId, attributeKey);
@@ -104,36 +105,28 @@ export const lockIfUndefined = (blockClientId, attributeKey, value) => {
104
105
  *
105
106
  */
106
107
  export const GutenbergBlock = (props) => {
107
- const {
108
- options: OptionsComponent,
109
- toolbar: ToolbarComponent,
110
- editor: EditorComponent,
111
- noOptionsContainer = false,
112
- title,
113
- } = props;
108
+ const { options: OptionsComponent, toolbar: ToolbarComponent, editor: EditorComponent, noOptionsContainer = false, title } = props;
114
109
 
115
110
  return (
116
111
  <>
117
- {OptionsComponent &&
112
+ {OptionsComponent && (
118
113
  <InspectorControls>
119
- {!noOptionsContainer &&
114
+ {!noOptionsContainer && (
120
115
  <ContainerPanel title={title ?? upperFirst(props?.attributes?.blockName)}>
121
116
  <OptionsComponent {...props} />
122
117
  </ContainerPanel>
123
- }
118
+ )}
124
119
  {noOptionsContainer && <OptionsComponent {...props} />}
125
120
  </InspectorControls>
126
- }
121
+ )}
127
122
 
128
- {ToolbarComponent &&
123
+ {ToolbarComponent && (
129
124
  <BlockControls>
130
125
  <ToolbarComponent {...props} />
131
126
  </BlockControls>
132
- }
127
+ )}
133
128
 
134
- {EditorComponent &&
135
- <EditorComponent {...props} />
136
- }
129
+ {EditorComponent && <EditorComponent {...props} />}
137
130
  </>
138
131
  );
139
132
  };
@@ -1,4 +1,6 @@
1
- import { unescapeHTML } from '@eightshift/ui-components/utilities';
1
+ import { truncate, unescapeHTML } from '@eightshift/ui-components/utilities';
2
+ import { addQueryArgs } from '@wordpress/url';
3
+ import apiFetch from '@wordpress/api-fetch';
2
4
 
3
5
  /**
4
6
  * Returns a function that fetches data from WordPress REST API.
@@ -7,13 +9,14 @@ import { unescapeHTML } from '@eightshift/ui-components/utilities';
7
9
  * @param {Object} options - Additional options.
8
10
  * @param {Function} [options.processId] - Function to process the ID. `(itemData: Object) => id: string | Number`
9
11
  * @param {Function} [options.processLabel] - Function to process the label. `(itemData: Object) => label: string`
12
+ * @param {string} [options.labelProp='title'] - Property to use as a label. Overriden by `processLabel`.
10
13
  * @param {Function} [options.processMetadata] - Function to process the metadata. `(itemData: Object) => metadata: Object`
11
14
  * @param {number} [options.perPage=30] - Number of items to fetch per page.
12
- * @param {string} [options.urlBase='<origin>/wp-json'] - Base URL for the API.
13
15
  * @param {string} [options.routePrefix='wp/v2'] - Route prefix for the API.
14
16
  * @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.
15
17
  * @param {SearchColumnsConfig} [options.searchColumns] - Allows narrowing the search scope.
16
18
  * @param {boolean} [options.noUnescapeTitle] - If `true`, the post title will not unescape HTML entities.
19
+ * @param {Number?} [options.truncateTitle=26] - If set, the title will be truncated to this length.
17
20
  *
18
21
  * @returns {Function} The `(searchText, [abortSignal]) => Promise` function.
19
22
  *
@@ -37,49 +40,53 @@ import { unescapeHTML } from '@eightshift/ui-components/utilities';
37
40
  export function fetchFromWpRest(endpoint, options = {}) {
38
41
  const {
39
42
  processId = ({ id }) => id,
40
- processLabel = ({ title }) => unescapeHTML(title),
43
+ labelProp = 'title',
44
+ processLabel = (item) => item[labelProp],
41
45
  processMetadata = () => null,
42
46
  perPage = 30,
43
- urlBase = `${window.location.origin}/wp-json`,
44
47
  routePrefix = 'wp/v2',
45
48
  fields = 'id,title',
46
49
  searchColumns,
47
50
  noUnescapeTitle = false,
48
- ...params
51
+ truncateTitle = 32,
52
+ ...additionalParams
49
53
  } = options;
50
54
 
51
55
  return async (searchText = '', abortSignal) => {
52
- const url = new URL(`${urlBase}/${routePrefix}/${endpoint}/`);
53
-
54
- url.searchParams.append('per_page', perPage);
56
+ let params = {
57
+ per_page: perPage,
58
+ };
55
59
 
56
60
  if (fields?.length > 0) {
57
- url.searchParams.append('_fields', fields);
61
+ params['_fields'] = fields;
58
62
  }
59
63
 
60
64
  if (searchColumns?.length > 0) {
61
- url.searchParams.append('search_columns', Array.isArray(searchColumns) ? searchColumns.join(',') : searchColumns);
65
+ params.search_columns = Array.isArray(searchColumns) ? searchColumns.join(',') : searchColumns;
62
66
  }
63
67
 
64
68
  if (Object.keys(params).length > 0) {
65
- for (const [key, value] of Object.entries(params)) {
66
- url.searchParams.append(key, value);
67
- }
69
+ params = {
70
+ ...params,
71
+ ...additionalParams,
72
+ };
68
73
  }
69
74
 
70
75
  if (searchText?.length > 0) {
71
- url.searchParams.append('search', searchText);
76
+ params.search = searchText;
72
77
  }
73
78
 
74
- const newData = await fetch(url.toString(), {
79
+ const newData = await apiFetch({
80
+ path: addQueryArgs(`${routePrefix}/${endpoint}/`, params),
75
81
  signal: abortSignal,
76
82
  });
77
83
 
78
- const newDataJson = await newData.json();
84
+ return newData.map((item) => {
85
+ const rawLabel = !noUnescapeTitle ? unescapeHTML(processLabel(item)) : processLabel(item);
86
+ const truncatedLabel = Number.isInteger(truncateTitle) && truncateTitle > 0 ? truncate(rawLabel, truncateTitle) : rawLabel;
79
87
 
80
- return [...newDataJson].map((item) => {
81
88
  return {
82
- label: noUnescapeTitle ? unescapeHTML(processLabel(item)) : processLabel(item),
89
+ label: truncatedLabel,
83
90
  value: processId(item),
84
91
  metadata: processMetadata(item),
85
92
  };
@@ -89,7 +96,7 @@ export function fetchFromWpRest(endpoint, options = {}) {
89
96
 
90
97
  export const wpSearchRoute = fetchFromWpRest('search', {
91
98
  processId: ({ url }) => url,
92
- processLabel: ({ title }) => title,
99
+ labelProp: 'title',
93
100
  processMetadata: ({ type, subtype }) => ({ type, subtype }),
94
101
  additionalParam: {
95
102
  type: 'post',
@@ -39,6 +39,7 @@ export const blocksFilterHook = createHigherOrderComponent((BlockListBlock) => {
39
39
  },
40
40
  };
41
41
  }
42
+
42
43
  return <BlockListBlock {...updatedProps} />;
43
44
  };
44
45
  }, 'blocksFilterHook');
@@ -36,7 +36,6 @@ import { lowerFirst, camelCase } from '@eightshift/ui-components/utilities';
36
36
  * ```
37
37
  */
38
38
  export const getOption = (key, attributes, manifest, isColor = false) => {
39
-
40
39
  // Check if there is prefix in the attributes object.
41
40
  const options = attributes?.['options'] || {};
42
41
 
@@ -61,7 +60,6 @@ export const getOption = (key, attributes, manifest, isColor = false) => {
61
60
 
62
61
  // Check the provided options overrides.
63
62
  if (Object.prototype.hasOwnProperty.call(options, newKey)) {
64
-
65
63
  // If color type use color output.
66
64
  if (isColor) {
67
65
  return getOptionColors(options[newKey]);
@@ -69,7 +67,7 @@ export const getOption = (key, attributes, manifest, isColor = false) => {
69
67
 
70
68
  // Used for array of objects (selectControl options). If so check override by value key.
71
69
  if (typeof componentOptions[key][0] === 'object') {
72
- return componentOptions[key].filter((item) => options[newKey].includes((item.value)));
70
+ return componentOptions[key].filter((item) => options[newKey].includes(item.value));
73
71
  }
74
72
 
75
73
  // If array only user array value for check.
@@ -140,7 +138,7 @@ export const getOptions = (attributes = {}, manifest = {}) => {
140
138
  const componentName = manifest['componentName'];
141
139
 
142
140
  const output = {};
143
- const prefix = (typeof attributes['prefix'] === 'undefined') ? '' : attributes['prefix'];
141
+ const prefix = typeof attributes['prefix'] === 'undefined' ? '' : attributes['prefix'];
144
142
 
145
143
  for (const [key, value] of Object.entries(optionsManifest)) {
146
144
  const newKey = key.replace(`${lowerFirst(camelCase(componentName))}`, '');