@helpwave/hightide-native 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 +3 -3
- package/src/components/chat/ChatMessageCard.tsx +1 -1
- package/src/components/chat/ChatSystemLine.tsx +1 -1
- package/src/components/user-interaction/Button.tsx +1 -1
- package/src/components/user-interaction/IconButton.tsx +1 -1
- package/src/components/user-interaction/Switch.tsx +177 -0
- package/src/components/user-interaction/index.ts +1 -0
- package/src/components/visualization-and-display/Avatar.tsx +286 -0
- package/src/components/visualization-and-display/Chip.tsx +1 -1
- package/src/components/visualization-and-display/index.ts +1 -0
- package/src/global-contexts/hightide-config/HightideConfigUtils.ts +3 -3
- package/src/global-contexts/theme/ThemeContext.ts +2 -2
- package/src/global-contexts/theme/ThemeProvider.tsx +3 -3
- package/src/theme/resolvers/avatar.ts +231 -0
- package/src/theme/resolvers/button.ts +1 -1
- package/src/theme/resolvers/chat.ts +2 -2
- package/src/theme/resolvers/checkbox.ts +1 -1
- package/src/theme/resolvers/chip.ts +1 -1
- package/src/theme/resolvers/coloring.ts +1 -1
- package/src/theme/resolvers/iconButton.ts +1 -1
- package/src/theme/resolvers/index.ts +2 -0
- package/src/theme/resolvers/input.ts +1 -1
- package/src/theme/resolvers/menu.ts +1 -1
- package/src/theme/resolvers/multiSelect.ts +1 -1
- package/src/theme/resolvers/select.ts +1 -1
- package/src/theme/resolvers/switch.ts +65 -0
- package/src/theme/themes/{createTheme.ts → createHightideTheme.ts} +8 -4
- package/src/theme/themes/hightideThemes.ts +14 -0
- package/src/theme/themes/index.ts +2 -2
- package/src/theme/types/components/avatar.ts +77 -0
- package/src/theme/types/components/button.ts +1 -1
- package/src/theme/types/components/chat.ts +1 -1
- package/src/theme/types/components/chip.ts +1 -1
- package/src/theme/types/components/hightide.ts +4 -0
- package/src/theme/types/components/iconButton.ts +1 -1
- package/src/theme/types/components/index.ts +2 -0
- package/src/theme/types/components/switch.ts +15 -0
- package/src/theme/types/layout.ts +12 -0
- package/src/theme/types/theme.ts +15 -6
- package/src/theme/themes/nativeThemes.ts +0 -16
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ImageStyle,
|
|
3
|
+
TextStyle,
|
|
4
|
+
ViewStyle
|
|
5
|
+
} from 'react-native'
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
componentLayouts,
|
|
9
|
+
fontWeights
|
|
10
|
+
} from '@helpwave/hightide-design/tokens'
|
|
11
|
+
import type {
|
|
12
|
+
ElementSize,
|
|
13
|
+
HightideThemeTokens as DesignTokensTheme,
|
|
14
|
+
TypographyTokens
|
|
15
|
+
} from '@helpwave/hightide-design/types'
|
|
16
|
+
|
|
17
|
+
import { resolveColoringStyles } from './coloring'
|
|
18
|
+
import type {
|
|
19
|
+
ColorPalette,
|
|
20
|
+
HightideSemanticColors
|
|
21
|
+
} from '../types/color'
|
|
22
|
+
import type {
|
|
23
|
+
AvatarGroupState,
|
|
24
|
+
AvatarIconStyle,
|
|
25
|
+
AvatarState,
|
|
26
|
+
AvatarStatus,
|
|
27
|
+
AvatarTheme,
|
|
28
|
+
AvatarWithLabelState,
|
|
29
|
+
AvatarWithStatusState
|
|
30
|
+
} from '../types/components/avatar'
|
|
31
|
+
import type { HightideComponentThemes } from '../types/components/hightide'
|
|
32
|
+
import { createStyleResolver } from '../types/resolver'
|
|
33
|
+
|
|
34
|
+
const avatarFontWeights: Record<ElementSize, string> = {
|
|
35
|
+
xs: fontWeights.semibold,
|
|
36
|
+
sm: fontWeights.semibold,
|
|
37
|
+
md: fontWeights.semibold,
|
|
38
|
+
lg: fontWeights.bold,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const statusColor = (
|
|
42
|
+
status: AvatarStatus,
|
|
43
|
+
semantic: HightideSemanticColors,
|
|
44
|
+
gray: ColorPalette
|
|
45
|
+
): string => {
|
|
46
|
+
switch (status) {
|
|
47
|
+
case 'online':
|
|
48
|
+
return semantic.positive
|
|
49
|
+
case 'busy':
|
|
50
|
+
return semantic.negative
|
|
51
|
+
case 'away':
|
|
52
|
+
return semantic.warning
|
|
53
|
+
case 'offline':
|
|
54
|
+
case 'unknown':
|
|
55
|
+
default:
|
|
56
|
+
return gray[500]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type CreateAvatarThemeOptions = {
|
|
61
|
+
semantic: HightideSemanticColors,
|
|
62
|
+
coloring: HightideComponentThemes['coloring'],
|
|
63
|
+
gray: ColorPalette,
|
|
64
|
+
typography: TypographyTokens,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const createAvatarTheme = ({
|
|
68
|
+
semantic,
|
|
69
|
+
coloring,
|
|
70
|
+
gray,
|
|
71
|
+
typography,
|
|
72
|
+
}: CreateAvatarThemeOptions): AvatarTheme => {
|
|
73
|
+
const resolveAvatar = (state: AvatarState) => {
|
|
74
|
+
const size = state.size ?? 'md'
|
|
75
|
+
const layout = componentLayouts.avatar[size]
|
|
76
|
+
const groupLayout = componentLayouts.avatarGroup
|
|
77
|
+
const resolved = resolveColoringStyles(coloring.primary, 'solid', semantic)
|
|
78
|
+
const borderRadius = layout.size / 2
|
|
79
|
+
|
|
80
|
+
const avatar: ViewStyle = {
|
|
81
|
+
position: state.isGrouped ? 'absolute' : 'relative',
|
|
82
|
+
flexDirection: 'row',
|
|
83
|
+
alignItems: 'center',
|
|
84
|
+
justifyContent: 'center',
|
|
85
|
+
width: layout.size,
|
|
86
|
+
height: layout.size,
|
|
87
|
+
padding: layout.padding,
|
|
88
|
+
borderRadius,
|
|
89
|
+
backgroundColor: resolved.backgroundColor,
|
|
90
|
+
overflow: 'hidden',
|
|
91
|
+
...(state.isGrouped ? {
|
|
92
|
+
left: (state.groupIndex ?? 0) * layout.size * groupLayout.overlap,
|
|
93
|
+
zIndex: groupLayout.maxShown - (state.groupIndex ?? 0),
|
|
94
|
+
shadowColor: '#000000',
|
|
95
|
+
shadowOffset: { width: 4, height: 0 },
|
|
96
|
+
shadowOpacity: 0.2,
|
|
97
|
+
shadowRadius: 4,
|
|
98
|
+
elevation: 4,
|
|
99
|
+
} : {}),
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const image: ImageStyle = {
|
|
103
|
+
position: 'absolute',
|
|
104
|
+
left: 0,
|
|
105
|
+
top: 0,
|
|
106
|
+
width: layout.size,
|
|
107
|
+
height: layout.size,
|
|
108
|
+
borderRadius,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const text: TextStyle = {
|
|
112
|
+
color: resolved.color,
|
|
113
|
+
fontSize: layout.fontSize,
|
|
114
|
+
fontWeight: avatarFontWeights[size] as TextStyle['fontWeight'],
|
|
115
|
+
textAlign: 'center',
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const icon: AvatarIconStyle = {
|
|
119
|
+
size: componentLayouts.icon[size].size,
|
|
120
|
+
strokeWidth: componentLayouts.icon[size].strokeWidth,
|
|
121
|
+
color: resolved.color,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return { avatar, image, text, icon }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const resolveWithStatus = (state: AvatarWithStatusState) => {
|
|
128
|
+
const size = state.size ?? 'md'
|
|
129
|
+
const status = state.status ?? 'unknown'
|
|
130
|
+
const layout = componentLayouts.avatar[size]
|
|
131
|
+
|
|
132
|
+
const container: ViewStyle = {
|
|
133
|
+
position: 'relative',
|
|
134
|
+
alignSelf: 'flex-start',
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const statusDot: ViewStyle = {
|
|
138
|
+
position: 'absolute',
|
|
139
|
+
right: 0,
|
|
140
|
+
bottom: 0,
|
|
141
|
+
zIndex: 1,
|
|
142
|
+
width: layout.statusDotSize,
|
|
143
|
+
height: layout.statusDotSize,
|
|
144
|
+
borderRadius: layout.statusDotSize / 2,
|
|
145
|
+
borderWidth: layout.statusDotBorderWidth,
|
|
146
|
+
borderColor: semantic.background,
|
|
147
|
+
backgroundColor: statusColor(status, semantic, gray),
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { container, statusDot }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const resolveWithLabel = (_state: AvatarWithLabelState) => {
|
|
154
|
+
const bodyMedium = typography.scales.body.medium
|
|
155
|
+
|
|
156
|
+
const container: ViewStyle = {
|
|
157
|
+
flexDirection: 'row',
|
|
158
|
+
alignItems: 'center',
|
|
159
|
+
gap: componentLayouts.avatarGroup.gap,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const text: TextStyle = {
|
|
163
|
+
fontSize: bodyMedium.fontSize,
|
|
164
|
+
fontWeight: bodyMedium.fontWeight as TextStyle['fontWeight'],
|
|
165
|
+
lineHeight: bodyMedium.lineHeight,
|
|
166
|
+
color: semantic.onBackground,
|
|
167
|
+
flexShrink: 1,
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return { container, text }
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const resolveGroup = (state: AvatarGroupState) => {
|
|
174
|
+
const size = state.size ?? 'md'
|
|
175
|
+
const layout = componentLayouts.avatar[size]
|
|
176
|
+
const groupLayout = componentLayouts.avatarGroup
|
|
177
|
+
const visibleCount = Math.min(state.count ?? groupLayout.maxShown, groupLayout.maxShown)
|
|
178
|
+
const stackWidth = layout.size * (groupLayout.overlap * Math.max(visibleCount - 1, 0) + 1)
|
|
179
|
+
|
|
180
|
+
const container: ViewStyle = {
|
|
181
|
+
flexDirection: 'row',
|
|
182
|
+
alignItems: 'center',
|
|
183
|
+
gap: groupLayout.gap,
|
|
184
|
+
height: layout.size,
|
|
185
|
+
alignSelf: 'flex-start',
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const stack: ViewStyle = {
|
|
189
|
+
position: 'relative',
|
|
190
|
+
width: stackWidth,
|
|
191
|
+
height: layout.size,
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const more: TextStyle = {
|
|
195
|
+
fontSize: (layout.size * 2) / 3,
|
|
196
|
+
color: semantic.onBackground,
|
|
197
|
+
flexShrink: 1,
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return { container, stack, more }
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
avatar: createStyleResolver((state) => resolveAvatar(state).avatar),
|
|
205
|
+
image: createStyleResolver((state) => resolveAvatar(state).image),
|
|
206
|
+
text: createStyleResolver((state) => resolveAvatar(state).text),
|
|
207
|
+
icon: createStyleResolver((state) => resolveAvatar(state).icon),
|
|
208
|
+
withStatus: {
|
|
209
|
+
container: createStyleResolver((state) => resolveWithStatus(state).container),
|
|
210
|
+
statusDot: createStyleResolver((state) => resolveWithStatus(state).statusDot),
|
|
211
|
+
},
|
|
212
|
+
withLabel: {
|
|
213
|
+
container: createStyleResolver((state) => resolveWithLabel(state).container),
|
|
214
|
+
text: createStyleResolver((state) => resolveWithLabel(state).text),
|
|
215
|
+
},
|
|
216
|
+
group: {
|
|
217
|
+
container: createStyleResolver((state) => resolveGroup(state).container),
|
|
218
|
+
stack: createStyleResolver((state) => resolveGroup(state).stack),
|
|
219
|
+
more: createStyleResolver((state) => resolveGroup(state).more),
|
|
220
|
+
},
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export const createAvatarThemeFromDesign = (theme: DesignTokensTheme): AvatarTheme => {
|
|
225
|
+
return createAvatarTheme({
|
|
226
|
+
semantic: theme.semanticColors,
|
|
227
|
+
coloring: theme.coloring as HightideComponentThemes['coloring'],
|
|
228
|
+
gray: theme.colors.gray.value as ColorPalette,
|
|
229
|
+
typography: theme.typography,
|
|
230
|
+
})
|
|
231
|
+
}
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
type ViewStyle
|
|
5
5
|
} from 'react-native'
|
|
6
6
|
|
|
7
|
-
import { hexWithAlpha } from '@helpwave/hightide-design/
|
|
7
|
+
import { hexWithAlpha } from '@helpwave/hightide-design/utils'
|
|
8
8
|
import { fontWeights } from '@helpwave/hightide-design/tokens'
|
|
9
9
|
import type {
|
|
10
10
|
ComponentColorTokens,
|
|
11
|
-
|
|
11
|
+
HightideThemeTokens as DesignTokensTheme
|
|
12
12
|
} from '@helpwave/hightide-design/types'
|
|
13
13
|
|
|
14
14
|
import type {
|
|
@@ -3,7 +3,7 @@ import type { ViewStyle } from 'react-native'
|
|
|
3
3
|
import { componentLayouts } from '@helpwave/hightide-design/tokens'
|
|
4
4
|
import type {
|
|
5
5
|
ComponentColorTokens,
|
|
6
|
-
|
|
6
|
+
HightideThemeTokens as DesignTokensTheme,
|
|
7
7
|
ElementSize
|
|
8
8
|
} from '@helpwave/hightide-design/types'
|
|
9
9
|
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
componentLayouts,
|
|
8
8
|
fontWeights
|
|
9
9
|
} from '@helpwave/hightide-design/tokens'
|
|
10
|
-
import type {
|
|
10
|
+
import type { HightideThemeTokens as DesignTokensTheme } from '@helpwave/hightide-design/types'
|
|
11
11
|
|
|
12
12
|
import { resolveColoringStyles } from './coloring'
|
|
13
13
|
import type { HightideSemanticColors } from '../types/color'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ViewStyle } from 'react-native'
|
|
2
2
|
|
|
3
3
|
import { componentLayouts } from '@helpwave/hightide-design/tokens'
|
|
4
|
-
import type {
|
|
4
|
+
import type { HightideThemeTokens as DesignTokensTheme } from '@helpwave/hightide-design/types'
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
isOutlineColoringStyle,
|
|
@@ -3,7 +3,7 @@ import type { TextStyle } from 'react-native'
|
|
|
3
3
|
import { componentLayouts } from '@helpwave/hightide-design/tokens'
|
|
4
4
|
import type {
|
|
5
5
|
ComponentColorTokens,
|
|
6
|
-
|
|
6
|
+
HightideThemeTokens as DesignTokensTheme
|
|
7
7
|
} from '@helpwave/hightide-design/types'
|
|
8
8
|
|
|
9
9
|
import type { HightideSemanticColors } from '../types/color'
|
|
@@ -3,7 +3,7 @@ import { StyleSheet } from 'react-native'
|
|
|
3
3
|
import { fontWeights } from '@helpwave/hightide-design/tokens'
|
|
4
4
|
import type {
|
|
5
5
|
ComponentColorTokens,
|
|
6
|
-
|
|
6
|
+
HightideThemeTokens as DesignTokensTheme
|
|
7
7
|
} from '@helpwave/hightide-design/types'
|
|
8
8
|
|
|
9
9
|
import type { HightideSemanticColors } from '../types/color'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fontWeights } from '@helpwave/hightide-design/tokens'
|
|
2
2
|
import type {
|
|
3
3
|
ComponentColorTokens,
|
|
4
|
-
|
|
4
|
+
HightideThemeTokens as DesignTokensTheme
|
|
5
5
|
} from '@helpwave/hightide-design/types'
|
|
6
6
|
|
|
7
7
|
import type { HightideSemanticColors } from '../types/color'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fontWeights } from '@helpwave/hightide-design/tokens'
|
|
2
2
|
import type {
|
|
3
3
|
ComponentColorTokens,
|
|
4
|
-
|
|
4
|
+
HightideThemeTokens as DesignTokensTheme
|
|
5
5
|
} from '@helpwave/hightide-design/types'
|
|
6
6
|
|
|
7
7
|
import type { HightideSemanticColors } from '../types/color'
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ComponentColorTokens,
|
|
3
|
+
HightideThemeTokens as DesignTokensTheme
|
|
4
|
+
} from '@helpwave/hightide-design/types'
|
|
5
|
+
|
|
6
|
+
import type { HightideSemanticColors } from '../types/color'
|
|
7
|
+
import type {
|
|
8
|
+
SwitchState,
|
|
9
|
+
SwitchTheme
|
|
10
|
+
} from '../types/components/switch'
|
|
11
|
+
import { createValueResolver } from '../types/resolver'
|
|
12
|
+
|
|
13
|
+
export type CreateSwitchThemeOptions = {
|
|
14
|
+
semantic: HightideSemanticColors,
|
|
15
|
+
component: ComponentColorTokens,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const createSwitchTheme = ({
|
|
19
|
+
semantic,
|
|
20
|
+
component,
|
|
21
|
+
}: CreateSwitchThemeOptions): SwitchTheme => {
|
|
22
|
+
const resolveState = (state: SwitchState) => {
|
|
23
|
+
const trackInactive = state.isDisabled
|
|
24
|
+
? semantic.disabled
|
|
25
|
+
: component.switch.track.inactive
|
|
26
|
+
const trackActive = state.isDisabled
|
|
27
|
+
? semantic.disabled
|
|
28
|
+
: component.switch.track.active
|
|
29
|
+
|
|
30
|
+
const trackColor = state.isActive ? trackActive : trackInactive
|
|
31
|
+
|
|
32
|
+
const borderColor = state.isDisabled
|
|
33
|
+
? semantic.disabled
|
|
34
|
+
: state.isInvalid
|
|
35
|
+
? semantic.negative
|
|
36
|
+
: state.isActive
|
|
37
|
+
? trackActive
|
|
38
|
+
: component.switch.borderColor
|
|
39
|
+
|
|
40
|
+
const thumbColor = state.isDisabled
|
|
41
|
+
? semantic.onDisabled
|
|
42
|
+
: state.isActive
|
|
43
|
+
? component.switch.thumb.active
|
|
44
|
+
: component.switch.thumb.inactive
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
trackColor,
|
|
48
|
+
borderColor,
|
|
49
|
+
thumbColor,
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
trackColor: createValueResolver((state) => resolveState(state).trackColor),
|
|
55
|
+
borderColor: createValueResolver((state) => resolveState(state).borderColor),
|
|
56
|
+
thumbColor: createValueResolver((state) => resolveState(state).thumbColor),
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const createSwitchThemeFromDesign = (theme: DesignTokensTheme): SwitchTheme => {
|
|
61
|
+
return createSwitchTheme({
|
|
62
|
+
semantic: theme.semanticColors,
|
|
63
|
+
component: theme.componentColors,
|
|
64
|
+
})
|
|
65
|
+
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ColorPaletteToken,
|
|
3
|
-
|
|
3
|
+
HightideThemeTokens
|
|
4
4
|
} from '@helpwave/hightide-design/types'
|
|
5
5
|
|
|
6
|
+
import { createAvatarThemeFromDesign } from '../resolvers/avatar'
|
|
6
7
|
import { createButtonThemeFromDesign } from '../resolvers/button'
|
|
7
8
|
import { createChatThemeFromDesign } from '../resolvers/chat'
|
|
8
9
|
import { createCheckboxThemeFromDesign } from '../resolvers/checkbox'
|
|
9
10
|
import { createChipThemeFromDesign } from '../resolvers/chip'
|
|
11
|
+
import { createSwitchThemeFromDesign } from '../resolvers/switch'
|
|
10
12
|
import { createIconButtonThemeFromDesign } from '../resolvers/iconButton'
|
|
11
13
|
import { createInputThemeFromDesign } from '../resolvers/input'
|
|
12
14
|
import { createMenuThemeFromDesign } from '../resolvers/menu'
|
|
@@ -17,7 +19,7 @@ import type {
|
|
|
17
19
|
ColorPalette,
|
|
18
20
|
HightideColors
|
|
19
21
|
} from '../types/color'
|
|
20
|
-
import type {
|
|
22
|
+
import type { HightideTheme } from '../types/theme'
|
|
21
23
|
|
|
22
24
|
const unwrapColorPaletteToken = (token: ColorPaletteToken): Color | ColorPalette => {
|
|
23
25
|
if (token.type === 'singleValue') {
|
|
@@ -26,7 +28,7 @@ const unwrapColorPaletteToken = (token: ColorPaletteToken): Color | ColorPalette
|
|
|
26
28
|
return token.value
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
const unwrapColors = (colors:
|
|
31
|
+
const unwrapColors = (colors: HightideThemeTokens['colors']): HightideColors & Record<string, Color | ColorPalette> => {
|
|
30
32
|
const result: Record<string, Color | ColorPalette> = {}
|
|
31
33
|
for (const [key, token] of Object.entries(colors)) {
|
|
32
34
|
result[key] = unwrapColorPaletteToken(token)
|
|
@@ -34,7 +36,7 @@ const unwrapColors = (colors: HightideDesignTokens['colors']): HightideColors &
|
|
|
34
36
|
return result as HightideColors & Record<string, Color | ColorPalette>
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
export const
|
|
39
|
+
export const createHightideTheme = (tokens: HightideThemeTokens): HightideTheme => ({
|
|
38
40
|
colors: unwrapColors(tokens.colors),
|
|
39
41
|
semantic: tokens.semanticColors,
|
|
40
42
|
typography: tokens.typography,
|
|
@@ -46,10 +48,12 @@ export const createTheme = (tokens: HightideDesignTokens): Theme => ({
|
|
|
46
48
|
iconButton: createIconButtonThemeFromDesign(tokens),
|
|
47
49
|
chip: createChipThemeFromDesign(tokens),
|
|
48
50
|
checkbox: createCheckboxThemeFromDesign(tokens),
|
|
51
|
+
switch: createSwitchThemeFromDesign(tokens),
|
|
49
52
|
input: createInputThemeFromDesign(tokens),
|
|
50
53
|
select: createSelectThemeFromDesign(tokens),
|
|
51
54
|
multiSelect: createMultiSelectThemeFromDesign(tokens),
|
|
52
55
|
chat: createChatThemeFromDesign(tokens),
|
|
53
56
|
menu: createMenuThemeFromDesign(tokens),
|
|
57
|
+
avatar: createAvatarThemeFromDesign(tokens),
|
|
54
58
|
},
|
|
55
59
|
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ThemeTokens as designThemes } from '@helpwave/hightide-design/tokens'
|
|
2
|
+
import { createHightideTheme } from './createHightideTheme'
|
|
3
|
+
|
|
4
|
+
export const lightTheme = createHightideTheme(designThemes.light)
|
|
5
|
+
export const darkTheme = createHightideTheme(designThemes.dark)
|
|
6
|
+
|
|
7
|
+
export const themes = {
|
|
8
|
+
light: lightTheme,
|
|
9
|
+
dark: darkTheme,
|
|
10
|
+
} as const
|
|
11
|
+
|
|
12
|
+
export type HightideThemeModes = 'dark' | 'light'
|
|
13
|
+
|
|
14
|
+
export type ThemeMode = string | HightideThemeModes
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
1
|
+
export * from './createHightideTheme'
|
|
2
|
+
export * from './hightideThemes'
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ImageStyle,
|
|
3
|
+
TextStyle,
|
|
4
|
+
ViewStyle
|
|
5
|
+
} from 'react-native'
|
|
6
|
+
|
|
7
|
+
import type { ElementSize } from '@helpwave/hightide-design/types'
|
|
8
|
+
|
|
9
|
+
import type { StyleResolverFunction } from '../resolver'
|
|
10
|
+
|
|
11
|
+
export type AvatarStatus = 'online' | 'offline' | 'away' | 'busy' | 'unknown'
|
|
12
|
+
|
|
13
|
+
export type AvatarState = {
|
|
14
|
+
size?: ElementSize,
|
|
15
|
+
isGrouped?: boolean,
|
|
16
|
+
groupIndex?: number,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type AvatarWithStatusState = {
|
|
20
|
+
size?: ElementSize,
|
|
21
|
+
status?: AvatarStatus,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type AvatarWithLabelState = {
|
|
25
|
+
size?: ElementSize,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type AvatarGroupState = {
|
|
29
|
+
size?: ElementSize,
|
|
30
|
+
count?: number,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type AvatarStyle = ViewStyle
|
|
34
|
+
|
|
35
|
+
export type AvatarImageStyle = ImageStyle
|
|
36
|
+
|
|
37
|
+
export type AvatarTextStyle = TextStyle
|
|
38
|
+
|
|
39
|
+
export type AvatarIconStyle = {
|
|
40
|
+
size: number,
|
|
41
|
+
strokeWidth: number,
|
|
42
|
+
color: string,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type AvatarStatusDotStyle = ViewStyle
|
|
46
|
+
|
|
47
|
+
export type AvatarWithStatusContainerStyle = ViewStyle
|
|
48
|
+
|
|
49
|
+
export type AvatarWithLabelContainerStyle = ViewStyle
|
|
50
|
+
|
|
51
|
+
export type AvatarWithLabelTextStyle = TextStyle
|
|
52
|
+
|
|
53
|
+
export type AvatarGroupContainerStyle = ViewStyle
|
|
54
|
+
|
|
55
|
+
export type AvatarGroupStackStyle = ViewStyle
|
|
56
|
+
|
|
57
|
+
export type AvatarGroupMoreStyle = TextStyle
|
|
58
|
+
|
|
59
|
+
export type AvatarTheme = {
|
|
60
|
+
avatar: StyleResolverFunction<AvatarState, AvatarStyle>,
|
|
61
|
+
image: StyleResolverFunction<AvatarState, AvatarImageStyle>,
|
|
62
|
+
text: StyleResolverFunction<AvatarState, AvatarTextStyle>,
|
|
63
|
+
icon: StyleResolverFunction<AvatarState, AvatarIconStyle>,
|
|
64
|
+
withStatus: {
|
|
65
|
+
container: StyleResolverFunction<AvatarWithStatusState, AvatarWithStatusContainerStyle>,
|
|
66
|
+
statusDot: StyleResolverFunction<AvatarWithStatusState, AvatarStatusDotStyle>,
|
|
67
|
+
},
|
|
68
|
+
withLabel: {
|
|
69
|
+
container: StyleResolverFunction<AvatarWithLabelState, AvatarWithLabelContainerStyle>,
|
|
70
|
+
text: StyleResolverFunction<AvatarWithLabelState, AvatarWithLabelTextStyle>,
|
|
71
|
+
},
|
|
72
|
+
group: {
|
|
73
|
+
container: StyleResolverFunction<AvatarGroupState, AvatarGroupContainerStyle>,
|
|
74
|
+
stack: StyleResolverFunction<AvatarGroupState, AvatarGroupStackStyle>,
|
|
75
|
+
more: StyleResolverFunction<AvatarGroupState, AvatarGroupMoreStyle>,
|
|
76
|
+
},
|
|
77
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Color } from '../color'
|
|
2
|
+
import type { AvatarTheme } from './avatar'
|
|
2
3
|
import type { ButtonTheme } from './button'
|
|
3
4
|
import type { ChatTheme } from './chat'
|
|
4
5
|
import type { CheckboxTheme } from './checkbox'
|
|
@@ -8,6 +9,7 @@ import type { InputTheme } from './input'
|
|
|
8
9
|
import type { MenuTheme } from './menu'
|
|
9
10
|
import type { MultiSelectTheme } from './multiSelect'
|
|
10
11
|
import type { SelectTheme } from './select'
|
|
12
|
+
import type { SwitchTheme } from './switch'
|
|
11
13
|
|
|
12
14
|
export type ColoringDefinition = {
|
|
13
15
|
color: Color,
|
|
@@ -34,9 +36,11 @@ export type HightideComponentThemes = {
|
|
|
34
36
|
iconButton: IconButtonTheme,
|
|
35
37
|
chip: ChipTheme,
|
|
36
38
|
checkbox: CheckboxTheme,
|
|
39
|
+
switch: SwitchTheme,
|
|
37
40
|
input: InputTheme,
|
|
38
41
|
select: SelectTheme,
|
|
39
42
|
multiSelect: MultiSelectTheme,
|
|
40
43
|
chat: ChatTheme,
|
|
41
44
|
menu: MenuTheme,
|
|
45
|
+
avatar: AvatarTheme,
|
|
42
46
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Color } from '../color'
|
|
2
|
+
import type {
|
|
3
|
+
InteractionState,
|
|
4
|
+
StyleResolverFunction
|
|
5
|
+
} from '../resolver'
|
|
6
|
+
|
|
7
|
+
export type SwitchState = InteractionState & {
|
|
8
|
+
isActive?: boolean,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type SwitchTheme = {
|
|
12
|
+
trackColor: StyleResolverFunction<SwitchState, Color>,
|
|
13
|
+
borderColor: StyleResolverFunction<SwitchState, Color>,
|
|
14
|
+
thumbColor: StyleResolverFunction<SwitchState, Color>,
|
|
15
|
+
}
|
|
@@ -43,4 +43,16 @@ export type HightideLayout = {
|
|
|
43
43
|
borderRadius: number,
|
|
44
44
|
fontSize: number,
|
|
45
45
|
}>,
|
|
46
|
+
avatar: Record<ElementSize, {
|
|
47
|
+
size: number,
|
|
48
|
+
padding: number,
|
|
49
|
+
fontSize: number,
|
|
50
|
+
statusDotSize: number,
|
|
51
|
+
statusDotBorderWidth: number,
|
|
52
|
+
}>,
|
|
53
|
+
avatarGroup: {
|
|
54
|
+
overlap: number,
|
|
55
|
+
maxShown: number,
|
|
56
|
+
gap: number,
|
|
57
|
+
},
|
|
46
58
|
}
|