@helpwave/hightide-native 0.0.7 → 0.1.0
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/README.md +4 -4
- package/package.json +8 -19
- package/src/components/card/Card.tsx +41 -0
- package/src/components/card/index.ts +1 -0
- package/src/components/chat/ChatAttachmentMessageBubble.tsx +246 -0
- package/src/components/chat/ChatConversationRow.tsx +21 -16
- package/src/components/chat/ChatDateDivider.tsx +2 -2
- package/src/components/chat/ChatMessageBubble.tsx +62 -52
- package/src/components/chat/ChatMessageComposer.tsx +16 -14
- package/src/components/chat/ChatQuickReplyChip.tsx +41 -43
- package/src/components/chat/ChatSystemLine.tsx +14 -7
- package/src/components/chat/ChatThreadHeader.tsx +60 -6
- package/src/components/chat/index.ts +1 -2
- package/src/components/index.ts +3 -1
- package/src/components/layout/Divider.tsx +60 -0
- package/src/components/layout/index.ts +1 -0
- package/src/components/list/ListActionItem.tsx +99 -0
- package/src/components/list/ListItem.tsx +96 -0
- package/src/components/list/ListNavigationItem.tsx +102 -0
- package/src/components/list/index.ts +3 -0
- package/src/components/user-interaction/Button.tsx +80 -31
- package/src/components/user-interaction/Checkbox.tsx +72 -32
- package/src/components/user-interaction/IconButton.tsx +68 -30
- package/src/components/user-interaction/Input.tsx +61 -14
- package/src/components/user-interaction/MultiSelect.tsx +142 -75
- package/src/components/user-interaction/SearchBar.tsx +222 -0
- package/src/components/user-interaction/Select.tsx +129 -58
- package/src/components/user-interaction/Switch.tsx +207 -0
- package/src/components/user-interaction/ThemedPressable.tsx +136 -0
- package/src/components/user-interaction/index.ts +3 -0
- package/src/components/visualization-and-display/Avatar.tsx +112 -93
- package/src/components/visualization-and-display/Chip.tsx +22 -22
- package/src/components/visualization-and-display/ThemedIcon.tsx +72 -0
- package/src/components/visualization-and-display/ThemedText.tsx +38 -0
- package/src/components/visualization-and-display/index.ts +2 -1
- package/src/global-contexts/HightideProvider.tsx +19 -10
- package/src/global-contexts/content-theme/ContentThemeContext.ts +22 -0
- package/src/global-contexts/content-theme/ContentThemeProvider.tsx +32 -0
- package/src/global-contexts/content-theme/index.ts +2 -0
- package/src/global-contexts/debug/forward-exports.ts +10 -0
- package/src/global-contexts/debug/index.ts +1 -0
- package/src/global-contexts/index.ts +2 -0
- package/src/global-contexts/theme/ThemeProvider.tsx +7 -1
- package/src/icons/HightideIconRegistry.ts +33 -0
- package/src/icons/index.ts +2 -0
- package/src/icons/types.ts +11 -0
- package/src/theme/adapters/container-adapter.ts +323 -0
- package/src/theme/adapters/defined.ts +11 -0
- package/src/theme/adapters/icon-style-adapter.ts +10 -0
- package/src/theme/adapters/index.ts +4 -0
- package/src/theme/adapters/text-style-adapter.ts +16 -0
- package/src/theme/index.ts +1 -0
- package/src/theme/resolvers/avatar.ts +385 -186
- package/src/theme/resolvers/button.ts +50 -82
- package/src/theme/resolvers/card.ts +27 -0
- package/src/theme/resolvers/chat/attachment-message-bubble.ts +163 -0
- package/src/theme/resolvers/chat/chat-theme.ts +69 -0
- package/src/theme/resolvers/chat/conversation-list.ts +35 -0
- package/src/theme/resolvers/chat/conversation-row.ts +64 -0
- package/src/theme/resolvers/chat/date-divider.ts +31 -0
- package/src/theme/resolvers/chat/index.ts +11 -0
- package/src/theme/resolvers/chat/message-bubble.ts +57 -0
- package/src/theme/resolvers/chat/message-composer.ts +38 -0
- package/src/theme/resolvers/chat/message-list.ts +27 -0
- package/src/theme/resolvers/chat/quick-reply-chip.ts +80 -0
- package/src/theme/resolvers/chat/system-line.ts +41 -0
- package/src/theme/resolvers/chat/thread-header.ts +85 -0
- package/src/theme/resolvers/checkbox.ts +87 -74
- package/src/theme/resolvers/chip.ts +30 -67
- package/src/theme/resolvers/colorScheme.ts +136 -0
- package/src/theme/resolvers/divider.ts +34 -0
- package/src/theme/resolvers/icon.ts +21 -0
- package/src/theme/resolvers/iconButton.ts +45 -61
- package/src/theme/resolvers/index.ts +8 -2
- package/src/theme/resolvers/input.ts +64 -42
- package/src/theme/resolvers/listItem.ts +115 -0
- package/src/theme/resolvers/multiSelect.ts +159 -84
- package/src/theme/resolvers/searchBar.ts +121 -0
- package/src/theme/resolvers/select.ts +141 -66
- package/src/theme/resolvers/switch.ts +71 -0
- package/src/theme/resolvers/themedPressable.ts +54 -0
- package/src/theme/themes/createHightideTheme.ts +214 -49
- package/src/theme/themes/hightideThemes.ts +10 -6
- package/src/theme/types/color.ts +2 -59
- package/src/theme/types/components/avatar.ts +37 -36
- package/src/theme/types/components/button.ts +13 -14
- package/src/theme/types/components/card.ts +9 -0
- package/src/theme/types/components/chat.ts +124 -103
- package/src/theme/types/components/checkbox.ts +11 -12
- package/src/theme/types/components/chip.ts +8 -14
- package/src/theme/types/components/divider.ts +18 -0
- package/src/theme/types/components/hightide.ts +41 -40
- package/src/theme/types/components/iconButton.ts +19 -14
- package/src/theme/types/components/index.ts +6 -1
- package/src/theme/types/components/input.ts +17 -8
- package/src/theme/types/components/listItem.ts +86 -0
- package/src/theme/types/components/multiSelect.ts +14 -12
- package/src/theme/types/components/searchBar.ts +28 -0
- package/src/theme/types/components/select.ts +21 -9
- package/src/theme/types/components/switch.ts +22 -0
- package/src/theme/types/components/themedPressable.ts +31 -0
- package/src/theme/types/decoration.ts +1 -11
- package/src/theme/types/icongraphy.ts +8 -0
- package/src/theme/types/index.ts +2 -0
- package/src/theme/types/layout.ts +25 -57
- package/src/theme/types/resolver.ts +54 -1
- package/src/theme/types/semantics.ts +72 -0
- package/src/theme/types/theme.ts +26 -13
- package/src/theme/types/typography.ts +16 -17
- package/src/utils/hitBoxOverlay.ts +44 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/minimumTouchTargetHitSlop.ts +68 -0
- package/src/components/chat/ChatAttachmentCard.tsx +0 -110
- package/src/components/chat/ChatMessageCard.tsx +0 -118
- package/src/components/menu/Menu.tsx +0 -61
- package/src/components/menu/MenuActionItem.tsx +0 -90
- package/src/components/menu/MenuItem.tsx +0 -73
- package/src/components/menu/MenuNavigationItem.tsx +0 -90
- package/src/components/menu/index.ts +0 -4
- package/src/components/visualization-and-display/Icon.tsx +0 -27
- package/src/storybook/helper.tsx +0 -36
- package/src/theme/resolvers/chat.ts +0 -418
- package/src/theme/resolvers/coloring.ts +0 -94
- package/src/theme/resolvers/menu.ts +0 -120
- package/src/theme/types/components/menu.ts +0 -57
package/README.md
CHANGED
|
@@ -31,18 +31,18 @@ import { HightideProvider } from "@helpwave/hightide-native/global-contexts";
|
|
|
31
31
|
Import from the package subpaths (there is no root export):
|
|
32
32
|
|
|
33
33
|
```tsx
|
|
34
|
-
import { Button, Input, Select } from "@helpwave/hightide-native/components";
|
|
34
|
+
import { Button, Input, Select, ThemedIcon } from "@helpwave/hightide-native/components";
|
|
35
35
|
import { HightideProvider } from "@helpwave/hightide-native/global-contexts";
|
|
36
36
|
import { useSelect } from "@helpwave/hightide-native/hooks";
|
|
37
|
-
import {
|
|
37
|
+
import { HightideIconRegistry } from "@helpwave/hightide-native/icons";
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
| Subpath | Contents |
|
|
41
41
|
| --- | --- |
|
|
42
|
-
| `@helpwave/hightide-native/components` | UI components (`Button`, `Checkbox`, `Chip`, `Input`, …) |
|
|
42
|
+
| `@helpwave/hightide-native/components` | UI components (`Button`, `Checkbox`, `Chip`, `Input`, `ThemedText`, `ThemedIcon`, …) |
|
|
43
43
|
| `@helpwave/hightide-native/global-contexts` | `HightideProvider` and related context providers |
|
|
44
44
|
| `@helpwave/hightide-native/hooks` | Native hooks (`useSelect`, `useMultiSelect`, …) |
|
|
45
|
-
| `@helpwave/hightide-native/icons` | Icon
|
|
45
|
+
| `@helpwave/hightide-native/icons` | Icon registry (`HightideIconRegistry`) |
|
|
46
46
|
| `@helpwave/hightide-native/theme` | Theme factories and style resolvers |
|
|
47
47
|
| `@helpwave/hightide-native/types` | Shared TypeScript types |
|
|
48
48
|
|
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
|
|
13
|
+
"version": "0.1.0",
|
|
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
|
|
47
|
-
"@helpwave/hightide-utils": "0.0
|
|
46
|
+
"@helpwave/hightide-design": "0.1.0",
|
|
47
|
+
"@helpwave/hightide-utils": "0.1.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@react-native-async-storage/async-storage": ">=2.0.0",
|
|
@@ -55,22 +55,13 @@
|
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@helpwave/eslint-config": "0.0.11",
|
|
57
57
|
"@react-native-async-storage/async-storage": "2.2.0",
|
|
58
|
-
"@
|
|
59
|
-
"@storybook/addon-links": "10.4.5",
|
|
60
|
-
"@storybook/react-native-web-vite": "10.4.5",
|
|
61
|
-
"@types/react": "19.2.3",
|
|
62
|
-
"@types/react-dom": "19.2.3",
|
|
58
|
+
"@types/react": "19.0.10",
|
|
63
59
|
"eslint": "9.31.0",
|
|
64
60
|
"eslint-plugin-import": "2.32.0",
|
|
65
|
-
"
|
|
66
|
-
"react": "
|
|
67
|
-
"react-dom": "19.2.3",
|
|
68
|
-
"react-native": "0.79.2",
|
|
61
|
+
"react": "19.0.0",
|
|
62
|
+
"react-native": "0.79.6",
|
|
69
63
|
"react-native-svg": "15.12.0",
|
|
70
|
-
"
|
|
71
|
-
"storybook": "10.4.5",
|
|
72
|
-
"typescript": "5.7.2",
|
|
73
|
-
"vite": "7.3.5"
|
|
64
|
+
"typescript": "5.7.2"
|
|
74
65
|
},
|
|
75
66
|
"keywords": [
|
|
76
67
|
"react-native",
|
|
@@ -81,13 +72,11 @@
|
|
|
81
72
|
"url": "https://github.com/helpwave/hightide/issues"
|
|
82
73
|
},
|
|
83
74
|
"scripts": {
|
|
84
|
-
"clean": "pnpm run barrel -- --clean && rm -rf node_modules
|
|
75
|
+
"clean": "pnpm run barrel -- --clean && rm -rf node_modules",
|
|
85
76
|
"init": "pnpm run barrel",
|
|
86
77
|
"barrel": "node node_modules/@helpwave/hightide-utils/scripts/barrel.js",
|
|
87
78
|
"barrel:check": "node node_modules/@helpwave/hightide-utils/scripts/barrel.js --check",
|
|
88
79
|
"build": "pnpm run barrel",
|
|
89
|
-
"storybook": "storybook dev -p 6007",
|
|
90
|
-
"build-storybook": "storybook build",
|
|
91
80
|
"lint": "eslint .",
|
|
92
81
|
"test": "node -e \"process.exit(0)\""
|
|
93
82
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMemo,
|
|
3
|
+
type ReactNode
|
|
4
|
+
} from 'react'
|
|
5
|
+
import {
|
|
6
|
+
View,
|
|
7
|
+
type StyleProp,
|
|
8
|
+
type ViewProps,
|
|
9
|
+
type ViewStyle
|
|
10
|
+
} from 'react-native'
|
|
11
|
+
|
|
12
|
+
import { useTheme } from '../../global-contexts/theme/ThemeContext'
|
|
13
|
+
import type { CardStyle } from '../../theme/types/components/card'
|
|
14
|
+
import type { StyleOverwrite } from '../../theme/types/resolver'
|
|
15
|
+
|
|
16
|
+
export type CardProps = Omit<ViewProps, 'children' | 'style'> & {
|
|
17
|
+
children?: ReactNode,
|
|
18
|
+
style?: StyleProp<ViewStyle>,
|
|
19
|
+
cardStyle?: StyleOverwrite<Record<string, never>, CardStyle>,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const Card = ({
|
|
23
|
+
children,
|
|
24
|
+
style,
|
|
25
|
+
cardStyle,
|
|
26
|
+
...props
|
|
27
|
+
}: CardProps) => {
|
|
28
|
+
const { theme } = useTheme()
|
|
29
|
+
const state = useMemo(() => ({}), [])
|
|
30
|
+
|
|
31
|
+
const resolvedCardStyle = useMemo(
|
|
32
|
+
() => theme.components.card.container(state, cardStyle),
|
|
33
|
+
[theme, state, cardStyle]
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<View {...props} style={[resolvedCardStyle, style]}>
|
|
38
|
+
{children}
|
|
39
|
+
</View>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Card'
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMemo,
|
|
3
|
+
type ReactNode
|
|
4
|
+
} from 'react'
|
|
5
|
+
import {
|
|
6
|
+
View,
|
|
7
|
+
type StyleProp,
|
|
8
|
+
type ViewStyle
|
|
9
|
+
} from 'react-native'
|
|
10
|
+
import { HightideIconRegistry } from '../../icons/HightideIconRegistry'
|
|
11
|
+
import { ThemedIcon } from '../visualization-and-display/ThemedIcon'
|
|
12
|
+
import { ThemedText } from '../visualization-and-display/ThemedText'
|
|
13
|
+
import { ThemedPressable } from '../user-interaction/ThemedPressable'
|
|
14
|
+
import { useTheme } from '../../global-contexts/theme/ThemeContext'
|
|
15
|
+
import type {
|
|
16
|
+
ChatAttachmentMessageBubbleFileMetadataTextStyle,
|
|
17
|
+
ChatAttachmentMessageBubbleFileNameTextStyle,
|
|
18
|
+
ChatAttachmentMessageBubbleState,
|
|
19
|
+
ChatMessageBubbleBodyStyle,
|
|
20
|
+
ChatMessageBubbleBodyTextStyle,
|
|
21
|
+
ChatMessageBubbleContainerStyle,
|
|
22
|
+
ChatMessageBubbleMetaDataContainerStyle,
|
|
23
|
+
ChatMessageBubbleMetaDataStatusContainerStyle,
|
|
24
|
+
ChatMessageBubbleMetaDataTextStyle,
|
|
25
|
+
ChatMessageBubbleState,
|
|
26
|
+
PressableContainerStyle,
|
|
27
|
+
PressableState
|
|
28
|
+
} from '../../theme/types/components/chat'
|
|
29
|
+
import type { StyleOverwrite } from '../../theme/types/resolver'
|
|
30
|
+
import {
|
|
31
|
+
ChatMessageBubble,
|
|
32
|
+
type ChatMessageBubbleProps
|
|
33
|
+
} from './ChatMessageBubble'
|
|
34
|
+
|
|
35
|
+
export type ChatAttachmentMessageBubbleProps = Omit<ChatMessageBubbleProps, 'children'> & {
|
|
36
|
+
children?: ReactNode,
|
|
37
|
+
name: ReactNode,
|
|
38
|
+
metadata?: ReactNode,
|
|
39
|
+
icon?: ReactNode,
|
|
40
|
+
downloadLabel?: string,
|
|
41
|
+
onDownload?: () => void,
|
|
42
|
+
contentContainerStyle?: StyleOverwrite<
|
|
43
|
+
PressableState,
|
|
44
|
+
PressableContainerStyle
|
|
45
|
+
>,
|
|
46
|
+
fileNameTextStyle?: StyleOverwrite<
|
|
47
|
+
ChatAttachmentMessageBubbleState,
|
|
48
|
+
ChatAttachmentMessageBubbleFileNameTextStyle
|
|
49
|
+
>,
|
|
50
|
+
fileMetadataTextStyle?: StyleOverwrite<
|
|
51
|
+
ChatAttachmentMessageBubbleState,
|
|
52
|
+
ChatAttachmentMessageBubbleFileMetadataTextStyle
|
|
53
|
+
>,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const mergeBubbleStyleOverwrite = <TStyle extends StyleProp<ViewStyle> | object>(
|
|
57
|
+
tokenOverride: TStyle,
|
|
58
|
+
userOverwrite?: StyleOverwrite<ChatMessageBubbleState, TStyle>
|
|
59
|
+
): StyleOverwrite<ChatMessageBubbleState, TStyle> => (
|
|
60
|
+
(prev, state) => {
|
|
61
|
+
const withTokenOverride = {
|
|
62
|
+
...(prev as object),
|
|
63
|
+
...(tokenOverride as object),
|
|
64
|
+
} as TStyle
|
|
65
|
+
|
|
66
|
+
if (userOverwrite === undefined) {
|
|
67
|
+
return withTokenOverride
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (typeof userOverwrite === 'function') {
|
|
71
|
+
return userOverwrite(withTokenOverride, state)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
...(withTokenOverride as object),
|
|
76
|
+
...(userOverwrite as object),
|
|
77
|
+
} as TStyle
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
export const ChatAttachmentMessageBubble = ({
|
|
82
|
+
children,
|
|
83
|
+
name,
|
|
84
|
+
metadata,
|
|
85
|
+
icon,
|
|
86
|
+
direction,
|
|
87
|
+
downloadLabel = 'Download',
|
|
88
|
+
onDownload,
|
|
89
|
+
timestamp,
|
|
90
|
+
readReceipt,
|
|
91
|
+
style,
|
|
92
|
+
containerStyle,
|
|
93
|
+
bodyStyle,
|
|
94
|
+
bodyTextStyle,
|
|
95
|
+
metaDataContainerStyle,
|
|
96
|
+
metaDataStatusContainerStyle,
|
|
97
|
+
metaDataTextStyle,
|
|
98
|
+
contentContainerStyle,
|
|
99
|
+
fileNameTextStyle,
|
|
100
|
+
fileMetadataTextStyle,
|
|
101
|
+
...props
|
|
102
|
+
}: ChatAttachmentMessageBubbleProps) => {
|
|
103
|
+
const { theme } = useTheme()
|
|
104
|
+
const state = useMemo(() => ({ direction }), [direction])
|
|
105
|
+
const attachment = theme.components.chat.attachmentMessageBubble
|
|
106
|
+
const bubbleOverrides = attachment.chatMessageBubbleOverrides
|
|
107
|
+
const contentResolvers = useMemo(
|
|
108
|
+
() => attachment.contentContainer(state),
|
|
109
|
+
[attachment, state]
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
const resolvedFileIconContainerStyle = useMemo(
|
|
113
|
+
() => attachment.fileIconContainer(state),
|
|
114
|
+
[attachment, state]
|
|
115
|
+
)
|
|
116
|
+
const resolvedFileIcon = useMemo(
|
|
117
|
+
() => attachment.fileIcon(state),
|
|
118
|
+
[attachment, state]
|
|
119
|
+
)
|
|
120
|
+
const resolvedDownloadIconContainerStyle = useMemo(
|
|
121
|
+
() => attachment.downloadIconContainer(state),
|
|
122
|
+
[attachment, state]
|
|
123
|
+
)
|
|
124
|
+
const resolvedDownloadIcon = useMemo(
|
|
125
|
+
() => attachment.downloadIcon(state),
|
|
126
|
+
[attachment, state]
|
|
127
|
+
)
|
|
128
|
+
const resolvedFileNameTextStyle = useMemo(
|
|
129
|
+
() => attachment.fileNameText(state, fileNameTextStyle),
|
|
130
|
+
[attachment, state, fileNameTextStyle]
|
|
131
|
+
)
|
|
132
|
+
const resolvedFileMetadataTextStyle = useMemo(
|
|
133
|
+
() => attachment.fileMetadataText(state, fileMetadataTextStyle),
|
|
134
|
+
[attachment, state, fileMetadataTextStyle]
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
const resolvedContainerStyle = useMemo(
|
|
138
|
+
() => mergeBubbleStyleOverwrite<ChatMessageBubbleContainerStyle>(
|
|
139
|
+
bubbleOverrides.container(state),
|
|
140
|
+
containerStyle
|
|
141
|
+
),
|
|
142
|
+
[bubbleOverrides, state, containerStyle]
|
|
143
|
+
)
|
|
144
|
+
const resolvedBodyStyle = useMemo(
|
|
145
|
+
() => mergeBubbleStyleOverwrite<ChatMessageBubbleBodyStyle>(
|
|
146
|
+
bubbleOverrides.body(state),
|
|
147
|
+
bodyStyle
|
|
148
|
+
),
|
|
149
|
+
[bubbleOverrides, state, bodyStyle]
|
|
150
|
+
)
|
|
151
|
+
const resolvedBodyTextStyle = useMemo(
|
|
152
|
+
() => mergeBubbleStyleOverwrite<ChatMessageBubbleBodyTextStyle>(
|
|
153
|
+
bubbleOverrides.bodyText(state),
|
|
154
|
+
bodyTextStyle
|
|
155
|
+
),
|
|
156
|
+
[bubbleOverrides, state, bodyTextStyle]
|
|
157
|
+
)
|
|
158
|
+
const resolvedMetaDataContainerStyle = useMemo(
|
|
159
|
+
() => mergeBubbleStyleOverwrite<ChatMessageBubbleMetaDataContainerStyle>(
|
|
160
|
+
bubbleOverrides.metaDataContainer(state),
|
|
161
|
+
metaDataContainerStyle
|
|
162
|
+
),
|
|
163
|
+
[bubbleOverrides, state, metaDataContainerStyle]
|
|
164
|
+
)
|
|
165
|
+
const resolvedMetaDataStatusContainerStyle = useMemo(
|
|
166
|
+
() => mergeBubbleStyleOverwrite<ChatMessageBubbleMetaDataStatusContainerStyle>(
|
|
167
|
+
bubbleOverrides.metaDataStatusContainer(state),
|
|
168
|
+
metaDataStatusContainerStyle
|
|
169
|
+
),
|
|
170
|
+
[bubbleOverrides, state, metaDataStatusContainerStyle]
|
|
171
|
+
)
|
|
172
|
+
const resolvedMetaDataTextStyle = useMemo(
|
|
173
|
+
() => mergeBubbleStyleOverwrite<ChatMessageBubbleMetaDataTextStyle>(
|
|
174
|
+
bubbleOverrides.metaDataText(state),
|
|
175
|
+
metaDataTextStyle
|
|
176
|
+
),
|
|
177
|
+
[bubbleOverrides, state, metaDataTextStyle]
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<ChatMessageBubble
|
|
182
|
+
{...props}
|
|
183
|
+
direction={direction}
|
|
184
|
+
timestamp={timestamp}
|
|
185
|
+
readReceipt={readReceipt}
|
|
186
|
+
style={style}
|
|
187
|
+
containerStyle={resolvedContainerStyle}
|
|
188
|
+
bodyStyle={resolvedBodyStyle}
|
|
189
|
+
bodyTextStyle={resolvedBodyTextStyle}
|
|
190
|
+
metaDataContainerStyle={resolvedMetaDataContainerStyle}
|
|
191
|
+
metaDataStatusContainerStyle={resolvedMetaDataStatusContainerStyle}
|
|
192
|
+
metaDataTextStyle={resolvedMetaDataTextStyle}
|
|
193
|
+
>
|
|
194
|
+
{children}
|
|
195
|
+
<ThemedPressable
|
|
196
|
+
accessibilityLabel={downloadLabel}
|
|
197
|
+
disabled={onDownload == null}
|
|
198
|
+
onPress={onDownload}
|
|
199
|
+
containerStyle={(_, pressableState) => (
|
|
200
|
+
contentResolvers.container(pressableState, contentContainerStyle)
|
|
201
|
+
)}
|
|
202
|
+
stateLayerStyle={(_, pressableState) => (
|
|
203
|
+
contentResolvers.stateLayer(pressableState)
|
|
204
|
+
)}
|
|
205
|
+
textStyle={(_, pressableState) => (
|
|
206
|
+
contentResolvers.text(pressableState)
|
|
207
|
+
)}
|
|
208
|
+
>
|
|
209
|
+
<View style={resolvedFileIconContainerStyle}>
|
|
210
|
+
{icon ?? (
|
|
211
|
+
<ThemedIcon
|
|
212
|
+
icon={HightideIconRegistry.FileText}
|
|
213
|
+
size={resolvedFileIcon.size}
|
|
214
|
+
strokeWidth={resolvedFileIcon.strokeWidth}
|
|
215
|
+
color={resolvedFileIcon.color}
|
|
216
|
+
/>
|
|
217
|
+
)}
|
|
218
|
+
</View>
|
|
219
|
+
<View style={{ flex: 1, minWidth: 0, gap: 2 }}>
|
|
220
|
+
{typeof name === 'string' || typeof name === 'number' ? (
|
|
221
|
+
<ThemedText style={resolvedFileNameTextStyle} numberOfLines={1}>{name}</ThemedText>
|
|
222
|
+
) : (
|
|
223
|
+
name
|
|
224
|
+
)}
|
|
225
|
+
{metadata != null && (
|
|
226
|
+
typeof metadata === 'string' || typeof metadata === 'number' ? (
|
|
227
|
+
<ThemedText appearance="description" style={resolvedFileMetadataTextStyle}>
|
|
228
|
+
{metadata}
|
|
229
|
+
</ThemedText>
|
|
230
|
+
) : (
|
|
231
|
+
metadata
|
|
232
|
+
)
|
|
233
|
+
)}
|
|
234
|
+
</View>
|
|
235
|
+
<View style={resolvedDownloadIconContainerStyle}>
|
|
236
|
+
<ThemedIcon
|
|
237
|
+
icon={HightideIconRegistry.Download}
|
|
238
|
+
size={resolvedDownloadIcon.size}
|
|
239
|
+
strokeWidth={resolvedDownloadIcon.strokeWidth}
|
|
240
|
+
color={resolvedDownloadIcon.color}
|
|
241
|
+
/>
|
|
242
|
+
</View>
|
|
243
|
+
</ThemedPressable>
|
|
244
|
+
</ChatMessageBubble>
|
|
245
|
+
)
|
|
246
|
+
}
|
|
@@ -4,18 +4,14 @@ import {
|
|
|
4
4
|
type ReactNode
|
|
5
5
|
} from 'react'
|
|
6
6
|
import {
|
|
7
|
-
Pressable,
|
|
8
|
-
Text,
|
|
9
7
|
View,
|
|
10
8
|
type PressableProps,
|
|
11
9
|
type StyleProp,
|
|
12
10
|
type ViewStyle
|
|
13
11
|
} from 'react-native'
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} from 'lucide-react-native'
|
|
18
|
-
|
|
12
|
+
import { HightideIconRegistry } from '../../icons/HightideIconRegistry'
|
|
13
|
+
import { ThemedIcon } from '../visualization-and-display/ThemedIcon'
|
|
14
|
+
import { ThemedText } from '../visualization-and-display/ThemedText'
|
|
19
15
|
import { useTheme } from '../../global-contexts/theme/ThemeContext'
|
|
20
16
|
import type {
|
|
21
17
|
ChatConversationRowPreviewStyle,
|
|
@@ -25,6 +21,7 @@ import type {
|
|
|
25
21
|
ChatConversationRowTitleStyle
|
|
26
22
|
} from '../../theme/types/components/chat'
|
|
27
23
|
import type { StyleOverwrite } from '../../theme/types/resolver'
|
|
24
|
+
import { ThemedPressable } from '../user-interaction'
|
|
28
25
|
|
|
29
26
|
export type ChatConversationSentIndicator = 'sent' | 'sentAndReceived'
|
|
30
27
|
|
|
@@ -47,6 +44,7 @@ type PressableInteraction = {
|
|
|
47
44
|
pressed: boolean,
|
|
48
45
|
hovered?: boolean,
|
|
49
46
|
focused?: boolean,
|
|
47
|
+
focusVisible?: boolean,
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
export const ChatConversationRow = ({
|
|
@@ -67,7 +65,9 @@ export const ChatConversationRow = ({
|
|
|
67
65
|
}: ChatConversationRowProps) => {
|
|
68
66
|
const { theme } = useTheme()
|
|
69
67
|
const isUnread = (unreadCount ?? 0) > 0
|
|
70
|
-
const
|
|
68
|
+
const sentIndicatorIcon = sentIndicator === 'sentAndReceived'
|
|
69
|
+
? HightideIconRegistry.CheckCheck
|
|
70
|
+
: HightideIconRegistry.Check
|
|
71
71
|
|
|
72
72
|
const resolveState = (interaction: PressableInteraction): ChatConversationRowState => ({
|
|
73
73
|
isUnread,
|
|
@@ -76,6 +76,7 @@ export const ChatConversationRow = ({
|
|
|
76
76
|
isPressed: interaction.pressed,
|
|
77
77
|
isHovered: !!interaction.hovered,
|
|
78
78
|
isFocused: !!interaction.focused,
|
|
79
|
+
isFocusVisible: !!interaction.focusVisible,
|
|
79
80
|
})
|
|
80
81
|
|
|
81
82
|
const staticState = useMemo(() => ({}), [])
|
|
@@ -93,7 +94,7 @@ export const ChatConversationRow = ({
|
|
|
93
94
|
)
|
|
94
95
|
|
|
95
96
|
return (
|
|
96
|
-
<
|
|
97
|
+
<ThemedPressable
|
|
97
98
|
{...props}
|
|
98
99
|
disabled={disabled}
|
|
99
100
|
style={(pressableState) => {
|
|
@@ -111,15 +112,15 @@ export const ChatConversationRow = ({
|
|
|
111
112
|
<Fragment>
|
|
112
113
|
{avatar}
|
|
113
114
|
<View style={{ flex: 1, minWidth: 0, gap: 5 }}>
|
|
114
|
-
<View style={{ flexDirection: 'row', alignItems: '
|
|
115
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
|
|
115
116
|
{typeof title === 'string' || typeof title === 'number' ? (
|
|
116
|
-
<
|
|
117
|
+
<ThemedText style={resolvedTitle} numberOfLines={1}>{title}</ThemedText>
|
|
117
118
|
) : (
|
|
118
119
|
title
|
|
119
120
|
)}
|
|
120
121
|
{timestamp != null && (
|
|
121
122
|
typeof timestamp === 'string' || typeof timestamp === 'number' ? (
|
|
122
|
-
<
|
|
123
|
+
<ThemedText style={resolvedTimestamp}>{timestamp}</ThemedText>
|
|
123
124
|
) : (
|
|
124
125
|
timestamp
|
|
125
126
|
)
|
|
@@ -128,11 +129,15 @@ export const ChatConversationRow = ({
|
|
|
128
129
|
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
|
|
129
130
|
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', gap: 4, minWidth: 0 }}>
|
|
130
131
|
{sentIndicator && (
|
|
131
|
-
<
|
|
132
|
+
<ThemedIcon
|
|
133
|
+
icon={sentIndicatorIcon}
|
|
134
|
+
size={16}
|
|
135
|
+
color={sentIndicatorColor}
|
|
136
|
+
/>
|
|
132
137
|
)}
|
|
133
138
|
{preview != null && (
|
|
134
139
|
typeof preview === 'string' || typeof preview === 'number' ? (
|
|
135
|
-
<
|
|
140
|
+
<ThemedText style={resolvedPreview} numberOfLines={1}>{preview}</ThemedText>
|
|
136
141
|
) : (
|
|
137
142
|
preview
|
|
138
143
|
)
|
|
@@ -140,7 +145,7 @@ export const ChatConversationRow = ({
|
|
|
140
145
|
</View>
|
|
141
146
|
{isUnread && (
|
|
142
147
|
<View style={unreadBadge}>
|
|
143
|
-
<
|
|
148
|
+
<ThemedText style={unreadBadgeText}>{unreadCount}</ThemedText>
|
|
144
149
|
</View>
|
|
145
150
|
)}
|
|
146
151
|
</View>
|
|
@@ -148,6 +153,6 @@ export const ChatConversationRow = ({
|
|
|
148
153
|
</Fragment>
|
|
149
154
|
)
|
|
150
155
|
}}
|
|
151
|
-
</
|
|
156
|
+
</ThemedPressable>
|
|
152
157
|
)
|
|
153
158
|
}
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
type ReactNode
|
|
4
4
|
} from 'react'
|
|
5
5
|
import {
|
|
6
|
-
Text,
|
|
7
6
|
View,
|
|
8
7
|
type StyleProp,
|
|
9
8
|
type ViewProps,
|
|
@@ -11,6 +10,7 @@ import {
|
|
|
11
10
|
} from 'react-native'
|
|
12
11
|
|
|
13
12
|
import { useTheme } from '../../global-contexts/theme/ThemeContext'
|
|
13
|
+
import { ThemedText } from '../visualization-and-display/ThemedText'
|
|
14
14
|
import type {
|
|
15
15
|
ChatDateDividerStyle,
|
|
16
16
|
ChatDateDividerTextStyle
|
|
@@ -46,7 +46,7 @@ export const ChatDateDivider = ({
|
|
|
46
46
|
return (
|
|
47
47
|
<View {...props} style={[resolvedDividerStyle, style]}>
|
|
48
48
|
{typeof children === 'string' || typeof children === 'number' ? (
|
|
49
|
-
<
|
|
49
|
+
<ThemedText style={resolvedTextStyle}>{children}</ThemedText>
|
|
50
50
|
) : (
|
|
51
51
|
children
|
|
52
52
|
)}
|