@atlaskit/heading 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/heading
2
2
 
3
+ ## 1.4.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#41226](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/41226) [`fc7aba3cbae`](https://bitbucket.org/atlassian/atlassian-frontend/commits/fc7aba3cbae) - [ux] Further fixes related to heading getting into possible invalid state. Heading will now always produce valid markup / aria-attributes for any configuration. Previously if there was no `HeadingContext` in the tree the heading would not produce accessibly correct markup in some cases. This is now resolved.
8
+
9
+ ## 1.4.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [#41124](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/41124) [`40cd7f0c882`](https://bitbucket.org/atlassian/atlassian-frontend/commits/40cd7f0c882) - Fix to prevent heading getting into possible invalid state.
14
+
3
15
  ## 1.4.1
4
16
 
5
17
  ### Patch Changes
@@ -4,7 +4,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.useHeadingElement = exports.default = void 0;
7
+ exports.useHeadingLevel = exports.useHeading = exports.default = void 0;
8
8
  var _react = _interopRequireWildcard(require("react"));
9
9
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
10
10
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -16,9 +16,22 @@ var HeadingLevelContext = /*#__PURE__*/(0, _react.createContext)(0);
16
16
  * @internal
17
17
  * @returns The current heading level context.
18
18
  */
19
- var useHeadingElement = exports.useHeadingElement = function useHeadingElement() {
19
+ var useHeadingLevel = exports.useHeadingLevel = function useHeadingLevel() {
20
20
  return (0, _react.useContext)(HeadingLevelContext);
21
21
  };
22
+
23
+ /**
24
+ * Infers the correct heading markup based on the current heading level context.
25
+ */
26
+ var useHeading = exports.useHeading = function useHeading(fallback) {
27
+ var hLevel = useHeadingLevel();
28
+ /**
29
+ * Order here is important, we for now apply
30
+ * 1. inferred a11y level (this only applies if context is present)
31
+ * 2. default final fallback
32
+ */
33
+ return [hLevel, hLevel && (hLevel > 6 ? 'div' : "h".concat(hLevel)) || fallback];
34
+ };
22
35
  /**
23
36
  * __Heading level provider__
24
37
  *
@@ -38,7 +51,7 @@ var useHeadingElement = exports.useHeadingElement = function useHeadingElement()
38
51
  var HeadingLevelContextProvider = function HeadingLevelContextProvider(_ref) {
39
52
  var children = _ref.children,
40
53
  value = _ref.value;
41
- var parentHeadingLevel = useHeadingElement();
54
+ var parentHeadingLevel = useHeadingLevel();
42
55
  var headingLevel = parentHeadingLevel + 1;
43
56
  return /*#__PURE__*/_react.default.createElement(HeadingLevelContext.Provider, {
44
57
  value: value || headingLevel
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
11
  var _react = require("@emotion/react");
11
12
  var _headingContext = require("./heading-context");
12
13
  var _heading = _interopRequireDefault(require("./heading.partial"));
@@ -117,20 +118,18 @@ var Heading = function Heading(_ref) {
117
118
  if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production' && as && typeof as !== 'string') {
118
119
  throw new Error('`as` prop should be a string.');
119
120
  }
120
- var hLevel = (0, _headingContext.useHeadingElement)();
121
- /**
122
- * Order here is important, we for now apply
123
- * 1. user choice
124
- * 2. inferred a11y level
125
- * 3. default final fallback
126
- */
127
- var Markup = as || hLevel && (hLevel > 6 ? 'div' : "h".concat(hLevel)) || levelMap[level];
121
+ var _useHeading = (0, _headingContext.useHeading)(levelMap[level]),
122
+ _useHeading2 = (0, _slicedToArray2.default)(_useHeading, 2),
123
+ hLevel = _useHeading2[0],
124
+ inferredElement = _useHeading2[1];
125
+ var Markup = as || inferredElement;
128
126
  var isSubtleHeading = level === 'h200' || level === 'h100';
127
+ var needsAriaRole = Markup === 'div' && hLevel;
129
128
  return (0, _react.jsx)(Markup, {
130
129
  id: id,
131
130
  "data-testid": testId,
132
- role: Markup === 'div' ? 'heading' : undefined,
133
- "aria-level": Markup === 'div' ? hLevel : undefined,
131
+ role: needsAriaRole ? 'heading' : undefined,
132
+ "aria-level": needsAriaRole ? hLevel : undefined,
134
133
  css: [headingResetStyles, level === 'h100' && h100Styles, level === 'h200' && h200Styles, level === 'h300' && h300Styles, level === 'h400' && h400Styles, level === 'h500' && h500Styles, level === 'h600' && h600Styles, level === 'h700' && h700Styles, level === 'h800' && h800Styles, level === 'h900' && h900Styles, color === 'inverse' && inverseStyles, color === 'default' && isSubtleHeading && subtlestStyles]
135
134
  }, children);
136
135
  };
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.default = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
7
9
  var _react = require("@emotion/react");
8
10
  var _headingContext = require("./heading-context");
9
11
  /** @jsx jsx */
@@ -54,19 +56,17 @@ var Heading = function Heading(_ref) {
54
56
  if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production' && as && typeof as !== 'string') {
55
57
  throw new Error('`as` prop should be a string.');
56
58
  }
57
- var hLevel = (0, _headingContext.useHeadingElement)();
58
- /**
59
- * Order here is important, we for now apply
60
- * 1. user choice
61
- * 2. inferred a11y level
62
- * 3. default final fallback
63
- */
64
- var Markup = as || hLevel && (hLevel > 6 ? 'div' : "h".concat(hLevel)) || levelMap[variant];
59
+ var _useHeading = (0, _headingContext.useHeading)(levelMap[variant]),
60
+ _useHeading2 = (0, _slicedToArray2.default)(_useHeading, 2),
61
+ hLevel = _useHeading2[0],
62
+ inferredElement = _useHeading2[1];
63
+ var Markup = as || inferredElement;
64
+ var needsAriaRole = Markup === 'div' && hLevel;
65
65
  return (0, _react.jsx)(Markup, {
66
66
  id: id,
67
67
  "data-testid": testId,
68
- role: Markup === 'div' ? 'heading' : undefined,
69
- "aria-level": Markup === 'div' ? hLevel : undefined,
68
+ role: needsAriaRole ? 'heading' : undefined,
69
+ "aria-level": needsAriaRole ? hLevel : undefined,
70
70
  css: [headingResetStyles, variant && headingVariantStylesMap[variant], color === 'inverse' && inverseStyles]
71
71
  }, children);
72
72
  };
@@ -8,9 +8,22 @@ const HeadingLevelContext = /*#__PURE__*/createContext(0);
8
8
  * @internal
9
9
  * @returns The current heading level context.
10
10
  */
11
- export const useHeadingElement = () => {
11
+ export const useHeadingLevel = () => {
12
12
  return useContext(HeadingLevelContext);
13
13
  };
14
+
15
+ /**
16
+ * Infers the correct heading markup based on the current heading level context.
17
+ */
18
+ export const useHeading = fallback => {
19
+ const hLevel = useHeadingLevel();
20
+ /**
21
+ * Order here is important, we for now apply
22
+ * 1. inferred a11y level (this only applies if context is present)
23
+ * 2. default final fallback
24
+ */
25
+ return [hLevel, hLevel && (hLevel > 6 ? 'div' : `h${hLevel}`) || fallback];
26
+ };
14
27
  /**
15
28
  * __Heading level provider__
16
29
  *
@@ -31,7 +44,7 @@ const HeadingLevelContextProvider = ({
31
44
  children,
32
45
  value
33
46
  }) => {
34
- const parentHeadingLevel = useHeadingElement();
47
+ const parentHeadingLevel = useHeadingLevel();
35
48
  const headingLevel = parentHeadingLevel + 1;
36
49
  return /*#__PURE__*/React.createElement(HeadingLevelContext.Provider, {
37
50
  value: value || headingLevel
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  /** @jsx jsx */
3
3
  import { css, jsx } from '@emotion/react';
4
- import { useHeadingElement } from './heading-context';
4
+ import { useHeading } from './heading-context';
5
5
  import NewHeading from './heading.partial';
6
6
  // https://atlassian.design/foundations/typography
7
7
  const levelMap = {
@@ -108,20 +108,15 @@ const Heading = ({
108
108
  if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production' && as && typeof as !== 'string') {
109
109
  throw new Error('`as` prop should be a string.');
110
110
  }
111
- const hLevel = useHeadingElement();
112
- /**
113
- * Order here is important, we for now apply
114
- * 1. user choice
115
- * 2. inferred a11y level
116
- * 3. default final fallback
117
- */
118
- const Markup = as || hLevel && (hLevel > 6 ? 'div' : `h${hLevel}`) || levelMap[level];
111
+ const [hLevel, inferredElement] = useHeading(levelMap[level]);
112
+ const Markup = as || inferredElement;
119
113
  const isSubtleHeading = level === 'h200' || level === 'h100';
114
+ const needsAriaRole = Markup === 'div' && hLevel;
120
115
  return jsx(Markup, {
121
116
  id: id,
122
117
  "data-testid": testId,
123
- role: Markup === 'div' ? 'heading' : undefined,
124
- "aria-level": Markup === 'div' ? hLevel : undefined,
118
+ role: needsAriaRole ? 'heading' : undefined,
119
+ "aria-level": needsAriaRole ? hLevel : undefined,
125
120
  css: [headingResetStyles, level === 'h100' && h100Styles, level === 'h200' && h200Styles, level === 'h300' && h300Styles, level === 'h400' && h400Styles, level === 'h500' && h500Styles, level === 'h600' && h600Styles, level === 'h700' && h700Styles, level === 'h800' && h800Styles, level === 'h900' && h900Styles, color === 'inverse' && inverseStyles, color === 'default' && isSubtleHeading && subtlestStyles]
126
121
  }, children);
127
122
  };
@@ -1,6 +1,6 @@
1
1
  /** @jsx jsx */
2
2
  import { css, jsx } from '@emotion/react';
3
- import { useHeadingElement } from './heading-context';
3
+ import { useHeading } from './heading-context';
4
4
  // https://atlassian.design/foundations/typography
5
5
  const levelMap = {
6
6
  xxlarge: 'h1',
@@ -47,19 +47,14 @@ const Heading = ({
47
47
  if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production' && as && typeof as !== 'string') {
48
48
  throw new Error('`as` prop should be a string.');
49
49
  }
50
- const hLevel = useHeadingElement();
51
- /**
52
- * Order here is important, we for now apply
53
- * 1. user choice
54
- * 2. inferred a11y level
55
- * 3. default final fallback
56
- */
57
- const Markup = as || hLevel && (hLevel > 6 ? 'div' : `h${hLevel}`) || levelMap[variant];
50
+ const [hLevel, inferredElement] = useHeading(levelMap[variant]);
51
+ const Markup = as || inferredElement;
52
+ const needsAriaRole = Markup === 'div' && hLevel;
58
53
  return jsx(Markup, {
59
54
  id: id,
60
55
  "data-testid": testId,
61
- role: Markup === 'div' ? 'heading' : undefined,
62
- "aria-level": Markup === 'div' ? hLevel : undefined,
56
+ role: needsAriaRole ? 'heading' : undefined,
57
+ "aria-level": needsAriaRole ? hLevel : undefined,
63
58
  css: [headingResetStyles, variant && headingVariantStylesMap[variant], color === 'inverse' && inverseStyles]
64
59
  }, children);
65
60
  };
@@ -8,9 +8,22 @@ var HeadingLevelContext = /*#__PURE__*/createContext(0);
8
8
  * @internal
9
9
  * @returns The current heading level context.
10
10
  */
11
- export var useHeadingElement = function useHeadingElement() {
11
+ export var useHeadingLevel = function useHeadingLevel() {
12
12
  return useContext(HeadingLevelContext);
13
13
  };
14
+
15
+ /**
16
+ * Infers the correct heading markup based on the current heading level context.
17
+ */
18
+ export var useHeading = function useHeading(fallback) {
19
+ var hLevel = useHeadingLevel();
20
+ /**
21
+ * Order here is important, we for now apply
22
+ * 1. inferred a11y level (this only applies if context is present)
23
+ * 2. default final fallback
24
+ */
25
+ return [hLevel, hLevel && (hLevel > 6 ? 'div' : "h".concat(hLevel)) || fallback];
26
+ };
14
27
  /**
15
28
  * __Heading level provider__
16
29
  *
@@ -30,7 +43,7 @@ export var useHeadingElement = function useHeadingElement() {
30
43
  var HeadingLevelContextProvider = function HeadingLevelContextProvider(_ref) {
31
44
  var children = _ref.children,
32
45
  value = _ref.value;
33
- var parentHeadingLevel = useHeadingElement();
46
+ var parentHeadingLevel = useHeadingLevel();
34
47
  var headingLevel = parentHeadingLevel + 1;
35
48
  return /*#__PURE__*/React.createElement(HeadingLevelContext.Provider, {
36
49
  value: value || headingLevel
@@ -1,9 +1,10 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
4
  var _excluded = ["level", "variant"];
4
5
  /** @jsx jsx */
5
6
  import { css, jsx } from '@emotion/react';
6
- import { useHeadingElement } from './heading-context';
7
+ import { useHeading } from './heading-context';
7
8
  import NewHeading from './heading.partial';
8
9
  // https://atlassian.design/foundations/typography
9
10
  var levelMap = {
@@ -110,20 +111,18 @@ var Heading = function Heading(_ref) {
110
111
  if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production' && as && typeof as !== 'string') {
111
112
  throw new Error('`as` prop should be a string.');
112
113
  }
113
- var hLevel = useHeadingElement();
114
- /**
115
- * Order here is important, we for now apply
116
- * 1. user choice
117
- * 2. inferred a11y level
118
- * 3. default final fallback
119
- */
120
- var Markup = as || hLevel && (hLevel > 6 ? 'div' : "h".concat(hLevel)) || levelMap[level];
114
+ var _useHeading = useHeading(levelMap[level]),
115
+ _useHeading2 = _slicedToArray(_useHeading, 2),
116
+ hLevel = _useHeading2[0],
117
+ inferredElement = _useHeading2[1];
118
+ var Markup = as || inferredElement;
121
119
  var isSubtleHeading = level === 'h200' || level === 'h100';
120
+ var needsAriaRole = Markup === 'div' && hLevel;
122
121
  return jsx(Markup, {
123
122
  id: id,
124
123
  "data-testid": testId,
125
- role: Markup === 'div' ? 'heading' : undefined,
126
- "aria-level": Markup === 'div' ? hLevel : undefined,
124
+ role: needsAriaRole ? 'heading' : undefined,
125
+ "aria-level": needsAriaRole ? hLevel : undefined,
127
126
  css: [headingResetStyles, level === 'h100' && h100Styles, level === 'h200' && h200Styles, level === 'h300' && h300Styles, level === 'h400' && h400Styles, level === 'h500' && h500Styles, level === 'h600' && h600Styles, level === 'h700' && h700Styles, level === 'h800' && h800Styles, level === 'h900' && h900Styles, color === 'inverse' && inverseStyles, color === 'default' && isSubtleHeading && subtlestStyles]
128
127
  }, children);
129
128
  };
@@ -1,6 +1,7 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
1
2
  /** @jsx jsx */
2
3
  import { css, jsx } from '@emotion/react';
3
- import { useHeadingElement } from './heading-context';
4
+ import { useHeading } from './heading-context';
4
5
  // https://atlassian.design/foundations/typography
5
6
  var levelMap = {
6
7
  xxlarge: 'h1',
@@ -47,19 +48,17 @@ var Heading = function Heading(_ref) {
47
48
  if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production' && as && typeof as !== 'string') {
48
49
  throw new Error('`as` prop should be a string.');
49
50
  }
50
- var hLevel = useHeadingElement();
51
- /**
52
- * Order here is important, we for now apply
53
- * 1. user choice
54
- * 2. inferred a11y level
55
- * 3. default final fallback
56
- */
57
- var Markup = as || hLevel && (hLevel > 6 ? 'div' : "h".concat(hLevel)) || levelMap[variant];
51
+ var _useHeading = useHeading(levelMap[variant]),
52
+ _useHeading2 = _slicedToArray(_useHeading, 2),
53
+ hLevel = _useHeading2[0],
54
+ inferredElement = _useHeading2[1];
55
+ var Markup = as || inferredElement;
56
+ var needsAriaRole = Markup === 'div' && hLevel;
58
57
  return jsx(Markup, {
59
58
  id: id,
60
59
  "data-testid": testId,
61
- role: Markup === 'div' ? 'heading' : undefined,
62
- "aria-level": Markup === 'div' ? hLevel : undefined,
60
+ role: needsAriaRole ? 'heading' : undefined,
61
+ "aria-level": needsAriaRole ? hLevel : undefined,
63
62
  css: [headingResetStyles, variant && headingVariantStylesMap[variant], color === 'inverse' && inverseStyles]
64
63
  }, children);
65
64
  };
@@ -1,15 +1,20 @@
1
1
  import { ReactNode } from 'react';
2
- type HeadingElement = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
2
+ type HeadingLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
3
+ type HeadingElement = `h${1 | 2 | 3 | 4 | 5 | 6}` | 'div';
3
4
  /**
4
5
  * @internal
5
6
  * @returns The current heading level context.
6
7
  */
7
- export declare const useHeadingElement: () => HeadingElement;
8
+ export declare const useHeadingLevel: () => HeadingLevel;
9
+ /**
10
+ * Infers the correct heading markup based on the current heading level context.
11
+ */
12
+ export declare const useHeading: (fallback: HeadingElement) => readonly [HeadingLevel, HeadingElement];
8
13
  export interface HeadingLevelContextProps {
9
14
  /**
10
15
  * Optional - only apply this value if the intent is to reset the heading context outside the normal content flow, for example inside a `section`.
11
16
  */
12
- value?: HeadingElement;
17
+ value?: HeadingLevel;
13
18
  /**
14
19
  * Semantic heirarchy of content below the heading context.
15
20
  */
@@ -1,15 +1,23 @@
1
1
  import { ReactNode } from 'react';
2
- type HeadingElement = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
2
+ type HeadingLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
3
+ type HeadingElement = `h${1 | 2 | 3 | 4 | 5 | 6}` | 'div';
3
4
  /**
4
5
  * @internal
5
6
  * @returns The current heading level context.
6
7
  */
7
- export declare const useHeadingElement: () => HeadingElement;
8
+ export declare const useHeadingLevel: () => HeadingLevel;
9
+ /**
10
+ * Infers the correct heading markup based on the current heading level context.
11
+ */
12
+ export declare const useHeading: (fallback: HeadingElement) => readonly [
13
+ HeadingLevel,
14
+ HeadingElement
15
+ ];
8
16
  export interface HeadingLevelContextProps {
9
17
  /**
10
18
  * Optional - only apply this value if the intent is to reset the heading context outside the normal content flow, for example inside a `section`.
11
19
  */
12
- value?: HeadingElement;
20
+ value?: HeadingLevel;
13
21
  /**
14
22
  * Semantic heirarchy of content below the heading context.
15
23
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/heading",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "description": "A heading is a typography component used to display text in different sizes and formats.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
package/report.api.md CHANGED
@@ -30,12 +30,12 @@ export const HeadingContextProvider: ({
30
30
  }: HeadingLevelContextProps) => JSX.Element;
31
31
 
32
32
  // @public (undocumented)
33
- type HeadingElement = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
33
+ type HeadingLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
34
34
 
35
35
  // @public (undocumented)
36
36
  interface HeadingLevelContextProps {
37
37
  children: ReactNode;
38
- value?: HeadingElement;
38
+ value?: HeadingLevel;
39
39
  }
40
40
 
41
41
  // @public (undocumented)
@@ -16,12 +16,12 @@ export default _default;
16
16
  export const HeadingContextProvider: ({ children, value, }: HeadingLevelContextProps) => JSX.Element;
17
17
 
18
18
  // @public (undocumented)
19
- type HeadingElement = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
19
+ type HeadingLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
20
20
 
21
21
  // @public (undocumented)
22
22
  interface HeadingLevelContextProps {
23
23
  children: ReactNode;
24
- value?: HeadingElement;
24
+ value?: HeadingLevel;
25
25
  }
26
26
 
27
27
  // @public (undocumented)