@reykjavik/hanna-react 0.10.103 → 0.10.104

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 (136) hide show
  1. package/AccordionList.js +2 -2
  2. package/Alert.d.ts +2 -2
  3. package/Alert.js +1 -0
  4. package/AutosuggestSearch.d.ts +40 -0
  5. package/AutosuggestSearch.js +70 -0
  6. package/BasicTable.d.ts +24 -4
  7. package/BasicTable.js +20 -19
  8. package/BreadCrumbs.d.ts +2 -2
  9. package/CHANGELOG.md +34 -0
  10. package/ContactBubble.d.ts +4 -3
  11. package/ContactBubble.js +7 -4
  12. package/Datepicker.d.ts +8 -3
  13. package/Datepicker.js +36 -14
  14. package/FileInput.d.ts +2 -1
  15. package/FileInput.js +2 -2
  16. package/FormField.js +2 -2
  17. package/Gallery.d.ts +2 -1
  18. package/Gallery.js +5 -0
  19. package/Layout.d.ts +4 -3
  20. package/Layout.js +0 -3
  21. package/MainMenu/_PrimaryPanel.d.ts +3 -4
  22. package/MainMenu/_PrimaryPanel.js +1 -1
  23. package/MainMenu.d.ts +6 -4
  24. package/MainMenu.js +8 -16
  25. package/Multiselect.d.ts +2 -1
  26. package/Multiselect.js +4 -3
  27. package/NameCard.d.ts +2 -1
  28. package/NameCard.js +7 -0
  29. package/Pagination.d.ts +2 -2
  30. package/ReadSpeakerPlayer.js +13 -5
  31. package/SearchInput.d.ts +24 -2
  32. package/SearchInput.js +13 -3
  33. package/SearchResults.d.ts +2 -1
  34. package/SearchResults.js +10 -2
  35. package/ShareButtons.d.ts +3 -2
  36. package/SiteSearchAutocomplete.d.ts +11 -11
  37. package/SiteSearchAutocomplete.js +21 -7
  38. package/SiteSearchCurtain.js +2 -2
  39. package/SiteSearchInput.d.ts +19 -10
  40. package/SiteSearchInput.js +9 -6
  41. package/Tooltip.js +4 -3
  42. package/VerticalTabsTOC.js +2 -2
  43. package/_abstract/_ScrollWrapper.d.ts +10 -0
  44. package/_abstract/_ScrollWrapper.js +21 -0
  45. package/_abstract/_Table.d.ts +71 -0
  46. package/_abstract/_Table.js +55 -0
  47. package/_abstract/_TogglerGroup.js +2 -2
  48. package/_abstract/_TogglerInput.js +2 -2
  49. package/_mixed_export_resolution_/ReactDatepicker.d.ts +3 -0
  50. package/esm/AccordionList.js +1 -1
  51. package/esm/Alert.d.ts +2 -2
  52. package/esm/Alert.js +1 -0
  53. package/esm/AutosuggestSearch.d.ts +40 -0
  54. package/esm/AutosuggestSearch.js +66 -0
  55. package/esm/BasicTable.d.ts +24 -4
  56. package/esm/BasicTable.js +19 -18
  57. package/esm/BreadCrumbs.d.ts +2 -2
  58. package/esm/ContactBubble.d.ts +4 -3
  59. package/esm/ContactBubble.js +6 -3
  60. package/esm/Datepicker.d.ts +8 -3
  61. package/esm/Datepicker.js +35 -13
  62. package/esm/FileInput.d.ts +2 -1
  63. package/esm/FileInput.js +1 -1
  64. package/esm/FormField.js +1 -1
  65. package/esm/Gallery.d.ts +2 -1
  66. package/esm/Gallery.js +5 -0
  67. package/esm/Layout.d.ts +4 -3
  68. package/esm/Layout.js +0 -3
  69. package/esm/MainMenu/_PrimaryPanel.d.ts +3 -4
  70. package/esm/MainMenu/_PrimaryPanel.js +1 -1
  71. package/esm/MainMenu.d.ts +6 -4
  72. package/esm/MainMenu.js +8 -16
  73. package/esm/Multiselect.d.ts +2 -1
  74. package/esm/Multiselect.js +2 -1
  75. package/esm/NameCard.d.ts +2 -1
  76. package/esm/NameCard.js +7 -0
  77. package/esm/Pagination.d.ts +2 -2
  78. package/esm/ReadSpeakerPlayer.js +13 -5
  79. package/esm/SearchInput.d.ts +24 -2
  80. package/esm/SearchInput.js +13 -3
  81. package/esm/SearchResults.d.ts +2 -1
  82. package/esm/SearchResults.js +9 -1
  83. package/esm/ShareButtons.d.ts +3 -2
  84. package/esm/SiteSearchAutocomplete.d.ts +11 -11
  85. package/esm/SiteSearchAutocomplete.js +21 -7
  86. package/esm/SiteSearchCurtain.js +1 -1
  87. package/esm/SiteSearchInput.d.ts +19 -10
  88. package/esm/SiteSearchInput.js +8 -6
  89. package/esm/Tooltip.js +2 -1
  90. package/esm/VerticalTabsTOC.js +1 -1
  91. package/esm/_abstract/_ScrollWrapper.d.ts +10 -0
  92. package/esm/_abstract/_ScrollWrapper.js +16 -0
  93. package/esm/_abstract/_Table.d.ts +71 -0
  94. package/esm/_abstract/_Table.js +51 -0
  95. package/esm/_abstract/_TogglerGroup.js +1 -1
  96. package/esm/_abstract/_TogglerInput.js +1 -1
  97. package/esm/_mixed_export_resolution_/ReactDatepicker.d.ts +3 -0
  98. package/esm/index.d.ts +1 -0
  99. package/esm/utils/browserSide.d.ts +119 -1
  100. package/esm/utils/browserSide.js +152 -1
  101. package/esm/utils/config.d.ts +1 -14
  102. package/esm/utils/config.js +0 -2
  103. package/esm/utils/useCallbackOnEsc.d.ts +6 -0
  104. package/esm/utils/useCallbackOnEsc.js +25 -0
  105. package/esm/utils/useDomid.d.ts +8 -0
  106. package/esm/utils/useDomid.js +17 -0
  107. package/esm/utils/useLaggedState.d.ts +18 -0
  108. package/esm/utils/useLaggedState.js +84 -0
  109. package/esm/utils/useOnClickOutside.d.ts +9 -0
  110. package/esm/utils/useOnClickOutside.js +32 -0
  111. package/esm/utils/useScrollEdgeDetect.d.ts +15 -0
  112. package/esm/utils/useScrollEdgeDetect.js +45 -0
  113. package/esm/utils/useShortState.d.ts +2 -0
  114. package/esm/utils/useShortState.js +34 -0
  115. package/esm/utils.d.ts +1 -0
  116. package/esm/utils.js +1 -0
  117. package/index.d.ts +1 -0
  118. package/package.json +6 -2
  119. package/utils/browserSide.d.ts +119 -1
  120. package/utils/browserSide.js +156 -4
  121. package/utils/config.d.ts +1 -14
  122. package/utils/config.js +1 -4
  123. package/utils/useCallbackOnEsc.d.ts +6 -0
  124. package/utils/useCallbackOnEsc.js +29 -0
  125. package/utils/useDomid.d.ts +8 -0
  126. package/utils/useDomid.js +21 -0
  127. package/utils/useLaggedState.d.ts +18 -0
  128. package/utils/useLaggedState.js +88 -0
  129. package/utils/useOnClickOutside.d.ts +9 -0
  130. package/utils/useOnClickOutside.js +35 -0
  131. package/utils/useScrollEdgeDetect.d.ts +15 -0
  132. package/utils/useScrollEdgeDetect.js +50 -0
  133. package/utils/useShortState.d.ts +2 -0
  134. package/utils/useShortState.js +38 -0
  135. package/utils.d.ts +1 -0
  136. package/utils.js +1 -0
@@ -1,18 +1,22 @@
1
1
  import React from 'react';
2
2
  import Autosuggest, { RenderSuggestion } from 'react-autosuggest';
3
- import { DefaultTexts } from '@reykjavik/hanna-utils/i18n';
3
+ import { DefaultTexts, HannaLang } from '@reykjavik/hanna-utils/i18n';
4
4
  import { BemProps } from './utils/types.js';
5
+ import { SiteSearchInputProps } from './SiteSearchInput.js';
5
6
  import { WrapperElmProps } from './utils.js';
6
7
  export type SiteSearchACI18n = {
7
- lang?: string;
8
8
  /** Label for the autocomplete's combobox container div */
9
9
  label: string;
10
10
  /** Label for the text input */
11
11
  inputLabel: string;
12
12
  /** Placeholder text for the text input */
13
13
  placeholder?: string;
14
+ /** Label for the search button */
15
+ buttonText?: string;
14
16
  /** Label for the suggestions item list container */
15
17
  suggestionsLabel: string;
18
+ /** @deprecated Not used (Will be removed in v0.11) */
19
+ lang?: string;
16
20
  };
17
21
  export declare const defaultSiteSearchACTexts: DefaultTexts<SiteSearchACI18n>;
18
22
  export type SiteSearchAutocompleteProps<T> = {
@@ -25,17 +29,13 @@ export type SiteSearchAutocompleteProps<T> = {
25
29
  onSuggestionHighlighted?: (params: {
26
30
  suggestion: T;
27
31
  }) => void;
28
- /** Triggered when user hits ENTER key with the focus inside the input field */
29
- onSubmit?: (value: string) => void;
30
- /** Custom action to perform when the user clicks the search button
31
- *
32
- * Defaults to `onSubmit`
33
- */
34
- onButtonClick?: (value: string) => void;
35
- lang?: string;
36
32
  texts?: SiteSearchACI18n;
33
+ lang?: HannaLang;
37
34
  /** @deprecated Use `text` prop instead (will be removed in v0.11) */
38
35
  label?: string;
39
- } & BemProps & WrapperElmProps;
36
+ } & Pick<SiteSearchInputProps, 'onSubmit' | 'onButtonClick'> & Pick<BemProps, 'bem'> & WrapperElmProps;
37
+ /**
38
+ * @deprecated Use `<AutosuggestSearch InputComponent={SiteSearchInput} itemActionIcon="search" />` instead (Will be removed in v0.11)
39
+ */
40
40
  export declare const SiteSearchAutocomplete: <T>(props: SiteSearchAutocompleteProps<T>) => JSX.Element;
41
41
  export default SiteSearchAutocomplete;
@@ -2,28 +2,41 @@ import { __rest } from "tslib";
2
2
  import React, { createRef, useState } from 'react';
3
3
  import Autosuggest from 'react-autosuggest';
4
4
  import { getTexts } from '@reykjavik/hanna-utils/i18n';
5
- import SiteSearchInput from './SiteSearchInput.js';
5
+ import { SiteSearchInput } from './SiteSearchInput.js';
6
6
  export const defaultSiteSearchACTexts = {
7
7
  is: {
8
- lang: 'is',
9
8
  label: 'Leit á vefnum',
10
9
  inputLabel: 'Leitarorð',
10
+ buttonText: 'Leita',
11
11
  placeholder: 'Sláðu inn leitarorð',
12
12
  suggestionsLabel: 'Tillögur',
13
13
  },
14
14
  en: {
15
- lang: 'en',
16
15
  label: 'Site search',
17
16
  inputLabel: 'Search terms',
17
+ buttonText: 'Search',
18
18
  placeholder: 'Enter search terms',
19
19
  suggestionsLabel: 'Suggestions',
20
20
  },
21
+ pl: {
22
+ label: 'Wyszukiwanie na stronie',
23
+ inputLabel: 'Wyszukiwane słowa',
24
+ buttonText: 'Szukaj',
25
+ placeholder: 'Wpisz wyszukiwane słowa',
26
+ suggestionsLabel: 'Sugestie',
27
+ },
21
28
  };
29
+ /**
30
+ * @deprecated Use `<AutosuggestSearch InputComponent={SiteSearchInput} itemActionIcon="search" />` instead (Will be removed in v0.11)
31
+ */
22
32
  export const SiteSearchAutocomplete = (props) => {
23
- const { suggestions, setSuggestions, renderSuggestion, getSuggestionValue, onSuggestionsFetchRequested, onSuggestionSelected, onSuggestionHighlighted, onSubmit, onButtonClick = onSubmit, bem = 'SiteSearchAutocomplete', wrapperProps, } = props;
33
+ const { suggestions, setSuggestions, renderSuggestion, getSuggestionValue, onSuggestionsFetchRequested, onSuggestionSelected, onSuggestionHighlighted, onSubmit, onButtonClick, bem = 'SiteSearchAutocomplete', wrapperProps, } = props;
24
34
  const [value, setValue] = useState('');
25
35
  const inputRef = createRef();
26
36
  const txt = getTexts(props, defaultSiteSearchACTexts);
37
+ if (process.env.NODE_ENV !== 'production' && !txt.buttonText) {
38
+ console.warn('SiteSearchAutocomplete: Missing translation: `buttonText`');
39
+ }
27
40
  return (React.createElement(Autosuggest, { theme: {
28
41
  container: bem,
29
42
  containerOpen: bem + '--open',
@@ -32,7 +45,7 @@ export const SiteSearchAutocomplete = (props) => {
32
45
  suggestionsList: bem + '__list',
33
46
  suggestion: bem + '__item',
34
47
  suggestionHighlighted: bem + '__item--highlighted',
35
- }, focusInputOnSuggestionClick: true, suggestions: suggestions, onSuggestionsClearRequested: () => setSuggestions([]), onSuggestionsFetchRequested: onSuggestionsFetchRequested, getSuggestionValue: getSuggestionValue, onSuggestionSelected: onSuggestionSelected, onSuggestionHighlighted: onSuggestionHighlighted, renderSuggestion: renderSuggestion || ((s) => String(s)), containerProps: { 'aria-label': txt.label }, renderSuggestionsContainer: ({ containerProps, children }) => (React.createElement("div", Object.assign({}, containerProps, { "aria-label": suggestions.length ? txt.suggestionsLabel : undefined }), children)), inputProps: {
48
+ }, focusInputOnSuggestionClick: true, suggestions: suggestions, onSuggestionsClearRequested: () => setSuggestions([]), onSuggestionsFetchRequested: onSuggestionsFetchRequested, getSuggestionValue: getSuggestionValue, onSuggestionSelected: onSuggestionSelected, onSuggestionHighlighted: onSuggestionHighlighted, renderSuggestion: renderSuggestion || ((s) => String(s)), containerProps: Object.assign(Object.assign({}, wrapperProps), { 'aria-label': txt.label }), renderSuggestionsContainer: ({ containerProps, children }) => (React.createElement("div", Object.assign({}, containerProps, { "aria-label": suggestions.length ? txt.suggestionsLabel : undefined }), children)), inputProps: {
36
49
  ref: inputRef,
37
50
  value: value,
38
51
  onChange: (_, { newValue }) => {
@@ -41,8 +54,9 @@ export const SiteSearchAutocomplete = (props) => {
41
54
  }, renderInputComponent: (inputProps) => {
42
55
  /* prettier-ignore */
43
56
  const { className, type, disabled, readOnly, required, children } = inputProps, siteSearchProps = __rest(inputProps, ["className", "type", "disabled", "readOnly", "required", "children"]);
44
- return (React.createElement(SiteSearchInput, Object.assign({}, siteSearchProps, { wrapperProps: wrapperProps, label: props.label || // eslint-disable-line deprecation/deprecation
45
- txt.inputLabel, placeholder: txt.placeholder, onSubmit: onSubmit && (() => onSubmit(value)), onButtonClick: onButtonClick && (() => onButtonClick(value)) })));
57
+ return (React.createElement(SiteSearchInput, Object.assign({}, siteSearchProps, { label: props.label || // eslint-disable-line deprecation/deprecation
58
+ txt.inputLabel, placeholder: txt.placeholder, buttonText: txt.buttonText, onSubmit: onSubmit && (() => onSubmit(value)), onButtonClick: onButtonClick && (() => onButtonClick(value)) })));
46
59
  } }));
47
60
  };
61
+ // eslint-disable-next-line deprecation/deprecation
48
62
  export default SiteSearchAutocomplete;
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import { modifiedClass } from '@hugsmidjan/qj/classUtils';
3
- import { useLaggedState } from '@hugsmidjan/react/hooks';
4
3
  import { isPreact } from './utils/env.js';
4
+ import { useLaggedState } from './utils/useLaggedState.js';
5
5
  // NOTE: This component is too low-level (and too esoteric and rarely used)
6
6
  // to justify `wrapperProps`
7
7
  export const SiteSearchCurtain = (props) => {
@@ -1,20 +1,29 @@
1
- import React from 'react';
2
1
  import { FormFieldWrappingProps } from './FormField.js';
3
- type InputElmProps = Omit<JSX.IntrinsicElements['input'], 'className' | 'type' | 'disabled' | 'readOnly' | 'required' | 'onSubmit'>;
2
+ type InputElmProps = Omit<JSX.IntrinsicElements['input'], 'className' | 'type' | 'disabled' | 'readOnly' | 'required' | 'onSubmit' | 'ref' | 'value'> & {
3
+ value?: string;
4
+ };
4
5
  export type SiteSearchInputProps = Pick<FormFieldWrappingProps, 'id' | 'label' | 'ssr' | 'wrapperProps'> & {
5
- /** Triggered when user hits ENTER key with the focus inside the input field
6
+ /**
7
+ * Triggered when user hits ENTER key with the focus inside the input field.
6
8
  *
7
- * Return `true` to __allow__ the browser's default submit hehavior
9
+ * Return `true` to __allow__ the browser's default submit hehavior.
8
10
  */
9
- onSubmit?: () => boolean | void;
10
- /** Custom action to perform when the user clicks the search button
11
+ onSubmit?: (value: string) => boolean | void;
12
+ /**
13
+ * Custom action to perform when the user clicks the search button.
11
14
  *
12
- * Return `true` to __allow__ the browser's default submit hehavior
15
+ * Return `true` to __allow__ the browser's default submit hehavior.
13
16
  *
14
- * Defaults to `onSearch`
17
+ * Defaults to `onSubmit`.
15
18
  */
16
- onButtonClick?: () => boolean | void;
19
+ onButtonClick?: (value: string) => boolean | void;
20
+ /**
21
+ * Toggle the search `<button/>`.
22
+ *
23
+ * Defaults to `true`.
24
+ */
25
+ button?: boolean;
17
26
  buttonText?: string;
18
27
  } & InputElmProps;
19
- export declare const SiteSearchInput: React.ForwardRefExoticComponent<Pick<SiteSearchInputProps, "form" | "label" | "slot" | "style" | "title" | "key" | "list" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "nonce" | "placeholder" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "step" | "value" | "pattern" | "name" | "wrapperProps" | "autoFocus" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "size" | "src" | "multiple" | "alt" | "ssr" | "accept" | "autoComplete" | "capture" | "checked" | "crossOrigin" | "enterKeyHint" | "height" | "max" | "maxLength" | "min" | "minLength" | "width" | "onButtonClick" | "buttonText"> & React.RefAttributes<HTMLInputElement>>;
28
+ export declare const SiteSearchInput: (props: SiteSearchInputProps) => JSX.Element;
20
29
  export default SiteSearchInput;
@@ -2,9 +2,9 @@ import { __rest } from "tslib";
2
2
  import React, { useState } from 'react';
3
3
  import FormField, { groupFormFieldWrapperProps, } from './FormField.js';
4
4
  // ---------------------------------------------------------------------------
5
- export const SiteSearchInput = React.forwardRef((props, ref) => {
5
+ export const SiteSearchInput = (props) => {
6
6
  var _a;
7
- const _b = groupFormFieldWrapperProps(props), { onChange, buttonText = 'Leita', onSubmit, onButtonClick = props.onSubmit, onKeyDown, placeholder = typeof props.label === 'string' ? props.label : undefined, fieldWrapperProps } = _b, inputElementProps = __rest(_b, ["onChange", "buttonText", "onSubmit", "onButtonClick", "onKeyDown", "placeholder", "fieldWrapperProps"]);
7
+ const _b = groupFormFieldWrapperProps(props), { onChange, buttonText = 'Leita', onSubmit, onButtonClick = props.onSubmit, button, onKeyDown, placeholder = typeof props.label === 'string' ? props.label : undefined, fieldWrapperProps } = _b, inputElementProps = __rest(_b, ["onChange", "buttonText", "onSubmit", "onButtonClick", "button", "onKeyDown", "placeholder", "fieldWrapperProps"]);
8
8
  const { value, defaultValue } = inputElementProps;
9
9
  const [hasValue, setHasValue] = useState(undefined);
10
10
  const filled = !!((_a = value !== null && value !== void 0 ? value : hasValue) !== null && _a !== void 0 ? _a : !!defaultValue);
@@ -15,16 +15,18 @@ export const SiteSearchInput = React.forwardRef((props, ref) => {
15
15
  setHasValue(!!e.target.value);
16
16
  onChange && onChange(e);
17
17
  };
18
+ const showButton = button !== false;
18
19
  return (React.createElement(FormField, Object.assign({ extraClassName: "SiteSearchInput", empty: empty, filled: filled }, fieldWrapperProps, { renderInput: (className, inputProps, addFocusProps) => (React.createElement("div", Object.assign({ className: className.input }, addFocusProps()),
19
20
  React.createElement("input", Object.assign({ className: "SiteSearchInput__input", onChange: _onChange }, inputProps, { placeholder: placeholder, onKeyDown: onSubmit
20
21
  ? (e) => {
21
- if (e.key === 'Enter' && onSubmit() !== true) {
22
+ if (e.key === 'Enter' && onSubmit(e.currentTarget.value) !== true) {
22
23
  e.preventDefault();
23
24
  }
24
25
  onKeyDown && onKeyDown(e);
25
26
  }
26
- : onKeyDown }, inputElementProps, { ref: ref })),
27
+ : onKeyDown }, inputElementProps)),
27
28
  ' ',
28
- React.createElement("button", { className: "SiteSearchInput__button", type: "submit", onClick: onButtonClick && ((e) => !onButtonClick() && e.preventDefault()), title: buttonText }, buttonText))) })));
29
- });
29
+ showButton && (React.createElement("button", { className: "SiteSearchInput__button", type: "submit", onClick: onButtonClick &&
30
+ ((e) => onButtonClick(e.currentTarget.value) !== true && e.preventDefault()), title: buttonText }, buttonText)))) })));
31
+ };
30
32
  export default SiteSearchInput;
package/esm/Tooltip.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import React, { useRef } from 'react';
2
2
  import { arrow as arrowPlugin, autoUpdate, flip, offset, shift, useFloating, } from '@floating-ui/react';
3
3
  import { modifiedClass } from '@hugsmidjan/qj/classUtils';
4
- import { useCallbackOnEsc, useLaggedState } from '@hugsmidjan/react/hooks';
4
+ import { useCallbackOnEsc } from './utils/useCallbackOnEsc.js';
5
+ import { useLaggedState } from './utils/useLaggedState.js';
5
6
  const getSide = (placement) => placement.split('-')[0];
6
7
  export const Tooltip = (props) => {
7
8
  const { text, label, iconOnly, wrapperProps = {} } = props;
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useMemo, useState } from 'react';
2
2
  import { setFrag } from '@hugsmidjan/qj/frag';
3
- import { useDomid } from '@hugsmidjan/react/hooks';
3
+ import { useDomid } from './utils/useDomid.js';
4
4
  import Tabs from './Tabs.js';
5
5
  const getId = (url) => (url && decodeURIComponent(url.split('#')[1] || '')) || '';
6
6
  const getItemId = (item) => getId(item && item.href);
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { WrapperElmProps } from '../utils.js';
3
+ import { BemProps } from '../utils/types.js';
4
+ type ScrollWrapperProps = {
5
+ children: React.ReactNode;
6
+ } & BemProps & WrapperElmProps;
7
+ export declare const ScrollWrapper: (props: ScrollWrapperProps & {
8
+ innerWrap?: true;
9
+ }) => JSX.Element;
10
+ export {};
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { modifiedClass } from '@hugsmidjan/qj/classUtils';
3
+ import { useIsBrowserSide } from '../utils.js';
4
+ import { useScrollEdgeDetect, } from '../utils/useScrollEdgeDetect.js';
5
+ const scrollOptions = {
6
+ axis: 'horizontal',
7
+ };
8
+ export const ScrollWrapper = (props) => {
9
+ const { innerWrap, children, modifier, bem = 'ScrollWrapper', wrapperProps = {}, } = props;
10
+ const isBrowser = useIsBrowserSide();
11
+ const [scrollerRef, scrollAt] = useScrollEdgeDetect(scrollOptions, wrapperProps.ref);
12
+ const modifiers = isBrowser
13
+ ? [modifier, 'at', scrollAt.start && 'at--start', scrollAt.end && 'at--end']
14
+ : modifier;
15
+ return (React.createElement("div", Object.assign({}, wrapperProps, { className: modifiedClass(bem, modifiers, wrapperProps.className), ref: !innerWrap ? scrollerRef : undefined }), isBrowser && innerWrap ? (React.createElement("div", { className: `${bem}__scroller`, ref: scrollerRef }, children)) : (children)));
16
+ };
@@ -0,0 +1,71 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { HTMLProps, WrapperElmProps } from '../utils.js';
3
+ type SectionTag = 'thead' | 'tfoot' | 'tbody';
4
+ type RowPropsFunction = (rowIdx: number, section: SectionTag) => HTMLProps<'tr'> | undefined;
5
+ export type TableCellMeta = {
6
+ className?: string;
7
+ number?: false;
8
+ tel?: false;
9
+ text?: false;
10
+ } | {
11
+ className?: string;
12
+ number: true | 'pos' | 'neg';
13
+ tel?: false;
14
+ text?: false;
15
+ } | {
16
+ className?: string;
17
+ tel: true;
18
+ number?: false;
19
+ text?: false;
20
+ } | {
21
+ className?: string;
22
+ text: true | 'right' | 'center';
23
+ number?: false;
24
+ tel?: false;
25
+ };
26
+ export type TableCellData = {
27
+ value: ReactNode | ((rowIdx: number) => ReactNode);
28
+ colSpan?: number;
29
+ key?: string | number;
30
+ } & TableCellMeta;
31
+ type RowData = {
32
+ cells: Array<TableCellData>;
33
+ key: string | number | undefined;
34
+ };
35
+ export type TableCols = Array<TableCellMeta | null>;
36
+ export type TableCell = string | TableCellData;
37
+ export type TableRow = Array<TableCell> | {
38
+ cells: Array<TableCell>;
39
+ /** Manual `key` prop for stable re-renders */
40
+ key?: string | number;
41
+ };
42
+ type TableSection = Array<TableRow>;
43
+ export type TableBody = TableSection;
44
+ export type TableHead = TableSection;
45
+ export type TableFoot = TableSection;
46
+ export type TableData = {
47
+ caption?: ReactNode;
48
+ thead: TableHead;
49
+ tfoot?: TableFoot;
50
+ } & ({
51
+ tbody: TableBody;
52
+ tbodies?: undefined;
53
+ } | {
54
+ tbody?: undefined;
55
+ tbodies: Array<TableBody>;
56
+ });
57
+ type TableSectionProps = {
58
+ section: Array<RowData>;
59
+ cols?: TableCols;
60
+ Tag: SectionTag;
61
+ getRowProps: RowPropsFunction;
62
+ };
63
+ declare const TableSection: ({ section, cols, Tag, getRowProps }: TableSectionProps) => JSX.Element | null;
64
+ export type TableProps = TableData & {
65
+ cols?: TableCols;
66
+ rowProps?: HTMLProps<'tr'> | RowPropsFunction;
67
+ } & WrapperElmProps<'table'>;
68
+ export declare const Table: React.MemoExoticComponent<(props: TableProps & {
69
+ className?: string;
70
+ }) => JSX.Element>;
71
+ export {};
@@ -0,0 +1,51 @@
1
+ import React, { memo, useMemo } from 'react';
2
+ import { classes } from '@hugsmidjan/qj/classUtils';
3
+ import { notNully } from '@reykjavik/hanna-utils';
4
+ const TableCell = (props) => {
5
+ const { data, meta = {}, rowIdx, rowScope } = props;
6
+ const Tag = props.th ? 'th' : 'td';
7
+ const { className = meta.className || '', number = meta.number, text = meta.text, tel = meta.tel, value, colSpan, } = data;
8
+ const numberClass = !number
9
+ ? ''
10
+ : number === true
11
+ ? 'Cell--number'
12
+ : 'Cell--number Cell--number--' + number;
13
+ const textClass = !text
14
+ ? ''
15
+ : text === true
16
+ ? 'Cell--text'
17
+ : 'Cell--text Cell--text--' + text;
18
+ const telClass = tel ? 'Cell--tel' : '';
19
+ return (React.createElement(Tag, { className: classes(numberClass || telClass || textClass, className), colSpan: colSpan && colSpan > 1 ? colSpan : undefined, scope: rowScope ? 'row' : undefined }, typeof value === 'function' ? value(rowIdx) : value));
20
+ };
21
+ const TableSection = ({ section, cols = [], Tag, getRowProps }) => section.length ? (React.createElement(Tag, null, section.map(({ key, cells }, rowIdx) => {
22
+ let colIdx = 0;
23
+ return (React.createElement("tr", Object.assign({}, getRowProps(rowIdx, Tag), { key: key != null ? key : rowIdx }), cells.map((cell, i) => {
24
+ const rowScope = i === 0;
25
+ const meta = cols[colIdx];
26
+ colIdx += cell.colSpan || 1;
27
+ return (React.createElement(TableCell, { key: cell.key || i, th: Tag === 'thead' || rowScope, data: cell, meta: meta || undefined, rowIdx: rowIdx, rowScope: rowScope }));
28
+ })));
29
+ }))) : null;
30
+ // ===========================================================================
31
+ const normalizeTableSectData = (rows) => !rows.length
32
+ ? undefined
33
+ : rows.map((row) => {
34
+ const cells = 'cells' in row ? row.cells : row;
35
+ return {
36
+ cells: cells.map((data) => (typeof data === 'string' ? { value: data } : data)),
37
+ key: 'key' in row ? row.key : undefined,
38
+ };
39
+ });
40
+ export const Table = memo((props) => {
41
+ const { caption, cols, className, rowProps, wrapperProps } = props;
42
+ const getRowProps = typeof rowProps === 'function' ? rowProps : () => rowProps;
43
+ const thead = useMemo(() => normalizeTableSectData(props.thead), [props.thead]);
44
+ const tfoot = useMemo(() => props.tfoot && normalizeTableSectData(props.tfoot), [props.tfoot]);
45
+ const tbodies = useMemo(() => (props.tbodies || [props.tbody]).map(normalizeTableSectData).filter(notNully), [props.tbody, props.tbodies]);
46
+ return (React.createElement("table", Object.assign({}, wrapperProps, { className: classes(className, wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.className) }),
47
+ caption && React.createElement("caption", null, caption),
48
+ thead && (React.createElement(TableSection, { section: thead, cols: cols, Tag: "thead", getRowProps: getRowProps })),
49
+ tfoot && (React.createElement(TableSection, { section: tfoot, cols: cols, Tag: "tfoot", getRowProps: getRowProps })),
50
+ tbodies.map((section, i) => (React.createElement(TableSection, { key: i, section: section, cols: cols, Tag: "tbody", getRowProps: getRowProps })))));
51
+ });
@@ -1,7 +1,7 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { modifiedClass } from '@hugsmidjan/qj/classUtils';
3
- import { useDomid } from '@hugsmidjan/react/hooks';
4
3
  import { useMixedControlState } from '../utils.js';
4
+ import { useDomid } from '../utils/useDomid.js';
5
5
  export const TogglerGroup = (props) => {
6
6
  const {
7
7
  // id,
@@ -1,7 +1,7 @@
1
1
  import { __rest } from "tslib";
2
2
  import React from 'react';
3
3
  import { modifiedClass } from '@hugsmidjan/qj/classUtils';
4
- import { useDomid } from '@hugsmidjan/react/hooks';
4
+ import { useDomid } from '../utils/useDomid.js';
5
5
  export const TogglerInput = (props) => {
6
6
  const { bem, modifier, className, label, invalid, errorMessage, Wrapper = 'div', required, reqText, type, id, innerWrap, wrapperProps, inputProps } = props, restInputProps = __rest(props, ["bem", "modifier", "className", "label", "invalid", "errorMessage", "Wrapper", "required", "reqText", "type", "id", "innerWrap", "wrapperProps", "inputProps"]);
7
7
  const domid = useDomid(id);
@@ -4,3 +4,6 @@ export declare const registerLocale: typeof reactDropzonePkg.registerLocale;
4
4
  export declare const setDefaultLocale: typeof reactDropzonePkg.setDefaultLocale;
5
5
  export declare const getDefaultLocale: typeof reactDropzonePkg.getDefaultLocale;
6
6
  export declare const CalendarContainer: typeof reactDropzonePkg.CalendarContainer;
7
+ export type CalendarContainerProps = reactDropzonePkg.CalendarContainerProps;
8
+ export type ReactDatePickerCustomHeaderProps = reactDropzonePkg.ReactDatePickerCustomHeaderProps;
9
+ export type ReactDatePickerProps = reactDropzonePkg.ReactDatePickerProps;
package/esm/index.d.ts CHANGED
@@ -89,6 +89,7 @@
89
89
  /// <reference path="./Bling.d.tsx" />
90
90
  /// <reference path="./BgBox.d.tsx" />
91
91
  /// <reference path="./BasicTable.d.tsx" />
92
+ /// <reference path="./AutosuggestSearch.d.tsx" />
92
93
  /// <reference path="./Attention.d.tsx" />
93
94
  /// <reference path="./ArticleMeta.d.tsx" />
94
95
  /// <reference path="./ArticleCarousel.d.tsx" />
@@ -1 +1,119 @@
1
- export { useIsBrowserSide, useIsServerSide } from '@hugsmidjan/react/hooks';
1
+ /**
2
+ * Indicates whether server-side rendering is supported or not.
3
+ *
4
+ * The `ssr-only` value is useful for cases where you need
5
+ * to demo the server-rendered version in a browser.
6
+ */
7
+ export type SSRSupport = boolean | 'ssr-only';
8
+ export type SSRSupportProps = {
9
+ /**
10
+ * Indicates whether server-side rendering is supported or not.
11
+ *
12
+ * The `ssr-only` value is useful for cases where you need
13
+ * to demo the server-rendered version in a browser.
14
+ */
15
+ ssr?: SSRSupport;
16
+ };
17
+ /**
18
+ * Returns `true` if `useEffect` has not executed yet.
19
+ *
20
+ * This signals that we're in "server-side rendering" mode
21
+ * and it's not yet appropriate to do JS-driven UI enhancements.
22
+ *
23
+ * ```js
24
+ * const Knob = (props) => {
25
+ * const [visible, setVisible] = useState(false);
26
+ * const isServer = useIsServerSide();
27
+ * const handleClick = () => {
28
+ * setVisible(!visible);
29
+ * props.onClick && props.onClick(!visible);
30
+ * };
31
+ *
32
+ * if (isServer) {
33
+ * return <span className="Knob">{props.label}</span>
34
+ * }
35
+ * return (
36
+ * <button className="Knob" aria-pressed={visible} onClick={handleClick}>
37
+ * {props.label}
38
+ * </button>
39
+ * );
40
+ * }
41
+ * ```
42
+ *
43
+ * SSR support mode can optionally be set to:
44
+ *
45
+ * - `true` (the default) enables the serve-side phase (returns `true` then `undefined`).
46
+ * - `false` disables (skips) the serve-side phase (always returns `undefined`).
47
+ * - `"ssr-only"` disables (skips) the browser-side phase (always returns `true`).
48
+ *
49
+ * NOTE: The `ssrSupport` parameter is ignored after the initial render.
50
+ */
51
+ export declare const useIsServerSide: (ssrSupport?: SSRSupport) => true | undefined;
52
+ /**
53
+ * Returns `true` when `useEffect` has executed.
54
+ *
55
+ * This signals the time to apply Progressive Enhancement.
56
+ *
57
+ * ```js
58
+ * const Knob = (props) => {
59
+ * const [visible, setVisible] = useState(false);
60
+ * const isBrowser = useIsBrowserSide();
61
+ * const handleClick = () => {
62
+ * setVisible(!visible);
63
+ * props.onClick && props.onClick(!visible);
64
+ * };
65
+ *
66
+ * if (isBrowser) {
67
+ * return (
68
+ * <button className="Knob" aria-pressed={visible} onClick={handleClick}>
69
+ * {props.label}
70
+ * </button>
71
+ * );
72
+ * }
73
+ * return <span className="Knob">{props.label}</span>
74
+ * }
75
+ * ```
76
+ *
77
+ * SSR support mode can optionally be set to:
78
+ *
79
+ * - `true` (the default) enables the serve-side phase (returns `true` then `undefined`).
80
+ * - `false` disables (skips) the serve-side phase (always returns `true`).
81
+ * - `"ssr-only"` disables (skips) the browser-side phase (always returns `undefined`).
82
+ *
83
+ * NOTE: The `ssrSupport` parameter is ignored after the initial render.
84
+ */
85
+ export declare const useIsBrowserSide: (ssrSupport?: SSRSupport) => true | undefined;
86
+ /**
87
+ * Allows you to set a the default SSRSupport value for the `useIsBRowserSide`
88
+ * and `useIsServerSide` hooks.
89
+ *
90
+ * Example use:
91
+ *
92
+ * ```js
93
+ * setDefaultSSR(false);
94
+ * ```
95
+ *
96
+ * The values are pushed to a simple stack, and if you want to revert
97
+ * a temporarily set value, use the `setDefaultSSR.pop()` method
98
+ * to go back to the previous value. Example:
99
+ *
100
+ * ```js
101
+ * setDefaultSSR('ssr-only');
102
+ * // ...render some components...
103
+ * setDefaultSSR.pop(); // go back to the previous state
104
+ * ```
105
+ *
106
+ * You explicitly switch to using the library's default by passing `undefined`
107
+ * as an argument — like so:
108
+ *
109
+ * ```js
110
+ * setDefaultSSR(undefined);
111
+ * ```
112
+ */
113
+ export declare const setDefaultSSR: {
114
+ (ssrSupport: SSRSupport | undefined): void;
115
+ /**
116
+ * Unsets the last pushed defaultSSR value
117
+ */
118
+ pop(): void;
119
+ };