@sproutsocial/seeds-react-duration 1.0.30 → 1.0.32

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,44 @@ 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(
75
+ ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx(Text2, { className: cn("seeds-duration", className), ...rest, ref, children })
76
+ );
77
+ DurationTailwind.displayName = "DurationTailwind";
78
+
79
+ // src/DurationHybrid.tsx
80
+ import { hasStyledProps } from "@sproutsocial/seeds-react-system-props";
81
+ import { jsx as jsx2 } from "react/jsx-runtime";
82
+ var DurationHybrid = React2.forwardRef(
83
+ (props, ref) => {
84
+ if (hasStyledProps(props)) {
85
+ return /* @__PURE__ */ jsx2(Container, { ref, ...props });
86
+ }
87
+ return /* @__PURE__ */ jsx2(DurationTailwind, { ref, ...props });
88
+ }
89
+ );
90
+ DurationHybrid.displayName = "DurationHybrid";
91
+
51
92
  // src/utils.ts
52
93
  var getLowestUnit = (displayUnits) => [...ORDERED_UNITS].reverse().find((unit) => displayUnits[unit]) || UNITS.milliseconds;
53
94
  var splitMillisecondsIntoUnits = (milliseconds, displayUnits) => {
@@ -93,7 +134,7 @@ var getDurationMaxDisplayUnits = ({
93
134
  };
94
135
 
95
136
  // src/Duration.tsx
96
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
137
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
97
138
  var _createDurationFormatter = (locale, unitDisplay, displayUnits) => {
98
139
  const timeUnitFormatter = (locale2, unit, unitDisplay2) => Intl.NumberFormat(locale2, { style: "unit", unit, unitDisplay: unitDisplay2 }).format;
99
140
  const formatterByUnit = {
@@ -137,16 +178,17 @@ var getDuration = ({
137
178
  invalidMillisecondsLabel,
138
179
  locale = DEFAULT_LOCALE,
139
180
  milliseconds = DEFAULT_MILLISECONDS,
140
- qa
181
+ qa,
182
+ ...rest
141
183
  } = props;
142
184
  const isReturnTypeString = returnType === "string";
143
185
  if (!isValidNumber(milliseconds)) {
144
186
  return isReturnTypeString ? EM_DASH : /* @__PURE__ */ jsxs(Fragment, { children: [
145
187
  invalidMillisecondsLabel ? (
146
188
  // Give screen readers something useful to read off + hide the em dash
147
- /* @__PURE__ */ jsx(VisuallyHidden, { children: invalidMillisecondsLabel })
189
+ /* @__PURE__ */ jsx3(VisuallyHidden, { children: invalidMillisecondsLabel })
148
190
  ) : null,
149
- /* @__PURE__ */ jsx(Container, { "aria-hidden": true, ...qa, children: EM_DASH })
191
+ /* @__PURE__ */ jsx3(DurationHybrid, { ...rest, "aria-hidden": true, ...qa, children: EM_DASH })
150
192
  ] });
151
193
  }
152
194
  const validatedDisplayUnits = Object.keys(displayUnits).length === 0 ? DEFAULT_DISPLAY_UNITS : displayUnits;
@@ -155,7 +197,7 @@ var getDuration = ({
155
197
  display,
156
198
  validatedDisplayUnits
157
199
  )(milliseconds);
158
- return isReturnTypeString ? fullText : /* @__PURE__ */ jsx(Container, { ...qa, children: fullText });
200
+ return isReturnTypeString ? fullText : /* @__PURE__ */ jsx3(DurationHybrid, { ...rest, ...qa, children: fullText });
159
201
  };
160
202
  var formatDuration = (props) => {
161
203
  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<HTMLSpanElement, TypeTextProps>(\n ({ className, children, ...rest }, ref) => (\n <Text className={cn(\"seeds-duration\", className)} {...rest} ref={ref}>\n {children}\n </Text>\n )\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":"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","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,44 @@ 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(
114
+ ({ className, children, ...rest }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_text2.default, { className: cn("seeds-duration", className), ...rest, ref, children })
115
+ );
116
+ DurationTailwind.displayName = "DurationTailwind";
117
+
118
+ // src/DurationHybrid.tsx
119
+ var import_seeds_react_system_props = require("@sproutsocial/seeds-react-system-props");
120
+ var import_jsx_runtime2 = require("react/jsx-runtime");
121
+ var DurationHybrid = import_react2.default.forwardRef(
122
+ (props, ref) => {
123
+ if ((0, import_seeds_react_system_props.hasStyledProps)(props)) {
124
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Container, { ref, ...props });
125
+ }
126
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DurationTailwind, { ref, ...props });
127
+ }
128
+ );
129
+ DurationHybrid.displayName = "DurationHybrid";
130
+
90
131
  // src/utils.ts
91
132
  var getLowestUnit = (displayUnits) => [...ORDERED_UNITS].reverse().find((unit) => displayUnits[unit]) || UNITS.milliseconds;
92
133
  var splitMillisecondsIntoUnits = (milliseconds, displayUnits) => {
@@ -132,7 +173,7 @@ var getDurationMaxDisplayUnits = ({
132
173
  };
133
174
 
134
175
  // src/Duration.tsx
135
- var import_jsx_runtime = require("react/jsx-runtime");
176
+ var import_jsx_runtime3 = require("react/jsx-runtime");
136
177
  var _createDurationFormatter = (locale, unitDisplay, displayUnits) => {
137
178
  const timeUnitFormatter = (locale2, unit, unitDisplay2) => Intl.NumberFormat(locale2, { style: "unit", unit, unitDisplay: unitDisplay2 }).format;
138
179
  const formatterByUnit = {
@@ -176,16 +217,17 @@ var getDuration = ({
176
217
  invalidMillisecondsLabel,
177
218
  locale = DEFAULT_LOCALE,
178
219
  milliseconds = DEFAULT_MILLISECONDS,
179
- qa
220
+ qa,
221
+ ...rest
180
222
  } = props;
181
223
  const isReturnTypeString = returnType === "string";
182
224
  if (!isValidNumber(milliseconds)) {
183
- return isReturnTypeString ? EM_DASH : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
225
+ return isReturnTypeString ? EM_DASH : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
184
226
  invalidMillisecondsLabel ? (
185
227
  // 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 })
228
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_visually_hidden.VisuallyHidden, { children: invalidMillisecondsLabel })
187
229
  ) : null,
188
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, { "aria-hidden": true, ...qa, children: EM_DASH })
230
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DurationHybrid, { ...rest, "aria-hidden": true, ...qa, children: EM_DASH })
189
231
  ] });
190
232
  }
191
233
  const validatedDisplayUnits = Object.keys(displayUnits).length === 0 ? DEFAULT_DISPLAY_UNITS : displayUnits;
@@ -194,7 +236,7 @@ var getDuration = ({
194
236
  display,
195
237
  validatedDisplayUnits
196
238
  )(milliseconds);
197
- return isReturnTypeString ? fullText : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, { ...qa, children: fullText });
239
+ return isReturnTypeString ? fullText : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DurationHybrid, { ...rest, ...qa, children: fullText });
198
240
  };
199
241
  var formatDuration = (props) => {
200
242
  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<HTMLSpanElement, TypeTextProps>(\n ({ className, children, ...rest }, ref) => (\n <Text className={cn(\"seeds-duration\", className)} {...rest} ref={ref}>\n {children}\n </Text>\n )\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.30",
3
+ "version": "1.0.32",
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",
@@ -19,9 +30,9 @@
19
30
  },
20
31
  "dependencies": {
21
32
  "@sproutsocial/seeds-react-theme": "^4.3.1",
22
- "@sproutsocial/seeds-react-system-props": "^3.1.3",
23
- "@sproutsocial/seeds-react-visually-hidden": "^1.0.28",
24
- "@sproutsocial/seeds-react-text": "^1.5.2",
33
+ "@sproutsocial/seeds-react-system-props": "^3.1.4",
34
+ "@sproutsocial/seeds-react-visually-hidden": "^1.0.29",
35
+ "@sproutsocial/seeds-react-text": "^1.5.3",
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 17ms
14
- ESM dist/esm/index.js 5.43 KB
15
- ESM dist/esm/index.js.map 12.18 KB
16
- ESM ⚡️ Build success in 17ms
17
- DTS Build start
18
- DTS ⚡️ Build success in 4632ms
19
- DTS dist/index.d.ts 1.70 KB
20
- DTS dist/index.d.mts 1.70 KB
21
- Done in 6.20s.