@times-design-system/components-wordpress 0.4.0 → 1.2.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 (189) hide show
  1. package/BLOCK_CREATION_CHECKLIST.md +160 -0
  2. package/BUILD.md +411 -0
  3. package/CHANGELOG.md +32 -0
  4. package/LICENSE +29 -0
  5. package/README.md +972 -5
  6. package/TRANSFORMATION_GUIDE.md +635 -0
  7. package/block.json +10 -0
  8. package/dist/block.json +10 -0
  9. package/dist/blocks/ad-container/block.json +28 -0
  10. package/dist/blocks/ad-container/edit.js +42 -0
  11. package/dist/blocks/ad-container/index.js +10 -0
  12. package/dist/blocks/ad-container/save.js +16 -0
  13. package/dist/blocks/ad-container/style-editor.css +4 -0
  14. package/dist/blocks/ad-container/style.css +27 -0
  15. package/dist/blocks/button/block.json +89 -0
  16. package/dist/blocks/button/edit.js +187 -0
  17. package/dist/blocks/button/index.js +11 -0
  18. package/dist/blocks/button/save.js +52 -0
  19. package/dist/blocks/button/style-editor.css +15 -0
  20. package/dist/blocks/button/style.css +37 -0
  21. package/dist/blocks/chip/block.json +57 -0
  22. package/dist/blocks/chip/edit.js +113 -0
  23. package/dist/blocks/chip/index.js +10 -0
  24. package/dist/blocks/chip/save.js +36 -0
  25. package/dist/blocks/chip/style-editor.css +5 -0
  26. package/dist/blocks/chip/style.css +48 -0
  27. package/dist/blocks/divider/block.json +31 -0
  28. package/dist/blocks/divider/edit.js +42 -0
  29. package/dist/blocks/divider/index.js +10 -0
  30. package/dist/blocks/divider/save.js +18 -0
  31. package/dist/blocks/divider/style-editor.css +4 -0
  32. package/dist/blocks/divider/style.css +25 -0
  33. package/dist/blocks/flag/block.json +48 -0
  34. package/dist/blocks/flag/edit.js +82 -0
  35. package/dist/blocks/flag/index.js +10 -0
  36. package/dist/blocks/flag/save.js +25 -0
  37. package/dist/blocks/flag/style-editor.css +5 -0
  38. package/dist/blocks/flag/style.css +45 -0
  39. package/dist/blocks/icon-button/block.json +43 -0
  40. package/dist/blocks/icon-button/edit.js +82 -0
  41. package/dist/blocks/icon-button/index.js +10 -0
  42. package/dist/blocks/icon-button/save.js +29 -0
  43. package/dist/blocks/icon-button/style-editor.css +5 -0
  44. package/dist/blocks/icon-button/style.css +32 -0
  45. package/dist/blocks/input/block.json +47 -0
  46. package/dist/blocks/input/edit.js +78 -0
  47. package/dist/blocks/input/index.js +10 -0
  48. package/dist/blocks/input/save.js +27 -0
  49. package/dist/blocks/input/style-editor.css +8 -0
  50. package/dist/blocks/input/style.css +30 -0
  51. package/dist/blocks/link/block.json +71 -0
  52. package/dist/blocks/link/edit.js +151 -0
  53. package/dist/blocks/link/index.js +10 -0
  54. package/dist/blocks/link/save.js +46 -0
  55. package/dist/blocks/link/style-editor.css +5 -0
  56. package/dist/blocks/link/style.css +66 -0
  57. package/dist/blocks/text/block.json +32 -0
  58. package/dist/blocks/text/edit.js +56 -0
  59. package/dist/blocks/text/index.js +10 -0
  60. package/dist/blocks/text/save.js +18 -0
  61. package/dist/blocks/text/style-editor.css +4 -0
  62. package/dist/blocks/text/style.css +20 -0
  63. package/dist/blocks/toast/block.json +39 -0
  64. package/dist/blocks/toast/edit.js +85 -0
  65. package/dist/blocks/toast/index.js +10 -0
  66. package/dist/blocks/toast/save.js +29 -0
  67. package/dist/blocks/toast/style-editor.css +4 -0
  68. package/dist/blocks/toast/style.css +51 -0
  69. package/dist/index.cjs +2232 -0
  70. package/dist/index.cjs.map +1 -0
  71. package/dist/index.css +2 -0
  72. package/dist/index.css.map +1 -0
  73. package/dist/index.js +2196 -255
  74. package/dist/index.js.map +1 -1
  75. package/dist/plugin.php +79 -0
  76. package/dist/utils/classBuilder.js +53 -0
  77. package/package.json +39 -7
  78. package/plugin.php +79 -0
  79. package/rollup.config.js +39 -22
  80. package/scripts/build-plugin.cjs +121 -0
  81. package/scripts/create-block.sh +141 -0
  82. package/src/blocks/ad-container/block.json +28 -0
  83. package/src/blocks/ad-container/edit.js +42 -0
  84. package/src/blocks/ad-container/index.js +10 -0
  85. package/src/blocks/ad-container/save.js +16 -0
  86. package/src/blocks/ad-container/style-editor.css +4 -0
  87. package/src/blocks/ad-container/style.css +27 -0
  88. package/src/blocks/button/block.json +89 -0
  89. package/src/blocks/button/edit.js +187 -0
  90. package/src/blocks/button/index.js +11 -0
  91. package/src/blocks/button/save.js +52 -0
  92. package/src/blocks/button/style-editor.css +15 -0
  93. package/src/blocks/button/style.css +37 -0
  94. package/src/blocks/chip/block.json +57 -0
  95. package/src/blocks/chip/edit.js +113 -0
  96. package/src/blocks/chip/index.js +10 -0
  97. package/src/blocks/chip/save.js +36 -0
  98. package/src/blocks/chip/style-editor.css +5 -0
  99. package/src/blocks/chip/style.css +48 -0
  100. package/src/blocks/divider/block.json +31 -0
  101. package/src/blocks/divider/edit.js +42 -0
  102. package/src/blocks/divider/index.js +10 -0
  103. package/src/blocks/divider/save.js +18 -0
  104. package/src/blocks/divider/style-editor.css +4 -0
  105. package/src/blocks/divider/style.css +25 -0
  106. package/src/blocks/flag/block.json +48 -0
  107. package/src/blocks/flag/edit.js +82 -0
  108. package/src/blocks/flag/index.js +10 -0
  109. package/src/blocks/flag/save.js +25 -0
  110. package/src/blocks/flag/style-editor.css +5 -0
  111. package/src/blocks/flag/style.css +45 -0
  112. package/src/blocks/icon-button/block.json +43 -0
  113. package/src/blocks/icon-button/edit.js +82 -0
  114. package/src/blocks/icon-button/index.js +10 -0
  115. package/src/blocks/icon-button/save.js +29 -0
  116. package/src/blocks/icon-button/style-editor.css +5 -0
  117. package/src/blocks/icon-button/style.css +32 -0
  118. package/src/blocks/input/block.json +47 -0
  119. package/src/blocks/input/edit.js +78 -0
  120. package/src/blocks/input/index.js +10 -0
  121. package/src/blocks/input/save.js +27 -0
  122. package/src/blocks/input/style-editor.css +8 -0
  123. package/src/blocks/input/style.css +30 -0
  124. package/src/blocks/link/block.json +71 -0
  125. package/src/blocks/link/edit.js +151 -0
  126. package/src/blocks/link/index.js +10 -0
  127. package/src/blocks/link/save.js +46 -0
  128. package/src/blocks/link/style-editor.css +5 -0
  129. package/src/blocks/link/style.css +66 -0
  130. package/src/blocks/text/block.json +32 -0
  131. package/src/blocks/text/edit.js +56 -0
  132. package/src/blocks/text/index.js +10 -0
  133. package/src/blocks/text/save.js +18 -0
  134. package/src/blocks/text/style-editor.css +4 -0
  135. package/src/blocks/text/style.css +20 -0
  136. package/src/blocks/toast/block.json +39 -0
  137. package/src/blocks/toast/edit.js +85 -0
  138. package/src/blocks/toast/index.js +10 -0
  139. package/src/blocks/toast/save.js +29 -0
  140. package/src/blocks/toast/style-editor.css +4 -0
  141. package/src/blocks/toast/style.css +51 -0
  142. package/src/index.js +15 -12
  143. package/src/utils/classBuilder.js +53 -0
  144. package/tsconfig.json +4 -4
  145. package/__tests__/wordpress.test.js +0 -0
  146. package/dist/AdContainer/AdContainer.d.ts +0 -9
  147. package/dist/Article/ArticleMetaContainer/ArticleMetaContainer.d.ts +0 -8
  148. package/dist/Article/UpNextArticles/UpNextArticles.d.ts +0 -13
  149. package/dist/Button/Button.d.ts +0 -15
  150. package/dist/CommentsDisabled/CommentsDisabled.d.ts +0 -10
  151. package/dist/CommentsDisabled/CommentsDisabled.stories.d.ts +0 -44
  152. package/dist/CommentsDisabled/index.d.ts +0 -2
  153. package/dist/Divider/Divider.d.ts +0 -15
  154. package/dist/Input/Input.d.ts +0 -25
  155. package/dist/Link/Link.d.ts +0 -18
  156. package/dist/Text/Text.d.ts +0 -14
  157. package/dist/index.cjs.js +0 -299
  158. package/dist/index.cjs.js.map +0 -1
  159. package/dist/styles.css +0 -151
  160. package/dist/typographyStyles.css +0 -30
  161. package/dist/utils/cn.d.ts +0 -1
  162. package/dist/utils/hooks.d.ts +0 -8
  163. package/src/AdContainer/AdContainer.tsx +0 -31
  164. package/src/AdContainer/styles.css +0 -58
  165. package/src/Article/ArticleMetaContainer/ArticleMetaContainer.tsx +0 -14
  166. package/src/Article/ArticleMetaContainer/styles.css +0 -151
  167. package/src/Article/UpNextArticles/UpNextArticles.tsx +0 -69
  168. package/src/Article/UpNextArticles/styles.css +0 -151
  169. package/src/Button/Button.tsx +0 -36
  170. package/src/Button/styles.css +0 -30
  171. package/src/CommentsDisabled/CommentsDisabled.stories.tsx +0 -178
  172. package/src/CommentsDisabled/CommentsDisabled.tsx +0 -63
  173. package/src/CommentsDisabled/IMPLEMENTATION_SUMMARY.md +0 -305
  174. package/src/CommentsDisabled/README.md +0 -284
  175. package/src/CommentsDisabled/TOKEN_MAPPING.md +0 -269
  176. package/src/CommentsDisabled/index.ts +0 -2
  177. package/src/CommentsDisabled/styles.css +0 -82
  178. package/src/Divider/Divider.tsx +0 -41
  179. package/src/Divider/styles.css +0 -80
  180. package/src/Input/Input.tsx +0 -62
  181. package/src/Input/styles.css +0 -69
  182. package/src/Link/Link.tsx +0 -49
  183. package/src/Link/styles.css +0 -111
  184. package/src/Text/Text.tsx +0 -38
  185. package/src/Text/styles.css +0 -30
  186. package/src/Text/typographyStyles.css +0 -30
  187. package/src/utils/cn.js +0 -3
  188. package/src/utils/cn.tsx +0 -3
  189. package/src/utils/hooks.ts +0 -34
package/rollup.config.js CHANGED
@@ -15,44 +15,61 @@ export default {
15
15
  sourcemap: true
16
16
  },
17
17
  {
18
- file: 'dist/index.cjs.js',
18
+ file: 'dist/index.cjs',
19
19
  format: 'cjs',
20
20
  sourcemap: true
21
21
  }
22
22
  ],
23
23
  plugins: [
24
24
  resolve({
25
- extensions: ['.js', '.jsx', '.ts', '.tsx']
25
+ extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
26
+ browser: true,
27
+ preferBuiltins: false
26
28
  }),
27
- commonjs(),
28
29
  json(),
29
30
  typescript({
30
- tsconfig: './tsconfig.json',
31
- declaration: true,
32
- declarationDir: 'dist'
33
- }),
34
- postcss({
35
- extract: false, // Inject CSS into JS
36
- inject: true, // Inject CSS into the head
37
- minimize: true,
38
- sourceMap: true,
39
- modules: {
40
- generateScopedName: '[name]__[local]___[hash:base64:5]'
41
- },
42
- use: {
43
- sass: {
44
- data: `@import "src/styles/variables.scss";` // Global SCSS variables
45
- }
31
+ tsconfig: false,
32
+ compilerOptions: {
33
+ jsx: 'react',
34
+ target: 'es2021',
35
+ module: 'es2015',
36
+ allowJs: true,
37
+ declaration: true,
38
+ declarationDir: 'dist',
39
+ strict: false
46
40
  }
47
41
  }),
48
42
  babel({
49
43
  babelHelpers: 'bundled',
50
44
  exclude: 'node_modules/**',
51
- extensions: ['.js', '.jsx', '.ts', '.tsx']
45
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
46
+ presets: [
47
+ ['@babel/preset-env', { modules: false }],
48
+ '@babel/preset-react'
49
+ ]
50
+ }),
51
+ commonjs(),
52
+ postcss({
53
+ extract: 'index.css',
54
+ inject: false,
55
+ minimize: true,
56
+ sourceMap: true
52
57
  }),
53
58
  copy({
54
- targets: [{ src: 'src/**/*.css', dest: 'dist', flatten: false }]
59
+ targets: [
60
+ { src: 'src/blocks', dest: 'dist' },
61
+ { src: 'src/utils', dest: 'dist' },
62
+ { src: 'plugin.php', dest: 'dist' },
63
+ { src: 'block.json', dest: 'dist' }
64
+ ],
65
+ flatten: false
55
66
  })
56
67
  ],
57
- external: ['react', 'react-dom'] // Don't bundle React
68
+ external: [
69
+ '@wordpress/blocks',
70
+ '@wordpress/block-editor',
71
+ '@wordpress/components',
72
+ '@wordpress/element'
73
+ ],
74
+ preserveEntrySignatures: 'strict'
58
75
  };
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Build script to generate WordPress plugin structure
5
+ * Organizes compiled blocks and plugin files for distribution
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const distDir = path.join(__dirname, '../dist');
12
+ const srcDir = path.join(__dirname, '../src');
13
+ const pluginFile = path.join(distDir, 'plugin.php');
14
+
15
+ console.log('📦 Building WordPress plugin structure...\n');
16
+
17
+ // Ensure dist directory exists
18
+ if (!fs.existsSync(distDir)) {
19
+ fs.mkdirSync(distDir, { recursive: true });
20
+ console.log('✓ Created dist directory');
21
+ }
22
+
23
+ // Copy plugin.php entry point
24
+ const srcPluginFile = path.join(__dirname, '../plugin.php');
25
+ if (fs.existsSync(srcPluginFile)) {
26
+ fs.copyFileSync(srcPluginFile, pluginFile);
27
+ console.log('✓ Plugin entry point created: dist/plugin.php');
28
+ } else {
29
+ console.warn('⚠ plugin.php not found, skipping');
30
+ }
31
+
32
+ // Ensure blocks directory structure
33
+ const blocksDistDir = path.join(distDir, 'blocks');
34
+ if (!fs.existsSync(blocksDistDir)) {
35
+ fs.mkdirSync(blocksDistDir, { recursive: true });
36
+ }
37
+
38
+ // Verify block.json files exist in dist
39
+ const blockDirs = fs.readdirSync(blocksDistDir, { withFileTypes: true })
40
+ .filter(dirent => dirent.isDirectory())
41
+ .map(dirent => dirent.name);
42
+
43
+ if (blockDirs.length === 0) {
44
+ console.warn('⚠ No block directories found in dist/blocks');
45
+ } else {
46
+ console.log(`✓ Found ${blockDirs.length} block(s): ${blockDirs.join(', ')}`);
47
+
48
+ // Verify each block has required files
49
+ blockDirs.forEach(blockName => {
50
+ const blockDir = path.join(blocksDistDir, blockName);
51
+ const blockJsonPath = path.join(blockDir, 'block.json');
52
+ const indexPath = path.join(blockDir, 'index.js');
53
+
54
+ const hasBlockJson = fs.existsSync(blockJsonPath);
55
+ const hasIndex = fs.existsSync(indexPath);
56
+
57
+ if (!hasBlockJson) {
58
+ console.warn(` ⚠ ${blockName}/block.json missing`);
59
+ }
60
+ if (!hasIndex) {
61
+ console.warn(` ⚠ ${blockName}/index.js missing`);
62
+ }
63
+ if (hasBlockJson && hasIndex) {
64
+ console.log(` ✓ ${blockName} (block.json + index.js)`);
65
+ }
66
+ });
67
+ }
68
+
69
+ // Create or verify root block.json
70
+ const blockJsonRoot = path.join(distDir, 'block.json');
71
+ if (fs.existsSync(blockJsonRoot)) {
72
+ console.log('✓ Root block.json found');
73
+ } else {
74
+ console.warn('⚠ Root block.json not found in dist');
75
+ }
76
+
77
+ // Verify utilities are copied
78
+ const utilsDir = path.join(distDir, 'utils');
79
+ if (fs.existsSync(utilsDir)) {
80
+ const utilFiles = fs.readdirSync(utilsDir).filter(f => f.endsWith('.js'));
81
+ console.log(`✓ Utilities copied: ${utilFiles.join(', ')}`);
82
+ } else {
83
+ console.warn('⚠ Utils directory not found in dist');
84
+ }
85
+
86
+ // Summary
87
+ console.log('\n📁 Plugin Structure:');
88
+ console.log(`dist/
89
+ ├── plugin.php # WordPress plugin entry point
90
+ ├── block.json # Root block manifest
91
+ ├── index.js # Main entry point
92
+ ├── index.cjs # CommonJS build
93
+ ├── index.css # Compiled styles
94
+ ├── blocks/
95
+ │ └── [block-name]/ # Individual block folders
96
+ │ ├── block.json # Block manifest
97
+ │ ├── index.js # Block registration
98
+ │ ├── edit.js # Editor component
99
+ │ ├── save.js # Frontend output
100
+ │ ├── style.css # Frontend styles
101
+ │ └── style-editor.css # Editor styles
102
+ └── utils/
103
+ └── *.js # Utility functions
104
+ `);
105
+
106
+ console.log('✅ WordPress plugin structure built successfully!');
107
+ console.log(`\n📦 Ready for distribution: ${distDir}\n`);
108
+
109
+ // Report any issues
110
+ const issues = [];
111
+ if (!fs.existsSync(pluginFile)) issues.push('plugin.php');
112
+ if (!fs.existsSync(blockJsonRoot)) issues.push('block.json');
113
+ if (blockDirs.length === 0) issues.push('No blocks');
114
+
115
+ if (issues.length > 0) {
116
+ console.error(`\n⚠️ Warning: Missing files - ${issues.join(', ')}`);
117
+ console.error('Build may not work correctly in WordPress\n');
118
+ process.exit(1);
119
+ } else {
120
+ console.log('All components present and ready!\n');
121
+ }
@@ -0,0 +1,141 @@
1
+ #!/bin/bash
2
+
3
+ # WordPress Block Creation Script
4
+ # Usage: ./scripts/create-block.sh <component-name>
5
+ # Example: ./scripts/create-block.sh text
6
+
7
+ set -e
8
+
9
+ if [ -z "$1" ]; then
10
+ echo "Usage: $0 <component-name>"
11
+ echo "Example: $0 text"
12
+ exit 1
13
+ fi
14
+
15
+ COMPONENT_NAME=$1
16
+ COMPONENT_NAME_PASCAL=$(echo "$COMPONENT_NAME" | sed 's/\b\(.\)/\U\1/g')
17
+ COMPONENT_DIR="src/blocks/$COMPONENT_NAME"
18
+
19
+ # Create directory structure
20
+ mkdir -p "$COMPONENT_DIR"
21
+
22
+ echo "Creating WordPress block: $COMPONENT_NAME"
23
+
24
+ # Create block.json
25
+ cat > "$COMPONENT_DIR/block.json" << 'EOF'
26
+ {
27
+ "$schema": "https://schemas.wp.org/trunk/block.json",
28
+ "apiVersion": 3,
29
+ "name": "times/COMPONENT_NAME",
30
+ "title": "COMPONENT_TITLE",
31
+ "category": "common",
32
+ "description": "A COMPONENT_TITLE component for Times Design System",
33
+ "icon": "admin-generic",
34
+ "supports": {
35
+ "html": false,
36
+ "spacing": {
37
+ "margin": true,
38
+ "padding": false
39
+ },
40
+ "align": true,
41
+ "customClassName": true
42
+ },
43
+ "textdomain": "times-design-system",
44
+ "attributes": {
45
+ },
46
+ "editorScript": "file:./index.js",
47
+ "editorStyle": "file:./style-editor.css",
48
+ "style": "file:./style.css"
49
+ }
50
+ EOF
51
+
52
+ # Create index.js
53
+ cat > "$COMPONENT_DIR/index.js" << 'EOF'
54
+ import { registerBlockType } from '@wordpress/blocks';
55
+ import Edit from './edit.js';
56
+ import Save from './save.js';
57
+ import metadata from './block.json';
58
+
59
+ registerBlockType(metadata.name, {
60
+ ...metadata,
61
+ edit: Edit,
62
+ save: Save,
63
+ });
64
+ EOF
65
+
66
+ # Create edit.js
67
+ cat > "$COMPONENT_DIR/edit.js" << 'EOF'
68
+ import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
69
+ import { PanelBody } from '@wordpress/components';
70
+ import './style-editor.css';
71
+
72
+ export default function Edit({ attributes, setAttributes }) {
73
+ const blockProps = useBlockProps({
74
+ className: 'tds-COMPONENT_NAME-wrapper',
75
+ });
76
+
77
+ return (
78
+ <>
79
+ <div {...blockProps}>
80
+ {/* Component preview */}
81
+ </div>
82
+
83
+ <InspectorControls>
84
+ <PanelBody title="Component Settings">
85
+ {/* Add inspector controls here */}
86
+ </PanelBody>
87
+ </InspectorControls>
88
+ </>
89
+ );
90
+ }
91
+ EOF
92
+
93
+ # Create save.js
94
+ cat > "$COMPONENT_DIR/save.js" << 'EOF'
95
+ import { useBlockProps } from '@wordpress/block-editor';
96
+
97
+ export default function Save({ attributes }) {
98
+ const blockProps = useBlockProps.save({
99
+ className: 'tds-COMPONENT_NAME-wrapper',
100
+ });
101
+
102
+ return (
103
+ <div {...blockProps}>
104
+ {/* Component output */}
105
+ </div>
106
+ );
107
+ }
108
+ EOF
109
+
110
+ # Create style.css
111
+ cat > "$COMPONENT_DIR/style.css" << 'EOF'
112
+ /* COMPONENT_TITLE Block Frontend Styles */
113
+
114
+ .tds-COMPONENT_NAME-wrapper {
115
+ /* Component wrapper styles */
116
+ }
117
+
118
+ .tds-COMPONENT_NAME {
119
+ /* Component styles - mostly inherited from @times-design-system/theme-scss */
120
+ }
121
+ EOF
122
+
123
+ # Create style-editor.css
124
+ cat > "$COMPONENT_DIR/style-editor.css" << 'EOF'
125
+ /* COMPONENT_TITLE Block Editor Styles */
126
+
127
+ .tds-COMPONENT_NAME-wrapper {
128
+ /* Editor-specific overrides */
129
+ }
130
+ EOF
131
+
132
+ echo ""
133
+ echo "✓ Block scaffold created at: $COMPONENT_DIR"
134
+ echo ""
135
+ echo "Next steps:"
136
+ echo "1. Edit $COMPONENT_DIR/block.json to add component attributes"
137
+ echo "2. Edit $COMPONENT_DIR/edit.js to add inspector controls"
138
+ echo "3. Edit $COMPONENT_DIR/save.js to define frontend output"
139
+ echo "4. Edit $COMPONENT_DIR/style.css to add component styles"
140
+ echo "5. Add import to src/index.js: import './blocks/$COMPONENT_NAME/index.js';"
141
+ echo ""
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://schemas.wp.org/trunk/block.json",
3
+ "apiVersion": 3,
4
+ "name": "times/ad-container",
5
+ "title": "Ad Container",
6
+ "category": "common",
7
+ "description": "Advertising container placeholder",
8
+ "icon": "image",
9
+ "supports": {
10
+ "html": false,
11
+ "spacing": {
12
+ "margin": true,
13
+ "padding": true
14
+ }
15
+ },
16
+ "attributes": {
17
+ "type": {
18
+ "type": "string",
19
+ "default": "inline",
20
+ "enum": ["header", "inline"]
21
+ },
22
+ "slotID": {
23
+ "type": "string",
24
+ "default": ""
25
+ }
26
+ },
27
+ "example": {}
28
+ }
@@ -0,0 +1,42 @@
1
+ import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
2
+ import { PanelBody, SelectControl, TextControl } from '@wordpress/components';
3
+
4
+ const edit = ({ attributes, setAttributes }) => {
5
+ const { type, slotID } = attributes;
6
+ const blockProps = useBlockProps();
7
+
8
+ return (
9
+ <>
10
+ <InspectorControls>
11
+ <PanelBody title="Ad Container Settings">
12
+ <SelectControl
13
+ label="Type"
14
+ value={type}
15
+ options={[
16
+ { label: 'Header', value: 'header' },
17
+ { label: 'Inline', value: 'inline' }
18
+ ]}
19
+ onChange={(val) => setAttributes({ type: val })}
20
+ />
21
+ <TextControl
22
+ label="Slot ID"
23
+ value={slotID}
24
+ onChange={(val) => setAttributes({ slotID: val })}
25
+ placeholder="e.g., /123456789/section/article-top"
26
+ />
27
+ </PanelBody>
28
+ </InspectorControls>
29
+ <div
30
+ {...blockProps}
31
+ className={`tds-ad-container tds-ad-container--${type}`}
32
+ data-slot-id={slotID}
33
+ >
34
+ <div className="tds-ad-container__placeholder">
35
+ <p>Ad Slot: {slotID || '(not configured)'}</p>
36
+ </div>
37
+ </div>
38
+ </>
39
+ );
40
+ };
41
+
42
+ export default edit;
@@ -0,0 +1,10 @@
1
+ import { registerBlockType } from '@wordpress/blocks';
2
+ import metadata from './block.json';
3
+ import edit from './edit';
4
+ import save from './save';
5
+
6
+ registerBlockType(metadata.name, {
7
+ ...metadata,
8
+ edit,
9
+ save
10
+ });
@@ -0,0 +1,16 @@
1
+ import { useBlockProps } from '@wordpress/block-editor';
2
+
3
+ const save = ({ attributes }) => {
4
+ const { type, slotID } = attributes;
5
+ const blockProps = useBlockProps.save();
6
+
7
+ return (
8
+ <div
9
+ {...blockProps}
10
+ className={`tds-ad-container tds-ad-container--${type}`}
11
+ data-slot-id={slotID}
12
+ />
13
+ );
14
+ };
15
+
16
+ export default save;
@@ -0,0 +1,4 @@
1
+ /* Ad Container Editor Styles */
2
+ .wp-block-times-ad-container {
3
+ margin: var(--spacing-m) 0;
4
+ }
@@ -0,0 +1,27 @@
1
+ /* Ad Container Styles */
2
+ .tds-ad-container {
3
+ display: block;
4
+ min-height: 250px;
5
+ background-color: var(--color-fill-secondary);
6
+ border: 1px dashed var(--color-border-secondary);
7
+ border-radius: var(--border-radius-s);
8
+ }
9
+
10
+ .tds-ad-container--header {
11
+ min-height: 90px;
12
+ }
13
+
14
+ .tds-ad-container--inline {
15
+ min-height: 250px;
16
+ }
17
+
18
+ .tds-ad-container__placeholder {
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ width: 100%;
23
+ height: 100%;
24
+ text-align: center;
25
+ color: var(--color-text-secondary);
26
+ font: var(--typography-body-small);
27
+ }
@@ -0,0 +1,89 @@
1
+ {
2
+ "$schema": "https://schemas.wp.org/trunk/block.json",
3
+ "apiVersion": 3,
4
+ "name": "times/button",
5
+ "title": "Button",
6
+ "category": "common",
7
+ "description": "A customizable button component for user interactions",
8
+ "icon": "admin-generic",
9
+ "supports": {
10
+ "html": false,
11
+ "spacing": {
12
+ "margin": true,
13
+ "padding": false
14
+ },
15
+ "align": true,
16
+ "customClassName": true
17
+ },
18
+ "textdomain": "times-design-system",
19
+ "attributes": {
20
+ "label": {
21
+ "type": "string",
22
+ "default": "Button label",
23
+ "description": "The text label displayed inside the button"
24
+ },
25
+ "intent": {
26
+ "type": "string",
27
+ "enum": ["primary", "secondary", "negative"],
28
+ "default": "primary",
29
+ "description": "Visual style variant"
30
+ },
31
+ "size": {
32
+ "type": "string",
33
+ "enum": ["small", "medium", "large"],
34
+ "default": "large",
35
+ "description": "Controls the overall dimensions of the button"
36
+ },
37
+ "behaviour": {
38
+ "type": "string",
39
+ "enum": ["hug", "full"],
40
+ "default": "hug",
41
+ "description": "Controls the width behaviour"
42
+ },
43
+ "state": {
44
+ "type": "string",
45
+ "enum": ["base", "hover", "pressed", "loading", "disabled", "focus"],
46
+ "default": "base",
47
+ "description": "The interaction state"
48
+ },
49
+ "disabled": {
50
+ "type": "boolean",
51
+ "default": false,
52
+ "description": "Whether the button is disabled"
53
+ },
54
+ "href": {
55
+ "type": "string",
56
+ "description": "Optional href to render as a link"
57
+ },
58
+ "target": {
59
+ "type": "string",
60
+ "enum": ["_blank", "_self", "_parent", "_top"],
61
+ "description": "Optional target attribute for links"
62
+ },
63
+ "rel": {
64
+ "type": "string",
65
+ "description": "Optional rel attribute for links"
66
+ },
67
+ "type": {
68
+ "type": "string",
69
+ "enum": ["button", "submit", "reset"],
70
+ "default": "button",
71
+ "description": "Button type"
72
+ },
73
+ "iconLeft": {
74
+ "type": "string",
75
+ "description": "Icon name to display on the left side of the label"
76
+ },
77
+ "iconRight": {
78
+ "type": "string",
79
+ "description": "Icon name to display on the right side of the label"
80
+ },
81
+ "ariaLabel": {
82
+ "type": "string",
83
+ "description": "Accessible name for icon-only buttons"
84
+ }
85
+ },
86
+ "editorScript": "file:./index.js",
87
+ "editorStyle": "file:./style-editor.css",
88
+ "style": "file:./style.css"
89
+ }