@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.
Files changed (40) hide show
  1. package/package.json +3 -3
  2. package/src/components/chat/ChatMessageCard.tsx +1 -1
  3. package/src/components/chat/ChatSystemLine.tsx +1 -1
  4. package/src/components/user-interaction/Button.tsx +1 -1
  5. package/src/components/user-interaction/IconButton.tsx +1 -1
  6. package/src/components/user-interaction/Switch.tsx +177 -0
  7. package/src/components/user-interaction/index.ts +1 -0
  8. package/src/components/visualization-and-display/Avatar.tsx +286 -0
  9. package/src/components/visualization-and-display/Chip.tsx +1 -1
  10. package/src/components/visualization-and-display/index.ts +1 -0
  11. package/src/global-contexts/hightide-config/HightideConfigUtils.ts +3 -3
  12. package/src/global-contexts/theme/ThemeContext.ts +2 -2
  13. package/src/global-contexts/theme/ThemeProvider.tsx +3 -3
  14. package/src/theme/resolvers/avatar.ts +231 -0
  15. package/src/theme/resolvers/button.ts +1 -1
  16. package/src/theme/resolvers/chat.ts +2 -2
  17. package/src/theme/resolvers/checkbox.ts +1 -1
  18. package/src/theme/resolvers/chip.ts +1 -1
  19. package/src/theme/resolvers/coloring.ts +1 -1
  20. package/src/theme/resolvers/iconButton.ts +1 -1
  21. package/src/theme/resolvers/index.ts +2 -0
  22. package/src/theme/resolvers/input.ts +1 -1
  23. package/src/theme/resolvers/menu.ts +1 -1
  24. package/src/theme/resolvers/multiSelect.ts +1 -1
  25. package/src/theme/resolvers/select.ts +1 -1
  26. package/src/theme/resolvers/switch.ts +65 -0
  27. package/src/theme/themes/{createTheme.ts → createHightideTheme.ts} +8 -4
  28. package/src/theme/themes/hightideThemes.ts +14 -0
  29. package/src/theme/themes/index.ts +2 -2
  30. package/src/theme/types/components/avatar.ts +77 -0
  31. package/src/theme/types/components/button.ts +1 -1
  32. package/src/theme/types/components/chat.ts +1 -1
  33. package/src/theme/types/components/chip.ts +1 -1
  34. package/src/theme/types/components/hightide.ts +4 -0
  35. package/src/theme/types/components/iconButton.ts +1 -1
  36. package/src/theme/types/components/index.ts +2 -0
  37. package/src/theme/types/components/switch.ts +15 -0
  38. package/src/theme/types/layout.ts +12 -0
  39. package/src/theme/types/theme.ts +15 -6
  40. package/src/theme/themes/nativeThemes.ts +0 -16
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "access": "public"
11
11
  },
12
12
  "license": "AGPL-3.0-only",
13
- "version": "0.0.6",
13
+ "version": "0.0.8",
14
14
  "type": "module",
15
15
  "files": [
16
16
  "src"
@@ -43,8 +43,8 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "lucide-react-native": "0.561.0",
46
- "@helpwave/hightide-design": "0.0.4",
47
- "@helpwave/hightide-utils": "0.0.4"
46
+ "@helpwave/hightide-design": "0.0.6",
47
+ "@helpwave/hightide-utils": "0.0.5"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "@react-native-async-storage/async-storage": ">=2.0.0",
@@ -10,7 +10,7 @@ import {
10
10
  type ViewStyle
11
11
  } from 'react-native'
12
12
 
13
- import type { ColoringType } from '@helpwave/hightide-design/helpers'
13
+ import type { ColoringType } from '@helpwave/hightide-design/utils'
14
14
 
15
15
  import { useTheme } from '../../global-contexts/theme/ThemeContext'
16
16
  import type {
@@ -11,7 +11,7 @@ import {
11
11
  } from 'react-native'
12
12
  import { CheckCheck } from 'lucide-react-native'
13
13
 
14
- import type { ColoringType } from '@helpwave/hightide-design/helpers'
14
+ import type { ColoringType } from '@helpwave/hightide-design/utils'
15
15
 
16
16
  import { useTheme } from '../../global-contexts/theme/ThemeContext'
17
17
  import type {
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  coloringTypes,
15
15
  type ColoringType
16
- } from '@helpwave/hightide-design/helpers'
16
+ } from '@helpwave/hightide-design/utils'
17
17
  import type {
18
18
  ButtonColoringStyle,
19
19
  ElementSize
@@ -10,7 +10,7 @@ import {
10
10
  } from 'react-native'
11
11
  import type { LucideIcon } from 'lucide-react-native'
12
12
 
13
- import type { ColoringType } from '@helpwave/hightide-design/helpers'
13
+ import type { ColoringType } from '@helpwave/hightide-design/utils'
14
14
  import type {
15
15
  ButtonColoringStyle,
16
16
  ElementSize
@@ -0,0 +1,177 @@
1
+ import {
2
+ useCallback,
3
+ useEffect,
4
+ useMemo,
5
+ useRef
6
+ } from 'react'
7
+ import {
8
+ Animated,
9
+ Pressable,
10
+ View,
11
+ type PressableProps,
12
+ type StyleProp,
13
+ type ViewStyle
14
+ } from 'react-native'
15
+
16
+ import {
17
+ useControlledState,
18
+ useEventCallbackStabilizer
19
+ } from '@helpwave/hightide-utils/hooks'
20
+
21
+ import { useTheme } from '../../global-contexts/theme/ThemeContext'
22
+ import type { SwitchState } from '../../theme/types/components/switch'
23
+ import type { StyleOverwrite } from '../../theme/types/resolver'
24
+ import type { Color } from '../../theme/types/color'
25
+ import type {
26
+ FormFieldDataHandling,
27
+ FormFieldInteractionStates
28
+ } from '../../types/formField'
29
+
30
+ const TRACK_WIDTH = 48
31
+ const TRACK_HEIGHT = 28
32
+ const TRACK_BORDER_WIDTH = 2
33
+ const TRACK_PADDING = 4
34
+ const THUMB_SIZE_INACTIVE = 12
35
+ const THUMB_SIZE_ACTIVE = 16
36
+ const THUMB_OFFSET_INACTIVE = 2
37
+ const ANIMATION_DURATION_MS = 250
38
+
39
+ const TRACK_INNER_WIDTH = TRACK_WIDTH - (TRACK_BORDER_WIDTH * 2) - (TRACK_PADDING * 2)
40
+ const TRACK_INNER_HEIGHT = TRACK_HEIGHT - (TRACK_BORDER_WIDTH * 2) - (TRACK_PADDING * 2)
41
+ const THUMB_OFFSET_ACTIVE = TRACK_INNER_WIDTH - THUMB_SIZE_ACTIVE
42
+ const THUMB_TOP_INACTIVE = (TRACK_INNER_HEIGHT - THUMB_SIZE_INACTIVE) / 2
43
+ const THUMB_TOP_ACTIVE = (TRACK_INNER_HEIGHT - THUMB_SIZE_ACTIVE) / 2
44
+
45
+ export type SwitchProps = Omit<PressableProps, 'children' | 'style' | 'disabled'>
46
+ & Partial<FormFieldInteractionStates>
47
+ & Partial<FormFieldDataHandling<boolean>>
48
+ & {
49
+ initialValue?: boolean,
50
+ style?: StyleProp<ViewStyle>,
51
+ trackColorStyle?: StyleOverwrite<SwitchState, Color>,
52
+ borderColorStyle?: StyleOverwrite<SwitchState, Color>,
53
+ thumbColorStyle?: StyleOverwrite<SwitchState, Color>,
54
+ }
55
+
56
+ export const Switch = ({
57
+ value: controlledValue,
58
+ initialValue = false,
59
+ invalid = false,
60
+ disabled = false,
61
+ readOnly = false,
62
+ onValueChange,
63
+ onEditComplete,
64
+ style,
65
+ trackColorStyle,
66
+ borderColorStyle,
67
+ thumbColorStyle,
68
+ accessibilityLabel,
69
+ ...props
70
+ }: SwitchProps) => {
71
+ const { theme } = useTheme()
72
+ const interactive = !disabled && !readOnly
73
+
74
+ const onEditCompleteStable = useEventCallbackStabilizer(onEditComplete)
75
+ const onValueChangeStable = useEventCallbackStabilizer(onValueChange)
76
+
77
+ const onChangeWrapper = useCallback((nextValue: boolean) => {
78
+ onValueChangeStable(nextValue)
79
+ onEditCompleteStable(nextValue)
80
+ }, [onEditCompleteStable, onValueChangeStable])
81
+
82
+ const [value, setValue] = useControlledState({
83
+ value: controlledValue,
84
+ onValueChange: onChangeWrapper,
85
+ defaultValue: initialValue,
86
+ })
87
+
88
+ const state = useMemo((): SwitchState => ({
89
+ isActive: value,
90
+ isInvalid: invalid,
91
+ isDisabled: disabled,
92
+ isReadOnly: readOnly,
93
+ }), [disabled, invalid, readOnly, value])
94
+
95
+ const trackColor = useMemo(
96
+ () => theme.components.switch.trackColor(state, trackColorStyle),
97
+ [theme, state, trackColorStyle]
98
+ )
99
+ const borderColor = useMemo(
100
+ () => theme.components.switch.borderColor(state, borderColorStyle),
101
+ [theme, state, borderColorStyle]
102
+ )
103
+ const thumbColor = useMemo(
104
+ () => theme.components.switch.thumbColor(state, thumbColorStyle),
105
+ [theme, state, thumbColorStyle]
106
+ )
107
+
108
+ const progress = useRef(new Animated.Value(value ? 1 : 0)).current
109
+
110
+ useEffect(() => {
111
+ Animated.timing(progress, {
112
+ toValue: value ? 1 : 0,
113
+ duration: ANIMATION_DURATION_MS,
114
+ useNativeDriver: false,
115
+ }).start()
116
+ }, [progress, value])
117
+
118
+ const thumbSize = progress.interpolate({
119
+ inputRange: [0, 1],
120
+ outputRange: [THUMB_SIZE_INACTIVE, THUMB_SIZE_ACTIVE],
121
+ })
122
+ const thumbTranslateX = progress.interpolate({
123
+ inputRange: [0, 1],
124
+ outputRange: [THUMB_OFFSET_INACTIVE, THUMB_OFFSET_ACTIVE],
125
+ })
126
+ const thumbTop = progress.interpolate({
127
+ inputRange: [0, 1],
128
+ outputRange: [THUMB_TOP_INACTIVE, THUMB_TOP_ACTIVE],
129
+ })
130
+
131
+ return (
132
+ <Pressable
133
+ {...props}
134
+ disabled={!interactive}
135
+ accessibilityRole="switch"
136
+ accessibilityLabel={accessibilityLabel}
137
+ accessibilityState={{
138
+ checked: value,
139
+ disabled,
140
+ }}
141
+ onPress={(event) => {
142
+ if (interactive) {
143
+ setValue((previous) => !previous)
144
+ }
145
+ props.onPress?.(event)
146
+ }}
147
+ style={style}
148
+ >
149
+ <View
150
+ style={{
151
+ width: TRACK_WIDTH,
152
+ height: TRACK_HEIGHT,
153
+ borderRadius: TRACK_HEIGHT / 2,
154
+ borderWidth: TRACK_BORDER_WIDTH,
155
+ borderColor,
156
+ backgroundColor: trackColor,
157
+ padding: TRACK_PADDING,
158
+ opacity: disabled ? 0.6 : 1,
159
+ }}
160
+ >
161
+ <View style={{ flex: 1 }}>
162
+ <Animated.View
163
+ style={{
164
+ position: 'absolute',
165
+ top: thumbTop,
166
+ width: thumbSize,
167
+ height: thumbSize,
168
+ borderRadius: THUMB_SIZE_ACTIVE / 2,
169
+ backgroundColor: thumbColor,
170
+ transform: [{ translateX: thumbTranslateX }],
171
+ }}
172
+ />
173
+ </View>
174
+ </View>
175
+ </Pressable>
176
+ )
177
+ }
@@ -4,3 +4,4 @@ export * from './IconButton'
4
4
  export * from './Input'
5
5
  export * from './MultiSelect'
6
6
  export * from './Select'
7
+ export * from './Switch'
@@ -0,0 +1,286 @@
1
+ import {
2
+ useEffect,
3
+ useMemo,
4
+ useState,
5
+ type ComponentType,
6
+ type ReactNode
7
+ } from 'react'
8
+ import {
9
+ Image,
10
+ Text,
11
+ View,
12
+ type ImageProps,
13
+ type StyleProp,
14
+ type ViewProps,
15
+ type ViewStyle
16
+ } from 'react-native'
17
+ import { User } from 'lucide-react-native'
18
+
19
+ import type { ElementSize } from '@helpwave/hightide-design/types'
20
+
21
+ import { useTheme } from '../../global-contexts/theme/ThemeContext'
22
+ import type {
23
+ AvatarGroupMoreStyle,
24
+ AvatarGroupStackStyle,
25
+ AvatarImageStyle,
26
+ AvatarIconStyle,
27
+ AvatarStatus,
28
+ AvatarStyle,
29
+ AvatarTextStyle,
30
+ AvatarWithLabelContainerStyle,
31
+ AvatarWithLabelTextStyle,
32
+ AvatarWithStatusContainerStyle,
33
+ AvatarStatusDotStyle
34
+ } from '../../theme/types/components/avatar'
35
+ import type { StyleOverwrite } from '../../theme/types/resolver'
36
+
37
+ export type AvatarSize = ElementSize
38
+
39
+ type ImageConfig = {
40
+ avatarUrl: string,
41
+ alt: string,
42
+ }
43
+
44
+ export type AvatarImageProps = Omit<ImageProps, 'source'> & {
45
+ source: { uri: string },
46
+ alt?: string,
47
+ }
48
+
49
+ const DefaultAvatarImage: ComponentType<AvatarImageProps> = ({ alt, ...props }) => (
50
+ <Image
51
+ {...props}
52
+ accessibilityLabel={alt}
53
+ />
54
+ )
55
+
56
+ export const AvatarUtil = {
57
+ sizes: ['xs', 'sm', 'md', 'lg'] as const satisfies readonly ElementSize[],
58
+ statuses: ['online', 'offline', 'away', 'busy', 'unknown'] as const satisfies readonly AvatarStatus[],
59
+ }
60
+
61
+ export type AvatarProps = Omit<ViewProps, 'children' | 'style'> & {
62
+ image?: ImageConfig,
63
+ name?: string,
64
+ size?: AvatarSize,
65
+ ImageComponent?: ComponentType<AvatarImageProps>,
66
+ style?: StyleProp<ViewStyle>,
67
+ avatarStyle?: StyleOverwrite<{ size?: ElementSize, isGrouped?: boolean, groupIndex?: number }, AvatarStyle>,
68
+ imageStyle?: StyleOverwrite<{ size?: ElementSize, isGrouped?: boolean, groupIndex?: number }, AvatarImageStyle>,
69
+ textStyle?: StyleOverwrite<{ size?: ElementSize, isGrouped?: boolean, groupIndex?: number }, AvatarTextStyle>,
70
+ iconStyle?: StyleOverwrite<{ size?: ElementSize, isGrouped?: boolean, groupIndex?: number }, AvatarIconStyle>,
71
+ isGrouped?: boolean,
72
+ groupIndex?: number,
73
+ }
74
+
75
+ export const Avatar = ({
76
+ image: initialImage,
77
+ name,
78
+ size = 'md',
79
+ ImageComponent = DefaultAvatarImage,
80
+ style,
81
+ avatarStyle,
82
+ imageStyle,
83
+ textStyle,
84
+ iconStyle,
85
+ isGrouped = false,
86
+ groupIndex,
87
+ ...props
88
+ }: AvatarProps) => {
89
+ const { theme } = useTheme()
90
+ const [hasError, setHasError] = useState(false)
91
+ const [hasLoaded, setHasLoaded] = useState(false)
92
+ const [image, setImage] = useState(initialImage)
93
+ const ImageElement = ImageComponent
94
+
95
+ const state = useMemo(() => ({
96
+ size,
97
+ isGrouped,
98
+ groupIndex,
99
+ }), [size, isGrouped, groupIndex])
100
+
101
+ const displayName = useMemo(() => {
102
+ const maxLetters = size === 'sm' ? 1 : 2
103
+ return (name ?? '')
104
+ .split(' ')
105
+ .filter((_, index) => index < maxLetters)
106
+ .map(value => value[0])
107
+ .join('')
108
+ .toUpperCase()
109
+ }, [name, size])
110
+
111
+ const isShowingImage = !!image && (!hasError || !hasLoaded)
112
+ const isShowingFallback = !hasLoaded || hasError
113
+
114
+ useEffect(() => {
115
+ if (initialImage?.avatarUrl !== image?.avatarUrl) {
116
+ setHasError(false)
117
+ setHasLoaded(false)
118
+ }
119
+ setImage(initialImage)
120
+ }, [image?.avatarUrl, initialImage])
121
+
122
+ const resolvedAvatar = theme.components.avatar.avatar(state, avatarStyle)
123
+ const resolvedImage = theme.components.avatar.image(state, imageStyle)
124
+ const resolvedText = theme.components.avatar.text(state, textStyle)
125
+ const resolvedIcon = theme.components.avatar.icon(state, iconStyle)
126
+
127
+ return (
128
+ <View
129
+ {...props}
130
+ style={[resolvedAvatar, style]}
131
+ >
132
+ {isShowingImage && (
133
+ <ImageElement
134
+ key={image?.avatarUrl}
135
+ source={{ uri: image?.avatarUrl ?? '' }}
136
+ alt={image?.alt}
137
+ style={[resolvedImage, { opacity: hasLoaded && !hasError ? 1 : 0 }]}
138
+ onLoad={() => setHasLoaded(true)}
139
+ onError={() => setHasError(true)}
140
+ />
141
+ )}
142
+ {isShowingFallback && (
143
+ name ? (
144
+ <Text style={resolvedText}>{displayName}</Text>
145
+ ) : (
146
+ <User
147
+ size={resolvedIcon.size}
148
+ strokeWidth={resolvedIcon.strokeWidth}
149
+ color={resolvedIcon.color}
150
+ />
151
+ )
152
+ )}
153
+ </View>
154
+ )
155
+ }
156
+
157
+ export type AvatarGroupProps = Omit<ViewProps, 'children' | 'style'> & {
158
+ avatars: Omit<AvatarProps, 'size' | 'isGrouped' | 'groupIndex'>[],
159
+ showTotalNumber?: boolean,
160
+ size?: AvatarSize,
161
+ ImageComponent?: ComponentType<AvatarImageProps>,
162
+ style?: StyleProp<ViewStyle>,
163
+ stackStyle?: StyleOverwrite<{ size?: ElementSize, count?: number }, AvatarGroupStackStyle>,
164
+ moreStyle?: StyleOverwrite<{ size?: ElementSize, count?: number }, AvatarGroupMoreStyle>,
165
+ }
166
+
167
+ export const AvatarGroup = ({
168
+ avatars,
169
+ showTotalNumber = true,
170
+ size = 'md',
171
+ ImageComponent,
172
+ style,
173
+ stackStyle,
174
+ moreStyle,
175
+ ...props
176
+ }: AvatarGroupProps) => {
177
+ const { theme } = useTheme()
178
+ const maxShownProfiles = theme.layout.avatarGroup.maxShown
179
+ const displayedProfiles = avatars.length < maxShownProfiles ? avatars : avatars.slice(0, maxShownProfiles)
180
+ const notDisplayedProfiles = avatars.length - maxShownProfiles
181
+
182
+ const state = useMemo(() => ({
183
+ size,
184
+ count: displayedProfiles.length,
185
+ }), [size, displayedProfiles.length])
186
+
187
+ const resolvedContainer = theme.components.avatar.group.container(state)
188
+ const resolvedStack = theme.components.avatar.group.stack(state, stackStyle)
189
+ const resolvedMore = theme.components.avatar.group.more(state, moreStyle)
190
+
191
+ return (
192
+ <View
193
+ {...props}
194
+ style={[resolvedContainer, style]}
195
+ >
196
+ <View style={resolvedStack}>
197
+ {displayedProfiles.map((avatar, index) => (
198
+ <Avatar
199
+ {...avatar}
200
+ key={index}
201
+ size={size}
202
+ isGrouped
203
+ groupIndex={index}
204
+ ImageComponent={avatar.ImageComponent ?? ImageComponent}
205
+ />
206
+ ))}
207
+ </View>
208
+ {showTotalNumber && notDisplayedProfiles > 0 && (
209
+ <Text style={resolvedMore}>
210
+ {`+ ${notDisplayedProfiles}`}
211
+ </Text>
212
+ )}
213
+ </View>
214
+ )
215
+ }
216
+
217
+ export type { AvatarStatus }
218
+
219
+ export type AvatarWithStatusProps = AvatarProps & {
220
+ status?: AvatarStatus,
221
+ containerStyle?: StyleOverwrite<{ size?: ElementSize, status?: AvatarStatus }, AvatarWithStatusContainerStyle>,
222
+ statusDotStyle?: StyleOverwrite<{ size?: ElementSize, status?: AvatarStatus }, AvatarStatusDotStyle>,
223
+ }
224
+
225
+ export const AvatarWithStatus = ({
226
+ status = 'unknown',
227
+ size = 'md',
228
+ style,
229
+ containerStyle,
230
+ statusDotStyle,
231
+ ...avatarProps
232
+ }: AvatarWithStatusProps) => {
233
+ const { theme } = useTheme()
234
+
235
+ const state = useMemo(() => ({
236
+ size,
237
+ status,
238
+ }), [size, status])
239
+
240
+ const resolvedContainer = theme.components.avatar.withStatus.container(state, containerStyle)
241
+ const resolvedStatusDot = theme.components.avatar.withStatus.statusDot(state, statusDotStyle)
242
+
243
+ return (
244
+ <View style={[resolvedContainer, style]}>
245
+ <Avatar {...avatarProps} size={size} />
246
+ <View style={resolvedStatusDot} />
247
+ </View>
248
+ )
249
+ }
250
+
251
+ type AvatarWithLabelPosition = 'left' | 'right'
252
+
253
+ export type AvatarWithLabelProps = AvatarProps & {
254
+ label: ReactNode,
255
+ labelPosition?: AvatarWithLabelPosition,
256
+ containerStyle?: StyleOverwrite<{ size?: ElementSize }, AvatarWithLabelContainerStyle>,
257
+ labelStyle?: StyleOverwrite<{ size?: ElementSize }, AvatarWithLabelTextStyle>,
258
+ }
259
+
260
+ export const AvatarWithLabel = ({
261
+ label,
262
+ labelPosition = 'left',
263
+ size = 'md',
264
+ style,
265
+ containerStyle,
266
+ labelStyle,
267
+ ...avatarProps
268
+ }: AvatarWithLabelProps) => {
269
+ const { theme } = useTheme()
270
+
271
+ const state = useMemo(() => ({ size }), [size])
272
+ const resolvedContainer = theme.components.avatar.withLabel.container(state, containerStyle)
273
+ const resolvedLabel = theme.components.avatar.withLabel.text(state, labelStyle)
274
+
275
+ const avatar = <Avatar {...avatarProps} size={size} />
276
+ const labelElement = typeof label === 'string' || typeof label === 'number'
277
+ ? <Text style={resolvedLabel}>{label}</Text>
278
+ : label
279
+
280
+ return (
281
+ <View style={[resolvedContainer, style]}>
282
+ {labelPosition === 'left' ? labelElement : avatar}
283
+ {labelPosition === 'left' ? avatar : labelElement}
284
+ </View>
285
+ )
286
+ }
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  coloringTypes,
15
15
  type ColoringType
16
- } from '@helpwave/hightide-design/helpers'
16
+ } from '@helpwave/hightide-design/utils'
17
17
  import type {
18
18
  ChipColoringStyle,
19
19
  ElementSize
@@ -1,2 +1,3 @@
1
+ export * from './Avatar'
1
2
  export * from './Chip'
2
3
  export * from './Icon'
@@ -1,8 +1,8 @@
1
1
  import type { SupportedThemesConfig } from '@helpwave/hightide-utils/context'
2
2
 
3
3
  import type { SupportedLocalesConfig } from '../localization/forward-exports'
4
- import { themes } from '../../theme/themes/nativeThemes'
5
- import type { Theme } from '../../theme/types/theme'
4
+ import { themes } from '../../theme/themes/hightideThemes'
5
+ import type { HightideTheme } from '../../theme/types/theme'
6
6
 
7
7
  export const HightideConfigUtils = {
8
8
  defaultSupportedLocales: {
@@ -24,5 +24,5 @@ export const HightideConfigUtils = {
24
24
  },
25
25
  theme: themes.dark,
26
26
  },
27
- } as const satisfies SupportedThemesConfig<Theme>,
27
+ } as const satisfies SupportedThemesConfig<HightideTheme>,
28
28
  }
@@ -7,11 +7,11 @@ import type {
7
7
  ThemeConfigValue,
8
8
  ThemeInformation
9
9
  } from './forward-exports'
10
- import type { Theme } from '../../theme/types/theme'
10
+ import type { HightideTheme } from '../../theme/types/theme'
11
11
 
12
12
  export type { ThemeInformation }
13
13
 
14
- export type ThemeContextValue = ThemeConfigValue<Theme> & {
14
+ export type ThemeContextValue = ThemeConfigValue<HightideTheme> & {
15
15
  isInitialized: boolean,
16
16
  }
17
17
 
@@ -19,8 +19,8 @@ import {
19
19
  type SystemTheme
20
20
  } from './forward-exports'
21
21
  import { useNativeKeyValueStore } from '../../hooks/useNativeKeyValueStore'
22
- import type { ThemeMode } from '../../theme/themes/nativeThemes'
23
- import type { Theme } from '../../theme/types/theme'
22
+ import type { ThemeMode } from '../../theme/themes/hightideThemes'
23
+ import type { HightideTheme } from '../../theme/types/theme'
24
24
 
25
25
  export type ThemeProviderProps<T> = PropsWithChildren & {
26
26
  theme?: ThemeMode | null,
@@ -66,7 +66,7 @@ export const ThemeProvider = ({
66
66
  fallbackTheme = 'light',
67
67
  supportedThemes = HightideConfigUtils.defaultSupportedThemes,
68
68
  onChangedTheme,
69
- }: ThemeProviderProps<Theme>) => {
69
+ }: ThemeProviderProps<HightideTheme>) => {
70
70
  const store = useNativeKeyValueStore()
71
71
  const systemTheme = useNativeSystemTheme()
72
72