@planningcenter/chat-react-native 2.2.0-rc.0 → 2.2.0-rc.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.
Files changed (62) hide show
  1. package/build/components/display/badge.d.ts +2 -9
  2. package/build/components/display/badge.d.ts.map +1 -1
  3. package/build/components/display/badge.js +8 -40
  4. package/build/components/display/badge.js.map +1 -1
  5. package/build/components/display/banner.d.ts +29 -0
  6. package/build/components/display/banner.d.ts.map +1 -0
  7. package/build/components/display/banner.js +16 -0
  8. package/build/components/display/banner.js.map +1 -0
  9. package/build/components/display/button.d.ts +1 -1
  10. package/build/components/display/button.d.ts.map +1 -1
  11. package/build/components/display/button.js +1 -1
  12. package/build/components/display/button.js.map +1 -1
  13. package/build/components/display/icon_button.d.ts +1 -1
  14. package/build/components/display/icon_button.d.ts.map +1 -1
  15. package/build/components/display/icon_button.js +1 -1
  16. package/build/components/display/icon_button.js.map +1 -1
  17. package/build/components/display/index.d.ts +1 -0
  18. package/build/components/display/index.d.ts.map +1 -1
  19. package/build/components/display/index.js +1 -0
  20. package/build/components/display/index.js.map +1 -1
  21. package/build/components/display/text_button.d.ts +1 -1
  22. package/build/components/display/text_button.d.ts.map +1 -1
  23. package/build/components/display/text_button.js +1 -1
  24. package/build/components/display/text_button.js.map +1 -1
  25. package/build/components/display/text_inline_button.d.ts +2 -2
  26. package/build/components/display/text_inline_button.d.ts.map +1 -1
  27. package/build/components/display/text_inline_button.js +3 -2
  28. package/build/components/display/text_inline_button.js.map +1 -1
  29. package/build/components/display/{button_color_utils.d.ts → utils/button_colors.d.ts} +1 -1
  30. package/build/components/display/utils/button_colors.d.ts.map +1 -0
  31. package/build/components/display/{button_color_utils.js → utils/button_colors.js} +2 -2
  32. package/build/components/display/utils/button_colors.js.map +1 -0
  33. package/build/components/display/utils/status_colors.d.ts +17 -0
  34. package/build/components/display/utils/status_colors.d.ts.map +1 -0
  35. package/build/components/display/utils/status_colors.js +49 -0
  36. package/build/components/display/utils/status_colors.js.map +1 -0
  37. package/build/components/primitive/banner_primitive.d.ts +38 -0
  38. package/build/components/primitive/banner_primitive.d.ts.map +1 -0
  39. package/build/components/primitive/banner_primitive.js +112 -0
  40. package/build/components/primitive/banner_primitive.js.map +1 -0
  41. package/build/hooks/use_font_scale.d.ts +1 -1
  42. package/build/hooks/use_font_scale.d.ts.map +1 -1
  43. package/build/hooks/use_font_scale.js +1 -1
  44. package/build/hooks/use_font_scale.js.map +1 -1
  45. package/build/screens/design_system_screen.d.ts.map +1 -1
  46. package/build/screens/design_system_screen.js +24 -1
  47. package/build/screens/design_system_screen.js.map +1 -1
  48. package/package.json +2 -2
  49. package/src/components/display/badge.tsx +9 -53
  50. package/src/components/display/banner.tsx +56 -0
  51. package/src/components/display/button.tsx +2 -2
  52. package/src/components/display/icon_button.tsx +2 -2
  53. package/src/components/display/index.ts +1 -0
  54. package/src/components/display/text_button.tsx +2 -2
  55. package/src/components/display/text_inline_button.tsx +4 -2
  56. package/src/components/display/{button_color_utils.ts → utils/button_colors.ts} +1 -1
  57. package/src/components/display/utils/status_colors.ts +85 -0
  58. package/src/components/primitive/banner_primitive.tsx +247 -0
  59. package/src/hooks/use_font_scale.ts +3 -1
  60. package/src/screens/design_system_screen.tsx +56 -0
  61. package/build/components/display/button_color_utils.d.ts.map +0 -1
  62. package/build/components/display/button_color_utils.js.map +0 -1
@@ -0,0 +1,85 @@
1
+ import { useTheme } from '../../../hooks'
2
+
3
+ // =================================
4
+ // ====== Exports ==================
5
+ // =================================
6
+
7
+ export { useStatusColorAppearanceMap }
8
+ export type { StatusAppearanceUnion }
9
+
10
+ // =================================
11
+ // ====== Constants ================
12
+ // =================================
13
+
14
+ const STATUS_APPEARANCES = {
15
+ error: 'error',
16
+ info: 'info',
17
+ neutral: 'neutral',
18
+ success: 'success',
19
+ warning: 'warning',
20
+ } as const
21
+
22
+ type StatusAppearanceUnion = (typeof STATUS_APPEARANCES)[keyof typeof STATUS_APPEARANCES]
23
+
24
+ type StatusAppearanceColors = Record<
25
+ StatusAppearanceUnion,
26
+ {
27
+ background: string
28
+ text: string
29
+ icon: string
30
+ }
31
+ >
32
+
33
+ // =================================
34
+ // ====== Hooks ====================
35
+ // =================================
36
+
37
+ function useStatusColorAppearanceMap(): StatusAppearanceColors {
38
+ const {
39
+ colors: {
40
+ statusErrorBackground,
41
+ statusErrorText,
42
+ statusErrorIcon,
43
+ statusInfoBackground,
44
+ statusInfoText,
45
+ statusInfoIcon,
46
+ statusNeutralBackground,
47
+ statusNeutralText,
48
+ statusNeutralIcon,
49
+ statusSuccessBackground,
50
+ statusSuccessText,
51
+ statusSuccessIcon,
52
+ statusWarningBackground,
53
+ statusWarningText,
54
+ statusWarningIcon,
55
+ },
56
+ } = useTheme()
57
+
58
+ return {
59
+ error: {
60
+ background: statusErrorBackground,
61
+ text: statusErrorText,
62
+ icon: statusErrorIcon,
63
+ },
64
+ info: {
65
+ background: statusInfoBackground,
66
+ text: statusInfoText,
67
+ icon: statusInfoIcon,
68
+ },
69
+ neutral: {
70
+ background: statusNeutralBackground,
71
+ text: statusNeutralText,
72
+ icon: statusNeutralIcon,
73
+ },
74
+ success: {
75
+ background: statusSuccessBackground,
76
+ text: statusSuccessText,
77
+ icon: statusSuccessIcon,
78
+ },
79
+ warning: {
80
+ background: statusWarningBackground,
81
+ text: statusWarningText,
82
+ icon: statusWarningIcon,
83
+ },
84
+ }
85
+ }
@@ -0,0 +1,247 @@
1
+ import React, { createContext, FC, ReactNode, useContext } from 'react'
2
+ import { StyleSheet, View } from 'react-native'
3
+ import {
4
+ useStatusColorAppearanceMap,
5
+ type StatusAppearanceUnion,
6
+ } from '../display/utils/status_colors'
7
+ import { MAX_FONT_SIZE_MULTIPLIER, platformFontWeightMedium, space } from '../../utils'
8
+ import { tokens } from '../../vendor/tapestry/tokens'
9
+ import { Heading, Icon, Text, TextInlineButton } from '../display'
10
+ import { useFontScale } from '../../hooks'
11
+
12
+ // ========================================
13
+ // ====== Exports =========================
14
+ // ========================================
15
+
16
+ const Banner = {
17
+ Root: BannerRoot,
18
+ StaticLayout: BannerStaticLayout,
19
+ Content: BannerContent,
20
+ StatusIcon: BannerStatusIcon,
21
+ Heading: BannerHeading,
22
+ Text: BannerText,
23
+ Link: BannerLink,
24
+ } as const
25
+
26
+ type BannerComponents = {
27
+ Root: FC<BannerRootProps>
28
+ StaticLayout: FC<BannerStaticLayoutProps>
29
+ Content: FC<BannerContentProps>
30
+ StatusIcon: FC<BannerStatusIconProps>
31
+ Heading: FC<BannerHeadingProps>
32
+ Text: FC<BannerTextProps>
33
+ Link: FC<BannerLinkProps>
34
+ }
35
+
36
+ export default Banner as BannerComponents
37
+ export type {
38
+ BannerRootProps,
39
+ BannerStaticLayoutProps,
40
+ BannerContentProps,
41
+ BannerStatusIconProps,
42
+ BannerHeadingProps,
43
+ BannerTextProps,
44
+ BannerLinkProps,
45
+ }
46
+
47
+ // ========================================
48
+ // ====== Context =========================
49
+ // ========================================
50
+
51
+ interface BannerContextType {
52
+ appearance?: StatusAppearanceUnion
53
+ }
54
+
55
+ const BannerContext = createContext<BannerContextType | null>(null)
56
+
57
+ function useBannerContext() {
58
+ const context = useContext(BannerContext)
59
+ if (!context) {
60
+ throw new Error('Banner components must be used within Banner.Root')
61
+ }
62
+ return context
63
+ }
64
+
65
+ // ========================================
66
+ // ====== BannerRoot ======================
67
+ // ========================================
68
+
69
+ interface BannerRootProps {
70
+ children: ReactNode
71
+ appearance?: StatusAppearanceUnion
72
+ }
73
+
74
+ function BannerRoot({ children, appearance = 'neutral' }: BannerRootProps) {
75
+ return <BannerContext.Provider value={{ appearance }}>{children}</BannerContext.Provider>
76
+ }
77
+
78
+ BannerRoot.displayName = 'Banner.Root'
79
+
80
+ // ========================================
81
+ // ====== BannerStaticLayout ==============
82
+ // ========================================
83
+
84
+ interface BannerStaticLayoutProps {
85
+ children: ReactNode
86
+ }
87
+
88
+ function BannerStaticLayout({ children }: BannerStaticLayoutProps) {
89
+ const { appearance } = useBannerContext()
90
+ const styles = useStyles({ appearance })
91
+
92
+ return <View style={styles.staticLayout}>{children}</View>
93
+ }
94
+
95
+ BannerStaticLayout.displayName = 'Banner.StaticLayout'
96
+
97
+ // ========================================
98
+ // ====== BannerContent ===================
99
+ // ========================================
100
+
101
+ interface BannerContentProps {
102
+ children: ReactNode
103
+ }
104
+
105
+ function BannerContent({ children }: BannerContentProps) {
106
+ const styles = useStyles()
107
+
108
+ return <View style={styles.content}>{children}</View>
109
+ }
110
+
111
+ BannerContent.displayName = 'Banner.Content'
112
+
113
+ // ========================================
114
+ // ====== BannerStatusIcon ================
115
+ // ========================================
116
+
117
+ interface BannerStatusIconProps {
118
+ iconName?: string
119
+ }
120
+
121
+ function BannerStatusIcon({ iconName }: BannerStatusIconProps) {
122
+ const { appearance = 'neutral' } = useBannerContext()
123
+ const styles = useStyles({ appearance })
124
+
125
+ const iconNameMap = {
126
+ error: 'general.exclamationTriangle',
127
+ info: 'general.outlinedInfoCircle',
128
+ neutral: 'general.outlinedInfoCircle',
129
+ success: 'general.check',
130
+ warning: 'general.exclamationTriangle',
131
+ } as const
132
+
133
+ return (
134
+ <Icon
135
+ name={iconName || iconNameMap[appearance]}
136
+ style={styles.icon}
137
+ maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER}
138
+ />
139
+ )
140
+ }
141
+
142
+ BannerStatusIcon.displayName = 'Banner.StatusIcon'
143
+
144
+ // ========================================
145
+ // ====== BannerHeading ===================
146
+ // ========================================
147
+
148
+ interface BannerHeadingProps {
149
+ children: ReactNode
150
+ }
151
+
152
+ function BannerHeading({ children }: BannerHeadingProps) {
153
+ const { appearance = 'neutral' } = useBannerContext()
154
+ const styles = useStyles({ appearance })
155
+
156
+ return (
157
+ <Heading variant="h3" style={styles.heading}>
158
+ {children}
159
+ </Heading>
160
+ )
161
+ }
162
+
163
+ BannerHeading.displayName = 'Banner.Heading'
164
+
165
+ // ========================================
166
+ // ====== BannerText ======================
167
+ // ========================================
168
+
169
+ interface BannerTextProps {
170
+ children: ReactNode
171
+ }
172
+
173
+ function BannerText({ children }: BannerTextProps) {
174
+ const { appearance = 'neutral' } = useBannerContext()
175
+ const styles = useStyles({ appearance })
176
+
177
+ return (
178
+ <Text variant="tertiary" style={styles.text}>
179
+ {children}
180
+ </Text>
181
+ )
182
+ }
183
+
184
+ BannerText.displayName = 'Banner.Text'
185
+
186
+ // ========================================
187
+ // ====== BannerLink ======================
188
+ // ========================================
189
+
190
+ interface BannerLinkProps {
191
+ children: ReactNode
192
+ onPress?: () => void
193
+ }
194
+
195
+ function BannerLink({ children, onPress }: BannerLinkProps) {
196
+ const { appearance = 'neutral' } = useBannerContext()
197
+ const styles = useStyles({ appearance })
198
+
199
+ return (
200
+ <TextInlineButton variant="tertiary" style={styles.text} onPress={onPress}>
201
+ {children}
202
+ </TextInlineButton>
203
+ )
204
+ }
205
+
206
+ BannerLink.displayName = 'Banner.Link'
207
+
208
+ // ========================================
209
+ // ====== Styles ==========================
210
+ // ========================================
211
+
212
+ interface Styles {
213
+ appearance?: StatusAppearanceUnion
214
+ }
215
+
216
+ const useStyles = ({ appearance = 'neutral' }: Styles = {}) => {
217
+ const statusColorMap = useStatusColorAppearanceMap()
218
+ const fontScale = useFontScale()
219
+
220
+ return StyleSheet.create({
221
+ staticLayout: {
222
+ flexDirection: 'row',
223
+ backgroundColor: statusColorMap[appearance].background,
224
+ padding: space(1.5),
225
+ gap: space(1),
226
+ borderRadius: tokens.borderRadiusMd,
227
+ flex: 1,
228
+ },
229
+ content: {
230
+ gap: space(0.5),
231
+ flex: 1,
232
+ },
233
+ icon: {
234
+ color: statusColorMap[appearance].icon,
235
+ fontSize: tokens.fontSizeMd,
236
+ marginTop: space(0.5) * fontScale,
237
+ },
238
+ heading: {
239
+ color: statusColorMap[appearance].text,
240
+ fontWeight: platformFontWeightMedium,
241
+ fontSize: tokens.fontSizeMd,
242
+ },
243
+ text: {
244
+ color: statusColorMap[appearance].text,
245
+ },
246
+ })
247
+ }
@@ -1,6 +1,8 @@
1
1
  import { useWindowDimensions } from 'react-native'
2
2
 
3
- export const useFontScale = ({ maxFontSizeMultiplier }: { maxFontSizeMultiplier?: number }) => {
3
+ export const useFontScale = ({
4
+ maxFontSizeMultiplier,
5
+ }: { maxFontSizeMultiplier?: number } = {}) => {
4
6
  const { fontScale: nativeFontScale } = useWindowDimensions()
5
7
  const scaleLimit = maxFontSizeMultiplier || nativeFontScale
6
8
  const fontScale = Math.min(scaleLimit, nativeFontScale)
@@ -6,6 +6,7 @@ import {
6
6
  Avatar,
7
7
  AvatarGroup,
8
8
  Badge,
9
+ Banner,
9
10
  Button,
10
11
  Heading,
11
12
  Icon,
@@ -23,6 +24,7 @@ import {
23
24
  platformPressedOpacityStyle,
24
25
  platformFontWeightMedium,
25
26
  } from '../utils'
27
+ import BannerPrimitive from '../components/primitive/banner_primitive'
26
28
 
27
29
  // =================================
28
30
  // ====== Docs Utils ===============
@@ -756,6 +758,47 @@ function StatusComponentsSection({ isLast }: SectionProps) {
756
758
  <Badge variant="metaSubtle" productLogoName="services" label="Team" />
757
759
  </Row>
758
760
  </Group>
761
+ <Group
762
+ title="Banner"
763
+ description="Banners that can convey a status with color and an optional icon. They render a description and optional heading. A `Banner.Link` can be used by wrapping it in `Banner.Text` and passing it to `description`. Target products can change colors via theming."
764
+ >
765
+ <Column>
766
+ <Banner
767
+ appearance="neutral"
768
+ showIcon={false}
769
+ description="Et sint Quis non excepturi enim et conseq atur porro est galisum labore ea volupt."
770
+ />
771
+ <Banner
772
+ appearance="info"
773
+ heading="Banner heading"
774
+ description="Et sint Quis non excepturi enim et conseq atur porro est galisum labore ea volupt."
775
+ />
776
+ <Banner
777
+ appearance="success"
778
+ heading="Banner heading"
779
+ description={
780
+ <BannerPrimitive.Text>
781
+ Et sint Quis non excepturi{' '}
782
+ <BannerPrimitive.Link onPress={buttonPress}>
783
+ enim et conseq atur porro est
784
+ </BannerPrimitive.Link>{' '}
785
+ galisum labore ea volupt.
786
+ </BannerPrimitive.Text>
787
+ }
788
+ />
789
+ <Banner
790
+ appearance="warning"
791
+ iconName="general.shieldExclamation"
792
+ heading="13 members under age 13"
793
+ description="Et sint Quis non excepturi enim et conseq atur porro est galisum labore ea volupt."
794
+ />
795
+ <Banner
796
+ appearance="error"
797
+ heading="Banner heading"
798
+ description="Et sint Quis non excepturi enim et conseq atur porro est galisum labore ea volupt."
799
+ />
800
+ </Column>
801
+ </Group>
759
802
  </CollapsableSection>
760
803
  )
761
804
  }
@@ -818,6 +861,16 @@ function Row({ children, style }: RowProps) {
818
861
  return <View style={[styles.row, style]}>{children}</View>
819
862
  }
820
863
 
864
+ interface ColumnProps {
865
+ children: React.ReactNode
866
+ style?: ViewStyle
867
+ }
868
+
869
+ function Column({ children, style }: ColumnProps) {
870
+ const styles = useStyles()
871
+ return <View style={[styles.column, style]}>{children}</View>
872
+ }
873
+
821
874
  function TextGroup({ children }: { children: React.ReactNode }) {
822
875
  const styles = useStyles()
823
876
  return <View style={styles.textGroup}>{children}</View>
@@ -893,6 +946,9 @@ const useStyles = () => {
893
946
  justifyContent: 'center',
894
947
  flexWrap: 'wrap',
895
948
  },
949
+ column: {
950
+ gap: space(2),
951
+ },
896
952
  textRow: {
897
953
  gap: space(1.5),
898
954
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"button_color_utils.d.ts","sourceRoot":"","sources":["../../../src/components/display/button_color_utils.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,CAAA;AACjG,YAAY,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,CAAA;AAMhE,QAAA,MAAM,kBAAkB;;;CAGd,CAAA;AAEV,KAAK,qBAAqB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAA;AAEzF,QAAA,MAAM,uBAAuB;;;;CAGnB,CAAA;AAEV,KAAK,yBAAyB,GAC5B,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,OAAO,uBAAuB,CAAC,CAAA;AAExE,QAAA,MAAM,oBAAoB;;;;CAGhB,CAAA;AAEV,KAAK,sBAAsB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,OAAO,oBAAoB,CAAC,CAAA;AAE9F,QAAA,MAAM,yBAAyB;;;;;CAGrB,CAAA;AAEV,KAAK,0BAA0B,GAC7B,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,OAAO,yBAAyB,CAAC,CAAA;AAM5E,KAAK,oBAAoB,GAAG,MAAM,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAA;AAClE,iBAAS,uBAAuB,IAAI,oBAAoB,CAQvD;AAED,KAAK,wBAAwB,GAAG,MAAM,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAA;AAC1E,iBAAS,2BAA2B,IAAI,wBAAwB,CAS/D;AAED,KAAK,gBAAgB,GAAG,MAAM,CAAC,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AACxE,iBAAS,mBAAmB,IAAI,gBAAgB,CAc/C;AAMD,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,EAAE,qBAAqB,GAAG,yBAAyB,CAAA;CAC9D;AACD,iBAAS,WAAW,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,eAAe,qDAGtE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"button_color_utils.js","sourceRoot":"","sources":["../../../src/components/display/button_color_utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,oCAAoC;AACpC,oCAAoC;AACpC,oCAAoC;AAEpC,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,CAAA;AAGjG,oCAAoC;AACpC,oCAAoC;AACpC,oCAAoC;AAEpC,MAAM,kBAAkB,GAAG;IACzB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,aAAa;CAClB,CAAA;AAIV,MAAM,uBAAuB,GAAG;IAC9B,GAAG,kBAAkB;IACrB,OAAO,EAAE,SAAS;CACV,CAAA;AAKV,MAAM,oBAAoB,GAAG;IAC3B,GAAG,kBAAkB;IACrB,QAAQ,EAAE,UAAU;CACZ,CAAA;AAIV,MAAM,yBAAyB,GAAG;IAChC,GAAG,oBAAoB;IACvB,GAAG,uBAAuB;CAClB,CAAA;AAUV,SAAS,uBAAuB;IAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,MAAM,EAAE,MAAM,CAAC,0BAA0B;QACzC,QAAQ,EAAE,MAAM,CAAC,wBAAwB;KAC1C,CAAA;AACH,CAAC;AAGD,SAAS,2BAA2B;IAClC,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,0BAA0B;QACzC,QAAQ,EAAE,MAAM,CAAC,wBAAwB;QACzC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,OAAO,EAAE,MAAM,CAAC,yBAAyB;KAC1C,CAAA;AACH,CAAC;AAGD,SAAS,mBAAmB;IAC1B,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,MAAM,iBAAiB,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAA;IAClE,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,WAAW,CAAA;IAE9D,OAAO;QACL,WAAW,EAAE,CAAC,iBAAiB,EAAE,eAAe,CAAC;QACjD,MAAM,EAAE,CAAC,MAAM,CAAC,0BAA0B,EAAE,MAAM,CAAC,0BAA0B,CAAC;QAC9E,QAAQ,EAAE;YACR,MAAM,CAAC,mCAAmC;YAC1C,MAAM,CAAC,mCAAmC;SAC3C;KACF,CAAA;AACH,CAAC;AAWD,SAAS,WAAW,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAmB;IACrE,IAAI,QAAQ,IAAI,OAAO;QAAE,OAAO,UAAU,CAAA;IAC1C,OAAO,UAAU,CAAA;AACnB,CAAC","sourcesContent":["import { useTheme } from '../../hooks'\n\n// =================================\n// ====== Exports ==================\n// =================================\n\nexport { getColorKey, useButtonColorOptionMap, useGradientColorMap, useIconButtonColorOptionMap }\nexport type { ButtonAppearanceUnion, IconButtonAppearanceUnion }\n\n// =================================\n// ====== Constants ================\n// =================================\n\nconst BUTTON_APPEARANCES = {\n danger: 'danger',\n interaction: 'interaction',\n} as const\n\ntype ButtonAppearanceUnion = (typeof BUTTON_APPEARANCES)[keyof typeof BUTTON_APPEARANCES]\n\nconst ICON_BUTTON_APPEARANCES = {\n ...BUTTON_APPEARANCES,\n neutral: 'neutral',\n} as const\n\ntype IconButtonAppearanceUnion =\n (typeof ICON_BUTTON_APPEARANCES)[keyof typeof ICON_BUTTON_APPEARANCES]\n\nconst BUTTON_COLOR_OPTIONS = {\n ...BUTTON_APPEARANCES,\n disabled: 'disabled',\n} as const\n\ntype ButtonColorOptionUnion = (typeof BUTTON_COLOR_OPTIONS)[keyof typeof BUTTON_COLOR_OPTIONS]\n\nconst ICON_BUTTON_COLOR_OPTIONS = {\n ...BUTTON_COLOR_OPTIONS,\n ...ICON_BUTTON_APPEARANCES,\n} as const\n\ntype IconButtonColorOptionUnion =\n (typeof ICON_BUTTON_COLOR_OPTIONS)[keyof typeof ICON_BUTTON_COLOR_OPTIONS]\n\n// =================================\n// ====== Hooks ====================\n// =================================\n\ntype ButtonColorOptionMap = Record<ButtonColorOptionUnion, string>\nfunction useButtonColorOptionMap(): ButtonColorOptionMap {\n const { colors } = useTheme()\n\n return {\n interaction: colors.interaction,\n danger: colors.fillColorStatusErrorMedium,\n disabled: colors.textColorDefaultDisabled,\n }\n}\n\ntype IconButtonColorOptionMap = Record<IconButtonColorOptionUnion, string>\nfunction useIconButtonColorOptionMap(): IconButtonColorOptionMap {\n const { colors } = useTheme()\n\n return {\n danger: colors.fillColorStatusErrorMedium,\n disabled: colors.textColorDefaultDisabled,\n interaction: colors.interaction,\n neutral: colors.iconColorDefaultSecondary,\n }\n}\n\ntype GradientColorMap = Record<ButtonColorOptionUnion, [string, string]>\nfunction useGradientColorMap(): GradientColorMap {\n const { colors } = useTheme()\n\n const defaultColorStart = colors.buttonStart || colors.interaction\n const defaultColorEnd = colors.buttonEnd || colors.interaction\n\n return {\n interaction: [defaultColorStart, defaultColorEnd],\n danger: [colors.fillColorStatusErrorMedium, colors.fillColorStatusErrorMedium],\n disabled: [\n colors.fillColorButtonNeutralSolidDisabled,\n colors.fillColorButtonNeutralSolidDisabled,\n ],\n }\n}\n\n// =================================\n// ====== Functions ================\n// =================================\n\ninterface GetColorKeyArgs {\n disabled: boolean | null\n loading?: boolean\n appearance: ButtonAppearanceUnion | IconButtonAppearanceUnion\n}\nfunction getColorKey({ disabled, loading, appearance }: GetColorKeyArgs) {\n if (disabled || loading) return 'disabled'\n return appearance\n}\n"]}