@dynatrace/strato-components 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/buttons/button/Button.css +16 -16
  2. package/buttons/button/Button.js +10 -10
  3. package/buttons/button/Button.sty.d.ts +4 -4
  4. package/buttons/button/Button.sty.js +8 -8
  5. package/buttons/button/Label.js +1 -1
  6. package/buttons/intent-button/IntentButton.d.ts +1 -0
  7. package/content/progress/ProgressBar.css +71 -71
  8. package/content/progress/ProgressBar.sty.js +5 -5
  9. package/content/progress/ProgressBarIcon.css +2 -2
  10. package/content/progress/ProgressBarIcon.sty.js +1 -1
  11. package/content/progress/ProgressBarLabel.css +3 -3
  12. package/content/progress/ProgressBarLabel.js +3 -3
  13. package/content/progress/ProgressBarLabel.sty.d.ts +1 -1
  14. package/content/progress/ProgressBarLabel.sty.js +2 -2
  15. package/content/progress/ProgressBarValue.css +5 -5
  16. package/content/progress/ProgressBarValue.js +2 -2
  17. package/content/progress/ProgressBarValue.sty.d.ts +1 -1
  18. package/content/progress/ProgressBarValue.sty.js +2 -2
  19. package/content/progress/ProgressCircle.css +40 -40
  20. package/content/progress/ProgressCircle.js +1 -1
  21. package/content/progress/ProgressCircle.sty.d.ts +13 -7
  22. package/content/progress/ProgressCircle.sty.js +5 -5
  23. package/content/skeleton/Skeleton.css +7 -7
  24. package/content/skeleton/Skeleton.js +2 -2
  25. package/content/skeleton/Skeleton.sty.js +5 -5
  26. package/content/skeleton/SkeletonText.js +3 -3
  27. package/core/styles/focusRing.css +66 -66
  28. package/core/styles/focusRing.sty.d.ts +34 -10
  29. package/core/styles/focusRing.sty.js +2 -2
  30. package/core/utils/colorUtils.css +60 -60
  31. package/core/utils/colorUtils.sty.d.ts +15 -5
  32. package/core/utils/colorUtils.sty.js +2 -2
  33. package/core/utils/is-node-environment.d.ts +15 -0
  34. package/core/utils/is-node-environment.js +34 -0
  35. package/core/utils/logging.d.ts +8 -0
  36. package/core/utils/logging.js +33 -0
  37. package/esm/buttons/button/Button.css +16 -16
  38. package/esm/buttons/button/Button.js +11 -11
  39. package/esm/buttons/button/Button.js.map +2 -2
  40. package/esm/buttons/button/Button.sty.js +8 -8
  41. package/esm/buttons/button/Button.sty.js.map +2 -2
  42. package/esm/buttons/button/Label.js +2 -2
  43. package/esm/buttons/button/Label.js.map +2 -2
  44. package/esm/buttons/index.js.map +2 -2
  45. package/esm/buttons/intent-button/IntentButton.js.map +2 -2
  46. package/esm/content/progress/ProgressBar.css +71 -71
  47. package/esm/content/progress/ProgressBar.sty.js +5 -5
  48. package/esm/content/progress/ProgressBar.sty.js.map +1 -1
  49. package/esm/content/progress/ProgressBarIcon.css +2 -2
  50. package/esm/content/progress/ProgressBarIcon.sty.js +1 -1
  51. package/esm/content/progress/ProgressBarIcon.sty.js.map +1 -1
  52. package/esm/content/progress/ProgressBarLabel.css +3 -3
  53. package/esm/content/progress/ProgressBarLabel.js +6 -6
  54. package/esm/content/progress/ProgressBarLabel.js.map +2 -2
  55. package/esm/content/progress/ProgressBarLabel.sty.js +2 -2
  56. package/esm/content/progress/ProgressBarLabel.sty.js.map +2 -2
  57. package/esm/content/progress/ProgressBarValue.css +5 -5
  58. package/esm/content/progress/ProgressBarValue.js +4 -4
  59. package/esm/content/progress/ProgressBarValue.js.map +2 -2
  60. package/esm/content/progress/ProgressBarValue.sty.js +2 -2
  61. package/esm/content/progress/ProgressBarValue.sty.js.map +2 -2
  62. package/esm/content/progress/ProgressCircle.css +40 -40
  63. package/esm/content/progress/ProgressCircle.js +2 -2
  64. package/esm/content/progress/ProgressCircle.js.map +2 -2
  65. package/esm/content/progress/ProgressCircle.sty.js +5 -5
  66. package/esm/content/progress/ProgressCircle.sty.js.map +1 -1
  67. package/esm/content/skeleton/Skeleton.css +7 -7
  68. package/esm/content/skeleton/Skeleton.js +1 -1
  69. package/esm/content/skeleton/Skeleton.js.map +1 -1
  70. package/esm/content/skeleton/Skeleton.sty.js +5 -5
  71. package/esm/content/skeleton/Skeleton.sty.js.map +1 -1
  72. package/esm/content/skeleton/SkeletonText.js +1 -1
  73. package/esm/content/skeleton/SkeletonText.js.map +1 -1
  74. package/esm/core/hooks/useId.js.map +2 -2
  75. package/esm/core/styles/focusRing.css +66 -66
  76. package/esm/core/styles/focusRing.sty.js +2 -2
  77. package/esm/core/styles/focusRing.sty.js.map +1 -1
  78. package/esm/core/utils/colorUtils.css +60 -60
  79. package/esm/core/utils/colorUtils.sty.js +2 -2
  80. package/esm/core/utils/colorUtils.sty.js.map +1 -1
  81. package/esm/core/utils/is-node-environment.js +15 -0
  82. package/esm/core/utils/is-node-environment.js.map +7 -0
  83. package/esm/core/utils/logging.js +14 -0
  84. package/esm/core/utils/logging.js.map +7 -0
  85. package/esm/layouts/container/Container.css +4 -4
  86. package/esm/layouts/container/Container.sty.js +1 -1
  87. package/esm/layouts/container/Container.sty.js.map +1 -1
  88. package/esm/layouts/divider/Divider.css +6 -6
  89. package/esm/layouts/divider/Divider.sty.js +1 -1
  90. package/esm/layouts/divider/Divider.sty.js.map +1 -1
  91. package/esm/layouts/surface/Surface.css +39 -39
  92. package/esm/layouts/surface/Surface.js +4 -4
  93. package/esm/layouts/surface/Surface.js.map +2 -2
  94. package/esm/layouts/surface/Surface.sty.js +2 -2
  95. package/esm/layouts/surface/Surface.sty.js.map +1 -1
  96. package/esm/layouts/surface/variables.sty.js +1 -1
  97. package/esm/layouts/surface/variables.sty.js.map +1 -1
  98. package/esm/styles/colorUtils.css +60 -60
  99. package/esm/styles/colorUtils.sty.js +3 -3
  100. package/esm/styles/colorUtils.sty.js.map +2 -2
  101. package/esm/styles/container.css +47 -47
  102. package/esm/styles/container.sty.js +2 -2
  103. package/esm/styles/container.sty.js.map +1 -1
  104. package/esm/styles/ellipsis.css +1 -1
  105. package/esm/styles/ellipsis.sty.js +2 -2
  106. package/esm/styles/ellipsis.sty.js.map +2 -2
  107. package/esm/styles/field.css +153 -153
  108. package/esm/styles/field.sty.js +3 -3
  109. package/esm/styles/field.sty.js.map +2 -2
  110. package/esm/styles/index.js +2 -2
  111. package/esm/styles/index.js.map +2 -2
  112. package/esm/styles/sprinkles.css +262 -262
  113. package/esm/styles/sprinkles.sty.js +1 -1
  114. package/esm/styles/sprinkles.sty.js.map +1 -1
  115. package/esm/styles/textStyle.css +8 -8
  116. package/esm/styles/textStyle.sty.js +2 -2
  117. package/esm/styles/textStyle.sty.js.map +2 -2
  118. package/esm/typography/block-quote/Blockquote.css +2 -2
  119. package/esm/typography/block-quote/Blockquote.sty.js +1 -1
  120. package/esm/typography/block-quote/Blockquote.sty.js.map +1 -1
  121. package/esm/typography/code/Code.css +1 -1
  122. package/esm/typography/code/Code.sty.js +1 -1
  123. package/esm/typography/code/Code.sty.js.map +1 -1
  124. package/esm/typography/emphasis/Emphasis.css +1 -1
  125. package/esm/typography/emphasis/Emphasis.sty.js +1 -1
  126. package/esm/typography/emphasis/Emphasis.sty.js.map +1 -1
  127. package/esm/typography/external-link/ExternalLink.css +6 -8
  128. package/esm/typography/external-link/ExternalLink.js +1 -1
  129. package/esm/typography/external-link/ExternalLink.js.map +2 -2
  130. package/esm/typography/external-link/ExternalLink.sty.js +1 -1
  131. package/esm/typography/external-link/ExternalLink.sty.js.map +1 -1
  132. package/esm/typography/heading/Heading.css +7 -7
  133. package/esm/typography/heading/Heading.sty.js +1 -1
  134. package/esm/typography/heading/Heading.sty.js.map +1 -1
  135. package/esm/typography/highlight/Highlight.css +5 -6
  136. package/esm/typography/highlight/Highlight.js +45 -138
  137. package/esm/typography/highlight/Highlight.js.map +3 -3
  138. package/esm/typography/highlight/Highlight.sty.js +2 -4
  139. package/esm/typography/highlight/Highlight.sty.js.map +2 -2
  140. package/esm/typography/highlight/utils/create-ranged-highlights.js +51 -0
  141. package/esm/typography/highlight/utils/create-ranged-highlights.js.map +7 -0
  142. package/esm/typography/highlight/utils/get-or-create-shared-highlight.js +25 -0
  143. package/esm/typography/highlight/utils/get-or-create-shared-highlight.js.map +7 -0
  144. package/esm/typography/link/Link.css +3 -3
  145. package/esm/typography/link/Link.sty.js +1 -1
  146. package/esm/typography/link/Link.sty.js.map +1 -1
  147. package/esm/typography/list/List.css +4 -4
  148. package/esm/typography/list/List.sty.js +2 -2
  149. package/esm/typography/list/List.sty.js.map +1 -1
  150. package/esm/typography/paragraph/Paragraph.css +3 -3
  151. package/esm/typography/paragraph/Paragraph.js +3 -7
  152. package/esm/typography/paragraph/Paragraph.js.map +2 -2
  153. package/esm/typography/paragraph/Paragraph.sty.js +2 -2
  154. package/esm/typography/paragraph/Paragraph.sty.js.map +2 -2
  155. package/esm/typography/strikethrough/Strikethrough.css +1 -1
  156. package/esm/typography/strikethrough/Strikethrough.sty.js +1 -1
  157. package/esm/typography/strikethrough/Strikethrough.sty.js.map +1 -1
  158. package/esm/typography/strong/Strong.css +1 -1
  159. package/esm/typography/strong/Strong.sty.js +1 -1
  160. package/esm/typography/strong/Strong.sty.js.map +1 -1
  161. package/esm/typography/text/Text.css +3 -3
  162. package/esm/typography/text/Text.js +5 -5
  163. package/esm/typography/text/Text.js.map +2 -2
  164. package/esm/typography/text/Text.sty.js +2 -2
  165. package/esm/typography/text/Text.sty.js.map +2 -2
  166. package/esm/typography/text-ellipsis/TextEllipsis.css +6 -6
  167. package/esm/typography/text-ellipsis/TextEllipsis.sty.js +2 -2
  168. package/esm/typography/text-ellipsis/TextEllipsis.sty.js.map +1 -1
  169. package/esm/typography/utils.js +17 -9
  170. package/esm/typography/utils.js.map +2 -2
  171. package/layouts/container/Container.css +4 -4
  172. package/layouts/container/Container.sty.js +1 -1
  173. package/layouts/divider/Divider.css +6 -6
  174. package/layouts/divider/Divider.sty.js +1 -1
  175. package/layouts/surface/Surface.css +39 -39
  176. package/layouts/surface/Surface.js +2 -2
  177. package/layouts/surface/Surface.sty.d.ts +19 -6
  178. package/layouts/surface/Surface.sty.js +2 -2
  179. package/layouts/surface/variables.sty.js +1 -1
  180. package/package.json +3 -3
  181. package/styles/colorUtils.css +60 -60
  182. package/styles/colorUtils.sty.d.ts +16 -6
  183. package/styles/colorUtils.sty.js +3 -3
  184. package/styles/container.css +47 -47
  185. package/styles/container.sty.d.ts +16 -6
  186. package/styles/container.sty.js +2 -2
  187. package/styles/ellipsis.css +1 -1
  188. package/styles/ellipsis.sty.d.ts +1 -1
  189. package/styles/ellipsis.sty.js +2 -2
  190. package/styles/field.css +153 -153
  191. package/styles/field.sty.d.ts +25 -18
  192. package/styles/field.sty.js +3 -3
  193. package/styles/index.d.ts +1 -1
  194. package/styles/index.js +1 -1
  195. package/styles/sprinkles.css +262 -262
  196. package/styles/sprinkles.sty.js +1 -1
  197. package/styles/textStyle.css +8 -8
  198. package/styles/textStyle.sty.d.ts +1 -1
  199. package/styles/textStyle.sty.js +2 -2
  200. package/typography/block-quote/Blockquote.css +2 -2
  201. package/typography/block-quote/Blockquote.sty.js +1 -1
  202. package/typography/code/Code.css +1 -1
  203. package/typography/code/Code.sty.js +1 -1
  204. package/typography/emphasis/Emphasis.css +1 -1
  205. package/typography/emphasis/Emphasis.sty.js +1 -1
  206. package/typography/external-link/ExternalLink.css +6 -8
  207. package/typography/external-link/ExternalLink.js +1 -1
  208. package/typography/external-link/ExternalLink.sty.js +1 -1
  209. package/typography/heading/Heading.css +7 -7
  210. package/typography/heading/Heading.sty.js +1 -1
  211. package/typography/highlight/Highlight.css +5 -6
  212. package/typography/highlight/Highlight.d.ts +1 -1
  213. package/typography/highlight/Highlight.js +43 -127
  214. package/typography/highlight/Highlight.sty.d.ts +1 -2
  215. package/typography/highlight/Highlight.sty.js +2 -4
  216. package/typography/highlight/utils/create-ranged-highlights.d.ts +10 -0
  217. package/typography/highlight/utils/create-ranged-highlights.js +70 -0
  218. package/typography/highlight/utils/get-or-create-shared-highlight.d.ts +7 -0
  219. package/typography/highlight/utils/get-or-create-shared-highlight.js +44 -0
  220. package/typography/link/Link.css +3 -3
  221. package/typography/link/Link.sty.js +1 -1
  222. package/typography/list/List.css +4 -4
  223. package/typography/list/List.sty.js +2 -2
  224. package/typography/paragraph/Paragraph.css +3 -3
  225. package/typography/paragraph/Paragraph.js +1 -5
  226. package/typography/paragraph/Paragraph.sty.d.ts +1 -1
  227. package/typography/paragraph/Paragraph.sty.js +2 -2
  228. package/typography/strikethrough/Strikethrough.css +1 -1
  229. package/typography/strikethrough/Strikethrough.sty.js +1 -1
  230. package/typography/strong/Strong.css +1 -1
  231. package/typography/strong/Strong.sty.js +1 -1
  232. package/typography/text/Text.css +3 -3
  233. package/typography/text/Text.js +3 -3
  234. package/typography/text/Text.sty.d.ts +1 -1
  235. package/typography/text/Text.sty.js +2 -2
  236. package/typography/text-ellipsis/TextEllipsis.css +6 -6
  237. package/typography/text-ellipsis/TextEllipsis.sty.js +2 -2
  238. package/typography/utils.js +17 -9
@@ -1,152 +1,59 @@
1
- import { Fragment, jsx } from "react/jsx-runtime";
2
- import {
3
- Children,
4
- cloneElement,
5
- createElement,
6
- Fragment as Fragment2,
7
- isValidElement
8
- } from "react";
9
- import {
10
- FormattedMessage,
11
- useIntl
12
- } from "react-intl";
13
- import { isElement } from "react-is";
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef } from "react";
14
3
  import * as styles from "./Highlight.sty.js";
15
- const HTML_CHARS_OVERRIDES = [
16
- [/&lt;/g, "<"],
17
- [/&gt;/g, ">"],
18
- [/&amp;/g, "&"],
19
- [/&nbsp;/g, " "]
20
- ];
21
- function escapeRegExp(text) {
22
- return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
23
- }
24
- function highlightChildren(intl, children, term, caseSensitive, dataTestId, dataDtrumMask, dataDtrumAllow) {
25
- const terms = (() => {
4
+ import { createRangedHighlights } from "./utils/create-ranged-highlights.js";
5
+ import { getOrCreateSharedHighlight } from "./utils/get-or-create-shared-highlight.js";
6
+ import { devLog } from "../../core/utils/logging.js";
7
+ const Highlight = (props) => {
8
+ const {
9
+ children,
10
+ term,
11
+ caseSensitive = false,
12
+ "data-testid": dataTestId,
13
+ "data-dtrum-mask": dataDtrumMask,
14
+ "data-dtrum-allow": dataDtrumAllow
15
+ } = props;
16
+ const rootRef = useRef(null);
17
+ const terms = useMemo(() => {
26
18
  if (Array.isArray(term)) {
27
19
  return term.filter((t) => t);
28
20
  }
29
21
  return term ? [term] : [];
30
- })();
31
- return terms.length > 0 ? Children.map(
32
- children,
33
- (child) => highlightRecursive(
34
- intl,
35
- child,
36
- terms,
37
- caseSensitive,
38
- dataTestId,
39
- dataDtrumMask,
40
- dataDtrumAllow
41
- )
42
- ) : children;
43
- }
44
- function isFormattedMessageElement(node) {
45
- return isElement(node) && node.type !== void 0 && node.type === FormattedMessage;
46
- }
47
- function highlightRecursive(intl, sourceElement, terms, caseSensitive, dataTestId, dataDtrumMask, dataDtrumAllow) {
48
- if (!sourceElement) {
49
- return sourceElement;
50
- }
51
- let elementToHighlight = sourceElement;
52
- if (isFormattedMessageElement(elementToHighlight)) {
53
- const { id, description, defaultMessage, values } = elementToHighlight.props;
54
- const messageDescriptor = {
55
- id,
56
- description,
57
- defaultMessage
58
- };
59
- elementToHighlight = intl.formatMessage(messageDescriptor, values);
60
- if (Array.isArray(elementToHighlight)) {
61
- return highlightRecursive(
62
- intl,
63
- createElement(Fragment2, {}, elementToHighlight),
22
+ }, [term]);
23
+ const highlight = getOrCreateSharedHighlight();
24
+ useEffect(() => {
25
+ const currentElement = rootRef.current;
26
+ const storedRanges = [];
27
+ if (currentElement) {
28
+ const ranges = createRangedHighlights(
29
+ currentElement,
64
30
  terms,
65
31
  caseSensitive,
66
- dataTestId,
67
- dataDtrumMask,
68
- dataDtrumAllow
32
+ highlight
69
33
  );
34
+ storedRanges.push(...ranges);
70
35
  }
71
- }
72
- if (isValidElement(elementToHighlight)) {
73
- const children = Children.map(
74
- elementToHighlight.props.children,
75
- (child) => highlightRecursive(
76
- intl,
77
- child,
78
- terms,
79
- caseSensitive,
80
- dataTestId,
81
- dataDtrumMask,
82
- dataDtrumAllow
83
- )
84
- );
85
- return cloneElement(
86
- elementToHighlight,
87
- elementToHighlight.props,
36
+ return () => {
37
+ for (const storedRange of storedRanges) {
38
+ try {
39
+ highlight.delete(storedRange);
40
+ } catch {
41
+ devLog("Failed to delete range", storedRange);
42
+ }
43
+ }
44
+ };
45
+ }, [children, highlight, terms, caseSensitive]);
46
+ return /* @__PURE__ */ jsx(
47
+ "span",
48
+ {
49
+ ref: rootRef,
50
+ className: styles.wrapper,
51
+ "data-testid": dataTestId,
52
+ "data-dtrum-mask": dataDtrumMask,
53
+ "data-dtrum-allow": dataDtrumAllow,
88
54
  children
89
- );
90
- }
91
- return highlightLeafElement(
92
- elementToHighlight,
93
- terms,
94
- caseSensitive,
95
- dataTestId,
96
- dataDtrumMask,
97
- dataDtrumAllow
98
- );
99
- }
100
- function highlightLeafElement(textContent, terms, caseSensitive, dataTestId, dataDtrumMask, dataDtrumAllow) {
101
- if (terms.length === 0) {
102
- return textContent;
103
- }
104
- const sanitizedTextContent = HTML_CHARS_OVERRIDES.reduce(
105
- (text, [needle, replacement]) => text.replace(needle, replacement),
106
- `${textContent}`
107
- );
108
- const termsInLowerCase = terms.map((t) => t.toLowerCase());
109
- return getTextTokens(sanitizedTextContent, terms, caseSensitive).map(
110
- (token, index) => termsInLowerCase.includes(token.toLowerCase()) ? /* @__PURE__ */ jsx(
111
- "mark",
112
- {
113
- role: "mark",
114
- className: styles.highlight,
115
- "data-dtrum-mask": dataDtrumMask,
116
- "data-dtrum-allow": dataDtrumAllow,
117
- children: token
118
- },
119
- `${token}-${index}`
120
- ) : /* @__PURE__ */ jsx("span", { className: styles.text, children: token }, `${token}-${index}`)
121
- );
122
- }
123
- function getTextTokens(textContent, terms, caseSensitive) {
124
- const flags = caseSensitive ? "gm" : "gmi";
125
- const regExp = new RegExp(
126
- `(${terms.map((t) => escapeRegExp(t)).join("|")})`,
127
- flags
55
+ }
128
56
  );
129
- return textContent.toString().split(regExp).filter((s) => s.length > 0);
130
- }
131
- const Highlight = (props) => {
132
- const {
133
- children,
134
- term,
135
- caseSensitive = false,
136
- "data-testid": dataTestId,
137
- "data-dtrum-mask": dataDtrumMask,
138
- "data-dtrum-allow": dataDtrumAllow
139
- } = props;
140
- const intl = useIntl();
141
- return /* @__PURE__ */ jsx(Fragment, { children: highlightChildren(
142
- intl,
143
- children,
144
- term,
145
- caseSensitive,
146
- dataTestId,
147
- dataDtrumMask,
148
- dataDtrumAllow
149
- ) });
150
57
  };
151
58
  Highlight.displayName = "Highlight";
152
59
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/typography/highlight/Highlight.tsx"],
4
- "sourcesContent": ["import {\n Children,\n cloneElement,\n createElement,\n Fragment,\n isValidElement,\n type PropsWithChildren,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n FormattedMessage,\n useIntl,\n type IntlShape,\n type MessageDescriptor,\n} from 'react-intl';\nimport { isElement } from 'react-is';\n\nimport * as styles from './Highlight.sty.js';\nimport type { DataTestId } from '../../core/types/data-props.js';\nimport type { MaskingProps } from '../../core/types/masking-props.js';\nimport type { WithChildren } from '../../core/types/with-children.js';\n\n/**\n * The props for the Heading component.\n * @public\n */\nexport interface HighlightProps extends WithChildren, DataTestId, MaskingProps {\n /**\n * Either a substring or an array of multiple different substrings that\n * should be highlighted in the projected content.\n * Every occurrence of the string(s) is highlighted accordingly.\n */\n term: string | string[];\n\n /**\n * Property that determines whether the highlighting search is case-sensitive.\n * If set to `true`, the component searches for case sensitive occurrences.\n * @defaultValue false\n */\n caseSensitive?: boolean;\n}\n\nconst HTML_CHARS_OVERRIDES: [RegExp, string][] = [\n [/&lt;/g, '<'],\n [/&gt;/g, '>'],\n [/&amp;/g, '&'],\n [/&nbsp;/g, ' '],\n];\n\n/** Escapes all characters that could be dangerous for a regular expression */\nfunction escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\n/** Highlights all occurences of a list of terms within a ReactNode. */\nfunction highlightChildren(\n intl: IntlShape,\n children: ReactNode,\n term: string | string[],\n caseSensitive: boolean,\n dataTestId?: string,\n dataDtrumMask?: boolean,\n dataDtrumAllow?: boolean,\n) {\n const terms = (() => {\n if (Array.isArray(term)) {\n return term.filter((t) => t);\n }\n\n return term ? [term] : [];\n })();\n\n return terms.length > 0\n ? Children.map(children, (child: ReactNode) =>\n highlightRecursive(\n intl,\n child,\n terms,\n caseSensitive,\n dataTestId,\n dataDtrumMask,\n dataDtrumAllow,\n ),\n )\n : children;\n}\n\nfunction isFormattedMessageElement(\n node: ReactNode,\n // Needs to overlap with the types from the FormattedMessage function\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): node is ReactElement<MessageDescriptor & { values: Record<string, any> }> {\n return (\n isElement(node) && node.type !== undefined && node.type === FormattedMessage\n );\n}\n\n/**\n * Iterates over all children of a ReactNode recursively to look\n * for a list of terms and highlights them.\n */\nfunction highlightRecursive(\n intl: IntlShape,\n sourceElement: ReactNode,\n terms: string[],\n caseSensitive: boolean,\n dataTestId?: string,\n dataDtrumMask?: boolean,\n dataDtrumAllow?: boolean,\n): ReactNode {\n if (!sourceElement) {\n return sourceElement;\n }\n\n let elementToHighlight = sourceElement;\n\n // For `FormattedMessage` components explicitly retrieve its node(s)\n if (isFormattedMessageElement(elementToHighlight)) {\n const { id, description, defaultMessage, values } =\n elementToHighlight.props;\n\n const messageDescriptor = {\n id,\n description,\n defaultMessage,\n };\n elementToHighlight = intl.formatMessage(messageDescriptor, values);\n\n if (Array.isArray(elementToHighlight)) {\n return highlightRecursive(\n intl,\n createElement(Fragment, {}, elementToHighlight),\n terms,\n caseSensitive,\n dataTestId,\n dataDtrumMask,\n dataDtrumAllow,\n );\n }\n }\n\n if (isValidElement(elementToHighlight)) {\n const children = Children.map(\n (elementToHighlight.props as PropsWithChildren).children,\n (child) =>\n highlightRecursive(\n intl,\n child,\n terms,\n caseSensitive,\n dataTestId,\n dataDtrumMask,\n dataDtrumAllow,\n ),\n );\n\n return cloneElement(\n elementToHighlight,\n elementToHighlight.props as PropsWithChildren,\n children,\n );\n }\n\n return highlightLeafElement(\n elementToHighlight as string | number,\n terms,\n caseSensitive,\n dataTestId,\n dataDtrumMask,\n dataDtrumAllow,\n );\n}\n\n/** Highlights parts of the text that match a certain group of terms. */\nfunction highlightLeafElement(\n textContent: string | number,\n terms: string[],\n caseSensitive: boolean,\n dataTestId?: string,\n dataDtrumMask?: boolean,\n dataDtrumAllow?: boolean,\n): ReactNode {\n if (terms.length === 0) {\n return textContent;\n }\n\n const sanitizedTextContent = HTML_CHARS_OVERRIDES.reduce(\n (text, [needle, replacement]) => text.replace(needle, replacement),\n `${textContent}`,\n );\n const termsInLowerCase = terms.map((t) => t.toLowerCase());\n\n return getTextTokens(sanitizedTextContent, terms, caseSensitive).map(\n (token: string, index) =>\n termsInLowerCase.includes(token.toLowerCase()) ? (\n <mark\n key={`${token}-${index}`}\n role=\"mark\"\n className={styles.highlight}\n data-dtrum-mask={dataDtrumMask}\n data-dtrum-allow={dataDtrumAllow}\n >\n {token}\n </mark>\n ) : (\n <span className={styles.text} key={`${token}-${index}`}>\n {token}\n </span>\n ),\n );\n}\n\n/**\n * Splits text into an array of strings where a given list of terms\n * acts as separator strings.\n */\nfunction getTextTokens(\n textContent: string | number,\n terms: string[],\n caseSensitive: boolean,\n): string[] {\n const flags = caseSensitive ? 'gm' : 'gmi';\n const regExp = new RegExp(\n `(${terms.map((t) => escapeRegExp(t)).join('|')})`,\n flags,\n );\n\n return textContent\n .toString()\n .split(regExp)\n .filter((s) => s.length > 0);\n}\n\n/**\n * Use the `Highlight` component to highlight one or more substrings within a\n * text.\n * @public\n */\nexport const Highlight = (props: HighlightProps): ReactElement => {\n const {\n children,\n term,\n caseSensitive = false,\n 'data-testid': dataTestId,\n 'data-dtrum-mask': dataDtrumMask,\n 'data-dtrum-allow': dataDtrumAllow,\n } = props;\n const intl = useIntl();\n\n return (\n <>\n {highlightChildren(\n intl,\n children,\n term,\n caseSensitive,\n dataTestId,\n dataDtrumMask,\n dataDtrumAllow,\n )}\n </>\n );\n};\n\n(Highlight as typeof Highlight & { displayName: string }).displayName =\n 'Highlight';\n"],
5
- "mappings": "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",
6
- "names": ["Fragment"]
4
+ "sourcesContent": ["import { useEffect, useMemo, useRef, type ReactElement } from 'react';\n\nimport * as styles from './Highlight.sty.js';\nimport { createRangedHighlights } from './utils/create-ranged-highlights.js';\nimport { getOrCreateSharedHighlight } from './utils/get-or-create-shared-highlight.js';\nimport type { DataTestId } from '../../core/types/data-props.js';\nimport type { MaskingProps } from '../../core/types/masking-props.js';\nimport type { WithChildren } from '../../core/types/with-children.js';\nimport { devLog } from '../../core/utils/logging.js';\n\n/**\n * The props for the Highlight component.\n * @public\n */\nexport interface HighlightProps extends WithChildren, DataTestId, MaskingProps {\n /**\n * Either a substring or an array of multiple different substrings that\n * should be highlighted in the projected content.\n * Every occurrence of the string(s) is highlighted accordingly.\n */\n term: string | string[];\n\n /**\n * Property that determines whether the highlighting search is case-sensitive.\n * If set to `true`, the component searches for case sensitive occurrences.\n * @defaultValue false\n */\n caseSensitive?: boolean;\n}\n\n/**\n * Use the `Highlight` component to highlight one or more substrings within a\n * text.\n * @public\n */\nexport const Highlight = (props: HighlightProps): ReactElement => {\n const {\n children,\n term,\n caseSensitive = false,\n 'data-testid': dataTestId,\n 'data-dtrum-mask': dataDtrumMask,\n 'data-dtrum-allow': dataDtrumAllow,\n } = props;\n const rootRef = useRef<HTMLSpanElement>(null);\n\n const terms = useMemo(() => {\n if (Array.isArray(term)) {\n return term.filter((t) => t);\n }\n\n return term ? [term] : [];\n }, [term]);\n\n const highlight = getOrCreateSharedHighlight();\n\n useEffect(() => {\n const currentElement = rootRef.current;\n const storedRanges: Array<Range> = [];\n\n if (currentElement) {\n const ranges = createRangedHighlights(\n currentElement,\n terms,\n caseSensitive,\n highlight,\n );\n storedRanges.push(...ranges);\n }\n\n return () => {\n for (const storedRange of storedRanges) {\n try {\n highlight.delete(storedRange);\n } catch {\n devLog('Failed to delete range', storedRange);\n }\n }\n };\n }, [children, highlight, terms, caseSensitive]);\n\n return (\n <span\n ref={rootRef}\n className={styles.wrapper}\n data-testid={dataTestId}\n data-dtrum-mask={dataDtrumMask}\n data-dtrum-allow={dataDtrumAllow}\n >\n {children}\n </span>\n );\n};\n\n(Highlight as typeof Highlight & { displayName: string }).displayName =\n 'Highlight';\n"],
5
+ "mappings": "AAkFI;AAlFJ,SAAS,WAAW,SAAS,cAAiC;AAE9D,YAAY,YAAY;AACxB,SAAS,8BAA8B;AACvC,SAAS,kCAAkC;AAI3C,SAAS,cAAc;AA2BhB,MAAM,YAAY,CAAC,UAAwC;AAChE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,EACtB,IAAI;AACJ,QAAM,UAAU,OAAwB,IAAI;AAE5C,QAAM,QAAQ,QAAQ,MAAM;AAC1B,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,aAAO,KAAK,OAAO,CAAC,MAAM,CAAC;AAAA,IAC7B;AAEA,WAAO,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,EAC1B,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,YAAY,2BAA2B;AAE7C,YAAU,MAAM;AACd,UAAM,iBAAiB,QAAQ;AAC/B,UAAM,eAA6B,CAAC;AAEpC,QAAI,gBAAgB;AAClB,YAAM,SAAS;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,mBAAa,KAAK,GAAG,MAAM;AAAA,IAC7B;AAEA,WAAO,MAAM;AACX,iBAAW,eAAe,cAAc;AACtC,YAAI;AACF,oBAAU,OAAO,WAAW;AAAA,QAC9B,QAAQ;AACN,iBAAO,0BAA0B,WAAW;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,UAAU,WAAW,OAAO,aAAa,CAAC;AAE9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW,OAAO;AAAA,MAClB,eAAa;AAAA,MACb,mBAAiB;AAAA,MACjB,oBAAkB;AAAA,MAEjB;AAAA;AAAA,EACH;AAEJ;AAEC,UAAyD,cACxD;",
6
+ "names": []
7
7
  }
@@ -1,8 +1,6 @@
1
1
  import "./Highlight.css";
2
- var highlight = "_lajjl30-1-14-0";
3
- var text = "_lajjl31-1-14-0";
2
+ var wrapper = "_lajjl30-1-16-0";
4
3
  export {
5
- highlight,
6
- text
4
+ wrapper
7
5
  };
8
6
  //# sourceMappingURL=Highlight.sty.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/typography/highlight/Highlight.css.ts"],
4
- "sourcesContent": ["import './Highlight.css';\nexport var highlight = '_lajjl30-1-14-0';\nexport var text = '_lajjl31-1-14-0';"],
5
- "mappings": "AAAA,OAAO;AACA,IAAI,YAAY;AAChB,IAAI,OAAO;",
4
+ "sourcesContent": ["import './Highlight.css';\nexport var wrapper = '_lajjl30-1-16-0';"],
5
+ "mappings": "AAAA,OAAO;AACA,IAAI,UAAU;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,51 @@
1
+ import { devLog } from "../../../core/utils/logging.js";
2
+ function collectTextNodes(node, textNodes = []) {
3
+ if (node.nodeType === Node.TEXT_NODE) {
4
+ textNodes.push(node);
5
+ } else {
6
+ for (const child of Array.from(node.childNodes)) {
7
+ collectTextNodes(child, textNodes);
8
+ }
9
+ }
10
+ return textNodes;
11
+ }
12
+ function getTextRangeForHighlight(element, terms, caseSensitive) {
13
+ const textNodes = collectTextNodes(element);
14
+ const ranges = [];
15
+ for (const textNode of textNodes) {
16
+ const textContent = textNode.textContent ?? "";
17
+ const searchText = caseSensitive ? textContent : textContent.toLocaleLowerCase();
18
+ for (const term of terms) {
19
+ const searchTerm = caseSensitive ? term : term.toLocaleLowerCase();
20
+ let index = 0;
21
+ while ((index = searchText.indexOf(searchTerm, index)) !== -1) {
22
+ const range = new Range();
23
+ range.setStart(textNode, index);
24
+ range.setEnd(textNode, index + term.length);
25
+ ranges.push(range);
26
+ index += term.length;
27
+ }
28
+ }
29
+ }
30
+ return ranges;
31
+ }
32
+ function createRangedHighlights(targetElement, terms, caseSensitive, highlight) {
33
+ const storedRanges = [];
34
+ if (terms.length === 0) {
35
+ return storedRanges;
36
+ }
37
+ const ranges = getTextRangeForHighlight(targetElement, terms, caseSensitive);
38
+ for (const range of ranges) {
39
+ try {
40
+ highlight.add(range);
41
+ storedRanges.push(range);
42
+ } catch {
43
+ devLog("Failed to add range", range);
44
+ }
45
+ }
46
+ return storedRanges;
47
+ }
48
+ export {
49
+ createRangedHighlights
50
+ };
51
+ //# sourceMappingURL=create-ranged-highlights.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/typography/highlight/utils/create-ranged-highlights.ts"],
4
+ "sourcesContent": ["import { devLog } from '../../../core/utils/logging.js';\n\n/**\n * Recursively collects all text nodes within a given node.\n * @param node - The node to collect text nodes from.\n * @param textNodes - The array to store collected text nodes.\n * @returns An array with all text nodes.\n */\nfunction collectTextNodes(node: Node, textNodes: Node[] = []): Node[] {\n if (node.nodeType === Node.TEXT_NODE) {\n textNodes.push(node);\n } else {\n for (const child of Array.from(node.childNodes)) {\n collectTextNodes(child, textNodes);\n }\n }\n\n return textNodes;\n}\n\n/**\n * Gets all text ranges for the given search terms.\n * @param element - The element to search.\n * @param terms - The terms to highlight.\n * @param caseSensitive - Whether the search is case-sensitive.\n * @returns An array of ranges matching the search terms.\n */\nfunction getTextRangeForHighlight(\n element: HTMLElement,\n terms: string[],\n caseSensitive: boolean,\n): Range[] {\n const textNodes: Node[] = collectTextNodes(element);\n\n // Collect ranges for all search terms\n const ranges: Range[] = [];\n\n for (const textNode of textNodes) {\n const textContent = textNode.textContent ?? '';\n // Normalize text content if case sensitivity is disabled\n const searchText = caseSensitive\n ? textContent\n : textContent.toLocaleLowerCase();\n\n for (const term of terms) {\n // Normalize search term if case sensitivity is disabled\n const searchTerm = caseSensitive ? term : term.toLocaleLowerCase();\n let index = 0;\n\n while ((index = searchText.indexOf(searchTerm, index)) !== -1) {\n const range = new Range();\n range.setStart(textNode, index);\n range.setEnd(textNode, index + term.length);\n ranges.push(range);\n index += term.length;\n }\n }\n }\n\n return ranges;\n}\n\n/**\n * Creates a local range array that is added to the highlight and returns it.\n * @param targetElement - The element to search within.\n * @param terms - The terms to highlight.\n * @param caseSensitive - Whether the search is case-sensitive.\n * @param highlight - The Highlight instance to add the ranges to.\n * @returns An array of ranges that were added to the highlight.\n * @internal\n */\nexport function createRangedHighlights(\n targetElement: HTMLElement,\n terms: string[],\n caseSensitive: boolean,\n highlight: Set<AbstractRange> | Highlight,\n): Range[] {\n const storedRanges: Range[] = [];\n\n if (terms.length === 0) {\n return storedRanges;\n }\n\n const ranges = getTextRangeForHighlight(targetElement, terms, caseSensitive);\n\n for (const range of ranges) {\n try {\n highlight.add(range);\n storedRanges.push(range);\n } catch {\n devLog('Failed to add range', range);\n }\n }\n\n return storedRanges;\n}\n"],
5
+ "mappings": "AAAA,SAAS,cAAc;AAQvB,SAAS,iBAAiB,MAAY,YAAoB,CAAC,GAAW;AACpE,MAAI,KAAK,aAAa,KAAK,WAAW;AACpC,cAAU,KAAK,IAAI;AAAA,EACrB,OAAO;AACL,eAAW,SAAS,MAAM,KAAK,KAAK,UAAU,GAAG;AAC/C,uBAAiB,OAAO,SAAS;AAAA,IACnC;AAAA,EACF;AAEA,SAAO;AACT;AASA,SAAS,yBACP,SACA,OACA,eACS;AACT,QAAM,YAAoB,iBAAiB,OAAO;AAGlD,QAAM,SAAkB,CAAC;AAEzB,aAAW,YAAY,WAAW;AAChC,UAAM,cAAc,SAAS,eAAe;AAE5C,UAAM,aAAa,gBACf,cACA,YAAY,kBAAkB;AAElC,eAAW,QAAQ,OAAO;AAExB,YAAM,aAAa,gBAAgB,OAAO,KAAK,kBAAkB;AACjE,UAAI,QAAQ;AAEZ,cAAQ,QAAQ,WAAW,QAAQ,YAAY,KAAK,OAAO,IAAI;AAC7D,cAAM,QAAQ,IAAI,MAAM;AACxB,cAAM,SAAS,UAAU,KAAK;AAC9B,cAAM,OAAO,UAAU,QAAQ,KAAK,MAAM;AAC1C,eAAO,KAAK,KAAK;AACjB,iBAAS,KAAK;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAWO,SAAS,uBACd,eACA,OACA,eACA,WACS;AACT,QAAM,eAAwB,CAAC;AAE/B,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,yBAAyB,eAAe,OAAO,aAAa;AAE3E,aAAW,SAAS,QAAQ;AAC1B,QAAI;AACF,gBAAU,IAAI,KAAK;AACnB,mBAAa,KAAK,KAAK;AAAA,IACzB,QAAQ;AACN,aAAO,uBAAuB,KAAK;AAAA,IACrC;AAAA,EACF;AAEA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,25 @@
1
+ import { devLog } from "../../../core/utils/logging.js";
2
+ const HIGHLIGHT_NAME = "strato-typography-highlight";
3
+ let sharedHighlight = null;
4
+ function getOrCreateSharedHighlight() {
5
+ if (sharedHighlight) {
6
+ return sharedHighlight;
7
+ }
8
+ if ("Highlight" in window) {
9
+ sharedHighlight = new Highlight();
10
+ if (sharedHighlight instanceof Highlight) {
11
+ CSS.highlights.set(HIGHLIGHT_NAME, sharedHighlight);
12
+ }
13
+ } else {
14
+ sharedHighlight = /* @__PURE__ */ new Set();
15
+ devLog(
16
+ "CSS Highlight API is not supported in this browser. Text highlighting will not be visible."
17
+ );
18
+ }
19
+ return sharedHighlight;
20
+ }
21
+ export {
22
+ HIGHLIGHT_NAME,
23
+ getOrCreateSharedHighlight
24
+ };
25
+ //# sourceMappingURL=get-or-create-shared-highlight.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/typography/highlight/utils/get-or-create-shared-highlight.ts"],
4
+ "sourcesContent": ["import { devLog } from '../../../core/utils/logging.js';\n\nexport const HIGHLIGHT_NAME = 'strato-typography-highlight';\nlet sharedHighlight: Set<AbstractRange> | Highlight | null = null;\n\n/**\n * Gets or creates the shared text highlight.\n * All Highlight components share the same highlight instance.\n * @internal\n */\nexport function getOrCreateSharedHighlight(): Set<AbstractRange> | Highlight {\n if (sharedHighlight) {\n return sharedHighlight;\n }\n\n if ('Highlight' in window) {\n sharedHighlight = new Highlight();\n if (sharedHighlight instanceof Highlight) {\n CSS.highlights.set(HIGHLIGHT_NAME, sharedHighlight);\n }\n } else {\n // Fallback for browsers without CSS Highlight API support\n sharedHighlight = new Set();\n devLog(\n 'CSS Highlight API is not supported in this browser. Text highlighting will not be visible.',\n );\n }\n\n return sharedHighlight;\n}\n"],
5
+ "mappings": "AAAA,SAAS,cAAc;AAEhB,MAAM,iBAAiB;AAC9B,IAAI,kBAAyD;AAOtD,SAAS,6BAA6D;AAC3E,MAAI,iBAAiB;AACnB,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,QAAQ;AACzB,sBAAkB,IAAI,UAAU;AAChC,QAAI,2BAA2B,WAAW;AACxC,UAAI,WAAW,IAAI,gBAAgB,eAAe;AAAA,IACpD;AAAA,EACF,OAAO;AAEL,sBAAkB,oBAAI,IAAI;AAC1B;AAAA,MACE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -1,12 +1,12 @@
1
- ._1iksxp40-1-14-0 {
1
+ ._1iksxp40-1-16-0 {
2
2
  display: inline;
3
3
  color: var(--dt-colors-text-primary-default, #464cce);
4
4
  text-decoration: underline;
5
5
  overflow-wrap: anywhere;
6
6
  }
7
- ._1iksxp40-1-14-0:hover {
7
+ ._1iksxp40-1-16-0:hover {
8
8
  color: var(--dt-colors-text-primary-default-hover, #3431b3);
9
9
  }
10
- ._1iksxp40-1-14-0:active {
10
+ ._1iksxp40-1-16-0:active {
11
11
  color: var(--dt-colors-text-primary-default-active, #250f98);
12
12
  }
@@ -1,5 +1,5 @@
1
1
  import "./Link.css";
2
- var link = "_1iksxp40-1-14-0";
2
+ var link = "_1iksxp40-1-16-0";
3
3
  export {
4
4
  link
5
5
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/typography/link/Link.css.ts"],
4
- "sourcesContent": ["import './Link.css';\nexport var link = '_1iksxp40-1-14-0';"],
4
+ "sourcesContent": ["import './Link.css';\nexport var link = '_1iksxp40-1-16-0';"],
5
5
  "mappings": "AAAA,OAAO;AACA,IAAI,OAAO;",
6
6
  "names": []
7
7
  }
@@ -1,16 +1,16 @@
1
- ._16276mt0-1-14-0 {
1
+ ._16276mt0-1-16-0 {
2
2
  margin: 0;
3
3
  padding-left: var(--dt-spacings-size-40, 40px);
4
4
  }
5
- ._16276mt0-1-14-0 ._16276mt0-1-14-0 {
5
+ ._16276mt0-1-16-0 ._16276mt0-1-16-0 {
6
6
  margin-block: var(--dt-spacings-size-4, 4px);
7
7
  padding-left: var(--dt-spacings-size-28, 28px);
8
8
  }
9
- ._16276mt1-1-14-0 {
9
+ ._16276mt1-1-16-0 {
10
10
  position: relative;
11
11
  overflow-wrap: break-word;
12
12
  margin-block: var(--dt-spacings-size-2, 2px);
13
13
  }
14
- ._16276mt1-1-14-0::marker {
14
+ ._16276mt1-1-16-0::marker {
15
15
  font-weight: var(--dt-typography-text-base-emphasized-weight, 500);
16
16
  }
@@ -1,6 +1,6 @@
1
1
  import "./List.css";
2
- var listCSS = "_16276mt0-1-14-0";
3
- var listItemCSS = "_16276mt1-1-14-0";
2
+ var listCSS = "_16276mt0-1-16-0";
3
+ var listItemCSS = "_16276mt1-1-16-0";
4
4
  export {
5
5
  listCSS,
6
6
  listItemCSS
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/typography/list/List.css.ts"],
4
- "sourcesContent": ["import './List.css';\nexport var listCSS = '_16276mt0-1-14-0';\nexport var listItemCSS = '_16276mt1-1-14-0';"],
4
+ "sourcesContent": ["import './List.css';\nexport var listCSS = '_16276mt0-1-16-0';\nexport var listItemCSS = '_16276mt1-1-16-0';"],
5
5
  "mappings": "AAAA,OAAO;AACA,IAAI,UAAU;AACd,IAAI,cAAc;",
6
6
  "names": []
7
7
  }
@@ -1,17 +1,17 @@
1
- ._487p2n0-1-14-0 {
1
+ ._487p2n0-1-16-0 {
2
2
  margin-top: 0;
3
3
  margin-bottom: 0;
4
4
  overflow-wrap: break-word;
5
5
  color: inherit;
6
6
  font-style: normal;
7
7
  }
8
- ._487p2n1-1-14-0 {
8
+ ._487p2n1-1-16-0 {
9
9
  display: block;
10
10
  white-space: nowrap;
11
11
  text-overflow: ellipsis;
12
12
  overflow: hidden;
13
13
  }
14
- ._487p2n2-1-14-0 {
14
+ ._487p2n2-1-16-0 {
15
15
  display: -webkit-box;
16
16
  -webkit-line-clamp: var(--strato-ellipsis-line-clamp);
17
17
  -webkit-box-orient: vertical;
@@ -1,8 +1,8 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import clsx from "clsx";
3
3
  import { forwardRef } from "react";
4
- import { paragraphCSS } from "./Paragraph.sty.js";
5
- import { textStyleCSS } from "../../styles/textStyle.sty.js";
4
+ import { paragraph } from "./Paragraph.sty.js";
5
+ import { textStyle } from "../../styles/textStyle.sty.js";
6
6
  const Paragraph = /* @__PURE__ */ forwardRef((props, ref) => {
7
7
  const {
8
8
  children,
@@ -29,11 +29,7 @@ const Paragraph = /* @__PURE__ */ forwardRef((props, ref) => {
29
29
  "data-testid": dataTestId,
30
30
  "data-dtrum-mask": dataDtrumMask,
31
31
  "data-dtrum-allow": dataDtrumAllow,
32
- className: clsx(
33
- paragraphCSS({ ellipsis }),
34
- textStyleCSS(),
35
- consumerClassName
36
- ),
32
+ className: clsx(paragraph({ ellipsis }), textStyle(), consumerClassName),
37
33
  style: {
38
34
  ...consumerStyle,
39
35
  "--strato-ellipsis-line-clamp": maxLines
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/typography/paragraph/Paragraph.tsx"],
4
- "sourcesContent": ["import clsx from 'clsx';\nimport { type CSSProperties, forwardRef } from 'react';\n\nimport { paragraphCSS } from './Paragraph.sty.js';\nimport type { DataTestId } from '../../core/types/data-props.js';\nimport type { DOMProps } from '../../core/types/dom.js';\nimport type { MaskingProps } from '../../core/types/masking-props.js';\nimport type { StylingProps } from '../../core/types/styling-props.js';\nimport type { WithChildren } from '../../core/types/with-children.js';\nimport { textStyleCSS } from '../../styles/textStyle.sty.js';\n\n/**\n * The props for the Paragraph component.\n * @public\n * */\nexport interface ParagraphProps\n extends WithChildren,\n DOMProps,\n StylingProps,\n DataTestId,\n MaskingProps {\n /**\n * Limits the text to the given number of lines and adds ellipsis if the text would need more lines.\n */\n maxLines?: number;\n}\n\n/**\n * The `Paragraph` component displays a block of text with the default text style and supports text truncation.\n * @public\n */\nexport const Paragraph = /* @__PURE__ */ forwardRef<\n HTMLParagraphElement,\n ParagraphProps\n>((props, ref) => {\n const {\n children,\n maxLines,\n className: consumerClassName,\n style: consumerStyle,\n 'data-testid': dataTestId,\n 'data-dtrum-mask': dataDtrumMask,\n 'data-dtrum-allow': dataDtrumAllow,\n ...remainingProps\n } = props;\n\n let ellipsis: undefined | 'singleLine' | 'multiLine';\n if (maxLines === undefined || maxLines === 0) {\n ellipsis = undefined;\n } else if (maxLines === 1) {\n ellipsis = 'singleLine';\n } else {\n ellipsis = 'multiLine';\n }\n\n return (\n <p\n ref={ref}\n data-testid={dataTestId}\n data-dtrum-mask={dataDtrumMask}\n data-dtrum-allow={dataDtrumAllow}\n className={clsx(\n paragraphCSS({ ellipsis }),\n textStyleCSS(),\n consumerClassName,\n )}\n style={\n {\n ...consumerStyle,\n '--strato-ellipsis-line-clamp': maxLines,\n } as CSSProperties\n }\n {...remainingProps}\n >\n {children}\n </p>\n );\n});\n(Paragraph as typeof Paragraph & { displayName: string }).displayName =\n 'Paragraph';\n"],
5
- "mappings": "AAwDI;AAxDJ,OAAO,UAAU;AACjB,SAA6B,kBAAkB;AAE/C,SAAS,oBAAoB;AAM7B,SAAS,oBAAoB;AAsBtB,MAAM,YAA4B,2BAGvC,CAAC,OAAO,QAAQ;AAChB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,IACP,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,IACpB,GAAG;AAAA,EACL,IAAI;AAEJ,MAAI;AACJ,MAAI,aAAa,UAAa,aAAa,GAAG;AAC5C,eAAW;AAAA,EACb,WAAW,aAAa,GAAG;AACzB,eAAW;AAAA,EACb,OAAO;AACL,eAAW;AAAA,EACb;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,eAAa;AAAA,MACb,mBAAiB;AAAA,MACjB,oBAAkB;AAAA,MAClB,WAAW;AAAA,QACT,aAAa,EAAE,SAAS,CAAC;AAAA,QACzB,aAAa;AAAA,QACb;AAAA,MACF;AAAA,MACA,OACE;AAAA,QACE,GAAG;AAAA,QACH,gCAAgC;AAAA,MAClC;AAAA,MAED,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ,CAAC;AACA,UAAyD,cACxD;",
4
+ "sourcesContent": ["import clsx from 'clsx';\nimport { type CSSProperties, forwardRef } from 'react';\n\nimport { paragraph } from './Paragraph.sty.js';\nimport type { DataTestId } from '../../core/types/data-props.js';\nimport type { DOMProps } from '../../core/types/dom.js';\nimport type { MaskingProps } from '../../core/types/masking-props.js';\nimport type { StylingProps } from '../../core/types/styling-props.js';\nimport type { WithChildren } from '../../core/types/with-children.js';\nimport { textStyle } from '../../styles/textStyle.sty.js';\n\n/**\n * The props for the Paragraph component.\n * @public\n * */\nexport interface ParagraphProps\n extends WithChildren,\n DOMProps,\n StylingProps,\n DataTestId,\n MaskingProps {\n /**\n * Limits the text to the given number of lines and adds ellipsis if the text would need more lines.\n */\n maxLines?: number;\n}\n\n/**\n * The `Paragraph` component displays a block of text with the default text style and supports text truncation.\n * @public\n */\nexport const Paragraph = /* @__PURE__ */ forwardRef<\n HTMLParagraphElement,\n ParagraphProps\n>((props, ref) => {\n const {\n children,\n maxLines,\n className: consumerClassName,\n style: consumerStyle,\n 'data-testid': dataTestId,\n 'data-dtrum-mask': dataDtrumMask,\n 'data-dtrum-allow': dataDtrumAllow,\n ...remainingProps\n } = props;\n\n let ellipsis: undefined | 'singleLine' | 'multiLine';\n if (maxLines === undefined || maxLines === 0) {\n ellipsis = undefined;\n } else if (maxLines === 1) {\n ellipsis = 'singleLine';\n } else {\n ellipsis = 'multiLine';\n }\n\n return (\n <p\n ref={ref}\n data-testid={dataTestId}\n data-dtrum-mask={dataDtrumMask}\n data-dtrum-allow={dataDtrumAllow}\n className={clsx(paragraph({ ellipsis }), textStyle(), consumerClassName)}\n style={\n {\n ...consumerStyle,\n '--strato-ellipsis-line-clamp': maxLines,\n } as CSSProperties\n }\n {...remainingProps}\n >\n {children}\n </p>\n );\n});\n(Paragraph as typeof Paragraph & { displayName: string }).displayName =\n 'Paragraph';\n"],
5
+ "mappings": "AAwDI;AAxDJ,OAAO,UAAU;AACjB,SAA6B,kBAAkB;AAE/C,SAAS,iBAAiB;AAM1B,SAAS,iBAAiB;AAsBnB,MAAM,YAA4B,2BAGvC,CAAC,OAAO,QAAQ;AAChB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,IACP,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,IACpB,GAAG;AAAA,EACL,IAAI;AAEJ,MAAI;AACJ,MAAI,aAAa,UAAa,aAAa,GAAG;AAC5C,eAAW;AAAA,EACb,WAAW,aAAa,GAAG;AACzB,eAAW;AAAA,EACb,OAAO;AACL,eAAW;AAAA,EACb;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,eAAa;AAAA,MACb,mBAAiB;AAAA,MACjB,oBAAkB;AAAA,MAClB,WAAW,KAAK,UAAU,EAAE,SAAS,CAAC,GAAG,UAAU,GAAG,iBAAiB;AAAA,MACvE,OACE;AAAA,QACE,GAAG;AAAA,QACH,gCAAgC;AAAA,MAClC;AAAA,MAED,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ,CAAC;AACA,UAAyD,cACxD;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import "./Paragraph.css";
2
2
  import { createRuntimeFn as _7a468 } from "@vanilla-extract/recipes/createRuntimeFn";
3
- var paragraphCSS = _7a468({ defaultClassName: "_487p2n0-1-14-0", variantClassNames: { ellipsis: { singleLine: "_487p2n1-1-14-0", multiLine: "_487p2n2-1-14-0" } }, defaultVariants: {}, compoundVariants: [] });
3
+ var paragraph = _7a468({ defaultClassName: "_487p2n0-1-16-0", variantClassNames: { ellipsis: { singleLine: "_487p2n1-1-16-0", multiLine: "_487p2n2-1-16-0" } }, defaultVariants: {}, compoundVariants: [] });
4
4
  export {
5
- paragraphCSS
5
+ paragraph
6
6
  };
7
7
  //# sourceMappingURL=Paragraph.sty.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/typography/paragraph/Paragraph.css.ts"],
4
- "sourcesContent": ["import './Paragraph.css';\nimport { createRuntimeFn as _7a468 } from '@vanilla-extract/recipes/createRuntimeFn';\nexport var paragraphCSS = _7a468({defaultClassName:'_487p2n0-1-14-0',variantClassNames:{ellipsis:{singleLine:'_487p2n1-1-14-0',multiLine:'_487p2n2-1-14-0'}},defaultVariants:{},compoundVariants:[]});"],
5
- "mappings": "AAAA,OAAO;AACP,SAAS,mBAAmB,cAAc;AACnC,IAAI,eAAe,OAAO,EAAC,kBAAiB,mBAAkB,mBAAkB,EAAC,UAAS,EAAC,YAAW,mBAAkB,WAAU,kBAAiB,EAAC,GAAE,iBAAgB,CAAC,GAAE,kBAAiB,CAAC,EAAC,CAAC;",
4
+ "sourcesContent": ["import './Paragraph.css';\nimport { createRuntimeFn as _7a468 } from '@vanilla-extract/recipes/createRuntimeFn';\nexport var paragraph = _7a468({defaultClassName:'_487p2n0-1-16-0',variantClassNames:{ellipsis:{singleLine:'_487p2n1-1-16-0',multiLine:'_487p2n2-1-16-0'}},defaultVariants:{},compoundVariants:[]});"],
5
+ "mappings": "AAAA,OAAO;AACP,SAAS,mBAAmB,cAAc;AACnC,IAAI,YAAY,OAAO,EAAC,kBAAiB,mBAAkB,mBAAkB,EAAC,UAAS,EAAC,YAAW,mBAAkB,WAAU,kBAAiB,EAAC,GAAE,iBAAgB,CAAC,GAAE,kBAAiB,CAAC,EAAC,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
- ._4oao6y0-1-14-0 {
1
+ ._4oao6y0-1-16-0 {
2
2
  text-decoration: line-through;
3
3
  text-decoration-style: solid;
4
4
  overflow-wrap: break-word;
@@ -1,5 +1,5 @@
1
1
  import "./Strikethrough.css";
2
- var strikethroughCSS = "_4oao6y0-1-14-0";
2
+ var strikethroughCSS = "_4oao6y0-1-16-0";
3
3
  export {
4
4
  strikethroughCSS
5
5
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/typography/strikethrough/Strikethrough.css.ts"],
4
- "sourcesContent": ["import './Strikethrough.css';\nexport var strikethroughCSS = '_4oao6y0-1-14-0';"],
4
+ "sourcesContent": ["import './Strikethrough.css';\nexport var strikethroughCSS = '_4oao6y0-1-16-0';"],
5
5
  "mappings": "AAAA,OAAO;AACA,IAAI,mBAAmB;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
- ._wxp4dd0-1-14-0 {
1
+ ._wxp4dd0-1-16-0 {
2
2
  font-weight: var(--dt-typography-text-base-emphasized-weight, 500);
3
3
  overflow-wrap: break-word;
4
4
  }
@@ -1,5 +1,5 @@
1
1
  import "./Strong.css";
2
- var strongCSS = "_wxp4dd0-1-14-0";
2
+ var strongCSS = "_wxp4dd0-1-16-0";
3
3
  export {
4
4
  strongCSS
5
5
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/typography/strong/Strong.css.ts"],
4
- "sourcesContent": ["import './Strong.css';\nexport var strongCSS = '_wxp4dd0-1-14-0';"],
4
+ "sourcesContent": ["import './Strong.css';\nexport var strongCSS = '_wxp4dd0-1-16-0';"],
5
5
  "mappings": "AAAA,OAAO;AACA,IAAI,YAAY;",
6
6
  "names": []
7
7
  }
@@ -1,16 +1,16 @@
1
- ._rup8ap0-1-14-0 {
1
+ ._rup8ap0-1-16-0 {
2
2
  margin-top: 0;
3
3
  margin-bottom: 0;
4
4
  min-width: 0;
5
5
  overflow-wrap: break-word;
6
6
  }
7
- ._rup8ap1-1-14-0 {
7
+ ._rup8ap1-1-16-0 {
8
8
  display: block;
9
9
  white-space: nowrap;
10
10
  text-overflow: ellipsis;
11
11
  overflow: hidden;
12
12
  }
13
- ._rup8ap2-1-14-0 {
13
+ ._rup8ap2-1-16-0 {
14
14
  display: -webkit-box;
15
15
  -webkit-line-clamp: var(--strato-ellipsis-line-clamp);
16
16
  -webkit-box-orient: vertical;