@koobiq/react-components 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/components/Alert/Alert.js +5 -3
  2. package/dist/components/Alert/types.d.ts +0 -3
  3. package/dist/components/Backdrop/Backdrop.js +1 -1
  4. package/dist/components/Backdrop/types.d.ts +4 -1
  5. package/dist/components/Button/Button.js +7 -7
  6. package/dist/components/Button/types.d.ts +0 -4
  7. package/dist/components/ButtonToggleGroup/ButtonToggleGroup.js +6 -6
  8. package/dist/components/ButtonToggleGroup/components/ButtonToggle/ButtonToggle.js +6 -6
  9. package/dist/components/ButtonToggleGroup/components/ButtonToggle/types.d.ts +0 -1
  10. package/dist/components/ButtonToggleGroup/types.d.ts +0 -3
  11. package/dist/components/Checkbox/Checkbox.js +6 -6
  12. package/dist/components/Checkbox/types.d.ts +0 -5
  13. package/dist/components/Container/Container.js +2 -2
  14. package/dist/components/Container/types.d.ts +0 -2
  15. package/dist/components/DateInput/DateInput.js +15 -11
  16. package/dist/components/DateInput/types.d.ts +1 -3
  17. package/dist/components/DatePicker/types.d.ts +1 -2
  18. package/dist/components/Dialog/Dialog.js +1 -1
  19. package/dist/components/Dialog/types.d.ts +0 -1
  20. package/dist/components/Divider/Divider.js +5 -4
  21. package/dist/components/Divider/types.d.ts +0 -2
  22. package/dist/components/FieldComponents/FieldAddon/FieldAddon.js +4 -4
  23. package/dist/components/FieldComponents/FieldContentGroup/FieldContentGroup.js +2 -2
  24. package/dist/components/FieldComponents/FieldError/FieldError.d.ts +4 -2
  25. package/dist/components/FieldComponents/FieldError/FieldError.js +6 -8
  26. package/dist/components/FieldComponents/FieldInput/FieldInput.js +3 -3
  27. package/dist/components/FieldComponents/FieldInputDate/FieldInputDate.js +2 -2
  28. package/dist/components/FieldComponents/FieldSelect/FieldSelect.js +4 -4
  29. package/dist/components/FormControl/FormControl.js +2 -2
  30. package/dist/components/FormControlLabel/FormControlLabel.js +1 -8
  31. package/dist/components/IconButton/IconButton.js +4 -4
  32. package/dist/components/IconButton/types.d.ts +0 -3
  33. package/dist/components/Input/Input.d.ts +2 -3
  34. package/dist/components/Input/Input.js +11 -7
  35. package/dist/components/Input/Input.module.css.js +4 -0
  36. package/dist/components/Input/types.d.ts +1 -10
  37. package/dist/components/InputNumber/InputNumber.d.ts +2 -3
  38. package/dist/components/InputNumber/InputNumber.js +7 -7
  39. package/dist/components/InputNumber/types.d.ts +0 -9
  40. package/dist/components/Link/Link.js +3 -3
  41. package/dist/components/Link/types.d.ts +0 -5
  42. package/dist/components/List/List.js +4 -3
  43. package/dist/components/List/List.module.css.js +1 -4
  44. package/dist/components/List/components/ListOption/ListOption.js +5 -5
  45. package/dist/components/List/components/ListSection/ListSection.js +4 -3
  46. package/dist/components/List/types.d.ts +2 -0
  47. package/dist/components/Menu/Menu.js +2 -2
  48. package/dist/components/Menu/components/MenuList/MenuList.d.ts +6 -0
  49. package/dist/components/Menu/components/{MenuInner/MenuInner.js → MenuList/MenuList.js} +6 -5
  50. package/dist/components/Menu/components/MenuList/MenuList.module.css.js +8 -0
  51. package/dist/components/Menu/components/MenuList/index.d.ts +1 -0
  52. package/dist/components/Menu/components/MenuSection/MenuSection.js +4 -3
  53. package/dist/components/Menu/components/index.d.ts +1 -1
  54. package/dist/components/Modal/Modal.js +1 -1
  55. package/dist/components/Modal/types.d.ts +1 -5
  56. package/dist/components/Popover/PopoverInner.js +2 -2
  57. package/dist/components/Popover/types.d.ts +0 -4
  58. package/dist/components/RadioGroup/RadioGroup.js +8 -11
  59. package/dist/components/RadioGroup/components/Radio/types.d.ts +0 -1
  60. package/dist/components/RadioGroup/types.d.ts +1 -8
  61. package/dist/components/SearchInput/SearchInput.d.ts +2 -3
  62. package/dist/components/SearchInput/SearchInput.js +13 -12
  63. package/dist/components/SearchInput/types.d.ts +1 -5
  64. package/dist/components/Select/Select.js +18 -20
  65. package/dist/components/Select/components/SelectList/SelectList.d.ts +4 -2
  66. package/dist/components/Select/components/SelectList/SelectList.js +35 -7
  67. package/dist/components/Select/components/SelectList/SelectList.module.css.js +3 -3
  68. package/dist/components/Select/components/SelectOption/SelectOption.js +5 -5
  69. package/dist/components/Select/intl.js +2 -0
  70. package/dist/components/Select/types.d.ts +8 -8
  71. package/dist/components/SidePanel/SidePanel.js +1 -1
  72. package/dist/components/SidePanel/types.d.ts +0 -5
  73. package/dist/components/Table/Table.js +4 -4
  74. package/dist/components/Table/components/TableRow/TableRow.js +5 -5
  75. package/dist/components/Table/types.d.ts +0 -2
  76. package/dist/components/TagGroup/components/Tag/Tag.js +6 -6
  77. package/dist/components/Textarea/Textarea.d.ts +1 -2
  78. package/dist/components/Textarea/Textarea.js +6 -6
  79. package/dist/components/Textarea/components/TextareaContextConsumer/TextareaContextConsumer.js +1 -1
  80. package/dist/components/Textarea/types.d.ts +1 -10
  81. package/dist/components/TimePicker/TimePicker.d.ts +1 -1
  82. package/dist/components/TimePicker/TimePicker.js +15 -11
  83. package/dist/components/TimePicker/types.d.ts +0 -2
  84. package/dist/components/Toggle/Toggle.js +3 -3
  85. package/dist/components/Toggle/types.d.ts +0 -3
  86. package/dist/components/Tooltip/Tooltip.js +9 -9
  87. package/dist/components/Tooltip/types.d.ts +0 -3
  88. package/dist/style.css +52 -50
  89. package/dist/styles/utility.d.ts +1 -0
  90. package/dist/styles/utility.js +2 -1
  91. package/dist/styles/utility.module.css.js +2 -1
  92. package/dist/utils/index.d.ts +1 -0
  93. package/package.json +5 -5
  94. package/dist/components/List/components/ListSection/ListSection.module.css.js +0 -11
  95. package/dist/components/Menu/components/MenuInner/MenuInner.d.ts +0 -6
  96. package/dist/components/Menu/components/MenuInner/MenuInner.module.css.js +0 -11
  97. package/dist/components/Menu/components/MenuInner/index.d.ts +0 -1
  98. package/dist/components/Menu/components/MenuSection/MenuSection.module.css.js +0 -11
  99. /package/dist/{components/FieldComponents/FieldSelect/utils.d.ts → utils/isPrimitiveNode.d.ts} +0 -0
  100. /package/dist/{components/FieldComponents/FieldSelect/utils.js → utils/isPrimitiveNode.js} +0 -0
@@ -15,7 +15,7 @@ import { FieldError } from "../FieldComponents/FieldError/FieldError.js";
15
15
  const RadioGroup = forwardRef(
16
16
  (props, ref) => {
17
17
  const {
18
- size,
18
+ size = "normal",
19
19
  label,
20
20
  children,
21
21
  slotProps,
@@ -39,10 +39,10 @@ const RadioGroup = forwardRef(
39
39
  required
40
40
  } = props;
41
41
  const caption = captionProp ?? description;
42
- const isDisabled = isDisabledProp ?? disabled ?? false;
43
- const isInvalid = isInvalidProp ?? error ?? false;
44
- const isReadOnly = isReadOnlyProp ?? readonly ?? false;
45
- const isRequired = isRequiredProp ?? required ?? false;
42
+ const isDisabled = isDisabledProp ?? disabled;
43
+ const isInvalid = isInvalidProp ?? error;
44
+ const isReadOnly = isReadOnlyProp ?? readonly;
45
+ const isRequired = isRequiredProp ?? required;
46
46
  if (process.env.NODE_ENV !== "production" && "description" in props) {
47
47
  deprecate(
48
48
  'RadioGroup: the "description" prop is deprecated. Use "caption" prop to replace it.'
@@ -82,10 +82,7 @@ const RadioGroup = forwardRef(
82
82
  ref,
83
83
  "data-size": size,
84
84
  "data-testid": testId,
85
- "data-invalid": isInvalid,
86
- "data-disabled": isDisabled,
87
- "data-required": isRequired,
88
- "data-readonly": isReadOnly
85
+ "data-orientation": orientation
89
86
  },
90
87
  slotProps?.root
91
88
  );
@@ -99,7 +96,7 @@ const RadioGroup = forwardRef(
99
96
  },
100
97
  slotProps?.radioGroup
101
98
  );
102
- return /* @__PURE__ */ jsx(RadioGroupContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx(FormControl, { as: RadioGroup$1, ...rootProps, children: ({ isInvalid: isInvalid2, isRequired: isRequired2 }) => {
99
+ return /* @__PURE__ */ jsx(RadioGroupContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx(FormControl, { as: RadioGroup$1, ...rootProps, children: ({ isRequired: isRequired2 }) => {
103
100
  const labelProps = mergeProps(
104
101
  {
105
102
  as: "span",
@@ -110,7 +107,7 @@ const RadioGroup = forwardRef(
110
107
  },
111
108
  slotProps?.label
112
109
  );
113
- const errorProps = mergeProps({ isInvalid: isInvalid2, children: errorMessage }, slotProps?.errorMessage);
110
+ const errorProps = mergeProps({ children: errorMessage }, slotProps?.errorMessage);
114
111
  const captionProps = mergeProps({ children: caption }, slotProps?.caption);
115
112
  return /* @__PURE__ */ jsxs(Fragment, { children: [
116
113
  /* @__PURE__ */ jsx(FormControlLabel, { ...labelProps }),
@@ -8,7 +8,6 @@ export type RadioPropLabelPlacement = (typeof radioPropLabelPlacement)[number];
8
8
  type RadioDeprecatedProps = {
9
9
  /**
10
10
  * If `true`, the component is disabled.
11
- * @default false
12
11
  * @deprecated
13
12
  * The "disabled" prop is deprecated. Use "isDisabled" prop to replace it.
14
13
  */
@@ -15,28 +15,24 @@ export type RadioGroupPropLabelAlign = FormControlPropLabelAlign;
15
15
  type RadioGroupDeprecatedProps = {
16
16
  /**
17
17
  * If `true`, the component is disabled.
18
- * @default false
19
18
  * @deprecated
20
19
  * The "disabled" prop is deprecated. Use "isDisabled" prop to replace it.
21
20
  */
22
21
  disabled?: boolean;
23
22
  /**
24
23
  * If `true`, the component will indicate an error.
25
- * @default false
26
24
  * @deprecated
27
25
  * The "error" prop is deprecated. Use "isInvalid" prop to replace it.
28
26
  */
29
27
  error?: boolean;
30
28
  /**
31
29
  * It prevents the user from changing the value of the checkbox.
32
- * @default false
33
30
  * @deprecated
34
31
  * The "readonly" prop is deprecated. Use "isReadonly" prop to replace it.
35
32
  */
36
33
  readonly?: boolean;
37
34
  /**
38
35
  * If `true`, the input element is required.
39
- * @default false
40
36
  * @deprecated
41
37
  * The "required" prop is deprecated. Use "isRequired" prop to replace it.
42
38
  */
@@ -71,11 +67,8 @@ export type RadioGroupBaseProps = ExtendableProps<{
71
67
  orientation?: RadioGroupPropOrientation;
72
68
  /**
73
69
  * If `true`, the label is hidden. Be sure to add aria-label to the input element.
74
- * @default false
75
70
  */
76
71
  isLabelHidden?: boolean;
77
- /** An error message for the field. */
78
- errorMessage?: ReactNode;
79
72
  /**
80
73
  * The label's overall position relative to the element it is labeling.
81
74
  * @default 'top'
@@ -94,6 +87,6 @@ export type RadioGroupBaseProps = ExtendableProps<{
94
87
  label?: FormControlLabelProps<'span'>;
95
88
  radioGroup?: ComponentPropsWithRef<'div'>;
96
89
  };
97
- } & RadioGroupDeprecatedProps, Omit<RadioGroupPrimitiveProps, 'validate' | 'validationBehavior' | 'validationState' | 'errorMessage'>>;
90
+ } & RadioGroupDeprecatedProps, Omit<RadioGroupPrimitiveProps, 'validationState'>>;
98
91
  export type RadioGroupProps = ExtendableComponentPropsWithRef<RadioGroupBaseProps, 'div'>;
99
92
  export {};
@@ -1,7 +1,7 @@
1
- import { type FieldCaptionProps, type FieldContentGroupProps, type FieldErrorProps, type FieldInputProps } from '../FieldComponents';
1
+ import { type FieldCaptionProps, type FieldContentGroupProps, type FieldInputProps, type FieldErrorProps } from '../FieldComponents';
2
2
  import { type FormControlProps } from '../FormControl';
3
3
  import { type FormControlLabelProps } from '../FormControlLabel';
4
- export declare const SearchInput: import("react").ForwardRefExoticComponent<Omit<Omit<import("@react-types/searchfield").AriaSearchFieldProps, "validationState" | "description" | "errorMessage">, "caption" | "style" | "className" | `data-${string}` | "labelPlacement" | "labelAlign" | "fullWidth" | "variant" | "slotProps" | "startAddon" | "endAddon" | "errorMessage" | "isLabelHidden"> & {
4
+ export declare const SearchInput: import("react").ForwardRefExoticComponent<Omit<Omit<import("@react-types/searchfield").AriaSearchFieldProps, "validationState" | "description">, "caption" | "style" | "className" | `data-${string}` | "labelPlacement" | "labelAlign" | "fullWidth" | "variant" | "slotProps" | "startAddon" | "endAddon" | "isLabelHidden"> & {
5
5
  className?: string;
6
6
  style?: import("react").CSSProperties;
7
7
  isLabelHidden?: boolean;
@@ -18,7 +18,6 @@ export declare const SearchInput: import("react").ForwardRefExoticComponent<Omit
18
18
  errorMessage?: FieldErrorProps;
19
19
  clearButton?: import("..").IconButtonProps;
20
20
  };
21
- errorMessage?: import("react").ReactNode;
22
21
  caption?: import("react").ReactNode;
23
22
  variant?: import("./types").SearchInputPropVariant;
24
23
  fullWidth?: boolean;
@@ -3,7 +3,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
3
  import { forwardRef } from "react";
4
4
  import { useDOMRef, mergeProps, clsx } from "@koobiq/react-core";
5
5
  import { IconMagnifyingGlass16, IconXmarkCircle16 } from "@koobiq/react-icons";
6
- import { useSearchFieldState, removeDataAttributes, useSearchField } from "@koobiq/react-primitives";
6
+ import { useSearchFieldState, removeDataAttributes, useSearchField, FieldErrorContext } from "@koobiq/react-primitives";
7
7
  import s from "./SearchInput.module.css.js";
8
8
  import { IconButton } from "../IconButton/IconButton.js";
9
9
  import { FormControl } from "../FormControl/FormControl.js";
@@ -18,20 +18,19 @@ const SearchInput = forwardRef(
18
18
  const {
19
19
  startAddon = /* @__PURE__ */ jsx(IconMagnifyingGlass16, { className: s.searchIcon }),
20
20
  variant = "filled",
21
- fullWidth = false,
22
- isLabelHidden = false,
21
+ fullWidth,
22
+ isLabelHidden,
23
23
  labelPlacement,
24
+ errorMessage,
24
25
  labelAlign,
25
26
  "data-testid": testId,
26
27
  style,
27
28
  className,
28
29
  caption,
29
- errorMessage,
30
30
  isRequired,
31
31
  isReadOnly,
32
32
  label,
33
33
  endAddon,
34
- isInvalid,
35
34
  isDisabled,
36
35
  slotProps
37
36
  } = props;
@@ -43,8 +42,10 @@ const SearchInput = forwardRef(
43
42
  inputProps: inputPropsAria,
44
43
  descriptionProps: descriptionPropsAria,
45
44
  errorMessageProps: errorMessagePropsAria,
46
- clearButtonProps: clearButtonPropsAria
45
+ clearButtonProps: clearButtonPropsAria,
46
+ ...validation
47
47
  } = useSearchField(removeDataAttributes(props), state, domRef);
48
+ const { isInvalid } = validation;
48
49
  const rootProps = mergeProps(
49
50
  {
50
51
  style,
@@ -53,10 +54,10 @@ const SearchInput = forwardRef(
53
54
  fullWidth,
54
55
  "data-testid": testId,
55
56
  "data-variant": variant,
56
- "data-invalid": isInvalid,
57
- "data-disabled": isDisabled,
58
- "data-required": isRequired,
59
- "data-readonly": isReadOnly,
57
+ "data-invalid": isInvalid || void 0,
58
+ "data-readonly": isReadOnly || void 0,
59
+ "data-disabled": isDisabled || void 0,
60
+ "data-required": isRequired || void 0,
60
61
  className: clsx(s.base, className)
61
62
  },
62
63
  slotProps?.root
@@ -105,7 +106,7 @@ const SearchInput = forwardRef(
105
106
  );
106
107
  const captionProps = mergeProps({ children: caption }, slotProps?.caption, descriptionPropsAria);
107
108
  const errorProps = mergeProps(
108
- { isInvalid, children: errorMessage },
109
+ { children: errorMessage },
109
110
  slotProps?.errorMessage,
110
111
  errorMessagePropsAria
111
112
  );
@@ -114,7 +115,7 @@ const SearchInput = forwardRef(
114
115
  /* @__PURE__ */ jsxs(Field, { children: [
115
116
  /* @__PURE__ */ jsx(FieldContentGroup, { ...groupProps, children: /* @__PURE__ */ jsx(FieldInput, { ...inputProps }) }),
116
117
  /* @__PURE__ */ jsx(FieldCaption, { ...captionProps }),
117
- /* @__PURE__ */ jsx(FieldError, { ...errorProps })
118
+ /* @__PURE__ */ jsx(FieldErrorContext.Provider, { value: validation, children: /* @__PURE__ */ jsx(FieldError, { ...errorProps }) })
118
119
  ] })
119
120
  ] });
120
121
  }
@@ -18,7 +18,6 @@ export type SearchInputProps = ExtendableProps<{
18
18
  style?: CSSProperties;
19
19
  /**
20
20
  * If `true`, the label is hidden. Be sure to add aria-label to the input element.
21
- * @default false
22
21
  */
23
22
  isLabelHidden?: boolean;
24
23
  /**
@@ -45,8 +44,6 @@ export type SearchInputProps = ExtendableProps<{
45
44
  errorMessage?: FieldErrorProps;
46
45
  clearButton?: IconButtonProps;
47
46
  };
48
- /** An error message for the field. */
49
- errorMessage?: ReactNode;
50
47
  /** The helper text content. */
51
48
  caption?: ReactNode;
52
49
  /**
@@ -56,8 +53,7 @@ export type SearchInputProps = ExtendableProps<{
56
53
  variant?: SearchInputPropVariant;
57
54
  /**
58
55
  * If `true`, the input will take up the full width of its container.
59
- * @default false
60
56
  */
61
57
  fullWidth?: boolean;
62
- } & DataAttributeProps, Omit<AriaSearchFieldProps, 'description' | 'errorMessage' | 'validationState'>>;
58
+ } & DataAttributeProps, Omit<AriaSearchFieldProps, 'description' | 'validationState'>>;
63
59
  export type SearchInputRef = ComponentRef<'input'>;
@@ -2,7 +2,7 @@ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { forwardRef, useCallback } from "react";
3
3
  import { useLocalizedStringFormatter, useDOMRef, useElementSize, mergeProps, clsx } from "@koobiq/react-core";
4
4
  import { IconXmarkCircle16, IconChevronDownS16 } from "@koobiq/react-icons";
5
- import { useMultiSelectState, removeDataAttributes, useMultiSelect } from "@koobiq/react-primitives";
5
+ import { useMultiSelectState, removeDataAttributes, useMultiSelect, FieldErrorContext } from "@koobiq/react-primitives";
6
6
  import { PopoverInner } from "../Popover/PopoverInner.js";
7
7
  import intlMessages from "./intl.js";
8
8
  import s from "./Select.module.css.js";
@@ -22,10 +22,11 @@ import { Section } from "../Collections/Section.js";
22
22
  import { Divider } from "../Collections/Divider.js";
23
23
  function SelectRender(props, ref) {
24
24
  const {
25
- fullWidth = false,
26
- isClearable = false,
25
+ fullWidth,
26
+ isClearable,
27
27
  "data-testid": testId,
28
28
  selectionMode = "single",
29
+ noItemsText,
29
30
  selectedTagsOverflow = "responsive",
30
31
  labelPlacement,
31
32
  labelAlign,
@@ -55,13 +56,13 @@ function SelectRender(props, ref) {
55
56
  onClear?.();
56
57
  }, [onClear, state]);
57
58
  const {
58
- isInvalid,
59
59
  menuProps,
60
60
  valueProps,
61
61
  triggerProps,
62
62
  labelProps: labelPropsAria,
63
63
  descriptionProps,
64
- errorMessageProps
64
+ errorMessageProps,
65
+ ...validation
65
66
  } = useMultiSelect(
66
67
  removeDataAttributes({
67
68
  ...props,
@@ -71,12 +72,13 @@ function SelectRender(props, ref) {
71
72
  state,
72
73
  domRef
73
74
  );
75
+ const { isInvalid } = validation;
74
76
  const { ref: containerRef, width } = useElementSize();
75
77
  const rootProps = mergeProps({
76
78
  "data-testid": testId,
77
- "data-invalid": isInvalid,
78
- "data-disabled": props.isDisabled,
79
- "data-required": props.isRequired,
79
+ "data-invalid": isInvalid || void 0,
80
+ "data-disabled": props.isDisabled || void 0,
81
+ "data-required": props.isRequired || void 0,
80
82
  className,
81
83
  fullWidth,
82
84
  labelPlacement,
@@ -84,14 +86,14 @@ function SelectRender(props, ref) {
84
86
  style
85
87
  });
86
88
  const listProps = mergeProps(
87
- { className: s.list, state },
88
- slotProps?.list,
89
- menuProps
89
+ { className: s.list, state, noItemsText },
90
+ menuProps,
91
+ slotProps?.list
90
92
  );
91
93
  const labelProps = mergeProps(
92
94
  { isHidden: isLabelHidden, children: label, isRequired },
93
- slotProps?.label,
94
- labelPropsAria
95
+ labelPropsAria,
96
+ slotProps?.label
95
97
  );
96
98
  const clearButtonProps = mergeProps(
97
99
  {
@@ -147,13 +149,9 @@ function SelectRender(props, ref) {
147
149
  slotProps?.popover
148
150
  );
149
151
  const captionProps = mergeProps({ children: caption }, slotProps?.caption, descriptionProps);
150
- const errorProps = mergeProps(
151
- { isInvalid, children: errorMessage },
152
- slotProps?.errorMessage,
153
- errorMessageProps
154
- );
152
+ const errorProps = mergeProps({ children: errorMessage }, slotProps?.errorMessage, errorMessageProps);
155
153
  const renderDefaultValue = (state2, states) => {
156
- if (!state2.selectedItems) return null;
154
+ if (!state2.selectedItems?.length) return null;
157
155
  if (selectionMode === "multiple")
158
156
  return /* @__PURE__ */ jsx(
159
157
  TagGroup,
@@ -176,7 +174,7 @@ function SelectRender(props, ref) {
176
174
  isRequired: props.isRequired
177
175
  }) }) }),
178
176
  /* @__PURE__ */ jsx(FieldCaption, { ...captionProps }),
179
- /* @__PURE__ */ jsx(FieldError, { ...errorProps })
177
+ /* @__PURE__ */ jsx(FieldErrorContext.Provider, { value: validation, children: /* @__PURE__ */ jsx(FieldError, { ...errorProps }) })
180
178
  ] })
181
179
  ] }),
182
180
  /* @__PURE__ */ jsx(PopoverInner, { ...popoverProps, children: /* @__PURE__ */ jsx(SelectList, { ...listProps }) })
@@ -1,8 +1,10 @@
1
- import type { Ref } from 'react';
1
+ import type { ReactNode, Ref } from 'react';
2
2
  import { type MultiSelectState } from '@koobiq/react-primitives';
3
3
  import type { ListProps } from '../../../List';
4
4
  export type SelectListProps<T extends object> = {
5
5
  state: MultiSelectState<T>;
6
6
  listRef?: Ref<HTMLUListElement>;
7
- } & Omit<ListProps<T>, 'ref'>;
7
+ /** Content to display when no items are available. */
8
+ noItemsText?: ReactNode;
9
+ } & Omit<ListProps<T>, 'ref' | 'children'>;
8
10
  export declare function SelectList<T extends object>(props: SelectListProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -1,16 +1,28 @@
1
- import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
- import { useDOMRef, mergeProps, clsx, isNotNil } from "@koobiq/react-core";
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useLocalizedStringFormatter, useDOMRef, mergeProps, clsx, isNotNil } from "@koobiq/react-core";
3
3
  import { useListBox } from "@koobiq/react-primitives";
4
4
  import { utilClasses } from "../../../../styles/utility.js";
5
+ import intlMessages from "../../intl.js";
5
6
  import s from "./SelectList.module.css.js";
6
7
  import { SelectOption } from "../SelectOption/SelectOption.js";
8
+ import { isPrimitiveNode } from "../../../../utils/isPrimitiveNode.js";
7
9
  import { Typography } from "../../../Typography/Typography.js";
8
10
  import { ListSection } from "../../../List/components/ListSection/ListSection.js";
9
11
  import { Divider } from "../../../Divider/Divider.js";
10
- const { list } = utilClasses;
12
+ const { list, typography } = utilClasses;
11
13
  function SelectList(props) {
12
- const { label, className, style, slotProps, state, listRef } = props;
14
+ const {
15
+ label,
16
+ className,
17
+ style,
18
+ slotProps,
19
+ state,
20
+ listRef,
21
+ noItemsText: noItemsTextProp
22
+ } = props;
23
+ const t = useLocalizedStringFormatter(intlMessages);
13
24
  const domRef = useDOMRef(listRef);
25
+ const isEmpty = state.collection.size === 0;
14
26
  const { listBoxProps, labelProps } = useListBox(props, state, domRef);
15
27
  const titleProps = mergeProps(
16
28
  {
@@ -24,15 +36,28 @@ function SelectList(props) {
24
36
  {
25
37
  style,
26
38
  ref: domRef,
27
- className: clsx(list, className)
39
+ className: clsx(list, className),
40
+ "data-padded": true
28
41
  },
29
42
  slotProps?.list,
30
43
  listBoxProps
31
44
  );
45
+ const noItemsText = noItemsTextProp ?? t.format("empty items");
46
+ const emptyState = isEmpty ? /* @__PURE__ */ jsx(
47
+ "div",
48
+ {
49
+ role: "option",
50
+ className: clsx(s.empty, typography["text-normal"]),
51
+ ...!isPrimitiveNode(noItemsText) && {
52
+ style: { display: "contents" }
53
+ },
54
+ children: noItemsText
55
+ }
56
+ ) : null;
32
57
  const renderItems = (treeState) => [...treeState.collection].map((item) => {
33
58
  switch (item.type) {
34
59
  case "divider":
35
- return /* @__PURE__ */ jsx(Divider, { className: s.divider }, item.key);
60
+ return /* @__PURE__ */ jsx(Divider, {}, item.key);
36
61
  case "item":
37
62
  return /* @__PURE__ */ jsx(SelectOption, { item, state }, item.key);
38
63
  case "section":
@@ -43,7 +68,10 @@ function SelectList(props) {
43
68
  });
44
69
  return /* @__PURE__ */ jsxs(Fragment, { children: [
45
70
  isNotNil(label) && /* @__PURE__ */ jsx(Typography, { ...titleProps, children: label }),
46
- /* @__PURE__ */ jsx("ul", { ...listProps, children: renderItems(state) })
71
+ /* @__PURE__ */ jsxs("ul", { ...listProps, children: [
72
+ renderItems(state),
73
+ emptyState
74
+ ] })
47
75
  ] });
48
76
  }
49
77
  export {
@@ -1,11 +1,11 @@
1
1
  const label = "kbq-selectlist-label-4b49f4";
2
- const divider = "kbq-selectlist-divider-7c167f";
2
+ const empty = "kbq-selectlist-empty-e6a9b0";
3
3
  const s = {
4
4
  label,
5
- divider
5
+ empty
6
6
  };
7
7
  export {
8
8
  s as default,
9
- divider,
9
+ empty,
10
10
  label
11
11
  };
@@ -25,11 +25,11 @@ function SelectOption({ item, state }) {
25
25
  className: clsx(listItem, textVariant["text-normal"], className),
26
26
  style,
27
27
  ref,
28
- "data-hovered": isHovered,
29
- "data-pressed": isPressed,
30
- "data-disabled": isDisabled,
31
- "data-selected": isSelected,
32
- "data-focus-visible": isFocusVisible,
28
+ "data-hovered": isHovered || void 0,
29
+ "data-pressed": isPressed || void 0,
30
+ "data-disabled": isDisabled || void 0,
31
+ "data-selected": isSelected || void 0,
32
+ "data-focus-visible": isFocusVisible || void 0,
33
33
  children: [
34
34
  state.selectionMode === "multiple" && /* @__PURE__ */ jsx(Checkbox, { isDisabled, isSelected, isReadOnly: true }),
35
35
  item.rendered
@@ -1,10 +1,12 @@
1
1
  const intlMessages = {
2
2
  "ru-RU": {
3
+ "empty items": "Нет вариантов выбора",
3
4
  "selected items": "Выбранные элементы",
4
5
  clear: "Очистить",
5
6
  more: ({ count }) => `еще ${count}`
6
7
  },
7
8
  "en-US": {
9
+ "empty items": "No options available",
8
10
  "selected items": "Selected items",
9
11
  clear: "Clear",
10
12
  more: ({ count }) => `${count} more`
@@ -5,8 +5,8 @@ import { type FieldErrorProps, type FieldSelectProps, type FieldCaptionProps, ty
5
5
  import { type FormControlPropLabelAlign, type FormControlPropLabelPlacement } from '../FormControl';
6
6
  import type { FormControlLabelProps } from '../FormControlLabel';
7
7
  import type { IconButtonProps } from '../IconButton';
8
- import type { ListProps } from '../List';
9
8
  import type { PopoverProps } from '../Popover';
9
+ import type { SelectListProps } from './components';
10
10
  export declare const selectPropSelectedTagsOverflow: readonly ["multiline", "responsive"];
11
11
  export type SelectPropSelectedTagsOverflow = (typeof selectPropSelectedTagsOverflow)[number];
12
12
  export declare const selectPropLabelPlacement: readonly ["top", "side"];
@@ -19,7 +19,7 @@ export type SelectProps<T> = ExtendableProps<{
19
19
  *
20
20
  *- `"multiline"` — tags wrap to multiple lines.
21
21
  *- `"responsive"` — tags collapse into a summary (e.g., "3 more").
22
- * @default "responsive"
22
+ * @default 'responsive'
23
23
  */
24
24
  selectedTagsOverflow?: SelectPropSelectedTagsOverflow;
25
25
  /** Handler that is called when the clear button is clicked. */
@@ -34,6 +34,8 @@ export type SelectProps<T> = ExtendableProps<{
34
34
  onSelectionChange?: Parameters<typeof useMultiSelectState>['0']['onSelectionChange'];
35
35
  /** The currently selected keys in the collection (controlled). */
36
36
  selectedKeys?: Parameters<typeof useMultiSelectState>['0']['selectedKeys'];
37
+ validate?: Parameters<typeof useMultiSelectState>['0']['validate'];
38
+ validationBehavior?: Parameters<typeof useMultiSelectState>['0']['validationBehavior'];
37
39
  /**
38
40
  * The type of selection that is allowed in the collection.
39
41
  * @default 'single'
@@ -45,11 +47,8 @@ export type SelectProps<T> = ExtendableProps<{
45
47
  endAddon?: ReactNode;
46
48
  /** Inline styles. */
47
49
  style?: CSSProperties;
48
- /** An error message for the field. */
49
- errorMessage?: ReactNode;
50
50
  /**
51
51
  * If `true`, the label is hidden. Be sure to add aria-label to the input element.
52
- * @default false
53
52
  */
54
53
  isLabelHidden?: boolean;
55
54
  /**
@@ -66,7 +65,6 @@ export type SelectProps<T> = ExtendableProps<{
66
65
  caption?: ReactNode;
67
66
  /**
68
67
  * If true, the input will take up the full width of its container.
69
- * @default false
70
68
  */
71
69
  fullWidth?: boolean;
72
70
  /** Unique identifier for testing purposes. */
@@ -79,17 +77,19 @@ export type SelectProps<T> = ExtendableProps<{
79
77
  isDisabled?: boolean;
80
78
  isRequired?: boolean;
81
79
  }) => ReactNode;
80
+ /** Content to display when no items are available. */
81
+ noItemsText?: ReactNode;
82
82
  /** The props used for each slot inside. */
83
83
  slotProps?: {
84
84
  popover?: PopoverProps;
85
85
  label?: FormControlLabelProps;
86
- list?: ListProps<T>;
86
+ list?: Omit<SelectListProps<object>, 'state'>;
87
87
  control?: FieldSelectProps;
88
88
  caption?: FieldCaptionProps;
89
89
  group?: FieldContentGroupProps;
90
90
  errorMessage?: FieldErrorProps;
91
91
  clearButton?: IconButtonProps;
92
92
  };
93
- }, Omit<AriaSelectProps<T>, 'description' | 'validate' | 'validationBehavior' | 'validationState' | 'selectedKey' | 'onSelectionChange' | 'defaultSelectedKey'>>;
93
+ }, Omit<AriaSelectProps<T>, 'description' | 'validationBehavior' | 'validate' | 'validationState' | 'selectedKey' | 'onSelectionChange' | 'defaultSelectedKey'>>;
94
94
  export type SelectComponent = <T>(props: SelectProps<T>) => ReactElement | null;
95
95
  export type SelectRef = ComponentRef<'div'>;
@@ -14,7 +14,7 @@ const SidePanelComponent = forwardRef(
14
14
  size = "medium",
15
15
  position = "left",
16
16
  placement = "start",
17
- hideCloseButton = false,
17
+ hideCloseButton,
18
18
  control,
19
19
  children,
20
20
  slotProps,
@@ -48,7 +48,6 @@ export type SidePanelProps = {
48
48
  control?: SidePanelPropControl;
49
49
  /**
50
50
  * If `true`, the close button isn't shown.
51
- * @default false
52
51
  */
53
52
  hideCloseButton?: boolean;
54
53
  /** Handler that is called when the modal's open state changes. */
@@ -60,17 +59,14 @@ export type SidePanelProps = {
60
59
  portalContainer?: Element;
61
60
  /**
62
61
  * If `true`, the modal window won't close when clicked outside of it.
63
- * @default false
64
62
  */
65
63
  disableExitOnClickOutside?: boolean;
66
64
  /**
67
65
  * If `true`, the modal window won't close when the ESC key is pressed.
68
- * @default false
69
66
  */
70
67
  disableExitOnEscapeKeyDown?: boolean;
71
68
  /**
72
69
  * If `true`, the underlay (backdrop) under the modal window isn't shown.
73
- * @default false
74
70
  */
75
71
  hideBackdrop?: boolean;
76
72
  /** Additional CSS-classes. */
@@ -79,7 +75,6 @@ export type SidePanelProps = {
79
75
  'data-testid'?: string | number;
80
76
  /**
81
77
  * If `true`, the focus trap in modal window is disabled.
82
- * @default false
83
78
  */
84
79
  disableFocusManagement?: boolean;
85
80
  /**
@@ -21,9 +21,9 @@ import { Cell } from "../Collections/Cell.js";
21
21
  const textNormal = utilClasses.typography["text-normal"];
22
22
  function TableRender(props, ref) {
23
23
  const {
24
- stickyHeader = false,
25
- fullWidth = false,
26
24
  divider = "none",
25
+ stickyHeader,
26
+ fullWidth,
27
27
  slotProps,
28
28
  selectionMode,
29
29
  selectionBehavior,
@@ -41,9 +41,9 @@ function TableRender(props, ref) {
41
41
  const tableProps = mergeProps(
42
42
  {
43
43
  className: clsx(s.base, fullWidth && s.fullWidth, textNormal, className),
44
- "data-sticky-header": stickyHeader,
44
+ "data-sticky-header": stickyHeader || void 0,
45
45
  "data-divider": divider,
46
- "data-fullwidth": fullWidth,
46
+ "data-fullwidth": fullWidth || void 0,
47
47
  ref: domRef,
48
48
  style
49
49
  },
@@ -29,11 +29,11 @@ function TableRow({ item, children, state }) {
29
29
  isFocusVisible && s.focusVisible,
30
30
  className
31
31
  ),
32
- "data-hovered": isHovered,
33
- "data-disabled": isDisabled,
34
- "data-selected": isSelected,
35
- "data-pressed": isPressed,
36
- "data-focus-visible": isFocusVisible,
32
+ "data-hovered": isHovered || void 0,
33
+ "data-disabled": isDisabled || void 0,
34
+ "data-selected": isSelected || void 0,
35
+ "data-pressed": isPressed || void 0,
36
+ "data-focus-visible": isFocusVisible || void 0,
37
37
  ...mergeProps(rowProps, hoverProps, focusProps),
38
38
  style,
39
39
  ref,
@@ -20,12 +20,10 @@ export type TableProps<T> = Pick<TableStateProps<T>, 'selectionBehavior' | 'sele
20
20
  divider?: TablePropDivider;
21
21
  /**
22
22
  * If `true`, the button will take up the full width of its container.
23
- * @default false
24
23
  */
25
24
  fullWidth?: boolean;
26
25
  /**
27
26
  * Flag indicating a fixed table header.
28
- * @default false
29
27
  */
30
28
  stickyHeader?: boolean;
31
29
  /**
@@ -37,12 +37,12 @@ function Tag(props) {
37
37
  ),
38
38
  style,
39
39
  "data-variant": variant,
40
- "data-focused": isFocused,
41
- "data-pressed": isPressed,
42
- "data-hovered": isHovered,
43
- "aria-disabled": isDisabled,
44
- "data-disabled": isDisabled,
45
- "data-focus-visible": isFocusVisible
40
+ "data-focused": isFocused || void 0,
41
+ "data-pressed": isPressed || void 0,
42
+ "data-hovered": isHovered || void 0,
43
+ "aria-disabled": isDisabled || void 0,
44
+ "data-disabled": isDisabled || void 0,
45
+ "data-focus-visible": isFocusVisible || void 0
46
46
  },
47
47
  rowProps,
48
48
  hoverProps,