@sproutsocial/seeds-react-numeral 1.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.
package/.eslintignore ADDED
@@ -0,0 +1,6 @@
1
+ # Node modules
2
+ node_modules/
3
+
4
+ # Build output
5
+ dist/
6
+ coverage/
package/.eslintrc.js ADDED
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: ["eslint-config-seeds/racine"],
4
+ };
@@ -0,0 +1,21 @@
1
+ yarn run v1.22.22
2
+ $ tsup --dts
3
+ CLI Building entry: src/index.ts
4
+ CLI Using tsconfig: tsconfig.json
5
+ CLI tsup v8.0.2
6
+ CLI Using tsup config: /home/runner/work/seeds/seeds/seeds-react/seeds-react-numeral/tsup.config.ts
7
+ CLI Target: es2022
8
+ CLI Cleaning output folder
9
+ CJS Build start
10
+ ESM Build start
11
+ CJS dist/index.js 6.55 KB
12
+ CJS dist/index.js.map 9.75 KB
13
+ CJS ⚡️ Build success in 78ms
14
+ ESM dist/esm/index.js 4.45 KB
15
+ ESM dist/esm/index.js.map 9.64 KB
16
+ ESM ⚡️ Build success in 77ms
17
+ DTS Build start
18
+ DTS ⚡️ Build success in 7488ms
19
+ DTS dist/index.d.ts 1.29 KB
20
+ DTS dist/index.d.mts 1.29 KB
21
+ Done in 9.98s.
package/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # @sproutsocial/seeds-react-numeral
2
+
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 4a52cff: Migrate Numeral and Tooltip components to their own seeds-react component
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [4a52cff]
12
+ - @sproutsocial/seeds-react-tooltip@1.0.0
@@ -0,0 +1,154 @@
1
+ // src/Numeral.tsx
2
+ import "react";
3
+ import memoize from "lru-memoize";
4
+
5
+ // src/constants.ts
6
+ var DEFAULT_THRESHOLD = 1e4;
7
+ var MEMO_CACHE_SIZE = 10;
8
+ var COMPARE_OBJECTS = true;
9
+ var MAX_PRECISION = 20;
10
+ var ABBREV_PRECISION = 2;
11
+ var DefaultPrecisions = {
12
+ decimal: [0, 2],
13
+ percent: [0, 1],
14
+ currency: [2, 2]
15
+ };
16
+ var EM_DASH = "\u2014";
17
+
18
+ // src/Numeral.tsx
19
+ import Tooltip from "@sproutsocial/seeds-react-tooltip";
20
+ import { VisuallyHidden } from "@sproutsocial/seeds-react-visually-hidden";
21
+
22
+ // src/styles.ts
23
+ import styled from "styled-components";
24
+ import Text from "@sproutsocial/seeds-react-text";
25
+ var Container = styled(Text)`
26
+ font-variant-numeric: tabular-nums;
27
+ `;
28
+ var AbbrContainer = styled(Text)`
29
+ font-variant-numeric: tabular-nums;
30
+ border-bottom: 1px dotted
31
+ ${(props) => props.theme.colors.container.border.base};
32
+ `;
33
+
34
+ // src/Numeral.tsx
35
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
36
+ var _getNumberFormatters = (options) => {
37
+ const { locale, format, currency, min, max } = options;
38
+ const compactPrecision = min === max ? min : ABBREV_PRECISION;
39
+ const _currency = format === "currency" ? currency : void 0;
40
+ const standard = {
41
+ style: format,
42
+ minimumFractionDigits: min,
43
+ maximumFractionDigits: max,
44
+ currency: _currency
45
+ };
46
+ const compact = {
47
+ style: format,
48
+ minimumFractionDigits: compactPrecision,
49
+ maximumFractionDigits: compactPrecision,
50
+ currency: _currency,
51
+ notation: "compact"
52
+ };
53
+ let abbreviated;
54
+ try {
55
+ abbreviated = new Intl.NumberFormat(locale, compact);
56
+ } catch (error) {
57
+ abbreviated = new Intl.NumberFormat(locale, standard);
58
+ }
59
+ return {
60
+ standard: new Intl.NumberFormat(locale, standard),
61
+ abbreviated
62
+ };
63
+ };
64
+ var memoizer = memoize(MEMO_CACHE_SIZE, COMPARE_OBJECTS);
65
+ var getNumberFormatters = memoizer(_getNumberFormatters);
66
+ var getThreshold = (abbreviate) => {
67
+ if (typeof abbreviate === "number")
68
+ return Math.max(1e3, Math.abs(abbreviate));
69
+ if (abbreviate)
70
+ return DEFAULT_THRESHOLD;
71
+ return Infinity;
72
+ };
73
+ var getMinMaxPrecision = (precision, format) => {
74
+ if (typeof precision === "number")
75
+ return [precision, precision];
76
+ if (precision === "none")
77
+ return [0, MAX_PRECISION];
78
+ return DefaultPrecisions[format];
79
+ };
80
+ var isValidNumber = (value) => {
81
+ return typeof value === "number" && isFinite(value);
82
+ };
83
+ var normalizeArgs = (props) => {
84
+ const {
85
+ number,
86
+ locale = "us-EN",
87
+ format = props.currency ? "currency" : "decimal",
88
+ currency = "USD",
89
+ abbreviate = true,
90
+ invalidNumberLabel,
91
+ precision,
92
+ qa,
93
+ ...rest
94
+ } = props;
95
+ const threshold = getThreshold(abbreviate);
96
+ const [min, max] = getMinMaxPrecision(precision, format);
97
+ const _number = number || 0;
98
+ const value = _number * (format === "percent" ? 0.01 : 1);
99
+ const canAbbreviate = Math.abs(_number) >= threshold;
100
+ const options = {
101
+ locale,
102
+ format,
103
+ currency,
104
+ min,
105
+ max
106
+ };
107
+ return {
108
+ value,
109
+ canAbbreviate,
110
+ invalidNumberLabel,
111
+ options,
112
+ qa,
113
+ rest
114
+ };
115
+ };
116
+ var getNumeral = ({
117
+ returnType,
118
+ props
119
+ }) => {
120
+ const isReturnTypeString = returnType === "string";
121
+ const { value, canAbbreviate, invalidNumberLabel, options, qa, rest } = normalizeArgs(props);
122
+ if (!isValidNumber(props.number)) {
123
+ return isReturnTypeString ? EM_DASH : /* @__PURE__ */ jsxs(Fragment, { children: [
124
+ invalidNumberLabel && // Give screen readers something useful to read off + hide the em dash
125
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: invalidNumberLabel }),
126
+ /* @__PURE__ */ jsx(Container, { "aria-hidden": true, ...qa, children: EM_DASH })
127
+ ] });
128
+ }
129
+ const formatters = getNumberFormatters(options);
130
+ const fullText = formatters.standard.format(value);
131
+ if (canAbbreviate) {
132
+ const abbreviatedText = formatters.abbreviated.format(value);
133
+ if (abbreviatedText !== fullText) {
134
+ return isReturnTypeString ? abbreviatedText : /* @__PURE__ */ jsx(Tooltip, { content: fullText, children: /* @__PURE__ */ jsx(AbbrContainer, { ...qa, ...rest, children: abbreviatedText }) });
135
+ }
136
+ }
137
+ return isReturnTypeString ? fullText : /* @__PURE__ */ jsx(Container, { ...qa, ...rest, children: fullText });
138
+ };
139
+ var formatNumeral = (props) => {
140
+ return getNumeral({ returnType: "string", props });
141
+ };
142
+ var Numeral = (props) => {
143
+ return getNumeral({ returnType: "component", props });
144
+ };
145
+ var Numeral_default = Numeral;
146
+
147
+ // src/index.ts
148
+ var src_default = Numeral_default;
149
+ export {
150
+ Numeral_default as Numeral,
151
+ src_default as default,
152
+ formatNumeral
153
+ };
154
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/Numeral.tsx","../../src/constants.ts","../../src/styles.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\n// @ts-expect-error lru-memoize is not typed\nimport memoize from \"lru-memoize\";\nimport { EM_DASH } from \"./constants\";\nimport Tooltip from \"@sproutsocial/seeds-react-tooltip\";\nimport type { TypeTextProps } from \"@sproutsocial/seeds-react-text\";\nimport { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\n\nimport {\n DEFAULT_THRESHOLD,\n MEMO_CACHE_SIZE,\n COMPARE_OBJECTS,\n MAX_PRECISION,\n ABBREV_PRECISION,\n DefaultPrecisions,\n} from \"./constants\";\nimport { AbbrContainer, Container } from \"./styles\";\nimport type { EnumNumeralFormat, TypeNumeralProps } from \"./NumeralTypes\";\n\ninterface TypeFormatOptions {\n locale: string;\n format: EnumNumeralFormat;\n currency: string;\n min: number;\n max: number;\n}\n\ninterface TypeFormatters {\n standard: Intl.NumberFormat;\n abbreviated: Intl.NumberFormat;\n}\n\ninterface TypeArgs {\n value: number;\n canAbbreviate: boolean;\n invalidNumberLabel?: string;\n ariaLabel?: string;\n options: TypeFormatOptions;\n qa: object | null | undefined;\n rest: Omit<TypeTextProps, \"children\">;\n}\n\nconst _getNumberFormatters = (options: TypeFormatOptions): TypeFormatters => {\n const { locale, format, currency, min, max } = options;\n const compactPrecision = min === max ? min : ABBREV_PRECISION;\n\n const _currency = format === \"currency\" ? currency : undefined;\n\n const standard: Intl.NumberFormatOptions = {\n style: format,\n minimumFractionDigits: min,\n maximumFractionDigits: max,\n currency: _currency,\n };\n const compact: Intl.NumberFormatOptions = {\n style: format,\n minimumFractionDigits: compactPrecision,\n maximumFractionDigits: compactPrecision,\n currency: _currency,\n notation: \"compact\",\n };\n // Safari 14.1 is currently throwing errors when trying to use the compact\n // options of NumberFormat\n // https://community.atlassian.com/t5/Trello-questions/Trello-stuck-at-loading-after-Safari-14-1-update-on-macOS-Mojave/qaq-p/1675577#M45687\n let abbreviated;\n\n try {\n abbreviated = new Intl.NumberFormat(locale, compact);\n } catch (error) {\n abbreviated = new Intl.NumberFormat(locale, standard);\n }\n\n return {\n standard: new Intl.NumberFormat(locale, standard),\n abbreviated,\n };\n};\n\n// Memoize to reduce the energy of creating new instances of Intl.NumberFormat\nconst memoizer = memoize(MEMO_CACHE_SIZE, COMPARE_OBJECTS);\nconst getNumberFormatters = memoizer(_getNumberFormatters);\n\nconst getThreshold = (abbreviate: boolean | number): number => {\n if (typeof abbreviate === \"number\")\n return Math.max(1000, Math.abs(abbreviate));\n if (abbreviate) return DEFAULT_THRESHOLD;\n return Infinity;\n};\n\nconst getMinMaxPrecision = (\n precision: TypeNumeralProps[\"precision\"],\n format: EnumNumeralFormat\n): [number, number] => {\n if (typeof precision === \"number\") return [precision, precision];\n if (precision === \"none\") return [0, MAX_PRECISION];\n return DefaultPrecisions[format];\n};\n\nconst isValidNumber = (value: unknown): boolean => {\n return typeof value === \"number\" && isFinite(value);\n};\n\nconst normalizeArgs = (props: TypeNumeralProps): TypeArgs => {\n const {\n number,\n locale = \"us-EN\",\n format = props.currency ? \"currency\" : \"decimal\",\n currency = \"USD\",\n abbreviate = true,\n invalidNumberLabel,\n precision,\n qa,\n ...rest\n } = props;\n const threshold = getThreshold(abbreviate);\n const [min, max] = getMinMaxPrecision(precision, format);\n\n const _number = number || 0;\n\n const value = _number * (format === \"percent\" ? 0.01 : 1);\n const canAbbreviate = Math.abs(_number) >= threshold;\n const options = {\n locale,\n format,\n currency,\n min,\n max,\n };\n\n return {\n value,\n canAbbreviate,\n invalidNumberLabel,\n options,\n qa,\n rest,\n };\n};\n\nconst getNumeral = ({\n returnType,\n props,\n}: {\n returnType: \"string\" | \"component\";\n props: TypeNumeralProps;\n}): string | React.ReactNode => {\n const isReturnTypeString = returnType === \"string\";\n const { value, canAbbreviate, invalidNumberLabel, options, qa, rest } =\n normalizeArgs(props);\n\n if (!isValidNumber(props.number)) {\n return isReturnTypeString ? (\n EM_DASH\n ) : (\n <>\n {invalidNumberLabel && (\n // Give screen readers something useful to read off + hide the em dash\n <VisuallyHidden>{invalidNumberLabel}</VisuallyHidden>\n )}\n <Container aria-hidden {...qa}>\n {EM_DASH}\n </Container>\n </>\n );\n }\n\n const formatters = getNumberFormatters(options);\n const fullText = formatters.standard.format(value);\n\n if (canAbbreviate) {\n const abbreviatedText = formatters.abbreviated.format(value);\n\n // The following are used to debug the skipped tests which are misbehaving!!!\n // console.log({ fullText, abbreviatedText });\n // console.log({ abbreviated: formatters.abbreviated.resolvedOptions() });\n // The following check is necessary because each locale may have differing thresholds\n // for which abbreviation begins.\n if (abbreviatedText !== fullText) {\n return isReturnTypeString ? (\n abbreviatedText\n ) : (\n <Tooltip content={fullText}>\n <AbbrContainer {...qa} {...rest}>\n {abbreviatedText}\n </AbbrContainer>\n </Tooltip>\n );\n }\n }\n\n return isReturnTypeString ? (\n fullText\n ) : (\n <Container {...qa} {...rest}>\n {fullText}\n </Container>\n );\n};\n\nexport const formatNumeral = (props: TypeNumeralProps): string => {\n return getNumeral({ returnType: \"string\", props }) as string;\n};\n\nconst Numeral = (props: TypeNumeralProps) => {\n return getNumeral({ returnType: \"component\", props });\n};\n\nexport default Numeral;\n","import type { EnumNumeralFormat } from \"./NumeralTypes\";\n\nexport const DEFAULT_THRESHOLD = 10000;\nexport const MEMO_CACHE_SIZE = 10;\nexport const COMPARE_OBJECTS = true;\nexport const MAX_PRECISION = 20;\nexport const ABBREV_PRECISION = 2;\nexport const DefaultPrecisions: {\n [key in EnumNumeralFormat]: [number, number];\n} = {\n decimal: [0, 2],\n percent: [0, 1],\n currency: [2, 2],\n};\n\nexport const EM_DASH = \"—\"; // shift + option + hyphen on a mac keyboard\n","import styled from \"styled-components\";\nimport Text from \"@sproutsocial/seeds-react-text\";\n\nexport const Container = styled(Text)`\n font-variant-numeric: tabular-nums;\n`;\n\nexport const AbbrContainer = styled(Text)`\n font-variant-numeric: tabular-nums;\n border-bottom: 1px dotted\n ${(props) => props.theme.colors.container.border.base};\n`;\n","import Numeral, { formatNumeral } from \"./Numeral\";\n\nexport default Numeral;\nexport { Numeral };\nexport { formatNumeral };\nexport * from \"./NumeralTypes\";\n"],"mappings":"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","names":[]}
@@ -0,0 +1,25 @@
1
+ import * as React from 'react';
2
+ import { TypeTextProps } from '@sproutsocial/seeds-react-text';
3
+
4
+ type EnumNumeralFormat = "decimal" | "currency" | "percent";
5
+ interface TypeNumeralProps extends Omit<TypeTextProps, "children"> {
6
+ /** The number to be formatted */
7
+ number?: number | null | undefined;
8
+ /** Locale to format. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument */
9
+ locale?: string;
10
+ format?: EnumNumeralFormat;
11
+ /** The currency format to use when formatting currency */
12
+ currency?: string;
13
+ /** A boolean determining whether or not the number should be abbreviated, or a number representing the abbreviation threshold */
14
+ abbreviate?: boolean | number;
15
+ /** Text to be read off by screen readers for invalid values (i.e., any value rendered as '—' (em dash)) */
16
+ invalidNumberLabel?: string;
17
+ /** Override the default decimal precision (2 for decimals/currency, 1 for percentages), or "none" allowing unrestricted precision. */
18
+ precision?: number | "none";
19
+ qa?: object;
20
+ }
21
+
22
+ declare const formatNumeral: (props: TypeNumeralProps) => string;
23
+ declare const Numeral: (props: TypeNumeralProps) => React.ReactNode;
24
+
25
+ export { type EnumNumeralFormat, Numeral, type TypeNumeralProps, Numeral as default, formatNumeral };
@@ -0,0 +1,25 @@
1
+ import * as React from 'react';
2
+ import { TypeTextProps } from '@sproutsocial/seeds-react-text';
3
+
4
+ type EnumNumeralFormat = "decimal" | "currency" | "percent";
5
+ interface TypeNumeralProps extends Omit<TypeTextProps, "children"> {
6
+ /** The number to be formatted */
7
+ number?: number | null | undefined;
8
+ /** Locale to format. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument */
9
+ locale?: string;
10
+ format?: EnumNumeralFormat;
11
+ /** The currency format to use when formatting currency */
12
+ currency?: string;
13
+ /** A boolean determining whether or not the number should be abbreviated, or a number representing the abbreviation threshold */
14
+ abbreviate?: boolean | number;
15
+ /** Text to be read off by screen readers for invalid values (i.e., any value rendered as '—' (em dash)) */
16
+ invalidNumberLabel?: string;
17
+ /** Override the default decimal precision (2 for decimals/currency, 1 for percentages), or "none" allowing unrestricted precision. */
18
+ precision?: number | "none";
19
+ qa?: object;
20
+ }
21
+
22
+ declare const formatNumeral: (props: TypeNumeralProps) => string;
23
+ declare const Numeral: (props: TypeNumeralProps) => React.ReactNode;
24
+
25
+ export { type EnumNumeralFormat, Numeral, type TypeNumeralProps, Numeral as default, formatNumeral };
package/dist/index.js ADDED
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ Numeral: () => Numeral_default,
34
+ default: () => src_default,
35
+ formatNumeral: () => formatNumeral
36
+ });
37
+ module.exports = __toCommonJS(src_exports);
38
+
39
+ // src/Numeral.tsx
40
+ var React = require("react");
41
+ var import_lru_memoize = __toESM(require("lru-memoize"));
42
+
43
+ // src/constants.ts
44
+ var DEFAULT_THRESHOLD = 1e4;
45
+ var MEMO_CACHE_SIZE = 10;
46
+ var COMPARE_OBJECTS = true;
47
+ var MAX_PRECISION = 20;
48
+ var ABBREV_PRECISION = 2;
49
+ var DefaultPrecisions = {
50
+ decimal: [0, 2],
51
+ percent: [0, 1],
52
+ currency: [2, 2]
53
+ };
54
+ var EM_DASH = "\u2014";
55
+
56
+ // src/Numeral.tsx
57
+ var import_seeds_react_tooltip = __toESM(require("@sproutsocial/seeds-react-tooltip"));
58
+ var import_seeds_react_visually_hidden = require("@sproutsocial/seeds-react-visually-hidden");
59
+
60
+ // src/styles.ts
61
+ var import_styled_components = __toESM(require("styled-components"));
62
+ var import_seeds_react_text = __toESM(require("@sproutsocial/seeds-react-text"));
63
+ var Container = (0, import_styled_components.default)(import_seeds_react_text.default)`
64
+ font-variant-numeric: tabular-nums;
65
+ `;
66
+ var AbbrContainer = (0, import_styled_components.default)(import_seeds_react_text.default)`
67
+ font-variant-numeric: tabular-nums;
68
+ border-bottom: 1px dotted
69
+ ${(props) => props.theme.colors.container.border.base};
70
+ `;
71
+
72
+ // src/Numeral.tsx
73
+ var import_jsx_runtime = require("react/jsx-runtime");
74
+ var _getNumberFormatters = (options) => {
75
+ const { locale, format, currency, min, max } = options;
76
+ const compactPrecision = min === max ? min : ABBREV_PRECISION;
77
+ const _currency = format === "currency" ? currency : void 0;
78
+ const standard = {
79
+ style: format,
80
+ minimumFractionDigits: min,
81
+ maximumFractionDigits: max,
82
+ currency: _currency
83
+ };
84
+ const compact = {
85
+ style: format,
86
+ minimumFractionDigits: compactPrecision,
87
+ maximumFractionDigits: compactPrecision,
88
+ currency: _currency,
89
+ notation: "compact"
90
+ };
91
+ let abbreviated;
92
+ try {
93
+ abbreviated = new Intl.NumberFormat(locale, compact);
94
+ } catch (error) {
95
+ abbreviated = new Intl.NumberFormat(locale, standard);
96
+ }
97
+ return {
98
+ standard: new Intl.NumberFormat(locale, standard),
99
+ abbreviated
100
+ };
101
+ };
102
+ var memoizer = (0, import_lru_memoize.default)(MEMO_CACHE_SIZE, COMPARE_OBJECTS);
103
+ var getNumberFormatters = memoizer(_getNumberFormatters);
104
+ var getThreshold = (abbreviate) => {
105
+ if (typeof abbreviate === "number")
106
+ return Math.max(1e3, Math.abs(abbreviate));
107
+ if (abbreviate)
108
+ return DEFAULT_THRESHOLD;
109
+ return Infinity;
110
+ };
111
+ var getMinMaxPrecision = (precision, format) => {
112
+ if (typeof precision === "number")
113
+ return [precision, precision];
114
+ if (precision === "none")
115
+ return [0, MAX_PRECISION];
116
+ return DefaultPrecisions[format];
117
+ };
118
+ var isValidNumber = (value) => {
119
+ return typeof value === "number" && isFinite(value);
120
+ };
121
+ var normalizeArgs = (props) => {
122
+ const {
123
+ number,
124
+ locale = "us-EN",
125
+ format = props.currency ? "currency" : "decimal",
126
+ currency = "USD",
127
+ abbreviate = true,
128
+ invalidNumberLabel,
129
+ precision,
130
+ qa,
131
+ ...rest
132
+ } = props;
133
+ const threshold = getThreshold(abbreviate);
134
+ const [min, max] = getMinMaxPrecision(precision, format);
135
+ const _number = number || 0;
136
+ const value = _number * (format === "percent" ? 0.01 : 1);
137
+ const canAbbreviate = Math.abs(_number) >= threshold;
138
+ const options = {
139
+ locale,
140
+ format,
141
+ currency,
142
+ min,
143
+ max
144
+ };
145
+ return {
146
+ value,
147
+ canAbbreviate,
148
+ invalidNumberLabel,
149
+ options,
150
+ qa,
151
+ rest
152
+ };
153
+ };
154
+ var getNumeral = ({
155
+ returnType,
156
+ props
157
+ }) => {
158
+ const isReturnTypeString = returnType === "string";
159
+ const { value, canAbbreviate, invalidNumberLabel, options, qa, rest } = normalizeArgs(props);
160
+ if (!isValidNumber(props.number)) {
161
+ return isReturnTypeString ? EM_DASH : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
162
+ invalidNumberLabel && // Give screen readers something useful to read off + hide the em dash
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_visually_hidden.VisuallyHidden, { children: invalidNumberLabel }),
164
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, { "aria-hidden": true, ...qa, children: EM_DASH })
165
+ ] });
166
+ }
167
+ const formatters = getNumberFormatters(options);
168
+ const fullText = formatters.standard.format(value);
169
+ if (canAbbreviate) {
170
+ const abbreviatedText = formatters.abbreviated.format(value);
171
+ if (abbreviatedText !== fullText) {
172
+ return isReturnTypeString ? abbreviatedText : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_tooltip.default, { content: fullText, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AbbrContainer, { ...qa, ...rest, children: abbreviatedText }) });
173
+ }
174
+ }
175
+ return isReturnTypeString ? fullText : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, { ...qa, ...rest, children: fullText });
176
+ };
177
+ var formatNumeral = (props) => {
178
+ return getNumeral({ returnType: "string", props });
179
+ };
180
+ var Numeral = (props) => {
181
+ return getNumeral({ returnType: "component", props });
182
+ };
183
+ var Numeral_default = Numeral;
184
+
185
+ // src/index.ts
186
+ var src_default = Numeral_default;
187
+ // Annotate the CommonJS export names for ESM import in node:
188
+ 0 && (module.exports = {
189
+ Numeral,
190
+ formatNumeral
191
+ });
192
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/Numeral.tsx","../src/constants.ts","../src/styles.ts"],"sourcesContent":["import Numeral, { formatNumeral } from \"./Numeral\";\n\nexport default Numeral;\nexport { Numeral };\nexport { formatNumeral };\nexport * from \"./NumeralTypes\";\n","import * as React from \"react\";\n// @ts-expect-error lru-memoize is not typed\nimport memoize from \"lru-memoize\";\nimport { EM_DASH } from \"./constants\";\nimport Tooltip from \"@sproutsocial/seeds-react-tooltip\";\nimport type { TypeTextProps } from \"@sproutsocial/seeds-react-text\";\nimport { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\n\nimport {\n DEFAULT_THRESHOLD,\n MEMO_CACHE_SIZE,\n COMPARE_OBJECTS,\n MAX_PRECISION,\n ABBREV_PRECISION,\n DefaultPrecisions,\n} from \"./constants\";\nimport { AbbrContainer, Container } from \"./styles\";\nimport type { EnumNumeralFormat, TypeNumeralProps } from \"./NumeralTypes\";\n\ninterface TypeFormatOptions {\n locale: string;\n format: EnumNumeralFormat;\n currency: string;\n min: number;\n max: number;\n}\n\ninterface TypeFormatters {\n standard: Intl.NumberFormat;\n abbreviated: Intl.NumberFormat;\n}\n\ninterface TypeArgs {\n value: number;\n canAbbreviate: boolean;\n invalidNumberLabel?: string;\n ariaLabel?: string;\n options: TypeFormatOptions;\n qa: object | null | undefined;\n rest: Omit<TypeTextProps, \"children\">;\n}\n\nconst _getNumberFormatters = (options: TypeFormatOptions): TypeFormatters => {\n const { locale, format, currency, min, max } = options;\n const compactPrecision = min === max ? min : ABBREV_PRECISION;\n\n const _currency = format === \"currency\" ? currency : undefined;\n\n const standard: Intl.NumberFormatOptions = {\n style: format,\n minimumFractionDigits: min,\n maximumFractionDigits: max,\n currency: _currency,\n };\n const compact: Intl.NumberFormatOptions = {\n style: format,\n minimumFractionDigits: compactPrecision,\n maximumFractionDigits: compactPrecision,\n currency: _currency,\n notation: \"compact\",\n };\n // Safari 14.1 is currently throwing errors when trying to use the compact\n // options of NumberFormat\n // https://community.atlassian.com/t5/Trello-questions/Trello-stuck-at-loading-after-Safari-14-1-update-on-macOS-Mojave/qaq-p/1675577#M45687\n let abbreviated;\n\n try {\n abbreviated = new Intl.NumberFormat(locale, compact);\n } catch (error) {\n abbreviated = new Intl.NumberFormat(locale, standard);\n }\n\n return {\n standard: new Intl.NumberFormat(locale, standard),\n abbreviated,\n };\n};\n\n// Memoize to reduce the energy of creating new instances of Intl.NumberFormat\nconst memoizer = memoize(MEMO_CACHE_SIZE, COMPARE_OBJECTS);\nconst getNumberFormatters = memoizer(_getNumberFormatters);\n\nconst getThreshold = (abbreviate: boolean | number): number => {\n if (typeof abbreviate === \"number\")\n return Math.max(1000, Math.abs(abbreviate));\n if (abbreviate) return DEFAULT_THRESHOLD;\n return Infinity;\n};\n\nconst getMinMaxPrecision = (\n precision: TypeNumeralProps[\"precision\"],\n format: EnumNumeralFormat\n): [number, number] => {\n if (typeof precision === \"number\") return [precision, precision];\n if (precision === \"none\") return [0, MAX_PRECISION];\n return DefaultPrecisions[format];\n};\n\nconst isValidNumber = (value: unknown): boolean => {\n return typeof value === \"number\" && isFinite(value);\n};\n\nconst normalizeArgs = (props: TypeNumeralProps): TypeArgs => {\n const {\n number,\n locale = \"us-EN\",\n format = props.currency ? \"currency\" : \"decimal\",\n currency = \"USD\",\n abbreviate = true,\n invalidNumberLabel,\n precision,\n qa,\n ...rest\n } = props;\n const threshold = getThreshold(abbreviate);\n const [min, max] = getMinMaxPrecision(precision, format);\n\n const _number = number || 0;\n\n const value = _number * (format === \"percent\" ? 0.01 : 1);\n const canAbbreviate = Math.abs(_number) >= threshold;\n const options = {\n locale,\n format,\n currency,\n min,\n max,\n };\n\n return {\n value,\n canAbbreviate,\n invalidNumberLabel,\n options,\n qa,\n rest,\n };\n};\n\nconst getNumeral = ({\n returnType,\n props,\n}: {\n returnType: \"string\" | \"component\";\n props: TypeNumeralProps;\n}): string | React.ReactNode => {\n const isReturnTypeString = returnType === \"string\";\n const { value, canAbbreviate, invalidNumberLabel, options, qa, rest } =\n normalizeArgs(props);\n\n if (!isValidNumber(props.number)) {\n return isReturnTypeString ? (\n EM_DASH\n ) : (\n <>\n {invalidNumberLabel && (\n // Give screen readers something useful to read off + hide the em dash\n <VisuallyHidden>{invalidNumberLabel}</VisuallyHidden>\n )}\n <Container aria-hidden {...qa}>\n {EM_DASH}\n </Container>\n </>\n );\n }\n\n const formatters = getNumberFormatters(options);\n const fullText = formatters.standard.format(value);\n\n if (canAbbreviate) {\n const abbreviatedText = formatters.abbreviated.format(value);\n\n // The following are used to debug the skipped tests which are misbehaving!!!\n // console.log({ fullText, abbreviatedText });\n // console.log({ abbreviated: formatters.abbreviated.resolvedOptions() });\n // The following check is necessary because each locale may have differing thresholds\n // for which abbreviation begins.\n if (abbreviatedText !== fullText) {\n return isReturnTypeString ? (\n abbreviatedText\n ) : (\n <Tooltip content={fullText}>\n <AbbrContainer {...qa} {...rest}>\n {abbreviatedText}\n </AbbrContainer>\n </Tooltip>\n );\n }\n }\n\n return isReturnTypeString ? (\n fullText\n ) : (\n <Container {...qa} {...rest}>\n {fullText}\n </Container>\n );\n};\n\nexport const formatNumeral = (props: TypeNumeralProps): string => {\n return getNumeral({ returnType: \"string\", props }) as string;\n};\n\nconst Numeral = (props: TypeNumeralProps) => {\n return getNumeral({ returnType: \"component\", props });\n};\n\nexport default Numeral;\n","import type { EnumNumeralFormat } from \"./NumeralTypes\";\n\nexport const DEFAULT_THRESHOLD = 10000;\nexport const MEMO_CACHE_SIZE = 10;\nexport const COMPARE_OBJECTS = true;\nexport const MAX_PRECISION = 20;\nexport const ABBREV_PRECISION = 2;\nexport const DefaultPrecisions: {\n [key in EnumNumeralFormat]: [number, number];\n} = {\n decimal: [0, 2],\n percent: [0, 1],\n currency: [2, 2],\n};\n\nexport const EM_DASH = \"—\"; // shift + option + hyphen on a mac keyboard\n","import styled from \"styled-components\";\nimport Text from \"@sproutsocial/seeds-react-text\";\n\nexport const Container = styled(Text)`\n font-variant-numeric: tabular-nums;\n`;\n\nexport const AbbrContainer = styled(Text)`\n font-variant-numeric: tabular-nums;\n border-bottom: 1px dotted\n ${(props) => props.theme.colors.container.border.base};\n`;\n"],"mappings":"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","names":["styled","Text","memoize","Tooltip"]}
package/jest.config.js ADDED
@@ -0,0 +1,13 @@
1
+ const baseConfig = require("@sproutsocial/seeds-testing");
2
+
3
+ /** * @type {import('jest').Config} */
4
+ const config = {
5
+ ...baseConfig,
6
+ displayName: "seeds-react-numeral",
7
+ testPathIgnorePatterns: [
8
+ ...baseConfig.testPathIgnorePatterns,
9
+ "testNumeral.tsx",
10
+ ],
11
+ };
12
+
13
+ module.exports = config;
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@sproutsocial/seeds-react-numeral",
3
+ "version": "1.0.0",
4
+ "description": "Seeds React Numeral",
5
+ "author": "Sprout Social, Inc.",
6
+ "license": "MIT",
7
+ "main": "dist/index.js",
8
+ "module": "dist/esm/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "scripts": {
11
+ "build": "tsup --dts",
12
+ "build:debug": "tsup --dts --metafile",
13
+ "dev": "tsup --watch --dts",
14
+ "clean": "rm -rf .turbo dist",
15
+ "clean:modules": "rm -rf node_modules",
16
+ "typecheck": "tsc --noEmit",
17
+ "test": "jest",
18
+ "test:watch": "jest --watch --coverage=false"
19
+ },
20
+ "dependencies": {
21
+ "@sproutsocial/seeds-react-theme": "*",
22
+ "@sproutsocial/seeds-react-system-props": "*",
23
+ "@sproutsocial/seeds-react-tooltip": "*",
24
+ "@sproutsocial/seeds-react-text": "*",
25
+ "@sproutsocial/seeds-react-visually-hidden": "*",
26
+ "lru-memoize": "~1.0.2"
27
+ },
28
+ "devDependencies": {
29
+ "@types/react": "^18.0.0",
30
+ "@types/styled-components": "^5.1.26",
31
+ "@sproutsocial/eslint-config-seeds": "*",
32
+ "react": "^18.0.0",
33
+ "styled-components": "^5.2.3",
34
+ "tsup": "^8.0.2",
35
+ "typescript": "^5.6.2",
36
+ "@sproutsocial/seeds-tsconfig": "*",
37
+ "@sproutsocial/seeds-testing": "*",
38
+ "@sproutsocial/seeds-react-testing-library": "*"
39
+ },
40
+ "peerDependencies": {
41
+ "styled-components": "^5.2.3"
42
+ },
43
+ "engines": {
44
+ "node": ">=18"
45
+ }
46
+ }