@planningcenter/chat-react-native 1.6.2-rc.1 → 1.6.2-rc.3
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/display/badge.d.ts +58 -0
- package/build/components/display/badge.d.ts.map +1 -0
- package/build/components/display/badge.js +186 -0
- package/build/components/display/badge.js.map +1 -0
- package/build/components/display/button_color_utils.d.ts +1 -1
- package/build/components/display/index.d.ts +2 -0
- package/build/components/display/index.d.ts.map +1 -1
- package/build/components/display/index.js +2 -0
- package/build/components/display/index.js.map +1 -1
- package/build/components/display/switch.d.ts +4 -0
- package/build/components/display/switch.d.ts.map +1 -0
- package/build/components/display/switch.js +14 -0
- package/build/components/display/switch.js.map +1 -0
- package/build/screens/design_system_screen.d.ts.map +1 -1
- package/build/screens/design_system_screen.js +408 -332
- package/build/screens/design_system_screen.js.map +1 -1
- package/build/utils/theme.d.ts +19 -0
- package/build/utils/theme.d.ts.map +1 -1
- package/build/utils/theme.js +37 -0
- package/build/utils/theme.js.map +1 -1
- package/build/vendor/tapestry/tokens.d.ts +30 -0
- package/build/vendor/tapestry/tokens.d.ts.map +1 -1
- package/build/vendor/tapestry/tokens.js +30 -0
- package/build/vendor/tapestry/tokens.js.map +1 -1
- package/package.json +2 -2
- package/src/components/display/badge.tsx +323 -0
- package/src/components/display/index.ts +2 -0
- package/src/components/display/switch.tsx +23 -0
- package/src/screens/design_system_screen.tsx +714 -571
- package/src/utils/theme.ts +56 -0
- package/src/vendor/tapestry/tokens.ts +30 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StyleSheet, View } from 'react-native'
|
|
3
|
+
import type { ViewStyle, TextStyle } from 'react-native'
|
|
4
|
+
import Svg, { Path, Defs, LinearGradient, Stop } from 'react-native-svg'
|
|
5
|
+
import { useFontScale, useTheme } from '../../hooks'
|
|
6
|
+
import { Icon } from './icon'
|
|
7
|
+
import { Text } from './text'
|
|
8
|
+
import { platformFontWeightMedium, space } from '../../utils'
|
|
9
|
+
import { tokens } from '../../vendor/tapestry/tokens'
|
|
10
|
+
|
|
11
|
+
// =================================
|
|
12
|
+
// ====== Constants ================
|
|
13
|
+
// =================================
|
|
14
|
+
|
|
15
|
+
const APPEARANCES = {
|
|
16
|
+
error: 'error',
|
|
17
|
+
info: 'info',
|
|
18
|
+
neutral: 'neutral',
|
|
19
|
+
success: 'success',
|
|
20
|
+
warning: 'warning',
|
|
21
|
+
} as const
|
|
22
|
+
|
|
23
|
+
type AppearanceUnion = (typeof APPEARANCES)[keyof typeof APPEARANCES]
|
|
24
|
+
|
|
25
|
+
type AppearanceColors = Record<
|
|
26
|
+
AppearanceUnion,
|
|
27
|
+
{
|
|
28
|
+
background: string
|
|
29
|
+
text: string
|
|
30
|
+
icon: string
|
|
31
|
+
}
|
|
32
|
+
>
|
|
33
|
+
|
|
34
|
+
const VARIANTS = {
|
|
35
|
+
default: 'default',
|
|
36
|
+
meta: 'meta',
|
|
37
|
+
metaSubtle: 'metaSubtle',
|
|
38
|
+
} as const
|
|
39
|
+
|
|
40
|
+
type VariantUnion = (typeof VARIANTS)[keyof typeof VARIANTS]
|
|
41
|
+
|
|
42
|
+
type VariantStyles = Record<
|
|
43
|
+
VariantUnion,
|
|
44
|
+
{
|
|
45
|
+
backgroundColor: string
|
|
46
|
+
paddingHorizontal: number
|
|
47
|
+
paddingVertical: number
|
|
48
|
+
borderWidth: number
|
|
49
|
+
borderRadius: number
|
|
50
|
+
textColor: string
|
|
51
|
+
gap: number
|
|
52
|
+
metaLabelPaddingLeft: number
|
|
53
|
+
fontWeight: TextStyle['fontWeight']
|
|
54
|
+
}
|
|
55
|
+
>
|
|
56
|
+
|
|
57
|
+
const LOGO_NAMES = {
|
|
58
|
+
groups: 'groups',
|
|
59
|
+
services: 'services',
|
|
60
|
+
} as const
|
|
61
|
+
|
|
62
|
+
type PoductLogoNameUnion = (typeof LOGO_NAMES)[keyof typeof LOGO_NAMES]
|
|
63
|
+
|
|
64
|
+
const PRODUCT_LOGO_COMPONENT_MAP = {
|
|
65
|
+
groups: GroupsLogo,
|
|
66
|
+
services: ServicesIcon,
|
|
67
|
+
} as const
|
|
68
|
+
|
|
69
|
+
// =================================
|
|
70
|
+
// ====== Component ================
|
|
71
|
+
// =================================
|
|
72
|
+
|
|
73
|
+
interface BadgeProps {
|
|
74
|
+
/**
|
|
75
|
+
* Renders the main text.
|
|
76
|
+
*/
|
|
77
|
+
label: string
|
|
78
|
+
/**
|
|
79
|
+
* Renders secondary meta text to the right of the label.
|
|
80
|
+
*/
|
|
81
|
+
metaLabel?: string
|
|
82
|
+
/**
|
|
83
|
+
* Changes the status color for the badge and icon.
|
|
84
|
+
*/
|
|
85
|
+
appearance?: AppearanceUnion
|
|
86
|
+
/**
|
|
87
|
+
* Changes form of the logo to support a meta label and badge
|
|
88
|
+
*/
|
|
89
|
+
variant?: VariantUnion
|
|
90
|
+
/**
|
|
91
|
+
* Adds a product logo to the left of the text.
|
|
92
|
+
*/
|
|
93
|
+
productLogoName?: PoductLogoNameUnion
|
|
94
|
+
/**
|
|
95
|
+
* Shows an icon of the user choice to the left of the text.
|
|
96
|
+
*/
|
|
97
|
+
iconName?: string
|
|
98
|
+
/**
|
|
99
|
+
* Styles badge wrapper.
|
|
100
|
+
*/
|
|
101
|
+
style?: ViewStyle
|
|
102
|
+
/**
|
|
103
|
+
* Specifies the maximum size a font can reach when allowFontScaling is enabled.
|
|
104
|
+
*/
|
|
105
|
+
maxFontSizeMultiplier?: number
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function Badge({
|
|
109
|
+
appearance = 'neutral',
|
|
110
|
+
metaLabel,
|
|
111
|
+
style,
|
|
112
|
+
iconName,
|
|
113
|
+
label,
|
|
114
|
+
productLogoName,
|
|
115
|
+
variant = 'default',
|
|
116
|
+
maxFontSizeMultiplier,
|
|
117
|
+
}: BadgeProps) {
|
|
118
|
+
const styles = useStyles({ appearance, maxFontSizeMultiplier, variant })
|
|
119
|
+
const { showBadgeLogo } = useTheme()
|
|
120
|
+
|
|
121
|
+
const isMetaSubtle = variant === 'metaSubtle'
|
|
122
|
+
const isMeta = variant === 'meta'
|
|
123
|
+
const hasMetaLabel = Boolean(metaLabel)
|
|
124
|
+
|
|
125
|
+
const showLogo = showBadgeLogo && productLogoName && isMeta
|
|
126
|
+
const ProductLogoSvg = showLogo && PRODUCT_LOGO_COMPONENT_MAP[productLogoName]
|
|
127
|
+
const badgeLabel = isMetaSubtle && hasMetaLabel ? `${label}:` : label
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<View style={[styles.badgeWrapper, style]}>
|
|
131
|
+
<View style={styles.badge}>
|
|
132
|
+
{showLogo && ProductLogoSvg && <ProductLogoSvg logoSize={styles.logo.fontSize} />}
|
|
133
|
+
{iconName && <Icon name={iconName} style={styles.icon} />}
|
|
134
|
+
<Text variant="footnote" style={styles.label}>
|
|
135
|
+
{badgeLabel}
|
|
136
|
+
</Text>
|
|
137
|
+
</View>
|
|
138
|
+
{hasMetaLabel && (
|
|
139
|
+
<Text variant="footnote" style={styles.metaLabel} numberOfLines={1}>
|
|
140
|
+
{metaLabel}
|
|
141
|
+
</Text>
|
|
142
|
+
)}
|
|
143
|
+
</View>
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// =================================
|
|
148
|
+
// ====== Styles ===================
|
|
149
|
+
// =================================
|
|
150
|
+
|
|
151
|
+
const useStyles = ({
|
|
152
|
+
appearance = 'neutral',
|
|
153
|
+
maxFontSizeMultiplier,
|
|
154
|
+
variant = 'default',
|
|
155
|
+
}: Partial<BadgeProps>) => {
|
|
156
|
+
const { colors } = useTheme()
|
|
157
|
+
const fontScale = useFontScale({ maxFontSizeMultiplier })
|
|
158
|
+
|
|
159
|
+
const apparenceColorMap: AppearanceColors = {
|
|
160
|
+
error: {
|
|
161
|
+
background: colors.statusErrorBackground,
|
|
162
|
+
text: colors.statusErrorText,
|
|
163
|
+
icon: colors.statusErrorIcon,
|
|
164
|
+
},
|
|
165
|
+
info: {
|
|
166
|
+
background: colors.statusInfoBackground,
|
|
167
|
+
text: colors.statusInfoText,
|
|
168
|
+
icon: colors.statusInfoIcon,
|
|
169
|
+
},
|
|
170
|
+
neutral: {
|
|
171
|
+
background: colors.statusNeutralBackground,
|
|
172
|
+
text: colors.statusNeutralText,
|
|
173
|
+
icon: colors.statusNeutralIcon,
|
|
174
|
+
},
|
|
175
|
+
success: {
|
|
176
|
+
background: colors.statusSuccessBackground,
|
|
177
|
+
text: colors.statusSuccessText,
|
|
178
|
+
icon: colors.statusSuccessIcon,
|
|
179
|
+
},
|
|
180
|
+
warning: {
|
|
181
|
+
background: colors.statusWarningBackground,
|
|
182
|
+
text: colors.statusWarningText,
|
|
183
|
+
icon: colors.statusWarningIcon,
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const badgePaddingHorizontal = space(1) * fontScale
|
|
188
|
+
const badgePaddingVertical = space(0.5) * fontScale
|
|
189
|
+
const badgeGap = space(0.5) * fontScale
|
|
190
|
+
const badgeFontSize = 12
|
|
191
|
+
|
|
192
|
+
const variantStylesMap: VariantStyles = {
|
|
193
|
+
default: {
|
|
194
|
+
gap: badgeGap,
|
|
195
|
+
backgroundColor: apparenceColorMap[appearance].background,
|
|
196
|
+
metaLabelPaddingLeft: badgePaddingHorizontal,
|
|
197
|
+
paddingHorizontal: badgePaddingHorizontal,
|
|
198
|
+
paddingVertical: badgePaddingVertical,
|
|
199
|
+
borderWidth: tokens.borderSizeDefault * fontScale,
|
|
200
|
+
borderRadius: tokens.borderRadiusMd,
|
|
201
|
+
textColor: apparenceColorMap[appearance].text,
|
|
202
|
+
fontWeight: 'normal',
|
|
203
|
+
},
|
|
204
|
+
meta: {
|
|
205
|
+
gap: badgeGap,
|
|
206
|
+
backgroundColor: apparenceColorMap[appearance].background,
|
|
207
|
+
metaLabelPaddingLeft: badgePaddingHorizontal,
|
|
208
|
+
paddingHorizontal: badgePaddingHorizontal,
|
|
209
|
+
paddingVertical: badgePaddingVertical,
|
|
210
|
+
borderWidth: tokens.borderSizeDefault * fontScale,
|
|
211
|
+
borderRadius: tokens.borderRadiusMd,
|
|
212
|
+
textColor: apparenceColorMap[appearance].text,
|
|
213
|
+
fontWeight: platformFontWeightMedium,
|
|
214
|
+
},
|
|
215
|
+
metaSubtle: {
|
|
216
|
+
gap: badgeGap,
|
|
217
|
+
backgroundColor: 'transparent',
|
|
218
|
+
metaLabelPaddingLeft: badgeGap,
|
|
219
|
+
paddingHorizontal: 0,
|
|
220
|
+
paddingVertical: 0,
|
|
221
|
+
borderWidth: 0,
|
|
222
|
+
borderRadius: 0,
|
|
223
|
+
textColor: colors.textColorDefaultSecondary,
|
|
224
|
+
fontWeight: platformFontWeightMedium,
|
|
225
|
+
},
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return StyleSheet.create({
|
|
229
|
+
badgeWrapper: {
|
|
230
|
+
flexDirection: 'row',
|
|
231
|
+
alignItems: 'center',
|
|
232
|
+
justifyContent: 'center',
|
|
233
|
+
borderRadius: variantStylesMap[variant].borderRadius,
|
|
234
|
+
borderWidth: variantStylesMap[variant].borderWidth,
|
|
235
|
+
borderColor: apparenceColorMap[appearance].background,
|
|
236
|
+
},
|
|
237
|
+
badge: {
|
|
238
|
+
flexDirection: 'row',
|
|
239
|
+
alignItems: 'center',
|
|
240
|
+
gap: variantStylesMap[variant].gap,
|
|
241
|
+
paddingVertical: variantStylesMap[variant].paddingVertical,
|
|
242
|
+
paddingHorizontal: variantStylesMap[variant].paddingHorizontal,
|
|
243
|
+
backgroundColor: variantStylesMap[variant].backgroundColor,
|
|
244
|
+
borderRadius: variantStylesMap[variant].borderRadius - 2,
|
|
245
|
+
},
|
|
246
|
+
icon: {
|
|
247
|
+
color: apparenceColorMap[appearance].icon,
|
|
248
|
+
fontSize: badgeFontSize,
|
|
249
|
+
},
|
|
250
|
+
logo: {
|
|
251
|
+
fontSize: badgeFontSize * fontScale,
|
|
252
|
+
},
|
|
253
|
+
label: {
|
|
254
|
+
color: variantStylesMap[variant].textColor,
|
|
255
|
+
fontWeight: variantStylesMap[variant].fontWeight,
|
|
256
|
+
fontSize: badgeFontSize,
|
|
257
|
+
},
|
|
258
|
+
metaLabel: {
|
|
259
|
+
paddingHorizontal: variantStylesMap[variant].paddingHorizontal,
|
|
260
|
+
fontSize: badgeFontSize,
|
|
261
|
+
flexShrink: 1,
|
|
262
|
+
paddingLeft: variantStylesMap[variant].metaLabelPaddingLeft,
|
|
263
|
+
},
|
|
264
|
+
})
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// =================================
|
|
268
|
+
// ====== Product Logos ============
|
|
269
|
+
// =================================
|
|
270
|
+
|
|
271
|
+
interface ProductLogoProps {
|
|
272
|
+
logoSize: number
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function GroupsLogo({ logoSize }: ProductLogoProps) {
|
|
276
|
+
return (
|
|
277
|
+
<Svg width={logoSize} height={logoSize} viewBox="0 0 16 16" fill="none">
|
|
278
|
+
<Path
|
|
279
|
+
d="M9.06 6.14H6.94c-.152.36-.438.646-.797.798v2.12c.359.152.645.438.797.797h2.117c.152-.359.437-.645.796-.797V6.94a1.502 1.502 0 01-.793-.8zM8 0C1.6 0 0 1.595 0 8s1.6 8 8 8 8-1.595 8-8-1.595-8-8-8zm3.939 10.44a1.5 1.5 0 01-2.882.585H6.94a1.5 1.5 0 11-1.963-1.963v-2.12A1.501 1.501 0 116.94 4.98h2.12a1.5 1.5 0 111.963 1.968v2.11a1.501 1.501 0 01.916 1.383z"
|
|
280
|
+
fill="url(#paint0_linear_2632_26363)"
|
|
281
|
+
/>
|
|
282
|
+
<Defs>
|
|
283
|
+
<LinearGradient
|
|
284
|
+
id="paint0_linear_2632_26363"
|
|
285
|
+
x1={-5.6338}
|
|
286
|
+
y1={5.6338}
|
|
287
|
+
x2={5.6338}
|
|
288
|
+
y2={16.9014}
|
|
289
|
+
gradientUnits="userSpaceOnUse"
|
|
290
|
+
>
|
|
291
|
+
<Stop stopColor="#FF962D" />
|
|
292
|
+
<Stop offset={1} stopColor="#FC7638" />
|
|
293
|
+
</LinearGradient>
|
|
294
|
+
</Defs>
|
|
295
|
+
</Svg>
|
|
296
|
+
)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function ServicesIcon({ logoSize }: ProductLogoProps) {
|
|
300
|
+
return (
|
|
301
|
+
<Svg width={logoSize} height={logoSize} viewBox="0 0 16 16" fill="none">
|
|
302
|
+
<Path
|
|
303
|
+
fillRule="evenodd"
|
|
304
|
+
clipRule="evenodd"
|
|
305
|
+
d="M.116 8c0-6.4 1.6-8 8-8s8 1.6 8 8-1.6 8-8 8-8-1.6-8-8zm4.123 3.464a.848.848 0 10.943-1.41.848.848 0 00-.943 1.41zm.001-2.76a.848.848 0 10.948-1.408.848.848 0 00-.948 1.407zm0-2.759a.849.849 0 10.948-1.408.849.849 0 00-.948 1.408zm8.1 5.34a.388.388 0 00.03-.149v-.755a.39.39 0 00-.39-.39H6.87a.39.39 0 00-.39.39v.755a.39.39 0 00.39.39h5.11a.39.39 0 00.36-.24zm0-2.758a.388.388 0 00.03-.149v-.757a.387.387 0 00-.39-.388H6.87a.388.388 0 00-.39.388v.757a.388.388 0 00.39.388h5.11a.388.388 0 00.36-.24zm0-2.76a.388.388 0 00.03-.148v-.754a.39.39 0 00-.39-.389H6.87a.39.39 0 00-.39.387v.756a.39.39 0 00.39.39h5.11a.389.389 0 00.36-.241z"
|
|
306
|
+
fill="url(#paint0_linear_2632_56586)"
|
|
307
|
+
/>
|
|
308
|
+
<Defs>
|
|
309
|
+
<LinearGradient
|
|
310
|
+
id="paint0_linear_2632_56586"
|
|
311
|
+
x1={-5.51759}
|
|
312
|
+
y1={5.6338}
|
|
313
|
+
x2={5.75001}
|
|
314
|
+
y2={16.9014}
|
|
315
|
+
gradientUnits="userSpaceOnUse"
|
|
316
|
+
>
|
|
317
|
+
<Stop stopColor="#6BB23D" />
|
|
318
|
+
<Stop offset={1} stopColor="#659630" />
|
|
319
|
+
</LinearGradient>
|
|
320
|
+
</Defs>
|
|
321
|
+
</Svg>
|
|
322
|
+
)
|
|
323
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export * from './avatar'
|
|
2
2
|
export * from './avatar_group'
|
|
3
|
+
export * from './badge'
|
|
3
4
|
export * from './button'
|
|
4
5
|
export * from './heading'
|
|
5
6
|
export * from './icon'
|
|
6
7
|
export * from './icon_button'
|
|
7
8
|
export * from './image'
|
|
8
9
|
export * from './spinner'
|
|
10
|
+
export * from './switch'
|
|
9
11
|
export * from './text'
|
|
10
12
|
export * from './text_button'
|
|
11
13
|
export * from './text_inline_button'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Switch as ReactNativeSwitch } from 'react-native'
|
|
3
|
+
import type { SwitchProps } from 'react-native'
|
|
4
|
+
import { useTheme } from '../../hooks'
|
|
5
|
+
|
|
6
|
+
// =================================
|
|
7
|
+
// ====== Component ================
|
|
8
|
+
// =================================
|
|
9
|
+
|
|
10
|
+
export function Switch({ disabled, ...props }: SwitchProps) {
|
|
11
|
+
const { colors } = useTheme()
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<ReactNativeSwitch
|
|
15
|
+
{...props}
|
|
16
|
+
trackColor={{
|
|
17
|
+
true: colors.switchTrackTrue,
|
|
18
|
+
false: colors.switchTrackFalse,
|
|
19
|
+
}}
|
|
20
|
+
thumbColor={disabled ? undefined : colors.switchThumbColor}
|
|
21
|
+
/>
|
|
22
|
+
)
|
|
23
|
+
}
|