@sproutsocial/seeds-react-duration 1.0.31 → 1.0.34

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.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Seeds Duration component classes
3
+ * Use these instead of writing out individual Tailwind utility classes.
4
+ *
5
+ * Requires @sproutsocial/seeds-react-theme/dist/theme-all.css imported for
6
+ * CSS variable definitions and dark mode support (consistent with other Seeds
7
+ * components). font-variant-numeric has no design token, so this rule uses none.
8
+ *
9
+ * Usage:
10
+ * <span class="seeds-duration">1m 30s</span>
11
+ */
12
+
13
+ @layer components {
14
+ .seeds-duration {
15
+ font-variant-numeric: tabular-nums;
16
+ }
17
+ }
package/dist/esm/index.js CHANGED
@@ -41,6 +41,9 @@ var EM_DASH = "\u2014";
41
41
  // src/Duration.tsx
42
42
  import { VisuallyHidden } from "@sproutsocial/seeds-react-visually-hidden";
43
43
 
44
+ // src/DurationHybrid.tsx
45
+ import React2 from "react";
46
+
44
47
  // src/styles.ts
45
48
  import styled from "styled-components";
46
49
  import Text from "@sproutsocial/seeds-react-text";
@@ -48,6 +51,42 @@ var Container = styled(Text)`
48
51
  font-variant-numeric: tabular-nums;
49
52
  `;
50
53
 
54
+ // src/DurationTailwind.tsx
55
+ import React from "react";
56
+ import Text2 from "@sproutsocial/seeds-react-text";
57
+ import { jsx } from "react/jsx-runtime";
58
+ function cn(...inputs) {
59
+ const classes = [];
60
+ for (const input of inputs) {
61
+ if (!input) continue;
62
+ if (typeof input === "string") {
63
+ classes.push(input);
64
+ } else if (typeof input === "object") {
65
+ for (const [key, value] of Object.entries(input)) {
66
+ if (value) {
67
+ classes.push(key);
68
+ }
69
+ }
70
+ }
71
+ }
72
+ return classes.join(" ");
73
+ }
74
+ var DurationTailwind = React.forwardRef(({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx(Text2, { className: cn("seeds-duration", className), ...rest, ref, children }));
75
+ DurationTailwind.displayName = "DurationTailwind";
76
+
77
+ // src/DurationHybrid.tsx
78
+ import { hasStyledProps } from "@sproutsocial/seeds-react-system-props";
79
+ import { jsx as jsx2 } from "react/jsx-runtime";
80
+ var DurationHybrid = React2.forwardRef(
81
+ (props, ref) => {
82
+ if (hasStyledProps(props)) {
83
+ return /* @__PURE__ */ jsx2(Container, { ref, ...props });
84
+ }
85
+ return /* @__PURE__ */ jsx2(DurationTailwind, { ref, ...props });
86
+ }
87
+ );
88
+ DurationHybrid.displayName = "DurationHybrid";
89
+
51
90
  // src/utils.ts
52
91
  var getLowestUnit = (displayUnits) => [...ORDERED_UNITS].reverse().find((unit) => displayUnits[unit]) || UNITS.milliseconds;
53
92
  var splitMillisecondsIntoUnits = (milliseconds, displayUnits) => {
@@ -93,7 +132,7 @@ var getDurationMaxDisplayUnits = ({
93
132
  };
94
133
 
95
134
  // src/Duration.tsx
96
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
135
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
97
136
  var _createDurationFormatter = (locale, unitDisplay, displayUnits) => {
98
137
  const timeUnitFormatter = (locale2, unit, unitDisplay2) => Intl.NumberFormat(locale2, { style: "unit", unit, unitDisplay: unitDisplay2 }).format;
99
138
  const formatterByUnit = {
@@ -137,16 +176,17 @@ var getDuration = ({
137
176
  invalidMillisecondsLabel,
138
177
  locale = DEFAULT_LOCALE,
139
178
  milliseconds = DEFAULT_MILLISECONDS,
140
- qa
179
+ qa,
180
+ ...rest
141
181
  } = props;
142
182
  const isReturnTypeString = returnType === "string";
143
183
  if (!isValidNumber(milliseconds)) {
144
184
  return isReturnTypeString ? EM_DASH : /* @__PURE__ */ jsxs(Fragment, { children: [
145
185
  invalidMillisecondsLabel ? (
146
186
  // Give screen readers something useful to read off + hide the em dash
147
- /* @__PURE__ */ jsx(VisuallyHidden, { children: invalidMillisecondsLabel })
187
+ /* @__PURE__ */ jsx3(VisuallyHidden, { children: invalidMillisecondsLabel })
148
188
  ) : null,
149
- /* @__PURE__ */ jsx(Container, { "aria-hidden": true, ...qa, children: EM_DASH })
189
+ /* @__PURE__ */ jsx3(DurationHybrid, { ...rest, "aria-hidden": true, ...qa, children: EM_DASH })
150
190
  ] });
151
191
  }
152
192
  const validatedDisplayUnits = Object.keys(displayUnits).length === 0 ? DEFAULT_DISPLAY_UNITS : displayUnits;
@@ -155,7 +195,7 @@ var getDuration = ({
155
195
  display,
156
196
  validatedDisplayUnits
157
197
  )(milliseconds);
158
- return isReturnTypeString ? fullText : /* @__PURE__ */ jsx(Container, { ...qa, children: fullText });
198
+ return isReturnTypeString ? fullText : /* @__PURE__ */ jsx3(DurationHybrid, { ...rest, ...qa, children: fullText });
159
199
  };
160
200
  var formatDuration = (props) => {
161
201
  return getDuration({ returnType: "string", props });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Duration.tsx","../../src/constants.ts","../../src/styles.ts","../../src/utils.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 { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\n\nimport {\n COMPARE_OBJECTS,\n DEFAULT_DISPLAY,\n DEFAULT_DISPLAY_UNITS,\n DEFAULT_LOCALE,\n DEFAULT_MILLISECONDS,\n MEMO_CACHE_SIZE,\n ORDERED_UNITS,\n UNITS,\n} from \"./constants\";\nimport { Container } from \"./styles\";\nimport type {\n TypeDurationProps,\n TypeDurationLocale,\n TypeDurationDisplay,\n TypeDurationDisplayUnits,\n} from \"./DurationTypes\";\nimport {\n isValidNumber,\n getLowestUnit,\n splitMillisecondsIntoUnits,\n} from \"./utils\";\n\nconst _createDurationFormatter = (\n locale: TypeDurationLocale,\n unitDisplay: TypeDurationDisplay,\n displayUnits: TypeDurationDisplayUnits\n) => {\n const timeUnitFormatter = (\n locale: TypeDurationProps[\"locale\"],\n unit: string,\n unitDisplay: TypeDurationProps[\"display\"]\n ) => Intl.NumberFormat(locale, { style: \"unit\", unit, unitDisplay }).format;\n\n const formatterByUnit = {\n [UNITS.days]: timeUnitFormatter(locale, \"day\", unitDisplay),\n [UNITS.hours]: timeUnitFormatter(locale, \"hour\", unitDisplay),\n [UNITS.minutes]: timeUnitFormatter(locale, \"minute\", unitDisplay),\n [UNITS.seconds]: timeUnitFormatter(locale, \"second\", unitDisplay),\n [UNITS.milliseconds]: timeUnitFormatter(locale, \"millisecond\", unitDisplay),\n };\n\n const formatList = new Intl.ListFormat(locale, {\n style: \"narrow\",\n type: \"unit\",\n });\n\n return (value: number) => {\n const lowestUnit = getLowestUnit(displayUnits);\n\n // if the value is zero or negative, we just want to return 0 for the lowest unit (ex \"0 minutes\")\n if (value <= 0) {\n // @ts-ignore TS error later\n return formatterByUnit[lowestUnit](0);\n }\n\n const millisecondsByUnit = splitMillisecondsIntoUnits(value, displayUnits);\n const list: string[] = [];\n\n ORDERED_UNITS.forEach((unit) => {\n if (unit in millisecondsByUnit) {\n // @ts-ignore TS error later\n const unitValue = millisecondsByUnit[unit];\n\n // we want to add to the list if one of two conditions are met:\n // 1) the unit has a value greater than 0 OR\n // 2) the unit has value 0 AND the unit is the lowest unit AND the list is already empty\n if (\n unitValue !== 0 ||\n (unitValue === 0 && unit === lowestUnit && list.length === 0)\n ) {\n // @ts-ignore TS error later\n list.push(formatterByUnit[unit](millisecondsByUnit[unit]));\n }\n }\n });\n\n return formatList.format(list);\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 createDurationFormatter = memoizer(_createDurationFormatter);\n\nconst getDuration = ({\n returnType,\n props,\n}: {\n returnType: \"string\" | \"component\";\n props: TypeDurationProps;\n}): string | React.ReactNode => {\n const {\n display = DEFAULT_DISPLAY,\n displayUnits = DEFAULT_DISPLAY_UNITS,\n invalidMillisecondsLabel,\n locale = DEFAULT_LOCALE,\n milliseconds = DEFAULT_MILLISECONDS,\n qa,\n } = props;\n const isReturnTypeString = returnType === \"string\";\n\n if (!isValidNumber(milliseconds)) {\n return isReturnTypeString ? (\n EM_DASH\n ) : (\n <>\n {invalidMillisecondsLabel ? (\n // Give screen readers something useful to read off + hide the em dash\n <VisuallyHidden>{invalidMillisecondsLabel}</VisuallyHidden>\n ) : null}\n <Container aria-hidden {...qa}>\n {EM_DASH}\n </Container>\n </>\n );\n }\n\n const validatedDisplayUnits =\n Object.keys(displayUnits).length === 0\n ? DEFAULT_DISPLAY_UNITS\n : displayUnits;\n\n const fullText = createDurationFormatter(\n locale,\n display,\n validatedDisplayUnits\n )(milliseconds);\n\n return isReturnTypeString ? (\n fullText\n ) : (\n <Container {...qa}>{fullText}</Container>\n );\n};\n\nexport const formatDuration = (props: TypeDurationProps): string => {\n return getDuration({ returnType: \"string\", props }) as string;\n};\n\nconst Duration = (props: TypeDurationProps) => {\n return getDuration({ returnType: \"component\", props });\n};\n\nexport default Duration;\n","export const COMPARE_OBJECTS = true;\nexport const MEMO_CACHE_SIZE = 10;\n\nexport const UNITS = {\n days: \"days\",\n hours: \"hours\",\n minutes: \"minutes\",\n seconds: \"seconds\",\n milliseconds: \"milliseconds\",\n};\n\nexport const MILLISECONDS_IN = {\n [UNITS.days]: 1 * 1000 * 60 * 60 * 24,\n [UNITS.hours]: 1 * 1000 * 60 * 60,\n [UNITS.minutes]: 1 * 1000 * 60,\n [UNITS.seconds]: 1 * 1000,\n [UNITS.milliseconds]: 1,\n};\n\nexport const ORDERED_UNITS = [\n UNITS.days,\n UNITS.hours,\n UNITS.minutes,\n UNITS.seconds,\n UNITS.milliseconds,\n];\n\n// Duration props defaults\nexport const DEFAULT_DISPLAY = \"narrow\";\nexport const DEFAULT_DISPLAY_UNITS = {\n [UNITS.days]: true,\n [UNITS.hours]: true,\n [UNITS.minutes]: true,\n [UNITS.seconds]: true,\n [UNITS.milliseconds]: false,\n};\n\nexport const DEFAULT_LOCALE = \"en-US\";\nexport const DEFAULT_MILLISECONDS = null;\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","import type {\n TypeDurationDisplayUnits,\n TypeDurationMilliseconds,\n} from \"./DurationTypes\";\nimport { MILLISECONDS_IN, ORDERED_UNITS, UNITS } from \"./constants\";\n\nexport const getLowestUnit = (displayUnits: TypeDurationDisplayUnits) =>\n [...ORDERED_UNITS]\n .reverse()\n .find((unit) => displayUnits[unit as keyof TypeDurationDisplayUnits]) ||\n UNITS.milliseconds;\n\nexport const splitMillisecondsIntoUnits = (\n milliseconds: number,\n displayUnits: TypeDurationDisplayUnits\n): {\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n milliseconds?: number;\n} => {\n const lowestUnit = getLowestUnit(displayUnits);\n\n // @ts-ignore TS error later\n const remainder = milliseconds % MILLISECONDS_IN[lowestUnit];\n // @ts-ignore TS error later\n if (2 * remainder >= MILLISECONDS_IN[lowestUnit]) {\n // if the remainder is large, add enough seconds to increse the lowest unit\n // @ts-ignore TS error later\n milliseconds += MILLISECONDS_IN[lowestUnit] - remainder;\n }\n\n const units = {};\n\n ORDERED_UNITS.forEach((unit) => {\n // @ts-ignore TS error later\n if (displayUnits[unit]) {\n // @ts-ignore TS error later\n units[unit] = Math.floor(milliseconds / MILLISECONDS_IN[unit]);\n // @ts-ignore TS error later\n milliseconds -= units[unit] * MILLISECONDS_IN[unit];\n }\n });\n\n return units;\n};\n\nexport const isValidNumber = (value: unknown): boolean =>\n typeof value === \"number\" && isFinite(value);\n\nexport interface TypeGetDurationMaxDisplayUnitsProps {\n milliseconds: TypeDurationMilliseconds;\n maxDisplayUnits: number;\n}\n\nexport const getDurationMaxDisplayUnits = ({\n milliseconds,\n maxDisplayUnits = ORDERED_UNITS.length,\n}: TypeGetDurationMaxDisplayUnitsProps): TypeDurationDisplayUnits => {\n const displayUnits = {};\n\n if (!isValidNumber(milliseconds)) {\n return displayUnits;\n }\n\n for (const unit of ORDERED_UNITS) {\n if (Object.keys(displayUnits).length >= maxDisplayUnits) {\n break;\n }\n\n // @ts-expect-error - stupid typescript isn't smart enough to check the isValidNumber check above ¯\\_(ツ)_/¯\n const millisecondsByUnit = splitMillisecondsIntoUnits(milliseconds, {\n days: true,\n hours: true,\n minutes: true,\n seconds: true,\n milliseconds: true,\n });\n\n // @ts-expect-error - stupid typescript isn't smart enough to check the isValidNumber check above ¯\\_(ツ)_/¯\n if (milliseconds > MILLISECONDS_IN[unit] && millisecondsByUnit[unit] > 0) {\n // @ts-ignore TS error later\n displayUnits[unit] = true;\n }\n }\n\n return displayUnits;\n};\n","import Duration, { formatDuration } from \"./Duration\";\nimport {\n getDurationMaxDisplayUnits,\n type TypeGetDurationMaxDisplayUnitsProps,\n} from \"./utils\";\n\nexport default Duration;\nexport { Duration };\nexport { formatDuration };\nexport { getDurationMaxDisplayUnits };\nexport type { TypeGetDurationMaxDisplayUnitsProps };\nexport * from \"./DurationTypes\";\n"],"mappings":"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","names":["locale","unitDisplay"]}
1
+ {"version":3,"sources":["../../src/Duration.tsx","../../src/constants.ts","../../src/DurationHybrid.tsx","../../src/styles.ts","../../src/DurationTailwind.tsx","../../src/utils.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 { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\n\nimport {\n COMPARE_OBJECTS,\n DEFAULT_DISPLAY,\n DEFAULT_DISPLAY_UNITS,\n DEFAULT_LOCALE,\n DEFAULT_MILLISECONDS,\n MEMO_CACHE_SIZE,\n ORDERED_UNITS,\n UNITS,\n} from \"./constants\";\nimport { DurationHybrid } from \"./DurationHybrid\";\nimport type {\n TypeDurationProps,\n TypeDurationLocale,\n TypeDurationDisplay,\n TypeDurationDisplayUnits,\n} from \"./DurationTypes\";\nimport {\n isValidNumber,\n getLowestUnit,\n splitMillisecondsIntoUnits,\n} from \"./utils\";\n\nconst _createDurationFormatter = (\n locale: TypeDurationLocale,\n unitDisplay: TypeDurationDisplay,\n displayUnits: TypeDurationDisplayUnits\n) => {\n const timeUnitFormatter = (\n locale: TypeDurationProps[\"locale\"],\n unit: string,\n unitDisplay: TypeDurationProps[\"display\"]\n ) => Intl.NumberFormat(locale, { style: \"unit\", unit, unitDisplay }).format;\n\n const formatterByUnit = {\n [UNITS.days]: timeUnitFormatter(locale, \"day\", unitDisplay),\n [UNITS.hours]: timeUnitFormatter(locale, \"hour\", unitDisplay),\n [UNITS.minutes]: timeUnitFormatter(locale, \"minute\", unitDisplay),\n [UNITS.seconds]: timeUnitFormatter(locale, \"second\", unitDisplay),\n [UNITS.milliseconds]: timeUnitFormatter(locale, \"millisecond\", unitDisplay),\n };\n\n const formatList = new Intl.ListFormat(locale, {\n style: \"narrow\",\n type: \"unit\",\n });\n\n return (value: number) => {\n const lowestUnit = getLowestUnit(displayUnits);\n\n // if the value is zero or negative, we just want to return 0 for the lowest unit (ex \"0 minutes\")\n if (value <= 0) {\n // @ts-ignore TS error later\n return formatterByUnit[lowestUnit](0);\n }\n\n const millisecondsByUnit = splitMillisecondsIntoUnits(value, displayUnits);\n const list: string[] = [];\n\n ORDERED_UNITS.forEach((unit) => {\n if (unit in millisecondsByUnit) {\n // @ts-ignore TS error later\n const unitValue = millisecondsByUnit[unit];\n\n // we want to add to the list if one of two conditions are met:\n // 1) the unit has a value greater than 0 OR\n // 2) the unit has value 0 AND the unit is the lowest unit AND the list is already empty\n if (\n unitValue !== 0 ||\n (unitValue === 0 && unit === lowestUnit && list.length === 0)\n ) {\n // @ts-ignore TS error later\n list.push(formatterByUnit[unit](millisecondsByUnit[unit]));\n }\n }\n });\n\n return formatList.format(list);\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 createDurationFormatter = memoizer(_createDurationFormatter);\n\nconst getDuration = ({\n returnType,\n props,\n}: {\n returnType: \"string\" | \"component\";\n props: TypeDurationProps;\n}): string | React.ReactNode => {\n const {\n display = DEFAULT_DISPLAY,\n displayUnits = DEFAULT_DISPLAY_UNITS,\n invalidMillisecondsLabel,\n locale = DEFAULT_LOCALE,\n milliseconds = DEFAULT_MILLISECONDS,\n qa,\n ...rest\n } = props;\n const isReturnTypeString = returnType === \"string\";\n\n if (!isValidNumber(milliseconds)) {\n return isReturnTypeString ? (\n EM_DASH\n ) : (\n <>\n {invalidMillisecondsLabel ? (\n // Give screen readers something useful to read off + hide the em dash\n <VisuallyHidden>{invalidMillisecondsLabel}</VisuallyHidden>\n ) : null}\n <DurationHybrid {...rest} aria-hidden {...qa}>\n {EM_DASH}\n </DurationHybrid>\n </>\n );\n }\n\n const validatedDisplayUnits =\n Object.keys(displayUnits).length === 0\n ? DEFAULT_DISPLAY_UNITS\n : displayUnits;\n\n const fullText = createDurationFormatter(\n locale,\n display,\n validatedDisplayUnits\n )(milliseconds);\n\n return isReturnTypeString ? (\n fullText\n ) : (\n <DurationHybrid {...rest} {...qa}>\n {fullText}\n </DurationHybrid>\n );\n};\n\nexport const formatDuration = (props: TypeDurationProps): string => {\n return getDuration({ returnType: \"string\", props }) as string;\n};\n\nconst Duration = (props: TypeDurationProps) => {\n return getDuration({ returnType: \"component\", props });\n};\n\nexport default Duration;\n","export const COMPARE_OBJECTS = true;\nexport const MEMO_CACHE_SIZE = 10;\n\nexport const UNITS = {\n days: \"days\",\n hours: \"hours\",\n minutes: \"minutes\",\n seconds: \"seconds\",\n milliseconds: \"milliseconds\",\n};\n\nexport const MILLISECONDS_IN = {\n [UNITS.days]: 1 * 1000 * 60 * 60 * 24,\n [UNITS.hours]: 1 * 1000 * 60 * 60,\n [UNITS.minutes]: 1 * 1000 * 60,\n [UNITS.seconds]: 1 * 1000,\n [UNITS.milliseconds]: 1,\n};\n\nexport const ORDERED_UNITS = [\n UNITS.days,\n UNITS.hours,\n UNITS.minutes,\n UNITS.seconds,\n UNITS.milliseconds,\n];\n\n// Duration props defaults\nexport const DEFAULT_DISPLAY = \"narrow\";\nexport const DEFAULT_DISPLAY_UNITS = {\n [UNITS.days]: true,\n [UNITS.hours]: true,\n [UNITS.minutes]: true,\n [UNITS.seconds]: true,\n [UNITS.milliseconds]: false,\n};\n\nexport const DEFAULT_LOCALE = \"en-US\";\nexport const DEFAULT_MILLISECONDS = null;\n\nexport const EM_DASH = \"—\"; // shift + option + hyphen on a mac keyboard\n","/**\n * Hybrid Duration Component\n * Automatically chooses between Tailwind and styled-components based on props\n */\n\nimport React from \"react\";\nimport type { TypeTextProps } from \"@sproutsocial/seeds-react-text\";\nimport { Container } from \"./styles\"; // Styled-components version (named export)\nimport { DurationTailwind } from \"./DurationTailwind\"; // Tailwind version\nimport { hasStyledProps } from \"@sproutsocial/seeds-react-system-props\";\n\nexport const DurationHybrid = React.forwardRef<HTMLSpanElement, TypeTextProps>(\n (props, ref) => {\n // styled-system props (e.g. color, fontSize) must render through the\n // styled-components Container so those styles apply. Everything else uses the\n // Tailwind path — a styled(Duration) extension still works there because\n // styled() forwards its generated className onto the rendered element.\n if (hasStyledProps(props)) {\n return <Container ref={ref} {...props} />;\n }\n\n // Use Tailwind version (preferred - better performance)\n return <DurationTailwind ref={ref} {...props} />;\n }\n);\n\nDurationHybrid.displayName = \"DurationHybrid\";\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","/**\n * Tailwind CSS implementation of Duration component\n * Uses the Seeds duration CSS class from duration.css\n */\n\nimport React from \"react\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport type { TypeTextProps } from \"@sproutsocial/seeds-react-text\";\n\n// Utility for merging class names properly\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\nexport const DurationTailwind = React.forwardRef<\n HTMLSpanElement,\n TypeTextProps\n>(({ className, children, ...rest }, ref) => (\n <Text className={cn(\"seeds-duration\", className)} {...rest} ref={ref}>\n {children}\n </Text>\n));\n\nDurationTailwind.displayName = \"DurationTailwind\";\n","import type {\n TypeDurationDisplayUnits,\n TypeDurationMilliseconds,\n} from \"./DurationTypes\";\nimport { MILLISECONDS_IN, ORDERED_UNITS, UNITS } from \"./constants\";\n\nexport const getLowestUnit = (displayUnits: TypeDurationDisplayUnits) =>\n [...ORDERED_UNITS]\n .reverse()\n .find((unit) => displayUnits[unit as keyof TypeDurationDisplayUnits]) ||\n UNITS.milliseconds;\n\nexport const splitMillisecondsIntoUnits = (\n milliseconds: number,\n displayUnits: TypeDurationDisplayUnits\n): {\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n milliseconds?: number;\n} => {\n const lowestUnit = getLowestUnit(displayUnits);\n\n // @ts-ignore TS error later\n const remainder = milliseconds % MILLISECONDS_IN[lowestUnit];\n // @ts-ignore TS error later\n if (2 * remainder >= MILLISECONDS_IN[lowestUnit]) {\n // if the remainder is large, add enough seconds to increse the lowest unit\n // @ts-ignore TS error later\n milliseconds += MILLISECONDS_IN[lowestUnit] - remainder;\n }\n\n const units = {};\n\n ORDERED_UNITS.forEach((unit) => {\n // @ts-ignore TS error later\n if (displayUnits[unit]) {\n // @ts-ignore TS error later\n units[unit] = Math.floor(milliseconds / MILLISECONDS_IN[unit]);\n // @ts-ignore TS error later\n milliseconds -= units[unit] * MILLISECONDS_IN[unit];\n }\n });\n\n return units;\n};\n\nexport const isValidNumber = (value: unknown): boolean =>\n typeof value === \"number\" && isFinite(value);\n\nexport interface TypeGetDurationMaxDisplayUnitsProps {\n milliseconds: TypeDurationMilliseconds;\n maxDisplayUnits: number;\n}\n\nexport const getDurationMaxDisplayUnits = ({\n milliseconds,\n maxDisplayUnits = ORDERED_UNITS.length,\n}: TypeGetDurationMaxDisplayUnitsProps): TypeDurationDisplayUnits => {\n const displayUnits = {};\n\n if (!isValidNumber(milliseconds)) {\n return displayUnits;\n }\n\n for (const unit of ORDERED_UNITS) {\n if (Object.keys(displayUnits).length >= maxDisplayUnits) {\n break;\n }\n\n // @ts-expect-error - stupid typescript isn't smart enough to check the isValidNumber check above ¯\\_(ツ)_/¯\n const millisecondsByUnit = splitMillisecondsIntoUnits(milliseconds, {\n days: true,\n hours: true,\n minutes: true,\n seconds: true,\n milliseconds: true,\n });\n\n // @ts-expect-error - stupid typescript isn't smart enough to check the isValidNumber check above ¯\\_(ツ)_/¯\n if (milliseconds > MILLISECONDS_IN[unit] && millisecondsByUnit[unit] > 0) {\n // @ts-ignore TS error later\n displayUnits[unit] = true;\n }\n }\n\n return displayUnits;\n};\n","import Duration, { formatDuration } from \"./Duration\";\nimport {\n getDurationMaxDisplayUnits,\n type TypeGetDurationMaxDisplayUnitsProps,\n} from \"./utils\";\n\nexport default Duration;\nexport { Duration };\nexport { formatDuration };\nexport { getDurationMaxDisplayUnits };\nexport type { TypeGetDurationMaxDisplayUnitsProps };\nexport * from \"./DurationTypes\";\n"],"mappings":";AAAA,OAAuB;AAEvB,OAAO,aAAa;;;ACFb,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AAExB,IAAM,QAAQ;AAAA,EACnB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,cAAc;AAChB;AAEO,IAAM,kBAAkB;AAAA,EAC7B,CAAC,MAAM,IAAI,GAAG,IAAI,MAAO,KAAK,KAAK;AAAA,EACnC,CAAC,MAAM,KAAK,GAAG,IAAI,MAAO,KAAK;AAAA,EAC/B,CAAC,MAAM,OAAO,GAAG,IAAI,MAAO;AAAA,EAC5B,CAAC,MAAM,OAAO,GAAG,IAAI;AAAA,EACrB,CAAC,MAAM,YAAY,GAAG;AACxB;AAEO,IAAM,gBAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAGO,IAAM,kBAAkB;AACxB,IAAM,wBAAwB;AAAA,EACnC,CAAC,MAAM,IAAI,GAAG;AAAA,EACd,CAAC,MAAM,KAAK,GAAG;AAAA,EACf,CAAC,MAAM,OAAO,GAAG;AAAA,EACjB,CAAC,MAAM,OAAO,GAAG;AAAA,EACjB,CAAC,MAAM,YAAY,GAAG;AACxB;AAEO,IAAM,iBAAiB;AACvB,IAAM,uBAAuB;AAE7B,IAAM,UAAU;;;ADpCvB,SAAS,sBAAsB;;;AEC/B,OAAOA,YAAW;;;ACLlB,OAAO,YAAY;AACnB,OAAO,UAAU;AAEV,IAAM,YAAY,OAAO,IAAI;AAAA;AAAA;;;ACEpC,OAAO,WAAW;AAClB,OAAOC,WAAU;AA8Bf;AA1BF,SAAS,MACJ,QACK;AACR,QAAM,UAAoB,CAAC;AAE3B,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,MAAO;AAEZ,QAAI,OAAO,UAAU,UAAU;AAC7B,cAAQ,KAAK,KAAK;AAAA,IACpB,WAAW,OAAO,UAAU,UAAU;AACpC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,YAAI,OAAO;AACT,kBAAQ,KAAK,GAAG;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ,KAAK,GAAG;AACzB;AAEO,IAAM,mBAAmB,MAAM,WAGpC,CAAC,EAAE,WAAW,UAAU,GAAG,KAAK,GAAG,QACnC,oBAACA,OAAA,EAAK,WAAW,GAAG,kBAAkB,SAAS,GAAI,GAAG,MAAM,KACzD,UACH,CACD;AAED,iBAAiB,cAAc;;;AFhC/B,SAAS,sBAAsB;AASlB,gBAAAC,YAAA;AAPN,IAAM,iBAAiBC,OAAM;AAAA,EAClC,CAAC,OAAO,QAAQ;AAKd,QAAI,eAAe,KAAK,GAAG;AACzB,aAAO,gBAAAD,KAAC,aAAU,KAAW,GAAG,OAAO;AAAA,IACzC;AAGA,WAAO,gBAAAA,KAAC,oBAAiB,KAAW,GAAG,OAAO;AAAA,EAChD;AACF;AAEA,eAAe,cAAc;;;AGpBtB,IAAM,gBAAgB,CAAC,iBAC5B,CAAC,GAAG,aAAa,EACd,QAAQ,EACR,KAAK,CAAC,SAAS,aAAa,IAAsC,CAAC,KACtE,MAAM;AAED,IAAM,6BAA6B,CACxC,cACA,iBAOG;AACH,QAAM,aAAa,cAAc,YAAY;AAG7C,QAAM,YAAY,eAAe,gBAAgB,UAAU;AAE3D,MAAI,IAAI,aAAa,gBAAgB,UAAU,GAAG;AAGhD,oBAAgB,gBAAgB,UAAU,IAAI;AAAA,EAChD;AAEA,QAAM,QAAQ,CAAC;AAEf,gBAAc,QAAQ,CAAC,SAAS;AAE9B,QAAI,aAAa,IAAI,GAAG;AAEtB,YAAM,IAAI,IAAI,KAAK,MAAM,eAAe,gBAAgB,IAAI,CAAC;AAE7D,sBAAgB,MAAM,IAAI,IAAI,gBAAgB,IAAI;AAAA,IACpD;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEO,IAAM,gBAAgB,CAAC,UAC5B,OAAO,UAAU,YAAY,SAAS,KAAK;AAOtC,IAAM,6BAA6B,CAAC;AAAA,EACzC;AAAA,EACA,kBAAkB,cAAc;AAClC,MAAqE;AACnE,QAAM,eAAe,CAAC;AAEtB,MAAI,CAAC,cAAc,YAAY,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,aAAW,QAAQ,eAAe;AAChC,QAAI,OAAO,KAAK,YAAY,EAAE,UAAU,iBAAiB;AACvD;AAAA,IACF;AAGA,UAAM,qBAAqB,2BAA2B,cAAc;AAAA,MAClE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,SAAS;AAAA,MACT,cAAc;AAAA,IAChB,CAAC;AAGD,QAAI,eAAe,gBAAgB,IAAI,KAAK,mBAAmB,IAAI,IAAI,GAAG;AAExE,mBAAa,IAAI,IAAI;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;;;ALyBM,mBAGI,OAAAE,MAHJ;AApFN,IAAM,2BAA2B,CAC/B,QACA,aACA,iBACG;AACH,QAAM,oBAAoB,CACxBC,SACA,MACAC,iBACG,KAAK,aAAaD,SAAQ,EAAE,OAAO,QAAQ,MAAM,aAAAC,aAAY,CAAC,EAAE;AAErE,QAAM,kBAAkB;AAAA,IACtB,CAAC,MAAM,IAAI,GAAG,kBAAkB,QAAQ,OAAO,WAAW;AAAA,IAC1D,CAAC,MAAM,KAAK,GAAG,kBAAkB,QAAQ,QAAQ,WAAW;AAAA,IAC5D,CAAC,MAAM,OAAO,GAAG,kBAAkB,QAAQ,UAAU,WAAW;AAAA,IAChE,CAAC,MAAM,OAAO,GAAG,kBAAkB,QAAQ,UAAU,WAAW;AAAA,IAChE,CAAC,MAAM,YAAY,GAAG,kBAAkB,QAAQ,eAAe,WAAW;AAAA,EAC5E;AAEA,QAAM,aAAa,IAAI,KAAK,WAAW,QAAQ;AAAA,IAC7C,OAAO;AAAA,IACP,MAAM;AAAA,EACR,CAAC;AAED,SAAO,CAAC,UAAkB;AACxB,UAAM,aAAa,cAAc,YAAY;AAG7C,QAAI,SAAS,GAAG;AAEd,aAAO,gBAAgB,UAAU,EAAE,CAAC;AAAA,IACtC;AAEA,UAAM,qBAAqB,2BAA2B,OAAO,YAAY;AACzE,UAAM,OAAiB,CAAC;AAExB,kBAAc,QAAQ,CAAC,SAAS;AAC9B,UAAI,QAAQ,oBAAoB;AAE9B,cAAM,YAAY,mBAAmB,IAAI;AAKzC,YACE,cAAc,KACb,cAAc,KAAK,SAAS,cAAc,KAAK,WAAW,GAC3D;AAEA,eAAK,KAAK,gBAAgB,IAAI,EAAE,mBAAmB,IAAI,CAAC,CAAC;AAAA,QAC3D;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO,WAAW,OAAO,IAAI;AAAA,EAC/B;AACF;AAGA,IAAM,WAAW,QAAQ,iBAAiB,eAAe;AACzD,IAAM,0BAA0B,SAAS,wBAAwB;AAEjE,IAAM,cAAc,CAAC;AAAA,EACnB;AAAA,EACA;AACF,MAGgC;AAC9B,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,eAAe;AAAA,IACf;AAAA,IACA,SAAS;AAAA,IACT,eAAe;AAAA,IACf;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,qBAAqB,eAAe;AAE1C,MAAI,CAAC,cAAc,YAAY,GAAG;AAChC,WAAO,qBACL,UAEA,iCACG;AAAA;AAAA;AAAA,QAEC,gBAAAF,KAAC,kBAAgB,oCAAyB;AAAA,UACxC;AAAA,MACJ,gBAAAA,KAAC,kBAAgB,GAAG,MAAM,eAAW,MAAE,GAAG,IACvC,mBACH;AAAA,OACF;AAAA,EAEJ;AAEA,QAAM,wBACJ,OAAO,KAAK,YAAY,EAAE,WAAW,IACjC,wBACA;AAEN,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,YAAY;AAEd,SAAO,qBACL,WAEA,gBAAAA,KAAC,kBAAgB,GAAG,MAAO,GAAG,IAC3B,oBACH;AAEJ;AAEO,IAAM,iBAAiB,CAAC,UAAqC;AAClE,SAAO,YAAY,EAAE,YAAY,UAAU,MAAM,CAAC;AACpD;AAEA,IAAM,WAAW,CAAC,UAA6B;AAC7C,SAAO,YAAY,EAAE,YAAY,aAAa,MAAM,CAAC;AACvD;AAEA,IAAO,mBAAQ;;;AMnJf,IAAO,gBAAQ;","names":["React","Text","jsx","React","jsx","locale","unitDisplay"]}
package/dist/index.js CHANGED
@@ -38,7 +38,7 @@ __export(index_exports, {
38
38
  module.exports = __toCommonJS(index_exports);
39
39
 
40
40
  // src/Duration.tsx
41
- var React = require("react");
41
+ var React3 = require("react");
42
42
  var import_lru_memoize = __toESM(require("lru-memoize"));
43
43
 
44
44
  // src/constants.ts
@@ -80,6 +80,9 @@ var EM_DASH = "\u2014";
80
80
  // src/Duration.tsx
81
81
  var import_seeds_react_visually_hidden = require("@sproutsocial/seeds-react-visually-hidden");
82
82
 
83
+ // src/DurationHybrid.tsx
84
+ var import_react2 = __toESM(require("react"));
85
+
83
86
  // src/styles.ts
84
87
  var import_styled_components = __toESM(require("styled-components"));
85
88
  var import_seeds_react_text = __toESM(require("@sproutsocial/seeds-react-text"));
@@ -87,6 +90,42 @@ var Container = (0, import_styled_components.default)(import_seeds_react_text.de
87
90
  font-variant-numeric: tabular-nums;
88
91
  `;
89
92
 
93
+ // src/DurationTailwind.tsx
94
+ var import_react = __toESM(require("react"));
95
+ var import_seeds_react_text2 = __toESM(require("@sproutsocial/seeds-react-text"));
96
+ var import_jsx_runtime = require("react/jsx-runtime");
97
+ function cn(...inputs) {
98
+ const classes = [];
99
+ for (const input of inputs) {
100
+ if (!input) continue;
101
+ if (typeof input === "string") {
102
+ classes.push(input);
103
+ } else if (typeof input === "object") {
104
+ for (const [key, value] of Object.entries(input)) {
105
+ if (value) {
106
+ classes.push(key);
107
+ }
108
+ }
109
+ }
110
+ }
111
+ return classes.join(" ");
112
+ }
113
+ var DurationTailwind = import_react.default.forwardRef(({ className, children, ...rest }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_text2.default, { className: cn("seeds-duration", className), ...rest, ref, children }));
114
+ DurationTailwind.displayName = "DurationTailwind";
115
+
116
+ // src/DurationHybrid.tsx
117
+ var import_seeds_react_system_props = require("@sproutsocial/seeds-react-system-props");
118
+ var import_jsx_runtime2 = require("react/jsx-runtime");
119
+ var DurationHybrid = import_react2.default.forwardRef(
120
+ (props, ref) => {
121
+ if ((0, import_seeds_react_system_props.hasStyledProps)(props)) {
122
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Container, { ref, ...props });
123
+ }
124
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DurationTailwind, { ref, ...props });
125
+ }
126
+ );
127
+ DurationHybrid.displayName = "DurationHybrid";
128
+
90
129
  // src/utils.ts
91
130
  var getLowestUnit = (displayUnits) => [...ORDERED_UNITS].reverse().find((unit) => displayUnits[unit]) || UNITS.milliseconds;
92
131
  var splitMillisecondsIntoUnits = (milliseconds, displayUnits) => {
@@ -132,7 +171,7 @@ var getDurationMaxDisplayUnits = ({
132
171
  };
133
172
 
134
173
  // src/Duration.tsx
135
- var import_jsx_runtime = require("react/jsx-runtime");
174
+ var import_jsx_runtime3 = require("react/jsx-runtime");
136
175
  var _createDurationFormatter = (locale, unitDisplay, displayUnits) => {
137
176
  const timeUnitFormatter = (locale2, unit, unitDisplay2) => Intl.NumberFormat(locale2, { style: "unit", unit, unitDisplay: unitDisplay2 }).format;
138
177
  const formatterByUnit = {
@@ -176,16 +215,17 @@ var getDuration = ({
176
215
  invalidMillisecondsLabel,
177
216
  locale = DEFAULT_LOCALE,
178
217
  milliseconds = DEFAULT_MILLISECONDS,
179
- qa
218
+ qa,
219
+ ...rest
180
220
  } = props;
181
221
  const isReturnTypeString = returnType === "string";
182
222
  if (!isValidNumber(milliseconds)) {
183
- return isReturnTypeString ? EM_DASH : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
223
+ return isReturnTypeString ? EM_DASH : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
184
224
  invalidMillisecondsLabel ? (
185
225
  // Give screen readers something useful to read off + hide the em dash
186
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_visually_hidden.VisuallyHidden, { children: invalidMillisecondsLabel })
226
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_visually_hidden.VisuallyHidden, { children: invalidMillisecondsLabel })
187
227
  ) : null,
188
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, { "aria-hidden": true, ...qa, children: EM_DASH })
228
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DurationHybrid, { ...rest, "aria-hidden": true, ...qa, children: EM_DASH })
189
229
  ] });
190
230
  }
191
231
  const validatedDisplayUnits = Object.keys(displayUnits).length === 0 ? DEFAULT_DISPLAY_UNITS : displayUnits;
@@ -194,7 +234,7 @@ var getDuration = ({
194
234
  display,
195
235
  validatedDisplayUnits
196
236
  )(milliseconds);
197
- return isReturnTypeString ? fullText : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, { ...qa, children: fullText });
237
+ return isReturnTypeString ? fullText : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DurationHybrid, { ...rest, ...qa, children: fullText });
198
238
  };
199
239
  var formatDuration = (props) => {
200
240
  return getDuration({ returnType: "string", props });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Duration.tsx","../src/constants.ts","../src/styles.ts","../src/utils.ts"],"sourcesContent":["import Duration, { formatDuration } from \"./Duration\";\nimport {\n getDurationMaxDisplayUnits,\n type TypeGetDurationMaxDisplayUnitsProps,\n} from \"./utils\";\n\nexport default Duration;\nexport { Duration };\nexport { formatDuration };\nexport { getDurationMaxDisplayUnits };\nexport type { TypeGetDurationMaxDisplayUnitsProps };\nexport * from \"./DurationTypes\";\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 { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\n\nimport {\n COMPARE_OBJECTS,\n DEFAULT_DISPLAY,\n DEFAULT_DISPLAY_UNITS,\n DEFAULT_LOCALE,\n DEFAULT_MILLISECONDS,\n MEMO_CACHE_SIZE,\n ORDERED_UNITS,\n UNITS,\n} from \"./constants\";\nimport { Container } from \"./styles\";\nimport type {\n TypeDurationProps,\n TypeDurationLocale,\n TypeDurationDisplay,\n TypeDurationDisplayUnits,\n} from \"./DurationTypes\";\nimport {\n isValidNumber,\n getLowestUnit,\n splitMillisecondsIntoUnits,\n} from \"./utils\";\n\nconst _createDurationFormatter = (\n locale: TypeDurationLocale,\n unitDisplay: TypeDurationDisplay,\n displayUnits: TypeDurationDisplayUnits\n) => {\n const timeUnitFormatter = (\n locale: TypeDurationProps[\"locale\"],\n unit: string,\n unitDisplay: TypeDurationProps[\"display\"]\n ) => Intl.NumberFormat(locale, { style: \"unit\", unit, unitDisplay }).format;\n\n const formatterByUnit = {\n [UNITS.days]: timeUnitFormatter(locale, \"day\", unitDisplay),\n [UNITS.hours]: timeUnitFormatter(locale, \"hour\", unitDisplay),\n [UNITS.minutes]: timeUnitFormatter(locale, \"minute\", unitDisplay),\n [UNITS.seconds]: timeUnitFormatter(locale, \"second\", unitDisplay),\n [UNITS.milliseconds]: timeUnitFormatter(locale, \"millisecond\", unitDisplay),\n };\n\n const formatList = new Intl.ListFormat(locale, {\n style: \"narrow\",\n type: \"unit\",\n });\n\n return (value: number) => {\n const lowestUnit = getLowestUnit(displayUnits);\n\n // if the value is zero or negative, we just want to return 0 for the lowest unit (ex \"0 minutes\")\n if (value <= 0) {\n // @ts-ignore TS error later\n return formatterByUnit[lowestUnit](0);\n }\n\n const millisecondsByUnit = splitMillisecondsIntoUnits(value, displayUnits);\n const list: string[] = [];\n\n ORDERED_UNITS.forEach((unit) => {\n if (unit in millisecondsByUnit) {\n // @ts-ignore TS error later\n const unitValue = millisecondsByUnit[unit];\n\n // we want to add to the list if one of two conditions are met:\n // 1) the unit has a value greater than 0 OR\n // 2) the unit has value 0 AND the unit is the lowest unit AND the list is already empty\n if (\n unitValue !== 0 ||\n (unitValue === 0 && unit === lowestUnit && list.length === 0)\n ) {\n // @ts-ignore TS error later\n list.push(formatterByUnit[unit](millisecondsByUnit[unit]));\n }\n }\n });\n\n return formatList.format(list);\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 createDurationFormatter = memoizer(_createDurationFormatter);\n\nconst getDuration = ({\n returnType,\n props,\n}: {\n returnType: \"string\" | \"component\";\n props: TypeDurationProps;\n}): string | React.ReactNode => {\n const {\n display = DEFAULT_DISPLAY,\n displayUnits = DEFAULT_DISPLAY_UNITS,\n invalidMillisecondsLabel,\n locale = DEFAULT_LOCALE,\n milliseconds = DEFAULT_MILLISECONDS,\n qa,\n } = props;\n const isReturnTypeString = returnType === \"string\";\n\n if (!isValidNumber(milliseconds)) {\n return isReturnTypeString ? (\n EM_DASH\n ) : (\n <>\n {invalidMillisecondsLabel ? (\n // Give screen readers something useful to read off + hide the em dash\n <VisuallyHidden>{invalidMillisecondsLabel}</VisuallyHidden>\n ) : null}\n <Container aria-hidden {...qa}>\n {EM_DASH}\n </Container>\n </>\n );\n }\n\n const validatedDisplayUnits =\n Object.keys(displayUnits).length === 0\n ? DEFAULT_DISPLAY_UNITS\n : displayUnits;\n\n const fullText = createDurationFormatter(\n locale,\n display,\n validatedDisplayUnits\n )(milliseconds);\n\n return isReturnTypeString ? (\n fullText\n ) : (\n <Container {...qa}>{fullText}</Container>\n );\n};\n\nexport const formatDuration = (props: TypeDurationProps): string => {\n return getDuration({ returnType: \"string\", props }) as string;\n};\n\nconst Duration = (props: TypeDurationProps) => {\n return getDuration({ returnType: \"component\", props });\n};\n\nexport default Duration;\n","export const COMPARE_OBJECTS = true;\nexport const MEMO_CACHE_SIZE = 10;\n\nexport const UNITS = {\n days: \"days\",\n hours: \"hours\",\n minutes: \"minutes\",\n seconds: \"seconds\",\n milliseconds: \"milliseconds\",\n};\n\nexport const MILLISECONDS_IN = {\n [UNITS.days]: 1 * 1000 * 60 * 60 * 24,\n [UNITS.hours]: 1 * 1000 * 60 * 60,\n [UNITS.minutes]: 1 * 1000 * 60,\n [UNITS.seconds]: 1 * 1000,\n [UNITS.milliseconds]: 1,\n};\n\nexport const ORDERED_UNITS = [\n UNITS.days,\n UNITS.hours,\n UNITS.minutes,\n UNITS.seconds,\n UNITS.milliseconds,\n];\n\n// Duration props defaults\nexport const DEFAULT_DISPLAY = \"narrow\";\nexport const DEFAULT_DISPLAY_UNITS = {\n [UNITS.days]: true,\n [UNITS.hours]: true,\n [UNITS.minutes]: true,\n [UNITS.seconds]: true,\n [UNITS.milliseconds]: false,\n};\n\nexport const DEFAULT_LOCALE = \"en-US\";\nexport const DEFAULT_MILLISECONDS = null;\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","import type {\n TypeDurationDisplayUnits,\n TypeDurationMilliseconds,\n} from \"./DurationTypes\";\nimport { MILLISECONDS_IN, ORDERED_UNITS, UNITS } from \"./constants\";\n\nexport const getLowestUnit = (displayUnits: TypeDurationDisplayUnits) =>\n [...ORDERED_UNITS]\n .reverse()\n .find((unit) => displayUnits[unit as keyof TypeDurationDisplayUnits]) ||\n UNITS.milliseconds;\n\nexport const splitMillisecondsIntoUnits = (\n milliseconds: number,\n displayUnits: TypeDurationDisplayUnits\n): {\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n milliseconds?: number;\n} => {\n const lowestUnit = getLowestUnit(displayUnits);\n\n // @ts-ignore TS error later\n const remainder = milliseconds % MILLISECONDS_IN[lowestUnit];\n // @ts-ignore TS error later\n if (2 * remainder >= MILLISECONDS_IN[lowestUnit]) {\n // if the remainder is large, add enough seconds to increse the lowest unit\n // @ts-ignore TS error later\n milliseconds += MILLISECONDS_IN[lowestUnit] - remainder;\n }\n\n const units = {};\n\n ORDERED_UNITS.forEach((unit) => {\n // @ts-ignore TS error later\n if (displayUnits[unit]) {\n // @ts-ignore TS error later\n units[unit] = Math.floor(milliseconds / MILLISECONDS_IN[unit]);\n // @ts-ignore TS error later\n milliseconds -= units[unit] * MILLISECONDS_IN[unit];\n }\n });\n\n return units;\n};\n\nexport const isValidNumber = (value: unknown): boolean =>\n typeof value === \"number\" && isFinite(value);\n\nexport interface TypeGetDurationMaxDisplayUnitsProps {\n milliseconds: TypeDurationMilliseconds;\n maxDisplayUnits: number;\n}\n\nexport const getDurationMaxDisplayUnits = ({\n milliseconds,\n maxDisplayUnits = ORDERED_UNITS.length,\n}: TypeGetDurationMaxDisplayUnitsProps): TypeDurationDisplayUnits => {\n const displayUnits = {};\n\n if (!isValidNumber(milliseconds)) {\n return displayUnits;\n }\n\n for (const unit of ORDERED_UNITS) {\n if (Object.keys(displayUnits).length >= maxDisplayUnits) {\n break;\n }\n\n // @ts-expect-error - stupid typescript isn't smart enough to check the isValidNumber check above ¯\\_(ツ)_/¯\n const millisecondsByUnit = splitMillisecondsIntoUnits(milliseconds, {\n days: true,\n hours: true,\n minutes: true,\n seconds: true,\n milliseconds: true,\n });\n\n // @ts-expect-error - stupid typescript isn't smart enough to check the isValidNumber check above ¯\\_(ツ)_/¯\n if (milliseconds > MILLISECONDS_IN[unit] && millisecondsByUnit[unit] > 0) {\n // @ts-ignore TS error later\n displayUnits[unit] = true;\n }\n }\n\n return displayUnits;\n};\n"],"mappings":"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","names":["styled","Text","locale","unitDisplay","memoize"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Duration.tsx","../src/constants.ts","../src/DurationHybrid.tsx","../src/styles.ts","../src/DurationTailwind.tsx","../src/utils.ts"],"sourcesContent":["import Duration, { formatDuration } from \"./Duration\";\nimport {\n getDurationMaxDisplayUnits,\n type TypeGetDurationMaxDisplayUnitsProps,\n} from \"./utils\";\n\nexport default Duration;\nexport { Duration };\nexport { formatDuration };\nexport { getDurationMaxDisplayUnits };\nexport type { TypeGetDurationMaxDisplayUnitsProps };\nexport * from \"./DurationTypes\";\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 { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\n\nimport {\n COMPARE_OBJECTS,\n DEFAULT_DISPLAY,\n DEFAULT_DISPLAY_UNITS,\n DEFAULT_LOCALE,\n DEFAULT_MILLISECONDS,\n MEMO_CACHE_SIZE,\n ORDERED_UNITS,\n UNITS,\n} from \"./constants\";\nimport { DurationHybrid } from \"./DurationHybrid\";\nimport type {\n TypeDurationProps,\n TypeDurationLocale,\n TypeDurationDisplay,\n TypeDurationDisplayUnits,\n} from \"./DurationTypes\";\nimport {\n isValidNumber,\n getLowestUnit,\n splitMillisecondsIntoUnits,\n} from \"./utils\";\n\nconst _createDurationFormatter = (\n locale: TypeDurationLocale,\n unitDisplay: TypeDurationDisplay,\n displayUnits: TypeDurationDisplayUnits\n) => {\n const timeUnitFormatter = (\n locale: TypeDurationProps[\"locale\"],\n unit: string,\n unitDisplay: TypeDurationProps[\"display\"]\n ) => Intl.NumberFormat(locale, { style: \"unit\", unit, unitDisplay }).format;\n\n const formatterByUnit = {\n [UNITS.days]: timeUnitFormatter(locale, \"day\", unitDisplay),\n [UNITS.hours]: timeUnitFormatter(locale, \"hour\", unitDisplay),\n [UNITS.minutes]: timeUnitFormatter(locale, \"minute\", unitDisplay),\n [UNITS.seconds]: timeUnitFormatter(locale, \"second\", unitDisplay),\n [UNITS.milliseconds]: timeUnitFormatter(locale, \"millisecond\", unitDisplay),\n };\n\n const formatList = new Intl.ListFormat(locale, {\n style: \"narrow\",\n type: \"unit\",\n });\n\n return (value: number) => {\n const lowestUnit = getLowestUnit(displayUnits);\n\n // if the value is zero or negative, we just want to return 0 for the lowest unit (ex \"0 minutes\")\n if (value <= 0) {\n // @ts-ignore TS error later\n return formatterByUnit[lowestUnit](0);\n }\n\n const millisecondsByUnit = splitMillisecondsIntoUnits(value, displayUnits);\n const list: string[] = [];\n\n ORDERED_UNITS.forEach((unit) => {\n if (unit in millisecondsByUnit) {\n // @ts-ignore TS error later\n const unitValue = millisecondsByUnit[unit];\n\n // we want to add to the list if one of two conditions are met:\n // 1) the unit has a value greater than 0 OR\n // 2) the unit has value 0 AND the unit is the lowest unit AND the list is already empty\n if (\n unitValue !== 0 ||\n (unitValue === 0 && unit === lowestUnit && list.length === 0)\n ) {\n // @ts-ignore TS error later\n list.push(formatterByUnit[unit](millisecondsByUnit[unit]));\n }\n }\n });\n\n return formatList.format(list);\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 createDurationFormatter = memoizer(_createDurationFormatter);\n\nconst getDuration = ({\n returnType,\n props,\n}: {\n returnType: \"string\" | \"component\";\n props: TypeDurationProps;\n}): string | React.ReactNode => {\n const {\n display = DEFAULT_DISPLAY,\n displayUnits = DEFAULT_DISPLAY_UNITS,\n invalidMillisecondsLabel,\n locale = DEFAULT_LOCALE,\n milliseconds = DEFAULT_MILLISECONDS,\n qa,\n ...rest\n } = props;\n const isReturnTypeString = returnType === \"string\";\n\n if (!isValidNumber(milliseconds)) {\n return isReturnTypeString ? (\n EM_DASH\n ) : (\n <>\n {invalidMillisecondsLabel ? (\n // Give screen readers something useful to read off + hide the em dash\n <VisuallyHidden>{invalidMillisecondsLabel}</VisuallyHidden>\n ) : null}\n <DurationHybrid {...rest} aria-hidden {...qa}>\n {EM_DASH}\n </DurationHybrid>\n </>\n );\n }\n\n const validatedDisplayUnits =\n Object.keys(displayUnits).length === 0\n ? DEFAULT_DISPLAY_UNITS\n : displayUnits;\n\n const fullText = createDurationFormatter(\n locale,\n display,\n validatedDisplayUnits\n )(milliseconds);\n\n return isReturnTypeString ? (\n fullText\n ) : (\n <DurationHybrid {...rest} {...qa}>\n {fullText}\n </DurationHybrid>\n );\n};\n\nexport const formatDuration = (props: TypeDurationProps): string => {\n return getDuration({ returnType: \"string\", props }) as string;\n};\n\nconst Duration = (props: TypeDurationProps) => {\n return getDuration({ returnType: \"component\", props });\n};\n\nexport default Duration;\n","export const COMPARE_OBJECTS = true;\nexport const MEMO_CACHE_SIZE = 10;\n\nexport const UNITS = {\n days: \"days\",\n hours: \"hours\",\n minutes: \"minutes\",\n seconds: \"seconds\",\n milliseconds: \"milliseconds\",\n};\n\nexport const MILLISECONDS_IN = {\n [UNITS.days]: 1 * 1000 * 60 * 60 * 24,\n [UNITS.hours]: 1 * 1000 * 60 * 60,\n [UNITS.minutes]: 1 * 1000 * 60,\n [UNITS.seconds]: 1 * 1000,\n [UNITS.milliseconds]: 1,\n};\n\nexport const ORDERED_UNITS = [\n UNITS.days,\n UNITS.hours,\n UNITS.minutes,\n UNITS.seconds,\n UNITS.milliseconds,\n];\n\n// Duration props defaults\nexport const DEFAULT_DISPLAY = \"narrow\";\nexport const DEFAULT_DISPLAY_UNITS = {\n [UNITS.days]: true,\n [UNITS.hours]: true,\n [UNITS.minutes]: true,\n [UNITS.seconds]: true,\n [UNITS.milliseconds]: false,\n};\n\nexport const DEFAULT_LOCALE = \"en-US\";\nexport const DEFAULT_MILLISECONDS = null;\n\nexport const EM_DASH = \"—\"; // shift + option + hyphen on a mac keyboard\n","/**\n * Hybrid Duration Component\n * Automatically chooses between Tailwind and styled-components based on props\n */\n\nimport React from \"react\";\nimport type { TypeTextProps } from \"@sproutsocial/seeds-react-text\";\nimport { Container } from \"./styles\"; // Styled-components version (named export)\nimport { DurationTailwind } from \"./DurationTailwind\"; // Tailwind version\nimport { hasStyledProps } from \"@sproutsocial/seeds-react-system-props\";\n\nexport const DurationHybrid = React.forwardRef<HTMLSpanElement, TypeTextProps>(\n (props, ref) => {\n // styled-system props (e.g. color, fontSize) must render through the\n // styled-components Container so those styles apply. Everything else uses the\n // Tailwind path — a styled(Duration) extension still works there because\n // styled() forwards its generated className onto the rendered element.\n if (hasStyledProps(props)) {\n return <Container ref={ref} {...props} />;\n }\n\n // Use Tailwind version (preferred - better performance)\n return <DurationTailwind ref={ref} {...props} />;\n }\n);\n\nDurationHybrid.displayName = \"DurationHybrid\";\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","/**\n * Tailwind CSS implementation of Duration component\n * Uses the Seeds duration CSS class from duration.css\n */\n\nimport React from \"react\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport type { TypeTextProps } from \"@sproutsocial/seeds-react-text\";\n\n// Utility for merging class names properly\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\nexport const DurationTailwind = React.forwardRef<\n HTMLSpanElement,\n TypeTextProps\n>(({ className, children, ...rest }, ref) => (\n <Text className={cn(\"seeds-duration\", className)} {...rest} ref={ref}>\n {children}\n </Text>\n));\n\nDurationTailwind.displayName = \"DurationTailwind\";\n","import type {\n TypeDurationDisplayUnits,\n TypeDurationMilliseconds,\n} from \"./DurationTypes\";\nimport { MILLISECONDS_IN, ORDERED_UNITS, UNITS } from \"./constants\";\n\nexport const getLowestUnit = (displayUnits: TypeDurationDisplayUnits) =>\n [...ORDERED_UNITS]\n .reverse()\n .find((unit) => displayUnits[unit as keyof TypeDurationDisplayUnits]) ||\n UNITS.milliseconds;\n\nexport const splitMillisecondsIntoUnits = (\n milliseconds: number,\n displayUnits: TypeDurationDisplayUnits\n): {\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n milliseconds?: number;\n} => {\n const lowestUnit = getLowestUnit(displayUnits);\n\n // @ts-ignore TS error later\n const remainder = milliseconds % MILLISECONDS_IN[lowestUnit];\n // @ts-ignore TS error later\n if (2 * remainder >= MILLISECONDS_IN[lowestUnit]) {\n // if the remainder is large, add enough seconds to increse the lowest unit\n // @ts-ignore TS error later\n milliseconds += MILLISECONDS_IN[lowestUnit] - remainder;\n }\n\n const units = {};\n\n ORDERED_UNITS.forEach((unit) => {\n // @ts-ignore TS error later\n if (displayUnits[unit]) {\n // @ts-ignore TS error later\n units[unit] = Math.floor(milliseconds / MILLISECONDS_IN[unit]);\n // @ts-ignore TS error later\n milliseconds -= units[unit] * MILLISECONDS_IN[unit];\n }\n });\n\n return units;\n};\n\nexport const isValidNumber = (value: unknown): boolean =>\n typeof value === \"number\" && isFinite(value);\n\nexport interface TypeGetDurationMaxDisplayUnitsProps {\n milliseconds: TypeDurationMilliseconds;\n maxDisplayUnits: number;\n}\n\nexport const getDurationMaxDisplayUnits = ({\n milliseconds,\n maxDisplayUnits = ORDERED_UNITS.length,\n}: TypeGetDurationMaxDisplayUnitsProps): TypeDurationDisplayUnits => {\n const displayUnits = {};\n\n if (!isValidNumber(milliseconds)) {\n return displayUnits;\n }\n\n for (const unit of ORDERED_UNITS) {\n if (Object.keys(displayUnits).length >= maxDisplayUnits) {\n break;\n }\n\n // @ts-expect-error - stupid typescript isn't smart enough to check the isValidNumber check above ¯\\_(ツ)_/¯\n const millisecondsByUnit = splitMillisecondsIntoUnits(milliseconds, {\n days: true,\n hours: true,\n minutes: true,\n seconds: true,\n milliseconds: true,\n });\n\n // @ts-expect-error - stupid typescript isn't smart enough to check the isValidNumber check above ¯\\_(ツ)_/¯\n if (milliseconds > MILLISECONDS_IN[unit] && millisecondsByUnit[unit] > 0) {\n // @ts-ignore TS error later\n displayUnits[unit] = true;\n }\n }\n\n return displayUnits;\n};\n"],"mappings":"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","names":["React","import_react","styled","Text","import_seeds_react_text","React","Text","import_jsx_runtime","React","import_jsx_runtime","locale","unitDisplay","memoize"]}
package/package.json CHANGED
@@ -1,15 +1,26 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-duration",
3
- "version": "1.0.31",
3
+ "version": "1.0.34",
4
4
  "description": "Seeds React Duration",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/esm/index.js",
9
9
  "types": "dist/index.d.ts",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "exports": {
14
+ ".": {
15
+ "import": "./dist/esm/index.js",
16
+ "require": "./dist/index.js",
17
+ "types": "./dist/index.d.ts"
18
+ },
19
+ "./dist/duration.css": "./dist/duration.css"
20
+ },
10
21
  "scripts": {
11
- "build": "tsup --dts",
12
- "build:debug": "tsup --dts --metafile",
22
+ "build": "tsup --dts && cp src/duration.css dist/duration.css",
23
+ "build:debug": "tsup --dts --metafile && cp src/duration.css dist/duration.css",
13
24
  "dev": "tsup --watch --dts",
14
25
  "clean": "rm -rf .turbo dist",
15
26
  "clean:modules": "rm -rf node_modules",
@@ -18,10 +29,10 @@
18
29
  "test:watch": "jest --watch --coverage=false"
19
30
  },
20
31
  "dependencies": {
21
- "@sproutsocial/seeds-react-theme": "^4.3.1",
22
- "@sproutsocial/seeds-react-system-props": "^3.1.4",
23
- "@sproutsocial/seeds-react-visually-hidden": "^1.0.29",
24
- "@sproutsocial/seeds-react-text": "^1.5.3",
32
+ "@sproutsocial/seeds-react-theme": "^4.4.0",
33
+ "@sproutsocial/seeds-react-system-props": "^3.2.0",
34
+ "@sproutsocial/seeds-react-visually-hidden": "^1.0.31",
35
+ "@sproutsocial/seeds-react-text": "^1.5.4",
25
36
  "lru-memoize": "~1.0.2"
26
37
  },
27
38
  "devDependencies": {
package/.eslintignore DELETED
@@ -1,6 +0,0 @@
1
- # Node modules
2
- node_modules/
3
-
4
- # Build output
5
- dist/
6
- coverage/
package/.eslintrc.js DELETED
@@ -1,4 +0,0 @@
1
- module.exports = {
2
- root: true,
3
- extends: ["eslint-config-seeds/racine"],
4
- };
@@ -1,21 +0,0 @@
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.5.0
6
- CLI Using tsup config: /home/runner/_work/seeds/seeds/seeds-react/seeds-react-duration/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 7.44 KB
12
- CJS dist/index.js.map 12.26 KB
13
- CJS ⚡️ Build success in 18ms
14
- ESM dist/esm/index.js 5.43 KB
15
- ESM dist/esm/index.js.map 12.18 KB
16
- ESM ⚡️ Build success in 18ms
17
- DTS Build start
18
- DTS ⚡️ Build success in 4694ms
19
- DTS dist/index.d.ts 1.70 KB
20
- DTS dist/index.d.mts 1.70 KB
21
- Done in 6.49s.