Skip to content

테마 사용자 정의 ​

lh-ui-plus는 완전한 CSS 변수 테마 시스템을 제공하여, 국풍 테마 색상, 다크 모드, 문양 배경, 런타임 전환 등 다양한 사용자 정의 기능을 지원합니다.

색상을 시각적으로 조정하고 scss를 바로 내보내고 싶다면 테마 스튜디오를 참고하세요.

국풍 테마 색상 체계 ​

컴포넌트 라이브러리는 전통 수묵 단청에서 디자인 영감을 얻어, 8가지 국풍 색상 테마를 정의합니다:

색상의미주요 색상hover적용
靛蓝 (쪽빛)청화자기의 푸름#2B4C7C#3D649E주요 버튼, 링크, 포커스 상태
松花绿 (송화록)대나무 그림자의 푸르름#5B8C5A#6FA36E성공 상태
藤黄 (등황)단풍잎의 금빛#C4A35A#D4B76F경고 상태
朱砂 (위험)도장의 주홍색#B23A3A#C45050위험/오류 상태 (--lh-danger-*)
黛色 (짙은 먹색)수묵의 옅은 채색#7A7A7A#8F8F8F정보 상태
金色 (금색)화려한 옛 정취#B8860B#D4A843장식 포인트 (--lh-gold-*)
朱砂红 (강조)진사가 붉은 쪽으로 치우친 강조 변형#C43A31#E85D4A강조 색상 (--lh-vermilion-*)
玉色 (옥색)싱그러운 대나무의 청아함#5B8C5A#7AAE7A성공/장식 (松花绿와 동일한 값)

각 색상은 일반적으로 4개의 계층 (주요 색상/hover/active/light 배경색)을 포함하며, 주요 색상과 금색은 추가로 lighter 테두리색 (*-color-border)을 제공하여 다양한 상황에서 적절한 대비를 보장합니다.

CSS 변수 테마 시스템 ​

모든 테마 색상은 CSS 사용자 속성 (--lh-*)으로 구현되며, 총 88+개 변수가 다음 카테고리를 다룹니다:

색상 변수 ​

변수 접두사설명예시
--lh-primary-color주요 색상 기본값#2B4C7C
--lh-primary-color-hover주요 색상 hover 상태#3D649E
--lh-primary-color-active주요 색상 active 상태#1F3A5F
--lh-primary-color-bg주요 색상의 옅은 배경#E8EDF3
--lh-success-color성공 색상#5B8C5A
--lh-warning-color경고 색상#C4A35A
--lh-danger-color위험 색상#B23A3A
--lh-info-color정보 색상#7A7A7A

텍스트 변수 ​

변수명설명기본값
--lh-text-primary주요 텍스트#2C2C2C
--lh-text-regular일반 텍스트#5A5A5A
--lh-text-secondary보조 텍스트#8A8A8A
--lh-text-placeholder플레이스홀더#B0B0B0
--lh-text-disabled비활성화 텍스트#C8C8C8

테두리 변수 ​

변수명설명기본값
--lh-border-color-base기본 테두리#D8D3CC
--lh-border-color-light가벼운 테두리#E5E0D8
--lh-border-radius-base기본 모서리 둥글기2px
--lh-border-radius-round캡슐형 모서리 둥글기20px

배경 변수 ​

변수명설명기본값
--lh-bg-color컴포넌트 배경#FAF6F0 (화선지색)
--lh-bg-color-page페이지 배경#F5F0EB
--lh-bg-color-overlay오버레이 배경rgba(26, 26, 26, 0.4)

그림자 변수 ​

변수명설명
--lh-box-shadow-base기본 그림자
--lh-box-shadow-light가벼운 그림자
--lh-box-shadow-lighter아주 가벼운 그림자

글꼴 변수 ​

변수명설명기본값
--lh-font-family글꼴 패밀리Noto Serif SC, STSong, SimSun...
--lh-font-size-base기본 글자 크기14px
--lh-font-size-small작은 글자 크기13px
--lh-font-weight-primary일반 글꼴 두께400
--lh-font-line-height-primary줄 높이1.8

간격 변수 ​

변수명값용도
--lh-spacing-xs4px아주 작은 간격
--lh-spacing-sm8px작은 간격
--lh-spacing-md12px중간 간격
--lh-spacing-base16px기본 간격
--lh-spacing-lg20px큰 간격
--lh-spacing-xl24px아주 큰 간격

Z-Index 변수 ​

변수명값용도
--lh-z-index-dropdown1000드롭다운 메뉴
--lh-z-index-modal1050모달
--lh-z-index-tooltip2000툴팁

트랜지션 변수 ​

변수명값설명
--lh-transition-duration-fast0.25s빠른 트랜지션
--lh-transition-duration-base0.3s기본 트랜지션
--lh-transition-duration-slow0.4s느린 트랜지션

다크 테마 ​

컴포넌트 라이브러리는 다크 테마 스타일을 내장하며, 모든 CSS 변수는 다크 모드에서 자동으로 적응된 값으로 전환됩니다.

방법 1: useLhTheme 컴포저블 사용 ​

Composition API ​

vue
<script setup lang="ts">
import { useLhTheme } from '@lh-ui/vue3'

const { theme, toggleTheme, setTheme } = useLhTheme()
</script>

<template>
  <div>
    <LhButton @click="toggleTheme">
      {{ theme === 'dark' ? '라이트로 전환' : '다크로 전환' }}
    </LhButton>
    <LhButton @click="() => setTheme('light')">라이트</LhButton>
    <LhButton @click="() => setTheme('dark')">다크</LhButton>
  </div>
</template>

Options API ​

vue
<script>
import { useLhTheme } from '@lh-ui/vue3'

export default {
  setup() {
    const { theme, toggleTheme, setTheme } = useLhTheme()
    return { theme, toggleTheme, setTheme }
  },
}
</script>

<template>
  <div>
    <LhButton @click="toggleTheme">
      {{ theme === 'dark' ? '라이트로 전환' : '다크로 전환' }}
    </LhButton>
  </div>
</template>

useLhTheme는 테마 상태를 localStorage(key: lh-ui-theme)에 자동으로 저장하여, 페이지를 새로고침해도 테마가 유지됩니다.

방법 2: HTML 속성 전환 ​

루트 요소에 data-theme="dark"를 설정하면 다크 모드가 전역으로 활성화됩니다:

html
<!DOCTYPE html>
<html lang="ko-KR" data-theme="dark">
  <!-- ... -->
</html>

사용자 정의 테마 색상 (青花瓷 / 松花绿 / 朱砂红) ​

내장된 라이트/다크 테마 외에, 컴포넌트 라이브러리는 themeVars를 통해 임의의 색상 조합을 사용자 정의하여 개인화된 테마를 구현할 수 있습니다. (青花瓷 (청화자기) / 松花绿 (송화록) / 朱砂红 (진사홍))

아래 예시는 수동으로 사용자 정의 변수를 작성하는 시연이며, 설명을 위해 값을 조정했으므로 사전 정의된 테마의 동일한 이름의 내장 프리셋 (cerblue / songhua / zhusha)과 완전히 같지는 않습니다. 내장 프리셋을 직접 사용하려면 useLhPresetTheme 또는 getThemeVars(name)을 사용하세요.

青花瓷 (청화자기) 테마 ​

짙은 쪽빛을 주요 색상으로 하며, 전통 청화자기에서 영감을 받았습니다.

Composition API ​

vue
<script setup lang="ts">
const cerblueTheme = {
  'primary-color': '#2B4C7C',
  'primary-color-hover': '#3D649E',
  'primary-color-active': '#1F3A5F',
  'primary-color-bg': '#E8EDF3',
  'bg-color': '#F0F4F8',
  'border-color-base': '#C8D6E5',
}
</script>

<template>
  <LhConfigProvider :theme-vars="cerblueTheme">
    <LhButton type="primary">청화자기 버튼</LhButton>
    <LhInput placeholder="청화자기 입력 상자" />
  </LhConfigProvider>
</template>

Options API ​

vue
<script>
import { LhConfigProvider, LhButton, LhInput } from '@lh-ui/vue3'

export default {
  components: { LhConfigProvider, LhButton, LhInput },
  data() {
    return {
      cerblueTheme: {
        'primary-color': '#2B4C7C',
        'primary-color-hover': '#3D649E',
        'primary-color-bg': '#E8EDF3',
        'bg-color': '#F0F4F8',
      },
    }
  },
}
</script>

<template>
  <LhConfigProvider :theme-vars="cerblueTheme">
    <LhButton type="primary">청화자기 버튼</LhButton>
  </LhConfigProvider>
</template>

松花绿 (송화록) 테마 ​

대나무 초록을 포인트로 삼아, 청량하고 자연스러운 분위기를 연출합니다.

vue
<script setup lang="ts">
const bambooTheme = {
  'primary-color': '#5B8C5A',
  'primary-color-hover': '#6FA36E',
  'primary-color-bg': '#EDF5EC',
  'success-color': '#5B8C5A',
  'bg-color': '#F6FAF5',
}
</script>

<template>
  <LhConfigProvider :theme-vars="bambooTheme">
    <LhButton type="primary">대숲 오솔길</LhButton>
    <LhTag type="success">새 잎</LhTag>
  </LhConfigProvider>
</template>

朱砂红 (진사홍) 테마 ​

도장의 주홍색을 주조로 하여, 우아하고 화려한 분위기를 돋보이게 합니다.

vue
<script setup lang="ts">
const vermilionTheme = {
  'primary-color': '#C43A31',
  'primary-color-hover': '#E85D4A',
  'primary-color-bg': '#FDF0EE',
  'bg-color': '#FFFBF9',
  'border-color-base': '#F0D5CF',
}
</script>

<template>
  <LhConfigProvider :theme-vars="vermilionTheme">
    <LhButton type="primary">주홍 증서</LhButton>
  </LhConfigProvider>
</template>

문양 배경 시스템 ​

컴포넌트 라이브러리는 국풍 시적인 문양 배경 시스템을 제공하여, 6가지 프리셋 문양을 지원하고 patternComponents 허용 목록으로 적용 범위를 정밀하게 제어할 수 있습니다.

프리셋 문양 ​

문양명CSS 변수설명
柳叶 (버들잎)var(--lh-pattern-willow)가늘고 긴 버들잎, 적당한 밀도
祥云 (상서로운 구름)var(--lh-pattern-cloud)펼쳐진 상서로운 구름, 유려하게 흐름
水波 (물결)var(--lh-pattern-water)미세하게 움직이는 잔물결, 겹겹이 쌓임
雪花 (눈꽃)var(--lh-pattern-snow)육각 눈꽃, 가지가 갈라짐
梅花 (매화)var(--lh-pattern-plum)다섯 잎이 펼쳐지고, 꽃밥이 또렷함
竹叶 (대나무잎)var(--lh-pattern-bamboo)바늘잎 형태의 대나무잎, 어우러짐

전역 문양 구성 ​

Composition API ​

vue
<script setup lang="ts">
const config = {
  themeVars: {
    'bg-pattern': 'var(--lh-pattern-cloud)',
    'bg-pattern-opacity': '0.15',
  },
  patternComponents: ['button', 'input'] as const,
}
</script>

<template>
  <LhConfigProvider
    :theme-vars="config.themeVars"
    :pattern-components="config.patternComponents"
  >
    <!-- 버튼과 입력 상자에 문양이 적용되고, Dialog에는 적용되지 않습니다 -->
    <LhButton>문양 버튼</LhButton>
    <LhInput placeholder="문양 입력 상자" />
  </LhConfigProvider>
</template>

Options API ​

vue
<script>
export default {
  data() {
    return {
      config: {
        themeVars: {
          'bg-pattern': 'var(--lh-pattern-cloud)',
          'bg-pattern-opacity': '0.15',
        },
        patternComponents: ['button', 'input'],
      },
    }
  },
}
</script>

<template>
  <LhConfigProvider
    :theme-vars="config.themeVars"
    :pattern-components="config.patternComponents"
  >
    <LhButton>문양 버튼</LhButton>
  </LhConfigProvider>
</template>

문양 변수 참고 ​

변수명설명기본값
--lh-bg-pattern문양 배경 URLnone
--lh-bg-pattern-repeat바둑판 배열 모드repeat
--lh-bg-pattern-size문양 크기40px
--lh-bg-pattern-opacity문양 불투명도0.15
--lh-bg-pattern-color문양 색상var(--lh-decoration-color, rgba(184, 134, 11, 0.12))
--lh-bg-pattern-blend혼합 모드soft-light

전체 구성 예시 ​

다음은 ConfigProvider의 전체 구성 사용법을 보여주며, 테마, 언어, 크기, 문양 등 모든 기능을 통합합니다.

Composition API ​

vue
<script setup lang="ts">
import { zhCN } from '@lh-ui/vue3'

const configProvider = {
  size: 'medium' as const,
  locale: zhCN,
  themeVars: {
    'primary-color': '#2B4C7C',
    'bg-pattern': 'var(--lh-pattern-cloud)',
    'bg-pattern-opacity': '0.15',
  },
  patternComponents: ['button', 'input', 'dialog'],
}
</script>

<template>
  <LhConfigProvider
    :size="configProvider.size"
    :locale="configProvider.locale"
    :theme-vars="configProvider.themeVars"
    :pattern-components="configProvider.patternComponents"
  >
    <slot />
  </LhConfigProvider>
</template>

Options API ​

vue
<script>
import { zhCN } from '@lh-ui/vue3'

export default {
  data() {
    return {
      configProvider: {
        size: 'medium',
        locale: zhCN,
        themeVars: {
          'primary-color': '#2B4C7C',
          'bg-pattern': 'var(--lh-pattern-cloud)',
        },
        patternComponents: ['button', 'input', 'dialog'],
      },
    }
  },
}
</script>

<template>
  <LhConfigProvider
    :size="configProvider.size"
    :locale="configProvider.locale"
    :theme-vars="configProvider.themeVars"
    :pattern-components="configProvider.patternComponents"
  >
    <slot />
  </LhConfigProvider>
</template>

테마 변수 우선순위 ​

컴포넌트가 최종적으로 사용하는 CSS 변수는 다음 우선순위로 병합됩니다 (후자가 전자를 덮어씁니다):

  1. ConfigProvider 전역 themeVars (가장 낮은 우선순위)
  2. ConfigProvider의 컴포넌트별 componentTheme[컴포넌트명]
  3. 컴포넌트 자체의 themeVars prop
  4. 컴포넌트 자체의 bgPattern prop (가장 높은 우선순위)

bg-pattern 변수의 경우 추가로 patternComponents 허용 목록의 제어를 받습니다: 허용 목록에 있는 컴포넌트만 전역으로 구성된 bg-pattern을 적용합니다.

sx 빠른 레이아웃 ​

sx 속성은 선언적인 인라인 레이아웃 방식을 제공하여, CSS를 작성하지 않고도 컴포넌트의 간격과 크기를 설정할 수 있습니다. 현재 다음 컴포넌트에서 지원합니다: Button, Input, Dialog, Tooltip, Alert, Card, Empty, Breadcrumb, Pagination, Steps, Tabs, Skeleton.

원리 ​

sx는 8px 기준 그리드를 사용하며, 숫자에 8을 곱해 실제 픽셀 값을 얻습니다. 예를 들어 mt: 2는 marginTop: 16px와 동일합니다.

지원 속성 ​

간격 ​

속성설명예시동등한 CSS
m네 면 바깥쪽 간격m: 2margin: 16px
mx수평 바깥쪽 간격mx: 1marginLeft: 8px; marginRight: 8px
my수직 바깥쪽 간격my: 1marginTop: 8px; marginBottom: 8px
mt, mr, mb, ml한쪽 방향 바깥쪽 간격mt: 2marginTop: 16px
p네 면 안쪽 간격p: 3padding: 24px
px수평 안쪽 간격px: 2paddingLeft: 16px; paddingRight: 16px
py수직 안쪽 간격py: 1paddingTop: 8px; paddingBottom: 8px
pt, pr, pb, pl한쪽 방향 안쪽 간격pt: 2paddingTop: 16px

크기 ​

속성설명예시
w너비 (숫자는 px, 문자열은 값 그 자체)w: 200 또는 w: '100%'
h높이h: 100 또는 h: 'auto'

Flex 레이아웃 ​

속성설명예시
display표시 유형display: 'flex'
flexflex 약식 표기flex: '1 1 0%'
flexDirection주축 방향flexDirection: 'column'
alignItems교차축 정렬alignItems: 'center'
justifyContent주축 정렬justifyContent: 'flex-end'

사용 예시 ​

vue
<script setup lang="ts">
import { ref } from 'vue'

const visible = ref(false)
</script>

<template>
  <!-- 버튼 간격 -->
  <LhButton type="primary" :sx="{ mt: 2, mx: 1 }">간격이 있는 버튼</LhButton>

  <!-- 입력 상자 바깥쪽 간격 -->
  <LhInput placeholder="입력 상자 상하 간격" :sx="{ my: 1 }" />

  <!-- Dialog 너비: sx는 w/h와 간격류 속성만 지원 -->
  <LhDialog v-model="visible" title="예시" :sx="{ w: 480 }">
    <p>고정 너비의 대화상자</p>
  </LhDialog>
</template>
vue
<script>
export default {
  data() {
    return { visible: false }
  },
}
</script>

<template>
  <LhButton type="primary" :sx="{ mt: 2, mx: 1 }">간격이 있는 버튼</LhButton>
</template>

국풍의 아름다움으로 코드의 토대를 세웁니다