feat(docs): add bilingual package documentation site
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: Adapter and pagination
|
||||
description: Implement cancellable search requests and return mergeable grouped pages.
|
||||
order: 20
|
||||
toc:
|
||||
- id: implement-adapter
|
||||
title: Implement the adapter
|
||||
- id: group-results
|
||||
title: Group results
|
||||
- id: paginate
|
||||
title: Paginate
|
||||
---
|
||||
|
||||
## Implement the adapter {#implement-adapter}
|
||||
|
||||
`SearchAdapter` is the package's only data dependency:
|
||||
|
||||
```ts
|
||||
const searchAdapter: SearchAdapter = {
|
||||
async search({ cursor, query, signal }) {
|
||||
const response = await fetch(
|
||||
`/api/search?q=${encodeURIComponent(query)}&cursor=${cursor ?? ""}`,
|
||||
{ signal }
|
||||
)
|
||||
|
||||
if (!response.ok) throw new Error("Search request failed")
|
||||
return response.json()
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Pass `signal` to the underlying request so an older response cannot replace a newer query.
|
||||
|
||||
## Group results {#group-results}
|
||||
|
||||
Each `SearchPage` contains `SearchResultGroup` values. Keep a group's `id` stable between pages and each item's `id` stable inside its group. Search uses both identifiers to merge results and remove duplicates.
|
||||
|
||||
Use `payload` for application data and `icon` or `image` to customize result presentation.
|
||||
|
||||
## Paginate {#paginate}
|
||||
|
||||
Return `nextCursor` when another page is available; return `null` or omit it at the end. The surface only displays “Load more” while a cursor exists. A cursor can be a string or number and is passed back to the adapter unchanged.
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: Global search example
|
||||
description: Compose a trigger, dialog, recent searches, and result navigation.
|
||||
order: 30
|
||||
toc:
|
||||
- id: define-results
|
||||
title: Define results
|
||||
- id: handle-selection
|
||||
title: Handle selection
|
||||
- id: control-history
|
||||
title: Control history
|
||||
---
|
||||
|
||||
## Define results {#define-results}
|
||||
|
||||
```ts
|
||||
const searchAdapter: SearchAdapter = {
|
||||
async search({ query }) {
|
||||
return {
|
||||
groups: [
|
||||
{
|
||||
id: "docs",
|
||||
label: "Documentation",
|
||||
items: documents
|
||||
.filter((document) => document.title.includes(query))
|
||||
.map((document) => ({
|
||||
id: document.slug,
|
||||
title: document.title,
|
||||
description: document.description,
|
||||
payload: { href: `/docs/${document.slug}` },
|
||||
})),
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Handle selection {#handle-selection}
|
||||
|
||||
```tsx
|
||||
<SearchProvider
|
||||
adapter={searchAdapter}
|
||||
onSelect={({ item }) => {
|
||||
const payload = item.payload as { href: string }
|
||||
router.navigate({ to: payload.href })
|
||||
}}
|
||||
>
|
||||
<HeaderSearchButton />
|
||||
<SearchDialog />
|
||||
</SearchProvider>
|
||||
```
|
||||
|
||||
Code that cannot render `SearchTrigger` can call `searchDialogHandle.open(null)`.
|
||||
|
||||
## Control history {#control-history}
|
||||
|
||||
Recent searches use `workspace-search-history` by default. Supply a product-specific `historyStorageKey`, or set it to `false` to keep history in memory for the current session only.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: Installation and setup
|
||||
description: Add Search, register its catalog, and mount the search surface.
|
||||
order: 10
|
||||
toc:
|
||||
- id: add-the-package
|
||||
title: Add the package
|
||||
- id: import-styles
|
||||
title: Import styles
|
||||
- id: mount-search
|
||||
title: Mount search
|
||||
---
|
||||
|
||||
## Add the package {#add-the-package}
|
||||
|
||||
Add Search to the consuming application:
|
||||
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"@workspace/search": "workspace:*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Import styles {#import-styles}
|
||||
|
||||
Import the Search stylesheet once from the application's global stylesheet so Tailwind scans the utilities used by the package:
|
||||
|
||||
```css
|
||||
@import "@workspace/search/globals.css";
|
||||
```
|
||||
|
||||
Also add `@workspace/search/locales/{locale}` to the application's internationalization catalog sources.
|
||||
|
||||
## Mount search {#mount-search}
|
||||
|
||||
```tsx
|
||||
import { SearchDialog, SearchProvider, SearchTrigger } from "@workspace/search"
|
||||
|
||||
;<SearchProvider adapter={searchAdapter} onSelect={openResult}>
|
||||
<SearchTrigger>Search</SearchTrigger>
|
||||
<SearchDialog />
|
||||
</SearchProvider>
|
||||
```
|
||||
|
||||
`SearchDialog` registers `Mod+K` by default. Pass `hotkey={false}` when the application manages shortcuts centrally.
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: Overview
|
||||
description: Understand the Search package data boundary, interactions, and use cases.
|
||||
order: 1
|
||||
toc:
|
||||
- id: package-role
|
||||
title: Package role
|
||||
- id: capabilities
|
||||
title: Capabilities
|
||||
- id: design-boundary
|
||||
title: Design boundary
|
||||
---
|
||||
|
||||
## Package role {#package-role}
|
||||
|
||||
`@workspace/search` provides an application-search surface and its state management. The host supplies data through `SearchAdapter`; Search owns the query lifecycle, pagination, result presentation, selection interactions, and recent searches.
|
||||
|
||||
## Capabilities {#capabilities}
|
||||
|
||||
- Connect any HTTP API, database, command registry, or local index through an adapter.
|
||||
- Present results in domain groups and merge paginated data.
|
||||
- Cancel stale requests with `AbortSignal`.
|
||||
- Keep recent searches with configurable local persistence.
|
||||
- Provide a `Mod+K` shortcut plus empty, loading, and error states.
|
||||
- Ship `en-US` and `zh-Hans` message catalogs.
|
||||
|
||||
## Design boundary {#design-boundary}
|
||||
|
||||
Search does not choose the data source or perform navigation. The application implements the adapter and interprets each result's `payload` in `onSelect`.
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: Adapter 与分页
|
||||
description: 实现可取消的搜索请求,并返回可合并的分组分页结果。
|
||||
order: 20
|
||||
toc:
|
||||
- id: implement-adapter
|
||||
title: 实现 Adapter
|
||||
- id: group-results
|
||||
title: 组织结果
|
||||
- id: paginate
|
||||
title: 分页
|
||||
---
|
||||
|
||||
## 实现 Adapter {#implement-adapter}
|
||||
|
||||
`SearchAdapter` 是 Search 唯一的数据依赖:
|
||||
|
||||
```ts
|
||||
const searchAdapter: SearchAdapter = {
|
||||
async search({ cursor, query, signal }) {
|
||||
const response = await fetch(
|
||||
`/api/search?q=${encodeURIComponent(query)}&cursor=${cursor ?? ""}`,
|
||||
{ signal }
|
||||
)
|
||||
|
||||
if (!response.ok) throw new Error("Search request failed")
|
||||
return response.json()
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
必须把 `signal` 传给底层请求,避免较早的响应覆盖较新的查询。
|
||||
|
||||
## 组织结果 {#group-results}
|
||||
|
||||
每个 `SearchPage` 包含若干 `SearchResultGroup`。Group 的 `id` 在分页之间应保持稳定;Item 的 `id` 在所属 Group 内应保持稳定。Search 会用这两个标识合并结果并消除重复项。
|
||||
|
||||
可以通过 `payload` 携带应用数据,通过 `icon` 或 `image` 自定义结果外观。
|
||||
|
||||
## 分页 {#paginate}
|
||||
|
||||
还有后续数据时返回 `nextCursor`;没有更多结果时返回 `null` 或省略。界面只在存在游标时显示“加载更多”。游标可以是字符串或数字,并会原样传回 Adapter。
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: 全局搜索示例
|
||||
description: 组合触发器、对话框、历史记录和结果导航。
|
||||
order: 30
|
||||
toc:
|
||||
- id: define-results
|
||||
title: 定义结果
|
||||
- id: handle-selection
|
||||
title: 处理选择
|
||||
- id: control-history
|
||||
title: 控制历史记录
|
||||
---
|
||||
|
||||
## 定义结果 {#define-results}
|
||||
|
||||
```ts
|
||||
const searchAdapter: SearchAdapter = {
|
||||
async search({ query }) {
|
||||
return {
|
||||
groups: [
|
||||
{
|
||||
id: "docs",
|
||||
label: "文档",
|
||||
items: documents
|
||||
.filter((document) => document.title.includes(query))
|
||||
.map((document) => ({
|
||||
id: document.slug,
|
||||
title: document.title,
|
||||
description: document.description,
|
||||
payload: { href: `/docs/${document.slug}` },
|
||||
})),
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## 处理选择 {#handle-selection}
|
||||
|
||||
```tsx
|
||||
<SearchProvider
|
||||
adapter={searchAdapter}
|
||||
onSelect={({ item }) => {
|
||||
const payload = item.payload as { href: string }
|
||||
router.navigate({ to: payload.href })
|
||||
}}
|
||||
>
|
||||
<HeaderSearchButton />
|
||||
<SearchDialog />
|
||||
</SearchProvider>
|
||||
```
|
||||
|
||||
不方便渲染 `SearchTrigger` 的位置可以调用 `searchDialogHandle.open(null)`。
|
||||
|
||||
## 控制历史记录 {#control-history}
|
||||
|
||||
历史记录默认保存在 `workspace-search-history`。为不同产品传入独立的 `historyStorageKey`,或者设置为 `false`,让历史只存在于当前内存会话中。
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: 安装与接入
|
||||
description: 添加 Search、注册翻译目录并挂载搜索界面。
|
||||
order: 10
|
||||
toc:
|
||||
- id: add-the-package
|
||||
title: 添加包
|
||||
- id: import-styles
|
||||
title: 导入样式
|
||||
- id: mount-search
|
||||
title: 挂载搜索
|
||||
---
|
||||
|
||||
## 添加包 {#add-the-package}
|
||||
|
||||
将 Search 加入应用依赖:
|
||||
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"@workspace/search": "workspace:*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 导入样式 {#import-styles}
|
||||
|
||||
在应用的全局样式入口导入一次 Search 样式,使 Tailwind 扫描包内使用的 utilities:
|
||||
|
||||
```css
|
||||
@import "@workspace/search/globals.css";
|
||||
```
|
||||
|
||||
同时将 `@workspace/search/locales/{locale}` 加入应用的国际化目录来源。
|
||||
|
||||
## 挂载搜索 {#mount-search}
|
||||
|
||||
```tsx
|
||||
import { SearchDialog, SearchProvider, SearchTrigger } from "@workspace/search"
|
||||
|
||||
;<SearchProvider adapter={searchAdapter} onSelect={openResult}>
|
||||
<SearchTrigger>搜索</SearchTrigger>
|
||||
<SearchDialog />
|
||||
</SearchProvider>
|
||||
```
|
||||
|
||||
`SearchDialog` 默认注册 `Mod+K`。如果应用已经统一管理快捷键,可以传入 `hotkey={false}`。
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: 概览
|
||||
description: 了解 Search 包的数据边界、交互能力和适用场景。
|
||||
order: 1
|
||||
toc:
|
||||
- id: package-role
|
||||
title: 包的职责
|
||||
- id: capabilities
|
||||
title: 主要能力
|
||||
- id: design-boundary
|
||||
title: 设计边界
|
||||
---
|
||||
|
||||
## 包的职责 {#package-role}
|
||||
|
||||
`@workspace/search` 提供应用级搜索界面与状态管理。宿主应用通过 `SearchAdapter` 提供数据,Search 负责查询生命周期、分页、结果展示、选择交互和搜索历史。
|
||||
|
||||
## 主要能力 {#capabilities}
|
||||
|
||||
- 使用 Adapter 连接任意 HTTP API、数据库、命令注册表或本地索引。
|
||||
- 按业务来源分组展示结果,并合并分页数据。
|
||||
- 使用 `AbortSignal` 取消已经过期的查询。
|
||||
- 提供最近搜索记录和可配置的本地持久化。
|
||||
- 内置 `Mod+K` 快捷键、无结果、加载与错误状态。
|
||||
- 提供 `en-US` 和 `zh-Hans` 消息目录。
|
||||
|
||||
## 设计边界 {#design-boundary}
|
||||
|
||||
Search 不决定数据从哪里获取,也不负责路由跳转。应用实现 Adapter,并在 `onSelect` 中解释结果的 `payload`。
|
||||
Reference in New Issue
Block a user