@coinbase/cds-web 9.18.0 → 9.20.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 CHANGED
@@ -8,6 +8,18 @@ All notable changes to this project will be documented in this file.
8
8
 
9
9
  <!-- template-start -->
10
10
 
11
+ ## 9.20.0 (8/20/2026 PST)
12
+
13
+ #### 🚀 Updates
14
+
15
+ - Feat: update default label style for input components: TextInput, Select, Combobox, DateInput, etc. Font: label1 -=> label2; color: fg => fgMuted.
16
+
17
+ ## 9.19.0 (8/20/2026 PST)
18
+
19
+ #### 🚀 Updates
20
+
21
+ - Feat: support custom icon sets in name-prop components. [[#848](https://github.com/coinbase/cds/pull/848)]
22
+
11
23
  ## 9.18.0 (8/19/2026 PST)
12
24
 
13
25
  #### 🚀 Updates
@@ -1 +1 @@
1
- {"version":3,"file":"SelectTrigger.d.ts","sourceRoot":"","sources":["../../src/controls/SelectTrigger.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAchD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAOhD,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,eAAe,EACf,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAC1D,GAAG;IACF,eAAe,EAAE,OAAO,CAAC;IACzB,qCAAqC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAeF,eAAO,MAAM,aAAa;qBApBP,OAAO;IACxB,qCAAqC;cAC3B,OAAO;IACjB,iEAAiE;cACvD,MAAM,IAAI;qCAyIrB,CAAC"}
1
+ {"version":3,"file":"SelectTrigger.d.ts","sourceRoot":"","sources":["../../src/controls/SelectTrigger.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAchD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAOhD,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,eAAe,EACf,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAC1D,GAAG;IACF,eAAe,EAAE,OAAO,CAAC;IACzB,qCAAqC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAeF,eAAO,MAAM,aAAa;qBApBP,OAAO;IACxB,qCAAqC;cAC3B,OAAO;IACjB,iEAAiE;cACvD,MAAM,IAAI;qCA+IrB,CAAC"}
@@ -4,31 +4,21 @@ import type { SharedProps } from '@coinbase/cds-common/types/SharedProps';
4
4
  import { type BoxBaseProps, type BoxDefaultElement, type BoxProps } from '../layout/Box';
5
5
  /** Default font family for the CDS icon glyph font. */
6
6
  export declare const DEFAULT_ICON_FONT_FAMILY = 'CoinbaseIcons';
7
- /**
8
- * Shape of the glyph map an icon set must provide. Keys are
9
- * `${name}-${sourcePixelSize}-${'active' | 'inactive'}` and values are the
10
- * single Unicode character rendered in the icon font.
11
- */
7
+ /** Values are the single character to render in the icon font. */
12
8
  export type GlyphMap<Name extends string> = Record<
13
9
  `${Name}-${IconSourcePixelSize}-${'active' | 'inactive'}`,
14
10
  string
15
11
  >;
16
- /** Arguments passed to a glyph resolver to look up an icon's glyph. */
17
12
  export type IconGlyphResolverArgs<Name extends string> = {
18
- /** Glyph map bound to this icon set. */
19
13
  glyphMap: GlyphMap<Name>;
20
- /** Icon name requested via the `name` prop. */
21
14
  name: Name;
22
- /** Size token requested via the `size` prop. */
23
15
  size: IconSize;
24
- /** Resolved pixel size from the theme for the requested `size` token. */
16
+ /** Pixel size resolved from the theme for the requested `size` token. */
25
17
  pixelSize: number;
26
- /** Whether the active variant was requested. */
27
18
  active: boolean;
28
19
  };
29
- /** Configuration used to bind an icon set to a typed `Icon` component. */
30
- export type CreateIconConfig<Name extends string> = {
31
- /** Generated glyph map for this icon set. */
20
+ /** An icon font and the glyphs it provides. */
21
+ export type IconGlyphSource<Name extends string = string> = {
32
22
  glyphMap: GlyphMap<Name>;
33
23
  /**
34
24
  * `@font-face` family name registered by the icon set's font.
@@ -36,13 +26,27 @@ export type CreateIconConfig<Name extends string> = {
36
26
  */
37
27
  fontFamily?: string;
38
28
  /**
39
- * Resolves the glyph to render for an icon from the glyph map. Override to
40
- * support a custom key format or size model. Defaults to the CDS scheme:
41
- * `${name}-${sourceSize}-${'active' | 'inactive'}`, where `sourceSize` is
42
- * `12`, `16`, or `24`.
29
+ * Override to use a custom key format or size model. Defaults to the CDS
30
+ * scheme: `${name}-${sourceSize}-${state}`, with `sourceSize` 12, 16, or 24.
43
31
  */
44
32
  getGlyph?: (args: IconGlyphResolverArgs<Name>) => string | undefined;
45
33
  };
34
+ export type IconGlyphSourceProviderProps = {
35
+ /** Consulted before the built-in glyphs. A nested provider replaces it. */
36
+ source: IconGlyphSource<any>;
37
+ children: React.ReactNode;
38
+ };
39
+ /**
40
+ * Adds a custom glyph source to every CDS icon rendered below.
41
+ *
42
+ * Scope this to a subtree: a source reusing a built-in name re-skins that icon
43
+ * everywhere below, including icons CDS renders internally (`close`, `caretUp`,
44
+ * `checkmark`). Its names must be names the icon component already accepts.
45
+ */
46
+ export declare function IconGlyphSourceProvider({
47
+ source,
48
+ children,
49
+ }: IconGlyphSourceProviderProps): import('react/jsx-runtime').JSX.Element;
46
50
  export type IconBaseProps<Name extends string = string> = SharedProps &
47
51
  Pick<
48
52
  BoxBaseProps,
@@ -95,19 +99,9 @@ export type IconProps<Name extends string = string> = IconBaseProps<Name> &
95
99
  };
96
100
  };
97
101
  declare const getIconSourceSize: (iconSize: number) => IconSourcePixelSize;
98
- /**
99
- * Creates a typed `Icon` component bound to a specific icon set (glyph map,
100
- * font family, and name union). The default CDS `Icon` is created from this
101
- * factory; consumers with their own icon package can create their own typed
102
- * icon component that reuses all of the CDS rendering, accessibility, and
103
- * theming behavior.
104
- */
105
- export declare function createIcon<Name extends string>({
106
- glyphMap,
107
- fontFamily,
108
- getGlyph,
109
- }: CreateIconConfig<Name>): React.NamedExoticComponent<
110
- Omit<IconProps<Name>, 'ref'> & React.RefAttributes<HTMLElement>
111
- >;
102
+ /** Creates a typed `Icon` component bound to an icon set. */
103
+ export declare function createIcon<Name extends string>(
104
+ source: IconGlyphSource<Name>,
105
+ ): React.NamedExoticComponent<Omit<IconProps<Name>, 'ref'> & React.RefAttributes<HTMLElement>>;
112
106
  export { getIconSourceSize };
113
107
  //# sourceMappingURL=createIcon.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createIcon.d.ts","sourceRoot":"","sources":["../../src/icons/createIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAQ1E,OAAO,EAAO,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI9F,uDAAuD;AACvD,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAExD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,CAAC,IAAI,SAAS,MAAM,IAAI,MAAM,CAChD,GAAG,IAAI,IAAI,mBAAmB,IAAI,QAAQ,GAAG,UAAU,EAAE,EACzD,MAAM,CACP,CAAC;AAEF,uEAAuE;AACvE,MAAM,MAAM,qBAAqB,CAAC,IAAI,SAAS,MAAM,IAAI;IACvD,wCAAwC;IACxC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzB,+CAA+C;IAC/C,IAAI,EAAE,IAAI,CAAC;IACX,gDAAgD;IAChD,IAAI,EAAE,QAAQ,CAAC;IACf,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,CAAC,IAAI,SAAS,MAAM,IAAI;IAClD,6CAA6C;IAC7C,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;CACtE,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI,WAAW,GACnE,IAAI,CACF,YAAY,EACV,SAAS,GACT,UAAU,GACV,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,cAAc,CACjB,GAAG;IACF;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,6CAA6C;IAC7C,IAAI,EAAE,IAAI,CAAC;IACX;;;SAGK;IACL,QAAQ,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEJ,MAAM,MAAM,SAAS,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI,aAAa,CAAC,IAAI,CAAC,GACvE,QAAQ,CAAC,iBAAiB,CAAC,GAAG;IAC5B,yEAAyE;IACzE,MAAM,CAAC,EAAE;QACP,gCAAgC;QAChC,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAC3B,+BAA+B;QAC/B,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;KAC5B,CAAC;IACF,uEAAuE;IACvE,UAAU,CAAC,EAAE;QACX,gCAAgC;QAChC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,+BAA+B;QAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAAC;AA2CJ,QAAA,MAAM,iBAAiB,GAAI,UAAU,MAAM,KAAG,mBAI7C,CAAC;AAcF;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,SAAS,MAAM,EAAE,EAC9C,QAAQ,EACR,UAAqC,EACrC,QAA0B,GAC3B,EAAE,gBAAgB,CAAC,IAAI,CAAC,+FAgGxB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"createIcon.d.ts","sourceRoot":"","sources":["../../src/icons/createIcon.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,11 @@
1
+ export type {
2
+ GlyphMap,
3
+ IconGlyphResolverArgs,
4
+ IconGlyphSource,
5
+ IconGlyphSourceProviderProps,
6
+ } from './createIcon';
7
+ export { createIcon, DEFAULT_ICON_FONT_FAMILY, IconGlyphSourceProvider } from './createIcon';
1
8
  export * from './Icon';
2
- export { createIcon, DEFAULT_ICON_FONT_FAMILY } from './createIcon';
3
- export type { CreateIconConfig, GlyphMap, IconGlyphResolverArgs } from './createIcon';
4
9
  export * from './LogoMark';
5
10
  export * from './LogoWordmark';
6
11
  export * from './SubBrandLogoMark';
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/icons/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,QAAQ,EACR,qBAAqB,EACrB,eAAe,EACf,4BAA4B,GAC7B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC7F,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
@@ -82,8 +82,8 @@ const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef(
82
82
  blendStyles,
83
83
  align = 'start',
84
84
  font = 'body',
85
- labelColor = 'fg',
86
- labelFont = 'label1',
85
+ labelColor = 'fgMuted',
86
+ labelFont = 'label2',
87
87
  bordered = true,
88
88
  borderWidth = bordered ? 100 : 0,
89
89
  focusedBorderWidth = bordered ? undefined : 200,
@@ -11,9 +11,9 @@ import { Text } from '../typography/Text';
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
12
12
  export const InputLabel = /*#__PURE__*/memo(function InputLabel(_ref) {
13
13
  let {
14
- color = 'fg',
14
+ color = 'fgMuted',
15
15
  disabled = false,
16
- font = 'label1'
16
+ font = 'label2'
17
17
  } = _ref,
18
18
  props = _objectWithoutProperties(_ref, _excluded);
19
19
  return /*#__PURE__*/_jsx(Text, _objectSpread({
@@ -52,6 +52,7 @@ export const SelectStack = /*#__PURE__*/memo(/*#__PURE__*/forwardRef(function Se
52
52
  onClick: handlePreventPropagation,
53
53
  children: /*#__PURE__*/_jsx(InputLabel, {
54
54
  color: "fg",
55
+ font: "label1",
55
56
  id: accessibilityLabelId,
56
57
  overflow: "truncate",
57
58
  children: label
@@ -89,6 +89,7 @@ export const SelectTrigger = /*#__PURE__*/memo(/*#__PURE__*/forwardRef(function
89
89
  paddingEnd: 1,
90
90
  children: /*#__PURE__*/_jsx(InputLabel, {
91
91
  color: "fg",
92
+ font: "label1",
92
93
  id: accessibilityLabelId,
93
94
  overflow: "truncate",
94
95
  children: label
@@ -111,6 +112,7 @@ export const SelectTrigger = /*#__PURE__*/memo(/*#__PURE__*/forwardRef(function
111
112
  width: "100%",
112
113
  children: [/*#__PURE__*/_jsx(InputLabel, {
113
114
  color: "fg",
115
+ font: "label1",
114
116
  id: accessibilityLabelId,
115
117
  overflow: "truncate",
116
118
  paddingY: 0,
@@ -48,8 +48,8 @@ export const TextInput = /*#__PURE__*/memo(/*#__PURE__*/forwardRef(function Text
48
48
  const mergedProps = useComponentConfig('TextInput', _props);
49
49
  const {
50
50
  label,
51
- labelFont = 'label1',
52
- labelColor = 'fg',
51
+ labelFont = 'label2',
52
+ labelColor = 'fgMuted',
53
53
  accessibilityLabel,
54
54
  helperText = '',
55
55
  variant = 'foregroundMuted',
@@ -1,12 +1,12 @@
1
1
  const _excluded = ["accessibilityLabel", "color", "dangerouslySetColor", "fallback", "name", "size", "testID", "className", "classNames", "style", "styles", "active"];
2
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
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; }
2
4
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
5
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
6
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
5
7
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
6
8
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
- function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
8
- 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; }
9
- import React, { forwardRef, memo, useMemo } from 'react';
9
+ import React, { createContext, forwardRef, memo, useContext, useMemo } from 'react';
10
10
  import { isDevelopment } from '@coinbase/cds-utils/env';
11
11
  import { cx } from '../cx';
12
12
  import { useComponentConfig } from '../hooks/useComponentConfig';
@@ -18,16 +18,28 @@ const COMPONENT_STATIC_CLASSNAME = 'cds-Icon';
18
18
  /** Default font family for the CDS icon glyph font. */
19
19
  export const DEFAULT_ICON_FONT_FAMILY = 'CoinbaseIcons';
20
20
 
21
- /**
22
- * Shape of the glyph map an icon set must provide. Keys are
23
- * `${name}-${sourcePixelSize}-${'active' | 'inactive'}` and values are the
24
- * single Unicode character rendered in the icon font.
25
- */
21
+ /** Values are the single character to render in the icon font. */
26
22
 
27
- /** Arguments passed to a glyph resolver to look up an icon's glyph. */
28
-
29
- /** Configuration used to bind an icon set to a typed `Icon` component. */
23
+ /** An icon font and the glyphs it provides. */
30
24
 
25
+ const IconGlyphSourceContext = /*#__PURE__*/createContext(undefined);
26
+ /**
27
+ * Adds a custom glyph source to every CDS icon rendered below.
28
+ *
29
+ * Scope this to a subtree: a source reusing a built-in name re-skins that icon
30
+ * everywhere below, including icons CDS renders internally (`close`, `caretUp`,
31
+ * `checkmark`). Its names must be names the icon component already accepts.
32
+ */
33
+ export function IconGlyphSourceProvider(_ref) {
34
+ let {
35
+ source,
36
+ children
37
+ } = _ref;
38
+ return /*#__PURE__*/_jsx(IconGlyphSourceContext.Provider, {
39
+ value: source,
40
+ children: children
41
+ });
42
+ }
31
43
  const iconCss = "iconCss-i1t3cbh7";
32
44
  const sizeCss = {
33
45
  xs: "xs-xffinnj",
@@ -42,31 +54,35 @@ const getIconSourceSize = iconSize => {
42
54
  };
43
55
 
44
56
  /** Default glyph resolver using the CDS `${name}-${sourceSize}-${state}` key scheme. */
45
- const defaultGetGlyph = _ref => {
57
+ const defaultGetGlyph = _ref2 => {
46
58
  let {
47
59
  glyphMap,
48
60
  name,
49
61
  pixelSize,
50
62
  active
51
- } = _ref;
63
+ } = _ref2;
52
64
  const sourceSize = getIconSourceSize(pixelSize);
53
65
  const key = "".concat(name, "-").concat(sourceSize, "-").concat(active ? 'active' : 'inactive');
54
66
  return glyphMap[key];
55
67
  };
68
+ /** Resolves a glyph from one source, with that source's font. */
69
+ const resolveFromSource = (source, args) => {
70
+ var _source$getGlyph, _source$fontFamily;
71
+ const char = ((_source$getGlyph = source.getGlyph) !== null && _source$getGlyph !== void 0 ? _source$getGlyph : defaultGetGlyph)(_objectSpread(_objectSpread({}, args), {}, {
72
+ glyphMap: source.glyphMap
73
+ }));
74
+ return char === undefined ? undefined : {
75
+ char,
76
+ fontFamily: (_source$fontFamily = source.fontFamily) !== null && _source$fontFamily !== void 0 ? _source$fontFamily : DEFAULT_ICON_FONT_FAMILY
77
+ };
78
+ };
79
+ const resolveGlyph = (contextSource, boundSource, args) => {
80
+ const fromContext = contextSource ? resolveFromSource(contextSource, args) : undefined;
81
+ return fromContext !== null && fromContext !== void 0 ? fromContext : resolveFromSource(boundSource, args);
82
+ };
56
83
 
57
- /**
58
- * Creates a typed `Icon` component bound to a specific icon set (glyph map,
59
- * font family, and name union). The default CDS `Icon` is created from this
60
- * factory; consumers with their own icon package can create their own typed
61
- * icon component that reuses all of the CDS rendering, accessibility, and
62
- * theming behavior.
63
- */
64
- export function createIcon(_ref2) {
65
- let {
66
- glyphMap,
67
- fontFamily = DEFAULT_ICON_FONT_FAMILY,
68
- getGlyph = defaultGetGlyph
69
- } = _ref2;
84
+ /** Creates a typed `Icon` component bound to an icon set. */
85
+ export function createIcon(source) {
70
86
  const Icon = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_props, ref) => {
71
87
  const mergedProps = useComponentConfig('Icon', _props);
72
88
  const {
@@ -86,23 +102,27 @@ export function createIcon(_ref2) {
86
102
  props = _objectWithoutProperties(mergedProps, _excluded);
87
103
  const theme = useTheme();
88
104
  const iconSize = theme.iconSize[size];
89
- const rootStyle = useMemo(() => _objectSpread(_objectSpread(_objectSpread({}, dangerouslySetColor ? {
90
- color: dangerouslySetColor
91
- } : {}), style), styles === null || styles === void 0 ? void 0 : styles.root), [dangerouslySetColor, style, styles === null || styles === void 0 ? void 0 : styles.root]);
92
105
 
93
- // Only override the font-family CSS variable when a custom font is bound;
94
- // the default is applied by the static Linaria block's fallback value.
95
- const iconStyle = useMemo(() => fontFamily === DEFAULT_ICON_FONT_FAMILY ? styles === null || styles === void 0 ? void 0 : styles.icon : _objectSpread({
96
- '--cds-icon-font-family': fontFamily
97
- }, styles === null || styles === void 0 ? void 0 : styles.icon), [styles === null || styles === void 0 ? void 0 : styles.icon]);
98
- const glyph = getGlyph({
99
- glyphMap,
106
+ // Tried before the bound set, so a source can override a built-in icon.
107
+ const contextSource = useContext(IconGlyphSourceContext);
108
+ const resolved = resolveGlyph(contextSource, source, {
100
109
  name,
101
110
  size,
102
111
  pixelSize: iconSize,
103
112
  active: Boolean(active)
104
113
  });
105
- if (glyph === undefined) {
114
+ const rootStyle = useMemo(() => _objectSpread(_objectSpread(_objectSpread({}, dangerouslySetColor ? {
115
+ color: dangerouslySetColor
116
+ } : {}), style), styles === null || styles === void 0 ? void 0 : styles.root), [dangerouslySetColor, style, styles === null || styles === void 0 ? void 0 : styles.root]);
117
+
118
+ // The matching source decides the font, so a source covering only some
119
+ // sizes or states of a name mixes fonts across that name.
120
+ // Only set the variable for non-default fonts; the Linaria block has the default.
121
+ const fontFamily = resolved === null || resolved === void 0 ? void 0 : resolved.fontFamily;
122
+ const iconStyle = useMemo(() => fontFamily === undefined || fontFamily === DEFAULT_ICON_FONT_FAMILY ? styles === null || styles === void 0 ? void 0 : styles.icon : _objectSpread({
123
+ '--cds-icon-font-family': fontFamily
124
+ }, styles === null || styles === void 0 ? void 0 : styles.icon), [fontFamily, styles === null || styles === void 0 ? void 0 : styles.icon]);
125
+ if (resolved === undefined) {
106
126
  if (isDevelopment()) {
107
127
  console.error("Unable to find glyph for icon \"".concat(name, "\" at size \"").concat(size, "\""));
108
128
  }
@@ -127,7 +147,7 @@ export function createIcon(_ref2) {
127
147
  style: iconStyle,
128
148
  title: accessibilityLabel,
129
149
  translate: "no",
130
- children: glyph
150
+ children: resolved.char
131
151
  })
132
152
  }));
133
153
  }));
@@ -1,5 +1,5 @@
1
+ export { createIcon, DEFAULT_ICON_FONT_FAMILY, IconGlyphSourceProvider } from './createIcon';
1
2
  export * from './Icon';
2
- export { createIcon, DEFAULT_ICON_FONT_FAMILY } from './createIcon';
3
3
  export * from './LogoMark';
4
4
  export * from './LogoWordmark';
5
5
  export * from './SubBrandLogoMark';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cds-web",
3
- "version": "9.18.0",
3
+ "version": "9.20.0",
4
4
  "description": "Coinbase Design System - Web",
5
5
  "repository": {
6
6
  "type": "git",
@@ -227,8 +227,8 @@
227
227
  "react-dom": "^18.0.0 || ~19.1.2"
228
228
  },
229
229
  "dependencies": {
230
- "@coinbase/cds-common": "^9.18.0",
231
- "@coinbase/cds-icons": "^5.21.0",
230
+ "@coinbase/cds-common": "^9.20.0",
231
+ "@coinbase/cds-icons": "^5.22.0",
232
232
  "@coinbase/cds-illustrations": "^4.48.0",
233
233
  "@coinbase/cds-lottie-files": "^3.3.4",
234
234
  "@coinbase/cds-utils": "^2.3.5",