Skip to content

Commit

Permalink
[Feat] Text 컴포넌트 추가 (#57)
Browse files Browse the repository at this point in the history
* feat(packages/ui): Text 컴포넌트

* feat(packages/ui): 컴파운드 객체 추가

* chore(packages/ui): TypographyType theme에서 가져오도록 수정

* fix(packages/ui): TextCompoundType 선언 시 중복되는 구문 수정

* fix(packages/ui): Compound Text 컴포넌트 선언 시 중복되는 로직 수정

* feat(packages/ui): Text 컴포넌트 사용 시 대문자 사용하도록 수정
  • Loading branch information
kongnayeon authored Jan 12, 2025
1 parent bac9147 commit 49fe65f
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 2 deletions.
6 changes: 4 additions & 2 deletions apps/web/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Icon } from '@repo/ui';
import { tokens } from '@repo/theme';
import { Icon, Text } from '@repo/ui';
export default function Home() {
return (
<div>
웹 1팀 파이팅!
<Icon size={24} name="stack" type="stroke" />
<Icon size={24} name="stack" type="fill" />
<Icon size={24} name="stack" type="stroke" color="warning300" />
<Text.H1 color="grey950" fontSize={28} fontWeight="semibold">
hihi
</Text.H1>
</div>
);
}
11 changes: 11 additions & 0 deletions packages/ui/src/components/Text/Text.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createVar, style } from '@vanilla-extract/css';

export const sizeVar = createVar();
export const weightVar = createVar();
export const colorVar = createVar();

export const textStyle = style({
fontSize: sizeVar,
fontWeight: weightVar,
color: colorVar,
});
51 changes: 51 additions & 0 deletions packages/ui/src/components/Text/Text.subComponents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { AllowedTags, TextProps, Text } from './Text';

function CreateSubText<T extends AllowedTags>({
as,
...rest
}: Omit<TextProps<T>, 'as'> & Required<Pick<TextProps<T>, 'as'>>) {
return <Text as={as} {...rest} />;
}

type TextCompoundType = {
<T extends AllowedTags = 'span'>(props: TextProps<T>): JSX.Element;
} & {
[K in AllowedTags]: (props?: Omit<TextProps<K>, 'as'>) => JSX.Element;
};

const BaseText = Text as TextCompoundType;

const tags: AllowedTags[] = [
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'p',
'span',
'div',
];

const compounds = tags.reduce(
(acc, tag) => {
const capitalizedTag = (tag.charAt(0).toUpperCase() +
tag.slice(1)) as Capitalize<typeof tag>;

acc[capitalizedTag] = (props?: Omit<TextProps<typeof tag>, 'as'>) =>
CreateSubText({
as: tag,
...props,
});
return acc;
},
{} as {
[K in AllowedTags as Capitalize<K>]: (
props?: Omit<TextProps<K>, 'as'>
) => JSX.Element;
}
);

const TextWithCompounds = Object.assign(BaseText, compounds);

export { TextWithCompounds as Text };
46 changes: 46 additions & 0 deletions packages/ui/src/components/Text/Text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { tokens, TypographyType } from '@repo/theme';
import { ComponentPropsWithoutRef } from 'react';
import { colorVar, sizeVar, textStyle, weightVar } from './Text.css';
import { assignInlineVars } from '@vanilla-extract/dynamic';

export type AllowedTags =
| 'span'
| 'p'
| 'h1'
| 'h2'
| 'h3'
| 'h4'
| 'h5'
| 'h6'
| 'div';

export type TextProps<T extends AllowedTags> = {
as?: T;
color?: keyof typeof tokens.colors;
fontSize?: keyof TypographyType['fontSize'];
fontWeight?: keyof TypographyType['fontWeight'];
} & ComponentPropsWithoutRef<T>;

export function Text<T extends AllowedTags = 'span'>({
as,
color = 'grey950',
fontSize = 14,
fontWeight = 'medium',
...rest
}: TextProps<T>) {
const Component = as || 'span';

return (
<Component
className={textStyle}
style={{
...assignInlineVars({
[colorVar]: tokens.colors[color],
[sizeVar]: tokens.typography.fontSize[fontSize],
[weightVar]: tokens.typography.fontWeight[fontWeight],
}),
}}
{...rest}
/>
);
}
2 changes: 2 additions & 0 deletions packages/ui/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export { Spacing } from './Spacing/Spacing';
export type { SpacingDirection, SpacingProps } from './Spacing/Spacing';
export { Icon } from './Icon/Icon';
export type { IconName, IconProps } from './Icon/Icon';
export { Text } from './Text/Text.subComponents';
export type { AllowedTags, TextProps } from './Text/Text';

0 comments on commit 49fe65f

Please sign in to comment.