diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index b9375459..457b6c69 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -4,6 +4,9 @@ on:
push:
branches: [main]
workflow_dispatch:
+ workflow_run:
+ workflows: ['Publish npm package']
+ types: [completed]
permissions:
contents: read
@@ -14,6 +17,7 @@ concurrency:
jobs:
build:
+ if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 00000000..d64954f1
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,137 @@
+name: Publish npm package
+
+on:
+ push:
+ tags: ['v*']
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+concurrency:
+ group: npm-release
+ cancel-in-progress: false
+
+jobs:
+ publish:
+ if: github.repository == 'ifhover/leaf-ui'
+ runs-on: ubuntu-latest
+ timeout-minutes: 30
+ environment: npm
+ permissions:
+ contents: read
+ id-token: write
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ github.sha }}
+ fetch-depth: 0
+ persist-credentials: false
+ - uses: actions/setup-node@v4
+ with:
+ node-version: '26'
+ registry-url: 'https://registry.npmjs.org'
+ - name: Validate release tag, source commit and npm version
+ id: release
+ env:
+ RELEASE_TAG: ${{ github.ref_name }}
+ run: |
+ node --input-type=module <<'NODE'
+ import assert from 'node:assert/strict';
+ import { execFileSync } from 'node:child_process';
+ import { appendFileSync, readFileSync } from 'node:fs';
+
+ const { RELEASE_TAG: tag, GITHUB_REF: ref, GITHUB_SHA: runCommit } = process.env;
+ assert.match(tag, /^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/, 'Use a vX.Y.Z stable release tag, including when running the workflow manually.');
+ assert.equal(ref, `refs/tags/${tag}`, 'Select the release tag under Run workflow, not a branch.');
+ const git = (...args) => execFileSync('git', args, { encoding: 'utf8' }).trim();
+ const commit = git('rev-parse', 'HEAD');
+ assert.equal(commit, runCommit, 'The checkout must match the workflow run commit for provenance.');
+ assert.equal(git('rev-parse', `refs/tags/${tag}^{commit}`), commit, 'The checkout must match the release tag.');
+ git('merge-base', '--is-ancestor', commit, 'origin/main');
+ const pkg = JSON.parse(readFileSync('packages/react/package.json', 'utf8'));
+ assert.equal(pkg.name, '@ifhover/leaf-ui');
+ assert.equal(tag, `v${pkg.version}`, 'The tag must match packages/react/package.json.');
+ assert.equal(pkg.repository.url, 'git+https://github.com/ifhover/leaf-ui.git');
+
+ const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(pkg.name)}`, {
+ signal: AbortSignal.timeout(30_000),
+ });
+ assert.ok(response.ok || response.status === 404, `npm registry returned ${response.status}.`);
+ const registry = response.status === 404 ? {} : await response.json();
+ const published = registry.versions?.[pkg.version];
+ const latest = registry['dist-tags']?.latest;
+ if (published) {
+ assert.equal(published.gitHead, commit, 'This version was already published from a different commit. Bump the version.');
+ assert.equal(latest, pkg.version, 'This version is no longer latest; refusing to republish an older release.');
+ console.log(`${pkg.name}@${pkg.version} is already published from this commit; skipping the upload.`);
+ } else if (latest) {
+ assert.match(latest, /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/, 'npm latest must be a stable version.');
+ const currentParts = pkg.version.split('.').map(BigInt);
+ const latestParts = latest.split('.').map(BigInt);
+ const differing = currentParts.findIndex((part, index) => part !== latestParts[index]);
+ assert.ok(differing >= 0 && currentParts[differing] > latestParts[differing], 'The release version must be newer than npm latest.');
+ }
+ appendFileSync(process.env.GITHUB_OUTPUT, `version=${pkg.version}\ncommit=${commit}\nalready_published=${Boolean(published)}\n`);
+ NODE
+ - uses: pnpm/action-setup@v4
+ if: steps.release.outputs.already_published != 'true'
+ - name: Install dependencies
+ if: steps.release.outputs.already_published != 'true'
+ run: pnpm install --frozen-lockfile
+ - name: Check source, tests and release notes
+ if: steps.release.outputs.already_published != 'true'
+ run: pnpm check
+ - name: Build and verify library and documentation
+ if: steps.release.outputs.already_published != 'true'
+ run: pnpm build
+ - name: Ensure the build did not change release sources
+ if: steps.release.outputs.already_published != 'true'
+ run: |
+ if [[ -n "$(git status --porcelain)" ]]; then
+ git status --short
+ echo 'Commit generated source changes before publishing.' >&2
+ exit 1
+ fi
+ - name: Install npm with trusted publishing support
+ if: steps.release.outputs.already_published != 'true'
+ run: npm install --global npm@11
+ - name: Publish to npm using OIDC
+ if: steps.release.outputs.already_published != 'true'
+ working-directory: packages/react
+ run: npm publish --access public --tag latest --provenance --registry https://registry.npmjs.org/
+ - name: Verify published commit and latest tag
+ env:
+ RELEASE_VERSION: ${{ steps.release.outputs.version }}
+ RELEASE_COMMIT: ${{ steps.release.outputs.commit }}
+ run: |
+ node --input-type=module <<'NODE'
+ import assert from 'node:assert/strict';
+ import { appendFileSync } from 'node:fs';
+ import { setTimeout } from 'node:timers/promises';
+
+ const { RELEASE_VERSION: version, RELEASE_COMMIT: commit } = process.env;
+ for (let attempt = 1; attempt <= 12; attempt++) {
+ try {
+ const response = await fetch('https://registry.npmjs.org/@ifhover%2Fleaf-ui', {
+ cache: 'no-store',
+ signal: AbortSignal.timeout(30_000),
+ });
+ assert.ok(response.ok, `npm registry returned ${response.status}.`);
+ const registry = await response.json();
+ assert.equal(registry.versions?.[version]?.gitHead, commit, 'npm gitHead does not match the release commit.');
+ assert.equal(registry['dist-tags']?.latest, version, 'npm latest does not match the release version.');
+ appendFileSync(process.env.GITHUB_STEP_SUMMARY, [
+ `Verified npm package: [@ifhover/leaf-ui@${version}](https://www.npmjs.com/package/@ifhover/leaf-ui/v/${version})`,
+ `Release tag: v${version}; commit: ${commit}`,
+ 'The Deploy documentation workflow runs after this workflow succeeds. Check its result before considering the release complete.',
+ '',
+ ].join('\n\n'));
+ break;
+ } catch (error) {
+ if (attempt === 12) throw error;
+ console.log(`Waiting for npm registry metadata (${attempt}/12): ${error.message}`);
+ await setTimeout(10_000);
+ }
+ }
+ NODE
diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml
index 6e204437..efc0657e 100644
--- a/.github/workflows/quality.yml
+++ b/.github/workflows/quality.yml
@@ -31,6 +31,7 @@ jobs:
with:
name: production-bundles
path: packages/react/.quality
+ include-hidden-files: true
react-compatibility:
runs-on: ubuntu-latest
@@ -71,6 +72,7 @@ jobs:
if: always()
with:
name: browser-${{ matrix.browser }}
+ include-hidden-files: true
path: |
packages/react/playwright-report
packages/react/test-results
diff --git a/.gitignore b/.gitignore
index f83a18a0..110a2e42 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
node_modules/
+apps/docs/docs/public/locales/
dist/
doc_build/
site_build/
diff --git a/AGENTS.md b/AGENTS.md
index 47f5f786..75a57506 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -4,6 +4,8 @@
开始开发、修改使用文档或准备发布前,必须阅读并遵守 [开发、版本与文档同步流程](DEVELOPMENT-WORKFLOW.md)。该文档是分支开发、正式发布、开发文档预览与清理的统一约定。
+新增、修改或重构组件前,必须阅读并遵守 [组件编写与开发规则](packages/react/DEVELOPMENT.md) 和 [样式与交互标准](DESIGN-STANDARDS.md)。组件的公共 API、区域默认参数、内部控件、复合组件、表单语义和验证要求均以这些规则为准。
+
## 核心规则
- `main` 是稳定发布分支。组件代码和使用文档的改动必须在新分支完成,合并到 `main` 意味着完成一次新版本发布。
@@ -16,8 +18,8 @@
## 相关说明
- 项目结构与本地开发:[DEVELOPMENT.md](DEVELOPMENT.md)
-- 组件实现约定:[packages/react/DEVELOPMENT.md](packages/react/DEVELOPMENT.md)
+- 组件编写与开发规则:[packages/react/DEVELOPMENT.md](packages/react/DEVELOPMENT.md)
- 样式与交互标准:[DESIGN-STANDARDS.md](DESIGN-STANDARDS.md)
- 发布操作:[packages/react/RELEASING.md](packages/react/RELEASING.md)
-- 文档构建与快照:[apps/docs/README.md](apps/docs/README.md)
+- 文档构建与快照:[apps/docs/AGENTS.md](apps/docs/AGENTS.md)
- 质量验收:[packages/react/QUALITY.md](packages/react/QUALITY.md)
diff --git a/DESIGN-REFRESH.md b/DESIGN-REFRESH.md
index bfe4cf40..db9d0a1e 100644
--- a/DESIGN-REFRESH.md
+++ b/DESIGN-REFRESH.md
@@ -31,7 +31,7 @@ All 83 catalog entries were reviewed. The seven static or direct manipulation pr
| Button, Input, InputNumber, Textarea, Checkbox, Radio, Switch, Slider, Rate, InputOTP, InputMask, SignaturePad, ImageCropper, ColorPicker | Neutral field hierarchy, focus/hover/press feedback, continuous check/thumb changes, measured textarea growth, stable loading button width/name, validation and tool feedback. Typing, drawing, cropping and pointer dragging remain immediate. |
| Select, AutoComplete, Mentions, Cascader, TreeSelect, Transfer | Refined trigger and option surfaces, opening origins, chevrons, selection feedback, column/list changes; virtual data windows do not animate as ordinary rows. |
| Calendar, DatePicker, DateTimePicker, DateRangePicker, TimePicker, TimeRangePicker | Directional view changes, shared calendar surfaces, direct date range selection, simultaneous time endpoints, continuous time selection and keyboard feedback. |
-| Tabs, Segmented, Menu, Steps, Breadcrumb, Pagination, Anchor, BackTop, FloatButton, AppBar | Measured shared selection indicators, retained tab panels, directional content and height transitions, progress rings, navigation hover/press, staggered quick actions. Geometry handles scrolling, RTL, resized text and scaled ancestors. |
+| Tabs, Segmented, Menu, Steps, Breadcrumb, Pagination, Anchor, BackTop, FloatButton, AppBar | Measured shared selection indicators, immediately switched tab panels with retained state, progress rings, navigation hover/press, staggered quick actions. Geometry handles scrolling, RTL, resized text and scaled ancestors. |
| Collapse, Tree, OrgChart, Carousel | Natural expansion/collapse with retained inert exit content, branch chevrons, interrupted list layout motion, zoom-aware geometry, directional overlapping carousel slides and natural host heights. Virtual Tree remains immediate. |
| Modal, Drawer, Confirm, Popover, Popconfirm, Tooltip, Dropdown, CommandPalette, Tour | Coordinated masks/surfaces, actual floating origins, moving highlights, natural content height changes, preserved inputs/focus, orderly exit presence, async generation isolation and correct Tour step references. |
| Alert, Message, Notification, Loading, LoadingBar, Progress, Result, ErrorBoundary, Skeleton, Statistic | State/icon feedback, continuous queue collapse, progress changes and completion, resolved skeleton content reveal without an extra wrapper, immediate numeric values with subtle update motion. Empty uses the Result family. |
diff --git a/DESIGN-STANDARDS.md b/DESIGN-STANDARDS.md
index 8353fccc..5f5222a7 100644
--- a/DESIGN-STANDARDS.md
+++ b/DESIGN-STANDARDS.md
@@ -4,22 +4,32 @@ The default appearance is quiet and readable. Every component uses semantic them
| Foundation | Comfortable | Compact |
| --- | --- | --- |
-| Base control height | 40 px | 34 px |
+| Base control height | 36 px | 30 px |
| Base body text | 14 px / 1.6 | 14 px / 1.6 |
| Secondary text | 13 px | 13 px |
| Spacing unit | 8 px | 6 px |
| Form row gap | 24 px | 16 px |
| List row vertical padding | 12 px | 8 px |
-| Popup option minimum height | 36 px | 30 px |
+| Popup option minimum height | 32 px | 26 px |
| Dialog padding, block / inline | 20 / 24 px | 16 / 20 px |
| Radius, small / base / medium / large | 6 / 10 / 12 / 16 px | 6 / 10 / 12 / 16 px |
Component size is a local choice; density is a region-wide layout choice. Compact is intended for pointer/keyboard data-heavy interfaces. Use comfortable or larger explicit controls for touch interfaces; essential targets should be at least 24 px and preferably 44 px.
-Hierarchy comes from radius, borders and type rather than decoration. Radii step down from the outside in: dialogs, drawers and popups use the large radius; content surfaces (Card, Alert, Collapse, Descriptions, Transfer, Upload, FileList, Result content, choice cards and lists) use the medium radius; buttons, fields and Table frames use the base radius; checkboxes and small chips use the small radius; status tags are pills. Content surfaces use hairline borders and muted fills without shadows; shadows are reserved for layers that float (popups use `shadow-md`, dialogs `shadow-lg`) and for raised handles such as slider thumbs and selected segments. Text hierarchy relies on size and color: 14 px body, 13 px secondary text, `fontWeight` (500) for component titles, labels, selected tabs and buttons, and `headingWeight` (600) only for Typography headings. Option group headings in Select, Dropdown, Menu, CommandPalette, List and rich choice groups use the shared section label: 12 px, weight 500, 0.04em tracking, uppercase for Latin text, muted color. Indicators that accompany text (Steps icons, Result and Upload symbols) are sized relative to the text, not to the control height.
+Hierarchy comes from radius, borders and type rather than decoration. Radii step down from the outside in: dialogs, drawers and popups use the large radius; content surfaces (Card, Alert, Collapse, Descriptions, Transfer, Upload, FileList, Result content, choice cards and lists) use the medium radius; buttons, fields and Table frames use the base radius; checkboxes and small chips use the small radius; status tags use borderless fills and the small radius. Content surfaces use hairline borders and muted fills without shadows; shadows are reserved for layers that float (popups use `shadow-md`, dialogs `shadow-lg`) and for raised handles such as slider thumbs and selected segments. Text hierarchy relies on size and color: 14 px body, 13 px secondary text, `fontWeight` (500) for component titles, labels, selected tabs and buttons, and `headingWeight` (600) only for Typography headings. Option group headings in Select, Dropdown, Menu, CommandPalette, List and rich choice groups use the shared section label: 12 px, weight 500, 0.04em tracking, uppercase for Latin text, muted color. Indicators that accompany text (Steps icons, Result and Upload symbols) are sized relative to the text, not to the control height.
Inset surfaces use concentric curves: `inner radius = max(0px, outer radius - padding - border width)`. A default popup has a 16 px outer radius, 6 px padding and a 1 px border, so its options use 9 px. Hover, selected and moving highlight layers share that curve. The shared geometry helper accounts for unequal padding with horizontal/vertical corner radii, including the extra insets in Cascader, TreeSelect and TimePicker. Theme and component padding changes update the curves automatically; small and square themes clamp to zero. Independent controls, calendar cells, tags and icons retain their semantic radii. Do not introduce clipping merely to hide a mismatch.
+Menu navigation items, hover backgrounds and moving selection indicators use the same base radius as buttons, independent of menu padding. An explicit Menu component radius overrides this shared default.
+
+Select, TreeSelect and Cascader use shared multi-selection tags: tag height is the current control height minus 8 px, with 6 px inline gaps and 3 px field padding above and below. Tags wrap by default; `tagWrap={false}` or `maxTagCount="responsive"` keeps one line, truncates long labels and collapses excess values into `+N`. Reserve the actual input, clear and arrow space; when a label cannot fit, show the count alone. Folding is presentation only and must not alter selection or FormData. Width-driven folding does not replay selection entry animations. TreeSelect retains expanded branches across popup unmounts; search expansion is temporary, arrows only expand, and checkbox rows accept both label and empty-area activation.
+
+Tag uses borderless tinted or solid fills and a tighter radius of five-sixths of the theme's small radius (5 px by default). Explicit Tag component radius overrides take precedence.
+
+Pagination defaults to surface-filled outline buttons; `variant="ghost"` keeps borderless controls. Both share control-height tokens, stable pressed geometry and a moving primary selection surface. Outline hover/press changes the border and text, while ghost uses neutral fills. `showTotal` accepts a boolean for a localized count or a render function. Page and page-size changes use one callback; quick jumps commit on Enter or on leaving the pagination region without overriding a clicked pagination action.
+
+Card-style Tabs fit the tab labels by default while panels retain the available content width. Their size describes the entire tab bar, including padding and borders: 30 / 36 / 42 px by default. Inner buttons subtract those insets from the shared control height. Tab entries, buttons and moving selection share an inner radius derived from the bar radius minus its actual padding and border, clamped at zero; regional themes and explicit component overrides feed the same calculation. Default bar padding is 2 / 4 / 5 px, with 12 px inline label padding and a 2 px gap. Keep room for the selection shadow inside the clipped track without introducing scroll overflow. Tab content and panel height update immediately without entry, fade, slide or height animations; the tab bar's selection indicator retains its movement animation.
+
| State | Required behavior |
| --- | --- |
| Default | Legible text, consistent icon alignment, stable geometry |
@@ -36,9 +46,9 @@ Use the primary color for actionable emphasis. Use success/info/warning/danger f
Warning glyphs, field accents and status fills use a clear amber (`#faad14` in light, `#ffc53d` in dark). Warning text derives a darker or lighter readable ink independently; solid warning tags choose a contrasting label. Do not darken every warning accent to achieve text contrast.
-Dropdown pointer, keyboard and pressed states share one moving background; danger transitions interpolate its color. Select uses the same opaque primary tint for selected rows and the moving highlight, which stays visible when crossing a selection. Selected text and checkmarks convey the persistent value without changing the hover fill.
+Unselected options use one opaque neutral hover color (`--leaf-color-option-hover`, 9% text mixed with 91% surface; default light `#ebebeb`, dark `#2f2f33`) for pointer, keyboard candidate and pressed feedback. Select, AutoComplete, Cascader, TreeSelect / Tree, time columns, Dropdown, Menu and CommandPalette share it. Persistent selections retain the opaque 9% primary tint, semantic text and checkmarks; suggestion candidates are neutral even when their listbox uses `aria-selected` to announce navigation. Moving backgrounds interpolate both position and color; opaque fills prevent darkening when they cross selected rows, and static rows must not add a second hover / pressed fill. Disabled options receive no interaction feedback; danger actions retain their red semantic fill. These states inherit the regional appearance and palette without changing option geometry.
-Ordinary action feedback uses 120–200 ms easing. Dialogs and drawers can use up to 320 ms; drawers slide without overshoot. Messages and notifications enter as one unit, without inner icon/text springs. Selection indicators may move to the newly selected item; their animation must not move the control itself. Card lift is opt-in through `hoverable`. Honor system reduced motion and `theme.motion={false}`; animation never gates functionality.
+Ordinary action feedback uses 120–200 ms easing. Dialogs and drawers can use up to 320 ms; drawers slide without overshoot. Messages and notifications enter as one unit, without inner icon/text springs. Selection indicators may move to the newly selected item; their animation must not move the control itself. Cards retain their position and surface on hover. Honor system reduced motion and `theme.motion={false}`; animation never gates functionality.
Solid and outlined Button activation uses a single translucent perimeter wave, following Ant Design's ease-out curve: a 400 ms expansion to 6 px outside the border and a 2 s opacity decay from 0.2. Ghost and link buttons omit the decoration, including danger and icon-only ghost buttons. Both timings follow the regional motion duration. One persistent decorative span and one browser animation handle both properties, without geometry/color measurement, per-click React roots, observers or per-frame JavaScript. It follows the actual corner radii and semantic action color and never clips or scales the label. Repeated activation replaces the current wave; disabling, loading, switching to ghost, unmounting or changing motion preferences cancels it. The decoration neither intercepts pointers nor changes scrollable layout, native submission, focus or accessible names. Forced colors omits the wave while retaining the focus outline.
@@ -46,14 +56,18 @@ Solid buttons brighten on hover and deepen on press; derived shades retain reada
Dialog headings, form edges and footer actions share the same inline padding. The body has sufficient separation from both heading and actions. A notification close action occupies only the heading row. Icons are decorative when the accompanying text already conveys the meaning. Every icon-only action needs an accessible name.
-Modal and Drawer use a content surface, subtle section dividers and a muted footer by default. `divided={false}` groups content with spacing. Their heading icons share a neutral circular base. Confirm is an API-only decision prompt: a compact 420 px surface, spacing-based sections, a bare semantic glyph beside the explanation and no background base or section dividers. Its heading starts at the content edge, independently of the body icon. Popconfirm and Notification use a bare semantic glyph aligned with the title line. Headers without a supporting description use a 16 px vertical inset; Modal and Confirm footers use 12 px. Titles and supporting descriptions share an independent text column. The close action remains on the inline end. Body content scrolls without moving the heading or footer. Borders and surfaces derive from the current light/dark region, including custom palettes and density.
+Modal and Drawer use a content surface, subtle section dividers and a muted footer by default. `divided={false}` groups content with spacing. Their heading icons share a neutral circular base. Confirm is an API-only decision prompt: a compact 420 px surface, spacing-based sections, a bare semantic glyph beside the explanation and no background base or section dividers. Its heading starts at the content edge, independently of the body icon. Popconfirm and Notification use a bare semantic glyph aligned with the title line. Headers without a supporting description use a 16 px vertical inset; Divided Card, Modal and Drawer footers share 12 px vertical insets; spacing-only dialog and Confirm footers use 12 px below their actions. Titles and supporting descriptions share an independent text column. The close action remains on the inline end. Body content scrolls without moving the heading or footer. Borders and surfaces derive from the current light/dark region, including custom palettes and density.
+
+Card no longer exposes `hoverable` or adds hover lift; `bordered` remains available. Card `size` offers small, default and large layouts: body padding defaults to 16 / 20 / 24 px, heading insets to 12 / 16 / 20 px and title text to 14 / 15 / 16 px. Embedded Tabs follow the Card size unless explicitly overridden; child controls keep their own sizes. Card headings use `fontWeight` (500 by default) and equal vertical insets; the body does not add a second inset below an undivided header. Card retains spacing-based sections by default; `divided` opts into borders and a muted footer for settings or action-focused content. Checkbox/Radio card choices have one full clickable label, a neutral icon base, a title/description column and a trailing native control. Groups may arrange these as a responsive grid or one list with shared borders and row separators. Selected borders use the primary color without gradients or lifting. Status tags are non-interactive, and supporting text is an accessible description rather than part of the choice name. Neutral Alert surfaces preserve semantic icon colors and announcement roles.
+
+Card can integrate top line tabs through its `tabs` configuration. With a heading, navigation sits below the title and description without an intervening divider; without a heading, tabs fill the entire heading height with vertically centered labels and Card actions move to the trailing edge. Replacement headings derive their minimum height from the Card title line and symmetric heading insets, respect larger explicit tab sizes, and have no top-only outer padding. One full-width divider runs under the entire tab bar, including its actions. Tab labels and panels align with the Card content edge, panel insets and header surfaces inherit Card tokens, and tab size follows Card size unless explicitly set. The footer retains Card's spacing or divided treatment. Reuse Tabs navigation, overflow, content retention and animation rather than creating a second tab state system; loading replaces panel content while navigation remains mounted.
-Card retains spacing-based sections by default; `divided` opts into borders and a muted footer for settings or action-focused content. Checkbox/Radio card choices have one full clickable label, a neutral icon base, a title/description column and a trailing native control. Groups may arrange these as a responsive grid or one list with shared borders and row separators. Selected borders use the primary color without gradients or lifting. Status tags are non-interactive, and supporting text is an accessible description rather than part of the choice name. Neutral Alert surfaces preserve semantic icon colors and announcement roles.
+FileList uses one shared frame and row separators for text and thumbnail lists. Visuals, file information and actions occupy separate columns; names truncate within their column, while type and optional size remain secondary. Upload state, progress and errors belong to the information column. Preview buttons, download links, removal and Upload actions share square geometry. Picture cards keep a stable preview ratio and align their actions at the bottom. Missing sizes leave no empty placeholder, failed thumbnails retain a type icon, and asynchronous removal feedback stays with its file. No row shadow or hover lift is applied.
-ConfigProvider remains the configuration entry. Base colors, radius and height derive related geometry; advanced `dividerColor`, component `borderColor`, `headerBackground` and `footerBackground` provide selective overrides. CSS variables are consumption points for application styling. Filled actions and checkmarks remain solid colors, and single-line controls keep the 40px base height.
+ConfigProvider remains the configuration entry. Base colors, radius and height derive related geometry; advanced `dividerColor`, component `borderColor`, `headerBackground` and `footerBackground` provide selective overrides. CSS variables are consumption points for application styling. Filled actions and checkmarks remain solid colors, and single-line controls keep the 36px base height.
Buttons expose solid, outline, ghost and link appearances. Link actions use theme-colored text with no border, padding or control-height minimum; hover and press change only their color, and activation has no wave. Outline uses a content surface, body text and a visible neutral border; danger uses its semantic text and border. Alerts use one neutral surface with semantic icon colors. Result icons sit on the same muted circular base for every status. Table frames use the same base radius as buttons, 13 px muted column headers and divider-colored row separators, and fill their container before horizontal overflow; a minimum width remains a lower bound. Scrollbar tracks overlay content and appear on hover, scroll or keyboard focus; dragging must neither steal input focus nor add a pointer focus outline.
-Development migration: replace Button `variant="soft"` with `variant="outline"` and remove Alert `variant` props. Comfortable controls now derive 34 / 40 / 46 px sizes; compact controls use a 34 px base. Set `theme.controlHeight` explicitly when an application needs to retain its former sizing. Content surfaces move from the large to the new medium radius (`borderRadiusMd` / `--leaf-radius-md`) and drop their default shadow; small text becomes 13 px (`fontSize - 1px`); button inline padding derives from its actual height (0.42 times the height, 16.8 px at 40 px), with explicit component padding taking precedence for every size; component titles use `fontWeight` instead of `headingWeight`; small Steps retain body-size labels and at least 24 px indicators; rich choice legends use section labels; replace controlled `Confirm` / `ConfirmProps` with `useConfirm().confirm(options)` / `ConfirmOptions`, and move rich confirmation flows to Modal; Confirm retains a bare body icon; tags become pills; popups use `shadow-md`; Pagination items become borderless. Include these compatibility changes in the next release's migration notes.
+Development migration: replace Button `variant="soft"` with `variant="outline"` and remove Alert `variant` props. Comfortable controls now derive 30 / 36 / 42 px sizes; compact controls use a 30 px base. Set `theme.controlHeight` explicitly when an application needs to retain its former sizing. Content surfaces move from the large to the new medium radius (`borderRadiusMd` / `--leaf-radius-md`) and drop their default shadow; small text becomes 13 px (`fontSize - 1px`); button inline padding derives from its actual height (0.42 times the height, 15.12 px at 36 px), with explicit component padding taking precedence for every size; component titles use `fontWeight` instead of `headingWeight`; small Steps retain body-size labels and at least 24 px indicators; rich choice legends use section labels; replace controlled `Confirm` / `ConfirmProps` with `useConfirm().confirm(options)` / `ConfirmOptions`, and move rich confirmation flows to Modal; Confirm retains a bare body icon; tags use borderless fills and the small radius; replace Tag `variant="outline"` with the default `soft` appearance; popups use `shadow-md`; Pagination uses outlined page buttons by default; set variant="ghost" to retain borderless buttons. Include these compatibility changes in the next release's migration notes.
Acceptance uses keyboard behavior, geometry assertions, axe, SSR, build/package checks and manual inspection in both themes and densities. Screenshot baseline comparisons are deliberately deferred. See `IMPLEMENTATION-BATCHES.md` and `packages/react/ACCESSIBILITY.md` for evidence and manual coverage limits.
diff --git a/DEVELOPMENT-WORKFLOW.md b/DEVELOPMENT-WORKFLOW.md
index 8f6fd715..5ad0a4f7 100644
--- a/DEVELOPMENT-WORKFLOW.md
+++ b/DEVELOPMENT-WORKFLOW.md
@@ -49,8 +49,8 @@ npm 新作用域为 `@ifhover/leaf-ui`;迁移前的稳定版仍属于 `@sudden
正式发布的操作命令见 [packages/react/RELEASING.md](packages/react/RELEASING.md)。发布顺序为:
1. 将准备好的发布分支合并到 `main`,确认版本、更新记录和源码已提交。此后不叠加新的待发布功能,先完成这一版本的发布。
-2. 在实际合并后的发布提交重新检查与构建,确保工作区干净。使用该提交发布 npm 和创建 `vX.Y.Z` 标签;采用 squash 或 rebase 合并时,以合并后的提交为准。
-3. 确认 npm 的版本、`latest` 和 `gitHead`,推送标签,并部署默认在线文档与 `/v/X.Y.Z/` 快照。若合并触发的 Pages 构建早于 npm 发布,发布后重新触发 `Deploy documentation` 工作流。
+2. 在实际合并后的发布提交重新检查与构建,确保工作区干净。创建并推送 `vX.Y.Z` 标签,触发 `Publish npm package` 通过 OIDC 发布 npm;普通提交与 `main` 推送不会发布 npm。也可手动运行发布工作流,并在 **Use workflow from** 中选择已推送的正式版本标签。采用 squash 或 rebase 合并时,以合并后的提交为准。
+3. 发布工作流确认 npm 的版本、`latest` 和 `gitHead` 后,自动触发 `Deploy documentation`,部署默认在线文档与 `/v/X.Y.Z/` 快照;文档部署失败时重跑文档工作流。源码、标签和 npm 必须对应同一提交,本地手动发布操作见发布说明。
4. 分支合并到 `main` 后必须删除对应临时在线文档、资源、预览入口与活动预览清单中的条目,并停止继续更新该预览的任务。放弃开发、关闭未合并 PR 或删除开发分支时,也执行相同清理;清理结果保留在 PR 或发布记录中。
5. 验证正式站点与 npm 一致,开发预览 URL 已不再提供开发内容,正式历史快照仍可访问,再报告发布完成。
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index 42e881af..80cc7f70 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -80,13 +80,13 @@ pnpm --dir packages/react pack
## 文档内容边界
-在线文档只包含组件使用说明。文档站运行与维护说明见 [apps/docs/README.md](apps/docs/README.md),组件开发流程见 [packages/react/DEVELOPMENT.md](packages/react/DEVELOPMENT.md)。
+在线文档只包含组件使用说明。文档站运行与维护说明见 [apps/docs/AGENTS.md](apps/docs/AGENTS.md),组件开发流程见 [packages/react/DEVELOPMENT.md](packages/react/DEVELOPMENT.md)。
-每次 npm 升版发布都需维护中英文更新记录,并同步部署版本快照。具体步骤见 [发布文档](packages/react/RELEASING.md);`pnpm check:release` 会校验组件包当前版本的记录。`pnpm build:versions` 使用 npm gitHead 独立构建每个已发布版本,导航和 AI 查询均以快照版本为准。版本构建与 AI 文档契约见 [文档站维护说明](apps/docs/README.md),Skill 发行见 [skills/README.md](skills/README.md)。
+每次 npm 升版发布都需维护中英文更新记录,并同步部署版本快照。具体步骤见 [发布文档](packages/react/RELEASING.md);`pnpm check:release` 会校验组件包当前版本的记录。`pnpm build:versions` 使用 npm gitHead 独立构建每个已发布版本,导航和 AI 查询均以快照版本为准。版本构建与 AI 文档契约见 [文档站维护说明](apps/docs/AGENTS.md),Skill 发行见 [skills/README.md](skills/README.md)。
## 样式与图标
-源码统一使用 SCSS,通过 @rsbuild/plugin-sass 构建。公共尺寸和样式 mixin 在 packages/react/src/styles;40px 是默认表单对齐基准。图标使用 lucide-react 的具名导入,具体约定见组件库开发文档。
+组件库与文档站主题使用 SCSS,通过 @rsbuild/plugin-sass 构建;文档示例优先使用 Flex、Space、Grid、FormField 和 Text,不依赖 Tailwind CSS;示例规则见 [文档站协作约定](apps/docs/AGENTS.md)。站点界面现有的 Tailwind CSS 入口由 PostCSS 编译。公共尺寸和样式 mixin 在 packages/react/src/styles;36px 是默认表单对齐基准。图标使用 lucide-react 的具名导入,具体约定见组件库开发文档。
## 质量验收
diff --git a/README.en-US.md b/README.en-US.md
new file mode 100644
index 00000000..d082ba3e
--- /dev/null
+++ b/README.en-US.md
@@ -0,0 +1,121 @@
+
+
+## ✨ Features
+
+- 🍃 **A natural starting point** — A green default theme and clear interaction states, with components for inputs, forms, layout, navigation, and feedback.
+- 🎨 **Make it yours** — Customize colors, radii, typography, control heights, and light or dark appearance through ConfigProvider, scoped themes, and CSS variables.
+- 🛡️ **Built with TypeScript** — Includes type declarations and preserves native HTML attributes, DOM refs, and form semantics.
+- 🌍 **Multiple languages** — Chinese and English documentation, built-in locales, custom translations, nested locale settings, and RTL direction.
+- ⌨️ **Thoughtful interactions** — Keyboard navigation, focus management, and support for reduced motion preferences.
+- 📦 **Fits your stack** — React 18 / 19, ESM, CommonJS, and SSR, with component styles retained on demand in supported production builds.
+
+## 🖥️ Compatibility
+
+Supports React **18 / 19**, modern browsers, and server-side rendering. We recommend the current or previous stable browser release.
+
+| Chrome | Edge | Firefox | Safari |
+| :-------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------: |
+| ≥ 109 | ≥ 109 | ≥ 121 | ≥ 16.4 |
+
+These are minimum support targets. See [browser compatibility](https://ifhover.github.io/leaf-ui/en/guide/compatibility.html) for test coverage and fallbacks, and the [SSR guide](https://ifhover.github.io/leaf-ui/en/guide/ssr.html) for Next.js and other frameworks.
+
+## 📦 Installation
+
+```bash
+pnpm add @ifhover/leaf-ui
+```
+
+
+Using npm / Yarn / Bun
+
+```bash
+npm install @ifhover/leaf-ui
+yarn add @ifhover/leaf-ui
+bun add @ifhover/leaf-ui
+```
+
+
+
+Your application must provide `react` and `react-dom`. Compiled CSS is included; you do not need Sass.
+
+## 🔨 Quick start
+
+```tsx
+import { Button, DatePicker } from '@ifhover/leaf-ui';
+
+export default function App() {
+ return (
+ <>
+
+ Get started
+ >
+ );
+}
+```
+
+Base styles and the required component and service styles load automatically, without manual CSS imports. Vite and Rsbuild / Rspack production builds retain styles on demand for named ESM imports from the root entry. For direct esbuild or CommonJS use, component subpaths such as `@ifhover/leaf-ui/button` are available. Custom SSR pipelines can use the full static stylesheet at `@ifhover/leaf-ui/styles/all.css`.
+
+Single-line controls default to **36px**, with **30 / 42px** small and large sizes. Find more examples in [getting started](https://ifhover.github.io/leaf-ui/en/guide/getting-started.html).
+
+## 🎨 Themes and locales
+
+Use ConfigProvider to configure a theme and locale for your application or a specific region:
+
+```tsx
+import { ConfigProvider } from '@ifhover/leaf-ui';
+import App from './App';
+
+export default function Root() {
+ return (
+
+
+
+ );
+}
+```
+
+Set `locale` to `zh-CN` for Simplified Chinese, or set `theme.appearance` to `dark` for dark mode. Nested providers inherit unspecified options, and popups and messages follow the theme and locale of their region.
+
+Explore [theming](https://ifhover.github.io/leaf-ui/en/guide/theming.html) · [ConfigProvider themes and locales](https://ifhover.github.io/leaf-ui/en/components/config-provider.html).
+
+## 🤖 AI-assisted development
+
+Install the Leaf UI Skill in your application directory so your AI assistant can look up component APIs for the version your project uses:
+
+```bash
+npx skills add ifhover/leaf-ui --skill leaf-ui
+```
+
+See [AI and Skills](https://ifhover.github.io/leaf-ui/en/guide/ai.html) for setup and usage. You can also switch between published versions at the top of the documentation site.
+
+## 🤝 Contributing
+
+Share bugs and ideas through [Issues](https://github.com/ifhover/leaf-ui/issues), or open a [Pull Request](https://github.com/ifhover/leaf-ui/pulls).
+
+See the [development guide](./DEVELOPMENT.md) for local setup, project structure, and builds. Before changing components or user documentation, read the [development, versioning, and documentation workflow](./DEVELOPMENT-WORKFLOW.md).
diff --git a/README.md b/README.md
index 99ae2ec9..ca9556e6 100644
--- a/README.md
+++ b/README.md
@@ -1,184 +1,121 @@
-# Leaf UI
+
+
+
+
-轻盈、自然、可定制的 React UI 组件库。默认绿色主题,通过 ConfigProvider 调整颜色、圆角、字体和控件高度。支持 React 18 / 19,提供 TypeScript 类型、ESM 和 CommonJS 入口。
+
Leaf UI
-[在线文档](https://ifhover.github.io/leaf-ui/) · [更新记录](https://ifhover.github.io/leaf-ui/changelog.html) · [npm](https://www.npmjs.com/package/@ifhover/leaf-ui)
+
轻盈 · 自然 · 可定制
+
一个以绿色为起点的 React UI 组件库,让界面保留你的个性。
-使用 AI 编写界面时,可在应用目录安装按项目实际版本查询 API 的 Skill:`npx skills add ifhover/leaf-ui --skill leaf-ui`。安装与使用见 [AI 与 Skills](https://ifhover.github.io/leaf-ui/guide/ai.html),文档顶部可切换已发布版本。
+
+
+
+
+
+
+
-## 安装与使用
+
+ 在线文档 ·
+ 组件总览 ·
+ 更新记录 ·
+ 反馈问题
+
-在你的 React 应用中安装组件包:
+
简体中文 · English
+
-```bash
-pnpm add @ifhover/leaf-ui
-```
-
-也可以使用 `npm install @ifhover/leaf-ui` 或 `yarn add @ifhover/leaf-ui`。样式只需在应用入口引入一次,使用组件无需安装 Sass。
+## ✨ 特性
-```tsx
-import { Button, DatePicker, Input, Select } from '@ifhover/leaf-ui';
-import '@ifhover/leaf-ui/styles.css';
+- 🍃 **轻盈自然** — 绿色默认主题、清晰的交互状态,覆盖输入、表单、布局、导航与反馈。
+- 🎨 **随心定制** — 通过 ConfigProvider 调整颜色、圆角、字体、控件高度和明暗外观,支持区域主题与 CSS 变量。
+- 🛡️ **类型完备** — 使用 TypeScript 编写,提供类型声明,保留原生 HTML 属性、DOM ref 与表单语义。
+- 🌍 **多语言** — 提供中英文文档,支持内置语言、自定义翻译、嵌套语言配置与 RTL 方向。
+- ⌨️ **细致交互** — 支持键盘操作、焦点管理,以及系统的减少动态效果偏好。
+- 📦 **融入工程** — 兼容 React 18 / 19,提供 ESM、CommonJS 和 SSR 用法,组件样式可随生产构建按需保留。
-export function App() {
- return (
-
- );
-}
-```
+## 🖥️ 兼容性
-单行控件默认高度统一为 **40px**,小 / 大尺寸为 **34 / 46px**。选择类组件使用统一的浮层,支持键盘操作、点击外部收起和局部主题。
-
-浏览器组件入口会自动加载样式。`styles.css` 在应用入口引入一次,提供主题变量及 API 服务样式。Vite、Rsbuild / Rspack 的生产构建支持根入口的 ESM 具名导入按需保留组件及其内部依赖的样式,无需使用组件子路径。直接使用 esbuild 或 CommonJS 根入口时不能保证样式裁剪,可使用 `@ifhover/leaf-ui/button` 等子路径。自行管理 SSR 样式时可使用完整静态入口 `@ifhover/leaf-ui/styles/all.css`。
-
-## 组件
-
-| 导入名称 | 用途 |
-| --- | --- |
-| `Button` | 按钮、图标、加载与红色危险状态 |
-| `Input` / `Textarea` | 单行 / 多行文本输入 |
-| `InputNumber` | 数量、金额、范围与小数精度 |
-| `Steps` / `Breadcrumb` / `Pagination` / `Tabs` | 步骤、路径、分页和内容切换 |
-| `Tag` / `Badge` | 分类标签、状态与未读角标 |
-| `Avatar` / `Card` / `Collapse` / `Tree` | 头像、卡片、折叠内容和层级数据 |
-| `Result` | 成功、警告、错误、信息与空数据结果 |
-| `TreeSelect` / `ColorPicker` | 层级选择、颜色与透明度选择 |
-| `Divider` / `Skeleton` / `Popover` | 内容分隔、加载占位和气泡卡片 |
-| `Slider` / `Rate` | 数值区间与评分输入 |
-| `Calendar` | 日历、日期选择与自定义日程 |
-| `Drawer` | 边缘抽屉,支持嵌套与表单操作 |
-| `Loading` / `Progress` / `Tooltip` | 加载、任务进度和文字说明 |
-| `Checkbox` | 多项选择与半选 |
-| `Radio` / `RadioGroup` | 单选与选项分组 |
-| `Switch` | 开关与加载状态 |
-| `Select` | 单选、多选和搜索,支持禁用选项与清除 |
-| `DatePicker` | 日期选择,支持最早 / 最晚日期 |
-| `TimePicker` | 24 / 12 小时制与秒选择 |
-| `AutoComplete` | 自由文本输入与动态建议 |
-| `Cascader` | 按层级选择完整路径 |
-| `Form` / `FormField` | 表单布局、自动标签宽度与校验反馈 |
-| `ConfigProvider` | 区域主题、自动派生尺寸、外观和中英文 |
-| `DateTimePicker` / `DateRangePicker` | 日期时间与多粒度起止区间 |
-| `Dropdown` | 操作菜单与键盘导航 |
-| `Modal` / `Confirm` | 弹窗与异步确认 |
-| `Alert` / `Message` / `useMessage` | 页内提示与短暂消息 |
-| `Layout` / `Grid` / `Row` / `Col` / `Space` / `ScrollArea` / `Masonry` | 页面布局、响应式栅格、间距、滚动与瀑布流 |
-| `Segmented` / `Menu` / `BackTop` | 分段切换、嵌套导航和回到顶部 |
-| `Descriptions` / `Timeline` / `QRCode` | 详情、事件和二维码 |
-| `Image` / `ImagePreviewGroup` / `ImagePreview` | 图片展示、缩放、图片组切换与全屏 |
-| `VirtualList` / `InfiniteScroll` | 大量数据和分页加载 |
-| `Transfer` / `InputOTP` / `InputMask` / `TimeRangePicker` | 穿梭选择、验证码、格式输入和时间范围 |
-| `Notification` / `useNotification` / `Popconfirm` / `ErrorBoundary` / `LoadingBar` / `useLoadingBar` | 通知、就地确认、异常恢复和任务进度 |
-| `Upload` / `FileList` / `ImageCropper` / `SignaturePad` | 文件上传、文件信息、图片裁剪和签名导出 |
-
-`Select` 的 onChange 返回字符串值与选项,多选时返回数组;`DatePicker` 返回 Date 或 null 及当前模式的日期字符串,支持日期、年、季度、月、周;`TimePicker` 返回 `HH:mm` 或 null;`AutoComplete` 返回输入文本;`Cascader` 返回路径数组与选项数组。
-
-设置 name 后,可通过 FormData 读取值。日期模式为 `YYYY-MM-DD`,其他日期粒度使用对应格式,时间为 `HH:mm`,级联路径为 JSON 数组字符串。非受控表单控件支持 form reset;受控组件需同时重置应用状态。为表单控件提供 label 或 aria-label。
-
-现有组件还提供 ButtonGroup / SplitButton、CheckboxGroup、AvatarGroup、CheckableTag / TagGroup、InputSearch / InputGroup、Textarea 自动高度、动态 FormList,以及 Select、Tree、TreeSelect、Tabs 的大数据、异步或排序能力。详细参数见组件文档。
-
-## 区域主题与语言
+支持 React **18 / 19**、现代浏览器与服务端渲染。推荐使用浏览器当前或上一代稳定版。
-```tsx
-import { ConfigProvider, DateTimePicker, Form, FormField } from '@ifhover/leaf-ui';
-
-
-
-
-```
+| Chrome | Edge | Firefox | Safari |
+| :-------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------: |
+| ≥ 109 | ≥ 109 | ≥ 121 | ≥ 16.4 |
-嵌套配置继承未设置的选项;浮层、确认框与消息沿用调用区域的主题和语言。ConfigProvider 自动托管确认框、消息、通知和顶部加载条,子组件直接调用相应 hook:
+以上为最低支持目标;各版本实测范围与功能降级见[浏览器兼容性](https://ifhover.github.io/leaf-ui/guide/compatibility.html),Next.js 等框架的接入见 [服务端渲染](https://ifhover.github.io/leaf-ui/guide/ssr.html)。
-```tsx
-import { Button, useMessage } from '@ifhover/leaf-ui';
+## 📦 安装
-export function SaveButton() {
- const { message } = useMessage();
- return message.success('保存成功')}>保存 ;
-}
+```bash
+pnpm add @ifhover/leaf-ui
```
-确认框同样直接使用:
+
+使用 npm / Yarn / Bun
-```tsx
-import { Button, useConfirm } from '@ifhover/leaf-ui';
-
-export function DeleteButton({ onDelete }: { onDelete: () => void | Promise }) {
- const { confirm } = useConfirm();
- return {
- if (await confirm({ title: '删除项目', children: '是否继续?', type: 'danger' })) {
- await onDelete();
- }
- }}>删除 ;
-}
+```bash
+npm install @ifhover/leaf-ui
+yarn add @ifhover/leaf-ui
+bun add @ifhover/leaf-ui
```
-将这些组件放在应用入口的 ConfigProvider 下即可。单独使用时可在入口选择 ConfirmProvider 或 MessageProvider。详细用法见[在线文档](https://ifhover.github.io/leaf-ui/)。
+
-通知和顶部加载条也由入口托管,子组件或自定义 hook 直接使用:
+需要在应用中安装 `react` 和 `react-dom`。组件提供编译后的 CSS,无需安装 Sass。
+
+## 🔨 快速使用
```tsx
-import { useLoadingBar, useNotification } from '@ifhover/leaf-ui';
-
-export function useProjectSave(saveProject: () => Promise) {
- const notification = useNotification();
- const loadingBar = useLoadingBar();
- return async () => {
- const finish = loadingBar.start();
- try {
- await saveProject();
- notification.success({ title: '保存成功', description: '项目内容已更新。' });
- } finally {
- finish();
- }
- };
+import { Button, DatePicker } from '@ifhover/leaf-ui';
+
+export default function App() {
+ return (
+ <>
+
+ 开始使用
+ >
+ );
}
```
-每个任务的完成函数相互独立,并发任务全部完成后才收起加载条。Upload 支持文件校验、进度、取消和重试;FileList 展示文件信息,预览图片与音视频。
+基础样式与所需的组件、服务样式会自动加载,无需手动导入 CSS。Vite、Rsbuild / Rspack 的生产构建支持根入口 ESM 具名导入的样式按需保留。直接使用 esbuild 或 CommonJS 时,可使用 `@ifhover/leaf-ui/button` 等子路径;自行管理 SSR 样式时可使用完整静态入口 `@ifhover/leaf-ui/styles/all.css`。
-## 主题定制
+单行控件默认高度为 **36px**,小 / 大尺寸为 **30 / 42px**。更多示例见[安装与快速开始](https://ifhover.github.io/leaf-ui/guide/getting-started.html)。
-使用 ConfigProvider 调整主题。只需给出基础圆角、高度和字号,其他尺寸自动生成;特殊需求通过可选的 tokens 覆盖。
+## 🎨 主题与语言
+
+使用 ConfigProvider 为应用或某个区域配置主题和语言:
```tsx
-
- 品牌按钮
-
-```
+import { ConfigProvider } from '@ifhover/leaf-ui';
+import App from './App';
-CSS 变量供业务组件读取:自己的按钮也可以使用 `var(--leaf-color-primary)`、`var(--leaf-radius)` 与 `var(--leaf-control-height)`,跟随所在区域的配置。
+export default function Root() {
+ return (
+
+
+
+ );
+}
+```
-服务端渲染使用同一份静态 CSS 和初始主题,动态切换无需重新生成样式。Next.js App Router、Pages Router 和其他框架的例子见 [SSR 使用](https://ifhover.github.io/leaf-ui/guide/ssr.html)。
+将 `locale` 改为 `en-US` 即可切换为英文;设置 `theme.appearance` 为 `dark` 可启用深色外观。嵌套配置继承未设置的选项,浮层和消息沿用所在区域的主题与语言。
-图标采用 [Lucide](https://lucide.dev/)。应用中需要使用图标时安装 `lucide-react`,然后通过具名导入将图标节点传给 Button 的 startIcon / endIcon 或 Input 的 prefix / suffix。
+了解[定制主题](https://ifhover.github.io/leaf-ui/guide/theming.html) · [ConfigProvider 主题与语言](https://ifhover.github.io/leaf-ui/components/config-provider.html)。
-## Git 与反馈
+## 🤖 AI 辅助开发
-公开仓库:[ifhover/leaf-ui](https://github.com/ifhover/leaf-ui)。问题与建议请提交至 [GitHub Issues](https://github.com/ifhover/leaf-ui/issues)。
+在应用目录安装 Leaf UI Skill,让 AI 按项目实际使用的版本查询组件 API:
```bash
-git clone https://github.com/ifhover/leaf-ui.git
+npx skills add ifhover/leaf-ui --skill leaf-ui
```
-源码维护、构建与文档站说明见 [开发文档](DEVELOPMENT.md)。
+安装与使用见 [AI 与 Skills](https://ifhover.github.io/leaf-ui/guide/ai.html)。在线文档顶部也可切换已发布版本。
+
+## 🤝 参与贡献
+
+欢迎通过 [Issues](https://github.com/ifhover/leaf-ui/issues) 反馈问题与建议,或提交 [Pull Request](https://github.com/ifhover/leaf-ui/pulls)。
+
+本地开发、项目结构与构建说明见 [开发文档](./DEVELOPMENT.md);提交组件或使用文档改动前,请阅读 [开发、版本与文档同步流程](./DEVELOPMENT-WORKFLOW.md)。
diff --git a/apps/docs/AGENTS.md b/apps/docs/AGENTS.md
new file mode 100644
index 00000000..b4ebb861
--- /dev/null
+++ b/apps/docs/AGENTS.md
@@ -0,0 +1,11 @@
+# 文档站 AI 协作约定
+
+本文件适用于 `apps/docs/`。修改文档、示例、主题或构建脚本前,必须阅读并遵守:
+
+- [开发、版本与文档同步流程](../../DEVELOPMENT-WORKFLOW.md):开发分支、正式版本、独立预览与清理。
+- [示例编写规则](EXAMPLE-WRITING.md):主站示例范围、布局、源码复用与验收。
+- [文档站维护说明](MAINTENANCE.md):运行、主题、导航、中英文、快照与 AI 文档。
+
+主站面向组件使用者。示例应简短、可运行,并直接体现 Leaf UI 的默认外观;复杂业务页面留给独立 example 站点。维护说明放在本目录的源码 Markdown 中,不放入会发布并进入搜索的 `docs/`。
+
+保留已有未提交工作。组件与使用文档变更在开发分支完成,合并与发布遵循仓库流程;报告实际执行的验证,未发布的工作不能称为已上线。
diff --git a/apps/docs/EXAMPLE-WRITING.md b/apps/docs/EXAMPLE-WRITING.md
new file mode 100644
index 00000000..1f6cfbbf
--- /dev/null
+++ b/apps/docs/EXAMPLE-WRITING.md
@@ -0,0 +1,46 @@
+# 文档示例编写规则
+
+本文件是 [AGENTS.md](AGENTS.md) 引用的必读约定,适用于主站组件和指南示例。
+
+## 内容范围
+
+每个示例说明一个明确的能力。基础用法先展示组件默认外观,再用独立示例说明尺寸、状态、受控值或必要的交互。状态对比应有清楚的名称。
+
+主站不编写完整的项目管理、权限工作台、十字段设置页或多步骤业务流程。复杂组合、装饰性封面和业务页面属于将来的独立 example 站点。展示 API 必需的本地状态、提交、重置和异步处理可以保留,但尽量使用最少的字段与数据。
+
+## 布局与样式
+
+- 示例容器 `ComponentExample` 默认在预览区水平、垂直居中,内容宽度为 **480px**;窄屏自动限制到可用宽度。用 `width={360}`、`width={600}` 或 `width="100%"` 调整单个示例。
+- 展示用宽度、居中和外围留白只写在 MDX 的 `ComponentExample` 配置中,不重复写进可复制示例源码。容器只控制外部展示,不改写组件圆角、字号、内边距、颜色和状态。
+- 只有一个触发按钮的浮层或服务示例使用 `width="fit-content"`,保持按钮自然宽度并居中;表单和对齐布局沿用默认宽度。
+- 组件排列使用公开的 `Flex`、`Space` 和 `Grid`。主轴对齐和换行使用 Flex;等间距组合使用 Space;分栏使用 Grid。
+- 表单标签、帮助信息和错误使用 `Form` / `FormField`,说明文字使用 `Text` / `Paragraph`,面板使用 `Card`。不手写相同的标签、面板或文字样式。
+- 主站示例不依赖 Tailwind 工具类、文档专属类名或隐藏样式文件。复制示例后,只安装 Leaf UI 及源码明确导入的依赖即可使用组件。
+- 只在表达当前能力必需时保留少量原生 `style`,例如滚动区域高度、浮层定位、动态颜色或实际演示的尺寸覆盖。不要用 CSS 装饰一个复杂场景来替代基础用法;需要大量 CSS 的内容移出主站。
+- 不通过源码过滤器删除布局或样式来制造简洁代码。预览组件与展示、复制、AI 导出的代码必须对应同一实现。
+
+## 源码与中英文
+
+中文示例位于 `src/examples//`,英文镜像位于 `src/examples/en//`。MDX 预览导入该组件,代码围栏的 `file` 引用相同的源码:
+
+````mdx
+import { ComponentExample } from '../../src/components/component-example';
+import { InputBasic } from '../../src/examples/input/basic';
+
+ } width={360} fileName="basic.tsx">
+
+```tsx lineNumbers file="../../src/examples/input/basic.tsx"
+```
+
+
+````
+
+不要再维护一份独立手抄的展示代码。语言专用的 `english` 参数和翻译判断由 `scripts/example-source.mjs` 消除;真实的语言切换状态继续保留。显示、复制和 AI Markdown 导出使用同样的处理。
+
+组件新增或 API 改变时,同步中英文页面、公共类型、侧边栏、总览元数据与 SVG 缩略图。API 默认值必须来自实际实现。
+
+## 验收
+
+按改动范围执行类型检查、文档测试、库和文档构建。新增公开组件还需检查根入口、子路径、声明、自动样式和 SSR。
+
+布局调整必须在浏览器验证中文、英文、桌面与窄屏、深浅外观及主题切换。检查预览溢出、控件交互、源码展开/收起和复制的一致性;仅构建通过不能报告视觉验收完成。
diff --git a/apps/docs/MAINTENANCE.md b/apps/docs/MAINTENANCE.md
new file mode 100644
index 00000000..daf3814e
--- /dev/null
+++ b/apps/docs/MAINTENANCE.md
@@ -0,0 +1,90 @@
+# 文档站维护说明
+
+本文件由 [AGENTS.md](AGENTS.md) 引用。示例写法遵循 [EXAMPLE-WRITING.md](EXAMPLE-WRITING.md),版本开发与发布遵循 [仓库流程](../../DEVELOPMENT-WORKFLOW.md)。
+
+## 运行与构建
+
+使用 Node.js 22.22.2+ / 24.15.0+ 的受支持 LTS,或 Node.js 26;pnpm 固定为 11.10.0。在仓库根目录运行:
+
+```bash
+pnpm install
+pnpm dev
+pnpm build:docs
+pnpm preview
+```
+
+开发和预览地址为 `http://127.0.0.1:3000`。Rspress 和 TypeScript 直接引用 `packages/react/src`,组件与 SCSS 修改会热更新。当前源码构建产物位于 `apps/docs/doc_build`。
+
+`LEAF_DOCS_BASE` 配置部署路径,默认 `/`。自定义站内链接用 `withBase` 并指向真实 `.html`,验证直接访问和刷新。
+
+## 内容、导航与主题
+
+`docs/guide`、`docs/components`、`docs/api` 面向使用者,英文镜像在 `docs/en`。首页、主题编辑器与预览容器在 `src/components`,示例在 `src/examples`,Rspress 主题在 `theme`。维护说明不得放到 `docs/`。
+
+导航在 `rspress.config.ts`,中英文指南和组件侧边栏使用各自路径键。组件名称使用实际导入名称,中文副标题写在 `tag` 中。新增组件同步 `src/components/component-catalog.ts`、`scripts/component-metadata.mjs` 和 `docs/public/components` 静态 SVG;总览不挂载所有交互实例。图标使用 `lucide-react` 具名导入,避免手绘运行时图标集合。
+
+顶部 API 导航使用独立 `/api/`、`/en/api/` 侧边栏。ConfigProvider 页面先介绍多语言、主题与外观、组件默认值,底部独立 API 章节集中放置 `ConfigProvider API`、`LeafTheme` 与类型参考;API 表格使用三级标题。完整 `LeafComponentDefaults`、`LeafThemeTokens` 分别放在 `api/component-defaults`、`api/theme-tokens`,通过链接查询。默认参数示例要直观展示占位文本等变化,并说明配置键的命名规则与实例覆盖。使用建议只保留简短、常见的注意事项。
+
+所有文档页使用相同的正文宽度和水平留白,不根据是否包含演示切换布局;首页保留独立的展示布局。同步修改 API 表格时保留所在标题层级,避免自动生成额外的主章节。
+
+阅读样式集中在 `theme/index.scss`:侧栏主文字 15px / 500、副标题 12px、行高 42px;顶栏 16px、代码 13px。侧栏分组标题吸顶,并保留 Rspress 展开/收起、路由与移动菜单。组件总览和详情页共用正文宽度与内边距。字体由 `@fontsource-variable/inter` 本地加载,中文用系统字体回退。
+
+组件总览顶部的输入框实时过滤组件目录,组件侧栏顶部的输入框独立过滤当前菜单;支持中英文名称和忽略大小写的匹配,清空后恢复全部内容。侧栏由 `docs-sidebar.tsx` 复用 Rspress `SidebarList`,搜索框位于独立滚动列表之外,分组标题仍在列表内吸顶。过滤时展开匹配分组,清空后保留原来的折叠状态;指南与 API 沿用原生侧栏。
+
+顶部导航、侧栏和右侧目录的选中与 hover 文字直接使用当前 `--leaf-color-primary`,不使用加深的派生文字色。侧栏分组标题的上边距与向上遮罩范围共用 `--rp-sidebar-padding`,避免遮住上一组最后一项的文字、选中背景和底部圆角。
+
+组件总览通过 `component-thumbnails.ts` 将仓库静态 SVG 作为文本内联,主色、插画色阶和中性表面消费当前区域的主题变量,保留状态与多色示意的语义。新增缩略图沿用现有色板,使用新色值时同步映射;渐变和裁剪 ID 自动按组件名称隔离。不要改回隔离主题变量的 ` `,也不要挂载全部交互组件。
+
+正文规则排除 `.rp-not-doc`。站点排版与组件 token 分开,不能覆盖预览或首页中组件的默认圆角、阴影、内边距与状态。搜索和主题按钮使用 Leaf UI Button;外观切换保留 Rspress ThemeContext、存储和键盘操作。
+
+`DocsThemeProvider` 通过外层 ConfigProvider 同步站点和示例主题色。`ThemeColorSwitcher` 使用 ColorPicker,配色存储在 `leaf-ui-docs-primary-color`,支持刷新、语言切换与同源标签页同步;静态 HTML 和初次渲染使用默认值,挂载后恢复存储。存储不可用时仍可切换。Rspress 搜索 portal 只同步根元素的站点强调色,组件色板由 ConfigProvider 生成;局部主题保持独立。
+
+首页、认识 Leaf UI 和快速开始共用 `PackageInstall`。包管理器偏好存储在 `leaf-ui-docs-package-manager`,支持刷新、页面与语言切换、同页实例和同源标签页同步;存储不可用时仍可切换。品牌图标使用 `data-no-zoom` 排除文档图片放大。指南的四种命令保留在 MDX 子内容中,Markdown 导出完整输出这些命令。
+
+配色入口、首页和主题编辑器共用 `src/components/theme-colors.ts`:绿色、黑色、橙色 `#ff6900`、蓝色 `#1d9bf0`、红色 `#cf0b2d`。深浅外观保留预设原色,实色按钮文字与 Switch 滑块为白色;浅底内容保持可读。主题编辑器把 HEX / RGB / HSL 归一为 HEX,生成代码含 `onPrimaryColor: '#fff'`。
+
+组件和站点主题使用 SCSS,由 `pluginSass` 编译。Tailwind 4 入口 `theme/tailwind.css` 只服务现有站点界面,不是组件示例的前置依赖;PostCSS 接入 `@tailwindcss/postcss`,扫描 `src`、`docs`、`theme`,不加载 Preflight,不使用全局 `!important`。组件行内布局通过公共参数调整。不要把 Tailwind 依赖加入组件包。
+
+## 示例容器
+
+ComponentExample 上方预览始终挂载,下方源码在构建时高亮;复制、换行、展开都读取同一份 MDX 源码。宽度配置和内容范围见 [示例规则](EXAMPLE-WRITING.md)。
+
+长代码默认折叠,短代码完整显示。展开使用测量高度与约 160ms 过渡;减少动态效果时直接切换。收起有渐变遮罩,展开后的收起按钮在当前源码内吸附视口底部;中途收起滚动回本示例代码顶部。外框使用 `overflow: clip`,避免阻断吸附。实现位于 `src/components/component-example.tsx` 与 `.scss`。
+
+## API 与 AI 文档
+
+```bash
+node apps/docs/scripts/sync-component-api.mjs
+pnpm test:docs
+pnpm test:skills
+```
+
+API 生成器从公共 TypeScript 导出更新中英文表格,保留人工说明与默认值;简单联合类型展开,公开数据类型链接到详情。可用 `--page=components/flex` 限定页面,用 `--from-ref=` 恢复历史说明。元数据与 AI 导出共用 `component-metadata.mjs`。
+
+两份全局配置参考也由 API 生成器同步,可分别使用 `--page=api/component-defaults`、`--page=api/theme-tokens`。没有独立默认值的参考表使用三列表头(属性、类型、说明),同步时保持三列。`documentationPage` 决定类型的唯一参考位置;AI 导出包含 `/api/` 页面及其版本标识,历史快照没有独立参考页时仍使用该快照原有的组件或指南页,不把新文档混入旧版本。
+
+`LeafComponentTokens`、`LeafThemeStyle` 的完整参考放在 `api/theme-tokens`,共享浮层参数 `PopupOptions` 放在 `api/popup-options`。定制主题指南按基础配置、深色模式、局部主题、密度与进阶覆盖递进,只链接完整参数。组件侧栏先放组件总览与使用图标;ConfigProvider 放在通用分组首项,中文副标题保留“全局配置”,最右侧另放蓝色“配置”标签(英文为“Config”),沿用指南 SSR 标签的原生样式。中文 `tag` 使用 Rspress 支持的逗号分隔多标签,第一项显示为副标题,最后一项保留标签样式。使用图标文档位于 `components/icons`,与总览同组。
+
+翻译资源参考位于 `api/translations`,ConfigProvider 页面保留简短说明与 JSON 示例。内置 JSON、Schema 和类型由组件包维护;`sync-locales.mjs` 在开发和构建前复制到忽略跟踪的 `docs/public/locales/`,AI 导出另从对应发布快照源码读取并复制到该版本根目录 `locales/`。旧快照缺少资源时不补入新版本词条。JSON 下载使用 ``,避免 Markdown 链接被 Rspress 转换成不存在的 `.json.html` 页面。
+
+API 类型单元格由 `scripts/api-type-display.mjs` 的 rehype 插件合并为一个行内代码容器,类型引用在容器内保持可点击并使用站点主题色;不能为标点和链接分别绘制代码底色。转换只作用于“类型 / Type”列,Markdown 源码、链接目标及 AI 导出保持原样。API 表格的说明列保留 240px 最小宽度,窄屏沿用表格内部横向滚动,避免说明被挤成过高的行。字段较多的高级 API 可使用 `leaf-api-details` 折叠表格,标题和类型锚点仍放在折叠容器外;不要隐藏主组件的常用参数表。
+
+Rspress 的 `llms: true` 输出页面 Markdown,`export-ai-docs.mjs` 输出 `api/index.json` 并写入准确包版本、提交和浏览器地址。每版根目录有 `llm.txt` / `llms.txt`;右侧 Markdown 链接必须指向当前版本。独立 Skill 维护见 [skills/README.md](../../skills/README.md)。
+
+## 正式站点与历史快照
+
+正式地址为 `https://ifhover.github.io/leaf-ui/`。`.github/workflows/pages.yml` 通过 GitHub Actions 部署 `site_build`,使用 `LEAF_DOCS_BASE=/leaf-ui/`。不提交静态产物和缓存。
+
+`pnpm build:versions` 从 npm 查询 `@ifhover/leaf-ui` 和历史包 `@sudden3/leaf-ui` 的已发布稳定版本、日期和 gitHead,经 `git archive` 还原发布提交,用对应源码、锁文件、示例与文档独立构建。需要完整 Git 历史。缺少提交、版本/包名不符、跨包重号、网络或权限错误、构建失败均中止部署。
+
+默认入口对应 npm latest,不跳转到版本目录;同一提交额外构建 `/v/X.Y.Z/`。两份产物分别使用自己的 base,不能复制带版本路径的页面充当根站点。新作用域首次正式发布前,默认仍展示历史包稳定版;历史快照保持原来的包名和 API。版本菜单读取 `versions.json`,切换保留页面和锚点,不存在时回退指南或组件总览。
+
+旧快照只补充版本导航和 AI 基础设施,组件实现、文档与示例保持发布提交。缓存 `.version-cache` 的键包含包名、提交、base 和基础设施摘要。修改 AI 导出的 import 后同步 `build-versioned-site.mjs` 的 `platformFiles` 及其直接依赖,并执行隔离快照测试。
+
+组件版本来自 `packages/react/package.json`;更新记录同步中英文,标题由 `pnpm check:release` 校验。未发布记录放在在线 `docs` 之外。npm、Git 标签、默认文档、固定快照和 AI 文档全部一致后才报告发布完成。
+
+## 开发预览
+
+开发分支可使用独立 `/dev//` 地址,展示开发状态、分支/提交和目标版本,使用独立资源、搜索与 base。稳定版本列表只记录 npm 正式版本;开发包使用 SemVer 预发布号和 `dev` 标签。
+
+当前 Pages 与 `build:versions` 没有自动开发预览部署/清理;配置 base 之外还需独立部署步骤。记录 URL、分支、提交、部署位置和清理方式。合并或放弃后删除预览、资源、入口与活动清单,保留清理证据;正式历史快照继续可访问。
diff --git a/apps/docs/README.md b/apps/docs/README.md
deleted file mode 100644
index 7b9cb2f6..00000000
--- a/apps/docs/README.md
+++ /dev/null
@@ -1,132 +0,0 @@
-# Leaf UI 文档站
-
-此目录使用 Rspress 编写 Leaf UI 的在线文档。在线内容只面向组件使用者;文档站运行、维护与仓库开发说明放在源码 Markdown 中。
-
-分支、版本同步和临时预览清理遵循 [开发、版本与文档同步流程](../../DEVELOPMENT-WORKFLOW.md)。默认在线文档、`main` 的组件与使用文档、npm `latest` 必须在发布完成时对应同一正式版本。
-
-## 运行环境
-
-Node.js 22.22.2+ / 24.15.0+ 的受支持 LTS 版本,或 Node.js 26;pnpm 11,工作区固定使用 11.10.0。
-
-在仓库根目录运行:
-
-```bash
-pnpm install
-pnpm dev
-```
-
-打开 `http://127.0.0.1:3000`。文档直接引用 `packages/react/src`,组件和 SCSS 修改会热更新,不需要预先构建组件包。
-
-## 构建与预览
-
-```bash
-pnpm build:docs
-pnpm preview
-```
-
-当前源码的预览产物位于 `apps/docs/doc_build`。`LEAF_DOCS_BASE` 控制部署路径,默认 `/`。自定义链接必须使用 withBase 并指向实际的 .html 文件,保证刷新和直接访问可用。
-
-## GitHub Pages
-
-在线站点:https://ifhover.github.io/leaf-ui/。仓库的 Pages 来源为 GitHub Actions,.github/workflows/pages.yml 在 main 推送或手动触发时检查源码、构建组件与当前文档,再构建已发布的历史版本,上传 `apps/docs/site_build`。构建设置 `LEAF_DOCS_BASE=/leaf-ui/`,不提交静态产物或缓存。
-
-## 版本快照与 AI 文档
-
-```bash
-pnpm build:versions
-```
-
-`scripts/build-versioned-site.mjs` 从 npm 注册表读取 `@ifhover/leaf-ui` 与历史包 `@sudden3/leaf-ui` 实际发布的稳定版本、发布日期和 `gitHead`。每个版本通过 `git archive` 在临时目录还原该发布提交,使用该提交的锁文件、组件源码、页面与示例独立构建。需要完整 Git 历史(CI 使用 `fetch-depth: 0`);缺少提交、包名或版本不匹配、跨包版本号重复或构建失败会中止部署。
-
-新包尚不存在或只有开发预发布时,默认文档保持旧包稳定版;新包正式发布后,默认入口使用新包的 `latest`。`versions.json` 顶层记录默认包名,每个版本条目记录其实际包名,旧版快照不会换成新作用域的安装命令或 API。新包注册表的网络错误与权限错误会中止构建,不会被当成尚未发布。
-
-默认地址 `/leaf-ui/` 直接展示 npm latest 指向的最新已发布文档,页面、资源和搜索都使用根地址,不跳转到版本路径。同一发布提交额外构建固定的 `/leaf-ui/v/X.Y.Z/` 快照供历史版本与 Skill 查询;两份构建使用各自 base,不能直接复制带版本路径的页面充当根站点。组件和使用文档在分支内开发,合并到 main 时完成新版本发布;构建器按 npm gitHead 部署,发布尚未完成时保留原稳定文档。顶部菜单从 `versions.json` 获取已发布列表,选择最新版返回根地址,旧版使用版本路径;切换时保留页面和锚点,目标没有该页面时回退对应指南或组件总览。
-
-旧快照只补充文档基础设施:版本菜单、AI 安装指南、Rspress Markdown 输出及 API 索引。基础设施的组件导入与安装提示使用该快照的包名;组件实现、例子与组件文档保持在发布提交。生成缓存位于 `.version-cache`,缓存键包含包名、发布提交、基础路径和基础设施文件摘要;修改基础设施会自动使缓存失效。
-
-Rspress `llms: true` 输出每页 Markdown,`scripts/export-ai-docs.mjs` 从各快照的公共导出建立 `api/index.json`,并为每页写入准确包版本、源码提交和浏览器地址。每版根目录提供 `llm.txt` 与标准 `llms.txt`,无需将完整手册放入 Skill。组件页面右侧的 Markdown 链接直接指向该版本的文本。
-
-维护 Skill 见 [skills/README.md](../../skills/README.md)。相关测试由 `pnpm test:docs` 和 `pnpm test:skills` 执行,均纳入 `pnpm check`。
-
-## 临时开发预览
-
-开发分支允许使用 `5.0-dev` 等名称部署独立在线预览,例如 `/leaf-ui/dev/5.0-dev/`。预览从对应分支提交构建,明确标记开发状态,使用自己的资源与搜索路径;稳定版版本列表仍只记录 npm 已发布的正式版本。
-
-当前 Pages 工作流与版本快照脚本尚未包含开发预览部署和自动清理;设置 `LEAF_DOCS_BASE` 后仍需独立部署步骤。分支合并到 `main` 或放弃开发后,必须删除该预览、资源和入口,正式发布验收包含清理结果。
-
-## 中英文文档
-
-中文页面位于 docs/guide 与 docs/components,英文镜像位于 docs/en。英文示例位于 src/examples/en;代码围栏与预览引用同一份源码。theme/Layout 按 Rspress useLang 设置 ConfigProvider 语言。组件侧边栏键需分别使用 /components/ 与 /en/components/,指南同理。
-
-组件总览数据在 src/components/component-catalog.ts;缩略图使用静态 SVG,新增资产可通过 scripts/generate-feedback-thumbnails.mjs 生成。
-
-## 内容与导航
-
-- `docs/guide/`:面向使用者的介绍、安装、快速开始、主题定制。
-- `docs/components/`:组件总览与各组件的使用/API 文档。
-- `docs/changelog.md` 与 `docs/en/changelog.md`:中英文版本更新记录。
-- `src/components/`:首页、主题编辑器、交互示例与示例容器。
-- `theme/`:Rspress 主题扩展和站点样式。
-
-`rspress.config.ts` 按路径分别配置指南和组件侧边栏。添加组件时同时更新总览、组件侧边栏和对应 MDX 页面。
-
-顶部版本号通过 Rspress 的 `afterNavTitle` 插槽展示,读取快照中的 `packages/react/package.json`,点击可切换已发布版本。每次 npm 发布都必须更新两份记录,具体步骤见 [发布文档](../../packages/react/RELEASING.md)。正式版本记录的标题格式由 `pnpm check:release` 校验,页面只记录已发布且面向使用者的变化,未发布草稿保留在 `docs` 目录之外。
-
-组件项的 text 使用实际导入名称,例如 DatePicker;tag 作为同一行的中文副标题,站点 SCSS 将其设置为更小、更浅的文字。不要在标题中拼接两种字号,或运行时修改 Rspress 的 DOM。
-
-导航与阅读样式集中在 `theme/index.scss`:侧栏主文字 15px、字重 500,中文副标题 12px,菜单行高 42px;顶部导航 16px,代码 13px。站点文字与组件预览的字体 token 分开调整,保持示例与实际组件一致。覆盖 Rspress 样式时使用布局作用域,确保当前项和悬停状态保持相同字号。语言入口复用 `theme/icons/languages.svg` 的 Lucide 图标,桌面和窄屏沿用 Rspress 的语言路由。
-
-字体由 `@fontsource-variable/inter` 本地打包加载,中文保留系统字体回退。首页的组件场景默认继承库的基础圆角和控件高度,只通过 `ConfigProvider` 切换主题色;不要再用站点 CSS 改写卡片圆角、阴影或内边距。正文排版规则排除 `.rp-not-doc`,保证可运行示例与实际组件一致。
-
-搜索和主题入口使用 Leaf UI `Button`。`SwitchAppearance` 保留 Rspress 的 `ThemeContext` 和主题存储,只替换交互控件,提供中英文的可访问名称和原生键盘操作;移动端沿用 Rspress 的菜单和路由。搜索文字在空间不足时省略,快捷键保持完整显示。
-
-不要将文档站运行命令、发布构建流程或仓库开发指南放入 `docs` 目录;其中的 Markdown 会成为在线页面并进入搜索索引。
-
-## 预览与代码模块
-
-首页的 HomeShowcase 提供组件、工作台和文件三种场景。组件场景在透明背景上以三列组织偏好表单、协作动态与空间创建,使用 34px 控件和按操作分组的按钮;窄屏按阅读顺序堆叠。工作台保留任务筛选、列表重排与两步弹窗。MotionGallery 展示选择、展开与保存反馈。示例中所有数据保存在本地 React 状态;保持中文/英文文案、窄屏和主题切换可用。ThemePlayground 同时展示表单控件和当前区域的动效开关。
-
-首页场景、主题编辑器与其颜色弹窗共用 `src/components/theme-colors.ts` 中的五种预设,顺序为主题绿、黑色、活力橙 `#ff6900`、亮蓝 `#1d9bf0` 和红色 `#cf0b2d`,默认绿色与组件库浅色主题一致。预设在深浅外观下均保持原色,实色按钮统一使用白色文字,Switch 滑块保持白色;浅底按钮、工作台选中菜单与分类标签保留可读的深色文字。编辑器将 ColorPicker 的 HEX / RGB / HSL 输出归一成 HEX,主题代码包含 `onPrimaryColor: '#fff'`。颜色选中圈及组件的选中、焦点和展开状态优先于 hover 样式。
-
-ComponentExample 在上方展示交互预览,下方同时展示源码,预览保持挂载。复制、换行和长代码展开行为读取同一份 MDX 高亮源码。通用示例布局(leaf-demo-*)和目录副标题样式位于 theme/index.scss,调整首页样式时必须保留这些共用规则。
-
-在 MDX 中使用 `ComponentExample`,将交互预览与源码包在同一个卡片内:
-
-````mdx
-import { ComponentExample } from '../../src/components/component-example';
-import { MyExample } from '../../src/components/my-example';
-
- } fileName="example.tsx">
-
-```tsx lineNumbers
-import { Button } from '@ifhover/leaf-ui';
-
-示例按钮
-```
-
-
-````
-
-预览节点单独放在 `preview` 属性中,子内容使用 MDX 代码围栏,可用 `file="../../src/examples/button/variants.tsx"` 直接引用实际预览源码,避免演示与代码脱节。语法高亮在构建时生成;示例容器负责折叠、复制完整源码和代码换行。
-
-长代码默认折叠;短代码会完整展示。样式与行为定义在 `src/components/component-example.tsx` 和 `src/components/component-example.scss`。
-
-展开 / 收起使用测量得到的源码高度,默认约 160ms;收起底部保留渐变遮罩,展开按钮独立显示,系统减少动态效果时直接切换。`scripts/example-source.mjs` 在高亮与 AI Markdown 导出时按预览的语言消除文档专用 `english` 参数和翻译判断;用户看到、复制和 AI 获取的代码保持一致。ConfigProvider 示例中真实的语言切换状态不属于文档参数,继续保留。
-
-仓库整体架构见 [DEVELOPMENT.md](../../DEVELOPMENT.md),组件开发约定见 [packages/react/DEVELOPMENT.md](../../packages/react/DEVELOPMENT.md)。
-
-## SCSS 与总览缩略图
-
-站点样式和示例模块使用 .scss,Rspress 的 builderConfig 启用 pluginSass。源码样式入口别名指向组件库的 src/styles/index.scss,消费者的 CSS 入口保持不变。
-
-总览位于 src/components/component-overview.tsx,采用静态 SVG 图片,资源保存在 docs/public/components。新增组件时更新卡片元数据和对应缩略图,无需在总览挂载交互组件。图标统一使用 lucide-react。
-
-选择类组件缩略图由 scripts/generate-picker-thumbnails.mjs 生成,包含静态控件与浮层示意,并复用 Lucide 图标;在此目录运行 `node scripts/generate-picker-thumbnails.mjs` 可重建。
-
-## API 与审计场景维护
-
-`node apps/docs/scripts/sync-component-api.mjs` 从公共 TypeScript 导出更新中英 API:简单联合类型直接展开,项目内对象类型链接到详细表格。生成器保留当前页面的人工说明与默认值,能够识别三列 / 四列表格与组合属性;`--from-ref=` 可恢复指定提交的说明。新增家族元数据在 scripts/component-metadata.mjs,AI 导出与 API 使用同一套页面映射。
-
-文档中的 API 表格默认值只写实际默认值;节点结构和回调信息无需制造默认值。每种示例要给出目的明确的标题或说明,不把不同状态挤成没有标识的一行。完整业务示例位于 src/examples/scenarios,包括复合字段 / 动态表单、Zod 校验与服务端错误、远程选项竞态。
-
-历史快照只复制版本导航和 AI 基础设施及其直接依赖。修改 export-ai-docs.mjs 的 import 后必须同步 build-versioned-site.mjs 的 platformFiles,并通过独立快照测试。未发布的新组件只进入工作区文档构建;线上与 `/v/` 仍按 npm gitHead 构建。
diff --git a/apps/docs/docs/api/component-defaults.mdx b/apps/docs/docs/api/component-defaults.mdx
new file mode 100644
index 00000000..6e9531ef
--- /dev/null
+++ b/apps/docs/docs/api/component-defaults.mdx
@@ -0,0 +1,151 @@
+# 组件默认参数
+
+通过 ConfigProvider 的 `components` 设置区域内的组件默认参数。常用示例、命名规则和继承方式见[组件默认值](/components/config-provider#组件默认值)。
+
+## LeafComponentDefaults
+
+所有配置项均可选。每项接受下表列出的参数,或用 `null` 清除继承;点击类型可查看参数含义及组件内置默认值。必填项、模式关联值、泛型数据和命令式引用仍由实例提供。
+
+| 属性 | 类型 | 说明 |
+| --- | --- | --- |
+| `Affix` | `Partial> \| null` | 设置 Affix。 |
+| `Alert` | `Partial> \| null` | 设置 Alert。 |
+| `Anchor` | `Partial> \| null` | 设置 Anchor。 |
+| `AppBar` | `Partial> \| null` | 设置 AppBar。 |
+| `AutoComplete` | `Partial> \| null` | 设置 AutoComplete。 |
+| `Avatar` | `Partial> \| null` | 设置 Avatar。 |
+| `AvatarGroup` | `Partial> \| null` | 设置 AvatarGroup。 |
+| `BackTop` | `Partial> \| null` | 设置 BackTop。 |
+| `Badge` | `Partial> \| null` | 设置 Badge。 |
+| `BottomNavigation` | `Partial> \| null` | 设置 BottomNavigation。 |
+| `Breadcrumb` | `Partial> \| null` | 设置 Breadcrumb。 |
+| `Button` | `Partial> \| null` | 按钮的默认参数。 |
+| `ButtonGroup` | `Partial> \| null` | 设置 ButtonGroup。 |
+| `Calendar` | `Partial> \| null` | 设置 Calendar。 |
+| `Card` | `Partial> \| null` | 设置 Card。 |
+| `Carousel` | `Partial> \| null` | 设置 Carousel。 |
+| `Cascader` | `Partial< Omit< `[`CascaderProps`](../components/cascader#cascader-api)`, 'key' \| 'ref' \| 'options' \| 'multiple' \| 'value' \| 'defaultValue' \| 'onChange' > > \| null` | 设置 Cascader。 |
+| `CheckableTag` | `Partial> \| null` | 设置 CheckableTag。 |
+| `Checkbox` | `Partial> \| null` | 设置 Checkbox。 |
+| `CheckboxGroup` | `Partial> \| null` | 设置 CheckboxGroup。 |
+| `Col` | `Partial> \| null` | 设置 Col。 |
+| `Collapse` | `Partial> \| null` | 设置 Collapse。 |
+| `ColorPicker` | `Partial> \| null` | 设置 ColorPicker。 |
+| `CommandPalette` | `Partial> \| null` | 设置 CommandPalette。 |
+| `Confirm` | `Partial> \| null` | 设置 Confirm。 |
+| `Countdown` | `Partial> \| null` | 设置 Countdown。 |
+| `DataTable` | `Partial> \| null` | 设置 DataTable。 |
+| `DataTableColumnVisibility` | `Partial> \| null` | 设置 DataTableColumnVisibility。 |
+| `DataTableContent` | `Partial> \| null` | 设置 DataTableContent。 |
+| `DataTableFooter` | `Partial, 'key' \| 'ref'>> \| null` | 设置 DataTableFooter。 |
+| `DataTablePagination` | `Partial> \| null` | 设置 DataTablePagination。 |
+| `DataTableSearch` | `Partial> \| null` | 设置 DataTableSearch。 |
+| `DataTableToolbar` | `Partial, 'key' \| 'ref'>> \| null` | 设置 DataTableToolbar。 |
+| `DatePicker` | `Partial< Omit<`[`DatePickerProps`](../components/date-picker#datepicker-api)`, 'key' \| 'ref' \| 'multiple' \| 'value' \| 'defaultValue' \| 'onChange'> > \| null` | 设置 DatePicker。 |
+| `DateRangePicker` | `Partial> \| null` | 设置 DateRangePicker。 |
+| `DateTimePicker` | `Partial> \| null` | 设置 DateTimePicker。 |
+| `Descriptions` | `Partial> \| null` | 设置 Descriptions。 |
+| `Divider` | `Partial> \| null` | 设置 Divider。 |
+| `Drawer` | `Partial> \| null` | 设置 Drawer。 |
+| `Dropdown` | `Partial> \| null` | 设置 Dropdown。 |
+| `Empty` | `Partial> \| null` | 设置 Empty。 |
+| `ErrorBoundary` | `Partial> \| null` | 设置 ErrorBoundary。 |
+| `FileList` | `Partial> \| null` | 设置 FileList。 |
+| `Flex` | `Partial> \| null` | 设置 Flex。 |
+| `FloatButton` | `Partial> \| null` | 设置 FloatButton。 |
+| `FloatButtonGroup` | `Partial> \| null` | 设置 FloatButtonGroup。 |
+| `Form` | `Partial> \| null` | 设置 Form。 |
+| `FormErrorSummary` | `Partial> \| null` | 设置 FormErrorSummary。 |
+| `FormField` | `Partial> \| null` | 设置 FormField。 |
+| `FormGroup` | `Partial> \| null` | 设置 FormGroup。 |
+| `FormList` | `Partial< Omit< `[`FormListProps`](../components/form#formlistprops-api)`, 'name' \| 'children' \| 'value' \| 'defaultValue' \| 'onChange' \| 'itemKey' > > \| null` | 设置 FormList。 |
+| `Grid` | `Partial> \| null` | 设置 Grid。 |
+| `Image` | `Partial> \| null` | 设置 Image。 |
+| `ImagePreview` | `Partial< Omit<`[`ImagePreviewProps`](../components/image#imagepreviewprops-api)`, 'key' \| 'ref' \| 'items' \| 'open' \| 'onClose'> > \| null` | 设置 ImagePreview。 |
+| `ImagePreviewGroup` | `Partial> \| null` | 设置 ImagePreviewGroup。 |
+| `InfiniteScroll` | `Partial< Omit<`[`InfiniteScrollProps`](../components/infinite-scroll#infinitescrollprops-api)`, 'key' \| 'ref' \| 'dataLength' \| 'hasMore' \| 'onLoadMore'> > \| null` | 设置 InfiniteScroll。 |
+| `Input` | `Partial> \| null` | 输入框的默认参数,InputSearch 也继承这些输入参数。 |
+| `InputGroup` | `Partial> \| null` | 设置 InputGroup。 |
+| `InputMask` | `Partial> \| null` | 设置 InputMask。 |
+| `InputNumber` | `Partial< Omit< `[`InputNumberProps`](../components/input-number#inputnumber-api)`, 'key' \| 'ref' \| 'stringMode' \| 'value' \| 'defaultValue' \| 'onChange' \| 'min' \| 'max' \| 'step' > > \| null` | 设置 InputNumber。 |
+| `InputOTP` | `Partial> \| null` | 设置 InputOTP。 |
+| `InputSearch` | `Partial> \| null` | 搜索框默认参数,优先于 Input 配置。 |
+| `Layout` | `Partial> \| null` | 设置 Layout。 |
+| `LayoutContent` | `Partial, 'key' \| 'ref'>> \| null` | 设置 LayoutContent。 |
+| `LayoutFooter` | `Partial, 'key' \| 'ref'>> \| null` | 设置 LayoutFooter。 |
+| `LayoutHeader` | `Partial, 'key' \| 'ref'>> \| null` | 设置 LayoutHeader。 |
+| `LayoutSider` | `Partial> \| null` | 设置 LayoutSider。 |
+| `Link` | `Partial> \| null` | 设置 Link。 |
+| `Loading` | `Partial> \| null` | 设置 Loading。 |
+| `LoadingBar` | `Partial> \| null` | 设置 LoadingBar。 |
+| `Masonry` | `Partial> \| null` | 设置 Masonry。 |
+| `Mentions` | `Partial> \| null` | 设置 Mentions。 |
+| `Menu` | `Partial> \| null` | 设置 Menu。 |
+| `Message` | `Partial> \| null` | 设置 Message。 |
+| `Modal` | `Partial> \| null` | 弹窗默认参数。 |
+| `Notification` | `Partial> \| null` | 设置 Notification。 |
+| `Pagination` | `Partial> \| null` | 设置 Pagination。 |
+| `Paragraph` | `Partial> \| null` | 设置 Paragraph。 |
+| `Popconfirm` | `Partial> \| null` | 设置 Popconfirm。 |
+| `Popover` | `Partial> \| null` | 设置 Popover。 |
+| `Progress` | `Partial> \| null` | 设置 Progress。 |
+| `QRCode` | `Partial> \| null` | 设置 QRCode。 |
+| `Radio` | `Partial> \| null` | 设置 Radio。 |
+| `RadioGroup` | `Partial> \| null` | 设置 RadioGroup。 |
+| `Rate` | `Partial> \| null` | 设置 Rate。 |
+| `Result` | `Partial> \| null` | 设置 Result。 |
+| `Row` | `Partial> \| null` | 设置 Row。 |
+| `ScrollArea` | `Partial> \| null` | 设置 ScrollArea。 |
+| `Scrollbar` | `Partial> \| null` | 设置 Scrollbar。 |
+| `Segmented` | `Partial> \| null` | 设置 Segmented。 |
+| `Select` | `Partial< Omit< `[`SelectProps`](../components/select#select-api)`, 'key' \| 'ref' \| 'options' \| 'multiple' \| 'value' \| 'defaultValue' \| 'onChange' > > \| null` | 选择器默认参数;模式、值与变更回调仍由实例设置。 |
+| `Skeleton` | `Partial> \| null` | 设置 Skeleton。 |
+| `Slider` | `Partial< Omit<`[`SliderProps`](../components/slider#slider-api)`, 'key' \| 'ref' \| 'range' \| 'value' \| 'defaultValue' \| 'onChange'> > \| null` | 设置 Slider。 |
+| `Space` | `Partial> \| null` | 设置 Space。 |
+| `SplitButton` | `Partial> \| null` | 设置 SplitButton。 |
+| `Splitter` | `Partial> \| null` | 设置 Splitter。 |
+| `Statistic` | `Partial> \| null` | 设置 Statistic。 |
+| `Steps` | `Partial> \| null` | 设置 Steps。 |
+| `Switch` | `Partial> \| null` | 设置 Switch。 |
+| `Table` | `Partial> \| null` | 设置 Table。 |
+| `TableBody` | `Partial, 'key' \| 'ref'>> \| null` | 设置 TableBody。 |
+| `TableCaption` | `Partial, 'key' \| 'ref'>> \| null` | 设置 TableCaption。 |
+| `TableCell` | `Partial> \| null` | 设置 TableCell。 |
+| `TableColumnHeader` | `Partial> \| null` | 设置 TableColumnHeader。 |
+| `TableEmpty` | `Partial> \| null` | 设置 TableEmpty。 |
+| `TableError` | `Partial> \| null` | 设置 TableError。 |
+| `TableFooter` | `Partial, 'key' \| 'ref'>> \| null` | 设置 TableFooter。 |
+| `TableHeader` | `Partial, 'key' \| 'ref'>> \| null` | 设置 TableHeader。 |
+| `TableLoading` | `Partial> \| null` | 设置 TableLoading。 |
+| `TableRow` | `Partial> \| null` | 设置 TableRow。 |
+| `Tabs` | `Partial> \| null` | 设置 Tabs。 |
+| `Tag` | `Partial> \| null` | 设置 Tag。 |
+| `TagGroup` | `Partial> \| null` | 设置 TagGroup。 |
+| `Text` | `Partial> \| null` | 设置 Text。 |
+| `Textarea` | `Partial> \| null` | 设置 Textarea。 |
+| `Timeline` | `Partial> \| null` | 设置 Timeline。 |
+| `TimePicker` | `Partial> \| null` | 设置 TimePicker。 |
+| `TimeRangePicker` | `Partial> \| null` | 设置 TimeRangePicker。 |
+| `Title` | `Partial> \| null` | 设置 Title。 |
+| `Toolbar` | `Partial> \| null` | 设置 Toolbar。 |
+| `Tooltip` | `Partial> \| null` | 设置 Tooltip。 |
+| `Tour` | `Partial> \| null` | 设置 Tour。 |
+| `Transfer` | `Partial> \| null` | 设置 Transfer。 |
+| `Tree` | `Partial> \| null` | 设置 Tree。 |
+| `TreeSelect` | `Partial< Omit< `[`TreeSelectProps`](../components/tree-select#treeselect-api)`, \| 'key' \| 'ref' \| 'options' \| 'multiple' \| 'treeCheckable' \| 'value' \| 'defaultValue' \| 'onChange' > > \| null` | 设置 TreeSelect。 |
+| `Typography` | `Partial> \| null` | 设置 Typography。 |
+| `Upload` | `Partial> \| null` | 设置 Upload。 |
+| `VirtualList` | `(Partial< Omit<`[`VirtualListProps`](../components/virtual-list#virtuallistprops-api)`, 'items' \| 'itemKey' \| 'renderItem' \| 'estimateSize'> > & { estimateSize?: number }) \| null` | 设置 VirtualList。 |
+
+## 类型导入
+
+```tsx
+import type { LeafComponentDefaults } from '@ifhover/leaf-ui';
+
+const components = {
+ Button: { variant: 'outline' },
+ Confirm: { confirmText: '继续', cancelText: '返回' },
+} satisfies LeafComponentDefaults;
+```
+
+将该对象传给 ``。实例参数和服务的单次调用参数仍优先于区域默认值。
diff --git a/apps/docs/docs/api/index.mdx b/apps/docs/docs/api/index.mdx
new file mode 100644
index 00000000..6f2a2115
--- /dev/null
+++ b/apps/docs/docs/api/index.mdx
@@ -0,0 +1,14 @@
+# API 参考
+
+这里提供全局配置的完整字段,方便有进阶需求时查询。常用写法和可运行示例见 [ConfigProvider](/components/config-provider)。
+
+## 全局配置
+
+| 参考 | 用途 |
+| --- | --- |
+| [LeafComponentDefaults](./component-defaults#leafcomponentdefaults) | 可配置的组件名称和默认参数范围。 |
+| [LeafThemeTokens](./theme-tokens#leafthemetokens) | 单独覆盖主题自动生成的样式。 |
+| [PopupOptions](./popup-options#popupoptions) | 选择器与浮层共用的挂载容器、位置和内容定制参数。 |
+| [翻译资源](./translations) | 补充自定义语言、设置回退顺序并检查 JSON。 |
+
+各组件自身的参数、默认值和示例仍在对应组件文档中查询。
diff --git a/apps/docs/docs/api/popup-options.mdx b/apps/docs/docs/api/popup-options.mdx
new file mode 100644
index 00000000..8ded4645
--- /dev/null
+++ b/apps/docs/docs/api/popup-options.mdx
@@ -0,0 +1,15 @@
+# PopupOptions
+
+Select、日期与时间选择器等组件共用的浮层参数。单个组件的配置优先于 ConfigProvider 的 `getPopupContainer`;Modal、Drawer 的挂载容器参数名为 `container`。
+
+## PopupOptions
+
+| 属性 | 类型 | 说明 |
+| --- | --- | --- |
+| `popupPlacement` | `'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | 浮层相对触发控件的位置。 |
+| `popupClassName` | `string` | 浮层的自定义类名。 |
+| `popupStyle` | `CSSProperties` | 浮层的自定义样式。 |
+| `popupRender` | `(content: React.ReactNode) => React.ReactNode` | 包装或补充面板内容,保留传入的内容以维持交互。 |
+| `getPopupContainer` | `() => Element \| DocumentFragment` | 返回浮层的挂载容器,也可返回 ShadowRoot。 |
+
+容器应在交互前挂载,并避免裁剪浮层。通过函数延迟访问 DOM;使用 ShadowRoot 时,也需在对应的影子根内加载组件样式。各组件的默认位置和附加选项见对应组件文档。
diff --git a/apps/docs/docs/api/theme-tokens.mdx b/apps/docs/docs/api/theme-tokens.mdx
new file mode 100644
index 00000000..9cab2a22
--- /dev/null
+++ b/apps/docs/docs/api/theme-tokens.mdx
@@ -0,0 +1,97 @@
+# 主题变量
+
+日常定制优先设置 ConfigProvider 的 `theme.primaryColor`、`theme.borderRadius` 和 `theme.controlHeight`,其他样式会自动派生,见[定制主题](/guide/theming)。
+
+## LeafThemeTokens
+
+需要单独调整某个派生值时,再通过 `theme.tokens` 覆盖。所有字段均可选,嵌套区域继承未设置的字段。长度为数字时按 px 处理,动效时长为数字时按 ms 处理。
+
+| 属性 | 类型 | 默认值 | 说明 |
+| --- | --- | --- | --- |
+| `onPrimaryColor` | `string` | 按主题生成 | 主题背景上的文字色 |
+| `dangerColor` | `string` | 按外观生成 | 危险色 / 危险背景上的文字色 |
+| `onDangerColor` | `string` | 按外观生成 | 危险色 / 危险背景上的文字色 |
+| `successColor` | `string` | 按外观生成 | 成功 / 警告 / 信息颜色 |
+| `warningColor` | `string` | 按外观生成 | 成功 / 警告 / 信息颜色 |
+| `infoColor` | `string` | 按外观生成 | 成功 / 警告 / 信息颜色 |
+| `textColor` | `string` | 按外观生成 | 主要 / 次要文字 |
+| `mutedTextColor` | `string` | 按外观生成 | 主要 / 次要文字 |
+| `subtleTextColor` | `string` | — | 更轻的辅助文字色。 |
+| `surfaceColor` | `string` | 按外观生成 | 表面 / 次级表面 |
+| `mutedSurfaceColor` | `string` | 按外观生成 | 表面 / 次级表面 |
+| `raisedSurfaceColor` | `string` | — | 浮层与抬升表面色。 |
+| `borderColor` | `string` | 按外观生成 | 中性边框 |
+| `borderHoverColor` | `string` | — | 悬停时的中性边框色。 |
+| `dividerColor` | `string` | — | 分区分隔线颜色;默认从边框和表面颜色派生。 |
+| `borderRadiusSm` | `number \| string` | `基础圆角 × 0.6` | 单独覆盖小 / 大圆角 |
+| `borderRadiusMd` | `number \| string` | `基础圆角 × 1.2` | 单独覆盖卡片、提示等内容表面的中圆角 |
+| `borderRadiusLg` | `number \| string` | 基础圆角 × 1.6 | 单独覆盖大圆角 |
+| `controlHeightSm` | `number \| string` | 基础高度 − 6px,最小 1px | 单独覆盖小尺寸控件高度 |
+| `controlHeightLg` | `number \| string` | 基础高度 + 6px | 单独覆盖大尺寸控件高度 |
+| `fontSizeSm` | `number \| string` | `基础字号 − 1px` | 单独覆盖小 / 大字号 |
+| `fontSizeLg` | `number \| string` | 基础字号 + 2px | 单独覆盖大字号 |
+| `fontWeight` | `number` | `500` | 按钮、标签与组件标题的强调字重 |
+| `motionDuration` | `number \| string` | `200` | 基础过渡时间;数字为 ms,也支持 CSS 时间。motion=false 时为 0。 |
+| `motionEasing` | `string` | `'cubic-bezier(0.22, 1, 0.36, 1)'` | 悬停、内容与普通过渡的曲线。 |
+| `motionSpring` | `string` | `'cubic-bezier(0.22, 1.28, 0.36, 1)'` | 选择与形状变化的轻微弹性曲线。 |
+| `popupZIndex` | `number` | `1000` | 浮层 / 弹窗 / 消息层级 |
+| `modalZIndex` | `number` | `1100` | 浮层 / 弹窗 / 消息层级 |
+| `messageZIndex` | `number` | `1200` | 浮层 / 弹窗 / 消息层级 |
+| `buttonBorderRadius` | `number \| string` | 当前控件尺寸 | 仅按钮的圆角 / 共用高度覆盖 |
+| `buttonHeight` | `number \| string` | 当前控件尺寸 | 仅按钮的圆角 / 共用高度覆盖 |
+| `choiceBorderRadius` | `number \| string` | 基础圆角 × 0.5 | 复选框圆角 |
+| `focusColor` | `string` | 当前语义色自动生成 | 焦点轮廓颜色 |
+| `primaryHoverColor` | `string` | 主题色自动生成 | 主色悬停 / 按下 |
+| `primaryActiveColor` | `string` | 主题色自动生成 | 主色悬停 / 按下 |
+| `primarySoftColor` | `string` | 主题色自动生成 | 主色柔和背景与交互状态 |
+| `primarySoftHoverColor` | `string` | 主题色自动生成 | 主色柔和背景与交互状态 |
+| `primarySoftActiveColor` | `string` | 主题色自动生成 | 主色柔和背景与交互状态 |
+| `primaryBorderColor` | `string` | 主题色自动生成 | 主题色边框 |
+| `dangerHoverColor` | `string` | 危险色自动生成 | 危险状态悬停 / 按下 |
+| `dangerActiveColor` | `string` | 危险色自动生成 | 危险状态悬停 / 按下 |
+| `spacingSm` | `number \| string` | — | 设置 spacingSm。 |
+| `spacingLg` | `number \| string` | — | 设置 spacingLg。 |
+| `shadowSm` | `string` | — | 设置 shadowSm。 |
+| `shadowXs` | `string` | — | 最轻的表面阴影。 |
+| `shadowMd` | `string` | — | 设置 shadowMd。 |
+| `shadowLg` | `string` | — | 设置 shadowLg。 |
+| `lineHeight` | `number` | — | 正文行高。 |
+
+## 类型导入
+
+```tsx
+import type { LeafThemeTokens } from '@ifhover/leaf-ui';
+
+const tokens = {
+ controlHeightSm: 28,
+ borderRadiusLg: 14,
+} satisfies LeafThemeTokens;
+```
+
+将该对象传给 ``。
+
+## LeafComponentTokens
+
+供 `theme.components` 按组件名称覆盖样式。各组件支持的字段以组件文档为准。
+
+| 属性 | 类型 | 说明 |
+| --- | --- | --- |
+| `borderRadius` | `string \| number` | 圆角;数字表示像素。 |
+| `controlHeight` | `string \| number` | 控件高度;数字表示像素。 |
+| `padding` | `string \| number` | 内容内边距。 |
+| `gap` | `string \| number` | 子项之间的间距。 |
+| `fontSize` | `string \| number` | 字号;数字表示像素。 |
+| `color` | `string` | 颜色或语义色。 |
+| `background` | `string` | 组件表面背景。 |
+| `borderColor` | `string` | 外层边框与分区分隔线颜色。 |
+| `headerBackground` | `string` | 标题区域背景。 |
+| `footerBackground` | `string` | 底部操作区域背景。 |
+| `shadow` | `string` | CSS box-shadow 的值。 |
+
+## LeafThemeStyle
+
+带 `--leaf-*` 自定义属性的 React 样式类型。业务 CSS 读取变量的示例见 [定制主题](/guide/theming#在业务样式中使用主题)。
+
+| 属性 | 类型 | 说明 |
+| --- | --- | --- |
+| `` [key: `--leaf-${string}`] `` | `string \| number \| undefined` | 可复用的 CSS 自定义属性。 |
diff --git a/apps/docs/docs/api/translations.mdx b/apps/docs/docs/api/translations.mdx
new file mode 100644
index 00000000..de5bfd21
--- /dev/null
+++ b/apps/docs/docs/api/translations.mdx
@@ -0,0 +1,98 @@
+import { withBase } from '@rspress/core/runtime';
+
+# 翻译资源
+
+通过 ConfigProvider 的 `translations` 补充语言,`locale` 决定当前语言与回退顺序。[查看可运行示例](/components/config-provider#补充自己的语言)。
+
+## 从 JSON 开始
+
+复制完整英文模板 ,按原有键翻译内容。模板与组件实际使用的资源一致,也可从安装的包中读取:
+
+```ts
+import enUS from '@ifhover/leaf-ui/locales/en-US.json';
+```
+
+内置的 `zh-CN.json`、`zh-TW.json`、`ja-JP.json`、`ko-KR.json` 使用同一路径。使用内置语言只需设置 `locale`,无需导入这些文件。JSON 只保存文本;对象按组件分组,通用动作在 `common` 中。不需要注册或调用辅助函数。
+
+以下用火星文演示自定义资源,`zh-CN-x-mars` 是私用语言标记,日期和数字按简体中文格式显示:
+
+```tsx
+import { ConfigProvider } from '@ifhover/leaf-ui';
+import mars from './locales/zh-CN-x-mars.json';
+
+const translations = { 'zh-CN-x-mars': mars };
+
+
+
+ ;
+```
+
+## 回退与继承
+
+| 情况 | 行为 |
+| --- | --- |
+| `locale="zh-CN-x-mars"` | 等价于 `['zh-CN-x-mars']`;缺词时回退内置英文 |
+| `locale={['zh-CN-x-mars', 'zh-CN']}` | 每个词条先找火星文,再找简体中文,最后找内置英文 |
+| 第一项语言 | 决定区域的 `lang`、日期和数字的 Intl 格式,不随单个词条回退而变化 |
+| 覆盖内置语言 | 提供同名语言资源,只覆盖写出的词条 |
+| 嵌套 `translations` | 按语言、分组和词条合并,内层覆盖外层 |
+| 嵌套 `locale` | 未传则继承,传入后替换整条链,不拼接 |
+| 空字符串 | 保留为空;只有缺失或 `undefined` 才继续回退 |
+| 星期数组 | 完整替换,固定为周一到周日的 7 项;`weekStartsOn` 决定显示顺序 |
+
+语言代码使用有效的 BCP 47 标签;空数组或无效标签会抛出错误。需要 `fr-CA → fr` 时显式写出这两项。最终英文兜底始终使用库内置资源,若需自定义英文也参与查找,请把 `en-US` 放进链中。
+
+组件实例参数与 `components` 提供的文字优先于翻译资源。业务内容由应用翻译。翻译不会自动改变 `direction` 或 `weekStartsOn`,需要时单独设置。
+
+## 动态文本
+
+句子使用 ICU MessageFormat 占位符,译者可以调整完整语序,也可以定义复数:
+
+```json
+{
+ "pagination": {
+ "total": "{total, plural, one {# item} other {# items}}"
+ }
+}
+```
+
+保留英文模板中的变量名,例如 `{total}`、`{label}`。复数规则使用实际提供该词条的语言。模板无效时该句回退内置英文,开发环境会输出对应词条的警告;内容作为普通文本渲染。
+
+## 检查翻译
+
+安装包提供 JSON Schema ,编辑器可将它关联到翻译文件。也可在 JSON 顶层添加 `$schema` 指向本地安装包的 `dist/locales/schema.json`,运行时会忽略此字段。
+
+检查未知键、遗漏和 ICU 变量:
+
+```bash
+pnpm exec leaf-ui-check-translations ./locales/zh-CN-x-mars.json --allow-partial
+```
+
+有意只翻译部分词条时使用 `--allow-partial`。此时仍检查结构、拼写和变量,缺失项只输出清单。组件升级后重新检查,可找到需要补充的词条。
+
+## 类型
+
+```ts
+import type { LeafTranslation, LeafTranslations } from '@ifhover/leaf-ui';
+
+const mars = {
+ select: { placeholder: '挑①個唄' },
+} satisfies LeafTranslation;
+
+const translations = { 'zh-CN-x-mars': mars } satisfies LeafTranslations;
+```
+
+### LeafTranslations
+
+| 属性 | 类型 | 说明 |
+| --- | --- | --- |
+| `[languageTag]` | [`LeafTranslation`](#leaftranslation) | 该语言的部分或完整翻译;标签大小写会按 BCP 47 规范化 |
+
+### LeafTranslation
+
+| 属性 | 类型 | 说明 |
+| --- | --- | --- |
+| `[group]` | `Partial>` | 英文模板定义的分组和词条,例如 `common.confirm`、`select.placeholder`;类型提示限制为实际存在的键 |
+| `$schema` | `string` | 可选的编辑器校验路径,不参与运行时翻译 |
+
+翻译资源是只读配置;更新时传入新对象。资源保留在当前 Provider 内,不写入全局注册表。SSR 时服务端与客户端传入相同的语言链、JSON 和初始值,详见 [服务端渲染](/guide/ssr)。
diff --git a/apps/docs/docs/changelog.md b/apps/docs/docs/changelog.md
index f503ee8e..a0bb8827 100644
--- a/apps/docs/docs/changelog.md
+++ b/apps/docs/docs/changelog.md
@@ -1,6 +1,5 @@
---
-pageType: doc-wide
-sidebar: false
+sidebar: placeholder
footer: false
---
@@ -8,6 +7,32 @@ footer: false
记录每个 npm 版本的新增功能、体验改进与问题修复。
+## 0.6.0 - 2026-10-16
+
+### 新增
+
+- `ConfigProvider.components` 为公开组件、复合组件部件及 Confirm API 提供区域默认参数。实例优先于内层、外层配置;`undefined` 继承,组件配置项的 `null` 清除继承。配置更新保留非受控值、DOM、焦点与表单语义。
+- 多语言配置支持 BCP 47 语言代码、显式回退链和自定义 `translations` JSON,内置简体中文、繁体中文、英文、日文与韩文。动态文案支持 ICU 变量与复数,提供翻译类型、JSON Schema、五种语言资源及 `leaf-ui-check-translations` 检查命令。
+- 新增 `Flex` 布局组件,以及 Tailwind CSS 3 preset `@ifhover/leaf-ui/tailwind` 和 Tailwind CSS 4 主题入口 `@ifhover/leaf-ui/tailwind.css`,复用区域颜色、尺寸、间距与动效变量。
+- Card 新增大尺寸和内嵌 `tabs`;FileList 提供文本、图片列表和图片卡片布局;Pagination 新增 `outline` / `ghost` 外观,`showTotal` 支持直接显示本地化总数。
+
+### 改进与修复
+
+- 默认控件高度统一为 36px,小、大尺寸为 30px / 42px,紧凑密度以 30px 为基准;表单、日期时间面板、虚拟列表估算和卡片式 Tabs 同步尺寸规则。
+- 浏览器入口自动加载共享基础样式与使用到的组件样式,无需手动导入 CSS;保留不加载 CSS 的 Node 入口与完整静态样式入口,并完善 Next.js、TanStack Start 与服务端渲染说明。
+- 统一选择器的中性候选背景、多选标签换行与折叠、菜单和 Tab 圆角、卡片层次、无边框标签及分页反馈。Tabs 内容立即切换,选中指示器保留移动动效。
+- 修复 FormField 校验后首次输入丢失、Tabs 选中文字未跟随主题色、TreeSelect 展开状态与选项点击、选择器重开光标和窄屏多选布局等问题。
+- 修复分页快速跳转与点击其他分页操作相互覆盖、页码和每页条数重复回调的问题;内部按钮与输入控件不再被其他公开组件的区域默认参数误改为提交、只读或禁用。
+- 重整中英文介绍、快速开始、主题、多语言、API 参考与基础示例;新增组件筛选、主题配色和包管理器偏好记忆,改善桌面、窄屏、深色外观与源码展开体验。
+
+### 迁移说明
+
+- 本次 `0.x` 次版本包含 API 与默认外观变化,升级前请检查以下项目。
+- 移除 `ConfigProvider.messages`、`textMessages` 和 `LeafMessages` 类型,改用按语言代码组织的 `translations` 及 `LeafTranslation` / `LeafTranslations`。语言回退需要在 `locale` 数组中显式列出,最终回退到内置英文。
+- 移除 `ImageCropper`、`SignaturePad`、相关类型及组件与样式子路径。需要图片裁剪或签名时,在应用中接入相应专用依赖。
+- Card 移除 `hoverable`;Tag 移除 `variant="outline"`,改用默认的 `soft` 或 `solid`。Pagination 默认使用带边框的按钮,原来的无边框外观可设置 `variant="ghost"`。
+- 如需保留 0.5.0 的基础控件高度,在 `ConfigProvider` 中设置 `theme={{ controlHeight: 40 }}`;需要自行管理 SSR 样式时继续使用 `@ifhover/leaf-ui/styles/all.css`。
+
## 0.5.0 - 2026-10-12
### 新增
diff --git a/apps/docs/docs/components/auto-complete.mdx b/apps/docs/docs/components/auto-complete.mdx
index 7de343ca..2046a1dc 100644
--- a/apps/docs/docs/components/auto-complete.mdx
+++ b/apps/docs/docs/components/auto-complete.mdx
@@ -10,7 +10,7 @@ import { AutoCompleteBasic, AutoCompleteSearch } from '../../src/components/form
通过 `options` 设置建议,默认按显示文本进行不区分大小写的包含匹配。`onChange` 响应输入和选择,`onSelect` 仅响应选择建议。
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/auto-complete/basic.tsx"
```
@@ -21,7 +21,7 @@ import { AutoCompleteBasic, AutoCompleteSearch } from '../../src/components/form
`onSearch` 接收用户输入。建议由你生成或从服务端获取时,可设置 `filterOption={false}` 直接展示传入结果。
- } fileName="search.tsx">
+ } fileName="search.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/auto-complete/search.tsx"
```
@@ -62,12 +62,12 @@ import { AutoCompleteBasic, AutoCompleteSearch } from '../../src/components/form
| `allowClear` | `boolean` | — | 展示清除操作。 |
| `virtual` | `boolean` | — | 启用虚拟滚动;大量选项默认启用。 |
| `listHeight` | `number` | `248` | 可视列表高度。 |
-| `optionHeight` | `number` | `36` | 虚拟选项的估算高度;实际行会被测量。 |
-| `popupPlacement` | [`PopupOptions`](../guide/control-contracts#popupoptions)`['popupPlacement']` | — | 浮层相对触发控件的位置。 |
+| `optionHeight` | `number` | `32` | 跟随区域控件高度和密度的预估行高;实际行会被测量。 |
+| `popupPlacement` | [`PopupOptions`](../api/popup-options#popupoptions)`['popupPlacement']` | — | 浮层相对触发控件的位置。 |
| `popupClassName` | `string` | — | 浮层的自定义类名。 |
-| `popupStyle` | [`PopupOptions`](../guide/control-contracts#popupoptions)`['popupStyle']` | — | 浮层的自定义样式。 |
-| `popupRender` | [`PopupOptions`](../guide/control-contracts#popupoptions)`['popupRender']` | — | 包装或补充面板内容,保留传入的内容以维持交互。 |
-| `getPopupContainer` | [`PopupOptions`](../guide/control-contracts#popupoptions)`['getPopupContainer']` | — | 返回浮层的挂载容器,也可返回 ShadowRoot。 |
+| `popupStyle` | [`PopupOptions`](../api/popup-options#popupoptions)`['popupStyle']` | — | 浮层的自定义样式。 |
+| `popupRender` | [`PopupOptions`](../api/popup-options#popupoptions)`['popupRender']` | — | 包装或补充面板内容,保留传入的内容以维持交互。 |
+| `getPopupContainer` | [`PopupOptions`](../api/popup-options#popupoptions)`['getPopupContainer']` | — | 返回浮层的挂载容器,也可返回 ShadowRoot。 |
| `disabled` | `boolean` | `false` | 禁用交互。 |
| `readOnly` | `boolean` | `false` | 锁定业务值,禁止输入、选择、清除和删除。 |
| `ref` | `Ref` | — | 输入框引用 |
diff --git a/apps/docs/docs/components/button.mdx b/apps/docs/docs/components/button.mdx
index 2db46987..dc348ff7 100644
--- a/apps/docs/docs/components/button.mdx
+++ b/apps/docs/docs/components/button.mdx
@@ -19,7 +19,7 @@ import { ButtonDanger, ButtonVariants, ButtonSizes, ButtonStates, ButtonIcons, B
-使用前,在应用入口导入一次 `@ifhover/leaf-ui/styles.css`。接入步骤见[快速开始](/guide/getting-started)。
+组件样式会自动加载,接入步骤见[快速开始](/guide/getting-started)。
## 危险操作
diff --git a/apps/docs/docs/components/calendar.mdx b/apps/docs/docs/components/calendar.mdx
index d73cf14c..fb67a0f7 100644
--- a/apps/docs/docs/components/calendar.mdx
+++ b/apps/docs/docs/components/calendar.mdx
@@ -9,7 +9,7 @@ import { CalendarMonth } from '../../src/examples/calendar/month';
## 日程日历
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/calendar/basic.tsx"
```
@@ -18,7 +18,7 @@ import { CalendarMonth } from '../../src/examples/calendar/month';
## 紧凑日历与禁用日期
- } fileName="compact.tsx">
+ } fileName="compact.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/calendar/compact.tsx"
```
@@ -27,7 +27,7 @@ import { CalendarMonth } from '../../src/examples/calendar/month';
## 选择月份
- } fileName="month.tsx">
+ } fileName="month.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/calendar/month.tsx"
```
@@ -63,4 +63,4 @@ import type { CalendarProps } from '@ifhover/leaf-ui';
`fullscreen={false}` 展示紧凑日历。`cellRender` 中使用文字、图标等非交互内容,避免在日期按钮内嵌套按钮。禁用选中项保留清晰的灰色状态,不会再次触发选择。
-方向键移动日期,Home / End 跳至一行首尾,PageUp / PageDown 切换月份。SSR 页面应提供一致的初始日期,详见 [SSR 使用](/guide/ssr)。
+方向键移动日期,Home / End 跳至一行首尾,PageUp / PageDown 切换月份。SSR 页面应提供一致的初始日期,详见 [服务端渲染](/guide/ssr)。
diff --git a/apps/docs/docs/components/card.mdx b/apps/docs/docs/components/card.mdx
index 02526f10..9b3f5164 100644
--- a/apps/docs/docs/components/card.mdx
+++ b/apps/docs/docs/components/card.mdx
@@ -1,6 +1,9 @@
import { CardSections } from '../../src/examples/card/sections';
import { ComponentExample } from '../../src/components/component-example';
import { CardBasic } from '../../src/examples/card/basic';
+import { CardSizes } from '../../src/examples/card/sizes';
+import { CardTabs } from '../../src/examples/card/tabs';
+import { CardTabsWithTitle } from '../../src/examples/card/tabs-with-title';
# Card 卡片
@@ -8,51 +11,109 @@ import { CardBasic } from '../../src/examples/card/basic';
## 基础用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={520}>
```tsx lineNumbers file="../../src/examples/card/basic.tsx"
```
+## 尺寸
+
+`size` 提供小、默认和大三种尺寸,同时调整卡片内边距、标题字号与标题栏高度。内嵌 Tabs 默认跟随卡片尺寸,也可通过 `tabs.size` 单独设置;卡片内的按钮、输入框等控件使用各自的 `size`。
+
+下面的三张卡片展示相同内容,方便对比标题、标签栏与正文留白;每张卡片的标签均可独立切换。
+
+ } fileName="sizes.tsx" width={520}>
+
+```tsx lineNumbers file="../../src/examples/card/sizes.tsx"
+```
+
+
+
## 内容分区
-默认以留白区分内容;设置 divided 可明确划分设置与操作区。
+默认以留白组织内容;设置 `divided` 可划分标题、正文与底部操作区。
- } fileName="sections.tsx">
+ } fileName="sections.tsx" width={560}>
```tsx lineNumbers file="../../src/examples/card/sections.tsx"
```
+## 标签页卡片
+
+通过 `tabs.items` 设置标签与对应内容。没有标题时,标签占满标题栏高度,文字上下留白一致;卡片的 `extra` 显示在标签栏右侧。
+
+ } fileName="tabs.tsx" width={520}>
+
+```tsx lineNumbers file="../../src/examples/card/tabs.tsx"
+```
+
+
+
+## 标题与标签页
+
+有 `title` 或 `description` 时,标签栏位于标题区域下方,两者之间没有分割线,分割线只展示在标签栏下方。`tabs.activeKey` / `tabs.onChange` 控制当前标签,默认保留已访问页面的输入内容;`divided` 继续控制底部操作区的分隔线和背景。
+
+ } fileName="tabs-with-title.tsx" width={520}>
+
+```tsx lineNumbers file="../../src/examples/card/tabs-with-title.tsx"
+```
+
+
+
## Card API
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
-| `title` | `ReactNode` | — | 标题 / 标题旁的内容 |
+| `title` | `ReactNode` | — | 卡片标题。 |
| `description` | `ReactNode` | — | 补充说明。 |
-| `extra` | `ReactNode` | — | 标题 / 标题旁的内容 |
-| `cover` | `ReactNode` | — | 顶部封面 / 底部内容 |
-| `footer` | `ReactNode` | — | 顶部封面 / 底部内容 |
+| `extra` | `ReactNode` | — | 标题旁的操作;没有标题时显示在标签栏右侧。 |
+| `tabs` | [`CardTabsProps`](#cardtabs-api) | — | 内嵌标签页;无标题时替代标题栏,有标题时位于其下方。 |
+| `cover` | `ReactNode` | — | 顶部封面。 |
+| `footer` | `ReactNode` | — | 底部内容或操作。 |
| `loading` | `boolean` | `false` | 使用骨架屏替换正文 |
-| `bordered` | `boolean` | `true` | 显示外轮廓 / 悬停强调卡片 |
+| `bordered` | `boolean` | `true` | 显示外轮廓 |
| `divided` | `boolean` | `false` | 用浅分隔线划分标题、内容和底部操作区。 |
-| `hoverable` | `boolean` | `false` | 显示外轮廓 / 悬停强调卡片 |
-| `size` | `'sm' \| 'md'` | `'md'` | 内容间距 |
+| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 卡片尺寸,影响内边距、标题字号、标题栏高度及内嵌 Tabs 的默认尺寸。 |
## 类型
定义组件属性或组装列表时可导入相关类型。
```ts
-import type { CardProps } from '@ifhover/leaf-ui';
+import type { CardProps, CardTabsProps, TabItem } from '@ifhover/leaf-ui';
```
## 使用说明
-extra 和 footer 可以放置按钮或链接。hoverable 提供视觉反馈,需要点击操作时请使用明确的按钮或链接。
+extra 和 footer 可以放置按钮或链接。需要点击操作时请使用明确的按钮或链接。
+
+`tabs` 复用 Tabs 的配置和交互,固定使用顶部线形标签。`tabs.items[].children` 是对应页面内容;Card 的 `children` 可放置在所有页面下方的公共说明。`loading` 替换正文为骨架屏,标题、标签栏和操作保持可用。标签默认跟随卡片的 `size`,可用 `tabs.size` 单独调整;标签数组为空时恢复普通卡片。
+
+可在 `tabs` 中设置禁用、图标、手动键盘激活、保留或销毁页面、溢出菜单以及增删、排序回调。`tabs.extra` 始终属于标签栏;有标题时 Card 的 `extra` 仍位于标题右侧。
## 外观与丰富内容
-`description` 显示标题下的补充说明。默认不显示内部边框;设置 `divided` 使用分区边框和淡灰底部。通过 `ConfigProvider` 的 `components.Card` 可定制背景、分区背景和边框。
+`description` 显示标题下的补充说明。普通卡片默认不显示内部边框,标签页卡片始终在标签栏下方展示分割线;设置 `divided` 可增加底部的分隔线与淡灰背景,操作区与 Modal、Drawer 使用一致的纵向留白。通过 `ConfigProvider` 的 `components.Card` 可定制背景、分区背景和边框。
+
+## CardTabs API
+
+| 属性 | 类型 | 默认值 | 说明 |
+| --- | --- | --- | --- |
+| `items` | `readonly `[`TabItem`](../components/tabs#tabitem)`[]` | 必填 | 必需。标签与页面列表;为空时恢复普通卡片。 |
+| `activeKey` | `string` | 首个可用项 | 受控的激活项。 |
+| `defaultActiveKey` | `string` | 首个可用项 | 初始激活项。 |
+| `onChange` | `(key: string) => void` | — | 激活项变化时调用。 |
+| `size` | `'sm' \| 'md' \| 'lg'` | Card 的 `size` | 标签尺寸,可单独覆盖。 |
+| `activationMode` | `'automatic' \| 'manual'` | `'automatic'` | 方向键直接激活,或回车 / 空格激活。 |
+| `destroyInactive` | `boolean` | `false` | 切走时卸载内容;默认保留已访问页面。 |
+| `extra` | `ReactNode` | — | 标签栏右侧的附加内容。 |
+| `onClose` | `(key: string, event: MouseEvent) => void` | — | 请求关闭,由应用移除对应项;可阻止默认切换。 |
+| `onAdd` | `() => void` | — | 添加页签,传入后显示添加按钮。 |
+| `addLabel` | `string` | 当前语言的提示 | 添加按钮的可访问名称。 |
+| `overflow` | `boolean` | `true` | 溢出页签收进更多菜单。 |
+| `sortable` | `boolean` | `false` | 启用排序,配合 `onReorder` 使用。 |
+| `onReorder` | `(items: `[`TabItem`](../components/tabs#tabitem)`[]) => void` | — | 返回排序后的原始页签,由应用更新列表。 |
diff --git a/apps/docs/docs/components/cascader.mdx b/apps/docs/docs/components/cascader.mdx
index ce5a31ab..83eccb55 100644
--- a/apps/docs/docs/components/cascader.mdx
+++ b/apps/docs/docs/components/cascader.mdx
@@ -1,3 +1,4 @@
+import { SingleLine } from '../../src/examples/cascader/single-line';
import { Capabilities } from '../../src/examples/cascader/capabilities';
import { ComponentExample } from '../../src/components/component-example';
import { CascaderBasic, CascaderControlled } from '../../src/components/form-examples';
@@ -10,7 +11,7 @@ import { CascaderBasic, CascaderControlled } from '../../src/components/form-exa
`children` 定义子选项。点击父项展开下一列,点击末级选项确认完整路径;`disabled` 可以禁用一个分支。
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/cascader/basic.tsx"
```
@@ -21,7 +22,7 @@ import { CascaderBasic, CascaderControlled } from '../../src/components/form-exa
`value` 是从根节点到末级节点的 value 数组,`onChange` 同时提供完整的选项对象路径。切换父项后会清除旧分支的后续选择。
- } fileName="controlled.tsx">
+ } fileName="controlled.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/cascader/controlled.tsx"
```
@@ -42,6 +43,17 @@ import { CascaderBasic, CascaderControlled } from '../../src/components/form-exa
+## 单行多选
+
+设置 `tagWrap={false}` 后,已选项始终展示在一行内。长文字自动省略,放不下的选项合并为 `+N`;空间很窄时只显示数量,打开浮层可查看和修改选择。`maxTagCount` 可进一步限制标签数量,`maxTagCount="responsive"` 也会启用单行自动折叠。
+
+ } fileName="single-line.tsx" width={360}>
+
+```tsx lineNumbers file="../../src/examples/cascader/single-line.tsx"
+```
+
+
+
## Cascader API
| 属性 | 类型 | 默认值 | 说明 |
@@ -69,6 +81,8 @@ import { CascaderBasic, CascaderControlled } from '../../src/components/form-exa
| `loadData` | `(option: `[`CascaderOption`](#cascaderoption)`, signal: AbortSignal) => Promise` | — | 异步加载子节点;应响应 AbortSignal。 |
| `onLoadError` | `(error: unknown, option: `[`CascaderOption`](#cascaderoption)`) => void` | — | 加载失败时调用,可展示重试提示。 |
| `cacheKey` | `string \| number` | — | 数据版本改变时清空懒加载缓存,并取消旧请求。 |
+| `tagWrap` | `boolean` | `true` | 允许多选标签换行;false 单行显示并自动折叠溢出项。 |
+| `maxTagCount` | `number \| 'responsive'` | — | 最多展示的标签数;responsive 根据可用宽度自动折叠。 |
| `multiple` | `false \| true` | `false` | 启用多选;value 和回调的类型随之变化。 |
| `value` | `readonly string[] \| readonly (readonly string[])[]` | `[]` | 受控路径 / 非受控初始路径 |
| `defaultValue` | `readonly string[] \| readonly (readonly string[])[]` | `[]` | 受控路径 / 非受控初始路径 |
diff --git a/apps/docs/docs/components/checkbox.mdx b/apps/docs/docs/components/checkbox.mdx
index 5b3d34b8..e8dfbe20 100644
--- a/apps/docs/docs/components/checkbox.mdx
+++ b/apps/docs/docs/components/checkbox.mdx
@@ -21,7 +21,7 @@ import { CheckboxBasic, CheckboxCheckAll } from '../../src/components/form-examp
indeterminate 表示部分选中,用于汇总子选项。它只影响显示与辅助技术识别;全选和提交值由 checked 决定。
- } fileName="check-all.tsx">
+ } fileName="check-all.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/checkbox/check-all.tsx"
```
diff --git a/apps/docs/docs/components/color-picker.mdx b/apps/docs/docs/components/color-picker.mdx
index 9ce99a00..b074d110 100644
--- a/apps/docs/docs/components/color-picker.mdx
+++ b/apps/docs/docs/components/color-picker.mdx
@@ -10,7 +10,9 @@ import { ColorPickerPresets } from '../../src/examples/color-picker/presets';
## 选择颜色
- } fileName="basic.tsx">
+点击色块、颜色文字或整行空白区域即可打开选择浮层。
+
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/color-picker/basic.tsx"
```
diff --git a/apps/docs/docs/components/command-palette.mdx b/apps/docs/docs/components/command-palette.mdx
index bcf8ede5..21560574 100644
--- a/apps/docs/docs/components/command-palette.mdx
+++ b/apps/docs/docs/components/command-palette.mdx
@@ -7,7 +7,7 @@ import { CommandPaletteBasic, CommandPaletteFailure } from '../../src/examples/c
## 基础用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/command-palette/basic.tsx"
```
@@ -16,7 +16,7 @@ import { CommandPaletteBasic, CommandPaletteFailure } from '../../src/examples/c
## 异步操作
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/command-palette/basic.tsx"
```
diff --git a/apps/docs/docs/components/config-provider.mdx b/apps/docs/docs/components/config-provider.mdx
index 41093a50..4ddf3e23 100644
--- a/apps/docs/docs/components/config-provider.mdx
+++ b/apps/docs/docs/components/config-provider.mdx
@@ -1,245 +1,232 @@
-import { ConfigProviderDensity } from '../../src/examples/config-provider/density';
+import { withBase } from '@rspress/core/runtime';
+
import { ComponentExample } from '../../src/components/component-example';
+import { DocsCollapse } from '../../src/components/docs-collapse';
import { ConfigProviderBasic } from '../../src/examples/config-provider/basic';
+import { ConfigProviderDefaults } from '../../src/examples/config-provider/defaults';
+import { ConfigProviderModalDefaults } from '../../src/examples/config-provider/modal-defaults';
+import { ConfigProviderInheritance } from '../../src/examples/config-provider/inheritance';
+import { ConfigProviderReset } from '../../src/examples/config-provider/reset';
+import { ConfigProviderLocale } from '../../src/examples/config-provider/locale';
+import { ConfigProviderTranslations } from '../../src/examples/config-provider/translations';
+import { ConfigProviderDensity } from '../../src/examples/config-provider/density';
import { ConfigProviderSizes } from '../../src/examples/config-provider/sizes';
# ConfigProvider 配置
-统一设置区域的主题、外观与语言。
+为整个应用或局部区域统一设置主题、语言和组件默认参数。
+
+放在应用入口时作用于整个应用;嵌套使用时只调整当前区域。
+
+| 想调整什么 | 使用的配置 |
+| --- | --- |
+| 内置文本与自定义语言 | `locale`、`translations` |
+| 主题色、外观、尺寸与间距 | `theme`、`density` |
+| 统一组件参数 | `components` |
+
+## 多语言
+
+`locale` 切换日期面板、空状态、清除按钮等内置文本。业务标题、字段标签和选项内容由应用自行翻译。
+
+### 内置语言
+
+以下语言已内置,无需额外导入语言包。未配置 `locale` 时,默认使用简体中文。
+
+| 语言 | `locale` |
+| --- | --- |
+| 简体中文 | `zh-CN` |
+| 繁體中文 | `zh-TW` |
+| English | `en-US` |
+| 日本語 | `ja-JP` |
+| 한국어 | `ko-KR` |
+
+其他语言需要[提供翻译资源](#补充自己的语言)。仅传入其他语言代码不会自动翻译内置文本;未找到的词条最终回退到英文。
+
+### 切换语言
+
+更新 `locale` 即可切换语言。在下拉框中选择语言,再打开日期或空选项控件,可比较五种语言的内置提示。
+
+ } fileName="locale.tsx" width={360}>
+
+```tsx lineNumbers file="../../src/examples/config-provider/locale.tsx"
+```
+
+
+
+嵌套区域未指定语言时继承上层;`direction` 调整文字方向,`weekStartsOn` 设置一周的起始日,浮层也会继承这些配置。
+
+### 补充自己的语言
+
+复制完整英文 JSON 作为模板,翻译后导入并传给 `translations`。键是语言代码,JSON 只包含按组件分组的文本,不需要重复写语言代码。可以只提供部分词条。
+
+👽 下面用[火星文](https://zh.wikipedia.org/wiki/火星文)演示自定义资源,作为一个小彩蛋。它是一种混用谐音字、形近字和符号的网络写法。
+
+未翻译的词条回退英文。字段名称、确认框正文等业务内容仍由应用提供。
-## 区域主题与语言
+火星文使用私用语言标记 `zh-CN-x-mars`,日期和数字仍按简体中文的区域格式显示。它仅用于演示,不属于内置语言。
- } fileName="basic.tsx">
+ } fileName="translations.tsx" width={360}>
+
+```tsx lineNumbers file="../../src/examples/config-provider/translations.tsx"
+```
+
+
+
+示例中的 `zh-CN-x-mars.json`:
+
+```json file="../../src/examples/config-provider/zh-CN-x-mars.json"
+```
+
+`locale={['zh-CN-x-mars', 'en-US']}` 按顺序查找每个缺失词条,最后由内置英文兜底。第一项始终控制当前语言、日期与数字的区域格式;字符串等价于单项数组,空数组无效。不会自动添加 `zh-CN-x-mars → zh-CN` 或 `fr-CA → fr` 等回退。
+
+嵌套时 `translations` 按语言和词条合并;未传 `locale` 则继承,显式传入则替换整条语言链。组件实例与 `components` 设置的文案优先。完整规则、类型、JSON Schema 和词条检查见[翻译资源](/api/translations)。
+
+## 主题与外观
+
+### 区域主题
+
+主题会应用到区域内的组件和浮层。通常只需要修改主题色或基础圆角,其余样式会随之调整。
+
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/config-provider/basic.tsx"
```
-## 基础尺寸与高级覆盖
+### 区域密度
+
+`density="compact"` 适合信息较多的界面,会一起收紧控件和内容间距;默认使用 `comfortable`。嵌套区域可单独设置。
+
+ } fileName="density.tsx" width={360}>
-修改基础高度时,小、大控件会同步调整。需要特殊尺寸时,再通过 tokens 单独覆盖。
+```tsx lineNumbers file="../../src/examples/config-provider/density.tsx"
+```
- } fileName="sizes.tsx">
+
+
+### 基础高度
+
+需要改变整体尺寸基准时,设置 `theme.controlHeight`,小、大尺寸会自动派生。无需逐项调整按钮和输入框的高度。
+
+ } fileName="sizes.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/config-provider/sizes.tsx"
```
-## 全局密度
+进一步定制见[定制主题](/guide/theming)。`theme.components` 调整组件局部样式,下方的 `components` 设置组件默认参数;两者用途不同,可以同时使用。服务端接入见 [服务端渲染](/guide/ssr)。
-密度调整间距与尺寸,同时保留正文字号。嵌套区域继承密度,可显式设置 comfortable 恢复舒适模式。
+## 组件默认值
- } fileName="density.tsx">
+**常用参数设一次,省去每个组件重复传参。** 用 `components` 统一按钮样式、输入提示、弹窗关闭方式,后续调整也只改一处。
-```tsx lineNumbers file="../../src/examples/config-provider/density.tsx"
+放在应用入口作用于全站,放在局部只影响当前区域;个别组件仍可用自身参数覆盖。
+
+### 统一表单习惯
+
+下面统一输入提示、清除按钮和按钮样式,结束日期与保存按钮单独覆盖。
+
+ } fileName="defaults.tsx" width={360}>
+
+```tsx lineNumbers file="../../src/examples/config-provider/defaults.tsx"
+```
+
+
+
+### 防止误点遮罩关闭弹窗
+
+编辑时不希望误点遮罩就关掉弹窗,可以统一设置 `Modal: { maskClosable: false }`。区域内的 Modal 都会沿用,无需逐个设置;关闭按钮和 Esc 仍然可用。
+
+ } fileName="modal-defaults.tsx" width="fit-content">
+
+```tsx lineNumbers file="../../src/examples/config-provider/modal-defaults.tsx"
```
-## ConfigProvider API
+### 继承与覆盖
+
+统一默认值后,局部仍可灵活调整:**实例参数 > 内层配置 > 外层配置 > 组件内置值**。
+
+ } fileName="inheritance.tsx">
+
+```tsx lineNumbers file="../../src/examples/config-provider/inheritance.tsx"
+```
+
+
+
+### 清除继承
+
+将组件配置设为 `null`,可在局部恢复它的内置默认值,例如 `components={{ Input: null }}`。
+
+ } fileName="reset.tsx" width={360}>
+
+```tsx lineNumbers file="../../src/examples/config-provider/reset.tsx"
+```
+
+
+
+
+
+使用 `LeafComponentDefaults` 获得类型提示,可配参数见[完整参考](/api/component-defaults#leafcomponentdefaults)。
+
+- 键名与组件名一致,如 `Input`、`Modal`。组合组件 `Table.Cell` 写作 `TableCell`,`Table.Root` 写作 `Table`;别名 `FAB`、`ResizablePanels` 使用 `FloatButton`、`Splitter`。
+- 只有 `undefined` 会回退到默认值;`false`、`0`、空字符串和类型允许的 `null` 均保留。对象、数组、类名和回调整体替换。
+- 组件配置为 `null` 时清除继承,空对象和 `undefined` 继续继承;其他组件与主题不受影响。
+- 每个实例的数据和事件仍写在组件上,如 `Select.options`、`Modal.open`、`onChange`。
+- 更新配置时传入新对象,不要直接修改原对象。
+- 内部按钮通过所属组件的参数调整,例如 `Modal.confirmButtonProps`;不会跟随全局 `Button` 配置。
+
+
+
+## API
+
+### ConfigProvider API
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
-| `locale` | `LeafLocale` | `'zh-CN'` | 内置文本语言,嵌套时继承 |
+| `locale` | `LeafLocale \| readonly LeafLocale[]` | `'zh-CN'` | 当前语言与逐词条回退顺序;未指定则继承 |
+| `translations` | `Readonly>` | — | 按语言代码提供 JSON 翻译,嵌套时按词条合并 |
| `theme` | [`LeafTheme`](#leaftheme) | — | 区域主题;未设置的字段继承上层 |
-| `messages` | `Partial<`[`LeafMessages`](#leafmessages)`>` | — | 覆盖内置组件的语言文本。 |
-| `textMessages` | `Record` | — | 以英文原文为 key,覆盖扩展组件的文本。 |
| `direction` | `'ltr' \| 'rtl'` | — | 文字和交互方向。 |
| `weekStartsOn` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6` | — | 一周起始日,0 表示周日、1 表示周一。 |
| `getPopupContainer` | `() => Element \| DocumentFragment` | — | 返回浮层的挂载容器,也可返回 ShadowRoot。 |
| `maskBlur` | `boolean` | `true` | 启用 Modal、Drawer 及基于 Modal 的确认框、命令面板等遮罩模糊;关闭可减少渲染开销,嵌套时继承。 |
| `density` | `'comfortable' \| 'compact'` | `'comfortable'` | 继承控件、表单、菜单、列表与浮层的密度;显式尺寸优先于预设。 |
+| `components` | [`LeafComponentDefaults`](../api/component-defaults#leafcomponentdefaults) | — | 当前区域的组件默认参数,嵌套时按组件和参数继承。 |
-其余原生 div 属性、className 和 style 作用于区域容器。主题设置通过 theme 传入。
+其余原生 div 属性、`className` 和 `style` 作用于区域容器。`maskBlur={false}` 关闭背景模糊,仍保留半透明遮罩;此设置独立于 `theme.motion`。
-遮罩模糊会随打开和关闭渐变。性能敏感的页面可使用 `` 关闭模糊,遮罩仍保留半透明背景;此设置独立于 `theme.motion`。
+### LeafTheme
-## LeafTheme
+常用主题配置。未设置的字段继承外层区域。
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `primaryColor` | `string` | `'#20834a'` | 主题色,悬停和按下等状态自动生成;深色默认采用较浅的绿色 |
| `borderRadius` | `number \| string` | `10` | 基础圆角;数字为 px,小 / 中 / 大圆角按 0.6 / 1.2 / 1.6 倍生成 |
-| `controlHeight` | `number \| string` | `40` | 基础控件高度;小 / 大尺寸分别减 / 加 6px |
+| `controlHeight` | `number \| string` | `36` | 基础控件高度;小 / 大尺寸分别减 / 加 6px |
| `fontSize` | `number \| string` | `14` | 基础字号;小字号减 1px,大字号加 2px |
| `fontFamily` | `string` | 系统无衬线字体 | 字体族 |
| `appearance` | `'light' \| 'dark'` | `'light'` | 浅色或深色;嵌套时继承显式配置 |
| `motion` | `boolean` | `true` | 启用当前区域的交互动效;系统减少动态效果优先,浮层继承此设置。 |
-| `tokens` | [`LeafThemeTokens`](#leafthemetokens) | — | 可选的高级覆盖,不必配置全部字段 |
+| `tokens` | [`LeafThemeTokens`](../api/theme-tokens#leafthemetokens) | — | 可选的高级覆盖,不必配置全部字段 |
| `spacing` | `number` | — | 基础间距,其他间距按比例派生。 |
| `lineHeight` | `number` | — | 正文行高。 |
| `headingWeight` | `number` | — | Typography 文档标题的字重;组件标题使用 `tokens.fontWeight`。 |
| `elevation` | `'none' \| 'soft' \| 'medium'` | — | 整体阴影强度。 |
| `breakpoints` | `Partial>` | — | useBreakpoint 使用的响应式断点。 |
-| `components` | `Record` | — | 按组件名称覆盖局部样式。 |
-
-以上默认值适用于未配置的应用。嵌套区域继承上层显式设置;长度也支持 CSS 单位。小控件高度和字号的自动结果不会小于 1px。
-
-## LeafThemeTokens
-
-所有字段均可选;显式值优先于默认或自动生成值。
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `onPrimaryColor` | `string` | 按主题生成 | 主题背景上的文字色 |
-| `dangerColor` | `string` | 按外观生成 | 危险色 / 危险背景上的文字色 |
-| `onDangerColor` | `string` | 按外观生成 | 危险色 / 危险背景上的文字色 |
-| `successColor` | `string` | 按外观生成 | 成功 / 警告 / 信息颜色 |
-| `warningColor` | `string` | 按外观生成 | 成功 / 警告 / 信息颜色 |
-| `infoColor` | `string` | 按外观生成 | 成功 / 警告 / 信息颜色 |
-| `textColor` | `string` | 按外观生成 | 主要 / 次要文字 |
-| `mutedTextColor` | `string` | 按外观生成 | 主要 / 次要文字 |
-| `subtleTextColor` | `string` | — | 更轻的辅助文字色。 |
-| `surfaceColor` | `string` | 按外观生成 | 表面 / 次级表面 |
-| `mutedSurfaceColor` | `string` | 按外观生成 | 表面 / 次级表面 |
-| `raisedSurfaceColor` | `string` | — | 浮层与抬升表面色。 |
-| `borderColor` | `string` | 按外观生成 | 中性边框 |
-| `borderHoverColor` | `string` | — | 悬停时的中性边框色。 |
-| `dividerColor` | `string` | — | 分区分隔线颜色;默认从边框和表面颜色派生。 |
-| `borderRadiusSm` | `number \| string` | `基础圆角 × 0.6` | 单独覆盖小 / 大圆角 |
-| `borderRadiusMd` | `number \| string` | `基础圆角 × 1.2` | 单独覆盖卡片、提示等内容表面的中圆角 |
-| `borderRadiusLg` | `number \| string` | `1.6` | 单独覆盖小 / 大圆角 |
-| `controlHeightSm` | `number \| string` | `基础高度 −` | 单独覆盖小 / 大高度 |
-| `controlHeightLg` | `number \| string` | `+ 6px` | 单独覆盖小 / 大高度 |
-| `fontSizeSm` | `number \| string` | `基础字号 − 1px` | 单独覆盖小 / 大字号 |
-| `fontSizeLg` | `number \| string` | `+ 2px` | 单独覆盖小 / 大字号 |
-| `fontWeight` | `number` | `500` | 按钮、标签与组件标题的强调字重 |
-| `motionDuration` | `number \| string` | `200` | 基础过渡时间;数字为 ms,也支持 CSS 时间。motion=false 时为 0。 |
-| `motionEasing` | `string` | `'cubic-bezier(0.22, 1, 0.36, 1)'` | 悬停、内容与普通过渡的曲线。 |
-| `motionSpring` | `string` | `'cubic-bezier(0.22, 1.28, 0.36, 1)'` | 选择与形状变化的轻微弹性曲线。 |
-| `popupZIndex` | `number` | `1000` | 浮层 / 弹窗 / 消息层级 |
-| `modalZIndex` | `number` | `1100` | 浮层 / 弹窗 / 消息层级 |
-| `messageZIndex` | `number` | `1200` | 浮层 / 弹窗 / 消息层级 |
-| `buttonBorderRadius` | `number \| string` | 当前控件尺寸 | 仅按钮的圆角 / 共用高度覆盖 |
-| `buttonHeight` | `number \| string` | 当前控件尺寸 | 仅按钮的圆角 / 共用高度覆盖 |
-| `choiceBorderRadius` | `number \| string` | 基础圆角 × 0.5 | 复选框圆角 |
-| `focusColor` | `string` | 当前语义色自动生成 | 焦点轮廓颜色 |
-| `primaryHoverColor` | `string` | 主题色自动生成 | 主色悬停 / 按下 |
-| `primaryActiveColor` | `string` | 主题色自动生成 | 主色悬停 / 按下 |
-| `primarySoftColor` | `string` | 主题色自动生成 | 主色柔和背景与交互状态 |
-| `primarySoftHoverColor` | `string` | 主题色自动生成 | 主色柔和背景与交互状态 |
-| `primarySoftActiveColor` | `string` | 主题色自动生成 | 主色柔和背景与交互状态 |
-| `primaryBorderColor` | `string` | 主题色自动生成 | 主题色边框 |
-| `dangerHoverColor` | `string` | 危险色自动生成 | 危险状态悬停 / 按下 |
-| `dangerActiveColor` | `string` | 危险色自动生成 | 危险状态悬停 / 按下 |
-| `spacingSm` | `number \| string` | — | 设置 spacingSm。 |
-| `spacingLg` | `number \| string` | — | 设置 spacingLg。 |
-| `shadowSm` | `string` | — | 设置 shadowSm。 |
-| `shadowXs` | `string` | — | 最轻的表面阴影。 |
-| `shadowMd` | `string` | — | 设置 shadowMd。 |
-| `shadowLg` | `string` | — | 设置 shadowLg。 |
-| `lineHeight` | `number` | — | 正文行高。 |
+| `components` | `Record` | — | 按组件名称覆盖局部样式。 |
-## 类型
+### 类型与完整参考
-组装可复用的主题或属性时,可导入这些类型:
+组装可复用配置时,可按需导入类型:
```ts
-import type { ConfigProviderProps, LeafTheme, LeafThemeTokens, LeafLocale } from '@ifhover/leaf-ui';
-
-const theme: LeafTheme = { primaryColor: '#7654c6', borderRadius: 8 };
-const advanced: LeafThemeTokens = { controlHeightLg: 44 };
+import type { ConfigProviderProps, LeafComponentDefaults, LeafTheme } from '@ifhover/leaf-ui';
```
-`LeafLocale` 直接表示 `'zh-CN' | 'en-US'`。ConfigProviderProps 对应上方 [ConfigProvider API](#configprovider-api)。
-
-## 使用说明
-
-嵌套区域按字段合并 tokens;手动指定的派生尺寸会继续继承。浮层、Modal、确认框和消息沿用调用区域的配置。ConfigProvider 自动托管确认框、消息、通知和顶部加载条,子组件调用相应 hook 即可,详见 [Confirm](/components/confirm) 和 [Message](/components/message)。
-
-语言覆盖内置提示、日期、时间、清除按钮和反馈组件;业务内容、label 和 options 由应用翻译。
-
-使用 ConfigProvider 调整主题,CSS 变量供业务组件读取和复用。入门示例见[定制主题](/guide/theming),服务端接入见 [SSR 使用](/guide/ssr)。
-
-## LeafMessages
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `select` | `string` | — | 必需。设置 select。 |
-| `empty` | `string` | — | 必需。设置 empty。 |
-| `noMatches` | `string` | — | 必需。设置 noMatches。 |
-| `clearSelection` | `string` | — | 必需。设置 clearSelection。 |
-| `date` | `string` | — | 必需。设置 date。 |
-| `time` | `string` | — | 必需。设置 time。 |
-| `dateTime` | `string` | — | 必需。设置 dateTime。 |
-| `range` | `string` | — | 必需。设置 range。 |
-| `clearDate` | `string` | — | 必需。设置 clearDate。 |
-| `clearTime` | `string` | — | 必需。设置 clearTime。 |
-| `clearRange` | `string` | — | 必需。设置 clearRange。 |
-| `clearCascader` | `string` | — | 必需。设置 clearCascader。 |
-| `chooseDate` | `string` | — | 必需。设置 chooseDate。 |
-| `chooseTime` | `string` | — | 必需。设置 chooseTime。 |
-| `previousMonth` | `string` | — | 必需。设置 previousMonth。 |
-| `nextMonth` | `string` | — | 必需。设置 nextMonth。 |
-| `previousYear` | `string` | — | 必需。设置 previousYear。 |
-| `nextYear` | `string` | — | 必需。设置 nextYear。 |
-| `previousYears` | `string` | — | 必需。设置 previousYears。 |
-| `nextYears` | `string` | — | 必需。设置 nextYears。 |
-| `hours` | `string` | — | 必需。设置 hours。 |
-| `minutes` | `string` | — | 必需。设置 minutes。 |
-| `seconds` | `string` | — | 必需。设置 seconds。 |
-| `period` | `string` | — | 必需。设置 period。 |
-| `am` | `string` | — | 必需。设置 am。 |
-| `pm` | `string` | — | 必需。设置 pm。 |
-| `weekdays` | `string[]` | — | 必需。设置 weekdays。 |
-| `confirm` | `string` | — | 必需。设置 confirm。 |
-| `cancel` | `string` | — | 必需。取消当前请求。 |
-| `close` | `string` | — | 必需。设置 close。 |
-| `start` | `string` | — | 必需。设置 start。 |
-| `end` | `string` | — | 必需。设置 end。 |
-| `required` | `string` | — | 必需。要求整体值非空,复合控件只校验一次。 |
-| `invalid` | `string` | — | 必需。设置 invalid。 |
-| `useTime` | `string` | — | 必需。设置 useTime。 |
-| `year` | `string` | — | 必需。设置 year。 |
-| `month` | `string` | — | 必需。设置 month。 |
-| `week` | `string` | — | 必需。设置 week。 |
-| `dateMode` | `string` | — | 必需。设置 dateMode。 |
-| `loading` | `string` | — | 必需。展示加载状态。 |
-| `today` | `string` | — | 必需。设置 today。 |
-| `now` | `string` | — | 必需。设置 now。 |
-| `selectTime` | `string` | — | 必需。设置 selectTime。 |
-| `selectDate` | `string` | — | 必需。设置 selectDate。 |
-| `remove` | `string` | — | 必需。设置 remove。 |
-| `search` | `string` | — | 必需。设置 search。 |
-| `breadcrumb` | `string` | — | 必需。设置 breadcrumb。 |
-| `pagination` | `string` | — | 必需。设置 pagination。 |
-| `previousPage` | `string` | — | 必需。设置 previousPage。 |
-| `nextPage` | `string` | — | 必需。设置 nextPage。 |
-| `page` | `string` | — | 必需。设置 page。 |
-| `pageSize` | `string` | — | 必需。设置 pageSize。 |
-| `itemsPerPage` | `string` | — | 必需。设置 itemsPerPage。 |
-| `jumpTo` | `string` | — | 必需。设置 jumpTo。 |
-| `showPassword` | `string` | — | 必需。设置 showPassword。 |
-| `hidePassword` | `string` | — | 必需。设置 hidePassword。 |
-| `increase` | `string` | — | 必需。设置 increase。 |
-| `decrease` | `string` | — | 必需。设置 decrease。 |
-| `invalidNumber` | `string` | — | 必需。设置 invalidNumber。 |
-| `progress` | `string` | — | 必需。设置 progress。 |
-| `calendar` | `string` | — | 必需。设置 calendar。 |
-| `clearInput` | `string` | — | 必需。设置 clearInput。 |
-| `noData` | `string` | — | 必需。设置 noData。 |
-| `avatar` | `string` | — | 必需。前置头像或图标。 |
-| `rating` | `string` | — | 必需。设置 rating。 |
-| `resultSuccess` | `string` | — | 必需。设置 resultSuccess。 |
-| `resultWarning` | `string` | — | 必需。设置 resultWarning。 |
-| `resultError` | `string` | — | 必需。设置 resultError。 |
-| `resultInfo` | `string` | — | 必需。设置 resultInfo。 |
-| `color` | `string` | — | 必需。颜色或语义色。 |
-| `clearColor` | `string` | — | 必需。设置 clearColor。 |
-| `saturation` | `string` | — | 必需。设置 saturation。 |
-| `brightness` | `string` | — | 必需。设置 brightness。 |
-| `hue` | `string` | — | 必需。设置 hue。 |
-| `alpha` | `string` | — | 必需。设置 alpha。 |
-| `colorValue` | `string` | — | 必需。设置 colorValue。 |
-| `invalidColor` | `string` | — | 必需。设置 invalidColor。 |
-| `presets` | `string` | — | 必需。快捷选项;value 可以动态计算。 |
-| `tree` | `string` | — | 必需。设置 tree。 |
-| `expand` | `string` | — | 必需。设置 expand。 |
-| `collapseNode` | `string` | — | 必需。设置 collapseNode。 |
-| `collapse` | `string` | — | 必需。设置 collapse。 |
-| `slider` | `string` | — | 必需。设置 slider。 |
-| `pageBack` | `string` | — | 必需。设置 pageBack。 |
-| `pageForward` | `string` | — | 必需。设置 pageForward。 |
-| `closeTab` | `string` | — | 必需。设置 closeTab。 |
+- [LeafComponentDefaults](/api/component-defaults#leafcomponentdefaults):组件名称与可配置的默认参数。
+- [LeafThemeTokens](/api/theme-tokens#leafthemetokens):高级主题覆盖。
diff --git a/apps/docs/docs/components/date-picker.mdx b/apps/docs/docs/components/date-picker.mdx
index 227f8104..df033ff4 100644
--- a/apps/docs/docs/components/date-picker.mdx
+++ b/apps/docs/docs/components/date-picker.mdx
@@ -14,7 +14,7 @@ import { DatePickerFooter } from '../../src/examples/date-picker/footer';
点击控件打开日历,选择日期后收起。`defaultValue` 设置初始日期,`disabled` 禁用整个控件。
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/date-picker/basic.tsx"
```
@@ -25,7 +25,7 @@ import { DatePickerFooter } from '../../src/examples/date-picker/footer';
通过 `minDate` / `maxDate` 限定可选日期,边界当天也可以选择。`onChange` 同时提供 Date 对象和本地日期字符串。
- } fileName="controlled.tsx">
+ } fileName="controlled.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/date-picker/controlled.tsx"
```
diff --git a/apps/docs/docs/components/date-range-picker.mdx b/apps/docs/docs/components/date-range-picker.mdx
index 9a2f6c6d..1aff8568 100644
--- a/apps/docs/docs/components/date-range-picker.mdx
+++ b/apps/docs/docs/components/date-range-picker.mdx
@@ -9,7 +9,7 @@ import { DateRangePickerModes } from '../../src/examples/date-range-picker/modes
## 受控区间
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/date-range-picker/basic.tsx"
```
diff --git a/apps/docs/docs/components/date-time-picker.mdx b/apps/docs/docs/components/date-time-picker.mdx
index cffec3a0..55714da9 100644
--- a/apps/docs/docs/components/date-time-picker.mdx
+++ b/apps/docs/docs/components/date-time-picker.mdx
@@ -8,7 +8,7 @@ import { DateTimePickerBasic } from '../../src/examples/date-time-picker/basic';
## 日期与时间
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/date-time-picker/basic.tsx"
```
@@ -17,7 +17,7 @@ import { DateTimePickerBasic } from '../../src/examples/date-time-picker/basic';
## 自定义格式与营业时间
- } fileName="capabilities.tsx">
+ } fileName="capabilities.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/date-time-picker/capabilities.tsx"
```
diff --git a/apps/docs/docs/components/drawer.mdx b/apps/docs/docs/components/drawer.mdx
index f6d2f931..2004b71e 100644
--- a/apps/docs/docs/components/drawer.mdx
+++ b/apps/docs/docs/components/drawer.mdx
@@ -18,7 +18,7 @@ import { DrawerBasic } from '../../src/examples/drawer/basic';
## 调整宽度与嵌套推移
- } fileName="capabilities.tsx">
+ } fileName="capabilities.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/drawer/capabilities.tsx"
```
@@ -29,7 +29,7 @@ import { DrawerBasic } from '../../src/examples/drawer/basic';
标题、内容与底部操作分区,适合较长的设置流程。
- } fileName="sections.tsx">
+ } fileName="sections.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/drawer/sections.tsx"
```
diff --git a/apps/docs/docs/components/dropdown.mdx b/apps/docs/docs/components/dropdown.mdx
index 56d93337..b136ee89 100644
--- a/apps/docs/docs/components/dropdown.mdx
+++ b/apps/docs/docs/components/dropdown.mdx
@@ -9,7 +9,7 @@ import { DropdownBasic } from '../../src/examples/dropdown/basic';
## 操作菜单
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/dropdown/basic.tsx"
```
@@ -18,7 +18,7 @@ import { DropdownBasic } from '../../src/examples/dropdown/basic';
## 扩展用法
- } fileName="extensions.tsx">
+ } fileName="extensions.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/dropdown/extensions.tsx"
```
diff --git a/apps/docs/docs/components/error-boundary.mdx b/apps/docs/docs/components/error-boundary.mdx
index f2034e1d..0d606aff 100644
--- a/apps/docs/docs/components/error-boundary.mdx
+++ b/apps/docs/docs/components/error-boundary.mdx
@@ -8,7 +8,7 @@ import { ErrorBoundaryCustom } from '../../src/examples/error-boundary/advanced'
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/error-boundary/basic.tsx"
```
@@ -17,7 +17,7 @@ import { ErrorBoundaryCustom } from '../../src/examples/error-boundary/advanced'
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/error-boundary/advanced.tsx"
```
diff --git a/apps/docs/docs/components/file-list.mdx b/apps/docs/docs/components/file-list.mdx
index f3d796eb..e69ff13b 100644
--- a/apps/docs/docs/components/file-list.mdx
+++ b/apps/docs/docs/components/file-list.mdx
@@ -1,32 +1,84 @@
import { ComponentExample } from '../../src/components/component-example';
import { FileListBasic } from '../../src/examples/file-list/basic';
import { FileListActions } from '../../src/examples/file-list/advanced';
+import { FileListPicture } from '../../src/examples/file-list/picture';
+import { FileListCards } from '../../src/examples/file-list/cards';
+import { FileListStates } from '../../src/examples/file-list/states';
+import { FileListEmpty } from '../../src/examples/file-list/empty';
# FileList 文件列表
-展示文件名称、图标与文件操作。
+展示文件信息、上传状态,并提供预览、下载和移除操作。
## 文件信息
- } fileName="basic.tsx">
+按文件类型展示图标,文件大小可按需提供。图片支持预览,其他文件可直接下载。
+
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/file-list/basic.tsx"
```
+## 缩略图列表
+
+使用 `listType="picture"` 展示图片缩略图,非图片文件保留类型图标。
+
+ } fileName="picture.tsx" width="100%">
+
+```tsx lineNumbers file="../../src/examples/file-list/picture.tsx"
+```
+
+
+
+## 图片卡片
+
+使用 `listType="picture-card"` 展示图片卡片,预览中可以切换同一列表中的图片。
+
+ } fileName="cards.tsx" width="100%">
+
+```tsx lineNumbers file="../../src/examples/file-list/cards.tsx"
+```
+
+
+
+## 上传状态
+
+分别展示上传进度、完成、失败、等待和取消状态。失败说明放在对应文件下方。
+
+ } fileName="states.tsx" width="100%">
+
+```tsx lineNumbers file="../../src/examples/file-list/states.tsx"
+```
+
+
+
## 仅 URL 与移除操作
- } fileName="advanced.tsx">
+名称可从 URL 获取。通过 `onRemove` 更新 `items`;返回 Promise 时,移除按钮会等待操作结束。
+
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/file-list/advanced.tsx"
```
+## 空列表
+
+没有文件时展示空状态,也可以通过 `emptyContent` 自定义内容。
+
+ } fileName="empty.tsx" width="100%">
+
+```tsx lineNumbers file="../../src/examples/file-list/empty.tsx"
+```
+
+
+
## 使用说明
-名称可从 URL 获取,大小可不提供,不会自动请求文件元信息。图标根据 MIME 或后缀识别。图片、视频、音频显示预览,其他文件只提供下载。媒体能否播放取决于浏览器支持的编码。跨域下载可能在新标签打开,可通过 onDownload 接入下载服务。
+文件大小可不提供,不会自动请求文件元信息。图标根据 MIME 或后缀识别,缩略图加载失败时回退为类型图标。图片、视频、音频支持预览,其他文件只提供下载。媒体能否播放取决于浏览器支持的编码。跨域下载可能在新标签打开,可通过 `onDownload` 接入下载服务。上传交互请使用 [Upload](./upload.mdx)。
## 类型
@@ -39,14 +91,14 @@ import type { FileItem, FileListProps } from '@ifhover/leaf-ui';
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `items` | `readonly `[`FileItem`](#fileitem-api)`[]` | 必填 | 必需。展示的文件 |
-| `downloadable` | `boolean` | `true` | 显示下载 / 媒体预览操作 |
-| `previewable` | `boolean` | `true` | 显示下载 / 媒体预览操作 |
-| `removable` | `boolean` | `false` | 显示移除操作 / 禁用操作 |
-| `onPreview` | `(file: `[`FileItem`](#fileitem-api)`) => void` | — | 自定义预览或下载;预览仍仅对媒体显示 |
-| `onDownload` | `(file: `[`FileItem`](#fileitem-api)`) => void` | — | 自定义预览或下载;预览仍仅对媒体显示 |
-| `onRemove` | `(file: `[`FileItem`](#fileitem-api)`) => void \| boolean \| Promise \| Promise` | — | 请求移除,由调用方更新 items |
+| `downloadable` | `boolean` | `true` | 为有 URL 的文件显示下载操作 |
+| `previewable` | `boolean` | `true` | 为有 URL 的图片、视频和音频显示预览操作 |
+| `removable` | `boolean` | `false` | 配合 `onRemove` 显示移除操作 |
+| `onPreview` | `(file: `[`FileItem`](#fileitem-api)`) => void` | — | 接管媒体预览;未提供时使用内置预览 |
+| `onDownload` | `(file: `[`FileItem`](#fileitem-api)`) => void` | — | 接管下载;未提供时使用文件 URL |
+| `onRemove` | `(file: `[`FileItem`](#fileitem-api)`) => void \| boolean \| Promise \| Promise` | — | 请求移除,由调用方更新 `items`。等待异步操作;拒绝时在该文件行显示错误。返回 `false` 可拒绝移除 |
| `renderActions` | `(file: `[`FileItem`](#fileitem-api)`, actions: ReactNode) => ReactNode` | — | 定制操作区 |
-| `emptyContent` | `ReactNode` | — | 空列表内容 |
+| `emptyContent` | `ReactNode` | 暂无文件 | 空列表内容 |
| `disabled` | `boolean` | `false` | 禁用交互。 |
| `listType` | `'text' \| 'picture' \| 'picture-card'` | `'text'` | 文件列表的展示形式。 |
diff --git a/apps/docs/docs/components/flex.mdx b/apps/docs/docs/components/flex.mdx
new file mode 100644
index 00000000..9c046fa8
--- /dev/null
+++ b/apps/docs/docs/components/flex.mdx
@@ -0,0 +1,52 @@
+import { ComponentExample } from '../../src/components/component-example';
+import { FlexBasic } from '../../src/examples/flex/basic';
+import { FlexAlignment } from '../../src/examples/flex/alignment';
+
+# Flex 弹性布局
+
+控制内容的排列方向、对齐、间距与换行,不为子元素添加额外容器。
+
+## 基础用法
+
+通过 `gap` 设置间距,`wrap` 允许内容在空间不足时换行。
+
+ } fileName="basic.tsx">
+
+```tsx lineNumbers file="../../src/examples/flex/basic.tsx"
+```
+
+
+
+## 方向与对齐
+
+`direction` 控制排列方向,`align` 控制交叉轴对齐,`justify` 控制主轴对齐;`start` / `end` 跟随对应弹性轴的方向。
+
+ } fileName="alignment.tsx">
+
+```tsx lineNumbers file="../../src/examples/flex/alignment.tsx"
+```
+
+
+
+## Flex API
+
+| 属性 | 类型 | 默认值 | 说明 |
+| --- | --- | --- | --- |
+| `direction` | `'row' \| 'row-reverse' \| 'column' \| 'column-reverse'` | `'row'` | 排列方向。反向排列不改变 DOM 阅读与键盘顺序。 |
+| `gap` | `number \| string \| readonly [number \| string, number \| string]` | `0` | 间距;数字为 px,支持 CSS 长度和 `sm` / `md` / `lg` 主题间距。数组为 [行间距, 列间距]。 |
+| `align` | `'start' \| 'center' \| 'end' \| 'stretch' \| 'baseline'` | `'stretch'` | 交叉轴对齐。 |
+| `justify` | `'start' \| 'center' \| 'end' \| 'space-between' \| 'space-around' \| 'space-evenly'` | `'start'` | 主轴对齐。 |
+| `wrap` | `boolean \| 'nowrap' \| 'wrap' \| 'wrap-reverse'` | `false` | 是否换行或具体换行方向。 |
+| `inline` | `boolean` | `false` | 使用行内弹性布局。 |
+
+## 类型
+
+```ts
+import type { FlexGap, FlexProps } from '@ifhover/leaf-ui';
+```
+
+`FlexGap` 为 `number | string`。组件支持原生 `div` 属性、`className`、`style` 和 DOM ref;显式 `style` 优先于布局属性。
+
+## 使用说明
+
+简单等间距排列可使用 Space;需要主轴对齐、反向排列或行内布局时使用 Flex;多列布局使用 Grid。Flex 不改变子元素的外观和尺寸。
diff --git a/apps/docs/docs/components/float-button.mdx b/apps/docs/docs/components/float-button.mdx
index 27cde0ea..73a7f0e8 100644
--- a/apps/docs/docs/components/float-button.mdx
+++ b/apps/docs/docs/components/float-button.mdx
@@ -27,7 +27,7 @@ import { FloatButtonBasic, FloatButtonActions } from '../../src/examples/float-b
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
-| `variant` | `'solid' \| 'outline' \| 'ghost'` | — | 设置 variant。 |
+| `variant` | `'solid' \| 'outline' \| 'ghost' \| 'link'` | — | 设置 variant。 |
| `size` | `'sm' \| 'md' \| 'lg'` | — | 展示尺寸。 |
| `danger` | `boolean` | — | 设置 danger。 |
| `loading` | `boolean` | — | 展示加载状态。 |
@@ -52,6 +52,7 @@ import { FloatButtonBasic, FloatButtonActions } from '../../src/examples/float-b
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `actions` | `readonly `[`FloatButtonAction`](#floatbuttonaction)`[]` | — | 必需。条目操作区。 |
+| `fixed` | `boolean` | `true` | 固定在视口角落;false 时参与页面布局。 |
| `expandable` | `boolean` | `true` | 提供展开操作组的按钮。 |
| `icon` | `ReactNode` | — | 图标内容。 |
| `open` | `boolean` | — | 控制面板是否展开。 |
diff --git a/apps/docs/docs/components/form.mdx b/apps/docs/docs/components/form.mdx
index f2003f5e..be1d3180 100644
--- a/apps/docs/docs/components/form.mdx
+++ b/apps/docs/docs/components/form.mdx
@@ -9,7 +9,7 @@ import { FormLabelWidth } from '../../src/examples/form/label-width';
## 提交与校验
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={600}>
```tsx lineNumbers file="../../src/examples/form/basic.tsx"
```
@@ -18,7 +18,7 @@ import { FormLabelWidth } from '../../src/examples/form/label-width';
## 标签宽度
- } fileName="label-width.tsx">
+ } fileName="label-width.tsx" width={600}>
```tsx lineNumbers file="../../src/examples/form/label-width.tsx"
```
@@ -27,7 +27,7 @@ import { FormLabelWidth } from '../../src/examples/form/label-width';
## 扩展用法
- } fileName="extensions.tsx">
+ } fileName="extensions.tsx" width={600}>
```tsx lineNumbers file="../../src/examples/form/extensions.tsx"
```
@@ -48,11 +48,11 @@ import { FormLabelWidth } from '../../src/examples/form/label-width';
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
-| `label` | `ReactNode` | — | 标签 / 提示 / 业务错误 |
+| `label` | `ReactNode` | — | 字段标签 |
| `htmlFor` | `string` | 自动生成 | 与输入控件的 id 关联;一个字段对应一个控件或组 |
| `required` | `boolean` | `false` | 要求整体值非空,复合控件只校验一次。 |
-| `help` | `ReactNode` | — | 标签 / 提示 / 业务错误 |
-| `error` | `ReactNode` | — | 标签 / 提示 / 业务错误 |
+| `help` | `ReactNode` | — | 显示在控件下方的辅助提示,占据正常布局空间 |
+| `error` | `ReactNode` | — | 错误提示,优先于 help 展示 |
| `labelWidth` | `number` | — | 当前字段的标签宽度,单位像素 |
## 类型
@@ -67,6 +67,8 @@ import type { FormProps, FormFieldProps } from '@ifhover/leaf-ui';
默认自动计算同一 Form 中最宽的标签。标签文本、字体或可见字段变化时更新;窄屏和 vertical 布局按纵向排列。支持 onSubmit、onReset、action、method 等表单属性。
+help 和错误提示会占据正常布局空间,并与下一项保留表单间距;文字换行后自然增加高度。
+
用 FormData 读取控件上的 name。简单校验使用 required、type、minLength 等属性,错误提示跟随字段显示;业务与服务端错误通过 error 传入。设置 noValidate 可以接管校验。FormData 返回字符串,不会自动转换为数字或嵌套对象,未勾选复选框不会提交 false。受控字段的重置由应用处理。
## 扩展类型
diff --git a/apps/docs/docs/components/grid.mdx b/apps/docs/docs/components/grid.mdx
index 72d27786..fae06a03 100644
--- a/apps/docs/docs/components/grid.mdx
+++ b/apps/docs/docs/components/grid.mdx
@@ -8,7 +8,7 @@ import { GridColumns } from '../../src/examples/grid/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/grid/basic.tsx"
```
@@ -17,7 +17,7 @@ import { GridColumns } from '../../src/examples/grid/advanced';
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/grid/advanced.tsx"
```
diff --git a/apps/docs/docs/components/icons.mdx b/apps/docs/docs/components/icons.mdx
new file mode 100644
index 00000000..4d4800e1
--- /dev/null
+++ b/apps/docs/docs/components/icons.mdx
@@ -0,0 +1,42 @@
+import { ComponentExample } from '../../src/components/component-example';
+import { ButtonIcons } from '../../src/examples/button/icons';
+
+# 使用图标
+
+Leaf UI 内部及本文示例使用 **Lucide**,但 `lucide-react` 并不是唯一选择。按钮的 `startIcon` / `endIcon`、输入框的 `prefix` / `suffix` 接受 `ReactNode`,可以传入其他图标库的 React 组件。
+
+## 在线挑选图标
+
+打开 [Lucide 图标目录](https://lucide.dev/icons/),按名称或关键词搜索、预览并挑选图标。项目源码见 [Lucide GitHub 仓库](https://github.com/lucide-icons/lucide)。
+
+也可以根据项目风格和已有依赖,选用以下图标库:
+
+| 图标库 | 在线目录 | GitHub |
+| --- | --- | --- |
+| React Icons(`react-icons`) | [挑选图标](https://react-icons.github.io/react-icons/) | [react-icons/react-icons](https://github.com/react-icons/react-icons) |
+| Heroicons | [挑选图标](https://heroicons.com/) | [tailwindlabs/heroicons](https://github.com/tailwindlabs/heroicons) |
+| Tabler Icons | [挑选图标](https://tabler.io/icons) | [tabler/tabler-icons](https://github.com/tabler/tabler-icons) |
+| Phosphor | [挑选图标](https://phosphoricons.com/) | [phosphor-icons/react](https://github.com/phosphor-icons/react) |
+
+## 安装和导入
+
+以下示例使用 `lucide-react`,直接引用时将它声明为应用依赖。如果使用其他图标库,安装对应依赖并替换图标导入即可。
+
+```bash
+pnpm add lucide-react
+```
+
+按名称导入需要的图标即可。尺寸默认跟随组件的图标容器,颜色继承组件的当前文字色。
+
+ } fileName="icons.tsx">
+
+```tsx lineNumbers file="../../src/examples/button/icons.tsx"
+```
+
+
+
+## 为图标操作提供名称
+
+带文字的按钮使用文字作为名称,前后图标按装饰性内容处理。仅图标按钮必须提供 `aria-label`,例如“添加项目”或“删除项目”。图标不应作为操作含义的唯一提示。
+
+Button 的危险状态会让图标和文字一起使用危险色,无需在图标中固定颜色。
diff --git a/apps/docs/docs/components/image-cropper.mdx b/apps/docs/docs/components/image-cropper.mdx
deleted file mode 100644
index 9edab6f4..00000000
--- a/apps/docs/docs/components/image-cropper.mdx
+++ /dev/null
@@ -1,80 +0,0 @@
-import { ComponentExample } from '../../src/components/component-example';
-import { ImageCropperBasic } from '../../src/examples/image-cropper/basic';
-import { ImageCropperAvatar } from '../../src/examples/image-cropper/advanced';
-
-# ImageCropper 图片裁剪
-
-移动选框并调整裁剪范围。
-
-## 基本用法
-
- } fileName="basic.tsx">
-
-```tsx lineNumbers file="../../src/examples/image-cropper/basic.tsx"
-```
-
-
-
-## 更多用法
-
- } fileName="advanced.tsx">
-
-```tsx lineNumbers file="../../src/examples/image-cropper/advanced.tsx"
-```
-
-
-
-## 使用说明
-
-图片保持固定,拖动选框移动,拖动边缘或角点调整尺寸,支持触摸与键盘。画布默认正方形。未指定 aspect 时矩形可自由调整,圆形固定为 1:1。export() 返回 Blob。远程图片须允许 CORS;圆形 PNG 保留透明边角,JPEG 使用白底。
-
-## 类型
-
-组装数据、定义回调和使用 ref 时,可以导入这些类型。
-
-```ts
-import type { CropArea, ImageCropperHandle, ImageCropperProps, ImageCropResult } from '@ifhover/leaf-ui';
-```
-
-## CropArea API
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `x` | `number` | 必填 | 横坐标 |
-| `y` | `number` | 必填 | 纵坐标 |
-| `width` | `number` | 必填 | 宽度,数字按像素计算 |
-| `height` | `number` | 必填 | 高度,数字按像素计算 |
-
-## ImageCropperHandle API
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `export` | [`() => Promise`](#imagecropresult-api) | 必填 | 导出为 Blob |
-| `reset` | `() => void` | 必填 | 重置状态或重试 |
-
-## ImageCropperProps API
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `src` | `string` | 必填 | 图片地址 |
-| `aspect` | `number` | — | 固定裁剪比例,未提供时自由调整 |
-| `shape` | `'rect' \| 'round'` | `'rect'` | 裁剪形状 |
-| `minWidth / minHeight` | `number` | `24` | 选框最小宽高,按显示像素计算 |
-| `disabled` | `boolean` | `false` | 禁止移动和调整选框 |
-| `showActions` | `boolean` | `true` | 显示重置与裁剪按钮 |
-| `showGrid` | `boolean` | `true` | 裁剪辅助线 |
-| `crossOrigin` | `'anonymous' \| 'use-credentials'` | `'anonymous'` | 图片跨域模式,导出需要服务器允许 CORS |
-| `type` | `'image/png' \| 'image/jpeg' \| 'image/webp'` | `'image/png'` | 导出图片格式 |
-| `quality` | `number` | `0.92` | 导出质量,0–1 |
-| `onChange` | [`(area: CropArea) => void`](#croparea-api) | — | 裁剪区域变化,坐标按原图像素计算 |
-| `onExport` | [`(result: ImageCropResult) => void`](#imagecropresult-api) | — | 导出成功 |
-| `onError` | `(error: Error) => void` | — | 异常回调 |
-| `extra` | `ReactNode` | — | 补充内容或操作 |
-
-## ImageCropResult API
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `blob` | `Blob` | 必填 | 导出的 Blob |
-| `width` | `number` | 必填 | 宽度,数字按像素计算 |
-| `height` | `number` | 必填 | 高度,数字按像素计算 |
diff --git a/apps/docs/docs/components/input-mask.mdx b/apps/docs/docs/components/input-mask.mdx
index 2d9bcccb..1f8a0ed2 100644
--- a/apps/docs/docs/components/input-mask.mdx
+++ b/apps/docs/docs/components/input-mask.mdx
@@ -8,7 +8,7 @@ import { InputMaskFormats } from '../../src/examples/input-mask/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input-mask/basic.tsx"
```
@@ -17,7 +17,7 @@ import { InputMaskFormats } from '../../src/examples/input-mask/advanced';
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input-mask/advanced.tsx"
```
diff --git a/apps/docs/docs/components/input-number.mdx b/apps/docs/docs/components/input-number.mdx
index 4a709594..1d6392d8 100644
--- a/apps/docs/docs/components/input-number.mdx
+++ b/apps/docs/docs/components/input-number.mdx
@@ -8,7 +8,7 @@ import { InputNumberBasic } from '../../src/examples/input-number/basic';
## 基础用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input-number/basic.tsx"
```
@@ -17,7 +17,7 @@ import { InputNumberBasic } from '../../src/examples/input-number/basic';
## 格式化与高精度
- } fileName="capabilities.tsx">
+ } fileName="capabilities.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input-number/capabilities.tsx"
```
diff --git a/apps/docs/docs/components/input-otp.mdx b/apps/docs/docs/components/input-otp.mdx
index f7113bb5..64cf4226 100644
--- a/apps/docs/docs/components/input-otp.mdx
+++ b/apps/docs/docs/components/input-otp.mdx
@@ -8,7 +8,7 @@ import { InputOTPOptions } from '../../src/examples/input-otp/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input-otp/basic.tsx"
```
@@ -17,7 +17,7 @@ import { InputOTPOptions } from '../../src/examples/input-otp/advanced';
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input-otp/advanced.tsx"
```
diff --git a/apps/docs/docs/components/input.mdx b/apps/docs/docs/components/input.mdx
index 9e3f6982..16b0ca1d 100644
--- a/apps/docs/docs/components/input.mdx
+++ b/apps/docs/docs/components/input.mdx
@@ -12,7 +12,7 @@ import { InputPassword } from '../../src/examples/input/password';
可以使用 Lucide 图标作为前缀,或通过原生 type 指定邮箱、密码等输入方式。
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input/basic.tsx"
```
@@ -23,7 +23,7 @@ import { InputPassword } from '../../src/examples/input/password';
设置 type="password" 可输入密码并切换可见状态。可自定义切换图标,也可以隐藏切换按钮。
- } fileName="password.tsx">
+ } fileName="password.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input/password.tsx"
```
@@ -34,7 +34,7 @@ import { InputPassword } from '../../src/examples/input/password';
通过 status 表达校验结果,并用 aria-describedby 关联说明。只读内容使用 readOnly。
- } fileName="states.tsx">
+ } fileName="states.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input/states.tsx"
```
@@ -45,7 +45,7 @@ import { InputPassword } from '../../src/examples/input/password';
onPressEnter 在按下 Enter 时触发;输入法正在组合文字或事件已被阻止时不会触发。
- } fileName="controlled.tsx">
+ } fileName="controlled.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input/controlled.tsx"
```
@@ -65,7 +65,7 @@ onPressEnter 在按下 Enter 时触发;输入法正在组合文字或事件已
## 清除与字数统计
- } fileName="clear.tsx">
+ } fileName="clear.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/input/clear.tsx"
```
diff --git a/apps/docs/docs/components/layout.mdx b/apps/docs/docs/components/layout.mdx
index 198a1f23..87a012f7 100644
--- a/apps/docs/docs/components/layout.mdx
+++ b/apps/docs/docs/components/layout.mdx
@@ -8,20 +8,20 @@ import { LayoutResponsive } from '../../src/examples/layout/advanced';
## 基本用法
-通过不同背景区分 Header、Sider、Content 和 Footer,横向嵌套区域负责排列侧栏与内容。
+用 Header、Sider、Content 和 Footer 组合页面,横向嵌套区域负责排列侧栏与内容。
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/layout/basic.tsx"
```
-## 可折叠的工作区
+## 响应式侧栏
侧栏支持手动折叠,在窄屏上自动收起;菜单同步切换为图标导航。
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/layout/advanced.tsx"
```
diff --git a/apps/docs/docs/components/loading-bar.mdx b/apps/docs/docs/components/loading-bar.mdx
index af78d749..657212f1 100644
--- a/apps/docs/docs/components/loading-bar.mdx
+++ b/apps/docs/docs/components/loading-bar.mdx
@@ -8,7 +8,7 @@ import { LoadingBarProgress } from '../../src/examples/loading-bar/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/loading-bar/basic.tsx"
```
diff --git a/apps/docs/docs/components/masonry.mdx b/apps/docs/docs/components/masonry.mdx
index bc287cfd..481ed887 100644
--- a/apps/docs/docs/components/masonry.mdx
+++ b/apps/docs/docs/components/masonry.mdx
@@ -8,7 +8,7 @@ import { MasonryImages } from '../../src/examples/masonry/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/masonry/basic.tsx"
```
@@ -17,7 +17,7 @@ import { MasonryImages } from '../../src/examples/masonry/advanced';
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/masonry/advanced.tsx"
```
diff --git a/apps/docs/docs/components/menu.mdx b/apps/docs/docs/components/menu.mdx
index 44b87199..7919c562 100644
--- a/apps/docs/docs/components/menu.mdx
+++ b/apps/docs/docs/components/menu.mdx
@@ -29,7 +29,7 @@ import { MenuRouting } from '../../src/examples/menu/capabilities';
`selectedKey` 跟随当前路由。`linkRender` 可替换默认链接,例如 React Router 或 Next.js 的 Link;保留传入链接的事件、类名和 ARIA 属性。
- } fileName="capabilities.tsx">
+ } fileName="capabilities.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/menu/capabilities.tsx"
```
@@ -42,6 +42,8 @@ import { MenuRouting } from '../../src/examples/menu/capabilities';
子菜单展开、收起以及侧栏宽度变化均带有过渡。收起的子项不会参与键盘导航;系统开启减少动态效果时,过渡会自动关闭。
+菜单项、悬停背景和选中高亮与按钮共用基础圆角。通过 `ConfigProvider` 的 `theme.borderRadius` 统一调整,也可用 `theme.components.Menu.borderRadius` 单独设置菜单圆角。
+
## 类型
组装数据、定义回调和使用 ref 时,可以导入这些类型。
diff --git a/apps/docs/docs/components/message.mdx b/apps/docs/docs/components/message.mdx
index 47685e50..2eaf96c7 100644
--- a/apps/docs/docs/components/message.mdx
+++ b/apps/docs/docs/components/message.mdx
@@ -13,7 +13,6 @@ import { MessageShared } from '../../src/examples/message/shared';
```tsx
import { ConfigProvider } from '@ifhover/leaf-ui';
-import '@ifhover/leaf-ui/styles.css';
export function Root() {
return ;
@@ -46,7 +45,7 @@ export function Root() {
消息关闭时,后续消息会平滑上移。不同高度的内容会按照实际占用空间收起。
- } fileName="stack.tsx">
+ } fileName="stack.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/message/stack.tsx"
```
diff --git a/apps/docs/docs/components/modal.mdx b/apps/docs/docs/components/modal.mdx
index 38f47ec9..1eb34389 100644
--- a/apps/docs/docs/components/modal.mdx
+++ b/apps/docs/docs/components/modal.mdx
@@ -1,4 +1,4 @@
-import { AccessScope } from '../../src/examples/modal/access-scope';
+import { ModalDescription } from '../../src/examples/modal/description';
import { Capabilities } from '../../src/examples/modal/capabilities';
import { ModalFooter } from '../../src/examples/modal/footer';
import { ComponentExample } from '../../src/components/component-example';
@@ -10,7 +10,7 @@ import { ModalBasic } from '../../src/examples/modal/basic';
## 编辑内容
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/modal/basic.tsx"
```
@@ -20,7 +20,7 @@ import { ModalBasic } from '../../src/examples/modal/basic';
## 自定义底部
- } fileName="footer.tsx">
+ } fileName="footer.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/modal/footer.tsx"
```
@@ -29,20 +29,20 @@ import { ModalBasic } from '../../src/examples/modal/basic';
## 状态销毁与初始焦点
- } fileName="capabilities.tsx">
+ } fileName="capabilities.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/modal/capabilities.tsx"
```
-## 权限设置
+## 图标与说明
-结合标题说明、卡片选项和成组权限列表完成设置。
+使用 `icon` 和 `description` 为操作补充上下文。
- } fileName="access-scope.tsx">
+ } fileName="description.tsx" width="fit-content">
-```tsx lineNumbers file="../../src/examples/modal/access-scope.tsx"
+```tsx lineNumbers file="../../src/examples/modal/description.tsx"
```
diff --git a/apps/docs/docs/components/notification.mdx b/apps/docs/docs/components/notification.mdx
index dc33ee1d..2439798e 100644
--- a/apps/docs/docs/components/notification.mdx
+++ b/apps/docs/docs/components/notification.mdx
@@ -8,7 +8,7 @@ import { NotificationOptions } from '../../src/examples/notification/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/notification/basic.tsx"
```
diff --git a/apps/docs/docs/components/pagination.mdx b/apps/docs/docs/components/pagination.mdx
index e72054ce..5471c409 100644
--- a/apps/docs/docs/components/pagination.mdx
+++ b/apps/docs/docs/components/pagination.mdx
@@ -1,5 +1,8 @@
import { ComponentExample } from '../../src/components/component-example';
import { PaginationBasic } from '../../src/examples/pagination/basic';
+import { PaginationSizes } from '../../src/examples/pagination/sizes';
+import { PaginationControlled } from '../../src/examples/pagination/controlled';
+import { PaginationStates } from '../../src/examples/pagination/states';
# Pagination 分页
@@ -7,6 +10,8 @@ import { PaginationBasic } from '../../src/examples/pagination/basic';
## 基础用法
+默认使用描边按钮,也可以通过 `variant="ghost"` 使用无边框按钮。
+
} fileName="basic.tsx">
```tsx lineNumbers file="../../src/examples/pagination/basic.tsx"
@@ -14,25 +19,62 @@ import { PaginationBasic } from '../../src/examples/pagination/basic';
+## 不同尺寸
+
+分别展示小、默认和大尺寸。
+
+ } fileName="sizes.tsx">
+
+```tsx lineNumbers file="../../src/examples/pagination/sizes.tsx"
+```
+
+
+
+## 数据控制
+
+同时控制页码和每页条数;开启统计、条数选择和页码跳转。
+
+ } width={720} fileName="controlled.tsx">
+
+```tsx lineNumbers file="../../src/examples/pagination/controlled.tsx"
+```
+
+
+
+## 简洁与禁用
+
+`simple` 只保留前后翻页和当前页信息;`disabled` 禁用所有操作。
+
+ } fileName="states.tsx">
+
+```tsx lineNumbers file="../../src/examples/pagination/states.tsx"
+```
+
+
+
## Pagination API
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
-| `total` | `number` | 必填 | 数据总条数 |
-| `current / defaultCurrent` | `number` | `1` | 受控页码 / 初始页码 |
-| `pageSize / defaultPageSize` | `number` | `10` | 受控每页条数 / 初始条数 |
-| `onChange` | `(page: number, pageSize: number) => void` | — | 页码或每页条数变化 |
+| `total` | `number` | 必填 | 必需。数据总条数 |
+| `current` | `number` | — | 受控页码,从 1 开始 |
+| `defaultCurrent` | `number` | `1` | 非受控初始页码 |
+| `pageSize` | `number` | — | 受控每页条数 |
+| `defaultPageSize` | `number` | `10` | 非受控初始每页条数 |
+| `onChange` | `(page: number, pageSize: number) => void` | — | 页码或条数实际变化时调用一次,同时返回两者 |
| `showSizeChanger` | `boolean` | `false` | 展示每页条数选择器 |
-| `pageSizeOptions` | `readonly number[]` | — | 可选每页条数 |
-| `showQuickJumper` | `boolean` | `false` | 允许输入页码,回车跳转 |
-| `showTotal` | `(total: number, range: readonly [number, number]) => ReactNode` | — | 自定义总数说明 |
-| `simple` | `boolean` | `false` | 使用简洁页码展示 |
-| `disabled / hideOnSinglePage` | `boolean` | `false` | 禁用 / 单页时隐藏 |
-| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 控件尺寸 |
+| `pageSizeOptions` | `readonly number[]` | `[10, 20, 50, 100]` | 可选每页条数;自动包含当前条数,忽略无效值并去重 |
+| `showQuickJumper` | `boolean` | `false` | 回车或离开分页区域时跳转;点击其他分页控件时以该操作为准 |
+| `showTotal` | `boolean \| ((total: number, range: readonly [number, number]) => ReactNode)` | `false` | true 展示默认统计,也可传入函数自定义;range 为当前页首末条目的序号 |
+| `simple` | `boolean` | `false` | 只展示前后翻页和当前页 / 总页数 |
+| `disabled` | `boolean` | `false` | 禁用交互。 |
+| `hideOnSinglePage` | `boolean` | `false` | 总页数不足两页时隐藏 |
+| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 页码按钮、条数选择器和跳转输入框的尺寸 |
+| `variant` | `'outline' \| 'ghost'` | `'outline'` | 按钮样式:描边 / 无边框 |
-## 类型
+组件同时支持 `aria-label`、`className`、`style` 等原生 `` 属性。
-定义组件属性或组装列表时可导入相关类型。
+## 类型
```ts
import type { PaginationProps } from '@ifhover/leaf-ui';
@@ -40,4 +82,15 @@ import type { PaginationProps } from '@ifhover/leaf-ui';
## 使用说明
-页码从 1 开始。应用根据 onChange 加载对应数据;改变每页条数时,页码会尽量保留当前数据的位置。越界页码会自动限制到有效范围。
+基础分页只需提供 `total`,组件自行管理页码和条数。加载远程数据时使用 `current` 和 `pageSize`,在 `onChange` 中一起更新并请求数据;`total` 应是完整结果的总条数,而非当前页条数。
+
+改变每页条数时尽量保留当前数据位置,例如从每页 10 条的第 3 页切换到每页 20 条,会进入第 2 页。越界页码自动限制到有效范围;空数据保留第 1 页,前后按钮均禁用。外部属性变化不会额外触发 `onChange`。
+
+`showTotal` 的默认统计跟随 ConfigProvider 的语言。需要展示当前数据范围时,可以传入渲染函数:
+
+```tsx
+ `${start}–${end} / ${total} 条`}
+/>
+```
diff --git a/apps/docs/docs/components/popconfirm.mdx b/apps/docs/docs/components/popconfirm.mdx
index 91758c22..3bc559a6 100644
--- a/apps/docs/docs/components/popconfirm.mdx
+++ b/apps/docs/docs/components/popconfirm.mdx
@@ -8,7 +8,7 @@ import { PopconfirmAsync } from '../../src/examples/popconfirm/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/popconfirm/basic.tsx"
```
@@ -17,7 +17,7 @@ import { PopconfirmAsync } from '../../src/examples/popconfirm/advanced';
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/popconfirm/advanced.tsx"
```
diff --git a/apps/docs/docs/components/popover.mdx b/apps/docs/docs/components/popover.mdx
index eaec3979..c781d73a 100644
--- a/apps/docs/docs/components/popover.mdx
+++ b/apps/docs/docs/components/popover.mdx
@@ -18,7 +18,7 @@ import { PopoverPlacements } from '../../src/examples/popover/placements';
## 受控编辑
- } fileName="controlled.tsx">
+ } fileName="controlled.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/popover/controlled.tsx"
```
diff --git a/apps/docs/docs/components/qr-code.mdx b/apps/docs/docs/components/qr-code.mdx
index 64115dc7..8cc8054c 100644
--- a/apps/docs/docs/components/qr-code.mdx
+++ b/apps/docs/docs/components/qr-code.mdx
@@ -17,7 +17,7 @@ import { QRCodeStatus } from '../../src/examples/qr-code/advanced';
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/qr-code/advanced.tsx"
```
diff --git a/apps/docs/docs/components/radio.mdx b/apps/docs/docs/components/radio.mdx
index de6159a7..2aa5a591 100644
--- a/apps/docs/docs/components/radio.mdx
+++ b/apps/docs/docs/components/radio.mdx
@@ -22,7 +22,7 @@ import { RadioBasic, RadioControlled } from '../../src/components/form-examples'
通过 value / onChange 管理选择结果,direction="vertical" 设置纵向排列。
- } fileName="controlled.tsx">
+ } fileName="controlled.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/radio/controlled.tsx"
```
diff --git a/apps/docs/docs/components/rate.mdx b/apps/docs/docs/components/rate.mdx
index b5a80c29..12414194 100644
--- a/apps/docs/docs/components/rate.mdx
+++ b/apps/docs/docs/components/rate.mdx
@@ -9,7 +9,7 @@ import { RateStates } from '../../src/examples/rate/states';
## 选择评分
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/rate/basic.tsx"
```
@@ -18,7 +18,7 @@ import { RateStates } from '../../src/examples/rate/states';
## 按分数变色
- } fileName="colors.tsx">
+ } fileName="colors.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/rate/colors.tsx"
```
@@ -27,7 +27,7 @@ import { RateStates } from '../../src/examples/rate/states';
## 只读与禁用
- } fileName="states.tsx">
+ } fileName="states.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/rate/states.tsx"
```
diff --git a/apps/docs/docs/components/result.mdx b/apps/docs/docs/components/result.mdx
index 77b9b08d..11a03ee0 100644
--- a/apps/docs/docs/components/result.mdx
+++ b/apps/docs/docs/components/result.mdx
@@ -51,7 +51,7 @@ import { ResultCustom } from '../../src/examples/result/custom';
可导入以下类型定义属性、组装数据或处理回调。
```ts
-import type { ResultProps } from '@ifhover/leaf-ui';
+import type { EmptyProps, ResultProps } from '@ifhover/leaf-ui';
```
## 使用说明
@@ -59,3 +59,14 @@ import type { ResultProps } from '@ifhover/leaf-ui';
空数据使用 `status="empty"`,成功、警告、错误与信息状态有对应图标和颜色。传入 `icon`、`title`、`description` 和 `extra` 可自定义内容。
原来的 `Empty` 仍保留兼容入口,建议迁移为 `Result`:`image` 改为 `icon`,`description` 改为 `title`,原本的操作按钮移到 `extra`。
+
+## Empty API
+
+兼容组件,新增用法请使用 `Result`。`EmptyProps` 同时支持原生 `div` 属性。
+
+| 属性 | 类型 | 默认值 | 说明 |
+| --- | --- | --- | --- |
+| `image` | `ReactNode` | 空数据图标 | 自定义图标;`null` 隐藏。 |
+| `description` | `ReactNode` | 语言默认标题 | 空数据说明;`null` 隐藏。 |
+| `size` | `'sm' \| 'md'` | `'md'` | 内容间距和图标大小。 |
+| `children` | `ReactNode` | — | 底部操作内容。 |
diff --git a/apps/docs/docs/components/segmented.mdx b/apps/docs/docs/components/segmented.mdx
index 29c07600..a285757d 100644
--- a/apps/docs/docs/components/segmented.mdx
+++ b/apps/docs/docs/components/segmented.mdx
@@ -8,7 +8,7 @@ import { SegmentedOptions } from '../../src/examples/segmented/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/segmented/basic.tsx"
```
@@ -17,7 +17,7 @@ import { SegmentedOptions } from '../../src/examples/segmented/advanced';
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/segmented/advanced.tsx"
```
diff --git a/apps/docs/docs/components/select.mdx b/apps/docs/docs/components/select.mdx
index 06d5d8e4..46ab9ea6 100644
--- a/apps/docs/docs/components/select.mdx
+++ b/apps/docs/docs/components/select.mdx
@@ -1,9 +1,10 @@
+import { SingleLine } from '../../src/examples/select/single-line';
import { Capabilities } from '../../src/examples/select/capabilities';
import { ExtensionDemo } from '../../src/examples/select/extensions';
import { SelectPopup } from '../../src/examples/select/popup';
import { SelectSearch } from '../../src/examples/select/search';
import { ComponentExample } from '../../src/components/component-example';
-import { SelectBasic, SelectControlled, SelectTheme, ControlSizes } from '../../src/components/form-examples';
+import { SelectBasic, SelectControlled, ControlSizes } from '../../src/components/form-examples';
# Select 选择器
@@ -13,7 +14,7 @@ import { SelectBasic, SelectControlled, SelectTheme, ControlSizes } from '../../
通过 options 传入选项;placeholder 在空值时提示选择,单个选项可以禁用。
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/select/basic.tsx"
```
@@ -24,24 +25,13 @@ import { SelectBasic, SelectControlled, SelectTheme, ControlSizes } from '../../
value / onChange 管理选择结果,回调直接返回字符串值和选项对象。`allowClear` 显示清除按钮;status="error" 同时提供错误外观与 aria-invalid。
- } fileName="controlled.tsx">
+ } fileName="controlled.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/select/controlled.tsx"
```
-## 局部主题
-
-通过 ConfigProvider 设置局部主题,选项浮层也会使用相同的颜色与圆角。
-
- } fileName="theme.tsx">
-
-```tsx lineNumbers file="../../src/examples/select/theme.tsx"
-```
-
-
-
## 尺寸对齐
} fileName="control-sizes.tsx">
@@ -56,7 +46,7 @@ value / onChange 管理选择结果,回调直接返回字符串值和选项对
showSearch 只筛选已有选项;multiple 使用数组值并在选择后保持展开,可移除标签。
- } fileName="search.tsx">
+ } fileName="search.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/select/search.tsx"
```
@@ -65,7 +55,7 @@ showSearch 只筛选已有选项;multiple 使用数组值并在选择后保持
## 浮层宽度与内容
- } fileName="popup.tsx">
+ } fileName="popup.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/select/popup.tsx"
```
@@ -90,6 +80,17 @@ showSearch 只筛选已有选项;multiple 使用数组值并在选择后保持
+## 单行多选
+
+设置 `tagWrap={false}` 后,已选项始终展示在一行内。长文字自动省略,放不下的选项合并为 `+N`;空间很窄时只显示数量,打开浮层可查看和修改选择。`maxTagCount` 可进一步限制标签数量,`maxTagCount="responsive"` 也会启用单行自动折叠。
+
+ } fileName="single-line.tsx" width={360}>
+
+```tsx lineNumbers file="../../src/examples/select/single-line.tsx"
+```
+
+
+
## Select API
| 属性 | 类型 | 默认值 | 说明 |
@@ -119,12 +120,13 @@ showSearch 只筛选已有选项;multiple 使用数组值并在选择后保持
| `notFoundContent` | `ReactNode` | — | 没有选项时的内容 |
| `optionRender` | `(option: `[`SelectOption`](#selectoption)`) => ReactNode` | — | 自定义选项内容 |
| `maxCount` | `number` | — | 多选数量上限,已选项可继续取消 |
-| `maxTagCount` | `number \| 'responsive'` | — | 展示的标签数量,其余用数量提示 |
+| `maxTagCount` | `number \| 'responsive'` | — | 最多展示的标签数;responsive 根据可用宽度自动折叠。 |
+| `tagWrap` | `boolean` | `true` | 允许多选标签换行;false 单行显示并自动折叠溢出项。 |
| `allowCreate` | `boolean` | `false` | 允许创建未匹配的选项 |
| `onCreate` | `(option: `[`SelectOption`](#selectoption)`) => void` | — | 新选项创建回调 |
| `virtual` | `boolean` | 选项超过 100 时启用 | 仅渲染可见项目 |
| `listHeight` | `number` | `248` | 列表高度 |
-| `optionHeight` | `number` | `36` | 虚拟列表的预估选项高度 |
+| `optionHeight` | `number` | `32` | 跟随区域控件高度和密度的预估行高;实际行会被测量。 |
| `multiple` | `false \| true` | `false` | 多选时值为数组,默认 [] |
| `value` | `string \| readonly string[]` | `''` | 受控值 / 非受控初始值 |
| `defaultValue` | `string \| readonly string[]` | `''` | 受控值 / 非受控初始值 |
diff --git a/apps/docs/docs/components/signature-pad.mdx b/apps/docs/docs/components/signature-pad.mdx
deleted file mode 100644
index 21070f0d..00000000
--- a/apps/docs/docs/components/signature-pad.mdx
+++ /dev/null
@@ -1,84 +0,0 @@
-import { ComponentExample } from '../../src/components/component-example';
-import { SignaturePadBasic } from '../../src/examples/signature-pad/basic';
-import { SignaturePadControlled } from '../../src/examples/signature-pad/advanced';
-
-# SignaturePad 签名板
-
-手写签名并导出图片。
-
-## 基本用法
-
- } fileName="basic.tsx">
-
-```tsx lineNumbers file="../../src/examples/signature-pad/basic.tsx"
-```
-
-
-
-## 更多用法
-
- } fileName="advanced.tsx">
-
-```tsx lineNumbers file="../../src/examples/signature-pad/advanced.tsx"
-```
-
-
-
-## 使用说明
-
-value / onChange 保存可恢复编辑的笔画,ref.export() 返回 PNG、JPEG 或 SVG Blob。按设备像素比绘制,并在尺寸变化时保留笔画。请提供无法手写时的替代签署方式。
-
-## 类型
-
-组装数据、定义回调和使用 ref 时,可以导入这些类型。
-
-```ts
-import type { SignaturePadHandle, SignaturePadProps, SignaturePoint, SignatureStroke } from '@ifhover/leaf-ui';
-```
-
-## SignaturePadHandle API
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `clear` | `() => void` | 必填 | 清空笔迹 |
-| `undo` | `() => void` | 必填 | 撤销最后一笔 |
-| `isEmpty` | `() => boolean` | 必填 | 是否没有笔迹 |
-| `getData` | [`() => SignatureStroke[]`](#signaturestroke-api) | 必填 | 获取可编辑笔画 |
-| `export` | `(type?: 'image/png' \| 'image/jpeg' \| 'image/svg+xml') => Promise` | 必填 | 导出为 Blob |
-
-## SignaturePadProps API
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `value` | [`readonly SignatureStroke[]`](#signaturestroke-api) | — | 受控值 |
-| `defaultValue` | [`readonly SignatureStroke[]`](#signaturestroke-api) | `[]` | 非受控模式的初始笔画 |
-| `onChange` | [`(strokes: SignatureStroke[]) => void`](#signaturestroke-api) | — | 值变化回调 |
-| `onError` | `(error: Error) => void` | — | 异常回调 |
-| `penColor` | `string` | `'#203329'` | 笔迹颜色 |
-| `backgroundColor` | `string` | `'#ffffff'` | 背景颜色 |
-| `minWidth` | `number` | `0.5` | 最细笔迹宽度 |
-| `maxWidth` | `number` | `2.5` | 最粗笔迹宽度 |
-| `height` | `number` | `220` | 高度,数字按像素计算 |
-| `disabled` | `boolean` | `false` | 禁止交互 |
-| `controls` | `boolean` | `true` | 显示操作栏 |
-
-## SignaturePoint API
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `x` | `number` | 必填 | 横坐标 |
-| `y` | `number` | 必填 | 纵坐标 |
-| `pressure` | `number` | 必填 | 笔压,0–1 |
-| `time` | `number` | 必填 | 点的时间戳 |
-
-## SignatureStroke API
-
-| 属性 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `points` | [`SignaturePoint[]`](#signaturepoint-api) | 必填 | 笔画的点序列 |
-| `penColor` | `string` | 必填 | 笔迹颜色 |
-| `minWidth` | `number` | 必填 | 最细笔迹宽度 |
-| `maxWidth` | `number` | 必填 | 最粗笔迹宽度 |
-| `dotSize` | `number` | 必填 | 单点尺寸 |
-| `velocityFilterWeight` | `number` | 必填 | 速度平滑系数 |
-| `compositeOperation` | `GlobalCompositeOperation` | 必填 | Canvas 合成模式 |
diff --git a/apps/docs/docs/components/splitter.mdx b/apps/docs/docs/components/splitter.mdx
index 82cc9b2b..b5e05522 100644
--- a/apps/docs/docs/components/splitter.mdx
+++ b/apps/docs/docs/components/splitter.mdx
@@ -7,7 +7,7 @@ import { SplitterBasic, SplitterVertical } from '../../src/examples/splitter/bas
## 基础用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/splitter/basic.tsx"
```
@@ -16,7 +16,7 @@ import { SplitterBasic, SplitterVertical } from '../../src/examples/splitter/bas
## 上下布局
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/splitter/basic.tsx"
```
diff --git a/apps/docs/docs/components/steps.mdx b/apps/docs/docs/components/steps.mdx
index 1051dc91..d89cb2cb 100644
--- a/apps/docs/docs/components/steps.mdx
+++ b/apps/docs/docs/components/steps.mdx
@@ -8,7 +8,7 @@ import { StepsBasic } from '../../src/examples/steps/basic';
## 基础用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/steps/basic.tsx"
```
@@ -17,7 +17,7 @@ import { StepsBasic } from '../../src/examples/steps/basic';
## 点状与进度模式
- } fileName="capabilities.tsx">
+ } fileName="capabilities.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/steps/capabilities.tsx"
```
diff --git a/apps/docs/docs/components/switch.mdx b/apps/docs/docs/components/switch.mdx
index 662f3876..a2a6da0a 100644
--- a/apps/docs/docs/components/switch.mdx
+++ b/apps/docs/docs/components/switch.mdx
@@ -20,7 +20,7 @@ loading 显示加载图标并阻止交互,可用于异步保存期间避免重
通过 `checked` / `onChange` 管理开关状态,`size` 调整大小。
- } fileName="controlled.tsx">
+ } fileName="controlled.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/switch/controlled.tsx"
```
diff --git a/apps/docs/docs/components/table.mdx b/apps/docs/docs/components/table.mdx
index 9aa79731..357c4b0b 100644
--- a/apps/docs/docs/components/table.mdx
+++ b/apps/docs/docs/components/table.mdx
@@ -32,7 +32,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 基础用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/basic.tsx"
```
@@ -43,7 +43,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 快捷数据表格
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/basic.tsx"
```
@@ -56,7 +56,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 排序、筛选、选择与分页
- } fileName="data.tsx">
+ } fileName="data.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/data.tsx"
```
@@ -81,7 +81,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 固定表头、固定列与列宽
- } fileName="data.tsx">
+ } fileName="data.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/data.tsx"
```
@@ -96,7 +96,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 分组与聚合
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/advanced.tsx"
```
@@ -105,7 +105,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 编辑单元格
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/advanced.tsx"
```
@@ -116,7 +116,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 行和列排序
- } fileName="reordering.tsx">
+ } fileName="reordering.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/reordering.tsx"
```
@@ -129,7 +129,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 大数据
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/advanced.tsx"
```
@@ -142,7 +142,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 服务端数据
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/advanced.tsx"
```
@@ -155,7 +155,7 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## 空数据、加载和错误
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/table/basic.tsx"
```
@@ -227,7 +227,6 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
-| `table` | `TanStackTable` | — | 必需。由 useReactTable 创建的实例,唯一的数据与状态来源。 |
| `children` | `ReactNode` | — | 自定义布局;传入后不再渲染默认 Content 和 Pagination。 |
| `caption` | `ReactNode` | — | 表格说明。 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 展示尺寸。 |
@@ -242,16 +241,17 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
| `onRetry` | `() => void` | — | 请求重试。 |
| `selection` | `false \| 'single' \| 'multiple'` | `false` | 不选择、单选或多选。 |
| `selectAllMode` | `'page' \| 'all'` | `'page'` | 全选当前页,或实例内已加载的可选择行。 |
-| `getRowLabel` | `(row: Row) => string` | — | 行操作的可访问名称;默认使用稳定 row.id。 |
-| `renderExpandedRow` | `(row: Row) => ReactNode` | — | 渲染叶子行详情,同时配置 getRowCanExpand。 |
-| `getRowProps` | `(row: Row) => `[`TableRowProps`](#tablerow-api) | — | 自定义行属性与事件。 |
-| `getCellProps` | `(cell: Cell) => `[`TableCellProps`](#tablecell-api) | — | 自定义单元格属性、样式或合并;colSpan / rowSpan 为 0 时省略该单元格。 |
| `resizable` | `boolean` | `false` | 展示可调整列的宽度手柄。 |
| `columnReordering` | `boolean` | `false` | 展示单层表头的拖拽手柄。 |
-| `onRowReorder` | `(info: `[`DataTableRowReorderInfo`](#datatablerowreorderinfo)`) => void` | — | 展示行拖拽手柄,并返回重排后的当前页行;应用负责更新数据。 |
| `virtual` | `boolean \| `[`DataTableVirtualOptions`](#datatablevirtualoptions) | `false` | 启用行虚拟化。 |
| `pagination` | `boolean` | `true` | 默认布局是否展示分页器。 |
| `tableRef` | `Ref` | — | 原生表格 DOM ref。 |
+| `table` | `TanStackTable` | — | 必需。由 useReactTable 创建的实例,唯一的数据与状态来源。 |
+| `getRowLabel` | `(row: Row) => string` | — | 行操作的可访问名称;默认使用稳定 row.id。 |
+| `renderExpandedRow` | `(row: Row) => ReactNode` | — | 渲染叶子行详情,同时配置 getRowCanExpand。 |
+| `getRowProps` | `(row: Row) => `[`TableRowProps`](#tablerow-api) | — | 自定义行属性与事件。 |
+| `getCellProps` | `(cell: Cell) => `[`TableCellProps`](#tablecell-api) | — | 自定义单元格属性、样式或合并;colSpan / rowSpan 为 0 时省略该单元格。 |
+| `onRowReorder` | `(info: `[`DataTableRowReorderInfo`](#datatablerowreorderinfo)`) => void` | — | 展示行拖拽手柄,并返回重排后的当前页行;应用负责更新数据。 |
尺寸、边框、交替行、固定表头、滚动区域和 loading 与 Table 相同。`aria-label` / `aria-labelledby` 应用于原生表格,其他原生 div 属性用于外层。
@@ -284,12 +284,13 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
| --- | --- | --- | --- |
| `showSizeChanger` | `boolean` | `true` | 展示每页条数选择器。 |
| `pageSizeOptions` | `readonly number[]` | — | 可选择的每页条数。 |
-| `showQuickJumper` | `boolean` | — | 展示页码跳转输入框。 |
-| `showTotal` | `(total: number, range: readonly [number, number]) => ReactNode` | — | 定制总数及当前范围的展示。 |
+| `showQuickJumper` | `boolean` | `false` | 回车或离开分页区域时跳转。 |
+| `showTotal` | `boolean \| ((total: number, range: readonly [number, number]) => ReactNode)` | `false` | true 展示默认统计,也可传入函数定制总数及当前范围。 |
| `simple` | `boolean` | — | 使用简洁分页器。 |
| `disabled` | `boolean` | — | 禁用交互。 |
| `hideOnSinglePage` | `boolean` | — | 只有一页时隐藏分页器。 |
| `size` | `'sm' \| 'md' \| 'lg'` | — | 默认跟随 DataTable 的尺寸。 |
+| `variant` | `'outline' \| 'ghost'` | `'outline'` | 分页按钮样式:描边 / 无边框。 |
| `hasNextPage` | `boolean` | — | 未知总数时控制下一页是否可用。 |
@@ -297,6 +298,11 @@ import type { DataTableProps, DataTableColumnMeta } from '@ifhover/leaf-ui/table
## DataTableContent API
+| 属性 | 类型 | 默认值 | 说明 |
+| --- | --- | --- | --- |
+| `className` | `string` | — | 内容区域的自定义类名。 |
+| `style` | `CSSProperties` | — | 内容区域的内联样式。 |
+
`DataTable.Content` 支持原生 `div` 属性,包括 `className`、`style` 和事件。表格的布局、选择、展开与加载参数在 [DataTable](#datatable-api) 上配置,表格 DOM ref 使用 `tableRef`。公开类型为 `DataTableContentProps`。
## DataTableColumnMeta
@@ -347,3 +353,29 @@ Header / Body / Footer、Caption、Row 和 Cell 支持对应元素的原生属
| `toIndex` | `number` | — | 必需。目标当前页索引,从 0 开始。 |
| `activeRow` | `Row` | — | 必需。正在移动的行,包含稳定 row.id。 |
| `overRow` | `Row` | — | 必需。放置目标行,包含稳定 row.id。 |
+
+## DataTablePresentation API
+
+ConfigProvider 的 `components.DataTable` 使用这些与行类型无关的参数。可从 `@ifhover/leaf-ui` 导入 `DataTablePresentationProps` 组装配置;只配置默认参数不需要安装 TanStack Table,使用 DataTable 时仍需要安装。
+
+| 属性 | 类型 | 默认值 | 说明 |
+| --- | --- | --- | --- |
+| `children` | `ReactNode` | — | 子内容;嵌套数据类型表示子节点。 |
+| `caption` | `ReactNode` | — | 设置 caption。 |
+| `size` | `'sm' \| 'md' \| 'lg'` | — | 展示尺寸。 |
+| `bordered` | `boolean` | — | 设置 bordered。 |
+| `striped` | `boolean` | — | 设置 striped。 |
+| `stickyHeader` | `boolean` | — | 设置 stickyHeader。 |
+| `maxHeight` | [`TableProps`](#table-api)`['maxHeight']` | — | 设置 maxHeight。 |
+| `minWidth` | [`TableProps`](#table-api)`['minWidth']` | — | 设置 minWidth。 |
+| `loading` | `boolean` | — | 展示加载状态。 |
+| `emptyContent` | `ReactNode` | — | 没有内容时的展示。 |
+| `error` | `ReactNode` | — | 设置 error。 |
+| `onRetry` | `() => void` | — | 设置 onRetry。 |
+| `selection` | `false \| 'single' \| 'multiple'` | — | 设置 selection。 |
+| `selectAllMode` | `'page' \| 'all'` | — | 设置 selectAllMode。 |
+| `resizable` | `boolean` | — | 允许拖动和使用方向键调整大小。 |
+| `columnReordering` | `boolean` | — | 设置 columnReordering。 |
+| `virtual` | `boolean \| `[`DataTableVirtualOptions`](#datatablevirtualoptions) | — | 启用虚拟滚动;大量选项默认启用。 |
+| `pagination` | `boolean` | — | 设置 pagination。 |
+| `tableRef` | `Ref` | — | 设置 tableRef。 |
diff --git a/apps/docs/docs/components/tabs.mdx b/apps/docs/docs/components/tabs.mdx
index 2311fb57..c51e4aa4 100644
--- a/apps/docs/docs/components/tabs.mdx
+++ b/apps/docs/docs/components/tabs.mdx
@@ -3,11 +3,16 @@ import { ExtensionDemo } from '../../src/examples/tabs/extensions';
import { TabsClosable } from '../../src/examples/tabs/closable';
import { ComponentExample } from '../../src/components/component-example';
import { TabsBasic } from '../../src/examples/tabs/basic';
+import { TabsSizes } from '../../src/examples/tabs/sizes';
# Tabs 标签页
在同一区域切换不同内容。
+切换时正文和内容区域高度立即更新,不使用过渡动画;标签栏的选中指示线保留移动效果。
+
+卡片样式的标签栏默认随标签内容调整宽度,空间不足时在栏内滚动。`size` 控制整个标签栏的尺寸,正文区域使用可用宽度。
+
## 基础用法
} fileName="basic.tsx">
@@ -17,8 +22,21 @@ import { TabsBasic } from '../../src/examples/tabs/basic';
+## 不同尺寸
+
+线形与卡片标签分别展示小、默认和大尺寸。
+
+ } fileName="sizes.tsx">
+
+```tsx lineNumbers file="../../src/examples/tabs/sizes.tsx"
+```
+
+
+
## 可关闭标签页
+点击加号新增标签页。全部关闭后组件隐藏,可使用示例中的新增按钮重新打开。
+
} fileName="closable.tsx">
```tsx lineNumbers file="../../src/examples/tabs/closable.tsx"
@@ -48,13 +66,13 @@ import { TabsBasic } from '../../src/examples/tabs/basic';
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
-| `items` | `readonly `[`TabItem`](#tabitem)`[]` | 必填 | 必需。标签页列表 |
+| `items` | `readonly `[`TabItem`](#tabitem)`[]` | 必填 | 标签页列表;为空时不渲染组件 |
| `activeKey` | `string` | 首个可用项 | 受控激活项 / 初始项 |
| `defaultActiveKey` | `string` | 首个可用项 | 受控激活项 / 初始项 |
| `onChange` | `(key: string) => void` | — | 激活项变化 |
| `type` | `'line' \| 'card'` | `'line'` | 标签形态 |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` | 标签栏位置 |
-| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 标签尺寸 |
+| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 标签尺寸;卡片样式包含标签栏的内边距和边框 |
| `activationMode` | `'automatic' \| 'manual'` | `'automatic'` | 方向键直接激活 / 回车或空格激活 |
| `destroyInactive` | `boolean` | `false` | 切走时卸载内容 |
| `extra` | `ReactNode` | — | 标签栏附加内容 |
diff --git a/apps/docs/docs/components/tag.mdx b/apps/docs/docs/components/tag.mdx
index 17d29c40..73c261ea 100644
--- a/apps/docs/docs/components/tag.mdx
+++ b/apps/docs/docs/components/tag.mdx
@@ -1,4 +1,3 @@
-import { ExtensionDemo } from '../../src/examples/tag/extensions';
import { ComponentExample } from '../../src/components/component-example';
import { TagBasic } from '../../src/examples/tag/basic';
@@ -15,22 +14,13 @@ import { TagBasic } from '../../src/examples/tag/basic';
-## 扩展用法
-
- } fileName="extensions.tsx">
-
-```tsx lineNumbers file="../../src/examples/tag/extensions.tsx"
-```
-
-
-
## Tag API
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `children` | `ReactNode` | — | 标签内容 |
| `color` | `'default' \| 'primary' \| 'success' \| 'warning' \| 'error' \| 'info' \| string` | `'default'` | 语义颜色或自定义颜色 |
-| `variant` | `'soft' \| 'outline' \| 'solid'` | `'soft'` | 展示形态 |
+| `variant` | `'soft' \| 'solid'` | `'soft'` | 浅底或实色形态,均为无边框小圆角 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 标签尺寸 |
| `icon` | `ReactNode` | — | 前置图标 |
| `closable` | `boolean` | `false` | 展示关闭按钮 |
@@ -41,18 +31,14 @@ import { TagBasic } from '../../src/examples/tag/basic';
定义组件属性或组装列表时可导入相关类型。
```ts
-import type { TagProps } from '@ifhover/leaf-ui';
+import type { TagProps, CheckableTagProps, TagGroupProps, TagOption } from '@ifhover/leaf-ui';
```
## 使用说明
-调用 event.preventDefault() 可阻止默认移除。在动态列表中,也可以通过 onClose 更新应用状态并移除对应项。
-
-## 扩展类型
+标签使用无边框的小圆角,仅提供浅底与实色形态。圆角跟随区域主题,也可通过 `ConfigProvider` 的 `theme.components.Tag.borderRadius` 单独设置。
-```ts
-import type { CheckableTagProps, TagGroupProps, TagOption } from '@ifhover/leaf-ui';
-```
+调用 event.preventDefault() 可阻止默认移除。在动态列表中,也可以通过 onClose 更新应用状态并移除对应项。
## CheckableTagProps API
diff --git a/apps/docs/docs/components/textarea.mdx b/apps/docs/docs/components/textarea.mdx
index f59dc6bc..c8268601 100644
--- a/apps/docs/docs/components/textarea.mdx
+++ b/apps/docs/docs/components/textarea.mdx
@@ -8,7 +8,7 @@ import { TextareaBasic, TextareaControlled } from '../../src/components/form-exa
## 基础用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/textarea/basic.tsx"
```
@@ -19,7 +19,7 @@ import { TextareaBasic, TextareaControlled } from '../../src/components/form-exa
使用 value / onChange 管理内容,结合 maxLength 限制长度。长度提示由业务决定,resize="none" 可以关闭手动缩放。
- } fileName="controlled.tsx">
+ } fileName="controlled.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/textarea/controlled.tsx"
```
diff --git a/apps/docs/docs/components/time-picker.mdx b/apps/docs/docs/components/time-picker.mdx
index ee4a6012..fc7b6211 100644
--- a/apps/docs/docs/components/time-picker.mdx
+++ b/apps/docs/docs/components/time-picker.mdx
@@ -11,7 +11,7 @@ import { TimePickerTwelveHours } from '../../src/examples/time-picker/twelve-hou
输入时间或在面板中选择小时、分钟和秒,点击确定后生效。关闭面板会放弃未确认的调整。
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/time-picker/basic.tsx"
```
@@ -22,7 +22,7 @@ import { TimePickerTwelveHours } from '../../src/examples/time-picker/twelve-hou
通过 `value` / `onChange` 管理值,`minuteStep` 调整分钟选项的间隔。已有值的分钟不在间隔内时,仍会保留为可选项。
- } fileName="controlled.tsx">
+ } fileName="controlled.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/time-picker/controlled.tsx"
```
@@ -33,7 +33,7 @@ import { TimePickerTwelveHours } from '../../src/examples/time-picker/twelve-hou
设置 `use12Hours` 展示上午、下午选项;`showSeconds` 开启秒。12 小时制只改变显示,值仍使用 24 小时格式。
- } fileName="twelve-hours.tsx">
+ } fileName="twelve-hours.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/time-picker/twelve-hours.tsx"
```
diff --git a/apps/docs/docs/components/time-range-picker.mdx b/apps/docs/docs/components/time-range-picker.mdx
index bac22f02..2a135114 100644
--- a/apps/docs/docs/components/time-range-picker.mdx
+++ b/apps/docs/docs/components/time-range-picker.mdx
@@ -9,7 +9,7 @@ import { TimeRangePickerOptions } from '../../src/examples/time-range-picker/adv
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/time-range-picker/basic.tsx"
```
@@ -18,7 +18,7 @@ import { TimeRangePickerOptions } from '../../src/examples/time-range-picker/adv
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/time-range-picker/advanced.tsx"
```
@@ -41,7 +41,7 @@ import type { TimeRangePickerProps, TimeRange, TimeParts } from '@ifhover/leaf-u
## 限制可选时间
- } fileName="capabilities.tsx">
+ } fileName="capabilities.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/time-range-picker/capabilities.tsx"
```
diff --git a/apps/docs/docs/components/timeline.mdx b/apps/docs/docs/components/timeline.mdx
index 919f7d77..393bafc5 100644
--- a/apps/docs/docs/components/timeline.mdx
+++ b/apps/docs/docs/components/timeline.mdx
@@ -8,7 +8,7 @@ import { TimelineAlternate } from '../../src/examples/timeline/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/timeline/basic.tsx"
```
@@ -17,7 +17,7 @@ import { TimelineAlternate } from '../../src/examples/timeline/advanced';
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/timeline/advanced.tsx"
```
diff --git a/apps/docs/docs/components/tour.mdx b/apps/docs/docs/components/tour.mdx
index e6db3ddc..70276803 100644
--- a/apps/docs/docs/components/tour.mdx
+++ b/apps/docs/docs/components/tour.mdx
@@ -16,7 +16,7 @@ import { TourBasic, TourCentered } from '../../src/examples/tour/basic';
## 欢迎说明
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="fit-content">
```tsx lineNumbers file="../../src/examples/tour/basic.tsx"
```
@@ -31,7 +31,7 @@ import { TourBasic, TourCentered } from '../../src/examples/tour/basic';
| `title` | `ReactNode` | — | 必需。标题内容。 |
| `description` | `ReactNode` | — | 补充说明。 |
| `target` | `string \| (() => HTMLElement \| null)` | — | 目标的选择器或返回元素的函数;省略时居中。 |
-| `placement` | [`PopupOptions`](../guide/control-contracts#popupoptions)`['popupPlacement']` | — | 布局或展示位置。 |
+| `placement` | [`PopupOptions`](../api/popup-options#popupoptions)`['popupPlacement']` | — | 布局或展示位置。 |
## Tour API
@@ -47,7 +47,7 @@ import { TourBasic, TourCentered } from '../../src/examples/tour/basic';
| `missingTarget` | `'center' \| 'skip' \| 'close'` | `'center'` | 目标缺失时居中、跳过或关闭。 |
| `mask` | `boolean` | `true` | 展示引导遮罩。 |
| `padding` | `number` | `8` | 内容或高亮目标的内边距。 |
-| `getPopupContainer` | [`PopupOptions`](../guide/control-contracts#popupoptions)`['getPopupContainer']` | — | 返回浮层的挂载容器,也可返回 ShadowRoot。 |
+| `getPopupContainer` | [`PopupOptions`](../api/popup-options#popupoptions)`['getPopupContainer']` | — | 返回浮层的挂载容器,也可返回 ShadowRoot。 |
## 类型与交互
diff --git a/apps/docs/docs/components/transfer.mdx b/apps/docs/docs/components/transfer.mdx
index eeb8ab0a..d429c8b0 100644
--- a/apps/docs/docs/components/transfer.mdx
+++ b/apps/docs/docs/components/transfer.mdx
@@ -8,7 +8,7 @@ import { TransferVirtual } from '../../src/examples/transfer/advanced';
## 基本用法
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/transfer/basic.tsx"
```
@@ -17,7 +17,7 @@ import { TransferVirtual } from '../../src/examples/transfer/advanced';
## 更多用法
- } fileName="advanced.tsx">
+ } fileName="advanced.tsx" width="100%">
```tsx lineNumbers file="../../src/examples/transfer/advanced.tsx"
```
diff --git a/apps/docs/docs/components/tree-select.mdx b/apps/docs/docs/components/tree-select.mdx
index 9e8aeafe..33826fc7 100644
--- a/apps/docs/docs/components/tree-select.mdx
+++ b/apps/docs/docs/components/tree-select.mdx
@@ -1,3 +1,4 @@
+import { SingleLine } from '../../src/examples/tree-select/single-line';
import { Capabilities } from '../../src/examples/tree-select/capabilities';
import { ExtensionDemo } from '../../src/examples/tree-select/extensions';
import { ComponentExample } from '../../src/components/component-example';
@@ -11,7 +12,7 @@ import { TreeSelectStates } from '../../src/examples/tree-select/states';
## 选择与搜索
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/tree-select/basic.tsx"
```
@@ -20,7 +21,7 @@ import { TreeSelectStates } from '../../src/examples/tree-select/states';
## 多选与勾选
- } fileName="multiple.tsx">
+ } fileName="multiple.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/tree-select/multiple.tsx"
```
@@ -29,7 +30,7 @@ import { TreeSelectStates } from '../../src/examples/tree-select/states';
## 状态与浮层
- } fileName="states.tsx">
+ } fileName="states.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/tree-select/states.tsx"
```
@@ -54,6 +55,19 @@ import { TreeSelectStates } from '../../src/examples/tree-select/states';
+## 单行多选
+
+设置 `tagWrap={false}` 后,已选项始终展示在一行内。长文字自动省略,放不下的选项合并为 `+N`;空间很窄时只显示数量,打开浮层可查看和修改选择。`maxTagCount` 可进一步限制标签数量,`maxTagCount="responsive"` 也会启用单行自动折叠。
+
+再次打开会保留上次展开的分支。不可选分类可点击整行展开;勾选模式可点击整行或按 Enter / 空格勾选,箭头只负责展开或收起。搜索临时展开匹配分支,不改变原有展开状态。
+
+ } fileName="single-line.tsx" width={360}>
+
+```tsx lineNumbers file="../../src/examples/tree-select/single-line.tsx"
+```
+
+
+
## TreeSelect API
| 属性 | 类型 | 默认值 | 说明 |
@@ -81,11 +95,12 @@ import { TreeSelectStates } from '../../src/examples/tree-select/states';
| `onLoadError` | `(error: unknown, option: `[`TreeSelectOption`](#treeselectoption)`) => void` | — | 加载失败,再次展开可重试 |
| `virtual` | `boolean` | `false` | 仅渲染可见项目 |
| `listHeight` | `number` | `256` | 列表高度 |
-| `itemHeight` | `number` | `34` | 虚拟列表预估行高 |
+| `itemHeight` | `number` | `38` | 跟随区域控件高度和密度的预估行高,包含行间距;实际行会被测量。 |
| `inputReadOnly` | `boolean` | — | 只禁止手动输入,仍可在面板中选择。 |
| `open` | `boolean` | — | 控制面板是否展开。 |
| `defaultOpen` | `boolean` | — | 面板初始展开状态。 |
-| `maxTagCount` | `number` | — | 最多展示的标签数;responsive 根据可用宽度折叠。 |
+| `maxTagCount` | `number \| 'responsive'` | — | 最多展示的标签数;responsive 根据可用宽度自动折叠。 |
+| `tagWrap` | `boolean` | `true` | 允许多选标签换行;false 单行显示并自动折叠溢出项。 |
| `maxCount` | `number` | — | 最多可选的数量。 |
| `treeExpandedKeys` | `readonly string[]` | — | 受控的展开节点。 |
| `onExpand` | `(keys: string[]) => void` | — | 展开节点发生变化时调用。 |
diff --git a/apps/docs/docs/components/tree.mdx b/apps/docs/docs/components/tree.mdx
index e16e4ab0..0e2867ee 100644
--- a/apps/docs/docs/components/tree.mdx
+++ b/apps/docs/docs/components/tree.mdx
@@ -12,7 +12,7 @@ import { TreeSearch } from '../../src/examples/tree/search';
## 浏览与选择
- } fileName="basic.tsx">
+ } fileName="basic.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/tree/basic.tsx"
```
@@ -21,7 +21,7 @@ import { TreeSearch } from '../../src/examples/tree/search';
## 父子勾选联动
- } fileName="checkable.tsx">
+ } fileName="checkable.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/tree/checkable.tsx"
```
@@ -41,7 +41,7 @@ import { TreeSearch } from '../../src/examples/tree/search';
## 搜索节点
- } fileName="search.tsx">
+ } fileName="search.tsx" width={360}>
```tsx lineNumbers file="../../src/examples/tree/search.tsx"
```
@@ -102,7 +102,7 @@ import { TreeSearch } from '../../src/examples/tree/search';
| `onLoadError` | `(error: unknown, node: `[`TreeNode`](#treenode)`) => void` | — | 加载失败,再次展开可重试 |
| `virtual` | `boolean` | `false` | 仅渲染可视节点;大量节点时建议启用。 |
| `height` | `number` | `320` | 高度,数字按像素计算 |
-| `itemHeight` | `number` | `34` | 虚拟列表预估行高 |
+| `itemHeight` | `number` | `42` | 跟随区域控件高度和密度的预估行高,包含行间距;实际行会被测量。 |
| `draggable` | `boolean \| ((node: `[`TreeNode`](#treenode)`) => boolean)` | `false` | 允许通过手柄移动节点 |
| `allowDrop` | `(info: Omit<`[`TreeDropInfo`](#treedropinfo-api)`, 'data'>) => boolean` | — | 限制放置位置 |
| `onDrop` | `(info: `[`TreeDropInfo`](#treedropinfo-api)`) => void` | — | 移动结果,调用方更新 data |
diff --git a/apps/docs/docs/en/api/component-defaults.mdx b/apps/docs/docs/en/api/component-defaults.mdx
new file mode 100644
index 00000000..4885ffe7
--- /dev/null
+++ b/apps/docs/docs/en/api/component-defaults.mdx
@@ -0,0 +1,151 @@
+# Component defaults
+
+Use `components` on ConfigProvider to set shared default props. See [component defaults](/en/components/config-provider#component-defaults) for examples, naming rules and inheritance.
+
+## LeafComponentDefaults
+
+All entries are optional. Each entry accepts the props listed below or `null` to clear inherited defaults. Follow a linked props type for the meaning and built-in default of each prop. Required props, mode-dependent values, generic data and imperative refs remain on instances.
+
+| Property | Type | Description |
+| --- | --- | --- |
+| `Affix` | `Partial> \| null` | Configure affix. |
+| `Alert` | `Partial> \| null` | Configure alert. |
+| `Anchor` | `Partial> \| null` | Configure anchor. |
+| `AppBar` | `Partial> \| null` | Configure app bar. |
+| `AutoComplete` | `Partial> \| null` | Configure auto complete. |
+| `Avatar` | `Partial> \| null` | Configure avatar. |
+| `AvatarGroup` | `Partial> \| null` | Configure avatar group. |
+| `BackTop` | `Partial> \| null` | Configure back top. |
+| `Badge` | `Partial> \| null` | Configure badge. |
+| `BottomNavigation` | `Partial> \| null` | Configure bottom navigation. |
+| `Breadcrumb` | `Partial> \| null` | Configure breadcrumb. |
+| `Button` | `Partial> \| null` | Default button props. |
+| `ButtonGroup` | `Partial> \| null` | Configure button group. |
+| `Calendar` | `Partial> \| null` | Configure calendar. |
+| `Card` | `Partial> \| null` | Configure card. |
+| `Carousel` | `Partial> \| null` | Configure carousel. |
+| `Cascader` | `Partial< Omit< `[`CascaderProps`](../components/cascader#cascader-api)`, 'key' \| 'ref' \| 'options' \| 'multiple' \| 'value' \| 'defaultValue' \| 'onChange' > > \| null` | Configure cascader. |
+| `CheckableTag` | `Partial> \| null` | Configure checkable tag. |
+| `Checkbox` | `Partial> \| null` | Configure checkbox. |
+| `CheckboxGroup` | `Partial> \| null` | Configure checkbox group. |
+| `Col` | `Partial> \| null` | Configure col. |
+| `Collapse` | `Partial> \| null` | Configure collapse. |
+| `ColorPicker` | `Partial> \| null` | Configure color picker. |
+| `CommandPalette` | `Partial> \| null` | Configure command palette. |
+| `Confirm` | `Partial> \| null` | Configure confirm. |
+| `Countdown` | `Partial> \| null` | Configure countdown. |
+| `DataTable` | `Partial> \| null` | Configure data table. |
+| `DataTableColumnVisibility` | `Partial> \| null` | Configure data table column visibility. |
+| `DataTableContent` | `Partial> \| null` | Configure data table content. |
+| `DataTableFooter` | `Partial, 'key' \| 'ref'>> \| null` | Configure data table footer. |
+| `DataTablePagination` | `Partial> \| null` | Configure data table pagination. |
+| `DataTableSearch` | `Partial> \| null` | Configure data table search. |
+| `DataTableToolbar` | `Partial, 'key' \| 'ref'>> \| null` | Configure data table toolbar. |
+| `DatePicker` | `Partial< Omit<`[`DatePickerProps`](../components/date-picker#datepicker-api)`, 'key' \| 'ref' \| 'multiple' \| 'value' \| 'defaultValue' \| 'onChange'> > \| null` | Configure date picker. |
+| `DateRangePicker` | `Partial> \| null` | Configure date range picker. |
+| `DateTimePicker` | `Partial> \| null` | Configure date time picker. |
+| `Descriptions` | `Partial> \| null` | Configure descriptions. |
+| `Divider` | `Partial> \| null` | Configure divider. |
+| `Drawer` | `Partial> \| null` | Configure drawer. |
+| `Dropdown` | `Partial> \| null` | Configure dropdown. |
+| `Empty` | `Partial> \| null` | Configure empty. |
+| `ErrorBoundary` | `Partial> \| null` | Configure error boundary. |
+| `FileList` | `Partial> \| null` | Configure file list. |
+| `Flex` | `Partial> \| null` | Configure flex. |
+| `FloatButton` | `Partial> \| null` | Configure float button. |
+| `FloatButtonGroup` | `Partial> \| null` | Configure float button group. |
+| `Form` | `Partial> \| null` | Configure form. |
+| `FormErrorSummary` | `Partial> \| null` | Configure form error summary. |
+| `FormField` | `Partial> \| null` | Configure form field. |
+| `FormGroup` | `Partial> \| null` | Configure form group. |
+| `FormList` | `Partial< Omit< `[`FormListProps`](../components/form#formlistprops-api)`, 'name' \| 'children' \| 'value' \| 'defaultValue' \| 'onChange' \| 'itemKey' > > \| null` | Configure form list. |
+| `Grid` | `Partial> \| null` | Configure grid. |
+| `Image` | `Partial> \| null` | Configure image. |
+| `ImagePreview` | `Partial< Omit<`[`ImagePreviewProps`](../components/image#imagepreviewprops-api)`, 'key' \| 'ref' \| 'items' \| 'open' \| 'onClose'> > \| null` | Configure image preview. |
+| `ImagePreviewGroup` | `Partial> \| null` | Configure image preview group. |
+| `InfiniteScroll` | `Partial< Omit<`[`InfiniteScrollProps`](../components/infinite-scroll#infinitescrollprops-api)`, 'key' \| 'ref' \| 'dataLength' \| 'hasMore' \| 'onLoadMore'> > \| null` | Configure infinite scroll. |
+| `Input` | `Partial> \| null` | Default input props, also inherited by InputSearch. |
+| `InputGroup` | `Partial> \| null` | Configure input group. |
+| `InputMask` | `Partial> \| null` | Configure input mask. |
+| `InputNumber` | `Partial< Omit< `[`InputNumberProps`](../components/input-number#inputnumber-api)`, 'key' \| 'ref' \| 'stringMode' \| 'value' \| 'defaultValue' \| 'onChange' \| 'min' \| 'max' \| 'step' > > \| null` | Configure input number. |
+| `InputOTP` | `Partial> \| null` | Configure input otp. |
+| `InputSearch` | `Partial> \| null` | Search input defaults, overriding Input defaults. |
+| `Layout` | `Partial> \| null` | Configure layout. |
+| `LayoutContent` | `Partial, 'key' \| 'ref'>> \| null` | Configure layout content. |
+| `LayoutFooter` | `Partial, 'key' \| 'ref'>> \| null` | Configure layout footer. |
+| `LayoutHeader` | `Partial, 'key' \| 'ref'>> \| null` | Configure layout header. |
+| `LayoutSider` | `Partial> \| null` | Configure layout sider. |
+| `Link` | `Partial> \| null` | Configure link. |
+| `Loading` | `Partial> \| null` | Configure loading. |
+| `LoadingBar` | `Partial> \| null` | Configure loading bar. |
+| `Masonry` | `Partial> \| null` | Configure masonry. |
+| `Mentions` | `Partial> \| null` | Configure mentions. |
+| `Menu` | `Partial> \| null` | Configure menu. |
+| `Message` | `Partial> \| null` | Configure message. |
+| `Modal` | `Partial> \| null` | Default modal props. |
+| `Notification` | `Partial> \| null` | Configure notification. |
+| `Pagination` | `Partial> \| null` | Configure pagination. |
+| `Paragraph` | `Partial> \| null` | Configure paragraph. |
+| `Popconfirm` | `Partial> \| null` | Configure popconfirm. |
+| `Popover` | `Partial> \| null` | Configure popover. |
+| `Progress` | `Partial> \| null` | Configure progress. |
+| `QRCode` | `Partial> \| null` | Configure qrcode. |
+| `Radio` | `Partial> \| null` | Configure radio. |
+| `RadioGroup` | `Partial> \| null` | Configure radio group. |
+| `Rate` | `Partial> \| null` | Configure rate. |
+| `Result` | `Partial> \| null` | Configure result. |
+| `Row` | `Partial> \| null` | Configure row. |
+| `ScrollArea` | `Partial> \| null` | Configure scroll area. |
+| `Scrollbar` | `Partial> \| null` | Configure scrollbar. |
+| `Segmented` | `Partial> \| null` | Configure segmented. |
+| `Select` | `Partial< Omit< `[`SelectProps`](../components/select#select-api)`, 'key' \| 'ref' \| 'options' \| 'multiple' \| 'value' \| 'defaultValue' \| 'onChange' > > \| null` | Select defaults; mode, values and change callbacks stay on the instance. |
+| `Skeleton` | `Partial> \| null` | Configure skeleton. |
+| `Slider` | `Partial< Omit<`[`SliderProps`](../components/slider#slider-api)`, 'key' \| 'ref' \| 'range' \| 'value' \| 'defaultValue' \| 'onChange'> > \| null` | Configure slider. |
+| `Space` | `Partial> \| null` | Configure space. |
+| `SplitButton` | `Partial> \| null` | Configure split button. |
+| `Splitter` | `Partial> \| null` | Configure splitter. |
+| `Statistic` | `Partial> \| null` | Configure statistic. |
+| `Steps` | `Partial