テーマカスタマイズ
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-xs | 4px | 極小の余白 |
--lh-spacing-sm | 8px | 小さな余白 |
--lh-spacing-md | 12px | 中程度の余白 |
--lh-spacing-base | 16px | 基本の余白 |
--lh-spacing-lg | 20px | 大きな余白 |
--lh-spacing-xl | 24px | 特大の余白 |
Z-Index 変数
| 変数名 | 値 | 用途 |
|---|---|---|
--lh-z-index-dropdown | 1000 | ドロップダウンメニュー |
--lh-z-index-modal | 1050 | モーダルダイアログ |
--lh-z-index-tooltip | 2000 | ツールチップ |
トランジション変数
| 変数名 | 値 | 説明 |
|---|---|---|
--lh-transition-duration-fast | 0.25s | 高速トランジション |
--lh-transition-duration-base | 0.3s | デフォルトのトランジション |
--lh-transition-duration-slow | 0.4s | 低速トランジション |
ダークテーマ
コンポーネントライブラリはダークテーマのスタイルを内蔵しており、すべての CSS 変数はダークモードで自動的に適合した値に切り替わります。
方式 1:useLhTheme composable 関数を使う
Composition API
<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
<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" を設定すると、グローバルにダークモードが有効になります:
<!DOCTYPE html>
<html lang="zh-CN" data-theme="dark">
<!-- ... -->
</html>カスタムテーマ色(青花瓷 / 松花绿 / 朱砂红)
内蔵のライト/ダークテーマに加えて、コンポーネントライブラリは themeVars による任意の色の組み合わせのカスタマイズをサポートし、パーソナライズされたテーマを実現します。
以下の例は手書きでカスタム変数を定義するデモです。解説のために値を調整しており、プリセットテーマの同名の内蔵プリセット(
cerblue/songhua/zhusha)とは完全には一致しません。内蔵プリセットをそのまま使うには、useLhPresetThemeまたはgetThemeVars(name)を使用してください。
青花瓷テーマ
深い靛藍を主要色とし、伝統的な青花瓷にインスピレーションを得ています。
Composition API
<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
<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>松花绿テーマ
竹の緑をアクセントにし、清新で自然な雰囲気を演出します。
<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>朱砂红テーマ
印泥の朱赤を基調とし、典雅で華貴な雰囲気を際立たせます。
<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
<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
<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 | 紋様背景の URL | none |
--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
<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
<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 変数は、以下の優先順位でマージされます(後のものが前のものを上書きします):
- ConfigProvider のグローバル
themeVars(最優先順位が低い) - ConfigProvider のコンポーネント別
componentTheme[コンポーネント名] - コンポーネント自身の
themeVarsprop - コンポーネント自身の
bgPatternprop(最優先順位が高い)
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: 2 | margin: 16px |
mx | 水平方向の外側余白 | mx: 1 | marginLeft: 8px; marginRight: 8px |
my | 垂直方向の外側余白 | my: 1 | marginTop: 8px; marginBottom: 8px |
mt, mr, mb, ml | 一辺の外側余白 | mt: 2 | marginTop: 16px |
p | 四辺の内側余白 | p: 3 | padding: 24px |
px | 水平方向の内側余白 | px: 2 | paddingLeft: 16px; paddingRight: 16px |
py | 垂直方向の内側余白 | py: 1 | paddingTop: 8px; paddingBottom: 8px |
pt, pr, pb, pl | 一辺の内側余白 | pt: 2 | paddingTop: 16px |
サイズ
| プロパティ | 説明 | 例 |
|---|---|---|
w | 幅(数値は px、文字列は値そのもの) | w: 200 または w: '100%' |
h | 高さ | h: 100 または h: 'auto' |
Flex レイアウト
| プロパティ | 説明 | 例 |
|---|---|---|
display | 表示タイプ | display: 'flex' |
flex | flex の一括指定 | flex: '1 1 0%' |
flexDirection | 主軸の方向 | flexDirection: 'column' |
alignItems | 交差軸の整列 | alignItems: 'center' |
justifyContent | 主軸の整列 | justifyContent: 'flex-end' |
使用例
<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><script>
export default {
data() {
return { visible: false }
},
}
</script>
<template>
<LhButton type="primary" :sx="{ mt: 2, mx: 1 }">余白付きボタン</LhButton>
</template>