diff --git a/templates/react-javascript/babel.config.js b/templates/react-javascript/babel.config.cjs similarity index 100% rename from templates/react-javascript/babel.config.js rename to templates/react-javascript/babel.config.cjs diff --git a/templates/react-javascript/docs/theming.md b/templates/react-javascript/docs/theming.md new file mode 100644 index 00000000..21f7ef16 --- /dev/null +++ b/templates/react-javascript/docs/theming.md @@ -0,0 +1,278 @@ +# RADFish Theming Guide + +This guide explains how to customize the look and feel of your RADFish application using USWDS, react-uswds, and RADFish theming. + +## Quick Start + +All theme customization happens in a single file: + +``` +themes/noaa-theme/styles/theme.scss +``` + +This file contains three sections: +1. **USWDS Token Variables** - Design system colors (`$primary`, `$secondary`, etc.) +2. **CSS Custom Properties** - Additional CSS variables (`:root { --noaa-* }`) +3. **Component Overrides** - Custom styles for USWDS components + +## How It Works + +The RADFish theme plugin: + +1. **Parses `theme.scss`** and extracts SCSS `$variables` for USWDS configuration +2. **Pre-compiles USWDS** with your color tokens +3. **Compiles theme.scss** to CSS for custom properties and component overrides +4. **Injects CSS** into your app via `` tags in `index.html` +5. **Watches for changes** and auto-recompiles on save + +### Architecture + +``` +themes/noaa-theme/ +├── assets/ # Icons and logos +│ ├── logo.png # Header logo +│ ├── favicon.ico # Browser favicon +│ ├── icon-144.png # PWA icon +│ ├── icon-192.png # PWA icon +│ └── icon-512.png # PWA icon +└── styles/ + └── theme.scss # All theme configuration (edit this) + +node_modules/.cache/radfish-theme/noaa-theme/ # Auto-generated (don't edit) +├── _uswds-entry.scss # Generated USWDS config +├── uswds-precompiled.css # Compiled USWDS styles +├── theme.css # Compiled theme overrides +└── .uswds-cache.json # Cache manifest +``` + +## Section 1: USWDS Token Variables + +At the top of `theme.scss`, define SCSS variables that configure the USWDS design system: + +```scss +/* themes/noaa-theme/styles/theme.scss */ + +// Primary colors +$primary: #0055a4; +$primary-dark: #00467f; +$primary-light: #59b9e0; + +// Secondary colors +$secondary: #007eb5; +$secondary-dark: #006a99; + +// State colors +$error: #d02c2f; +$success: #4c9c2e; +$warning: #ff8300; +$info: #1ecad3; + +// Base/neutral colors +$base-lightest: #ffffff; +$base-lighter: #e8e8e8; +$base: #71767a; +$base-darkest: #333333; +``` + +### Available USWDS Tokens + +- **Base**: `base-lightest`, `base-lighter`, `base-light`, `base`, `base-dark`, `base-darker`, `base-darkest` +- **Primary**: `primary-lighter`, `primary-light`, `primary`, `primary-vivid`, `primary-dark`, `primary-darker` +- **Secondary**: `secondary-lighter`, `secondary-light`, `secondary`, `secondary-vivid`, `secondary-dark`, `secondary-darker` +- **Accent Cool**: `accent-cool-lighter`, `accent-cool-light`, `accent-cool`, `accent-cool-dark`, `accent-cool-darker` +- **Accent Warm**: `accent-warm-lighter`, `accent-warm-light`, `accent-warm`, `accent-warm-dark`, `accent-warm-darker` +- **State**: `info`, `error`, `warning`, `success` (with `-lighter`, `-light`, `-dark`, `-darker` variants) +- **Disabled**: `disabled-light`, `disabled`, `disabled-dark` + +See [USWDS Design Tokens](https://designsystem.digital.gov/design-tokens/color/theme-tokens/) for complete list. + +## Section 2: CSS Custom Properties + +Add custom CSS variables in the `:root` block for agency-specific colors: + +```scss +/* themes/noaa-theme/styles/theme.scss */ + +:root { + // Brand colors + --noaa-process-blue: #0093D0; + --noaa-reflex-blue: #0055A4; + + // Regional colors + --noaa-region-alaska: #FF8300; + --noaa-region-west-coast: #4C9C2E; + --noaa-region-southeast: #B2292E; +} +``` + +Use these in your application CSS: +```css +.region-badge--alaska { + background-color: var(--noaa-region-alaska); +} +``` + +### Auto-Generated CSS Variables + +The plugin also auto-generates `--radfish-color-*` variables from your USWDS tokens: + +- `--radfish-color-primary` +- `--radfish-color-secondary` +- `--radfish-color-error` +- `--radfish-color-success` +- etc. + +## Section 3: Component Overrides + +At the bottom of `theme.scss`, add custom CSS for USWDS components: + +```scss +/* themes/noaa-theme/styles/theme.scss */ + +/* Header Background */ +.usa-header.header-container, +header.usa-header { + background-color: var(--radfish-color-primary); +} + +/* Custom button styles */ +.usa-button { + border-radius: 8px; + font-weight: 600; +} + +/* Custom card styles */ +.usa-card { + border-color: #ddd; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} +``` + +### Available USWDS Components + +**Layout & Navigation**: `usa-header`, `usa-footer`, `usa-sidenav`, `usa-breadcrumb`, `usa-banner` + +**Forms & Inputs**: `usa-button`, `usa-input`, `usa-checkbox`, `usa-radio`, `usa-select`, `usa-form` + +**Content & Display**: `usa-card`, `usa-alert`, `usa-table`, `usa-list`, `usa-accordion`, `usa-tag` + +**Interactive**: `usa-modal`, `usa-tooltip`, `usa-pagination` + +## Developer Styles + +For application-specific styles (not theme-related), use: + +``` +src/styles/style.css +``` + +This file is loaded after theme styles, so you can override anything: + +```css +/* src/styles/style.css */ + +.dashboard-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; +} + +.fish-data-card { + background: var(--radfish-color-base-lightest); + border: 1px solid #ddd; + padding: 1.5rem; +} +``` + +## Configuration + +In `vite.config.js`, configure the app name and description: + +```javascript +const configOverrides = { + app: { + name: "My App Name", + shortName: "MyApp", + description: "App description for PWA", + }, +}; + +radFishThemePlugin("noaa-theme", configOverrides) +``` + +The theme name matches the folder in `themes/` directory. + +## Changing Assets + +Replace files in `themes/noaa-theme/assets/` to customize: + +| File | Purpose | Recommended Size | +|------|---------|------------------| +| `logo.png` | Header logo | Height ~48-72px | +| `favicon.ico` | Browser tab icon | 64x64, 32x32, 16x16 | +| `icon-144.png` | PWA icon | 144x144 | +| `icon-192.png` | PWA icon | 192x192 | +| `icon-512.png` | PWA icon/splash | 512x512 | + +## Creating a New Theme + +1. Create theme folder: + ```bash + mkdir -p themes/my-agency/assets themes/my-agency/styles + ``` + +2. Add assets to `themes/my-agency/assets/`: + - `logo.png`, `favicon.ico`, `icon-144.png`, `icon-192.png`, `icon-512.png` + +3. Copy and customize the theme file: + ```bash + cp themes/noaa-theme/styles/theme.scss themes/my-agency/styles/ + ``` + +4. Update `vite.config.js`: + ```javascript + radFishThemePlugin("my-agency", { + app: { name: "My Agency App" } + }) + ``` + +5. Restart the dev server + +## CSS Load Order + +Styles are loaded in this order: + +1. **uswds-precompiled.css** - USWDS with your color tokens +2. **theme.css** - Your CSS custom properties and component overrides +3. **src/styles/style.css** - Your application styles + +This ensures correct CSS cascade: USWDS base → Theme overrides → App styles + +## Troubleshooting + +### Changes not appearing? + +- Save `theme.scss` - the dev server auto-restarts on changes +- Clear browser cache: Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac) +- Restart dev server: `npm start` + +### Styles not applying? + +- Check CSS specificity - you may need more specific selectors +- Inspect element in DevTools to see which styles are being applied +- Ensure your selectors match USWDS class names exactly + +### Cache issues? + +Delete the cache folder and restart: +```bash +rm -rf node_modules/.cache/radfish-theme +npm start +``` + +## Additional Resources + +- [USWDS Design System](https://designsystem.digital.gov/) +- [USWDS Design Tokens](https://designsystem.digital.gov/design-tokens/) +- [USWDS Components](https://designsystem.digital.gov/components/) +- [React USWDS (Trussworks)](https://trussworks.github.io/react-uswds/) diff --git a/templates/react-javascript/index.html b/templates/react-javascript/index.html index 565b3820..2a69826e 100644 --- a/templates/react-javascript/index.html +++ b/templates/react-javascript/index.html @@ -2,16 +2,16 @@ - + - - + + - + + + `; + + // Generate CSS variables from config + const cssVariables = ` + `; + + return html + .replace("", `${cssImports}\n${cssVariables}\n `) + .replace( + /.*?<\/title>/, + `<title>${config.app.shortName}`, + ) + .replace( + //, + ``, + ) + .replace( + //, + ``, + ) + .replace( + //, + ``, + ) + .replace( + //, + ``, + ); + }, + + // Write manifest.json after build completes + closeBundle() { + if (!config || !resolvedViteConfig) return; + + // Only write manifest for build, not serve + const outDir = resolvedViteConfig.build?.outDir || "dist"; + const outDirPath = path.resolve(resolvedViteConfig.root, outDir); + const manifestPath = path.resolve(outDirPath, "manifest.json"); + + // Ensure output directory exists + if (!fs.existsSync(outDirPath)) { + return; // Build hasn't created output dir yet + } + + // Copy theme assets to dist/icons if using theme directory + if (themeDir) { + const themeAssetsDir = path.join(themeDir, "assets"); + const distIconsDir = path.join(outDirPath, "icons"); + if (fs.existsSync(themeAssetsDir)) { + copyDirSync(themeAssetsDir, distIconsDir); + console.log("[radfish-theme] Copied theme assets to:", distIconsDir); + } + + // Copy pre-compiled CSS files to dist/radfish-theme/ + const cacheDir = getCacheDir(themeName); + const distThemeDir = path.join(outDirPath, "radfish-theme"); + if (fs.existsSync(cacheDir)) { + if (!fs.existsSync(distThemeDir)) { + fs.mkdirSync(distThemeDir, { recursive: true }); + } + const cssFiles = ["uswds-precompiled.css", "theme.css"]; + for (const cssFile of cssFiles) { + const srcPath = path.join(cacheDir, cssFile); + const destPath = path.join(distThemeDir, cssFile); + if (fs.existsSync(srcPath)) { + fs.copyFileSync(srcPath, destPath); + } + } + console.log("[radfish-theme] Copied CSS files to:", distThemeDir); + } + } + + const manifest = { + short_name: config.app.shortName, + name: config.app.name, + description: config.app.description, + icons: getManifestIcons(), + start_url: ".", + display: "standalone", + theme_color: config.pwa.themeColor, + background_color: config.pwa.backgroundColor, + }; + + fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2)); + console.log("[radfish-theme] Wrote manifest.json to", manifestPath); + }, + }; +} diff --git a/templates/react-javascript/src/App.jsx b/templates/react-javascript/src/App.jsx index d333f639..4c8c0543 100644 --- a/templates/react-javascript/src/App.jsx +++ b/templates/react-javascript/src/App.jsx @@ -1,10 +1,31 @@ +/** + * App.jsx - Main Application Component + * + * Welcome to RADFish! This is the entry point for your application. + * + * This file sets up: + * - The Application wrapper (provides offline storage, state management) + * - Header with navigation + * - React Router for page routing + * + * Quick Start: + * 1. Add new pages in src/pages/ + * 2. Add routes in the section below + * 3. Add navigation links in the PrimaryNav items array + * + * Theme customization: + * - Edit themes/noaa-theme/styles/theme.scss for colors and styles + * - App name and icons are configured in the theme plugin (vite.config.js) + * + * Learn more: https://nmfs-radfish.github.io/radfish/ + */ + import "./index.css"; import { BrowserRouter, Routes, Route, Link } from "react-router-dom"; import { useState } from "react"; import { Application } from "@nmfs-radfish/react-radfish"; import { GridContainer, - Title, NavMenuButton, PrimaryNav, Header, @@ -14,6 +35,7 @@ import HomePage from "./pages/Home"; function App({ application }) { const [isExpanded, setExpanded] = useState(false); + return ( @@ -21,6 +43,7 @@ function App({ application }) {
+ {/* Header - Uses USWDS Header component */}
- RADFish Application + + {import.meta.env.RADFISH_APP_NAME} + setExpanded((prvExpanded) => !prvExpanded)} + onClick={() => setExpanded((prev) => !prev)} label="Menu" />
+ + {/* Navigation - Add your nav links here */} Home , + // Add more navigation links here: + // About, ]} mobileExpanded={isExpanded} - onToggleMobileNav={() => - setExpanded((prvExpanded) => !prvExpanded) - } - > + onToggleMobileNav={() => setExpanded((prev) => !prev)} + />
+ + {/* Main Content Area */} } /> + {/* Add more routes here: + } /> + */}
diff --git a/templates/react-javascript/src/index.css b/templates/react-javascript/src/index.css index 3bfaa65a..2b4fe62f 100644 --- a/templates/react-javascript/src/index.css +++ b/templates/react-javascript/src/index.css @@ -1,6 +1,13 @@ -/* trussworks component styles */ -@import "@trussworks/react-uswds/lib/uswds.css"; -@import "@trussworks/react-uswds/lib/index.css"; +/* Main CSS Entry Point */ +/* + * Theme CSS imports (USWDS, theme-components, theme-overrides) are + * automatically injected by the RADFish Vite plugin into index.html. + * + * This file is for developer-specific styles only. + */ + +/* Developer's page-level custom styles */ +@import "./styles/style.css"; /* normalize css */ body { @@ -21,6 +28,24 @@ body { width: 100%; } +.header-logo-link { + display: flex; + align-items: center; +} + +.header-logo { + height: 48px; + width: auto; +} + +/* Keep menu button on the right on mobile/tablet */ +.usa-navbar { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +} + @media (min-width: 64em) { .usa-nav__primary button[aria-expanded=false] span:after { background: white; diff --git a/templates/react-javascript/src/index.jsx b/templates/react-javascript/src/index.jsx index 5ed01d1f..bd0efb23 100644 --- a/templates/react-javascript/src/index.jsx +++ b/templates/react-javascript/src/index.jsx @@ -1,12 +1,15 @@ import React from "react"; import ReactDOM from "react-dom/client"; -import "./styles/theme.css"; import App from "./App"; import { Application } from "@nmfs-radfish/radfish"; const root = ReactDOM.createRoot(document.getElementById("root")); -const app = new Application(); +const app = new Application({ + serviceWorker: { + url: "/service-worker.js", + }, +}); app.on("ready", async () => { root.render( diff --git a/templates/react-javascript/src/pages/Home.jsx b/templates/react-javascript/src/pages/Home.jsx index 2a993a26..85dc0bd0 100644 --- a/templates/react-javascript/src/pages/Home.jsx +++ b/templates/react-javascript/src/pages/Home.jsx @@ -1,24 +1,81 @@ +/** + * Home.jsx - Welcome Page + * + * This is the default home page for your RADFish application. + * Replace this content with your own! + */ + import "../index.css"; -import React from "react"; import { Button } from "@trussworks/react-uswds"; import { Link } from "react-router-dom"; function HomePage() { return ( -
- RADFish logo -

- Edit src/App.js and save to reload. -

-

- - - -

-
+
+

Welcome to RADFish

+ +

+ You're ready to start building your fisheries data collection application. + This template includes everything you need to get started. +

+ +

Quick Start

+
    +
  • + Edit vite.config.js to change app name and description +
  • +
  • + Edit src/App.jsx to modify the header and navigation +
  • +
  • + Edit src/pages/Home.jsx to change this page +
  • +
  • + Replace images in themes/noaa-theme/assets/ to change logo and favicon +
  • +
+ +

What's Included

+
    +
  • + USWDS Components - U.S. Web Design System via react-uswds +
  • +
  • + Offline Storage - IndexedDB for offline-first data collection +
  • +
  • + Theming - Customizable NOAA brand colors and styles +
  • +
  • + PWA Ready - Progressive Web App support for mobile deployment +
  • +
+ +

Resources

+

+ + + {" "} + + + {" "} + + + {" "} + + + +

+
); } diff --git a/templates/react-javascript/src/styles/style.css b/templates/react-javascript/src/styles/style.css new file mode 100644 index 00000000..4d9fdea9 --- /dev/null +++ b/templates/react-javascript/src/styles/style.css @@ -0,0 +1,37 @@ +/** + * Developer Page-Level Custom Styles + * + * Add your application-specific page and layout styles here. + * This file is for styling YOUR OWN pages/layouts, NOT theme config or component overrides. + * + * For different types of customization: + * - USWDS theme colors → themes//styles/theme.scss (Section 1) + * - RADFish components → themes//styles/theme.scss (Section 2) + * - react-uswds overrides → themes//styles/theme.scss (Section 3) + * - Page/layout styles → THIS FILE + * + * Examples: + */ + +/* Page-specific layouts +.dashboard-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; +} +*/ + +/* Custom application components +.fish-data-card { + background: var(--radfish-background); + border: 1px solid var(--radfish-border-light); + padding: 1.5rem; +} + +.catch-summary-badge { + background-color: var(--radfish-primary); + color: white; + padding: 0.25rem 0.75rem; + border-radius: 4px; +} +*/ \ No newline at end of file diff --git a/templates/react-javascript/src/styles/theme.css b/templates/react-javascript/src/styles/theme.css deleted file mode 100644 index 92b1e2d3..00000000 --- a/templates/react-javascript/src/styles/theme.css +++ /dev/null @@ -1,37 +0,0 @@ -:root { - --noaa-dark-blue: #0054a4; - --noaa-light-blue: #0093d0; - --noaa-yellow-one: #fff3cd; - --noaa-yellow-two: #ffeeba; - --noaa-yellow-three: #856404; - --noaa-accent-color: #00467f; - --noaa-text-color: #333; - --noaa-error-color: #af292e; - --noaa-button-hover: #0073b6; - --noaa-label-color: #0054a4; - --noaa-border-dark: #565c65; - --noaa-border-light: #ddd; -} - -body { - font-family: - Arial Narrow, - sans-serif; - color: var(--noaa-text-color); - background-color: #f4f4f4; - line-height: 1.6; - border-radius: 4px; -} - -.header-container { - background: var(--noaa-dark-blue); -} - -.header-title { - color: white; -} - -/* Minimum size for NOAA logo must be 72px (0.75 in) */ -.header-logo { - width: 72px; -} diff --git a/templates/react-javascript/themes/noaa-theme/assets/favicon.ico b/templates/react-javascript/themes/noaa-theme/assets/favicon.ico new file mode 100644 index 00000000..b3daf0af Binary files /dev/null and b/templates/react-javascript/themes/noaa-theme/assets/favicon.ico differ diff --git a/templates/react-javascript/themes/noaa-theme/assets/icon-144.png b/templates/react-javascript/themes/noaa-theme/assets/icon-144.png new file mode 100644 index 00000000..e82b34ba Binary files /dev/null and b/templates/react-javascript/themes/noaa-theme/assets/icon-144.png differ diff --git a/templates/react-javascript/themes/noaa-theme/assets/icon-192.png b/templates/react-javascript/themes/noaa-theme/assets/icon-192.png new file mode 100644 index 00000000..0457a794 Binary files /dev/null and b/templates/react-javascript/themes/noaa-theme/assets/icon-192.png differ diff --git a/templates/react-javascript/themes/noaa-theme/assets/icon-512.png b/templates/react-javascript/themes/noaa-theme/assets/icon-512.png new file mode 100644 index 00000000..3bb3ed58 Binary files /dev/null and b/templates/react-javascript/themes/noaa-theme/assets/icon-512.png differ diff --git a/templates/react-javascript/themes/noaa-theme/assets/logo.png b/templates/react-javascript/themes/noaa-theme/assets/logo.png new file mode 100644 index 00000000..3c797585 Binary files /dev/null and b/templates/react-javascript/themes/noaa-theme/assets/logo.png differ diff --git a/templates/react-javascript/themes/noaa-theme/styles/theme.scss b/templates/react-javascript/themes/noaa-theme/styles/theme.scss new file mode 100644 index 00000000..f002e472 --- /dev/null +++ b/templates/react-javascript/themes/noaa-theme/styles/theme.scss @@ -0,0 +1,244 @@ +/** + * NOAA Fisheries Brand Theme + * + * This single file contains all theme configuration: + * 1. USWDS Token Variables ($variables) - extracted by the RADFish plugin for USWDS configuration + * 2. CSS Custom Properties (:root) - additional NOAA-specific variables + * 3. Component Overrides - custom styles for USWDS/RADFish components + * + * NOAA Palette → USWDS Token Mapping: + * NOAA Dark Blue (Reflex Blue #0055A4) → primary-* + * NOAA Light Blue (Process Blue #0093D0) → secondary-* + * URCHIN (Purples) → accent-cool-* + * CRUSTACEAN (Orange) → accent-warm-* + * SEAGRASS (Greens) → success-* + * CORAL (Reds) → error-* + * Neutrals → base-* + */ + +// ============================================================================= +// SECTION 1: USWDS TOKEN VARIABLES +// These $variables are extracted by the RADFish plugin and fed to USWDS. +// They configure the design system colors but don't produce CSS output directly. +// ============================================================================= + +// ----------------------------------------------------------------------------- +// BASE COLORS - NOAA Neutrals +// ----------------------------------------------------------------------------- +$base-lightest: #ffffff; +$base-lighter: #e8e8e8; +$base-light: #d0d0d0; +$base: #71767a; // USWDS gray-50 (better contrast) +$base-dark: #7b7b7b; +$base-darker: #4a4a4a; // Darkened for AA contrast with base-lighter links +$base-darkest: #333333; + +// ----------------------------------------------------------------------------- +// PRIMARY - NOAA Dark Blue (Reflex Blue) +// Main brand color from NOAA Fisheries Primary Palette +// ----------------------------------------------------------------------------- +$primary-lighter: #b2def1; // 15% tint +$primary-light: #59b9e0; // 30% tint +$primary: #0055a4; // Reflex Blue - NOAA Dark Blue (main brand) +$primary-vivid: #0055a4; // Reflex Blue +$primary-dark: #00467f; // Navy Blue (Pantone 541) +$primary-darker: #002d4d; // Darker Navy + +// ----------------------------------------------------------------------------- +// SECONDARY - NOAA Light Blue (Process Blue) +// From NOAA Fisheries Primary Palette +// ----------------------------------------------------------------------------- +$secondary-lighter: #d9eff8; // 15% tint +$secondary-light: #59b9e0; // 30% tint +$secondary: #007eb5; // Darkened Process Blue for AA contrast +$secondary-vivid: #0093d0; // Process Blue (original) +$secondary-dark: #006a99; // Darker for AA contrast with white text +$secondary-darker: #00557a; // Darkest Process Blue + +// ----------------------------------------------------------------------------- +// ACCENT-COOL - URCHIN (Purples) +// ----------------------------------------------------------------------------- +$accent-cool-lighter: #c9c9ff; // Light tint +$accent-cool-light: #9f9fff; // Mid tint +$accent-cool: #5a5ae6; // Darkened for AA contrast with white text +$accent-cool-dark: #625bc4; // PMS 2725 +$accent-cool-darker: #575195; // PMS 7670 + +// ----------------------------------------------------------------------------- +// ACCENT-WARM - CRUSTACEAN (Oranges) +// ----------------------------------------------------------------------------- +$accent-warm-lighter: #ffd9b3; // Light tint +$accent-warm-light: #ffb366; // Mid tint +$accent-warm: #ff8300; // PMS 151 +$accent-warm-dark: #b54d00; // Darkened for AA contrast with white text +$accent-warm-darker: #bc4700; // PMS 1525 + +// ----------------------------------------------------------------------------- +// STATE COLORS +// ----------------------------------------------------------------------------- + +// INFO - WAVES (Teal) +$info-lighter: #e0f7f8; +$info-light: #5de0e6; +$info: #1ecad3; // PMS 319 +$info-dark: #008998; // PMS 321 +$info-darker: #007078; // PMS 322 + +// ERROR - CORAL (Red) +$error-lighter: #ffe5e4; +$error-light: #ff7a73; +$error: #d02c2f; // PMS 711 +$error-dark: #b2292e; // PMS 1805 +$error-darker: #8b1f24; + +// WARNING - CRUSTACEAN (Orange) +$warning-lighter: #fff3e0; +$warning-light: #ffd9b3; +$warning: #ff8300; // PMS 151 +$warning-dark: #d65f00; // PMS 717 +$warning-darker: #bc4700; // PMS 1525 + +// SUCCESS - SEAGRASS (Greens) +$success-lighter: #e8f5d6; // Light tint +$success-light: #b8e67d; // Mid tint +$success: #93d500; // PMS 375 +$success-dark: #4c9c2e; // PMS 362 +$success-darker: #007934; // PMS 356 + +// ----------------------------------------------------------------------------- +// DISABLED STATE +// ----------------------------------------------------------------------------- +$disabled-light: #e8e8e8; +$disabled: #d0d0d0; +$disabled-dark: #9a9a9a; + + +// ============================================================================= +// SECTION 2: CSS CUSTOM PROPERTIES +// These extend the USWDS theme tokens for NOAA-specific needs. +// Available throughout your application via var(--noaa-*). +// ============================================================================= + +:root { + // --------------------------------------------------------------------------- + // NOAA PRIMARY BRAND COLORS (Direct Access) + // For cases where you need exact brand colors + // --------------------------------------------------------------------------- + --noaa-process-blue: #0093D0; // NOAA Light Blue + --noaa-reflex-blue: #0055A4; // NOAA Dark Blue + --noaa-navy-blue: #00467F; // PMS 541 + + // --------------------------------------------------------------------------- + // REGIONAL WEB COLORS + // For region-specific styling, badges, and indicators + // --------------------------------------------------------------------------- + --noaa-region-national: #0055A4; // Blue (Reflex Blue) + --noaa-region-west-coast: #4C9C2E; // Green (PMS 362) + --noaa-region-southeast: #B2292E; // Red (PMS 1805) + --noaa-region-alaska: #FF8300; // Orange (PMS 151) + --noaa-region-pacific-islands: #625BC4; // Purple (PMS 2725) + --noaa-region-mid-atlantic: #625BC4; // Purple (PMS 2725) + + // --------------------------------------------------------------------------- + // THEME PALETTE QUICK ACCESS + // All six NOAA theme palettes for easy reference + // --------------------------------------------------------------------------- + + // OCEANS (mapped to primary-*) + --noaa-oceans-light: #0093D0; + --noaa-oceans: #0055A4; + --noaa-oceans-dark: #00467F; + + // WAVES (mapped to accent-cool-*) + --noaa-waves-light: #1ECAD3; + --noaa-waves: #008998; + --noaa-waves-dark: #007078; + + // SEAGRASS (mapped to success-*) + --noaa-seagrass-light: #93D500; + --noaa-seagrass: #4C9C2E; + --noaa-seagrass-dark: #007934; + + // CRUSTACEAN (mapped to accent-warm-*) + --noaa-crustacean-light: #FF8300; + --noaa-crustacean: #D65F00; + --noaa-crustacean-dark: #BC4700; + + // CORAL (mapped to secondary-*) + --noaa-coral-light: #FF4438; + --noaa-coral: #D02C2F; + --noaa-coral-dark: #B2292E; +} + + +// ============================================================================= +// SECTION 3: COMPONENT OVERRIDES +// Customize RADFish and USWDS components here. +// +// Available CSS variables (injected by RADFish plugin): +// var(--radfish-color-primary) - Primary brand color +// var(--radfish-color-primary-dark) - Darker primary +// var(--radfish-color-secondary) - Secondary color +// var(--radfish-color-secondary-dark) - Darker secondary +// var(--radfish-color-accent-cool) - Cool accent (teal) +// var(--radfish-color-accent-warm) - Warm accent (orange) +// var(--radfish-color-base-lightest) - Lightest gray +// var(--radfish-color-error) - Error red +// var(--radfish-color-success) - Success green +// var(--radfish-color-warning) - Warning orange +// +// Available react-uswds components to override: +// Layout & Navigation: usa-header, usa-footer, usa-sidenav, usa-breadcrumb +// Forms & Inputs: usa-button, usa-input, usa-checkbox, usa-radio, usa-select +// Content & Display: usa-card, usa-alert, usa-table, usa-list, usa-accordion +// Interactive: usa-modal, usa-tooltip, usa-pagination, usa-language-selector +// +// See: https://designsystem.digital.gov/components/overview/ +// ============================================================================= + +// ----------------------------------------------------------------------------- +// HEADER +// ----------------------------------------------------------------------------- + +/* Header Background */ +.usa-header.usa-header--basic.header-container, +.usa-header.header-container, +header.usa-header { + background-color: var(--radfish-color-primary); +} + +/* Header Logo Width - Minimum 72px for agency logos */ + +// ----------------------------------------------------------------------------- +// EXAMPLE OVERRIDES (uncomment to use) +// ----------------------------------------------------------------------------- + +/* Example: Regional badge styling */ +/* +.region-badge { + padding: 0.25rem 0.75rem; + border-radius: 4px; + font-size: 0.875rem; + font-weight: 600; + color: white; +} + +.region-badge--national { background-color: var(--noaa-region-national); } +.region-badge--west-coast { background-color: var(--noaa-region-west-coast); } +.region-badge--southeast { background-color: var(--noaa-region-southeast); } +.region-badge--alaska { background-color: var(--noaa-region-alaska); } +.region-badge--pacific-islands { background-color: var(--noaa-region-pacific-islands); } +.region-badge--mid-atlantic { background-color: var(--noaa-region-mid-atlantic); } +*/ + +/* Example: Custom button styles */ +/* .usa-button { + border-radius: 8px; + font-weight: 600; +} */ + +/* Example: Custom card styles */ +/* .usa-card { + border-color: color("base-light"); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} */ diff --git a/templates/react-javascript/vite.config.js b/templates/react-javascript/vite.config.js index e5d836a4..66cfc900 100644 --- a/templates/react-javascript/vite.config.js +++ b/templates/react-javascript/vite.config.js @@ -1,11 +1,75 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import { VitePWA } from "vite-plugin-pwa"; +import path from "path"; +import { radFishThemePlugin, getDefaultConfig } from "./plugins/vite-plugin-radfish-theme.js"; -export default defineConfig((env) => ({ +/** + * RADFish Theme Configuration + * + * IMPORTANT: Change theme settings in ONE place: + * themes/noaa-theme/styles/theme.scss + * + * The radFishThemePlugin automatically: + * - Parses theme.scss and generates _uswds-generated.scss + * - Injects CSS variables into index.html + * - Updates index.html meta tags + * - Provides values to PWA manifest (below) + * + * Usage: + * radFishThemePlugin("noaa-theme") // Use default NOAA theme + * radFishThemePlugin("noaa-theme", { app: {...} }) // With app config overrides + * + * Available themes (in themes/ folder): + * - noaa-theme: Default NOAA branding with USWDS colors + */ + +// Get default config (includes parsed colors as fallback) +const defaultConfig = getDefaultConfig(); + +// Define config overrides here (app name, description) +// NOTE: Colors automatically come from themes//styles/theme.scss (Section 1) +const configOverrides = { + app: { + name: "RADFish App", + shortName: "RADFish", + description: "Offline-first fisheries data collection built with RADFish", + }, + pwa: { + // NOTE: The PWA manifest theme_color is dynamically generated by radFishThemePlugin + // It reads the actual color from themes//styles/theme.scss (Section 1) + // The defaultConfig.colors.primary below is just a fallback used during config parsing + // In dev mode: manifest.json is served via configureServer hook with parsed colors + // In build: manifest.json is written via closeBundle hook with parsed colors + themeColor: defaultConfig.colors.primary, + }, +}; + +export default defineConfig({ base: "/", + resolve: { + alias: { + '@theme': path.resolve(__dirname, 'themes/noaa-theme/styles'), + }, + }, + css: { + preprocessorOptions: { + scss: { + includePaths: ["node_modules/@uswds/uswds/packages"], + // Suppress USWDS deprecation warnings about global built-in functions + // These are from USWDS using map-merge() which will be fixed in Dart Sass 3.0.0 + quietDeps: true, + }, + }, + }, plugins: [ + // RADFish theme plugin - provides: + // - import.meta.env.RADFISH_* constants + // - CSS variable injection + // - manifest.json generation on build + radFishThemePlugin("noaa-theme", configOverrides), react(), + // VitePWA for service worker VitePWA({ devOptions: { enabled: process.env.NODE_ENV === "development", @@ -16,66 +80,15 @@ export default defineConfig((env) => ({ strategies: "injectManifest", srcDir: "src", filename: "service-worker.js", + // Manifest configuration (synced with radFishThemePlugin configOverrides) manifest: { - short_name: "RADFish", - name: "RADFish React Boilerplate", - icons: [ - { - src: "icons/radfish.ico", - sizes: "512x512 256x256 144x144 64x64 32x32 24x24 16x16", - type: "image/x-icon", - }, - { - src: "icons/radfish-144.ico", - sizes: "144x144 64x64 32x32 24x24 16x16", - type: "image/x-icon", - }, - { - src: "icons/radfish-144.ico", - type: "image/icon", - sizes: "144x144", - purpose: "any", - }, - { - src: "icons/radfish-192.ico", - type: "image/icon", - sizes: "192x192", - purpose: "any", - }, - { - src: "icons/radfish-512.ico", - type: "image/icon", - sizes: "512x512", - purpose: "any", - }, - { - src: "icons/144.png", - type: "image/png", - sizes: "144x144", - purpose: "any", - }, - { - src: "icons/144.png", - type: "image/png", - sizes: "144x144", - purpose: "maskable", - }, - { - src: "icons/192.png", - type: "image/png", - sizes: "192x192", - purpose: "maskable", - }, - { - src: "icons/512.png", - type: "image/png", - sizes: "512x512", - purpose: "maskable", - }, - ], - start_url: ".", + short_name: configOverrides.app.shortName, + name: configOverrides.app.name, + description: configOverrides.app.description, + start_url: "/", display: "standalone", - theme_color: "#000000", + scope: "/", + theme_color: configOverrides.pwa.themeColor, background_color: "#ffffff", }, }), @@ -89,4 +102,4 @@ export default defineConfig((env) => ({ setupFiles: "./src/__tests__/setup.js", environment: "jsdom", }, -})); +});