diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index 3c032078a..000000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -18 diff --git a/bun.lock b/bun.lock index da7fa985b..4c363cca7 100644 --- a/bun.lock +++ b/bun.lock @@ -37,7 +37,6 @@ "@sanity/visual-editing": "^2.10.5", "@seed-design/react": "0.0.0", "@seed-design/react-icon": "^0.7.3", - "@seed-design/react-tabs": "0.0.0-alpha-20241209060641", "@seed-design/recipe": "0.0.0-alpha-20241212122822", "@seed-design/rootage-cli": "0.0.0", "@seed-design/rootage-core": "0.0.0", @@ -431,10 +430,14 @@ "name": "@seed-design/react-tabs", "version": "0.0.0-alpha-20241209060641", "dependencies": { + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-use-callback-ref": "^1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "^1.1.0", "@radix-ui/react-use-size": "^1.1.0", "@seed-design/dom-utils": "0.0.0-alpha-20241030023710", - "@use-gesture/react": "^10.3.1", + "embla-carousel-auto-height": "^8.5.2", + "embla-carousel-react": "^8.5.2", }, "devDependencies": { "esbuild": "^0.25.0", @@ -618,7 +621,9 @@ "tools/figma-extractor": { "name": "@seed-design/figma-extractor", "version": "0.0.3", - "bin": "./bin/index.mjs", + "bin": { + "figma-extractor": "./bin/index.mjs" + }, "dependencies": { "@figma/rest-api-spec": "^0.23.0", "cac": "^6.7.14", @@ -748,11 +753,11 @@ "@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=="], - "@babel/compat-data": ["@babel/compat-data@7.26.5", "", {}, "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg=="], + "@babel/compat-data": ["@babel/compat-data@7.26.8", "", {}, "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ=="], - "@babel/core": ["@babel/core@7.26.7", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.26.5", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", "@babel/helpers": "^7.26.7", "@babel/parser": "^7.26.7", "@babel/template": "^7.25.9", "@babel/traverse": "^7.26.7", "@babel/types": "^7.26.7", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA=="], + "@babel/core": ["@babel/core@7.26.8", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.26.8", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", "@babel/helpers": "^7.26.7", "@babel/parser": "^7.26.8", "@babel/template": "^7.26.8", "@babel/traverse": "^7.26.8", "@babel/types": "^7.26.8", "@types/gensync": "^1.0.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ=="], - "@babel/generator": ["@babel/generator@7.26.5", "", { "dependencies": { "@babel/parser": "^7.26.5", "@babel/types": "^7.26.5", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw=="], + "@babel/generator": ["@babel/generator@7.26.8", "", { "dependencies": { "@babel/parser": "^7.26.8", "@babel/types": "^7.26.8", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA=="], "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.25.9", "", { "dependencies": { "@babel/types": "^7.25.9" } }, "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g=="], @@ -790,7 +795,7 @@ "@babel/helpers": ["@babel/helpers@7.26.7", "", { "dependencies": { "@babel/template": "^7.25.9", "@babel/types": "^7.26.7" } }, "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A=="], - "@babel/parser": ["@babel/parser@7.26.7", "", { "dependencies": { "@babel/types": "^7.26.7" }, "bin": "./bin/babel-parser.js" }, "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w=="], + "@babel/parser": ["@babel/parser@7.26.8", "", { "dependencies": { "@babel/types": "^7.26.8" }, "bin": "./bin/babel-parser.js" }, "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw=="], "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g=="], @@ -822,7 +827,7 @@ "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg=="], - "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-remap-async-to-generator": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw=="], + "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.26.8", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-remap-async-to-generator": "^7.25.9", "@babel/traverse": "^7.26.8" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg=="], "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.25.9", "", { "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-remap-async-to-generator": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ=="], @@ -916,7 +921,7 @@ "@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg=="], - "@babel/plugin-transform-runtime": ["@babel/plugin-transform-runtime@7.25.9", "", { "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ=="], + "@babel/plugin-transform-runtime": ["@babel/plugin-transform-runtime@7.26.8", "", { "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-plugin-utils": "^7.26.5", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-H0jlQxFMI0Q8SyGPsj9pO3ygVQRxPkIGytsL3m1Zqca8KrCPpMlvh+e2dxknqdfS8LFwBw+PpiYPD9qy/FPQpA=="], "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng=="], @@ -924,11 +929,11 @@ "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA=="], - "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw=="], + "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.26.8", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q=="], "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.26.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw=="], - "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.26.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/plugin-syntax-typescript": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5cJurntg+AT+cgelGP9Bt788DKiAw9gIMSMU2NJrLAilnj0m8WZWUNZPSLOmadYsujHutpgElO+50foX+ib/Wg=="], + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.26.8", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/plugin-syntax-typescript": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw=="], "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q=="], @@ -938,7 +943,7 @@ "@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ=="], - "@babel/preset-env": ["@babel/preset-env@7.26.7", "", { "dependencies": { "@babel/compat-data": "^7.26.5", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.26.0", "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.9", "@babel/plugin-transform-async-generator-functions": "^7.25.9", "@babel/plugin-transform-async-to-generator": "^7.25.9", "@babel/plugin-transform-block-scoped-functions": "^7.26.5", "@babel/plugin-transform-block-scoping": "^7.25.9", "@babel/plugin-transform-class-properties": "^7.25.9", "@babel/plugin-transform-class-static-block": "^7.26.0", "@babel/plugin-transform-classes": "^7.25.9", "@babel/plugin-transform-computed-properties": "^7.25.9", "@babel/plugin-transform-destructuring": "^7.25.9", "@babel/plugin-transform-dotall-regex": "^7.25.9", "@babel/plugin-transform-duplicate-keys": "^7.25.9", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-dynamic-import": "^7.25.9", "@babel/plugin-transform-exponentiation-operator": "^7.26.3", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-for-of": "^7.25.9", "@babel/plugin-transform-function-name": "^7.25.9", "@babel/plugin-transform-json-strings": "^7.25.9", "@babel/plugin-transform-literals": "^7.25.9", "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", "@babel/plugin-transform-member-expression-literals": "^7.25.9", "@babel/plugin-transform-modules-amd": "^7.25.9", "@babel/plugin-transform-modules-commonjs": "^7.26.3", "@babel/plugin-transform-modules-systemjs": "^7.25.9", "@babel/plugin-transform-modules-umd": "^7.25.9", "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-new-target": "^7.25.9", "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", "@babel/plugin-transform-numeric-separator": "^7.25.9", "@babel/plugin-transform-object-rest-spread": "^7.25.9", "@babel/plugin-transform-object-super": "^7.25.9", "@babel/plugin-transform-optional-catch-binding": "^7.25.9", "@babel/plugin-transform-optional-chaining": "^7.25.9", "@babel/plugin-transform-parameters": "^7.25.9", "@babel/plugin-transform-private-methods": "^7.25.9", "@babel/plugin-transform-private-property-in-object": "^7.25.9", "@babel/plugin-transform-property-literals": "^7.25.9", "@babel/plugin-transform-regenerator": "^7.25.9", "@babel/plugin-transform-regexp-modifiers": "^7.26.0", "@babel/plugin-transform-reserved-words": "^7.25.9", "@babel/plugin-transform-shorthand-properties": "^7.25.9", "@babel/plugin-transform-spread": "^7.25.9", "@babel/plugin-transform-sticky-regex": "^7.25.9", "@babel/plugin-transform-template-literals": "^7.25.9", "@babel/plugin-transform-typeof-symbol": "^7.26.7", "@babel/plugin-transform-unicode-escapes": "^7.25.9", "@babel/plugin-transform-unicode-property-regex": "^7.25.9", "@babel/plugin-transform-unicode-regex": "^7.25.9", "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.38.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ycg2tnXwixaXOVb29rana8HNPgLVBof8qqtNQ9LE22IoyZboQbGSxI6ZySMdW3K5nAe6gu35IaJefUJflhUFTQ=="], + "@babel/preset-env": ["@babel/preset-env@7.26.8", "", { "dependencies": { "@babel/compat-data": "^7.26.8", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.26.0", "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.9", "@babel/plugin-transform-async-generator-functions": "^7.26.8", "@babel/plugin-transform-async-to-generator": "^7.25.9", "@babel/plugin-transform-block-scoped-functions": "^7.26.5", "@babel/plugin-transform-block-scoping": "^7.25.9", "@babel/plugin-transform-class-properties": "^7.25.9", "@babel/plugin-transform-class-static-block": "^7.26.0", "@babel/plugin-transform-classes": "^7.25.9", "@babel/plugin-transform-computed-properties": "^7.25.9", "@babel/plugin-transform-destructuring": "^7.25.9", "@babel/plugin-transform-dotall-regex": "^7.25.9", "@babel/plugin-transform-duplicate-keys": "^7.25.9", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-dynamic-import": "^7.25.9", "@babel/plugin-transform-exponentiation-operator": "^7.26.3", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-for-of": "^7.25.9", "@babel/plugin-transform-function-name": "^7.25.9", "@babel/plugin-transform-json-strings": "^7.25.9", "@babel/plugin-transform-literals": "^7.25.9", "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", "@babel/plugin-transform-member-expression-literals": "^7.25.9", "@babel/plugin-transform-modules-amd": "^7.25.9", "@babel/plugin-transform-modules-commonjs": "^7.26.3", "@babel/plugin-transform-modules-systemjs": "^7.25.9", "@babel/plugin-transform-modules-umd": "^7.25.9", "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-new-target": "^7.25.9", "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", "@babel/plugin-transform-numeric-separator": "^7.25.9", "@babel/plugin-transform-object-rest-spread": "^7.25.9", "@babel/plugin-transform-object-super": "^7.25.9", "@babel/plugin-transform-optional-catch-binding": "^7.25.9", "@babel/plugin-transform-optional-chaining": "^7.25.9", "@babel/plugin-transform-parameters": "^7.25.9", "@babel/plugin-transform-private-methods": "^7.25.9", "@babel/plugin-transform-private-property-in-object": "^7.25.9", "@babel/plugin-transform-property-literals": "^7.25.9", "@babel/plugin-transform-regenerator": "^7.25.9", "@babel/plugin-transform-regexp-modifiers": "^7.26.0", "@babel/plugin-transform-reserved-words": "^7.25.9", "@babel/plugin-transform-shorthand-properties": "^7.25.9", "@babel/plugin-transform-spread": "^7.25.9", "@babel/plugin-transform-sticky-regex": "^7.25.9", "@babel/plugin-transform-template-literals": "^7.26.8", "@babel/plugin-transform-typeof-symbol": "^7.26.7", "@babel/plugin-transform-unicode-escapes": "^7.25.9", "@babel/plugin-transform-unicode-property-regex": "^7.25.9", "@babel/plugin-transform-unicode-regex": "^7.25.9", "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.40.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-um7Sy+2THd697S4zJEfv/U5MHGJzkN2xhtsR3T/SWRbVSic62nbISh51VVfU9JiO/L/Z97QczHTaFVkOU8IzNg=="], "@babel/preset-flow": ["@babel/preset-flow@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-validator-option": "^7.25.9", "@babel/plugin-transform-flow-strip-types": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-EASHsAhE+SSlEzJ4bzfusnXSHiU+JfAYzj+jbw2vgQKgq5HrUr8qs+vgtiEL5dOH6sEweI+PNt2D7AqrDSHyqQ=="], @@ -952,11 +957,11 @@ "@babel/runtime": ["@babel/runtime@7.26.7", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ=="], - "@babel/template": ["@babel/template@7.25.9", "", { "dependencies": { "@babel/code-frame": "^7.25.9", "@babel/parser": "^7.25.9", "@babel/types": "^7.25.9" } }, "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg=="], + "@babel/template": ["@babel/template@7.26.8", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/parser": "^7.26.8", "@babel/types": "^7.26.8" } }, "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q=="], - "@babel/traverse": ["@babel/traverse@7.26.7", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.26.5", "@babel/parser": "^7.26.7", "@babel/template": "^7.25.9", "@babel/types": "^7.26.7", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA=="], + "@babel/traverse": ["@babel/traverse@7.26.8", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.26.8", "@babel/parser": "^7.26.8", "@babel/template": "^7.26.8", "@babel/types": "^7.26.8", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA=="], - "@babel/types": ["@babel/types@7.26.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg=="], + "@babel/types": ["@babel/types@7.26.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA=="], "@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="], @@ -1342,17 +1347,17 @@ "@pnpm/npm-conf": ["@pnpm/npm-conf@2.3.1", "", { "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", "config-chain": "^1.1.11" } }, "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw=="], - "@portabletext/block-tools": ["@portabletext/block-tools@1.1.5", "", { "dependencies": { "get-random-values-esm": "1.0.2", "lodash": "^4.17.21" }, "peerDependencies": { "@sanity/types": "^3.74.0", "@types/react": "18 || 19" } }, "sha512-8feoCEzIKKWCahoBZn3d4MXLt8hJGUPjvj2lgVn1vzFCHM6CEb7KeM+dxEM7ViCV1TBqR5wapxpRdg3xAHWyQw=="], + "@portabletext/block-tools": ["@portabletext/block-tools@1.1.6", "", { "dependencies": { "get-random-values-esm": "1.0.2", "lodash": "^4.17.21" }, "peerDependencies": { "@sanity/types": "^3.74.1", "@types/react": "18 || 19" } }, "sha512-u+eJpY/60vzKGDxus1UDOdZ7fRR42qQcFJcJaMHo0yyeRvp2Pz2/e5AEDhO45XDd2M2FSM8eSFqSGRiGgS3NhQ=="], - "@portabletext/editor": ["@portabletext/editor@1.30.4", "", { "dependencies": { "@portabletext/block-tools": "1.1.5", "@portabletext/patches": "1.1.2", "@portabletext/to-html": "^2.0.13", "@xstate/react": "^5.0.2", "debug": "^4.4.0", "get-random-values-esm": "^1.0.2", "lodash": "^4.17.21", "lodash.startcase": "^4.4.0", "react-compiler-runtime": "19.0.0-beta-714736e-20250131", "slate": "0.112.0", "slate-dom": "^0.112.2", "slate-react": "0.112.1", "use-effect-event": "^1.0.2", "xstate": "^5.19.2" }, "peerDependencies": { "@sanity/schema": "^3.74.0", "@sanity/types": "^3.74.0", "react": "^16.9 || ^17 || ^18 || ^19", "rxjs": "^7.8.1" } }, "sha512-xArxjIi5Ii4Uy24yBVKBGmUZo9MUV8QIIrz7p+NlQXyHcdQdLHGdqyRQb3F7pjdlzWVW0dYXcpubnRsyGl7f5g=="], + "@portabletext/editor": ["@portabletext/editor@1.31.0", "", { "dependencies": { "@portabletext/block-tools": "1.1.6", "@portabletext/patches": "1.1.2", "@portabletext/to-html": "^2.0.14", "@xstate/react": "^5.0.2", "debug": "^4.4.0", "get-random-values-esm": "^1.0.2", "lodash": "^4.17.21", "lodash.startcase": "^4.4.0", "react-compiler-runtime": "19.0.0-beta-714736e-20250131", "slate": "0.112.0", "slate-dom": "^0.112.2", "slate-react": "0.112.1", "use-effect-event": "^1.0.2", "xstate": "^5.19.2" }, "peerDependencies": { "@sanity/schema": "^3.74.1", "@sanity/types": "^3.74.1", "react": "^16.9 || ^17 || ^18 || ^19", "rxjs": "^7.8.1" } }, "sha512-354MCNmqkrDAktcg4+h42IKDP2mLu/q48Vv7MvvNEQIwdSpqxkGzg8RsEw2IlkjXB4heJvpQKGi8e6Q9JdfPZg=="], "@portabletext/patches": ["@portabletext/patches@1.1.2", "", { "dependencies": { "@sanity/diff-match-patch": "^3.2.0", "lodash": "^4.17.21" } }, "sha512-ENGxLD+AJc2Uq2GfDCNmeU/9dT50VYBMX5zKYyPVw2/OYDEpLYDlEZBjh0v0RqEuE2ecUu+eBaHf4PE6C0CoQQ=="], - "@portabletext/react": ["@portabletext/react@3.2.0", "", { "dependencies": { "@portabletext/toolkit": "^2.0.16", "@portabletext/types": "^2.0.13" }, "peerDependencies": { "react": "^17 || ^18 || >=19.0.0-0" } }, "sha512-BA216Z8yhb/eP24bfb09uiT0SVnQHTVZMPXf4MRBEZ+G8cMzZM/ab3tcp8owyp91+3kTKR0qSIpzYSKdm1Pakw=="], + "@portabletext/react": ["@portabletext/react@3.2.1", "", { "dependencies": { "@portabletext/toolkit": "^2.0.17", "@portabletext/types": "^2.0.13" }, "peerDependencies": { "react": "^17 || ^18 || >=19.0.0-0" } }, "sha512-RyFLk6u2q6ZyABTdOk+xoNR2Tq/4fcQFEWayNk4Kbd3gHpUUTabqOrDMChcmG6C7YVLSpwIEBwHoBVcy4vK/hA=="], - "@portabletext/to-html": ["@portabletext/to-html@2.0.13", "", { "dependencies": { "@portabletext/toolkit": "^2.0.15", "@portabletext/types": "^2.0.13" } }, "sha512-T3zL+2RcPCPGCp7rRrGrNJnGAqkdlpiOZnb/wh4tjDYJevteGY+5hmA0/5idLXzLiPv6vT8Gld852Sc0aFXwUA=="], + "@portabletext/to-html": ["@portabletext/to-html@2.0.14", "", { "dependencies": { "@portabletext/toolkit": "^2.0.17", "@portabletext/types": "^2.0.13" } }, "sha512-wW2et59PoOT/mc56C4U3z+DKAx1yjieN/gp2q9szTfTwusMpb6mclR9+EPIfGrcQWdwGn6PEN7nxVFXnqlZ/0A=="], - "@portabletext/toolkit": ["@portabletext/toolkit@2.0.16", "", { "dependencies": { "@portabletext/types": "^2.0.13" } }, "sha512-aBvnD8MscoAlEIuZBn0Aksd+oCuoMGFOT3CtHIgRBaac0Vu4YnnMUF45xo/B/T5vmwWcnDXoJEJdn+SKDg1m+A=="], + "@portabletext/toolkit": ["@portabletext/toolkit@2.0.17", "", { "dependencies": { "@portabletext/types": "^2.0.13" } }, "sha512-5wj+oUaCmHm9Ay1cytPmT1Yc0SrR1twwUIc0qNQ3MtaXaNMPw99Gjt1NcA34yfyKmEf/TAB2NiiT72jFxdddIQ=="], "@portabletext/types": ["@portabletext/types@2.0.13", "", {}, "sha512-5xk5MSyQU9CrDho3Rsguj38jhijhD36Mk8S6mZo3huv6PM+t4M/5kJN2KFIxgvt4ONpvOEs1pVIZAV0cL0Vi+Q=="], @@ -1442,43 +1447,43 @@ "@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.34.4", "", { "os": "android", "cpu": "arm" }, "sha512-gGi5adZWvjtJU7Axs//CWaQbQd/vGy8KGcnEaCWiyCqxWYDxwIlAHFuSe6Guoxtd0SRvSfVTDMPd5H+4KE2kKA=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.34.6", "", { "os": "android", "cpu": "arm" }, "sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.34.4", "", { "os": "android", "cpu": "arm64" }, "sha512-1aRlh1gqtF7vNPMnlf1vJKk72Yshw5zknR/ZAVh7zycRAGF2XBMVDAHmFQz/Zws5k++nux3LOq/Ejj1WrDR6xg=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.34.6", "", { "os": "android", "cpu": "arm64" }, "sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.34.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-drHl+4qhFj+PV/jrQ78p9ch6A0MfNVZScl/nBps5a7u01aGf/GuBRrHnRegA9bP222CBDfjYbFdjkIJ/FurvSQ=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.34.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.34.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-hQqq/8QALU6t1+fbNmm6dwYsa0PDD4L5r3TpHx9dNl+aSEMnIksHZkSO3AVH+hBMvZhpumIGrTFj8XCOGuIXjw=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.34.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.34.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-/L0LixBmbefkec1JTeAQJP0ETzGjFtNml2gpQXA8rpLo7Md+iXQzo9kwEgzyat5Q+OG/C//2B9Fx52UxsOXbzw=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.34.6", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.34.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-6Rk3PLRK+b8L/M6m/x6Mfj60LhAUcLJ34oPaxufA+CfqkUrDoUPQYFdRrhqyOvtOKXLJZJwxlOLbQjNYQcRQfw=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.34.6", "", { "os": "freebsd", "cpu": "x64" }, "sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.34.4", "", { "os": "linux", "cpu": "arm" }, "sha512-kmT3x0IPRuXY/tNoABp2nDvI9EvdiS2JZsd4I9yOcLCCViKsP0gB38mVHOhluzx+SSVnM1KNn9k6osyXZhLoCA=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.34.6", "", { "os": "linux", "cpu": "arm" }, "sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.34.4", "", { "os": "linux", "cpu": "arm" }, "sha512-3iSA9tx+4PZcJH/Wnwsvx/BY4qHpit/u2YoZoXugWVfc36/4mRkgGEoRbRV7nzNBSCOgbWMeuQ27IQWgJ7tRzw=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.34.6", "", { "os": "linux", "cpu": "arm" }, "sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.34.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-7CwSJW+sEhM9sESEk+pEREF2JL0BmyCro8UyTq0Kyh0nu1v0QPNY3yfLPFKChzVoUmaKj8zbdgBxUhBRR+xGxg=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.34.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.34.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-GZdafB41/4s12j8Ss2izofjeFXRAAM7sHCb+S4JsI9vaONX/zQ8cXd87B9MRU/igGAJkKvmFmJJBeeT9jJ5Cbw=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.34.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q=="], - "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.34.4", "", { "os": "linux", "cpu": "none" }, "sha512-uuphLuw1X6ur11675c2twC6YxbzyLSpWggvdawTUamlsoUv81aAXRMPBC1uvQllnBGls0Qt5Siw8reSIBnbdqQ=="], + "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.34.6", "", { "os": "linux", "cpu": "none" }, "sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw=="], - "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.34.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-KvLEw1os2gSmD6k6QPCQMm2T9P2GYvsMZMRpMz78QpSoEevHbV/KOUbI/46/JRalhtSAYZBYLAnT9YE4i/l4vg=="], + "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.34.6", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.34.4", "", { "os": "linux", "cpu": "none" }, "sha512-wcpCLHGM9yv+3Dql/CI4zrY2mpQ4WFergD3c9cpRowltEh5I84pRT/EuHZsG0In4eBPPYthXnuR++HrFkeqwkA=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.34.6", "", { "os": "linux", "cpu": "none" }, "sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.34.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-nLbfQp2lbJYU8obhRQusXKbuiqm4jSJteLwfjnunDT5ugBKdxqw1X9KWwk8xp1OMC6P5d0WbzxzhWoznuVK6XA=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.34.6", "", { "os": "linux", "cpu": "s390x" }, "sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.34.4", "", { "os": "linux", "cpu": "x64" }, "sha512-JGejzEfVzqc/XNiCKZj14eb6s5w8DdWlnQ5tWUbs99kkdvfq9btxxVX97AaxiUX7xJTKFA0LwoS0KU8C2faZRg=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.34.6", "", { "os": "linux", "cpu": "x64" }, "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.34.4", "", { "os": "linux", "cpu": "x64" }, "sha512-/iFIbhzeyZZy49ozAWJ1ZR2KW6ZdYUbQXLT4O5n1cRZRoTpwExnHLjlurDXXPKEGxiAg0ujaR9JDYKljpr2fDg=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.34.6", "", { "os": "linux", "cpu": "x64" }, "sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.34.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-qORc3UzoD5UUTneiP2Afg5n5Ti1GAW9Gp5vHPxzvAFFA3FBaum9WqGvYXGf+c7beFdOKNos31/41PRMUwh1tpA=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.34.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.34.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-5g7E2PHNK2uvoD5bASBD9aelm44nf1w4I5FEI7MPHLWcCSrR8JragXZWgKPXk5i2FU3JFfa6CGZLw2RrGBHs2Q=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.34.6", "", { "os": "win32", "cpu": "ia32" }, "sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.34.4", "", { "os": "win32", "cpu": "x64" }, "sha512-p0scwGkR4kZ242xLPBuhSckrJ734frz6v9xZzD+kHVYRAkSUmdSLCIJRfql6H5//aF8Q10K+i7q8DiPfZp0b7A=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.34.6", "", { "os": "win32", "cpu": "x64" }, "sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w=="], "@rushstack/node-core-library": ["@rushstack/node-core-library@5.10.1", "", { "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", "ajv-formats": "~3.0.1", "fs-extra": "~7.0.1", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", "semver": "~7.5.4" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg=="], @@ -1522,7 +1527,7 @@ "@sanity/incompatible-plugin": ["@sanity/incompatible-plugin@1.0.5", "", { "peerDependencies": { "react": "^16.9 || ^17 || ^18 || ^19", "react-dom": "^16.9 || ^17 || ^18 || ^19" } }, "sha512-9JGAacbElUPy9Chghd+sllIiM3jAcraZdD65bWYWUVKkghOsf1L/+jFLz1rcAuvrA9o2s7Y+T75BNcXuLwRcvw=="], - "@sanity/insert-menu": ["@sanity/insert-menu@1.0.20", "", { "dependencies": { "@sanity/icons": "^3.5.7", "@sanity/ui": "^2.11.4", "lodash": "^4.17.21" }, "peerDependencies": { "@sanity/types": "*", "react": "^18.3 || >=19.0.0-rc", "react-dom": "^18.3 || >=19.0.0-rc", "react-is": "^18.3 || >=19.0.0-rc" } }, "sha512-oYhGCerabMOJBU47ukjY5Hq6g87yHlN8Xr/HaqNLGG7ustGaT6cWA4UMaDuWd980qbWeC3s9Ph6cKRT/Sy8JtA=="], + "@sanity/insert-menu": ["@sanity/insert-menu@1.1.0", "", { "dependencies": { "@sanity/icons": "^3.5.7", "@sanity/ui": "^2.12.1", "lodash": "^4.17.21", "react-compiler-runtime": "19.0.0-beta-714736e-20250131" }, "peerDependencies": { "@sanity/types": "*", "react": "^18.3 || >=19.0.0-rc", "react-dom": "^18.3 || >=19.0.0-rc", "react-is": "^18.3 || >=19.0.0-rc" } }, "sha512-RMzR7Gy2dbR6GAa24iddioJbpaZpiOjMY1HZ/TzgUTI+zrBtt2Pt1bjgx9lP+n72nypW67KLxKT1/wzXyIBbtA=="], "@sanity/logos": ["@sanity/logos@2.1.13", "", { "peerDependencies": { "@sanity/color": "^2.0 || ^3.0 || ^3.0.0-beta", "react": "^18.3 || >=19.0.0-rc" } }, "sha512-PKAbPbM4zn+6wHYjCVwuhmlZnFqyZ9lT/O7OT3BVd2SGAqXoZTimfBOHrVPifytuazdoQ1T2M5eYJTtW/VXLyA=="], @@ -1532,13 +1537,13 @@ "@sanity/mutator": ["@sanity/mutator@3.74.1", "", { "dependencies": { "@sanity/diff-match-patch": "^3.1.1", "@sanity/types": "3.74.1", "@sanity/uuid": "^3.0.1", "debug": "^4.3.4", "lodash": "^4.17.21" } }, "sha512-Bvy5dRCoemV4K3TQKWqSfoC+P6vbd26dmktiqiS/IFtj83HQp0bh5LBAPUt/ZUTdfSV1bpeTfuzQELTvpXkTwA=="], - "@sanity/next-loader": ["@sanity/next-loader@1.2.22", "", { "dependencies": { "@sanity/client": "^6.27.2", "@sanity/comlink": "^3.0.1", "@sanity/presentation-comlink": "^1.0.4", "use-effect-event": "^1.0.2" }, "peerDependencies": { "next": "^14.1 || ^15.0.0-0", "react": "^18.3 || ^19.0.0-0" } }, "sha512-ravBnqrzaYYguFKCiIWubk/iiV2TtoEvMIqMLs8ows0hoaHsgKTVhvfq5Rzqy/tXNRKdsBBcxI8rg796hNF/QA=="], + "@sanity/next-loader": ["@sanity/next-loader@1.2.23", "", { "dependencies": { "@sanity/client": "^6.27.2", "@sanity/comlink": "^3.0.1", "@sanity/presentation-comlink": "^1.0.5", "use-effect-event": "^1.0.2" }, "peerDependencies": { "next": "^14.1 || ^15.0.0-0", "react": "^18.3 || ^19.0.0-0" } }, "sha512-L397cRNGvY7GAjvsMOyM3luKHAksjZ0uzgcfn4uUf+uZMkuoxSM4vDsWLSolFJUALxGuJKHhco2u0XnuuER3XA=="], "@sanity/pkg-utils": ["@sanity/pkg-utils@6.13.4", "", { "dependencies": { "@babel/core": "^7.26.0", "@babel/preset-typescript": "^7.26.0", "@babel/types": "^7.26.3", "@microsoft/api-extractor": "7.48.1", "@microsoft/tsdoc-config": "0.17.1", "@optimize-lodash/rollup-plugin": "5.0.0", "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.2", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.0", "@rollup/plugin-replace": "^6.0.2", "@rollup/plugin-terser": "^0.4.4", "@sanity/browserslist-config": "^1.0.5", "browserslist": "^4.24.4", "cac": "^6.7.14", "chalk": "^4.1.2", "chokidar": "^4.0.3", "esbuild": "^0.24.2", "esbuild-register": "^3.6.0", "find-config": "^1.0.0", "get-latest-version": "^5.1.0", "git-url-parse": "^16.0.0", "globby": "^11.1.0", "jsonc-parser": "^3.3.1", "mkdirp": "^3.0.1", "outdent": "^0.8.0", "parse-git-config": "^3.0.0", "pkg-up": "^3.1.0", "prettier": "^3.4.2", "pretty-bytes": "^5.6.0", "prompts": "^2.4.2", "recast": "0.23.9", "rimraf": "^4.4.1", "rollup": "^4.30.1", "rollup-plugin-esbuild": "^6.1.1", "rxjs": "^7.8.1", "treeify": "^1.1.0", "uuid": "^11.0.4", "zod": "3.24.1", "zod-validation-error": "3.4.0" }, "peerDependencies": { "babel-plugin-react-compiler": "*", "typescript": "5.4.x || 5.5.x || 5.6.x || 5.7.x" }, "optionalPeers": ["babel-plugin-react-compiler"], "bin": { "pkg": "bin/pkg-utils.cjs", "pkg-utils": "bin/pkg-utils.cjs" } }, "sha512-m4x0qyu2wiUHKuVxy/B2kcQRh20RvsyvUlUjPbiM5ENt4hwpJPLFfxtPe53GOCf3NJfcSK/te4yQkMOyL8RzAA=="], - "@sanity/presentation-comlink": ["@sanity/presentation-comlink@1.0.4", "", { "dependencies": { "@sanity/comlink": "^3.0.1", "@sanity/visual-editing-types": "^1.0.4" }, "peerDependencies": { "@sanity/client": "^6.27.2" } }, "sha512-TqXTjVPM8vRFXpATZ5eRPv9vGp3XsStGcW1SB3csXekNTEJSdP/VgWqtaMTsrtE4tYYcYPe1kB2DsbnE5k0Sxg=="], + "@sanity/presentation-comlink": ["@sanity/presentation-comlink@1.0.5", "", { "dependencies": { "@sanity/comlink": "^3.0.1", "@sanity/visual-editing-types": "^1.0.5" }, "peerDependencies": { "@sanity/client": "^6.27.2" } }, "sha512-R3SN7rckwhnpWAIbm0KzTKQD3F1Dss/BXlchK0MHEmVRWKIylnfHBzSEuOAq910HrZnRGkeUvwjtxHT2gASDYw=="], - "@sanity/preview-kit": ["@sanity/preview-kit@5.2.2", "", { "dependencies": { "@sanity/comlink": "^3.0.1", "@sanity/presentation-comlink": "^1.0.4", "mendoza": "3.0.8" }, "peerDependencies": { "@sanity/client": "^6.27.2", "react": "^18.0.0 || >=19.0.0-rc" }, "optionalPeers": ["react"] }, "sha512-DwOuApteYFhviUiB6EM37bXRwPLzLENITCu0PkW2aoH9w+wONX9X4uXlxfifAHjiGqRYPnD91GfnTPmMF0mOJQ=="], + "@sanity/preview-kit": ["@sanity/preview-kit@5.2.3", "", { "dependencies": { "@sanity/comlink": "^3.0.1", "@sanity/presentation-comlink": "^1.0.5", "mendoza": "3.0.8" }, "peerDependencies": { "@sanity/client": "^6.27.2", "react": "^18.0.0 || >=19.0.0-rc" }, "optionalPeers": ["react"] }, "sha512-4jxTgukV0t7wDSgYd3jenTxP0C2HU6rxltcnOqJ0G8WJykdHYUQBv1K/iObY9eBOszmF81TsrMDo96Yfeqd7YQ=="], "@sanity/preview-url-secret": ["@sanity/preview-url-secret@2.1.4", "", { "dependencies": { "@sanity/uuid": "3.0.2" }, "peerDependencies": { "@sanity/client": "^6.27.2" } }, "sha512-D66VcYbGGXIkF4VQrvWo61l921LdyHKZgg5PYH0ZHcAE/wTXrMIM93I70jOp1DpN913c0vJ1sLxbLCbrEk7n8Q=="], @@ -1552,7 +1557,7 @@ "@sanity/types": ["@sanity/types@3.74.1", "", { "dependencies": { "@sanity/client": "^6.27.2" }, "peerDependencies": { "@types/react": "18 || 19" } }, "sha512-VjV2ZrGXJFYAReoYZ/ea/lMATSqM6utfkYn7mxRm+S6b7lBRaTwQ5uvG2dlbUNjaKGJ2YmrWLh9872hIB94AKw=="], - "@sanity/ui": ["@sanity/ui@2.11.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.1.2", "@sanity/color": "^3.0.6", "@sanity/icons": "^3.5.7", "csstype": "^3.1.3", "framer-motion": "^12.0.6", "react-compiler-runtime": "19.0.0-beta-714736e-20250131", "react-refractor": "^2.2.0", "use-effect-event": "^1.0.2" }, "peerDependencies": { "react": "^18 || >=19.0.0-0", "react-dom": "^18 || >=19.0.0-0", "react-is": "^18 || >=19.0.0-0", "styled-components": "^5.2 || ^6" } }, "sha512-zi+tDVtt/DFGgIN7jEpzzzmUAHCmJdJ0kExZD8/FnMfHEcorSQg0wYawisrrxCNuJ8HM8we8HSF8qFR66AH6oA=="], + "@sanity/ui": ["@sanity/ui@2.12.2", "", { "dependencies": { "@floating-ui/react-dom": "^2.1.2", "@juggle/resize-observer": "^3.4.0", "@sanity/color": "^3.0.6", "@sanity/icons": "^3.5.7", "csstype": "^3.1.3", "framer-motion": "^12.4.1", "react-compiler-runtime": "19.0.0-beta-714736e-20250131", "react-refractor": "^2.2.0", "use-effect-event": "^1.0.2" }, "peerDependencies": { "react": "^18 || >=19.0.0-0", "react-dom": "^18 || >=19.0.0-0", "react-is": "^18 || >=19.0.0-0", "styled-components": "^5.2 || ^6" } }, "sha512-HzuZ54nmC7mSdyOUtiu3T31vzVouiQd7780aS6M/SaGGPptYxJ2gwxlrlU6KEaOM+VkjLt6Dk3ewDA7T4sNcbg=="], "@sanity/util": ["@sanity/util@3.74.1", "", { "dependencies": { "@sanity/client": "^6.27.2", "@sanity/types": "3.74.1", "get-random-values-esm": "1.0.2", "moment": "^2.30.1", "rxjs": "^7.8.1" } }, "sha512-wwRR0r3dB1+O4DFHZfsFD698wqnIcTFLpbUD/oerVvD/Q3pL/ntveomcZFQ8sZancsBg/z4+41D/6mt7x0BQNg=="], @@ -1560,11 +1565,11 @@ "@sanity/vision": ["@sanity/vision@3.74.1", "", { "dependencies": { "@codemirror/autocomplete": "^6.1.0", "@codemirror/commands": "^6.0.1", "@codemirror/lang-javascript": "^6.0.2", "@codemirror/language": "^6.2.1", "@codemirror/search": "^6.0.1", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.1.1", "@juggle/resize-observer": "^3.3.1", "@lezer/highlight": "^1.0.0", "@rexxars/react-json-inspector": "^9.0.1", "@rexxars/react-split-pane": "^1.0.0", "@sanity/color": "^3.0.0", "@sanity/icons": "^3.5.7", "@sanity/ui": "^2.11.8", "@uiw/react-codemirror": "^4.11.4", "is-hotkey-esm": "^1.0.0", "json-2-csv": "^5.5.1", "json5": "^2.2.3", "lodash": "^4.17.21", "quick-lru": "^5.1.1", "react-compiler-runtime": "19.0.0-beta-714736e-20250131", "react-fast-compare": "^3.2.2" }, "peerDependencies": { "react": "^18 || ^19.0.0", "styled-components": "^6.1" } }, "sha512-r8L43x2loBGuNXIY853AlN5Ol7vMDdGuj9NtUrrJWkd8B2vSjZf1dZVROJ5nBQZNx53qxGmeQfs71sjobROasQ=="], - "@sanity/visual-editing": ["@sanity/visual-editing@2.12.14", "", { "dependencies": { "@sanity/comlink": "^3.0.1", "@sanity/mutate": "0.11.0-canary.4", "@sanity/presentation-comlink": "^1.0.4", "@sanity/preview-url-secret": "^2.1.4", "@sanity/visual-editing-csm": "^2.0.2", "@vercel/stega": "0.1.2", "get-random-values-esm": "^1.0.2", "rxjs": "^7.8.1", "scroll-into-view-if-needed": "^3.1.0", "use-effect-event": "^1.0.2", "valibot": "0.31.1", "xstate": "^5.19.2" }, "peerDependencies": { "@remix-run/react": ">= 2", "@sanity/client": "^6.27.2", "@sveltejs/kit": ">= 2", "next": ">= 13 || >=14.3.0-canary.0 <14.3.0 || >=15.0.0-rc", "react": "^18.3 || >=19.0.0-rc", "react-dom": "^18.3 || >=19.0.0-rc", "react-router": ">= 6 || >= 7", "svelte": ">= 4" }, "optionalPeers": ["@remix-run/react", "@sanity/client", "@sveltejs/kit", "next", "react-router", "svelte"] }, "sha512-4vXd9huhhD1o0TZbTy3vM4z0/owR5x25gU65OLZc065cBzV1OFm7PXZrBVUtfa8ryEVRE++XmBMbeO2NQCG9Mg=="], + "@sanity/visual-editing": ["@sanity/visual-editing@2.13.0", "", { "dependencies": { "@sanity/comlink": "^3.0.1", "@sanity/icons": "^3.5.7", "@sanity/insert-menu": "^1.1.0", "@sanity/mutate": "0.11.0-canary.4", "@sanity/presentation-comlink": "^1.0.5", "@sanity/preview-url-secret": "^2.1.4", "@sanity/ui": "^2.12.1", "@sanity/visual-editing-csm": "^2.0.3", "@vercel/stega": "0.1.2", "get-random-values-esm": "^1.0.2", "rxjs": "^7.8.1", "scroll-into-view-if-needed": "^3.1.0", "styled-components": "^6.1.15", "use-effect-event": "^1.0.2", "valibot": "0.31.1", "xstate": "^5.19.2" }, "peerDependencies": { "@remix-run/react": ">= 2", "@sanity/client": "^6.27.2", "@sveltejs/kit": ">= 2", "next": ">= 13 || >=14.3.0-canary.0 <14.3.0 || >=15.0.0-rc", "react": "^18.3 || >=19.0.0-rc", "react-dom": "^18.3 || >=19.0.0-rc", "react-is": "^18.3 || >=19.0.0-rc", "react-router": ">= 6 || >= 7", "svelte": ">= 4" }, "optionalPeers": ["@remix-run/react", "@sanity/client", "@sveltejs/kit", "next", "react-router", "svelte"] }, "sha512-hEWBH93A9k1il0+cTryGFrvIRUPpypXQZ4P0kn7cn7wxS/QJg9xkzrOPuhnJPsdatDN8mrLifTfW0cFwwuUQ1g=="], - "@sanity/visual-editing-csm": ["@sanity/visual-editing-csm@2.0.2", "", { "dependencies": { "@sanity/visual-editing-types": "^1.0.4", "valibot": "0.31.1" }, "peerDependencies": { "@sanity/client": "^6.27.2" } }, "sha512-Trk9cosL/mwx9wMPIMcPulf66Yodil0Z+KVM9h4NfI9lj5LbIzp5jejOnZqLr1HASQik0JG7k8azJJR8fdSiqg=="], + "@sanity/visual-editing-csm": ["@sanity/visual-editing-csm@2.0.3", "", { "dependencies": { "@sanity/visual-editing-types": "^1.0.5", "valibot": "0.31.1" }, "peerDependencies": { "@sanity/client": "^6.27.2" } }, "sha512-tfR6CCBoR6r4FoVBg01nyNXY5pTeOk8kaKEG2BrkaEVdYfIHI6ugf9rRxduS9jEVpLwRX5Ojik2Gfn+JGsSjQA=="], - "@sanity/visual-editing-types": ["@sanity/visual-editing-types@1.0.4", "", { "peerDependencies": { "@sanity/client": "^6.27.2", "@sanity/types": "*" }, "optionalPeers": ["@sanity/types"] }, "sha512-zg4fObu+okPBD4/xAYF1IQjvtDTmRzS2eRFYvqG+TGHGygNIZjIx0obZAMioXvUoTZqy3eZzyzyadbsYM/w0RA=="], + "@sanity/visual-editing-types": ["@sanity/visual-editing-types@1.0.5", "", { "peerDependencies": { "@sanity/client": "^6.27.2", "@sanity/types": "*" }, "optionalPeers": ["@sanity/types"] }, "sha512-iRTgMU53P6vv2tGAi/mrGSfZIlMnQ9S2UQB8v2qC/YDxETNpRec3+00mW/pc3IlrPjE7dIOjI6dWHgLG3cSLFg=="], "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], @@ -1672,11 +1677,11 @@ "@shikijs/langs": ["@shikijs/langs@1.29.2", "", { "dependencies": { "@shikijs/types": "1.29.2" } }, "sha512-FIBA7N3LZ+223U7cJDUYd5shmciFQlYkFXlkKVaHsCPgfVLiO+e12FmQE6Tf9vuyEsFe3dIl8qGWKXgEHL9wmQ=="], - "@shikijs/rehype": ["@shikijs/rehype@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1", "@types/hast": "^3.0.4", "hast-util-to-string": "^3.0.1", "shiki": "2.3.1", "unified": "^11.0.5", "unist-util-visit": "^5.0.0" } }, "sha512-PDNWMjbcvrkt8mSHB6xBL5fqFKDTWgo2A4t3yy+xyA1eWmpGQa4xWTH0i7VKNg0acLRc+qvUesZv2GV681ADKw=="], + "@shikijs/rehype": ["@shikijs/rehype@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2", "@types/hast": "^3.0.4", "hast-util-to-string": "^3.0.1", "shiki": "2.3.2", "unified": "^11.0.5", "unist-util-visit": "^5.0.0" } }, "sha512-ikzqbG46CXQLo+Ew86Fc7wOSoBRgoRKT+520e4hwI6gsJsJHSc/pTgzBZhs1xTw+pq6iGMhNunBVdDzxfhagYw=="], "@shikijs/themes": ["@shikijs/themes@1.29.2", "", { "dependencies": { "@shikijs/types": "1.29.2" } }, "sha512-i9TNZlsq4uoyqSbluIcZkmPL9Bfi3djVxRnofUHwvx/h6SRW3cwgBC5SML7vsDcWyukY0eCzVN980rqP6qNl9g=="], - "@shikijs/transformers": ["@shikijs/transformers@2.3.1", "", { "dependencies": { "@shikijs/core": "2.3.1", "@shikijs/types": "2.3.1" } }, "sha512-f+ylRE6IFBpy0uovip1HpIlq2vqfZCkurtwYvwk0OEIPKbRR1e90n9QQdFcNgWIGBkmmPlz/FFx60nIHJTjanA=="], + "@shikijs/transformers": ["@shikijs/transformers@2.3.2", "", { "dependencies": { "@shikijs/core": "2.3.2", "@shikijs/types": "2.3.2" } }, "sha512-2HDnJumw8A/9GecRpTgvfqSbPjEbJ4DPWq5J++OVP1gNMLvbV0MqFsP4canqRNM1LqB7VmWY45Stipb0ZIJ+0A=="], "@shikijs/types": ["@shikijs/types@1.29.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw=="], @@ -1708,6 +1713,8 @@ "@stackflow/react-ui-core": ["@stackflow/react-ui-core@1.2.1", "", { "peerDependencies": { "@stackflow/core": "^1.1.0-canary.0", "@stackflow/react": "^1.3.2-canary.0", "@types/react": ">=16.8.0", "react": ">=16.8.0" } }, "sha512-7usdZGAf0fQArBx9OXP8ZVZX4GERnHhSg4Pyq4w7F0EW247K1/yNenOpdkHixORX85iZFp/oRQAHHsg46oqY4w=="], + "@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="], + "@storybook/addon-actions": ["@storybook/addon-actions@8.5.3", "", { "dependencies": { "@storybook/global": "^5.0.0", "@types/uuid": "^9.0.1", "dequal": "^2.0.2", "polished": "^4.2.2", "uuid": "^9.0.0" }, "peerDependencies": { "storybook": "^8.5.3" } }, "sha512-7a+SD4EZdZocm+NG1Kx4yV6Aw7+YUlRIyGvKcxsGtYMOLaqrUewApqveXF83+FbYWMoezXcoZCLQFROtS/Z6Fw=="], "@storybook/addon-backgrounds": ["@storybook/addon-backgrounds@8.5.3", "", { "dependencies": { "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3", "ts-dedent": "^2.0.0" }, "peerDependencies": { "storybook": "^8.5.3" } }, "sha512-sZcw8/C/HIIgbRBY+0ZYTBc5Py8xvw3bt6lzSVQEXA2aygfJpO/jiQJlmOXTmK3g5F5pjFKaaCodfXT7V/9mzw=="], @@ -1770,27 +1777,27 @@ "@storybook/theming": ["@storybook/theming@8.5.3", "", { "peerDependencies": { "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" } }, "sha512-Jvzw+gT1HNarkJo21WZBq5pU89qDN8u/pD3woSh/1c2h5RS6UylWjQHotPFpcBIQiUSrDFtvCU9xugJm4MD0+w=="], - "@swc/core": ["@swc/core@1.10.14", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.17" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.10.14", "@swc/core-darwin-x64": "1.10.14", "@swc/core-linux-arm-gnueabihf": "1.10.14", "@swc/core-linux-arm64-gnu": "1.10.14", "@swc/core-linux-arm64-musl": "1.10.14", "@swc/core-linux-x64-gnu": "1.10.14", "@swc/core-linux-x64-musl": "1.10.14", "@swc/core-win32-arm64-msvc": "1.10.14", "@swc/core-win32-ia32-msvc": "1.10.14", "@swc/core-win32-x64-msvc": "1.10.14" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-WSrnE6JRnH20ZYjOOgSS4aOaPv9gxlkI2KRkN24kagbZnPZMnN8bZZyzw1rrLvwgpuRGv17Uz+hflosbR+SP6w=="], + "@swc/core": ["@swc/core@1.10.15", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.17" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.10.15", "@swc/core-darwin-x64": "1.10.15", "@swc/core-linux-arm-gnueabihf": "1.10.15", "@swc/core-linux-arm64-gnu": "1.10.15", "@swc/core-linux-arm64-musl": "1.10.15", "@swc/core-linux-x64-gnu": "1.10.15", "@swc/core-linux-x64-musl": "1.10.15", "@swc/core-win32-arm64-msvc": "1.10.15", "@swc/core-win32-ia32-msvc": "1.10.15", "@swc/core-win32-x64-msvc": "1.10.15" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-/iFeQuNaGdK7mfJbQcObhAhsMqLT7qgMYl7jX2GEIO+VDTejESpzAyKwaMeYXExN8D6e5BRHBCe7M5YlsuzjDA=="], - "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.10.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Dh4VyrhDDb05tdRmqJ/MucOPMTnrB4pRJol18HVyLlqu1HOT5EzonUniNTCdQbUXjgdv5UVJSTE1lYTzrp+myA=="], + "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.10.15", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zFdZ6/yHqMCPk7OhLFqHy/MQ1EqJhcZMpNHd1gXYT7VRU3FaqvvKETrUlG3VYl65McPC7AhMRfXPyJ0JO/jARQ=="], - "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.10.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-KpzotL/I0O12RE3tF8NmQErINv0cQe/0mnN/Q50ESFzB5kU6bLgp2HMnnwDTm/XEZZRJCNe0oc9WJ5rKbAJFRQ=="], + "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.10.15", "", { "os": "darwin", "cpu": "x64" }, "sha512-8g4yiQwbr8fxOOjKXdot0dEkE5zgE8uNZudLy/ZyAhiwiZ8pbJ8/wVrDOu6dqbX7FBXAoDnvZ7fwN1jk4C8jdA=="], - "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.10.14", "", { "os": "linux", "cpu": "arm" }, "sha512-20yRXZjMJVz1wp1TcscKiGTVXistG+saIaxOmxSNQia1Qun3hSWLL+u6+5kXbfYGr7R2N6kqSwtZbIfJI25r9Q=="], + "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.10.15", "", { "os": "linux", "cpu": "arm" }, "sha512-rl+eVOltl2+7WXOnvmWBpMgh6aO13G5x0U0g8hjwlmD6ku3Y9iRcThpOhm7IytMEarUp5pQxItNoPq+VUGjVHg=="], - "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.10.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-Gy7cGrNkiMfPxQyLGxdgXPwyWzNzbHuWycJFcoKBihxZKZIW8hkPBttkGivuLC+0qOgsV2/U+S7tlvAju7FtmQ=="], + "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.10.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-qxWEQeyAJMWJqjaN4hi58WMpPdt3Tn0biSK9CYRegQtvZWCbewr6v2agtSu5AZ2rudeH6OfCWAMDQQeSgn6PJQ=="], - "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.10.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-+oYVqJvFw62InZ8PIy1rBACJPC2WTe4vbVb9kM1jJj2D7dKLm9acnnYIVIDsM5Wo7Uab8RvPHXVbs19IBurzuw=="], + "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.10.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-QcELd9/+HjZx0WCxRrKcyKGWTiQ0485kFb5w8waxcSNd0d9Lgk4EFfWWVyvIb5gIHpDQmhrgzI/yRaWQX4YSZQ=="], - "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.10.14", "", { "os": "linux", "cpu": "x64" }, "sha512-OmEbVEKQFLQVHwo4EJl9osmlulURy46k232Opfpn/1ji0t2KcNCci3POsnfMuoZjLkGJv8vGNJdPQxX+CP+wSA=="], + "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.10.15", "", { "os": "linux", "cpu": "x64" }, "sha512-S1+ZEEn3+a/MiMeQqQypbwTGoBG8/sPoCvpNbk+uValyygT+jSn3U0xVr45FbukpmMB+NhBMqfedMLqKA0QnJA=="], - "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.10.14", "", { "os": "linux", "cpu": "x64" }, "sha512-OZW+Icm8DMPqHbhdxplkuG8qrNnPk5i7xJOZWYi1y5bTjgGFI4nEzrsmmeHKMdQTaWwsFrm3uK1rlyQ48MmXmg=="], + "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.10.15", "", { "os": "linux", "cpu": "x64" }, "sha512-qW+H9g/2zTJ4jP7NDw4VAALY0ZlNEKzYsEoSj/HKi7k3tYEHjMzsxjfsY9I8WZCft23bBdV3RTCPoxCshaj1CQ=="], - "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.10.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-sTvc+xrDQXy3HXZFtTEClY35Efvuc3D+busYm0+rb1+Thau4HLRY9WP+sOKeGwH9/16rzfzYEqD7Ds8A9ykrHw=="], + "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.10.15", "", { "os": "win32", "cpu": "arm64" }, "sha512-AhRB11aA6LxjIqut+mg7qsu/7soQDmbK6MKR9nP3hgBszpqtXbRba58lr24xIbBCMr+dpo6kgEapWt+t5Po6Zg=="], - "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.10.14", "", { "os": "win32", "cpu": "ia32" }, "sha512-j2iQ4y9GWTKtES5eMU0sDsFdYni7IxME7ejFej25Tv3Fq4B+U9tgtYWlJwh1858nIWDXelHiKcSh/UICAyVMdQ=="], + "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.10.15", "", { "os": "win32", "cpu": "ia32" }, "sha512-UGdh430TQwbDn6KjgvRTg1fO022sbQ4yCCHUev0+5B8uoBwi9a89qAz3emy2m56C8TXxUoihW9Y9OMfaRwPXUw=="], - "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.10.14", "", { "os": "win32", "cpu": "x64" }, "sha512-TYtWkUSMkjs0jGPeWdtWbex4B+DlQZmN/ySVLiPI+EltYCLEXsFMkVFq6aWn48dqFHggFK0UYfvDrJUR2c3Qxg=="], + "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.10.15", "", { "os": "win32", "cpu": "x64" }, "sha512-XJzBCqO1m929qbJsOG7FZXQWX26TnEoMctS3QjuCoyBmkHxxQmZsy78KjMes1aomTcKHCyFYgrRGWgVmk7tT4Q=="], "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], @@ -1800,11 +1807,11 @@ "@tanstack/react-table": ["@tanstack/react-table@8.20.6", "", { "dependencies": { "@tanstack/table-core": "8.20.5" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-w0jluT718MrOKthRcr2xsjqzx+oEM7B7s/XXyfs19ll++hlId3fjTm+B2zrR3ijpANpkzBAr15j1XGVOMxpggQ=="], - "@tanstack/react-virtual": ["@tanstack/react-virtual@3.12.0", "", { "dependencies": { "@tanstack/virtual-core": "3.12.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-6krceiPN07kpxXmU6m8AY7EL0X1gHLu8m3nJdh4phvktzVNxkQfBmSwnRUpoUjGQO1PAn8wSAhYaL8hY1cS1vw=="], + "@tanstack/react-virtual": ["@tanstack/react-virtual@3.13.0", "", { "dependencies": { "@tanstack/virtual-core": "3.13.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-CchF0NlLIowiM2GxtsoKBkXA4uqSnY2KvnXo+kyUFD4a4ll6+J0qzoRsUPMwXV/H26lRsxgJIr/YmjYum2oEjg=="], "@tanstack/table-core": ["@tanstack/table-core@8.20.5", "", {}, "sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg=="], - "@tanstack/virtual-core": ["@tanstack/virtual-core@3.12.0", "", {}, "sha512-7mDINtua3v/pOnn6WUmuT9dPXYSO7WidFej7JzoAfqEOcbbpt/iZ1WPqd+eg+FnrL9nUJK8radqj4iAU51Zchg=="], + "@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.0", "", {}, "sha512-NBKJP3OIdmZY3COJdWkSonr50FMVIi+aj5ZJ7hI/DTpEKg2RMfo/KvP8A3B/zOSpMgIe52B5E2yn7rryULzA6g=="], "@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=="], @@ -1858,6 +1865,8 @@ "@types/fs-extra": ["@types/fs-extra@11.0.4", "", { "dependencies": { "@types/jsonfile": "*", "@types/node": "*" } }, "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ=="], + "@types/gensync": ["@types/gensync@1.0.4", "", {}, "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA=="], + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], "@types/html-minifier-terser": ["@types/html-minifier-terser@6.1.0", "", {}, "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg=="], @@ -1924,10 +1933,6 @@ "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], - "@use-gesture/core": ["@use-gesture/core@10.3.1", "", {}, "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw=="], - - "@use-gesture/react": ["@use-gesture/react@10.3.1", "", { "dependencies": { "@use-gesture/core": "10.3.1" }, "peerDependencies": { "react": ">= 16.8.0" } }, "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g=="], - "@vanilla-extract/babel-plugin-debug-ids": ["@vanilla-extract/babel-plugin-debug-ids@1.2.0", "", { "dependencies": { "@babel/core": "^7.23.9" } }, "sha512-z5nx2QBnOhvmlmBKeRX5sPVLz437wV30u+GJL+Hzj1rGiJYVNvgIIlzUpRNjVQ0MgAgiQIqIUbqPnmMc6HmDlQ=="], "@vanilla-extract/compiler": ["@vanilla-extract/compiler@0.1.1", "", { "dependencies": { "@vanilla-extract/css": "^1.17.1", "@vanilla-extract/integration": "^8.0.0", "vite": "^5.0.0 || ^6.0.0", "vite-node": "^3.0.4" } }, "sha512-OJk31hrDZlDKP7K3Yr5y731Wrm1vf7fNyM5eXjfGyDovZLcVAFuB8tt7pXqpdCz0RnrKsMzlvJD3f6WT2MaIug=="], @@ -1950,7 +1955,7 @@ "@vitejs/plugin-react": ["@vitejs/plugin-react@4.3.4", "", { "dependencies": { "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx-self": "^7.25.9", "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug=="], - "@vitejs/plugin-react-swc": ["@vitejs/plugin-react-swc@3.7.2", "", { "dependencies": { "@swc/core": "^1.7.26" }, "peerDependencies": { "vite": "^4 || ^5 || ^6" } }, "sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew=="], + "@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/expect": ["@vitest/expect@1.6.1", "", { "dependencies": { "@vitest/spy": "1.6.1", "@vitest/utils": "1.6.1", "chai": "^4.3.10" } }, "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog=="], @@ -2016,13 +2021,13 @@ "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], - "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], + "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="], "ajv-formats": ["ajv-formats@2.1.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="], - "ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], + "ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], @@ -2090,7 +2095,7 @@ "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.12", "", { "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og=="], - "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.10.6", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.2", "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA=="], + "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.11.1", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.3", "core-js-compat": "^3.40.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ=="], "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.3", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q=="], @@ -2188,7 +2193,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.30001697", "", {}, "sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ=="], + "caniuse-lite": ["caniuse-lite@1.0.30001699", "", {}, "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w=="], "case-sensitive-paths-webpack-plugin": ["case-sensitive-paths-webpack-plugin@2.4.0", "", {}, "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw=="], @@ -2494,10 +2499,18 @@ "easy-table": ["easy-table@1.2.0", "", { "dependencies": { "ansi-regex": "^5.0.1" }, "optionalDependencies": { "wcwidth": "^1.0.1" } }, "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww=="], - "electron-to-chromium": ["electron-to-chromium@1.5.93", "", {}, "sha512-M+29jTcfNNoR9NV7la4SwUqzWAxEwnc7ThA5e1m6LRSotmpfpCpLcIfgtSCVL+MllNLgAyM/5ru86iMRemPzDQ=="], + "electron-to-chromium": ["electron-to-chromium@1.5.96", "", {}, "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w=="], "elliptic": ["elliptic@6.6.1", "", { "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", "hash.js": "^1.0.0", "hmac-drbg": "^1.0.1", "inherits": "^2.0.4", "minimalistic-assert": "^1.0.1", "minimalistic-crypto-utils": "^1.0.1" } }, "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g=="], + "embla-carousel": ["embla-carousel@8.5.2", "", {}, "sha512-xQ9oVLrun/eCG/7ru3R+I5bJ7shsD8fFwLEY7yPe27/+fDHCNj0OT5EoG5ZbFyOxOcG6yTwW8oTz/dWyFnyGpg=="], + + "embla-carousel-auto-height": ["embla-carousel-auto-height@8.5.2", "", { "peerDependencies": { "embla-carousel": "8.5.2" } }, "sha512-cWO35ThnVVr8kSS5zni/Ywf6gNSpROV8PgFTd/jfiQZ73Wd6SltugitVQ74kHfchLXMWXGQgHxmUg4Ya+r4axg=="], + + "embla-carousel-react": ["embla-carousel-react@8.5.2", "", { "dependencies": { "embla-carousel": "8.5.2", "embla-carousel-reactive-utils": "8.5.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA=="], + + "embla-carousel-reactive-utils": ["embla-carousel-reactive-utils@8.5.2", "", { "peerDependencies": { "embla-carousel": "8.5.2" } }, "sha512-QC8/hYSK/pEmqEdU1IO5O+XNc/Ptmmq7uCB44vKplgLKhB/l0+yvYx0+Cv0sF6Ena8Srld5vUErZkT+yTahtDg=="], + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="], @@ -2668,7 +2681,7 @@ "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="], - "framer-motion": ["framer-motion@12.3.1", "", { "dependencies": { "motion-dom": "^12.0.0", "motion-utils": "^12.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Br4a2YhdeEvdzMDX8ToVO+/Jbqm2Loo/8rMjizX1nejjBvRJGMfz+NW1qBo4WCHF26uIdES5MBztUlB4pIyfqQ=="], + "framer-motion": ["framer-motion@12.4.1", "", { "dependencies": { "motion-dom": "^12.0.0", "motion-utils": "^12.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-5Ijbea3topSZjadQ0hgc/TcWj2ldMZmNREM7RvAhvsThYOA1HHOA8TT1yKvMu1YXP3jWaFwoZ6Vo9Nw+DUZrzA=="], "from2": ["from2@2.3.0", "", { "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g=="], @@ -2688,7 +2701,7 @@ "fumadocs-docgen": ["fumadocs-docgen@1.3.6", "", { "dependencies": { "estree-util-value-to-estree": "^3.3.2", "fumadocs-typescript": "^3.0.3", "hast-util-to-estree": "^3.1.1", "npm-to-yarn": "^3.0.1", "oxc-transform": "^0.48.2", "unist-util-visit": "^5.0.0", "zod": "^3.24.1" } }, "sha512-W/ddPpy5JYdn7bBZTxqvqRcU2+SiHvj/v6dALWWBYMSizCkNl84zWX78NLBMVoIwxYWvj5lupK86G22teCUDeA=="], - "fumadocs-mdx": ["fumadocs-mdx@11.5.1", "", { "dependencies": { "@mdx-js/mdx": "^3.1.0", "chokidar": "^4.0.3", "cross-spawn": "^7.0.6", "esbuild": "^0.24.2", "estree-util-value-to-estree": "^3.3.2", "fast-glob": "^3.3.3", "gray-matter": "^4.0.3", "micromatch": "^4.0.8", "unist-util-visit": "^5.0.0", "zod": "^3.24.1" }, "peerDependencies": { "@fumadocs/mdx-remote": "^1.2.0", "fumadocs-core": "^14.0.0 || ^15.0.0", "next": "14.x.x || 15.x.x" }, "optionalPeers": ["@fumadocs/mdx-remote"], "bin": { "fumadocs-mdx": "bin.js" } }, "sha512-YSujA/yoM2OiYt4kPa0YXkd54T9QzGR/iM7c+2YAn+7waBvBv9+xMDHnCNMvCroFkfmj8IVtDbLwfSyLZ1RT9g=="], + "fumadocs-mdx": ["fumadocs-mdx@11.5.3", "", { "dependencies": { "@mdx-js/mdx": "^3.1.0", "@standard-schema/spec": "^1.0.0", "chokidar": "^4.0.3", "cross-spawn": "^7.0.6", "esbuild": "^0.24.2", "estree-util-value-to-estree": "^3.3.2", "fast-glob": "^3.3.3", "gray-matter": "^4.0.3", "unist-util-visit": "^5.0.0", "zod": "^3.24.1" }, "peerDependencies": { "@fumadocs/mdx-remote": "^1.2.0", "fumadocs-core": "^14.0.0 || ^15.0.0", "next": "14.x.x || 15.x.x" }, "optionalPeers": ["@fumadocs/mdx-remote"], "bin": { "fumadocs-mdx": "bin.js" } }, "sha512-aPRKPo48tfpCdzXEKcaNfMJo33WvrwiTgLTeHUJpLFV1LYnb+Wloa7wBchqyL6lA/5hm1L43HduCK8BCWdK0BA=="], "fumadocs-typescript": ["fumadocs-typescript@3.0.3", "", { "dependencies": { "fast-glob": "^3.3.3", "hast-util-to-jsx-runtime": "^2.3.2", "mdast-util-from-markdown": "^2.0.2", "mdast-util-gfm": "^3.0.0", "mdast-util-to-hast": "^13.2.0", "shiki": "^2.0.3", "ts-morph": "^25.0.0" }, "peerDependencies": { "typescript": "*" } }, "sha512-TpVem2Sy+fo5e8wJibisn1XZoRdwNyY8+MuxQWBC2k8Q4oaxA6qVVsy2paCVEa716UnXbES0sVP1HqX3HCEhBg=="], @@ -2748,7 +2761,7 @@ "globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], - "globby": ["globby@14.0.2", "", { "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", "ignore": "^5.2.4", "path-type": "^5.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.1.0" } }, "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw=="], + "globby": ["globby@14.1.0", "", { "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.3", "ignore": "^7.0.3", "path-type": "^6.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.3.0" } }, "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA=="], "globrex": ["globrex@0.1.2", "", {}, "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="], @@ -2992,7 +3005,7 @@ "json-reduce": ["json-reduce@3.0.0", "", {}, "sha512-zvnhEvwhqTOxBIcXnxvHvhqtubdwFRp+FascmCaL56BT9jdttRU8IFc+Ilh2HPJ0AtioF8mFPxmReuJKLW0Iyw=="], - "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "json-stream-stringify": ["json-stream-stringify@2.0.4", "", {}, "sha512-gIPoa6K5w6j/RnQ3fOtmvICKNJGViI83A7dnTIL+0QJ/1GKuNvCPFvbFWxt0agruF4iGgDFJvge4Gua4ZoiggQ=="], @@ -3298,7 +3311,7 @@ "next": ["next@14.2.23", "", { "dependencies": { "@next/env": "14.2.23", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "graceful-fs": "^4.2.11", "postcss": "8.4.31", "styled-jsx": "5.1.1" }, "optionalDependencies": { "@next/swc-darwin-arm64": "14.2.23", "@next/swc-darwin-x64": "14.2.23", "@next/swc-linux-arm64-gnu": "14.2.23", "@next/swc-linux-arm64-musl": "14.2.23", "@next/swc-linux-x64-gnu": "14.2.23", "@next/swc-linux-x64-musl": "14.2.23", "@next/swc-win32-arm64-msvc": "14.2.23", "@next/swc-win32-ia32-msvc": "14.2.23", "@next/swc-win32-x64-msvc": "14.2.23" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-mjN3fE6u/tynneLiEg56XnthzuYw+kD7mCujgVqioxyPqbmiotUCGJpIZGS/VaPg3ZDT1tvWxiVyRzeqJFm/kw=="], - "next-sanity": ["next-sanity@9.8.51", "", { "dependencies": { "@portabletext/react": "^3.2.0", "@sanity/client": "^6.27.2", "@sanity/next-loader": "1.2.22", "@sanity/preview-kit": "5.2.2", "@sanity/preview-url-secret": "2.1.4", "@sanity/visual-editing": "2.12.14", "groq": "^3.74.0", "history": "^5.3.0" }, "peerDependencies": { "@sanity/icons": "^3.5.7", "@sanity/types": "^3.74.0", "@sanity/ui": "^2.11.8", "next": "^14.2 || ^15.0.0-0", "react": "^18.3 || ^19.0.0-0", "sanity": "^3.74.0", "styled-components": "^6.1" } }, "sha512-4V71BUAvSfVGxWI0fKrkeOAIO8X7r1ff8kBKySOiIvLhRZI901cRkQbhHCP+wute8sfTI1sbnJ4r2s+RXzOmlg=="], + "next-sanity": ["next-sanity@9.8.54", "", { "dependencies": { "@portabletext/react": "^3.2.1", "@sanity/client": "^6.27.2", "@sanity/next-loader": "1.2.23", "@sanity/preview-kit": "5.2.3", "@sanity/preview-url-secret": "2.1.4", "@sanity/visual-editing": "2.13.0", "groq": "^3.74.1", "history": "^5.3.0" }, "peerDependencies": { "@sanity/icons": "^3.5.7", "@sanity/types": "^3.74.1", "@sanity/ui": "^2.12.2", "next": "^14.2 || ^15.0.0-0", "react": "^18.3 || ^19.0.0-0", "sanity": "^3.74.1", "styled-components": "^6.1" } }, "sha512-aMHa23ULOvPmaOyaeYx2ivbDLOmWJ029lLSLWu2bkzJJuoKpyqnYpZi0IqY9/bzNDXsHCAMTVwEGvi1kbewjpA=="], "next-themes": ["next-themes@0.4.4", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ=="], @@ -3432,7 +3445,7 @@ "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], - "path-type": ["path-type@5.0.0", "", {}, "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg=="], + "path-type": ["path-type@6.0.0", "", {}, "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ=="], "pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="], @@ -3472,7 +3485,7 @@ "polished": ["polished@4.3.1", "", { "dependencies": { "@babel/runtime": "^7.17.8" } }, "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA=="], - "possible-typed-array-names": ["possible-typed-array-names@1.0.0", "", {}, "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q=="], + "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], "postcss": ["postcss@8.5.1", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ=="], @@ -3636,7 +3649,7 @@ "react-fast-compare": ["react-fast-compare@3.2.2", "", {}, "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="], - "react-focus-lock": ["react-focus-lock@2.13.5", "", { "dependencies": { "@babel/runtime": "^7.0.0", "focus-lock": "^1.3.5", "prop-types": "^15.6.2", "react-clientside-effect": "^1.2.6", "use-callback-ref": "^1.3.2", "use-sidecar": "^1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-HjHuZFFk2+j6ZT3LDQpyqffue541HrxUG/OFchCEwis9nstgNg0rREVRAxHBcB1lHJ5Fsxtx1qya/5xFwxDb4g=="], + "react-focus-lock": ["react-focus-lock@2.13.6", "", { "dependencies": { "@babel/runtime": "^7.0.0", "focus-lock": "^1.3.6", "prop-types": "^15.6.2", "react-clientside-effect": "^1.2.7", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ehylFFWyYtBKXjAO9+3v8d0i+cnc1trGS0vlTGhzFW1vbFXVUTmR8s2tt/ZQG8x5hElg6rhENlLG1H3EZK0Llg=="], "react-hook-form": ["react-hook-form@7.54.2", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg=="], @@ -3704,7 +3717,7 @@ "regexpu-core": ["regexpu-core@6.2.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.0", "regjsgen": "^0.8.0", "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" } }, "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA=="], - "registry-auth-token": ["registry-auth-token@5.0.3", "", { "dependencies": { "@pnpm/npm-conf": "^2.1.0" } }, "sha512-1bpc9IyC+e+CNFRaWyn77tk4xGG4PPUyfakSmA6F6cvUDjrm58dfyJ3II+9yb10EDkHoy1LaPSmHaWLOH3m6HA=="], + "registry-auth-token": ["registry-auth-token@5.1.0", "", { "dependencies": { "@pnpm/npm-conf": "^2.1.0" } }, "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw=="], "registry-url": ["registry-url@5.1.0", "", { "dependencies": { "rc": "^1.2.8" } }, "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw=="], @@ -3762,7 +3775,7 @@ "ripemd160": ["ripemd160@2.0.2", "", { "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA=="], - "rollup": ["rollup@4.34.4", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.34.4", "@rollup/rollup-android-arm64": "4.34.4", "@rollup/rollup-darwin-arm64": "4.34.4", "@rollup/rollup-darwin-x64": "4.34.4", "@rollup/rollup-freebsd-arm64": "4.34.4", "@rollup/rollup-freebsd-x64": "4.34.4", "@rollup/rollup-linux-arm-gnueabihf": "4.34.4", "@rollup/rollup-linux-arm-musleabihf": "4.34.4", "@rollup/rollup-linux-arm64-gnu": "4.34.4", "@rollup/rollup-linux-arm64-musl": "4.34.4", "@rollup/rollup-linux-loongarch64-gnu": "4.34.4", "@rollup/rollup-linux-powerpc64le-gnu": "4.34.4", "@rollup/rollup-linux-riscv64-gnu": "4.34.4", "@rollup/rollup-linux-s390x-gnu": "4.34.4", "@rollup/rollup-linux-x64-gnu": "4.34.4", "@rollup/rollup-linux-x64-musl": "4.34.4", "@rollup/rollup-win32-arm64-msvc": "4.34.4", "@rollup/rollup-win32-ia32-msvc": "4.34.4", "@rollup/rollup-win32-x64-msvc": "4.34.4", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-spF66xoyD7rz3o08sHP7wogp1gZ6itSq22SGa/IZTcUDXDlOyrShwMwkVSB+BUxFRZZCUYqdb3KWDEOMVQZxuw=="], + "rollup": ["rollup@4.34.6", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.34.6", "@rollup/rollup-android-arm64": "4.34.6", "@rollup/rollup-darwin-arm64": "4.34.6", "@rollup/rollup-darwin-x64": "4.34.6", "@rollup/rollup-freebsd-arm64": "4.34.6", "@rollup/rollup-freebsd-x64": "4.34.6", "@rollup/rollup-linux-arm-gnueabihf": "4.34.6", "@rollup/rollup-linux-arm-musleabihf": "4.34.6", "@rollup/rollup-linux-arm64-gnu": "4.34.6", "@rollup/rollup-linux-arm64-musl": "4.34.6", "@rollup/rollup-linux-loongarch64-gnu": "4.34.6", "@rollup/rollup-linux-powerpc64le-gnu": "4.34.6", "@rollup/rollup-linux-riscv64-gnu": "4.34.6", "@rollup/rollup-linux-s390x-gnu": "4.34.6", "@rollup/rollup-linux-x64-gnu": "4.34.6", "@rollup/rollup-linux-x64-musl": "4.34.6", "@rollup/rollup-win32-arm64-msvc": "4.34.6", "@rollup/rollup-win32-ia32-msvc": "4.34.6", "@rollup/rollup-win32-x64-msvc": "4.34.6", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ=="], "rollup-plugin-esbuild": ["rollup-plugin-esbuild@6.2.0", "", { "dependencies": { "debug": "^4.4.0", "es-module-lexer": "^1.6.0", "get-tsconfig": "^4.10.0", "unplugin-utils": "^0.2.3" }, "peerDependencies": { "esbuild": ">=0.18.0", "rollup": "^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" } }, "sha512-LbkHaCahA6ceyWzAd6md2yajNS+HfZmZ5o58ShkZp0cQeZOnZECG2D2xWFNBq5SF6X6pfMK2udkZ+wRtvpzyVQ=="], @@ -3802,7 +3815,7 @@ "scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], - "schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="], + "schema-utils": ["schema-utils@4.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g=="], "scroll-into-view-if-needed": ["scroll-into-view-if-needed@3.1.0", "", { "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ=="], @@ -4008,7 +4021,7 @@ "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="], - "terser": ["terser@5.38.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-a4GD5R1TjEeuCT6ZRiYMHmIf7okbCPEuhQET8bczV6FrQMMlFXA1n+G0KKjdlFCm3TEHV77GxfZB3vZSUQGFpg=="], + "terser": ["terser@5.38.1", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-GWANVlPM/ZfYzuPHjq0nxT+EbOEDDN3Jwhwdg1D8TU8oSkktp8w64Uq4auuGLxFSoNTRDncTq2hQHX1Ld9KHkA=="], "terser-webpack-plugin": ["terser-webpack-plugin@5.3.11", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", "serialize-javascript": "^6.0.2", "terser": "^5.31.1" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ=="], @@ -4042,9 +4055,9 @@ "tinyspy": ["tinyspy@2.2.1", "", {}, "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A=="], - "tldts": ["tldts@6.1.76", "", { "dependencies": { "tldts-core": "^6.1.76" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-6U2ti64/nppsDxQs9hw8ephA3nO6nSQvVVfxwRw8wLQPFtLI1cFI1a1eP22g+LUP+1TA2pKKjUTwWB+K2coqmQ=="], + "tldts": ["tldts@6.1.77", "", { "dependencies": { "tldts-core": "^6.1.77" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-lBpoWgy+kYmuXWQ83+R7LlJCnsd9YW8DGpZSHhrMl4b8Ly/1vzOie3OdtmUJDkKxcgRGOehDu5btKkty+JEe+g=="], - "tldts-core": ["tldts-core@6.1.76", "", {}, "sha512-uzhJ02RaMzgQR3yPoeE65DrcHI6LoM4saUqXOt/b5hmb3+mc4YWpdSeAQqVqRUlQ14q8ZuLRWyBR1ictK1dzzg=="], + "tldts-core": ["tldts-core@6.1.77", "", {}, "sha512-bCaqm24FPk8OgBkM0u/SrEWJgHnhBWYqeBo6yUmcZJDCHt/IfyWBb+14CXdGi4RInMv4v7eUAin15W0DoA+Ytg=="], "tmp": ["tmp@0.2.3", "", {}, "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w=="], @@ -4094,7 +4107,7 @@ "type-detect": ["type-detect@4.1.0", "", {}, "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw=="], - "type-fest": ["type-fest@4.33.0", "", {}, "sha512-s6zVrxuyKbbAsSAD5ZPTB77q4YIdRctkTbJ2/Dqlinwz+8ooH2gd+YA7VA6Pa93KML9GockVvoxjZ2vHP+mu8g=="], + "type-fest": ["type-fest@4.34.0", "", {}, "sha512-Qcg88ZJsJvRcUijtD6supagRSDf0y1FPZh4NroJpwRkoPYj6gGNidREwTgDuC0Pmq0PVAAzL8C8BZW7xhx5Q4A=="], "typed-css-modules": ["typed-css-modules@0.9.1", "", { "dependencies": { "camelcase": "^6.0.0", "chalk": "^4.0.0", "chokidar": "^3.4.0", "glob": "^10.3.10", "icss-replace-symbols": "^1.1.0", "is-there": "^4.4.2", "mkdirp": "^3.0.0", "postcss": "^8.0.0", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "yargs": "^17.7.2" }, "bin": { "tcm": "lib/cli.js" } }, "sha512-W2HWKncdKd+bLWsnuWB2EyuQBzZ7KJ9Byr/67KLiiyGegcN52rOveun9JR8yAvuL5IXunRMxt0eORMtAUj5bmA=="], @@ -4330,6 +4343,8 @@ "@babel/helper-create-regexp-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.10.6", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.2", "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA=="], + "@babel/plugin-transform-runtime/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/preset-env/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], @@ -4410,8 +4425,6 @@ "@pmmmwh/react-refresh-webpack-plugin/loader-utils": ["loader-utils@2.0.4", "", { "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw=="], - "@pmmmwh/react-refresh-webpack-plugin/schema-utils": ["schema-utils@4.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g=="], - "@pmmmwh/react-refresh-webpack-plugin/source-map": ["source-map@0.7.4", "", {}, "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="], "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="], @@ -4438,7 +4451,7 @@ "@sanity/cli/esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], - "@sanity/cli/prettier": ["prettier@3.4.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ=="], + "@sanity/cli/prettier": ["prettier@3.5.0", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-quyMrVt6svPS7CjQ9gKb3GLEX/rl3BCL2oa/QkNcXv4YNVBC9olt3s+H7ukto06q7B1Qz46PbrKLO34PR6vXcA=="], "@sanity/codegen/globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], @@ -4464,7 +4477,7 @@ "@sanity/pkg-utils/globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], - "@sanity/pkg-utils/prettier": ["prettier@3.4.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ=="], + "@sanity/pkg-utils/prettier": ["prettier@3.5.0", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-quyMrVt6svPS7CjQ9gKb3GLEX/rl3BCL2oa/QkNcXv4YNVBC9olt3s+H7ukto06q7B1Qz46PbrKLO34PR6vXcA=="], "@sanity/pkg-utils/rimraf": ["rimraf@4.4.1", "", { "dependencies": { "glob": "^9.2.0" }, "bin": { "rimraf": "dist/cjs/src/bin.js" } }, "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og=="], @@ -4490,13 +4503,13 @@ "@segment/analytics-node/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], - "@shikijs/rehype/@shikijs/types": ["@shikijs/types@2.3.1", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-1BQV6R4zF4pDPpPTbML8mPFX6RsNYtROfhgPT2YX+KW4B99a2UNtwuvmNj03BRy/sDz9GeAx9gAmnv8NroS/2w=="], + "@shikijs/rehype/@shikijs/types": ["@shikijs/types@2.3.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-CBaMY+a3pepyC4SETi7+bSzO0f6hxEQJUUuS4uD7zppzjmrN4ZRtBqxaT+wOan26CR9eeJ5iBhc4qvWEwn7Eeg=="], - "@shikijs/rehype/shiki": ["shiki@2.3.1", "", { "dependencies": { "@shikijs/core": "2.3.1", "@shikijs/engine-javascript": "2.3.1", "@shikijs/engine-oniguruma": "2.3.1", "@shikijs/langs": "2.3.1", "@shikijs/themes": "2.3.1", "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-bD1XuVAyZBVxHiPlO/m2nM2F5g8G5MwSZHNYx+ArpcOW52+fCN6peGP5gG61O0gZpzUVbImeR3ar8cF+Z5WM8g=="], + "@shikijs/rehype/shiki": ["shiki@2.3.2", "", { "dependencies": { "@shikijs/core": "2.3.2", "@shikijs/engine-javascript": "2.3.2", "@shikijs/engine-oniguruma": "2.3.2", "@shikijs/langs": "2.3.2", "@shikijs/themes": "2.3.2", "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-UZhz/gsUz7DHFbQBOJP7eXqvKyYvMGramxQiSDc83M/7OkWm6OdVHAReEc3vMLh6L6TRhgL9dvhXz9XDkCDaaw=="], - "@shikijs/transformers/@shikijs/core": ["@shikijs/core@2.3.1", "", { "dependencies": { "@shikijs/engine-javascript": "2.3.1", "@shikijs/engine-oniguruma": "2.3.1", "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-u9WTI0CgQUicTJjkHoJbZosxLP2AlBPr8RV3cuh4SQDsXYqMomjnAoo4lZSqVq8a8kpMwyv/LqoSrg69dH0ZeA=="], + "@shikijs/transformers/@shikijs/core": ["@shikijs/core@2.3.2", "", { "dependencies": { "@shikijs/engine-javascript": "2.3.2", "@shikijs/engine-oniguruma": "2.3.2", "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-s7vyL3LzUKm3Qwf36zRWlavX9BQMZTIq9B1almM63M5xBuSldnsTHCmsXzoF/Kyw4k7Xgas7yAyJz9VR/vcP1A=="], - "@shikijs/transformers/@shikijs/types": ["@shikijs/types@2.3.1", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-1BQV6R4zF4pDPpPTbML8mPFX6RsNYtROfhgPT2YX+KW4B99a2UNtwuvmNj03BRy/sDz9GeAx9gAmnv8NroS/2w=="], + "@shikijs/transformers/@shikijs/types": ["@shikijs/types@2.3.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-CBaMY+a3pepyC4SETi7+bSzO0f6hxEQJUUuS4uD7zppzjmrN4ZRtBqxaT+wOan26CR9eeJ5iBhc4qvWEwn7Eeg=="], "@sindresorhus/slugify/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], @@ -4564,10 +4577,6 @@ "aggregate-error/indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], - "ajv-draft-04/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], - - "ajv-formats/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], - "ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], "ansi-split/ansi-regex": ["ansi-regex@3.0.1", "", {}, "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw=="], @@ -4592,8 +4601,6 @@ "babel-loader/find-cache-dir": ["find-cache-dir@4.0.0", "", { "dependencies": { "common-path-prefix": "^3.0.0", "pkg-dir": "^7.0.0" } }, "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg=="], - "babel-loader/schema-utils": ["schema-utils@4.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g=="], - "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], @@ -4700,23 +4707,25 @@ "fork-ts-checker-webpack-plugin/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], + "fork-ts-checker-webpack-plugin/schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="], + "framer-motion/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], "from2/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], "ftp/readable-stream": ["readable-stream@1.1.14", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ=="], - "fumadocs-core/shiki": ["shiki@2.3.1", "", { "dependencies": { "@shikijs/core": "2.3.1", "@shikijs/engine-javascript": "2.3.1", "@shikijs/engine-oniguruma": "2.3.1", "@shikijs/langs": "2.3.1", "@shikijs/themes": "2.3.1", "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-bD1XuVAyZBVxHiPlO/m2nM2F5g8G5MwSZHNYx+ArpcOW52+fCN6peGP5gG61O0gZpzUVbImeR3ar8cF+Z5WM8g=="], + "fumadocs-core/shiki": ["shiki@2.3.2", "", { "dependencies": { "@shikijs/core": "2.3.2", "@shikijs/engine-javascript": "2.3.2", "@shikijs/engine-oniguruma": "2.3.2", "@shikijs/langs": "2.3.2", "@shikijs/themes": "2.3.2", "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-UZhz/gsUz7DHFbQBOJP7eXqvKyYvMGramxQiSDc83M/7OkWm6OdVHAReEc3vMLh6L6TRhgL9dvhXz9XDkCDaaw=="], "fumadocs-mdx/chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "fumadocs-mdx/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=="], - "fumadocs-typescript/shiki": ["shiki@2.3.1", "", { "dependencies": { "@shikijs/core": "2.3.1", "@shikijs/engine-javascript": "2.3.1", "@shikijs/engine-oniguruma": "2.3.1", "@shikijs/langs": "2.3.1", "@shikijs/themes": "2.3.1", "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-bD1XuVAyZBVxHiPlO/m2nM2F5g8G5MwSZHNYx+ArpcOW52+fCN6peGP5gG61O0gZpzUVbImeR3ar8cF+Z5WM8g=="], + "fumadocs-typescript/shiki": ["shiki@2.3.2", "", { "dependencies": { "@shikijs/core": "2.3.2", "@shikijs/engine-javascript": "2.3.2", "@shikijs/engine-oniguruma": "2.3.2", "@shikijs/langs": "2.3.2", "@shikijs/themes": "2.3.2", "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-UZhz/gsUz7DHFbQBOJP7eXqvKyYvMGramxQiSDc83M/7OkWm6OdVHAReEc3vMLh6L6TRhgL9dvhXz9XDkCDaaw=="], "fumadocs-typescript/ts-morph": ["ts-morph@25.0.1", "", { "dependencies": { "@ts-morph/common": "~0.26.0", "code-block-writer": "^13.0.3" } }, "sha512-QJEiTdnz1YjrB3JFhd626gX4rKHDLSjSVMvGGG4v7ONc3RBwa0Eei98G9AT9uNFDMtV54JyuXsFeC+OH0n6bXQ=="], - "fumadocs-ui/postcss-selector-parser": ["postcss-selector-parser@7.0.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ=="], + "fumadocs-ui/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="], "get-source/data-uri-to-buffer": ["data-uri-to-buffer@2.0.2", "", {}, "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA=="], @@ -4730,7 +4739,7 @@ "globby/@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="], - "globby/unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="], + "globby/ignore": ["ignore@7.0.3", "", {}, "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA=="], "gray-matter/js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="], @@ -4824,13 +4833,13 @@ "pkg-up/find-up": ["find-up@3.0.0", "", { "dependencies": { "locate-path": "^3.0.0" } }, "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="], - "postcss-calc/postcss-selector-parser": ["postcss-selector-parser@7.0.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ=="], + "postcss-calc/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="], "postcss-loader/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], - "postcss-modules-local-by-default/postcss-selector-parser": ["postcss-selector-parser@7.0.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ=="], + "postcss-modules-local-by-default/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="], - "postcss-modules-scope/postcss-selector-parser": ["postcss-selector-parser@7.0.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ=="], + "postcss-modules-scope/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="], "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], @@ -4898,7 +4907,7 @@ "rollup-pluginutils/estree-walker": ["estree-walker@0.6.1", "", {}, "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w=="], - "rxjs/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], + "sanity/@sanity/insert-menu": ["@sanity/insert-menu@1.0.20", "", { "dependencies": { "@sanity/icons": "^3.5.7", "@sanity/ui": "^2.11.4", "lodash": "^4.17.21" }, "peerDependencies": { "@sanity/types": "*", "react": "^18.3 || >=19.0.0-rc", "react-dom": "^18.3 || >=19.0.0-rc", "react-is": "^18.3 || >=19.0.0-rc" } }, "sha512-oYhGCerabMOJBU47ukjY5Hq6g87yHlN8Xr/HaqNLGG7ustGaT6cWA4UMaDuWd980qbWeC3s9Ph6cKRT/Sy8JtA=="], "sanity/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], @@ -4954,8 +4963,6 @@ "tempy/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], - "terser-webpack-plugin/schema-utils": ["schema-utils@4.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g=="], - "through2/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], "tough-cookie/universalify": ["universalify@0.2.0", "", {}, "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="], @@ -4994,7 +5001,7 @@ "vscode-languageclient/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], - "webpack-dev-middleware/schema-utils": ["schema-utils@4.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g=="], + "webpack/schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="], "whatwg-encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], @@ -5108,18 +5115,10 @@ "@microsoft/api-extractor/semver/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], - "@microsoft/tsdoc-config/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - "@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@20.0.0", "", {}, "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="], "@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@20.0.0", "", {}, "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="], - "@pmmmwh/react-refresh-webpack-plugin/schema-utils/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], - - "@pmmmwh/react-refresh-webpack-plugin/schema-utils/ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], - - "@rushstack/node-core-library/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - "@rushstack/node-core-library/ajv-formats/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "@rushstack/node-core-library/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], @@ -5340,19 +5339,19 @@ "@seed-design/rootage-core/vitest/vite-node": ["vite-node@0.34.6", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.3.4", "mlly": "^1.4.0", "pathe": "^1.1.1", "picocolors": "^1.0.0", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA=="], - "@shikijs/rehype/shiki/@shikijs/core": ["@shikijs/core@2.3.1", "", { "dependencies": { "@shikijs/engine-javascript": "2.3.1", "@shikijs/engine-oniguruma": "2.3.1", "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-u9WTI0CgQUicTJjkHoJbZosxLP2AlBPr8RV3cuh4SQDsXYqMomjnAoo4lZSqVq8a8kpMwyv/LqoSrg69dH0ZeA=="], + "@shikijs/rehype/shiki/@shikijs/core": ["@shikijs/core@2.3.2", "", { "dependencies": { "@shikijs/engine-javascript": "2.3.2", "@shikijs/engine-oniguruma": "2.3.2", "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-s7vyL3LzUKm3Qwf36zRWlavX9BQMZTIq9B1almM63M5xBuSldnsTHCmsXzoF/Kyw4k7Xgas7yAyJz9VR/vcP1A=="], - "@shikijs/rehype/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^3.1.0" } }, "sha512-sZLM4utrD1D28ENLtVS1+b7TIf1OIr3Gt0gLejMIG69lmFQI8mY0eGBdvbuvvM3Ys2M0kNYJF6BaWct27PggHw=="], + "@shikijs/rehype/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^3.1.0" } }, "sha512-w3IEMu5HfL/OaJTsMbIfZ1HRPnWVYRANeDtmsdIIEgUOcLjzFJFQwlnkckGjKHekEzNqlMLbgB/twnfZ/EEAGg=="], - "@shikijs/rehype/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1" } }, "sha512-UKJEMht1gkF2ROigCgb3FE2ssmbR8CJEwUneImJ2QoZqayH/96Vp88p2N+RmyqJEHo1rsOivlJKeU9shhKpfSA=="], + "@shikijs/rehype/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1" } }, "sha512-vikMY1TroyZXUHIXbMnvY/mjtOxMn+tavcfAeQPgWS9FHcgFSUoEtywF5B5sOLb9NXb8P2vb7odkh3nj15/00A=="], - "@shikijs/rehype/shiki/@shikijs/langs": ["@shikijs/langs@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1" } }, "sha512-3csAX8RGm2EQCbpCb1Eq+r4DSpkku6gxb4jiHnOxlV4D36VYZsmunUiDo/4NZvpFA0CW33v/JoYmFJ3yQ2TvSw=="], + "@shikijs/rehype/shiki/@shikijs/langs": ["@shikijs/langs@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2" } }, "sha512-UqI6bSxFzhexIJficZLKeB1L2Sc3xoNiAV0yHpfbg5meck93du+EKQtsGbBv66Ki53XZPhnR/kYkOr85elIuFw=="], - "@shikijs/rehype/shiki/@shikijs/themes": ["@shikijs/themes@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1" } }, "sha512-QtkIM4Vz166+m4KED7/U5iVpgAdhfsHqMbBbjIzdTyTM1GIk2XQLcaB9b/LQY0y83Zl4lg7A7Hg+FT8+vAGL5A=="], + "@shikijs/rehype/shiki/@shikijs/themes": ["@shikijs/themes@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2" } }, "sha512-QAh7D/hhfYKHibkG2tti8vxNt3ekAH5EqkXJeJbTh7FGvTCWEI7BHqNCtMdjFvZ0vav5nvUgdvA7/HI7pfsB4w=="], - "@shikijs/transformers/@shikijs/core/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^3.1.0" } }, "sha512-sZLM4utrD1D28ENLtVS1+b7TIf1OIr3Gt0gLejMIG69lmFQI8mY0eGBdvbuvvM3Ys2M0kNYJF6BaWct27PggHw=="], + "@shikijs/transformers/@shikijs/core/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^3.1.0" } }, "sha512-w3IEMu5HfL/OaJTsMbIfZ1HRPnWVYRANeDtmsdIIEgUOcLjzFJFQwlnkckGjKHekEzNqlMLbgB/twnfZ/EEAGg=="], - "@shikijs/transformers/@shikijs/core/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1" } }, "sha512-UKJEMht1gkF2ROigCgb3FE2ssmbR8CJEwUneImJ2QoZqayH/96Vp88p2N+RmyqJEHo1rsOivlJKeU9shhKpfSA=="], + "@shikijs/transformers/@shikijs/core/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1" } }, "sha512-vikMY1TroyZXUHIXbMnvY/mjtOxMn+tavcfAeQPgWS9FHcgFSUoEtywF5B5sOLb9NXb8P2vb7odkh3nj15/00A=="], "@storybook/core/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="], @@ -5502,16 +5501,8 @@ "@vitest/utils/pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], - "ajv-draft-04/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - - "ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - "babel-loader/find-cache-dir/pkg-dir": ["pkg-dir@7.0.0", "", { "dependencies": { "find-up": "^6.3.0" } }, "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA=="], - "babel-loader/schema-utils/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], - - "babel-loader/schema-utils/ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], - "browserify-sign/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "browserify-sign/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], @@ -5552,6 +5543,10 @@ "fork-ts-checker-webpack-plugin/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], + "fork-ts-checker-webpack-plugin/schema-utils/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], + + "fork-ts-checker-webpack-plugin/schema-utils/ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], + "from2/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "from2/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], @@ -5560,17 +5555,17 @@ "ftp/readable-stream/string_decoder": ["string_decoder@0.10.31", "", {}, "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="], - "fumadocs-core/shiki/@shikijs/core": ["@shikijs/core@2.3.1", "", { "dependencies": { "@shikijs/engine-javascript": "2.3.1", "@shikijs/engine-oniguruma": "2.3.1", "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-u9WTI0CgQUicTJjkHoJbZosxLP2AlBPr8RV3cuh4SQDsXYqMomjnAoo4lZSqVq8a8kpMwyv/LqoSrg69dH0ZeA=="], + "fumadocs-core/shiki/@shikijs/core": ["@shikijs/core@2.3.2", "", { "dependencies": { "@shikijs/engine-javascript": "2.3.2", "@shikijs/engine-oniguruma": "2.3.2", "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-s7vyL3LzUKm3Qwf36zRWlavX9BQMZTIq9B1almM63M5xBuSldnsTHCmsXzoF/Kyw4k7Xgas7yAyJz9VR/vcP1A=="], - "fumadocs-core/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^3.1.0" } }, "sha512-sZLM4utrD1D28ENLtVS1+b7TIf1OIr3Gt0gLejMIG69lmFQI8mY0eGBdvbuvvM3Ys2M0kNYJF6BaWct27PggHw=="], + "fumadocs-core/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^3.1.0" } }, "sha512-w3IEMu5HfL/OaJTsMbIfZ1HRPnWVYRANeDtmsdIIEgUOcLjzFJFQwlnkckGjKHekEzNqlMLbgB/twnfZ/EEAGg=="], - "fumadocs-core/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1" } }, "sha512-UKJEMht1gkF2ROigCgb3FE2ssmbR8CJEwUneImJ2QoZqayH/96Vp88p2N+RmyqJEHo1rsOivlJKeU9shhKpfSA=="], + "fumadocs-core/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1" } }, "sha512-vikMY1TroyZXUHIXbMnvY/mjtOxMn+tavcfAeQPgWS9FHcgFSUoEtywF5B5sOLb9NXb8P2vb7odkh3nj15/00A=="], - "fumadocs-core/shiki/@shikijs/langs": ["@shikijs/langs@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1" } }, "sha512-3csAX8RGm2EQCbpCb1Eq+r4DSpkku6gxb4jiHnOxlV4D36VYZsmunUiDo/4NZvpFA0CW33v/JoYmFJ3yQ2TvSw=="], + "fumadocs-core/shiki/@shikijs/langs": ["@shikijs/langs@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2" } }, "sha512-UqI6bSxFzhexIJficZLKeB1L2Sc3xoNiAV0yHpfbg5meck93du+EKQtsGbBv66Ki53XZPhnR/kYkOr85elIuFw=="], - "fumadocs-core/shiki/@shikijs/themes": ["@shikijs/themes@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1" } }, "sha512-QtkIM4Vz166+m4KED7/U5iVpgAdhfsHqMbBbjIzdTyTM1GIk2XQLcaB9b/LQY0y83Zl4lg7A7Hg+FT8+vAGL5A=="], + "fumadocs-core/shiki/@shikijs/themes": ["@shikijs/themes@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2" } }, "sha512-QAh7D/hhfYKHibkG2tti8vxNt3ekAH5EqkXJeJbTh7FGvTCWEI7BHqNCtMdjFvZ0vav5nvUgdvA7/HI7pfsB4w=="], - "fumadocs-core/shiki/@shikijs/types": ["@shikijs/types@2.3.1", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-1BQV6R4zF4pDPpPTbML8mPFX6RsNYtROfhgPT2YX+KW4B99a2UNtwuvmNj03BRy/sDz9GeAx9gAmnv8NroS/2w=="], + "fumadocs-core/shiki/@shikijs/types": ["@shikijs/types@2.3.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-CBaMY+a3pepyC4SETi7+bSzO0f6hxEQJUUuS4uD7zppzjmrN4ZRtBqxaT+wOan26CR9eeJ5iBhc4qvWEwn7Eeg=="], "fumadocs-mdx/chokidar/readdirp": ["readdirp@4.1.1", "", {}, "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw=="], @@ -5624,17 +5619,17 @@ "fumadocs-mdx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="], - "fumadocs-typescript/shiki/@shikijs/core": ["@shikijs/core@2.3.1", "", { "dependencies": { "@shikijs/engine-javascript": "2.3.1", "@shikijs/engine-oniguruma": "2.3.1", "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-u9WTI0CgQUicTJjkHoJbZosxLP2AlBPr8RV3cuh4SQDsXYqMomjnAoo4lZSqVq8a8kpMwyv/LqoSrg69dH0ZeA=="], + "fumadocs-typescript/shiki/@shikijs/core": ["@shikijs/core@2.3.2", "", { "dependencies": { "@shikijs/engine-javascript": "2.3.2", "@shikijs/engine-oniguruma": "2.3.2", "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-s7vyL3LzUKm3Qwf36zRWlavX9BQMZTIq9B1almM63M5xBuSldnsTHCmsXzoF/Kyw4k7Xgas7yAyJz9VR/vcP1A=="], - "fumadocs-typescript/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^3.1.0" } }, "sha512-sZLM4utrD1D28ENLtVS1+b7TIf1OIr3Gt0gLejMIG69lmFQI8mY0eGBdvbuvvM3Ys2M0kNYJF6BaWct27PggHw=="], + "fumadocs-typescript/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^3.1.0" } }, "sha512-w3IEMu5HfL/OaJTsMbIfZ1HRPnWVYRANeDtmsdIIEgUOcLjzFJFQwlnkckGjKHekEzNqlMLbgB/twnfZ/EEAGg=="], - "fumadocs-typescript/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1", "@shikijs/vscode-textmate": "^10.0.1" } }, "sha512-UKJEMht1gkF2ROigCgb3FE2ssmbR8CJEwUneImJ2QoZqayH/96Vp88p2N+RmyqJEHo1rsOivlJKeU9shhKpfSA=="], + "fumadocs-typescript/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2", "@shikijs/vscode-textmate": "^10.0.1" } }, "sha512-vikMY1TroyZXUHIXbMnvY/mjtOxMn+tavcfAeQPgWS9FHcgFSUoEtywF5B5sOLb9NXb8P2vb7odkh3nj15/00A=="], - "fumadocs-typescript/shiki/@shikijs/langs": ["@shikijs/langs@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1" } }, "sha512-3csAX8RGm2EQCbpCb1Eq+r4DSpkku6gxb4jiHnOxlV4D36VYZsmunUiDo/4NZvpFA0CW33v/JoYmFJ3yQ2TvSw=="], + "fumadocs-typescript/shiki/@shikijs/langs": ["@shikijs/langs@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2" } }, "sha512-UqI6bSxFzhexIJficZLKeB1L2Sc3xoNiAV0yHpfbg5meck93du+EKQtsGbBv66Ki53XZPhnR/kYkOr85elIuFw=="], - "fumadocs-typescript/shiki/@shikijs/themes": ["@shikijs/themes@2.3.1", "", { "dependencies": { "@shikijs/types": "2.3.1" } }, "sha512-QtkIM4Vz166+m4KED7/U5iVpgAdhfsHqMbBbjIzdTyTM1GIk2XQLcaB9b/LQY0y83Zl4lg7A7Hg+FT8+vAGL5A=="], + "fumadocs-typescript/shiki/@shikijs/themes": ["@shikijs/themes@2.3.2", "", { "dependencies": { "@shikijs/types": "2.3.2" } }, "sha512-QAh7D/hhfYKHibkG2tti8vxNt3ekAH5EqkXJeJbTh7FGvTCWEI7BHqNCtMdjFvZ0vav5nvUgdvA7/HI7pfsB4w=="], - "fumadocs-typescript/shiki/@shikijs/types": ["@shikijs/types@2.3.1", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-1BQV6R4zF4pDPpPTbML8mPFX6RsNYtROfhgPT2YX+KW4B99a2UNtwuvmNj03BRy/sDz9GeAx9gAmnv8NroS/2w=="], + "fumadocs-typescript/shiki/@shikijs/types": ["@shikijs/types@2.3.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-CBaMY+a3pepyC4SETi7+bSzO0f6hxEQJUUuS4uD7zppzjmrN4ZRtBqxaT+wOan26CR9eeJ5iBhc4qvWEwn7Eeg=="], "fumadocs-typescript/ts-morph/@ts-morph/common": ["@ts-morph/common@0.26.1", "", { "dependencies": { "fast-glob": "^3.3.2", "minimatch": "^9.0.4", "path-browserify": "^1.0.1" } }, "sha512-Sn28TGl/4cFpcM+jwsH1wLncYq3FtN/BIpem+HOygfBWPT5pAeS5dB4VFVzV8FbnOKHpDLZmvAl4AjPEev5idA=="], @@ -5658,7 +5653,7 @@ "isomorphic-dompurify/jsdom/rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="], - "isomorphic-dompurify/jsdom/tough-cookie": ["tough-cookie@5.1.0", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-rvZUv+7MoBYTiDmFPBrhL7Ujx9Sk+q9wwm22x8c8T5IJaR+Wsyc7TNxbVxo84kZoRJZZMazowFLqpankBEQrGg=="], + "isomorphic-dompurify/jsdom/tough-cookie": ["tough-cookie@5.1.1", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA=="], "lazystream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], @@ -5792,10 +5787,6 @@ "sanity/yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], - "terser-webpack-plugin/schema-utils/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], - - "terser-webpack-plugin/schema-utils/ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], - "through2/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "through2/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], @@ -5870,9 +5861,9 @@ "vscode-languageclient/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], - "webpack-dev-middleware/schema-utils/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + "webpack/schema-utils/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], - "webpack-dev-middleware/schema-utils/ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], + "webpack/schema-utils/ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], "wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.17.19", "", { "os": "android", "cpu": "arm" }, "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A=="], @@ -5922,10 +5913,6 @@ "@microsoft/api-extractor/semver/lru-cache/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], - "@pmmmwh/react-refresh-webpack-plugin/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - - "@rushstack/node-core-library/ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - "@rushstack/node-core-library/semver/lru-cache/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], "@sanity/export/rimraf/glob/jackspeak": ["jackspeak@4.0.2", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" } }, "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw=="], @@ -6082,8 +6069,6 @@ "babel-loader/find-cache-dir/pkg-dir/find-up": ["find-up@6.3.0", "", { "dependencies": { "locate-path": "^7.1.0", "path-exists": "^5.0.0" } }, "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw=="], - "babel-loader/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - "colorspace/color/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], "decompress-tar/tar-stream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], @@ -6092,6 +6077,8 @@ "find-cache-dir/pkg-dir/find-up/locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="], + "fork-ts-checker-webpack-plugin/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + "fumadocs-core/shiki/@shikijs/engine-javascript/oniguruma-to-es": ["oniguruma-to-es@3.1.0", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-BJ3Jy22YlgejHSO7Fvmz1kKazlaPmRSUH+4adTDUS/dKQ4wLxI+gALZ8updbaux7/m7fIlpgOZ5fp/Inq5jUAw=="], "fumadocs-typescript/shiki/@shikijs/engine-javascript/oniguruma-to-es": ["oniguruma-to-es@3.1.0", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-BJ3Jy22YlgejHSO7Fvmz1kKazlaPmRSUH+4adTDUS/dKQ4wLxI+gALZ8updbaux7/m7fIlpgOZ5fp/Inq5jUAw=="], @@ -6172,11 +6159,9 @@ "sanity/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="], - "terser-webpack-plugin/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - "vitest/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], - "webpack-dev-middleware/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "webpack/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "@sanity/export/rimraf/glob/path-scurry/lru-cache": ["lru-cache@11.0.2", "", {}, "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA=="], diff --git a/docs/components/example/chip-tabs-basic-activity.tsx b/docs/components/example/chip-tabs-basic-activity.tsx index 7672c1688..c071cc1e7 100644 --- a/docs/components/example/chip-tabs-basic-activity.tsx +++ b/docs/components/example/chip-tabs-basic-activity.tsx @@ -2,7 +2,7 @@ import * as React from "react"; -import { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from "seed-design/ui/chip-tabs"; +import { ChipTabsRoot, ChipTabsTrigger, ChipTabsList } from "seed-design/ui/chip-tabs"; import type { ActivityComponentType } from "@stackflow/react/future"; import AppScreen from "@/components/stackflow/ActivityLayout"; @@ -26,18 +26,18 @@ const ChipTabsBasicActivity: ActivityComponentType<"chip-tabs-basic"> = () => { return ( - setValue(value)} > - - 라벨1 - 라벨2 - 라벨3 - - + + 라벨1 + 라벨2 + 라벨3 + + {value === "1" &&
content 1
} {value === "2" &&
content 2
} {value === "3" &&
content 3
} diff --git a/docs/components/example/chip-tabs-preview.tsx b/docs/components/example/chip-tabs-preview.tsx index bf9f7bf57..ebee645eb 100644 --- a/docs/components/example/chip-tabs-preview.tsx +++ b/docs/components/example/chip-tabs-preview.tsx @@ -1,24 +1,24 @@ "use client"; import * as React from "react"; -import { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from "seed-design/ui/chip-tabs"; +import { ChipTabsRoot, ChipTabsTrigger, ChipTabsList } from "seed-design/ui/chip-tabs"; export default function ChipTabsPreview() { const [value, setValue] = React.useState("1"); return ( <> - setValue(value)} > - - 라벨1 - 라벨2 - 라벨3 - - + + 라벨1 + 라벨2 + 라벨3 + + {value === "1" &&
content 1
} {value === "2" &&
content 2
} {value === "3" &&
content 3
} diff --git a/docs/components/example/chip-tabs-variant-brand-solid.tsx b/docs/components/example/chip-tabs-variant-brand-solid.tsx index 5c41d8a27..dbb928f65 100644 --- a/docs/components/example/chip-tabs-variant-brand-solid.tsx +++ b/docs/components/example/chip-tabs-variant-brand-solid.tsx @@ -1,24 +1,24 @@ "use client"; import * as React from "react"; -import { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from "seed-design/ui/chip-tabs"; +import { ChipTabsRoot, ChipTabsTrigger, ChipTabsList } from "seed-design/ui/chip-tabs"; export default function ChipTabsVariantBrandSolid() { const [value, setValue] = React.useState("1"); return ( <> - setValue(value)} > - - 라벨1 - 라벨2 - 라벨3 - - + + 라벨1 + 라벨2 + 라벨3 + + {value === "1" &&
content 1
} {value === "2" &&
content 2
} {value === "3" &&
content 3
} diff --git a/docs/components/example/chip-tabs-variant-neutral-solid.tsx b/docs/components/example/chip-tabs-variant-neutral-solid.tsx index 39d198148..e5a5a5b85 100644 --- a/docs/components/example/chip-tabs-variant-neutral-solid.tsx +++ b/docs/components/example/chip-tabs-variant-neutral-solid.tsx @@ -1,24 +1,24 @@ "use client"; import * as React from "react"; -import { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from "seed-design/ui/chip-tabs"; +import { ChipTabsRoot, ChipTabsTrigger, ChipTabsList } from "seed-design/ui/chip-tabs"; export default function ChipTabsVariantNeutralSolid() { const [value, setValue] = React.useState("1"); return ( <> - setValue(value)} > - - 라벨1 - 라벨2 - 라벨3 - - + + 라벨1 + 라벨2 + 라벨3 + + {value === "1" &&
content 1
} {value === "2" &&
content 2
} {value === "3" &&
content 3
} diff --git a/docs/components/example/demo/index.tsx b/docs/components/example/demo/index.tsx index 34903a7d5..b16569ddf 100644 --- a/docs/components/example/demo/index.tsx +++ b/docs/components/example/demo/index.tsx @@ -4,7 +4,7 @@ import { useState } from "react"; import { type ActivityComponentType } from "@stackflow/react/future"; import { AppBar, AppBarMain } from "seed-design/ui/app-bar"; import { AppScreen, AppScreenContent } from "seed-design/ui/app-screen"; -import { Tabs, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsRoot, TabsTrigger, TabsList } from "seed-design/ui/tabs"; import { ErrorState } from "seed-design/ui/error-state"; import { SnackbarProvider } from "seed-design/ui/snackbar"; import { Recommendations } from "@/components/example/demo/tabs/recommendations"; @@ -41,21 +41,21 @@ const DemoActivity: ActivityComponentType<"demo/index"> = () => { Demo - setTab(value as Tab)} - layout="fill" + triggerLayout="fill" size="medium" - fixTriggerList + stickyList style={{ height: "100%", overflowY: "auto" }} > - + {TABS.map(({ label, value }) => ( - + {label} - + ))} - + {tab === "recommendations" && } {tab === "subscriptions" && ( = () => { }} /> )} - +
diff --git a/docs/components/example/index.json b/docs/components/example/index.json index 8061fd2e3..5b8d0ec64 100644 --- a/docs/components/example/index.json +++ b/docs/components/example/index.json @@ -1,215 +1,215 @@ { - "text-button-large": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonLarge() {\n return (\n } size=\"large\">\n 추가\n \n );\n}", - "avatar-preview": "import { Avatar, AvatarBadge } from \"seed-design/ui/avatar\";\nimport { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\nimport { Flex } from \"seed-design/ui/layout\";\n\nexport default function AvatarPreview() {\n return (\n \n }\n >\n \n
\n \n \n } />\n \n );\n}", + "action-button-brand-outline": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonBrandOutline() {\n return 라벨;\n}", + "action-button-brand-solid": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonBrandSolid() {\n return 라벨;\n}", + "action-button-critical-solid": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonCriticalSolid() {\n return 라벨;\n}", + "action-button-disabled": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonDisabled() {\n return 라벨;\n}", "action-button-icon-only": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonIconOnly() {\n return (\n \n \n \n );\n}", - "alert-dialog-stackflow": "import { useActivity } from \"@stackflow/react\";\nimport { useFlow, ActivityComponentType } from \"@stackflow/react/future\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n} from \"seed-design/ui/alert-dialog\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"alert-dialog-stackflow\": unknown;\n }\n}\n\nconst AlertDialogStackflow: ActivityComponentType<\"alert-dialog-stackflow\"> = () => {\n const activity = useActivity();\n const { pop } = useFlow();\n\n return (\n !open && pop()}>\n \n \n 제목\n Stackflow\n \n \n \n 확인\n \n \n \n \n );\n};\n\nexport default AlertDialogStackflow;", - "help-bubble-preview": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { HelpBubbleTrigger } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubblePreview() {\n return (\n \n 열기\n \n );\n}", + "action-button-loading": "import { useState } from \"react\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonLoading() {\n const [loading, setLoading] = useState(false);\n\n function handleClick() {\n setLoading(true);\n setTimeout(() => setLoading(false), 2000);\n }\n\n // 이벤트 핸들링이 필요할 수 있으므로 loading은 disabled를 포함하지 않습니다. 이벤트 발생을 원하지 않는 경우, disabled 속성을 추가해주세요.\n return (\n \n 시간이 걸리는 액션\n \n );\n}", + "action-button-neutral-outline": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonNeutralOutline() {\n return 라벨;\n}", + "action-button-neutral-solid": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonNeutralSolid() {\n return 라벨;\n}", + "action-button-neutral-weak": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonNeutralWeak() {\n return 라벨;\n}", + "action-button-prefix-icon": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonPrefixIcon() {\n return }>라벨;\n}", + "action-button-preview": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonPreview() {\n return 라벨;\n}", "action-button-suffix-icon": "import { IconChevronRightFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonSuffixIcon() {\n return }>라벨;\n}", - "control-chip-small": "import { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ActionChipSmall() {\n return 라벨;\n}", - "text-field-form": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { useState, useCallback, type FormEvent } from \"react\";\nimport { Column, Columns, Stack } from \"seed-design/ui/layout\";\n\ninterface FormValues {\n name: string;\n address: string;\n}\n\ntype FieldErrors = Record;\n\nexport default function TextFieldForm() {\n const [formValues, setFormValues] = useState({\n name: \"\",\n address: \"\",\n });\n\n const [fieldErrors, setFieldStates] = useState({\n name: null,\n address: null,\n });\n\n const validateForm = useCallback((): boolean => {\n let isValid = true;\n\n const newFieldErrors: FieldErrors = {\n name: null,\n address: null,\n };\n\n // Name validation\n if (!formValues.name) {\n newFieldErrors.name = \"필수 입력 항목입니다\";\n isValid = false;\n }\n\n if (!formValues.address.startsWith(\"대한민국\")) {\n newFieldErrors.address = \"대한민국으로 시작해주세요\";\n isValid = false;\n }\n\n if (!formValues.address) {\n newFieldErrors.address = \"필수 입력 항목입니다\";\n isValid = false;\n }\n\n setFieldStates(newFieldErrors);\n\n return isValid;\n }, [formValues]);\n\n const handleSubmit = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n\n if (validateForm()) {\n window.alert(JSON.stringify(formValues, null, 2));\n }\n },\n [formValues, validateForm],\n );\n\n const handleReset = useCallback((event: FormEvent) => {\n event.preventDefault();\n\n setFormValues({ name: \"\", address: \"\" });\n setFieldStates({ name: null, address: null });\n }, []);\n\n const handleNameChange = (value: string) => {\n setFormValues((prev) => ({ ...prev, name: value }));\n setFieldStates((prev) => ({ ...prev, name: null }));\n };\n\n const handleAddressChange = (value: string) => {\n setFormValues((prev) => ({ ...prev, address: value }));\n setFieldStates((prev) => ({ ...prev, address: null }));\n };\n\n return (\n \n \n \n handleNameChange(value)}\n {...(fieldErrors.name && { invalid: true, errorMessage: fieldErrors.name })}\n >\n \n \n \n \n handleAddressChange(slicedValue)}\n {...(fieldErrors.address && { invalid: true, errorMessage: fieldErrors.address })}\n >\n \n \n \n \n \n \n \n 초기화\n \n \n \n 제출\n \n \n \n );\n}", - "multiline-text-field-formatting": "import { useMemo, useState } from \"react\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldFormatting() {\n const [value, setValue] = useState(\"\");\n\n const formattedValue = useMemo(\n () =>\n value\n .split(\"\")\n .filter((char) => char !== \" \")\n .join(\"\"),\n [value],\n );\n\n return (\n setValue(value)}\n >\n \n \n );\n}", + "action-chip-icon-only": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipIconOnly() {\n return (\n \n \n \n );\n}", + "action-chip-medium": "import { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipMedium() {\n return 라벨;\n}", + "action-chip-prefix-icon": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipPrefixIcon() {\n return }>라벨;\n}", + "action-chip-preview": "import { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipPreview() {\n return 라벨;\n}", + "action-chip-small": "import { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipSmall() {\n return 라벨;\n}", + "action-chip-suffix-icon": "import { IconChevronDownFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipSuffixIcon() {\n return }>라벨;\n}", + "action-sheet-preview": "import {\n ActionSheetContent,\n ActionSheetItem,\n ActionSheetRoot,\n ActionSheetTrigger,\n} from \"seed-design/ui/action-sheet\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nconst ActionSheetPreview = () => {\n return (\n \n \n Open\n \n \n \n \n \n \n \n );\n};\n\nexport default ActionSheetPreview;", + "alert-dialog-critical": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"seed-design/ui/alert-dialog\";\nimport { Column, Columns } from \"@seed-design/react\";\n\nconst AlertDialogCritical = () => {\n return (\n // You can set z-index dialog with \"--layer-index\" custom property. useful for stackflow integration.\n \n \n 열기\n \n \n \n 제목\n 파괴적, 비가역적 작업을 경고합니다.\n \n \n \n \n \n 취소\n \n \n \n \n 확인\n \n \n \n \n \n \n );\n};\n\nexport default AlertDialogCritical;", + "alert-dialog-neutral": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"seed-design/ui/alert-dialog\";\nimport { Column, Columns } from \"@seed-design/react\";\n\nconst AlertDialogNeutral = () => {\n return (\n // You can set z-index dialog with \"--layer-index\" custom property. useful for stackflow integration.\n \n \n 열기\n \n \n \n 제목\n 중립적인 선택지를 제공합니다.\n \n \n \n \n \n 취소\n \n \n \n \n 확인\n \n \n \n \n \n \n );\n};\n\nexport default AlertDialogNeutral;", + "alert-dialog-preview": "import { Column, Columns } from \"@seed-design/react\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"seed-design/ui/alert-dialog\";\n\nconst AlertDialogSingle = () => {\n return (\n // You can set z-index dialog with \"--layer-index\" custom property. useful for stackflow integration.\n \n \n 열기\n \n \n \n 주의\n 이 작업은 되돌릴 수 없습니다.\n \n \n \n \n \n 취소\n \n \n \n \n 확인\n \n \n \n \n \n \n );\n};\n\nexport default AlertDialogSingle;", + "alert-dialog-single": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"seed-design/ui/alert-dialog\";\n\nconst AlertDialogSingle = () => {\n // You can set z-index dialog with \"--layer-index\" custom property. useful for stackflow integration.\n return (\n \n \n 열기\n \n \n \n 제목\n 단일 선택지를 제공합니다.\n \n \n \n 확인\n \n \n \n \n );\n};\n\nexport default AlertDialogSingle;", + "alert-dialog-stackflow": "import { useActivity } from \"@stackflow/react\";\nimport { useFlow, ActivityComponentType } from \"@stackflow/react/future\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n} from \"seed-design/ui/alert-dialog\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"alert-dialog-stackflow\": unknown;\n }\n}\n\nconst AlertDialogStackflow: ActivityComponentType<\"alert-dialog-stackflow\"> = () => {\n const activity = useActivity();\n const { pop } = useFlow();\n\n return (\n !open && pop()}>\n \n \n 제목\n Stackflow\n \n \n \n 확인\n \n \n \n \n );\n};\n\nexport default AlertDialogStackflow;", + "app-screen-preview": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport {\n AppBar,\n AppBarCloseButton,\n AppBarIconButton,\n AppBarLeft,\n AppBarMain,\n AppBarRight,\n} from \"seed-design/ui/app-bar\";\nimport { AppScreen, AppScreenContent } from \"seed-design/ui/app-screen\";\nimport { Flex } from \"seed-design/ui/layout\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"app-screen-preview\": unknown;\n }\n}\n\nconst AppScreenPreviewActivity: ActivityComponentType<\"app-screen-preview\"> = () => {\n return (\n \n \n \n \n \n Preview\n \n \n \n \n \n \n \n \n Preview\n \n \n \n );\n};\n\nexport default AppScreenPreviewActivity;", + "app-screen-transparent-bar": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport {\n AppBar,\n AppBarCloseButton,\n AppBarIconButton,\n AppBarLeft,\n AppBarMain,\n AppBarRight,\n} from \"seed-design/ui/app-bar\";\nimport { AppScreen, AppScreenContent } from \"seed-design/ui/app-screen\";\nimport { Flex } from \"seed-design/ui/layout\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"app-screen-transparent-bar\": unknown;\n }\n}\n\nconst AppScreenTransparentBarActivity: ActivityComponentType<\"app-screen-transparent-bar\"> = () => {\n return (\n \n \n \n \n \n Preview\n \n \n \n \n \n \n \n \n Preview\n \n \n \n );\n};\n\nexport default AppScreenTransparentBarActivity;", + "avatar-badge": "import { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\nimport { Avatar, AvatarBadge } from \"seed-design/ui/avatar\";\n\nexport default function AvatarWithBadge() {\n return (\n }\n >\n \n
\n \n \n );\n}", + "avatar-preview": "import { Avatar, AvatarBadge } from \"seed-design/ui/avatar\";\nimport { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\nimport { Flex } from \"seed-design/ui/layout\";\n\nexport default function AvatarPreview() {\n return (\n \n }\n >\n \n
\n \n \n } />\n \n );\n}", + "avatar-size": "import { Avatar } from \"seed-design/ui/avatar\";\nimport { Flex } from \"seed-design/ui/layout\";\n\nexport default function AvatarSize() {\n return (\n \n \n \n \n \n \n \n \n \n );\n}", + "avatar-stack": "import { Avatar, AvatarStack } from \"seed-design/ui/avatar\";\nimport { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\n\nexport default function AvatarStackExample() {\n return (\n \n }\n />\n }\n />\n }\n />\n }\n />\n \n );\n}", + "badge-as-child": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeAsChild() {\n return (\n \n \n 링크\n \n \n );\n}", + "badge-brand": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeBrand() {\n return 라벨;\n}", + "badge-critical": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeCritical() {\n return 라벨;\n}", + "badge-informative": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeInformative() {\n return 라벨;\n}", "badge-large": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeLarge() {\n return 라벨;\n}", - "reaction-button-xsmall": "import { IconFaceSmileCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { ReactionButton } from \"seed-design/ui/reaction-button\";\n\nexport default function ReactionButtonXsmall() {\n return (\n } size=\"xsmall\" count={1}>\n 도움돼요\n \n );\n}", - "action-button-loading": "import { useState } from \"react\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonLoading() {\n const [loading, setLoading] = useState(false);\n\n function handleClick() {\n setLoading(true);\n setTimeout(() => setLoading(false), 2000);\n }\n\n // 이벤트 핸들링이 필요할 수 있으므로 loading은 disabled를 포함하지 않습니다. 이벤트 발생을 원하지 않는 경우, disabled 속성을 추가해주세요.\n return (\n \n 시간이 걸리는 액션\n \n );\n}", - "help-bubble-flip": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { HelpBubbleTrigger } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubbleFlip() {\n return (\n \n 열기\n \n );\n}", - "multiline-text-field-grapheme-count": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldGraphemeCount() {\n return (\n \n \n \n );\n}", - "multiline-text-field-xlarge": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldXlarge() {\n return (\n \n \n \n );\n}", - "action-button-brand-outline": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonBrandOutline() {\n return 라벨;\n}", - "switch-preview": "import { useState } from \"react\";\nimport { Switch } from \"seed-design/ui/switch\";\n\nexport default function SwitchPreview() {\n const [isChecked, setIsChecked] = useState(false);\n\n return ;\n}", - "snackbar-preview": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { Snackbar, SnackbarProvider, useSnackbarAdapter } from \"seed-design/ui/snackbar\";\n\nfunction Component() {\n const adapter = useSnackbarAdapter();\n\n return (\n \n adapter.create({\n timeout: 5000,\n onClose: () => {},\n render: () => {}} />,\n })\n }\n >\n 실행\n \n );\n}\n\nexport default function SnackbarPreview() {\n return (\n \n \n \n );\n}", + "badge-medium": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeMedium() {\n return 라벨;\n}", + "badge-neutral": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeNeutral() {\n return 라벨;\n}", "badge-outline": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeOutline() {\n return 라벨;\n}", - "toggle-button-neutral-weak": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonBrandSolid() {\n const [pressed, setPressed] = useState(false);\n\n return (\n \n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", - "checkbox-preview": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxPreview() {\n return ;\n}", - "progress-circle-24": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircle24() {\n return ;\n}", - "tabs-size-small": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsSizeSmall() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n
\n );\n};", - "toggle-button-prefix-icon": "import { IconCheckmarkLine, IconPlusLine } from \"@daangn/react-monochrome-icon\";\nimport { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonPrefixIcon() {\n const [pressed, setPressed] = useState(false);\n\n return (\n : }\n pressed={pressed}\n onPressedChange={setPressed}\n >\n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", + "badge-pill": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeRectangle() {\n return 라벨;\n}", + "badge-positive": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgePositive() {\n return 라벨;\n}", + "badge-preview": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgePreview() {\n return 라벨;\n}", + "badge-rectangle": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeRectangle() {\n return 라벨;\n}", + "badge-solid": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeSolid() {\n return 라벨;\n}", + "badge-weak": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeWeak() {\n return 라벨;\n}", + "bottom-sheet-preview": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n BottomSheetRoot,\n BottomSheetBody,\n BottomSheetContent,\n BottomSheetFooter,\n BottomSheetTrigger,\n} from \"seed-design/ui/bottom-sheet\";\n\nconst BottomSheetPreview = () => {\n return (\n \n \n Open\n \n \n {/* BottomSheetBody is simple paddingX helper. */}\n {/* If you need to omit padding, replace with or other layout you need. */}\n Content\n \n 확인\n \n \n \n );\n};\n\nexport default BottomSheetPreview;", + "box-preview": "import { Box } from \"seed-design/ui/layout\";\n\nexport default function BoxPreview() {\n return (\n \n Box Example\n \n );\n}", + "callout-critical": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutCritical() {\n return (\n \n \n \n \n \n );\n}", + "callout-informative": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutInformative() {\n return (\n \n \n \n \n \n );\n}", + "callout-link-label-as-child": "import { Stack } from \"seed-design/ui/layout\";\nimport { Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutLinkLabelAsChild() {\n return (\n \n \n 시도해 보기\n \n }\n linkProps={{ asChild: true }}\n />\n \n 시도해 보기\n \n }\n linkProps={{ asChild: true }}\n />\n \n );\n}", + "callout-magic": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutMagic() {\n return (\n \n \n \n \n \n );\n}", + "callout-neutral": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutNeutral() {\n return (\n \n \n \n \n \n );\n}", + "callout-preview": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutPreview() {\n return (\n \n \n \n \n \n );\n}", + "callout-text-only": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutTextOnly() {\n return (\n \n \n \n \n \n );\n}", + "callout-warning": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWarning() {\n return (\n \n \n \n \n \n );\n}", + "callout-with-all": "import { IconCalendarFill } from \"@daangn/react-monochrome-icon\";\nimport { Callout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWithAll() {\n return (\n }\n description=\"기능에 대한 안내 또는 유익한 내용을 전달해요. 콜아웃은 꼭 필요한 경우에만 절제하여 사용해요.\"\n linkLabel=\"시도해 보기\"\n />\n );\n}", + "callout-with-icon": "import { IconCalendarFill } from \"@daangn/react-monochrome-icon\";\nimport { Callout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWithIcon() {\n return (\n }\n description=\"기능에 대한 안내 또는 유익한 내용을 전달해요. 콜아웃은 꼭 필요한 경우에만 절제하여 사용해요.\"\n />\n );\n}", + "callout-with-link-label": "import { Stack } from \"seed-design/ui/layout\";\nimport { Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWithLinkLabel() {\n return (\n \n \n \n \n );\n}", + "callout-with-title-text": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWithTitleText() {\n return (\n \n \n \n \n \n );\n}", + "check-select-box-preview": "import { Stack } from \"@seed-design/react\";\nimport { CheckSelectBox, CheckSelectBoxGroup } from \"seed-design/ui/select-box\";\n\nexport default function CheckSelectBoxPreview() {\n return (\n \n \n \n \n \n \n \n );\n}", + "check-select-box-react-hook-form": "import { Column, Columns, Stack } from \"@seed-design/react\";\nimport { useCallback, type FormEvent } from \"react\";\nimport { useController, useForm } from \"react-hook-form\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { CheckSelectBox, CheckSelectBoxGroup } from \"seed-design/ui/select-box\";\n\nconst POSSIBLE_FRUIT_VALUES = [\"apple\", \"melon\", \"mango\"] as const;\n\ntype FormValues = Record<(typeof POSSIBLE_FRUIT_VALUES)[number], boolean>;\n\nexport default function CheckSelectBoxReactHookForm() {\n const { handleSubmit, reset, setValue, control } = useForm({\n defaultValues: {\n apple: false,\n melon: true,\n mango: false,\n },\n });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n return (\n \n \n \n {POSSIBLE_FRUIT_VALUES.map((name) => {\n const {\n field: { value, ...restProps },\n fieldState: { invalid },\n } = useController({ name, control });\n\n return (\n \n );\n })}\n \n \n \n \n \n 초기화\n \n \n \n setValue(\"mango\", true)}>\n mango 선택\n \n \n \n 제출\n \n \n \n );\n}", + "checkbox-disabled": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxDisabled() {\n return (\n
\n \n \n \n \n
\n );\n}", + "checkbox-indeterminate": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxIndeterminate() {\n return ;\n}", "checkbox-long-text": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxLongText() {\n return (\n
\n \n \n
\n );\n}", - "text-field-read-only": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Columns, Column } from \"seed-design/ui/layout\";\n\nexport default function TextFieldReadOnly() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", - "toggle-button-disabled": "import { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonDisabled() {\n return 비활성;\n}", - "stack-preview": "import { Box, Stack } from \"seed-design/ui/layout\";\n\nexport default function StackPreview() {\n return (\n \n \n 1\n \n \n 2\n \n \n 3\n \n \n );\n}", - "chip-tabs-basic-activity": "import * as React from \"react\";\n\nimport { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from \"seed-design/ui/chip-tabs\";\n\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport AppScreen from \"@/components/stackflow/ActivityLayout\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"chip-tabs-basic\": unknown;\n }\n}\n\nconst ChipTabsBasicActivity: ActivityComponentType<\"chip-tabs-basic\"> = () => {\n const [value, setValue] = React.useState(\"1\");\n\n const commonStyle = {\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n backgroundColor: \"#eeeeee\",\n height: \"100%\",\n };\n\n return (\n \n setValue(value)}\n >\n \n 라벨1\n 라벨2\n 라벨3\n \n \n {value === \"1\" &&
content 1
}\n {value === \"2\" &&
content 2
}\n {value === \"3\" &&
content 3
}\n
\n );\n};\n\nexport default ChipTabsBasicActivity;", - "action-chip-prefix-icon": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipPrefixIcon() {\n return }>라벨;\n}", + "checkbox-preview": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxPreview() {\n return ;\n}", + "checkbox-react-hook-form": "import { useController, useForm } from \"react-hook-form\";\nimport { Checkbox } from \"seed-design/ui/checkbox\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { Column, Columns, Stack } from \"seed-design/ui/layout\";\nimport { useCallback, type FormEvent } from \"react\";\n\nconst POSSIBLE_FRUIT_VALUES = [\"apple\", \"melon\", \"mango\"] as const;\n\ntype FormValues = Record<(typeof POSSIBLE_FRUIT_VALUES)[number], boolean>;\n\nexport default function CheckboxReactHookForm() {\n const { handleSubmit, reset, setValue, control } = useForm({\n defaultValues: {\n apple: false,\n melon: true,\n mango: false,\n },\n });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n return (\n \n \n {POSSIBLE_FRUIT_VALUES.map((name) => {\n const {\n field: { value, ...restProps },\n fieldState: { invalid },\n } = useController({ name, control });\n return (\n \n );\n })}\n \n \n \n \n 초기화\n \n \n \n setValue(\"mango\", true)}>\n mango 선택\n \n \n \n 제출\n \n \n \n );\n}", + "checkbox-size": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxSize() {\n return (\n
\n \n \n
\n );\n}", + "checkbox-stronger": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxStronger() {\n return ;\n}", + "checkbox-variant": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxVariant() {\n return (\n
\n \n \n
\n );\n}", + "chip-tabs-basic-activity": "import * as React from \"react\";\n\nimport { ChipTabsRoot, ChipTabsTrigger, ChipTabsList } from \"seed-design/ui/chip-tabs\";\n\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport AppScreen from \"@/components/stackflow/ActivityLayout\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"chip-tabs-basic\": unknown;\n }\n}\n\nconst ChipTabsBasicActivity: ActivityComponentType<\"chip-tabs-basic\"> = () => {\n const [value, setValue] = React.useState(\"1\");\n\n const commonStyle = {\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n backgroundColor: \"#eeeeee\",\n height: \"100%\",\n };\n\n return (\n \n setValue(value)}\n >\n \n 라벨1\n 라벨2\n 라벨3\n \n \n {value === \"1\" &&
content 1
}\n {value === \"2\" &&
content 2
}\n {value === \"3\" &&
content 3
}\n
\n );\n};\n\nexport default ChipTabsBasicActivity;", + "chip-tabs-preview": "import * as React from \"react\";\nimport { ChipTabsRoot, ChipTabsTrigger, ChipTabsList } from \"seed-design/ui/chip-tabs\";\n\nexport default function ChipTabsPreview() {\n const [value, setValue] = React.useState(\"1\");\n return (\n <>\n setValue(value)}\n >\n \n 라벨1\n 라벨2\n 라벨3\n \n \n {value === \"1\" &&
content 1
}\n {value === \"2\" &&
content 2
}\n {value === \"3\" &&
content 3
}\n \n );\n}", + "chip-tabs-variant-brand-solid": "import * as React from \"react\";\nimport { ChipTabsRoot, ChipTabsTrigger, ChipTabsList } from \"seed-design/ui/chip-tabs\";\n\nexport default function ChipTabsVariantBrandSolid() {\n const [value, setValue] = React.useState(\"1\");\n return (\n <>\n setValue(value)}\n >\n \n 라벨1\n 라벨2\n 라벨3\n \n \n {value === \"1\" &&
content 1
}\n {value === \"2\" &&
content 2
}\n {value === \"3\" &&
content 3
}\n \n );\n}", + "chip-tabs-variant-neutral-solid": "import * as React from \"react\";\nimport { ChipTabsRoot, ChipTabsTrigger, ChipTabsList } from \"seed-design/ui/chip-tabs\";\n\nexport default function ChipTabsVariantNeutralSolid() {\n const [value, setValue] = React.useState(\"1\");\n return (\n <>\n setValue(value)}\n >\n \n 라벨1\n 라벨2\n 라벨3\n \n \n {value === \"1\" &&
content 1
}\n {value === \"2\" &&
content 2
}\n {value === \"3\" &&
content 3
}\n \n );\n}", + "columns-preview": "import { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function ColumnsPreview() {\n return (\n \n \n 1\n \n \n Content Width\n \n \n 2\n \n \n );\n}", + "control-chip-icon-only": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ControlChipIconOnly() {\n return (\n \n \n \n );\n}", + "control-chip-medium": "import { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ActionChipMedium() {\n return 라벨;\n}", + "control-chip-prefix-icon": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ControlChipPrefixIcon() {\n return }>라벨;\n}", + "control-chip-preview": "import { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ControlChipPreview() {\n return 라벨;\n}", + "control-chip-small": "import { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ActionChipSmall() {\n return 라벨;\n}", + "control-chip-suffix-icon": "import { IconChevronDownFill } from \"@daangn/react-monochrome-icon\";\nimport { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ControlChipSuffixIcon() {\n return }>라벨;\n}", "error-state-basement": "import { Stack } from \"@seed-design/react\";\nimport { ErrorState } from \"seed-design/ui/error-state\";\n\nexport default function ErrorStateBasement() {\n return (\n \n \n \n );\n}", - "multiline-text-field-constraints": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldConstraints() {\n return (\n \n \n \n );\n}", "error-state-preview": "import { Stack } from \"@seed-design/react\";\nimport { ErrorState } from \"seed-design/ui/error-state\";\n\nexport default function ErrorStatePreview() {\n return (\n \n \n \n );\n}", - "tabs-swipeable": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsSwipeable() {\n return (\n
\n console.log(\"swipe start\")}\n onSwipeEnd={() => console.log(\"swipe end\")}\n >\n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n
\n );\n};", - "action-button-neutral-solid": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonNeutralSolid() {\n return 라벨;\n}", - "multiline-text-field-read-only": "import { Column, Columns } from \"seed-design/ui/layout\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldReadOnly() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", - "badge-brand": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeBrand() {\n return 라벨;\n}", - "avatar-size": "import { Avatar } from \"seed-design/ui/avatar\";\nimport { Flex } from \"seed-design/ui/layout\";\n\nexport default function AvatarSize() {\n return (\n \n \n \n \n \n \n \n \n \n );\n}", - "progress-circle-indeterminate": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCirclePreview() {\n // if you want to show an indeterminate progress circle, you can pass `undefined` or omit the `value` prop\n return ;\n}", - "action-button-brand-solid": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonBrandSolid() {\n return 라벨;\n}", - "text-field-react-hook-form": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { useController, useForm } from \"react-hook-form\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { useCallback, type FormEvent } from \"react\";\nimport { Column, Columns, Stack } from \"seed-design/ui/layout\";\n\ninterface FormValues {\n name: string;\n address: string;\n}\n\nexport default function TextFieldReactHookForm() {\n const { handleSubmit, reset, control } = useForm({\n defaultValues: {\n name: \"\",\n address: \"\",\n },\n });\n\n const { field: nameField, fieldState: nameFieldState } = useController({\n name: \"name\",\n control,\n rules: {\n required: \"필수 입력 항목입니다\",\n },\n });\n const {\n field: { onChange: addressOnChange, ...addressField },\n fieldState: addressFieldState,\n } = useController({\n name: \"address\",\n control,\n rules: {\n required: \"필수 입력 항목입니다\",\n pattern: { value: /^대한민국/, message: \"대한민국으로 시작해주세요\" },\n },\n });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n return (\n \n \n \n \n \n \n \n \n addressOnChange(slicedValue)}\n required\n {...addressField}\n >\n \n \n \n \n \n \n \n 초기화\n \n \n \n 제출\n \n \n \n );\n}", - "text-button-small": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonSmall() {\n return (\n } size=\"small\">\n 추가\n \n );\n}", - "checkbox-indeterminate": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxIndeterminate() {\n return ;\n}", - "text-button-brand": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonBrand() {\n return (\n }>\n 추가\n \n );\n}", - "progress-circle-small": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCirclePreview() {\n return ;\n}", - "inline-banner-activity": "import * as React from \"react\";\n\nimport { InlineBanner, type InlineBannerProps } from \"seed-design/ui/inline-banner\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport AppScreen from \"@/components/stackflow/ActivityLayout\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"inline-banner\": unknown;\n }\n}\n\nconst InlineBannerActivity: ActivityComponentType<\"inline-banner\"> = () => {\n const [variant, setVariant] =\n React.useState>(\n \"criticalSolid\",\n );\n\n return (\n \n \n
\n \n setVariant((prev) => (prev === \"criticalSolid\" ? \"neutralWeak\" : \"criticalSolid\"))\n }\n >\n Toggle tone\n \n

\n Lorem ipsum dolor sit, amet consectetur adipisicing elit. At a eaque fugiat sint sapiente.\n Id, hic ex, blanditiis totam animi amet delectus temporibus quae fugiat magnam, quos eaque\n dolorum a? Lorem ipsum dolor, sit amet consectetur adipisicing elit. Possimus labore unde\n minus temporibus beatae commodi et nesciunt iure in dignissimos suscipit, alias ab\n voluptatem facilis tempora numquam. Veritatis, dolorum suscipit! Lorem ipsum dolor sit,\n amet consectetur adipisicing elit. Explicabo fugiat molestias iusto, ipsum distinctio\n officia ad id ratione esse ducimus architecto deleniti illum reiciendis rerum, at\n blanditiis molestiae. Cupiditate, nobis? Lorem ipsum dolor sit amet consectetur\n adipisicing elit. Ab, magni. Aliquid inventore quaerat nemo architecto harum earum quas\n porro repudiandae explicabo repellat repellendus magni, corporis omnis laborum, velit\n dicta blanditiis. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Debitis,\n eveniet quas. Accusamus facere veritatis expedita delectus, asperiores numquam placeat\n necessitatibus assumenda, nesciunt in dolorem sit provident repellendus, voluptatem earum!\n Consequatur. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Aut earum\n asperiores aliquam magnam est delectus veritatis numquam sint porro tenetur dolores nobis,\n deleniti voluptas quaerat, quia voluptatum soluta autem perspiciatis? Lorem ipsum dolor\n sit amet consectetur adipisicing elit. Facilis possimus eaque aliquam maxime? Quidem enim,\n sed itaque at veritatis nihil officia esse qui provident ipsa adipisci necessitatibus\n officiis distinctio laborum!\n

\n
\n
\n );\n};\n\nexport default InlineBannerActivity;", - "progress-circle-brand": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircleBrand() {\n return ;\n}", - "app-screen-preview": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport {\n AppBar,\n AppBarCloseButton,\n AppBarIconButton,\n AppBarLeft,\n AppBarMain,\n AppBarRight,\n} from \"seed-design/ui/app-bar\";\nimport { AppScreen, AppScreenContent } from \"seed-design/ui/app-screen\";\nimport { Flex } from \"seed-design/ui/layout\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"app-screen-preview\": unknown;\n }\n}\n\nconst AppScreenPreviewActivity: ActivityComponentType<\"app-screen-preview\"> = () => {\n return (\n \n \n \n \n \n Preview\n \n \n \n \n \n \n \n \n Preview\n \n \n \n );\n};\n\nexport default AppScreenPreviewActivity;", - "checkbox-size": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxSize() {\n return (\n
\n \n \n
\n );\n}", - "reaction-button-preview": "import { IconFaceSmileCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { ReactionButton } from \"seed-design/ui/reaction-button\";\n\nexport default function ReactionButtonPreview() {\n return (\n } count={1}>\n 도움돼요\n \n );\n}", - "callout-magic": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutMagic() {\n return (\n \n \n \n \n \n );\n}", - "action-button-prefix-icon": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonPrefixIcon() {\n return }>라벨;\n}", + "extended-action-sheet-preview": "import { IconEyeSlashLine } from \"@daangn/react-monochrome-icon\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n ExtendedActionSheetContent,\n ExtendedActionSheetGroup,\n ExtendedActionSheetItem,\n ExtendedActionSheetRoot,\n ExtendedActionSheetTrigger,\n} from \"seed-design/ui/extended-action-sheet\";\n\nconst ExtendedActionSheetPreview = () => {\n return (\n \n \n Open\n \n \n \n } label=\"Action 1\" />\n } label=\"Action 2\" />\n } label=\"Action 3\" />\n \n \n } label=\"Action 4\" />\n }\n label=\"Action 5\"\n />\n \n \n \n );\n};\n\nexport default ExtendedActionSheetPreview;", + "extended-fab-layer-floating": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabLayerFloating() {\n return (\n }>\n 알림 설정\n \n );\n}", + "extended-fab-medium": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabMedium() {\n return (\n }>\n 알림 설정\n \n );\n}", + "extended-fab-neutral-solid": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabNeutralSolid() {\n return (\n }>\n 알림 설정\n \n );\n}", + "extended-fab-preview": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabPreview() {\n return }>알림 설정;\n}", + "extended-fab-small": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabSmall() {\n return (\n }>\n 알림 설정\n \n );\n}", + "fab-preview": "import IconPlusLine from \"@daangn/react-monochrome-icon/IconPlusLine\";\nimport { Fab } from \"seed-design/ui/fab\";\n\nexport default function FabPreview() {\n return (\n \n \n \n );\n}", + "flex-preview": "import { Flex } from \"seed-design/ui/layout\";\n\nexport default function FlexPreview() {\n return (\n \n \n \n 1\n \n \n 2\n \n \n \n \n 3\n \n \n 4\n \n \n \n 5\n \n \n );\n}", "help-bubble-anchor": "import { Avatar } from \"seed-design/ui/avatar\";\nimport { HelpBubbleAnchor } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubbleAnchorExample() {\n return (\n \n \n \n );\n}", + "help-bubble-close-button": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { HelpBubbleTrigger } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubbleCloseButton() {\n return (\n \n 열기\n \n );\n}", + "help-bubble-flip": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { HelpBubbleTrigger } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubbleFlip() {\n return (\n \n 열기\n \n );\n}", "help-bubble-placement": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { HelpBubbleTrigger } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubblePreview() {\n return (\n \n 열기\n \n );\n}", - "inline-banner-with-all": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWithAll() {\n return (\n \n }\n title=\"타이틀\"\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n title=\"타이틀\"\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n title=\"타이틀\"\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n title=\"타이틀\"\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", - "badge-informative": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeInformative() {\n return 라벨;\n}", - "alert-dialog-single": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"seed-design/ui/alert-dialog\";\n\nconst AlertDialogSingle = () => {\n // You can set z-index dialog with \"--layer-index\" custom property. useful for stackflow integration.\n return (\n \n \n 열기\n \n \n \n 제목\n 단일 선택지를 제공합니다.\n \n \n \n 확인\n \n \n \n \n );\n};\n\nexport default AlertDialogSingle;", - "text-button-medium": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonMedium() {\n return (\n } size=\"medium\">\n 추가\n \n );\n}", - "toggle-button-brand-solid": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonBrandSolid() {\n const [pressed, setPressed] = useState(false);\n\n return (\n \n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", - "toggle-button-loading": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonLoading() {\n const [pressed, setPressed] = useState(false);\n const [loading, setLoading] = useState(false);\n\n function handleToggle() {\n setLoading(true);\n setTimeout(() => {\n setLoading(false);\n setPressed((prev) => !prev);\n }, 2000);\n }\n\n // 이벤트 핸들링이 필요할 수 있으므로 loading은 disabled를 포함하지 않습니다. 이벤트 발생을 원하지 않는 경우, disabled 속성을 추가해주세요.\n return (\n \n 시간이 걸리는 토글\n \n );\n}", + "help-bubble-preview": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { HelpBubbleTrigger } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubblePreview() {\n return (\n \n 열기\n \n );\n}", + "help-bubble-title-only": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { HelpBubbleTrigger } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubbleTitleOnly() {\n return (\n \n 열기\n \n );\n}", + "identity-placeholder-preview": "import { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\n\nexport default function IdentityPlaceholderPreview() {\n return ;\n}", + "inline-banner-activity": "import * as React from \"react\";\n\nimport { InlineBanner, type InlineBannerProps } from \"seed-design/ui/inline-banner\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport AppScreen from \"@/components/stackflow/ActivityLayout\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"inline-banner\": unknown;\n }\n}\n\nconst InlineBannerActivity: ActivityComponentType<\"inline-banner\"> = () => {\n const [variant, setVariant] =\n React.useState>(\n \"criticalSolid\",\n );\n\n return (\n \n \n
\n \n setVariant((prev) => (prev === \"criticalSolid\" ? \"neutralWeak\" : \"criticalSolid\"))\n }\n >\n Toggle tone\n \n

\n Lorem ipsum dolor sit, amet consectetur adipisicing elit. At a eaque fugiat sint sapiente.\n Id, hic ex, blanditiis totam animi amet delectus temporibus quae fugiat magnam, quos eaque\n dolorum a? Lorem ipsum dolor, sit amet consectetur adipisicing elit. Possimus labore unde\n minus temporibus beatae commodi et nesciunt iure in dignissimos suscipit, alias ab\n voluptatem facilis tempora numquam. Veritatis, dolorum suscipit! Lorem ipsum dolor sit,\n amet consectetur adipisicing elit. Explicabo fugiat molestias iusto, ipsum distinctio\n officia ad id ratione esse ducimus architecto deleniti illum reiciendis rerum, at\n blanditiis molestiae. Cupiditate, nobis? Lorem ipsum dolor sit amet consectetur\n adipisicing elit. Ab, magni. Aliquid inventore quaerat nemo architecto harum earum quas\n porro repudiandae explicabo repellat repellendus magni, corporis omnis laborum, velit\n dicta blanditiis. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Debitis,\n eveniet quas. Accusamus facere veritatis expedita delectus, asperiores numquam placeat\n necessitatibus assumenda, nesciunt in dolorem sit provident repellendus, voluptatem earum!\n Consequatur. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Aut earum\n asperiores aliquam magnam est delectus veritatis numquam sint porro tenetur dolores nobis,\n deleniti voluptas quaerat, quia voluptatum soluta autem perspiciatis? Lorem ipsum dolor\n sit amet consectetur adipisicing elit. Facilis possimus eaque aliquam maxime? Quidem enim,\n sed itaque at veritatis nihil officia esse qui provident ipsa adipisci necessitatibus\n officiis distinctio laborum!\n

\n
\n
\n );\n};\n\nexport default InlineBannerActivity;", + "inline-banner-critical-solid": "import {\n ActionableInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconExclamationmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerCriticalSolid() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", + "inline-banner-critical-weak": "import {\n ActionableInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconExclamationmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerCriticalWeak() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", "inline-banner-informative-weak": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconILowercaseSerifCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerInformativeWeak() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", - "text-field-enabled": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function TextFieldEnabled() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", - "help-bubble-close-button": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { HelpBubbleTrigger } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubbleCloseButton() {\n return (\n \n 열기\n \n );\n}", - "segmented-control-long-label-fixed-width": "import { SegmentedControl, SegmentedControlItem } from \"seed-design/ui/segmented-control\";\n\nexport default function SegmentedControlLongLabelFixedWidth() {\n return (\n \n 가격 높은 순\n 할인율 높은 순\n 인기 많은 순\n \n );\n}", - "tabs-alert": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsAlert() {\n return (\n
\n \n \n 라벨1\n \n 라벨2\n \n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n
\n );\n};", - "action-chip-suffix-icon": "import { IconChevronDownFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipSuffixIcon() {\n return }>라벨;\n}", - "action-button-disabled": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonDisabled() {\n return 라벨;\n}", - "callout-text-only": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutTextOnly() {\n return (\n \n \n \n \n \n );\n}", - "snackbar-avoid-overlap": "import { Flex } from \"seed-design/ui/layout\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n Snackbar,\n SnackbarAvoidOverlap,\n SnackbarProvider,\n useSnackbarAdapter,\n} from \"seed-design/ui/snackbar\";\n\nfunction Component() {\n const adapter = useSnackbarAdapter();\n\n return (\n \n \n adapter.create({\n timeout: 5000,\n onClose: () => {},\n render: () => {}} />,\n })\n }\n >\n 실행\n \n \n \n Snackbar가 이 영역과 겹치지 않게 조정됩니다. 스크롤은 무시합니다.\n \n \n
\n );\n}\n\nexport default function SnackbarPreview() {\n return (\n \n \n \n );\n}", - "extended-fab-layer-floating": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabLayerFloating() {\n return (\n }>\n 알림 설정\n \n );\n}", "inline-banner-link-label-as-child": "import { LinkInlineBanner } from \"seed-design/ui/inline-banner\";\n\nexport default function InlineBannerLinkLabelAsChild() {\n return (\n \n 자세히보기\n \n }\n linkProps={{ asChild: true }}\n />\n );\n}", - "reaction-button-small": "import { IconFaceSmileCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { ReactionButton } from \"seed-design/ui/reaction-button\";\n\nexport default function ReactionButtonSmall() {\n return (\n } size=\"small\" count={1}>\n 도움돼요\n \n );\n}", - "text-field-suffix": "import { IconWonLine } from \"@daangn/react-monochrome-icon\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Columns, Column } from \"seed-design/ui/layout\";\n\nexport default function TextFieldSuffix() {\n return (\n \n \n \n \n \n \n \n }>\n \n \n \n \n );\n}", + "inline-banner-neutral-weak": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerNeutralWeak() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", + "inline-banner-positive-weak": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconCheckmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerPositiveWeak() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", + "inline-banner-preview": "import { Stack } from \"seed-design/ui/layout\";\nimport {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\n\nexport default function InlineBannerPreview() {\n return (\n \n \n \n \n \n \n );\n}", + "inline-banner-text-only": "import { Stack } from \"seed-design/ui/layout\";\nimport {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\n\nexport default function InlineBannerTextOnly() {\n return (\n \n \n \n \n \n \n );\n}", + "inline-banner-warning-solid": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconExclamationmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWarningSolid() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", + "inline-banner-warning-weak": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconExclamationmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWarningWeak() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", + "inline-banner-with-all": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWithAll() {\n return (\n \n }\n title=\"타이틀\"\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n title=\"타이틀\"\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n title=\"타이틀\"\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n title=\"타이틀\"\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", + "inline-banner-with-icon": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWithIcon() {\n return (\n \n } description=\"사업자 정보를 등록해주세요.\" />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n } description=\"사업자 정보를 등록해주세요.\" />\n } description=\"사업자 정보를 등록해주세요.\" />\n \n );\n}", + "inline-banner-with-title-text": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWithTitleText() {\n return (\n \n \n \n \n \n \n );\n}", + "inline-preview": "import { Box, Inline } from \"seed-design/ui/layout\";\n\nexport default function InlinePreview() {\n return (\n \n \n 1\n \n \n 2\n \n \n 3\n \n \n );\n}", "manner-temp-badge-preview": "import { Stack } from \"seed-design/ui/layout\";\nimport { MannerTempBadge } from \"seed-design/ui/manner-temp-badge\";\n\nexport default function BadgePreview() {\n return (\n \n \n \n \n \n \n \n \n );\n}", - "text-field-preview": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldPreview() {\n return (\n \n \n \n );\n}", - "progress-circle-40": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircle40() {\n return ;\n}", - "skeleton-radius": "import { Skeleton } from \"seed-design/ui/skeleton\";\nimport { Flex } from \"seed-design/ui/layout\";\n\nexport default function SkeletonRadius() {\n return (\n \n \n \n \n \n \n );\n}", - "fab-preview": "import IconPlusLine from \"@daangn/react-monochrome-icon/IconPlusLine\";\nimport { Fab } from \"seed-design/ui/fab\";\n\nexport default function FabPreview() {\n return (\n \n \n \n );\n}", + "multiline-text-field-constraints": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldConstraints() {\n return (\n \n \n \n );\n}", + "multiline-text-field-disabled": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function MultilineTextFieldDisabled() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", + "multiline-text-field-enabled": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function MultilineTextFieldEnabled() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", + "multiline-text-field-fixed-height": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldSpecifiedHeight() {\n return (\n \n \n \n );\n}", + "multiline-text-field-form": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { Column, Columns, Inline, Stack } from \"seed-design/ui/layout\";\nimport { useState, useCallback, type FormEvent } from \"react\";\n\ninterface FormValues {\n bio: string;\n address: string;\n}\n\ntype FieldErrors = Record;\n\nexport default function MultilineTextFieldForm() {\n const [formValues, setFormValues] = useState({\n bio: \"\",\n address: \"\",\n });\n\n const [fieldErrors, setFieldStates] = useState({\n bio: null,\n address: null,\n });\n\n const validateForm = useCallback((): boolean => {\n let isValid = true;\n\n const newFieldErrors: FieldErrors = {\n bio: null,\n address: null,\n };\n\n // Name validation\n if (!formValues.bio) {\n newFieldErrors.bio = \"필수 입력 항목입니다\";\n isValid = false;\n }\n\n if (!formValues.address.startsWith(\"대한민국\")) {\n newFieldErrors.address = \"대한민국으로 시작해주세요\";\n isValid = false;\n }\n\n if (!formValues.address) {\n newFieldErrors.address = \"필수 입력 항목입니다\";\n isValid = false;\n }\n\n setFieldStates(newFieldErrors);\n\n return isValid;\n }, [formValues]);\n\n const handleSubmit = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n\n if (validateForm()) {\n window.alert(JSON.stringify(formValues, null, 2));\n }\n },\n [formValues, validateForm],\n );\n\n const handleReset = useCallback((event: FormEvent) => {\n event.preventDefault();\n\n setFormValues({ bio: \"\", address: \"\" });\n setFieldStates({ bio: null, address: null });\n }, []);\n\n const handleNameChange = (value: string) => {\n setFormValues((prev) => ({ ...prev, bio: value }));\n setFieldStates((prev) => ({ ...prev, name: null }));\n };\n\n const handleAddressChange = (value: string) => {\n setFormValues((prev) => ({ ...prev, address: value }));\n setFieldStates((prev) => ({ ...prev, address: null }));\n };\n\n return (\n \n \n \n handleNameChange(value)}\n {...(fieldErrors.bio && { invalid: true, errorMessage: fieldErrors.bio })}\n >\n \n \n \n \n handleAddressChange(slicedValue)}\n {...(fieldErrors.address && { invalid: true, errorMessage: fieldErrors.address })}\n >\n \n \n \n \n \n \n \n 초기화\n \n \n \n 제출\n \n \n \n );\n}", + "multiline-text-field-formatting": "import { useMemo, useState } from \"react\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldFormatting() {\n const [value, setValue] = useState(\"\");\n\n const formattedValue = useMemo(\n () =>\n value\n .split(\"\")\n .filter((char) => char !== \" \")\n .join(\"\"),\n [value],\n );\n\n return (\n setValue(value)}\n >\n \n \n );\n}", + "multiline-text-field-grapheme-count": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldGraphemeCount() {\n return (\n \n \n \n );\n}", + "multiline-text-field-large": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldLarge() {\n return (\n \n \n \n );\n}", "multiline-text-field-medium": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldMedium() {\n return (\n \n \n \n );\n}", - "callout-with-icon": "import { IconCalendarFill } from \"@daangn/react-monochrome-icon\";\nimport { Callout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWithIcon() {\n return (\n }\n description=\"기능에 대한 안내 또는 유익한 내용을 전달해요. 콜아웃은 꼭 필요한 경우에만 절제하여 사용해요.\"\n />\n );\n}", - "callout-informative": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutInformative() {\n return (\n \n \n \n \n \n );\n}", - "inline-banner-preview": "import { Stack } from \"seed-design/ui/layout\";\nimport {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\n\nexport default function InlineBannerPreview() {\n return (\n \n \n \n \n \n \n );\n}", + "multiline-text-field-optional": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldOptional() {\n return (\n \n \n \n );\n}", + "multiline-text-field-preview": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldPreview() {\n return (\n \n \n \n );\n}", + "multiline-text-field-react-hook-form": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { useController, useForm } from \"react-hook-form\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { Column, Columns, Stack } from \"seed-design/ui/layout\";\nimport { useCallback, type FormEvent, type KeyboardEvent } from \"react\";\n\ninterface FormValues {\n bio: string;\n address: string;\n}\n\nexport default function MultilineTextFieldReactHookForm() {\n const { handleSubmit, reset, control } = useForm({\n defaultValues: {\n bio: \"\",\n address: \"\",\n },\n shouldFocusError: true,\n });\n\n const { field: bioField, fieldState: bioFieldState } = useController({\n name: \"bio\",\n control,\n rules: {\n required: \"필수 입력 항목입니다\",\n },\n });\n const {\n field: { onChange: addressOnChange, ...addressField },\n fieldState: addressFieldState,\n } = useController({\n name: \"address\",\n control,\n rules: {\n required: \"필수 입력 항목입니다\",\n pattern: { value: /^대한민국/, message: \"대한민국으로 시작해주세요\" },\n },\n });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n const onMetaReturn = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === \"Enter\" && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n handleSubmit(onValid)();\n }\n },\n [handleSubmit, onValid],\n );\n\n return (\n \n \n \n \n \n \n \n \n addressOnChange(slicedValue)}\n required\n {...addressField}\n >\n \n \n \n \n \n \n \n 초기화\n \n \n \n 제출\n \n \n \n );\n}", + "multiline-text-field-read-only": "import { Column, Columns } from \"seed-design/ui/layout\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldReadOnly() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", + "multiline-text-field-required": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldRequired() {\n return (\n \n \n \n );\n}", "multiline-text-field-slicing": "import { useState } from \"react\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldSlicing() {\n const [value, setValue] = useState(\"\");\n\n return (\n setValue(slicedValue)}\n >\n \n \n );\n}", - "callout-link-label-as-child": "import { Stack } from \"seed-design/ui/layout\";\nimport { Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutLinkLabelAsChild() {\n return (\n \n \n 시도해 보기\n \n }\n linkProps={{ asChild: true }}\n />\n \n 시도해 보기\n \n }\n linkProps={{ asChild: true }}\n />\n \n );\n}", - "tabs-size-medium": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsSizeMedium() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", - "switch-disabled": "import { Switch } from \"seed-design/ui/switch\";\n\nexport default function SwitchDisabled() {\n return (\n
\n \n \n
\n );\n}", - "text-button-icon-first": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonIconFirst() {\n return (\n }>\n 추가\n \n );\n}", - "checkbox-variant": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxVariant() {\n return (\n
\n \n \n
\n );\n}", - "action-button-neutral-weak": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonNeutralWeak() {\n return 라벨;\n}", - "radio-select-box-react-hook-form": "import { Column, Columns, Stack } from \"@seed-design/react\";\nimport { useCallback, type FormEvent } from \"react\";\nimport { useController, useForm } from \"react-hook-form\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { RadioSelectBoxItem, RadioSelectBoxRoot } from \"seed-design/ui/select-box\";\n\nconst POSSIBLE_FRUIT_VALUES = [\"apple\", \"melon\", \"mango\"] as const;\n\ninterface FormValues {\n fruit: (typeof POSSIBLE_FRUIT_VALUES)[number];\n}\n\nexport default function RadioSelectBoxReactHookForm() {\n const { handleSubmit, reset, setValue, control } = useForm({\n defaultValues: {\n fruit: \"melon\",\n },\n });\n const { field } = useController({ name: \"fruit\", control });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n return (\n \n \n \n {POSSIBLE_FRUIT_VALUES.map((value) => (\n \n ))}\n \n \n \n \n \n 초기화\n \n \n \n setValue(\"fruit\", \"mango\")}\n >\n mango 선택\n \n \n \n 제출\n \n \n \n );\n}", - "control-chip-prefix-icon": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ControlChipPrefixIcon() {\n return }>라벨;\n}", - "segmented-control-disabled": "import { SegmentedControl, SegmentedControlItem } from \"seed-design/ui/segmented-control\";\n\nexport default function SegmentedControlPreview() {\n return (\n \n Hot\n New\n \n );\n}", - "text-button-neutral-subtle": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonNeutralSubtle() {\n return (\n }>\n 추가\n \n );\n}", - "chip-tabs-preview": "import * as React from \"react\";\nimport { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from \"seed-design/ui/chip-tabs\";\n\nexport default function ChipTabsPreview() {\n const [value, setValue] = React.useState(\"1\");\n return (\n <>\n setValue(value)}\n >\n \n 라벨1\n 라벨2\n 라벨3\n \n \n {value === \"1\" &&
content 1
}\n {value === \"2\" &&
content 2
}\n {value === \"3\" &&
content 3
}\n \n );\n}", + "multiline-text-field-xlarge": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldXlarge() {\n return (\n \n \n \n );\n}", + "progress-circle-24": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircle24() {\n return ;\n}", + "progress-circle-40": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircle40() {\n return ;\n}", + "progress-circle-brand": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircleBrand() {\n return ;\n}", + "progress-circle-determinate": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircleDeterminate() {\n return ;\n}", + "progress-circle-indeterminate": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCirclePreview() {\n // if you want to show an indeterminate progress circle, you can pass `undefined` or omit the `value` prop\n return ;\n}", "progress-circle-neutral": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircleNeutral() {\n return ;\n}", - "identity-placeholder-preview": "import { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\n\nexport default function IdentityPlaceholderPreview() {\n return ;\n}", - "bottom-sheet-preview": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n BottomSheetRoot,\n BottomSheetBody,\n BottomSheetContent,\n BottomSheetFooter,\n BottomSheetTrigger,\n} from \"seed-design/ui/bottom-sheet\";\n\nconst BottomSheetPreview = () => {\n return (\n \n \n Open\n \n \n {/* BottomSheetBody is simple paddingX helper. */}\n {/* If you need to omit padding, replace with or other layout you need. */}\n Content\n \n 확인\n \n \n \n );\n};\n\nexport default BottomSheetPreview;", - "flex-preview": "import { Flex } from \"seed-design/ui/layout\";\n\nexport default function FlexPreview() {\n return (\n \n \n \n 1\n \n \n 2\n \n \n \n \n 3\n \n \n 4\n \n \n \n 5\n \n \n );\n}", - "text-field-medium": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldMedium() {\n return (\n \n \n \n );\n}", - "text-button-disabled": "import { IconPenHorizlineLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonPreview() {\n return (\n }>\n 새 글\n \n );\n}", - "callout-critical": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutCritical() {\n return (\n \n \n \n \n \n );\n}", - "multiline-text-field-large": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldLarge() {\n return (\n \n \n \n );\n}", "progress-circle-preview": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCirclePreview() {\n return ;\n}", - "inline-banner-with-title-text": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWithTitleText() {\n return (\n \n \n \n \n \n \n );\n}", - "check-select-box-react-hook-form": "import { Column, Columns, Stack } from \"@seed-design/react\";\nimport { useCallback, type FormEvent } from \"react\";\nimport { useController, useForm } from \"react-hook-form\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { CheckSelectBox, CheckSelectBoxGroup } from \"seed-design/ui/select-box\";\n\nconst POSSIBLE_FRUIT_VALUES = [\"apple\", \"melon\", \"mango\"] as const;\n\ntype FormValues = Record<(typeof POSSIBLE_FRUIT_VALUES)[number], boolean>;\n\nexport default function CheckSelectBoxReactHookForm() {\n const { handleSubmit, reset, setValue, control } = useForm({\n defaultValues: {\n apple: false,\n melon: true,\n mango: false,\n },\n });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n return (\n \n \n \n {POSSIBLE_FRUIT_VALUES.map((name) => {\n const {\n field: { value, ...restProps },\n fieldState: { invalid },\n } = useController({ name, control });\n\n return (\n \n );\n })}\n \n \n \n \n \n 초기화\n \n \n \n setValue(\"mango\", true)}>\n mango 선택\n \n \n \n 제출\n \n \n \n );\n}", - "tabs-disabled": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsDisabled() {\n return (\n
\n \n \n 라벨1\n \n 라벨2\n \n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", - "checkbox-react-hook-form": "import { useController, useForm } from \"react-hook-form\";\nimport { Checkbox } from \"seed-design/ui/checkbox\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { Column, Columns, Stack } from \"seed-design/ui/layout\";\nimport { useCallback, type FormEvent } from \"react\";\n\nconst POSSIBLE_FRUIT_VALUES = [\"apple\", \"melon\", \"mango\"] as const;\n\ntype FormValues = Record<(typeof POSSIBLE_FRUIT_VALUES)[number], boolean>;\n\nexport default function CheckboxReactHookForm() {\n const { handleSubmit, reset, setValue, control } = useForm({\n defaultValues: {\n apple: false,\n melon: true,\n mango: false,\n },\n });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n return (\n \n \n {POSSIBLE_FRUIT_VALUES.map((name) => {\n const {\n field: { value, ...restProps },\n fieldState: { invalid },\n } = useController({ name, control });\n return (\n \n );\n })}\n \n \n \n \n 초기화\n \n \n \n setValue(\"mango\", true)}>\n mango 선택\n \n \n \n 제출\n \n \n \n );\n}", - "badge-as-child": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeAsChild() {\n return (\n \n \n 링크\n \n \n );\n}", - "tabs-layout-fill": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsLayoutFill() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", - "extended-fab-neutral-solid": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabNeutralSolid() {\n return (\n }>\n 알림 설정\n \n );\n}", - "callout-with-title-text": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWithTitleText() {\n return (\n \n \n \n \n \n );\n}", - "checkbox-stronger": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxStronger() {\n return ;\n}", - "action-button-neutral-outline": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonNeutralOutline() {\n return 라벨;\n}", - "switch-medium": "import { useState } from \"react\";\nimport { Switch } from \"seed-design/ui/switch\";\n\nexport default function SwitchMedium() {\n const [isChecked, setIsChecked] = useState(false);\n\n return ;\n}", - "multiline-text-field-preview": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldPreview() {\n return (\n \n \n \n );\n}", - "badge-positive": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgePositive() {\n return 라벨;\n}", - "action-chip-small": "import { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipSmall() {\n return 라벨;\n}", - "toggle-button-preview": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonPreview() {\n const [pressed, setPressed] = useState(false);\n\n return (\n \n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", - "inline-banner-warning-weak": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconExclamationmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWarningWeak() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", - "alert-dialog-neutral": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"seed-design/ui/alert-dialog\";\nimport { Column, Columns } from \"@seed-design/react\";\n\nconst AlertDialogNeutral = () => {\n return (\n // You can set z-index dialog with \"--layer-index\" custom property. useful for stackflow integration.\n \n \n 열기\n \n \n \n 제목\n 중립적인 선택지를 제공합니다.\n \n \n \n \n \n 취소\n \n \n \n \n 확인\n \n \n \n \n \n \n );\n};\n\nexport default AlertDialogNeutral;", - "text-field-slicing": "import { useState } from \"react\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldSlicing() {\n const [value, setValue] = useState(\"\");\n\n return (\n setValue(slicedValue)}\n >\n \n \n );\n}", - "action-button-critical-solid": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonCriticalSolid() {\n return 라벨;\n}", - "inline-banner-critical-solid": "import {\n ActionableInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconExclamationmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerCriticalSolid() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", - "inline-banner-positive-weak": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconCheckmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerPositiveWeak() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", - "multiline-text-field-react-hook-form": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { useController, useForm } from \"react-hook-form\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { Column, Columns, Stack } from \"seed-design/ui/layout\";\nimport { useCallback, type FormEvent, type KeyboardEvent } from \"react\";\n\ninterface FormValues {\n bio: string;\n address: string;\n}\n\nexport default function MultilineTextFieldReactHookForm() {\n const { handleSubmit, reset, control } = useForm({\n defaultValues: {\n bio: \"\",\n address: \"\",\n },\n shouldFocusError: true,\n });\n\n const { field: bioField, fieldState: bioFieldState } = useController({\n name: \"bio\",\n control,\n rules: {\n required: \"필수 입력 항목입니다\",\n },\n });\n const {\n field: { onChange: addressOnChange, ...addressField },\n fieldState: addressFieldState,\n } = useController({\n name: \"address\",\n control,\n rules: {\n required: \"필수 입력 항목입니다\",\n pattern: { value: /^대한민국/, message: \"대한민국으로 시작해주세요\" },\n },\n });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n const onMetaReturn = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === \"Enter\" && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n handleSubmit(onValid)();\n }\n },\n [handleSubmit, onValid],\n );\n\n return (\n \n \n \n \n \n \n \n \n addressOnChange(slicedValue)}\n required\n {...addressField}\n >\n \n \n \n \n \n \n \n 초기화\n \n \n \n 제출\n \n \n \n );\n}", - "callout-warning": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWarning() {\n return (\n \n \n \n \n \n );\n}", + "progress-circle-small": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCirclePreview() {\n return ;\n}", + "progress-circle-static-white": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircleStaticWhite() {\n return (\n \n \n \n );\n}", "radio-select-box-preview": "import { Stack } from \"@seed-design/react\";\nimport { RadioSelectBoxItem, RadioSelectBoxRoot } from \"seed-design/ui/select-box\";\n\nexport default function RadioSelectBoxPreview() {\n return (\n \n \n \n \n \n \n \n );\n}", - "badge-critical": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeCritical() {\n return 라벨;\n}", - "alert-dialog-preview": "import { Column, Columns } from \"@seed-design/react\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"seed-design/ui/alert-dialog\";\n\nconst AlertDialogSingle = () => {\n return (\n // You can set z-index dialog with \"--layer-index\" custom property. useful for stackflow integration.\n \n \n 열기\n \n \n \n 주의\n 이 작업은 되돌릴 수 없습니다.\n \n \n \n \n \n 취소\n \n \n \n \n 확인\n \n \n \n \n \n \n );\n};\n\nexport default AlertDialogSingle;", - "toggle-button-xsmall": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonXsmall() {\n const [pressed, setPressed] = useState(false);\n\n return (\n \n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", - "text-button-icon-last": "import { IconChevronRightLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonIconLast() {\n return (\n }>\n 추가\n \n );\n}", - "multiline-text-field-required": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldRequired() {\n return (\n \n \n \n );\n}", - "inline-banner-warning-solid": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconExclamationmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWarningSolid() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", - "multiline-text-field-enabled": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function MultilineTextFieldEnabled() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", - "callout-preview": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutPreview() {\n return (\n \n \n \n \n \n );\n}", - "badge-neutral": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeNeutral() {\n return 라벨;\n}", - "callout-with-all": "import { IconCalendarFill } from \"@daangn/react-monochrome-icon\";\nimport { Callout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWithAll() {\n return (\n }\n description=\"기능에 대한 안내 또는 유익한 내용을 전달해요. 콜아웃은 꼭 필요한 경우에만 절제하여 사용해요.\"\n linkLabel=\"시도해 보기\"\n />\n );\n}", - "text-field-grapheme-count": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldGraphemeCount() {\n return (\n \n \n \n );\n}", - "avatar-badge": "import { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\nimport { Avatar, AvatarBadge } from \"seed-design/ui/avatar\";\n\nexport default function AvatarWithBadge() {\n return (\n }\n >\n \n
\n \n \n );\n}", - "help-bubble-title-only": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { HelpBubbleTrigger } from \"seed-design/ui/help-bubble\";\n\nexport default function HelpBubbleTitleOnly() {\n return (\n \n 열기\n \n );\n}", - "callout-neutral": "import { Stack } from \"seed-design/ui/layout\";\nimport { ActionableCallout, Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutNeutral() {\n return (\n \n \n \n \n \n );\n}", - "badge-preview": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgePreview() {\n return 라벨;\n}", - "columns-preview": "import { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function ColumnsPreview() {\n return (\n \n \n 1\n \n \n Content Width\n \n \n 2\n \n \n );\n}", - "callout-with-link-label": "import { Stack } from \"seed-design/ui/layout\";\nimport { Callout, DismissibleCallout } from \"seed-design/ui/callout\";\n\nexport default function CalloutWithLinkLabel() {\n return (\n \n \n \n \n );\n}", - "tabs-standalone": "import { useState } from \"react\";\nimport { Tabs, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsStandalone() {\n const [activeTab, setActiveTab] = useState(\"1\");\n\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n {activeTab === \"1\" && (\n
\n Content 1\n
\n )}\n {activeTab === \"2\" && (\n
\n Content 2\n
\n )}\n {activeTab === \"3\" && (\n
\n Content 3\n
\n )}\n
\n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n
\n );\n};", - "inline-banner-neutral-weak": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerNeutralWeak() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", - "reaction-button-loading": "import { IconFaceSmileCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { useState } from \"react\";\nimport { ReactionButton } from \"seed-design/ui/reaction-button\";\n\nexport default function ReactionButtonLoading() {\n const [pressed, setPressed] = useState(false);\n const [loading, setLoading] = useState(false);\n\n function handleToggle() {\n setLoading(true);\n setTimeout(() => {\n setLoading(false);\n setPressed((prev) => !prev);\n }, 2000);\n }\n\n // 이벤트 핸들링이 필요할 수 있으므로 loading은 disabled를 포함하지 않습니다. 이벤트 발생을 원하지 않는 경우, disabled 속성을 추가해주세요.\n return (\n }\n loading={loading}\n pressed={pressed}\n onPressedChange={handleToggle}\n >\n 시간이 걸리는 토글\n \n );\n}", - "snackbar-positive": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { Snackbar, SnackbarProvider, useSnackbarAdapter } from \"seed-design/ui/snackbar\";\n\nfunction Component() {\n const adapter = useSnackbarAdapter();\n\n return (\n \n adapter.create({\n timeout: 5000,\n onClose: () => {},\n render: () => (\n {}}\n />\n ),\n })\n }\n >\n 실행\n \n );\n}\n\nexport default function SnackbarPositive() {\n return (\n \n \n \n );\n}", - "text-field-disabled": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function TextFieldDisabled() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", - "badge-solid": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeSolid() {\n return 라벨;\n}", - "badge-pill": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeRectangle() {\n return 라벨;\n}", - "tabs-preview": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsPreview() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "radio-select-box-react-hook-form": "import { Column, Columns, Stack } from \"@seed-design/react\";\nimport { useCallback, type FormEvent } from \"react\";\nimport { useController, useForm } from \"react-hook-form\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { RadioSelectBoxItem, RadioSelectBoxRoot } from \"seed-design/ui/select-box\";\n\nconst POSSIBLE_FRUIT_VALUES = [\"apple\", \"melon\", \"mango\"] as const;\n\ninterface FormValues {\n fruit: (typeof POSSIBLE_FRUIT_VALUES)[number];\n}\n\nexport default function RadioSelectBoxReactHookForm() {\n const { handleSubmit, reset, setValue, control } = useForm({\n defaultValues: {\n fruit: \"melon\",\n },\n });\n const { field } = useController({ name: \"fruit\", control });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n return (\n \n \n \n {POSSIBLE_FRUIT_VALUES.map((value) => (\n \n ))}\n \n \n \n \n \n 초기화\n \n \n \n setValue(\"fruit\", \"mango\")}\n >\n mango 선택\n \n \n \n 제출\n \n \n \n );\n}", "reaction-button-disabled": "import { IconFaceSmileCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { ReactionButton } from \"seed-design/ui/reaction-button\";\n\nexport default function ReactionButtonDisabled() {\n return (\n } disabled>\n 비활성\n \n );\n}", - "tabs-scroll-top": "import { RefObject, useRef, useState } from \"react\";\nimport { TabContent, TabContentList, Tabs, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsScrollTop() {\n const [currentTab, setCurrentTab] = useState(\"1\");\n const contentRefs: Record> = {\n \"1\": useRef(null),\n \"2\": useRef(null),\n };\n\n const handleTriggerClick = (value: string) => {\n if (value === currentTab) {\n contentRefs[value].current?.scrollTo({ top: 0, behavior: \"smooth\" });\n }\n };\n\n return (\n
\n \n \n handleTriggerClick(\"1\")} value=\"1\">\n 라벨1\n \n handleTriggerClick(\"2\")} value=\"2\">\n 라벨2\n \n \n \n \n Content 1\n \n \n Content 2\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren<{ height: string }>) => {\n const { height, children } = props;\n return (\n \n {children}\n \n );\n};", - "tabs-layout-hug": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsLayoutHug() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", - "text-preview": "import { Flex } from \"seed-design/ui/layout\";\nimport { Text } from \"seed-design/ui/text\";\n\nexport default function TextPreview() {\n return (\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n );\n}", - "text-field-indicator": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldIndicator() {\n return (\n \n \n \n );\n}", - "check-select-box-preview": "import { Stack } from \"@seed-design/react\";\nimport { CheckSelectBox, CheckSelectBoxGroup } from \"seed-design/ui/select-box\";\n\nexport default function CheckSelectBoxPreview() {\n return (\n \n \n \n \n \n \n \n );\n}", - "snackbar-critical": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { Snackbar, SnackbarProvider, useSnackbarAdapter } from \"seed-design/ui/snackbar\";\n\nfunction Component() {\n const adapter = useSnackbarAdapter();\n\n return (\n \n adapter.create({\n timeout: 50000000,\n onClose: () => {},\n render: () => (\n {}}\n />\n ),\n })\n }\n >\n 실행\n \n );\n}\n\nexport default function SnackbarNegative() {\n return (\n \n \n \n );\n}", - "inline-banner-critical-weak": "import {\n ActionableInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconExclamationmarkCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerCriticalWeak() {\n return (\n \n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n }\n description=\"사업자 정보를 등록해주세요.\"\n />\n \n );\n}", - "control-chip-suffix-icon": "import { IconChevronDownFill } from \"@daangn/react-monochrome-icon\";\nimport { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ControlChipSuffixIcon() {\n return }>라벨;\n}", - "tabs-fix-trigger-list": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsFixTriggerList() {\n return (\n // 600은 화면 높이라고 가정합니다.\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren<{ height: string }>) => {\n const { height, children } = props;\n return (\n \n {children}\n \n );\n};", - "control-chip-icon-only": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ControlChipIconOnly() {\n return (\n \n \n \n );\n}", - "chip-tabs-variant-neutral-solid": "import * as React from \"react\";\nimport { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from \"seed-design/ui/chip-tabs\";\n\nexport default function ChipTabsVariantNeutralSolid() {\n const [value, setValue] = React.useState(\"1\");\n return (\n <>\n setValue(value)}\n >\n \n 라벨1\n 라벨2\n 라벨3\n \n \n {value === \"1\" &&
content 1
}\n {value === \"2\" &&
content 2
}\n {value === \"3\" &&
content 3
}\n \n );\n}", + "reaction-button-loading": "import { IconFaceSmileCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { useState } from \"react\";\nimport { ReactionButton } from \"seed-design/ui/reaction-button\";\n\nexport default function ReactionButtonLoading() {\n const [pressed, setPressed] = useState(false);\n const [loading, setLoading] = useState(false);\n\n function handleToggle() {\n setLoading(true);\n setTimeout(() => {\n setLoading(false);\n setPressed((prev) => !prev);\n }, 2000);\n }\n\n // 이벤트 핸들링이 필요할 수 있으므로 loading은 disabled를 포함하지 않습니다. 이벤트 발생을 원하지 않는 경우, disabled 속성을 추가해주세요.\n return (\n }\n loading={loading}\n pressed={pressed}\n onPressedChange={handleToggle}\n >\n 시간이 걸리는 토글\n \n );\n}", + "reaction-button-preview": "import { IconFaceSmileCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { ReactionButton } from \"seed-design/ui/reaction-button\";\n\nexport default function ReactionButtonPreview() {\n return (\n } count={1}>\n 도움돼요\n \n );\n}", + "reaction-button-small": "import { IconFaceSmileCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { ReactionButton } from \"seed-design/ui/reaction-button\";\n\nexport default function ReactionButtonSmall() {\n return (\n } size=\"small\" count={1}>\n 도움돼요\n \n );\n}", + "reaction-button-xsmall": "import { IconFaceSmileCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { ReactionButton } from \"seed-design/ui/reaction-button\";\n\nexport default function ReactionButtonXsmall() {\n return (\n } size=\"xsmall\" count={1}>\n 도움돼요\n \n );\n}", + "segmented-control-disabled": "import { SegmentedControl, SegmentedControlItem } from \"seed-design/ui/segmented-control\";\n\nexport default function SegmentedControlPreview() {\n return (\n \n Hot\n New\n \n );\n}", "segmented-control-fixed-width": "import { SegmentedControl, SegmentedControlItem } from \"seed-design/ui/segmented-control\";\n\nexport default function SegmentedControlFixedWidth() {\n return (\n \n New\n Hot\n \n );\n}", - "extended-fab-small": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabSmall() {\n return (\n }>\n 알림 설정\n \n );\n}", + "segmented-control-long-label-fixed-width": "import { SegmentedControl, SegmentedControlItem } from \"seed-design/ui/segmented-control\";\n\nexport default function SegmentedControlLongLabelFixedWidth() {\n return (\n \n 가격 높은 순\n 할인율 높은 순\n 인기 많은 순\n \n );\n}", "segmented-control-long-label": "import { SegmentedControl, SegmentedControlItem } from \"seed-design/ui/segmented-control\";\n\nexport default function SegmentedControlLongLabel() {\n return (\n \n 가격 높은 순\n 할인율 높은 순\n 인기 많은 순\n \n );\n}", - "action-chip-icon-only": "import { IconPlusFill } from \"@daangn/react-monochrome-icon\";\nimport { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipIconOnly() {\n return (\n \n \n \n );\n}", - "control-chip-medium": "import { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ActionChipMedium() {\n return 라벨;\n}", - "extended-action-sheet-preview": "import { IconEyeSlashLine } from \"@daangn/react-monochrome-icon\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n ExtendedActionSheetContent,\n ExtendedActionSheetGroup,\n ExtendedActionSheetItem,\n ExtendedActionSheetRoot,\n ExtendedActionSheetTrigger,\n} from \"seed-design/ui/extended-action-sheet\";\n\nconst ExtendedActionSheetPreview = () => {\n return (\n \n \n Open\n \n \n \n } label=\"Action 1\" />\n } label=\"Action 2\" />\n } label=\"Action 3\" />\n \n \n } label=\"Action 4\" />\n }\n label=\"Action 5\"\n />\n \n \n \n );\n};\n\nexport default ExtendedActionSheetPreview;", "segmented-control-preview": "import { SegmentedControl, SegmentedControlItem } from \"seed-design/ui/segmented-control\";\n\nexport default function SegmentedControlPreview() {\n return (\n \n Hot\n New\n \n );\n}", - "chip-tabs-variant-brand-solid": "import * as React from \"react\";\nimport { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from \"seed-design/ui/chip-tabs\";\n\nexport default function ChipTabsVariantBrandSolid() {\n const [value, setValue] = React.useState(\"1\");\n return (\n <>\n setValue(value)}\n >\n \n 라벨1\n 라벨2\n 라벨3\n \n \n {value === \"1\" &&
content 1
}\n {value === \"2\" &&
content 2
}\n {value === \"3\" &&
content 3
}\n \n );\n}", - "switch-small": "import { useState } from \"react\";\nimport { Switch } from \"seed-design/ui/switch\";\n\nexport default function SwitchSmall() {\n const [isChecked, setIsChecked] = useState(false);\n\n return ;\n}", - "action-chip-medium": "import { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipMedium() {\n return 라벨;\n}", - "multiline-text-field-form": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { Column, Columns, Inline, Stack } from \"seed-design/ui/layout\";\nimport { useState, useCallback, type FormEvent } from \"react\";\n\ninterface FormValues {\n bio: string;\n address: string;\n}\n\ntype FieldErrors = Record;\n\nexport default function MultilineTextFieldForm() {\n const [formValues, setFormValues] = useState({\n bio: \"\",\n address: \"\",\n });\n\n const [fieldErrors, setFieldStates] = useState({\n bio: null,\n address: null,\n });\n\n const validateForm = useCallback((): boolean => {\n let isValid = true;\n\n const newFieldErrors: FieldErrors = {\n bio: null,\n address: null,\n };\n\n // Name validation\n if (!formValues.bio) {\n newFieldErrors.bio = \"필수 입력 항목입니다\";\n isValid = false;\n }\n\n if (!formValues.address.startsWith(\"대한민국\")) {\n newFieldErrors.address = \"대한민국으로 시작해주세요\";\n isValid = false;\n }\n\n if (!formValues.address) {\n newFieldErrors.address = \"필수 입력 항목입니다\";\n isValid = false;\n }\n\n setFieldStates(newFieldErrors);\n\n return isValid;\n }, [formValues]);\n\n const handleSubmit = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n\n if (validateForm()) {\n window.alert(JSON.stringify(formValues, null, 2));\n }\n },\n [formValues, validateForm],\n );\n\n const handleReset = useCallback((event: FormEvent) => {\n event.preventDefault();\n\n setFormValues({ bio: \"\", address: \"\" });\n setFieldStates({ bio: null, address: null });\n }, []);\n\n const handleNameChange = (value: string) => {\n setFormValues((prev) => ({ ...prev, bio: value }));\n setFieldStates((prev) => ({ ...prev, name: null }));\n };\n\n const handleAddressChange = (value: string) => {\n setFormValues((prev) => ({ ...prev, address: value }));\n setFieldStates((prev) => ({ ...prev, address: null }));\n };\n\n return (\n \n \n \n handleNameChange(value)}\n {...(fieldErrors.bio && { invalid: true, errorMessage: fieldErrors.bio })}\n >\n \n \n \n \n handleAddressChange(slicedValue)}\n {...(fieldErrors.address && { invalid: true, errorMessage: fieldErrors.address })}\n >\n \n \n \n \n \n \n \n 초기화\n \n \n \n 제출\n \n \n \n );\n}", - "multiline-text-field-optional": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldOptional() {\n return (\n \n \n \n );\n}", - "checkbox-disabled": "import { Checkbox } from \"seed-design/ui/checkbox\";\n\nexport default function CheckboxDisabled() {\n return (\n
\n \n \n \n \n
\n );\n}", - "multiline-text-field-fixed-height": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\n\nexport default function MultilineTextFieldSpecifiedHeight() {\n return (\n \n \n \n );\n}", - "multiline-text-field-disabled": "import { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function MultilineTextFieldDisabled() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", - "tabs-dynamic-height": "import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\n\nexport default function TabsDynamicHeight() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
아래 컨텐츠
\n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren<{ height: string }>) => {\n const { height, children } = props;\n return (\n \n {children}\n \n );\n};", - "progress-circle-determinate": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircleDeterminate() {\n return ;\n}", - "text-button-preview": "import { IconPenHorizlineLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonPreview() {\n return }>새 글;\n}", - "extended-fab-preview": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabPreview() {\n return }>알림 설정;\n}", - "text-field-large": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldLarge() {\n return (\n \n \n \n );\n}", - "text-field-xlarge": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldXlarge() {\n return (\n \n \n \n );\n}", - "progress-circle-static-white": "import { ProgressCircle } from \"seed-design/ui/progress-circle\";\n\nexport default function ProgressCircleStaticWhite() {\n return (\n \n \n \n );\n}", "skeleton-preview": "import { Flex } from \"seed-design/ui/layout\";\nimport { Skeleton } from \"seed-design/ui/skeleton\";\n\nexport default function SkeletonPreview() {\n return (\n \n \n \n \n \n \n \n );\n}", - "badge-medium": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeMedium() {\n return 라벨;\n}", - "badge-rectangle": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeRectangle() {\n return 라벨;\n}", + "skeleton-radius": "import { Skeleton } from \"seed-design/ui/skeleton\";\nimport { Flex } from \"seed-design/ui/layout\";\n\nexport default function SkeletonRadius() {\n return (\n \n \n \n \n \n \n );\n}", + "snackbar-avoid-overlap": "import { Flex } from \"seed-design/ui/layout\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n Snackbar,\n SnackbarAvoidOverlap,\n SnackbarProvider,\n useSnackbarAdapter,\n} from \"seed-design/ui/snackbar\";\n\nfunction Component() {\n const adapter = useSnackbarAdapter();\n\n return (\n \n \n adapter.create({\n timeout: 5000,\n onClose: () => {},\n render: () => {}} />,\n })\n }\n >\n 실행\n \n \n \n Snackbar가 이 영역과 겹치지 않게 조정됩니다. 스크롤은 무시합니다.\n \n \n \n );\n}\n\nexport default function SnackbarPreview() {\n return (\n \n \n \n );\n}", + "snackbar-critical": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { Snackbar, SnackbarProvider, useSnackbarAdapter } from \"seed-design/ui/snackbar\";\n\nfunction Component() {\n const adapter = useSnackbarAdapter();\n\n return (\n \n adapter.create({\n timeout: 50000000,\n onClose: () => {},\n render: () => (\n {}}\n />\n ),\n })\n }\n >\n 실행\n \n );\n}\n\nexport default function SnackbarNegative() {\n return (\n \n \n \n );\n}", + "snackbar-positive": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { Snackbar, SnackbarProvider, useSnackbarAdapter } from \"seed-design/ui/snackbar\";\n\nfunction Component() {\n const adapter = useSnackbarAdapter();\n\n return (\n \n adapter.create({\n timeout: 5000,\n onClose: () => {},\n render: () => (\n {}}\n />\n ),\n })\n }\n >\n 실행\n \n );\n}\n\nexport default function SnackbarPositive() {\n return (\n \n \n \n );\n}", + "snackbar-preview": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { Snackbar, SnackbarProvider, useSnackbarAdapter } from \"seed-design/ui/snackbar\";\n\nfunction Component() {\n const adapter = useSnackbarAdapter();\n\n return (\n \n adapter.create({\n timeout: 5000,\n onClose: () => {},\n render: () => {}} />,\n })\n }\n >\n 실행\n \n );\n}\n\nexport default function SnackbarPreview() {\n return (\n \n \n \n );\n}", + "stack-preview": "import { Box, Stack } from \"seed-design/ui/layout\";\n\nexport default function StackPreview() {\n return (\n \n \n 1\n \n \n 2\n \n \n 3\n \n \n );\n}", + "switch-disabled": "import { Switch } from \"seed-design/ui/switch\";\n\nexport default function SwitchDisabled() {\n return (\n
\n \n \n
\n );\n}", + "switch-medium": "import { useState } from \"react\";\nimport { Switch } from \"seed-design/ui/switch\";\n\nexport default function SwitchMedium() {\n const [isChecked, setIsChecked] = useState(false);\n\n return ;\n}", + "switch-preview": "import { useState } from \"react\";\nimport { Switch } from \"seed-design/ui/switch\";\n\nexport default function SwitchPreview() {\n const [isChecked, setIsChecked] = useState(false);\n\n return ;\n}", + "switch-small": "import { useState } from \"react\";\nimport { Switch } from \"seed-design/ui/switch\";\n\nexport default function SwitchSmall() {\n const [isChecked, setIsChecked] = useState(false);\n\n return ;\n}", + "tabs-disabled": "import { TabsRoot, TabsContent, TabsTrigger, TabsList } from \"seed-design/ui/tabs\";\n\nexport default function TabsDisabled() {\n return (\n
\n \n \n 라벨1\n \n 라벨2\n \n 라벨3\n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "tabs-dynamic-height": "import { TabsRoot, TabsContent, TabsTrigger, TabsList, TabsCarousel } from \"seed-design/ui/tabs\";\n\nexport default function TabsDynamicHeight() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
아래 컨텐츠
\n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren<{ height: string }>) => {\n const { height, children } = props;\n return (\n \n {children}\n \n );\n};", + "tabs-layout-fill": "import { TabsContent, TabsList, TabsRoot, TabsTrigger } from \"seed-design/ui/tabs\";\n\nexport default function TabsLayoutFill() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "tabs-layout-hug": "import { TabsRoot, TabsContent, TabsTrigger, TabsList } from \"seed-design/ui/tabs\";\n\nexport default function TabsLayoutHug() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "tabs-notification": "import { TabsRoot, TabsContent, TabsTrigger, TabsList } from \"seed-design/ui/tabs\";\n\nexport default function TabsNotification() {\n return (\n
\n \n \n 라벨1\n \n 라벨2\n \n 라벨3\n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "tabs-preview": "import { TabsRoot, TabsContent, TabsTrigger, TabsList } from \"seed-design/ui/tabs\";\n\nexport default function TabsPreview() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "tabs-scroll-top": "import { RefObject, useRef, useState } from \"react\";\nimport { TabsCarousel, TabsContent, TabsList, TabsRoot, TabsTrigger } from \"seed-design/ui/tabs\";\n\nexport default function TabsScrollTop() {\n const [currentTab, setCurrentTab] = useState(\"1\");\n const contentRefs: Record> = {\n \"1\": useRef(null),\n \"2\": useRef(null),\n };\n\n const handleTriggerClick = (value: string) => {\n if (value === currentTab) {\n contentRefs[value].current?.scrollTo({ top: 0, behavior: \"smooth\" });\n }\n };\n\n return (\n
\n \n \n handleTriggerClick(\"1\")} value=\"1\">\n 라벨1\n \n handleTriggerClick(\"2\")} value=\"2\">\n 라벨2\n \n \n \n \n Content 1\n \n \n Content 2\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren<{ height: string }>) => {\n const { height, children } = props;\n return (\n \n {children}\n \n );\n};", + "tabs-size-medium": "import { TabsContent, TabsList, TabsRoot, TabsTrigger } from \"seed-design/ui/tabs\";\n\nexport default function TabsSizeMedium() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "tabs-size-small": "import { TabsRoot, TabsTrigger, TabsList, TabsContent } from \"seed-design/ui/tabs\";\n\nexport default function TabsSizeSmall() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "tabs-standalone": "import { useState } from \"react\";\nimport { TabsRoot, TabsList, TabsTrigger } from \"seed-design/ui/tabs\";\n\nexport default function TabsStandalone() {\n const [activeTab, setActiveTab] = useState(\"1\");\n\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n {activeTab === \"1\" && (\n
\n Content 1\n
\n )}\n {activeTab === \"2\" && (\n
\n Content 2\n
\n )}\n {activeTab === \"3\" && (\n
\n Content 3\n
\n )}\n
\n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "tabs-sticky-list": "import { TabsContent, TabsList, TabsRoot, TabsTrigger } from \"seed-design/ui/tabs\";\n\nexport default function TabsStickyList() {\n return (\n // 600은 화면 높이라고 가정합니다.\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren<{ height: string }>) => {\n const { height, children } = props;\n return (\n \n {children}\n \n );\n};", + "tabs-swipeable": "import { TabsRoot, TabsList, TabsTrigger, TabsCarousel, TabsContent } from \"seed-design/ui/tabs\";\n\nexport default function TabsSwipeable() {\n return (\n
\n \n \n 라벨1\n 라벨2\n 라벨3\n \n \n \n Content 1\n \n \n Content 2\n \n \n Content 3\n \n \n \n
\n );\n}\n\nconst Content = (props: React.PropsWithChildren) => {\n return (\n \n {props.children}\n \n );\n};", + "text-button-brand": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonBrand() {\n return (\n }>\n 추가\n \n );\n}", "text-button-critical": "import { IconTrashcanLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonCritical() {\n return (\n }>\n 삭제\n \n );\n}", - "text-field-both-affixes": "import { IconPlusCircleLine, IconWonLine } from \"@daangn/react-monochrome-icon\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Columns, Column } from \"seed-design/ui/layout\";\n\nexport default function TextFieldSuffix() {\n return (\n \n \n \n \n \n \n \n }\n suffixIcon={}\n >\n \n \n \n \n );\n}", - "action-sheet-preview": "import {\n ActionSheetContent,\n ActionSheetItem,\n ActionSheetRoot,\n ActionSheetTrigger,\n} from \"seed-design/ui/action-sheet\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\n\nconst ActionSheetPreview = () => {\n return (\n \n \n Open\n \n \n \n \n \n \n \n );\n};\n\nexport default ActionSheetPreview;", - "inline-banner-text-only": "import { Stack } from \"seed-design/ui/layout\";\nimport {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\n\nexport default function InlineBannerTextOnly() {\n return (\n \n \n \n \n \n \n );\n}", + "text-button-disabled": "import { IconPenHorizlineLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonPreview() {\n return (\n }>\n 새 글\n \n );\n}", + "text-button-icon-first": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonIconFirst() {\n return (\n }>\n 추가\n \n );\n}", + "text-button-icon-last": "import { IconChevronRightLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonIconLast() {\n return (\n }>\n 추가\n \n );\n}", + "text-button-large": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonLarge() {\n return (\n } size=\"large\">\n 추가\n \n );\n}", + "text-button-medium": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonMedium() {\n return (\n } size=\"medium\">\n 추가\n \n );\n}", + "text-button-neutral-subtle": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonNeutralSubtle() {\n return (\n }>\n 추가\n \n );\n}", "text-button-neutral": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonNeutral() {\n return (\n }>\n 추가\n \n );\n}", + "text-button-preview": "import { IconPenHorizlineLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonPreview() {\n return }>새 글;\n}", + "text-button-small": "import { IconPlusCircleLine } from \"@daangn/react-monochrome-icon\";\nimport { TextButton } from \"seed-design/ui/text-button\";\n\nexport default function TextButtonSmall() {\n return (\n } size=\"small\">\n 추가\n \n );\n}", + "text-field-both-affixes": "import { IconPlusCircleLine, IconWonLine } from \"@daangn/react-monochrome-icon\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Columns, Column } from \"seed-design/ui/layout\";\n\nexport default function TextFieldSuffix() {\n return (\n \n \n \n \n \n \n \n }\n suffixIcon={}\n >\n \n \n \n \n );\n}", + "text-field-disabled": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function TextFieldDisabled() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", + "text-field-enabled": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Column, Columns } from \"seed-design/ui/layout\";\n\nexport default function TextFieldEnabled() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", + "text-field-form": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { useState, useCallback, type FormEvent } from \"react\";\nimport { Column, Columns, Stack } from \"seed-design/ui/layout\";\n\ninterface FormValues {\n name: string;\n address: string;\n}\n\ntype FieldErrors = Record;\n\nexport default function TextFieldForm() {\n const [formValues, setFormValues] = useState({\n name: \"\",\n address: \"\",\n });\n\n const [fieldErrors, setFieldStates] = useState({\n name: null,\n address: null,\n });\n\n const validateForm = useCallback((): boolean => {\n let isValid = true;\n\n const newFieldErrors: FieldErrors = {\n name: null,\n address: null,\n };\n\n // Name validation\n if (!formValues.name) {\n newFieldErrors.name = \"필수 입력 항목입니다\";\n isValid = false;\n }\n\n if (!formValues.address.startsWith(\"대한민국\")) {\n newFieldErrors.address = \"대한민국으로 시작해주세요\";\n isValid = false;\n }\n\n if (!formValues.address) {\n newFieldErrors.address = \"필수 입력 항목입니다\";\n isValid = false;\n }\n\n setFieldStates(newFieldErrors);\n\n return isValid;\n }, [formValues]);\n\n const handleSubmit = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n\n if (validateForm()) {\n window.alert(JSON.stringify(formValues, null, 2));\n }\n },\n [formValues, validateForm],\n );\n\n const handleReset = useCallback((event: FormEvent) => {\n event.preventDefault();\n\n setFormValues({ name: \"\", address: \"\" });\n setFieldStates({ name: null, address: null });\n }, []);\n\n const handleNameChange = (value: string) => {\n setFormValues((prev) => ({ ...prev, name: value }));\n setFieldStates((prev) => ({ ...prev, name: null }));\n };\n\n const handleAddressChange = (value: string) => {\n setFormValues((prev) => ({ ...prev, address: value }));\n setFieldStates((prev) => ({ ...prev, address: null }));\n };\n\n return (\n \n \n \n handleNameChange(value)}\n {...(fieldErrors.name && { invalid: true, errorMessage: fieldErrors.name })}\n >\n \n \n \n \n handleAddressChange(slicedValue)}\n {...(fieldErrors.address && { invalid: true, errorMessage: fieldErrors.address })}\n >\n \n \n \n \n \n \n \n 초기화\n \n \n \n 제출\n \n \n \n );\n}", + "text-field-grapheme-count": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldGraphemeCount() {\n return (\n \n \n \n );\n}", + "text-field-indicator": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldIndicator() {\n return (\n \n \n \n );\n}", + "text-field-large": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldLarge() {\n return (\n \n \n \n );\n}", + "text-field-medium": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldMedium() {\n return (\n \n \n \n );\n}", + "text-field-number-formatting": "import { useMemo, useState } from \"react\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldNumberFormatting() {\n const [value, setValue] = useState(\"1000\");\n\n const formattedValue = useMemo(() => {\n if (value === \"\") return value;\n\n const number = Number(value.replace(/,/g, \"\"));\n if (Number.isNaN(number)) return \"\";\n\n return number.toLocaleString();\n }, [value]);\n\n return (\n setValue(value)}\n >\n \n \n );\n}", "text-field-prefix": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { IconMagnifyingglassLine } from \"@daangn/react-monochrome-icon\";\nimport { Columns, Column } from \"seed-design/ui/layout\";\n\nexport default function TextFieldPrefix() {\n return (\n \n \n \n \n \n \n \n }\n >\n \n \n \n \n );\n}", - "alert-dialog-critical": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport {\n AlertDialogAction,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogRoot,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"seed-design/ui/alert-dialog\";\nimport { Column, Columns } from \"@seed-design/react\";\n\nconst AlertDialogCritical = () => {\n return (\n // You can set z-index dialog with \"--layer-index\" custom property. useful for stackflow integration.\n \n \n 열기\n \n \n \n 제목\n 파괴적, 비가역적 작업을 경고합니다.\n \n \n \n \n \n 취소\n \n \n \n \n 확인\n \n \n \n \n \n \n );\n};\n\nexport default AlertDialogCritical;", + "text-field-preview": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldPreview() {\n return (\n \n \n \n );\n}", + "text-field-react-hook-form": "import { ActionButton } from \"seed-design/ui/action-button\";\nimport { useController, useForm } from \"react-hook-form\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { useCallback, type FormEvent } from \"react\";\nimport { Column, Columns, Stack } from \"seed-design/ui/layout\";\n\ninterface FormValues {\n name: string;\n address: string;\n}\n\nexport default function TextFieldReactHookForm() {\n const { handleSubmit, reset, control } = useForm({\n defaultValues: {\n name: \"\",\n address: \"\",\n },\n });\n\n const { field: nameField, fieldState: nameFieldState } = useController({\n name: \"name\",\n control,\n rules: {\n required: \"필수 입력 항목입니다\",\n },\n });\n const {\n field: { onChange: addressOnChange, ...addressField },\n fieldState: addressFieldState,\n } = useController({\n name: \"address\",\n control,\n rules: {\n required: \"필수 입력 항목입니다\",\n pattern: { value: /^대한민국/, message: \"대한민국으로 시작해주세요\" },\n },\n });\n\n const onValid = useCallback((data: FormValues) => {\n window.alert(JSON.stringify(data, null, 2));\n }, []);\n\n const onReset = useCallback(\n (event: FormEvent) => {\n event.preventDefault();\n reset();\n },\n [reset],\n );\n\n return (\n \n \n \n \n \n \n \n \n addressOnChange(slicedValue)}\n required\n {...addressField}\n >\n \n \n \n \n \n \n \n 초기화\n \n \n \n 제출\n \n \n \n );\n}", + "text-field-read-only": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Columns, Column } from \"seed-design/ui/layout\";\n\nexport default function TextFieldReadOnly() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n );\n}", + "text-field-slicing": "import { useState } from \"react\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldSlicing() {\n const [value, setValue] = useState(\"\");\n\n return (\n setValue(slicedValue)}\n >\n \n \n );\n}", + "text-field-suffix": "import { IconWonLine } from \"@daangn/react-monochrome-icon\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\nimport { Columns, Column } from \"seed-design/ui/layout\";\n\nexport default function TextFieldSuffix() {\n return (\n \n \n \n \n \n \n \n }>\n \n \n \n \n );\n}", + "text-field-xlarge": "import { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldXlarge() {\n return (\n \n \n \n );\n}", + "text-preview": "import { Flex } from \"seed-design/ui/layout\";\nimport { Text } from \"seed-design/ui/text\";\n\nexport default function TextPreview() {\n return (\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n 다람쥐 헌 쳇바퀴에 타고파\n \n \n );\n}", + "toggle-button-brand-solid": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonBrandSolid() {\n const [pressed, setPressed] = useState(false);\n\n return (\n \n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", + "toggle-button-disabled": "import { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonDisabled() {\n return 비활성;\n}", + "toggle-button-loading": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonLoading() {\n const [pressed, setPressed] = useState(false);\n const [loading, setLoading] = useState(false);\n\n function handleToggle() {\n setLoading(true);\n setTimeout(() => {\n setLoading(false);\n setPressed((prev) => !prev);\n }, 2000);\n }\n\n // 이벤트 핸들링이 필요할 수 있으므로 loading은 disabled를 포함하지 않습니다. 이벤트 발생을 원하지 않는 경우, disabled 속성을 추가해주세요.\n return (\n \n 시간이 걸리는 토글\n \n );\n}", + "toggle-button-neutral-weak": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonBrandSolid() {\n const [pressed, setPressed] = useState(false);\n\n return (\n \n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", + "toggle-button-prefix-icon": "import { IconCheckmarkLine, IconPlusLine } from \"@daangn/react-monochrome-icon\";\nimport { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonPrefixIcon() {\n const [pressed, setPressed] = useState(false);\n\n return (\n : }\n pressed={pressed}\n onPressedChange={setPressed}\n >\n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", + "toggle-button-preview": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonPreview() {\n const [pressed, setPressed] = useState(false);\n\n return (\n \n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", "toggle-button-small": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonSmall() {\n const [pressed, setPressed] = useState(false);\n\n return (\n \n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", - "inline-preview": "import { Box, Inline } from \"seed-design/ui/layout\";\n\nexport default function InlinePreview() {\n return (\n \n \n 1\n \n \n 2\n \n \n 3\n \n \n );\n}", - "box-preview": "import { Box } from \"seed-design/ui/layout\";\n\nexport default function BoxPreview() {\n return (\n \n Box Example\n \n );\n}", - "text-field-number-formatting": "import { useMemo, useState } from \"react\";\nimport { TextField, TextFieldInput } from \"seed-design/ui/text-field\";\n\nexport default function TextFieldNumberFormatting() {\n const [value, setValue] = useState(\"1000\");\n\n const formattedValue = useMemo(() => {\n if (value === \"\") return value;\n\n const number = Number(value.replace(/,/g, \"\"));\n if (Number.isNaN(number)) return \"\";\n\n return number.toLocaleString();\n }, [value]);\n\n return (\n setValue(value)}\n >\n \n \n );\n}", - "action-button-preview": "import { ActionButton } from \"seed-design/ui/action-button\";\n\nexport default function ActionButtonPreview() {\n return 라벨;\n}", - "avatar-stack": "import { Avatar, AvatarStack } from \"seed-design/ui/avatar\";\nimport { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\n\nexport default function AvatarStackExample() {\n return (\n \n }\n />\n }\n />\n }\n />\n }\n />\n \n );\n}", - "app-screen-transparent-bar": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport {\n AppBar,\n AppBarCloseButton,\n AppBarIconButton,\n AppBarLeft,\n AppBarMain,\n AppBarRight,\n} from \"seed-design/ui/app-bar\";\nimport { AppScreen, AppScreenContent } from \"seed-design/ui/app-screen\";\nimport { Flex } from \"seed-design/ui/layout\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"app-screen-transparent-bar\": unknown;\n }\n}\n\nconst AppScreenTransparentBarActivity: ActivityComponentType<\"app-screen-transparent-bar\"> = () => {\n return (\n \n \n \n \n \n Preview\n \n \n \n \n \n \n \n \n Preview\n \n \n \n );\n};\n\nexport default AppScreenTransparentBarActivity;", - "control-chip-preview": "import { ControlChip } from \"seed-design/ui/control-chip\";\n\nexport default function ControlChipPreview() {\n return 라벨;\n}", - "action-chip-preview": "import { ActionChip } from \"seed-design/ui/action-chip\";\n\nexport default function ActionChipPreview() {\n return 라벨;\n}", - "extended-fab-medium": "import { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\n\nexport default function ExtendedFabMedium() {\n return (\n }>\n 알림 설정\n \n );\n}", - "inline-banner-with-icon": "import {\n ActionableInlineBanner,\n DismissibleInlineBanner,\n InlineBanner,\n LinkInlineBanner,\n} from \"seed-design/ui/inline-banner\";\nimport { IconBellFill } from \"@daangn/react-monochrome-icon\";\nimport { Stack } from \"seed-design/ui/layout\";\n\nexport default function InlineBannerWithIcon() {\n return (\n \n } description=\"사업자 정보를 등록해주세요.\" />\n }\n description=\"사업자 정보를 등록해주세요.\"\n linkLabel=\"자세히보기\"\n />\n } description=\"사업자 정보를 등록해주세요.\" />\n } description=\"사업자 정보를 등록해주세요.\" />\n \n );\n}", - "badge-weak": "import { Badge } from \"seed-design/ui/badge\";\n\nexport default function BadgeWeak() {\n return 라벨;\n}", - "demo/index": "import { useState } from \"react\";\nimport { type ActivityComponentType } from \"@stackflow/react/future\";\nimport { AppBar, AppBarMain } from \"seed-design/ui/app-bar\";\nimport { AppScreen, AppScreenContent } from \"seed-design/ui/app-screen\";\nimport { Tabs, TabTrigger, TabTriggerList } from \"seed-design/ui/tabs\";\nimport { ErrorState } from \"seed-design/ui/error-state\";\nimport { SnackbarProvider } from \"seed-design/ui/snackbar\";\nimport { Recommendations } from \"@/components/example/demo/tabs/recommendations\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"demo/index\": unknown;\n }\n}\n\nconst TABS = [\n { label: \"추천\", value: \"recommendations\" },\n { label: \"구독\", value: \"subscriptions\" },\n] as const satisfies {\n label: string;\n value: string;\n}[];\n\ntype Tab = (typeof TABS)[number][\"value\"];\n\nconst DemoActivity: ActivityComponentType<\"demo/index\"> = () => {\n const [tab, setTab] = useState(\"recommendations\");\n\n return (\n \n \n dangerouslySetInnerHTML={{\n __html: \"::-webkit-scrollbar{display:none}\",\n }}\n />\n \n \n Demo\n \n \n setTab(value as Tab)}\n layout=\"fill\"\n size=\"medium\"\n fixTriggerList\n style={{ height: \"100%\", overflowY: \"auto\" }}\n >\n \n {TABS.map(({ label, value }) => (\n \n {label}\n \n ))}\n \n {tab === \"recommendations\" && }\n {tab === \"subscriptions\" && (\n setTab(\"recommendations\"),\n }}\n />\n )}\n \n \n \n \n );\n};\n\nexport default DemoActivity;", - "demo/article-detail": "import { CATEGORIES, type Article } from \"@/components/example/demo/data\";\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport { AppScreen, AppScreenContent } from \"seed-design/ui/app-screen\";\nimport {\n AppBar,\n AppBarBackButton,\n AppBarCloseButton,\n AppBarRight,\n AppBarLeft,\n} from \"seed-design/ui/app-bar\";\nimport { Stack, Columns, Column, Box } from \"seed-design/ui/layout\";\nimport { Text } from \"seed-design/ui/text\";\nimport { Badge } from \"seed-design/ui/badge\";\nimport { SegmentedControl, SegmentedControlItem } from \"seed-design/ui/segmented-control\";\nimport { Callout } from \"seed-design/ui/callout\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { ErrorState } from \"seed-design/ui/error-state\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { Skeleton } from \"seed-design/ui/skeleton\";\nimport { IconILowercaseSerifCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { ArticleAuthor } from \"./components/article-author\";\nimport { formatDate } from \"@/components/example/demo/utils/date\";\nimport { useState } from \"react\";\n\nimport img from \"@/public/penguin.webp\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"demo/article-detail\": {\n article: Article;\n };\n }\n}\n\nconst SEGMENTS = [\n { value: \"popular\", label: \"인기\" },\n { value: \"latest\", label: \"최근\" },\n] as const satisfies { value: string; label: string }[];\n\nconst DemoArticleDetail: ActivityComponentType<\"demo/article-detail\"> = ({\n params: { article },\n}) => {\n const categoryName = CATEGORIES.find((c) => c.id === article.categoryId)?.name;\n const [isImageLoading, setIsImageLoading] = useState(true);\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n setIsImageLoading(false)}\n style={{ position: \"absolute\", zIndex: 1 }}\n />\n {isImageLoading && }\n \n \n \n {article.isPopular && (\n \n 인기\n \n )}\n \n \n {article.title}\n \n \n {article.content}\n \n \n \n \n \n \n \n \n {categoryName} ⸱ {formatDate(article.createdAt)}\n \n \n \n \n \n }\n />\n \n {SEGMENTS.map((tab) => (\n \n {tab.label}\n \n ))}\n \n \n \n \n \n \n \n 게시\n \n \n \n \n \n );\n};\n\nexport default DemoArticleDetail;", - "demo/tabs/recommendations": "import { useMemo, useState } from \"react\";\nimport { IconChevronDownFill, IconPenHorizlineFill } from \"@daangn/react-monochrome-icon\";\n\nimport { Flex, Inline, Stack } from \"seed-design/ui/layout\";\nimport { ControlChip } from \"seed-design/ui/control-chip\";\nimport {\n BottomSheetBody,\n BottomSheetRoot,\n BottomSheetContent,\n BottomSheetFooter,\n BottomSheetTrigger,\n} from \"seed-design/ui/bottom-sheet\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { Snackbar, useSnackbarAdapter } from \"seed-design/ui/snackbar\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\nimport { ARTICLES, CATEGORIES, type Category } from \"@/components/example/demo/data\";\nimport { ArticleListItem } from \"@/components/example/demo/components/article-list-item\";\n\nconst FILTERS = [\n { label: \"카테고리\", value: \"category\" },\n { label: \"동네\", value: \"location\" },\n { label: \"작성자\", value: \"author\" },\n { label: \"작성 시간\", value: \"createdAt\" },\n] as const satisfies {\n label: string;\n value: string;\n}[];\n\ntype Filter = (typeof FILTERS)[number][\"value\"];\n\nexport function Recommendations() {\n const [currentFilterBottomSheet, setCurrentFilterBottomSheet] = useState(null);\n\n const defaultFilters = useMemo(\n () => ({\n category: [],\n location: [],\n author: [],\n createdAt: [],\n }),\n [],\n );\n\n const [selectedFilters, setSelectedFilters] = useState>(defaultFilters);\n\n const adapter = useSnackbarAdapter();\n\n const onUnavailableFilterClick = () =>\n adapter.create({\n render: () => (\n \n ),\n });\n\n const filteredArticles = useMemo(() => {\n let filtered = ARTICLES;\n\n if (selectedFilters.category?.length) {\n filtered = ARTICLES.filter((article) =>\n selectedFilters.category?.includes(article.categoryId),\n );\n }\n\n // XXX: Add more filters if needed\n\n return filtered;\n }, [selectedFilters]);\n\n const handleFilterConfirm = (filter: Filter, values: string[]) => {\n setSelectedFilters((prev) => ({ ...prev, [filter]: values }));\n };\n\n return (\n \n }\n style={{ position: \"fixed\", insetBlockEnd: \"16px\", insetInlineEnd: \"16px\" }}\n >\n 글쓰기\n \n \n {FILTERS.map(({ label, value }) => (\n setCurrentFilterBottomSheet(open ? value : null)}\n >\n {value === \"category\" ? (\n \n }\n onClick={value !== \"category\" ? onUnavailableFilterClick : undefined}\n >\n {selectedFilters[value]?.length\n ? selectedFilters[value]\n .map((id) => CATEGORIES.find((c) => c.id === id)?.name)\n .join(\", \") || label\n : label}\n \n \n ) : (\n }\n onClick={onUnavailableFilterClick}\n >\n {label}\n \n )}\n setCurrentFilterBottomSheet(null)}\n onConfirm={(values) => handleFilterConfirm(value, values)}\n />\n \n ))}\n \n \n {filteredArticles\n .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())\n .map((article) => (\n
  • \n \n
  • \n ))}\n
    \n
    \n );\n}\n\nexport function FilterBottomSheet({\n filter,\n currentFilter,\n onClose,\n onConfirm,\n}: {\n filter: string;\n currentFilter: string[];\n onClose: () => void;\n onConfirm: (values: string[]) => void;\n}) {\n const options = useMemo(() => {\n switch (filter) {\n case \"category\":\n return CATEGORIES;\n // Add more cases for other filters if needed\n default:\n return [];\n }\n }, [filter]);\n\n const [selectedOptions, setSelectedOptions] = useState(currentFilter);\n\n return (\n f.value === filter)?.label}>\n \n \n {options.map((option: Category) => (\n \n setSelectedOptions((prev) =>\n checked ? [...prev, option.id] : prev.filter((id) => id !== option.id),\n )\n }\n >\n {option.name}\n \n ))}\n \n \n \n {\n onConfirm(selectedOptions);\n onClose();\n }}\n >\n 완료\n \n \n \n );\n}", - "demo/components/article-list-item": "import { useFlow } from \"@stackflow/react/future\";\nimport { Inline, Stack } from \"seed-design/ui/layout\";\nimport { Text } from \"seed-design/ui/text\";\nimport { Badge } from \"seed-design/ui/badge\";\nimport { CATEGORIES, type Article } from \"@/components/example/demo/data\";\nimport { ArticleAuthor } from \"@/components/example/demo/components/article-author\";\nimport { formatDate } from \"@/components/example/demo/utils/date\";\n\ntype ArticleProps = Article & {};\n\nexport function ArticleListItem(article: ArticleProps) {\n const { title, content, author, categoryId, createdAt, isPopular } = article;\n const categoryName = CATEGORIES.find((c) => c.id === categoryId)?.name;\n const { push } = useFlow();\n\n return (\n push(\"demo/article-detail\", { article })}\n style={{ textAlign: \"start\" }}\n gap=\"s2_5\"\n paddingX=\"spacingX.globalGutter\"\n paddingY=\"s1\"\n >\n \n \n \n \n \n \n {title}\n \n \n {content}\n \n \n \n {isPopular && (\n \n 인기\n \n )}\n \n {categoryName} ⸱ 서초2동 ⸱ {formatDate(createdAt)}\n \n \n \n \n );\n}", - "demo/components/article-author": "import { Avatar } from \"seed-design/ui/avatar\";\nimport { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\nimport { Text } from \"seed-design/ui/text\";\nimport { Inline } from \"seed-design/ui/layout\";\n\nexport function ArticleAuthor({ author }: { author: string }) {\n return (\n \n }\n size=\"20\"\n style={{ zIndex: -1 }}\n />\n \n {author}\n \n \n );\n}" + "toggle-button-xsmall": "import { useState } from \"react\";\nimport { ToggleButton } from \"seed-design/ui/toggle-button\";\n\nexport default function ToggleButtonXsmall() {\n const [pressed, setPressed] = useState(false);\n\n return (\n \n {pressed ? \"선택됨\" : \"미선택\"}\n \n );\n}", + "demo\\article-detail": "import { CATEGORIES, type Article } from \"@/components/example/demo/data\";\nimport type { ActivityComponentType } from \"@stackflow/react/future\";\nimport { AppScreen, AppScreenContent } from \"seed-design/ui/app-screen\";\nimport {\n AppBar,\n AppBarBackButton,\n AppBarCloseButton,\n AppBarRight,\n AppBarLeft,\n} from \"seed-design/ui/app-bar\";\nimport { Stack, Columns, Column, Box } from \"seed-design/ui/layout\";\nimport { Text } from \"seed-design/ui/text\";\nimport { Badge } from \"seed-design/ui/badge\";\nimport { SegmentedControl, SegmentedControlItem } from \"seed-design/ui/segmented-control\";\nimport { Callout } from \"seed-design/ui/callout\";\nimport { TextField, TextFieldTextarea } from \"seed-design/ui/text-field\";\nimport { ErrorState } from \"seed-design/ui/error-state\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { Skeleton } from \"seed-design/ui/skeleton\";\nimport { IconILowercaseSerifCircleFill } from \"@daangn/react-monochrome-icon\";\nimport { ArticleAuthor } from \"./components/article-author\";\nimport { formatDate } from \"@/components/example/demo/utils/date\";\nimport { useState } from \"react\";\n\nimport img from \"@/public/penguin.webp\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"demo/article-detail\": {\n article: Article;\n };\n }\n}\n\nconst SEGMENTS = [\n { value: \"popular\", label: \"인기\" },\n { value: \"latest\", label: \"최근\" },\n] as const satisfies { value: string; label: string }[];\n\nconst DemoArticleDetail: ActivityComponentType<\"demo/article-detail\"> = ({\n params: { article },\n}) => {\n const categoryName = CATEGORIES.find((c) => c.id === article.categoryId)?.name;\n const [isImageLoading, setIsImageLoading] = useState(true);\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n setIsImageLoading(false)}\n style={{ position: \"absolute\", zIndex: 1 }}\n />\n {isImageLoading && }\n \n \n \n {article.isPopular && (\n \n 인기\n \n )}\n \n \n {article.title}\n \n \n {article.content}\n \n \n \n \n \n \n \n \n {categoryName} ⸱ {formatDate(article.createdAt)}\n \n \n \n \n \n }\n />\n \n {SEGMENTS.map((tab) => (\n \n {tab.label}\n \n ))}\n \n \n \n \n \n \n \n 게시\n \n \n \n \n \n );\n};\n\nexport default DemoArticleDetail;", + "demo\\index": "import { useState } from \"react\";\nimport { type ActivityComponentType } from \"@stackflow/react/future\";\nimport { AppBar, AppBarMain } from \"seed-design/ui/app-bar\";\nimport { AppScreen, AppScreenContent } from \"seed-design/ui/app-screen\";\nimport { TabsRoot, TabsTrigger, TabsList } from \"seed-design/ui/tabs\";\nimport { ErrorState } from \"seed-design/ui/error-state\";\nimport { SnackbarProvider } from \"seed-design/ui/snackbar\";\nimport { Recommendations } from \"@/components/example/demo/tabs/recommendations\";\n\ndeclare module \"@stackflow/config\" {\n interface Register {\n \"demo/index\": unknown;\n }\n}\n\nconst TABS = [\n { label: \"추천\", value: \"recommendations\" },\n { label: \"구독\", value: \"subscriptions\" },\n] as const satisfies {\n label: string;\n value: string;\n}[];\n\ntype Tab = (typeof TABS)[number][\"value\"];\n\nconst DemoActivity: ActivityComponentType<\"demo/index\"> = () => {\n const [tab, setTab] = useState(\"recommendations\");\n\n return (\n \n \n dangerouslySetInnerHTML={{\n __html: \"::-webkit-scrollbar{display:none}\",\n }}\n />\n \n \n Demo\n \n \n setTab(value as Tab)}\n triggerLayout=\"fill\"\n size=\"medium\"\n stickyList\n style={{ height: \"100%\", overflowY: \"auto\" }}\n >\n \n {TABS.map(({ label, value }) => (\n \n {label}\n \n ))}\n \n {tab === \"recommendations\" && }\n {tab === \"subscriptions\" && (\n setTab(\"recommendations\"),\n }}\n />\n )}\n \n \n \n \n );\n};\n\nexport default DemoActivity;", + "demo\\components\\article-author": "import { Avatar } from \"seed-design/ui/avatar\";\nimport { IdentityPlaceholder } from \"seed-design/ui/identity-placeholder\";\nimport { Text } from \"seed-design/ui/text\";\nimport { Inline } from \"seed-design/ui/layout\";\n\nexport function ArticleAuthor({ author }: { author: string }) {\n return (\n \n }\n size=\"20\"\n style={{ zIndex: -1 }}\n />\n \n {author}\n \n \n );\n}", + "demo\\components\\article-list-item": "import { useFlow } from \"@stackflow/react/future\";\nimport { Inline, Stack } from \"seed-design/ui/layout\";\nimport { Text } from \"seed-design/ui/text\";\nimport { Badge } from \"seed-design/ui/badge\";\nimport { CATEGORIES, type Article } from \"@/components/example/demo/data\";\nimport { ArticleAuthor } from \"@/components/example/demo/components/article-author\";\nimport { formatDate } from \"@/components/example/demo/utils/date\";\n\ntype ArticleProps = Article & {};\n\nexport function ArticleListItem(article: ArticleProps) {\n const { title, content, author, categoryId, createdAt, isPopular } = article;\n const categoryName = CATEGORIES.find((c) => c.id === categoryId)?.name;\n const { push } = useFlow();\n\n return (\n push(\"demo/article-detail\", { article })}\n style={{ textAlign: \"start\" }}\n gap=\"s2_5\"\n paddingX=\"spacingX.globalGutter\"\n paddingY=\"s1\"\n >\n \n \n \n \n \n \n {title}\n \n \n {content}\n \n \n \n {isPopular && (\n \n 인기\n \n )}\n \n {categoryName} ⸱ 서초2동 ⸱ {formatDate(createdAt)}\n \n \n \n \n );\n}", + "demo\\tabs\\recommendations": "import { useMemo, useState } from \"react\";\nimport { IconChevronDownFill, IconPenHorizlineFill } from \"@daangn/react-monochrome-icon\";\n\nimport { Flex, Inline, Stack } from \"seed-design/ui/layout\";\nimport { ControlChip } from \"seed-design/ui/control-chip\";\nimport {\n BottomSheetBody,\n BottomSheetRoot,\n BottomSheetContent,\n BottomSheetFooter,\n BottomSheetTrigger,\n} from \"seed-design/ui/bottom-sheet\";\nimport { ActionButton } from \"seed-design/ui/action-button\";\nimport { Snackbar, useSnackbarAdapter } from \"seed-design/ui/snackbar\";\nimport { ExtendedFab } from \"seed-design/ui/extended-fab\";\nimport { ARTICLES, CATEGORIES, type Category } from \"@/components/example/demo/data\";\nimport { ArticleListItem } from \"@/components/example/demo/components/article-list-item\";\n\nconst FILTERS = [\n { label: \"카테고리\", value: \"category\" },\n { label: \"동네\", value: \"location\" },\n { label: \"작성자\", value: \"author\" },\n { label: \"작성 시간\", value: \"createdAt\" },\n] as const satisfies {\n label: string;\n value: string;\n}[];\n\ntype Filter = (typeof FILTERS)[number][\"value\"];\n\nexport function Recommendations() {\n const [currentFilterBottomSheet, setCurrentFilterBottomSheet] = useState(null);\n\n const defaultFilters = useMemo(\n () => ({\n category: [],\n location: [],\n author: [],\n createdAt: [],\n }),\n [],\n );\n\n const [selectedFilters, setSelectedFilters] = useState>(defaultFilters);\n\n const adapter = useSnackbarAdapter();\n\n const onUnavailableFilterClick = () =>\n adapter.create({\n render: () => (\n \n ),\n });\n\n const filteredArticles = useMemo(() => {\n let filtered = ARTICLES;\n\n if (selectedFilters.category?.length) {\n filtered = ARTICLES.filter((article) =>\n selectedFilters.category?.includes(article.categoryId),\n );\n }\n\n // XXX: Add more filters if needed\n\n return filtered;\n }, [selectedFilters]);\n\n const handleFilterConfirm = (filter: Filter, values: string[]) => {\n setSelectedFilters((prev) => ({ ...prev, [filter]: values }));\n };\n\n return (\n \n }\n style={{ position: \"fixed\", insetBlockEnd: \"16px\", insetInlineEnd: \"16px\" }}\n >\n 글쓰기\n \n \n {FILTERS.map(({ label, value }) => (\n setCurrentFilterBottomSheet(open ? value : null)}\n >\n {value === \"category\" ? (\n \n }\n onClick={value !== \"category\" ? onUnavailableFilterClick : undefined}\n >\n {selectedFilters[value]?.length\n ? selectedFilters[value]\n .map((id) => CATEGORIES.find((c) => c.id === id)?.name)\n .join(\", \") || label\n : label}\n \n \n ) : (\n }\n onClick={onUnavailableFilterClick}\n >\n {label}\n \n )}\n setCurrentFilterBottomSheet(null)}\n onConfirm={(values) => handleFilterConfirm(value, values)}\n />\n \n ))}\n \n \n {filteredArticles\n .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())\n .map((article) => (\n
  • \n \n
  • \n ))}\n
    \n
    \n );\n}\n\nexport function FilterBottomSheet({\n filter,\n currentFilter,\n onClose,\n onConfirm,\n}: {\n filter: string;\n currentFilter: string[];\n onClose: () => void;\n onConfirm: (values: string[]) => void;\n}) {\n const options = useMemo(() => {\n switch (filter) {\n case \"category\":\n return CATEGORIES;\n // Add more cases for other filters if needed\n default:\n return [];\n }\n }, [filter]);\n\n const [selectedOptions, setSelectedOptions] = useState(currentFilter);\n\n return (\n f.value === filter)?.label}>\n \n \n {options.map((option: Category) => (\n \n setSelectedOptions((prev) =>\n checked ? [...prev, option.id] : prev.filter((id) => id !== option.id),\n )\n }\n >\n {option.name}\n \n ))}\n \n \n \n {\n onConfirm(selectedOptions);\n onClose();\n }}\n >\n 완료\n \n \n \n );\n}" } \ No newline at end of file diff --git a/docs/components/example/tabs-alert.tsx b/docs/components/example/tabs-alert.tsx deleted file mode 100644 index b5ec7c390..000000000 --- a/docs/components/example/tabs-alert.tsx +++ /dev/null @@ -1,46 +0,0 @@ -"use client"; - -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; - -export default function TabsAlert() { - return ( -
    - - - 라벨1 - - 라벨2 - - 라벨3 - - - - Content 1 - - - Content 2 - - - Content 3 - - - -
    - ); -} - -const Content = (props: React.PropsWithChildren) => { - return ( -
    - {props.children} -
    - ); -}; diff --git a/docs/components/example/tabs-disabled.tsx b/docs/components/example/tabs-disabled.tsx index 20e28865e..6565cfbb9 100644 --- a/docs/components/example/tabs-disabled.tsx +++ b/docs/components/example/tabs-disabled.tsx @@ -1,28 +1,26 @@ -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsRoot, TabsContent, TabsTrigger, TabsList } from "seed-design/ui/tabs"; export default function TabsDisabled() { return (
    - - - 라벨1 - + + + 라벨1 + 라벨2 - - 라벨3 - - - - Content 1 - - - Content 2 - - - Content 3 - - - + + 라벨3 + + + Content 1 + + + Content 2 + + + Content 3 + +
    ); } diff --git a/docs/components/example/tabs-dynamic-height.tsx b/docs/components/example/tabs-dynamic-height.tsx index 45866434f..c5183f6e6 100644 --- a/docs/components/example/tabs-dynamic-height.tsx +++ b/docs/components/example/tabs-dynamic-height.tsx @@ -1,26 +1,26 @@ -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsRoot, TabsContent, TabsTrigger, TabsList, TabsCarousel } from "seed-design/ui/tabs"; export default function TabsDynamicHeight() { return (
    - - - 라벨1 - 라벨2 - 라벨3 - - - + + + 라벨1 + 라벨2 + 라벨3 + + + Content 1 - - + + Content 2 - - + + Content 3 - - - + + +
    아래 컨텐츠
    ); diff --git a/docs/components/example/tabs-fix-trigger-list.tsx b/docs/components/example/tabs-fix-trigger-list.tsx deleted file mode 100644 index e8d1f00a4..000000000 --- a/docs/components/example/tabs-fix-trigger-list.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; - -export default function TabsFixTriggerList() { - return ( - // 600은 화면 높이라고 가정합니다. -
    - - - 라벨1 - 라벨2 - 라벨3 - - - - Content 1 - - - Content 2 - - - Content 3 - - - -
    - ); -} - -const Content = (props: React.PropsWithChildren<{ height: string }>) => { - const { height, children } = props; - return ( -
    - {children} -
    - ); -}; diff --git a/docs/components/example/tabs-layout-fill.tsx b/docs/components/example/tabs-layout-fill.tsx index 1d482b730..4f1c022a5 100644 --- a/docs/components/example/tabs-layout-fill.tsx +++ b/docs/components/example/tabs-layout-fill.tsx @@ -1,26 +1,24 @@ -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsContent, TabsList, TabsRoot, TabsTrigger } from "seed-design/ui/tabs"; export default function TabsLayoutFill() { return (
    - - - 라벨1 - 라벨2 - 라벨3 - - - - Content 1 - - - Content 2 - - - Content 3 - - - + + + 라벨1 + 라벨2 + 라벨3 + + + Content 1 + + + Content 2 + + + Content 3 + +
    ); } diff --git a/docs/components/example/tabs-layout-hug.tsx b/docs/components/example/tabs-layout-hug.tsx index d38d14c71..7b0953de6 100644 --- a/docs/components/example/tabs-layout-hug.tsx +++ b/docs/components/example/tabs-layout-hug.tsx @@ -1,26 +1,24 @@ -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsRoot, TabsContent, TabsTrigger, TabsList } from "seed-design/ui/tabs"; export default function TabsLayoutHug() { return (
    - - - 라벨1 - 라벨2 - 라벨3 - - - - Content 1 - - - Content 2 - - - Content 3 - - - + + + 라벨1 + 라벨2 + 라벨3 + + + Content 1 + + + Content 2 + + + Content 3 + +
    ); } diff --git a/docs/components/example/tabs-notification.tsx b/docs/components/example/tabs-notification.tsx new file mode 100644 index 000000000..aeabdece6 --- /dev/null +++ b/docs/components/example/tabs-notification.tsx @@ -0,0 +1,44 @@ +"use client"; + +import { TabsRoot, TabsContent, TabsTrigger, TabsList } from "seed-design/ui/tabs"; + +export default function TabsNotification() { + return ( +
    + + + 라벨1 + + 라벨2 + + 라벨3 + + + Content 1 + + + Content 2 + + + Content 3 + + +
    + ); +} + +const Content = (props: React.PropsWithChildren) => { + return ( +
    + {props.children} +
    + ); +}; diff --git a/docs/components/example/tabs-preview.tsx b/docs/components/example/tabs-preview.tsx index 404343435..a2e794c2e 100644 --- a/docs/components/example/tabs-preview.tsx +++ b/docs/components/example/tabs-preview.tsx @@ -1,26 +1,24 @@ -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsRoot, TabsContent, TabsTrigger, TabsList } from "seed-design/ui/tabs"; export default function TabsPreview() { return (
    - - - 라벨1 - 라벨2 - 라벨3 - - - - Content 1 - - - Content 2 - - - Content 3 - - - + + + 라벨1 + 라벨2 + 라벨3 + + + Content 1 + + + Content 2 + + + Content 3 + +
    ); } diff --git a/docs/components/example/tabs-scroll-top.tsx b/docs/components/example/tabs-scroll-top.tsx index f393c86a7..7da815da1 100644 --- a/docs/components/example/tabs-scroll-top.tsx +++ b/docs/components/example/tabs-scroll-top.tsx @@ -1,7 +1,7 @@ "use client"; import { RefObject, useRef, useState } from "react"; -import { TabContent, TabContentList, Tabs, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsCarousel, TabsContent, TabsList, TabsRoot, TabsTrigger } from "seed-design/ui/tabs"; export default function TabsScrollTop() { const [currentTab, setCurrentTab] = useState("1"); @@ -18,24 +18,24 @@ export default function TabsScrollTop() { return (
    - - - handleTriggerClick("1")} value="1"> + + + handleTriggerClick("1")} value="1"> 라벨1 - - handleTriggerClick("2")} value="2"> + + handleTriggerClick("2")} value="2"> 라벨2 - - - - + + + + Content 1 - - + + Content 2 - - - + + +
    ); } diff --git a/docs/components/example/tabs-size-medium.tsx b/docs/components/example/tabs-size-medium.tsx index 2b5c1b0f2..ab0b14ab3 100644 --- a/docs/components/example/tabs-size-medium.tsx +++ b/docs/components/example/tabs-size-medium.tsx @@ -1,26 +1,24 @@ -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsContent, TabsList, TabsRoot, TabsTrigger } from "seed-design/ui/tabs"; export default function TabsSizeMedium() { return (
    - - - 라벨1 - 라벨2 - 라벨3 - - - - Content 1 - - - Content 2 - - - Content 3 - - - + + + 라벨1 + 라벨2 + 라벨3 + + + Content 1 + + + Content 2 + + + Content 3 + +
    ); } diff --git a/docs/components/example/tabs-size-small.tsx b/docs/components/example/tabs-size-small.tsx index fb5dda9bd..900c12cf9 100644 --- a/docs/components/example/tabs-size-small.tsx +++ b/docs/components/example/tabs-size-small.tsx @@ -1,26 +1,24 @@ -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsRoot, TabsTrigger, TabsList, TabsContent } from "seed-design/ui/tabs"; export default function TabsSizeSmall() { return (
    - - - 라벨1 - 라벨2 - 라벨3 - - - - Content 1 - - - Content 2 - - - Content 3 - - - + + + 라벨1 + 라벨2 + 라벨3 + + + Content 1 + + + Content 2 + + + Content 3 + +
    ); } diff --git a/docs/components/example/tabs-standalone.tsx b/docs/components/example/tabs-standalone.tsx index 5c1655b36..33b098443 100644 --- a/docs/components/example/tabs-standalone.tsx +++ b/docs/components/example/tabs-standalone.tsx @@ -1,19 +1,19 @@ "use client"; import { useState } from "react"; -import { Tabs, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsRoot, TabsList, TabsTrigger } from "seed-design/ui/tabs"; export default function TabsStandalone() { const [activeTab, setActiveTab] = useState("1"); return (
    - - - 라벨1 - 라벨2 - 라벨3 - + + + 라벨1 + 라벨2 + 라벨3 + {activeTab === "1" && (
    Content 1 @@ -29,7 +29,7 @@ export default function TabsStandalone() { Content 3
    )} -
    +
    ); } diff --git a/docs/components/example/tabs-sticky-list.tsx b/docs/components/example/tabs-sticky-list.tsx new file mode 100644 index 000000000..7d0ffa370 --- /dev/null +++ b/docs/components/example/tabs-sticky-list.tsx @@ -0,0 +1,47 @@ +import { TabsContent, TabsList, TabsRoot, TabsTrigger } from "seed-design/ui/tabs"; + +export default function TabsStickyList() { + return ( + // 600은 화면 높이라고 가정합니다. +
    + + + 라벨1 + 라벨2 + 라벨3 + + + Content 1 + + + Content 2 + + + Content 3 + + +
    + ); +} + +const Content = (props: React.PropsWithChildren<{ height: string }>) => { + const { height, children } = props; + return ( +
    + {children} +
    + ); +}; diff --git a/docs/components/example/tabs-swipeable.tsx b/docs/components/example/tabs-swipeable.tsx index bef9ba69d..83abe74a8 100644 --- a/docs/components/example/tabs-swipeable.tsx +++ b/docs/components/example/tabs-swipeable.tsx @@ -1,33 +1,28 @@ "use client"; -import { Tabs, TabContent, TabContentList, TabTrigger, TabTriggerList } from "seed-design/ui/tabs"; +import { TabsRoot, TabsList, TabsTrigger, TabsCarousel, TabsContent } from "seed-design/ui/tabs"; export default function TabsSwipeable() { return (
    - console.log("swipe start")} - onSwipeEnd={() => console.log("swipe end")} - > - - 라벨1 - 라벨2 - 라벨3 - - - + + + 라벨1 + 라벨2 + 라벨3 + + + Content 1 - - + + Content 2 - - + + Content 3 - - - + + +
    ); } diff --git a/docs/content/docs/react/components/tabs/chip-tabs.mdx b/docs/content/docs/react/components/tabs/chip-tabs.mdx index 59b3fb53e..3fec8611f 100644 --- a/docs/content/docs/react/components/tabs/chip-tabs.mdx +++ b/docs/content/docs/react/components/tabs/chip-tabs.mdx @@ -11,9 +11,25 @@ description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core ## Props -### `ChipTabs` +### `ChipTabsRoot` - + + +### `ChipTabsList` + + + +### `ChipTabsTrigger` + + + +### `ChipTabsCarousel` + + + +### `ChipTabsContent` + + ## Examples diff --git a/docs/content/docs/react/components/tabs/tabs.mdx b/docs/content/docs/react/components/tabs/tabs.mdx index e4b172607..ad70fcbb6 100644 --- a/docs/content/docs/react/components/tabs/tabs.mdx +++ b/docs/content/docs/react/components/tabs/tabs.mdx @@ -11,21 +11,33 @@ description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core ## Props -Tabs +### TabsRoot - + -TabTrigger +### TabsList - + + +### TabsTrigger + + + +### TabsCarousel + + + +### TabsContent + + ## Examples -### Layout Fill +### Layout Fill (Default) -### Layout Hug (Default) +### Layout Hug @@ -45,19 +57,19 @@ TabTrigger -### Alert +### Notification - + -### Fix Trigger List +### Sticky List -탭이 전체화면을 차지하고, Tab의 머리 부분인 TriggerList가 top에 고정되어 있는 경우 사용하는 예시입니다. +탭이 전체화면을 차지하고, Tabs.List가 top에 고정되어 있는 경우 사용하는 예시입니다. - + ### Standalone diff --git a/docs/package.json b/docs/package.json index 6904775db..47e1a0363 100644 --- a/docs/package.json +++ b/docs/package.json @@ -33,7 +33,6 @@ "@sanity/visual-editing": "^2.10.5", "@seed-design/react": "0.0.0", "@seed-design/react-icon": "^0.7.3", - "@seed-design/react-tabs": "0.0.0-alpha-20241209060641", "@seed-design/recipe": "0.0.0-alpha-20241212122822", "@seed-design/rootage-cli": "0.0.0", "@seed-design/rootage-core": "0.0.0", diff --git a/docs/public/__registry__/ui/chip-tabs.json b/docs/public/__registry__/ui/chip-tabs.json index 3612a24c1..0ee248f38 100644 --- a/docs/public/__registry__/ui/chip-tabs.json +++ b/docs/public/__registry__/ui/chip-tabs.json @@ -1,13 +1,13 @@ { "name": "chip-tabs", "dependencies": [ - "@seed-design/react-tabs" + "@seed-design/react" ], "registries": [ { "name": "chip-tabs.tsx", "type": "ui", - "content": "\"use client\";\n\nimport {\n useLazyContents,\n useTabs,\n type ContentProps,\n type TriggerProps,\n type UseLazyContentsProps,\n type UseTabsProps,\n} from \"@seed-design/react-tabs\";\nimport { chipTab } from \"@seed-design/recipe/chipTab\";\nimport { type ChipTabsVariant, chipTabs } from \"@seed-design/recipe/chipTabs\";\nimport clsx from \"clsx\";\nimport * as React from \"react\";\n\ntype Assign = Omit & U;\n\ninterface ChipTabsContextValue {\n api: ReturnType;\n classNames: ReturnType;\n shouldRender: (value: string) => boolean;\n variant: ChipTabsVariant[\"variant\"];\n}\n\nconst ChipTabsContext = React.createContext(null);\n\nconst useChipTabsContext = () => {\n const context = React.useContext(ChipTabsContext);\n if (!context) {\n throw new Error(\"Tabs cannot be rendered outside the Tabs\");\n }\n return context;\n};\n\nexport interface ChipTabsProps\n extends Assign<\n React.HTMLAttributes,\n Omit\n >,\n ChipTabsVariant,\n Omit {}\n\n/**\n * @see https://v3.seed-design.io/docs/react/components/tabs/chip-tabs\n */\nexport const ChipTabs = React.forwardRef(\n (props, ref) => {\n const { className, lazyMode, isLazy, variant } = props;\n const api = useTabs(props);\n const classNames = chipTabs({\n variant,\n });\n const { rootProps, value, restProps } = api;\n const { shouldRender } = useLazyContents({\n currentValue: value ?? \"\",\n lazyMode,\n isLazy,\n });\n\n return (\n \n \n {props.children}\n \n \n );\n },\n);\nChipTabs.displayName = \"ChipTabs\";\n\nexport const ChipTabTriggerList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, children, ...otherProps }, ref) => {\n const { api, classNames } = useChipTabsContext();\n const { tabTriggerListProps, triggerSize } = api;\n const { left } = triggerSize;\n const { triggerList } = classNames;\n\n const containerRef = React.useRef(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n if (containerRef.current) {\n containerRef.current?.scrollTo({\n // NOTE: 27px is half of tab's min-width\n left: left - 27,\n behavior: \"smooth\",\n });\n }\n }, [left]);\n\n return (\n \n {children}\n \n );\n});\nChipTabTriggerList.displayName = \"ChipTabTriggerList\";\n\nexport interface ChipTabTriggerProps\n extends Assign, TriggerProps> {}\n\nexport const ChipTabTrigger = React.forwardRef<\n HTMLButtonElement,\n ChipTabTriggerProps\n>(({ className, children, value, isDisabled, ...otherProps }, ref) => {\n const { api, variant } = useChipTabsContext();\n const { getTabTriggerProps } = api;\n const { label, root } = chipTab({\n variant,\n });\n const { rootProps, labelProps } = getTabTriggerProps({ value, isDisabled });\n\n return (\n \n \n {children}\n \n \n );\n});\nChipTabTrigger.displayName = \"ChipTabTrigger\";\n\nexport const ChipTabContent = React.forwardRef<\n HTMLDivElement,\n Assign, ContentProps>\n>(({ className, children, value, ...otherProps }, ref) => {\n const { api, classNames, shouldRender } = useChipTabsContext();\n const { getTabContentProps } = api;\n const { content } = classNames;\n const tabContentProps = getTabContentProps({ value });\n const isRender = shouldRender(value);\n\n return (\n \n {isRender && children}\n \n );\n});\nChipTabContent.displayName = \"ChipTabContent\";\n" + "content": "\"use client\";\n\nimport { ChipTabs as SeedChipTabs } from \"@seed-design/react\";\nimport { forwardRef } from \"react\";\n\nexport interface ChipTabsRootProps extends SeedChipTabs.RootProps {}\n\nexport const ChipTabsRoot = forwardRef(\n (props, ref) => {\n const { children, ...otherProps } = props;\n return (\n \n {children}\n \n );\n },\n);\nChipTabsRoot.displayName = \"ChipTabsRoot\";\n\nexport interface ChipTabsListProps extends SeedChipTabs.ListProps {}\n\nexport const ChipTabsList = SeedChipTabs.List;\n\nexport interface ChipTabsTriggerProps\n extends Omit {\n notification?: boolean;\n}\n\nexport const ChipTabsTrigger = forwardRef<\n HTMLButtonElement,\n ChipTabsTriggerProps\n>((props, ref) => {\n const { children, notification, ...otherProps } = props;\n return (\n \n {children}\n \n );\n});\nChipTabsTrigger.displayName = \"ChipTabsTrigger\";\n\nexport interface ChipTabsCarouselProps\n extends Omit {}\n\nexport const ChipTabsCarousel = (props: ChipTabsCarouselProps) => {\n const { children, ...otherProps } = props;\n return (\n \n {children}\n \n );\n};\nChipTabsCarousel.displayName = \"ChipTabsCarousel\";\n\nexport interface ChipTabsContentProps extends SeedChipTabs.ContentProps {}\n\nexport const ChipTabsContent = SeedChipTabs.Content;\n" } ] } \ No newline at end of file diff --git a/docs/public/__registry__/ui/help-bubble.json b/docs/public/__registry__/ui/help-bubble.json index e888024fd..1f8f6ccfb 100644 --- a/docs/public/__registry__/ui/help-bubble.json +++ b/docs/public/__registry__/ui/help-bubble.json @@ -1,8 +1,7 @@ { "name": "help-bubble", "dependencies": [ - "@seed-design/react", - "@radix-ui/react-slot" + "@seed-design/react" ], "registries": [ { diff --git a/docs/public/__registry__/ui/index.json b/docs/public/__registry__/ui/index.json index 901f89411..f325f9353 100644 --- a/docs/public/__registry__/ui/index.json +++ b/docs/public/__registry__/ui/index.json @@ -225,8 +225,7 @@ { "name": "help-bubble", "dependencies": [ - "@seed-design/react", - "@radix-ui/react-slot" + "@seed-design/react" ], "files": [ "ui:help-bubble.tsx" @@ -235,7 +234,7 @@ { "name": "tabs", "dependencies": [ - "@seed-design/react-tabs" + "@seed-design/react" ], "files": [ "ui:tabs.tsx" @@ -244,7 +243,7 @@ { "name": "chip-tabs", "dependencies": [ - "@seed-design/react-tabs" + "@seed-design/react" ], "files": [ "ui:chip-tabs.tsx" @@ -309,8 +308,7 @@ "name": "text-field", "dependencies": [ "@seed-design/react", - "@daangn/react-monochrome-icon", - "@radix-ui/react-slot" + "@daangn/react-monochrome-icon" ], "files": [ "ui:text-field.tsx" diff --git a/docs/public/__registry__/ui/tabs.json b/docs/public/__registry__/ui/tabs.json index 370b54df3..d18c67203 100644 --- a/docs/public/__registry__/ui/tabs.json +++ b/docs/public/__registry__/ui/tabs.json @@ -1,13 +1,13 @@ { "name": "tabs", "dependencies": [ - "@seed-design/react-tabs" + "@seed-design/react" ], "registries": [ { "name": "tabs.tsx", "type": "ui", - "content": "\"use client\";\n\nimport clsx from \"clsx\";\nimport * as React from \"react\";\nimport {\n useTabs,\n useSwipeable,\n type UseTabsProps,\n type TriggerProps,\n type ContentProps,\n useLazyContents,\n type UseLazyContentsProps,\n} from \"@seed-design/react-tabs\";\nimport { tabs } from \"@seed-design/recipe/tabs\";\nimport { tab } from \"@seed-design/recipe/tab\";\n\ntype Assign = Omit & U;\n\ninterface TabsContextValue {\n api: ReturnType;\n classNames: ReturnType;\n shouldRender: (value: string) => boolean;\n\n /**\n * @default false\n */\n isSwipeable: boolean;\n\n layout: \"fill\" | \"hug\";\n size: \"small\" | \"medium\";\n onSwipeStart?: () => void;\n onSwipeEnd?: () => void;\n}\n\nconst TabsContext = React.createContext(null);\n\nconst useTabsContext = () => {\n const context = React.useContext(TabsContext);\n if (!context) {\n throw new Error(\"Tabs cannot be rendered outside the Tabs\");\n }\n return context;\n};\n\nexport interface TabsProps\n extends Omit,\n UseTabsProps {\n /**\n * @default \"hug\"\n */\n layout?: \"fill\" | \"hug\";\n\n /**\n * @default \"small\"\n */\n size?: \"small\" | \"medium\";\n\n /**\n * @default false\n */\n fixTriggerList?: boolean;\n}\n\ninterface ReactTabsProps\n extends Assign, UseTabsProps>,\n Omit,\n TabsProps {}\n\n/**\n * @see https://v3.seed-design.io/docs/react/components/tabs/tabs\n */\nexport const Tabs = React.forwardRef(\n (props, ref) => {\n const {\n className,\n lazyMode,\n isLazy,\n isSwipeable = false,\n layout = \"hug\",\n size = \"small\",\n fixTriggerList = false,\n onSwipeStart,\n onSwipeEnd,\n } = props;\n const useTabsProps = useTabs(props);\n const classNames = tabs({\n layout,\n size,\n fixTriggerList,\n });\n const { rootProps, value } = useTabsProps;\n const { shouldRender } = useLazyContents({\n currentValue: value ?? \"\",\n lazyMode,\n isLazy,\n });\n const api = {\n ...useTabsProps,\n };\n\n return (\n \n \n {props.children}\n \n \n );\n },\n);\nTabs.displayName = \"Tabs\";\n\nexport const TabTriggerList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, children, ...otherProps }, ref) => {\n const { api, classNames } = useTabsContext();\n const { tabTriggerListProps, triggerSize } = api;\n const { left } = triggerSize;\n const { triggerList } = classNames;\n\n const containerRef = React.useRef(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n if (containerRef.current) {\n containerRef.current?.scrollTo({\n // NOTE: 27px is half of tab's min-width\n left: left - 27,\n behavior: \"smooth\",\n });\n }\n }, [left]);\n\n return (\n \n {children}\n \n \n );\n});\nTabTriggerList.displayName = \"TabTriggerList\";\n\nexport interface TabTriggerProps extends TriggerProps {\n /**\n * @default false\n */\n alert?: boolean;\n\n isDisabled?: boolean;\n\n value: string;\n}\n\ninterface ReactTabTriggerProps\n extends Assign<\n React.ButtonHTMLAttributes,\n TabTriggerProps\n > {}\n\nexport const TabTrigger = React.forwardRef<\n HTMLButtonElement,\n ReactTabTriggerProps\n>(\n (\n { className, children, value, isDisabled, alert = false, ...otherProps },\n ref,\n ) => {\n const { api, layout, size } = useTabsContext();\n const { getTabTriggerProps } = api;\n const { label, notification, root } = tab({\n size,\n layout,\n });\n const { rootProps, notificationProps, labelProps } = getTabTriggerProps({\n value,\n isDisabled,\n });\n\n return (\n {\n rootProps.onClick?.(e);\n otherProps.onClick?.(e);\n }}\n >\n \n {children}\n {alert &&
    }\n \n \n );\n },\n);\nTabTrigger.displayName = \"TabTrigger\";\n\nexport const TabContentList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, children, ...otherProps }, ref) => {\n const { api, classNames, isSwipeable, onSwipeStart, onSwipeEnd } =\n useTabsContext();\n const {\n tabContentListProps,\n tabContentCameraProps,\n currentTabEnabledIndex,\n tabEnabledCount,\n moveNext,\n movePrev,\n } = api;\n const { contentList, contentCamera } = classNames;\n const { dragProps, swipeMoveX, swipeStatus } = useSwipeable({\n isSwipeable,\n onSwipeLeftToRight: movePrev,\n onSwipeRightToLeft: moveNext,\n onSwipeStart,\n onSwipeEnd,\n });\n\n const getCameraTranslateX = () => {\n const MODIFIER = 5;\n\n const isSide =\n currentTabEnabledIndex === 0 ||\n currentTabEnabledIndex === tabEnabledCount - 1;\n const swipeOffset = isSide ? swipeMoveX / MODIFIER : swipeMoveX;\n\n return `calc(var(--seed-design-tabs-current-tab-enabled-index) * var(--seed-design-tabs-tab-camera-width) * -1px + ${swipeOffset}px)`;\n };\n\n return (\n \n \n {children}\n
    \n \n );\n});\nTabContentList.displayName = \"TabContentList\";\n\nexport const TabContent = React.forwardRef<\n HTMLDivElement,\n Assign, ContentProps>\n>(({ className, children, value, ...otherProps }, ref) => {\n const { api, classNames, shouldRender } = useTabsContext();\n const { getTabContentProps } = api;\n const { content } = classNames;\n const tabContentProps = getTabContentProps({ value });\n const isRender = shouldRender(value);\n\n return (\n \n {isRender && children}\n \n );\n});\nTabContent.displayName = \"TabContent\";\n\nconst TabIndicator = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...otherProps }, ref) => {\n const { api, classNames } = useTabsContext();\n const { tabIndicatorProps } = api;\n const { indicator } = classNames;\n\n return (\n \n );\n});\nTabIndicator.displayName = \"TabIndicator\";\n" + "content": "\"use client\";\n\nimport { Tabs as SeedTabs } from \"@seed-design/react\";\nimport { forwardRef } from \"react\";\n\nexport interface TabsRootProps extends SeedTabs.RootProps {}\n\nexport const TabsRoot = forwardRef(\n (props, ref) => {\n const { children, ...otherProps } = props;\n return (\n \n {children}\n \n );\n },\n);\nTabsRoot.displayName = \"TabsRoot\";\n\nexport interface TabsListProps extends SeedTabs.ListProps {}\n\nexport const TabsList = forwardRef(\n (props, ref) => {\n const { children, ...otherProps } = props;\n return (\n \n {children}\n \n \n );\n },\n);\nTabsList.displayName = \"TabsList\";\n\nexport interface TabsTriggerProps\n extends Omit {\n notification?: boolean;\n}\n\nexport const TabsTrigger = forwardRef(\n (props, ref) => {\n const { children, notification, ...otherProps } = props;\n return (\n \n \n {children}\n {notification && }\n \n \n );\n },\n);\nTabsTrigger.displayName = \"TabsTrigger\";\n\nexport interface TabsCarouselProps\n extends Omit {}\n\nexport const TabsCarousel = (props: TabsCarouselProps) => {\n const { children, ...otherProps } = props;\n return (\n \n {children}\n \n );\n};\nTabsCarousel.displayName = \"TabsCarousel\";\n\nexport interface TabsContentProps extends SeedTabs.ContentProps {}\n\nexport const TabsContent = SeedTabs.Content;\n" } ] } \ No newline at end of file diff --git a/docs/public/__registry__/ui/text-field.json b/docs/public/__registry__/ui/text-field.json index 7b9150957..cf873f02d 100644 --- a/docs/public/__registry__/ui/text-field.json +++ b/docs/public/__registry__/ui/text-field.json @@ -2,8 +2,7 @@ "name": "text-field", "dependencies": [ "@seed-design/react", - "@daangn/react-monochrome-icon", - "@radix-ui/react-slot" + "@daangn/react-monochrome-icon" ], "registries": [ { diff --git a/docs/public/rootage-next/components/chip-tablist.json b/docs/public/rootage-next/components/chip-tablist.json index f3c0a8f0a..bc014b83d 100644 --- a/docs/public/rootage-next/components/chip-tablist.json +++ b/docs/public/rootage-next/components/chip-tablist.json @@ -36,7 +36,7 @@ "enabled" ], "slots": { - "triggerList": { + "root": { "gap": { "type": "dimension", "value": { @@ -59,7 +59,7 @@ "enabled" ], "slots": { - "triggerList": { + "root": { "gap": { "type": "dimension", "value": { diff --git a/docs/public/rootage-next/components/tab.json b/docs/public/rootage-next/components/tab.json index fec7ef261..952c8d470 100644 --- a/docs/public/rootage-next/components/tab.json +++ b/docs/public/rootage-next/components/tab.json @@ -102,6 +102,10 @@ "type": "dimension", "value": "$font-size.s5" }, + "lineHeight": { + "type": "dimension", + "value": "$line-height.s5" + }, "fontWeight": { "type": "number", "value": "$font-weight.bold" @@ -143,6 +147,10 @@ "type": "dimension", "value": "$font-size.s4" }, + "lineHeight": { + "type": "dimension", + "value": "$line-height.s4" + }, "fontWeight": { "type": "number", "value": "$font-weight.bold" diff --git a/docs/public/rootage-next/components/tablist.json b/docs/public/rootage-next/components/tablist.json index cab9d7ae1..9bb4bd824 100644 --- a/docs/public/rootage-next/components/tablist.json +++ b/docs/public/rootage-next/components/tablist.json @@ -44,6 +44,14 @@ "color": { "type": "color", "value": "$color.fg.neutral" + }, + "transformDuration": { + "type": "duration", + "value": "$duration.s4" + }, + "transformTimingFunction": { + "type": "cubicBezier", + "value": "$timing-function.easing" } } } @@ -63,7 +71,16 @@ "root": { "paddingX": { "type": "dimension", - "value": "$dimension.s4" + "value": "$dimension.spacing-x.global-gutter" + } + }, + "indicator": { + "insetX": { + "type": "dimension", + "value": { + "value": 0, + "unit": "px" + } } } } @@ -88,6 +105,12 @@ "unit": "px" } } + }, + "indicator": { + "insetX": { + "type": "dimension", + "value": "$dimension.spacing-x.global-gutter" + } } } } diff --git a/docs/public/rootage/components/chip-tablist.json b/docs/public/rootage/components/chip-tablist.json index bb7cfba91..34ce6bf46 100644 --- a/docs/public/rootage/components/chip-tablist.json +++ b/docs/public/rootage/components/chip-tablist.json @@ -14,14 +14,14 @@ }, "variant=neutral solid": { "enabled": { - "triggerList": { + "root": { "gap": "0px" } } }, "variant=brand solid": { "enabled": { - "triggerList": { + "root": { "gap": "8px" } } diff --git a/docs/public/rootage/components/tab.json b/docs/public/rootage/components/tab.json index a20186512..311aaa5fc 100644 --- a/docs/public/rootage/components/tab.json +++ b/docs/public/rootage/components/tab.json @@ -37,6 +37,7 @@ }, "label": { "fontSize": "$font-size.s5", + "lineHeight": "$line-height.s5", "fontWeight": "$font-weight.bold" } } @@ -50,6 +51,7 @@ }, "label": { "fontSize": "$font-size.s4", + "lineHeight": "$line-height.s4", "fontWeight": "$font-weight.bold" } } diff --git a/docs/public/rootage/components/tablist.json b/docs/public/rootage/components/tablist.json index d5fde8f4b..44d8b9d78 100644 --- a/docs/public/rootage/components/tablist.json +++ b/docs/public/rootage/components/tablist.json @@ -14,14 +14,19 @@ }, "indicator": { "height": "2px", - "color": "$color.fg.neutral" + "color": "$color.fg.neutral", + "transformDuration": "$duration.s4", + "transformTimingFunction": "$timing-function.easing" } } }, "layout=hug": { "enabled": { "root": { - "paddingX": "$dimension.s4" + "paddingX": "$dimension.spacing-x.global-gutter" + }, + "indicator": { + "insetX": "0px" } } }, @@ -29,6 +34,9 @@ "enabled": { "root": { "paddingX": "0px" + }, + "indicator": { + "insetX": "$dimension.spacing-x.global-gutter" } } }, diff --git a/docs/public/rootage/parsed.json b/docs/public/rootage/parsed.json index 79941a7f5..ec82d5441 100644 --- a/docs/public/rootage/parsed.json +++ b/docs/public/rootage/parsed.json @@ -14443,7 +14443,7 @@ ], "slot": [ { - "key": "triggerList", + "key": "root", "property": [ { "key": "gap", @@ -14470,7 +14470,7 @@ ], "slot": [ { - "key": "triggerList", + "key": "root", "property": [ { "key": "gap", @@ -22067,6 +22067,16 @@ "key": "s5" } }, + { + "key": "lineHeight", + "value": { + "type": "token", + "group": [ + "line-height" + ], + "key": "s5" + } + }, { "key": "fontWeight", "value": { @@ -22139,6 +22149,16 @@ "key": "s4" } }, + { + "key": "lineHeight", + "value": { + "type": "token", + "group": [ + "line-height" + ], + "key": "s4" + } + }, { "key": "fontWeight", "value": { @@ -22225,6 +22245,26 @@ ], "key": "neutral" } + }, + { + "key": "transformDuration", + "value": { + "type": "token", + "group": [ + "duration" + ], + "key": "s4" + } + }, + { + "key": "transformTimingFunction", + "value": { + "type": "token", + "group": [ + "timing-function" + ], + "key": "easing" + } } ] } @@ -22250,9 +22290,23 @@ "value": { "type": "token", "group": [ - "dimension" + "dimension", + "spacing-x" ], - "key": "s4" + "key": "global-gutter" + } + } + ] + }, + { + "key": "indicator", + "property": [ + { + "key": "insetX", + "value": { + "type": "dimension", + "value": 0, + "unit": "px" } } ] @@ -22283,6 +22337,22 @@ } } ] + }, + { + "key": "indicator", + "property": [ + { + "key": "insetX", + "value": { + "type": "token", + "group": [ + "dimension", + "spacing-x" + ], + "key": "global-gutter" + } + } + ] } ] } diff --git a/docs/registry/registry-ui.ts b/docs/registry/registry-ui.ts index c9ddbf62c..fccd78b69 100644 --- a/docs/registry/registry-ui.ts +++ b/docs/registry/registry-ui.ts @@ -122,19 +122,17 @@ export const registryUI: RegistryUI = [ }, { name: "help-bubble", - dependencies: ["@seed-design/react", "@radix-ui/react-slot"], + dependencies: ["@seed-design/react"], files: ["ui:help-bubble.tsx"], }, { name: "tabs", - // TODO: 탭 코드 수정 후 `@seed-design/react`로 변경 - dependencies: ["@seed-design/react-tabs"], + dependencies: ["@seed-design/react"], files: ["ui:tabs.tsx"], }, { name: "chip-tabs", - // TODO: 탭 코드 수정 후 `@seed-design/react`로 변경 - dependencies: ["@seed-design/react-tabs"], + dependencies: ["@seed-design/react"], files: ["ui:chip-tabs.tsx"], }, { @@ -169,11 +167,7 @@ export const registryUI: RegistryUI = [ }, { name: "text-field", - dependencies: [ - "@seed-design/react", - "@daangn/react-monochrome-icon", - "@radix-ui/react-slot", - ], + dependencies: ["@seed-design/react", "@daangn/react-monochrome-icon"], files: ["ui:text-field.tsx"], }, ]; diff --git a/docs/registry/ui/chip-tabs.tsx b/docs/registry/ui/chip-tabs.tsx index a87c561b4..c6e0f30be 100644 --- a/docs/registry/ui/chip-tabs.tsx +++ b/docs/registry/ui/chip-tabs.tsx @@ -1,168 +1,57 @@ "use client"; -import { - useLazyContents, - useTabs, - type ContentProps, - type TriggerProps, - type UseLazyContentsProps, - type UseTabsProps, -} from "@seed-design/react-tabs"; -import { chipTab } from "@seed-design/recipe/chipTab"; -import { type ChipTabsVariant, chipTabs } from "@seed-design/recipe/chipTabs"; -import clsx from "clsx"; -import * as React from "react"; +import { ChipTabs as SeedChipTabs } from "@seed-design/react"; +import { forwardRef } from "react"; -type Assign = Omit & U; +export interface ChipTabsRootProps extends SeedChipTabs.RootProps {} -interface ChipTabsContextValue { - api: ReturnType; - classNames: ReturnType; - shouldRender: (value: string) => boolean; - variant: ChipTabsVariant["variant"]; -} - -const ChipTabsContext = React.createContext(null); - -const useChipTabsContext = () => { - const context = React.useContext(ChipTabsContext); - if (!context) { - throw new Error("Tabs cannot be rendered outside the Tabs"); - } - return context; -}; - -export interface ChipTabsProps - extends Assign< - React.HTMLAttributes, - Omit - >, - ChipTabsVariant, - Omit {} - -/** - * @see https://v3.seed-design.io/docs/react/components/tabs/chip-tabs - */ -export const ChipTabs = React.forwardRef( +export const ChipTabsRoot = forwardRef( (props, ref) => { - const { className, lazyMode, isLazy, variant } = props; - const api = useTabs(props); - const classNames = chipTabs({ - variant, - }); - const { rootProps, value, restProps } = api; - const { shouldRender } = useLazyContents({ - currentValue: value ?? "", - lazyMode, - isLazy, - }); - + const { children, ...otherProps } = props; return ( -
    - - {props.children} - -
    + + {children} + ); }, ); -ChipTabs.displayName = "ChipTabs"; +ChipTabsRoot.displayName = "ChipTabsRoot"; -export const ChipTabTriggerList = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, children, ...otherProps }, ref) => { - const { api, classNames } = useChipTabsContext(); - const { tabTriggerListProps, triggerSize } = api; - const { left } = triggerSize; - const { triggerList } = classNames; +export interface ChipTabsListProps extends SeedChipTabs.ListProps {} - const containerRef = React.useRef(null); - React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement); +export const ChipTabsList = SeedChipTabs.List; - React.useEffect(() => { - if (containerRef.current) { - containerRef.current?.scrollTo({ - // NOTE: 27px is half of tab's min-width - left: left - 27, - behavior: "smooth", - }); - } - }, [left]); +export interface ChipTabsTriggerProps + extends Omit { + notification?: boolean; +} +export const ChipTabsTrigger = forwardRef< + HTMLButtonElement, + ChipTabsTriggerProps +>((props, ref) => { + const { children, notification, ...otherProps } = props; return ( -
    - {children} -
    + + {children} + ); }); -ChipTabTriggerList.displayName = "ChipTabTriggerList"; - -export interface ChipTabTriggerProps - extends Assign, TriggerProps> {} +ChipTabsTrigger.displayName = "ChipTabsTrigger"; -export const ChipTabTrigger = React.forwardRef< - HTMLButtonElement, - ChipTabTriggerProps ->(({ className, children, value, isDisabled, ...otherProps }, ref) => { - const { api, variant } = useChipTabsContext(); - const { getTabTriggerProps } = api; - const { label, root } = chipTab({ - variant, - }); - const { rootProps, labelProps } = getTabTriggerProps({ value, isDisabled }); +export interface ChipTabsCarouselProps + extends Omit {} +export const ChipTabsCarousel = (props: ChipTabsCarouselProps) => { + const { children, ...otherProps } = props; return ( - + + {children} + ); -}); -ChipTabTrigger.displayName = "ChipTabTrigger"; +}; +ChipTabsCarousel.displayName = "ChipTabsCarousel"; -export const ChipTabContent = React.forwardRef< - HTMLDivElement, - Assign, ContentProps> ->(({ className, children, value, ...otherProps }, ref) => { - const { api, classNames, shouldRender } = useChipTabsContext(); - const { getTabContentProps } = api; - const { content } = classNames; - const tabContentProps = getTabContentProps({ value }); - const isRender = shouldRender(value); +export interface ChipTabsContentProps extends SeedChipTabs.ContentProps {} - return ( -
    - {isRender && children} -
    - ); -}); -ChipTabContent.displayName = "ChipTabContent"; +export const ChipTabsContent = SeedChipTabs.Content; diff --git a/docs/registry/ui/tabs.tsx b/docs/registry/ui/tabs.tsx index 055d9cae7..ea51e0707 100644 --- a/docs/registry/ui/tabs.tsx +++ b/docs/registry/ui/tabs.tsx @@ -1,328 +1,70 @@ "use client"; -import clsx from "clsx"; -import * as React from "react"; -import { - useTabs, - useSwipeable, - type UseTabsProps, - type TriggerProps, - type ContentProps, - useLazyContents, - type UseLazyContentsProps, -} from "@seed-design/react-tabs"; -import { tabs } from "@seed-design/recipe/tabs"; -import { tab } from "@seed-design/recipe/tab"; +import { Tabs as SeedTabs } from "@seed-design/react"; +import { forwardRef } from "react"; -type Assign = Omit & U; +export interface TabsRootProps extends SeedTabs.RootProps {} -interface TabsContextValue { - api: ReturnType; - classNames: ReturnType; - shouldRender: (value: string) => boolean; - - /** - * @default false - */ - isSwipeable: boolean; - - layout: "fill" | "hug"; - size: "small" | "medium"; - onSwipeStart?: () => void; - onSwipeEnd?: () => void; -} - -const TabsContext = React.createContext(null); - -const useTabsContext = () => { - const context = React.useContext(TabsContext); - if (!context) { - throw new Error("Tabs cannot be rendered outside the Tabs"); - } - return context; -}; - -export interface TabsProps - extends Omit, - UseTabsProps { - /** - * @default "hug" - */ - layout?: "fill" | "hug"; - - /** - * @default "small" - */ - size?: "small" | "medium"; - - /** - * @default false - */ - fixTriggerList?: boolean; -} - -interface ReactTabsProps - extends Assign, UseTabsProps>, - Omit, - TabsProps {} - -/** - * @see https://v3.seed-design.io/docs/react/components/tabs/tabs - */ -export const Tabs = React.forwardRef( +export const TabsRoot = forwardRef( (props, ref) => { - const { - className, - lazyMode, - isLazy, - isSwipeable = false, - layout = "hug", - size = "small", - fixTriggerList = false, - onSwipeStart, - onSwipeEnd, - } = props; - const useTabsProps = useTabs(props); - const classNames = tabs({ - layout, - size, - fixTriggerList, - }); - const { rootProps, value } = useTabsProps; - const { shouldRender } = useLazyContents({ - currentValue: value ?? "", - lazyMode, - isLazy, - }); - const api = { - ...useTabsProps, - }; - + const { children, ...otherProps } = props; return ( -
    - - {props.children} - -
    + + {children} + ); }, ); -Tabs.displayName = "Tabs"; - -export const TabTriggerList = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, children, ...otherProps }, ref) => { - const { api, classNames } = useTabsContext(); - const { tabTriggerListProps, triggerSize } = api; - const { left } = triggerSize; - const { triggerList } = classNames; - - const containerRef = React.useRef(null); - React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement); - - React.useEffect(() => { - if (containerRef.current) { - containerRef.current?.scrollTo({ - // NOTE: 27px is half of tab's min-width - left: left - 27, - behavior: "smooth", - }); - } - }, [left]); - - return ( -
    - {children} - -
    - ); -}); -TabTriggerList.displayName = "TabTriggerList"; +TabsRoot.displayName = "TabsRoot"; -export interface TabTriggerProps extends TriggerProps { - /** - * @default false - */ - alert?: boolean; +export interface TabsListProps extends SeedTabs.ListProps {} - isDisabled?: boolean; +export const TabsList = forwardRef( + (props, ref) => { + const { children, ...otherProps } = props; + return ( + + {children} + + + ); + }, +); +TabsList.displayName = "TabsList"; - value: string; +export interface TabsTriggerProps + extends Omit { + notification?: boolean; } -interface ReactTabTriggerProps - extends Assign< - React.ButtonHTMLAttributes, - TabTriggerProps - > {} - -export const TabTrigger = React.forwardRef< - HTMLButtonElement, - ReactTabTriggerProps ->( - ( - { className, children, value, isDisabled, alert = false, ...otherProps }, - ref, - ) => { - const { api, layout, size } = useTabsContext(); - const { getTabTriggerProps } = api; - const { label, notification, root } = tab({ - size, - layout, - }); - const { rootProps, notificationProps, labelProps } = getTabTriggerProps({ - value, - isDisabled, - }); - +export const TabsTrigger = forwardRef( + (props, ref) => { + const { children, notification, ...otherProps } = props; return ( - + {notification && } + + ); }, ); -TabTrigger.displayName = "TabTrigger"; - -export const TabContentList = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, children, ...otherProps }, ref) => { - const { api, classNames, isSwipeable, onSwipeStart, onSwipeEnd } = - useTabsContext(); - const { - tabContentListProps, - tabContentCameraProps, - currentTabEnabledIndex, - tabEnabledCount, - moveNext, - movePrev, - } = api; - const { contentList, contentCamera } = classNames; - const { dragProps, swipeMoveX, swipeStatus } = useSwipeable({ - isSwipeable, - onSwipeLeftToRight: movePrev, - onSwipeRightToLeft: moveNext, - onSwipeStart, - onSwipeEnd, - }); +TabsTrigger.displayName = "TabsTrigger"; - const getCameraTranslateX = () => { - const MODIFIER = 5; - - const isSide = - currentTabEnabledIndex === 0 || - currentTabEnabledIndex === tabEnabledCount - 1; - const swipeOffset = isSide ? swipeMoveX / MODIFIER : swipeMoveX; - - return `calc(var(--seed-design-tabs-current-tab-enabled-index) * var(--seed-design-tabs-tab-camera-width) * -1px + ${swipeOffset}px)`; - }; - - return ( -
    -
    - {children} -
    -
    - ); -}); -TabContentList.displayName = "TabContentList"; - -export const TabContent = React.forwardRef< - HTMLDivElement, - Assign, ContentProps> ->(({ className, children, value, ...otherProps }, ref) => { - const { api, classNames, shouldRender } = useTabsContext(); - const { getTabContentProps } = api; - const { content } = classNames; - const tabContentProps = getTabContentProps({ value }); - const isRender = shouldRender(value); +export interface TabsCarouselProps + extends Omit {} +export const TabsCarousel = (props: TabsCarouselProps) => { + const { children, ...otherProps } = props; return ( -
    - {isRender && children} -
    + + {children} + ); -}); -TabContent.displayName = "TabContent"; +}; +TabsCarousel.displayName = "TabsCarousel"; -const TabIndicator = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...otherProps }, ref) => { - const { api, classNames } = useTabsContext(); - const { tabIndicatorProps } = api; - const { indicator } = classNames; +export interface TabsContentProps extends SeedTabs.ContentProps {} - return ( -
    - ); -}); -TabIndicator.displayName = "TabIndicator"; +export const TabsContent = SeedTabs.Content; diff --git a/docs/stories/ChipTabs.stories.tsx b/docs/stories/ChipTabs.stories.tsx index e70a74291..0f1d169b7 100644 --- a/docs/stories/ChipTabs.stories.tsx +++ b/docs/stories/ChipTabs.stories.tsx @@ -1,11 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { - ChipTabs, - ChipTabsProps, - ChipTabTrigger, - ChipTabTriggerList, -} from "seed-design/ui/chip-tabs"; +import { ChipTabs, ChipTabsProps, ChipTabsTrigger, ChipTabsList } from "seed-design/ui/chip-tabs"; import { chipTabsVariantMap } from "@seed-design/recipe/chipTabs"; import { SeedThemeDecorator } from "./components/decorator"; @@ -15,11 +10,11 @@ import { createStoryWithParameters } from "@/stories/utils/parameters"; const Component = (props: ChipTabsProps) => { return ( - - Tab 1 - Tab 2 - Tab 3 - + + Tab 1 + Tab 2 + Tab 3 + ); }; diff --git a/examples/stackflow-spa/src/activities/ActivityAnimatedTabs.tsx b/examples/stackflow-spa/src/activities/ActivityAnimatedTabs.tsx new file mode 100644 index 000000000..f161b185c --- /dev/null +++ b/examples/stackflow-spa/src/activities/ActivityAnimatedTabs.tsx @@ -0,0 +1,56 @@ +import { Box } from "@seed-design/react"; +import type { ActivityComponentType } from "@stackflow/react"; +import { + AppBar, + AppBarBackButton, + AppBarLeft, + AppBarMain, +} from "../design-system/stackflow/AppBar"; +import { AppScreen, AppScreenContent } from "../design-system/stackflow/AppScreen"; +import { + TabsCarousel, + TabsContent, + TabsList, + TabsRoot, + TabsTrigger, +} from "../design-system/ui/tabs"; + +const ActivityAnimatedTabs: ActivityComponentType = () => { + return ( + + + + + + + + + + + Tab 1 + + Disabled + + + Tab 2 + + + + + + Tab 1 content + + + + + Tab 2 content + + + + + + + ); +}; + +export default ActivityAnimatedTabs; diff --git a/examples/stackflow-spa/src/activities/ActivityHome.tsx b/examples/stackflow-spa/src/activities/ActivityHome.tsx index cdc7bda89..22a5c8796 100644 --- a/examples/stackflow-spa/src/activities/ActivityHome.tsx +++ b/examples/stackflow-spa/src/activities/ActivityHome.tsx @@ -154,6 +154,37 @@ const ActivityHome: ActivityComponentType = () => { title="Snackbar (critical)" /> + + snackbarAdapter.create({ + render: () => , + }) + } + title="Snackbar" + /> + + snackbarAdapter.create({ + render: () => ( + + ), + }) + } + title="Snackbar (positive)" + /> + + snackbarAdapter.create({ + render: () => ( + + ), + }) + } + title="Snackbar (critical)" + /> + push("ActivityTabs", {})} title="Tabs" /> + push("ActivityAnimatedTabs", {})} title="AnimatedTabs" /> + push("ActivitySwipeableTabs", {})} title="SwipeableTabs" /> diff --git a/examples/stackflow-spa/src/activities/ActivitySwipeableTabs.tsx b/examples/stackflow-spa/src/activities/ActivitySwipeableTabs.tsx new file mode 100644 index 000000000..d3e3c5199 --- /dev/null +++ b/examples/stackflow-spa/src/activities/ActivitySwipeableTabs.tsx @@ -0,0 +1,115 @@ +import { Inline, PullToRefresh, Stack, Text } from "@seed-design/react"; +import type { ActivityComponentType } from "@stackflow/react"; +import { + AppBar, + AppBarBackButton, + AppBarLeft, + AppBarMain, +} from "../design-system/stackflow/AppBar"; +import { AppScreen, AppScreenContent } from "../design-system/stackflow/AppScreen"; +import { ProgressCircle } from "../design-system/ui/progress-circle"; +import { + TabsCarousel, + TabsContent, + TabsList, + TabsRoot, + TabsTrigger, +} from "../design-system/ui/tabs"; + +const ActivitySwipeableTabs: ActivityComponentType = () => { + return ( + + + + + + + + + + + Tab 1 + + Disabled + + + Tab 2 + + + + + { + await new Promise((resolve) => setTimeout(resolve, 1000)); + }} + > + + {(props) => } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +const Feed = () => { + return ( + + + + + 독서 습관 만들기 + + + 하루 10페이지부터 시작하자. 취침 전 20분 독서는 수면의 질도 높여주는 일석이조 습관이다. + + + + + 라이프스타일 ⸱ 서초2동 + + + + + ); +}; + +export default ActivitySwipeableTabs; diff --git a/examples/stackflow-spa/src/activities/ActivityTabs.tsx b/examples/stackflow-spa/src/activities/ActivityTabs.tsx new file mode 100644 index 000000000..b28392653 --- /dev/null +++ b/examples/stackflow-spa/src/activities/ActivityTabs.tsx @@ -0,0 +1,61 @@ +import { Box } from "@seed-design/react"; +import type { ActivityComponentType } from "@stackflow/react"; +import { useEffect, useState } from "react"; +import { + AppBar, + AppBarBackButton, + AppBarLeft, + AppBarMain, +} from "../design-system/stackflow/AppBar"; +import { AppScreen, AppScreenContent } from "../design-system/stackflow/AppScreen"; +import { TabsContent, TabsList, TabsRoot, TabsTrigger } from "../design-system/ui/tabs"; + +const ActivityTabs: ActivityComponentType = () => { + return ( + + + + + + + + +
    + Sticky Tablist + + + Tab 1 + Tab 2 + + + + Tab 1 content + + + + + + Tab 2 content + + + + +
    +
    +
    + ); +}; + +const AsyncContent = (props: { children: React.ReactNode }) => { + const [loaded, setLoaded] = useState(false); + + useEffect(() => { + setTimeout(() => { + setLoaded(true); + }, 1000); + }, []); + + return loaded ? <>{props.children} :
    Loading...
    ; +}; + +export default ActivityTabs; diff --git a/examples/stackflow-spa/src/design-system/ui/tabs.tsx b/examples/stackflow-spa/src/design-system/ui/tabs.tsx new file mode 100644 index 000000000..f96c219d2 --- /dev/null +++ b/examples/stackflow-spa/src/design-system/ui/tabs.tsx @@ -0,0 +1,62 @@ +"use client"; + +import { Tabs as SeedTabs } from "@seed-design/react"; +import { forwardRef } from "react"; + +export interface TabsRootProps extends SeedTabs.RootProps {} + +export const TabsRoot = forwardRef((props, ref) => { + const { children, ...otherProps } = props; + return ( + + {children} + + ); +}); +TabsRoot.displayName = "TabsRoot"; + +export interface TabsListProps extends SeedTabs.ListProps {} + +export const TabsList = forwardRef((props, ref) => { + const { children, ...otherProps } = props; + return ( + + {children} + + + ); +}); +TabsList.displayName = "TabsList"; + +export interface TabsTriggerProps extends Omit { + notification?: boolean; +} + +export const TabsTrigger = forwardRef((props, ref) => { + const { children, notification, ...otherProps } = props; + return ( + + + {children} + {notification && } + + + ); +}); +TabsTrigger.displayName = "TabsTrigger"; + +export interface TabsCarouselProps extends Omit {} + +export const TabsCarousel = (props: TabsCarouselProps) => { + const { children, ...otherProps } = props; + return ( + + {children} + + ); +}; +TabsCarousel.displayName = "TabsCarousel"; + +export interface TabsContentProps extends SeedTabs.ContentProps {} + +export const TabsContent = SeedTabs.Content; diff --git a/examples/stackflow-spa/src/stackflow/Stack.tsx b/examples/stackflow-spa/src/stackflow/Stack.tsx index 5beeaa2c9..52305fbbf 100644 --- a/examples/stackflow-spa/src/stackflow/Stack.tsx +++ b/examples/stackflow-spa/src/stackflow/Stack.tsx @@ -40,6 +40,9 @@ const { Stack, useFlow, useStepFlow } = stackflow({ ActivityErrorState: React.lazy(() => import("../activities/ActivityErrorState")), ActivityFab: React.lazy(() => import("../activities/ActivityFab")), ActivityExtendedFab: React.lazy(() => import("../activities/ActivityExtendedFab")), + ActivityTabs: React.lazy(() => import("../activities/ActivityTabs")), + ActivityAnimatedTabs: React.lazy(() => import("../activities/ActivityAnimatedTabs")), + ActivitySwipeableTabs: React.lazy(() => import("../activities/ActivitySwipeableTabs")), ActivityNotFound, }, plugins: [ @@ -82,6 +85,9 @@ const { Stack, useFlow, useStepFlow } = stackflow({ ActivityFab: "/fab", ActivityExtendedFab: "/extended-fab", ActivityReactionButton: "/reaction-button", + ActivityTabs: "/tabs", + ActivitySwipeableTabs: "/swipeable-tabs", + ActivityAnimatedTabs: "/animated-tabs", ActivityNotFound: "/404", }, }), diff --git a/packages/qvism-preset/src/index.ts b/packages/qvism-preset/src/index.ts index dd58e7598..b77ff1cae 100644 --- a/packages/qvism-preset/src/index.ts +++ b/packages/qvism-preset/src/index.ts @@ -9,7 +9,6 @@ import badge from "./recipes/badge"; import bottomSheet from "./recipes/bottom-sheet"; import callout from "./recipes/callout"; import checkbox from "./recipes/checkbox"; -import chipTab from "./recipes/chip-tab"; import chipTabs from "./recipes/chip-tabs"; import controlChip from "./recipes/control-chip"; import dialog from "./recipes/dialog"; @@ -31,7 +30,6 @@ import { selectBox, selectBoxGroup } from "./recipes/select-box"; import skeleton from "./recipes/skeleton"; import { snackbar, snackbarRegion } from "./recipes/snackbar"; import switchRecipe from "./recipes/switch"; -import tab from "./recipes/tab"; import tabs from "./recipes/tabs"; import text from "./recipes/text"; import textButton from "./recipes/text-button"; @@ -40,7 +38,6 @@ import toggleButton from "./recipes/toggle-button"; import visuallyHidden from "./recipes/visually-hidden"; import { appBar, appBarMain } from "./stackflow/app-bar"; import { appScreen } from "./stackflow/app-screen"; - const recipes = { avatar, avatarStack, @@ -72,9 +69,7 @@ const recipes = { identityPlaceholder, inlineBanner, progressCircle, - tab, tabs, - chipTab, chipTabs, skeleton, snackbar, diff --git a/packages/qvism-preset/src/recipes/chip-tab.ts b/packages/qvism-preset/src/recipes/chip-tab.ts deleted file mode 100644 index cc942f81a..000000000 --- a/packages/qvism-preset/src/recipes/chip-tab.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { chipTab as vars } from "@seed-design/vars/component"; -import { defineRecipe } from "../utils/define-recipe"; -import { pseudo, selected, active, disabled } from "../utils/pseudo"; - -const chipTab = defineRecipe({ - name: "chipTab", - slots: ["root", "label"], - base: { - root: { - display: "flex", - justifyContent: "center", - alignItems: "center", - padding: `${vars.base.enabled.root.paddingY} ${vars.base.enabled.root.paddingX}`, - cursor: "pointer", - border: "none", - borderRadius: vars.base.enabled.root.cornerRadius, - boxSizing: "border-box", - whiteSpace: "nowrap", - minHeight: vars.base.enabled.root.minHeight, - fontFamily: "inherit", - }, - label: { - fontSize: vars.base.enabled.label.fontSize, - fontWeight: vars.base.enabled.label.fontWeight, - }, - }, - variants: { - variant: { - neutralSolid: { - root: { - [pseudo(selected)]: { - backgroundColor: vars.variantNeutralSolid.selected.root.color, - }, - - [pseudo(active)]: { - backgroundColor: vars.variantNeutralSolid.enabledPressed.root.color, - }, - - [pseudo(selected, active)]: { - backgroundColor: vars.variantNeutralSolid.selectedPressed.root.color, - }, - - [pseudo(disabled)]: { - cursor: "not-allowed", - backgroundColor: undefined, - }, - - [pseudo(disabled, selected)]: { - backgroundColor: vars.variantNeutralSolid.selectedDisabled.root.color, - }, - }, - - label: { - color: vars.variantNeutralSolid.enabled.label.color, - fontWeight: vars.base.enabled.label.fontWeight, - - [pseudo(selected)]: { - color: vars.variantNeutralSolid.selected.label.color, - }, - - [pseudo(disabled)]: { - color: vars.variantNeutralSolid.disabled.label.color, - }, - - [pseudo(disabled, selected)]: { - color: vars.variantNeutralSolid.selectedDisabled.label.color, - }, - }, - }, - brandSolid: { - root: { - fontWeight: vars.variantBrandSolid.enabled.label.fontWeight, - backgroundColor: vars.variantBrandSolid.enabled.root.color, - - [pseudo(selected)]: { - backgroundColor: vars.variantBrandSolid.selected.root.color, - }, - - [pseudo(active)]: { - backgroundColor: vars.variantBrandSolid.enabledPressed.root.color, - }, - - [pseudo(selected, active)]: { - backgroundColor: vars.variantBrandSolid.selectedPressed.root.color, - }, - - [pseudo(disabled)]: { - cursor: "not-allowed", - backgroundColor: vars.variantBrandSolid.disabled.root.color, - }, - - [pseudo(disabled, selected)]: { - backgroundColor: vars.variantBrandSolid.selectedDisabled.root.color, - }, - }, - - label: { - color: vars.variantBrandSolid.enabled.label.color, - fontWeight: vars.variantBrandSolid.enabled.label.fontWeight, - - [pseudo(selected)]: { - color: vars.variantBrandSolid.selected.label.color, - fontWeight: vars.variantBrandSolid.selected.label.fontWeight, - }, - - [pseudo(disabled)]: { - color: vars.variantBrandSolid.disabled.label.color, - }, - }, - }, - }, - }, - defaultVariants: { - variant: "neutralSolid", - }, -}); - -export default chipTab; diff --git a/packages/qvism-preset/src/recipes/chip-tabs.ts b/packages/qvism-preset/src/recipes/chip-tabs.ts index e098a0970..eaa688c1e 100644 --- a/packages/qvism-preset/src/recipes/chip-tabs.ts +++ b/packages/qvism-preset/src/recipes/chip-tabs.ts @@ -1,17 +1,18 @@ -import { chipTablist as vars } from "@seed-design/vars/component"; +import { chipTablist as vars, chipTab as triggerVars } from "@seed-design/vars/component"; import { defineRecipe } from "../utils/define-recipe"; +import { active, disabled, not, pseudo, selected } from "../utils/pseudo"; const chipTabs = defineRecipe({ name: "chipTabs", - slots: ["root", "triggerList", "contentList", "contentCamera", "content"], + slots: ["root", "list", "carousel", "carouselCamera", "content", "trigger", "triggerLabel"], base: { root: { - overflowX: "hidden", - }, - triggerList: { position: "relative", + }, + list: { display: "flex", - flexDirection: "row", + position: "relative", + isolation: "isolate", flexWrap: "nowrap", alignItems: "stretch", alignContent: "stretch", @@ -26,35 +27,178 @@ const chipTabs = defineRecipe({ display: "none", }, }, - contentList: {}, - contentCamera: { + carousel: { + display: "block", + overflow: "hidden", + }, + carouselCamera: { display: "flex", - width: "100%", - height: "100%", + + [pseudo("[data-auto-height]")]: { + alignItems: "flex-start", + }, }, content: { - width: "100%", - height: "100%", - flexShrink: 0, - overflow: "auto", + flex: "0 0 100%", + minWidth: 0, + transform: "translate3d(0, 0, 0)", + overflowY: "auto", + overflowX: "hidden", + + [pseudo(not("[data-carousel]"), not(selected))]: { + display: "none", + }, + }, + + trigger: { + display: "flex", + justifyContent: "center", + alignItems: "center", + cursor: "pointer", + border: "none", + boxSizing: "border-box", + whiteSpace: "nowrap", + fontFamily: "inherit", + + borderRadius: triggerVars.base.enabled.root.cornerRadius, + padding: `${triggerVars.base.enabled.root.paddingY} ${triggerVars.base.enabled.root.paddingX}`, + minHeight: triggerVars.base.enabled.root.minHeight, + }, + triggerLabel: { + fontSize: triggerVars.base.enabled.label.fontSize, + fontWeight: triggerVars.base.enabled.label.fontWeight, }, }, variants: { variant: { neutralSolid: { - triggerList: { - gap: vars.variantNeutralSolid.enabled.triggerList.gap, + list: { + gap: vars.variantNeutralSolid.enabled.root.gap, + }, + trigger: { + [pseudo(selected)]: { + backgroundColor: triggerVars.variantNeutralSolid.selected.root.color, + }, + + [pseudo(active)]: { + backgroundColor: triggerVars.variantNeutralSolid.enabledPressed.root.color, + }, + + [pseudo(selected, active)]: { + backgroundColor: triggerVars.variantNeutralSolid.selectedPressed.root.color, + }, + + [pseudo(disabled)]: { + cursor: "not-allowed", + backgroundColor: undefined, + }, + + [pseudo(disabled, selected)]: { + backgroundColor: triggerVars.variantNeutralSolid.selectedDisabled.root.color, + }, + }, + + triggerLabel: { + color: triggerVars.variantNeutralSolid.enabled.label.color, + fontWeight: triggerVars.base.enabled.label.fontWeight, + + [pseudo(selected)]: { + color: triggerVars.variantNeutralSolid.selected.label.color, + }, + + [pseudo(disabled)]: { + color: triggerVars.variantNeutralSolid.disabled.label.color, + }, + + [pseudo(disabled, selected)]: { + color: triggerVars.variantNeutralSolid.selectedDisabled.label.color, + }, }, }, brandSolid: { - triggerList: { - gap: vars.variantBrandSolid.enabled.triggerList.gap, + list: { + gap: vars.variantBrandSolid.enabled.root.gap, + }, + trigger: { + fontWeight: triggerVars.variantBrandSolid.enabled.label.fontWeight, + backgroundColor: triggerVars.variantBrandSolid.enabled.root.color, + + [pseudo(selected)]: { + backgroundColor: triggerVars.variantBrandSolid.selected.root.color, + }, + + [pseudo(active)]: { + backgroundColor: triggerVars.variantBrandSolid.enabledPressed.root.color, + }, + + [pseudo(selected, active)]: { + backgroundColor: triggerVars.variantBrandSolid.selectedPressed.root.color, + }, + + [pseudo(disabled)]: { + cursor: "not-allowed", + backgroundColor: triggerVars.variantBrandSolid.disabled.root.color, + }, + + [pseudo(disabled, selected)]: { + backgroundColor: triggerVars.variantBrandSolid.selectedDisabled.root.color, + }, + }, + + triggerLabel: { + color: triggerVars.variantBrandSolid.enabled.label.color, + fontWeight: triggerVars.variantBrandSolid.enabled.label.fontWeight, + + [pseudo(selected)]: { + color: triggerVars.variantBrandSolid.selected.label.color, + fontWeight: triggerVars.variantBrandSolid.selected.label.fontWeight, + }, + + [pseudo(disabled)]: { + color: triggerVars.variantBrandSolid.disabled.label.color, + }, + }, + }, + }, + contentLayout: { + fill: { + root: { + display: "flex", + flexDirection: "column", + height: "100%", + }, + carousel: { + flex: 1, + }, + carouselCamera: { + height: "100%", + alignItems: "stretch", + }, + }, + hug: { + root: { + display: "block", + }, + }, + }, + stickyList: { + true: { + root: { + position: "relative", + }, + list: { + position: "sticky", + top: 0, + zIndex: 1, }, }, + false: {}, }, }, defaultVariants: { variant: "neutralSolid", + contentLayout: "hug", + stickyList: false, }, }); diff --git a/packages/qvism-preset/src/recipes/tab.ts b/packages/qvism-preset/src/recipes/tab.ts deleted file mode 100644 index 683c24602..000000000 --- a/packages/qvism-preset/src/recipes/tab.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { tab as vars } from "@seed-design/vars/component"; -import { defineRecipe } from "../utils/define-recipe"; -import { disabled, pseudo, selected } from "../utils/pseudo"; - -const tab = defineRecipe({ - name: "tab", - slots: ["root", "label", "notification"], - base: { - root: { - display: "flex", - justifyContent: "center", - alignItems: "flex-end", - cursor: "pointer", - border: "none", - boxSizing: "border-box", - backgroundColor: "transparent", - whiteSpace: "nowrap", - [pseudo(disabled)]: { - cursor: "not-allowed", - }, - }, - label: { - position: "relative", - color: vars.base.enabled.label.color, - [pseudo(selected)]: { - color: vars.base.selected.label.color, - }, - [pseudo(disabled)]: { - color: vars.base.disabled.label.color, - }, - }, - notification: { - position: "absolute", - top: 0, - - /** - * notification이 Tabs의 박스 사이즈에 잡히지 않도록 하기 위한 트릭 - * notification의 위치를 absolute로 잡아주고, right를 음수로 설정하여 박스 밖으로 나가게 함 - * 이때, 텍스트에서 marginLeft만큼 떨어진 위치에 위치해야하기 위해서는 - * 우선 notification의 size만큼 오른쪽으로 한번 이동하고 거기서 marginLeft만큼 오른쪽으로 이동해야함 - * 그래서 아래와 같은 식이 나옴 - */ - right: `calc(-1 * ${vars.base.enabled.notification.size} - ${vars.base.enabled.notification.marginLeft})`, - - alignSelf: "flex-start", - backgroundColor: vars.base.enabled.notification.color, - width: vars.base.enabled.notification.size, - height: vars.base.enabled.notification.size, - borderRadius: vars.base.enabled.notification.cornerRadius, - }, - }, - variants: { - layout: { - fill: { - root: { - flex: 1, - }, - }, - hug: {}, - }, - size: { - medium: { - root: { - minHeight: vars.sizeMedium.enabled.root.minHeight, - paddingInline: vars.sizeMedium.enabled.root.paddingX, - paddingBlock: vars.sizeMedium.enabled.root.paddingY, - }, - label: { - fontSize: vars.sizeMedium.enabled.label.fontSize, - fontWeight: vars.sizeMedium.enabled.label.fontWeight, - }, - }, - small: { - root: { - minHeight: vars.sizeSmall.enabled.root.minHeight, - paddingInline: vars.sizeSmall.enabled.root.paddingX, - paddingBlock: vars.sizeSmall.enabled.root.paddingY, - }, - label: { - fontSize: vars.sizeSmall.enabled.label.fontSize, - fontWeight: vars.sizeSmall.enabled.label.fontWeight, - }, - }, - }, - }, - defaultVariants: { - size: "medium", - layout: "hug", - }, -}); - -export default tab; diff --git a/packages/qvism-preset/src/recipes/tabs.ts b/packages/qvism-preset/src/recipes/tabs.ts index 0ef8252cf..9128caffb 100644 --- a/packages/qvism-preset/src/recipes/tabs.ts +++ b/packages/qvism-preset/src/recipes/tabs.ts @@ -1,17 +1,28 @@ -import { tablist as vars } from "@seed-design/vars/component"; +import { tablist as vars, tab as triggerVars } from "@seed-design/vars/component"; import { defineRecipe } from "../utils/define-recipe"; +import { disabled, not, pseudo, selected } from "../utils/pseudo"; const tabs = defineRecipe({ name: "tabs", - slots: ["root", "triggerList", "contentList", "contentCamera", "content", "indicator"], + slots: [ + "root", + "list", + "carousel", + "carouselCamera", + "content", + "indicator", + "trigger", + "triggerLabel", + "triggerNotification", + ], base: { root: { - overflow: "hidden", - }, - triggerList: { position: "relative", + }, + list: { display: "flex", - flexDirection: "row", + position: "relative", + isolation: "isolate", flexWrap: "nowrap", alignItems: "stretch", alignContent: "stretch", @@ -19,102 +30,211 @@ const tabs = defineRecipe({ overflowX: "auto", msOverflowStyle: "none", scrollbarWidth: "none", - - background: vars.base.enabled.root.color, - borderBottom: `${vars.base.enabled.root.strokeBottomWidth} solid ${vars.base.enabled.root.strokeColor}`, - "&::-webkit-scrollbar": { display: "none", }, + + background: vars.base.enabled.root.color, + // use inset boxShadow instead of border to avoid layout shift + boxShadow: `inset 0 -${vars.base.enabled.root.strokeBottomWidth} ${vars.base.enabled.root.strokeColor}`, }, - contentList: { - width: "100%", + carousel: { + display: "block", + overflow: "hidden", }, - contentCamera: { + carouselCamera: { display: "flex", - width: "100%", - height: "100%", + + [pseudo("[data-auto-height]")]: { + alignItems: "flex-start", + }, }, content: { - width: "100%", - height: "100%", - flexShrink: 0, + flex: "0 0 100%", + minWidth: 0, + transform: "translate3d(0, 0, 0)", overflowY: "auto", overflowX: "hidden", + + [pseudo(not("[data-carousel]"), not(selected))]: { + display: "none", + }, }, indicator: { position: "absolute", willChange: "left, width", - transition: - "left 0.2s cubic-bezier(0.15, 0.3, 0.25, 1), width 0.2s cubic-bezier(0.15, 0.3, 0.25, 1)", - left: "var(--seed-design-tabs-indicator-left, 0px)", - width: "var(--seed-design-tabs-indicator-width, 0px)", + transitionProperty: "left, width", + transitionDuration: vars.base.enabled.indicator.transformDuration, + transitionTimingFunction: vars.base.enabled.indicator.transformTimingFunction, + left: "var(--indicator-left, 0px)", + width: "var(--indicator-width, 0px)", color: vars.base.enabled.indicator.color, borderBottom: `${vars.base.enabled.indicator.height} solid ${vars.base.enabled.indicator.color}`, bottom: 0, + + [pseudo("[data-ssr]")]: { + display: "none", + }, + }, + + trigger: { + position: "relative", + display: "flex", + justifyContent: "center", + alignItems: "flex-end", + cursor: "pointer", + border: "none", + boxSizing: "border-box", + backgroundColor: "transparent", + whiteSpace: "nowrap", + [pseudo(disabled)]: { + cursor: "not-allowed", + }, + + [pseudo(selected, "[data-ssr]:after")]: { + content: "''", + position: "absolute", + bottom: 0, + left: 0, + right: 0, + height: vars.base.enabled.indicator.height, + backgroundColor: vars.base.enabled.indicator.color, + }, + }, + triggerLabel: { + position: "relative", + color: triggerVars.base.enabled.label.color, + [pseudo(selected)]: { + color: triggerVars.base.selected.label.color, + }, + [pseudo(disabled)]: { + color: triggerVars.base.disabled.label.color, + }, + }, + triggerNotification: { + position: "absolute", + top: 0, + + /** + * notification이 Tabs의 박스 사이즈에 잡히지 않도록 하기 위한 트릭 + * notification의 위치를 absolute로 잡아주고, right를 음수로 설정하여 박스 밖으로 나가게 함 + * 이때, 텍스트에서 marginLeft만큼 떨어진 위치에 위치해야하기 위해서는 + * 우선 notification의 size만큼 오른쪽으로 한번 이동하고 거기서 marginLeft만큼 오른쪽으로 이동해야함 + * 그래서 아래와 같은 식이 나옴 + */ + right: `calc(-1 * ${triggerVars.base.enabled.notification.size} - ${triggerVars.base.enabled.notification.marginLeft})`, + + alignSelf: "flex-start", + backgroundColor: triggerVars.base.enabled.notification.color, + width: triggerVars.base.enabled.notification.size, + height: triggerVars.base.enabled.notification.size, + borderRadius: triggerVars.base.enabled.notification.cornerRadius, }, }, variants: { - layout: { + triggerLayout: { fill: { - triggerList: { - padding: `0px ${vars.layoutFill.enabled.root.paddingX}`, + list: { + paddingInline: vars.layoutFill.enabled.root.paddingX, justifyContent: "space-around", }, indicator: { - left: "calc(var(--seed-design-tabs-indicator-left, 0px) + 16px)", - width: "calc(var(--seed-design-tabs-indicator-width, 0px) - 32px)", + left: `calc(var(--indicator-left, 0px) + ${vars.layoutFill.enabled.indicator.insetX})`, + width: `calc(var(--indicator-width, 0px) - 2 * ${vars.layoutFill.enabled.indicator.insetX})`, + }, + trigger: { + flex: 1, }, }, hug: { - triggerList: { - padding: `0px ${vars.layoutHug.enabled.root.paddingX}`, + list: { + paddingInline: vars.layoutHug.enabled.root.paddingX, justifyContent: "flex-start", }, indicator: { - left: "calc(var(--seed-design-tabs-indicator-left, 0px))", - width: "calc(var(--seed-design-tabs-indicator-width, 0px))", + left: `calc(var(--indicator-left, 0px) + ${vars.layoutHug.enabled.indicator.insetX})`, + width: `calc(var(--indicator-width, 0px) - 2 * ${vars.layoutHug.enabled.indicator.insetX})`, + }, + }, + }, + contentLayout: { + fill: { + root: { + display: "flex", + flexDirection: "column", + height: "100%", + }, + carousel: { + flex: 1, + }, + carouselCamera: { + height: "100%", + alignItems: "stretch", + }, + }, + hug: { + root: { + display: "block", }, }, }, size: { small: { root: { - "--seed-design-tabs-trigger-list-height": vars.sizeSmall.enabled.root.height, + "--tabs-list-height": vars.sizeSmall.enabled.root.height, + }, + list: { + minHeight: vars.sizeSmall.enabled.root.height, + }, + trigger: { + minHeight: triggerVars.sizeSmall.enabled.root.minHeight, + paddingInline: triggerVars.sizeSmall.enabled.root.paddingX, + paddingBlock: triggerVars.sizeSmall.enabled.root.paddingY, }, - triggerList: { - height: vars.sizeSmall.enabled.root.height, + triggerLabel: { + fontSize: triggerVars.sizeSmall.enabled.label.fontSize, + lineHeight: triggerVars.sizeSmall.enabled.label.lineHeight, + fontWeight: triggerVars.sizeSmall.enabled.label.fontWeight, }, }, medium: { root: { - "--seed-design-tabs-trigger-list-height": vars.sizeMedium.enabled.root.height, + "--tabs-list-height": vars.sizeMedium.enabled.root.height, }, - triggerList: { - height: vars.sizeMedium.enabled.root.height, + list: { + minHeight: vars.sizeMedium.enabled.root.height, + }, + trigger: { + minHeight: triggerVars.sizeMedium.enabled.root.minHeight, + paddingInline: triggerVars.sizeMedium.enabled.root.paddingX, + paddingBlock: triggerVars.sizeMedium.enabled.root.paddingY, + }, + triggerLabel: { + fontSize: triggerVars.sizeMedium.enabled.label.fontSize, + lineHeight: triggerVars.sizeMedium.enabled.label.lineHeight, + fontWeight: triggerVars.sizeMedium.enabled.label.fontWeight, }, }, }, - fixTriggerList: { + stickyList: { true: { root: { position: "relative", }, - triggerList: { + list: { position: "sticky", top: 0, - }, - contentList: { - height: "calc(100% - var(--seed-design-tabs-trigger-list-height))", + zIndex: 1, }, }, false: {}, }, }, defaultVariants: { - layout: "hug", + triggerLayout: "fill", + contentLayout: "hug", size: "small", - fixTriggerList: false, + stickyList: false, }, }); diff --git a/packages/react-headless/tabs/package.json b/packages/react-headless/tabs/package.json index 27c908350..e96f677d0 100644 --- a/packages/react-headless/tabs/package.json +++ b/packages/react-headless/tabs/package.json @@ -26,10 +26,14 @@ "build": "bun build.mjs && tsc" }, "dependencies": { + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-use-callback-ref": "^1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "^1.1.0", "@radix-ui/react-use-size": "^1.1.0", "@seed-design/dom-utils": "0.0.0-alpha-20241030023710", - "@use-gesture/react": "^10.3.1" + "embla-carousel-auto-height": "^8.5.2", + "embla-carousel-react": "^8.5.2" }, "peerDependencies": { "react": ">=18.0.0", diff --git a/packages/react-headless/tabs/src/Tabs.namespace.ts b/packages/react-headless/tabs/src/Tabs.namespace.ts new file mode 100644 index 000000000..fd5b3b229 --- /dev/null +++ b/packages/react-headless/tabs/src/Tabs.namespace.ts @@ -0,0 +1,16 @@ +export { + TabsContent as Content, + TabsIndicator as Indicator, + TabsList as List, + TabsRoot as Root, + TabsCarouselCamera as CarouselCamera, + TabsCarousel as Carousel, + TabsTrigger as Trigger, + type TabsContentProps as ContentProps, + type TabsIndicatorProps as IndicatorProps, + type TabsListProps as ListProps, + type TabsRootProps as RootProps, + type TabsCarouselCameraProps as CarouselCameraProps, + type TabsCarouselProps as CarouselProps, + type TabsTriggerProps as TriggerProps, +} from "./Tabs"; diff --git a/packages/react-headless/tabs/src/Tabs.tsx b/packages/react-headless/tabs/src/Tabs.tsx new file mode 100644 index 000000000..00b1981b3 --- /dev/null +++ b/packages/react-headless/tabs/src/Tabs.tsx @@ -0,0 +1,156 @@ +import { composeRefs } from "@radix-ui/react-compose-refs"; +import { mergeProps } from "@seed-design/dom-utils"; +import { Primitive, type PrimitiveProps } from "@seed-design/react-primitive"; +import type * as React from "react"; +import { forwardRef } from "react"; +import { useRenderStrategy, type UseRenderStrategyProps } from "./private/useRenderStrategy"; +import { + RenderStrategyProvider, + useRenderStrategyContext, +} from "./private/useRenderStrategyContext"; +import { useTabsCarousel, type UseTabsCarouselProps } from "./useTabsCarousel"; +import type { UseTabsContentProps, UseTabsProps, UseTabsTriggerProps } from "./useTabs"; +import { useTabs } from "./useTabs"; +import { TabsProvider, useTabsContext } from "./useTabsContext"; +import { TabsCarouselProvider, useTabsCarouselContext } from "./useTabsCarouselContext"; +import { TabsTriggerProvider } from "./useTabsTriggerContext"; + +//////////////////////////////////////////////////////////////////////////////////// + +export interface TabsRootProps + extends UseTabsProps, + UseRenderStrategyProps, + PrimitiveProps, + Omit, "defaultValue"> {} + +export const TabsRoot = forwardRef((props, ref) => { + const { + defaultValue, + value, + onValueChange, + orientation, + lazyMount, + unmountOnExit, + ...otherProps + } = props; + const api = useTabs({ + defaultValue, + value, + onValueChange, + orientation, + }); + const renderStrategyApi = useRenderStrategy({ lazyMount, unmountOnExit }); + return ( + + + + + + ); +}); +TabsRoot.displayName = "TabsRoot"; + +//////////////////////////////////////////////////////////////////////////////////// + +export interface TabsListProps extends PrimitiveProps, React.HTMLAttributes {} + +export const TabsList = forwardRef((props, ref) => { + const api = useTabsContext(); + return ( + + ); +}); +TabsList.displayName = "TabsList"; + +//////////////////////////////////////////////////////////////////////////////////// + +export interface TabsTriggerProps + extends UseTabsTriggerProps, + PrimitiveProps, + React.HTMLAttributes {} + +export const TabsTrigger = forwardRef((props, ref) => { + const { value, disabled, ...otherProps } = props; + const api = useTabsContext(); + const triggerApi = api.getTriggerProps({ value, disabled }); + return ( + + + + ); +}); +TabsTrigger.displayName = "TabsTrigger"; + +//////////////////////////////////////////////////////////////////////////////////// + +export interface TabsContentProps + extends PrimitiveProps, + UseTabsContentProps, + React.HTMLAttributes {} + +export const TabsContent = forwardRef((props, ref) => { + const { value, ...otherProps } = props; + const api = useTabsContext(); + const carouselApi = useTabsCarouselContext({ strict: false }); + const { getUnmounted } = useRenderStrategyContext(); + const unmounted = getUnmounted(api.value === value); + if (unmounted) return null; + + return ( + + ); +}); +TabsContent.displayName = "TabsContent"; + +//////////////////////////////////////////////////////////////////////////////////// + +export interface TabsIndicatorProps extends PrimitiveProps, React.HTMLAttributes {} + +export const TabsIndicator = forwardRef((props, ref) => { + const api = useTabsContext(); + return ; +}); + +//////////////////////////////////////////////////////////////////////////////////// + +export interface TabsCarouselProps + extends PrimitiveProps, + UseTabsCarouselProps, + React.HTMLAttributes {} + +export const TabsCarousel = forwardRef((props, ref) => { + const { dragThreshold, loop, swipeable, autoHeight, onSettle, ...otherProps } = props; + const api = useTabsCarousel({ dragThreshold, loop, swipeable, onSettle, autoHeight }); + + return ( + + + {props.children} + + + ); +}); +TabsCarousel.displayName = "TabsCarousel"; + +//////////////////////////////////////////////////////////////////////////////////// + +export interface TabsCarouselCameraProps + extends PrimitiveProps, + React.HTMLAttributes {} + +export const TabsCarouselCamera = forwardRef( + (props, ref) => { + const api = useTabsCarouselContext(); + return ; + }, +); +TabsCarouselCamera.displayName = "TabsCarouselCamera"; diff --git a/packages/react-headless/tabs/src/dom.ts b/packages/react-headless/tabs/src/dom.ts index 012f2c283..031ba2e6f 100644 --- a/packages/react-headless/tabs/src/dom.ts +++ b/packages/react-headless/tabs/src/dom.ts @@ -1,94 +1,17 @@ /* ID ----------------------------------------------------------------------- -------------------------------------------------------------------------------- */ -export const getRootId = (id: string) => `tabs:${id}:root`; -export const getTabTriggerRootId = (value: string, id: string) => - `tabs:${value}:${id}:trigger-root`; -export const getTabTriggerLabelId = (value: string, id: string) => - `tabs:${value}:${id}:trigger-label`; -export const getTabTriggerNotificationId = (value: string, id: string) => - `tabs:${value}:${id}:trigger-notification`; -export const getTabTriggerListId = (id: string) => `tabs:${id}:trigger-list`; -export const getTabContentId = (value: string, id: string) => `tabs:${value}:${id}:content`; -export const getTabContentListId = (id: string) => `tabs:${id}:content-list`; -export const getTabContentCameraId = (id: string) => `tabs:${id}:content-camera`; -export const getIndicatorId = (id: string) => `tabs:${id}:indicator`; +export const getTriggerId = (value: string, id: string) => `tabs:${value}:${id}:trigger-root`; +export const getListId = (id: string) => `tabs:${id}:list`; +export const getContentId = (value: string, id: string) => `tabs:${value}:${id}:content`; -/* Element ----------------------------------------------------------------------- +/* Query ----------------------------------------------------------------------- -------------------------------------------------------------------------------- */ -const isClient = typeof window === "object"; - -export const getRootEl = (id: string) => (isClient ? document.getElementById(getRootId(id)) : null); -export const getTabTriggerListEl = (id: string) => - isClient ? document.getElementById(getTabTriggerListId(id)) : null; -export const getTabTriggerEl = (value: string, id: string) => - isClient ? document.getElementById(getTabTriggerRootId(value, id)) : null; -export const getTabContentEl = (value: string, id: string) => - isClient ? document.getElementById(getTabContentId(value, id)) : null; -export const getTabContentListEl = (id: string) => - isClient ? document.getElementById(getTabContentListId(id)) : null; -export const getTabContentCameraEl = (id: string) => - isClient ? document.getElementById(getTabContentCameraId(id)) : null; -export const getIndicatorEl = (id: string) => - isClient ? document.getElementById(getIndicatorId(id)) : null; - -export const getDisabledElements = (id: string) => { - const triggerListId = getTabTriggerListId(id); - const triggerListEl = getTabTriggerListEl(id); - const selector = `[role=tab][data-ownedby='${triggerListId}'][aria-disabled=true]`; - return queryAll(triggerListEl, selector); -}; - -/* Utils ----------------------------------------------------------------------- --------------------------------------------------------------------------------- */ - -type Root = Document | Element | null | undefined; - -export function queryAll(root: Root, selector: string) { - return Array.from(root?.querySelectorAll(selector) ?? []); -} - -export function query(root: Root, selector: string) { - return root?.querySelector(selector) ?? null; -} - -export type ItemToId = (v: T) => string; - -export const defaultItemToId = (v: T) => v.id; -export function itemById( - v: T[], - id: string, - itemToId: ItemToId = defaultItemToId, -) { - return v.find((item) => itemToId(item) === id); -} - -export const getAllValues = (id: string) => { - const el = getTabTriggerListEl(id); - - if (!el) return []; - return Array.from(el.children) - .map((child) => child.getAttribute("data-value")) - .filter(Boolean); -}; - -export const getEnabledValues = (id: string) => { - const el = getTabTriggerListEl(id); - +export const getEnabledValues = (el: HTMLElement) => { if (!el) return []; return Array.from(el.children) .filter((child) => !child.hasAttribute("aria-disabled")) .map((child) => child.getAttribute("data-value")) .filter(Boolean); }; - -export const getTabIndex = (value: string, id: string) => { - const values = getAllValues(id); - return values.indexOf(value); -}; - -export const getTabIndexOnlyEnabled = (value: string, id: string) => { - const values = getEnabledValues(id); - return values.indexOf(value); -}; diff --git a/packages/react-headless/tabs/src/index.ts b/packages/react-headless/tabs/src/index.ts index 06a7a93db..13e3171dd 100644 --- a/packages/react-headless/tabs/src/index.ts +++ b/packages/react-headless/tabs/src/index.ts @@ -1,9 +1,25 @@ -import { useTabs } from "./useTabs"; -import { useLazyContents, type UseLazyContentsProps } from "./useLazyContents"; -import { useSwipeable } from "./useSwipeable"; +export { + TabsContent, + TabsIndicator, + TabsList, + TabsRoot, + TabsCarouselCamera, + TabsCarousel, + TabsTrigger, + type TabsContentProps, + type TabsIndicatorProps, + type TabsListProps, + type TabsRootProps, + type TabsCarouselCameraProps, + type TabsCarouselProps, + type TabsTriggerProps, +} from "./Tabs"; -import type { ContentProps, TriggerProps, UseTabsProps } from "./types"; -import type { UseSwipeableProps } from "./useSwipeable"; +export * as Tabs from "./Tabs.namespace"; -export { useLazyContents, useTabs, useSwipeable }; -export type { ContentProps, TriggerProps, UseTabsProps, UseLazyContentsProps, UseSwipeableProps }; +export { useTabsContext, type UseTabsContext } from "./useTabsContext"; +export { + useTabsCarouselContext, + type UseTabsCarouselContext, +} from "./useTabsCarouselContext"; +export { useTabsTriggerContext, type UseTabsTriggerContext } from "./useTabsTriggerContext"; diff --git a/packages/react-headless/tabs/src/private/useRenderStrategy.ts b/packages/react-headless/tabs/src/private/useRenderStrategy.ts new file mode 100644 index 000000000..f71cdaf0e --- /dev/null +++ b/packages/react-headless/tabs/src/private/useRenderStrategy.ts @@ -0,0 +1,36 @@ +import { useRef } from "react"; + +export interface UseRenderStrategyProps { + /** + * If `true`, the component will be mounted lazily. + * @default false + */ + lazyMount?: boolean; + + /** + * If `true`, the component will be unmounted when it's not selected. + * @default false + * */ + unmountOnExit?: boolean; +} + +export type UseRenderStrategyReturn = ReturnType; + +export function useRenderStrategy(props: UseRenderStrategyProps) { + const wasEverPresent = useRef(false); + + function getUnmounted(isPresent: boolean) { + if (isPresent) { + wasEverPresent.current = true; + } + + return ( + (!isPresent && !wasEverPresent.current && props.lazyMount) || + (props.unmountOnExit && !isPresent && wasEverPresent.current) + ); + } + + return { + getUnmounted, + }; +} diff --git a/packages/react-headless/tabs/src/private/useRenderStrategyContext.tsx b/packages/react-headless/tabs/src/private/useRenderStrategyContext.tsx new file mode 100644 index 000000000..4186111c2 --- /dev/null +++ b/packages/react-headless/tabs/src/private/useRenderStrategyContext.tsx @@ -0,0 +1,21 @@ +import { createContext, useContext } from "react"; +import type { UseRenderStrategyReturn } from "./useRenderStrategy"; + +export interface UseRenderStrategyContext extends UseRenderStrategyReturn {} + +const RenderStrategyContext = createContext(null); + +export const RenderStrategyProvider = RenderStrategyContext.Provider; + +export function useRenderStrategyContext({ + strict = true, +}: { strict?: T } = {}): T extends false + ? UseRenderStrategyContext | null + : UseRenderStrategyContext { + const context = useContext(RenderStrategyContext); + if (!context && strict) { + throw new Error("useRenderStrategyContext must be used within a RenderStrategy"); + } + + return context as UseRenderStrategyContext; +} diff --git a/packages/react-headless/tabs/src/types.ts b/packages/react-headless/tabs/src/types.ts deleted file mode 100644 index 06ed9d516..000000000 --- a/packages/react-headless/tabs/src/types.ts +++ /dev/null @@ -1,58 +0,0 @@ -export type Vector2 = [number, number]; - -export interface UseSwipeableStateProps { - /** - * tab swipe 기능 활성화 여부 - * @default false - */ - isSwipeable?: boolean; - - onSwipeStart?: () => void; - onSwipeEnd?: () => void; -} - -export interface UseTabsStateProps { - value?: string; - defaultValue?: string; - onValueChange?: (value: string) => void; -} - -export interface UseTabsProps extends UseTabsStateProps, UseSwipeableStateProps { - swipeConfig?: { - /** - * @default 0.3 - * The minimum velocity per axis (in pixels / ms) the drag gesture needs to - * reach before the pointer is released. - */ - velocity?: number | Vector2; - /** - * @default 50 - * The minimum distance per axis (in pixels) the drag gesture needs to - * travel to trigger a swipe. Defaults to 50. - */ - distance?: number | Vector2; - /** - * @default 250 - * The maximum duration in milliseconds that a swipe is detected. Defaults - * to 250. - */ - duration?: number; - }; - - orientation?: "horizontal" | "vertical"; -} - -export interface TriggerProps { - value: string; - isDisabled?: boolean; -} - -export interface ContentProps { - value: string; - - /** - * @default "keep" - * @description 실제 value에 해당하는 컨텐츠를 보여줄 때, 다른 컨텐츠를 숨길지 여부 - */ - visibilityMode?: "hidden" | "keep"; -} diff --git a/packages/react-headless/tabs/src/useLazyContents.test.tsx b/packages/react-headless/tabs/src/useLazyContents.test.tsx deleted file mode 100644 index 0c69fae9c..000000000 --- a/packages/react-headless/tabs/src/useLazyContents.test.tsx +++ /dev/null @@ -1,223 +0,0 @@ -import "@testing-library/jest-dom/vitest"; -import { cleanup, render } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import { afterEach, describe, expect, it } from "vitest"; - -import type { ReactElement } from "react"; -import * as React from "react"; - -import { - useLazyContents, - useTabs, - type ContentProps, - type TriggerProps, - type UseLazyContentsProps, - type UseTabsProps, -} from "./index"; - -afterEach(cleanup); - -/** - * @see https://github.com/ZeeCoder/use-resize-observer/issues/40#issuecomment-644536259 - * useSize에서 사용하는 ResizeObserver를 mock으로 대체합니다. - */ -class ResizeObserver { - observe() {} - unobserve() {} - disconnect() {} -} - -function setUp(jsx: ReactElement) { - return { - user: userEvent.setup(), - ...render(jsx), - }; -} - -const TabsContext = React.createContext<{ - api: ReturnType; - shouldRender?: (value: string) => boolean; -} | null>(null); - -const useTabsContext = () => { - const context = React.useContext(TabsContext); - if (!context) { - throw new Error("Tabs cannot be rendered outside the Tabs"); - } - return context; -}; - -function TabsWithLazy( - props: React.PropsWithChildren>, -) { - const api = useTabs(props); - const { rootProps, value } = api; - const { shouldRender } = useLazyContents({ - currentValue: value, - lazyMode: props.lazyMode, - isLazy: props.isLazy, - }); - - return ( -
    - {props.children} -
    - ); -} - -function TabTriggerList(props: React.PropsWithChildren) { - const { api } = useTabsContext(); - const { tabTriggerListProps } = api; - return
    {props.children}
    ; -} - -function TabTrigger(props: React.PropsWithChildren) { - const { api } = useTabsContext(); - const { getTabTriggerProps } = api; - const { labelProps, notificationProps, rootProps } = getTabTriggerProps(props); - - return ( - - ); -} - -function TabContentList(props: React.PropsWithChildren) { - const { api } = useTabsContext(); - const { tabContentListProps, tabContentCameraProps } = api; - return ( -
    -
    {props.children}
    -
    - ); -} - -function TabContentWithLazy(props: React.PropsWithChildren) { - const { api, shouldRender } = useTabsContext(); - const { getTabContentProps } = api; - const tabContentProps = getTabContentProps(props); - - return
    {shouldRender(props.value) && props.children}
    ; -} - -const tabs = { - tab1: { - value: "Tab 1", - label: "Label 1", - content: "Content 1", - }, - tab2: { - value: "Tab 2", - label: "Label 2", - content: "Content 2", - }, - tab3: { - value: "Tab 3", - label: "Label 3", - content: "Content 3", - }, -}; - -function LazyTabs(props: UseTabsProps & Omit) { - return ( - - - {Object.values(tabs).map(({ value, label }) => ( - - {label} - - ))} - - - {Object.values(tabs).map(({ value, content }) => ( - - {content} - - ))} - - - ); -} - -describe("useLazyContents", () => { - window.ResizeObserver = ResizeObserver; - - it("should render all tabs when isLazy=false, lazyMode='keepMounted'", async () => { - const { queryByText, user } = setUp(); - - await user.click(queryByText(tabs.tab1.label)); - - expect(queryByText(tabs.tab1.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab2.content)).toBeInTheDocument(); - }); - - it("should render all tabs when isLazy=false, lazyMode='unmount'", async () => { - const { queryByText, user } = setUp(); - - await user.click(queryByText(tabs.tab1.label)); - - expect(queryByText(tabs.tab1.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab2.content)).toBeInTheDocument(); - }); - - it("should only render first tab when isLazy=true, lazyMode='keepMounted'", async () => { - const { queryByText, user } = setUp(); - - await user.click(queryByText(tabs.tab1.label)); - - expect(queryByText(tabs.tab1.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab2.content)).not.toBeInTheDocument(); - }); - - it("should render all tabs after all tabs was selected when isLazy=true, lazyMode='keepMounted'", async () => { - const { queryByText, user } = setUp(); - - await user.click(queryByText(tabs.tab1.label)); - - // only render tab1 - expect(queryByText(tabs.tab1.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab2.content)).not.toBeInTheDocument(); - expect(queryByText(tabs.tab3.content)).not.toBeInTheDocument(); - - await user.click(queryByText(tabs.tab2.label)); - - // render tab1 and tab2 - expect(queryByText(tabs.tab1.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab2.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab3.content)).not.toBeInTheDocument(); - - await user.click(queryByText(tabs.tab3.label)); - - // render tab1, tab2 and tab3 - expect(queryByText(tabs.tab1.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab2.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab3.content)).toBeInTheDocument(); - }); - - it("should render only selected tab when isLazy=true, lazyMode='unmount'", async () => { - const { queryByText, user } = setUp(); - - await user.click(queryByText(tabs.tab1.label)); - - // only render tab1 - expect(queryByText(tabs.tab1.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab2.content)).not.toBeInTheDocument(); - expect(queryByText(tabs.tab3.content)).not.toBeInTheDocument(); - - await user.click(queryByText(tabs.tab2.label)); - - // only render tab2 - expect(queryByText(tabs.tab1.content)).not.toBeInTheDocument(); - expect(queryByText(tabs.tab2.content)).toBeInTheDocument(); - expect(queryByText(tabs.tab3.content)).not.toBeInTheDocument(); - - await user.click(queryByText(tabs.tab3.label)); - - // only render tab3 - expect(queryByText(tabs.tab1.content)).not.toBeInTheDocument(); - expect(queryByText(tabs.tab2.content)).not.toBeInTheDocument(); - expect(queryByText(tabs.tab3.content)).toBeInTheDocument(); - }); -}); diff --git a/packages/react-headless/tabs/src/useLazyContents.ts b/packages/react-headless/tabs/src/useLazyContents.ts deleted file mode 100644 index 80ad34432..000000000 --- a/packages/react-headless/tabs/src/useLazyContents.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { useEffect, useState } from "react"; - -export interface UseLazyContentsProps { - currentValue: string; - - isLazy?: boolean; - - lazyMode?: "keepMounted" | "unmount"; -} - -interface LazyOptions { - enabled?: boolean; - isSelected?: boolean; - wasSelected?: boolean; - mode?: UseLazyContentsProps["lazyMode"]; -} - -function lazyDisclosure(options: LazyOptions) { - const { enabled, isSelected, wasSelected, mode = "unmount" } = options; - - if (!enabled) return true; - - // if the disclosure is selected, render the disclosure's content - if (isSelected) return true; - - // if the disclosure was selected but not active, keep its content active - if (mode === "keepMounted" && wasSelected) return true; - - return false; -} - -export function useLazyContents(props: UseLazyContentsProps) { - const { currentValue, isLazy, lazyMode } = props; - const [previousValues, setPreviousValues] = useState>({}); - - useEffect(() => { - setPreviousValues((prev) => ({ - ...prev, - [currentValue]: true, - })); - }, [currentValue]); - - function shouldRender(value: string): boolean { - return lazyDisclosure({ - enabled: isLazy, - isSelected: value === currentValue, - wasSelected: previousValues[value], - mode: lazyMode, - }); - } - - return { - shouldRender, - }; -} diff --git a/packages/react-headless/tabs/src/useSwipeable.ts b/packages/react-headless/tabs/src/useSwipeable.ts deleted file mode 100644 index 564664c60..000000000 --- a/packages/react-headless/tabs/src/useSwipeable.ts +++ /dev/null @@ -1,129 +0,0 @@ -import * as React from "react"; - -import { type FullGestureState, useGesture } from "@use-gesture/react"; - -import type { UseSwipeableStateProps } from "./types"; - -const useSwipeableState = (props: UseSwipeableStateProps) => { - const { isSwipeable, onSwipeEnd, onSwipeStart } = props; - const [swipeStatus, setSwipeStatus] = React.useState<"idle" | "dragging">("idle"); - const [swipeMoveX, setSwipeMoveX] = React.useState(0); - - return { - swipeStatus, - swipeMoveX, - onDrag: ( - state: Omit, "event"> & { - event: PointerEvent | MouseEvent | TouchEvent | KeyboardEvent; - }, - ) => { - if (!isSwipeable) return; - - setSwipeMoveX(state.movement[0]); - }, - onDragStart: () => { - if (!isSwipeable) return; - - onSwipeStart?.(); - setSwipeStatus("dragging"); - }, - onDragEnd: () => { - if (!isSwipeable) return; - - onSwipeEnd?.(); - setSwipeStatus("idle"); - setSwipeMoveX(0); - }, - }; -}; - -export type Vector2 = [number, number]; - -export interface UseSwipeableProps extends UseSwipeableStateProps { - onSwipeLeftToRight?: () => void; - onSwipeRightToLeft?: () => void; - - swipeConfig?: { - /** - * @default 0.3 - * The minimum velocity per axis (in pixels / ms) the drag gesture needs to - * reach before the pointer is released. - */ - velocity?: number | Vector2; - /** - * @default 50 - * The minimum distance per axis (in pixels) the drag gesture needs to - * travel to trigger a swipe. Defaults to 50. - */ - distance?: number | Vector2; - /** - * @default 250 - * The maximum duration in milliseconds that a swipe is detected. Defaults - * to 250. - */ - duration?: number; - }; -} - -export const useSwipeable = (props: UseSwipeableProps) => { - const { - isSwipeable = true, - swipeConfig, - onSwipeLeftToRight, - onSwipeRightToLeft, - onSwipeEnd, - onSwipeStart, - } = props; - - const { onDrag, onDragEnd, onDragStart, swipeMoveX, swipeStatus } = useSwipeableState({ - isSwipeable, - onSwipeEnd, - onSwipeStart, - }); - - const getDragProps = useGesture( - { - onDragStart: () => { - if (!isSwipeable) return; - - onDragStart(); - }, - - onDragEnd: ({ swipe: [swipeX] }) => { - if (!isSwipeable) return; - - if (swipeX === -1) onSwipeRightToLeft?.(); - - if (swipeX === 1) onSwipeLeftToRight?.(); - - onDragEnd(); - }, - - onDrag, - }, - { - drag: { - filterTaps: false, - preventScrollAxis: "y", - preventDefault: true, - swipe: { - distance: swipeConfig?.distance || 50, - velocity: swipeConfig?.velocity || 0.3, - duration: swipeConfig?.duration || 250, - }, - }, - }, - ); - - const dragProps = isSwipeable - ? { - ...getDragProps(), - } - : {}; - - return { - swipeMoveX, - swipeStatus, - dragProps, - }; -}; diff --git a/packages/react-headless/tabs/src/useTabs.test.tsx b/packages/react-headless/tabs/src/useTabs.test.tsx index 0ff06b80b..286a18709 100644 --- a/packages/react-headless/tabs/src/useTabs.test.tsx +++ b/packages/react-headless/tabs/src/useTabs.test.tsx @@ -49,16 +49,16 @@ function Tabs(props: React.PropsWithChildren) { ); } -function TabTriggerList(props: React.PropsWithChildren) { +function TabsList(props: React.PropsWithChildren) { const { api } = useTabsContext(); - const { tabTriggerListProps } = api; + const { listProps: tabTriggerListProps } = api; return
    {props.children}
    ; } -function TabTrigger(props: React.PropsWithChildren) { +function TabsTrigger(props: React.PropsWithChildren) { const { api } = useTabsContext(); - const { getTabTriggerProps } = api; - const { labelProps, notificationProps, rootProps } = getTabTriggerProps(props); + const { getTriggerProps: getTabsTriggerProps } = api; + const { labelProps, notificationProps, rootProps } = getTabsTriggerProps(props); return (