@doubao-dev/template 0.0.38 → 0.0.39
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 +116 -44
- package/dist/ask-human-card/index.d.ts +1 -3
- package/dist/ask-human-card/index.js +4 -8
- package/dist/checkout-card/index.d.ts +3 -5
- package/dist/checkout-card/index.js +2 -2
- package/dist/components/info-section/index.d.ts +0 -2
- package/dist/components/info-section/index.js +4 -7
- package/dist/components/info-section/styles.css +28 -18
- package/dist/components/product-summary/index.d.ts +5 -1
- package/dist/components/product-summary/index.js +9 -7
- package/dist/components/product-summary/styles.css +25 -16
- package/dist/components/route-section/index.d.ts +5 -1
- package/dist/components/route-section/index.js +2 -0
- package/dist/components/route-section/styles.css +24 -0
- package/dist/content-card/index.d.ts +13 -3
- package/dist/content-card/index.js +12 -6
- package/dist/content-card/styles.css +9 -5
- package/dist/index.d.ts +1 -1
- package/dist/price-action-card/index.d.ts +8 -2
- package/dist/price-action-card/index.js +2 -8
- package/dist/price-action-card/styles.css +15 -29
- package/dist/primitives/index.d.ts +4 -0
- package/dist/primitives/index.js +3 -0
- package/dist/primitives/price/index.d.ts +5 -0
- package/dist/primitives/price/index.js +56 -0
- package/dist/primitives/price/styles.css +130 -0
- package/dist/primitives/price/types.d.ts +26 -0
- package/dist/primitives/price/types.js +0 -0
- package/dist/primitives/tag/index.d.ts +5 -0
- package/dist/primitives/tag/index.js +10 -0
- package/dist/primitives/tag/styles.css +70 -0
- package/dist/primitives/tag/types.d.ts +14 -0
- package/dist/primitives/tag/types.js +0 -0
- package/dist/primitives/title/index.d.ts +5 -0
- package/dist/primitives/title/index.js +18 -0
- package/dist/primitives/title/styles.css +63 -0
- package/dist/primitives/title/types.d.ts +18 -0
- package/dist/primitives/title/types.js +0 -0
- package/dist/ticket-order-card/index.d.ts +20 -1
- package/dist/types.d.ts +1 -0
- package/package.json +6 -1
- package/dist/components/action-bar/index.d.ts +0 -31
- package/dist/components/action-bar/index.js +0 -15
- package/dist/components/action-bar/styles.css +0 -27
- package/dist/components/title-bar/index.d.ts +0 -11
- package/dist/components/title-bar/index.js +0 -33
- package/dist/components/title-bar/styles.css +0 -66
|
@@ -19,11 +19,13 @@ function renderTemplateRouteSectionItem(item, index) {
|
|
|
19
19
|
if (!hasTemplateRouteSectionItemContent(item)) return null;
|
|
20
20
|
const titleNode = renderTemplateRouteSectionTextField(item.title, 'doubao-template-route-section__title-text');
|
|
21
21
|
const descriptionNode = renderTemplateRouteSectionTextField(item.description, "doubao-template-route-section__description");
|
|
22
|
+
const tagNode = renderTemplateRouteSectionTextField(item.tagText, 'highlight' === item.tagTone ? 'doubao-template-route-section__tag doubao-template-route-section__tag--highlight' : 'doubao-template-route-section__tag');
|
|
22
23
|
const showChevron = false !== item.showChevron && titleNode;
|
|
23
24
|
return <view className="doubao-template-route-section__item" key={item.key ?? index} {...null != item.onClick ? {
|
|
24
25
|
catchtap: item.onClick
|
|
25
26
|
} : {}}>
|
|
26
27
|
{titleNode && <view className="doubao-template-route-section__title">
|
|
28
|
+
{tagNode}
|
|
27
29
|
{titleNode}
|
|
28
30
|
{showChevron && <TemplateChevronRightIcon className="doubao-template-route-section__chevron"/>}
|
|
29
31
|
</view>}
|
|
@@ -42,6 +42,30 @@
|
|
|
42
42
|
margin-left: 5px;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
.doubao-template-route-section__tag {
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
height: 18px;
|
|
48
|
+
color: var(--neutral-70);
|
|
49
|
+
text-overflow: ellipsis;
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
background-color: var(--bg-base-2-overlay);
|
|
52
|
+
border-radius: 4px;
|
|
53
|
+
flex-shrink: 0;
|
|
54
|
+
margin-right: 4px;
|
|
55
|
+
padding: 2px 4px;
|
|
56
|
+
font-family: PingFang SC, sans-serif;
|
|
57
|
+
font-size: 12px;
|
|
58
|
+
font-style: normal;
|
|
59
|
+
font-weight: 400;
|
|
60
|
+
line-height: 14px;
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.doubao-template-route-section__tag--highlight {
|
|
65
|
+
color: var(--primary-60);
|
|
66
|
+
background-color: var(--primary-transparent-1);
|
|
67
|
+
}
|
|
68
|
+
|
|
45
69
|
.doubao-template-route-section__description {
|
|
46
70
|
width: 100%;
|
|
47
71
|
height: 20px;
|
|
@@ -12,7 +12,10 @@ export interface ContentCardProps {
|
|
|
12
12
|
items?: ContentCardItem[];
|
|
13
13
|
/** 底部操作区配置。 */
|
|
14
14
|
footer?: TemplateCardFooterProps;
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* 自定义列表内容区域;传入后不再渲染默认列表内容,标题栏和底部操作区仍由模板渲染。
|
|
17
|
+
* @deprecated 仅为兼容旧代码保留。新代码请使用 items。
|
|
18
|
+
*/
|
|
16
19
|
children?: ReactNode;
|
|
17
20
|
/** 卡片根节点自定义类名。 */
|
|
18
21
|
className?: string;
|
|
@@ -28,9 +31,16 @@ export interface ContentCardItem {
|
|
|
28
31
|
title?: ReactNode;
|
|
29
32
|
/** 列表项副标题。字符串会按默认单行副标题样式渲染,传入节点时直接渲染自定义内容。 */
|
|
30
33
|
subtitle?: ReactNode;
|
|
31
|
-
/**
|
|
34
|
+
/** 列表项补充描述。字符串会按默认单行描述样式渲染,传入节点时直接渲染自定义内容。 */
|
|
35
|
+
description?: ReactNode;
|
|
36
|
+
/** 列表项左侧缩略图地址。 */
|
|
37
|
+
thumbnailSrc?: string;
|
|
38
|
+
/** 列表项左侧缩略视觉内容;优先级高于 thumbnailSrc。 */
|
|
32
39
|
thumbnail?: ReactNode;
|
|
33
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* 列表项自定义内容;传入后不再渲染默认图文结构。
|
|
42
|
+
* @deprecated 仅为兼容旧代码保留。新代码请使用 title、subtitle、description、thumbnail 和 action。
|
|
43
|
+
*/
|
|
34
44
|
children?: ReactNode;
|
|
35
45
|
/** 列表项右侧操作区;传标准控件配置时使用模板样式,传节点时直接渲染自定义内容。 */
|
|
36
46
|
action?: TemplateExtraAction | ReactNode;
|
|
@@ -7,9 +7,13 @@ import "./styles.css";
|
|
|
7
7
|
function isContentCardNodeEmpty(content) {
|
|
8
8
|
return null == content || 'boolean' == typeof content || '' === content;
|
|
9
9
|
}
|
|
10
|
-
function ContentCardThumbnail({ thumbnail }) {
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
function ContentCardThumbnail({ thumbnail, thumbnailSrc }) {
|
|
11
|
+
const hasThumbnailNode = !isContentCardNodeEmpty(thumbnail);
|
|
12
|
+
const resolvedThumbnailSrc = thumbnailSrc && thumbnailSrc.length > 0 ? thumbnailSrc : null;
|
|
13
|
+
if (!hasThumbnailNode && null == resolvedThumbnailSrc) return null;
|
|
14
|
+
return <view className="doubao-content-card__thumbnail">
|
|
15
|
+
{hasThumbnailNode ? thumbnail : <image className="doubao-content-card__thumbnail-image" src={resolvedThumbnailSrc} mode="aspectFill"/>}
|
|
16
|
+
</view>;
|
|
13
17
|
}
|
|
14
18
|
function renderContentCardText(content, className) {
|
|
15
19
|
if (isContentCardNodeEmpty(content)) return null;
|
|
@@ -37,19 +41,21 @@ function renderContentCardAction(action) {
|
|
|
37
41
|
return action;
|
|
38
42
|
}
|
|
39
43
|
function ContentCardItemView({ item, isLast }) {
|
|
40
|
-
const { title, subtitle } = item;
|
|
41
|
-
const hasThumbnail = !isContentCardNodeEmpty(item.thumbnail);
|
|
44
|
+
const { title, subtitle, description } = item;
|
|
45
|
+
const hasThumbnail = !isContentCardNodeEmpty(item.thumbnail) || null != item.thumbnailSrc && item.thumbnailSrc.length > 0;
|
|
42
46
|
const subtitleNode = renderContentCardText(subtitle, 'doubao-content-card__subtitle');
|
|
47
|
+
const descriptionNode = renderContentCardText(description, "doubao-content-card__description");
|
|
43
48
|
const actionNode = renderContentCardAction(item.action);
|
|
44
49
|
return <view className={clsx('doubao-content-card__item', isLast && 'doubao-content-card__item--last', !hasThumbnail && 'doubao-content-card__item--without-thumbnail', item.className)} style={item.style} {...null != item.onClick ? {
|
|
45
50
|
catchtap: item.onClick
|
|
46
51
|
} : {}}>
|
|
47
52
|
{item.children ?? <view className="doubao-content-card__content">
|
|
48
53
|
<view className="doubao-content-card__main">
|
|
49
|
-
{hasThumbnail && <ContentCardThumbnail thumbnail={item.thumbnail}/>}
|
|
54
|
+
{hasThumbnail && <ContentCardThumbnail thumbnail={item.thumbnail} thumbnailSrc={item.thumbnailSrc}/>}
|
|
50
55
|
<view className="doubao-content-card__text">
|
|
51
56
|
{renderContentCardText(title, 'doubao-content-card__title')}
|
|
52
57
|
{subtitleNode && <view className="doubao-content-card__secondary">{subtitleNode}</view>}
|
|
58
|
+
{descriptionNode && <view className="doubao-content-card__tertiary">{descriptionNode}</view>}
|
|
53
59
|
</view>
|
|
54
60
|
</view>
|
|
55
61
|
{actionNode && <view className="doubao-content-card__item-action" catchtap={stopTemplateExtraActionTap}>
|
|
@@ -70,17 +70,22 @@
|
|
|
70
70
|
overflow: hidden;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
.doubao-content-card__thumbnail-image {
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
}
|
|
77
|
+
|
|
73
78
|
.doubao-content-card__text {
|
|
74
79
|
flex-direction: column;
|
|
75
80
|
flex: 1 1 0;
|
|
76
81
|
align-items: flex-start;
|
|
82
|
+
gap: 2px;
|
|
77
83
|
min-width: 0;
|
|
78
84
|
display: flex;
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
.doubao-content-card__title {
|
|
82
88
|
width: 100%;
|
|
83
|
-
height: 24px;
|
|
84
89
|
color: var(--neutral-100);
|
|
85
90
|
text-overflow: ellipsis;
|
|
86
91
|
white-space: nowrap;
|
|
@@ -92,7 +97,7 @@
|
|
|
92
97
|
overflow: hidden;
|
|
93
98
|
}
|
|
94
99
|
|
|
95
|
-
.doubao-content-card__title-custom, .doubao-content-card__subtitle-custom {
|
|
100
|
+
.doubao-content-card__title-custom, .doubao-content-card__subtitle-custom, .doubao-content-card__description-custom {
|
|
96
101
|
flex-direction: row;
|
|
97
102
|
align-items: center;
|
|
98
103
|
width: 100%;
|
|
@@ -101,17 +106,16 @@
|
|
|
101
106
|
overflow: hidden;
|
|
102
107
|
}
|
|
103
108
|
|
|
104
|
-
.doubao-content-card__secondary {
|
|
109
|
+
.doubao-content-card__secondary, .doubao-content-card__tertiary {
|
|
105
110
|
flex-direction: row;
|
|
106
111
|
align-items: center;
|
|
107
112
|
width: 100%;
|
|
108
113
|
min-width: 0;
|
|
109
|
-
height: 24px;
|
|
110
114
|
display: flex;
|
|
111
115
|
overflow: hidden;
|
|
112
116
|
}
|
|
113
117
|
|
|
114
|
-
.doubao-content-card__subtitle {
|
|
118
|
+
.doubao-content-card__subtitle, .doubao-content-card__description {
|
|
115
119
|
width: 100%;
|
|
116
120
|
color: var(--neutral-70);
|
|
117
121
|
text-overflow: ellipsis;
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ export { AskHumanCard, type AskHumanCardArrowPosition, type AskHumanCardItem, ty
|
|
|
6
6
|
export { CheckoutCard, type CheckoutCardFeeItem, type CheckoutCardInfoItem, type CheckoutCardProductItem, type CheckoutCardProps } from './checkout-card/index.js';
|
|
7
7
|
export { PriceActionCard, type PriceActionCardInfoRow, type PriceActionCardItem, type PriceActionCardProps } from './price-action-card/index.js';
|
|
8
8
|
export { TransitCard, type TransitCardItem, type TransitCardProps } from './transit-card/index.js';
|
|
9
|
-
export type { TemplateKey, TemplateText } from './types.js';
|
|
9
|
+
export type { TemplateKey, TemplateTagTone, TemplateText } from './types.js';
|
|
10
10
|
export { TicketOrderCard, type TicketOrderCardFeeItem, type TicketOrderCardInfoItem, type TicketOrderCardProps, type TicketOrderCardRouteItem } from './ticket-order-card/index.js';
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -11,7 +11,10 @@ export interface PriceActionCardProps {
|
|
|
11
11
|
items?: PriceActionCardItem[];
|
|
12
12
|
/** 底部操作区配置。 */
|
|
13
13
|
footer?: TemplateCardFooterProps;
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* 自定义卡片内容;传入后不再渲染默认列表,标题栏和底部操作区仍由模板渲染。
|
|
16
|
+
* @deprecated 仅为兼容旧代码保留。新代码请使用 items 的结构化字段。
|
|
17
|
+
*/
|
|
15
18
|
children?: ReactNode;
|
|
16
19
|
/** 卡片根节点自定义类名。 */
|
|
17
20
|
className?: string;
|
|
@@ -31,7 +34,10 @@ export interface PriceActionCardItem {
|
|
|
31
34
|
infoRows?: PriceActionCardInfoRow[];
|
|
32
35
|
/** 右侧操作按钮文案;不传或传空字符串时不展示。 */
|
|
33
36
|
actionText?: string;
|
|
34
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* 列表项自定义内容;传入后不再渲染默认三列结构。
|
|
39
|
+
* @deprecated 仅为兼容旧代码保留。新代码请使用 price、badgeText、infoRows 和 actionText。
|
|
40
|
+
*/
|
|
35
41
|
children?: ReactNode;
|
|
36
42
|
/** 列表项根节点自定义类名。 */
|
|
37
43
|
className?: string;
|
|
@@ -2,6 +2,7 @@ import { Button, useThemeClassName } from "@byted-doubao-apps/components";
|
|
|
2
2
|
import { clsx } from "clsx";
|
|
3
3
|
import { TemplateCardFooter } from "../components/footer/index.js";
|
|
4
4
|
import { TemplateCardHeader } from "../components/header/index.js";
|
|
5
|
+
import { Price } from "../primitives/price/index.js";
|
|
5
6
|
import "./styles.css";
|
|
6
7
|
const PRICE_ACTION_CARD_INFO_ROW_LIMIT = 2;
|
|
7
8
|
const PRICE_ACTION_CARD_CURRENCY_PATTERN = /^([¥¥$€£])(.+)$/;
|
|
@@ -14,14 +15,7 @@ function isPriceActionCardNodeEmpty(content) {
|
|
|
14
15
|
function PriceActionCardPrice({ price }) {
|
|
15
16
|
const priceText = String(price);
|
|
16
17
|
const [, currency, value] = priceText.match(PRICE_ACTION_CARD_CURRENCY_PATTERN) ?? [];
|
|
17
|
-
return <
|
|
18
|
-
{null != currency && <text className="doubao-price-action-card__price-currency" text-maxline="1">
|
|
19
|
-
{currency}
|
|
20
|
-
</text>}
|
|
21
|
-
<text className="doubao-price-action-card__price-value" text-maxline="1">
|
|
22
|
-
{value ?? priceText}
|
|
23
|
-
</text>
|
|
24
|
-
</view>;
|
|
18
|
+
return <Price className="doubao-price-action-card__price" currency={currency ?? ''} value={value ?? priceText} tone="highlight"/>;
|
|
25
19
|
}
|
|
26
20
|
function PriceActionCardItemView({ item, isLast }) {
|
|
27
21
|
const hasPrice = !isPriceActionCardTextEmpty(item.price);
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
align-items: center;
|
|
29
29
|
width: 100%;
|
|
30
30
|
height: 82px;
|
|
31
|
-
padding:
|
|
31
|
+
padding: 20px 12px;
|
|
32
32
|
display: flex;
|
|
33
33
|
position: relative;
|
|
34
34
|
}
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
.doubao-price-action-card__item-content {
|
|
51
51
|
flex-direction: row;
|
|
52
52
|
align-items: center;
|
|
53
|
+
gap: 12px;
|
|
53
54
|
width: 100%;
|
|
54
|
-
padding-left: 4px;
|
|
55
55
|
display: flex;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -59,44 +59,32 @@
|
|
|
59
59
|
flex-direction: column;
|
|
60
60
|
flex-shrink: 0;
|
|
61
61
|
align-items: flex-start;
|
|
62
|
-
width:
|
|
62
|
+
width: 94px;
|
|
63
63
|
min-width: 0;
|
|
64
|
+
padding: 0 4px;
|
|
64
65
|
display: flex;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
.doubao-price-action-card__price {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
color: var(--pink-500);
|
|
71
|
-
white-space: nowrap;
|
|
72
|
-
flex-direction: row;
|
|
73
|
-
align-items: flex-end;
|
|
74
|
-
font-family: SF Pro, sans-serif;
|
|
75
|
-
font-style: normal;
|
|
76
|
-
display: flex;
|
|
68
|
+
.doubao-price-action-card__price.doubao-price {
|
|
69
|
+
width: 100%;
|
|
70
|
+
min-width: 0;
|
|
77
71
|
overflow: hidden;
|
|
78
72
|
}
|
|
79
73
|
|
|
80
|
-
.doubao-price-action-card__price-
|
|
74
|
+
.doubao-price-action-card__price.doubao-price .doubao-price__amount, .doubao-price-action-card__price.doubao-price .doubao-price__main, .doubao-price-action-card__price.doubao-price .doubao-price__integer-group {
|
|
81
75
|
min-width: 0;
|
|
82
|
-
|
|
83
|
-
text-overflow: ellipsis;
|
|
84
|
-
white-space: nowrap;
|
|
85
|
-
font-family: SF Pro, sans-serif;
|
|
86
|
-
font-style: normal;
|
|
87
|
-
font-weight: 600;
|
|
76
|
+
max-width: 100%;
|
|
88
77
|
overflow: hidden;
|
|
89
78
|
}
|
|
90
79
|
|
|
91
|
-
.doubao-price-action-card__price-
|
|
92
|
-
flex-shrink:
|
|
93
|
-
font-size: 13px;
|
|
94
|
-
line-height: 15px;
|
|
80
|
+
.doubao-price-action-card__price.doubao-price .doubao-price__main, .doubao-price-action-card__price.doubao-price .doubao-price__integer-group, .doubao-price-action-card__price.doubao-price .doubao-price__integer {
|
|
81
|
+
flex-shrink: 1;
|
|
95
82
|
}
|
|
96
83
|
|
|
97
|
-
.doubao-price-action-card__price-
|
|
98
|
-
|
|
99
|
-
|
|
84
|
+
.doubao-price-action-card__price.doubao-price .doubao-price__integer {
|
|
85
|
+
text-overflow: ellipsis;
|
|
86
|
+
min-width: 0;
|
|
87
|
+
overflow: hidden;
|
|
100
88
|
}
|
|
101
89
|
|
|
102
90
|
.doubao-price-action-card__badge {
|
|
@@ -122,7 +110,6 @@
|
|
|
122
110
|
flex: 1 1 0;
|
|
123
111
|
justify-content: center;
|
|
124
112
|
min-width: 0;
|
|
125
|
-
margin-left: 16px;
|
|
126
113
|
display: flex;
|
|
127
114
|
}
|
|
128
115
|
|
|
@@ -156,6 +143,5 @@
|
|
|
156
143
|
flex-shrink: 0;
|
|
157
144
|
width: 80px;
|
|
158
145
|
height: 38px;
|
|
159
|
-
margin-left: 12px;
|
|
160
146
|
}
|
|
161
147
|
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { Price, type PriceProps, type PriceTone, type PriceValue } from './price/index.js';
|
|
2
|
+
export { Tag, type TagProps, type TagTone, type TagValue } from './tag/index.js';
|
|
3
|
+
export { Title, type TitleMaxLines, type TitleProps, type TitleValue } from './title/index.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PriceProps } from './types.js';
|
|
2
|
+
import './styles.scss';
|
|
3
|
+
export type { PriceProps, PriceTone, PriceValue } from './types.js';
|
|
4
|
+
export declare function Price({ value, currency, prefix, suffix, description, originalPrice, tone, loading, className, style }: PriceProps): any;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useThemeClassName } from "@byted-doubao-apps/components";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import "./styles.css";
|
|
4
|
+
function splitPriceValue(value) {
|
|
5
|
+
const price = String(value);
|
|
6
|
+
const decimalIndex = price.indexOf('.');
|
|
7
|
+
if (-1 === decimalIndex) return {
|
|
8
|
+
integer: price,
|
|
9
|
+
decimal: ''
|
|
10
|
+
};
|
|
11
|
+
return {
|
|
12
|
+
integer: price.slice(0, decimalIndex),
|
|
13
|
+
decimal: price.slice(decimalIndex)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function formatOriginalPrice(value, currency) {
|
|
17
|
+
const originalPrice = String(value);
|
|
18
|
+
return currency && originalPrice.startsWith(currency) ? originalPrice : `${currency}${originalPrice}`;
|
|
19
|
+
}
|
|
20
|
+
function Price({ value, currency = '¥', prefix, suffix, description, originalPrice, tone = 'default', loading = false, className, style }) {
|
|
21
|
+
const themedClassName = useThemeClassName(className);
|
|
22
|
+
const { integer, decimal } = splitPriceValue(value);
|
|
23
|
+
return <view className={clsx('doubao-price', `doubao-price--tone-${tone}`, {
|
|
24
|
+
'doubao-price--loading': loading
|
|
25
|
+
}, themedClassName)} style={style}>
|
|
26
|
+
{loading ? <view className="doubao-price__placeholder"/> : <>
|
|
27
|
+
<view className="doubao-price__amount">
|
|
28
|
+
{prefix ? <view className="doubao-price__affix">
|
|
29
|
+
<text className="doubao-price__prefix">{prefix}</text>
|
|
30
|
+
</view> : null}
|
|
31
|
+
|
|
32
|
+
<view className="doubao-price__main">
|
|
33
|
+
<view className="doubao-price__integer-group">
|
|
34
|
+
{currency ? <text className="doubao-price__currency">{currency}</text> : null}
|
|
35
|
+
<text className="doubao-price__integer">{integer}</text>
|
|
36
|
+
</view>
|
|
37
|
+
{decimal ? <view className="doubao-price__decimal-group">
|
|
38
|
+
<text className="doubao-price__decimal">{decimal}</text>
|
|
39
|
+
</view> : null}
|
|
40
|
+
</view>
|
|
41
|
+
|
|
42
|
+
{suffix ? <view className="doubao-price__affix">
|
|
43
|
+
<text className="doubao-price__suffix">{suffix}</text>
|
|
44
|
+
</view> : null}
|
|
45
|
+
</view>
|
|
46
|
+
|
|
47
|
+
{void 0 !== originalPrice || description ? <view className="doubao-price__meta">
|
|
48
|
+
{void 0 !== originalPrice ? <text className="doubao-price__original-price">
|
|
49
|
+
{formatOriginalPrice(originalPrice, currency)}
|
|
50
|
+
</text> : null}
|
|
51
|
+
{description ? <text className="doubao-price__description">{description}</text> : null}
|
|
52
|
+
</view> : null}
|
|
53
|
+
</>}
|
|
54
|
+
</view>;
|
|
55
|
+
}
|
|
56
|
+
export { Price };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
.doubao-price {
|
|
2
|
+
height: 22px;
|
|
3
|
+
color: var(--neutral-100);
|
|
4
|
+
white-space: nowrap;
|
|
5
|
+
flex-direction: row;
|
|
6
|
+
align-items: flex-end;
|
|
7
|
+
gap: 4px;
|
|
8
|
+
font-family: PingFang SC, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, sans-serif;
|
|
9
|
+
font-style: normal;
|
|
10
|
+
display: flex;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.doubao-price--tone-highlight .doubao-price__prefix, .doubao-price--tone-highlight .doubao-price__currency, .doubao-price--tone-highlight .doubao-price__integer, .doubao-price--tone-highlight .doubao-price__decimal, .doubao-price--tone-highlight .doubao-price__suffix {
|
|
14
|
+
color: #ff375f;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.doubao-price--loading {
|
|
18
|
+
align-items: center;
|
|
19
|
+
width: 100%;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.doubao-price__amount {
|
|
23
|
+
flex-direction: row;
|
|
24
|
+
flex-shrink: 0;
|
|
25
|
+
align-items: flex-end;
|
|
26
|
+
gap: 2px;
|
|
27
|
+
height: 22px;
|
|
28
|
+
display: flex;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.doubao-price__affix, .doubao-price__meta {
|
|
32
|
+
flex-direction: row;
|
|
33
|
+
flex-shrink: 0;
|
|
34
|
+
align-items: center;
|
|
35
|
+
gap: 4px;
|
|
36
|
+
height: 19px;
|
|
37
|
+
display: flex;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.doubao-price__main {
|
|
41
|
+
flex-direction: row;
|
|
42
|
+
flex-shrink: 0;
|
|
43
|
+
align-items: flex-end;
|
|
44
|
+
height: 22px;
|
|
45
|
+
display: flex;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.doubao-price__integer-group {
|
|
49
|
+
flex-direction: row;
|
|
50
|
+
flex-shrink: 0;
|
|
51
|
+
align-items: center;
|
|
52
|
+
height: 22px;
|
|
53
|
+
display: flex;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.doubao-price__decimal-group {
|
|
57
|
+
flex-shrink: 0;
|
|
58
|
+
align-items: center;
|
|
59
|
+
height: 21px;
|
|
60
|
+
display: flex;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.doubao-price__prefix, .doubao-price__currency, .doubao-price__integer, .doubao-price__decimal, .doubao-price__suffix, .doubao-price__description, .doubao-price__original-price {
|
|
64
|
+
color: var(--neutral-100);
|
|
65
|
+
letter-spacing: 0;
|
|
66
|
+
white-space: nowrap;
|
|
67
|
+
flex-shrink: 0;
|
|
68
|
+
font-family: PingFang SC, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, sans-serif;
|
|
69
|
+
font-style: normal;
|
|
70
|
+
display: block;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.doubao-price__prefix {
|
|
74
|
+
font-size: 12px;
|
|
75
|
+
font-weight: 500;
|
|
76
|
+
line-height: 11px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.doubao-price__currency {
|
|
80
|
+
font-size: 13px;
|
|
81
|
+
font-weight: 500;
|
|
82
|
+
line-height: 11px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.doubao-price__integer {
|
|
86
|
+
font-size: 17px;
|
|
87
|
+
font-weight: 500;
|
|
88
|
+
line-height: 24px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.doubao-price__decimal {
|
|
92
|
+
font-size: 14px;
|
|
93
|
+
font-weight: 500;
|
|
94
|
+
line-height: 11px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.doubao-price__suffix, .doubao-price__description, .doubao-price__original-price {
|
|
98
|
+
font-size: 13px;
|
|
99
|
+
font-weight: 400;
|
|
100
|
+
line-height: 11px;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.doubao-price__description, .doubao-price__original-price {
|
|
104
|
+
color: var(--neutral-70);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.doubao-price__original-price {
|
|
108
|
+
text-decoration: line-through;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.doubao-price__placeholder {
|
|
112
|
+
background-image: linear-gradient(90deg, #f7f7f7 0%, #e6e6e6 30%, #f7f7f7 100%);
|
|
113
|
+
background-size: 200% 100%;
|
|
114
|
+
border-radius: 4px;
|
|
115
|
+
width: 100%;
|
|
116
|
+
max-width: 60%;
|
|
117
|
+
height: 16px;
|
|
118
|
+
animation: 1.4s ease-in-out infinite doubao-price-placeholder-shimmer;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@keyframes doubao-price-placeholder-shimmer {
|
|
122
|
+
0% {
|
|
123
|
+
background-position: 100% 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
100% {
|
|
127
|
+
background-position: -100% 0;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CSSProperties } from '@lynx-js/types';
|
|
2
|
+
export type PriceValue = string | number;
|
|
3
|
+
export type PriceTone = 'default' | 'highlight';
|
|
4
|
+
export interface PriceProps {
|
|
5
|
+
/** 价格值。传入字符串时会保留前导零和末尾小数位。 */
|
|
6
|
+
value: PriceValue;
|
|
7
|
+
/** 币种符号。@defaultValue '¥' */
|
|
8
|
+
currency?: string;
|
|
9
|
+
/** 价格前缀,例如“均”“起”。 */
|
|
10
|
+
prefix?: string;
|
|
11
|
+
/** 价格后缀,例如“券后价”“/10斤”。 */
|
|
12
|
+
suffix?: string;
|
|
13
|
+
/** 价格后的辅助说明,例如“销量100+”。 */
|
|
14
|
+
description?: string;
|
|
15
|
+
/** 原价。传入后会在辅助信息区域以删除线展示。 */
|
|
16
|
+
originalPrice?: PriceValue;
|
|
17
|
+
/** 价格色调。highlight 对应营销强调色。@defaultValue 'default' */
|
|
18
|
+
tone?: PriceTone;
|
|
19
|
+
/** 是否展示价格占位骨架。@defaultValue false */
|
|
20
|
+
loading?: boolean;
|
|
21
|
+
/** 组件类名。 */
|
|
22
|
+
className?: string;
|
|
23
|
+
/** 组件样式。 */
|
|
24
|
+
style?: CSSProperties;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useThemeClassName } from "@byted-doubao-apps/components";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import "./styles.css";
|
|
4
|
+
function Tag({ text: text1, tone = 'authority', className, style }) {
|
|
5
|
+
const themedClassName = useThemeClassName(className);
|
|
6
|
+
return <view className={clsx('doubao-tag', `doubao-tag--tone-${tone}`, themedClassName)} style={style}>
|
|
7
|
+
<text className="doubao-tag__text">{text1}</text>
|
|
8
|
+
</view>;
|
|
9
|
+
}
|
|
10
|
+
export { Tag };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
.doubao-tag {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
border-radius: 4px;
|
|
4
|
+
flex-shrink: 0;
|
|
5
|
+
align-items: center;
|
|
6
|
+
height: 20px;
|
|
7
|
+
padding: 2px 3px;
|
|
8
|
+
display: flex;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.doubao-tag__text {
|
|
13
|
+
white-space: nowrap;
|
|
14
|
+
flex-shrink: 0;
|
|
15
|
+
font-family: PingFang SC, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, sans-serif;
|
|
16
|
+
font-size: 12px;
|
|
17
|
+
font-style: normal;
|
|
18
|
+
font-weight: 400;
|
|
19
|
+
line-height: 14px;
|
|
20
|
+
display: block;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.doubao-tag--tone-marketing {
|
|
24
|
+
background-color: #fff3ee;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.doubao-tag--tone-marketing .doubao-tag__text {
|
|
28
|
+
color: #ff375f;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.doubao-tag--tone-authority {
|
|
32
|
+
background-color: #fff8e7;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.doubao-tag--tone-authority .doubao-tag__text {
|
|
36
|
+
color: #814300;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.doubao-tag--tone-neutral {
|
|
40
|
+
background-color: #f7f7f7;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.doubao-tag--tone-neutral .doubao-tag__text {
|
|
44
|
+
color: #666;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.doubao-tag.doubao-theme-dark.doubao-tag--tone-marketing {
|
|
48
|
+
background-color: #3f2b27;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.doubao-tag.doubao-theme-dark.doubao-tag--tone-marketing .doubao-tag__text {
|
|
52
|
+
color: #ff5c7c;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.doubao-tag.doubao-theme-dark.doubao-tag--tone-authority {
|
|
56
|
+
background-color: #3a3324;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.doubao-tag.doubao-theme-dark.doubao-tag--tone-authority .doubao-tag__text {
|
|
60
|
+
color: #e2a45c;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.doubao-tag.doubao-theme-dark.doubao-tag--tone-neutral {
|
|
64
|
+
background-color: #252525;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.doubao-tag.doubao-theme-dark.doubao-tag--tone-neutral .doubao-tag__text {
|
|
68
|
+
color: #bababa;
|
|
69
|
+
}
|
|
70
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CSSProperties } from '@lynx-js/types';
|
|
2
|
+
export type TagValue = string | number;
|
|
3
|
+
export type TagTone = 'marketing' | 'authority' | 'neutral';
|
|
4
|
+
export interface TagProps {
|
|
5
|
+
/** 标签内容。 */
|
|
6
|
+
text: TagValue;
|
|
7
|
+
/** 标签色调。@defaultValue 'authority' */
|
|
8
|
+
tone?: TagTone;
|
|
9
|
+
/** 组件类名。 */
|
|
10
|
+
className?: string;
|
|
11
|
+
/** 组件样式。 */
|
|
12
|
+
style?: CSSProperties;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=types.d.ts.map
|
|
File without changes
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TitleProps } from './types.js';
|
|
2
|
+
import './styles.scss';
|
|
3
|
+
export type { TitleMaxLines, TitleProps, TitleValue } from './types.js';
|
|
4
|
+
export declare function Title({ text, maxLines, showArrow, loading, className, style }: TitleProps): any;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|