@uniweb/kit

中文文档
1.7.2发布于 2026/11/03Apache-2.0ES Module

Uniweb基础的标准组件库

中文使用文档
文档目录33 节
  1. 安装
  2. Tree-Shaking好处
  3. 快速入门
  4. 组件
  5. 链接
  6. 图像
  7. SafeHtml
  8. 图标
  9. SocialIcon
  10. 排版
  11. 媒体
  12. FileLogo
  13. MediaIcon
  14. 资产
  15. 钩子
  16. useWebsite
  17. useActiveRoute
  18. useScrolled
  19. useMobileMenu
  20. useAccordion
  21. useInView
  22. useGridLayout
  23. 主题挂钩
  24. 搜索
  25. useSearch
  26. useSearchPrefetch
  27. useSearchShortcut
  28. createSearchClient
  29. 风格的组件
  30. 公用事业公司
  31. 体系结构
  32. 为什么捆绑套件而外部化核心?
  33. 许可证

@uniweb /工具

Uniweb基础的标准组件库。用于构建基础组件的可摇树实用程序、组件和挂钩。

安装

npm install @uniweb/kit

Tree-Shaking好处

Kit被设计成捆绑在你的基础(而不是外部化像 @uniweb/core). 这意味着:

  • 只有你使用的是捆绑的 —导入3个组件?只有这3个最终成为你的基金
  • 没有运行时开销 -在构建时消除未使用的代码
  • 可定制的 -覆盖或扩展任何组件而不携带死代码
  • 小的基础 -最小的粉底使用 Link 和 useWebsite 保持小
// vite.config.js - Kit is bundled, core is external
export default {
  build: {
    rollupOptions: {
      external: ['react', 'react-dom', 'react-router-dom', '@uniweb/core']
      // Note: @uniweb/kit is NOT in external — it gets tree-shaken
    }
  }
}

快速入门

import { Link, Image, useWebsite } from '@uniweb/kit'

function Hero({ content }) {
  const { localize } = useWebsite()

  return (
    <div>
      <Image src={content.images[0]?.url} alt="Hero" />
      <h1>{localize({ en: 'Welcome', es: 'Bienvenido' })}</h1>
      <Link to="/about">Learn More</Link>
    </div>
  )
}

组件

具有路由和下载功能的智能链接组件。一个离开网站、下载文件、写电子邮件或打电话的链接会得到一个提示;内部链接没有。

import { Link } from '@uniweb/kit'

<Link to="/about">About</Link>
<Link href="https://github.com">GitHub</Link>
<Link href="/files/report.pdf">Download Report</Link>
<Link href="mailto:[email protected]">Contact</Link>
道具类型描述
to / hrefstring目标URL
titlestring工具提示。如果省略,则只有当链接离开网站、下载、写电子邮件或拨打电话时才会生成一个链接
targetstring链接的目标
downloadboolean强制下载行为

图像

具有过滤器和大小预设的通用图像组件。

import { Image } from '@uniweb/kit'

<Image src="/photo.jpg" alt="Photo" />
<Image src="/photo.jpg" filter={{ grayscale: 100 }} />
<Image src="/team/ada.jpg" alt="Ada" size="lg" rounded />
道具类型描述
src / urlstring图像URL
altstringAlt文本
sizestring预设:xs, sm, md, lg, xl, 2xl, full
roundedboolean|string边界半径
filterobjectCSS滤镜:模糊、亮度、对比度、灰度、饱和度、棕褐色

SafeHtml

安全渲染HTML,解析 page: 链接和基本路径。

import { SafeHtml } from '@uniweb/kit'

<SafeHtml value="<p>Hello <strong>World</strong></p>" />
<SafeHtml value='<a href="page:about">About</a>' />

图标

带有内置图标和URL加载的SVG图标组件。

import { Icon } from '@uniweb/kit'

<Icon name="check" size="24" color="green" />
<Icon url="/icons/custom.svg" />
<Icon svg="<svg>...</svg>" />

内置:检查,警报,用户,心,设置,星号,关闭,菜单,雪佛兰下,雪佛兰右,外部链接,下载,播放

SocialIcon

自动检测社交媒体平台图标。

import { SocialIcon, getSocialPlatform, filterSocialLinks } from '@uniweb/kit'

<SocialIcon platform="twitter" size={24} />
<SocialIcon url="https://twitter.com/example" />

// Utilities
getSocialPlatform('https://linkedin.com/in/user')  // 'linkedin'
filterSocialLinks(links)  // Filter to only social links

支持:facebook, twitter, x, linkedin, instagram, youtube, github, medium, pinterest,抖音,discord,乳齿象,蓝天,电子邮件,电话,orcid, researchgate, google学者

排版

用于呈现语义解析器输出的智能排版组件。

import { Text, H1, H2, P, PlainText } from '@uniweb/kit'

<H1 text="Main Title" />
<H2 text={["Multi-line", "Subtitle"]} />
<P text="A paragraph of content" />
<P text={["First paragraph", "Second paragraph"]} />

// Plain text (HTML shown as text)
<PlainText text="Show <strong>tags</strong> as text" />
道具类型描述
textstring|string[]要呈现的内容
asstring标签:'h1'-'h6', 'p', 'div', ‘span’
htmlboolean渲染为HTML(默认值:true)
lineAsstring数组项的标签

别名: H1, H2, H3, H4, H5, H6, P, Span, Div, PlainText

媒体

视频播放器的YouTube, Vimeo,和本地视频。

import { Media } from '@uniweb/kit'

<Media src="https://youtube.com/watch?v=abc123" />
<Media src="/videos/intro.mp4" controls />
<Media src="https://youtube.com/..." thumbnail="/poster.jpg" facade />

基于文件名的文件类型图标。

import { FileLogo } from '@uniweb/kit'

<FileLogo filename="report.pdf" size="32" />

MediaIcon

平台图标(YouTube, Vimeo等)。

import { MediaIcon } from '@uniweb/kit'

<MediaIcon type="youtube" size="24" />

资产

文件预览与下载功能。

import { Asset } from '@uniweb/kit'

<Asset value="/files/document.pdf" />

钩子

useWebsite

访问网站实例和实用程序。

import { useWebsite } from '@uniweb/kit'

function MyComponent() {
  const {
    website,      // Website instance
    localize,     // Localize multilingual values
    makeHref,     // Resolve page: references to routes
    getLanguage,  // Current language code
    getLanguages  // Available languages
  } = useWebsite()

  return <div>{localize({ en: 'Hello', fr: 'Bonjour' })}</div>
}

useActiveRoute

检测活动导航状态。

import { useActiveRoute } from '@uniweb/kit'

function NavLink({ page }) {
  const { isActive, isActiveOrAncestor } = useActiveRoute()

  return (
    <Link
      to={page.route}
      className={isActiveOrAncestor(page) ? 'font-bold' : ''}
    >
      {page.title}
    </Link>
  )
}

useScrolled

检测粘贴头的滚动位置。

import { useScrolled } from '@uniweb/kit'

function Header() {
  const scrolled = useScrolled(50)  // Threshold in pixels

  return (
    <header className={scrolled ? 'shadow-md' : ''}>
      ...
    </header>
  )
}

useMobileMenu

移动菜单状态管理。

import { useMobileMenu } from '@uniweb/kit'

function Navbar() {
  const { isOpen, toggle, close } = useMobileMenu()

  return (
    <>
      <button onClick={toggle}>Menu</button>
      {isOpen && <MobileMenu onClose={close} />}
    </>
  )
}

useAccordion

Accordion/FAQ状态管理。

import { useAccordion } from '@uniweb/kit'

function FAQ({ items }) {
  const { isOpen, toggle } = useAccordion()

  return items.map((item, i) => (
    <div key={i}>
      <button onClick={() => toggle(i)}>{item.question}</button>
      {isOpen(i) && <p>{item.answer}</p>}
    </div>
  ))
}

useInView

延迟加载和动画的视口交叉检测。

import { useInView, useIsInView } from '@uniweb/kit'

function AnimatedSection() {
  const { ref, inView } = useInView({ threshold: 0.2, once: true })

  return (
    <div ref={ref} className={inView ? 'animate-fade-in' : 'opacity-0'}>
      Content appears when scrolled into view
    </div>
  )
}

// Simple boolean version
function LazyImage({ src }) {
  const [ref, isInView] = useIsInView()
  return <div ref={ref}>{isInView && <img src={src} />}</div>
}

useGridLayout

响应式电网公用事业。

import { useGridLayout, getGridClasses } from '@uniweb/kit'

function Gallery({ items }) {
  const { columns } = useGridLayout(items.length, { maxColumns: 4 })

  return (
    <div className={getGridClasses(columns)}>
      {items.map(item => <Card key={item.id} {...item} />)}
    </div>
  )
}

主题挂钩

在运行时访问站点主题化数据。

import {
  useThemeData,
  useThemeColor,
  useThemeColorVar,
  useColorContext,
  useAppearance
} from '@uniweb/kit'

function ThemedComponent({ block }) {
  // Full theme access
  const theme = useThemeData()
  const palettes = theme?.getPaletteNames()  // ['primary', 'secondary', ...]

  // Get specific color
  const primaryColor = useThemeColor('primary', 500)  // '#3b82f6'
  const primaryVar = useThemeColorVar('primary', 600)  // 'var(--primary-600)'

  // Context-aware (light/medium/dark sections)
  const context = useColorContext(block)  // 'light' | 'medium' | 'dark'

  // Dark mode
  const { scheme, toggle, canToggle } = useAppearance()

  return (
    <div style={{ color: primaryColor }}>
      {canToggle && (
        <button onClick={toggle}>
          {scheme === 'dark' ? 'Light' : 'Dark'}
        </button>
      )}
    </div>
  )
}

全文搜索由Fuse.js提供支持。需要 fuse.js 作为你基金会的同伴依赖。

npm install fuse.js

useSearch

主要的搜索挂钩与脱绑定和状态管理。

import { useSearch, useWebsite } from '@uniweb/kit'

function SearchComponent() {
  const { website } = useWebsite()
  const { query, results, isLoading, isEnabled, preload } = useSearch(website)

  if (!isEnabled) return null

  return (
    <div>
      <input onChange={e => query(e.target.value)} placeholder="Search..." />
      {isLoading && <span>Searching...</span>}
      {results.map(r => (
        <a key={r.id} href={r.href}>{r.title}</a>
      ))}
    </div>
  )
}

useSearchPrefetch

预取搜索索引悬停,焦点或触摸,而不是在页面加载。

import { useSearchPrefetch, useSearchShortcut } from '@uniweb/kit'

function SearchButton({ onClick }) {
  const { website } = useWebsite()
  const { triggerPreload, prefetchProps } = useSearchPrefetch(website)

  // Cmd/Ctrl+K shortcut with preload
  useSearchShortcut({
    onOpen: onClick,
    onPreload: triggerPreload,
  })

  return (
    <button onClick={onClick} {...prefetchProps}>
      Search
    </button>
  )
}

从不搜索的访问者永远不会下载索引。它取一次。

useSearchShortcut

打开搜索的键盘快捷方式。

import { useSearchShortcut } from '@uniweb/kit'

// Simple
useSearchShortcut(() => setSearchOpen(true))

// With preload on shortcut
useSearchShortcut({
  onOpen: () => setSearchOpen(true),
  onPreload: () => searchClient.preload()
})

createSearchClient

低级搜索客户端供高级使用。

import { createSearchClient } from '@uniweb/kit'

const client = createSearchClient(website, {
  fuseOptions: { threshold: 0.3 },
  defaultLimit: 10
})

// Query — returns SearchResult[]
const results = await client.query('authentication', { limit: 5 })

// Same query, plus how many matched before `limit` — the 47 in "showing 10 of 47".
// `total` is null when the active provider cannot say (a deployment fact, not an
// error): the local index always knows it; an endpoint knows it only if it
// reports one. Render the count conditionally, the results unconditionally.
const { results: page, total } = await client.queryWithTotal('authentication', { limit: 5 })

// Preload index
await client.preload()

// Check status
client.isEnabled()
client.getIndexUrl()

风格的组件

使用顺风CSS预样式组件。

import { Section, SidebarLayout, Disclaimer } from '@uniweb/kit'

<Section width="lg" padding="md" className="bg-gray-50">
  <h1>Welcome</h1>
</Section>

<SidebarLayout sidebar={<Nav />} sidebarPosition="left">
  <main>Content</main>
</SidebarLayout>

<Disclaimer
  title="Terms of Service"
  content="<p>Please read our terms...</p>"
  triggerText="View Terms"
/>

公用事业公司

import { cn, stripTags, isExternalUrl, isFileUrl, detectMediaType } from '@uniweb/kit'

// Merge Tailwind classes (uses tailwind-merge)
cn('px-4 py-2', 'bg-blue-500', condition && 'opacity-50')

// Strip HTML tags
stripTags('<p>Hello</p>')  // "Hello"

// URL utilities
isExternalUrl('https://google.com')  // true
isFileUrl('/files/doc.pdf')          // true
detectMediaType('https://youtube.com/...')  // 'youtube'

体系结构

┌─────────────────────────────────────────────────────────────┐
│  Foundation (your code)                                     │
│    ├── imports @uniweb/kit (bundled, tree-shaken)           │
│    └── @uniweb/core marked as external                      │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│  @uniweb/runtime (browser)                                  │
│    ├── Loads foundation dynamically                         │
│    ├── Provides @uniweb/core singleton                      │
│    └── Orchestrates React rendering                         │
└─────────────────────────────────────────────────────────────┘

为什么捆绑套件而外部化核心?

  • 工具包:不同的基础可能使用不同的套件子集。摇树确保每个基础只包含它使用的东西。

  • 核心包含Website, Page和Block类,这些类必须是单例的。运行时提供这些基础,通过外部导入引用它们。

许可证

apache - 2.0

版本与发布记录

@uniweb/kit 共发布 242 个版本,首次发布于 2026/01/17;过去 12 个月发布了 242 个版本。

版本发布日期距今
1.7.2latest2026/11/03今天
1.7.12026/11/021 天前
1.7.02026/11/021 天前
1.6.162026/11/021 天前
1.6.152026/11/021 天前
1.6.142026/11/011 天前

关于 @uniweb/kit 的常见问题

@uniweb/kit 是什么?

Uniweb基础的标准组件库

如何安装 @uniweb/kit?

在项目目录运行 npm install @uniweb/kit,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19.0.0)、react-dom(^19.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@uniweb/kit 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/uniweb__kit 是否存在。

@uniweb/kit 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@uniweb/kit 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.12。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@uniweb/kit 可以商用吗?

@uniweb/kit 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@uniweb/kit 还在维护吗?

最新版本 1.7.2 发布于 2026/11/03(今天);至今共发布 242 个版本,其中过去 12 个月发布了 242 个;首次发布于 2026/01/17。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。