@planningcenter/chat-react-native 3.44.2 → 3.44.3-qa-staging.1
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.js +2 -2
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_form.js +2 -2
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/conversation/message_reaction.js +4 -4
- package/build/components/conversation/message_reaction.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/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 +6 -0
- package/build/hooks/use_interaction_tinted_background_color.d.ts.map +1 -0
- package/build/hooks/use_interaction_tinted_background_color.js +15 -0
- package/build/hooks/use_interaction_tinted_background_color.js.map +1 -0
- package/build/hooks/use_rest_away_from_dismiss_edge.d.ts +4 -0
- package/build/hooks/use_rest_away_from_dismiss_edge.d.ts.map +1 -1
- package/build/hooks/use_rest_away_from_dismiss_edge.js +4 -0
- package/build/hooks/use_rest_away_from_dismiss_edge.js.map +1 -1
- package/build/hooks/use_selected_chip_background_color.d.ts +7 -0
- package/build/hooks/use_selected_chip_background_color.d.ts.map +1 -0
- package/build/hooks/use_selected_chip_background_color.js +16 -0
- package/build/hooks/use_selected_chip_background_color.js.map +1 -0
- package/build/screens/design_system_screen.js +3 -3
- package/build/screens/design_system_screen.js.map +1 -1
- package/build/utils/response_error.d.ts.map +1 -1
- package/build/utils/response_error.js +3 -2
- package/build/utils/response_error.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_interaction_tinted_background_color.test.tsx +67 -0
- 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 +2 -2
- package/src/components/conversation/message_form.tsx +2 -2
- package/src/components/conversation/message_reaction.tsx +4 -4
- package/src/components/display/__tests__/toggle_button.test.tsx +135 -0
- package/src/components/display/toggle_button.tsx +9 -5
- package/src/hooks/index.ts +2 -1
- package/src/hooks/use_interaction_tinted_background_color.ts +20 -0
- package/src/hooks/use_rest_away_from_dismiss_edge.ts +4 -0
- package/src/hooks/use_selected_chip_background_color.ts +21 -0
- package/src/screens/design_system_screen.tsx +3 -3
- package/src/types/whatwg-fetch.d.ts +5 -0
- package/src/utils/__tests__/response_error.test.ts +13 -0
- package/src/utils/response_error.ts +3 -2
- package/src/utils/theme.ts +28 -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,21 @@
|
|
|
1
|
+
import colorFunction from 'color'
|
|
2
|
+
import { useMemo } from 'react'
|
|
3
|
+
import { useTheme } from './use_theme'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Background color for a chip surface (filter button, reaction pill) in its
|
|
7
|
+
* selected state. Falls back to `colors.interaction` when a consumer hasn't
|
|
8
|
+
* supplied `colors.fillColorChipSelected`.
|
|
9
|
+
*/
|
|
10
|
+
export function useSelectedChipBackgroundColor() {
|
|
11
|
+
const { colors, chip } = useTheme()
|
|
12
|
+
|
|
13
|
+
return useMemo(
|
|
14
|
+
() =>
|
|
15
|
+
colorFunction(colors.fillColorChipSelected ?? colors.interaction)
|
|
16
|
+
.hsl()
|
|
17
|
+
.lightness(chip.hslLightnessChipSelected)
|
|
18
|
+
.string(),
|
|
19
|
+
[colors.fillColorChipSelected, colors.interaction, chip.hslLightnessChipSelected]
|
|
20
|
+
)
|
|
21
|
+
}
|
|
@@ -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,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Response as ReactNativeResponse } from 'whatwg-fetch'
|
|
2
|
+
|
|
1
3
|
import { isResponseLike, ResponseError, throwResponseError } from '../response_error'
|
|
2
4
|
|
|
3
5
|
// Mimics Expo's winter `FetchResponse`: the full Response shape, but NOT an
|
|
@@ -24,6 +26,17 @@ describe('isResponseLike', () => {
|
|
|
24
26
|
expect(isResponseLike(notARealResponse)).toBe(true)
|
|
25
27
|
})
|
|
26
28
|
|
|
29
|
+
it("recognizes React Native's fetch Response, which never assigns `redirected`", () => {
|
|
30
|
+
const response = new ReactNativeResponse(JSON.stringify({ errors: [] }), {
|
|
31
|
+
status: 401,
|
|
32
|
+
statusText: 'Unauthorized',
|
|
33
|
+
headers: { 'Content-Type': 'application/json' },
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
expect('redirected' in response).toBe(false)
|
|
37
|
+
expect(isResponseLike(response)).toBe(true)
|
|
38
|
+
})
|
|
39
|
+
|
|
27
40
|
it('rejects things that are not responses', () => {
|
|
28
41
|
expect(isResponseLike(null)).toBe(false)
|
|
29
42
|
expect(isResponseLike(new Error('boom'))).toBe(false)
|
|
@@ -18,7 +18,9 @@ export class ResponseError extends Error {
|
|
|
18
18
|
|
|
19
19
|
// Detect a fetch Response by shape, not `instanceof`: Expo's winter runtime
|
|
20
20
|
// swaps in a `fetch` whose `FetchResponse` isn't an instance of the global
|
|
21
|
-
// `Response`, so `instanceof` silently misses it under Expo.
|
|
21
|
+
// `Response`, so `instanceof` silently misses it under Expo. We avoid checking
|
|
22
|
+
// `redirected` because React Native's whatwg-fetch polyfill never assigns it,
|
|
23
|
+
// which would reject every real response under RN's fetch.
|
|
22
24
|
export const isResponseLike = (value: unknown): value is Response => {
|
|
23
25
|
if (typeof value !== 'object' || value === null) return false
|
|
24
26
|
|
|
@@ -27,7 +29,6 @@ export const isResponseLike = (value: unknown): value is Response => {
|
|
|
27
29
|
typeof candidate.status === 'number' &&
|
|
28
30
|
typeof candidate.statusText === 'string' &&
|
|
29
31
|
typeof candidate.ok === 'boolean' &&
|
|
30
|
-
typeof candidate.redirected === 'boolean' &&
|
|
31
32
|
typeof candidate.url === 'string' &&
|
|
32
33
|
typeof candidate.headers === 'object' &&
|
|
33
34
|
candidate.headers !== null &&
|
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,22 @@ interface ChatColors {
|
|
|
91
97
|
statusNeutralComposedIcon: string
|
|
92
98
|
statusNeutralComposedText: string
|
|
93
99
|
statusNeutralComposedBackground: string
|
|
100
|
+
// borderColorChip / textColorChip match the alias tokens
|
|
101
|
+
// `borderColorDefaultBase` / `textColorDefaultSecondary` the unselected
|
|
102
|
+
// `ToggleButton` state used before dedicated chip tokens existed.
|
|
103
|
+
borderColorChip: string
|
|
104
|
+
fillColorChip: string
|
|
105
|
+
textColorChip: string
|
|
106
|
+
/**
|
|
107
|
+
* Selected-chip colors (border/fill/text). Never assign a static default
|
|
108
|
+
* directly — these stay optional so they always fall back to
|
|
109
|
+
* `colors.interaction` via `??` at the read site. Every current consumer
|
|
110
|
+
* overrides `interaction` at runtime, and a seeded default here could win
|
|
111
|
+
* over that override depending on merge order.
|
|
112
|
+
*/
|
|
113
|
+
borderColorChipSelected?: string
|
|
114
|
+
fillColorChipSelected?: string
|
|
115
|
+
textColorChipSelected?: string
|
|
94
116
|
}
|
|
95
117
|
|
|
96
118
|
// 'link' is an iOS-only semantic color name — constructing it on Android is
|
|
@@ -138,6 +160,9 @@ const colorsChatLight: ChatColors = {
|
|
|
138
160
|
statusNeutralComposedIcon: tokens.iconColorStatusNeutralPrimary,
|
|
139
161
|
statusNeutralComposedText: tokens.textColorStatusNeutral,
|
|
140
162
|
statusNeutralComposedBackground: tokens.fillColorStatusNeutralGhost,
|
|
163
|
+
borderColorChip: tokens.colorNeutral88,
|
|
164
|
+
fillColorChip: 'transparent',
|
|
165
|
+
textColorChip: tokens.colorNeutral45,
|
|
141
166
|
}
|
|
142
167
|
|
|
143
168
|
const colorsChatDark: ChatColors = {
|
|
@@ -183,6 +208,9 @@ const colorsChatDark: ChatColors = {
|
|
|
183
208
|
statusNeutralComposedIcon: tokens.iconColorStatusNeutralPrimaryDark,
|
|
184
209
|
statusNeutralComposedText: tokens.textColorStatusNeutralDark,
|
|
185
210
|
statusNeutralComposedBackground: tokens.fillColorStatusNeutralGhostDark,
|
|
211
|
+
borderColorChip: tokens.colorNeutral24,
|
|
212
|
+
fillColorChip: 'transparent',
|
|
213
|
+
textColorChip: tokens.colorNeutral68,
|
|
186
214
|
}
|
|
187
215
|
|
|
188
216
|
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
|
-
}
|