开始

安装

Hina UI 以源码分发,依赖 Tailwind CSS v4 与 Vue 3.5。

安装依赖

pnpm add @hina-ui/vue
bash

vue 是 peer 依赖,版本要求 ^3.5.0。其余依赖会随包安装,不需要手动声明。

样式入口

@import 'tailwindcss';
@import '@hina-ui/vue/styles/tokens.css';
css

tokens.css 是唯一的样式入口,不需要再引入其他文件,也不需要为本库另写 @source,需要扫描的路径已经由这个入口登记。

字体

正文的西文采用 Noto Sans,中文采用 Noto Sans SC;等宽采用 JetBrains Mono。字体由应用负责加载。

根元素的 lang 为中文时,Noto Sans SC 排在前面,页面里的西文也使用 Noto Sans SC。

export default defineNuxtConfig({
  modules: ['@nuxt/fonts'],
  fonts: {
    families: [
      { name: 'Noto Sans', provider: 'google', weights: [400, 500, 600, 700], global: true },
      { name: 'Noto Sans SC', provider: 'google', weights: [400, 500, 600, 700], global: true },
      { name: 'JetBrains Mono', provider: 'google', weights: [400, 500], global: true },
    ],
  },
})
ts

字体名称定义在 --hn-font-* 变量中,自动扫描无法识别它们,需要显式声明,并将 global 设置为 true。

在最外层挂载

<template>
  <TooltipProvider>
    <NuxtPage />
    <Toaster />
  </TooltipProvider>
</template>
vue

Tooltip 与 Toast 各自需要一个根节点,在应用入口挂载一次即可。使用 AppShell 时,它已经内置了 TooltipProvider。

单例约束

vue、@hina-ui/vue 在同一个应用中各自只能存在一份实例。如果存在多份,会导致浮层行为异常、焦点管理失效。

pnpm why vue @hina-ui/vue
bash

深色模式

<html lang="zh-CN" class="dark">
  <!-- 深色模式下的整个文档 -->
</html>
html

dark 类也可以加在页面中的某个容器上,容器内的语义颜色随之切换为深色。弹层默认传送到 body,不在容器内,跟随根元素的主题。

深色模式由根元素上的 dark 类切换,语义颜色随之翻转。使用 @nuxtjs/color-mode 时,需要将 classSuffix 设置为空字符串。

密度

<section data-density="compact">
  <!-- 该容器内的控件整体收紧 -->
</section>
html

控件的高度、内边距与间距均取自密度变量,默认为 comfortable。密度在容器上声明,对容器内的所有控件生效。

草稿
<script setup lang="ts">
  import { ref } from 'vue'
  import { Search } from '@lucide/vue'
  import { Button, IconButton, Inline, Input, Stack, Tag } from '@hina-ui/vue'

  const compact = ref(false)
</script>

<template>
  <Stack align="center">
    <Button variant="outline" tone="neutral" size="sm" @click="compact = !compact">
      {{ compact ? '切换回默认密度' : '切换到紧凑密度' }}
    </Button>

    <Inline :data-density="compact ? 'compact' : undefined" align="center">
      <Input placeholder="搜索" />
      <Button>提交</Button>
      <Button variant="outline" tone="neutral">重置</Button>
      <IconButton label="搜索" variant="outline">
        <Search />
      </IconButton>
      <Tag>草稿</Tag>
    </Inline>
  </Stack>
</template>
vue

size 与密度相互独立:size 决定单个控件的尺寸,密度控制整体的缩放。密度不随设备类型变化,如果触摸屏上需要更大的点击目标,应当显式使用默认密度。

语言

内置 zhCN、enUS、jaJP 三个语言包,默认使用 zhCN。

import { enUS, provideUiLocale } from '@hina-ui/vue'

provideUiLocale(enUS)
ts

组件的内置文字默认为简体中文,在应用的最外层调用一次即可切换。也可以只传入一部分内容,覆盖个别文字,未覆盖的部分仍然使用中文。

<script setup lang="ts">
  import { ConfigProvider } from '@hina-ui/vue'
</script>

<template>
  <ConfigProvider dir="ltr">
    <RouterView />
  </ConfigProvider>
</template>
vue

ConfigProvider 设置全局的文字方向 dir,组件未单独设置 dir 时都会继承它;teleportTo 可以指定浮层挂载的容器。

验证安装

<script setup lang="ts">
  import { Button, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack align="center" class="p-10">
    <Button>安装成功</Button>
  </Stack>
</template>
vue

如果按钮显示为强调色底色,悬停时变色,按下时出现波纹,说明依赖与样式都已经就位。如果只有结构而没有样式,通常是样式入口没有引入。