@rescui/select 0.14.4-RUI-286-Fix-tooltip-stacking-f4145b01.1 → 0.15.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.
@@ -1,15 +1,15 @@
1
1
  var styles = {
2
- "sizeS": "_sizeS_z3nhpr_3",
3
- "sizeM": "_sizeM_z3nhpr_6",
4
- "sizeL": "_sizeL_z3nhpr_9",
5
- "menu": "_menu_z3nhpr_13",
6
- "menuSizeS": "_menuSizeS_z3nhpr_26",
7
- "menuSizeM": "_menuSizeM_z3nhpr_30",
8
- "menuSizeL": "_menuSizeL_z3nhpr_34",
9
- "withGroupsLabel": "_withGroupsLabel_z3nhpr_40",
10
- "lastOption": "_lastOption_z3nhpr_39",
11
- "divider": "_divider_z3nhpr_45",
12
- "checkIcon": "_checkIcon_z3nhpr_51",
13
- "observable": "_observable_z3nhpr_56"
2
+ "sizeS": "_sizeS_18ip9hg_3",
3
+ "sizeM": "_sizeM_18ip9hg_6",
4
+ "sizeL": "_sizeL_18ip9hg_9",
5
+ "menu": "_menu_18ip9hg_13",
6
+ "menuSizeS": "_menuSizeS_18ip9hg_26",
7
+ "menuSizeM": "_menuSizeM_18ip9hg_30",
8
+ "menuSizeL": "_menuSizeL_18ip9hg_34",
9
+ "withGroupsLabel": "_withGroupsLabel_18ip9hg_40",
10
+ "lastOption": "_lastOption_18ip9hg_39",
11
+ "divider": "_divider_18ip9hg_45",
12
+ "checkIcon": "_checkIcon_18ip9hg_51",
13
+ "observable": "_observable_18ip9hg_56"
14
14
  };
15
15
  export { styles as default };
@@ -5,12 +5,30 @@ export declare type FormTriggerWrapperProps = {
5
5
  size?: SelectSize;
6
6
  theme?: Theme;
7
7
  className?: string;
8
+ id?: string;
9
+ disabled?: boolean;
10
+ errorId?: string;
8
11
  error?: boolean | React.ReactNode;
12
+ reserveErrorLine?: boolean;
9
13
  label?: React.ReactNode;
10
14
  note?: React.ReactNode;
11
15
  onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
12
16
  boldLabel?: boolean;
13
17
  children?: React.ReactNode;
14
- };
15
- declare const FormTriggerWrapper: React.ForwardRefExoticComponent<FormTriggerWrapperProps & React.RefAttributes<HTMLDivElement>>;
18
+ } & React.HTMLAttributes<HTMLDivElement>;
19
+ declare const FormTriggerWrapper: React.ForwardRefExoticComponent<{
20
+ size?: SelectSize;
21
+ theme?: Theme;
22
+ className?: string;
23
+ id?: string;
24
+ disabled?: boolean;
25
+ errorId?: string;
26
+ error?: boolean | React.ReactNode;
27
+ reserveErrorLine?: boolean;
28
+ label?: React.ReactNode;
29
+ note?: React.ReactNode;
30
+ onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
31
+ boldLabel?: boolean;
32
+ children?: React.ReactNode;
33
+ } & React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
16
34
  export default FormTriggerWrapper;
@@ -2,7 +2,7 @@
2
2
  import React from 'react';
3
3
  import cn from 'classnames';
4
4
  import { useThemeWithUndefined } from '@rescui/ui-contexts';
5
- import WarningIcon from '../_virtual/warning.js';
5
+ import { shouldRenderErrorMessage, ErrorMessage } from '@rescui/form-field';
6
6
  import styles from './form-trigger.p.module.css.js';
7
7
  const SIZE_STYLES = {
8
8
  l: styles.sizeL,
@@ -30,39 +30,47 @@ const Label = _ref => {
30
30
  }
31
31
  };
32
32
 
33
- const FormTriggerWrapper = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
33
+ const FormTriggerWrapper = /*#__PURE__*/React.forwardRef( // eslint-disable-next-line complexity
34
+ (_ref2, ref) => {
34
35
  let {
35
36
  size,
36
37
  theme: themeFromProps,
37
38
  className,
39
+ id,
40
+ disabled,
38
41
  error,
42
+ errorId,
43
+ reserveErrorLine = false,
39
44
  label,
40
45
  note,
41
46
  children,
42
47
  onKeyDown,
43
- boldLabel
48
+ boldLabel,
49
+ ...restProps
44
50
  } = _ref2;
45
51
  const theme = useThemeWithUndefined(themeFromProps);
52
+ const hasFooter = Boolean(note) || shouldRenderErrorMessage(error, reserveErrorLine);
46
53
  return /*#__PURE__*/React.createElement("div", {
47
- className: cn(className, styles.main, SIZE_STYLES[size], THEME_STYLES[theme]),
54
+ className: cn(className, styles.main, SIZE_STYLES[size], THEME_STYLES[theme], Boolean(error) && styles.error, disabled && styles.disabled),
55
+ id: id,
48
56
  ref: ref,
49
57
  "data-test": "select-wrapper",
50
- "data-rs-internal": 'select-form-trigger-wrapper'
58
+ "data-rs-internal": 'select-form-trigger-wrapper',
59
+ ...restProps
51
60
  }, /*#__PURE__*/React.createElement(Label, {
52
61
  boldLabel: boldLabel
53
62
  }, label), /*#__PURE__*/React.createElement("div", {
54
63
  onKeyDown: onKeyDown
55
- }, children), error && /*#__PURE__*/React.createElement("div", {
64
+ }, children), hasFooter && /*#__PURE__*/React.createElement("div", {
65
+ className: styles.footer
66
+ }, /*#__PURE__*/React.createElement(ErrorMessage, {
67
+ id: errorId,
56
68
  className: styles.errorMessage,
57
- "data-rs-internal": 'select-form-trigger-wrapper__error-message'
58
- }, /*#__PURE__*/React.createElement(WarningIcon, {
59
- className: styles.errorIcon,
60
- "data-rs-internal": 'select-form-trigger-wrapper__error-icon',
61
- "data-render-all-sizes": true
62
- }), /*#__PURE__*/React.createElement("span", null, error)), note && /*#__PURE__*/React.createElement("div", {
69
+ reserveLine: reserveErrorLine
70
+ }, error), note && /*#__PURE__*/React.createElement("div", {
63
71
  className: styles.note,
64
72
  "data-rs-internal": 'select-form-trigger-wrapper__note'
65
- }, note));
73
+ }, note)));
66
74
  });
67
75
  FormTriggerWrapper.displayName = 'FormTriggerWrapper';
68
76
  export { FormTriggerWrapper as default };
@@ -1,13 +1,15 @@
1
1
  var styles = {
2
- "themeLight": "_themeLight_qkx1ai_7",
3
- "themeDark": "_themeDark_qkx1ai_10",
4
- "sizeS": "_sizeS_qkx1ai_14",
5
- "sizeM": "_sizeM_qkx1ai_17",
6
- "sizeL": "_sizeL_qkx1ai_20",
7
- "main": "_main_qkx1ai_24",
8
- "label": "_label_qkx1ai_28",
9
- "errorMessage": "_errorMessage_qkx1ai_34",
10
- "errorIcon": "_errorIcon_qkx1ai_45",
11
- "note": "_note_qkx1ai_50"
2
+ "themeLight": "_themeLight_14qtra6_6",
3
+ "themeDark": "_themeDark_14qtra6_9",
4
+ "sizeS": "_sizeS_14qtra6_13",
5
+ "sizeM": "_sizeM_14qtra6_16",
6
+ "sizeL": "_sizeL_14qtra6_19",
7
+ "main": "_main_14qtra6_23",
8
+ "label": "_label_14qtra6_27",
9
+ "disabled": "_disabled_14qtra6_33",
10
+ "footer": "_footer_14qtra6_38",
11
+ "errorMessage": "_errorMessage_14qtra6_45",
12
+ "error": "_error_14qtra6_45",
13
+ "note": "_note_14qtra6_54"
12
14
  };
13
15
  export { styles as default };
@@ -6,6 +6,7 @@ export interface MultiselectProps {
6
6
  * Additional class name
7
7
  */
8
8
  className?: string;
9
+ id?: string;
9
10
  /**
10
11
  * Array of options
11
12
  */
@@ -54,6 +55,11 @@ export interface MultiselectProps {
54
55
  * Error state flag or React.ReactNode (use with forms)
55
56
  */
56
57
  error?: boolean | React.ReactNode;
58
+ /**
59
+ * If `true`, there will be reserved a space for a 1-line error message. Subsequent lines will be placed below normally.
60
+ * If `false`, there will be no reservation.
61
+ */
62
+ reserveErrorLine?: boolean;
57
63
  /**
58
64
  * Label element upper then Multiselect element (use with forms)
59
65
  */
@@ -66,7 +72,6 @@ export interface MultiselectProps {
66
72
  * Note element below then Multiselect element (use with forms)
67
73
  */
68
74
  note?: React.ReactNode;
69
- id?: string;
70
75
  /**
71
76
  * Text to display when there are no options
72
77
  */
@@ -6,6 +6,7 @@ import cn from 'classnames';
6
6
  import scrollIntoView from 'scroll-into-view-if-needed';
7
7
  import { Dropdown } from '@rescui/dropdown';
8
8
  import { Menu, MenuItem, Divider, GroupHeader } from '@rescui/menu';
9
+ import { ErrorMessage } from '@rescui/form-field';
9
10
  import { useThemeWithUndefined } from '@rescui/ui-contexts';
10
11
  import CheckOutlineIcon from '../_virtual/check-outline.js';
11
12
  import { useStrongMemo, getDefaultCursorIndex, isGroupsEmpty, getOptionValue, getMovedCursorIndex, shouldOpenSelect, isIndexMatchCursor, withoutGroupsLabel, getPlainOptionsFromGroups, getEmptyMessage, OptionGroupTypes, convertToOptionGroupsIfNeeded, calculateMaxHeight } from '../utils.js';
@@ -14,6 +15,7 @@ import { ARROW_DOWN, ARROW_UP, ENTER, SPACE, TAB, ESCAPE, BACKSPACE } from '../k
14
15
  import SelectTrigger from './trigger.js';
15
16
  import FormTriggerWrapper from './form-trigger-wrapper.js';
16
17
  import { useObservableForceRerender } from './use-observable-force-rerender.js';
18
+ import { useBackwardCompatibleId } from './use-backward-compatible-id.js';
17
19
  import styles from './common-select.p.module.css.js'; // eslint-disable-next-line complexity
18
20
 
19
21
  const Option = _ref => {
@@ -149,6 +151,7 @@ const Multiselect = _ref4 => {
149
151
  mode = 'classic',
150
152
  theme: themeFromProps,
151
153
  className = null,
154
+ id,
152
155
  value = undefined,
153
156
  onChange,
154
157
  placeholder,
@@ -157,8 +160,10 @@ const Multiselect = _ref4 => {
157
160
  isLoading = false,
158
161
  isDisabled = false,
159
162
  noOptionsMessage,
163
+ error,
164
+ reserveErrorLine = false,
160
165
  placement = 'bottom',
161
- boldLabel,
166
+ boldLabel = true,
162
167
  ...restProps
163
168
  } = _ref4;
164
169
  const [triggerFormWrapperRef, setTriggerFormWrapperRef] = useState(null);
@@ -341,6 +346,8 @@ const Multiselect = _ref4 => {
341
346
  const actualSize = sizeFromCss || size;
342
347
  const maxHeight = calculateMaxHeight(actualSize);
343
348
  const withGroupsLabel = !withoutGroupsLabel(filteredGroups);
349
+ const uniqueId = `multiselect-${useBackwardCompatibleId()}`;
350
+ const errorId = `${id ? id : uniqueId}-error`;
344
351
  return /*#__PURE__*/React.createElement(Dropdown, {
345
352
  theme: theme,
346
353
  onRequestClose: handleClose,
@@ -360,13 +367,21 @@ const Multiselect = _ref4 => {
360
367
  return /*#__PURE__*/React.createElement(FormTriggerWrapper, {
361
368
  ref: setTriggerFormWrapperRef,
362
369
  className: cn(className, SIZE_STYLES[size]),
370
+ id: id,
371
+ errorId: errorId,
363
372
  theme: theme,
364
373
  size: size,
365
- error: restProps.error,
374
+ disabled: isDisabled,
375
+ error: error,
376
+ reserveErrorLine: reserveErrorLine,
366
377
  label: restProps.label,
367
378
  note: restProps.note,
368
379
  onKeyDown: handleTriggerKeyDown,
369
- boldLabel: boldLabel
380
+ boldLabel: boldLabel,
381
+ role: "listbox",
382
+ "aria-errormessage": error ? errorId : undefined,
383
+ "aria-invalid": Boolean(error),
384
+ "aria-multiselectable": true
370
385
  }, /*#__PURE__*/React.createElement("div", {
371
386
  ref: observableRef,
372
387
  className: styles.observable
@@ -388,8 +403,7 @@ const Multiselect = _ref4 => {
388
403
  onClick: handleClick,
389
404
  onClearClick: handleClearClick,
390
405
  onItemClearClick: handleUnselectClick,
391
- error: Boolean(restProps.error),
392
- id: restProps.id,
406
+ error: Boolean(error),
393
407
  "data-target": "trigger"
394
408
  }));
395
409
  },
@@ -429,7 +443,7 @@ Multiselect.propTypes = {
429
443
  isClearable: PropTypes.bool,
430
444
  isDisabled: PropTypes.bool,
431
445
  isLoading: PropTypes.bool,
432
- error: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
446
+ error: ErrorMessage.propTypes.children,
433
447
  label: PropTypes.node,
434
448
  note: PropTypes.node,
435
449
  id: PropTypes.string,
@@ -12,6 +12,7 @@ export declare type NativeSelectProps = {
12
12
  size?: SelectSize;
13
13
  theme?: Theme;
14
14
  className?: string;
15
+ id?: string;
15
16
  style?: object;
16
17
  value: NativeSelectOption;
17
18
  onChange?: (newValue: NativeSelectOption) => void;
@@ -22,6 +23,11 @@ export declare type NativeSelectProps = {
22
23
  label?: React.ReactNode;
23
24
  note?: React.ReactNode;
24
25
  error?: boolean | React.ReactNode;
26
+ /**
27
+ * If `true`, there will be reserved a space for a 1-line error message. Subsequent lines will be placed below normally.
28
+ * If `false`, there will be no reservation.
29
+ */
30
+ reserveErrorLine?: boolean;
25
31
  noOptionsMessage?: NoOptionsMessage;
26
32
  name?: string;
27
33
  boldLabel?: boolean;
@@ -3,9 +3,11 @@ import React, { useState } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import cn from 'classnames';
5
5
  import { useThemeWithUndefined } from '@rescui/ui-contexts';
6
+ import { ErrorMessage } from '@rescui/form-field';
6
7
  import { nativeOptionType, nativeOptionsGroupType, noOptionsMessageType } from '../common-prop-types.js';
7
8
  import SelectTrigger from './trigger.js';
8
9
  import FormTriggerWrapper from './form-trigger-wrapper.js';
10
+ import { useBackwardCompatibleId } from './use-backward-compatible-id.js';
9
11
  import styles from './native-select.p.module.css.js';
10
12
  const DEFAULT_NO_OPTIONS_MESSAGES = {
11
13
  noOptions: 'No options',
@@ -138,6 +140,7 @@ const NativeSelect = _ref6 => {
138
140
  size = 'm',
139
141
  theme: themeFromProps,
140
142
  className = null,
143
+ id,
141
144
  style,
142
145
  value = undefined,
143
146
  onChange,
@@ -148,9 +151,10 @@ const NativeSelect = _ref6 => {
148
151
  label,
149
152
  note,
150
153
  error,
154
+ reserveErrorLine = false,
151
155
  noOptionsMessage,
152
156
  name,
153
- boldLabel
157
+ boldLabel = true
154
158
  } = _ref6;
155
159
  const theme = useThemeWithUndefined(themeFromProps);
156
160
  const [hovered, setHovered] = useState(false);
@@ -196,11 +200,17 @@ const NativeSelect = _ref6 => {
196
200
  });
197
201
  }
198
202
 
203
+ const currentId = `native-select-${useBackwardCompatibleId()}`;
204
+ const errorId = `${id ? id : currentId}-error`;
199
205
  return /*#__PURE__*/React.createElement(FormTriggerWrapper, {
200
206
  className: cn(className, styles.main, SIZE_STYLES[size]),
207
+ id: id,
201
208
  theme: theme,
202
209
  size: size,
210
+ disabled: isDisabled,
203
211
  error: error,
212
+ errorId: errorId,
213
+ reserveErrorLine: reserveErrorLine,
204
214
  label: label,
205
215
  note: note,
206
216
  onKeyDown: () => false,
@@ -218,12 +228,15 @@ const NativeSelect = _ref6 => {
218
228
  disabled: isDisabled ? true : undefined,
219
229
  onChange: handleChange,
220
230
  name: name,
221
- value: (value === null || value === void 0 ? void 0 : value.label) !== '' ? value === null || value === void 0 ? void 0 : value.value : PLACEHOLDER_VALUE
231
+ value: (value === null || value === void 0 ? void 0 : value.label) !== '' ? value === null || value === void 0 ? void 0 : value.value : PLACEHOLDER_VALUE,
232
+ "aria-errormessage": error ? errorId : undefined,
233
+ "aria-invalid": Boolean(error)
222
234
  }, optionList)));
223
235
  };
224
236
 
225
237
  NativeSelect.propTypes = {
226
238
  className: PropTypes.string,
239
+ id: PropTypes.string,
227
240
  options: PropTypes.arrayOf(PropTypes.oneOfType([nativeOptionType, nativeOptionsGroupType])),
228
241
  value: nativeOptionType,
229
242
  onChange: PropTypes.func,
@@ -233,7 +246,7 @@ NativeSelect.propTypes = {
233
246
  isDisabled: PropTypes.bool,
234
247
  isLoading: PropTypes.bool,
235
248
  trigger: PropTypes.func,
236
- error: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
249
+ error: ErrorMessage.propTypes.children,
237
250
  label: PropTypes.node,
238
251
  note: PropTypes.node,
239
252
  noOptionsMessage: noOptionsMessageType,
@@ -1,9 +1,9 @@
1
1
  var styles = {
2
- "sizeS": "_sizeS_1gl6ux4_6",
3
- "sizeM": "_sizeM_1gl6ux4_9",
4
- "sizeL": "_sizeL_1gl6ux4_12",
5
- "main": "_main_1gl6ux4_16",
6
- "wrapper": "_wrapper_1gl6ux4_20",
7
- "select": "_select_1gl6ux4_24"
2
+ "sizeS": "_sizeS_1e02zs3_6",
3
+ "sizeM": "_sizeM_1e02zs3_9",
4
+ "sizeL": "_sizeL_1e02zs3_12",
5
+ "main": "_main_1e02zs3_16",
6
+ "wrapper": "_wrapper_1e02zs3_20",
7
+ "select": "_select_1e02zs3_24"
8
8
  };
9
9
  export { styles as default };
@@ -1,31 +1,31 @@
1
1
  var styles = {
2
- "themeLight": "_themeLight_ufjs6v_27",
3
- "themeDark": "_themeDark_ufjs6v_30",
4
- "sizeS": "_sizeS_ufjs6v_34",
5
- "sizeM": "_sizeM_ufjs6v_37",
6
- "sizeL": "_sizeL_ufjs6v_40",
7
- "classic": "_classic_ufjs6v_44",
8
- "rock": "_rock_ufjs6v_47",
9
- "main": "_main_ufjs6v_51",
10
- "open": "_open_ufjs6v_80",
11
- "searchKeyFocused": "_searchKeyFocused_ufjs6v_85",
12
- "error": "_error_ufjs6v_89",
13
- "disabled": "_disabled_ufjs6v_95",
14
- "enabled": "_enabled_ufjs6v_103",
15
- "searchFocused": "_searchFocused_ufjs6v_104",
16
- "focused": "_focused_ufjs6v_105",
17
- "isMulti": "_isMulti_ufjs6v_138",
18
- "iconsWrapper": "_iconsWrapper_ufjs6v_142",
19
- "labelWrapper": "_labelWrapper_ufjs6v_157",
20
- "label": "_label_ufjs6v_157",
21
- "labelNotSelected": "_labelNotSelected_ufjs6v_197",
22
- "searchInput": "_searchInput_ufjs6v_210",
23
- "multi": "_multi_ufjs6v_240",
24
- "tagsContainer": "_tagsContainer_ufjs6v_256",
25
- "tag": "_tag_ufjs6v_256",
26
- "filledTag": "_filledTag_ufjs6v_279",
27
- "toggle": "_toggle_ufjs6v_286",
28
- "icon": "_icon_ufjs6v_142",
29
- "clearIcon": "_clearIcon_ufjs6v_353"
2
+ "themeLight": "_themeLight_106h1g8_6",
3
+ "themeDark": "_themeDark_106h1g8_9",
4
+ "sizeS": "_sizeS_106h1g8_13",
5
+ "sizeM": "_sizeM_106h1g8_16",
6
+ "sizeL": "_sizeL_106h1g8_19",
7
+ "classic": "_classic_106h1g8_23",
8
+ "rock": "_rock_106h1g8_26",
9
+ "main": "_main_106h1g8_30",
10
+ "open": "_open_106h1g8_60",
11
+ "searchKeyFocused": "_searchKeyFocused_106h1g8_65",
12
+ "error": "_error_106h1g8_69",
13
+ "disabled": "_disabled_106h1g8_75",
14
+ "enabled": "_enabled_106h1g8_83",
15
+ "searchFocused": "_searchFocused_106h1g8_84",
16
+ "focused": "_focused_106h1g8_85",
17
+ "isMulti": "_isMulti_106h1g8_118",
18
+ "iconsWrapper": "_iconsWrapper_106h1g8_122",
19
+ "labelWrapper": "_labelWrapper_106h1g8_137",
20
+ "label": "_label_106h1g8_137",
21
+ "labelNotSelected": "_labelNotSelected_106h1g8_177",
22
+ "searchInput": "_searchInput_106h1g8_190",
23
+ "multi": "_multi_106h1g8_220",
24
+ "tagsContainer": "_tagsContainer_106h1g8_236",
25
+ "tag": "_tag_106h1g8_236",
26
+ "filledTag": "_filledTag_106h1g8_259",
27
+ "toggle": "_toggle_106h1g8_266",
28
+ "icon": "_icon_106h1g8_122",
29
+ "clearIcon": "_clearIcon_106h1g8_333"
30
30
  };
31
31
  export { styles as default };
@@ -0,0 +1,4 @@
1
+ export declare const useBackwardCompatibleId: {
2
+ (): string | number;
3
+ counter: number;
4
+ };
@@ -0,0 +1,14 @@
1
+ import React, { useRef } from 'react';
2
+
3
+ const useBackwardCompatibleId = () => {
4
+ const id = useRef(null);
5
+
6
+ if (id.current === null) {
7
+ id.current = useBackwardCompatibleId.counter++;
8
+ }
9
+
10
+ return (React.useId ? React.useId : () => id.current)();
11
+ };
12
+
13
+ useBackwardCompatibleId.counter = 0;
14
+ export { useBackwardCompatibleId };