space —— 간격
space는 컴포넌트 라이브러리에서 가장 흔한 문제 하나를 해결합니다: 요소 집합을 고정 간격으로 나열하는 것. 이것은 레이아웃 프레임워크가 아니고(그것은 LhGrid입니다) ’간격의 의미화’입니다. small / medium / large는 디자인 토큰이고, 숫자는 임시 미세 조정이며, 배열은 행/열 간격을 따로 제어합니다.
언제 사용할까
섹션 제목: “언제 사용할까”- 각 단말이
LhSpace를 구현할 때: 버튼 그룹, 폼 항목 나열, 카드 안 요소의 레이아웃. - ’이 요소들 사이를 떨어뜨린다’를 컴포넌트 안에서 표현해야 하는 모든 곳.
- 사용하면 안 되는 곳: 2차원 그리드가 필요할 때(
LhGrid사용), flex의 고급 정렬이 필요할 때(직접 스타일 작성). space는 간격만 담당하고 정렬은align이 그대로 전달합니다.
가져오기
섹션 제목: “가져오기”import { getSpaceClassNames, resolveSpaceGaps, resolveSpaceAlignment } from '@lh-ui/share/core/space'import type { LhSpaceState, LhSpaceSizeInput, LhSpaceAlignment } from '@lh-ui/share/core/space'설계 의도
섹션 제목: “설계 의도”resolveSpaceGaps의 핵심은 ’토큰’과 ’리터럴’을 구분하는 것입니다:
- 사전 정의 단계(
small/medium/large)는var(--lh-spacing-*)를 출력하고usesTokens: true를 반환합니다. 간격이 테마 커스터마이징에 따라 변합니다. - 숫자는 px 리터럴로 간주하여
usesTokens: false를 반환합니다. 간격은 호출 쪽의 일회성 결정입니다. - 배열
[columnGap, rowGap]은 두 축을 따로 제어합니다.
왜 usesTokens를 밖으로 드러낼까요? UI 계층의 렌더링 전략이 다르기 때문입니다: 토큰을 쓸 때는 클래스명을 생략할 수 있고(gap이 CSS 변수로 직접 구동), 리터럴을 쓸 때는 반드시 인라인 스타일을 써야 합니다. 이 표시가 있으면 UI 계층이 출력 값을 정규식으로 다시 파싱하지 않아도 됩니다.
단계는 var.scss에 실제로 등록된 spacing token만 참조하며, 폴백 값은 토큰의 기본값과 일치합니다. 사용자가 --lh-spacing-*를 덮어써야 실제 효과가 있으며, 이 일관성은 verify:styles가 보장합니다.
함수 표
섹션 제목: “함수 표”| 함수 | 시그니처 | 반환 | 역할 |
|---|---|---|---|
getSpaceClassNames |
(state: LhSpaceState) => string[] |
클래스명 배열 | 방향, 줄바꿈, 크기 수정자 클래스 |
resolveSpaceGaps |
(size: LhSpaceSizeInput) => { columnGap: string; rowGap: string; usesTokens: boolean } |
gap 설명 | size를 CSS gap으로 정규화 |
resolveSpaceAlignment |
(alignment: string) => string |
CSS 값 | 정렬 값 그대로 전달 |
resolveSpaceGaps의 매핑:
| 입력 | columnGap / rowGap | usesTokens |
|---|---|---|
'small' |
var(--lh-spacing-sm, 8px) |
true |
'medium' |
var(--lh-spacing-base, 16px) |
true |
'large' |
var(--lh-spacing-xl, 24px) |
true |
24(숫자) |
24px |
false |
[16, 8] |
16px / 8px |
false |
경계: 배열의 빈 항목이나 유한하지 않은 값은 0으로 되돌아갑니다("undefinedpx"를 피하기 위해); 단계와 숫자의 혼합(['medium', 8] 등)은 지원하지 않습니다.
타입 정의
섹션 제목: “타입 정의”export type LhSpaceAlignment = 'start' | 'center' | 'end' | 'baseline'export type LhSpaceSizeInput = 'small' | 'medium' | 'large' | number | [number, number]
export interface LhSpaceState { direction: 'horizontal' | 'vertical' wrap: boolean size: string // 클래스명 계산은 사전 정의 단계만 받음}타입상의 역할 분담에 주의하세요: LhSpaceState.size(클래스명용)는 사전 정의 단계 문자열만 받고, LhSpaceSizeInput(gap 계산용)은 추가로 숫자와 배열을 받습니다. 클래스명에 lh-space--16px 같은 것은 나올 수 없습니다.
접근성
섹션 제목: “접근성”space는 순수 레이아웃 요소로, aria 속성을 출력하지 않고 자체는 스크린 리더에 보이지 않습니다. 이것이 감싼 콘텐츠는 각자 원래의 의미를 유지합니다. 이것이 <button> 같은 컨테이너와의 space의 차이입니다: space는 어떤 의미 계층도 도입하지 않습니다.
사용 예
섹션 제목: “사용 예”import { getSpaceClassNames, resolveSpaceGaps } from '@lh-ui/share/core/space'
getSpaceClassNames({ direction: 'horizontal', wrap: true, size: 'small' })// ['lh-space', 'lh-space--horizontal', 'lh-space--small', 'lh-space--wrap']
resolveSpaceGaps('medium')// { columnGap: 'var(--lh-spacing-base, 16px)', rowGap: 'var(--lh-spacing-base, 16px)', usesTokens: true }
resolveSpaceGaps([16, 8])// { columnGap: '16px', rowGap: '8px', usesTokens: false }<!-- Vue3 --><div :class="getSpaceClassNames({ direction, wrap, size })" :style="gapStyle"> <slot /></div>// Reactconst gaps = resolveSpaceGaps(size)const style = { columnGap: gaps.columnGap, rowGap: gaps.rowGap }return <div className={getSpaceClassNames({ direction, wrap, size }).join(' ')} style={style}>{children}</div>// uniapp: gap은 h5가 아닌 단말에서도 잘 지원됩니다(nvue/uvue 모두 지원);// 일부 단말이 gap을 지원하지 않으면 UI 계층은 자식 항목에 margin을 주는 것으로 저하합니다스타일과 토큰
섹션 제목: “스타일과 토큰”| 클래스명 | 의미 |
|---|---|
.lh-space |
기본 클래스: flex 컨테이너 |
.lh-space--horizontal / .lh-space--vertical |
방향(flex-direction) |
.lh-space--wrap |
줄바꿈 허용 |
.lh-space--{small|medium|large} |
단계 클래스(--lh-spacing-* 토큰과 연동) |
단계 클래스와 resolveSpaceGaps의 사전 정의 출력은 같은 토큰의 두 가지 표현입니다: 클래스명은 @use의 SCSS 변수(컴파일 시점)를 따르고, gap은 CSS 변수(실행 시점)를 따릅니다. 두 값은 일치하며, verify:styles가 검증합니다.
주의사항
섹션 제목: “주의사항”- 혼용하지 마세요:
resolveSpaceGaps(['medium', 8])는 지원되지 않습니다(구현상 혼합을 인식하지 못함). 두 축의 간격을 다르게 하려면 모두 숫자인[16, 8]을 사용하세요. - 숫자와 토큰의 선택: 컴포넌트 라이브러리 내부의 기본값은 단계를 따라야 하고(테마에 따라 변함), 비즈니스 호출 지점의 임시 미세 조정에는 숫자를 씁니다.
- 줄바꿈(
wrap)은 horizontal에서만 의미가 있습니다; vertical + wrap은 효과가 없습니다. resolveSpaceAlignment는 현재 직접 전달이며, 구체적인 flex 키워드 매핑은 스타일 계층에 있습니다(클래스명으로 구동).
@lh-ui/share/core/space → resolveSpaceGaps( )(填好参数后点运行)Copyright © 2024-2026 FengMo WenXue