# Technical Documentation: lc-soft/LCUI

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/lc-soft/LCUI)

### Overview (`README.md`)

<p align="center">
  <a href="http://lcui.dev/">
    <img src="https://lcui.dev/img/logo.png" alt="logo" width=72 height=72>
  </a>
  <h3 align="center">LCUI</h3>
  <p align="center">
    The C library for build user interfaces
  </p>
  <p align="center">
    <a href="https://github.com/lc-soft/LCUI/actions"><img alt="GitHub Actions" src="https://github.com/lc-soft/LCUI/workflows/C%2FC%2B%2B%20CI/badge.svg"></a>
    <a href="https://codecov.io/gh/lc-soft/LCUI"><img src="https://codecov.io/gh/lc-soft/LCUI/branch/develop/graph/badge.svg" /></a>
    <img src="https://img.shields.io/github/repo-size/lc-soft/LCUI.svg" alt="Repo size">
    <img src="https://img.shields.io/github/languages/code-size/lc-soft/LCUI.svg" alt="Code size">
  </p>
</p>

## Introduction

[中文版说明文档](README.zh-cn.md)

LCUI is a library written in C for building graphical user interfaces. Its goal is to explore and practice new ways of developing user interfaces, characterized by its small size, ease of use, and provision of convenient development tools to help developers quickly create desktop applications with graphical user interfaces.

**LC** originates from the initials of the author's name. The library was initially designed to help the author develop small projects and gain development experience. However, the author did not gain a competitive advantage in the job market, which is crowded with C/C++ experts, and thus had to work in web front-end development. As a result, LCUI now leans towards integrating technologies from the web front-end domain.

### Key Features

- **Cross-platform:** Supports Windows and Linux.
- **Fully custom-drawn components:** Ensures consistent appearance and behavior of components across platforms.
- **DPI awareness:** Automatically scales the UI on high-resolution screens to maintain a clear display.
- **Built-in CSS engine:** Enables the use of CSS for defining UI styles and layouts, making it easier for developers with web development experience to get started.
- **Modern development tools:** Includes tools that allow you to build user interfaces using [TypeScript](https://lcui-dev.github.io/docs/guide/typescript) with JSX syntax, the React library, and other web frontend technologies.

### Development Experience Preview

You can get an overview of the development experience for LCUI applications from the following image:



- **Component Development in React-like Style:** Writing UI configuration files using TypeScript. With the combined advantages of TypeScript, JSX syntax, and the LCUI React library, you can succinctly describe UI structure, resource dependencies, component states, data binding, and event binding.
- **Various Stylesheet Writing Methods:** [Tailwind CSS](https://tailwindcss.com/), [CSS Modules](https://github.com/css-modules/css-modules), [Sass](https://sass-lang.com/), and global CSS.
- **File-system based router:** Organize application pages in directory form, with each page corresponding to a directory. The path of the directory serves as the route for that page. With the built-in application router, you can easily implement page switching and navigation without manual route configuration.
- **User-friendly and Modern Icon Library:** Icons are sourced from the [fluentui-system-icons](https://github.com/microsoft/fluentui-system-icons) library, with partial customization to fit LCUI's characteristics, offering similar usage patterns.
- **Command-line Development Tool:** Run the `lcui build` command to preprocess configuration files within the app directory, then generate corresponding C source code and resource files.

### Architecture

Over time LCUI has been built up to be based on various libraries:

- [lib/yutil](./lib/yutil): Utility library providing common data structures and functions.
- [lib/pandagl](./lib/pandagl): PandaGL (Panda Graphics Library), a graphics library offering font management, text layout, image processing, and rendering capabilities.
- [lib/css](./lib/css): CSS parser and selector engine, enabling CSS parsing and selection functionalities.
- [lib/ptk](./lib/ptk): Platform Toolkit library offering cross-platform unified system-related APIs, including message loops, window management, timers, worker threads, and input methods.
- [lib/thread](./lib/thread): Thread library offering cross-platform multithreading capabilities.
- [lib/router](./lib/ui-router): Router manager offering routing and navigation functionalities.
- [lib/worker](./lib/worker): Worker thread library providing simple communication and management for worker threads.
- [lib/ui](./lib/ui): Core UI library that manages UI components, event queues, style computation, drawing, and other essential UI functionalities.
- [lib/ui-xml](./lib/ui-xml): XML parsing library enabling the creation of UI components from XML file content.
- [lib/ui-cursor](./lib/ui-cursor): Cursor library providing cursor rendering capabilities.
- [lib/ui-server](./lib/ui-server): UI server that maps UI components to system windows.

The core source code of LCUI is located in the `src/` directory and is divided into the following modules:

- **app:** Application lifecycle, event, and UI management.
- **fonts:** Default font settings.
- **settings:** Global settings, providing switches and parameter configurations for certain features.
- **ui:** UI and window management.
- **widgets:** Predefined components.
- **worker:** Asynchronous task management.

## Quick Start

Before you begin, you need to install the following software on your computer:

- [Git](https://git-scm.com/download/): Version control tool used to download the source code of the example project.
- [XMake](https://xmake.io/#/zh-cn/?id=%e5%ae%89%e8%a3%85): Build tool used to build the project.
- [Node.js](https://nodejs.org/): JavaScript runtime environment used to run the LCUI command-line development tool.

Then, run the following commands in a command-line window:

```shell
# Install the LCUI command-line development tool
npm install @lcui/cli

# Create an LCUI application project
lcui create my-lcui-app
```

Follow the prompts provided by the commands afterward.

## Documentation

- [Online Documentation](https://lcui-dev.github.io/docs/next/guides/base/)
- [Request for Comments (RFC)](https://lcui-dev.github.io/docs/next/rfcs/)
- [Changelog](CHANGELOG.md)
- [Contribution Guidelines](.github/CONTRIBUTING.md)

### Tutorials

<table>
  <thead>
    <tr>
      <th width="140">Title</th>
      <th>Preview</th>
      <th>Summary</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        <a href="https://lcui-dev.github.io/docs/tutorials/kantu">Image Viewer</a>
      </td>
      <td><img src="./examples/kantu.jpg" alt="kantu" /></td>
      <td>Develop an image viewer program based on the LCUI library, build its graphical interface with web technologies, implement the interface interaction logic and various functions with C language, and deeply explore the features and development techniques of LCUI in the UI aspect.</td>
    </tr>
    <tr>
      <td>
        <a href="https://lcui-dev.github.io/docs/tutorials/todolist">Todo List</a>
      </td>
      <td><img src="./examples/todolist.jpg" alt="kantu" /></td>
      <td>Learn the basic concepts and usage of LCUI, as well as how to use it to build UI and implement state management, UI updates, and interactions.</td>
    </tr>
    <tr>
      <td>
        <a href="https://lcui-dev.github.io/docs/tutorials/render-fabric">Fabric</a>
      </td>
      <td><img src="./examples/fabric.jpg" alt="kantu" /></td>
      <td>Rewrite the existing fabric simulation program's JavaScript source code in C language, and use the cairo graphics library for fabric rendering. Then, apply LCUI to implement fabric animation playback and interaction.</td>
    </tr>
    <tr>
      <td>
        <a href="https://lcui-dev.github.io/docs/2.x/tutorial/browser">Browser</a>
        <b>(Outdated)</b>
      </td>
      <td><img src="./examples/browser.jpg" alt="browser" /></td>
      <td>Referencing a web browser, use LCUI to implement similar UI structure, layout, style, and multi-tab management features. Utilize LCUI's routing management functionality to implement multi-tab page state management and navigation, as well as a simple file browsing page.</td>
    </tr>
  </tbody>
</table>

## Roadmap

Below are the items for potential future development:

- **LCUI**

  - Improve API design.
  - Enhance the CSS engine to support `inherit` and `!important`.
  - Add an [SDL](https://www.libsdl.org/) backend to replace the lib/ptk library.
  - Adapt other open-source graphics libraries to achieve better rendering performance.
  - Multi language support for internationalization.
  - Optimize memory usage.
  - Improve performance.

- **Command-Line Tools**

  - `lcui build --watch`: Continuously monitor file changes and automatically rebuild.
  - `lcui dev-server`: Similar to webpack-dev-server, build LCUI applications as websites to allow developers to preview UI in the browser.
  - Add build caching to rebuild only the modified files.

- **React Component Library**  
  Develop a component library for LCUI applications using TypeScript + React, inspired by some web frontend component libraries (e.g., [radix](https://www.radix-ui.com/), [shadcn/ui](https://ui.shadcn.com/)), and reuse components from the [LC Design](https://github.com/lcui-dev/lc-design) library.

- **Documentation**
  - Tutorials
  - Request for Comments (RFC)

## Contribution

Think LCUI is slow to update? there are many ways to [contribute](.github/CONTRIBUTING.md) to LCUI.

- [Submit bugs](https://github.com/lc-soft/LCUI/issues) and help us verify fixes as they are checked in.
- Share some interesting ideas related to GUI development in the [issues page](https://github.com/lc-soft/LCUI/issues).
- [Search for FIXME comments](https://github.com/lc-soft/LCUI/search?l=C&q=FIXME) in the source code and try to fix them.
- Fund the issues that interest you on [IssueHunt](https://issuehunt.io/r/lc-soft/LCUI) to attract other developers to contribute.
- Review the [source code changes](https://github.com/lc-soft/LCUI/pulls).
- [Contribute bug fixes](CONTRIBUTING.md).

LCUI has adopted the code of conduct defined by the Contributor Covenant. This document is used across many open source communities, and we think it articulates our values well. For more, see the [Code of Conduct](CODE_OF_CONDUCT.md).

## FAQ

**Compilation error**

The build configuration of this project has included the "Treat Warnings as Errors" compilation option. This might be because your compiler is relatively new and can detect more issues from the code. 

You can try to search for all xmake.lua files that contain `set_warnings("all", "error")` and remove this rule.

**Is this a browser engine? Or a development library like Electron that integrates a browser environment?**

No, you can think of it as a traditional GUI development library that incorporates some web technologies.

**Why should I choose LCUI over other GUI libraries/frameworks?**

It's recommended to prioritize other GUI libraries/frameworks, as LCUI currently lacks:

- **Rich Built-in Components:** You will need to build almost all the components in your UI from scratch, leading to higher development costs.
- **Efficient Graphics Rendering Performance:** Interfaces with extensive and complex content may experience lag.
- **Animation System:** The lack of visual feedback affects the user interaction experience.
- **Detailed and User-friendly Documentation**: The existing documentation and examples are only for a simple understanding. If you want to study in depth, you need to read the source code, so the learning cost is relatively high.
- **Active Updates**: Limited by the maintainer's personal interests and time, the update frequency of this project is very low. Therefore, the functional requirements or bugs you submit may not necessarily be resolved, especially those in the old versions.

Given its current state, LCUI is best suited for fulfilling the maintainer's personal needs or developing simple tools with minimal UI content and interactions.

**Support development with TypeScript? If I know how to use it, why wouldn’t I just go with Electron?**

Currently, TypeScript is primarily used to describe UI and resource dependencies, with only a few TypeScript features in use. You don’t need to study it in depth; in most cases, you can simply refer to example code for implementation.

If you have extensive web development experience and are willing to learn Electron, then Electron is clearly the better choice.

**How about CSS support?**

The following is a list of supported CSS features. Checked is supported (But does not mean full support). Unlisted properties are not supported by default.

<details>
  <summary>CSS feature coverage</summary>

- at rules
  - [x] `@font-face`
  - [ ] `@keyframes`
  - [ ] `@media`
- keywords
  - [ ] `!important`
- selectors
  - [x] `*`
  - [x] `type`
  - [x] `#id`
  - [x] `.class`
  - [x] `:hover`
  - [x] `:focus`
  - [x] `:active`
  - [x] `:first-child`
  - [x] `:last-child`
  - [ ] `[attr="value"]`
  - [ ] `:not()`
  - [ ] `:nth-child()`
  - [ ] `parent > child`
  - [ ] `a ~ b`
  - [ ] `::after`
  - [ ] `::before`
  - [ ] ...
- units
  - [x] px
  - [x] dp
  - [x] sp
  - [x] pt
  - [x] %
  - [ ] rem
  - [ ] vh
  - [ ] vw
- properties
  - [x] top, right, bottom, left
  - [x] width, height
  - [x] visibility
  - [x] display
    - [x] none
    - [x] inline-block
    - [x] block
    - [x] flex
    - [ ] inline-flex
    - [ ] inline
    - [ ] grid
    - [ ] table
    - [ ] table-cell
    - [ ] table-row
    - [ ] table-column
    - [ ] ...
  - [x] position
    - [x] static
    - [x] relative
    - [x] absolute
    - [ ] fixed
  - [x] box-sizing
    - [x] border-box
    - [x] content-box
  - [x] border
  - [x] border-radius
  - [x] background-color
  - [x] background-image
  - [x] background-position
  - [x] background-cover
  - [ ] background
  - [x] pointer-events
  - [x] font-face
  - [x] font-family
  - [x] font-size
  - [x] font-style
  - [x] flex
  - [x] flex-shrink
  - [x] flex-grow
  - [x] flex-basis
  - [x] flex-wrap
  - [x] flex-direction
  - [x] justify-content
    - [x] flex-start
    - [x] center
    - [x] flex-end
  - [x] align-items
    - [x] flex-start
    - [x] center
    - [x] flex-end
    - [x] stretch
  - [ ] float
  - [ ] transition
  - [ ] transform
  - [ ] ...

</details>

## License

The LCUI Project is released under [the MIT License](<(https://opensource.org/licenses/MIT)>).

---

### Overview (`lib/css/README.md`)

# libCSS

CSS (Cascading Style Sheet) parser and selection engine, providing CSS parsing and selection capabilities.

---

### Overview (`lib/pandagl/README.md`)

# PandaGL

PandaGL (Panda Graphics Library) is a 2D graph library to draw some basic graphics.

---

### Overview (`lib/router/README.md`)

# lcui-router

(**English**/[中文](README.zh-cn.md))

## Introduction

LCUI Router is the official router for [LCUI](https://github.com/lc-soft/LCUI). It provides a similar development experience to the [Vue Router](https://github.com/vuejs/vue-router) and make building multiple views applications with LCUI a breeze. Features include:

- Nested route/view mapping
- Modular, component-based router configuration
- Route params, query, wildcards
- Fine-grained navigation control
- Links with automatic active CSS classes

## Getting Started

> **Note:** We will using [lcui-cli](https://github.com/lc-ui/lcui-cli) tool to manage the configuration and source code for the router.

Create an LCUI application project:

``` bash
lcui create myapp
cd myapp
```

Overwrite the following code to the file `app/assets/views/app.xml`:

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<lcui-app>
  <resource type="text/css" src="assets/stylesheets/app.css"/>
  <ui>
    <w>
      <textview>Hello App!</textview>
      <w>
        
        
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
      </w>
      
      
      <router-view />
    </w>
  </ui>
</lcui-app>
```

Generate two widgets:

```bash
lcui generate widget foo
lcui generate widget bar
```

Save following code as file `config/router.js`:

```js
module.exports = [
  { path: '/foo', component: 'foo' },
  { path: '/bar', component: 'bar' }
]
```

Compile config file for router:

```bash
lcui compile router
```

Run app:

``` bash
lcpkg run start
```

For more examples, please see the [lcui-router-app](https://github.com/lc-ui/lcui-router-app) project.

## Documentation

LCUI Router is referenced from Vue Router, so you can read the [Vue Router documentation](https://router.vuejs.org/) to learn about the basic usage of LCUI Router.

## License

[MIT licensed](LICENSE).

---

### Overview (`lib/ui-router/README.md`)

# libui-router

(**English**/[中文](README.zh-cn.md))

`libui-router` is the UI binding layer that connects [librouter](../router/README.md) to [libui](../ui/) widgets.

It ships two widgets:

- `router-link` — a clickable widget that triggers navigation; mirrors `<router-link>` from Vue Router. Toggles `router-link-active` and `router-link-exact-active` classes based on the current route.
- `router-view` — a route outlet that renders the matched component for the current route.

## Usage

```c
#include <ui.h>
#include <ui_router.h>

ui_init();
ui_register_router_link();
ui_register_router_view();

/* Now "router-link" and "router-view" widget types are available. */
```

When LCUI is used as a whole, `lcui_init()` already calls these registration functions through `lcui_widgets_init()`; this lib only needs to be called manually if you embed `libui-router` without the LCUI top-level shell.

## License

[MIT licensed](../../LICENSE.TXT).

---

### Overview (`lib/yutil/README.md`)

# yutil

一个用 c 语言实现的基础工具类函数库。

## 简介

`yutil` 易工具：是一个用 c 语言实现的实用类函数库。


目前计划以下内容。

## 特性

**容器**

- 提供链表、数组、红黑树、字典等常用容器。

**实用工具**

- 实现日志输出工具。

**字符编码**

- 支持 utf8、ansi 与 Unicode 之间的互相转码。

**数学运算**

- 提供一些特定的数学函数。

**内存**

- 提供 strpool 用于解决大量相同字符串的内存占用问题。
- 提供 strlist 满足多字符串存储需求，配合  strpool 使用。

**其他**

- 提供部分字符串、宽字符串操作。
- 提供 directory、time 等常用系统接口。
- 提供不依赖事件循环的定时器。

---

### Overview (`lib/pandagl/examples/cairo/README.md`)

# Cairo Example

(**English**/[中文](./README.zh-cn.md))

An example of drawing with PandaGL and Cairo graphics libraries. It creates a canvas using PandaGL, then creates a Surface based on the canvas for Cairo to draw complex shapes, fills simple shapes with PandaGL, and outputs the results as a PNG image file using Cairo.

```bash
# Build PandaGL
xmake build pandagl

# Package PandaGL
xmake package pandagl

# Build example project
xmake -P .

# Run example project
xmake run -P . -w .
```

Open the output.png file and you'll see something like this:

---

### Sidebars.Json (`docs/sidebars.json`)

{
  "sidebar": [
    {
      "slug": "overview",
      "label": { "en": "Overview", "zh-CN": "概述" },
      "items": [
        { "slug": "quick-start", "label": { "en": "Quick Start", "zh-CN": "快速开始" } },
        { "slug": "about", "label": { "en": "About", "zh-CN": "关于" } }
      ]
    },
    {
      "slug": "handbook",
      "label": { "en": "Handbook", "zh-CN": "手册" },
      "items": [
        { "slug": "styling", "label": { "en": "Styling", "zh-CN": "样式" } },
        { "slug": "customization", "label": { "en": "Customization", "zh-CN": "自定义" } }
      ]
    },
    {
      "slug": "devtools",
      "label": { "en": "Dev Tools", "zh-CN": "开发工具" },
      "items": [
        { "slug": "tsx-and-dev-tools", "label": { "en": "TSX & @lcui/cli", "zh-CN": "TSX 与 @lcui/cli" } },
        { "slug": "css-modules", "label": { "en": "CSS Modules", "zh-CN": "CSS Modules" } },
        { "slug": "tailwind-css", "label": { "en": "Tailwind CSS", "zh-CN": "Tailwind CSS" } },
        { "slug": "sass", "label": { "en": "Sass", "zh-CN": "Sass" } },
        { "slug": "icon-library", "label": { "en": "Icon Library", "zh-CN": "图标库" } }
      ]
    },
    {
      "slug": "widgets",
      "label": { "en": "Widgets", "zh-CN": "组件" },
      "items": [
        { "slug": "anchor", "label": { "en": "Anchor", "zh-CN": "Anchor 锚点" } },
        { "slug": "button", "label": { "en": "Button", "zh-CN": "Button 按钮" } },
        { "slug": "checkbox", "label": { "en": "Checkbox", "zh-CN": "Checkbox 复选框" } },
        { "slug": "field", "label": { "en": "Field", "zh-CN": "Field 表单字段" } },
        { "slug": "label", "label": { "en": "Label", "zh-CN": "Label 标签" } },
        { "slug": "progress", "label": { "en": "Progress", "zh-CN": "Progress 进度条" } },
        { "slug": "radio-group", "label": { "en": "RadioGroup", "zh-CN": "RadioGroup 单选组" } },
        { "slug": "select", "label": { "en": "Select", "zh-CN": "Select 下拉选择" } },
        { "slug": "scrollarea", "label": { "en": "ScrollArea", "zh-CN": "ScrollArea 滚动区域" } },
        { "slug": "text", "label": { "en": "Text", "zh-CN": "Text 文本" } },
        { "slug": "text-input", "label": { "en": "TextInput", "zh-CN": "TextInput 文本输入" } }
      ]
    }
  ]
}

---

### Issues Used Size Pollutes Intrinsic Contribution (`docs/issues/used-size-pollutes-intrinsic-contribution.md`)

# Used size 污染 intrinsic contribution

- 状态：已知问题 / 暂缓
- 严重程度：Medium（中等）。该问题会造成布局无法随内容收缩和出现多余留白，但不会导致崩溃或内存安全问题，且以固定父尺寸为主的普通空间分配通常不受影响。
- 发现日期：2026-07-27

## 现象

在 auto 或 fit-content 父级内放置百分比 flex item，并由固定宽度子元素提供 intrinsic contribution。初始子元素宽度为 `100px` 时，布局结果为：

- group content width：`333.344px`
- item border width：`100.003px`
- child border width：`100px`

将 child 宽度从 `100px` 改为 `50px` 并执行更新后，child 会变为 `50px`，但 group 仍为 `333.344px`，item 仍为 `100.003px`，二者均不收缩。

## 根因

`ui_widget_update_size()` 将 `content_box` 的 used size 写入 `max_content_width` 和 `max_content_height`。后续 fit-content 和 percentage intrinsic 计算会读取这些 `max_content_*` 值，因此上一轮布局得到的 used size 被误当成新的 intrinsic contribution。内容缩小后，历史尺寸继续参与计算，阻止父级和百分比 item 收缩。

## 影响范围

已确认或直接相关的场景包括：

- auto 或 fit-content 父级；
- 百分比 flex item；
- 子内容缩小或移除；
- 局部 style refresh 后重新布局。

以固定父尺寸为主的普通空间分配通常不受影响。Block、flex 以及其他读取 `max_content_*` 的路径也可能受影响，仍需进一步调查。

## 风险

- 容器和 item 无法随内容收缩；
- 页面产生多余留白；
- 最终布局依赖历史 used size，可能因更新顺序不同而不同；
- 该问题不属于崩溃或内存安全风险。

## 当前修复为何不包含此问题

当前 percentage wrap 修复处理百分比 flex item 的 intrinsic 宽度求解、换行和 gap 分配。used size 污染 intrinsic contribution 属于尺寸状态建模和更新生命周期问题，修复需要重新划分 `ui_widget_update_size()` 及其调用方维护的尺寸语义，并审计 block、flex 等共享读取路径。将其并入当前修复会显著扩大范围和回归风险，因此暂缓处理。当前修复不应被视为已经解决此问题。

## 未来修复方向

1. 区分 pure intrinsic contribution 与布局产生的 used size，避免共用 `max_content_width` / `max_content_height` 状态。
2. 审计所有 `max_content_*` 的写入点和读取点，明确每条路径需要 intrinsic size 还是 used size。
3. 保持 load 阶段为纯读取，禁止在 load 阶段触发 child reflow。
4. 使用 TDD 重新添加 child 从 `100px` 缩小到 `50px` 后 group 和 item 同步收缩的回归测试。

## 复现步骤

伪代码：

```c
group = create_fit_content_flex_group();
item = append_percentage_flex_item(group, 30_percent);
child = append_fixed_width_child(item, 100_px);
ui_update();

assert(group->content_box.width == 333.344_px);
assert(item->border_box.width == 100.003_px);

set_width(child, 50_px);
ui_update();

// 当前已知问题：child 已缩至 50px，但以下两个尺寸保持不变。
assert(group->content_box.width == 333.344_px);
assert(item->border_box.width == 100.003_px);
```

可使用 `tests/integration/test_flex_layout_percentage_wrap.c` 中的 `intrinsic percentage flex item` 场景作为初始边界覆盖；重新加入动态收缩断言前，应先完成尺寸语义修复。

## 验收标准

- child 从 `100px` 缩小到 `50px` 后，group 和百分比 item 在同一次正常更新流程中收缩到新的 intrinsic 解；
- item 的 content box 仍能容纳 child；
- 结果不依赖此前布局得到的 used size，也不依赖额外的全树 style refresh；
- 修复不在 load 阶段触发 child reflow；
- percentage wrap、固定父尺寸分配以及 block/flex 相关布局测试全部通过；
- 回归测试采用 TDD 恢复并覆盖内容缩小和移除场景。

## 相关文件

- `tests/integration/test_flex_layout_percentage_wrap.c`
- `tests/fixtures/test_flex_layout_percentage_wrap.xml`
- `tests/fixtures/test_flex_layout_percentage_wrap.css`
- `lib/ui/src/ui_updater.c`
- `lib/ui/src/ui_widget_layout.c`
- `lib/ui/src/ui_flexbox_layout.c`
- `lib/ui/src/ui_block_layout.c`
- `lib/ui/src/ui_resizer.c`

---

### En Devtools Css Modules (`docs/en/devtools/css-modules.mdx`)

# CSS Modules

CSS Modules create locally scoped CSS classes for TSX components, avoiding naming conflicts and improving maintainability.

## Usage

Create a file with the `.module.css` suffix:

```css title="MyComponent.module.css"
.card {
  border: 1px solid #eee;
  border-radius: 4px;
}
```

Import it in a `.tsx` file:

```tsx title="MyComponent.tsx"
import styles from "./MyComponent.module.css";
```

Use the `styles` object instead of string class names in JSX:

```diff
- <Widget className="card" />
+ <Widget className={styles.card} />
```

During compilation, `@lcui/cli` converts `.module.css` into C identifier bindings, automatically generating unique C constant names for class names to avoid global conflicts.

---

### En Devtools Icon Library (`docs/en/devtools/icon-library.mdx`)

# Icon Library

`@lcui/fluent-icons` is an icon library adapted for LCUI. All icons come from Microsoft's [fluentui-system-icons](https://github.com/microsoft/fluentui-system-icons) project.

## Installation

```sh
npm install @lcui/fluent-icons
```

## Choosing icons

Search and select icons on [flicon.io](https://www.flicon.io/). For example, the zoom-in icon is typically named "Zoom In" in English.

fluentui-system-icons icons are available in sizes like 16, 20, and 24, named in the format "icon name + size + style". `@lcui/fluent-icons` uses the naming format "icon name + style", and when the style is Regular it can be omitted.

## Usage

```tsx
import { ZoomIn } from "@lcui/fluent-icons";

<ZoomIn />
```

The default size is 20. If the icon size is fixed and you want better rendering, specify the size parameter:

```tsx
<ZoomIn size={32} />
```

---

### En Devtools Sass (`docs/en/devtools/sass.mdx`)

# Sass

Sass is a popular CSS preprocessor that extends CSS with variables, nesting rules, mixins, and more.

## Usage

`@lcui/cli` has a built-in Sass preprocessor that is automatically invoked when compiling `.sass` and `.scss` files — no additional installation or configuration needed.

Import Sass files directly in TSX:

```tsx title="MyComponent.tsx"
import "./MyComponent.scss";
```

The CLI compiles Sass files into CSS, then converts them to C code for runtime loading.

---

### En Devtools Tailwind Css (`docs/en/devtools/tailwind-css.mdx`)

# Tailwind CSS

Tailwind CSS is a utility-first CSS framework that helps developers quickly apply styles through predefined CSS classes. Compared to traditional CSS, you don't need to create new CSS files, write rules, or think up class names.

## Installation

```sh
npm install -D tailwindcss postcss @thedutchcoder/postcss-rem-to-px
```

## Configuration

Copy the following files from the [lcui-quick-start](https://github.com/lcui-dev/lcui-quick-start) template project to your project root:

- `postcss.config.js`
- `tailwind.config.js`
- `app/global.css`

`global.css` contains the Tailwind directives:

```css title="app/global.css"
@tailwind base;
@tailwind components;
@tailwind utilities;
```

When compiling, `@lcui/cli` processes Tailwind directives through the PostCSS chain (postcss + tailwindcss + postcss-rem-to-px) to generate the final CSS output.

:::tip
If you don't want to place global.css inside the app directory, change the `content` path matching rules in `tailwind.config.js`.
:::

---

### En Devtools Tsx And Dev Tools (`docs/en/devtools/tsx-and-dev-tools.mdx`)

# TSX & Dev Tools

With `@lcui/cli`, you can write declarative UIs using TypeScript with JSX syntax. The CLI compiles TSX into C code, so you don't need to manually write widget tree construction logic.

The benefit is that the declarative approach makes state binding, event binding, and resource imports more concise and intuitive. Handling logic and view in the same file reduces context switching.

However, `@lcui/react` currently has limited capabilities — you can only declare component state, data bindings, and event bindings. For complex operations like conditional rendering or list rendering, you still need to write C code.

## Installing dev tools

`@lcui/cli` is a command-line tool that integrates a TypeScript compiler, Sass preprocessor, resource file loader, and more. It requires a Node.js runtime:

```sh
npm install @lcui/cli
```

## How the preprocessor works

LCUI uses a preprocessor approach: TSX files are only executed during preprocessing and do not become runtime code. You can think of TSX files as configuration files, where the TypeScript code acts as preprocessing directives.

The preprocessor matches the appropriate loader by file extension, parses the TSX code, collects dependencies, executes component functions, and then generates C source files based on the returned JSX elements and Hook call results.

## Usage overview

```tsx title="src/App.tsx"
import { useState, TextInput, Button } from "@lcui/react";

export default function App() {
  const inputRef = { current: { value: "" } };
  const [name, setName] = useState("LCUI");

  return (
    <Widget className="container">
      <Widget className="flex flex-col items-center pt-6">
        <Text className="my-4 text-2xl text-center">Hello, {name}!</Text>
        <TextInput
          $ref={inputRef}
          className="mt-2"
          placeholder="Please input..."
        />
        <Button
          className="mt-2"
          onClick={() => setName(inputRef.current.value)}
        >
          Change
        </Button>
      </Widget>
    </Widget>
  );
}
```

## React library

`@lcui/react` is a UI library tailored for LCUI's features and preprocessor workflow, providing built-in components, utility functions, and hooks.

Installation:

```sh
npm install @lcui/react
```

### Component functions

The preprocessor executes component functions, collects data from `useState`, `useRef`, etc. and the returned JSX elements, then converts them into C code.

:::warning
- Component function return values must be a single JSX element — `<Fragment>`, null, undefined, strings, numbers, or other objects are not supported.
- Declaring and passing component props is not yet supported.
:::

### State management

`useState` declares a state variable for a component:

```tsx
import { useState } from "@lcui/react";

function MyComponent() {
  const [age, setAge] = useState(23);
  const [name, setName] = useState("Taylor");
  // ...
}
```

`useState` returns an array:

- The state variable, initialized to the value passed to `useState`.
- A set function, which lets you change the state variable in response to interactions.

`useState` adds a member to the component's state struct and generates initialization code in the init function:

```c
/* Component state struct */
struct MyComponent_state {
  int age;
  char *name;
};

/* Code in component init function */
_that->state.age = 23;
_that->state.name = strdup2("Taylor");
```

The state's set function inserts C code in the current scope, e.g. `setAge(30)` generates `_that->state.age = 30;`.

:::warning
`useState` parameters can only be string or number types.
:::

### Refs

Use the `$ref` attribute to reference a widget object:

```tsx
<TextInput $ref="input" />
```

Then operate on it in C code:

```c
ui_textinput_set_content(_that->refs.input, "hello");
```

The `$ref` value can also be a reference object returned by `useRef`:

```tsx
import { useRef } from "@lcui/react";

function MyComponent() {
  const inputRef = useRef();

  return <TextInput $ref={inputRef} />;
}
```

`useRef` currently only implements value property read/write binding for TextInput:

```tsx
inputRef.current.value = "World";

<Button onClick={() => setName(inputRef.current.value)}>Click</Button>
```

:::warning
`@lcui/react`'s `useRef` is different from React's `useRef` — it is only for referencing widget objects.
:::

### Responding to events

Declare event handlers using the `on + event name` attribute:

```tsx
<Button onClick="handleClick">Click me</Button>
```

The preprocessor generates C code to bind the event:

```c
ui_widget_on(_that->refs.ref_0, "click", handleClick, w);
```

You can also bind JavaScript functions to events:

```tsx
import { useState, Text, Button } from "@lcui/react";

export default function Counter() {
  const [text, setText] = useState("Click me");

  function handleClick() {
    setText("You clicked");
  }

  return (
    <Button onClick={handleClick}>
      {text}
    </Button>
  );
}
```

The preprocessor generates a C-language version of the event handler based on the code executed inside the handler function.

:::warning
Currently, only state variable set functions can be called inside event handlers. Accessing the event object or executing other statements is not supported.
:::

### Conditional rendering

:::warning
Not yet supported.
We are considering implementing conditional rendering with a `<Show>` component, inspired by Solid.js's `<Show>`.
:::

### Rendering lists

:::warning
Not yet supported.
We are considering implementing array iteration with a `<For>` component, inspired by Solid.js's `<For>`.
:::

---

### En Handbook Customization (`docs/en/handbook/customization.mdx`)

# Customization

You can create entirely new widget types or extend existing ones.

## Creating a custom widget

Use `ui_create_widget_prototype()` to register a new widget type:

```c title="src/counter.c"
#include <LCUI.h>

typedef struct {
        int value;
} counter_data_t;

static ui_widget_prototype_t *counter_proto;

static void counter_init(ui_widget_t *w)
{
        counter_data_t *data;
        ui_widget_t *text;

        data = ui_widget_add_data(w, counter_proto, sizeof(counter_data_t));
        data->value = 0;

        text = ui_create_widget("text");
        ui_text_set_content(text, "0");
        ui_widget_append(w, text);
}

static void counter_destroy(ui_widget_t *w)
{
        /* Release owned resources (if any) */
}

void register_counter_widget(void)
{
        counter_proto = ui_create_widget_prototype("counter", NULL);
        counter_proto->init = counter_init;
        counter_proto->destroy = counter_destroy;
}
```

Use the custom widget:

```c title="src/main.c"
extern void register_counter_widget(void);

int main(void)
{
        ui_widget_t *counter;

        lcui_init();
        register_counter_widget();

        counter = ui_create_widget("counter");
        ui_widget_append(ui_root(), counter);
        return lcui_main();
}
```

## Extending an existing widget

Pass a parent type name as the second argument to `ui_create_widget_prototype()`:

```c title="src/icon_button.c"
static ui_widget_prototype_t *icon_button_proto;

static void icon_button_init(ui_widget_t *w)
{
        /* Call parent (button) init logic */
        icon_button_proto->proto->init(w);
        ui_widget_add_class(w, "icon-button");
}

void register_icon_button(void)
{
        icon_button_proto =
            ui_create_widget_prototype("icon-button", "button");
        icon_button_proto->init = icon_button_init;
}
```

:::warning
**Parent `init` must be called manually.** LCUI does not automatically call the parent type's `init` when creating a subtype widget. If you forget to call `proto->proto->init(w)`, the widget will lack the parent type's base behaviors (e.g. `button` won't register click events or set default styles).
:::

## Widget lifecycle

`ui_widget_prototype_t` has several callback hooks covering each lifecycle stage:

- **`init`** — When the widget is created. Responsible for initializing owned data, child widgets, and event bindings.
- **`destroy`** — When the widget is destroyed. Responsible for releasing owned memory and unbinding events.
- **`update`** — When the widget needs updating, receives a `ui_task_type_t` parameter indicating the update type (style update, property update, etc.). Called by LCUI during each frame's update loop.
- **`setattr`** — When an XML attribute is set (for responding to attribute changes).
- **`settext`** — When text content is set.
- **`sizehint`** — Estimates the widget's natural size constraints (min/max content size) without external constraints. The layout engine uses this when computing child widget sizes.
- **`resize`** — When the widget size changes. Receives the new content area width and height as parameters.
- **`paint`** — When the widget needs to be redrawn. Used for custom drawing logic.

## Custom painting

Override the `paint` callback to draw custom graphics on a widget:

```c title="src/my_widget.c"
static void my_widget_paint(ui_widget_t *w, pd_context_t *paint_ctx,
                              ui_widget_actual_style_t *style)
{
        pd_canvas_t *canvas = paint_ctx->canvas;
        pd_color_t color = pd_color_from_rgb(255, 0, 0);
        pd_rect_t rect = { style->left, style->top, w->width, w->height };

        pd_canvas_fill_rect(canvas, color, rect);
}

static void register_my_widget(void)
{
        ui_widget_prototype_t *proto =
            ui_create_widget_prototype("my-widget", NULL);
        proto->paint = my_widget_paint;
}
```

:::warning
**`paint` is only for drawing.** Widget size estimation is handled by `sizehint`; do not modify widget size or the child widget tree inside `paint`, as it may cause infinite loops.
:::

## Caveats

:::warning
**`destroy` must release owned resources.** If a custom widget allocated memory, opened files, or subscribed to system events (e.g. `lcui_settings_on_deserialize`) in `init`, it must perform symmetric cleanup in `destroy`.
:::

:::warning
**Custom widgets must be registered after `lcui_init()` and before first instantiation.** Calling your `register_xxx()` function right at the start of `main()` is the safest place, ensuring all consumers (XML loading, router instantiation, TSX compilation results) can see the prototype.
:::

---

### En Handbook Styling (`docs/en/handbook/styling.mdx`)

# Styling

Use CSS to set colors, borders, padding, margins, dimensions, and layout for widgets.

## How to set styles

### Inline styles

Use `ui_widget_set_style_string()` to set individual CSS properties directly:

```c title="main.c"
ui_widget_t *w = ui_create_widget("text");

ui_widget_set_style_string(w, "color", "#336699");
ui_widget_set_style_string(w, "font-size", "20px");
ui_widget_set_style_string(w, "padding", "8px 16px");
```

### CSS class selectors

Use `ui_load_css_string()` or `ui_load_css_file()` to load CSS rules, then apply them to widgets with `ui_widget_add_class()`:

```c title="main.c"
ui_load_css_file("styles.css");

ui_widget_t *w = ui_create_widget("text");
ui_widget_add_class(w, "title");
```

```css title="app/styles.css"
.title {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 16px;
}
```

You can also use `ui_load_css_string()` to load CSS rules from a string. The second parameter is a source identifier used for debugging to locate conflicting rules:

```c title="main.c"
ui_load_css_string(".title { font-size: 24px; }", "app.css");
```

## Supported CSS features

LCUI's CSS engine implements a subset of the web standard. This section lists all supported features and their supported values; **anything not listed is not supported by default**.

### At Rules

- **`@font-face`** — Load external fonts

### Selectors

- `*` (universal), `type`, `#id`, `.class`
- Pseudo-classes `:hover`, `:focus`, `:active`, `:first-child`, `:last-child`
- `!important` is not supported

### Units

- `px`, `dp`, `sp`, `pt`, `%`

### Properties

#### Layout

- **`display`** — `none`, `inline-block`, `block`, `flex`, `inline-flex`, `table`, `inline-table`, `table-row`, `table-cell`
- **`position`** — `static`, `relative`, `absolute`
- **`top` / `right` / `bottom` / `left`** — `<length>` or `<percentage>` or `auto`
- **`z-index`** — `auto` or integer
- **`box-sizing`** — `content-box`, `border-box`

#### Box model

- **`width` / `height`** — `<length>`, `<percentage>`, `auto`
- **`min-width` / `max-width` / `min-height` / `max-height`** — same as above
- **`padding`** — shorthand, 1-4 `<length>` values (e.g. `8px`, `4px 8px`, `4px 8px 12px`, `4px 8px 12px 16px`)
- **`padding-top` / `padding-right` / `padding-bottom` / `padding-left`** — longhand properties
- **`margin`** — shorthand, same syntax as padding
- **`margin-top` / `margin-right` / `margin-bottom` / `margin-left`**
- **`border`** — shorthand `1px solid #ccc` (width + style + color)
- **`border-color` / `border-width` / `border-style` / `border-radius`** — multi-value shorthand, same syntax as padding
- **`border-top` / `border-right` / `border-bottom` / `border-left`** — per-side shorthand
- **`border-top-color` / `border-right-color` / `border-bottom-color` / `border-left-color`**
- **`border-top-width` / `border-right-width` / `border-bottom-width` / `border-left-width`**
- **`border-top-style` / `border-right-style` / `border-bottom-style` / `border-left-style`**
- **`border-top-left-radius` / `border-top-right-radius` / `border-bottom-left-radius` / `border-bottom-right-radius`**
- **`border-style` values** — `none`, `solid`
- **`table-layout`** — `auto`, `fixed`
- **`border-spacing`** — `<length>{1,2}`

#### Background

- **`background`** — shorthand `bg-image || bg-position || bg-size || repeat-style || color` (single layer only)
- **`background-color`** — `<color>`
- **`background-image`** — `none` or `<url>`
- **`background-position`** — two values: x y
- **`background-position-x` / `background-position-y`**
- **`background-repeat`** — `<repeat-style>`
- **`background-size`** — `<bg-size>`
- **`background-clip`** — `border-box`, `padding-box`, `content-box`

#### Flexbox layout

- **`flex`** — shorthand (`flex-grow` + `flex-shrink` + `flex-basis`)
- **`flex-shrink` / `flex-grow` / `flex-basis`**
- **`flex-wrap`** — `nowrap`, `wrap`
- **`flex-direction`** — `row`, `column`
- **`justify-content`** — `flex-start`, `center`, `flex-end`
- **`align-items`** — `flex-start`, `center`, `flex-end`, `stretch`
- **`align-content`** — same as justify-content plus `space-between`, `space-around`, `space-evenly`
- **`gap`** — shorthand, sets both row-gap and column-gap
- **`row-gap` / `column-gap`** — `normal` or `<length-percentage>`

#### Typography

- **`font-face`** — (load fonts via `@font-face` rule)
- **`font-family`** — `<font-family>` (recommended to use built-in aliases like `monospace`)
- **`font-size`** — `<length>`
- **`font-style`** — `normal`, `italic`, `oblique`
- **`font-weight`** — `normal`, `bold`, `<number>`
- **`text-align`** — `left`, `center`, `right`
- **`line-height`** — `normal` or `<length>` or `<number>`
- **`color`** — `<color>`
- **`white-space`** — `normal`, `nowrap`
- **`word-break`** — `normal`, `break-all`
- **`content`** — `<string>` or `none`

#### Other

- **`opacity`** — `<number>` or `<percentage>`
- **`visibility`** — `visible`, `hidden`
- **`pointer-events`** — `auto`, `none`
- **`box-shadow`** — `none` or `<shadow>` (format `<length>{2,4} && <color>?`)

## Caveats

:::warning
**`white-space: pre` does not work.** LCUI's `white-space` only implements `normal` and `nowrap`. If you need to preserve leading whitespace from source code, replace spaces with U+00A0 (NBSP).
:::

:::warning
**`overflow` does not clip content.** To clip or scroll child content, use the `scrollarea` built-in widget instead.
:::

:::warning
**`background` shorthand does not support multiple layers.** Writing multi-background syntax like `background: url(a.png) no-repeat, url(b.png) center;` will not work. Use individual properties like `background-image` / `background-position` to set each layer separately.
:::

:::warning
**CSS does not support inheritance.** Properties like `color`, `font-family`, and `font-size` do not cascade from parent to child widgets. Every widget that displays text (e.g. `text`, `button`) must explicitly set these properties.
:::

---

### En Overview About (`docs/en/overview/about.mdx`)

# About LCUI

LCUI is an open-source desktop graphical user interface library written in C, designed to provide C developers with a simple and easy-to-use GUI development experience, while incorporating CSS styling and declarative UI description from web development to lower the learning barrier.

## Key features

- **Cross-platform** — Supports Windows and Linux.
- **Fully self-drawn widgets** — Widgets maintain consistent appearance and behavior across platforms.
- **DPI-adaptive** — Automatically scales the UI on high-resolution screens for crisp display.
- **Built-in CSS engine** — Supports using CSS to define UI styles and layouts, making it easy to pick up for those with web development experience.
- **Modern development tools** — Through the `@lcui/cli` tool, you can use TypeScript with JSX syntax to write user interfaces.

## Who should use LCUI

LCUI is suitable for these developers:

- Want to keep using C on the desktop, but want to escape the tedious Win32 / X11 native development experience.
- Already familiar with web frontend (HTML, CSS) and want to transfer that experience to desktop applications.
- Need to build single-window desktop tools with simple UI content.

If your use case is a large commercial desktop product, a game engine, or a tool deeply integrated with the OS, LCUI may not be the best choice; in such scenarios, consider Qt, GTK, or native APIs instead.

## Architecture

LCUI is divided into four layers from top to bottom:

### Application layer

Your business code: custom widgets, CSS styles, TSX/JSX code, event handling. This is the only part tied to your project domain.

### LCUI Runtime

Initialization, event loop, application lifecycle management. Responsible for running the app, dispatching events, and driving rendering.

### UI Helpers

UI XML parsing, UI Router, cursor management, internationalization (i18n), and other helper modules. These package common UI behaviors into pluggable subsystems.

### Foundation layer

YUtil (general utility library), PandaGL (2D rendering engine), CSS engine, UI widget system, Thread / Worker abstractions. These modules can also be used independently.

The platform layer (Windows / Linux) handles window management and input events.

## License

LCUI is released under the MIT License. See LICENSE.TXT in the repository root for details.

## Contributing

Contributions are welcome! Before submitting a Pull Request, please read CONTRIBUTING.md in the repository root.

- **Bug reports** — Open an issue on GitHub Issues.
- **Feature requests** — Start a discussion on GitHub Discussions.
- **Code contributions** — Fork the repo, create a branch, and submit a PR.

## Community

If you run into issues, you can ask questions on GitHub Discussions (use the `Q&A` label). We also encourage experienced users to help newcomers.

---

### En Overview Quick Start (`docs/en/overview/quick-start.mdx`)

# Quick Start

Get up and running with LCUI in minutes.

## Prerequisites

- **Operating system** — Windows (recommended) or Linux
- **Node.js** — Required to run `@lcui/cli`
- **xmake** — C/C++ build tool
- **Git** — Download and manage source code

## Installation

Install the LCUI CLI globally:

```sh
npm install @lcui/cli
```

Create and run your first app:

```sh
lcui create my-app
cd my-app
lcui build
xmake run app
```

`lcui create` clones a minimal project from the lcui-quick-start template repository, including xmake.lua configuration, example code, and dependencies. Once done, run `lcui build` to compile TSX resources, then `xmake run app` to launch the application.

## Next steps

- Explore the sample project generated by `lcui create` — look at the code and file structure to understand the basics of an LCUI application.
- Read the widget reference (Button, Text, TextInput, Anchor, ScrollArea) to learn about built-in widgets.
- Read the Styling chapter to learn how to apply CSS properties to widgets.
- Read the Customization chapter to learn how to create custom widgets.
- Read the TSX & Dev Tools chapter to understand `@lcui/react` usage and limitations in depth.

## Having trouble?

If you run into problems while learning, you can get help through:

- Ask questions on GitHub Discussions (use the `Q&A` label).
- Check CONTRIBUTING.md in the repository root to learn how to contribute.

---

### En Widgets Anchor (`docs/en/widgets/anchor.mdx`)

# Anchor

A navigation widget similar to the HTML `<a>` element. It can open external URLs in the system browser or load an XML view into a target container widget.

<WidgetExample name="anchor-basic" />

## Use cases

- **Suitable** — placing external links in a page (opens in the system browser).
- **Not suitable** — performing an action (use `button`).

## Usage

```tsx
<a href="https://example.com">Link text</a>
```

## API

### `ui_anchor_open`

```c
void ui_anchor_open(ui_widget_t *w);
```

Programmatically triggers the anchor's action (same as a click). Reads the `href` attribute from the widget:

- If `href` starts with `http://` or `https://` — opens in the system browser.
- If `href` starts with `file:///` — opens the local file in the system browser.
- Otherwise — asynchronously loads an XML file at the given path and injects its content into the widget identified by the `target` attribute.

## XML tag

```xml
<a href="..." target="..." key="...">Link text</a>
```

Attributes:

| Attribute | Required | Description |
|---|---|---|
| `href` | Yes | URL to open, or relative XML file path to load |
| `target` | For view loading | ID of the container widget where the loaded view is injected |
| `key` | No | Arbitrary string passed as `event.data` to the `loaded.anchor` event |

## Events

### `loaded.anchor`

Fired on `ui_root()` after a view has been loaded and injected:

```c
static void on_view_loaded(ui_widget_t *w, ui_event_t *e, void *arg)
{
        /* e->data contains the value of the anchor's "key" attribute */
        printf("Loaded view key: %s\n", (char *)e->data);
}

ui_widget_on(ui_root(), "loaded.anchor", on_view_loaded, NULL);
```

---

### En Widgets Button (`docs/en/widgets/button.mdx`)

# Button

A clickable button widget, typically used to trigger an action.

<WidgetExample name="button-basic" />

## Use cases

- **Suitable**: users click to perform an action (submit a form, open a page, toggle a state)
- **Suitable**: interactive entry points in toolbars, dialogs, and navbars
- **Not suitable**: non-interactive text display (use `text` instead)

## Usage

```tsx
import { Button } from "@lcui/react"
```

```tsx
<Button>Button</Button>
```

## API Reference

<FieldTable name="button" />

---

### En Widgets Checkbox (`docs/en/widgets/checkbox.mdx`)

# Checkbox

A control that allows the user to toggle between checked and not checked.

<WidgetExample name="checkbox-basic" />

## Use cases

- **Suitable**: a single binary choice (accepting terms, toggling a subscription).
- **Suitable**: checkable options inside a form.
- **Not suitable**: mutually exclusive single-choice scenarios (use `radio-group`).

## Usage

```tsx
import { Checkbox } from "@lcui/react"
```

```tsx
<Checkbox />
```

## Caveats

:::caution
**indeterminate is a state, not a default value.** The half-selected state (`indeterminate="true"`) expresses the visual notion that some sub-items are selected (for example, a parent checkbox shown as indeterminate when only some of its children are checked). Clicking a checkbox in the indeterminate state transitions it to the checked state.
:::

## Examples

### Disabled

<WidgetExample name="checkbox-disabled" />

## API Reference

<FieldTable name="checkbox" />

---

### En Widgets Field (`docs/en/widgets/field.mdx`)

# Field

Composes a label, a control, and helper text into an accessible form field.

<WidgetExample name="field-basic" />

## Use cases

- **Use**: as a unified shell for form fields (label + control + description + error)
- **Use**: when you need to place a label and a control side-by-side in a horizontal layout
- **Use**: to group multiple fields into a semantic group (FieldSet + FieldLegend)
- **Don't**: use for single-line inline text (use the `text` widget instead)
- **Don't**: use in places where native HTML `<form>` submission semantics are required (LCUI does not replicate them)

## Usage

```tsx
import { Field, FieldLabel, FieldDescription, FieldSet } from "@lcui/react"
```

```tsx
<Field>
  <FieldLabel htmlFor="username">Username</FieldLabel>
  <TextInput id="username" placeholder="evil_rabbit" />
  <FieldDescription>Choose a unique username.</FieldDescription>
</Field>
```

## Composition

Use the following composition to build a Field:

```
Field
├── FieldLabel
├── TextInput / Checkbox / RadioGroup
└── FieldDescription

FieldSet
├── FieldLegend
├── FieldDescription
└── FieldGroup
    ├── Field
    ├── FieldSeparator
    └── Field
```

## Examples

### Checkbox
<WidgetExample name="field-checkbox" />
### Choice Card
<WidgetExample name="field-choice-card" />
### Fieldset
<WidgetExample name="field-fieldset" />
### Field Group
<WidgetExample name="field-group" />
### Input
<WidgetExample name="field-input" />
### Radio
<WidgetExample name="field-radio" />

## API Reference

### Field
A field container providing orientation control.
<FieldTable name="field" />

### FieldSet
A semantic grouping container.
<FieldTable name="field-set" />

### FieldLegend
The title of a group.
<FieldTable name="field-legend" />

### FieldGroup
A visual stacking container.
<FieldTable name="field-group" />

### FieldLabel
A field label whose clicks are forwarded to the target input.
<FieldTable name="field-label" />

### FieldContent
The text content block within a horizontal field.
<FieldTable name="field-content" />

### FieldTitle
The title text within a FieldContent.
<FieldTable name="field-title" />

### FieldDescription
Helper text for a field.
<FieldTable name="field-description" />

### FieldSeparator
A horizontal divider between field groups.
<FieldTable name="field-separator" />

## Caveats

:::note
**FieldLabel's click forwarding depends on the `for` attribute**. You must set `for="input-id"` on the FieldLabel and assign the same `id` to the target control, otherwise the click will not be forwarded.
:::

---

### En Widgets Label (`docs/en/widgets/label.mdx`)

# Label

Renders an accessible label associated with controls. Click events are forwarded to the target widget referenced by the `for` attribute.

<WidgetExample name="label-basic" />

## Use cases

- **Suitable**: extending the clickable area of interactive widgets such as checkbox and text-input so that clicking the label text also triggers the widget.
- **Suitable**: associating text with a control for accessibility (a11y).
- **Not suitable**: purely decorative text display (use the `text` widget instead).

## Usage

```tsx
import { Label } from "@lcui/react"
```

```tsx
<Label for="agree">I agree</Label>
```

## API Reference

<FieldTable name="label" />

---

### En Widgets Progress (`docs/en/widgets/progress.mdx`)

# Progress

A linear progress bar widget used to indicate the completion of a task such as file uploads or loading states.

<WidgetExample name="progress-basic" />

## Use cases

- **Suitable**: file upload/download, installation, or any long-running task that needs progress feedback
- **Suitable**: form submission or async operations that need a wait indicator
- **Not suitable**: scenarios that require precise numeric values or indeterminate progress (use `text` to render manually)

## Usage

```tsx
import { Progress } from "@lcui/react"
```

```tsx
<Progress value={20} />
```

## API Reference

<FieldTable name="progress" />

---

### En Widgets Radio Group (`docs/en/widgets/radio-group.mdx`)

# RadioGroup

A set of mutually exclusive radio buttons—only one item in the group can be selected at a time.

<WidgetExample name="radio-group-basic" />

## Use cases

- **Suitable**: pick exactly one option from a mutually exclusive set (view density, sort order, single-choice enumerations).
- **Suitable**: simple cases with a fixed 2–7 options.
- **Not suitable**: scenarios that allow multiple concurrent selections (use `checkbox`).
- **Not suitable**: large option lists that need search or filtering (no `select` provided yet).

## Usage

```tsx
import { RadioGroup, RadioGroupItem } from "@lcui/react"
```

```tsx
<RadioGroup value="comfortable">
  <RadioGroupItem value="default" id="r1" />
  <RadioGroupItem value="comfortable" id="r2" />
  <RadioGroupItem value="compact" id="r3" />
</RadioGroup>
```

## Composition

Use the following composition to build a `RadioGroup`:

```
RadioGroup
├── RadioGroupItem
└── RadioGroupItem
```

In practice, each item is paired with a `Label` placed in the same flex row, with the Label's `for` pointing at the RadioGroupItem's `id`—clicking the Label forwards the click event to the matching item.

## Examples

### Disabled

<WidgetExample name="radio-group-disabled" />

## API Reference

### RadioGroup

The container that manages mutually exclusive selection across its items.

<FieldTable name="radio-group" />

### RadioGroupItem

A single selectable option. At most one RadioGroupItem within the same RadioGroup is checked at any time.

<FieldTable name="radio-group-item" />

---

### En Widgets Scrollarea (`docs/en/widgets/scrollarea.mdx`)

# ScrollArea

A container that provides scrollable content when children overflow.

<WidgetExample name="scrollarea-basic" />

## Use cases

- **Suitable** — content height or width may exceed the container (long lists, documents, logs).
- **Suitable** — scrollbars needed for visual feedback.
- **Not suitable** — content always fits within the container (use a plain `widget`).

## Usage

```tsx
import { ScrollArea, ScrollAreaContent, Scrollbar } from "@lcui/react"
```

```tsx
<ScrollArea>
  <ScrollAreaContent>{/* child content */}</ScrollAreaContent>
  <Scrollbar orientation="horizontal" />
  <Scrollbar />
</ScrollArea>
```

## Composition

Use the following composition to build a `ScrollArea`:

```
ScrollArea
├── ScrollAreaContent
└── Scrollbar
```

## API

### `ui_create_scrollarea`

```c
ui_widget_t *ui_create_scrollarea(void);
```

Creates and returns a new scroll area widget.

### `ui_create_scrollarea_content`

```c
ui_widget_t *ui_create_scrollarea_content(void);
```

Creates and returns a new scroll content container to be appended inside a scroll area.

### `ui_scrollarea_set_scroll_top`

```c
void ui_scrollarea_set_scroll_top(ui_widget_t *w, float value);
```

Sets the vertical scroll position in pixels.

### `ui_scrollarea_set_scroll_left`

```c
void ui_scrollarea_set_scroll_left(ui_widget_t *w, float value);
```

Sets the horizontal scroll position in pixels.

### `ui_scrollarea_get_scroll_top`

```c
float ui_scrollarea_get_scroll_top(ui_widget_t *w);
```

Returns the current vertical scroll position.

### `ui_scrollarea_get_scroll_left`

```c
float ui_scrollarea_get_scroll_left(ui_widget_t *w);
```

Returns the current horizontal scroll position.

### `ui_scrollarea_get_scroll_width`

```c
float ui_scrollarea_get_scroll_width(ui_widget_t *w);
```

Returns the total scrollable width of the content.

### `ui_scrollarea_get_scroll_height`

```c
float ui_scrollarea_get_scroll_height(ui_widget_t *w);
```

Returns the total scrollable height of the content.

### `ui_scrollarea_set_wheel_scroll_direction`

```c
void ui_scrollarea_set_wheel_scroll_direction(
    ui_widget_t *w, ui_scrollarea_direction_t direction);
```

Sets which direction the mouse wheel scrolls.

| Value | Description |
|---|---|
| `UI_SCROLLAREA_AUTO` | Vertical if content is taller; horizontal if wider |
| `UI_SCROLLAREA_VERTICAL` | Always scroll vertically |
| `UI_SCROLLAREA_HORIZONTAL` | Always scroll horizontally |

### `ui_scrollarea_update`

```c
void ui_scrollarea_update(ui_widget_t *w);
```

Forces the scroll area to recalculate its layout and scrollbar positions.

## XML tag

```xml
<scrollarea style="width: 300px; height: 200px;">
  
</scrollarea>
```

---

### En Widgets Select (`docs/en/widgets/select.mdx`)

# Select

Select provides an expandable list of options for choosing one value from multiple candidates.

<WidgetExample name="select-basic" />

## Use cases

- **Suitable**: Choosing one value from multiple options
- **Suitable**: Forms with many options where page space should be preserved
- **Not suitable**: Choosing multiple values at once (use `checkbox`)

## Usage

```tsx
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@lcui/react"
```

```tsx
<Select>
  <SelectTrigger>
    <SelectValue placeholder="Choose a theme" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="light">Light</SelectItem>
    <SelectItem value="dark">Dark</SelectItem>
    <SelectItem value="system">System</SelectItem>
  </SelectContent>
</Select>
```

## Composition

Use the following composition to build a `Select`:

```
Select
├── SelectTrigger
│   └── SelectValue
└── SelectContent
    └── SelectItem
```

## API Reference

### Select

The Select state container that manages the current value, placeholder, and content panel.

<FieldTable name="select" />

### SelectTrigger

The trigger that opens or closes the content panel.

<FieldTable name="select-trigger" />

### SelectContent

The option panel mounted at the root level through Portal.

<FieldTable name="select-content" />

### SelectItem

An option representing one selectable value.

<FieldTable name="select-item" />

---

### En Widgets Text Input (`docs/en/widgets/text-input.mdx`)

# TextInput

An editable text input widget. Supports single-line, multiline, password, placeholder, and readonly modes.

<WidgetExample name="text-input-basic" />

## Use cases

- **Suitable** — user text input (form fields, search boxes).
- **Not suitable** — text display only (use `text`).

## Usage

```tsx
import { TextInput } from "@lcui/react"
```

```tsx
<TextInput placeholder="Enter text" />
```

## API

### `ui_textinput_set_text`

```c
int ui_textinput_set_text(ui_widget_t *widget, const char *utf8_str);
```

Sets the input value from a UTF-8 string.

### `ui_textinput_set_text_w`

```c
int ui_textinput_set_text_w(ui_widget_t *widget, const wchar_t *wstr);
```

Sets the input value from a wide character string.

### `ui_textinput_get_text_w`

```c
size_t ui_textinput_get_text_w(ui_widget_t *w, size_t start,
                               size_t max_len, wchar_t *buf);
```

Reads the current input value. Returns the number of characters written.

### `ui_textinput_get_text_length`

```c
size_t ui_textinput_get_text_length(ui_widget_t *w);
```

Returns the current text length in characters.

### `ui_textinput_clear_text`

```c
void ui_textinput_clear_text(ui_widget_t *widget);
```

Clears all text from the input.

### `ui_textinput_set_placeholder`

```c
int ui_textinput_set_placeholder(ui_widget_t *w, const char *str);
```

Sets the placeholder text shown when the input is empty.

### `ui_textinput_set_placeholder_w`

```c
int ui_textinput_set_placeholder_w(ui_widget_t *w, const wchar_t *wstr);
```

Sets the placeholder text from a wide character string.

### `ui_textinput_set_password_char`

```c
void ui_textinput_set_password_char(ui_widget_t *w, wchar_t ch);
```

Masks the input with the given character (e.g. `L'*'` for password fields).

### `ui_textinput_enable_multiline`

```c
void ui_textinput_enable_multiline(ui_widget_t *widget, bool enable);
```

Enables or disables multiline input mode.

### `ui_textinput_enable_style_tag`

```c
void ui_textinput_enable_style_tag(ui_widget_t *widget, bool enable);
```

Enables or disables inline style tag parsing in the input.

### `ui_textinput_append_text_w`

```c
int ui_textinput_append_text_w(ui_widget_t *widget, const wchar_t *wstr);
```

Appends text at the end of the current content.

### `ui_textinput_insert_text_w`

```c
int ui_textinput_insert_text_w(ui_widget_t *widget, const wchar_t *wstr);
```

Inserts text at the current caret position.

### `ui_textinput_set_caret_blink`

```c
void ui_textinput_set_caret_blink(ui_widget_t *w, bool visible, int time);
```

Controls the caret blink animation. `time` is the blink interval in milliseconds.

## XML tag

```xml
<textedit placeholder="..." style="width: 200px;" />
```

Attributes:

| Attribute | Description |
|---|---|
| `placeholder` | Placeholder text |
| `multiline` | `"true"` for multiline mode |
| `readonly` | `"true"` to make the input read-only |
| `type` | `"password"` to mask input |

---

### En Widgets Text (`docs/en/widgets/text.mdx`)

# Text

A widget for displaying text. Supports single-line and multiline modes, inline style tags, and CSS styling.

<WidgetExample name="text-basic" />

## Use cases

- **Suitable** — static text display (titles, labels, descriptions).
- **Not suitable** — editable text input (use `textinput`).

## Usage

```tsx
import { Text } from "@lcui/react"
```

```tsx
<Text>Hello</Text>
```

## API

### `ui_text_set_content`

```c
int ui_text_set_content(ui_widget_t *w, const char *utf8_text);
```

Sets the text content from a UTF-8 string. Supports inline style tags.

### `ui_text_set_content_w`

```c
int ui_text_set_content_w(ui_widget_t *w, const wchar_t *text);
```

Sets the text content from a wide character string.

### `ui_text_get_content_w`

```c
size_t ui_text_get_content_w(ui_widget_t *w, wchar_t *buf, size_t size);
```

Reads the current text content into `buf` (up to `size` wide characters). Returns the number of characters written.

### `ui_text_set_multiline`

```c
void ui_text_set_multiline(ui_widget_t *w, bool enable);
```

Enables or disables multiline mode. When enabled, `\n` characters create new lines.

## XML tag

```xml
<text>Text content here</text>
```

Attributes:

| Attribute | Description |
|---|---|
| `multiline` | Set to `"true"` to enable multiline mode |

## Inline style tags

The text widget supports a BBCode-like inline styling syntax:

| Tag | Example | Effect |
|---|---|---|
| `[color=X]` | `[color=#ff0000]Red[/color]` | Text color |
| `[b]` | `[b]Bold[/b]` | Bold font |
| `[i]` | `[i]Italic[/i]` | Italic font |
| `[size=X]` | `[size=20]Large[/size]` | Font size in px |

---

### Zh CN Devtools Css Modules (`docs/zh-CN/devtools/css-modules.mdx`)

# CSS Modules

CSS Modules 为 TSX 组件创建局部作用域的 CSS 类，避免命名冲突并提高可维护性。

## 用法

创建 `.module.css` 后缀的文件：

```css title="MyComponent.module.css"
.card {
  border: 1px solid #eee;
  border-radius: 4px;
}
```

在 `.tsx` 文件中导入：

```tsx title="MyComponent.tsx"
import styles from "./MyComponent.module.css";
```

在 JSX 中用 `styles` 对象替代字符串类名：

```diff
- <Widget className="card" />
+ <Widget className={styles.card} />
```

`@lcui/cli` 编译时会将 `.module.css` 转换为 C 标识符绑定，类名会自动生成唯一的 C 常量名，避免全局冲突。

---

### Zh CN Devtools Icon Library (`docs/zh-CN/devtools/icon-library.mdx`)

# 图标库

`@lcui/fluent-icons` 是专为 LCUI 适配的图标库，图标都来自 Microsoft 的 [fluentui-system-icons](https://github.com/microsoft/fluentui-system-icons) 项目。

## 安装

```sh
npm install @lcui/fluent-icons
```

## 选取图标

在 [flicon.io](https://www.flicon.io/) 网站中搜索和选取图标。以放大图标为例，英文名通常是 Zoom In。

fluentui-system-icons 的图标有 16、20、24 等几种尺寸可选，命名方式是"图标名+尺寸+风格"。`@lcui/fluent-icons` 的命名方式是"图标名+风格"，当风格为 Regular 时可以省略它。

## 用法

```tsx
import { ZoomIn } from "@lcui/fluent-icons";

<ZoomIn />
```

默认尺寸是 20。如果图标尺寸固定且希望更好的渲染效果，可以指定 size 参数：

```tsx
<ZoomIn size={32} />
```

---

### Zh CN Devtools Sass (`docs/zh-CN/devtools/sass.mdx`)

# Sass

Sass 是一个流行的 CSS 预处理器，通过变量、嵌套规则和混合元素等功能扩展 CSS。

## 用法

`@lcui/cli` 已内置 Sass 预处理器，在编译 `.sass` 和 `.scss` 后缀的文件时会自动调用，无需额外安装或配置。

在 TSX 中直接导入 Sass 文件：

```tsx title="MyComponent.tsx"
import "./MyComponent.scss";
```

CLI 会将 Sass 文件编译为 CSS，再转换为 C 代码在运行时加载。

---

### Zh CN Devtools Tailwind Css (`docs/zh-CN/devtools/tailwind-css.mdx`)

# Tailwind CSS

Tailwind CSS 是一个功能类优先（Utility-First）的 CSS 框架，通过预定义的 CSS 类帮助开发者快速设置样式。相比传统 CSS 编写方式，无需新建 CSS 文件、编写规则和思考类名。

## 安装

```sh
npm install -D tailwindcss postcss @thedutchcoder/postcss-rem-to-px
```

## 配置

从 [lcui-quick-start](https://github.com/lcui-dev/lcui-quick-start) 模板项目复制以下文件到项目根目录：

- `postcss.config.js`
- `tailwind.config.js`
- `app/global.css`

`global.css` 中包含 Tailwind 的指令：

```css title="app/global.css"
@tailwind base;
@tailwind components;
@tailwind utilities;
```

`@lcui/cli` 编译时会通过 PostCSS 链（postcss + tailwindcss + postcss-rem-to-px）处理 Tailwind 指令，生成最终的 CSS 输出。

:::tip
如果你不想将 global.css 放到 app 目录内，请更改 `tailwind.config.js` 中 `content` 配置项的路径匹配规则。
:::

---

### Zh CN Devtools Tsx And Dev Tools (`docs/zh-CN/devtools/tsx-and-dev-tools.mdx`)

# TSX 与开发工具

配合 `@lcui/cli`，你可以用 TypeScript 搭配 JSX 语法编写声明式界面。CLI 会编译 TSX 为 C 代码，你无需手动编写部件树构建逻辑。

这样做的好处是：声明式编程方式使得状态绑定、事件绑定和资源引入更加简洁直观，在同一份文件中处理逻辑和视图可以减少上下文切换。

不过，`@lcui/react` 目前功能有限，你只能声明组件的状态、数据绑定和事件绑定。对于条件渲染、列表渲染等复杂操作，你仍需要编写 C 代码。

## 安装开发工具

`@lcui/cli` 是一个命令行工具，集成了 TypeScript 编译器、Sass 预处理器、资源文件加载器等功能。它依赖 Node.js 运行时环境：

```sh
npm install @lcui/cli
```

## 预处理器工作原理

LCUI 采用预处理器方案：TSX 文件只在预处理阶段执行，不会成为运行时代码。你可以理解为 TSX 文件是配置文件，其中的 TypeScript 代码都是预处理指令。

预处理器按文件后缀名匹配合适的加载器，解析 TSX 代码、收集依赖、执行组件函数，然后根据返回的 JSX 元素和 Hook 调用结果生成 C 源文件。

## 用法概览

```tsx title="src/App.tsx"
import { useState, TextInput, Button } from "@lcui/react";

export default function App() {
  const inputRef = { current: { value: "" } };
  const [name, setName] = useState("LCUI");

  return (
    <Widget className="container">
      <Widget className="flex flex-col items-center pt-6">
        <Text className="my-4 text-2xl text-center">Hello, {name}!</Text>
        <TextInput
          $ref={inputRef}
          className="mt-2"
          placeholder="Please input..."
        />
        <Button
          className="mt-2"
          onClick={() => setName(inputRef.current.value)}
        >
          Change
        </Button>
      </Widget>
    </Widget>
  );
}
```

## React 库

`@lcui/react` 是针对 LCUI 特性和预处理器工作模式的用户界面库，提供预置组件、工具函数和 Hook 函数。

安装方法：

```sh
npm install @lcui/react
```

### 组件函数

预处理器会执行组件函数，收集 `useState`、`useRef` 等产出的数据和返回的 JSX 元素，然后转换成 C 代码。

:::warning
- 组件函数返回值必须是一个 JSX 元素，不能是 `<Fragment>`、null、undefined、字符串、数字等对象。
- 暂不支持声明和传递组件 props 参数。
:::

### 状态管理

`useState` 为组件声明状态变量：

```tsx
import { useState } from "@lcui/react";

function MyComponent() {
  const [age, setAge] = useState(23);
  const [name, setName] = useState("Taylor");
  // ...
}
```

`useState` 返回一个数组：

- 状态变量，初始值为你传给 `useState` 的值。
- set 函数，允许你在响应交互时更改状态变量。

`useState` 会为组件的状态结构体添加成员，并在初始化函数中添加初始化代码：

```c
/* 组件状态结构体 */
struct MyComponent_state {
  int age;
  char *name;
};

/* 组件初始化函数中的代码 */
_that->state.age = 23;
_that->state.name = strdup2("Taylor");
```

状态的 set 函数会在当前作用域中插入 C 代码，例如 `setAge(30)` 会生成 `_that->state.age = 30;`。

:::warning
`useState` 的参数只能是 string、number 类型。
:::

### 引用

用 `$ref` 属性引用部件对象：

```tsx
<TextInput $ref="input" />
```

之后在 C 代码中操作它：

```c
ui_textinput_set_content(_that->refs.input, "hello");
```

`$ref` 的值也可以是 `useRef` 返回的引用对象：

```tsx
import { useRef } from "@lcui/react";

function MyComponent() {
  const inputRef = useRef();

  return <TextInput $ref={inputRef} />;
}
```

`useRef` 目前只实现了 TextInput 的 value 属性读写绑定：

```tsx
inputRef.current.value = "World";

<Button onClick={() => setName(inputRef.current.value)}>Click</Button>
```

:::warning
`@lcui/react` 的 `useRef` 和 React 的 `useRef` 不同，仅用于引用部件对象。
:::

### 响应事件

通过 `on + 事件名` 属性声明事件处理函数：

```tsx
<Button onClick="handleClick">点我</Button>
```

预处理器会生成 C 代码绑定事件：

```c
ui_widget_on(_that->refs.ref_0, "click", handleClick, w);
```

也可以将 JavaScript 函数与事件绑定：

```tsx
import { useState, Text, Button } from "@lcui/react";

export default function Counter() {
  const [text, setText] = useState("点我");

  function handleClick() {
    setText("你已点击");
  }

  return (
    <Button onClick={handleClick}>
      {text}
    </Button>
  );
}
```

预处理器会根据事件处理函数内部的代码执行结果，为其生成 C 语言版本的事件处理函数。

:::warning
暂时只支持在事件处理函数中执行状态变量的 set 函数，不支持访问事件对象，不支持执行其它语句。
:::

### 条件渲染

:::warning
暂不支持。
我们正考虑使用 `<Show>` 组件实现条件渲染，参考 Solid.js 的 `<Show>`。
:::

### 渲染列表

:::warning
暂不支持。
我们正考虑使用 `<For>` 组件实现数组遍历，参考 Solid.js 的 `<For>`。
:::

---

### Zh CN Handbook Customization (`docs/zh-CN/handbook/customization.mdx`)

# 自定义

你可以创建全新的部件类型，也可以在现有部件基础上进行扩展。

## 创建自定义部件

使用 `ui_create_widget_prototype()` 注册新的部件类型：

```c title="src/counter.c"
#include <LCUI.h>

typedef struct {
        int value;
} counter_data_t;

static ui_widget_prototype_t *counter_proto;

static void counter_init(ui_widget_t *w)
{
        counter_data_t *data;
        ui_widget_t *text;

        data = ui_widget_add_data(w, counter_proto, sizeof(counter_data_t));
        data->value = 0;

        text = ui_create_widget("text");
        ui_text_set_content(text, "0");
        ui_widget_append(w, text);
}

static void counter_destroy(ui_widget_t *w)
{
        /* 释放自有资源（如有） */
}

void register_counter_widget(void)
{
        counter_proto = ui_create_widget_prototype("counter", NULL);
        counter_proto->init = counter_init;
        counter_proto->destroy = counter_destroy;
}
```

使用这个自定义部件：

```c title="src/main.c"
extern void register_counter_widget(void);

int main(void)
{
        ui_widget_t *counter;

        lcui_init();
        register_counter_widget();

        counter = ui_create_widget("counter");
        ui_widget_append(ui_root(), counter);
        return lcui_main();
}
```

## 扩展现有部件

把父类型名作为 `ui_create_widget_prototype()` 的第二个参数传入：

```c title="src/icon_button.c"
static ui_widget_prototype_t *icon_button_proto;

static void icon_button_init(ui_widget_t *w)
{
        /* 调用父类（button）的初始化逻辑 */
        icon_button_proto->proto->init(w);
        ui_widget_add_class(w, "icon-button");
}

void register_icon_button(void)
{
        icon_button_proto =
            ui_create_widget_prototype("icon-button", "button");
        icon_button_proto->init = icon_button_init;
}
```

:::warning
**父类的 `init` 必须手动调用。** LCUI 在创建子类型部件时不会自动调用父类型的 `init`。如果你忘记调用 `proto->proto->init(w)`，部件会缺少父类型的基础行为（例如 `button` 不会注册点击事件、不会设置默认样式）。
:::

## 部件生命周期

`ui_widget_prototype_t` 上有多个回调钩子，覆盖部件的各个生命周期阶段：

- **`init`** — 部件创建时。负责初始化自有数据、子部件、事件绑定。
- **`destroy`** — 部件销毁时。负责释放自有内存、解绑事件。
- **`update`** — 部件需要更新时，接收 `ui_task_type_t` 参数标识更新类型（样式更新、属性更新等）。LCUI 内部在每帧更新循环中调用此钩子。
- **`setattr`** — 设置 XML 属性时（用于响应属性变更）。
- **`settext`** — 设置文本内容时。
- **`sizehint`** — 估算部件在无外部约束时的自然尺寸约束（最小/最大内容尺寸）。布局引擎在计算子部件尺寸时会参考此结果。
- **`resize`** — 部件尺寸变化时。接收新的内容区域宽高作为参数。
- **`paint`** — 部件需要重绘时。用于自定义绘制逻辑。

## 自定义绘制

可以重写 `paint` 回调，在部件上绘制自定义图形：

```c title="src/my_widget.c"
static void my_widget_paint(ui_widget_t *w, pd_context_t *paint_ctx,
                              ui_widget_actual_style_t *style)
{
        pd_canvas_t *canvas = paint_ctx->canvas;
        pd_color_t color = pd_color_from_rgb(255, 0, 0);
        pd_rect_t rect = { style->left, style->top, w->width, w->height };

        pd_canvas_fill_rect(canvas, color, rect);
}

static void register_my_widget(void)
{
        ui_widget_prototype_t *proto =
            ui_create_widget_prototype("my-widget", NULL);
        proto->paint = my_widget_paint;
}
```

:::warning
**`paint` 只负责绘制。** 部件尺寸估算由 `sizehint` 处理；不要在 `paint` 里修改部件尺寸或子部件树，否则可能触发无限循环。
:::

## 注意事项

:::warning
**`destroy` 回调要释放自有资源。** 如果自定义部件在 `init` 里分配了内存、打开了文件、订阅了系统事件（如 `lcui_settings_on_deserialize`），必须在 `destroy` 里做对称释放。
:::

:::warning
**自定义部件必须在 `lcui_init()` 之后、首次实例化之前注册。** 在 `main()` 开头立即调用你的 `register_xxx()` 函数是最稳妥的位置，可以确保所有使用方（XML 加载、路由实例化、TSX 编译结果）都能看到原型。
:::

---

### Zh CN Handbook Styling (`docs/zh-CN/handbook/styling.mdx`)

# 样式

用 CSS 给部件设置颜色、边框、内外边距、尺寸和布局。

## 设置方式

### 内联样式

用 `ui_widget_set_style_string()` 直接设置单个 CSS 属性：

```c title="main.c"
ui_widget_t *w = ui_create_widget("text");

ui_widget_set_style_string(w, "color", "#336699");
ui_widget_set_style_string(w, "font-size", "20px");
ui_widget_set_style_string(w, "padding", "8px 16px");
```

### CSS 类选择器

用 `ui_load_css_string()` 或 `ui_load_css_file()` 加载 CSS 规则，再用 `ui_widget_add_class()` 给部件加类名使其生效：

```c title="main.c"
ui_load_css_file("styles.css");

ui_widget_t *w = ui_create_widget("text");
ui_widget_add_class(w, "title");
```

```css title="app/styles.css"
.title {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 16px;
}
```

也可以用 `ui_load_css_string()` 从字符串加载 CSS 规则，第二个参数是来源标识，用于调试定位冲突规则：

```c title="main.c"
ui_load_css_string(".title { font-size: 24px; }", "app.css");
```

## 支持的 CSS 特性

LCUI 的 CSS 引擎实现了 Web 标准的一个子集。本节列出所有已支持的特性和它们支持的值；**未列出的特性默认不支持**。

### At Rules

- **`@font-face`** — 加载外部字体

### 选择器

- `*`（通配符）、`type`、`#id`、`.class`
- 伪类 `:hover`、`:focus`、`:active`、`:first-child`、`:last-child`
- 不支持 `!important`

### 单位

- `px`、`dp`、`sp`、`pt`、`%`

### 属性

#### 布局

- **`display`** — `none`、`inline-block`、`block`、`flex`、`inline-flex`、`table`、`inline-table`、`table-row`、`table-cell`
- **`position`** — `static`、`relative`、`absolute`
- **`top` / `right` / `bottom` / `left`** — `<length>` 或 `<percentage>` 或 `auto`
- **`z-index`** — `auto` 或整数
- **`box-sizing`** — `content-box`、`border-box`

#### 盒模型

- **`width` / `height`** — `<length>`、`<percentage>`、`auto`
- **`min-width` / `max-width` / `min-height` / `max-height`** — 同上
- **`padding`** — 简写，1-4 个 `<length>` 值（如 `8px`、`4px 8px`、`4px 8px 12px`、`4px 8px 12px 16px`）
- **`padding-top` / `padding-right` / `padding-bottom` / `padding-left`** — 长边属性
- **`margin`** — 简写，同 padding
- **`margin-top` / `margin-right` / `margin-bottom` / `margin-left`**
- **`border`** — 简写 `1px solid #ccc`（width + style + color）
- **`border-color` / `border-width` / `border-style` / `border-radius`** — 同 padding 语法的多值简写
- **`border-top` / `border-right` / `border-bottom` / `border-left`** — 单边简写
- **`border-top-color` / `border-right-color` / `border-bottom-color` / `border-left-color`**
- **`border-top-width` / `border-right-width` / `border-bottom-width` / `border-left-width`**
- **`border-top-style` / `border-right-style` / `border-bottom-style` / `border-left-style`**
- **`border-top-left-radius` / `border-top-right-radius` / `border-bottom-left-radius` / `border-bottom-right-radius`**
- **`border-style` 可取值** — `none`、`solid`
- **`table-layout`** — `auto`、`fixed`
- **`border-spacing`** — `<length>{1,2}`

#### 背景

- **`background`** — 简写形式 `bg-image || bg-position || bg-size || repeat-style || color`（仅单图层）
- **`background-color`** — `<color>`
- **`background-image`** — `none` 或 `<url>`
- **`background-position`** — x y 两个值
- **`background-position-x` / `background-position-y`**
- **`background-repeat`** — `<repeat-style>`
- **`background-size`** — `<bg-size>`
- **`background-clip`** — `border-box`、`padding-box`、`content-box`

#### Flexbox 布局

- **`flex`** — 简写（`flex-grow` + `flex-shrink` + `flex-basis`）
- **`flex-shrink` / `flex-grow` / `flex-basis`**
- **`flex-wrap`** — `nowrap`、`wrap`
- **`flex-direction`** — `row`、`column`
- **`justify-content`** — `flex-start`、`center`、`flex-end`
- **`align-items`** — `flex-start`、`center`、`flex-end`、`stretch`
- **`align-content`** — 同 justify-content 加 `space-between`、`space-around`、`space-evenly`
- **`gap`** — 简写，同时设 row-gap + column-gap
- **`row-gap` / `column-gap`** — `normal` 或 `<length-percentage>`

#### 排版

- **`font-face`** — （通过 `@font-face` 规则加载字体）
- **`font-family`** — `<font-family>`（建议用内置别名如 `monospace`）
- **`font-size`** — `<length>`
- **`font-style`** — `normal`、`italic`、`oblique`
- **`font-weight`** — `normal`、`bold`、`<number>`
- **`text-align`** — `left`、`center`、`right`
- **`line-height`** — `normal` 或 `<length>` 或 `<number>`
- **`color`** — `<color>`
- **`white-space`** — `normal`、`nowrap`
- **`word-break`** — `normal`、`break-all`
- **`content`** — `<string>` 或 `none`

#### 其他

- **`opacity`** — `<number>` 或 `<percentage>`
- **`visibility`** — `visible`、`hidden`
- **`pointer-events`** — `auto`、`none`
- **`box-shadow`** — `none` 或 `<shadow>`（格式 `<length>{2,4} && <color>?`）

## 注意事项

:::warning
**`white-space: pre` 无效。** LCUI 的 `white-space` 仅实现 `normal` 和 `nowrap`。如需保留源代码前导缩进，把空格换成 U+00A0 (NBSP)。
:::

:::warning
**`overflow` 不裁切内容。** 要裁切或滚动子内容，改用 `scrollarea` 内置部件。
:::

:::warning
**`background` 简写不支持多图层。** 写 `background: url(a.png) no-repeat, url(b.png) center;` 这种多背景语法不会生效。请拆成 `background-image` / `background-position` 等分属性逐个设置。
:::

:::warning
**CSS 不支持继承。** 像 `color`、`font-family`、`font-size` 不会从父部件流向子部件。每个 `text` / `button` 等需要文本显示的部件都必须显式设置这些属性。
:::

---

### Zh CN Overview About (`docs/zh-CN/overview/about.mdx`)

# 关于 LCUI

LCUI 是一个用 C 语言编写的开源桌面图形界面库，旨在为 C 开发者提供简洁易用的 GUI 开发体验，同时融入 CSS 样式、声明式界面描述等 Web 开发技术降低学习门槛。

## 主要特性

- **跨平台** — 支持 Windows 和 Linux。
- **全自绘组件** — 组件在多个平台中都能保持一致的外观和行为。
- **DPI 自适应** — 自动在高分辨率屏幕上缩放 UI，保持清晰显示。
- **自带 CSS 引擎** — 支持使用 CSS 来定义用户界面的样式和布局，对于有网页开发经验的人比较容易上手。
- **提供现代化的开发工具** — 通过 `@lcui/cli` 工具，允许你使用 TypeScript 语言搭配 JSX 语法来编写用户界面。

## 适合谁使用

LCUI 适合这些开发者：

- 想在桌面端继续使用 C 语言，但希望摆脱繁琐的 Win32 / X11 原生开发体验。
- 已经熟悉 Web 前端（HTML、CSS），想把这套经验迁移到桌面应用。
- 需要构建单窗口、界面内容简单的桌面小工具。

如果场景是大型商业桌面产品、游戏引擎或与操作系统深度集成的工具，LCUI 可能不是最合适的选择；这种场景下建议参考 Qt、GTK 或原生 API。

## 架构

LCUI 从上到下分为四层：

### 应用层

你的业务代码：自定义组件、CSS 样式、TSX/JSX 代码、事件处理。这是唯一与你的项目领域相关的部分。

### LCUI 运行时

初始化、事件循环、应用生命周期管理。负责把应用跑起、派发事件、驱动渲染。

### UI 辅助层

UI XML 解析、UI Router 路由、光标管理、国际化（i18n）等辅助模块。把常用 UI 行为封装成可插拔的子系统。

### 基础设施层

YUtil（通用工具库）、PandaGL（2D 渲染引擎）、CSS 引擎、UI 部件系统、Thread / Worker 抽象。这些模块也可以单独使用。

平台层（Windows / Linux）负责窗口管理与输入事件。

## 许可证

LCUI 基于 MIT License 发布。详情请查看仓库根目录的 LICENSE.TXT。

## 如何参与贡献

欢迎贡献！在提交 Pull Request 之前，请先阅读仓库根目录的 CONTRIBUTING.md。

- **Bug 反馈** — 在 GitHub Issues 提交问题。
- **功能建议** — 在 GitHub Discussions 发起讨论。
- **代码贡献** — Fork 仓库，创建分支，然后提交 PR。

## 社区

遇到使用问题时，可以通过 GitHub Discussions 提问（建议使用 `Q&A` 标签）。同时我们也鼓励资深用户给新人提供帮助。

---

### Zh CN Overview Quick Start (`docs/zh-CN/overview/quick-start.mdx`)

# 快速开始

几分钟内上手 LCUI。

## 环境要求

- **操作系统** — Windows（推荐）或 Linux
- **Node.js** — 运行 `@lcui/cli` 工具
- **xmake** — C/C++ 构建工具
- **Git** — 下载和管理源码

## 安装

全局安装 LCUI CLI：

```sh
npm install @lcui/cli
```

创建并运行你的第一个应用：

```sh
lcui create my-app
cd my-app
lcui build
xmake run app
```

`lcui create` 会从 lcui-quick-start 模板仓库克隆一个最小项目，包含 xmake.lua 配置、示例代码和依赖。完成后运行 `lcui build` 编译 TSX 资源，再运行 `xmake run app` 启动应用。

## 下一步

- 查看样板项目（`lcui create` 生成的项目）中的代码和文件结构，了解 LCUI 应用的基本用法。
- 阅读组件参考（Button、Text、TextInput、Anchor、ScrollArea），了解内置部件。
- 阅读样式章节，学习如何用 CSS 为部件添加外观。
- 阅读自定义章节，学习如何创建自定义部件。
- 阅读 TSX 与开发工具章节，深入理解 `@lcui/react` 的用法和限制。

## 遇到问题？

如果你在学习过程中遇到问题，可以通过以下途径获取帮助：

- 在 GitHub Discussions 提问（建议使用 `Q&A` 标签）。
- 在仓库根目录查看 CONTRIBUTING.md，了解如何参与贡献。

---

### Zh CN Widgets Anchor (`docs/zh-CN/widgets/anchor.mdx`)

# Anchor

链接部件，用法与 HTML 的 `<a>` 标签相同，用于打开外部 URL。

<WidgetExample name="anchor-basic" />

## 适用场景

- **适用** — 在页面中放置外部链接（点击后在系统浏览器中打开）。
- **不适用** — 需要执行动作的按钮（用 `button`）。

## 用法

```tsx
<a href="https://example.com">链接</a>
```

## API 参考

<FieldTable name="anchor" />

---

### Zh CN Widgets Button (`docs/zh-CN/widgets/button.mdx`)

# Button

可点击的按钮部件，通常用于触发某个操作。

<WidgetExample name="button-basic" />

## 适用场景

- **适用**：用户点击执行动作（提交表单、打开页面、切换状态）
- **适用**：工具栏、对话框、导航栏中的交互入口
- **不适用**：不需要交互的纯文本展示（用 `text`）

## 用法

```tsx
import { Button } from "@lcui/react"
```

```tsx
<Button>Button</Button>
```

## API 参考

<FieldTable name="button" />

---

### Zh CN Widgets Checkbox (`docs/zh-CN/widgets/checkbox.mdx`)

# Checkbox

允许用户在已选和未选之间切换的控件。

<WidgetExample name="checkbox-basic" />

## 适用场景

- **适用**：单条二元选择（同意条款、订阅开关）
- **适用**：表单中的勾选项
- **不适用**：互斥的多选一场景（用 `radio-group`）

## 用法

```tsx
import { Checkbox } from "@lcui/react"
```

```tsx
<Checkbox />
```

## 注意事项

:::caution
**indeterminate 是状态，不是默认值**。半选态（`indeterminate="true"`）用于表达"子项部分被选中"的视觉状态（例如父级 checkbox 在部分子项被选时显示半选）。点击 indeterminate 状态的 checkbox 会转为 checked 状态。
:::

## 示例

### 禁用

<WidgetExample name="checkbox-disabled" />

## API 参考

<FieldTable name="checkbox" />

---

### Zh CN Widgets Field (`docs/zh-CN/widgets/field.mdx`)

# Field

组合 label、控件和说明文字，构成可访问的表单字段。

<WidgetExample name="field-basic" />

## 适用场景

- **适用**：表单字段的统一外壳（label + 控件 + 描述 + 错误信息）
- **适用**：需要在横向布局里把 label 和控件并排
- **适用**：把多个字段组成语义分组（FieldSet + FieldLegend）
- **不适用**：单行 inline 文本（用 text widget）
- **不适用**：要求原生 HTML `<form>` 提交语义的场景（LCUI 没复刻）

## 用法

```tsx
import { Field, FieldLabel, FieldDescription, FieldSet } from "@lcui/react"
```

```tsx
<Field>
  <FieldLabel htmlFor="username">用户名</FieldLabel>
  <TextInput id="username" placeholder="evil_rabbit" />
  <FieldDescription>选择一个唯一的用户名。</FieldDescription>
</Field>
```

## 组合

使用以下组合来构建 Field：

```
Field
├── FieldLabel
├── TextInput / Checkbox / RadioGroup
└── FieldDescription

FieldSet
├── FieldLegend
├── FieldDescription
└── FieldGroup
    ├── Field
    ├── FieldSeparator
    └── Field
```

## 示例

### Checkbox
<WidgetExample name="field-checkbox" />
### Choice Card
<WidgetExample name="field-choice-card" />
### Fieldset
<WidgetExample name="field-fieldset" />
### Field Group
<WidgetExample name="field-group" />
### Input
<WidgetExample name="field-input" />
### Radio
<WidgetExample name="field-radio" />

## API 参考

### Field
字段容器，提供方向控制。
<FieldTable name="field" />

### FieldSet
语义分组容器。
<FieldTable name="field-set" />

### FieldLegend
分组标题。
<FieldTable name="field-legend" />

### FieldGroup
视觉堆叠容器。
<FieldTable name="field-group" />

### FieldLabel
字段标签，点击转发到目标 input。
<FieldTable name="field-label" />

### FieldContent
横向字段中的文本内容块。
<FieldTable name="field-content" />

### FieldTitle
FieldContent 内的标题文本。
<FieldTable name="field-title" />

### FieldDescription
字段辅助说明。
<FieldTable name="field-description" />

### FieldSeparator
字段组之间的分隔线。
<FieldTable name="field-separator" />

## 注意事项

:::note
**FieldLabel 的 click forwarding 依赖 `for` 属性**。必须给 FieldLabel 设 `for="input-id"` 并给目标控件设相同 `id`，点击才会转发。
:::

---

### Zh CN Widgets Label (`docs/zh-CN/widgets/label.mdx`)

# Label

渲染与控件关联的可访问标签，点击时将 click 事件转发到 `for` 指向的目标部件。

<WidgetExample name="label-basic" />

## 适用场景

- **适用**：为 checkbox、text-input 等可交互控件提供点击区域扩展（点击文字也能触发控件）
- **适用**：辅助功能（a11y）中将文本与控件关联
- **不适用**：纯展示文本（用 `text` 部件）

## 用法

```tsx
import { Label } from "@lcui/react"
```

```tsx
<Label for="agree">I agree</Label>
```

## API 参考

<FieldTable name="label" />

---

### Zh CN Widgets Progress (`docs/zh-CN/widgets/progress.mdx`)

# Progress

用于展示任务进度（如文件上传、加载状态）的线性进度条部件。

<WidgetExample name="progress-basic" />

## 适用场景

- **适用**：文件上传/下载、安装、加载等长时间任务的进度展示
- **适用**：表单提交、异步操作的等待反馈
- **不适用**：需要精确数值或不确定进度的场景（用 `text` 自行绘制）

## 用法

```tsx
import { Progress } from "@lcui/react"
```

```tsx
<Progress value={20} />
```

## API 参考

<FieldTable name="progress" />

---

### Zh CN Widgets Radio Group (`docs/zh-CN/widgets/radio-group.mdx`)

# RadioGroup

一组互斥的单选按钮，同一时刻最多只有一项被选中。

<WidgetExample name="radio-group-basic" />

## 适用场景

- **适用**：从一组互斥的选项中选出唯一一个（视图密度、排序方式、单选枚举等）
- **适用**：选项数量固定为 2~7 个的简单场景
- **不适用**：需要并选多个选项的场景（用 `checkbox`）
- **不适用**：选项数量大到需要搜索或筛选（暂未提供 `select`）

## 用法

```tsx
import { RadioGroup, RadioGroupItem } from "@lcui/react"
```

```tsx
<RadioGroup value="comfortable">
  <RadioGroupItem value="default" id="r1" />
  <RadioGroupItem value="comfortable" id="r2" />
  <RadioGroupItem value="compact" id="r3" />
</RadioGroup>
```

## 组合

使用以下组合来构建 `RadioGroup`：

```
RadioGroup
├── RadioGroupItem
└── RadioGroupItem
```

通常每项会与一个 `Label` 搭配放置在同一行 flex 容器里，Label 的 `for` 指向 RadioGroupItem 的 `id`，点击 Label 会把 click 事件转发到对应的 item。

## 示例

### 禁用

<WidgetExample name="radio-group-disabled" />

## API 参考

### RadioGroup

单选组容器，管理组内各项的互斥选中状态。

<FieldTable name="radio-group" />

### RadioGroupItem

单选项，每一项代表一个可选值。同一 RadioGroup 内同一时刻最多只有一项处于 checked 状态。

<FieldTable name="radio-group-item" />

---

### Zh CN Widgets Scrollarea (`docs/zh-CN/widgets/scrollarea.mdx`)

# ScrollArea

当子内容超出容器范围时，提供滚动能力的容器部件。

<WidgetExample name="scrollarea-basic" />

## 适用场景

- **适用** — 内容高度或宽度可能超过容器（长列表、文档、日志）。
- **适用** — 需要滚动条可视化反馈的场景。
- **不适用** — 内容总是小于容器（直接用普通 `widget` 即可）。

## 用法

```tsx
import { ScrollArea, ScrollAreaContent, Scrollbar } from "@lcui/react"
```

```tsx
<ScrollArea>
  <ScrollAreaContent>{/* 子内容 */}</ScrollAreaContent>
  <Scrollbar orientation="horizontal" />
  <Scrollbar />
</ScrollArea>
```

## 组合

使用以下组合来构建 `ScrollArea`：

```
ScrollArea
├── ScrollAreaContent
└── Scrollbar
```

## 示例

### 双向滚动

<WidgetExample name="scrollarea-dual-scrollbars" />

当内容需要在水平和垂直两个方向上滚动时，同时设置横向和纵向滚动条。

## API 参考

### ScrollArea

滚动容器，负责裁剪超出范围的子内容并接收滚动事件。

<FieldTable name="scrollarea" />

### ScrollAreaContent

滚动内容容器，承载实际的子部件。必须作为 ScrollArea 的直接子部件使用。

<FieldTable name="scrollarea-content" />

### Scrollbar

滚动条部件，用于显示并操作滚动条。作为 ScrollArea 的直接子部件使用。

<FieldTable name="scrollbar" />

---

### Zh CN Widgets Select (`docs/zh-CN/widgets/select.mdx`)

# Select

Select 提供一个可展开的下拉选项列表，用于从多个候选值中选择一项。

<WidgetExample name="select-basic" />

## 适用场景

- **适用**：从多个选项中选择唯一值
- **适用**：选项较多、需要节省页面空间的表单
- **不适用**：需要同时选择多个值的场景（用 `checkbox`）

## 用法

```tsx
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@lcui/react"
```

```tsx
<Select>
  <SelectTrigger>
    <SelectValue placeholder="选择主题" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="light">浅色</SelectItem>
    <SelectItem value="dark">深色</SelectItem>
    <SelectItem value="system">跟随系统</SelectItem>
  </SelectContent>
</Select>
```

## 组合

使用以下组合来构建 `Select`：

```
Select
├── SelectTrigger
│   └── SelectValue
└── SelectContent
    └── SelectItem
```

## API 参考

### Select

Select 状态容器，管理当前选中值、placeholder 和下拉面板。

<FieldTable name="select" />

### SelectTrigger

触发下拉面板打开或关闭的按钮。

<FieldTable name="select-trigger" />

### SelectContent

通过 Portal 挂载到 root 层级的选项面板。

<FieldTable name="select-content" />

### SelectItem

代表一个可选值的选项。

<FieldTable name="select-item" />

---

### Zh CN Widgets Text Input (`docs/zh-CN/widgets/text-input.mdx`)

# TextInput

可编辑的文本输入部件。

<WidgetExample name="text-input-basic" />

## 适用场景

- **适用** — 用户输入文本（表单字段、搜索框）。
- **不适用** — 仅需要展示文本（用 `text`）。

## 用法

```tsx
import { TextInput } from "@lcui/react"
```

```tsx
<TextInput />
```

## API 参考

<FieldTable name="text-input" />

---

### Zh CN Widgets Text (`docs/zh-CN/widgets/text.mdx`)

# Text

用于显示文本的部件。

<WidgetExample name="text-basic" />

## 适用场景

- **适用** — 静态文本显示（标题、标签、说明文字）。
- **不适用** — 需要用户编辑文本（用 `textinput`）。

## 用法

```tsx
import { Text } from "@lcui/react"
```

```tsx
<Text>Hello</Text>
```

## API 参考

<FieldTable name="text" />

---

--- METRICS ---
- Files Extracted: 49
- Estimated Token Budget: ~22553 tokens
- Canonical Reference: https://codewiki.google/github.com/lc-soft/LCUI
