From 68a5cde8cfcd7c4595115a2d9ca4473d69a46552 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:16:00 -0700 Subject: [PATCH 01/14] moving files --- .../local-addon/decorators/withHeader.js | 2 +- .../anchor-menu => src/js}/anchor-menu.js | 14 ++++++-- .../molecules/banners => src/js}/banner.js | 0 .../js}/blockquote-animated.js | 10 +++--- .../src/js/bootstrap-helper.js | 11 ++++++ .../molecules/calendar => src/js}/calendar.js | 9 +++++ .../js/card-ranking.js} | 6 +++- .../js}/charts-and-graphs.js | 15 +++++++- .../heroes => src/js}/heroes-video.js | 8 +++-- .../js}/image-parallax.js | 16 ++++----- .../atoms/modals => src/js}/modals.js | 4 +++ .../tabbed-panels => src/js}/tabbed-panels.js | 0 .../molecules/tables => src/js}/tables.js | 23 ++++++++----- .../src/js/unity-bootstrap-theme.js | 34 +++++++++++++++++++ .../{stories/atoms/video => src/js}/video.js | 3 ++ .../tabbed-panels.js.stories.mdx | 8 ----- .../organisms/global-footer/global-footer.js | 25 -------------- .../global-header.examples.stories.js | 2 +- ...mplates.js => global-header.templates.jsx} | 0 19 files changed, 127 insertions(+), 63 deletions(-) rename packages/unity-bootstrap-theme/{stories/atoms/anchor-menu => src/js}/anchor-menu.js (94%) rename packages/unity-bootstrap-theme/{stories/molecules/banners => src/js}/banner.js (100%) rename packages/unity-bootstrap-theme/{stories/atoms/blockquote => src/js}/blockquote-animated.js (77%) create mode 100644 packages/unity-bootstrap-theme/src/js/bootstrap-helper.js rename packages/unity-bootstrap-theme/{stories/molecules/calendar => src/js}/calendar.js (96%) rename packages/unity-bootstrap-theme/{stories/molecules/cards/ranking-cards.js => src/js/card-ranking.js} (62%) rename packages/unity-bootstrap-theme/{stories/molecules/charts-and-graphs => src/js}/charts-and-graphs.js (77%) rename packages/unity-bootstrap-theme/{stories/molecules/heroes => src/js}/heroes-video.js (90%) rename packages/unity-bootstrap-theme/{stories/molecules/image-parallax => src/js}/image-parallax.js (90%) rename packages/unity-bootstrap-theme/{stories/atoms/modals => src/js}/modals.js (78%) rename packages/unity-bootstrap-theme/{stories/molecules/tabbed-panels => src/js}/tabbed-panels.js (100%) rename packages/unity-bootstrap-theme/{stories/molecules/tables => src/js}/tables.js (79%) create mode 100644 packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js rename packages/unity-bootstrap-theme/{stories/atoms/video => src/js}/video.js (94%) delete mode 100644 packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.js.stories.mdx delete mode 100644 packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.js rename packages/unity-bootstrap-theme/stories/organisms/global-header/{global-header.templates.js => global-header.templates.jsx} (100%) diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withHeader.js b/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withHeader.js index 395afd71e9..dae88174b2 100644 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withHeader.js +++ b/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withHeader.js @@ -1,7 +1,7 @@ import React, { useEffect, useRef} from 'react'; import { makeDecorator } from '@storybook/addons'; -import { Basic as Header } from "../../../stories/organisms/global-header/global-header.templates"; +import { Basic as Header } from "../../../stories/organisms/global-header/global-header.templates.jsx"; import { initGlobalHeader } from "../../../src/js/storybook-global-header"; diff --git a/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.js b/packages/unity-bootstrap-theme/src/js/anchor-menu.js similarity index 94% rename from packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.js rename to packages/unity-bootstrap-theme/src/js/anchor-menu.js index 3200e706d3..d13fb7ea26 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.js +++ b/packages/unity-bootstrap-theme/src/js/anchor-menu.js @@ -1,9 +1,15 @@ -const bootstrap = require('bootstrap'); +import { EventHandler } from "./bootstrap-helper"; -function initializeAnchorMenu () { +function initAnchorMenu () { const HEADER_IDS = ['asu-header', 'asuHeader']; const globalHeaderId = HEADER_IDS.find((id) => document.getElementById(id)); + + if (globalHeaderId === undefined) { + // Asu header not found in the DOM. + return; + } + const globalHeader = document.getElementById(globalHeaderId); const navbar = document.getElementById('uds-anchor-menu'); const navbarOriginalParent = navbar.parentNode; @@ -115,4 +121,6 @@ function initializeAnchorMenu () { } }; -export { initializeAnchorMenu }; +EventHandler.on(window, 'load.uds.anchor-menu', initAnchorMenu); + +export { initAnchorMenu }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/banners/banner.js b/packages/unity-bootstrap-theme/src/js/banner.js similarity index 100% rename from packages/unity-bootstrap-theme/stories/molecules/banners/banner.js rename to packages/unity-bootstrap-theme/src/js/banner.js diff --git a/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote-animated.js b/packages/unity-bootstrap-theme/src/js/blockquote-animated.js similarity index 77% rename from packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote-animated.js rename to packages/unity-bootstrap-theme/src/js/blockquote-animated.js index 3acc52fa28..d41fb235ab 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote-animated.js +++ b/packages/unity-bootstrap-theme/src/js/blockquote-animated.js @@ -1,5 +1,6 @@ -function initializeBlockquoteAnimation () { - window.addEventListener("load", () => { +import { EventHandler } from "./bootstrap-helper"; + +function initBlockquoteAnimation () { // Find all marks with a class starting with pen- const markers = document.querySelectorAll('mark[class^="pen-"]'); @@ -24,7 +25,8 @@ function initializeBlockquoteAnimation () { markers.forEach((mark) => { observer.observe(mark); }); - }); } -export { initializeBlockquoteAnimation }; +EventHandler.on(window, 'load.uds.blockquote-animation', initBlockquoteAnimation); + +export { initBlockquoteAnimation }; diff --git a/packages/unity-bootstrap-theme/src/js/bootstrap-helper.js b/packages/unity-bootstrap-theme/src/js/bootstrap-helper.js new file mode 100644 index 0000000000..b5176666eb --- /dev/null +++ b/packages/unity-bootstrap-theme/src/js/bootstrap-helper.js @@ -0,0 +1,11 @@ +import BaseComponent from 'bootstrap/js/src/base-component.js' +import EventHandler from "bootstrap/js/src/dom/event-handler.js"; +import { enableDismissTrigger } from 'bootstrap/js/src/util/component-functions.js' +import { defineJQueryPlugin } from 'bootstrap/js/src/util/index.js' + +export { + BaseComponent, + EventHandler, + enableDismissTrigger, + defineJQueryPlugin, +}; diff --git a/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.js b/packages/unity-bootstrap-theme/src/js/calendar.js similarity index 96% rename from packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.js rename to packages/unity-bootstrap-theme/src/js/calendar.js index 415d4b825f..dca9f533d0 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.js +++ b/packages/unity-bootstrap-theme/src/js/calendar.js @@ -1,3 +1,5 @@ +import { EventHandler } from "./bootstrap-helper"; + function initCalendar() { const months = [ 'January', @@ -81,6 +83,11 @@ function initCalendar() { const render = () => { const calendarContainer = document.getElementById('calendar'); + + if (!calendarContainer) { + return; + } + calendarContainer.innerHTML = `

${months[state.month]} ${ state.year @@ -154,4 +161,6 @@ function initCalendar() { showCalendar(0); }; +EventHandler.on(window, 'load.uds.calendar', initCalendar); + export { initCalendar } diff --git a/packages/unity-bootstrap-theme/stories/molecules/cards/ranking-cards.js b/packages/unity-bootstrap-theme/src/js/card-ranking.js similarity index 62% rename from packages/unity-bootstrap-theme/stories/molecules/cards/ranking-cards.js rename to packages/unity-bootstrap-theme/src/js/card-ranking.js index 449f2ae793..88cc28d4ec 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/cards/ranking-cards.js +++ b/packages/unity-bootstrap-theme/src/js/card-ranking.js @@ -1,12 +1,16 @@ +import { EventHandler } from "./bootstrap-helper"; + // method ot handle the custom behavior of the ranking card function rankingFunc() { const $infoLayer = document.querySelector(".info-layer"); const $toggleIcon = document.getElementById("dispatch"); - $toggleIcon?.addEventListener("click", function () { + EventHandler.on($toggleIcon, "click", function () { $infoLayer?.classList.toggle("active"); }); }; +EventHandler.on(window, 'load.uds.ranking-card', rankingFunc); + export { rankingFunc }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.js b/packages/unity-bootstrap-theme/src/js/charts-and-graphs.js similarity index 77% rename from packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.js rename to packages/unity-bootstrap-theme/src/js/charts-and-graphs.js index db09b07981..a7233eda59 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.js +++ b/packages/unity-bootstrap-theme/src/js/charts-and-graphs.js @@ -1,11 +1,22 @@ import { Chart, registerables } from 'chart.js'; +import { EventHandler } from './bootstrap-helper'; + +// Chart.js library should be peer dependency + Chart.register(...registerables); function initChart() { const GRAPH_PERCENTAGE_COMPLETE = 50; + + var ctx = document.getElementById('uds-donut'); + + if (!ctx) { + // id="uds-donut" not found in the DOM. + return; + } + document.getElementById('percentage-display').innerHTML = GRAPH_PERCENTAGE_COMPLETE + '%'; - var ctx = document.getElementById('uds-donut'); const config = { type: 'doughnut', @@ -29,4 +40,6 @@ function initChart() { var myChart = new Chart(ctx, config); }; +EventHandler.on(window, 'load.uds.chart', initChart); + export { initChart }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes-video.js b/packages/unity-bootstrap-theme/src/js/heroes-video.js similarity index 90% rename from packages/unity-bootstrap-theme/stories/molecules/heroes/heroes-video.js rename to packages/unity-bootstrap-theme/src/js/heroes-video.js index ed33567562..5b60fdff4f 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes-video.js +++ b/packages/unity-bootstrap-theme/src/js/heroes-video.js @@ -1,4 +1,6 @@ -function initVideo() { +import { EventHandler } from "./bootstrap-helper"; + +function initHeroesVideo() { // common selectors const DOM_ELEMENT_VIDEO = "video"; const DOM_ELEMENT_BTN_PLAY = "#playHeroVid"; @@ -50,4 +52,6 @@ function initVideo() { }; -export { initVideo }; +EventHandler.on(window, 'load.uds.heroes-video', initHeroesVideo); + +export { initHeroesVideo }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.js b/packages/unity-bootstrap-theme/src/js/image-parallax.js similarity index 90% rename from packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.js rename to packages/unity-bootstrap-theme/src/js/image-parallax.js index 404a427d40..f36e1befb8 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.js +++ b/packages/unity-bootstrap-theme/src/js/image-parallax.js @@ -1,3 +1,5 @@ +import { EventHandler } from "./bootstrap-helper"; + export const initImageParallax = () => { const MAGIC_PARALLAX_FACTOR = 1.2; @@ -91,7 +93,7 @@ export const initImageParallax = () => { // dataLayer elements focus event listener const elements = document.querySelectorAll('[data-ga-image-parallax]'); elements.forEach((element) => - element.addEventListener('focus', () => { + EventHandler.on(element, 'focus.uds.image-parallax', () => { const args = { section: element .getAttribute('data-ga-image-parallax-section') @@ -103,13 +105,11 @@ export const initImageParallax = () => { ); // Window management - window.addEventListener('DOMContentLoaded', function () { - manage_image_sizes(); - }); + manage_image_sizes(); - window.addEventListener('resize', function () { - manage_image_sizes(); - }); + EventHandler.on(window, 'resize.uds.image-parallax', manage_image_sizes); - window.addEventListener('scroll', scrollHandler); + EventHandler.on(window, 'scroll.uds.image-parallax', scrollHandler); }; + +EventHandler.on(window, 'load.uds.image-parallax', initImageParallax); diff --git a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.js b/packages/unity-bootstrap-theme/src/js/modals.js similarity index 78% rename from packages/unity-bootstrap-theme/stories/atoms/modals/modals.js rename to packages/unity-bootstrap-theme/src/js/modals.js index 44d4128ffb..52a00c961e 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.js +++ b/packages/unity-bootstrap-theme/src/js/modals.js @@ -1,3 +1,5 @@ +import { EventHandler } from "./bootstrap-helper"; + function initModals() { document .getElementById('openModalButton') @@ -12,4 +14,6 @@ function initModals() { }); }; +EventHandler.on(window, 'load.uds.modals', initModals); + export { initModals }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.js b/packages/unity-bootstrap-theme/src/js/tabbed-panels.js similarity index 100% rename from packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.js rename to packages/unity-bootstrap-theme/src/js/tabbed-panels.js diff --git a/packages/unity-bootstrap-theme/stories/molecules/tables/tables.js b/packages/unity-bootstrap-theme/src/js/tables.js similarity index 79% rename from packages/unity-bootstrap-theme/stories/molecules/tables/tables.js rename to packages/unity-bootstrap-theme/src/js/tables.js index 19edab9e2e..57a3b2890f 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/tables/tables.js +++ b/packages/unity-bootstrap-theme/src/js/tables.js @@ -4,12 +4,15 @@ * Fixed table should display scroll buttons when hovering over scrollable * portion of table, and hide them when hovering over fixed column or when * mouse exits table. - * - * The scroll buttons must be outside the table container, within the table wrapper, - * due to the absolute positioning requirements. Because the table scrolls, - * if they were to be absolutely positioned in the same container as the table, - * they would scroll with it. - */ +* +* The scroll buttons must be outside the table container, within the table wrapper, +* due to the absolute positioning requirements. Because the table scrolls, +* if they were to be absolutely positioned in the same container as the table, +* they would scroll with it. +*/ + +import { EventHandler } from "./bootstrap-helper"; + function initializeFixedTable() { function setPreButtonPosition() { @@ -43,12 +46,12 @@ function initializeFixedTable() { const nextButton = wrapper.querySelector(nextScrollSelector); ['click', 'focus'].forEach((eventName) => { - prevButton.addEventListener(eventName, function () { + EventHandler.on(prevButton, eventName, function () { /* Scroll can't go beyond it's bounds, it won't go lower than 0 */ container.scrollLeft -= 100; }); - nextButton.addEventListener(eventName, function () { + EventHandler.on(nextButton, eventName, function () { container.scrollLeft += 100; }); }); @@ -66,9 +69,11 @@ function initializeFixedTable() { } setPreButtonPosition(); setButtonLiListeners(); - window.addEventListener('resize', function () { + EventHandler.on(window, 'resize', function () { debounce(setPreButtonPosition, 100)(); }); } +EventHandler.on(window, 'load.uds.fixed-table', initializeFixedTable); + export { initializeFixedTable }; diff --git a/packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js b/packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js new file mode 100644 index 0000000000..4e5b7311be --- /dev/null +++ b/packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js @@ -0,0 +1,34 @@ +import { initAnchorMenu } from "./anchor-menu.js"; +// import Banner from "./banner.js"; +import { initBlockquoteAnimation } from "./blockquote-animated.js"; +import { initCalendar } from "./calendar.js"; +import { rankingFunc } from "./card-ranking.js"; +import { initChart } from "./charts-and-graphs.js"; +import { initDataLayer } from "./data-layer.js"; +import { initGlobalHeader } from "./global-header.js"; +import { initHeroesVideo } from "./heroes-video.js"; +import { initImageParallax } from "./image-parallax.js"; +import { initModals } from "./modals.js"; +import { initTabs } from "./tabbed-panels.js"; +import { initializeFixedTable } from "./tables.js"; +import { initVideo } from "./video.js"; + +const unityBootstrap = { + // EventHandler, + initAnchorMenu, + // Banner, + initBlockquoteAnimation, + initCalendar, + rankingFunc, + initChart, + initDataLayer, + initGlobalHeader, + initHeroesVideo, + initImageParallax, + initModals, + initializeFixedTable, + initVideo, + initTabs, +} + +export default unityBootstrap; diff --git a/packages/unity-bootstrap-theme/stories/atoms/video/video.js b/packages/unity-bootstrap-theme/src/js/video.js similarity index 94% rename from packages/unity-bootstrap-theme/stories/atoms/video/video.js rename to packages/unity-bootstrap-theme/src/js/video.js index e3a7a495b8..866a19252a 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/video/video.js +++ b/packages/unity-bootstrap-theme/src/js/video.js @@ -1,3 +1,4 @@ +import { EventHandler } from "./bootstrap-helper"; function initVideo() { // constants @@ -57,4 +58,6 @@ function initVideo() { }; +EventHandler.on(window, 'load.uds.video', initVideo); + export { initVideo }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.js.stories.mdx b/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.js.stories.mdx deleted file mode 100644 index 342e4a8540..0000000000 --- a/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.js.stories.mdx +++ /dev/null @@ -1,8 +0,0 @@ -import { Meta, Source } from "@storybook/blocks"; -import { initTabs as initFunc } from "./tabbed-panels.js" - - - -## Tabbed Panels - - diff --git a/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.js b/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.js deleted file mode 100644 index c847b32f49..0000000000 --- a/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.js +++ /dev/null @@ -1,25 +0,0 @@ -export const initFooterGA = () => { - const pushFooterGAEvent = (args) => { - const { dataLayer } = window; - const event = { - event: 'link', - action: 'click', - name: 'onclick', - region: 'footer', - ...args, - }; - if (dataLayer) dataLayer.push(event); - }; - - const elements = document.querySelectorAll('[data-ga-footer]'); - elements.forEach((element) => - element.addEventListener('focus', () => { - const args = { - type: element.getAttribute('data-ga-footer-type').toLowerCase(), - section: element.getAttribute('data-ga-footer-section').toLowerCase(), - text: element.getAttribute('data-ga-footer').toLowerCase(), - }; - pushFooterGAEvent(args); - }) - ); -}; diff --git a/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.examples.stories.js b/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.examples.stories.js index 3f3cced52b..864132747b 100644 --- a/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.examples.stories.js @@ -8,7 +8,7 @@ import { NoNavigationAndWithButtons, ScrolledState, Partner, -} from "./global-header.templates.js"; +} from "./global-header.templates.jsx"; export default { title: "Organisms/Global Header/Examples", diff --git a/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.templates.js b/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.templates.jsx similarity index 100% rename from packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.templates.js rename to packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.templates.jsx From 1ec8be19a6397778666f7d50deeafd98f15f44d6 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:31:31 -0700 Subject: [PATCH 02/14] removing initFunctions --- .../.storybook/local-addon/addon.js | 17 ------------- .../local-addon/decorators/withFooter.js | 14 +---------- .../local-addon/decorators/withHeader.js | 14 +---------- .../local-addon/decorators/withInitFunc.js | 18 -------------- .../local-addon/decorators/withLoadEvent.js | 24 ------------------- .../.storybook/local-addon/entry.js | 10 -------- .../unity-bootstrap-theme/.storybook/main.js | 1 + .../blockquote.templates.stories.js | 5 ---- .../atoms/modals/modals.examples.stories.js | 6 ----- .../atoms/modals/modals.templates.stories.js | 5 ---- .../atoms/video/video.templates.stories.js | 7 ------ .../banners/banners.templates.stories.js | 10 ++------ .../calendar/calendar.templates.stories.js | 5 ---- .../molecules/cards/cards.examples.stories.js | 13 ---------- .../charts-and-graphs.templates.stories.js | 5 ---- .../cookie-consent-full-screen.stories.js | 2 -- .../cookie-consent/cookie-consent.stories.js | 3 +-- .../heroes/heroes.examples.stories.js | 8 ------- .../image-parallax.examples.stories.js | 5 ---- .../tabbed-panels.templates.stories.js | 8 ------- .../tables/tables.templates.stories.js | 7 ------ .../global-footer.examples.stories.js | 5 ---- 22 files changed, 6 insertions(+), 186 deletions(-) delete mode 100644 packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withInitFunc.js delete mode 100644 packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withLoadEvent.js diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js b/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js index 20e3985e4e..aa71394add 100644 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js +++ b/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js @@ -6,23 +6,6 @@ import { formatWithBabelParser } from './helpers'; import { Toggle } from '../../../../.storybook-config/Toggle' addons.register('local-addon', (api) => { - addons.add('local-addon/panel', { - title: 'Javascript', - //👇 Sets the type of UI element in Storybook - type: types.PANEL, - paramKey: 'initFunc', - render: ({active, key}) => { - const data = api.getCurrentStoryData(); - const initFunc = data?.parameters?.initFunc?.code || ''; - const code = formatWithBabelParser(`${initFunc}`); - - return( - - - - )}, - }); - addons.add('local-addon/tools', { title: 'tools', type: types.TOOL, diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withFooter.js b/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withFooter.js index f3a5d1f4f2..0f33d32028 100644 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withFooter.js +++ b/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withFooter.js @@ -1,27 +1,15 @@ -import React, { useEffect, useRef} from 'react'; +import React from 'react'; import { makeDecorator } from '@storybook/addons'; - import { GlobalElementsOnly as Footer } from "../../../stories/organisms/global-footer/global-footer.templates"; -import { initFooterGA } from "../../../stories/organisms/global-footer/global-footer" export const withFooter = makeDecorator({ name: 'withFooter', parameterName: 'footer', skipIfNoParametersOrOptions: true, wrapper: (storyFn, context) => { - const loaded = useRef(0); - useEffect(()=>{ - if(document.readyState !== "loading") { - initFooterGA() - } - },[loaded.current]); - loaded.current++; - const { globals, parameters } = context; - const footer = parameters?.footer; const isFooterActive = (globals.footer == true && footer?.disable !== true) || footer.forced == true; - const isStory = context.viewMode === 'story'; return <> diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withHeader.js b/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withHeader.js index dae88174b2..bc1c1b3d3b 100644 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withHeader.js +++ b/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withHeader.js @@ -1,28 +1,16 @@ -import React, { useEffect, useRef} from 'react'; +import React from 'react'; import { makeDecorator } from '@storybook/addons'; import { Basic as Header } from "../../../stories/organisms/global-header/global-header.templates.jsx"; -import { initGlobalHeader } from "../../../src/js/storybook-global-header"; - export const withHeader = makeDecorator({ name: 'withHeader', parameterName: 'header', skipIfNoParametersOrOptions: true, wrapper: (storyFn, context) => { - const loaded = useRef(0); - useEffect(()=>{ - if(document.readyState !== "loading") { - initGlobalHeader() - } - },[loaded.current]); - loaded.current++; - const { globals, parameters } = context; - const header = parameters?.header; const isHeaderActive = (globals.header == true && header?.disable !== true) || header.forced === true; - const isStory = context.viewMode === 'story'; return <> diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withInitFunc.js b/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withInitFunc.js deleted file mode 100644 index db95f2d47b..0000000000 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withInitFunc.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; - -import { makeDecorator } from '@storybook/addons'; - -export const withInitFunc = makeDecorator({ - name: 'withInitFunc', - parameterName: 'initFunc', - skipIfNoParametersOrOptions: true, - wrapper: (storyFn, context) => { - React.useEffect(()=>{ - const initFunc = context?.parameters?.initFunc?.code; - if (typeof initFunc === "function") { - initFunc() - } - },[]) - return storyFn(context); - } -}); diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withLoadEvent.js b/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withLoadEvent.js deleted file mode 100644 index 6de93ee762..0000000000 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/decorators/withLoadEvent.js +++ /dev/null @@ -1,24 +0,0 @@ -import { useEffect, useRef} from 'react'; - -import { makeDecorator } from '@storybook/addons'; - -export const withLoadEvent = makeDecorator({ - name: 'withLoadEvent', - parameterName: 'loadEvent', - skipIfNoParametersOrOptions: true, - wrapper: (storyFn, context) => { - const loaded = useRef(0); - useEffect(()=>{ - if(document.readyState !== "loading") { - // globalThis = window - globalThis.dispatchEvent(new Event("DOMContentLoaded")); - globalThis.dispatchEvent(new Event('load')); - } - if(typeof globalThis.initDataLayer === "function") { - globalThis.initDataLayer(); - } - },[loaded.current]); - loaded.current++; - return storyFn(context) - } -}); diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/entry.js b/packages/unity-bootstrap-theme/.storybook/local-addon/entry.js index 76d4b6985a..ffa92e9e45 100644 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/entry.js +++ b/packages/unity-bootstrap-theme/.storybook/local-addon/entry.js @@ -5,10 +5,6 @@ import { import { withFooter } from './decorators/withFooter'; import { withHeader } from './decorators/withHeader'; -import { withInitFunc } from './decorators/withInitFunc'; -import { withLoadEvent } from './decorators/withLoadEvent'; - -import "../../src/js/data-layer.js"; export const parameters = { header: { @@ -20,10 +16,6 @@ export const parameters = { loadEvent: { disable: false }, - initFunc: { - disable: true, - code: null - }, docs:{ source: { transform: (src,storyContext)=>{ @@ -40,8 +32,6 @@ export const globals = { footer: false } export const decorators = [ - withLoadEvent, - withInitFunc, withHeader, withFooter, ] diff --git a/packages/unity-bootstrap-theme/.storybook/main.js b/packages/unity-bootstrap-theme/.storybook/main.js index 80e3ce3d3f..a696a46574 100644 --- a/packages/unity-bootstrap-theme/.storybook/main.js +++ b/packages/unity-bootstrap-theme/.storybook/main.js @@ -4,6 +4,7 @@ export default { staticDirs: ['../dist'], stories: ["../stories/**/*.stories.mdx", "../stories/**/*.stories.@(js|jsx|ts|tsx)"], addons: [ + "./local-addon", "../../../.storybook-config", "../../../.storybook-config/dataLayerListener", "@whitespace/storybook-addon-html", diff --git a/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote.templates.stories.js b/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote.templates.stories.js index bb30006ef8..e81016be34 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote.templates.stories.js @@ -2,15 +2,10 @@ import React from "react"; import { imageName } from "../../../../../shared/assets"; import { defaultDecorator } from "../../../../../shared/components/Layout.js"; -import { initializeBlockquoteAnimation as doAnimate } from "./blockquote-animated"; export default { title: "Atoms/Blockquotes and Testimonials/Templates", parameters: { - initFunc: { - disable: false, - code: doAnimate, - }, }, args: { type: "On White", diff --git a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.examples.stories.js b/packages/unity-bootstrap-theme/stories/atoms/modals/modals.examples.stories.js index dac601a545..68555a4534 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/modals/modals.examples.stories.js @@ -1,14 +1,8 @@ import React from "react"; -import { initModals as initFunc } from "./modals.js"; - export default { title: "Atoms/Modals/Examples", parameters: { - initFunc: { - disable: false, - code: initFunc - }, header: { forced: true, }, diff --git a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.templates.stories.js b/packages/unity-bootstrap-theme/stories/atoms/modals/modals.templates.stories.js index 1e42a5ffa2..c87847dee5 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/modals/modals.templates.stories.js @@ -1,16 +1,11 @@ import React from "react"; import { defaultDecorator } from "../../../../../shared/components/Layout"; -import { initModals as initFunc } from "./modals.js"; export default { title: "Atoms/Modals/Templates", decorators: [ defaultDecorator ], parameters: { - initFunc: { - disable: false, - code: initFunc - }, header: { forced: true, }, diff --git a/packages/unity-bootstrap-theme/stories/atoms/video/video.templates.stories.js b/packages/unity-bootstrap-theme/stories/atoms/video/video.templates.stories.js index d795f44e27..5668c84a8f 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/video/video.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/video/video.templates.stories.js @@ -2,7 +2,6 @@ import React from "react"; // @ts-ignore import stockVideo from "./stock-video-person-drawing.mp4"; -import { initVideo as initFunc } from "./video"; export default { @@ -14,12 +13,6 @@ export default { control: { type: "boolean" }, }, }, - parameters: { - initFunc: { - disable: false, - code: initFunc - }, - }, }; export const Default = ({content}) => diff --git a/packages/unity-bootstrap-theme/stories/molecules/banners/banners.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/banners/banners.templates.stories.js index d4b783311f..d385da5dc8 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/banners/banners.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/banners/banners.templates.stories.js @@ -1,19 +1,12 @@ import React from "react"; import { fullLayoutDecorator } from "../../../../../shared/components/Layout"; -import { initBanner as initFunc } from "./banner"; export default { title: "Molecules/Banners/Templates", decorators: [ fullLayoutDecorator ], - parameters: { - initFunc: { - code: initFunc, - disable: false, - }, - }, argTypes: { color: { name: "Color", @@ -36,7 +29,7 @@ export default { export const Banner = ({color}) => { return ( -
+
@@ -67,6 +60,7 @@ export const Banner = ({color}) => { type="button" className="btn btn-circle btn-circle-alt-black close" aria-label="Close" + data-bs-dismiss="alert" > diff --git a/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.templates.stories.js index 08572e5917..b8352665a8 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.templates.stories.js @@ -1,16 +1,11 @@ import React from "react"; import { defaultDecorator } from "../../../../../shared/components/Layout"; -import { initCalendar as initFunc } from "./calendar"; export default { title: "Molecules/Calendar/Templates", decorators: [ defaultDecorator ], parameters: { - initFunc: { - code: initFunc, - disable: false, - }, controls: { disable: true } }, }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/cards/cards.examples.stories.js b/packages/unity-bootstrap-theme/stories/molecules/cards/cards.examples.stories.js index 6e26e221eb..36ab1b6916 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/cards/cards.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/cards/cards.examples.stories.js @@ -3,7 +3,6 @@ import React from "react"; import { defaultDecorator, htmlRootDecorator } from "../../../../../shared/components/Layout"; import cardsImage from "./cards-image.jpg"; import { horizontalCardsMap as horizontalCard } from "./cardVariations.js"; -import { rankingFunc as initRankFunc } from "./ranking-cards.js"; export default { title: "Molecules/Cards/Examples", @@ -1508,12 +1507,6 @@ export const RankingCardLarge = () => (
); -RankingCardLarge.parameters = { - initFunc: { - code: initRankFunc, - disable: false, - }, -} RankingCardLarge.decorators = [ defaultDecorator ]; export const RankingCardSmall = () => ( @@ -1582,10 +1575,4 @@ export const RankingCardSmall = () => ( ); -RankingCardSmall.parameters = { - initFunc: { - code: initRankFunc, - disable: false, - }, -} RankingCardSmall.decorators = [ defaultDecorator ]; diff --git a/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.templates.stories.js index 90743c6124..b80e150c45 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.templates.stories.js @@ -1,16 +1,11 @@ import React from "react"; import { defaultDecorator } from "../../../../../shared/components/Layout"; -import { initChart } from "./charts-and-graphs"; export default { title: "Molecules/Charts And Graphs/Templates", decorators: [ defaultDecorator ], parameters: { - initFunc: { - code: initChart, - disable: false, - }, controls: { disable: true } }, }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/cookie-consent/cookie-consent-full-screen.stories.js b/packages/unity-bootstrap-theme/stories/molecules/cookie-consent/cookie-consent-full-screen.stories.js index 6af8fd3a30..cca5da4139 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/cookie-consent/cookie-consent-full-screen.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/cookie-consent/cookie-consent-full-screen.stories.js @@ -1,11 +1,9 @@ import React, { useEffect } from "react"; -import { forceReloadOfStory } from "../../../.storybook/decorators"; import { allCookieConsentJS } from "../../../src/js/cookie-consent-full-screen"; import "../../../src/css/cookie-consent-full-screen.css"; export default { title: "Molecules/Cookie Consent", - decorators: [forceReloadOfStory], parameters: { controls: { disable: true } }, }; export const FullScreenBannerCookieConsent = () => { diff --git a/packages/unity-bootstrap-theme/stories/molecules/cookie-consent/cookie-consent.stories.js b/packages/unity-bootstrap-theme/stories/molecules/cookie-consent/cookie-consent.stories.js index a41fbb788c..3ee99bb9d4 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/cookie-consent/cookie-consent.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/cookie-consent/cookie-consent.stories.js @@ -1,11 +1,10 @@ import React, { useEffect } from "react"; import { allCookieConsentJS } from "../../../src/js/cookie-consent"; -import { forceReloadOfStory } from "../../../.storybook/decorators"; + import "../../../src/css/cookie-consent.css"; export default { title: "Molecules/Cookie Consent", - decorators: [forceReloadOfStory], parameters: { controls: { disable: true } }, }; export const MaxWidthCookieConsent = () => { diff --git a/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes.examples.stories.js b/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes.examples.stories.js index 2c4352b8b5..32e5f28adf 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes.examples.stories.js @@ -3,7 +3,6 @@ import React from "react"; import { fullLayoutDecorator } from "../../../../../shared/components/Layout.js"; import stockVideo from "../../atoms/video/stock-video-person-drawing.mp4"; import cardsImage from "../cards/cards-image.jpg"; -import { initVideo as initFunc } from "./heroes-video"; export default { title: "Molecules/Heroes/Examples", @@ -242,10 +241,3 @@ export const HeroVideo = () => ( ); -HeroVideo.parameters = { - initFunc: { - code: initFunc, - disable: false, - }, -}; - diff --git a/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.examples.stories.js b/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.examples.stories.js index 34432827f3..78f5578371 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.examples.stories.js @@ -2,16 +2,11 @@ import React from "react"; import { imageName } from "../../../../../shared/assets"; import { defaultDecorator } from "../../../../../shared/components/Layout"; -import { initImageParallax as initFunc } from "./image-parallax"; export default { title: "Molecules/Image Parallax/Examples", decorators: [ defaultDecorator ], parameters: { - initFunc: { - code: initFunc, - disable: false, - }, controls: { disable: true } } }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.templates.stories.js index 3509c381f6..dcc1f82c99 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.templates.stories.js @@ -15,8 +15,6 @@ const extraOptions = { }, }; -import { initTabs as initFunc } from "./tabbed-panels.js"; - export const TabbedPanels = (args) => { return (
@@ -251,12 +249,6 @@ export const TabbedPanels = (args) => { ); } -TabbedPanels.parameters = { - initFunc: { - disable: false, - code: initFunc - } -} export default { title: "Molecules/Tabbed Panels", component: TabbedPanels, diff --git a/packages/unity-bootstrap-theme/stories/molecules/tables/tables.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/tables/tables.templates.stories.js index f11a4e1f85..1d721cf552 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/tables/tables.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/tables/tables.templates.stories.js @@ -1,7 +1,6 @@ import React from "react"; import { defaultDecorator } from "../../../../../shared/components/Layout"; -import {initializeFixedTable as initFunc} from "./tables"; export default { title: "Molecules/Tables/Templates", @@ -19,12 +18,6 @@ export default { fixed: false, columns: 5, }, - parameters: { - initFunc: { - code: initFunc, - disable: false, - }, - } }; const makingUpFakeNumbers = (a,b,c) => Math.round(a*(b+c)).toLocaleString('en-US'); diff --git a/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.examples.stories.js b/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.examples.stories.js index 0bbd3efa33..0365865bda 100644 --- a/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.examples.stories.js @@ -1,5 +1,4 @@ import { htmlRootDecorator } from "../../../../../shared/components/Layout.js"; -import { initFooterGA as initFunc } from "./global-footer"; import { GlobalElementsOnly, ZeroColumns, @@ -19,10 +18,6 @@ export default { footer: { disable: true }, - initFunc: { - disable: false, - code: initFunc - }, controls: { disable: true } }, decorators: [htmlRootDecorator] From 4fc88b8dd7cf4eac5b643d0fb12a3abb101fbdfe Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:33:20 -0700 Subject: [PATCH 03/14] storybook config changes --- .../.storybook/decorators.jsx | 37 +++-- .../.storybook/eventSpy.js | 13 ++ .../.storybook/preview.js | 12 +- .../withDataLayerListener.js | 2 +- .../.storybook-configv8/preset/preview.js | 5 - .../.storybook/decorators.tsx | 140 +++++++++++------- .../unity-react-core/.storybook/eventSpy.js | 13 ++ .../unity-react-core/.storybook/preview.jsx | 8 +- 8 files changed, 154 insertions(+), 76 deletions(-) create mode 100644 packages/unity-bootstrap-theme/.storybook/eventSpy.js create mode 100644 packages/unity-react-core/.storybook/eventSpy.js diff --git a/packages/unity-bootstrap-theme/.storybook/decorators.jsx b/packages/unity-bootstrap-theme/.storybook/decorators.jsx index f5e632a20a..5ec5eab362 100644 --- a/packages/unity-bootstrap-theme/.storybook/decorators.jsx +++ b/packages/unity-bootstrap-theme/.storybook/decorators.jsx @@ -1,15 +1,32 @@ -import React, { useEffect } from "react"; +import { useEffect } from "react"; + +export const windowLoadEvent = (storyFn) => { + const mount = () => { + // console.log("sb mounting"); + + // custom events created by eventSpy.js to allow storybook to dispatch load events after the page is loaded + document.dispatchEvent(new Event("sb_DOMContentLoaded")); + window.dispatchEvent(new Event('sb_load')); + } + + const unmount = () => { + // console.log("sb unmounting"); + + // bootstrap script has functionality initiated with window load event, + // so we need to reload the page every time we unmount the story. + // We set the opacity to 0 to avoid flickering. + document.body.style.opacity = "0"; + + // variable to prevent calling mount function before the page is reloaded + window.unloading = true; + window.location.reload(); + } -export const forceReloadOfStory = (storyFn, context) => { useEffect(() => { - setTimeout(() => { - context.globals.shouldReload = true; - }, 100); - return () => { - if (context.globals.shouldReload) { - window.location.reload(); - } - }; + if (!window.unloading) { + mount() + } + return unmount }, []); return storyFn(); diff --git a/packages/unity-bootstrap-theme/.storybook/eventSpy.js b/packages/unity-bootstrap-theme/.storybook/eventSpy.js new file mode 100644 index 0000000000..1c85cfa49f --- /dev/null +++ b/packages/unity-bootstrap-theme/.storybook/eventSpy.js @@ -0,0 +1,13 @@ +var originalAddEventListener = EventTarget.prototype.addEventListener; +EventTarget.prototype.addEventListener = function (type, listener, options) { + if(listener.uidEvent && (type === "load" || type === "DOMContentLoaded")) { + /** + * Used by storybook windowLoadEvent decorator + * creates custom events sb_load and sb_DOMContentLoaded + * to allow storybook to dispatch load events after the page is loaded + * */ + originalAddEventListener.call(this, `sb_${type}`, listener, options); + } + + originalAddEventListener.call(this, type, listener, options); +}; diff --git a/packages/unity-bootstrap-theme/.storybook/preview.js b/packages/unity-bootstrap-theme/.storybook/preview.js index 121823f1b0..05796d5bd0 100644 --- a/packages/unity-bootstrap-theme/.storybook/preview.js +++ b/packages/unity-bootstrap-theme/.storybook/preview.js @@ -1,8 +1,13 @@ +import "./eventSpy.js"; import "../src/scss/unity-bootstrap-theme.bundle.scss"; +import { default as bootstrap } from "bootstrap/js/index.umd.js"; +globalThis.bootstrap = bootstrap; +import { default as udsBootstrap } from "@asu/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js"; +globalThis.udsBootstrap = udsBootstrap; + import { removeFontAwesomeChanges } from "./local-addon/helpers"; -// Import all the Bootstrap bundle -import "../../../node_modules/bootstrap/dist/js/bootstrap.bundle.min"; +import { windowLoadEvent } from "./decorators.jsx"; const parameters = { options: { @@ -58,7 +63,8 @@ const parameters = { /** @type { import('@storybook/react').Preview } */ const preview = { - parameters + parameters, + decorators: [windowLoadEvent], }; export default preview; diff --git a/packages/unity-react-core/.storybook-configv8/dataLayerListener/withDataLayerListener.js b/packages/unity-react-core/.storybook-configv8/dataLayerListener/withDataLayerListener.js index 2e444dd022..a4f927dcac 100644 --- a/packages/unity-react-core/.storybook-configv8/dataLayerListener/withDataLayerListener.js +++ b/packages/unity-react-core/.storybook-configv8/dataLayerListener/withDataLayerListener.js @@ -10,7 +10,7 @@ export const withDataLayerListener = makeDecorator({ function removeDOMObjects(eventObject){ return Object.entries(eventObject).reduce((acc, [k, v])=>{ - acc[k] = (typeof v === "object" && v.tagName) ? v.tagName : v; + acc[k] = (typeof v === "object" && v?.tagName) ? v.tagName : v; return acc },{}) } diff --git a/packages/unity-react-core/.storybook-configv8/preset/preview.js b/packages/unity-react-core/.storybook-configv8/preset/preview.js index 66dbb9f41b..ddac55b8ac 100644 --- a/packages/unity-react-core/.storybook-configv8/preset/preview.js +++ b/packages/unity-react-core/.storybook-configv8/preset/preview.js @@ -2,10 +2,6 @@ import { withColumns } from '../withColumns'; import { customViewports } from '../viewports'; -export const globals = { - columns: false, -}; - export const initialGlobals = { columns: false, }; @@ -23,7 +19,6 @@ export const decorators = [ /** @type { import('@storybook/react').Preview } */ const preview = { - globals, initialGlobals, parameters, decorators, diff --git a/packages/unity-react-core/.storybook/decorators.tsx b/packages/unity-react-core/.storybook/decorators.tsx index 3b23852304..bd4c65f287 100644 --- a/packages/unity-react-core/.storybook/decorators.tsx +++ b/packages/unity-react-core/.storybook/decorators.tsx @@ -1,48 +1,34 @@ /** * This file houses all non-addon related decorators */ -import { renderToStaticMarkup } from "react-dom/server"; import { Decorator } from "@storybook/react"; -import React, { useLayoutEffect, StrictMode } from "react"; +import React, { forwardRef, ReactNode, StrictMode, useEffect } from "react"; import { getBootstrapHTML } from "../src/components/GaEventWrapper/useBaseSpecificFramework"; import { useChannel } from "@storybook/preview-api"; -declare global { - interface Window { - initDataLayer: () => void; - } +type ContainerComponent = React.ForwardRefExoticComponent>; + +declare interface ContainerProps { + children?: ReactNode; + dangerouslySetInnerHTML?: { + __html: string; + }; } -const Full = ({ children, rootRef }) => ( -
- {children} -
-); +const Full:ContainerComponent = forwardRef((props, ref) => { + return ( +
+)}); -const UdsContainer = ({ children, rootRef }) => ( +const UdsContainer:ContainerComponent = forwardRef((props, ref) => { + return (
-
- {children} -
+
-); - -const StaticStory = ({ args, Container, children, rootRef }) => { - useLayoutEffect(() => { - /** - * Storybook only useId() will prefix the id with this identifier allowing - * us to identify when the output is meant for bootstrap (non react) - */ - const code = getBootstrapHTML(children); - rootRef.current.innerHTML = code; - - window.initDataLayer(); - }, [args]); - return ; -}; +)}); export const withContainer: Decorator = ( StoryFn, @@ -52,39 +38,83 @@ export const withContainer: Decorator = ( parameters: { layout = "fullscreen" }, } ) => { - const root = React.useRef(null); + const isBootstrap = framework === "bootstrap"; + const isReact = !isBootstrap; + const root = React.useRef(null as any); const emit = useChannel({ "HTML/CodeUpdated": () => {} }); + + + const mount = () => { + // console.log("sb mounting"); + + if (root.current) { + if (isBootstrap) { + // custom events created by eventSpy.js to allow storybook to dispatch load events after the page is loaded + document.dispatchEvent(new Event("sb_DOMContentLoaded")); + window.dispatchEvent(new Event('sb_load')); + } + + emit("HTML/CodeUpdated", { code: root.current.innerHTML }); + } + + } + + const unmount = () => { + // console.log("sb unmounting"); + if (isBootstrap) { + // bootstrap script has functionality initiated with window load event, + // so we need to reload the page every time we unmount the story. + // We set the opacity to 0 to avoid flickering. + document.body.style.opacity = "0"; + + // @ts-ignore + window.unloading = true; // variable to prevent calling mount function before the page is reloaded + + // adding this timeout allows controls time to update + setTimeout(()=>{window.location.reload()}, 100); + } + } + + + + + + + + + useEffect(() => { + // @ts-ignore + if (!window.unloading) { + mount() + } else { + + } + return unmount + }, [StoryFn, args, framework]); + let Container = Full; if (layout === "container") { Container = UdsContainer; } - let html = ""; - let WrappedStory: React.ReactNode; - if (framework === "bootstrap") { - html = getBootstrapHTML(); - WrappedStory = ( - - - - - - ); - } else { - html = renderToStaticMarkup(); - WrappedStory = ( - - - + + return ( + + { + isBootstrap + ? )}}/> + : + - - ); - } - // emit the html So Addon Panel can update - emit("HTML/CodeUpdated", { code: html }); - return WrappedStory; + } + + ); }; // ordered from innermost to outermost, be careful with the order! -export const globalDecorators = [withContainer]; +export const globalDecorators = [ + withContainer +]; + + diff --git a/packages/unity-react-core/.storybook/eventSpy.js b/packages/unity-react-core/.storybook/eventSpy.js new file mode 100644 index 0000000000..1c85cfa49f --- /dev/null +++ b/packages/unity-react-core/.storybook/eventSpy.js @@ -0,0 +1,13 @@ +var originalAddEventListener = EventTarget.prototype.addEventListener; +EventTarget.prototype.addEventListener = function (type, listener, options) { + if(listener.uidEvent && (type === "load" || type === "DOMContentLoaded")) { + /** + * Used by storybook windowLoadEvent decorator + * creates custom events sb_load and sb_DOMContentLoaded + * to allow storybook to dispatch load events after the page is loaded + * */ + originalAddEventListener.call(this, `sb_${type}`, listener, options); + } + + originalAddEventListener.call(this, type, listener, options); +}; diff --git a/packages/unity-react-core/.storybook/preview.jsx b/packages/unity-react-core/.storybook/preview.jsx index cedd5be456..893c937d86 100644 --- a/packages/unity-react-core/.storybook/preview.jsx +++ b/packages/unity-react-core/.storybook/preview.jsx @@ -1,8 +1,12 @@ +import "./eventSpy.js"; import "@asu/unity-bootstrap-theme/src/scss/unity-bootstrap-theme.bundle.scss"; -import "bootstrap/dist/js/bootstrap.bundle.min.js"; +import * as bootstrap from "bootstrap/dist/js/bootstrap.bundle.min.js"; +globalThis.bootstrap = bootstrap; + +import "@asu/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js"; import { globalDecorators } from "./decorators.tsx"; import { Container } from "./docPage.tsx"; -import "@asu/unity-bootstrap-theme/src/js/data-layer.js"; + const sourceCodeRootSelector = "#html-root"; From 21581b3f9030510be2069dabf7dc0e4b59450e85 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 10 Apr 2025 09:02:12 -0700 Subject: [PATCH 04/14] fix anchor menu --- .../anchor-menu.examples.stories.js | 204 +++++++++++++++--- .../src/components/AnchorMenu/AnchorMenu.jsx | 10 +- .../AnchorMenu/AnchorMenu.stories.jsx | 100 +++++---- 3 files changed, 248 insertions(+), 66 deletions(-) diff --git a/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.examples.stories.js b/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.examples.stories.js index c6956bd1ed..beff5b4fae 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.examples.stories.js @@ -1,33 +1,185 @@ import React from "react"; -import { defaultDecorator } from "../../../../../shared/components/Layout"; - +import { imageName } from "../../../../../shared/assets"; +import { htmlRootDecorator } from "../../../../../shared/components/Layout"; +import {getLoremSentences} from "../../../../../shared/constants/strings"; export default { title: "Atoms/Anchor Menu", - decorators: [ defaultDecorator ], - parameters: { - controls: { disable: true }, - docs: { - description: { - component: `This example has moved to unity-react-core. - -React components and HTML templates are now located in a shared space to ensure consistency between the React and Bootstrap usages. - `, - }, + parameters: { + header: { + forced: true, }, - } + controls: { disable: true }, + }, + decorators: [htmlRootDecorator], }; - - -export const AnchorMenu = { - render: () =>

- Follow the link to view the{" "} - - anchor menu - {" "} - example in @asu/unity-react-core. -

+let loremOffset = 0; +export const AnchorMenu = () => { + return ( + <> +
+
+ Sample placeholder image. +

+ Gettysburg Address +

+
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. +

+
+ +
+ +
+
+
+
+
+

{getLoremSentences(40, loremOffset++ * 3)}

+

{getLoremSentences(30, loremOffset++ * 3)}

+

{getLoremSentences(20, loremOffset++ * 3)}

+

{getLoremSentences(40, loremOffset++ * 3)}

+
+
+

first

+

First. {getLoremSentences(40, loremOffset++ * 3)}

+

First. {getLoremSentences(50, loremOffset++ * 3)}

+

First. {getLoremSentences(10, loremOffset++ * 3)}

+
+
+

second

+

Second. {getLoremSentences(20, loremOffset++ * 3)}

+

Second. {getLoremSentences(50, loremOffset++ * 3)}

+

Second. {getLoremSentences(60, loremOffset++ * 3)}

+
+
+

third

+

Third. {getLoremSentences(20, loremOffset++ * 3)}

+

Third. {getLoremSentences(10, loremOffset++ * 3)}

+

Third. {getLoremSentences(40, loremOffset++ * 3)}

+

Third. {getLoremSentences(10, loremOffset++ * 3)}

+
+
+

fourth

+

Fourth. {getLoremSentences(70, loremOffset++ * 3)}

+

Fourth. {getLoremSentences(40, loremOffset++ * 3)}

+
+
+

fifth

+

Fifth. {getLoremSentences(40, loremOffset++ * 3)}

+

Fifth. {getLoremSentences(10, loremOffset++ * 3)}

+

Fifth. {getLoremSentences(30, loremOffset++ * 3)}

+

Fifth. {getLoremSentences(20, loremOffset++ * 3)}

+
+
+
+
+
+
+ + ); }; diff --git a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.jsx b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.jsx index 35a0214b7c..b2e9dddda6 100644 --- a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.jsx +++ b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.jsx @@ -20,6 +20,7 @@ import { import { Button } from "../Button/Button"; import { GaEventWrapper } from "../GaEventWrapper/GaEventWrapper"; import { AnchorMenuWrapper } from "./AnchorMenu.styles"; +import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework"; const menuTitle = "On This Page"; @@ -43,6 +44,9 @@ export const AnchorMenu = ({ firstElementId, focusFirstFocusableElement = false, }) => { + + const { isReact, isBootstrap } = useBaseSpecificFramework(); + const anchorMenuRef = useRef(null); const isSmallDevice = useMediaQuery("(max-width: 991px)"); const [state, setState] = useState({ @@ -190,6 +194,7 @@ export const AnchorMenu = ({ // @ts-ignore requiresAltMenuSpacing={state.hasAltMenuSpacing} ref={anchorMenuRef} + id="uds-anchor-menu" className={classNames( "uds-anchor-menu", "uds-anchor-menu-expanded-lg", @@ -252,7 +257,10 @@ export const AnchorMenu = ({ ariaLabel={item.text} label={item.text} icon={item.icon} - onClick={() => handleClickLink(item.targetIdName)} + onClick={ + isReact && (() => handleClickLink(item.targetIdName)) + } + href={isBootstrap && `#${item.targetIdName}`} /> ))} diff --git a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx index dfc7fbb832..2c6c397dd2 100644 --- a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx +++ b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx @@ -2,19 +2,21 @@ import classNames from "classnames"; import React from "react"; +import { + getLoremSentences, + titleCaseDefinition, +} from "../../../../../shared/constants/strings"; import { Divider } from "../Divider/Divider"; import { AnchorMenu } from "./AnchorMenu"; -import { getLoremSentences, titleCaseDefinition } from "../../../../../shared/constants/strings"; +import { Basic as Header } from "../../../../unity-bootstrap-theme/stories/organisms/global-header/global-header.templates.jsx"; +import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework.js"; -const titleCaseTitle = "Anchor Menus Should Always be Formatted with Title Case"; +const titleCaseTitle = + "Anchor Menus Should Always be Formatted with Title Case"; export default { title: "Components/AnchorMenu", component: AnchorMenu, excludeStories: ["Containers"], - globals: { - framework: "react", - }, - tags: ["!bootstrap"], parameters: { docs: { description: { @@ -54,46 +56,66 @@ const items = [ export const Containers = () => { return ( <> - {items && items.map((item, index) => { - const lastStyle = (index === items.length - 1) ? {marginBottom: "100vh"} : undefined; - return ( -
-

{item.text}

- {/* use titleCaseDefinition for the first item */} - { (index === 0) && - <> -

{titleCaseTitle}

+ {items && + items.map((item, index) => { + const lastStyle = + index === items.length - 1 ? { marginBottom: "100vh" } : undefined; + return ( +
+

{item.text}

+ {/* use titleCaseDefinition for the first item */} + {index === 0 && ( + <> +

{titleCaseTitle}

+

+ Definition: + {titleCaseDefinition} +

+ + + )}

- Definition: { titleCaseDefinition } + { + getLoremSentences( + 40, + index * 3 + ) /* 40 sentences, index * 3 offset just creates some variety */ + }

- - - } -

- {getLoremSentences(40, index * 3) /* 40 sentences, index * 3 offset just creates some variety */} -

-
- ); - })} +
+ ); + })} ); }; -const Template = args => ( -
-
-
- {/* Component */} - - {/* Demostration purposes containers */} - +const Template = args => { + const { isBootstrap } = useBaseSpecificFramework(); + + return ( + <> + {/* Bootstrap version of anchor menu depends on the header component */} + {isBootstrap &&
} + +
+
+
+ {/* Component */} + + {/* Demostration purposes containers */} + +
+
-
-
-); + + ); +}; export const Default = Template.bind({}); Default.args = { From 5ee8a4224ce3a6b807754bc61708692e54edd5e2 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 10 Apr 2025 09:05:34 -0700 Subject: [PATCH 05/14] enable bootstrap --- .../src/components/Modal/Modal.stories.tsx | 5 +- .../src/components/Modal/Modal.tsx | 77 +++++++++------- .../components/TabbedPanels/TabbedPanels.jsx | 89 ++++++++++++------- .../TabbedPanels/TabbedPanels.stories.jsx | 4 - .../TabbedPanels/components/NavControls.jsx | 10 ++- .../TabbedPanels/components/TabHeader.jsx | 7 +- .../src/components/Tables/Tables.stories.tsx | 4 - 7 files changed, 113 insertions(+), 83 deletions(-) diff --git a/packages/unity-react-core/src/components/Modal/Modal.stories.tsx b/packages/unity-react-core/src/components/Modal/Modal.stories.tsx index f321fd6309..ce72416743 100644 --- a/packages/unity-react-core/src/components/Modal/Modal.stories.tsx +++ b/packages/unity-react-core/src/components/Modal/Modal.stories.tsx @@ -4,10 +4,9 @@ import { Modal } from "./Modal"; export default { title: "Components/Modal", component: Modal, - globals: { - framework: "react", + args: { + open: false, }, - tags: ["!bootstrap"], }; const modalTemplate = args => ; diff --git a/packages/unity-react-core/src/components/Modal/Modal.tsx b/packages/unity-react-core/src/components/Modal/Modal.tsx index dd0d7f95d9..cf043a551d 100644 --- a/packages/unity-react-core/src/components/Modal/Modal.tsx +++ b/packages/unity-react-core/src/components/Modal/Modal.tsx @@ -2,6 +2,8 @@ import React, { useEffect } from "react"; import { ButtonIconOnly } from "../ButtonIconOnly/ButtonIconOnly"; import { GaEventWrapper } from "../GaEventWrapper/GaEventWrapper"; +import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework"; +import classNames from "classnames"; /** * * TODO: Should we be using bootstrap's built in modal functionality? @@ -18,6 +20,7 @@ const defaultGaData = { }; export interface ModalProps { + open?: boolean; gaData?: { name: string; event: string; @@ -29,51 +32,59 @@ export interface ModalProps { }; } -export const Modal: React.FC = ({ gaData }) => { - useEffect(() => { - document - ?.getElementById("openModalButton") - .addEventListener("click", function () { - document.getElementById("uds-modal").classList.add("open"); - }); +export const Modal: React.FC = ({ open, gaData }) => { + const { isReact, isBootstrap } = useBaseSpecificFramework(); + const [openState, setOpen] = React.useState(open); - document - ?.getElementById("closeModalButton") - .addEventListener("click", function () { - document.getElementById("uds-modal").classList.remove("open"); - }); - }); + const handleOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; return (
-
-
- - - -

Content

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do - eiusmod incididuntåç ut labore et dolore magna aliqua eiusmod tempo. -

- + {(openState || isBootstrap) && ( +
+
+ + + +

Content

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod incididuntåç ut labore et dolore magna aliqua eiusmod + tempo. +

+ +
-
+ )}
); }; diff --git a/packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.jsx b/packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.jsx index c28dd57118..ffa010c883 100644 --- a/packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.jsx +++ b/packages/unity-react-core/src/components/TabbedPanels/TabbedPanels.jsx @@ -10,6 +10,7 @@ import PropTypes from "prop-types"; import React, { useState, useEffect, useRef, useCallback } from "react"; +import { throttle, debounce } from "../../../../../shared"; import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework"; import { NavControls, TabHeader } from "./components"; @@ -26,19 +27,23 @@ function useRefs() { return [refs, register]; } -const Tab = ({ id, bgColor, selected, children }) => - selected && ( -
- {children} -
+const Tab = ({ id, bgColor, selected, children }) => { + const { isBootstrap } = useBaseSpecificFramework(); + return ( + (selected || isBootstrap) && ( +
+ {children} +
+ ) ); +}; Tab.propTypes = { id: PropTypes.string.isRequired, @@ -54,13 +59,15 @@ const TabbedPanels = ({ onTabChange = _ => {}, }) => { const childrenArray = React.Children.toArray(children); + if (childrenArray.length === 0) { + return null; + } const isMounted = useRef(false); const [activeTabID, setActiveTabID] = useState( initialTab && initialTab !== "null" ? initialTab : childrenArray[0].props.id ); const headerTabs = useRef(null); const [headerTabItems, setHeaderTabItems] = useRefs(); - const { isReact, isBootstrap } = useBaseSpecificFramework(); const updateActiveTabID = tab => { onTabChange(tab); @@ -72,31 +79,47 @@ const TabbedPanels = ({ const [scrollLeft, setScrollLeft] = useState(0); const [scrollableWidth, setScrollableWidth] = useState(); + const handleResize = () => { + setScrollableWidth( + headerTabs.current?.scrollWidth - headerTabs.current?.offsetWidth + ); + }; + + const handleScroll = () => { + setScrollLeft(headerTabs.current?.scrollLeft); + }; + + const throttleScroll = () => { + const timeout = 150; + // prevent function from being called excessively + throttle(handleScroll, timeout); + // ensure function executes after scrolling stops + debounce(handleScroll, timeout); + }; + + const throttleResize = () => { + const timeout = 150; + // prevent function from being called excessively + throttle(handleResize, timeout); + // ensure function executes after scrolling stops + debounce(handleResize, timeout); + }; + useEffect(() => { - const onScroll = () => { - setScrollLeft(headerTabs.current.scrollLeft); - }; - headerTabs.current.addEventListener("scroll", onScroll); - onScroll(); + headerTabs.current.addEventListener("scroll", throttleScroll); + handleScroll(); return () => { if (headerTabs.current) { - headerTabs.current.removeEventListener("scroll", onScroll); + headerTabs.current.removeEventListener("scroll", throttleScroll); } }; }, [scrollableWidth]); useEffect(() => { - const onResize = () => { - setScrollableWidth( - headerTabs.current.scrollWidth - headerTabs.current.offsetWidth - ); - }; - window.addEventListener("resize", onResize); - onResize(); + window.addEventListener("resize", throttleResize); + handleResize(); return () => { - if (headerTabs.current) { - window.removeEventListener("resize", onResize); - } + window.removeEventListener("resize", throttleResize); }; }, []); @@ -190,10 +213,10 @@ const TabbedPanels = ({ title={child.props.title} selected={activeTabID === child.props.id} gaData={trackLinkEvent} - selectTab={isReact && switchToTab} + selectTab={switchToTab} key={child.props.id} - leftKeyPressed={isReact && (() => incrementIndex(false))} - rightKeyPressed={isReact && (() => incrementIndex())} + leftKeyPressed={() => incrementIndex(false)} + rightKeyPressed={() => incrementIndex()} icon={child.props.icon} index={index} /> @@ -205,7 +228,7 @@ const TabbedPanels = ({ hidePrev={scrollLeft <= 0} hideNext={scrollLeft >= scrollableWidth} gaData={trackArrowsEvent} - slideNav={isReact && slideNav} + slideNav={slideNav} />
{ diff --git a/packages/unity-react-core/src/components/TabbedPanels/components/NavControls.jsx b/packages/unity-react-core/src/components/TabbedPanels/components/NavControls.jsx index d18eabe0da..4eec29bbfc 100644 --- a/packages/unity-react-core/src/components/TabbedPanels/components/NavControls.jsx +++ b/packages/unity-react-core/src/components/TabbedPanels/components/NavControls.jsx @@ -3,6 +3,7 @@ import React from "react"; import { GaEventWrapper } from "../../GaEventWrapper/GaEventWrapper"; import { NavControlButtons } from "./NavControls.styles"; +import { useBaseSpecificFramework } from "../../GaEventWrapper/useBaseSpecificFramework"; /** * @typedef {Object} NavControlsProps @@ -12,14 +13,15 @@ import { NavControlButtons } from "./NavControls.styles"; * @property {() => void} slideNav */ const NavControls = ({ gaData, hidePrev, hideNext, slideNav }) => { + const { isReact, isBootstrap } = useBaseSpecificFramework(); return ( - {!hidePrev && ( + {(!hidePrev || isBootstrap) && ( )} - {!hideNext && ( + {(!hideNext || isBootstrap) && (
), ], - globals: { - framework: "react", - }, - tags: ["!bootstrap"], }; export const BasicTable: StoryObj = { From 7580ecc2a491b76cd1852c81fb87ae657724bd13 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 10 Apr 2025 09:06:30 -0700 Subject: [PATCH 06/14] remove defautProps warning --- .../src/components/Article/Article.jsx | 22 +--- .../src/components/Button/Button.jsx | 29 +---- .../ButtonIconOnly/ButtonIconOnly.jsx | 21 +--- .../src/components/ButtonTag/ButtonTag.jsx | 18 +-- .../src/components/Card/Card.jsx | 118 +++++------------- .../Pagination/PageItem/PageItem.jsx | 18 +-- .../src/components/Pagination/Pagination.jsx | 9 +- 7 files changed, 62 insertions(+), 173 deletions(-) diff --git a/packages/unity-react-core/src/components/Article/Article.jsx b/packages/unity-react-core/src/components/Article/Article.jsx index 48fc2bf8eb..ebfd0c07ea 100644 --- a/packages/unity-react-core/src/components/Article/Article.jsx +++ b/packages/unity-react-core/src/components/Article/Article.jsx @@ -27,7 +27,7 @@ import { Wrapper, EventInfoWrapper } from "./Article.styles"; * @returns {JSX.Element} */ export const Article = ({ - type, + type = "news", articleUrl, publicationDate, title, @@ -192,7 +192,11 @@ export const Article = ({ data-testid="uds-hero" className="uds-hero uds-hero-md" style={{ - backgroundImage: `linear-gradient(180deg, #19191900 0%, #191919c9 100%), url(${headerImageUrl})`, + // @ts-ignore + "--color1": "#19191900", + "--color2": "#191919c9", + // moved colors to variable because hex color in linear-gradient breaks react + "backgroundImage": `linear-gradient(180deg, var(--color1) 0%, var(--color2) 100%), url(${headerImageUrl})`, }} /> )} @@ -369,17 +373,3 @@ Article.propTypes = { */ zoomUrl: PropTypes.string, }; - -Article.defaultProps = { - type: "news", - authorEmail: undefined, - authorPhone: undefined, - authorTitle: undefined, - breadcrumbs: undefined, - calendarUrl: undefined, - headerImageUrl: undefined, - eventLocation: undefined, - eventTime: undefined, - registrationUrl: undefined, - zoomUrl: undefined, -}; diff --git a/packages/unity-react-core/src/components/Button/Button.jsx b/packages/unity-react-core/src/components/Button/Button.jsx index 2f80471f9b..ad044ff7dd 100644 --- a/packages/unity-react-core/src/components/Button/Button.jsx +++ b/packages/unity-react-core/src/components/Button/Button.jsx @@ -24,21 +24,21 @@ const gaDefaultObject = { * @returns {JSX.Element} */ export const Button = ({ - label, - cardTitle, + label = "", + cardTitle = "", gaData, ariaLabel, block, - color, + color = "gray", disabled, - element, + element = "button", href, icon, innerRef, onClick, - size, + size = "default", classes, - target, + target = "_self", ...props }) => { const btnClasses = classNames("btn", { @@ -164,20 +164,3 @@ Button.propTypes = { */ target: PropTypes.oneOf(["_blank", "_self", "_top", "_parent"]), }; - -Button.defaultProps = { - label: "", - cardTitle: "", - ariaLabel: undefined, - block: undefined, - color: "gray", - disabled: undefined, - element: "button", - href: undefined, - icon: undefined, - innerRef: undefined, - onClick: undefined, - size: "default", - classes: undefined, - target: "_self", -}; diff --git a/packages/unity-react-core/src/components/ButtonIconOnly/ButtonIconOnly.jsx b/packages/unity-react-core/src/components/ButtonIconOnly/ButtonIconOnly.jsx index fe6829256c..c5fb46f526 100644 --- a/packages/unity-react-core/src/components/ButtonIconOnly/ButtonIconOnly.jsx +++ b/packages/unity-react-core/src/components/ButtonIconOnly/ButtonIconOnly.jsx @@ -22,12 +22,12 @@ const gaDefaultObject = { * @returns {JSX.Element} */ export const ButtonIconOnly = ({ - color, - icon, - innerRef, - onClick, - size, - cardTitle, + color = "gray", + icon = undefined, + innerRef = undefined, + onClick = undefined, + size = "small", + cardTitle = "", className, gaData, ...rest @@ -99,12 +99,3 @@ ButtonIconOnly.propTypes = { size: PropTypes.oneOf(["large", "small"]), className: PropTypes.string, }; - -ButtonIconOnly.defaultProps = { - color: "gray", - icon: undefined, - innerRef: undefined, - onClick: undefined, - size: "small", - cardTitle: "", -}; diff --git a/packages/unity-react-core/src/components/ButtonTag/ButtonTag.jsx b/packages/unity-react-core/src/components/ButtonTag/ButtonTag.jsx index e456cb7ef3..c60e0c1678 100644 --- a/packages/unity-react-core/src/components/ButtonTag/ButtonTag.jsx +++ b/packages/unity-react-core/src/components/ButtonTag/ButtonTag.jsx @@ -24,11 +24,11 @@ const gaDefaultObject = { * @returns {JSX.Element} */ export const ButtonTag = ({ - label, - cardTitle, + label = "", + cardTitle = "", gaData, ariaLabel, - color, + color = "gray", disabled, element = "button", innerRef, @@ -137,15 +137,3 @@ ButtonTag.propTypes = { */ onClick: PropTypes.func, }; - -ButtonTag.defaultProps = { - label: "", - cardTitle: "", - ariaLabel: undefined, - color: "gray", - disabled: undefined, - element: "button", - href: undefined, - innerRef: undefined, - onClick: undefined, -}; diff --git a/packages/unity-react-core/src/components/Card/Card.jsx b/packages/unity-react-core/src/components/Card/Card.jsx index fbdb40470e..7dc9f2c84a 100644 --- a/packages/unity-react-core/src/components/Card/Card.jsx +++ b/packages/unity-react-core/src/components/Card/Card.jsx @@ -29,22 +29,22 @@ const gaDefaultObject = { * @returns {JSX.Element} */ export const Card = ({ - type, - width, - horizontal, + type = "default", + width = "100%", + horizontal = false, image, imageAltText, title, icon, body, - eventFormat, + eventFormat = "stack", eventLocation, eventTime, buttons, linkLabel, linkUrl, tags, - showBorders, + showBorders = true, cardLink, }) => { return ( @@ -154,44 +154,26 @@ Card.propTypes = { cardLink: PropTypes.string, }; -Card.defaultProps = { - type: "default", - width: "100%", - horizontal: false, - body: undefined, - eventFormat: "stack", - eventTime: undefined, - eventLocation: undefined, - icon: undefined, - image: undefined, - imageAltText: undefined, - buttons: undefined, - linkLabel: undefined, - linkUrl: undefined, - tags: undefined, - showBorders: true, -}; - /* * Sub-components defined after this */ const BaseCard = ({ - type, - width, - horizontal, - image, - imageAltText, + type = "default", + width = "100%", + horizontal = false, + image = "", + imageAltText = "", title, - icon, - body, - eventFormat, - eventLocation, - eventTime, - buttons, - linkLabel, - linkUrl, - tags, - showBorders, + icon = undefined, + body = "", + eventFormat = "stack", + eventLocation = "", + eventTime = "", + buttons = undefined, + linkLabel = undefined, + linkUrl = undefined, + tags = undefined, + showBorders = true, cardLink, }) => { const cardClass = classNames("card", "cards-components", { @@ -297,35 +279,17 @@ BaseCard.propTypes = { cardLink: PropTypes.string, }; -BaseCard.defaultProps = { - type: "default", - width: "100%", - horizontal: false, - body: "", - eventFormat: "stack", - eventTime: "", - eventLocation: "", - icon: undefined, - image: "", - imageAltText: "", - buttons: undefined, - linkLabel: undefined, - linkUrl: undefined, - tags: undefined, - showBorders: true, -}; - const CardContent = ({ - type, - body, - eventFormat, - eventLocation, - eventTime, + type = "default", + body = "", + eventFormat = "stack", + eventLocation = "", + eventTime = "", title, - buttons, - linkLabel, - linkUrl, - tags, + buttons = undefined, + linkLabel = undefined, + linkUrl = undefined, + tags = undefined, cardLink, }) => ( <> @@ -438,19 +402,11 @@ CardContent.propTypes = { cardLink: PropTypes.string, }; -CardContent.defaultProps = { - type: "default", - body: "", - eventFormat: "stack", - eventLocation: "", - eventTime: "", - buttons: undefined, - linkLabel: undefined, - linkUrl: undefined, - tags: undefined, -}; - -const EventInfo = ({ eventFormat, eventTime, eventLocation }) => { +const EventInfo = ({ + eventFormat = "stack", + eventLocation = "", + eventTime = "", +}) => { if (eventFormat === "inline") { return (
@@ -516,9 +472,3 @@ EventInfo.propTypes = { eventLocation: PropTypes.string, eventTime: PropTypes.string, }; - -EventInfo.defaultProps = { - eventFormat: "stack", - eventLocation: "", - eventTime: "", -}; diff --git a/packages/unity-react-core/src/components/Pagination/PageItem/PageItem.jsx b/packages/unity-react-core/src/components/Pagination/PageItem/PageItem.jsx index 026b248efb..918b3948c5 100644 --- a/packages/unity-react-core/src/components/Pagination/PageItem/PageItem.jsx +++ b/packages/unity-react-core/src/components/Pagination/PageItem/PageItem.jsx @@ -14,11 +14,11 @@ import React from "react"; */ export const PageItem = ({ dataId, - isClickeable, - disabled, - pageLinkIcon, - selectedPage, - onClick, + isClickeable = false, + disabled = false, + pageLinkIcon = false, + selectedPage = false, + onClick = () => {}, ellipses, ariaLabel, children, @@ -69,11 +69,3 @@ PageItem.propTypes = { ariaLabel: PropTypes.string, ariaDisabled: PropTypes.bool, }; - -PageItem.defaultProps = { - isClickeable: false, - disabled: false, - pageLinkIcon: false, - selectedPage: false, - onClick: () => {}, -}; diff --git a/packages/unity-react-core/src/components/Pagination/Pagination.jsx b/packages/unity-react-core/src/components/Pagination/Pagination.jsx index 8574f174fa..1412c7a5e1 100644 --- a/packages/unity-react-core/src/components/Pagination/Pagination.jsx +++ b/packages/unity-react-core/src/components/Pagination/Pagination.jsx @@ -33,8 +33,8 @@ const defaultGAEvent = { export const Pagination = ({ type, background, - currentPage, - totalPages, + currentPage = 1, + totalPages = 10, onChange, }) => { const [selectedPage, setSelectedPage] = useState(null); @@ -230,8 +230,3 @@ Pagination.propTypes = { */ onChange: PropTypes.func.isRequired, }; - -Pagination.defaultProps = { - currentPage: 1, - totalPages: 10, -}; From 804ce9acc756acb6031012b9cf9b6fb2aeb5a2ff Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 10 Apr 2025 12:09:16 -0700 Subject: [PATCH 07/14] fix(unity-bootstrap-theme): update build to include js --- packages/unity-bootstrap-theme/jsconfig.json | 22 ++ packages/unity-bootstrap-theme/package.json | 12 +- .../unity-bootstrap-theme/src/js/banner.js | 91 +++++++- .../src/js/bootstrap-helper.js | 15 +- .../src/js/charts-and-graphs.js | 11 +- .../src/js/data-layer.js | 25 ++- .../src/js/global-header.js | 10 +- .../src/js/storybook-data-layer.js | 5 - .../src/js/storybook-global-header.js | 5 - .../src/js/tabbed-panels.js | 209 ++++++++---------- .../src/js/unity-bootstrap-theme.js | 1 - .../scss/unity-bootstrap-header-footer.scss | 12 + .../scss/unity-bootstrap-theme.bundle.scss | 3 +- .../vite.config.bundle.js | 85 +++++++ packages/unity-bootstrap-theme/vite.config.js | 14 +- 15 files changed, 346 insertions(+), 174 deletions(-) create mode 100644 packages/unity-bootstrap-theme/jsconfig.json delete mode 100644 packages/unity-bootstrap-theme/src/js/storybook-data-layer.js delete mode 100644 packages/unity-bootstrap-theme/src/js/storybook-global-header.js create mode 100644 packages/unity-bootstrap-theme/src/scss/unity-bootstrap-header-footer.scss create mode 100644 packages/unity-bootstrap-theme/vite.config.bundle.js diff --git a/packages/unity-bootstrap-theme/jsconfig.json b/packages/unity-bootstrap-theme/jsconfig.json new file mode 100644 index 0000000000..1d95ba1e0b --- /dev/null +++ b/packages/unity-bootstrap-theme/jsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM"], + "resolveJsonModule": true, + "jsx": "react", + "allowImportingTsExtensions": true, + "esModuleInterop": true, + "moduleResolution": "node16", + "module": "node16", + "allowSyntheticDefaultImports": true, + "paths": { + "@shared/*": [ "../../shared/*" ], + }, + }, + "include": [ + "src/**/*", + "stories/**/*", + "../../shared/**/*", + ], +} diff --git a/packages/unity-bootstrap-theme/package.json b/packages/unity-bootstrap-theme/package.json index 046857e7f1..235874b446 100644 --- a/packages/unity-bootstrap-theme/package.json +++ b/packages/unity-bootstrap-theme/package.json @@ -13,7 +13,9 @@ "url": "git+https://github.com/ASU/asu-unity-stack.git" }, "scripts": { - "build": "vite build", + "build": "yarn build:1 && yarn build:2", + "build:1": "vite build", + "build:2": "vite build --config vite.config.bundle.js", "watch": "rimraf ./dist && webpack --watch && rimraf ./.tmp", "storybook": "storybook dev -p 9000", "build-storybook": "storybook build -o ../../build/$npm_package_name", @@ -77,14 +79,6 @@ "webpack-node-externals": "^3.0.0" }, "exports": { - "./js/global-header.js": { - "module": "./src/js/storybook-global-header.js", - "default": "./src/js/global-header.js" - }, - "./js/data-layer.js": { - "module": "./src/js/storybook-data-layer.js", - "default": "./src/js/data-layer.js" - }, "./*": "./*", ".": "./dist/css/unity-bootstrap-theme.css" }, diff --git a/packages/unity-bootstrap-theme/src/js/banner.js b/packages/unity-bootstrap-theme/src/js/banner.js index b90c378843..42192d9771 100644 --- a/packages/unity-bootstrap-theme/src/js/banner.js +++ b/packages/unity-bootstrap-theme/src/js/banner.js @@ -1,11 +1,84 @@ -const initBanner = () => { - const closeButtons = document.querySelectorAll('.banner-close button'); - closeButtons.forEach((button) => - button.addEventListener('click', () => { - const bannerToClose = button.parentElement.parentElement.parentElement; - bannerToClose.classList.add('hidden-banner'); +// should we just use bootstrap's Alert + +import { + BaseComponent, + EventHandler, + enableDismissTrigger, + defineJQueryPlugin, +} from "./bootstrap-helper.js"; + +/** + * Constants + */ + +const NAME = 'banner-container' +const DATA_KEY = 'uds.banner' +const EVENT_KEY = `.${DATA_KEY}` + +const EVENT_CLOSE = `close${EVENT_KEY}` +const EVENT_CLOSED = `closed${EVENT_KEY}` +const CLASS_NAME_FADE = 'fade' +const CLASS_NAME_SHOW = 'show' + +/** + * Class definition + */ + +class Banner extends BaseComponent { + // Getters + static get NAME() { + return NAME + } + + // Public + close() { + const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE) + + if (closeEvent.defaultPrevented) { + return + } + + this._element.classList.remove(CLASS_NAME_SHOW) + + const isAnimated = this._element.classList.contains(CLASS_NAME_FADE) + this._queueCallback(() => this._destroyElement(), this._element, isAnimated) + } + + // Private + _destroyElement() { + this._element.remove() + EventHandler.trigger(this._element, EVENT_CLOSED) + this.dispose() + } + + // Static + static jQueryInterface(config) { + return this.each(function () { + const data = Banner.getOrCreateInstance(this) + + if (typeof config !== 'string') { + return + } + + if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { + throw new TypeError(`No method named "${config}"`) + } + + data[config](this) }) - ); -}; + } +} + +/** + * Data API implementation + */ + +enableDismissTrigger(Banner, 'close') + +/** + * jQuery + */ + +defineJQueryPlugin(Banner) -export { initBanner }; +export default Banner diff --git a/packages/unity-bootstrap-theme/src/js/bootstrap-helper.js b/packages/unity-bootstrap-theme/src/js/bootstrap-helper.js index b5176666eb..af8ada0cf0 100644 --- a/packages/unity-bootstrap-theme/src/js/bootstrap-helper.js +++ b/packages/unity-bootstrap-theme/src/js/bootstrap-helper.js @@ -1,11 +1,4 @@ -import BaseComponent from 'bootstrap/js/src/base-component.js' -import EventHandler from "bootstrap/js/src/dom/event-handler.js"; -import { enableDismissTrigger } from 'bootstrap/js/src/util/component-functions.js' -import { defineJQueryPlugin } from 'bootstrap/js/src/util/index.js' - -export { - BaseComponent, - EventHandler, - enableDismissTrigger, - defineJQueryPlugin, -}; +export { default as BaseComponent } from 'bootstrap/js/src/base-component.js'; +export { default as EventHandler } from "bootstrap/js/src/dom/event-handler.js"; +export { enableDismissTrigger } from 'bootstrap/js/src/util/component-functions.js'; +export { defineJQueryPlugin } from 'bootstrap/js/src/util/index.js'; diff --git a/packages/unity-bootstrap-theme/src/js/charts-and-graphs.js b/packages/unity-bootstrap-theme/src/js/charts-and-graphs.js index a7233eda59..1a9b25bd27 100644 --- a/packages/unity-bootstrap-theme/src/js/charts-and-graphs.js +++ b/packages/unity-bootstrap-theme/src/js/charts-and-graphs.js @@ -1,11 +1,10 @@ -import { Chart, registerables } from 'chart.js'; -import { EventHandler } from './bootstrap-helper'; - -// Chart.js library should be peer dependency +import * as Chart from 'chart.js'; -Chart.register(...registerables); +import { EventHandler } from './bootstrap-helper'; function initChart() { + Chart.Chart.register(...Chart.registerables); + const GRAPH_PERCENTAGE_COMPLETE = 50; var ctx = document.getElementById('uds-donut'); @@ -37,7 +36,7 @@ function initChart() { }, }; - var myChart = new Chart(ctx, config); + var myChart = new Chart.Chart(ctx, config); }; EventHandler.on(window, 'load.uds.chart', initChart); diff --git a/packages/unity-bootstrap-theme/src/js/data-layer.js b/packages/unity-bootstrap-theme/src/js/data-layer.js index d401a3c5bb..bb02e76f43 100644 --- a/packages/unity-bootstrap-theme/src/js/data-layer.js +++ b/packages/unity-bootstrap-theme/src/js/data-layer.js @@ -1,4 +1,5 @@ -(function(){ +import { EventHandler } from "./bootstrap-helper"; + function initDataLayer() { /** * Push events to data layer (Google Analytics) @@ -144,6 +145,23 @@ }); }) ); + + document.querySelectorAll('[data-ga-footer]').forEach((element) => + element.addEventListener('focus', () => { + const args = { + type: element.getAttribute('data-ga-footer-type').toLowerCase(), + section: element.getAttribute('data-ga-footer-section').toLowerCase(), + text: element.getAttribute('data-ga-footer').toLowerCase(), + }; + pushGAEvent({ + event: 'link', + action: 'click', + name: 'onclick', + region: 'footer', + ...args, + }); + }) + ); } /* Function must be initialized after document load @@ -151,4 +169,7 @@ * window.initDataLayer(); */ window.initDataLayer = window.initDataLayer || initDataLayer; -})(); + + EventHandler.on(window, 'load.uds.data-layer', initDataLayer); + +export { initDataLayer }; diff --git a/packages/unity-bootstrap-theme/src/js/global-header.js b/packages/unity-bootstrap-theme/src/js/global-header.js index 54ed350301..c7b231a0c5 100644 --- a/packages/unity-bootstrap-theme/src/js/global-header.js +++ b/packages/unity-bootstrap-theme/src/js/global-header.js @@ -1,4 +1,5 @@ -(function(){ +import { EventHandler } from "./bootstrap-helper"; + const initGlobalHeader = () => { // Scroll state const handleWindowScroll = () => { @@ -9,7 +10,7 @@ : headerEl?.classList.remove('scrolled'); }; - window.addEventListener('scroll', handleWindowScroll); + EventHandler.on(window, 'scroll.uds.header', handleWindowScroll); }; window.initGlobalHeader = window.initGlobalHeader || initGlobalHeader; @@ -18,4 +19,7 @@ * Example: * window.initGlobalHeader(); */ -})(); + + EventHandler.on(window, 'load.uds.global-header', initGlobalHeader); + +export { initGlobalHeader }; diff --git a/packages/unity-bootstrap-theme/src/js/storybook-data-layer.js b/packages/unity-bootstrap-theme/src/js/storybook-data-layer.js deleted file mode 100644 index 1ef8146689..0000000000 --- a/packages/unity-bootstrap-theme/src/js/storybook-data-layer.js +++ /dev/null @@ -1,5 +0,0 @@ -require('./data-layer.js'); - -const { initDataLayer: googleAnalytics } = window; - -export { googleAnalytics }; diff --git a/packages/unity-bootstrap-theme/src/js/storybook-global-header.js b/packages/unity-bootstrap-theme/src/js/storybook-global-header.js deleted file mode 100644 index f089fe6b4f..0000000000 --- a/packages/unity-bootstrap-theme/src/js/storybook-global-header.js +++ /dev/null @@ -1,5 +0,0 @@ -require('./global-header.js'); - -const { initGlobalHeader } = window; - -export { initGlobalHeader }; diff --git a/packages/unity-bootstrap-theme/src/js/tabbed-panels.js b/packages/unity-bootstrap-theme/src/js/tabbed-panels.js index 74c1adf8e2..e711e26820 100644 --- a/packages/unity-bootstrap-theme/src/js/tabbed-panels.js +++ b/packages/unity-bootstrap-theme/src/js/tabbed-panels.js @@ -1,5 +1,8 @@ +import { EventHandler } from "./bootstrap-helper"; + function initTabs() { - "use strict"; + ("use strict"); + const DOM_ELEMENT_A = "a"; const DOM_ELEMENT_BUTTON = "button"; const DOM_ELEMENT_NAV_TABS = ".nav-tabs"; @@ -7,12 +10,12 @@ function initTabs() { const DOM_ELEMENT_UDS_TABBED_PANELS = ".uds-tabbed-panels"; const DOM_ELEMENT_SCROLL_CONTROL_PREV = ".scroll-control-prev"; const DOM_ELEMENT_SCROLL_CONTROL_NEXT = ".scroll-control-next"; - const EVENT_LOAD = "load"; const EVENT_CLICK = "click"; const EVENT_SCROLL = "scroll"; + const EVENT_FOCUS = "focus"; const CSS_DISPLAY_NONE = "none"; const CSS_DISPLAY_BLOCK = "block"; - const magicalNumberThree = 3; + const scrollTollerance = 10; const LG_BREAKPOINT = 992; // helpers functions @@ -23,146 +26,120 @@ function initTabs() { } }; - const slideNav = (clicked, e, direction) => { - e.preventDefault(); - const parentNav = Array.from(clicked.parentElement.children).filter(child => - child.classList.contains("nav-tabs") - ); - - let scrollPosition = parseInt(parentNav[0].dataset.scrollPosition, 10); - - const navItems = Array.from( - parentNav[0].querySelectorAll(DOM_ELEMENT_NAV_ITEM) - ); + document + .querySelectorAll(DOM_ELEMENT_UDS_TABBED_PANELS) + .forEach(parentContainer => { + const parentNav = parentContainer.querySelector(DOM_ELEMENT_NAV_TABS); + const navItems = parentContainer.querySelectorAll(DOM_ELEMENT_NAV_ITEM); + const prevButton = parentContainer.querySelector( + DOM_ELEMENT_SCROLL_CONTROL_PREV + ); + const nextButton = parentContainer.querySelector( + DOM_ELEMENT_SCROLL_CONTROL_NEXT + ); + let scrollPosition = 0; - // get left value to interact with scroll - const rawLeftValue = getComputedStyle(parentNav[0]).left; - const sanitizedLeftValue = rawLeftValue.replace("px", ""); - let scrollOffset = parseInt(sanitizedLeftValue, 10); + parentContainer.addEventListener(EVENT_CLICK, function (e) { + setButtonsCompatibility(e); + }); - if (direction === 1 && scrollPosition > 0) { - scrollPosition -= 1; - } - if (scrollPosition < navItems.length - 1 && direction == -1) { - scrollPosition += 1; - } - parentNav[0].dataset.scrollPosition = scrollPosition; - - scrollOffset = 0; - for (var i = 0; i < scrollPosition; i++) { - scrollOffset += - navItems[i].offsetWidth + - parseInt(getComputedStyle(navItems[i]).marginLeft, 10) + - parseInt(getComputedStyle(navItems[i]).marginRight, 10); - } + const slideNav = (clicked, e, direction) => { + e.preventDefault(); - // set the position of the scroll of the .nav-tabs element - parentNav[0].scrollLeft = scrollOffset; - setControlVisibility(clicked, scrollOffset); - }; + // get left value to interact with scroll + const rawLeftValue = getComputedStyle(parentNav).left; + const sanitizedLeftValue = rawLeftValue.replace("px", ""); + let scrollOffset = parseInt(sanitizedLeftValue, 10); - const setControlVisibility = (clicked, scrollOffset) => { - // select the nearest ancestor with the class ".uds-tabbed-panels". - const parentContainer = clicked.closest(DOM_ELEMENT_UDS_TABBED_PANELS); - // select the sibling parent elements of the clicked element. - const parentNav = parentContainer.querySelector(DOM_ELEMENT_NAV_TABS); + if (direction === 1 && scrollPosition > 0) { + scrollPosition -= 1; + } + if (scrollPosition < navItems.length - 1 && direction == -1) { + scrollPosition += 1; + } + parentNav.dataset.scrollPosition = scrollPosition; + + scrollOffset = 0; + for (var i = 0; i < scrollPosition; i++) { + scrollOffset += + navItems[i].offsetWidth + + parseInt(getComputedStyle(navItems[i]).marginLeft, 10) + + parseInt(getComputedStyle(navItems[i]).marginRight, 10); + } - // get the value of the data-scroll-position attribute and make sure it is an integer - const scrollPosition = parseInt(parentNav.dataset.scrollPosition, 10); - const tabPosition = parentNav.scrollWidth - scrollOffset; + // set the position of the scroll of the .nav-tabs element + parentNav.scrollLeft = scrollOffset; + setControlVisibility(clicked, scrollOffset); + }; - // hide or show the scroll buttons based on the scroll position - if (scrollPosition == 0) { - parentContainer.querySelector( - DOM_ELEMENT_SCROLL_CONTROL_PREV - ).style.display = CSS_DISPLAY_NONE; - } else { - parentContainer.querySelector( - DOM_ELEMENT_SCROLL_CONTROL_PREV - ).style.display = CSS_DISPLAY_BLOCK; - } - if (tabPosition <= parentContainer.offsetWidth) { - parentContainer.querySelector( - DOM_ELEMENT_SCROLL_CONTROL_NEXT - ).style.display = CSS_DISPLAY_NONE; - } else { - parentContainer.querySelector( - DOM_ELEMENT_SCROLL_CONTROL_NEXT - ).style.display = CSS_DISPLAY_BLOCK; - } - }; + const setControlVisibility = (clicked, scrollOffset) => { + const tabPosition = parentNav.scrollWidth - scrollOffset; - // wait to load the page and all resources before initializing - window.addEventListener(EVENT_LOAD, function windowLoad() { - window.removeEventListener(EVENT_LOAD, windowLoad) - // wait to DOM content is loaded before run these scripts - document.addEventListener(EVENT_CLICK, function (e) { - setButtonsCompatibility(e); - }); + // hide or show the scroll buttons based on the scroll position + if (scrollPosition == 0) { + prevButton.style.display = CSS_DISPLAY_NONE; + } else { + prevButton.style.display = CSS_DISPLAY_BLOCK; + } + if (tabPosition <= parentContainer.offsetWidth) { + nextButton.style.display = CSS_DISPLAY_NONE; + } else { + nextButton.style.display = CSS_DISPLAY_BLOCK; + } + }; - // handle focus event for tabs titles - const navItems = document.querySelectorAll(DOM_ELEMENT_NAV_ITEM); - navItems.forEach(tabTitle => { - tabTitle.addEventListener("focus", function (e) { - tabTitle.scrollIntoView(); - }) - }) - - // handle scroll for tabs titles - document.querySelectorAll(DOM_ELEMENT_UDS_TABBED_PANELS).forEach(item => { - const nav = item.querySelector(DOM_ELEMENT_NAV_TABS); - nav.addEventListener(EVENT_SCROLL, event => { + parentNav.addEventListener(EVENT_SCROLL, event => { const scrollPos = event.target.scrollLeft; - const prevButton = item.querySelector(DOM_ELEMENT_SCROLL_CONTROL_PREV); - const nextButton = item.querySelector(DOM_ELEMENT_SCROLL_CONTROL_NEXT); const atFarRight = - nav.offsetWidth + scrollPos + magicalNumberThree >= nav.scrollWidth; + parentNav.offsetWidth + scrollPos + scrollTollerance >= + parentNav.scrollWidth; prevButton.style.display = - scrollPos === 0 ? CSS_DISPLAY_NONE : CSS_DISPLAY_BLOCK; + scrollPos < scrollTollerance ? CSS_DISPLAY_NONE : CSS_DISPLAY_BLOCK; nextButton.style.display = atFarRight ? CSS_DISPLAY_NONE : CSS_DISPLAY_BLOCK; }); - }); + // }); + + // handle focus event for tabs titles + navItems.forEach(tabTitle => { + tabTitle.addEventListener(EVENT_FOCUS, function (e) { + tabTitle.scrollIntoView(); + }); + }); - // click of the next button - document - .querySelector(DOM_ELEMENT_SCROLL_CONTROL_NEXT) - .addEventListener(EVENT_CLICK, function (e) { + // click of the next button + nextButton.addEventListener(EVENT_CLICK, function (e) { if (window.innerWidth > LG_BREAKPOINT) { slideNav(this, e, -1); } }); - // click of the prev button - document - .querySelector(DOM_ELEMENT_SCROLL_CONTROL_PREV) - .addEventListener(EVENT_CLICK, function (e) { + // click of the prev button + prevButton.addEventListener(EVENT_CLICK, function (e) { if (window.innerWidth > LG_BREAKPOINT) { slideNav(this, e, 1); } }); - // hide prev button on load - document.querySelector( - `${DOM_ELEMENT_UDS_TABBED_PANELS} ${DOM_ELEMENT_SCROLL_CONTROL_PREV}` - ).style.display = CSS_DISPLAY_NONE; + // hide prev button on load - // width of all tabs - const navTabWidth = - document.querySelector(DOM_ELEMENT_NAV_TABS).scrollWidth; + prevButton.style.display = CSS_DISPLAY_NONE; - // width of the parent element - const udsTabbedPanelsWidth = document.querySelector( - DOM_ELEMENT_UDS_TABBED_PANELS - ).offsetWidth; + // width of all tabs + const navTabWidth = parentNav.scrollWidth; - if (navTabWidth <= udsTabbedPanelsWidth) { - document.querySelector( - `${DOM_ELEMENT_UDS_TABBED_PANELS} ${DOM_ELEMENT_SCROLL_CONTROL_NEXT}` - ).style.display = CSS_DISPLAY_NONE; - } - }); -}; + // width of the parent element + const udsTabbedPanelsWidth = parentContainer.offsetWidth; + + if (navTabWidth <= udsTabbedPanelsWidth) { + nextButton.style.display = CSS_DISPLAY_NONE; + } + }); +} + +EventHandler.on(window, 'load.uds.tabs', initTabs); + +// window.addEventListener("load.uds.tabs", initTabs, true); -export {initTabs} +export { initTabs }; diff --git a/packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js b/packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js index 4e5b7311be..e2f009ebba 100644 --- a/packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js +++ b/packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js @@ -14,7 +14,6 @@ import { initializeFixedTable } from "./tables.js"; import { initVideo } from "./video.js"; const unityBootstrap = { - // EventHandler, initAnchorMenu, // Banner, initBlockquoteAnimation, diff --git a/packages/unity-bootstrap-theme/src/scss/unity-bootstrap-header-footer.scss b/packages/unity-bootstrap-theme/src/scss/unity-bootstrap-header-footer.scss new file mode 100644 index 0000000000..2ec330b025 --- /dev/null +++ b/packages/unity-bootstrap-theme/src/scss/unity-bootstrap-header-footer.scss @@ -0,0 +1,12 @@ +@import "shared"; + +// 8. Add additional custom code here + +// import bootstrap core +// @import "bootstrap/scss/bootstrap"; +// css Bootstrap doesn't have variables for +// @import "unity-bootstrap-theme-extends"; +@import 'extends/global-header'; +@import 'extends/globalfooter'; + +@import 'end-style'; diff --git a/packages/unity-bootstrap-theme/src/scss/unity-bootstrap-theme.bundle.scss b/packages/unity-bootstrap-theme/src/scss/unity-bootstrap-theme.bundle.scss index 1faa1ce120..398cb6aab8 100755 --- a/packages/unity-bootstrap-theme/src/scss/unity-bootstrap-theme.bundle.scss +++ b/packages/unity-bootstrap-theme/src/scss/unity-bootstrap-theme.bundle.scss @@ -1,7 +1,6 @@ $add_end_styles: false; @import 'unity-bootstrap-theme'; -@import 'unity-bootstrap-header'; -@import 'unity-bootstrap-footer'; +@import 'unity-bootstrap-header-footer'; $add_end_styles: true; @import 'end-style'; diff --git a/packages/unity-bootstrap-theme/vite.config.bundle.js b/packages/unity-bootstrap-theme/vite.config.bundle.js new file mode 100644 index 0000000000..1789284ed3 --- /dev/null +++ b/packages/unity-bootstrap-theme/vite.config.bundle.js @@ -0,0 +1,85 @@ +import react from "@vitejs/plugin-react"; +import path, { resolve } from "path"; +import fs from "fs"; +import { defineConfig, transformWithEsbuild } from "vite"; + +import pkg from "./package.json"; +/** @typedef {import('vite').UserConfig} UserConfig */ + +/** @type {UserConfig} */ +const c = { + root: resolve(__dirname), + plugins: [ + react(), + { + name: "treat-js-files-as-jsx", + async transform(code, id) { + if (!id.match(/stories\/.*\.js$/)) return null; + + return transformWithEsbuild(code, id, { + loader: "jsx", + jsx: "automatic", + }); + }, + }, + ], + optimizeDeps: { + esbuildOptions: { + target: "es2021", + loader: { + ".js": "jsx", + }, + }, + }, + build: { + emptyOutDir: false, + sourcemap: true, + cssMinify: true, + cssCodeSplit: false, + lib: { + entry: resolve(__dirname, "src/js/unity-bootstrap-theme.js"), + formats: ["es", "cjs", "umd"], + name: 'unityBootstrap', + fileName: (format) => `js/${format}/unity-bootstrap-theme.js`, + }, + outDir: "dist", + rollupOptions: { + external: [...Object.keys(pkg.peerDependencies), "chart.js"], + treeshake: true, + output: { + globals: { + "chart.js": "Chart", + }, + assetFileNames: (assetInfo) => { + console.log(assetInfo) + if (assetInfo.originalFileNames && assetInfo.originalFileNames[0]?.includes("bundle")) { + return "css/unity-bootstrap-theme.bundle.[ext]"; + } + return "css/[name].[ext]"; + }, + }, + }, + }, + esbuild: { + loader: "jsx", + include: /.*\.jsx?$/, + exclude: [], + }, + css: { + preprocessorOptions: { + scss: { + api: "modern-compiler", + }, + }, + }, + server: { + port: 9000, + }, + resolve: { + alias: [ + { find: '@shared', replacement: path.resolve(__dirname, '../../shared') }, + ], + }, +}; + +export default defineConfig(c); diff --git a/packages/unity-bootstrap-theme/vite.config.js b/packages/unity-bootstrap-theme/vite.config.js index 658cbece41..e3863eba61 100644 --- a/packages/unity-bootstrap-theme/vite.config.js +++ b/packages/unity-bootstrap-theme/vite.config.js @@ -50,26 +50,30 @@ const c = { entry: [ resolve(__dirname, "src/scss/unity-bootstrap-theme.bundle.scss"), resolve(__dirname, "src/scss/unity-bootstrap-theme.scss"), + resolve(__dirname, "src/scss/unity-bootstrap-header-footer.scss"), resolve(__dirname, "src/scss/unity-bootstrap-header.scss"), resolve(__dirname, "src/scss/unity-bootstrap-footer.scss"), resolve(__dirname, "src/js/global-header.js"), resolve(__dirname, "src/js/data-layer.js"), - resolve(__dirname, "../../node_modules/bootstrap/js/index.esm.js"), + // resolve(__dirname, "../../node_modules/bootstrap/js/index.esm.js"), ], }, outDir: "dist", rollupOptions: { - external: Object.keys(pkg.peerDependencies), + external: [...Object.keys(pkg.peerDependencies), "chart.js"], treeshake: true, output: { + globals: { + "chart.js": "Chart", + }, entryFileNames: chunkInfo => { if (chunkInfo.name.includes("index.esm")) { - return "js/bootstrap.bundle.min.[format]"; + return "js/[format]/bootstrap.bundle.min.js"; } - return "js/[name].[format]"; + return "js/[format]/[name].js"; }, - chunkFileNames: "js/[name].[format]", + chunkFileNames: "js/[format]/[name].js", assetFileNames: (assetInfo) => { if (assetInfo.originalFileNames && assetInfo.originalFileNames[0].includes("bundle")) { return "css/unity-bootstrap-theme.bundle.[ext]"; From 118efeb5732c3bf881737b72cff9032acc2181d8 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 10 Apr 2025 12:10:04 -0700 Subject: [PATCH 08/14] fix(unity-react-core): update sb to use uds js --- packages/unity-react-core/src/core/models/shared-prop-types.js | 2 +- packages/unity-react-core/vite.config.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/unity-react-core/src/core/models/shared-prop-types.js b/packages/unity-react-core/src/core/models/shared-prop-types.js index b7d82960f9..57ddae8d5e 100644 --- a/packages/unity-react-core/src/core/models/shared-prop-types.js +++ b/packages/unity-react-core/src/core/models/shared-prop-types.js @@ -18,7 +18,7 @@ const contentPropType = PropTypes.shape({ const accordionCardPropTypes = PropTypes.shape({ color: PropTypes.oneOf(["gold", "maroon", "gray", "dark"]), content: PropTypes.shape({ - icon: PropTypes.string, + icon: PropTypes.arrayOf(PropTypes.string), header: PropTypes.string, body: PropTypes.string, }), diff --git a/packages/unity-react-core/vite.config.js b/packages/unity-react-core/vite.config.js index 9ca5287036..ce573119c8 100644 --- a/packages/unity-react-core/vite.config.js +++ b/packages/unity-react-core/vite.config.js @@ -73,6 +73,9 @@ export default defineConfig({ }, }, ], + // optimizeDeps: { + // force: true, + // }, resolve: { alias: { "@shared": path.resolve(__dirname, "./../../shared"), From c3f1e27d674f9fc31ab20c2353638ea58a7c72e0 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 10 Apr 2025 12:28:12 -0700 Subject: [PATCH 09/14] chore(unity-react-core): lint fix --- .../src/components/AnchorMenu/AnchorMenu.stories.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx index 2c6c397dd2..f7518e8e24 100644 --- a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx +++ b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx @@ -6,10 +6,10 @@ import { getLoremSentences, titleCaseDefinition, } from "../../../../../shared/constants/strings"; +import { Basic as Header } from "../../../../unity-bootstrap-theme/stories/organisms/global-header/global-header.templates"; import { Divider } from "../Divider/Divider"; +import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework"; import { AnchorMenu } from "./AnchorMenu"; -import { Basic as Header } from "../../../../unity-bootstrap-theme/stories/organisms/global-header/global-header.templates.jsx"; -import { useBaseSpecificFramework } from "../GaEventWrapper/useBaseSpecificFramework.js"; const titleCaseTitle = "Anchor Menus Should Always be Formatted with Title Case"; From d9efa19fa269e90525fb698eccafd255cbd68b48 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 10 Apr 2025 16:02:02 -0700 Subject: [PATCH 10/14] chore(unity-react-core): storybook docs should only render react example --- .../.storybook/decorators.tsx | 29 ++++++------------- .../unity-react-core/.storybook/preview.jsx | 10 ------- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/packages/unity-react-core/.storybook/decorators.tsx b/packages/unity-react-core/.storybook/decorators.tsx index bd4c65f287..ef94907bd0 100644 --- a/packages/unity-react-core/.storybook/decorators.tsx +++ b/packages/unity-react-core/.storybook/decorators.tsx @@ -18,14 +18,14 @@ declare interface ContainerProps { const Full:ContainerComponent = forwardRef((props, ref) => { return ( -
+
)}); const UdsContainer:ContainerComponent = forwardRef((props, ref) => { return (
-
+
)}); @@ -34,21 +34,22 @@ export const withContainer: Decorator = ( StoryFn, { args, - globals: { framework = "react" }, + globals, parameters: { layout = "fullscreen" }, + viewMode, } ) => { + let { framework = "react" } = globals; + // Doc page will only render react framework + if(viewMode === "docs") { + framework = "react"; + } const isBootstrap = framework === "bootstrap"; - const isReact = !isBootstrap; const root = React.useRef(null as any); const emit = useChannel({ "HTML/CodeUpdated": () => {} }); - - const mount = () => { - // console.log("sb mounting"); - if (root.current) { if (isBootstrap) { // custom events created by eventSpy.js to allow storybook to dispatch load events after the page is loaded @@ -58,7 +59,6 @@ export const withContainer: Decorator = ( emit("HTML/CodeUpdated", { code: root.current.innerHTML }); } - } const unmount = () => { @@ -77,19 +77,10 @@ export const withContainer: Decorator = ( } } - - - - - - - useEffect(() => { // @ts-ignore if (!window.unloading) { mount() - } else { - } return unmount }, [StoryFn, args, framework]); @@ -116,5 +107,3 @@ export const withContainer: Decorator = ( export const globalDecorators = [ withContainer ]; - - diff --git a/packages/unity-react-core/.storybook/preview.jsx b/packages/unity-react-core/.storybook/preview.jsx index 893c937d86..01a9458598 100644 --- a/packages/unity-react-core/.storybook/preview.jsx +++ b/packages/unity-react-core/.storybook/preview.jsx @@ -7,9 +7,6 @@ import "@asu/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js"; import { globalDecorators } from "./decorators.tsx"; import { Container } from "./docPage.tsx"; - -const sourceCodeRootSelector = "#html-root"; - const parameters = { controls: { expanded: true }, argTypes: { @@ -29,13 +26,6 @@ const parameters = { }, ], }, - html: { - prettier: { - tabWidth: 4, - htmlWhitespaceSensitivity: "ignore", - }, - root: sourceCodeRootSelector, - }, docs: { // Table of contents stopped working, so I disabled it. // If we can figure out how to get it working again, we can re-enable it. From 090021037959d12925a9551ef3235b483a774b68 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 24 Apr 2025 13:12:32 -0700 Subject: [PATCH 11/14] feat(unity-bootstrap-theme): update dist files and README docs for usage --- .../.storybook/local-addon/addon.js | 22 +++- .../.storybook/local-addon/entry.js | 3 + .../.storybook/preview.js | 2 +- packages/unity-bootstrap-theme/package.json | 6 +- .../src/js/card-ranking.js | 6 +- .../src/js/tabbed-panels.js | 6 +- .../unity-bootstrap-theme/src/js/tables.js | 6 +- ...-bootstrap-theme.js => unity-bootstrap.js} | 16 +-- .../anchor-menu.examples.stories.js | 4 + .../blockquote/blockquote.examples.stories.js | 6 +- .../atoms/modals/modals.examples.stories.js | 3 + .../atoms/modals/modals.templates.stories.js | 5 +- .../atoms/video/video.templates.stories.js | 5 + .../docs/GetStarted/get-started.stories.mdx | 37 +++++- .../banners/banners.templates.stories.js | 5 + .../calendar/calendar.templates.stories.js | 3 + .../molecules/cards/cards.examples.stories.js | 10 ++ .../charts-and-graphs.templates.stories.js | 3 + .../heroes/heroes.examples.stories.js | 6 + .../image-parallax.examples.stories.js | 3 + .../tabbed-panels.templates.stories.js | 7 +- .../tables/tables.templates.stories.js | 6 + .../global-footer.examples.stories.js | 3 + .../global-header.examples.stories.js | 3 + .../vite.config.bundle.js | 124 +++++++----------- packages/unity-bootstrap-theme/vite.config.js | 68 ++++------ 26 files changed, 216 insertions(+), 152 deletions(-) rename packages/unity-bootstrap-theme/src/js/{unity-bootstrap-theme.js => unity-bootstrap.js} (73%) diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js b/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js index aa71394add..c21b71102d 100644 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js +++ b/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js @@ -1,11 +1,29 @@ import React from 'react'; import { AddonPanel } from '@storybook/components'; -import { Source } from '@storybook/blocks'; import { addons, types } from '@storybook/addons'; -import { formatWithBabelParser } from './helpers'; import { Toggle } from '../../../../.storybook-config/Toggle' addons.register('local-addon', (api) => { + addons.add('local-addon/panel', { + title: 'Javascript', + //👇 Sets the type of UI element in Storybook + type: types.PANEL, + paramKey: 'initFunc', + render: ({active, key}) => { + + return( + +
+ + This component requires Javascript.

+ + View the documentation{" "}on how to use the component in your project. + +
+
+ )}, + }); + addons.add('local-addon/tools', { title: 'tools', type: types.TOOL, diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/entry.js b/packages/unity-bootstrap-theme/.storybook/local-addon/entry.js index ffa92e9e45..c59229045d 100644 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/entry.js +++ b/packages/unity-bootstrap-theme/.storybook/local-addon/entry.js @@ -16,6 +16,9 @@ export const parameters = { loadEvent: { disable: false }, + initFunc: { + disable: true + }, docs:{ source: { transform: (src,storyContext)=>{ diff --git a/packages/unity-bootstrap-theme/.storybook/preview.js b/packages/unity-bootstrap-theme/.storybook/preview.js index 05796d5bd0..fc622e9c19 100644 --- a/packages/unity-bootstrap-theme/.storybook/preview.js +++ b/packages/unity-bootstrap-theme/.storybook/preview.js @@ -2,7 +2,7 @@ import "./eventSpy.js"; import "../src/scss/unity-bootstrap-theme.bundle.scss"; import { default as bootstrap } from "bootstrap/js/index.umd.js"; globalThis.bootstrap = bootstrap; -import { default as udsBootstrap } from "@asu/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js"; +import { default as udsBootstrap } from "../src/js/unity-bootstrap.js"; globalThis.udsBootstrap = udsBootstrap; import { removeFontAwesomeChanges } from "./local-addon/helpers"; diff --git a/packages/unity-bootstrap-theme/package.json b/packages/unity-bootstrap-theme/package.json index e3a173c374..9551ea54e6 100644 --- a/packages/unity-bootstrap-theme/package.json +++ b/packages/unity-bootstrap-theme/package.json @@ -13,9 +13,9 @@ "url": "git+https://github.com/ASU/asu-unity-stack.git" }, "scripts": { - "build": "yarn build:1 && yarn build:2", - "build:1": "vite build", - "build:2": "vite build --config vite.config.bundle.js", + "build": "yarn build:css && yarn build:js", + "build:css": "vite build", + "build:js": "vite build --config vite.config.bundle.js", "watch": "rimraf ./dist && webpack --watch && rimraf ./.tmp", "storybook": "storybook dev -p 9000", "build-storybook": "storybook build -o ../../build/$npm_package_name", diff --git a/packages/unity-bootstrap-theme/src/js/card-ranking.js b/packages/unity-bootstrap-theme/src/js/card-ranking.js index 88cc28d4ec..d0d1507eeb 100644 --- a/packages/unity-bootstrap-theme/src/js/card-ranking.js +++ b/packages/unity-bootstrap-theme/src/js/card-ranking.js @@ -1,7 +1,7 @@ import { EventHandler } from "./bootstrap-helper"; // method ot handle the custom behavior of the ranking card -function rankingFunc() { +function initRankingCard() { const $infoLayer = document.querySelector(".info-layer"); const $toggleIcon = document.getElementById("dispatch"); @@ -11,6 +11,6 @@ function rankingFunc() { }; -EventHandler.on(window, 'load.uds.ranking-card', rankingFunc); +EventHandler.on(window, 'load.uds.ranking-card', initRankingCard); -export { rankingFunc }; +export { initRankingCard }; diff --git a/packages/unity-bootstrap-theme/src/js/tabbed-panels.js b/packages/unity-bootstrap-theme/src/js/tabbed-panels.js index e711e26820..bd8b42ff5a 100644 --- a/packages/unity-bootstrap-theme/src/js/tabbed-panels.js +++ b/packages/unity-bootstrap-theme/src/js/tabbed-panels.js @@ -1,6 +1,6 @@ import { EventHandler } from "./bootstrap-helper"; -function initTabs() { +function initTabbedPanels() { ("use strict"); const DOM_ELEMENT_A = "a"; @@ -138,8 +138,8 @@ function initTabs() { }); } -EventHandler.on(window, 'load.uds.tabs', initTabs); +EventHandler.on(window, 'load.uds.tabs', initTabbedPanels); // window.addEventListener("load.uds.tabs", initTabs, true); -export { initTabs }; +export { initTabbedPanels }; diff --git a/packages/unity-bootstrap-theme/src/js/tables.js b/packages/unity-bootstrap-theme/src/js/tables.js index 57a3b2890f..6eeb122b29 100644 --- a/packages/unity-bootstrap-theme/src/js/tables.js +++ b/packages/unity-bootstrap-theme/src/js/tables.js @@ -14,7 +14,7 @@ import { EventHandler } from "./bootstrap-helper"; -function initializeFixedTable() { +function initFixedTable() { function setPreButtonPosition() { const wrapperSelector = '.uds-table-fixed-wrapper'; const tableSelector = '.uds-table.uds-table-fixed table'; @@ -74,6 +74,6 @@ function initializeFixedTable() { }); } -EventHandler.on(window, 'load.uds.fixed-table', initializeFixedTable); +EventHandler.on(window, 'load.uds.fixed-table', initFixedTable); -export { initializeFixedTable }; +export { initFixedTable }; diff --git a/packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js b/packages/unity-bootstrap-theme/src/js/unity-bootstrap.js similarity index 73% rename from packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js rename to packages/unity-bootstrap-theme/src/js/unity-bootstrap.js index e2f009ebba..2a1fcf0d65 100644 --- a/packages/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js +++ b/packages/unity-bootstrap-theme/src/js/unity-bootstrap.js @@ -1,33 +1,33 @@ -import { initAnchorMenu } from "./anchor-menu.js"; // import Banner from "./banner.js"; +import { initAnchorMenu } from "./anchor-menu.js"; import { initBlockquoteAnimation } from "./blockquote-animated.js"; import { initCalendar } from "./calendar.js"; -import { rankingFunc } from "./card-ranking.js"; +import { initRankingCard } from "./card-ranking.js"; import { initChart } from "./charts-and-graphs.js"; import { initDataLayer } from "./data-layer.js"; import { initGlobalHeader } from "./global-header.js"; import { initHeroesVideo } from "./heroes-video.js"; import { initImageParallax } from "./image-parallax.js"; import { initModals } from "./modals.js"; -import { initTabs } from "./tabbed-panels.js"; -import { initializeFixedTable } from "./tables.js"; +import { initTabbedPanels } from "./tabbed-panels.js"; +import { initFixedTable } from "./tables.js"; import { initVideo } from "./video.js"; const unityBootstrap = { + // Banner, // code updated to use bootstrap alert so we don't need this initAnchorMenu, - // Banner, initBlockquoteAnimation, initCalendar, - rankingFunc, initChart, initDataLayer, + initFixedTable, initGlobalHeader, initHeroesVideo, initImageParallax, initModals, - initializeFixedTable, + initRankingCard, + initTabbedPanels, initVideo, - initTabs, } export default unityBootstrap; diff --git a/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.examples.stories.js b/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.examples.stories.js index beff5b4fae..ea919af2fb 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/anchor-menu/anchor-menu.examples.stories.js @@ -3,9 +3,13 @@ import React from "react"; import { imageName } from "../../../../../shared/assets"; import { htmlRootDecorator } from "../../../../../shared/components/Layout"; import {getLoremSentences} from "../../../../../shared/constants/strings"; + export default { title: "Atoms/Anchor Menu", parameters: { + initFunc: { + disable: false, + }, header: { forced: true, }, diff --git a/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote.examples.stories.js b/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote.examples.stories.js index 0e3006b417..bff33af586 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/blockquote/blockquote.examples.stories.js @@ -219,7 +219,11 @@ export const BlockquoteAnimated = () => ( ); - +BlockquoteAnimated.parameters = { + initFunc: { + disable: false, + }, +}; export const TestimonialsNoImage = () => ( <>
diff --git a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.examples.stories.js b/packages/unity-bootstrap-theme/stories/atoms/modals/modals.examples.stories.js index 68555a4534..7f04bf84ee 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/modals/modals.examples.stories.js @@ -3,6 +3,9 @@ import React from "react"; export default { title: "Atoms/Modals/Examples", parameters: { + initFunc: { + disable: false, + }, header: { forced: true, }, diff --git a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.templates.stories.js b/packages/unity-bootstrap-theme/stories/atoms/modals/modals.templates.stories.js index c87847dee5..5b7fb7cab3 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/modals/modals.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/modals/modals.templates.stories.js @@ -6,12 +6,15 @@ export default { title: "Atoms/Modals/Templates", decorators: [ defaultDecorator ], parameters: { + initFunc: { + disable: false, + }, header: { forced: true, }, footer: { forced: true, - } + }, }, args: {open: true}, argTypes: { diff --git a/packages/unity-bootstrap-theme/stories/atoms/video/video.templates.stories.js b/packages/unity-bootstrap-theme/stories/atoms/video/video.templates.stories.js index 5668c84a8f..0d2879f732 100644 --- a/packages/unity-bootstrap-theme/stories/atoms/video/video.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/atoms/video/video.templates.stories.js @@ -13,6 +13,11 @@ export default { control: { type: "boolean" }, }, }, + parameters: { + initFunc: { + disable: false, + }, + }, }; export const Default = ({content}) => diff --git a/packages/unity-bootstrap-theme/stories/docs/GetStarted/get-started.stories.mdx b/packages/unity-bootstrap-theme/stories/docs/GetStarted/get-started.stories.mdx index d76d45d785..05a39d8b38 100755 --- a/packages/unity-bootstrap-theme/stories/docs/GetStarted/get-started.stories.mdx +++ b/packages/unity-bootstrap-theme/stories/docs/GetStarted/get-started.stories.mdx @@ -17,12 +17,37 @@ This is the Storybook reference site for the Unity Bootstrap theme. Browse the d ## ❯ Including Unity in your project -We bundle the necessary CSS and Javascript in the `dist/` folder. There are more options so you don't have to include CSS you don't use. - -* `dist/unity-bootstrap-theme.bundle.css` - base theme with header and footer CSS -* `dist/unity-bootstrap-theme.css` - base theme without header and footer CSS -* `dist/unity-bootstrap-header.css` (optional) - header CSS only - don't use if using the Unity `component-header` React component -* `dist/unity-bootstrap-footer.css` (optional) - footer CSS only - don't use if using the Unity `component-footer` React component +We bundle the necessary CSS and Javascript in the `dist/` folder. There are more options so you don't have to include CSS you don't use. +### CSS +* `dist/css/unity-bootstrap-theme.bundle.css` - base theme with header and footer CSS +* `dist/css/unity-bootstrap-theme.css` - base theme without header and footer CSS +* `dist/css/unity-bootstrap-header-footer.css` (optional) - header and footer CSS only - don't use if using the Unity `component-header-footer` React component + +### Javascript +All you need to do is include the script on your page, the scripts will execute with the window load event. +We provide 3 formats ("UMD", "CJS", "ES"). +* exports: + * `initAnchorMenu`, + * `initBlockquoteAnimation`, + * `initCalendar`, + * `initChart`, + * `initDataLayer`, + * `initFixedTable`, + * `initGlobalHeader`, + * `initHeroesVideo`, + * `initImageParallax`, + * `initModals`, + * `initRankingCard`, + * `initTabbedPanels`, + * `initVideo`, +* Unity File Formats + * dist/js/unity-bootstrap.umd.js (universal) + * creates a global variable `unityBootstrap` if you need to manaully call the init function ex: `unityBootstrap.initAnchorMenu()` + * dist/js/unity-bootstrap.cjs.js (common js) + * dist/js/unity-bootstrap.es.js (module) +* Vendor Files + * dist/js/bootstrap.bundle.min.js (unaltered bootstrap version) + * dist/js/chart.min.js (only needed if you are using the donut chart) ## ❯ How to use the Unity Storybook reference site diff --git a/packages/unity-bootstrap-theme/stories/molecules/banners/banners.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/banners/banners.templates.stories.js index d385da5dc8..6678d53d0f 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/banners/banners.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/banners/banners.templates.stories.js @@ -25,6 +25,11 @@ export default { args: { color: "Orange", }, + parameters: { + initFunc: { + disable: false, + }, + }, }; export const Banner = ({color}) => { diff --git a/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.templates.stories.js index b8352665a8..9300680f28 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/calendar/calendar.templates.stories.js @@ -6,6 +6,9 @@ export default { title: "Molecules/Calendar/Templates", decorators: [ defaultDecorator ], parameters: { + initFunc: { + disable: false, + }, controls: { disable: true } }, }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/cards/cards.examples.stories.js b/packages/unity-bootstrap-theme/stories/molecules/cards/cards.examples.stories.js index 8b9f58c812..465ca2f5ac 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/cards/cards.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/cards/cards.examples.stories.js @@ -1530,6 +1530,11 @@ export const RankingCardLarge = () => (
); +RankingCardLarge.parameters = { + initFunc: { + disable: false, + }, +}; RankingCardLarge.decorators = [ defaultDecorator ]; export const RankingCardSmall = () => ( @@ -1598,4 +1603,9 @@ export const RankingCardSmall = () => (
); +RankingCardSmall.parameters = { + initFunc: { + disable: false, + }, +}; RankingCardSmall.decorators = [ defaultDecorator ]; diff --git a/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.templates.stories.js index b80e150c45..f05f97eca8 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/charts-and-graphs/charts-and-graphs.templates.stories.js @@ -6,6 +6,9 @@ export default { title: "Molecules/Charts And Graphs/Templates", decorators: [ defaultDecorator ], parameters: { + initFunc: { + disable: false, + }, controls: { disable: true } }, }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes.examples.stories.js b/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes.examples.stories.js index 32e5f28adf..d9ee2ae957 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/heroes/heroes.examples.stories.js @@ -241,3 +241,9 @@ export const HeroVideo = () => (
); + +HeroVideo.parameters = { + initFunc: { + disable: false, + }, +}; diff --git a/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.examples.stories.js b/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.examples.stories.js index 78f5578371..732f327779 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/image-parallax/image-parallax.examples.stories.js @@ -7,6 +7,9 @@ export default { title: "Molecules/Image Parallax/Examples", decorators: [ defaultDecorator ], parameters: { + initFunc: { + disable: false, + }, controls: { disable: true } } }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.templates.stories.js index dcc1f82c99..9ce3659a71 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/tabbed-panels/tabbed-panels.templates.stories.js @@ -252,5 +252,10 @@ export const TabbedPanels = (args) => { export default { title: "Molecules/Tabbed Panels", component: TabbedPanels, - argTypes: {...extraOptions} + argTypes: {...extraOptions}, + parameters: { + initFunc: { + disable: false, + }, + }, }; diff --git a/packages/unity-bootstrap-theme/stories/molecules/tables/tables.templates.stories.js b/packages/unity-bootstrap-theme/stories/molecules/tables/tables.templates.stories.js index 1d721cf552..e213b36dbd 100644 --- a/packages/unity-bootstrap-theme/stories/molecules/tables/tables.templates.stories.js +++ b/packages/unity-bootstrap-theme/stories/molecules/tables/tables.templates.stories.js @@ -125,3 +125,9 @@ FixedComponent.args = { fixed: true, columns: 7, } +FixedComponent.parameters = { + initFunc: { + disable: false, + }, +}; + diff --git a/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.examples.stories.js b/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.examples.stories.js index 0365865bda..b01700771f 100644 --- a/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/organisms/global-footer/global-footer.examples.stories.js @@ -15,6 +15,9 @@ export default { title: "Organisms/Global Footer/Examples", argTypes: {}, parameters: { + initFunc: { + disable: false, + }, footer: { disable: true }, diff --git a/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.examples.stories.js b/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.examples.stories.js index 864132747b..6b38997e51 100644 --- a/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.examples.stories.js +++ b/packages/unity-bootstrap-theme/stories/organisms/global-header/global-header.examples.stories.js @@ -14,6 +14,9 @@ export default { title: "Organisms/Global Header/Examples", decorators: [ htmlRootDecorator ], parameters: { + initFunc: { + disable: false, + }, header: { disable: true }, diff --git a/packages/unity-bootstrap-theme/vite.config.bundle.js b/packages/unity-bootstrap-theme/vite.config.bundle.js index 1789284ed3..2877d94be8 100644 --- a/packages/unity-bootstrap-theme/vite.config.bundle.js +++ b/packages/unity-bootstrap-theme/vite.config.bundle.js @@ -1,85 +1,53 @@ -import react from "@vitejs/plugin-react"; -import path, { resolve } from "path"; import fs from "fs"; -import { defineConfig, transformWithEsbuild } from "vite"; +import { resolve } from "path"; +import { defineConfig } from "vite"; -import pkg from "./package.json"; -/** @typedef {import('vite').UserConfig} UserConfig */ +import baseConfig from "./vite.config.js"; -/** @type {UserConfig} */ -const c = { - root: resolve(__dirname), - plugins: [ - react(), - { - name: "treat-js-files-as-jsx", - async transform(code, id) { - if (!id.match(/stories\/.*\.js$/)) return null; +export default defineConfig( + (/** @type {import('vite').ConfigEnv} */ _) => { - return transformWithEsbuild(code, id, { - loader: "jsx", - jsx: "automatic", - }); - }, - }, - ], - optimizeDeps: { - esbuildOptions: { - target: "es2021", - loader: { - ".js": "jsx", - }, - }, - }, - build: { - emptyOutDir: false, - sourcemap: true, - cssMinify: true, - cssCodeSplit: false, - lib: { - entry: resolve(__dirname, "src/js/unity-bootstrap-theme.js"), - formats: ["es", "cjs", "umd"], - name: 'unityBootstrap', - fileName: (format) => `js/${format}/unity-bootstrap-theme.js`, - }, - outDir: "dist", - rollupOptions: { - external: [...Object.keys(pkg.peerDependencies), "chart.js"], - treeshake: true, - output: { - globals: { - "chart.js": "Chart", + return { + ...baseConfig, + plugins: [ + { + name: "copy", + writeBundle() { + fs.mkdirSync(resolve(__dirname, "dist/js"), { + recursive: true, + }); + fs.copyFileSync( + resolve( + __dirname, + "../../node_modules", + "bootstrap/dist/js/bootstrap.bundle.min.js" + ), + resolve(__dirname, "dist/js/bootstrap.bundle.min.js") + ); + fs.copyFileSync( + resolve( + __dirname, + "../../node_modules", + "chart.js/dist/chart.min.js" + ), + resolve(__dirname, "dist/js/chart.min.js") + ); + }, }, - assetFileNames: (assetInfo) => { - console.log(assetInfo) - if (assetInfo.originalFileNames && assetInfo.originalFileNames[0]?.includes("bundle")) { - return "css/unity-bootstrap-theme.bundle.[ext]"; - } - return "css/[name].[ext]"; + ], + build: { + ...baseConfig.build, + emptyOutDir: false, + lib: { + entry: resolve(__dirname, "src/js/unity-bootstrap.js"), + formats: ["umd", "cjs", "es"], + name: "unityBootstrap", + }, + rollupOptions: { + ...baseConfig.build.rollupOptions, + input: undefined, }, }, - }, - }, - esbuild: { - loader: "jsx", - include: /.*\.jsx?$/, - exclude: [], - }, - css: { - preprocessorOptions: { - scss: { - api: "modern-compiler", - }, - }, - }, - server: { - port: 9000, - }, - resolve: { - alias: [ - { find: '@shared', replacement: path.resolve(__dirname, '../../shared') }, - ], - }, -}; - -export default defineConfig(c); + }; + } +); diff --git a/packages/unity-bootstrap-theme/vite.config.js b/packages/unity-bootstrap-theme/vite.config.js index e3863eba61..ed3e09081b 100644 --- a/packages/unity-bootstrap-theme/vite.config.js +++ b/packages/unity-bootstrap-theme/vite.config.js @@ -1,12 +1,18 @@ import react from "@vitejs/plugin-react"; -import path, { resolve } from "path"; -import fs from "fs"; +import { resolve } from "path"; import { defineConfig, transformWithEsbuild } from "vite"; import pkg from "./package.json"; -/** @typedef {import('vite').UserConfig} UserConfig */ -/** @type {UserConfig} */ +const getName = ({originalFileNames}) => { + // regex matches string after last slash and before the last dot + // e.g. /path/to/file.css -> file + // e.g. /path/to/file.min.css -> file.min + const name = originalFileNames?.at(0)?.match(/\/([^/]*)?\..*$/).at(1) || "[name]"; + return name; +} + +/** @type {import('vite').UserConfig} */ const c = { root: resolve(__dirname), plugins: [ @@ -15,23 +21,12 @@ const c = { name: "treat-js-files-as-jsx", async transform(code, id) { if (!id.match(/stories\/.*\.js$/)) return null; - return transformWithEsbuild(code, id, { loader: "jsx", jsx: "automatic", }); }, }, - { - name: 'copy-bootstrap-umd-to-dist', - // See https://vite.dev/guide/api-plugin#universal-hooks for closeBundle info - closeBundle() { - const srcPath = path.resolve(__dirname, "../../node_modules", 'bootstrap/dist/js/bootstrap.bundle.min.js'); - const destDir = path.resolve(__dirname, 'dist/js/bootstrap.bundle.min.js'); - - fs.copyFileSync(srcPath, destDir); - } - } ], optimizeDeps: { esbuildOptions: { @@ -46,41 +41,22 @@ const c = { sourcemap: true, cssMinify: true, cssCodeSplit: true, - lib: { - entry: [ - resolve(__dirname, "src/scss/unity-bootstrap-theme.bundle.scss"), - resolve(__dirname, "src/scss/unity-bootstrap-theme.scss"), - resolve(__dirname, "src/scss/unity-bootstrap-header-footer.scss"), - resolve(__dirname, "src/scss/unity-bootstrap-header.scss"), - resolve(__dirname, "src/scss/unity-bootstrap-footer.scss"), - resolve(__dirname, "src/js/global-header.js"), - resolve(__dirname, "src/js/data-layer.js"), - // resolve(__dirname, "../../node_modules/bootstrap/js/index.esm.js"), - ], - - }, outDir: "dist", rollupOptions: { external: [...Object.keys(pkg.peerDependencies), "chart.js"], treeshake: true, + input: [ + resolve(__dirname, "src/scss/unity-bootstrap-theme.bundle.scss"), + resolve(__dirname, "src/scss/unity-bootstrap-theme.scss"), + resolve(__dirname, "src/scss/unity-bootstrap-header-footer.scss"), + ], output: { globals: { "chart.js": "Chart", }, - entryFileNames: chunkInfo => { - if (chunkInfo.name.includes("index.esm")) { - return "js/[format]/bootstrap.bundle.min.js"; - } - return "js/[format]/[name].js"; - }, - chunkFileNames: "js/[format]/[name].js", - assetFileNames: (assetInfo) => { - if (assetInfo.originalFileNames && assetInfo.originalFileNames[0].includes("bundle")) { - return "css/unity-bootstrap-theme.bundle.[ext]"; - } - return "css/[name].[ext]"; - }, - format: "es", + entryFileNames: (info) => `js/${getName(info)}.[format].js`, + chunkFileNames: (info) => `js/${getName(info)}.[format].js`, + assetFileNames: (info) => `css/${getName(info)}.[ext]`, }, }, }, @@ -99,6 +75,14 @@ const c = { server: { port: 9000, }, + resolve: { + alias: [ + { + find: "@shared", + replacement: resolve(__dirname, "../../shared"), + }, + ], + }, }; export default defineConfig(c); From 74254693eaf2ca71e23963ffaa4b836c5f4a1bdc Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 24 Apr 2025 13:38:00 -0700 Subject: [PATCH 12/14] feat(unity-react-core): update storybook to use renamed file unity-bootstrap.js --- packages/unity-react-core/.storybook/preview.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/unity-react-core/.storybook/preview.jsx b/packages/unity-react-core/.storybook/preview.jsx index 01a9458598..673af7e0af 100644 --- a/packages/unity-react-core/.storybook/preview.jsx +++ b/packages/unity-react-core/.storybook/preview.jsx @@ -3,7 +3,7 @@ import "@asu/unity-bootstrap-theme/src/scss/unity-bootstrap-theme.bundle.scss"; import * as bootstrap from "bootstrap/dist/js/bootstrap.bundle.min.js"; globalThis.bootstrap = bootstrap; -import "@asu/unity-bootstrap-theme/src/js/unity-bootstrap-theme.js"; +import "@asu/unity-bootstrap-theme/src/js/unity-bootstrap.js"; import { globalDecorators } from "./decorators.tsx"; import { Container } from "./docPage.tsx"; From ec333b1888cb0c4faacf9a97a8a941fe49b414a7 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 24 Apr 2025 14:03:07 -0700 Subject: [PATCH 13/14] chore: staging site does not have a default page for index.html --- packages/unity-bootstrap-theme/.storybook/local-addon/addon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js b/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js index c21b71102d..47c42bc5ab 100644 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js +++ b/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js @@ -17,7 +17,7 @@ addons.register('local-addon', (api) => { This component requires Javascript.

- View the documentation{" "}on how to use the component in your project. + View the documentation{" "}on how to use the component in your project.
From 26cc48ebb34cc34f6a59c391566d3b08248bbfc1 Mon Sep 17 00:00:00 2001 From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com> Date: Thu, 24 Apr 2025 15:19:16 -0700 Subject: [PATCH 14/14] chore: pr changes --- .../.storybook/local-addon/addon.js | 8 +--- .../docs/GetStarted/get-started.stories.mdx | 40 ++++++++++--------- .../vite.config.bundle.js | 2 +- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js b/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js index 47c42bc5ab..c2539aee21 100644 --- a/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js +++ b/packages/unity-bootstrap-theme/.storybook/local-addon/addon.js @@ -10,15 +10,11 @@ addons.register('local-addon', (api) => { type: types.PANEL, paramKey: 'initFunc', render: ({active, key}) => { - return(
- - This component requires Javascript.

- - View the documentation{" "}on how to use the component in your project. - + This component requires Javascript.

+ View the documentation on including unity in your project
)}, diff --git a/packages/unity-bootstrap-theme/stories/docs/GetStarted/get-started.stories.mdx b/packages/unity-bootstrap-theme/stories/docs/GetStarted/get-started.stories.mdx index 05a39d8b38..41f6e22200 100755 --- a/packages/unity-bootstrap-theme/stories/docs/GetStarted/get-started.stories.mdx +++ b/packages/unity-bootstrap-theme/stories/docs/GetStarted/get-started.stories.mdx @@ -26,28 +26,30 @@ We bundle the necessary CSS and Javascript in the `dist/` folder. There are more ### Javascript All you need to do is include the script on your page, the scripts will execute with the window load event. We provide 3 formats ("UMD", "CJS", "ES"). -* exports: - * `initAnchorMenu`, - * `initBlockquoteAnimation`, - * `initCalendar`, - * `initChart`, - * `initDataLayer`, - * `initFixedTable`, - * `initGlobalHeader`, - * `initHeroesVideo`, - * `initImageParallax`, - * `initModals`, - * `initRankingCard`, - * `initTabbedPanels`, - * `initVideo`, + * Unity File Formats - * dist/js/unity-bootstrap.umd.js (universal) + * `dist/js/unity-bootstrap.umd.js` (universal) * creates a global variable `unityBootstrap` if you need to manaully call the init function ex: `unityBootstrap.initAnchorMenu()` - * dist/js/unity-bootstrap.cjs.js (common js) - * dist/js/unity-bootstrap.es.js (module) + * `dist/js/unity-bootstrap.cjs.js` (common js) + * `dist/js/unity-bootstrap.es.js` (module) * Vendor Files - * dist/js/bootstrap.bundle.min.js (unaltered bootstrap version) - * dist/js/chart.min.js (only needed if you are using the donut chart) + * `dist/js/bootstrap.bundle.min.js` (unaltered bootstrap version) + * `dist/js/chart.min.js` (only needed if you are using the donut chart) + +* Exports: + * `initAnchorMenu` + * `initBlockquoteAnimation` + * `initCalendar` + * `initChart` + * `initDataLayer` + * `initFixedTable` + * `initGlobalHeader` + * `initHeroesVideo` + * `initImageParallax` + * `initModals` + * `initRankingCard` + * `initTabbedPanels` + * `initVideo` ## ❯ How to use the Unity Storybook reference site diff --git a/packages/unity-bootstrap-theme/vite.config.bundle.js b/packages/unity-bootstrap-theme/vite.config.bundle.js index 2877d94be8..7bd3029316 100644 --- a/packages/unity-bootstrap-theme/vite.config.bundle.js +++ b/packages/unity-bootstrap-theme/vite.config.bundle.js @@ -12,7 +12,7 @@ export default defineConfig( plugins: [ { name: "copy", - writeBundle() { + closeBundle() { fs.mkdirSync(resolve(__dirname, "dist/js"), { recursive: true, });