@pixelated-tech/components 3.4.2 → 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.
- package/README.md +32 -191
- package/dist/components/admin/componentusage/componentAnalysis.js +12 -4
- package/dist/components/admin/componentusage/componentDiscovery.js +20 -6
- package/dist/components/admin/site-health/seo-metrics.config.json +111 -0
- package/dist/components/admin/site-health/site-health-accessibility.js +5 -1
- package/dist/components/admin/site-health/site-health-axe-core.js +4 -0
- package/dist/components/admin/site-health/site-health-cloudwatch.integration.js +0 -5
- package/dist/components/admin/site-health/site-health-cloudwatch.js +7 -1
- package/dist/components/admin/site-health/site-health-dependency-vulnerabilities.js +4 -0
- package/dist/components/admin/site-health/site-health-github.js +6 -0
- package/dist/components/admin/site-health/site-health-google-analytics.js +6 -0
- package/dist/components/admin/site-health/site-health-google-search-console.js +6 -0
- package/dist/components/admin/site-health/site-health-on-site-seo.integration.js +379 -12
- package/dist/components/admin/site-health/site-health-on-site-seo.js +4 -0
- package/dist/components/admin/site-health/site-health-overview.js +11 -4
- package/dist/components/admin/site-health/site-health-performance.js +4 -0
- package/dist/components/admin/site-health/site-health-security.js +5 -1
- package/dist/components/admin/site-health/site-health-seo.js +5 -1
- package/dist/components/admin/site-health/site-health-template.js +19 -9
- package/dist/components/admin/site-health/site-health-uptime.js +4 -0
- package/dist/components/callout/callout.js +0 -10
- package/dist/components/carousel/carousel.js +15 -4
- package/dist/components/carousel/tiles.js +1 -1
- package/dist/components/cms/contentful.items.components.js +3 -4
- package/dist/components/cms/flickr.js +1 -1
- package/dist/components/cms/google.reviews.components.js +3 -3
- package/dist/components/cms/instagram.components.js +15 -5
- package/dist/components/cms/smartimage.js +2 -2
- package/dist/components/cms/wordpress.components.js +32 -6
- package/dist/components/cms/yelp.js +5 -0
- package/dist/components/config/config.server.js +7 -1
- package/dist/components/general/css.js +0 -1
- package/dist/components/general/image.js +0 -1
- package/dist/components/general/loading.js +2 -1
- package/dist/components/general/microinteractions.js +0 -1
- package/dist/components/general/modal.css +2 -4
- package/dist/components/general/modal.js +72 -30
- package/dist/components/general/sidepanel.js +16 -0
- package/dist/components/general/tab.js +1 -0
- package/dist/components/menu/menu-accordion.css +1 -1
- package/dist/components/menu/menu-accordion.js +15 -4
- package/dist/components/menu/menu-expando.js +21 -19
- package/dist/components/menu/menu-simple.js +14 -14
- package/dist/components/nerdjoke/nerdjoke.js +1 -1
- package/dist/components/seo/googlesearch.js +0 -1
- package/dist/components/seo/schema-blogposting.js +6 -1
- package/dist/components/seo/schema-recipe.js +34 -1
- package/dist/components/seo/schema-services.js +20 -2
- package/dist/components/shoppingcart/ebay.components.js +3 -3
- package/dist/components/shoppingcart/shoppingcart.components.js +76 -28
- package/dist/components/shoppingcart/shoppingcart.functions.js +4 -4
- package/dist/components/sitebuilder/config/CompoundFontSelector.js +13 -4
- package/dist/components/sitebuilder/config/ConfigBuilder.css +194 -5
- package/dist/components/sitebuilder/config/ConfigBuilder.js +183 -17
- package/dist/components/sitebuilder/config/FontSelector.js +13 -2
- package/dist/components/sitebuilder/config/routes-form.json +67 -0
- package/dist/components/sitebuilder/config/siteinfo-form.json +28 -14
- package/dist/components/sitebuilder/config/visualdesignform.json +4 -4
- package/dist/components/sitebuilder/form/formbuilder.js +1 -0
- package/dist/components/sitebuilder/form/formcomponents.js +2 -3
- package/dist/components/sitebuilder/form/formengine.js +6 -5
- package/dist/components/sitebuilder/form/formvalidator.js +5 -0
- package/dist/components/sitebuilder/page/components/PageBuilderUI.js +5 -1
- package/dist/components/structured/buzzwordbingo.css +0 -1
- package/dist/components/structured/recipe.js +1 -1
- package/dist/components/structured/socialcard.js +2 -2
- package/dist/components/utilities/functions.js +82 -1
- package/dist/components/utilities/gemini-api.client.js +76 -0
- package/dist/components/utilities/gemini-api.server.js +185 -0
- package/dist/data/routes.json +5 -5
- package/dist/index.adminclient.js +30 -0
- package/dist/index.adminserver.js +21 -0
- package/dist/index.js +4 -18
- package/dist/index.server.js +15 -28
- package/dist/types/components/admin/componentusage/componentAnalysis.d.ts.map +1 -1
- package/dist/types/components/admin/componentusage/componentDiscovery.d.ts +1 -1
- package/dist/types/components/admin/componentusage/componentDiscovery.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-accessibility.d.ts +7 -4
- package/dist/types/components/admin/site-health/site-health-accessibility.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-axe-core.d.ts +7 -4
- package/dist/types/components/admin/site-health/site-health-axe-core.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts +9 -6
- package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-cloudwatch.integration.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts +7 -4
- package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-github.d.ts +9 -6
- package/dist/types/components/admin/site-health/site-health-github.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts +9 -6
- package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts +9 -6
- package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts +8 -3
- package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-overview.d.ts +7 -4
- package/dist/types/components/admin/site-health/site-health-overview.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-performance.d.ts +7 -4
- package/dist/types/components/admin/site-health/site-health-performance.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-security.d.ts +7 -4
- package/dist/types/components/admin/site-health/site-health-security.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-seo.d.ts +7 -4
- package/dist/types/components/admin/site-health/site-health-seo.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-template.d.ts +12 -10
- package/dist/types/components/admin/site-health/site-health-template.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-uptime.d.ts +7 -4
- package/dist/types/components/admin/site-health/site-health-uptime.d.ts.map +1 -1
- package/dist/types/components/callout/callout.d.ts +3 -3
- package/dist/types/components/callout/callout.d.ts.map +1 -1
- package/dist/types/components/carousel/carousel.d.ts +16 -7
- package/dist/types/components/carousel/carousel.d.ts.map +1 -1
- package/dist/types/components/carousel/tiles.d.ts +3 -6
- package/dist/types/components/carousel/tiles.d.ts.map +1 -1
- package/dist/types/components/cms/flickr.d.ts +3 -6
- package/dist/types/components/cms/flickr.d.ts.map +1 -1
- package/dist/types/components/cms/google.reviews.components.d.ts +1 -7
- package/dist/types/components/cms/google.reviews.components.d.ts.map +1 -1
- package/dist/types/components/cms/hubspot.components.d.ts +1 -2
- package/dist/types/components/cms/hubspot.components.d.ts.map +1 -1
- package/dist/types/components/cms/instagram.components.d.ts +14 -9
- package/dist/types/components/cms/instagram.components.d.ts.map +1 -1
- package/dist/types/components/cms/smartimage.d.ts +2 -28
- package/dist/types/components/cms/smartimage.d.ts.map +1 -1
- package/dist/types/components/cms/wordpress.components.d.ts +33 -14
- package/dist/types/components/cms/wordpress.components.d.ts.map +1 -1
- package/dist/types/components/cms/yelp.d.ts +9 -4
- package/dist/types/components/cms/yelp.d.ts.map +1 -1
- package/dist/types/components/config/config.server.d.ts +9 -6
- package/dist/types/components/config/config.server.d.ts.map +1 -1
- package/dist/types/components/general/loading.d.ts +5 -1
- package/dist/types/components/general/loading.d.ts.map +1 -1
- package/dist/types/components/general/microinteractions.d.ts +1 -3
- package/dist/types/components/general/microinteractions.d.ts.map +1 -1
- package/dist/types/components/general/modal.d.ts +11 -5
- package/dist/types/components/general/modal.d.ts.map +1 -1
- package/dist/types/components/general/semantic.d.ts +3 -3
- package/dist/types/components/general/sidepanel.d.ts +20 -13
- package/dist/types/components/general/sidepanel.d.ts.map +1 -1
- package/dist/types/components/general/tab.d.ts +1 -2
- package/dist/types/components/general/tab.d.ts.map +1 -1
- package/dist/types/components/menu/menu-accordion.d.ts +22 -9
- package/dist/types/components/menu/menu-accordion.d.ts.map +1 -1
- package/dist/types/components/menu/menu-expando.d.ts +14 -5
- package/dist/types/components/menu/menu-expando.d.ts.map +1 -1
- package/dist/types/components/menu/menu-simple.d.ts +4 -5
- package/dist/types/components/menu/menu-simple.d.ts.map +1 -1
- package/dist/types/components/nerdjoke/nerdjoke.d.ts +1 -1
- package/dist/types/components/nerdjoke/nerdjoke.d.ts.map +1 -1
- package/dist/types/components/seo/googleanalytics.d.ts.map +1 -1
- package/dist/types/components/seo/metadata.components.d.ts +2 -2
- package/dist/types/components/seo/metadata.components.d.ts.map +1 -1
- package/dist/types/components/seo/schema-blogposting.d.ts +7 -4
- package/dist/types/components/seo/schema-blogposting.d.ts.map +1 -1
- package/dist/types/components/seo/schema-recipe.d.ts +29 -30
- package/dist/types/components/seo/schema-recipe.d.ts.map +1 -1
- package/dist/types/components/seo/schema-services.d.ts +19 -9
- package/dist/types/components/seo/schema-services.d.ts.map +1 -1
- package/dist/types/components/shoppingcart/paypal.d.ts +1 -1
- package/dist/types/components/shoppingcart/paypal.d.ts.map +1 -1
- package/dist/types/components/shoppingcart/shoppingcart.components.d.ts +77 -28
- package/dist/types/components/shoppingcart/shoppingcart.components.d.ts.map +1 -1
- package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts +4 -23
- package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts +10 -11
- package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts +41 -174
- package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/config/FontSelector.d.ts +12 -13
- package/dist/types/components/sitebuilder/config/FontSelector.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/form/formbuilder.d.ts +7 -3
- package/dist/types/components/sitebuilder/form/formbuilder.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/form/formcomponents.d.ts +1 -1
- package/dist/types/components/sitebuilder/form/formcomponents.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/form/formengine.d.ts +1 -2
- package/dist/types/components/sitebuilder/form/formengine.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/form/formextractor.d.ts +5 -4
- package/dist/types/components/sitebuilder/form/formextractor.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/form/formtypes.d.ts +3 -3
- package/dist/types/components/sitebuilder/form/formtypes.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/form/formvalidator.d.ts +8 -3
- package/dist/types/components/sitebuilder/form/formvalidator.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/page/components/ComponentPropertiesForm.d.ts +2 -3
- package/dist/types/components/sitebuilder/page/components/ComponentPropertiesForm.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/page/components/ComponentSelector.d.ts +2 -3
- package/dist/types/components/sitebuilder/page/components/ComponentSelector.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/page/components/ComponentTree.d.ts +2 -3
- package/dist/types/components/sitebuilder/page/components/ComponentTree.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/page/components/PageBuilderUI.d.ts +8 -7
- package/dist/types/components/sitebuilder/page/components/PageBuilderUI.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/page/components/PageEngine.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/page/components/SaveLoadSection.d.ts +2 -3
- package/dist/types/components/sitebuilder/page/components/SaveLoadSection.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/page/lib/componentMap.d.ts +1 -1
- package/dist/types/components/structured/markdown.d.ts +1 -3
- package/dist/types/components/structured/markdown.d.ts.map +1 -1
- package/dist/types/components/structured/recipe.d.ts +5 -32
- package/dist/types/components/structured/recipe.d.ts.map +1 -1
- package/dist/types/components/structured/socialcard.d.ts +4 -0
- package/dist/types/components/structured/socialcard.d.ts.map +1 -1
- package/dist/types/components/structured/timeline.d.ts +1 -3
- package/dist/types/components/structured/timeline.d.ts.map +1 -1
- package/dist/types/components/utilities/functions.d.ts +20 -0
- package/dist/types/components/utilities/functions.d.ts.map +1 -1
- package/dist/types/components/utilities/gemini-api.client.d.ts +38 -0
- package/dist/types/components/utilities/gemini-api.client.d.ts.map +1 -0
- package/dist/types/components/utilities/gemini-api.server.d.ts +17 -0
- package/dist/types/components/utilities/gemini-api.server.d.ts.map +1 -0
- package/dist/types/index.adminclient.d.ts +27 -0
- package/dist/types/index.adminclient.d.ts.map +1 -0
- package/dist/types/index.adminserver.d.ts +19 -0
- package/dist/types/index.adminserver.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -18
- package/dist/types/index.server.d.ts +5 -28
- package/dist/types/stories/admin/site-health.stories.d.ts +4 -0
- package/dist/types/stories/admin/site-health.stories.d.ts.map +1 -1
- package/dist/types/stories/general/sidepanel.stories.d.ts.map +1 -1
- package/dist/types/stories/general/smartimage.stories.d.ts +74 -2
- package/dist/types/stories/general/smartimage.stories.d.ts.map +1 -1
- package/dist/types/tests/site-health-cloudwatch.test.d.ts +2 -0
- package/dist/types/tests/site-health-cloudwatch.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-on-site-seo.integration.test.d.ts +2 -0
- package/dist/types/tests/site-health-on-site-seo.integration.test.d.ts.map +1 -0
- package/package.json +20 -10
- package/README.COMPONENTS.md +0 -2162
- package/dist/components/cms/pixelated.linkedin.js +0 -180
- package/dist/components/cms/pixelated.linkedin1.js +0 -84
- package/dist/components/cms/pixelated.linkedin2.js +0 -92
- package/dist/types/components/cms/pixelated.linkedin.d.ts +0 -2
- package/dist/types/components/cms/pixelated.linkedin.d.ts.map +0 -1
- package/dist/types/components/cms/pixelated.linkedin1.d.ts +0 -2
- package/dist/types/components/cms/pixelated.linkedin1.d.ts.map +0 -1
- package/dist/types/components/cms/pixelated.linkedin2.d.ts +0 -2
- package/dist/types/components/cms/pixelated.linkedin2.d.ts.map +0 -1
- package/dist/types/tests/pixelated.menu-expando.test.d.ts +0 -2
- package/dist/types/tests/pixelated.menu-expando.test.d.ts.map +0 -1
|
@@ -1,6 +1,10 @@
|
|
|
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 { SiteHealthTemplate } from './site-health-template';
|
|
5
|
+
SiteHealthUptime.propTypes = {
|
|
6
|
+
siteName: PropTypes.string.isRequired,
|
|
7
|
+
};
|
|
4
8
|
export function SiteHealthUptime({ siteName }) {
|
|
5
9
|
const fetchUptimeData = async (site) => {
|
|
6
10
|
const response = await fetch(`/api/site-health/uptime?siteName=${encodeURIComponent(site)}`);
|
|
@@ -89,16 +89,6 @@ CalloutButton.propTypes = {
|
|
|
89
89
|
url: PropTypes.string.isRequired,
|
|
90
90
|
target: PropTypes.string
|
|
91
91
|
};
|
|
92
|
-
/* export function CalloutButton( { title, url, target } : CalloutButtonType) {
|
|
93
|
-
return (
|
|
94
|
-
<div className="callout-button">
|
|
95
|
-
{ (url)
|
|
96
|
-
? <button type="button" className="callout-button"><a href={url || ""} target={target || ""} rel={target=="_blank" ? "noopener noreferrer" : ""}>{title}</a></button>
|
|
97
|
-
: null
|
|
98
|
-
}
|
|
99
|
-
</div>
|
|
100
|
-
);
|
|
101
|
-
} */
|
|
102
92
|
export function CalloutButton({ title, url, target }) {
|
|
103
93
|
const handleClick = () => {
|
|
104
94
|
if (target === '_blank') {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useEffect, useRef } from 'react';
|
|
4
|
-
import PropTypes
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
5
|
import { SmartImage } from '../cms/smartimage';
|
|
6
6
|
import { usePixelatedConfig } from '../config/config.client';
|
|
7
7
|
import { DragHandler } from './carousel.drag';
|
|
@@ -11,11 +11,22 @@ function capitalize(str) {
|
|
|
11
11
|
}
|
|
12
12
|
/* ========== CAROUSEL ========== */
|
|
13
13
|
Carousel.propTypes = {
|
|
14
|
-
cards: PropTypes.
|
|
14
|
+
cards: PropTypes.arrayOf(PropTypes.shape({
|
|
15
|
+
index: PropTypes.number.isRequired,
|
|
16
|
+
cardIndex: PropTypes.number.isRequired,
|
|
17
|
+
cardLength: PropTypes.number.isRequired,
|
|
18
|
+
link: PropTypes.string,
|
|
19
|
+
linkTarget: PropTypes.string,
|
|
20
|
+
image: PropTypes.string.isRequired,
|
|
21
|
+
imageAlt: PropTypes.string,
|
|
22
|
+
imgFit: PropTypes.oneOf(['contain', 'cover', 'fill']),
|
|
23
|
+
headerText: PropTypes.string,
|
|
24
|
+
subHeaderText: PropTypes.string,
|
|
25
|
+
bodyText: PropTypes.string,
|
|
26
|
+
})).isRequired,
|
|
15
27
|
draggable: PropTypes.bool,
|
|
16
28
|
imgFit: PropTypes.oneOf(['contain', 'cover', 'fill'])
|
|
17
29
|
};
|
|
18
|
-
// export type CarouselType = InferProps<typeof Carousel.propTypes>;
|
|
19
30
|
export function Carousel(props) {
|
|
20
31
|
const debug = false;
|
|
21
32
|
let timer = useRef(null);
|
|
@@ -74,7 +85,7 @@ export function Carousel(props) {
|
|
|
74
85
|
console.log('CarouselSimple: Dragging disabled');
|
|
75
86
|
}
|
|
76
87
|
if (props.cards && props.cards.length > 0) {
|
|
77
|
-
return (_jsxs("div", { className: "carousel-container", children: [_jsx("div", { className: "carousel-cards-container", children: props.cards.map((card, i) => (_jsx(CarouselCard, { index: i, cardIndex: cardIndex, cardLength: props.cards.length, link: card.link, linkTarget: card.linkTarget || '_self', image: card.image, imageAlt: card.imageAlt, imgFit: props.imgFit
|
|
88
|
+
return (_jsxs("div", { className: "carousel-container", children: [_jsx("div", { className: "carousel-cards-container", children: props.cards.map((card, i) => (_jsx(CarouselCard, { index: i, cardIndex: cardIndex, cardLength: props.cards.length, link: card.link, linkTarget: card.linkTarget || '_self', image: card.image, imageAlt: card.imageAlt, imgFit: (props.imgFit || 'fill'), headerText: card.headerText, subHeaderText: card.subHeaderText, bodyText: card.bodyText }, i))) }), _jsxs("div", { className: "carousel-buttons", children: [_jsx(CarouselButton, { clickFunction: previousCard, glyph: '\u25C0' }), _jsx(CarouselButton, { clickFunction: stopTimer, glyph: '\u23F8' }), _jsx(CarouselButton, { clickFunction: nextCard, glyph: '\u25B6' })] })] }));
|
|
78
89
|
}
|
|
79
90
|
else {
|
|
80
91
|
return (_jsx("div", { className: 'section-container', children: _jsx("div", { className: "carousel-container", children: _jsx(CarouselLoading, {}) }) }));
|
|
@@ -7,7 +7,7 @@ import { usePixelatedConfig } from '../config/config.client';
|
|
|
7
7
|
import "../../css/pixelated.grid.scss";
|
|
8
8
|
import "./tiles.css";
|
|
9
9
|
Tiles.propTypes = {
|
|
10
|
-
cards: PropTypes.
|
|
10
|
+
cards: PropTypes.array.isRequired,
|
|
11
11
|
rowCount: PropTypes.number,
|
|
12
12
|
};
|
|
13
13
|
export function Tiles(props) {
|
|
@@ -5,7 +5,7 @@ import PropTypes from "prop-types";
|
|
|
5
5
|
import { Carousel } from '../carousel/carousel';
|
|
6
6
|
import { getContentfulEntriesByType, getContentfulEntryByEntryID } from "./contentful.delivery";
|
|
7
7
|
import { usePixelatedConfig } from '../config/config.client';
|
|
8
|
-
import {
|
|
8
|
+
import { addToShoppingCart } from "../shoppingcart/shoppingcart.functions";
|
|
9
9
|
import { AddToCartButton, /* GoToCartButton */ ViewItemDetails } from "../shoppingcart/shoppingcart.components";
|
|
10
10
|
import { getCloudinaryRemoteFetchURL as getImg } from "./cloudinary";
|
|
11
11
|
// import { Loading, ToggleLoading } from "../general/pixelated.loading";
|
|
@@ -135,7 +135,7 @@ export function ContentfulListItem(props) {
|
|
|
135
135
|
? _jsx(ContentfulItemHeader, { url: itemURL, target: itemURLTarget, title: thisItem.fields.title })
|
|
136
136
|
: _jsx(ContentfulItemHeader, { title: thisItem.fields.title }) }), _jsxs("div", { className: "contentful-item-details grid12", children: [_jsxs("div", { children: [_jsx("b", { children: "Item ID: " }), thisItem.sys.id] }), _jsxs("div", { children: [_jsx("b", { children: "UPC ID: " }), thisItem.fields.id] }), _jsxs("div", { children: [_jsx("b", { children: "Quantity: " }), thisItem.fields.quantity] }), _jsxs("div", { children: [_jsx("b", { children: "Brand / Model: " }), thisItem.fields.brand, " ", thisItem.fields.model] }), _jsxs("div", { children: [_jsx("b", { children: "Listing Date: " }), thisItem.fields.date] })] }), _jsx("div", { className: "contentful-item-price", children: itemURL
|
|
137
137
|
? _jsxs("a", { href: itemURL, target: itemURLTarget, rel: "noreferrer", children: ["$", thisItem.fields.price, " USD"] })
|
|
138
|
-
: "$" + thisItem.fields.price + " USD" }), _jsx("br", {}), _jsxs("div", { className: "contentful-item-addtocart", children: [_jsx(ViewItemDetails, { href: "/store", itemID: thisItem.sys.id }), _jsx(AddToCartButton, { handler:
|
|
138
|
+
: "$" + thisItem.fields.price + " USD" }), _jsx("br", {}), _jsxs("div", { className: "contentful-item-addtocart", children: [_jsx(ViewItemDetails, { href: "/store", itemID: thisItem.sys.id }), _jsx(AddToCartButton, { handler: addToShoppingCart, item: shoppingCartItem, itemID: thisItem.sys.id })] })] })] }));
|
|
139
139
|
}
|
|
140
140
|
/* ========== CONTENTFUL ITEM HEADER ========== */
|
|
141
141
|
ContentfulItemHeader.propTypes = {
|
|
@@ -156,7 +156,6 @@ ContentfulItemDetail.propTypes = {
|
|
|
156
156
|
};
|
|
157
157
|
export function ContentfulItemDetail(props) {
|
|
158
158
|
const [item, setItem] = useState({});
|
|
159
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
160
159
|
const [assets, setAssets] = useState({});
|
|
161
160
|
const [cards, setCards] = useState([]);
|
|
162
161
|
const providerContentfulApiProps = usePixelatedConfig()?.contentful;
|
|
@@ -235,7 +234,7 @@ export function ContentfulItemDetail(props) {
|
|
|
235
234
|
? _jsx(ContentfulItemHeader, { url: itemURL, title: thisItem.fields.title })
|
|
236
235
|
: _jsx(ContentfulItemHeader, { title: thisItem.fields.title }) }), _jsx("br", {}), _jsx("div", { className: "contentful-item-photo-carousel grid-s1-e7", children: _jsx(Carousel, { cards: cards, draggable: true, imgFit: "contain" }) }), _jsxs("div", { className: "grid-s7-e13", children: [_jsx("div", { className: "contentful-item-details grid12", children: _jsx("div", { dangerouslySetInnerHTML: { __html: thisItem.fields.description.replace(/(<br\s*\/?>\s*){2,}/gi, '') } }) }), _jsx("br", {}), _jsxs("div", { className: "contentful-item-details grid12", children: [_jsxs("div", { children: [_jsx("b", { children: "Item ID: " }), thisItem.sys.id] }), _jsxs("div", { children: [_jsx("b", { children: "UPC ID: " }), thisItem.fields.id] }), _jsxs("div", { children: [_jsx("b", { children: "Quantity: " }), thisItem.fields.quantity] }), _jsxs("div", { children: [_jsx("b", { children: "Brand / Model: " }), thisItem.fields.brand, " ", thisItem.fields.model] }), _jsxs("div", { children: [_jsx("b", { children: "Listing Date: " }), thisItem.fields.date] }), _jsx("br", {})] }), _jsx("div", { className: "contentful-item-price", children: itemURL
|
|
237
236
|
? _jsxs("a", { href: itemURL, target: itemURLTarget, rel: "noreferrer", children: ["$", thisItem.fields.price, " USD"] })
|
|
238
|
-
: "$" + thisItem.fields.price + " USD" }), _jsx("br", {}), _jsx("div", { className: "contentful-item-addtocart", children: _jsx(AddToCartButton, { handler:
|
|
237
|
+
: "$" + thisItem.fields.price + " USD" }), _jsx("br", {}), _jsx("div", { className: "contentful-item-addtocart", children: _jsx(AddToCartButton, { handler: addToShoppingCart, item: shoppingCartItem, itemID: thisItem.sys.id }) })] })] }) }));
|
|
239
238
|
}
|
|
240
239
|
else {
|
|
241
240
|
return (_jsx(_Fragment, { children: _jsx("div", { id: "contentful-items", className: "contentful-items", children: _jsx("div", { className: "centered", children: "Loading..." }) }) }));
|
|
@@ -22,9 +22,9 @@ export function GoogleReviewsCard(props) {
|
|
|
22
22
|
try {
|
|
23
23
|
const result = await getGoogleReviewsByPlaceId({
|
|
24
24
|
placeId: props.placeId,
|
|
25
|
-
language: props.language,
|
|
26
|
-
maxReviews: props.maxReviews,
|
|
27
|
-
proxyBase: props.proxyBase,
|
|
25
|
+
language: props.language ?? undefined,
|
|
26
|
+
maxReviews: props.maxReviews ?? undefined,
|
|
27
|
+
proxyBase: props.proxyBase ?? undefined,
|
|
28
28
|
apiKey: props.apiKey || GOOGLE_MAPS_API_KEY,
|
|
29
29
|
});
|
|
30
30
|
setPlace(result.place);
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useEffect } from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
4
5
|
import { getInstagramTiles } from './instagram.functions';
|
|
5
6
|
import { Tiles } from '../carousel/tiles';
|
|
7
|
+
InstagramTiles.propTypes = {
|
|
8
|
+
accessToken: PropTypes.string,
|
|
9
|
+
userId: PropTypes.string,
|
|
10
|
+
limit: PropTypes.number,
|
|
11
|
+
rowCount: PropTypes.number,
|
|
12
|
+
useThumbnails: PropTypes.bool,
|
|
13
|
+
includeVideos: PropTypes.bool,
|
|
14
|
+
includeCaptions: PropTypes.bool,
|
|
15
|
+
};
|
|
6
16
|
export function InstagramTiles(props) {
|
|
7
17
|
const [tiles, setTiles] = useState([]);
|
|
8
18
|
const [loading, setLoading] = useState(true);
|
|
@@ -11,12 +21,12 @@ export function InstagramTiles(props) {
|
|
|
11
21
|
(async () => {
|
|
12
22
|
try {
|
|
13
23
|
const result = await getInstagramTiles({
|
|
14
|
-
accessToken: props.accessToken,
|
|
15
|
-
userId: props.userId,
|
|
24
|
+
accessToken: props.accessToken ?? undefined,
|
|
25
|
+
userId: props.userId ?? undefined,
|
|
16
26
|
limit: props.limit ?? 12,
|
|
17
|
-
useThumbnails: props.useThumbnails,
|
|
18
|
-
includeVideos: props.includeVideos,
|
|
19
|
-
includeCaptions: props.includeCaptions,
|
|
27
|
+
useThumbnails: props.useThumbnails ?? undefined,
|
|
28
|
+
includeVideos: props.includeVideos ?? undefined,
|
|
29
|
+
includeCaptions: props.includeCaptions ?? undefined,
|
|
20
30
|
});
|
|
21
31
|
setTiles(result);
|
|
22
32
|
setLoading(false);
|
|
@@ -80,8 +80,8 @@ export function SmartImage(props) {
|
|
|
80
80
|
newProps.name = safeString(name);
|
|
81
81
|
newProps.title = safeString(title);
|
|
82
82
|
newProps.alt = safeString(alt) ?? '';
|
|
83
|
-
newProps.width = parseNumber(width)
|
|
84
|
-
newProps.height = parseNumber(height)
|
|
83
|
+
newProps.width = parseNumber(width ?? undefined) ?? 500;
|
|
84
|
+
newProps.height = parseNumber(height ?? undefined) ?? 500;
|
|
85
85
|
const filename = (newProps.src).split('/').pop()?.split('?')[0] || '';
|
|
86
86
|
const imageName = filename.replace(/\.[^.]+$/, '');
|
|
87
87
|
newProps.id = newProps.id || newProps.name || sanitizeString(newProps.title) || sanitizeString(newProps.alt) || sanitizeString(imageName);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
4
5
|
import { usePixelatedConfig } from "../config/config.client";
|
|
5
6
|
import { SmartImage } from './smartimage';
|
|
6
7
|
import { PageGridItem } from '../general/semantic';
|
|
@@ -13,6 +14,13 @@ function decodeString(str) {
|
|
|
13
14
|
textarea.innerHTML = str;
|
|
14
15
|
return textarea.value;
|
|
15
16
|
}
|
|
17
|
+
BlogPostList.propTypes = {
|
|
18
|
+
site: PropTypes.string,
|
|
19
|
+
baseURL: PropTypes.string,
|
|
20
|
+
count: PropTypes.number,
|
|
21
|
+
posts: PropTypes.array,
|
|
22
|
+
showCategories: PropTypes.bool,
|
|
23
|
+
};
|
|
16
24
|
export function BlogPostList(props) {
|
|
17
25
|
const { site: propSite, baseURL: propBaseURL, count, posts: cachedPosts, showCategories = true } = props;
|
|
18
26
|
const config = usePixelatedConfig();
|
|
@@ -34,7 +42,12 @@ export function BlogPostList(props) {
|
|
|
34
42
|
// Otherwise, fetch from WordPress
|
|
35
43
|
ToggleLoading({ show: true });
|
|
36
44
|
(async () => {
|
|
37
|
-
const
|
|
45
|
+
const params = { site };
|
|
46
|
+
if (count !== null && count !== undefined)
|
|
47
|
+
params.count = count;
|
|
48
|
+
if (baseURL !== null && baseURL !== undefined)
|
|
49
|
+
params.baseURL = baseURL;
|
|
50
|
+
const data = (await getWordPressItems(params)) ?? [];
|
|
38
51
|
const sorted = data.sort((a, b) => ((a.date ?? '') < (b.date ?? '')) ? 1 : -1);
|
|
39
52
|
setPosts(sorted);
|
|
40
53
|
ToggleLoading({ show: false });
|
|
@@ -42,20 +55,33 @@ export function BlogPostList(props) {
|
|
|
42
55
|
}, [site, baseURL, count, cachedPosts]);
|
|
43
56
|
return (_jsxs(_Fragment, { children: [_jsx(Loading, {}), posts.map((post) => (_jsx(PageGridItem, { children: _jsx(BlogPostSummary, { ID: post.ID, title: post.title, date: post.date, excerpt: post.excerpt, URL: post.URL, categories: post.categories, featured_image: post.featured_image, showCategories: showCategories }) }, post.ID)))] }));
|
|
44
57
|
}
|
|
58
|
+
BlogPostSummary.propTypes = {
|
|
59
|
+
ID: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
60
|
+
title: PropTypes.string,
|
|
61
|
+
date: PropTypes.string,
|
|
62
|
+
excerpt: PropTypes.string,
|
|
63
|
+
URL: PropTypes.string,
|
|
64
|
+
categories: PropTypes.object,
|
|
65
|
+
featured_image: PropTypes.string,
|
|
66
|
+
showCategories: PropTypes.bool,
|
|
67
|
+
};
|
|
45
68
|
export function BlogPostSummary(props) {
|
|
46
|
-
const myCategoryImages = Object.entries(props.categories).map(([category, index]) => [category
|
|
69
|
+
const myCategoryImages = props.categories ? Object.entries(props.categories).map(([category, index]) => [category?.trim().toLowerCase().replace(/[ /]+/g, '-'), index]).sort() : [];
|
|
47
70
|
const config = usePixelatedConfig();
|
|
48
|
-
const myExcerpt = decodeString(props.excerpt).replace(/\[…\]/g, '<a href="' + props.URL + '" target="_blank" rel="noopener noreferrer">[…]</a>');
|
|
49
|
-
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 } }) })] })) :
|
|
71
|
+
const myExcerpt = props.excerpt ? decodeString(props.excerpt).replace(/\[…\]/g, '<a href="' + (props.URL || '') + '" target="_blank" rel="noopener noreferrer">[…]</a>') : '';
|
|
72
|
+
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: props.title ? decodeString(props.title) : '' }) }), _jsxs("div", { className: "dt-published", children: ["Published: ", props.date ? 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: props.title ? decodeString(props.title) : '', title: props.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 } }) })] })) :
|
|
50
73
|
_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));
|
|
51
74
|
}
|
|
75
|
+
BlogPostCategories.propTypes = {
|
|
76
|
+
categories: PropTypes.arrayOf(PropTypes.string),
|
|
77
|
+
};
|
|
52
78
|
export function BlogPostCategories(props) {
|
|
53
79
|
if (!props.categories || props.categories.length === 0) {
|
|
54
80
|
return null;
|
|
55
81
|
}
|
|
56
|
-
const myCategoryImages = props.categories.map((category) => (category !== "Uncategorized")
|
|
82
|
+
const myCategoryImages = props.categories.map((category) => (category && category !== "Uncategorized")
|
|
57
83
|
? category.trim().toLowerCase().replace(/[ /]+/g, '-')
|
|
58
|
-
: undefined).sort();
|
|
84
|
+
: undefined).filter(Boolean).sort();
|
|
59
85
|
const config = usePixelatedConfig();
|
|
60
86
|
return (_jsxs("div", { className: "blogPostCategories", children: [_jsx("div", { children: "Categories: " }), myCategoryImages.map((categoryImg, index) => categoryImg ? (_jsx("span", { className: "p-category", children: _jsx(SmartImage, { className: "u-photo", 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)) : null)] }));
|
|
61
87
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useEffect } from "react";
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
4
5
|
/*
|
|
5
6
|
NOTE : development has stopped for this component
|
|
6
7
|
as Yelp Base API Access costs $229 per month.
|
|
@@ -12,6 +13,10 @@ https://www.google.com/search?q=yelp+reviews+react+component&oq=yelp+reviews+rea
|
|
|
12
13
|
https://www.reddit.com/r/nextjs/comments/16smhqa/next_js_fetching_data_from_yelp_api/
|
|
13
14
|
https://helloputnam.medium.com/easiest-way-to-include-business-reviews-on-a-web-app-google-facebook-yelp-etc-de3e243bbe75
|
|
14
15
|
*/
|
|
16
|
+
YelpReviews.propTypes = {
|
|
17
|
+
businessID: PropTypes.string.isRequired,
|
|
18
|
+
key: PropTypes.string,
|
|
19
|
+
};
|
|
15
20
|
export function YelpReviews(props) {
|
|
16
21
|
const [reviews, setReviews] = useState([]);
|
|
17
22
|
const [loading, setLoading] = useState(true);
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
2
3
|
import { getClientOnlyPixelatedConfig } from './config';
|
|
3
4
|
// Server wrapper: reads server env blob and sanitizes it, then mounts the client provider.
|
|
4
5
|
// Important: do NOT import client components at module scope — dynamically import
|
|
5
6
|
// the client provider inside the function so this module remains server-safe.
|
|
6
|
-
|
|
7
|
+
PixelatedServerConfigProvider.propTypes = {
|
|
8
|
+
config: PropTypes.object,
|
|
9
|
+
children: PropTypes.node.isRequired,
|
|
10
|
+
};
|
|
11
|
+
export async function PixelatedServerConfigProvider(props) {
|
|
12
|
+
const { config, children } = props;
|
|
7
13
|
const cfg = config ?? getClientOnlyPixelatedConfig();
|
|
8
14
|
const mod = await import('./config.client');
|
|
9
15
|
const Provider = mod.PixelatedClientConfigProvider;
|
|
@@ -7,7 +7,8 @@ https://signalvnoise.com/posts/2577-loading-spinner-animation-using-css-and-webk
|
|
|
7
7
|
https://www.andreaverlicchi.eu/blog/css-3-only-spinning-loading-animation/
|
|
8
8
|
*/
|
|
9
9
|
/* ========== MARKDOWN ========== */
|
|
10
|
-
|
|
10
|
+
Loading.propTypes = {};
|
|
11
|
+
export function Loading(props) {
|
|
11
12
|
return (_jsx(_Fragment, { children: _jsx("div", { id: "loadingSpinner", className: "loading", children: _jsxs("div", { className: "spinner", children: [_jsx("div", { className: "bar1" }), _jsx("div", { className: "bar2" }), _jsx("div", { className: "bar3" }), _jsx("div", { className: "bar4" }), _jsx("div", { className: "bar5" }), _jsx("div", { className: "bar6" }), _jsx("div", { className: "bar7" }), _jsx("div", { className: "bar8" }), _jsx("div", { className: "bar9" }), _jsx("div", { className: "bar10" }), _jsx("div", { className: "bar11" }), _jsx("div", { className: "bar12" })] }) }) }));
|
|
12
13
|
}
|
|
13
14
|
ToggleLoading.propTypes = {
|
|
@@ -29,7 +29,6 @@ export function MicroInteractions(props) {
|
|
|
29
29
|
if (props.scrollfadeElements)
|
|
30
30
|
ScrollFade(props.scrollfadeElements);
|
|
31
31
|
}
|
|
32
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
33
32
|
function isElementInViewport(el) {
|
|
34
33
|
const rect = el.getBoundingClientRect();
|
|
35
34
|
return (rect.top >= 0 &&
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
.modal {
|
|
3
|
-
|
|
4
3
|
position: fixed; /* Stay in place */
|
|
5
4
|
z-index: 1000; /* Sit on top */
|
|
6
|
-
top:
|
|
7
|
-
left:
|
|
8
|
-
transform: translate(-50%, -50%);
|
|
5
|
+
top: 0;
|
|
6
|
+
left: 0;
|
|
9
7
|
width: 100%; /* Full width */
|
|
10
8
|
height: 100%; /* Full height */
|
|
11
9
|
overflow: auto; /* Enable scroll if needed */
|
|
@@ -1,45 +1,87 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect } from 'react';
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
4
5
|
import './modal.css';
|
|
5
6
|
/*
|
|
6
7
|
https://www.w3schools.com/howto/howto_css_modals.asp
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
Modal.propTypes = {
|
|
10
|
+
modalContent: PropTypes.node.isRequired,
|
|
11
|
+
modalID: PropTypes.string,
|
|
12
|
+
isOpen: PropTypes.bool,
|
|
13
|
+
handleCloseEvent: PropTypes.func,
|
|
14
|
+
};
|
|
15
|
+
export function Modal({ modalContent, modalID, isOpen = false, handleCloseEvent }) {
|
|
16
|
+
const myModalID = "myModal" + (modalID ?? '');
|
|
17
|
+
const myModalCloseID = "myModalClose" + (modalID ?? '');
|
|
18
|
+
const modalRef = useRef(null);
|
|
11
19
|
useEffect(() => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
myModal
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
const myModalClose = document.getElementById(myModalCloseID);
|
|
20
|
-
if (myModalClose) {
|
|
21
|
-
myModalClose.addEventListener('click', handleModalClose);
|
|
22
|
-
}
|
|
23
|
-
;
|
|
24
|
-
const handleWindowOnClick = (event) => {
|
|
25
|
-
const myModal = document.getElementById(myModalID);
|
|
26
|
-
if (event.target == myModal) {
|
|
20
|
+
// Only use DOM event listeners for backward compatibility when handleCloseEvent is not provided
|
|
21
|
+
if (!handleCloseEvent) {
|
|
22
|
+
const handleModalClose = (event) => {
|
|
23
|
+
event.preventDefault();
|
|
24
|
+
const myModal = document.getElementById(myModalID);
|
|
27
25
|
if (myModal) {
|
|
28
|
-
myModal.style.display =
|
|
26
|
+
myModal.style.display = 'none';
|
|
29
27
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
};
|
|
33
|
-
window.addEventListener('click', handleWindowOnClick);
|
|
34
|
-
return () => {
|
|
35
|
-
window.removeEventListener('click', handleWindowOnClick);
|
|
28
|
+
};
|
|
29
|
+
const myModalClose = document.getElementById(myModalCloseID);
|
|
36
30
|
if (myModalClose) {
|
|
37
|
-
myModalClose.
|
|
31
|
+
myModalClose.addEventListener('click', handleModalClose);
|
|
38
32
|
}
|
|
39
33
|
;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
const handleWindowOnClick = (event) => {
|
|
35
|
+
const myModal = document.getElementById(myModalID);
|
|
36
|
+
if (event.target == myModal) {
|
|
37
|
+
if (myModal) {
|
|
38
|
+
myModal.style.display = 'none';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
window.addEventListener('click', handleWindowOnClick);
|
|
43
|
+
return () => {
|
|
44
|
+
window.removeEventListener('click', handleWindowOnClick);
|
|
45
|
+
if (myModalClose) {
|
|
46
|
+
myModalClose.removeEventListener('click', handleModalClose);
|
|
47
|
+
}
|
|
48
|
+
;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// For React approach, add escape key listener
|
|
53
|
+
const handleEscape = (event) => {
|
|
54
|
+
if (event.key === 'Escape') {
|
|
55
|
+
handleCloseEvent();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
document.addEventListener('keydown', handleEscape);
|
|
59
|
+
return () => {
|
|
60
|
+
document.removeEventListener('keydown', handleEscape);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}, [myModalID, myModalCloseID, handleCloseEvent]);
|
|
64
|
+
const handleCloseClick = handleCloseEvent ? (event) => {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
handleCloseEvent();
|
|
67
|
+
} : undefined;
|
|
68
|
+
const handleCloseKeyDown = handleCloseEvent ? (event) => {
|
|
69
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
handleCloseEvent();
|
|
72
|
+
}
|
|
73
|
+
} : undefined;
|
|
74
|
+
const handleModalClick = handleCloseEvent ? (event) => {
|
|
75
|
+
if (event.target === modalRef.current) {
|
|
76
|
+
handleCloseEvent();
|
|
77
|
+
}
|
|
78
|
+
} : undefined;
|
|
79
|
+
const handleModalKeyDown = handleCloseEvent ? (event) => {
|
|
80
|
+
if (event.key === 'Escape' && event.target === modalRef.current) {
|
|
81
|
+
handleCloseEvent();
|
|
82
|
+
}
|
|
83
|
+
} : undefined;
|
|
84
|
+
return (_jsx("div", { id: myModalID, className: "modal", style: { display: isOpen ? 'block' : 'none' }, ref: modalRef, onClick: handleModalClick, children: _jsxs("div", { className: "modal-content", role: "dialog", "aria-modal": "true", children: [_jsx("button", { id: myModalCloseID, className: "modal-close", "aria-label": "Close modal", onClick: handleCloseClick, onKeyDown: handleCloseKeyDown, type: "button", children: "\u00D7" }), modalContent] }) }));
|
|
43
85
|
}
|
|
44
86
|
export const handleModalOpen = (event, modalID) => {
|
|
45
87
|
const myModalID = "myModal" + (modalID ?? '');
|
|
@@ -3,7 +3,23 @@
|
|
|
3
3
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { useEffect, useRef, useState } from 'react';
|
|
5
5
|
import { createPortal } from 'react-dom';
|
|
6
|
+
import PropTypes from 'prop-types';
|
|
6
7
|
import './sidepanel.css';
|
|
8
|
+
// Define const arrays for options - used by both PropTypes and form generation
|
|
9
|
+
export const positions = ['left', 'right'];
|
|
10
|
+
SidePanel.propTypes = {
|
|
11
|
+
isOpen: PropTypes.bool.isRequired,
|
|
12
|
+
onClose: PropTypes.func.isRequired,
|
|
13
|
+
onToggle: PropTypes.func,
|
|
14
|
+
position: PropTypes.oneOf([...positions]),
|
|
15
|
+
width: PropTypes.string,
|
|
16
|
+
showOverlay: PropTypes.bool,
|
|
17
|
+
showTab: PropTypes.bool,
|
|
18
|
+
tabIcon: PropTypes.node,
|
|
19
|
+
tabLabel: PropTypes.string,
|
|
20
|
+
children: PropTypes.node,
|
|
21
|
+
className: PropTypes.string,
|
|
22
|
+
};
|
|
7
23
|
export default function SidePanel({ isOpen, onClose, onToggle, position = 'left', width = '300px', showOverlay = true, showTab = false, tabIcon /* = "≡" */, tabLabel, children, className = '' }) {
|
|
8
24
|
const portalRootRef = useRef(null);
|
|
9
25
|
const wrapperRef = useRef(null);
|
|
@@ -4,6 +4,15 @@ import { useEffect, useRef } from 'react';
|
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import './menu-accordion.css';
|
|
6
6
|
const hamburgerIcon = "≡"; /* (U+2261) */ /* ||| */
|
|
7
|
+
const menuItemShape = PropTypes.shape({
|
|
8
|
+
name: PropTypes.string.isRequired,
|
|
9
|
+
path: PropTypes.string,
|
|
10
|
+
target: PropTypes.string,
|
|
11
|
+
routes: PropTypes.array, // Will be refined after function declaration
|
|
12
|
+
hidden: PropTypes.bool,
|
|
13
|
+
});
|
|
14
|
+
// Update the recursive reference after the shape is defined
|
|
15
|
+
menuItemShape.routes = PropTypes.arrayOf(menuItemShape);
|
|
7
16
|
function generateMenuItems({ menuData, state = "hide" }) {
|
|
8
17
|
const myItems = [];
|
|
9
18
|
let index = 0;
|
|
@@ -27,9 +36,8 @@ function generateMenuItems({ menuData, state = "hide" }) {
|
|
|
27
36
|
}
|
|
28
37
|
return myItems;
|
|
29
38
|
}
|
|
30
|
-
/* ========== MENU ========== */
|
|
31
39
|
MenuAccordion.propTypes = {
|
|
32
|
-
menuItems: PropTypes.
|
|
40
|
+
menuItems: PropTypes.arrayOf(menuItemShape).isRequired,
|
|
33
41
|
showHidden: PropTypes.bool,
|
|
34
42
|
};
|
|
35
43
|
export function MenuAccordion(props) {
|
|
@@ -145,7 +153,10 @@ export function MenuAccordion(props) {
|
|
|
145
153
|
}
|
|
146
154
|
/* ========== MENU GROUP ========== */
|
|
147
155
|
MenuAccordionGroup.propTypes = {
|
|
148
|
-
menuItems: PropTypes.
|
|
156
|
+
menuItems: PropTypes.oneOfType([
|
|
157
|
+
menuItemShape,
|
|
158
|
+
PropTypes.arrayOf(menuItemShape)
|
|
159
|
+
]).isRequired,
|
|
149
160
|
state: PropTypes.string,
|
|
150
161
|
};
|
|
151
162
|
export function MenuAccordionGroup(props) {
|
|
@@ -168,7 +179,7 @@ export function MenuAccordionItem(props) {
|
|
|
168
179
|
https://www.unclebigbay.com/blog/building-the-world-simplest-hamburger-with-html-and-css
|
|
169
180
|
*/
|
|
170
181
|
MenuAccordionButton.propTypes = {};
|
|
171
|
-
export function MenuAccordionButton() {
|
|
182
|
+
export function MenuAccordionButton(props) {
|
|
172
183
|
function slideMobilePanel() {
|
|
173
184
|
if (typeof window !== 'undefined' && window.moveMenu) {
|
|
174
185
|
window.moveMenu();
|