@pixelated-tech/components 3.4.3 → 3.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.
Files changed (228) hide show
  1. package/README.md +12 -191
  2. package/dist/components/admin/componentusage/componentAnalysis.js +12 -4
  3. package/dist/components/admin/componentusage/componentDiscovery.js +20 -6
  4. package/dist/components/admin/site-health/site-health-accessibility.js +5 -1
  5. package/dist/components/admin/site-health/site-health-axe-core.js +4 -0
  6. package/dist/components/admin/site-health/site-health-cloudwatch.integration.js +0 -5
  7. package/dist/components/admin/site-health/site-health-cloudwatch.js +7 -1
  8. package/dist/components/admin/site-health/site-health-dependency-vulnerabilities.js +4 -0
  9. package/dist/components/admin/site-health/site-health-github.js +6 -0
  10. package/dist/components/admin/site-health/site-health-google-analytics.js +6 -0
  11. package/dist/components/admin/site-health/site-health-google-search-console.js +6 -0
  12. package/dist/components/admin/site-health/site-health-on-site-seo.integration.js +128 -55
  13. package/dist/components/admin/site-health/site-health-on-site-seo.js +4 -0
  14. package/dist/components/admin/site-health/site-health-overview.js +11 -4
  15. package/dist/components/admin/site-health/site-health-performance.js +4 -0
  16. package/dist/components/admin/site-health/site-health-security.js +5 -1
  17. package/dist/components/admin/site-health/site-health-seo.js +5 -1
  18. package/dist/components/admin/site-health/site-health-template.js +19 -9
  19. package/dist/components/admin/site-health/site-health-uptime.js +4 -0
  20. package/dist/components/callout/callout.js +0 -10
  21. package/dist/components/carousel/carousel.js +15 -4
  22. package/dist/components/carousel/tiles.js +1 -1
  23. package/dist/components/cms/contentful.items.components.js +3 -4
  24. package/dist/components/cms/flickr.js +1 -1
  25. package/dist/components/cms/google.reviews.components.js +3 -3
  26. package/dist/components/cms/instagram.components.js +15 -5
  27. package/dist/components/cms/smartimage.js +2 -2
  28. package/dist/components/cms/wordpress.components.js +32 -6
  29. package/dist/components/cms/yelp.js +5 -0
  30. package/dist/components/config/config.server.js +7 -1
  31. package/dist/components/general/css.js +0 -1
  32. package/dist/components/general/image.js +0 -1
  33. package/dist/components/general/loading.js +2 -1
  34. package/dist/components/general/microinteractions.js +0 -1
  35. package/dist/components/general/modal.css +2 -4
  36. package/dist/components/general/modal.js +72 -30
  37. package/dist/components/general/sidepanel.js +16 -0
  38. package/dist/components/general/tab.js +1 -0
  39. package/dist/components/menu/menu-accordion.css +1 -1
  40. package/dist/components/menu/menu-accordion.js +15 -4
  41. package/dist/components/menu/menu-expando.js +21 -19
  42. package/dist/components/menu/menu-simple.js +14 -14
  43. package/dist/components/nerdjoke/nerdjoke.js +1 -1
  44. package/dist/components/seo/googlesearch.js +0 -1
  45. package/dist/components/seo/schema-blogposting.js +6 -1
  46. package/dist/components/seo/schema-recipe.js +34 -1
  47. package/dist/components/seo/schema-services.js +20 -2
  48. package/dist/components/shoppingcart/ebay.components.js +3 -3
  49. package/dist/components/shoppingcart/shoppingcart.components.js +76 -28
  50. package/dist/components/shoppingcart/shoppingcart.functions.js +4 -4
  51. package/dist/components/sitebuilder/config/CompoundFontSelector.js +13 -4
  52. package/dist/components/sitebuilder/config/ConfigBuilder.css +194 -5
  53. package/dist/components/sitebuilder/config/ConfigBuilder.js +183 -17
  54. package/dist/components/sitebuilder/config/FontSelector.js +13 -2
  55. package/dist/components/sitebuilder/config/routes-form.json +67 -0
  56. package/dist/components/sitebuilder/config/siteinfo-form.json +28 -14
  57. package/dist/components/sitebuilder/config/visualdesignform.json +4 -4
  58. package/dist/components/sitebuilder/form/formbuilder.js +1 -0
  59. package/dist/components/sitebuilder/form/formcomponents.js +2 -3
  60. package/dist/components/sitebuilder/form/formengine.js +6 -5
  61. package/dist/components/sitebuilder/form/formvalidator.js +5 -0
  62. package/dist/components/sitebuilder/page/components/PageBuilderUI.js +5 -1
  63. package/dist/components/structured/buzzwordbingo.css +0 -1
  64. package/dist/components/structured/recipe.js +1 -1
  65. package/dist/components/structured/socialcard.js +2 -2
  66. package/dist/components/utilities/functions.js +82 -1
  67. package/dist/components/utilities/gemini-api.client.js +76 -0
  68. package/dist/components/utilities/gemini-api.server.js +185 -0
  69. package/dist/data/routes.json +5 -5
  70. package/dist/index.adminclient.js +30 -0
  71. package/dist/index.adminserver.js +21 -0
  72. package/dist/index.js +4 -18
  73. package/dist/index.server.js +15 -28
  74. package/dist/types/components/admin/componentusage/componentAnalysis.d.ts.map +1 -1
  75. package/dist/types/components/admin/componentusage/componentDiscovery.d.ts +1 -1
  76. package/dist/types/components/admin/componentusage/componentDiscovery.d.ts.map +1 -1
  77. package/dist/types/components/admin/site-health/site-health-accessibility.d.ts +7 -4
  78. package/dist/types/components/admin/site-health/site-health-accessibility.d.ts.map +1 -1
  79. package/dist/types/components/admin/site-health/site-health-axe-core.d.ts +7 -4
  80. package/dist/types/components/admin/site-health/site-health-axe-core.d.ts.map +1 -1
  81. package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts +9 -6
  82. package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts.map +1 -1
  83. package/dist/types/components/admin/site-health/site-health-cloudwatch.integration.d.ts.map +1 -1
  84. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts +7 -4
  85. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts.map +1 -1
  86. package/dist/types/components/admin/site-health/site-health-github.d.ts +9 -6
  87. package/dist/types/components/admin/site-health/site-health-github.d.ts.map +1 -1
  88. package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts +9 -6
  89. package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts.map +1 -1
  90. package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts +9 -6
  91. package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts.map +1 -1
  92. package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts +8 -3
  93. package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts.map +1 -1
  94. package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts.map +1 -1
  95. package/dist/types/components/admin/site-health/site-health-overview.d.ts +7 -4
  96. package/dist/types/components/admin/site-health/site-health-overview.d.ts.map +1 -1
  97. package/dist/types/components/admin/site-health/site-health-performance.d.ts +7 -4
  98. package/dist/types/components/admin/site-health/site-health-performance.d.ts.map +1 -1
  99. package/dist/types/components/admin/site-health/site-health-security.d.ts +7 -4
  100. package/dist/types/components/admin/site-health/site-health-security.d.ts.map +1 -1
  101. package/dist/types/components/admin/site-health/site-health-seo.d.ts +7 -4
  102. package/dist/types/components/admin/site-health/site-health-seo.d.ts.map +1 -1
  103. package/dist/types/components/admin/site-health/site-health-template.d.ts +12 -10
  104. package/dist/types/components/admin/site-health/site-health-template.d.ts.map +1 -1
  105. package/dist/types/components/admin/site-health/site-health-uptime.d.ts +7 -4
  106. package/dist/types/components/admin/site-health/site-health-uptime.d.ts.map +1 -1
  107. package/dist/types/components/callout/callout.d.ts +3 -3
  108. package/dist/types/components/callout/callout.d.ts.map +1 -1
  109. package/dist/types/components/carousel/carousel.d.ts +16 -7
  110. package/dist/types/components/carousel/carousel.d.ts.map +1 -1
  111. package/dist/types/components/carousel/tiles.d.ts +3 -6
  112. package/dist/types/components/carousel/tiles.d.ts.map +1 -1
  113. package/dist/types/components/cms/flickr.d.ts +3 -6
  114. package/dist/types/components/cms/flickr.d.ts.map +1 -1
  115. package/dist/types/components/cms/google.reviews.components.d.ts +1 -7
  116. package/dist/types/components/cms/google.reviews.components.d.ts.map +1 -1
  117. package/dist/types/components/cms/hubspot.components.d.ts +1 -2
  118. package/dist/types/components/cms/hubspot.components.d.ts.map +1 -1
  119. package/dist/types/components/cms/instagram.components.d.ts +14 -9
  120. package/dist/types/components/cms/instagram.components.d.ts.map +1 -1
  121. package/dist/types/components/cms/smartimage.d.ts +2 -28
  122. package/dist/types/components/cms/smartimage.d.ts.map +1 -1
  123. package/dist/types/components/cms/wordpress.components.d.ts +33 -14
  124. package/dist/types/components/cms/wordpress.components.d.ts.map +1 -1
  125. package/dist/types/components/cms/yelp.d.ts +9 -4
  126. package/dist/types/components/cms/yelp.d.ts.map +1 -1
  127. package/dist/types/components/config/config.server.d.ts +9 -6
  128. package/dist/types/components/config/config.server.d.ts.map +1 -1
  129. package/dist/types/components/general/loading.d.ts +5 -1
  130. package/dist/types/components/general/loading.d.ts.map +1 -1
  131. package/dist/types/components/general/microinteractions.d.ts +1 -3
  132. package/dist/types/components/general/microinteractions.d.ts.map +1 -1
  133. package/dist/types/components/general/modal.d.ts +11 -5
  134. package/dist/types/components/general/modal.d.ts.map +1 -1
  135. package/dist/types/components/general/semantic.d.ts +3 -3
  136. package/dist/types/components/general/sidepanel.d.ts +20 -13
  137. package/dist/types/components/general/sidepanel.d.ts.map +1 -1
  138. package/dist/types/components/general/tab.d.ts +1 -2
  139. package/dist/types/components/general/tab.d.ts.map +1 -1
  140. package/dist/types/components/menu/menu-accordion.d.ts +22 -9
  141. package/dist/types/components/menu/menu-accordion.d.ts.map +1 -1
  142. package/dist/types/components/menu/menu-expando.d.ts +14 -5
  143. package/dist/types/components/menu/menu-expando.d.ts.map +1 -1
  144. package/dist/types/components/menu/menu-simple.d.ts +4 -5
  145. package/dist/types/components/menu/menu-simple.d.ts.map +1 -1
  146. package/dist/types/components/nerdjoke/nerdjoke.d.ts +1 -1
  147. package/dist/types/components/nerdjoke/nerdjoke.d.ts.map +1 -1
  148. package/dist/types/components/seo/googleanalytics.d.ts.map +1 -1
  149. package/dist/types/components/seo/metadata.components.d.ts +2 -2
  150. package/dist/types/components/seo/metadata.components.d.ts.map +1 -1
  151. package/dist/types/components/seo/schema-blogposting.d.ts +7 -4
  152. package/dist/types/components/seo/schema-blogposting.d.ts.map +1 -1
  153. package/dist/types/components/seo/schema-recipe.d.ts +29 -30
  154. package/dist/types/components/seo/schema-recipe.d.ts.map +1 -1
  155. package/dist/types/components/seo/schema-services.d.ts +19 -9
  156. package/dist/types/components/seo/schema-services.d.ts.map +1 -1
  157. package/dist/types/components/shoppingcart/paypal.d.ts +1 -1
  158. package/dist/types/components/shoppingcart/paypal.d.ts.map +1 -1
  159. package/dist/types/components/shoppingcart/shoppingcart.components.d.ts +77 -28
  160. package/dist/types/components/shoppingcart/shoppingcart.components.d.ts.map +1 -1
  161. package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts +4 -23
  162. package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts.map +1 -1
  163. package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts +10 -11
  164. package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts.map +1 -1
  165. package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts +41 -174
  166. package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts.map +1 -1
  167. package/dist/types/components/sitebuilder/config/FontSelector.d.ts +12 -13
  168. package/dist/types/components/sitebuilder/config/FontSelector.d.ts.map +1 -1
  169. package/dist/types/components/sitebuilder/form/formbuilder.d.ts +7 -3
  170. package/dist/types/components/sitebuilder/form/formbuilder.d.ts.map +1 -1
  171. package/dist/types/components/sitebuilder/form/formcomponents.d.ts +1 -1
  172. package/dist/types/components/sitebuilder/form/formcomponents.d.ts.map +1 -1
  173. package/dist/types/components/sitebuilder/form/formengine.d.ts +1 -2
  174. package/dist/types/components/sitebuilder/form/formengine.d.ts.map +1 -1
  175. package/dist/types/components/sitebuilder/form/formextractor.d.ts +5 -4
  176. package/dist/types/components/sitebuilder/form/formextractor.d.ts.map +1 -1
  177. package/dist/types/components/sitebuilder/form/formtypes.d.ts +3 -3
  178. package/dist/types/components/sitebuilder/form/formtypes.d.ts.map +1 -1
  179. package/dist/types/components/sitebuilder/form/formvalidator.d.ts +8 -3
  180. package/dist/types/components/sitebuilder/form/formvalidator.d.ts.map +1 -1
  181. package/dist/types/components/sitebuilder/page/components/ComponentPropertiesForm.d.ts +2 -3
  182. package/dist/types/components/sitebuilder/page/components/ComponentPropertiesForm.d.ts.map +1 -1
  183. package/dist/types/components/sitebuilder/page/components/ComponentSelector.d.ts +2 -3
  184. package/dist/types/components/sitebuilder/page/components/ComponentSelector.d.ts.map +1 -1
  185. package/dist/types/components/sitebuilder/page/components/ComponentTree.d.ts +2 -3
  186. package/dist/types/components/sitebuilder/page/components/ComponentTree.d.ts.map +1 -1
  187. package/dist/types/components/sitebuilder/page/components/PageBuilderUI.d.ts +8 -7
  188. package/dist/types/components/sitebuilder/page/components/PageBuilderUI.d.ts.map +1 -1
  189. package/dist/types/components/sitebuilder/page/components/PageEngine.d.ts.map +1 -1
  190. package/dist/types/components/sitebuilder/page/components/SaveLoadSection.d.ts +2 -3
  191. package/dist/types/components/sitebuilder/page/components/SaveLoadSection.d.ts.map +1 -1
  192. package/dist/types/components/sitebuilder/page/lib/componentMap.d.ts +1 -1
  193. package/dist/types/components/structured/markdown.d.ts +1 -3
  194. package/dist/types/components/structured/markdown.d.ts.map +1 -1
  195. package/dist/types/components/structured/recipe.d.ts +5 -32
  196. package/dist/types/components/structured/recipe.d.ts.map +1 -1
  197. package/dist/types/components/structured/socialcard.d.ts +4 -0
  198. package/dist/types/components/structured/socialcard.d.ts.map +1 -1
  199. package/dist/types/components/structured/timeline.d.ts +1 -3
  200. package/dist/types/components/structured/timeline.d.ts.map +1 -1
  201. package/dist/types/components/utilities/functions.d.ts +20 -0
  202. package/dist/types/components/utilities/functions.d.ts.map +1 -1
  203. package/dist/types/components/utilities/gemini-api.client.d.ts +38 -0
  204. package/dist/types/components/utilities/gemini-api.client.d.ts.map +1 -0
  205. package/dist/types/components/utilities/gemini-api.server.d.ts +17 -0
  206. package/dist/types/components/utilities/gemini-api.server.d.ts.map +1 -0
  207. package/dist/types/index.adminclient.d.ts +27 -0
  208. package/dist/types/index.adminclient.d.ts.map +1 -0
  209. package/dist/types/index.adminserver.d.ts +19 -0
  210. package/dist/types/index.adminserver.d.ts.map +1 -0
  211. package/dist/types/index.d.ts +4 -18
  212. package/dist/types/index.server.d.ts +5 -28
  213. package/dist/types/stories/general/sidepanel.stories.d.ts.map +1 -1
  214. package/dist/types/stories/general/smartimage.stories.d.ts +74 -2
  215. package/dist/types/stories/general/smartimage.stories.d.ts.map +1 -1
  216. package/package.json +19 -9
  217. package/README.COMPONENTS.md +0 -2310
  218. package/dist/components/cms/pixelated.linkedin.js +0 -180
  219. package/dist/components/cms/pixelated.linkedin1.js +0 -84
  220. package/dist/components/cms/pixelated.linkedin2.js +0 -92
  221. package/dist/types/components/cms/pixelated.linkedin.d.ts +0 -2
  222. package/dist/types/components/cms/pixelated.linkedin.d.ts.map +0 -1
  223. package/dist/types/components/cms/pixelated.linkedin1.d.ts +0 -2
  224. package/dist/types/components/cms/pixelated.linkedin1.d.ts.map +0 -1
  225. package/dist/types/components/cms/pixelated.linkedin2.d.ts +0 -2
  226. package/dist/types/components/cms/pixelated.linkedin2.d.ts.map +0 -1
  227. package/dist/types/tests/pixelated.menu-expando.test.d.ts +0 -2
  228. package/dist/types/tests/pixelated.menu-expando.test.d.ts.map +0 -1
package/README.md CHANGED
@@ -268,7 +268,7 @@ npm install @pixelated-tech/components
268
268
  import { Accordion, Callout } from '@pixelated-tech/components';
269
269
  ```
270
270
 
271
- For detailed usage examples and API documentation, see the [Component Reference Guide](README.COMPONENTS.md).
271
+ For detailed usage examples and API documentation, see the [Component Reference Guide](docs/components.md).
272
272
 
273
273
  ### Storybook Interactive Demos
274
274
 
@@ -282,71 +282,22 @@ npm run storybook
282
282
  **Access locally at:** `http://localhost:6006`
283
283
 
284
284
 
285
+ See the [open issues](https://github.com/brianwhaley/pixelated-components/issues) for a full list of proposed features (and known issues).
286
+
287
+
288
+
289
+
290
+
285
291
  <!-- ROADMAP -->
286
- ## Roadmap
287
-
288
- ### New Components
289
- - [ ] **IN PROGRESS** - Testimonial Block (Nextdoor/Yelp/Google): ingest review feeds + render carousel/grid.
290
- - [ ] **ON HOLD** LinkedIn Recommendations Integration (Not possible with current LinkedIn API)
291
- - [ ] **ON HOLD** eBay Feedback Integration - requires user OAuth login
292
- - [ ] **ON HOLD** Yelp Recommendations integration (Cost Prohibitive)
293
- - [ ] Instagram Image Integration for Carousels
294
- - [ ] Shopify Integration
295
- - [ ] Quickbooks Integration
296
- - [ ] Buffer Integration (or Sendible, Sprout Social, Hootsuite)
297
- - [ ] Zapier Integration
298
- - [ ] Hero Banner: headline, subtext, CTA, background image/video, overlay.
299
- - [ ] Accessibility Enhancer: wrapper component that automatically improves accessibility across Pixelated sites by adding ARIA labels, roles, and states to existing components. Includes color contrast checking, keyboard navigation helpers, alt-text suggestions for images, and automated accessibility audits.
300
- - [ ] SEO Dashboard with AI Integration: component that analyzes site content, suggests optimizations, integrates with AI for meta descriptions and keyword research.
301
-
302
- ### CI / CD Improvements
303
- - [ ] Add CI workflow to run tests and lints on pull requests.
304
-
305
- ### Component Improvements
306
- - [ ] Implement minimal `createContentfulImageURLs` with single `/images` sitemap entry.
307
- - [ ] Review Contentful helper functions for per-page mapping capability.
308
- - [ ] Implement `createContentfulImageURLs` per-page mapping with `contentType` & `pageField` config.
309
- - [ ] Align typography to `--font-sizeN` clamp variables.
310
- - [ ] Provide Cloudinary transforms presets for image components.
311
- - [ ] find a better solution than to generate image via build script in amplify for json for sitemap creation
312
- - [ ] **SocialCards Component**: Fix state initialization to track prop changes properly.
313
- - [ ] **Modal Component**: Clarify content source pattern (accepts both `modalContent` and `children`).
314
- - [ ] **Carousel Component**: Fix active card state reset when `props.cards` changes.
315
- - [ ] **NerdJoke Component**: Add props to useEffect dependencies if endpoint becomes configurable.
316
- - [ ] **GoogleReviews Component**: Add carousel/grid display modes.
317
- - [ ] **GoogleReviews Component**: Add API key to config provider instead of hardcoding.
318
- - [ ] **Instagram Component**: Add accessToken and userId to config provider for centralized API credentials.
319
- - [ ] **Critters Integration**: Explore adding critters CSS inlining tool for improved page load performance and critical CSS optimization.
320
-
321
- ### Platform Enhancements
322
- - [ ] **Project Scaffolding CLI**: Interactive CLI tool that generates complete Next.js projects with pixelated-components pre-configured, including routes.json, layout.tsx, package.json, and basic page structure
323
- - [ ] **Template Marketplace**: Pre-built industry-specific templates (restaurant, law firm, contractor, etc.) that users can clone and customize
324
- - [ ] **Configuration Wizard**: Step-by-step setup wizard that collects business info, generates site configuration, and creates initial content structure
325
- - [ ] **Content Migration Tools**: Automated importers for WordPress, Squarespace, Wix, and other platforms to migrate content to pixelated sites
326
- - [ ] **A/B Testing Framework**: Built-in experimentation system for testing different layouts, content, and CTAs with automatic winner selection
327
- - [ ] **Personalization Engine**: Dynamic content delivery based on user behavior, location, and preferences
328
- - [ ] **Hot Module Replacement for Configs**: Live preview of configuration changes without full rebuilds
329
- - [ ] **Automated Dependency Updates**: Smart update system that tests component changes across all sites before deployment
330
- - [ ] **Rollback System**: One-click rollback to previous versions with automatic database and asset restoration
331
- - [ ] **Performance Budget Tracker**: Automated monitoring of Core Web Vitals with alerts when sites exceed performance budgets
332
- - [ ] **ConfigBuilder SEO Enhancement**: Upgrade ConfigBuilder with AI-powered meta description generation, keyword optimization suggestions, and automated schema markup
333
- - [ ] **Conversion Funnel Builder**: Visual funnel creation with automated tracking, A/B testing, and optimization recommendations
334
- - [ ] **Automated Security Scanner**: Regular security audits with vulnerability detection and automated fixes
335
- - [ ] **GDPR Compliance Toolkit**: Automated cookie consent, data mapping, and privacy policy generation
336
- - [ ] **API Gateway**: Unified API management for connecting to CRM, email marketing, payment processors, and other business tools
337
- - [ ] **Webhook Automation**: Event-driven automation for form submissions, new content, user registrations, and business workflows
338
- - [ ] **Third-Party Sync Engine**: Bidirectional sync with tools like HubSpot, Mailchimp, QuickBooks, and project management systems
339
- - [ ] **Testing Strategy for Config Failure Scenarios**: Comprehensive testing framework for config-dependent components and error handling
340
- - Test components with missing config providers
341
- - Test error pages without config dependencies
342
- - Test app initialization with invalid environment variables
343
- - Include chaos engineering tests that simulate config failures
344
- - [ ] **Documentation Auto-Generator**: Automatically generated API docs, component usage guides, and deployment instructions
292
+ ## 🚀 Roadmap
345
293
 
294
+ See our detailed [Roadmap](docs/roadmap.md) for planned improvements and refactoring initiatives.
346
295
 
347
- See the [open issues](https://github.com/brianwhaley/pixelated-components/issues) for a full list of proposed features (and known issues).
348
296
 
297
+ <!-- TESTING -->
298
+ ## 🧪 Testing
349
299
 
300
+ See our comprehensive [Testing Documentation](docs/testing.md) for test coverage, setup, and strategies.
350
301
 
351
302
 
352
303
  <!-- CONTRIBUTING -->
@@ -396,136 +347,6 @@ Project Link: [https://github.com/brianwhaley/pixelated-components](https://gith
396
347
 
397
348
 
398
349
 
399
- ## 🧪 Testing
400
-
401
- ### Overview
402
-
403
- **Current Status**: ✅ 2,387 tests passing across 79 test files
404
-
405
- | Metric | Value |
406
- |--------|-------|
407
- | Test Files | 79 |
408
- | Total Tests | 2,387 |
409
- | Coverage (Statements) | 77.13% |
410
- | Coverage (Lines) | 79.73% |
411
- | Coverage (Functions) | 77.98% |
412
- | Coverage (Branches) | 67.55% |
413
- | Test Framework | Vitest 4.x |
414
- | Testing Library | @testing-library/react + jsdom |
415
-
416
- ### Quick Start
417
-
418
- ```bash
419
- npm run test # Watch mode
420
- npm run test:ui # Interactive UI dashboard
421
- npm run test:coverage # Generate coverage reports
422
- npm run test:run # Single run (for CI)
423
- ```
424
-
425
- ### Component Coverage
426
-
427
- **Component Coverage Summary**
428
-
429
- #### Component Coverage (Sorted by Statement Coverage)
430
- - **site-health-cache.ts**: 100% statements *(new shared caching utility)*
431
- - **sites.integration.ts**: 100% statements *(new site management functions)*
432
- - **site-health-indicators.ts**: 100% statements
433
- - **tiles.tsx**: 100% statements
434
- - **google.reviews.functions.ts**: 100% statements
435
- - **accordion.tsx**: 100% statements
436
- - **modal.tsx**: 100% statements
437
- - **tab.tsx**: 100% statements
438
- - **ComponentPropertiesForm.tsx**: 100% statements
439
- - **ComponentSelector.tsx**: 100% statements
440
- - **ComponentTree.tsx**: 100% statements
441
- - **formvalidations.tsx**: 100% statements
442
- - **googlesearch.tsx**: 100% statements
443
- - **schema-localbusiness.tsx**: 100% statements
444
- - **schema-recipe.tsx**: 100% statements
445
- - **schema-services.tsx**: 100% statements
446
- - **schema-website.tsx**: 100% statements
447
- - **schema-blogposting.tsx**: 100% statements
448
- - **buzzwordbingo.tsx**: 100% statements
449
- - **markdown.tsx**: 100% statements
450
- - **timeline.tsx**: 100% statements
451
- - **config.client.tsx**: 100% statements
452
- - **sidepanel.tsx**: 97.5% statements
453
- - **config.ts**: 96.55% statements
454
- - **google.reviews.components.tsx**: 95.83% statements
455
- - **schema-blogposting.tsx**: 95.24% statements
456
- - **recipe.tsx**: 94.59% statements
457
- - **resume.tsx**: 94.38% statements
458
- - **contentful.delivery.ts**: 92.5% statements
459
- - **css.tsx**: 91.43% statements
460
- - **functions.ts**: 90.91% statements
461
- - **menu-expando.tsx**: 90.12% statements
462
- - **site-health-cloudwatch.tsx**: 88% statements
463
- - **loading.tsx**: 85.71% statements
464
- - **SaveLoadSection.tsx**: 84.85% statements
465
- - **table.tsx**: 84.48% statements
466
- - **ConfigBuilder.tsx**: 83.52% statements
467
- - **cloudinary.ts**: 83.33% statements
468
- - **formcomponents.tsx**: 83.33% statements
469
- - **form.tsx**: 83.2% statements
470
- - **shoppingcart.functions.ts**: 81.7% statements
471
- - **callout.tsx**: 80% statements
472
- - **microinteractions.tsx**: 80% statements
473
- - **smartimage.tsx**: 82.75% statements
474
- - **sitemap.ts**: 76.06% statements
475
- - **manifest.tsx**: 75% statements
476
- - **carousel.tsx**: 71.7% statements
477
- - **nerdjoke.tsx**: 69.44% statements
478
- - **menu-accordion.tsx**: 68.47% statements
479
- - **semantic.tsx**: 63.51% statements
480
- - **componentMap.tsx**: 60% statements
481
- - **propTypeIntrospection.tsx**: 60% statements
482
- - **wordpress.functions.ts**: 51.43% statements
483
- - **config.server.tsx**: 50% statements
484
- - **PageEngine.tsx**: 48% statements
485
- - **componentGeneration.tsx**: 38.89% statements
486
- - **socialcard.tsx**: 29.51% statements
487
- - **PageBuilderUI.tsx**: 26.67% statements
488
-
489
- ### Testing Next Steps
490
-
491
- #### Integration Testing Gaps
492
- - [ ] **Cross-component interactions** - Test how components work together (e.g., forms with validation, carousels with loading states)
493
- - [ ] **Form validation edge cases** - Test URL validation, required fields, and complex validation rules under various conditions
494
- - [ ] **CMS API integrations** - Test API failures, rate limiting, authentication errors, and network timeouts
495
- - [ ] **Responsive design breakpoints** - Test component behavior across different screen sizes and device types
496
- - [ ] **Accessibility (a11y) compliance** - Test keyboard navigation, screen reader compatibility, and ARIA attributes
497
-
498
- ### Test Configuration
499
-
500
-
501
- **Coverage Targets** (configured in `vitest.config.ts`):
502
- - **Statements**: 70% threshold
503
- - **Lines**: 70% threshold
504
- - **Functions**: 70% threshold
505
- - **Branches**: 60% threshold
506
-
507
- **Coverage Thresholds in vitest.config.ts**:
508
- - Lines: 70% threshold
509
- - Functions: 70% threshold
510
- - Branches: 60% threshold
511
- - Statements: 70% threshold
512
-
513
- **Test Environment**: jsdom with @testing-library/react
514
- **Test Pattern**: Data-focused validation + behavioral testing
515
-
516
- ### Tools & Dependencies
517
-
518
- | Tool | Purpose |
519
- |------|---------|
520
- | Vitest 4.x | Test runner |
521
- | @testing-library/react | Component testing utilities |
522
- | jsdom | DOM environment for tests |
523
- | v8 | Coverage reporting |
524
-
525
-
526
-
527
-
528
-
529
350
  <!-- MARKDOWN LINKS & IMAGES -->
530
351
  <!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
531
352
  [contributors-shield]: https://img.shields.io/github/contributors/brianwhaley/pixelated-components.svg?style=for-the-badge
@@ -71,13 +71,17 @@ export async function checkComponentUsage(sitePath, componentName) {
71
71
  ];
72
72
  for (const file of files) {
73
73
  const content = await fs.readFile(file, 'utf-8');
74
- if (content.includes('@pixelated-tech/components')) {
74
+ if (content.includes('@pixelated-tech/components') ||
75
+ content.includes('@pixelated-tech/components/adminclient') ||
76
+ content.includes('@pixelated-tech/components/adminserver')) {
75
77
  // Check if any semantic export is imported (case insensitive)
76
78
  for (const exportName of semanticExports) {
77
79
  const contentLower = content.toLowerCase();
78
80
  const exportNameLower = exportName.toLowerCase();
79
81
  if (contentLower.includes(exportNameLower) ||
80
- new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components`, 'i').test(content)) {
82
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components`, 'i').test(content) ||
83
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components/adminclient`, 'i').test(content) ||
84
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components/adminserver`, 'i').test(content)) {
81
85
  return true;
82
86
  }
83
87
  }
@@ -92,9 +96,13 @@ export async function checkComponentUsage(sitePath, componentName) {
92
96
  // Check for import statements - look for the actual export name (case insensitive)
93
97
  const contentLower = content.toLowerCase();
94
98
  const exportNameLower = exportName.toLowerCase();
95
- if (content.includes('@pixelated-tech/components') &&
99
+ if ((content.includes('@pixelated-tech/components') ||
100
+ content.includes('@pixelated-tech/components/adminclient') ||
101
+ content.includes('@pixelated-tech/components/adminserver')) &&
96
102
  (contentLower.includes(exportNameLower) ||
97
- new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components`, 'i').test(content))) {
103
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components`, 'i').test(content) ||
104
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components/adminclient`, 'i').test(content) ||
105
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components/adminserver`, 'i').test(content))) {
98
106
  return true;
99
107
  }
100
108
  }
@@ -44,19 +44,33 @@ function getPixelatedComponentsPath() {
44
44
  }
45
45
  }
46
46
  /**
47
- * Discover components dynamically by parsing the pixelated-components index
47
+ * Discover components dynamically by parsing the pixelated-components index files
48
48
  * This runs on the server side during API calls
49
49
  */
50
50
  export async function discoverComponentsFromLibrary() {
51
51
  try {
52
52
  // Get the pixelated-components package path
53
53
  const pixelatedPath = getPixelatedComponentsPath();
54
- // Look for the built dist/index.js file
54
+ const componentNames = [];
55
+ // Read from main index.js
55
56
  const indexPath = path.join(pixelatedPath, 'dist', 'index.js');
56
- // Read and parse the index.js file
57
- const indexContent = fs.readFileSync(indexPath, 'utf-8');
58
- const componentNames = parseComponentExports(indexContent);
59
- return componentNames;
57
+ if (fs.existsSync(indexPath)) {
58
+ const indexContent = fs.readFileSync(indexPath, 'utf-8');
59
+ componentNames.push(...parseComponentExports(indexContent));
60
+ }
61
+ // Read from adminclient index
62
+ const adminClientPath = path.join(pixelatedPath, 'dist', 'index.adminclient.js');
63
+ if (fs.existsSync(adminClientPath)) {
64
+ const adminClientContent = fs.readFileSync(adminClientPath, 'utf-8');
65
+ componentNames.push(...parseComponentExports(adminClientContent));
66
+ }
67
+ // Read from adminserver index
68
+ const adminServerPath = path.join(pixelatedPath, 'dist', 'index.adminserver.js');
69
+ if (fs.existsSync(adminServerPath)) {
70
+ const adminServerContent = fs.readFileSync(adminServerPath, 'utf-8');
71
+ componentNames.push(...parseComponentExports(adminServerContent));
72
+ }
73
+ return [...new Set(componentNames)].sort(); // Remove duplicates and sort alphabetically
60
74
  }
61
75
  catch (error) {
62
76
  console.error('Error in dynamic component discovery:', error);
@@ -1,8 +1,12 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useCallback } from 'react';
4
+ import PropTypes from 'prop-types';
4
5
  import { SiteHealthTemplate } from './site-health-template';
5
6
  import { getScoreIndicator } from './site-health-indicators';
7
+ SiteHealthAccessibility.propTypes = {
8
+ siteName: PropTypes.string.isRequired,
9
+ };
6
10
  export function SiteHealthAccessibility({ siteName }) {
7
11
  const fetchAccessibilityData = useCallback(async (site) => {
8
12
  const response = await fetch(`/api/site-health/core-web-vitals?siteName=${encodeURIComponent(site)}`);
@@ -116,7 +120,7 @@ export function SiteHealthAccessibility({ siteName }) {
116
120
  width: `${(siteData.scores.accessibility || 0) * 100}%`,
117
121
  backgroundColor: getScoreColor(siteData.scores.accessibility)
118
122
  } }) })] }) })), siteData.categories.accessibility && siteData.categories.accessibility.audits.length > 0 && (_jsxs("div", { children: [_jsx("h5", { style: { fontSize: '1rem', fontWeight: '600', marginBottom: '1rem' }, children: "Accessibility Issues & Recommendations" }), _jsx("div", { className: "space-y-2", children: siteData.categories.accessibility.audits
119
- .filter(audit => audit.scoreDisplayMode !== 'notApplicable')
123
+ .filter((audit) => audit.scoreDisplayMode !== 'notApplicable')
120
124
  .sort((a, b) => {
121
125
  // Prioritize specific important accessibility audits
122
126
  const priorityAudits = [
@@ -1,8 +1,12 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useCallback } from 'react';
4
+ import PropTypes from 'prop-types';
4
5
  import { SiteHealthTemplate } from './site-health-template';
5
6
  import { getImpactIndicator, getIncompleteIndicator, getPassingIndicator } from './site-health-indicators';
7
+ SiteHealthAxeCore.propTypes = {
8
+ siteName: PropTypes.string.isRequired,
9
+ };
6
10
  export function SiteHealthAxeCore({ siteName }) {
7
11
  const fetchAxeCoreData = useCallback(async (site) => {
8
12
  const response = await fetch(`/api/site-health/axe-core?siteName=${encodeURIComponent(site)}`);
@@ -28,7 +28,6 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
28
28
  // Add 1 day to end time to include the full end date
29
29
  const endTimePlusOne = new Date(endTime);
30
30
  endTimePlusOne.setDate(endTimePlusOne.getDate() + 1);
31
- console.log(`CloudWatch: Fetching data for health check ${config.healthCheckId} from ${startTime.toISOString()} to ${endTimePlusOne.toISOString()}`);
32
31
  const metricDataQuery = {
33
32
  MetricDataQueries: [
34
33
  {
@@ -55,9 +54,7 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
55
54
  };
56
55
  const command = new GetMetricDataCommand(metricDataQuery);
57
56
  const response = await cloudWatchClient.send(command);
58
- console.log(`CloudWatch: Received ${response.MetricDataResults?.[0]?.Timestamps?.length || 0} data points`);
59
57
  if (!response.MetricDataResults || response.MetricDataResults.length === 0) {
60
- console.log(`CloudWatch: No metric data found for health check ${config.healthCheckId}`);
61
58
  return {
62
59
  success: false,
63
60
  error: 'No health check metric data found'
@@ -65,7 +62,6 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
65
62
  }
66
63
  const metricResult = response.MetricDataResults[0];
67
64
  if (!metricResult.Timestamps || !metricResult.Values) {
68
- console.log(`CloudWatch: No timestamps or values in metric data`);
69
65
  return {
70
66
  success: false,
71
67
  error: 'No health check metric data available'
@@ -101,7 +97,6 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
101
97
  };
102
98
  })
103
99
  .sort((a, b) => a.date.localeCompare(b.date));
104
- console.log(`CloudWatch: Processed ${data.length} date groups with data`);
105
100
  // Fill in the date range with data points for each day
106
101
  let filledData = [];
107
102
  if (startDate && endDate) {
@@ -1,7 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import PropTypes from 'prop-types';
3
4
  import { ComposedChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthCloudwatch.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ startDate: PropTypes.string,
9
+ endDate: PropTypes.string,
10
+ };
5
11
  export function SiteHealthCloudwatch({ siteName, startDate, endDate }) {
6
12
  const fetchCloudwatchData = async (site) => {
7
13
  const params = new URLSearchParams({ siteName: site });
@@ -29,7 +35,7 @@ export function SiteHealthCloudwatch({ siteName, startDate, endDate }) {
29
35
  return (_jsx("div", { className: "flex items-center justify-center h-64", children: _jsx("div", { className: "text-gray-500", children: "No uptime data available. Route53 health checks may not be configured to send metrics to CloudWatch." }) }));
30
36
  }
31
37
  // Check if all data points have zero checks (no actual data)
32
- const hasActualData = data.some(point => point.totalChecks > 0);
38
+ const hasActualData = data.some((point) => point.totalChecks > 0);
33
39
  if (!hasActualData) {
34
40
  return (_jsx("div", { className: "flex items-center justify-center h-64", children: _jsxs("div", { className: "text-gray-500", children: ["Health check exists but has no metric data in CloudWatch for the selected period.", _jsx("br", {}), "Route53 health checks must be configured to send metrics to CloudWatch for historical data."] }) }));
35
41
  }
@@ -1,7 +1,11 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useCallback } from 'react';
4
+ import PropTypes from 'prop-types';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthDependencyVulnerabilities.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ };
5
9
  export function SiteHealthDependencyVulnerabilities({ siteName }) {
6
10
  const fetchDependencyData = useCallback(async (site) => {
7
11
  const response = await fetch(`/api/site-health/security?siteName=${encodeURIComponent(site)}`);
@@ -1,7 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import PropTypes from 'prop-types';
3
4
  import { Table } from '@pixelated-tech/components';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthGit.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ startDate: PropTypes.string,
9
+ endDate: PropTypes.string,
10
+ };
5
11
  export function SiteHealthGit({ siteName, startDate, endDate }) {
6
12
  const fetchGitData = async (site) => {
7
13
  const params = new URLSearchParams({ site: encodeURIComponent(site) });
@@ -1,7 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import PropTypes from 'prop-types';
3
4
  import { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthGoogleAnalytics.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ startDate: PropTypes.string,
9
+ endDate: PropTypes.string,
10
+ };
5
11
  export function SiteHealthGoogleAnalytics({ siteName, startDate, endDate }) {
6
12
  const fetchAnalyticsData = async (site) => {
7
13
  const params = new URLSearchParams({ siteName: site });
@@ -1,7 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import PropTypes from 'prop-types';
3
4
  import { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthGoogleSearchConsole.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ startDate: PropTypes.string,
9
+ endDate: PropTypes.string,
10
+ };
5
11
  export function SiteHealthGoogleSearchConsole({ siteName, startDate, endDate }) {
6
12
  const fetchSearchConsoleData = async (site) => {
7
13
  const params = new URLSearchParams({ siteName: site });