From 359006111e01a1d9b9547cd8391f2e9c158face1 Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Wed, 4 Oct 2023 11:57:12 +0300 Subject: [PATCH 01/10] feat: InlineSelect ability --- components/Common/Select/index.module.css | 12 ++++++++ components/Common/Select/index.stories.tsx | 34 ++++++++++++++++++++++ components/Common/Select/index.tsx | 17 +++++++++-- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/components/Common/Select/index.module.css b/components/Common/Select/index.module.css index a113316b5fbe4..7f39efb302fa2 100644 --- a/components/Common/Select/index.module.css +++ b/components/Common/Select/index.module.css @@ -39,6 +39,12 @@ dark:focus:border-neutral-600 dark:focus:ring-neutral-600 dark:data-[placeholder]:text-neutral-200; + + & span { + @apply flex + items-center + gap-2; + } } .icon { @@ -75,6 +81,12 @@ data-[highlighted]:outline-none dark:text-neutral-200 dark:data-[highlighted]:bg-green-600; + + & span { + @apply flex + items-center + gap-2; + } } .label { diff --git a/components/Common/Select/index.stories.tsx b/components/Common/Select/index.stories.tsx index 2d7a0903029dd..589bf9ba5a31e 100644 --- a/components/Common/Select/index.stories.tsx +++ b/components/Common/Select/index.stories.tsx @@ -62,4 +62,38 @@ export const DropdownLabel: Story = { }, }; +export const InlineSelect: Story = { + args: { + values: [ + { + value: 'ubuntu', + label: 'Ubuntu', + iconImageUrl: '/static/images/logos/platform-linux.svg', + }, + { + value: 'apple', + label: 'Apple', + iconImageUrl: '/static/images/logos/platform-apple.svg', + }, + { + value: 'microsoft', + label: 'Microsoft', + iconImageUrl: '/static/images/logos/platform-microsoft.svg', + }, + { + value: 'homebrew', + label: 'Homebrew', + iconImageUrl: '/static/images/logos/platform-homebrew.svg', + }, + { + value: 'placeholder', + label: 'Placeholder', + iconImageUrl: '/static/images/logos/platform-placeholder.svg', + }, + ], + dropdownLabel: 'Platform', + placeholder: 'Select a platform', + }, +}; + export default { component: Select } as Meta; diff --git a/components/Common/Select/index.tsx b/components/Common/Select/index.tsx index cd48710e2b818..5eb01a24b2027 100644 --- a/components/Common/Select/index.tsx +++ b/components/Common/Select/index.tsx @@ -1,12 +1,13 @@ import { ChevronDownIcon } from '@heroicons/react/24/outline'; import * as Primitive from '@radix-ui/react-select'; +import Image from 'next/image'; import { useId } from 'react'; import type { FC } from 'react'; import styles from './index.module.css'; type SelectProps = { - values: ({ label: string; value: string } | string)[]; + values: ({ label: string; value: string; iconImageUrl?: string } | string)[]; defaultValue?: string; placeholder?: string; dropdownLabel?: string; @@ -34,7 +35,7 @@ const Select: FC = ({ @@ -59,7 +60,17 @@ const Select: FC = ({ value={value} className={`${styles.item} ${styles.text}`} > - {label} + + {typeof item !== 'string' && item?.iconImageUrl && ( + {label} + )} + {label} + ); })} From 482c905bdd365e9a5a137e6209ecafa8a2172a0d Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Wed, 4 Oct 2023 12:13:21 +0300 Subject: [PATCH 02/10] refactor: Unnecessary optional chaining removed --- components/Common/Select/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/Common/Select/index.tsx b/components/Common/Select/index.tsx index 5eb01a24b2027..feda941b8a3b3 100644 --- a/components/Common/Select/index.tsx +++ b/components/Common/Select/index.tsx @@ -61,7 +61,7 @@ const Select: FC = ({ className={`${styles.item} ${styles.text}`} > - {typeof item !== 'string' && item?.iconImageUrl && ( + {typeof item !== 'string' && item.iconImageUrl && ( {label} Date: Wed, 4 Oct 2023 12:22:37 +0300 Subject: [PATCH 03/10] chore: css indentation --- components/Common/Select/index.module.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/Common/Select/index.module.css b/components/Common/Select/index.module.css index 7f39efb302fa2..dea98ede6b142 100644 --- a/components/Common/Select/index.module.css +++ b/components/Common/Select/index.module.css @@ -42,8 +42,8 @@ & span { @apply flex - items-center - gap-2; + items-center + gap-2; } } @@ -84,8 +84,8 @@ & span { @apply flex - items-center - gap-2; + items-center + gap-2; } } From e52f9e48342fbcf29d60fda539ed8667422c755c Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Wed, 4 Oct 2023 19:01:15 +0300 Subject: [PATCH 04/10] refactor: Inline Select style updates and improvements --- components/Common/Select/index.module.css | 48 ++++++++++--- components/Common/Select/index.stories.tsx | 25 +++---- components/Common/Select/index.tsx | 83 ++++++++++++++-------- 3 files changed, 101 insertions(+), 55 deletions(-) diff --git a/components/Common/Select/index.module.css b/components/Common/Select/index.module.css index dea98ede6b142..4821b534ee6f9 100644 --- a/components/Common/Select/index.module.css +++ b/components/Common/Select/index.module.css @@ -39,12 +39,12 @@ dark:focus:border-neutral-600 dark:focus:ring-neutral-600 dark:data-[placeholder]:text-neutral-200; + } - & span { - @apply flex - items-center - gap-2; - } + .trigger span { + @apply flex + items-center + gap-2; } .icon { @@ -81,12 +81,12 @@ data-[highlighted]:outline-none dark:text-neutral-200 dark:data-[highlighted]:bg-green-600; + } - & span { - @apply flex - items-center - gap-2; - } + .text span { + @apply flex + items-center + gap-2; } .label { @@ -94,3 +94,31 @@ dark:text-neutral-400; } } + +.inline { + .trigger { + @apply min-w-fit + px-2.5 + py-2 + text-sm + font-medium; + } + + .icon { + @apply h-4 + w-4; + } + + .text { + @apply text-neutral-900 + data-[highlighted]:bg-neutral-100 + data-[highlighted]:text-neutral-900 + dark:text-white + dark:data-[highlighted]:bg-neutral-900; + } + + &.dropdown { + @apply mt-1 + w-[calc(100%+1.5rem)]; + } +} diff --git a/components/Common/Select/index.stories.tsx b/components/Common/Select/index.stories.tsx index 589bf9ba5a31e..fee14bf007f53 100644 --- a/components/Common/Select/index.stories.tsx +++ b/components/Common/Select/index.stories.tsx @@ -66,33 +66,24 @@ export const InlineSelect: Story = { args: { values: [ { - value: 'ubuntu', - label: 'Ubuntu', + value: 'linux', + label: 'Linux', iconImageUrl: '/static/images/logos/platform-linux.svg', }, { - value: 'apple', - label: 'Apple', + value: 'macos', + label: 'MacOS', iconImageUrl: '/static/images/logos/platform-apple.svg', }, { - value: 'microsoft', - label: 'Microsoft', + value: 'windows', + label: 'Windows', iconImageUrl: '/static/images/logos/platform-microsoft.svg', }, - { - value: 'homebrew', - label: 'Homebrew', - iconImageUrl: '/static/images/logos/platform-homebrew.svg', - }, - { - value: 'placeholder', - label: 'Placeholder', - iconImageUrl: '/static/images/logos/platform-placeholder.svg', - }, ], dropdownLabel: 'Platform', - placeholder: 'Select a platform', + defaultValue: 'macos', + inline: true, }, }; diff --git a/components/Common/Select/index.tsx b/components/Common/Select/index.tsx index feda941b8a3b3..3147feb37ec96 100644 --- a/components/Common/Select/index.tsx +++ b/components/Common/Select/index.tsx @@ -1,17 +1,25 @@ import { ChevronDownIcon } from '@heroicons/react/24/outline'; import * as Primitive from '@radix-ui/react-select'; +import classNames from 'classnames'; import Image from 'next/image'; -import { useId } from 'react'; +import { useId, useMemo } from 'react'; import type { FC } from 'react'; import styles from './index.module.css'; +type SelectValue = { + label: string; + value: string; + iconImageUrl?: string; +}; + type SelectProps = { - values: ({ label: string; value: string; iconImageUrl?: string } | string)[]; + values: SelectValue[] | string[]; defaultValue?: string; placeholder?: string; dropdownLabel?: string; label?: string; + inline?: boolean; onChange?: (value: string) => void; }; @@ -21,12 +29,33 @@ const Select: FC = ({ placeholder, label, dropdownLabel, + inline, onChange, }) => { const id = useId(); + const mappedValues: SelectValue[] = useMemo(() => { + if (!values.length) { + return []; + } + + const [firstItem, ...items] = values; + + if (typeof firstItem === 'string') { + return [firstItem, ...(items as string[])].map(value => ({ + value, + label: value, + })); + } + + if (typeof firstItem === 'object') { + return [firstItem, ...(items as SelectValue[])]; + } + + return []; + }, [values]); return ( -
+
{label && (