diff --git a/.pnp.cjs b/.pnp.cjs index a20190c..e8984ef 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -29,6 +29,7 @@ const RAW_RUNTIME_STATE = ["@commitlint/cli", "npm:19.6.1"],\ ["@commitlint/config-conventional", "npm:19.6.0"],\ ["@radix-ui/react-dialog", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:1.1.5"],\ + ["@radix-ui/react-toast", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:1.2.6"],\ ["@radix-ui/react-visually-hidden", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:1.1.1"],\ ["@storybook/addon-essentials", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:8.5.0"],\ ["@storybook/addon-interactions", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:8.5.0"],\ @@ -2292,6 +2293,36 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["@radix-ui/react-collection", [\ + ["npm:1.1.2", {\ + "packageLocation": "./.yarn/cache/@radix-ui-react-collection-npm-1.1.2-99cb65db59-8376aa0c0f.zip/node_modules/@radix-ui/react-collection/",\ + "packageDependencies": [\ + ["@radix-ui/react-collection", "npm:1.1.2"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.2", {\ + "packageLocation": "./.yarn/__virtual__/@radix-ui-react-collection-virtual-8e1fce0846/0/cache/@radix-ui-react-collection-npm-1.1.2-99cb65db59-8376aa0c0f.zip/node_modules/@radix-ui/react-collection/",\ + "packageDependencies": [\ + ["@radix-ui/react-collection", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.2"],\ + ["@radix-ui/react-compose-refs", "virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.1"],\ + ["@radix-ui/react-context", "virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.1"],\ + ["@radix-ui/react-primitive", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:2.0.2"],\ + ["@radix-ui/react-slot", "virtual:8e1fce08460584dcb29fb8e303830c127607b0bbe9c497b08cc7094f1905064c525354b944254c05714055f10c29c25daad9f1ede6441d75bfdcdb85b7babda4#npm:1.1.2"],\ + ["@types/react", "npm:18.3.18"],\ + ["@types/react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.5"],\ + ["react", "npm:18.3.1"],\ + ["react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.1"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@radix-ui/react-compose-refs", [\ ["npm:1.1.1", {\ "packageLocation": "./.yarn/cache/@radix-ui-react-compose-refs-npm-1.1.1-2480de3ef9-3e84580024.zip/node_modules/@radix-ui/react-compose-refs/",\ @@ -2384,6 +2415,35 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ + ["npm:1.1.5", {\ + "packageLocation": "./.yarn/cache/@radix-ui-react-dismissable-layer-npm-1.1.5-f531f953f8-05c5adfcd4.zip/node_modules/@radix-ui/react-dismissable-layer/",\ + "packageDependencies": [\ + ["@radix-ui/react-dismissable-layer", "npm:1.1.5"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.5", {\ + "packageLocation": "./.yarn/__virtual__/@radix-ui-react-dismissable-layer-virtual-150b17045c/0/cache/@radix-ui-react-dismissable-layer-npm-1.1.5-f531f953f8-05c5adfcd4.zip/node_modules/@radix-ui/react-dismissable-layer/",\ + "packageDependencies": [\ + ["@radix-ui/react-dismissable-layer", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.5"],\ + ["@radix-ui/primitive", "npm:1.1.1"],\ + ["@radix-ui/react-compose-refs", "virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.1"],\ + ["@radix-ui/react-primitive", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:2.0.2"],\ + ["@radix-ui/react-use-callback-ref", "virtual:9f9dcdaf5901958c78efa2392d9299bb381a71460708930508e4449872424c266f0c601ad84b4cbb05a13eee5867c3f70e780af659c17dd10a3fc7b354d86228#npm:1.1.0"],\ + ["@radix-ui/react-use-escape-keydown", "virtual:9f9dcdaf5901958c78efa2392d9299bb381a71460708930508e4449872424c266f0c601ad84b4cbb05a13eee5867c3f70e780af659c17dd10a3fc7b354d86228#npm:1.1.0"],\ + ["@types/react", "npm:18.3.18"],\ + ["@types/react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.5"],\ + ["react", "npm:18.3.1"],\ + ["react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.1"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }],\ ["virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.4", {\ "packageLocation": "./.yarn/__virtual__/@radix-ui-react-dismissable-layer-virtual-9f9dcdaf59/0/cache/@radix-ui-react-dismissable-layer-npm-1.1.4-c9500c86c8-8657bf3e7e.zip/node_modules/@radix-ui/react-dismissable-layer/",\ "packageDependencies": [\ @@ -2489,6 +2549,32 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ + ["npm:1.1.4", {\ + "packageLocation": "./.yarn/cache/@radix-ui-react-portal-npm-1.1.4-5d4a909642-e4038eb2f2.zip/node_modules/@radix-ui/react-portal/",\ + "packageDependencies": [\ + ["@radix-ui/react-portal", "npm:1.1.4"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.4", {\ + "packageLocation": "./.yarn/__virtual__/@radix-ui-react-portal-virtual-fa41425fc8/0/cache/@radix-ui-react-portal-npm-1.1.4-5d4a909642-e4038eb2f2.zip/node_modules/@radix-ui/react-portal/",\ + "packageDependencies": [\ + ["@radix-ui/react-portal", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.4"],\ + ["@radix-ui/react-primitive", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:2.0.2"],\ + ["@radix-ui/react-use-layout-effect", "virtual:5c244d354bef42ce878d59d62335b237cdf324168be51086f1b8f898f860e19b2aec28b76bec93885a80b746e0550d6fbd652d2f1bd3b3ee4c4574e7695a228a#npm:1.1.0"],\ + ["@types/react", "npm:18.3.18"],\ + ["@types/react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.5"],\ + ["react", "npm:18.3.1"],\ + ["react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.1"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }],\ ["virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.3", {\ "packageLocation": "./.yarn/__virtual__/@radix-ui-react-portal-virtual-08fd77d25a/0/cache/@radix-ui-react-portal-npm-1.1.3-4dd747e0ee-b3cd1a8151.zip/node_modules/@radix-ui/react-portal/",\ "packageDependencies": [\ @@ -2545,6 +2631,31 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ + ["npm:2.0.2", {\ + "packageLocation": "./.yarn/cache/@radix-ui-react-primitive-npm-2.0.2-53536e6763-1af7a33a86.zip/node_modules/@radix-ui/react-primitive/",\ + "packageDependencies": [\ + ["@radix-ui/react-primitive", "npm:2.0.2"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:2.0.2", {\ + "packageLocation": "./.yarn/__virtual__/@radix-ui-react-primitive-virtual-0ba88c4652/0/cache/@radix-ui-react-primitive-npm-2.0.2-53536e6763-1af7a33a86.zip/node_modules/@radix-ui/react-primitive/",\ + "packageDependencies": [\ + ["@radix-ui/react-primitive", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:2.0.2"],\ + ["@radix-ui/react-slot", "virtual:8e1fce08460584dcb29fb8e303830c127607b0bbe9c497b08cc7094f1905064c525354b944254c05714055f10c29c25daad9f1ede6441d75bfdcdb85b7babda4#npm:1.1.2"],\ + ["@types/react", "npm:18.3.18"],\ + ["@types/react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.5"],\ + ["react", "npm:18.3.1"],\ + ["react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.1"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }],\ ["virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:2.0.1", {\ "packageLocation": "./.yarn/__virtual__/@radix-ui-react-primitive-virtual-765778dc2a/0/cache/@radix-ui-react-primitive-npm-2.0.1-a63c88e534-6a562bec14.zip/node_modules/@radix-ui/react-primitive/",\ "packageDependencies": [\ @@ -2572,6 +2683,13 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ + ["npm:1.1.2", {\ + "packageLocation": "./.yarn/cache/@radix-ui-react-slot-npm-1.1.2-646d6951b9-81d4509180.zip/node_modules/@radix-ui/react-slot/",\ + "packageDependencies": [\ + ["@radix-ui/react-slot", "npm:1.1.2"]\ + ],\ + "linkType": "SOFT"\ + }],\ ["virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.1", {\ "packageLocation": "./.yarn/__virtual__/@radix-ui-react-slot-virtual-24517c8127/0/cache/@radix-ui-react-slot-npm-1.1.1-23892fb17a-f3cc71c165.zip/node_modules/@radix-ui/react-slot/",\ "packageDependencies": [\ @@ -2585,6 +2703,58 @@ const RAW_RUNTIME_STATE = "react"\ ],\ "linkType": "HARD"\ + }],\ + ["virtual:8e1fce08460584dcb29fb8e303830c127607b0bbe9c497b08cc7094f1905064c525354b944254c05714055f10c29c25daad9f1ede6441d75bfdcdb85b7babda4#npm:1.1.2", {\ + "packageLocation": "./.yarn/__virtual__/@radix-ui-react-slot-virtual-43b8050225/0/cache/@radix-ui-react-slot-npm-1.1.2-646d6951b9-81d4509180.zip/node_modules/@radix-ui/react-slot/",\ + "packageDependencies": [\ + ["@radix-ui/react-slot", "virtual:8e1fce08460584dcb29fb8e303830c127607b0bbe9c497b08cc7094f1905064c525354b944254c05714055f10c29c25daad9f1ede6441d75bfdcdb85b7babda4#npm:1.1.2"],\ + ["@radix-ui/react-compose-refs", "virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.1"],\ + ["@types/react", "npm:18.3.18"],\ + ["react", "npm:18.3.1"]\ + ],\ + "packagePeers": [\ + "@types/react",\ + "react"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@radix-ui/react-toast", [\ + ["npm:1.2.6", {\ + "packageLocation": "./.yarn/cache/@radix-ui-react-toast-npm-1.2.6-090f1eed9b-34334eb835.zip/node_modules/@radix-ui/react-toast/",\ + "packageDependencies": [\ + ["@radix-ui/react-toast", "npm:1.2.6"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:1.2.6", {\ + "packageLocation": "./.yarn/__virtual__/@radix-ui-react-toast-virtual-2baf2d2d64/0/cache/@radix-ui-react-toast-npm-1.2.6-090f1eed9b-34334eb835.zip/node_modules/@radix-ui/react-toast/",\ + "packageDependencies": [\ + ["@radix-ui/react-toast", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:1.2.6"],\ + ["@radix-ui/primitive", "npm:1.1.1"],\ + ["@radix-ui/react-collection", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.2"],\ + ["@radix-ui/react-compose-refs", "virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.1"],\ + ["@radix-ui/react-context", "virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.1"],\ + ["@radix-ui/react-dismissable-layer", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.5"],\ + ["@radix-ui/react-portal", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.4"],\ + ["@radix-ui/react-presence", "virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.2"],\ + ["@radix-ui/react-primitive", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:2.0.2"],\ + ["@radix-ui/react-use-callback-ref", "virtual:9f9dcdaf5901958c78efa2392d9299bb381a71460708930508e4449872424c266f0c601ad84b4cbb05a13eee5867c3f70e780af659c17dd10a3fc7b354d86228#npm:1.1.0"],\ + ["@radix-ui/react-use-controllable-state", "virtual:5c250568c0c5c23d295e66cf48eafb9443988da8119b081acc1a66c32705fe6541f862f293bf80f25180ae8db61e89bf87b75c2b4a6dd5c9652fe5c2995529d5#npm:1.1.0"],\ + ["@radix-ui/react-use-layout-effect", "virtual:5c244d354bef42ce878d59d62335b237cdf324168be51086f1b8f898f860e19b2aec28b76bec93885a80b746e0550d6fbd652d2f1bd3b3ee4c4574e7695a228a#npm:1.1.0"],\ + ["@radix-ui/react-visually-hidden", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.2"],\ + ["@types/react", "npm:18.3.18"],\ + ["@types/react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.5"],\ + ["react", "npm:18.3.1"],\ + ["react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.1"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@radix-ui/react-use-callback-ref", [\ @@ -2685,6 +2855,31 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ + ["npm:1.1.2", {\ + "packageLocation": "./.yarn/cache/@radix-ui-react-visually-hidden-npm-1.1.2-f7a0bfd13c-ea6dc8ec28.zip/node_modules/@radix-ui/react-visually-hidden/",\ + "packageDependencies": [\ + ["@radix-ui/react-visually-hidden", "npm:1.1.2"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.2", {\ + "packageLocation": "./.yarn/__virtual__/@radix-ui-react-visually-hidden-virtual-a1d71c8f0e/0/cache/@radix-ui-react-visually-hidden-npm-1.1.2-f7a0bfd13c-ea6dc8ec28.zip/node_modules/@radix-ui/react-visually-hidden/",\ + "packageDependencies": [\ + ["@radix-ui/react-visually-hidden", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:1.1.2"],\ + ["@radix-ui/react-primitive", "virtual:2baf2d2d64616d564665d651fe1375d22bd4ba00ec40db06f727759074f4cc3e9cfd1d945a4bd4c8a51bd1dcdd44a573e66e63e6ce4dc31de7628a6f206f7086#npm:2.0.2"],\ + ["@types/react", "npm:18.3.18"],\ + ["@types/react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.5"],\ + ["react", "npm:18.3.1"],\ + ["react-dom", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:18.3.1"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }],\ ["virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:1.1.1", {\ "packageLocation": "./.yarn/__virtual__/@radix-ui-react-visually-hidden-virtual-28b806a908/0/cache/@radix-ui-react-visually-hidden-npm-1.1.1-d1e551a0fa-9a34b8e09d.zip/node_modules/@radix-ui/react-visually-hidden/",\ "packageDependencies": [\ @@ -10578,6 +10773,7 @@ const RAW_RUNTIME_STATE = ["@commitlint/cli", "npm:19.6.1"],\ ["@commitlint/config-conventional", "npm:19.6.0"],\ ["@radix-ui/react-dialog", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:1.1.5"],\ + ["@radix-ui/react-toast", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:1.2.6"],\ ["@radix-ui/react-visually-hidden", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:1.1.1"],\ ["@storybook/addon-essentials", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:8.5.0"],\ ["@storybook/addon-interactions", "virtual:bf4b7fdd92a9723d0b8b3c0ad1d9b3bf177b06bda2d8d90eee6bb9b559bcf7f6a4e86d3e1e4088168d00f3b758fa58c40c57bffe4a3e68627cd86f7a3c1c2191#npm:8.5.0"],\ diff --git a/.yarn/cache/@radix-ui-react-collection-npm-1.1.2-99cb65db59-8376aa0c0f.zip b/.yarn/cache/@radix-ui-react-collection-npm-1.1.2-99cb65db59-8376aa0c0f.zip new file mode 100644 index 0000000..4180b5d Binary files /dev/null and b/.yarn/cache/@radix-ui-react-collection-npm-1.1.2-99cb65db59-8376aa0c0f.zip differ diff --git a/.yarn/cache/@radix-ui-react-dismissable-layer-npm-1.1.5-f531f953f8-05c5adfcd4.zip b/.yarn/cache/@radix-ui-react-dismissable-layer-npm-1.1.5-f531f953f8-05c5adfcd4.zip new file mode 100644 index 0000000..a687fbf Binary files /dev/null and b/.yarn/cache/@radix-ui-react-dismissable-layer-npm-1.1.5-f531f953f8-05c5adfcd4.zip differ diff --git a/.yarn/cache/@radix-ui-react-portal-npm-1.1.4-5d4a909642-e4038eb2f2.zip b/.yarn/cache/@radix-ui-react-portal-npm-1.1.4-5d4a909642-e4038eb2f2.zip new file mode 100644 index 0000000..ba87c15 Binary files /dev/null and b/.yarn/cache/@radix-ui-react-portal-npm-1.1.4-5d4a909642-e4038eb2f2.zip differ diff --git a/.yarn/cache/@radix-ui-react-primitive-npm-2.0.2-53536e6763-1af7a33a86.zip b/.yarn/cache/@radix-ui-react-primitive-npm-2.0.2-53536e6763-1af7a33a86.zip new file mode 100644 index 0000000..6c930c4 Binary files /dev/null and b/.yarn/cache/@radix-ui-react-primitive-npm-2.0.2-53536e6763-1af7a33a86.zip differ diff --git a/.yarn/cache/@radix-ui-react-slot-npm-1.1.2-646d6951b9-81d4509180.zip b/.yarn/cache/@radix-ui-react-slot-npm-1.1.2-646d6951b9-81d4509180.zip new file mode 100644 index 0000000..625c95e Binary files /dev/null and b/.yarn/cache/@radix-ui-react-slot-npm-1.1.2-646d6951b9-81d4509180.zip differ diff --git a/.yarn/cache/@radix-ui-react-toast-npm-1.2.6-090f1eed9b-34334eb835.zip b/.yarn/cache/@radix-ui-react-toast-npm-1.2.6-090f1eed9b-34334eb835.zip new file mode 100644 index 0000000..c088670 Binary files /dev/null and b/.yarn/cache/@radix-ui-react-toast-npm-1.2.6-090f1eed9b-34334eb835.zip differ diff --git a/.yarn/cache/@radix-ui-react-visually-hidden-npm-1.1.2-f7a0bfd13c-ea6dc8ec28.zip b/.yarn/cache/@radix-ui-react-visually-hidden-npm-1.1.2-f7a0bfd13c-ea6dc8ec28.zip new file mode 100644 index 0000000..34e58ae Binary files /dev/null and b/.yarn/cache/@radix-ui-react-visually-hidden-npm-1.1.2-f7a0bfd13c-ea6dc8ec28.zip differ diff --git a/package.json b/package.json index 3ebc62c..1cae871 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ }, "dependencies": { "@radix-ui/react-dialog": "^1.1.5", + "@radix-ui/react-toast": "^1.2.6", "@radix-ui/react-visually-hidden": "^1.1.1", "@tanstack/react-query": "^5.64.2", "canvas-confetti": "^1.9.3", diff --git a/src/components/ui/Toast/Toast.module.scss b/src/components/ui/Toast/Toast.module.scss index 5880167..27de95d 100644 --- a/src/components/ui/Toast/Toast.module.scss +++ b/src/components/ui/Toast/Toast.module.scss @@ -19,20 +19,67 @@ } } +.ToastViewport { + position: fixed; + left: 50%; + bottom: 7rem; + z-index: 9999; + width: fit-content; + display: flex; + flex-direction: column; + gap: 0.5rem; + transform: translateX(-50%); + width: calc(100% - 2.5rem); +} + .Toast { - width: 100%; - height: 3.25rem; - z-index: 2; - border-radius: 0.75rem; - background-color: white; - padding: 0.875rem 1.125rem; + &[data-swipe="cancel"] { + transform: translateX(0); + } + &[data-swipe="end"] { + transform: translateX(var(--radix-toast-swipe-end-x)); + } + &[data-swipe="move"] { + transform: translateX(var(--radix-toast-swipe-move-x)); + } + &[data-state="open"] { + animation: slide-in-from-bottom-full 0.4s ease-out forwards; + } + + &[data-state="closed"] { + animation: slide-out-to-bottom-full 0.4s ease-in forwards; + } +} + +@keyframes slide-in-from-bottom-full { + from { + opacity: 0; + transform: translateY(300%); + } + to { + opacity: 1; + transform: translateY(0); + } +} - transition: - opacity 0.3s, - transform 0.3s; +@keyframes slide-out-to-bottom-full { + from { + opacity: 1; + transform: translateY(0); + } + to { + opacity: 0; + transform: translateY(300%); + } } -.show { - opacity: 1; - transform: translateY(0); +.Toaster { + border-radius: 0.75rem; + background-color: var(--color-white); + width: 100%; + padding: 0.875rem 1.125rem; + + & > span { + line-height: 1.5rem; + } } diff --git a/src/components/ui/Toast/Toast.stories.tsx b/src/components/ui/Toast/Toast.stories.tsx deleted file mode 100644 index 2578950..0000000 --- a/src/components/ui/Toast/Toast.stories.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import Toast from "@/components/ui/Toast/Toast"; - -import type { Meta, StoryObj } from "@storybook/react"; - -type ToastProps = { - text: string; -}; - -const meta: Meta = { - title: "Example/Toast", - component: Toast, -}; - -export default meta; - -export const Primary: StoryObj = { - args: { - text: "링크가 복사되었어요.", - }, -}; diff --git a/src/components/ui/Toast/Toast.tsx b/src/components/ui/Toast/Toast.tsx index 6b9aebe..36b0b82 100644 --- a/src/components/ui/Toast/Toast.tsx +++ b/src/components/ui/Toast/Toast.tsx @@ -1,20 +1,54 @@ import { forwardRef } from "react"; +import * as ToastPrimitives from "@radix-ui/react-toast"; import classNames from "classnames"; -import Text from "@/components/ui/Text/Text"; import styles from "@/components/ui/Toast/Toast.module.scss"; -export interface ToastProps extends React.HTMLAttributes { - text: string; -} +import { useToast } from "@/hooks/common/useToast"; + +const ToastProvider = ToastPrimitives.Provider; + +const ToastViewport = forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +ToastViewport.displayName = ToastPrimitives.Viewport.displayName; + +const Toast = forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, open, id, ...props }, ref) => { + const { removeToast } = useToast(); -const Toast = forwardRef(({ text, className, ...props }, ref) => { return ( -
- {text} -
+ { + if (!isOpen) { + setTimeout(() => removeToast(id), 400); // 0.4초 뒤 제거 + } + }} + className={classNames(styles.Toast, className)} + {...props} + /> ); }); +Toast.displayName = ToastPrimitives.Root.displayName; + +const ToastTitle = forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +ToastTitle.displayName = ToastPrimitives.Title.displayName; -export default Toast; +export { ToastProvider, ToastViewport, Toast, ToastTitle }; diff --git a/src/components/ui/Toast/Toaster.tsx b/src/components/ui/Toast/Toaster.tsx new file mode 100644 index 0000000..8701f84 --- /dev/null +++ b/src/components/ui/Toast/Toaster.tsx @@ -0,0 +1,32 @@ +import Text from "@/components/ui/Text/Text"; +import { Toast, ToastProvider, ToastViewport } from "@/components/ui/Toast/Toast"; +import styles from "@/components/ui/Toast/Toast.module.scss"; + +import { useToast } from "@/hooks/common/useToast"; + +export function Toaster() { + const { toasts, removeToast } = useToast(); + + return ( + + {toasts.map(({ id, duration, open }) => ( + { + if (!isOpen) { + setTimeout(() => removeToast(id), 400); + } + }} + className={styles.Toaster} + > + + 링크가 복사되었어요. + + + ))} + + + ); +} diff --git a/src/hooks/common/useToast.ts b/src/hooks/common/useToast.ts deleted file mode 100644 index ffe0ed3..0000000 --- a/src/hooks/common/useToast.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useState } from "react"; - -interface UseToastReturn { - isToast: boolean; - showToast: () => void; -} - -const useToast = (duration: number = 1000): UseToastReturn => { - const [isToast, setIsToast] = useState(false); - - const showToast = () => { - setIsToast(true); - setTimeout(() => { - setIsToast(false); - }, duration); - }; - - return { isToast, showToast }; -}; - -export default useToast; diff --git a/src/hooks/common/useToast.tsx b/src/hooks/common/useToast.tsx new file mode 100644 index 0000000..9c315b3 --- /dev/null +++ b/src/hooks/common/useToast.tsx @@ -0,0 +1,59 @@ +import type { ReactNode } from "react"; +import { createContext, useContext, useState } from "react"; + +type ToastType = { + id: string; + title: string; + open: boolean; + duration?: number; +}; + +type ToastContextType = { + toasts: ToastType[]; + addToast: (title: string, duration?: number) => string; + removeToast: (id?: string) => void; +}; + +const ToastContext = createContext(undefined); + +export function ToastProvider({ children }: { children: ReactNode }) { + const [toasts, setToasts] = useState([]); + + const addToast = (title: string, duration = 3000): string => { + const id = crypto.randomUUID(); + + const isToastOpen = toasts.some((toast) => toast.open); + + if (isToastOpen) { + return ""; + } + + const newToast: ToastType = { + id, + title, + open: true, + duration, + }; + setToasts((prev) => [...prev, newToast]); + + return id; + }; + + const removeToast = (id?: string) => { + setToasts((prev) => prev.map((toast) => (toast.id === id ? { ...toast, open: false } : toast))); + }; + + return ( + + {children} + + ); +} + +export function useToast() { + const context = useContext(ToastContext); + if (!context) { + throw new Error("useToast must be used within a ToastProvider"); + } + return context; +} diff --git a/src/main.tsx b/src/main.tsx index 3a49d45..ab3eb9d 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -8,6 +8,9 @@ import AppRouter from "@/router/AppRouter"; import { AppBridgeProvider } from "@/components/provider/AppBridgeProvider/AppBridgeProvider"; import ReactQueryClientProvider from "@/components/provider/ReactQueryClientProvider"; import { UserAgentProvider } from "@/components/provider/UserAgentProvider"; +import { Toaster } from "@/components/ui/Toast/Toaster"; + +import { ToastProvider } from "@/hooks/common/useToast"; import "@/styles/reset.scss"; import "@/styles/global.scss"; @@ -17,8 +20,11 @@ ReactDom.createRoot(document.getElementById("root")!).render( - - + + + + + diff --git a/src/pages/ReviewResultPage/ReviewResultPage.tsx b/src/pages/ReviewResultPage/ReviewResultPage.tsx index 0e89f13..980e228 100644 --- a/src/pages/ReviewResultPage/ReviewResultPage.tsx +++ b/src/pages/ReviewResultPage/ReviewResultPage.tsx @@ -11,6 +11,7 @@ import Text from "@/components/ui/Text/Text"; import { useOverlay } from "@/hooks/common/useOverlay"; import { useRoute } from "@/hooks/common/useRoute"; +import { useToast } from "@/hooks/common/useToast"; import styles from "@/pages/ReviewResultPage/ReviewResultPage.module.scss"; @@ -29,6 +30,8 @@ export default function ReviewResultPage() { const { isOpen, handleClose, handleOpen } = useOverlay(); + const { addToast } = useToast(); + const { ocrText, hashTag, reviewStyle } = createReviewData; const handleConfetti = () => { @@ -86,11 +89,12 @@ export default function ReviewResultPage() { size="sm" onClick={() => { send({ type: AppBridgeMessageType.COPY, payload: { review: generateReviewData } }); + + addToast("리뷰가 복사되었어요"); }} /> -