@geektech/one 0.1.0 → 0.3.1

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 CHANGED
@@ -50,12 +50,15 @@ createApp({ root: App }).mount();
50
50
 
51
51
  ## 组件分类
52
52
 
53
- - 基础:`OneButton`、`OneInput`
54
- - 表单:`OneForm`、`OneFormItem`、`OneSelect`、`OneCheckbox`、
55
- `OneCheckboxGroup`、`OneSwitch`
53
+ - 基础:`OneButton`
54
+ - 表单:`OneForm`、`OneFormItem`、`OneInput`、`OneSelect`、`OneTimePicker`、
55
+ `OneCheckbox`、`OneCheckboxGroup`、`OneRadio`、`OneRadioGroup`、`OneSwitch`、
56
+ `OneSlider`、`OneRate`、`OneUpload`
56
57
  - 导航:`OneTabs`、`OneBreadcrumb`、`OnePagination`
57
- - 数据展示:`OneCard`、`OneTag`、`OneBadge`、`OneEmpty`
58
- - 反馈与浮层:`OneAlert`、`OneMessage`、`OneDialog`、`OneTooltip`
58
+ - 数据展示:`OneCard`、`OneTag`、`OneBadge`、`OneAvatar`、`OneProgress`、
59
+ `OneEmpty`、`OneTable`、`OneCollapse`、`OneSkeleton`
60
+ - 反馈与浮层:`OneAlert`、`OneMessage`、`OneDialog`、`OneTooltip`、
61
+ `OneLoading`
59
62
 
60
63
  ## 导航
61
64
 
@@ -119,8 +122,9 @@ void basicPagination;
119
122
 
120
123
  ## 数据展示
121
124
 
122
- 标签适合表达紧凑状态,徽标适合展示数量,无数据时使用空状态。`OneEmpty`
123
- 支持通过 `actions` 插槽提供下一步操作。
125
+ 标签适合表达紧凑状态,徽标适合展示数量,头像适合表达身份,进度条适合表达完成
126
+ 度,无数据时使用空状态,表格适合组织行列数据,折叠面板适合组织分组详情,加载中
127
+ 使用骨架占位。`OneEmpty` 支持通过 `actions` 插槽提供下一步操作。
124
128
 
125
129
  ```ts
126
130
  import { OneBadge, OneButton, OneEmpty, OneTag } from '@geektech/one';
@@ -137,13 +141,46 @@ const actions = [
137
141
  new OneEmpty({ description: '暂无结果', children: actions });
138
142
  ```
139
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
+
140
177
  ## 反馈与浮层
141
178
 
142
179
  持续显示的页面内反馈使用 `OneAlert`,附着到单个触发元素的简短说明使用
143
- `OneTooltip`:
180
+ `OneTooltip`,进行中的加载状态使用 `OneLoading`:
144
181
 
145
182
  ```ts
146
- import { OneAlert, OneButton, OneTooltip } from '@geektech/one';
183
+ import { OneAlert, OneButton, OneLoading, OneTooltip } from '@geektech/one';
147
184
 
148
185
  const alert = new OneAlert({
149
186
  title: '保存成功',
@@ -156,6 +193,8 @@ const tooltip = new OneTooltip({
156
193
  placement: 'bottom-end',
157
194
  children: [{ component: OneButton, children: ['复制'] }],
158
195
  });
196
+
197
+ const loading = new OneLoading({ size: 'md', label: '加载中' });
159
198
  ```
160
199
 
161
200
  临时消息和确认流程可以使用命令式服务:
@@ -220,6 +259,70 @@ uncontrolled.on('change', (payload) => {
220
259
  });
221
260
  ```
222
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
+
223
326
  ## 卡片插槽
224
327
 
225
328
  带有 `slot: 'header'` 或 `slot: 'footer'` 的子节点进入对应命名插槽,未指定
package/README.md CHANGED
@@ -50,12 +50,15 @@ createApp({ root: App }).mount();
50
50
 
51
51
  ## Component categories
52
52
 
53
- - Basic: `OneButton`, `OneInput`
54
- - Form: `OneForm`, `OneFormItem`, `OneSelect`, `OneCheckbox`,
55
- `OneCheckboxGroup`, `OneSwitch`
53
+ - Basic: `OneButton`
54
+ - Form: `OneForm`, `OneFormItem`, `OneInput`, `OneSelect`, `OneTimePicker`,
55
+ `OneCheckbox`, `OneCheckboxGroup`, `OneRadio`, `OneRadioGroup`, `OneSwitch`,
56
+ `OneSlider`, `OneRate`, `OneUpload`
56
57
  - Navigation: `OneTabs`, `OneBreadcrumb`, `OnePagination`
57
- - Data display: `OneCard`, `OneTag`, `OneBadge`, `OneEmpty`
58
- - Feedback and overlays: `OneAlert`, `OneMessage`, `OneDialog`, `OneTooltip`
58
+ - Data display: `OneCard`, `OneTag`, `OneBadge`, `OneAvatar`, `OneProgress`,
59
+ `OneEmpty`, `OneTable`, `OneCollapse`, `OneSkeleton`
60
+ - Feedback and overlays: `OneAlert`, `OneMessage`, `OneDialog`, `OneTooltip`,
61
+ `OneLoading`
59
62
 
60
63
  ## Navigation
61
64
 
@@ -120,8 +123,10 @@ void basicPagination;
120
123
 
121
124
  ## Data display
122
125
 
123
- Use tags for compact status, badges for counts, and empty states when a view has
124
- no content. `OneEmpty` accepts an `actions` slot for the next useful action.
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.
125
130
 
126
131
  ```ts
127
132
  import { OneBadge, OneButton, OneEmpty, OneTag } from '@geektech/one';
@@ -138,13 +143,47 @@ const actions = [
138
143
  new OneEmpty({ description: 'No results', children: actions });
139
144
  ```
140
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
+
141
179
  ## Feedback and overlays
142
180
 
143
- Use `OneAlert` for persistent inline feedback and `OneTooltip` for a short
144
- description attached to one trigger element:
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:
145
184
 
146
185
  ```ts
147
- import { OneAlert, OneButton, OneTooltip } from '@geektech/one';
186
+ import { OneAlert, OneButton, OneLoading, OneTooltip } from '@geektech/one';
148
187
 
149
188
  const alert = new OneAlert({
150
189
  title: 'Saved',
@@ -157,6 +196,8 @@ const tooltip = new OneTooltip({
157
196
  placement: 'bottom-end',
158
197
  children: [{ component: OneButton, children: ['Copy'] }],
159
198
  });
199
+
200
+ const loading = new OneLoading({ size: 'md', label: 'Loading' });
160
201
  ```
161
202
 
162
203
  Use the imperative services for transient messages and confirmation flows:
@@ -221,6 +262,72 @@ uncontrolled.on('change', (payload) => {
221
262
  });
222
263
  ```
223
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
+
224
331
  ## Card slots
225
332
 
226
333
  Children with `slot: 'header'` or `slot: 'footer'` fill the named regions;
@@ -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,2 @@
1
+ export { OneAvatar } from './OneAvatar';
2
+ export type { OneAvatarProps, OneAvatarShape } from './OneAvatar';
@@ -2,11 +2,11 @@ export type OneComponentCategory = 'basic' | 'form' | 'navigation' | 'data-displ
2
2
  export declare const ONE_COMPONENT_CATEGORIES: readonly [{
3
3
  readonly id: "basic";
4
4
  readonly label: "基础";
5
- readonly components: readonly ["OneButton", "OneInput"];
5
+ readonly components: readonly ["OneButton"];
6
6
  }, {
7
7
  readonly id: "form";
8
8
  readonly label: "表单";
9
- readonly components: readonly ["OneForm", "OneFormItem", "OneSelect", "OneCheckbox", "OneCheckboxGroup", "OneSwitch"];
9
+ readonly components: readonly ["OneForm", "OneFormItem", "OneInput", "OneSelect", "OneTimePicker", "OneCheckbox", "OneCheckboxGroup", "OneRadio", "OneRadioGroup", "OneSwitch", "OneSlider", "OneRate", "OneUpload"];
10
10
  }, {
11
11
  readonly id: "navigation";
12
12
  readonly label: "导航";
@@ -14,9 +14,9 @@ export declare const ONE_COMPONENT_CATEGORIES: readonly [{
14
14
  }, {
15
15
  readonly id: "data-display";
16
16
  readonly label: "数据展示";
17
- readonly components: readonly ["OneCard", "OneTag", "OneBadge", "OneEmpty"];
17
+ readonly components: readonly ["OneCard", "OneAvatar", "OneTag", "OneBadge", "OneProgress", "OneEmpty", "OneTable", "OneCollapse", "OneSkeleton"];
18
18
  }, {
19
19
  readonly id: "feedback";
20
20
  readonly label: "反馈与浮层";
21
- readonly components: readonly ["OneAlert", "OneMessage", "OneDialog", "OneTooltip"];
21
+ readonly components: readonly ["OneAlert", "OneMessage", "OneDialog", "OneTooltip", "OneLoading"];
22
22
  }];
@@ -0,0 +1,31 @@
1
+ import { Component, type VNode } from '@geektech/tsone';
2
+ import { type OneNamedStyle } from '../styles/shared';
3
+ export interface OneCollapseItem {
4
+ value: string;
5
+ title: string;
6
+ children?: Array<VNode | string>;
7
+ disabled?: boolean;
8
+ }
9
+ export interface OneCollapseChangeEvent {
10
+ value: string[];
11
+ originalEvent: Event;
12
+ }
13
+ export interface OneCollapseProps {
14
+ items?: readonly OneCollapseItem[];
15
+ defaultActive?: readonly string[];
16
+ active?: readonly string[];
17
+ accordion?: boolean;
18
+ ariaLabel?: string;
19
+ }
20
+ interface OneCollapseState {
21
+ internalActive: string[];
22
+ }
23
+ export declare const ONE_COLLAPSE_STYLES: OneNamedStyle[];
24
+ export declare class OneCollapse extends Component<OneCollapseProps, OneCollapseState> {
25
+ protected initState(): OneCollapseState;
26
+ protected initStyles(): void;
27
+ protected render(): VNode;
28
+ private getActive;
29
+ private toggle;
30
+ }
31
+ export {};
@@ -0,0 +1,2 @@
1
+ export { OneCollapse } from './OneCollapse';
2
+ export type { OneCollapseChangeEvent, OneCollapseItem, OneCollapseProps, } from './OneCollapse';
package/dist/index.d.ts CHANGED
@@ -10,8 +10,18 @@ export type { OneCheckboxGroupProps, OneCheckboxProps } from './checkbox';
10
10
  export { OneCheckboxGroup } from './checkbox';
11
11
  export { OneSwitch } from './switch';
12
12
  export type { OneSwitchProps } from './switch';
13
+ export { OneRadio, OneRadioGroup } from './radio';
14
+ export type { OneRadioGroupProps, OneRadioProps } from './radio';
13
15
  export { OneSelect } from './select';
14
16
  export type { OneSelectOption, OneSelectOptionGroup, OneSelectProps, } from './select';
17
+ export { OneTimePicker } from './time-picker';
18
+ export type { OneTimePickerProps, OneTimePickerValueEvent, } from './time-picker';
19
+ export { OneSlider } from './slider';
20
+ export type { OneSliderProps, OneSliderValueEvent } from './slider';
21
+ export { OneRate } from './rate';
22
+ export type { OneRateProps, OneRateValueEvent } from './rate';
23
+ export { OneUpload, formatOneFileSize } from './upload';
24
+ export type { OneUploadChangeEvent, OneUploadFile, OneUploadProps, } from './upload';
15
25
  export { OneTabs } from './tabs';
16
26
  export type { OneTabItem, OneTabsChangeEvent, OneTabsProps } from './tabs';
17
27
  export { OneBreadcrumb } from './breadcrumb';
@@ -29,6 +39,16 @@ export { OneBadge } from './badge';
29
39
  export type { OneBadgeProps } from './badge';
30
40
  export { OneEmpty } from './empty';
31
41
  export type { OneEmptyProps } from './empty';
42
+ export { OneAvatar } from './avatar';
43
+ export type { OneAvatarProps, OneAvatarShape } from './avatar';
44
+ export { OneProgress } from './progress';
45
+ export type { OneProgressProps } from './progress';
46
+ export { OneTable } from './table';
47
+ export type { OneTableColumn, OneTableProps, OneTableRow } from './table';
48
+ export { OneCollapse } from './collapse';
49
+ export type { OneCollapseChangeEvent, OneCollapseItem, OneCollapseProps, } from './collapse';
50
+ export { OneSkeleton } from './skeleton';
51
+ export type { OneSkeletonProps } from './skeleton';
32
52
  export { ONE_THEME_DEFAULTS } from './styles/shared';
33
53
  export { ONE_DEFAULT_THEME, OneThemeConfigError, OneThemeEnvironmentError, OneThemeNotFoundError, oneTheme, } from './theme';
34
54
  export type { OneResolvedTheme, OneThemeBorder, OneThemeColors, OneThemeDefinition, OneThemeInitOptions, OneThemeRadius, OneThemeService, OneThemeTypography, } from './theme';
@@ -42,5 +62,7 @@ export { OneDialog, OneDialogService, createOneDialogService, oneDialog, } from
42
62
  export type { OneDialogProps, OneDialogServiceOptions } from './dialog';
43
63
  export { OneTooltip } from './tooltip';
44
64
  export type { OneTooltipProps, OneTooltipTrigger } from './tooltip';
65
+ export { OneLoading } from './loading';
66
+ export type { OneLoadingProps } from './loading';
45
67
  export declare const ONE_NAME = "@geektech/one";
46
- export declare const ONE_VERSION = "0.0.1";
68
+ export declare const ONE_VERSION = "0.3.1";