create-wp-typia 0.1.0 → 1.0.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.
Files changed (91) hide show
  1. package/README.md +8 -28
  2. package/bin/create-wp-typia.js +3 -0
  3. package/package.json +9 -37
  4. package/dist/cli.js +0 -87837
  5. package/dist/highlights-eq9cgrbb.scm +0 -604
  6. package/dist/highlights-ghv9g403.scm +0 -205
  7. package/dist/highlights-hk7bwhj4.scm +0 -284
  8. package/dist/highlights-r812a2qc.scm +0 -150
  9. package/dist/highlights-x6tmsnaa.scm +0 -115
  10. package/dist/injections-73j83es3.scm +0 -27
  11. package/dist/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  12. package/dist/tree-sitter-markdown-411r6y9b.wasm +0 -0
  13. package/dist/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  14. package/dist/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  15. package/dist/tree-sitter-zig-e78zbjpm.wasm +0 -0
  16. package/lib/entry.js +0 -29
  17. package/lib/node-cli.js +0 -326
  18. package/lib/package-managers.d.ts +0 -29
  19. package/lib/package-managers.js +0 -170
  20. package/lib/scaffold.d.ts +0 -64
  21. package/lib/scaffold.js +0 -565
  22. package/lib/template-registry.d.ts +0 -18
  23. package/lib/template-registry.js +0 -58
  24. package/src/cli.ts +0 -329
  25. package/templates/advanced/README.md.mustache +0 -70
  26. package/templates/advanced/block.json.mustache +0 -42
  27. package/templates/advanced/index.js +0 -21
  28. package/templates/advanced/package.json.mustache +0 -48
  29. package/templates/advanced/scripts/generate-migrations.ts.mustache +0 -267
  30. package/templates/advanced/scripts/lib/typia-metadata-core.ts +0 -806
  31. package/templates/advanced/scripts/migration-cli.ts.mustache +0 -260
  32. package/templates/advanced/scripts/sync-types-to-block-json.ts.mustache +0 -25
  33. package/templates/advanced/src/admin/migration-dashboard.tsx.mustache +0 -450
  34. package/templates/advanced/src/components/ErrorBoundary.tsx.mustache +0 -47
  35. package/templates/advanced/src/deprecated.ts.mustache +0 -184
  36. package/templates/advanced/src/edit.tsx.mustache +0 -93
  37. package/templates/advanced/src/hooks/useDebounce.ts.mustache +0 -20
  38. package/templates/advanced/src/hooks/useLocalStorage.ts.mustache +0 -31
  39. package/templates/advanced/src/hooks.ts.mustache +0 -56
  40. package/templates/advanced/src/index.tsx.mustache +0 -16
  41. package/templates/advanced/src/migration-detector.ts.mustache +0 -417
  42. package/templates/advanced/src/migrations/index.ts.mustache +0 -361
  43. package/templates/advanced/src/save.tsx.mustache +0 -40
  44. package/templates/advanced/src/style.scss.mustache +0 -84
  45. package/templates/advanced/src/types/versions.ts.mustache +0 -108
  46. package/templates/advanced/src/types.ts.mustache +0 -45
  47. package/templates/advanced/src/utils/classnames.ts.mustache +0 -51
  48. package/templates/advanced/src/utils/debounce.ts.mustache +0 -37
  49. package/templates/advanced/src/utils/index.ts.mustache +0 -7
  50. package/templates/advanced/src/utils/uuid.ts.mustache +0 -17
  51. package/templates/advanced/src/validators.ts.mustache +0 -39
  52. package/templates/advanced/src/view.ts.mustache +0 -59
  53. package/templates/advanced/tsconfig.json.mustache +0 -9
  54. package/templates/advanced/webpack.config.js.mustache +0 -85
  55. package/templates/basic/package.json.mustache +0 -39
  56. package/templates/basic/scripts/lib/typia-metadata-core.ts +0 -806
  57. package/templates/basic/scripts/sync-types-to-block-json.ts +0 -25
  58. package/templates/basic/src/block.json +0 -51
  59. package/templates/basic/src/edit.tsx +0 -85
  60. package/templates/basic/src/hooks.ts +0 -75
  61. package/templates/basic/src/index.tsx +0 -37
  62. package/templates/basic/src/save.tsx +0 -27
  63. package/templates/basic/src/style.scss +0 -42
  64. package/templates/basic/src/types.ts +0 -47
  65. package/templates/basic/src/validators.ts +0 -39
  66. package/templates/basic/tsconfig.json +0 -20
  67. package/templates/basic/webpack.config.js +0 -85
  68. package/templates/full/package.json.mustache +0 -40
  69. package/templates/full/scripts/lib/typia-metadata-core.ts +0 -806
  70. package/templates/full/scripts/sync-types-to-block-json.ts.mustache +0 -25
  71. package/templates/full/src/block.json.mustache +0 -121
  72. package/templates/full/src/edit.tsx.mustache +0 -300
  73. package/templates/full/src/editor.scss.mustache +0 -251
  74. package/templates/full/src/hooks.ts.mustache +0 -140
  75. package/templates/full/src/index.tsx.mustache +0 -27
  76. package/templates/full/src/save.tsx.mustache +0 -39
  77. package/templates/full/src/style.scss.mustache +0 -224
  78. package/templates/full/src/types.ts.mustache +0 -34
  79. package/templates/full/src/validators.ts.mustache +0 -84
  80. package/templates/full/tsconfig.json.mustache +0 -9
  81. package/templates/full/webpack.config.js.mustache +0 -85
  82. package/templates/interactivity/package.json.mustache +0 -41
  83. package/templates/interactivity/scripts/lib/typia-metadata-core.ts +0 -806
  84. package/templates/interactivity/scripts/sync-types-to-block-json.ts.mustache +0 -25
  85. package/templates/interactivity/src/block.json.mustache +0 -75
  86. package/templates/interactivity/src/edit.tsx.mustache +0 -206
  87. package/templates/interactivity/src/interactivity.ts.mustache +0 -183
  88. package/templates/interactivity/src/save.tsx.mustache +0 -87
  89. package/templates/interactivity/src/types.ts.mustache +0 -29
  90. package/templates/interactivity/tsconfig.json.mustache +0 -9
  91. package/templates/interactivity/webpack.config.js.mustache +0 -85
@@ -1,25 +0,0 @@
1
- import { syncBlockMetadata } from "./lib/typia-metadata-core";
2
-
3
- async function main() {
4
- const result = await syncBlockMetadata({
5
- blockJsonFile: "src/block.json",
6
- manifestFile: "src/typia.manifest.json",
7
- sourceTypeName: "{{pascalCase}}Attributes",
8
- typesFile: "src/types.ts",
9
- });
10
-
11
- console.log("✅ block.json and typia.manifest.json were generated from TypeScript types!");
12
- console.log("📝 Generated attributes:", result.attributeNames);
13
-
14
- if (result.lossyProjectionWarnings.length > 0) {
15
- console.warn("⚠️ Some Typia constraints were preserved only in typia.manifest.json:");
16
- for (const warning of result.lossyProjectionWarnings) {
17
- console.warn(` - ${warning}`);
18
- }
19
- }
20
- }
21
-
22
- main().catch((error) => {
23
- console.error("❌ Type sync failed:", error);
24
- process.exit(1);
25
- });
@@ -1,121 +0,0 @@
1
- {
2
- "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 3,
4
- "name": "create-block/{{slugKebabCase}}",
5
- "version": "0.1.0",
6
- "title": "{{title}}",
7
- "category": "widgets",
8
- "icon": "smiley",
9
- "description": "{{description}}",
10
- "example": {},
11
- "supports": {
12
- "html": false,
13
- "align": true,
14
- "alignWide": true,
15
- "anchor": true,
16
- "className": true,
17
- "customClassName": true,
18
- "color": {
19
- "gradients": true,
20
- "link": true,
21
- "text": true,
22
- "background": true
23
- },
24
- "spacing": {
25
- "margin": true,
26
- "padding": true,
27
- "blockGap": true
28
- },
29
- "typography": {
30
- "fontSize": true,
31
- "lineHeight": true,
32
- "fontStyle": true,
33
- "fontWeight": true,
34
- "letterSpacing": true,
35
- "textAlign": true,
36
- "textDecoration": true,
37
- "textTransform": true,
38
- "writingMode": true
39
- },
40
- "dimensions": {
41
- "minHeight": true
42
- },
43
- "position": {
44
- "sticky": true,
45
- "fixed": true
46
- },
47
- "interactivity": true
48
- },
49
- "attributes": {
50
- "content": {
51
- "type": "string",
52
- "source": "html",
53
- "selector": ".{{cssClassName}}__content",
54
- "default": ""
55
- },
56
- "alignment": {
57
- "type": "string",
58
- "enum": ["left", "center", "right", "justify"],
59
- "default": "left"
60
- },
61
- "isVisible": {
62
- "type": "boolean",
63
- "default": true
64
- },
65
- "fontSize": {
66
- "type": "string",
67
- "enum": ["small", "medium", "large", "xlarge"],
68
- "default": "medium"
69
- },
70
- "textColor": {
71
- "type": "string",
72
- "default": ""
73
- },
74
- "backgroundColor": {
75
- "type": "string",
76
- "default": ""
77
- },
78
- "padding": {
79
- "type": "object",
80
- "default": {
81
- "top": 0,
82
- "right": 0,
83
- "bottom": 0,
84
- "left": 0
85
- }
86
- },
87
- "borderRadius": {
88
- "type": "number",
89
- "default": 0
90
- },
91
- "shadow": {
92
- "type": "object",
93
- "default": {
94
- "enabled": false,
95
- "x": 0,
96
- "y": 4,
97
- "blur": 8,
98
- "spread": 0,
99
- "color": "rgba(0, 0, 0, 0.1)"
100
- }
101
- },
102
- "animation": {
103
- "type": "string",
104
- "enum": ["none", "fadeIn", "slideUp", "slideDown", "zoomIn"],
105
- "default": "none"
106
- },
107
- "customCSS": {
108
- "type": "string",
109
- "default": ""
110
- },
111
- "uniqueId": {
112
- "type": "string",
113
- "default": ""
114
- }
115
- },
116
- "textdomain": "{{slugSnakeCase}}",
117
- "editorScript": "file:./index.js",
118
- "editorStyle": "file:./index.css",
119
- "style": "file:./style-index.css",
120
- "viewScript": "file:./view.js"
121
- }
@@ -1,300 +0,0 @@
1
- import { __ } from '@wordpress/i18n';
2
- import { useBlockProps, InspectorControls, RichText, BlockControls, AlignmentToolbar } from '@wordpress/block-editor';
3
- import { PanelBody, TextControl, SelectControl, ToggleControl, RangeControl, ColorPicker, ColorPalette, TabPanel, Disabled, Notice } from '@wordpress/components';
4
- import { useState, useEffect } from '@wordpress/element';
5
- import { use{{pascalCase}}Attributes, useColorScheme } from './hooks';
6
- import type { {{pascalCase}}Attributes } from './types';
7
-
8
- export default function Edit({ attributes, setAttributes, isSelected }: {
9
- attributes: {{pascalCase}}Attributes;
10
- setAttributes: (attrs: Partial<{{pascalCase}}Attributes>) => void;
11
- isSelected: boolean;
12
- }) {
13
- const { attributes: validatedAttrs, updateAttribute, validationErrors, isValid } = use{{pascalCase}}Attributes(attributes);
14
- const { getColorVariable } = useColorScheme();
15
- const [activeTab, setActiveTab] = useState('content');
16
-
17
- const blockProps = useBlockProps({
18
- className: `wp-block-{{slugKebabCase}} wp-block-{{slugKebabCase}}--${validatedAttrs.fontSize} wp-block-{{slugKebabCase}}--align-${validatedAttrs.alignment}`,
19
- style: {
20
- color: getColorVariable(validatedAttrs.textColor),
21
- backgroundColor: getColorVariable(validatedAttrs.backgroundColor),
22
- padding: `${validatedAttrs.padding.top}px ${validatedAttrs.padding.right}px ${validatedAttrs.padding.bottom}px ${validatedAttrs.padding.left}px`,
23
- borderRadius: `${validatedAttrs.borderRadius}px`,
24
- boxShadow: validatedAttrs.shadow.enabled
25
- ? `${validatedAttrs.shadow.x}px ${validatedAttrs.shadow.y}px ${validatedAttrs.shadow.blur}px ${validatedAttrs.shadow.spread}px ${validatedAttrs.shadow.color}`
26
- : 'none',
27
- display: validatedAttrs.isVisible ? 'block' : 'none',
28
- opacity: validatedAttrs.isVisible ? 1 : 0.5,
29
- }
30
- });
31
-
32
- useEffect(() => {
33
- if (isValid && validatedAttrs !== attributes) {
34
- setAttributes(validatedAttrs);
35
- }
36
- }, [validatedAttrs, isValid, attributes, setAttributes]);
37
-
38
- const contentTabs = [
39
- {
40
- name: 'content',
41
- title: __('Content', '{{slugSnakeCase}}'),
42
- className: 'tab-content'
43
- },
44
- {
45
- name: 'style',
46
- title: __('Style', '{{slugSnakeCase}}'),
47
- className: 'tab-style'
48
- },
49
- {
50
- name: 'advanced',
51
- title: __('Advanced', '{{slugSnakeCase}}'),
52
- className: 'tab-advanced'
53
- }
54
- ];
55
-
56
- return (
57
- <>
58
- <BlockControls>
59
- <AlignmentToolbar
60
- value={validatedAttrs.alignment}
61
- onChange={(value) => updateAttribute('alignment', value || 'left')}
62
- />
63
- </BlockControls>
64
-
65
- <InspectorControls>
66
- <TabPanel
67
- tabs={contentTabs}
68
- onSelect={setActiveTab}
69
- className="wp-block-{{slugKebabCase}}__tabs"
70
- >
71
- {(tab) => {
72
- if (tab.name === 'content') {
73
- return (
74
- <>
75
- <PanelBody title={__('Text Settings', '{{slugSnakeCase}}')}>
76
- <TextControl
77
- label={__('Unique ID', '{{slugSnakeCase}}')}
78
- value={validatedAttrs.uniqueId}
79
- onChange={(value) => updateAttribute('uniqueId', value)}
80
- help={__('Optional unique identifier for this block', '{{slugSnakeCase}}')}
81
- />
82
-
83
- <ToggleControl
84
- label={__('Visible', '{{slugSnakeCase}}')}
85
- checked={validatedAttrs.isVisible}
86
- onChange={(value) => updateAttribute('isVisible', value)}
87
- />
88
- </PanelBody>
89
-
90
- <PanelBody title={__('Typography', '{{slugSnakeCase}}')}>
91
- <SelectControl
92
- label={__('Font Size', '{{slugSnakeCase}}')}
93
- value={validatedAttrs.fontSize}
94
- options={[
95
- { label: __('Small', '{{slugSnakeCase}}'), value: 'small' },
96
- { label: __('Medium', '{{slugSnakeCase}}'), value: 'medium' },
97
- { label: __('Large', '{{slugSnakeCase}}'), value: 'large' },
98
- { label: __('Extra Large', '{{slugSnakeCase}}'), value: 'xlarge' },
99
- ]}
100
- onChange={(value) => updateAttribute('fontSize', value)}
101
- />
102
- </PanelBody>
103
- </>
104
- );
105
- }
106
-
107
- if (tab.name === 'style') {
108
- return (
109
- <>
110
- <PanelBody title={__('Colors', '{{slugSnakeCase}}')}>
111
- <div className="components-base-control">
112
- <label className="components-base-control__label">
113
- {__('Text Color', '{{slugSnakeCase}}')}
114
- </label>
115
- <ColorPalette
116
- value={validatedAttrs.textColor}
117
- onChange={(value) => updateAttribute('textColor', value)}
118
- disableCustomColors={false}
119
- clearable={true}
120
- />
121
- </div>
122
-
123
- <div className="components-base-control" style={{ marginTop: '1em' }}>
124
- <label className="components-base-control__label">
125
- {__('Background Color', '{{slugSnakeCase}}')}
126
- </label>
127
- <ColorPalette
128
- value={validatedAttrs.backgroundColor}
129
- onChange={(value) => updateAttribute('backgroundColor', value)}
130
- disableCustomColors={false}
131
- clearable={true}
132
- />
133
- </div>
134
- </PanelBody>
135
-
136
- <PanelBody title={__('Spacing', '{{slugSnakeCase}}')}>
137
- <RangeControl
138
- label={__('Border Radius', '{{slugSnakeCase}}')}
139
- value={validatedAttrs.borderRadius}
140
- onChange={(value) => updateAttribute('borderRadius', value)}
141
- min={0}
142
- max={50}
143
- />
144
-
145
- <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1em', marginTop: '1em' }}>
146
- <RangeControl
147
- label={__('Padding Top', '{{slugSnakeCase}}')}
148
- value={validatedAttrs.padding.top}
149
- onChange={(value) => updateAttribute('padding', { ...validatedAttrs.padding, top: value })}
150
- min={0}
151
- max={100}
152
- />
153
- <RangeControl
154
- label={__('Padding Right', '{{slugSnakeCase}}')}
155
- value={validatedAttrs.padding.right}
156
- onChange={(value) => updateAttribute('padding', { ...validatedAttrs.padding, right: value })}
157
- min={0}
158
- max={100}
159
- />
160
- <RangeControl
161
- label={__('Padding Bottom', '{{slugSnakeCase}}')}
162
- value={validatedAttrs.padding.bottom}
163
- onChange={(value) => updateAttribute('padding', { ...validatedAttrs.padding, bottom: value })}
164
- min={0}
165
- max={100}
166
- />
167
- <RangeControl
168
- label={__('Padding Left', '{{slugSnakeCase}}')}
169
- value={validatedAttrs.padding.left}
170
- onChange={(value) => updateAttribute('padding', { ...validatedAttrs.padding, left: value })}
171
- min={0}
172
- max={100}
173
- />
174
- </div>
175
- </PanelBody>
176
-
177
- <PanelBody title={__('Shadow', '{{slugSnakeCase}}')}>
178
- <ToggleControl
179
- label={__('Enable Shadow', '{{slugSnakeCase}}')}
180
- checked={validatedAttrs.shadow.enabled}
181
- onChange={(value) => updateAttribute('shadow', { ...validatedAttrs.shadow, enabled: value })}
182
- />
183
-
184
- {validatedAttrs.shadow.enabled && (
185
- <>
186
- <RangeControl
187
- label={__('Horizontal Offset', '{{slugSnakeCase}}')}
188
- value={validatedAttrs.shadow.x}
189
- onChange={(value) => updateAttribute('shadow', { ...validatedAttrs.shadow, x: value })}
190
- min={-50}
191
- max={50}
192
- />
193
- <RangeControl
194
- label={__('Vertical Offset', '{{slugSnakeCase}}')}
195
- value={validatedAttrs.shadow.y}
196
- onChange={(value) => updateAttribute('shadow', { ...validatedAttrs.shadow, y: value })}
197
- min={-50}
198
- max={50}
199
- />
200
- <RangeControl
201
- label={__('Blur', '{{slugSnakeCase}}')}
202
- value={validatedAttrs.shadow.blur}
203
- onChange={(value) => updateAttribute('shadow', { ...validatedAttrs.shadow, blur: value })}
204
- min={0}
205
- max={100}
206
- />
207
- <RangeControl
208
- label={__('Spread', '{{slugSnakeCase}}')}
209
- value={validatedAttrs.shadow.spread}
210
- onChange={(value) => updateAttribute('shadow', { ...validatedAttrs.shadow, spread: value })}
211
- min={-50}
212
- max={50}
213
- />
214
- <div className="components-base-control">
215
- <label className="components-base-control__label">
216
- {__('Shadow Color', '{{slugSnakeCase}}')}
217
- </label>
218
- <ColorPicker
219
- color={validatedAttrs.shadow.color}
220
- onChangeComplete={(value) => updateAttribute('shadow', { ...validatedAttrs.shadow, color: value.hex })}
221
- disableAlpha={false}
222
- />
223
- </div>
224
- </>
225
- )}
226
- </PanelBody>
227
-
228
- <PanelBody title={__('Animation', '{{slugSnakeCase}}')}>
229
- <SelectControl
230
- label={__('Animation Type', '{{slugSnakeCase}}')}
231
- value={validatedAttrs.animation}
232
- options={[
233
- { label: __('None', '{{slugSnakeCase}}'), value: 'none' },
234
- { label: __('Fade In', '{{slugSnakeCase}}'), value: 'fadeIn' },
235
- { label: __('Slide Up', '{{slugSnakeCase}}'), value: 'slideUp' },
236
- { label: __('Slide Down', '{{slugSnakeCase}}'), value: 'slideDown' },
237
- { label: __('Zoom In', '{{slugSnakeCase}}'), value: 'zoomIn' },
238
- ]}
239
- onChange={(value) => updateAttribute('animation', value)}
240
- />
241
- </PanelBody>
242
- </>
243
- );
244
- }
245
-
246
- if (tab.name === 'advanced') {
247
- return (
248
- <>
249
- <PanelBody title={__('Advanced', '{{slugSnakeCase}}')}>
250
- {!isValid && validationErrors.length > 0 && (
251
- <Notice status="error" isDismissible={false}>
252
- <strong>{__('Validation Errors:', '{{slugSnakeCase}}')}</strong>
253
- <ul>
254
- {validationErrors.map((error, index) => (
255
- <li key={index}>{error}</li>
256
- ))}
257
- </ul>
258
- </Notice>
259
- )}
260
-
261
- <TextControl
262
- label={__('Custom CSS', '{{slugSnakeCase}}')}
263
- value={validatedAttrs.customCSS}
264
- onChange={(value) => updateAttribute('customCSS', value)}
265
- multiline={5}
266
- help={__('Add custom CSS classes or inline styles', '{{slugSnakeCase}}')}
267
- />
268
- </PanelBody>
269
- </>
270
- );
271
- }
272
-
273
- return null;
274
- }}
275
- </TabPanel>
276
- </InspectorControls>
277
-
278
- <div {...blockProps}>
279
- {isSelected && validatedAttrs.animation !== 'none' && (
280
- <div className="wp-block-{{slugKebabCase}}__animation-preview">
281
- {__('Animation Preview:', '{{slugSnakeCase}}')} {validatedAttrs.animation}
282
- </div>
283
- )}
284
-
285
- <div
286
- className={`{{cssClassName}}__content {{cssClassName}}__content--${validatedAttrs.fontSize}`}
287
- style={{ textAlign: validatedAttrs.alignment }}
288
- >
289
- <RichText
290
- tagName="p"
291
- value={validatedAttrs.content}
292
- onChange={(value) => updateAttribute('content', value)}
293
- placeholder={__('{{title}} – hello from the editor!', '{{slugSnakeCase}}')}
294
- allowedFormats={['core/bold', 'core/italic', 'core/link', 'core/strikethrough']}
295
- />
296
- </div>
297
- </div>
298
- </>
299
- );
300
- }
@@ -1,251 +0,0 @@
1
- /**
2
- * {{title}} Block Editor Styles
3
- */
4
-
5
- .wp-block-{{slugKebabCase}} {
6
- // Editor-specific styles
7
- border: 1px dashed #e0e0e0;
8
- padding: 1em;
9
- min-height: 60px;
10
- position: relative;
11
-
12
- // Visual indicator when block is selected
13
- &.is-selected {
14
- border-color: var(--wp-admin-theme-color, #0073aa);
15
- background-color: rgba(var(--wp-admin-theme-color--rgb, 0, 115, 170), 0.04);
16
- }
17
-
18
- // Animation preview indicator
19
- &__animation-preview {
20
- position: absolute;
21
- top: -30px;
22
- left: 0;
23
- font-size: 11px;
24
- color: #757575;
25
- background: #fff;
26
- padding: 2px 6px;
27
- border-radius: 2px;
28
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
29
- z-index: 10;
30
- }
31
-
32
- // Content editor styles
33
- .{{cssClassName}}__content {
34
- min-height: 1em;
35
-
36
- // Rich text editor styles
37
- .block-editor-rich-text__editable {
38
- outline: none;
39
-
40
- &:focus {
41
- box-shadow: 0 0 0 1px var(--wp-admin-theme-color, #0073aa);
42
- border-radius: 2px;
43
- padding: 0 2px;
44
- }
45
-
46
- // Placeholder styles
47
- &[data-is-placeholder-visible="true"] {
48
- color: #757575;
49
- font-style: italic;
50
- }
51
- }
52
-
53
- // Link styles in editor
54
- a {
55
- color: var(--wp-admin-theme-color, #0073aa);
56
- text-decoration: underline;
57
-
58
- &:hover {
59
- color: var(--wp-admin-theme-color--hover, #005a87);
60
- }
61
- }
62
- }
63
-
64
- // Tab panel styles in inspector
65
- &__tabs {
66
- .components-tab-panel__tabs {
67
- border-bottom: 1px solid #e0e0e0;
68
- margin-bottom: 1em;
69
- }
70
-
71
- .components-tab-panel__tab {
72
- padding: 0.5em 1em;
73
- margin-bottom: -1px;
74
- border-bottom: 2px solid transparent;
75
- cursor: pointer;
76
-
77
- &:hover {
78
- background-color: #f5f5f5;
79
- }
80
-
81
- &.is-active-tab {
82
- border-bottom-color: var(--wp-admin-theme-color, #0073aa);
83
- color: var(--wp-admin-theme-color, #0073aa);
84
- }
85
- }
86
- }
87
-
88
- // Inspector controls enhancements
89
- .components-panel__body {
90
- .components-base-control {
91
- margin-bottom: 1em;
92
-
93
- &:last-child {
94
- margin-bottom: 0;
95
- }
96
- }
97
-
98
- // Color picker enhancements
99
- .components-color-picker {
100
- margin-top: 0.5em;
101
- }
102
-
103
- // Range control enhancements
104
- .components-range-control {
105
- .components-range-control__slider {
106
- margin: 0 10px;
107
- }
108
-
109
- .components-range-control__number {
110
- width: 60px;
111
- }
112
- }
113
-
114
- // Toggle control enhancements
115
- .components-toggle-control {
116
- .components-toggle-control__label {
117
- font-weight: 500;
118
- }
119
- }
120
- }
121
-
122
- // Validation error styles
123
- .components-notice {
124
- &.is-error {
125
- border-left-color: #cc1818;
126
- background-color: #fcf0f1;
127
-
128
- ul {
129
- margin: 0.5em 0;
130
- padding-left: 1.5em;
131
-
132
- li {
133
- margin-bottom: 0.25em;
134
- font-size: 12px;
135
- }
136
- }
137
- }
138
- }
139
-
140
- // Shadow preview
141
- &__shadow-preview {
142
- width: 100%;
143
- height: 60px;
144
- border: 1px solid #e0e0e0;
145
- border-radius: 4px;
146
- margin-top: 0.5em;
147
- display: flex;
148
- align-items: center;
149
- justify-content: center;
150
- background: white;
151
- position: relative;
152
- overflow: hidden;
153
-
154
- &::before {
155
- content: '';
156
- position: absolute;
157
- top: 50%;
158
- left: 50%;
159
- transform: translate(-50%, -50%);
160
- width: 30px;
161
- height: 30px;
162
- background: var(--wp-admin-theme-color, #0073aa);
163
- border-radius: 4px;
164
- }
165
- }
166
-
167
- // Padding preview
168
- &__padding-preview {
169
- display: grid;
170
- grid-template-columns: 1fr 1fr;
171
- grid-template-rows: 1fr 1fr;
172
- gap: 5px;
173
- width: 120px;
174
- height: 120px;
175
- margin: 1em auto;
176
- border: 1px solid #e0e0e0;
177
-
178
- > div {
179
- background: #f5f5f5;
180
- display: flex;
181
- align-items: center;
182
- justify-content: center;
183
- font-size: 10px;
184
- color: #757575;
185
-
186
- &.center {
187
- background: var(--wp-admin-theme-color, #0073aa);
188
- color: white;
189
- }
190
- }
191
- }
192
-
193
- // Block appender styles
194
- &.block-list-appender {
195
- min-height: 100px;
196
- display: flex;
197
- align-items: center;
198
- justify-content: center;
199
- border: 2px dashed #e0e0e0;
200
- background: #f9f9f9;
201
- cursor: pointer;
202
-
203
- &:hover {
204
- border-color: var(--wp-admin-theme-color, #0073aa);
205
- background: rgba(var(--wp-admin-theme-color--rgb, 0, 115, 170), 0.04);
206
- }
207
-
208
- .block-list-appender__toggle {
209
- margin: 0;
210
- }
211
- }
212
-
213
- // Multi-selection styles
214
- &.is-multi-selected {
215
- background-color: rgba(var(--wp-admin-theme-color--rgb, 0, 115, 170), 0.08);
216
- border-color: var(--wp-admin-theme-color, #0073aa);
217
- }
218
-
219
- // Highlight when dragging
220
- &.is-dragging {
221
- opacity: 0.5;
222
- }
223
-
224
- // Drop zone indicator
225
- &.is-drop-target {
226
- background-color: rgba(var(--wp-admin-theme-color--rgb, 0, 115, 170), 0.12);
227
- border-color: var(--wp-admin-theme-color, #0073aa);
228
- border-style: solid;
229
- }
230
-
231
- // Responsive preview in editor
232
- @media (max-width: 768px) {
233
- padding: 0.5em;
234
- min-height: 40px;
235
-
236
- .{{cssClassName}}__content {
237
- font-size: 0.9em;
238
- }
239
- }
240
- }
241
-
242
- // Block toolbar styles
243
- .block-editor-block-toolbar {
244
- .wp-block-{{slugKebab-case}}__toolbar {
245
- .components-button {
246
- font-size: 12px;
247
- padding: 0 6px;
248
- height: 32px;
249
- }
250
- }
251
- }