@omit-design/preset-mobile 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,29 +1,122 @@
1
1
  # @omit-design/preset-mobile
2
2
 
3
- omit-design 的默认移动端 preset:Om* 组件白名单 + `--om-*` token 体系 + Ionic 8 运行时。
3
+ > Default mobile preset for [omit-design](https://github.com/leefanv/omit-design): `Om*` whitelist components, `--om-*` token system, Ionic 8 runtime, and 8 ready-to-use patterns with copy-paste templates.
4
4
 
5
- ## 三条硬规则(由 [@omit-design/eslint-plugin](../eslint-plugin/) 强制)
5
+ [![npm](https://img.shields.io/npm/v/@omit-design/preset-mobile)](https://www.npmjs.com/package/@omit-design/preset-mobile)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
6
7
 
7
- 1. **Token 优先**:所有颜色、间距、字号、圆角、阴影必须走 token,**禁止字面量**(`#FF6B00`、`12px`、`16px` 等都不允许出现在业务代码里)
8
- 2. **组件白名单**:业务页面(`design/**`)只能 import `@omit-design/preset-mobile`,**禁止**直接 import `@ionic/react`(例外:`IonList` / `IonBackButton` / `IonIcon`,仅做排版/图标宿主)
9
- 3. **模式标注**:每个业务页面文件头第一行必须是 `// @pattern: <name>`,name 必须存在于 [PATTERNS.md](./PATTERNS.md)
8
+ [简体中文](./README.zh-CN.md)
10
9
 
11
- ## 组件清单
10
+ ## What it is
12
11
 
13
- 21 Om* 组件,全部从 `@omit-design/preset-mobile` 导出:
12
+ `preset-mobile` is the canonical preset most omit-design projects use. It provides:
14
13
 
15
- `OmPage` `OmHeader` `OmAppBar` `OmButton` `OmCard` `OmListRow` `OmInput` `OmSelect` `OmDialog` `OmTabBar` `OmNumpad` `OmSearchBar` `OmProductCard` `OmEmptyState` `OmTag` `OmOrderFooter` `OmCouponCard` `OmStatCard` `OmMenuCard` `OmSettingRow` `OmSheet`
14
+ - **21 `Om*` components** the import whitelist for `design/**/*.tsx`
15
+ - **`--om-*` token system** mapped to Ionic 8 runtime (`--ion-*`)
16
+ - **8 patterns** with copy-paste `.tmpl.tsx` skeletons (consumed by `omit-design new-page`)
16
17
 
17
- 详见 [components/index.ts](./components/index.ts)
18
+ ## Three hard rules (enforced by [@omit-design/eslint-plugin](../eslint-plugin/))
18
19
 
19
- ## 设计模式
20
+ 1. **Tokens only.** All colors / spacing / font sizes / radii / shadows must go through tokens. Raw literals (`#FF6B00`, `12px`, `16px`, etc.) are forbidden in business code.
21
+ 2. **Whitelist imports.** Business pages (under `design/**`) can only import from `@omit-design/preset-mobile`. Direct `@ionic/react` imports are forbidden — exceptions: `IonList`, `IonBackButton`, `IonIcon` (layout / icon hosts only).
22
+ 3. **Pattern header.** Every business page must start with `// @pattern: <name>`, where `<name>` is registered in [PATTERNS.md](./PATTERNS.md).
20
23
 
21
- 8 个开箱即用的 pattern,每个有可复制的 template:
24
+ ## Components (21)
22
25
 
23
- `list-view` `detail-view` `form-view` `sheet-action` `dialog-view` `welcome-view` `dashboard` `tab-view`
26
+ All exported from `@omit-design/preset-mobile`:
24
27
 
25
- 详见 [PATTERNS.md](./PATTERNS.md)。
28
+ | Layout | Inputs | Display | Overlays |
29
+ |---|---|---|---|
30
+ | `OmPage` | `OmInput` | `OmCard` | `OmDialog` |
31
+ | `OmHeader` | `OmSelect` | `OmListRow` | `OmSheet` |
32
+ | `OmAppBar` | `OmSearchBar` | `OmStatCard` | |
33
+ | `OmTabBar` | `OmNumpad` | `OmMenuCard` | |
34
+ | | `OmButton` | `OmProductCard` | |
35
+ | | | `OmCouponCard` | |
36
+ | | | `OmSettingRow` | |
37
+ | | | `OmEmptyState` | |
38
+ | | | `OmTag` | |
39
+ | | | `OmOrderFooter` | |
26
40
 
27
- ## Token 命名
41
+ Full source list: [components/index.ts](./components/index.ts).
28
42
 
29
- `--om-color-*` `--om-spacing-*` `--om-radius-*` `--om-font-size-*` `--om-shadow-*` 详见 [theme/variables.css](./theme/variables.css)
43
+ ## Patterns (8)
44
+
45
+ Each pattern ships:
46
+ - A documented section in [PATTERNS.md](./PATTERNS.md)
47
+ - A copy-paste `.tmpl.tsx` template
48
+
49
+ | Pattern | Use for |
50
+ |---|---|
51
+ | `dashboard` | Stat cards + entry tiles (cafe POS home, admin overview) |
52
+ | `list-view` | Vertical list with filter / search |
53
+ | `detail-view` | Single record with sections (order, product, member) |
54
+ | `form-view` | Input-heavy edit / create forms |
55
+ | `dialog-view` | Modal with title + body + actions |
56
+ | `sheet-action` | Bottom sheet for quick actions |
57
+ | `tab-view` | Top-tab segmented content |
58
+ | `welcome-view` | First-launch / onboarding |
59
+
60
+ Generate a new page from a pattern:
61
+ ```bash
62
+ npx omit-design new-page list-view design/orders/list
63
+ # → design/orders/list.tsx with the list-view skeleton
64
+ ```
65
+
66
+ ## Token naming
67
+
68
+ | Family | Examples |
69
+ |---|---|
70
+ | `--om-color-*` | `--om-color-primary`, `--om-color-text`, `--om-color-text-muted` |
71
+ | `--om-spacing-*` | `--om-spacing-xs` (4) … `--om-spacing-xxl` (32) |
72
+ | `--om-radius-*` | `--om-radius-sm`, `--om-radius-md`, `--om-radius-lg` |
73
+ | `--om-font-size-*` | `--om-font-size-sm`, `--om-font-size-md`, `--om-font-size-lg` |
74
+ | `--om-shadow-*` | `--om-shadow-sm`, `--om-shadow-md` |
75
+
76
+ Defaults defined in [theme/variables.css](./theme/variables.css). Override in your project's CSS:
77
+
78
+ ```css
79
+ :root {
80
+ --om-color-primary: #ff6b00;
81
+ --om-radius-md: 8px;
82
+ }
83
+ ```
84
+
85
+ Or use the in-browser theme editor at `/workspace/:projectId/theme-editor` (writes back to your `preset/theme.css`).
86
+
87
+ ## Install
88
+
89
+ ```bash
90
+ npm install @omit-design/preset-mobile @omit-design/engine @ionic/react ionicons
91
+ ```
92
+
93
+ Required peers: `@omit-design/engine ^0.2.0`, `@ionic/react ^8`, `ionicons ^7 || ^8`, `react ^19`, `react-router-dom ^6`.
94
+
95
+ ## Usage
96
+
97
+ ```tsx
98
+ // design/main/welcome.tsx
99
+ // @pattern: welcome-view
100
+ export const meta = {
101
+ name: "Welcome",
102
+ pattern: "welcome-view",
103
+ description: "First-launch screen",
104
+ } as const;
105
+
106
+ import { OmButton, OmPage } from "@omit-design/preset-mobile";
107
+
108
+ export default function Welcome() {
109
+ return (
110
+ <OmPage padding="none">
111
+ <div style={{ padding: "var(--om-spacing-xl)" }}>
112
+ <h1>Hello</h1>
113
+ <OmButton expand="block">Continue</OmButton>
114
+ </div>
115
+ </OmPage>
116
+ );
117
+ }
118
+ ```
119
+
120
+ ## License
121
+
122
+ [MIT](../../LICENSE)
@@ -0,0 +1,123 @@
1
+ # @omit-design/preset-mobile
2
+
3
+ > [omit-design](https://github.com/leefanv/omit-design) 的默认移动端 preset:`Om*` 组件白名单 + `--om-*` token 体系 + Ionic 8 运行时 + 8 个开箱即用 pattern 与对应模板。
4
+
5
+ [![npm](https://img.shields.io/npm/v/@omit-design/preset-mobile)](https://www.npmjs.com/package/@omit-design/preset-mobile)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
7
+
8
+ [English](./README.md)
9
+
10
+ ## 这是什么
11
+
12
+ `preset-mobile` 是 omit-design 项目默认用的 preset,提供:
13
+
14
+ - **21 个 `Om*` 组件** — `design/**/*.tsx` 的 import 白名单
15
+ - **`--om-*` token 体系**,映射到 Ionic 8 运行时(`--ion-*`)
16
+ - **8 个 pattern** + 对应的 `.tmpl.tsx` 模板(`omit-design new-page` 消费)
17
+
18
+ ## 三条硬规则(由 [@omit-design/eslint-plugin](../eslint-plugin/) 强制)
19
+
20
+ 1. **Token 优先**:所有颜色、间距、字号、圆角、阴影必须走 token,**禁止字面量**(`#FF6B00`、`12px`、`16px` 等都不允许出现在业务代码里)。
21
+ 2. **组件白名单**:业务页面(`design/**`)只能 import `@omit-design/preset-mobile`,**禁止**直接 import `@ionic/react`(例外:`IonList` / `IonBackButton` / `IonIcon`,仅做排版/图标宿主)。
22
+ 3. **模式标注**:每个业务页面文件头第一行必须是 `// @pattern: <name>`,`<name>` 必须在 [PATTERNS.md](./PATTERNS.md) 里登记。
23
+
24
+ ## 组件清单(21 个)
25
+
26
+ 全部从 `@omit-design/preset-mobile` 导出:
27
+
28
+ | 布局 | 输入 | 展示 | 浮层 |
29
+ |---|---|---|---|
30
+ | `OmPage` | `OmInput` | `OmCard` | `OmDialog` |
31
+ | `OmHeader` | `OmSelect` | `OmListRow` | `OmSheet` |
32
+ | `OmAppBar` | `OmSearchBar` | `OmStatCard` | |
33
+ | `OmTabBar` | `OmNumpad` | `OmMenuCard` | |
34
+ | | `OmButton` | `OmProductCard` | |
35
+ | | | `OmCouponCard` | |
36
+ | | | `OmSettingRow` | |
37
+ | | | `OmEmptyState` | |
38
+ | | | `OmTag` | |
39
+ | | | `OmOrderFooter` | |
40
+
41
+ 完整列表:[components/index.ts](./components/index.ts)。
42
+
43
+ ## Patterns(8 个)
44
+
45
+ 每个 pattern 自带:
46
+ - [PATTERNS.md](./PATTERNS.md) 里一段文档
47
+ - 一份可复制的 `.tmpl.tsx` 模板
48
+
49
+ | Pattern | 适用场景 |
50
+ |---|---|
51
+ | `dashboard` | 统计卡 + 入口磁贴(咖啡店 POS 首页、admin 总览) |
52
+ | `list-view` | 带筛选 / 搜索的纵向列表 |
53
+ | `detail-view` | 单条记录详情(订单、商品、会员) |
54
+ | `form-view` | 输入密集的编辑 / 创建表单 |
55
+ | `dialog-view` | 标题 + 内容 + 操作按钮的模态 |
56
+ | `sheet-action` | 底部弹起的快捷操作 |
57
+ | `tab-view` | 顶部分段切换 |
58
+ | `welcome-view` | 首启 / 引导页 |
59
+
60
+ 从 pattern 生成新页面:
61
+
62
+ ```bash
63
+ npx omit-design new-page list-view design/orders/list
64
+ # → design/orders/list.tsx 已含 list-view 骨架
65
+ ```
66
+
67
+ ## Token 命名
68
+
69
+ | 类别 | 例子 |
70
+ |---|---|
71
+ | `--om-color-*` | `--om-color-primary` / `--om-color-text` / `--om-color-text-muted` |
72
+ | `--om-spacing-*` | `--om-spacing-xs` (4) … `--om-spacing-xxl` (32) |
73
+ | `--om-radius-*` | `--om-radius-sm` / `--om-radius-md` / `--om-radius-lg` |
74
+ | `--om-font-size-*` | `--om-font-size-sm` / `--om-font-size-md` / `--om-font-size-lg` |
75
+ | `--om-shadow-*` | `--om-shadow-sm` / `--om-shadow-md` |
76
+
77
+ 默认值在 [theme/variables.css](./theme/variables.css)。在项目 CSS 里覆盖:
78
+
79
+ ```css
80
+ :root {
81
+ --om-color-primary: #ff6b00;
82
+ --om-radius-md: 8px;
83
+ }
84
+ ```
85
+
86
+ 或用浏览器内的主题编辑器(`/workspace/:projectId/theme-editor`),编辑后写回项目的 `preset/theme.css`。
87
+
88
+ ## 安装
89
+
90
+ ```bash
91
+ npm install @omit-design/preset-mobile @omit-design/engine @ionic/react ionicons
92
+ ```
93
+
94
+ peer 依赖:`@omit-design/engine ^0.2.0`、`@ionic/react ^8`、`ionicons ^7 || ^8`、`react ^19`、`react-router-dom ^6`。
95
+
96
+ ## 用例
97
+
98
+ ```tsx
99
+ // design/main/welcome.tsx
100
+ // @pattern: welcome-view
101
+ export const meta = {
102
+ name: "欢迎",
103
+ pattern: "welcome-view",
104
+ description: "首启页",
105
+ } as const;
106
+
107
+ import { OmButton, OmPage } from "@omit-design/preset-mobile";
108
+
109
+ export default function Welcome() {
110
+ return (
111
+ <OmPage padding="none">
112
+ <div style={{ padding: "var(--om-spacing-xl)" }}>
113
+ <h1>你好</h1>
114
+ <OmButton expand="block">开始</OmButton>
115
+ </div>
116
+ </OmPage>
117
+ );
118
+ }
119
+ ```
120
+
121
+ ## 许可
122
+
123
+ [MIT](../../LICENSE)
@@ -39,7 +39,7 @@ export function OmDialog({
39
39
  iconColor = "primary",
40
40
  title,
41
41
  subtitle,
42
- confirmText = "知道了",
42
+ confirmText = "OK",
43
43
  confirmColor = "primary",
44
44
  confirmHref,
45
45
  onConfirm,
@@ -81,7 +81,7 @@ export function OmDialog({
81
81
  <>
82
82
  {hasCancel && (
83
83
  <OmButton variant="outline" color="medium" onClick={handleCancel}>
84
- {cancelText ?? "取消"}
84
+ {cancelText ?? "Cancel"}
85
85
  </OmButton>
86
86
  )}
87
87
  <OmButton color={confirmColor} onClick={handleConfirm}>
@@ -63,14 +63,14 @@ export function OmNumpad({
63
63
  {/* 右下角 */}
64
64
  {clearMode ? (
65
65
  <button className="om-numpad__key pos-numpad__key--clear" type="button" onClick={() => onClear?.()}>
66
- 清空
66
+ Clear
67
67
  </button>
68
68
  ) : showBackspace ? (
69
69
  <button
70
70
  className="om-numpad__key pos-numpad__key--ghost"
71
71
  type="button"
72
72
  onClick={() => onBackspace?.()}
73
- aria-label="退格"
73
+ aria-label="Backspace"
74
74
  >
75
75
  <IonIcon icon={backspaceOutline} />
76
76
  </button>
@@ -43,7 +43,7 @@ export function OmOrderFooter({
43
43
  className="om-order-footer__cart"
44
44
  type="button"
45
45
  onClick={onCartClick}
46
- aria-label="购物车"
46
+ aria-label="Cart"
47
47
  >
48
48
  <IonIcon icon={cartOutline} />
49
49
  {typeof cartCount === "number" && cartCount > 0 && (
@@ -55,7 +55,7 @@ export function OmOrderFooter({
55
55
  <button className="om-order-footer__discount" type="button" onClick={onDiscountClick}>
56
56
  <span className="om-order-footer__discount-amount">{discountLabel}</span>
57
57
  <span className="om-order-footer__discount-label">
58
- 优惠明细
58
+ Discount details
59
59
  <IonIcon icon={chevronForward} aria-hidden />
60
60
  </span>
61
61
  </button>
@@ -55,12 +55,12 @@ export function OmProductCard({
55
55
  <span className="om-product__price-value">{price.toFixed(2)}</span>
56
56
  </span>
57
57
  <span className="om-product__unit">/{unit}</span>
58
- <span className="om-product__stock">库存{stock}</span>
58
+ <span className="om-product__stock">Stock {stock}</span>
59
59
  </div>
60
60
  <button
61
61
  className="om-product__add"
62
62
  type="button"
63
- aria-label={`加购 ${name}`}
63
+ aria-label={`Add ${name}`}
64
64
  onClick={(e) => {
65
65
  e.stopPropagation();
66
66
  onAdd?.();
@@ -22,7 +22,7 @@ interface OmSearchBarProps {
22
22
  */
23
23
  export function OmSearchBar({
24
24
  value,
25
- placeholder = "搜索",
25
+ placeholder = "Search",
26
26
  onChange,
27
27
  onFocus,
28
28
  trailing,
@@ -37,7 +37,7 @@ export function OmSheet({ title, children, onDismiss, dismissHref, size = "auto"
37
37
  {title && (
38
38
  <div className="om-sheet__head">
39
39
  <span className="om-sheet__title">{title}</span>
40
- <button className="om-sheet__close" type="button" onClick={dismiss} aria-label="关闭">
40
+ <button className="om-sheet__close" type="button" onClick={dismiss} aria-label="Close">
41
41
  <IonIcon icon={closeOutline} />
42
42
  </button>
43
43
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omit-design/preset-mobile",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "Mobile design preset for omit-design: Om* whitelist components, --om-* / --ion-* token map, Ionic 8 runtime.",
6
6
  "main": "./index.ts",
@@ -5,9 +5,9 @@
5
5
  // 3. 给 TILES 加合适 ionicons + href
6
6
 
7
7
  export const meta = {
8
- name: "TODO 工作台",
8
+ name: "TODO Dashboard",
9
9
  pattern: "dashboard",
10
- description: "TODO 一句话描述",
10
+ description: "TODO one-line description",
11
11
  source: "prd",
12
12
  } as const;
13
13
 
@@ -41,13 +41,13 @@ interface Tile {
41
41
 
42
42
  // TODO: 替换为真实 mock import
43
43
  const STATS: Stat[] = [
44
- { label: "今日营收", value: "¥0.00", caption: "含已结金额" },
45
- { label: "客单量", value: "0", caption: "单数" },
44
+ { label: "Today's revenue", value: "$0.00", caption: "Includes settled amount" },
45
+ { label: "Order count", value: "0", caption: "orders" },
46
46
  ];
47
47
 
48
48
  const TILES: Tile[] = [
49
49
  { id: "pos", icon: cashOutline, label: "POS", href: "/designs/TODO" },
50
- { id: "orders", icon: receiptOutline, label: "订单", href: "/designs/TODO" },
50
+ { id: "orders", icon: receiptOutline, label: "Orders", href: "/designs/TODO" },
51
51
  ];
52
52
 
53
53
  export function TodoDashboardPage() {
@@ -56,7 +56,7 @@ export function TodoDashboardPage() {
56
56
  padding="lg"
57
57
  header={
58
58
  <OmHeader
59
- title="TODO 工作台"
59
+ title="TODO Dashboard"
60
60
  start={<IonBackButton defaultHref="/designs/TODO-from" />}
61
61
  />
62
62
  }
@@ -6,9 +6,9 @@
6
6
  // 4. 主操作改成业务跳转
7
7
 
8
8
  export const meta = {
9
- name: "TODO 详情页名",
9
+ name: "TODO Detail page",
10
10
  pattern: "detail-view",
11
- description: "TODO 一句话描述",
11
+ description: "TODO one-line description",
12
12
  source: "prd",
13
13
  } as const;
14
14
 
@@ -30,9 +30,9 @@ interface Record {
30
30
  // TODO: 替换为真实 mock import
31
31
  const RECORD: Record = {
32
32
  id: "TODO",
33
- title: "示例标题",
33
+ title: "Sample title",
34
34
  amount: 0,
35
- status: "TODO 状态",
35
+ status: "TODO status",
36
36
  };
37
37
 
38
38
  export function TodoDetailPage() {
@@ -41,19 +41,19 @@ export function TodoDetailPage() {
41
41
  padding="lg"
42
42
  header={
43
43
  <OmHeader
44
- title="TODO 详情"
44
+ title="TODO Detail"
45
45
  start={<IonBackButton defaultHref="/designs/TODO" />}
46
46
  />
47
47
  }
48
48
  >
49
49
  <OmCard title={RECORD.title} subtitle={`#${RECORD.id}`}>
50
- <p>金额:¥{RECORD.amount.toFixed(2)}</p>
51
- <p>状态:{RECORD.status}</p>
50
+ <p>Amount: ${RECORD.amount.toFixed(2)}</p>
51
+ <p>Status: {RECORD.status}</p>
52
52
  </OmCard>
53
53
 
54
54
  {/* TODO: 关联信息分块 —— 增加更多 OmCard */}
55
55
 
56
- <OmButton expand="block">主操作</OmButton>
56
+ <OmButton expand="block">Primary action</OmButton>
57
57
  </OmPage>
58
58
  );
59
59
  }
@@ -6,9 +6,9 @@
6
6
  // 4. iconColor / confirmColor 按场景设(danger / warning / success / primary)
7
7
 
8
8
  export const meta = {
9
- name: "TODO 对话框",
9
+ name: "TODO Dialog",
10
10
  pattern: "dialog-view",
11
- description: "TODO 一句话描述",
11
+ description: "TODO one-line description",
12
12
  source: "prd",
13
13
  } as const;
14
14
 
@@ -21,11 +21,11 @@ export function TodoDialogPage() {
21
21
  <OmDialog
22
22
  icon={informationCircleOutline}
23
23
  iconColor="primary"
24
- title="TODO 标题"
25
- subtitle="TODO 副标题描述。"
26
- cancelText="取消"
24
+ title="TODO Title"
25
+ subtitle="TODO subtitle description."
26
+ cancelText="Cancel"
27
27
  cancelHref="/designs/TODO-from"
28
- confirmText="确认"
28
+ confirmText="Confirm"
29
29
  confirmHref="/designs/TODO-next"
30
30
  />
31
31
  </OmPage>
@@ -6,9 +6,9 @@
6
6
  // 4. IonBackButton defaultHref 改成上一级
7
7
 
8
8
  export const meta = {
9
- name: "TODO 表单页名",
9
+ name: "TODO Form page",
10
10
  pattern: "form-view",
11
- description: "TODO 一句话描述",
11
+ description: "TODO one-line description",
12
12
  source: "prd",
13
13
  } as const;
14
14
 
@@ -32,19 +32,19 @@ export function TodoFormPage() {
32
32
  padding="lg"
33
33
  header={
34
34
  <OmHeader
35
- title="TODO 表单"
35
+ title="TODO Form"
36
36
  start={<IonBackButton defaultHref="/designs/TODO" />}
37
37
  />
38
38
  }
39
39
  >
40
- <OmInput label="字段一" value={field1} onChange={setField1} />
41
- <OmInput label="字段二" value={field2} onChange={setField2} />
40
+ <OmInput label="Field one" value={field1} onChange={setField1} />
41
+ <OmInput label="Field two" value={field2} onChange={setField2} />
42
42
 
43
43
  <OmButton
44
44
  expand="block"
45
45
  onClick={() => navigate("/designs/TODO-next")}
46
46
  >
47
- 提交
47
+ Submit
48
48
  </OmButton>
49
49
  </OmPage>
50
50
  );
@@ -6,9 +6,9 @@
6
6
  // 4. 调整空态文案
7
7
 
8
8
  export const meta = {
9
- name: "TODO 列表页名",
9
+ name: "TODO List page",
10
10
  pattern: "list-view",
11
- description: "TODO 一句话描述",
11
+ description: "TODO one-line description",
12
12
  source: "prd",
13
13
  } as const;
14
14
 
@@ -28,8 +28,8 @@ interface Item {
28
28
 
29
29
  // TODO: 替换为 import { items } from ""./mock/<group>" 相对路径";
30
30
  const ITEMS: Item[] = [
31
- { id: "1", title: "示例条目 1", detail: "副信息" },
32
- { id: "2", title: "示例条目 2" },
31
+ { id: "1", title: "Sample item 1", detail: "Subinfo" },
32
+ { id: "2", title: "Sample item 2" },
33
33
  ];
34
34
 
35
35
  export function TodoListPage() {
@@ -38,13 +38,13 @@ export function TodoListPage() {
38
38
  padding="none"
39
39
  header={
40
40
  <OmHeader
41
- title="TODO 标题"
41
+ title="TODO Title"
42
42
  start={<IonBackButton defaultHref="/designs/TODO" />}
43
43
  />
44
44
  }
45
45
  >
46
46
  {ITEMS.length === 0 ? (
47
- <OmEmptyState title="暂无数据" description="TODO 空态描述" />
47
+ <OmEmptyState title="No data" description="TODO empty-state description" />
48
48
  ) : (
49
49
  <IonList lines="none">
50
50
  {ITEMS.map((it) => (
@@ -5,9 +5,9 @@
5
5
  // 3. dismissHref 改成来源页路径
6
6
 
7
7
  export const meta = {
8
- name: "TODO 操作菜单",
8
+ name: "TODO Action menu",
9
9
  pattern: "sheet-action",
10
- description: "TODO 一句话描述",
10
+ description: "TODO one-line description",
11
11
  source: "prd",
12
12
  } as const;
13
13
 
@@ -24,15 +24,15 @@ interface MenuItem {
24
24
  }
25
25
 
26
26
  const ITEMS: MenuItem[] = [
27
- { label: "TODO 项一", icon: ellipsisHorizontalOutline, href: "/designs/TODO" },
28
- { label: "TODO 项二", icon: ellipsisHorizontalOutline, href: "/designs/TODO" },
27
+ { label: "TODO Item one", icon: ellipsisHorizontalOutline, href: "/designs/TODO" },
28
+ { label: "TODO Item two", icon: ellipsisHorizontalOutline, href: "/designs/TODO" },
29
29
  ];
30
30
 
31
31
  export function TodoSheetActionPage() {
32
32
  const navigate = useNavigate();
33
33
  return (
34
34
  <OmPage padding="none">
35
- <OmSheet title="TODO 标题" dismissHref="/designs/TODO-from">
35
+ <OmSheet title="TODO Title" dismissHref="/designs/TODO-from">
36
36
  <div>
37
37
  {ITEMS.map((it) => (
38
38
  <button
@@ -8,9 +8,9 @@
8
8
  // 本 template 展示扁平结构,首批落地后可重构为 shell。
9
9
 
10
10
  export const meta = {
11
- name: "TODO Tab ",
11
+ name: "TODO Tab page",
12
12
  pattern: "tab-view",
13
- description: "TODO 一句话描述",
13
+ description: "TODO one-line description",
14
14
  source: "prd",
15
15
  } as const;
16
16
 
@@ -28,21 +28,21 @@ import {
28
28
  } from "@omit-design/preset-mobile";
29
29
 
30
30
  const TABS: OmTabItem[] = [
31
- { tab: "stored", href: "/designs/TODO-stored", label: "寄存", icon: cubeOutline },
32
- { tab: "orders", href: "/designs/TODO-orders", label: "订单", icon: receiptOutline },
33
- { tab: "member", href: "/designs/TODO-member", label: "会员", icon: peopleOutline },
34
- { tab: "settings", href: "/designs/TODO-settings", label: "设置", icon: settingsOutline },
31
+ { tab: "stored", href: "/designs/TODO-stored", label: "Stored", icon: cubeOutline },
32
+ { tab: "orders", href: "/designs/TODO-orders", label: "Orders", icon: receiptOutline },
33
+ { tab: "member", href: "/designs/TODO-member", label: "Members", icon: peopleOutline },
34
+ { tab: "settings", href: "/designs/TODO-settings", label: "Settings", icon: settingsOutline },
35
35
  ];
36
36
 
37
37
  export function TodoTabPage() {
38
38
  return (
39
39
  <OmPage
40
40
  padding="lg"
41
- header={<OmAppBar variant="brand" brandTitle="TODO 品牌" />}
41
+ header={<OmAppBar variant="brand" brandTitle="TODO Brand" />}
42
42
  >
43
43
  <div>
44
44
  {/* TODO: 主体内容 —— 表单 / 列表 / 空态 */}
45
- <h1>TODO Tab 页主体</h1>
45
+ <h1>TODO Tab page body</h1>
46
46
  </div>
47
47
  <OmTabBar items={TABS} />
48
48
  </OmPage>
@@ -6,9 +6,9 @@
6
6
  // 4. tagline / version 走 mock 或常量
7
7
 
8
8
  export const meta = {
9
- name: "TODO 欢迎页",
9
+ name: "TODO Welcome page",
10
10
  pattern: "welcome-view",
11
- description: "TODO 一句话描述",
11
+ description: "TODO one-line description",
12
12
  source: "prd",
13
13
  } as const;
14
14
 
@@ -23,14 +23,14 @@ export function TodoWelcomePage() {
23
23
  {/* TODO: 替换为品牌 logo 组件 */}
24
24
  <div>
25
25
  <h1>Welcome</h1>
26
- <p>TODO 欢迎语</p>
26
+ <p>TODO welcome message</p>
27
27
  </div>
28
28
 
29
29
  <OmButton
30
30
  expand="block"
31
31
  onClick={() => navigate("/designs/TODO-next")}
32
32
  >
33
- 开始
33
+ Get started
34
34
  </OmButton>
35
35
  </OmPage>
36
36
  );