Skip to content

Commit

Permalink
Enhance Typography system with dynamic font-family (#3)
Browse files Browse the repository at this point in the history
## Description

Enhanced the typography system to support dynamic font families based on
weights (`normal`, `thin`, `bold`). The `setFontFamily` function now
updates font configurations globally, and `getFontFamilies` dynamically
applies these settings to all typography components (`Title`,
`Heading1`, `Body1`, etc.). Default font families (`Pretendard`) ensure
backward compatibility while allowing seamless customization.

## Test Plan

```tsx
setFontFamily({
  normal: 'NotoSans-Regular',
  thin: 'NotoSans-Thin',
  bold: 'NotoSans-Bold',
});
```

```tsx
<Typography.Title>Bold Title</Typography.Title>
<Typography.Body1>Normal Body Text</Typography.Body1>
``` 

## Related Issues

N/A

## Tests

N/A

## Checklist

Before you create this PR confirms that it meets all requirements listed
below by checking the relevant checkboxes (`[x]`). This will ensure a
smooth and quick review process.

- [x] I read the [Contributor
Guide](https://github.com/crossplatformkorea/cpk-ui/blob/main/CONTRIBUTING.md)
and followed the process outlined there for submitting PRs.
- [x] Run `yarn test:all` and make sure nothing fails.
- [x] I am willing to follow-up on review comments in a timely manner.
  • Loading branch information
hyochan authored Jan 18, 2025
1 parent 537dea4 commit f02b805
Showing 1 changed file with 29 additions and 31 deletions.
60 changes: 29 additions & 31 deletions src/components/uis/Typography/Typography.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import React, {ReactNode} from 'react';
import {StyleProp, Text} from 'react-native';

import {CpkTheme, isEmptyObject} from '../../../utils/theme';
import {withTheme} from '../../../providers/ThemeProvider';
import {light} from '../../../utils/colors';
import {type TextStyle} from 'react-native';
import styled, {css} from '@emotion/native';

// Base Styled Component Factory
type FontFamilyOptions = {
normal: string;
thin?: string;
bold?: string;
};

const createBaseText = (
colorResolver: (theme: CpkTheme) => string,
fallbackColor: string,
) => styled.Text<{theme?: CpkTheme; fontWeight?: 'normal' | 'bold' | 'thin'}>`
font-family: ${({fontWeight}) =>
fontWeight === 'bold'
? 'Pretendard-Bold'
: fontWeight === 'thin'
? 'Pretendard-Thin'
: 'Pretendard'};
font-family: ${({fontWeight}) => {
const {normal, thin = normal, bold = normal} = getFontFamilies();
switch (fontWeight) {
case 'bold':
return bold;
case 'thin':
return thin;
default:
return normal;
}
}};
color: ${({theme}) => {
if (!theme || isEmptyObject(theme)) {
return fallbackColor;
Expand All @@ -26,7 +35,6 @@ const createBaseText = (
}};
`;

// Common Text Component Factory
type TextComponentType = ReturnType<typeof styled.Text>;

const createTextComponent = ({
Expand Down Expand Up @@ -68,14 +76,12 @@ const createTextComponent = ({
),
) as unknown as TextComponentType;

// Standard and Inverted Base Components
const StandardBaseText = createBaseText((theme) => theme.text.basic, 'gray');
const InvertedBaseText = createBaseText(
(theme) => theme.text.contrast,
light.text.contrast,
);

// Standard Typography Components
const Title = createTextComponent({
BaseText: StandardBaseText,
fontSize: 36,
Expand Down Expand Up @@ -142,7 +148,6 @@ const Body4 = createTextComponent({
lineHeight: 16.4,
});

// Inverted Typography Components
const InvertedTitle = createTextComponent({
BaseText: InvertedBaseText,
fontSize: 36,
Expand Down Expand Up @@ -209,6 +214,18 @@ const InvertedBody4 = createTextComponent({
lineHeight: 16.4,
});

let currentFontFamilies: FontFamilyOptions = {
normal: 'Pretendard',
thin: 'Pretendard-Thin',
bold: 'Pretendard-Bold',
};

export const setFontFamily = (fontFamilies: FontFamilyOptions): void => {
currentFontFamilies = {...currentFontFamilies, ...fontFamilies};
};

export const getFontFamilies = (): FontFamilyOptions => currentFontFamilies;

export const Typography = {
Title,
Heading1,
Expand All @@ -234,22 +251,3 @@ export const TypographyInverted = {
Body3: InvertedBody3,
Body4: InvertedBody4,
};

export const setFontFamily = (fontFamily: string): void => {
const style = {
includeFontPadding: false,
fontFamily,
};

// @ts-ignore
let oldRender = Text.render;

// @ts-ignore
Text.render = (...args: any) => {
let origin = oldRender.call(this, ...args);

return React.cloneElement(origin, {
style: [style, origin.props.style],
});
};
};

0 comments on commit f02b805

Please sign in to comment.