@reykjavik/hanna-react 0.10.99 → 0.10.101

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 (344) hide show
  1. package/AccordionList.d.ts +2 -2
  2. package/AccordionList.js +2 -2
  3. package/ActionCards.d.ts +2 -1
  4. package/ActionCards.js +1 -1
  5. package/Alert.d.ts +2 -2
  6. package/Alert.js +20 -12
  7. package/ArticleCards.d.ts +4 -1
  8. package/ArticleCards.js +1 -1
  9. package/ArticleCarousel/_ArticleCarouselCard.js +1 -2
  10. package/ArticleCarousel.d.ts +2 -2
  11. package/ArticleCarousel.js +1 -1
  12. package/ArticleMeta.d.ts +2 -1
  13. package/ArticleMeta.js +2 -2
  14. package/Attention.d.ts +2 -1
  15. package/Attention.js +4 -1
  16. package/BasicTable.d.ts +2 -1
  17. package/BgBox.d.ts +2 -1
  18. package/BgBox.js +4 -2
  19. package/Bling.d.ts +2 -1
  20. package/Bling.js +5 -3
  21. package/BlockBreak.js +1 -0
  22. package/BreadCrumbs.d.ts +2 -1
  23. package/BreadCrumbs.js +3 -2
  24. package/ButtonBack.js +2 -0
  25. package/ButtonBar.d.ts +4 -3
  26. package/ButtonBar.js +3 -3
  27. package/ButtonPrimary.js +2 -0
  28. package/ButtonSecondary.js +2 -0
  29. package/ButtonTertiary.js +2 -0
  30. package/CHANGELOG.md +14 -1
  31. package/CarouselStepper.d.ts +2 -1
  32. package/CenterColumn.d.ts +2 -1
  33. package/CenterColumn.js +4 -2
  34. package/CheckboxButton.d.ts +4 -2
  35. package/CheckboxButtonsGroup.js +2 -2
  36. package/CityBlock.d.ts +2 -1
  37. package/CityBlock.js +1 -1
  38. package/ContactBubble.d.ts +2 -2
  39. package/ContactBubble.js +5 -4
  40. package/ContentArticle.d.ts +2 -1
  41. package/ContentArticle.js +3 -2
  42. package/ContentImage.d.ts +2 -1
  43. package/ContentImage.js +4 -3
  44. package/Datepicker.js +6 -6
  45. package/ExtraLinks.d.ts +2 -1
  46. package/ExtraLinks.js +4 -2
  47. package/FeatureList.d.ts +2 -1
  48. package/FeatureList.js +3 -2
  49. package/FieldGroup.d.ts +2 -1
  50. package/FieldGroup.js +4 -2
  51. package/FileInput.d.ts +2 -2
  52. package/FileInput.js +10 -5
  53. package/Foonote.js +3 -4
  54. package/Footnote.d.ts +2 -1
  55. package/Footnote.js +2 -1
  56. package/Form.js +4 -5
  57. package/FormField.d.ts +25 -5
  58. package/FormField.js +32 -7
  59. package/Gallery/_GalleryItem.js +2 -2
  60. package/Gallery/_GalleryModalItem.js +1 -1
  61. package/Gallery.d.ts +2 -2
  62. package/Gallery.js +5 -4
  63. package/GridBlocks.d.ts +2 -5
  64. package/GridBlocks.js +3 -3
  65. package/Heading.d.ts +2 -1
  66. package/Heading.js +3 -3
  67. package/HeroBlock.d.ts +2 -1
  68. package/HeroBlock.js +4 -3
  69. package/IframeBlock.d.ts +9 -4
  70. package/IframeBlock.js +13 -12
  71. package/Illustration.d.ts +2 -1
  72. package/Illustration.js +1 -1
  73. package/ImageCards.d.ts +2 -1
  74. package/ImageCards.js +2 -2
  75. package/InfoBlock.d.ts +2 -1
  76. package/InfoBlock.js +3 -2
  77. package/InfoHero.d.ts +2 -1
  78. package/InfoHero.js +3 -3
  79. package/IslandBlock.d.ts +2 -1
  80. package/IslandBlock.js +2 -2
  81. package/IslandPageBlock.d.ts +2 -1
  82. package/IslandPageBlock.js +2 -2
  83. package/LabeledTextBlock.d.ts +2 -1
  84. package/LabeledTextBlock.js +2 -2
  85. package/Layout.d.ts +2 -2
  86. package/Layout.js +3 -3
  87. package/MainMenu.d.ts +2 -2
  88. package/MainMenu.js +4 -3
  89. package/MiniMetrics.d.ts +2 -1
  90. package/MiniMetrics.js +3 -2
  91. package/Modal.d.ts +2 -1
  92. package/Multiselect.d.ts +11 -6
  93. package/Multiselect.js +15 -11
  94. package/NameCard.d.ts +2 -1
  95. package/NameCard.js +10 -6
  96. package/NameCards.d.ts +3 -2
  97. package/NameCards.js +3 -2
  98. package/NewsHero.d.ts +2 -1
  99. package/NewsHero.js +3 -3
  100. package/PageFilter.d.ts +2 -1
  101. package/PageFilter.js +2 -2
  102. package/PageHeading.d.ts +2 -1
  103. package/PageHeading.js +2 -5
  104. package/Picture.d.ts +2 -1
  105. package/Picture.js +1 -5
  106. package/ProcessOverview.d.ts +2 -1
  107. package/ProcessOverview.js +2 -5
  108. package/RadioButtonsGroup.js +2 -2
  109. package/RadioGroup.js +1 -1
  110. package/ReadSpeakerPlayer.d.ts +1 -1
  111. package/ReadSpeakerPlayer.js +2 -2
  112. package/RelatedLinks.d.ts +2 -1
  113. package/RelatedLinks.js +3 -2
  114. package/RowBlock.d.ts +2 -1
  115. package/RowBlock.js +2 -2
  116. package/RowBlockColumn.d.ts +2 -1
  117. package/RowBlockColumn.js +3 -3
  118. package/SearchInput.d.ts +3 -9
  119. package/SearchInput.js +4 -5
  120. package/SearchResults/_SearchResultsItem.js +1 -1
  121. package/SearchResults.d.ts +2 -1
  122. package/SearchResults.js +2 -2
  123. package/SeenEffect.js +2 -0
  124. package/Selectbox.js +3 -4
  125. package/ShareButtons.d.ts +2 -2
  126. package/ShareButtons.js +5 -3
  127. package/Sharpie.d.ts +2 -1
  128. package/Sharpie.js +2 -2
  129. package/SiteSearchAutocomplete.d.ts +2 -1
  130. package/SiteSearchAutocomplete.js +4 -4
  131. package/SiteSearchCurtain.js +2 -0
  132. package/SiteSearchInput.d.ts +3 -6
  133. package/SiteSearchInput.js +4 -4
  134. package/Skeleton.d.ts +4 -1
  135. package/Skeleton.js +15 -18
  136. package/SubHeading.d.ts +2 -1
  137. package/SubHeading.js +3 -3
  138. package/Tabs.d.ts +2 -2
  139. package/Tabs.js +5 -5
  140. package/TagPill.js +2 -0
  141. package/TextBlock.d.ts +2 -1
  142. package/TextBlock.js +3 -3
  143. package/TextButton.js +2 -0
  144. package/TextInput.d.ts +2 -2
  145. package/TextInput.js +3 -4
  146. package/Tooltip.d.ts +2 -1
  147. package/Tooltip.js +28 -15
  148. package/VSpacer.d.ts +2 -1
  149. package/VSpacer.js +3 -7
  150. package/VerticalTabsTOC.d.ts +1 -1
  151. package/VerticalTabsTOC.js +1 -1
  152. package/WizardLayout.d.ts +2 -2
  153. package/WizardLayout.js +4 -3
  154. package/WizardLayoutClose.js +2 -0
  155. package/WizardStepper.d.ts +2 -1
  156. package/WizardStepper.js +2 -2
  157. package/_abstract/_AbstractCarousel.d.ts +2 -2
  158. package/_abstract/_AbstractCarousel.js +6 -3
  159. package/_abstract/_Block.d.ts +2 -1
  160. package/_abstract/_Block.js +3 -3
  161. package/_abstract/_Button.js +4 -1
  162. package/_abstract/_CardList.d.ts +3 -1
  163. package/_abstract/_CardList.js +6 -3
  164. package/_abstract/_Image.d.ts +6 -3
  165. package/_abstract/_Image.js +11 -4
  166. package/_abstract/_Quote.d.ts +2 -1
  167. package/_abstract/_Quote.js +3 -2
  168. package/_abstract/_TogglerGroup.js +1 -1
  169. package/_abstract/_TogglerGroupField.js +5 -5
  170. package/_abstract/_TogglerInput.d.ts +2 -2
  171. package/_abstract/_TogglerInput.js +4 -2
  172. package/esm/AccordionList.d.ts +2 -2
  173. package/esm/AccordionList.js +3 -3
  174. package/esm/ActionCards.d.ts +2 -1
  175. package/esm/ActionCards.js +1 -1
  176. package/esm/Alert.d.ts +2 -2
  177. package/esm/Alert.js +21 -13
  178. package/esm/ArticleCards.d.ts +4 -1
  179. package/esm/ArticleCards.js +1 -1
  180. package/esm/ArticleCarousel/_ArticleCarouselCard.js +1 -2
  181. package/esm/ArticleCarousel.d.ts +2 -2
  182. package/esm/ArticleCarousel.js +1 -1
  183. package/esm/ArticleMeta.d.ts +2 -1
  184. package/esm/ArticleMeta.js +2 -2
  185. package/esm/Attention.d.ts +2 -1
  186. package/esm/Attention.js +4 -1
  187. package/esm/BasicTable.d.ts +2 -1
  188. package/esm/BgBox.d.ts +2 -1
  189. package/esm/BgBox.js +4 -2
  190. package/esm/Bling.d.ts +2 -1
  191. package/esm/Bling.js +5 -3
  192. package/esm/BlockBreak.js +1 -0
  193. package/esm/BreadCrumbs.d.ts +2 -1
  194. package/esm/BreadCrumbs.js +3 -2
  195. package/esm/ButtonBack.js +2 -0
  196. package/esm/ButtonBar.d.ts +4 -3
  197. package/esm/ButtonBar.js +3 -3
  198. package/esm/ButtonPrimary.js +2 -0
  199. package/esm/ButtonSecondary.js +2 -0
  200. package/esm/ButtonTertiary.js +2 -0
  201. package/esm/CarouselStepper.d.ts +2 -1
  202. package/esm/CenterColumn.d.ts +2 -1
  203. package/esm/CenterColumn.js +4 -2
  204. package/esm/CheckboxButton.d.ts +4 -2
  205. package/esm/CheckboxButtonsGroup.js +2 -2
  206. package/esm/CityBlock.d.ts +2 -1
  207. package/esm/CityBlock.js +1 -1
  208. package/esm/ContactBubble.d.ts +2 -2
  209. package/esm/ContactBubble.js +5 -4
  210. package/esm/ContentArticle.d.ts +2 -1
  211. package/esm/ContentArticle.js +3 -2
  212. package/esm/ContentImage.d.ts +2 -1
  213. package/esm/ContentImage.js +4 -3
  214. package/esm/Datepicker.js +7 -7
  215. package/esm/ExtraLinks.d.ts +2 -1
  216. package/esm/ExtraLinks.js +4 -2
  217. package/esm/FeatureList.d.ts +2 -1
  218. package/esm/FeatureList.js +3 -2
  219. package/esm/FieldGroup.d.ts +2 -1
  220. package/esm/FieldGroup.js +4 -2
  221. package/esm/FileInput.d.ts +2 -2
  222. package/esm/FileInput.js +10 -5
  223. package/esm/Foonote.js +2 -2
  224. package/esm/Footnote.d.ts +2 -1
  225. package/esm/Footnote.js +2 -1
  226. package/esm/Form.js +5 -5
  227. package/esm/FormField.d.ts +25 -5
  228. package/esm/FormField.js +30 -6
  229. package/esm/Gallery/_GalleryItem.js +2 -2
  230. package/esm/Gallery/_GalleryModalItem.js +1 -1
  231. package/esm/Gallery.d.ts +2 -2
  232. package/esm/Gallery.js +6 -5
  233. package/esm/GridBlocks.d.ts +2 -5
  234. package/esm/GridBlocks.js +3 -3
  235. package/esm/Heading.d.ts +2 -1
  236. package/esm/Heading.js +3 -3
  237. package/esm/HeroBlock.d.ts +2 -1
  238. package/esm/HeroBlock.js +4 -3
  239. package/esm/IframeBlock.d.ts +9 -4
  240. package/esm/IframeBlock.js +13 -12
  241. package/esm/Illustration.d.ts +2 -1
  242. package/esm/Illustration.js +1 -1
  243. package/esm/ImageCards.d.ts +2 -1
  244. package/esm/ImageCards.js +2 -2
  245. package/esm/InfoBlock.d.ts +2 -1
  246. package/esm/InfoBlock.js +3 -2
  247. package/esm/InfoHero.d.ts +2 -1
  248. package/esm/InfoHero.js +3 -3
  249. package/esm/IslandBlock.d.ts +2 -1
  250. package/esm/IslandBlock.js +2 -2
  251. package/esm/IslandPageBlock.d.ts +2 -1
  252. package/esm/IslandPageBlock.js +2 -2
  253. package/esm/LabeledTextBlock.d.ts +2 -1
  254. package/esm/LabeledTextBlock.js +2 -2
  255. package/esm/Layout.d.ts +2 -2
  256. package/esm/Layout.js +3 -3
  257. package/esm/MainMenu.d.ts +2 -2
  258. package/esm/MainMenu.js +4 -3
  259. package/esm/MiniMetrics.d.ts +2 -1
  260. package/esm/MiniMetrics.js +3 -2
  261. package/esm/Modal.d.ts +2 -1
  262. package/esm/Multiselect.d.ts +11 -6
  263. package/esm/Multiselect.js +15 -11
  264. package/esm/NameCard.d.ts +2 -1
  265. package/esm/NameCard.js +10 -6
  266. package/esm/NameCards.d.ts +3 -2
  267. package/esm/NameCards.js +3 -2
  268. package/esm/NewsHero.d.ts +2 -1
  269. package/esm/NewsHero.js +3 -3
  270. package/esm/PageFilter.d.ts +2 -1
  271. package/esm/PageFilter.js +2 -2
  272. package/esm/PageHeading.d.ts +2 -1
  273. package/esm/PageHeading.js +2 -5
  274. package/esm/Picture.d.ts +2 -1
  275. package/esm/Picture.js +1 -5
  276. package/esm/ProcessOverview.d.ts +2 -1
  277. package/esm/ProcessOverview.js +2 -5
  278. package/esm/RadioButtonsGroup.js +2 -2
  279. package/esm/RadioGroup.js +1 -1
  280. package/esm/ReadSpeakerPlayer.d.ts +1 -1
  281. package/esm/ReadSpeakerPlayer.js +2 -2
  282. package/esm/RelatedLinks.d.ts +2 -1
  283. package/esm/RelatedLinks.js +3 -2
  284. package/esm/RowBlock.d.ts +2 -1
  285. package/esm/RowBlock.js +2 -2
  286. package/esm/RowBlockColumn.d.ts +2 -1
  287. package/esm/RowBlockColumn.js +3 -3
  288. package/esm/SearchInput.d.ts +3 -9
  289. package/esm/SearchInput.js +4 -5
  290. package/esm/SearchResults/_SearchResultsItem.js +1 -1
  291. package/esm/SearchResults.d.ts +2 -1
  292. package/esm/SearchResults.js +2 -2
  293. package/esm/SeenEffect.js +2 -0
  294. package/esm/Selectbox.js +3 -4
  295. package/esm/ShareButtons.d.ts +2 -2
  296. package/esm/ShareButtons.js +5 -3
  297. package/esm/Sharpie.d.ts +2 -1
  298. package/esm/Sharpie.js +2 -2
  299. package/esm/SiteSearchAutocomplete.d.ts +2 -1
  300. package/esm/SiteSearchAutocomplete.js +4 -4
  301. package/esm/SiteSearchCurtain.js +2 -0
  302. package/esm/SiteSearchInput.d.ts +3 -6
  303. package/esm/SiteSearchInput.js +4 -4
  304. package/esm/Skeleton.d.ts +4 -1
  305. package/esm/Skeleton.js +15 -18
  306. package/esm/SubHeading.d.ts +2 -1
  307. package/esm/SubHeading.js +3 -3
  308. package/esm/Tabs.d.ts +2 -2
  309. package/esm/Tabs.js +5 -5
  310. package/esm/TagPill.js +2 -0
  311. package/esm/TextBlock.d.ts +2 -1
  312. package/esm/TextBlock.js +3 -3
  313. package/esm/TextButton.js +2 -0
  314. package/esm/TextInput.d.ts +2 -2
  315. package/esm/TextInput.js +3 -4
  316. package/esm/Tooltip.d.ts +2 -1
  317. package/esm/Tooltip.js +28 -15
  318. package/esm/VSpacer.d.ts +2 -1
  319. package/esm/VSpacer.js +3 -7
  320. package/esm/VerticalTabsTOC.d.ts +1 -1
  321. package/esm/VerticalTabsTOC.js +1 -1
  322. package/esm/WizardLayout.d.ts +2 -2
  323. package/esm/WizardLayout.js +4 -3
  324. package/esm/WizardLayoutClose.js +2 -0
  325. package/esm/WizardStepper.d.ts +2 -1
  326. package/esm/WizardStepper.js +2 -2
  327. package/esm/_abstract/_AbstractCarousel.d.ts +2 -2
  328. package/esm/_abstract/_AbstractCarousel.js +6 -3
  329. package/esm/_abstract/_Block.d.ts +2 -1
  330. package/esm/_abstract/_Block.js +3 -3
  331. package/esm/_abstract/_Button.js +4 -1
  332. package/esm/_abstract/_CardList.d.ts +3 -1
  333. package/esm/_abstract/_CardList.js +6 -3
  334. package/esm/_abstract/_Image.d.ts +6 -3
  335. package/esm/_abstract/_Image.js +12 -5
  336. package/esm/_abstract/_Quote.d.ts +2 -1
  337. package/esm/_abstract/_Quote.js +3 -2
  338. package/esm/_abstract/_TogglerGroup.js +1 -1
  339. package/esm/_abstract/_TogglerGroupField.js +5 -5
  340. package/esm/_abstract/_TogglerInput.d.ts +2 -2
  341. package/esm/_abstract/_TogglerInput.js +4 -2
  342. package/esm/utils.d.ts +25 -2
  343. package/package.json +1 -1
  344. package/utils.d.ts +25 -2
package/esm/TextInput.js CHANGED
@@ -1,17 +1,16 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { useEffect, useRef, useState } from 'react';
3
3
  import { modifiedClass } from '@hugsmidjan/qj/classUtils';
4
- import FormField from './FormField.js';
4
+ import FormField, { groupFormFieldWrapperProps, } from './FormField.js';
5
5
  export const TextInput = (props) => {
6
6
  var _a;
7
7
  const _inputRef = useRef(null);
8
- const { className, label, assistText, hideLabel, disabled, readOnly, invalid, errorMessage, required, reqText, id, onChange, small, type, ssr, inputRef = _inputRef } = props, inputElementProps = __rest(props, ["className", "label", "assistText", "hideLabel", "disabled", "readOnly", "invalid", "errorMessage", "required", "reqText", "id", "onChange", "small", "type", "ssr", "inputRef"]);
8
+ const _b = groupFormFieldWrapperProps(props), { onChange, type, inputRef = _inputRef, fieldWrapperProps } = _b, inputElementProps = __rest(_b, ["onChange", "type", "inputRef", "fieldWrapperProps"]);
9
9
  const { value, defaultValue, placeholder } = inputElementProps;
10
10
  const [hasValue, setHasValue] = useState(undefined);
11
11
  const filled = !!((_a = value !== null && value !== void 0 ? value : hasValue) !== null && _a !== void 0 ? _a : !!defaultValue);
12
12
  const empty = !filled && !placeholder;
13
13
  const multiline = type === 'textarea';
14
- const modifiers = [multiline && 'multiline'];
15
14
  const _onChange = value != null
16
15
  ? onChange
17
16
  : (e) => {
@@ -27,6 +26,6 @@ export const TextInput = (props) => {
27
26
  setHasValue(true);
28
27
  }
29
28
  }, []);
30
- return (React.createElement(FormField, { className: modifiedClass('TextInput', modifiers, className), ssr: ssr, small: small, label: label, empty: empty, filled: filled, assistText: assistText, hideLabel: hideLabel, disabled: disabled, readOnly: readOnly, invalid: invalid, errorMessage: errorMessage, required: required, reqText: reqText, id: id, renderInput: (className, inputProps, addFocusProps) => multiline ? (React.createElement("textarea", Object.assign({ className: className.input, onChange: _onChange }, inputProps, addFocusProps(inputElementProps), { ref: inputRef }))) : (React.createElement("input", Object.assign({ className: className.input, onChange: _onChange, type: type }, inputProps, addFocusProps(inputElementProps), { ref: inputRef }))) }));
29
+ return (React.createElement(FormField, Object.assign({ extraClassName: modifiedClass('TextInput', [multiline && 'multiline']), empty: empty, filled: filled }, fieldWrapperProps, { renderInput: (className, inputProps, addFocusProps) => multiline ? (React.createElement("textarea", Object.assign({ className: className.input, onChange: _onChange }, inputProps, addFocusProps(inputElementProps), { ref: inputRef }))) : (React.createElement("input", Object.assign({ className: className.input, onChange: _onChange, type: type }, inputProps, addFocusProps(inputElementProps), { ref: inputRef }))) })));
31
30
  };
32
31
  export default TextInput;
package/esm/Tooltip.d.ts CHANGED
@@ -1,7 +1,8 @@
1
+ import { WrapperElmProps } from './utils.js';
1
2
  export type TooltipProps = {
2
3
  label: string;
3
4
  text: string | JSX.Element;
4
5
  iconOnly?: boolean;
5
- };
6
+ } & WrapperElmProps<'details', 'open'>;
6
7
  export declare const Tooltip: (props: TooltipProps) => JSX.Element;
7
8
  export default Tooltip;
package/esm/Tooltip.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import React, { useRef } from 'react';
2
2
  import { arrow as arrowPlugin, autoUpdate, flip, offset, shift, useFloating, } from '@floating-ui/react';
3
- import { useCallbackOnEsc, useLaggedState } from '@hugsmidjan/react/hooks';
4
3
  import { modifiedClass } from '@hugsmidjan/qj/classUtils';
4
+ import { useCallbackOnEsc, useLaggedState } from '@hugsmidjan/react/hooks';
5
5
  const getSide = (placement) => placement.split('-')[0];
6
6
  export const Tooltip = (props) => {
7
- const { text, label, iconOnly } = props;
7
+ const { text, label, iconOnly, wrapperProps = {} } = props;
8
8
  const arrowRef = useRef(null);
9
9
  const [isOpen, setIsOpen] = useLaggedState(false, 300);
10
- const { x, y, reference, floating, middlewareData, placement } = useFloating({
10
+ const { x, y, refs, middlewareData, placement } = useFloating({
11
11
  placement: 'top',
12
12
  middleware: [offset(10), flip(), shift(), arrowPlugin({ element: arrowRef })],
13
13
  whileElementsMounted: autoUpdate,
@@ -18,40 +18,53 @@ export const Tooltip = (props) => {
18
18
  useCallbackOnEsc(() => {
19
19
  setIsOpen(false);
20
20
  });
21
- return (React.createElement("details", { className: `Tooltip Tooltip--${getSide(placement)}`, open: isOpen, onMouseEnter: () => setIsOpen(true, 100), onFocus: () => {
21
+ return (React.createElement("details", Object.assign({}, props.wrapperProps, { className: modifiedClass('Tooltip', getSide(placement), wrapperProps.className), open: isOpen, onMouseEnter: (e) => {
22
+ var _a;
23
+ setIsOpen(true, 100);
24
+ (_a = wrapperProps.onMouseEnter) === null || _a === void 0 ? void 0 : _a.call(wrapperProps, e);
25
+ }, onFocus: (e) => {
26
+ var _a;
22
27
  if (isOpen) {
23
28
  setIsOpen(true, 0);
24
29
  }
25
- }, onBlur: () => setIsOpen(false), onClick: (e) => {
30
+ (_a = wrapperProps.onFocus) === null || _a === void 0 ? void 0 : _a.call(wrapperProps, e);
31
+ }, onBlur: (e) => {
32
+ var _a;
33
+ setIsOpen(false);
34
+ (_a = wrapperProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(wrapperProps, e);
35
+ }, onClick: (e) => {
36
+ var _a;
26
37
  e.preventDefault();
27
38
  setIsOpen(!isOpen, 0);
28
- }, onMouseDown: () => {
39
+ (_a = wrapperProps.onClick) === null || _a === void 0 ? void 0 : _a.call(wrapperProps, e);
40
+ }, onMouseDown: (e) => {
41
+ var _a;
29
42
  if (isOpen) {
30
43
  setTimeout(() => {
31
44
  setIsOpen(true, 0);
32
45
  }, 100);
33
46
  }
47
+ (_a = wrapperProps.onMouseDown) === null || _a === void 0 ? void 0 : _a.call(wrapperProps, e);
34
48
  }, onMouseLeave: (e) => {
49
+ var _a;
35
50
  if (e.currentTarget.$contextClicked_firefox_fix) {
36
51
  return;
37
52
  }
38
53
  setIsOpen(false);
54
+ (_a = wrapperProps.onMouseLeave) === null || _a === void 0 ? void 0 : _a.call(wrapperProps, e);
39
55
  }, onContextMenu: (e) => {
56
+ var _a;
40
57
  const elm = e.currentTarget;
41
58
  clearTimeout(elm.$contextClicked_firefox_fix);
42
59
  elm.$contextClicked_firefox_fix = setTimeout(() => {
43
60
  delete elm.$contextClicked_firefox_fix;
44
61
  }, 300);
62
+ (_a = wrapperProps.onContextMenu) === null || _a === void 0 ? void 0 : _a.call(wrapperProps, e);
45
63
  }, style: x == null
46
- ? undefined
47
- : {
48
- '--tooltip-content-pos-y': `${y}px`,
49
- '--tooltip-content-pos-x': `${x}px`,
50
- '--tooltip-arrow-pos-x': `${arrowX}px`,
51
- '--tooltip-arrow-pos-y': `${arrowY}px`,
52
- } },
53
- React.createElement("summary", { className: modifiedClass('Tooltip__trigger', iconOnly && 'icononly'), ref: reference }, label),
54
- React.createElement("div", { className: "Tooltip__content", onClick: (e) => e.stopPropagation(), ref: floating },
64
+ ? wrapperProps.style
65
+ : Object.assign(Object.assign({}, wrapperProps.style), { '--tooltip-content-pos-y': `${y}px`, '--tooltip-content-pos-x': `${x}px`, '--tooltip-arrow-pos-x': `${arrowX}px`, '--tooltip-arrow-pos-y': `${arrowY}px` }) }),
66
+ React.createElement("summary", { className: modifiedClass('Tooltip__trigger', iconOnly && 'icononly'), ref: refs.setReference }, label),
67
+ React.createElement("div", { className: "Tooltip__content", onClick: (e) => e.stopPropagation(), ref: refs.setFloating },
55
68
  x !== null && (React.createElement("div", { "data-floating-ui-hack-plz-ignore": "", style: { position: 'absolute', display: 'none' }, ref: arrowRef })),
56
69
  text)));
57
70
  };
package/esm/VSpacer.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { EitherObj } from '@reykjavik/hanna-utils';
3
+ import { WrapperElmProps } from './utils.js';
3
4
  declare const sizes: {
4
5
  readonly none: "none";
5
6
  readonly small: "small";
@@ -17,6 +18,6 @@ export type VSpacerProps = EitherObj<{
17
18
  size?: VSpacerSizePos;
18
19
  top?: VSpacerSize;
19
20
  bottom?: VSpacerSize;
20
- }>;
21
+ }> & WrapperElmProps;
21
22
  export declare const VSpacer: (props: VSpacerProps) => JSX.Element;
22
23
  export default VSpacer;
package/esm/VSpacer.js CHANGED
@@ -11,7 +11,7 @@ const sizes = {
11
11
  const hasChildren = (children) => (children && !(Array.isArray(children) && !children.length)) || undefined;
12
12
  const normalizeProp = (value, exclude) => value && value !== exclude ? sizes[value] : undefined;
13
13
  export const VSpacer = (props) => {
14
- const { size, top, bottom, children } = props;
14
+ const { size, top, bottom, children, wrapperProps } = props;
15
15
  const isWrapper = hasChildren(children);
16
16
  let topVal = normalizeProp(isWrapper && top);
17
17
  let bottomVal = normalizeProp(isWrapper && bottom);
@@ -31,11 +31,7 @@ export const VSpacer = (props) => {
31
31
  bottomVal = undefined;
32
32
  }
33
33
  }
34
- const className = modifiedClass('VSpacer', [
35
- sizeVal,
36
- topVal && 'top--' + topVal,
37
- bottomVal && 'bottom--' + bottomVal,
38
- ]);
39
- return isWrapper ? (React.createElement("div", { className: className }, children)) : (React.createElement("hr", { className: className }));
34
+ const className = modifiedClass('VSpacer', [sizeVal, topVal && 'top--' + topVal, bottomVal && 'bottom--' + bottomVal], (wrapperProps || {}).className);
35
+ return isWrapper ? (React.createElement("div", Object.assign({}, wrapperProps, { className: className }), children)) : (React.createElement("hr", Object.assign({}, wrapperProps, { className: className })));
40
36
  };
41
37
  export default VSpacer;
@@ -9,6 +9,6 @@ export type VerticalTabsTOCSubItem = TabItemProps & {
9
9
  export type VerticalTabsTOCProps = {
10
10
  items: Array<VerticalTabsTOCItem>;
11
11
  onItemSelect: (itemId: string) => void;
12
- } & Pick<TabsProps, 'aria-label' | 'ssr' | 'activateOnFocus' | 'id' | 'startSeen'>;
12
+ } & Pick<TabsProps, 'aria-label' | 'ssr' | 'activateOnFocus' | 'id' | 'startSeen' | 'wrapperProps'>;
13
13
  export declare const VerticalTabsTOC: (props: VerticalTabsTOCProps) => JSX.Element;
14
14
  export default VerticalTabsTOC;
@@ -58,7 +58,7 @@ export const VerticalTabsTOC = (props) => {
58
58
  window.addEventListener('hashchange', handleHash);
59
59
  return () => window.removeEventListener('hashchange', handleHash);
60
60
  }, [itemsById, onItemSelect]);
61
- return (React.createElement(Tabs, { id: domid, vertical: true, "aria-label": props['aria-label'], onSetActive: (_, item) => {
61
+ return (React.createElement(Tabs, { wrapperProps: props.wrapperProps, id: domid, vertical: true, "aria-label": props['aria-label'], onSetActive: (_, item) => {
62
62
  var _a;
63
63
  const itemId = getItemId(item);
64
64
  const newId = itemId || getItemId((_a = itemsById[itemId].subTabs) === null || _a === void 0 ? void 0 : _a.tabs[0]);
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import type { HannaColorTheme } from '@reykjavik/hanna-css';
3
- import { SSRSupportProps } from './utils.js';
3
+ import { SSRSupportProps, WrapperElmProps } from './utils.js';
4
4
  type WizardLayoutProps = {
5
5
  wizardStepper?: ReactNode | false;
6
6
  wizardFooter?: ReactNode | false;
@@ -9,6 +9,6 @@ type WizardLayoutProps = {
9
9
  logoLink?: string;
10
10
  globalAlerts?: ReactNode;
11
11
  children?: ReactNode;
12
- } & SSRSupportProps;
12
+ } & SSRSupportProps & WrapperElmProps;
13
13
  export declare const WizardLayout: (props: WizardLayoutProps) => JSX.Element;
14
14
  export default WizardLayout;
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { modifiedClass } from '@hugsmidjan/qj/classUtils';
2
3
  import { getAssetUrl } from '@reykjavik/hanna-utils/assets';
3
4
  import { Image } from './_abstract/_Image.js';
4
5
  import { Link } from './_abstract/_Link.js';
@@ -8,15 +9,15 @@ export const WizardLayout = (props) => {
8
9
  useScrollbarWidthCSSVar();
9
10
  const {
10
11
  // ssr,
11
- wizardStepper, wizardFooter, children, colorTheme, logoLink = '/', siteName = '', globalAlerts, } = props;
12
+ wizardStepper, wizardFooter, children, colorTheme, logoLink = '/', siteName = '', globalAlerts, wrapperProps, } = props;
12
13
  const isBrowser = useIsBrowserSide( /* ssr */);
13
- return (React.createElement("div", { className: "WizardLayout", "data-sprinkled": isBrowser, "data-color-theme": colorTheme },
14
+ return (React.createElement("div", Object.assign({}, wrapperProps, { className: modifiedClass('WizardLayout', null, (wrapperProps || {}).className), "data-sprinkled": isBrowser, "data-color-theme": colorTheme }),
14
15
  globalAlerts && (React.createElement("div", { className: "WizardLayout__alerts", role: "alert" }, globalAlerts)),
15
16
  React.createElement("div", { className: "WizardLayout__content" },
16
17
  React.createElement("div", { className: "WizardLayout__header", role: "banner" },
17
18
  React.createElement(Link, { className: "WizardLayout__header__logo", href: logoLink },
18
19
  ' ',
19
- React.createElement(Image, { className: undefined, inline: true, src: getAssetUrl('reykjavik-logo.svg'), altText: "Reykjav\u00EDk" }),
20
+ React.createElement(Image, { bem: undefined, inline: true, src: getAssetUrl('reykjavik-logo.svg'), altText: "Reykjav\u00EDk" }),
20
21
  ' ',
21
22
  siteName,
22
23
  ' '),
@@ -1,4 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Button } from './_abstract/_Button.js';
3
+ // NOTE: As a `_abstract/_Button.tsx`-derived component, all `<button/>` and
4
+ // `<a/>` props are allowed directly, so adding `wrapperProps` makes no sense.
3
5
  export const WizardLayoutClose = (props) => (React.createElement(Button, Object.assign({ bem: "WizardLayoutClose" }, props)));
4
6
  export default WizardLayoutClose;
@@ -1,3 +1,4 @@
1
+ import { WrapperElmProps } from './utils.js';
1
2
  export type WizardStepperStep = {
2
3
  label: string;
3
4
  /**
@@ -31,6 +32,6 @@ export type WizardStepperProps = {
31
32
  /** By default, clickable steps after the active step are not immediately clickable */
32
33
  allowForwardSkip?: boolean;
33
34
  onClick: (clickedIndex: number) => void;
34
- };
35
+ } & WrapperElmProps;
35
36
  export declare const WizardStepper: (props: WizardStepperProps) => JSX.Element;
36
37
  export default WizardStepper;
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import { modifiedClass } from '@hugsmidjan/qj/classUtils';
3
3
  export const WizardStepper = (props) => {
4
- const { steps, activeStep = -1, allowForwardSkip, disableBacktrack, onClick } = props;
5
- return (React.createElement("div", { className: modifiedClass('WizardStepper', activeStep === -1 && 'preview') }, steps.map((step, i) => {
4
+ const { steps, activeStep = -1, allowForwardSkip, disableBacktrack, onClick, wrapperProps, } = props;
5
+ return (React.createElement("div", Object.assign({}, wrapperProps, { className: modifiedClass('WizardStepper', activeStep === -1 && 'preview', (wrapperProps || {}).className) }), steps.map((step, i) => {
6
6
  const { clickable, done, neutral } = step;
7
7
  const label = step.label || '…';
8
8
  const stepClass = modifiedClass('WizardStepper__step', [
@@ -1,6 +1,6 @@
1
1
  import { ReactElement, ReactNode } from 'react';
2
2
  import { EitherObj } from '@reykjavik/hanna-utils';
3
- import { SSRSupportProps } from '../utils.js';
3
+ import { SSRSupportProps, WrapperElmProps } from '../utils.js';
4
4
  import { SeenProp } from '../utils/seenEffect.js';
5
5
  import { BemProps } from '../utils/types.js';
6
6
  export type CarouselProps<I extends Record<string, unknown> = {}, P extends Record<string, unknown> | undefined = {}> = {
@@ -20,7 +20,7 @@ export type CarouselProps<I extends Record<string, unknown> = {}, P extends Reco
20
20
  * `<Fragment />` or some such.
21
21
  */
22
22
  itemCount?: number;
23
- }> & SeenProp;
23
+ }> & WrapperElmProps & SeenProp;
24
24
  type AbstractCarouselProps<I extends Record<string, unknown> = Record<string, unknown>, P extends Record<string, unknown> | undefined = Record<string, unknown>> = CarouselProps<I, P> & BemProps & {
25
25
  title?: string;
26
26
  };
@@ -19,15 +19,16 @@ const scrollXBy = (elm, deltaX) => {
19
19
  // NOTE 2: Both Chrome and Safari tend to snap hard to the nearest list item
20
20
  // while Firefox is more smooth. Haven't found a way around that.
21
21
  };
22
+ // eslint-disable-next-line complexity
22
23
  export const AbstractCarousel = (props) => {
23
- const { title, items = [], Component, ComponentProps, bem = 'Carousel', modifier, ssr, startSeen, } = props;
24
+ const { title, items = [], Component, ComponentProps, bem = 'Carousel', modifier, ssr, startSeen, className, wrapperProps, } = props;
24
25
  const children = !props.children
25
26
  ? undefined
26
27
  : Array.isArray(props.children)
27
28
  ? props.children.filter(notNully)
28
29
  : [props.children];
29
30
  const [leftOffset, setLeftOffset] = useState();
30
- const itemCount = props.itemCount || (children || items).length;
31
+ const itemCount = props.itemCount != null ? props.itemCount : (children || items).length;
31
32
  const listRef = useRef(null);
32
33
  const [activeItem, setActiveItem] = useState(0);
33
34
  const isBrowser = useIsBrowserSide(ssr);
@@ -92,7 +93,9 @@ export const AbstractCarousel = (props) => {
92
93
  items.map((item, i) => (
93
94
  // @ts-expect-error (Can't be arsed...)
94
95
  React.createElement(Component, Object.assign({ key: i }, ComponentProps, item))))));
95
- return (React.createElement("div", { className: modifiedClass(bem, modifier, props.className), ref: outerRef, "data-sprinkled": isBrowser },
96
+ return (React.createElement("div", Object.assign({}, wrapperProps, { className: modifiedClass(bem, modifier,
97
+ // Prefer `className` over `wrapperProps.className`
98
+ className || (wrapperProps || {}).className), ref: outerRef, "data-sprinkled": isBrowser }),
96
99
  title && React.createElement("h2", { className: bem + '__title' }, title),
97
100
  isBrowser ? (React.createElement("div", { className: bem + '__itemlist-wrapper' },
98
101
  itemList,
@@ -1,3 +1,4 @@
1
+ import { WrapperElmProps } from '../utils.js';
1
2
  import { SeenProp } from '../utils/seenEffect.js';
2
3
  import { BemModifierProps } from '../utils/types.js';
3
4
  import { ButtonProps } from './_Button.js';
@@ -15,7 +16,7 @@ export type ContentBlock = {
15
16
  content: Array<BlockItem>;
16
17
  image?: undefined;
17
18
  } & SeenProp;
18
- export type BlockProps = BemModifierProps & (ContentBlock | ContentImageBlock);
19
+ export type BlockProps = (ContentBlock | ContentImageBlock) & BemModifierProps & WrapperElmProps;
19
20
  export declare const Block: (props: BlockProps & {
20
21
  bem: string;
21
22
  }) => JSX.Element;
@@ -4,10 +4,10 @@ import { useSeenEffect } from '../utils/seenEffect.js';
4
4
  import { Button } from './_Button.js';
5
5
  import { Image } from './_Image.js';
6
6
  export const Block = (props) => {
7
- const { image, modifier, bem, content, startSeen } = props;
7
+ const { image, modifier, bem, content, startSeen, wrapperProps } = props;
8
8
  const [ref] = useSeenEffect(startSeen);
9
9
  const contentItems = Array.isArray(content) ? content : [content];
10
- return (React.createElement("div", { className: modifiedClass(bem, modifier), ref: ref },
10
+ return (React.createElement("div", Object.assign({}, wrapperProps, { className: modifiedClass(bem, modifier, (wrapperProps || {}).className), ref: ref }),
11
11
  contentItems.map(({ title, summary, buttons = [] }, i) => {
12
12
  const hasSummary = summary && (typeof summary !== 'string' || !!summary.trim());
13
13
  return (React.createElement("div", { key: i, className: `${bem}__content` },
@@ -19,5 +19,5 @@ export const Block = (props) => {
19
19
  React.createElement(Button, Object.assign({ bem: `${bem}__button`, key: i }, buttonProps)),
20
20
  ' ')))))));
21
21
  }),
22
- image && React.createElement(Image, Object.assign({ className: `${bem}__image` }, image))));
22
+ image && React.createElement(Image, Object.assign({ bem: `${bem}__image` }, image))));
23
23
  };
@@ -22,8 +22,11 @@ const icons = {
22
22
  // TODO: insert icons
23
23
  edit: 'edit',
24
24
  };
25
+ // NOTE: As this component already accepts all `<button/>` and `<a/>` props
26
+ // directly, it makes little sense to add support for `wrapperProps` on top.
25
27
  export const Button = (props) => {
26
- const { bem, small, size = 'normal', modifier, children, variant = 'normal', icon = 'none', label = children } = props, buttonProps = __rest(props, ["bem", "small", "size", "modifier", "children", "variant", "icon", "label"]);
28
+ const { bem, small, // eslint-disable-line deprecation/deprecation
29
+ size = small ? 'small' : 'normal', modifier, children, variant = 'normal', icon = 'none', label = children } = props, buttonProps = __rest(props, ["bem", "small", "size", "modifier", "children", "variant", "icon", "label"]);
27
30
  const className = bem &&
28
31
  modifiedClass(bem, [modifier, variants[variant], sizes[size], navigationFlags[icon]]);
29
32
  const iconProp = icons[icon] && { 'data-icon': icons[icon] };
@@ -1,5 +1,7 @@
1
1
  import React, { ReactElement, ReactNode } from 'react';
2
2
  import { EitherObj } from '@reykjavik/hanna-utils';
3
+ import { WrapperElmProps } from '../utils.js';
4
+ import { BemModifierProps } from '../utils/types.js';
3
5
  import { ImageProps } from './_Image.js';
4
6
  export type TextCardProps = {
5
7
  title: string;
@@ -28,6 +30,6 @@ type _CardListProps = EitherObj<ImageCardListProps, TextCardListProps> & CardLis
28
30
  bemPrefix: string;
29
31
  children?: ReactNode;
30
32
  standalone?: boolean;
31
- };
33
+ } & WrapperElmProps<'ul'> & BemModifierProps;
32
34
  export declare const CardList: (props: _CardListProps) => JSX.Element;
33
35
  export {};
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { modifiedClass } from '@hugsmidjan/qj/classUtils';
2
3
  import { Button } from './_Button.js';
3
4
  import { Image } from './_Image.js';
4
5
  const Card = (props) => {
@@ -7,7 +8,7 @@ const Card = (props) => {
7
8
  return (React.createElement(React.Fragment, null,
8
9
  React.createElement(Button, { bem: cardClass, href: href, target: target },
9
10
  ' ',
10
- !!(image || imgPlaceholder) && (React.createElement(Image, Object.assign({ className: `${bem}__image` }, image, { placeholder: imgPlaceholder }))),
11
+ !!(image || imgPlaceholder) && (React.createElement(Image, Object.assign({ bem: `${bem}__image` }, image, { placeholder: imgPlaceholder }))),
11
12
  React.createElement("span", { className: `${cardClass}__title` }, title),
12
13
  ' ',
13
14
  meta && React.createElement("span", { className: `${cardClass}__meta` }, meta),
@@ -17,7 +18,7 @@ const Card = (props) => {
17
18
  ' '));
18
19
  };
19
20
  export const CardList = (props) => {
20
- const { bemPrefix, title, summaryElement, cards, titleTag = 'h2', children, imgPlaceholder, } = props;
21
+ const { bemPrefix, modifier, title, summaryElement, cards, titleTag = 'h2', children, imgPlaceholder, wrapperProps, } = props;
21
22
  const TitleTag = titleTag;
22
23
  const fallbackImageUrl = (imgPlaceholder !== true && imgPlaceholder) || undefined;
23
24
  const fallbackImageStyle = fallbackImageUrl
@@ -29,7 +30,9 @@ export const CardList = (props) => {
29
30
  summaryElement ? (React.createElement("div", { className: bemPrefix + '__summary' },
30
31
  title && React.createElement(TitleTag, { className: bemPrefix + '__title' }, title),
31
32
  summaryElement)) : (title && React.createElement(TitleTag, { className: bemPrefix + '__title' }, title)),
32
- React.createElement("ul", { className: bemPrefix + (props.standalone ? '' : '__list'), style: fallbackImageStyle }, cards.map((card, i) => (React.createElement("li", { key: i, className: bemPrefix + '__item' },
33
+ React.createElement("ul", Object.assign({}, wrapperProps, { className: props.standalone
34
+ ? modifiedClass(bemPrefix, modifier, (wrapperProps || {}).className)
35
+ : bemPrefix + '__list', style: fallbackImageStyle }), cards.map((card, i) => (React.createElement("li", { key: i, className: bemPrefix + '__item' },
33
36
  React.createElement(Card
34
37
  /* Assert as `ImageCardProps` to silence the imgPlaceholder false-positive */
35
38
  , Object.assign({}, card, { bem: bemPrefix, imgPlaceholder: !!imgPlaceholder })))))),
@@ -1,3 +1,5 @@
1
+ import { WrapperElmProps } from '../utils.js';
2
+ import { BemProps } from '../utils/types.js';
1
3
  export type Source = {
2
4
  srcset: string;
3
5
  media: string;
@@ -23,14 +25,15 @@ export type ImagePropsInlinedSvg = {
23
25
  };
24
26
  export type ImageProps = ImagePropsLinked | ImagePropsInlinedSvg;
25
27
  type _ImageProps = {
26
- /** container className */
27
- className: string | undefined;
28
28
  /** Controls if the container is rendered when image is missing/undefined.
29
29
  * (With a `--missing` className modifier added.)
30
30
  *
31
31
  * Accepts a function that defines a default content for the container.
32
32
  */
33
33
  placeholder?: boolean | (() => JSX.Element);
34
- };
34
+ /** Extra, custom className in addition to the `bem` base */
35
+ className?: string | undefined;
36
+ bem: string | undefined;
37
+ } & BemProps & WrapperElmProps;
35
38
  export declare const Image: (props: ImageProps & _ImageProps) => JSX.Element | null;
36
39
  export {};
@@ -1,21 +1,28 @@
1
1
  import React from 'react';
2
- import { modifiedClass } from '@hugsmidjan/qj/classUtils';
2
+ import { classes, modifiedClass } from '@hugsmidjan/qj/classUtils';
3
3
  import { useGetSVGtext } from '../utils/useGetSVGtext.js';
4
4
  // eslint-disable-next-line complexity
5
5
  export const Image = (props) => {
6
- const { src, altText = '', sources = [], preloadSrc, className, inline, placeholder, focalPoint, } = props;
6
+ const { src, altText = '', sources = [], preloadSrc, modifier, bem, inline, placeholder, focalPoint, className, wrapperProps = {}, } = props;
7
7
  const _src = (sources.length && preloadSrc) || src;
8
8
  const imageSrc = _src || (sources[0] != null ? sources[0].srcset.split(' ')[0] : undefined);
9
9
  const imgLoading = preloadSrc ? 'eager' : 'lazy';
10
10
  const inlineSvg = useGetSVGtext(inline ? imageSrc : undefined, altText);
11
+ const extraClasses = classes(className, wrapperProps.className) || undefined;
12
+ const classNames = bem
13
+ ? modifiedClass(bem, [modifier, !imageSrc && 'missing'], extraClasses)
14
+ : extraClasses;
11
15
  if (!imageSrc) {
12
- return placeholder ? (React.createElement("span", { className: className && modifiedClass(className, 'missing') }, placeholder !== true && placeholder())) : null;
16
+ return placeholder ? (React.createElement("span", Object.assign({}, props.wrapperProps, { className: classNames }), placeholder !== true && placeholder())) : null;
13
17
  }
14
18
  if (inline && inlineSvg) {
15
19
  const __html = inlineSvg.imageSrc === imageSrc ? inlineSvg.code : '';
16
- return React.createElement("span", { className: className, dangerouslySetInnerHTML: { __html } });
20
+ return (React.createElement("span", Object.assign({}, props.wrapperProps, { className: classNames, dangerouslySetInnerHTML: { __html } })));
17
21
  }
18
- return (React.createElement("picture", { className: className, style: focalPoint ? { '--focalPoint': focalPoint } : undefined },
22
+ const wrapperStyles = wrapperProps.style;
23
+ return (React.createElement("picture", Object.assign({}, props.wrapperProps, { className: classNames, style: focalPoint
24
+ ? Object.assign(Object.assign({}, wrapperStyles), { '--focalPoint': focalPoint })
25
+ : wrapperStyles }),
19
26
  ' ',
20
27
  sources.map((source, i) => (React.createElement(React.Fragment, null,
21
28
  React.createElement("source", { key: i, srcSet: source.srcset, media: source.media }),
@@ -1,8 +1,9 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { EitherObj } from '@reykjavik/hanna-utils';
3
+ import { WrapperElmProps } from '../utils.js';
3
4
  export type QuoteProps = {
4
5
  children: ReactNode;
5
- } & EitherObj<object, {
6
+ } & WrapperElmProps & EitherObj<object, {
6
7
  by: string | JSX.Element;
7
8
  byHref?: string;
8
9
  }>;
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
+ import { modifiedClass } from '@hugsmidjan/qj/classUtils';
2
3
  import { Link } from './_Link.js';
3
4
  export const _Quote = (props) => {
4
- const { bem, children, by, byHref } = props;
5
- return (React.createElement("figure", { className: bem },
5
+ const { bem, children, by, byHref, wrapperProps } = props;
6
+ return (React.createElement("figure", Object.assign({}, wrapperProps, { className: modifiedClass(bem, null, (wrapperProps || {}).className) }),
6
7
  React.createElement("blockquote", { className: bem + '__quote' }, children),
7
8
  by && (React.createElement("figcaption", { className: bem + '__by' }, byHref ? (React.createElement(Link, { href: byHref }, by)) : typeof by === 'string' ? (React.createElement("span", null, by)) : (by)))));
8
9
  };
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
- import { useDomid } from '@hugsmidjan/react/hooks';
3
2
  import { modifiedClass } from '@hugsmidjan/qj/classUtils';
3
+ import { useDomid } from '@hugsmidjan/react/hooks';
4
4
  import { useMixedControlState } from '../utils.js';
5
5
  export const TogglerGroup = (props) => {
6
6
  const {
@@ -1,17 +1,17 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { useMemo } from 'react';
3
3
  import { modifiedClass } from '@hugsmidjan/qj/classUtils';
4
- import FormField from '../FormField.js';
4
+ import FormField, { groupFormFieldWrapperProps, } from '../FormField.js';
5
5
  import { TogglerGroup, } from './_TogglerGroup.js';
6
6
  export const TogglerGroupField = (props) => {
7
- const { bem, Toggler, className, modifier, label, LabelTag, assistText, hideLabel, disabled, readOnly, invalid, errorMessage, required, reqText, id, value, defaultValue } = props, togglerGroupProps = __rest(props, ["bem", "Toggler", "className", "modifier", "label", "LabelTag", "assistText", "hideLabel", "disabled", "readOnly", "invalid", "errorMessage", "required", "reqText", "id", "value", "defaultValue"]);
7
+ const _a = groupFormFieldWrapperProps(props), { bem, Toggler, modifier, value, defaultValue, fieldWrapperProps } = _a, togglerGroupProps = __rest(_a, ["bem", "Toggler", "modifier", "value", "defaultValue", "fieldWrapperProps"]);
8
8
  const _value = useMemo(() => (value == null ? undefined : typeof value === 'string' ? [value] : value), [value]);
9
9
  const _defaultValue = useMemo(() => defaultValue == null
10
10
  ? undefined
11
11
  : typeof defaultValue === 'string'
12
12
  ? [defaultValue]
13
13
  : defaultValue, [defaultValue]);
14
- return (React.createElement(FormField, { className: modifiedClass(bem, modifier, className), group: true, label: label, LabelTag: LabelTag, assistText: assistText, hideLabel: hideLabel, disabled: !!disabled, readOnly: readOnly, invalid: invalid, errorMessage: errorMessage, required: required, reqText: reqText, id: id, renderInput: (className, inputProps) => {
15
- return (React.createElement(TogglerGroup, Object.assign({ bem: className.options }, inputProps, togglerGroupProps, { disabled: disabled, value: _value, defaultValue: _defaultValue, Toggler: Toggler })));
16
- } }));
14
+ return (React.createElement(FormField, Object.assign({ extraClassName: modifiedClass(bem, modifier), group: true }, fieldWrapperProps, { renderInput: (className, inputProps) => {
15
+ return (React.createElement(TogglerGroup, Object.assign({ bem: className.options }, inputProps, togglerGroupProps, { disabled: props.disabled, value: _value, defaultValue: _defaultValue, Toggler: Toggler })));
16
+ } })));
17
17
  };
@@ -1,3 +1,4 @@
1
+ import { WrapperElmProps } from '../utils.js';
1
2
  import { BemModifierProps } from '../utils/types.js';
2
3
  export type TogglerInputProps = {
3
4
  label: string | JSX.Element;
@@ -13,9 +14,8 @@ export type TogglerInputProps = {
13
14
  reqText?: string | false;
14
15
  errorMessage?: string | JSX.Element;
15
16
  Wrapper?: 'div' | 'li';
16
- wrapperProps?: JSX.IntrinsicElements['div'];
17
17
  inputProps?: JSX.IntrinsicElements['input'];
18
- } & BemModifierProps & Omit<JSX.IntrinsicElements['input'], 'type'>;
18
+ } & BemModifierProps & WrapperElmProps & Omit<JSX.IntrinsicElements['input'], 'type'>;
19
19
  type _TogglerInputProps = {
20
20
  bem: string;
21
21
  type: 'radio' | 'checkbox';
@@ -7,7 +7,7 @@ export const TogglerInput = (props) => {
7
7
  const domid = useDomid(id);
8
8
  const errorId = errorMessage && 'error' + domid;
9
9
  const reqStar = required && reqText !== false && (React.createElement("abbr", { className: bem + '__label__reqstar',
10
- // TODO: add mo-better i18n thinking
10
+ // FIXME: add mo-better i18n thinking
11
11
  title: (reqText || 'Þarf að haka í') + ': ' }, "*"));
12
12
  const readOnly = restInputProps.readOnly || (inputProps || {}).readOnly;
13
13
  const labelContent = (React.createElement(React.Fragment, null,
@@ -16,7 +16,9 @@ export const TogglerInput = (props) => {
16
16
  " ",
17
17
  label,
18
18
  ' '));
19
- return (React.createElement(Wrapper, Object.assign({}, wrapperProps, { className: modifiedClass(bem, modifier, className) }),
19
+ return (React.createElement(Wrapper, Object.assign({}, wrapperProps, { className: modifiedClass(bem, modifier,
20
+ // Prefer `className` over `wrapperProps.className`
21
+ className || (wrapperProps || {}).className) }),
20
22
  React.createElement("input", Object.assign({ className: bem + '__input', type: type, id: domid, "aria-invalid": invalid || !!errorMessage || undefined, "aria-describedby": errorId }, restInputProps, inputProps, (readOnly && { disabled: true }))),
21
23
  ' ',
22
24
  React.createElement("label", { className: bem + '__label', htmlFor: domid },
package/esm/utils.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { ElementRef } from 'react';
1
2
  export * from './utils/browserSide.js';
2
3
  export * from './utils/config.js';
3
4
  export { HannaUIState, useHannaUIState } from './utils/HannaUIState.js';
@@ -9,8 +10,30 @@ export * from './utils/useMixedControlState.js';
9
10
  export * from './utils/useScrollbarWidthCSSVar.js';
10
11
  /**
11
12
  * Helper type to add HTML element props to a component, **including**
12
- * `data-*` attributes
13
+ * `data-*` attributes.
13
14
  */
14
- export type HTMLProps<T extends keyof JSX.IntrinsicElements> = JSX.IntrinsicElements[T] & {
15
+ export type HTMLProps<TagName extends keyof JSX.IntrinsicElements | null = null, ExcludeProps extends string = never> = Omit<JSX.IntrinsicElements[TagName extends null ? 'div' : TagName], 'ref' | 'children' | 'dangerouslySetInnerHTML' | ExcludeProps> & {
16
+ ref?: React.RefObject<ElementRef<TagName extends null ? 'div' : TagName>>;
15
17
  [dataAttr: `data-${string}`]: unknown;
16
18
  };
19
+ export type WrapperElmProps<TagName extends keyof JSX.IntrinsicElements | null = null, ExcludeProps extends string = never> = {
20
+ /**
21
+ * Custom HTML attributes for the component's wrapper element.
22
+ *
23
+ * Note, however, that some props may be intentionally
24
+ * excluded from the list.
25
+ *
26
+ * **WARNING**
27
+ * In some cases props added this way can break the component, og hurt its
28
+ * accessibility. Also, some props may get ignored, or over-ridden by the
29
+ * component. User discretion is advised.
30
+ */
31
+ wrapperProps?: HTMLProps<TagName, ExcludeProps>;
32
+ };
33
+ export type MissingWrapperElmProps = {
34
+ /**
35
+ * This component does NOT allow `wrapperPRops` yet, but will do so
36
+ * in a near-future version of the `@reykjavik/hanna-react` library.
37
+ */
38
+ wrapperProps?: undefined;
39
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reykjavik/hanna-react",
3
- "version": "0.10.99",
3
+ "version": "0.10.101",
4
4
  "author": "Reykjavík (http://www.reykjavik.is)",
5
5
  "contributors": [
6
6
  "Hugsmiðjan ehf (http://www.hugsmidjan.is)",