@planningcenter/chat-react-native 3.44.3 → 3.44.5-qa-900.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/build/components/conversation/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +3 -3
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js +3 -3
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/conversation/message_reaction.d.ts.map +1 -1
- package/build/components/conversation/message_reaction.js +5 -5
- package/build/components/conversation/message_reaction.js.map +1 -1
- package/build/components/conversations/conversation_actions.d.ts.map +1 -1
- package/build/components/conversations/conversation_actions.js +1 -1
- package/build/components/conversations/conversation_actions.js.map +1 -1
- package/build/components/display/toggle_button.js +9 -5
- package/build/components/display/toggle_button.js.map +1 -1
- package/build/components/primitive/form_sheet.d.ts +1 -0
- package/build/components/primitive/form_sheet.d.ts.map +1 -1
- package/build/components/primitive/form_sheet.js +2 -2
- package/build/components/primitive/form_sheet.js.map +1 -1
- package/build/hooks/index.d.ts +2 -1
- package/build/hooks/index.d.ts.map +1 -1
- package/build/hooks/index.js +2 -1
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/use_interaction_tinted_background_color.d.ts +2 -0
- package/build/hooks/use_interaction_tinted_background_color.d.ts.map +1 -0
- package/build/hooks/use_interaction_tinted_background_color.js +11 -0
- package/build/hooks/use_interaction_tinted_background_color.js.map +1 -0
- package/build/hooks/use_selected_chip_background_color.d.ts +2 -0
- package/build/hooks/use_selected_chip_background_color.d.ts.map +1 -0
- package/build/hooks/use_selected_chip_background_color.js +11 -0
- package/build/hooks/use_selected_chip_background_color.js.map +1 -0
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +1 -1
- package/build/screens/conversation_screen.js.map +1 -1
- package/build/screens/conversation_select_type_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_type_screen.js +1 -1
- package/build/screens/conversation_select_type_screen.js.map +1 -1
- package/build/screens/conversations/components/list_header_component.d.ts.map +1 -1
- package/build/screens/conversations/components/list_header_component.js +1 -1
- package/build/screens/conversations/components/list_header_component.js.map +1 -1
- package/build/screens/design_system_screen.js +3 -3
- package/build/screens/design_system_screen.js.map +1 -1
- package/build/utils/theme.d.ts +16 -0
- package/build/utils/theme.d.ts.map +1 -1
- package/build/utils/theme.js +9 -0
- package/build/utils/theme.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/hooks/use_selected_chip_background_color.test.tsx +78 -0
- package/src/__tests__/utils/theme.ts +23 -0
- package/src/components/conversation/message.tsx +3 -2
- package/src/components/conversation/message_form.tsx +3 -2
- package/src/components/conversation/message_reaction.tsx +5 -4
- package/src/components/conversations/conversation_actions.tsx +1 -0
- package/src/components/display/__tests__/toggle_button.test.tsx +135 -0
- package/src/components/display/toggle_button.tsx +9 -5
- package/src/components/primitive/form_sheet.tsx +3 -0
- package/src/hooks/index.ts +2 -1
- package/src/hooks/use_interaction_tinted_background_color.ts +16 -0
- package/src/hooks/use_selected_chip_background_color.ts +16 -0
- package/src/screens/conversation_screen.tsx +1 -0
- package/src/screens/conversation_select_type_screen.tsx +3 -0
- package/src/screens/conversations/components/list_header_component.tsx +1 -0
- package/src/screens/design_system_screen.tsx +3 -3
- package/src/utils/theme.ts +25 -0
- package/build/hooks/use_interaction_ghost_color.d.ts +0 -2
- package/build/hooks/use_interaction_ghost_color.d.ts.map +0 -1
- package/build/hooks/use_interaction_ghost_color.js +0 -14
- package/build/hooks/use_interaction_ghost_color.js.map +0 -1
- package/src/hooks/use_interaction_ghost_color.ts +0 -15
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
2
|
+
import { renderHook } from '@testing-library/react-native'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { buildTestQueryClient } from '../../__utils__/query_client'
|
|
5
|
+
import { ChatProvider, CreateChatThemeProps } from '../../contexts/chat_context'
|
|
6
|
+
import { useSelectedChipBackgroundColor } from '../../hooks'
|
|
7
|
+
|
|
8
|
+
let themeProps: CreateChatThemeProps
|
|
9
|
+
let queryClient: QueryClient
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
queryClient = buildTestQueryClient({
|
|
13
|
+
defaultOptions: {
|
|
14
|
+
queries: {
|
|
15
|
+
refetchInterval: false,
|
|
16
|
+
refetchOnWindowFocus: false,
|
|
17
|
+
refetchOnReconnect: false,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
queryClient.clear()
|
|
25
|
+
queryClient.cancelQueries()
|
|
26
|
+
queryClient.removeQueries()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
|
30
|
+
return (
|
|
31
|
+
<QueryClientProvider client={queryClient}>
|
|
32
|
+
<ChatProvider value={{ onUnauthorizedResponse: () => {}, theme: themeProps }}>
|
|
33
|
+
{children}
|
|
34
|
+
</ChatProvider>
|
|
35
|
+
</QueryClientProvider>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe('useSelectedChipBackgroundColor', () => {
|
|
40
|
+
test('falls back to colors.interaction when fillColorChipSelected is absent', () => {
|
|
41
|
+
themeProps = { theme: { colors: { interaction: 'rgb(0, 255, 0)' } } }
|
|
42
|
+
|
|
43
|
+
const { result } = renderHook(() => useSelectedChipBackgroundColor(), {
|
|
44
|
+
wrapper: Wrapper,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
expect(result.current).toBe('hsl(120, 100%, 92%)')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test('prefers fillColorChipSelected over colors.interaction when supplied', () => {
|
|
51
|
+
themeProps = {
|
|
52
|
+
theme: {
|
|
53
|
+
colors: { interaction: 'rgb(0, 255, 0)', fillColorChipSelected: 'rgb(255, 0, 0)' },
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { result } = renderHook(() => useSelectedChipBackgroundColor(), {
|
|
58
|
+
wrapper: Wrapper,
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
expect(result.current).toBe('hsl(0, 100%, 92%)')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('respects a custom hslLightnessChipSelected', () => {
|
|
65
|
+
themeProps = {
|
|
66
|
+
theme: {
|
|
67
|
+
colors: { interaction: 'rgb(0, 255, 0)' },
|
|
68
|
+
chip: { hslLightnessChipSelected: 50 },
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const { result } = renderHook(() => useSelectedChipBackgroundColor(), {
|
|
73
|
+
wrapper: Wrapper,
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
expect(result.current).toBe('hsl(120, 100%, 50%)')
|
|
77
|
+
})
|
|
78
|
+
})
|
|
@@ -20,4 +20,27 @@ describe('defaultTheme', () => {
|
|
|
20
20
|
// render an unstyled or misthemed UI.
|
|
21
21
|
expect(defaultTheme('unspecified').colors).toMatchObject(aliasTokensColorMap.light)
|
|
22
22
|
})
|
|
23
|
+
|
|
24
|
+
describe('chip tokens', () => {
|
|
25
|
+
test('seeds static defaults for the non-selected chip trio in both schemes', () => {
|
|
26
|
+
const light = defaultTheme('light').colors
|
|
27
|
+
const dark = defaultTheme('dark').colors
|
|
28
|
+
|
|
29
|
+
expect(light.borderColorChip).toBe('hsl(0, 0%, 88%)')
|
|
30
|
+
expect(light.fillColorChip).toBe('transparent')
|
|
31
|
+
expect(light.textColorChip).toBe('hsl(0, 0%, 45%)')
|
|
32
|
+
|
|
33
|
+
expect(dark.borderColorChip).toBe('hsl(0, 0%, 24%)')
|
|
34
|
+
expect(dark.fillColorChip).toBe('transparent')
|
|
35
|
+
expect(dark.textColorChip).toBe('hsl(0, 0%, 68%)')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('never seeds a static default for the selected chip trio', () => {
|
|
39
|
+
const { colors } = defaultTheme('light')
|
|
40
|
+
|
|
41
|
+
expect(colors.borderColorChipSelected).toBeUndefined()
|
|
42
|
+
expect(colors.fillColorChipSelected).toBeUndefined()
|
|
43
|
+
expect(colors.textColorChipSelected).toBeUndefined()
|
|
44
|
+
})
|
|
45
|
+
})
|
|
23
46
|
})
|
|
@@ -13,7 +13,7 @@ import { MessageReaction } from '../../components/conversation/message_reaction'
|
|
|
13
13
|
import { Avatar, Icon, Spinner, Text, TextButton, TextInlineButton } from '../../components/display'
|
|
14
14
|
import {
|
|
15
15
|
useAnimatedMessageBackgroundColor,
|
|
16
|
-
|
|
16
|
+
useInteractionTintedBackgroundColor,
|
|
17
17
|
useTheme,
|
|
18
18
|
} from '../../hooks'
|
|
19
19
|
import { useDeletingIds } from '../../hooks'
|
|
@@ -194,6 +194,7 @@ export function Message({
|
|
|
194
194
|
|
|
195
195
|
return (
|
|
196
196
|
<Pressable
|
|
197
|
+
testID={`message-${message.id}`}
|
|
197
198
|
onLongPress={isDeleting ? undefined : handleMessageLongPress}
|
|
198
199
|
onPress={isDeleting ? undefined : handleMessagePress}
|
|
199
200
|
onPressIn={isDeleting ? undefined : handleMessagePressIn}
|
|
@@ -341,7 +342,7 @@ export function Message({
|
|
|
341
342
|
|
|
342
343
|
const useMessageStyles = (mine: boolean, isDeleting: boolean) => {
|
|
343
344
|
const { colors } = useTheme()
|
|
344
|
-
const myMessageBackgroundColor =
|
|
345
|
+
const myMessageBackgroundColor = useInteractionTintedBackgroundColor()
|
|
345
346
|
const { width } = useWindowDimensions()
|
|
346
347
|
const tabletWidth = width >= 744 // Smallest iPad Mini's width
|
|
347
348
|
|
|
@@ -17,7 +17,7 @@ import { ChatContext } from '../../contexts/chat_context'
|
|
|
17
17
|
import {
|
|
18
18
|
useCreateAndroidRippleColor,
|
|
19
19
|
useTheme,
|
|
20
|
-
|
|
20
|
+
useInteractionTintedBackgroundColor,
|
|
21
21
|
useScalableNumberOfLines,
|
|
22
22
|
useFontScale,
|
|
23
23
|
} from '../../hooks'
|
|
@@ -465,6 +465,7 @@ function MessageFormInput() {
|
|
|
465
465
|
) : null}
|
|
466
466
|
|
|
467
467
|
<TextInput
|
|
468
|
+
testID="message-composer-input"
|
|
468
469
|
style={[styles.textInput, usingGiphy && styles.textInputWithGiphy]}
|
|
469
470
|
multiline={true}
|
|
470
471
|
placeholder={placeholder}
|
|
@@ -783,7 +784,7 @@ const useMessageFormStyles = () => {
|
|
|
783
784
|
const navigationTheme = useNavigationTheme()
|
|
784
785
|
const buttonSize = 38
|
|
785
786
|
|
|
786
|
-
const giphyBadgeBackgroundColor =
|
|
787
|
+
const giphyBadgeBackgroundColor = useInteractionTintedBackgroundColor()
|
|
787
788
|
|
|
788
789
|
return StyleSheet.create({
|
|
789
790
|
container: {
|
|
@@ -3,7 +3,7 @@ import colorFunction from 'color'
|
|
|
3
3
|
import React, { useMemo } from 'react'
|
|
4
4
|
import { StyleSheet } from 'react-native'
|
|
5
5
|
import { Text } from '../../components/display'
|
|
6
|
-
import {
|
|
6
|
+
import { useSelectedChipBackgroundColor, useTheme } from '../../hooks'
|
|
7
7
|
import { useCreateAndroidRippleColor } from '../../hooks/use_create_android_ripple_color'
|
|
8
8
|
import { useMessageReactionToggle } from '../../hooks/use_message_reaction_toggle'
|
|
9
9
|
import { MessageResource } from '../../types'
|
|
@@ -43,6 +43,7 @@ export function MessageReaction({
|
|
|
43
43
|
return (
|
|
44
44
|
<PlatformPressable
|
|
45
45
|
key={reaction.value}
|
|
46
|
+
testID={`reaction-${message.id}-${reaction.value}`}
|
|
46
47
|
style={styles.reaction}
|
|
47
48
|
onLongPress={() => onLongPress(reaction)}
|
|
48
49
|
onPress={handlePress}
|
|
@@ -57,12 +58,12 @@ export function MessageReaction({
|
|
|
57
58
|
export const useReactionStyles = ({ mine }: { mine: number }) => {
|
|
58
59
|
const { colors } = useTheme()
|
|
59
60
|
const activeBorderColor = useMemo(() => {
|
|
60
|
-
return colorFunction(colors.interaction)
|
|
61
|
+
return colorFunction(colors.borderColorChipSelected ?? colors.interaction)
|
|
61
62
|
.hsl()
|
|
62
63
|
.lightness(colors.name === 'dark' ? 20 : 80)
|
|
63
64
|
.string()
|
|
64
|
-
}, [colors.interaction, colors.name])
|
|
65
|
-
const activeBackgroundColor =
|
|
65
|
+
}, [colors.borderColorChipSelected, colors.interaction, colors.name])
|
|
66
|
+
const activeBackgroundColor = useSelectedChipBackgroundColor()
|
|
66
67
|
|
|
67
68
|
return StyleSheet.create({
|
|
68
69
|
reaction: {
|
|
@@ -146,6 +146,7 @@ export function ConversationActions({
|
|
|
146
146
|
)}
|
|
147
147
|
>
|
|
148
148
|
<Pressable
|
|
149
|
+
testID={`conversation-${conversation.id}`}
|
|
149
150
|
onPress={handlePress}
|
|
150
151
|
style={({ pressed }) => [style, pressed && platformPressedOpacityStyle]}
|
|
151
152
|
android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
2
|
+
import { render } from '@testing-library/react-native'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { buildTestQueryClient } from '../../../__utils__/query_client'
|
|
5
|
+
import { ChatProvider, CreateChatThemeProps } from '../../../contexts/chat_context'
|
|
6
|
+
import { ToggleButton } from '../toggle_button'
|
|
7
|
+
|
|
8
|
+
let themeProps: CreateChatThemeProps
|
|
9
|
+
let queryClient: QueryClient
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
queryClient = buildTestQueryClient({
|
|
13
|
+
defaultOptions: {
|
|
14
|
+
queries: {
|
|
15
|
+
refetchInterval: false,
|
|
16
|
+
refetchOnWindowFocus: false,
|
|
17
|
+
refetchOnReconnect: false,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
queryClient.clear()
|
|
25
|
+
queryClient.cancelQueries()
|
|
26
|
+
queryClient.removeQueries()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
|
30
|
+
return (
|
|
31
|
+
<QueryClientProvider client={queryClient}>
|
|
32
|
+
<ChatProvider
|
|
33
|
+
value={{
|
|
34
|
+
token: {
|
|
35
|
+
access_token: '',
|
|
36
|
+
created_at: 0,
|
|
37
|
+
expires_in: 0,
|
|
38
|
+
scope: '',
|
|
39
|
+
refresh_token: '',
|
|
40
|
+
token_type: '',
|
|
41
|
+
},
|
|
42
|
+
onUnauthorizedResponse: () => {},
|
|
43
|
+
theme: themeProps,
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
{children}
|
|
47
|
+
</ChatProvider>
|
|
48
|
+
</QueryClientProvider>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const renderToggleButton = (active: boolean) => {
|
|
53
|
+
const view = render(<ToggleButton active={active} accessibilityLabel="Filter" title="Filter" />, {
|
|
54
|
+
wrapper: Wrapper,
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
button: view.getByLabelText('Filter'),
|
|
59
|
+
text: view.getByText('Filter'),
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe('ToggleButton chip colors', () => {
|
|
64
|
+
describe('backward compatibility (Services / sandbox pass only colors.interaction)', () => {
|
|
65
|
+
const distinctiveGreen = 'rgb(0, 255, 0)'
|
|
66
|
+
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
themeProps = {
|
|
69
|
+
theme: {
|
|
70
|
+
colors: {
|
|
71
|
+
interaction: distinctiveGreen,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
test('active state derives border, fill, and text color from colors.interaction', () => {
|
|
78
|
+
const { button, text } = renderToggleButton(true)
|
|
79
|
+
|
|
80
|
+
expect(button).toHaveStyle({ borderColor: distinctiveGreen })
|
|
81
|
+
// The active fill is the green interaction color lightened via the
|
|
82
|
+
// chip-background hook (hsl lightness 92 in the light scheme), not
|
|
83
|
+
// the raw interaction color — pins the hook's transform in place.
|
|
84
|
+
expect(button).toHaveStyle({ backgroundColor: 'hsl(120, 100%, 92%)' })
|
|
85
|
+
expect(text).toHaveStyle({ color: distinctiveGreen })
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
test.each([
|
|
89
|
+
['light', undefined, 'hsl(0, 0%, 88%)', 'hsl(0, 0%, 45%)'],
|
|
90
|
+
['dark', 'dark' as const, 'hsl(0, 0%, 24%)', 'hsl(0, 0%, 68%)'],
|
|
91
|
+
])(
|
|
92
|
+
'inactive state uses the static chip defaults in the %s scheme',
|
|
93
|
+
(_label, colorScheme, borderColor, color) => {
|
|
94
|
+
themeProps = {
|
|
95
|
+
theme: { colors: { interaction: distinctiveGreen } },
|
|
96
|
+
colorScheme,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const { button, text } = renderToggleButton(false)
|
|
100
|
+
|
|
101
|
+
expect(button).toHaveStyle({ borderColor })
|
|
102
|
+
expect(text).toHaveStyle({ color })
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
describe('explicit chip token overrides', () => {
|
|
108
|
+
const explicitBorder = 'rgb(1, 2, 3)'
|
|
109
|
+
const explicitFill = 'rgb(4, 5, 6)'
|
|
110
|
+
const explicitText = 'rgb(7, 8, 9)'
|
|
111
|
+
|
|
112
|
+
beforeEach(() => {
|
|
113
|
+
themeProps = {
|
|
114
|
+
theme: {
|
|
115
|
+
colors: {
|
|
116
|
+
interaction: 'rgb(0, 255, 0)',
|
|
117
|
+
borderColorChipSelected: explicitBorder,
|
|
118
|
+
fillColorChipSelected: explicitFill,
|
|
119
|
+
textColorChipSelected: explicitText,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
test('active state prefers explicit chip tokens over colors.interaction', () => {
|
|
126
|
+
const { button, text } = renderToggleButton(true)
|
|
127
|
+
|
|
128
|
+
expect(button).toHaveStyle({ borderColor: explicitBorder })
|
|
129
|
+
// fillColorChipSelected still passes through the chip-background hook's
|
|
130
|
+
// lightness transform, so the rendered fill isn't the raw override.
|
|
131
|
+
expect(button).toHaveStyle({ backgroundColor: 'hsl(210, 20%, 92%)' })
|
|
132
|
+
expect(text).toHaveStyle({ color: explicitText })
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
})
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useTheme,
|
|
6
6
|
useFontScale,
|
|
7
7
|
useCreateAndroidRippleColor,
|
|
8
|
-
|
|
8
|
+
useSelectedChipBackgroundColor,
|
|
9
9
|
} from '../../hooks'
|
|
10
10
|
import {
|
|
11
11
|
MAX_FONT_SIZE_MULTIPLIER_LANDMARK,
|
|
@@ -164,16 +164,20 @@ const useStyles = ({ active, maxFontSizeMultiplier }: Partial<ToggleButtonProps>
|
|
|
164
164
|
const { colors, button } = useTheme()
|
|
165
165
|
const fontScale = useFontScale({ maxFontSizeMultiplier })
|
|
166
166
|
|
|
167
|
-
const activeBackgroundColor =
|
|
167
|
+
const activeBackgroundColor = useSelectedChipBackgroundColor()
|
|
168
168
|
|
|
169
|
-
const
|
|
169
|
+
const borderColor = active
|
|
170
|
+
? (colors.borderColorChipSelected ?? colors.interaction)
|
|
171
|
+
: colors.borderColorChip
|
|
172
|
+
const fillColor = active ? activeBackgroundColor : colors.fillColorChip
|
|
173
|
+
const color = active ? (colors.textColorChipSelected ?? colors.interaction) : colors.textColorChip
|
|
170
174
|
|
|
171
175
|
return StyleSheet.create({
|
|
172
176
|
pressable: {
|
|
173
177
|
borderRadius: button.borderRadius * fontScale,
|
|
174
178
|
borderWidth: 1,
|
|
175
|
-
borderColor
|
|
176
|
-
backgroundColor:
|
|
179
|
+
borderColor,
|
|
180
|
+
backgroundColor: fillColor,
|
|
177
181
|
paddingHorizontal: 16 * fontScale,
|
|
178
182
|
flexDirection: 'row',
|
|
179
183
|
alignItems: 'center',
|
|
@@ -247,6 +247,7 @@ interface FormSheetActionProps {
|
|
|
247
247
|
appearance?: FormSheetActionAppearanceUnion
|
|
248
248
|
disabled?: boolean
|
|
249
249
|
disabledReason?: string
|
|
250
|
+
testID?: string
|
|
250
251
|
}
|
|
251
252
|
|
|
252
253
|
function FormSheetAction({
|
|
@@ -259,11 +260,13 @@ function FormSheetAction({
|
|
|
259
260
|
appearance = 'neutral',
|
|
260
261
|
disabled = false,
|
|
261
262
|
disabledReason,
|
|
263
|
+
testID,
|
|
262
264
|
}: FormSheetActionProps) {
|
|
263
265
|
const styles = useStyles({ appearance, disabled })
|
|
264
266
|
|
|
265
267
|
return (
|
|
266
268
|
<PlatformPressable
|
|
269
|
+
testID={testID}
|
|
267
270
|
onPress={onPress}
|
|
268
271
|
accessibilityLabel={accessibilityLabel}
|
|
269
272
|
accessibilityHint={
|
package/src/hooks/index.ts
CHANGED
|
@@ -13,7 +13,8 @@ export * from './use_font_scale'
|
|
|
13
13
|
export * from './use_has_direct_messages'
|
|
14
14
|
export * from './use_groups_groups'
|
|
15
15
|
export * from './use_groups'
|
|
16
|
-
export * from './
|
|
16
|
+
export * from './use_selected_chip_background_color'
|
|
17
|
+
export * from './use_interaction_tinted_background_color'
|
|
17
18
|
export * from './use_message_reaction_toggle'
|
|
18
19
|
export * from './use_new_conversation_entry'
|
|
19
20
|
export * from './use_organization'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import colorFunction from 'color'
|
|
2
|
+
import { useMemo } from 'react'
|
|
3
|
+
import { useTheme } from './use_theme'
|
|
4
|
+
|
|
5
|
+
export function useInteractionTintedBackgroundColor() {
|
|
6
|
+
const { colors } = useTheme()
|
|
7
|
+
|
|
8
|
+
return useMemo(
|
|
9
|
+
() =>
|
|
10
|
+
colorFunction(colors.interaction)
|
|
11
|
+
.hsl()
|
|
12
|
+
.lightness(colors.name === 'dark' ? 12 : 92)
|
|
13
|
+
.string(),
|
|
14
|
+
[colors.interaction, colors.name]
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import colorFunction from 'color'
|
|
2
|
+
import { useMemo } from 'react'
|
|
3
|
+
import { useTheme } from './use_theme'
|
|
4
|
+
|
|
5
|
+
export function useSelectedChipBackgroundColor() {
|
|
6
|
+
const { colors, chip } = useTheme()
|
|
7
|
+
|
|
8
|
+
return useMemo(
|
|
9
|
+
() =>
|
|
10
|
+
colorFunction(colors.fillColorChipSelected ?? colors.interaction)
|
|
11
|
+
.hsl()
|
|
12
|
+
.lightness(chip.hslLightnessChipSelected)
|
|
13
|
+
.string(),
|
|
14
|
+
[colors.fillColorChipSelected, colors.interaction, chip.hslLightnessChipSelected]
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -95,6 +95,7 @@ export function ConversationSelectTypeScreen({ route }: ConversationSelectTypeSc
|
|
|
95
95
|
)}
|
|
96
96
|
{canCreateGroupsConversations && (
|
|
97
97
|
<FormSheet.Action
|
|
98
|
+
testID="conversation-select-type-group"
|
|
98
99
|
title="Group"
|
|
99
100
|
onPress={handleGroupPress}
|
|
100
101
|
accessibilityHint="Opens group selection screen"
|
|
@@ -102,6 +103,7 @@ export function ConversationSelectTypeScreen({ route }: ConversationSelectTypeSc
|
|
|
102
103
|
)}
|
|
103
104
|
{canCreateServicesConversations && (
|
|
104
105
|
<FormSheet.Action
|
|
106
|
+
testID="conversation-select-type-team"
|
|
105
107
|
title="Team"
|
|
106
108
|
onPress={handleTeamPress}
|
|
107
109
|
accessibilityHint="Opens team selection screen"
|
|
@@ -109,6 +111,7 @@ export function ConversationSelectTypeScreen({ route }: ConversationSelectTypeSc
|
|
|
109
111
|
)}
|
|
110
112
|
{showDirectMessageOption && (
|
|
111
113
|
<FormSheet.Action
|
|
114
|
+
testID="conversation-select-type-direct-message"
|
|
112
115
|
title="Direct message"
|
|
113
116
|
onPress={handleDirectMessagePress}
|
|
114
117
|
disabled={directMessagesDisabled}
|
|
@@ -162,6 +162,7 @@ export const ListHeaderComponent = () => {
|
|
|
162
162
|
name="general.cog"
|
|
163
163
|
onPress={handleChatSettings}
|
|
164
164
|
accessibilityLabel="Chat settings"
|
|
165
|
+
testID="conversations-chat-settings-button"
|
|
165
166
|
maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER_LANDMARK}
|
|
166
167
|
/>
|
|
167
168
|
{canCreateConversations && (
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import { VideoAttachmentPreview } from '../components/display/video_attachment_preview'
|
|
30
30
|
import BannerPrimitive from '../components/primitive/banner_primitive'
|
|
31
31
|
import BlankState from '../components/primitive/blank_state_primitive'
|
|
32
|
-
import {
|
|
32
|
+
import { useSelectedChipBackgroundColor, useTheme } from '../hooks'
|
|
33
33
|
import {
|
|
34
34
|
MAX_FONT_SIZE_MULTIPLIER,
|
|
35
35
|
platformPressedOpacityStyle,
|
|
@@ -1325,7 +1325,7 @@ function HapticButton({ title, onPress }: { title: string; onPress: () => void }
|
|
|
1325
1325
|
|
|
1326
1326
|
const useStyles = () => {
|
|
1327
1327
|
const { colors } = useTheme()
|
|
1328
|
-
const
|
|
1328
|
+
const selectedChipBackgroundColor = useSelectedChipBackgroundColor()
|
|
1329
1329
|
|
|
1330
1330
|
return StyleSheet.create({
|
|
1331
1331
|
hapticButton: {
|
|
@@ -1334,7 +1334,7 @@ const useStyles = () => {
|
|
|
1334
1334
|
padding: 16,
|
|
1335
1335
|
alignItems: 'center',
|
|
1336
1336
|
justifyContent: 'center',
|
|
1337
|
-
backgroundColor:
|
|
1337
|
+
backgroundColor: selectedChipBackgroundColor,
|
|
1338
1338
|
borderWidth: 1,
|
|
1339
1339
|
borderColor: colors.interaction,
|
|
1340
1340
|
borderRadius: 8,
|
package/src/utils/theme.ts
CHANGED
|
@@ -28,6 +28,9 @@ export interface DefaultTheme {
|
|
|
28
28
|
button: {
|
|
29
29
|
borderRadius: number
|
|
30
30
|
}
|
|
31
|
+
chip: {
|
|
32
|
+
hslLightnessChipSelected: number
|
|
33
|
+
}
|
|
31
34
|
showBadgeProductLogo: boolean
|
|
32
35
|
}
|
|
33
36
|
|
|
@@ -44,6 +47,9 @@ export const defaultTheme = (colorScheme: ColorSchemeName | null): ChatTheme =>
|
|
|
44
47
|
button: {
|
|
45
48
|
borderRadius: 40,
|
|
46
49
|
},
|
|
50
|
+
chip: {
|
|
51
|
+
hslLightnessChipSelected: scheme === 'dark' ? 12 : 92,
|
|
52
|
+
},
|
|
47
53
|
showBadgeProductLogo: true, // Overrides visibility of the product logo in `src/display/badge.tsx`
|
|
48
54
|
}
|
|
49
55
|
}
|
|
@@ -91,6 +97,19 @@ interface ChatColors {
|
|
|
91
97
|
statusNeutralComposedIcon: string
|
|
92
98
|
statusNeutralComposedText: string
|
|
93
99
|
statusNeutralComposedBackground: string
|
|
100
|
+
borderColorChip: string
|
|
101
|
+
fillColorChip: string
|
|
102
|
+
textColorChip: string
|
|
103
|
+
/**
|
|
104
|
+
* Selected-chip colors (border/fill/text). Never assign a static default
|
|
105
|
+
* directly — these stay optional so they always fall back to
|
|
106
|
+
* `colors.interaction` via `??` at the read site. Every current consumer
|
|
107
|
+
* overrides `interaction` at runtime, and a seeded default here could win
|
|
108
|
+
* over that override depending on merge order.
|
|
109
|
+
*/
|
|
110
|
+
borderColorChipSelected?: string
|
|
111
|
+
fillColorChipSelected?: string
|
|
112
|
+
textColorChipSelected?: string
|
|
94
113
|
}
|
|
95
114
|
|
|
96
115
|
// 'link' is an iOS-only semantic color name — constructing it on Android is
|
|
@@ -138,6 +157,9 @@ const colorsChatLight: ChatColors = {
|
|
|
138
157
|
statusNeutralComposedIcon: tokens.iconColorStatusNeutralPrimary,
|
|
139
158
|
statusNeutralComposedText: tokens.textColorStatusNeutral,
|
|
140
159
|
statusNeutralComposedBackground: tokens.fillColorStatusNeutralGhost,
|
|
160
|
+
borderColorChip: tokens.colorNeutral88,
|
|
161
|
+
fillColorChip: 'transparent',
|
|
162
|
+
textColorChip: tokens.colorNeutral45,
|
|
141
163
|
}
|
|
142
164
|
|
|
143
165
|
const colorsChatDark: ChatColors = {
|
|
@@ -183,6 +205,9 @@ const colorsChatDark: ChatColors = {
|
|
|
183
205
|
statusNeutralComposedIcon: tokens.iconColorStatusNeutralPrimaryDark,
|
|
184
206
|
statusNeutralComposedText: tokens.textColorStatusNeutralDark,
|
|
185
207
|
statusNeutralComposedBackground: tokens.fillColorStatusNeutralGhostDark,
|
|
208
|
+
borderColorChip: tokens.colorNeutral24,
|
|
209
|
+
fillColorChip: 'transparent',
|
|
210
|
+
textColorChip: tokens.colorNeutral68,
|
|
186
211
|
}
|
|
187
212
|
|
|
188
213
|
const chatThemeColorMap = {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use_interaction_ghost_color.d.ts","sourceRoot":"","sources":["../../src/hooks/use_interaction_ghost_color.ts"],"names":[],"mappings":"AAIA,wBAAgB,kCAAkC,WAUjD"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import colorFunction from 'color';
|
|
2
|
-
import { useMemo } from 'react';
|
|
3
|
-
import { useTheme } from './use_theme';
|
|
4
|
-
export function useInteractionGhostBackgroundColor() {
|
|
5
|
-
const { colors } = useTheme();
|
|
6
|
-
const interactionGhostColor = useMemo(() => {
|
|
7
|
-
return colorFunction(colors.interaction)
|
|
8
|
-
.hsl()
|
|
9
|
-
.lightness(colors.name === 'dark' ? 12 : 92)
|
|
10
|
-
.string();
|
|
11
|
-
}, [colors.interaction, colors.name]);
|
|
12
|
-
return interactionGhostColor;
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=use_interaction_ghost_color.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use_interaction_ghost_color.js","sourceRoot":"","sources":["../../src/hooks/use_interaction_ghost_color.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,MAAM,UAAU,kCAAkC;IAChD,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAC7B,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,EAAE;QACzC,OAAO,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC;aACrC,GAAG,EAAE;aACL,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3C,MAAM,EAAE,CAAA;IACb,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IAErC,OAAO,qBAAqB,CAAA;AAC9B,CAAC","sourcesContent":["import colorFunction from 'color'\nimport { useMemo } from 'react'\nimport { useTheme } from './use_theme'\n\nexport function useInteractionGhostBackgroundColor() {\n const { colors } = useTheme()\n const interactionGhostColor = useMemo(() => {\n return colorFunction(colors.interaction)\n .hsl()\n .lightness(colors.name === 'dark' ? 12 : 92)\n .string()\n }, [colors.interaction, colors.name])\n\n return interactionGhostColor\n}\n"]}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import colorFunction from 'color'
|
|
2
|
-
import { useMemo } from 'react'
|
|
3
|
-
import { useTheme } from './use_theme'
|
|
4
|
-
|
|
5
|
-
export function useInteractionGhostBackgroundColor() {
|
|
6
|
-
const { colors } = useTheme()
|
|
7
|
-
const interactionGhostColor = useMemo(() => {
|
|
8
|
-
return colorFunction(colors.interaction)
|
|
9
|
-
.hsl()
|
|
10
|
-
.lightness(colors.name === 'dark' ? 12 : 92)
|
|
11
|
-
.string()
|
|
12
|
-
}, [colors.interaction, colors.name])
|
|
13
|
-
|
|
14
|
-
return interactionGhostColor
|
|
15
|
-
}
|