@helpwave/hightide-native 0.0.1 → 0.0.5

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.
Files changed (89) hide show
  1. package/README.md +56 -0
  2. package/package.json +3 -3
  3. package/src/components/chat/ChatAttachmentCard.tsx +110 -0
  4. package/src/components/chat/ChatConversationList.tsx +72 -0
  5. package/src/components/chat/ChatConversationRow.tsx +153 -0
  6. package/src/components/chat/ChatDateDivider.tsx +55 -0
  7. package/src/components/chat/ChatMessageBubble.tsx +112 -0
  8. package/src/components/chat/ChatMessageCard.tsx +118 -0
  9. package/src/components/chat/ChatMessageComposer.tsx +115 -0
  10. package/src/components/chat/ChatMessageList.tsx +66 -0
  11. package/src/components/chat/ChatQuickReplyChip.tsx +72 -0
  12. package/src/components/chat/ChatSystemLine.tsx +68 -0
  13. package/src/components/chat/ChatThreadHeader.tsx +90 -0
  14. package/src/components/chat/index.ts +11 -0
  15. package/src/components/index.ts +4 -7
  16. package/src/components/menu/Menu.tsx +61 -0
  17. package/src/components/menu/MenuActionItem.tsx +90 -0
  18. package/src/components/menu/MenuItem.tsx +73 -0
  19. package/src/components/menu/MenuNavigationItem.tsx +90 -0
  20. package/src/components/menu/index.ts +4 -0
  21. package/src/components/user-interaction/Button.tsx +101 -0
  22. package/src/components/{Checkbox → user-interaction}/Checkbox.tsx +38 -16
  23. package/src/components/user-interaction/IconButton.tsx +95 -0
  24. package/src/components/{Input → user-interaction}/Input.tsx +35 -14
  25. package/src/components/{MultiSelect → user-interaction}/MultiSelect.tsx +47 -15
  26. package/src/components/{Select → user-interaction}/Select.tsx +44 -12
  27. package/src/components/user-interaction/index.ts +6 -0
  28. package/src/components/{Chip → visualization-and-display}/Chip.tsx +36 -20
  29. package/src/components/visualization-and-display/Icon.tsx +27 -0
  30. package/src/components/{Chip → visualization-and-display}/index.ts +1 -0
  31. package/src/global-contexts/HightideContext.ts +4 -1
  32. package/src/global-contexts/HightideProvider.tsx +22 -10
  33. package/src/global-contexts/hightide-config/HightideConfigUtils.ts +15 -12
  34. package/src/global-contexts/localization/LocalizationProvider.tsx +4 -2
  35. package/src/global-contexts/localization/forward-exports.ts +1 -0
  36. package/src/global-contexts/theme/ThemeContext.ts +11 -6
  37. package/src/global-contexts/theme/ThemeProvider.tsx +35 -38
  38. package/src/hooks/useMultiSelect.ts +1 -0
  39. package/src/hooks/useNativeKeyValueStore.ts +7 -1
  40. package/src/hooks/useSelect.ts +1 -0
  41. package/src/theme/resolvers/button.ts +38 -23
  42. package/src/theme/resolvers/chat.ts +418 -0
  43. package/src/theme/resolvers/checkbox.ts +26 -21
  44. package/src/theme/resolvers/chip.ts +32 -22
  45. package/src/theme/resolvers/coloring.ts +21 -17
  46. package/src/theme/resolvers/iconButton.ts +28 -18
  47. package/src/theme/resolvers/index.ts +2 -0
  48. package/src/theme/resolvers/input.ts +28 -19
  49. package/src/theme/resolvers/menu.ts +120 -0
  50. package/src/theme/resolvers/multiSelect.ts +39 -34
  51. package/src/theme/resolvers/select.ts +35 -30
  52. package/src/theme/themes/createTheme.ts +44 -15
  53. package/src/theme/themes/nativeThemes.ts +7 -6
  54. package/src/theme/types/color.ts +60 -0
  55. package/src/theme/types/components/button.ts +30 -0
  56. package/src/theme/types/components/chat.ts +198 -0
  57. package/src/theme/types/components/checkbox.ts +33 -0
  58. package/src/theme/types/components/chip.ts +30 -0
  59. package/src/theme/types/components/hightide.ts +42 -0
  60. package/src/theme/types/components/iconButton.ts +30 -0
  61. package/src/theme/types/components/index.ts +10 -0
  62. package/src/theme/types/components/input.ts +19 -0
  63. package/src/theme/types/components/menu.ts +57 -0
  64. package/src/theme/types/components/multiSelect.ts +47 -0
  65. package/src/theme/types/components/select.ts +47 -0
  66. package/src/theme/types/decoration.ts +11 -0
  67. package/src/theme/types/index.ts +4 -7
  68. package/src/theme/types/layout.ts +46 -0
  69. package/src/theme/types/resolver.ts +43 -1
  70. package/src/theme/types/theme.ts +14 -10
  71. package/src/theme/types/typography.ts +18 -0
  72. package/src/components/Button/Button.tsx +0 -101
  73. package/src/components/Button/index.ts +0 -1
  74. package/src/components/Checkbox/index.ts +0 -1
  75. package/src/components/IconButton/IconButton.tsx +0 -89
  76. package/src/components/IconButton/index.ts +0 -1
  77. package/src/components/Input/index.ts +0 -1
  78. package/src/components/MultiSelect/index.ts +0 -1
  79. package/src/components/Select/index.ts +0 -1
  80. package/src/icons/Icon.tsx +0 -35
  81. package/src/icons/index.ts +0 -1
  82. package/src/theme/types/button.ts +0 -41
  83. package/src/theme/types/checkbox.ts +0 -36
  84. package/src/theme/types/chip.ts +0 -41
  85. package/src/theme/types/components.ts +0 -17
  86. package/src/theme/types/iconButton.ts +0 -34
  87. package/src/theme/types/input.ts +0 -25
  88. package/src/theme/types/multiSelect.ts +0 -65
  89. package/src/theme/types/select.ts +0 -77
@@ -0,0 +1,418 @@
1
+ import {
2
+ StyleSheet,
3
+ type TextStyle,
4
+ type ViewStyle
5
+ } from 'react-native'
6
+
7
+ import { hexWithAlpha } from '@helpwave/hightide-design/helpers'
8
+ import { fontWeights } from '@helpwave/hightide-design/tokens'
9
+ import type {
10
+ ComponentColorTokens,
11
+ HightideDesignTokens as DesignTokensTheme
12
+ } from '@helpwave/hightide-design/types'
13
+
14
+ import type {
15
+ Color,
16
+ HightideSemanticColors
17
+ } from '@/src/theme/types/color'
18
+ import type {
19
+ ChatAttachmentCardState,
20
+ ChatConversationRowState,
21
+ ChatMessageBubbleState,
22
+ ChatMessageCardState,
23
+ ChatQuickReplyChipState,
24
+ ChatSystemLineState,
25
+ ChatTheme
26
+ } from '@/src/theme/types/components/chat'
27
+ import type { HightideComponentThemes } from '@/src/theme/types/components/hightide'
28
+ import {
29
+ createStyleResolver,
30
+ createValueResolver
31
+ } from '@/src/theme/types/resolver'
32
+
33
+ export type CreateChatThemeOptions = {
34
+ semantic: HightideSemanticColors,
35
+ component: ComponentColorTokens,
36
+ coloring: HightideComponentThemes['coloring'],
37
+ }
38
+
39
+ export const createChatTheme = ({
40
+ semantic,
41
+ component,
42
+ coloring,
43
+ }: CreateChatThemeOptions): ChatTheme => {
44
+ const resolveConversationRow = (state: ChatConversationRowState): ViewStyle => {
45
+ const pressed = !!state.isPressed && !state.isDisabled
46
+
47
+ return {
48
+ flexDirection: 'row',
49
+ alignItems: 'center',
50
+ gap: 12,
51
+ width: '100%',
52
+ paddingHorizontal: 14,
53
+ paddingVertical: 12,
54
+ backgroundColor: state.isSelected
55
+ ? semantic.background
56
+ : pressed
57
+ ? semantic.surfaceHover
58
+ : 'transparent',
59
+ borderLeftWidth: state.isSelected ? 4 : 0,
60
+ borderLeftColor: state.isSelected ? semantic.primary : 'transparent',
61
+ borderRadius: 6,
62
+ }
63
+ }
64
+
65
+ return {
66
+ conversationRow: {
67
+ container: createStyleResolver<ChatConversationRowState, ViewStyle>(resolveConversationRow),
68
+ title: createStyleResolver<ChatConversationRowState, TextStyle>((state) => ({
69
+ flex: 1,
70
+ color: semantic.onSurface,
71
+ fontSize: 16,
72
+ fontWeight: state.isUnread ? fontWeights.bold : fontWeights.medium,
73
+ })),
74
+ timestamp: createStyleResolver<ChatConversationRowState, TextStyle>((state) => ({
75
+ color: state.isUnread ? semantic.primary : semantic.description,
76
+ fontSize: 12,
77
+ fontWeight: state.isUnread ? fontWeights.medium : fontWeights.base,
78
+ flexShrink: 0,
79
+ })),
80
+ preview: createStyleResolver<ChatConversationRowState, TextStyle>((state) => ({
81
+ flex: 1,
82
+ color: state.isUnread ? semantic.onSurface : semantic.description,
83
+ fontSize: 14,
84
+ fontWeight: fontWeights.light,
85
+ })),
86
+ unreadBadge: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
87
+ minWidth: 20,
88
+ height: 20,
89
+ paddingHorizontal: 6,
90
+ borderRadius: 999,
91
+ backgroundColor: semantic.primary,
92
+ alignItems: 'center',
93
+ justifyContent: 'center',
94
+ })),
95
+ unreadBadgeText: createStyleResolver<Record<string, never>, TextStyle>(() => ({
96
+ color: semantic.onPrimary,
97
+ fontSize: 11,
98
+ fontWeight: fontWeights.bold,
99
+ })),
100
+ sentIndicator: createValueResolver<Record<string, never>, { color: Color }>(() => ({
101
+ color: semantic.primary,
102
+ })),
103
+ },
104
+ conversationList: {
105
+ container: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
106
+ flex: 1,
107
+ backgroundColor: semantic.surface,
108
+ })),
109
+ header: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
110
+ paddingHorizontal: 14,
111
+ paddingVertical: 14,
112
+ gap: 12,
113
+ })),
114
+ footer: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
115
+ paddingHorizontal: 14,
116
+ paddingVertical: 8,
117
+ })),
118
+ },
119
+ threadHeader: {
120
+ container: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
121
+ flexDirection: 'row',
122
+ alignItems: 'center',
123
+ gap: 12,
124
+ paddingHorizontal: 14,
125
+ paddingVertical: 12,
126
+ borderBottomWidth: StyleSheet.hairlineWidth,
127
+ borderBottomColor: component.divider,
128
+ backgroundColor: semantic.surface,
129
+ })),
130
+ title: createStyleResolver<Record<string, never>, TextStyle>(() => ({
131
+ color: semantic.onSurface,
132
+ fontSize: 16,
133
+ fontWeight: fontWeights.bold,
134
+ })),
135
+ subtitle: createStyleResolver<Record<string, never>, TextStyle>(() => ({
136
+ color: semantic.description,
137
+ fontSize: 12,
138
+ fontWeight: fontWeights.light,
139
+ })),
140
+ },
141
+ messageList: {
142
+ container: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
143
+ flex: 1,
144
+ paddingHorizontal: 16,
145
+ paddingVertical: 18,
146
+ gap: 12,
147
+ backgroundColor: semantic.background,
148
+ })),
149
+ },
150
+ messageBubble: {
151
+ container: createStyleResolver<ChatMessageBubbleState, ViewStyle>((state) => ({
152
+ maxWidth: 280,
153
+ gap: 4,
154
+ alignSelf: state.direction === 'outgoing' ? 'flex-end' : 'flex-start',
155
+ alignItems: state.direction === 'outgoing' ? 'flex-end' : 'flex-start',
156
+ })),
157
+ bubble: createStyleResolver<ChatMessageBubbleState, ViewStyle>((state) => {
158
+ const outgoing = state.direction === 'outgoing'
159
+ const radius = 12
160
+ const corner = 4
161
+
162
+ return {
163
+ paddingHorizontal: 15,
164
+ paddingVertical: 11,
165
+ backgroundColor: outgoing ? semantic.primary : semantic.neutral,
166
+ borderTopLeftRadius: radius,
167
+ borderTopRightRadius: radius,
168
+ borderBottomLeftRadius: outgoing ? radius : corner,
169
+ borderBottomRightRadius: outgoing ? corner : radius,
170
+ }
171
+ }),
172
+ content: createStyleResolver<ChatMessageBubbleState, TextStyle>((state) => ({
173
+ color: state.direction === 'outgoing' ? semantic.onPrimary : semantic.onNeutral,
174
+ fontSize: 16,
175
+ fontWeight: fontWeights.light,
176
+ lineHeight: 22.4,
177
+ })),
178
+ timestamp: createStyleResolver<ChatMessageBubbleState, TextStyle>((state) => ({
179
+ marginTop: 5,
180
+ color: state.direction === 'outgoing'
181
+ ? hexWithAlpha(semantic.onPrimary, 0.75)
182
+ : semantic.description,
183
+ fontSize: 11,
184
+ fontWeight: fontWeights.medium,
185
+ textAlign: 'right',
186
+ })),
187
+ receipt: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
188
+ flexDirection: 'row',
189
+ alignItems: 'center',
190
+ gap: 5,
191
+ })),
192
+ receiptText: createStyleResolver<Record<string, never>, TextStyle>(() => ({
193
+ color: semantic.description,
194
+ fontSize: 11,
195
+ fontWeight: fontWeights.medium,
196
+ })),
197
+ receiptIcon: createValueResolver<Record<string, never>, { color: Color }>(() => ({
198
+ color: semantic.primary,
199
+ })),
200
+ },
201
+ messageCard: {
202
+ container: createStyleResolver<ChatMessageCardState, ViewStyle>((state) => {
203
+ const outgoing = state.direction === 'outgoing'
204
+ const radius = 12
205
+ const corner = 4
206
+
207
+ return {
208
+ width: 290,
209
+ maxWidth: 300,
210
+ backgroundColor: semantic.surface,
211
+ borderWidth: 1,
212
+ borderColor: component.divider,
213
+ borderTopLeftRadius: radius,
214
+ borderTopRightRadius: radius,
215
+ borderBottomLeftRadius: outgoing ? radius : corner,
216
+ borderBottomRightRadius: outgoing ? corner : radius,
217
+ overflow: 'hidden',
218
+ alignSelf: outgoing ? 'flex-end' : 'flex-start',
219
+ }
220
+ }),
221
+ header: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
222
+ flexDirection: 'row',
223
+ alignItems: 'center',
224
+ gap: 10,
225
+ paddingHorizontal: 15,
226
+ paddingVertical: 12,
227
+ borderBottomWidth: StyleSheet.hairlineWidth,
228
+ borderBottomColor: component.divider,
229
+ })),
230
+ icon: createStyleResolver<ChatMessageCardState, ViewStyle>((state) => {
231
+ const color = state.color ?? 'primary'
232
+ const tokens = coloring[color]
233
+
234
+ return {
235
+ width: 36,
236
+ height: 36,
237
+ borderRadius: 6,
238
+ alignItems: 'center',
239
+ justifyContent: 'center',
240
+ backgroundColor: hexWithAlpha(tokens.tonalBackground ?? tokens.color, 0.2),
241
+ }
242
+ }),
243
+ iconColor: createValueResolver<ChatMessageCardState, { color: Color }>((state) => {
244
+ const color = state.color ?? 'primary'
245
+ const tokens = coloring[color]
246
+
247
+ return {
248
+ color: tokens.tonalText ?? tokens.color,
249
+ }
250
+ }),
251
+ title: createStyleResolver<ChatMessageCardState, TextStyle>((state) => {
252
+ const color = state.color ?? 'primary'
253
+ const tokens = coloring[color]
254
+
255
+ return {
256
+ color: tokens.text ?? tokens.color,
257
+ fontSize: 14,
258
+ fontWeight: fontWeights.bold,
259
+ }
260
+ }),
261
+ subtitle: createStyleResolver<Record<string, never>, TextStyle>(() => ({
262
+ color: semantic.description,
263
+ fontSize: 12,
264
+ })),
265
+ body: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
266
+ paddingHorizontal: 15,
267
+ paddingVertical: 12,
268
+ gap: 4,
269
+ })),
270
+ actions: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
271
+ flexDirection: 'row',
272
+ gap: 10,
273
+ paddingHorizontal: 15,
274
+ paddingBottom: 15,
275
+ })),
276
+ },
277
+ attachmentCard: {
278
+ container: createStyleResolver<ChatAttachmentCardState, ViewStyle>((state) => {
279
+ const outgoing = state.direction === 'outgoing'
280
+ const radius = 12
281
+ const corner = 4
282
+
283
+ return {
284
+ flexDirection: 'row',
285
+ alignItems: 'center',
286
+ gap: 12,
287
+ maxWidth: 280,
288
+ padding: 12,
289
+ backgroundColor: semantic.surface,
290
+ borderWidth: 1,
291
+ borderColor: component.divider,
292
+ borderTopLeftRadius: radius,
293
+ borderTopRightRadius: radius,
294
+ borderBottomLeftRadius: outgoing ? radius : corner,
295
+ borderBottomRightRadius: outgoing ? corner : radius,
296
+ alignSelf: outgoing ? 'flex-end' : 'flex-start',
297
+ }
298
+ }),
299
+ icon: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
300
+ width: 44,
301
+ height: 44,
302
+ borderRadius: 6,
303
+ alignItems: 'center',
304
+ justifyContent: 'center',
305
+ backgroundColor: hexWithAlpha(semantic.negative, 0.2),
306
+ })),
307
+ iconColor: createValueResolver<Record<string, never>, { color: Color }>(() => ({
308
+ color: semantic.negative,
309
+ })),
310
+ name: createStyleResolver<Record<string, never>, TextStyle>(() => ({
311
+ color: semantic.onSurface,
312
+ fontSize: 14,
313
+ fontWeight: fontWeights.medium,
314
+ })),
315
+ metadata: createStyleResolver<Record<string, never>, TextStyle>(() => ({
316
+ color: semantic.description,
317
+ fontSize: 12,
318
+ })),
319
+ },
320
+ systemLine: {
321
+ container: createStyleResolver<ChatSystemLineState, ViewStyle>(() => ({
322
+ flexDirection: 'row',
323
+ alignItems: 'center',
324
+ justifyContent: 'center',
325
+ alignSelf: 'center',
326
+ gap: 6,
327
+ })),
328
+ text: createStyleResolver<ChatSystemLineState, TextStyle>((state) => {
329
+ const color = state.color ?? 'primary'
330
+ const tokens = coloring[color]
331
+
332
+ return {
333
+ color: tokens.text ?? tokens.color,
334
+ fontSize: 12,
335
+ fontWeight: fontWeights.medium,
336
+ }
337
+ }),
338
+ icon: createValueResolver<ChatSystemLineState, { color: Color }>((state) => {
339
+ const color = state.color ?? 'primary'
340
+ const tokens = coloring[color]
341
+
342
+ return {
343
+ color: tokens.text ?? tokens.color,
344
+ }
345
+ }),
346
+ },
347
+ dateDivider: {
348
+ container: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
349
+ alignSelf: 'center',
350
+ paddingHorizontal: 14,
351
+ paddingVertical: 4,
352
+ borderRadius: 999,
353
+ backgroundColor: semantic.surface,
354
+ })),
355
+ text: createStyleResolver<Record<string, never>, TextStyle>(() => ({
356
+ color: semantic.description,
357
+ fontSize: 12,
358
+ fontWeight: fontWeights.medium,
359
+ })),
360
+ },
361
+ quickReplyChip: {
362
+ container: createStyleResolver<ChatQuickReplyChipState, ViewStyle>((state) => {
363
+ const pressed = !!state.isPressed && !state.isDisabled
364
+
365
+ return {
366
+ flexDirection: 'row',
367
+ alignItems: 'center',
368
+ alignSelf: 'flex-start',
369
+ gap: 6,
370
+ paddingHorizontal: 14,
371
+ paddingVertical: 6,
372
+ borderRadius: 999,
373
+ borderWidth: 1,
374
+ borderColor: state.isActive ? semantic.primary : component.divider,
375
+ backgroundColor: pressed ? semantic.surfaceHover : semantic.surface,
376
+ }
377
+ }),
378
+ text: createStyleResolver<ChatQuickReplyChipState, TextStyle>((state) => ({
379
+ color: state.isActive ? semantic.primary : semantic.description,
380
+ fontSize: 14,
381
+ fontWeight: fontWeights.medium,
382
+ })),
383
+ },
384
+ messageComposer: {
385
+ container: createStyleResolver<Record<string, never>, ViewStyle>(() => ({
386
+ flexDirection: 'row',
387
+ alignItems: 'flex-end',
388
+ width: '100%',
389
+ gap: 8,
390
+ paddingHorizontal: 14,
391
+ paddingVertical: 12,
392
+ backgroundColor: semantic.surface,
393
+ borderTopWidth: StyleSheet.hairlineWidth,
394
+ borderTopColor: component.divider,
395
+ })),
396
+ input: createStyleResolver<Record<string, never>, TextStyle>(() => ({
397
+ flex: 1,
398
+ minHeight: 44,
399
+ maxHeight: 44 * 7,
400
+ paddingHorizontal: 12,
401
+ paddingVertical: 12,
402
+ borderRadius: 6,
403
+ backgroundColor: semantic.surfaceVariant,
404
+ color: semantic.onSurface,
405
+ fontSize: 15,
406
+ })),
407
+ placeholderColor: createValueResolver<Record<string, never>, Color>(() => semantic.placeholder),
408
+ },
409
+ }
410
+ }
411
+
412
+ export const createChatThemeFromDesign = (theme: DesignTokensTheme): ChatTheme => {
413
+ return createChatTheme({
414
+ semantic: theme.semanticColors,
415
+ component: theme.componentColors,
416
+ coloring: theme.coloring as HightideComponentThemes['coloring'],
417
+ })
418
+ }
@@ -1,22 +1,27 @@
1
- import {
2
- remToPx,
3
- spacing,
4
- type ComponentColors,
5
- type DesignTheme as DesignTokensTheme,
6
- type ElementSize,
7
- type SemanticColors
8
- } from '@helpwave/hightide-design'
1
+ import type { ViewStyle } from 'react-native'
2
+
3
+ import { componentLayouts } from '@helpwave/hightide-design/tokens'
4
+ import type {
5
+ ComponentColorTokens,
6
+ HightideDesignTokens as DesignTokensTheme,
7
+ ElementSize
8
+ } from '@helpwave/hightide-design/types'
9
+
10
+ import type { HightideSemanticColors } from '@/src/theme/types/color'
9
11
  import type {
10
12
  CheckboxSize,
11
13
  CheckboxState,
12
- CheckboxStyle,
13
14
  CheckboxTheme
14
- } from '../types'
15
+ } from '@/src/theme/types/components/checkbox'
16
+ import {
17
+ createStyleResolver,
18
+ createValueResolver
19
+ } from '@/src/theme/types/resolver'
15
20
 
16
21
  const checkboxSizes: Record<CheckboxSize, number> = {
17
- sm: remToPx('1.25rem'),
18
- md: remToPx('1.5rem'),
19
- lg: remToPx('2rem'),
22
+ sm: 20,
23
+ md: 24,
24
+ lg: 32,
20
25
  }
21
26
 
22
27
  const checkboxIconSizes: Record<CheckboxSize, Exclude<ElementSize, 'xs'>> = {
@@ -26,8 +31,8 @@ const checkboxIconSizes: Record<CheckboxSize, Exclude<ElementSize, 'xs'>> = {
26
31
  }
27
32
 
28
33
  export type CreateCheckboxThemeOptions = {
29
- semantic: SemanticColors,
30
- component: ComponentColors,
34
+ semantic: HightideSemanticColors,
35
+ component: ComponentColorTokens,
31
36
  }
32
37
 
33
38
  export const createCheckboxTheme = ({
@@ -50,12 +55,12 @@ export const createCheckboxTheme = ({
50
55
  ? semantic.disabled
51
56
  : (isActive ? semantic.primary : component.input.background)
52
57
 
53
- const checkbox: CheckboxStyle = {
58
+ const checkbox: ViewStyle = {
54
59
  width: dimension,
55
60
  height: dimension,
56
61
  alignItems: 'center',
57
62
  justifyContent: 'center',
58
- borderWidth: remToPx(spacing.coloringOutlineWidth),
63
+ borderWidth: componentLayouts.shared.coloringOutlineWidth,
59
64
  borderColor,
60
65
  borderRadius: state.isRounded ? dimension / 2 : 6,
61
66
  backgroundColor,
@@ -73,14 +78,14 @@ export const createCheckboxTheme = ({
73
78
  }
74
79
 
75
80
  return {
76
- checkbox: (state) => resolveState(state).checkbox,
77
- icon: (state) => resolveState(state).icon,
81
+ checkbox: createStyleResolver((state) => resolveState(state).checkbox),
82
+ icon: createValueResolver((state) => resolveState(state).icon),
78
83
  }
79
84
  }
80
85
 
81
86
  export const createCheckboxThemeFromDesign = (theme: DesignTokensTheme): CheckboxTheme => {
82
87
  return createCheckboxTheme({
83
- semantic: theme.semantic,
84
- component: theme.component,
88
+ semantic: theme.semanticColors,
89
+ component: theme.componentColors,
85
90
  })
86
91
  }
@@ -1,16 +1,26 @@
1
+ import type {
2
+ TextStyle,
3
+ ViewStyle
4
+ } from 'react-native'
5
+
1
6
  import {
2
7
  componentLayouts,
3
- toPx,
4
- type ColoringTokensDefinitions,
5
- type DesignTheme as DesignTokensTheme,
6
- type SemanticColors
7
- } from '@helpwave/hightide-design'
8
- import type { ChipState, ChipStyle, ChipTextStyle, ChipTheme } from '../types'
9
- import { resolveColoringStyles } from './coloring'
8
+ fontWeights
9
+ } from '@helpwave/hightide-design/tokens'
10
+ import type { HightideDesignTokens as DesignTokensTheme } from '@helpwave/hightide-design/types'
11
+
12
+ import { resolveColoringStyles } from '@/src/theme/resolvers/coloring'
13
+ import type { HightideSemanticColors } from '@/src/theme/types/color'
14
+ import type {
15
+ ChipState,
16
+ ChipTheme
17
+ } from '@/src/theme/types/components/chip'
18
+ import type { HightideComponentThemes } from '@/src/theme/types/components/hightide'
19
+ import { createStyleResolver } from '@/src/theme/types/resolver'
10
20
 
11
21
  export type CreateChipThemeOptions = {
12
- semantic: SemanticColors,
13
- coloring: ColoringTokensDefinitions,
22
+ semantic: HightideSemanticColors,
23
+ coloring: HightideComponentThemes['coloring'],
14
24
  }
15
25
 
16
26
  export const createChipTheme = ({
@@ -25,7 +35,7 @@ export const createChipTheme = ({
25
35
  const resolved = resolveColoringStyles(tokens, coloringStyle, semantic, state)
26
36
  const layout = componentLayouts.chip[size]
27
37
 
28
- const chip: ChipStyle = {
38
+ const chip: ViewStyle = {
29
39
  flexDirection: 'row',
30
40
  alignItems: 'center',
31
41
  justifyContent: 'center',
@@ -33,32 +43,32 @@ export const createChipTheme = ({
33
43
  backgroundColor: resolved.backgroundColor,
34
44
  borderColor: resolved.borderColor,
35
45
  borderWidth: resolved.borderWidth,
36
- paddingVertical: toPx(layout.paddingVertical),
37
- paddingHorizontal: toPx(layout.paddingHorizontal),
38
- gap: toPx(layout.gap),
39
- minHeight: toPx(layout.minHeight),
40
- borderRadius: toPx(layout.borderRadius),
46
+ paddingVertical: layout.paddingVertical,
47
+ paddingHorizontal: layout.paddingHorizontal,
48
+ gap: layout.gap,
49
+ minHeight: layout.minHeight,
50
+ borderRadius: layout.borderRadius,
41
51
  opacity: state.isDisabled ? 0.6 : 1,
42
52
  }
43
53
 
44
- const text: ChipTextStyle = {
54
+ const text: TextStyle = {
45
55
  color: resolved.color,
46
- fontSize: toPx(layout.fontSize),
47
- fontWeight: '600',
56
+ fontSize: layout.fontSize,
57
+ fontWeight: fontWeights.semibold,
48
58
  }
49
59
 
50
60
  return { chip, text }
51
61
  }
52
62
 
53
63
  return {
54
- chip: (state) => resolveState(state).chip,
55
- text: (state) => resolveState(state).text,
64
+ chip: createStyleResolver((state) => resolveState(state).chip),
65
+ text: createStyleResolver((state) => resolveState(state).text),
56
66
  }
57
67
  }
58
68
 
59
69
  export const createChipThemeFromDesign = (theme: DesignTokensTheme): ChipTheme => {
60
70
  return createChipTheme({
61
- semantic: theme.semantic,
62
- coloring: theme.coloring,
71
+ semantic: theme.semanticColors,
72
+ coloring: theme.coloring as HightideComponentThemes['coloring'],
63
73
  })
64
74
  }
@@ -1,20 +1,24 @@
1
1
  import {
2
- componentLayouts,
3
- hexWithAlpha,
4
- toPx,
5
- type ButtonColoringStyle,
6
- type ChipColoringStyle,
7
- type ColorValue,
8
- type ColoringToken,
9
- type ColoringStyle,
10
- type SemanticColors
11
- } from '@helpwave/hightide-design'
12
- import type { InteractionState } from '../types'
2
+ hexWithAlpha
3
+ } from '@helpwave/hightide-design/helpers'
4
+ import { componentLayouts } from '@helpwave/hightide-design/tokens'
5
+ import type {
6
+ ButtonColoringStyle,
7
+ ChipColoringStyle,
8
+ ColoringStyle
9
+ } from '@helpwave/hightide-design/types'
10
+
11
+ import type {
12
+ Color,
13
+ HightideSemanticColors
14
+ } from '@/src/theme/types/color'
15
+ import type { ColoringDefinition } from '@/src/theme/types/components/hightide'
16
+ import type { InteractionState } from '@/src/theme/types/resolver'
13
17
 
14
18
  export type ResolvedColoringStyles = {
15
- backgroundColor: ColorValue | 'transparent',
16
- color: ColorValue,
17
- borderColor?: ColorValue,
19
+ backgroundColor: Color | 'transparent',
20
+ color: Color,
21
+ borderColor?: Color,
18
22
  borderWidth: number,
19
23
  }
20
24
 
@@ -23,12 +27,12 @@ const usesHover = (state: InteractionState): boolean => {
23
27
  }
24
28
 
25
29
  export const resolveColoringStyles = (
26
- tokens: ColoringToken,
30
+ tokens: ColoringDefinition,
27
31
  coloringStyle: ColoringStyle,
28
- semantic: SemanticColors,
32
+ semantic: HightideSemanticColors,
29
33
  state: InteractionState = {}
30
34
  ): ResolvedColoringStyles => {
31
- const outlineWidth = toPx(componentLayouts.shared.coloringOutlineWidth)
35
+ const outlineWidth = componentLayouts.shared.coloringOutlineWidth
32
36
  const hovered = usesHover(state)
33
37
 
34
38
  if (state.isDisabled) {