@coinbase/cds-mobile 9.7.2 → 9.8.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/CHANGELOG.md +6 -0
- package/dts/hooks/useAppState.d.ts +1 -1
- package/dts/icons/Icon.d.ts +39 -57
- package/dts/icons/Icon.d.ts.map +1 -1
- package/dts/icons/createIcon.d.ts +130 -0
- package/dts/icons/createIcon.d.ts.map +1 -0
- package/dts/icons/index.d.ts +2 -0
- package/dts/icons/index.d.ts.map +1 -1
- package/esm/icons/Icon.js +4 -87
- package/esm/icons/createIcon.js +144 -0
- package/esm/icons/index.js +1 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,12 @@ All notable changes to this project will be documented in this file.
|
|
|
8
8
|
|
|
9
9
|
<!-- template-start -->
|
|
10
10
|
|
|
11
|
+
## 9.8.0 (7/23/2026 PST)
|
|
12
|
+
|
|
13
|
+
#### 🚀 Updates
|
|
14
|
+
|
|
15
|
+
- Feat: add createIcon factory to decouple Icon from a single icon set. [[#786](https://github.com/coinbase/cds/pull/786)]
|
|
16
|
+
|
|
11
17
|
## 9.7.2 (7/23/2026 PST)
|
|
12
18
|
|
|
13
19
|
#### 🐞 Fixes
|
package/dts/icons/Icon.d.ts
CHANGED
|
@@ -1,70 +1,52 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Animated, type StyleProp, type TextStyle, type ViewStyle } from 'react-native';
|
|
3
|
-
import type { ThemeVars } from '@coinbase/cds-common/core/theme';
|
|
4
1
|
import type { IconName } from '@coinbase/cds-common/types/IconName';
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
};
|
|
41
|
-
export type IconProps = IconBaseProps & {
|
|
42
|
-
/** Custom styles for individual elements of the Icon component */
|
|
43
|
-
styles?: {
|
|
44
|
-
/** Outer Box wrapper element */
|
|
45
|
-
root?: StyleProp<ViewStyle>;
|
|
46
|
-
/** Inner icon glyph Text element */
|
|
47
|
-
icon?: StyleProp<TextStyle>;
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
declare const getIconSourceSize: (iconSize: number) => IconSourcePixelSize;
|
|
51
|
-
export declare const Icon: React.MemoExoticComponent<
|
|
52
|
-
(
|
|
53
|
-
_props: IconProps,
|
|
54
|
-
) =>
|
|
2
|
+
import {
|
|
3
|
+
getIconSourceSize,
|
|
4
|
+
type IconBaseProps as IconBasePropsGeneric,
|
|
5
|
+
type IconProps as IconPropsGeneric,
|
|
6
|
+
} from './createIcon';
|
|
7
|
+
export type IconBaseProps = IconBasePropsGeneric<IconName>;
|
|
8
|
+
export type IconProps = IconPropsGeneric<IconName>;
|
|
9
|
+
export declare const Icon: import('react').MemoExoticComponent<
|
|
10
|
+
({
|
|
11
|
+
ref,
|
|
12
|
+
..._props
|
|
13
|
+
}: import('@coinbase/cds-common').SharedProps &
|
|
14
|
+
import('@coinbase/cds-common').PaddingProps &
|
|
15
|
+
Pick<
|
|
16
|
+
import('@coinbase/cds-common').SharedAccessibilityProps,
|
|
17
|
+
'accessibilityLabel' | 'accessibilityHint'
|
|
18
|
+
> & {
|
|
19
|
+
size?: import('@coinbase/cds-common').IconSize;
|
|
20
|
+
name: IconName;
|
|
21
|
+
fallback?: null | React.ReactNode;
|
|
22
|
+
active?: boolean;
|
|
23
|
+
color?: import('@coinbase/cds-common').ThemeVars.Color;
|
|
24
|
+
dangerouslySetColor?: string | import('react-native').Animated.AnimatedInterpolation<string>;
|
|
25
|
+
animated?: boolean;
|
|
26
|
+
} & {
|
|
27
|
+
style?: import('react-native').Animated.WithAnimatedValue<
|
|
28
|
+
import('react-native').StyleProp<import('react-native').TextStyle>
|
|
29
|
+
>;
|
|
30
|
+
styles?: {
|
|
31
|
+
root?: import('react-native').StyleProp<import('react-native').ViewStyle>;
|
|
32
|
+
icon?: import('react-native').StyleProp<import('react-native').TextStyle>;
|
|
33
|
+
};
|
|
34
|
+
} & {
|
|
35
|
+
ref?: React.Ref<import('react-native').Text>;
|
|
36
|
+
}) =>
|
|
55
37
|
| string
|
|
56
38
|
| number
|
|
57
39
|
| bigint
|
|
58
40
|
| boolean
|
|
59
|
-
| Iterable<
|
|
41
|
+
| Iterable<import('react').ReactNode>
|
|
60
42
|
| Promise<
|
|
61
43
|
| string
|
|
62
44
|
| number
|
|
63
45
|
| bigint
|
|
64
46
|
| boolean
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
| Iterable<
|
|
47
|
+
| import('react').ReactPortal
|
|
48
|
+
| import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>
|
|
49
|
+
| Iterable<import('react').ReactNode>
|
|
68
50
|
| null
|
|
69
51
|
| undefined
|
|
70
52
|
>
|
package/dts/icons/Icon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/icons/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/icons/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAGpE,OAAO,EAGL,iBAAiB,EACjB,KAAK,aAAa,IAAI,oBAAoB,EAC1C,KAAK,SAAS,IAAI,gBAAgB,EACnC,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,aAAa,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;AAC3D,MAAM,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AAEnD,eAAO,MAAM,IAAI;;;;;;;;;;;YAM8nG,CAAC;YAAyE,CAAC;;;;kWAHxtG,CAAC;AAEH,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Animated, type StyleProp, Text, type TextStyle, type ViewStyle } from 'react-native';
|
|
3
|
+
import type { ThemeVars } from '@coinbase/cds-common/core/theme';
|
|
4
|
+
import type { IconSize, IconSourcePixelSize } from '@coinbase/cds-common/types/IconSize';
|
|
5
|
+
import type { SharedAccessibilityProps } from '@coinbase/cds-common/types/SharedAccessibilityProps';
|
|
6
|
+
import type { SharedProps } from '@coinbase/cds-common/types/SharedProps';
|
|
7
|
+
import type { PaddingProps } from '@coinbase/cds-common/types/SpacingProps';
|
|
8
|
+
/** Default font family for the CDS icon glyph font. */
|
|
9
|
+
export declare const DEFAULT_ICON_FONT_FAMILY = 'CoinbaseIcons';
|
|
10
|
+
/**
|
|
11
|
+
* Shape of the glyph map an icon set must provide. Keys are
|
|
12
|
+
* `${name}-${sourcePixelSize}-${'active' | 'inactive'}` and values are the
|
|
13
|
+
* single Unicode character rendered in the icon font.
|
|
14
|
+
*/
|
|
15
|
+
export type GlyphMap<Name extends string> = Record<
|
|
16
|
+
`${Name}-${IconSourcePixelSize}-${'active' | 'inactive'}`,
|
|
17
|
+
string
|
|
18
|
+
>;
|
|
19
|
+
/** Arguments passed to a glyph resolver to look up an icon's glyph. */
|
|
20
|
+
export type IconGlyphResolverArgs<Name extends string> = {
|
|
21
|
+
/** Glyph map bound to this icon set. */
|
|
22
|
+
glyphMap: GlyphMap<Name>;
|
|
23
|
+
/** Icon name requested via the `name` prop. */
|
|
24
|
+
name: Name;
|
|
25
|
+
/** Size token requested via the `size` prop. */
|
|
26
|
+
size: IconSize;
|
|
27
|
+
/** Resolved pixel size from the theme (includes device font scaling). */
|
|
28
|
+
pixelSize: number;
|
|
29
|
+
/** Whether the active variant was requested. */
|
|
30
|
+
active: boolean;
|
|
31
|
+
};
|
|
32
|
+
/** Configuration used to bind an icon set to a typed `Icon` component. */
|
|
33
|
+
export type CreateIconConfig<Name extends string> = {
|
|
34
|
+
/** Generated glyph map for this icon set. */
|
|
35
|
+
glyphMap: GlyphMap<Name>;
|
|
36
|
+
/**
|
|
37
|
+
* Font family registered by the icon set's font (loaded via `expo-font`).
|
|
38
|
+
* @default 'CoinbaseIcons'
|
|
39
|
+
*/
|
|
40
|
+
fontFamily?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Resolves the glyph to render for an icon from the glyph map. Override to
|
|
43
|
+
* support a custom key format or size model. Defaults to the CDS scheme:
|
|
44
|
+
* `${name}-${sourceSize}-${'active' | 'inactive'}`, where `sourceSize` is
|
|
45
|
+
* `12`, `16`, or `24`.
|
|
46
|
+
*/
|
|
47
|
+
getGlyph?: (args: IconGlyphResolverArgs<Name>) => string | undefined;
|
|
48
|
+
};
|
|
49
|
+
export type IconBaseProps<Name extends string = string> = SharedProps &
|
|
50
|
+
PaddingProps &
|
|
51
|
+
Pick<SharedAccessibilityProps, 'accessibilityLabel' | 'accessibilityHint'> & {
|
|
52
|
+
/**
|
|
53
|
+
* Size for a given icon.
|
|
54
|
+
* @default m
|
|
55
|
+
*/
|
|
56
|
+
size?: IconSize;
|
|
57
|
+
/** Name of the icon, as defined in Figma. */
|
|
58
|
+
name: Name;
|
|
59
|
+
/**
|
|
60
|
+
* Fallback element to render if unable to find an icon with matching name
|
|
61
|
+
* @default null
|
|
62
|
+
* */
|
|
63
|
+
fallback?: null | React.ReactNode;
|
|
64
|
+
/**
|
|
65
|
+
* Toggles the active and inactive state of the navigation icon
|
|
66
|
+
* @default false
|
|
67
|
+
*/
|
|
68
|
+
active?: boolean;
|
|
69
|
+
/** Color of the icon when used as a foreground.
|
|
70
|
+
* @default primary
|
|
71
|
+
*/
|
|
72
|
+
color?: ThemeVars.Color;
|
|
73
|
+
/**
|
|
74
|
+
* @deprecated Use `style`, `styles.icon`, or the `color` prop to customize icon color. This will be removed in a future major release.
|
|
75
|
+
* @deprecationExpectedRemoval v10
|
|
76
|
+
*/
|
|
77
|
+
dangerouslySetColor?: string | Animated.AnimatedInterpolation<string>;
|
|
78
|
+
animated?: boolean;
|
|
79
|
+
};
|
|
80
|
+
export type IconProps<Name extends string = string> = IconBaseProps<Name> & {
|
|
81
|
+
/** Custom style applied to the outer container. */
|
|
82
|
+
style?: Animated.WithAnimatedValue<StyleProp<TextStyle>>;
|
|
83
|
+
/** Custom styles for individual elements of the Icon component */
|
|
84
|
+
styles?: {
|
|
85
|
+
/** Outer Box wrapper element */
|
|
86
|
+
root?: StyleProp<ViewStyle>;
|
|
87
|
+
/** Inner icon glyph Text element */
|
|
88
|
+
icon?: StyleProp<TextStyle>;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
declare const getIconSourceSize: (iconSize: number) => IconSourcePixelSize;
|
|
92
|
+
/**
|
|
93
|
+
* Creates a typed `Icon` component bound to a specific icon set (glyph map,
|
|
94
|
+
* font family, and name union). The default CDS `Icon` is created from this
|
|
95
|
+
* factory; consumers with their own icon package can create their own typed
|
|
96
|
+
* icon component that reuses all of the CDS rendering, accessibility, and
|
|
97
|
+
* theming behavior.
|
|
98
|
+
*/
|
|
99
|
+
export declare function createIcon<Name extends string>({
|
|
100
|
+
glyphMap,
|
|
101
|
+
fontFamily,
|
|
102
|
+
getGlyph,
|
|
103
|
+
}: CreateIconConfig<Name>): React.MemoExoticComponent<
|
|
104
|
+
({
|
|
105
|
+
ref,
|
|
106
|
+
..._props
|
|
107
|
+
}: IconProps<Name> & {
|
|
108
|
+
ref?: React.Ref<Text>;
|
|
109
|
+
}) =>
|
|
110
|
+
| string
|
|
111
|
+
| number
|
|
112
|
+
| bigint
|
|
113
|
+
| boolean
|
|
114
|
+
| Iterable<React.ReactNode>
|
|
115
|
+
| Promise<
|
|
116
|
+
| string
|
|
117
|
+
| number
|
|
118
|
+
| bigint
|
|
119
|
+
| boolean
|
|
120
|
+
| React.ReactPortal
|
|
121
|
+
| React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
|
|
122
|
+
| Iterable<React.ReactNode>
|
|
123
|
+
| null
|
|
124
|
+
| undefined
|
|
125
|
+
>
|
|
126
|
+
| import('react/jsx-runtime').JSX.Element
|
|
127
|
+
| null
|
|
128
|
+
>;
|
|
129
|
+
export { getIconSourceSize };
|
|
130
|
+
//# sourceMappingURL=createIcon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createIcon.d.ts","sourceRoot":"","sources":["../../src/icons/createIcon.tsx"],"names":[],"mappings":"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"}
|
package/dts/icons/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from './Icon';
|
|
2
|
+
export { createIcon, DEFAULT_ICON_FONT_FAMILY } from './createIcon';
|
|
3
|
+
export type { CreateIconConfig, GlyphMap, IconGlyphResolverArgs } from './createIcon';
|
|
2
4
|
export * from './LogoMark';
|
|
3
5
|
export * from './LogoWordmark';
|
|
4
6
|
export * from './SubBrandLogoMark';
|
package/dts/icons/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/icons/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/icons/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACpE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACtF,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC"}
|
package/esm/icons/Icon.js
CHANGED
|
@@ -1,90 +1,7 @@
|
|
|
1
|
-
import React, { memo, useMemo } from 'react';
|
|
2
|
-
import { Animated, Text, useWindowDimensions } from 'react-native';
|
|
3
1
|
import { glyphMap } from '@coinbase/cds-icons/glyphMap';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
-
const getIconSourceSize = iconSize => {
|
|
10
|
-
if (iconSize <= 12) return 12;
|
|
11
|
-
if (iconSize <= 16) return 16;
|
|
12
|
-
return 24;
|
|
13
|
-
};
|
|
14
|
-
export const Icon = /*#__PURE__*/memo(_props => {
|
|
15
|
-
const mergedProps = useComponentConfig('Icon', _props);
|
|
16
|
-
const {
|
|
17
|
-
accessibilityLabel,
|
|
18
|
-
accessibilityHint,
|
|
19
|
-
animated = false,
|
|
20
|
-
color = 'fgPrimary',
|
|
21
|
-
dangerouslySetColor,
|
|
22
|
-
style,
|
|
23
|
-
styles,
|
|
24
|
-
fallback = null,
|
|
25
|
-
name,
|
|
26
|
-
size = 'm',
|
|
27
|
-
testID,
|
|
28
|
-
padding,
|
|
29
|
-
paddingX,
|
|
30
|
-
paddingY,
|
|
31
|
-
paddingTop,
|
|
32
|
-
paddingEnd,
|
|
33
|
-
paddingBottom,
|
|
34
|
-
paddingStart,
|
|
35
|
-
active
|
|
36
|
-
} = mergedProps;
|
|
37
|
-
const TextComponent = animated ? Animated.Text : Text;
|
|
38
|
-
const theme = useTheme();
|
|
39
|
-
const {
|
|
40
|
-
fontScale
|
|
41
|
-
} = useWindowDimensions();
|
|
42
|
-
|
|
43
|
-
// Scale according to device a11y font size settings
|
|
44
|
-
const iconSize = theme.iconSize[size] * fontScale;
|
|
45
|
-
const sourceSize = getIconSourceSize(iconSize);
|
|
46
|
-
const iconColor = theme.color[color];
|
|
47
|
-
const finalColor = dangerouslySetColor != null ? dangerouslySetColor : iconColor;
|
|
48
|
-
const rootStyle = useMemo(() => {
|
|
49
|
-
var _ref, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
|
|
50
|
-
return [{
|
|
51
|
-
paddingTop: theme.space[(_ref = (_ref2 = paddingTop != null ? paddingTop : paddingY) != null ? _ref2 : padding) != null ? _ref : 0],
|
|
52
|
-
paddingEnd: theme.space[(_ref3 = (_ref4 = paddingEnd != null ? paddingEnd : paddingX) != null ? _ref4 : padding) != null ? _ref3 : 0],
|
|
53
|
-
paddingBottom: theme.space[(_ref5 = (_ref6 = paddingBottom != null ? paddingBottom : paddingY) != null ? _ref6 : padding) != null ? _ref5 : 0],
|
|
54
|
-
paddingStart: theme.space[(_ref7 = (_ref8 = paddingStart != null ? paddingStart : paddingX) != null ? _ref8 : padding) != null ? _ref7 : 0]
|
|
55
|
-
}, style, styles == null ? void 0 : styles.root];
|
|
56
|
-
}, [style, theme.space, padding, paddingX, paddingY, paddingTop, paddingEnd, paddingBottom, paddingStart, styles == null ? void 0 : styles.root]);
|
|
57
|
-
const iconStyle = useMemo(() => [{
|
|
58
|
-
fontFamily: 'CoinbaseIcons',
|
|
59
|
-
fontSize: iconSize,
|
|
60
|
-
height: iconSize,
|
|
61
|
-
width: iconSize,
|
|
62
|
-
lineHeight: iconSize,
|
|
63
|
-
color: finalColor
|
|
64
|
-
}, styles == null ? void 0 : styles.icon], [finalColor, iconSize, styles == null ? void 0 : styles.icon]);
|
|
65
|
-
const iconName = name + "-" + sourceSize + "-" + (active ? 'active' : 'inactive');
|
|
66
|
-
const glyph = glyphMap[iconName];
|
|
67
|
-
if (glyph === undefined) {
|
|
68
|
-
if (isDevelopment()) {
|
|
69
|
-
console.error("Unable to find glyph for icon name \"" + name + "\" with glyph key \"" + iconName + "\"");
|
|
70
|
-
}
|
|
71
|
-
return fallback;
|
|
72
|
-
}
|
|
73
|
-
return /*#__PURE__*/_jsx(Box, {
|
|
74
|
-
animated: animated,
|
|
75
|
-
style: rootStyle,
|
|
76
|
-
testID: testID,
|
|
77
|
-
children: /*#__PURE__*/_jsx(TextComponent, {
|
|
78
|
-
accessibilityHint: accessibilityHint,
|
|
79
|
-
accessibilityLabel: accessibilityLabel,
|
|
80
|
-
accessibilityRole: "image",
|
|
81
|
-
accessible: !!accessibilityLabel,
|
|
82
|
-
allowFontScaling: false
|
|
83
|
-
// TODO https://linear.app/coinbase/issue/CDS-1518/audit-potentially-harmful-reactnative-animated-pattern
|
|
84
|
-
,
|
|
85
|
-
style: iconStyle,
|
|
86
|
-
children: glyph
|
|
87
|
-
})
|
|
88
|
-
});
|
|
2
|
+
import { createIcon, DEFAULT_ICON_FONT_FAMILY, getIconSourceSize } from './createIcon';
|
|
3
|
+
export const Icon = createIcon({
|
|
4
|
+
glyphMap,
|
|
5
|
+
fontFamily: DEFAULT_ICON_FONT_FAMILY
|
|
89
6
|
});
|
|
90
7
|
export { getIconSourceSize };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
const _excluded = ["ref"];
|
|
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
|
+
import React, { memo, useMemo } from 'react';
|
|
4
|
+
import { Animated, Text, useWindowDimensions } from 'react-native';
|
|
5
|
+
import { isDevelopment } from '@coinbase/cds-utils';
|
|
6
|
+
import { useComponentConfig } from '../hooks/useComponentConfig';
|
|
7
|
+
import { useTheme } from '../hooks/useTheme';
|
|
8
|
+
import { Box } from '../layout/Box';
|
|
9
|
+
|
|
10
|
+
/** Default font family for the CDS icon glyph font. */
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
export const DEFAULT_ICON_FONT_FAMILY = 'CoinbaseIcons';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Shape of the glyph map an icon set must provide. Keys are
|
|
16
|
+
* `${name}-${sourcePixelSize}-${'active' | 'inactive'}` and values are the
|
|
17
|
+
* single Unicode character rendered in the icon font.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Arguments passed to a glyph resolver to look up an icon's glyph. */
|
|
21
|
+
|
|
22
|
+
/** Configuration used to bind an icon set to a typed `Icon` component. */
|
|
23
|
+
|
|
24
|
+
const getIconSourceSize = iconSize => {
|
|
25
|
+
if (iconSize <= 12) return 12;
|
|
26
|
+
if (iconSize <= 16) return 16;
|
|
27
|
+
return 24;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** Default glyph resolver using the CDS `${name}-${sourceSize}-${state}` key scheme. */
|
|
31
|
+
const defaultGetGlyph = _ref => {
|
|
32
|
+
let {
|
|
33
|
+
glyphMap,
|
|
34
|
+
name,
|
|
35
|
+
pixelSize,
|
|
36
|
+
active
|
|
37
|
+
} = _ref;
|
|
38
|
+
const sourceSize = getIconSourceSize(pixelSize);
|
|
39
|
+
const key = name + "-" + sourceSize + "-" + (active ? 'active' : 'inactive');
|
|
40
|
+
return glyphMap[key];
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Creates a typed `Icon` component bound to a specific icon set (glyph map,
|
|
45
|
+
* font family, and name union). The default CDS `Icon` is created from this
|
|
46
|
+
* factory; consumers with their own icon package can create their own typed
|
|
47
|
+
* icon component that reuses all of the CDS rendering, accessibility, and
|
|
48
|
+
* theming behavior.
|
|
49
|
+
*/
|
|
50
|
+
export function createIcon(_ref2) {
|
|
51
|
+
let {
|
|
52
|
+
glyphMap,
|
|
53
|
+
fontFamily = DEFAULT_ICON_FONT_FAMILY,
|
|
54
|
+
getGlyph = defaultGetGlyph
|
|
55
|
+
} = _ref2;
|
|
56
|
+
const Icon = /*#__PURE__*/memo(_ref3 => {
|
|
57
|
+
let {
|
|
58
|
+
ref
|
|
59
|
+
} = _ref3,
|
|
60
|
+
_props = _objectWithoutPropertiesLoose(_ref3, _excluded);
|
|
61
|
+
const mergedProps = useComponentConfig('Icon', _props);
|
|
62
|
+
const {
|
|
63
|
+
accessibilityLabel,
|
|
64
|
+
accessibilityHint,
|
|
65
|
+
animated = false,
|
|
66
|
+
color = 'fgPrimary',
|
|
67
|
+
dangerouslySetColor,
|
|
68
|
+
style,
|
|
69
|
+
styles,
|
|
70
|
+
fallback = null,
|
|
71
|
+
name,
|
|
72
|
+
size = 'm',
|
|
73
|
+
testID,
|
|
74
|
+
padding,
|
|
75
|
+
paddingX,
|
|
76
|
+
paddingY,
|
|
77
|
+
paddingTop,
|
|
78
|
+
paddingEnd,
|
|
79
|
+
paddingBottom,
|
|
80
|
+
paddingStart,
|
|
81
|
+
active
|
|
82
|
+
} = mergedProps;
|
|
83
|
+
const TextComponent = animated ? Animated.Text : Text;
|
|
84
|
+
const theme = useTheme();
|
|
85
|
+
const {
|
|
86
|
+
fontScale
|
|
87
|
+
} = useWindowDimensions();
|
|
88
|
+
|
|
89
|
+
// Scale according to device a11y font size settings
|
|
90
|
+
const iconSize = theme.iconSize[size] * fontScale;
|
|
91
|
+
const iconColor = theme.color[color];
|
|
92
|
+
const finalColor = dangerouslySetColor != null ? dangerouslySetColor : iconColor;
|
|
93
|
+
const rootStyle = useMemo(() => {
|
|
94
|
+
var _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _ref0, _ref1;
|
|
95
|
+
return [{
|
|
96
|
+
paddingTop: theme.space[(_ref4 = (_ref5 = paddingTop != null ? paddingTop : paddingY) != null ? _ref5 : padding) != null ? _ref4 : 0],
|
|
97
|
+
paddingEnd: theme.space[(_ref6 = (_ref7 = paddingEnd != null ? paddingEnd : paddingX) != null ? _ref7 : padding) != null ? _ref6 : 0],
|
|
98
|
+
paddingBottom: theme.space[(_ref8 = (_ref9 = paddingBottom != null ? paddingBottom : paddingY) != null ? _ref9 : padding) != null ? _ref8 : 0],
|
|
99
|
+
paddingStart: theme.space[(_ref0 = (_ref1 = paddingStart != null ? paddingStart : paddingX) != null ? _ref1 : padding) != null ? _ref0 : 0]
|
|
100
|
+
}, style, styles == null ? void 0 : styles.root];
|
|
101
|
+
}, [style, theme.space, padding, paddingX, paddingY, paddingTop, paddingEnd, paddingBottom, paddingStart, styles == null ? void 0 : styles.root]);
|
|
102
|
+
const iconStyle = useMemo(() => [{
|
|
103
|
+
fontFamily,
|
|
104
|
+
fontSize: iconSize,
|
|
105
|
+
height: iconSize,
|
|
106
|
+
width: iconSize,
|
|
107
|
+
lineHeight: iconSize,
|
|
108
|
+
color: finalColor
|
|
109
|
+
}, styles == null ? void 0 : styles.icon], [finalColor, iconSize, styles == null ? void 0 : styles.icon]);
|
|
110
|
+
const glyph = getGlyph({
|
|
111
|
+
glyphMap,
|
|
112
|
+
name,
|
|
113
|
+
size,
|
|
114
|
+
pixelSize: iconSize,
|
|
115
|
+
active: Boolean(active)
|
|
116
|
+
});
|
|
117
|
+
if (glyph === undefined) {
|
|
118
|
+
if (isDevelopment()) {
|
|
119
|
+
console.error("Unable to find glyph for icon \"" + name + "\" at size \"" + size + "\"");
|
|
120
|
+
}
|
|
121
|
+
return fallback;
|
|
122
|
+
}
|
|
123
|
+
return /*#__PURE__*/_jsx(Box, {
|
|
124
|
+
animated: animated,
|
|
125
|
+
style: rootStyle,
|
|
126
|
+
testID: testID,
|
|
127
|
+
children: /*#__PURE__*/_jsx(TextComponent, {
|
|
128
|
+
ref: ref,
|
|
129
|
+
accessibilityHint: accessibilityHint,
|
|
130
|
+
accessibilityLabel: accessibilityLabel,
|
|
131
|
+
accessibilityRole: "image",
|
|
132
|
+
accessible: !!accessibilityLabel,
|
|
133
|
+
allowFontScaling: false
|
|
134
|
+
// TODO https://linear.app/coinbase/issue/CDS-1518/audit-potentially-harmful-reactnative-animated-pattern
|
|
135
|
+
,
|
|
136
|
+
style: iconStyle,
|
|
137
|
+
children: glyph
|
|
138
|
+
})
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
Icon.displayName = 'Icon';
|
|
142
|
+
return Icon;
|
|
143
|
+
}
|
|
144
|
+
export { getIconSourceSize };
|
package/esm/icons/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coinbase/cds-mobile",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.8.0",
|
|
4
4
|
"description": "Coinbase Design System - Mobile",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
"react-native-worklets": "0.5.2"
|
|
219
219
|
},
|
|
220
220
|
"dependencies": {
|
|
221
|
-
"@coinbase/cds-common": "^9.
|
|
221
|
+
"@coinbase/cds-common": "^9.8.0",
|
|
222
222
|
"@coinbase/cds-icons": "^5.21.0",
|
|
223
223
|
"@coinbase/cds-illustrations": "^4.44.0",
|
|
224
224
|
"@coinbase/cds-lottie-files": "^3.3.4",
|