@yorkjs/hive-ui 0.0.6 → 0.0.8
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/package.json +1 -1
- package/src/components/Checkbox/index.tsx +3 -2
- package/src/components/FieldCard/index.module.styl +60 -0
- package/src/components/FieldCard/index.tsx +83 -0
- package/src/components/Tag/index.tsx +2 -1
- package/src/config.ts +26 -0
- package/src/index.ts +3 -1
- package/src/item/{ProductCard/index.tsx → ProductItem/ProductItem.tsx} +29 -28
- package/src/item/ProductItem/config.ts +35 -0
- package/src/item/ProductItem/index.tsx +8 -0
- /package/src/item/{ProductCard → ProductItem}/index.module.styl +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useMemo } from 'react'
|
|
2
2
|
import { View, Text } from '@tarojs/components'
|
|
3
3
|
|
|
4
|
+
import { useTheme } from '../../config'
|
|
4
5
|
import { isAndroid, isApp } from '../../util/env'
|
|
5
6
|
import { formatClassNames } from '../../util/function'
|
|
6
7
|
|
|
@@ -18,8 +19,6 @@ export interface CheckboxProps {
|
|
|
18
19
|
className?: string
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
const isDark = false
|
|
22
|
-
|
|
23
22
|
const Checkbox: React.FC<CheckboxProps> = (props) => {
|
|
24
23
|
const {
|
|
25
24
|
label,
|
|
@@ -31,6 +30,8 @@ const Checkbox: React.FC<CheckboxProps> = (props) => {
|
|
|
31
30
|
className,
|
|
32
31
|
} = props
|
|
33
32
|
|
|
33
|
+
const { isDark } = useTheme()
|
|
34
|
+
|
|
34
35
|
const handlePress = (e: any) => {
|
|
35
36
|
if (disabled || readOnly) return
|
|
36
37
|
onChange?.(!checked)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
@import '../../styles/mixin.styl'
|
|
2
|
+
|
|
3
|
+
$CELL_PADDING_HORIZONTAL = 16PX
|
|
4
|
+
$CELL_PADDING_VERTICAL = 14PX
|
|
5
|
+
$TITLE_FONT_SIZE = 16PX
|
|
6
|
+
|
|
7
|
+
.field-card-container
|
|
8
|
+
border-radius 10PX
|
|
9
|
+
background-color var(--containerCard)
|
|
10
|
+
margin 0 12PX
|
|
11
|
+
margin-bottom 12PX
|
|
12
|
+
overflow visible
|
|
13
|
+
|
|
14
|
+
.card-header
|
|
15
|
+
display flex
|
|
16
|
+
flex-direction row
|
|
17
|
+
align-items center
|
|
18
|
+
justify-content space-between
|
|
19
|
+
padding $CELL_PADDING_VERTICAL $CELL_PADDING_HORIZONTAL
|
|
20
|
+
position relative
|
|
21
|
+
min-height 48PX
|
|
22
|
+
box-sizing border-box
|
|
23
|
+
halfBorder(bottom, var(--lineBorder))
|
|
24
|
+
|
|
25
|
+
.header-left
|
|
26
|
+
flex 1
|
|
27
|
+
display flex
|
|
28
|
+
flex-direction row
|
|
29
|
+
align-items center
|
|
30
|
+
min-width 0
|
|
31
|
+
|
|
32
|
+
.header-title
|
|
33
|
+
color var(--textTitle)
|
|
34
|
+
font-size $TITLE_FONT_SIZE
|
|
35
|
+
font-weight 500
|
|
36
|
+
line-height 1.4
|
|
37
|
+
lineClamp(1)
|
|
38
|
+
|
|
39
|
+
.edit-icon
|
|
40
|
+
margin-left 6PX
|
|
41
|
+
color var(--textMuted)
|
|
42
|
+
flex-shrink 0
|
|
43
|
+
|
|
44
|
+
.header-extra
|
|
45
|
+
margin-left 12PX
|
|
46
|
+
flex-shrink 0
|
|
47
|
+
display flex
|
|
48
|
+
align-items center
|
|
49
|
+
// 动作区域通常字号稍小
|
|
50
|
+
font-size 14PX
|
|
51
|
+
|
|
52
|
+
.action-text
|
|
53
|
+
color #FF4D4F
|
|
54
|
+
|
|
55
|
+
.action-link
|
|
56
|
+
color var(--primary)
|
|
57
|
+
|
|
58
|
+
.card-content
|
|
59
|
+
border-radius 0 0 10PX 10PX
|
|
60
|
+
overflow hidden
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { View, Text, ITouchEvent } from '@tarojs/components'
|
|
3
|
+
|
|
4
|
+
import { formatClassNames } from '../../util/function'
|
|
5
|
+
import Icon from '../Icon'
|
|
6
|
+
|
|
7
|
+
import styles from './index.module.styl'
|
|
8
|
+
|
|
9
|
+
export interface FieldCardProps {
|
|
10
|
+
/** 标题内容 */
|
|
11
|
+
title: string
|
|
12
|
+
/** 是否显示标题旁的编辑小图标 */
|
|
13
|
+
showEditIcon?: boolean
|
|
14
|
+
/** 右侧动作区域:支持字符串、Icon 或自定义节点 */
|
|
15
|
+
extra?: React.ReactNode
|
|
16
|
+
/** 点击整个 Header 区域的回调 */
|
|
17
|
+
onHeaderClick?: (e: ITouchEvent) => void
|
|
18
|
+
/** 点击右侧 extra 区域的回调 (如果传了 extra 且需要独立点击) */
|
|
19
|
+
onExtraClick?: (e: ITouchEvent) => void
|
|
20
|
+
/** 子组件 */
|
|
21
|
+
children?: React.ReactNode
|
|
22
|
+
/** 外部样式 */
|
|
23
|
+
className?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const FieldCard: React.FC<FieldCardProps> = (props) => {
|
|
27
|
+
const {
|
|
28
|
+
title,
|
|
29
|
+
showEditIcon = false,
|
|
30
|
+
extra,
|
|
31
|
+
onHeaderClick,
|
|
32
|
+
onExtraClick,
|
|
33
|
+
children,
|
|
34
|
+
className
|
|
35
|
+
} = props
|
|
36
|
+
|
|
37
|
+
const handleExtraClick = (e: ITouchEvent) => {
|
|
38
|
+
if (onExtraClick) {
|
|
39
|
+
e.stopPropagation()
|
|
40
|
+
onExtraClick(e)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<View className={formatClassNames(styles['field-card-container'], className)}>
|
|
46
|
+
<View className={styles['card-header']} onClick={onHeaderClick}>
|
|
47
|
+
<View className={styles['header-left']}>
|
|
48
|
+
<Text className={styles['header-title']}>{title}</Text>
|
|
49
|
+
{
|
|
50
|
+
showEditIcon
|
|
51
|
+
? (
|
|
52
|
+
<Icon name='edit' size={14} className={styles['edit-icon']} />
|
|
53
|
+
)
|
|
54
|
+
: undefined
|
|
55
|
+
}
|
|
56
|
+
</View>
|
|
57
|
+
|
|
58
|
+
{extra && (
|
|
59
|
+
<View
|
|
60
|
+
className={styles['header-extra']}
|
|
61
|
+
onClick={handleExtraClick}
|
|
62
|
+
>
|
|
63
|
+
{
|
|
64
|
+
typeof extra === 'string'
|
|
65
|
+
? (
|
|
66
|
+
<Text className={styles['action-text']}>{extra}</Text>
|
|
67
|
+
)
|
|
68
|
+
: (
|
|
69
|
+
extra
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
</View>
|
|
73
|
+
)}
|
|
74
|
+
</View>
|
|
75
|
+
|
|
76
|
+
<View className={styles['card-content']}>
|
|
77
|
+
{children}
|
|
78
|
+
</View>
|
|
79
|
+
</View>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default FieldCard
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useMemo } from 'react'
|
|
2
2
|
import { View, Text } from '@tarojs/components'
|
|
3
3
|
|
|
4
|
+
import { useTheme } from '../../config'
|
|
4
5
|
import { formatClassNames } from '../../util/function'
|
|
5
6
|
|
|
6
7
|
import styles from './index.module.styl'
|
|
@@ -30,7 +31,7 @@ const Tag: React.FC<TagProps> = ({
|
|
|
30
31
|
className,
|
|
31
32
|
style
|
|
32
33
|
}) => {
|
|
33
|
-
const themeSelect = (
|
|
34
|
+
const { themeSelect } = useTheme()
|
|
34
35
|
|
|
35
36
|
const tagStyle = useMemo(() => {
|
|
36
37
|
const colors = {
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react'
|
|
2
|
+
|
|
3
|
+
let globalIsDark = false
|
|
4
|
+
const listeners = new Set<(isDark: boolean) => void>()
|
|
5
|
+
|
|
6
|
+
export const setGlobalTheme = (theme: 'light' | 'dark' | string) => {
|
|
7
|
+
globalIsDark = theme === 'dark'
|
|
8
|
+
listeners.forEach((callback) => callback(globalIsDark))
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const useTheme = () => {
|
|
12
|
+
const [isDark, setIsDark] = useState(globalIsDark)
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
listeners.add(setIsDark)
|
|
16
|
+
return () => {
|
|
17
|
+
listeners.delete(setIsDark)
|
|
18
|
+
}
|
|
19
|
+
}, [])
|
|
20
|
+
|
|
21
|
+
const themeSelect = <T>(lightValue: T, darkValue: T): T => {
|
|
22
|
+
return isDark ? darkValue : lightValue
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return { isDark, themeSelect }
|
|
26
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { setGlobalTheme, useTheme } from './config'
|
|
2
|
+
|
|
1
3
|
export { default as NumberKeyboard } from './components/NumberKeyboard'
|
|
2
4
|
export { default as Cell, setCellConfig } from './components/Cell'
|
|
3
5
|
export { default as Icon } from './components/Icon'
|
|
@@ -5,4 +7,4 @@ export { default as Checkbox } from './components/Checkbox'
|
|
|
5
7
|
export { default as Tag } from './components/Tag'
|
|
6
8
|
|
|
7
9
|
export { default as FlowItem } from './item/FlowItem'
|
|
8
|
-
export { default as
|
|
10
|
+
export { default as ProductItem, setProductItemConfig } from './item/ProductItem'
|
|
@@ -7,8 +7,6 @@ import Tag from '../../components/Tag'
|
|
|
7
7
|
import Icon from '../../components/Icon'
|
|
8
8
|
import Checkbox from '../../components/Checkbox'
|
|
9
9
|
|
|
10
|
-
import styles from './index.module.styl'
|
|
11
|
-
|
|
12
10
|
import {
|
|
13
11
|
MALL_PRODUCT_TYPE_REAL,
|
|
14
12
|
MALL_PRODUCT_TYPE_VIRTUAL,
|
|
@@ -22,6 +20,9 @@ import {
|
|
|
22
20
|
PROMOTION_ACTIVITY_TYPE_HOT,
|
|
23
21
|
PROMOTION_ACTIVITY_TYPE_PRESENT,
|
|
24
22
|
} from '../../constant/mall'
|
|
23
|
+
import { getProductItemConfig } from './config'
|
|
24
|
+
|
|
25
|
+
import styles from './index.module.styl'
|
|
25
26
|
|
|
26
27
|
export interface IProductCardLabels {
|
|
27
28
|
product_type?: { real: string; virtual: string; service: string }
|
|
@@ -73,6 +74,10 @@ export interface IProductCardProps {
|
|
|
73
74
|
customization?: string
|
|
74
75
|
/** 做法描述最大显示行数 (默认3) */
|
|
75
76
|
customizationMaxLines?: number
|
|
77
|
+
/** 套餐信息描述 */
|
|
78
|
+
combo? : string
|
|
79
|
+
/** 套餐描述最大显示行数 (默认3) */
|
|
80
|
+
comboMaxLines?: number
|
|
76
81
|
/** 售价 */
|
|
77
82
|
salePrice: string | number
|
|
78
83
|
/** 原价 (划线价) */
|
|
@@ -93,8 +98,6 @@ export interface IProductCardProps {
|
|
|
93
98
|
onDelete?: () => void
|
|
94
99
|
/** 右下角自定义操作区域 (与 buyCount 互斥) */
|
|
95
100
|
action?: React.ReactNode
|
|
96
|
-
/** 国际化标签注入 */
|
|
97
|
-
labels?: IProductCardLabels
|
|
98
101
|
/** 是否显示底部分边框 */
|
|
99
102
|
showBottomBorder?: boolean
|
|
100
103
|
/** 是否显示底部分割线 */
|
|
@@ -104,21 +107,7 @@ export interface IProductCardProps {
|
|
|
104
107
|
children?: React.ReactNode
|
|
105
108
|
}
|
|
106
109
|
|
|
107
|
-
const
|
|
108
|
-
product_type: { real: '实物', virtual: '虚拟', service: '服务' },
|
|
109
|
-
delivery_type: { dine: '堂食', self_pickup: '到店自取', delivery: '送货上门' },
|
|
110
|
-
activity_type: { flash: '秒杀活动', brand: '品牌活动', hot: '热点活动', present: '买赠活动' },
|
|
111
|
-
present_badge: '赠',
|
|
112
|
-
stock_label: '库存',
|
|
113
|
-
sale_label: '销量',
|
|
114
|
-
multiple_spec: '多规格',
|
|
115
|
-
barcode_label: '条码',
|
|
116
|
-
spec_label: '规格',
|
|
117
|
-
sold_out: '售罄',
|
|
118
|
-
offline: '已下架'
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const ProductCard: React.FC<IProductCardProps> = (props) => {
|
|
110
|
+
const ProductItem: React.FC<IProductCardProps> = (props) => {
|
|
122
111
|
const {
|
|
123
112
|
image,
|
|
124
113
|
title,
|
|
@@ -134,6 +123,8 @@ const ProductCard: React.FC<IProductCardProps> = (props) => {
|
|
|
134
123
|
deliveryTypes = [],
|
|
135
124
|
customization,
|
|
136
125
|
customizationMaxLines = 3,
|
|
126
|
+
combo,
|
|
127
|
+
comboMaxLines = 3,
|
|
137
128
|
salePrice,
|
|
138
129
|
originalPrice,
|
|
139
130
|
buyCount,
|
|
@@ -149,7 +140,6 @@ const ProductCard: React.FC<IProductCardProps> = (props) => {
|
|
|
149
140
|
className,
|
|
150
141
|
showBottomBorder = false,
|
|
151
142
|
showSeparator = false,
|
|
152
|
-
labels: customLabels,
|
|
153
143
|
onClick,
|
|
154
144
|
children
|
|
155
145
|
} = props
|
|
@@ -165,13 +155,12 @@ const ProductCard: React.FC<IProductCardProps> = (props) => {
|
|
|
165
155
|
}
|
|
166
156
|
}
|
|
167
157
|
|
|
168
|
-
const labels = useMemo(() =>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}), [customLabels])
|
|
158
|
+
const labels = useMemo(() => {
|
|
159
|
+
const globalConfig = getProductItemConfig()
|
|
160
|
+
return {
|
|
161
|
+
...globalConfig,
|
|
162
|
+
}
|
|
163
|
+
}, [])
|
|
175
164
|
|
|
176
165
|
const productTypeTag = useMemo(() => {
|
|
177
166
|
if (productType === undefined) return null
|
|
@@ -359,6 +348,18 @@ const ProductCard: React.FC<IProductCardProps> = (props) => {
|
|
|
359
348
|
)
|
|
360
349
|
: undefined
|
|
361
350
|
}
|
|
351
|
+
{
|
|
352
|
+
combo
|
|
353
|
+
? (
|
|
354
|
+
<Text
|
|
355
|
+
className={styles['customization-text']}
|
|
356
|
+
style={{ WebkitLineClamp: comboMaxLines }}
|
|
357
|
+
>
|
|
358
|
+
{combo}
|
|
359
|
+
</Text>
|
|
360
|
+
)
|
|
361
|
+
: undefined
|
|
362
|
+
}
|
|
362
363
|
</View>
|
|
363
364
|
<View className={styles['content-bottom']}>
|
|
364
365
|
<View className={styles['price-container']}>
|
|
@@ -432,4 +433,4 @@ const ProductCard: React.FC<IProductCardProps> = (props) => {
|
|
|
432
433
|
)
|
|
433
434
|
}
|
|
434
435
|
|
|
435
|
-
export default React.memo(
|
|
436
|
+
export default React.memo(ProductItem)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { IProductCardLabels } from './ProductItem'
|
|
2
|
+
|
|
3
|
+
// 初始默认文案
|
|
4
|
+
let globalLabels: IProductCardLabels = {
|
|
5
|
+
product_type: {
|
|
6
|
+
real: '实物',
|
|
7
|
+
virtual: '虚拟',
|
|
8
|
+
service: '服务'
|
|
9
|
+
},
|
|
10
|
+
delivery_type: {
|
|
11
|
+
dine: '堂食',
|
|
12
|
+
self_pickup: '到店自取',
|
|
13
|
+
delivery: '送货上门'
|
|
14
|
+
},
|
|
15
|
+
activity_type: {
|
|
16
|
+
flash: '秒杀活动',
|
|
17
|
+
brand: '品牌活动',
|
|
18
|
+
hot: '热点活动',
|
|
19
|
+
present: '买赠活动'
|
|
20
|
+
},
|
|
21
|
+
present_badge: '赠',
|
|
22
|
+
stock_label: '库存',
|
|
23
|
+
sale_label: '销量',
|
|
24
|
+
multiple_spec: '多规格',
|
|
25
|
+
barcode_label: '条码',
|
|
26
|
+
spec_label: '规格',
|
|
27
|
+
sold_out: '售罄',
|
|
28
|
+
offline: '已下架'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const setProductItemConfig = (labels: IProductCardLabels) => {
|
|
32
|
+
globalLabels = { ...globalLabels, ...labels }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const getProductItemConfig = () => globalLabels
|
|
File without changes
|