Pattern
Foundation
선·점·격자 같은 반복 요소로 형태적 구분을 주는 패턴.
Usage
import
API Reference
사용 가이드
예제
Usage
색상만으로 구분하기 어려운 영역에 선·점·격자 패턴을 더해 접근성을 높일 때 사용한다. 차트·상태 영역처럼 같은 색조 안에서도 범주를 형태로 구분해야 할 때 사용한다.
import
import
import { Pattern } from '@mildang/design-system/Pattern';예제를 복사해 쓸 때 필요한 준비
• @mildang/styled-system 은 이 저장소에서 Panda 가 생성하는 산출물이다. 저장소 안에서는 turbo run ship 이후 쓸 수 있고, 패키지 소비자는 자기 Panda 산출물이나 다른 레이아웃 수단으로 바꿔야 한다.
API Reference
Pattern Props
Prop
Type
Default
type
필수
"horizontal" | "vertical" | "diagonal" | "diagonalReverse" | "crossDot" | "dot" | "square" | "cross" | "grid" | "gridBold"
지정 안 함
backColor
string
transparent
frontColor
string
neutral.border.high
opacity
"10" | "20" | "40" | "30" | "50" | "60" | "70" | "80" | "90" | "100" | "disable"
100
panda
SystemStyleObject
지정 안 함
size
"sm" | "md" | "lg"
md
spacing
number
1
사용 가이드
권장
- 배경색과 패턴색의 대비를 확인하고 색상 외 구분 단서로 사용한다.
지양
- 장식만을 위해 본문 전체에 강한 패턴을 반복해 가독성을 낮추지 않는다.
예제
패턴 유형
다섯 패턴 유형과 세 크기를 나란히 비교한다. frontColor·backColor 를 비우면 각각 neutral 테두리색과 투명으로 그려진다.
코드
import type { ComponentProps } from 'react';
import { Pattern as Pattern } from '@mildang/design-system/Pattern';
import { css } from '@mildang/styled-system/css';
import { type PatternVariantProps } from '@mildang/styled-system/recipes';
const boxStyle = css({
width: '40px',
height: '40px',
border: '1px solid token(colors.neutral.border.base)',
borderRadius: 4,
boxShadow: 'core.3',
});
const patternList: {
name: PatternVariantProps['type'];
sizes: Partial<PatternVariantProps['size']>[];
}[] = [
{ name: 'diagonal', sizes: ['sm', 'lg'] },
{ name: 'diagonalReverse', sizes: ['sm', 'lg'] },
{ name: 'crossDot', sizes: [] },
{ name: 'dot', sizes: [] },
{ name: 'grid', sizes: [] },
{ name: 'vertical', sizes: [] },
{ name: 'horizontal', sizes: [] },
{ name: 'cross', sizes: [] },
{ name: 'square', sizes: ['sm', 'md', 'lg'] },
];
const sizeList = ['sm', 'md', 'lg'] as PatternVariantProps['size'][];
const STORY_DEFAULT_ARGS = { ...({}), ...({
backColor: 'neutral.surface.low',
frontColor: 'positive.text.base',
opacity: '100',
spacing: 1,
size: 'sm',
}) } as ComponentProps<typeof Pattern>;
const PatternAllStoriesExampleRender = (args: ComponentProps<typeof Pattern>) => (
<table style={{ borderCollapse: 'collapse', width: 'auto' }}>
<thead>
<tr>
<th style={{ border: '1px solid #ddd', padding: 4 }}>패턴명</th>
{sizeList.map((size) => (
<th key={size} style={{ border: '1px solid #ddd', padding: 4 }}>
{size}
</th>
))}
</tr>
</thead>
<tbody>
{patternList.map((pattern) => (
<tr key={pattern.name}>
<td style={{ border: '1px solid #ddd', padding: 4 }}>{pattern.name}</td>
{sizeList.map((size) => (
<td key={size} style={{ border: '1px solid #ddd', padding: 4 }}>
{pattern.sizes.length === 0 && size === 'sm' && (
<Pattern {...args} type={pattern.name} className={boxStyle} />
)}
{pattern.sizes.includes(size) && (
<Pattern {...args} type={pattern.name} size={size} className={boxStyle} />
)}
</td>
))}
</tr>
))}
</tbody>
</table>
);
export default function PatternAllStoriesExample(props: Partial<ComponentProps<typeof Pattern>>) {
const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Pattern>;
return PatternAllStoriesExampleRender(mergedProps);
}
Demo
import type { ComponentProps } from 'react';
import { Pattern as Pattern } from '@mildang/design-system/Pattern';
import { css } from '@mildang/styled-system/css';
const boxStyle = css({
width: '40px',
height: '40px',
border: '1px solid token(colors.neutral.border.base)',
borderRadius: 4,
boxShadow: 'core.3',
});
const STORY_DEFAULT_ARGS = { ...({}), ...({
type: 'diagonal',
backColor: 'neutral.surface.low',
frontColor: 'positive.fill.base',
opacity: '100',
spacing: 1,
size: 'sm',
}) } as ComponentProps<typeof Pattern>;
const PatternDemoExampleRender = (args: ComponentProps<typeof Pattern>) => <Pattern {...args} className={boxStyle} />;
export default function PatternDemoExample(props: Partial<ComponentProps<typeof Pattern>>) {
const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Pattern>;
return PatternDemoExampleRender(mergedProps);
}
RecipeOnly
코드
import type { ComponentProps } from 'react';
import { Pattern as Pattern } from '@mildang/design-system/Pattern';
import { type Token, token } from '@mildang/styled-system/tokens';
import { type CSSProperties } from 'react';
import { css, cx } from '@mildang/styled-system/css';
import { pattern } from '@mildang/styled-system/recipes';
const STORY_DEFAULT_ARGS = { ...({}), ...({
type: 'diagonal',
size: 'sm',
backColor: 'critical.fill.base',
frontColor: 'neutral.surface.low',
opacity: '100',
spacing: 1,
}) } as ComponentProps<typeof Pattern>;
const PatternRecipeOnlyExampleRender = (args: ComponentProps<typeof Pattern>) => {
const { backColor, frontColor, opacity, spacing, ...rest } = args;
return (
<div
style={
{
'--pattern-back-color': token(`colors.${backColor}` as Token),
'--pattern-front-color': token(`colors.${frontColor}` as Token),
'--pattern-spacing': `${spacing}px`,
'--pattern-opacity': token(`opacity.${opacity}` as Token),
} as CSSProperties
}
className={cx(
pattern({ ...rest }),
css({
width: '80px',
height: '80px',
boxShadow: 'core.5',
clipPath:
'path("M40 15 C40 5, 25 0, 20 10 C15 0, 0 5, 0 15 C0 30, 20 40, 20 40 C20 40, 40 30, 40 15 Z")',
}),
)}
/>
);
};
export default function PatternRecipeOnlyExample(props: Partial<ComponentProps<typeof Pattern>>) {
const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Pattern>;
return PatternRecipeOnlyExampleRender(mergedProps);
}