From 1b499cf75c3cb3232b78b4e26314caaaac9f16ea Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Sep 2023 21:05:27 +0900 Subject: [PATCH 1/4] chore(dep): add @radix-ui/react-select --- packages/components/package.json | 1 + pnpm-lock.yaml | 242 ++++++++++++++++++++++++++++++- 2 files changed, 242 insertions(+), 1 deletion(-) diff --git a/packages/components/package.json b/packages/components/package.json index f450131..23491fe 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -10,6 +10,7 @@ "build:storybook": "storybook build" }, "dependencies": { + "@radix-ui/react-select": "^1.2.2", "@radix-ui/react-tooltip": "^1.0.6", "clsx": "^1.2.1", "react": "^18.2.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4b8263..6a2f571 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -105,6 +105,9 @@ importers: packages/components: dependencies: + '@radix-ui/react-select': + specifier: ^1.2.2 + version: 1.2.2(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-tooltip': specifier: ^1.0.6 version: 1.0.6(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) @@ -3031,6 +3034,12 @@ packages: fastq: 1.15.0 dev: true + /@radix-ui/number@1.0.1: + resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} + dependencies: + '@babel/runtime': 7.22.5 + dev: false + /@radix-ui/primitive@1.0.1: resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} dependencies: @@ -3057,6 +3066,29 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-collection@1.0.3(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.14)(react@18.2.0): resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} peerDependencies: @@ -3085,6 +3117,20 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-direction@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + /@radix-ui/react-dismissable-layer@1.0.4(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==} peerDependencies: @@ -3109,6 +3155,42 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-focus-scope@1.0.3(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-id@1.0.1(@types/react@18.2.14)(react@18.2.0): resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} peerDependencies: @@ -3214,6 +3296,46 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-select@1.2.2(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/number': 1.0.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.4(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.3(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-popper': 1.1.2(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.3(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.14 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.14)(react@18.2.0) + dev: false + /@radix-ui/react-slot@1.0.2(@types/react@18.2.14)(react@18.2.0): resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: @@ -3318,6 +3440,20 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.14)(react@18.2.0): resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} peerDependencies: @@ -5168,6 +5304,13 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true + /aria-hidden@1.2.3: + resolution: {integrity: sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==} + engines: {node: '>=10'} + dependencies: + tslib: 2.6.0 + dev: false + /aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} dependencies: @@ -5969,6 +6112,10 @@ packages: engines: {node: '>=8'} dev: true + /detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dev: false + /detect-package-manager@2.0.1: resolution: {integrity: sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==} engines: {node: '>=12'} @@ -6834,6 +6981,11 @@ packages: has-symbols: 1.0.3 dev: true + /get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + dev: false + /get-npm-tarball-url@2.0.3: resolution: {integrity: sha512-R/PW6RqyaBQNWYaSyfrh54/qtcnOp22FHCCiRhSSZj0FP3KQWCsxxt0DzIdVTbwTqe9CtQfvl/FPD4UIPt4pqw==} engines: {node: '>=12.17'} @@ -7196,6 +7348,12 @@ packages: engines: {node: '>= 0.10'} dev: true + /invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: false + /ip@2.0.0: resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} dev: true @@ -8755,6 +8913,58 @@ packages: engines: {node: '>=0.10.0'} dev: true + /react-remove-scroll-bar@2.3.4(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.14 + react: 18.2.0 + react-style-singleton: 2.2.1(@types/react@18.2.14)(react@18.2.0) + tslib: 2.6.0 + dev: false + + /react-remove-scroll@2.5.5(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.14 + react: 18.2.0 + react-remove-scroll-bar: 2.3.4(@types/react@18.2.14)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.14)(react@18.2.0) + tslib: 2.6.0 + use-callback-ref: 1.3.0(@types/react@18.2.14)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.14)(react@18.2.0) + dev: false + + /react-style-singleton@2.2.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.14 + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.2.0 + tslib: 2.6.0 + dev: false + /react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -9557,7 +9767,6 @@ packages: /tslib@2.6.0: resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==} - dev: true /tsutils@3.21.0(typescript@5.1.5): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} @@ -9822,6 +10031,21 @@ packages: punycode: 2.3.0 dev: true + /use-callback-ref@1.3.0(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.14 + react: 18.2.0 + tslib: 2.6.0 + dev: false + /use-resize-observer@9.1.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==} peerDependencies: @@ -9833,6 +10057,22 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true + /use-sidecar@1.1.2(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.14 + detect-node-es: 1.1.0 + react: 18.2.0 + tslib: 2.6.0 + dev: false + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true From 83c586dd684be76d0c438c8448d0204b1dca5dd0 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Sep 2023 21:55:41 +0900 Subject: [PATCH 2/4] feat: implement selectbox --- packages/components/src/index.ts | 1 + .../src/select-box/SelectBox.module.scss | 136 ++++++++++++++++++ .../src/select-box/SelectBox.stories.tsx | 33 +++++ .../components/src/select-box/SelectBox.tsx | 53 +++++++ packages/components/src/select-box/index.ts | 1 + 5 files changed, 224 insertions(+) create mode 100644 packages/components/src/select-box/SelectBox.module.scss create mode 100644 packages/components/src/select-box/SelectBox.stories.tsx create mode 100644 packages/components/src/select-box/SelectBox.tsx create mode 100644 packages/components/src/select-box/index.ts diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 72f50c8..cebc5ae 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -3,3 +3,4 @@ export * from './card'; export * from './tooltip'; export * from './timeline'; export * from './input'; +export * from './select-box'; diff --git a/packages/components/src/select-box/SelectBox.module.scss b/packages/components/src/select-box/SelectBox.module.scss new file mode 100644 index 0000000..e2f3d8a --- /dev/null +++ b/packages/components/src/select-box/SelectBox.module.scss @@ -0,0 +1,136 @@ +.trigger { + display: flex; + align-items: center; + justify-content: space-between; + height: 100%; + padding: 0.5rem 0.5rem 0.5rem 1rem; + gap: 0.5rem; + border-radius: 0.5rem; + border-width: 2px; + border-style: solid; + font-size: 1rem; + cursor: pointer; + transition: border-color 0.2s ease-in-out; + + :global(.light) & { + border-color: $color-gray-200; + background-color: $color-gray-100; + color: $color-gray-900; + + &:hover { + border-color: $color-gray-400; + } + + &:focus { + outline: none; + } + + &:focus-visible { + outline-offset: -2px; + border-color: $color-green-400; + } + + &[data-placeholder] { + color: $color-gray-500; + } + } + + :global(.dark) & { + border-color: $color-gray-700; + background-color: $color-gray-800; + color: $color-gray-50; + + &:hover { + border-color: $color-gray-500; + } + + &:focus { + outline: none; + } + + &:focus-visible { + outline-offset: -2px; + border-color: $color-green-500; + } + + &[data-placeholder] { + color: $color-gray-400; + } + } + + &.expanded { + width: 100%; + } +} + +.icon { + transition: transform 0.3s ease-in-out; + line-height: 0; + + .trigger[data-state='open'] & { + transform: rotate(-180deg); + } +} + +.content { + display: flex; + align-items: stretch; + justify-content: space-between; + width: 100%; + padding: 0.5rem; + box-sizing: border-box; + border-radius: 0.5rem; + transition: border-color 0.2s ease-in-out; + + :global(.light) &, + &:global(.light) { + background-color: $color-gray-200; + box-shadow: $shadow-light; + } + + :global(.dark) &, + &:global(.dark) { + background-color: $color-gray-700; + box-shadow: $shadow-dark; + } +} + +.item { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + padding: 0.5rem; + box-sizing: border-box; + border-radius: 0.5rem; + transition: background-color 0.2s ease-in-out; + cursor: pointer; + + :global(.light) & { + color: $color-gray-900; + + &:hover { + outline: none; + background-color: $color-gray-100; + } + + &:focus-visible { + outline-offset: -2px; + background-color: $color-gray-100; + } + } + + :global(.dark) & { + color: $color-gray-50; + + &:hover { + outline: none; + background-color: $color-gray-800; + } + + &:focus-visible { + outline-offset: -2px; + background-color: $color-gray-800; + } + } +} diff --git a/packages/components/src/select-box/SelectBox.stories.tsx b/packages/components/src/select-box/SelectBox.stories.tsx new file mode 100644 index 0000000..fc87171 --- /dev/null +++ b/packages/components/src/select-box/SelectBox.stories.tsx @@ -0,0 +1,33 @@ +import { Container } from '../__stories__/containter'; +import { VStack } from '../__stories__/v-stack'; + +import { Props, SelectBox } from './SelectBox'; + +import type { Meta } from '@storybook/react'; + +const meta: Meta = { + component: SelectBox, +}; + +export default meta; + +const SelectBoxes = (args: Props) => ( + + + + + + + + +); + +const DUMMY_OPTIONS = [ + { label: 'Option 1', value: 'option-1' }, + { label: 'Option Option 2', value: 'option-2' }, + { label: 'Option Option Option 3', value: 'option-3' }, +]; + +export const Default = () => ; + +export const Expanded = () => ; diff --git a/packages/components/src/select-box/SelectBox.tsx b/packages/components/src/select-box/SelectBox.tsx new file mode 100644 index 0000000..c465780 --- /dev/null +++ b/packages/components/src/select-box/SelectBox.tsx @@ -0,0 +1,53 @@ +import * as Select from '@radix-ui/react-select'; +import clsx from 'clsx'; +import { ChevronDown } from 'react-feather'; + +import styles from './SelectBox.module.scss'; + +export type Props = { + expanded?: boolean; + options: { + label: string; + value: string; + }[]; + placeholder?: string; + /** don't use this prop, it's for storybook only */ + _theme?: 'light' | 'dark'; +}; + +export const SelectBox = ({ + expanded = false, + options, + placeholder = 'Select an option', + _theme, +}: Props) => { + return ( + + + + + + + + + + + + + {options.map((option) => ( + + {option.label} + + ))} + + + + + ); +}; diff --git a/packages/components/src/select-box/index.ts b/packages/components/src/select-box/index.ts new file mode 100644 index 0000000..10ea3c1 --- /dev/null +++ b/packages/components/src/select-box/index.ts @@ -0,0 +1 @@ +export * from './SelectBox'; From 1d7adfe8c80e28ec8e8c3abde45a494f423797ce Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Sep 2023 22:32:04 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20selectbox=E3=81=ABgroup=E5=8C=96?= =?UTF-8?q?=E7=94=A8=E3=81=AE=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/select-box/SelectBox.module.scss | 47 ++++++++++++ .../src/select-box/SelectBox.stories.tsx | 29 ++++++- .../components/src/select-box/SelectBox.tsx | 76 +++++++++++++++---- 3 files changed, 136 insertions(+), 16 deletions(-) diff --git a/packages/components/src/select-box/SelectBox.module.scss b/packages/components/src/select-box/SelectBox.module.scss index e2f3d8a..eab5d62 100644 --- a/packages/components/src/select-box/SelectBox.module.scss +++ b/packages/components/src/select-box/SelectBox.module.scss @@ -134,3 +134,50 @@ } } } + +.groupLabel { + padding: 0.25rem; + font-size: 0.875rem; + + :global(.light) & { + color: $color-gray-600; + } + + :global(.dark) & { + color: $color-gray-300; + } +} + +.separator { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 2px; + margin: 0.5rem 0; + border-radius: 9999px; + transition: background-color 0.2s ease-in-out; + + :global(.light) & { + background-color: $color-gray-300; + } + + :global(.dark) & { + background-color: $color-gray-600; + } +} + +.scrollButton { + display: flex; + align-items: center; + justify-content: center; + cursor: default; + + :global(.light) & { + color: $color-gray-600; + } + + :global(.dark) & { + color: $color-gray-300; + } +} diff --git a/packages/components/src/select-box/SelectBox.stories.tsx b/packages/components/src/select-box/SelectBox.stories.tsx index fc87171..fb19c1f 100644 --- a/packages/components/src/select-box/SelectBox.stories.tsx +++ b/packages/components/src/select-box/SelectBox.stories.tsx @@ -28,6 +28,33 @@ const DUMMY_OPTIONS = [ { label: 'Option Option Option 3', value: 'option-3' }, ]; -export const Default = () => ; +const DUMMY_GROUPED_OPTIONS = [ + { + label: 'Group 1', + options: [ + { label: 'Option 1', value: 'option-1' }, + { label: 'Option Option 2', value: 'option-2' }, + { label: 'Option Option Option 3', value: 'option-3' }, + ], + }, + { + label: 'Group 2', + options: [ + { label: 'Option 4', value: 'option-4' }, + { label: 'Option Option 5', value: 'option-5' }, + { label: 'Option Option Option 6', value: 'option-6' }, + ], + }, +]; + +export const Simple = () => ; + +export const Grouped = () => ( + +); + +export const Placeholder = () => ( + +); export const Expanded = () => ; diff --git a/packages/components/src/select-box/SelectBox.tsx b/packages/components/src/select-box/SelectBox.tsx index c465780..6f3b032 100644 --- a/packages/components/src/select-box/SelectBox.tsx +++ b/packages/components/src/select-box/SelectBox.tsx @@ -1,23 +1,69 @@ import * as Select from '@radix-ui/react-select'; import clsx from 'clsx'; -import { ChevronDown } from 'react-feather'; +import { ChevronDown, ChevronUp } from 'react-feather'; import styles from './SelectBox.module.scss'; +type SingleGroupOptions = { + label: string; + value: string; +}[]; + +type GroupedOptions = { + label: string; + options: SingleGroupOptions; +}[]; + export type Props = { expanded?: boolean; - options: { - label: string; - value: string; - }[]; placeholder?: string; /** don't use this prop, it's for storybook only */ _theme?: 'light' | 'dark'; +} & ( + | { + options: SingleGroupOptions; + groupedOptions?: undefined; + } + | { + options?: undefined; + groupedOptions: GroupedOptions; + } +); + +const SelectBoxItems = ({ options }: { options: SingleGroupOptions }) => { + return options.map((option) => ( + + {option.label} + + )); +}; + +const SelectBoxGroups = ({ + groupedOptions, +}: { + groupedOptions: GroupedOptions; +}) => { + return groupedOptions.map((group, i) => ( + <> + + {group.label} + + + {i < groupedOptions.length - 1 && ( + + )} + + )); }; export const SelectBox = ({ expanded = false, options, + groupedOptions, placeholder = 'Select an option', _theme, }: Props) => { @@ -34,18 +80,18 @@ export const SelectBox = ({ - + + + - {options.map((option) => ( - - {option.label} - - ))} + {options && } + {groupedOptions && ( + + )} + + + From 648bf6770d9c70bf51b442afb570bda50b8aa3d6 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Sep 2023 22:33:46 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=E6=A8=AA=E5=B9=85=E3=81=AE=E3=82=B9?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=AB=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/components/src/select-box/SelectBox.module.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/components/src/select-box/SelectBox.module.scss b/packages/components/src/select-box/SelectBox.module.scss index eab5d62..2a5bef3 100644 --- a/packages/components/src/select-box/SelectBox.module.scss +++ b/packages/components/src/select-box/SelectBox.module.scss @@ -100,7 +100,7 @@ align-items: center; justify-content: space-between; width: 100%; - padding: 0.5rem; + padding: 0.5rem 1rem; box-sizing: border-box; border-radius: 0.5rem; transition: background-color 0.2s ease-in-out; @@ -136,15 +136,15 @@ } .groupLabel { - padding: 0.25rem; + padding: 0.25rem 0.5rem; font-size: 0.875rem; :global(.light) & { - color: $color-gray-600; + color: $color-gray-500; } :global(.dark) & { - color: $color-gray-300; + color: $color-gray-400; } }