@coinbase/cds-mobile 9.0.0-rc.2 → 9.0.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +99 -5
  2. package/README.md +2 -2
  3. package/dts/buttons/Button.d.ts.map +1 -1
  4. package/dts/buttons/IconButton.d.ts +19 -1
  5. package/dts/buttons/IconButton.d.ts.map +1 -1
  6. package/dts/cells/Cell.d.ts +2 -1
  7. package/dts/cells/Cell.d.ts.map +1 -1
  8. package/dts/controls/InputIconButton.d.ts +5 -0
  9. package/dts/controls/InputIconButton.d.ts.map +1 -1
  10. package/dts/controls/InputLabel.d.ts.map +1 -1
  11. package/dts/controls/NativeInput.d.ts +12 -2
  12. package/dts/controls/NativeInput.d.ts.map +1 -1
  13. package/dts/controls/SearchInput.d.ts +5 -1
  14. package/dts/controls/SearchInput.d.ts.map +1 -1
  15. package/dts/controls/TextInput.d.ts +5 -2
  16. package/dts/controls/TextInput.d.ts.map +1 -1
  17. package/dts/core/theme.d.ts +12 -0
  18. package/dts/core/theme.d.ts.map +1 -1
  19. package/dts/illustrations/createIllustration.d.ts +3 -0
  20. package/dts/illustrations/createIllustration.d.ts.map +1 -1
  21. package/dts/page/PageFooter.d.ts +8 -0
  22. package/dts/page/PageFooter.d.ts.map +1 -1
  23. package/dts/system/ThemeProvider.d.ts.map +1 -1
  24. package/dts/tabs/DefaultTab.d.ts +4 -2
  25. package/dts/tabs/DefaultTab.d.ts.map +1 -1
  26. package/dts/tabs/DefaultTabsActiveIndicator.d.ts.map +1 -1
  27. package/dts/tabs/SegmentedTab.d.ts +4 -4
  28. package/dts/tabs/Tabs.d.ts +10 -1
  29. package/dts/tabs/Tabs.d.ts.map +1 -1
  30. package/dts/tag/Tag.d.ts +5 -3
  31. package/dts/tag/Tag.d.ts.map +1 -1
  32. package/dts/themes/coinbaseDenseTheme.d.ts +34 -2
  33. package/dts/themes/coinbaseDenseTheme.d.ts.map +1 -1
  34. package/dts/themes/coinbaseHighContrastTheme.d.ts +32 -0
  35. package/dts/themes/coinbaseHighContrastTheme.d.ts.map +1 -1
  36. package/dts/themes/coinbaseTheme.d.ts +34 -2
  37. package/dts/themes/coinbaseTheme.d.ts.map +1 -1
  38. package/dts/themes/defaultHighContrastTheme.d.ts +32 -0
  39. package/dts/themes/defaultHighContrastTheme.d.ts.map +1 -1
  40. package/dts/themes/defaultTheme.d.ts +34 -2
  41. package/dts/themes/defaultTheme.d.ts.map +1 -1
  42. package/dts/utils/convertThemedSvgToHex.d.ts +6 -0
  43. package/dts/utils/convertThemedSvgToHex.d.ts.map +1 -0
  44. package/dts/utils/testHelpers.d.ts +34 -2
  45. package/dts/utils/testHelpers.d.ts.map +1 -1
  46. package/dts/visualizations/chart/PeriodSelector.d.ts.map +1 -1
  47. package/dts/visualizations/chart/gradient/Gradient.d.ts.map +1 -1
  48. package/esm/buttons/IconButton.js +11 -3
  49. package/esm/buttons/__stories__/IconButton.stories.js +65 -0
  50. package/esm/controls/InputLabel.js +4 -3
  51. package/esm/controls/NativeInput.js +3 -1
  52. package/esm/controls/TextInput.js +25 -15
  53. package/esm/illustrations/__stories__/ThemedIllustrations.stories.js +214 -0
  54. package/esm/illustrations/__stories__/illustrationThemes.js +122 -0
  55. package/esm/illustrations/createIllustration.js +31 -5
  56. package/esm/page/PageFooter.js +16 -5
  57. package/esm/page/__figma__/PageFooter.figma.js +49 -6
  58. package/esm/system/ThemeProvider.js +3 -1
  59. package/esm/system/__stories__/componentConfigStickerSheet/StickerSheet.js +4 -0
  60. package/esm/system/__stories__/componentConfigStickerSheet/customComponentConfig.js +24 -12
  61. package/esm/system/__stories__/componentConfigStickerSheet/examples/ListCell.js +2 -0
  62. package/esm/system/__stories__/componentConfigStickerSheet/examples/Tabs.js +24 -0
  63. package/esm/system/__stories__/componentConfigStickerSheet/examples/TextInput.js +12 -0
  64. package/esm/tabs/DefaultTab.js +7 -9
  65. package/esm/tabs/DefaultTabsActiveIndicator.js +1 -2
  66. package/esm/tabs/Tabs.js +18 -12
  67. package/esm/tabs/__stories__/SegmentedTabs.stories.js +8 -1
  68. package/esm/tabs/__stories__/Tabs.stories.js +0 -1
  69. package/esm/tag/Tag.js +14 -4
  70. package/esm/themes/coinbaseHighContrastTheme.js +32 -0
  71. package/esm/themes/coinbaseTheme.js +34 -2
  72. package/esm/themes/defaultHighContrastTheme.js +32 -0
  73. package/esm/themes/defaultTheme.js +34 -2
  74. package/esm/utils/convertThemedSvgToHex.js +9 -0
  75. package/esm/visualizations/chart/PeriodSelector.js +3 -4
  76. package/esm/visualizations/chart/area/__stories__/AreaChart.stories.js +44 -2
  77. package/esm/visualizations/chart/gradient/Gradient.js +11 -2
  78. package/package.json +3 -3
@@ -0,0 +1,214 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import { useCallback, useState } from 'react';
3
+ import { Example, ExampleScreen } from '../../examples/ExampleScreen';
4
+ import { useTheme } from '../../hooks/useTheme';
5
+ import { HStack, VStack } from '../../layout';
6
+ import { ThemeProvider } from '../../system/ThemeProvider';
7
+ import { SegmentedTabs } from '../../tabs/SegmentedTabs';
8
+ import { defaultTheme } from '../../themes/defaultTheme';
9
+ import { Text } from '../../typography/Text';
10
+ import { HeroSquare } from '../HeroSquare';
11
+ import { Pictogram } from '../Pictogram';
12
+ import { SpotIcon } from '../SpotIcon';
13
+ import { SpotRectangle } from '../SpotRectangle';
14
+ import { SpotSquare } from '../SpotSquare';
15
+ import { ILLUSTRATION_THEME_TABS, ILLUSTRATION_THEMES } from './illustrationThemes';
16
+
17
+ // ─── Illustration samples ────────────────────────────────────────────────────
18
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
+ const HERO_SQUARE_SAMPLES = ['accessToAdvancedCharts', 'accountUnderReview', 'add2Fa', 'addBankAccount', 'addCreditCard'];
20
+ const SPOT_SQUARE_SAMPLES = ['accessToAdvancedCharts', 'addCard', 'addEth', 'addMultipleCrypto', 'addPasswordProtection'];
21
+ const PICTOGRAM_SAMPLES = ['accountsNavigation', 'accreditedInvestor', 'add', 'addCard', 'addPayment'];
22
+ const SPOT_ICON_SAMPLES = ['advancedTradeProduct', 'arrowsUpDown', 'assetEmptyStateAa', 'assetEmptyStateAb', 'assetEmptyStateAc'];
23
+ const SPOT_RECTANGLE_SAMPLES = ['accessToAdvancedCharts', 'addBank', 'addPhoneNumber', 'advancedTradeCharts', 'advancedTrading'];
24
+
25
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
26
+
27
+ const resolveTheme = key => key === 'default' ? defaultTheme : _extends({}, defaultTheme, ILLUSTRATION_THEMES[key]);
28
+
29
+ // ─── Story ───────────────────────────────────────────────────────────────────
30
+
31
+ const ThemedIllustrationsStory = () => {
32
+ var _activeTab$id;
33
+ const {
34
+ activeColorScheme
35
+ } = useTheme();
36
+ const [activeTab, setActiveTab] = useState(ILLUSTRATION_THEME_TABS[0]);
37
+ const handleChange = useCallback(tab => setActiveTab(tab), []);
38
+ const themeKey = (_activeTab$id = activeTab == null ? void 0 : activeTab.id) != null ? _activeTab$id : 'default';
39
+ const theme = resolveTheme(themeKey);
40
+ const garishTheme = resolveTheme('garish');
41
+ return /*#__PURE__*/_jsxs(ExampleScreen, {
42
+ children: [/*#__PURE__*/_jsx(Example, {
43
+ title: "Side-by-side comparison",
44
+ children: /*#__PURE__*/_jsxs(HStack, {
45
+ gap: 4,
46
+ children: [/*#__PURE__*/_jsx(ThemeProvider, {
47
+ activeColorScheme: activeColorScheme,
48
+ theme: defaultTheme,
49
+ children: /*#__PURE__*/_jsxs(VStack, {
50
+ alignItems: "center",
51
+ gap: 2,
52
+ padding: 2,
53
+ style: {
54
+ flex: 1
55
+ },
56
+ children: [/*#__PURE__*/_jsx(Text, {
57
+ font: "label2",
58
+ children: "Default"
59
+ }), /*#__PURE__*/_jsx(HeroSquare, {
60
+ applyTheme: true,
61
+ name: "accessToAdvancedCharts",
62
+ scaleMultiplier: 0.35
63
+ }), /*#__PURE__*/_jsx(SpotSquare, {
64
+ applyTheme: true,
65
+ name: "accessToAdvancedCharts"
66
+ }), /*#__PURE__*/_jsx(Pictogram, {
67
+ applyTheme: true,
68
+ name: "add"
69
+ }), /*#__PURE__*/_jsx(SpotIcon, {
70
+ applyTheme: true,
71
+ name: "advancedTradeProduct"
72
+ })]
73
+ })
74
+ }), /*#__PURE__*/_jsx(ThemeProvider, {
75
+ activeColorScheme: activeColorScheme,
76
+ theme: garishTheme,
77
+ children: /*#__PURE__*/_jsxs(VStack, {
78
+ alignItems: "center",
79
+ gap: 2,
80
+ padding: 2,
81
+ style: {
82
+ flex: 1
83
+ },
84
+ children: [/*#__PURE__*/_jsx(Text, {
85
+ font: "label2",
86
+ children: "Garish"
87
+ }), /*#__PURE__*/_jsx(HeroSquare, {
88
+ applyTheme: true,
89
+ name: "accessToAdvancedCharts",
90
+ scaleMultiplier: 0.35
91
+ }), /*#__PURE__*/_jsx(SpotSquare, {
92
+ applyTheme: true,
93
+ name: "accessToAdvancedCharts"
94
+ }), /*#__PURE__*/_jsx(Pictogram, {
95
+ applyTheme: true,
96
+ name: "add"
97
+ }), /*#__PURE__*/_jsx(SpotIcon, {
98
+ applyTheme: true,
99
+ name: "advancedTradeProduct"
100
+ })]
101
+ })
102
+ })]
103
+ })
104
+ }), /*#__PURE__*/_jsx(Example, {
105
+ title: "Theme",
106
+ children: /*#__PURE__*/_jsx(SegmentedTabs, {
107
+ accessibilityLabel: "Select illustration theme",
108
+ activeTab: activeTab,
109
+ onChange: handleChange,
110
+ tabs: ILLUSTRATION_THEME_TABS
111
+ })
112
+ }), /*#__PURE__*/_jsxs(ThemeProvider, {
113
+ activeColorScheme: activeColorScheme,
114
+ theme: theme,
115
+ children: [/*#__PURE__*/_jsx(Example, {
116
+ title: "HeroSquare",
117
+ children: /*#__PURE__*/_jsx(HStack, {
118
+ flexWrap: "wrap",
119
+ gap: 2,
120
+ children: HERO_SQUARE_SAMPLES.map(name => /*#__PURE__*/_jsxs(VStack, {
121
+ alignItems: "center",
122
+ gap: 0,
123
+ children: [/*#__PURE__*/_jsx(HeroSquare, {
124
+ applyTheme: true,
125
+ name: name,
126
+ scaleMultiplier: 0.3
127
+ }), /*#__PURE__*/_jsx(Text, {
128
+ color: "fgMuted",
129
+ font: "legal",
130
+ numberOfLines: 1,
131
+ children: name
132
+ })]
133
+ }, name))
134
+ })
135
+ }), /*#__PURE__*/_jsx(Example, {
136
+ title: "SpotSquare",
137
+ children: /*#__PURE__*/_jsx(HStack, {
138
+ flexWrap: "wrap",
139
+ gap: 2,
140
+ children: SPOT_SQUARE_SAMPLES.map(name => /*#__PURE__*/_jsxs(VStack, {
141
+ alignItems: "center",
142
+ gap: 0,
143
+ children: [/*#__PURE__*/_jsx(SpotSquare, {
144
+ applyTheme: true,
145
+ name: name
146
+ }), /*#__PURE__*/_jsx(Text, {
147
+ color: "fgMuted",
148
+ font: "legal",
149
+ numberOfLines: 1,
150
+ children: name
151
+ })]
152
+ }, name))
153
+ })
154
+ }), /*#__PURE__*/_jsx(Example, {
155
+ title: "Pictogram",
156
+ children: /*#__PURE__*/_jsx(HStack, {
157
+ flexWrap: "wrap",
158
+ gap: 2,
159
+ children: PICTOGRAM_SAMPLES.map(name => /*#__PURE__*/_jsxs(VStack, {
160
+ alignItems: "center",
161
+ gap: 0,
162
+ children: [/*#__PURE__*/_jsx(Pictogram, {
163
+ applyTheme: true,
164
+ name: name
165
+ }), /*#__PURE__*/_jsx(Text, {
166
+ color: "fgMuted",
167
+ font: "legal",
168
+ numberOfLines: 1,
169
+ children: name
170
+ })]
171
+ }, name))
172
+ })
173
+ }), /*#__PURE__*/_jsx(Example, {
174
+ title: "SpotIcon",
175
+ children: /*#__PURE__*/_jsx(HStack, {
176
+ flexWrap: "wrap",
177
+ gap: 2,
178
+ children: SPOT_ICON_SAMPLES.map(name => /*#__PURE__*/_jsxs(VStack, {
179
+ alignItems: "center",
180
+ gap: 0,
181
+ children: [/*#__PURE__*/_jsx(SpotIcon, {
182
+ applyTheme: true,
183
+ name: name
184
+ }), /*#__PURE__*/_jsx(Text, {
185
+ color: "fgMuted",
186
+ font: "legal",
187
+ numberOfLines: 1,
188
+ children: name
189
+ })]
190
+ }, name))
191
+ })
192
+ }), /*#__PURE__*/_jsx(Example, {
193
+ title: "SpotRectangle",
194
+ children: /*#__PURE__*/_jsx(VStack, {
195
+ gap: 2,
196
+ children: SPOT_RECTANGLE_SAMPLES.map(name => /*#__PURE__*/_jsxs(VStack, {
197
+ gap: 0,
198
+ children: [/*#__PURE__*/_jsx(SpotRectangle, {
199
+ applyTheme: true,
200
+ name: name,
201
+ scaleMultiplier: 0.5
202
+ }), /*#__PURE__*/_jsx(Text, {
203
+ color: "fgMuted",
204
+ font: "legal",
205
+ numberOfLines: 1,
206
+ children: name
207
+ })]
208
+ }, name))
209
+ })
210
+ })]
211
+ })]
212
+ });
213
+ };
214
+ export default ThemedIllustrationsStory;
@@ -0,0 +1,122 @@
1
+ export const ILLUSTRATION_THEME_TABS = [{
2
+ id: 'default',
3
+ label: 'Default'
4
+ }, {
5
+ id: 'warm',
6
+ label: 'Warm'
7
+ }, {
8
+ id: 'monochrome',
9
+ label: 'Mono'
10
+ }, {
11
+ id: 'garish',
12
+ label: 'Garish'
13
+ }];
14
+ export const WARM_ILLUSTRATION_THEME = {
15
+ lightIllustrationColor: {
16
+ primary: 'rgb(234, 88, 12)',
17
+ black: 'rgb(28, 25, 23)',
18
+ white: 'rgb(255, 247, 237)',
19
+ gray: 'rgb(254, 243, 199)',
20
+ gray2: 'rgb(254, 243, 199)',
21
+ gray3: 'rgb(253, 230, 138)',
22
+ positive: 'rgb(34, 197, 94)',
23
+ negative: 'rgb(239, 68, 68)',
24
+ accent1: 'rgb(250, 204, 21)',
25
+ accent2: 'rgb(249, 115, 22)',
26
+ accent3: 'rgb(239, 68, 68)',
27
+ accent4: 'rgb(254, 215, 170)',
28
+ invert: 'rgb(120, 53, 15)',
29
+ invert2: 'rgb(255, 247, 237)'
30
+ },
31
+ darkIllustrationColor: {
32
+ primary: 'rgb(251, 146, 60)',
33
+ black: 'rgb(255, 247, 237)',
34
+ white: 'rgb(28, 25, 23)',
35
+ gray: 'rgb(120, 53, 15)',
36
+ gray2: 'rgb(120, 53, 15)',
37
+ gray3: 'rgb(154, 52, 18)',
38
+ positive: 'rgb(74, 222, 128)',
39
+ negative: 'rgb(248, 113, 113)',
40
+ accent1: 'rgb(253, 224, 71)',
41
+ accent2: 'rgb(253, 186, 116)',
42
+ accent3: 'rgb(248, 113, 113)',
43
+ accent4: 'rgb(154, 52, 18)',
44
+ invert: 'rgb(255, 237, 213)',
45
+ invert2: 'rgb(120, 53, 15)'
46
+ }
47
+ };
48
+ export const MONOCHROME_ILLUSTRATION_THEME = {
49
+ lightIllustrationColor: {
50
+ primary: 'rgb(113, 113, 122)',
51
+ black: 'rgb(9, 9, 11)',
52
+ white: 'rgb(250, 250, 250)',
53
+ gray: 'rgb(228, 228, 231)',
54
+ gray2: 'rgb(212, 212, 216)',
55
+ gray3: 'rgb(196, 196, 202)',
56
+ positive: 'rgb(161, 161, 170)',
57
+ negative: 'rgb(82, 82, 91)',
58
+ accent1: 'rgb(161, 161, 170)',
59
+ accent2: 'rgb(113, 113, 122)',
60
+ accent3: 'rgb(82, 82, 91)',
61
+ accent4: 'rgb(212, 212, 216)',
62
+ invert: 'rgb(9, 9, 11)',
63
+ invert2: 'rgb(244, 244, 245)'
64
+ },
65
+ darkIllustrationColor: {
66
+ primary: 'rgb(161, 161, 170)',
67
+ black: 'rgb(244, 244, 245)',
68
+ white: 'rgb(24, 24, 27)',
69
+ gray: 'rgb(63, 63, 70)',
70
+ gray2: 'rgb(63, 63, 70)',
71
+ gray3: 'rgb(82, 82, 91)',
72
+ positive: 'rgb(113, 113, 122)',
73
+ negative: 'rgb(212, 212, 216)',
74
+ accent1: 'rgb(113, 113, 122)',
75
+ accent2: 'rgb(161, 161, 170)',
76
+ accent3: 'rgb(212, 212, 216)',
77
+ accent4: 'rgb(63, 63, 70)',
78
+ invert: 'rgb(244, 244, 245)',
79
+ invert2: 'rgb(39, 39, 42)'
80
+ }
81
+ };
82
+
83
+ // Maximally distinct colors — ideal for verifying every token is wired correctly
84
+ export const GARISH_ILLUSTRATION_THEME = {
85
+ lightIllustrationColor: {
86
+ primary: 'rgb(220, 38, 38)',
87
+ black: 'rgb(20, 83, 45)',
88
+ white: 'rgb(254, 249, 195)',
89
+ gray: 'rgb(243, 232, 255)',
90
+ gray2: 'rgb(243, 232, 255)',
91
+ gray3: 'rgb(219, 234, 254)',
92
+ positive: 'rgb(34, 197, 94)',
93
+ negative: 'rgb(185, 28, 28)',
94
+ accent1: 'rgb(249, 115, 22)',
95
+ accent2: 'rgb(20, 184, 166)',
96
+ accent3: 'rgb(34, 197, 94)',
97
+ accent4: 'rgb(147, 197, 253)',
98
+ invert: 'rgb(127, 29, 29)',
99
+ invert2: 'rgb(219, 234, 254)'
100
+ },
101
+ darkIllustrationColor: {
102
+ primary: 'rgb(248, 113, 113)',
103
+ black: 'rgb(187, 247, 208)',
104
+ white: 'rgb(30, 27, 75)',
105
+ gray: 'rgb(88, 28, 135)',
106
+ gray2: 'rgb(88, 28, 135)',
107
+ gray3: 'rgb(30, 58, 138)',
108
+ positive: 'rgb(74, 222, 128)',
109
+ negative: 'rgb(252, 165, 165)',
110
+ accent1: 'rgb(253, 186, 116)',
111
+ accent2: 'rgb(94, 234, 212)',
112
+ accent3: 'rgb(74, 222, 128)',
113
+ accent4: 'rgb(147, 197, 253)',
114
+ invert: 'rgb(254, 202, 202)',
115
+ invert2: 'rgb(30, 58, 138)'
116
+ }
117
+ };
118
+ export const ILLUSTRATION_THEMES = {
119
+ warm: WARM_ILLUSTRATION_THEME,
120
+ monochrome: MONOCHROME_ILLUSTRATION_THEME,
121
+ garish: GARISH_ILLUSTRATION_THEME
122
+ };
@@ -5,11 +5,12 @@ import { convertSizeWithMultiplier } from '@coinbase/cds-common/utils/convertSiz
5
5
  import { getDefaultSizeObjectForIllustration } from '@coinbase/cds-common/utils/getDefaultSizeObjectForIllustration';
6
6
  import { isDevelopment } from '@coinbase/cds-utils';
7
7
  import { useTheme } from '../hooks/useTheme';
8
+ import { convertThemedSvgToHex } from '../utils/convertThemedSvgToHex';
8
9
  import { jsx as _jsx } from "react/jsx-runtime";
9
10
  export function createIllustration(variant, config) {
10
11
  const defaultSize = getDefaultSizeObjectForIllustration(variant);
11
12
  const Illustration = /*#__PURE__*/memo(function Illustration(_ref) {
12
- var _config$name;
13
+ var _config$name2, _config$name3;
13
14
  let {
14
15
  fallback = null,
15
16
  name,
@@ -17,13 +18,13 @@ export function createIllustration(variant, config) {
17
18
  scaleMultiplier,
18
19
  testID,
19
20
  accessibilityHint,
20
- accessibilityLabel
21
+ accessibilityLabel,
22
+ applyTheme
21
23
  } = _ref;
22
24
  const {
23
- activeColorScheme
25
+ activeColorScheme,
26
+ illustrationColor
24
27
  } = useTheme();
25
- const requireFn = (_config$name = config[name]) == null ? void 0 : _config$name[activeColorScheme];
26
- const xml = useMemo(() => requireFn == null ? void 0 : requireFn(), [requireFn]);
27
28
  const style = useMemo(() => {
28
29
  let size = defaultSize;
29
30
  if (dimension) {
@@ -34,6 +35,31 @@ export function createIllustration(variant, config) {
34
35
  }
35
36
  return size;
36
37
  }, [dimension, scaleMultiplier]);
38
+ const themedXml = useMemo(() => {
39
+ var _config$name, _config$name$themeabl;
40
+ if (!applyTheme || illustrationColor === undefined) return null;
41
+ const raw = (_config$name = config[name]) == null || (_config$name$themeabl = _config$name['themeable']) == null ? void 0 : _config$name$themeabl.call(_config$name);
42
+ return raw ? convertThemedSvgToHex(raw, illustrationColor) : null;
43
+ }, [name, applyTheme, illustrationColor]);
44
+ if (applyTheme) {
45
+ if (themedXml) {
46
+ return /*#__PURE__*/_jsx(SvgXml, {
47
+ accessibilityHint: accessibilityHint,
48
+ accessibilityLabel: accessibilityLabel,
49
+ accessibilityRole: "image",
50
+ accessible: !!accessibilityLabel,
51
+ style: style,
52
+ testID: testID,
53
+ xml: themedXml
54
+ });
55
+ }
56
+
57
+ // No themed variant available or no palette — return fallback.
58
+ return fallback;
59
+ }
60
+
61
+ // Default light/dark path.
62
+ const xml = (_config$name2 = config[name]) == null || (_config$name3 = _config$name2[activeColorScheme === 'dark' ? 'dark' : 'light']) == null ? void 0 : _config$name3.call(_config$name2);
37
63
  if (!xml) {
38
64
  if (isDevelopment()) {
39
65
  console.error("Unable to find illustration with name: " + name);
@@ -1,25 +1,36 @@
1
- const _excluded = ["action"];
1
+ const _excluded = ["action", "legalText"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
4
  import React, { forwardRef, memo } from 'react';
5
5
  import { pageFooterHeight } from '@coinbase/cds-common/tokens/page';
6
6
  import { useComponentConfig } from '../hooks/useComponentConfig';
7
7
  import { Box } from '../layout/Box';
8
- import { jsx as _jsx } from "react/jsx-runtime";
8
+ import { VStack } from '../layout/VStack';
9
+ import { Text } from '../typography/Text';
10
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
11
  export const PageFooter = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_props, ref) => {
10
12
  const mergedProps = useComponentConfig('PageFooter', _props);
11
13
  const {
12
- action
14
+ action,
15
+ legalText
13
16
  } = mergedProps,
14
17
  props = _objectWithoutPropertiesLoose(mergedProps, _excluded);
15
18
  return /*#__PURE__*/_jsx(Box, _extends({
16
19
  ref: ref,
17
20
  accessibilityRole: "toolbar",
18
21
  alignItems: "center",
19
- height: pageFooterHeight,
22
+ height: legalText ? undefined : pageFooterHeight,
20
23
  paddingX: 3,
21
24
  paddingY: 1.5
22
25
  }, props, {
23
- children: action
26
+ children: legalText ? /*#__PURE__*/_jsxs(VStack, {
27
+ alignItems: "center",
28
+ gap: 2,
29
+ children: [action, /*#__PURE__*/_jsx(Text, {
30
+ color: "fgMuted",
31
+ font: "legal",
32
+ children: legalText
33
+ })]
34
+ }) : action
24
35
  }));
25
36
  }));
@@ -1,18 +1,61 @@
1
1
  import React from 'react';
2
2
  import { figma } from '@figma/code-connect';
3
+ import { Button } from '../../buttons/Button';
4
+ import { ButtonGroup } from '../../buttons/ButtonGroup';
3
5
  import { PageFooter } from '../PageFooter';
4
- import { jsx as _jsx } from "react/jsx-runtime";
5
- figma.connect(PageFooter, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/✨-CDS-Components?node-id=17685%3A3266', {
6
- imports: ["import { PageFooter } from '@coinbase/cds-mobile/page/PageFooter'"],
6
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
+ const url = 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/✨-CDS-Components?node-id=17685%3A3266';
8
+ figma.connect(PageFooter, url, {
9
+ imports: ["import { PageFooter } from '@coinbase/cds-mobile/page/PageFooter'", "import { Button } from '@coinbase/cds-mobile/buttons/Button'"],
10
+ variant: {
11
+ '# of actions': '1'
12
+ },
7
13
  props: {
8
- action: figma.children('ButtonGroup')
14
+ legalText: figma.boolean('show legal text', {
15
+ true: 'Your legal text here.',
16
+ false: undefined
17
+ })
9
18
  },
10
19
  example: _ref => {
11
20
  let {
12
- action
21
+ legalText
13
22
  } = _ref;
14
23
  return /*#__PURE__*/_jsx(PageFooter, {
15
- action: action
24
+ action: /*#__PURE__*/_jsx(Button, {
25
+ variant: "primary",
26
+ children: "Next"
27
+ }),
28
+ legalText: legalText
29
+ });
30
+ }
31
+ });
32
+ figma.connect(PageFooter, url, {
33
+ imports: ["import { PageFooter } from '@coinbase/cds-mobile/page/PageFooter'", "import { Button } from '@coinbase/cds-mobile/buttons/Button'", "import { ButtonGroup } from '@coinbase/cds-mobile/buttons/ButtonGroup'"],
34
+ variant: {
35
+ '# of actions': '2'
36
+ },
37
+ props: {
38
+ legalText: figma.boolean('show legal text', {
39
+ true: 'Your legal text here.',
40
+ false: undefined
41
+ })
42
+ },
43
+ example: _ref2 => {
44
+ let {
45
+ legalText
46
+ } = _ref2;
47
+ return /*#__PURE__*/_jsx(PageFooter, {
48
+ action: /*#__PURE__*/_jsxs(ButtonGroup, {
49
+ block: true,
50
+ children: [/*#__PURE__*/_jsx(Button, {
51
+ variant: "secondary",
52
+ children: "Back"
53
+ }), /*#__PURE__*/_jsx(Button, {
54
+ variant: "primary",
55
+ children: "Next"
56
+ })]
57
+ }),
58
+ legalText: legalText
16
59
  });
17
60
  }
18
61
  });
@@ -35,6 +35,7 @@ export const ThemeProvider = /*#__PURE__*/memo(_ref => {
35
35
  const themeApi = useMemo(() => {
36
36
  const activeSpectrumKey = activeColorScheme === 'dark' ? 'darkSpectrum' : 'lightSpectrum';
37
37
  const activeColorKey = activeColorScheme === 'dark' ? 'darkColor' : 'lightColor';
38
+ const activeIllustrationKey = activeColorScheme === 'dark' ? 'darkIllustrationColor' : 'lightIllustrationColor';
38
39
  const inverseSpectrumKey = activeColorScheme === 'dark' ? 'lightSpectrum' : 'darkSpectrum';
39
40
  const inverseColorKey = activeColorScheme === 'dark' ? 'lightColor' : 'darkColor';
40
41
  if (!theme[activeColorKey]) throw Error("ThemeProvider activeColorScheme is " + activeColorScheme + " but no " + activeColorScheme + " colors are defined for the theme. See the docs https://cds.coinbase.com/getting-started/theming");
@@ -44,7 +45,8 @@ export const ThemeProvider = /*#__PURE__*/memo(_ref => {
44
45
  return _extends({}, theme, {
45
46
  activeColorScheme: activeColorScheme,
46
47
  spectrum: theme[activeSpectrumKey],
47
- color: theme[activeColorKey]
48
+ color: theme[activeColorKey],
49
+ illustrationColor: theme[activeIllustrationKey]
48
50
  });
49
51
  }, [theme, activeColorScheme]);
50
52
  return /*#__PURE__*/_jsx(ThemeContext.Provider, {
@@ -16,6 +16,7 @@ import { SearchExample } from './examples/Search';
16
16
  import { SegmentedTabsExample } from './examples/SegmentedTabs';
17
17
  import { SelectExample } from './examples/Select';
18
18
  import { SelectChipExample } from './examples/SelectChip';
19
+ import { TabsExample } from './examples/Tabs';
19
20
  import { TagExample } from './examples/Tag';
20
21
  import { TextInputExample } from './examples/TextInput';
21
22
  import { Container } from './Container';
@@ -38,6 +39,9 @@ export const StickerSheet = /*#__PURE__*/memo(() => {
38
39
  }), /*#__PURE__*/_jsx(Container, {
39
40
  title: "Segmented Tabs",
40
41
  children: /*#__PURE__*/_jsx(SegmentedTabsExample, {})
42
+ }), /*#__PURE__*/_jsx(Container, {
43
+ title: "Tabs",
44
+ children: /*#__PURE__*/_jsx(TabsExample, {})
41
45
  }), /*#__PURE__*/_jsx(Container, {
42
46
  title: "Select Input (SelectOption)",
43
47
  children: /*#__PURE__*/_jsx(SelectExample, {})
@@ -1,8 +1,6 @@
1
- const _excluded = ["label", "labelNode"];
1
+ const _excluded = ["label", "labelNode", "readOnly"];
2
2
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
3
3
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
- import { Text } from '../../../typography/Text';
5
- import { jsx as _jsx } from "react/jsx-runtime";
6
4
  export const customComponentConfig = {
7
5
  Banner: {
8
6
  borderRadius: 0
@@ -29,18 +27,14 @@ export const customComponentConfig = {
29
27
  },
30
28
  TextInput: _ref => {
31
29
  let {
32
- label,
33
- labelNode
30
+ readOnly
34
31
  } = _ref,
35
32
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
36
33
  return {
37
- labelNode: (labelNode != null ? labelNode : label) ? /*#__PURE__*/_jsx(Text, {
38
- color: "fgMuted",
39
- font: "label2",
40
- children: label
41
- }) : undefined,
34
+ labelColor: 'fgMuted',
35
+ labelFont: 'label2',
42
36
  bordered: false,
43
- inputBackground: 'bgAlternate',
37
+ inputBackground: readOnly ? 'bgSecondary' : 'bgAlternate',
44
38
  font: props.compact ? 'label2' : 'body',
45
39
  variant: 'foregroundMuted',
46
40
  focusedBorderWidth: 100
@@ -112,5 +106,23 @@ export const customComponentConfig = {
112
106
  font: props.compact ? 'label2' : 'body',
113
107
  labelColor: 'fgMuted',
114
108
  labelFont: props.compact ? props.align === 'end' ? 'label1' : 'label2' : 'body'
115
- })
109
+ }),
110
+ ListCell: props => {
111
+ var _props$spacingVariant;
112
+ const spacingVariant = (_props$spacingVariant = props.spacingVariant) != null ? _props$spacingVariant : props.compact ? 'compact' : 'normal';
113
+ return _extends({}, spacingVariant === 'normal' ? {
114
+ minHeight: 36
115
+ } : {});
116
+ },
117
+ Tabs: {
118
+ activeColor: 'fg',
119
+ color: 'fgMuted',
120
+ activeBackground: 'fg'
121
+ },
122
+ Tag: {
123
+ paddingY: 0.5,
124
+ paddingX: 1,
125
+ font: 'caption',
126
+ emphasis: 'low'
127
+ }
116
128
  };
@@ -43,6 +43,8 @@ export const ListCellExample = /*#__PURE__*/memo(() => {
43
43
  onPress: () => undefined,
44
44
  subtitle: "XRP",
45
45
  title: "XRP"
46
+ }), /*#__PURE__*/_jsx(ListCell, {
47
+ title: "Short"
46
48
  })]
47
49
  });
48
50
  });
@@ -0,0 +1,24 @@
1
+ import React, { memo, useState } from 'react';
2
+ import { Tabs } from '../../../../tabs/Tabs';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ const tabs = [{
5
+ id: 'orderBook',
6
+ label: 'Order book'
7
+ }, {
8
+ id: 'tradeHistory',
9
+ label: 'Trade history'
10
+ }, {
11
+ id: 'orders',
12
+ label: 'Orders'
13
+ }];
14
+ export const TabsExample = /*#__PURE__*/memo(() => {
15
+ const [activeTab, setActiveTab] = useState(tabs[0]);
16
+ return /*#__PURE__*/_jsx(Tabs, {
17
+ accessibilityLabel: "Market views",
18
+ activeTab: activeTab,
19
+ background: "bg",
20
+ gap: 4,
21
+ onChange: setActiveTab,
22
+ tabs: tabs
23
+ });
24
+ });
@@ -40,6 +40,18 @@ export const TextInputExample = /*#__PURE__*/memo(() => {
40
40
  labelVariant: "inside",
41
41
  onChangeText: setValue,
42
42
  placeholder: "Input with icon button",
43
+ style: {
44
+ flexGrow: 1
45
+ },
46
+ value: value
47
+ }), /*#__PURE__*/_jsx(TextInput, {
48
+ readOnly: true,
49
+ label: "Label",
50
+ onChangeText: setValue,
51
+ placeholder: "Read only input",
52
+ style: {
53
+ flexGrow: 1
54
+ },
43
55
  value: value
44
56
  })]
45
57
  });