@pixelated-tech/components 3.12.0 → 3.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/components/admin/componentusage/componentAnalysis.js +2 -0
  2. package/dist/components/admin/deploy/deployment.integration.js +8 -0
  3. package/dist/components/admin/site-health/site-health-dependency-vulnerabilities.js +3 -1
  4. package/dist/components/config/config.js +41 -2
  5. package/dist/components/general/buzzwordbingo.css +8 -8
  6. package/dist/components/general/buzzwordbingo.js +3 -3
  7. package/dist/components/general/countup.css +19 -0
  8. package/dist/components/general/countup.js +62 -0
  9. package/dist/components/general/global-error.css +1 -1
  10. package/dist/components/general/global-error.js +1 -1
  11. package/dist/components/general/menu-accordion.css +24 -24
  12. package/dist/components/general/menu-accordion.js +13 -13
  13. package/dist/components/general/menu-expando.css +4 -4
  14. package/dist/components/general/menu-expando.js +7 -7
  15. package/dist/components/general/metadata.functions.js +1 -1
  16. package/dist/components/general/microinteractions.css +1 -1
  17. package/dist/components/general/nerdjoke.css +5 -5
  18. package/dist/components/general/nerdjoke.js +2 -2
  19. package/dist/components/general/recipe.css +1 -1
  20. package/dist/components/general/recipe.js +1 -1
  21. package/dist/components/general/semantic.js +1 -1
  22. package/dist/components/general/sidepanel.css +3 -3
  23. package/dist/components/general/skeleton.css +4 -4
  24. package/dist/components/general/skeleton.js +3 -3
  25. package/dist/components/general/styleguide.js +2 -2
  26. package/dist/components/general/table.css +6 -6
  27. package/dist/components/general/table.js +5 -5
  28. package/dist/components/general/tiles.js +3 -2
  29. package/dist/components/general/well-known.js +137 -0
  30. package/dist/components/integrations/contentful.management.js +25 -25
  31. package/dist/components/integrations/socialcard.css +6 -6
  32. package/dist/components/integrations/socialcard.js +2 -2
  33. package/dist/components/integrations/wordpress.components.js +1 -1
  34. package/dist/components/integrations/wordpress.css +2 -2
  35. package/dist/components/shoppingcart/ebay.components.js +11 -11
  36. package/dist/components/shoppingcart/ebay.css +20 -20
  37. package/dist/components/shoppingcart/shoppingcart.components.js +11 -11
  38. package/dist/components/shoppingcart/shoppingcart.css +19 -19
  39. package/dist/components/sitebuilder/form/form.css +4 -4
  40. package/dist/components/sitebuilder/form/formcomponents.js +3 -3
  41. package/dist/components/sitebuilder/page/components/PageBuilderUI.js +2 -2
  42. package/dist/components/sitebuilder/page/lib/pageStorageContentful.js +4 -4
  43. package/dist/config/pixelated.config.json.enc +1 -1
  44. package/dist/css/pixelated.grid.scss +1 -1
  45. package/dist/index.js +1 -1
  46. package/dist/index.server.js +3 -4
  47. package/dist/scripts/pixelated-eslint-plugin.js +51 -3
  48. package/dist/types/components/admin/componentusage/componentAnalysis.d.ts +2 -5
  49. package/dist/types/components/admin/componentusage/componentAnalysis.d.ts.map +1 -1
  50. package/dist/types/components/admin/deploy/deployment.integration.d.ts +1 -5
  51. package/dist/types/components/admin/deploy/deployment.integration.d.ts.map +1 -1
  52. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts.map +1 -1
  53. package/dist/types/components/admin/site-health/site-health-github.integration.d.ts +1 -11
  54. package/dist/types/components/admin/site-health/site-health-github.integration.d.ts.map +1 -1
  55. package/dist/types/components/admin/sites/sites.integration.d.ts +7 -1
  56. package/dist/types/components/admin/sites/sites.integration.d.ts.map +1 -1
  57. package/dist/types/components/config/config.d.ts.map +1 -1
  58. package/dist/types/components/config/config.types.d.ts +2 -2
  59. package/dist/types/components/config/config.types.d.ts.map +1 -1
  60. package/dist/types/components/general/countup.d.ts +17 -0
  61. package/dist/types/components/general/countup.d.ts.map +1 -0
  62. package/dist/types/components/general/tiles.d.ts.map +1 -1
  63. package/dist/types/components/general/well-known.d.ts +56 -0
  64. package/dist/types/components/general/well-known.d.ts.map +1 -0
  65. package/dist/types/components/integrations/contentful.management.d.ts +1 -5
  66. package/dist/types/components/integrations/contentful.management.d.ts.map +1 -1
  67. package/dist/types/components/shoppingcart/ebay.functions.d.ts +2 -2
  68. package/dist/types/components/shoppingcart/ebay.functions.d.ts.map +1 -1
  69. package/dist/types/components/shoppingcart/paypal.d.ts.map +1 -1
  70. package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts +20 -12
  71. package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts.map +1 -1
  72. package/dist/types/components/sitebuilder/page/lib/pageStorageContentful.d.ts +1 -1
  73. package/dist/types/components/sitebuilder/page/lib/pageStorageContentful.d.ts.map +1 -1
  74. package/dist/types/index.d.ts +1 -1
  75. package/dist/types/index.server.d.ts +3 -4
  76. package/dist/types/scripts/pixelated-eslint-plugin.d.ts +18 -0
  77. package/dist/types/stories/general/countup.stories.d.ts +47 -0
  78. package/dist/types/stories/general/countup.stories.d.ts.map +1 -0
  79. package/dist/types/tests/securitytxt.test.d.ts +2 -0
  80. package/dist/types/tests/securitytxt.test.d.ts.map +1 -0
  81. package/package.json +23 -13
  82. package/dist/components/config/config.utils.js +0 -52
  83. package/dist/components/general/humanstxt.js +0 -81
  84. package/dist/types/components/config/config.utils.d.ts +0 -6
  85. package/dist/types/components/config/config.utils.d.ts.map +0 -1
  86. package/dist/types/components/general/humanstxt.d.ts +0 -37
  87. package/dist/types/components/general/humanstxt.d.ts.map +0 -1
@@ -128,5 +128,5 @@ export function generateMetaTags(props) {
128
128
  const image_height = prop_image_height || siteInfo?.image_height;
129
129
  const image_width = prop_image_width || siteInfo?.image_width;
130
130
  const favicon = prop_favicon || siteInfo?.favicon;
131
- return (_jsxs(_Fragment, { children: [_jsx("title", { children: title }), _jsx("meta", { charSet: "UTF-8" }), _jsx("meta", { httpEquiv: "content-type", content: "text/html; charset=UTF-8" }), _jsx("meta", { httpEquiv: 'Expires', content: '0' }), _jsx("meta", { httpEquiv: 'Pragma', content: 'no-cache' }), _jsx("meta", { httpEquiv: 'Cache-Control', content: 'no-cache' }), _jsx("meta", { name: "application-name", content: site_name }), _jsx("meta", { name: "author", content: site_name + ", " + email }), _jsx("meta", { name: 'copyright', content: site_name }), _jsx("meta", { name: "creator", content: site_name }), _jsx("meta", { name: "description", content: description }), _jsx("meta", { name: "keywords", content: keywords }), _jsx("meta", { name: 'language', content: 'EN' }), _jsx("meta", { name: 'owner', content: site_name }), _jsx("meta", { name: "publisher", content: site_name }), _jsx("meta", { name: 'rating', content: 'General' }), _jsx("meta", { name: 'reply-to', content: email }), _jsx("meta", { name: "robots", content: "index, follow" }), _jsx("meta", { name: 'url', content: url }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0, shrink-to-fit=no" }), _jsx("meta", { property: "og:description", content: description }), _jsx("meta", { property: 'og:email', content: email }), _jsx("meta", { property: "og:image", content: image }), _jsx("meta", { property: "og:image:height", content: image_height != null ? String(image_height) : undefined }), _jsx("meta", { property: "og:image:width", content: image_width != null ? String(image_width) : undefined }), _jsx("meta", { property: "og:locale", content: "en_US" }), _jsx("meta", { property: "og:site_name", content: site_name }), _jsx("meta", { property: "og:title", content: title }), _jsx("meta", { property: "og:type", content: "website" }), _jsx("meta", { property: "og:url", content: url }), _jsx("meta", { itemProp: "name", content: site_name }), _jsx("meta", { itemProp: "url", content: url }), _jsx("meta", { itemProp: "description", content: description }), _jsx("meta", { itemProp: "thumbnailUrl", content: image }), _jsx("meta", { property: "twitter:domain", content: newOrigin }), _jsx("meta", { property: "twitter:url", content: url }), _jsx("meta", { name: "twitter:card", content: "summary_large_image" }), _jsx("meta", { name: "twitter:creator", content: site_name }), _jsx("meta", { name: "twitter:description", content: description }), _jsx("meta", { name: "twitter:image", content: image }), _jsx("meta", { name: "twitter:image:height", content: image_height != null ? String(image_height) : undefined }), _jsx("meta", { name: "twitter:image:width", content: image_width != null ? String(image_width) : undefined }), _jsx("meta", { name: "twitter:title", content: title }), _jsx("link", { rel: "author", href: newOrigin }), _jsx("link", { rel: "canonical", href: url }), _jsx("link", { rel: "icon", type: "image/x-icon", href: favicon }), _jsx("link", { rel: "shortcut icon", type: "image/x-icon", href: favicon }), _jsx("link", { rel: "manifest", href: "/manifest.webmanifest" }), _jsx("link", { rel: "preconnect", href: "https://images.ctfassets.net/" }), _jsx("link", { rel: "preconnect", href: "https://res.cloudinary.com/" }), _jsx("link", { rel: "preconnect", href: "https://farm2.static.flickr.com" }), _jsx("link", { rel: "preconnect", href: "https://farm6.static.flickr.com" }), _jsx("link", { rel: "preconnect", href: "https://farm8.static.flickr.com" }), _jsx("link", { rel: "preconnect", href: "https://farm66.static.flickr.com" })] }));
131
+ return (_jsxs(_Fragment, { children: [_jsx("title", { children: title }), _jsx("meta", { charSet: "UTF-8" }), _jsx("meta", { httpEquiv: "content-type", content: "text/html; charset=UTF-8" }), _jsx("meta", { httpEquiv: 'Expires', content: '0' }), _jsx("meta", { httpEquiv: 'Pragma', content: 'no-cache' }), _jsx("meta", { httpEquiv: 'Cache-Control', content: 'no-cache' }), _jsx("meta", { name: "application-name", content: site_name }), _jsx("meta", { name: "author", content: site_name + ", " + email }), _jsx("meta", { name: 'copyright', content: site_name }), _jsx("meta", { name: "creator", content: site_name }), _jsx("meta", { name: "description", content: description }), _jsx("meta", { name: "keywords", content: keywords }), _jsx("meta", { name: 'language', content: 'EN' }), _jsx("meta", { name: 'owner', content: site_name }), _jsx("meta", { name: "publisher", content: site_name }), _jsx("meta", { name: 'rating', content: 'General' }), _jsx("meta", { name: 'reply-to', content: email }), _jsx("meta", { name: "robots", content: "index, follow" }), _jsx("meta", { name: 'url', content: url }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0, shrink-to-fit=no" }), _jsx("meta", { property: "og:description", content: description }), _jsx("meta", { property: 'og:email', content: email }), _jsx("meta", { property: "og:image", content: image }), _jsx("meta", { property: "og:image:height", content: image_height != null ? String(image_height) : undefined }), _jsx("meta", { property: "og:image:width", content: image_width != null ? String(image_width) : undefined }), _jsx("meta", { property: "og:locale", content: "en_US" }), _jsx("meta", { property: "og:site_name", content: site_name }), _jsx("meta", { property: "og:title", content: title }), _jsx("meta", { property: "og:type", content: "website" }), _jsx("meta", { property: "og:url", content: url }), _jsx("meta", { itemProp: "name", content: site_name }), _jsx("meta", { itemProp: "url", content: url }), _jsx("meta", { itemProp: "description", content: description }), _jsx("meta", { itemProp: "thumbnailUrl", content: image }), _jsx("meta", { property: "twitter:domain", content: newOrigin }), _jsx("meta", { property: "twitter:url", content: url }), _jsx("meta", { name: "twitter:card", content: "summary_large_image" }), _jsx("meta", { name: "twitter:creator", content: site_name }), _jsx("meta", { name: "twitter:description", content: description }), _jsx("meta", { name: "twitter:image", content: image }), _jsx("meta", { name: "twitter:image:height", content: image_height != null ? String(image_height) : undefined }), _jsx("meta", { name: "twitter:image:width", content: image_width != null ? String(image_width) : undefined }), _jsx("meta", { name: "twitter:title", content: title }), _jsx("link", { rel: "author", href: "humans.txt" }), _jsx("link", { rel: "canonical", href: url }), _jsx("link", { rel: "icon", type: "image/x-icon", href: favicon }), _jsx("link", { rel: "shortcut icon", type: "image/x-icon", href: favicon }), _jsx("link", { rel: "manifest", href: "/manifest.webmanifest" }), _jsx("link", { rel: "preconnect", href: "https://images.ctfassets.net/" }), _jsx("link", { rel: "preconnect", href: "https://res.cloudinary.com/" }), _jsx("link", { rel: "preconnect", href: "https://farm2.static.flickr.com" }), _jsx("link", { rel: "preconnect", href: "https://farm6.static.flickr.com" }), _jsx("link", { rel: "preconnect", href: "https://farm8.static.flickr.com" }), _jsx("link", { rel: "preconnect", href: "https://farm66.static.flickr.com" })] }));
132
132
  }
@@ -43,7 +43,7 @@ body.buttonring {
43
43
  box-shadow: 0 0 0 10px rgba(0, 0, 0, 0);
44
44
  }
45
45
  }
46
- body.cartpulse .pixCart #pixCartButton {
46
+ body.cartpulse .pix-cart #pix-cart-button {
47
47
  animation: pulse-glow 2s infinite;
48
48
  }
49
49
 
@@ -3,12 +3,12 @@
3
3
  =============== NERDJOKE ===============
4
4
  ======================================== */
5
5
 
6
- .nerdJoke {
6
+ .nerd-joke {
7
7
  padding-bottom: 20px;
8
8
  font-size: 24px;
9
9
  }
10
10
 
11
- .nerdJoke .jokeText div {
11
+ .nerd-joke .joke-text div {
12
12
  padding-bottom: 15px;
13
13
  }
14
14
 
@@ -20,7 +20,7 @@
20
20
  font-weight: bold;
21
21
  }
22
22
 
23
- .jokeButton {
23
+ .joke-button {
24
24
  /* background-image: url(/images/pix/pix-bg-sm-bw.gif); */
25
25
  border: 1px solid #999;
26
26
  display: inline-block;
@@ -44,14 +44,14 @@
44
44
  }
45
45
 
46
46
 
47
- .jokeTimer {
47
+ .joke-timer {
48
48
  border: 1px solid #AAA;
49
49
  position: relative;
50
50
  /* height: 25px;
51
51
  width: 100%; */
52
52
  }
53
53
 
54
- .jokeTimerSvg {
54
+ .joke-timer-svg {
55
55
  width: 100%;
56
56
  height: 10px;
57
57
  fill: rgb(190,190,190);
@@ -103,7 +103,7 @@ export function NerdJoke(props) {
103
103
  }
104
104
  };
105
105
  }, [loadJoke, startTimer]);
106
- return (_jsx("div", { className: "nerdJoke", children: _jsxs("div", { className: "row-12col", children: [_jsx("div", { className: "grid-s1-e5", children: _jsx("div", { className: "left", children: _jsx(JokeButton, { clickFunction: pauseTimer, buttonText: "Pause || / Play >" }) }) }), _jsx("div", { className: "grid-s9-e13", children: _jsx("div", { className: "right", children: _jsx(JokeButton, { clickFunction: loadJoke, buttonText: "Next Joke ->" }) }) }), _jsx("div", { className: "jokeTimer grid-s1-e13", children: _jsxs("div", { className: "row-12col", children: [_jsx("div", { className: "grid-s1-e11", children: _jsx("svg", { className: "jokeTimerSvg", xmlns: "http://www.w3.org/2000/svg", children: _jsx("rect", { id: "jokeTimerPathElapsed" }) }) }), _jsx("div", { className: "grid-s11-e13 center", id: "jokeTimerLabel", children: formatTimeLeft(timeLeftRef.current) })] }) }), _jsxs("div", { className: "jokeText grid-s1-e13", children: [_jsxs("div", { children: [_jsx("span", { className: "label", children: "Q: " }), _jsxs("span", { className: "question", children: [" ", joke.question, " "] })] }), _jsxs("div", { children: [_jsx("span", { className: "label", children: "A: " }), _jsxs("span", { className: "answer", children: [" ", joke.answer, " "] })] })] })] }) }));
106
+ return (_jsx("div", { className: "nerd-joke", children: _jsxs("div", { className: "row-12col", children: [_jsx("div", { className: "grid-s1-e5", children: _jsx("div", { className: "left", children: _jsx(JokeButton, { clickFunction: pauseTimer, buttonText: "Pause || / Play >" }) }) }), _jsx("div", { className: "grid-s9-e13", children: _jsx("div", { className: "right", children: _jsx(JokeButton, { clickFunction: loadJoke, buttonText: "Next Joke ->" }) }) }), _jsx("div", { className: "joke-timer grid-s1-e13", children: _jsxs("div", { className: "row-12col", children: [_jsx("div", { className: "grid-s1-e11", children: _jsx("svg", { className: "joke-timer-svg", xmlns: "http://www.w3.org/2000/svg", children: _jsx("rect", { id: "jokeTimerPathElapsed" }) }) }), _jsx("div", { className: "grid-s11-e13 center", id: "jokeTimerLabel", children: formatTimeLeft(timeLeftRef.current) })] }) }), _jsxs("div", { className: "joke-text grid-s1-e13", children: [_jsxs("div", { children: [_jsx("span", { className: "label", children: "Q: " }), _jsxs("span", { className: "question", children: [" ", joke.question, " "] })] }), _jsxs("div", { children: [_jsx("span", { className: "label", children: "A: " }), _jsxs("span", { className: "answer", children: [" ", joke.answer, " "] })] })] })] }) }));
107
107
  }
108
108
  JokeButton.propTypes = {
109
109
  /** Click handler invoked when the button is pressed (e.g., pause or fetch next). */
@@ -115,5 +115,5 @@ function JokeButton(props) {
115
115
  /* <div className="jokeButton" onClick={props.clickFunction}>
116
116
  {props.buttonText}
117
117
  </div> */
118
- return (_jsx("button", { className: "jokeButton", onClick: props.clickFunction, children: props.buttonText }));
118
+ return (_jsx("button", { className: "joke-button", onClick: props.clickFunction, children: props.buttonText }));
119
119
  }
@@ -86,7 +86,7 @@
86
86
  ========== BACK TO TOP ==============
87
87
  ======================================== */
88
88
 
89
- .backToTop {
89
+ .back-to-top {
90
90
  background: #FFF;
91
91
  border: 1px solid #CCC;
92
92
  color: #000;
@@ -259,5 +259,5 @@ export function BackToTop() {
259
259
  return false;
260
260
  }
261
261
  const config = usePixelatedConfig();
262
- return (_jsx("div", { className: "backToTop", children: _jsxs("a", { href: "#top", onClick: scrollToTop, children: [_jsx("div", { children: _jsx(SmartImage, { src: "/images/icons/up.jpg", title: "Back To Top", alt: "Back To Top", cloudinaryEnv: config?.cloudinary?.product_env ?? undefined, cloudinaryDomain: config?.cloudinary?.baseUrl ?? undefined, cloudinaryTransforms: config?.cloudinary?.transforms ?? undefined }) }), _jsx("div", { children: "Back To Top" })] }) }));
262
+ return (_jsx("div", { className: "back-to-top", children: _jsxs("a", { href: "#top", onClick: scrollToTop, children: [_jsx("div", { children: _jsx(SmartImage, { src: "/images/icons/up.jpg", title: "Back To Top", alt: "Back To Top", cloudinaryEnv: config?.cloudinary?.product_env ?? undefined, cloudinaryDomain: config?.cloudinary?.baseUrl ?? undefined, cloudinaryTransforms: config?.cloudinary?.transforms ?? undefined }) }), _jsx("div", { children: "Back To Top" })] }) }));
263
263
  }
@@ -243,7 +243,7 @@ export function PageGridItem({ id, className, columnSpan, rowSpan, columnStart,
243
243
  return (
244
244
  /* THIS IS AN OLD STYLE */
245
245
  /* <div className={"grid-item" + */
246
- _jsx("div", { className: "gridItem" +
246
+ _jsx("div", { className: "grid-item" +
247
247
  (className ? ` ${className}` : '') +
248
248
  (columnStart && columnSpan && !columnEnd ? ` grid-s${columnStart}-w${columnSpan}` : '') +
249
249
  (columnStart && columnEnd && !columnSpan ? ` grid-s${columnStart}-e${columnEnd}` : ''), id: (id) ? id : undefined, style: itemStyle, children: children }));
@@ -110,7 +110,7 @@
110
110
  .sidepanel-tab-label { display: none; }
111
111
 
112
112
  /* Integration overrides for MenuAccordion inside SidePanel */
113
- .sidepanel-content .accordionMenuWrapper {
113
+ .sidepanel-content .accordion-menu-wrapper {
114
114
  position: relative !important;
115
115
  top: auto !important;
116
116
  left: auto !important;
@@ -123,7 +123,7 @@
123
123
  }
124
124
 
125
125
  /* Ensure the inner list takes full width */
126
- .sidepanel-content .accordionMenu,
127
- .sidepanel-content .accordionMenu ul {
126
+ .sidepanel-content .accordion-menu,
127
+ .sidepanel-content .accordion-menu ul {
128
128
  width: 100% !important;
129
129
  }
@@ -8,18 +8,18 @@
8
8
  min-height: 0;
9
9
  }
10
10
 
11
- .skeleton--animated {
11
+ .skeleton-animated {
12
12
  animation: pulse 1.5s ease-in-out infinite;
13
13
  }
14
14
 
15
- .skeleton--avatar {
15
+ .skeleton-avatar {
16
16
  width: 3rem;
17
17
  height: 3rem;
18
18
  border-radius: 9999px;
19
19
  display: inline-block;
20
20
  }
21
21
 
22
- .skeleton--rect {
22
+ .skeleton-rect {
23
23
  display: block;
24
24
  width: 100%;
25
25
  height: 160px;
@@ -44,5 +44,5 @@
44
44
  }
45
45
 
46
46
  @media (prefers-reduced-motion: reduce) {
47
- .skeleton--animated { animation: none }
47
+ .skeleton-animated { animation: none }
48
48
  }
@@ -24,13 +24,13 @@ Skeleton.propTypes = {
24
24
  animated: PropTypes.bool,
25
25
  };
26
26
  export function Skeleton({ variant = 'text', lines = 1, width, height, animated = true, }) {
27
- const base = `skeleton ${animated ? 'skeleton--animated' : ''}`;
27
+ const base = `skeleton ${animated ? 'skeleton-animated' : ''}`;
28
28
  if (variant === 'avatar') {
29
29
  const avatarStyle = width != null || height != null ? { ...(width != null ? { width } : {}), ...(height != null ? { height } : {}) } : undefined;
30
- return _jsx("div", { "aria-hidden": "true", className: `${base} skeleton--avatar`, style: avatarStyle });
30
+ return _jsx("div", { "aria-hidden": "true", className: `${base} skeleton-avatar`, style: avatarStyle });
31
31
  }
32
32
  if (variant === 'rect') {
33
- return (_jsx("div", { "aria-hidden": "true", className: `${base} skeleton--rect`, style: { width: width ?? '100%', height: height ?? 160 } }));
33
+ return (_jsx("div", { "aria-hidden": "true", className: `${base} skeleton-rect`, style: { width: width ?? '100%', height: height ?? 160 } }));
34
34
  }
35
35
  return (_jsx("div", { "aria-hidden": "true", className: "skeleton-text", children: Array.from({ length: Math.max(1, Number(lines || 1)) }).map((_, i) => (_jsx("div", { className: base + ' skeleton-line', style: { width: typeof width === 'number' ? `${width}%` : (width ?? (i === (lines || 1) - 1 ? '60%' : '100%')) } }, i))) }));
36
36
  }
@@ -24,8 +24,8 @@ export function StyleGuideUI(props) {
24
24
  const bodyFonts = getComputedStyle(document.documentElement).getPropertyValue("--body-font").trim();
25
25
  primaryBodyFont = bodyFonts.split(',')[0].replaceAll('"', '').replaceAll("'", '');
26
26
  }
27
- return (_jsxs(_Fragment, { children: [_jsx(PageTitleHeader, { title: "Style Guide" }), _jsxs(PageSection, { columns: 1, maxWidth: "1024px", padding: "20px", id: "colors-section", children: [_jsx("h2", { children: "Color Palette" }), _jsxs("div", { style: { display: 'flex', gap: '10px', flexWrap: 'wrap' }, children: [_jsx("div", { style: { backgroundColor: 'var(--primary-color)', color: '#fff' }, className: "colorSwatch", children: "Primary Color" }), _jsx("div", { style: { backgroundColor: 'var(--secondary-color)' }, className: "colorSwatch", children: "Secondary Color" }), _jsx("div", { style: { backgroundColor: 'var(--accent1-color)' }, className: "colorSwatch", children: "Accent 1 Color" }), _jsx("div", { style: { backgroundColor: 'var(--accent2-color)' }, className: "colorSwatch", children: "Accent 2 Color" }), _jsx("div", { style: { backgroundColor: 'var(--bg-color)' }, className: "colorSwatch", children: "Background Color" }), _jsx("div", { style: { backgroundColor: 'var(--text-color)' }, className: "colorSwatch", children: "Text Color" })] })] }), _jsx("style", { children: `
28
- .colorSwatch {
27
+ return (_jsxs(_Fragment, { children: [_jsx(PageTitleHeader, { title: "Style Guide" }), _jsxs(PageSection, { columns: 1, maxWidth: "1024px", padding: "20px", id: "colors-section", children: [_jsx("h2", { children: "Color Palette" }), _jsxs("div", { style: { display: 'flex', gap: '10px', flexWrap: 'wrap' }, children: [_jsx("div", { style: { backgroundColor: 'var(--primary-color)', color: '#fff' }, className: "color-swatch", children: "Primary Color" }), _jsx("div", { style: { backgroundColor: 'var(--secondary-color)' }, className: "color-swatch", children: "Secondary Color" }), _jsx("div", { style: { backgroundColor: 'var(--accent1-color)' }, className: "color-swatch", children: "Accent 1 Color" }), _jsx("div", { style: { backgroundColor: 'var(--accent2-color)' }, className: "color-swatch", children: "Accent 2 Color" }), _jsx("div", { style: { backgroundColor: 'var(--bg-color)' }, className: "color-swatch", children: "Background Color" }), _jsx("div", { style: { backgroundColor: 'var(--text-color)' }, className: "color-swatch", children: "Text Color" })] })] }), _jsx("style", { children: `
28
+ .color-swatch {
29
29
  color: #000;
30
30
  border: 1px solid #ccc;
31
31
  padding: 10px;
@@ -1,13 +1,13 @@
1
- table.pixTable, .pixTable th, .pixTable tr, .pixTable td {
1
+ table.pix-table, .pix-table th, .pix-table tr, .pix-table td {
2
2
  border : 1px solid #ccc ;
3
3
  text-align: left;
4
4
  }
5
5
 
6
- table.pixTable {
6
+ table.pix-table {
7
7
  width: 100%
8
8
  }
9
9
 
10
- table.pixTable {
10
+ table.pix-table {
11
11
  th {
12
12
  text-transform: uppercase;
13
13
  font-size: 1.2em;
@@ -60,14 +60,14 @@ dialog {
60
60
  }
61
61
 
62
62
 
63
- .sortArrow {
63
+ .sort-arrow {
64
64
  display: inline-block;
65
65
  margin-left: 5px;
66
66
  font-size: 0.8em;
67
67
  }
68
- .sortArrow.asc::before {
68
+ .sort-arrow.asc::before {
69
69
  content: '▲'; /* Up arrow for ascending */
70
70
  }
71
- .sortArrow.desc::before {
71
+ .sort-arrow.desc::before {
72
72
  content: '▼'; /* Down arrow for descending */
73
73
  }
@@ -38,7 +38,7 @@ export function Table(props) {
38
38
  function getHeadings(data) {
39
39
  const headings = Object.keys(data[0]).map((key, i) => {
40
40
  return (props.sortable && props.sortable == true)
41
- ? _jsxs("th", { onClick: () => { sortTable(key); }, children: [_jsx("span", { children: key }), " ", _jsx("span", { className: "sortArrow" })] }, i)
41
+ ? _jsxs("th", { onClick: () => { sortTable(key); }, children: [_jsx("span", { children: key }), " ", _jsx("span", { className: "sort-arrow" })] }, i)
42
42
  : _jsx("th", { children: _jsx("span", { children: key }) }, i);
43
43
  });
44
44
  return _jsx("tr", { children: headings });
@@ -96,7 +96,7 @@ export function Table(props) {
96
96
  return (myHeader);
97
97
  }
98
98
  function getDirection(header) {
99
- const arrow = header.querySelector('.sortArrow');
99
+ const arrow = header.querySelector('.sort-arrow');
100
100
  let oldDirection = '';
101
101
  if (arrow) {
102
102
  const oldClassList = arrow.classList;
@@ -113,7 +113,7 @@ export function Table(props) {
113
113
  const table = document.getElementById(props.id);
114
114
  const headers = table.querySelectorAll('th');
115
115
  headers.forEach(header => {
116
- const arrow = header.querySelector('.sortArrow');
116
+ const arrow = header.querySelector('.sort-arrow');
117
117
  if (arrow) {
118
118
  arrow.classList.remove('asc', 'desc');
119
119
  }
@@ -121,7 +121,7 @@ export function Table(props) {
121
121
  }
122
122
  function updateArrow(column, oldDirection) {
123
123
  const header = getHeader(column);
124
- const arrow = header.querySelector('.sortArrow');
124
+ const arrow = header.querySelector('.sort-arrow');
125
125
  if (arrow) {
126
126
  if (oldDirection == 'asc') {
127
127
  arrow.classList.add('desc');
@@ -146,6 +146,6 @@ export function Table(props) {
146
146
  updateArrow(column, oldDirection);
147
147
  }
148
148
  }
149
- return (_jsx("div", { children: _jsxs("table", { id: props.id ?? undefined, className: "pixTable", children: [_jsx("thead", { children: getHeadings(tableData) }), _jsx("tbody", { children: getRows(tableData) })] }) }));
149
+ return (_jsx("div", { children: _jsxs("table", { id: props.id ?? undefined, className: "pix-table", children: [_jsx("thead", { children: getHeadings(tableData) }), _jsx("tbody", { children: getRows(tableData) })] }) }));
150
150
  }
151
151
  ;
@@ -1,3 +1,4 @@
1
+ /* eslint-disable pixelated/class-name-kebab-case */
1
2
  "use client";
2
3
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
4
  import PropTypes from "prop-types";
@@ -32,7 +33,7 @@ Tiles.propTypes = {
32
33
  export function Tiles(props) {
33
34
  const rowCount = props.rowCount ?? 2;
34
35
  if (props.cards && props.cards.length > 0) {
35
- return (_jsx("div", { className: "tiles-container", children: _jsx("div", { className: `tile-container row-${rowCount}col`, children: props.cards.map((card, i) => (_jsx("div", { className: "gridItem", children: _jsx(Tile, { index: i, cardLength: props.cards.length, link: card.link, image: card.image, imageAlt: card.imageAlt, bodyText: card.bodyText, imgClick: props.imgClick, variant: (props.variant ?? "overlay") }) }, i))) }) }));
36
+ return (_jsx("div", { className: "tiles-container", children: _jsx("div", { className: `tile-container row-${rowCount}col`, children: props.cards.map((card, i) => (_jsx("div", { className: "grid-item", children: _jsx(Tile, { index: i, cardLength: props.cards.length, link: card.link, image: card.image, imageAlt: card.imageAlt, bodyText: card.bodyText, imgClick: props.imgClick, variant: (props.variant ?? "overlay") }) }, i))) }) }));
36
37
  }
37
38
  else {
38
39
  return (_jsx(Loading, {}));
@@ -76,7 +77,7 @@ function Tile(props) {
76
77
  const tileBody = _jsxs("div", { className: "tile-image" + (imgClick ? " clickable" : ""), children: [_jsx(SmartImage, { src: props.image, title: props?.imageAlt ?? undefined, alt: props?.imageAlt ?? "", onClick: imgClick ? (event) => imgClick(event, props.image) : undefined, cloudinaryEnv: config?.cloudinary?.product_env ?? undefined }), _jsx("div", { className: "tile-image-overlay", children: _jsxs("div", { className: "tile-image-overlay-text", children: [_jsx("div", { className: "tile-image-overlay-title", children: props.imageAlt }), _jsx("div", { className: "tile-image-overlay-body", children: props.bodyText })] }) })] });
77
78
  const rootClass = `tile${(props.variant) ? ' ' + props.variant : ''}`;
78
79
  return (_jsx("div", { className: rootClass, id: 'tile-' + props.index, children: props.link ?
79
- _jsx("a", { href: props.link, className: "tileLink", children: tileBody })
80
+ _jsx("a", { href: props.link, className: "tile-link", children: tileBody })
80
81
  :
81
82
  tileBody }));
82
83
  }
@@ -0,0 +1,137 @@
1
+ import PropTypes from 'prop-types';
2
+ import { readFile } from 'fs/promises';
3
+ import crypto from 'crypto';
4
+ import { NextResponse } from 'next/server';
5
+ import { flattenRoutes } from './sitemap';
6
+ /* ===== Shared helpers for .well-known files ===== */
7
+ /**
8
+ * Read JSON from disk safely — returns null on error. Exported for testing.
9
+ */
10
+ export async function safeJSON(path) {
11
+ try {
12
+ const raw = await readFile(path, 'utf8');
13
+ return JSON.parse(raw);
14
+ }
15
+ catch {
16
+ return null;
17
+ }
18
+ }
19
+ /**
20
+ * Normalize a value into a single-line trimmed string (safe for humans.txt / security.txt).
21
+ * Exported for testing.
22
+ */
23
+ export function sanitizeString(v) {
24
+ return v == null ? '' : String(v).replace(/\s+/g, ' ').trim();
25
+ }
26
+ /**
27
+ * Build a plain-text response payload including ETag and standard headers.
28
+ * Exported for testing and reuse across .well-known generators.
29
+ */
30
+ export function createTextResponsePayload(body) {
31
+ const etag = crypto.createHash('sha1').update(body).digest('hex');
32
+ const headers = {
33
+ 'Content-Type': 'text/plain; charset=utf-8',
34
+ 'Cache-Control': 'public, max-age=60, stale-while-revalidate=3600',
35
+ ETag: etag,
36
+ };
37
+ return { body, etag, headers };
38
+ }
39
+ /* ========== HUMANS.TXT ========== */
40
+ generateHumansTxt.propTypes = {
41
+ /** base directory to read package.json / routes.json from (defaults to process.cwd()) */
42
+ cwd: PropTypes.string,
43
+ /** optional package.json object (if provided, fs is not used) */
44
+ pkg: PropTypes.object,
45
+ /** optional routes.json object (if provided, fs is not used) */
46
+ routesJson: PropTypes.object,
47
+ /** limit how many routes to include (default 50) */
48
+ maxRoutes: PropTypes.number,
49
+ };
50
+ export async function generateHumansTxt(opts = {}) {
51
+ const cwd = opts.cwd ?? process.cwd();
52
+ const pkg = opts.pkg ?? (await safeJSON(cwd + '/package.json')) ?? {};
53
+ const data = opts.routesJson ?? (await safeJSON(cwd + '/src/app/data/routes.json')) ?? {};
54
+ const site = data.siteInfo ?? {};
55
+ const routes = Array.isArray(data.routes) ? data.routes : [];
56
+ const lines = [
57
+ '/* HUMAN-READABLE SITE INFORMATION - generated at runtime */',
58
+ '',
59
+ '/* AUTHOR */',
60
+ ` Author Name: ${sanitizeString(site.author ?? '')}`,
61
+ ` Author Address: ${sanitizeString(site.address
62
+ ? [
63
+ site.address.streetAddress,
64
+ site.address.addressLocality,
65
+ site.address.addressRegion,
66
+ site.address.postalCode,
67
+ site.address.addressCountry,
68
+ ]
69
+ .filter(Boolean)
70
+ .join(' ')
71
+ : '')}`,
72
+ ` Author Email: ${sanitizeString(site.email ?? '')}`,
73
+ ` Author Telephone: ${sanitizeString(site.telephone ?? '')}`,
74
+ '',
75
+ '/* DEVELOPER */',
76
+ ` Developer Name: Brian Whaley`,
77
+ ` Developer Company: Pixelated Technologies LLC`,
78
+ ` Developer Address: 10 Jade Circle, Denville NJ 07834 USA`,
79
+ ` Developer Email: brian@pixelated.tech`,
80
+ ` Developer Website: https://www.pixelated.tech`,
81
+ ` Developer Telephone: +1 (973) 722-2601`,
82
+ '',
83
+ '/* SITE */',
84
+ ` Site Name: ${sanitizeString(site.name ?? '')}`,
85
+ ` Site Package Name: ${sanitizeString(pkg.name ?? '')}`,
86
+ ` Site Package Version: ${sanitizeString(pkg.version ?? '')}`,
87
+ ` Site URL: ${sanitizeString(site.url ?? '')}`,
88
+ ` Site Languages: React, Node, NextJS, JavaScript, HTML5, CSS3, SASS `,
89
+ ` Site Tools: VSCode, GitHub, AWS, Contently, Cloudinary, Wordpress, Google Analytics, Google Search Console`,
90
+ ` Site Pages: (${routes.length})`,
91
+ ];
92
+ const limit = typeof opts.maxRoutes === 'number' ? opts.maxRoutes : 50;
93
+ for (const r of flattenRoutes(routes).slice(0, limit)) {
94
+ lines.push(` - ${sanitizeString(r.path ?? r.pathname ?? r.url ?? '')} - ${sanitizeString(r.title ?? '')}`);
95
+ }
96
+ const body = lines.join('\n');
97
+ return createTextResponsePayload(body);
98
+ }
99
+ /* ========== SECURITY.TXT ========== */
100
+ generateSecurityTxt.propTypes = {
101
+ routesJson: PropTypes.object,
102
+ };
103
+ export async function generateSecurityTxt(props = {}) {
104
+ const data = props.routesJson ?? (await safeJSON(process.cwd() + '/src/app/data/routes.json')) ?? {};
105
+ const siteInfo = data.siteInfo ?? {};
106
+ const lines = [
107
+ '# Contact methods for security researchers',
108
+ `Contact: mailto:${sanitizeString(siteInfo.email ?? '')}`,
109
+ '',
110
+ "# Link to your vulnerability disclosure policy",
111
+ 'Policy: ',
112
+ '',
113
+ "# Link to your PGP public key for encrypted communication",
114
+ 'Encryption: ',
115
+ '',
116
+ "# Languages supported",
117
+ 'Preferred-Languages: en',
118
+ '',
119
+ "# Date and time the file should be considered stale",
120
+ `Expires: ${new Date(new Date().getFullYear(), 11, 31).toISOString()}`,
121
+ ];
122
+ const body = lines.join('\n');
123
+ return createTextResponsePayload(body);
124
+ }
125
+ /* ========== Convenience helper ========== */
126
+ /**
127
+ * Create a response for a well-known resource.
128
+ * @param {'humans'|'security'} type - Which resource to generate ('humans' | 'security').
129
+ */
130
+ export async function createWellKnownResponse(type, req, opts = {}) {
131
+ const payload = (type === 'humans') ? await generateHumansTxt(opts) : await generateSecurityTxt(opts);
132
+ const { body, etag, headers } = payload;
133
+ if (req?.headers?.get && req.headers.get('if-none-match') === etag) {
134
+ return new NextResponse(null, { status: 304, headers });
135
+ }
136
+ return new NextResponse(body, { status: 200, headers });
137
+ }
@@ -7,11 +7,11 @@
7
7
  * List all entries of a specific content type
8
8
  */
9
9
  export async function listEntries(contentType, config) {
10
- const { spaceId, accessToken, environment = 'master' } = config;
10
+ const { space_id, delivery_access_token, environment = 'master' } = config;
11
11
  try {
12
- const response = await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${environment}/entries?content_type=${contentType}`, {
12
+ const response = await fetch(`https://api.contentful.com/spaces/${space_id}/environments/${environment}/entries?content_type=${contentType}`, {
13
13
  headers: {
14
- 'Authorization': `Bearer ${accessToken}`,
14
+ 'Authorization': `Bearer ${delivery_access_token}`,
15
15
  'Content-Type': 'application/json',
16
16
  },
17
17
  });
@@ -37,11 +37,11 @@ export async function listEntries(contentType, config) {
37
37
  * Get a single entry by ID
38
38
  */
39
39
  export async function getEntryById(entryId, config) {
40
- const { spaceId, accessToken, environment = 'master' } = config;
40
+ const { space_id, delivery_access_token, environment = 'master' } = config;
41
41
  try {
42
- const response = await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${environment}/entries/${entryId}`, {
42
+ const response = await fetch(`https://api.contentful.com/spaces/${space_id}/environments/${environment}/entries/${entryId}`, {
43
43
  headers: {
44
- 'Authorization': `Bearer ${accessToken}`,
44
+ 'Authorization': `Bearer ${delivery_access_token}`,
45
45
  'Content-Type': 'application/json',
46
46
  },
47
47
  });
@@ -71,11 +71,11 @@ export async function getEntryById(entryId, config) {
71
71
  * Search for entries by field value
72
72
  */
73
73
  export async function searchEntriesByField(contentType, fieldName, fieldValue, config) {
74
- const { spaceId, accessToken, environment = 'master' } = config;
74
+ const { space_id, delivery_access_token, environment = 'master' } = config;
75
75
  try {
76
- const response = await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${environment}/entries?content_type=${contentType}&fields.${fieldName}=${encodeURIComponent(fieldValue)}`, {
76
+ const response = await fetch(`https://api.contentful.com/spaces/${space_id}/environments/${environment}/entries?content_type=${contentType}&fields.${fieldName}=${encodeURIComponent(fieldValue)}`, {
77
77
  headers: {
78
- 'Authorization': `Bearer ${accessToken}`,
78
+ 'Authorization': `Bearer ${delivery_access_token}`,
79
79
  'Content-Type': 'application/json',
80
80
  },
81
81
  });
@@ -101,17 +101,17 @@ export async function searchEntriesByField(contentType, fieldName, fieldValue, c
101
101
  * Create a new entry
102
102
  */
103
103
  export async function createEntry(contentType, fields, config, autoPublish = true) {
104
- const { spaceId, accessToken, environment = 'master' } = config;
104
+ const { space_id, delivery_access_token, environment = 'master' } = config;
105
105
  try {
106
106
  // Convert fields to Contentful format (with 'en-US' locale)
107
107
  const contentfulFields = {};
108
108
  for (const [key, value] of Object.entries(fields)) {
109
109
  contentfulFields[key] = { 'en-US': value };
110
110
  }
111
- const createResponse = await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${environment}/entries`, {
111
+ const createResponse = await fetch(`https://api.contentful.com/spaces/${space_id}/environments/${environment}/entries`, {
112
112
  method: 'POST',
113
113
  headers: {
114
- 'Authorization': `Bearer ${accessToken}`,
114
+ 'Authorization': `Bearer ${delivery_access_token}`,
115
115
  'Content-Type': 'application/vnd.contentful.management.v1+json',
116
116
  'X-Contentful-Content-Type': contentType,
117
117
  },
@@ -126,10 +126,10 @@ export async function createEntry(contentType, fields, config, autoPublish = tru
126
126
  const newEntry = await createResponse.json();
127
127
  // Publish if requested
128
128
  if (autoPublish) {
129
- await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${environment}/entries/${newEntry.sys.id}/published`, {
129
+ await fetch(`https://api.contentful.com/spaces/${space_id}/environments/${environment}/entries/${newEntry.sys.id}/published`, {
130
130
  method: 'PUT',
131
131
  headers: {
132
- 'Authorization': `Bearer ${accessToken}`,
132
+ 'Authorization': `Bearer ${delivery_access_token}`,
133
133
  'X-Contentful-Version': newEntry.sys.version.toString(),
134
134
  },
135
135
  });
@@ -151,7 +151,7 @@ export async function createEntry(contentType, fields, config, autoPublish = tru
151
151
  * Update an existing entry
152
152
  */
153
153
  export async function updateEntry(entryId, fields, config, autoPublish = true) {
154
- const { spaceId, accessToken, environment = 'master' } = config;
154
+ const { space_id, delivery_access_token, environment = 'master' } = config;
155
155
  try {
156
156
  // Get current entry to get version
157
157
  const getResponse = await getEntryById(entryId, config);
@@ -167,10 +167,10 @@ export async function updateEntry(entryId, fields, config, autoPublish = true) {
167
167
  for (const [key, value] of Object.entries(fields)) {
168
168
  contentfulFields[key] = { 'en-US': value };
169
169
  }
170
- const updateResponse = await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${environment}/entries/${entryId}`, {
170
+ const updateResponse = await fetch(`https://api.contentful.com/spaces/${space_id}/environments/${environment}/entries/${entryId}`, {
171
171
  method: 'PUT',
172
172
  headers: {
173
- 'Authorization': `Bearer ${accessToken}`,
173
+ 'Authorization': `Bearer ${delivery_access_token}`,
174
174
  'Content-Type': 'application/vnd.contentful.management.v1+json',
175
175
  'X-Contentful-Version': currentEntry.sys.version.toString(),
176
176
  },
@@ -185,10 +185,10 @@ export async function updateEntry(entryId, fields, config, autoPublish = true) {
185
185
  const updatedEntry = await updateResponse.json();
186
186
  // Publish if requested
187
187
  if (autoPublish) {
188
- await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${environment}/entries/${entryId}/published`, {
188
+ await fetch(`https://api.contentful.com/spaces/${space_id}/environments/${environment}/entries/${entryId}/published`, {
189
189
  method: 'PUT',
190
190
  headers: {
191
- 'Authorization': `Bearer ${accessToken}`,
191
+ 'Authorization': `Bearer ${delivery_access_token}`,
192
192
  'X-Contentful-Version': updatedEntry.sys.version.toString(),
193
193
  },
194
194
  });
@@ -210,7 +210,7 @@ export async function updateEntry(entryId, fields, config, autoPublish = true) {
210
210
  * Delete an entry (unpublish first, then delete)
211
211
  */
212
212
  export async function deleteEntry(entryId, config) {
213
- const { spaceId, accessToken, environment = 'master' } = config;
213
+ const { space_id, delivery_access_token, environment = 'master' } = config;
214
214
  try {
215
215
  // Get current entry to get version
216
216
  const getResponse = await getEntryById(entryId, config);
@@ -222,18 +222,18 @@ export async function deleteEntry(entryId, config) {
222
222
  }
223
223
  const entry = getResponse.entry;
224
224
  // Unpublish first
225
- await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${environment}/entries/${entryId}/published`, {
226
- method: 'DELETE',
225
+ await fetch(`https://api.contentful.com/spaces/${space_id}/environments/${environment}/entries/${entry.sys.id}/published`, {
226
+ method: 'PUT',
227
227
  headers: {
228
- 'Authorization': `Bearer ${accessToken}`,
228
+ 'Authorization': `Bearer ${delivery_access_token}`,
229
229
  'X-Contentful-Version': entry.sys.version.toString(),
230
230
  },
231
231
  });
232
232
  // Delete the entry
233
- const deleteResponse = await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${environment}/entries/${entryId}`, {
233
+ const deleteResponse = await fetch(`https://api.contentful.com/spaces/${space_id}/environments/${environment}/entries/${entryId}`, {
234
234
  method: 'DELETE',
235
235
  headers: {
236
- 'Authorization': `Bearer ${accessToken}`,
236
+ 'Authorization': `Bearer ${delivery_access_token}`,
237
237
  'X-Contentful-Version': (entry.sys.version + 1).toString(),
238
238
  },
239
239
  });