From fb932eeb0404c59501eb04eed6b903ba04281a62 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 22 Feb 2024 17:01:36 +0700 Subject: [PATCH 1/5] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20implement=20ta?= =?UTF-8?q?gs=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/shared/Tags/Tags.theme.ts | 93 +++++++++++++++++++ .../src/components/shared/Tags/Tags.tsx | 75 +++++++++++++++ .../src/components/shared/Tags/index.ts | 2 + 3 files changed, 170 insertions(+) create mode 100644 packages/frontend/src/components/shared/Tags/Tags.theme.ts create mode 100644 packages/frontend/src/components/shared/Tags/Tags.tsx create mode 100644 packages/frontend/src/components/shared/Tags/index.ts diff --git a/packages/frontend/src/components/shared/Tags/Tags.theme.ts b/packages/frontend/src/components/shared/Tags/Tags.theme.ts new file mode 100644 index 0000000..299f31e --- /dev/null +++ b/packages/frontend/src/components/shared/Tags/Tags.theme.ts @@ -0,0 +1,93 @@ +import { tv } from 'tailwind-variants'; +import type { VariantProps } from 'tailwind-variants'; + +export const tagsTheme = tv( + { + slots: { + wrapper: ['flex', 'gap-1.5', 'rounded-lg', 'border'], + icon: ['h-4', 'w-4'], + label: ['font-inter', 'text-xs'], + }, + variants: { + type: { + attention: { + icon: ['text-elements-warning'], + }, + negative: { + icon: ['text-elements-danger'], + }, + positive: { + icon: ['text-elements-success'], + }, + emphasized: { + icon: ['text-elements-on-secondary'], + }, + neutral: { + icon: ['text-elements-mid-em'], + }, + }, + style: { + default: {}, + minimal: { + wrapper: ['border-border-interactive', 'bg-controls-tertiary'], + label: ['text-elements-high-em'], + }, + }, + size: { + sm: { + wrapper: ['px-2', 'py-2'], + }, + xs: { + wrapper: ['px-2', 'py-1.5'], + }, + }, + }, + compoundVariants: [ + { + type: 'attention', + style: 'default', + class: { + wrapper: ['border-orange-200', 'bg-orange-50'], + }, + }, + { + type: 'negative', + style: 'default', + class: { + wrapper: ['border-rose-200', 'bg-rose-50'], + }, + }, + { + type: 'positive', + style: 'default', + class: { + wrapper: ['border-emerald-200', 'bg-emerald-50'], + }, + }, + { + type: 'emphasized', + style: 'default', + class: { + wrapper: ['border-snowball-200', 'bg-snowball-50'], + }, + }, + { + type: 'neutral', + style: 'default', + class: { + wrapper: ['border-gray-200', 'bg-gray-50'], + }, + }, + ], + defaultVariants: { + type: 'attention', + style: 'default', + size: 'sm', + }, + }, + { + responsiveVariants: true, + }, +); + +export type TagsTheme = VariantProps; diff --git a/packages/frontend/src/components/shared/Tags/Tags.tsx b/packages/frontend/src/components/shared/Tags/Tags.tsx new file mode 100644 index 0000000..9cdb123 --- /dev/null +++ b/packages/frontend/src/components/shared/Tags/Tags.tsx @@ -0,0 +1,75 @@ +import React, { + type ReactNode, + type ComponentPropsWithoutRef, + useMemo, +} from 'react'; +import { TagsTheme, tagsTheme } from './Tags.theme'; +import { cloneIcon } from 'utils/cloneIcon'; + +type TagsProps = ComponentPropsWithoutRef<'div'> & + TagsTheme & { + /** + * The optional left icon element for a component. + * @type {ReactNode} + */ + leftIcon?: ReactNode; + /** + * The optional right icon element to display. + * @type {ReactNode} + */ + rightIcon?: ReactNode; + /** + * The optional type of the tags component. + * @type {TagsTheme['type']} + **/ + type?: TagsTheme['type']; + /** + * The optional style of the tags component. + * @type {TagsTheme['style']} + */ + style?: TagsTheme['style']; + /** + * The optional size of the tags component. + * @type {TagsTheme['size']} + */ + size?: TagsTheme['size']; + }; + +export const Tags = ({ + children, + leftIcon, + rightIcon, + type = 'attention', + style = 'default', + size = 'sm', +}: TagsProps) => { + const { + wrapper: wrapperCls, + icon: iconCls, + label: labelCls, + } = tagsTheme({ + type, + style, + size, + }); + + const renderLeftIcon = useMemo(() => { + if (!leftIcon) return null; + return
{cloneIcon(leftIcon, { size: 16 })}
; + }, [iconCls, leftIcon]); + + const renderRightIcon = useMemo(() => { + if (!rightIcon) return null; + return ( +
{cloneIcon(rightIcon, { size: 16 })}
+ ); + }, [iconCls, rightIcon]); + + return ( +
+ {renderLeftIcon} +

{children}

+ {renderRightIcon} +
+ ); +}; diff --git a/packages/frontend/src/components/shared/Tags/index.ts b/packages/frontend/src/components/shared/Tags/index.ts new file mode 100644 index 0000000..de1af19 --- /dev/null +++ b/packages/frontend/src/components/shared/Tags/index.ts @@ -0,0 +1,2 @@ +export * from './Tags'; +export * from './Tags.theme'; From 596889b5e2b70feab7a0c1ccddfb8daed6895b48 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 22 Feb 2024 17:01:58 +0700 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=94=A7=20chore:=20add=20render=20tags?= =?UTF-8?q?=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/pages/components/index.tsx | 14 +++++ .../src/pages/components/renders/tags.tsx | 63 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 packages/frontend/src/pages/components/renders/tags.tsx diff --git a/packages/frontend/src/pages/components/index.tsx b/packages/frontend/src/pages/components/index.tsx index 67e68e0..2da8cc9 100644 --- a/packages/frontend/src/pages/components/index.tsx +++ b/packages/frontend/src/pages/components/index.tsx @@ -23,6 +23,7 @@ import { renderInlineNotifications, } from './renders/inlineNotifications'; import { renderInputs } from './renders/input'; +import { renderDefaultTags, renderMinimalTags } from './renders/tags'; const Page = () => { const [singleDate, setSingleDate] = useState(); @@ -41,6 +42,19 @@ const Page = () => {
+ {/* Tags */} +
+
+

Tags

+
+ {renderDefaultTags()} + {renderMinimalTags()} +
+
+
+ +
+ {/* Button */}

Input

diff --git a/packages/frontend/src/pages/components/renders/tags.tsx b/packages/frontend/src/pages/components/renders/tags.tsx new file mode 100644 index 0000000..760b731 --- /dev/null +++ b/packages/frontend/src/pages/components/renders/tags.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import { Tags } from 'components/shared/Tags'; +import { PlusIcon } from 'components/shared/CustomIcon'; + +export const renderDefaultTags = () => + (['default'] as const).map((style) => ( +
+ {( + ['attention', 'negative', 'positive', 'emphasized', 'neutral'] as const + ).map((type) => ( +
+ } + rightIcon={} + style={style} + type={type} + size="sm" + > + Label + + } + rightIcon={} + size="xs" + style={style} + type={type} + > + Label + +
+ ))} +
+ )); + +export const renderMinimalTags = () => + (['minimal'] as const).map((style) => ( +
+ {( + ['attention', 'negative', 'positive', 'emphasized', 'neutral'] as const + ).map((type) => ( +
+ } + rightIcon={} + style={style} + type={type} + size="sm" + > + Label + + } + rightIcon={} + size="xs" + style={style} + type={type} + > + Label + +
+ ))} +
+ )); From 55848b1dd161aa2628259fa1497c04d85f8e7f40 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 22 Feb 2024 22:46:10 +0700 Subject: [PATCH 3/5] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20rename=20t?= =?UTF-8?q?ags=20to=20tag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{Tags/Tags.theme.ts => Tag/Tag.theme.ts} | 4 +-- .../shared/{Tags/Tags.tsx => Tag/Tag.tsx} | 27 +++++-------------- .../src/components/shared/Tag/index.ts | 2 ++ .../src/components/shared/Tags/index.ts | 2 -- .../frontend/src/pages/components/index.tsx | 10 +++---- .../src/pages/components/renders/tags.tsx | 22 +++++++-------- 6 files changed, 26 insertions(+), 41 deletions(-) rename packages/frontend/src/components/shared/{Tags/Tags.theme.ts => Tag/Tag.theme.ts} (95%) rename packages/frontend/src/components/shared/{Tags/Tags.tsx => Tag/Tag.tsx} (66%) create mode 100644 packages/frontend/src/components/shared/Tag/index.ts delete mode 100644 packages/frontend/src/components/shared/Tags/index.ts diff --git a/packages/frontend/src/components/shared/Tags/Tags.theme.ts b/packages/frontend/src/components/shared/Tag/Tag.theme.ts similarity index 95% rename from packages/frontend/src/components/shared/Tags/Tags.theme.ts rename to packages/frontend/src/components/shared/Tag/Tag.theme.ts index 299f31e..086b59b 100644 --- a/packages/frontend/src/components/shared/Tags/Tags.theme.ts +++ b/packages/frontend/src/components/shared/Tag/Tag.theme.ts @@ -1,7 +1,7 @@ import { tv } from 'tailwind-variants'; import type { VariantProps } from 'tailwind-variants'; -export const tagsTheme = tv( +export const tagTheme = tv( { slots: { wrapper: ['flex', 'gap-1.5', 'rounded-lg', 'border'], @@ -90,4 +90,4 @@ export const tagsTheme = tv( }, ); -export type TagsTheme = VariantProps; +export type TagTheme = VariantProps; diff --git a/packages/frontend/src/components/shared/Tags/Tags.tsx b/packages/frontend/src/components/shared/Tag/Tag.tsx similarity index 66% rename from packages/frontend/src/components/shared/Tags/Tags.tsx rename to packages/frontend/src/components/shared/Tag/Tag.tsx index 9cdb123..2d10012 100644 --- a/packages/frontend/src/components/shared/Tags/Tags.tsx +++ b/packages/frontend/src/components/shared/Tag/Tag.tsx @@ -3,11 +3,11 @@ import React, { type ComponentPropsWithoutRef, useMemo, } from 'react'; -import { TagsTheme, tagsTheme } from './Tags.theme'; +import { tagTheme, type TagTheme } from './Tag.theme'; import { cloneIcon } from 'utils/cloneIcon'; -type TagsProps = ComponentPropsWithoutRef<'div'> & - TagsTheme & { +type TagProps = ComponentPropsWithoutRef<'div'> & + TagTheme & { /** * The optional left icon element for a component. * @type {ReactNode} @@ -18,36 +18,21 @@ type TagsProps = ComponentPropsWithoutRef<'div'> & * @type {ReactNode} */ rightIcon?: ReactNode; - /** - * The optional type of the tags component. - * @type {TagsTheme['type']} - **/ - type?: TagsTheme['type']; - /** - * The optional style of the tags component. - * @type {TagsTheme['style']} - */ - style?: TagsTheme['style']; - /** - * The optional size of the tags component. - * @type {TagsTheme['size']} - */ - size?: TagsTheme['size']; }; -export const Tags = ({ +export const Tag = ({ children, leftIcon, rightIcon, type = 'attention', style = 'default', size = 'sm', -}: TagsProps) => { +}: TagProps) => { const { wrapper: wrapperCls, icon: iconCls, label: labelCls, - } = tagsTheme({ + } = tagTheme({ type, style, size, diff --git a/packages/frontend/src/components/shared/Tag/index.ts b/packages/frontend/src/components/shared/Tag/index.ts new file mode 100644 index 0000000..e889934 --- /dev/null +++ b/packages/frontend/src/components/shared/Tag/index.ts @@ -0,0 +1,2 @@ +export * from './Tag'; +export * from './Tag.theme'; diff --git a/packages/frontend/src/components/shared/Tags/index.ts b/packages/frontend/src/components/shared/Tags/index.ts deleted file mode 100644 index de1af19..0000000 --- a/packages/frontend/src/components/shared/Tags/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './Tags'; -export * from './Tags.theme'; diff --git a/packages/frontend/src/pages/components/index.tsx b/packages/frontend/src/pages/components/index.tsx index 2da8cc9..b3dc640 100644 --- a/packages/frontend/src/pages/components/index.tsx +++ b/packages/frontend/src/pages/components/index.tsx @@ -23,7 +23,7 @@ import { renderInlineNotifications, } from './renders/inlineNotifications'; import { renderInputs } from './renders/input'; -import { renderDefaultTags, renderMinimalTags } from './renders/tags'; +import { renderDefaultTag, renderMinimalTag } from './renders/Tag'; const Page = () => { const [singleDate, setSingleDate] = useState(); @@ -42,13 +42,13 @@ const Page = () => {
- {/* Tags */} + {/* Tag */}
-

Tags

+

Tag

- {renderDefaultTags()} - {renderMinimalTags()} + {renderDefaultTag()} + {renderMinimalTag()}
diff --git a/packages/frontend/src/pages/components/renders/tags.tsx b/packages/frontend/src/pages/components/renders/tags.tsx index 760b731..f01c526 100644 --- a/packages/frontend/src/pages/components/renders/tags.tsx +++ b/packages/frontend/src/pages/components/renders/tags.tsx @@ -1,15 +1,15 @@ import React from 'react'; -import { Tags } from 'components/shared/Tags'; +import { Tag } from 'components/shared/Tag'; import { PlusIcon } from 'components/shared/CustomIcon'; -export const renderDefaultTags = () => +export const renderDefaultTag = () => (['default'] as const).map((style) => (
{( ['attention', 'negative', 'positive', 'emphasized', 'neutral'] as const ).map((type) => (
- } rightIcon={} style={style} @@ -17,8 +17,8 @@ export const renderDefaultTags = () => size="sm" > Label - - + } rightIcon={} size="xs" @@ -26,20 +26,20 @@ export const renderDefaultTags = () => type={type} > Label - +
))}
)); -export const renderMinimalTags = () => +export const renderMinimalTag = () => (['minimal'] as const).map((style) => (
{( ['attention', 'negative', 'positive', 'emphasized', 'neutral'] as const ).map((type) => (
- } rightIcon={} style={style} @@ -47,8 +47,8 @@ export const renderMinimalTags = () => size="sm" > Label - - + } rightIcon={} size="xs" @@ -56,7 +56,7 @@ export const renderMinimalTags = () => type={type} > Label - +
))}
From 05e1ac6b0284c09ceb90940207e01904f241d7e6 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 22 Feb 2024 22:48:31 +0700 Subject: [PATCH 4/5] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20change=20t?= =?UTF-8?q?ags=20to=20tag=20for=20rencer=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/components/index.tsx | 2 +- .../frontend/src/pages/components/renders/{tags.tsx => tag.tsx} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/frontend/src/pages/components/renders/{tags.tsx => tag.tsx} (100%) diff --git a/packages/frontend/src/pages/components/index.tsx b/packages/frontend/src/pages/components/index.tsx index b3dc640..5c1708e 100644 --- a/packages/frontend/src/pages/components/index.tsx +++ b/packages/frontend/src/pages/components/index.tsx @@ -23,7 +23,7 @@ import { renderInlineNotifications, } from './renders/inlineNotifications'; import { renderInputs } from './renders/input'; -import { renderDefaultTag, renderMinimalTag } from './renders/Tag'; +import { renderDefaultTag, renderMinimalTag } from './renders/tag'; const Page = () => { const [singleDate, setSingleDate] = useState(); diff --git a/packages/frontend/src/pages/components/renders/tags.tsx b/packages/frontend/src/pages/components/renders/tag.tsx similarity index 100% rename from packages/frontend/src/pages/components/renders/tags.tsx rename to packages/frontend/src/pages/components/renders/tag.tsx From 5a5756bcf2eac1e9122edf0b8d6a54a4a5c228e7 Mon Sep 17 00:00:00 2001 From: Andre H Date: Fri, 23 Feb 2024 10:47:50 +0700 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=94=A7=20chore:=20add=20cloneIcon=20t?= =?UTF-8?q?o=20dep=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/shared/Tag/Tag.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/components/shared/Tag/Tag.tsx b/packages/frontend/src/components/shared/Tag/Tag.tsx index 2d10012..086d351 100644 --- a/packages/frontend/src/components/shared/Tag/Tag.tsx +++ b/packages/frontend/src/components/shared/Tag/Tag.tsx @@ -41,14 +41,14 @@ export const Tag = ({ const renderLeftIcon = useMemo(() => { if (!leftIcon) return null; return
{cloneIcon(leftIcon, { size: 16 })}
; - }, [iconCls, leftIcon]); + }, [cloneIcon, iconCls, leftIcon]); const renderRightIcon = useMemo(() => { if (!rightIcon) return null; return (
{cloneIcon(rightIcon, { size: 16 })}
); - }, [iconCls, rightIcon]); + }, [cloneIcon, iconCls, rightIcon]); return (