Skip to content
Docs
dot

유틸리티 함수

stable

dotCx, semanticVars, dotExplain — 보조 유틸리티 및 진단 함수

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 | '')[]): string

Parameters

파라미터타입설명
...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

파라미터타입설명
...namesstring[]시맨틱 토큰 이름 목록
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
): DotExplainResult

Parameters

파라미터타입설명
input`string \undefined \null`공백 구분 유틸리티 문자열
optionsDotOptionsdot()과 동일한 옵션

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
): CapabilityLevel

Parameters

파라미터타입설명
propertystringCSS 속성명
targetDotTarget대상 플랫폼
valuestring(선택) 속성값. 값 레벨 재정의 확인 시 사용

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_MATRIXPROPERTY_TO_FAMILY는 불변 상수입니다. 런타임에 수정하지 마세요.