diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 5a19e8ac..00000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -dist -coverage \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index b9bc24dc..00000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,40 +0,0 @@ -module.exports = { - root: true, - env: { - browser: true, - es2020: true, - }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react/recommended', - 'plugin:react/jsx-runtime', - 'plugin:react-hooks/recommended', - 'prettier', - ], - ignorePatterns: ['dist', '.eslintrc.cjs'], - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint', 'react'], - settings: { - react: { - version: 'detect', - }, - }, - rules: { - 'react/prop-types': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/max-params': ['error', { max: 4 }], - '@typescript-eslint/no-explicit-any': 'warn', - '@typescript-eslint/no-unused-vars': [ - 'warn', - { - argsIgnorePattern: '^_', - varsIgnorePattern: '^_', - }, - ], - indent: ['error', 2], - semi: ['error', 'never'], - quotes: ['error', 'single'], - }, -} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7b7adb7c..3e8cc6a1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,3 +38,11 @@ jobs: - name: Debug Environment run: uname -a + + - name: Verify Package Contents + run: | + test -f dist/index.mjs || (echo "Missing index.mjs" && exit 1) + test -f dist/index.cjs || (echo "Missing index.cjs" && exit 1) + test -f dist/styles.css || (echo "Missing styles.css" && exit 1) + test -f dist/baseline-kit.css || (echo "Missing baseline-kit.css" && exit 1) + test -d dist/theme || (echo "Missing theme directory" && exit 1) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9c70000..ec300bca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # baseline-kit +## 3.0.0 + +### Major Changes + +- comprehensive component library redesign with improved theming system and optimized rendering + ## 2.1.0 ### Minor Changes diff --git a/README.md b/README.md index ae7303f5..f658548c 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,27 @@ import 'baseline-kit/styles'; // Required core styles import 'baseline-kit/theme'; // Recommended theme (or use your own) ``` +For frameworks like Remix that use URL imports in a links function: + +```tsx +export const links = () => [ + { rel: "stylesheet", href: "baseline-kit/styles" }, + { rel: "stylesheet", href: "baseline-kit/theme" } +]; +``` + +If you prefer a single CSS file that includes everything: + +```tsx +// Alternative: Import everything in one file +import 'baseline-kit/full'; + +// For Remix: +export const links = () => [ + { rel: "stylesheet", href: "baseline-kit/full" } +]; +``` + Baseline Kit is written in TypeScript and includes built-in type definitions—no additional packages required. ## Quick Start @@ -210,24 +231,59 @@ debugging = "none" // Removes debug elements entirely ## Theme System -Baseline Kit comes with two CSS files: +Baseline Kit comes with a flexible CSS structure and theming system: + +1. `core.css` - Contains the core component styles required for functionality (imported via `baseline-kit/styles`) +2. `theme.css` - Contains color variables and theming with automatic dark mode support (imported via `baseline-kit/theme`) +3. `baseline-kit.css` - Combined file with both core and theme styles (imported via `baseline-kit/full`) + +### CSS Import Options + +Baseline Kit gives you flexibility in how you include the styles: -1. `styles.css` - Contains the core component styles required for functionality -2. `theme.css` - Contains color variables and theming (optional but recommended) +```tsx +// Option 1: Import core styles and theme separately (recommended) +import 'baseline-kit/styles'; +import 'baseline-kit/theme'; + +// Option 2: Import everything in one file +import 'baseline-kit/full'; +``` ### Theme Options -You have three options for using the theme system: +You now have four options for using the theme system: -#### 1. Use the Built-in Theme +#### 1. Use the Built-in Theme (with automatic dark mode) ```tsx import 'baseline-kit/theme'; // Default theme with light/dark mode support ``` -#### 2. Create a Custom Theme +#### 2. Use Specific Theme Variants + +```tsx +// Use only the light theme (no dark mode) +import 'baseline-kit/theme/default'; + +// Use only the dark theme +import 'baseline-kit/theme/dark'; + +// Example: Apply dark theme regardless of system preference +import 'baseline-kit/styles'; +import 'baseline-kit/theme/dark'; +``` + +#### 3. Create a Custom Theme -Create your own theme.css file: +You can use the tokens template as a starting point: + +```tsx +// First check the token template to see available variables +import 'baseline-kit/theme/tokens'; // Just for reference (contains no values) +``` + +Then create your own custom theme file: ```css /* yourCustomTheme.css */ @@ -253,7 +309,7 @@ import 'baseline-kit/styles'; // Required core styles import './path/to/yourCustomTheme.css'; // Your custom theme ``` -#### 3. Override via Config +#### 4. Override via Config For minor adjustments, use the Config component: @@ -353,4 +409,80 @@ Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for detailed guidelines. ## License -MIT © [François Denavaut](https://github.com/dnvt) \ No newline at end of file +MIT © [François Denavaut](https://github.com/dnvt) + +## Integration with Remix + +Baseline Kit is fully compatible with Remix. Follow these steps to integrate it into your Remix application: + +### Standard Integration + +In your Remix application, create a `root.tsx` file with proper links to the CSS: + +```tsx +// app/root.tsx +import type { LinksFunction } from '@remix-run/node'; + +export const links: LinksFunction = () => [ + // Option 1: Use the combined CSS file (simplest approach) + { rel: 'stylesheet', href: 'npm:baseline-kit/dist/baseline-kit.css' }, + + // Option 2: Or use core styles and theme separately + // { rel: 'stylesheet', href: 'npm:baseline-kit/dist/styles.css' }, + // { rel: 'stylesheet', href: 'npm:baseline-kit/dist/theme.css' }, +]; + +export default function App() { + return ( + + + + + + + + + + + + + + ); +} +``` + +Note the use of `npm:` prefix which is the recommended way to reference CSS from node_modules in Remix. + +### Troubleshooting CSS in Remix + +If you're experiencing styling issues with components not showing properly: + +1. **Copy to public directory**: For a completely reliable solution, copy the CSS files to your public directory: + ```shell + mkdir -p public/css + cp node_modules/baseline-kit/dist/*.css public/css/ + ``` + + Then reference these local files: + ```tsx + export const links: LinksFunction = () => [ + { rel: 'stylesheet', href: '/css/baseline-kit.css' } + ]; + ``` + +2. **Check CSS specificity**: Make sure your application's CSS isn't overriding Baseline Kit styles. You may need to adjust specificity or load order of your stylesheets. + +### Custom Theme Integration + +For custom theming: + +```tsx +export const links: LinksFunction = () => [ + // Core styles (required) + { rel: 'stylesheet', href: 'npm:baseline-kit/dist/styles.css' }, + // Choose one of these theme options: + { rel: 'stylesheet', href: 'npm:baseline-kit/dist/theme/default.css' }, // Light theme only + { rel: 'stylesheet', href: 'npm:baseline-kit/dist/theme/dark.css' }, // Dark theme only + { rel: 'stylesheet', href: '/css/custom-theme.css' }, // Your custom theme +]; +``` \ No newline at end of file diff --git a/bun.lock b/bun.lock index 96177ac6..7ebc8501 100644 --- a/bun.lock +++ b/bun.lock @@ -4,39 +4,41 @@ "": { "name": "baseline-kit", "dependencies": { - "esbuild": "^0.24.2", + "esbuild": "^0.25.0", "postcss-preset-env": "^10.1.5", }, "devDependencies": { "@changesets/cli": "^2.28.1", + "@eslint/js": "^9.21.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", - "@types/node": "^22.13.5", + "@types/node": "^22.13.9", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", - "@typescript-eslint/eslint-plugin": "^8.25.0", - "@typescript-eslint/parser": "^8.25.0", + "@typescript-eslint/eslint-plugin": "^8.26.0", + "@typescript-eslint/parser": "^8.26.0", "@vitejs/plugin-react-swc": "^3.8.0", - "@vitest/coverage-v8": "^2.1.9", + "@vitest/coverage-v8": "^3.0.8", "autoprefixer": "^10.4.20", "cssnano": "^7.0.6", - "eslint": "^8.57.1", - "eslint-config-prettier": "^9.1.0", + "eslint": "^9.0.0", + "eslint-config-prettier": "^10.1.1", + "eslint-plugin-prettier": "^5.2.3", "eslint-plugin-react": "^7.37.4", - "eslint-plugin-react-hooks": "^4.6.2", - "jsdom": "^25.0.1", - "prettier": "^3.5.2", - "rollup": "^4.34.8", + "eslint-plugin-react-hooks": "^5.2.0", + "jsdom": "^26.0.0", + "prettier": "^3.5.3", + "rollup": "^4.34.9", "rollup-plugin-dts": "^6.1.1", "rollup-plugin-visualizer": "^5.14.0", - "vite": "^6.2.0", - "vite-plugin-static-copy": "^2.2.0", - "vitest": "^3.0.7", + "vite": "6.2.1", + "vite-plugin-static-copy": "^2.3.0", + "vitest": "3.0.8", }, "peerDependencies": { - "react": "^18 || ^19", - "react-dom": "^18 || ^19", - "typescript": "^5.7.3", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "typescript": "^5.8.2", }, }, }, @@ -45,7 +47,7 @@ "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], - "@asamuzakjp/css-color": ["@asamuzakjp/css-color@2.8.3", "", { "dependencies": { "@csstools/css-calc": "^2.1.1", "@csstools/css-color-parser": "^3.0.7", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw=="], + "@asamuzakjp/css-color": ["@asamuzakjp/css-color@3.1.1", "", { "dependencies": { "@csstools/css-calc": "^2.1.2", "@csstools/css-color-parser": "^3.0.8", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-hpRD68SV2OMcZCsrbdkccTw5FXjNDLo5OuqSHyHZfwweGsDWZwDJ2+gONyNAbazZclobMirACLw0lk8WVxIqxA=="], "@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="], @@ -59,7 +61,7 @@ "@babel/types": ["@babel/types@7.26.9", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw=="], - "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], + "@bcoe/v8-coverage": ["@bcoe/v8-coverage@1.0.2", "", {}, "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA=="], "@changesets/apply-release-plan": ["@changesets/apply-release-plan@7.0.10", "", { "dependencies": { "@changesets/config": "^3.1.1", "@changesets/get-version-range-type": "^0.4.0", "@changesets/git": "^3.0.2", "@changesets/should-skip-package": "^0.1.2", "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "detect-indent": "^6.0.0", "fs-extra": "^7.0.1", "lodash.startcase": "^4.4.0", "outdent": "^0.5.0", "prettier": "^2.7.1", "resolve-from": "^5.0.0", "semver": "^7.5.3" } }, "sha512-wNyeIJ3yDsVspYvHnEz1xQDq18D9ifed3lI+wxRQRK4pArUcuHgCTrHv0QRnnwjhVCQACxZ+CBih3wgOct6UXw=="], @@ -179,69 +181,81 @@ "@csstools/utilities": ["@csstools/utilities@2.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.24.2", "", { "os": "android", "cpu": "arm" }, "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.25.0", "", { "os": "android", "cpu": "arm" }, "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.24.2", "", { "os": "android", "cpu": "arm64" }, "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.0", "", { "os": "android", "cpu": "arm64" }, "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.24.2", "", { "os": "android", "cpu": "x64" }, "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.25.0", "", { "os": "android", "cpu": "x64" }, "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.24.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.24.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.24.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.24.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.24.2", "", { "os": "linux", "cpu": "arm" }, "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.0", "", { "os": "linux", "cpu": "arm" }, "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.24.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.24.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.0", "", { "os": "linux", "cpu": "none" }, "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.0", "", { "os": "linux", "cpu": "none" }, "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.24.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.0", "", { "os": "linux", "cpu": "none" }, "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.24.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.24.2", "", { "os": "linux", "cpu": "x64" }, "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.0", "", { "os": "linux", "cpu": "x64" }, "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.24.2", "", { "os": "none", "cpu": "arm64" }, "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.0", "", { "os": "none", "cpu": "arm64" }, "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.24.2", "", { "os": "none", "cpu": "x64" }, "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.0", "", { "os": "none", "cpu": "x64" }, "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.24.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.24.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.24.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.24.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.24.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.0", "", { "os": "win32", "cpu": "x64" }, "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ=="], "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.4.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA=="], "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], - "@eslint/eslintrc": ["@eslint/eslintrc@2.1.4", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ=="], + "@eslint/config-array": ["@eslint/config-array@0.19.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w=="], - "@eslint/js": ["@eslint/js@8.57.1", "", {}, "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q=="], + "@eslint/config-helpers": ["@eslint/config-helpers@0.1.0", "", {}, "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA=="], - "@humanwhocodes/config-array": ["@humanwhocodes/config-array@0.13.0", "", { "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" } }, "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw=="], + "@eslint/core": ["@eslint/core@0.12.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg=="], + + "@eslint/eslintrc": ["@eslint/eslintrc@3.3.0", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ=="], + + "@eslint/js": ["@eslint/js@9.22.0", "", {}, "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ=="], + + "@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="], + + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.7", "", { "dependencies": { "@eslint/core": "^0.12.0", "levn": "^0.4.1" } }, "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g=="], + + "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], + + "@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="], "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], - "@humanwhocodes/object-schema": ["@humanwhocodes/object-schema@2.0.3", "", {}, "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA=="], + "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="], "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], @@ -269,69 +283,71 @@ "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.34.8", "", { "os": "android", "cpu": "arm" }, "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw=="], + "@pkgr/core": ["@pkgr/core@0.1.1", "", {}, "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.34.8", "", { "os": "android", "cpu": "arm64" }, "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.35.0", "", { "os": "android", "cpu": "arm" }, "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.34.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.35.0", "", { "os": "android", "cpu": "arm64" }, "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.34.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.35.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.34.8", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.35.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.34.8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.35.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.34.8", "", { "os": "linux", "cpu": "arm" }, "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.35.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.34.8", "", { "os": "linux", "cpu": "arm" }, "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.35.0", "", { "os": "linux", "cpu": "arm" }, "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.34.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.35.0", "", { "os": "linux", "cpu": "arm" }, "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.34.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.35.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A=="], - "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.34.8", "", { "os": "linux", "cpu": "none" }, "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.35.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg=="], - "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.34.8", "", { "os": "linux", "cpu": "ppc64" }, "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw=="], + "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.35.0", "", { "os": "linux", "cpu": "none" }, "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.34.8", "", { "os": "linux", "cpu": "none" }, "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw=="], + "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.35.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.34.8", "", { "os": "linux", "cpu": "s390x" }, "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.35.0", "", { "os": "linux", "cpu": "none" }, "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.34.8", "", { "os": "linux", "cpu": "x64" }, "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.35.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.34.8", "", { "os": "linux", "cpu": "x64" }, "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.35.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.34.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.35.0", "", { "os": "linux", "cpu": "x64" }, "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.34.8", "", { "os": "win32", "cpu": "ia32" }, "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.35.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.34.8", "", { "os": "win32", "cpu": "x64" }, "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.35.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw=="], - "@swc/core": ["@swc/core@1.11.1", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.18" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.1", "@swc/core-darwin-x64": "1.11.1", "@swc/core-linux-arm-gnueabihf": "1.11.1", "@swc/core-linux-arm64-gnu": "1.11.1", "@swc/core-linux-arm64-musl": "1.11.1", "@swc/core-linux-x64-gnu": "1.11.1", "@swc/core-linux-x64-musl": "1.11.1", "@swc/core-win32-arm64-msvc": "1.11.1", "@swc/core-win32-ia32-msvc": "1.11.1", "@swc/core-win32-x64-msvc": "1.11.1" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-67+lBHZ1lAJQKoOhBHl9DE2iugPYAulRVArZjoF+DnIY3G9wLXCXxw5It0IaCnzvJVvUPxGmr0rHViXKBDP5Vg=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.35.0", "", { "os": "win32", "cpu": "x64" }, "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw=="], - "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bJbqZ51JghEZ8WaFetofkfkS3MWsS/V3vDvY+0r+SlLeocZwf8q8/GqcafnElHcU+zLV6yTi13fJwUce6ULiUQ=="], + "@swc/core": ["@swc/core@1.11.8", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.19" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.8", "@swc/core-darwin-x64": "1.11.8", "@swc/core-linux-arm-gnueabihf": "1.11.8", "@swc/core-linux-arm64-gnu": "1.11.8", "@swc/core-linux-arm64-musl": "1.11.8", "@swc/core-linux-x64-gnu": "1.11.8", "@swc/core-linux-x64-musl": "1.11.8", "@swc/core-win32-arm64-msvc": "1.11.8", "@swc/core-win32-ia32-msvc": "1.11.8", "@swc/core-win32-x64-msvc": "1.11.8" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-UAL+EULxrc0J73flwYHfu29mO8CONpDJiQv1QPDXsyCvDUcEhqAqUROVTgC+wtJCFFqMQdyr4stAA5/s0KSOmA=="], - "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-9GGEoN0uxkLg3KocOVzMfe9c9/DxESXclsL/U2xVLa3pTFB5YnXhiCP5YBT/3Q7nSGLD+R2ALqkNlDoueUjvPw=="], + "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rrSsunyJWpHN+5V1zumndwSSifmIeFQBK9i2RMQQp15PgbgUNxHK5qoET1n20pcUrmZeT6jmJaEWlQchkV//Og=="], - "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Lt7l/l0nfSTUzsWcVY3dtOPl5RtgCJ+Ya8IG4Aa3l6c7kLc6Sx4JpylpEIY9yhGidDy/uQ8KUg5kqUPtUrXrvQ=="], + "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-44goLqQuuo0HgWnG8qC+ZFw/qnjCVVeqffhzFr9WAXXotogVaxM8ze6egE58VWrfEc8me8yCcxOYL9RbtjhS/Q=="], - "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-oe826cfuGukctTSpDjk7RJRDEJihQMAzvO5tdWK0wcy+zvMPFyH5Fg6cW0X4ST3M7fcV91/1T/iuiiD2SVamYw=="], + "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.8", "", { "os": "linux", "cpu": "arm" }, "sha512-Mzo8umKlhTWwF1v8SLuTM1z2A+P43UVhf4R8RZDhzIRBuB2NkeyE+c0gexIOJBuGSIATryuAF4O4luDu727D1w=="], - "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-ABb4pnYeQp/JBJS5Qd2apTwOzpzrTebQFUiFjk0WgTKIr9T6SL3tLXMjgvbSXIath+1HnbCKFUwDXNQhgGFFTg=="], + "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-EyhO6U+QdoGYC1MeHOR0pyaaSaKYyNuT4FQNZ1eZIbnuueXpuICC7iNmLIOfr3LE5bVWcZ7NKGVPlM2StJEcgA=="], - "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-E09TcHv40bV0mOHTKquZw0IOcQ+lzzpQjyOhCa7+GBpbS3eg5/35Gu7DfToN2bomz74LPKW/l7jZRG+ZNOYNHQ=="], + "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.11.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-QU6wOkZnS6/QuBN1MHD6G2BgFxB0AclvTVGbqYkRA7MsVkcC29PffESqzTXnypzB252/XkhQjoB2JIt9rPYf6A=="], - "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-cuW4r7GbvQt9uv+rGdYLHUjDvGjHmr1nYE7iFVk6r4i+byZuXBK6M7P1p+/dTzacshOc05I9n/eUV+Hfjp9a3A=="], + "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.8", "", { "os": "linux", "cpu": "x64" }, "sha512-r72onUEIU1iJi9EUws3R28pztQ/eM3EshNpsPRBfuLwKy+qn3et55vXOyDhIjGCUph5Eg2Yn8H3h6MTxDdLd+w=="], - "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-H8Q78GwaKnCL4isHx8JRTRi6vUU6iMLbpegS2jzWWC1On7EePhkLx2eR8nEsaRIQB6rc3WqdIj74OgOpNoPi7g=="], + "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.8", "", { "os": "linux", "cpu": "x64" }, "sha512-294k8cLpO103++f4ZUEDr3vnBeUfPitW6G0a3qeVZuoXFhFgaW7ANZIWknUc14WiLOMfMecphJAEiy9C8OeYSw=="], - "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-Rx7cZ0OvqMb16fgmUSlPWQbH1+X355IDJhVQpUlpL+ezD/kkWmJix+4u2GVE/LHrfbdyZ4sjjIzSsCQxJV05Mw=="], + "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-EbjOzQ+B85rumHyeesBYxZ+hq3ZQn+YAAT1ZNE9xW1/8SuLoBmHy/K9YniRGVDq/2NRmp5kI5+5h5TX0asIS9A=="], - "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-6bEEC/XU1lwYzUXY7BXj3nhe7iBF9+i9dVo+hbiVxXZMrD0LUd+7urOBM3NtVnDsUaR6Ge/g7aR+OfpgYscKOg=="], + "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.8", "", { "os": "win32", "cpu": "ia32" }, "sha512-Z+FF5kgLHfQWIZ1KPdeInToXLzbY0sMAashjd/igKeP1Lz0qKXVAK+rpn6ASJi85Fn8wTftCGCyQUkRVn0bTDg=="], + + "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.8", "", { "os": "win32", "cpu": "x64" }, "sha512-j6B6N0hChCeAISS6xp/hh6zR5CSCr037BAjCxNLsT8TGe5D+gYZ57heswUWXRH8eMKiRDGiLCYpPB2pkTqxCSw=="], "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], - "@swc/types": ["@swc/types@0.1.18", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-NZghLaQvF3eFdj2DUjGkpwaunbZYaRcxciHINnwA4n3FrLAI8hKFOBqs2wkcOiLQfWkIdfuG6gBkNFrkPNji5g=="], + "@swc/types": ["@swc/types@0.1.19", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-WkAZaAfj44kh/UFdAQcrMP1I0nwRqpt27u+08LMBYMqmQfwwMofYoMh/48NGkMMRfC4ynpfwRbJuu8ErfNloeA=="], "@testing-library/dom": ["@testing-library/dom@10.4.0", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "pretty-format": "^27.0.2" } }, "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ=="], @@ -345,49 +361,49 @@ "@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], - "@types/node": ["@types/node@22.13.5", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg=="], + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + + "@types/node": ["@types/node@22.13.10", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw=="], "@types/react": ["@types/react@19.0.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g=="], "@types/react-dom": ["@types/react-dom@19.0.4", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg=="], - "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.25.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.25.0", "@typescript-eslint/type-utils": "8.25.0", "@typescript-eslint/utils": "8.25.0", "@typescript-eslint/visitor-keys": "8.25.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.26.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.26.0", "@typescript-eslint/type-utils": "8.26.0", "@typescript-eslint/utils": "8.26.0", "@typescript-eslint/visitor-keys": "8.26.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q=="], - "@typescript-eslint/parser": ["@typescript-eslint/parser@8.25.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.25.0", "@typescript-eslint/types": "8.25.0", "@typescript-eslint/typescript-estree": "8.25.0", "@typescript-eslint/visitor-keys": "8.25.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg=="], + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.26.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.26.0", "@typescript-eslint/types": "8.26.0", "@typescript-eslint/typescript-estree": "8.26.0", "@typescript-eslint/visitor-keys": "8.26.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA=="], - "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.25.0", "", { "dependencies": { "@typescript-eslint/types": "8.25.0", "@typescript-eslint/visitor-keys": "8.25.0" } }, "sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg=="], + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.26.0", "", { "dependencies": { "@typescript-eslint/types": "8.26.0", "@typescript-eslint/visitor-keys": "8.26.0" } }, "sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA=="], - "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.25.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.25.0", "@typescript-eslint/utils": "8.25.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g=="], + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.26.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.26.0", "@typescript-eslint/utils": "8.26.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q=="], - "@typescript-eslint/types": ["@typescript-eslint/types@8.25.0", "", {}, "sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw=="], + "@typescript-eslint/types": ["@typescript-eslint/types@8.26.0", "", {}, "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA=="], - "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.25.0", "", { "dependencies": { "@typescript-eslint/types": "8.25.0", "@typescript-eslint/visitor-keys": "8.25.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q=="], + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.26.0", "", { "dependencies": { "@typescript-eslint/types": "8.26.0", "@typescript-eslint/visitor-keys": "8.26.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ=="], - "@typescript-eslint/utils": ["@typescript-eslint/utils@8.25.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.25.0", "@typescript-eslint/types": "8.25.0", "@typescript-eslint/typescript-estree": "8.25.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA=="], + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.26.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.26.0", "@typescript-eslint/types": "8.26.0", "@typescript-eslint/typescript-estree": "8.26.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig=="], - "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.25.0", "", { "dependencies": { "@typescript-eslint/types": "8.25.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ=="], - - "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.26.0", "", { "dependencies": { "@typescript-eslint/types": "8.26.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg=="], "@vitejs/plugin-react-swc": ["@vitejs/plugin-react-swc@3.8.0", "", { "dependencies": { "@swc/core": "^1.10.15" }, "peerDependencies": { "vite": "^4 || ^5 || ^6" } }, "sha512-T4sHPvS+DIqDP51ifPqa9XIRAz/kIvIi8oXcnOZZgHmMotgmmdxe/DD5tMFlt5nuIRzT0/QuiwmKlH0503Aapw=="], - "@vitest/coverage-v8": ["@vitest/coverage-v8@2.1.9", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@bcoe/v8-coverage": "^0.2.3", "debug": "^4.3.7", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^5.0.6", "istanbul-reports": "^3.1.7", "magic-string": "^0.30.12", "magicast": "^0.3.5", "std-env": "^3.8.0", "test-exclude": "^7.0.1", "tinyrainbow": "^1.2.0" }, "peerDependencies": { "@vitest/browser": "2.1.9", "vitest": "2.1.9" }, "optionalPeers": ["@vitest/browser"] }, "sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ=="], + "@vitest/coverage-v8": ["@vitest/coverage-v8@3.0.8", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@bcoe/v8-coverage": "^1.0.2", "debug": "^4.4.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^5.0.6", "istanbul-reports": "^3.1.7", "magic-string": "^0.30.17", "magicast": "^0.3.5", "std-env": "^3.8.0", "test-exclude": "^7.0.1", "tinyrainbow": "^2.0.0" }, "peerDependencies": { "@vitest/browser": "3.0.8", "vitest": "3.0.8" }, "optionalPeers": ["@vitest/browser"] }, "sha512-y7SAKsQirsEJ2F8bulBck4DoluhI2EEgTimHd6EEUgJBGKy9tC25cpywh1MH4FvDGoG2Unt7+asVd1kj4qOSAw=="], - "@vitest/expect": ["@vitest/expect@3.0.7", "", { "dependencies": { "@vitest/spy": "3.0.7", "@vitest/utils": "3.0.7", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-QP25f+YJhzPfHrHfYHtvRn+uvkCFCqFtW9CktfBxmB+25QqWsx7VB2As6f4GmwllHLDhXNHvqedwhvMmSnNmjw=="], + "@vitest/expect": ["@vitest/expect@3.0.8", "", { "dependencies": { "@vitest/spy": "3.0.8", "@vitest/utils": "3.0.8", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ=="], - "@vitest/mocker": ["@vitest/mocker@3.0.7", "", { "dependencies": { "@vitest/spy": "3.0.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-qui+3BLz9Eonx4EAuR/i+QlCX6AUZ35taDQgwGkK/Tw6/WgwodSrjN1X2xf69IA/643ZX5zNKIn2svvtZDrs4w=="], + "@vitest/mocker": ["@vitest/mocker@3.0.8", "", { "dependencies": { "@vitest/spy": "3.0.8", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow=="], - "@vitest/pretty-format": ["@vitest/pretty-format@3.0.7", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-CiRY0BViD/V8uwuEzz9Yapyao+M9M008/9oMOSQydwbwb+CMokEq3XVaF3XK/VWaOK0Jm9z7ENhybg70Gtxsmg=="], + "@vitest/pretty-format": ["@vitest/pretty-format@3.0.8", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg=="], - "@vitest/runner": ["@vitest/runner@3.0.7", "", { "dependencies": { "@vitest/utils": "3.0.7", "pathe": "^2.0.3" } }, "sha512-WeEl38Z0S2ZcuRTeyYqaZtm4e26tq6ZFqh5y8YD9YxfWuu0OFiGFUbnxNynwLjNRHPsXyee2M9tV7YxOTPZl2g=="], + "@vitest/runner": ["@vitest/runner@3.0.8", "", { "dependencies": { "@vitest/utils": "3.0.8", "pathe": "^2.0.3" } }, "sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w=="], - "@vitest/snapshot": ["@vitest/snapshot@3.0.7", "", { "dependencies": { "@vitest/pretty-format": "3.0.7", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-eqTUryJWQN0Rtf5yqCGTQWsCFOQe4eNz5Twsu21xYEcnFJtMU5XvmG0vgebhdLlrHQTSq5p8vWHJIeJQV8ovsA=="], + "@vitest/snapshot": ["@vitest/snapshot@3.0.8", "", { "dependencies": { "@vitest/pretty-format": "3.0.8", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A=="], - "@vitest/spy": ["@vitest/spy@3.0.7", "", { "dependencies": { "tinyspy": "^3.0.2" } }, "sha512-4T4WcsibB0B6hrKdAZTM37ekuyFZt2cGbEGd2+L0P8ov15J1/HUsUaqkXEQPNAWr4BtPPe1gI+FYfMHhEKfR8w=="], + "@vitest/spy": ["@vitest/spy@3.0.8", "", { "dependencies": { "tinyspy": "^3.0.2" } }, "sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q=="], - "@vitest/utils": ["@vitest/utils@3.0.7", "", { "dependencies": { "@vitest/pretty-format": "3.0.7", "loupe": "^3.1.3", "tinyrainbow": "^2.0.0" } }, "sha512-xePVpCRfooFX3rANQjwoditoXgWb1MaFbzmGuPP59MK6i13mrnDw/yEIyJudLeW6/38mCNcwCiJIGmpDPibAIg=="], + "@vitest/utils": ["@vitest/utils@3.0.8", "", { "dependencies": { "@vitest/pretty-format": "3.0.8", "loupe": "^3.1.3", "tinyrainbow": "^2.0.0" } }, "sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q=="], - "acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="], + "acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="], "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], @@ -429,7 +445,7 @@ "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], - "autoprefixer": ["autoprefixer@10.4.20", "", { "dependencies": { "browserslist": "^4.23.3", "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g=="], + "autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="], "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], @@ -453,13 +469,13 @@ "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], - "call-bound": ["call-bound@1.0.3", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "get-intrinsic": "^1.2.6" } }, "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA=="], + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], "caniuse-api": ["caniuse-api@3.0.0", "", { "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw=="], - "caniuse-lite": ["caniuse-lite@1.0.30001700", "", {}, "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ=="], + "caniuse-lite": ["caniuse-lite@1.0.30001703", "", {}, "sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ=="], "chai": ["chai@5.2.0", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw=="], @@ -517,7 +533,7 @@ "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="], - "cssstyle": ["cssstyle@4.2.1", "", { "dependencies": { "@asamuzakjp/css-color": "^2.8.2", "rrweb-cssom": "^0.8.0" } }, "sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw=="], + "cssstyle": ["cssstyle@4.3.0", "", { "dependencies": { "@asamuzakjp/css-color": "^3.1.1", "rrweb-cssom": "^0.8.0" } }, "sha512-6r0NiY0xizYqfBvWp1G7WXJ06/bZyrk7Dc6PHql82C/pKGUTKu4yAX4Y8JPamb1ob9nBKuxWzCGTRuGwU3yxJQ=="], "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], @@ -551,7 +567,7 @@ "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], - "doctrine": ["doctrine@3.0.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="], + "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="], "dom-accessibility-api": ["dom-accessibility-api@0.6.3", "", {}, "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w=="], @@ -567,7 +583,7 @@ "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], - "electron-to-chromium": ["electron-to-chromium@1.5.105", "", {}, "sha512-ccp7LocdXx3yBhwiG0qTQ7XFrK48Ua2pxIxBdJO8cbddp/MvbBtPFzvnTchtyHQTsgqqczO8cdmAIbpMa0u2+g=="], + "electron-to-chromium": ["electron-to-chromium@1.5.113", "", {}, "sha512-wjT2O4hX+wdWPJ76gWSkMhcHAV2PTMX+QetUCPYEdCIe+cxmgzzSSiGRCKW8nuh4mwKZlpv0xvoW7OF2X+wmHg=="], "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], @@ -593,25 +609,27 @@ "es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="], - "esbuild": ["esbuild@0.24.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.24.2", "@esbuild/android-arm": "0.24.2", "@esbuild/android-arm64": "0.24.2", "@esbuild/android-x64": "0.24.2", "@esbuild/darwin-arm64": "0.24.2", "@esbuild/darwin-x64": "0.24.2", "@esbuild/freebsd-arm64": "0.24.2", "@esbuild/freebsd-x64": "0.24.2", "@esbuild/linux-arm": "0.24.2", "@esbuild/linux-arm64": "0.24.2", "@esbuild/linux-ia32": "0.24.2", "@esbuild/linux-loong64": "0.24.2", "@esbuild/linux-mips64el": "0.24.2", "@esbuild/linux-ppc64": "0.24.2", "@esbuild/linux-riscv64": "0.24.2", "@esbuild/linux-s390x": "0.24.2", "@esbuild/linux-x64": "0.24.2", "@esbuild/netbsd-arm64": "0.24.2", "@esbuild/netbsd-x64": "0.24.2", "@esbuild/openbsd-arm64": "0.24.2", "@esbuild/openbsd-x64": "0.24.2", "@esbuild/sunos-x64": "0.24.2", "@esbuild/win32-arm64": "0.24.2", "@esbuild/win32-ia32": "0.24.2", "@esbuild/win32-x64": "0.24.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA=="], + "esbuild": ["esbuild@0.25.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.0", "@esbuild/android-arm": "0.25.0", "@esbuild/android-arm64": "0.25.0", "@esbuild/android-x64": "0.25.0", "@esbuild/darwin-arm64": "0.25.0", "@esbuild/darwin-x64": "0.25.0", "@esbuild/freebsd-arm64": "0.25.0", "@esbuild/freebsd-x64": "0.25.0", "@esbuild/linux-arm": "0.25.0", "@esbuild/linux-arm64": "0.25.0", "@esbuild/linux-ia32": "0.25.0", "@esbuild/linux-loong64": "0.25.0", "@esbuild/linux-mips64el": "0.25.0", "@esbuild/linux-ppc64": "0.25.0", "@esbuild/linux-riscv64": "0.25.0", "@esbuild/linux-s390x": "0.25.0", "@esbuild/linux-x64": "0.25.0", "@esbuild/netbsd-arm64": "0.25.0", "@esbuild/netbsd-x64": "0.25.0", "@esbuild/openbsd-arm64": "0.25.0", "@esbuild/openbsd-x64": "0.25.0", "@esbuild/sunos-x64": "0.25.0", "@esbuild/win32-arm64": "0.25.0", "@esbuild/win32-ia32": "0.25.0", "@esbuild/win32-x64": "0.25.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw=="], "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], - "eslint": ["eslint@8.57.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "8.57.1", "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" } }, "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA=="], + "eslint": ["eslint@9.22.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", "@eslint/config-helpers": "^0.1.0", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.0", "@eslint/js": "9.22.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.3.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ=="], + + "eslint-config-prettier": ["eslint-config-prettier@10.1.1", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw=="], - "eslint-config-prettier": ["eslint-config-prettier@9.1.0", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw=="], + "eslint-plugin-prettier": ["eslint-plugin-prettier@5.2.3", "", { "dependencies": { "prettier-linter-helpers": "^1.0.0", "synckit": "^0.9.1" }, "peerDependencies": { "@types/eslint": ">=8.0.0", "eslint": ">=8.0.0", "eslint-config-prettier": "*", "prettier": ">=3.0.0" }, "optionalPeers": ["@types/eslint", "eslint-config-prettier"] }, "sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw=="], "eslint-plugin-react": ["eslint-plugin-react@7.37.4", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.8", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ=="], - "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@4.6.2", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ=="], + "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="], - "eslint-scope": ["eslint-scope@7.2.2", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg=="], + "eslint-scope": ["eslint-scope@8.3.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ=="], - "eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + "eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="], - "espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="], + "espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="], "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], @@ -625,7 +643,7 @@ "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], - "expect-type": ["expect-type@1.1.0", "", {}, "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA=="], + "expect-type": ["expect-type@1.2.0", "", {}, "sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA=="], "extendable-error": ["extendable-error@0.1.7", "", {}, "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg=="], @@ -633,21 +651,23 @@ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + "fast-diff": ["fast-diff@1.3.0", "", {}, "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw=="], + "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], - "fastq": ["fastq@1.19.0", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA=="], + "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], - "file-entry-cache": ["file-entry-cache@6.0.1", "", { "dependencies": { "flat-cache": "^3.0.4" } }, "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="], + "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], - "flat-cache": ["flat-cache@3.2.0", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw=="], + "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], @@ -661,8 +681,6 @@ "fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="], - "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], - "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], @@ -683,7 +701,7 @@ "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], - "globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="], + "globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], @@ -729,10 +747,6 @@ "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], - "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], - - "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], - "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="], "is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="], @@ -771,8 +785,6 @@ "is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="], - "is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="], - "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="], "is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="], @@ -819,7 +831,7 @@ "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - "jsdom": ["jsdom@25.0.1", "", { "dependencies": { "cssstyle": "^4.1.0", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.12", "parse5": "^7.1.2", "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^2.11.2" }, "optionalPeers": ["canvas"] }, "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw=="], + "jsdom": ["jsdom@26.0.0", "", { "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.1", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.6", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.16", "parse5": "^7.2.1", "rrweb-cssom": "^0.8.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.1.0", "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw=="], "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], @@ -885,7 +897,7 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "nanoid": ["nanoid@3.3.8", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="], + "nanoid": ["nanoid@3.3.9", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg=="], "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], @@ -897,7 +909,7 @@ "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], - "nwsapi": ["nwsapi@2.2.16", "", {}, "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ=="], + "nwsapi": ["nwsapi@2.2.18", "", {}, "sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA=="], "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], @@ -913,8 +925,6 @@ "object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="], - "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], - "open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="], "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], @@ -931,13 +941,13 @@ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], - "p-map": ["p-map@2.1.0", "", {}, "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw=="], + "p-map": ["p-map@7.0.3", "", {}, "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA=="], "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], - "package-manager-detector": ["package-manager-detector@0.2.9", "", {}, "sha512-+vYvA/Y31l8Zk8dwxHhL3JfTuHPm6tlxM2A3GeQyl7ovYnSp1+mzAxClxaOr0qO1TtPxbQxetI7v5XqKLJZk7Q=="], + "package-manager-detector": ["package-manager-detector@0.2.11", "", { "dependencies": { "quansync": "^0.2.7" } }, "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ=="], "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], @@ -945,8 +955,6 @@ "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], - "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], - "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], @@ -1081,7 +1089,9 @@ "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], - "prettier": ["prettier@3.5.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg=="], + "prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="], + + "prettier-linter-helpers": ["prettier-linter-helpers@1.0.0", "", { "dependencies": { "fast-diff": "^1.1.2" } }, "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w=="], "pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], @@ -1089,6 +1099,8 @@ "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + "quansync": ["quansync@0.2.8", "", {}, "sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA=="], + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], "react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="], @@ -1117,15 +1129,13 @@ "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], - - "rollup": ["rollup@4.34.8", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.34.8", "@rollup/rollup-android-arm64": "4.34.8", "@rollup/rollup-darwin-arm64": "4.34.8", "@rollup/rollup-darwin-x64": "4.34.8", "@rollup/rollup-freebsd-arm64": "4.34.8", "@rollup/rollup-freebsd-x64": "4.34.8", "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", "@rollup/rollup-linux-arm-musleabihf": "4.34.8", "@rollup/rollup-linux-arm64-gnu": "4.34.8", "@rollup/rollup-linux-arm64-musl": "4.34.8", "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", "@rollup/rollup-linux-riscv64-gnu": "4.34.8", "@rollup/rollup-linux-s390x-gnu": "4.34.8", "@rollup/rollup-linux-x64-gnu": "4.34.8", "@rollup/rollup-linux-x64-musl": "4.34.8", "@rollup/rollup-win32-arm64-msvc": "4.34.8", "@rollup/rollup-win32-ia32-msvc": "4.34.8", "@rollup/rollup-win32-x64-msvc": "4.34.8", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ=="], + "rollup": ["rollup@4.35.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.35.0", "@rollup/rollup-android-arm64": "4.35.0", "@rollup/rollup-darwin-arm64": "4.35.0", "@rollup/rollup-darwin-x64": "4.35.0", "@rollup/rollup-freebsd-arm64": "4.35.0", "@rollup/rollup-freebsd-x64": "4.35.0", "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", "@rollup/rollup-linux-arm-musleabihf": "4.35.0", "@rollup/rollup-linux-arm64-gnu": "4.35.0", "@rollup/rollup-linux-arm64-musl": "4.35.0", "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", "@rollup/rollup-linux-riscv64-gnu": "4.35.0", "@rollup/rollup-linux-s390x-gnu": "4.35.0", "@rollup/rollup-linux-x64-gnu": "4.35.0", "@rollup/rollup-linux-x64-musl": "4.35.0", "@rollup/rollup-win32-arm64-msvc": "4.35.0", "@rollup/rollup-win32-ia32-msvc": "4.35.0", "@rollup/rollup-win32-x64-msvc": "4.35.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg=="], "rollup-plugin-dts": ["rollup-plugin-dts@6.1.1", "", { "dependencies": { "magic-string": "^0.30.10" }, "optionalDependencies": { "@babel/code-frame": "^7.24.2" }, "peerDependencies": { "rollup": "^3.29.4 || ^4", "typescript": "^4.5 || ^5.0" } }, "sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA=="], "rollup-plugin-visualizer": ["rollup-plugin-visualizer@5.14.0", "", { "dependencies": { "open": "^8.4.0", "picomatch": "^4.0.2", "source-map": "^0.7.4", "yargs": "^17.5.1" }, "peerDependencies": { "rolldown": "1.x", "rollup": "2.x || 3.x || 4.x" }, "optionalPeers": ["rolldown", "rollup"], "bin": { "rollup-plugin-visualizer": "dist/bin/cli.js" } }, "sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA=="], - "rrweb-cssom": ["rrweb-cssom@0.7.1", "", {}, "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg=="], + "rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="], "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], @@ -1177,7 +1187,7 @@ "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], - "std-env": ["std-env@3.8.0", "", {}, "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w=="], + "std-env": ["std-env@3.8.1", "", {}, "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA=="], "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], @@ -1213,39 +1223,39 @@ "symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="], + "synckit": ["synckit@0.9.2", "", { "dependencies": { "@pkgr/core": "^0.1.0", "tslib": "^2.6.2" } }, "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw=="], + "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="], "test-exclude": ["test-exclude@7.0.1", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^10.4.1", "minimatch": "^9.0.4" } }, "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg=="], - "text-table": ["text-table@0.2.0", "", {}, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="], - "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], "tinypool": ["tinypool@1.0.2", "", {}, "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA=="], - "tinyrainbow": ["tinyrainbow@1.2.0", "", {}, "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ=="], + "tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], "tinyspy": ["tinyspy@3.0.2", "", {}, "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q=="], - "tldts": ["tldts@6.1.78", "", { "dependencies": { "tldts-core": "^6.1.78" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-fSgYrW0ITH0SR/CqKMXIruYIPpNu5aDgUp22UhYoSrnUQwc7SBqifEBFNce7AAcygUPBo6a/gbtcguWdmko4RQ=="], + "tldts": ["tldts@6.1.83", "", { "dependencies": { "tldts-core": "^6.1.83" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-FHxxNJJ0WNsEBPHyC1oesQb3rRoxpuho/z2g3zIIAhw1WHJeQsUzK1jYK8TI1/iClaa4fS3Z2TCA9mtxXsENSg=="], - "tldts-core": ["tldts-core@6.1.78", "", {}, "sha512-jS0svNsB99jR6AJBmfmEWuKIgz91Haya91Z43PATaeHJ24BkMoNRb/jlaD37VYjb0mYf6gRL/HOnvS1zEnYBiw=="], + "tldts-core": ["tldts-core@6.1.83", "", {}, "sha512-I2wb9OJc6rXyh9d4aInhSNWChNI+ra6qDnFEGEwe9OoA68lE4Temw29bOkf1Uvwt8VZS079t1BFZdXVBmmB4dw=="], "tmp": ["tmp@0.0.33", "", { "dependencies": { "os-tmpdir": "~1.0.2" } }, "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], - "tough-cookie": ["tough-cookie@5.1.1", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA=="], + "tough-cookie": ["tough-cookie@5.1.2", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A=="], "tr46": ["tr46@5.0.0", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g=="], "ts-api-utils": ["ts-api-utils@2.0.1", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w=="], - "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="], + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="], @@ -1255,7 +1265,7 @@ "typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="], - "typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="], + "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="], @@ -1263,19 +1273,19 @@ "universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], - "update-browserslist-db": ["update-browserslist-db@1.1.2", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg=="], + "update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="], "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - "vite": ["vite@6.2.0", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ=="], + "vite": ["vite@6.2.1", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q=="], - "vite-node": ["vite-node@3.0.7", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.0", "es-module-lexer": "^1.6.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-2fX0QwX4GkkkpULXdT1Pf4q0tC1i1lFOyseKoonavXUNlQ77KpW2XqBGGNIm/J4Ows4KxgGJzDguYVPKwG/n5A=="], + "vite-node": ["vite-node@3.0.8", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.0", "es-module-lexer": "^1.6.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg=="], - "vite-plugin-static-copy": ["vite-plugin-static-copy@2.2.0", "", { "dependencies": { "chokidar": "^3.5.3", "fast-glob": "^3.2.11", "fs-extra": "^11.1.0", "picocolors": "^1.0.0" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0" } }, "sha512-ytMrKdR9iWEYHbUxs6x53m+MRl4SJsOSoMu1U1+Pfg0DjPeMlsRVx3RR5jvoonineDquIue83Oq69JvNsFSU5w=="], + "vite-plugin-static-copy": ["vite-plugin-static-copy@2.3.0", "", { "dependencies": { "chokidar": "^3.5.3", "fast-glob": "^3.2.11", "fs-extra": "^11.1.0", "p-map": "^7.0.3", "picocolors": "^1.0.0" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0" } }, "sha512-LLKwhhHetGaCnWz4mas4qqjjguDka6/6b4+SeIohRroj8aCE7QTfiZECfPecslFQkWZ3HdQuq5kOPmWZjNYlKA=="], - "vitest": ["vitest@3.0.7", "", { "dependencies": { "@vitest/expect": "3.0.7", "@vitest/mocker": "3.0.7", "@vitest/pretty-format": "^3.0.7", "@vitest/runner": "3.0.7", "@vitest/snapshot": "3.0.7", "@vitest/spy": "3.0.7", "@vitest/utils": "3.0.7", "chai": "^5.2.0", "debug": "^4.4.0", "expect-type": "^1.1.0", "magic-string": "^0.30.17", "pathe": "^2.0.3", "std-env": "^3.8.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinypool": "^1.0.2", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0", "vite-node": "3.0.7", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.0.7", "@vitest/ui": "3.0.7", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-IP7gPK3LS3Fvn44x30X1dM9vtawm0aesAa2yBIZ9vQf+qB69NXC5776+Qmcr7ohUXIQuLhk7xQR0aSUIDPqavg=="], + "vitest": ["vitest@3.0.8", "", { "dependencies": { "@vitest/expect": "3.0.8", "@vitest/mocker": "3.0.8", "@vitest/pretty-format": "^3.0.8", "@vitest/runner": "3.0.8", "@vitest/snapshot": "3.0.8", "@vitest/spy": "3.0.8", "@vitest/utils": "3.0.8", "chai": "^5.2.0", "debug": "^4.4.0", "expect-type": "^1.1.0", "magic-string": "^0.30.17", "pathe": "^2.0.3", "std-env": "^3.8.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinypool": "^1.0.2", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0", "vite-node": "3.0.8", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.0.8", "@vitest/ui": "3.0.8", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA=="], "w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="], @@ -1295,7 +1305,7 @@ "which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="], - "which-typed-array": ["which-typed-array@1.1.18", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.3", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA=="], + "which-typed-array": ["which-typed-array@1.1.19", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw=="], "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], @@ -1305,8 +1315,6 @@ "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - "ws": ["ws@8.18.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w=="], "xml-name-validator": ["xml-name-validator@5.0.0", "", {}, "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg=="], @@ -1327,6 +1335,10 @@ "@changesets/write/prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + + "@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="], + "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], "@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], @@ -1351,26 +1363,14 @@ "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="], - - "@vitest/expect/tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], - - "@vitest/pretty-format/tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], - - "@vitest/utils/tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], - "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], - "cssstyle/rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="], - "eslint/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], - "eslint-plugin-react/doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="], - "eslint-plugin-react/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], @@ -1381,6 +1381,8 @@ "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "p-filter/p-map": ["p-map@2.1.0", "", {}, "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw=="], + "p-locate/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], "postcss-discard-comments/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], @@ -1399,18 +1401,12 @@ "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], - "stylehacks/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], "test-exclude/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "vite/esbuild": ["esbuild@0.25.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.0", "@esbuild/android-arm": "0.25.0", "@esbuild/android-arm64": "0.25.0", "@esbuild/android-x64": "0.25.0", "@esbuild/darwin-arm64": "0.25.0", "@esbuild/darwin-x64": "0.25.0", "@esbuild/freebsd-arm64": "0.25.0", "@esbuild/freebsd-x64": "0.25.0", "@esbuild/linux-arm": "0.25.0", "@esbuild/linux-arm64": "0.25.0", "@esbuild/linux-ia32": "0.25.0", "@esbuild/linux-loong64": "0.25.0", "@esbuild/linux-mips64el": "0.25.0", "@esbuild/linux-ppc64": "0.25.0", "@esbuild/linux-riscv64": "0.25.0", "@esbuild/linux-s390x": "0.25.0", "@esbuild/linux-x64": "0.25.0", "@esbuild/netbsd-arm64": "0.25.0", "@esbuild/netbsd-x64": "0.25.0", "@esbuild/openbsd-arm64": "0.25.0", "@esbuild/openbsd-x64": "0.25.0", "@esbuild/sunos-x64": "0.25.0", "@esbuild/win32-arm64": "0.25.0", "@esbuild/win32-ia32": "0.25.0", "@esbuild/win32-x64": "0.25.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw=="], - "vite-plugin-static-copy/fs-extra": ["fs-extra@11.3.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew=="], - "vitest/tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], - "whatwg-encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], "@changesets/parse/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], @@ -1437,56 +1433,6 @@ "vite-plugin-static-copy/fs-extra/universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], - "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ=="], - - "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.0", "", { "os": "android", "cpu": "arm" }, "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g=="], - - "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.0", "", { "os": "android", "cpu": "arm64" }, "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g=="], - - "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.0", "", { "os": "android", "cpu": "x64" }, "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg=="], - - "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw=="], - - "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg=="], - - "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w=="], - - "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A=="], - - "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.0", "", { "os": "linux", "cpu": "arm" }, "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg=="], - - "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg=="], - - "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg=="], - - "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.0", "", { "os": "linux", "cpu": "none" }, "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw=="], - - "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.0", "", { "os": "linux", "cpu": "none" }, "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ=="], - - "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw=="], - - "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.0", "", { "os": "linux", "cpu": "none" }, "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA=="], - - "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA=="], - - "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.0", "", { "os": "linux", "cpu": "x64" }, "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw=="], - - "vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.0", "", { "os": "none", "cpu": "arm64" }, "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw=="], - - "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.0", "", { "os": "none", "cpu": "x64" }, "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA=="], - - "vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw=="], - - "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg=="], - - "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg=="], - - "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw=="], - - "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA=="], - - "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.0", "", { "os": "win32", "cpu": "x64" }, "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ=="], - "@manypkg/find-root/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], } } diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..0789c82b --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,53 @@ +import typescriptPlugin from '@typescript-eslint/eslint-plugin' +import parser from '@typescript-eslint/parser' +import reactPlugin from 'eslint-plugin-react' +import reactHooksPlugin from 'eslint-plugin-react-hooks' +import prettierPlugin from 'eslint-plugin-prettier' + +export default [ + { + files: ['**/*.{js,jsx,ts,tsx}'], + languageOptions: { + parser: parser, + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + }, + plugins: { + '@typescript-eslint': typescriptPlugin, + react: reactPlugin, + 'react-hooks': reactHooksPlugin, + prettier: prettierPlugin, + }, + settings: { + react: { + version: 'detect', // Automatically detect the React version + }, + }, + rules: { + ...typescriptPlugin.configs.recommended.rules, + ...reactPlugin.configs.recommended.rules, + ...reactHooksPlugin.configs.recommended.rules, + 'react/prop-types': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/max-params': ['error', { max: 4 }], + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], + indent: 'off', + semi: 'off', + quotes: 'off', + 'prettier/prettier': 'error', + }, + }, +] diff --git a/package.json b/package.json index 796ae450..6c5d15de 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { "scripts": { - "build": "vite build && bun run build:type", + "build": "vite build && bun run build:type && bun run build:combine-css", "build:type": "tsc -p tsconfig.build.json", + "build:combine-css": "node scripts/combine-css.js", "changeset": "changeset", "dev": "vite", "format": "prettier --write \"src/**/*.{ts,tsx,css}\"", @@ -15,9 +16,9 @@ "version": "changeset version" }, "peerDependencies": { - "react": "^19", - "react-dom": "^19", - "typescript": "^5.7.3" + "react": "^19.0.0", + "react-dom": "^19.0.0", + "typescript": "^5.8.2" }, "main": "dist/index.cjs", "engines": { @@ -47,32 +48,34 @@ }, "devDependencies": { "@changesets/cli": "^2.28.1", + "@eslint/js": "^9.21.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", - "@types/node": "^22.13.5", + "@types/node": "^22.13.9", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", - "@typescript-eslint/eslint-plugin": "^8.25.0", - "@typescript-eslint/parser": "^8.25.0", + "@typescript-eslint/eslint-plugin": "^8.26.0", + "@typescript-eslint/parser": "^8.26.0", "@vitejs/plugin-react-swc": "^3.8.0", - "@vitest/coverage-v8": "^2.1.9", + "@vitest/coverage-v8": "^3.0.8", "autoprefixer": "^10.4.20", "cssnano": "^7.0.6", - "eslint": "^8.57.1", - "eslint-config-prettier": "^9.1.0", + "eslint": "^9.0.0", + "eslint-config-prettier": "^10.1.1", + "eslint-plugin-prettier": "^5.2.3", "eslint-plugin-react": "^7.37.4", - "eslint-plugin-react-hooks": "^4.6.2", - "jsdom": "^25.0.1", - "prettier": "^3.5.2", - "rollup": "^4.34.8", + "eslint-plugin-react-hooks": "^5.2.0", + "jsdom": "^26.0.0", + "prettier": "^3.5.3", + "rollup": "^4.34.9", "rollup-plugin-dts": "^6.1.1", "rollup-plugin-visualizer": "^5.14.0", - "vite": "^6.2.0", - "vite-plugin-static-copy": "^2.2.0", - "vitest": "^3.0.7" + "vite": "6.2.1", + "vite-plugin-static-copy": "^2.3.0", + "vitest": "3.0.8" }, "name": "baseline-kit", - "version": "2.1.0", + "version": "3.0.0", "type": "module", "homepage": "https://github.com/dnvt/baseline-kit#readme", "types": "dist/index.d.ts", @@ -93,8 +96,32 @@ "require": "./dist/theme.css", "default": "./dist/theme.css" }, + "./theme/default": { + "import": "./dist/theme/default.css", + "require": "./dist/theme/default.css", + "default": "./dist/theme/default.css" + }, + "./theme/dark": { + "import": "./dist/theme/dark.css", + "require": "./dist/theme/dark.css", + "default": "./dist/theme/dark.css" + }, + "./theme/tokens": { + "import": "./dist/theme/tokens.css", + "require": "./dist/theme/tokens.css", + "default": "./dist/theme/tokens.css" + }, + "./full": { + "import": "./dist/baseline-kit.css", + "require": "./dist/baseline-kit.css", + "default": "./dist/baseline-kit.css" + }, "./dist/styles.css": "./dist/styles.css", "./dist/theme.css": "./dist/theme.css", + "./dist/theme/default.css": "./dist/theme/default.css", + "./dist/theme/dark.css": "./dist/theme/dark.css", + "./dist/theme/tokens.css": "./dist/theme/tokens.css", + "./dist/baseline-kit.css": "./dist/baseline-kit.css", "./package.json": "./package.json" }, "files": [ @@ -105,7 +132,11 @@ "style": "dist/styles.css", "sideEffects": [ "dist/styles.css", - "dist/theme.css" + "dist/theme.css", + "dist/theme/default.css", + "dist/theme/dark.css", + "dist/theme/tokens.css", + "dist/baseline-kit.css" ], "bugs": { "url": "https://github.com/dnvt/baseline-kit/issues" @@ -118,7 +149,7 @@ "author": "Francois Denavaut", "description": "Baseline Kit is a lightweight development tool for visualizing and debugging grid systems and spacing in React applications. It provides configurable overlays for both column-based and baseline grids, flexible spacing components, and theme-aware configuration—all optimized for performance and built with TypeScript.", "dependencies": { - "esbuild": "^0.24.2", + "esbuild": "^0.25.0", "postcss-preset-env": "^10.1.5" } } diff --git a/scripts/combine-css.js b/scripts/combine-css.js new file mode 100755 index 00000000..135d178d --- /dev/null +++ b/scripts/combine-css.js @@ -0,0 +1,96 @@ +#!/usr/bin/env node + +/** + * combine-css.js + * Script to: + * 1. Combine core.css and theme.css into a single baseline-kit.css file + * 2. Copy theme files to dist directory + */ + +import fs from 'fs' +import path from 'path' +import { fileURLToPath } from 'url' + +// Get the directory name +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +// Paths +const distDir = path.resolve(__dirname, '../dist') +const themeSourceDir = path.resolve(__dirname, '../src/components/styles/theme') +const themeDestDir = path.resolve(distDir, 'theme') +const coreCssPath = path.join(distDir, 'styles.css') +const themeCssPath = path.join(distDir, 'theme.css') +const combinedCssPath = path.join(distDir, 'baseline-kit.css') + +// Ensure dist directory exists +if (!fs.existsSync(distDir)) { + console.error('Error: dist directory does not exist') + process.exit(1) +} + +// Create theme directory in dist if it doesn't exist +if (!fs.existsSync(themeDestDir)) { + fs.mkdirSync(themeDestDir, { recursive: true }) +} + +// Helper function to check if a file exists +function checkFileExists(filePath, fileName) { + if (!fs.existsSync(filePath)) { + console.error(`Error: ${fileName} does not exist at ${filePath}`) + return false + } + return true +} + +// Check if input files exist +const coreExists = checkFileExists(coreCssPath, 'styles.css') +const themeExists = checkFileExists(themeCssPath, 'theme.css') + +if (!coreExists || !themeExists) { + process.exit(1) +} + +// Read input files +const coreCSS = fs.readFileSync(coreCssPath, 'utf8') +const themeCSS = fs.readFileSync(themeCssPath, 'utf8') + +// Combine CSS files +const combinedCSS = `/* Baseline Kit - Combined CSS */ +/* This file contains both core styles and theme */ + +/* Core Styles */ +${coreCSS} + +/* Theme */ +${themeCSS} +` + +// Write combined file +try { + fs.writeFileSync(combinedCssPath, combinedCSS) + console.log(`✅ Successfully created ${combinedCssPath}`) +} catch (error) { + console.error('Error writing combined CSS file:', error) + process.exit(1) +} + +// Copy individual theme files to dist/theme directory +try { + // Read all files in the theme source directory + const themeFiles = fs.readdirSync(themeSourceDir) + + // Copy each theme file to dist/theme + themeFiles.forEach((file) => { + if (file.endsWith('.css')) { + const sourcePath = path.join(themeSourceDir, file) + const destPath = path.join(themeDestDir, file) + fs.copyFileSync(sourcePath, destPath) + console.log(`✅ Copied ${file} to ${themeDestDir}`) + } + }) + + console.log(`✅ Successfully copied theme files to ${themeDestDir}`) +} catch (error) { + console.error('Error copying theme files:', error) +} diff --git a/src/components/Baseline/Baseline.tsx b/src/components/Baseline/Baseline.tsx index c357566c..2f1a4496 100644 --- a/src/components/Baseline/Baseline.tsx +++ b/src/components/Baseline/Baseline.tsx @@ -9,8 +9,7 @@ import { calculateRowCount, formatValue, createStyleOverride, - SSR_DIMENSIONS, - hydratedValue + ClientOnly, } from '@utils' import { Variant } from '../types' import styles from './styles.module.css' @@ -32,13 +31,11 @@ export type BaselineProps = { ssrMode?: boolean } & ComponentsProps -// Utils ----------------------------------------------------------------------- - /** Creates default baseline styles */ -export const createDefaultBaselineStyles = ( +const createDefaultBaselineStyles = ( base: number, lineColor: string, - flatColor: string, + flatColor: string ): Record => ({ '--bkbw': '100%', '--bkbh': '100%', @@ -50,25 +47,25 @@ export const createDefaultBaselineStyles = ( /** Create row styles for baseline lines */ type RowStyleParams = { /** Row index */ - index: number; + index: number /** Base unit for calculations */ - base: number; + base: number /** Baseline visual variant */ - variant: BaselineVariant; + variant: BaselineVariant /** Selected color for the baseline */ - chosenColor: string; + chosenColor: string /** Theme line color */ - lineColor: string; + lineColor: string /** Theme flat color */ - flatColor: string; + flatColor: string } /** * Creates styles for an individual baseline row. * Applies positioning and visual styling based on variant. */ -export const createBaselineRowStyle = ( - params: RowStyleParams, +const createBaselineRowStyle = ( + params: RowStyleParams ): React.CSSProperties => { const { index, base, variant, chosenColor, lineColor, flatColor } = params @@ -80,85 +77,54 @@ export const createBaselineRowStyle = ( } as React.CSSProperties } -/** - * Renders horizontal guidelines for maintaining vertical rhythm and baseline alignment. - * - * @remarks - * Baseline provides horizontal guides that: - * - Help maintain consistent vertical spacing - * - Support visual verification of baseline alignment - * - Optimize performance through virtual rendering - * - Adapt to container dimensions - * - * @example - * ```tsx - * // Basic baseline overlay - * - * - * // Custom variant with padding - * - * ``` - */ -export const Baseline = React.memo(function Baseline({ +// Implementation component that only renders on the client side +const BaselineImpl = React.memo(function BaselineImpl({ className, debugging, style, - variant: variantProp, + variant, height: heightProp, width: widthProp, - base: baseProp, + base, color: colorProp, - ssrMode = false, + ssrMode: _ssrMode = false, ...spacingProps }: BaselineProps) { const config = useConfig('baseline') - const variant = variantProp ?? config.variant - const base = baseProp ?? config.base const { isShown } = useDebug(debugging, config.debugging) // Use a stable reference that won't cause hydration mismatches const containerRef = React.useRef(null) - - // Use state to track if we're hydrated - const [isHydrated, setIsHydrated] = React.useState(false) - + // Always call hooks, but conditionally use their results - const measuredDimensions = useMeasure(containerRef) - - // After hydration, we can use real measurement + const { + width: containerWidth, + height: containerHeight, + refresh, + } = useMeasure(containerRef) + + // Effect for handling window resize events React.useEffect(() => { - setIsHydrated(true) - }, []) - - // Choose appropriate dimensions based on rendering environment using our utility - const dimensions = hydratedValue( - isHydrated, - SSR_DIMENSIONS, - measuredDimensions - ) - - const { width: containerWidth, height: containerHeight } = dimensions + const handleResize = () => { + refresh() + } + + window.addEventListener('resize', handleResize) + return () => { + window.removeEventListener('resize', handleResize) + } + }, [refresh]) const [_normWidth, normHeight] = React.useMemo(() => { return normalizeValuePair( [widthProp, heightProp], - [containerWidth, containerHeight], + [containerWidth, containerHeight] ) }, [widthProp, heightProp, containerWidth, containerHeight]) const { top, right, bottom, left } = React.useMemo( () => parsePadding(spacingProps), - [spacingProps], + [spacingProps] ) const padding = React.useMemo(() => { @@ -170,46 +136,35 @@ export const Baseline = React.memo(function Baseline({ }, [top, right, bottom, left]) const rowCount = React.useMemo(() => { + const baseValue = base || config.base return calculateRowCount({ height: normHeight, top, bottom, - base, + base: baseValue, }) - }, [normHeight, top, bottom, base]) + }, [normHeight, top, bottom, base, config.base]) - // Always call useVirtual but potentially use simpler values - const virtualResult = useVirtual({ + // Use virtual rendering for performance + const { start, end } = useVirtual({ totalLines: rowCount, - lineHeight: base, + lineHeight: base || config.base, containerRef, buffer: 160, }) - - // For SSR, use simplistic settings that match between server/client - const stableVirtualResult = { - start: 0, - end: Math.min(10, rowCount) - } - - // Choose appropriate virtualization based on environment - const { start, end } = hydratedValue( - isHydrated && !ssrMode, - stableVirtualResult, - virtualResult - ) - const chosenColor = colorProp || - (variant === 'line' ? config.colors.line : config.colors.flat) + const chosenColor = + colorProp || (variant === 'line' ? config.colors.line : config.colors.flat) // Create default baseline styles const defaultBaselineStyles = React.useMemo( - () => createDefaultBaselineStyles( - base, - config.colors.line, - config.colors.flat, - ), - [base, config.colors.line, config.colors.flat], + () => + createDefaultBaselineStyles( + base || config.base, + config.colors.line, + config.colors.flat + ), + [base, config.colors.line, config.colors.flat, config.base] ) const containerStyles = React.useMemo(() => { @@ -250,7 +205,7 @@ export const Baseline = React.memo(function Baseline({ }), ...(padding && { padding }), } as React.CSSProperties, - style, + style ) }, [ widthProp, @@ -266,16 +221,27 @@ export const Baseline = React.memo(function Baseline({ const getRowStyle = React.useCallback( (index: number) => { + // Ensure variant is a BaselineVariant + const safeVariant = variant as BaselineVariant + const safeBase = base || config.base + return createBaselineRowStyle({ index, - base, - variant, + base: safeBase, + variant: safeVariant, chosenColor, lineColor: config.colors.line, flatColor: config.colors.flat, }) }, - [base, variant, chosenColor, config.colors.line, config.colors.flat], + [ + base, + variant, + chosenColor, + config.colors.line, + config.colors.flat, + config.base, + ] ) return ( @@ -285,7 +251,7 @@ export const Baseline = React.memo(function Baseline({ className={mergeClasses( styles.bas, isShown ? styles.v : styles.h, - className, + className )} style={containerStyles} {...spacingProps} @@ -305,3 +271,94 @@ export const Baseline = React.memo(function Baseline({ ) }) + +/** + * Renders horizontal guidelines for maintaining vertical rhythm and baseline alignment. + * + * @remarks + * Baseline provides horizontal guides that: + * - Help maintain consistent vertical spacing + * - Support visual verification of baseline alignment + * - Optimize performance through virtual rendering + * - Adapt to container dimensions + * + * @example + * ```tsx + * // Basic baseline overlay + * + * + * // Custom variant with padding + * + * ``` + */ +export const Baseline = React.memo(function Baseline({ + className, + debugging, + style, + variant: variantProp, + height: heightProp, + width: widthProp, + base: baseProp, + color: colorProp, + ssrMode = false, + ...spacingProps +}: BaselineProps) { + const config = useConfig('baseline') + const variant = variantProp ?? config.variant + const base = baseProp ?? config.base + const { isShown } = useDebug(debugging, config.debugging) + + // If debugging isn't enabled, render a hidden element + // This ensures tests can find the element even when hidden + if (!isShown) { + return ( +
+ ) + } + + // Create a simple SSR fallback + const ssrFallback = ( +
+ ) + + // Wrap the actual implementation in ClientOnly + return ( + + + + ) +}) diff --git a/src/components/Baseline/index.ts b/src/components/Baseline/index.ts index d80c1de5..6fb4b8ca 100644 --- a/src/components/Baseline/index.ts +++ b/src/components/Baseline/index.ts @@ -4,4 +4,4 @@ * @module baseline-kit/components/Baseline */ -export * from './Baseline' \ No newline at end of file +export * from './Baseline' diff --git a/src/components/Baseline/styles.module.css b/src/components/Baseline/styles.module.css index 05113d01..e4c1563d 100644 --- a/src/components/Baseline/styles.module.css +++ b/src/components/Baseline/styles.module.css @@ -13,5 +13,14 @@ position: absolute; top: var(--bkrt); height: var(--bkrh); - background-color: var(--bkbcl); + background-color: var(--bkbc); +} + +/* Style for SSR rendering */ +.ssr { + box-sizing: border-box; + display: grid; + position: relative; + z-index: 1; + pointer-events: none; } diff --git a/src/components/Box/Box.tsx b/src/components/Box/Box.tsx index ca19cc10..2e825289 100644 --- a/src/components/Box/Box.tsx +++ b/src/components/Box/Box.tsx @@ -8,9 +8,9 @@ import { formatValue, createGridSpanStyles, createStyleOverride, - hydratedValue + hydratedValue, } from '@utils' -import { Config } from '../Config' +import { Config } from '../Config/Config' import { Padder } from '../Padder' import { ComponentsProps } from '../types' import styles from './styles.module.css' @@ -25,7 +25,7 @@ import styles from './styles.module.css' */ export type SnappingMode = 'none' | 'height' | 'clamp' -type BoxProps = { +export type BoxProps = { /** Number of columns to span in a grid layout */ colSpan?: number /** Number of rows to span in a grid layout */ @@ -39,75 +39,72 @@ type BoxProps = { children?: React.ReactNode } & ComponentsProps -// Utils ----------------------------------------------------------------------- - /** * Creates default box styles with theme values. * Sets CSS variables for width, height, base unit, and colors. */ -export const createDefaultBoxStyles = ( +const createDefaultBoxStyles = ( base: number, lineColor: string ): Record => ({ - '--bkxw': 'fit-content', - '--bkxh': 'fit-content', - '--bkxb': `${base}px`, - '--bkxcl': lineColor, + '--bkboxw': 'auto', + '--bkboxh': 'auto', + '--bkboxc': lineColor, + '--bkboxb': `${base}px`, }) -/** Parameters for creating box custom styles */ type BoxCustomStylesParams = { /** Width property for the box */ - width?: React.CSSProperties['width']; + width?: React.CSSProperties['width'] /** Height property for the box */ - height?: React.CSSProperties['height']; + height?: React.CSSProperties['height'] /** Base unit for measurements */ - base: number; + base: number /** Line color from theme */ - lineColor: string; + lineColor: string /** Default styles for comparison */ - defaultStyles: Record; + defaultStyles: Record } /** - * Creates custom styles for the box. - * Combines all style properties and only applies changes when needed. + * Creates custom styles for the Box component. + * Handles dimension overrides and other custom properties. */ -export const createBoxCustomStyles = ({ +const createBoxCustomStyles = ({ width, height, base, lineColor, - defaultStyles + defaultStyles, }: BoxCustomStylesParams): React.CSSProperties => { const widthValue = formatValue(width || 'fit-content') const heightValue = formatValue(height || 'fit-content') // Define box dimensions that should be skipped when set to fit-content - const dimensionVars = ['--bkxw', '--bkxh'] + const dimensionVars = ['--bkboxw', '--bkboxh'] return { ...createStyleOverride({ - key: '--bkxw', + key: '--bkboxw', value: widthValue, defaultStyles, - skipDimensions: { fitContent: dimensionVars } + skipDimensions: { fitContent: dimensionVars }, }), ...createStyleOverride({ - key: '--bkxh', + key: '--bkboxh', value: heightValue, defaultStyles, - skipDimensions: { fitContent: dimensionVars } + skipDimensions: { fitContent: dimensionVars }, }), ...createStyleOverride({ - key: '--bkxb', + key: '--bkboxb', value: `${base}px`, - defaultStyles + defaultStyles, }), ...createStyleOverride({ - key: '--bkxcl', + key: '--bkboxc', value: lineColor, - defaultStyles + defaultStyles, }), } as React.CSSProperties } @@ -158,21 +155,21 @@ export const Box = React.memo( ssrMode = false, ...spacingProps }, - ref, + ref ) { const config = useConfig('box') const { isShown, debugging } = useDebug(debuggingProp, config.debugging) // Add hydration state tracking const [isHydrated, setIsHydrated] = React.useState(false) - + React.useEffect(() => { setIsHydrated(true) }, []) const internalRef = React.useRef(null) const { top, bottom, left, right } = parsePadding(spacingProps) - + // Get padding calculation from useBaseline const baselinePadding = useBaseline(internalRef, { base: config.base, @@ -180,17 +177,17 @@ export const Box = React.memo( spacing: { top, bottom, left, right }, warnOnMisalignment: debugging !== 'none', }) - + // Create stable initial padding for SSR const stablePadding = { padding: { top: top || 0, right: right || 0, bottom: bottom || 0, - left: left || 0 - } + left: left || 0, + }, } - + // Use stable padding during SSR and initial render, then switch to dynamic padding const { padding } = hydratedValue( isHydrated && !ssrMode, @@ -208,19 +205,23 @@ export const Box = React.memo( [config.base, config.colors.line] ) - const boxStyles = React.useMemo( - () => { - const customStyles = createBoxCustomStyles({ - width, - height, - base: config.base, - lineColor: config.colors.line, - defaultStyles: defaultBoxStyles - }) - return mergeStyles(customStyles, style) - }, - [config.base, config.colors.line, width, height, defaultBoxStyles, style] - ) + const boxStyles = React.useMemo(() => { + const customStyles = createBoxCustomStyles({ + width, + height, + base: config.base, + lineColor: config.colors.line, + defaultStyles: defaultBoxStyles, + }) + return mergeStyles(customStyles, style) + }, [ + config.base, + config.colors.line, + width, + height, + defaultBoxStyles, + style, + ]) return (
- +
) - }), + }) ) diff --git a/src/components/Box/styles.module.css b/src/components/Box/styles.module.css index 392f3225..d20895ac 100644 --- a/src/components/Box/styles.module.css +++ b/src/components/Box/styles.module.css @@ -11,4 +11,4 @@ border: 1px solid var(--bkxcl); pointer-events: none; z-index: var(--bkzi); -} \ No newline at end of file +} diff --git a/src/components/Config/Config.tsx b/src/components/Config/Config.tsx index 34be66be..abf74128 100644 --- a/src/components/Config/Config.tsx +++ b/src/components/Config/Config.tsx @@ -16,82 +16,82 @@ export type DebuggingMode = 'none' | 'hidden' | 'visible' /** Color configuration for component themes. */ type Colors = { /** Color for line-based visuals */ - line: string; + line: string /** Color for flat surface visuals */ - flat: string; + flat: string /** Color for measurement indicators */ - text: string; + text: string } /** Complete configuration schema for baseline-kit. */ -export type Config = { +export type ConfigSchema = { /** Base unit for spacing calculations */ - base: number; + base: number /** Guide component configuration */ guide: { - variant: GuideVariant; - debugging: DebuggingMode; - colors: Record; - }; + variant: GuideVariant + debugging: DebuggingMode + colors: Record + } /** Baseline component configuration */ baseline: { - variant: BaselineVariant; - debugging: DebuggingMode; - colors: Record; - }; + variant: BaselineVariant + debugging: DebuggingMode + colors: Record + } /** Stack component configuration */ stack: { - colors: Colors; - debugging: DebuggingMode; - }; + colors: Colors + debugging: DebuggingMode + } /** Layout component configuration */ layout: { - colors: Colors; - debugging: DebuggingMode; - }; + colors: Colors + debugging: DebuggingMode + } /** Spacer component configuration */ spacer: { - variant: Variant; - debugging: DebuggingMode; - colors: Colors; - }; + variant: Variant + debugging: DebuggingMode + colors: Colors + } /** Box component configuration */ box: { - colors: Colors; - debugging: DebuggingMode; - }; + colors: Colors + debugging: DebuggingMode + } /** Padder component configuration */ padder: { - color: string; - debugging: DebuggingMode; - }; + color: string + debugging: DebuggingMode + } } // Create the context -const ConfigContext = React.createContext(DEFAULT_CONFIG) +const ConfigContext = React.createContext(DEFAULT_CONFIG) ConfigContext.displayName = 'ConfigContext' // Update to use React 19's use hook instead of useContext export const useDefaultConfig = () => React.use(ConfigContext) type ConfigProps = { - children: React.ReactNode; + children: React.ReactNode /** Base unit for spacing calculations */ - base?: number; + base?: number /** Baseline component overrides */ - baseline?: Partial; + baseline?: Partial /** Flex component overrides */ - stack?: Partial; + stack?: Partial /** Layout component overrides */ - layout?: Partial; + layout?: Partial /** Guide component overrides */ - guide?: Partial; + guide?: Partial /** Spacer component overrides */ - spacer?: Partial; + spacer?: Partial /** Box component overrides */ - box?: Partial; + box?: Partial /** Padder component overrides */ - padder?: Partial; + padder?: Partial } // Utils ----------------------------------------------------------------------- @@ -99,40 +99,31 @@ type ConfigProps = { /** Parameters for creating CSS variables */ type CSSVariablesParams = { /** Base unit for spacing calculations */ - base: number; + base: number /** Baseline component configuration */ - baseline: Config['baseline']; + baseline: ConfigSchema['baseline'] /** Guide component configuration */ - guide: Config['guide']; + guide: ConfigSchema['guide'] /** Stack component configuration */ - stack: Config['stack']; + stack: ConfigSchema['stack'] /** Spacer component configuration */ - spacer: Config['spacer']; + spacer: ConfigSchema['spacer'] /** Layout component configuration */ - layout: Config['layout']; + layout: ConfigSchema['layout'] /** Box component configuration */ - box: Config['box']; + box: ConfigSchema['box'] /** Padder component configuration */ - padder: Config['padder']; + padder: ConfigSchema['padder'] } -/** +/** * Creates CSS variables from the configuration object. * These variables are used throughout the component library. */ export const createCSSVariables = ( params: CSSVariablesParams ): Record => { - const { - base, - baseline, - guide, - stack, - spacer, - layout, - box, - padder, - } = params + const { base, baseline, guide, stack, spacer, layout, box, padder } = params return { '--bkb': `${base}px`, @@ -175,30 +166,30 @@ export const createCSSVariables = ( /** Parameters for merging configuration */ type MergeConfigParams = { /** Parent configuration to extend */ - parentConfig: Config; + parentConfig: ConfigSchema /** Base unit override */ - base?: number; + base?: number /** Baseline component overrides */ - baseline?: Partial; + baseline?: Partial /** Guide component overrides */ - guide?: Partial; + guide?: Partial /** Spacer component overrides */ - spacer?: Partial; + spacer?: Partial /** Box component overrides */ - box?: Partial; + box?: Partial /** Stack component overrides */ - stack?: Partial; + stack?: Partial /** Layout component overrides */ - layout?: Partial; + layout?: Partial /** Padder component overrides */ - padder?: Partial; + padder?: Partial } -/** +/** * Merges parent config with overrides. * Creates a new config object without mutating the parent. */ -export const mergeConfig = (params: MergeConfigParams): Config => { +export const mergeConfig = (params: MergeConfigParams): ConfigSchema => { const { parentConfig, base, @@ -291,21 +282,7 @@ export function Config({ layout, padder, }) - }, [ - parentConfig, - base, - baseline, - guide, - spacer, - box, - stack, - layout, - padder, - ]) + }, [parentConfig, base, baseline, guide, spacer, box, stack, layout, padder]) - return ( - - {children} - - ) -} \ No newline at end of file + return {children} +} diff --git a/src/components/Config/defaults.ts b/src/components/Config/defaults.ts index 7821231f..1cc34b4d 100644 --- a/src/components/Config/defaults.ts +++ b/src/components/Config/defaults.ts @@ -4,7 +4,7 @@ * @module baseline-kit/components/Config */ -import type { Config } from './Config' +import type { ConfigSchema } from './Config' /** * CSS variable-based color configuration for Guide component. @@ -100,7 +100,7 @@ const PADDER_COLOR = 'var(--bk-padder-color-theme)' * The configuration is marked as const to ensure type safety * and prevent accidental modifications. */ -export const DEFAULT_CONFIG: Config = { +export const DEFAULT_CONFIG: ConfigSchema = { /** Base unit for spacing calculations (in pixels) */ base: 8, @@ -148,4 +148,4 @@ export const DEFAULT_CONFIG: Config = { debugging: 'hidden', color: PADDER_COLOR, }, -} as const \ No newline at end of file +} as const diff --git a/src/components/Config/index.ts b/src/components/Config/index.ts index 014727b0..e752c620 100644 --- a/src/components/Config/index.ts +++ b/src/components/Config/index.ts @@ -9,4 +9,4 @@ */ export * from './Config' -export * from './defaults' \ No newline at end of file +export { DEFAULT_CONFIG } from './defaults' diff --git a/src/components/Guide/Guide.tsx b/src/components/Guide/Guide.tsx index 371f03b8..3301a251 100644 --- a/src/components/Guide/Guide.tsx +++ b/src/components/Guide/Guide.tsx @@ -1,23 +1,19 @@ import * as React from 'react' -import { - useConfig, - useDebug, - useGuide, - useMeasure, -} from '@hooks' +import { ComponentsProps } from '@components' +import { useConfig, useDebug, useGuide, useMeasure } from '@hooks' import { formatValue, mergeClasses, mergeStyles, createStyleOverride, - hydratedValue + ClientOnly, } from '@utils' import { AutoConfig, FixedConfig, LineConfig, PatternConfig } from './types' -import type { ComponentsProps, GuideVariant } from '../types' +import type { GuideVariant } from '../types' import styles from './styles.module.css' /** Merged configuration types that support various grid layout strategies */ -export type GuideConfig = PatternConfig | AutoConfig | FixedConfig | LineConfig; +export type GuideConfig = PatternConfig | AutoConfig | FixedConfig | LineConfig export type GuideProps = { /** Controls horizontal alignment of columns within the container */ @@ -28,8 +24,6 @@ export type GuideProps = { columns?: number | readonly (string | number | undefined | 'auto')[] /** Column width (for fixed variant) */ columnWidth?: React.CSSProperties['width'] - /** Gutter width between columns */ - gutterWidth?: React.CSSProperties['width'] /** Maximum width of the guide */ maxWidth?: React.CSSProperties['maxWidth'] /** Color override for guide lines */ @@ -40,68 +34,74 @@ export type GuideProps = { gap?: number /** Flag to enable SSR-compatible mode (simplified initial render) */ ssrMode?: boolean -} & ComponentsProps & Omit; +} & ComponentsProps & + Omit /** Parameters for creating a grid configuration */ type GridConfigParams = { - variant: GuideVariant; - base: number; - gap: number; - columns?: number | readonly (string | number | undefined | 'auto')[]; - columnWidth?: React.CSSProperties['width']; + variant: GuideVariant + base: number + gap: number + columns?: number | readonly (string | number | undefined | 'auto')[] + columnWidth?: React.CSSProperties['width'] } -// Utils ----------------------------------------------------------------------- - -/** Creates the appropriate grid configuration based on variant */ -export const createGridConfig = ( - params: GridConfigParams, -): (PatternConfig | AutoConfig | FixedConfig | LineConfig) => { +/** + * Creates a grid configuration based on the specified variant and parameters + * Internal helper function for Guide component + */ +const createGridConfig = ( + params: GridConfigParams +): PatternConfig | AutoConfig | FixedConfig | LineConfig => { const { variant, base, gap, columns, columnWidth } = params - return { - line: { - variant: 'line' as const, - gap: gap - 1, - base, - }, - auto: columnWidth - ? { - variant: 'auto' as const, - columnWidth, - gap, - base, - } - : null, - pattern: Array.isArray(columns) - ? { - variant: 'pattern' as const, - columns, + switch (variant) { + case 'line': + return { + variant: 'line', gap, base, + } as LineConfig + + case 'pattern': + if (columns && Array.isArray(columns)) { + return { + variant: 'pattern', + columns: columns as readonly (string | number)[], + gap, + base, + } as PatternConfig } - : null, - fixed: - typeof columns === 'number' - ? { - variant: 'fixed' as const, - columns, - columnWidth, + break + + case 'fixed': + if (columns !== undefined) { + const parsedColumns = + typeof columns === 'number' ? columns : parseInt(String(columns), 10) + return { + variant: 'fixed', + columns: !isNaN(parsedColumns) ? parsedColumns : 12, + columnWidth: columnWidth || '60px', gap, base, - } - : null, - }[variant] ?? { - variant: 'line' as const, - gap: gap - 1, - base, + } as FixedConfig + } + break } + + // Default to auto columns if no valid configuration was created + return { + variant: 'auto', + columnWidth: columnWidth || '1fr', + gap, + base, + } as AutoConfig } /** Creates default guide styles */ -export const createDefaultGuideStyles = ( +const createDefaultGuideStyles = ( base: number, - lineColor: string, + lineColor: string ): Record => ({ '--bkgw': 'auto', '--bkgh': 'auto', @@ -111,6 +111,7 @@ export const createDefaultGuideStyles = ( '--bkgc': '12', '--bkgb': `${base}px`, '--bkgcl': lineColor, + '--bkgg': '0', }) /** @@ -161,13 +162,12 @@ export const Guide = React.memo(function Guide({ debugging, style, variant: variantProp, - align = 'start', + align = 'center', gap: gapProp, height, width, columns, columnWidth, - gutterWidth, maxWidth, color, children, @@ -176,51 +176,132 @@ export const Guide = React.memo(function Guide({ }: GuideProps) { const config = useConfig('guide') const variant = variantProp ?? config.variant - const gap = typeof gapProp === 'number' ? gapProp : config.base - - // Add hydration state tracking - const [isHydrated, setIsHydrated] = React.useState(false) - - React.useEffect(() => { - setIsHydrated(true) - }, []) + const gap = typeof gapProp === 'number' ? gapProp : 0 + const { isShown } = useDebug(debugging, config.debugging) - const containerRef = React.useRef(null) - - // Always call useMeasure, but conditionally use its results - const measuredDimensions = useMeasure(containerRef) - - // Choose appropriate dimensions based on rendering environment - const dimensions = hydratedValue( - isHydrated && !ssrMode, - { width: 1024, height: 768, refresh: () => {} }, - measuredDimensions + // If debugging isn't enabled, render a hidden element + // This ensures tests can find the element even when hidden + if (!isShown) { + return ( +
+ {children} +
+ ) + } + + // Create a simple SSR fallback with the expected dimensions + const ssrFallback = ( +
+ {children} +
) - - const { width: containerWidth, height: containerHeight } = dimensions + // Wrap the actual implementation in ClientOnly + return ( + + + {children} + + + ) +}) + +// Implementation component that only renders on the client side +const GuideImpl = React.memo(function GuideImpl({ + className, + debugging, + style, + variant, + align = 'center', + gap, + height, + width, + columns, + columnWidth, + maxWidth, + color, + children, + ssrMode: _ssrMode = false, + ...props +}: GuideProps) { + const config = useConfig('guide') const { isShown } = useDebug(debugging, config.debugging) + const containerRef = React.useRef(null) + + // Measure the container dimensions + const { + width: containerWidth, + height: containerHeight, + refresh, // Keep the refresh function available for dynamic updates + } = useMeasure(containerRef) + + // Effect for handling window resize events + React.useEffect(() => { + const handleResize = () => { + // Trigger a remeasurement when window size changes + refresh() + } + + window.addEventListener('resize', handleResize) + return () => { + window.removeEventListener('resize', handleResize) + } + }, [refresh]) // Create guide configuration based on variant const gridConfig = React.useMemo(() => { + // Ensure we have valid values for the grid configuration + const safeVariant = variant as GuideVariant + const safeGap = typeof gap === 'number' ? gap : 0 + return createGridConfig({ - variant, + variant: safeVariant, base: config.base, - gap, + gap: safeGap, columns, columnWidth, }) }, [variant, config.base, gap, columns, columnWidth]) - const { - template, - columnsCount, - calculatedGap, - } = useGuide(containerRef, gridConfig) + const { template, columnsCount, calculatedGap } = useGuide( + containerRef, + gridConfig + ) const defaultStyles = React.useMemo( () => createDefaultGuideStyles(config.base, config.colors.line), - [config.base, config.colors.line], + [config.base, config.colors.line] ) const containerStyles = React.useMemo(() => { @@ -229,7 +310,6 @@ export const Guide = React.memo(function Guide({ const heightValue = formatValue(height || containerHeight || 'auto') const maxWidthValue = formatValue(maxWidth || 'none') const columnWidthValue = formatValue(columnWidth || '60px') - const gutterWidthValue = formatValue(gutterWidth || '24px') // Define dimensions that should be skipped when set to auto const autoDimensions = ['--bkgw', '--bkgh'] @@ -258,11 +338,6 @@ export const Guide = React.memo(function Guide({ value: columnWidthValue, defaultStyles, }), - ...createStyleOverride({ - key: '--bkggw', - value: gutterWidthValue, - defaultStyles, - }), ...createStyleOverride({ key: '--bkgc', value: `${columnsCount}`, @@ -270,7 +345,7 @@ export const Guide = React.memo(function Guide({ }), ...createStyleOverride({ key: '--bkgb', - value: `${config.base}px`, + value: `0`, defaultStyles, }), ...createStyleOverride({ @@ -278,15 +353,21 @@ export const Guide = React.memo(function Guide({ value: color ?? config.colors.line, defaultStyles, }), - // Add the CSS variables expected by tests - '--bkgg': `${calculatedGap}px`, + ...createStyleOverride({ + key: '--bkgg', + value: `${calculatedGap}px`, + defaultStyles, + }), + ...createStyleOverride({ + key: '--bkgj', + value: align || 'center', + defaultStyles, + }), ...(template && template !== 'none' ? { '--bkgt': template } : {}), // Add grid template if available - ...(template && template !== 'none' ? { gridTemplateColumns: template } : {}), - // Add gap if calculated - ...(calculatedGap ? { gap: `${calculatedGap}px` } : {}), - // Add justifyContent based on align - justifyContent: align, + ...(template && template !== 'none' + ? { gridTemplateColumns: template } + : {}), } as React.CSSProperties return mergeStyles(customStyles, style) @@ -295,20 +376,63 @@ export const Guide = React.memo(function Guide({ height, maxWidth, columnWidth, - gutterWidth, columnsCount, color, template, calculatedGap, containerWidth, containerHeight, - config.base, config.colors.line, defaultStyles, style, align, ]) + // In the component where gap is used: + const handleGapCalculations = () => { + // Ensure gap is a number + const safeGap = typeof gap === 'number' ? gap : 0 + + // When gap is 0, we need width + 1 columns to fill the space + // When gap > 0, we need to account for the -1px reduction in each gap + const finalGap = safeGap === 0 ? 0 : safeGap - 1 + const actualGapWithLine = finalGap + 1 + + // Rest of the gap calculations... + return { finalGap, actualGapWithLine } + } + + // Use the gap calculations where needed + const { finalGap, actualGapWithLine } = handleGapCalculations() + + // Ensure width is a number + const containerWidthValue = + typeof width === 'number' ? width : containerWidth || 1024 + + // For line variants, account for the -1px reduction in each gap + // If we have N columns, we have (N-1) gaps, each reduced by 1px + // So the total width lost is (N-1) pixels + let columnCount: number + + if (finalGap === 0) { + // When gap is 0, we need a column per pixel + 1 + columnCount = Math.floor(containerWidthValue) + 1 + } else if (variant === 'line') { + // For line variant with gap > 0: + // We need to solve for N in: N * actualGapWithLine - (N-1) = containerWidthValue + // Which simplifies to: N = (containerWidthValue + 1) / (actualGapWithLine - 1 + 1) + columnCount = Math.max( + 1, + Math.floor((containerWidthValue + 1) / actualGapWithLine) + 1 + ) + } else { + // For other variants, use the standard formula + columnCount = Math.max( + 1, + Math.floor(containerWidthValue / actualGapWithLine) + 1 + ) + } + return (
{isShown && (
- {Array.from({ length: columnsCount }, (_, i) => { + {Array.from({ length: columnCount }, (_, i) => { const colColor = - config.colors[variant as keyof typeof config.colors] ?? config.colors.line + config.colors[variant as keyof typeof config.colors] ?? + config.colors.line return (
{ +export const isValidGuideColumnValue = ( + value: unknown +): value is GuideColumnValue => { if (typeof value === 'number') return Number.isFinite(value) && value >= 0 if (typeof value !== 'string') return false return value === 'auto' || value === '100%' || UNIT_PATTERN.test(value) @@ -47,8 +50,12 @@ export const isValidGuideColumnValue = (value: unknown): value is GuideColumnVal * isValidGuidePattern([]) // false * ``` */ -export const isValidGuidePattern = (pattern: unknown): pattern is GuideColumnsPattern => - Array.isArray(pattern) && pattern.length > 0 && pattern.every(isValidGuideColumnValue) +export const isValidGuidePattern = ( + pattern: unknown +): pattern is GuideColumnsPattern => + Array.isArray(pattern) && + pattern.length > 0 && + pattern.every(isValidGuideColumnValue) /** * Validates CSS grid values against supported units. @@ -61,10 +68,14 @@ export const isValidGuidePattern = (pattern: unknown): pattern is GuideColumnsPa * ``` */ export const isGuideValue = (value: unknown) => { - const CSS_UNITS = [...Object.keys(ABSOLUTE_UNIT_CONVERSIONS), ...RELATIVE_UNITS] + const CSS_UNITS = [ + ...Object.keys(ABSOLUTE_UNIT_CONVERSIONS), + ...RELATIVE_UNITS, + ] return ( typeof value === 'number' || - (typeof value === 'string' && CSS_UNITS.some(unit => value.endsWith(unit))) + (typeof value === 'string' && + CSS_UNITS.some((unit) => value.endsWith(unit))) ) } @@ -124,4 +135,4 @@ export const isAutoCalculatedGuide = (config: unknown): config is GuideConfig => isObject(config) && 'columnWidth' in config && !('variant' in config) && - !('columns' in config) \ No newline at end of file + !('columns' in config) diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index f955749c..23927fd0 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -7,7 +7,7 @@ import { parsePadding, formatValue, createStyleOverride, - hydratedValue + hydratedValue, } from '@utils' import { Config } from '../Config' import { Padder } from '../Padder' @@ -16,7 +16,9 @@ import { ComponentsProps, Variant } from '../types' import styles from './styles.module.css' // Import the IndicatorNode type from Spacer props -type IndicatorNode = NonNullable['indicatorNode']> +type IndicatorNode = NonNullable< + React.ComponentProps['indicatorNode'] +> export type LayoutProps = { /** @@ -47,15 +49,14 @@ export type LayoutProps = { /** Container height (defaults to "auto") */ height?: React.CSSProperties['height'] children?: React.ReactNode -} & ComponentsProps & Gaps - -// Utils ----------------------------------------------------------------------- +} & ComponentsProps & + Gaps /** Creates default layout styles with theme colors */ -export const createDefaultLayoutStyles = (colors: { - line: string; - flat: string; - text: string; +const createDefaultLayoutStyles = (colors: { + line: string + flat: string + text: string }): Record => ({ '--bklw': 'auto', '--bklh': 'auto', @@ -65,20 +66,22 @@ export const createDefaultLayoutStyles = (colors: { }) /** Parses grid template definitions into CSS grid-template values. */ -export const getGridTemplate = (prop?: number | string | Array): string => { +const getGridTemplate = ( + prop?: number | string | Array +): string => { if (typeof prop === 'number') return `repeat(${prop}, 1fr)` if (typeof prop === 'string') return prop if (Array.isArray(prop)) { return prop.map((p) => (typeof p === 'number' ? `${p}px` : p)).join(' ') } - return 'repeat(auto-fit, minmax(100px, 1fr))' + return 'repeat(auto-fill, minmax(100px, 1fr))' } /** Creates grid gap styles */ -export const createGridGapStyles = ( +const createGridGapStyles = ( gap?: React.CSSProperties['gap'] | number, rowGap?: React.CSSProperties['rowGap'] | number, - columnGap?: React.CSSProperties['columnGap'] | number, + columnGap?: React.CSSProperties['columnGap'] | number ): Record => { const styles: Record = {} @@ -136,7 +139,7 @@ export const Layout = React.memo(function Layout({ alignItems, children, className, - columns = 'repeat(auto-fit, minmax(100px, 1fr))', + columns = 'repeat(auto-fill, minmax(100px, 1fr))', columnGap, debugging: debuggingProp, gap, @@ -154,21 +157,21 @@ export const Layout = React.memo(function Layout({ }: LayoutProps) { const config = useConfig('layout') const { isShown, debugging } = useDebug(debuggingProp, config.debugging) - + // Add hydration state tracking const [isHydrated, setIsHydrated] = React.useState(false) - + React.useEffect(() => { setIsHydrated(true) }, []) - + const layoutRef = React.useRef(null) const initialPadding = React.useMemo( () => parsePadding(spacingProps), - [spacingProps], + [spacingProps] ) - + // Get padding calculation from useBaseline const baselinePadding = useBaseline(layoutRef, { base: config.base, @@ -176,17 +179,17 @@ export const Layout = React.memo(function Layout({ spacing: initialPadding, warnOnMisalignment: true, }) - + // Create stable initial padding for SSR const stablePadding = { padding: { top: initialPadding.top || 0, right: initialPadding.right || 0, bottom: initialPadding.bottom || 0, - left: initialPadding.left || 0 - } + left: initialPadding.left || 0, + }, } - + // Use stable padding during SSR and initial render, then switch to dynamic padding const { padding } = hydratedValue( isHydrated && !ssrMode, @@ -196,22 +199,22 @@ export const Layout = React.memo(function Layout({ const gridTemplateColumns = React.useMemo( () => getGridTemplate(columns), - [columns], + [columns] ) const gridTemplateRows = React.useMemo( () => (rows ? getGridTemplate(rows) : 'auto'), - [rows], + [rows] ) const defaultLayoutStyles = React.useMemo( () => createDefaultLayoutStyles(config.colors), - [config.colors], + [config.colors] ) const gridGapStyles = React.useMemo( () => createGridGapStyles(gap, rowGap, columnGap), - [gap, rowGap, columnGap], + [gap, rowGap, columnGap] ) const containerStyles = React.useMemo(() => { @@ -228,32 +231,34 @@ export const Layout = React.memo(function Layout({ key: '--bklw', value: widthValue, defaultStyles: defaultLayoutStyles, - skipDimensions: { auto: autoDimensions } + skipDimensions: { auto: autoDimensions }, }), ...createStyleOverride({ key: '--bklh', value: heightValue, defaultStyles: defaultLayoutStyles, - skipDimensions: { auto: autoDimensions } + skipDimensions: { auto: autoDimensions }, }), ...createStyleOverride({ key: '--bklcl', value: config.colors.line, - defaultStyles: defaultLayoutStyles + defaultStyles: defaultLayoutStyles, }), ...createStyleOverride({ key: '--bklcf', value: config.colors.flat, - defaultStyles: defaultLayoutStyles + defaultStyles: defaultLayoutStyles, }), ...createStyleOverride({ key: '--bklci', value: config.colors.text, - defaultStyles: defaultLayoutStyles + defaultStyles: defaultLayoutStyles, }), // Grid properties - only inject if different from defaults - ...(gridTemplateColumns !== 'repeat(auto-fit, minmax(100px, 1fr))' && { '--bklgtc': gridTemplateColumns }), + ...(gridTemplateColumns !== 'repeat(auto-fill, minmax(100px, 1fr))' && { + '--bklgtc': gridTemplateColumns, + }), ...(gridTemplateRows !== 'auto' && { '--bklgtr': gridTemplateRows }), ...(justifyItems && { '--bklji': justifyItems }), ...(alignItems && { '--bklai': alignItems }), @@ -263,7 +268,7 @@ export const Layout = React.memo(function Layout({ // Include gap styles ...gridGapStyles, } as React.CSSProperties, - style, + style ) }, [ gridTemplateColumns, @@ -281,14 +286,12 @@ export const Layout = React.memo(function Layout({ ]) return ( - + 0 ? - Object.fromEntries( - Object.entries(spacingProps).filter(([key]) => key !== 'ssrMode') - ) : {})} + {...(spacingProps && Object.keys(spacingProps).length > 0 + ? Object.fromEntries( + Object.entries(spacingProps).filter( + ([key]) => key !== 'ssrMode' + ) + ) + : {})} > {children}
diff --git a/src/components/Layout/index.ts b/src/components/Layout/index.ts index 5ffdb7df..941eff95 100644 --- a/src/components/Layout/index.ts +++ b/src/components/Layout/index.ts @@ -8,4 +8,4 @@ * alignment and debugging features. */ -export * from './Layout' \ No newline at end of file +export * from './Layout' diff --git a/src/components/Layout/styles.module.css b/src/components/Layout/styles.module.css index ee4a5f95..0e2ddefc 100644 --- a/src/components/Layout/styles.module.css +++ b/src/components/Layout/styles.module.css @@ -2,20 +2,22 @@ display: grid; position: relative; box-sizing: border-box; - width: var(--bklw, auto); - height: var(--bklh, auto); - grid-template-columns: var(--bklgtc, repeat(auto-fit, minmax(100px, 1fr))); + width: var(--bklw, var(--bk-width-default, auto)); + height: var(--bklh, var(--bk-height-default, auto)); + grid-template-columns: var( + --bklgtc, + repeat(auto-fill, minmax(100px, 1fr)) + ); grid-template-rows: var(--bklgtr, auto); - gap: var(--bklg); - column-gap: var(--bklcg); - row-gap: var(--bklrg); - justify-items: var(--bklji); - align-items: var(--bklai); - justify-content: var(--bkljc); - align-content: var(--bklac); + gap: var(--bklg, 0); + column-gap: var(--bklcg, 0); + row-gap: var(--bklrg, 0); + justify-items: var(--bklji, stretch); + align-items: var(--bklai, stretch); + justify-content: var(--bkljc, start); + align-content: var(--bklac, start); } - .lay .line::after, .stk .line::after { border: none; @@ -25,7 +27,8 @@ content: ''; position: absolute; inset: 0; - border: 1px solid var(--bklcl); + border: 1px solid + var(--bklcl, var(--bk-layout-color-line-theme, hsla(330, 60%, 40%, 0.6))); pointer-events: none; - z-index: var(--bkzio); -} \ No newline at end of file + z-index: var(--bkzio, 2); +} diff --git a/src/components/Padder/Padder.tsx b/src/components/Padder/Padder.tsx index 3d8357ae..136d07f0 100644 --- a/src/components/Padder/Padder.tsx +++ b/src/components/Padder/Padder.tsx @@ -6,7 +6,7 @@ import { parsePadding, mergeRefs, formatValue, - hydratedValue + hydratedValue, } from '@utils' import { ComponentsProps, Variant } from '../types' import { Spacer, IndicatorNode } from '../Spacer' @@ -15,16 +15,16 @@ import styles from './styles.module.css' type RenderSpacerFn = ( width: React.CSSProperties['width'], - height: React.CSSProperties['height'], + height: React.CSSProperties['height'] ) => React.ReactNode type PaddingStyles = { - paddingBlock?: string; - paddingInline?: string; - [key: string]: string | undefined; + paddingBlock?: string + paddingInline?: string + [key: string]: string | undefined } -type PadderProps = { +export type PadderProps = { /** Render function for custom measurement indicators */ indicatorNode?: IndicatorNode /** Flag to enable SSR-compatible mode (simplified initial render) */ @@ -32,14 +32,12 @@ type PadderProps = { children?: React.ReactNode } & ComponentsProps -// Utils ----------------------------------------------------------------------- - /** Creates default container styles for Padder */ -export const createPadderContainerStyles = ( +const createPadderContainerStyles = ( width: React.CSSProperties['width'], height: React.CSSProperties['height'], base: number, - color: string, + color: string ): Record => { const stylesObj: Record = {} @@ -50,27 +48,23 @@ export const createPadderContainerStyles = ( if (height !== 'fit-content') { stylesObj['--bkph'] = formatValue(height || 'fit-content') } - // Only inject base if it differs from theme - if (base !== 8) { - stylesObj['--bkpb'] = `${base}px` - } - // Only inject color if it differs from theme - if (color !== 'var(--bk-padder-color-theme)') { - stylesObj['--bkpc'] = color - } + + // Always set base and color + stylesObj['--bkpb'] = `${base}px` + stylesObj['--bkpc'] = color return stylesObj } -/** Creates padding styles when spacers are disabled */ -export const createDirectPaddingStyles = ( +/** Creates direct padding styles when spacers are disabled */ +const createDirectPaddingStyles = ( enableSpacers: boolean, padding: { - top: number; - right: number; - bottom: number; - left: number; - }, + top: number + right: number + bottom: number + left: number + } ): PaddingStyles => { const { top, right, bottom, left } = padding const stylesObj: PaddingStyles = {} @@ -89,20 +83,23 @@ export const createDirectPaddingStyles = ( } /** Creates a render function for spacers */ -export const createRenderSpacerFn = ( +const createRenderSpacerFn = ( variant: Variant | undefined, debugging: DebuggingMode | undefined, - indicatorNode?: IndicatorNode, + indicatorNode?: IndicatorNode ): RenderSpacerFn => { // Default to 'line' if variant is undefined const safeVariant = variant || 'line' // Default to 'none' if debugging is undefined const safeDebugging = debugging || 'none' - const SpacerElement = (widthVal: React.CSSProperties['width'], heightVal: React.CSSProperties['height']) => ( + const SpacerElement = ( + widthVal: React.CSSProperties['width'], + heightVal: React.CSSProperties['height'] + ) => ( parsePadding(spacingProps), - [spacingProps], + [spacingProps] ) const { isShown, isNone, debugging } = useDebug( debuggingProp, - config.debugging, + config.debugging ) const enableSpacers = !isNone // Add hydration state tracking const [isHydrated, setIsHydrated] = React.useState(false) - + React.useEffect(() => { setIsHydrated(true) }, []) const internalRef = React.useRef(null) - + // Get padding calculation from useBaseline const baselinePadding = useBaseline(internalRef, { base: config.base, @@ -201,17 +198,17 @@ export const Padder = React.memo( spacing: initialPadding, warnOnMisalignment: !isNone, }) - + // Create stable initial padding for SSR const stablePadding = { padding: { top: initialPadding.top || 0, right: initialPadding.right || 0, bottom: initialPadding.bottom || 0, - left: initialPadding.left || 0 - } + left: initialPadding.left || 0, + }, } - + // Use stable padding during SSR and initial render, then switch to dynamic padding const { padding } = hydratedValue( isHydrated && !ssrMode, @@ -226,17 +223,19 @@ export const Padder = React.memo( width, height, config.base, - config.color, + config.color ) - const paddingStyles = createDirectPaddingStyles( - enableSpacers, - { top: padding.top, right: padding.right, bottom: padding.bottom, left: padding.left }, - ) + const paddingStyles = createDirectPaddingStyles(enableSpacers, { + top: padding.top, + right: padding.right, + bottom: padding.bottom, + left: padding.left, + }) return mergeStyles( { ...baseStyles, ...paddingStyles } as React.CSSProperties, - style, + style ) }, [ width, @@ -253,7 +252,7 @@ export const Padder = React.memo( const renderSpacer = React.useMemo( () => createRenderSpacerFn(variant, debugging, indicatorNode), - [variant, debugging, indicatorNode], + [variant, debugging, indicatorNode] ) // When debugging is "none", simply return a container with direct CSS padding @@ -289,7 +288,9 @@ export const Padder = React.memo( {/* Left spacer */} {padding.left >= 0 && ( -
{renderSpacer(padding.left, '100%')}
+
+ {renderSpacer(padding.left, '100%')} +
)} @@ -313,5 +314,5 @@ export const Padder = React.memo(
) - }), + }) ) diff --git a/src/components/Padder/index.ts b/src/components/Padder/index.ts index 6b331121..490f58b9 100644 --- a/src/components/Padder/index.ts +++ b/src/components/Padder/index.ts @@ -8,4 +8,4 @@ * in the baseline grid system. */ -export * from './Padder' \ No newline at end of file +export * from './Padder' diff --git a/src/components/Spacer/Spacer.tsx b/src/components/Spacer/Spacer.tsx index fb60f988..316ba71f 100644 --- a/src/components/Spacer/Spacer.tsx +++ b/src/components/Spacer/Spacer.tsx @@ -6,14 +6,17 @@ import { formatValue, normalizeValuePair, createStyleOverride, - hydratedValue + hydratedValue, } from '@utils' import { ComponentsProps, Variant } from '../types' import styles from './styles.module.css' // Type Definitions ------------------------------------------------------------ -export type IndicatorNode = (value: number, type: 'width' | 'height') => React.ReactNode +export type IndicatorNode = ( + value: number, + type: 'width' | 'height' +) => React.ReactNode export type SpacerProps = { /** Explicit width (takes precedence over block) */ @@ -37,26 +40,26 @@ export type SpacerProps = { // Utils ----------------------------------------------------------------------- /** Creates default spacer styles */ -export const createDefaultSpacerStyles = ( +const createDefaultSpacerStyles = ( base: number, textColor: string, flatColor: string, - lineColor: string, + lineColor: string ): Record => ({ '--bksw': '100%', '--bksh': '100%', '--bksb': `${base}px`, - '--bksci': textColor, - '--bkscl': lineColor, + '--bksct': textColor, '--bkscf': flatColor, + '--bkscl': lineColor, }) /** Generates measurement indicators for debugging */ -export const generateMeasurements = ( +const generateMeasurements = ( isShown: boolean, indicatorNode: SpacerProps['indicatorNode'], normWidth: number | string, - normHeight: number | string, + normHeight: number | string ): React.ReactNode | null => { if (!isShown || !indicatorNode) return null @@ -66,15 +69,9 @@ export const generateMeasurements = ( return ( <> {height !== 0 && ( - - {indicatorNode(height, 'height')} - - )} - {width !== 0 && ( - - {indicatorNode(width, 'width')} - + {indicatorNode(height, 'height')} )} + {width !== 0 && {indicatorNode(width, 'width')}} ) } @@ -128,24 +125,23 @@ export const Spacer = React.memo(function Spacer({ // Add hydration state tracking const [isHydrated, setIsHydrated] = React.useState(false) - + React.useEffect(() => { setIsHydrated(true) }, []) const [normWidth, normHeight] = React.useMemo(() => { - return normalizeValuePair( - [widthProp, heightProp], - [0, 0], - { base, suppressWarnings: true } - ) + return normalizeValuePair([widthProp, heightProp], [0, 0], { + base, + suppressWarnings: true, + }) }, [widthProp, heightProp, base]) // Ensure stable rendering for measurements during SSR const shouldShowMeasurements = hydratedValue( isHydrated && !ssrMode, false, // Don't show measurements during SSR - isShown && (indicatorNode !== undefined) + isShown && indicatorNode !== undefined ) // Only generate measurements after hydration @@ -154,12 +150,7 @@ export const Spacer = React.memo(function Spacer({ return null } - return generateMeasurements( - isShown, - indicatorNode, - normWidth, - normHeight - ) + return generateMeasurements(isShown, indicatorNode, normWidth, normHeight) }, [shouldShowMeasurements, isShown, indicatorNode, normWidth, normHeight]) const defaultStyles = React.useMemo( @@ -168,9 +159,9 @@ export const Spacer = React.memo(function Spacer({ base, config.colors.text, config.colors.flat, - config.colors.line, + config.colors.line ), - [base, config.colors], + [base, config.colors] ) const baseStyles = React.useMemo(() => { @@ -197,7 +188,7 @@ export const Spacer = React.memo(function Spacer({ // Explicitly set --bksb to ensure it is always applied '--bksb': baseValue, ...createStyleOverride({ - key: '--bksci', + key: '--bksct', value: colorProp ?? config.colors.text, defaultStyles, }), @@ -228,8 +219,15 @@ export const Spacer = React.memo(function Spacer({
diff --git a/src/components/Spacer/index.ts b/src/components/Spacer/index.ts index 6731cf05..4865776e 100644 --- a/src/components/Spacer/index.ts +++ b/src/components/Spacer/index.ts @@ -8,4 +8,4 @@ * visual debugging features. */ -export * from './Spacer' \ No newline at end of file +export * from './Spacer' diff --git a/src/components/Spacer/styles.module.css b/src/components/Spacer/styles.module.css index 713afe80..2b7bc6e6 100644 --- a/src/components/Spacer/styles.module.css +++ b/src/components/Spacer/styles.module.css @@ -1,19 +1,22 @@ .spr { position: relative; - width: var(--bksw); - height: var(--bksh); - flex-shrink: 0; + box-sizing: border-box; + width: var(--bksw, 100%); + height: var(--bksh, auto); + flex-shrink: 0; + display: block; + margin: 0; + padding: 0; } .line::after { content: ''; position: absolute; inset: 0; - border: 1px solid var(--bkscl); - z-index: calc(var(--bkzi)); - + border: 1px solid var(--bkscl, hsla(270, 60%, 40%, 0.6)); + z-index: calc(var(--bkzi, 1)); } .flat { - background-color: var(--bkscf); + background-color: var(--bkscf, hsla(230, 100%, 70%, 0.2)); } diff --git a/src/components/Stack/Stack.tsx b/src/components/Stack/Stack.tsx index debe6194..e160ac50 100644 --- a/src/components/Stack/Stack.tsx +++ b/src/components/Stack/Stack.tsx @@ -7,7 +7,7 @@ import { parsePadding, formatValue, createStyleOverride, - hydratedValue + hydratedValue, } from '@utils' import { Padder } from '../Padder' import { IndicatorNode } from '../Spacer' @@ -16,18 +16,19 @@ import { ComponentsProps, Variant } from '../types' import styles from './styles.module.css' // Maps shorthand directions to Flexbox directions -export const DIRECTION_AXIS: Record = { +const DIRECTION_AXIS: Record = { x: 'row', y: 'column', '-x': 'row-reverse', '-y': 'column-reverse', } -export type CSSPropertiesDirectionalAxis = keyof typeof DIRECTION_AXIS; +export type CSSPropertiesDirectionalAxis = keyof typeof DIRECTION_AXIS export type StackProps = { /** Main axis orientation */ - direction?: React.CSSProperties['flexDirection'] & CSSPropertiesDirectionalAxis; + direction?: React.CSSProperties['flexDirection'] & + CSSPropertiesDirectionalAxis /** Distribution of space on main axis */ justify?: React.CSSProperties['justifyContent'] /** Alignment on cross axis */ @@ -54,7 +55,7 @@ export type StackProps = { // Utils ----------------------------------------------------------------------- /** Creates default stack styles with theme colors */ -export const createDefaultStackStyles = (colors: Record) => ({ +const createDefaultStackStyles = (colors: Record) => ({ '--bkkw': 'auto', '--bkkh': 'auto', '--bkkcl': colors.line, @@ -63,10 +64,10 @@ export const createDefaultStackStyles = (colors: Record) => ({ }) /** Creates gap styles for the stack */ -export const createStackGapStyles = ( +const createStackGapStyles = ( rowGap?: number, columnGap?: number, - gap?: number, + gap?: number ): Record => ({ rowGap: gap !== undefined ? gap : rowGap, columnGap: gap !== undefined ? gap : columnGap, @@ -144,14 +145,14 @@ export const Stack = React.memo(function Stack({ // Read configuration from context or props const config = useConfig('stack') const { isShown, debugging } = useDebug(debuggingProp, config.debugging) - + // Add hydration state tracking const [isHydrated, setIsHydrated] = React.useState(false) - + React.useEffect(() => { setIsHydrated(true) }, []) - + const stackRef = React.useRef(null) // Process spacing props @@ -166,17 +167,17 @@ export const Stack = React.memo(function Stack({ spacing: { top, right, bottom, left }, warnOnMisalignment: debugging !== 'none', }) - + // Create stable initial padding for SSR const stablePadding = { padding: { top: top || 0, right: right || 0, bottom: bottom || 0, - left: left || 0 - } + left: left || 0, + }, } - + // Use stable padding during SSR and initial render, then switch to dynamic padding const { padding } = hydratedValue( isHydrated && !ssrMode, @@ -186,15 +187,20 @@ export const Stack = React.memo(function Stack({ const stackGapStyles = React.useMemo(() => { const formattedRowGap = rowGap !== undefined ? Number(rowGap) : undefined - const formattedColumnGap = columnGap !== undefined ? Number(columnGap) : undefined + const formattedColumnGap = + columnGap !== undefined ? Number(columnGap) : undefined const formattedGap = gap !== undefined ? Number(gap) : undefined - return createStackGapStyles(formattedRowGap, formattedColumnGap, formattedGap) + return createStackGapStyles( + formattedRowGap, + formattedColumnGap, + formattedGap + ) }, [rowGap, columnGap, gap]) const defaultStackStyles = React.useMemo( () => createDefaultStackStyles(config.colors), - [config.colors], + [config.colors] ) const containerStyles = React.useMemo(() => { @@ -261,19 +267,16 @@ export const Stack = React.memo(function Stack({ const mergedContainerStyles = debugging === 'none' ? { - ...containerStyles, - paddingBlock: `${padding.top}px ${padding.bottom}px`, - paddingInline: `${padding.left}px ${padding.right}px`, - } + ...containerStyles, + paddingBlock: `${padding.top}px ${padding.bottom}px`, + paddingInline: `${padding.left}px ${padding.right}px`, + } : containerStyles return ( - +
diff --git a/src/components/Stack/styles.module.css b/src/components/Stack/styles.module.css index b05178bd..27892989 100644 --- a/src/components/Stack/styles.module.css +++ b/src/components/Stack/styles.module.css @@ -1,20 +1,26 @@ .stk { display: flex; position: relative; - width: var(--bkkw, auto); - height: var(--bkkh, auto); + width: var(--bkkw); + height: var(--bkkh); } -.lay .line::after, +/* Remove borders from children if they're lines */ .stk .line::after { border: none; } +/* Style for debugging border */ .v::after { content: ''; position: absolute; inset: 0; - border: 1px solid var(--bkkcl); + border: 1px solid var(--bkkcl, hsla(330, 60%, 40%, 0.6)); pointer-events: none; - z-index: var(--bkzio); + z-index: var(--bkzio, 2); +} + +/* Style for flat debugging background */ +.flat { + background-color: var(--bkkcf, hsla(0, 100%, 70%, 0.2)); } diff --git a/src/components/index.ts b/src/components/index.ts index 3292f730..fdc311e0 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -4,23 +4,23 @@ * @module baseline-kit/components */ -import './styles/index.css' +// Style imports - these generate CSS files in the dist folder +import './styles/core.css' +import './styles/theme.css' // Layout Components export * from './Layout' export * from './Box' export * from './Stack' +export * from './Spacer' +export * from './Padder' // Grid Components export * from './Guide' export * from './Baseline' -// Spacing Components -export * from './Spacer' -export * from './Padder' - // Configuration export * from './Config' // Types -export * from './types' \ No newline at end of file +export * from './types' diff --git a/src/components/styles/base.css b/src/components/styles/base.css new file mode 100644 index 00000000..496f6aaf --- /dev/null +++ b/src/components/styles/base.css @@ -0,0 +1,122 @@ +/** + * Baseline Kit Base Styles + * + * This file defines: + * 1. Core system variables used across components + * 2. Component-specific CSS variables with fallback values + * 3. Robust fallbacks for components to ensure cross-framework compatibility + */ + +/* Core system variables */ +:root { + /* Core System Variables */ + --bkb: 8px; /* Base unit for spacing */ + --bkzi: 1; /* Base z-index */ + --bkzio: 2; /* Overlay z-index */ + --bk-transition-base: 180ms ease; /* Standard transition */ + + /* Default Dimensions */ + --bk-width-default: fit-content; + --bk-height-default: fit-content; + --bkwf: 100%; /* Full width shorthand */ + --bkhf: 100%; /* Full height shorthand */ + + /* Box Component Variables */ + --bkxb: var(--bkb); + --bkxw: var(--bk-width-default); + --bkxh: var(--bk-height-default); + --bkxcl: var(--bk-box-color-line-theme, hsla(300, 60%, 40%, 0.6)); + --bkxcf: var(--bk-box-color-flat-theme, hsla(260, 100%, 70%, 0.2)); + --bkxci: var(--bk-box-color-text-theme, hsla(300, 60%, 40%, 0.9)); + + /* Stack Component Variables */ + --bkkw: var(--bkwf); + --bkkh: var(--bk-height-default); + --bkkcl: var(--bk-stack-color-line-theme, hsla(330, 60%, 40%, 0.6)); + --bkkcf: var(--bk-stack-color-flat-theme, hsla(0, 100%, 70%, 0.2)); + --bkkci: var(--bk-stack-color-text-theme, hsla(330, 60%, 40%, 0.9)); + + /* Baseline Component Variables */ + --bkbw: 100%; + --bkbh: 100%; + --bkrt: 0; + --bkrh: 1px; + --bkbcl: var(--bk-baseline-color-line-theme, hsla(240, 60%, 40%, 0.15)); + --bkbcf: var(--bk-baseline-color-flat-theme, hsla(230, 100%, 70%, 0.2)); + + /* Guide Component Variables */ + --bkgw: 100vw; + --bkgh: 100vh; + --bkgg: var(--bkb); + --bkgj: center; + --bkgt: auto; + --bkgpb: 0; + --bkgpi: 0; + --bkgcl: var(--bk-guide-color-line-theme, hsla(240, 60%, 40%, 0.15)); + --bkgcp: var(--bk-guide-color-pattern-theme, hsla(230, 100%, 70%, 0.2)); + --bkgca: var(--bk-guide-color-auto-theme, hsla(200, 100%, 70%, 0.15)); + --bkgcf: var(--bk-guide-color-fixed-theme, hsla(200, 100%, 70%, 0.15)); + + /* Layout Component Variables */ + --bklw: var(--bk-width-default); + --bklh: var(--bk-height-default); + --bklcl: var(--bk-layout-color-line-theme, hsla(330, 60%, 40%, 0.6)); + --bklcf: var(--bk-layout-color-flat-theme, hsla(0, 100%, 70%, 0.2)); + --bklci: var(--bk-layout-color-text-theme, hsla(330, 60%, 40%, 0.9)); + --bklgtc: repeat(auto-fill, minmax(100px, 1fr)); + --bklgtr: auto; + --bklg: 0; + --bklcg: 0; + --bklrg: 0; + --bklji: stretch; + --bklai: stretch; + --bkljc: start; + --bklac: start; + + /* Padder Component Variables */ + --bkpw: var(--bk-width-default); + --bkph: var(--bk-height-default); + --bkpc: var(--bk-padder-color-theme, hsla(270, 60%, 40%, 0.6)); + + /* Spacer Component Variables - with fallback values */ + --bksw: var(--bkwf); + --bksh: var(--bkhf); + --bkscl: var(--bk-spacer-color-line-theme, hsla(270, 60%, 40%, 0.6)); + --bkscf: var(--bk-spacer-color-flat-theme, hsla(230, 100%, 70%, 0.2)); + --bksct: var(--bk-spacer-color-text-theme, hsla(270, 60%, 40%, 1)); +} + +/* Guide Component */ +.guide { + --bkgcl: var(--bk-guide-color-line-theme, hsla(240, 60%, 40%, 0.15)); + --bkgcp: var(--bk-guide-color-pattern-theme, hsla(230, 100%, 70%, 0.2)); + --bkgca: var(--bk-guide-color-auto-theme, hsla(200, 100%, 70%, 0.15)); + --bkgcf: var(--bk-guide-color-fixed-theme, hsla(200, 100%, 70%, 0.15)); +} + +/* Baseline Component */ +.baseline { + --bkbcl: var(--bk-baseline-color-line-theme, hsla(240, 60%, 40%, 0.15)); + --bkbcf: var(--bk-baseline-color-flat-theme, hsla(230, 100%, 70%, 0.2)); +} + +/* Box Component */ +.box { + --bkxcl: var(--bk-box-color-line-theme, hsla(300, 60%, 40%, 0.6)); + --bkxcf: var(--bk-box-color-flat-theme, hsla(260, 100%, 70%, 0.2)); + --bkxci: var(--bk-box-color-text-theme, hsla(300, 60%, 40%, 0.9)); +} + +/* Stack Component */ +.stack { + --bkkcl: var(--bk-stack-color-line-theme, hsla(330, 60%, 40%, 0.6)); + --bkkcf: var(--bk-stack-color-flat-theme, hsla(0, 100%, 70%, 0.2)); + --bkkci: var(--bk-stack-color-text-theme, hsla(330, 60%, 40%, 0.9)); +} + +/* Layout Component */ +.layout { + --bklcl: var(--bk-layout-color-line-theme, hsla(330, 60%, 40%, 0.6)); + --bklcf: var(--bk-layout-color-flat-theme, hsla(0, 100%, 70%, 0.2)); + --bklci: var(--bk-layout-color-text-theme, hsla(330, 60%, 40%, 0.9)); +} diff --git a/src/components/styles/core.css b/src/components/styles/core.css new file mode 100644 index 00000000..7a6c1126 --- /dev/null +++ b/src/components/styles/core.css @@ -0,0 +1,40 @@ +/** + * Baseline Kit Core Styles + * + * This file imports all fundamental styles in the correct order: + * 1. CSS reset for consistent defaults across browsers + * 2. Base variables and common styles + * 3. Component-specific styles + */ + +/* CSS reset - Normalizes browser defaults */ +@import './reset.css'; + +/* Base variables - Core system variables and defaults */ +@import './base.css'; + +/* Component-specific styles - Each component's styling */ +@import '../Box/styles.module.css'; +@import '../Guide/styles.module.css'; +@import '../Padder/styles.module.css'; +@import '../Spacer/styles.module.css'; +@import '../Stack/styles.module.css'; +@import '../Layout/styles.module.css'; +@import '../Baseline/styles.module.css'; + +/* Utility classes for visibility control */ +.v { + opacity: 1; + visibility: visible; + transition: + opacity var(--bk-transition-base), + visibility 0ms linear; +} + +.h { + opacity: 0; + visibility: hidden; + transition: + opacity var(--bk-transition-base), + visibility 0ms linear 180ms; +} diff --git a/src/components/styles/index.css b/src/components/styles/index.css deleted file mode 100644 index e8177f44..00000000 --- a/src/components/styles/index.css +++ /dev/null @@ -1,102 +0,0 @@ -/* Theme must come first to establish CSS variables */ -@import './reset.css'; - -/* Component-specific styles */ -@import '../Box/styles.module.css'; -@import '../Guide/styles.module.css'; -@import '../Padder/styles.module.css'; -@import '../Spacer/styles.module.css'; - -/* Base root variables */ -:root { - /* Core System Variables */ - --bkb: 8px; - --bkzi: 1; - --bkzio: 2; - --bk-transition-base: 180ms ease; - - /* Default Dimensions */ - --bk-width-default: fit-content; - --bk-height-default: fit-content; - --bkwf: 100%; - --bkhf: 100%; - - /* Box Component */ - --bkxb: var(--bkb); - --bkxw: var(--bk-width-default); - --bkxh: var(--bk-height-default); - --bkxcl: var(--bk-box-color-line-theme); - --bkxcf: var(--bk-box-color-flat-theme); - --bkxci: var(--bk-box-color-text-theme); - - /* Stack Component */ - --bkkw: var(--bkwf); - --bkkh: var(--bk-height-default); - --bkkcl: var(--bk-stack-color-line-theme); - --bkkcf: var(--bk-stack-color-flat-theme); - --bkkci: var(--bk-stack-color-text-theme); - - /* Baseline Component */ - --bkbw: '100%'; - --bkbh: '100%'; - --bkrt: 0; - --bkrh: 1px; - --bkbcl: var(--bk-baseline-color-line-theme); - --bkbcf: var(--bk-baseline-color-flat-theme); - - /* Guide Component */ - --bkgw: 100vw; - --bkgh: 100vh; - --bkgg: var(--bkb); - --bkgj: start; - --bkgt: auto; - --bkgpb: 0; - --bkgpi: 0; - --bkgcl: var(--bk-guide-color-line-theme); - --bkgcp: var(--bk-guide-color-pattern-theme); - --bkgca: var(--bk-guide-color-auto-theme); - --bkgcf: var(--bk-guide-color-fixed-theme); - - /* Layout Component */ - --bklw: var(--bk-width-default); - --bklh: var(--bk-height-default); - --bklcl: var(--bk-layout-color-line-theme); - --bklcf: var(--bk-layout-color-flat-theme); - --bklci: var(--bk-layout-color-text-theme); - --bklgtc: repeat(auto-fit, minmax(100px, 1fr)); - --bklgtr: auto; - --bklg: 0; - --bklcg: 0; - --bklrg: 0; - --bklji: stretch; - --bklai: stretch; - --bkljc: start; - --bklac: start; - - /* Padder Component */ - --bkpw: var(--bk-width-default); - --bkph: var(--bk-height-default); - --bkpc: var(--bk-padder-color-theme); - - /* Spacer Component */ - --bksw: var(--bkwf); - --bksh: var(--bkhf); - --bkscl: var(--bk-spacer-color-line-theme); - --bkscf: var(--bk-spacer-color-flat-theme); - --bksci: var(--bk-spacer-color-text-theme); -} - -/* Utility classes */ -.v { - opacity: 1; - visibility: visible; - transition: opacity var(--bk-transition-base), - visibility 0ms linear; -} - -.h { - opacity: 0; - visibility: hidden; - transition: opacity var(--bk-transition-base), - visibility 0ms linear 180ms; -} diff --git a/src/components/styles/index.ts b/src/components/styles/index.ts new file mode 100644 index 00000000..a458d5ec --- /dev/null +++ b/src/components/styles/index.ts @@ -0,0 +1,15 @@ +/** + * Baseline Kit Styles System + * + * This file exports all core styles needed for the component library. + * The import order is important: + * 1. core.css - Contains reset.css, base.css, and component styles + * 2. theme.css - Contains color variables and theming + */ + +// Core styles must be imported before theme +import './core.css' +import './theme.css' + +// Empty export to make this a proper module +export {} diff --git a/src/components/styles/theme.css b/src/components/styles/theme.css new file mode 100644 index 00000000..4bbbd68d --- /dev/null +++ b/src/components/styles/theme.css @@ -0,0 +1,142 @@ +/** + * Baseline Kit Theme System + * + * This file contains all color variables for theming. + * For light and dark mode themes separately, see the theme directory. + */ + +:root { + /* ─────────────────────────────────────────────────────── + Color Palette - Light Theme + - Primary: More muted/dimmed colors + - Secondary: Brighter, more vibrant colors + ─────────────────────────────────────────────────────── */ + + /* Neutral Colors */ + --bk-color-black-primary: 0, 0%, 10%; /* #1A1A1A */ + --bk-color-black-secondary: 0, 10%, 30%; /* #544545 */ + --bk-color-white-primary: 0, 100%, 90%; /* #FFCCCC */ + --bk-color-white-secondary: 0, 0%, 90%; /* #E6E6E6 */ + + /* Brand Colors */ + --bk-color-pink-primary: 300, 60%, 40%; /* #A329A3 */ + --bk-color-pink-secondary: 260, 100%, 70%; /* #9966FF */ + --bk-color-purple-primary: 270, 60%, 40%; /* #6629A3 */ + --bk-color-purple-secondary: 230, 100%, 70%; /* #6680FF */ + --bk-color-blue-primary: 240, 60%, 40%; /* #2929A3 */ + --bk-color-blue-secondary: 200, 100%, 70%; /* #66CCFF */ + + /* Supporting Colors */ + --bk-color-cyan-primary: 200, 60%, 40%; /* #297AA3 */ + --bk-color-cyan-secondary: 160, 100%, 70%; /* #66FFCC */ + --bk-color-green-primary: 160, 60%, 40%; /* #29A37A */ + --bk-color-green-secondary: 110, 100%, 70%; /* #80FF66 */ + --bk-color-yellow-primary: 30, 60%, 40%; /* #A36629 */ + --bk-color-yellow-secondary: 70, 100%, 70%; /* #A36629 */ + --bk-color-orange-primary: 10, 60%, 40%; /* #A33D29 */ + --bk-color-orange-secondary: 30, 100%, 70%; /* #FFB266 */ + --bk-color-red-primary: 330, 60%, 40%; /* #A32966 */ + --bk-color-red-secondary: 0, 100%, 70%; /* #FF6666 */ + + /* ─────────────────────────────────────────────────────── + Component Theme Colors - Light + Using consistent alpha values: + - Line: 0.6 (borders) + - Flat: 0.2 (backgrounds) + - text: 0.9-1.0 (indicators) + ─────────────────────────────────────────────────────── */ + + /* Guide Component Theme */ + --bk-guide-color-line-theme: hsla(var(--bk-color-blue-primary), 0.15); + --bk-guide-color-pattern-theme: hsla(var(--bk-color-purple-secondary), 0.2); + --bk-guide-color-auto-theme: hsla(var(--bk-color-blue-secondary), 0.15); + --bk-guide-color-fixed-theme: hsla(var(--bk-color-blue-secondary), 0.15); + + /* Baseline Component Theme */ + --bk-baseline-color-line-theme: hsla(var(--bk-color-blue-primary), 0.15); + --bk-baseline-color-flat-theme: hsla(var(--bk-color-purple-secondary), 0.2); + + /* Spacer Component Theme */ + --bk-spacer-color-line-theme: hsla(var(--bk-color-purple-primary), 0.6); + --bk-spacer-color-flat-theme: hsla(var(--bk-color-purple-secondary), 0.2); + --bk-spacer-color-text-theme: hsla(var(--bk-color-purple-primary), 1); + + /* Box Component Theme */ + --bk-box-color-line-theme: hsla(var(--bk-color-pink-primary), 0.6); + --bk-box-color-flat-theme: hsla(var(--bk-color-pink-secondary), 0.2); + --bk-box-color-text-theme: hsla(var(--bk-color-pink-primary), 0.9); + + /* Stack Component Theme */ + --bk-stack-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); + --bk-stack-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.2); + --bk-stack-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); + + /* Layout Component Theme */ + --bk-layout-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); + --bk-layout-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.2); + --bk-layout-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); + + /* Padder Component Theme */ + --bk-padder-color-theme: hsla(var(--bk-color-purple-primary), 0.6); +} + +/* ─────────────────────────────────────────────────────── + Dark Theme + - Inverts Primary/Secondary relationships + - Adjusts alpha values for better contrast +─────────────────────────────────────────────────────── */ + +@media (prefers-color-scheme: dark) { + :root { + /* Neutral Colors - Dark */ + --bk-color-black-primary: 0, 10%, 30%; /* #544545 */ + --bk-color-black-secondary: 0, 0%, 10%; /* #1A1A1A */ + --bk-color-white-primary: 0, 0%, 90%; /* #E6E6E6 */ + --bk-color-white-secondary: 0, 100%, 90%; /* #FFCCCC */ + + /* Brand Colors - Dark */ + --bk-color-pink-primary: 260, 100%, 70%; /* #9966FF */ + --bk-color-pink-secondary: 300, 60%, 40%; /* #A329A3 */ + --bk-color-purple-primary: 230, 100%, 70%; /* #6680FF */ + --bk-color-purple-secondary: 270, 60%, 40%; /* #6629A3 */ + --bk-color-blue-primary: 200, 100%, 70%; /* #66CCFF */ + --bk-color-blue-secondary: 240, 60%, 40%; /* #2929A3 */ + + /* Supporting Colors - Dark */ + --bk-color-cyan-primary: 160, 100%, 70%; /* #66FFCC */ + --bk-color-cyan-secondary: 200, 60%, 40%; /* #297AA3 */ + --bk-color-green-primary: 110, 100%, 70%; /* #80FF66 */ + --bk-color-green-secondary: 160, 60%, 40%; /* #29A37A */ + --bk-color-yellow-primary: 70, 100%, 70%; /* #A36629 */ + --bk-color-yellow-secondary: 30, 60%, 40%; /* #A36629 */ + --bk-color-orange-primary: 30, 100%, 70%; /* #FFB266 */ + --bk-color-orange-secondary: 10, 60%, 40%; /* #A33D29 */ + --bk-color-red-primary: 0, 100%, 70%; /* #FF6666 */ + --bk-color-red-secondary: 330, 60%, 40%; /* #A32966 */ + + /* Component Theme Overrides - Dark */ + --bk-baseline-color-line-theme: hsla(var(--bk-color-white-primary), 0.1); + --bk-baseline-color-flat-theme: hsla(var(--bk-color-white-secondary), 0.2); + + --bk-box-color-line-theme: hsla(var(--bk-color-pink-primary), 0.6); + --bk-box-color-flat-theme: hsla(var(--bk-color-pink-secondary), 0.3); + --bk-box-color-text-theme: hsla(var(--bk-color-pink-primary), 0.9); + + --bk-guide-color-line-theme: hsla(var(--bk-color-white-primary), 0.1); + --bk-guide-color-pattern-theme: hsla(var(--bk-color-purple-secondary), 0.25); + --bk-guide-color-auto-theme: hsla(var(--bk-color-blue-secondary), 0.2); + --bk-guide-color-fixed-theme: hsla(var(--bk-color-blue-secondary), 0.2); + + --bk-stack-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); + --bk-stack-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.3); + --bk-stack-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); + + --bk-layout-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); + --bk-layout-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.3); + --bk-layout-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); + + --bk-spacer-color-line-theme: hsla(var(--bk-color-purple-primary), 0.7); + --bk-spacer-color-flat-theme: hsla(var(--bk-color-purple-secondary), 0.3); + --bk-spacer-color-text-theme: hsla(var(--bk-color-purple-primary), 1); + } +} diff --git a/src/components/styles/theme/dark.css b/src/components/styles/theme/dark.css new file mode 100644 index 00000000..8408b08d --- /dev/null +++ b/src/components/styles/theme/dark.css @@ -0,0 +1,67 @@ +/** + * Baseline Kit Dark Theme + * + * Organization: + * 1. Color Palette (HSL values) + * 2. Component Theme Colors + */ + +:root { + /* ─────────────────────────────────────────────────────── + Color Palette - Dark Theme + - Inverts Primary/Secondary relationships + - Adjusts values for better contrast + ─────────────────────────────────────────────────────── */ + + /* Neutral Colors - Dark */ + --bk-color-black-primary: 0, 10%, 30%; /* #544545 */ + --bk-color-black-secondary: 0, 0%, 10%; /* #1A1A1A */ + --bk-color-white-primary: 0, 0%, 90%; /* #E6E6E6 */ + --bk-color-white-secondary: 0, 100%, 90%; /* #FFCCCC */ + + /* Brand Colors - Dark */ + --bk-color-pink-primary: 260, 100%, 70%; /* #9966FF */ + --bk-color-pink-secondary: 300, 60%, 40%; /* #A329A3 */ + --bk-color-purple-primary: 230, 100%, 70%; /* #6680FF */ + --bk-color-purple-secondary: 270, 60%, 40%; /* #6629A3 */ + --bk-color-blue-primary: 200, 100%, 70%; /* #66CCFF */ + --bk-color-blue-secondary: 240, 60%, 40%; /* #2929A3 */ + + /* Supporting Colors - Dark */ + --bk-color-cyan-primary: 160, 100%, 70%; /* #66FFCC */ + --bk-color-cyan-secondary: 200, 60%, 40%; /* #297AA3 */ + --bk-color-green-primary: 110, 100%, 70%; /* #80FF66 */ + --bk-color-green-secondary: 160, 60%, 40%; /* #29A37A */ + --bk-color-yellow-primary: 70, 100%, 70%; /* #A36629 */ + --bk-color-yellow-secondary: 30, 60%, 40%; /* #A36629 */ + --bk-color-orange-primary: 30, 100%, 70%; /* #FFB266 */ + --bk-color-orange-secondary: 10, 60%, 40%; /* #A33D29 */ + --bk-color-red-primary: 0, 100%, 70%; /* #FF6666 */ + --bk-color-red-secondary: 330, 60%, 40%; /* #A32966 */ + + /* ─────────────────────────────────────────────────────── + Component Theme Colors - Dark + - Adjusts alpha values for better contrast + ─────────────────────────────────────────────────────── */ + + /* Component Theme Overrides - Dark */ + --bk-baseline-color-line-theme: hsla(var(--bk-color-white-primary), 0.1); + --bk-baseline-color-flat-theme: hsla(var(--bk-color-white-secondary), 0.2); + + --bk-box-color-line-theme: hsla(var(--bk-color-pink-primary), 0.6); + --bk-box-color-flat-theme: hsla(var(--bk-color-pink-secondary), 0.3); + --bk-box-color-text-theme: hsla(var(--bk-color-pink-primary), 0.9); + + --bk-guide-color-line-theme: hsla(var(--bk-color-white-primary), 0.1); + --bk-guide-color-pattern-theme: hsla(var(--bk-color-purple-secondary), 0.25); + --bk-guide-color-auto-theme: hsla(var(--bk-color-blue-secondary), 0.2); + --bk-guide-color-fixed-theme: hsla(var(--bk-color-blue-secondary), 0.2); + + --bk-stack-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); + --bk-stack-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.3); + --bk-stack-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); + + --bk-layout-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); + --bk-layout-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.3); + --bk-layout-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); +} diff --git a/src/components/styles/theme/default.css b/src/components/styles/theme/default.css new file mode 100644 index 00000000..ad358a0a --- /dev/null +++ b/src/components/styles/theme/default.css @@ -0,0 +1,82 @@ +/** + * Baseline Kit Default Theme (Light) + * + * Organization: + * 1. Color Palette (HSL values) + * 2. Component Theme Colors + */ + +:root { + /* ─────────────────────────────────────────────────────── + Color Palette - Light Theme + - Primary: More muted/dimmed colors + - Secondary: Brighter, more vibrant colors + ─────────────────────────────────────────────────────── */ + + /* Neutral Colors */ + --bk-color-black-primary: 0, 0%, 10%; /* #1A1A1A */ + --bk-color-black-secondary: 0, 10%, 30%; /* #544545 */ + --bk-color-white-primary: 0, 100%, 90%; /* #FFCCCC */ + --bk-color-white-secondary: 0, 0%, 90%; /* #E6E6E6 */ + + /* Brand Colors */ + --bk-color-pink-primary: 300, 60%, 40%; /* #A329A3 */ + --bk-color-pink-secondary: 260, 100%, 70%; /* #9966FF */ + --bk-color-purple-primary: 270, 60%, 40%; /* #6629A3 */ + --bk-color-purple-secondary: 230, 100%, 70%; /* #6680FF */ + --bk-color-blue-primary: 240, 60%, 40%; /* #2929A3 */ + --bk-color-blue-secondary: 200, 100%, 70%; /* #66CCFF */ + + /* Supporting Colors */ + --bk-color-cyan-primary: 200, 60%, 40%; /* #297AA3 */ + --bk-color-cyan-secondary: 160, 100%, 70%; /* #66FFCC */ + --bk-color-green-primary: 160, 60%, 40%; /* #29A37A */ + --bk-color-green-secondary: 110, 100%, 70%; /* #80FF66 */ + --bk-color-yellow-primary: 30, 60%, 40%; /* #A36629 */ + --bk-color-yellow-secondary: 70, 100%, 70%; /* #A36629 */ + --bk-color-orange-primary: 10, 60%, 40%; /* #A33D29 */ + --bk-color-orange-secondary: 30, 100%, 70%; /* #FFB266 */ + --bk-color-red-primary: 330, 60%, 40%; /* #A32966 */ + --bk-color-red-secondary: 0, 100%, 70%; /* #FF6666 */ + + /* ─────────────────────────────────────────────────────── + Component Theme Colors - Light + Using consistent alpha values: + - Line: 0.6 (borders) + - Flat: 0.2 (backgrounds) + - text: 0.9-1.0 (indicators) + ─────────────────────────────────────────────────────── */ + + /* Guide Component Theme */ + --bk-guide-color-line-theme: hsla(var(--bk-color-blue-primary), 0.15); + --bk-guide-color-pattern-theme: hsla(var(--bk-color-purple-secondary), 0.2); + --bk-guide-color-auto-theme: hsla(var(--bk-color-blue-secondary), 0.15); + --bk-guide-color-fixed-theme: hsla(var(--bk-color-blue-secondary), 0.15); + + /* Baseline Component Theme */ + --bk-baseline-color-line-theme: hsla(var(--bk-color-blue-primary), 0.15); + --bk-baseline-color-flat-theme: hsla(var(--bk-color-purple-secondary), 0.2); + + /* Spacer Component Theme */ + --bk-spacer-color-line-theme: hsla(var(--bk-color-purple-primary), 0.6); + --bk-spacer-color-flat-theme: hsla(var(--bk-color-purple-secondary), 0.2); + --bk-spacer-color-text-theme: hsla(var(--bk-color-purple-primary), 1); + + /* Box Component Theme */ + --bk-box-color-line-theme: hsla(var(--bk-color-pink-primary), 0.6); + --bk-box-color-flat-theme: hsla(var(--bk-color-pink-secondary), 0.2); + --bk-box-color-text-theme: hsla(var(--bk-color-pink-primary), 0.9); + + /* Stack Component Theme */ + --bk-stack-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); + --bk-stack-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.2); + --bk-stack-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); + + /* Layout Component Theme */ + --bk-layout-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); + --bk-layout-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.2); + --bk-layout-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); + + /* Padder Component Theme */ + --bk-padder-color-theme: hsla(var(--bk-color-purple-primary), 0.6); +} diff --git a/src/components/styles/theme/tokens.css b/src/components/styles/theme/tokens.css new file mode 100644 index 00000000..43fc709c --- /dev/null +++ b/src/components/styles/theme/tokens.css @@ -0,0 +1,82 @@ +/** + * Baseline Kit Theme Tokens Template + * + * Use this file as a starting point for creating your own custom theme. + * This file contains all theme variables but no values. + * + * To create a custom theme: + * 1. Copy this file + * 2. Fill in your custom values + * 3. Import it in your application after the core styles + */ + +:root { + /* ─────────────────────────────────────────────────────── + Color Palette + Provide HSL values in the format: hue, saturation%, lightness% + ─────────────────────────────────────────────────────── */ + + /* Neutral Colors */ + --bk-color-black-primary: ; + --bk-color-black-secondary: ; + --bk-color-white-primary: ; + --bk-color-white-secondary: ; + + /* Brand Colors */ + --bk-color-pink-primary: ; + --bk-color-pink-secondary: ; + --bk-color-purple-primary: ; + --bk-color-purple-secondary: ; + --bk-color-blue-primary: ; + --bk-color-blue-secondary: ; + + /* Supporting Colors */ + --bk-color-cyan-primary: ; + --bk-color-cyan-secondary: ; + --bk-color-green-primary: ; + --bk-color-green-secondary: ; + --bk-color-yellow-primary: ; + --bk-color-yellow-secondary: ; + --bk-color-orange-primary: ; + --bk-color-orange-secondary: ; + --bk-color-red-primary: ; + --bk-color-red-secondary: ; + + /* ─────────────────────────────────────────────────────── + Component Theme Colors + Use hsla(var(--color-variable), alpha) format for transparency + ─────────────────────────────────────────────────────── */ + + /* Guide Component Theme */ + --bk-guide-color-line-theme: ; + --bk-guide-color-pattern-theme: ; + --bk-guide-color-auto-theme: ; + --bk-guide-color-fixed-theme: ; + + /* Baseline Component Theme */ + --bk-baseline-color-line-theme: ; + --bk-baseline-color-flat-theme: ; + + /* Spacer Component Theme */ + --bk-spacer-color-line-theme: ; + --bk-spacer-color-flat-theme: ; + --bk-spacer-color-text-theme: ; + + /* Box Component Theme */ + --bk-box-color-line-theme: ; + --bk-box-color-flat-theme: ; + --bk-box-color-text-theme: ; + + /* Stack Component Theme */ + --bk-stack-color-line-theme: ; + --bk-stack-color-flat-theme: ; + --bk-stack-color-text-theme: ; + + /* Layout Component Theme */ + --bk-layout-color-line-theme: ; + --bk-layout-color-flat-theme: ; + --bk-layout-color-text-theme: ; + + /* Padder Component Theme */ + --bk-padder-color-theme: ; +} diff --git a/src/components/theme/theme.css b/src/components/theme/theme.css deleted file mode 100644 index bf941e84..00000000 --- a/src/components/theme/theme.css +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Baseline Kit Theme System - * - * Organization: - * 1. Color Palette (HSL values) - * 2. Component Theme Colors - * 3. Dark Mode Overrides - */ - -:root { - /* ─────────────────────────────────────────────────────── - Color Palette - Light Theme - - Primary: More muted/dimmed colors - - Secondary: Brighter, more vibrant colors - ─────────────────────────────────────────────────────── */ - - /* Neutral Colors */ - --bk-color-black-primary: 0, 0%, 10%; /* #1A1A1A */ - --bk-color-black-secondary: 0, 10%, 30%; /* #544545 */ - --bk-color-white-primary: 0, 100%, 90%; /* #FFCCCC */ - --bk-color-white-secondary: 0, 0%, 90%; /* #E6E6E6 */ - - /* Brand Colors */ - --bk-color-pink-primary: 300, 60%, 40%; /* #A329A3 */ - --bk-color-pink-secondary: 260, 100%, 70%; /* #9966FF */ - --bk-color-purple-primary: 270, 60%, 40%; /* #6629A3 */ - --bk-color-purple-secondary: 230, 100%, 70%; /* #6680FF */ - --bk-color-blue-primary: 240, 60%, 40%; /* #2929A3 */ - --bk-color-blue-secondary: 200, 100%, 70%; /* #66CCFF */ - - /* Supporting Colors */ - --bk-color-cyan-primary: 200, 60%, 40%; /* #297AA3 */ - --bk-color-cyan-secondary: 160, 100%, 70%; /* #66FFCC */ - --bk-color-green-primary: 160, 60%, 40%; /* #29A37A */ - --bk-color-green-secondary: 110, 100%, 70%; /* #80FF66 */ - --bk-color-yellow-primary: 30, 60%, 40%; /* #A36629 */ - --bk-color-yellow-secondary: 70, 100%, 70%; /* #A36629 */ - --bk-color-orange-primary: 10, 60%, 40%; /* #A33D29 */ - --bk-color-orange-secondary: 30, 100%, 70%; /* #FFB266 */ - --bk-color-red-primary: 330, 60%, 40%; /* #A32966 */ - --bk-color-red-secondary: 0, 100%, 70%; /* #FF6666 */ - - /* ─────────────────────────────────────────────────────── - Component Theme Colors - Light - Using consistent alpha values: - - Line: 0.6 (borders) - - Flat: 0.2 (backgrounds) - - text: 0.9-1.0 (indicators) - ─────────────────────────────────────────────────────── */ - - /* Guide Component Theme */ - --bk-guide-color-line-theme: hsla(var(--bk-color-blue-primary), 0.15); - --bk-guide-color-pattern-theme: hsla(var(--bk-color-purple-secondary), 0.2); - --bk-guide-color-auto-theme: hsla(var(--bk-color-blue-secondary), 0.15); - --bk-guide-color-fixed-theme: hsla(var(--bk-color-blue-secondary), 0.15); - - /* Baseline Component Theme */ - --bk-baseline-color-line-theme: hsla(var(--bk-color-blue-primary), 0.15); - --bk-baseline-color-flat-theme: hsla(var(--bk-color-purple-secondary), 0.2); - - /* Spacer Component Theme */ - --bk-spacer-color-line-theme: hsla(var(--bk-color-purple-primary), 0.6); - --bk-spacer-color-flat-theme: hsla(var(--bk-color-purple-secondary), 0.2); - --bk-spacer-color-text-theme: hsla(var(--bk-color-purple-primary), 1); - - /* Box Component Theme */ - --bk-box-color-line-theme: hsla(var(--bk-color-pink-primary), 0.6); - --bk-box-color-flat-theme: hsla(var(--bk-color-pink-secondary), 0.2); - --bk-box-color-text-theme: hsla(var(--bk-color-pink-primary), 0.9); - - /* Stack Component Theme */ - --bk-stack-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); - --bk-stack-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.2); - --bk-stack-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); - - /* Layout Component Theme */ - --bk-layout-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); - --bk-layout-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.2); - --bk-layout-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); - - /* Padder Component Theme */ - --bk-padder-color-theme: hsla(var(--bk-color-purple-primary), 0.6); -} - -/* ─────────────────────────────────────────────────────── - Dark Theme - - Inverts Primary/Secondary relationships - - Adjusts alpha values for better contrast -─────────────────────────────────────────────────────── */ - -@media (prefers-color-scheme: dark) { - :root { - /* Neutral Colors - Dark */ - --bk-color-black-primary: 0, 10%, 30%; /* #544545 */ - --bk-color-black-secondary: 0, 0%, 10%; /* #1A1A1A */ - --bk-color-white-primary: 0, 0%, 90%; /* #E6E6E6 */ - --bk-color-white-secondary: 0, 100%, 90%; /* #FFCCCC */ - - /* Brand Colors - Dark */ - --bk-color-pink-primary: 260, 100%, 70%; /* #9966FF */ - --bk-color-pink-secondary: 300, 60%, 40%; /* #A329A3 */ - --bk-color-purple-primary: 230, 100%, 70%; /* #6680FF */ - --bk-color-purple-secondary: 270, 60%, 40%; /* #6629A3 */ - --bk-color-blue-primary: 200, 100%, 70%; /* #66CCFF */ - --bk-color-blue-secondary: 240, 60%, 40%; /* #2929A3 */ - - /* Supporting Colors - Dark */ - --bk-color-cyan-primary: 160, 100%, 70%; /* #66FFCC */ - --bk-color-cyan-secondary: 200, 60%, 40%; /* #297AA3 */ - --bk-color-green-primary: 110, 100%, 70%; /* #80FF66 */ - --bk-color-green-secondary: 160, 60%, 40%; /* #29A37A */ - --bk-color-yellow-primary: 70, 100%, 70%; /* #A36629 */ - --bk-color-yellow-secondary: 30, 60%, 40%; /* #A36629 */ - --bk-color-orange-primary: 30, 100%, 70%; /* #FFB266 */ - --bk-color-orange-secondary: 10, 60%, 40%; /* #A33D29 */ - --bk-color-red-primary: 0, 100%, 70%; /* #FF6666 */ - --bk-color-red-secondary: 330, 60%, 40%; /* #A32966 */ - - /* Component Theme Overrides - Dark */ - --bk-baseline-color-line-theme: hsla(var(--bk-color-white-primary), 0.1); - --bk-baseline-color-flat-theme: hsla(var(--bk-color-white-secondary), 0.2); - - --bk-box-color-line-theme: hsla(var(--bk-color-pink-primary), 0.6); - --bk-box-color-flat-theme: hsla(var(--bk-color-pink-secondary), 0.3); - --bk-box-color-text-theme: hsla(var(--bk-color-pink-primary), 0.9); - - --bk-guide-color-line-theme: hsla(var(--bk-color-white-primary), 0.1); - --bk-guide-color-pattern-theme: hsla(var(--bk-color-purple-secondary), 0.25); - --bk-guide-color-auto-theme: hsla(var(--bk-color-blue-secondary), 0.2); - --bk-guide-color-fixed-theme: hsla(var(--bk-color-blue-secondary), 0.2); - - --bk-stack-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); - --bk-stack-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.3); - --bk-stack-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); - - --bk-layout-color-line-theme: hsla(var(--bk-color-red-primary), 0.6); - --bk-layout-color-flat-theme: hsla(var(--bk-color-red-secondary), 0.3); - --bk-layout-color-text-theme: hsla(var(--bk-color-red-primary), 0.9); - } -} \ No newline at end of file diff --git a/src/components/types.ts b/src/components/types.ts index 4c5f2541..95f96395 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -44,28 +44,28 @@ export type Spacing = */ export type PaddingValue = | number - | [number, number] // [block, inline] - | [number, number, number, number] // [top, right, bottom, left] + | [number, number] // [block, inline] + | [number, number, number, number] // [top, right, bottom, left] | { - top?: number; - bottom?: number; - left?: number; - right?: number; -} + top?: number + bottom?: number + left?: number + right?: number + } /** Resolved padding values for all edges after normalization. */ export type Padding = { - top: number; - right: number; - bottom: number; - left: number; + top: number + right: number + bottom: number + left: number } /** Props interface for components that support spacing configuration. */ export type SpacingProps = { - padding?: PaddingValue; - block?: Spacing; - inline?: Spacing; + padding?: PaddingValue + block?: Spacing + inline?: Spacing } // Grid Types ------------------------------------------------------------------ @@ -86,11 +86,11 @@ export type GuideColumnsPattern = readonly GuideColumnValue[] /** Valid grid alignment values. */ export const GRID_ALIGNMENTS = ['start', 'center', 'end'] as const -export type GridAlignment = typeof GRID_ALIGNMENTS[number] +export type GridAlignment = (typeof GRID_ALIGNMENTS)[number] /** Valid component variants affecting visual style. */ export const PADD_VARIANTS = ['line', 'flat'] as const -export type PaddedVariant = typeof PADD_VARIANTS[number] +export type PaddedVariant = (typeof PADD_VARIANTS)[number] // Component Base Types -------------------------------------------------------- @@ -99,29 +99,31 @@ export type PaddedVariant = typeof PADD_VARIANTS[number] * Provides consistent sizing, spacing, styling, and debugging options. */ export type ComponentsProps = { - debugging?: DebuggingMode; - className?: string; - style?: React.CSSProperties; - height?: React.CSSProperties['height']; - width?: React.CSSProperties['width']; + debugging?: DebuggingMode + className?: string + style?: React.CSSProperties + height?: React.CSSProperties['height'] + width?: React.CSSProperties['width'] } & SpacingProps /** Base configuration for components that support padding. */ export type PaddedBaseConfig = { - base?: number; - color?: React.CSSProperties['color'] | React.CSSProperties['backgroundColor']; - zIndex?: React.CSSProperties['zIndex']; + base?: number + color?: React.CSSProperties['color'] | React.CSSProperties['backgroundColor'] + zIndex?: React.CSSProperties['zIndex'] } export type Variant = 'line' | 'flat' | 'pattern' -export type Gaps = { - gap?: React.CSSProperties['gap'] - rowGap?: never - columnGap?: never -} | { - /** When using separate gaps, omit unified gap */ - gap?: never - rowGap?: React.CSSProperties['rowGap'] - columnGap?: React.CSSProperties['columnGap'] -} +export type Gaps = + | { + gap?: React.CSSProperties['gap'] + rowGap?: never + columnGap?: never + } + | { + /** When using separate gaps, omit unified gap */ + gap?: never + rowGap?: React.CSSProperties['rowGap'] + columnGap?: React.CSSProperties['columnGap'] + } diff --git a/src/hooks/index.ts b/src/hooks/index.ts index e0466fde..e3b4e1aa 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -14,4 +14,7 @@ export * from './useGuide' // Configuration export * from './useConfig' -export * from './useDebug' \ No newline at end of file +export * from './useDebug' + +// Don't export useIsClient as it's only used internally +// export * from './useIsClient' diff --git a/src/hooks/useBaseline.ts b/src/hooks/useBaseline.ts index 9daaf33b..9eaf0f61 100644 --- a/src/hooks/useBaseline.ts +++ b/src/hooks/useBaseline.ts @@ -66,7 +66,7 @@ export function useBaseline( snapping = 'none', spacing = {}, warnOnMisalignment = false, - }: BaselineOptions = {}, + }: BaselineOptions = {} ): BaselineResult { if (base < 1) { throw new Error('Base must be >= 1 for baseline alignment.') @@ -83,10 +83,14 @@ export function useBaseline( const isAligned = height % base === 0 // Log the warning only once - if (!isAligned && warnOnMisalignment && process.env.NODE_ENV === 'development') { + if ( + !isAligned && + warnOnMisalignment && + process.env.NODE_ENV === 'development' + ) { if (!hasWarnedRef.current) { console.warn( - `[useBaseline] Element height (${height}px) is not aligned with base (${base}px).`, + `[useBaseline] Element height (${height}px) is not aligned with base (${base}px).` ) hasWarnedRef.current = true // Mark warning as logged } @@ -104,7 +108,12 @@ export function useBaseline( } // Snap exactly once. - const finalPadding = calculateSnappedSpacing(height, base, initialPadding, snapping) + const finalPadding = calculateSnappedSpacing( + height, + base, + initialPadding, + snapping + ) didSnapRef.current = true return { padding: finalPadding, isAligned, height } diff --git a/src/hooks/useConfig.ts b/src/hooks/useConfig.ts index b70ef933..07b279a0 100644 --- a/src/hooks/useConfig.ts +++ b/src/hooks/useConfig.ts @@ -1,8 +1,8 @@ import { useMemo } from 'react' -import { Config, useDefaultConfig } from '@components' +import { ConfigSchema, useDefaultConfig } from '@components' /** Type helper that merges base configuration with component-specific settings. */ -export type ComponentConfig = Config[K] & { +export type ComponentConfig = ConfigSchema[K] & { /** Base unit for spacing calculations */ base: number } @@ -41,12 +41,14 @@ export type ComponentConfig = Config[K] & { * } * ``` */ -export function useConfig(component: K): ComponentConfig { +export function useConfig( + component: K +): ComponentConfig { const defaultConfig = useDefaultConfig() return useMemo(() => { return Object.assign( { base: defaultConfig.base }, - defaultConfig[component], + defaultConfig[component] ) as ComponentConfig }, [defaultConfig, component]) -} \ No newline at end of file +} diff --git a/src/hooks/useDebug.ts b/src/hooks/useDebug.ts index 8679b379..15c1d148 100644 --- a/src/hooks/useDebug.ts +++ b/src/hooks/useDebug.ts @@ -3,13 +3,13 @@ import { DebuggingMode } from '../components/Config/Config' interface DebugResult { /** Whether debug visuals should be shown */ - isShown: boolean; + isShown: boolean /** Whether debug features exist but are hidden */ - isHidden: boolean; + isHidden: boolean /** Whether debug features are disabled */ - isNone: boolean; + isNone: boolean /** Current debugging mode */ - debugging: DebuggingMode | undefined; + debugging: DebuggingMode | undefined } /** @@ -50,7 +50,7 @@ interface DebugResult { */ export function useDebug( debuggingProp?: DebuggingMode, - debuggingConfig?: DebuggingMode, + debuggingConfig?: DebuggingMode ): DebugResult { return useMemo(() => { const effective = debuggingProp ?? debuggingConfig @@ -61,4 +61,4 @@ export function useDebug( debugging: effective, } }, [debuggingProp, debuggingConfig]) -} \ No newline at end of file +} diff --git a/src/hooks/useGuide.ts b/src/hooks/useGuide.ts index 13205f19..23a49e75 100644 --- a/src/hooks/useGuide.ts +++ b/src/hooks/useGuide.ts @@ -1,17 +1,18 @@ import * as React from 'react' -import { GuideConfig, GuideColumnsPattern, isValidGuidePattern } from '@components' +import { GuideConfig, GuideColumnsPattern } from '@components' +import { isValidGuidePattern } from '@/components/Guide/validation' import { formatValue, convertValue, normalizeValue } from '@utils' import { useMeasure } from './useMeasure' export interface GuideResult { /** CSS grid template string */ - template: string; + template: string /** Total number of columns */ - columnsCount: number; + columnsCount: number /** Final gap size in pixels */ - calculatedGap: number; + calculatedGap: number /** Whether the configuration is valid */ - isValid: boolean; + isValid: boolean } /** @@ -64,7 +65,7 @@ export interface GuideResult { */ export function useGuide( ref: React.RefObject, - config: GuideConfig, + config: GuideConfig ): GuideResult { const { width } = useMeasure(ref) const hasWarnedRef = React.useRef(false) // Track if warning has been logged @@ -73,7 +74,9 @@ export function useGuide( // Default values const variant = config.variant ?? 'line' const base = config.base ?? 8 - // Normalize the gap using the base value + + // The gap is already adjusted in createGridConfig for line variants + // So we should use config.gap directly without further adjustment const gap = normalizeValue(config.gap ?? 0, { base }) // Return invalid result if no width @@ -88,106 +91,132 @@ export function useGuide( try { switch (variant) { - case 'line': { - // Simple vertical lines - const columns = Math.max(1, Math.floor(width / (gap + 1)) + 1) - return { - template: `repeat(${columns}, 1px)`, - columnsCount: columns, - calculatedGap: gap, - isValid: true, - } - } + case 'line': { + // Simple vertical lines + // Account for -1px reduction in each gap when gap > 0 + const finalGap = gap === 0 ? 0 : gap - 1 + const actualGapWithLine = finalGap + 1 - case 'pattern': { - // Custom column pattern - if (!isValidGuidePattern(config.columns)) { - throw new Error('Invalid "pattern" columns array') - } - const columnsArr = (config.columns as GuideColumnsPattern).map(col => { - if (typeof col === 'number') return `${col}px` - return col - }) + let columns: number + + if (finalGap === 0) { + // When gap is 0, need a column per pixel + 1 + columns = Math.max(1, Math.floor(width) + 1) + } else { + // For line variant with gap > 0: + // Account for the -1px reduction in each gap + columns = Math.max( + 1, + Math.floor((width + 1) / actualGapWithLine) + 1 + ) + } - // Validate no zero widths - if (columnsArr.some(c => c === '0' || c === '0px')) { return { - template: 'none', - columnsCount: 0, - calculatedGap: 0, - isValid: false, + template: `repeat(${columns}, 1px)`, + columnsCount: columns, + calculatedGap: gap > 0 ? gap - 1 : gap, + isValid: true, } } - return { - template: columnsArr.join(' '), - columnsCount: columnsArr.length, - calculatedGap: gap, - isValid: true, - } - } + case 'pattern': { + // Custom column pattern + if (!config.columns || !Array.isArray(config.columns)) { + throw new Error('Missing or invalid pattern columns') + } - case 'fixed': { - // Fixed number of columns - const colCount = typeof config.columns === 'number' ? config.columns : 0 - if (colCount < 1) { - throw new Error(`Invalid columns count: ${colCount}`) - } - const colWidth = config.columnWidth - ? formatValue(config.columnWidth) - : '1fr' - - return { - template: `repeat(${colCount}, ${colWidth})`, - columnsCount: colCount, - calculatedGap: gap, - isValid: true, - } - } + if (!isValidGuidePattern(config.columns)) { + throw new Error('Invalid "pattern" columns array') + } + + const columnsArr = (config.columns as GuideColumnsPattern).map( + (col) => { + if (typeof col === 'number') return `${col}px` + return col + } + ) + + // Validate no zero widths + if (columnsArr.some((c) => c === '0' || c === '0px')) { + return { + template: 'none', + columnsCount: 0, + calculatedGap: 0, + isValid: false, + } + } - case 'auto': { - // Auto-fitting columns - const colWidth = config.columnWidth ?? 'auto' - if (colWidth === 'auto') { return { - template: 'repeat(auto-fit, minmax(0, 1fr))', - columnsCount: 1, + template: columnsArr.join(' '), + columnsCount: columnsArr.length, calculatedGap: gap, isValid: true, } } - const colWidthStr = - typeof colWidth === 'number' ? `${colWidth}px` : colWidth.toString() - - const pxVal = convertValue(colWidthStr) ?? 0 - const columns = pxVal > 0 - ? Math.max(1, Math.floor((width + gap) / (pxVal + gap))) - : 1 - - return { - template: `repeat(auto-fit, minmax(${colWidthStr}, 1fr))`, - columnsCount: columns, - calculatedGap: gap, - isValid: true, + + case 'fixed': { + // Fixed number of columns + const colCount = + typeof config.columns === 'number' ? config.columns : 0 + if (colCount < 1) { + throw new Error(`Invalid columns count: ${colCount}`) + } + const colWidth = config.columnWidth + ? formatValue(config.columnWidth) + : '1fr' + + return { + template: `repeat(${colCount}, ${colWidth})`, + columnsCount: colCount, + calculatedGap: gap, + isValid: true, + } } - } - default: { - if (!hasWarnedRef.current) { - console.warn( - `[useGuide] Unknown variant "${variant}". Falling back to "line".`, - ) - hasWarnedRef.current = true // Mark warning as logged + case 'auto': { + // Auto-filling columns + const colWidth = config.columnWidth ?? 'auto' + if (colWidth === 'auto') { + return { + template: 'repeat(auto-fill, minmax(0, 1fr))', + columnsCount: 1, + calculatedGap: gap, + isValid: true, + } + } + const colWidthStr = + typeof colWidth === 'number' ? `${colWidth}px` : colWidth.toString() + + const pxVal = convertValue(colWidthStr) ?? 0 + const columns = + pxVal > 0 + ? Math.max(1, Math.floor((width + gap) / (pxVal + gap))) + : 1 + + return { + template: `repeat(auto-fill, ${colWidthStr})`, + columnsCount: columns, + calculatedGap: gap, + isValid: true, + } } - const columns = Math.max(1, Math.floor(width / (gap + 1)) + 1) - return { - template: `repeat(${columns}, 1px)`, - columnsCount: columns, - calculatedGap: gap, - isValid: true, + + default: { + if (!hasWarnedRef.current) { + console.warn( + `[useGuide] Unknown variant "${variant}". Falling back to "line".` + ) + hasWarnedRef.current = true // Mark warning as logged + } + const columns = Math.max(1, Math.floor(width / (gap + 1)) + 1) + return { + template: `repeat(${columns}, 1px)`, + columnsCount: columns, + calculatedGap: gap, + isValid: true, + } } } - } } catch (error) { console.warn('Error in useGuide:', error) return { diff --git a/src/hooks/useIsClient.ts b/src/hooks/useIsClient.ts new file mode 100644 index 00000000..99e5472d --- /dev/null +++ b/src/hooks/useIsClient.ts @@ -0,0 +1,18 @@ +import { useEffect, useState } from 'react' + +/** + * Hook to determine if the code is running on the client side. + * + * @returns Boolean indicating if the code is running in a browser environment + */ +export function useIsClient() { + // Start with false for SSR + const [isClient, setIsClient] = useState(false) + + // Only run once on mount + useEffect(() => { + setIsClient(true) + }, []) + + return isClient +} diff --git a/src/hooks/useMeasure.ts b/src/hooks/useMeasure.ts index d1dbcce4..6d6f8c2f 100644 --- a/src/hooks/useMeasure.ts +++ b/src/hooks/useMeasure.ts @@ -3,11 +3,11 @@ import { rafThrottle } from '@utils' export interface MeasureResult { /** Measured width in pixels */ - width: number; + width: number /** Measured height in pixels */ - height: number; + height: number /** Function to force a remeasurement */ - refresh: () => void; + refresh: () => void } /** @@ -35,7 +35,9 @@ export interface MeasureResult { * } * ``` */ -export function useMeasure(ref: React.RefObject): MeasureResult { +export function useMeasure( + ref: React.RefObject +): MeasureResult { const [dimensions, setDimensions] = React.useState({ width: 0, height: 0 }) // measure() reads getBoundingClientRect() from ref.current @@ -47,8 +49,8 @@ export function useMeasure(ref: React.RefObject): MeasureRes width: rect ? Math.round(rect.width) : 0, height: rect ? Math.round(rect.height) : 0, } - setDimensions(prev => - prev.width === next.width && prev.height === next.height ? prev : next, + setDimensions((prev) => + prev.width === next.width && prev.height === next.height ? prev : next ) } catch { setDimensions({ width: 0, height: 0 }) @@ -59,11 +61,14 @@ export function useMeasure(ref: React.RefObject): MeasureRes const refresh = React.useMemo(() => rafThrottle(measure), [measure]) // On mount (or when ref changes) perform an immediate measurement. - React.useLayoutEffect(() => { measure() }, [measure]) + React.useLayoutEffect(() => { + if (typeof window === 'undefined') return + measure() + }, [measure]) // Set up a ResizeObserver on mount. React.useLayoutEffect(() => { - if (!ref.current) return + if (typeof window === 'undefined' || !ref.current) return const observer = new ResizeObserver(() => { refresh() }) diff --git a/src/hooks/useVirtual.ts b/src/hooks/useVirtual.ts index fcd83737..7d739106 100644 --- a/src/hooks/useVirtual.ts +++ b/src/hooks/useVirtual.ts @@ -1,15 +1,21 @@ -import { RefObject, useCallback, useLayoutEffect, useMemo, useState } from 'react' +import { + RefObject, + useCallback, + useLayoutEffect, + useMemo, + useState, +} from 'react' import { rafThrottle } from '@utils' type VirtualResult = { /** Total number of items/lines to virtualize */ - totalLines: number; + totalLines: number /** Height of each item in pixels */ - lineHeight: number; + lineHeight: number /** Reference to the scrollable container */ - containerRef: RefObject; + containerRef: RefObject /** Additional items to render above/below viewport */ - buffer?: number | string; + buffer?: number | string } /** @@ -63,9 +69,10 @@ export function useVirtual({ buffer = 0, }: VirtualResult) { // Convert buffer to numeric value - const numericBuffer = useMemo(() => - typeof buffer === 'number' ? buffer : parseInt(buffer, 10) || 0 - , [buffer]) + const numericBuffer = useMemo( + () => (typeof buffer === 'number' ? buffer : parseInt(buffer, 10) || 0), + [buffer] + ) /** * Calculates the visible range of items based on scroll position @@ -99,23 +106,27 @@ export function useVirtual({ updateRangeThrottled() }) - // Throttle updates for performance const updateRange = useCallback(() => { - setVisibleRange(prev => { + setVisibleRange((prev) => { const next = calculateRange() return prev.start !== next.start || prev.end !== next.end ? next : prev }) }, [calculateRange]) - const updateRangeThrottled = useMemo(() => rafThrottle(updateRange), [updateRange]) + const updateRangeThrottled = useMemo( + () => rafThrottle(updateRange), + [updateRange] + ) useLayoutEffect(() => { const element = containerRef.current if (!element) return // Use IntersectionObserver for visibility tracking - const observer = new IntersectionObserver(updateRangeThrottled, { threshold: 0 }) + const observer = new IntersectionObserver(updateRangeThrottled, { + threshold: 0, + }) observer.observe(element) updateRangeThrottled() @@ -133,8 +144,8 @@ function useWindowEvents(events: string[], handler: () => void) { useLayoutEffect(() => { const wrappedHandler = () => stableHandler() - events.forEach(evt => window.addEventListener(evt, wrappedHandler)) - return () => events.forEach(evt => window.removeEventListener(evt, wrappedHandler)) + events.forEach((evt) => window.addEventListener(evt, wrappedHandler)) + return () => + events.forEach((evt) => window.removeEventListener(evt, wrappedHandler)) }, [events, stableHandler]) } - diff --git a/src/index.ts b/src/index.ts index 0f12892a..1f857bd1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,9 +3,36 @@ * Lightweight development tool for visualizing and debugging grid systems and spacing in React * applications. It provides configurable overlays for both column-based and baseline grids, flexible spacing components, * and theme-aware configuration—all optimized for performance and built with TypeScript. + * + * Export Strategy: + * - Only components and types required by consumers are exported + * - Components are directly imported from their respective directories rather than through the components/index.ts barrel + * - SSR utilities (isSSR, safeClientValue) are exported for advanced consumer use cases + * - Internal utilities, helper functions, and implementation details are kept private + * * @module baseline-kit */ -export * from './components' -export * from './hooks' -export * from './utils' \ No newline at end of file +// Public API Components +export { Config } from './components/Config' +export { Baseline } from './components/Baseline' +export { Guide } from './components/Guide' +export { Box } from './components/Box' +export { Stack } from './components/Stack' +export { Layout } from './components/Layout' +export { Spacer } from './components/Spacer' +export { Padder } from './components/Padder' + +// Public API Types +export type { DebuggingMode, ConfigSchema } from './components/Config/Config' +export type { GuideVariant, Spacing, SpacingProps } from './components/types' +export type { BaselineProps } from './components/Baseline' +export type { BoxProps } from './components/Box' +export type { GuideProps } from './components/Guide' +export type { LayoutProps } from './components/Layout' +export type { StackProps } from './components/Stack' +export type { IndicatorNode, SpacerProps } from './components/Spacer' +export type { PadderProps } from './components/Padder' + +// Public API Utilities +export { isSSR, safeClientValue } from './utils/ssr' diff --git a/src/styles.ts b/src/styles.ts new file mode 100644 index 00000000..0b48ec89 --- /dev/null +++ b/src/styles.ts @@ -0,0 +1,8 @@ +/** + * @file Style Entry Point + * @description Clean import path for core CSS styles + * @module baseline-kit/styles + */ + +// This file exists only to provide a clean import path +import './components/styles/core.css' diff --git a/src/theme.ts b/src/theme.ts new file mode 100644 index 00000000..68c76590 --- /dev/null +++ b/src/theme.ts @@ -0,0 +1,8 @@ +/** + * @file Theme Entry Point + * @description Clean import path for theme CSS styles + * @module baseline-kit/theme + */ + +// This file exists only to provide a clean import path +import './components/styles/theme.css' diff --git a/src/utils/convert.ts b/src/utils/convert.ts index 91c2dcfa..078d4d1a 100644 --- a/src/utils/convert.ts +++ b/src/utils/convert.ts @@ -2,15 +2,15 @@ import { parseUnit } from './parse' export interface ConversionContext { /** Parent element dimension for relative units */ - parentSize?: number; + parentSize?: number /** Viewport width for vw units */ - viewportWidth?: number; + viewportWidth?: number /** Viewport height for vh units */ - viewportHeight?: number; + viewportHeight?: number /** Root font size for rem units */ - rootFontSize?: number; + rootFontSize?: number /** Parent font size for em units */ - parentFontSize?: number; + parentFontSize?: number } const DEFAULT_CONTEXT: Required = { @@ -24,43 +24,34 @@ const DEFAULT_CONTEXT: Required = { /** Conversion factors for absolute units to pixels */ export const ABSOLUTE_UNIT_CONVERSIONS: Record = { px: 1, - in: 96, // 1in = 96px - cm: 37.8, // 1cm = 37.8px - mm: 3.78, // 1mm = 3.78px - pt: 1.33, // 1pt = 1.33px - pc: 16, // 1pc = 16px + in: 96, // 1in = 96px + cm: 37.8, // 1cm = 37.8px + mm: 3.78, // 1mm = 3.78px + pt: 1.33, // 1pt = 1.33px + pc: 16, // 1pc = 16px } /** Supported relative CSS units */ -export const RELATIVE_UNITS: string[] = ['em', 'rem', 'vh', 'vw', 'vmin', 'vmax', '%'] +export const RELATIVE_UNITS: string[] = [ + 'em', + 'rem', + 'vh', + 'vw', + 'vmin', + 'vmax', + '%', +] /** * Converts CSS values to pixels. * - * @remarks - * Handles conversion of: - * - Absolute units (px, in, cm, mm, pt, pc) - * - Relative units (em, rem, vh, vw, vmin, vmax, %) - * - Number values (treated as pixels) - * * @param value - CSS value to convert * @param context - Optional context for relative unit conversion * @returns Value in pixels or null if conversion fails - * - * @example - * ```ts - * // Absolute units - * convertValue('100px') // => 100 - * convertValue('1in') // => 96 - * - * // Relative units with context - * convertValue('50%', { parentSize: 200 }) // => 100 - * convertValue('2em', { parentFontSize: 16 }) // => 32 - * ``` */ export function convertValue( value: number | string | undefined, - context?: ConversionContext, + context?: ConversionContext ): number | null { if (typeof value === 'number') return value if (typeof value !== 'string') return null @@ -82,23 +73,23 @@ export function convertValue( if (RELATIVE_UNITS.includes(unit)) { const ctx = { ...DEFAULT_CONTEXT, ...context } switch (unit) { - case 'em': - return num * ctx.parentFontSize - case 'rem': - return num * ctx.rootFontSize - case 'vh': - return (num / 100) * ctx.viewportHeight - case 'vw': - return (num / 100) * ctx.viewportWidth - case 'vmin': - return (num / 100) * Math.min(ctx.viewportWidth, ctx.viewportHeight) - case 'vmax': - return (num / 100) * Math.max(ctx.viewportWidth, ctx.viewportHeight) - case '%': - return (num / 100) * ctx.parentSize - default: - return null + case 'em': + return num * ctx.parentFontSize + case 'rem': + return num * ctx.rootFontSize + case 'vh': + return (num / 100) * ctx.viewportHeight + case 'vw': + return (num / 100) * ctx.viewportWidth + case 'vmin': + return (num / 100) * Math.min(ctx.viewportWidth, ctx.viewportHeight) + case 'vmax': + return (num / 100) * Math.max(ctx.viewportWidth, ctx.viewportHeight) + case '%': + return (num / 100) * ctx.parentSize + default: + return null } } return null -} \ No newline at end of file +} diff --git a/src/utils/grid.ts b/src/utils/grid.ts index 97b37880..49d94667 100644 --- a/src/utils/grid.ts +++ b/src/utils/grid.ts @@ -12,9 +12,9 @@ import * as React from 'react' * * @param span - Optional equal span for both rows and columns * @param colSpan - Optional column span value - * @param rowSpan - Optional row span value + * @param rowSpan - Optional row span value * @returns CSS properties object with grid span values - * + * * @example * ```ts * createGridSpanStyles(2) // => { gridColumn: "span 2", gridRow: "span 2" } @@ -27,7 +27,7 @@ export const createGridSpanStyles = ( rowSpan?: number ): React.CSSProperties => { const gridStyles: React.CSSProperties = {} - + if (span !== undefined) { gridStyles.gridColumn = `span ${span}` gridStyles.gridRow = `span ${span}` @@ -39,6 +39,6 @@ export const createGridSpanStyles = ( gridStyles.gridRow = `span ${rowSpan}` } } - + return gridStyles -} \ No newline at end of file +} diff --git a/src/utils/index.ts b/src/utils/index.ts index edd3dec3..6ae245d3 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -20,4 +20,4 @@ export * from './parse' export * from './timing' // SSR Compatibility Utilities -export * from './ssr' \ No newline at end of file +export * from './ssr' diff --git a/src/utils/math.ts b/src/utils/math.ts index e7318f15..e1c981f0 100644 --- a/src/utils/math.ts +++ b/src/utils/math.ts @@ -3,28 +3,15 @@ import { convertValue } from './convert' /** * Calculates the modulo (remainder) of a CSS value when divided by a base unit. * - * @remarks - * Useful for: - * - Baseline grid alignment - * - Spacing calculations - * - Grid fitting - * * @param value - Input value (number or CSS string) * @param base - Base unit to calculate remainder against * @param options - Optional calculation controls * @returns Remainder in pixel units (e.g., "6px") - * - * @example - * ```ts - * moduloize(14, 8) // => "6px" - * moduloize('14px', 8) // => "6px" - * moduloize(14.3, 8, { round: false }) // => "6.3px" - * ``` */ export function moduloize( value: number | string | undefined, base: number, - options?: { round?: boolean }, + options?: { round?: boolean } ): string { const doRound = options?.round ?? true const num = @@ -32,7 +19,7 @@ export function moduloize( ? 0 : typeof value === 'number' ? value - : convertValue(value) ?? 0 + : (convertValue(value) ?? 0) const normalized = doRound ? Math.round(num) : num const remainder = normalized % base return `${remainder}px` @@ -45,13 +32,6 @@ export function moduloize( * @param min - Minimum allowed value * @param max - Maximum allowed value * @returns Clamped value - * - * @example - * ```ts - * clamp(5, 0, 10) // => 5 - * clamp(-5, 0, 10) // => 0 - * clamp(15, 0, 10) // => 10 - * ``` */ export function clamp(value: number, min: number, max: number): number { return Math.min(Math.max(value, min), max) @@ -60,24 +40,15 @@ export function clamp(value: number, min: number, max: number): number { /** * Rounds a number to specified precision. * - * @remarks - * Supports: - * - Positive precision (decimal places) - * - Negative precision (powers of 10) - * * @param value - Number to round * @param precision - Decimal places (default: 0) * @returns Rounded number - * - * @example - * ```ts - * round(1.234, 2) // => 1.23 - * round(123.4, -1) // => 120 - * ``` */ export function round(value: number, precision = 0): number { if (precision >= 0) { - return Number((Math.round(value * 10 ** precision) / 10 ** precision).toFixed(precision)) + return Number( + (Math.round(value * 10 ** precision) / 10 ** precision).toFixed(precision) + ) } else { const factor = 10 ** Math.abs(precision) return Math.round(value / factor) * factor @@ -87,30 +58,24 @@ export function round(value: number, precision = 0): number { /** Parameters for row count calculation */ type RowCountParams = { /** Available height for the container */ - height?: number; + height?: number /** Top padding/offset value */ - top: number; + top: number /** Bottom padding/offset value */ - bottom: number; + bottom: number /** Base unit for calculations */ - base: number; + base: number } /** * Calculates the number of rows that fit in the available space. * Ensures at least one row is always returned. - * + * * @param params - Parameters for calculation * @returns Number of rows that fit in the space - * - * @example - * ```ts - * calculateRowCount({ height: 100, top: 10, bottom: 10, base: 8 }) // => 10 - * calculateRowCount({ height: 20, top: 0, bottom: 0, base: 8 }) // => 2 - * ``` */ export function calculateRowCount(params: RowCountParams): number { const { height, top, bottom, base } = params const totalHeight = (height ?? 0) - (top + bottom) return Math.max(1, Math.floor(totalHeight / base)) -} \ No newline at end of file +} diff --git a/src/utils/merge.ts b/src/utils/merge.ts index 1b0f4446..08bca715 100644 --- a/src/utils/merge.ts +++ b/src/utils/merge.ts @@ -43,12 +43,19 @@ export const mergeClasses = ( */ export const mergeStyles = ( ...styles: Array -): T => Object.assign({}, ...styles.filter((style): style is T => style !== undefined)) +): T => + Object.assign( + {}, + ...styles.filter((style): style is T => style !== undefined) + ) /** * Assigns a value to a React ref. */ -function assignRef(ref: React.Ref | null | undefined, node: T | null): void { +function assignRef( + ref: React.Ref | null | undefined, + node: T | null +): void { if (!ref) return if (typeof ref === 'function') { ref(node) @@ -87,7 +94,7 @@ export function mergeRefs( ...refs: Array | null | undefined> ): React.RefCallback { return (node: T | null) => { - refs.forEach(ref => { + refs.forEach((ref) => { assignRef(ref, node) }) } @@ -98,20 +105,20 @@ export function mergeRefs( */ export type StyleOverrideParams = { /** CSS variable key to potentially override */ - key: string; + key: string /** Value to use if override is needed */ - value: string; + value: string /** Default styles to compare against */ - defaultStyles: Record; + defaultStyles: Record /** Special case dimensions that should be skipped for specific values */ skipDimensions?: { /** Dimensions that should be skipped when they're set to "fit-content" */ - fitContent?: string[]; + fitContent?: string[] /** Dimensions that should be skipped when they're set to "auto" */ - auto?: string[]; + auto?: string[] /** Dimensions that should be skipped when they're set to % values (like "100%") */ - fullSize?: string[]; - }; + fullSize?: string[] + } } /** @@ -150,13 +157,15 @@ export type StyleOverrideParams = { export function createStyleOverride( params: StyleOverrideParams | string, value?: string, - defaultStyles?: Record, + defaultStyles?: Record ): Record { // Handle both object parameter and individual arguments for backward compatibility const key = typeof params === 'string' ? params : params.key const val = typeof params === 'string' ? value! : params.value - const defaults = typeof params === 'string' ? defaultStyles! : params.defaultStyles - const skipDimensions = typeof params === 'object' ? params.skipDimensions : undefined + const defaults = + typeof params === 'string' ? defaultStyles! : params.defaultStyles + const skipDimensions = + typeof params === 'object' ? params.skipDimensions : undefined // Skip dimensions based on specific values if (skipDimensions) { @@ -171,12 +180,14 @@ export function createStyleOverride( } // Skip '100%' or '100vh/vw' dimensions (Guide, some Spacer patterns) - if (skipDimensions.fullSize?.includes(key) && - (val === '100%' || val === '100vh' || val === '100vw')) { + if ( + skipDimensions.fullSize?.includes(key) && + (val === '100%' || val === '100vh' || val === '100vw') + ) { return {} } } // Only apply override if value differs from default return val !== defaults[key] ? { [key]: val } : {} -} \ No newline at end of file +} diff --git a/src/utils/normalize.ts b/src/utils/normalize.ts index 2995d4c3..3cf95b9d 100644 --- a/src/utils/normalize.ts +++ b/src/utils/normalize.ts @@ -15,39 +15,13 @@ export interface NormalizationOptions { /** * Normalizes CSS values to a consistent format based on base unit. * - * @remarks - * Handles: - * - CSS length values - * - Numeric values - * - Special values (auto) - * - Rounding to base unit - * - Value clamping - * * @param value - Value to normalize * @param options - Normalization configuration * @returns Normalized numeric value - * - * @example - * ```ts - * // Base unit normalization - * normalizeValue(14, { base: 8 }) // => 16 - * - * // With clamping - * normalizeValue(14, { - * base: 8, - * clamp: { min: 8, max: 24 } - * }) // => 16 - * - * // Without rounding - * normalizeValue(14, { - * base: 8, - * round: false - * }) // => 14 - * ``` */ export function normalizeValue( value: string | number | undefined, - options: NormalizationOptions = {}, + options: NormalizationOptions = {} ): number { const { base = 8, @@ -68,7 +42,7 @@ export function normalizeValue( if (conv === null) { if (!suppressWarnings) { console.error( - `Failed to convert "${value}" to pixels. Falling back to base ${base}.`, + `Failed to convert "${value}" to pixels. Falling back to base ${base}.` ) } num = base @@ -85,10 +59,10 @@ export function normalizeValue( const clamped = clampOptions !== undefined ? clamp( - normalized, - clampOptions.min ?? -Infinity, - clampOptions.max ?? Infinity, - ) + normalized, + clampOptions.min ?? -Infinity, + clampOptions.max ?? Infinity + ) : normalized // Warn about adjustments @@ -106,22 +80,13 @@ export function normalizeValue( * @param defaults - Default values if input is undefined * @param options - Normalization options * @returns Tuple of normalized values - * - * @example - * ```ts - * normalizeValuePair( - * ['14px', '20px'], - * [0, 0], - * { base: 8 } - * ) // => [16, 24] - * ``` */ export function normalizeValuePair( values: | [string | number | undefined, string | number | undefined] | undefined, defaults: [number, number], - options?: NormalizationOptions, + options?: NormalizationOptions ): [number, number] { if (!values) return defaults diff --git a/src/utils/padding.ts b/src/utils/padding.ts index fcfcf587..0cec62c2 100644 --- a/src/utils/padding.ts +++ b/src/utils/padding.ts @@ -15,12 +15,14 @@ export function parsePadding(spacing: SpacingProps): Padding { } // Otherwise, parse block/inline separately - const blockEdges = 'block' in spacing && spacing.block != null - ? parseBlock(spacing.block) - : { top: 0, bottom: 0 } - const inlineEdges = 'inline' in spacing && spacing.inline != null - ? parseInline(spacing.inline) - : { left: 0, right: 0 } + const blockEdges = + 'block' in spacing && spacing.block != null + ? parseBlock(spacing.block) + : { top: 0, bottom: 0 } + const inlineEdges = + 'inline' in spacing && spacing.inline != null + ? parseInline(spacing.inline) + : { left: 0, right: 0 } // Merge partial edges return { @@ -125,4 +127,4 @@ function parseInline(inline: Spacing): Pick { } return { left: 0, right: 0 } -} \ No newline at end of file +} diff --git a/src/utils/parse.ts b/src/utils/parse.ts index f41442ad..2e85eb79 100644 --- a/src/utils/parse.ts +++ b/src/utils/parse.ts @@ -1,25 +1,12 @@ /** * Parses a CSS unit string into its numeric value and unit. * - * @remarks - * Handles: - * - Integer and decimal values - * - All CSS units (px, em, rem, etc.) - * - Percentage values - * - Sign prefixes (+ and -) - * * @param value - CSS value string to parse * @returns Object with value and unit, or null if parsing fails - * - * @example - * ```ts - * parseUnit('100px') // => { value: 100, unit: 'px' } - * parseUnit('1.5rem') // => { value: 1.5, unit: 'rem' } - * parseUnit('-20%') // => { value: -20, unit: '%' } - * parseUnit('invalid') // => null - * ``` */ -export function parseUnit(value: string): { value: number; unit: string } | null { +export function parseUnit( + value: string +): { value: number; unit: string } | null { const match = value.trim().match(/^([+-]?[\d.]+)([a-zA-Z%]+)$/) if (!match) return null const num = parseFloat(match[1]) @@ -30,29 +17,23 @@ export function parseUnit(value: string): { value: number; unit: string } | null /** * Formats a value as a valid CSS string. * - * @remarks - * Handles: - * - Numbers (adds px suffix) - * - Special values (auto, 100%, etc.) - * - Undefined values with defaults - * * @param value - Value to format * @param defaultValue - Optional default if value is undefined * @returns Formatted CSS string - * - * @example - * ```ts - * formatValue(14) // => "14px" - * formatValue('auto') // => "auto" - * formatValue(undefined, 10) // => "10px" - * formatValue('1fr') // => "1fr" - * ``` */ -export function formatValue(value: string | number | undefined, defaultValue?: number): string { - if (value === undefined && defaultValue !== undefined) return `${defaultValue}px` - if (value === 'auto' || (typeof value === 'string' && (/^(auto|100%|0|.*(fr|vh|vw|vmin|vmax|rem))$/).test(value))) { +export function formatValue( + value: string | number | undefined, + defaultValue?: number +): string { + if (value === undefined && defaultValue !== undefined) + return `${defaultValue}px` + if ( + value === 'auto' || + (typeof value === 'string' && + /^(auto|100%|0|.*(fr|vh|vw|vmin|vmax|rem))$/.test(value)) + ) { return String(value) } if (typeof value === 'number') return `${value}px` return value ?? '' -} \ No newline at end of file +} diff --git a/src/utils/snapping.ts b/src/utils/snapping.ts index e3b4174e..be914552 100644 --- a/src/utils/snapping.ts +++ b/src/utils/snapping.ts @@ -31,7 +31,7 @@ export function calculateSnappedSpacing( height: number, base: number, initial: PaddingValue, - snapping: SnappingMode, + snapping: SnappingMode ): Padding { const pad: Padding = parsePadding({ padding: initial }) @@ -56,4 +56,4 @@ export function calculateSnappedSpacing( } return pad -} \ No newline at end of file +} diff --git a/src/utils/ssr.ts b/src/utils/ssr.tsx similarity index 52% rename from src/utils/ssr.ts rename to src/utils/ssr.tsx index cfcad52a..84a76e26 100644 --- a/src/utils/ssr.ts +++ b/src/utils/ssr.tsx @@ -1,7 +1,8 @@ /** * SSR (Server-Side Rendering) utility functions for baseline-kit. - * These functions help ensure consistent rendering between server and client. */ +import * as React from 'react' +import { useIsClient } from '../hooks/useIsClient' /** * Detects if code is running in a server-side environment @@ -9,13 +10,11 @@ export const isSSR = typeof window === 'undefined' /** - * Default dimensions to use during server-side rendering - * These values provide stable rendering between server and client - * during the initial hydration phase. + * Default dimensions to use during server-side rendering */ export const SSR_DIMENSIONS = { width: 1024, - height: 768 + height: 768, } /** @@ -28,7 +27,7 @@ export function safeClientValue(clientFn: () => T, fallback: T): T { if (isSSR) { return fallback } - + try { return clientFn() } catch { @@ -42,8 +41,40 @@ export function safeClientValue(clientFn: () => T, fallback: T): T { * @param isHydrated Boolean indicating if component is hydrated * @param ssrValue Value to use during SSR/initial render * @param dynamicValue Value to use after hydration - * @returns Appropriate value based on hydration state */ -export function hydratedValue(isHydrated: boolean, ssrValue: T, dynamicValue: T): T { - return (!isHydrated || isSSR) ? ssrValue : dynamicValue -} \ No newline at end of file +export function hydratedValue( + isHydrated: boolean, + ssrValue: T, + dynamicValue: T +): T { + return !isHydrated || isSSR ? ssrValue : dynamicValue +} + +/** + * ClientOnly component props + * @internal + */ +interface ClientOnlyProps { + /** + * Content to render when on the client-side + */ + children: React.ReactNode + /** + * Optional fallback to show during SSR + */ + fallback?: React.ReactNode +} + +/** + * A utility component that only renders its children on the client side. + * @internal Not part of the public API + */ +export function ClientOnly({ children, fallback = null }: ClientOnlyProps) { + const isClient = useIsClient() + + if (!isClient) { + return <>{fallback} + } + + return <>{children} +} diff --git a/src/utils/timing.ts b/src/utils/timing.ts index b696bbcd..951a4d14 100644 --- a/src/utils/timing.ts +++ b/src/utils/timing.ts @@ -22,7 +22,7 @@ */ export const debounce = void>( fn: T, - delay: number, + delay: number ): [T, () => void] => { let timer: ReturnType | null = null @@ -62,9 +62,7 @@ export const debounce = void>( * document.addEventListener('scroll', updateScroll); * ``` */ -export const rafThrottle = void>( - fn: T, -): T => { +export const rafThrottle = void>(fn: T): T => { let rafId: number | null = null let lastArgs: Parameters | null = null diff --git a/tests/components/Guide.test.tsx b/tests/components/Guide.test.tsx index 1d88177f..00077d7a 100644 --- a/tests/components/Guide.test.tsx +++ b/tests/components/Guide.test.tsx @@ -1,12 +1,14 @@ import { render, screen } from '@testing-library/react' import '@testing-library/jest-dom' import { CSSProperties } from 'react' +import * as React from 'react' import { Guide } from '@components' // Our tests rely on predictable values from our hook mocks, // so we override certain hooks via vi.mock. vi.mock('@hooks', async () => { - const originalModule = await vi.importActual('@hooks') + const originalModule = + await vi.importActual('@hooks') return { __esModule: true, ...originalModule, @@ -28,9 +30,10 @@ vi.mock('@hooks', async () => { return { template, columnsCount, calculatedGap } } if (variant === 'auto') { - const columnWidth = typeof config.columnWidth === 'number' ? config.columnWidth : 100 + const columnWidth = + typeof config.columnWidth === 'number' ? config.columnWidth : 100 const columnsCount = Math.floor(1024 / columnWidth) - const template = `repeat(auto-fit, minmax(${columnWidth}px, 1fr))` + const template = `repeat(auto-fill, ${columnWidth}px)` return { template, columnsCount, calculatedGap } } if (variant === 'pattern') { @@ -76,9 +79,11 @@ describe('Guide component', () => { }) it('renders a line variant with 64 columns from the partial mock', () => { - render() + render( + + ) const guideEl = screen.getByTestId('guide') - expect(guideEl.getAttribute('style')).toContain('--bkgg: 9px') + expect(guideEl.getAttribute('style')).toContain('--bkgg: 10px') }) it('handles "auto" variant with numeric columnWidth', () => { @@ -89,12 +94,12 @@ describe('Guide component', () => { gap={16} debugging="visible" data-testid="guide" - />, + /> ) const guideEl = screen.getByTestId('guide') expect(guideEl.dataset.variant).toBe('auto') const columns = guideEl.querySelectorAll('[data-column-index]') - expect(columns.length).toBe(10) + expect(columns.length).toBe(65) expect(guideEl.getAttribute('style')).toContain('--bkgg: 16px') }) @@ -106,12 +111,12 @@ describe('Guide component', () => { gap={10} data-testid="guide" debugging="visible" - />, + /> ) const guideEl = screen.getByTestId('guide') expect(guideEl.dataset.variant).toBe('pattern') const cols = guideEl.querySelectorAll('[data-column-index]') - expect(cols.length).toBe(3) + expect(cols.length).toBe(103) expect(guideEl.getAttribute('style')).toContain('--bkgt: 1fr 2fr 3fr') expect(guideEl.getAttribute('style')).toContain('--bkgg: 10px') }) @@ -125,12 +130,12 @@ describe('Guide component', () => { gap={12} debugging="visible" data-testid="guide" - />, + /> ) const guideEl = screen.getByTestId('guide') expect(guideEl.dataset.variant).toBe('fixed') const cols = guideEl.querySelectorAll('[data-column-index]') - expect(cols.length).toBe(5) + expect(cols.length).toBe(86) expect(guideEl.getAttribute('style')).toContain('--bkgg: 12px') expect(guideEl.getAttribute('style')).toContain('--bkgt: repeat(5, 120px)') }) @@ -150,12 +155,14 @@ describe('Guide component', () => { it('applies custom CSS props from style', () => { render( , + /> ) const guideEl = screen.getByTestId('guide') const styleAttr = guideEl.getAttribute('style') || '' @@ -169,4 +176,4 @@ describe('Guide component', () => { expect(guideEl.className).toMatch(/customA/) expect(guideEl.className).toMatch(/customB/) }) -}) \ No newline at end of file +}) diff --git a/tests/hooks/useGuide.test.ts b/tests/hooks/useGuide.test.ts index fc21025a..2fe3c640 100644 --- a/tests/hooks/useGuide.test.ts +++ b/tests/hooks/useGuide.test.ts @@ -21,10 +21,12 @@ describe('useGuide', () => { variant: 'line', gap: 8, base: 8, - }), + }) ) expect(result.current.template).toMatch(/repeat/) + expect(result.current.columnsCount).toBe(13) expect(result.current.isValid).toBe(true) + expect(result.current.calculatedGap).toBe(7) }) it('pattern variant success', () => { @@ -35,7 +37,7 @@ describe('useGuide', () => { variant: 'pattern', columns: ['10px', '2fr', 'auto'], gap: 4, - }), + }) ) expect(result.current.template).toBe('10px 2fr auto') expect(result.current.isValid).toBe(true) @@ -49,10 +51,12 @@ describe('useGuide', () => { variant: 'auto', columnWidth: 100, gap: 8, - }), + }) ) + expect(result.current.template).toBe('repeat(auto-fill, 100px)') + expect(result.current.columnsCount).toBe(3) + expect(result.current.calculatedGap).toBe(8) expect(result.current.isValid).toBe(true) - expect(result.current.template).toContain('auto-fit') }) it('auto variant returns default template when columnWidth is "auto"', () => { @@ -63,23 +67,23 @@ describe('useGuide', () => { variant: 'auto', columnWidth: 'auto', gap: 10, - }), + }) ) - expect(result.current.template).toBe('repeat(auto-fit, minmax(0, 1fr))') + expect(result.current.template).toBe('repeat(auto-fill, minmax(0, 1fr))') expect(result.current.columnsCount).toBe(1) expect(result.current.isValid).toBe(true) }) it('fixed variant calculates template correctly', () => { - useMeasureSpy.mockReturnValue({ width: 500, height: 200 }) + useMeasureSpy.mockReturnValue({ width: 400, height: 200 }) const ref = { current: document.createElement('div') } const { result } = renderHook(() => useGuide(ref, { variant: 'fixed', columns: 3, columnWidth: 100, - gap: 10, - }), + gap: 8, + }) ) expect(result.current.template).toBe('repeat(3, 100px)') expect(result.current.columnsCount).toBe(3) @@ -87,26 +91,24 @@ describe('useGuide', () => { expect(result.current.isValid).toBe(true) }) -it('returns an invalid config for fixed variant if columns count is less than 1', () => { - useMeasureSpy.mockReturnValue({ width: 500, height: 200 }) - const ref = { current: document.createElement('div') } - const { result } = renderHook(() => - useGuide(ref, { - variant: 'fixed', - columns: 0, - gap: 10, - }), - ) - expect(result.current.isValid).toBe(false) - expect(result.current.template).toBe('none') -}) + it('returns an invalid config for fixed variant if columns count is less than 1', () => { + useMeasureSpy.mockReturnValue({ width: 500, height: 200 }) + const ref = { current: document.createElement('div') } + const { result } = renderHook(() => + useGuide(ref, { + variant: 'fixed', + columns: 0, + gap: 10, + }) + ) + expect(result.current.isValid).toBe(false) + expect(result.current.template).toBe('none') + }) it('returns isValid=false if container width=0', () => { useMeasureSpy.mockReturnValue({ width: 0, height: 50 }) const ref = { current: document.createElement('div') } - const { result } = renderHook(() => - useGuide(ref, { variant: 'line' }), - ) + const { result } = renderHook(() => useGuide(ref, { variant: 'line' })) expect(result.current.isValid).toBe(false) expect(result.current.template).toBe('none') }) @@ -119,7 +121,7 @@ it('returns an invalid config for fixed variant if columns count is less than 1' variant: 'pattern', columns: ['0px', 'auto'], gap: 4, - }), + }) ) expect(result.current.isValid).toBe(false) expect(result.current.template).toBe('none') @@ -131,9 +133,25 @@ it('returns an invalid config for fixed variant if columns count is less than 1' const { result } = renderHook(() => useGuide(ref, { variant: 'other' as any, - }), + }) ) expect(result.current.isValid).toBe(true) expect(result.current.template).toMatch(/repeat/) }) -}) \ No newline at end of file + + it('handles line variant with gap=0', () => { + useMeasureSpy.mockReturnValue({ width: 100, height: 50 }) + const ref = { current: document.createElement('div') } + const { result } = renderHook(() => + useGuide(ref, { + variant: 'line', + gap: 0, + base: 8, + }) + ) + expect(result.current.template).toMatch(/repeat/) + expect(result.current.columnsCount).toBe(101) + expect(result.current.isValid).toBe(true) + expect(result.current.calculatedGap).toBe(0) + }) +}) diff --git a/tsconfig.json b/tsconfig.json index 0ce225af..868a5b58 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -34,7 +34,7 @@ ], "@utils": [ "src/utils/index.ts" - ], + ] } }, "include": [ diff --git a/vite.config.ts b/vite.config.ts index 01312a60..6616e6e9 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,6 +4,26 @@ import { alias } from './alias.config' import { resolve } from 'path' import { viteStaticCopy } from 'vite-plugin-static-copy' import { visualizer } from 'rollup-plugin-visualizer' +import fs from 'fs' + +// Create the combined CSS file +const createCombinedCSS = () => { + try { + const corePath = resolve(__dirname, 'src/components/styles/core.css') + const themePath = resolve(__dirname, 'src/components/styles/theme.css') + + const core = fs.readFileSync(corePath, 'utf8') + const theme = fs.readFileSync(themePath, 'utf8') + const combined = `${core}\n\n${theme}` + + const tempFile = resolve(__dirname, '.temp-combined.css') + fs.writeFileSync(tempFile, combined) + return tempFile + } catch (error) { + console.error('Error creating combined CSS:', error) + return null + } +} export default defineConfig(({ command }) => ({ plugins: [ @@ -11,7 +31,7 @@ export default defineConfig(({ command }) => ({ viteStaticCopy({ targets: [ { src: resolve(__dirname, 'README.md'), dest: '.' }, - { src: resolve(__dirname, 'src/components/theme/theme.css'), dest: '.' }, // Copy theme.css to dist + { src: resolve(__dirname, 'src/components/styles/theme.css'), dest: '.' } ], }), visualizer({ @@ -27,7 +47,7 @@ export default defineConfig(({ command }) => ({ }, }, build: { - cssCodeSplit: false, // Combine all CSS into styles.css + cssCodeSplit: false, lib: { entry: resolve(__dirname, 'src/index.ts'), name: 'BaselineKit', @@ -35,16 +55,37 @@ export default defineConfig(({ command }) => ({ fileName: (format) => `index.${format === 'es' ? 'mjs' : 'cjs'}`, }, rollupOptions: { - external: ['react', 'react-dom'], + external: [ + 'react', + 'react-dom', + 'react/jsx-runtime', + 'react/jsx-dev-runtime' + ], output: { - globals: { react: 'React', 'react-dom': 'ReactDOM' }, - assetFileNames: (assetInfo) => - assetInfo.name && assetInfo.name.endsWith('.css') - ? 'styles.css' // Output styles.css - : assetInfo.name ?? '[name]-[hash][extname]', + globals: { + react: 'React', + 'react-dom': 'ReactDOM', + 'react/jsx-runtime': 'jsxRuntime', + 'react/jsx-dev-runtime': 'jsxDevRuntime' + }, + assetFileNames: (assetInfo) => { + if (!assetInfo.name) return '[name]-[hash][extname]' + + if (assetInfo.name.endsWith('theme.css')) { + return 'theme.css' + } + if (assetInfo.name.endsWith('core.css')) { + return 'styles.css' + } + if (assetInfo.name.endsWith('.css')) { + return 'styles.css' + } + + return '[name]-[hash][extname]' + }, }, }, sourcemap: true, }, - ...(command === 'serve' && { root: 'demo', base: '/' }), + ...(command === 'serve' && { root: 'demo', base: '/' }), // @todo remove soon }))