@geektech/one 0.0.1 → 0.2.0
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-zh.md +258 -3
- package/README.md +265 -3
- package/dist/alert/OneAlert.d.ts +21 -0
- package/dist/alert/index.d.ts +2 -0
- package/dist/avatar/OneAvatar.d.ts +21 -0
- package/dist/avatar/index.d.ts +2 -0
- package/dist/badge/OneBadge.d.ts +18 -0
- package/dist/badge/index.d.ts +2 -0
- package/dist/breadcrumb/OneBreadcrumb.d.ts +38 -0
- package/dist/breadcrumb/index.d.ts +1 -0
- package/dist/categories.d.ts +9 -5
- package/dist/checkbox/OneCheckboxGroup.d.ts +2 -0
- package/dist/collapse/OneCollapse.d.ts +31 -0
- package/dist/collapse/index.d.ts +2 -0
- package/dist/data-display/index.d.ts +2 -0
- package/dist/data-display/types.d.ts +2 -0
- package/dist/dialog/DialogOverlay.d.ts +30 -0
- package/dist/dialog/OneDialog.d.ts +20 -0
- package/dist/dialog/focus-manager.d.ts +10 -0
- package/dist/dialog/index.d.ts +7 -0
- package/dist/dialog/scroll-lock.d.ts +2 -0
- package/dist/dialog/service.d.ts +22 -0
- package/dist/dialog/types.d.ts +14 -0
- package/dist/empty/OneEmpty.d.ts +12 -0
- package/dist/empty/index.d.ts +2 -0
- package/dist/form/OneForm.d.ts +1 -1
- package/dist/form/OneFormItem.d.ts +1 -1
- package/dist/index.d.ts +49 -2
- package/dist/index.js +5761 -98
- package/dist/index.js.map +59 -15
- package/dist/loading/OneLoading.d.ts +16 -0
- package/dist/loading/index.d.ts +2 -0
- package/dist/message/MessageOverlay.d.ts +25 -0
- package/dist/message/OneMessage.d.ts +19 -0
- package/dist/message/index.d.ts +6 -0
- package/dist/message/normalize.d.ts +8 -0
- package/dist/message/service.d.ts +17 -0
- package/dist/message/timer.d.ts +21 -0
- package/dist/message/types.d.ts +14 -0
- package/dist/navigation/index.d.ts +2 -0
- package/dist/navigation/normalize.d.ts +3 -0
- package/dist/navigation/types.d.ts +4 -0
- package/dist/overlay/container.d.ts +2 -0
- package/dist/overlay/errors.d.ts +9 -0
- package/dist/overlay/host.d.ts +16 -0
- package/dist/overlay/index.d.ts +7 -0
- package/dist/overlay/mount-controller.d.ts +13 -0
- package/dist/overlay/positioner.d.ts +36 -0
- package/dist/overlay/types.d.ts +32 -0
- package/dist/pagination/OnePagination.d.ts +42 -0
- package/dist/pagination/index.d.ts +2 -0
- package/dist/pagination/tokens.d.ts +2 -0
- package/dist/progress/OneProgress.d.ts +15 -0
- package/dist/progress/index.d.ts +2 -0
- package/dist/radio/OneRadio.d.ts +32 -0
- package/dist/radio/OneRadioGroup.d.ts +30 -0
- package/dist/radio/index.d.ts +4 -0
- package/dist/rate/OneRate.d.ts +28 -0
- package/dist/rate/index.d.ts +2 -0
- package/dist/skeleton/OneSkeleton.d.ts +16 -0
- package/dist/skeleton/index.d.ts +2 -0
- package/dist/slider/OneSlider.d.ts +29 -0
- package/dist/slider/index.d.ts +2 -0
- package/dist/styles/shared.d.ts +13 -0
- package/dist/table/OneTable.d.ts +26 -0
- package/dist/table/index.d.ts +2 -0
- package/dist/tabs/OneTabs.d.ts +34 -0
- package/dist/tabs/index.d.ts +2 -0
- package/dist/tag/OneTag.d.ts +21 -0
- package/dist/tag/index.d.ts +2 -0
- package/dist/theme/OneThemeService.d.ts +14 -0
- package/dist/theme/default-theme.d.ts +2 -0
- package/dist/theme/errors.d.ts +9 -0
- package/dist/theme/index.d.ts +4 -0
- package/dist/theme/normalize.d.ts +6 -0
- package/dist/theme/types.d.ts +57 -0
- package/dist/theme/variables.d.ts +6 -0
- package/dist/time-picker/OneTimePicker.d.ts +47 -0
- package/dist/time-picker/index.d.ts +2 -0
- package/dist/tooltip/OneTooltip.d.ts +45 -0
- package/dist/tooltip/TooltipBubble.d.ts +29 -0
- package/dist/tooltip/index.d.ts +4 -0
- package/dist/tooltip/types.d.ts +17 -0
- package/dist/upload/OneUpload.d.ts +36 -0
- package/dist/upload/index.d.ts +2 -0
- package/package.json +3 -2
package/README-zh.md
CHANGED
|
@@ -48,6 +48,168 @@ class App extends Component {
|
|
|
48
48
|
createApp({ root: App }).mount();
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
## 组件分类
|
|
52
|
+
|
|
53
|
+
- 基础:`OneButton`
|
|
54
|
+
- 表单:`OneForm`、`OneFormItem`、`OneInput`、`OneSelect`、`OneTimePicker`、
|
|
55
|
+
`OneCheckbox`、`OneCheckboxGroup`、`OneRadio`、`OneRadioGroup`、`OneSwitch`、
|
|
56
|
+
`OneSlider`、`OneRate`、`OneUpload`
|
|
57
|
+
- 导航:`OneTabs`、`OneBreadcrumb`、`OnePagination`
|
|
58
|
+
- 数据展示:`OneCard`、`OneTag`、`OneBadge`、`OneAvatar`、`OneProgress`、
|
|
59
|
+
`OneEmpty`、`OneTable`、`OneCollapse`、`OneSkeleton`
|
|
60
|
+
- 反馈与浮层:`OneAlert`、`OneMessage`、`OneDialog`、`OneTooltip`、
|
|
61
|
+
`OneLoading`
|
|
62
|
+
|
|
63
|
+
## 导航
|
|
64
|
+
|
|
65
|
+
并列内容使用标签页,层级位置使用面包屑,大量同类记录使用分页。三个组件分别
|
|
66
|
+
提供受控状态;涉及原生链接时也可以通过事件决定是否继续导航。
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import {
|
|
70
|
+
OneBreadcrumb,
|
|
71
|
+
OnePagination,
|
|
72
|
+
OneTabs,
|
|
73
|
+
type OneBreadcrumbClickEvent,
|
|
74
|
+
type OnePaginationChangeEvent,
|
|
75
|
+
type OneTabsChangeEvent,
|
|
76
|
+
} from '@geektech/one';
|
|
77
|
+
|
|
78
|
+
const tabs = new OneTabs({
|
|
79
|
+
value: 'overview',
|
|
80
|
+
items: [
|
|
81
|
+
{ value: 'overview', label: '概览' },
|
|
82
|
+
{ value: 'security', label: '安全' },
|
|
83
|
+
],
|
|
84
|
+
children: [
|
|
85
|
+
{ tag: 'p', slot: 'overview', children: ['概览内容'] },
|
|
86
|
+
{ tag: 'p', slot: 'security', children: ['安全内容'] },
|
|
87
|
+
],
|
|
88
|
+
});
|
|
89
|
+
tabs.on('change', (payload) => {
|
|
90
|
+
const event = payload as OneTabsChangeEvent;
|
|
91
|
+
tabs.setProps({ value: event.value });
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const breadcrumb = new OneBreadcrumb({
|
|
95
|
+
maxItems: 3,
|
|
96
|
+
separator: '/',
|
|
97
|
+
items: [
|
|
98
|
+
{ label: '首页', href: '/' },
|
|
99
|
+
{ label: '项目', href: '/projects' },
|
|
100
|
+
{ label: '详情', current: true },
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
breadcrumb.on('itemClick', (payload) => {
|
|
104
|
+
const event = payload as OneBreadcrumbClickEvent;
|
|
105
|
+
console.log(event.item, event.index);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const basicPagination = new OnePagination({ total: 95 });
|
|
109
|
+
const pagination = new OnePagination({
|
|
110
|
+
total: 95,
|
|
111
|
+
page: 1,
|
|
112
|
+
pageSize: 10,
|
|
113
|
+
pageSizeOptions: [10, 20, 50],
|
|
114
|
+
showQuickJumper: true,
|
|
115
|
+
});
|
|
116
|
+
pagination.on('change', (payload) => {
|
|
117
|
+
const event = payload as OnePaginationChangeEvent;
|
|
118
|
+
pagination.setProps({ page: event.page, pageSize: event.pageSize });
|
|
119
|
+
});
|
|
120
|
+
void basicPagination;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 数据展示
|
|
124
|
+
|
|
125
|
+
标签适合表达紧凑状态,徽标适合展示数量,头像适合表达身份,进度条适合表达完成
|
|
126
|
+
度,无数据时使用空状态,表格适合组织行列数据,折叠面板适合组织分组详情,加载中
|
|
127
|
+
使用骨架占位。`OneEmpty` 支持通过 `actions` 插槽提供下一步操作。
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { OneBadge, OneButton, OneEmpty, OneTag } from '@geektech/one';
|
|
131
|
+
|
|
132
|
+
new OneTag({ variant: 'success', closable: true });
|
|
133
|
+
new OneBadge({ value: 120, max: 99 });
|
|
134
|
+
const actions = [
|
|
135
|
+
{
|
|
136
|
+
component: OneButton,
|
|
137
|
+
slot: 'actions',
|
|
138
|
+
children: ['创建项目'],
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
new OneEmpty({ description: '暂无结果', children: actions });
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { OneAvatar, OneProgress } from '@geektech/one';
|
|
146
|
+
|
|
147
|
+
new OneAvatar({ text: 'M', variant: 'primary' });
|
|
148
|
+
new OneAvatar({ src: '/avatar.png', alt: '头像', shape: 'square' });
|
|
149
|
+
new OneProgress({ percent: 65, showText: true });
|
|
150
|
+
new OneProgress({ percent: 30, variant: 'success' });
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
import { OneTable, OneCollapse, OneSkeleton } from '@geektech/one';
|
|
155
|
+
|
|
156
|
+
new OneTable({
|
|
157
|
+
data: [
|
|
158
|
+
{ name: '林晚', role: '设计' },
|
|
159
|
+
{ name: '苏北', role: '前端' },
|
|
160
|
+
],
|
|
161
|
+
columns: [
|
|
162
|
+
{ key: 'name', title: '姓名' },
|
|
163
|
+
{ key: 'role', title: '角色' },
|
|
164
|
+
],
|
|
165
|
+
});
|
|
166
|
+
new OneCollapse({
|
|
167
|
+
accordion: true,
|
|
168
|
+
defaultActive: ['basic'],
|
|
169
|
+
items: [
|
|
170
|
+
{ value: 'basic', title: '基础用法', children: ['内容'] },
|
|
171
|
+
{ value: 'advanced', title: '高级用法', children: ['更多内容'] },
|
|
172
|
+
],
|
|
173
|
+
});
|
|
174
|
+
new OneSkeleton({ rows: 3, title: true, avatar: true });
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## 反馈与浮层
|
|
178
|
+
|
|
179
|
+
持续显示的页面内反馈使用 `OneAlert`,附着到单个触发元素的简短说明使用
|
|
180
|
+
`OneTooltip`,进行中的加载状态使用 `OneLoading`:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
import { OneAlert, OneButton, OneLoading, OneTooltip } from '@geektech/one';
|
|
184
|
+
|
|
185
|
+
const alert = new OneAlert({
|
|
186
|
+
title: '保存成功',
|
|
187
|
+
variant: 'success',
|
|
188
|
+
closable: true,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const tooltip = new OneTooltip({
|
|
192
|
+
content: '复制链接',
|
|
193
|
+
placement: 'bottom-end',
|
|
194
|
+
children: [{ component: OneButton, children: ['复制'] }],
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const loading = new OneLoading({ size: 'md', label: '加载中' });
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
临时消息和确认流程可以使用命令式服务:
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
import { oneDialog, oneMessage } from '@geektech/one';
|
|
204
|
+
|
|
205
|
+
oneMessage.success('Saved');
|
|
206
|
+
|
|
207
|
+
const confirmed = await oneDialog.confirm({
|
|
208
|
+
title: 'Delete item?',
|
|
209
|
+
description: 'This action cannot be undone.',
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
51
213
|
## 按钮变体、尺寸、加载状态和事件
|
|
52
214
|
|
|
53
215
|
`OneButton` 提供 `primary`、`secondary`、`danger` 三种变体,以及 `sm`、
|
|
@@ -97,6 +259,70 @@ uncontrolled.on('change', (payload) => {
|
|
|
97
259
|
});
|
|
98
260
|
```
|
|
99
261
|
|
|
262
|
+
## 选择与时间
|
|
263
|
+
|
|
264
|
+
单选按钮从多个选项中选一个,时间选择器提供可编辑文本输入,点击展开时/分/秒下拉
|
|
265
|
+
面板。二者都支持受控与非受控模式。
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
import {
|
|
269
|
+
OneRadio,
|
|
270
|
+
OneRadioGroup,
|
|
271
|
+
OneTimePicker,
|
|
272
|
+
type OneFieldValueEvent,
|
|
273
|
+
} from '@geektech/one';
|
|
274
|
+
|
|
275
|
+
const radio = new OneRadio({ value: 'design', defaultChecked: true });
|
|
276
|
+
const group = new OneRadioGroup({
|
|
277
|
+
defaultValue: 'weekly',
|
|
278
|
+
ariaLabel: '通知频率',
|
|
279
|
+
options: [
|
|
280
|
+
{ value: 'daily', label: '每天' },
|
|
281
|
+
{ value: 'weekly', label: '每周' },
|
|
282
|
+
],
|
|
283
|
+
});
|
|
284
|
+
group.on('change', (payload) => {
|
|
285
|
+
const event = payload as OneFieldValueEvent<string>;
|
|
286
|
+
console.log(event.value);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
new OneTimePicker({ defaultValue: '09:30', ariaLabel: '开始时间' });
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## 滑块、评分与上传
|
|
293
|
+
|
|
294
|
+
滑块在范围内选择一个数值,评分用星星表达打分,上传用于收集本地文件元数据。
|
|
295
|
+
三者都支持受控与非受控模式。
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
import {
|
|
299
|
+
OneSlider,
|
|
300
|
+
OneRate,
|
|
301
|
+
OneUpload,
|
|
302
|
+
type OneSliderValueEvent,
|
|
303
|
+
type OneRateValueEvent,
|
|
304
|
+
type OneUploadChangeEvent,
|
|
305
|
+
} from '@geektech/one';
|
|
306
|
+
|
|
307
|
+
const slider = new OneSlider({ defaultValue: 60, showValue: true });
|
|
308
|
+
slider.on('change', (payload) => {
|
|
309
|
+
const event = payload as OneSliderValueEvent;
|
|
310
|
+
console.log(event.value);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
const rating = new OneRate({ defaultValue: 4, allowClear: true });
|
|
314
|
+
rating.on('change', (payload) => {
|
|
315
|
+
const event = payload as OneRateValueEvent;
|
|
316
|
+
console.log(event.value);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
const upload = new OneUpload({ multiple: true, ariaLabel: '附件' });
|
|
320
|
+
upload.on('change', (payload) => {
|
|
321
|
+
const event = payload as OneUploadChangeEvent;
|
|
322
|
+
console.log(event.files.map((file) => file.name));
|
|
323
|
+
});
|
|
324
|
+
```
|
|
325
|
+
|
|
100
326
|
## 卡片插槽
|
|
101
327
|
|
|
102
328
|
带有 `slot: 'header'` 或 `slot: 'footer'` 的子节点进入对应命名插槽,未指定
|
|
@@ -104,16 +330,45 @@ slot 的子节点进入默认内容区。
|
|
|
104
330
|
|
|
105
331
|
```ts
|
|
106
332
|
import { createComponent } from '@geektech/tsone';
|
|
107
|
-
import { OneCard } from '@geektech/one';
|
|
333
|
+
import { OneButton, OneCard } from '@geektech/one';
|
|
108
334
|
|
|
109
335
|
const card = createComponent(OneCard, {}, [
|
|
110
336
|
{ tag: 'h2', slot: 'header', children: ['账户'] },
|
|
111
337
|
{ tag: 'p', children: ['默认插槽内容'] },
|
|
112
|
-
{
|
|
338
|
+
{ component: OneButton, slot: 'footer', children: ['继续'] },
|
|
113
339
|
]);
|
|
114
340
|
```
|
|
115
341
|
|
|
116
|
-
##
|
|
342
|
+
## 全局主题
|
|
343
|
+
|
|
344
|
+
不可变的内置 `default` 主题始终可用。可以注册任意多套局部配置;未填写的颜色、
|
|
345
|
+
字体、行高、边框和圆角字段都会从 `ONE_DEFAULT_THEME` 继承。
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
import { ONE_DEFAULT_THEME, oneTheme } from '@geektech/one';
|
|
349
|
+
|
|
350
|
+
oneTheme.init({
|
|
351
|
+
defaultTheme: 'brand',
|
|
352
|
+
themes: {
|
|
353
|
+
brand: {
|
|
354
|
+
colors: { primary: '#326bff' },
|
|
355
|
+
typography: { fontFamily: 'Inter, sans-serif', lineHeight: '1.6' },
|
|
356
|
+
border: { color: '#cbd5e1', width: '1px', style: 'solid' },
|
|
357
|
+
radius: { sm: '4px', md: '8px', lg: '12px' },
|
|
358
|
+
},
|
|
359
|
+
night: { colors: { surface: '#101510', text: '#f4f8f4' } },
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
oneTheme.switch('default');
|
|
364
|
+
console.log(oneTheme.currentTheme, ONE_DEFAULT_THEME.colors.primary);
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
主题服务只写入 `document.documentElement`,不创建局部主题,也不会自动持久化选中
|
|
368
|
+
名称或跟随系统配色。无效配置会抛出 `OneThemeConfigError`,未知主题名称会抛出
|
|
369
|
+
`OneThemeNotFoundError`。
|
|
370
|
+
|
|
371
|
+
## CSS 变量覆盖
|
|
117
372
|
|
|
118
373
|
One UI 样式限定在 `.one-*` 选择器中。可以在应用容器或 `:root` 上覆盖公开
|
|
119
374
|
CSS 变量:
|
package/README.md
CHANGED
|
@@ -48,6 +48,171 @@ class App extends Component {
|
|
|
48
48
|
createApp({ root: App }).mount();
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
## Component categories
|
|
52
|
+
|
|
53
|
+
- Basic: `OneButton`
|
|
54
|
+
- Form: `OneForm`, `OneFormItem`, `OneInput`, `OneSelect`, `OneTimePicker`,
|
|
55
|
+
`OneCheckbox`, `OneCheckboxGroup`, `OneRadio`, `OneRadioGroup`, `OneSwitch`,
|
|
56
|
+
`OneSlider`, `OneRate`, `OneUpload`
|
|
57
|
+
- Navigation: `OneTabs`, `OneBreadcrumb`, `OnePagination`
|
|
58
|
+
- Data display: `OneCard`, `OneTag`, `OneBadge`, `OneAvatar`, `OneProgress`,
|
|
59
|
+
`OneEmpty`, `OneTable`, `OneCollapse`, `OneSkeleton`
|
|
60
|
+
- Feedback and overlays: `OneAlert`, `OneMessage`, `OneDialog`, `OneTooltip`,
|
|
61
|
+
`OneLoading`
|
|
62
|
+
|
|
63
|
+
## Navigation
|
|
64
|
+
|
|
65
|
+
Use tabs for parallel views, breadcrumbs for a hierarchy, and pagination for a
|
|
66
|
+
long collection. All three components support controlled state or cancellable
|
|
67
|
+
events where native navigation is involved.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import {
|
|
71
|
+
OneBreadcrumb,
|
|
72
|
+
OnePagination,
|
|
73
|
+
OneTabs,
|
|
74
|
+
type OneBreadcrumbClickEvent,
|
|
75
|
+
type OnePaginationChangeEvent,
|
|
76
|
+
type OneTabsChangeEvent,
|
|
77
|
+
} from '@geektech/one';
|
|
78
|
+
|
|
79
|
+
const tabs = new OneTabs({
|
|
80
|
+
value: 'overview',
|
|
81
|
+
items: [
|
|
82
|
+
{ value: 'overview', label: 'Overview' },
|
|
83
|
+
{ value: 'security', label: 'Security' },
|
|
84
|
+
],
|
|
85
|
+
children: [
|
|
86
|
+
{ tag: 'p', slot: 'overview', children: ['Overview content'] },
|
|
87
|
+
{ tag: 'p', slot: 'security', children: ['Security content'] },
|
|
88
|
+
],
|
|
89
|
+
});
|
|
90
|
+
tabs.on('change', (payload) => {
|
|
91
|
+
const event = payload as OneTabsChangeEvent;
|
|
92
|
+
tabs.setProps({ value: event.value });
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const breadcrumb = new OneBreadcrumb({
|
|
96
|
+
maxItems: 3,
|
|
97
|
+
separator: '/',
|
|
98
|
+
items: [
|
|
99
|
+
{ label: 'Home', href: '/' },
|
|
100
|
+
{ label: 'Projects', href: '/projects' },
|
|
101
|
+
{ label: 'Details', current: true },
|
|
102
|
+
],
|
|
103
|
+
});
|
|
104
|
+
breadcrumb.on('itemClick', (payload) => {
|
|
105
|
+
const event = payload as OneBreadcrumbClickEvent;
|
|
106
|
+
console.log(event.item, event.index);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const basicPagination = new OnePagination({ total: 95 });
|
|
110
|
+
const pagination = new OnePagination({
|
|
111
|
+
total: 95,
|
|
112
|
+
page: 1,
|
|
113
|
+
pageSize: 10,
|
|
114
|
+
pageSizeOptions: [10, 20, 50],
|
|
115
|
+
showQuickJumper: true,
|
|
116
|
+
});
|
|
117
|
+
pagination.on('change', (payload) => {
|
|
118
|
+
const event = payload as OnePaginationChangeEvent;
|
|
119
|
+
pagination.setProps({ page: event.page, pageSize: event.pageSize });
|
|
120
|
+
});
|
|
121
|
+
void basicPagination;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Data display
|
|
125
|
+
|
|
126
|
+
Use tags for compact status, badges for counts, avatars for identity, progress
|
|
127
|
+
bars for completion, empty states when a view has no content, tables for row
|
|
128
|
+
data, collapsible panels for grouped detail, and skeletons while content loads.
|
|
129
|
+
`OneEmpty` accepts an `actions` slot for the next useful action.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import { OneBadge, OneButton, OneEmpty, OneTag } from '@geektech/one';
|
|
133
|
+
|
|
134
|
+
new OneTag({ variant: 'success', closable: true });
|
|
135
|
+
new OneBadge({ value: 120, max: 99 });
|
|
136
|
+
const actions = [
|
|
137
|
+
{
|
|
138
|
+
component: OneButton,
|
|
139
|
+
slot: 'actions',
|
|
140
|
+
children: ['Create project'],
|
|
141
|
+
},
|
|
142
|
+
];
|
|
143
|
+
new OneEmpty({ description: 'No results', children: actions });
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { OneAvatar, OneProgress } from '@geektech/one';
|
|
148
|
+
|
|
149
|
+
new OneAvatar({ text: 'M', variant: 'primary' });
|
|
150
|
+
new OneAvatar({ src: '/avatar.png', alt: 'Avatar', shape: 'square' });
|
|
151
|
+
new OneProgress({ percent: 65, showText: true });
|
|
152
|
+
new OneProgress({ percent: 30, variant: 'success' });
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { OneTable, OneCollapse, OneSkeleton } from '@geektech/one';
|
|
157
|
+
|
|
158
|
+
new OneTable({
|
|
159
|
+
data: [
|
|
160
|
+
{ name: 'Eve Lin', role: 'Design' },
|
|
161
|
+
{ name: 'Ben Su', role: 'Frontend' },
|
|
162
|
+
],
|
|
163
|
+
columns: [
|
|
164
|
+
{ key: 'name', title: 'Name' },
|
|
165
|
+
{ key: 'role', title: 'Role' },
|
|
166
|
+
],
|
|
167
|
+
});
|
|
168
|
+
new OneCollapse({
|
|
169
|
+
accordion: true,
|
|
170
|
+
defaultActive: ['basic'],
|
|
171
|
+
items: [
|
|
172
|
+
{ value: 'basic', title: 'Basic usage', children: ['Content'] },
|
|
173
|
+
{ value: 'advanced', title: 'Advanced usage', children: ['More content'] },
|
|
174
|
+
],
|
|
175
|
+
});
|
|
176
|
+
new OneSkeleton({ rows: 3, title: true, avatar: true });
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Feedback and overlays
|
|
180
|
+
|
|
181
|
+
Use `OneAlert` for persistent inline feedback, `OneTooltip` for a short
|
|
182
|
+
description attached to one trigger element, and `OneLoading` for an
|
|
183
|
+
in-progress indicator:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
import { OneAlert, OneButton, OneLoading, OneTooltip } from '@geektech/one';
|
|
187
|
+
|
|
188
|
+
const alert = new OneAlert({
|
|
189
|
+
title: 'Saved',
|
|
190
|
+
variant: 'success',
|
|
191
|
+
closable: true,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const tooltip = new OneTooltip({
|
|
195
|
+
content: 'Copy link',
|
|
196
|
+
placement: 'bottom-end',
|
|
197
|
+
children: [{ component: OneButton, children: ['Copy'] }],
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
const loading = new OneLoading({ size: 'md', label: 'Loading' });
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Use the imperative services for transient messages and confirmation flows:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { oneDialog, oneMessage } from '@geektech/one';
|
|
207
|
+
|
|
208
|
+
oneMessage.success('Saved');
|
|
209
|
+
|
|
210
|
+
const confirmed = await oneDialog.confirm({
|
|
211
|
+
title: 'Delete item?',
|
|
212
|
+
description: 'This action cannot be undone.',
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
51
216
|
## Button variants, sizes, loading and events
|
|
52
217
|
|
|
53
218
|
`OneButton` supports `primary`, `secondary`, and `danger` variants and `sm`,
|
|
@@ -97,6 +262,72 @@ uncontrolled.on('change', (payload) => {
|
|
|
97
262
|
});
|
|
98
263
|
```
|
|
99
264
|
|
|
265
|
+
## Selection and time
|
|
266
|
+
|
|
267
|
+
Radio buttons pick one option out of several. Time pickers offer an editable
|
|
268
|
+
text input plus a click-to-open hour/minute/second dropdown. Both support
|
|
269
|
+
controlled and uncontrolled modes.
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
import {
|
|
273
|
+
OneRadio,
|
|
274
|
+
OneRadioGroup,
|
|
275
|
+
OneTimePicker,
|
|
276
|
+
type OneFieldValueEvent,
|
|
277
|
+
} from '@geektech/one';
|
|
278
|
+
|
|
279
|
+
const radio = new OneRadio({ value: 'design', defaultChecked: true });
|
|
280
|
+
const group = new OneRadioGroup({
|
|
281
|
+
defaultValue: 'weekly',
|
|
282
|
+
ariaLabel: 'Frequency',
|
|
283
|
+
options: [
|
|
284
|
+
{ value: 'daily', label: 'Daily' },
|
|
285
|
+
{ value: 'weekly', label: 'Weekly' },
|
|
286
|
+
],
|
|
287
|
+
});
|
|
288
|
+
group.on('change', (payload) => {
|
|
289
|
+
const event = payload as OneFieldValueEvent<string>;
|
|
290
|
+
console.log(event.value);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
new OneTimePicker({ defaultValue: '09:30', ariaLabel: 'Start time' });
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Sliders, ratings and uploads
|
|
297
|
+
|
|
298
|
+
Sliders pick a number within a range, ratings express a star score, and uploads
|
|
299
|
+
collect local file metadata. All three support controlled and uncontrolled
|
|
300
|
+
modes.
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
import {
|
|
304
|
+
OneSlider,
|
|
305
|
+
OneRate,
|
|
306
|
+
OneUpload,
|
|
307
|
+
type OneSliderValueEvent,
|
|
308
|
+
type OneRateValueEvent,
|
|
309
|
+
type OneUploadChangeEvent,
|
|
310
|
+
} from '@geektech/one';
|
|
311
|
+
|
|
312
|
+
const slider = new OneSlider({ defaultValue: 60, showValue: true });
|
|
313
|
+
slider.on('change', (payload) => {
|
|
314
|
+
const event = payload as OneSliderValueEvent;
|
|
315
|
+
console.log(event.value);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
const rating = new OneRate({ defaultValue: 4, allowClear: true });
|
|
319
|
+
rating.on('change', (payload) => {
|
|
320
|
+
const event = payload as OneRateValueEvent;
|
|
321
|
+
console.log(event.value);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
const upload = new OneUpload({ multiple: true, ariaLabel: 'Attachments' });
|
|
325
|
+
upload.on('change', (payload) => {
|
|
326
|
+
const event = payload as OneUploadChangeEvent;
|
|
327
|
+
console.log(event.files.map((file) => file.name));
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
100
331
|
## Card slots
|
|
101
332
|
|
|
102
333
|
Children with `slot: 'header'` or `slot: 'footer'` fill the named regions;
|
|
@@ -104,16 +335,47 @@ children without a slot fill the default body.
|
|
|
104
335
|
|
|
105
336
|
```ts
|
|
106
337
|
import { createComponent } from '@geektech/tsone';
|
|
107
|
-
import { OneCard } from '@geektech/one';
|
|
338
|
+
import { OneButton, OneCard } from '@geektech/one';
|
|
108
339
|
|
|
109
340
|
const card = createComponent(OneCard, {}, [
|
|
110
341
|
{ tag: 'h2', slot: 'header', children: ['Account'] },
|
|
111
342
|
{ tag: 'p', children: ['Default slot content'] },
|
|
112
|
-
{
|
|
343
|
+
{ component: OneButton, slot: 'footer', children: ['Continue'] },
|
|
113
344
|
]);
|
|
114
345
|
```
|
|
115
346
|
|
|
116
|
-
##
|
|
347
|
+
## Global themes
|
|
348
|
+
|
|
349
|
+
The immutable `default` theme is always available. Register any number of
|
|
350
|
+
partial themes; omitted colors, typography, border, and radius values inherit
|
|
351
|
+
from `ONE_DEFAULT_THEME`.
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
import { ONE_DEFAULT_THEME, oneTheme } from '@geektech/one';
|
|
355
|
+
|
|
356
|
+
oneTheme.init({
|
|
357
|
+
defaultTheme: 'brand',
|
|
358
|
+
themes: {
|
|
359
|
+
brand: {
|
|
360
|
+
colors: { primary: '#326bff' },
|
|
361
|
+
typography: { fontFamily: 'Inter, sans-serif', lineHeight: '1.6' },
|
|
362
|
+
border: { color: '#cbd5e1', width: '1px', style: 'solid' },
|
|
363
|
+
radius: { sm: '4px', md: '8px', lg: '12px' },
|
|
364
|
+
},
|
|
365
|
+
night: { colors: { surface: '#101510', text: '#f4f8f4' } },
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
oneTheme.switch('default');
|
|
370
|
+
console.log(oneTheme.currentTheme, ONE_DEFAULT_THEME.colors.primary);
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
The service writes to `document.documentElement` only. It does not create local
|
|
374
|
+
themes, persist the selected name, or follow the operating-system scheme.
|
|
375
|
+
Invalid configuration throws `OneThemeConfigError`; unknown theme names throw
|
|
376
|
+
`OneThemeNotFoundError`.
|
|
377
|
+
|
|
378
|
+
## CSS variable overrides
|
|
117
379
|
|
|
118
380
|
One UI styles are scoped to `.one-*` selectors. Override public CSS variables
|
|
119
381
|
on an application container or `:root`:
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Component, type VNode } from '@geektech/tsone';
|
|
2
|
+
import type { OneFeedbackVariant } from '../overlay';
|
|
3
|
+
import { type OneNamedStyle } from '../styles/shared';
|
|
4
|
+
export interface OneAlertProps {
|
|
5
|
+
title?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
variant?: OneFeedbackVariant;
|
|
8
|
+
closable?: boolean;
|
|
9
|
+
children?: Array<VNode | string>;
|
|
10
|
+
}
|
|
11
|
+
interface OneAlertState {
|
|
12
|
+
visible: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare const ONE_ALERT_STYLES: OneNamedStyle[];
|
|
15
|
+
export declare class OneAlert extends Component<OneAlertProps, OneAlertState> {
|
|
16
|
+
protected initState(): OneAlertState;
|
|
17
|
+
protected initStyles(): void;
|
|
18
|
+
protected render(): VNode;
|
|
19
|
+
private close;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Component, type VNode } from '@geektech/tsone';
|
|
2
|
+
import { type OneDataDisplayVariant } from '../data-display';
|
|
3
|
+
import { type OneNamedStyle } from '../styles/shared';
|
|
4
|
+
import type { OneComponentSize } from '../types';
|
|
5
|
+
export type OneAvatarShape = 'circle' | 'square';
|
|
6
|
+
export interface OneAvatarProps {
|
|
7
|
+
src?: string;
|
|
8
|
+
alt?: string;
|
|
9
|
+
text?: string;
|
|
10
|
+
size?: OneComponentSize;
|
|
11
|
+
shape?: OneAvatarShape;
|
|
12
|
+
variant?: OneDataDisplayVariant;
|
|
13
|
+
ariaLabel?: string;
|
|
14
|
+
children?: Array<VNode | string>;
|
|
15
|
+
}
|
|
16
|
+
export declare const ONE_AVATAR_STYLES: OneNamedStyle[];
|
|
17
|
+
export declare class OneAvatar extends Component<OneAvatarProps> {
|
|
18
|
+
protected initState(): object;
|
|
19
|
+
protected initStyles(): void;
|
|
20
|
+
protected render(): VNode;
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Component, type VNode } from '@geektech/tsone';
|
|
2
|
+
import { type OneDataDisplayVariant } from '../data-display';
|
|
3
|
+
import { type OneNamedStyle } from '../styles/shared';
|
|
4
|
+
export interface OneBadgeProps {
|
|
5
|
+
value?: number | string;
|
|
6
|
+
max?: number;
|
|
7
|
+
dot?: boolean;
|
|
8
|
+
showZero?: boolean;
|
|
9
|
+
variant?: OneDataDisplayVariant;
|
|
10
|
+
ariaLabel?: string;
|
|
11
|
+
children?: Array<VNode | string>;
|
|
12
|
+
}
|
|
13
|
+
export declare const ONE_BADGE_STYLES: OneNamedStyle[];
|
|
14
|
+
export declare class OneBadge extends Component<OneBadgeProps> {
|
|
15
|
+
protected initState(): object;
|
|
16
|
+
protected initStyles(): void;
|
|
17
|
+
protected render(): VNode;
|
|
18
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Component, type VNode } from '@geektech/tsone';
|
|
2
|
+
import { type OneNamedStyle } from '../styles/shared';
|
|
3
|
+
export interface OneBreadcrumbItem {
|
|
4
|
+
label: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
current?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface OneBreadcrumbClickEvent {
|
|
9
|
+
item: OneBreadcrumbItem;
|
|
10
|
+
index: number;
|
|
11
|
+
originalEvent: MouseEvent;
|
|
12
|
+
}
|
|
13
|
+
export interface OneBreadcrumbProps {
|
|
14
|
+
items: readonly OneBreadcrumbItem[];
|
|
15
|
+
separator?: string;
|
|
16
|
+
maxItems?: number;
|
|
17
|
+
ariaLabel?: string;
|
|
18
|
+
children?: Array<VNode | string>;
|
|
19
|
+
}
|
|
20
|
+
interface OneBreadcrumbState {
|
|
21
|
+
expanded: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare const ONE_BREADCRUMB_STYLES: OneNamedStyle[];
|
|
24
|
+
export declare class OneBreadcrumb extends Component<OneBreadcrumbProps, OneBreadcrumbState> {
|
|
25
|
+
protected initState(): OneBreadcrumbState;
|
|
26
|
+
protected initStyles(): void;
|
|
27
|
+
protected render(): VNode;
|
|
28
|
+
private normalizedItems;
|
|
29
|
+
private currentIndex;
|
|
30
|
+
private tokens;
|
|
31
|
+
private renderToken;
|
|
32
|
+
private renderItem;
|
|
33
|
+
private renderCollapse;
|
|
34
|
+
private renderSeparator;
|
|
35
|
+
private handleItemClick;
|
|
36
|
+
private hasSlot;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ONE_BREADCRUMB_STYLES, OneBreadcrumb, type OneBreadcrumbClickEvent, type OneBreadcrumbItem, type OneBreadcrumbProps, } from './OneBreadcrumb';
|