@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yorkjs/hive-ui",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Hive UI - Taro React component library",
5
5
  "main": "src/index.ts",
6
6
  "module": "src/index.ts",
@@ -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 = (light: string, dark: string) => (isDark ? dark : light)
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 ProductCard } from './item/ProductCard'
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 DEFAULT_LABELS: IProductCardLabels = {
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
- ...DEFAULT_LABELS,
170
- ...customLabels,
171
- product_type: { ...DEFAULT_LABELS.product_type, ...customLabels?.product_type },
172
- delivery_type: { ...DEFAULT_LABELS.delivery_type, ...customLabels?.delivery_type },
173
- activity_type: { ...DEFAULT_LABELS.activity_type, ...customLabels?.activity_type }
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(ProductCard)
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
@@ -0,0 +1,8 @@
1
+ import ProductItemMain from './ProductItem'
2
+ import { setProductItemConfig } from './config'
3
+
4
+ export type { IProductCardLabels, IProductCardProps } from './ProductItem'
5
+
6
+ export { setProductItemConfig }
7
+
8
+ export default ProductItemMain