@doubao-dev/template 0.0.42 → 0.1.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.md +70 -7
- package/dist/primitives/icon/index.d.ts +6 -0
- package/dist/primitives/icon/index.js +25 -0
- package/dist/primitives/icon/styles.css +7 -0
- package/dist/primitives/icon/types.d.ts +11 -0
- package/dist/primitives/icon/types.js +0 -0
- package/dist/primitives/index.d.ts +2 -0
- package/dist/primitives/index.js +2 -0
- package/dist/primitives/option-group/index.d.ts +5 -0
- package/dist/primitives/option-group/index.js +90 -0
- package/dist/primitives/option-group/styles.css +98 -0
- package/dist/primitives/option-group/types.d.ts +71 -0
- package/dist/primitives/option-group/types.js +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ export default function ProductCard() {
|
|
|
51
51
|
|
|
52
52
|
## Primitives
|
|
53
53
|
|
|
54
|
-
`primitives` 是模板体系中的可组合业务单元,不包含完整卡片外壳。`Title`、`Tag`、`Price`、后续的 `Play` 等单元统一通过该子入口导入。
|
|
54
|
+
`primitives` 是模板体系中的可组合业务单元,不包含完整卡片外壳。`Title`、`Tag`、`Icon`、`OptionGroup`、`Price`、后续的 `Play` 等单元统一通过该子入口导入。
|
|
55
55
|
|
|
56
56
|
### Title
|
|
57
57
|
|
|
@@ -96,6 +96,69 @@ import { Tag } from '@doubao-dev/template/primitives';
|
|
|
96
96
|
- 标签内容不会收缩或截断;业务容器负责测量或通过换行裁切隐藏放不下的整枚标签,不能只裁切标签文字。
|
|
97
97
|
- `className` 和 `style` 可用于样式定制。
|
|
98
98
|
|
|
99
|
+
### Icon
|
|
100
|
+
|
|
101
|
+
图标组件,通过名称选择模板体系提供的图标。
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { Icon } from '@doubao-dev/template/primitives';
|
|
105
|
+
|
|
106
|
+
<Icon name="add" />
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
说明:
|
|
110
|
+
|
|
111
|
+
- `name` 当前仅支持 `add`。
|
|
112
|
+
- 默认尺寸为 14px × 14px。
|
|
113
|
+
- `className` 和 `style` 可用于调整图标尺寸和布局;当前 `add` 图标使用 `neutral-50` 并自动适配主题。
|
|
114
|
+
|
|
115
|
+
### OptionGroup
|
|
116
|
+
|
|
117
|
+
选项集合组件,用于座席、乘车人等选择场景,统一管理选项布局、换行和选择状态。
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import { useState } from '@byted-lynx/react';
|
|
121
|
+
import { OptionGroup } from '@doubao-dev/template/primitives';
|
|
122
|
+
|
|
123
|
+
const [seatValue, setSeatValue] = useState<string | number>('second');
|
|
124
|
+
|
|
125
|
+
<OptionGroup
|
|
126
|
+
size="lg"
|
|
127
|
+
columns={3}
|
|
128
|
+
items={[
|
|
129
|
+
{ value: 'second', title: '二等座', subtitle: '¥38.5 有票' },
|
|
130
|
+
{ value: 'first', title: '一等座', subtitle: '¥60 有票' },
|
|
131
|
+
{ value: 'business', title: '商务座', subtitle: '¥130 16张' },
|
|
132
|
+
{ value: 'standing', title: '无座', subtitle: '¥38.5 有票' }
|
|
133
|
+
]}
|
|
134
|
+
value={seatValue}
|
|
135
|
+
onChange={(nextValue) => setSeatValue(nextValue)}
|
|
136
|
+
/>
|
|
137
|
+
|
|
138
|
+
const [passengerValues, setPassengerValues] = useState<Array<string | number>>(['wang']);
|
|
139
|
+
|
|
140
|
+
<OptionGroup
|
|
141
|
+
selectionMode="multiple"
|
|
142
|
+
maxSelected={2}
|
|
143
|
+
items={[
|
|
144
|
+
{ value: 'wang', title: '王一山' },
|
|
145
|
+
{ value: 'zheng', title: '郑天' },
|
|
146
|
+
{ value: 'add', title: '添加', icon: 'add' }
|
|
147
|
+
]}
|
|
148
|
+
value={passengerValues}
|
|
149
|
+
onChange={(nextValues) => setPassengerValues(nextValues)}
|
|
150
|
+
/>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
说明:
|
|
154
|
+
|
|
155
|
+
- `items` 是唯一的选项内容入口,不支持 `children`;每项使用唯一的 `value` 标识,并可配置 `title`、`disabled` 和独立 `onClick`。
|
|
156
|
+
- `size` 支持 `md | lg`,默认是 `md`;`md` 高 44px、由内容撑开并自动换行,支持 `icon`;`lg` 高 62px、按栏等分并自动换行,支持 `subtitle`。
|
|
157
|
+
- `columns` 仅用于 `lg`,默认每行 3 栏,选项间距固定为 8px;最后一行的选项保持单栏宽度。
|
|
158
|
+
- `selectionMode` 默认是 `single`,此时 `value` 和 `onChange` 使用单个值;传 `multiple` 时使用值数组,并可通过 `maxSelected={2}` 限制为双选;达到上限后点击未选项不会触发 `onChange`,但仍会触发该 item 的 `onClick`,已选项仍可取消。
|
|
159
|
+
- 用户点击选项时,组件先计算新选择并触发 `onChange`,再触发该 item 的 `onClick`;禁用项不触发事件。
|
|
160
|
+
- `className` 和 `style` 只作用于集合根节点,单项样式由模板统一管理。
|
|
161
|
+
|
|
99
162
|
### Price
|
|
100
163
|
|
|
101
164
|
价格展示组件,用于卡片内容中的金额、币种、前后缀、辅助信息和原价排版。`Price` 是业务展示组件,不包含卡片外壳。
|
|
@@ -121,7 +184,7 @@ import { Price } from '@doubao-dev/template/primitives';
|
|
|
121
184
|
|
|
122
185
|
## ContentCard
|
|
123
186
|
|
|
124
|
-
<img src="https://unpkg.com/@doubao-dev/template@0.0
|
|
187
|
+
<img src="https://unpkg.com/@doubao-dev/template@0.1.0/assets/content-card.png" alt="ContentCard 示例" width="400" />
|
|
125
188
|
|
|
126
189
|
通用列表卡,由标题栏、列表内容和底部操作区组成,适合商品、服务、内容入口等可重复条目。
|
|
127
190
|
|
|
@@ -163,7 +226,7 @@ import { ContentCard } from '@doubao-dev/template';
|
|
|
163
226
|
|
|
164
227
|
## PriceActionCard
|
|
165
228
|
|
|
166
|
-
<img src="https://unpkg.com/@doubao-dev/template@0.0
|
|
229
|
+
<img src="https://unpkg.com/@doubao-dev/template@0.1.0/assets/price-action-card.png" alt="PriceActionCard 示例" width="400" />
|
|
167
230
|
|
|
168
231
|
价格操作卡,由多条"价格 + 信息 + 右侧按钮"组成,适合报价、权益、服务方案等结果列表。
|
|
169
232
|
|
|
@@ -196,7 +259,7 @@ import { PriceActionCard } from '@doubao-dev/template';
|
|
|
196
259
|
|
|
197
260
|
## CheckoutCard
|
|
198
261
|
|
|
199
|
-
<img src="https://unpkg.com/@doubao-dev/template@0.0
|
|
262
|
+
<img src="https://unpkg.com/@doubao-dev/template@0.1.0/assets/checkout-card.png" alt="CheckoutCard 示例" width="400" />
|
|
200
263
|
|
|
201
264
|
通用提单卡,由商品摘要、提单信息、费用汇总和底部操作区组成,适合下单确认、支付确认等场景。
|
|
202
265
|
|
|
@@ -247,7 +310,7 @@ import { CheckoutCard } from '@doubao-dev/template';
|
|
|
247
310
|
|
|
248
311
|
## TicketOrderCard
|
|
249
312
|
|
|
250
|
-
<img src="https://unpkg.com/@doubao-dev/template@0.0
|
|
313
|
+
<img src="https://unpkg.com/@doubao-dev/template@0.1.0/assets/ticket-checkout-card.png" alt="TicketOrderCard 示例" width="400" />
|
|
251
314
|
|
|
252
315
|
> **已废弃:** 请使用 `CheckoutCard`。`TicketOrderCard` 仅为兼容现有代码保留。
|
|
253
316
|
|
|
@@ -294,7 +357,7 @@ import { TicketOrderCard } from '@doubao-dev/template';
|
|
|
294
357
|
|
|
295
358
|
## TransitCard
|
|
296
359
|
|
|
297
|
-
<img src="https://unpkg.com/@doubao-dev/template@0.0
|
|
360
|
+
<img src="https://unpkg.com/@doubao-dev/template@0.1.0/assets/transit-card.png" alt="TransitCard 示例" width="400" />
|
|
298
361
|
|
|
299
362
|
交通票务列表卡,由多条出发、中转、到达和价格信息组成,适合展示机票、火车票、大巴等推荐列表。
|
|
300
363
|
|
|
@@ -342,7 +405,7 @@ import { TransitCard } from '@doubao-dev/template';
|
|
|
342
405
|
|
|
343
406
|
## AskHumanCard
|
|
344
407
|
|
|
345
|
-
<img src="https://unpkg.com/@doubao-dev/template@0.0
|
|
408
|
+
<img src="https://unpkg.com/@doubao-dev/template@0.1.0/assets/ask-human-card.png" alt="AskHumanCard 示例" width="400" />
|
|
346
409
|
|
|
347
410
|
人工确认选项卡,由一组选项组成,适合让用户在多个候选项中确认选择。
|
|
348
411
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { IconName, IconProps } from './types.js';
|
|
2
|
+
import './styles.scss';
|
|
3
|
+
export type { IconName, IconProps } from './types.js';
|
|
4
|
+
export declare function isIconSupported(name: string): name is IconName;
|
|
5
|
+
export declare function Icon({ name, className, style }: IconProps): any;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useTheme } from "@byted-doubao-apps/components";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import "./styles.css";
|
|
4
|
+
function getAddIconContent(color) {
|
|
5
|
+
return `<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
6
|
+
<g transform="translate(1.16667 1.10835)">
|
|
7
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.83333 2.80481e-08C6.18771 4.35387e-08 6.475 0.287284 6.475 0.641667L6.475 11.1417C6.475 11.496 6.18771 11.7833 5.83333 11.7833C5.47895 11.7833 5.19166 11.496 5.19166 11.1417L5.19166 0.641667C5.19166 0.287284 5.47895 1.25576e-08 5.83333 2.80481e-08Z" fill="${color}"/>
|
|
8
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.7833 5.95C11.7833 6.30439 11.496 6.59167 11.1417 6.59167L0.641665 6.59167C0.287284 6.59167 -3.68276e-07 6.30439 -3.37294e-07 5.95C-3.06313e-07 5.59562 0.287284 5.30834 0.641665 5.30834L11.1417 5.30834C11.496 5.30834 11.7833 5.59562 11.7833 5.95Z" fill="${color}"/>
|
|
9
|
+
</g>
|
|
10
|
+
</svg>`;
|
|
11
|
+
}
|
|
12
|
+
const ICON_CONTENT_GETTERS = {
|
|
13
|
+
add: getAddIconContent
|
|
14
|
+
};
|
|
15
|
+
function isIconSupported(name) {
|
|
16
|
+
return Object.prototype.hasOwnProperty.call(ICON_CONTENT_GETTERS, name);
|
|
17
|
+
}
|
|
18
|
+
function Icon({ name, className, style }) {
|
|
19
|
+
const theme = useTheme();
|
|
20
|
+
const getContent = ICON_CONTENT_GETTERS[name];
|
|
21
|
+
if (!getContent) return null;
|
|
22
|
+
const color = 'dark' === theme ? '#777777' : '#999999';
|
|
23
|
+
return <svg className={clsx('doubao-icon', className)} style={style} content={getContent(color)}/>;
|
|
24
|
+
}
|
|
25
|
+
export { Icon, isIconSupported };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CSSProperties } from '@lynx-js/types';
|
|
2
|
+
export type IconName = 'add';
|
|
3
|
+
export interface IconProps {
|
|
4
|
+
/** 图标名称。 */
|
|
5
|
+
name: IconName;
|
|
6
|
+
/** 组件类名。 */
|
|
7
|
+
className?: string;
|
|
8
|
+
/** 组件样式。 */
|
|
9
|
+
style?: CSSProperties;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=types.d.ts.map
|
|
File without changes
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { Icon, type IconName, type IconProps } from './icon/index.js';
|
|
2
|
+
export { OptionGroup, type OptionGroupItem, type OptionGroupLargeItem, type OptionGroupMediumItem, type OptionGroupProps, type OptionGroupSize, type OptionGroupText, type OptionGroupValue } from './option-group/index.js';
|
|
1
3
|
export { Price, type PricePrefixTone, type PriceProps, type PriceTone, type PriceValue } from './price/index.js';
|
|
2
4
|
export { Tag, type TagProps, type TagTone, type TagValue } from './tag/index.js';
|
|
3
5
|
export { Title, type TitleMaxLines, type TitleProps, type TitleValue } from './title/index.js';
|
package/dist/primitives/index.js
CHANGED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { OptionGroupProps } from './types.js';
|
|
2
|
+
import './styles.scss';
|
|
3
|
+
export type { OptionGroupItem, OptionGroupLargeItem, OptionGroupMediumItem, OptionGroupProps, OptionGroupSize, OptionGroupText, OptionGroupValue } from './types.js';
|
|
4
|
+
export declare function OptionGroup(props: OptionGroupProps): any;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { useThemeClassName } from "@byted-doubao-apps/components";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { Icon, isIconSupported } from "../icon/index.js";
|
|
4
|
+
import "./styles.css";
|
|
5
|
+
const OPTION_GAP = 8;
|
|
6
|
+
const DEFAULT_COLUMNS = 3;
|
|
7
|
+
const COLUMN_ROUNDING_TOLERANCE = 0.5;
|
|
8
|
+
function resolveColumns(columns) {
|
|
9
|
+
return null != columns && Number.isFinite(columns) && columns >= 1 ? Math.floor(columns) : DEFAULT_COLUMNS;
|
|
10
|
+
}
|
|
11
|
+
function getLargeOptionStyle(columns) {
|
|
12
|
+
const reservedWidth = (columns - 1) * OPTION_GAP + COLUMN_ROUNDING_TOLERANCE;
|
|
13
|
+
const width = `calc((100% - ${reservedWidth}px) / ${columns})`;
|
|
14
|
+
return {
|
|
15
|
+
width,
|
|
16
|
+
flexBasis: width
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function isSelected(props, value) {
|
|
20
|
+
if ('multiple' === props.selectionMode) return props.value?.includes(value) ?? false;
|
|
21
|
+
return props.value === value;
|
|
22
|
+
}
|
|
23
|
+
function handleOptionClick(props, item, event) {
|
|
24
|
+
if ('multiple' === props.selectionMode) {
|
|
25
|
+
const currentValue = props.value ?? [];
|
|
26
|
+
const selected = currentValue.includes(item.value);
|
|
27
|
+
const maxSelected = null != props.maxSelected && Number.isFinite(props.maxSelected) && props.maxSelected >= 1 ? Math.floor(props.maxSelected) : void 0;
|
|
28
|
+
if (selected) props.onChange?.(currentValue.filter((value)=>value !== item.value), item, event);
|
|
29
|
+
else if (null == maxSelected || currentValue.length < maxSelected) props.onChange?.([
|
|
30
|
+
...currentValue,
|
|
31
|
+
item.value
|
|
32
|
+
], item, event);
|
|
33
|
+
} else if (props.value !== item.value) props.onChange?.(item.value, item, event);
|
|
34
|
+
item.onClick?.(event);
|
|
35
|
+
}
|
|
36
|
+
function MediumOptionItemView({ item, selected, onClick }) {
|
|
37
|
+
const hasIcon = Boolean(item.icon) && isIconSupported(item.icon ?? '');
|
|
38
|
+
return <view className={clsx('doubao-option-group__item', 'doubao-option-group__item--size-md', {
|
|
39
|
+
'doubao-option-group__item--selected': selected,
|
|
40
|
+
'doubao-option-group__item--disabled': item.disabled,
|
|
41
|
+
'doubao-option-group__item--with-icon': hasIcon
|
|
42
|
+
})} bindtap={item.disabled ? void 0 : onClick}>
|
|
43
|
+
{hasIcon && item.icon ? <Icon className="doubao-option-group__icon" name={item.icon}/> : null}
|
|
44
|
+
<view className="doubao-option-group__content">
|
|
45
|
+
<text className="doubao-option-group__title" text-maxline="1">
|
|
46
|
+
{item.title}
|
|
47
|
+
</text>
|
|
48
|
+
</view>
|
|
49
|
+
</view>;
|
|
50
|
+
}
|
|
51
|
+
function LargeOptionItemView({ item, selected, style, onClick }) {
|
|
52
|
+
return <view className={clsx('doubao-option-group__item', 'doubao-option-group__item--size-lg', {
|
|
53
|
+
'doubao-option-group__item--selected': selected,
|
|
54
|
+
'doubao-option-group__item--disabled': item.disabled
|
|
55
|
+
})} style={style} bindtap={item.disabled ? void 0 : onClick}>
|
|
56
|
+
<view className="doubao-option-group__content">
|
|
57
|
+
<text className="doubao-option-group__title" text-maxline="1">
|
|
58
|
+
{item.title}
|
|
59
|
+
</text>
|
|
60
|
+
{void 0 !== item.subtitle ? <text className="doubao-option-group__subtitle" text-maxline="1">
|
|
61
|
+
{item.subtitle}
|
|
62
|
+
</text> : null}
|
|
63
|
+
</view>
|
|
64
|
+
</view>;
|
|
65
|
+
}
|
|
66
|
+
function renderOptionViews(props) {
|
|
67
|
+
if ('lg' === props.size) {
|
|
68
|
+
const optionStyle = getLargeOptionStyle(resolveColumns(props.columns));
|
|
69
|
+
return props.items.map((item)=>{
|
|
70
|
+
const selected = isSelected(props, item.value);
|
|
71
|
+
const onClick = (event)=>handleOptionClick(props, item, event);
|
|
72
|
+
return <LargeOptionItemView key={item.value} item={item} selected={selected} style={optionStyle} onClick={onClick}/>;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return props.items.map((item)=>{
|
|
76
|
+
const selected = isSelected(props, item.value);
|
|
77
|
+
const onClick = (event)=>handleOptionClick(props, item, event);
|
|
78
|
+
return <MediumOptionItemView key={item.value} item={item} selected={selected} onClick={onClick}/>;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function OptionGroup(props) {
|
|
82
|
+
const { className, style } = props;
|
|
83
|
+
const size = props.size ?? 'md';
|
|
84
|
+
const themedClassName = useThemeClassName(clsx('doubao-option-group', `doubao-option-group--size-${size}`, className));
|
|
85
|
+
const optionViews = renderOptionViews(props);
|
|
86
|
+
return <view className={themedClassName} style={style}>
|
|
87
|
+
{optionViews}
|
|
88
|
+
</view>;
|
|
89
|
+
}
|
|
90
|
+
export { OptionGroup };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
.doubao-option-group {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
flex-flow: wrap;
|
|
4
|
+
align-items: center;
|
|
5
|
+
gap: 8px;
|
|
6
|
+
width: 100%;
|
|
7
|
+
min-width: 0;
|
|
8
|
+
display: flex;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.doubao-option-group--size-lg {
|
|
12
|
+
align-items: flex-start;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.doubao-option-group__item {
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
background-color: var(--bg-base-2-overlay);
|
|
18
|
+
border: .5px solid #0000;
|
|
19
|
+
border-radius: 8px;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
align-items: center;
|
|
22
|
+
min-width: 0;
|
|
23
|
+
display: flex;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.doubao-option-group__item--size-md {
|
|
28
|
+
width: max-content;
|
|
29
|
+
max-width: 100%;
|
|
30
|
+
height: 44px;
|
|
31
|
+
padding: 12px 16px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.doubao-option-group__item--size-lg {
|
|
35
|
+
border-width: 1px;
|
|
36
|
+
flex-grow: 0;
|
|
37
|
+
flex-shrink: 0;
|
|
38
|
+
height: 62px;
|
|
39
|
+
padding: 12px 4px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.doubao-option-group__item--with-icon {
|
|
43
|
+
gap: 4px;
|
|
44
|
+
padding-left: 12px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.doubao-option-group__item--selected {
|
|
48
|
+
background-color: var(--bg-base-1);
|
|
49
|
+
border-color: var(--primary-50);
|
|
50
|
+
background-image: linear-gradient(#0066ff0f, #0066ff0f);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.doubao-option-group__item--disabled {
|
|
54
|
+
opacity: .3;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.doubao-option-group__icon {
|
|
58
|
+
width: 14px;
|
|
59
|
+
height: 14px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.doubao-option-group__content {
|
|
63
|
+
flex-direction: column;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: 2px;
|
|
66
|
+
min-width: 0;
|
|
67
|
+
max-width: 100%;
|
|
68
|
+
display: flex;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.doubao-option-group__title, .doubao-option-group__subtitle {
|
|
72
|
+
text-align: center;
|
|
73
|
+
text-overflow: ellipsis;
|
|
74
|
+
white-space: nowrap;
|
|
75
|
+
min-width: 0;
|
|
76
|
+
max-width: 100%;
|
|
77
|
+
font-family: PingFang SC, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, sans-serif;
|
|
78
|
+
font-size: 13px;
|
|
79
|
+
font-style: normal;
|
|
80
|
+
line-height: 18px;
|
|
81
|
+
display: block;
|
|
82
|
+
overflow: hidden;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.doubao-option-group__title {
|
|
86
|
+
color: var(--neutral-100);
|
|
87
|
+
font-weight: 500;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.doubao-option-group__subtitle {
|
|
91
|
+
color: var(--neutral-70);
|
|
92
|
+
font-weight: 400;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.doubao-option-group__item--size-lg .doubao-option-group__content, .doubao-option-group__item--size-lg .doubao-option-group__title, .doubao-option-group__item--size-lg .doubao-option-group__subtitle {
|
|
96
|
+
width: 100%;
|
|
97
|
+
}
|
|
98
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { CSSProperties, TouchEvent } from '@lynx-js/types';
|
|
2
|
+
import type { IconName } from '../icon/index.js';
|
|
3
|
+
export type OptionGroupValue = string | number;
|
|
4
|
+
export type OptionGroupText = string | number;
|
|
5
|
+
export type OptionGroupSize = 'md' | 'lg';
|
|
6
|
+
interface OptionGroupItemCommon {
|
|
7
|
+
/** 选项唯一值。 */
|
|
8
|
+
value: OptionGroupValue;
|
|
9
|
+
/** 选项标题。 */
|
|
10
|
+
title: OptionGroupText;
|
|
11
|
+
/** 是否禁用。@defaultValue false */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** 点击当前选项时触发。 */
|
|
14
|
+
onClick?: (event: TouchEvent) => void;
|
|
15
|
+
}
|
|
16
|
+
export interface OptionGroupMediumItem extends OptionGroupItemCommon {
|
|
17
|
+
/** 标题前图标名称,由 Icon Primitive 解析。 */
|
|
18
|
+
icon?: IconName;
|
|
19
|
+
subtitle?: never;
|
|
20
|
+
}
|
|
21
|
+
export interface OptionGroupLargeItem extends OptionGroupItemCommon {
|
|
22
|
+
/** 第二行辅助信息。 */
|
|
23
|
+
subtitle?: OptionGroupText;
|
|
24
|
+
icon?: never;
|
|
25
|
+
}
|
|
26
|
+
export type OptionGroupItem = OptionGroupMediumItem | OptionGroupLargeItem;
|
|
27
|
+
interface OptionGroupCommonProps {
|
|
28
|
+
/** 组件类名。 */
|
|
29
|
+
className?: string;
|
|
30
|
+
/** 组件样式。 */
|
|
31
|
+
style?: CSSProperties;
|
|
32
|
+
}
|
|
33
|
+
interface OptionGroupMediumLayoutProps extends OptionGroupCommonProps {
|
|
34
|
+
/** 选项尺寸。@defaultValue 'md' */
|
|
35
|
+
size?: 'md';
|
|
36
|
+
/** 中尺寸选项数据。 */
|
|
37
|
+
items: OptionGroupMediumItem[];
|
|
38
|
+
columns?: never;
|
|
39
|
+
}
|
|
40
|
+
interface OptionGroupLargeLayoutProps extends OptionGroupCommonProps {
|
|
41
|
+
/** 选项尺寸。 */
|
|
42
|
+
size: 'lg';
|
|
43
|
+
/** 大尺寸选项数据。 */
|
|
44
|
+
items: OptionGroupLargeItem[];
|
|
45
|
+
/** 每行展示栏数。@defaultValue 3 */
|
|
46
|
+
columns?: number;
|
|
47
|
+
}
|
|
48
|
+
interface OptionGroupSingleSelectionProps {
|
|
49
|
+
/** 选择模式。@defaultValue 'single' */
|
|
50
|
+
selectionMode?: 'single';
|
|
51
|
+
/** 当前选中的选项值。 */
|
|
52
|
+
value?: OptionGroupValue;
|
|
53
|
+
maxSelected?: never;
|
|
54
|
+
/** 选中项变化时触发。 */
|
|
55
|
+
onChange?: (value: OptionGroupValue, item: OptionGroupItem, event: TouchEvent) => void;
|
|
56
|
+
}
|
|
57
|
+
interface OptionGroupMultipleSelectionProps {
|
|
58
|
+
/** 多选模式。 */
|
|
59
|
+
selectionMode: 'multiple';
|
|
60
|
+
/** 当前选中的选项值。 */
|
|
61
|
+
value?: OptionGroupValue[];
|
|
62
|
+
/** 最大选择数量;双选时传 2。 */
|
|
63
|
+
maxSelected?: number;
|
|
64
|
+
/** 选中项变化时触发。 */
|
|
65
|
+
onChange?: (value: OptionGroupValue[], item: OptionGroupItem, event: TouchEvent) => void;
|
|
66
|
+
}
|
|
67
|
+
type OptionGroupLayoutProps = OptionGroupMediumLayoutProps | OptionGroupLargeLayoutProps;
|
|
68
|
+
type OptionGroupSelectionProps = OptionGroupSingleSelectionProps | OptionGroupMultipleSelectionProps;
|
|
69
|
+
export type OptionGroupProps = OptionGroupLayoutProps & OptionGroupSelectionProps;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=types.d.ts.map
|
|
File without changes
|