dot
유틸리티 함수
stabledotCx, semanticVars, dotExplain — 보조 유틸리티 및 진단 함수
@hua-labs/dotv2.0.0
Import
import { dotCx, semanticVars, dotExplain } from '@hua-labs/dot';
import { CAPABILITY_MATRIX, PROPERTY_TO_FAMILY, getCapability } from '@hua-labs/dot';
import type { DotExplainResult, CapabilityLevel } from '@hua-labs/dot';Functions
dotCx
clsx의 대체 함수입니다. falsy 값을 필터링하고 유틸리티 문자열을 하나로 결합합니다. 스타일 계산 없이 문자열 조작만 수행합니다.
Signature
function dotCx(...inputs: (string | false | null | undefined | 0 | '')[]): stringParameters
| 파라미터 | 타입 | 설명 | |||||
|---|---|---|---|---|---|---|---|
...inputs | `(string \ | false \ | null \ | undefined \ | 0 \ | '')[]` | 결합할 유틸리티 문자열 또는 falsy 값 |
Returns
string — falsy 값이 제거된 공백 구분 유틸리티 문자열.
Usage
import { dotCx, dot } from '@hua-labs/dot';
// 기본 사용
dotCx('p-4', 'flex', 'items-center');
// → 'p-4 flex items-center'
// 조건부 결합
const isActive = true;
dotCx('p-4', isActive && 'bg-primary-500', !isActive && 'bg-gray-100');
// → 'p-4 bg-primary-500' (false는 무시됨)
// null/undefined 필터링
const extraClass = undefined;
dotCx('p-4', null, extraClass, 'rounded-lg');
// → 'p-4 rounded-lg'
// dot()와 함께
const baseStyles = 'p-4 flex items-center';
const conditionalStyles = dotCx(
baseStyles,
isLoading && 'opacity-50 pointer-events-none',
hasError && 'border border-red-500',
className,
);
const style = dot(conditionalStyles);
// React 컴포넌트 예시
function Button({
children,
disabled,
variant = 'primary',
}: {
children: React.ReactNode;
disabled?: boolean;
variant?: 'primary' | 'secondary';
}) {
const utilStr = dotCx(
'px-4 py-2 rounded-lg font-medium',
variant === 'primary' && 'bg-primary-500 text-white',
variant === 'secondary' && 'bg-gray-100 text-gray-900',
disabled && 'opacity-50 cursor-not-allowed',
);
return <button style={dot(utilStr)} disabled={disabled}>{children}</button>;
}semanticVars
시맨틱 색상 토큰 이름을 CSS 변수 참조 문자열로 매핑하는 오브젝트를 생성합니다. createDotConfig()의 theme.semanticColors와 함께 사용합니다.
Signature
// 기본 접두사 (--color)
function semanticVars(...names: string[]): Record<string, string>
// 커스텀 접두사
function semanticVars(
options: { prefix: string },
...names: string[]
): Record<string, string>Parameters
| 파라미터 | 타입 | 설명 |
|---|---|---|
...names | string[] | 시맨틱 토큰 이름 목록 |
options | { prefix: string } | CSS 변수 접두사 지정 시 첫 인자로 전달 |
Returns
Record<string, string> — { name: 'var(--color-name)' } 형태의 매핑 오브젝트.
Usage
import { semanticVars, createDotConfig } from '@hua-labs/dot';
// 기본 접두사 --color
const vars = semanticVars('sidebar', 'sidebar-foreground', 'chart-1');
// { sidebar: 'var(--color-sidebar)', 'sidebar-foreground': 'var(--color-sidebar-foreground)', 'chart-1': 'var(--color-chart-1)' }
// createDotConfig에 통합
createDotConfig({
theme: {
semanticColors: {
...semanticVars('sidebar', 'sidebar-foreground', 'chart-1'),
brand: 'var(--my-brand)', // 명시적 매핑과 혼합 가능
},
},
});
// 커스텀 접두사
const themeVars = semanticVars({ prefix: '--theme' }, 'primary', 'secondary', 'accent');
// { primary: 'var(--theme-primary)', secondary: 'var(--theme-secondary)', accent: 'var(--theme-accent)' }
// Next.js + shadcn/ui 스타일 시맨틱 설정
createDotConfig({
theme: {
semanticColors: {
...semanticVars(
'background', 'foreground',
'card', 'card-foreground',
'popover', 'popover-foreground',
'primary', 'primary-foreground',
'secondary', 'secondary-foreground',
'muted', 'muted-foreground',
'accent', 'accent-foreground',
'destructive', 'destructive-foreground',
'border', 'input', 'ring',
),
},
},
});
dot('bg-background text-foreground border-border');
// { backgroundColor: 'var(--color-background)', color: 'var(--color-foreground)', borderColor: 'var(--color-border)' }dotExplain
유틸리티 문자열을 해석하고 스타일과 함께 플랫폼 호환성 보고서를 반환합니다. 크로스 플랫폼 개발 시 어떤 유틸리티가 드롭되거나 근사화되는지 진단하는 데 사용합니다.
Signature
function dotExplain(
input: string | undefined | null,
options?: DotOptions
): DotExplainResultParameters
| 파라미터 | 타입 | 설명 | ||
|---|---|---|---|---|
input | `string \ | undefined \ | null` | 공백 구분 유틸리티 문자열 |
options | DotOptions | dot()과 동일한 옵션 |
Returns
DotExplainResult — 스타일과 호환성 보고서.
interface DotExplainResult {
/** dot()과 동일한 해석된 스타일 오브젝트 */
styles: StyleObject | RNStyleObject | FlutterRecipe;
/** 플랫폼 호환성 보고서 */
report: DotCapabilityReport;
}
interface DotCapabilityReport {
/** 대상 플랫폼에서 드롭된 유틸리티 목록 */
_dropped?: string[];
/** 근사화된 유틸리티 목록 (정확하지 않음) */
_approximated?: string[];
/** 패밀리별 지원 수준 */
_capabilities?: Record<string, CapabilityLevel>;
/** 근사화 세부 사항 (예: boxShadow: ['inset dropped', 'spread ignored']) */
_details?: Record<string, string[]>;
}CapabilityLevel
| 값 | 설명 |
|---|---|
'native' | 대상이 직접 지원 |
'approximate' | 유사하지만 동일하지 않은 출력 |
'recipe-only' | 위젯/컴포넌트 레시피 필요 (Flutter) |
'plugin-backed' | 에코시스템 플러그인 필요 |
'unsupported' | 대상에서 사용 불가 |
Usage
import { dotExplain } from '@hua-labs/dot';
// React Native 호환성 확인
const result = dotExplain('p-4 blur-md grid grid-cols-3', { target: 'native' });
// {
// styles: { padding: 16 },
// report: {
// _dropped: ['filter', 'gridTemplateColumns'],
// _capabilities: {
// filter: 'unsupported',
// grid: 'unsupported',
// },
// },
// }
// Flutter 호환성 확인
const flutterResult = dotExplain('p-4 transition-all hover:bg-gray-100', { target: 'flutter' });
// {
// styles: FlutterRecipe { padding: { top: 16, ... } },
// report: {
// _dropped: ['transitionProperty'],
// _capabilities: { transition: 'unsupported' },
// },
// }
// 웹은 항상 빈 보고서
const webResult = dotExplain('p-4 flex blur-md');
// { styles: { padding: '16px', display: 'flex', filter: 'blur(12px)' }, report: {} }
// 박스 쉐도우 근사화 세부 정보
const shadowResult = dotExplain('shadow-lg ring-2 ring-inset', { target: 'native' });
// {
// styles: RNStyleObject,
// report: {
// _approximated: ['boxShadow'],
// _capabilities: { boxShadow: 'approximate' },
// _details: { boxShadow: ['inset dropped', 'spread ignored'] },
// },
// }CAPABILITY_MATRIX
유틸리티 패밀리별, 플랫폼별 지원 수준을 담은 정적 상수입니다.
Type
const CAPABILITY_MATRIX: Record<string, Partial<Record<DotTarget, CapabilityLevel>>>Usage
import { CAPABILITY_MATRIX } from '@hua-labs/dot';
CAPABILITY_MATRIX['gradient'];
// { web: 'native', native: 'unsupported', flutter: 'recipe-only' }
CAPABILITY_MATRIX['filter'];
// { web: 'native', native: 'unsupported', flutter: 'plugin-backed' }
CAPABILITY_MATRIX['spacing'];
// { web: 'native', native: 'native', flutter: 'native' }
// 플랫폼별 미지원 패밀리 목록
const nativeUnsupported = Object.entries(CAPABILITY_MATRIX)
.filter(([, caps]) => caps.native === 'unsupported')
.map(([family]) => family);
// ['transition', 'animation', 'filter', 'grid', 'gradient', ...]PROPERTY_TO_FAMILY
CSS 속성명을 유틸리티 패밀리명으로 매핑하는 정적 상수입니다. CAPABILITY_MATRIX와 함께 사용합니다.
Type
const PROPERTY_TO_FAMILY: Record<string, string>Usage
import { PROPERTY_TO_FAMILY, CAPABILITY_MATRIX } from '@hua-labs/dot';
PROPERTY_TO_FAMILY['backgroundImage'];
// 'gradient'
PROPERTY_TO_FAMILY['padding'];
// 'spacing'
// CSS 속성의 네이티브 지원 수준 확인
function checkNativeSupport(cssProperty: string) {
const family = PROPERTY_TO_FAMILY[cssProperty];
if (!family) return 'unknown';
return CAPABILITY_MATRIX[family]?.native ?? 'unknown';
}
checkNativeSupport('backgroundImage'); // 'unsupported'
checkNativeSupport('padding'); // 'native'getCapability
단일 CSS 속성의 특정 플랫폼 지원 수준을 프로그래밍 방식으로 조회합니다.
Signature
function getCapability(
property: string,
target: DotTarget,
value?: string
): CapabilityLevelParameters
| 파라미터 | 타입 | 설명 |
|---|---|---|
property | string | CSS 속성명 |
target | DotTarget | 대상 플랫폼 |
value | string | (선택) 속성값. 값 레벨 재정의 확인 시 사용 |
Returns
CapabilityLevel — 해당 속성의 플랫폼 지원 수준.
Usage
import { getCapability } from '@hua-labs/dot';
getCapability('padding', 'native'); // 'native'
getCapability('filter', 'native'); // 'unsupported'
getCapability('display', 'native', 'flex'); // 'native'
getCapability('display', 'native', 'grid'); // 'unsupported'Notes
dotCx()는 스타일 계산 없이 문자열만 결합합니다. 결합된 문자열을dot()에 전달하면 스타일이 해석됩니다.dotExplain()은target: 'web'이면 항상 빈 보고서를 반환합니다. 웹은 모든 유틸리티를 지원하기 때문입니다.semanticVars()는 CSS 변수 값이 실제로 정의되어 있다고 가정합니다. 변수가 정의되지 않으면 스타일이 적용되지 않습니다.CAPABILITY_MATRIX와PROPERTY_TO_FAMILY는 불변 상수입니다. 런타임에 수정하지 마세요.