@siratik/wp-component-library 0.1.0 → 0.1.2

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 (96) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +51 -5
  3. package/components/attachment-image/README.md +118 -0
  4. package/components/attachment-image/index.js +105 -0
  5. package/components/attributes-panel/README.md +92 -0
  6. package/components/attributes-panel/index.js +324 -0
  7. package/components/badge/README.md +61 -0
  8. package/components/badge/index.js +105 -0
  9. package/components/block-appender/README.md +158 -0
  10. package/components/block-appender/index.js +135 -0
  11. package/components/block-extension/index.js +214 -0
  12. package/components/business-hours/SpecialHoursControl.js +211 -0
  13. package/components/business-hours/WeeklyHoursControl.js +419 -0
  14. package/components/business-hours/index.js +8 -0
  15. package/components/button/README.md +172 -0
  16. package/components/button/index.js +84 -0
  17. package/components/captcha-placeholder/CloudflareTurnstile.js +111 -0
  18. package/components/captcha-placeholder/GoogleRecaptcha.js +132 -0
  19. package/components/captcha-placeholder/HCaptcha.js +99 -0
  20. package/components/captcha-placeholder/README.md +228 -0
  21. package/components/captcha-placeholder/index.js +39 -0
  22. package/components/captcha-placeholder/styles.js +33 -0
  23. package/components/geocoder/AddressEntryControl.js +390 -0
  24. package/components/geocoder/GeocoderSearchControl.js +353 -0
  25. package/components/geocoder/countryOptions.js +66 -0
  26. package/components/geocoder/geocoder.js +400 -0
  27. package/components/geocoder/index.js +16 -0
  28. package/components/icon-picker/Icon.js +53 -0
  29. package/components/icon-picker/IconPicker.js +70 -0
  30. package/components/icon-picker/IconPickerModal.js +474 -0
  31. package/components/icon-picker/IconPickerToolbarButton.js +60 -0
  32. package/components/icon-picker/InlineIconPicker.js +92 -0
  33. package/components/icon-picker/api.js +181 -0
  34. package/components/icon-picker/config-bootstrap.js +108 -0
  35. package/components/icon-picker/hooks.js +157 -0
  36. package/components/icon-picker/index.js +39 -0
  37. package/components/icon-picker/load-script.js +33 -0
  38. package/components/icon-picker/loaders.js +79 -0
  39. package/components/icon-picker/store.js +223 -0
  40. package/components/icon-picker/styles.js +232 -0
  41. package/components/icon-picker/utils.js +138 -0
  42. package/components/layout/README.md +268 -0
  43. package/components/link-tools-panel/README.md +49 -0
  44. package/components/link-tools-panel/index.js +198 -0
  45. package/components/link-tools-panel/styles.js +90 -0
  46. package/components/media/README.md +288 -0
  47. package/components/media/SettingsMediaUpload.js +187 -0
  48. package/components/media/editor-media-upload.js +65 -0
  49. package/components/media/image-controls.js +196 -0
  50. package/components/media/index.js +13 -0
  51. package/components/media/inspector-media-upload.js +290 -0
  52. package/components/media/toolbar-media-upload.js +53 -0
  53. package/components/media/utils/aspect-ratios.js +118 -0
  54. package/components/meta/MetaPanel.js +75 -0
  55. package/components/meta/README.md +46 -0
  56. package/components/meta/index.js +6 -0
  57. package/components/meta/meta-gated-editor.js +282 -0
  58. package/components/query/README.md +340 -0
  59. package/components/query/cardTemplatePartPanel.js +69 -0
  60. package/components/query/cardTemplatePartSelect.js +165 -0
  61. package/components/query/cardTemplatePartUtils.js +119 -0
  62. package/components/query/columnCountControl.js +63 -0
  63. package/components/query/displayTypeSelect.js +52 -0
  64. package/components/query/examples.js +166 -0
  65. package/components/query/hideCurrentPostControl.js +47 -0
  66. package/components/query/index.js +20 -0
  67. package/components/query/manualPostSelector.js +125 -0
  68. package/components/query/manualTermSelector.js +141 -0
  69. package/components/query/orderBySelect.js +95 -0
  70. package/components/query/postTypeSelect.js +67 -0
  71. package/components/query/postsPerPageControl.js +51 -0
  72. package/components/query/selectionModeControl.js +61 -0
  73. package/components/query/taxonomySelect.js +139 -0
  74. package/components/query/utils.js +75 -0
  75. package/components/repeater/README.md +159 -0
  76. package/components/repeater/index.js +829 -0
  77. package/components/segmented-bar/README.md +30 -0
  78. package/components/segmented-bar/index.js +68 -0
  79. package/components/sortable-select/README.md +153 -0
  80. package/components/sortable-select/custom-sortable-token.js +127 -0
  81. package/components/sortable-select/index.js +693 -0
  82. package/components/style-picker/README.md +36 -0
  83. package/components/style-picker/index.js +92 -0
  84. package/components/variable-field/README.md +299 -0
  85. package/components/variable-field/index.js +592 -0
  86. package/components/variable-field/value-to-chip-html.js +38 -0
  87. package/components/variable-inserter/README.md +68 -0
  88. package/components/variable-inserter/index.js +168 -0
  89. package/constants/statusColors.js +16 -6
  90. package/editor.js +16 -0
  91. package/index.js +127 -0
  92. package/package.json +27 -16
  93. package/utils/kitaris-localize.js +128 -0
  94. package/utils/slug-aware-color-setter.js +27 -0
  95. package/build/index.asset.php +0 -20
  96. package/build/index.js +0 -1233
@@ -0,0 +1,168 @@
1
+ import styled from "@emotion/styled";
2
+ import { Button, Popover } from "@wordpress/components";
3
+ import { useRef, useState } from "@wordpress/element";
4
+ import { __ } from "@wordpress/i18n";
5
+ import { Icon, plusCircle } from "@wordpress/icons";
6
+
7
+ const StyledVariableInserter = styled.div`
8
+ display: inline-flex;
9
+ align-items: flex-start;
10
+ margin-top: 1.5rem;
11
+ align-self: flex-start;
12
+ `;
13
+
14
+ const StyledPopover = styled(Popover)`
15
+ &.components-popover {
16
+ .components-popover__content {
17
+ min-width: 280px;
18
+ max-width: min(440px, 92vw);
19
+ padding: 0;
20
+ }
21
+ }
22
+ `;
23
+
24
+ const StyledChipPanel = styled.div`
25
+ padding: 14px 16px;
26
+ display: flex;
27
+ flex-wrap: wrap;
28
+ gap: 8px;
29
+ max-height: 300px;
30
+ overflow-y: auto;
31
+ background-color: #f6f7f7;
32
+ border-radius: 2px;
33
+ `;
34
+
35
+ const StyledChip = styled.button`
36
+ display: inline-flex;
37
+ align-items: center;
38
+ margin: 0;
39
+ padding: 7px 14px;
40
+ border: 1px solid var(--wp-admin-theme-color, #3858e9);
41
+ border-radius: 999px;
42
+ background: #fff;
43
+ color: var(--wp-admin-theme-color, #3858e9);
44
+ font-family: inherit;
45
+ font-size: 11px;
46
+ font-weight: 400;
47
+ line-height: 1.35;
48
+ cursor: pointer;
49
+ transition:
50
+ background-color 0.15s ease,
51
+ color 0.15s ease,
52
+ border-color 0.15s ease;
53
+
54
+ &:hover,
55
+ &:focus-visible {
56
+ background: var(--wp-admin-theme-color, #3858e9);
57
+ border-color: var(--wp-admin-theme-color, #3858e9);
58
+ color: #fff;
59
+ outline: none;
60
+ }
61
+
62
+ @media (prefers-color-scheme: dark) {
63
+ background: #1e1e1e;
64
+ color: #fff;
65
+ border-color: var(--wp-admin-theme-color, #3858e9);
66
+
67
+ &:hover,
68
+ &:focus-visible {
69
+ background: var(--wp-admin-theme-color, #3858e9);
70
+ color: #fff;
71
+ }
72
+ }
73
+ `;
74
+
75
+ const StyledEmpty = styled.div`
76
+ padding: 16px 20px;
77
+ text-align: center;
78
+ color: #646970;
79
+ font-size: 13px;
80
+ font-style: italic;
81
+ line-height: 1.4;
82
+
83
+ @media (prefers-color-scheme: dark) {
84
+ color: #c3c4c7;
85
+ }
86
+ `;
87
+
88
+ /**
89
+ * VariableInserter — popover of merge-tag chips for text fields.
90
+ *
91
+ * @param {Object} props
92
+ * @param {Array<{label: string, value: string}>} props.variables
93
+ * @param {string} props.currentValue
94
+ * @param {Function} props.onChange
95
+ * @param {Object} props.buttonProps
96
+ * @param {string} props.placeholder
97
+ * @param {string} props.className
98
+ * @param {string} props.size
99
+ * @param {string} props.variant
100
+ */
101
+ const VariableInserter = ({
102
+ variables = [],
103
+ currentValue = "",
104
+ onChange,
105
+ buttonProps = {},
106
+ placeholder = __("Insert variable", "wp-component-library"),
107
+ className = "",
108
+ size = "default",
109
+ variant = "tertiary",
110
+ ...props
111
+ }) => {
112
+ const [isOpen, setIsOpen] = useState(false);
113
+ const buttonRef = useRef(null);
114
+
115
+ const handleVariableClick = (variable) => {
116
+ onChange(currentValue + variable.value);
117
+ setIsOpen(false);
118
+ };
119
+
120
+ return (
121
+ <StyledVariableInserter className={className} {...props}>
122
+ <Button
123
+ ref={buttonRef}
124
+ icon={<Icon icon={plusCircle} />}
125
+ label={placeholder}
126
+ onClick={() => setIsOpen((open) => !open)}
127
+ size={size}
128
+ variant={variant}
129
+ {...buttonProps}
130
+ />
131
+
132
+ {isOpen && (
133
+ <StyledPopover
134
+ className="variable-inserter-popover"
135
+ anchor={buttonRef.current}
136
+ onClose={() => setIsOpen(false)}
137
+ placement="bottom-start"
138
+ >
139
+ <StyledChipPanel className="variable-inserter-chips">
140
+ {variables.length === 0 ? (
141
+ <StyledEmpty>
142
+ {__(
143
+ "No variables available",
144
+ "wp-component-library",
145
+ )}
146
+ </StyledEmpty>
147
+ ) : (
148
+ variables.map((variable) => (
149
+ <StyledChip
150
+ key={variable.value}
151
+ type="button"
152
+ className="variable-inserter-chip"
153
+ onClick={() =>
154
+ handleVariableClick(variable)
155
+ }
156
+ >
157
+ {variable.label}
158
+ </StyledChip>
159
+ ))
160
+ )}
161
+ </StyledChipPanel>
162
+ </StyledPopover>
163
+ )}
164
+ </StyledVariableInserter>
165
+ );
166
+ };
167
+
168
+ export { VariableInserter };
@@ -24,7 +24,7 @@ export const STATUS_COLOR_FALLBACKS = {
24
24
  warning: {
25
25
  base: "#f0b849",
26
26
  light: "#fef8e6",
27
- dark: "#b26200",
27
+ dark: "#a35a00",
28
28
  },
29
29
  error: {
30
30
  base: "#cc1818",
@@ -53,6 +53,7 @@ const CORE_FAMILY = {
53
53
  * - accent: text, icons and chart series on neutral chrome
54
54
  * - stroke: borders, dots and markers
55
55
  * - surface: tinted backgrounds
56
+ * - fill: chart series, rings and bars (see statusColor)
56
57
  */
57
58
  const ROLES = {
58
59
  content: ["foreground-content-%s", "dark"],
@@ -64,15 +65,24 @@ const ROLES = {
64
65
  /**
65
66
  * A status colour by role.
66
67
  *
68
+ * `fill` has no core token: core's status foregrounds are darkened for text
69
+ * contrast (caution reads olive as a fill), so filled shapes use the bright
70
+ * base palette instead.
71
+ *
67
72
  * @param {'success' | 'warning' | 'error' | 'info'} type
68
- * @param {'content' | 'accent' | 'stroke' | 'surface'} [role='accent']
73
+ * @param {'content' | 'accent' | 'stroke' | 'surface' | 'fill'} [role='accent']
69
74
  * @returns {string}
70
75
  */
71
76
  export const statusColor = (type, role = "accent") => {
77
+ if (role === "fill") {
78
+ return STATUS_COLOR_FALLBACKS[type]?.base ?? STATUS_COLOR_FALLBACKS.error.base;
79
+ }
80
+
72
81
  const [token, variant] = ROLES[role] ?? ROLES.accent;
73
82
  const family = CORE_FAMILY[type] ?? "error";
74
83
  const fallback = STATUS_COLOR_FALLBACKS[type]?.[variant] ?? "#646970";
75
84
 
85
+ // eslint-disable-next-line @wordpress/no-unknown-ds-tokens -- token names come from the ROLES/CORE_FAMILY maps above.
76
86
  return `var(--wpds-color-${token.replace("%s", family)}, ${fallback})`;
77
87
  };
78
88
 
@@ -143,7 +153,7 @@ export const getScoreChartColors = (score) => {
143
153
  const tier = getScoreStatusTier(score);
144
154
 
145
155
  return {
146
- chart: statusColor(tier, "accent"),
156
+ chart: statusColor(tier, "fill"),
147
157
  text: statusColor(tier, "content"),
148
158
  };
149
159
  };
@@ -192,8 +202,8 @@ export const getBadgeIntentColors = (intent) => {
192
202
  export const defaultChartStatusColors = [
193
203
  ADMIN_COLOR.brandFill,
194
204
  "#646970",
195
- statusColor("success"),
196
- statusColor("warning"),
197
- statusColor("error"),
205
+ statusColor("success", "fill"),
206
+ statusColor("warning", "fill"),
207
+ statusColor("error", "fill"),
198
208
  "#8b5cf6",
199
209
  ];
package/editor.js ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Post-editor-only components and helpers: everything here needs
3
+ * @wordpress/editor or its `core/editor` store. Import them from
4
+ * `@siratik/wp-component-library/editor`; the main entry (index.js) has the
5
+ * rest, so screens outside the post editor don't load @wordpress/editor.
6
+ */
7
+ export {
8
+ isMetaValueEmpty,
9
+ isTemplateEditorSurface,
10
+ useMetaGatedEditorVisibility,
11
+ } from "./components/meta/meta-gated-editor";
12
+ export { MetaPanel } from "./components/meta/MetaPanel";
13
+ export {
14
+ default as AttributesPanel,
15
+ useAttributes,
16
+ } from "./components/attributes-panel";
package/index.js ADDED
@@ -0,0 +1,127 @@
1
+ /**
2
+ * WordPress Component Library
3
+ *
4
+ * A collection of reusable components for WordPress projects.
5
+ */
6
+
7
+ export { AttachmentImage } from "./components/attachment-image";
8
+ export {
9
+ registerBlockExtension,
10
+ unregisterBlockExtension,
11
+ } from "./components/block-extension";
12
+ export {
13
+ CustomBlockAppender,
14
+ CustomColumnAppender,
15
+ CustomInlineAppender,
16
+ CustomInspectorAppender,
17
+ } from "./components/block-appender";
18
+ export { ButtonFrontend } from "./components/button";
19
+ export {
20
+ EditorMediaUpload,
21
+ InspectorMediaUpload,
22
+ SettingsMediaUpload,
23
+ ToolbarMediaUpload,
24
+ } from "./components/media";
25
+ export { ImageControls } from "./components/media/image-controls";
26
+ // MetaPanel, AttributesPanel and the meta-gated editor helpers need the post
27
+ // editor (@wordpress/editor or its store): they live in
28
+ // `@siratik/wp-component-library/editor` (editor.js), so screens outside the
29
+ // post editor never load @wordpress/editor through this entry.
30
+ export { DragHandle, RemoveButton, Repeater } from "./components/repeater";
31
+ // Query Controls - Individual ToolsPanelItems that can be composed together
32
+ export { Badge } from "./components/badge";
33
+ // Address search (Nominatim, explicit submit only).
34
+ export {
35
+ AddressEntryControl,
36
+ GeocoderSearchControl,
37
+ geocodeAddress,
38
+ getCountryOptions,
39
+ toOrganizationLocation,
40
+ GEOCODER_ATTRIBUTION_HTML,
41
+ DEFAULT_GEOCODER_COUNTRY_CODES,
42
+ } from "./components/geocoder";
43
+ // Weekly business hours editor (controlled).
44
+ export { SpecialHoursControl, WeeklyHoursControl } from "./components/business-hours";
45
+ export { SegmentedBar } from "./components/segmented-bar";
46
+ export { StylePicker } from "./components/style-picker";
47
+ export {
48
+ STATUS_COLOR_FALLBACKS,
49
+ statusColor,
50
+ statusVar,
51
+ getStatusSurfaceColors,
52
+ getScoreStatusTier,
53
+ getScoreSurfaceColors,
54
+ getScoreChartColors,
55
+ getBadgeIntentColors,
56
+ defaultChartStatusColors,
57
+ } from "./constants/statusColors";
58
+ export { ADMIN_COLOR } from "./constants/adminColors";
59
+ export { CaptchaPlaceholder } from "./components/captcha-placeholder";
60
+ export { useAspectRatioOptions } from "./components/media/utils/aspect-ratios";
61
+ export {
62
+ ColumnCountControl,
63
+ defaultOrderOptions,
64
+ DisplayTypeSelect,
65
+ HideCurrentPostControl,
66
+ ManualPostSelector,
67
+ ManualTermSelector,
68
+ OrderBySelect,
69
+ PostsPerPageControl,
70
+ PostTypeSelect,
71
+ CardTemplatePartSelect,
72
+ CardTemplatePartPanel,
73
+ getDefaultCardSlugForPostType,
74
+ reorderByIds,
75
+ SelectionModeControl,
76
+ TaxonomySelect,
77
+ useOrderedTerms,
78
+ } from "./components/query";
79
+ export {
80
+ default as SortableSelect,
81
+ tokensToString,
82
+ } from "./components/sortable-select";
83
+ export {
84
+ LinkToolsPanel,
85
+ LinkToolsPanelItems,
86
+ LINK_DEFAULTS,
87
+ } from "./components/link-tools-panel";
88
+ export { VariableField } from "./components/variable-field";
89
+ export { VariableInserter } from "./components/variable-inserter";
90
+
91
+
92
+ export {
93
+ getEditorExperiencePatterns,
94
+ getEditorExperienceSectionDivider,
95
+ getLocalize,
96
+ getLocalizeWindow,
97
+ getKitarisLocalize, // @deprecated — use getLocalize
98
+ getKitarisLocalizeWindow, // @deprecated — use getLocalizeWindow
99
+ SKIN_CHANGED_EVENT,
100
+ } from "./utils/kitaris-localize";
101
+
102
+ // Color controls
103
+ export { slugAwareColorSetter } from "./utils/slug-aware-color-setter";
104
+
105
+ // Icon Picker & Registry
106
+ export {
107
+ iconStore,
108
+ ICON_STORE_NAME,
109
+ registerIconSet,
110
+ registerIcons,
111
+ registerConfigIconSets,
112
+ removeIconSet,
113
+ loadIconSet,
114
+ loadAllIconSets,
115
+ useIconSets,
116
+ useGroupedIcons,
117
+ useIconPickerGroups,
118
+ useAllIcons,
119
+ useIcons,
120
+ useIcon,
121
+ Icon,
122
+ IconPicker,
123
+ IconPickerModal,
124
+ IconPickerToolbarButton,
125
+ InlineIconPicker,
126
+ safeSvgSource,
127
+ } from "./components/icon-picker";
package/package.json CHANGED
@@ -1,17 +1,27 @@
1
1
  {
2
2
  "name": "@siratik/wp-component-library",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Library of components for use in the WordPress block editor.",
5
- "main": "build/index.js",
6
- "module": "build/index.js",
5
+ "main": "index.js",
6
+ "module": "index.js",
7
7
  "exports": {
8
- ".": "./build/index.js",
8
+ ".": "./index.js",
9
+ "./editor": "./editor.js",
9
10
  "./constants/*": "./constants/*.js"
10
11
  },
11
- "sideEffects": false,
12
+ "files": [
13
+ "index.js",
14
+ "editor.js",
15
+ "components",
16
+ "utils",
17
+ "constants",
18
+ "!**/test/**",
19
+ "!**/*.test.js"
20
+ ],
21
+ "sideEffects": [
22
+ "./components/icon-picker/store.js"
23
+ ],
12
24
  "scripts": {
13
- "start": "wp-scripts start",
14
- "build": "wp-scripts build",
15
25
  "format": "wp-scripts format",
16
26
  "lint:js": "wp-scripts lint-js",
17
27
  "lint:md:docs": "wp-scripts lint-md-docs",
@@ -20,30 +30,31 @@
20
30
  },
21
31
  "repository": {
22
32
  "type": "git",
23
- "url": "git+:https://github.com/builtnorth/wp-component-library.git"
33
+ "url": "git+https://github.com/builtnorth/wp-component-library.git"
24
34
  },
25
35
  "author": "Built North",
26
- "license": "GPL-2.0-or-later",
36
+ "license": "GPL-3.0-or-later",
27
37
  "bugs": {
28
- "url": "https://github.com/builtnorth/wp-component-library.git/issues"
38
+ "url": "https://github.com/builtnorth/wp-component-library/issues"
29
39
  },
30
- "homepage": "https://github.com/builtnorth/wp-admin-dashboard?tab=readme-ov-file#readme",
40
+ "homepage": "https://github.com/builtnorth/wp-component-library#readme",
31
41
  "dependencies": {
32
42
  "@dnd-kit/core": "^6.3.1",
33
43
  "@dnd-kit/modifiers": "^9.0.0",
34
44
  "@dnd-kit/sortable": "^10.0.0",
35
45
  "@dnd-kit/utilities": "^3.2.2",
36
- "@leeoniya/ufuzzy": "^1.0.14",
46
+ "@wordpress/icons": "^15.5.0",
37
47
  "classnames": "^2.5.1",
38
- "dompurify": "^3.4.7",
39
- "prop-types": "^15.8.1",
40
- "react-window": "^1.8.11"
48
+ "dompurify": "^3.4.17",
49
+ "prop-types": "^15.8.1"
41
50
  },
42
51
  "peerDependencies": {
43
52
  "@emotion/react": "^11.14.0",
44
53
  "@emotion/styled": "^11.14.1"
45
54
  },
46
55
  "devDependencies": {
47
- "@wordpress/scripts": "^34.2.0"
56
+ "@wordpress/scripts": "^34.2.0",
57
+ "react": "^18.3.1",
58
+ "react-dom": "^18.3.1"
48
59
  }
49
60
  }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Resolve kitaris_localize across nested editor iframes (canvas vs shell).
3
+ *
4
+ * NOTE: window.kitaris_localize, window.kitarisLocalizeAdmin, and
5
+ * window.kitarisLocalizeShared are PHP-injected globals — their names are
6
+ * controlled by the host plugin and cannot be changed here.
7
+ */
8
+ export const SKIN_CHANGED_EVENT = "themeSkinSwitcherChanged";
9
+
10
+ /**
11
+ * Whether a window's globals can be read from here (same origin).
12
+ *
13
+ * @param {Window} win
14
+ * @return {boolean}
15
+ */
16
+ function isReadableWindow(win) {
17
+ try {
18
+ // Throws a SecurityError for a cross-origin window.
19
+ return !!win.document;
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * The current window plus each same-origin ancestor. The walk stops at the
27
+ * first cross-origin parent, so callers can read globals from every entry.
28
+ *
29
+ * @return {Window[]}
30
+ */
31
+ function getEditorWindowChain() {
32
+ const chain = [window];
33
+
34
+ try {
35
+ let win = window;
36
+
37
+ while (win.parent && win.parent !== win) {
38
+ win = win.parent;
39
+
40
+ if (!isReadableWindow(win)) {
41
+ break;
42
+ }
43
+
44
+ chain.push(win);
45
+ }
46
+ } catch {
47
+ // Keep whatever was collected before the error.
48
+ }
49
+
50
+ return chain;
51
+ }
52
+
53
+ /**
54
+ * @param {string} patternSlug Optional active pattern slug for best-match lookup.
55
+ * @return {Window}
56
+ */
57
+ export function getLocalizeWindow(patternSlug = "") {
58
+ const chain = getEditorWindowChain();
59
+
60
+ if (patternSlug) {
61
+ for (let i = chain.length - 1; i >= 0; i--) {
62
+ const url =
63
+ chain[i].kitaris_localize?.blocks?.editor_experience?.patterns
64
+ ?.pattern_urls?.[patternSlug];
65
+
66
+ if (url) {
67
+ return chain[i];
68
+ }
69
+ }
70
+
71
+ for (let i = chain.length - 1; i >= 0; i--) {
72
+ const patterns =
73
+ chain[i].kitaris_localize?.blocks?.editor_experience?.patterns;
74
+
75
+ if (patterns?.available_patterns?.[patternSlug]) {
76
+ return chain[i];
77
+ }
78
+ }
79
+ }
80
+
81
+ for (let i = chain.length - 1; i >= 0; i--) {
82
+ if (chain[i].kitaris_localize?.blocks?.editor_experience?.patterns) {
83
+ return chain[i];
84
+ }
85
+ }
86
+
87
+ return window;
88
+ }
89
+
90
+ /**
91
+ * @param {string} patternSlug
92
+ * @return {object|undefined}
93
+ */
94
+ export function getLocalize(patternSlug = "") {
95
+ return getLocalizeWindow(patternSlug).kitaris_localize;
96
+ }
97
+
98
+ /**
99
+ * @param {string} patternSlug
100
+ * @return {object|undefined}
101
+ */
102
+ export function getEditorExperiencePatterns(patternSlug = "") {
103
+ return getLocalize(patternSlug)?.blocks?.editor_experience?.patterns;
104
+ }
105
+
106
+ /**
107
+ * @return {object|undefined}
108
+ */
109
+ export function getEditorExperienceSectionDivider() {
110
+ const chain = getEditorWindowChain();
111
+
112
+ for (let i = chain.length - 1; i >= 0; i--) {
113
+ const sectionDivider =
114
+ chain[i].kitaris_localize?.blocks?.editor_experience?.section_divider;
115
+
116
+ if (sectionDivider) {
117
+ return sectionDivider;
118
+ }
119
+ }
120
+
121
+ return undefined;
122
+ }
123
+
124
+ // Backwards-compat aliases for the renamed functions.
125
+ /** @deprecated Use getLocalizeWindow instead. */
126
+ export const getKitarisLocalizeWindow = getLocalizeWindow;
127
+ /** @deprecated Use getLocalize instead. */
128
+ export const getKitarisLocalize = getLocalize;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * A withColors() setter that keeps the palette slug the user picked.
3
+ *
4
+ * withColors' own setters only receive the hex and save the first palette
5
+ * entry with that hex, so when two presets share a value (e.g. "white" and
6
+ * "primary-contrast" are both #ffffff) picking the second saves the first.
7
+ * The color dropdown also passes the slug, as core's color supports use it;
8
+ * save that directly and leave custom colors to the withColors setter.
9
+ *
10
+ * @param {Function} setAttributes Block attribute setter.
11
+ * @param {string} name Color attribute mapped in withColors().
12
+ * @param {Function} setter withColors' setter for that attribute.
13
+ * @return {Function} onColorChange handler: ( value, slug ) => void.
14
+ */
15
+ export function slugAwareColorSetter(setAttributes, name, setter) {
16
+ return (value, slug) => {
17
+ if (!value || !slug) {
18
+ setter(value);
19
+ return;
20
+ }
21
+
22
+ setAttributes({
23
+ [name]: slug,
24
+ [`custom${name.charAt(0).toUpperCase()}${name.slice(1)}`]: undefined,
25
+ });
26
+ };
27
+ }
@@ -1,20 +0,0 @@
1
- <?php return array(
2
- 'dependencies' => array(
3
- 'react',
4
- 'react-dom',
5
- 'react-jsx-runtime',
6
- 'wp-block-editor',
7
- 'wp-blocks',
8
- 'wp-components',
9
- 'wp-compose',
10
- 'wp-core-data',
11
- 'wp-data',
12
- 'wp-editor',
13
- 'wp-element',
14
- 'wp-hooks',
15
- 'wp-i18n',
16
- 'wp-keycodes',
17
- 'wp-media-utils'
18
- ),
19
- 'version' => 'ddaddbc0f9b3a1701879'
20
- );