@ledvance/base 1.2.76 → 1.2.78

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
@@ -4,7 +4,7 @@
4
4
  "name": "@ledvance/base",
5
5
  "pid": [],
6
6
  "uiid": "",
7
- "version": "1.2.76",
7
+ "version": "1.2.78",
8
8
  "scripts": {
9
9
  "prepublishOnly": "python update-localazy.py"
10
10
  },
@@ -27,8 +27,8 @@ interface GroupFeatureEvent {
27
27
  }
28
28
 
29
29
  interface GroupDpEvent {
30
- tyGroupId?: number
31
- dps?: any
30
+ tyGroupId: number
31
+ dps: any
32
32
  }
33
33
 
34
34
  interface DeviceEvent {
@@ -5,6 +5,7 @@ import Card from 'components/Card'
5
5
  import Spacer from 'components/Spacer'
6
6
 
7
7
  const { convertX: cx } = Utils.RatioUtils
8
+ const { withTheme } = Utils.ThemeUtils
8
9
 
9
10
  export interface AdvancedData {
10
11
  title: string
@@ -37,6 +38,7 @@ export function getAdvancedStatusColor(status: AdvancedStatus): string {
37
38
  }
38
39
 
39
40
  export interface AdvanceCardProps extends PropsWithChildren<ViewProps> {
41
+ theme?: any
40
42
  data: AdvancedData
41
43
  onPress: () => void
42
44
  }
@@ -49,21 +51,21 @@ const AdvanceCard = (props: AdvanceCardProps) => {
49
51
  containerStyle={styles.itemContent}
50
52
  onPress={props.onPress}>
51
53
  {!!statusColor && <View style={styles.dotBg}>
52
- <View
53
- style={[
54
- styles.dot,
55
- {backgroundColor: props.data.statusColor},
56
- ]}/>
54
+ <View
55
+ style={[
56
+ styles.dot,
57
+ {backgroundColor: props.data.statusColor},
58
+ ]}/>
57
59
  </View>}
58
60
  {
59
61
  props.children ?
60
62
  props.children :
61
63
  <View style={styles.titleBg}>
62
- <Text style={styles.title}>{props.data.title}</Text>
64
+ <Text style={{...styles.title, color: props.theme.global.fontColor}}>{props.data.title}</Text>
63
65
  <Spacer height={cx(8)} />
64
66
  {
65
67
  (!!props.data.subtitles) && props.data.subtitles.map((subtitle, index) => (
66
- <Text style={styles.subtitle} key={`${subtitle}_${index}`}>{subtitle}</Text>
68
+ <Text style={{...styles.subtitle, color: props.theme.global.secondFontColor}} key={`${subtitle}_${index}`}>{subtitle}</Text>
67
69
  ))
68
70
  }
69
71
  </View>
@@ -85,13 +87,11 @@ const styles = StyleSheet.create({
85
87
  },
86
88
  title: {
87
89
  marginHorizontal: cx(16),
88
- color: '#000',
89
90
  fontSize: cx(14),
90
91
  textAlign: 'center',
91
92
  fontFamily: 'helvetica_neue_lt_std_roman',
92
93
  },
93
94
  subtitle: {
94
- color: '#666',
95
95
  fontSize: cx(10),
96
96
  textAlign: 'center',
97
97
  fontFamily: 'helvetica_neue_lt_std_roman',
@@ -114,4 +114,4 @@ const styles = StyleSheet.create({
114
114
  },
115
115
  })
116
116
 
117
- export default AdvanceCard
117
+ export default withTheme(AdvanceCard)
@@ -3,23 +3,25 @@ import React, {PropsWithChildren} from 'react'
3
3
  import {Utils} from 'tuya-panel-kit'
4
4
 
5
5
  const cx = Utils.RatioUtils.convertX
6
+ const { withTheme } = Utils.ThemeUtils
6
7
 
7
8
  interface CardProps extends PropsWithChildren<ViewProps> {
9
+ theme?: any
8
10
  shadowHeight?: number | undefined
9
11
  onPress?: () => void
10
12
  onLongPress?: () => void
11
13
  containerStyle?: StyleProp<ViewStyle>
12
14
  }
13
15
 
14
- export default function Card(props: CardProps) {
16
+ const Card = (props: CardProps) => {
15
17
  const shadowHeight = props.shadowHeight || cx(7)
16
18
  return (
17
19
  <View
18
20
  style={[{
19
21
  overflow: Platform.OS === 'ios' ? undefined : 'hidden',
20
- backgroundColor: 'white',
22
+ backgroundColor: props.theme.card.background,
21
23
  elevation: shadowHeight,
22
- shadowColor: '#000000',
24
+ shadowColor: props.theme.card.shadowColor,
23
25
  shadowOpacity: 0.2,
24
26
  shadowRadius: shadowHeight,
25
27
  shadowOffset: {
@@ -33,4 +35,6 @@ export default function Card(props: CardProps) {
33
35
  </TouchableOpacity>
34
36
  </View>
35
37
  )
36
- }
38
+ }
39
+
40
+ export default withTheme(Card)
@@ -3,8 +3,10 @@ import { StyleProp, Text, TextStyle, TouchableOpacity, ViewStyle } from 'react-n
3
3
  import { Utils } from 'tuya-panel-kit'
4
4
 
5
5
  const cx = Utils.RatioUtils.convertX
6
+ const { withTheme } = Utils.ThemeUtils
6
7
 
7
8
  interface DeleteButtonProps {
9
+ theme?: any
8
10
  text: string,
9
11
  onPress: () => void,
10
12
  style?: StyleProp<ViewStyle>,
@@ -21,13 +23,13 @@ const DeleteButton = (props: DeleteButtonProps) => {
21
23
  style={[{
22
24
  width: '100%',
23
25
  height: cx(50),
24
- backgroundColor: '#666',
26
+ backgroundColor: props.theme.button.disabled,
25
27
  alignItems: 'center',
26
28
  justifyContent: 'center',
27
29
  borderRadius: cx(8),
28
30
  }, style]}>
29
31
  <Text style={[{
30
- color: '#fff',
32
+ color: props.theme.button.fontColor,
31
33
  fontSize: cx(16),
32
34
  fontFamily: 'helvetica_neue_lt_std_bd',
33
35
  }, textStyle]}>{text}</Text>
@@ -35,4 +37,4 @@ const DeleteButton = (props: DeleteButtonProps) => {
35
37
  )
36
38
  }
37
39
 
38
- export default DeleteButton
40
+ export default withTheme(DeleteButton)
@@ -2,11 +2,14 @@ import React, { PropsWithChildren, useCallback, useEffect } from 'react'
2
2
  import { BackHandler, View, ViewProps } from 'react-native'
3
3
  import LDVTopBar from './ldvTopBar'
4
4
  import { useNavigation } from '@react-navigation/native'
5
- import { Dialog, Toast } from 'tuya-panel-kit'
5
+ import {Dialog, Toast, Utils} from 'tuya-panel-kit'
6
6
  import I18n from '@i18n'
7
7
  import LdvTopName from './ldvTopName'
8
8
 
9
+ const { withTheme } = Utils.ThemeUtils
10
+
9
11
  interface PageProps extends PropsWithChildren<ViewProps> {
12
+ theme?: any
10
13
  rightButtonDisabled?: boolean
11
14
  backText: string
12
15
  onBackClick?: () => void
@@ -19,6 +22,7 @@ interface PageProps extends PropsWithChildren<ViewProps> {
19
22
  headlineText?: string
20
23
  headlineIcon?: string | number
21
24
  onHeadlineIconClick?: () => void
25
+ headlineContent?: React.ReactNode
22
26
  showGreenery?: boolean
23
27
  greeneryIcon?: string | undefined | number
24
28
  loading?: boolean
@@ -63,7 +67,7 @@ const Page = (props: PageProps) => {
63
67
 
64
68
  return (
65
69
  <>
66
- <View style={[{ flex: 1, position: 'relative' }, props.style]}>
70
+ <View style={[{ flex: 1, position: 'relative', backgroundColor: props.theme.global.backgroud }, props.style]}>
67
71
  <LDVTopBar
68
72
  title={props.backText}
69
73
  onBackPress={
@@ -82,7 +86,9 @@ const Page = (props: PageProps) => {
82
86
  rightIcon={props.headlineIcon}
83
87
  rightIconClick={props.onHeadlineIconClick}
84
88
  showGreenery={props.showGreenery}
85
- greeneryIcon={props.greeneryIcon}/>}
89
+ greeneryIcon={props.greeneryIcon}
90
+ headlineContent={props.headlineContent}
91
+ />}
86
92
  {props.children}
87
93
  </View>
88
94
  {!!props.loading && <Toast.Loading
@@ -95,4 +101,4 @@ const Page = (props: PageProps) => {
95
101
  )
96
102
  }
97
103
 
98
- export default Page
104
+ export default withTheme(Page)
@@ -4,17 +4,65 @@ import {Utils} from 'tuya-panel-kit'
4
4
  import res from '../res'
5
5
 
6
6
  const cx = Utils.RatioUtils.convertX
7
+ const { withTheme } = Utils.ThemeUtils
7
8
 
8
9
  interface TextFieldProps extends TextInputProps {
9
- showError?: boolean
10
- errorText?: string
11
- tipIcon?: ImageSourcePropType
12
- tipColor?: string
10
+ theme?: any
11
+ showError?: boolean
12
+ errorText?: string
13
+ tipIcon?: ImageSourcePropType
14
+ tipColor?: string
13
15
  }
14
16
 
15
17
  const TextField = (props: TextFieldProps) => {
16
18
  const icon = props.tipIcon || res.ic_warning_amber
17
- const color = props.tipColor || '#FF9500'
19
+ const color = props.tipColor || props.theme.global.warning
20
+
21
+ const styles = StyleSheet.create({
22
+ topTip: {
23
+ marginTop: cx(5),
24
+ fontSize: cx(12),
25
+ marginStart: cx(13),
26
+ color: props.theme.global.secondFontColor,
27
+ fontFamily: 'helvetica_neue_lt_std_bd',
28
+ },
29
+ textInputGroup: {
30
+ flexDirection: 'row',
31
+ borderRadius: cx(4),
32
+ backgroundColor: props.theme.textInput.background,
33
+ alignItems: 'center',
34
+ },
35
+ textInput: {
36
+ flex: 1,
37
+ height: cx(44),
38
+ marginStart: cx(16),
39
+ marginEnd: cx(6),
40
+ fontSize: cx(16),
41
+ color: props.theme.textInput.fontColor,
42
+ fontFamily: 'helvetica_neue_lt_std_roman',
43
+ },
44
+ iconTouchable: {
45
+ marginEnd: cx(18),
46
+ padding: cx(4),
47
+ },
48
+ icon: {
49
+ width: cx(16),
50
+ height: cx(16),
51
+ },
52
+ line: {
53
+ height: 1,
54
+ position: 'absolute',
55
+ start: cx(4),
56
+ end: cx(4),
57
+ bottom: 0,
58
+ backgroundColor: props.theme.textInput.line,
59
+ },
60
+ errorContainer: {
61
+ flexDirection: 'row',
62
+ alignItems: 'center',
63
+ marginStart: cx(13),
64
+ },
65
+ })
18
66
  return (
19
67
  <View style={props.style}>
20
68
  <Text style={[styles.topTip, { opacity: (!!props.value) ? 1 : 0 }]}>{props.placeholder}</Text>
@@ -41,50 +89,4 @@ const TextField = (props: TextFieldProps) => {
41
89
  )
42
90
  }
43
91
 
44
- const styles = StyleSheet.create({
45
- topTip: {
46
- marginTop: cx(5),
47
- fontSize: cx(12),
48
- marginStart: cx(13),
49
- color: '#666',
50
- fontFamily: 'helvetica_neue_lt_std_bd',
51
- },
52
- textInputGroup: {
53
- flexDirection: 'row',
54
- borderRadius: cx(4),
55
- backgroundColor: '#f6f6f6',
56
- alignItems: 'center',
57
- },
58
- textInput: {
59
- flex: 1,
60
- height: cx(44),
61
- marginStart: cx(16),
62
- marginEnd: cx(6),
63
- fontSize: cx(16),
64
- color: '#000',
65
- fontFamily: 'helvetica_neue_lt_std_roman',
66
- },
67
- iconTouchable: {
68
- marginEnd: cx(18),
69
- padding: cx(4),
70
- },
71
- icon: {
72
- width: cx(16),
73
- height: cx(16),
74
- },
75
- line: {
76
- height: 1,
77
- position: 'absolute',
78
- start: cx(4),
79
- end: cx(4),
80
- bottom: 0,
81
- backgroundColor: '#cbcbcb',
82
- },
83
- errorContainer: {
84
- flexDirection: 'row',
85
- alignItems: 'center',
86
- marginStart: cx(13),
87
- },
88
- })
89
-
90
- export default TextField
92
+ export default withTheme(TextField)
@@ -4,8 +4,10 @@ import React from 'react'
4
4
  import res from "../res/index";
5
5
 
6
6
  const cx = Utils.RatioUtils.convertX
7
+ const { withTheme } = Utils.ThemeUtils
7
8
 
8
9
  interface TextFieldStyleButtonProps extends ViewProps {
10
+ theme?: any
9
11
  placeholder: string
10
12
  text: string
11
13
  onPress: () => void,
@@ -14,69 +16,70 @@ interface TextFieldStyleButtonProps extends ViewProps {
14
16
  }
15
17
 
16
18
  const TextFieldStyleButton = (props: TextFieldStyleButtonProps) => {
19
+ const styles = StyleSheet.create({
20
+ topTip: {
21
+ marginTop: cx(5),
22
+ fontSize: cx(12),
23
+ marginStart: cx(13),
24
+ color: props.theme.global.secondFontColor,
25
+ fontFamily: 'helvetica_neue_lt_std_bd',
26
+ },
27
+ textGroup: {
28
+ flexDirection: 'row',
29
+ borderRadius: cx(4),
30
+ backgroundColor: props.theme.textInput.background,
31
+ alignItems: 'center',
32
+ },
33
+ textParent: {
34
+ flex: 1,
35
+ height: cx(44),
36
+ justifyContent: 'center',
37
+ },
38
+ text: {
39
+ marginStart: cx(16),
40
+ marginEnd: cx(6),
41
+ fontSize: cx(16),
42
+ color: props.theme.textInput.fontColor,
43
+ fontFamily: 'helvetica_neue_lt_std_roman',
44
+ },
45
+ line: {
46
+ height: 1,
47
+ position: 'absolute',
48
+ start: cx(4),
49
+ end: cx(4),
50
+ bottom: 0,
51
+ backgroundColor: props.theme.textInput.line,
52
+ },
53
+ tipParent: {
54
+ flexDirection: 'row',
55
+ alignItems: 'center',
56
+ },
57
+ tipIcon: {
58
+ width: cx(16),
59
+ height: cx(16),
60
+ marginStart: cx(4),
61
+ }
62
+ })
63
+
17
64
  return (
18
- <View style={props.style}>
19
- <View style={styles.tipParent}>
20
- <Text style={styles.topTip}>{props.placeholder}</Text>
21
- {props.showTipIcon && <TouchableOpacity onPress={props.onTipIconPress}>
22
- <Image source={res.ic_info} style={styles.tipIcon}/>
23
- </TouchableOpacity>}
24
- </View>
25
- <TouchableOpacity onPress={props.onPress}>
26
- <View style={styles.textGroup}>
27
- <View style={styles.textParent}>
28
- <Text style={styles.text}>{props.text}</Text>
29
- </View>
30
- <View style={styles.line} />
31
- </View>
32
- </TouchableOpacity>
33
- </View>
65
+ <View style={props.style}>
66
+ <View style={styles.tipParent}>
67
+ <Text style={styles.topTip}>{props.placeholder}</Text>
68
+ {props.showTipIcon && <TouchableOpacity onPress={props.onTipIconPress}>
69
+ <Image source={res.ic_info} style={styles.tipIcon}/>
70
+ </TouchableOpacity>}
71
+ </View>
72
+ <TouchableOpacity onPress={props.onPress}>
73
+ <View style={styles.textGroup}>
74
+ <View style={styles.textParent}>
75
+ <Text style={styles.text}>{props.text}</Text>
76
+ </View>
77
+ <View style={styles.line} />
78
+ </View>
79
+ </TouchableOpacity>
80
+ </View>
34
81
  )
35
82
  }
36
83
 
37
- const styles = StyleSheet.create({
38
- topTip: {
39
- marginTop: cx(5),
40
- fontSize: cx(12),
41
- marginStart: cx(13),
42
- color: '#666',
43
- fontFamily: 'helvetica_neue_lt_std_bd',
44
- },
45
- textGroup: {
46
- flexDirection: 'row',
47
- borderRadius: cx(4),
48
- backgroundColor: '#f6f6f6',
49
- alignItems: 'center',
50
- },
51
- textParent: {
52
- flex: 1,
53
- height: cx(44),
54
- justifyContent: 'center',
55
- },
56
- text: {
57
- marginStart: cx(16),
58
- marginEnd: cx(6),
59
- fontSize: cx(16),
60
- color: '#000',
61
- fontFamily: 'helvetica_neue_lt_std_roman',
62
- },
63
- line: {
64
- height: 1,
65
- position: 'absolute',
66
- start: cx(4),
67
- end: cx(4),
68
- bottom: 0,
69
- backgroundColor: '#cbcbcb',
70
- },
71
- tipParent: {
72
- flexDirection: 'row',
73
- alignItems: 'center',
74
- },
75
- tipIcon: {
76
- width: cx(16),
77
- height: cx(16),
78
- marginStart: cx(4),
79
- }
80
- })
81
84
 
82
- export default TextFieldStyleButton
85
+ export default withTheme(TextFieldStyleButton)
@@ -4,12 +4,14 @@ import {Picker, Utils} from 'tuya-panel-kit'
4
4
  import _ from 'lodash'
5
5
 
6
6
  const {convertX} = Utils.RatioUtils
7
+ const { withTheme } = Utils.ThemeUtils
7
8
 
8
9
  const pickerTheme = {
9
10
  fontSize: 20,
10
11
  }
11
12
 
12
13
  interface LdvPickerViewProps {
14
+ theme?: any
13
15
  hour: string,
14
16
  minute: string,
15
17
  setHour: (string) => void,
@@ -25,6 +27,28 @@ const LdvPickerView = (props: LdvPickerViewProps) => {
25
27
  const {hour, minute, unit, setHour, setMinute, minutesStep = 1, maxHour = 24} = props
26
28
  const hours = useMemo(() => _.times(maxHour, (n) => _.padStart(n.toString(), 2, '0')), [])
27
29
  const minutes = useMemo(() => _.times(60 / minutesStep, (n) => _.padStart((n * minutesStep).toString(), 2, '0')) , [props.minutesStep])
30
+
31
+ const styles = StyleSheet.create({
32
+ pickerContainer: {
33
+ flexDirection: 'row',
34
+ alignItems: 'center',
35
+ },
36
+ picker: {
37
+ flex: 1,
38
+ backgroundColor: props.theme.card.background,
39
+ },
40
+ pickerLeft: {},
41
+ pickerItem: {},
42
+ picContainer: {
43
+ flex: 1,
44
+ position: 'relative',
45
+ },
46
+ pickerUnit: {
47
+ position: 'absolute',
48
+ right: convertX(20),
49
+ top: '44%',
50
+ },
51
+ })
28
52
  return (
29
53
  <View style={[styles.pickerContainer, props.style]}>
30
54
  <View style={styles.picContainer}>
@@ -42,7 +66,7 @@ const LdvPickerView = (props: LdvPickerViewProps) => {
42
66
  ))}
43
67
  </Picker>
44
68
  {unit ? <View style={styles.pickerUnit}>
45
- <Text style={{color: '#000', fontSize: convertX(18)}}>
69
+ <Text style={{color: props.theme.global.fontColor, fontSize: convertX(18)}}>
46
70
  {unit[0]}
47
71
  </Text>
48
72
  </View> : null}
@@ -61,7 +85,7 @@ const LdvPickerView = (props: LdvPickerViewProps) => {
61
85
  ))}
62
86
  </Picker>
63
87
  {unit ? <View style={styles.pickerUnit}>
64
- <Text style={{color: '#000', fontSize: convertX(18)}}>
88
+ <Text style={{color: props.theme.global.fontColor, fontSize: convertX(18)}}>
65
89
  {unit[1]}
66
90
  </Text>
67
91
  </View> : null}
@@ -70,25 +94,4 @@ const LdvPickerView = (props: LdvPickerViewProps) => {
70
94
  )
71
95
  }
72
96
 
73
- const styles = StyleSheet.create({
74
- pickerContainer: {
75
- flexDirection: 'row',
76
- alignItems: 'center',
77
- },
78
- picker: {
79
- flex: 1,
80
- },
81
- pickerLeft: {},
82
- pickerItem: {},
83
- picContainer: {
84
- flex: 1,
85
- position: 'relative',
86
- },
87
- pickerUnit: {
88
- position: 'absolute',
89
- right: convertX(20),
90
- top: '44%',
91
- },
92
- })
93
-
94
- export default LdvPickerView
97
+ export default withTheme(LdvPickerView)
@@ -4,8 +4,10 @@ import {SwitchButton, Utils} from 'tuya-panel-kit'
4
4
  import Spacer from './Spacer'
5
5
 
6
6
  const {convertX: cx} = Utils.RatioUtils
7
+ const { withTheme } = Utils.ThemeUtils
7
8
 
8
9
  interface Prop {
10
+ theme?: any
9
11
  title: string
10
12
  color: string
11
13
  colorAlpha: number
@@ -18,7 +20,7 @@ const LdvSwitch = (props: Prop) => {
18
20
  const {title, color, colorAlpha, enable, setEnable, showSwitch = true} = props
19
21
  return (
20
22
  <View style={styles.titleBGView}>
21
- <Text style={styles.title}>{title}</Text>
23
+ <Text style={{...styles.title, color: props.theme.global.fontColor}}>{title}</Text>
22
24
  <View style={[styles.colorBlock, {backgroundColor: color, opacity: colorAlpha}]}/>
23
25
  <Spacer style={{flex: 1}} height={0} width={0}/>
24
26
  {showSwitch && <SwitchButton value={enable} onValueChange={setEnable}/>}
@@ -39,7 +41,6 @@ const styles = StyleSheet.create({
39
41
  borderRadius: cx(4),
40
42
  },
41
43
  title: {
42
- color: '#000',
43
44
  fontSize: cx(16),
44
45
  // fontFamily: 'helvetica_neue_lt_std_bd',
45
46
  fontWeight: 'bold',
@@ -48,4 +49,4 @@ const styles = StyleSheet.create({
48
49
  },
49
50
  })
50
51
 
51
- export default LdvSwitch
52
+ export default withTheme(LdvSwitch)
@@ -5,8 +5,10 @@ import {IconFont, Utils} from 'tuya-panel-kit'
5
5
  const backIcon = Platform.OS === 'ios' ? 'backIos' : 'backAndroid'
6
6
 
7
7
  const cx = Utils.RatioUtils.convertX
8
+ const { withTheme } = Utils.ThemeUtils
8
9
 
9
10
  interface TopBarProps {
11
+ theme?: any
10
12
  title: string
11
13
  onBackPress: () => void
12
14
  rightButtonIcon?: any | {}
@@ -35,13 +37,13 @@ const LDVTopBar = (props: TopBarProps) => {
35
37
  alignItems: 'center',
36
38
  flex: 1,
37
39
  }}>
38
- <IconFont size={cx(16)} color={'#f60'} name={backIcon}/>
40
+ <IconFont size={cx(16)} color={props.theme.global.brand} name={backIcon}/>
39
41
  <View style={{width: cx(10)}}/>
40
42
  <Text
41
43
  numberOfLines={1}
42
44
  style={{
43
45
  maxWidth: cx(290),
44
- color: '#f60',
46
+ color: props.theme.global.brand,
45
47
  fontSize: cx(16),
46
48
  fontFamily: 'helvetica_neue_lt_std_roman',
47
49
  }}>{props.title}</Text>
@@ -71,4 +73,4 @@ const LDVTopBar = (props: TopBarProps) => {
71
73
  )
72
74
  }
73
75
 
74
- export default LDVTopBar
76
+ export default withTheme(LDVTopBar)
@@ -3,18 +3,32 @@ import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native'
3
3
  import {Utils} from 'tuya-panel-kit'
4
4
 
5
5
  const cx = Utils.RatioUtils.convertX
6
+ const { withTheme } = Utils.ThemeUtils
6
7
 
7
8
  interface LdvTopNameProps {
9
+ theme?: any
8
10
  title: string,
9
11
  rightIcon?: string | undefined | number,
10
12
  rightIconClick?: () => void
11
13
  showGreenery?: boolean
12
14
  greeneryIcon?: string | undefined | number
15
+ headlineContent?: React.ReactNode
13
16
  }
14
17
 
15
18
  const LdvTopName = (props: LdvTopNameProps) => {
16
19
  const rightIcon = typeof props.rightIcon === 'number' ? props.rightIcon : {uri: props.rightIcon}
17
20
  const greeneryIcon = typeof props.greeneryIcon === 'number' ? props.greeneryIcon : {uri: props.greeneryIcon}
21
+
22
+ const styles = StyleSheet.create({
23
+ container: {
24
+ marginHorizontal: cx(24),
25
+ marginBottom: cx(12),
26
+ },
27
+ title: {
28
+ color: props.theme.global.brand,
29
+ fontSize: cx(24),
30
+ },
31
+ })
18
32
  return (
19
33
  <View style={styles.container}>
20
34
  <View
@@ -37,23 +51,13 @@ const LdvTopName = (props: LdvTopNameProps) => {
37
51
  {props.rightIcon && <TouchableOpacity
38
52
  onPress={props.rightIconClick}>
39
53
  <Image
40
- style={{width: cx(24), height: cx(24), tintColor: '#ff6600'}}
54
+ style={{width: cx(24), height: cx(24), tintColor: props.theme.global.brand}}
41
55
  source={rightIcon}/>
42
56
  </TouchableOpacity>}
57
+ {props.headlineContent && props.headlineContent}
43
58
  </View>
44
59
  </View>
45
60
  )
46
61
  }
47
62
 
48
- const styles = StyleSheet.create({
49
- container: {
50
- marginHorizontal: cx(24),
51
- marginBottom: cx(12),
52
- },
53
- title: {
54
- color: '#f60',
55
- fontSize: cx(24),
56
- },
57
- })
58
-
59
- export default LdvTopName
63
+ export default withTheme(LdvTopName)
@@ -4,6 +4,7 @@ import {Utils} from 'tuya-panel-kit'
4
4
  import I18n from '../i18n/index'
5
5
 
6
6
  const cx = Utils.RatioUtils.convertX
7
+ const { withTheme } = Utils.ThemeUtils
7
8
 
8
9
  const repeatPeriod = [
9
10
  {
@@ -46,7 +47,7 @@ export const setDataSource = (loop) => {
46
47
  })
47
48
  }
48
49
 
49
- export default (props) => {
50
+ const WeekSelect = (props) => {
50
51
 
51
52
  const {value, onSelect, style} = props
52
53
  const dataSource = setDataSource(value)
@@ -74,15 +75,15 @@ export default (props) => {
74
75
  justifyContent: 'center',
75
76
  alignItems: 'center',
76
77
  borderRadius: cx(20),
77
- backgroundColor: period.enabled ? '#ffe0d4' : '#fff',
78
+ backgroundColor: period.enabled ? props.theme.global.thirdBrand : props.theme.global.background,
78
79
  borderWidth: cx(1),
79
80
  // borderColor: period.enabled ? "#fff" : 'rgba(120, 120, 128, 0.2)'
80
- borderColor: '#f60',
81
+ borderColor: props.theme.global.brand,
81
82
  }}>
82
83
 
83
84
  <Text
84
85
  style={{
85
- color: '#f60',
86
+ color: props.theme.global.brand,
86
87
  textAlign: 'center',
87
88
  }}>{period.title}</Text>
88
89
  </View>
@@ -92,4 +93,6 @@ export default (props) => {
92
93
  </View>
93
94
 
94
95
  </View>)
95
- }
96
+ }
97
+
98
+ export default withTheme(WeekSelect)
@@ -3,7 +3,7 @@ import React, { Component } from 'react'
3
3
  import { Provider } from 'react-redux'
4
4
  import { DevInfo, DpValue, Theme, TYSdk } from 'tuya-panel-kit'
5
5
  import { actions, store } from './models'
6
- import { addListener, removeListener } from 'api/nativeEventEmitter'
6
+ import {addListener, nativeEventEmitter, removeListener} from 'api/nativeEventEmitter'
7
7
  import {getSystemTimeFormat, getTimeZone, NativeApi} from 'api/native'
8
8
  import {
9
9
  DeviceInfo,
@@ -17,12 +17,15 @@ import {
17
17
  } from './models/modules/NativePropsSlice'
18
18
  import { DpSchema, GlobalParams } from './models/GlobalParams'
19
19
  import Connect from './components/connect'
20
+ import darkTheme from "./config/dark-theme";
21
+ import lightTheme from "./config/light-theme";
20
22
 
21
23
  interface Props {
22
24
  devInfo: DevInfo
23
25
  preload?: boolean
24
26
  ldvDevInfo: LdvDevInfo
25
27
  uaGroupInfo: UAGroupInfoProps
28
+ colorScheme?: string
26
29
  }
27
30
 
28
31
  interface LdvDevInfo extends DeviceInfo {
@@ -40,14 +43,6 @@ interface UAGroupInfoProps extends UAGroupInfo {
40
43
  const TYEvent = TYSdk.event
41
44
  const TYDevice = TYSdk.device
42
45
 
43
- const theme = {
44
- global: {
45
- background: '#fff',
46
- },
47
- ldvMainBgColor: '#f60',
48
- 'slider.trackRadius': 15,
49
- }
50
-
51
46
  /**
52
47
  *
53
48
  * @param {} component - 需要连接到redux store的组件,通常为即为main
@@ -93,6 +88,9 @@ const composeLayout = (component: React.ComponentType) => {
93
88
  * 如果面板进入时,`devInfo`不存在,
94
89
  * 那么会调用 getDeviceInfo 异步获取处理好的`devInfo`,并置入`redux`
95
90
  */
91
+ state = {
92
+ colorScheme: 'light'
93
+ }
96
94
  constructor(props: Props) {
97
95
  super(props)
98
96
  if (props && props.devInfo && props.devInfo.devId) {
@@ -119,6 +117,12 @@ const composeLayout = (component: React.ComponentType) => {
119
117
  this.initReduxGroupNativeProps(props.uaGroupInfo)
120
118
  this.initGroupDevices(props.uaGroupInfo?.tyGroupId)
121
119
  }
120
+
121
+ if (!!props.colorScheme) {
122
+ this.state = {
123
+ colorScheme: props.colorScheme || 'light'
124
+ }
125
+ }
122
126
  getSystemTimeFormat().then(time => {
123
127
  dispatch(setSystemTimeFormat(time === 24))
124
128
  })
@@ -213,10 +217,32 @@ const composeLayout = (component: React.ComponentType) => {
213
217
  return dps
214
218
  }
215
219
 
220
+ componentDidMount() {
221
+ nativeEventEmitter.addListener('ColorSchemeUpdate', this.handleColorSchemeUpdate)
222
+ }
223
+
224
+ componentWillUnmount() {
225
+ removeListener()
226
+ nativeEventEmitter.removeListener('ColorSchemeUpdate', this.handleColorSchemeUpdate)
227
+ }
228
+
229
+ handleColorSchemeUpdate = (event: { colorScheme: string }) => {
230
+ this.updateColorScheme(event.colorScheme)
231
+ }
232
+
233
+ updateColorScheme(colorScheme: string) {
234
+ this.setState({
235
+ colorScheme: colorScheme
236
+ })
237
+ }
238
+
216
239
  render() {
240
+ // const { colorScheme } = this.state
241
+ const colorScheme = 'light'
242
+ console.log('colorScheme', colorScheme)
217
243
  return (
218
244
  <Provider store={store}>
219
- <Theme theme={theme}>
245
+ <Theme theme={colorScheme === 'dark' ? darkTheme : lightTheme}>
220
246
  <Connect mapStateToProps={_.identity}>
221
247
  {({ mapStateToProps, ...props }: { mapStateToProps: any; [_: string]: any }) => {
222
248
  return <NavigatorLayout {...props} />
@@ -226,10 +252,6 @@ const composeLayout = (component: React.ComponentType) => {
226
252
  </Provider>
227
253
  )
228
254
  }
229
-
230
- componentWillUnmount() {
231
- removeListener()
232
- }
233
255
  }
234
256
 
235
257
  return PanelComponent
@@ -0,0 +1,56 @@
1
+ import {Utils} from "tuya-panel-kit";
2
+
3
+ const { convertX: cx } = Utils.RatioUtils
4
+
5
+ export default {
6
+ type: 'dark',
7
+ global: {
8
+ brand: '#fff',
9
+ secondBrand: '#fff',
10
+ thirdBrand: '#FFE0D4',
11
+ background: '#000',
12
+ fontColor: '#fff',
13
+ secondFontColor: '#cccccc',
14
+ success: '#00C931',
15
+ warning: '#ff9500',
16
+ error: '#ff0015',
17
+ },
18
+ card: {
19
+ head: '#666',
20
+ background: '#2a2a2a',
21
+ fontColor: '#ffffff',
22
+ borderColor: '#444444',
23
+ shadowColor: '#444444'
24
+ },
25
+ button: {
26
+ active: '#f60',
27
+ disabled: '#f60',
28
+ fontColor: '#000'
29
+ },
30
+ textInput: {
31
+ background: '#737373',
32
+ fontColor: '#fff',
33
+ line: '#fff'
34
+ },
35
+ dialog: {
36
+ width: cx(315), // 弹窗容器宽度
37
+ bg: "#2a2a2a", // 弹窗背景色
38
+ radius: cx(8), // 弹窗容器圆角
39
+ cellHeight: 56, // 列表高度(头部、底部)
40
+ lineColor: "#e5e5e5", // 分隔线颜色
41
+ titleFontSize: 18, // 标题字体大小
42
+ titleFontColor: "#fff", // 头部栏标题颜色
43
+ subTitleFontSize: 16, // 副标题字体大小
44
+ subTitleFontColor: "#cccccc", // 头部栏副标题颜色
45
+ cancelFontSize: 16, // 底部栏取消字体大小
46
+ cancelFontColor: "#cccccc", // 底部栏取消字体颜色
47
+ confirmFontSize: 16, // 底部栏确认字体大小
48
+ confirmFontColor: "#f60", // 底部栏确认字体颜色
49
+ prompt: {
50
+ bg: "#737373", // 输入框背景色
51
+ radius: cx(4), // 输入框圆角
52
+ padding: "12px 16px", // 输入框边距
53
+ placeholder: "#fff", // 占位符字体颜色
54
+ },
55
+ },
56
+ }
@@ -0,0 +1,56 @@
1
+ import {Utils} from "tuya-panel-kit";
2
+
3
+ const { convertX: cx } = Utils.RatioUtils
4
+
5
+ export default {
6
+ type: 'light',
7
+ global: {
8
+ brand: '#f60',
9
+ secondBrand: '#ff8555',
10
+ thirdBrand: '#FFE0D4',
11
+ background: '#fff',
12
+ fontColor: '#000',
13
+ secondFontColor: '#666666',
14
+ success: '#00C931',
15
+ warning: '#ff9500',
16
+ error: '#ff0015',
17
+ },
18
+ card: {
19
+ head: '#DFDEDE',
20
+ background: '#fff',
21
+ fontColor: '#000',
22
+ borderColor: '#e0e0e0',
23
+ shadowColor: '#000'
24
+ },
25
+ button: {
26
+ active: '#f60',
27
+ disabled: '#666666',
28
+ fontColor: '#000'
29
+ },
30
+ textInput: {
31
+ background: '#F6F6F6',
32
+ fontColor: '#000',
33
+ line: '#cbcbcb'
34
+ },
35
+ dialog: {
36
+ width: cx(315), // 弹窗容器宽度
37
+ bg: "#fff", // 弹窗背景色
38
+ radius: cx(8), // 弹窗容器圆角
39
+ cellHeight: 56, // 列表高度(头部、底部)
40
+ lineColor: "#e5e5e5", // 分隔线颜色
41
+ titleFontSize: 18, // 标题字体大小
42
+ titleFontColor: "#333", // 头部栏标题颜色
43
+ subTitleFontSize: 16, // 副标题字体大小
44
+ subTitleFontColor: "#999", // 头部栏副标题颜色
45
+ cancelFontSize: 16, // 底部栏取消字体大小
46
+ cancelFontColor: "#666", // 底部栏取消字体颜色
47
+ confirmFontSize: 16, // 底部栏确认字体大小
48
+ confirmFontColor: "#f60", // 底部栏确认字体颜色
49
+ prompt: {
50
+ bg: "#f8f8f8", // 输入框背景色
51
+ radius: cx(4), // 输入框圆角
52
+ padding: "12px 16px", // 输入框边距
53
+ placeholder: "#d6d6de", // 占位符字体颜色
54
+ },
55
+ },
56
+ }
@@ -9311,7 +9311,7 @@ export default {
9311
9311
  "country_ZA": "Afrique du Sud",
9312
9312
  "country_cu": "Cuba",
9313
9313
  "country_england": "Angleterre",
9314
- "country_gb": "Great Britain",
9314
+ "country_gb": "Grande-Bretagne",
9315
9315
  "country_ir": "Iran",
9316
9316
  "country_pe": "Peru",
9317
9317
  "country_scotland": "Écosse",
@@ -9487,16 +9487,16 @@ export default {
9487
9487
  "matter_gradient_light_on_title": "Fondu(s) à l'allumage",
9488
9488
  "matter_gradient_overview_headline_text": "Fondu",
9489
9489
  "matterplug_LED": "Indicateur LED",
9490
- "matterplug_description": "Configuration of the LED indicator after being switched On/Off",
9491
- "matterplug_heading": "LED indicator status",
9492
- "matterplug_option1description": "The status of the switch corresponds to the LED indicator: Socket is switched on when the LED is on, and switched off when the LED is off.",
9493
- "matterplug_option1title": "Indicates On/Off status",
9494
- "matterplug_option2description": "The status of the switch is inversely indicated by the LED indicator: when the LED is off, the socket is on; when the LED is on, the socket is off.",
9495
- "matterplug_option2title": "Inverse On/Off status",
9496
- "matterplug_option3description": "The LED indicator remains switched OFF irrespective of the Plug status.",
9497
- "matterplug_option3title": "Always Off",
9498
- "matterplug_option4description": "The LED indicator remains switched ON irrespective of the socket status.",
9499
- "matterplug_option4title": "Always On",
9490
+ "matterplug_description": "Configuration du voyant LED après mise sous/hors tension",
9491
+ "matterplug_heading": "État de l'indicateur LED",
9492
+ "matterplug_option1description": "L'état de l'interrupteur correspond à l'indicateur LED : la prise est allumée lorsque la LED est allumée et éteinte lorsque la LED est éteinte.",
9493
+ "matterplug_option1title": "Indique le statut On/Off",
9494
+ "matterplug_option2description": "L'état de l'interrupteur est indiqué en sens inverse par le voyant LED : lorsque la LED est éteinte, la prise est allumée ; lorsque la LED est allumée, la prise est éteinte.",
9495
+ "matterplug_option2title": "Statut marche/arrêt inversé",
9496
+ "matterplug_option3description": "L’indicateur LED reste éteint quel que soit l’état de la prise.",
9497
+ "matterplug_option3title": "Toujours éteint",
9498
+ "matterplug_option4description": "L'indicateur LED reste allumé quel que soit l'état de la prise.",
9499
+ "matterplug_option4title": "Toujours allumé",
9500
9500
  "mesh_device_detail_lighting_color_mode": "Mode couleur",
9501
9501
  "mesh_device_detail_lighting_goodnight": "Bonne nuit",
9502
9502
  "mesh_device_detail_lighting_leisure": "Loisirs",
package/src/main.tsx CHANGED
@@ -1,9 +1,9 @@
1
1
  import {createNavigator, GlobalTheme, NavigationRoute} from 'tuya-panel-kit'
2
- import composeLayout from './composeLayout'
2
+ import ComposeLayout from './composeLayout'
3
3
 
4
4
  export function Navigation(router: NavigationRoute[]) {
5
- return composeLayout(createNavigator<{ theme: GlobalTheme }>({
5
+ return ComposeLayout(createNavigator<{ theme: GlobalTheme }>({
6
6
  router: router,
7
7
  screenOptions: {},
8
8
  }))
9
- }
9
+ }