@chayns-components/core 5.5.29 → 5.5.31-alpha.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 (259) hide show
  1. package/AGENTS.md +10 -0
  2. package/lib/cjs/components/accordion/Accordion.js +10 -0
  3. package/lib/cjs/components/accordion/Accordion.js.map +1 -1
  4. package/lib/cjs/components/accordion/Accordion.styles.js +0 -2
  5. package/lib/cjs/components/accordion/Accordion.styles.js.map +1 -1
  6. package/lib/cjs/components/amount-control/AmountControl.js +14 -3
  7. package/lib/cjs/components/amount-control/AmountControl.js.map +1 -1
  8. package/lib/cjs/components/amount-control/AmountControl.styles.js +0 -17
  9. package/lib/cjs/components/amount-control/AmountControl.styles.js.map +1 -1
  10. package/lib/cjs/components/button/Button.js +6 -1
  11. package/lib/cjs/components/button/Button.js.map +1 -1
  12. package/lib/cjs/components/button/Button.styles.js +0 -10
  13. package/lib/cjs/components/button/Button.styles.js.map +1 -1
  14. package/lib/cjs/components/checkbox/Checkbox.js +8 -1
  15. package/lib/cjs/components/checkbox/Checkbox.js.map +1 -1
  16. package/lib/cjs/components/checkbox/Checkbox.styles.js +0 -10
  17. package/lib/cjs/components/checkbox/Checkbox.styles.js.map +1 -1
  18. package/lib/cjs/components/combobox/ComboBox.js +7 -1
  19. package/lib/cjs/components/combobox/ComboBox.js.map +1 -1
  20. package/lib/cjs/components/combobox/ComboBox.styles.js +3 -10
  21. package/lib/cjs/components/combobox/ComboBox.styles.js.map +1 -1
  22. package/lib/cjs/components/context-menu/ContextMenu.js +12 -0
  23. package/lib/cjs/components/context-menu/ContextMenu.js.map +1 -1
  24. package/lib/cjs/components/context-menu/ContextMenu.styles.js +7 -35
  25. package/lib/cjs/components/context-menu/ContextMenu.styles.js.map +1 -1
  26. package/lib/cjs/components/copyable-content/CopyableContent.js +8 -1
  27. package/lib/cjs/components/copyable-content/CopyableContent.js.map +1 -1
  28. package/lib/cjs/components/copyable-content/CopyableContent.styles.js +7 -2
  29. package/lib/cjs/components/copyable-content/CopyableContent.styles.js.map +1 -1
  30. package/lib/cjs/components/file-list/file-item/FileItem.js +7 -0
  31. package/lib/cjs/components/file-list/file-item/FileItem.js.map +1 -1
  32. package/lib/cjs/components/file-list/file-item/FileItem.styles.js +1 -11
  33. package/lib/cjs/components/file-list/file-item/FileItem.styles.js.map +1 -1
  34. package/lib/cjs/components/file-select/FileSelect.js +12 -3
  35. package/lib/cjs/components/file-select/FileSelect.js.map +1 -1
  36. package/lib/cjs/components/file-select/FileSelect.styles.js +3 -9
  37. package/lib/cjs/components/file-select/FileSelect.styles.js.map +1 -1
  38. package/lib/cjs/components/filter/Filter.js +44 -16
  39. package/lib/cjs/components/filter/Filter.js.map +1 -1
  40. package/lib/cjs/components/filter/Filter.styles.js +2 -2
  41. package/lib/cjs/components/filter/Filter.styles.js.map +1 -1
  42. package/lib/cjs/components/filter-buttons/filter-button/FilterButton.js +9 -1
  43. package/lib/cjs/components/filter-buttons/filter-button/FilterButton.js.map +1 -1
  44. package/lib/cjs/components/filter-buttons/filter-button/FilterButton.styles.js +0 -2
  45. package/lib/cjs/components/filter-buttons/filter-button/FilterButton.styles.js.map +1 -1
  46. package/lib/cjs/components/grid-image/GridImage.js +7 -1
  47. package/lib/cjs/components/grid-image/GridImage.js.map +1 -1
  48. package/lib/cjs/components/grid-image/GridImage.styles.js +5 -10
  49. package/lib/cjs/components/grid-image/GridImage.styles.js.map +1 -1
  50. package/lib/cjs/components/grouped-image/GroupedImage.js +8 -2
  51. package/lib/cjs/components/grouped-image/GroupedImage.js.map +1 -1
  52. package/lib/cjs/components/grouped-image/GroupedImage.styles.js +3 -8
  53. package/lib/cjs/components/grouped-image/GroupedImage.styles.js.map +1 -1
  54. package/lib/cjs/components/highlight-slider/highlight-slider-item/HighlightSliderItem.js +7 -2
  55. package/lib/cjs/components/highlight-slider/highlight-slider-item/HighlightSliderItem.js.map +1 -1
  56. package/lib/cjs/components/highlight-slider/highlight-slider-item/HighlightSliderItem.styles.js +5 -10
  57. package/lib/cjs/components/highlight-slider/highlight-slider-item/HighlightSliderItem.styles.js.map +1 -1
  58. package/lib/cjs/components/icon/Icon.js +10 -2
  59. package/lib/cjs/components/icon/Icon.js.map +1 -1
  60. package/lib/cjs/components/icon/Icon.styles.js +4 -22
  61. package/lib/cjs/components/icon/Icon.styles.js.map +1 -1
  62. package/lib/cjs/components/input/Input.js +14 -2
  63. package/lib/cjs/components/input/Input.js.map +1 -1
  64. package/lib/cjs/components/input/Input.styles.js +0 -3
  65. package/lib/cjs/components/input/Input.styles.js.map +1 -1
  66. package/lib/cjs/components/list/List.utils.js +3 -9
  67. package/lib/cjs/components/list/List.utils.js.map +1 -1
  68. package/lib/cjs/components/list/list-item/ListItem.js +13 -2
  69. package/lib/cjs/components/list/list-item/ListItem.js.map +1 -1
  70. package/lib/cjs/components/list/list-item/ListItem.styles.js +9 -2
  71. package/lib/cjs/components/list/list-item/ListItem.styles.js.map +1 -1
  72. package/lib/cjs/components/list/list-item/list-item-head/ListItemHead.js +5 -4
  73. package/lib/cjs/components/list/list-item/list-item-head/ListItemHead.js.map +1 -1
  74. package/lib/cjs/components/list/list-item/list-item-head/list-item-image/ListItemImage.js +2 -5
  75. package/lib/cjs/components/list/list-item/list-item-head/list-item-image/ListItemImage.js.map +1 -1
  76. package/lib/cjs/components/multi-action-button/action-button/ActionButton.js +8 -2
  77. package/lib/cjs/components/multi-action-button/action-button/ActionButton.js.map +1 -1
  78. package/lib/cjs/components/multi-action-button/action-button/ActionButton.styles.js +3 -12
  79. package/lib/cjs/components/multi-action-button/action-button/ActionButton.styles.js.map +1 -1
  80. package/lib/cjs/components/radio-button/RadioButton.js +7 -1
  81. package/lib/cjs/components/radio-button/RadioButton.js.map +1 -1
  82. package/lib/cjs/components/radio-button/RadioButton.styles.js +0 -10
  83. package/lib/cjs/components/radio-button/RadioButton.styles.js.map +1 -1
  84. package/lib/cjs/components/search-input/SearchInput.js +9 -10
  85. package/lib/cjs/components/search-input/SearchInput.js.map +1 -1
  86. package/lib/cjs/components/search-input/SearchInput.styles.js +5 -15
  87. package/lib/cjs/components/search-input/SearchInput.styles.js.map +1 -1
  88. package/lib/cjs/components/sharing-bar/SharingBar.js +13 -0
  89. package/lib/cjs/components/sharing-bar/SharingBar.js.map +1 -1
  90. package/lib/cjs/components/sharing-bar/SharingBar.styles.js +1 -5
  91. package/lib/cjs/components/sharing-bar/SharingBar.styles.js.map +1 -1
  92. package/lib/cjs/components/slider/Slider.js +13 -6
  93. package/lib/cjs/components/slider/Slider.js.map +1 -1
  94. package/lib/cjs/components/slider/Slider.styles.js +2 -9
  95. package/lib/cjs/components/slider/Slider.styles.js.map +1 -1
  96. package/lib/cjs/components/slider-button/SliderButton.js +6 -2
  97. package/lib/cjs/components/slider-button/SliderButton.js.map +1 -1
  98. package/lib/cjs/components/slider-button/SliderButton.styles.js +2 -15
  99. package/lib/cjs/components/slider-button/SliderButton.styles.js.map +1 -1
  100. package/lib/cjs/components/tag-input/TagInput.js +8 -1
  101. package/lib/cjs/components/tag-input/TagInput.js.map +1 -1
  102. package/lib/cjs/components/tag-input/TagInput.styles.js +1 -3
  103. package/lib/cjs/components/tag-input/TagInput.styles.js.map +1 -1
  104. package/lib/cjs/components/text-area/TextArea.js +68 -56
  105. package/lib/cjs/components/text-area/TextArea.js.map +1 -1
  106. package/lib/cjs/components/text-area/TextArea.styles.js +0 -2
  107. package/lib/cjs/components/text-area/TextArea.styles.js.map +1 -1
  108. package/lib/cjs/components/truncation/Truncation.js +9 -5
  109. package/lib/cjs/components/truncation/Truncation.js.map +1 -1
  110. package/lib/cjs/components/truncation/Truncation.styles.js +0 -11
  111. package/lib/cjs/components/truncation/Truncation.styles.js.map +1 -1
  112. package/lib/cjs/hooks/useFocusRingPortal.js +197 -0
  113. package/lib/cjs/hooks/useFocusRingPortal.js.map +1 -0
  114. package/lib/cjs/hooks/useKeyboardFocusHighlighting.js +9 -3
  115. package/lib/cjs/hooks/useKeyboardFocusHighlighting.js.map +1 -1
  116. package/lib/cjs/index.js +14 -0
  117. package/lib/cjs/index.js.map +1 -1
  118. package/lib/esm/components/accordion/Accordion.js +10 -0
  119. package/lib/esm/components/accordion/Accordion.js.map +1 -1
  120. package/lib/esm/components/accordion/Accordion.styles.js +0 -2
  121. package/lib/esm/components/accordion/Accordion.styles.js.map +1 -1
  122. package/lib/esm/components/amount-control/AmountControl.js +14 -3
  123. package/lib/esm/components/amount-control/AmountControl.js.map +1 -1
  124. package/lib/esm/components/amount-control/AmountControl.styles.js +0 -17
  125. package/lib/esm/components/amount-control/AmountControl.styles.js.map +1 -1
  126. package/lib/esm/components/button/Button.js +7 -2
  127. package/lib/esm/components/button/Button.js.map +1 -1
  128. package/lib/esm/components/button/Button.styles.js +0 -10
  129. package/lib/esm/components/button/Button.styles.js.map +1 -1
  130. package/lib/esm/components/checkbox/Checkbox.js +8 -1
  131. package/lib/esm/components/checkbox/Checkbox.js.map +1 -1
  132. package/lib/esm/components/checkbox/Checkbox.styles.js +0 -10
  133. package/lib/esm/components/checkbox/Checkbox.styles.js.map +1 -1
  134. package/lib/esm/components/combobox/ComboBox.js +7 -1
  135. package/lib/esm/components/combobox/ComboBox.js.map +1 -1
  136. package/lib/esm/components/combobox/ComboBox.styles.js +3 -10
  137. package/lib/esm/components/combobox/ComboBox.styles.js.map +1 -1
  138. package/lib/esm/components/context-menu/ContextMenu.js +11 -0
  139. package/lib/esm/components/context-menu/ContextMenu.js.map +1 -1
  140. package/lib/esm/components/context-menu/ContextMenu.styles.js +7 -35
  141. package/lib/esm/components/context-menu/ContextMenu.styles.js.map +1 -1
  142. package/lib/esm/components/copyable-content/CopyableContent.js +8 -1
  143. package/lib/esm/components/copyable-content/CopyableContent.js.map +1 -1
  144. package/lib/esm/components/copyable-content/CopyableContent.styles.js +7 -2
  145. package/lib/esm/components/copyable-content/CopyableContent.styles.js.map +1 -1
  146. package/lib/esm/components/file-list/file-item/FileItem.js +8 -1
  147. package/lib/esm/components/file-list/file-item/FileItem.js.map +1 -1
  148. package/lib/esm/components/file-list/file-item/FileItem.styles.js +1 -11
  149. package/lib/esm/components/file-list/file-item/FileItem.styles.js.map +1 -1
  150. package/lib/esm/components/file-select/FileSelect.js +13 -4
  151. package/lib/esm/components/file-select/FileSelect.js.map +1 -1
  152. package/lib/esm/components/file-select/FileSelect.styles.js +3 -9
  153. package/lib/esm/components/file-select/FileSelect.styles.js.map +1 -1
  154. package/lib/esm/components/filter/Filter.js +43 -16
  155. package/lib/esm/components/filter/Filter.js.map +1 -1
  156. package/lib/esm/components/filter/Filter.styles.js +2 -2
  157. package/lib/esm/components/filter/Filter.styles.js.map +1 -1
  158. package/lib/esm/components/filter-buttons/filter-button/FilterButton.js +10 -2
  159. package/lib/esm/components/filter-buttons/filter-button/FilterButton.js.map +1 -1
  160. package/lib/esm/components/filter-buttons/filter-button/FilterButton.styles.js +0 -2
  161. package/lib/esm/components/filter-buttons/filter-button/FilterButton.styles.js.map +1 -1
  162. package/lib/esm/components/grid-image/GridImage.js +8 -2
  163. package/lib/esm/components/grid-image/GridImage.js.map +1 -1
  164. package/lib/esm/components/grid-image/GridImage.styles.js +4 -9
  165. package/lib/esm/components/grid-image/GridImage.styles.js.map +1 -1
  166. package/lib/esm/components/grouped-image/GroupedImage.js +9 -3
  167. package/lib/esm/components/grouped-image/GroupedImage.js.map +1 -1
  168. package/lib/esm/components/grouped-image/GroupedImage.styles.js +3 -8
  169. package/lib/esm/components/grouped-image/GroupedImage.styles.js.map +1 -1
  170. package/lib/esm/components/highlight-slider/highlight-slider-item/HighlightSliderItem.js +8 -3
  171. package/lib/esm/components/highlight-slider/highlight-slider-item/HighlightSliderItem.js.map +1 -1
  172. package/lib/esm/components/highlight-slider/highlight-slider-item/HighlightSliderItem.styles.js +4 -9
  173. package/lib/esm/components/highlight-slider/highlight-slider-item/HighlightSliderItem.styles.js.map +1 -1
  174. package/lib/esm/components/icon/Icon.js +9 -2
  175. package/lib/esm/components/icon/Icon.js.map +1 -1
  176. package/lib/esm/components/icon/Icon.styles.js +4 -22
  177. package/lib/esm/components/icon/Icon.styles.js.map +1 -1
  178. package/lib/esm/components/input/Input.js +14 -2
  179. package/lib/esm/components/input/Input.js.map +1 -1
  180. package/lib/esm/components/input/Input.styles.js +0 -3
  181. package/lib/esm/components/input/Input.styles.js.map +1 -1
  182. package/lib/esm/components/list/List.utils.js +1 -6
  183. package/lib/esm/components/list/List.utils.js.map +1 -1
  184. package/lib/esm/components/list/list-item/ListItem.js +13 -2
  185. package/lib/esm/components/list/list-item/ListItem.js.map +1 -1
  186. package/lib/esm/components/list/list-item/ListItem.styles.js +9 -2
  187. package/lib/esm/components/list/list-item/ListItem.styles.js.map +1 -1
  188. package/lib/esm/components/list/list-item/list-item-head/ListItemHead.js +5 -4
  189. package/lib/esm/components/list/list-item/list-item-head/ListItemHead.js.map +1 -1
  190. package/lib/esm/components/list/list-item/list-item-head/list-item-image/ListItemImage.js +2 -5
  191. package/lib/esm/components/list/list-item/list-item-head/list-item-image/ListItemImage.js.map +1 -1
  192. package/lib/esm/components/multi-action-button/action-button/ActionButton.js +7 -2
  193. package/lib/esm/components/multi-action-button/action-button/ActionButton.js.map +1 -1
  194. package/lib/esm/components/multi-action-button/action-button/ActionButton.styles.js +3 -12
  195. package/lib/esm/components/multi-action-button/action-button/ActionButton.styles.js.map +1 -1
  196. package/lib/esm/components/radio-button/RadioButton.js +7 -1
  197. package/lib/esm/components/radio-button/RadioButton.js.map +1 -1
  198. package/lib/esm/components/radio-button/RadioButton.styles.js +0 -10
  199. package/lib/esm/components/radio-button/RadioButton.styles.js.map +1 -1
  200. package/lib/esm/components/search-input/SearchInput.js +9 -10
  201. package/lib/esm/components/search-input/SearchInput.js.map +1 -1
  202. package/lib/esm/components/search-input/SearchInput.styles.js +5 -15
  203. package/lib/esm/components/search-input/SearchInput.styles.js.map +1 -1
  204. package/lib/esm/components/sharing-bar/SharingBar.js +12 -0
  205. package/lib/esm/components/sharing-bar/SharingBar.js.map +1 -1
  206. package/lib/esm/components/sharing-bar/SharingBar.styles.js +1 -5
  207. package/lib/esm/components/sharing-bar/SharingBar.styles.js.map +1 -1
  208. package/lib/esm/components/slider/Slider.js +13 -6
  209. package/lib/esm/components/slider/Slider.js.map +1 -1
  210. package/lib/esm/components/slider/Slider.styles.js +1 -8
  211. package/lib/esm/components/slider/Slider.styles.js.map +1 -1
  212. package/lib/esm/components/slider-button/SliderButton.js +6 -2
  213. package/lib/esm/components/slider-button/SliderButton.js.map +1 -1
  214. package/lib/esm/components/slider-button/SliderButton.styles.js +1 -14
  215. package/lib/esm/components/slider-button/SliderButton.styles.js.map +1 -1
  216. package/lib/esm/components/tag-input/TagInput.js +8 -1
  217. package/lib/esm/components/tag-input/TagInput.js.map +1 -1
  218. package/lib/esm/components/tag-input/TagInput.styles.js +1 -3
  219. package/lib/esm/components/tag-input/TagInput.styles.js.map +1 -1
  220. package/lib/esm/components/text-area/TextArea.js +68 -56
  221. package/lib/esm/components/text-area/TextArea.js.map +1 -1
  222. package/lib/esm/components/text-area/TextArea.styles.js +0 -2
  223. package/lib/esm/components/text-area/TextArea.styles.js.map +1 -1
  224. package/lib/esm/components/truncation/Truncation.js +9 -5
  225. package/lib/esm/components/truncation/Truncation.js.map +1 -1
  226. package/lib/esm/components/truncation/Truncation.styles.js +0 -11
  227. package/lib/esm/components/truncation/Truncation.styles.js.map +1 -1
  228. package/lib/esm/hooks/useFocusRingPortal.js +188 -0
  229. package/lib/esm/hooks/useFocusRingPortal.js.map +1 -0
  230. package/lib/esm/hooks/useKeyboardFocusHighlighting.js +7 -2
  231. package/lib/esm/hooks/useKeyboardFocusHighlighting.js.map +1 -1
  232. package/lib/esm/index.js +2 -0
  233. package/lib/esm/index.js.map +1 -1
  234. package/lib/types/components/amount-control/AmountControl.styles.d.ts +4 -8
  235. package/lib/types/components/button/Button.styles.d.ts +2 -4
  236. package/lib/types/components/checkbox/Checkbox.styles.d.ts +1 -5
  237. package/lib/types/components/combobox/ComboBox.styles.d.ts +2 -4
  238. package/lib/types/components/copyable-content/CopyableContent.d.ts +4 -0
  239. package/lib/types/components/file-select/FileSelect.styles.d.ts +2 -4
  240. package/lib/types/components/grid-image/GridImage.styles.d.ts +2 -4
  241. package/lib/types/components/grouped-image/GroupedImage.styles.d.ts +2 -4
  242. package/lib/types/components/highlight-slider/highlight-slider-item/HighlightSliderItem.styles.d.ts +1 -5
  243. package/lib/types/components/icon/Icon.styles.d.ts +0 -1
  244. package/lib/types/components/input/Input.styles.d.ts +4 -4
  245. package/lib/types/components/multi-action-button/action-button/ActionButton.styles.d.ts +2 -4
  246. package/lib/types/components/radio-button/RadioButton.styles.d.ts +2 -4
  247. package/lib/types/components/search-input/SearchInput.styles.d.ts +6 -13
  248. package/lib/types/components/slider/Slider.styles.d.ts +8 -12
  249. package/lib/types/components/slider-button/SliderButton.styles.d.ts +2 -4
  250. package/lib/types/components/truncation/Truncation.styles.d.ts +1 -5
  251. package/lib/types/hooks/useFocusRingPortal.d.ts +18 -0
  252. package/lib/types/hooks/useKeyboardFocusHighlighting.d.ts +1 -0
  253. package/lib/types/index.d.ts +2 -0
  254. package/package.json +4 -4
  255. package/lib/cjs/utils/keyboardFocusHighlighting.styles.js +0 -29
  256. package/lib/cjs/utils/keyboardFocusHighlighting.styles.js.map +0 -1
  257. package/lib/esm/utils/keyboardFocusHighlighting.styles.js +0 -24
  258. package/lib/esm/utils/keyboardFocusHighlighting.styles.js.map +0 -1
  259. package/lib/types/utils/keyboardFocusHighlighting.styles.d.ts +0 -9
@@ -1,4 +1,5 @@
1
- import React, { useCallback, useState } from 'react';
1
+ import React, { useCallback, useRef, useState } from 'react';
2
+ import { useFocusRingPortal } from '../../hooks/useFocusRingPortal';
2
3
  import { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';
3
4
  import { useColorScheme } from '../color-scheme-provider/ColorSchemeProvider';
4
5
  import { StyledGridBottomRightImage, StyledGridImage, StyledGridLeftImage, StyledGridTopRightImage } from './GridImage.styles';
@@ -10,6 +11,7 @@ const GridImage = ({
10
11
  onClick,
11
12
  shouldEnableKeyboardHighlighting
12
13
  }) => {
14
+ const gridImageRef = useRef(null);
13
15
  const colorScheme = useColorScheme();
14
16
  const shouldEnableKeyboardHighlightingEffective = shouldEnableKeyboardHighlighting ?? colorScheme?.shouldEnableKeyboardHighlighting ?? false;
15
17
  const [hasLoadedLeftImage, setHasLoadedLeftImage] = useState(false);
@@ -18,6 +20,10 @@ const GridImage = ({
18
20
  const isClickable = typeof onClick === 'function';
19
21
  const isKeyboardFocusable = isClickable && shouldEnableKeyboardHighlightingEffective;
20
22
  const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(isKeyboardFocusable);
23
+ useFocusRingPortal(gridImageRef, {
24
+ isEnabled: shouldShowKeyboardHighlighting,
25
+ shape: shouldShowRoundImage ? 'circle' : 'rectangle'
26
+ });
21
27
  const handleKeyDown = useCallback(event => {
22
28
  if (!isClickable) {
23
29
  return;
@@ -32,9 +38,9 @@ const GridImage = ({
32
38
  const handleBottomRightImageLoaded = useCallback(() => setHasLoadedBottomRightImage(true), []);
33
39
  const isGridImageHidden = !hasLoadedLeftImage || !hasLoadedTopRightImage || !hasLoadedBottomRightImage;
34
40
  return /*#__PURE__*/React.createElement(StyledGridImage, {
41
+ ref: gridImageRef,
35
42
  $background: background,
36
43
  $shouldShowRoundImage: shouldShowRoundImage,
37
- $shouldShowKeyboardHighlighting: shouldShowKeyboardHighlighting,
38
44
  $size: size,
39
45
  onClick: isClickable ? onClick : undefined,
40
46
  onKeyDown: isKeyboardFocusable ? handleKeyDown : undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"GridImage.js","names":["React","useCallback","useState","useKeyboardFocusHighlighting","useColorScheme","StyledGridBottomRightImage","StyledGridImage","StyledGridLeftImage","StyledGridTopRightImage","GridImage","background","images","shouldShowRoundImage","size","onClick","shouldEnableKeyboardHighlighting","colorScheme","shouldEnableKeyboardHighlightingEffective","hasLoadedLeftImage","setHasLoadedLeftImage","hasLoadedTopRightImage","setHasLoadedTopRightImage","hasLoadedBottomRightImage","setHasLoadedBottomRightImage","isClickable","isKeyboardFocusable","shouldShowKeyboardHighlighting","handleKeyDown","event","key","preventDefault","handleLeftImageLoaded","handleTopRightImageLoaded","handleBottomRightImageLoaded","isGridImageHidden","createElement","$background","$shouldShowRoundImage","$shouldShowKeyboardHighlighting","$size","undefined","onKeyDown","tabIndex","role","$isHidden","onLoad","src","displayName"],"sources":["../../../../src/components/grid-image/GridImage.tsx"],"sourcesContent":["import React, {\n CSSProperties,\n FC,\n KeyboardEventHandler,\n MouseEventHandler,\n MouseEvent,\n useCallback,\n useState,\n} from 'react';\nimport { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';\nimport { useColorScheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport {\n StyledGridBottomRightImage,\n StyledGridImage,\n StyledGridLeftImage,\n StyledGridTopRightImage,\n} from './GridImage.styles';\n\ntype GridImageProps = {\n /**\n * The background color of the image.\n */\n background?: CSSProperties['background'];\n /**\n * The images to be displayed in the `GridImage`. Only the first three images are displayed.\n */\n images: string[];\n /**\n * Function to be executed when the images are clicked.\n */\n onClick?: MouseEventHandler<HTMLDivElement>;\n /**\n * Images of users should always be displayed in a round shape. Therefore, this property can be set to true.\n */\n shouldShowRoundImage?: boolean;\n /**\n * The size of the `GridImage` in pixels, which is set as both width and height.\n */\n size: number;\n /**\n * Enables keyboard-only focus highlighting for clickable GridImage instances.\n */\n shouldEnableKeyboardHighlighting?: boolean;\n};\n\nconst GridImage: FC<GridImageProps> = ({\n background,\n images,\n shouldShowRoundImage,\n size,\n onClick,\n shouldEnableKeyboardHighlighting,\n}) => {\n const colorScheme = useColorScheme();\n const shouldEnableKeyboardHighlightingEffective =\n shouldEnableKeyboardHighlighting ?? colorScheme?.shouldEnableKeyboardHighlighting ?? false;\n\n const [hasLoadedLeftImage, setHasLoadedLeftImage] = useState(false);\n const [hasLoadedTopRightImage, setHasLoadedTopRightImage] = useState(false);\n const [hasLoadedBottomRightImage, setHasLoadedBottomRightImage] = useState(false);\n\n const isClickable = typeof onClick === 'function';\n const isKeyboardFocusable = isClickable && shouldEnableKeyboardHighlightingEffective;\n const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(isKeyboardFocusable);\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLDivElement>>(\n (event) => {\n if (!isClickable) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick?.(event as unknown as MouseEvent<HTMLDivElement>);\n }\n },\n [isClickable, onClick],\n );\n\n const handleLeftImageLoaded = useCallback(() => setHasLoadedLeftImage(true), []);\n\n const handleTopRightImageLoaded = useCallback(() => setHasLoadedTopRightImage(true), []);\n\n const handleBottomRightImageLoaded = useCallback(() => setHasLoadedBottomRightImage(true), []);\n\n const isGridImageHidden =\n !hasLoadedLeftImage || !hasLoadedTopRightImage || !hasLoadedBottomRightImage;\n\n return (\n <StyledGridImage\n $background={background}\n $shouldShowRoundImage={shouldShowRoundImage}\n $shouldShowKeyboardHighlighting={shouldShowKeyboardHighlighting}\n $size={size}\n onClick={isClickable ? onClick : undefined}\n onKeyDown={isKeyboardFocusable ? handleKeyDown : undefined}\n tabIndex={isKeyboardFocusable ? 0 : -1}\n role={isClickable ? 'button' : undefined}\n >\n <StyledGridLeftImage\n $isHidden={isGridImageHidden}\n onLoad={handleLeftImageLoaded}\n $size={size}\n src={images[0]}\n />\n <StyledGridTopRightImage\n $isHidden={isGridImageHidden}\n onLoad={handleTopRightImageLoaded}\n $size={size}\n src={images[1]}\n />\n <StyledGridBottomRightImage\n $isHidden={isGridImageHidden}\n onLoad={handleBottomRightImageLoaded}\n src={images[2]}\n />\n </StyledGridImage>\n );\n};\n\nGridImage.displayName = 'GridImage';\n\nexport default GridImage;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"GridImage.js","names":["React","useCallback","useRef","useState","useFocusRingPortal","useKeyboardFocusHighlighting","useColorScheme","StyledGridBottomRightImage","StyledGridImage","StyledGridLeftImage","StyledGridTopRightImage","GridImage","background","images","shouldShowRoundImage","size","onClick","shouldEnableKeyboardHighlighting","gridImageRef","colorScheme","shouldEnableKeyboardHighlightingEffective","hasLoadedLeftImage","setHasLoadedLeftImage","hasLoadedTopRightImage","setHasLoadedTopRightImage","hasLoadedBottomRightImage","setHasLoadedBottomRightImage","isClickable","isKeyboardFocusable","shouldShowKeyboardHighlighting","isEnabled","shape","handleKeyDown","event","key","preventDefault","handleLeftImageLoaded","handleTopRightImageLoaded","handleBottomRightImageLoaded","isGridImageHidden","createElement","ref","$background","$shouldShowRoundImage","$size","undefined","onKeyDown","tabIndex","role","$isHidden","onLoad","src","displayName"],"sources":["../../../../src/components/grid-image/GridImage.tsx"],"sourcesContent":["import React, {\n CSSProperties,\n FC,\n KeyboardEventHandler,\n MouseEventHandler,\n MouseEvent,\n useCallback,\n useRef,\n useState,\n} from 'react';\nimport { useFocusRingPortal } from '../../hooks/useFocusRingPortal';\nimport { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';\nimport { useColorScheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport {\n StyledGridBottomRightImage,\n StyledGridImage,\n StyledGridLeftImage,\n StyledGridTopRightImage,\n} from './GridImage.styles';\n\ntype GridImageProps = {\n /**\n * The background color of the image.\n */\n background?: CSSProperties['background'];\n /**\n * The images to be displayed in the `GridImage`. Only the first three images are displayed.\n */\n images: string[];\n /**\n * Function to be executed when the images are clicked.\n */\n onClick?: MouseEventHandler<HTMLDivElement>;\n /**\n * Images of users should always be displayed in a round shape. Therefore, this property can be set to true.\n */\n shouldShowRoundImage?: boolean;\n /**\n * The size of the `GridImage` in pixels, which is set as both width and height.\n */\n size: number;\n /**\n * Enables keyboard-only focus highlighting for clickable GridImage instances.\n */\n shouldEnableKeyboardHighlighting?: boolean;\n};\n\nconst GridImage: FC<GridImageProps> = ({\n background,\n images,\n shouldShowRoundImage,\n size,\n onClick,\n shouldEnableKeyboardHighlighting,\n}) => {\n const gridImageRef = useRef<HTMLDivElement>(null);\n const colorScheme = useColorScheme();\n const shouldEnableKeyboardHighlightingEffective =\n shouldEnableKeyboardHighlighting ?? colorScheme?.shouldEnableKeyboardHighlighting ?? false;\n\n const [hasLoadedLeftImage, setHasLoadedLeftImage] = useState(false);\n const [hasLoadedTopRightImage, setHasLoadedTopRightImage] = useState(false);\n const [hasLoadedBottomRightImage, setHasLoadedBottomRightImage] = useState(false);\n\n const isClickable = typeof onClick === 'function';\n const isKeyboardFocusable = isClickable && shouldEnableKeyboardHighlightingEffective;\n const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(isKeyboardFocusable);\n useFocusRingPortal(gridImageRef, {\n isEnabled: shouldShowKeyboardHighlighting,\n shape: shouldShowRoundImage ? 'circle' : 'rectangle',\n });\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLDivElement>>(\n (event) => {\n if (!isClickable) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick?.(event as unknown as MouseEvent<HTMLDivElement>);\n }\n },\n [isClickable, onClick],\n );\n\n const handleLeftImageLoaded = useCallback(() => setHasLoadedLeftImage(true), []);\n\n const handleTopRightImageLoaded = useCallback(() => setHasLoadedTopRightImage(true), []);\n\n const handleBottomRightImageLoaded = useCallback(() => setHasLoadedBottomRightImage(true), []);\n\n const isGridImageHidden =\n !hasLoadedLeftImage || !hasLoadedTopRightImage || !hasLoadedBottomRightImage;\n\n return (\n <StyledGridImage\n ref={gridImageRef}\n $background={background}\n $shouldShowRoundImage={shouldShowRoundImage}\n $size={size}\n onClick={isClickable ? onClick : undefined}\n onKeyDown={isKeyboardFocusable ? handleKeyDown : undefined}\n tabIndex={isKeyboardFocusable ? 0 : -1}\n role={isClickable ? 'button' : undefined}\n >\n <StyledGridLeftImage\n $isHidden={isGridImageHidden}\n onLoad={handleLeftImageLoaded}\n $size={size}\n src={images[0]}\n />\n <StyledGridTopRightImage\n $isHidden={isGridImageHidden}\n onLoad={handleTopRightImageLoaded}\n $size={size}\n src={images[1]}\n />\n <StyledGridBottomRightImage\n $isHidden={isGridImageHidden}\n onLoad={handleBottomRightImageLoaded}\n src={images[2]}\n />\n </StyledGridImage>\n );\n};\n\nGridImage.displayName = 'GridImage';\n\nexport default GridImage;\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,4 @@
1
- import styled, { css } from 'styled-components';
2
- import { keyboardFocusHighlightingRingCss } from '../../utils/keyboardFocusHighlighting.styles';
1
+ import styled from 'styled-components';
3
2
  export const StyledGridImage = styled.div`
4
3
  background: ${({
5
4
  $background,
@@ -22,13 +21,9 @@ export const StyledGridImage = styled.div`
22
21
  }) => $size}px;
23
22
  flex: 0 0 auto;
24
23
 
25
- ${({
26
- $shouldShowKeyboardHighlighting
27
- }) => $shouldShowKeyboardHighlighting && css`
28
- &:focus-visible {
29
- ${keyboardFocusHighlightingRingCss}
30
- }
31
- `}
24
+ &:focus-visible {
25
+ outline: none;
26
+ }
32
27
  `;
33
28
  export const StyledGridLeftImage = styled.img`
34
29
  border-right: ${({
@@ -1 +1 @@
1
- {"version":3,"file":"GridImage.styles.js","names":["styled","css","keyboardFocusHighlightingRingCss","StyledGridImage","div","$background","theme","$shouldShowRoundImage","undefined","$size","$shouldShowKeyboardHighlighting","StyledGridLeftImage","img","$isHidden","StyledGridTopRightImage","StyledGridBottomRightImage"],"sources":["../../../../src/components/grid-image/GridImage.styles.ts"],"sourcesContent":["import { CSSProperties } from 'react';\nimport styled, { css } from 'styled-components';\nimport type { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport { keyboardFocusHighlightingRingCss } from '../../utils/keyboardFocusHighlighting.styles';\n\ntype StyledGridImageProps = WithTheme<{\n $background?: CSSProperties['background'];\n $shouldShowRoundImage?: boolean;\n $shouldShowKeyboardHighlighting?: boolean;\n $size: number;\n}>;\n\nexport const StyledGridImage = styled.div<StyledGridImageProps>`\n background: ${({ $background, theme }: StyledGridImageProps) =>\n $background || `rgba(${theme['text-rgb'] ?? '0,0,0'}, 0.1)`};\n border-radius: ${({ $shouldShowRoundImage }) => ($shouldShowRoundImage ? '50%' : undefined)};\n box-shadow: 0 0 0 1px rgba(${({ theme }: StyledGridImageProps) => theme['009-rgb']}, 0.08) inset;\n height: ${({ $size }) => $size}px;\n overflow: hidden;\n position: relative;\n transition: border-radius 0.3s ease;\n width: ${({ $size }) => $size}px;\n flex: 0 0 auto;\n\n ${({ $shouldShowKeyboardHighlighting }) =>\n $shouldShowKeyboardHighlighting &&\n css`\n &:focus-visible {\n ${keyboardFocusHighlightingRingCss}\n }\n `}\n`;\n\ntype StyledGridLeftImageProps = {\n $isHidden: boolean;\n $size: number;\n};\n\nexport const StyledGridLeftImage = styled.img<StyledGridLeftImageProps>`\n border-right: ${({ $size }) => $size / 40}px solid white;\n height: 100%;\n left: 0;\n object-fit: cover;\n opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)};\n position: absolute;\n top: 0;\n transition: opacity 0.4s ease;\n width: 60%;\n`;\n\ntype StyledGridTopRightImageProps = {\n $isHidden: boolean;\n $size: number;\n};\n\nexport const StyledGridTopRightImage = styled.img<StyledGridTopRightImageProps>`\n border-bottom: ${({ $size }) => $size / 40}px solid white;\n height: 50%;\n object-fit: cover;\n opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)};\n position: absolute;\n right: 0;\n top: 0;\n transition: opacity 0.3s ease;\n width: 40%;\n`;\n\ntype StyledGridBottomRightImageProps = {\n $isHidden: boolean;\n};\n\nexport const StyledGridBottomRightImage = styled.img<StyledGridBottomRightImageProps>`\n bottom: 0;\n height: 50%;\n object-fit: cover;\n opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)};\n position: absolute;\n right: 0;\n transition: opacity 0.3s ease;\n width: 40%;\n`;\n"],"mappings":"AACA,OAAOA,MAAM,IAAIC,GAAG,QAAQ,mBAAmB;AAE/C,SAASC,gCAAgC,QAAQ,8CAA8C;AAS/F,OAAO,MAAMC,eAAe,GAAGH,MAAM,CAACI,GAAyB;AAC/D,kBAAkB,CAAC;EAAEC,WAAW;EAAEC;AAA4B,CAAC,KACvDD,WAAW,IAAI,QAAQC,KAAK,CAAC,UAAU,CAAC,IAAI,OAAO,QAAQ;AACnE,qBAAqB,CAAC;EAAEC;AAAsB,CAAC,KAAMA,qBAAqB,GAAG,KAAK,GAAGC,SAAU;AAC/F,iCAAiC,CAAC;EAAEF;AAA4B,CAAC,KAAKA,KAAK,CAAC,SAAS,CAAC;AACtF,cAAc,CAAC;EAAEG;AAAM,CAAC,KAAKA,KAAK;AAClC;AACA;AACA;AACA,aAAa,CAAC;EAAEA;AAAM,CAAC,KAAKA,KAAK;AACjC;AACA;AACA,MAAM,CAAC;EAAEC;AAAgC,CAAC,KAClCA,+BAA+B,IAC/BT,GAAG;AACX;AACA,kBAAkBC,gCAAgC;AAClD;AACA,SAAS;AACT,CAAC;AAOD,OAAO,MAAMS,mBAAmB,GAAGX,MAAM,CAACY,GAA6B;AACvE,oBAAoB,CAAC;EAAEH;AAAM,CAAC,KAAKA,KAAK,GAAG,EAAE;AAC7C;AACA;AACA;AACA,eAAe,CAAC;EAAEI;AAAU,CAAC,KAAMA,SAAS,GAAG,CAAC,GAAG,CAAE;AACrD;AACA;AACA;AACA;AACA,CAAC;AAOD,OAAO,MAAMC,uBAAuB,GAAGd,MAAM,CAACY,GAAiC;AAC/E,qBAAqB,CAAC;EAAEH;AAAM,CAAC,KAAKA,KAAK,GAAG,EAAE;AAC9C;AACA;AACA,eAAe,CAAC;EAAEI;AAAU,CAAC,KAAMA,SAAS,GAAG,CAAC,GAAG,CAAE;AACrD;AACA;AACA;AACA;AACA;AACA,CAAC;AAMD,OAAO,MAAME,0BAA0B,GAAGf,MAAM,CAACY,GAAoC;AACrF;AACA;AACA;AACA,eAAe,CAAC;EAAEC;AAAU,CAAC,KAAMA,SAAS,GAAG,CAAC,GAAG,CAAE;AACrD;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"GridImage.styles.js","names":["styled","StyledGridImage","div","$background","theme","$shouldShowRoundImage","undefined","$size","StyledGridLeftImage","img","$isHidden","StyledGridTopRightImage","StyledGridBottomRightImage"],"sources":["../../../../src/components/grid-image/GridImage.styles.ts"],"sourcesContent":["import { CSSProperties } from 'react';\nimport styled, { css } from 'styled-components';\nimport type { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\n\ntype StyledGridImageProps = WithTheme<{\n $background?: CSSProperties['background'];\n $shouldShowRoundImage?: boolean;\n $size: number;\n}>;\n\nexport const StyledGridImage = styled.div<StyledGridImageProps>`\n background: ${({ $background, theme }: StyledGridImageProps) =>\n $background || `rgba(${theme['text-rgb'] ?? '0,0,0'}, 0.1)`};\n border-radius: ${({ $shouldShowRoundImage }) => ($shouldShowRoundImage ? '50%' : undefined)};\n box-shadow: 0 0 0 1px rgba(${({ theme }: StyledGridImageProps) => theme['009-rgb']}, 0.08) inset;\n height: ${({ $size }) => $size}px;\n overflow: hidden;\n position: relative;\n transition: border-radius 0.3s ease;\n width: ${({ $size }) => $size}px;\n flex: 0 0 auto;\n\n &:focus-visible {\n outline: none;\n }\n`;\n\ntype StyledGridLeftImageProps = {\n $isHidden: boolean;\n $size: number;\n};\n\nexport const StyledGridLeftImage = styled.img<StyledGridLeftImageProps>`\n border-right: ${({ $size }) => $size / 40}px solid white;\n height: 100%;\n left: 0;\n object-fit: cover;\n opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)};\n position: absolute;\n top: 0;\n transition: opacity 0.4s ease;\n width: 60%;\n`;\n\ntype StyledGridTopRightImageProps = {\n $isHidden: boolean;\n $size: number;\n};\n\nexport const StyledGridTopRightImage = styled.img<StyledGridTopRightImageProps>`\n border-bottom: ${({ $size }) => $size / 40}px solid white;\n height: 50%;\n object-fit: cover;\n opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)};\n position: absolute;\n right: 0;\n top: 0;\n transition: opacity 0.3s ease;\n width: 40%;\n`;\n\ntype StyledGridBottomRightImageProps = {\n $isHidden: boolean;\n};\n\nexport const StyledGridBottomRightImage = styled.img<StyledGridBottomRightImageProps>`\n bottom: 0;\n height: 50%;\n object-fit: cover;\n opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)};\n position: absolute;\n right: 0;\n transition: opacity 0.3s ease;\n width: 40%;\n`;\n"],"mappings":"AACA,OAAOA,MAAM,MAAe,mBAAmB;AAS/C,OAAO,MAAMC,eAAe,GAAGD,MAAM,CAACE,GAAyB;AAC/D,kBAAkB,CAAC;EAAEC,WAAW;EAAEC;AAA4B,CAAC,KACvDD,WAAW,IAAI,QAAQC,KAAK,CAAC,UAAU,CAAC,IAAI,OAAO,QAAQ;AACnE,qBAAqB,CAAC;EAAEC;AAAsB,CAAC,KAAMA,qBAAqB,GAAG,KAAK,GAAGC,SAAU;AAC/F,iCAAiC,CAAC;EAAEF;AAA4B,CAAC,KAAKA,KAAK,CAAC,SAAS,CAAC;AACtF,cAAc,CAAC;EAAEG;AAAM,CAAC,KAAKA,KAAK;AAClC;AACA;AACA;AACA,aAAa,CAAC;EAAEA;AAAM,CAAC,KAAKA,KAAK;AACjC;AACA;AACA;AACA;AACA;AACA,CAAC;AAOD,OAAO,MAAMC,mBAAmB,GAAGR,MAAM,CAACS,GAA6B;AACvE,oBAAoB,CAAC;EAAEF;AAAM,CAAC,KAAKA,KAAK,GAAG,EAAE;AAC7C;AACA;AACA;AACA,eAAe,CAAC;EAAEG;AAAU,CAAC,KAAMA,SAAS,GAAG,CAAC,GAAG,CAAE;AACrD;AACA;AACA;AACA;AACA,CAAC;AAOD,OAAO,MAAMC,uBAAuB,GAAGX,MAAM,CAACS,GAAiC;AAC/E,qBAAqB,CAAC;EAAEF;AAAM,CAAC,KAAKA,KAAK,GAAG,EAAE;AAC9C;AACA;AACA,eAAe,CAAC;EAAEG;AAAU,CAAC,KAAMA,SAAS,GAAG,CAAC,GAAG,CAAE;AACrD;AACA;AACA;AACA;AACA;AACA,CAAC;AAMD,OAAO,MAAME,0BAA0B,GAAGZ,MAAM,CAACS,GAAoC;AACrF;AACA;AACA;AACA,eAAe,CAAC;EAAEC;AAAU,CAAC,KAAMA,SAAS,GAAG,CAAC,GAAG,CAAE;AACrD;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
@@ -1,8 +1,9 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useRef } from 'react';
2
2
  import { StyledCornerElement, StyledCornerImage, StyledGroupedImage, StyledGroupImageElement } from './GroupedImage.styles';
3
3
  import CareOfClipPath from './clip-paths/CareOfClipPath';
4
4
  import { useUuid } from '../../hooks/uuid';
5
5
  import SecondImageClipPath from './clip-paths/SecondImageClipPath';
6
+ import { useFocusRingPortal } from '../../hooks/useFocusRingPortal';
6
7
  import { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';
7
8
  import { useColorScheme } from '../color-scheme-provider/ColorSchemeProvider';
8
9
  const GROUPED_IMAGE_SERVICE_ORIGIN = 'https://tsimg.cloud';
@@ -50,6 +51,7 @@ const GroupedImage = ({
50
51
  onImageError,
51
52
  shouldEnableKeyboardHighlighting
52
53
  }) => {
54
+ const groupedImageRef = useRef(null);
53
55
  const colorScheme = useColorScheme();
54
56
  const shouldEnableKeyboardHighlightingEffective = shouldEnableKeyboardHighlighting ?? colorScheme?.shouldEnableKeyboardHighlighting ?? false;
55
57
  const hasCornerImage = Boolean(cornerImage);
@@ -60,6 +62,10 @@ const GroupedImage = ({
60
62
  const isClickable = typeof onClick === 'function';
61
63
  const isKeyboardFocusable = isClickable && shouldEnableKeyboardHighlightingEffective;
62
64
  const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(isKeyboardFocusable);
65
+ useFocusRingPortal(groupedImageRef, {
66
+ isEnabled: shouldShowKeyboardHighlighting,
67
+ shape: shouldShowRoundImage ? 'circle' : 'rectangle'
68
+ });
63
69
  const handleKeyDown = useCallback(event => {
64
70
  if (!isClickable) {
65
71
  return;
@@ -95,12 +101,12 @@ const GroupedImage = ({
95
101
  onError: event => typeof onImageError === 'function' && onImageError(event, index)
96
102
  })))));
97
103
  return /*#__PURE__*/React.createElement(StyledGroupedImage, {
104
+ ref: groupedImageRef,
98
105
  onClick: isClickable ? onClick : undefined,
99
106
  onKeyDown: isKeyboardFocusable ? handleKeyDown : undefined,
100
107
  tabIndex: isKeyboardFocusable ? 0 : -1,
101
108
  role: isClickable ? 'button' : undefined,
102
- $height: height,
103
- $shouldShowKeyboardHighlighting: shouldShowKeyboardHighlighting
109
+ $height: height
104
110
  }, hasCornerImage && /*#__PURE__*/React.createElement(CareOfClipPath, {
105
111
  height: height,
106
112
  uuid: uuid,
@@ -1 +1 @@
1
- {"version":3,"file":"GroupedImage.js","names":["React","useCallback","StyledCornerElement","StyledCornerImage","StyledGroupedImage","StyledGroupImageElement","CareOfClipPath","useUuid","SecondImageClipPath","useKeyboardFocusHighlighting","useColorScheme","GROUPED_IMAGE_SERVICE_ORIGIN","IMAGE_SERVICE_PARAM_PATTERN","getGroupedImageDisplayUrl","url","size","urlObject","URL","origin","pathSegments","pathname","split","fileName","pop","extensionIndex","lastIndexOf","extension","slice","fileBaseName","parameterSegment","hasImageServiceParameters","Boolean","every","parameter","test","normalizedSize","Math","max","round","fileBaseNameWithoutParams","preservedParams","filter","p","newParams","push","join","toString","GroupedImage","cornerImage","height","imageBackground","images","onClick","shouldPreventBackground","shouldShowRoundImage","cornerElement","onImageError","shouldEnableKeyboardHighlighting","colorScheme","shouldEnableKeyboardHighlightingEffective","hasCornerImage","hasCornerElement","hasMultipleImages","length","uuid","cornerImageDisplayUrl","undefined","isClickable","isKeyboardFocusable","shouldShowKeyboardHighlighting","handleKeyDown","event","key","preventDefault","imageElements","map","src","index","createElement","$background","$isSecondImage","$hasCornerImage","$hasMultipleImages","$shouldPreventBackground","$shouldShowRoundImage","$uuid","width","viewBox","xmlns","preserveAspectRatio","alt","onError","onKeyDown","tabIndex","role","$height","$shouldShowKeyboardHighlighting","imageFactors","displayName"],"sources":["../../../../src/components/grouped-image/GroupedImage.tsx"],"sourcesContent":["import React, {\n CSSProperties,\n FC,\n KeyboardEventHandler,\n MouseEvent,\n MouseEventHandler,\n ReactNode,\n SyntheticEvent,\n useCallback,\n} from 'react';\nimport {\n StyledCornerElement,\n StyledCornerImage,\n StyledGroupedImage,\n StyledGroupImageElement,\n} from './GroupedImage.styles';\nimport CareOfClipPath from './clip-paths/CareOfClipPath';\nimport { useUuid } from '../../hooks/uuid';\nimport SecondImageClipPath from './clip-paths/SecondImageClipPath';\nimport { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';\nimport { useColorScheme } from '../color-scheme-provider/ColorSchemeProvider';\n\nconst GROUPED_IMAGE_SERVICE_ORIGIN = 'https://tsimg.cloud';\nconst IMAGE_SERVICE_PARAM_PATTERN =\n /^(?:[whsbd]\\d+|f(?:webp|avif|json|none)|c(?:c|f)|m(?:cr|sd|ct|pd|cv))$/i;\n\ninterface GroupedImageProps {\n /**\n * Optional image to display in the bottom right corner of the grouped image.\n */\n cornerImage?: string;\n /**\n * Height of the grouped image container.\n */\n height?: number;\n /**\n * Background for the single images.\n */\n imageBackground?: CSSProperties['background'];\n /**\n * Array of image URLs to display in the grouped image. If only one image is provided, it will be displayed as a full image.\n */\n images: string[];\n /**\n * Optional click handler for the grouped image.\n */\n onClick?: MouseEventHandler<HTMLDivElement>;\n /**\n * Whether to prevent the background of the images from being set.\n */\n shouldPreventBackground?: boolean;\n /**\n * Whether to show the images in a round shape.\n */\n shouldShowRoundImage?: boolean;\n /**\n * Optional Element to display in the right corner of the image\n */\n cornerElement?: ReactNode;\n /**\n * Optional handler for image load errors.\n */\n onImageError?: (event: SyntheticEvent<HTMLImageElement, Event>, index: number) => void;\n /**\n * Enables keyboard-only focus highlighting for clickable grouped images.\n */\n shouldEnableKeyboardHighlighting?: boolean;\n}\n\nconst getGroupedImageDisplayUrl = (url: string, size: number): string => {\n try {\n const urlObject = new URL(url);\n\n if (urlObject.origin !== GROUPED_IMAGE_SERVICE_ORIGIN) {\n return url;\n }\n\n const pathSegments = urlObject.pathname.split('/');\n const fileName = pathSegments.pop();\n\n if (!fileName) {\n return url;\n }\n\n const extensionIndex = fileName.lastIndexOf('.');\n const extension = extensionIndex > -1 ? fileName.slice(extensionIndex) : '';\n const fileBaseName = extensionIndex > -1 ? fileName.slice(0, extensionIndex) : fileName;\n const parameterSegment = fileBaseName.split('_').pop() ?? '';\n const hasImageServiceParameters = Boolean(\n parameterSegment &&\n parameterSegment !== fileBaseName &&\n parameterSegment\n .split('-')\n .every((parameter) => IMAGE_SERVICE_PARAM_PATTERN.test(parameter)),\n );\n const normalizedSize = Math.max(1, Math.round(size));\n\n if (hasImageServiceParameters) {\n const fileBaseNameWithoutParams = fileBaseName.slice(0, fileBaseName.lastIndexOf('_'));\n const preservedParams = parameterSegment\n .split('-')\n .filter((p) => !/^[whs]\\d+$/i.test(p));\n const newParams = [...preservedParams, `w${normalizedSize}`, `h${normalizedSize}`];\n pathSegments.push(`${fileBaseNameWithoutParams}_${newParams.join('-')}${extension}`);\n } else {\n pathSegments.push(`${fileBaseName}_w${normalizedSize}-h${normalizedSize}${extension}`);\n }\n urlObject.pathname = pathSegments.join('/');\n\n return urlObject.toString();\n } catch {\n return url;\n }\n};\n\nconst GroupedImage: FC<GroupedImageProps> = ({\n cornerImage,\n height = 40,\n imageBackground,\n images,\n onClick,\n shouldPreventBackground = false,\n shouldShowRoundImage = false,\n cornerElement,\n onImageError,\n shouldEnableKeyboardHighlighting,\n}) => {\n const colorScheme = useColorScheme();\n const shouldEnableKeyboardHighlightingEffective =\n shouldEnableKeyboardHighlighting ?? colorScheme?.shouldEnableKeyboardHighlighting ?? false;\n\n const hasCornerImage = Boolean(cornerImage);\n const hasCornerElement = Boolean(cornerElement);\n const hasMultipleImages = images.length > 1;\n const uuid = useUuid();\n const cornerImageDisplayUrl = cornerImage\n ? getGroupedImageDisplayUrl(cornerImage, height)\n : undefined;\n const isClickable = typeof onClick === 'function';\n const isKeyboardFocusable = isClickable && shouldEnableKeyboardHighlightingEffective;\n const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(isKeyboardFocusable);\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLDivElement>>(\n (event) => {\n if (!isClickable) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick?.(event as unknown as MouseEvent<HTMLDivElement>);\n }\n },\n [isClickable, onClick],\n );\n\n const imageElements = images.slice(0, 2).map((src, index) => (\n <StyledGroupImageElement\n $background={imageBackground}\n $isSecondImage={index === 1}\n $hasCornerImage={hasCornerImage}\n $hasMultipleImages={hasMultipleImages}\n $shouldPreventBackground={shouldPreventBackground}\n $shouldShowRoundImage={shouldShowRoundImage}\n $uuid={uuid}\n // eslint-disable-next-line react/no-array-index-key\n key={index}\n >\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 40 40\"\n xmlns=\"http://www.w3.org/2000/svg\"\n preserveAspectRatio=\"xMidYMid slice\"\n >\n <foreignObject width=\"40\" height=\"40\">\n <img\n alt={`image--${index}`}\n src={getGroupedImageDisplayUrl(src, height)}\n onError={(event) =>\n typeof onImageError === 'function' && onImageError(event, index)\n }\n />\n </foreignObject>\n </svg>\n </StyledGroupImageElement>\n ));\n\n return (\n <StyledGroupedImage\n onClick={isClickable ? onClick : undefined}\n onKeyDown={isKeyboardFocusable ? handleKeyDown : undefined}\n tabIndex={isKeyboardFocusable ? 0 : -1}\n role={isClickable ? 'button' : undefined}\n $height={height}\n $shouldShowKeyboardHighlighting={shouldShowKeyboardHighlighting}\n >\n {hasCornerImage && (\n <CareOfClipPath\n height={height}\n uuid={uuid}\n imageFactors={hasMultipleImages ? [0.76, 0.8] : [1]}\n />\n )}\n {hasMultipleImages && (\n <SecondImageClipPath\n height={height}\n uuid={uuid}\n shouldShowRoundImage={shouldShowRoundImage}\n />\n )}\n\n {imageElements}\n\n {hasCornerImage && (\n <StyledCornerImage\n $background={imageBackground}\n $shouldPreventBackground={shouldPreventBackground}\n $hasMultipleImages={hasMultipleImages}\n src={cornerImageDisplayUrl}\n key=\"corner-image\"\n />\n )}\n {hasCornerElement && <StyledCornerElement>{cornerElement}</StyledCornerElement>}\n </StyledGroupedImage>\n );\n};\n\nGroupedImage.displayName = 'GroupedImage';\n\nexport default GroupedImage;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"GroupedImage.js","names":["React","useCallback","useRef","StyledCornerElement","StyledCornerImage","StyledGroupedImage","StyledGroupImageElement","CareOfClipPath","useUuid","SecondImageClipPath","useFocusRingPortal","useKeyboardFocusHighlighting","useColorScheme","GROUPED_IMAGE_SERVICE_ORIGIN","IMAGE_SERVICE_PARAM_PATTERN","getGroupedImageDisplayUrl","url","size","urlObject","URL","origin","pathSegments","pathname","split","fileName","pop","extensionIndex","lastIndexOf","extension","slice","fileBaseName","parameterSegment","hasImageServiceParameters","Boolean","every","parameter","test","normalizedSize","Math","max","round","fileBaseNameWithoutParams","preservedParams","filter","p","newParams","push","join","toString","GroupedImage","cornerImage","height","imageBackground","images","onClick","shouldPreventBackground","shouldShowRoundImage","cornerElement","onImageError","shouldEnableKeyboardHighlighting","groupedImageRef","colorScheme","shouldEnableKeyboardHighlightingEffective","hasCornerImage","hasCornerElement","hasMultipleImages","length","uuid","cornerImageDisplayUrl","undefined","isClickable","isKeyboardFocusable","shouldShowKeyboardHighlighting","isEnabled","shape","handleKeyDown","event","key","preventDefault","imageElements","map","src","index","createElement","$background","$isSecondImage","$hasCornerImage","$hasMultipleImages","$shouldPreventBackground","$shouldShowRoundImage","$uuid","width","viewBox","xmlns","preserveAspectRatio","alt","onError","ref","onKeyDown","tabIndex","role","$height","imageFactors","displayName"],"sources":["../../../../src/components/grouped-image/GroupedImage.tsx"],"sourcesContent":["import React, {\n CSSProperties,\n FC,\n KeyboardEventHandler,\n MouseEvent,\n MouseEventHandler,\n ReactNode,\n SyntheticEvent,\n useCallback,\n useRef,\n} from 'react';\nimport {\n StyledCornerElement,\n StyledCornerImage,\n StyledGroupedImage,\n StyledGroupImageElement,\n} from './GroupedImage.styles';\nimport CareOfClipPath from './clip-paths/CareOfClipPath';\nimport { useUuid } from '../../hooks/uuid';\nimport SecondImageClipPath from './clip-paths/SecondImageClipPath';\nimport { useFocusRingPortal } from '../../hooks/useFocusRingPortal';\nimport { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';\nimport { useColorScheme } from '../color-scheme-provider/ColorSchemeProvider';\n\nconst GROUPED_IMAGE_SERVICE_ORIGIN = 'https://tsimg.cloud';\nconst IMAGE_SERVICE_PARAM_PATTERN =\n /^(?:[whsbd]\\d+|f(?:webp|avif|json|none)|c(?:c|f)|m(?:cr|sd|ct|pd|cv))$/i;\n\ninterface GroupedImageProps {\n /**\n * Optional image to display in the bottom right corner of the grouped image.\n */\n cornerImage?: string;\n /**\n * Height of the grouped image container.\n */\n height?: number;\n /**\n * Background for the single images.\n */\n imageBackground?: CSSProperties['background'];\n /**\n * Array of image URLs to display in the grouped image. If only one image is provided, it will be displayed as a full image.\n */\n images: string[];\n /**\n * Optional click handler for the grouped image.\n */\n onClick?: MouseEventHandler<HTMLDivElement>;\n /**\n * Whether to prevent the background of the images from being set.\n */\n shouldPreventBackground?: boolean;\n /**\n * Whether to show the images in a round shape.\n */\n shouldShowRoundImage?: boolean;\n /**\n * Optional Element to display in the right corner of the image\n */\n cornerElement?: ReactNode;\n /**\n * Optional handler for image load errors.\n */\n onImageError?: (event: SyntheticEvent<HTMLImageElement, Event>, index: number) => void;\n /**\n * Enables keyboard-only focus highlighting for clickable grouped images.\n */\n shouldEnableKeyboardHighlighting?: boolean;\n}\n\nconst getGroupedImageDisplayUrl = (url: string, size: number): string => {\n try {\n const urlObject = new URL(url);\n\n if (urlObject.origin !== GROUPED_IMAGE_SERVICE_ORIGIN) {\n return url;\n }\n\n const pathSegments = urlObject.pathname.split('/');\n const fileName = pathSegments.pop();\n\n if (!fileName) {\n return url;\n }\n\n const extensionIndex = fileName.lastIndexOf('.');\n const extension = extensionIndex > -1 ? fileName.slice(extensionIndex) : '';\n const fileBaseName = extensionIndex > -1 ? fileName.slice(0, extensionIndex) : fileName;\n const parameterSegment = fileBaseName.split('_').pop() ?? '';\n const hasImageServiceParameters = Boolean(\n parameterSegment &&\n parameterSegment !== fileBaseName &&\n parameterSegment\n .split('-')\n .every((parameter) => IMAGE_SERVICE_PARAM_PATTERN.test(parameter)),\n );\n const normalizedSize = Math.max(1, Math.round(size));\n\n if (hasImageServiceParameters) {\n const fileBaseNameWithoutParams = fileBaseName.slice(0, fileBaseName.lastIndexOf('_'));\n const preservedParams = parameterSegment\n .split('-')\n .filter((p) => !/^[whs]\\d+$/i.test(p));\n const newParams = [...preservedParams, `w${normalizedSize}`, `h${normalizedSize}`];\n pathSegments.push(`${fileBaseNameWithoutParams}_${newParams.join('-')}${extension}`);\n } else {\n pathSegments.push(`${fileBaseName}_w${normalizedSize}-h${normalizedSize}${extension}`);\n }\n urlObject.pathname = pathSegments.join('/');\n\n return urlObject.toString();\n } catch {\n return url;\n }\n};\n\nconst GroupedImage: FC<GroupedImageProps> = ({\n cornerImage,\n height = 40,\n imageBackground,\n images,\n onClick,\n shouldPreventBackground = false,\n shouldShowRoundImage = false,\n cornerElement,\n onImageError,\n shouldEnableKeyboardHighlighting,\n}) => {\n const groupedImageRef = useRef<HTMLDivElement>(null);\n const colorScheme = useColorScheme();\n const shouldEnableKeyboardHighlightingEffective =\n shouldEnableKeyboardHighlighting ?? colorScheme?.shouldEnableKeyboardHighlighting ?? false;\n\n const hasCornerImage = Boolean(cornerImage);\n const hasCornerElement = Boolean(cornerElement);\n const hasMultipleImages = images.length > 1;\n const uuid = useUuid();\n const cornerImageDisplayUrl = cornerImage\n ? getGroupedImageDisplayUrl(cornerImage, height)\n : undefined;\n const isClickable = typeof onClick === 'function';\n const isKeyboardFocusable = isClickable && shouldEnableKeyboardHighlightingEffective;\n const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(isKeyboardFocusable);\n useFocusRingPortal(groupedImageRef, {\n isEnabled: shouldShowKeyboardHighlighting,\n shape: shouldShowRoundImage ? 'circle' : 'rectangle',\n });\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLDivElement>>(\n (event) => {\n if (!isClickable) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick?.(event as unknown as MouseEvent<HTMLDivElement>);\n }\n },\n [isClickable, onClick],\n );\n\n const imageElements = images.slice(0, 2).map((src, index) => (\n <StyledGroupImageElement\n $background={imageBackground}\n $isSecondImage={index === 1}\n $hasCornerImage={hasCornerImage}\n $hasMultipleImages={hasMultipleImages}\n $shouldPreventBackground={shouldPreventBackground}\n $shouldShowRoundImage={shouldShowRoundImage}\n $uuid={uuid}\n // eslint-disable-next-line react/no-array-index-key\n key={index}\n >\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 40 40\"\n xmlns=\"http://www.w3.org/2000/svg\"\n preserveAspectRatio=\"xMidYMid slice\"\n >\n <foreignObject width=\"40\" height=\"40\">\n <img\n alt={`image--${index}`}\n src={getGroupedImageDisplayUrl(src, height)}\n onError={(event) =>\n typeof onImageError === 'function' && onImageError(event, index)\n }\n />\n </foreignObject>\n </svg>\n </StyledGroupImageElement>\n ));\n\n return (\n <StyledGroupedImage\n ref={groupedImageRef}\n onClick={isClickable ? onClick : undefined}\n onKeyDown={isKeyboardFocusable ? handleKeyDown : undefined}\n tabIndex={isKeyboardFocusable ? 0 : -1}\n role={isClickable ? 'button' : undefined}\n $height={height}\n >\n {hasCornerImage && (\n <CareOfClipPath\n height={height}\n uuid={uuid}\n imageFactors={hasMultipleImages ? [0.76, 0.8] : [1]}\n />\n )}\n {hasMultipleImages && (\n <SecondImageClipPath\n height={height}\n uuid={uuid}\n shouldShowRoundImage={shouldShowRoundImage}\n />\n )}\n\n {imageElements}\n\n {hasCornerImage && (\n <StyledCornerImage\n $background={imageBackground}\n $shouldPreventBackground={shouldPreventBackground}\n $hasMultipleImages={hasMultipleImages}\n src={cornerImageDisplayUrl}\n key=\"corner-image\"\n />\n )}\n {hasCornerElement && <StyledCornerElement>{cornerElement}</StyledCornerElement>}\n </StyledGroupedImage>\n );\n};\n\nGroupedImage.displayName = 'GroupedImage';\n\nexport default GroupedImage;\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,4 @@
1
1
  import styled, { css } from 'styled-components';
2
- import { keyboardFocusHighlightingRingCss } from '../../utils/keyboardFocusHighlighting.styles';
3
2
  export const StyledGroupedImage = styled.div`
4
3
  flex: 0 0 auto;
5
4
  height: ${({
@@ -10,13 +9,9 @@ export const StyledGroupedImage = styled.div`
10
9
  $height
11
10
  }) => $height}px;
12
11
 
13
- ${({
14
- $shouldShowKeyboardHighlighting
15
- }) => $shouldShowKeyboardHighlighting && css`
16
- &:focus-visible {
17
- ${keyboardFocusHighlightingRingCss}
18
- }
19
- `}
12
+ &:focus-visible {
13
+ outline: none;
14
+ }
20
15
  `;
21
16
  export const StyledGroupImageElement = styled.div.attrs(({
22
17
  $isSecondImage,
@@ -1 +1 @@
1
- {"version":3,"file":"GroupedImage.styles.js","names":["styled","css","keyboardFocusHighlightingRingCss","StyledGroupedImage","div","$height","$shouldShowKeyboardHighlighting","StyledGroupImageElement","attrs","$isSecondImage","$hasMultipleImages","$hasCornerImage","$uuid","clipPath","style","$shouldShowRoundImage","$background","$shouldPreventBackground","theme","StyledCornerImage","img","StyledCornerElement","span"],"sources":["../../../../src/components/grouped-image/GroupedImage.styles.ts"],"sourcesContent":["import styled, { css } from 'styled-components';\nimport { CSSProperties } from 'react';\nimport { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport { keyboardFocusHighlightingRingCss } from '../../utils/keyboardFocusHighlighting.styles';\n\ntype StyledGroupedImageProps = WithTheme<{\n $height: CSSProperties['height'];\n $shouldShowKeyboardHighlighting?: boolean;\n}>;\n\nexport const StyledGroupedImage = styled.div<StyledGroupedImageProps>`\n flex: 0 0 auto;\n height: ${({ $height }) => $height}px;\n position: relative;\n width: ${({ $height }) => $height}px;\n\n ${({ $shouldShowKeyboardHighlighting }) =>\n $shouldShowKeyboardHighlighting &&\n css`\n &:focus-visible {\n ${keyboardFocusHighlightingRingCss}\n }\n `}\n`;\n\ntype StyledImageProps = WithTheme<{\n $background?: CSSProperties['background'];\n $isSecondImage?: boolean;\n $shouldPreventBackground?: boolean;\n $shouldShowRoundImage?: boolean;\n $hasCornerImage: boolean;\n $hasMultipleImages: boolean;\n $uuid: string;\n}>;\n\nexport const StyledGroupImageElement = styled.div.attrs<StyledImageProps>(\n ({ $isSecondImage, $hasMultipleImages, $hasCornerImage, $uuid }) => {\n let clipPath: string | undefined;\n if (\n ($isSecondImage && $hasCornerImage) ||\n (!$isSecondImage && !$hasMultipleImages && $hasCornerImage)\n ) {\n clipPath = `url(#care-of-mask--${$uuid})`;\n } else if (!$isSecondImage && $hasMultipleImages) {\n clipPath = `url(#second-image-mask--${$uuid})`;\n }\n\n return {\n style: {\n clipPath,\n },\n };\n },\n)`\n aspect-ratio: 1;\n border-radius: ${({ $shouldShowRoundImage }) => ($shouldShowRoundImage ? '50%' : '0')};\n position: absolute;\n overflow: hidden;\n\n ${({ $hasMultipleImages, $isSecondImage }) => {\n if (!$hasMultipleImages) {\n return css`\n height: 100%;\n `;\n }\n\n if ($isSecondImage) {\n return css`\n height: 80%;\n `;\n }\n\n return css`\n height: 76%;\n `;\n }}\n\n ${({ $isSecondImage }) =>\n $isSecondImage\n ? css`\n bottom: 0;\n right: 0;\n `\n : css`\n top: 0;\n left: 0;\n `}\n\n ${({ $background, $shouldPreventBackground, theme }) =>\n !$shouldPreventBackground &&\n css`\n background: ${$background || `rgba(${theme['text-rgb'] ?? '0,0,0'}, 0.1)`};\n box-shadow: 0 0 0 1px rgba(${theme['009-rgb']}, 0.08) inset;\n `}\n \n img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n`;\n\ntype StyledCornerImageProps = WithTheme<{\n $background?: CSSProperties['background'];\n $shouldPreventBackground?: boolean;\n $hasMultipleImages: boolean;\n}>;\n\nexport const StyledCornerImage = styled.img<StyledCornerImageProps>`\n aspect-ratio: 1;\n bottom: 0;\n height: ${({ $hasMultipleImages }) => ($hasMultipleImages ? '28%' : '38%')};\n position: absolute;\n right: 0;\n\n ${({ $background, $shouldPreventBackground, theme }) =>\n !$shouldPreventBackground &&\n css`\n background: ${$background || `rgba(${theme['text-rgb'] ?? '0,0,0'}, 0.1)`};\n box-shadow: 0 0 0 1px rgba(${theme['009-rgb']}, 0.08) inset;\n `}\n`;\n\nexport const StyledCornerElement = styled.span`\n height: 18px;\n width: 18px;\n position: absolute;\n bottom: 0;\n right: -5px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n & > * {\n max-height: 100%;\n max-width: 100%;\n display: block;\n }\n`;\n"],"mappings":"AAAA,OAAOA,MAAM,IAAIC,GAAG,QAAQ,mBAAmB;AAG/C,SAASC,gCAAgC,QAAQ,8CAA8C;AAO/F,OAAO,MAAMC,kBAAkB,GAAGH,MAAM,CAACI,GAA4B;AACrE;AACA,cAAc,CAAC;EAAEC;AAAQ,CAAC,KAAKA,OAAO;AACtC;AACA,aAAa,CAAC;EAAEA;AAAQ,CAAC,KAAKA,OAAO;AACrC;AACA,MAAM,CAAC;EAAEC;AAAgC,CAAC,KAClCA,+BAA+B,IAC/BL,GAAG;AACX;AACA,kBAAkBC,gCAAgC;AAClD;AACA,SAAS;AACT,CAAC;AAYD,OAAO,MAAMK,uBAAuB,GAAGP,MAAM,CAACI,GAAG,CAACI,KAAK,CACnD,CAAC;EAAEC,cAAc;EAAEC,kBAAkB;EAAEC,eAAe;EAAEC;AAAM,CAAC,KAAK;EAChE,IAAIC,QAA4B;EAChC,IACKJ,cAAc,IAAIE,eAAe,IACjC,CAACF,cAAc,IAAI,CAACC,kBAAkB,IAAIC,eAAgB,EAC7D;IACEE,QAAQ,GAAG,sBAAsBD,KAAK,GAAG;EAC7C,CAAC,MAAM,IAAI,CAACH,cAAc,IAAIC,kBAAkB,EAAE;IAC9CG,QAAQ,GAAG,2BAA2BD,KAAK,GAAG;EAClD;EAEA,OAAO;IACHE,KAAK,EAAE;MACHD;IACJ;EACJ,CAAC;AACL,CACJ,CAAC;AACD;AACA,qBAAqB,CAAC;EAAEE;AAAsB,CAAC,KAAMA,qBAAqB,GAAG,KAAK,GAAG,GAAI;AACzF;AACA;AACA;AACA,MAAM,CAAC;EAAEL,kBAAkB;EAAED;AAAe,CAAC,KAAK;EAC1C,IAAI,CAACC,kBAAkB,EAAE;IACrB,OAAOT,GAAG;AACtB;AACA,aAAa;EACL;EAEA,IAAIQ,cAAc,EAAE;IAChB,OAAOR,GAAG;AACtB;AACA,aAAa;EACL;EAEA,OAAOA,GAAG;AAClB;AACA,SAAS;AACL,CAAC;AACL;AACA,MAAM,CAAC;EAAEQ;AAAe,CAAC,KACjBA,cAAc,GACRR,GAAG;AACjB;AACA;AACA,eAAe,GACDA,GAAG;AACjB;AACA;AACA,eAAe;AACf;AACA,MAAM,CAAC;EAAEe,WAAW;EAAEC,wBAAwB;EAAEC;AAAM,CAAC,KAC/C,CAACD,wBAAwB,IACzBhB,GAAG;AACX,0BAA0Be,WAAW,IAAI,QAAQE,KAAK,CAAC,UAAU,CAAC,IAAI,OAAO,QAAQ;AACrF,yCAAyCA,KAAK,CAAC,SAAS,CAAC;AACzD,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAQD,OAAO,MAAMC,iBAAiB,GAAGnB,MAAM,CAACoB,GAA2B;AACnE;AACA;AACA,cAAc,CAAC;EAAEV;AAAmB,CAAC,KAAMA,kBAAkB,GAAG,KAAK,GAAG,KAAM;AAC9E;AACA;AACA;AACA,MAAM,CAAC;EAAEM,WAAW;EAAEC,wBAAwB;EAAEC;AAAM,CAAC,KAC/C,CAACD,wBAAwB,IACzBhB,GAAG;AACX,0BAA0Be,WAAW,IAAI,QAAQE,KAAK,CAAC,UAAU,CAAC,IAAI,OAAO,QAAQ;AACrF,yCAAyCA,KAAK,CAAC,SAAS,CAAC;AACzD,SAAS;AACT,CAAC;AAED,OAAO,MAAMG,mBAAmB,GAAGrB,MAAM,CAACsB,IAAI;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"GroupedImage.styles.js","names":["styled","css","StyledGroupedImage","div","$height","StyledGroupImageElement","attrs","$isSecondImage","$hasMultipleImages","$hasCornerImage","$uuid","clipPath","style","$shouldShowRoundImage","$background","$shouldPreventBackground","theme","StyledCornerImage","img","StyledCornerElement","span"],"sources":["../../../../src/components/grouped-image/GroupedImage.styles.ts"],"sourcesContent":["import styled, { css } from 'styled-components';\nimport { CSSProperties } from 'react';\nimport { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\n\ntype StyledGroupedImageProps = WithTheme<{\n $height: CSSProperties['height'];\n}>;\n\nexport const StyledGroupedImage = styled.div<StyledGroupedImageProps>`\n flex: 0 0 auto;\n height: ${({ $height }) => $height}px;\n position: relative;\n width: ${({ $height }) => $height}px;\n\n &:focus-visible {\n outline: none;\n }\n`;\n\ntype StyledImageProps = WithTheme<{\n $background?: CSSProperties['background'];\n $isSecondImage?: boolean;\n $shouldPreventBackground?: boolean;\n $shouldShowRoundImage?: boolean;\n $hasCornerImage: boolean;\n $hasMultipleImages: boolean;\n $uuid: string;\n}>;\n\nexport const StyledGroupImageElement = styled.div.attrs<StyledImageProps>(\n ({ $isSecondImage, $hasMultipleImages, $hasCornerImage, $uuid }) => {\n let clipPath: string | undefined;\n if (\n ($isSecondImage && $hasCornerImage) ||\n (!$isSecondImage && !$hasMultipleImages && $hasCornerImage)\n ) {\n clipPath = `url(#care-of-mask--${$uuid})`;\n } else if (!$isSecondImage && $hasMultipleImages) {\n clipPath = `url(#second-image-mask--${$uuid})`;\n }\n\n return {\n style: {\n clipPath,\n },\n };\n },\n)`\n aspect-ratio: 1;\n border-radius: ${({ $shouldShowRoundImage }) => ($shouldShowRoundImage ? '50%' : '0')};\n position: absolute;\n overflow: hidden;\n\n ${({ $hasMultipleImages, $isSecondImage }) => {\n if (!$hasMultipleImages) {\n return css`\n height: 100%;\n `;\n }\n\n if ($isSecondImage) {\n return css`\n height: 80%;\n `;\n }\n\n return css`\n height: 76%;\n `;\n }}\n\n ${({ $isSecondImage }) =>\n $isSecondImage\n ? css`\n bottom: 0;\n right: 0;\n `\n : css`\n top: 0;\n left: 0;\n `}\n\n ${({ $background, $shouldPreventBackground, theme }) =>\n !$shouldPreventBackground &&\n css`\n background: ${$background || `rgba(${theme['text-rgb'] ?? '0,0,0'}, 0.1)`};\n box-shadow: 0 0 0 1px rgba(${theme['009-rgb']}, 0.08) inset;\n `}\n \n img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n`;\n\ntype StyledCornerImageProps = WithTheme<{\n $background?: CSSProperties['background'];\n $shouldPreventBackground?: boolean;\n $hasMultipleImages: boolean;\n}>;\n\nexport const StyledCornerImage = styled.img<StyledCornerImageProps>`\n aspect-ratio: 1;\n bottom: 0;\n height: ${({ $hasMultipleImages }) => ($hasMultipleImages ? '28%' : '38%')};\n position: absolute;\n right: 0;\n\n ${({ $background, $shouldPreventBackground, theme }) =>\n !$shouldPreventBackground &&\n css`\n background: ${$background || `rgba(${theme['text-rgb'] ?? '0,0,0'}, 0.1)`};\n box-shadow: 0 0 0 1px rgba(${theme['009-rgb']}, 0.08) inset;\n `}\n`;\n\nexport const StyledCornerElement = styled.span`\n height: 18px;\n width: 18px;\n position: absolute;\n bottom: 0;\n right: -5px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n & > * {\n max-height: 100%;\n max-width: 100%;\n display: block;\n }\n`;\n"],"mappings":"AAAA,OAAOA,MAAM,IAAIC,GAAG,QAAQ,mBAAmB;AAQ/C,OAAO,MAAMC,kBAAkB,GAAGF,MAAM,CAACG,GAA4B;AACrE;AACA,cAAc,CAAC;EAAEC;AAAQ,CAAC,KAAKA,OAAO;AACtC;AACA,aAAa,CAAC;EAAEA;AAAQ,CAAC,KAAKA,OAAO;AACrC;AACA;AACA;AACA;AACA,CAAC;AAYD,OAAO,MAAMC,uBAAuB,GAAGL,MAAM,CAACG,GAAG,CAACG,KAAK,CACnD,CAAC;EAAEC,cAAc;EAAEC,kBAAkB;EAAEC,eAAe;EAAEC;AAAM,CAAC,KAAK;EAChE,IAAIC,QAA4B;EAChC,IACKJ,cAAc,IAAIE,eAAe,IACjC,CAACF,cAAc,IAAI,CAACC,kBAAkB,IAAIC,eAAgB,EAC7D;IACEE,QAAQ,GAAG,sBAAsBD,KAAK,GAAG;EAC7C,CAAC,MAAM,IAAI,CAACH,cAAc,IAAIC,kBAAkB,EAAE;IAC9CG,QAAQ,GAAG,2BAA2BD,KAAK,GAAG;EAClD;EAEA,OAAO;IACHE,KAAK,EAAE;MACHD;IACJ;EACJ,CAAC;AACL,CACJ,CAAC;AACD;AACA,qBAAqB,CAAC;EAAEE;AAAsB,CAAC,KAAMA,qBAAqB,GAAG,KAAK,GAAG,GAAI;AACzF;AACA;AACA;AACA,MAAM,CAAC;EAAEL,kBAAkB;EAAED;AAAe,CAAC,KAAK;EAC1C,IAAI,CAACC,kBAAkB,EAAE;IACrB,OAAOP,GAAG;AACtB;AACA,aAAa;EACL;EAEA,IAAIM,cAAc,EAAE;IAChB,OAAON,GAAG;AACtB;AACA,aAAa;EACL;EAEA,OAAOA,GAAG;AAClB;AACA,SAAS;AACL,CAAC;AACL;AACA,MAAM,CAAC;EAAEM;AAAe,CAAC,KACjBA,cAAc,GACRN,GAAG;AACjB;AACA;AACA,eAAe,GACDA,GAAG;AACjB;AACA;AACA,eAAe;AACf;AACA,MAAM,CAAC;EAAEa,WAAW;EAAEC,wBAAwB;EAAEC;AAAM,CAAC,KAC/C,CAACD,wBAAwB,IACzBd,GAAG;AACX,0BAA0Ba,WAAW,IAAI,QAAQE,KAAK,CAAC,UAAU,CAAC,IAAI,OAAO,QAAQ;AACrF,yCAAyCA,KAAK,CAAC,SAAS,CAAC;AACzD,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAQD,OAAO,MAAMC,iBAAiB,GAAGjB,MAAM,CAACkB,GAA2B;AACnE;AACA;AACA,cAAc,CAAC;EAAEV;AAAmB,CAAC,KAAMA,kBAAkB,GAAG,KAAK,GAAG,KAAM;AAC9E;AACA;AACA;AACA,MAAM,CAAC;EAAEM,WAAW;EAAEC,wBAAwB;EAAEC;AAAM,CAAC,KAC/C,CAACD,wBAAwB,IACzBd,GAAG;AACX,0BAA0Ba,WAAW,IAAI,QAAQE,KAAK,CAAC,UAAU,CAAC,IAAI,OAAO,QAAQ;AACrF,yCAAyCA,KAAK,CAAC,SAAS,CAAC;AACzD,SAAS;AACT,CAAC;AAED,OAAO,MAAMG,mBAAmB,GAAGnB,MAAM,CAACoB,IAAI;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
@@ -1,4 +1,5 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useRef } from 'react';
2
+ import { useFocusRingPortal } from '../../../hooks/useFocusRingPortal';
2
3
  import { StyledHighlightSliderItem, StyledHighlightSliderItemBackground, StyledHighlightSliderItemProgress } from './HighlightSliderItem.styles';
3
4
  import { StyledProgressBarProgressWrapper } from '../../progress-bar/ProgressBar.styles';
4
5
  import { useUuid } from '../../../hooks/uuid';
@@ -14,8 +15,12 @@ const HighlightSliderItem = ({
14
15
  shouldEnableKeyboardHighlighting,
15
16
  shouldShowKeyboardHighlighting = false
16
17
  }) => {
18
+ const itemRef = useRef(null);
17
19
  const uuid = useUuid();
18
20
  const isKeyboardFocusable = isInteractive && shouldEnableKeyboardHighlighting;
21
+ useFocusRingPortal(itemRef, {
22
+ isEnabled: shouldShowKeyboardHighlighting
23
+ });
19
24
  const handleKeyDown = useCallback(event => {
20
25
  if (!isInteractive) {
21
26
  return;
@@ -26,11 +31,11 @@ const HighlightSliderItem = ({
26
31
  }
27
32
  }, [index, isInteractive, onClick]);
28
33
  return /*#__PURE__*/React.createElement(StyledHighlightSliderItem, {
34
+ ref: itemRef,
29
35
  onClick: isInteractive ? () => onClick(index) : undefined,
30
36
  onKeyDown: isKeyboardFocusable ? handleKeyDown : undefined,
31
37
  tabIndex: isKeyboardFocusable ? 0 : -1,
32
- role: isInteractive ? 'button' : undefined,
33
- $shouldShowKeyboardHighlighting: shouldShowKeyboardHighlighting
38
+ role: isInteractive ? 'button' : undefined
34
39
  }, /*#__PURE__*/React.createElement(StyledProgressBarProgressWrapper, null, isActive && /*#__PURE__*/React.createElement(StyledHighlightSliderItemProgress, {
35
40
  key: `highlight-slider-item-active--${uuid}`,
36
41
  initial: {
@@ -1 +1 @@
1
- {"version":3,"file":"HighlightSliderItem.js","names":["React","useCallback","StyledHighlightSliderItem","StyledHighlightSliderItemBackground","StyledHighlightSliderItemProgress","StyledProgressBarProgressWrapper","useUuid","HighlightSliderItem","colors","isActive","isFinished","onFinish","index","onClick","duration","isInteractive","shouldEnableKeyboardHighlighting","shouldShowKeyboardHighlighting","uuid","isKeyboardFocusable","handleKeyDown","event","key","preventDefault","createElement","undefined","onKeyDown","tabIndex","role","$shouldShowKeyboardHighlighting","initial","width","left","animate","exit","onAnimationComplete","$backgroundColor","fillColor","transition","ease","style","backgroundColor","displayName"],"sources":["../../../../../src/components/highlight-slider/highlight-slider-item/HighlightSliderItem.tsx"],"sourcesContent":["import React, { FC, KeyboardEventHandler, useCallback } from 'react';\nimport {\n StyledHighlightSliderItem,\n StyledHighlightSliderItemBackground,\n StyledHighlightSliderItemProgress,\n} from './HighlightSliderItem.styles';\nimport { StyledProgressBarProgressWrapper } from '../../progress-bar/ProgressBar.styles';\nimport { useUuid } from '../../../hooks/uuid';\n\nexport interface HighlightSliderItemColors {\n backgroundColor: string;\n fillColor: string;\n}\n\nexport type HighlightSliderItemProps = {\n index: number;\n isActive: boolean;\n isFinished: boolean;\n onClick: (index: number) => void;\n onFinish: (index: number) => void;\n duration: number;\n colors: HighlightSliderItemColors;\n isInteractive: boolean;\n shouldEnableKeyboardHighlighting?: boolean;\n shouldShowKeyboardHighlighting?: boolean;\n};\n\nconst HighlightSliderItem: FC<HighlightSliderItemProps> = ({\n colors,\n isActive,\n isFinished,\n onFinish,\n index,\n onClick,\n duration,\n isInteractive,\n shouldEnableKeyboardHighlighting,\n shouldShowKeyboardHighlighting = false,\n}) => {\n const uuid = useUuid();\n const isKeyboardFocusable = isInteractive && shouldEnableKeyboardHighlighting;\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLDivElement>>(\n (event) => {\n if (!isInteractive) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick(index);\n }\n },\n [index, isInteractive, onClick],\n );\n\n return (\n <StyledHighlightSliderItem\n onClick={isInteractive ? () => onClick(index) : undefined}\n onKeyDown={isKeyboardFocusable ? handleKeyDown : undefined}\n tabIndex={isKeyboardFocusable ? 0 : -1}\n role={isInteractive ? 'button' : undefined}\n $shouldShowKeyboardHighlighting={shouldShowKeyboardHighlighting}\n >\n <StyledProgressBarProgressWrapper>\n {isActive && (\n <StyledHighlightSliderItemProgress\n key={`highlight-slider-item-active--${uuid}`}\n initial={{ width: '100%', left: '-100%' }}\n animate={{ width: '100%', left: '0%' }}\n exit={{ width: '100%', left: '0%' }}\n onAnimationComplete={() => onFinish(index)}\n $backgroundColor={colors.fillColor}\n transition={{\n ease: 'linear',\n duration,\n }}\n />\n )}\n {isFinished && (\n <StyledHighlightSliderItemProgress\n key={`highlight-slider-item-finished--${uuid}`}\n style={{ width: '100%', left: '0%' }}\n $backgroundColor={colors.fillColor}\n />\n )}\n <StyledHighlightSliderItemBackground $backgroundColor={colors.backgroundColor} />\n </StyledProgressBarProgressWrapper>\n </StyledHighlightSliderItem>\n );\n};\n\nHighlightSliderItem.displayName = 'HighlightSliderItem';\n\nexport default HighlightSliderItem;\n"],"mappings":"AAAA,OAAOA,KAAK,IAA8BC,WAAW,QAAQ,OAAO;AACpE,SACIC,yBAAyB,EACzBC,mCAAmC,EACnCC,iCAAiC,QAC9B,8BAA8B;AACrC,SAASC,gCAAgC,QAAQ,uCAAuC;AACxF,SAASC,OAAO,QAAQ,qBAAqB;AAoB7C,MAAMC,mBAAiD,GAAGA,CAAC;EACvDC,MAAM;EACNC,QAAQ;EACRC,UAAU;EACVC,QAAQ;EACRC,KAAK;EACLC,OAAO;EACPC,QAAQ;EACRC,aAAa;EACbC,gCAAgC;EAChCC,8BAA8B,GAAG;AACrC,CAAC,KAAK;EACF,MAAMC,IAAI,GAAGZ,OAAO,CAAC,CAAC;EACtB,MAAMa,mBAAmB,GAAGJ,aAAa,IAAIC,gCAAgC;EAE7E,MAAMI,aAAa,GAAGnB,WAAW,CAC5BoB,KAAK,IAAK;IACP,IAAI,CAACN,aAAa,EAAE;MAChB;IACJ;IAEA,IAAIM,KAAK,CAACC,GAAG,KAAK,OAAO,IAAID,KAAK,CAACC,GAAG,KAAK,GAAG,EAAE;MAC5CD,KAAK,CAACE,cAAc,CAAC,CAAC;MACtBV,OAAO,CAACD,KAAK,CAAC;IAClB;EACJ,CAAC,EACD,CAACA,KAAK,EAAEG,aAAa,EAAEF,OAAO,CAClC,CAAC;EAED,oBACIb,KAAA,CAAAwB,aAAA,CAACtB,yBAAyB;IACtBW,OAAO,EAAEE,aAAa,GAAG,MAAMF,OAAO,CAACD,KAAK,CAAC,GAAGa,SAAU;IAC1DC,SAAS,EAAEP,mBAAmB,GAAGC,aAAa,GAAGK,SAAU;IAC3DE,QAAQ,EAAER,mBAAmB,GAAG,CAAC,GAAG,CAAC,CAAE;IACvCS,IAAI,EAAEb,aAAa,GAAG,QAAQ,GAAGU,SAAU;IAC3CI,+BAA+B,EAAEZ;EAA+B,gBAEhEjB,KAAA,CAAAwB,aAAA,CAACnB,gCAAgC,QAC5BI,QAAQ,iBACLT,KAAA,CAAAwB,aAAA,CAACpB,iCAAiC;IAC9BkB,GAAG,EAAE,iCAAiCJ,IAAI,EAAG;IAC7CY,OAAO,EAAE;MAAEC,KAAK,EAAE,MAAM;MAAEC,IAAI,EAAE;IAAQ,CAAE;IAC1CC,OAAO,EAAE;MAAEF,KAAK,EAAE,MAAM;MAAEC,IAAI,EAAE;IAAK,CAAE;IACvCE,IAAI,EAAE;MAAEH,KAAK,EAAE,MAAM;MAAEC,IAAI,EAAE;IAAK,CAAE;IACpCG,mBAAmB,EAAEA,CAAA,KAAMxB,QAAQ,CAACC,KAAK,CAAE;IAC3CwB,gBAAgB,EAAE5B,MAAM,CAAC6B,SAAU;IACnCC,UAAU,EAAE;MACRC,IAAI,EAAE,QAAQ;MACdzB;IACJ;EAAE,CACL,CACJ,EACAJ,UAAU,iBACPV,KAAA,CAAAwB,aAAA,CAACpB,iCAAiC;IAC9BkB,GAAG,EAAE,mCAAmCJ,IAAI,EAAG;IAC/CsB,KAAK,EAAE;MAAET,KAAK,EAAE,MAAM;MAAEC,IAAI,EAAE;IAAK,CAAE;IACrCI,gBAAgB,EAAE5B,MAAM,CAAC6B;EAAU,CACtC,CACJ,eACDrC,KAAA,CAAAwB,aAAA,CAACrB,mCAAmC;IAACiC,gBAAgB,EAAE5B,MAAM,CAACiC;EAAgB,CAAE,CAClD,CACX,CAAC;AAEpC,CAAC;AAEDlC,mBAAmB,CAACmC,WAAW,GAAG,qBAAqB;AAEvD,eAAenC,mBAAmB","ignoreList":[]}
1
+ {"version":3,"file":"HighlightSliderItem.js","names":["React","useCallback","useRef","useFocusRingPortal","StyledHighlightSliderItem","StyledHighlightSliderItemBackground","StyledHighlightSliderItemProgress","StyledProgressBarProgressWrapper","useUuid","HighlightSliderItem","colors","isActive","isFinished","onFinish","index","onClick","duration","isInteractive","shouldEnableKeyboardHighlighting","shouldShowKeyboardHighlighting","itemRef","uuid","isKeyboardFocusable","isEnabled","handleKeyDown","event","key","preventDefault","createElement","ref","undefined","onKeyDown","tabIndex","role","initial","width","left","animate","exit","onAnimationComplete","$backgroundColor","fillColor","transition","ease","style","backgroundColor","displayName"],"sources":["../../../../../src/components/highlight-slider/highlight-slider-item/HighlightSliderItem.tsx"],"sourcesContent":["import React, { FC, KeyboardEventHandler, useCallback, useRef } from 'react';\nimport { useFocusRingPortal } from '../../../hooks/useFocusRingPortal';\nimport {\n StyledHighlightSliderItem,\n StyledHighlightSliderItemBackground,\n StyledHighlightSliderItemProgress,\n} from './HighlightSliderItem.styles';\nimport { StyledProgressBarProgressWrapper } from '../../progress-bar/ProgressBar.styles';\nimport { useUuid } from '../../../hooks/uuid';\n\nexport interface HighlightSliderItemColors {\n backgroundColor: string;\n fillColor: string;\n}\n\nexport type HighlightSliderItemProps = {\n index: number;\n isActive: boolean;\n isFinished: boolean;\n onClick: (index: number) => void;\n onFinish: (index: number) => void;\n duration: number;\n colors: HighlightSliderItemColors;\n isInteractive: boolean;\n shouldEnableKeyboardHighlighting?: boolean;\n shouldShowKeyboardHighlighting?: boolean;\n};\n\nconst HighlightSliderItem: FC<HighlightSliderItemProps> = ({\n colors,\n isActive,\n isFinished,\n onFinish,\n index,\n onClick,\n duration,\n isInteractive,\n shouldEnableKeyboardHighlighting,\n shouldShowKeyboardHighlighting = false,\n}) => {\n const itemRef = useRef<HTMLDivElement>(null);\n const uuid = useUuid();\n const isKeyboardFocusable = isInteractive && shouldEnableKeyboardHighlighting;\n useFocusRingPortal(itemRef, { isEnabled: shouldShowKeyboardHighlighting });\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLDivElement>>(\n (event) => {\n if (!isInteractive) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick(index);\n }\n },\n [index, isInteractive, onClick],\n );\n\n return (\n <StyledHighlightSliderItem\n ref={itemRef}\n onClick={isInteractive ? () => onClick(index) : undefined}\n onKeyDown={isKeyboardFocusable ? handleKeyDown : undefined}\n tabIndex={isKeyboardFocusable ? 0 : -1}\n role={isInteractive ? 'button' : undefined}\n >\n <StyledProgressBarProgressWrapper>\n {isActive && (\n <StyledHighlightSliderItemProgress\n key={`highlight-slider-item-active--${uuid}`}\n initial={{ width: '100%', left: '-100%' }}\n animate={{ width: '100%', left: '0%' }}\n exit={{ width: '100%', left: '0%' }}\n onAnimationComplete={() => onFinish(index)}\n $backgroundColor={colors.fillColor}\n transition={{\n ease: 'linear',\n duration,\n }}\n />\n )}\n {isFinished && (\n <StyledHighlightSliderItemProgress\n key={`highlight-slider-item-finished--${uuid}`}\n style={{ width: '100%', left: '0%' }}\n $backgroundColor={colors.fillColor}\n />\n )}\n <StyledHighlightSliderItemBackground $backgroundColor={colors.backgroundColor} />\n </StyledProgressBarProgressWrapper>\n </StyledHighlightSliderItem>\n );\n};\n\nHighlightSliderItem.displayName = 'HighlightSliderItem';\n\nexport default HighlightSliderItem;\n"],"mappings":"AAAA,OAAOA,KAAK,IAA8BC,WAAW,EAAEC,MAAM,QAAQ,OAAO;AAC5E,SAASC,kBAAkB,QAAQ,mCAAmC;AACtE,SACIC,yBAAyB,EACzBC,mCAAmC,EACnCC,iCAAiC,QAC9B,8BAA8B;AACrC,SAASC,gCAAgC,QAAQ,uCAAuC;AACxF,SAASC,OAAO,QAAQ,qBAAqB;AAoB7C,MAAMC,mBAAiD,GAAGA,CAAC;EACvDC,MAAM;EACNC,QAAQ;EACRC,UAAU;EACVC,QAAQ;EACRC,KAAK;EACLC,OAAO;EACPC,QAAQ;EACRC,aAAa;EACbC,gCAAgC;EAChCC,8BAA8B,GAAG;AACrC,CAAC,KAAK;EACF,MAAMC,OAAO,GAAGlB,MAAM,CAAiB,IAAI,CAAC;EAC5C,MAAMmB,IAAI,GAAGb,OAAO,CAAC,CAAC;EACtB,MAAMc,mBAAmB,GAAGL,aAAa,IAAIC,gCAAgC;EAC7Ef,kBAAkB,CAACiB,OAAO,EAAE;IAAEG,SAAS,EAAEJ;EAA+B,CAAC,CAAC;EAE1E,MAAMK,aAAa,GAAGvB,WAAW,CAC5BwB,KAAK,IAAK;IACP,IAAI,CAACR,aAAa,EAAE;MAChB;IACJ;IAEA,IAAIQ,KAAK,CAACC,GAAG,KAAK,OAAO,IAAID,KAAK,CAACC,GAAG,KAAK,GAAG,EAAE;MAC5CD,KAAK,CAACE,cAAc,CAAC,CAAC;MACtBZ,OAAO,CAACD,KAAK,CAAC;IAClB;EACJ,CAAC,EACD,CAACA,KAAK,EAAEG,aAAa,EAAEF,OAAO,CAClC,CAAC;EAED,oBACIf,KAAA,CAAA4B,aAAA,CAACxB,yBAAyB;IACtByB,GAAG,EAAET,OAAQ;IACbL,OAAO,EAAEE,aAAa,GAAG,MAAMF,OAAO,CAACD,KAAK,CAAC,GAAGgB,SAAU;IAC1DC,SAAS,EAAET,mBAAmB,GAAGE,aAAa,GAAGM,SAAU;IAC3DE,QAAQ,EAAEV,mBAAmB,GAAG,CAAC,GAAG,CAAC,CAAE;IACvCW,IAAI,EAAEhB,aAAa,GAAG,QAAQ,GAAGa;EAAU,gBAE3C9B,KAAA,CAAA4B,aAAA,CAACrB,gCAAgC,QAC5BI,QAAQ,iBACLX,KAAA,CAAA4B,aAAA,CAACtB,iCAAiC;IAC9BoB,GAAG,EAAE,iCAAiCL,IAAI,EAAG;IAC7Ca,OAAO,EAAE;MAAEC,KAAK,EAAE,MAAM;MAAEC,IAAI,EAAE;IAAQ,CAAE;IAC1CC,OAAO,EAAE;MAAEF,KAAK,EAAE,MAAM;MAAEC,IAAI,EAAE;IAAK,CAAE;IACvCE,IAAI,EAAE;MAAEH,KAAK,EAAE,MAAM;MAAEC,IAAI,EAAE;IAAK,CAAE;IACpCG,mBAAmB,EAAEA,CAAA,KAAM1B,QAAQ,CAACC,KAAK,CAAE;IAC3C0B,gBAAgB,EAAE9B,MAAM,CAAC+B,SAAU;IACnCC,UAAU,EAAE;MACRC,IAAI,EAAE,QAAQ;MACd3B;IACJ;EAAE,CACL,CACJ,EACAJ,UAAU,iBACPZ,KAAA,CAAA4B,aAAA,CAACtB,iCAAiC;IAC9BoB,GAAG,EAAE,mCAAmCL,IAAI,EAAG;IAC/CuB,KAAK,EAAE;MAAET,KAAK,EAAE,MAAM;MAAEC,IAAI,EAAE;IAAK,CAAE;IACrCI,gBAAgB,EAAE9B,MAAM,CAAC+B;EAAU,CACtC,CACJ,eACDzC,KAAA,CAAA4B,aAAA,CAACvB,mCAAmC;IAACmC,gBAAgB,EAAE9B,MAAM,CAACmC;EAAgB,CAAE,CAClD,CACX,CAAC;AAEpC,CAAC;AAEDpC,mBAAmB,CAACqC,WAAW,GAAG,qBAAqB;AAEvD,eAAerC,mBAAmB","ignoreList":[]}
@@ -1,6 +1,5 @@
1
- import styled, { css } from 'styled-components';
1
+ import styled from 'styled-components';
2
2
  import { motion } from 'motion/react';
3
- import { keyboardFocusHighlightingRingCss } from '../../../utils/keyboardFocusHighlighting.styles';
4
3
  export const StyledHighlightSliderItem = styled.div`
5
4
  overflow: hidden;
6
5
  position: relative;
@@ -9,13 +8,9 @@ export const StyledHighlightSliderItem = styled.div`
9
8
  border-radius: 4px;
10
9
  cursor: pointer;
11
10
 
12
- ${({
13
- $shouldShowKeyboardHighlighting
14
- }) => $shouldShowKeyboardHighlighting && css`
15
- &:focus-visible {
16
- ${keyboardFocusHighlightingRingCss}
17
- }
18
- `}
11
+ &:focus-visible {
12
+ outline: none;
13
+ }
19
14
  `;
20
15
  export const StyledHighlightSliderItemProgress = styled(motion.div)`
21
16
  height: 4px;
@@ -1 +1 @@
1
- {"version":3,"file":"HighlightSliderItem.styles.js","names":["styled","css","motion","keyboardFocusHighlightingRingCss","StyledHighlightSliderItem","div","$shouldShowKeyboardHighlighting","StyledHighlightSliderItemProgress","$backgroundColor","StyledHighlightSliderItemBackground"],"sources":["../../../../../src/components/highlight-slider/highlight-slider-item/HighlightSliderItem.styles.ts"],"sourcesContent":["import styled, { css } from 'styled-components';\nimport { motion } from 'motion/react';\nimport { WithTheme } from '../../color-scheme-provider/ColorSchemeProvider';\nimport { keyboardFocusHighlightingRingCss } from '../../../utils/keyboardFocusHighlighting.styles';\n\ntype StyledHighlightSliderItemProps = {\n $shouldShowKeyboardHighlighting?: boolean;\n};\n\nexport const StyledHighlightSliderItem = styled.div<StyledHighlightSliderItemProps>`\n overflow: hidden;\n position: relative;\n width: 100%;\n height: 4px;\n border-radius: 4px;\n cursor: pointer;\n\n ${({ $shouldShowKeyboardHighlighting }) =>\n $shouldShowKeyboardHighlighting &&\n css`\n &:focus-visible {\n ${keyboardFocusHighlightingRingCss}\n }\n `}\n`;\ntype StyledHighlightSliderItemProgressProps = WithTheme<{ $backgroundColor: string }>;\n\nexport const StyledHighlightSliderItemProgress = styled(\n motion.div,\n)<StyledHighlightSliderItemProgressProps>`\n height: 4px;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n background-color: ${({ $backgroundColor }: StyledHighlightSliderItemProgressProps) =>\n $backgroundColor};\n`;\n\ntype StyledHighlightSliderItemBackgroundProps = WithTheme<{ $backgroundColor: string }>;\n\nexport const StyledHighlightSliderItemBackground = styled(\n motion.div,\n)<StyledHighlightSliderItemBackgroundProps>`\n height: 4px;\n width: 100%;\n border-radius: 2px;\n background-color: ${({ $backgroundColor }: StyledHighlightSliderItemBackgroundProps) =>\n $backgroundColor};\n`;\n"],"mappings":"AAAA,OAAOA,MAAM,IAAIC,GAAG,QAAQ,mBAAmB;AAC/C,SAASC,MAAM,QAAQ,cAAc;AAErC,SAASC,gCAAgC,QAAQ,iDAAiD;AAMlG,OAAO,MAAMC,yBAAyB,GAAGJ,MAAM,CAACK,GAAmC;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,CAAC;EAAEC;AAAgC,CAAC,KAClCA,+BAA+B,IAC/BL,GAAG;AACX;AACA,kBAAkBE,gCAAgC;AAClD;AACA,SAAS;AACT,CAAC;AAGD,OAAO,MAAMI,iCAAiC,GAAGP,MAAM,CACnDE,MAAM,CAACG,GACX,CAAyC;AACzC;AACA;AACA;AACA;AACA;AACA,wBAAwB,CAAC;EAAEG;AAAyD,CAAC,KAC7EA,gBAAgB;AACxB,CAAC;AAID,OAAO,MAAMC,mCAAmC,GAAGT,MAAM,CACrDE,MAAM,CAACG,GACX,CAA2C;AAC3C;AACA;AACA;AACA,wBAAwB,CAAC;EAAEG;AAA2D,CAAC,KAC/EA,gBAAgB;AACxB,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"HighlightSliderItem.styles.js","names":["styled","motion","StyledHighlightSliderItem","div","StyledHighlightSliderItemProgress","$backgroundColor","StyledHighlightSliderItemBackground"],"sources":["../../../../../src/components/highlight-slider/highlight-slider-item/HighlightSliderItem.styles.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { motion } from 'motion/react';\nimport { WithTheme } from '../../color-scheme-provider/ColorSchemeProvider';\n\nexport const StyledHighlightSliderItem = styled.div`\n overflow: hidden;\n position: relative;\n width: 100%;\n height: 4px;\n border-radius: 4px;\n cursor: pointer;\n\n &:focus-visible {\n outline: none;\n }\n`;\ntype StyledHighlightSliderItemProgressProps = WithTheme<{ $backgroundColor: string }>;\n\nexport const StyledHighlightSliderItemProgress = styled(\n motion.div,\n)<StyledHighlightSliderItemProgressProps>`\n height: 4px;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n background-color: ${({ $backgroundColor }: StyledHighlightSliderItemProgressProps) =>\n $backgroundColor};\n`;\n\ntype StyledHighlightSliderItemBackgroundProps = WithTheme<{ $backgroundColor: string }>;\n\nexport const StyledHighlightSliderItemBackground = styled(\n motion.div,\n)<StyledHighlightSliderItemBackgroundProps>`\n height: 4px;\n width: 100%;\n border-radius: 2px;\n background-color: ${({ $backgroundColor }: StyledHighlightSliderItemBackgroundProps) =>\n $backgroundColor};\n`;\n"],"mappings":"AAAA,OAAOA,MAAM,MAAM,mBAAmB;AACtC,SAASC,MAAM,QAAQ,cAAc;AAGrC,OAAO,MAAMC,yBAAyB,GAAGF,MAAM,CAACG,GAAG;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAGD,OAAO,MAAMC,iCAAiC,GAAGJ,MAAM,CACnDC,MAAM,CAACE,GACX,CAAyC;AACzC;AACA;AACA;AACA;AACA;AACA,wBAAwB,CAAC;EAAEE;AAAyD,CAAC,KAC7EA,gBAAgB;AACxB,CAAC;AAID,OAAO,MAAMC,mCAAmC,GAAGN,MAAM,CACrDC,MAAM,CAACE,GACX,CAA2C;AAC3C;AACA;AACA;AACA,wBAAwB,CAAC;EAAEE;AAA2D,CAAC,KAC/EA,gBAAgB;AACxB,CAAC","ignoreList":[]}
@@ -1,6 +1,7 @@
1
1
  import clsx from 'clsx';
2
- import React from 'react';
2
+ import React, { useRef } from 'react';
3
3
  import { getStackSizeFactor } from '../../utils/icon';
4
+ import { useFocusRingPortal } from '../../hooks/useFocusRingPortal';
4
5
  import { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';
5
6
  import { useColorScheme } from '../color-scheme-provider/ColorSchemeProvider';
6
7
  import { StyledIcon as StyledIconElement, StyledIconWrapper } from './Icon.styles';
@@ -18,11 +19,17 @@ const Icon = ({
18
19
  shouldStopPropagation,
19
20
  shouldEnableKeyboardHighlighting
20
21
  }) => {
22
+ const iconWrapperRef = useRef(null);
21
23
  const theme = useTheme();
22
24
  const colorScheme = useColorScheme();
23
25
  const shouldEnableKeyboardHighlightingEffective = shouldEnableKeyboardHighlighting ?? colorScheme?.shouldEnableKeyboardHighlighting ?? false;
24
26
  const isClickable = typeof onClick === 'function' && !isDisabled;
25
27
  const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(shouldEnableKeyboardHighlightingEffective && isClickable);
28
+ useFocusRingPortal(iconWrapperRef, {
29
+ isEnabled: shouldShowKeyboardHighlighting,
30
+ shape: 'circle',
31
+ padding: 4
32
+ });
26
33
  const handleClick = event => {
27
34
  if (shouldStopPropagation) {
28
35
  event.stopPropagation();
@@ -58,6 +65,7 @@ const Icon = ({
58
65
  const shouldUseStackedIcon = icons.length > 1;
59
66
  const wrapperClasses = clsx('beta-chayns-icon', shouldUseStackedIcon ? 'fa-stack' : '', className);
60
67
  return /*#__PURE__*/React.createElement(StyledIconWrapper, {
68
+ ref: iconWrapperRef,
61
69
  tabIndex: shouldEnableKeyboardHighlightingEffective && isClickable ? tabIndex ?? 0 : tabIndex,
62
70
  className: wrapperClasses,
63
71
  $isDisabled: isDisabled,
@@ -66,7 +74,6 @@ const Icon = ({
66
74
  onDoubleClick: typeof onDoubleClick === 'function' && !isDisabled ? handleDoubleClick : undefined,
67
75
  onMouseDown: typeof onMouseDown === 'function' && !isDisabled ? onMouseDown : undefined,
68
76
  onKeyDown: shouldEnableKeyboardHighlightingEffective ? handleKeyDown : undefined,
69
- $shouldShowKeyboardHighlighting: shouldShowKeyboardHighlighting,
70
77
  $size: size,
71
78
  role: isClickable ? 'button' : undefined
72
79
  }, icons.map(icon => {
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.js","names":["clsx","React","getStackSizeFactor","useKeyboardFocusHighlighting","useColorScheme","StyledIcon","StyledIconElement","StyledIconWrapper","useTheme","Icon","className","color","icons","isDisabled","onClick","onDoubleClick","onMouseDown","tabIndex","size","shouldStopPropagation","shouldEnableKeyboardHighlighting","theme","colorScheme","shouldEnableKeyboardHighlightingEffective","isClickable","shouldShowKeyboardHighlighting","handleClick","event","stopPropagation","handleDoubleClick","handleKeyDown","key","preventDefault","maxStackSizeFactor","forEach","icon","stackSizeFactor","shouldUseStackedIcon","length","wrapperClasses","createElement","$isDisabled","undefined","$isOnClick","onKeyDown","$shouldShowKeyboardHighlighting","$size","role","map","iconStyle","themedIcon","replace","iconClasses","$color","includes","$fontSize","$isStacked","displayName"],"sources":["../../../../src/components/icon/Icon.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport React, { FC, KeyboardEventHandler, MouseEventHandler } from 'react';\nimport { getStackSizeFactor } from '../../utils/icon';\nimport { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';\nimport { useColorScheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport { StyledIcon as StyledIconElement, StyledIconWrapper } from './Icon.styles';\nimport { useTheme } from 'styled-components';\nimport type { Theme } from '../color-scheme-provider/ColorSchemeProvider';\n\nexport type IconProps = {\n /**\n * Additional class name for the icon wrapper element.\n * @description\n * This class name is applied to the wrapper element that contains the icon. It can be used to\n * style the icon wrapper element.\n * @example\n * <Icon className=\"my-custom-class\" icons={['fa-user']} />\n * @optional\n */\n className?: string;\n /**\n * The color of the icon.\n * @description\n * This property can be used to set the color of the icon. The color is only used for icons that\n * don't have a predefined color (e.g., 'fa-inverse' icons will always be white). If no color is\n * specified, the icon color of the theme or the text color will be used.\n * @example\n * <Icon color=\"red\" icons={['fa-user']} />\n * @optional\n */\n color?: string;\n /**\n * The icon(s) to be displayed.\n * @description\n * This property can be used to set the icon(s) to be displayed. The icon(s) must be specified as\n * an array of strings. Each string must be a valid icon name.\n * @example\n * <Icon icons={['fa-user']} />\n * <Icon icons={['fa fa-circle fa-stack-2x', 'fa fa-french-fries fa-inverse']} />\n */\n icons: string[];\n /**\n * Whether the icon should be disabled.\n * @description\n * This property can be used to disable the icon. When the icon is disabled, it will not be\n * clickable, and it will not emit any events.\n * @example\n * <Icon icons={['fa-user']} isDisabled />\n * @optional\n */\n isDisabled?: boolean;\n /**\n * Function to be executed when the icon is clicked.\n * @description\n * This function is executed when the icon is clicked. It can be used to handle the click event.\n * @example\n * <Icon icons={['fa-user']} onClick={() => console.log('Icon clicked')} />\n * @optional\n */\n onClick?: MouseEventHandler<HTMLSpanElement>;\n /**\n * Function to be executed when the icon is double-clicked.\n * @description\n * This function is executed when the icon is double-clicked. It can be used to handle the\n * double-click event.\n * @example\n * <Icon icons={['fa-user']} onDoubleClick={() => console.log('Icon double-clicked')} />\n * @optional\n */\n onDoubleClick?: MouseEventHandler<HTMLSpanElement>;\n /**\n * Function to be executed when the icon is pressed.\n * @description\n * This function is executed when the icon is pressed. It can be used to handle the mouse down event.\n * @example\n * <Icon icons={['fa-user']} onMouseDown={() => console.log('Icon pressed')} />\n * @optional\n */\n onMouseDown?: MouseEventHandler<HTMLSpanElement>;\n /**\n * The size of the icon.\n * @description\n * This property can be used to set the size of the icon. The size must be specified as a number\n * in pixels.\n * @default 15\n * @example\n * <Icon icons={['fa-user']} size={20} />\n * @optional\n */\n size?: number;\n /**\n * Stops event propagation on click.\n * @description\n * This property can be used to prevent the icon from propagating the click event to its parent\n * elements.\n * @example\n * <Icon icons={['fa-user']} shouldStopPropagation />\n * @optional\n */\n shouldStopPropagation?: boolean;\n /**\n * Optional tab index for the icon.\n */\n tabIndex?: number;\n /**\n * Enables keyboard-only focus highlighting for clickable icons.\n */\n shouldEnableKeyboardHighlighting?: boolean;\n};\n\nconst Icon: FC<IconProps> = ({\n className,\n color,\n icons,\n isDisabled,\n onClick,\n onDoubleClick,\n onMouseDown,\n tabIndex,\n size = 15,\n shouldStopPropagation,\n shouldEnableKeyboardHighlighting,\n}) => {\n const theme = useTheme() as Theme;\n const colorScheme = useColorScheme();\n const shouldEnableKeyboardHighlightingEffective =\n shouldEnableKeyboardHighlighting ?? colorScheme?.shouldEnableKeyboardHighlighting ?? false;\n\n const isClickable = typeof onClick === 'function' && !isDisabled;\n const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(\n shouldEnableKeyboardHighlightingEffective && isClickable,\n );\n\n const handleClick: MouseEventHandler<HTMLSpanElement> = (event) => {\n if (shouldStopPropagation) {\n event.stopPropagation();\n }\n\n if (typeof onClick === 'function') {\n onClick(event);\n }\n };\n\n const handleDoubleClick: MouseEventHandler<HTMLSpanElement> = (event) => {\n if (shouldStopPropagation) {\n event.stopPropagation();\n }\n\n if (typeof onDoubleClick === 'function') {\n onDoubleClick(event);\n }\n };\n\n const handleKeyDown: KeyboardEventHandler<HTMLSpanElement> = (event) => {\n if (!isClickable) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleClick(event as unknown as React.MouseEvent<HTMLSpanElement>);\n }\n };\n\n let maxStackSizeFactor = 1;\n\n icons.forEach((icon) => {\n const stackSizeFactor = getStackSizeFactor(icon);\n\n if (stackSizeFactor && stackSizeFactor > maxStackSizeFactor) {\n maxStackSizeFactor = stackSizeFactor;\n }\n });\n\n const shouldUseStackedIcon = icons.length > 1;\n\n const wrapperClasses = clsx(\n 'beta-chayns-icon',\n shouldUseStackedIcon ? 'fa-stack' : '',\n className,\n );\n\n return (\n <StyledIconWrapper\n tabIndex={\n shouldEnableKeyboardHighlightingEffective && isClickable\n ? (tabIndex ?? 0)\n : tabIndex\n }\n className={wrapperClasses}\n $isDisabled={isDisabled}\n onClick={isClickable ? handleClick : undefined}\n $isOnClick={isClickable}\n onDoubleClick={\n typeof onDoubleClick === 'function' && !isDisabled ? handleDoubleClick : undefined\n }\n onMouseDown={typeof onMouseDown === 'function' && !isDisabled ? onMouseDown : undefined}\n onKeyDown={shouldEnableKeyboardHighlightingEffective ? handleKeyDown : undefined}\n $shouldShowKeyboardHighlighting={shouldShowKeyboardHighlighting}\n $size={size}\n role={isClickable ? 'button' : undefined}\n >\n {icons.map((icon) => {\n const stackSizeFactor = getStackSizeFactor(icon);\n\n const iconStyle = `${(theme?.iconStyle as string) ?? 'fa-regular'} `;\n const themedIcon = icon?.replace(/^fa\\s/, iconStyle);\n\n const iconClasses = clsx(themedIcon, {\n 'fa-stack-1x': shouldUseStackedIcon && stackSizeFactor === undefined,\n });\n\n return (\n <StyledIconElement\n className={iconClasses}\n $color={icon.includes('fa-inverse') ? 'white' : color}\n $fontSize={((stackSizeFactor || 1) / maxStackSizeFactor) * size}\n $isStacked={shouldUseStackedIcon}\n key={icon}\n $size={size}\n />\n );\n })}\n </StyledIconWrapper>\n );\n};\n\nIcon.displayName = 'Icon';\n\nexport default Icon;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Icon.js","names":["clsx","React","useRef","getStackSizeFactor","useFocusRingPortal","useKeyboardFocusHighlighting","useColorScheme","StyledIcon","StyledIconElement","StyledIconWrapper","useTheme","Icon","className","color","icons","isDisabled","onClick","onDoubleClick","onMouseDown","tabIndex","size","shouldStopPropagation","shouldEnableKeyboardHighlighting","iconWrapperRef","theme","colorScheme","shouldEnableKeyboardHighlightingEffective","isClickable","shouldShowKeyboardHighlighting","isEnabled","shape","padding","handleClick","event","stopPropagation","handleDoubleClick","handleKeyDown","key","preventDefault","maxStackSizeFactor","forEach","icon","stackSizeFactor","shouldUseStackedIcon","length","wrapperClasses","createElement","ref","$isDisabled","undefined","$isOnClick","onKeyDown","$size","role","map","iconStyle","themedIcon","replace","iconClasses","$color","includes","$fontSize","$isStacked","displayName"],"sources":["../../../../src/components/icon/Icon.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport React, { FC, KeyboardEventHandler, MouseEventHandler, useRef } from 'react';\nimport { getStackSizeFactor } from '../../utils/icon';\nimport { useFocusRingPortal } from '../../hooks/useFocusRingPortal';\nimport { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';\nimport { useColorScheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport { StyledIcon as StyledIconElement, StyledIconWrapper } from './Icon.styles';\nimport { useTheme } from 'styled-components';\nimport type { Theme } from '../color-scheme-provider/ColorSchemeProvider';\n\nexport type IconProps = {\n /**\n * Additional class name for the icon wrapper element.\n * @description\n * This class name is applied to the wrapper element that contains the icon. It can be used to\n * style the icon wrapper element.\n * @example\n * <Icon className=\"my-custom-class\" icons={['fa-user']} />\n * @optional\n */\n className?: string;\n /**\n * The color of the icon.\n * @description\n * This property can be used to set the color of the icon. The color is only used for icons that\n * don't have a predefined color (e.g., 'fa-inverse' icons will always be white). If no color is\n * specified, the icon color of the theme or the text color will be used.\n * @example\n * <Icon color=\"red\" icons={['fa-user']} />\n * @optional\n */\n color?: string;\n /**\n * The icon(s) to be displayed.\n * @description\n * This property can be used to set the icon(s) to be displayed. The icon(s) must be specified as\n * an array of strings. Each string must be a valid icon name.\n * @example\n * <Icon icons={['fa-user']} />\n * <Icon icons={['fa fa-circle fa-stack-2x', 'fa fa-french-fries fa-inverse']} />\n */\n icons: string[];\n /**\n * Whether the icon should be disabled.\n * @description\n * This property can be used to disable the icon. When the icon is disabled, it will not be\n * clickable, and it will not emit any events.\n * @example\n * <Icon icons={['fa-user']} isDisabled />\n * @optional\n */\n isDisabled?: boolean;\n /**\n * Function to be executed when the icon is clicked.\n * @description\n * This function is executed when the icon is clicked. It can be used to handle the click event.\n * @example\n * <Icon icons={['fa-user']} onClick={() => console.log('Icon clicked')} />\n * @optional\n */\n onClick?: MouseEventHandler<HTMLSpanElement>;\n /**\n * Function to be executed when the icon is double-clicked.\n * @description\n * This function is executed when the icon is double-clicked. It can be used to handle the\n * double-click event.\n * @example\n * <Icon icons={['fa-user']} onDoubleClick={() => console.log('Icon double-clicked')} />\n * @optional\n */\n onDoubleClick?: MouseEventHandler<HTMLSpanElement>;\n /**\n * Function to be executed when the icon is pressed.\n * @description\n * This function is executed when the icon is pressed. It can be used to handle the mouse down event.\n * @example\n * <Icon icons={['fa-user']} onMouseDown={() => console.log('Icon pressed')} />\n * @optional\n */\n onMouseDown?: MouseEventHandler<HTMLSpanElement>;\n /**\n * The size of the icon.\n * @description\n * This property can be used to set the size of the icon. The size must be specified as a number\n * in pixels.\n * @default 15\n * @example\n * <Icon icons={['fa-user']} size={20} />\n * @optional\n */\n size?: number;\n /**\n * Stops event propagation on click.\n * @description\n * This property can be used to prevent the icon from propagating the click event to its parent\n * elements.\n * @example\n * <Icon icons={['fa-user']} shouldStopPropagation />\n * @optional\n */\n shouldStopPropagation?: boolean;\n /**\n * Optional tab index for the icon.\n */\n tabIndex?: number;\n /**\n * Enables keyboard-only focus highlighting for clickable icons.\n */\n shouldEnableKeyboardHighlighting?: boolean;\n};\n\nconst Icon: FC<IconProps> = ({\n className,\n color,\n icons,\n isDisabled,\n onClick,\n onDoubleClick,\n onMouseDown,\n tabIndex,\n size = 15,\n shouldStopPropagation,\n shouldEnableKeyboardHighlighting,\n}) => {\n const iconWrapperRef = useRef<HTMLSpanElement>(null);\n const theme = useTheme() as Theme;\n const colorScheme = useColorScheme();\n const shouldEnableKeyboardHighlightingEffective =\n shouldEnableKeyboardHighlighting ?? colorScheme?.shouldEnableKeyboardHighlighting ?? false;\n\n const isClickable = typeof onClick === 'function' && !isDisabled;\n const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(\n shouldEnableKeyboardHighlightingEffective && isClickable,\n );\n useFocusRingPortal(iconWrapperRef, {\n isEnabled: shouldShowKeyboardHighlighting,\n shape: 'circle',\n padding: 4,\n });\n\n const handleClick: MouseEventHandler<HTMLSpanElement> = (event) => {\n if (shouldStopPropagation) {\n event.stopPropagation();\n }\n\n if (typeof onClick === 'function') {\n onClick(event);\n }\n };\n\n const handleDoubleClick: MouseEventHandler<HTMLSpanElement> = (event) => {\n if (shouldStopPropagation) {\n event.stopPropagation();\n }\n\n if (typeof onDoubleClick === 'function') {\n onDoubleClick(event);\n }\n };\n\n const handleKeyDown: KeyboardEventHandler<HTMLSpanElement> = (event) => {\n if (!isClickable) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleClick(event as unknown as React.MouseEvent<HTMLSpanElement>);\n }\n };\n\n let maxStackSizeFactor = 1;\n\n icons.forEach((icon) => {\n const stackSizeFactor = getStackSizeFactor(icon);\n\n if (stackSizeFactor && stackSizeFactor > maxStackSizeFactor) {\n maxStackSizeFactor = stackSizeFactor;\n }\n });\n\n const shouldUseStackedIcon = icons.length > 1;\n\n const wrapperClasses = clsx(\n 'beta-chayns-icon',\n shouldUseStackedIcon ? 'fa-stack' : '',\n className,\n );\n\n return (\n <StyledIconWrapper\n ref={iconWrapperRef}\n tabIndex={\n shouldEnableKeyboardHighlightingEffective && isClickable\n ? (tabIndex ?? 0)\n : tabIndex\n }\n className={wrapperClasses}\n $isDisabled={isDisabled}\n onClick={isClickable ? handleClick : undefined}\n $isOnClick={isClickable}\n onDoubleClick={\n typeof onDoubleClick === 'function' && !isDisabled ? handleDoubleClick : undefined\n }\n onMouseDown={typeof onMouseDown === 'function' && !isDisabled ? onMouseDown : undefined}\n onKeyDown={shouldEnableKeyboardHighlightingEffective ? handleKeyDown : undefined}\n $size={size}\n role={isClickable ? 'button' : undefined}\n >\n {icons.map((icon) => {\n const stackSizeFactor = getStackSizeFactor(icon);\n\n const iconStyle = `${(theme?.iconStyle as string) ?? 'fa-regular'} `;\n const themedIcon = icon?.replace(/^fa\\s/, iconStyle);\n\n const iconClasses = clsx(themedIcon, {\n 'fa-stack-1x': shouldUseStackedIcon && stackSizeFactor === undefined,\n });\n\n return (\n <StyledIconElement\n className={iconClasses}\n $color={icon.includes('fa-inverse') ? 'white' : color}\n $fontSize={((stackSizeFactor || 1) / maxStackSizeFactor) * size}\n $isStacked={shouldUseStackedIcon}\n key={icon}\n $size={size}\n />\n );\n })}\n </StyledIconWrapper>\n );\n};\n\nIcon.displayName = 'Icon';\n\nexport default Icon;\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,4 @@
1
1
  import styled, { css } from 'styled-components';
2
- import { keyboardFocusHighlightingCircleRingCss } from '../../utils/keyboardFocusHighlighting.styles';
3
2
  export const StyledIconWrapper = styled.span`
4
3
  align-items: center;
5
4
  cursor: ${({
@@ -20,27 +19,10 @@ export const StyledIconWrapper = styled.span`
20
19
  $size
21
20
  }) => `${$size}px`};
22
21
 
23
- ${({
24
- $shouldShowKeyboardHighlighting,
25
- $size
26
- }) => $shouldShowKeyboardHighlighting && css`
27
- &:focus-visible {
28
- outline: none;
29
- color: inherit;
30
- }
31
-
32
- &:focus-visible::after {
33
- ${keyboardFocusHighlightingCircleRingCss};
34
- content: '';
35
- position: absolute;
36
- top: 50%;
37
- left: 50%;
38
- width: ${$size + 14}px;
39
- height: ${$size + 14}px;
40
- transform: translate(-50%, -50%);
41
- pointer-events: none;
42
- }
43
- `}
22
+ &:focus-visible {
23
+ outline: none;
24
+ color: inherit;
25
+ }
44
26
 
45
27
  // To insure that stacked icons have the same size as normal icons.
46
28
  &&.fa-stack {
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.styles.js","names":["styled","css","keyboardFocusHighlightingCircleRingCss","StyledIconWrapper","span","$isDisabled","$isOnClick","$size","$shouldShowKeyboardHighlighting","StyledIcon","i","$color","theme","iconColor","text","$isStacked","undefined","$fontSize","StyledUnicodeIcon","headline","$icon","iconStyle"],"sources":["../../../../src/components/icon/Icon.styles.ts"],"sourcesContent":["import styled, { css } from 'styled-components';\nimport type { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport { keyboardFocusHighlightingCircleRingCss } from '../../utils/keyboardFocusHighlighting.styles';\n\ntype StyledIconWrapperProps = {\n $isDisabled?: boolean;\n $isOnClick: boolean;\n $size: number;\n $shouldShowKeyboardHighlighting?: boolean;\n};\n\nexport const StyledIconWrapper = styled.span<StyledIconWrapperProps>`\n align-items: center;\n cursor: ${({ $isDisabled, $isOnClick }) =>\n $isOnClick && !$isDisabled ? 'pointer' : 'inherit'};\n display: inline-flex;\n min-height: ${({ $size }) => `${$size}px`};\n justify-content: center;\n opacity: ${({ $isDisabled }) => ($isDisabled ? 0.5 : 1)};\n position: relative;\n transition: opacity 0.3s ease;\n min-width: ${({ $size }) => `${$size}px`};\n\n ${({ $shouldShowKeyboardHighlighting, $size }) =>\n $shouldShowKeyboardHighlighting &&\n css`\n &:focus-visible {\n outline: none;\n color: inherit;\n }\n\n &:focus-visible::after {\n ${keyboardFocusHighlightingCircleRingCss};\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: ${$size + 14}px;\n height: ${$size + 14}px;\n transform: translate(-50%, -50%);\n pointer-events: none;\n }\n `}\n\n // To insure that stacked icons have the same size as normal icons.\n &&.fa-stack {\n height: fit-content;\n width: fit-content;\n line-height: ${({ $size }) => $size}px;\n }\n`;\n\ntype StyledIconProps = WithTheme<{\n $fontSize: number;\n $isStacked?: boolean;\n $color?: string;\n $size: number;\n}>;\n\nexport const StyledIcon = styled.i<StyledIconProps>`\n color: ${({ $color, theme }: StyledIconProps) => $color || theme.iconColor || theme.text};\n display: ${({ $isStacked }) => ($isStacked ? undefined : 'inline-flex')};\n font-size: ${({ $fontSize }) => `${$fontSize}px`};\n\n ${({ $fontSize, $size }) =>\n $fontSize !== $size &&\n css`\n top: 50%;\n transform: translateY(-50%);\n `}\n`;\n\ntype StyledUnicodeIconProps = WithTheme<{ $icon: string }>;\n\nexport const StyledUnicodeIcon = styled.i<StyledUnicodeIconProps>`\n align-items: center;\n justify-content: center;\n display: flex;\n color: ${({ theme }: StyledUnicodeIconProps) => theme.iconColor || theme.headline};\n\n &:before {\n content: ${({ $icon }) => `\"\\\\${$icon}\" !important`};\n }\n &:after {\n content: ${({ theme, $icon }) => {\n if (theme.iconStyle === 'fa-duotone') {\n return `\"\\\\${$icon}\" !important`;\n }\n return '';\n }};\n }\n`;\n"],"mappings":"AAAA,OAAOA,MAAM,IAAIC,GAAG,QAAQ,mBAAmB;AAE/C,SAASC,sCAAsC,QAAQ,8CAA8C;AASrG,OAAO,MAAMC,iBAAiB,GAAGH,MAAM,CAACI,IAA4B;AACpE;AACA,cAAc,CAAC;EAAEC,WAAW;EAAEC;AAAW,CAAC,KAClCA,UAAU,IAAI,CAACD,WAAW,GAAG,SAAS,GAAG,SAAS;AAC1D;AACA,kBAAkB,CAAC;EAAEE;AAAM,CAAC,KAAK,GAAGA,KAAK,IAAI;AAC7C;AACA,eAAe,CAAC;EAAEF;AAAY,CAAC,KAAMA,WAAW,GAAG,GAAG,GAAG,CAAE;AAC3D;AACA;AACA,iBAAiB,CAAC;EAAEE;AAAM,CAAC,KAAK,GAAGA,KAAK,IAAI;AAC5C;AACA,MAAM,CAAC;EAAEC,+BAA+B;EAAED;AAAM,CAAC,KACzCC,+BAA+B,IAC/BP,GAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkBC,sCAAsC;AACxD;AACA;AACA;AACA;AACA,yBAAyBK,KAAK,GAAG,EAAE;AACnC,0BAA0BA,KAAK,GAAG,EAAE;AACpC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,uBAAuB,CAAC;EAAEA;AAAM,CAAC,KAAKA,KAAK;AAC3C;AACA,CAAC;AASD,OAAO,MAAME,UAAU,GAAGT,MAAM,CAACU,CAAkB;AACnD,aAAa,CAAC;EAAEC,MAAM;EAAEC;AAAuB,CAAC,KAAKD,MAAM,IAAIC,KAAK,CAACC,SAAS,IAAID,KAAK,CAACE,IAAI;AAC5F,eAAe,CAAC;EAAEC;AAAW,CAAC,KAAMA,UAAU,GAAGC,SAAS,GAAG,aAAc;AAC3E,iBAAiB,CAAC;EAAEC;AAAU,CAAC,KAAK,GAAGA,SAAS,IAAI;AACpD;AACA,MAAM,CAAC;EAAEA,SAAS;EAAEV;AAAM,CAAC,KACnBU,SAAS,KAAKV,KAAK,IACnBN,GAAG;AACX;AACA;AACA,SAAS;AACT,CAAC;AAID,OAAO,MAAMiB,iBAAiB,GAAGlB,MAAM,CAACU,CAAyB;AACjE;AACA;AACA;AACA,aAAa,CAAC;EAAEE;AAA8B,CAAC,KAAKA,KAAK,CAACC,SAAS,IAAID,KAAK,CAACO,QAAQ;AACrF;AACA;AACA,mBAAmB,CAAC;EAAEC;AAAM,CAAC,KAAK,MAAMA,KAAK,cAAc;AAC3D;AACA;AACA,mBAAmB,CAAC;EAAER,KAAK;EAAEQ;AAAM,CAAC,KAAK;EAC7B,IAAIR,KAAK,CAACS,SAAS,KAAK,YAAY,EAAE;IAClC,OAAO,MAAMD,KAAK,cAAc;EACpC;EACA,OAAO,EAAE;AACb,CAAC;AACT;AACA,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"Icon.styles.js","names":["styled","css","StyledIconWrapper","span","$isDisabled","$isOnClick","$size","StyledIcon","i","$color","theme","iconColor","text","$isStacked","undefined","$fontSize","StyledUnicodeIcon","headline","$icon","iconStyle"],"sources":["../../../../src/components/icon/Icon.styles.ts"],"sourcesContent":["import styled, { css } from 'styled-components';\nimport type { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\n\ntype StyledIconWrapperProps = {\n $isDisabled?: boolean;\n $isOnClick: boolean;\n $size: number;\n};\n\nexport const StyledIconWrapper = styled.span<StyledIconWrapperProps>`\n align-items: center;\n cursor: ${({ $isDisabled, $isOnClick }) =>\n $isOnClick && !$isDisabled ? 'pointer' : 'inherit'};\n display: inline-flex;\n min-height: ${({ $size }) => `${$size}px`};\n justify-content: center;\n opacity: ${({ $isDisabled }) => ($isDisabled ? 0.5 : 1)};\n position: relative;\n transition: opacity 0.3s ease;\n min-width: ${({ $size }) => `${$size}px`};\n\n &:focus-visible {\n outline: none;\n color: inherit;\n }\n\n // To insure that stacked icons have the same size as normal icons.\n &&.fa-stack {\n height: fit-content;\n width: fit-content;\n line-height: ${({ $size }) => $size}px;\n }\n`;\n\ntype StyledIconProps = WithTheme<{\n $fontSize: number;\n $isStacked?: boolean;\n $color?: string;\n $size: number;\n}>;\n\nexport const StyledIcon = styled.i<StyledIconProps>`\n color: ${({ $color, theme }: StyledIconProps) => $color || theme.iconColor || theme.text};\n display: ${({ $isStacked }) => ($isStacked ? undefined : 'inline-flex')};\n font-size: ${({ $fontSize }) => `${$fontSize}px`};\n\n ${({ $fontSize, $size }) =>\n $fontSize !== $size &&\n css`\n top: 50%;\n transform: translateY(-50%);\n `}\n`;\n\ntype StyledUnicodeIconProps = WithTheme<{ $icon: string }>;\n\nexport const StyledUnicodeIcon = styled.i<StyledUnicodeIconProps>`\n align-items: center;\n justify-content: center;\n display: flex;\n color: ${({ theme }: StyledUnicodeIconProps) => theme.iconColor || theme.headline};\n\n &:before {\n content: ${({ $icon }) => `\"\\\\${$icon}\" !important`};\n }\n &:after {\n content: ${({ theme, $icon }) => {\n if (theme.iconStyle === 'fa-duotone') {\n return `\"\\\\${$icon}\" !important`;\n }\n return '';\n }};\n }\n`;\n"],"mappings":"AAAA,OAAOA,MAAM,IAAIC,GAAG,QAAQ,mBAAmB;AAS/C,OAAO,MAAMC,iBAAiB,GAAGF,MAAM,CAACG,IAA4B;AACpE;AACA,cAAc,CAAC;EAAEC,WAAW;EAAEC;AAAW,CAAC,KAClCA,UAAU,IAAI,CAACD,WAAW,GAAG,SAAS,GAAG,SAAS;AAC1D;AACA,kBAAkB,CAAC;EAAEE;AAAM,CAAC,KAAK,GAAGA,KAAK,IAAI;AAC7C;AACA,eAAe,CAAC;EAAEF;AAAY,CAAC,KAAMA,WAAW,GAAG,GAAG,GAAG,CAAE;AAC3D;AACA;AACA,iBAAiB,CAAC;EAAEE;AAAM,CAAC,KAAK,GAAGA,KAAK,IAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,CAAC;EAAEA;AAAM,CAAC,KAAKA,KAAK;AAC3C;AACA,CAAC;AASD,OAAO,MAAMC,UAAU,GAAGP,MAAM,CAACQ,CAAkB;AACnD,aAAa,CAAC;EAAEC,MAAM;EAAEC;AAAuB,CAAC,KAAKD,MAAM,IAAIC,KAAK,CAACC,SAAS,IAAID,KAAK,CAACE,IAAI;AAC5F,eAAe,CAAC;EAAEC;AAAW,CAAC,KAAMA,UAAU,GAAGC,SAAS,GAAG,aAAc;AAC3E,iBAAiB,CAAC;EAAEC;AAAU,CAAC,KAAK,GAAGA,SAAS,IAAI;AACpD;AACA,MAAM,CAAC;EAAEA,SAAS;EAAET;AAAM,CAAC,KACnBS,SAAS,KAAKT,KAAK,IACnBL,GAAG;AACX;AACA;AACA,SAAS;AACT,CAAC;AAID,OAAO,MAAMe,iBAAiB,GAAGhB,MAAM,CAACQ,CAAyB;AACjE;AACA;AACA;AACA,aAAa,CAAC;EAAEE;AAA8B,CAAC,KAAKA,KAAK,CAACC,SAAS,IAAID,KAAK,CAACO,QAAQ;AACrF;AACA;AACA,mBAAmB,CAAC;EAAEC;AAAM,CAAC,KAAK,MAAMA,KAAK,cAAc;AAC3D;AACA;AACA,mBAAmB,CAAC;EAAER,KAAK;EAAEQ;AAAM,CAAC,KAAK;EAC7B,IAAIR,KAAK,CAACS,SAAS,KAAK,YAAY,EAAE;IAClC,OAAO,MAAMD,KAAK,cAAc;EACpC;EACA,OAAO,EAAE;AACb,CAAC;AACT;AACA,CAAC","ignoreList":[]}