From 357d24b904fe9c4a1118af82f8bf759d5581019f Mon Sep 17 00:00:00 2001 From: dnvt Date: Sat, 8 Mar 2025 12:20:25 -0500 Subject: [PATCH 1/5] Refactor and expand theming, styling, and build processes This commit introduces improved theming with dedicated theme files and variables for light/dark modes, alongside CSS splitting capabilities. It also restructures configuration and debugging for enhanced clarity, updates eslint configurations, and integrates a CSS combination script for optimized builds. --- .eslintignore | 3 - .eslintrc.cjs | 40 --- README.md | 150 ++++++++- bun.lock | 386 +++++++++------------- eslint.config.js | 53 +++ package.json | 69 ++-- scripts/combine-css.js | 96 ++++++ src/components/Baseline/Baseline.tsx | 61 ++-- src/components/Baseline/index.ts | 2 +- src/components/Baseline/styles.module.css | 2 +- src/components/Box/Box.tsx | 73 ++-- src/components/Box/styles.module.css | 2 +- src/components/Config/Config.tsx | 143 ++++---- src/components/Config/defaults.ts | 2 +- src/components/Config/index.ts | 2 +- src/components/Guide/Guide.tsx | 182 ++++++---- src/components/Guide/index.ts | 2 +- src/components/Guide/styles.module.css | 12 +- src/components/Guide/types.ts | 38 +-- src/components/Guide/validation.ts | 25 +- src/components/Layout/Layout.tsx | 80 +++-- src/components/Layout/index.ts | 2 +- src/components/Layout/styles.module.css | 33 +- src/components/Padder/Padder.tsx | 71 ++-- src/components/Padder/index.ts | 2 +- src/components/Spacer/Spacer.tsx | 54 ++- src/components/Spacer/index.ts | 2 +- src/components/Spacer/styles.module.css | 17 +- src/components/Stack/Stack.tsx | 54 +-- src/components/Stack/styles.module.css | 16 +- src/components/index.ts | 6 +- src/components/styles/base.css | 158 +++++++++ src/components/styles/core.css | 26 ++ src/components/styles/index.css | 102 ------ src/components/styles/index.ts | 8 + src/components/styles/theme.css | 142 ++++++++ src/components/styles/theme/dark.css | 67 ++++ src/components/styles/theme/default.css | 82 +++++ src/components/styles/theme/tokens.css | 82 +++++ src/components/theme/theme.css | 140 -------- src/components/types.ts | 70 ++-- src/hooks/index.ts | 2 +- src/hooks/useBaseline.ts | 17 +- src/hooks/useConfig.ts | 8 +- src/hooks/useDebug.ts | 12 +- src/hooks/useGuide.ts | 205 +++++++----- src/hooks/useMeasure.ts | 18 +- src/hooks/useVirtual.ts | 41 ++- src/index.ts | 2 +- src/styles.ts | 8 + src/theme.ts | 8 + src/utils/convert.ts | 66 ++-- src/utils/grid.ts | 10 +- src/utils/index.ts | 2 +- src/utils/math.ts | 22 +- src/utils/merge.ts | 43 ++- src/utils/normalize.ts | 14 +- src/utils/padding.ts | 16 +- src/utils/parse.ts | 20 +- src/utils/snapping.ts | 4 +- src/utils/ssr.ts | 16 +- src/utils/timing.ts | 6 +- tests/components/Guide.test.tsx | 37 ++- tests/hooks/useGuide.test.ts | 72 ++-- vite.config.ts | 59 +++- 65 files changed, 2014 insertions(+), 1251 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.cjs create mode 100644 eslint.config.js create mode 100755 scripts/combine-css.js create mode 100644 src/components/styles/base.css create mode 100644 src/components/styles/core.css delete mode 100644 src/components/styles/index.css create mode 100644 src/components/styles/index.ts create mode 100644 src/components/styles/theme.css create mode 100644 src/components/styles/theme/dark.css create mode 100644 src/components/styles/theme/default.css create mode 100644 src/components/styles/theme/tokens.css delete mode 100644 src/components/theme/theme.css create mode 100644 src/styles.ts create mode 100644 src/theme.ts 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/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..2fa0a5cc 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", }, }, }, @@ -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,79 @@ "@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/core": ["@eslint/core@0.12.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg=="], - "@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/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.21.0", "", {}, "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw=="], + + "@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 +281,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-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.34.9", "", { "os": "android", "cpu": "arm" }, "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.34.8", "", { "os": "android", "cpu": "arm64" }, "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.34.9", "", { "os": "android", "cpu": "arm64" }, "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.34.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.34.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.34.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.34.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.34.8", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.34.9", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.34.8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.34.9", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.34.8", "", { "os": "linux", "cpu": "arm" }, "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.34.9", "", { "os": "linux", "cpu": "arm" }, "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg=="], - "@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-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.34.9", "", { "os": "linux", "cpu": "arm" }, "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.34.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.34.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw=="], - "@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-musl": ["@rollup/rollup-linux-arm64-musl@4.34.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A=="], - "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.34.8", "", { "os": "linux", "cpu": "none" }, "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ=="], + "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.34.9", "", { "os": "linux", "cpu": "none" }, "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg=="], - "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.34.8", "", { "os": "linux", "cpu": "ppc64" }, "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw=="], + "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.34.9", "", { "os": "linux", "cpu": "ppc64" }, "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.34.8", "", { "os": "linux", "cpu": "none" }, "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.34.9", "", { "os": "linux", "cpu": "none" }, "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.34.8", "", { "os": "linux", "cpu": "s390x" }, "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.34.9", "", { "os": "linux", "cpu": "s390x" }, "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.34.8", "", { "os": "linux", "cpu": "x64" }, "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.34.9", "", { "os": "linux", "cpu": "x64" }, "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A=="], - "@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-musl": ["@rollup/rollup-linux-x64-musl@4.34.9", "", { "os": "linux", "cpu": "x64" }, "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.34.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.34.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q=="], - "@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-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.34.9", "", { "os": "win32", "cpu": "ia32" }, "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.34.8", "", { "os": "win32", "cpu": "x64" }, "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.34.9", "", { "os": "win32", "cpu": "x64" }, "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw=="], - "@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=="], + "@swc/core": ["@swc/core@1.11.7", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.19" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.7", "@swc/core-darwin-x64": "1.11.7", "@swc/core-linux-arm-gnueabihf": "1.11.7", "@swc/core-linux-arm64-gnu": "1.11.7", "@swc/core-linux-arm64-musl": "1.11.7", "@swc/core-linux-x64-gnu": "1.11.7", "@swc/core-linux-x64-musl": "1.11.7", "@swc/core-win32-arm64-msvc": "1.11.7", "@swc/core-win32-ia32-msvc": "1.11.7", "@swc/core-win32-x64-msvc": "1.11.7" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-ICuzjyfz8Hh3U16Mb21uCRJeJd/lUgV999GjgvPhJSISM1L8GDSB5/AMNcwuGs7gFywTKI4vAeeXWyCETUXHAg=="], - "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bJbqZ51JghEZ8WaFetofkfkS3MWsS/V3vDvY+0r+SlLeocZwf8q8/GqcafnElHcU+zLV6yTi13fJwUce6ULiUQ=="], + "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3+LhCP2H50CLI6yv/lhOtoZ5B/hi7Q/23dye1KhbSDeDprLTm/KfLJh/iQqwaHUponf5m8C2U0y6DD+HGLz8Yw=="], - "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-9GGEoN0uxkLg3KocOVzMfe9c9/DxESXclsL/U2xVLa3pTFB5YnXhiCP5YBT/3Q7nSGLD+R2ALqkNlDoueUjvPw=="], + "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-1diWpJqwX1XmOghf9ENFaeRaTtqLiqlZIW56RfOqmeZ7tPp3qS7VygWb9akptBsO5pEA5ZwNgSerD6AJlQcjAw=="], - "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Lt7l/l0nfSTUzsWcVY3dtOPl5RtgCJ+Ya8IG4Aa3l6c7kLc6Sx4JpylpEIY9yhGidDy/uQ8KUg5kqUPtUrXrvQ=="], + "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.7", "", { "os": "linux", "cpu": "arm" }, "sha512-MV8+hLREf0NN23NuSKemsjFaWjl/HnqdOkE7uhXTnHzg8WTwp6ddVtU5Yriv15+d/ktfLWPVAOhLHQ4gzaoa8A=="], - "@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-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-5GNs8ZjHQy/UTSnzzn+gm1RCUpCYo43lsxYOl8mpcnZSfxkNFVpjfylBv0QuJ5qhdfZ2iU55+v4iJCwCMtw0nA=="], - "@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-musl": ["@swc/core-linux-arm64-musl@1.11.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-cTydaYBwDbVV5CspwVcCp9IevYWpGD1cF5B5KlBdjmBzxxeWyTAJRtKzn8w5/UJe/MfdAptarpqMPIs2f33YEQ=="], - "@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-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.7", "", { "os": "linux", "cpu": "x64" }, "sha512-YAX2KfYPlbDsnZiVMI4ZwotF3VeURUrzD+emJgFf1g26F4eEmslldgnDrKybW7V+bObsH22cDqoy6jmQZgpuPQ=="], - "@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-musl": ["@swc/core-linux-x64-musl@1.11.7", "", { "os": "linux", "cpu": "x64" }, "sha512-mYT6FTDZyYx5pailc8xt6ClS2yjKmP8jNHxA9Ce3K21n5qkKilI5M2N7NShwXkd3Ksw3F29wKrg+wvEMXTRY/A=="], - "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-H8Q78GwaKnCL4isHx8JRTRi6vUU6iMLbpegS2jzWWC1On7EePhkLx2eR8nEsaRIQB6rc3WqdIj74OgOpNoPi7g=="], + "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-uLDQEcv0BHcepypstyxKkNsW6KfLyI5jVxTbcxka+B2UnMcFpvoR87nGt2JYW0grO2SNZPoFz+UnoKL9c6JxpA=="], - "@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-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.7", "", { "os": "win32", "cpu": "ia32" }, "sha512-wiq5G3fRizdxAJVFcon7zpyfbfrb+YShuTy+TqJ4Nf5PC0ueMOXmsmeuyQGApn6dVWtGCyymYQYt77wHeQajdA=="], - "@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-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.7", "", { "os": "win32", "cpu": "x64" }, "sha512-/zQdqY4fHkSORxEJ2cKtRBOwglvf/8gs6Tl4Q6VMx2zFtFpIOwFQstfY5u8wBNN2Z+PkAzyUCPoi8/cQFK8HLQ=="], "@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 +359,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.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], "@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/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/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/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/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/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/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/types": ["@typescript-eslint/types@8.25.0", "", {}, "sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw=="], + "@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/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/types": ["@typescript-eslint/types@8.26.0", "", {}, "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA=="], - "@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/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/visitor-keys": ["@typescript-eslint/visitor-keys@8.25.0", "", { "dependencies": { "@typescript-eslint/types": "8.25.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ=="], + "@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=="], - "@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=="], @@ -453,13 +467,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.30001702", "", {}, "sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA=="], "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=="], @@ -551,7 +565,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 +581,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 +607,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.21.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.0", "@eslint/js": "9.21.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.2.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-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg=="], - "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-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-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.2.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A=="], - "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 +641,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 +649,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 +679,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 +699,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 +745,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 +783,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 +829,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 +895,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 +907,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 +923,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 +939,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 +953,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 +1087,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 +1097,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 +1127,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.34.9", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.34.9", "@rollup/rollup-android-arm64": "4.34.9", "@rollup/rollup-darwin-arm64": "4.34.9", "@rollup/rollup-darwin-x64": "4.34.9", "@rollup/rollup-freebsd-arm64": "4.34.9", "@rollup/rollup-freebsd-x64": "4.34.9", "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", "@rollup/rollup-linux-arm-musleabihf": "4.34.9", "@rollup/rollup-linux-arm64-gnu": "4.34.9", "@rollup/rollup-linux-arm64-musl": "4.34.9", "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", "@rollup/rollup-linux-riscv64-gnu": "4.34.9", "@rollup/rollup-linux-s390x-gnu": "4.34.9", "@rollup/rollup-linux-x64-gnu": "4.34.9", "@rollup/rollup-linux-x64-musl": "4.34.9", "@rollup/rollup-win32-arm64-msvc": "4.34.9", "@rollup/rollup-win32-ia32-msvc": "4.34.9", "@rollup/rollup-win32-x64-msvc": "4.34.9", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ=="], "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 +1185,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 +1221,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 +1263,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 +1271,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=="], @@ -1305,8 +1313,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 +1333,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 +1361,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 +1379,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 +1399,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 +1431,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..e0917cc1 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,29 +48,31 @@ }, "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", @@ -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..9d70275c 100644 --- a/src/components/Baseline/Baseline.tsx +++ b/src/components/Baseline/Baseline.tsx @@ -10,7 +10,7 @@ import { formatValue, createStyleOverride, SSR_DIMENSIONS, - hydratedValue + hydratedValue, } from '@utils' import { Variant } from '../types' import styles from './styles.module.css' @@ -38,7 +38,7 @@ export type BaselineProps = { export const createDefaultBaselineStyles = ( base: number, lineColor: string, - flatColor: string, + flatColor: string ): Record => ({ '--bkbw': '100%', '--bkbh': '100%', @@ -50,17 +50,17 @@ 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 } /** @@ -68,7 +68,7 @@ type RowStyleParams = { * Applies positioning and visual styling based on variant. */ export const createBaselineRowStyle = ( - params: RowStyleParams, + params: RowStyleParams ): React.CSSProperties => { const { index, base, variant, chosenColor, lineColor, flatColor } = params @@ -128,37 +128,37 @@ export const Baseline = React.memo(function Baseline({ // 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 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 [_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(() => { @@ -185,13 +185,13 @@ export const Baseline = React.memo(function Baseline({ containerRef, buffer: 160, }) - + // For SSR, use simplistic settings that match between server/client - const stableVirtualResult = { - start: 0, - end: Math.min(10, rowCount) + const stableVirtualResult = { + start: 0, + end: Math.min(10, rowCount), } - + // Choose appropriate virtualization based on environment const { start, end } = hydratedValue( isHydrated && !ssrMode, @@ -199,17 +199,14 @@ export const Baseline = React.memo(function Baseline({ 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.colors.line, config.colors.flat), + [base, config.colors.line, config.colors.flat] ) const containerStyles = React.useMemo(() => { @@ -250,7 +247,7 @@ export const Baseline = React.memo(function Baseline({ }), ...(padding && { padding }), } as React.CSSProperties, - style, + style ) }, [ widthProp, @@ -275,7 +272,7 @@ export const Baseline = React.memo(function Baseline({ flatColor: config.colors.flat, }) }, - [base, variant, chosenColor, config.colors.line, config.colors.flat], + [base, variant, chosenColor, config.colors.line, config.colors.flat] ) return ( @@ -285,7 +282,7 @@ export const Baseline = React.memo(function Baseline({ className={mergeClasses( styles.bas, isShown ? styles.v : styles.h, - className, + className )} style={containerStyles} {...spacingProps} 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..417b2c8a 100644 --- a/src/components/Baseline/styles.module.css +++ b/src/components/Baseline/styles.module.css @@ -13,5 +13,5 @@ position: absolute; top: var(--bkrt); height: var(--bkrh); - background-color: var(--bkbcl); + background-color: var(--bkbc); } diff --git a/src/components/Box/Box.tsx b/src/components/Box/Box.tsx index ca19cc10..08f731cc 100644 --- a/src/components/Box/Box.tsx +++ b/src/components/Box/Box.tsx @@ -8,7 +8,7 @@ import { formatValue, createGridSpanStyles, createStyleOverride, - hydratedValue + hydratedValue, } from '@utils' import { Config } from '../Config' import { Padder } from '../Padder' @@ -58,15 +58,15 @@ export const createDefaultBoxStyles = ( /** 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 } /** @@ -78,7 +78,7 @@ export const createBoxCustomStyles = ({ height, base, lineColor, - defaultStyles + defaultStyles, }: BoxCustomStylesParams): React.CSSProperties => { const widthValue = formatValue(width || 'fit-content') const heightValue = formatValue(height || 'fit-content') @@ -91,23 +91,23 @@ export const createBoxCustomStyles = ({ key: '--bkxw', value: widthValue, defaultStyles, - skipDimensions: { fitContent: dimensionVars } + skipDimensions: { fitContent: dimensionVars }, }), ...createStyleOverride({ key: '--bkxh', value: heightValue, defaultStyles, - skipDimensions: { fitContent: dimensionVars } + skipDimensions: { fitContent: dimensionVars }, }), ...createStyleOverride({ key: '--bkxb', value: `${base}px`, - defaultStyles + defaultStyles, }), ...createStyleOverride({ key: '--bkxcl', value: lineColor, - defaultStyles + defaultStyles, }), } as React.CSSProperties } @@ -158,21 +158,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 +180,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 +208,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..2b949e1b 100644 --- a/src/components/Config/Config.tsx +++ b/src/components/Config/Config.tsx @@ -16,55 +16,55 @@ 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 = { /** 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 @@ -75,23 +75,23 @@ ConfigContext.displayName = 'ConfigContext' 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: Config['baseline'] /** Guide component configuration */ - guide: Config['guide']; + guide: Config['guide'] /** Stack component configuration */ - stack: Config['stack']; + stack: Config['stack'] /** Spacer component configuration */ - spacer: Config['spacer']; + spacer: Config['spacer'] /** Layout component configuration */ - layout: Config['layout']; + layout: Config['layout'] /** Box component configuration */ - box: Config['box']; + box: Config['box'] /** Padder component configuration */ - padder: Config['padder']; + padder: Config['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,26 +166,26 @@ export const createCSSVariables = ( /** Parameters for merging configuration */ type MergeConfigParams = { /** Parent configuration to extend */ - parentConfig: Config; + parentConfig: Config /** 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. */ @@ -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..3e0e6d55 100644 --- a/src/components/Config/defaults.ts +++ b/src/components/Config/defaults.ts @@ -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..f0e8f25e 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 * from './defaults' diff --git a/src/components/Guide/Guide.tsx b/src/components/Guide/Guide.tsx index 371f03b8..7ca140ca 100644 --- a/src/components/Guide/Guide.tsx +++ b/src/components/Guide/Guide.tsx @@ -1,23 +1,18 @@ import * as React from 'react' -import { - useConfig, - useDebug, - useGuide, - useMeasure, -} from '@hooks' +import { useConfig, useDebug, useGuide, useMeasure } from '@hooks' import { formatValue, mergeClasses, mergeStyles, createStyleOverride, - hydratedValue + hydratedValue, } from '@utils' import { AutoConfig, FixedConfig, LineConfig, PatternConfig } from './types' import type { ComponentsProps, 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 */ @@ -40,68 +35,71 @@ 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) => { + 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, - gap, + return ( + { + line: { + variant: 'line' as const, + gap: gap - 1, base, - } - : null, - fixed: - typeof columns === 'number' + }, + auto: columnWidth ? { - variant: 'fixed' as const, - columns, - columnWidth, - gap, - base, - } + variant: 'auto' as const, + columnWidth, + gap, + base, + } : null, - }[variant] ?? { - variant: 'line' as const, - gap: gap - 1, - base, - } + pattern: Array.isArray(columns) + ? { + variant: 'pattern' as const, + columns, + gap, + base, + } + : null, + fixed: + typeof columns === 'number' + ? { + variant: 'fixed' as const, + columns, + columnWidth, + gap, + base, + } + : null, + }[variant] ?? { + variant: 'line' as const, + gap: gap - 1, + base, + } + ) } /** Creates default guide styles */ export const createDefaultGuideStyles = ( base: number, - lineColor: string, + lineColor: string ): Record => ({ '--bkgw': 'auto', '--bkgh': 'auto', @@ -111,6 +109,7 @@ export const createDefaultGuideStyles = ( '--bkgc': '12', '--bkgb': `${base}px`, '--bkgcl': lineColor, + '--bkgg': '0', }) /** @@ -176,27 +175,27 @@ 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 - + const gap = typeof gapProp === 'number' ? gapProp : 0 + // Add hydration state tracking const [isHydrated, setIsHydrated] = React.useState(false) - + React.useEffect(() => { setIsHydrated(true) }, []) 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 ) - + const { width: containerWidth, height: containerHeight } = dimensions const { isShown } = useDebug(debugging, config.debugging) @@ -212,15 +211,14 @@ export const Guide = React.memo(function Guide({ }) }, [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(() => { @@ -270,7 +268,7 @@ export const Guide = React.memo(function Guide({ }), ...createStyleOverride({ key: '--bkgb', - value: `${config.base}px`, + value: `0`, defaultStyles, }), ...createStyleOverride({ @@ -278,13 +276,17 @@ export const Guide = React.memo(function Guide({ value: color ?? config.colors.line, defaultStyles, }), - // Add the CSS variables expected by tests - '--bkgg': `${calculatedGap}px`, + // Use style override for gap to be consistent with other properties + ...createStyleOverride({ + key: '--bkgg', + value: `${calculatedGap}px`, + defaultStyles, + }), ...(template && template !== 'none' ? { '--bkgt': template } : {}), // Add grid template if available - ...(template && template !== 'none' ? { gridTemplateColumns: template } : {}), - // Add gap if calculated - ...(calculatedGap ? { gap: `${calculatedGap}px` } : {}), + ...(template && template !== 'none' + ? { gridTemplateColumns: template } + : {}), // Add justifyContent based on align justifyContent: align, } as React.CSSProperties @@ -302,13 +304,46 @@ export const Guide = React.memo(function Guide({ calculatedGap, containerWidth, containerHeight, - config.base, config.colors.line, defaultStyles, style, align, ]) + // Calculate how many columns we need + // 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 = gap === 0 ? 0 : gap - 1 + const actualGapWithLine = finalGap + 1 + + // 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..544d907c 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,16 @@ export type LayoutProps = { /** Container height (defaults to "auto") */ height?: React.CSSProperties['height'] children?: React.ReactNode -} & ComponentsProps & Gaps +} & ComponentsProps & + Gaps // Utils ----------------------------------------------------------------------- /** Creates default layout styles with theme colors */ export const createDefaultLayoutStyles = (colors: { - line: string; - flat: string; - text: string; + line: string + flat: string + text: string }): Record => ({ '--bklw': 'auto', '--bklh': 'auto', @@ -65,7 +68,9 @@ export const createDefaultLayoutStyles = (colors: { }) /** Parses grid template definitions into CSS grid-template values. */ -export const getGridTemplate = (prop?: number | string | Array): string => { +export 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)) { @@ -78,7 +83,7 @@ export const getGridTemplate = (prop?: number | string | Array) export 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 = {} @@ -154,21 +159,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 +181,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 +201,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 +233,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-fit, minmax(100px, 1fr))' && { + '--bklgtc': gridTemplateColumns, + }), ...(gridTemplateRows !== 'auto' && { '--bklgtr': gridTemplateRows }), ...(justifyItems && { '--bklji': justifyItems }), ...(alignItems && { '--bklai': alignItems }), @@ -263,7 +270,7 @@ export const Layout = React.memo(function Layout({ // Include gap styles ...gridGapStyles, } as React.CSSProperties, - style, + style ) }, [ gridTemplateColumns, @@ -281,14 +288,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..1f2234ca 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))); - 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); + width: var(--bklw, var(--bk-width-default, auto)); + height: var(--bklh, var(--bk-height-default, auto)); + grid-template-columns: var( + --bklgtc, + var(--bk-layout-gtc, repeat(auto-fit, minmax(100px, 1fr))) + ); + grid-template-rows: var(--bklgtr, var(--bk-layout-gtr, auto)); + gap: var(--bklg, 0); + column-gap: var(--bklcg, var(--bk-layout-cg, 0)); + row-gap: var(--bklrg, var(--bk-layout-rg, 0)); + justify-items: var(--bklji, var(--bk-layout-ji, stretch)); + align-items: var(--bklai, var(--bk-layout-ai, stretch)); + justify-content: var(--bkljc, var(--bk-layout-jc, start)); + align-content: var(--bklac, var(--bk-layout-ac, 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..56c9dfe7 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,13 +15,13 @@ 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 = { @@ -39,7 +39,7 @@ export const createPadderContainerStyles = ( width: React.CSSProperties['width'], height: React.CSSProperties['height'], base: number, - color: string, + color: string ): Record => { const stylesObj: Record = {} @@ -66,11 +66,11 @@ export const createPadderContainerStyles = ( export 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 = {} @@ -92,17 +92,20 @@ export const createDirectPaddingStyles = ( export 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 +204,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 +229,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 +258,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 +294,9 @@ export const Padder = React.memo( {/* Left spacer */} {padding.left >= 0 && ( -
{renderSpacer(padding.left, '100%')}
+
+ {renderSpacer(padding.left, '100%')} +
)} @@ -313,5 +320,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..2461582a 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) */ @@ -41,7 +44,7 @@ export const createDefaultSpacerStyles = ( base: number, textColor: string, flatColor: string, - lineColor: string, + lineColor: string ): Record => ({ '--bksw': '100%', '--bksh': '100%', @@ -56,7 +59,7 @@ export 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(() => { @@ -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..5359a420 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,22 @@ import { ComponentsProps, Variant } from '../types' import styles from './styles.module.css' // Maps shorthand directions to Flexbox directions -export const DIRECTION_AXIS: Record = { +export const DIRECTION_AXIS: Record< + string, + React.CSSProperties['flexDirection'] +> = { 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 */ @@ -66,7 +70,7 @@ export const createDefaultStackStyles = (colors: Record) => ({ export const createStackGapStyles = ( rowGap?: number, columnGap?: number, - gap?: number, + gap?: number ): Record => ({ rowGap: gap !== undefined ? gap : rowGap, columnGap: gap !== undefined ? gap : columnGap, @@ -144,14 +148,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 +170,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 +190,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 +270,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..22e18677 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -4,7 +4,9 @@ * @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' @@ -23,4 +25,4 @@ export * from './Padder' 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..00cd6bed --- /dev/null +++ b/src/components/styles/base.css @@ -0,0 +1,158 @@ +/* Core system 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, 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 */ + --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 */ + --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 */ + --bkgw: 100vw; + --bkgh: 100vh; + --bkgg: var(--bkb); + --bkgj: start; + --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 */ + --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-fit, minmax(100px, 1fr)); + --bklgtr: auto; + --bklg: 0; + --bklcg: 0; + --bklrg: 0; + --bklji: stretch; + --bklai: stretch; + --bkljc: start; + --bklac: start; + + /* Layout Component alternative variables */ + --bk-layout-gtc: repeat(auto-fit, minmax(100px, 1fr)); + --bk-layout-gtr: auto; + --bk-layout-cg: 0; + --bk-layout-rg: 0; + --bk-layout-ji: stretch; + --bk-layout-ai: stretch; + --bk-layout-jc: start; + --bk-layout-ac: start; + + /* Padder Component */ + --bkpw: var(--bk-width-default); + --bkph: var(--bk-height-default); + --bkpc: var(--bk-padder-color-theme, hsla(270, 60%, 40%, 0.6)); + + /* Spacer Component - 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)); +} + +/* Component styles with enhanced fallbacks to ensure visibility in all environments */ + +/* Spacer Component - Robust fallback styles */ +.spr_zbcF6 { + /* Variable definitions with fallbacks */ + --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)); + --bkzi: 1; + --bkzio: 2; + + /* Essential layout properties */ + position: relative; + box-sizing: border-box; + margin: 0; + padding: 0; + width: var(--bksw, 100%); + height: var(--bksh, auto); + background-color: var(--bkscf); + border: 1px dashed var(--bkscl); +} + +/* Spacer text indicator */ +.spr_zbcF6[data-height]::before { + content: attr(data-height); + color: var(--bksct); + font-family: monospace; + font-size: 12px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: var(--bkzio); +} + +/* Guide Component - Robust fallbacks */ +.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 - Robust fallbacks */ +.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 - Robust fallbacks */ +.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 - Robust fallbacks */ +.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 - Robust fallbacks */ +.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..5f4214f0 --- /dev/null +++ b/src/components/styles/core.css @@ -0,0 +1,26 @@ +/* Core styles - Variables and fundamentals */ +@import './reset.css'; +@import './base.css'; + +/* Component imports */ +@import '../Box/styles.module.css'; +@import '../Guide/styles.module.css'; +@import '../Padder/styles.module.css'; +@import '../Spacer/styles.module.css'; + +/* 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.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..b817ca40 --- /dev/null +++ b/src/components/styles/index.ts @@ -0,0 +1,8 @@ +// This file ensures all styling files are properly exported +import './core.css' +import './theme.css' + +// Utility exports +export * from '../types' + +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..a564dc39 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -14,4 +14,4 @@ export * from './useGuide' // Configuration export * from './useConfig' -export * from './useDebug' \ No newline at end of file +export * from './useDebug' 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..ae02e2eb 100644 --- a/src/hooks/useConfig.ts +++ b/src/hooks/useConfig.ts @@ -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..37f1ab49 100644 --- a/src/hooks/useGuide.ts +++ b/src/hooks/useGuide.ts @@ -1,17 +1,21 @@ import * as React from 'react' -import { GuideConfig, GuideColumnsPattern, isValidGuidePattern } from '@components' +import { + GuideConfig, + GuideColumnsPattern, + isValidGuidePattern, +} from '@components' 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 +68,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 +77,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 +94,127 @@ 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 (!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 + } + ) - 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, - } - } + // 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-fitting columns + const colWidth = config.columnWidth ?? 'auto' + if (colWidth === 'auto') { + return { + template: 'repeat(auto-fit, 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-fit, minmax(${colWidthStr}, 1fr))`, + 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/useMeasure.ts b/src/hooks/useMeasure.ts index d1dbcce4..6077cdd0 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,7 +61,9 @@ 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(() => { + measure() + }, [measure]) // Set up a ResizeObserver on mount. React.useLayoutEffect(() => { 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..0f5fd5a9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,4 +8,4 @@ export * from './components' export * from './hooks' -export * from './utils' \ No newline at end of file +export * from './utils' 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..82f303c7 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,15 +24,23 @@ 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. @@ -60,7 +68,7 @@ export const RELATIVE_UNITS: string[] = ['em', 'rem', 'vh', 'vw', 'vmin', 'vmax' */ 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 +90,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..e9c9a528 100644 --- a/src/utils/math.ts +++ b/src/utils/math.ts @@ -24,7 +24,7 @@ import { convertValue } from './convert' 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 +32,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` @@ -77,7 +77,9 @@ export function clamp(value: number, min: number, max: number): number { */ 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,22 +89,22 @@ 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 @@ -113,4 +115,4 @@ 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..bc27775e 100644 --- a/src/utils/normalize.ts +++ b/src/utils/normalize.ts @@ -47,7 +47,7 @@ export interface NormalizationOptions { */ export function normalizeValue( value: string | number | undefined, - options: NormalizationOptions = {}, + options: NormalizationOptions = {} ): number { const { base = 8, @@ -68,7 +68,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 +85,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 @@ -121,7 +121,7 @@ export function normalizeValuePair( | [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..c3de0919 100644 --- a/src/utils/parse.ts +++ b/src/utils/parse.ts @@ -19,7 +19,9 @@ * 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]) @@ -48,11 +50,19 @@ export function parseUnit(value: string): { value: number; unit: string } | null * 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.ts index cfcad52a..2c59db75 100644 --- a/src/utils/ssr.ts +++ b/src/utils/ssr.ts @@ -9,13 +9,13 @@ export const isSSR = typeof window === 'undefined' /** - * Default dimensions to use during server-side rendering + * Default dimensions to use during server-side rendering * These values provide stable rendering between server and client * during the initial hydration phase. */ export const SSR_DIMENSIONS = { width: 1024, - height: 768 + height: 768, } /** @@ -28,7 +28,7 @@ export function safeClientValue(clientFn: () => T, fallback: T): T { if (isSSR) { return fallback } - + try { return clientFn() } catch { @@ -44,6 +44,10 @@ export function safeClientValue(clientFn: () => T, fallback: T): T { * @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 +} 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..573ec332 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,7 +30,8 @@ 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))` return { template, columnsCount, calculatedGap } @@ -76,7 +79,9 @@ 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') }) @@ -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..f4fe3735 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-fit, minmax(100px, 1fr))') + 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,7 +67,7 @@ describe('useGuide', () => { variant: 'auto', columnWidth: 'auto', gap: 10, - }), + }) ) expect(result.current.template).toBe('repeat(auto-fit, minmax(0, 1fr))') expect(result.current.columnsCount).toBe(1) @@ -71,15 +75,15 @@ describe('useGuide', () => { }) 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/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 })) From 36c37f568d553cea47dcf3c47af05816cc6c8685 Mon Sep 17 00:00:00 2001 From: dnvt Date: Sat, 8 Mar 2025 13:28:24 -0500 Subject: [PATCH 2/5] Improve code organization and add detailed documentation. Added comments to clarify the purpose and structure of CSS files, including descriptions for variables and components. Enhanced imports and module exports for better readability and maintainability. --- src/components/styles/base.css | 51 +++++++++++++++++++++------------- src/components/styles/core.css | 20 +++++++++++-- src/components/styles/index.ts | 14 ++++++++-- 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/src/components/styles/base.css b/src/components/styles/base.css index 00cd6bed..b962d714 100644 --- a/src/components/styles/base.css +++ b/src/components/styles/base.css @@ -1,18 +1,27 @@ +/** + * 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; - --bkzi: 1; - --bkzio: 2; - --bk-transition-base: 180ms ease; + --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%; - --bkhf: 100%; + --bkwf: 100%; /* Full width shorthand */ + --bkhf: 100%; /* Full height shorthand */ - /* Box Component */ + /* Box Component Variables */ --bkxb: var(--bkb); --bkxw: var(--bk-width-default); --bkxh: var(--bk-height-default); @@ -20,14 +29,14 @@ --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 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 */ + /* Baseline Component Variables */ --bkbw: 100%; --bkbh: 100%; --bkrt: 0; @@ -35,7 +44,7 @@ --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 */ + /* Guide Component Variables */ --bkgw: 100vw; --bkgh: 100vh; --bkgg: var(--bkb); @@ -48,7 +57,7 @@ --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 */ + /* 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)); @@ -64,7 +73,7 @@ --bkljc: start; --bklac: start; - /* Layout Component alternative variables */ + /* Layout Component alternative variables (explicitly named) */ --bk-layout-gtc: repeat(auto-fit, minmax(100px, 1fr)); --bk-layout-gtr: auto; --bk-layout-cg: 0; @@ -74,12 +83,12 @@ --bk-layout-jc: start; --bk-layout-ac: start; - /* Padder Component */ + /* 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 - with fallback values */ + /* 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)); @@ -87,7 +96,7 @@ --bksct: var(--bk-spacer-color-text-theme, hsla(270, 60%, 40%, 1)); } -/* Component styles with enhanced fallbacks to ensure visibility in all environments */ +/* Component-specific fallback styles to ensure cross-framework compatibility */ /* Spacer Component - Robust fallback styles */ .spr_zbcF6 { @@ -122,7 +131,9 @@ z-index: var(--bkzio); } -/* Guide Component - Robust fallbacks */ +/* Component-specific fallback values for theming */ + +/* 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)); @@ -130,27 +141,27 @@ --bkgcf: var(--bk-guide-color-fixed-theme, hsla(200, 100%, 70%, 0.15)); } -/* Baseline Component - Robust fallbacks */ +/* 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 - Robust fallbacks */ +/* 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 - Robust fallbacks */ +/* 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 - Robust fallbacks */ +/* 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)); diff --git a/src/components/styles/core.css b/src/components/styles/core.css index 5f4214f0..7a6c1126 100644 --- a/src/components/styles/core.css +++ b/src/components/styles/core.css @@ -1,14 +1,28 @@ -/* Core styles - Variables and fundamentals */ +/** + * 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 imports */ +/* 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 */ +/* Utility classes for visibility control */ .v { opacity: 1; visibility: visible; diff --git a/src/components/styles/index.ts b/src/components/styles/index.ts index b817ca40..05d563ec 100644 --- a/src/components/styles/index.ts +++ b/src/components/styles/index.ts @@ -1,8 +1,18 @@ -// This file ensures all styling files are properly exported +/** + * 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' -// Utility exports +// Export component types for external usage export * from '../types' +// Empty export to make this a proper module export {} From 69479aa026bbf0f6f489c38d2c1b74358d3a0c15 Mon Sep 17 00:00:00 2001 From: dnvt Date: Sun, 9 Mar 2025 14:37:12 -0400 Subject: [PATCH 3/5] Update dependencies and refactor components for SSR support This commit upgrades various dependencies, improves server-side rendering support, and ensures a consistent fallback UI for components like `Guide` and `Baseline`. It introduces a new `ClientOnly` utility, enhances measurement handling, and replaces auto-fit with auto-fill for grid templates. --- bun.lock | 80 ++++++----- src/components/Baseline/Baseline.tsx | 142 +++++++++++++------ src/components/Baseline/styles.module.css | 9 ++ src/components/Guide/Guide.tsx | 164 +++++++++++++++++----- src/components/Guide/styles.module.css | 13 ++ src/components/Guide/types.ts | 2 +- src/components/Layout/Layout.tsx | 6 +- src/components/Layout/styles.module.css | 16 +-- src/components/index.ts | 4 + src/components/styles/base.css | 63 ++------- src/components/styles/index.ts | 2 +- src/hooks/index.ts | 1 + src/hooks/useGuide.ts | 6 +- src/hooks/useIsClient.ts | 34 +++++ src/hooks/useMeasure.ts | 3 +- src/utils/{ssr.ts => ssr.tsx} | 44 ++++++ tests/components/Guide.test.tsx | 2 +- tests/hooks/useGuide.test.ts | 4 +- 18 files changed, 402 insertions(+), 193 deletions(-) create mode 100644 src/hooks/useIsClient.ts rename src/utils/{ssr.ts => ssr.tsx} (56%) diff --git a/bun.lock b/bun.lock index 2fa0a5cc..bad0dfcf 100644 --- a/bun.lock +++ b/bun.lock @@ -47,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=="], @@ -237,11 +237,13 @@ "@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/config-helpers": ["@eslint/config-helpers@0.1.0", "", {}, "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA=="], + "@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.21.0", "", {}, "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw=="], + "@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=="], @@ -283,65 +285,65 @@ "@pkgr/core": ["@pkgr/core@0.1.1", "", {}, "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.34.9", "", { "os": "android", "cpu": "arm" }, "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.35.0", "", { "os": "android", "cpu": "arm" }, "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.34.9", "", { "os": "android", "cpu": "arm64" }, "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.35.0", "", { "os": "android", "cpu": "arm64" }, "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.34.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.35.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.34.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q=="], + "@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-arm64": ["@rollup/rollup-freebsd-arm64@4.34.9", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.35.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.34.9", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.35.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.34.9", "", { "os": "linux", "cpu": "arm" }, "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.35.0", "", { "os": "linux", "cpu": "arm" }, "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.34.9", "", { "os": "linux", "cpu": "arm" }, "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.35.0", "", { "os": "linux", "cpu": "arm" }, "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.34.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw=="], + "@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-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.34.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A=="], + "@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-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.34.9", "", { "os": "linux", "cpu": "none" }, "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg=="], + "@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-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.34.9", "", { "os": "linux", "cpu": "ppc64" }, "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA=="], + "@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-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.34.9", "", { "os": "linux", "cpu": "none" }, "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.35.0", "", { "os": "linux", "cpu": "none" }, "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.34.9", "", { "os": "linux", "cpu": "s390x" }, "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ=="], + "@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-gnu": ["@rollup/rollup-linux-x64-gnu@4.34.9", "", { "os": "linux", "cpu": "x64" }, "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.35.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.34.9", "", { "os": "linux", "cpu": "x64" }, "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.35.0", "", { "os": "linux", "cpu": "x64" }, "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.34.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q=="], + "@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-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.34.9", "", { "os": "win32", "cpu": "ia32" }, "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.35.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.34.9", "", { "os": "win32", "cpu": "x64" }, "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.35.0", "", { "os": "win32", "cpu": "x64" }, "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw=="], - "@swc/core": ["@swc/core@1.11.7", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.19" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.7", "@swc/core-darwin-x64": "1.11.7", "@swc/core-linux-arm-gnueabihf": "1.11.7", "@swc/core-linux-arm64-gnu": "1.11.7", "@swc/core-linux-arm64-musl": "1.11.7", "@swc/core-linux-x64-gnu": "1.11.7", "@swc/core-linux-x64-musl": "1.11.7", "@swc/core-win32-arm64-msvc": "1.11.7", "@swc/core-win32-ia32-msvc": "1.11.7", "@swc/core-win32-x64-msvc": "1.11.7" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-ICuzjyfz8Hh3U16Mb21uCRJeJd/lUgV999GjgvPhJSISM1L8GDSB5/AMNcwuGs7gFywTKI4vAeeXWyCETUXHAg=="], + "@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-arm64": ["@swc/core-darwin-arm64@1.11.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3+LhCP2H50CLI6yv/lhOtoZ5B/hi7Q/23dye1KhbSDeDprLTm/KfLJh/iQqwaHUponf5m8C2U0y6DD+HGLz8Yw=="], + "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rrSsunyJWpHN+5V1zumndwSSifmIeFQBK9i2RMQQp15PgbgUNxHK5qoET1n20pcUrmZeT6jmJaEWlQchkV//Og=="], - "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-1diWpJqwX1XmOghf9ENFaeRaTtqLiqlZIW56RfOqmeZ7tPp3qS7VygWb9akptBsO5pEA5ZwNgSerD6AJlQcjAw=="], + "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-44goLqQuuo0HgWnG8qC+ZFw/qnjCVVeqffhzFr9WAXXotogVaxM8ze6egE58VWrfEc8me8yCcxOYL9RbtjhS/Q=="], - "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.7", "", { "os": "linux", "cpu": "arm" }, "sha512-MV8+hLREf0NN23NuSKemsjFaWjl/HnqdOkE7uhXTnHzg8WTwp6ddVtU5Yriv15+d/ktfLWPVAOhLHQ4gzaoa8A=="], + "@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-gnu": ["@swc/core-linux-arm64-gnu@1.11.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-5GNs8ZjHQy/UTSnzzn+gm1RCUpCYo43lsxYOl8mpcnZSfxkNFVpjfylBv0QuJ5qhdfZ2iU55+v4iJCwCMtw0nA=="], + "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-EyhO6U+QdoGYC1MeHOR0pyaaSaKYyNuT4FQNZ1eZIbnuueXpuICC7iNmLIOfr3LE5bVWcZ7NKGVPlM2StJEcgA=="], - "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.11.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-cTydaYBwDbVV5CspwVcCp9IevYWpGD1cF5B5KlBdjmBzxxeWyTAJRtKzn8w5/UJe/MfdAptarpqMPIs2f33YEQ=="], + "@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-gnu": ["@swc/core-linux-x64-gnu@1.11.7", "", { "os": "linux", "cpu": "x64" }, "sha512-YAX2KfYPlbDsnZiVMI4ZwotF3VeURUrzD+emJgFf1g26F4eEmslldgnDrKybW7V+bObsH22cDqoy6jmQZgpuPQ=="], + "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.8", "", { "os": "linux", "cpu": "x64" }, "sha512-r72onUEIU1iJi9EUws3R28pztQ/eM3EshNpsPRBfuLwKy+qn3et55vXOyDhIjGCUph5Eg2Yn8H3h6MTxDdLd+w=="], - "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.7", "", { "os": "linux", "cpu": "x64" }, "sha512-mYT6FTDZyYx5pailc8xt6ClS2yjKmP8jNHxA9Ce3K21n5qkKilI5M2N7NShwXkd3Ksw3F29wKrg+wvEMXTRY/A=="], + "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.8", "", { "os": "linux", "cpu": "x64" }, "sha512-294k8cLpO103++f4ZUEDr3vnBeUfPitW6G0a3qeVZuoXFhFgaW7ANZIWknUc14WiLOMfMecphJAEiy9C8OeYSw=="], - "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-uLDQEcv0BHcepypstyxKkNsW6KfLyI5jVxTbcxka+B2UnMcFpvoR87nGt2JYW0grO2SNZPoFz+UnoKL9c6JxpA=="], + "@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-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.7", "", { "os": "win32", "cpu": "ia32" }, "sha512-wiq5G3fRizdxAJVFcon7zpyfbfrb+YShuTy+TqJ4Nf5PC0ueMOXmsmeuyQGApn6dVWtGCyymYQYt77wHeQajdA=="], + "@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.7", "", { "os": "win32", "cpu": "x64" }, "sha512-/zQdqY4fHkSORxEJ2cKtRBOwglvf/8gs6Tl4Q6VMx2zFtFpIOwFQstfY5u8wBNN2Z+PkAzyUCPoi8/cQFK8HLQ=="], + "@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=="], @@ -361,7 +363,7 @@ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], - "@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "@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=="], @@ -443,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=="], @@ -531,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=="], @@ -613,7 +615,7 @@ "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], - "eslint": ["eslint@9.21.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.0", "@eslint/js": "9.21.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.2.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-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg=="], + "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=="], @@ -623,7 +625,7 @@ "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@8.2.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A=="], + "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@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="], @@ -1127,7 +1129,7 @@ "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - "rollup": ["rollup@4.34.9", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.34.9", "@rollup/rollup-android-arm64": "4.34.9", "@rollup/rollup-darwin-arm64": "4.34.9", "@rollup/rollup-darwin-x64": "4.34.9", "@rollup/rollup-freebsd-arm64": "4.34.9", "@rollup/rollup-freebsd-x64": "4.34.9", "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", "@rollup/rollup-linux-arm-musleabihf": "4.34.9", "@rollup/rollup-linux-arm64-gnu": "4.34.9", "@rollup/rollup-linux-arm64-musl": "4.34.9", "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", "@rollup/rollup-linux-riscv64-gnu": "4.34.9", "@rollup/rollup-linux-s390x-gnu": "4.34.9", "@rollup/rollup-linux-x64-gnu": "4.34.9", "@rollup/rollup-linux-x64-musl": "4.34.9", "@rollup/rollup-win32-arm64-msvc": "4.34.9", "@rollup/rollup-win32-ia32-msvc": "4.34.9", "@rollup/rollup-win32-x64-msvc": "4.34.9", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ=="], + "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=="], @@ -1303,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=="], diff --git a/src/components/Baseline/Baseline.tsx b/src/components/Baseline/Baseline.tsx index 9d70275c..cdff090d 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' @@ -126,28 +125,88 @@ export const Baseline = React.memo(function Baseline({ 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 ( + + + + ) +}) + +// Implementation component that only renders on the client side +const BaselineImpl = React.memo(function BaselineImpl({ + className, + debugging, + style, + variant, + height: heightProp, + width: widthProp, + base, + color: colorProp, + ssrMode: _ssrMode = false, + ...spacingProps +}: BaselineProps) { + const config = useConfig('baseline') + 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) + const { + width: containerWidth, + height: containerHeight, + refresh, + } = useMeasure(containerRef) - // After hydration, we can use real measurement + // 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 handleResize = () => { + refresh() + } - const { width: containerWidth, height: containerHeight } = dimensions + window.addEventListener('resize', handleResize) + return () => { + window.removeEventListener('resize', handleResize) + } + }, [refresh]) const [_normWidth, normHeight] = React.useMemo(() => { return normalizeValuePair( @@ -170,43 +229,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) // 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(() => { @@ -263,16 +314,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 ( diff --git a/src/components/Baseline/styles.module.css b/src/components/Baseline/styles.module.css index 417b2c8a..e4c1563d 100644 --- a/src/components/Baseline/styles.module.css +++ b/src/components/Baseline/styles.module.css @@ -15,3 +15,12 @@ height: var(--bkrh); 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/Guide/Guide.tsx b/src/components/Guide/Guide.tsx index 7ca140ca..859b7396 100644 --- a/src/components/Guide/Guide.tsx +++ b/src/components/Guide/Guide.tsx @@ -1,14 +1,15 @@ import * as React from 'react' +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 */ @@ -23,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 */ @@ -160,13 +159,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,36 +174,118 @@ export const Guide = React.memo(function Guide({ const config = useConfig('guide') const variant = variantProp ?? config.variant const gap = typeof gapProp === 'number' ? gapProp : 0 + const { isShown } = useDebug(debugging, config.debugging) - // Add hydration state tracking - const [isHydrated, setIsHydrated] = React.useState(false) + // If debugging isn't enabled, render a hidden element + // This ensures tests can find the element even when hidden + if (!isShown) { + return ( +
+ {children} +
+ ) + } - React.useEffect(() => { - setIsHydrated(true) - }, []) + // Create a simple SSR fallback with the expected dimensions + const ssrFallback = ( +
+ {children} +
+ ) - const containerRef = React.useRef(null) + // Wrap the actual implementation in ClientOnly + return ( + + + {children} + + + ) +}) - // Always call useMeasure, but conditionally use its results - const measuredDimensions = useMeasure(containerRef) +// 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) - // Choose appropriate dimensions based on rendering environment - const dimensions = hydratedValue( - isHydrated && !ssrMode, - { width: 1024, height: 768, refresh: () => {} }, - measuredDimensions - ) + // Measure the container dimensions + const { + width: containerWidth, + height: containerHeight, + refresh, // Keep the refresh function available for dynamic updates + } = useMeasure(containerRef) - const { width: containerWidth, height: containerHeight } = dimensions + // Effect for handling window resize events + React.useEffect(() => { + const handleResize = () => { + // Trigger a remeasurement when window size changes + refresh() + } - const { isShown } = useDebug(debugging, config.debugging) + 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, }) @@ -227,7 +307,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'] @@ -256,11 +335,6 @@ export const Guide = React.memo(function Guide({ value: columnWidthValue, defaultStyles, }), - ...createStyleOverride({ - key: '--bkggw', - value: gutterWidthValue, - defaultStyles, - }), ...createStyleOverride({ key: '--bkgc', value: `${columnsCount}`, @@ -276,19 +350,21 @@ export const Guide = React.memo(function Guide({ value: color ?? config.colors.line, defaultStyles, }), - // Use style override for gap to be consistent with other properties ...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 justifyContent based on align - justifyContent: align, } as React.CSSProperties return mergeStyles(customStyles, style) @@ -297,7 +373,6 @@ export const Guide = React.memo(function Guide({ height, maxWidth, columnWidth, - gutterWidth, columnsCount, color, template, @@ -310,11 +385,22 @@ export const Guide = React.memo(function Guide({ align, ]) - // Calculate how many columns we need - // 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 = gap === 0 ? 0 : gap - 1 - const actualGapWithLine = finalGap + 1 + // 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 = diff --git a/src/components/Guide/styles.module.css b/src/components/Guide/styles.module.css index 6d7d9a03..d0019214 100644 --- a/src/components/Guide/styles.module.css +++ b/src/components/Guide/styles.module.css @@ -14,10 +14,12 @@ inset: 0; display: grid; column-gap: var(--bkgg); + grid-template-rows: 1fr; grid-template-columns: var(--bkgt); justify-content: var(--bkgj); width: var(--bkwf); height: var(--bkhf); + overflow: hidden; } .col { @@ -38,8 +40,19 @@ .col[data-variant='auto'] { background-color: var(--bkgca); + overflow: hidden; } .col[data-variant='fixed'] { background-color: var(--bkgcf); } + +/* Style for SSR rendering */ +.ssr { + box-sizing: border-box; + display: grid; + position: relative; + z-index: 1; + pointer-events: none; + min-height: 100px; /* Ensures a minimum height during SSR */ +} diff --git a/src/components/Guide/types.ts b/src/components/Guide/types.ts index affa1b8d..3442f0d1 100644 --- a/src/components/Guide/types.ts +++ b/src/components/Guide/types.ts @@ -96,7 +96,7 @@ export type FixedConfig = BaseGuideConfig & { * * @example * ```ts - * // Auto-fit columns of 200px + * // Auto-fill columns of 200px * const auto: AutoConfig = { * variant: 'auto', * columnWidth: '200px', diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 544d907c..bff5f610 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -76,7 +76,7 @@ export const getGridTemplate = ( 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 */ @@ -141,7 +141,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, @@ -258,7 +258,7 @@ export const Layout = React.memo(function Layout({ }), // Grid properties - only inject if different from defaults - ...(gridTemplateColumns !== 'repeat(auto-fit, minmax(100px, 1fr))' && { + ...(gridTemplateColumns !== 'repeat(auto-fill, minmax(100px, 1fr))' && { '--bklgtc': gridTemplateColumns, }), ...(gridTemplateRows !== 'auto' && { '--bklgtr': gridTemplateRows }), diff --git a/src/components/Layout/styles.module.css b/src/components/Layout/styles.module.css index 1f2234ca..0e2ddefc 100644 --- a/src/components/Layout/styles.module.css +++ b/src/components/Layout/styles.module.css @@ -6,16 +6,16 @@ height: var(--bklh, var(--bk-height-default, auto)); grid-template-columns: var( --bklgtc, - var(--bk-layout-gtc, repeat(auto-fit, minmax(100px, 1fr))) + repeat(auto-fill, minmax(100px, 1fr)) ); - grid-template-rows: var(--bklgtr, var(--bk-layout-gtr, auto)); + grid-template-rows: var(--bklgtr, auto); gap: var(--bklg, 0); - column-gap: var(--bklcg, var(--bk-layout-cg, 0)); - row-gap: var(--bklrg, var(--bk-layout-rg, 0)); - justify-items: var(--bklji, var(--bk-layout-ji, stretch)); - align-items: var(--bklai, var(--bk-layout-ai, stretch)); - justify-content: var(--bkljc, var(--bk-layout-jc, start)); - align-content: var(--bklac, var(--bk-layout-ac, start)); + 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, diff --git a/src/components/index.ts b/src/components/index.ts index 22e18677..ef2cda02 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -26,3 +26,7 @@ export * from './Config' // Types export * from './types' + +// Other component exports... + +// DON'T export ClientOnly from here anymore as it's been moved to utils/ssr diff --git a/src/components/styles/base.css b/src/components/styles/base.css index b962d714..496f6aaf 100644 --- a/src/components/styles/base.css +++ b/src/components/styles/base.css @@ -10,16 +10,16 @@ /* 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 */ + --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 */ + --bkwf: 100%; /* Full width shorthand */ + --bkhf: 100%; /* Full height shorthand */ /* Box Component Variables */ --bkxb: var(--bkb); @@ -48,7 +48,7 @@ --bkgw: 100vw; --bkgh: 100vh; --bkgg: var(--bkb); - --bkgj: start; + --bkgj: center; --bkgt: auto; --bkgpb: 0; --bkgpi: 0; @@ -63,7 +63,7 @@ --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-fit, minmax(100px, 1fr)); + --bklgtc: repeat(auto-fill, minmax(100px, 1fr)); --bklgtr: auto; --bklg: 0; --bklcg: 0; @@ -73,16 +73,6 @@ --bkljc: start; --bklac: start; - /* Layout Component alternative variables (explicitly named) */ - --bk-layout-gtc: repeat(auto-fit, minmax(100px, 1fr)); - --bk-layout-gtr: auto; - --bk-layout-cg: 0; - --bk-layout-rg: 0; - --bk-layout-ji: stretch; - --bk-layout-ai: stretch; - --bk-layout-jc: start; - --bk-layout-ac: start; - /* Padder Component Variables */ --bkpw: var(--bk-width-default); --bkph: var(--bk-height-default); @@ -96,43 +86,6 @@ --bksct: var(--bk-spacer-color-text-theme, hsla(270, 60%, 40%, 1)); } -/* Component-specific fallback styles to ensure cross-framework compatibility */ - -/* Spacer Component - Robust fallback styles */ -.spr_zbcF6 { - /* Variable definitions with fallbacks */ - --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)); - --bkzi: 1; - --bkzio: 2; - - /* Essential layout properties */ - position: relative; - box-sizing: border-box; - margin: 0; - padding: 0; - width: var(--bksw, 100%); - height: var(--bksh, auto); - background-color: var(--bkscf); - border: 1px dashed var(--bkscl); -} - -/* Spacer text indicator */ -.spr_zbcF6[data-height]::before { - content: attr(data-height); - color: var(--bksct); - font-family: monospace; - font-size: 12px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - z-index: var(--bkzio); -} - -/* Component-specific fallback values for theming */ - /* Guide Component */ .guide { --bkgcl: var(--bk-guide-color-line-theme, hsla(240, 60%, 40%, 0.15)); diff --git a/src/components/styles/index.ts b/src/components/styles/index.ts index 05d563ec..ca903b32 100644 --- a/src/components/styles/index.ts +++ b/src/components/styles/index.ts @@ -1,6 +1,6 @@ /** * 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 diff --git a/src/hooks/index.ts b/src/hooks/index.ts index a564dc39..dc06ae22 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -15,3 +15,4 @@ export * from './useGuide' // Configuration export * from './useConfig' export * from './useDebug' +export * from './useIsClient' diff --git a/src/hooks/useGuide.ts b/src/hooks/useGuide.ts index 37f1ab49..6e224533 100644 --- a/src/hooks/useGuide.ts +++ b/src/hooks/useGuide.ts @@ -172,11 +172,11 @@ export function useGuide( } case 'auto': { - // Auto-fitting columns + // Auto-filling columns const colWidth = config.columnWidth ?? 'auto' if (colWidth === 'auto') { return { - template: 'repeat(auto-fit, minmax(0, 1fr))', + template: 'repeat(auto-fill, minmax(0, 1fr))', columnsCount: 1, calculatedGap: gap, isValid: true, @@ -192,7 +192,7 @@ export function useGuide( : 1 return { - template: `repeat(auto-fit, minmax(${colWidthStr}, 1fr))`, + template: `repeat(auto-fill, ${colWidthStr})`, columnsCount: columns, calculatedGap: gap, isValid: true, diff --git a/src/hooks/useIsClient.ts b/src/hooks/useIsClient.ts new file mode 100644 index 00000000..22e10e89 --- /dev/null +++ b/src/hooks/useIsClient.ts @@ -0,0 +1,34 @@ +import { useEffect, useState } from 'react' + +/** + * Hook to determine if the code is running on the client side. + * + * Safely detects client-side environments and provides a boolean flag + * that can be used for conditional rendering of client-only components. + * + * @returns Boolean indicating if the code is running in a browser environment + * + * @example + * ```tsx + * function ClientOnlyComponent() { + * const isClient = useIsClient() + * + * if (!isClient) { + * return null // or a placeholder/skeleton + * } + * + * return
This only renders on the client
+ * } + * ``` + */ +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 6077cdd0..6d6f8c2f 100644 --- a/src/hooks/useMeasure.ts +++ b/src/hooks/useMeasure.ts @@ -62,12 +62,13 @@ export function useMeasure( // On mount (or when ref changes) perform an immediate measurement. 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/utils/ssr.ts b/src/utils/ssr.tsx similarity index 56% rename from src/utils/ssr.ts rename to src/utils/ssr.tsx index 2c59db75..c86355f9 100644 --- a/src/utils/ssr.ts +++ b/src/utils/ssr.tsx @@ -2,6 +2,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' /** * Detects if code is running in a server-side environment @@ -51,3 +53,45 @@ export function hydratedValue( ): T { return !isHydrated || isSSR ? ssrValue : dynamicValue } + +export 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. + * + * Useful for components that rely on browser-specific APIs like DOM measurements, + * which aren't available during server-side rendering. + * + * @example + * ```tsx + * // With no fallback (renders nothing during SSR) + * + * + * + * + * // With a fallback (renders placeholder during SSR) + * }> + * + * + * ``` + */ +export function ClientOnly({ children, fallback = null }: ClientOnlyProps) { + const isClient = useIsClient() + + // On the server or during hydration, render the fallback + if (!isClient) { + return <>{fallback} + } + + // On the client, render the actual content + return <>{children} +} diff --git a/tests/components/Guide.test.tsx b/tests/components/Guide.test.tsx index 573ec332..c8ec2c13 100644 --- a/tests/components/Guide.test.tsx +++ b/tests/components/Guide.test.tsx @@ -33,7 +33,7 @@ vi.mock('@hooks', async () => { 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') { diff --git a/tests/hooks/useGuide.test.ts b/tests/hooks/useGuide.test.ts index f4fe3735..2fe3c640 100644 --- a/tests/hooks/useGuide.test.ts +++ b/tests/hooks/useGuide.test.ts @@ -53,7 +53,7 @@ describe('useGuide', () => { gap: 8, }) ) - expect(result.current.template).toBe('repeat(auto-fit, minmax(100px, 1fr))') + 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) @@ -69,7 +69,7 @@ describe('useGuide', () => { 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) }) From 0909b008bdd5843d21045f13f04c8d232a89f32d Mon Sep 17 00:00:00 2001 From: dnvt Date: Sun, 9 Mar 2025 15:39:52 -0400 Subject: [PATCH 4/5] Refactor components and utilities, revise exports, and add package verification. This commit implements several structural improvements and optimizations, including reducing export scope to only essential components, types, and utilities, while keeping internal functionalities private. Component and utility functions were modified to improve consistency, and `useIsClient` and `ClientOnly` are now internalized. Additionally, workflow updates were introduced to verify package contents during CI. --- .github/workflows/test.yml | 8 ++ bun.lock | 2 +- src/components/Baseline/Baseline.tsx | 188 +++++++++++++-------------- src/components/Box/Box.tsx | 33 +++-- src/components/Config/Config.tsx | 50 +++---- src/components/Config/defaults.ts | 4 +- src/components/Config/index.ts | 2 +- src/components/Guide/Guide.tsx | 89 +++++++------ src/components/Guide/index.ts | 6 - src/components/Layout/Layout.tsx | 8 +- src/components/Padder/Padder.tsx | 24 ++-- src/components/Spacer/Spacer.tsx | 10 +- src/components/Stack/Stack.tsx | 9 +- src/components/index.ts | 10 +- src/components/styles/index.ts | 3 - src/hooks/index.ts | 4 +- src/hooks/useConfig.ts | 6 +- src/hooks/useGuide.ts | 12 +- src/hooks/useIsClient.ts | 16 --- src/index.ts | 33 ++++- src/utils/convert.ts | 17 --- src/utils/math.ts | 37 ------ src/utils/normalize.ts | 35 ----- src/utils/parse.ts | 29 ----- src/utils/ssr.tsx | 31 +---- tests/components/Guide.test.tsx | 2 +- tsconfig.json | 2 +- 27 files changed, 265 insertions(+), 405 deletions(-) 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/bun.lock b/bun.lock index bad0dfcf..7ebc8501 100644 --- a/bun.lock +++ b/bun.lock @@ -475,7 +475,7 @@ "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.30001702", "", {}, "sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA=="], + "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=="], diff --git a/src/components/Baseline/Baseline.tsx b/src/components/Baseline/Baseline.tsx index cdff090d..2f1a4496 100644 --- a/src/components/Baseline/Baseline.tsx +++ b/src/components/Baseline/Baseline.tsx @@ -31,10 +31,8 @@ export type BaselineProps = { ssrMode?: boolean } & ComponentsProps -// Utils ----------------------------------------------------------------------- - /** Creates default baseline styles */ -export const createDefaultBaselineStyles = ( +const createDefaultBaselineStyles = ( base: number, lineColor: string, flatColor: string @@ -66,7 +64,7 @@ type RowStyleParams = { * Creates styles for an individual baseline row. * Applies positioning and visual styling based on variant. */ -export const createBaselineRowStyle = ( +const createBaselineRowStyle = ( params: RowStyleParams ): React.CSSProperties => { const { index, base, variant, chosenColor, lineColor, flatColor } = params @@ -79,97 +77,6 @@ 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({ - 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 ( - - - - ) -}) - // Implementation component that only renders on the client side const BaselineImpl = React.memo(function BaselineImpl({ className, @@ -364,3 +271,94 @@ const BaselineImpl = React.memo(function BaselineImpl({
) }) + +/** + * 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/Box/Box.tsx b/src/components/Box/Box.tsx index 08f731cc..2e825289 100644 --- a/src/components/Box/Box.tsx +++ b/src/components/Box/Box.tsx @@ -10,7 +10,7 @@ import { createStyleOverride, 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,23 +39,20 @@ 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'] @@ -70,10 +67,10 @@ type BoxCustomStylesParams = { } /** - * 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, @@ -84,28 +81,28 @@ export const createBoxCustomStyles = ({ 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 }, }), ...createStyleOverride({ - key: '--bkxh', + key: '--bkboxh', value: heightValue, defaultStyles, skipDimensions: { fitContent: dimensionVars }, }), ...createStyleOverride({ - key: '--bkxb', + key: '--bkboxb', value: `${base}px`, defaultStyles, }), ...createStyleOverride({ - key: '--bkxcl', + key: '--bkboxc', value: lineColor, defaultStyles, }), diff --git a/src/components/Config/Config.tsx b/src/components/Config/Config.tsx index 2b949e1b..abf74128 100644 --- a/src/components/Config/Config.tsx +++ b/src/components/Config/Config.tsx @@ -24,7 +24,7 @@ type Colors = { } /** Complete configuration schema for baseline-kit. */ -export type Config = { +export type ConfigSchema = { /** Base unit for spacing calculations */ base: number /** Guide component configuration */ @@ -68,7 +68,7 @@ export type Config = { } // 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 @@ -79,19 +79,19 @@ type ConfigProps = { /** Base unit for spacing calculations */ 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 ----------------------------------------------------------------------- @@ -101,19 +101,19 @@ type CSSVariablesParams = { /** Base unit for spacing calculations */ 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'] } /** @@ -166,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 /** 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, diff --git a/src/components/Config/defaults.ts b/src/components/Config/defaults.ts index 3e0e6d55..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, diff --git a/src/components/Config/index.ts b/src/components/Config/index.ts index f0e8f25e..e752c620 100644 --- a/src/components/Config/index.ts +++ b/src/components/Config/index.ts @@ -9,4 +9,4 @@ */ export * from './Config' -export * from './defaults' +export { DEFAULT_CONFIG } from './defaults' diff --git a/src/components/Guide/Guide.tsx b/src/components/Guide/Guide.tsx index 859b7396..3301a251 100644 --- a/src/components/Guide/Guide.tsx +++ b/src/components/Guide/Guide.tsx @@ -46,57 +46,60 @@ type GridConfigParams = { columnWidth?: React.CSSProperties['width'] } -// Utils ----------------------------------------------------------------------- - -/** Creates the appropriate grid configuration based on variant */ -export const createGridConfig = ( +/** + * 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, + switch (variant) { + case 'line': + return { + variant: 'line', + gap, base, - }, - auto: columnWidth - ? { - variant: 'auto' as const, - columnWidth, - gap, - base, - } - : null, - pattern: Array.isArray(columns) - ? { - variant: 'pattern' as const, - columns, - gap, - base, - } - : null, - fixed: - typeof columns === 'number' - ? { - variant: 'fixed' as const, - columns, - columnWidth, - gap, - base, - } - : null, - }[variant] ?? { - variant: 'line' as const, - gap: gap - 1, - base, - } - ) + } as LineConfig + + case 'pattern': + if (columns && Array.isArray(columns)) { + return { + variant: 'pattern', + columns: columns as readonly (string | number)[], + gap, + base, + } as PatternConfig + } + 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, + } 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 ): Record => ({ diff --git a/src/components/Guide/index.ts b/src/components/Guide/index.ts index fcc68e69..68c8da5b 100644 --- a/src/components/Guide/index.ts +++ b/src/components/Guide/index.ts @@ -2,12 +2,6 @@ * @file Guide Component Entry (components/Guide/index.ts) * @description Visual grid overlay system for alignment * @module baseline-kit/components/Guide - * - * @remarks - * Provides visual grid overlays for layout alignment with - * multiple grid strategies and validation. */ export * from './Guide' -export * from './types' -export * from './validation' diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index bff5f610..23927fd0 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -52,10 +52,8 @@ export type LayoutProps = { } & ComponentsProps & Gaps -// Utils ----------------------------------------------------------------------- - /** Creates default layout styles with theme colors */ -export const createDefaultLayoutStyles = (colors: { +const createDefaultLayoutStyles = (colors: { line: string flat: string text: string @@ -68,7 +66,7 @@ export const createDefaultLayoutStyles = (colors: { }) /** Parses grid template definitions into CSS grid-template values. */ -export const getGridTemplate = ( +const getGridTemplate = ( prop?: number | string | Array ): string => { if (typeof prop === 'number') return `repeat(${prop}, 1fr)` @@ -80,7 +78,7 @@ export const getGridTemplate = ( } /** Creates grid gap styles */ -export const createGridGapStyles = ( +const createGridGapStyles = ( gap?: React.CSSProperties['gap'] | number, rowGap?: React.CSSProperties['rowGap'] | number, columnGap?: React.CSSProperties['columnGap'] | number diff --git a/src/components/Padder/Padder.tsx b/src/components/Padder/Padder.tsx index 56c9dfe7..136d07f0 100644 --- a/src/components/Padder/Padder.tsx +++ b/src/components/Padder/Padder.tsx @@ -24,7 +24,7 @@ type PaddingStyles = { [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,10 +32,8 @@ 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, @@ -50,20 +48,16 @@ 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 @@ -89,7 +83,7 @@ export const createDirectPaddingStyles = ( } /** Creates a render function for spacers */ -export const createRenderSpacerFn = ( +const createRenderSpacerFn = ( variant: Variant | undefined, debugging: DebuggingMode | undefined, indicatorNode?: IndicatorNode diff --git a/src/components/Spacer/Spacer.tsx b/src/components/Spacer/Spacer.tsx index 2461582a..316ba71f 100644 --- a/src/components/Spacer/Spacer.tsx +++ b/src/components/Spacer/Spacer.tsx @@ -40,7 +40,7 @@ export type SpacerProps = { // Utils ----------------------------------------------------------------------- /** Creates default spacer styles */ -export const createDefaultSpacerStyles = ( +const createDefaultSpacerStyles = ( base: number, textColor: string, flatColor: string, @@ -49,13 +49,13 @@ export const createDefaultSpacerStyles = ( '--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, @@ -188,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, }), diff --git a/src/components/Stack/Stack.tsx b/src/components/Stack/Stack.tsx index 5359a420..e160ac50 100644 --- a/src/components/Stack/Stack.tsx +++ b/src/components/Stack/Stack.tsx @@ -16,10 +16,7 @@ import { ComponentsProps, Variant } from '../types' import styles from './styles.module.css' // Maps shorthand directions to Flexbox directions -export const DIRECTION_AXIS: Record< - string, - React.CSSProperties['flexDirection'] -> = { +const DIRECTION_AXIS: Record = { x: 'row', y: 'column', '-x': 'row-reverse', @@ -58,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, @@ -67,7 +64,7 @@ export const createDefaultStackStyles = (colors: Record) => ({ }) /** Creates gap styles for the stack */ -export const createStackGapStyles = ( +const createStackGapStyles = ( rowGap?: number, columnGap?: number, gap?: number diff --git a/src/components/index.ts b/src/components/index.ts index ef2cda02..fdc311e0 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -12,21 +12,15 @@ import './styles/theme.css' 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' - -// Other component exports... - -// DON'T export ClientOnly from here anymore as it's been moved to utils/ssr diff --git a/src/components/styles/index.ts b/src/components/styles/index.ts index ca903b32..a458d5ec 100644 --- a/src/components/styles/index.ts +++ b/src/components/styles/index.ts @@ -11,8 +11,5 @@ import './core.css' import './theme.css' -// Export component types for external usage -export * from '../types' - // Empty export to make this a proper module export {} diff --git a/src/hooks/index.ts b/src/hooks/index.ts index dc06ae22..e3b4e1aa 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -15,4 +15,6 @@ export * from './useGuide' // Configuration export * from './useConfig' export * from './useDebug' -export * from './useIsClient' + +// Don't export useIsClient as it's only used internally +// export * from './useIsClient' diff --git a/src/hooks/useConfig.ts b/src/hooks/useConfig.ts index ae02e2eb..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,7 +41,7 @@ export type ComponentConfig = Config[K] & { * } * ``` */ -export function useConfig( +export function useConfig( component: K ): ComponentConfig { const defaultConfig = useDefaultConfig() diff --git a/src/hooks/useGuide.ts b/src/hooks/useGuide.ts index 6e224533..23a49e75 100644 --- a/src/hooks/useGuide.ts +++ b/src/hooks/useGuide.ts @@ -1,9 +1,6 @@ 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' @@ -124,9 +121,14 @@ export function useGuide( case 'pattern': { // Custom column pattern + if (!config.columns || !Array.isArray(config.columns)) { + throw new Error('Missing or invalid pattern columns') + } + 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` diff --git a/src/hooks/useIsClient.ts b/src/hooks/useIsClient.ts index 22e10e89..99e5472d 100644 --- a/src/hooks/useIsClient.ts +++ b/src/hooks/useIsClient.ts @@ -3,23 +3,7 @@ import { useEffect, useState } from 'react' /** * Hook to determine if the code is running on the client side. * - * Safely detects client-side environments and provides a boolean flag - * that can be used for conditional rendering of client-only components. - * * @returns Boolean indicating if the code is running in a browser environment - * - * @example - * ```tsx - * function ClientOnlyComponent() { - * const isClient = useIsClient() - * - * if (!isClient) { - * return null // or a placeholder/skeleton - * } - * - * return
This only renders on the client
- * } - * ``` */ export function useIsClient() { // Start with false for SSR diff --git a/src/index.ts b/src/index.ts index 0f5fd5a9..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' +// 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/utils/convert.ts b/src/utils/convert.ts index 82f303c7..078d4d1a 100644 --- a/src/utils/convert.ts +++ b/src/utils/convert.ts @@ -45,26 +45,9 @@ export const RELATIVE_UNITS: string[] = [ /** * 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, diff --git a/src/utils/math.ts b/src/utils/math.ts index e9c9a528..e1c981f0 100644 --- a/src/utils/math.ts +++ b/src/utils/math.ts @@ -3,23 +3,10 @@ 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, @@ -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,20 +40,9 @@ 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) { @@ -104,12 +73,6 @@ type RowCountParams = { * * @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 diff --git a/src/utils/normalize.ts b/src/utils/normalize.ts index bc27775e..3cf95b9d 100644 --- a/src/utils/normalize.ts +++ b/src/utils/normalize.ts @@ -15,35 +15,9 @@ 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, @@ -106,15 +80,6 @@ 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: diff --git a/src/utils/parse.ts b/src/utils/parse.ts index c3de0919..2e85eb79 100644 --- a/src/utils/parse.ts +++ b/src/utils/parse.ts @@ -1,23 +1,8 @@ /** * 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 @@ -32,23 +17,9 @@ export function parseUnit( /** * 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, diff --git a/src/utils/ssr.tsx b/src/utils/ssr.tsx index c86355f9..84a76e26 100644 --- a/src/utils/ssr.tsx +++ b/src/utils/ssr.tsx @@ -1,9 +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' +import { useIsClient } from '../hooks/useIsClient' /** * Detects if code is running in a server-side environment @@ -12,8 +11,6 @@ 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. */ export const SSR_DIMENSIONS = { width: 1024, @@ -44,7 +41,6 @@ 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, @@ -54,7 +50,11 @@ export function hydratedValue( return !isHydrated || isSSR ? ssrValue : dynamicValue } -export interface ClientOnlyProps { +/** + * ClientOnly component props + * @internal + */ +interface ClientOnlyProps { /** * Content to render when on the client-side */ @@ -67,31 +67,14 @@ export interface ClientOnlyProps { /** * A utility component that only renders its children on the client side. - * - * Useful for components that rely on browser-specific APIs like DOM measurements, - * which aren't available during server-side rendering. - * - * @example - * ```tsx - * // With no fallback (renders nothing during SSR) - * - * - * - * - * // With a fallback (renders placeholder during SSR) - * }> - * - * - * ``` + * @internal Not part of the public API */ export function ClientOnly({ children, fallback = null }: ClientOnlyProps) { const isClient = useIsClient() - // On the server or during hydration, render the fallback if (!isClient) { return <>{fallback} } - // On the client, render the actual content return <>{children} } diff --git a/tests/components/Guide.test.tsx b/tests/components/Guide.test.tsx index c8ec2c13..00077d7a 100644 --- a/tests/components/Guide.test.tsx +++ b/tests/components/Guide.test.tsx @@ -83,7 +83,7 @@ describe('Guide component', () => { ) 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', () => { 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": [ From ae8846828b836ed18495d911dc7dece129b73d77 Mon Sep 17 00:00:00 2001 From: dnvt Date: Sun, 9 Mar 2025 15:47:14 -0400 Subject: [PATCH 5/5] version bump --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) 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/package.json b/package.json index e0917cc1..6c5d15de 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "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",