@times-design-system/components-wordpress 1.4.0 → 1.5.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/BLOCK_CREATION_CHECKLIST.md +124 -12
- package/CHANGELOG.md +6 -0
- package/README.md +46 -29
- package/TESTING.md +152 -0
- package/dist/blocks/dialog-box/block.json +24 -0
- package/dist/blocks/dialog-box/edit.js +41 -0
- package/dist/blocks/dialog-box/index.js +17 -0
- package/dist/blocks/dialog-box/render.php +24 -0
- package/dist/blocks/dialog-box/save.js +23 -0
- package/dist/blocks/dialog-box/style.css +23 -0
- package/dist/blocks/icon/block.json +24 -0
- package/dist/blocks/icon/edit.js +41 -0
- package/dist/blocks/icon/index.js +17 -0
- package/dist/blocks/icon/render.php +24 -0
- package/dist/blocks/icon/save.js +23 -0
- package/dist/blocks/icon/style.css +23 -0
- package/dist/blocks/input-helper-message/block.json +24 -0
- package/dist/blocks/input-helper-message/edit.js +42 -0
- package/dist/blocks/input-helper-message/index.js +17 -0
- package/dist/blocks/input-helper-message/render.php +24 -0
- package/dist/blocks/input-helper-message/save.js +23 -0
- package/dist/blocks/input-helper-message/style.css +23 -0
- package/dist/blocks/tab/block.json +24 -0
- package/dist/blocks/tab/edit.js +41 -0
- package/dist/blocks/tab/index.js +17 -0
- package/dist/blocks/tab/render.php +24 -0
- package/dist/blocks/tab/save.js +23 -0
- package/dist/blocks/tab/style.css +23 -0
- package/dist/blocks/tab-group/block.json +24 -0
- package/dist/blocks/tab-group/edit.js +41 -0
- package/dist/blocks/tab-group/index.js +17 -0
- package/dist/blocks/tab-group/render.php +24 -0
- package/dist/blocks/tab-group/save.js +23 -0
- package/dist/blocks/tab-group/style.css +23 -0
- package/dist/vitest.config.d.ts +2 -0
- package/dist/vitest.setup.d.ts +1 -0
- package/package.json +21 -5
- package/scripts/create-wordpress-block-tests.cjs +438 -0
- package/scripts/create-wordpress-block.cjs +681 -0
- package/src/blocks/dialog-box/block.json +24 -0
- package/src/blocks/dialog-box/edit.js +41 -0
- package/src/blocks/dialog-box/index.js +17 -0
- package/src/blocks/dialog-box/render.php +24 -0
- package/src/blocks/dialog-box/save.js +23 -0
- package/src/blocks/dialog-box/style.css +23 -0
- package/src/blocks/icon/block.json +24 -0
- package/src/blocks/icon/edit.js +41 -0
- package/src/blocks/icon/index.js +17 -0
- package/src/blocks/icon/render.php +24 -0
- package/src/blocks/icon/save.js +23 -0
- package/src/blocks/icon/style.css +23 -0
- package/src/blocks/input-helper-message/block.json +24 -0
- package/src/blocks/input-helper-message/edit.js +42 -0
- package/src/blocks/input-helper-message/index.js +17 -0
- package/src/blocks/input-helper-message/render.php +24 -0
- package/src/blocks/input-helper-message/save.js +23 -0
- package/src/blocks/input-helper-message/style.css +23 -0
- package/src/blocks/tab/block.json +24 -0
- package/src/blocks/tab/edit.js +41 -0
- package/src/blocks/tab/index.js +17 -0
- package/src/blocks/tab/render.php +24 -0
- package/src/blocks/tab/save.js +23 -0
- package/src/blocks/tab/style.css +23 -0
- package/src/blocks/tab-group/block.json +24 -0
- package/src/blocks/tab-group/edit.js +41 -0
- package/src/blocks/tab-group/index.js +17 -0
- package/src/blocks/tab-group/render.php +24 -0
- package/src/blocks/tab-group/save.js +23 -0
- package/src/blocks/tab-group/style.css +23 -0
- package/vitest.config.js +28 -0
- package/vitest.config.ts +28 -0
- package/vitest.setup.ts +129 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block Editor Component: TabGroup
|
|
3
|
+
*
|
|
4
|
+
* Renders the editor UI for the TabGroup block in Gutenberg.
|
|
5
|
+
* Reference: packages/components-react/src/TabGroup/
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
|
|
9
|
+
import { PanelBody, TextControl } from '@wordpress/components';
|
|
10
|
+
|
|
11
|
+
export function edit(props) {
|
|
12
|
+
const { attributes, setAttributes } = props;
|
|
13
|
+
const blockProps = useBlockProps();
|
|
14
|
+
|
|
15
|
+
// TODO: Implement editor UI based on component props
|
|
16
|
+
// - Add inspector controls for attributes
|
|
17
|
+
// - Render preview of component in editor
|
|
18
|
+
// - Handle attribute changes via setAttributes()
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<InspectorControls>
|
|
23
|
+
<PanelBody title="TabGroup Settings" initialOpen={true}>
|
|
24
|
+
<TextControl
|
|
25
|
+
label="Content"
|
|
26
|
+
value={attributes.content || ''}
|
|
27
|
+
onChange={(content) => setAttributes({ content })}
|
|
28
|
+
placeholder="Enter content..."
|
|
29
|
+
/>
|
|
30
|
+
{/* TODO: Add more controls based on component variants */}
|
|
31
|
+
</PanelBody>
|
|
32
|
+
</InspectorControls>
|
|
33
|
+
<div {...blockProps}>
|
|
34
|
+
<p>📝 TabGroup block editor</p>
|
|
35
|
+
<p style={{ fontSize: '12px', color: '#666' }}>
|
|
36
|
+
TODO: Render the TabGroup component here with current attributes
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
</>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress Block Loader: TabGroup
|
|
3
|
+
*
|
|
4
|
+
* Reference: packages/components-react/src/TabGroup/
|
|
5
|
+
* TODO: Update attributes in block.json based on component props
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { registerBlockType } from '@wordpress/blocks';
|
|
9
|
+
import { edit as Edit } from './edit';
|
|
10
|
+
import { save as Save } from './save';
|
|
11
|
+
import blockConfig from './block.json';
|
|
12
|
+
|
|
13
|
+
registerBlockType(blockConfig.name, {
|
|
14
|
+
...blockConfig,
|
|
15
|
+
edit: Edit,
|
|
16
|
+
save: Save
|
|
17
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Block Rendering: TabGroup
|
|
4
|
+
*
|
|
5
|
+
* Server-side rendering for the TabGroup block.
|
|
6
|
+
* Reference: packages/components-react/src/TabGroup/
|
|
7
|
+
*
|
|
8
|
+
* @param array $attributes Block attributes
|
|
9
|
+
* @param string $content Saved block content
|
|
10
|
+
* @param WP_Block $block The block instance
|
|
11
|
+
* @return string Rendered HTML
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
$wrapper_attributes = get_block_wrapper_attributes();
|
|
15
|
+
|
|
16
|
+
// TODO: Render the TabGroup component
|
|
17
|
+
// Extract attributes and render appropriate HTML with BEM classes
|
|
18
|
+
|
|
19
|
+
?>
|
|
20
|
+
<div <?php echo wp_kses_post( $wrapper_attributes ); ?>>
|
|
21
|
+
<!-- TODO: Render TabGroup component here -->
|
|
22
|
+
<!-- Use CSS custom properties from packages/tokens/data/resolved-hexes.json -->
|
|
23
|
+
<!-- Apply BEM naming: tds-tab-group--{modifier} -->
|
|
24
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block Save Component: TabGroup
|
|
3
|
+
*
|
|
4
|
+
* Renders the static output saved to the database.
|
|
5
|
+
* Reference: packages/components-react/src/TabGroup/
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useBlockProps } from '@wordpress/block-editor';
|
|
9
|
+
|
|
10
|
+
export function save(props) {
|
|
11
|
+
const { attributes } = props;
|
|
12
|
+
const blockProps = useBlockProps.save();
|
|
13
|
+
|
|
14
|
+
// TODO: Render the actual TabGroup component with attributes
|
|
15
|
+
// This output is saved to the database and displayed on the frontend
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div {...blockProps}>
|
|
19
|
+
{/* TODO: Render TabGroup component */}
|
|
20
|
+
{attributes.content && <p>{attributes.content}</p>}
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Styles for TabGroup Block
|
|
3
|
+
*
|
|
4
|
+
* Reference: packages/components-react/src/TabGroup/
|
|
5
|
+
* Token Reference: packages/tokens/data/resolved-hexes.json
|
|
6
|
+
*
|
|
7
|
+
* TODO: Adapt styles from React component
|
|
8
|
+
* - Copy relevant CSS from React component
|
|
9
|
+
* - Map CSS custom properties to resolved hex values
|
|
10
|
+
* - Use BEM naming: .tds-tab-group--{modifier}
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
.tds-tab-group {
|
|
14
|
+
/* TODO: Add component styles here */
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.tds-tab-group--focus {
|
|
18
|
+
/* TODO: Add focus state styles */
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.tds-tab-group--disabled {
|
|
22
|
+
/* TODO: Add disabled state styles */
|
|
23
|
+
}
|
package/vitest.config.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'jsdom',
|
|
7
|
+
setupFiles: ['./vitest.setup.ts'],
|
|
8
|
+
pool: 'forks',
|
|
9
|
+
include: ['./__tests__/**/*.test.{js,jsx,ts,tsx}'],
|
|
10
|
+
coverage: {
|
|
11
|
+
provider: 'v8',
|
|
12
|
+
reporter: ['text', 'json', 'html'],
|
|
13
|
+
exclude: [
|
|
14
|
+
'node_modules/',
|
|
15
|
+
'dist/',
|
|
16
|
+
'**/*.d.ts',
|
|
17
|
+
'**/*.test.ts',
|
|
18
|
+
'**/*.test.tsx',
|
|
19
|
+
'**/*.test.js',
|
|
20
|
+
'**/*.test.jsx'
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
resolve: {
|
|
25
|
+
extensions: ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs'],
|
|
26
|
+
conditions: ['node']
|
|
27
|
+
}
|
|
28
|
+
});
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'jsdom',
|
|
7
|
+
setupFiles: ['./vitest.setup.ts'],
|
|
8
|
+
pool: 'forks',
|
|
9
|
+
include: ['./__tests__/**/*.test.{js,jsx,ts,tsx}'],
|
|
10
|
+
coverage: {
|
|
11
|
+
provider: 'v8',
|
|
12
|
+
reporter: ['text', 'json', 'html'],
|
|
13
|
+
exclude: [
|
|
14
|
+
'node_modules/',
|
|
15
|
+
'dist/',
|
|
16
|
+
'**/*.d.ts',
|
|
17
|
+
'**/*.test.ts',
|
|
18
|
+
'**/*.test.tsx',
|
|
19
|
+
'**/*.test.js',
|
|
20
|
+
'**/*.test.jsx'
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
resolve: {
|
|
25
|
+
extensions: ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs'],
|
|
26
|
+
conditions: ['node']
|
|
27
|
+
}
|
|
28
|
+
});
|
package/vitest.setup.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
2
|
+
import { expect, afterEach, beforeEach, vi } from 'vitest';
|
|
3
|
+
import { cleanup } from '@testing-library/react';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
interface MockProps {
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface MockSelectOption {
|
|
12
|
+
value: string;
|
|
13
|
+
label: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface MockSelectControlProps {
|
|
17
|
+
value: string;
|
|
18
|
+
onChange: (value: string) => void;
|
|
19
|
+
options?: MockSelectOption[];
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface MockTextControlProps {
|
|
24
|
+
value: string;
|
|
25
|
+
onChange: (value: string) => void;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface MockToggleControlProps {
|
|
30
|
+
checked: boolean;
|
|
31
|
+
onChange: (checked: boolean) => void;
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface MockRichTextProps {
|
|
36
|
+
value: string;
|
|
37
|
+
onChange: (value: string) => void;
|
|
38
|
+
[key: string]: unknown;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Mock WordPress block editor
|
|
42
|
+
vi.mock('@wordpress/block-editor', () => ({
|
|
43
|
+
useBlockProps: vi.fn(() => ({ className: 'wp-block' })),
|
|
44
|
+
InspectorControls: ({ children }: MockProps) =>
|
|
45
|
+
React.createElement(
|
|
46
|
+
'div',
|
|
47
|
+
{ 'data-testid': 'inspector-controls' },
|
|
48
|
+
children
|
|
49
|
+
),
|
|
50
|
+
RichText: ({ value, onChange, ...props }: MockRichTextProps) =>
|
|
51
|
+
React.createElement(
|
|
52
|
+
'div',
|
|
53
|
+
{
|
|
54
|
+
...props,
|
|
55
|
+
'data-testid': 'rich-text',
|
|
56
|
+
contentEditable: true
|
|
57
|
+
},
|
|
58
|
+
value
|
|
59
|
+
)
|
|
60
|
+
}));
|
|
61
|
+
|
|
62
|
+
// Mock WordPress components
|
|
63
|
+
vi.mock('@wordpress/components', () => ({
|
|
64
|
+
PanelBody: ({ children }: MockProps) =>
|
|
65
|
+
React.createElement('div', { 'data-testid': 'panel-body' }, children),
|
|
66
|
+
SelectControl: ({ value, onChange, options }: MockSelectControlProps) =>
|
|
67
|
+
React.createElement(
|
|
68
|
+
'select',
|
|
69
|
+
{
|
|
70
|
+
value,
|
|
71
|
+
onChange: (e: React.ChangeEvent<HTMLSelectElement>) =>
|
|
72
|
+
onChange(e.target.value),
|
|
73
|
+
'data-testid': 'select-control'
|
|
74
|
+
},
|
|
75
|
+
options?.map((opt: MockSelectOption) =>
|
|
76
|
+
React.createElement(
|
|
77
|
+
'option',
|
|
78
|
+
{ key: opt.value, value: opt.value },
|
|
79
|
+
opt.label
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
),
|
|
83
|
+
TextControl: ({ value, onChange }: MockTextControlProps) =>
|
|
84
|
+
React.createElement('input', {
|
|
85
|
+
type: 'text',
|
|
86
|
+
value,
|
|
87
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement>) =>
|
|
88
|
+
onChange(e.target.value),
|
|
89
|
+
'data-testid': 'text-control'
|
|
90
|
+
}),
|
|
91
|
+
ToggleControl: ({ checked, onChange }: MockToggleControlProps) =>
|
|
92
|
+
React.createElement('input', {
|
|
93
|
+
type: 'checkbox',
|
|
94
|
+
checked,
|
|
95
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement>) =>
|
|
96
|
+
onChange(e.target.checked),
|
|
97
|
+
'data-testid': 'toggle-control'
|
|
98
|
+
})
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
// Mock WordPress element
|
|
102
|
+
vi.mock(
|
|
103
|
+
'@wordpress/element',
|
|
104
|
+
() => ({
|
|
105
|
+
Fragment: ({ children }: MockProps) => children
|
|
106
|
+
}),
|
|
107
|
+
{ esmock: true }
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Mock WordPress blocks
|
|
111
|
+
vi.mock('@wordpress/blocks', () => ({
|
|
112
|
+
registerBlockType: vi.fn()
|
|
113
|
+
}));
|
|
114
|
+
|
|
115
|
+
// Cleanup after each test
|
|
116
|
+
afterEach(() => {
|
|
117
|
+
cleanup();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Mock console methods to reduce noise during tests
|
|
121
|
+
beforeEach(() => {
|
|
122
|
+
vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
123
|
+
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
afterEach(() => {
|
|
127
|
+
console.warn.mockRestore?.();
|
|
128
|
+
console.error.mockRestore?.();
|
|
129
|
+
});
|