@pixelated-tech/components 3.2.12 → 3.2.13

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/README.md CHANGED
@@ -168,106 +168,11 @@ npm run storybook
168
168
  **Access locally at:** `http://localhost:6006`
169
169
 
170
170
 
171
-
172
- ## 🧪 Testing
173
-
174
- ### Overview
175
-
176
- **Current Status**: ✅ 2,184 tests passing across 59 test files (7 skipped)
177
-
178
- | Metric | Value |
179
- |--------|-------|
180
- | Test Files | 59 |
181
- | Total Tests | 2,184 |
182
- | Skipped Tests | 7 |
183
- | Coverage (Statements) | 79.26% |
184
- | Coverage (Lines) | 82.73% |
185
- | Coverage (Functions) | 84.73% |
186
- | Coverage (Branches) | 67.19% |
187
- | Test Framework | Vitest 4.x |
188
- | Testing Library | @testing-library/react + jsdom |
189
-
190
- ### Quick Start
191
-
192
- ```bash
193
- npm run test # Watch mode
194
- npm run test:ui # Interactive UI dashboard
195
- npm run test:coverage # Generate coverage reports
196
- npm run test:run # Single run (for CI)
197
- ```
198
-
199
- ### Component Coverage
200
-
201
- **52 of 52 Frontend Components + 2 Utility Modules Fully Tested (100%)**
202
-
203
- #### Component Coverage (Sorted by Statement Coverage)
204
- - **sitemap.ts**: 100% statements
205
- - **google.reviews.functions.ts**: 100% statements
206
- - **googlesearch.tsx**: 100% statements
207
- - **formvalidations.tsx**: 100% statements
208
- - **tiles.tsx**: 100% statements
209
- - **markdown.tsx**: 100% statements
210
- - **buzzwordbingo.tsx**: 100% statements
211
- - **timeline.tsx**: 100% statements
212
- - **config.server.tsx**: 100% statements
213
- - **modal.tsx**: 100% statements
214
- - **google.reviews.components.tsx**: 100% statements
215
- - **recipe.tsx**: 98.8% statements
216
- - **sidepanel.tsx**: 97.5% statements
217
- - **resume.tsx**: 94.38% statements
218
- - **callout.tsx**: 93.75% statements
219
- - **contentful.delivery.ts**: 92.5% statements
220
- - **css.tsx**: 91.42% statements
221
- - **functions.ts**: 90.9% statements
222
- - **config.client.tsx**: 90% statements
223
- - **api.ts**: 87.5% statements
224
- - **loading.tsx**: 85.71% statements
225
- - **table.tsx**: 84.48% statements
226
- - **cloudinary.ts**: 83.33% statements
227
- - **shoppingcart.functions.ts**: 81.69% statements
228
- - **carousel.tsx**: 76.19% statements
229
- - **nerdjoke.tsx**: 70.58% statements
230
- - **menu-accordion.tsx**: 68.13% statements
231
- - **carousel.tsx**: 58.49% statements
232
- - **config.ts**: 55.17% statements
233
-
234
- ### Test Configuration
235
-
236
- **Coverage Summary (latest run)**:
237
- - **Statements**: 79.26%
238
- - **Lines**: 82.73%
239
- - **Functions**: 84.73%
240
- - **Branches**: 67.19%
241
-
242
- **Coverage Targets** (configured in `vitest.config.ts`):
243
- - **Statements**: 70% threshold
244
- - **Lines**: 70% threshold
245
- - **Functions**: 70% threshold
246
- - **Branches**: 60% threshold
247
-
248
- **Coverage Thresholds in vitest.config.ts**:
249
- - Lines: 70% threshold
250
- - Functions: 70% threshold
251
- - Branches: 60% threshold
252
- - Statements: 70% threshold
253
-
254
- **Test Environment**: jsdom with @testing-library/react
255
- **Test Pattern**: Data-focused validation + behavioral testing
256
-
257
- ### Tools & Dependencies
258
-
259
- | Tool | Purpose |
260
- |------|---------|
261
- | Vitest 4.x | Test runner |
262
- | @testing-library/react | Component testing utilities |
263
- | jsdom | DOM environment for tests |
264
- | v8 | Coverage reporting |
265
-
266
-
267
171
  <!-- ROADMAP -->
268
172
  ## Roadmap
269
173
 
270
174
  ### New Components
175
+ - [ ] **IN PROGRESS** - Testimonial Block (Nextdoor/Yelp/Google): ingest review feeds + render carousel/grid.
271
176
  - [ ] **ON HOLD** LinkedIn Recommendations Integration (Not possible with current LinkedIn API)
272
177
  - [ ] **ON HOLD** eBay Feedback Integration - requires user OAuth login
273
178
  - [ ] **ON HOLD** Yelp Recommendations integration (Cost Prohibitive)
@@ -277,7 +182,6 @@ npm run test:run # Single run (for CI)
277
182
  - [ ] Buffer Integration (or Sendible, Sprout Social, Hootsuite)
278
183
  - [ ] Zapier Integration
279
184
  - [ ] Hero Banner: headline, subtext, CTA, background image/video, overlay.
280
- - [ ] **IN PROGRESS** - Testimonial Block (Nextdoor/Yelp/Google): ingest review feeds + render carousel/grid.
281
185
 
282
186
  ### CI / CD Improvements
283
187
  - [ ] Add CI workflow to run tests and lints on pull requests.
@@ -344,7 +248,7 @@ Distributed under the MIT License. See `LICENSE.txt` for more information.
344
248
  <!-- CONTACT -->
345
249
  ## Contact
346
250
 
347
- Your Name - [@brianwhaley](https://twitter.com/@brianwhaley) - brian.whaley@gmail.com
251
+ Brian Whaley - [@brianwhaley](https://twitter.com/@brianwhaley) - brian.whaley@gmail.com
348
252
 
349
253
  Project Link: [https://github.com/brianwhaley/pixelated-components](https://github.com/brianwhaley/pixelated-components)
350
254
 
@@ -353,6 +257,113 @@ Project Link: [https://github.com/brianwhaley/pixelated-components](https://gith
353
257
 
354
258
 
355
259
 
260
+ ## 🧪 Testing
261
+
262
+ ### Overview
263
+
264
+ **Current Status**: ✅ 2,184 tests passing across 59 test files
265
+
266
+ | Metric | Value |
267
+ |--------|-------|
268
+ | Test Files | 59 |
269
+ | Total Tests | 2,184 |
270
+ | Coverage (Statements) | 79.27% |
271
+ | Coverage (Lines) | 82.74% |
272
+ | Coverage (Functions) | 84.74% |
273
+ | Coverage (Branches) | 67.19% |
274
+ | Test Framework | Vitest 4.x |
275
+ | Testing Library | @testing-library/react + jsdom |
276
+
277
+ ### Quick Start
278
+
279
+ ```bash
280
+ npm run test # Watch mode
281
+ npm run test:ui # Interactive UI dashboard
282
+ npm run test:coverage # Generate coverage reports
283
+ npm run test:run # Single run (for CI)
284
+ ```
285
+
286
+ ### Component Coverage
287
+
288
+ **Component Coverage Summary**
289
+
290
+ #### Component Coverage (Sorted by Statement Coverage)
291
+ - **google.reviews.functions.ts**: 100% statements
292
+ - **googlesearch.tsx**: 100% statements
293
+ - **formvalidations.tsx**: 100% statements
294
+ - **tiles.tsx**: 100% statements
295
+ - **markdown.tsx**: 100% statements
296
+ - **buzzwordbingo.tsx**: 100% statements
297
+ - **timeline.tsx**: 100% statements
298
+ - **config.server.tsx**: 100% statements
299
+ - **modal.tsx**: 100% statements
300
+ - **recipe.tsx**: 98.8% statements
301
+ - **sidepanel.tsx**: 97.5% statements
302
+ - **google.reviews.components.tsx**: 95.83% statements
303
+ - **resume.tsx**: 94.38% statements
304
+ - **contentful.delivery.ts**: 92.5% statements
305
+ - **css.tsx**: 91.42% statements
306
+ - **functions.ts**: 90.9% statements
307
+ - **config.client.tsx**: 90% statements
308
+ - **api.ts**: 87.5% statements
309
+ - **loading.tsx**: 85.71% statements
310
+ - **table.tsx**: 84.48% statements
311
+ - **cloudinary.ts**: 83.33% statements
312
+ - **shoppingcart.functions.ts**: 81.69% statements
313
+ - **callout.tsx**: 80.00% statements
314
+ - **sitemap.ts**: 76.38% statements
315
+ - **carousel.tsx**: 71.70% statements
316
+ - **nerdjoke.tsx**: 70.58% statements
317
+ - **menu-accordion.tsx**: 68.13% statements
318
+ - **semantic.tsx**: 60.81% statements
319
+ - **config.ts**: 55.17% statements
320
+ - **socialcard.tsx**: 29.5% statements
321
+ - **ComponentPropertiesForm.tsx**: 0% statements (no tests)
322
+ - **ComponentSelector.tsx**: 0% statements (no tests)
323
+ - **ComponentTree.tsx**: 0% statements (no tests)
324
+ - **PageBuilderUI.tsx**: 0% statements (no tests)
325
+ - **PageEngine.tsx**: 0% statements (no tests)
326
+ - **SaveLoadSection.tsx**: 0% statements (no tests)
327
+
328
+ ### Testing Next Steps
329
+
330
+ #### Integration Testing Gaps
331
+ - [ ] **Cross-component interactions** - Test how components work together (e.g., forms with validation, carousels with loading states)
332
+ - [ ] **Form validation edge cases** - Test URL validation, required fields, and complex validation rules under various conditions
333
+ - [ ] **CMS API integrations** - Test API failures, rate limiting, authentication errors, and network timeouts
334
+ - [ ] **Responsive design breakpoints** - Test component behavior across different screen sizes and device types
335
+ - [ ] **Accessibility (a11y) compliance** - Test keyboard navigation, screen reader compatibility, and ARIA attributes
336
+
337
+ ### Test Configuration
338
+
339
+
340
+ **Coverage Targets** (configured in `vitest.config.ts`):
341
+ - **Statements**: 70% threshold
342
+ - **Lines**: 70% threshold
343
+ - **Functions**: 70% threshold
344
+ - **Branches**: 60% threshold
345
+
346
+ **Coverage Thresholds in vitest.config.ts**:
347
+ - Lines: 70% threshold
348
+ - Functions: 70% threshold
349
+ - Branches: 60% threshold
350
+ - Statements: 70% threshold
351
+
352
+ **Test Environment**: jsdom with @testing-library/react
353
+ **Test Pattern**: Data-focused validation + behavioral testing
354
+
355
+ ### Tools & Dependencies
356
+
357
+ | Tool | Purpose |
358
+ |------|---------|
359
+ | Vitest 4.x | Test runner |
360
+ | @testing-library/react | Component testing utilities |
361
+ | jsdom | DOM environment for tests |
362
+ | v8 | Coverage reporting |
363
+
364
+
365
+
366
+
356
367
 
357
368
  <!-- MARKDOWN LINKS & IMAGES -->
358
369
  <!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
@@ -45,7 +45,7 @@ export function BlogPostSummary(props) {
45
45
  const myCategoryImages = Object.entries(props.categories).map(([category, index]) => [category.trim().toLowerCase().replace(/[ /]+/g, '-'), index]).sort();
46
46
  const config = usePixelatedConfig();
47
47
  const myExcerpt = decodeString(props.excerpt).replace(/\[…\]/g, '<a href="' + props.URL + '" target="_blank" rel="noopener noreferrer">[…]</a>');
48
- return (_jsx("div", { className: "blog-post-summary", children: _jsxs("article", { className: "h-entry", children: [_jsx("h2", { className: "p-name", children: _jsx("a", { className: "u-url blog-post-url", href: props.URL, target: "_blank", rel: "noopener noreferrer", children: decodeString(props.title) }) }), _jsxs("div", { className: "dt-published", children: ["Published: ", new Date(props.date).toLocaleDateString()] }), props.featured_image ? (_jsxs("div", { className: "article-body row-12col", children: [_jsx("div", { className: "article-featured-image grid-s1-e4", children: _jsx(SmartImage, { className: "u-photo", src: props.featured_image, alt: decodeString(props.title), title: decodeString(props.title), style: { borderRadius: '20px' }, cloudinaryEnv: config?.cloudinary?.product_env ?? undefined, cloudinaryDomain: config?.cloudinary?.baseUrl ?? undefined, cloudinaryTransforms: config?.cloudinary?.transforms ?? undefined }) }), _jsx("div", { className: "article-excerpt grid-s4-e13", children: _jsx("div", { className: "p-summary", dangerouslySetInnerHTML: { __html: myExcerpt } }) })] })) :
48
+ return (_jsx("div", { className: "blog-post-summary", children: _jsxs("article", { className: "h-entry", children: [_jsx("h2", { className: "p-name", children: _jsx("a", { className: "u-url blog-post-url", href: props.URL, target: "_blank", rel: "noopener noreferrer", children: decodeString(props.title) }) }), _jsxs("div", { className: "dt-published", children: ["Published: ", new Date(props.date).toLocaleDateString()] }), props.featured_image ? (_jsxs("div", { className: "article-body row-12col", children: [_jsx("div", { className: "article-featured-image grid-s1-e4", children: _jsx(SmartImage, { className: "u-photo", src: props.featured_image, alt: decodeString(props.title), title: decodeString(props.title), style: {}, cloudinaryEnv: config?.cloudinary?.product_env ?? undefined, cloudinaryDomain: config?.cloudinary?.baseUrl ?? undefined, cloudinaryTransforms: config?.cloudinary?.transforms ?? undefined }) }), _jsx("div", { className: "article-excerpt grid-s4-e13", children: _jsx("div", { className: "p-summary", dangerouslySetInnerHTML: { __html: myExcerpt } }) })] })) :
49
49
  _jsx("div", { className: "article-excerpt grid-s1-e13", children: _jsx("div", { className: "p-summary", dangerouslySetInnerHTML: { __html: myExcerpt } }) }), props.showCategories !== false && (_jsxs("div", { children: ["Categories:", myCategoryImages.map(([categoryImg, index]) => (_jsx("span", { className: "p-category", children: _jsx(SmartImage, { src: `/images/icons/${categoryImg}.png`, title: String(categoryImg), alt: String(categoryImg), cloudinaryEnv: config?.cloudinary?.product_env ?? undefined, cloudinaryDomain: config?.cloudinary?.baseUrl ?? undefined, cloudinaryTransforms: config?.cloudinary?.transforms ?? undefined }) }, categoryImg + "-" + index)))] }))] }) }, props.ID));
50
50
  }
51
51
  export function BlogPostCategories(props) {
@@ -44,6 +44,13 @@
44
44
  hyphens: auto;
45
45
  }
46
46
 
47
+ .article-featured-image img {
48
+ /* border-radius: 20px; */
49
+ width: 100%;
50
+ height: 100%;
51
+ object-fit: cover;
52
+ }
53
+
47
54
  }
48
55
 
49
56
  .blog-post-summary .p-category img,
@@ -7,7 +7,7 @@ import { FormEngine } from '../form/form';
7
7
  * Shows FormEngine when component is selected, placeholder otherwise
8
8
  */
9
9
  ComponentPropertiesForm.propTypes = {
10
- editableComponent: PropTypes.object.isRequired,
10
+ editableComponent: PropTypes.object,
11
11
  onSubmit: PropTypes.func.isRequired,
12
12
  };
13
13
  export function ComponentPropertiesForm({ editableComponent, onSubmit }) {
@@ -3,7 +3,7 @@ type ComponentPropertiesFormProps = InferProps<typeof ComponentPropertiesForm.pr
3
3
  export declare function ComponentPropertiesForm({ editableComponent, onSubmit }: ComponentPropertiesFormProps): import("react/jsx-runtime").JSX.Element;
4
4
  export declare namespace ComponentPropertiesForm {
5
5
  var propTypes: {
6
- editableComponent: PropTypes.Validator<object>;
6
+ editableComponent: PropTypes.Requireable<object>;
7
7
  onSubmit: PropTypes.Validator<(...args: any[]) => any>;
8
8
  };
9
9
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=component-properties-form.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-properties-form.test.d.ts","sourceRoot":"","sources":["../../../src/tests/component-properties-form.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=component-selector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-selector.test.d.ts","sourceRoot":"","sources":["../../../src/tests/component-selector.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=component-tree.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-tree.test.d.ts","sourceRoot":"","sources":["../../../src/tests/component-tree.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=page-builder-ui.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-builder-ui.test.d.ts","sourceRoot":"","sources":["../../../src/tests/page-builder-ui.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=page-engine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-engine.test.d.ts","sourceRoot":"","sources":["../../../src/tests/page-engine.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=save-load-section.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-load-section.test.d.ts","sourceRoot":"","sources":["../../../src/tests/save-load-section.test.tsx"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixelated-tech/components",
3
- "version": "3.2.12",
3
+ "version": "3.2.13",
4
4
  "private": false,
5
5
  "author": {
6
6
  "name": "Pixelated Technologies",
@@ -91,7 +91,7 @@
91
91
  "@eslint/markdown": "^7.5.1",
92
92
  "@storybook/addon-webpack5-compiler-babel": "^4.0.0",
93
93
  "@storybook/preset-scss": "^1.0.3",
94
- "@storybook/react-webpack5": "^10.1.9",
94
+ "@storybook/react-webpack5": "^10.1.10",
95
95
  "@testing-library/dom": "^10.4.1",
96
96
  "@testing-library/react": "^16.3.1",
97
97
  "@testing-library/user-event": "^14.6.1",
@@ -117,7 +117,7 @@
117
117
  "eslint-plugin-n": "^17.23.1",
118
118
  "eslint-plugin-promise": "^7.2.1",
119
119
  "eslint-plugin-react": "^7.37.4",
120
- "eslint-plugin-storybook": "^10.1.9",
120
+ "eslint-plugin-storybook": "^10.1.10",
121
121
  "file-loader": "^6.2.0",
122
122
  "happy-dom": "^20.0.11",
123
123
  "jsdom": "^27.3.0",
@@ -131,7 +131,7 @@
131
131
  "react-test-renderer": "^19.2.3",
132
132
  "sass": "^1.97.0",
133
133
  "sass-loader": "^16.0.6",
134
- "storybook": "^10.1.9",
134
+ "storybook": "^10.1.10",
135
135
  "style-loader": "^4.0.0",
136
136
  "ts-loader": "^9.5.4",
137
137
  "typescript": "^5.9.3",