Simplify Testing Structure #28
@@ -1,57 +1,35 @@
|
||||
name: CI Pipeline
|
||||
run-name: ${{ gitea.actor }} triggered CI pipeline
|
||||
run-name: "${{ gitea.actor }} triggered CI pipeline"
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
pull_request:
|
||||
branches: [main, develop] # PRs into main/develop
|
||||
branches: [main]
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
env:
|
||||
NODE_VERSION: "20"
|
||||
NEXT_TELEMETRY_DISABLED: "1"
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: [self-hosted, macos-latest]
|
||||
strategy:
|
||||
matrix: { node-version: [18, 20] }
|
||||
env:
|
||||
NODE_OPTIONS: "--max_old_space_size=8192 --max_semi_space_size=128"
|
||||
CI: true
|
||||
VITEST_MAX_CONCURRENCY: 1
|
||||
VITEST_MAX_THREADS: 1
|
||||
VITEST_MIN_THREADS: 1
|
||||
VITEST_POOL: "vmThreads"
|
||||
VITEST_POOL_OPTIONS: '{"vmThreads":{"singleThread":true}}'
|
||||
VITEST_LOG_LEVEL: "info"
|
||||
DEBUG: "vitest:*"
|
||||
VITEST_WORKER_TIMEOUT: "300000"
|
||||
VITEST_POOL_TIMEOUT: "300000"
|
||||
VITEST_FORCE_RERUN_TRIGGERS: "**"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: "${{ env.NODE_VERSION }}"
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- name: Show system info
|
||||
run: |
|
||||
echo "Node.js version: $(node -v)"
|
||||
echo "NPM version: $(npm -v)"
|
||||
echo "Available memory: $(free -h || vm_stat | head -10)"
|
||||
echo "CPU info: $(sysctl -n machdep.cpu.brand_string || uname -m)"
|
||||
- run: |
|
||||
echo "Running tests with CI optimizations..."
|
||||
# Run tests in smaller batches to avoid resource contention
|
||||
echo "Running unit tests..."
|
||||
npm test -- tests/unit/ --run --reporter=verbose --no-coverage --maxConcurrency=1
|
||||
echo "Running integration tests..."
|
||||
npm test -- tests/integration/ --run --reporter=verbose --no-coverage --maxConcurrency=1
|
||||
echo "Running accessibility tests..."
|
||||
npm test -- tests/accessibility/ --run --reporter=verbose --no-coverage --maxConcurrency=1
|
||||
- run: npm ci --no-audit --fund=false
|
||||
- run: npm test -- --reporter=dot --maxConcurrency=1
|
||||
# If the Codecov Action fails on Gitea, replace this with the bash uploader below
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
token: "${{ secrets.CODECOV_TOKEN }}"
|
||||
files: ./coverage/lcov.info
|
||||
flags: unittests
|
||||
|
||||
@@ -64,23 +42,22 @@ jobs:
|
||||
e2e:
|
||||
runs-on: [self-hosted, macos-latest]
|
||||
strategy:
|
||||
matrix: { browser: [chromium, firefox, webkit] }
|
||||
matrix:
|
||||
browser: [chromium, firefox, webkit]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url == 'https://github.com' }}
|
||||
with: { node-version: 20, cache: npm }
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url != 'https://github.com' || !github.server_url }}
|
||||
with: { node-version: 20 }
|
||||
- run: npm ci
|
||||
with:
|
||||
node-version: "${{ env.NODE_VERSION }}"
|
||||
cache: npm
|
||||
- run: npm ci --no-audit --fund=false
|
||||
- name: Install Playwright
|
||||
run: npx playwright install --with-deps ${{ matrix.browser }}
|
||||
run: "npx playwright install --with-deps ${{ matrix.browser }}"
|
||||
- run: npm run build
|
||||
|
||||
- name: E2E (start + test + teardown)
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
set -euo pipefail
|
||||
|
||||
export PORT="${PORT:-3010}"
|
||||
export HOST="127.0.0.1"
|
||||
@@ -118,12 +95,12 @@ jobs:
|
||||
|
||||
# package artifacts (keeps file count small)
|
||||
- name: Package E2E artifacts
|
||||
if: always()
|
||||
if: failure()
|
||||
run: |
|
||||
tar -czf playwright-${{ matrix.browser }}.tgz playwright-report test-results || true
|
||||
|
||||
- name: Upload E2E artifacts
|
||||
if: always()
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: playwright-results-${{ matrix.browser }}
|
||||
@@ -135,25 +112,23 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url == 'https://github.com' }}
|
||||
with: { node-version: 20, cache: npm }
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url != 'https://github.com' || !github.server_url }}
|
||||
with: { node-version: 20 }
|
||||
- run: npm ci
|
||||
with:
|
||||
node-version: "${{ env.NODE_VERSION }}"
|
||||
cache: npm
|
||||
- run: npm ci --no-audit --fund=false
|
||||
- name: Install Playwright
|
||||
run: npx playwright install --with-deps
|
||||
- run: npm run build
|
||||
# 1) Sanity check that the build exists
|
||||
- name: Verify Next build output
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
set -euo pipefail
|
||||
ls -la .next || true
|
||||
test -f .next/BUILD_ID || (echo "No Next build output (.next) – did build fail?" && exit 1)
|
||||
|
||||
- name: Visual Regression (start + test + teardown)
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
set -euo pipefail
|
||||
|
||||
export PORT="${PORT:-3010}"
|
||||
export HOST="127.0.0.1"
|
||||
@@ -295,7 +270,7 @@ jobs:
|
||||
NODE_OPTIONS: "--max-old-space-size=8192"
|
||||
|
||||
- name: Package visual artifacts
|
||||
if: always()
|
||||
if: failure()
|
||||
run: |
|
||||
# Include server logs for debugging
|
||||
echo "📋 Server logs for debugging:"
|
||||
@@ -305,7 +280,7 @@ jobs:
|
||||
tar -czf visual-regression.tgz test-results tests/e2e/visual-regression.spec.ts-snapshots .next/runner.log || true
|
||||
|
||||
- name: Upload visual artifacts
|
||||
if: always()
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: visual-regression-results
|
||||
@@ -324,36 +299,25 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url == 'https://github.com' }}
|
||||
with: { node-version: 20, cache: npm }
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url != 'https://github.com' || !github.server_url }}
|
||||
with: { node-version: 20 }
|
||||
- run: npm ci
|
||||
|
||||
- name: Install LHCI
|
||||
run: npm i -D @lhci/cli
|
||||
with:
|
||||
node-version: "${{ env.NODE_VERSION }}"
|
||||
cache: npm
|
||||
- run: npm ci --no-audit --fund=false
|
||||
|
||||
- name: Build application
|
||||
run: npm run build
|
||||
|
||||
- name: Comprehensive Performance Testing
|
||||
run: |
|
||||
echo "🧪 Running comprehensive performance testing..."
|
||||
npm run test:performance:ci
|
||||
echo "✅ Performance testing complete"
|
||||
|
||||
# 1) Sanity check that the build exists
|
||||
# 1) Sanity check that the build exists
|
||||
- name: Verify Next build output
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
set -euo pipefail
|
||||
ls -la .next || true
|
||||
test -f .next/BUILD_ID || (echo "No Next build output (.next) – did build fail?" && exit 1)
|
||||
|
||||
- name: Install Chrome via Puppeteer (mac_arm)
|
||||
run: |
|
||||
# Install Chrome (arm64) into a local cache
|
||||
set -euxo pipefail
|
||||
set -euo pipefail
|
||||
mkdir -p .cache/puppeteer
|
||||
|
||||
# 1) Install and capture the build id that was actually installed
|
||||
@@ -387,7 +351,7 @@ jobs:
|
||||
|
||||
- name: Ensure arm64 Node for Lighthouse
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
set -euo pipefail
|
||||
echo "node before: $(node -v) arch=$(node -p 'process.arch')"
|
||||
if [ "$(node -p 'process.arch')" != "arm64" ]; then
|
||||
NODE_VER=20.17.0
|
||||
@@ -407,7 +371,7 @@ jobs:
|
||||
|
||||
- name: Performance (start + test + teardown)
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
set -euo pipefail
|
||||
|
||||
export PORT=3010 HOST=127.0.0.1
|
||||
mkdir -p .next
|
||||
@@ -462,7 +426,7 @@ jobs:
|
||||
NODE_OPTIONS: "--max-old-space-size=8192"
|
||||
|
||||
- name: Upload Performance Artifacts
|
||||
if: always()
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: performance-results
|
||||
@@ -474,34 +438,15 @@ jobs:
|
||||
.next/test-results
|
||||
retention-days: 30
|
||||
|
||||
storybook:
|
||||
runs-on: [self-hosted, macos-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url == 'https://github.com' }}
|
||||
with: { node-version: 20, cache: npm }
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url != 'https://github.com' || !github.server_url }}
|
||||
with: { node-version: 20 }
|
||||
- run: npm ci
|
||||
- run: npm run storybook:build:github
|
||||
# Temporarily disabled - test-runner needs updates for Storybook 10.x compatibility
|
||||
# Will be re-enabled once test-runner compatibility issues are resolved
|
||||
# - run: npm run test:sb
|
||||
# env: { CI: true }
|
||||
|
||||
lint:
|
||||
runs-on: [self-hosted, macos-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url == 'https://github.com' }}
|
||||
with: { node-version: 20, cache: npm }
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url != 'https://github.com' || !github.server_url }}
|
||||
with: { node-version: 20 }
|
||||
- run: npm ci
|
||||
with:
|
||||
node-version: "${{ env.NODE_VERSION }}"
|
||||
cache: npm
|
||||
- run: npm ci --no-audit --fund=false
|
||||
- run: npm run lint
|
||||
- run: npm exec prettier -- --check "**/*.{js,jsx,ts,tsx,json,css,md}"
|
||||
|
||||
@@ -510,11 +455,9 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url == 'https://github.com' }}
|
||||
with: { node-version: 20, cache: npm }
|
||||
- uses: actions/setup-node@v4
|
||||
if: ${{ github.server_url != 'https://github.com' || !github.server_url }}
|
||||
with: { node-version: 20 }
|
||||
- run: npm ci
|
||||
with:
|
||||
node-version: "${{ env.NODE_VERSION }}"
|
||||
cache: npm
|
||||
- run: npm ci --no-audit --fund=false
|
||||
- run: npm run build
|
||||
- run: npm run storybook:build:github
|
||||
|
||||
@@ -23,6 +23,7 @@ npm-cache/
|
||||
|
||||
# Lighthouse CI results
|
||||
/lhci-results/
|
||||
/.lighthouseci/
|
||||
|
||||
# Ignore other image files (but not visual regression snapshots)
|
||||
*.png
|
||||
@@ -76,10 +77,6 @@ next-env.d.ts
|
||||
*storybook.log
|
||||
storybook-static
|
||||
|
||||
# storybook config files (to avoid git changes when switching between local and production)
|
||||
.storybook/main.js
|
||||
.storybook/preview.js
|
||||
|
||||
# Gitea runner runtime files
|
||||
.runner
|
||||
.runner.pid
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
[
|
||||
{
|
||||
"name": "maxNumericValue",
|
||||
"expected": 5000,
|
||||
"actual": 6316.213500000003,
|
||||
"values": [6352.161499999999, 6316.213500000003, 6810.3611],
|
||||
"operator": "<=",
|
||||
"passed": false,
|
||||
"auditId": "interactive",
|
||||
"level": "warn",
|
||||
"url": "http://127.0.0.1:3010/",
|
||||
"auditTitle": "Time to Interactive",
|
||||
"auditDocumentationLink": "https://developer.chrome.com/docs/lighthouse/performance/interactive/"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
.next/
|
||||
out/
|
||||
build/
|
||||
dist/
|
||||
node_modules/
|
||||
|
||||
# Test/build artifacts
|
||||
coverage/
|
||||
playwright-report/
|
||||
test-results/
|
||||
lhci-results/
|
||||
.lighthouseci/
|
||||
|
||||
# Storybook build output
|
||||
storybook-static/
|
||||
|
||||
# Misc generated
|
||||
*.log
|
||||
@@ -1,33 +0,0 @@
|
||||
module.exports = {
|
||||
// Test runner configuration
|
||||
testMatch: ["**/*.stories.@(js|jsx|ts|tsx)"],
|
||||
testTimeout: 30000,
|
||||
retries: 2,
|
||||
// Fix for the StorybookTestRunnerError initialization issue
|
||||
setupFilesAfterEnv: [
|
||||
"<rootDir>/node_modules/@storybook/test-runner/jest-setup.js",
|
||||
],
|
||||
// Ensure proper module resolution
|
||||
moduleNameMapping: {
|
||||
"^@/(.*)$": "<rootDir>/app/$1",
|
||||
},
|
||||
// Test environment configuration
|
||||
testEnvironment: "jsdom",
|
||||
// Transform configuration
|
||||
transform: {
|
||||
"^.+\\.(js|jsx|ts|tsx)$": [
|
||||
"babel-jest",
|
||||
{ presets: ["@babel/preset-env", "@babel/preset-react"] },
|
||||
],
|
||||
},
|
||||
// Module file extensions
|
||||
moduleFileExtensions: ["js", "jsx", "ts", "tsx", "json"],
|
||||
// Ignore patterns
|
||||
testPathIgnorePatterns: ["/node_modules/", "/.next/"],
|
||||
// Coverage configuration
|
||||
collectCoverageFrom: [
|
||||
"app/**/*.{js,jsx,ts,tsx}",
|
||||
"!app/**/*.d.ts",
|
||||
"!app/**/*.stories.{js,jsx,ts,tsx}",
|
||||
],
|
||||
};
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
A Next.js application for community decision-making and governance documentation.
|
||||
|
||||
## 📋 Requirements
|
||||
|
||||
- **Node.js**: 20.0.0 or higher (LTS recommended)
|
||||
- **npm**: 10.0.0 or higher
|
||||
|
||||
## 🚀 Getting Started
|
||||
|
||||
Run the development server:
|
||||
@@ -14,28 +19,22 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the
|
||||
|
||||
## 🧪 Testing Framework
|
||||
|
||||
This project includes a comprehensive testing framework with multiple layers of testing:
|
||||
This project uses a simplified, component‑first testing model:
|
||||
|
||||
- **Component tests (Vitest + RTL)** live in `tests/components/` with a single file per component.
|
||||
- **E2E tests (Playwright)** cover critical user journeys and visual regression.
|
||||
|
||||
### Quick Test Commands
|
||||
|
||||
```bash
|
||||
# Unit tests with coverage
|
||||
# All component tests with coverage
|
||||
npm test
|
||||
|
||||
# E2E tests
|
||||
npm run e2e
|
||||
# Component tests only (new structure)
|
||||
npm run test:component
|
||||
|
||||
# Performance tests
|
||||
npm run lhci
|
||||
|
||||
# Storybook tests
|
||||
npm run test:sb
|
||||
|
||||
# Performance monitoring
|
||||
npm run test:performance # Comprehensive performance testing
|
||||
npm run bundle:analyze # Bundle size analysis
|
||||
npm run web-vitals:track # Web Vitals tracking
|
||||
npm run monitor:all # All monitoring tools
|
||||
# E2E tests only
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
### Test Coverage
|
||||
@@ -56,7 +55,7 @@ npm run monitor:all # All monitoring tools
|
||||
- **Performance monitoring**
|
||||
- **Code coverage reporting**
|
||||
|
||||
📖 **For detailed testing documentation, see [docs/README.md](docs/README.md)**
|
||||
📖 **For detailed testing documentation, see `docs/TESTING_GUIDE.md` and [docs/README.md](docs/README.md)**
|
||||
|
||||
## ⚡ Performance Optimizations
|
||||
|
||||
@@ -73,16 +72,27 @@ This project includes comprehensive performance optimizations for sub-2-second l
|
||||
|
||||
### Performance Monitoring
|
||||
|
||||
```bash
|
||||
# Individual monitoring tools
|
||||
npm run bundle:analyze # Analyze bundle sizes and budgets
|
||||
npm run performance:monitor # Performance metrics and Lighthouse CI
|
||||
npm run web-vitals:track # Core Web Vitals tracking
|
||||
Performance testing is handled by:
|
||||
|
||||
# Comprehensive testing
|
||||
npm run test:performance # All performance tests
|
||||
npm run monitor:all # All monitoring tools
|
||||
```
|
||||
- **Lighthouse CI** (`.lighthouserc.json`): Comprehensive performance testing in CI
|
||||
|
||||
```bash
|
||||
npm run lhci # Run Lighthouse CI
|
||||
npm run lhci:mobile # Mobile preset
|
||||
npm run lhci:desktop # Desktop preset
|
||||
npm run performance:budget # With performance budgets
|
||||
```
|
||||
|
||||
- **E2E Performance Tests** (`tests/e2e/performance.spec.ts`): Essential performance checks
|
||||
|
||||
```bash
|
||||
npm run e2e:performance # Run E2E performance tests
|
||||
```
|
||||
|
||||
- **Bundle Analysis**: Analyze bundle sizes
|
||||
```bash
|
||||
npm run bundle:analyze # Analyze bundle sizes
|
||||
```
|
||||
|
||||
### Performance Targets
|
||||
|
||||
@@ -144,14 +154,15 @@ The Storybook configuration automatically detects the environment:
|
||||
|
||||
### Testing
|
||||
|
||||
- `npm test` - Run unit tests with coverage
|
||||
- `npm test` - Run all component tests with coverage
|
||||
- `npm run test:component` - Run tests in `tests/components/` only
|
||||
- `npm run test:watch` - Run tests in watch mode
|
||||
- `npm run test:ui` - Run tests with UI
|
||||
- `npm run e2e` - Run E2E tests
|
||||
- `npm run test:e2e` - Run E2E tests only
|
||||
- `npm run e2e` - Alias for Playwright E2E tests
|
||||
- `npm run e2e:ui` - Run E2E tests with UI
|
||||
- `npm run e2e:serve` - Start dev server and run E2E tests
|
||||
- `npm run lhci` - Run performance tests
|
||||
- `npm run test:sb` - Run Storybook tests
|
||||
|
||||
### Storybook
|
||||
|
||||
@@ -175,22 +186,21 @@ community-rule/
|
||||
│ └── runner-config.yaml # Runner configuration
|
||||
├── docs/ # Documentation
|
||||
│ ├── README.md # Documentation index
|
||||
│ └── guides/ # Comprehensive guides
|
||||
│ ├── testing.md # Testing strategy
|
||||
│ ├── testing-framework.md # Testing framework details
|
||||
│ ├── testing-quick-reference.md # Quick reference
|
||||
│ ├── performance.md # Performance optimization
|
||||
│ ├── visual-regression.md # Visual testing
|
||||
│ └── content-creation.md # Content guidelines
|
||||
│ ├── TESTING_GUIDE.md # Testing guide
|
||||
│ ├── CUSTOM_HOOKS.md # Custom hooks documentation
|
||||
│ └── guides/ # Guides
|
||||
│ └── content-creation.md # Content creation guide
|
||||
├── scripts/ # Utility scripts
|
||||
│ ├── start-runner.sh # Start Gitea runner
|
||||
│ ├── status-runner.sh # Check runner status
|
||||
│ └── stop-runner.sh # Stop Gitea runner
|
||||
├── tests/ # Test files
|
||||
│ ├── unit/ # Unit tests
|
||||
│ ├── integration/ # Integration tests
|
||||
│ ├── e2e/ # E2E tests
|
||||
│ └── accessibility/ # Accessibility tests
|
||||
│ ├── components/ # Component tests (Vitest + RTL)
|
||||
│ ├── pages/ # Page-level tests
|
||||
│ ├── e2e/ # E2E tests (Playwright)
|
||||
│ ├── utils/ # Test utilities (componentTestSuite, etc.)
|
||||
│ ├── msw/ # MSW server setup
|
||||
│ └── accessibility/ # E2E accessibility checks
|
||||
├── .storybook/ # Storybook configuration
|
||||
├── .gitea/ # Gitea Actions workflows
|
||||
│ └── workflows/
|
||||
@@ -200,26 +210,27 @@ community-rule/
|
||||
|
||||
## 🔧 Technology Stack
|
||||
|
||||
- **Framework**: Next.js 15 + React 19
|
||||
- **Framework**: Next.js 16 + React 19
|
||||
- **Runtime**: Node.js 20+ (LTS)
|
||||
- **Styling**: Tailwind CSS 4
|
||||
- **Testing**: Vitest + Playwright + Lighthouse CI
|
||||
- **Documentation**: Storybook 9
|
||||
- **Documentation**: Storybook 10
|
||||
- **CI/CD**: Gitea Actions
|
||||
- **Hosting**: Gitea (Git hosting)
|
||||
|
||||
## 📖 Documentation
|
||||
|
||||
- **[Documentation Index](docs/README.md)** - Complete documentation guide
|
||||
- **[Testing Guides](docs/guides/)** - Testing strategy, framework, and quick reference
|
||||
- **[Performance Guide](docs/guides/performance.md)** - Performance optimization guide
|
||||
- **[Visual Regression Guide](docs/guides/visual-regression.md)** - Visual testing guide
|
||||
- **[Testing Guide](docs/TESTING_GUIDE.md)** - Testing strategy, component tests, E2E tests, and accessibility
|
||||
- **[Custom Hooks](docs/CUSTOM_HOOKS.md)** - Documentation for custom React hooks
|
||||
- **[Content Creation Guide](docs/guides/content-creation.md)** - Guide for creating blog content
|
||||
- **[Storybook](http://localhost:6006)** - Component documentation (local)
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
1. **Fork the repository**
|
||||
2. **Create a feature branch**: `git checkout -b feature/amazing-feature`
|
||||
3. **Write tests first** (see [Testing Guide](docs/guides/testing.md))
|
||||
3. **Write tests first** (see [Testing Guide](docs/TESTING_GUIDE.md))
|
||||
4. **Make your changes**
|
||||
5. **Run tests**: `npm test && npm run e2e`
|
||||
6. **Commit changes**: `git commit -m "feat: add amazing feature"`
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
// Mock CSS imports for tests
|
||||
// This prevents jsdom from trying to parse Tailwind CSS v4 syntax
|
||||
export default {};
|
||||
@@ -99,11 +99,13 @@ const AskOrganizer = memo<AskOrganizerProps>(
|
||||
? "gap-[var(--spacing-scale-020)]"
|
||||
: "gap-[var(--spacing-scale-040)]";
|
||||
|
||||
const labelledBy = title ? "ask-organizer-headline" : undefined;
|
||||
|
||||
return (
|
||||
<section
|
||||
className={`${sectionPadding} ${className}`}
|
||||
aria-labelledby="ask-organizer-headline"
|
||||
role="region"
|
||||
aria-labelledby={labelledBy}
|
||||
aria-label={labelledBy ? undefined : "Ask an organizer"}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div className={`flex flex-col ${contentGap} ${styles.container}`}>
|
||||
@@ -114,6 +116,7 @@ const AskOrganizer = memo<AskOrganizerProps>(
|
||||
description={description}
|
||||
variant={variant === "inverse" ? "ask-inverse" : "ask"}
|
||||
alignment={variant === "left-aligned" ? "left" : "center"}
|
||||
titleId={labelledBy}
|
||||
/>
|
||||
|
||||
{/* Button */}
|
||||
|
||||
@@ -15,6 +15,11 @@ interface ContentLockupProps {
|
||||
linkText?: string;
|
||||
linkHref?: string;
|
||||
alignment?: "center" | "left";
|
||||
/**
|
||||
* Optional id to attach to the primary title heading.
|
||||
* Useful when a parent section uses aria-labelledby.
|
||||
*/
|
||||
titleId?: string;
|
||||
}
|
||||
|
||||
interface VariantStyle {
|
||||
@@ -39,6 +44,7 @@ const ContentLockup = memo<ContentLockupProps>(
|
||||
linkText,
|
||||
linkHref,
|
||||
alignment = "center",
|
||||
titleId,
|
||||
}) => {
|
||||
// Variant-specific styling
|
||||
const variantStyles: Record<string, VariantStyle> = {
|
||||
@@ -132,9 +138,13 @@ const ContentLockup = memo<ContentLockupProps>(
|
||||
alignment === "left" ? "justify-start" : "justify-center"
|
||||
}`}
|
||||
>
|
||||
<h1 className={styles.title}>{title}</h1>
|
||||
{title ? (
|
||||
<h1 id={titleId} className={styles.title}>
|
||||
{title}
|
||||
</h1>
|
||||
) : null}
|
||||
</div>
|
||||
<h2 className={styles.subtitle}>{subtitle}</h2>
|
||||
{subtitle ? <h2 className={styles.subtitle}>{subtitle}</h2> : null}
|
||||
</div>
|
||||
) : (
|
||||
/* Full structure for other variants */
|
||||
@@ -143,7 +153,11 @@ const ContentLockup = memo<ContentLockupProps>(
|
||||
<div className={styles.titleGroup}>
|
||||
{/* Title container */}
|
||||
<div className={styles.titleContainer}>
|
||||
<h1 className={styles.title}>{title}</h1>
|
||||
{title ? (
|
||||
<h1 id={titleId} className={styles.title}>
|
||||
{title}
|
||||
</h1>
|
||||
) : null}
|
||||
{variant === "hero" && (
|
||||
<img
|
||||
src={getAssetPath("assets/Shapes_1.svg")}
|
||||
@@ -155,7 +169,9 @@ const ContentLockup = memo<ContentLockupProps>(
|
||||
</div>
|
||||
|
||||
{/* Subtitle */}
|
||||
<h2 className={styles.subtitle}>{subtitle}</h2>
|
||||
{subtitle ? (
|
||||
<h2 className={styles.subtitle}>{subtitle}</h2>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
|
||||
@@ -50,12 +50,13 @@ const FeatureGrid = memo<FeatureGridProps>(
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const labelledBy = title ? "feature-grid-headline" : undefined;
|
||||
return (
|
||||
<section
|
||||
className={`p-0 lg:p-[var(--spacing-scale-064)] ${className}`}
|
||||
aria-labelledby="feature-grid-headline"
|
||||
role="region"
|
||||
tabIndex={-1}
|
||||
aria-labelledby={labelledBy}
|
||||
aria-label={labelledBy ? undefined : "Feature tools and services"}
|
||||
>
|
||||
<div className="py-[var(--spacing-scale-032)] px-[var(--spacing-scale-020)] md:pt-[var(--spacing-scale-076)] md:pb-[var(--spacing-scale-048)] lg:pb-[var(--spacing-scale-076)] md:px-[var(--spacing-scale-048)] bg-[#171717] rounded-[var(--radius-measures-radius-xlarge)] focus-within:ring-2 focus-within:ring-[var(--color-surface-default-brand-royal)] focus-within:ring-offset-2">
|
||||
<div className="w-full mx-auto gap-[var(--spacing-scale-048)] lg:flex lg:items-start lg:gap-[var(--spacing-scale-048)] [container-type:inline-size]">
|
||||
@@ -67,15 +68,12 @@ const FeatureGrid = memo<FeatureGridProps>(
|
||||
variant="feature"
|
||||
linkText="Learn more"
|
||||
linkHref="#"
|
||||
titleId={labelledBy}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* MiniCard Grid */}
|
||||
<div
|
||||
className="grid grid-cols-2 md:grid-cols-4 gap-[var(--spacing-scale-012)] mt-[var(--spacing-scale-048)] lg:mt-0 lg:flex-grow lg:shrink-0"
|
||||
role="grid"
|
||||
aria-label="Feature tools and services"
|
||||
>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-[var(--spacing-scale-012)] mt-[var(--spacing-scale-048)] lg:mt-0 lg:flex-grow lg:shrink-0">
|
||||
{features.map((feature, index) => (
|
||||
<MiniCard
|
||||
key={index}
|
||||
|
||||
@@ -1,63 +1,47 @@
|
||||
# Documentation Index
|
||||
# Documentation
|
||||
|
||||
This directory contains all project documentation organized by topic.
|
||||
This directory contains project documentation organized by topic.
|
||||
|
||||
## 📚 Documentation Structure
|
||||
## Documentation Structure
|
||||
|
||||
### Core Documentation
|
||||
|
||||
- **[TESTING_GUIDE.md](./TESTING_GUIDE.md)** - Complete testing guide covering component tests, E2E tests, accessibility, and testing philosophy
|
||||
- **[CUSTOM_HOOKS.md](./CUSTOM_HOOKS.md)** - Documentation for all custom React hooks used in the project
|
||||
|
||||
### Guides (`guides/`)
|
||||
|
||||
Comprehensive guides for different aspects of the project:
|
||||
- **[content-creation.md](./guides/content-creation.md)** - Guide for creating blog content
|
||||
|
||||
#### Testing
|
||||
## Quick Navigation
|
||||
|
||||
- **[testing.md](./guides/testing.md)** - Complete testing strategy and philosophy
|
||||
- **[testing-framework.md](./guides/testing-framework.md)** - Detailed testing framework documentation
|
||||
- **[testing-quick-reference.md](./guides/testing-quick-reference.md)** - Quick reference for daily development
|
||||
- **[visual-regression.md](./guides/visual-regression.md)** - Visual regression testing guide
|
||||
### For Testing
|
||||
|
||||
#### Performance
|
||||
Start with **[TESTING_GUIDE.md](./TESTING_GUIDE.md)** for:
|
||||
|
||||
- **[performance.md](./guides/performance.md)** - Performance optimization and monitoring guide
|
||||
- Testing philosophy and approach
|
||||
- Component testing with `componentTestSuite`
|
||||
- E2E testing with Playwright
|
||||
- Accessibility testing
|
||||
- How to add tests for new components
|
||||
|
||||
#### Content
|
||||
### For Custom Hooks
|
||||
|
||||
- **[content-creation.md](./guides/content-creation.md)** - Content creation guidelines
|
||||
See **[CUSTOM_HOOKS.md](./CUSTOM_HOOKS.md)** for:
|
||||
|
||||
## 🎯 Quick Navigation
|
||||
- Available custom hooks
|
||||
- Usage examples
|
||||
- API documentation
|
||||
|
||||
### For New Team Members
|
||||
### For Content Creation
|
||||
|
||||
1. Start with **[testing.md](./guides/testing.md)** to understand the testing strategy
|
||||
2. Use **[testing-quick-reference.md](./guides/testing-quick-reference.md)** for daily development
|
||||
3. Reference **[performance.md](./guides/performance.md)** for performance optimization
|
||||
See **[content-creation.md](./guides/content-creation.md)** for:
|
||||
|
||||
### For Daily Development
|
||||
- How to create blog articles
|
||||
- Content guidelines
|
||||
- Contribution workflow
|
||||
|
||||
- **[testing-quick-reference.md](./guides/testing-quick-reference.md)** - Essential commands and troubleshooting
|
||||
- **[testing-framework.md](./guides/testing-framework.md)** - Detailed testing explanations
|
||||
|
||||
### For Specific Topics
|
||||
|
||||
- **Visual Testing**: [visual-regression.md](./guides/visual-regression.md)
|
||||
- **Performance**: [performance.md](./guides/performance.md)
|
||||
- **Content**: [content-creation.md](./guides/content-creation.md)
|
||||
|
||||
## 📊 Current Project Status
|
||||
|
||||
- **Unit Tests**: 94.88% coverage (exceeds 85% target)
|
||||
- **Integration Tests**: 5 comprehensive test suites
|
||||
- **E2E Tests**: 92 tests across 4 browsers
|
||||
- **Visual Regression**: 23 tests per browser
|
||||
- **Accessibility**: WCAG 2.1 AA compliance
|
||||
- **Performance**: Lighthouse CI with budgets
|
||||
- **Bundle Analysis**: Real-time monitoring with budgets
|
||||
- **Web Vitals Tracking**: Core Web Vitals collection
|
||||
|
||||
## 🔄 Documentation Updates
|
||||
|
||||
This documentation is maintained by the CommunityRule development team and updated regularly.
|
||||
|
||||
## 📚 Additional Resources
|
||||
## Additional Resources
|
||||
|
||||
- **Vitest Documentation**: https://vitest.dev/
|
||||
- **Playwright Documentation**: https://playwright.dev/
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
## Testing Guide
|
||||
|
||||
### Philosophy
|
||||
|
||||
- **Test behaviour, not implementation**: Focus on what the user can see and do, not internal details.
|
||||
- **Single source of truth per component**: Each component should have **one consolidated test file**.
|
||||
- **Accessibility is mandatory**: Basic a11y checks run as part of every component suite.
|
||||
- **E2E is sparse**: Only cover critical user journeys that span pages or systems.
|
||||
|
||||
### Test Structure
|
||||
|
||||
The test directory structure is organized as follows:
|
||||
|
||||
```text
|
||||
tests/
|
||||
components/ # All component-focused tests (Vitest + RTL)
|
||||
Button.test.tsx
|
||||
Input.test.tsx
|
||||
Checkbox.test.tsx
|
||||
Select.test.tsx
|
||||
Switch.test.tsx
|
||||
pages/ # Page-level tests (home, blog, etc.)
|
||||
home.test.jsx
|
||||
blog.test.jsx
|
||||
e2e/ # True end‑to‑end flows + visual regression (Playwright)
|
||||
critical-journeys.spec.ts # Main user journeys (homepage, navigation, interactions)
|
||||
visual-regression.spec.ts # Critical page screenshots only (5 tests)
|
||||
edge-cases.spec.ts # Critical error scenarios (4 tests)
|
||||
performance.spec.ts # Essential performance checks (2 tests)
|
||||
utils/ # Shared test utilities
|
||||
componentTestSuite.tsx
|
||||
msw/ # MSW server setup for mocking
|
||||
server.ts
|
||||
accessibility/
|
||||
e2e/ # E2E accessibility checks (WCAG compliance)
|
||||
wcag-compliance.spec.ts
|
||||
```
|
||||
|
||||
**Component tests** (`tests/components/`) use the standard `componentTestSuite` utility to ensure consistent baseline coverage for all UI components. **Page tests** (`tests/pages/`) cover page-level rendering and flows. **E2E tests** (`tests/e2e/`) focus on critical user journeys, visual regression, and performance. **Accessibility E2E** (`tests/accessibility/e2e/`) provides high-level WCAG compliance checks.
|
||||
|
||||
### E2E Testing Philosophy
|
||||
|
||||
E2E tests follow a **sparse, critical-path approach** optimized for open source projects:
|
||||
|
||||
- **Focus on user value**: Test critical user journeys that span multiple pages or systems, not individual component interactions
|
||||
- **Maintainability over coverage**: Keep tests maintainable and contributor-friendly rather than comprehensive
|
||||
- **Visual regression is minimal**: Only capture screenshots of major pages (homepage, blog listing/post, 404), not every component or viewport
|
||||
- **Performance monitoring is essential**: Track homepage load and Core Web Vitals, but detailed performance analysis is handled by Lighthouse CI
|
||||
- **Edge cases are critical only**: Test scenarios that would break user experience (slow network, offline mode, JS errors, missing images)
|
||||
|
||||
This approach reduces test maintenance burden while ensuring critical functionality remains stable.
|
||||
|
||||
### Standard Component Test Suite
|
||||
|
||||
Use the shared suite in `tests/utils/componentTestSuite.tsx` to get a consistent baseline:
|
||||
|
||||
```ts
|
||||
import Component from "../../app/components/Component";
|
||||
import {
|
||||
componentTestSuite,
|
||||
type ComponentTestSuiteConfig,
|
||||
} from "../utils/componentTestSuite";
|
||||
|
||||
type Props = React.ComponentProps<typeof Component>;
|
||||
|
||||
const config: ComponentTestSuiteConfig<Props> = {
|
||||
component: Component,
|
||||
name: "Component",
|
||||
props: {
|
||||
/* default props */
|
||||
} as Props,
|
||||
requiredProps: ["label"],
|
||||
optionalProps: {
|
||||
disabled: true,
|
||||
},
|
||||
queries: {
|
||||
getPrimaryElement: (s) => s.getByRole("button"),
|
||||
},
|
||||
variants: {
|
||||
disabled: {
|
||||
props: { disabled: true },
|
||||
assert: (el) => {
|
||||
expect(el).toBeDisabled();
|
||||
},
|
||||
},
|
||||
error: {
|
||||
props: { error: true } as Partial<Props>,
|
||||
assert: (el) => {
|
||||
expect(el).toHaveClass(
|
||||
"border-[var(--color-border-default-utility-negative)]",
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
testCases: {
|
||||
renders: true,
|
||||
accessibility: true,
|
||||
keyboardNavigation: true,
|
||||
disabledState: true,
|
||||
errorState: true,
|
||||
},
|
||||
};
|
||||
|
||||
componentTestSuite<Props>(config);
|
||||
```
|
||||
|
||||
#### What the Standard Suite Covers
|
||||
|
||||
- **Rendering**
|
||||
- Component renders without throwing using the provided `props`.
|
||||
- Required props are present and do not break rendering.
|
||||
- Optional props can be applied without breaking.
|
||||
|
||||
- **Accessibility**
|
||||
- Runs `axe` against the rendered output.
|
||||
- Fails on common WCAG 2.1 issues (roles, labels, contrast, etc.).
|
||||
|
||||
- **Keyboard Navigation**
|
||||
- Ensures the primary element can receive focus.
|
||||
- Smoke‑tests basic keyboard activation (`Enter`, `Space`) without runtime errors.
|
||||
|
||||
- **Disabled State**
|
||||
- Uses `variants.disabled` to verify disabled behaviour (e.g., `aria-disabled`, `disabled` attribute, tab index).
|
||||
|
||||
- **Error State**
|
||||
- Uses `variants.error` to verify error styling/attributes when applicable.
|
||||
|
||||
### When to Add Custom Tests
|
||||
|
||||
Use the standard suite for **baseline coverage**, then add custom `describe` blocks in the same file when:
|
||||
|
||||
- The component has **important variants** (different sizes, modes, label variants).
|
||||
- There is **non‑trivial interaction** (menus, dropdowns, complex keyboard behaviour).
|
||||
- You need to exercise **stateful flows** (forms, validation, error messages).
|
||||
|
||||
Example (inside the same `*.test.tsx` file):
|
||||
|
||||
```ts
|
||||
describe("Input – behaviour specifics", () => {
|
||||
it("calls onChange when user types", async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Test Commands
|
||||
|
||||
- **All component tests** (Vitest + RTL):
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
- **Component-only tests** (faster inner loop, focused on `tests/components/`):
|
||||
|
||||
```bash
|
||||
npm run test:component
|
||||
# filter by name:
|
||||
npm run test:component -- --run tests/components/Button.test.tsx
|
||||
```
|
||||
|
||||
- **E2E tests only** (Playwright):
|
||||
|
||||
```bash
|
||||
npm run test:e2e
|
||||
# or, equivalently:
|
||||
npm run e2e
|
||||
```
|
||||
|
||||
### What to Test vs. What Not to Test
|
||||
|
||||
- **Do test**
|
||||
- Public behaviour: visible text, roles, labels, ARIA, keyboard paths.
|
||||
- State transitions that users rely on (error -> success, disabled -> enabled).
|
||||
- Critical component interactions (clicks, form submissions, dropdown selection).
|
||||
- Accessibility invariants (no axe violations, basic keyboard support).
|
||||
|
||||
- **Avoid testing**
|
||||
- Pure styling details that are likely to change frequently (exact shadow radius, minor spacing).
|
||||
- Internal implementation details (private helpers, hook internals, memoisation specifics).
|
||||
- Responsive visibility in JSDOM (use Playwright visual / responsive tests instead).
|
||||
|
||||
### Adding Tests for a New Component (≈5 minutes)
|
||||
|
||||
1. **Create the component file** in `app/components/`.
|
||||
2. **Create a test file** in `tests/components/ComponentName.test.tsx`.
|
||||
3. **Wire the standard suite** using `componentTestSuite`.
|
||||
4. **Add 1–3 custom tests** for any unique behaviours.
|
||||
5. Run:
|
||||
|
||||
```bash
|
||||
npm run test:component -- --run tests/components/ComponentName.test.tsx
|
||||
```
|
||||
|
||||
### E2E and Visual Regression
|
||||
|
||||
E2E tests are organized into focused files:
|
||||
|
||||
- **`critical-journeys.spec.ts`**: Main user journeys (homepage loads, navigation, key interactions)
|
||||
- **`visual-regression.spec.ts`**: Critical page screenshots only (homepage full/viewport, blog listing/post, 404)
|
||||
- **`edge-cases.spec.ts`**: Critical error scenarios (slow network, offline mode, JS errors, missing images)
|
||||
- **`performance.spec.ts`**: Essential performance checks (homepage load, Core Web Vitals)
|
||||
|
||||
**Commands:**
|
||||
|
||||
```bash
|
||||
# Run all E2E tests
|
||||
npm run test:e2e
|
||||
|
||||
# Run visual regression tests only
|
||||
npm run visual:test
|
||||
|
||||
# Update visual regression snapshots (after UI changes)
|
||||
npm run visual:update
|
||||
|
||||
# Run specific test file
|
||||
npx playwright test tests/e2e/critical-journeys.spec.ts
|
||||
```
|
||||
|
||||
**When to add E2E tests:**
|
||||
|
||||
- **Add E2E tests** when:
|
||||
- A new critical user journey is introduced (e.g., new multi-step flow)
|
||||
- A major page is added that needs visual regression coverage
|
||||
- A critical error scenario needs to be tested (e.g., payment failure, form submission errors)
|
||||
|
||||
- **Don't add E2E tests** for:
|
||||
- Component-level interactions (use component tests instead)
|
||||
- Single-page functionality (use page tests instead)
|
||||
- Minor UI changes (visual regression will catch major regressions)
|
||||
- Edge cases that don't impact core user experience
|
||||
|
||||
**Visual regression snapshots:**
|
||||
|
||||
Visual regression tests capture screenshots of critical pages. When UI changes are intentional, update snapshots:
|
||||
|
||||
```bash
|
||||
npm run visual:update
|
||||
```
|
||||
|
||||
This updates snapshots for all 5 critical page tests. Review the changes carefully before committing.
|
||||
|
||||
### Storybook
|
||||
|
||||
**Storybook is used for component documentation and visual review only.** It is not used for automated testing.
|
||||
|
||||
- Component tests (`tests/components/*.test.tsx`) provide all test coverage previously handled by Storybook test-runner
|
||||
- Storybook stories (`stories/*.stories.js`) serve as living documentation and visual examples
|
||||
- Interaction functions are inlined in story files for demonstration purposes
|
||||
- Run Storybook locally with `npm run storybook` for component development and review
|
||||
|
||||
### Accessibility Testing
|
||||
|
||||
Accessibility is tested at two levels:
|
||||
|
||||
1. **Component-level accessibility** (`tests/components/*.test.tsx`):
|
||||
- Automatically covered by `componentTestSuite` using `jest-axe`
|
||||
- Tests roles, labels, ARIA attributes, keyboard navigation
|
||||
- Runs as part of every component test suite
|
||||
|
||||
2. **Full-page accessibility** (`tests/accessibility/e2e/wcag-compliance.spec.ts`):
|
||||
- E2E tests using Playwright and `@axe-core/playwright`
|
||||
- Validates WCAG 2.1 AA compliance across entire pages
|
||||
- Tests complete user journeys for accessibility barriers
|
||||
|
||||
This two-tier approach ensures both individual components and full page experiences meet accessibility standards.
|
||||
@@ -1,15 +0,0 @@
|
||||
import { j as u } from "./jsx-runtime-C_nHp4yK.js";
|
||||
function o({ src: e, alt: s, size: a = "small", className: l = "", ...r }) {
|
||||
const t = `rounded-[var(--radius-measures-radius-full)] object-cover ${{ small: "w-[16px] h-[16px]", medium: "w-[18px] h-[18px]", large: "w-[24px] h-[24px]", xlarge: "w-[32px] h-[32px]" }[a]} ${l}`;
|
||||
return u.jsx("img", { src: e, alt: s, className: t, ...r });
|
||||
}
|
||||
o.__docgenInfo = {
|
||||
description: "",
|
||||
methods: [],
|
||||
displayName: "Avatar",
|
||||
props: {
|
||||
size: { defaultValue: { value: '"small"', computed: !1 }, required: !1 },
|
||||
className: { defaultValue: { value: '""', computed: !1 }, required: !1 },
|
||||
},
|
||||
};
|
||||
export { o as A };
|
||||
@@ -1,358 +0,0 @@
|
||||
import { j as s } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { A as a } from "./Avatar-C4Vb3oYl.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const d = {
|
||||
title: "Components/Avatar",
|
||||
component: a,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A simple avatar component that displays user profile images with multiple size variants. Supports custom images and alt text for accessibility.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
src: {
|
||||
control: { type: "text" },
|
||||
description: "The source URL of the avatar image",
|
||||
},
|
||||
alt: {
|
||||
control: { type: "text" },
|
||||
description: "Alt text for accessibility",
|
||||
},
|
||||
size: {
|
||||
control: { type: "select" },
|
||||
options: ["small", "medium", "large", "xlarge"],
|
||||
description: "The size of the avatar",
|
||||
},
|
||||
className: {
|
||||
control: { type: "text" },
|
||||
description: "Additional CSS classes",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
r = {
|
||||
args: { src: "/assets/Avatar_1.png", alt: "User Avatar", size: "medium" },
|
||||
},
|
||||
t = {
|
||||
args: { src: "/assets/Avatar_1.png", alt: "User Avatar" },
|
||||
render: (e) =>
|
||||
s.jsx("div", {
|
||||
className: "space-y-4",
|
||||
children: s.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
s.jsx(a, { ...e, size: "small" }),
|
||||
s.jsx(a, { ...e, size: "medium" }),
|
||||
s.jsx(a, { ...e, size: "large" }),
|
||||
s.jsx(a, { ...e, size: "xlarge" }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different size variants available for the avatar component.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
i = {
|
||||
args: { size: "large" },
|
||||
render: (e) =>
|
||||
s.jsx("div", {
|
||||
className: "space-y-4",
|
||||
children: s.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
s.jsx(a, { ...e, src: "assets/Avatar_1.png", alt: "User 1" }),
|
||||
s.jsx(a, { ...e, src: "assets/Avatar_2.png", alt: "User 2" }),
|
||||
s.jsx(a, { ...e, src: "assets/Avatar_3.png", alt: "User 3" }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different avatar images available in the project.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
n = {
|
||||
args: {},
|
||||
render: () =>
|
||||
s.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Small Size",
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "small",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "small",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "small",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Medium Size",
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "medium",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "medium",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "medium",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Large Size",
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "XLarge Size",
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "xlarge",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "xlarge",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "xlarge",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Complete overview of all avatar sizes with different user images.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
r.parameters = {
|
||||
...r.parameters,
|
||||
docs: {
|
||||
...r.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
src: "/assets/Avatar_1.png",
|
||||
alt: "User Avatar",
|
||||
size: "medium"
|
||||
}
|
||||
}`,
|
||||
...r.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
src: "/assets/Avatar_1.png",
|
||||
alt: "User Avatar"
|
||||
},
|
||||
render: args => <div className="space-y-4">
|
||||
<div className="space-x-4">
|
||||
<Avatar {...args} size="small" />
|
||||
<Avatar {...args} size="medium" />
|
||||
<Avatar {...args} size="large" />
|
||||
<Avatar {...args} size="xlarge" />
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different size variants available for the avatar component."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
i.parameters = {
|
||||
...i.parameters,
|
||||
docs: {
|
||||
...i.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
size: "large"
|
||||
},
|
||||
render: args => <div className="space-y-4">
|
||||
<div className="space-x-4">
|
||||
<Avatar {...args} src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar {...args} src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar {...args} src="assets/Avatar_3.png" alt="User 3" />
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different avatar images available in the project."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...i.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
n.parameters = {
|
||||
...n.parameters,
|
||||
docs: {
|
||||
...n.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Small Size</h3>
|
||||
<div className="space-x-4">
|
||||
<Avatar size="small" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="small" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="small" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Medium Size</h3>
|
||||
<div className="space-x-4">
|
||||
<Avatar size="medium" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="medium" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="medium" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Large Size</h3>
|
||||
<div className="space-x-4">
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="large" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="large" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">XLarge Size</h3>
|
||||
<div className="space-x-4">
|
||||
<Avatar size="xlarge" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="xlarge" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="xlarge" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Complete overview of all avatar sizes with different user images."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...n.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const v = [
|
||||
"Default",
|
||||
"Sizes",
|
||||
"DifferentAvatars",
|
||||
"AllSizesWithDifferentAvatars",
|
||||
];
|
||||
export {
|
||||
n as AllSizesWithDifferentAvatars,
|
||||
r as Default,
|
||||
i as DifferentAvatars,
|
||||
t as Sizes,
|
||||
v as __namedExportsOrder,
|
||||
d as default,
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
import { j as r } from "./jsx-runtime-C_nHp4yK.js";
|
||||
function i({ children: e, size: a = "small", className: s = "", ...l }) {
|
||||
const t = `items-center ${{ small: "flex -space-x-2", medium: "flex -space-x-[9px]", large: "flex -space-x-[10px]", xlarge: "flex -space-x-[13px]" }[a]} ${s}`;
|
||||
return r.jsx("div", { className: t, ...l, children: e });
|
||||
}
|
||||
i.__docgenInfo = {
|
||||
description: "",
|
||||
methods: [],
|
||||
displayName: "AvatarContainer",
|
||||
props: {
|
||||
size: { defaultValue: { value: '"small"', computed: !1 }, required: !1 },
|
||||
className: { defaultValue: { value: '""', computed: !1 }, required: !1 },
|
||||
},
|
||||
};
|
||||
export { i as A };
|
||||
@@ -1,664 +0,0 @@
|
||||
import { j as s } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { A as e } from "./AvatarContainer-Bt0G0TWZ.js";
|
||||
import { A as a } from "./Avatar-C4Vb3oYl.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const g = {
|
||||
title: "Components/AvatarContainer",
|
||||
component: e,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A container component that groups multiple avatars together with overlapping spacing. Useful for displaying multiple users or team members in a compact format.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
control: { type: "select" },
|
||||
options: ["small", "medium", "large", "xlarge"],
|
||||
description: "The size of the avatar container and its children",
|
||||
},
|
||||
className: {
|
||||
control: { type: "text" },
|
||||
description: "Additional CSS classes",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
t = {
|
||||
args: { size: "medium" },
|
||||
render: (r) =>
|
||||
s.jsxs(e, {
|
||||
...r,
|
||||
children: [
|
||||
s.jsx(a, { size: r.size, src: "assets/Avatar_1.png", alt: "User 1" }),
|
||||
s.jsx(a, { size: r.size, src: "assets/Avatar_2.png", alt: "User 2" }),
|
||||
s.jsx(a, { size: r.size, src: "assets/Avatar_3.png", alt: "User 3" }),
|
||||
],
|
||||
}),
|
||||
},
|
||||
n = {
|
||||
args: {},
|
||||
render: () =>
|
||||
s.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Small Size",
|
||||
}),
|
||||
s.jsxs(e, {
|
||||
size: "small",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "small",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "small",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "small",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Medium Size",
|
||||
}),
|
||||
s.jsxs(e, {
|
||||
size: "medium",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "medium",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "medium",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "medium",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Large Size",
|
||||
}),
|
||||
s.jsxs(e, {
|
||||
size: "large",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "XLarge Size",
|
||||
}),
|
||||
s.jsxs(e, {
|
||||
size: "xlarge",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "xlarge",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "xlarge",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "xlarge",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Different size variants of the avatar container with overlapping spacing.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
i = {
|
||||
args: {},
|
||||
render: () =>
|
||||
s.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "2 Users",
|
||||
}),
|
||||
s.jsxs(e, {
|
||||
size: "large",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "3 Users",
|
||||
}),
|
||||
s.jsxs(e, {
|
||||
size: "large",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "4 Users",
|
||||
}),
|
||||
s.jsxs(e, {
|
||||
size: "large",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 4",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "5 Users",
|
||||
}),
|
||||
s.jsxs(e, {
|
||||
size: "large",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 4",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 5",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Avatar containers with different numbers of users to show the overlapping effect.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
l = {
|
||||
args: {},
|
||||
render: () =>
|
||||
s.jsx("div", {
|
||||
className: "min-h-screen bg-[var(--color-surface-default-primary)] p-8",
|
||||
children: s.jsxs("div", {
|
||||
className: "max-w-4xl mx-auto",
|
||||
children: [
|
||||
s.jsx("h2", {
|
||||
className: "text-white font-semibold mb-6",
|
||||
children: "Avatar Container in Context",
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className: "space-y-8",
|
||||
children: [
|
||||
s.jsxs("div", {
|
||||
className:
|
||||
"bg-[var(--color-surface-default-secondary)] p-6 rounded-lg",
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-4",
|
||||
children: "Team Members",
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
s.jsxs(e, {
|
||||
size: "medium",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "medium",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "medium",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "medium",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsx("span", {
|
||||
className: "text-white",
|
||||
children: "3 team members",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className:
|
||||
"bg-[var(--color-surface-default-secondary)] p-6 rounded-lg",
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-4",
|
||||
children: "Project Contributors",
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
s.jsxs(e, {
|
||||
size: "large",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_3.png",
|
||||
alt: "User 3",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "large",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 4",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsx("span", {
|
||||
className: "text-white",
|
||||
children: "4 contributors",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className:
|
||||
"bg-[var(--color-surface-default-secondary)] p-6 rounded-lg",
|
||||
children: [
|
||||
s.jsx("h3", {
|
||||
className: "text-white font-semibold mb-4",
|
||||
children: "Small Team",
|
||||
}),
|
||||
s.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
s.jsxs(e, {
|
||||
size: "small",
|
||||
children: [
|
||||
s.jsx(a, {
|
||||
size: "small",
|
||||
src: "assets/Avatar_1.png",
|
||||
alt: "User 1",
|
||||
}),
|
||||
s.jsx(a, {
|
||||
size: "small",
|
||||
src: "assets/Avatar_2.png",
|
||||
alt: "User 2",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
s.jsx("span", {
|
||||
className: "text-white",
|
||||
children: "2 members",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Avatar containers used in realistic contexts to show how they integrate with other UI elements.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
size: "medium"
|
||||
},
|
||||
render: args => <AvatarContainer {...args}>
|
||||
<Avatar size={args.size} src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size={args.size} src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size={args.size} src="assets/Avatar_3.png" alt="User 3" />
|
||||
</AvatarContainer>
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
n.parameters = {
|
||||
...n.parameters,
|
||||
docs: {
|
||||
...n.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Small Size</h3>
|
||||
<AvatarContainer size="small">
|
||||
<Avatar size="small" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="small" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="small" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</AvatarContainer>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Medium Size</h3>
|
||||
<AvatarContainer size="medium">
|
||||
<Avatar size="medium" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="medium" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="medium" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</AvatarContainer>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Large Size</h3>
|
||||
<AvatarContainer size="large">
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="large" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="large" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</AvatarContainer>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">XLarge Size</h3>
|
||||
<AvatarContainer size="xlarge">
|
||||
<Avatar size="xlarge" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="xlarge" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="xlarge" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</AvatarContainer>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different size variants of the avatar container with overlapping spacing."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...n.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
i.parameters = {
|
||||
...i.parameters,
|
||||
docs: {
|
||||
...i.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">2 Users</h3>
|
||||
<AvatarContainer size="large">
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="large" src="assets/Avatar_2.png" alt="User 2" />
|
||||
</AvatarContainer>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">3 Users</h3>
|
||||
<AvatarContainer size="large">
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="large" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="large" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</AvatarContainer>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">4 Users</h3>
|
||||
<AvatarContainer size="large">
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="large" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="large" src="assets/Avatar_3.png" alt="User 3" />
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 4" />
|
||||
</AvatarContainer>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">5 Users</h3>
|
||||
<AvatarContainer size="large">
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="large" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="large" src="assets/Avatar_3.png" alt="User 3" />
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 4" />
|
||||
<Avatar size="large" src="assets/Avatar_2.png" alt="User 5" />
|
||||
</AvatarContainer>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Avatar containers with different numbers of users to show the overlapping effect."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...i.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
l.parameters = {
|
||||
...l.parameters,
|
||||
docs: {
|
||||
...l.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="min-h-screen bg-[var(--color-surface-default-primary)] p-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h2 className="text-white font-semibold mb-6">
|
||||
Avatar Container in Context
|
||||
</h2>
|
||||
|
||||
<div className="space-y-8">
|
||||
<div className="bg-[var(--color-surface-default-secondary)] p-6 rounded-lg">
|
||||
<h3 className="text-white font-semibold mb-4">Team Members</h3>
|
||||
<div className="flex items-center space-x-4">
|
||||
<AvatarContainer size="medium">
|
||||
<Avatar size="medium" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="medium" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="medium" src="assets/Avatar_3.png" alt="User 3" />
|
||||
</AvatarContainer>
|
||||
<span className="text-white">3 team members</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-[var(--color-surface-default-secondary)] p-6 rounded-lg">
|
||||
<h3 className="text-white font-semibold mb-4">
|
||||
Project Contributors
|
||||
</h3>
|
||||
<div className="flex items-center space-x-4">
|
||||
<AvatarContainer size="large">
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="large" src="assets/Avatar_2.png" alt="User 2" />
|
||||
<Avatar size="large" src="assets/Avatar_3.png" alt="User 3" />
|
||||
<Avatar size="large" src="assets/Avatar_1.png" alt="User 4" />
|
||||
</AvatarContainer>
|
||||
<span className="text-white">4 contributors</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-[var(--color-surface-default-secondary)] p-6 rounded-lg">
|
||||
<h3 className="text-white font-semibold mb-4">Small Team</h3>
|
||||
<div className="flex items-center space-x-4">
|
||||
<AvatarContainer size="small">
|
||||
<Avatar size="small" src="assets/Avatar_1.png" alt="User 1" />
|
||||
<Avatar size="small" src="assets/Avatar_2.png" alt="User 2" />
|
||||
</AvatarContainer>
|
||||
<span className="text-white">2 members</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Avatar containers used in realistic contexts to show how they integrate with other UI elements."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...l.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const p = ["Default", "Sizes", "DifferentGroupSizes", "InContext"];
|
||||
export {
|
||||
t as Default,
|
||||
i as DifferentGroupSizes,
|
||||
l as InContext,
|
||||
n as Sizes,
|
||||
p as __namedExportsOrder,
|
||||
g as default,
|
||||
};
|
||||
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,10 +0,0 @@
|
||||
<svg width="24" height="22" viewBox="0 0 24 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_18411_62931)">
|
||||
<path d="M5.42835 2.2446C8.08819 4.2226 10.9492 8.23317 11.9996 10.3855C13.05 8.23333 15.9108 4.22256 18.5708 2.2446C20.49 0.817353 23.5996 -0.28697 23.5996 3.22704C23.5996 3.92884 23.1934 9.1225 22.9551 9.96567C22.127 12.8971 19.1094 13.6448 16.4251 13.1923C21.1171 13.9833 22.3107 16.6034 19.733 19.2236C14.8374 24.1998 12.6966 17.9751 12.1478 16.3801C12.0472 16.0877 12.0002 15.9509 11.9995 16.0672C11.9988 15.9509 11.9517 16.0877 11.8512 16.3801C11.3026 17.9751 9.16185 24.2 4.26597 19.2236C1.68821 16.6034 2.88177 13.9831 7.57385 13.1923C4.88953 13.6448 1.87185 12.8971 1.04385 9.96567C0.805606 9.12242 0.399414 3.92876 0.399414 3.22704C0.399414 -0.28697 3.50909 0.817353 5.42821 2.2446H5.42835Z" fill="#949494"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_18411_62931">
|
||||
<rect width="24" height="21" fill="white" transform="translate(0 0.5)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1001 B |
@@ -1,97 +0,0 @@
|
||||
import { j as u } from "./jsx-runtime-C_nHp4yK.js";
|
||||
function g({
|
||||
children: o,
|
||||
variant: e = "default",
|
||||
size: a = "xsmall",
|
||||
className: v = "",
|
||||
disabled: r = !1,
|
||||
type: p = "button",
|
||||
onClick: t,
|
||||
href: l,
|
||||
target: s,
|
||||
rel: c,
|
||||
ariaLabel: n,
|
||||
...f
|
||||
}) {
|
||||
const b = {
|
||||
xsmall:
|
||||
"px-[var(--spacing-scale-006)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-001)]",
|
||||
small:
|
||||
"px-[var(--spacing-measures-spacing-008)] py-[var(--spacing-measures-spacing-008)] gap-[var(--spacing-scale-004)]",
|
||||
medium: "p-[var(--spacing-scale-010)] gap-[var(--spacing-scale-004)]",
|
||||
large:
|
||||
"px-[var(--spacing-scale-012)] py-[var(--spacing-scale-010)] gap-[var(--spacing-scale-004)]",
|
||||
xlarge:
|
||||
"px-[var(--spacing-scale-020)] py-[var(--spacing-scale-012)] gap-[var(--spacing-scale-008)]",
|
||||
},
|
||||
m = {
|
||||
xsmall:
|
||||
"font-['Inter'] text-[10px] leading-[12px] font-medium tracking-[0%]",
|
||||
small:
|
||||
"font-['Inter'] text-[12px] leading-[14px] font-medium tracking-[0%]",
|
||||
medium:
|
||||
"font-['Inter'] text-[14px] leading-[16px] font-medium tracking-[0%]",
|
||||
large:
|
||||
"font-['Inter'] text-[16px] leading-[20px] font-medium tracking-[0%]",
|
||||
xlarge:
|
||||
"font-['Inter'] text-[24px] leading-[28px] font-normal tracking-[0%]",
|
||||
},
|
||||
y = {
|
||||
default:
|
||||
"bg-[var(--color-surface-inverse-primary)] text-[var(--color-content-inverse-primary)] hover:bg-[var(--color-surface-inverse-primary)] hover:text-[var(--color-content-inverse-brand-primary)] hover:outline-[var(--border-color-default-brandprimary)] hover:outline-inset hover:scale-[1.02] hover:shadow-lg focus:shadow-[0_0_10px_1px_var(--color-surface-default-brand-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--color-content-default-brand-primary)] focus:ring-offset-1 focus:scale-[1.02] active:bg-[var(--color-surface-inverse-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:outline-[var(--border-color-default-brandprimary)] active:outline-offset-1 active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100 disabled:hover:shadow-none disabled:hover:outline-none",
|
||||
secondary:
|
||||
"bg-transparent text-[var(--color-content-default-brand-primary)] hover:text-[var(--color-content-default-primary)] hover:scale-[1.02] hover:bg-transparent hover:outline-none focus:outline-1 focus:outline-inset focus:outline-[var(--border-color-default-tertiary)] focus:shadow-[0_0_10px_1px_var(--color-surface-default-brand-primary)] focus:blur-[0px] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
||||
primary:
|
||||
"bg-[var(--color-surface-default-primary)] text-[var(--color-content-default-primary)] hover:bg-[var(--color-surface-default-primary)] hover:text-[var(--color-content-default-brand-primary)] hover:scale-[1.02] focus:bg-[var(--color-surface-default-primary)] focus:text-[var(--color-content-default-brand-primary)] focus:outline-none focus:shadow-[0_0_10px_1px_var(--color-surface-default-brand-primary)] focus:blur-[0px] focus:scale-[1.02] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-inverse-secondary)] disabled:text-[var(--color-content-default-primary)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
||||
outlined:
|
||||
"bg-transparent text-[var(--color-content-default-primary)] border-[1.5px] border-[var(--color-content-default-primary)] hover:bg-transparent hover:text-[var(--color-content-default-brand-primary)] hover:border-[1.5px] hover:border-[var(--color-content-default-brand-primary)] hover:scale-[1.02] focus:bg-transparent focus:text-[var(--color-content-default-primary)] focus:outline-none focus:border-[1.5px] focus:border-[var(--color-content-default-primary)] focus:shadow-[0_0_10px_1px_var(--color-surface-default-brand-primary)] focus:blur-[0px] focus:scale-[1.02] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:border-transparent active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:border-[1.5px] disabled:border-[var(--color-surface-default-secondary)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
||||
dark: "bg-transparent text-[var(--color-content-inverse-primary)] border border-[var(--border-color-default-primary)] hover:bg-transparent hover:text-[var(--color-content-inverse-brand-primary)] hover:border hover:border-[var(--border-color-inverse-brandprimary)] hover:scale-[1.02] focus:bg-transparent focus:text-[var(--color-content-inverse-primary)] focus:outline-none focus:border focus:border-[var(--border-color-default-primary)] focus:shadow-[0_0_10px_1px_var(--color-surface-default-brand-primary)] focus:blur-[0px] focus:scale-[1.02] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:border-transparent active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-inverse-secondary)] disabled:text-[var(--color-content-default-primary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
||||
inverse:
|
||||
"bg-transparent text-[var(--color-content-inverse-primary)] hover:text-[var(--color-content-inverse-brand-primary)] hover:scale-[1.02] hover:bg-transparent hover:outline-none focus:outline-1 focus:outline-inset focus:outline-[var(--border-color-default-tertiary)] focus:shadow-[0_0_10px_1px_var(--color-surface-default-tertiary)] focus:blur-[0px] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-inverse-secondary)] disabled:text-[var(--color-content-default-primary)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
||||
},
|
||||
x =
|
||||
e === "primary" || e === "outlined" || e === "dark" || e === "inverse"
|
||||
? ""
|
||||
: {
|
||||
xsmall: "hover:outline-1",
|
||||
small: "hover:outline-1",
|
||||
medium: "hover:outline-1",
|
||||
large: "hover:outline-2",
|
||||
xlarge: "hover:outline-[2.5px]",
|
||||
}[a],
|
||||
i = `${`inline-flex items-center justify-start box-border ${b[a]} rounded-[var(--radius-measures-radius-full)] ${m[a]} transition-all duration-500 ease-in-out cursor-pointer ${y[e]} ${x}`} ${v}`,
|
||||
d = {
|
||||
...(n && { "aria-label": n }),
|
||||
...(r && { "aria-disabled": "true" }),
|
||||
...(s && { target: s }),
|
||||
...(c && { rel: c }),
|
||||
tabIndex: r ? -1 : 0,
|
||||
...f,
|
||||
};
|
||||
return l && !r
|
||||
? u.jsx("a", { href: l, className: i, onClick: t, ...d, children: o })
|
||||
: u.jsx("button", {
|
||||
type: p,
|
||||
className: i,
|
||||
disabled: r,
|
||||
onClick: t,
|
||||
...d,
|
||||
children: o,
|
||||
});
|
||||
}
|
||||
g.__docgenInfo = {
|
||||
description: "",
|
||||
methods: [],
|
||||
displayName: "Button",
|
||||
props: {
|
||||
variant: {
|
||||
defaultValue: { value: '"default"', computed: !1 },
|
||||
required: !1,
|
||||
},
|
||||
size: { defaultValue: { value: '"xsmall"', computed: !1 }, required: !1 },
|
||||
className: { defaultValue: { value: '""', computed: !1 }, required: !1 },
|
||||
disabled: { defaultValue: { value: "false", computed: !1 }, required: !1 },
|
||||
type: { defaultValue: { value: '"button"', computed: !1 }, required: !1 },
|
||||
},
|
||||
};
|
||||
export { g as B };
|
||||
@@ -1,687 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { B as n } from "./Button-Z4hbXct5.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const u = {
|
||||
title: "Components/Button",
|
||||
component: n,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A versatile button component with multiple variants, sizes, and states. Can render as a button or link with full accessibility support. Includes focus states with keyboard navigation - use Tab key to test focus indicators.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: { type: "select" },
|
||||
options: [
|
||||
"default",
|
||||
"secondary",
|
||||
"primary",
|
||||
"outlined",
|
||||
"dark",
|
||||
"inverse",
|
||||
],
|
||||
description: "The visual style variant of the button",
|
||||
},
|
||||
size: {
|
||||
control: { type: "select" },
|
||||
options: ["xsmall", "small", "medium", "large", "xlarge"],
|
||||
description: "The size of the button",
|
||||
},
|
||||
disabled: {
|
||||
control: { type: "boolean" },
|
||||
description: "Whether the button is disabled",
|
||||
},
|
||||
href: {
|
||||
control: { type: "text" },
|
||||
description: "If provided, renders as a link instead of a button",
|
||||
},
|
||||
onClick: { action: "clicked" },
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
t = { args: { children: "Button" } },
|
||||
s = {
|
||||
args: { children: "Button", size: "large" },
|
||||
render: (a) =>
|
||||
e.jsx("div", {
|
||||
className: "space-y-4",
|
||||
children: e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, { ...a, variant: "default", children: "Default" }),
|
||||
e.jsx(n, { ...a, variant: "secondary", children: "Secondary" }),
|
||||
e.jsx(n, { ...a, variant: "primary", children: "Primary" }),
|
||||
e.jsx(n, { ...a, variant: "outlined", children: "Outlined" }),
|
||||
e.jsx(n, { ...a, variant: "dark", children: "Dark" }),
|
||||
e.jsx(n, { ...a, variant: "inverse", children: "Inverse" }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different visual variants of the button component.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
i = {
|
||||
args: { children: "Button", variant: "default" },
|
||||
render: (a) =>
|
||||
e.jsx("div", {
|
||||
className: "space-y-4",
|
||||
children: e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, { ...a, size: "xsmall", children: "XSmall" }),
|
||||
e.jsx(n, { ...a, size: "small", children: "Small" }),
|
||||
e.jsx(n, { ...a, size: "medium", children: "Medium" }),
|
||||
e.jsx(n, { ...a, size: "large", children: "Large" }),
|
||||
e.jsx(n, { ...a, size: "xlarge", children: "XLarge" }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different sizes available for the button component.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
r = {
|
||||
args: { children: "Button", size: "large", variant: "default" },
|
||||
render: (a) =>
|
||||
e.jsx("div", {
|
||||
className: "space-y-4",
|
||||
children: e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, { ...a, children: "Normal" }),
|
||||
e.jsx(n, { ...a, disabled: !0, children: "Disabled" }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: { story: "Different states of the button component." },
|
||||
},
|
||||
},
|
||||
},
|
||||
l = {
|
||||
args: {},
|
||||
render: () =>
|
||||
e.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Default Variant",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, { size: "xsmall", children: "XSmall" }),
|
||||
e.jsx(n, { size: "small", children: "Small" }),
|
||||
e.jsx(n, { size: "medium", children: "Medium" }),
|
||||
e.jsx(n, { size: "large", children: "Large" }),
|
||||
e.jsx(n, { size: "xlarge", children: "XLarge" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Secondary Variant",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, {
|
||||
variant: "secondary",
|
||||
size: "xsmall",
|
||||
children: "XSmall",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "secondary",
|
||||
size: "small",
|
||||
children: "Small",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "secondary",
|
||||
size: "medium",
|
||||
children: "Medium",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "secondary",
|
||||
size: "large",
|
||||
children: "Large",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "secondary",
|
||||
size: "xlarge",
|
||||
children: "XLarge",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Primary Variant",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, {
|
||||
variant: "primary",
|
||||
size: "xsmall",
|
||||
children: "XSmall",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "primary",
|
||||
size: "small",
|
||||
children: "Small",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "primary",
|
||||
size: "medium",
|
||||
children: "Medium",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "primary",
|
||||
size: "large",
|
||||
children: "Large",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "primary",
|
||||
size: "xlarge",
|
||||
children: "XLarge",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Outlined Variant",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, {
|
||||
variant: "outlined",
|
||||
size: "xsmall",
|
||||
children: "XSmall",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "outlined",
|
||||
size: "small",
|
||||
children: "Small",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "outlined",
|
||||
size: "medium",
|
||||
children: "Medium",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "outlined",
|
||||
size: "large",
|
||||
children: "Large",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "outlined",
|
||||
size: "xlarge",
|
||||
children: "XLarge",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Dark Variant",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, {
|
||||
variant: "dark",
|
||||
size: "xsmall",
|
||||
children: "XSmall",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "dark",
|
||||
size: "small",
|
||||
children: "Small",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "dark",
|
||||
size: "medium",
|
||||
children: "Medium",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "dark",
|
||||
size: "large",
|
||||
children: "Large",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "dark",
|
||||
size: "xlarge",
|
||||
children: "XLarge",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Inverse Variant",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, {
|
||||
variant: "inverse",
|
||||
size: "xsmall",
|
||||
children: "XSmall",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "inverse",
|
||||
size: "small",
|
||||
children: "Small",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "inverse",
|
||||
size: "medium",
|
||||
children: "Medium",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "inverse",
|
||||
size: "large",
|
||||
children: "Large",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "inverse",
|
||||
size: "xlarge",
|
||||
children: "XLarge",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Disabled States",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(n, {
|
||||
size: "large",
|
||||
disabled: !0,
|
||||
children: "Default Disabled",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "secondary",
|
||||
size: "large",
|
||||
disabled: !0,
|
||||
children: "Secondary Disabled",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "primary",
|
||||
size: "large",
|
||||
disabled: !0,
|
||||
children: "Primary Disabled",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "outlined",
|
||||
size: "large",
|
||||
disabled: !0,
|
||||
children: "Outlined Disabled",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "dark",
|
||||
size: "large",
|
||||
disabled: !0,
|
||||
children: "Dark Disabled",
|
||||
}),
|
||||
e.jsx(n, {
|
||||
variant: "inverse",
|
||||
size: "large",
|
||||
disabled: !0,
|
||||
children: "Inverse Disabled",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Complete overview of all button variants, sizes, and states.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
children: "Button"
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
s.parameters = {
|
||||
...s.parameters,
|
||||
docs: {
|
||||
...s.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
children: "Button",
|
||||
size: "large"
|
||||
},
|
||||
render: args => <div className="space-y-4">
|
||||
<div className="space-x-4">
|
||||
<Button {...args} variant="default">
|
||||
Default
|
||||
</Button>
|
||||
<Button {...args} variant="secondary">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button {...args} variant="primary">
|
||||
Primary
|
||||
</Button>
|
||||
<Button {...args} variant="outlined">
|
||||
Outlined
|
||||
</Button>
|
||||
<Button {...args} variant="dark">
|
||||
Dark
|
||||
</Button>
|
||||
<Button {...args} variant="inverse">
|
||||
Inverse
|
||||
</Button>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different visual variants of the button component."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...s.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
i.parameters = {
|
||||
...i.parameters,
|
||||
docs: {
|
||||
...i.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
children: "Button",
|
||||
variant: "default"
|
||||
},
|
||||
render: args => <div className="space-y-4">
|
||||
<div className="space-x-4">
|
||||
<Button {...args} size="xsmall">
|
||||
XSmall
|
||||
</Button>
|
||||
<Button {...args} size="small">
|
||||
Small
|
||||
</Button>
|
||||
<Button {...args} size="medium">
|
||||
Medium
|
||||
</Button>
|
||||
<Button {...args} size="large">
|
||||
Large
|
||||
</Button>
|
||||
<Button {...args} size="xlarge">
|
||||
XLarge
|
||||
</Button>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different sizes available for the button component."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...i.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
r.parameters = {
|
||||
...r.parameters,
|
||||
docs: {
|
||||
...r.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
children: "Button",
|
||||
size: "large",
|
||||
variant: "default"
|
||||
},
|
||||
render: args => <div className="space-y-4">
|
||||
<div className="space-x-4">
|
||||
<Button {...args}>Normal</Button>
|
||||
<Button {...args} disabled>
|
||||
Disabled
|
||||
</Button>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different states of the button component."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...r.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
l.parameters = {
|
||||
...l.parameters,
|
||||
docs: {
|
||||
...l.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Default Variant</h3>
|
||||
<div className="space-x-4">
|
||||
<Button size="xsmall">XSmall</Button>
|
||||
<Button size="small">Small</Button>
|
||||
<Button size="medium">Medium</Button>
|
||||
<Button size="large">Large</Button>
|
||||
<Button size="xlarge">XLarge</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Secondary Variant</h3>
|
||||
<div className="space-x-4">
|
||||
<Button variant="secondary" size="xsmall">
|
||||
XSmall
|
||||
</Button>
|
||||
<Button variant="secondary" size="small">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="secondary" size="medium">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="secondary" size="large">
|
||||
Large
|
||||
</Button>
|
||||
<Button variant="secondary" size="xlarge">
|
||||
XLarge
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Primary Variant</h3>
|
||||
<div className="space-x-4">
|
||||
<Button variant="primary" size="xsmall">
|
||||
XSmall
|
||||
</Button>
|
||||
<Button variant="primary" size="small">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="primary" size="medium">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="primary" size="large">
|
||||
Large
|
||||
</Button>
|
||||
<Button variant="primary" size="xlarge">
|
||||
XLarge
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Outlined Variant</h3>
|
||||
<div className="space-x-4">
|
||||
<Button variant="outlined" size="xsmall">
|
||||
XSmall
|
||||
</Button>
|
||||
<Button variant="outlined" size="small">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="outlined" size="medium">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="outlined" size="large">
|
||||
Large
|
||||
</Button>
|
||||
<Button variant="outlined" size="xlarge">
|
||||
XLarge
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Dark Variant</h3>
|
||||
<div className="space-x-4">
|
||||
<Button variant="dark" size="xsmall">
|
||||
XSmall
|
||||
</Button>
|
||||
<Button variant="dark" size="small">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="dark" size="medium">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="dark" size="large">
|
||||
Large
|
||||
</Button>
|
||||
<Button variant="dark" size="xlarge">
|
||||
XLarge
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Inverse Variant</h3>
|
||||
<div className="space-x-4">
|
||||
<Button variant="inverse" size="xsmall">
|
||||
XSmall
|
||||
</Button>
|
||||
<Button variant="inverse" size="small">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="inverse" size="medium">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="inverse" size="large">
|
||||
Large
|
||||
</Button>
|
||||
<Button variant="inverse" size="xlarge">
|
||||
XLarge
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Disabled States</h3>
|
||||
<div className="space-x-4">
|
||||
<Button size="large" disabled>
|
||||
Default Disabled
|
||||
</Button>
|
||||
<Button variant="secondary" size="large" disabled>
|
||||
Secondary Disabled
|
||||
</Button>
|
||||
<Button variant="primary" size="large" disabled>
|
||||
Primary Disabled
|
||||
</Button>
|
||||
<Button variant="outlined" size="large" disabled>
|
||||
Outlined Disabled
|
||||
</Button>
|
||||
<Button variant="dark" size="large" disabled>
|
||||
Dark Disabled
|
||||
</Button>
|
||||
<Button variant="inverse" size="large" disabled>
|
||||
Inverse Disabled
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Complete overview of all button variants, sizes, and states."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...l.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const v = ["Default", "Variants", "Sizes", "States", "AllVariants"];
|
||||
export {
|
||||
l as AllVariants,
|
||||
t as Default,
|
||||
i as Sizes,
|
||||
r as States,
|
||||
s as Variants,
|
||||
v as __namedExportsOrder,
|
||||
u as default,
|
||||
};
|
||||
@@ -1,96 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { B as s } from "./Button-Z4hbXct5.js";
|
||||
const n = ({
|
||||
title: l,
|
||||
subtitle: i,
|
||||
description: x,
|
||||
ctaText: a,
|
||||
ctaHref: t,
|
||||
buttonClassName: r = "",
|
||||
}) =>
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col gap-[var(--spacing-scale-006)] sm:gap-[var(--spacing-scale-012)] md:gap-[var(--spacing-scale-020)] lg:gap-[var(--spacing-scale-020)] relative z-10",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col md:gap-[var(--spacing-scale-004)] lg:gap-[var(--spacing-scale-008)] xl:gap-[var(--spacing-scale-020)]",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
className: "flex flex-col xl:gap-0",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex gap-[var(--spacing-scale-008)] xl:gap-[var(--spacing-scale-010)] items-center",
|
||||
children: [
|
||||
e.jsx("h1", {
|
||||
className:
|
||||
"font-bricolage-grotesque font-medium text-[32px] leading-[32px] sm:text-[52px] sm:leading-[52px] md:text-[44px] md:leading-[44px] lg:text-[64px] lg:leading-[64px] xl:text-[96px] xl:leading-[110%] text-[var(--color-content-inverse-primary)]",
|
||||
children: l,
|
||||
}),
|
||||
e.jsx("img", {
|
||||
src: "assets/Shapes_1.svg",
|
||||
alt: "Decorative shapes",
|
||||
className:
|
||||
"w-[27.2px] h-[27.2px] md:w-[34px] md:h-[34px] lg:w-[50px] lg:h-[50px]",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsx("h2", {
|
||||
className:
|
||||
"font-bricolage-grotesque font-medium text-[32px] leading-[32px] sm:text-[52px] sm:leading-[52px] md:text-[44px] md:leading-[44px] lg:text-[64px] lg:leading-[64px] xl:text-[96px] xl:leading-[110%] text-[var(--color-content-inverse-primary)]",
|
||||
children: i,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsx("p", {
|
||||
className:
|
||||
"font-inter font-[400] text-[18px] leading-[130%] lg:text-[24px] lg:leading-[32px] xl:text-[32px] xl:leading-[40px] text-[var(--color-content-inverse-primary)] pr-[var(--spacing-scale-032)] md:pr-[var(--spacing-scale-008)] lg:pr-[var(--spacing-scale-032)]",
|
||||
children: x,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex justify-start",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className: "block md:hidden",
|
||||
children: e.jsx(s, {
|
||||
variant: "primary",
|
||||
size: "small",
|
||||
children: a,
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden md:block xl:hidden",
|
||||
children: e.jsx(s, {
|
||||
variant: "primary",
|
||||
size: "large",
|
||||
className: r,
|
||||
children: a,
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden xl:block",
|
||||
children: e.jsx(s, {
|
||||
variant: "primary",
|
||||
size: "xlarge",
|
||||
children: a,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
n.__docgenInfo = {
|
||||
description: "",
|
||||
methods: [],
|
||||
displayName: "ContentLockup",
|
||||
props: {
|
||||
buttonClassName: {
|
||||
defaultValue: { value: '""', computed: !1 },
|
||||
required: !1,
|
||||
},
|
||||
},
|
||||
};
|
||||
export { n as C };
|
||||
@@ -1,221 +0,0 @@
|
||||
import { C as s } from "./ContentLockup-DbWiPA4N.js";
|
||||
import "./jsx-runtime-C_nHp4yK.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
import "./Button-Z4hbXct5.js";
|
||||
const p = {
|
||||
title: "Components/ContentLockup",
|
||||
component: s,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A content lockup component that groups title, subtitle, description, and CTA button. Features responsive typography and spacing that adapts across breakpoints. Used within the HeroBanner component.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
title: { control: { type: "text" }, description: "The main title text" },
|
||||
subtitle: { control: { type: "text" }, description: "The subtitle text" },
|
||||
description: {
|
||||
control: { type: "text" },
|
||||
description: "The description text",
|
||||
},
|
||||
ctaText: {
|
||||
control: { type: "text" },
|
||||
description: "The call-to-action button text",
|
||||
},
|
||||
ctaHref: {
|
||||
control: { type: "text" },
|
||||
description: "The call-to-action button link",
|
||||
},
|
||||
buttonClassName: {
|
||||
control: { type: "text" },
|
||||
description:
|
||||
"Additional CSS classes to apply to the large button (md/lg breakpoints)",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
t = {
|
||||
args: {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Default content lockup with standard Community Rule messaging.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
e = {
|
||||
args: {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values. Our platform provides the tools and frameworks needed to build successful, sustainable communities that can navigate complex challenges together.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Content lockup with longer description text to test text wrapping.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
o = {
|
||||
args: {
|
||||
title: "Simple",
|
||||
subtitle: "solution",
|
||||
description: "Easy community decision making.",
|
||||
ctaText: "Try it",
|
||||
ctaHref: "#",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Content lockup with minimal content to test compact layouts.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
n = {
|
||||
args: {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
buttonClassName: "shrink-0 whitespace-nowrap min-w-[280px]",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Content lockup with custom button styling applied to the large button (md/lg breakpoints).",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description: "Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Default content lockup with standard Community Rule messaging."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
e.parameters = {
|
||||
...e.parameters,
|
||||
docs: {
|
||||
...e.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description: "Help your community make important decisions in a way that reflects its unique values. Our platform provides the tools and frameworks needed to build successful, sustainable communities that can navigate complex challenges together.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Content lockup with longer description text to test text wrapping."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...e.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
o.parameters = {
|
||||
...o.parameters,
|
||||
docs: {
|
||||
...o.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Simple",
|
||||
subtitle: "solution",
|
||||
description: "Easy community decision making.",
|
||||
ctaText: "Try it",
|
||||
ctaHref: "#"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Content lockup with minimal content to test compact layouts."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...o.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
n.parameters = {
|
||||
...n.parameters,
|
||||
docs: {
|
||||
...n.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description: "Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
buttonClassName: "shrink-0 whitespace-nowrap min-w-[280px]"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Content lockup with custom button styling applied to the large button (md/lg breakpoints)."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...n.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const u = ["Default", "LongDescription", "ShortContent", "CustomButtonStyling"];
|
||||
export {
|
||||
n as CustomButtonStyling,
|
||||
t as Default,
|
||||
e as LongDescription,
|
||||
o as ShortContent,
|
||||
u as __namedExportsOrder,
|
||||
p as default,
|
||||
};
|
||||
@@ -1,351 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { L as o } from "./Logo-DM7O8ATg.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
function n() {
|
||||
return e.jsx("div", {
|
||||
className: "flex flex-col items-center self-stretch",
|
||||
children: e.jsx("div", {
|
||||
className:
|
||||
"flex items-start self-stretch h-px w-full bg-[var(--border-color-default-secondary)]",
|
||||
}),
|
||||
});
|
||||
}
|
||||
n.__docgenInfo = { description: "", methods: [], displayName: "Separator" };
|
||||
function r() {
|
||||
const a = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
name: "Media Economies Design Lab",
|
||||
email: "medlab@colorado.edu",
|
||||
url: "https://communityrule.com",
|
||||
sameAs: [
|
||||
"https://bsky.app/profile/medlabboulder",
|
||||
"https://gitlab.com/medlabboulder",
|
||||
],
|
||||
};
|
||||
return e.jsxs(e.Fragment, {
|
||||
children: [
|
||||
e.jsx("script", {
|
||||
type: "application/ld+json",
|
||||
dangerouslySetInnerHTML: { __html: JSON.stringify(a) },
|
||||
}),
|
||||
e.jsx("footer", {
|
||||
className: "bg-[var(--color-surface-default-primary)] w-full",
|
||||
children: e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col items-start mx-auto px-[var(--spacing-measures-spacing-016)] py-[var(--spacing-measures-spacing-040)] gap-[var(--spacing-measures-spacing-040)] sm:px-[var(--spacing-measures-spacing-032)] sm:py-[var(--spacing-measures-spacing-024)] sm:gap-[var(--spacing-measures-spacing-024)] lg:px-[var(--spacing-measures-spacing-120,120px)] lg:py-[var(--spacing-measures-spacing-096,96px)] lg:gap-[var(--spacing-measures-spacing-060,60px)]",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className: "block sm:hidden",
|
||||
children: e.jsx(o, {}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden sm:block lg:hidden",
|
||||
children: e.jsx(o, { size: "footer" }),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden lg:block",
|
||||
children: e.jsx(o, { size: "footerLg" }),
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col items-start w-full gap-[var(--spacing-measures-spacing-048,48px)] sm:flex-row sm:justify-between sm:gap-0",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col items-start gap-[var(--spacing-measures-spacing-064,64px)] order-2 sm:order-1",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col items-start gap-[var(--spacing-measures-spacing-016,16px)]",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"text-[var(--color-content-default-primary)] font-['Inter'] text-base leading-5 font-medium tracking-[0%] lg:text-2xl lg:leading-7 lg:font-normal",
|
||||
children: "Media Economies Design Lab",
|
||||
}),
|
||||
e.jsx("a", {
|
||||
href: "mailto:medlab@colorado.edu",
|
||||
className:
|
||||
"text-[var(--color-content-default-primary)] font-['Inter'] text-base leading-5 font-medium tracking-[0%] lg:text-2xl lg:leading-7 lg:font-normal hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-primary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity p-2 -m-2 cursor-pointer",
|
||||
children: "medlab@colorado.edu",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col items-start gap-[var(--spacing-measures-spacing-016,16px)]",
|
||||
children: [
|
||||
e.jsxs("a", {
|
||||
href: "#",
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-measures-spacing-06,6px)] hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-primary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity p-2 -m-2 cursor-pointer group",
|
||||
"aria-label": "Follow us on Bluesky",
|
||||
children: [
|
||||
e.jsx("img", {
|
||||
src: "assets/Bluesky_Logo.svg",
|
||||
alt: "Bluesky",
|
||||
width: 24,
|
||||
height: 22,
|
||||
className:
|
||||
"flex-shrink-0 group-hover:scale-110 transition-transform",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"text-[var(--color-content-default-primary)] font-['Inter'] text-base leading-5 font-medium tracking-[0%] lg:text-2xl lg:leading-7 lg:font-normal",
|
||||
children: "medlabboulder",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("a", {
|
||||
href: "#",
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-measures-spacing-06,6px)] hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-primary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity p-2 -m-2 cursor-pointer group",
|
||||
"aria-label": "Follow us on GitLab",
|
||||
children: [
|
||||
e.jsx("img", {
|
||||
src: "assets/GitLab_Icon.png",
|
||||
alt: "GitLab",
|
||||
width: 22,
|
||||
height: 22,
|
||||
className:
|
||||
"flex-shrink-0 grayscale group-hover:scale-110 transition-transform",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"text-[var(--color-content-default-primary)] font-['Inter'] text-base leading-5 font-medium tracking-[0%] lg:text-2xl lg:leading-7 lg:font-normal",
|
||||
children: "medlabboulder",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col items-start gap-[var(--spacing-measures-spacing-032,32px)] order-1 sm:order-2 sm:items-end",
|
||||
children: [
|
||||
e.jsx("a", {
|
||||
href: "#",
|
||||
className:
|
||||
"text-[var(--color-content-default-primary)] font-['Inter'] text-base leading-5 font-medium tracking-[0%] lg:text-2xl lg:leading-7 lg:font-normal hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-primary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity p-2 -m-2 cursor-pointer",
|
||||
children: "Use cases",
|
||||
}),
|
||||
e.jsx("a", {
|
||||
href: "#",
|
||||
className:
|
||||
"text-[var(--color-content-default-primary)] font-['Inter'] text-base leading-5 font-medium tracking-[0%] lg:text-2xl lg:leading-7 lg:font-normal hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-primary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity p-2 -m-2 cursor-pointer",
|
||||
children: "Learn",
|
||||
}),
|
||||
e.jsx("a", {
|
||||
href: "#",
|
||||
className:
|
||||
"text-[var(--color-content-default-primary)] font-['Inter'] text-base leading-5 font-medium tracking-[0%] lg:text-2xl lg:leading-7 lg:font-normal hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-primary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity p-2 -m-2 cursor-pointer",
|
||||
children: "About",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsx(n, {}),
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col items-start gap-[var(--spacing-measures-spacing-032,32px)] sm:flex-row sm:justify-between sm:items-center w-full",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"text-[var(--color-content-default-secondary)] font-['Inter'] text-sm leading-5 font-medium sm:text-xs sm:leading-4 lg:text-sm lg:leading-5 lg:font-normal",
|
||||
children: "© All right reserved",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col items-start gap-[var(--spacing-measures-spacing-040,40px)] sm:flex-row sm:gap-[var(--spacing-measures-spacing-040,40px)]",
|
||||
children: [
|
||||
e.jsx("a", {
|
||||
href: "#",
|
||||
className:
|
||||
"text-[var(--color-content-default-secondary)] font-['Inter'] text-sm leading-5 font-medium underline sm:text-xs sm:leading-4 sm:no-underline lg:text-sm lg:leading-5 lg:font-normal hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-secondary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity p-2 -m-2 cursor-pointer",
|
||||
children: "Privacy Policy",
|
||||
}),
|
||||
e.jsx("a", {
|
||||
href: "#",
|
||||
className:
|
||||
"text-[var(--color-content-default-secondary)] font-['Inter'] text-sm leading-5 font-medium underline sm:text-xs sm:leading-4 sm:no-underline lg:text-sm lg:leading-5 lg:font-normal hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-secondary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity p-2 -m-2 cursor-pointer",
|
||||
children: "Terms of Service",
|
||||
}),
|
||||
e.jsx("a", {
|
||||
href: "#",
|
||||
className:
|
||||
"text-[var(--color-content-default-secondary)] font-['Inter'] text-sm leading-5 font-medium underline sm:text-xs sm:leading-4 sm:no-underline lg:text-sm lg:leading-5 lg:font-normal hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-secondary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity p-2 -m-2 cursor-pointer",
|
||||
children: "Cookies Settings",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
r.__docgenInfo = { description: "", methods: [], displayName: "Footer" };
|
||||
const d = {
|
||||
title: "Components/Footer",
|
||||
component: r,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"The main footer with responsive layout, branding section, navigation links, and legal information. Features different logo sizes and layout changes across breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
s = {
|
||||
args: {},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Use the Viewport toolbar to see how the footer adapts to different screen sizes. The layout changes from stacked to side-by-side and logo sizes adjust.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
t = {
|
||||
args: {},
|
||||
render: () =>
|
||||
e.jsxs("div", {
|
||||
className: "min-h-screen bg-[var(--color-surface-default-primary)]",
|
||||
children: [
|
||||
e.jsx("main", {
|
||||
className: "p-8",
|
||||
children: e.jsxs("div", {
|
||||
className: "max-w-4xl mx-auto",
|
||||
children: [
|
||||
e.jsx("h1", {
|
||||
className: "text-2xl font-bold text-white mb-4",
|
||||
children: "Example Page Content",
|
||||
}),
|
||||
e.jsx("p", {
|
||||
className: "text-white mb-4",
|
||||
children:
|
||||
"This demonstrates how the footer looks in a realistic page context. The footer maintains its responsive behavior while providing navigation and branding information.",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
|
||||
children: [1, 2, 3, 4, 5, 6].map((a) =>
|
||||
e.jsxs(
|
||||
"div",
|
||||
{
|
||||
className:
|
||||
"bg-[var(--color-surface-default-secondary)] p-4 rounded-lg",
|
||||
children: [
|
||||
e.jsxs("h3", {
|
||||
className: "text-white font-semibold mb-2",
|
||||
children: ["Content Block ", a],
|
||||
}),
|
||||
e.jsx("p", {
|
||||
className:
|
||||
"text-[var(--color-content-default-secondary)] text-sm",
|
||||
children:
|
||||
"This is example content to show how the footer integrates with page content.",
|
||||
}),
|
||||
],
|
||||
},
|
||||
a,
|
||||
),
|
||||
),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
e.jsx(r, {}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"The footer integrated into a full page layout to show how it works in context.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
s.parameters = {
|
||||
...s.parameters,
|
||||
docs: {
|
||||
...s.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Use the Viewport toolbar to see how the footer adapts to different screen sizes. The layout changes from stacked to side-by-side and logo sizes adjust."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...s.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="min-h-screen bg-[var(--color-surface-default-primary)]">
|
||||
<main className="p-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h1 className="text-2xl font-bold text-white mb-4">
|
||||
Example Page Content
|
||||
</h1>
|
||||
<p className="text-white mb-4">
|
||||
This demonstrates how the footer looks in a realistic page context.
|
||||
The footer maintains its responsive behavior while providing
|
||||
navigation and branding information.
|
||||
</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{[1, 2, 3, 4, 5, 6].map(i => <div key={i} className="bg-[var(--color-surface-default-secondary)] p-4 rounded-lg">
|
||||
<h3 className="text-white font-semibold mb-2">
|
||||
Content Block {i}
|
||||
</h3>
|
||||
<p className="text-[var(--color-content-default-secondary)] text-sm">
|
||||
This is example content to show how the footer integrates with
|
||||
page content.
|
||||
</p>
|
||||
</div>)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<Footer />
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "The footer integrated into a full page layout to show how it works in context."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const f = ["Default", "InPageContext"];
|
||||
export {
|
||||
s as Default,
|
||||
t as InPageContext,
|
||||
f as __namedExportsOrder,
|
||||
d as default,
|
||||
};
|
||||
|
Before Width: | Height: | Size: 53 KiB |
@@ -1,191 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { L as v } from "./Logo-DM7O8ATg.js";
|
||||
import { M as t } from "./MenuBar-anMCqtJv.js";
|
||||
import { M as d } from "./MenuBarItem-Dp8NM2fx.js";
|
||||
import { B as j } from "./Button-Z4hbXct5.js";
|
||||
import { A as b } from "./AvatarContainer-Bt0G0TWZ.js";
|
||||
import { A as f } from "./Avatar-C4Vb3oYl.js";
|
||||
function N({ onToggle: c }) {
|
||||
const m = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
name: "CommunityRule",
|
||||
url: "https://communityrule.com",
|
||||
potentialAction: {
|
||||
"@type": "SearchAction",
|
||||
target: "https://communityrule.com/search?q={search_term_string}",
|
||||
"query-input": "required name=search_term_string",
|
||||
},
|
||||
},
|
||||
o = [
|
||||
{ href: "#", text: "Use cases", extraPadding: !0 },
|
||||
{ href: "#", text: "Learn" },
|
||||
{ href: "#", text: "About" },
|
||||
],
|
||||
x = [
|
||||
{ src: "/assets/Avatar_1.png", alt: "Avatar 1" },
|
||||
{ src: "/assets/Avatar_2.png", alt: "Avatar 2" },
|
||||
{ src: "/assets/Avatar_3.png", alt: "Avatar 3" },
|
||||
],
|
||||
h = [
|
||||
{ breakpoint: "block sm:hidden", size: "header", showText: !1 },
|
||||
{ breakpoint: "hidden sm:block md:hidden", size: "header", showText: !0 },
|
||||
{
|
||||
breakpoint: "hidden md:block lg:hidden",
|
||||
size: "headerMd",
|
||||
showText: !0,
|
||||
},
|
||||
{
|
||||
breakpoint: "hidden lg:block xl:hidden",
|
||||
size: "headerLg",
|
||||
showText: !0,
|
||||
},
|
||||
{ breakpoint: "hidden xl:block", size: "headerXl", showText: !0 },
|
||||
],
|
||||
i = (a) =>
|
||||
o.map((s, r) =>
|
||||
e.jsx(
|
||||
d,
|
||||
{
|
||||
href: s.href,
|
||||
size: s.extraPadding && a === "xsmall" ? "xsmallUseCases" : a,
|
||||
onClick: c,
|
||||
ariaLabel: `Navigate to ${s.text} page`,
|
||||
children: s.text,
|
||||
},
|
||||
r,
|
||||
),
|
||||
),
|
||||
g = (a, s) =>
|
||||
e.jsx(b, {
|
||||
size: a,
|
||||
children: x.map((r, u) =>
|
||||
e.jsx(f, { src: r.src, alt: r.alt, size: s }, u),
|
||||
),
|
||||
}),
|
||||
l = (a) =>
|
||||
e.jsx(d, {
|
||||
href: "#",
|
||||
size: a,
|
||||
ariaLabel: "Log in to your account",
|
||||
children: "Log in",
|
||||
}),
|
||||
n = (a, s, r) =>
|
||||
e.jsxs(j, {
|
||||
size: a,
|
||||
ariaLabel: "Create a new rule with avatar decoration",
|
||||
children: [g(s, r), e.jsx("span", { children: "Create rule" })],
|
||||
}),
|
||||
p = (a, s) => e.jsx(v, { size: a, showText: s });
|
||||
return e.jsxs(e.Fragment, {
|
||||
children: [
|
||||
e.jsx("script", {
|
||||
type: "application/ld+json",
|
||||
dangerouslySetInnerHTML: { __html: JSON.stringify(m) },
|
||||
}),
|
||||
e.jsx("header", {
|
||||
className:
|
||||
"bg-[var(--color-surface-default-primary)] w-full border-b border-[var(--border-color-default-tertiary)]",
|
||||
role: "banner",
|
||||
"aria-label": "Main navigation header",
|
||||
children: e.jsxs("nav", {
|
||||
className:
|
||||
"flex items-center justify-between mx-auto h-[40px] lg:h-[84px] xl:h-[88px] px-[var(--spacing-measures-spacing-016)] py-[var(--spacing-measures-spacing-008)] lg:px-[var(--spacing-measures-spacing-64,64px)] lg:py-[var(--spacing-measures-spacing-016,16px)]",
|
||||
role: "navigation",
|
||||
"aria-label": "Main navigation",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className: "flex items-center",
|
||||
children: h.map((a, s) =>
|
||||
e.jsx(
|
||||
"div",
|
||||
{ className: a.breakpoint, children: p(a.size, a.showText) },
|
||||
s,
|
||||
),
|
||||
),
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center",
|
||||
children: [
|
||||
e.jsx("div", { className: "block sm:hidden" }),
|
||||
e.jsx("div", {
|
||||
className: "hidden sm:block md:hidden",
|
||||
children: e.jsxs(t, {
|
||||
size: "default",
|
||||
children: [i("xsmall"), l("xsmall")],
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden md:block lg:hidden",
|
||||
children: e.jsx(t, {
|
||||
size: "default",
|
||||
children: i("xsmall"),
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden lg:block xl:hidden",
|
||||
children: e.jsx(t, { size: "large", children: i("large") }),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden xl:block",
|
||||
children: e.jsx(t, { size: "large", children: i("xlarge") }),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className: "block sm:hidden",
|
||||
children: e.jsxs("div", {
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-scale-001)]",
|
||||
children: [
|
||||
i("xsmall"),
|
||||
l("xsmall"),
|
||||
n("xsmall", "small", "small"),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden sm:block md:hidden",
|
||||
children: e.jsx("div", {
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-scale-004)]",
|
||||
children: n("xsmall", "small", "small"),
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden md:block lg:hidden",
|
||||
children: e.jsxs("div", {
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-measures-spacing-010)]",
|
||||
children: [l("xsmall"), n("xsmall", "medium", "medium")],
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden lg:block xl:hidden",
|
||||
children: e.jsxs("div", {
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-measures-spacing-004)]",
|
||||
children: [l("large"), n("large", "xlarge", "xlarge")],
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden xl:block",
|
||||
children: e.jsxs("div", {
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-measures-spacing-004)]",
|
||||
children: [l("xlarge"), n("xlarge", "xlarge", "xlarge")],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
N.__docgenInfo = { description: "", methods: [], displayName: "Header" };
|
||||
export { N as H };
|
||||
@@ -1,168 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { H as o } from "./Header-Bz-bT1Sq.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
import "./Logo-DM7O8ATg.js";
|
||||
import "./MenuBar-anMCqtJv.js";
|
||||
import "./MenuBarItem-Dp8NM2fx.js";
|
||||
import "./Button-Z4hbXct5.js";
|
||||
import "./AvatarContainer-Bt0G0TWZ.js";
|
||||
import "./Avatar-C4Vb3oYl.js";
|
||||
const x = {
|
||||
title: "Components/Header",
|
||||
component: o,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"The main navigation header with responsive behavior across different breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: { onToggle: { action: "toggled" } },
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
t = {
|
||||
args: {},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Use the Viewport toolbar to change the iframe width and see how the header adapts to different screen sizes. The header shows different layouts for mobile, tablet, and desktop breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
a = {
|
||||
args: {},
|
||||
render: () =>
|
||||
e.jsxs("div", {
|
||||
className: "min-h-screen bg-[var(--color-surface-default-primary)]",
|
||||
children: [
|
||||
e.jsx(o, {}),
|
||||
e.jsx("main", {
|
||||
className: "p-8",
|
||||
children: e.jsxs("div", {
|
||||
className: "max-w-4xl mx-auto",
|
||||
children: [
|
||||
e.jsx("h1", {
|
||||
className: "text-2xl font-bold text-white mb-4",
|
||||
children: "Example Page Content",
|
||||
}),
|
||||
e.jsx("p", {
|
||||
className: "text-white mb-4",
|
||||
children:
|
||||
"This demonstrates how the header looks in a realistic page context. The header maintains its responsive behavior while providing navigation for the page content.",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
|
||||
children: [1, 2, 3, 4, 5, 6].map((s) =>
|
||||
e.jsxs(
|
||||
"div",
|
||||
{
|
||||
className:
|
||||
"bg-[var(--color-surface-default-secondary)] p-4 rounded-lg",
|
||||
children: [
|
||||
e.jsxs("h3", {
|
||||
className: "text-white font-semibold mb-2",
|
||||
children: ["Content Block ", s],
|
||||
}),
|
||||
e.jsx("p", {
|
||||
className:
|
||||
"text-[var(--color-content-default-secondary)] text-sm",
|
||||
children:
|
||||
"This is example content to show how the header integrates with page content.",
|
||||
}),
|
||||
],
|
||||
},
|
||||
s,
|
||||
),
|
||||
),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"The header integrated into a full page layout to show how it works in context.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Use the Viewport toolbar to change the iframe width and see how the header adapts to different screen sizes. The header shows different layouts for mobile, tablet, and desktop breakpoints."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
a.parameters = {
|
||||
...a.parameters,
|
||||
docs: {
|
||||
...a.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="min-h-screen bg-[var(--color-surface-default-primary)]">
|
||||
<Header />
|
||||
<main className="p-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h1 className="text-2xl font-bold text-white mb-4">
|
||||
Example Page Content
|
||||
</h1>
|
||||
<p className="text-white mb-4">
|
||||
This demonstrates how the header looks in a realistic page context.
|
||||
The header maintains its responsive behavior while providing
|
||||
navigation for the page content.
|
||||
</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{[1, 2, 3, 4, 5, 6].map(i => <div key={i} className="bg-[var(--color-surface-default-secondary)] p-4 rounded-lg">
|
||||
<h3 className="text-white font-semibold mb-2">
|
||||
Content Block {i}
|
||||
</h3>
|
||||
<p className="text-[var(--color-content-default-secondary)] text-sm">
|
||||
This is example content to show how the header integrates with
|
||||
page content.
|
||||
</p>
|
||||
</div>)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "The header integrated into a full page layout to show how it works in context."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...a.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const f = ["Default", "InPageContext"];
|
||||
export {
|
||||
t as Default,
|
||||
a as InPageContext,
|
||||
f as __namedExportsOrder,
|
||||
x as default,
|
||||
};
|
||||
@@ -1,41 +0,0 @@
|
||||
import { j as s } from "./jsx-runtime-C_nHp4yK.js";
|
||||
function n({ children: a, className: e = "", stretch: l = !1, ...p }) {
|
||||
const r = l
|
||||
? "flex-1 sm:mr-[var(--spacing-scale-008)] md:mr-[185px] lg:mr-[var(--spacing-scale-024)] xl:mr-[var(--spacing-scale-032)]"
|
||||
: "";
|
||||
return s.jsxs("div", {
|
||||
className: `HeaderTab header-breakpoint-transition relative bg-[var(--color-surface-default-brand-primary)] rounded-t-[32px] sm:rounded-t-[32px] md:rounded-t-[32px] lg:rounded-t-[32px] xl:rounded-t-[32px] pl-[var(--spacing-measures-spacing-012)] h-[40px] sm:h-[52px] md:h-[52px] lg:h-[52px] xl:h-[64px] sm:pr-[var(--spacing-scale-006)] md:pl-[var(--spacing-scale-024)] lg:pl-[var(--spacing-scale-024)] xl:pl-[var(--spacing-scale-032)] md:pr-[var(--spacing-scale-012)] lg:pr-[var(--spacing-scale-048)] xl:pr-[var(--spacing-scale-120)] md:gap-[var(--spacing-scale-032)] ${r} ${e}`,
|
||||
...p,
|
||||
children: [
|
||||
a,
|
||||
s.jsx("img", {
|
||||
src: "assets/Union_xsm.svg",
|
||||
alt: "Union",
|
||||
className:
|
||||
"absolute -bottom-[3px] -right-[52px] w-[61px] h-[24px] sm:w-[61px] sm:h-[31.5px] sm:hidden -z-10",
|
||||
}),
|
||||
s.jsx("img", {
|
||||
src: "assets/Union_sm_md_lg.svg",
|
||||
alt: "Union",
|
||||
className:
|
||||
"absolute -bottom-[3.7px] -right-[53px] w-[61px] h-[24px] sm:w-[61px] sm:h-[31.5px] hidden sm:block xl:hidden -z-10",
|
||||
}),
|
||||
s.jsx("img", {
|
||||
src: "assets/Union_xlg.svg",
|
||||
alt: "Union",
|
||||
className:
|
||||
"absolute -bottom-[6px] -right-[94px] w-[105px] h-[53px] hidden xl:block -z-10",
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
n.__docgenInfo = {
|
||||
description: "",
|
||||
methods: [],
|
||||
displayName: "HeaderTab",
|
||||
props: {
|
||||
className: { defaultValue: { value: '""', computed: !1 }, required: !1 },
|
||||
stretch: { defaultValue: { value: "false", computed: !1 }, required: !1 },
|
||||
},
|
||||
};
|
||||
export { n as H };
|
||||
@@ -1,53 +0,0 @@
|
||||
import { j as t } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { H as r } from "./HeaderTab-D9jUrYUx.js";
|
||||
import { L as s } from "./Logo-DM7O8ATg.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const p = {
|
||||
title: "Components/HeaderTab",
|
||||
component: r,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A header tab container with decorative Union images and responsive behavior. Used to wrap content in the header with consistent styling and responsive breakpoint transitions.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
stretch: {
|
||||
control: { type: "boolean" },
|
||||
description: "Whether the tab should stretch to fill available space",
|
||||
},
|
||||
className: {
|
||||
control: { type: "text" },
|
||||
description: "Additional CSS classes",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
e = {
|
||||
args: { stretch: !1 },
|
||||
render: (a) =>
|
||||
t.jsx(r, { ...a, children: t.jsx(s, { size: "homeHeaderMd" }) }),
|
||||
};
|
||||
e.parameters = {
|
||||
...e.parameters,
|
||||
docs: {
|
||||
...e.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
stretch: false
|
||||
},
|
||||
render: args => <HeaderTab {...args}>
|
||||
<Logo size="homeHeaderMd" />
|
||||
</HeaderTab>
|
||||
}`,
|
||||
...e.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const m = ["Default"];
|
||||
export { e as Default, m as __namedExportsOrder, p as default };
|
||||
@@ -1,43 +0,0 @@
|
||||
import { j as a } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { C as t } from "./ContentLockup-DbWiPA4N.js";
|
||||
import { H as p } from "./HeroDecor-Csfoi-N_.js";
|
||||
const c = ({ title: e, subtitle: s, description: r, ctaText: l, ctaHref: n }) =>
|
||||
a.jsx("section", {
|
||||
className:
|
||||
"bg-transparent px-[var(--spacing-scale-008)] sm:px-[var(--spacing-scale-010)] md:px-[var(--spacing-scale-016)] lg:px-[var(--spacing-scale-024)] xl:px-[var(--spacing-scale-048)]",
|
||||
children: a.jsx("div", {
|
||||
className: "flex flex-col gap-[var(--spacing-scale-010)]",
|
||||
children: a.jsxs("div", {
|
||||
className:
|
||||
"bg-[var(--color-surface-default-brand-primary)] p-[var(--spacing-scale-012)] sm:p-[var(--spacing-scale-016)] md:p-[var(--spacing-scale-064)] lg:py-[var(--spacing-scale-096)] lg:px-[var(--spacing-scale-064)] rounded-tl-none rounded-tr-[16px] rounded-br-[16px] rounded-bl-[16px] flex flex-col gap-[var(--spacing-scale-024)] sm:gap-[var(--spacing-scale-024)] md:flex-row md:gap-[var(--spacing-scale-048)] relative overflow-hidden",
|
||||
children: [
|
||||
a.jsx(p, {
|
||||
className:
|
||||
"pointer-events-none absolute z-0 left-0 top-0 translate-x-[-72px] translate-y-[26px] sm:translate-x-[-78px] sm:translate-y-[24px] md:translate-x-[-86px] md:translate-y-[16px] lg:translate-x-[-88px] lg:translate-y-[16px] w-[1540px] h-[645px] scale-[1.04]",
|
||||
}),
|
||||
a.jsx("div", {
|
||||
className: "md:flex-1",
|
||||
children: a.jsx(t, {
|
||||
title: e,
|
||||
subtitle: s,
|
||||
description: r,
|
||||
ctaText: l,
|
||||
ctaHref: n,
|
||||
buttonClassName: "shrink-0 whitespace-nowrap min-w-[280px]",
|
||||
}),
|
||||
}),
|
||||
a.jsx("div", {
|
||||
className:
|
||||
"w-full md:flex-1 rounded-[8px] overflow-hidden relative z-10 flex items-center justify-center",
|
||||
children: a.jsx("img", {
|
||||
src: "assets/HeroImage.png",
|
||||
alt: "Hero illustration",
|
||||
className: "w-full h-auto",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
});
|
||||
c.__docgenInfo = { description: "", methods: [], displayName: "HeroBanner" };
|
||||
export { c as H };
|
||||
@@ -1,82 +0,0 @@
|
||||
import { H as e } from "./HeroBanner-D2qHR4vw.js";
|
||||
import "./jsx-runtime-C_nHp4yK.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
import "./ContentLockup-DbWiPA4N.js";
|
||||
import "./Button-Z4hbXct5.js";
|
||||
import "./HeroDecor-Csfoi-N_.js";
|
||||
const p = {
|
||||
title: "Components/HeroBanner",
|
||||
component: e,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A responsive hero banner component that showcases the Community Rule branding and messaging. Adapts across multiple breakpoints with proper spacing, typography, and interactive elements. Includes background decorations and product demo integration.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
title: { control: { type: "text" }, description: "The main title text" },
|
||||
subtitle: { control: { type: "text" }, description: "The subtitle text" },
|
||||
description: {
|
||||
control: { type: "text" },
|
||||
description: "The description text",
|
||||
},
|
||||
ctaText: {
|
||||
control: { type: "text" },
|
||||
description: "The call-to-action button text",
|
||||
},
|
||||
ctaHref: {
|
||||
control: { type: "text" },
|
||||
description: "The call-to-action button link",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
t = {
|
||||
args: {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Default hero banner with standard Community Rule messaging and branding.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description: "Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Default hero banner with standard Community Rule messaging and branding."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const l = ["Default"];
|
||||
export { t as Default, l as __namedExportsOrder, p as default };
|
||||
@@ -1,523 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { H as t } from "./HeroBanner-D2qHR4vw.js";
|
||||
import { C as r } from "./ContentLockup-DbWiPA4N.js";
|
||||
import { H as o } from "./HeroDecor-Csfoi-N_.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
import "./Button-Z4hbXct5.js";
|
||||
const y = {
|
||||
title: "Systems/HeroBanner System",
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"Complete HeroBanner system showcasing all nested components working together. This demonstrates the full responsive behavior and component integration.",
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
n = {
|
||||
render: () =>
|
||||
e.jsx("div", {
|
||||
className: "min-h-screen bg-gray-50",
|
||||
children: e.jsx(t, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Complete HeroBanner system with all components integrated. Resize your browser to see responsive behavior across all breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
a = {
|
||||
render: () =>
|
||||
e.jsx("div", {
|
||||
className: "space-y-12 p-8",
|
||||
children: e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h2", {
|
||||
className: "text-2xl font-bold mb-6",
|
||||
children: "HeroBanner Components",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-y-8",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-4",
|
||||
children: "1. ContentLockup Component",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"bg-[var(--color-surface-default-brand-primary)] p-8 rounded-lg",
|
||||
children: e.jsx(r, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-4",
|
||||
children: "2. HeroDecor Component",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"bg-[var(--color-surface-default-brand-primary)] p-8 rounded-lg relative overflow-hidden h-64",
|
||||
children: [
|
||||
e.jsx(o, { className: "w-full h-full" }),
|
||||
e.jsx("div", {
|
||||
className: "relative z-10 text-white mt-4",
|
||||
children: e.jsx("p", {
|
||||
children: "Decoration appears behind content",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-4",
|
||||
children: "3. Complete HeroBanner",
|
||||
}),
|
||||
e.jsx(t, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Breakdown of individual components that make up the HeroBanner system, showing how they work together.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
s = {
|
||||
render: () =>
|
||||
e.jsxs("div", {
|
||||
className: "space-y-8 p-8",
|
||||
children: [
|
||||
e.jsx("h2", {
|
||||
className: "text-2xl font-bold",
|
||||
children: "Responsive Breakpoints",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-2",
|
||||
children: "XSmall (≤429px)",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"border-2 border-gray-300 rounded-lg overflow-hidden",
|
||||
style: { width: "400px" },
|
||||
children: e.jsx(t, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-2",
|
||||
children: "Small (430px+)",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"border-2 border-gray-300 rounded-lg overflow-hidden",
|
||||
style: { width: "600px" },
|
||||
children: e.jsx(t, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-2",
|
||||
children: "Medium (768px+)",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"border-2 border-gray-300 rounded-lg overflow-hidden",
|
||||
style: { width: "900px" },
|
||||
children: e.jsx(t, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-2",
|
||||
children: "Large (1024px+)",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"border-2 border-gray-300 rounded-lg overflow-hidden",
|
||||
style: { width: "1200px" },
|
||||
children: e.jsx(t, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-2",
|
||||
children: "XLarge (1440px+)",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"border-2 border-gray-300 rounded-lg overflow-hidden",
|
||||
style: { width: "1600px" },
|
||||
children: e.jsx(t, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"HeroBanner system demonstrating responsive behavior at each breakpoint. Each container simulates a different screen size.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
i = {
|
||||
render: () =>
|
||||
e.jsxs("div", {
|
||||
className: "space-y-8 p-8",
|
||||
children: [
|
||||
e.jsx("h2", {
|
||||
className: "text-2xl font-bold",
|
||||
children: "Content Variations",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-2",
|
||||
children: "Standard Content",
|
||||
}),
|
||||
e.jsx(t, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-2",
|
||||
children: "Alternative Content",
|
||||
}),
|
||||
e.jsx(t, {
|
||||
title: "Build",
|
||||
subtitle: "better communities",
|
||||
description:
|
||||
"Create operating manuals that help your community thrive and make decisions together.",
|
||||
ctaText: "Get started today",
|
||||
ctaHref: "/signup",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-lg font-semibold mb-2",
|
||||
children: "Long Description",
|
||||
}),
|
||||
e.jsx(t, {
|
||||
title: "Collaborate",
|
||||
subtitle: "with clarity",
|
||||
description:
|
||||
"Help your community make important decisions in a way that reflects its unique values. Our platform provides the tools and frameworks needed to build successful, sustainable communities that can navigate complex challenges together.",
|
||||
ctaText: "Learn how Community Rule works",
|
||||
ctaHref: "#",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"HeroBanner system with different content variations to demonstrate flexibility and content handling.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
n.parameters = {
|
||||
...n.parameters,
|
||||
docs: {
|
||||
...n.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
render: () => <div className="min-h-screen bg-gray-50">
|
||||
<HeroBanner title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Complete HeroBanner system with all components integrated. Resize your browser to see responsive behavior across all breakpoints."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...n.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
a.parameters = {
|
||||
...a.parameters,
|
||||
docs: {
|
||||
...a.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
render: () => <div className="space-y-12 p-8">
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold mb-6">HeroBanner Components</h2>
|
||||
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-4">
|
||||
1. ContentLockup Component
|
||||
</h3>
|
||||
<div className="bg-[var(--color-surface-default-brand-primary)] p-8 rounded-lg">
|
||||
<ContentLockup title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-4">
|
||||
2. HeroDecor Component
|
||||
</h3>
|
||||
<div className="bg-[var(--color-surface-default-brand-primary)] p-8 rounded-lg relative overflow-hidden h-64">
|
||||
<HeroDecor className="w-full h-full" />
|
||||
<div className="relative z-10 text-white mt-4">
|
||||
<p>Decoration appears behind content</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-4">
|
||||
3. Complete HeroBanner
|
||||
</h3>
|
||||
<HeroBanner title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Breakdown of individual components that make up the HeroBanner system, showing how they work together."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...a.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
s.parameters = {
|
||||
...s.parameters,
|
||||
docs: {
|
||||
...s.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
render: () => <div className="space-y-8 p-8">
|
||||
<h2 className="text-2xl font-bold">Responsive Breakpoints</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2">XSmall (≤429px)</h3>
|
||||
<div className="border-2 border-gray-300 rounded-lg overflow-hidden" style={{
|
||||
width: "400px"
|
||||
}}>
|
||||
<HeroBanner title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2">Small (430px+)</h3>
|
||||
<div className="border-2 border-gray-300 rounded-lg overflow-hidden" style={{
|
||||
width: "600px"
|
||||
}}>
|
||||
<HeroBanner title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2">Medium (768px+)</h3>
|
||||
<div className="border-2 border-gray-300 rounded-lg overflow-hidden" style={{
|
||||
width: "900px"
|
||||
}}>
|
||||
<HeroBanner title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2">Large (1024px+)</h3>
|
||||
<div className="border-2 border-gray-300 rounded-lg overflow-hidden" style={{
|
||||
width: "1200px"
|
||||
}}>
|
||||
<HeroBanner title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2">XLarge (1440px+)</h3>
|
||||
<div className="border-2 border-gray-300 rounded-lg overflow-hidden" style={{
|
||||
width: "1600px"
|
||||
}}>
|
||||
<HeroBanner title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "HeroBanner system demonstrating responsive behavior at each breakpoint. Each container simulates a different screen size."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...s.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
i.parameters = {
|
||||
...i.parameters,
|
||||
docs: {
|
||||
...i.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
render: () => <div className="space-y-8 p-8">
|
||||
<h2 className="text-2xl font-bold">Content Variations</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2">Standard Content</h3>
|
||||
<HeroBanner title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2">Alternative Content</h3>
|
||||
<HeroBanner title="Build" subtitle="better communities" description="Create operating manuals that help your community thrive and make decisions together." ctaText="Get started today" ctaHref="/signup" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2">Long Description</h3>
|
||||
<HeroBanner title="Collaborate" subtitle="with clarity" description="Help your community make important decisions in a way that reflects its unique values. Our platform provides the tools and frameworks needed to build successful, sustainable communities that can navigate complex challenges together." ctaText="Learn how Community Rule works" ctaHref="#" />
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "HeroBanner system with different content variations to demonstrate flexibility and content handling."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...i.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const v = [
|
||||
"CompleteSystem",
|
||||
"ComponentBreakdown",
|
||||
"ResponsiveBreakpoints",
|
||||
"ContentVariations",
|
||||
];
|
||||
export {
|
||||
n as CompleteSystem,
|
||||
a as ComponentBreakdown,
|
||||
i as ContentVariations,
|
||||
s as ResponsiveBreakpoints,
|
||||
v as __namedExportsOrder,
|
||||
y as default,
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
const s = ({ className: C = "" }) =>
|
||||
e.jsx("svg", {
|
||||
className: `text-[#FDFAA8] opacity-50 ${C}`,
|
||||
viewBox: "0 0 1540 645",
|
||||
"aria-hidden": "true",
|
||||
overflow: "visible",
|
||||
preserveAspectRatio: "xMidYMid slice",
|
||||
children: e.jsxs("g", {
|
||||
fill: "currentColor",
|
||||
children: [
|
||||
e.jsx("defs", {
|
||||
children: e.jsxs("filter", {
|
||||
id: "grain",
|
||||
filterUnits: "objectBoundingBox",
|
||||
x: "0",
|
||||
y: "0",
|
||||
width: "1",
|
||||
height: "1",
|
||||
colorInterpolationFilters: "sRGB",
|
||||
children: [
|
||||
e.jsx("feTurbulence", {
|
||||
type: "fractalNoise",
|
||||
baseFrequency: "0.8",
|
||||
numOctaves: "2",
|
||||
seed: "3",
|
||||
stitchTiles: "stitch",
|
||||
result: "noise",
|
||||
}),
|
||||
e.jsx("feColorMatrix", {
|
||||
in: "noise",
|
||||
result: "softNoise",
|
||||
type: "matrix",
|
||||
values: " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0",
|
||||
}),
|
||||
e.jsx("feComposite", {
|
||||
in: "softNoise",
|
||||
in2: "SourceAlpha",
|
||||
operator: "in",
|
||||
result: "maskedNoise",
|
||||
}),
|
||||
e.jsx("feBlend", {
|
||||
in: "SourceGraphic",
|
||||
in2: "maskedNoise",
|
||||
mode: "multiply",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
e.jsxs("g", {
|
||||
fill: "currentColor",
|
||||
filter: "url(#grain)",
|
||||
children: [
|
||||
e.jsx("path", {
|
||||
d: "M1441.54 226.758C1495.92 226.758 1540 320.385 1540 435.879C1540 551.373 1495.92 645 1441.54 645C1387.16 645 1343.08 551.373 1343.08 435.879C1343.08 320.385 1387.16 226.758 1441.54 226.758Z",
|
||||
}),
|
||||
e.jsx("path", {
|
||||
d: "M1441.54 226.758C1495.92 226.758 1540 320.385 1540 435.879C1540 551.373 1495.92 645 1441.54 645C1387.16 645 1343.08 551.373 1343.08 435.879C1343.08 320.385 1387.16 226.758 1441.54 226.758Z",
|
||||
}),
|
||||
e.jsx("path", {
|
||||
d: "M674.066 209.121C728.443 209.121 772.525 302.748 772.525 418.242C772.525 533.737 728.443 627.363 674.066 627.363C619.688 627.363 575.607 533.737 575.607 418.242C575.607 302.748 619.688 209.121 674.066 209.121Z",
|
||||
}),
|
||||
e.jsx("path", {
|
||||
d: "M674.066 209.121C728.443 209.121 772.525 302.748 772.525 418.242C772.525 533.737 728.443 627.363 674.066 627.363C619.688 627.363 575.607 533.737 575.607 418.242C575.607 302.748 619.688 209.121 674.066 209.121Z",
|
||||
}),
|
||||
e.jsx("path", {
|
||||
d: "M290.328 0C344.705 0 388.787 93.6267 388.787 209.121C388.787 211.519 388.765 213.907 388.728 216.285C401.725 133.082 438.661 73.0664 482.197 73.0664C536.574 73.0664 580.656 166.693 580.656 282.188C580.656 397.682 536.574 491.309 482.197 491.309C427.819 491.309 383.738 397.682 383.738 282.188C383.738 279.79 383.758 277.401 383.796 275.023C370.798 358.226 333.864 418.242 290.328 418.242C246.792 418.242 209.856 358.226 196.859 275.023C196.897 277.401 196.918 279.79 196.918 282.188C196.918 397.682 152.836 491.309 98.459 491.309C44.0816 491.309 0 397.682 0 282.188C0 166.693 44.0816 73.0664 98.459 73.0664C141.995 73.0664 178.929 133.082 191.927 216.285C191.889 213.907 191.869 211.519 191.869 209.121C191.869 93.6267 235.95 0 290.328 0Z",
|
||||
}),
|
||||
e.jsx("path", {
|
||||
d: "M290.328 0C344.705 0 388.787 93.6267 388.787 209.121C388.787 211.519 388.765 213.907 388.728 216.285C401.725 133.082 438.661 73.0664 482.197 73.0664C536.574 73.0664 580.656 166.693 580.656 282.188C580.656 397.682 536.574 491.309 482.197 491.309C427.819 491.309 383.738 397.682 383.738 282.188C383.738 279.79 383.758 277.401 383.796 275.023C370.798 358.226 333.864 418.242 290.328 418.242C246.792 418.242 209.856 358.226 196.859 275.023C196.897 277.401 196.918 279.79 196.918 282.188C196.918 397.682 152.836 491.309 98.459 491.309C44.0816 491.309 0 397.682 0 282.188C0 166.693 44.0816 73.0664 98.459 73.0664C141.995 73.0664 178.929 133.082 191.927 216.285C191.889 213.907 191.869 211.519 191.869 209.121C191.869 93.6267 235.95 0 290.328 0Z",
|
||||
}),
|
||||
e.jsx("path", {
|
||||
d: "M1057.8 0C1112.18 0 1156.26 93.6267 1156.26 209.121C1156.26 211.519 1156.24 213.907 1156.2 216.285C1169.2 133.082 1206.14 73.0664 1249.67 73.0664C1304.05 73.0664 1348.13 166.693 1348.13 282.188C1348.13 397.682 1304.05 491.309 1249.67 491.309C1195.29 491.309 1151.21 397.682 1151.21 282.188C1151.21 279.79 1151.23 277.401 1151.27 275.023C1138.27 358.226 1101.34 418.242 1057.8 418.242C1014.27 418.242 977.332 358.226 964.334 275.023C964.372 277.401 964.393 279.79 964.393 282.188C964.393 397.682 920.312 491.309 865.934 491.309C811.557 491.309 767.475 397.682 767.475 282.188C767.475 166.693 811.557 73.0664 865.934 73.0664C909.47 73.0664 946.405 133.082 959.402 216.285C959.365 213.907 959.344 211.519 959.344 209.121C959.344 93.6267 1003.43 0 1057.8 0Z",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
});
|
||||
s.__docgenInfo = {
|
||||
description: "",
|
||||
methods: [],
|
||||
displayName: "HeroDecor",
|
||||
props: {
|
||||
className: { defaultValue: { value: '""', computed: !1 }, required: !1 },
|
||||
},
|
||||
};
|
||||
export { s as H };
|
||||
@@ -1,120 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { H as o } from "./HeroDecor-Csfoi-N_.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const d = {
|
||||
title: "Components/HeroDecor",
|
||||
component: o,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A decorative SVG component that provides background visual elements for the HeroBanner. Features grain effects and organic shapes that enhance the visual appeal without interfering with content readability.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
className: {
|
||||
control: { type: "text" },
|
||||
description: "Additional CSS classes for positioning and styling",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
r = {
|
||||
args: { className: "w-[400px] h-[200px]" },
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Default hero decoration with standard sizing and positioning.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
t = {
|
||||
args: { className: "w-[600px] h-[300px]" },
|
||||
render: (a) =>
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"bg-[var(--color-surface-default-brand-primary)] p-8 rounded-lg relative overflow-hidden",
|
||||
children: [
|
||||
e.jsx(o, { ...a }),
|
||||
e.jsxs("div", {
|
||||
className: "relative z-10 text-white mt-4",
|
||||
children: [
|
||||
e.jsx("h3", { children: "Content Overlay" }),
|
||||
e.jsx("p", {
|
||||
children:
|
||||
"This demonstrates how the decoration appears behind content.",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Hero decoration with background color to show how it integrates with content.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
r.parameters = {
|
||||
...r.parameters,
|
||||
docs: {
|
||||
...r.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
className: "w-[400px] h-[200px]"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Default hero decoration with standard sizing and positioning."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...r.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
className: "w-[600px] h-[300px]"
|
||||
},
|
||||
render: args => <div className="bg-[var(--color-surface-default-brand-primary)] p-8 rounded-lg relative overflow-hidden">
|
||||
<HeroDecor {...args} />
|
||||
<div className="relative z-10 text-white mt-4">
|
||||
<h3>Content Overlay</h3>
|
||||
<p>This demonstrates how the decoration appears behind content.</p>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Hero decoration with background color to show how it integrates with content."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const p = ["Default", "WithBackground"];
|
||||
export {
|
||||
r as Default,
|
||||
t as WithBackground,
|
||||
p as __namedExportsOrder,
|
||||
d as default,
|
||||
};
|
||||
|
Before Width: | Height: | Size: 112 KiB |
@@ -1,393 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { r as w } from "./iframe-D_aMTKb2.js";
|
||||
import { L as N } from "./Logo-DM7O8ATg.js";
|
||||
import { M as l } from "./MenuBar-anMCqtJv.js";
|
||||
import { M as p } from "./MenuBarItem-Dp8NM2fx.js";
|
||||
import { B as y } from "./Button-Z4hbXct5.js";
|
||||
import { A as k } from "./AvatarContainer-Bt0G0TWZ.js";
|
||||
import { A as H } from "./Avatar-C4Vb3oYl.js";
|
||||
import { H as T } from "./HeaderTab-D9jUrYUx.js";
|
||||
import { H as A } from "./Header-Bz-bT1Sq.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
function m() {
|
||||
const [t, h] = w.useState(!1),
|
||||
g = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
name: "CommunityRule",
|
||||
url: "https://communityrule.com",
|
||||
description: "Build operating manuals for successful communities",
|
||||
potentialAction: {
|
||||
"@type": "SearchAction",
|
||||
target: "https://communityrule.com/search?q={search_term_string}",
|
||||
"query-input": "required name=search_term_string",
|
||||
},
|
||||
},
|
||||
x = [
|
||||
{ href: "#", text: "Use cases", extraPadding: !0 },
|
||||
{ href: "#", text: "Learn" },
|
||||
{ href: "#", text: "About" },
|
||||
],
|
||||
u = [
|
||||
{ src: "/assets/Avatar_1.png", alt: "Avatar 1" },
|
||||
{ src: "/assets/Avatar_2.png", alt: "Avatar 2" },
|
||||
{ src: "/assets/Avatar_3.png", alt: "Avatar 3" },
|
||||
],
|
||||
f = [
|
||||
{ breakpoint: "block sm:hidden", size: "homeHeaderXsmall", showText: !1 },
|
||||
{
|
||||
breakpoint: "hidden sm:block md:hidden",
|
||||
size: "homeHeaderSm",
|
||||
showText: !0,
|
||||
},
|
||||
{
|
||||
breakpoint: "hidden md:block lg:hidden",
|
||||
size: "homeHeaderMd",
|
||||
showText: !0,
|
||||
},
|
||||
{
|
||||
breakpoint: "hidden lg:block xl:hidden",
|
||||
size: "homeHeaderLg",
|
||||
showText: !0,
|
||||
},
|
||||
{ breakpoint: "hidden xl:block", size: "homeHeaderXl", showText: !0 },
|
||||
],
|
||||
n = (a) =>
|
||||
x.map((r, s) =>
|
||||
e.jsx(
|
||||
p,
|
||||
{
|
||||
href: r.href,
|
||||
size:
|
||||
r.extraPadding &&
|
||||
(a === "xsmall" ||
|
||||
a === "default" ||
|
||||
a === "home" ||
|
||||
a === "homeMd" ||
|
||||
a === "large" ||
|
||||
a === "homeXlarge")
|
||||
? a === "home" || a === "homeMd"
|
||||
? "homeMd"
|
||||
: a === "large"
|
||||
? "large"
|
||||
: a === "homeXlarge"
|
||||
? "homeXlarge"
|
||||
: "xsmallUseCases"
|
||||
: a,
|
||||
variant:
|
||||
a === "xsmall" ||
|
||||
a === "default" ||
|
||||
a === "home" ||
|
||||
a === "homeMd" ||
|
||||
a === "large" ||
|
||||
a === "homeXlarge"
|
||||
? "home"
|
||||
: "default",
|
||||
onClick: () => h(!t),
|
||||
ariaLabel: `Navigate to ${r.text} page`,
|
||||
children: r.text,
|
||||
},
|
||||
s,
|
||||
),
|
||||
),
|
||||
v = (a, r) =>
|
||||
e.jsx(k, {
|
||||
size: a,
|
||||
children: u.map((s, j) =>
|
||||
e.jsx(H, { src: s.src, alt: s.alt, size: r }, j),
|
||||
),
|
||||
}),
|
||||
o = (a) =>
|
||||
e.jsx(p, {
|
||||
href: "#",
|
||||
size: a,
|
||||
variant: a === "xsmall" || a === "default" ? "home" : "default",
|
||||
ariaLabel: "Log in to your account",
|
||||
children: "Log in",
|
||||
}),
|
||||
d = (a, r, s) =>
|
||||
e.jsxs(y, {
|
||||
size: a,
|
||||
variant: "secondary",
|
||||
ariaLabel: "Create a new rule with avatar decoration",
|
||||
children: [v(r, s), e.jsx("span", { children: "Create rule" })],
|
||||
}),
|
||||
b = (a, r) => e.jsx(N, { size: a, showText: r });
|
||||
return t
|
||||
? e.jsx(A, { onToggle: () => h(!1) })
|
||||
: e.jsxs(e.Fragment, {
|
||||
children: [
|
||||
e.jsx("script", {
|
||||
type: "application/ld+json",
|
||||
dangerouslySetInnerHTML: { __html: JSON.stringify(g) },
|
||||
}),
|
||||
e.jsx("header", {
|
||||
className: "w-full bg-transparent overflow-hidden",
|
||||
role: "banner",
|
||||
"aria-label": "Home page navigation header",
|
||||
children: e.jsxs("nav", {
|
||||
className:
|
||||
"relative flex items-center justify-between mx-auto h-[50px] sm:h-[62px] md:h-[68px] lg:h-[68px] xl:h-[88px] px-[var(--spacing-scale-008)] pr-[var(--spacing-scale-016)] pt-[var(--spacing-scale-010)] sm:px-[var(--spacing-scale-010)] sm:pr-[var(--spacing-scale-020)] sm:pt-[var(--spacing-scale-010)] md:px-[var(--spacing-scale-016)] md:pr-[var(--spacing-scale-032)] md:pt-[var(--spacing-scale-016)] lg:pl-[var(--spacing-scale-024)] lg:pt-[var(--spacing-scale-016)] lg:pr-[var(--spacing-scale-056)] xl:pl-[var(--spacing-scale-048)] xl:pt-[var(--spacing-scale-024)] xl:pr-[var(--spacing-scale-056)]",
|
||||
role: "navigation",
|
||||
"aria-label": "Main navigation",
|
||||
children: [
|
||||
e.jsxs(T, {
|
||||
className: "flex items-center self-end",
|
||||
stretch: !0,
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
children: f.map((a, r) =>
|
||||
e.jsx(
|
||||
"div",
|
||||
{
|
||||
className: a.breakpoint,
|
||||
children: b(a.size, a.showText),
|
||||
},
|
||||
r,
|
||||
),
|
||||
),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "block sm:hidden -me-[2px]",
|
||||
children: e.jsxs(l, {
|
||||
size: "default",
|
||||
children: [n("xsmall"), o("xsmall")],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"absolute left-1/2 transform -translate-x-1/2 hidden sm:block",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className: "hidden sm:block md:hidden",
|
||||
children: e.jsxs(l, {
|
||||
size: "default",
|
||||
children: [n("xsmall"), o("xsmall")],
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden md:block lg:hidden",
|
||||
children: e.jsx(l, {
|
||||
size: "medium",
|
||||
children: n("homeMd"),
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden lg:block xl:hidden",
|
||||
children: e.jsx(l, {
|
||||
size: "large",
|
||||
children: n("large"),
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden xl:block",
|
||||
children: e.jsx(l, {
|
||||
size: "large",
|
||||
children: n("homeXlarge"),
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className: "block md:hidden",
|
||||
children: d("xsmall", "small", "small"),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"hidden md:block lg:hidden absolute right-[var(--spacing-measures-spacing-016)]",
|
||||
children: e.jsxs("div", {
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-scale-010)]",
|
||||
children: [o("homeMd"), d("small", "medium", "medium")],
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden lg:flex xl:hidden items-center",
|
||||
children: e.jsxs("div", {
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-scale-004)]",
|
||||
children: [o("large"), d("large", "large", "large")],
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden xl:flex items-center",
|
||||
children: e.jsxs("div", {
|
||||
className:
|
||||
"flex items-center gap-[var(--spacing-scale-004)]",
|
||||
children: [
|
||||
o("homeXlarge"),
|
||||
d("xlarge", "xlarge", "xlarge"),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
m.__docgenInfo = { description: "", methods: [], displayName: "HomeHeader" };
|
||||
const U = {
|
||||
title: "Components/HomeHeader",
|
||||
component: m,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"The home page header with transparent background, HeaderTab wrapper, and responsive behavior. Features a toggle to switch between home header and regular header.",
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
i = {
|
||||
args: {},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Use the Viewport toolbar to see how the home header adapts to different screen sizes. The header has a transparent background and uses HeaderTab for the left section.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
c = {
|
||||
args: {},
|
||||
render: () =>
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"min-h-screen bg-gradient-to-b from-[var(--color-surface-default-primary)] to-[var(--color-surface-default-secondary)]",
|
||||
children: [
|
||||
e.jsx(m, {}),
|
||||
e.jsx("main", {
|
||||
className: "p-8",
|
||||
children: e.jsxs("div", {
|
||||
className: "max-w-4xl mx-auto text-center",
|
||||
children: [
|
||||
e.jsx("h1", {
|
||||
className: "text-4xl font-bold text-white mb-4",
|
||||
children: "Welcome to CommunityRule",
|
||||
}),
|
||||
e.jsx("p", {
|
||||
className:
|
||||
"text-xl text-[var(--color-content-default-secondary)] mb-8",
|
||||
children:
|
||||
"This demonstrates how the home header looks in a realistic home page context. The header maintains its transparent background and responsive behavior.",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",
|
||||
children: [1, 2, 3].map((t) =>
|
||||
e.jsxs(
|
||||
"div",
|
||||
{
|
||||
className:
|
||||
"bg-[var(--color-surface-default-secondary)] p-6 rounded-lg border border-[var(--border-color-default-tertiary)]",
|
||||
children: [
|
||||
e.jsxs("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: ["Feature ", t],
|
||||
}),
|
||||
e.jsx("p", {
|
||||
className:
|
||||
"text-[var(--color-content-default-secondary)]",
|
||||
children:
|
||||
"This is example content to show how the home header integrates with home page content.",
|
||||
}),
|
||||
],
|
||||
},
|
||||
t,
|
||||
),
|
||||
),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"The home header integrated into a full home page layout with gradient background to show the transparent header effect.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
i.parameters = {
|
||||
...i.parameters,
|
||||
docs: {
|
||||
...i.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Use the Viewport toolbar to see how the home header adapts to different screen sizes. The header has a transparent background and uses HeaderTab for the left section."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...i.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
c.parameters = {
|
||||
...c.parameters,
|
||||
docs: {
|
||||
...c.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="min-h-screen bg-gradient-to-b from-[var(--color-surface-default-primary)] to-[var(--color-surface-default-secondary)]">
|
||||
<HomeHeader />
|
||||
<main className="p-8">
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
<h1 className="text-4xl font-bold text-white mb-4">
|
||||
Welcome to CommunityRule
|
||||
</h1>
|
||||
<p className="text-xl text-[var(--color-content-default-secondary)] mb-8">
|
||||
This demonstrates how the home header looks in a realistic home page
|
||||
context. The header maintains its transparent background and
|
||||
responsive behavior.
|
||||
</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{[1, 2, 3].map(i => <div key={i} className="bg-[var(--color-surface-default-secondary)] p-6 rounded-lg border border-[var(--border-color-default-tertiary)]">
|
||||
<h3 className="text-white font-semibold mb-3">Feature {i}</h3>
|
||||
<p className="text-[var(--color-content-default-secondary)]">
|
||||
This is example content to show how the home header integrates
|
||||
with home page content.
|
||||
</p>
|
||||
</div>)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "The home header integrated into a full home page layout with gradient background to show the transparent header effect."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...c.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const q = ["Default", "InHomePageContext"];
|
||||
export {
|
||||
i as Default,
|
||||
c as InHomePageContext,
|
||||
q as __namedExportsOrder,
|
||||
U as default,
|
||||
};
|
||||
@@ -1,144 +0,0 @@
|
||||
import { j as i } from "./jsx-runtime-C_nHp4yK.js";
|
||||
function p({ size: e = "default", showText: o = !0 }) {
|
||||
const a = {
|
||||
default: {
|
||||
containerHeight: "h-[41px]",
|
||||
gap: "gap-[8.28px]",
|
||||
textSize: "text-[21.97px]",
|
||||
lineHeight: "leading-[27.05px]",
|
||||
iconSize: "w-[27.05px] h-[27.05px]",
|
||||
},
|
||||
homeHeaderXsmall: {
|
||||
containerHeight: "h-[14.11px]",
|
||||
gap: "gap-[4.21px]",
|
||||
textSize: "text-[11.57px]",
|
||||
lineHeight: "leading-[14.24px]",
|
||||
iconSize: "w-[14.11px] h-[14.11px]",
|
||||
},
|
||||
homeHeaderSm: {
|
||||
containerHeight: "h-[21.06px]",
|
||||
gap: "gap-[3.19px]",
|
||||
textSize: "text-[11.69px]",
|
||||
lineHeight: "leading-[14.39px]",
|
||||
iconSize: "w-[14.39px] h-[14.39px]",
|
||||
},
|
||||
homeHeaderMd: {
|
||||
containerHeight: "h-[32.24px]",
|
||||
gap: "gap-[4.89px]",
|
||||
textSize: "text-[17.89px]",
|
||||
lineHeight: "leading-[22.02px]",
|
||||
iconSize: "w-[22.02px] h-[22.02px]",
|
||||
},
|
||||
homeHeaderLg: {
|
||||
containerHeight: "h-[28px]",
|
||||
gap: "gap-[6.55px]",
|
||||
textSize: "text-[21.97px]",
|
||||
lineHeight: "leading-[27.05px]",
|
||||
iconSize: "w-[27.05px] h-[27.05px]",
|
||||
},
|
||||
homeHeaderXl: {
|
||||
containerHeight: "h-[36px]",
|
||||
gap: "gap-[8.64px]",
|
||||
textSize: "text-[29.01px]",
|
||||
lineHeight: "leading-[35.7px]",
|
||||
iconSize: "w-[35.7px] h-[35.7px]",
|
||||
},
|
||||
header: {
|
||||
containerHeight: "h-[20.85px]",
|
||||
gap: "gap-[4.21px]",
|
||||
textSize: "text-[11.57px]",
|
||||
lineHeight: "leading-[14.24px]",
|
||||
iconSize: "w-[14.24px] h-[14.24px]",
|
||||
},
|
||||
headerMd: {
|
||||
containerHeight: "h-[17.91px]",
|
||||
gap: "gap-[6.51px]",
|
||||
textSize: "text-[17.89px]",
|
||||
lineHeight: "leading-[22.02px]",
|
||||
iconSize: "w-[22.02px] h-[22.02px]",
|
||||
},
|
||||
headerLg: {
|
||||
containerHeight: "h-[28px]",
|
||||
gap: "gap-[6.55px]",
|
||||
textSize: "text-[21.97px]",
|
||||
lineHeight: "leading-[27.05px]",
|
||||
iconSize: "w-[27.05px] h-[27.05px]",
|
||||
},
|
||||
headerXl: {
|
||||
containerHeight: "h-[34px]",
|
||||
gap: "gap-[8.19px]",
|
||||
textSize: "text-[27.47px]",
|
||||
lineHeight: "leading-[33.81px]",
|
||||
iconSize: "w-[33.81px] h-[33.81px]",
|
||||
},
|
||||
footer: {
|
||||
containerHeight: "h-[calc(40px*1.37)]",
|
||||
gap: "gap-[calc(8px*1.37)]",
|
||||
textSize: "text-[calc(21.97px*1.37)]",
|
||||
lineHeight: "leading-[calc(27.05px*1.37)]",
|
||||
iconSize: "w-[calc(27.05px*1.37)] h-[calc(27.05px*1.37)]",
|
||||
},
|
||||
footerLg: {
|
||||
containerHeight: "h-[calc(40px*2.05)]",
|
||||
gap: "gap-[calc(8px*2.05)]",
|
||||
textSize: "text-[calc(21.97px*2.05)]",
|
||||
lineHeight: "leading-[calc(27.05px*2.05)]",
|
||||
iconSize: "w-[calc(27.05px*2.05)] h-[calc(27.05px*2.05)]",
|
||||
},
|
||||
},
|
||||
t =
|
||||
e === "homeHeaderXsmall"
|
||||
? a.homeHeaderXsmall
|
||||
: e === "homeHeaderSm"
|
||||
? a.homeHeaderSm
|
||||
: e === "homeHeaderMd"
|
||||
? a.homeHeaderMd
|
||||
: e === "homeHeaderLg"
|
||||
? a.homeHeaderLg
|
||||
: e === "homeHeaderXl"
|
||||
? a.homeHeaderXl
|
||||
: e === "header"
|
||||
? a.header
|
||||
: e === "headerMd"
|
||||
? a.headerMd
|
||||
: e === "headerLg"
|
||||
? a.headerLg
|
||||
: e === "headerXl"
|
||||
? a.headerXl
|
||||
: e === "footer"
|
||||
? a.footer
|
||||
: e === "footerLg"
|
||||
? a.footerLg
|
||||
: a.default;
|
||||
return i.jsxs("div", {
|
||||
className: `flex items-center ${t.containerHeight} ${o ? t.gap : ""} transition-all duration-200 ease-in-out hover:scale-[1.02] cursor-pointer`,
|
||||
role: "banner",
|
||||
"aria-label": "CommunityRule Logo",
|
||||
children: [
|
||||
o &&
|
||||
i.jsx("div", {
|
||||
className: `font-['Bricolage_Grotesque'] ${e === "homeHeaderXsmall" || e === "homeHeaderSm" || e === "homeHeaderMd" || e === "homeHeaderLg" || e === "homeHeaderXl" ? "text-[var(--color-content-inverse-primary)]" : "text-[var(--color-content-default-primary)]"} ${t.textSize} ${t.lineHeight} font-normal tracking-[0px] transition-colors duration-200`,
|
||||
"aria-label": "CommunityRule",
|
||||
children: "CommunityRule",
|
||||
}),
|
||||
i.jsx("img", {
|
||||
src: "assets/Logo.svg",
|
||||
alt: "CommunityRule Logo Icon",
|
||||
width: 27.05,
|
||||
height: 27.05,
|
||||
className: `flex-shrink-0 ${t.iconSize} transition-all duration-200 ${e === "homeHeaderXsmall" || e === "homeHeaderSm" || e === "homeHeaderMd" || e === "homeHeaderLg" || e === "homeHeaderXl" ? "filter brightness-0" : ""}`,
|
||||
"aria-hidden": "true",
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
p.__docgenInfo = {
|
||||
description: "",
|
||||
methods: [],
|
||||
displayName: "Logo",
|
||||
props: {
|
||||
size: { defaultValue: { value: '"default"', computed: !1 }, required: !1 },
|
||||
showText: { defaultValue: { value: "true", computed: !1 }, required: !1 },
|
||||
},
|
||||
};
|
||||
export { p as L };
|
||||
@@ -1,672 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { L as s } from "./Logo-DM7O8ATg.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const h = {
|
||||
title: "Components/Logo",
|
||||
component: s,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"The CommunityRule logo component with multiple size variants for different contexts (header, footer, home header). Can display with or without text and adapts colors based on context.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
control: { type: "select" },
|
||||
options: [
|
||||
"default",
|
||||
"homeHeaderXsmall",
|
||||
"homeHeaderSm",
|
||||
"homeHeaderMd",
|
||||
"homeHeaderLg",
|
||||
"homeHeaderXl",
|
||||
"header",
|
||||
"headerMd",
|
||||
"headerLg",
|
||||
"headerXl",
|
||||
"footer",
|
||||
"footerLg",
|
||||
],
|
||||
description: "The size variant of the logo",
|
||||
},
|
||||
showText: {
|
||||
control: { type: "boolean" },
|
||||
description: "Whether to show the text portion of the logo",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
t = { args: { size: "default", showText: !0 } },
|
||||
n = {
|
||||
args: { showText: !0 },
|
||||
render: (a) =>
|
||||
e.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Default Sizes",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(s, { ...a, size: "default" }),
|
||||
e.jsx(s, { ...a, size: "header" }),
|
||||
e.jsx(s, { ...a, size: "footer" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Header Sizes",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(s, { ...a, size: "header" }),
|
||||
e.jsx(s, { ...a, size: "headerMd" }),
|
||||
e.jsx(s, { ...a, size: "headerLg" }),
|
||||
e.jsx(s, { ...a, size: "headerXl" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Home Header Sizes",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(s, { ...a, size: "homeHeaderXsmall" }),
|
||||
e.jsx(s, { ...a, size: "homeHeaderSm" }),
|
||||
e.jsx(s, { ...a, size: "homeHeaderMd" }),
|
||||
e.jsx(s, { ...a, size: "homeHeaderLg" }),
|
||||
e.jsx(s, { ...a, size: "homeHeaderXl" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Footer Sizes",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(s, { ...a, size: "footer" }),
|
||||
e.jsx(s, { ...a, size: "footerLg" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Different size variants available for the logo component across different contexts.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
r = {
|
||||
args: { size: "default", showText: !1 },
|
||||
render: (a) =>
|
||||
e.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Icon Only - Default Sizes",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(s, { ...a, size: "default" }),
|
||||
e.jsx(s, { ...a, size: "header" }),
|
||||
e.jsx(s, { ...a, size: "footer" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Icon Only - Header Sizes",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(s, { ...a, size: "header" }),
|
||||
e.jsx(s, { ...a, size: "headerMd" }),
|
||||
e.jsx(s, { ...a, size: "headerLg" }),
|
||||
e.jsx(s, { ...a, size: "headerXl" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Icon Only - Home Header Sizes",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(s, { ...a, size: "homeHeaderXsmall" }),
|
||||
e.jsx(s, { ...a, size: "homeHeaderSm" }),
|
||||
e.jsx(s, { ...a, size: "homeHeaderMd" }),
|
||||
e.jsx(s, { ...a, size: "homeHeaderLg" }),
|
||||
e.jsx(s, { ...a, size: "homeHeaderXl" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Logo variants with only the icon, no text. Useful for compact spaces.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
i = {
|
||||
args: {},
|
||||
render: () =>
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"min-h-screen bg-gradient-to-b from-[var(--color-surface-default-primary)] to-[var(--color-surface-default-secondary)] p-8",
|
||||
children: e.jsxs("div", {
|
||||
className: "max-w-4xl mx-auto",
|
||||
children: [
|
||||
e.jsx("h2", {
|
||||
className: "text-white font-semibold mb-6",
|
||||
children: "Home Header Context (White Text)",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-y-4",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "XSmall:",
|
||||
}),
|
||||
e.jsx(s, { size: "homeHeaderXsmall" }),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "Small:",
|
||||
}),
|
||||
e.jsx(s, { size: "homeHeaderSm" }),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "Medium:",
|
||||
}),
|
||||
e.jsx(s, { size: "homeHeaderMd" }),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "Large:",
|
||||
}),
|
||||
e.jsx(s, { size: "homeHeaderLg" }),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "XLarge:",
|
||||
}),
|
||||
e.jsx(s, { size: "homeHeaderXl" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Home header context showing white text variants. These are used on dark/transparent backgrounds.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
o = {
|
||||
args: {},
|
||||
render: () =>
|
||||
e.jsx("div", {
|
||||
className: "min-h-screen bg-[var(--color-surface-default-primary)] p-8",
|
||||
children: e.jsxs("div", {
|
||||
className: "max-w-4xl mx-auto",
|
||||
children: [
|
||||
e.jsx("h2", {
|
||||
className: "text-white font-semibold mb-6",
|
||||
children: "Header Context (Dark Text)",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-y-4",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "Default:",
|
||||
}),
|
||||
e.jsx(s, { size: "header" }),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "Medium:",
|
||||
}),
|
||||
e.jsx(s, { size: "headerMd" }),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "Large:",
|
||||
}),
|
||||
e.jsx(s, { size: "headerLg" }),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "XLarge:",
|
||||
}),
|
||||
e.jsx(s, { size: "headerXl" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Header context showing dark text variants. These are used on light backgrounds.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
d = {
|
||||
args: {},
|
||||
render: () =>
|
||||
e.jsx("div", {
|
||||
className: "min-h-screen bg-[var(--color-surface-default-primary)] p-8",
|
||||
children: e.jsxs("div", {
|
||||
className: "max-w-4xl mx-auto",
|
||||
children: [
|
||||
e.jsx("h2", {
|
||||
className: "text-white font-semibold mb-6",
|
||||
children: "Footer Context (Larger Sizes)",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-y-4",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "Default:",
|
||||
}),
|
||||
e.jsx(s, { size: "footer" }),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "flex items-center space-x-4",
|
||||
children: [
|
||||
e.jsx("span", {
|
||||
className: "text-white text-sm w-24",
|
||||
children: "Large:",
|
||||
}),
|
||||
e.jsx(s, { size: "footerLg" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Footer context showing larger size variants for footer placement.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
size: "default",
|
||||
showText: true
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
n.parameters = {
|
||||
...n.parameters,
|
||||
docs: {
|
||||
...n.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
showText: true
|
||||
},
|
||||
render: args => <div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Default Sizes</h3>
|
||||
<div className="space-x-4">
|
||||
<Logo {...args} size="default" />
|
||||
<Logo {...args} size="header" />
|
||||
<Logo {...args} size="footer" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Header Sizes</h3>
|
||||
<div className="space-x-4">
|
||||
<Logo {...args} size="header" />
|
||||
<Logo {...args} size="headerMd" />
|
||||
<Logo {...args} size="headerLg" />
|
||||
<Logo {...args} size="headerXl" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Home Header Sizes</h3>
|
||||
<div className="space-x-4">
|
||||
<Logo {...args} size="homeHeaderXsmall" />
|
||||
<Logo {...args} size="homeHeaderSm" />
|
||||
<Logo {...args} size="homeHeaderMd" />
|
||||
<Logo {...args} size="homeHeaderLg" />
|
||||
<Logo {...args} size="homeHeaderXl" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Footer Sizes</h3>
|
||||
<div className="space-x-4">
|
||||
<Logo {...args} size="footer" />
|
||||
<Logo {...args} size="footerLg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different size variants available for the logo component across different contexts."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...n.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
r.parameters = {
|
||||
...r.parameters,
|
||||
docs: {
|
||||
...r.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
size: "default",
|
||||
showText: false
|
||||
},
|
||||
render: args => <div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">
|
||||
Icon Only - Default Sizes
|
||||
</h3>
|
||||
<div className="space-x-4">
|
||||
<Logo {...args} size="default" />
|
||||
<Logo {...args} size="header" />
|
||||
<Logo {...args} size="footer" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">
|
||||
Icon Only - Header Sizes
|
||||
</h3>
|
||||
<div className="space-x-4">
|
||||
<Logo {...args} size="header" />
|
||||
<Logo {...args} size="headerMd" />
|
||||
<Logo {...args} size="headerLg" />
|
||||
<Logo {...args} size="headerXl" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">
|
||||
Icon Only - Home Header Sizes
|
||||
</h3>
|
||||
<div className="space-x-4">
|
||||
<Logo {...args} size="homeHeaderXsmall" />
|
||||
<Logo {...args} size="homeHeaderSm" />
|
||||
<Logo {...args} size="homeHeaderMd" />
|
||||
<Logo {...args} size="homeHeaderLg" />
|
||||
<Logo {...args} size="homeHeaderXl" />
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Logo variants with only the icon, no text. Useful for compact spaces."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...r.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
i.parameters = {
|
||||
...i.parameters,
|
||||
docs: {
|
||||
...i.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="min-h-screen bg-gradient-to-b from-[var(--color-surface-default-primary)] to-[var(--color-surface-default-secondary)] p-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h2 className="text-white font-semibold mb-6">
|
||||
Home Header Context (White Text)
|
||||
</h2>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">XSmall:</span>
|
||||
<Logo size="homeHeaderXsmall" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">Small:</span>
|
||||
<Logo size="homeHeaderSm" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">Medium:</span>
|
||||
<Logo size="homeHeaderMd" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">Large:</span>
|
||||
<Logo size="homeHeaderLg" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">XLarge:</span>
|
||||
<Logo size="homeHeaderXl" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Home header context showing white text variants. These are used on dark/transparent backgrounds."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...i.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
o.parameters = {
|
||||
...o.parameters,
|
||||
docs: {
|
||||
...o.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="min-h-screen bg-[var(--color-surface-default-primary)] p-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h2 className="text-white font-semibold mb-6">
|
||||
Header Context (Dark Text)
|
||||
</h2>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">Default:</span>
|
||||
<Logo size="header" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">Medium:</span>
|
||||
<Logo size="headerMd" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">Large:</span>
|
||||
<Logo size="headerLg" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">XLarge:</span>
|
||||
<Logo size="headerXl" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Header context showing dark text variants. These are used on light backgrounds."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...o.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
d.parameters = {
|
||||
...d.parameters,
|
||||
docs: {
|
||||
...d.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="min-h-screen bg-[var(--color-surface-default-primary)] p-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h2 className="text-white font-semibold mb-6">
|
||||
Footer Context (Larger Sizes)
|
||||
</h2>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">Default:</span>
|
||||
<Logo size="footer" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-white text-sm w-24">Large:</span>
|
||||
<Logo size="footerLg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Footer context showing larger size variants for footer placement."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...d.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const p = [
|
||||
"Default",
|
||||
"Sizes",
|
||||
"IconOnly",
|
||||
"HomeHeaderContext",
|
||||
"HeaderContext",
|
||||
"FooterContext",
|
||||
];
|
||||
export {
|
||||
t as Default,
|
||||
d as FooterContext,
|
||||
o as HeaderContext,
|
||||
i as HomeHeaderContext,
|
||||
r as IconOnly,
|
||||
n as Sizes,
|
||||
p as __namedExportsOrder,
|
||||
h as default,
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M27.5948 13.9998L0.549194 0.477051L7.31736 13.9998L0.549194 27.5226L27.5948 13.9998ZM14.0855 11.1905C14.6377 11.1938 15.1766 11.3603 15.6343 11.6689C16.092 11.9776 16.4481 12.4146 16.6577 12.925C16.8673 13.4353 16.9211 13.9962 16.8123 14.5371C16.7036 15.0779 16.437 15.5746 16.0463 15.9644C15.6556 16.3543 15.1582 16.6199 14.6166 16.728C14.0751 16.836 13.5137 16.7816 13.0031 16.5715C12.4924 16.3615 12.0554 16.0053 11.747 15.5477C11.4386 15.09 11.2726 14.5515 11.27 13.9998C11.2682 13.6301 11.3398 13.2637 11.4807 12.9218C11.6216 12.58 11.829 12.2694 12.0908 12.0081C12.3527 11.7468 12.6638 11.54 13.0062 11.3997C13.3486 11.2594 13.7154 11.1882 14.0855 11.1905Z" fill="#FFFDD2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 793 B |
@@ -1,21 +0,0 @@
|
||||
import { j as p } from "./jsx-runtime-C_nHp4yK.js";
|
||||
function r({ children: a, className: e = "", size: s = "default", ...l }) {
|
||||
const c = `flex items-center ${{ xsmall: "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-001)] rounded-[4px]", default: "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-001)]", medium: "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-004)]", large: "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-012)]" }[s]} ${e}`;
|
||||
return p.jsx("nav", {
|
||||
className: c,
|
||||
role: "menubar",
|
||||
"aria-label": "Main navigation menu",
|
||||
...l,
|
||||
children: a,
|
||||
});
|
||||
}
|
||||
r.__docgenInfo = {
|
||||
description: "",
|
||||
methods: [],
|
||||
displayName: "MenuBar",
|
||||
props: {
|
||||
className: { defaultValue: { value: '""', computed: !1 }, required: !1 },
|
||||
size: { defaultValue: { value: '"default"', computed: !1 }, required: !1 },
|
||||
},
|
||||
};
|
||||
export { r as M };
|
||||
@@ -1,200 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { M as s } from "./MenuBar-anMCqtJv.js";
|
||||
import { M as n } from "./MenuBarItem-Dp8NM2fx.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const d = {
|
||||
title: "Components/MenuBar",
|
||||
component: s,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A navigation menu bar container that groups MenuBarItem components together. Provides consistent spacing and layout for navigation menus with multiple size variants.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
control: { type: "select" },
|
||||
options: ["xsmall", "default", "medium", "large"],
|
||||
description: "The size of the menu bar and its children",
|
||||
},
|
||||
className: {
|
||||
control: { type: "text" },
|
||||
description: "Additional CSS classes",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
a = {
|
||||
args: { size: "default" },
|
||||
render: (t) =>
|
||||
e.jsxs(s, {
|
||||
...t,
|
||||
children: [
|
||||
e.jsx(n, { size: "large", children: "Home" }),
|
||||
e.jsx(n, { size: "large", children: "About" }),
|
||||
e.jsx(n, { size: "large", children: "Contact" }),
|
||||
],
|
||||
}),
|
||||
},
|
||||
r = {
|
||||
args: {},
|
||||
render: () =>
|
||||
e.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "XSmall Size",
|
||||
}),
|
||||
e.jsxs(s, {
|
||||
size: "xsmall",
|
||||
children: [
|
||||
e.jsx(n, { size: "xsmall", children: "Home" }),
|
||||
e.jsx(n, { size: "xsmall", children: "About" }),
|
||||
e.jsx(n, { size: "xsmall", children: "Contact" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Default Size",
|
||||
}),
|
||||
e.jsxs(s, {
|
||||
size: "default",
|
||||
children: [
|
||||
e.jsx(n, { size: "large", children: "Home" }),
|
||||
e.jsx(n, { size: "large", children: "About" }),
|
||||
e.jsx(n, { size: "large", children: "Contact" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Medium Size",
|
||||
}),
|
||||
e.jsxs(s, {
|
||||
size: "medium",
|
||||
children: [
|
||||
e.jsx(n, { size: "large", children: "Home" }),
|
||||
e.jsx(n, { size: "large", children: "About" }),
|
||||
e.jsx(n, { size: "large", children: "Contact" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Large Size",
|
||||
}),
|
||||
e.jsxs(s, {
|
||||
size: "large",
|
||||
children: [
|
||||
e.jsx(n, { size: "large", children: "Home" }),
|
||||
e.jsx(n, { size: "large", children: "About" }),
|
||||
e.jsx(n, { size: "large", children: "Contact" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Different size variants of the menu bar with consistent spacing and layout.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
a.parameters = {
|
||||
...a.parameters,
|
||||
docs: {
|
||||
...a.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
size: "default"
|
||||
},
|
||||
render: args => <MenuBar {...args}>
|
||||
<MenuBarItem size="large">Home</MenuBarItem>
|
||||
<MenuBarItem size="large">About</MenuBarItem>
|
||||
<MenuBarItem size="large">Contact</MenuBarItem>
|
||||
</MenuBar>
|
||||
}`,
|
||||
...a.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
r.parameters = {
|
||||
...r.parameters,
|
||||
docs: {
|
||||
...r.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">XSmall Size</h3>
|
||||
<MenuBar size="xsmall">
|
||||
<MenuBarItem size="xsmall">Home</MenuBarItem>
|
||||
<MenuBarItem size="xsmall">About</MenuBarItem>
|
||||
<MenuBarItem size="xsmall">Contact</MenuBarItem>
|
||||
</MenuBar>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Default Size</h3>
|
||||
<MenuBar size="default">
|
||||
<MenuBarItem size="large">Home</MenuBarItem>
|
||||
<MenuBarItem size="large">About</MenuBarItem>
|
||||
<MenuBarItem size="large">Contact</MenuBarItem>
|
||||
</MenuBar>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Medium Size</h3>
|
||||
<MenuBar size="medium">
|
||||
<MenuBarItem size="large">Home</MenuBarItem>
|
||||
<MenuBarItem size="large">About</MenuBarItem>
|
||||
<MenuBarItem size="large">Contact</MenuBarItem>
|
||||
</MenuBar>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Large Size</h3>
|
||||
<MenuBar size="large">
|
||||
<MenuBarItem size="large">Home</MenuBarItem>
|
||||
<MenuBarItem size="large">About</MenuBarItem>
|
||||
<MenuBarItem size="large">Contact</MenuBarItem>
|
||||
</MenuBar>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different size variants of the menu bar with consistent spacing and layout."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...r.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const u = ["Default", "Sizes"];
|
||||
export { a as Default, r as Sizes, u as __namedExportsOrder, d as default };
|
||||
@@ -1,123 +0,0 @@
|
||||
import { j as p } from "./jsx-runtime-C_nHp4yK.js";
|
||||
function U({
|
||||
href: v = "#",
|
||||
children: o,
|
||||
variant: d = "default",
|
||||
size: e = "default",
|
||||
className: f = "",
|
||||
disabled: a = !1,
|
||||
ariaLabel: l,
|
||||
...m
|
||||
}) {
|
||||
const x = {
|
||||
default:
|
||||
"bg-transparent text-[var(--color-content-default-brand-primary)] hover:bg-[var(--color-surface-default-tertiary)] hover:text-[var(--color-content-default-brand-primary)] hover:scale-[1.02] active:bg-transparent active:text-[var(--color-content-default-brand-primary)] active:scale-[0.98] disabled:bg-[var(--color-surface-default-tertiary)] disabled:text-[var(--color-content-default-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 disabled:active:scale-100",
|
||||
home: "bg-transparent text-[var(--color-content-inverse-primary)] hover:bg-[var(--color-content-default-brand-accent)] hover:text-[var(--color-content-inverse-primary)] hover:scale-[1.02] active:bg-transparent active:text-[var(--color-content-inverse-primary)] active:scale-[0.98] disabled:bg-[var(--color-surface-default-tertiary)] disabled:text-[var(--color-content-default-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 disabled:active:scale-100",
|
||||
},
|
||||
g = {
|
||||
xsmall:
|
||||
"active:outline-1 active:outline-[var(--color-content-default-primary)] focus:outline-1 focus:outline-[var(--color-content-default-primary)]",
|
||||
xsmallUseCases:
|
||||
"active:outline-1 active:outline-[var(--color-content-default-primary)] focus:outline-1 focus:outline-[var(--color-content-default-primary)]",
|
||||
default:
|
||||
"active:outline-1 active:outline-[var(--color-content-default-brand-primary)] focus:outline-1 focus:outline-[var(--color-content-default-brand-primary)]",
|
||||
homeMd:
|
||||
"active:outline-[1.5px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-brand-primary)]",
|
||||
homeUseCases:
|
||||
"active:outline-[1.5px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-brand-primary)]",
|
||||
large:
|
||||
"active:outline-[1.75px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[1.75px] focus:outline-[var(--color-content-default-brand-primary)]",
|
||||
largeUseCases:
|
||||
"active:outline-[1.75px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[1.75px] focus:outline-[var(--color-content-default-brand-primary)]",
|
||||
homeXlarge:
|
||||
"active:outline-[2px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[2px] focus:outline-[var(--color-content-default-brand-primary)]",
|
||||
xlarge:
|
||||
"active:outline-2 active:outline-[var(--color-content-default-brand-primary)] focus:outline-2 focus:outline-[var(--color-content-default-brand-primary)]",
|
||||
},
|
||||
y = {
|
||||
xsmall:
|
||||
"active:outline-1 active:outline-[var(--color-content-default-primary)] focus:outline-1 focus:outline-[var(--color-content-default-primary)]",
|
||||
xsmallUseCases:
|
||||
"active:outline-1 active:outline-[var(--color-content-default-primary)] focus:outline-1 focus:outline-[var(--color-content-default-primary)]",
|
||||
default:
|
||||
"active:outline-[1.5px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-primary)]",
|
||||
homeMd:
|
||||
"active:outline-[1.5px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-primary)]",
|
||||
homeUseCases:
|
||||
"active:outline-[1.5px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-primary)]",
|
||||
largeUseCases:
|
||||
"active:outline-[1.75px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.75px] focus:outline-[var(--color-content-default-primary)]",
|
||||
large:
|
||||
"active:outline-[1.75px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.75px] focus:outline-[var(--color-content-default-primary)]",
|
||||
homeXlarge:
|
||||
"active:outline-[2px] active:outline-[var(--color-content-default-primary)] focus:outline-[2px] focus:outline-[var(--color-content-default-primary)]",
|
||||
xlarge:
|
||||
"active:outline-2 active:outline-[var(--color-content-default-primary)] focus:outline-2 focus:outline-[var(--color-content-default-primary)]",
|
||||
},
|
||||
b = {
|
||||
default:
|
||||
"px-[var(--spacing-measures-spacing-016)] py-[var(--spacing-measures-spacing-016)] gap-[var(--spacing-scale-004)]",
|
||||
xsmall:
|
||||
"px-[var(--spacing-scale-004)] py-[var(--spacing-scale-002)] gap-[var(--spacing-scale-004)]",
|
||||
xsmallUseCases:
|
||||
"px-[var(--spacing-scale-002)] py-[var(--spacing-scale-002)] gap-[var(--spacing-scale-004)]",
|
||||
homeMd:
|
||||
"px-[var(--spacing-scale-008)] py-[var(--spacing-scale-008)] gap-[var(--spacing-scale-004)]",
|
||||
homeUseCases:
|
||||
"px-[var(--spacing-scale-002)] py-[var(--spacing-scale-008)] gap-[var(--spacing-scale-004)]",
|
||||
large:
|
||||
"px-[var(--spacing-scale-012)] py-[var(--spacing-scale-012)] gap-[var(--spacing-scale-004)] h-[44px]",
|
||||
largeUseCases:
|
||||
"px-[var(--spacing-scale-012)] py-[var(--spacing-scale-012)] gap-[var(--spacing-scale-004)] h-[44px]",
|
||||
homeXlarge:
|
||||
"px-[var(--spacing-scale-016)] py-[var(--spacing-scale-016)] gap-[var(--spacing-scale-004)] h-[44px]",
|
||||
xlarge:
|
||||
"px-[var(--spacing-scale-016)] py-[var(--spacing-scale-008)] gap-[var(--spacing-scale-004)] h-[44px]",
|
||||
},
|
||||
t = "font-['Inter'] text-[10px] leading-[12px] font-medium tracking-[0%]",
|
||||
n = "font-['Inter'] text-[12px] leading-[14px] font-medium tracking-[0%]",
|
||||
c = "font-['Inter'] text-[16px] leading-[20px] font-medium tracking-[0%]",
|
||||
i = "font-['Inter'] text-[24px] leading-[28px] font-normal tracking-[0%]",
|
||||
h = {
|
||||
default: t,
|
||||
xsmall: t,
|
||||
xsmallUseCases: t,
|
||||
home: t,
|
||||
homeMd: n,
|
||||
homeUseCases: n,
|
||||
large: c,
|
||||
largeUseCases: c,
|
||||
homeXlarge: i,
|
||||
xlarge: i,
|
||||
},
|
||||
C = `inline-flex items-center ${b[e]} rounded-[var(--radius-measures-radius-full)] ${h[e]} transition-all duration-200 ease-in-out cursor-pointer focus:scale-[1.02]`;
|
||||
let r = d;
|
||||
a && (r = "default");
|
||||
const s = `${C} ${x[r]} ${r === "home" ? y[e] : g[e]} ${f}`,
|
||||
u = {
|
||||
...(l && { "aria-label": l }),
|
||||
...(a && { "aria-disabled": "true" }),
|
||||
role: "menuitem",
|
||||
tabIndex: a ? -1 : 0,
|
||||
...m,
|
||||
};
|
||||
return a
|
||||
? p.jsx("span", { className: s, ...u, children: o })
|
||||
: p.jsx("a", { href: v, className: s, ...u, children: o });
|
||||
}
|
||||
U.__docgenInfo = {
|
||||
description: "",
|
||||
methods: [],
|
||||
displayName: "MenuBarItem",
|
||||
props: {
|
||||
href: { defaultValue: { value: '"#"', computed: !1 }, required: !1 },
|
||||
variant: {
|
||||
defaultValue: { value: '"default"', computed: !1 },
|
||||
required: !1,
|
||||
},
|
||||
size: { defaultValue: { value: '"default"', computed: !1 }, required: !1 },
|
||||
className: { defaultValue: { value: '""', computed: !1 }, required: !1 },
|
||||
disabled: { defaultValue: { value: "false", computed: !1 }, required: !1 },
|
||||
},
|
||||
};
|
||||
export { U as M };
|
||||
@@ -1,372 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { M as a } from "./MenuBarItem-Dp8NM2fx.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const u = {
|
||||
title: "Components/MenuBarItem",
|
||||
component: a,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A navigation menu item component with multiple variants, sizes, and states. Can render as a link or disabled span with full accessibility support. Includes focus states with keyboard navigation - use Tab key to test focus indicators.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: { type: "select" },
|
||||
options: ["default", "home"],
|
||||
description: "The visual style variant of the menu item",
|
||||
},
|
||||
size: {
|
||||
control: { type: "select" },
|
||||
options: [
|
||||
"xsmall",
|
||||
"xsmallUseCases",
|
||||
"homeMd",
|
||||
"homeUseCases",
|
||||
"large",
|
||||
"largeUseCases",
|
||||
"homeXlarge",
|
||||
"xlarge",
|
||||
],
|
||||
description: "The size of the menu item",
|
||||
},
|
||||
disabled: {
|
||||
control: { type: "boolean" },
|
||||
description: "Whether the menu item is disabled",
|
||||
},
|
||||
href: { control: { type: "text" }, description: "The link destination" },
|
||||
onClick: { action: "clicked" },
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
n = { args: { children: "Menu Item", size: "large" } },
|
||||
r = {
|
||||
args: { children: "Menu Item", size: "large" },
|
||||
render: (s) =>
|
||||
e.jsx("div", {
|
||||
className: "space-y-4",
|
||||
children: e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(a, { ...s, variant: "default", children: "Default" }),
|
||||
e.jsx(a, { ...s, variant: "home", children: "Home" }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different visual variants of the menu item component.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
t = {
|
||||
args: { children: "Menu Item", variant: "default" },
|
||||
render: (s) =>
|
||||
e.jsx("div", {
|
||||
className: "space-y-4",
|
||||
children: e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(a, { ...s, size: "xsmall", children: "XSmall" }),
|
||||
e.jsx(a, { ...s, size: "large", children: "Large" }),
|
||||
e.jsx(a, { ...s, size: "xlarge", children: "XLarge" }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different sizes available for the menu item component.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
i = {
|
||||
args: { children: "Menu Item", size: "large", variant: "default" },
|
||||
render: (s) =>
|
||||
e.jsx("div", {
|
||||
className: "space-y-4",
|
||||
children: e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(a, { ...s, children: "Normal" }),
|
||||
e.jsx(a, { ...s, disabled: !0, children: "Disabled" }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: { story: "Different states of the menu item component." },
|
||||
},
|
||||
},
|
||||
},
|
||||
l = {
|
||||
args: {},
|
||||
render: () =>
|
||||
e.jsxs("div", {
|
||||
className: "space-y-6",
|
||||
children: [
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Default Variant",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(a, { size: "xsmall", children: "XSmall" }),
|
||||
e.jsx(a, { size: "large", children: "Large" }),
|
||||
e.jsx(a, { size: "xlarge", children: "XLarge" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Home Variant",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(a, {
|
||||
variant: "home",
|
||||
size: "xsmall",
|
||||
children: "XSmall",
|
||||
}),
|
||||
e.jsx(a, {
|
||||
variant: "home",
|
||||
size: "large",
|
||||
children: "Large",
|
||||
}),
|
||||
e.jsx(a, {
|
||||
variant: "home",
|
||||
size: "xlarge",
|
||||
children: "XLarge",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
children: [
|
||||
e.jsx("h3", {
|
||||
className: "text-white font-semibold mb-3",
|
||||
children: "Disabled States",
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "space-x-4",
|
||||
children: [
|
||||
e.jsx(a, {
|
||||
size: "large",
|
||||
disabled: !0,
|
||||
children: "Default Disabled",
|
||||
}),
|
||||
e.jsx(a, {
|
||||
variant: "home",
|
||||
size: "large",
|
||||
disabled: !0,
|
||||
children: "Home Disabled",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Complete overview of all menu item variants, sizes, and states.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
n.parameters = {
|
||||
...n.parameters,
|
||||
docs: {
|
||||
...n.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
children: "Menu Item",
|
||||
size: "large"
|
||||
}
|
||||
}`,
|
||||
...n.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
r.parameters = {
|
||||
...r.parameters,
|
||||
docs: {
|
||||
...r.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
children: "Menu Item",
|
||||
size: "large"
|
||||
},
|
||||
render: args => <div className="space-y-4">
|
||||
<div className="space-x-4">
|
||||
<MenuBarItem {...args} variant="default">
|
||||
Default
|
||||
</MenuBarItem>
|
||||
<MenuBarItem {...args} variant="home">
|
||||
Home
|
||||
</MenuBarItem>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different visual variants of the menu item component."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...r.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
children: "Menu Item",
|
||||
variant: "default"
|
||||
},
|
||||
render: args => <div className="space-y-4">
|
||||
<div className="space-x-4">
|
||||
<MenuBarItem {...args} size="xsmall">
|
||||
XSmall
|
||||
</MenuBarItem>
|
||||
<MenuBarItem {...args} size="large">
|
||||
Large
|
||||
</MenuBarItem>
|
||||
<MenuBarItem {...args} size="xlarge">
|
||||
XLarge
|
||||
</MenuBarItem>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different sizes available for the menu item component."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
i.parameters = {
|
||||
...i.parameters,
|
||||
docs: {
|
||||
...i.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
children: "Menu Item",
|
||||
size: "large",
|
||||
variant: "default"
|
||||
},
|
||||
render: args => <div className="space-y-4">
|
||||
<div className="space-x-4">
|
||||
<MenuBarItem {...args}>Normal</MenuBarItem>
|
||||
<MenuBarItem {...args} disabled>
|
||||
Disabled
|
||||
</MenuBarItem>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Different states of the menu item component."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...i.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
l.parameters = {
|
||||
...l.parameters,
|
||||
docs: {
|
||||
...l.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {},
|
||||
render: () => <div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Default Variant</h3>
|
||||
<div className="space-x-4">
|
||||
<MenuBarItem size="xsmall">XSmall</MenuBarItem>
|
||||
<MenuBarItem size="large">Large</MenuBarItem>
|
||||
<MenuBarItem size="xlarge">XLarge</MenuBarItem>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Home Variant</h3>
|
||||
<div className="space-x-4">
|
||||
<MenuBarItem variant="home" size="xsmall">
|
||||
XSmall
|
||||
</MenuBarItem>
|
||||
<MenuBarItem variant="home" size="large">
|
||||
Large
|
||||
</MenuBarItem>
|
||||
<MenuBarItem variant="home" size="xlarge">
|
||||
XLarge
|
||||
</MenuBarItem>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-white font-semibold mb-3">Disabled States</h3>
|
||||
<div className="space-x-4">
|
||||
<MenuBarItem size="large" disabled>
|
||||
Default Disabled
|
||||
</MenuBarItem>
|
||||
<MenuBarItem variant="home" size="large" disabled>
|
||||
Home Disabled
|
||||
</MenuBarItem>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Complete overview of all menu item variants, sizes, and states."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...l.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const p = ["Default", "Variants", "Sizes", "States", "AllVariants"];
|
||||
export {
|
||||
l as AllVariants,
|
||||
n as Default,
|
||||
t as Sizes,
|
||||
i as States,
|
||||
r as Variants,
|
||||
p as __namedExportsOrder,
|
||||
u as default,
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { S as t } from "./SectionNumber-Cptefv18.js";
|
||||
const r = ({ number: l, text: s, iconShape: o, iconColor: a }) =>
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"bg-[var(--color-surface-inverse-primary)] rounded-[12px] p-5 shadow-lg flex flex-col gap-4 sm:p-8 sm:gap-8 sm:flex-row sm:items-center lg:p-8 lg:gap-0 lg:flex-row lg:items-stretch lg:relative lg:h-[238px]",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"flex justify-end sm:justify-start sm:flex-shrink-0 lg:absolute lg:top-8 lg:right-8",
|
||||
children: e.jsx(t, { number: l }),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "sm:flex-1 lg:absolute lg:bottom-8 lg:left-8 lg:right-16",
|
||||
children: e.jsx("p", {
|
||||
className:
|
||||
"font-bricolage-grotesque font-medium text-[24px] leading-[32px] sm:font-normal sm:leading-[24px] sm:text-[24px] lg:text-[24px] lg:leading-[24px] xl:text-[32px] xl:leading-[32px] text-[#141414]",
|
||||
children: s,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
r.__docgenInfo = { description: "", methods: [], displayName: "NumberedCard" };
|
||||
export { r as N };
|
||||
@@ -1,176 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { N as o } from "./NumberedCard-ClCynPua.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
import "./SectionNumber-Cptefv18.js";
|
||||
const m = {
|
||||
title: "Components/NumberedCard",
|
||||
component: o,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"Individual numbered card component that displays a step in a process with a numbered icon and descriptive text. Supports responsive layouts across different breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
number: {
|
||||
control: { type: "number", min: 1, max: 9 },
|
||||
description: "The number to display on the card",
|
||||
},
|
||||
text: {
|
||||
control: { type: "text" },
|
||||
description: "The descriptive text for this step",
|
||||
},
|
||||
iconShape: {
|
||||
control: { type: "select" },
|
||||
options: ["blob", "gear", "star"],
|
||||
description:
|
||||
"The shape of the icon background (currently not used, uses PNG images)",
|
||||
},
|
||||
iconColor: {
|
||||
control: { type: "select" },
|
||||
options: ["green", "purple", "orange", "blue"],
|
||||
description:
|
||||
"The color theme for the icon (currently not used, uses PNG images)",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
t = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Document how your community makes decisions",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
},
|
||||
r = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Example card text",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
render: (s) =>
|
||||
e.jsxs("div", {
|
||||
className: "space-y-4",
|
||||
children: [
|
||||
e.jsx(o, { ...s, number: 1, text: "First step in the process" }),
|
||||
e.jsx(o, {
|
||||
...s,
|
||||
number: 2,
|
||||
text: "Second step with different content",
|
||||
}),
|
||||
e.jsx(o, {
|
||||
...s,
|
||||
number: 3,
|
||||
text: "Third and final step of the workflow",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Shows all three numbered cards with different content to demonstrate the visual hierarchy.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
n = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "This is a much longer piece of text that demonstrates how the card handles content that spans multiple lines and requires more space to display properly",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Demonstrates how the card handles longer text content across different breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Document how your community makes decisions",
|
||||
iconShape: "blob",
|
||||
iconColor: "green"
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
r.parameters = {
|
||||
...r.parameters,
|
||||
docs: {
|
||||
...r.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Example card text",
|
||||
iconShape: "blob",
|
||||
iconColor: "green"
|
||||
},
|
||||
render: args => <div className="space-y-4">
|
||||
<NumberedCard {...args} number={1} text="First step in the process" />
|
||||
<NumberedCard {...args} number={2} text="Second step with different content" />
|
||||
<NumberedCard {...args} number={3} text="Third and final step of the workflow" />
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Shows all three numbered cards with different content to demonstrate the visual hierarchy."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...r.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
n.parameters = {
|
||||
...n.parameters,
|
||||
docs: {
|
||||
...n.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
number: 1,
|
||||
text: "This is a much longer piece of text that demonstrates how the card handles content that spans multiple lines and requires more space to display properly",
|
||||
iconShape: "blob",
|
||||
iconColor: "green"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Demonstrates how the card handles longer text content across different breakpoints."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...n.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const l = ["Default", "AllNumbers", "LongText"];
|
||||
export {
|
||||
r as AllNumbers,
|
||||
t as Default,
|
||||
n as LongText,
|
||||
l as __namedExportsOrder,
|
||||
m as default,
|
||||
};
|
||||
@@ -1,249 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { N as m } from "./NumberedCard-ClCynPua.js";
|
||||
import { S as u } from "./SectionHeader-CadpOP1T.js";
|
||||
import { B as c } from "./Button-Z4hbXct5.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
import "./SectionNumber-Cptefv18.js";
|
||||
const l = ({ title: r, subtitle: a, cards: i }) => {
|
||||
const p = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: r,
|
||||
description: a,
|
||||
step: i.map((o, t) => ({
|
||||
"@type": "HowToStep",
|
||||
position: t + 1,
|
||||
name: o.text,
|
||||
text: o.text,
|
||||
})),
|
||||
};
|
||||
return e.jsxs(e.Fragment, {
|
||||
children: [
|
||||
e.jsx("script", {
|
||||
type: "application/ld+json",
|
||||
dangerouslySetInnerHTML: { __html: JSON.stringify(p) },
|
||||
}),
|
||||
e.jsx("section", {
|
||||
className:
|
||||
"bg-transparent py-[var(--spacing-scale-032)] px-[var(--spacing-scale-020)] sm:py-[var(--spacing-scale-048)] sm:px-[var(--spacing-scale-032)] lg:py-[var(--spacing-scale-064)] lg:px-[var(--spacing-scale-064)] xl:py-[var(--spacing-scale-076)] xl:px-[var(--spacing-scale-064)]",
|
||||
children: e.jsx("div", {
|
||||
className: "max-w-[var(--spacing-measures-max-width-lg)] mx-auto",
|
||||
children: e.jsxs("div", {
|
||||
className:
|
||||
"grid grid-cols-1 gap-y-[var(--spacing-scale-032)] lg:gap-y-[var(--spacing-scale-056)]",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
children: e.jsx(u, {
|
||||
title: r,
|
||||
subtitle: a,
|
||||
titleLg: "How CommunityRule helps",
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"grid grid-cols-1 gap-y-[var(--spacing-scale-024)] lg:grid-cols-3 lg:gap-[var(--spacing-scale-024)]",
|
||||
children: i.map((o, t) =>
|
||||
e.jsx(
|
||||
m,
|
||||
{
|
||||
number: t + 1,
|
||||
text: o.text,
|
||||
iconShape: o.iconShape,
|
||||
iconColor: o.iconColor,
|
||||
},
|
||||
t,
|
||||
),
|
||||
),
|
||||
}),
|
||||
e.jsxs("div", {
|
||||
className: "text-center sm:text-left lg:text-center",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className: "block lg:hidden",
|
||||
children: e.jsx(c, {
|
||||
variant: "default",
|
||||
size: "large",
|
||||
children: "Create CommunityRule",
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "hidden lg:block",
|
||||
children: e.jsx(c, {
|
||||
variant: "outlined",
|
||||
size: "large",
|
||||
children: "See how it works",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
};
|
||||
l.__docgenInfo = { description: "", methods: [], displayName: "NumberedCards" };
|
||||
const C = {
|
||||
title: "Components/NumberedCards",
|
||||
component: l,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A component system for visually communicating multi-step workflows, processes, or value propositions. The component's modular design with NumberedCard and SectionNumber sub-components makes it ideal for explaining any sequential process while maintaining brand consistency and accessibility standards across the design system.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
title: {
|
||||
control: { type: "text" },
|
||||
description: "The main title for the section",
|
||||
},
|
||||
subtitle: {
|
||||
control: { type: "text" },
|
||||
description: "The subtitle text below the main title",
|
||||
},
|
||||
cards: {
|
||||
control: { type: "object" },
|
||||
description:
|
||||
"Array of card objects with text, iconShape, and iconColor properties",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
n = {
|
||||
args: {
|
||||
title: "How CommunityRule works",
|
||||
subtitle: "Here's a quick overview of the process, from start to finish.",
|
||||
cards: [
|
||||
{
|
||||
text: "Document how your community makes decisions",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
{
|
||||
text: "Build an operating manual for a successful community",
|
||||
iconShape: "gear",
|
||||
iconColor: "purple",
|
||||
},
|
||||
{
|
||||
text: "Get a link to your manual for your group to review and evolve",
|
||||
iconShape: "star",
|
||||
iconColor: "orange",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
s = {
|
||||
args: {
|
||||
title: "Our Process",
|
||||
subtitle: "Follow these simple steps to get started with your project.",
|
||||
cards: [
|
||||
{
|
||||
text: "Define your project requirements and goals",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
{
|
||||
text: "Collaborate with our team to create the perfect solution",
|
||||
iconShape: "gear",
|
||||
iconColor: "purple",
|
||||
},
|
||||
{
|
||||
text: "Launch and iterate based on user feedback",
|
||||
iconShape: "star",
|
||||
iconColor: "orange",
|
||||
},
|
||||
{
|
||||
text: "Scale and optimize for continued success",
|
||||
iconShape: "blob",
|
||||
iconColor: "blue",
|
||||
},
|
||||
],
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Example with custom content and four cards to show flexibility.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
n.parameters = {
|
||||
...n.parameters,
|
||||
docs: {
|
||||
...n.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "How CommunityRule works",
|
||||
subtitle: "Here's a quick overview of the process, from start to finish.",
|
||||
cards: [{
|
||||
text: "Document how your community makes decisions",
|
||||
iconShape: "blob",
|
||||
iconColor: "green"
|
||||
}, {
|
||||
text: "Build an operating manual for a successful community",
|
||||
iconShape: "gear",
|
||||
iconColor: "purple"
|
||||
}, {
|
||||
text: "Get a link to your manual for your group to review and evolve",
|
||||
iconShape: "star",
|
||||
iconColor: "orange"
|
||||
}]
|
||||
}
|
||||
}`,
|
||||
...n.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
s.parameters = {
|
||||
...s.parameters,
|
||||
docs: {
|
||||
...s.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Our Process",
|
||||
subtitle: "Follow these simple steps to get started with your project.",
|
||||
cards: [{
|
||||
text: "Define your project requirements and goals",
|
||||
iconShape: "blob",
|
||||
iconColor: "green"
|
||||
}, {
|
||||
text: "Collaborate with our team to create the perfect solution",
|
||||
iconShape: "gear",
|
||||
iconColor: "purple"
|
||||
}, {
|
||||
text: "Launch and iterate based on user feedback",
|
||||
iconShape: "star",
|
||||
iconColor: "orange"
|
||||
}, {
|
||||
text: "Scale and optimize for continued success",
|
||||
iconShape: "blob",
|
||||
iconColor: "blue"
|
||||
}]
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Example with custom content and four cards to show flexibility."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...s.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const v = ["Default", "CustomContent"];
|
||||
export {
|
||||
s as CustomContent,
|
||||
n as Default,
|
||||
v as __namedExportsOrder,
|
||||
C as default,
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
const a = ({ title: l, subtitle: t, titleLg: x }) =>
|
||||
e.jsxs("div", {
|
||||
className:
|
||||
"flex flex-col gap-1 w-full lg:flex-row lg:justify-between lg:items-start xl:gap-[var(--spacing-scale-024)]",
|
||||
children: [
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"lg:w-[369px] lg:h-[120px] lg:flex lg:items-center xl:w-[452px] xl:h-[156px] xl:flex xl:items-center",
|
||||
children: e.jsxs("h2", {
|
||||
className:
|
||||
"font-bricolage-grotesque font-bold text-[28px] leading-[36px] sm:text-[32px] sm:leading-[40px] lg:text-[32px] lg:leading-[40px] lg:w-[369px] lg:pr-24 xl:text-[40px] xl:leading-[52px] xl:w-[452px] xl:pr-24 text-[var(--color-content-default-primary)]",
|
||||
children: [
|
||||
e.jsx("span", { className: "block lg:hidden", children: l }),
|
||||
e.jsx("span", { className: "hidden lg:block", children: x || l }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className:
|
||||
"lg:w-[928px] lg:h-[120px] lg:flex lg:items-center lg:justify-end xl:w-[763px] xl:h-[156px] xl:flex xl:items-center xl:justify-end",
|
||||
children: e.jsx("p", {
|
||||
className:
|
||||
"font-inter font-normal text-[18px] leading-[130%] sm:text-[18px] sm:leading-[32px] lg:text-[24px] lg:leading-[32px] xl:text-[32px] xl:leading-[40px] xl:text-right text-[#484848] sm:text-[var(--color-content-default-tertiary)] lg:text-[var(--color-content-default-tertiary)] xl:text-[var(--color-content-default-tertiary)] tracking-[0px]",
|
||||
children: t,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
a.__docgenInfo = { description: "", methods: [], displayName: "SectionHeader" };
|
||||
export { a as S };
|
||||
@@ -1,226 +0,0 @@
|
||||
import { S as n } from "./SectionHeader-CadpOP1T.js";
|
||||
import "./jsx-runtime-C_nHp4yK.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const p = {
|
||||
title: "Components/SectionHeader",
|
||||
component: n,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A section header component that displays a title and subtitle with responsive typography and layout. Supports different title text for large breakpoints and maintains consistent spacing across all screen sizes.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
title: {
|
||||
control: { type: "text" },
|
||||
description: "The main title text (used for xsm and sm breakpoints)",
|
||||
},
|
||||
subtitle: {
|
||||
control: { type: "text" },
|
||||
description: "The subtitle text below the main title",
|
||||
},
|
||||
titleLg: {
|
||||
control: { type: "text" },
|
||||
description:
|
||||
"The title text for lg and xl breakpoints (optional, falls back to title)",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
e = {
|
||||
args: {
|
||||
title: "How CommunityRule works",
|
||||
subtitle: "Here's a quick overview of the process, from start to finish.",
|
||||
titleLg: "How CommunityRule helps",
|
||||
},
|
||||
},
|
||||
t = {
|
||||
args: {
|
||||
title: "Our Mission",
|
||||
subtitle:
|
||||
"We're dedicated to helping communities thrive through better decision-making processes and transparent governance structures.",
|
||||
titleLg: "Building Better Communities",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Example with custom content to show the flexibility of the component.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
s = {
|
||||
args: {
|
||||
title: "Complex Process",
|
||||
subtitle:
|
||||
"This is a much longer subtitle that demonstrates how the component handles extended text content across different breakpoints and layout configurations.",
|
||||
titleLg: "Complex Process Simplified",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Demonstrates how the component handles longer subtitle text across different breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
o = {
|
||||
args: {
|
||||
title: "Responsive Design",
|
||||
subtitle:
|
||||
"Test the responsive behavior by resizing your browser window or using the viewport controls in Storybook.",
|
||||
titleLg: "Responsive Design Test",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Test the responsive behavior by resizing your browser window or using the viewport controls in Storybook.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
r = {
|
||||
args: {
|
||||
title: "Simple Header",
|
||||
subtitle:
|
||||
"This example doesn't specify a titleLg prop, so it will use the same title text across all breakpoints.",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Shows the component without a titleLg prop, demonstrating the fallback behavior.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
e.parameters = {
|
||||
...e.parameters,
|
||||
docs: {
|
||||
...e.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "How CommunityRule works",
|
||||
subtitle: "Here's a quick overview of the process, from start to finish.",
|
||||
titleLg: "How CommunityRule helps"
|
||||
}
|
||||
}`,
|
||||
...e.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Our Mission",
|
||||
subtitle: "We're dedicated to helping communities thrive through better decision-making processes and transparent governance structures.",
|
||||
titleLg: "Building Better Communities"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Example with custom content to show the flexibility of the component."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
s.parameters = {
|
||||
...s.parameters,
|
||||
docs: {
|
||||
...s.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Complex Process",
|
||||
subtitle: "This is a much longer subtitle that demonstrates how the component handles extended text content across different breakpoints and layout configurations.",
|
||||
titleLg: "Complex Process Simplified"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Demonstrates how the component handles longer subtitle text across different breakpoints."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...s.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
o.parameters = {
|
||||
...o.parameters,
|
||||
docs: {
|
||||
...o.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Responsive Design",
|
||||
subtitle: "Test the responsive behavior by resizing your browser window or using the viewport controls in Storybook.",
|
||||
titleLg: "Responsive Design Test"
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Test the responsive behavior by resizing your browser window or using the viewport controls in Storybook."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...o.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
r.parameters = {
|
||||
...r.parameters,
|
||||
docs: {
|
||||
...r.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
title: "Simple Header",
|
||||
subtitle: "This example doesn't specify a titleLg prop, so it will use the same title text across all breakpoints."
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Shows the component without a titleLg prop, demonstrating the fallback behavior."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...r.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const m = [
|
||||
"Default",
|
||||
"CustomContent",
|
||||
"LongSubtitle",
|
||||
"ResponsiveTest",
|
||||
"WithoutTitleLg",
|
||||
];
|
||||
export {
|
||||
t as CustomContent,
|
||||
e as Default,
|
||||
s as LongSubtitle,
|
||||
o as ResponsiveTest,
|
||||
r as WithoutTitleLg,
|
||||
m as __namedExportsOrder,
|
||||
p as default,
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
const a = ({ number: t }) => {
|
||||
const s = (r) => {
|
||||
switch (r) {
|
||||
case 1:
|
||||
return "/assets/SectionNumber_1.png";
|
||||
case 2:
|
||||
return "/assets/SectionNumber_2.png";
|
||||
case 3:
|
||||
return "/assets/SectionNumber_3.png";
|
||||
default:
|
||||
return "/assets/SectionNumber_1.png";
|
||||
}
|
||||
};
|
||||
return e.jsxs("div", {
|
||||
className: "relative size-[40px] overflow-visible -rotate-[15deg]",
|
||||
children: [
|
||||
e.jsx("img", {
|
||||
src: s(t),
|
||||
alt: `Section ${t}`,
|
||||
className:
|
||||
"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 size-[47.37px] max-w-none",
|
||||
}),
|
||||
e.jsx("div", {
|
||||
className: "absolute inset-0 flex items-center justify-center",
|
||||
children: e.jsx("span", {
|
||||
className:
|
||||
"text-[var(--font-size-body-small)] font-[var(--font-weight-bold)] text-[var(--color-content-inverse-primary)]",
|
||||
children: t,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
};
|
||||
a.__docgenInfo = { description: "", methods: [], displayName: "SectionNumber" };
|
||||
export { a as S };
|
||||
@@ -1,174 +0,0 @@
|
||||
import { j as e } from "./jsx-runtime-C_nHp4yK.js";
|
||||
import { S as r } from "./SectionNumber-Cptefv18.js";
|
||||
import "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const u = {
|
||||
title: "Components/SectionNumber",
|
||||
component: r,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A numbered icon component that displays a number overlaid on a PNG background image. The component uses different PNG images for numbers 1, 2, and 3, with the image extending beyond the 40px container size.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
number: {
|
||||
control: { type: "number", min: 1, max: 3 },
|
||||
description: "The number to display (1, 2, or 3)",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
},
|
||||
n = { args: { number: 1 } },
|
||||
s = { args: { number: 2 } },
|
||||
o = { args: { number: 3 } },
|
||||
a = {
|
||||
render: () =>
|
||||
e.jsxs("div", {
|
||||
className: "flex space-x-4",
|
||||
children: [
|
||||
e.jsx(r, { number: 1 }),
|
||||
e.jsx(r, { number: 2 }),
|
||||
e.jsx(r, { number: 3 }),
|
||||
],
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Shows all three numbered icons side by side to demonstrate the different PNG backgrounds.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
t = {
|
||||
render: () =>
|
||||
e.jsx("div", {
|
||||
className: "bg-gray-100 p-8 rounded-lg",
|
||||
children: e.jsxs("div", {
|
||||
className: "flex space-x-4",
|
||||
children: [
|
||||
e.jsx(r, { number: 1 }),
|
||||
e.jsx(r, { number: 2 }),
|
||||
e.jsx(r, { number: 3 }),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Shows the numbered icons on a background to demonstrate how the PNG images extend beyond the container.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
n.parameters = {
|
||||
...n.parameters,
|
||||
docs: {
|
||||
...n.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
number: 1
|
||||
}
|
||||
}`,
|
||||
...n.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
s.parameters = {
|
||||
...s.parameters,
|
||||
docs: {
|
||||
...s.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
number: 2
|
||||
}
|
||||
}`,
|
||||
...s.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
o.parameters = {
|
||||
...o.parameters,
|
||||
docs: {
|
||||
...o.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
args: {
|
||||
number: 3
|
||||
}
|
||||
}`,
|
||||
...o.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
a.parameters = {
|
||||
...a.parameters,
|
||||
docs: {
|
||||
...a.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
render: () => <div className="flex space-x-4">
|
||||
<SectionNumber number={1} />
|
||||
<SectionNumber number={2} />
|
||||
<SectionNumber number={3} />
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Shows all three numbered icons side by side to demonstrate the different PNG backgrounds."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...a.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
t.parameters = {
|
||||
...t.parameters,
|
||||
docs: {
|
||||
...t.parameters?.docs,
|
||||
source: {
|
||||
originalSource: `{
|
||||
render: () => <div className="bg-gray-100 p-8 rounded-lg">
|
||||
<div className="flex space-x-4">
|
||||
<SectionNumber number={1} />
|
||||
<SectionNumber number={2} />
|
||||
<SectionNumber number={3} />
|
||||
</div>
|
||||
</div>,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: "Shows the numbered icons on a background to demonstrate how the PNG images extend beyond the container."
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
...t.parameters?.docs?.source,
|
||||
},
|
||||
},
|
||||
};
|
||||
const b = [
|
||||
"NumberOne",
|
||||
"NumberTwo",
|
||||
"NumberThree",
|
||||
"AllNumbers",
|
||||
"WithBackground",
|
||||
];
|
||||
export {
|
||||
a as AllNumbers,
|
||||
n as NumberOne,
|
||||
o as NumberThree,
|
||||
s as NumberTwo,
|
||||
t as WithBackground,
|
||||
b as __namedExportsOrder,
|
||||
u as default,
|
||||
};
|
||||
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 22 KiB |
@@ -1,15 +0,0 @@
|
||||
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_18586_27811)">
|
||||
<mask id="mask0_18586_27811" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="28" height="28">
|
||||
<path d="M27.2 0.399994L0 0.399994L0 27.6H27.2V0.399994Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_18586_27811)">
|
||||
<path d="M13.6 24.0284C3.31356 32.6244 -5.02436 24.2865 3.57164 14C-5.02436 3.71355 3.31356 -4.62436 13.6 3.97164C23.8845 -4.62436 32.2244 3.71355 23.6284 14C32.2244 24.2786 23.8845 32.6244 13.6 24.0284Z" fill="black"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_18586_27811">
|
||||
<rect width="27.2" height="27.2" fill="white" transform="translate(0 0.399994)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 752 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="105" height="42" viewBox="0 0 105 42" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.0492 10.0151C12.0492 4.49227 7.57203 0 2.04918 0H0V53H105V42.0635H44.0492C26.3761 42.0635 12.0492 27.6882 12.0492 10.0151Z" fill="#FEFCC9"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 259 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="61" height="25" viewBox="0 0 61 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7 0H0V31.5H61V25H31C17.7452 25 7 14.2548 7 1V0Z" fill="#FEFCC9"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 179 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="105" height="42" viewBox="0 0 105 42" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.0492 10.0151C12.0492 4.49227 7.57203 0 2.04918 0H0V53H105V42.0635H44.0492C26.3761 42.0635 12.0492 27.6882 12.0492 10.0151Z" fill="#FEFCC9"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 259 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="61" height="19" viewBox="0 0 61 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7 0H0V24H61V19.0476H23C14.1634 19.0476 7 11.8842 7 3.04761V0Z" fill="#FEFCC9"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 193 B |
@@ -1,26 +0,0 @@
|
||||
import { R as e } from "./iframe-D_aMTKb2.js";
|
||||
import "./preload-helper-DIZFD4sK.js";
|
||||
const o = {},
|
||||
c = e.createContext(o);
|
||||
function u(n) {
|
||||
const t = e.useContext(c);
|
||||
return e.useMemo(
|
||||
function () {
|
||||
return typeof n == "function" ? n(t) : { ...t, ...n };
|
||||
},
|
||||
[t, n],
|
||||
);
|
||||
}
|
||||
function r(n) {
|
||||
let t;
|
||||
return (
|
||||
n.disableParentContext
|
||||
? (t =
|
||||
typeof n.components == "function"
|
||||
? n.components(o)
|
||||
: n.components || o)
|
||||
: (t = u(n.components)),
|
||||
e.createElement(c.Provider, { value: t }, n.children)
|
||||
);
|
||||
}
|
||||
export { r as MDXProvider, u as useMDXComponents };
|
||||
@@ -1,3 +0,0 @@
|
||||
import { b as r } from "./iframe-D_aMTKb2.js";
|
||||
var s = r();
|
||||
export { s as j };
|
||||
@@ -1,58 +0,0 @@
|
||||
const p = "modulepreload",
|
||||
v = function (l) {
|
||||
return "/CommunityRuleStorybook/" + l;
|
||||
},
|
||||
u = {},
|
||||
E = function (d, c, y) {
|
||||
let i = Promise.resolve();
|
||||
if (c && c.length > 0) {
|
||||
let m = function (e) {
|
||||
return Promise.all(
|
||||
e.map((o) =>
|
||||
Promise.resolve(o).then(
|
||||
(s) => ({ status: "fulfilled", value: s }),
|
||||
(s) => ({ status: "rejected", reason: s }),
|
||||
),
|
||||
),
|
||||
);
|
||||
};
|
||||
document.getElementsByTagName("link");
|
||||
const r = document.querySelector("meta[property=csp-nonce]"),
|
||||
t = r?.nonce || r?.getAttribute("nonce");
|
||||
i = m(
|
||||
c.map((e) => {
|
||||
if (((e = v(e)), e in u)) return;
|
||||
u[e] = !0;
|
||||
const o = e.endsWith(".css"),
|
||||
s = o ? '[rel="stylesheet"]' : "";
|
||||
if (document.querySelector(`link[href="${e}"]${s}`)) return;
|
||||
const n = document.createElement("link");
|
||||
if (
|
||||
((n.rel = o ? "stylesheet" : p),
|
||||
o || (n.as = "script"),
|
||||
(n.crossOrigin = ""),
|
||||
(n.href = e),
|
||||
t && n.setAttribute("nonce", t),
|
||||
document.head.appendChild(n),
|
||||
o)
|
||||
)
|
||||
return new Promise((f, h) => {
|
||||
(n.addEventListener("load", f),
|
||||
n.addEventListener("error", () =>
|
||||
h(new Error(`Unable to preload CSS for ${e}`)),
|
||||
));
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
function a(r) {
|
||||
const t = new Event("vite:preloadError", { cancelable: !0 });
|
||||
if (((t.payload = r), window.dispatchEvent(t), !t.defaultPrevented))
|
||||
throw r;
|
||||
}
|
||||
return i.then((r) => {
|
||||
for (const t of r || []) t.status === "rejected" && a(t.reason);
|
||||
return d().catch(a);
|
||||
});
|
||||
};
|
||||
export { E as _ };
|
||||
@@ -1,46 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<mask id="active-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M25,15.3 C26.8630998,15.3 28.7261995,16.2284418 29.795607,18.0853254 L29.795607,18.0853254 L34.7484772,26.6853254 C35.2679728,27.5873604 35.5068948,28.5446245 35.509009,29.4780654 C35.5112408,30.4762222 35.243212,31.4466974 34.7610935,32.2926531 C34.2789749,33.1386087 33.5826171,33.8603071 32.7267084,34.3600412 C31.9262928,34.8273748 30.9864445,35.1 29.9528702,35.1 L29.9528702,35.1 L20.0471298,35.1 C19.0135555,35.1 18.0737072,34.8273748 17.2732916,34.3600412 C16.4173829,33.8603071 15.7210251,33.1386087 15.2389065,32.2926531 C14.756788,31.4466974 14.4887592,30.4762222 14.490991,29.4780654 C14.4931052,28.5446245 14.7320272,27.5873604 15.2515228,26.6853254 L15.2515228,26.6853254 L20.204393,18.0853254 C21.2738005,16.2284418 23.1369002,15.3 25,15.3 Z"
|
||||
transform="rotate(90 25 25.2)" />
|
||||
</mask>
|
||||
<mask id="critical-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M23.9,14.6 C26.7442665,14.6 29.3192665,15.7528668 31.1831998,17.6168002 C33.0471332,19.4807335 34.2,22.0557335 34.2,24.9 C34.2,27.7442665 33.0471332,30.3192665 31.1831998,32.1831998 C29.3192665,34.0471332 26.7442665,35.2 23.9,35.2 C21.0557335,35.2 18.4807335,34.0471332 16.6168002,32.1831998 C14.7528668,30.3192665 13.6,27.7442665 13.6,24.9 C13.6,22.0557335 14.7528668,19.4807335 16.6168002,17.6168002 C18.4807335,15.7528668 21.0557335,14.6 23.9,14.6 Z" />
|
||||
</mask>
|
||||
<mask id="negative-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M28.2,14.8 C29.633165,14.8 31.06633,15.346734 32.159798,16.440202 C33.2414078,17.5218119 33.7880833,18.9357904 33.8,20.353376 C33.811544,21.7725108 33.2872104,23.1952877 32.2266806,24.2917914 L32.2266806,24.2917914 L31.7206,24.8006729 L32.159798,25.240202 C33.253266,26.33367 33.8,27.766835 33.8,29.2 C33.8,30.633165 33.253266,32.06633 32.159798,33.159798 C31.0781881,34.2414078 29.6642096,34.7880833 28.246624,34.8 C26.8274892,34.811544 25.4047123,34.2872104 24.3082086,33.2266806 L24.3082086,33.2266806 L23.7993271,32.7206 L23.359798,33.159798 C22.26633,34.253266 20.833165,34.8 19.4,34.8 C17.966835,34.8 16.53367,34.253266 15.440202,33.159798 C14.3585922,32.0781881 13.8119167,30.6642096 13.8,29.246624 C13.788456,27.8274892 14.3127896,26.4047123 15.3733194,25.3082086 L15.3733194,25.3082086 L15.8794,24.7993271 L15.440202,24.359798 C14.346734,23.26633 13.8,21.833165 13.8,20.4 C13.8,18.966835 14.346734,17.53367 15.440202,16.440202 C16.5218119,15.3585922 17.9357904,14.8119167 19.353376,14.8 C20.7725108,14.788456 22.1952877,15.3127896 23.2917914,16.3733194 L23.2917914,16.3733194 L23.8006729,16.8794 L24.240202,16.440202 C25.33367,15.346734 26.766835,14.8 28.2,14.8 Z" />
|
||||
</mask>
|
||||
<mask id="positive-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M29.7294207,16.9922805 C31.1625744,16.9866282 32.5979013,17.5276612 33.6957071,18.6167741 C34.7816077,19.6940761 35.3338993,21.1058704 35.351258,22.5233982 C35.3686336,23.9423122 34.8500808,25.3669976 33.7941627,26.4676563 L33.7941627,26.4676563 L27.1794488,33.1363075 C26.0960963,34.2283069 24.675298,34.7802389 23.2508341,34.7920857 C21.8249459,34.8039445 20.3953569,34.27469 19.296927,33.2041927 L19.296927,33.2041927 L15.7761737,29.656491 C14.6870608,28.5586851 14.1460279,27.1233582 14.1516801,25.6902046 C14.1574213,24.2570509 14.7098478,22.8260705 15.8076536,21.7369576 C16.7544861,20.7976225 17.9523748,20.2659173 19.1834383,20.1411672 C20.4372495,20.0141119 21.7255226,20.3088158 22.8178242,21.0249737 L22.8178242,21.0249737 L23.1781395,21.2667759 L25.7761737,18.648254 C26.8652867,17.5504481 28.2962671,16.9980217 29.7294207,16.9922805 Z" />
|
||||
</mask>
|
||||
<mask id="warning-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M23.8,14.8 C25.6808284,14.8 27.5616567,15.7284418 28.6412402,17.5853254 L28.6412402,17.5853254 L33.6412402,26.1853254 C34.1656792,27.0873604 34.4068747,28.0446245 34.409009,28.9780654 C34.4112621,29.9762222 34.1406828,30.9466974 33.6539766,31.7926531 C33.1672704,32.6386087 32.4642862,33.3603071 31.600233,33.8600412 C30.7922009,34.3273748 29.8434094,34.6 28.8,34.6 L28.8,34.6 L18.8,34.6 C17.7565906,34.6 16.8077991,34.3273748 15.999767,33.8600412 C15.1357138,33.3603071 14.4327296,32.6386087 13.9460234,31.7926531 C13.4593172,30.9466974 13.1887379,29.9762222 13.190991,28.9780654 C13.1931253,28.0446245 13.4343208,27.0873604 13.9587598,26.1853254 L13.9587598,26.1853254 L18.9587598,17.5853254 C20.0383433,15.7284418 21.9191716,14.8 23.8,14.8 Z" />
|
||||
</mask>
|
||||
|
||||
<polygon id="active" fill="none" stroke="#029CFD" stroke-linejoin="round" stroke-width="2.8"
|
||||
points="25 21 30 29.6 20 29.6" transform="rotate(90 25 25.3)" />
|
||||
<circle id="critical" fill="none" cx="23.9" cy="24.9" r="4.7" stroke="#000" stroke-linejoin="round"
|
||||
stroke-width="2.8" />
|
||||
<path id="negative" fill="none" stroke="#F40" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.8"
|
||||
d="M19.4,20.4 L28.2,29.2 M28.2,20.4 L19.4,29.2" />
|
||||
<polyline id="positive" fill="none" stroke="#66BF3C" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2.8" points="19.752 25.712 23.204 29.192 29.752 22.592" />
|
||||
<polygon id="warning" fill="none" stroke="#FFAE00" stroke-linejoin="round" stroke-width="2.8"
|
||||
points="23.8 20.4 28.8 29 18.8 29" />
|
||||
</defs>
|
||||
|
||||
<g id="mask">
|
||||
<use id="icon" />
|
||||
</g>
|
||||
<use id="status" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.7 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><g fill="none" fill-rule="evenodd"><path fill="#FF4785" fill-rule="nonzero" d="M3.19456517,29.5523576 L2.20116517,3.08035756 C2.16820317,2.206041 2.83853396,1.46497625 3.71176517,1.41035756 L26.2285652,0.00315756388 C26.6728415,-0.0246745074 27.1088544,0.132425741 27.4332785,0.437229126 C27.7577026,0.74203251 27.9415652,1.16741027 27.9415652,1.61255756 L27.9415652,30.4585576 C27.9415652,30.8987416 27.7615266,31.3197739 27.4433606,31.6239653 C27.1251947,31.9281568 26.6965078,32.0890657 26.2567652,32.0693576 L4.73376517,31.1027576 C3.89549138,31.0651477 3.22618762,30.3908861 3.19476517,29.5523576 L3.19456517,29.5523576 Z"/><path fill="#FFF" d="M24.4581652,0.113957564 L21.3591652,0.307557564 L21.2081652,3.94195756 C21.2043927,4.0349625 21.2546048,4.1217998 21.3370927,4.16492627 C21.4195807,4.20805273 21.5195442,4.19973049 21.5937652,4.14355756 L23.0057652,3.07275756 L24.1981652,4.01215756 C24.2717133,4.07021898 24.3722957,4.08025391 24.4558654,4.03786787 C24.539435,3.99548183 24.5907604,3.90840015 24.5873652,3.81475756 L24.4581652,0.113757564 L24.4581652,0.113957564 Z M22.0463652,12.2851576 C21.4791652,12.7257576 17.2533652,13.0265576 17.2533652,12.3991576 C17.3427652,10.0053576 16.2709652,9.90035756 15.6755652,9.90035756 C15.1099652,9.90035756 14.1575652,10.0713576 14.1575652,11.3537576 C14.1575652,12.6605576 15.5495652,13.3983576 17.1835652,14.2643576 C19.5049652,15.4943576 22.3143652,16.9831576 22.3143652,20.7295576 C22.3143652,24.3201576 19.3967652,26.3037576 15.6755652,26.3037576 C11.8353652,26.3037576 8.47936517,24.7499576 8.85836517,19.3633576 C9.00716517,18.7307576 13.8895652,18.8811576 13.8895652,19.3633576 C13.8299652,21.5861576 14.3359652,22.2399576 15.6161652,22.2399576 C16.5985652,22.2399576 17.0449652,21.6983576 17.0449652,20.7865576 C17.0449652,19.4065576 15.5945652,18.5919576 13.9259652,17.6551576 C11.6665652,16.3865576 9.00716517,14.8935576 9.00716517,11.4679576 C9.00716517,8.04835756 11.3591652,5.76855756 15.5565652,5.76855756 C19.7541652,5.76855756 22.0463652,8.01335756 22.0463652,12.2853576 L22.0463652,12.2851576 Z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1 +0,0 @@
|
||||
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 391 B |
@@ -1 +0,0 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
@@ -1,391 +0,0 @@
|
||||
# Performance Optimization Guide
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Performance Targets](#performance-targets)
|
||||
- [Frontend Optimizations](#frontend-optimizations)
|
||||
- [Performance Monitoring](#performance-monitoring)
|
||||
- [Bundle Analysis](#bundle-analysis)
|
||||
- [Web Vitals Tracking](#web-vitals-tracking)
|
||||
- [Performance Testing](#performance-testing)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Best Practices](#best-practices)
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
This guide covers the comprehensive performance optimization strategy implemented in Community Rule 3.0 to achieve sub-2-second load times across all platform features.
|
||||
|
||||
### Performance Philosophy
|
||||
|
||||
- **Measure First**: Comprehensive monitoring before optimization
|
||||
- **Performance Budgets**: Enforce limits to prevent regression
|
||||
- **Real User Monitoring**: Track actual user experience
|
||||
- **Continuous Optimization**: Regular monitoring and improvement
|
||||
|
||||
## 🎯 Performance Targets
|
||||
|
||||
### Core Web Vitals
|
||||
|
||||
- **LCP (Largest Contentful Paint)**: < 2.5s (Good)
|
||||
- **FID (First Input Delay)**: < 100ms (Good)
|
||||
- **CLS (Cumulative Layout Shift)**: < 0.1 (Good)
|
||||
- **FCP (First Contentful Paint)**: < 1.8s (Good)
|
||||
- **TTFB (Time to First Byte)**: < 800ms (Good)
|
||||
|
||||
### Bundle Size Targets
|
||||
|
||||
- **Initial JavaScript Bundle**: < 250KB gzipped (currently 101KB)
|
||||
- **Total Bundle Size**: < 2MB
|
||||
- **Individual Component Bundles**: < 50KB
|
||||
- **Image Assets**: Optimized with WebP/AVIF formats
|
||||
|
||||
### Lighthouse Scores
|
||||
|
||||
- **Performance**: > 90
|
||||
- **Accessibility**: > 90
|
||||
- **Best Practices**: > 90
|
||||
- **SEO**: > 90
|
||||
|
||||
## ⚡ Frontend Optimizations
|
||||
|
||||
### 1. Code Splitting
|
||||
|
||||
Dynamic imports for non-critical components to reduce initial bundle size:
|
||||
|
||||
```javascript
|
||||
// Dynamic imports for non-critical components
|
||||
const NumberedCards = dynamic(() => import("./components/NumberedCards"), {
|
||||
loading: () => <div className="loading-placeholder">Loading...</div>,
|
||||
});
|
||||
|
||||
const LogoWall = dynamic(() => import("./components/LogoWall"), {
|
||||
loading: () => <div className="loading-placeholder">Loading...</div>,
|
||||
});
|
||||
```
|
||||
|
||||
### 2. React.memo Optimization
|
||||
|
||||
Applied to all 30+ components to prevent unnecessary re-renders:
|
||||
|
||||
```javascript
|
||||
import React, { memo } from "react";
|
||||
|
||||
const MyComponent = memo(({ prop1, prop2 }) => {
|
||||
return <div>{/* Component content */}</div>;
|
||||
});
|
||||
|
||||
MyComponent.displayName = "MyComponent";
|
||||
export default MyComponent;
|
||||
```
|
||||
|
||||
### 3. useMemo and useCallback
|
||||
|
||||
Optimized expensive computations and event handlers:
|
||||
|
||||
```javascript
|
||||
import React, { memo, useMemo, useCallback } from "react";
|
||||
|
||||
const OptimizedComponent = memo(({ data, onAction }) => {
|
||||
// Memoize expensive computations
|
||||
const processedData = useMemo(() => {
|
||||
return data.map((item) => expensiveOperation(item));
|
||||
}, [data]);
|
||||
|
||||
// Memoize event handlers
|
||||
const handleClick = useCallback(
|
||||
(id) => {
|
||||
onAction(id);
|
||||
},
|
||||
[onAction],
|
||||
);
|
||||
|
||||
return <div onClick={handleClick}>{/* Component content */}</div>;
|
||||
});
|
||||
```
|
||||
|
||||
### 4. Image Optimization
|
||||
|
||||
Enhanced `next/image` with lazy loading and blur placeholders:
|
||||
|
||||
```javascript
|
||||
import Image from "next/image";
|
||||
|
||||
<Image
|
||||
src="/assets/image.jpg"
|
||||
alt="Description"
|
||||
width={300}
|
||||
height={200}
|
||||
sizes="(max-width: 768px) 100vw, 50vw"
|
||||
loading="lazy"
|
||||
placeholder="blur"
|
||||
blurDataURL="data:image/jpeg;base64,..."
|
||||
/>;
|
||||
```
|
||||
|
||||
### 5. Font Optimization
|
||||
|
||||
Preloading and fallbacks for all fonts:
|
||||
|
||||
```javascript
|
||||
import { Inter, Bricolage_Grotesque, Space_Grotesk } from "next/font/google";
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ["latin"],
|
||||
preload: true,
|
||||
fallback: ["system-ui", "arial"],
|
||||
});
|
||||
|
||||
const bricolageGrotesque = Bricolage_Grotesque({
|
||||
subsets: ["latin"],
|
||||
preload: true,
|
||||
fallback: ["system-ui", "arial"],
|
||||
});
|
||||
```
|
||||
|
||||
### 6. Error Boundaries
|
||||
|
||||
Comprehensive error handling to prevent cascade failures:
|
||||
|
||||
```javascript
|
||||
import React, { Component } from "react";
|
||||
|
||||
class ErrorBoundary extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { hasError: false, error: null };
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error) {
|
||||
return { hasError: true };
|
||||
}
|
||||
|
||||
componentDidCatch(error, errorInfo) {
|
||||
console.error("ErrorBoundary caught an error:", error, errorInfo);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return <div>Something went wrong.</div>;
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Performance Monitoring
|
||||
|
||||
### Available Scripts
|
||||
|
||||
```bash
|
||||
# Individual monitoring tools
|
||||
npm run bundle:analyze # Analyze bundle sizes and budgets
|
||||
npm run performance:monitor # Performance metrics and Lighthouse CI
|
||||
npm run web-vitals:track # Core Web Vitals tracking
|
||||
|
||||
# Comprehensive testing
|
||||
npm run test:performance # All performance tests
|
||||
npm run monitor:all # All monitoring tools
|
||||
```
|
||||
|
||||
### Performance Dashboard
|
||||
|
||||
Access the performance monitoring dashboard at `/monitor` to view:
|
||||
|
||||
- Real-time Web Vitals metrics
|
||||
- Historical performance data
|
||||
- Bundle analysis results
|
||||
- Performance budget status
|
||||
- Optimization recommendations
|
||||
|
||||
## 📦 Bundle Analysis
|
||||
|
||||
### Bundle Analyzer Script
|
||||
|
||||
The bundle analyzer provides comprehensive analysis of bundle sizes:
|
||||
|
||||
```bash
|
||||
npm run bundle:analyze
|
||||
```
|
||||
|
||||
**Features:**
|
||||
|
||||
- Analyzes static assets, chunks, and pages
|
||||
- Checks against performance budgets
|
||||
- Generates optimization recommendations
|
||||
- Saves results in JSON and Markdown formats
|
||||
|
||||
**Output Files:**
|
||||
|
||||
- `.next/analyze/bundle-analysis.json` - Detailed analysis data
|
||||
- `.next/analyze/bundle-report.md` - Human-readable report
|
||||
|
||||
### Performance Budgets
|
||||
|
||||
Defined in `performance-budgets.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"budgets": [
|
||||
{
|
||||
"name": "lcp",
|
||||
"maxValue": 2500,
|
||||
"description": "Largest Contentful Paint"
|
||||
},
|
||||
{
|
||||
"name": "bundle-size",
|
||||
"maxSizeKB": 250,
|
||||
"description": "Initial JavaScript bundle size"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 📈 Web Vitals Tracking
|
||||
|
||||
### Real-time Monitoring
|
||||
|
||||
The Web Vitals tracking system collects and reports Core Web Vitals:
|
||||
|
||||
```bash
|
||||
npm run web-vitals:track
|
||||
```
|
||||
|
||||
**Features:**
|
||||
|
||||
- Collects LCP, FID, CLS, FCP, TTFB metrics
|
||||
- Stores historical data (last 100 entries per metric)
|
||||
- Generates summary reports
|
||||
- Provides optimization recommendations
|
||||
|
||||
**API Endpoint:**
|
||||
|
||||
- `POST /api/web-vitals` - Receives Web Vitals data
|
||||
- `GET /api/web-vitals` - Returns aggregated metrics
|
||||
|
||||
### Web Vitals Dashboard
|
||||
|
||||
The dashboard component displays real-time and historical metrics:
|
||||
|
||||
```javascript
|
||||
import WebVitalsDashboard from "./components/WebVitalsDashboard";
|
||||
|
||||
<WebVitalsDashboard />;
|
||||
```
|
||||
|
||||
## 🧪 Performance Testing
|
||||
|
||||
### Comprehensive Testing
|
||||
|
||||
Run all performance tests with a single command:
|
||||
|
||||
```bash
|
||||
npm run test:performance
|
||||
```
|
||||
|
||||
**Test Coverage:**
|
||||
|
||||
- Bundle analysis with budget checking
|
||||
- Performance monitoring with Lighthouse CI
|
||||
- Web Vitals tracking setup
|
||||
- Comprehensive reporting
|
||||
|
||||
### Individual Tests
|
||||
|
||||
```bash
|
||||
# Bundle analysis only
|
||||
npm run bundle:analyze
|
||||
|
||||
# Performance monitoring only
|
||||
npm run performance:monitor
|
||||
|
||||
# Web Vitals tracking only
|
||||
npm run web-vitals:track
|
||||
|
||||
# All monitoring tools
|
||||
npm run monitor:all
|
||||
```
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### 1. Bundle Size Exceeds Budget
|
||||
|
||||
```bash
|
||||
# Check bundle analysis
|
||||
npm run bundle:analyze
|
||||
|
||||
# Review recommendations in .next/analyze/bundle-report.md
|
||||
# Consider code splitting or removing unused dependencies
|
||||
```
|
||||
|
||||
#### 2. Web Vitals Poor Performance
|
||||
|
||||
```bash
|
||||
# Check Web Vitals data
|
||||
npm run web-vitals:track
|
||||
|
||||
# Review dashboard at /monitor
|
||||
# Optimize images, fonts, or JavaScript
|
||||
```
|
||||
|
||||
#### 3. Performance Tests Failing
|
||||
|
||||
```bash
|
||||
# Run comprehensive performance test
|
||||
npm run test:performance
|
||||
|
||||
# Check individual components
|
||||
npm run bundle:analyze
|
||||
npm run performance:monitor
|
||||
```
|
||||
|
||||
### Debug Commands
|
||||
|
||||
```bash
|
||||
# Debug bundle analysis
|
||||
npm run bundle:analyze --verbose
|
||||
|
||||
# Debug performance monitoring
|
||||
npm run performance:monitor --debug
|
||||
|
||||
# Check Web Vitals data
|
||||
curl http://localhost:3000/api/web-vitals
|
||||
```
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
### Development
|
||||
|
||||
1. **Always use React.memo** for components that receive props
|
||||
2. **Implement useMemo/useCallback** for expensive operations
|
||||
3. **Use dynamic imports** for non-critical components
|
||||
4. **Optimize images** with proper sizing and formats
|
||||
5. **Preload critical fonts** and resources
|
||||
|
||||
### Monitoring
|
||||
|
||||
1. **Run bundle analysis** before major releases
|
||||
2. **Monitor Web Vitals** in production
|
||||
3. **Check performance budgets** in CI/CD
|
||||
4. **Review optimization recommendations** regularly
|
||||
|
||||
### Performance Budgets
|
||||
|
||||
1. **Set realistic budgets** based on user needs
|
||||
2. **Monitor budget violations** in CI/CD
|
||||
3. **Optimize when budgets are exceeded**
|
||||
4. **Update budgets** as requirements change
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- **Next.js Performance**: https://nextjs.org/docs/advanced-features/measuring-performance
|
||||
- **Web Vitals**: https://web.dev/vitals/
|
||||
- **Lighthouse CI**: https://github.com/GoogleChrome/lighthouse-ci
|
||||
- **React Performance**: https://react.dev/learn/render-and-commit
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2024
|
||||
**Maintained by**: CommunityRule Development Team
|
||||
@@ -1,810 +0,0 @@
|
||||
# Testing Framework Documentation
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Testing Architecture](#testing-architecture)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Test Types & Coverage](#test-types--coverage)
|
||||
- [Unit & Integration Testing](#unit--integration-testing)
|
||||
- [E2E Testing](#e2e-testing)
|
||||
- [Visual Regression Testing](#visual-regression-testing)
|
||||
- [Accessibility Testing](#accessibility-testing)
|
||||
- [Performance Testing](#performance-testing)
|
||||
- [CI/CD Pipeline](#cicd-pipeline)
|
||||
- [Development Workflow](#development-workflow)
|
||||
- [Best Practices](#best-practices)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
The CommunityRule platform uses a comprehensive testing framework with multiple layers to ensure code quality, functionality, visual consistency, and accessibility across all browsers and devices.
|
||||
|
||||
### Testing Stack
|
||||
|
||||
- **Unit/Integration**: Vitest + JSDOM + React Testing Library
|
||||
- **E2E**: Playwright (Chromium, Firefox, WebKit, Mobile)
|
||||
- **Visual Regression**: Playwright Screenshots
|
||||
- **Performance**: Lighthouse CI
|
||||
- **Accessibility**: Axe-core + Playwright
|
||||
- **CI/CD**: Gitea Actions
|
||||
|
||||
### Current Status
|
||||
|
||||
- ✅ **428 Unit Tests** (94.88% coverage - exceeds 85% target)
|
||||
- ✅ **92 E2E Tests** across 4 browsers
|
||||
- ✅ **23 Visual Regression Tests** per browser
|
||||
- ✅ **Performance Budgets** with Lighthouse CI
|
||||
- ✅ **WCAG 2.1 AA Compliance** with automated testing
|
||||
- ✅ **Bundle Analysis** with automated monitoring
|
||||
- ✅ **Web Vitals Tracking** with real-time metrics
|
||||
- ✅ **Performance Optimization** with React.memo and code splitting
|
||||
|
||||
## 🏗 Testing Architecture
|
||||
|
||||
### Test Pyramid
|
||||
|
||||
- **Unit Tests**: Fast, focused, high coverage (94.88%)
|
||||
- **Integration Tests**: Component interactions, data flow
|
||||
- **E2E Tests**: Critical user journeys, cross-browser compatibility
|
||||
|
||||
### Testing Philosophy
|
||||
|
||||
**JSDOM Limitations**: Unit tests in JSDOM can't truly test responsive behavior since CSS media queries aren't evaluated. Therefore:
|
||||
|
||||
- **Unit/Integration Tests**: Test component structure, accessibility, and configuration
|
||||
- **E2E Tests**: Test real responsive behavior at actual viewport widths
|
||||
- **Visual Tests**: Capture visual consistency across breakpoints
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Install Playwright browsers
|
||||
npx playwright install
|
||||
```
|
||||
|
||||
### Essential Commands
|
||||
|
||||
```bash
|
||||
# Unit tests with coverage
|
||||
npm test
|
||||
|
||||
# E2E tests
|
||||
npm run e2e
|
||||
|
||||
# Visual regression tests
|
||||
npm run visual:test
|
||||
|
||||
# Performance tests
|
||||
npm run lhci
|
||||
|
||||
# Storybook tests
|
||||
npm run test:sb
|
||||
```
|
||||
|
||||
## 🧪 Test Types & Coverage
|
||||
|
||||
### Test Structure
|
||||
|
||||
```
|
||||
tests/
|
||||
├── unit/ # Component unit tests
|
||||
│ ├── Button.test.jsx # 12 tests
|
||||
│ ├── Logo.test.jsx # 12 tests
|
||||
│ ├── RuleCard.test.jsx # 18 tests
|
||||
│ ├── SectionHeader.test.jsx # 17 tests
|
||||
│ ├── NumberedCard.test.jsx # 18 tests
|
||||
│ └── accessibility.test.jsx # 18 tests
|
||||
├── integration/ # Component integration tests
|
||||
│ ├── component-interactions.integration.test.jsx
|
||||
│ ├── page-flow.integration.test.jsx
|
||||
│ ├── user-journey.integration.test.jsx
|
||||
│ ├── layout.integration.test.jsx
|
||||
│ └── ContentLockup.integration.test.jsx
|
||||
└── e2e/ # End-to-end tests
|
||||
├── homepage.spec.ts # Homepage functionality
|
||||
├── user-journeys.spec.ts # User workflows
|
||||
├── header.responsive.spec.js # Responsive header
|
||||
├── footer.responsive.spec.js # Responsive footer
|
||||
├── visual-regression.spec.ts # Visual consistency
|
||||
├── accessibility.spec.ts # Accessibility compliance
|
||||
└── performance.spec.ts # Performance metrics
|
||||
```
|
||||
|
||||
### Coverage Requirements
|
||||
|
||||
- **Statements**: >85% (Current: 94.88%) ✅
|
||||
- **Branches**: >80% (Current: 86.93%) ✅
|
||||
- **Functions**: >80% (Current: 88.67%) ✅
|
||||
- **Lines**: >85% (Current: 94.88%) ✅
|
||||
|
||||
## 🧩 Unit & Integration Testing
|
||||
|
||||
### Framework
|
||||
|
||||
- **Vitest**: Fast unit test runner
|
||||
- **JSDOM**: Browser environment simulation
|
||||
- **React Testing Library**: Component testing utilities
|
||||
- **MSW**: API mocking
|
||||
|
||||
### Configuration
|
||||
|
||||
```javascript
|
||||
// vitest.config.js
|
||||
export default defineConfig({
|
||||
plugins: [react({ jsxRuntime: "automatic" })],
|
||||
test: {
|
||||
environment: "jsdom",
|
||||
setupFiles: ["./vitest.setup.js"],
|
||||
coverage: {
|
||||
provider: "v8",
|
||||
thresholds: { lines: 85, functions: 85, statements: 85, branches: 80 },
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Writing Unit Tests
|
||||
|
||||
```jsx
|
||||
// tests/unit/Component.test.jsx
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, test, expect, afterEach } from "vitest";
|
||||
import { cleanup } from "@testing-library/react";
|
||||
import Component from "../../app/components/Component";
|
||||
|
||||
describe("Component", () => {
|
||||
afterEach(() => cleanup());
|
||||
|
||||
test("renders correctly", () => {
|
||||
render(<Component />);
|
||||
expect(screen.getByRole("button")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("handles user interactions", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<Component />);
|
||||
|
||||
const button = screen.getByRole("button");
|
||||
await user.click(button);
|
||||
|
||||
expect(button).toHaveClass("clicked");
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Testing Library Queries (Priority Order)
|
||||
|
||||
1. **`getByRole`**: Most accessible, tests user experience
|
||||
2. **`getByLabelText`**: For form inputs
|
||||
3. **`getByText`**: For content
|
||||
4. **`getByTestId`**: Last resort, avoid when possible
|
||||
|
||||
### Integration Testing
|
||||
|
||||
```jsx
|
||||
test("components work together", () => {
|
||||
render(
|
||||
<div>
|
||||
<Header />
|
||||
<MainContent />
|
||||
<Footer />
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Test that components complement each other
|
||||
expect(screen.getByRole("banner")).toBeInTheDocument();
|
||||
expect(screen.getByRole("main")).toBeInTheDocument();
|
||||
expect(screen.getByRole("contentinfo")).toBeInTheDocument();
|
||||
});
|
||||
```
|
||||
|
||||
### Available Scripts
|
||||
|
||||
```bash
|
||||
npm test # Run all tests with coverage
|
||||
npm run test:watch # Run tests in watch mode
|
||||
npm run test:ui # Run tests with UI
|
||||
```
|
||||
|
||||
## 🌐 E2E Testing
|
||||
|
||||
### Framework
|
||||
|
||||
- **Playwright**: Cross-browser E2E testing
|
||||
- **Browsers**: Chromium, Firefox, WebKit, Mobile
|
||||
- **Accessibility**: Axe-core integration
|
||||
|
||||
### Configuration
|
||||
|
||||
```typescript
|
||||
// playwright.config.ts
|
||||
export default defineConfig({
|
||||
testDir: "./tests/e2e",
|
||||
projects: [
|
||||
{ name: "chromium", use: { ...devices["Desktop Chrome"] } },
|
||||
{ name: "firefox", use: { ...devices["Desktop Firefox"] } },
|
||||
{ name: "webkit", use: { ...devices["Desktop Safari"] } },
|
||||
{ name: "mobile", use: { ...devices["iPhone 13"] } },
|
||||
],
|
||||
use: {
|
||||
timezoneId: "UTC",
|
||||
locale: "en-US",
|
||||
headless: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Test Categories
|
||||
|
||||
#### 1. Functional Tests
|
||||
|
||||
- Page loading and sections
|
||||
- Component functionality
|
||||
- Navigation and interactions
|
||||
- User workflows
|
||||
|
||||
#### 2. Responsive Tests
|
||||
|
||||
- Layout changes between breakpoints
|
||||
- Component visibility at different viewports
|
||||
- Interactive behavior across screen sizes
|
||||
|
||||
#### 3. Accessibility Tests
|
||||
|
||||
- WCAG 2.1 AA compliance
|
||||
- Screen reader compatibility
|
||||
- Keyboard navigation
|
||||
- Color contrast
|
||||
|
||||
### Writing E2E Tests
|
||||
|
||||
```typescript
|
||||
// tests/e2e/example.spec.ts
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test.describe("Feature", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto("/");
|
||||
});
|
||||
|
||||
test("should work correctly", async ({ page }) => {
|
||||
await expect(page).toHaveTitle(/CommunityRule/);
|
||||
await expect(page.locator("h1")).toBeVisible();
|
||||
});
|
||||
|
||||
test("responsive behavior", async ({ page }) => {
|
||||
// Test mobile viewport
|
||||
await page.setViewportSize({ width: 375, height: 667 });
|
||||
await expect(page.getByTestId("mobile-nav")).toBeVisible();
|
||||
|
||||
// Test desktop viewport
|
||||
await page.setViewportSize({ width: 1280, height: 800 });
|
||||
await expect(page.getByTestId("desktop-nav")).toBeVisible();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Available Scripts
|
||||
|
||||
```bash
|
||||
npm run e2e # Run all E2E tests
|
||||
npm run e2e:ui # Run E2E tests with UI
|
||||
npm run e2e:serve # Start dev server and run tests
|
||||
```
|
||||
|
||||
## 🎨 Visual Regression Testing
|
||||
|
||||
### Overview
|
||||
|
||||
Visual regression testing ensures UI consistency across browsers and prevents unintended visual changes by comparing screenshots against baseline images.
|
||||
|
||||
### Configuration
|
||||
|
||||
- **Snapshot Template**: `{testDir}/{testFileName}-snapshots/{arg}-{projectName}.png`
|
||||
- **Deterministic Rendering**: Fixed timezone (UTC), locale (en-US), viewport
|
||||
- **Tolerance**: 2% pixel difference or 500 pixels maximum
|
||||
- **Animation Handling**: Disabled during capture
|
||||
|
||||
### Screenshots Generated
|
||||
|
||||
- **Full page screenshots** (mobile, tablet, desktop)
|
||||
- **Component screenshots** (hero, logo wall, cards, etc.)
|
||||
- **Interactive states** (hover, focus, loading, error)
|
||||
- **Special modes** (dark mode, high contrast, reduced motion)
|
||||
|
||||
### Breakpoint Coverage
|
||||
|
||||
- **Mobile**: 375x667 (iPhone)
|
||||
- **Tablet**: 768x1024 (iPad)
|
||||
- **Desktop**: 1280x800 (Standard)
|
||||
- **Large Desktop**: 1920x1080 (Full HD)
|
||||
|
||||
### Managing Visual Changes
|
||||
|
||||
```bash
|
||||
# Update baselines after intentional changes
|
||||
npm run visual:update
|
||||
|
||||
# Run visual regression tests
|
||||
npm run visual:test
|
||||
|
||||
# Run with UI for debugging
|
||||
npm run visual:ui
|
||||
```
|
||||
|
||||
### Snapshot Management
|
||||
|
||||
```bash
|
||||
# Update snapshots for all projects
|
||||
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts
|
||||
|
||||
# Update snapshots for specific project
|
||||
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium
|
||||
|
||||
# View test results
|
||||
npx playwright show-report
|
||||
```
|
||||
|
||||
## ♿ Accessibility Testing
|
||||
|
||||
### Framework
|
||||
|
||||
- **Unit Level**: jest-axe with Vitest (`tests/accessibility/unit/`)
|
||||
- **E2E Level**: Playwright accessibility tests (`tests/accessibility/e2e/`)
|
||||
- **Standards**: WCAG 2.1 AA compliance
|
||||
|
||||
### Test Organization
|
||||
|
||||
Accessibility tests are organized in a dedicated `tests/accessibility/` folder:
|
||||
|
||||
```
|
||||
tests/accessibility/
|
||||
├── unit/ # Unit-level accessibility tests
|
||||
│ └── components.test.jsx # Component accessibility (jest-axe)
|
||||
└── e2e/ # E2E accessibility tests
|
||||
└── wcag-compliance.spec.ts # WCAG compliance (Playwright)
|
||||
```
|
||||
|
||||
### Unit-Level Accessibility Testing
|
||||
|
||||
```jsx
|
||||
// tests/accessibility/unit/components.test.jsx
|
||||
import { axe, toHaveNoViolations } from "jest-axe";
|
||||
|
||||
test("component has no accessibility violations", async () => {
|
||||
const { container } = render(<Component />);
|
||||
const results = await axe(container);
|
||||
expect(results).toHaveNoViolations();
|
||||
});
|
||||
```
|
||||
|
||||
### E2E Accessibility Testing
|
||||
|
||||
```typescript
|
||||
// tests/accessibility/e2e/wcag-compliance.spec.ts
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test("WCAG 2.1 AA compliance - homepage", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
|
||||
// Check for proper HTML structure
|
||||
const html = page.locator("html");
|
||||
const lang = await html.getAttribute("lang");
|
||||
expect(lang).toBeTruthy();
|
||||
|
||||
// Check for main heading
|
||||
const h1 = page.locator("h1").first();
|
||||
await expect(h1).toBeVisible();
|
||||
});
|
||||
```
|
||||
|
||||
### Running Accessibility Tests
|
||||
|
||||
```bash
|
||||
# Run all accessibility tests
|
||||
npm test tests/accessibility/
|
||||
|
||||
# Run unit accessibility tests only
|
||||
npm test tests/accessibility/unit/
|
||||
|
||||
# Run E2E accessibility tests only
|
||||
npx playwright test tests/accessibility/e2e/
|
||||
|
||||
# Run specific accessibility test
|
||||
npx playwright test tests/accessibility/e2e/wcag-compliance.spec.ts
|
||||
```
|
||||
|
||||
### Manual Testing Checklist
|
||||
|
||||
- [ ] Screen reader compatibility
|
||||
- [ ] Keyboard navigation
|
||||
- [ ] Color contrast (WCAG AA)
|
||||
- [ ] Focus management
|
||||
- [ ] ARIA attributes
|
||||
- [ ] Semantic HTML
|
||||
|
||||
### WCAG 2.1 AA Requirements
|
||||
|
||||
- **Perceivable**: Text alternatives, captions, adaptable content
|
||||
- **Operable**: Keyboard accessible, timing adjustable, navigation
|
||||
- **Understandable**: Readable, predictable, input assistance
|
||||
- **Robust**: Compatible with assistive technologies
|
||||
|
||||
## ⚡ Performance Testing
|
||||
|
||||
### Framework
|
||||
|
||||
- **Lighthouse CI**: Automated performance testing
|
||||
- **Bundle Analysis**: Real-time bundle size monitoring
|
||||
- **Web Vitals Tracking**: Core Web Vitals collection and reporting
|
||||
- **Performance Monitoring**: Comprehensive performance metrics
|
||||
- **Performance Budgets**: Defined thresholds with automated enforcement
|
||||
|
||||
### Configuration
|
||||
|
||||
```json
|
||||
// .lighthouserc.json
|
||||
{
|
||||
"ci": {
|
||||
"collect": {
|
||||
"url": ["http://localhost:3010"],
|
||||
"chromeFlags": [
|
||||
"--no-sandbox",
|
||||
"--disable-dev-shm-usage",
|
||||
"--disable-gpu",
|
||||
"--headless"
|
||||
]
|
||||
},
|
||||
"assert": {
|
||||
"assertions": {
|
||||
"categories:performance": ["warn", { "minScore": 0.8 }],
|
||||
"categories:accessibility": ["error", { "minScore": 0.8 }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Performance Metrics
|
||||
|
||||
- **Core Web Vitals**: LCP < 2.5s, FID < 100ms, CLS < 0.1
|
||||
- **Performance Score**: >80
|
||||
- **Accessibility Score**: >80
|
||||
- **Best Practices**: >90
|
||||
- **Bundle Size**: <250KB gzipped (currently 101KB)
|
||||
|
||||
### Performance Budgets
|
||||
|
||||
- **First Contentful Paint**: <3000ms
|
||||
- **Largest Contentful Paint**: <5000ms
|
||||
- **First Input Delay**: <100ms
|
||||
- **TTFB**: <700ms
|
||||
- **Bundle Size**: <250KB gzipped
|
||||
- **Total Bundle Size**: <2MB
|
||||
|
||||
### Performance Optimizations
|
||||
|
||||
- **✅ Code Splitting**: Dynamic imports for non-critical components
|
||||
- **✅ React.memo**: Applied to all 30+ components
|
||||
- **✅ Image Optimization**: Enhanced `next/image` with lazy loading
|
||||
- **✅ Font Optimization**: Preloading and fallbacks
|
||||
- **✅ Bundle Analysis**: Real-time monitoring with budgets
|
||||
- **✅ Error Boundaries**: Comprehensive error handling
|
||||
|
||||
### Available Scripts
|
||||
|
||||
```bash
|
||||
# Individual monitoring tools
|
||||
npm run bundle:analyze # Analyze bundle sizes and budgets
|
||||
npm run performance:monitor # Performance metrics and Lighthouse CI
|
||||
npm run web-vitals:track # Core Web Vitals tracking
|
||||
|
||||
# Comprehensive testing
|
||||
npm run test:performance # All performance tests
|
||||
npm run monitor:all # All monitoring tools
|
||||
|
||||
# Traditional Lighthouse CI
|
||||
npm run lhci # Run Lighthouse CI
|
||||
npm run lhci:mobile # Run with mobile preset
|
||||
npm run lhci:desktop # Run with desktop preset
|
||||
```
|
||||
|
||||
### Performance Monitoring Dashboard
|
||||
|
||||
Access the performance monitoring dashboard at `/monitor` to view:
|
||||
|
||||
- Real-time Web Vitals metrics
|
||||
- Historical performance data
|
||||
- Bundle analysis results
|
||||
- Performance budget status
|
||||
- Optimization recommendations
|
||||
|
||||
## 🔄 CI/CD Pipeline
|
||||
|
||||
### Gitea Actions Workflow
|
||||
|
||||
Location: `.gitea/workflows/ci.yaml`
|
||||
|
||||
### Pipeline Jobs
|
||||
|
||||
#### 1. Unit Tests
|
||||
|
||||
- **Node.js versions**: 18, 20
|
||||
- **Coverage reporting**: Codecov integration
|
||||
- **Parallel execution**: Matrix strategy
|
||||
|
||||
#### 2. E2E Tests
|
||||
|
||||
- **Browsers**: Chromium, Firefox, WebKit
|
||||
- **Parallel execution**: Matrix strategy
|
||||
- **Artifact upload**: Test results and reports
|
||||
|
||||
#### 3. Visual Regression Tests
|
||||
|
||||
- **Screenshot comparison**: Baseline vs current
|
||||
- **Cross-browser validation**: All 4 browser projects
|
||||
|
||||
#### 4. Performance Tests
|
||||
|
||||
- **Lighthouse CI**: Performance budgets
|
||||
- **Core Web Vitals**: Monitoring
|
||||
- **Accessibility compliance**
|
||||
|
||||
#### 5. Storybook Tests
|
||||
|
||||
- **Component testing**: Automated tests
|
||||
- **Accessibility validation**: WCAG compliance
|
||||
- **Build verification**: Storybook compilation
|
||||
|
||||
#### 6. Lint & Format
|
||||
|
||||
- **ESLint**: Code quality
|
||||
- **Prettier**: Code formatting
|
||||
|
||||
#### 7. Build Verification
|
||||
|
||||
- **Next.js build**: Application compilation
|
||||
- **Storybook build**: Documentation compilation
|
||||
|
||||
### Triggers
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
```
|
||||
|
||||
## 🛠 Development Workflow
|
||||
|
||||
### 1. Feature Development
|
||||
|
||||
```bash
|
||||
# Create feature branch
|
||||
git checkout -b feature/new-component
|
||||
|
||||
# Write tests first (TDD)
|
||||
npm run test:watch
|
||||
|
||||
# Implement feature
|
||||
# Ensure tests pass
|
||||
|
||||
# Run E2E tests
|
||||
npm run e2e
|
||||
|
||||
# Commit changes
|
||||
git add .
|
||||
git commit -m "feat: add new component with tests"
|
||||
```
|
||||
|
||||
### 2. Pull Request Process
|
||||
|
||||
1. **Create PR** → CI pipeline starts automatically
|
||||
2. **Review CI Results** → All 7 jobs must pass
|
||||
3. **Check Coverage** → Ensure >85% coverage
|
||||
4. **Review Visual Changes** → Check screenshot diffs
|
||||
5. **Merge** → Only if all checks pass
|
||||
|
||||
### 3. Visual Changes
|
||||
|
||||
```bash
|
||||
# Make visual changes
|
||||
# Run visual regression tests
|
||||
npm run visual:test
|
||||
|
||||
# If changes are intentional, update baselines
|
||||
npm run visual:update
|
||||
|
||||
# Review and commit updated snapshots
|
||||
git add tests/e2e/visual-regression.spec.ts-snapshots/
|
||||
git commit -m "Update visual regression snapshots for [describe changes]"
|
||||
```
|
||||
|
||||
### 4. Performance Monitoring
|
||||
|
||||
```bash
|
||||
# Check performance before deploying
|
||||
npm run lhci
|
||||
|
||||
# Review performance budgets
|
||||
# Update .lighthouserc.json if needed
|
||||
```
|
||||
|
||||
## 📋 Best Practices
|
||||
|
||||
### 1. Test-Driven Development
|
||||
|
||||
- Write tests before implementation
|
||||
- Use descriptive test names
|
||||
- Test edge cases and error scenarios
|
||||
- Maintain high test coverage
|
||||
|
||||
### 2. Component Testing
|
||||
|
||||
```jsx
|
||||
// ✅ Good: Test behavior, not implementation
|
||||
test("shows error message when form is invalid", () => {
|
||||
render(<Form />);
|
||||
fireEvent.click(screen.getByRole("button"));
|
||||
expect(screen.getByText("Please fill all fields")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// ❌ Avoid: Testing implementation details
|
||||
test("calls onSubmit with form data", () => {
|
||||
const mockSubmit = vi.fn();
|
||||
render(<Form onSubmit={mockSubmit} />);
|
||||
// Implementation details...
|
||||
});
|
||||
```
|
||||
|
||||
### 3. E2E Testing
|
||||
|
||||
- Test user workflows, not technical details
|
||||
- Use semantic selectors (role, text, label)
|
||||
- Test accessibility features
|
||||
- Include error scenarios
|
||||
|
||||
### 4. Visual Regression
|
||||
|
||||
- Update baselines only for intentional changes
|
||||
- Review screenshot diffs carefully
|
||||
- Test across multiple viewports
|
||||
- Consider animation states
|
||||
|
||||
### 5. Performance Testing
|
||||
|
||||
- Set realistic performance budgets
|
||||
- Monitor Core Web Vitals
|
||||
- Test on different network conditions
|
||||
- Regular performance audits
|
||||
|
||||
### 6. Responsive Testing
|
||||
|
||||
```javascript
|
||||
// ✅ Good: Test real viewport sizes
|
||||
await page.setViewportSize({ width: 640, height: 700 });
|
||||
|
||||
// ✅ Good: Test visibility at breakpoints
|
||||
if (bp.name === "xs") {
|
||||
await expect(page.getByTestId("auth-xs")).toBeVisible();
|
||||
}
|
||||
|
||||
// ❌ Avoid: Testing responsive behavior in JSDOM
|
||||
// JSDOM doesn't evaluate CSS media queries
|
||||
```
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### 1. Unit Tests Failing
|
||||
|
||||
```bash
|
||||
# Run tests locally
|
||||
npm test
|
||||
|
||||
# Check for:
|
||||
# - Missing imports
|
||||
# - Incorrect assertions
|
||||
# - Component changes
|
||||
# - Test environment issues
|
||||
```
|
||||
|
||||
#### 2. E2E Tests Failing
|
||||
|
||||
```bash
|
||||
# Run locally first
|
||||
npm run e2e
|
||||
|
||||
# Common issues:
|
||||
# - Selector changes
|
||||
# - Component structure changes
|
||||
# - Network issues
|
||||
# - Browser compatibility
|
||||
```
|
||||
|
||||
#### 3. Visual Regression Failing
|
||||
|
||||
```bash
|
||||
# Check if changes are intentional
|
||||
npm run visual:test
|
||||
|
||||
# Update baselines if needed
|
||||
npm run visual:update
|
||||
|
||||
# Review screenshot diffs in CI artifacts
|
||||
```
|
||||
|
||||
#### 4. Performance Tests Failing
|
||||
|
||||
```bash
|
||||
# Run locally
|
||||
npm run lhci
|
||||
|
||||
# Check performance budgets in .lighthouserc.json
|
||||
# Optimize slow components
|
||||
# Review bundle size
|
||||
```
|
||||
|
||||
#### 5. CI Pipeline Issues
|
||||
|
||||
```bash
|
||||
# Check Gitea Actions logs
|
||||
# Verify workflow configuration
|
||||
# Check for missing dependencies
|
||||
# Review environment variables
|
||||
```
|
||||
|
||||
### Debug Commands
|
||||
|
||||
```bash
|
||||
# Debug unit tests
|
||||
npm run test:ui
|
||||
|
||||
# Debug E2E tests
|
||||
npm run e2e:ui
|
||||
|
||||
# Debug with browser dev tools
|
||||
npx playwright test --debug
|
||||
|
||||
# Run specific test file
|
||||
npx playwright test tests/e2e/homepage.spec.ts
|
||||
|
||||
# Run tests in headed mode
|
||||
npx playwright test --headed
|
||||
```
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
### Documentation
|
||||
|
||||
- [Vitest Documentation](https://vitest.dev/)
|
||||
- [Playwright Documentation](https://playwright.dev/)
|
||||
- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/)
|
||||
- [Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci)
|
||||
- [Storybook Testing](https://storybook.js.org/docs/writing-tests/introduction)
|
||||
|
||||
### Tools
|
||||
|
||||
- [Codecov](https://codecov.io/) - Coverage reporting
|
||||
- [Axe-core](https://github.com/dequelabs/axe-core) - Accessibility testing
|
||||
- [MSW](https://mswjs.io/) - API mocking
|
||||
|
||||
### Best Practices
|
||||
|
||||
- [Testing Best Practices](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)
|
||||
- [E2E Testing Guide](https://playwright.dev/docs/best-practices)
|
||||
- [Visual Regression Testing](https://storybook.js.org/docs/writing-tests/visual-testing)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2024
|
||||
**Framework Version**: Next.js 15 + React 19 + Tailwind 4 + Storybook 9
|
||||
**Maintained by**: CommunityRule Development Team
|
||||
@@ -1,357 +0,0 @@
|
||||
# Testing Quick Reference
|
||||
|
||||
## 🚀 Essential Commands
|
||||
|
||||
### Daily Development
|
||||
|
||||
```bash
|
||||
# Run all tests with coverage
|
||||
npm test
|
||||
|
||||
# Watch mode (during development)
|
||||
npm run test:watch
|
||||
|
||||
# E2E tests
|
||||
npm run e2e
|
||||
|
||||
# Visual regression tests
|
||||
npm run visual:test
|
||||
|
||||
# Performance check
|
||||
npm run lhci
|
||||
|
||||
# Performance monitoring
|
||||
npm run test:performance # Comprehensive performance testing
|
||||
npm run bundle:analyze # Bundle size analysis
|
||||
npm run web-vitals:track # Web Vitals tracking
|
||||
npm run monitor:all # All monitoring tools
|
||||
|
||||
# Storybook tests
|
||||
npm run test:sb
|
||||
```
|
||||
|
||||
### Test UI & Debugging
|
||||
|
||||
```bash
|
||||
# Debug unit tests
|
||||
npm run test:ui
|
||||
|
||||
# Debug E2E tests
|
||||
npm run e2e:ui
|
||||
|
||||
# Debug with browser
|
||||
npx playwright test --debug
|
||||
|
||||
# Run tests in headed mode
|
||||
npx playwright test --headed
|
||||
```
|
||||
|
||||
## 📊 Current Test Status
|
||||
|
||||
- **Unit Tests**: 94.88% ✅ (Target: >85%)
|
||||
- **Integration Tests**: 5 comprehensive test suites ✅
|
||||
- **E2E Tests**: 92 tests across 4 browsers ✅
|
||||
- **Visual Regression**: 23 tests per browser ✅
|
||||
- **Accessibility Tests**: WCAG 2.1 AA compliance ✅
|
||||
- **Performance Tests**: Lighthouse CI with budgets ✅
|
||||
- **Bundle Analysis**: Real-time monitoring with budgets ✅
|
||||
- **Web Vitals Tracking**: Core Web Vitals collection ✅
|
||||
- **Performance Optimization**: React.memo + code splitting ✅
|
||||
|
||||
## 🔧 Common Test Commands
|
||||
|
||||
### Unit Testing
|
||||
|
||||
```bash
|
||||
# Run specific test file
|
||||
npm test -- --run tests/unit/Component.test.jsx
|
||||
|
||||
# Run tests matching pattern
|
||||
npm test -- --run Component
|
||||
|
||||
# Run with coverage report
|
||||
npm test -- --coverage
|
||||
|
||||
# Run in watch mode
|
||||
npm run test:watch
|
||||
```
|
||||
|
||||
### E2E Testing
|
||||
|
||||
```bash
|
||||
# Run specific test file
|
||||
npm run e2e -- tests/e2e/homepage.spec.ts
|
||||
|
||||
# Run specific project (browser)
|
||||
npm run e2e -- --project=chromium
|
||||
|
||||
# Run with headed browser
|
||||
npm run e2e -- --headed
|
||||
|
||||
# Run with debug mode
|
||||
npm run e2e -- --debug
|
||||
```
|
||||
|
||||
### Visual Regression
|
||||
|
||||
```bash
|
||||
# Update snapshots for all projects
|
||||
npm run visual:update
|
||||
|
||||
# Update snapshots for specific project
|
||||
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium
|
||||
|
||||
# View test results
|
||||
npx playwright show-report
|
||||
```
|
||||
|
||||
### Performance Testing
|
||||
|
||||
```bash
|
||||
# Run mobile performance test
|
||||
npm run lhci:mobile
|
||||
|
||||
# Run desktop performance test
|
||||
npm run lhci:desktop
|
||||
|
||||
# Run with custom budget
|
||||
npm run performance:budget
|
||||
```
|
||||
|
||||
### Accessibility Testing
|
||||
|
||||
```bash
|
||||
# Run all accessibility tests
|
||||
npm test tests/accessibility/
|
||||
|
||||
# Run unit accessibility tests only
|
||||
npm test tests/accessibility/unit/
|
||||
|
||||
# Run E2E accessibility tests only
|
||||
npx playwright test tests/accessibility/e2e/
|
||||
|
||||
# Run specific accessibility test
|
||||
npx playwright test tests/accessibility/e2e/wcag-compliance.spec.ts
|
||||
```
|
||||
|
||||
## 📱 Browser Support
|
||||
|
||||
| Browser | Project Name | Status |
|
||||
| ----------- | ------------ | --------------- |
|
||||
| **Chrome** | `chromium` | ✅ Full Support |
|
||||
| **Firefox** | `firefox` | ✅ Full Support |
|
||||
| **Safari** | `webkit` | ✅ Full Support |
|
||||
| **Mobile** | `mobile` | ✅ Full Support |
|
||||
|
||||
## 🎯 Testing Best Practices
|
||||
|
||||
### 1. Test Structure (AAA Pattern)
|
||||
|
||||
```jsx
|
||||
test("should do something", () => {
|
||||
// Arrange: Set up test data
|
||||
const data = { name: "Test" };
|
||||
|
||||
// Act: Perform the action
|
||||
const result = processData(data);
|
||||
|
||||
// Assert: Verify the outcome
|
||||
expect(result).toBe("Processed Test");
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Query Priority
|
||||
|
||||
1. **`getByRole`** - Most accessible, tests user experience
|
||||
2. **`getByLabelText`** - For form inputs
|
||||
3. **`getByText`** - For content
|
||||
4. **`getByTestId`** - Last resort, avoid when possible
|
||||
|
||||
### 3. Async Testing
|
||||
|
||||
```jsx
|
||||
test("async operation", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<Component />);
|
||||
const button = screen.getByRole("button");
|
||||
|
||||
await user.click(button);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Success")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 4. Responsive Testing
|
||||
|
||||
```javascript
|
||||
// ✅ Good: Test real viewport sizes
|
||||
await page.setViewportSize({ width: 640, height: 700 });
|
||||
|
||||
// ✅ Good: Test visibility at breakpoints
|
||||
if (bp.name === "xs") {
|
||||
await expect(page.getByTestId("auth-xs")).toBeVisible();
|
||||
}
|
||||
|
||||
// ❌ Avoid: Testing responsive behavior in JSDOM
|
||||
// JSDOM doesn't evaluate CSS media queries
|
||||
```
|
||||
|
||||
## 🔍 Common Issues & Solutions
|
||||
|
||||
### Visual Regression Failures
|
||||
|
||||
```bash
|
||||
# Regenerate snapshots
|
||||
npm run visual:update
|
||||
|
||||
# Check for environment differences
|
||||
# Ensure deterministic rendering in Playwright config
|
||||
```
|
||||
|
||||
### E2E Test Failures
|
||||
|
||||
```bash
|
||||
# Use waitFor instead of waitForTimeout
|
||||
await page.waitForSelector("button", { state: "visible" });
|
||||
|
||||
# Use role-based selectors
|
||||
await page.getByRole("button", { name: "Submit" }).click();
|
||||
|
||||
# Check for selector changes
|
||||
# Verify component structure hasn't changed
|
||||
```
|
||||
|
||||
### Performance Test Failures
|
||||
|
||||
```bash
|
||||
# Check Chrome path on macOS
|
||||
# Ensure arm64 Chrome for Apple Silicon
|
||||
# Verify performance budgets in .lighthouserc.json
|
||||
```
|
||||
|
||||
### Unit Test Failures
|
||||
|
||||
```bash
|
||||
# Check for missing imports
|
||||
# Verify component exports
|
||||
# Ensure test environment setup
|
||||
# Check for component changes
|
||||
```
|
||||
|
||||
## 📈 Performance Budgets
|
||||
|
||||
### Lighthouse CI Targets
|
||||
|
||||
- **Performance Score**: >80
|
||||
- **Accessibility Score**: >80
|
||||
- **Best Practices**: >90
|
||||
- **SEO Score**: >90
|
||||
|
||||
### Core Web Vitals
|
||||
|
||||
- **LCP**: <2.5s
|
||||
- **FID**: <100ms
|
||||
- **CLS**: <0.1
|
||||
|
||||
### Performance Budgets
|
||||
|
||||
- **First Contentful Paint**: <3000ms
|
||||
- **Largest Contentful Paint**: <5000ms
|
||||
- **First Input Delay**: <100ms
|
||||
- **TTFB**: <700ms
|
||||
|
||||
## 🔄 CI/CD Pipeline Jobs
|
||||
|
||||
1. **Unit Tests** (Node 18, 20) - Coverage reporting
|
||||
2. **E2E Tests** (Chromium, Firefox, WebKit) - Cross-browser testing
|
||||
3. **Visual Regression Tests** - Screenshot comparison
|
||||
4. **Performance Tests** - Lighthouse CI with budgets
|
||||
5. **Storybook Tests** - Component testing & accessibility
|
||||
6. **Lint & Format** - Code quality & formatting
|
||||
7. **Build Verification** - Next.js & Storybook builds
|
||||
|
||||
## 📁 Test File Structure
|
||||
|
||||
```
|
||||
tests/
|
||||
├── unit/ # Component tests
|
||||
│ ├── Button.test.jsx # 12 tests
|
||||
│ ├── Logo.test.jsx # 12 tests
|
||||
│ ├── RuleCard.test.jsx # 18 tests
|
||||
│ ├── SectionHeader.test.jsx # 17 tests
|
||||
│ ├── NumberedCard.test.jsx # 18 tests
|
||||
│ └── ... # Other component tests
|
||||
├── integration/ # Integration tests
|
||||
│ ├── component-interactions.integration.test.jsx
|
||||
│ ├── page-flow.integration.test.jsx
|
||||
│ ├── user-journey.integration.test.jsx
|
||||
│ ├── layout.integration.test.jsx
|
||||
│ └── ContentLockup.integration.test.jsx
|
||||
├── accessibility/ # Accessibility-focused tests
|
||||
│ ├── unit/ # Unit-level accessibility (jest-axe)
|
||||
│ │ └── components.test.jsx # Component accessibility tests
|
||||
│ └── e2e/ # E2E accessibility (Playwright + axe-core)
|
||||
│ └── wcag-compliance.spec.ts # WCAG compliance tests
|
||||
└── e2e/ # General E2E tests
|
||||
├── homepage.spec.ts # Homepage functionality
|
||||
├── user-journeys.spec.ts # User workflows
|
||||
├── header.responsive.spec.js # Responsive header
|
||||
├── footer.responsive.spec.js # Responsive footer
|
||||
├── visual-regression.spec.ts # Visual consistency
|
||||
├── accessibility.spec.ts # General accessibility tests
|
||||
└── performance.spec.ts # Performance metrics
|
||||
```
|
||||
|
||||
## 🎨 Visual Regression Screenshots
|
||||
|
||||
### Generated Screenshots
|
||||
|
||||
- Full page (mobile, tablet, desktop)
|
||||
- Component sections (hero, logo wall, cards)
|
||||
- Interactive states (hover, focus, loading)
|
||||
- Special modes (dark, high contrast, reduced motion)
|
||||
|
||||
### Managing Changes
|
||||
|
||||
```bash
|
||||
# Intentional changes
|
||||
npm run visual:update
|
||||
|
||||
# Review changes
|
||||
git diff tests/e2e/visual-regression.spec.ts-snapshots/
|
||||
|
||||
# Commit updated snapshots
|
||||
git add tests/e2e/visual-regression.spec.ts-snapshots/
|
||||
git commit -m "Update visual regression snapshots for [describe changes]"
|
||||
```
|
||||
|
||||
## 📈 Monitoring
|
||||
|
||||
### Test Metrics
|
||||
|
||||
- **Unit Tests**: 305 tests (94.88% coverage)
|
||||
- **E2E Tests**: 92 tests (4 browsers)
|
||||
- **Visual Screenshots**: 92 baselines per browser
|
||||
- **Coverage**: >85% target (exceeded)
|
||||
|
||||
### CI Metrics
|
||||
|
||||
- **Pipeline Jobs**: 7 parallel jobs
|
||||
- **Execution Time**: Monitor build performance
|
||||
- **Success Rate**: Track pipeline stability
|
||||
- **Artifacts**: Test results and screenshots
|
||||
|
||||
## 🔗 Useful Links
|
||||
|
||||
- **Full Testing Documentation**: [docs/guides/testing-framework.md](./testing-framework.md)
|
||||
- **Vitest Docs**: https://vitest.dev/
|
||||
- **Playwright Docs**: https://playwright.dev/
|
||||
- **React Testing Library**: https://testing-library.com/docs/react-testing-library/intro/
|
||||
- **Lighthouse CI**: https://github.com/GoogleChrome/lighthouse-ci
|
||||
|
||||
---
|
||||
|
||||
**Quick Reference Version**: December 2024
|
||||
**For detailed guidelines, see [testing-framework.md](./testing-framework.md)**
|
||||
@@ -1,258 +0,0 @@
|
||||
# Testing Strategy for CommunityRule
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines our comprehensive testing strategy that properly separates unit testing from responsive behavior testing, following best practices for JSDOM limitations and real browser testing.
|
||||
|
||||
## Current Test Status
|
||||
|
||||
- **236 total tests** across the project
|
||||
- **227 tests passing** (96.2% success rate)
|
||||
- **9 tests failing** (performance and interaction tests)
|
||||
- **15 test files** covering all major components
|
||||
- **Performance Monitoring**: Comprehensive regression detection and budget enforcement
|
||||
|
||||
## Testing Philosophy
|
||||
|
||||
### The Problem with JSDOM and Responsive Testing
|
||||
|
||||
**Short take: Unit tests in JSDOM can't truly "switch breakpoints."** JSDOM doesn't evaluate CSS media queries, so Tailwind's `hidden sm:block …` won't change visibility when you "resize" the window.
|
||||
|
||||
### Solution: Proper Test Separation
|
||||
|
||||
- **Unit / component tests (Vitest + RTL):** assert **structure and classes**, not responsive visibility.
|
||||
- **Responsive behavior:** verify with **browser-based tests** (Playwright) or **visual tests** (Chromatic/Storybook) at real viewport widths.
|
||||
|
||||
## Test Categories
|
||||
|
||||
### 1. Unit Tests (Vitest + React Testing Library)
|
||||
|
||||
**Purpose:** Test component structure, accessibility, and configuration data.
|
||||
|
||||
**What to test:**
|
||||
|
||||
- DOM roles/labels exist: `role="banner"`, nav landmark, menu items
|
||||
- The right **Tailwind classes** are present on wrappers (`block sm:hidden`, `hidden md:block`, etc.)
|
||||
- Data-driven bits produce the expected count/order (e.g., `navigationItems`, `avatarImages`, `logoConfig`)
|
||||
- Component configuration and exported data structures
|
||||
|
||||
**Example:**
|
||||
|
||||
```javascript
|
||||
// tests/unit/Header.structure.test.js
|
||||
test("logo wrappers include breakpoint classes", () => {
|
||||
render(<Header />);
|
||||
const logoWrappers = screen.getAllByTestId("logo-wrapper");
|
||||
|
||||
// Check first logo variant (xs only)
|
||||
expect(logoWrappers[0]).toHaveClass("block", "sm:hidden");
|
||||
|
||||
// Check second logo variant (sm only)
|
||||
expect(logoWrappers[1]).toHaveClass("hidden", "sm:block", "md:hidden");
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Browser-Based Tests (Playwright)
|
||||
|
||||
**Purpose:** Test real responsive behavior at actual viewport widths.
|
||||
|
||||
**What to test:**
|
||||
|
||||
- **Visibility** at real breakpoints
|
||||
- **Layout changes** between breakpoints
|
||||
- **Interactive behavior** at different screen sizes
|
||||
- **Accessibility** across viewports
|
||||
|
||||
**Example:**
|
||||
|
||||
```javascript
|
||||
// tests/e2e/header.responsive.spec.js
|
||||
const breakpoints = [
|
||||
{ name: "xs", width: 360, height: 700 },
|
||||
{ name: "sm", width: 640, height: 700 },
|
||||
{ name: "md", width: 768, height: 700 },
|
||||
{ name: "lg", width: 1024, height: 700 },
|
||||
{ name: "xl", width: 1280, height: 700 },
|
||||
];
|
||||
|
||||
for (const bp of breakpoints) {
|
||||
test(`header layout at ${bp.name}`, async ({ page }) => {
|
||||
await page.setViewportSize({ width: bp.width, height: bp.height });
|
||||
await page.goto("/");
|
||||
|
||||
const nav = page.getByRole("navigation", { name: /main navigation/i });
|
||||
await expect(nav).toBeVisible();
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Visual Tests (Storybook + Chromatic)
|
||||
|
||||
**Purpose:** Visual regression testing and design system validation.
|
||||
|
||||
**What to test:**
|
||||
|
||||
- **Visual diffs** per breakpoint
|
||||
- **Design consistency** across viewports
|
||||
- **Component variations** and states
|
||||
|
||||
**Example:**
|
||||
|
||||
```javascript
|
||||
// stories/Header.responsive.stories.js
|
||||
export default {
|
||||
parameters: {
|
||||
chromatic: {
|
||||
viewports: [360, 640, 768, 1024, 1280],
|
||||
delay: 100,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Component Improvements
|
||||
|
||||
### Header Component Enhancements
|
||||
|
||||
1. **Added Test IDs** for easier testing:
|
||||
|
||||
```jsx
|
||||
<div data-testid="logo-wrapper" className={config.breakpoint}>
|
||||
{renderLogo(config.size, config.showText)}
|
||||
</div>
|
||||
```
|
||||
|
||||
2. **Exported Configuration** for testing:
|
||||
|
||||
```javascript
|
||||
export const navigationItems = [...];
|
||||
export const avatarImages = [...];
|
||||
export const logoConfig = [...];
|
||||
```
|
||||
|
||||
3. **Structured Breakpoint Containers**:
|
||||
```jsx
|
||||
<div data-testid="nav-xs" className="block sm:hidden">
|
||||
<div data-testid="nav-sm" className="hidden sm:block md:hidden">
|
||||
<div data-testid="nav-md" className="hidden md:block lg:hidden">
|
||||
```
|
||||
|
||||
## Test File Structure
|
||||
|
||||
```
|
||||
tests/
|
||||
├── unit/ # Unit tests (Vitest + RTL)
|
||||
│ ├── Header.test.jsx # CONSOLIDATED: Comprehensive Header tests
|
||||
│ ├── Footer.test.jsx
|
||||
│ ├── Layout.test.jsx
|
||||
│ └── Page.test.jsx
|
||||
├── integration/ # Integration tests
|
||||
│ └── ContentLockup.integration.test.jsx
|
||||
├── e2e/ # Browser tests (Playwright)
|
||||
│ └── header.responsive.spec.js # NEW: Responsive behavior tests
|
||||
└── stories/ # Storybook stories
|
||||
└── Header.responsive.stories.js # NEW: Visual testing
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Unit Testing (JSDOM)
|
||||
|
||||
1. **Test structure, not visibility**:
|
||||
|
||||
```javascript
|
||||
// ✅ Good: Test classes exist
|
||||
expect(element).toHaveClass("block", "sm:hidden");
|
||||
|
||||
// ❌ Bad: Test visibility (doesn't work in JSDOM)
|
||||
expect(element).toBeVisible();
|
||||
```
|
||||
|
||||
2. **Use test IDs for containers**:
|
||||
|
||||
```javascript
|
||||
// ✅ Good: Test specific containers
|
||||
const logoWrapper = screen.getByTestId("logo-wrapper");
|
||||
|
||||
// ❌ Bad: Query by complex class strings
|
||||
const logoWrapper = document.querySelector(".block.sm\\:hidden");
|
||||
```
|
||||
|
||||
3. **Test configuration data**:
|
||||
```javascript
|
||||
// ✅ Good: Test exported configuration
|
||||
expect(navigationItems).toHaveLength(3);
|
||||
expect(logoConfig).toHaveLength(5);
|
||||
```
|
||||
|
||||
### Browser Testing (Playwright)
|
||||
|
||||
1. **Test real viewport sizes**:
|
||||
|
||||
```javascript
|
||||
await page.setViewportSize({ width: 640, height: 700 });
|
||||
```
|
||||
|
||||
2. **Test visibility at breakpoints**:
|
||||
|
||||
```javascript
|
||||
if (bp.name === "xs") {
|
||||
await expect(page.getByTestId("auth-xs")).toBeVisible();
|
||||
}
|
||||
```
|
||||
|
||||
3. **Test accessibility across viewports**:
|
||||
|
||||
```javascript
|
||||
const interactiveElements = [
|
||||
page.getByRole("link", { name: /use cases/i }),
|
||||
page.getByRole("button", { name: /create rule/i }),
|
||||
];
|
||||
|
||||
for (const element of interactiveElements) {
|
||||
await expect(element).toBeVisible();
|
||||
await expect(element).toBeEnabled();
|
||||
}
|
||||
```
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Unit Tests
|
||||
|
||||
```bash
|
||||
npm test # Run all unit tests
|
||||
npm test tests/unit/ # Run only unit tests
|
||||
npm test Header.structure # Run specific test file
|
||||
```
|
||||
|
||||
### Browser Tests
|
||||
|
||||
```bash
|
||||
npx playwright test # Run all browser tests
|
||||
npx playwright test header.responsive.spec.js # Run specific test
|
||||
```
|
||||
|
||||
### Visual Tests
|
||||
|
||||
```bash
|
||||
npm run storybook # Start Storybook
|
||||
npx chromatic --project-token=xxx # Run visual tests
|
||||
```
|
||||
|
||||
## Future Improvements
|
||||
|
||||
1. **Add more Playwright tests** for other components
|
||||
2. **Set up Chromatic** for visual regression testing
|
||||
3. **Add performance tests** for responsive behavior
|
||||
4. **Create component-specific test utilities**
|
||||
5. **Add accessibility testing** with axe-core
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
1. **JSDOM limitations** require separating structure tests from visibility tests
|
||||
2. **Test IDs** make testing more reliable and maintainable
|
||||
3. **Exported configuration** enables better data structure testing
|
||||
4. **Real browser testing** is essential for responsive behavior
|
||||
5. **Visual testing** catches design regressions across breakpoints
|
||||
|
||||
This strategy provides comprehensive coverage while respecting the limitations of different testing environments.
|
||||
@@ -1,391 +0,0 @@
|
||||
# Visual Regression Testing Guide
|
||||
|
||||
## Overview
|
||||
|
||||
Visual regression testing ensures UI consistency across browsers and prevents unintended visual changes by comparing screenshots against baseline images. This guide covers the complete workflow for managing visual regression tests.
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### First-Time Setup
|
||||
|
||||
```bash
|
||||
# 1. Generate baseline snapshots for all projects
|
||||
npm run visual:update
|
||||
|
||||
# 2. Verify snapshots were created
|
||||
ls tests/e2e/visual-regression.spec.ts-snapshots/
|
||||
|
||||
# 3. Commit the snapshots
|
||||
git add tests/e2e/visual-regression.spec.ts-snapshots/
|
||||
git commit -m "Add baseline visual regression snapshots"
|
||||
|
||||
# 4. Verify setup works
|
||||
npm run visual:test
|
||||
```
|
||||
|
||||
### Daily Workflow
|
||||
|
||||
```bash
|
||||
# Run visual regression tests
|
||||
npm run visual:test
|
||||
|
||||
# Run with UI for debugging
|
||||
npm run visual:ui
|
||||
|
||||
# Update snapshots after UI changes
|
||||
npm run visual:update
|
||||
```
|
||||
|
||||
## 📝 Managing Visual Changes
|
||||
|
||||
### When UI Changes Are Intentional
|
||||
|
||||
1. **Make your UI changes** (design updates, component modifications, etc.)
|
||||
|
||||
2. **Update snapshots to reflect new design:**
|
||||
|
||||
```bash
|
||||
npm run visual:update
|
||||
```
|
||||
|
||||
3. **Review changes:**
|
||||
|
||||
```bash
|
||||
git diff tests/e2e/visual-regression.spec.ts-snapshots/
|
||||
```
|
||||
|
||||
4. **Commit updated snapshots:**
|
||||
```bash
|
||||
git add tests/e2e/visual-regression.spec.ts-snapshots/
|
||||
git commit -m "Update snapshots for [describe changes]"
|
||||
```
|
||||
|
||||
### When UI Changes Are Unintentional
|
||||
|
||||
1. **Investigate the failure** - Check what changed and why
|
||||
2. **Fix the regression** - Revert or fix the unintended change
|
||||
3. **Re-run tests** - Ensure they pass without updating snapshots
|
||||
4. **Commit the fix** - Don't update snapshots for bug fixes
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
### Playwright Configuration
|
||||
|
||||
The visual regression tests use these key settings in `playwright.config.ts`:
|
||||
|
||||
```typescript
|
||||
export default defineConfig({
|
||||
expect: {
|
||||
toHaveScreenshot: {
|
||||
animations: "disabled",
|
||||
maxDiffPixelRatio: 0.02, // 2% tolerance
|
||||
maxDiffPixels: 500, // 500 pixel tolerance
|
||||
},
|
||||
},
|
||||
use: {
|
||||
timezoneId: "UTC", // Consistent timezone
|
||||
locale: "en-US", // Consistent locale
|
||||
headless: true, // Headless for CI
|
||||
},
|
||||
snapshotPathTemplate:
|
||||
"{testDir}/{testFileName}-snapshots/{arg}-{projectName}.png",
|
||||
});
|
||||
```
|
||||
|
||||
### Deterministic Rendering
|
||||
|
||||
To ensure consistent screenshots across environments:
|
||||
|
||||
- **Fixed timezone**: UTC
|
||||
- **Fixed locale**: en-US
|
||||
- **Fixed viewport**: 1280x800 (configurable per test)
|
||||
- **Disabled animations**: Prevents timing-related differences
|
||||
- **Browser-specific snapshots**: Separate baselines per browser
|
||||
|
||||
## 📱 Breakpoint Coverage
|
||||
|
||||
### Standard Viewports
|
||||
|
||||
| Breakpoint | Width | Height | Description |
|
||||
| ----------- | ------ | ------ | ---------------- |
|
||||
| **Mobile** | 375px | 667px | iPhone portrait |
|
||||
| **Tablet** | 768px | 1024px | iPad portrait |
|
||||
| **Desktop** | 1280px | 800px | Standard desktop |
|
||||
| **Large** | 1920px | 1080px | Full HD desktop |
|
||||
|
||||
### Custom Viewports
|
||||
|
||||
```typescript
|
||||
test("mobile layout", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 375, height: 667 });
|
||||
await expect(page).toHaveScreenshot("mobile-layout.png");
|
||||
});
|
||||
|
||||
test("tablet layout", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 768, height: 1024 });
|
||||
await expect(page).toHaveScreenshot("tablet-layout.png");
|
||||
});
|
||||
```
|
||||
|
||||
## 🎨 Screenshot Types
|
||||
|
||||
### Full Page Screenshots
|
||||
|
||||
```typescript
|
||||
test("homepage full page", async ({ page }) => {
|
||||
await expect(page).toHaveScreenshot("homepage-full.png", {
|
||||
fullPage: true,
|
||||
animations: "disabled",
|
||||
scale: "css",
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Component Screenshots
|
||||
|
||||
```typescript
|
||||
test("hero section", async ({ page }) => {
|
||||
const hero = page.locator("[data-testid='hero-section']");
|
||||
await expect(hero).toHaveScreenshot("hero-section.png");
|
||||
});
|
||||
```
|
||||
|
||||
### Interactive States
|
||||
|
||||
```typescript
|
||||
test("button hover state", async ({ page }) => {
|
||||
const button = page.getByRole("button", { name: "Submit" });
|
||||
|
||||
// Normal state
|
||||
await expect(button).toHaveScreenshot("button-normal.png");
|
||||
|
||||
// Hover state
|
||||
await button.hover();
|
||||
await expect(button).toHaveScreenshot("button-hover.png");
|
||||
});
|
||||
```
|
||||
|
||||
### Special Modes
|
||||
|
||||
```typescript
|
||||
test("dark mode", async ({ page }) => {
|
||||
// Enable dark mode
|
||||
await page.evaluate(() => {
|
||||
document.documentElement.classList.add("dark");
|
||||
});
|
||||
|
||||
await expect(page).toHaveScreenshot("dark-mode.png");
|
||||
});
|
||||
|
||||
test("high contrast", async ({ page }) => {
|
||||
// Enable high contrast
|
||||
await page.evaluate(() => {
|
||||
document.body.style.filter = "contrast(200%)";
|
||||
});
|
||||
|
||||
await expect(page).toHaveScreenshot("high-contrast.png");
|
||||
});
|
||||
```
|
||||
|
||||
## 🔄 Snapshot Management
|
||||
|
||||
### Update Commands
|
||||
|
||||
```bash
|
||||
# Update all snapshots for all projects
|
||||
npm run visual:update
|
||||
|
||||
# Update snapshots for specific project
|
||||
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium
|
||||
|
||||
# Update snapshots for specific test
|
||||
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --grep="homepage"
|
||||
```
|
||||
|
||||
### Snapshot Naming Convention
|
||||
|
||||
Snapshots follow this pattern:
|
||||
|
||||
```
|
||||
{testDir}/{testFileName}-snapshots/{arg}-{projectName}.png
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
- `tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-chromium.png`
|
||||
- `tests/e2e/visual-regression.spec.ts-snapshots/hero-section-firefox.png`
|
||||
- `tests/e2e/visual-regression.spec.ts-snapshots/button-hover-webkit.png`
|
||||
- `tests/e2e/visual-regression.spec.ts-snapshots/mobile-layout-mobile.png`
|
||||
|
||||
### File Organization
|
||||
|
||||
```
|
||||
tests/e2e/visual-regression.spec.ts-snapshots/
|
||||
├── homepage-full-chromium.png
|
||||
├── homepage-full-firefox.png
|
||||
├── homepage-full-webkit.png
|
||||
├── homepage-full-mobile.png
|
||||
├── hero-section-chromium.png
|
||||
├── hero-section-firefox.png
|
||||
├── hero-section-webkit.png
|
||||
├── hero-section-mobile.png
|
||||
└── ... (92 total screenshots)
|
||||
```
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### 1. "Snapshot doesn't exist" errors
|
||||
|
||||
**Cause**: Baseline snapshots haven't been generated or are missing
|
||||
|
||||
**Solution**:
|
||||
|
||||
```bash
|
||||
# Regenerate all snapshots
|
||||
npm run visual:update
|
||||
|
||||
# Or regenerate for specific project
|
||||
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium
|
||||
```
|
||||
|
||||
#### 2. Platform differences (macOS vs Linux)
|
||||
|
||||
**Cause**: Different font rendering between platforms
|
||||
|
||||
**Solution**:
|
||||
|
||||
- Use CI-generated snapshots for consistency
|
||||
- Ensure deterministic rendering settings
|
||||
- Check font availability across platforms
|
||||
|
||||
#### 3. Minor pixel differences
|
||||
|
||||
**Cause**: Font rendering, anti-aliasing, scaling differences
|
||||
|
||||
**Solution**:
|
||||
|
||||
- Check tolerance settings in `playwright.config.ts`
|
||||
- Use `scale: "css"` for consistent scaling
|
||||
- Ensure deterministic CSS properties
|
||||
|
||||
#### 4. Animation-related failures
|
||||
|
||||
**Cause**: Animations not fully disabled
|
||||
|
||||
**Solution**:
|
||||
|
||||
- Ensure `animations: "disabled"` is set in test configuration
|
||||
- Wait for animations to complete before screenshots
|
||||
- Use `waitForTimeout` if necessary
|
||||
|
||||
#### 5. Height differences (especially WebKit)
|
||||
|
||||
**Cause**: WebKit may render elements with slightly different heights
|
||||
|
||||
**Solution**:
|
||||
|
||||
- Increase tolerance for height-sensitive tests
|
||||
- Use `maxDiffPixels: 1000` for specific tests
|
||||
- Consider using `ignoreSize: false` (default)
|
||||
|
||||
### Debug Commands
|
||||
|
||||
```bash
|
||||
# Run with UI for visual debugging
|
||||
npm run visual:ui
|
||||
|
||||
# Run specific test with debugging
|
||||
npx playwright test tests/e2e/visual-regression.spec.ts --grep="homepage" --debug
|
||||
|
||||
# Run with headed browser
|
||||
npx playwright test tests/e2e/visual-regression.spec.ts --headed
|
||||
|
||||
# View test results
|
||||
npx playwright show-report
|
||||
```
|
||||
|
||||
### Environment Consistency
|
||||
|
||||
To ensure consistent results:
|
||||
|
||||
1. **Use same Node.js version** across environments
|
||||
2. **Use same Playwright version** across environments
|
||||
3. **Use same browser versions** when possible
|
||||
4. **Set consistent environment variables** (timezone, locale)
|
||||
5. **Use deterministic CSS** (avoid random values, timestamps)
|
||||
|
||||
## 📊 CI/CD Integration
|
||||
|
||||
### CI Workflow
|
||||
|
||||
Visual regression tests run automatically in the CI pipeline:
|
||||
|
||||
- **Main branch**: Tests run against existing snapshots
|
||||
- **Feature branches**: Tests run against existing snapshots
|
||||
- **Artifacts**: Test results and screenshots uploaded for review
|
||||
|
||||
### CI Best Practices
|
||||
|
||||
1. **Don't regenerate snapshots in CI** for feature branches
|
||||
2. **Use CI-generated snapshots** as the source of truth
|
||||
3. **Review screenshot diffs** in CI artifacts
|
||||
4. **Fail fast** on visual regressions
|
||||
|
||||
### Artifact Management
|
||||
|
||||
```yaml
|
||||
# Example CI artifact configuration
|
||||
- name: Upload visual regression results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: visual-regression-results
|
||||
path: |
|
||||
test-results/
|
||||
tests/e2e/visual-regression.spec.ts-snapshots/
|
||||
```
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
### 1. Snapshot Management
|
||||
|
||||
- **Update snapshots only for intentional changes**
|
||||
- **Review all changes** before committing
|
||||
- **Use descriptive names** for snapshot files
|
||||
- **Keep snapshots in version control**
|
||||
|
||||
### 2. Test Design
|
||||
|
||||
- **Test critical UI components** first
|
||||
- **Use consistent viewport sizes** across tests
|
||||
- **Test responsive breakpoints** systematically
|
||||
- **Include interactive states** when relevant
|
||||
|
||||
### 3. Performance
|
||||
|
||||
- **Limit snapshot count** to essential components
|
||||
- **Use appropriate timeouts** for slow operations
|
||||
- **Parallelize tests** when possible
|
||||
- **Cache browser installations** in CI
|
||||
|
||||
### 4. Maintenance
|
||||
|
||||
- **Regular cleanup** of outdated snapshots
|
||||
- **Update snapshots promptly** after UI changes
|
||||
- **Monitor test execution time** and optimize
|
||||
- **Review and update tolerance settings** as needed
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- **Main Testing Documentation**: [testing-framework.md](./testing-framework.md) | [testing.md](./testing.md)
|
||||
- **Playwright Visual Testing**: https://playwright.dev/docs/screenshots
|
||||
- **Visual Regression Best Practices**: https://storybook.js.org/docs/writing-tests/visual-testing
|
||||
- **CI/CD Integration**: [testing-quick-reference.md](./testing-quick-reference.md)
|
||||
- **Performance Guide**: [performance.md](./performance.md)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2024
|
||||
**Maintained by**: CommunityRule Development Team
|
||||
@@ -1,751 +0,0 @@
|
||||
<!doctype html>
|
||||
<!--suppress HtmlUnknownTarget -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script type="module" src="/vite-inject-mocker-entry.js"></script>
|
||||
<meta charset="utf-8" />
|
||||
<title>Storybook</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Nunito Sans";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("./sb-common-assets/nunito-sans-regular.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito Sans";
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("./sb-common-assets/nunito-sans-italic.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito Sans";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("./sb-common-assets/nunito-sans-bold.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito Sans";
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("./sb-common-assets/nunito-sans-bold-italic.woff2")
|
||||
format("woff2");
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
window.CONFIG_TYPE = "PRODUCTION";
|
||||
window.LOGLEVEL = "info";
|
||||
window.FRAMEWORK_OPTIONS = {};
|
||||
window.CHANNEL_OPTIONS = {};
|
||||
window.FEATURES = {
|
||||
argTypeTargetsV7: true,
|
||||
legacyDecoratorFileOrder: false,
|
||||
disallowImplicitActionsInRenderV8: true,
|
||||
viewport: true,
|
||||
highlight: true,
|
||||
controls: true,
|
||||
interactions: true,
|
||||
actions: true,
|
||||
backgrounds: true,
|
||||
outline: true,
|
||||
measure: true,
|
||||
};
|
||||
window.STORIES = [
|
||||
{
|
||||
titlePrefix: "",
|
||||
directory: "./stories",
|
||||
files: "**/*.mdx",
|
||||
importPathMatcher:
|
||||
"^\\.[\\\\/](?:stories(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.mdx)$",
|
||||
},
|
||||
{
|
||||
titlePrefix: "",
|
||||
directory: "./stories",
|
||||
files: "**/*.stories.@(js|jsx|mjs|ts|tsx)",
|
||||
importPathMatcher:
|
||||
"^\\.[\\\\/](?:stories(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|mjs|ts|tsx))$",
|
||||
},
|
||||
];
|
||||
window.DOCS_OPTIONS = { defaultName: "Docs" };
|
||||
window.TAGS_OPTIONS = {
|
||||
"dev-only": { excludeFromDocsStories: true },
|
||||
"docs-only": { excludeFromSidebar: true },
|
||||
"test-only": { excludeFromSidebar: true, excludeFromDocsStories: true },
|
||||
};
|
||||
|
||||
// We do this so that "module && module.hot" etc. in Storybook source code
|
||||
// doesn't fail (it will simply be disabled)
|
||||
window.module = undefined;
|
||||
window.global = window;
|
||||
</script>
|
||||
<base target="_parent" />
|
||||
|
||||
<style>
|
||||
/* While we aren't showing the main block yet, but still preparing, we want everything the user has rendered, which may or may not be in #storybook-root, to be display none */
|
||||
.sb-show-preparing-story:not(.sb-show-main) > :not(.sb-preparing-story) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sb-show-preparing-docs:not(.sb-show-main) > :not(.sb-preparing-docs) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide our own blocks when we aren't supposed to be showing them */
|
||||
:not(.sb-show-preparing-story) > .sb-preparing-story,
|
||||
:not(.sb-show-preparing-docs) > .sb-preparing-docs,
|
||||
:not(.sb-show-nopreview) > .sb-nopreview,
|
||||
:not(.sb-show-errordisplay) > .sb-errordisplay {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sb-show-main.sb-main-centered {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.sb-show-main.sb-main-centered #storybook-root {
|
||||
box-sizing: border-box;
|
||||
margin: auto;
|
||||
padding: 1rem;
|
||||
max-height: 100%;
|
||||
/* Hack for centering correctly in IE11 */
|
||||
}
|
||||
|
||||
/* Vertical centering fix for IE11 */
|
||||
@media screen and (-ms-high-contrast: none), (-ms-high-contrast: active) {
|
||||
.sb-show-main.sb-main-centered:after {
|
||||
content: "";
|
||||
min-height: inherit;
|
||||
font-size: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sb-show-main.sb-main-fullscreen {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sb-show-main.sb-main-padded {
|
||||
margin: 0;
|
||||
padding: 1rem;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.sb-wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
padding: 40px;
|
||||
font-family:
|
||||
"Nunito Sans",
|
||||
-apple-system,
|
||||
".SFNSText-Regular",
|
||||
"San Francisco",
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
"Helvetica Neue",
|
||||
Helvetica,
|
||||
Arial,
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.sb-wrapper {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.sb-wrapper {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.sb-heading {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.2px;
|
||||
margin: 10px 0;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.sb-nopreview {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.sb-nopreview_main {
|
||||
margin: auto;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
background: rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
.sb-nopreview_heading {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sb-errordisplay {
|
||||
background: #f6f9fc;
|
||||
color: black;
|
||||
z-index: 999999;
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
|
||||
& ol {
|
||||
padding-left: 18px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
& h1 {
|
||||
font-family: Nunito Sans;
|
||||
font-size: 22px;
|
||||
font-weight: 400;
|
||||
line-height: 30px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: #ff4400;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
& p,
|
||||
& ol {
|
||||
font-family: Nunito Sans;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 19px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
& li + li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
& a {
|
||||
color: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
.sb-errordisplay_main {
|
||||
margin: auto;
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
border: 1px solid #ff0000;
|
||||
box-shadow: 0 0 64px rgba(0, 0, 0, 0.1);
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.sb-errordisplay_code {
|
||||
padding: 10px;
|
||||
flex: 1;
|
||||
background: #242424;
|
||||
color: #c6c6c6;
|
||||
box-sizing: border-box;
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 19px;
|
||||
border-radius: 4px;
|
||||
|
||||
font-family:
|
||||
"Operator Mono", "Fira Code Retina", "Fira Code", "FiraCode-Retina",
|
||||
"Andale Mono", "Lucida Console", Consolas, Monaco, monospace;
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.sb-errordisplay pre {
|
||||
white-space: pre-wrap;
|
||||
white-space: revert;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sb-rotate360 {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sb-rotate360 {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes sb-glow {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sb-glow {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
/* We display the preparing loaders *over* the rendering story */
|
||||
.sb-preparing-story,
|
||||
.sb-preparing-docs {
|
||||
background-color: white;
|
||||
/* Maximum possible z-index. It would be better to use stacking contexts to ensure it's always
|
||||
on top, but this isn't possible as it would require making CSS changes that could affect user code */
|
||||
z-index: 2147483647;
|
||||
}
|
||||
|
||||
.sb-loader {
|
||||
-webkit-animation: sb-rotate360 0.7s linear infinite;
|
||||
animation: sb-rotate360 0.7s linear infinite;
|
||||
border-color: rgba(97, 97, 97, 0.29);
|
||||
border-radius: 50%;
|
||||
border-style: solid;
|
||||
border-top-color: #646464;
|
||||
border-width: 2px;
|
||||
display: inline-block;
|
||||
height: 32px;
|
||||
left: 50%;
|
||||
margin-left: -16px;
|
||||
margin-top: -16px;
|
||||
mix-blend-mode: difference;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transition: all 200ms ease-out;
|
||||
vertical-align: top;
|
||||
width: 32px;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.sb-previewBlock {
|
||||
background: #fff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 4px;
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 0 1px 3px 0;
|
||||
margin: 25px auto 40px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.sb-previewBlock_header {
|
||||
align-items: center;
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 0 -1px 0 0 inset;
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
height: 40px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.sb-previewBlock_icon {
|
||||
-webkit-animation: sb-glow 1.5s ease-in-out infinite;
|
||||
animation: sb-glow 1.5s ease-in-out infinite;
|
||||
background: #e6e6e6;
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.sb-previewBlock_icon:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.sb-previewBlock_body {
|
||||
-webkit-animation: sb-glow 1.5s ease-in-out infinite;
|
||||
animation: sb-glow 1.5s ease-in-out infinite;
|
||||
height: 182px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sb-argstableBlock {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
margin: 25px auto 40px;
|
||||
max-width: 600px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sb-argstableBlock th:first-of-type,
|
||||
.sb-argstableBlock td:first-of-type {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock th:nth-of-type(2),
|
||||
.sb-argstableBlock td:nth-of-type(2) {
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
.sb-argstableBlock th:nth-of-type(3),
|
||||
.sb-argstableBlock td:nth-of-type(3) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
.sb-argstableBlock th:last-of-type,
|
||||
.sb-argstableBlock td:last-of-type {
|
||||
width: 25%;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock th span,
|
||||
.sb-argstableBlock td span {
|
||||
-webkit-animation: sb-glow 1.5s ease-in-out infinite;
|
||||
animation: sb-glow 1.5s ease-in-out infinite;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.sb-argstableBlock th {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body {
|
||||
border-radius: 4px;
|
||||
box-shadow:
|
||||
rgba(0, 0, 0, 0.1) 0 1px 3px 1px,
|
||||
rgba(0, 0, 0, 0.065) 0 0 0 1px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body tr {
|
||||
background: transparent;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body tr:not(:first-child) {
|
||||
border-top: 1px solid #e6e6e6;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body tr:first-child td:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body tr:first-child td:last-child {
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body tr:last-child td:first-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body tr:last-child td:last-child {
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body td {
|
||||
background: #fff;
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body td:not(:first-of-type) {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-body button {
|
||||
-webkit-animation: sb-glow 1.5s ease-in-out infinite;
|
||||
animation: sb-glow 1.5s ease-in-out infinite;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
color: transparent;
|
||||
display: inline;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
padding: 10px 16px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-summary {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.sb-argstableBlock-code {
|
||||
margin-right: 4px;
|
||||
margin-bottom: 4px;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
.sb-sr-only,
|
||||
.sb-hidden-until-focus:not(:focus) {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.sb-hidden-until-focus {
|
||||
opacity: 0;
|
||||
transition: opacity 150ms ease-out;
|
||||
}
|
||||
|
||||
.sb-hidden-until-focus:focus {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
/* globals window */
|
||||
try {
|
||||
if (window.top !== window) {
|
||||
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ =
|
||||
window.top.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
window.__VUE_DEVTOOLS_GLOBAL_HOOK__ =
|
||||
window.top.__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
||||
window.top.__VUE_DEVTOOLS_CONTEXT__ = window.document;
|
||||
}
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("unable to connect to top frame for connecting dev tools");
|
||||
}
|
||||
</script>
|
||||
|
||||
<script
|
||||
type="module"
|
||||
crossorigin
|
||||
src="/CommunityRuleStorybook/assets/iframe-D_aMTKb2.js"
|
||||
></script>
|
||||
<link
|
||||
rel="modulepreload"
|
||||
crossorigin
|
||||
href="/CommunityRuleStorybook/assets/preload-helper-DIZFD4sK.js"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
crossorigin
|
||||
href="/CommunityRuleStorybook/assets/iframe-7VPDhVZ9.css"
|
||||
/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="sb-preparing-story sb-wrapper">
|
||||
<div class="sb-loader"></div>
|
||||
</div>
|
||||
|
||||
<div class="sb-preparing-docs sb-wrapper">
|
||||
<div class="sb-previewBlock">
|
||||
<div class="sb-previewBlock_header">
|
||||
<div class="sb-previewBlock_icon"></div>
|
||||
<div class="sb-previewBlock_icon"></div>
|
||||
<div class="sb-previewBlock_icon"></div>
|
||||
<div class="sb-previewBlock_icon"></div>
|
||||
</div>
|
||||
<div class="sb-previewBlock_body">
|
||||
<div class="sb-loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
<table aria-hidden="true" class="sb-argstableBlock">
|
||||
<thead class="sb-argstableBlock-head">
|
||||
<tr>
|
||||
<th><span>Name</span></th>
|
||||
<th><span>Description</span></th>
|
||||
<th><span>Default</span></th>
|
||||
<th><span>Control </span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="sb-argstableBlock-body">
|
||||
<tr>
|
||||
<td><span>propertyName</span><span title="Required">*</span></td>
|
||||
<td>
|
||||
<div><span>This is a short description</span></div>
|
||||
<div class="sb-argstableBlock-summary">
|
||||
<div><span class="sb-argstableBlock-code">summary</span></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<span class="sb-argstableBlock-code">defaultValue</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><button>Set string</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span>propertyName</span><span>*</span></td>
|
||||
<td>
|
||||
<div><span>This is a short description</span></div>
|
||||
<div class="sb-argstableBlock-summary">
|
||||
<div><span class="sb-argstableBlock-code">summary</span></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<span class="sb-argstableBlock-code">defaultValue</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><button>Set string</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span>propertyName</span><span>*</span></td>
|
||||
<td>
|
||||
<div><span>This is a short description</span></div>
|
||||
<div class="sb-argstableBlock-summary">
|
||||
<div><span class="sb-argstableBlock-code">summary</span></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<span class="sb-argstableBlock-code">defaultValue</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><button>Set string</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="sb-nopreview sb-wrapper">
|
||||
<div class="sb-nopreview_main">
|
||||
<h1 class="sb-nopreview_heading sb-heading">No Preview</h1>
|
||||
<p>
|
||||
Sorry, but you either have no stories or none are selected somehow.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Please check the Storybook config.</li>
|
||||
<li>Try reloading the page.</li>
|
||||
</ul>
|
||||
<p>
|
||||
If the problem persists, check the browser console, or the terminal
|
||||
you've run Storybook from.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-errordisplay sb-wrapper">
|
||||
<div class="sb-errordisplay_main">
|
||||
<h1 id="error-message"></h1>
|
||||
<p>
|
||||
The component failed to render properly, likely due to a configuration
|
||||
issue in Storybook. Here are some common causes and how you can
|
||||
address them:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
<strong>Missing Context/Providers</strong>: You can use decorators
|
||||
to supply specific contexts or providers, which are sometimes
|
||||
necessary for components to render correctly. For detailed
|
||||
instructions on using decorators, please visit the
|
||||
<a href="https://storybook.js.org/docs/writing-stories/decorators"
|
||||
>Decorators documentation</a
|
||||
>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Misconfigured Webpack or Vite</strong>: Verify that
|
||||
Storybook picks up all necessary settings for loaders, plugins, and
|
||||
other relevant parameters. You can find step-by-step guides for
|
||||
configuring
|
||||
<a href="https://storybook.js.org/docs/builders/webpack">Webpack</a>
|
||||
or
|
||||
<a href="https://storybook.js.org/docs/builders/vite">Vite</a>
|
||||
with Storybook.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Missing Environment Variables</strong>: Your Storybook may
|
||||
require specific environment variables to function as intended. You
|
||||
can set up custom environment variables as outlined in the
|
||||
<a
|
||||
href="https://storybook.js.org/docs/configure/environment-variables"
|
||||
>Environment Variables documentation</a
|
||||
>.
|
||||
</li>
|
||||
</ol>
|
||||
<pre class="sb-errordisplay_code"><code id="error-stack"></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="storybook-root"></div>
|
||||
<div id="storybook-docs"></div>
|
||||
<script>
|
||||
function __onViteAppLoadingError(event) {
|
||||
const hostname = globalThis.location.hostname;
|
||||
if (
|
||||
hostname !== "localhost" &&
|
||||
globalThis.CONFIG_TYPE === "DEVELOPMENT"
|
||||
) {
|
||||
const message = `Failed to load the Storybook preview file 'vite-app.js':
|
||||
|
||||
It looks like you're visiting the Storybook development server on another hostname than localhost: '${hostname}', but you haven't configured the necessary security features to support this.
|
||||
Please re-run your Storybook development server with the '--host ${hostname}' flag, or manually configure your Vite allowedHosts configuration with viteFinal.
|
||||
|
||||
See:`;
|
||||
const docs = [
|
||||
"https://storybook.js.org/docs/api/cli-options#dev",
|
||||
"https://storybook.js.org/docs/api/main-config/main-config-vite-final",
|
||||
"https://vite.dev/config/server-options.html#server-allowedhosts",
|
||||
];
|
||||
console.error(
|
||||
`${message}\n${docs.map((doc) => `- ${doc}`).join("\n")}`,
|
||||
);
|
||||
|
||||
document.getElementById("storybook-root").innerHTML =
|
||||
`<p style="color: red; max-width: 70ch">${message.replaceAll(
|
||||
"\n",
|
||||
"<br/>",
|
||||
)}<ul>${docs.map((doc) => `<li><a href='${doc}' target='_blank'>${doc}</a></li>`).join("")}<ul></p>`;
|
||||
return;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,141 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<title>storybook - Storybook</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="./favicon.svg" />
|
||||
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Nunito Sans";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("./sb-common-assets/nunito-sans-regular.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito Sans";
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("./sb-common-assets/nunito-sans-italic.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito Sans";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("./sb-common-assets/nunito-sans-bold.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito Sans";
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("./sb-common-assets/nunito-sans-bold-italic.woff2")
|
||||
format("woff2");
|
||||
}
|
||||
</style>
|
||||
|
||||
<link href="./sb-manager/runtime.js" rel="modulepreload" />
|
||||
|
||||
<link
|
||||
href="./sb-addons/storybook-core-server-presets-0/common-manager-bundle.js"
|
||||
rel="modulepreload"
|
||||
/>
|
||||
|
||||
<link
|
||||
href="./sb-addons/chromatic-com-storybook-1/manager-bundle.js"
|
||||
rel="modulepreload"
|
||||
/>
|
||||
|
||||
<link href="./sb-addons/docs-2/manager-bundle.js" rel="modulepreload" />
|
||||
|
||||
<link
|
||||
href="./sb-addons/onboarding-3/manager-bundle.js"
|
||||
rel="modulepreload"
|
||||
/>
|
||||
|
||||
<link href="./sb-addons/a11y-4/manager-bundle.js" rel="modulepreload" />
|
||||
|
||||
<link href="./sb-addons/vitest-5/manager-bundle.js" rel="modulepreload" />
|
||||
|
||||
<style>
|
||||
#storybook-root[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<script>
|
||||
window["FEATURES"] = {
|
||||
argTypeTargetsV7: true,
|
||||
legacyDecoratorFileOrder: false,
|
||||
disallowImplicitActionsInRenderV8: true,
|
||||
viewport: true,
|
||||
highlight: true,
|
||||
controls: true,
|
||||
interactions: true,
|
||||
actions: true,
|
||||
backgrounds: true,
|
||||
outline: true,
|
||||
measure: true,
|
||||
};
|
||||
|
||||
window["REFS"] = {};
|
||||
|
||||
window["LOGLEVEL"] = "info";
|
||||
|
||||
window["DOCS_OPTIONS"] = {
|
||||
defaultName: "Docs",
|
||||
};
|
||||
|
||||
window["CONFIG_TYPE"] = "PRODUCTION";
|
||||
|
||||
window["TAGS_OPTIONS"] = {
|
||||
"dev-only": {
|
||||
excludeFromDocsStories: true,
|
||||
},
|
||||
"docs-only": {
|
||||
excludeFromSidebar: true,
|
||||
},
|
||||
"test-only": {
|
||||
excludeFromSidebar: true,
|
||||
excludeFromDocsStories: true,
|
||||
},
|
||||
};
|
||||
|
||||
window["STORYBOOK_RENDERER"] = "react";
|
||||
|
||||
window["STORYBOOK_BUILDER"] = "@storybook/builder-vite";
|
||||
|
||||
window["STORYBOOK_FRAMEWORK"] = "@storybook/nextjs-vite";
|
||||
</script>
|
||||
|
||||
<script type="module">
|
||||
import "./sb-manager/globals-runtime.js";
|
||||
|
||||
import "./sb-addons/storybook-core-server-presets-0/common-manager-bundle.js";
|
||||
|
||||
import "./sb-addons/chromatic-com-storybook-1/manager-bundle.js";
|
||||
|
||||
import "./sb-addons/docs-2/manager-bundle.js";
|
||||
|
||||
import "./sb-addons/onboarding-3/manager-bundle.js";
|
||||
|
||||
import "./sb-addons/a11y-4/manager-bundle.js";
|
||||
|
||||
import "./sb-addons/vitest-5/manager-bundle.js";
|
||||
|
||||
import "./sb-manager/runtime.js";
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,694 +0,0 @@
|
||||
{
|
||||
"v": 5,
|
||||
"entries": {
|
||||
"components-avatar--docs": {
|
||||
"id": "components-avatar--docs",
|
||||
"title": "Components/Avatar",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/Avatar.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-avatar--default": {
|
||||
"type": "story",
|
||||
"id": "components-avatar--default",
|
||||
"name": "Default",
|
||||
"title": "Components/Avatar",
|
||||
"importPath": "./stories/Avatar.stories.js",
|
||||
"componentPath": "./app/components/Avatar.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-avatar--sizes": {
|
||||
"type": "story",
|
||||
"id": "components-avatar--sizes",
|
||||
"name": "Sizes",
|
||||
"title": "Components/Avatar",
|
||||
"importPath": "./stories/Avatar.stories.js",
|
||||
"componentPath": "./app/components/Avatar.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-avatar--different-avatars": {
|
||||
"type": "story",
|
||||
"id": "components-avatar--different-avatars",
|
||||
"name": "Different Avatars",
|
||||
"title": "Components/Avatar",
|
||||
"importPath": "./stories/Avatar.stories.js",
|
||||
"componentPath": "./app/components/Avatar.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-avatar--all-sizes-with-different-avatars": {
|
||||
"type": "story",
|
||||
"id": "components-avatar--all-sizes-with-different-avatars",
|
||||
"name": "All Sizes With Different Avatars",
|
||||
"title": "Components/Avatar",
|
||||
"importPath": "./stories/Avatar.stories.js",
|
||||
"componentPath": "./app/components/Avatar.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-avatarcontainer--docs": {
|
||||
"id": "components-avatarcontainer--docs",
|
||||
"title": "Components/AvatarContainer",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/AvatarContainer.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-avatarcontainer--default": {
|
||||
"type": "story",
|
||||
"id": "components-avatarcontainer--default",
|
||||
"name": "Default",
|
||||
"title": "Components/AvatarContainer",
|
||||
"importPath": "./stories/AvatarContainer.stories.js",
|
||||
"componentPath": "./app/components/AvatarContainer.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-avatarcontainer--sizes": {
|
||||
"type": "story",
|
||||
"id": "components-avatarcontainer--sizes",
|
||||
"name": "Sizes",
|
||||
"title": "Components/AvatarContainer",
|
||||
"importPath": "./stories/AvatarContainer.stories.js",
|
||||
"componentPath": "./app/components/AvatarContainer.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-avatarcontainer--different-group-sizes": {
|
||||
"type": "story",
|
||||
"id": "components-avatarcontainer--different-group-sizes",
|
||||
"name": "Different Group Sizes",
|
||||
"title": "Components/AvatarContainer",
|
||||
"importPath": "./stories/AvatarContainer.stories.js",
|
||||
"componentPath": "./app/components/AvatarContainer.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-avatarcontainer--in-context": {
|
||||
"type": "story",
|
||||
"id": "components-avatarcontainer--in-context",
|
||||
"name": "In Context",
|
||||
"title": "Components/AvatarContainer",
|
||||
"importPath": "./stories/AvatarContainer.stories.js",
|
||||
"componentPath": "./app/components/AvatarContainer.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-button--docs": {
|
||||
"id": "components-button--docs",
|
||||
"title": "Components/Button",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/Button.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-button--default": {
|
||||
"type": "story",
|
||||
"id": "components-button--default",
|
||||
"name": "Default",
|
||||
"title": "Components/Button",
|
||||
"importPath": "./stories/Button.stories.js",
|
||||
"componentPath": "./app/components/Button.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-button--variants": {
|
||||
"type": "story",
|
||||
"id": "components-button--variants",
|
||||
"name": "Variants",
|
||||
"title": "Components/Button",
|
||||
"importPath": "./stories/Button.stories.js",
|
||||
"componentPath": "./app/components/Button.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-button--sizes": {
|
||||
"type": "story",
|
||||
"id": "components-button--sizes",
|
||||
"name": "Sizes",
|
||||
"title": "Components/Button",
|
||||
"importPath": "./stories/Button.stories.js",
|
||||
"componentPath": "./app/components/Button.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-button--states": {
|
||||
"type": "story",
|
||||
"id": "components-button--states",
|
||||
"name": "States",
|
||||
"title": "Components/Button",
|
||||
"importPath": "./stories/Button.stories.js",
|
||||
"componentPath": "./app/components/Button.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-button--all-variants": {
|
||||
"type": "story",
|
||||
"id": "components-button--all-variants",
|
||||
"name": "All Variants",
|
||||
"title": "Components/Button",
|
||||
"importPath": "./stories/Button.stories.js",
|
||||
"componentPath": "./app/components/Button.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-contentlockup--docs": {
|
||||
"id": "components-contentlockup--docs",
|
||||
"title": "Components/ContentLockup",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/ContentLockup.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-contentlockup--default": {
|
||||
"type": "story",
|
||||
"id": "components-contentlockup--default",
|
||||
"name": "Default",
|
||||
"title": "Components/ContentLockup",
|
||||
"importPath": "./stories/ContentLockup.stories.js",
|
||||
"componentPath": "./app/components/ContentLockup.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-contentlockup--long-description": {
|
||||
"type": "story",
|
||||
"id": "components-contentlockup--long-description",
|
||||
"name": "Long Description",
|
||||
"title": "Components/ContentLockup",
|
||||
"importPath": "./stories/ContentLockup.stories.js",
|
||||
"componentPath": "./app/components/ContentLockup.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-contentlockup--short-content": {
|
||||
"type": "story",
|
||||
"id": "components-contentlockup--short-content",
|
||||
"name": "Short Content",
|
||||
"title": "Components/ContentLockup",
|
||||
"importPath": "./stories/ContentLockup.stories.js",
|
||||
"componentPath": "./app/components/ContentLockup.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-contentlockup--custom-button-styling": {
|
||||
"type": "story",
|
||||
"id": "components-contentlockup--custom-button-styling",
|
||||
"name": "Custom Button Styling",
|
||||
"title": "Components/ContentLockup",
|
||||
"importPath": "./stories/ContentLockup.stories.js",
|
||||
"componentPath": "./app/components/ContentLockup.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-footer--docs": {
|
||||
"id": "components-footer--docs",
|
||||
"title": "Components/Footer",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/Footer.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-footer--default": {
|
||||
"type": "story",
|
||||
"id": "components-footer--default",
|
||||
"name": "Default",
|
||||
"title": "Components/Footer",
|
||||
"importPath": "./stories/Footer.stories.js",
|
||||
"componentPath": "./app/components/Footer.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-footer--in-page-context": {
|
||||
"type": "story",
|
||||
"id": "components-footer--in-page-context",
|
||||
"name": "In Page Context",
|
||||
"title": "Components/Footer",
|
||||
"importPath": "./stories/Footer.stories.js",
|
||||
"componentPath": "./app/components/Footer.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-header--docs": {
|
||||
"id": "components-header--docs",
|
||||
"title": "Components/Header",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/Header.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-header--default": {
|
||||
"type": "story",
|
||||
"id": "components-header--default",
|
||||
"name": "Default",
|
||||
"title": "Components/Header",
|
||||
"importPath": "./stories/Header.stories.js",
|
||||
"componentPath": "./app/components/Header.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-header--in-page-context": {
|
||||
"type": "story",
|
||||
"id": "components-header--in-page-context",
|
||||
"name": "In Page Context",
|
||||
"title": "Components/Header",
|
||||
"importPath": "./stories/Header.stories.js",
|
||||
"componentPath": "./app/components/Header.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-headertab--docs": {
|
||||
"id": "components-headertab--docs",
|
||||
"title": "Components/HeaderTab",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/HeaderTab.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-headertab--default": {
|
||||
"type": "story",
|
||||
"id": "components-headertab--default",
|
||||
"name": "Default",
|
||||
"title": "Components/HeaderTab",
|
||||
"importPath": "./stories/HeaderTab.stories.js",
|
||||
"componentPath": "./app/components/HeaderTab.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-herobanner--docs": {
|
||||
"id": "components-herobanner--docs",
|
||||
"title": "Components/HeroBanner",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/HeroBanner.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-herobanner--default": {
|
||||
"type": "story",
|
||||
"id": "components-herobanner--default",
|
||||
"name": "Default",
|
||||
"title": "Components/HeroBanner",
|
||||
"importPath": "./stories/HeroBanner.stories.js",
|
||||
"componentPath": "./app/components/HeroBanner.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"systems-herobanner-system--docs": {
|
||||
"id": "systems-herobanner-system--docs",
|
||||
"title": "Systems/HeroBanner System",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/HeroBannerSystem.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"systems-herobanner-system--complete-system": {
|
||||
"type": "story",
|
||||
"id": "systems-herobanner-system--complete-system",
|
||||
"name": "Complete System",
|
||||
"title": "Systems/HeroBanner System",
|
||||
"importPath": "./stories/HeroBannerSystem.stories.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"systems-herobanner-system--component-breakdown": {
|
||||
"type": "story",
|
||||
"id": "systems-herobanner-system--component-breakdown",
|
||||
"name": "Component Breakdown",
|
||||
"title": "Systems/HeroBanner System",
|
||||
"importPath": "./stories/HeroBannerSystem.stories.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"systems-herobanner-system--responsive-breakpoints": {
|
||||
"type": "story",
|
||||
"id": "systems-herobanner-system--responsive-breakpoints",
|
||||
"name": "Responsive Breakpoints",
|
||||
"title": "Systems/HeroBanner System",
|
||||
"importPath": "./stories/HeroBannerSystem.stories.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"systems-herobanner-system--content-variations": {
|
||||
"type": "story",
|
||||
"id": "systems-herobanner-system--content-variations",
|
||||
"name": "Content Variations",
|
||||
"title": "Systems/HeroBanner System",
|
||||
"importPath": "./stories/HeroBannerSystem.stories.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-herodecor--docs": {
|
||||
"id": "components-herodecor--docs",
|
||||
"title": "Components/HeroDecor",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/HeroDecor.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-herodecor--default": {
|
||||
"type": "story",
|
||||
"id": "components-herodecor--default",
|
||||
"name": "Default",
|
||||
"title": "Components/HeroDecor",
|
||||
"importPath": "./stories/HeroDecor.stories.js",
|
||||
"componentPath": "./app/components/HeroDecor.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-herodecor--with-background": {
|
||||
"type": "story",
|
||||
"id": "components-herodecor--with-background",
|
||||
"name": "With Background",
|
||||
"title": "Components/HeroDecor",
|
||||
"importPath": "./stories/HeroDecor.stories.js",
|
||||
"componentPath": "./app/components/HeroDecor.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-homeheader--docs": {
|
||||
"id": "components-homeheader--docs",
|
||||
"title": "Components/HomeHeader",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/HomeHeader.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-homeheader--default": {
|
||||
"type": "story",
|
||||
"id": "components-homeheader--default",
|
||||
"name": "Default",
|
||||
"title": "Components/HomeHeader",
|
||||
"importPath": "./stories/HomeHeader.stories.js",
|
||||
"componentPath": "./app/components/HomeHeader.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-homeheader--in-home-page-context": {
|
||||
"type": "story",
|
||||
"id": "components-homeheader--in-home-page-context",
|
||||
"name": "In Home Page Context",
|
||||
"title": "Components/HomeHeader",
|
||||
"importPath": "./stories/HomeHeader.stories.js",
|
||||
"componentPath": "./app/components/HomeHeader.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-logo--docs": {
|
||||
"id": "components-logo--docs",
|
||||
"title": "Components/Logo",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/Logo.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-logo--default": {
|
||||
"type": "story",
|
||||
"id": "components-logo--default",
|
||||
"name": "Default",
|
||||
"title": "Components/Logo",
|
||||
"importPath": "./stories/Logo.stories.js",
|
||||
"componentPath": "./app/components/Logo.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-logo--sizes": {
|
||||
"type": "story",
|
||||
"id": "components-logo--sizes",
|
||||
"name": "Sizes",
|
||||
"title": "Components/Logo",
|
||||
"importPath": "./stories/Logo.stories.js",
|
||||
"componentPath": "./app/components/Logo.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-logo--icon-only": {
|
||||
"type": "story",
|
||||
"id": "components-logo--icon-only",
|
||||
"name": "Icon Only",
|
||||
"title": "Components/Logo",
|
||||
"importPath": "./stories/Logo.stories.js",
|
||||
"componentPath": "./app/components/Logo.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-logo--home-header-context": {
|
||||
"type": "story",
|
||||
"id": "components-logo--home-header-context",
|
||||
"name": "Home Header Context",
|
||||
"title": "Components/Logo",
|
||||
"importPath": "./stories/Logo.stories.js",
|
||||
"componentPath": "./app/components/Logo.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-logo--header-context": {
|
||||
"type": "story",
|
||||
"id": "components-logo--header-context",
|
||||
"name": "Header Context",
|
||||
"title": "Components/Logo",
|
||||
"importPath": "./stories/Logo.stories.js",
|
||||
"componentPath": "./app/components/Logo.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-logo--footer-context": {
|
||||
"type": "story",
|
||||
"id": "components-logo--footer-context",
|
||||
"name": "Footer Context",
|
||||
"title": "Components/Logo",
|
||||
"importPath": "./stories/Logo.stories.js",
|
||||
"componentPath": "./app/components/Logo.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-menubar--docs": {
|
||||
"id": "components-menubar--docs",
|
||||
"title": "Components/MenuBar",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/MenuBar.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-menubar--default": {
|
||||
"type": "story",
|
||||
"id": "components-menubar--default",
|
||||
"name": "Default",
|
||||
"title": "Components/MenuBar",
|
||||
"importPath": "./stories/MenuBar.stories.js",
|
||||
"componentPath": "./app/components/MenuBar.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-menubar--sizes": {
|
||||
"type": "story",
|
||||
"id": "components-menubar--sizes",
|
||||
"name": "Sizes",
|
||||
"title": "Components/MenuBar",
|
||||
"importPath": "./stories/MenuBar.stories.js",
|
||||
"componentPath": "./app/components/MenuBar.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-menubaritem--docs": {
|
||||
"id": "components-menubaritem--docs",
|
||||
"title": "Components/MenuBarItem",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/MenuBarItem.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-menubaritem--default": {
|
||||
"type": "story",
|
||||
"id": "components-menubaritem--default",
|
||||
"name": "Default",
|
||||
"title": "Components/MenuBarItem",
|
||||
"importPath": "./stories/MenuBarItem.stories.js",
|
||||
"componentPath": "./app/components/MenuBarItem.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-menubaritem--variants": {
|
||||
"type": "story",
|
||||
"id": "components-menubaritem--variants",
|
||||
"name": "Variants",
|
||||
"title": "Components/MenuBarItem",
|
||||
"importPath": "./stories/MenuBarItem.stories.js",
|
||||
"componentPath": "./app/components/MenuBarItem.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-menubaritem--sizes": {
|
||||
"type": "story",
|
||||
"id": "components-menubaritem--sizes",
|
||||
"name": "Sizes",
|
||||
"title": "Components/MenuBarItem",
|
||||
"importPath": "./stories/MenuBarItem.stories.js",
|
||||
"componentPath": "./app/components/MenuBarItem.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-menubaritem--states": {
|
||||
"type": "story",
|
||||
"id": "components-menubaritem--states",
|
||||
"name": "States",
|
||||
"title": "Components/MenuBarItem",
|
||||
"importPath": "./stories/MenuBarItem.stories.js",
|
||||
"componentPath": "./app/components/MenuBarItem.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-menubaritem--all-variants": {
|
||||
"type": "story",
|
||||
"id": "components-menubaritem--all-variants",
|
||||
"name": "All Variants",
|
||||
"title": "Components/MenuBarItem",
|
||||
"importPath": "./stories/MenuBarItem.stories.js",
|
||||
"componentPath": "./app/components/MenuBarItem.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-numberedcard--docs": {
|
||||
"id": "components-numberedcard--docs",
|
||||
"title": "Components/NumberedCard",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/NumberedCard.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-numberedcard--default": {
|
||||
"type": "story",
|
||||
"id": "components-numberedcard--default",
|
||||
"name": "Default",
|
||||
"title": "Components/NumberedCard",
|
||||
"importPath": "./stories/NumberedCard.stories.js",
|
||||
"componentPath": "./app/components/NumberedCard.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-numberedcard--all-numbers": {
|
||||
"type": "story",
|
||||
"id": "components-numberedcard--all-numbers",
|
||||
"name": "All Numbers",
|
||||
"title": "Components/NumberedCard",
|
||||
"importPath": "./stories/NumberedCard.stories.js",
|
||||
"componentPath": "./app/components/NumberedCard.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-numberedcard--long-text": {
|
||||
"type": "story",
|
||||
"id": "components-numberedcard--long-text",
|
||||
"name": "Long Text",
|
||||
"title": "Components/NumberedCard",
|
||||
"importPath": "./stories/NumberedCard.stories.js",
|
||||
"componentPath": "./app/components/NumberedCard.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-numberedcards--docs": {
|
||||
"id": "components-numberedcards--docs",
|
||||
"title": "Components/NumberedCards",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/NumberedCards.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-numberedcards--default": {
|
||||
"type": "story",
|
||||
"id": "components-numberedcards--default",
|
||||
"name": "Default",
|
||||
"title": "Components/NumberedCards",
|
||||
"importPath": "./stories/NumberedCards.stories.js",
|
||||
"componentPath": "./app/components/NumberedCards.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-numberedcards--custom-content": {
|
||||
"type": "story",
|
||||
"id": "components-numberedcards--custom-content",
|
||||
"name": "Custom Content",
|
||||
"title": "Components/NumberedCards",
|
||||
"importPath": "./stories/NumberedCards.stories.js",
|
||||
"componentPath": "./app/components/NumberedCards.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionheader--docs": {
|
||||
"id": "components-sectionheader--docs",
|
||||
"title": "Components/SectionHeader",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/SectionHeader.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-sectionheader--default": {
|
||||
"type": "story",
|
||||
"id": "components-sectionheader--default",
|
||||
"name": "Default",
|
||||
"title": "Components/SectionHeader",
|
||||
"importPath": "./stories/SectionHeader.stories.js",
|
||||
"componentPath": "./app/components/SectionHeader.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionheader--custom-content": {
|
||||
"type": "story",
|
||||
"id": "components-sectionheader--custom-content",
|
||||
"name": "Custom Content",
|
||||
"title": "Components/SectionHeader",
|
||||
"importPath": "./stories/SectionHeader.stories.js",
|
||||
"componentPath": "./app/components/SectionHeader.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionheader--long-subtitle": {
|
||||
"type": "story",
|
||||
"id": "components-sectionheader--long-subtitle",
|
||||
"name": "Long Subtitle",
|
||||
"title": "Components/SectionHeader",
|
||||
"importPath": "./stories/SectionHeader.stories.js",
|
||||
"componentPath": "./app/components/SectionHeader.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionheader--responsive-test": {
|
||||
"type": "story",
|
||||
"id": "components-sectionheader--responsive-test",
|
||||
"name": "Responsive Test",
|
||||
"title": "Components/SectionHeader",
|
||||
"importPath": "./stories/SectionHeader.stories.js",
|
||||
"componentPath": "./app/components/SectionHeader.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionheader--without-title-lg": {
|
||||
"type": "story",
|
||||
"id": "components-sectionheader--without-title-lg",
|
||||
"name": "Without Title Lg",
|
||||
"title": "Components/SectionHeader",
|
||||
"importPath": "./stories/SectionHeader.stories.js",
|
||||
"componentPath": "./app/components/SectionHeader.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionnumber--docs": {
|
||||
"id": "components-sectionnumber--docs",
|
||||
"title": "Components/SectionNumber",
|
||||
"name": "Docs",
|
||||
"importPath": "./stories/SectionNumber.stories.js",
|
||||
"type": "docs",
|
||||
"tags": ["dev", "test", "autodocs"],
|
||||
"storiesImports": []
|
||||
},
|
||||
"components-sectionnumber--number-one": {
|
||||
"type": "story",
|
||||
"id": "components-sectionnumber--number-one",
|
||||
"name": "Number One",
|
||||
"title": "Components/SectionNumber",
|
||||
"importPath": "./stories/SectionNumber.stories.js",
|
||||
"componentPath": "./app/components/SectionNumber.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionnumber--number-two": {
|
||||
"type": "story",
|
||||
"id": "components-sectionnumber--number-two",
|
||||
"name": "Number Two",
|
||||
"title": "Components/SectionNumber",
|
||||
"importPath": "./stories/SectionNumber.stories.js",
|
||||
"componentPath": "./app/components/SectionNumber.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionnumber--number-three": {
|
||||
"type": "story",
|
||||
"id": "components-sectionnumber--number-three",
|
||||
"name": "Number Three",
|
||||
"title": "Components/SectionNumber",
|
||||
"importPath": "./stories/SectionNumber.stories.js",
|
||||
"componentPath": "./app/components/SectionNumber.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionnumber--all-numbers": {
|
||||
"type": "story",
|
||||
"id": "components-sectionnumber--all-numbers",
|
||||
"name": "All Numbers",
|
||||
"title": "Components/SectionNumber",
|
||||
"importPath": "./stories/SectionNumber.stories.js",
|
||||
"componentPath": "./app/components/SectionNumber.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
},
|
||||
"components-sectionnumber--with-background": {
|
||||
"type": "story",
|
||||
"id": "components-sectionnumber--with-background",
|
||||
"name": "With Background",
|
||||
"title": "Components/SectionNumber",
|
||||
"importPath": "./stories/SectionNumber.stories.js",
|
||||
"componentPath": "./app/components/SectionNumber.js",
|
||||
"tags": ["dev", "test", "autodocs"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"generatedAt": 1755714532484,
|
||||
"userSince": 1754920905774,
|
||||
"hasCustomBabel": false,
|
||||
"hasCustomWebpack": false,
|
||||
"hasStaticDirs": true,
|
||||
"hasStorybookEslint": true,
|
||||
"refCount": 0,
|
||||
"metaFramework": {
|
||||
"name": "Next",
|
||||
"packageName": "next",
|
||||
"version": "15.2.4"
|
||||
},
|
||||
"testPackages": {
|
||||
"@chromatic-com/storybook": "4.1.0",
|
||||
"@storybook/addon-vitest": "9.1.2",
|
||||
"@vitest/browser": "3.2.4",
|
||||
"@vitest/coverage-v8": "3.2.4",
|
||||
"playwright": "1.54.2",
|
||||
"vitest": "3.2.4"
|
||||
},
|
||||
"hasRouterPackage": true,
|
||||
"packageManager": {
|
||||
"type": "npm",
|
||||
"agent": "npm",
|
||||
"nodeLinker": "node_modules"
|
||||
},
|
||||
"preview": { "usesGlobals": false },
|
||||
"framework": { "name": "@storybook/nextjs-vite", "options": {} },
|
||||
"builder": "@storybook/builder-vite",
|
||||
"renderer": "@storybook/react",
|
||||
"portableStoriesFileCount": 0,
|
||||
"applicationFileCount": 1,
|
||||
"storybookVersion": "9.1.2",
|
||||
"language": "javascript",
|
||||
"storybookPackages": {
|
||||
"@storybook/addon-styling-webpack": { "version": "2.0.0" },
|
||||
"@storybook/addon-viewport": { "version": "9.0.8" },
|
||||
"@storybook/nextjs-vite": { "version": "9.1.2" },
|
||||
"eslint-plugin-storybook": { "version": "9.1.2" },
|
||||
"storybook": { "version": "9.1.2" }
|
||||
},
|
||||
"addons": {
|
||||
"@chromatic-com/storybook": { "version": "4.1.0" },
|
||||
"@storybook/addon-docs": { "version": "9.1.2" },
|
||||
"@storybook/addon-onboarding": { "version": "9.1.2" },
|
||||
"@storybook/addon-a11y": { "version": "9.1.2" },
|
||||
"@storybook/addon-vitest": { "version": "9.1.2" }
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
Bundled license information:
|
||||
|
||||
filesize/dist/filesize.esm.js:
|
||||
/**
|
||||
* filesize
|
||||
*
|
||||
* @copyright 2024 Jason Mulligan <jason.mulligan@avoidwork.com>
|
||||
* @license BSD-3-Clause
|
||||
* @version 10.1.6
|
||||
*/
|
||||
|
||||
@chromatic-com/storybook/dist/manager.mjs:
|
||||
/*! Bundled license information:
|
||||
|
||||
popper.js/dist/esm/popper.js:
|
||||
(**!
|
||||
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
||||
* @version 1.16.1
|
||||
* @license
|
||||
* Copyright (c) 2016 Federico Zivolo and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*)
|
||||
*/
|
||||
@@ -1,46 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<mask id="active-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M25,15.3 C26.8630998,15.3 28.7261995,16.2284418 29.795607,18.0853254 L29.795607,18.0853254 L34.7484772,26.6853254 C35.2679728,27.5873604 35.5068948,28.5446245 35.509009,29.4780654 C35.5112408,30.4762222 35.243212,31.4466974 34.7610935,32.2926531 C34.2789749,33.1386087 33.5826171,33.8603071 32.7267084,34.3600412 C31.9262928,34.8273748 30.9864445,35.1 29.9528702,35.1 L29.9528702,35.1 L20.0471298,35.1 C19.0135555,35.1 18.0737072,34.8273748 17.2732916,34.3600412 C16.4173829,33.8603071 15.7210251,33.1386087 15.2389065,32.2926531 C14.756788,31.4466974 14.4887592,30.4762222 14.490991,29.4780654 C14.4931052,28.5446245 14.7320272,27.5873604 15.2515228,26.6853254 L15.2515228,26.6853254 L20.204393,18.0853254 C21.2738005,16.2284418 23.1369002,15.3 25,15.3 Z"
|
||||
transform="rotate(90 25 25.2)" />
|
||||
</mask>
|
||||
<mask id="critical-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M23.9,14.6 C26.7442665,14.6 29.3192665,15.7528668 31.1831998,17.6168002 C33.0471332,19.4807335 34.2,22.0557335 34.2,24.9 C34.2,27.7442665 33.0471332,30.3192665 31.1831998,32.1831998 C29.3192665,34.0471332 26.7442665,35.2 23.9,35.2 C21.0557335,35.2 18.4807335,34.0471332 16.6168002,32.1831998 C14.7528668,30.3192665 13.6,27.7442665 13.6,24.9 C13.6,22.0557335 14.7528668,19.4807335 16.6168002,17.6168002 C18.4807335,15.7528668 21.0557335,14.6 23.9,14.6 Z" />
|
||||
</mask>
|
||||
<mask id="negative-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M28.2,14.8 C29.633165,14.8 31.06633,15.346734 32.159798,16.440202 C33.2414078,17.5218119 33.7880833,18.9357904 33.8,20.353376 C33.811544,21.7725108 33.2872104,23.1952877 32.2266806,24.2917914 L32.2266806,24.2917914 L31.7206,24.8006729 L32.159798,25.240202 C33.253266,26.33367 33.8,27.766835 33.8,29.2 C33.8,30.633165 33.253266,32.06633 32.159798,33.159798 C31.0781881,34.2414078 29.6642096,34.7880833 28.246624,34.8 C26.8274892,34.811544 25.4047123,34.2872104 24.3082086,33.2266806 L24.3082086,33.2266806 L23.7993271,32.7206 L23.359798,33.159798 C22.26633,34.253266 20.833165,34.8 19.4,34.8 C17.966835,34.8 16.53367,34.253266 15.440202,33.159798 C14.3585922,32.0781881 13.8119167,30.6642096 13.8,29.246624 C13.788456,27.8274892 14.3127896,26.4047123 15.3733194,25.3082086 L15.3733194,25.3082086 L15.8794,24.7993271 L15.440202,24.359798 C14.346734,23.26633 13.8,21.833165 13.8,20.4 C13.8,18.966835 14.346734,17.53367 15.440202,16.440202 C16.5218119,15.3585922 17.9357904,14.8119167 19.353376,14.8 C20.7725108,14.788456 22.1952877,15.3127896 23.2917914,16.3733194 L23.2917914,16.3733194 L23.8006729,16.8794 L24.240202,16.440202 C25.33367,15.346734 26.766835,14.8 28.2,14.8 Z" />
|
||||
</mask>
|
||||
<mask id="positive-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M29.7294207,16.9922805 C31.1625744,16.9866282 32.5979013,17.5276612 33.6957071,18.6167741 C34.7816077,19.6940761 35.3338993,21.1058704 35.351258,22.5233982 C35.3686336,23.9423122 34.8500808,25.3669976 33.7941627,26.4676563 L33.7941627,26.4676563 L27.1794488,33.1363075 C26.0960963,34.2283069 24.675298,34.7802389 23.2508341,34.7920857 C21.8249459,34.8039445 20.3953569,34.27469 19.296927,33.2041927 L19.296927,33.2041927 L15.7761737,29.656491 C14.6870608,28.5586851 14.1460279,27.1233582 14.1516801,25.6902046 C14.1574213,24.2570509 14.7098478,22.8260705 15.8076536,21.7369576 C16.7544861,20.7976225 17.9523748,20.2659173 19.1834383,20.1411672 C20.4372495,20.0141119 21.7255226,20.3088158 22.8178242,21.0249737 L22.8178242,21.0249737 L23.1781395,21.2667759 L25.7761737,18.648254 C26.8652867,17.5504481 28.2962671,16.9980217 29.7294207,16.9922805 Z" />
|
||||
</mask>
|
||||
<mask id="warning-mask">
|
||||
<rect x="0" y="0" width="32" height="32" fill="#FFF" />
|
||||
<path fill="#000" fill-rule="nonzero"
|
||||
d="M23.8,14.8 C25.6808284,14.8 27.5616567,15.7284418 28.6412402,17.5853254 L28.6412402,17.5853254 L33.6412402,26.1853254 C34.1656792,27.0873604 34.4068747,28.0446245 34.409009,28.9780654 C34.4112621,29.9762222 34.1406828,30.9466974 33.6539766,31.7926531 C33.1672704,32.6386087 32.4642862,33.3603071 31.600233,33.8600412 C30.7922009,34.3273748 29.8434094,34.6 28.8,34.6 L28.8,34.6 L18.8,34.6 C17.7565906,34.6 16.8077991,34.3273748 15.999767,33.8600412 C15.1357138,33.3603071 14.4327296,32.6386087 13.9460234,31.7926531 C13.4593172,30.9466974 13.1887379,29.9762222 13.190991,28.9780654 C13.1931253,28.0446245 13.4343208,27.0873604 13.9587598,26.1853254 L13.9587598,26.1853254 L18.9587598,17.5853254 C20.0383433,15.7284418 21.9191716,14.8 23.8,14.8 Z" />
|
||||
</mask>
|
||||
|
||||
<polygon id="active" fill="none" stroke="#029CFD" stroke-linejoin="round" stroke-width="2.8"
|
||||
points="25 21 30 29.6 20 29.6" transform="rotate(90 25 25.3)" />
|
||||
<circle id="critical" fill="none" cx="23.9" cy="24.9" r="4.7" stroke="#000" stroke-linejoin="round"
|
||||
stroke-width="2.8" />
|
||||
<path id="negative" fill="none" stroke="#F40" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.8"
|
||||
d="M19.4,20.4 L28.2,29.2 M28.2,20.4 L19.4,29.2" />
|
||||
<polyline id="positive" fill="none" stroke="#66BF3C" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2.8" points="19.752 25.712 23.204 29.192 29.752 22.592" />
|
||||
<polygon id="warning" fill="none" stroke="#FFAE00" stroke-linejoin="round" stroke-width="2.8"
|
||||
points="23.8 20.4 28.8 29 18.8 29" />
|
||||
</defs>
|
||||
|
||||
<g id="mask">
|
||||
<use id="icon" />
|
||||
</g>
|
||||
<use id="status" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.7 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><g fill="none" fill-rule="evenodd"><path fill="#FF4785" fill-rule="nonzero" d="M3.19456517,29.5523576 L2.20116517,3.08035756 C2.16820317,2.206041 2.83853396,1.46497625 3.71176517,1.41035756 L26.2285652,0.00315756388 C26.6728415,-0.0246745074 27.1088544,0.132425741 27.4332785,0.437229126 C27.7577026,0.74203251 27.9415652,1.16741027 27.9415652,1.61255756 L27.9415652,30.4585576 C27.9415652,30.8987416 27.7615266,31.3197739 27.4433606,31.6239653 C27.1251947,31.9281568 26.6965078,32.0890657 26.2567652,32.0693576 L4.73376517,31.1027576 C3.89549138,31.0651477 3.22618762,30.3908861 3.19476517,29.5523576 L3.19456517,29.5523576 Z"/><path fill="#FFF" d="M24.4581652,0.113957564 L21.3591652,0.307557564 L21.2081652,3.94195756 C21.2043927,4.0349625 21.2546048,4.1217998 21.3370927,4.16492627 C21.4195807,4.20805273 21.5195442,4.19973049 21.5937652,4.14355756 L23.0057652,3.07275756 L24.1981652,4.01215756 C24.2717133,4.07021898 24.3722957,4.08025391 24.4558654,4.03786787 C24.539435,3.99548183 24.5907604,3.90840015 24.5873652,3.81475756 L24.4581652,0.113757564 L24.4581652,0.113957564 Z M22.0463652,12.2851576 C21.4791652,12.7257576 17.2533652,13.0265576 17.2533652,12.3991576 C17.3427652,10.0053576 16.2709652,9.90035756 15.6755652,9.90035756 C15.1099652,9.90035756 14.1575652,10.0713576 14.1575652,11.3537576 C14.1575652,12.6605576 15.5495652,13.3983576 17.1835652,14.2643576 C19.5049652,15.4943576 22.3143652,16.9831576 22.3143652,20.7295576 C22.3143652,24.3201576 19.3967652,26.3037576 15.6755652,26.3037576 C11.8353652,26.3037576 8.47936517,24.7499576 8.85836517,19.3633576 C9.00716517,18.7307576 13.8895652,18.8811576 13.8895652,19.3633576 C13.8299652,21.5861576 14.3359652,22.2399576 15.6161652,22.2399576 C16.5985652,22.2399576 17.0449652,21.6983576 17.0449652,20.7865576 C17.0449652,19.4065576 15.5945652,18.5919576 13.9259652,17.6551576 C11.6665652,16.3865576 9.00716517,14.8935576 9.00716517,11.4679576 C9.00716517,8.04835756 11.3591652,5.76855756 15.5565652,5.76855756 C19.7541652,5.76855756 22.0463652,8.01335756 22.0463652,12.2853576 L22.0463652,12.2851576 Z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |