@festo-ui/react 9.0.1-dev.772 → 9.0.1-dev.776

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 (38) hide show
  1. package/dist/forms/combobox/ComboBox.css +3 -42
  2. package/dist/forms/combobox/ComboBox.js +16 -15
  3. package/dist/forms/multi-select/MultiSelect.d.ts +20 -0
  4. package/dist/forms/multi-select/MultiSelect.js +186 -0
  5. package/dist/forms/multi-select/MultiSelect.module.js +8 -0
  6. package/dist/forms/multi-select/MultiSelect_module.css +13 -0
  7. package/dist/forms/select/Select.d.ts +12 -13
  8. package/dist/forms/select/Select.js +74 -82
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.js +2 -2
  11. package/package.json +1 -1
  12. package/dist/forms/select/Select.css +0 -160
  13. package/dist/forms/select/internal/HiddenInput.d.ts +0 -8
  14. package/dist/forms/select/internal/HiddenInput.js +0 -15
  15. package/dist/forms/select/internal/ListItem.d.ts +0 -18
  16. package/dist/forms/select/internal/ListItem.js +0 -69
  17. package/dist/forms/select/internal/SelectButton.d.ts +0 -12
  18. package/dist/forms/select/internal/SelectButton.js +0 -49
  19. package/dist/forms/select/internal/SelectButtonContent.d.ts +0 -7
  20. package/dist/forms/select/internal/SelectButtonContent.js +0 -31
  21. package/dist/forms/select/internal/SelectCheckbox.d.ts +0 -4
  22. package/dist/forms/select/internal/SelectCheckbox.js +0 -13
  23. package/dist/forms/select/internal/SelectLabel.d.ts +0 -7
  24. package/dist/forms/select/internal/SelectLabel.js +0 -12
  25. package/dist/forms/select/internal/SelectOptionsContainer.d.ts +0 -17
  26. package/dist/forms/select/internal/SelectOptionsContainer.js +0 -103
  27. package/dist/forms/select/internal/SelectScrollContainer.d.ts +0 -8
  28. package/dist/forms/select/internal/SelectScrollContainer.js +0 -15
  29. package/dist/forms/select/internal/SelectWrapper.d.ts +0 -6
  30. package/dist/forms/select/internal/SelectWrapper.js +0 -12
  31. package/dist/forms/select/internal/index.d.ts +0 -6
  32. package/dist/forms/select/internal/index.js +0 -7
  33. package/dist/forms/select/internal/utils.d.ts +0 -7
  34. package/dist/forms/select/internal/utils.js +0 -30
  35. package/dist/forms/select/select-option/SelectOption.d.ts +0 -14
  36. package/dist/forms/select/select-option/SelectOption.js +0 -12
  37. package/dist/forms/select/utils.d.ts +0 -2
  38. package/dist/forms/select/utils.js +0 -12
@@ -106,57 +106,18 @@
106
106
  display: none;
107
107
  }
108
108
 
109
- .fr-combobox-options-container {
110
- background-color: var(--fwe-white);
111
- border: 1px solid var(--fwe-gray-200);
112
- border-radius: 4px;
113
- max-width: 100%;
114
- margin: 0;
115
- padding: 8px;
116
- list-style: none;
117
- box-shadow: 0 1px 4px #00000029;
118
- }
119
-
120
- .fr-combobox-option {
121
- cursor: pointer;
122
- min-height: 24px;
123
- padding: 12px 8px;
124
- line-height: 24px;
125
- position: relative;
126
- }
127
-
128
- .fr-combobox-option:hover, .fr-combobox-option.fr-focus, .fr-combobox-option.fr-selected {
129
- background-color: var(--fwe-gray-100);
130
- outline: none;
131
- }
132
-
133
- .fr-combobox-option:last-child {
134
- border-bottom: none;
135
- }
136
-
137
- .fr-combobox-option.fr-disabled {
138
- color: var(--fwe-text-disabled);
139
- cursor: default;
140
- }
141
-
142
- .fr-combobox-option.fr-disabled:hover, .fr-combobox-option.fr-disabled:focus, .fr-combobox-option.fr-disabled.fr-focus {
143
- background-color: #0000;
144
- }
145
-
146
- .fr-combobox-option-content {
109
+ .fwe-combobox-option-content {
147
110
  white-space: nowrap;
148
111
  text-overflow: ellipsis;
149
- min-height: 24px;
150
- line-height: 24px;
151
112
  display: block;
152
113
  overflow: hidden;
153
114
  }
154
115
 
155
- .fr-combobox-highlight {
116
+ .fwe-combobox-highlight {
156
117
  color: var(--fwe-hero);
157
118
  }
158
119
 
159
- .fr-combobox-empty {
120
+ .fwe-combobox-empty {
160
121
  cursor: default;
161
122
  color: var(--fwe-text-disabled);
162
123
  }
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import "./ComboBox.css";
3
3
  import { Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions } from "@headlessui/react";
4
4
  import classnames from "classnames";
5
- import { forwardRef, useMemo, useRef, useState } from "react";
5
+ import { forwardRef, useMemo, useState } from "react";
6
6
  import { useControlled } from "../../utils/useControlled.js";
7
7
  import { useId } from "../../utils/useId.js";
8
8
  function getHighlightedLabel(label, query) {
@@ -39,7 +39,6 @@ function getHighlightedLabel(label, query) {
39
39
  }
40
40
  function ComboBoxComponent({ defaultValue = '', value: controlled, label, options = [], onChange, required = false, disabled, name, id: idProp, hint, error, placeholder, onInputChange, emptyMessage = 'No results found', className, ...props }, ref) {
41
41
  const id = useId(idProp);
42
- const controlRef = useRef(null);
43
42
  const [value, setValue] = useControlled({
44
43
  controlled,
45
44
  default: defaultValue,
@@ -88,13 +87,12 @@ function ComboBoxComponent({ defaultValue = '', value: controlled, label, option
88
87
  ...props,
89
88
  children: [
90
89
  /*#__PURE__*/ jsx("label", {
91
- className: classnames('fr-combobox-label'),
90
+ className: "fr-combobox-label",
92
91
  htmlFor: id,
93
92
  children: label || ''
94
93
  }),
95
94
  /*#__PURE__*/ jsxs("div", {
96
95
  className: "fr-combobox-control",
97
- ref: controlRef,
98
96
  children: [
99
97
  /*#__PURE__*/ jsx(ComboboxInput, {
100
98
  className: inputClasses,
@@ -115,19 +113,22 @@ function ComboBoxComponent({ defaultValue = '', value: controlled, label, option
115
113
  ]
116
114
  }),
117
115
  /*#__PURE__*/ jsxs(ComboboxOptions, {
118
- className: "fr-combobox-options-container",
116
+ className: "fwe-options-container",
119
117
  as: "ul",
120
118
  portal: false,
119
+ style: {
120
+ minWidth: 'var(--input-width)'
121
+ },
121
122
  anchor: {
122
123
  to: 'bottom start',
123
- gap: 20,
124
+ gap: 12,
124
125
  padding: 8
125
126
  },
126
127
  children: [
127
128
  0 === filteredOptions.length && /*#__PURE__*/ jsx("li", {
128
- className: "fr-combobox-option fr-combobox-empty",
129
+ className: "fwe-combobox-option fwe-combobox-empty",
129
130
  children: /*#__PURE__*/ jsx("span", {
130
- className: "fr-combobox-option-content",
131
+ className: "fwe-combobox-option-content",
131
132
  children: emptyMessage
132
133
  })
133
134
  }),
@@ -135,17 +136,17 @@ function ComboBoxComponent({ defaultValue = '', value: controlled, label, option
135
136
  value: option,
136
137
  disabled: option.disabled,
137
138
  as: "li",
138
- className: ({ focus, selected, disabled: isDisabled })=>classnames('fr-combobox-option', {
139
- 'fr-selected': selected,
140
- 'fr-focus': focus,
141
- 'fr-disabled': isDisabled
139
+ className: ({ focus, selected, disabled: isDisabled })=>classnames('fwe-combobox-option', {
140
+ 'fwe-selected': selected,
141
+ 'fwe-focus': focus,
142
+ 'fwe-disabled': isDisabled
142
143
  }),
143
144
  children: /*#__PURE__*/ jsx("span", {
144
- className: "fr-combobox-option-content",
145
- "data-testid": "fr-combobox-option-content",
145
+ className: "fwe-combobox-option-content",
146
+ "data-testid": "fwe-combobox-option-content",
146
147
  children: getHighlightedLabel(option.label, query).map((part, index)=>/*#__PURE__*/ jsx("span", {
147
148
  className: classnames({
148
- 'fr-combobox-highlight': part.highlighted
149
+ 'fwe-combobox-highlight': part.highlighted
149
150
  }),
150
151
  children: part.text
151
152
  }, `${part.text}-${index}`))
@@ -0,0 +1,20 @@
1
+ import type { Ref } from 'react';
2
+ import type { ComponentBase } from '../../utils/types';
3
+ import type { SelectOption } from '../select/Select';
4
+ export interface MultiSelectProps<T> extends ComponentBase {
5
+ readonly defaultValue?: T[];
6
+ readonly value?: T[];
7
+ readonly label?: string;
8
+ readonly options?: SelectOption<T>[];
9
+ readonly onChange?: (value: T[]) => void;
10
+ readonly disabled?: boolean;
11
+ readonly name?: string;
12
+ readonly hint?: string;
13
+ readonly error?: string;
14
+ readonly placeholder?: string;
15
+ }
16
+ declare function MultiSelectComponent<T>({ defaultValue, value: controlled, label, options, onChange, disabled, name, id: idProp, hint, error, placeholder, className, ...props }: MultiSelectProps<T>, ref: Ref<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
17
+ export declare const MultiSelect: <T>(props: MultiSelectProps<T> & {
18
+ ref?: Ref<HTMLDivElement>;
19
+ }) => ReturnType<typeof MultiSelectComponent>;
20
+ export {};
@@ -0,0 +1,186 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from "@headlessui/react";
3
+ import classnames from "classnames";
4
+ import { forwardRef, useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
5
+ import { useControlled } from "../../utils/useControlled.js";
6
+ import { useId } from "../../utils/useId.js";
7
+ import MultiSelect_module from "./MultiSelect.module.js";
8
+ function MultiSelectComponent({ defaultValue = [], value: controlled, label, options = [], onChange, disabled, name, id: idProp, hint, error, placeholder, className, ...props }, ref) {
9
+ const id = useId(idProp);
10
+ const labelId = `${id}-label`;
11
+ const [value, setValue] = useControlled({
12
+ controlled,
13
+ default: defaultValue,
14
+ onChange
15
+ });
16
+ const selectedOptions = useMemo(()=>options.filter((option)=>!option.disabled && (value ?? []).includes(option.data)), [
17
+ options,
18
+ value
19
+ ]);
20
+ function handleChange(nextOptions) {
21
+ setValue(nextOptions.map((option)=>option.data));
22
+ }
23
+ const chipsRef = useRef(null);
24
+ const [overflowCount, setOverflowCount] = useState(0);
25
+ const measureOverflow = useCallback((optionCount)=>{
26
+ const container = chipsRef.current;
27
+ if (!container) return void setOverflowCount(0);
28
+ const allChildren = Array.from(container.children);
29
+ const optionChildren = allChildren.filter((child)=>'true' === child.dataset.optionChip);
30
+ for (const child of optionChildren)child.style.display = '';
31
+ const containerRect = container.getBoundingClientRect();
32
+ const isOverflow = optionChildren.some((child)=>{
33
+ const childRect = child.getBoundingClientRect();
34
+ return childRect.right > containerRect.right;
35
+ });
36
+ if (isOverflow && optionCount > 1) {
37
+ let remainingWidth = containerRect.width - 64;
38
+ let count = 0;
39
+ for (const child of optionChildren){
40
+ const width = child.getBoundingClientRect().width + 8;
41
+ if (width <= remainingWidth) {
42
+ remainingWidth -= width;
43
+ child.style.display = '';
44
+ } else {
45
+ count++;
46
+ child.style.display = 'none';
47
+ }
48
+ }
49
+ setOverflowCount(count);
50
+ } else setOverflowCount(0);
51
+ }, []);
52
+ useLayoutEffect(()=>{
53
+ measureOverflow(selectedOptions.length);
54
+ const container = chipsRef.current;
55
+ if (!container) return;
56
+ const observer = new ResizeObserver(()=>{
57
+ measureOverflow(selectedOptions.length);
58
+ });
59
+ observer.observe(container);
60
+ return ()=>observer.disconnect();
61
+ }, [
62
+ selectedOptions,
63
+ measureOverflow
64
+ ]);
65
+ return /*#__PURE__*/ jsx(Listbox, {
66
+ value: selectedOptions,
67
+ onChange: handleChange,
68
+ disabled: disabled,
69
+ name: name,
70
+ multiple: true,
71
+ children: /*#__PURE__*/ jsxs("div", {
72
+ className: classnames(className, 'fwe-select-wrapper', {
73
+ 'fwe-disabled': disabled
74
+ }),
75
+ ref: ref,
76
+ ...props,
77
+ children: [
78
+ /*#__PURE__*/ jsx(ListboxButton, {
79
+ className: classnames('fwe-select', {
80
+ 'fwe-invalid': error
81
+ }),
82
+ id: id,
83
+ "aria-labelledby": label ? labelId : void 0,
84
+ disabled: disabled,
85
+ children: selectedOptions.length > 0 ? /*#__PURE__*/ jsxs("span", {
86
+ ref: chipsRef,
87
+ className: MultiSelect_module["chip-container"],
88
+ children: [
89
+ selectedOptions.map((o)=>/*#__PURE__*/ jsx("span", {
90
+ "data-option-chip": "true",
91
+ className: classnames('fwe-chip', {
92
+ 'fwe-disabled': disabled
93
+ }),
94
+ style: {
95
+ minWidth: 0,
96
+ flexShrink: 1 === selectedOptions.length ? 1 : 0
97
+ },
98
+ children: /*#__PURE__*/ jsx("span", {
99
+ className: MultiSelect_module["chip-ellipsis"],
100
+ children: o.label
101
+ })
102
+ }, String(o.data))),
103
+ overflowCount > 0 && /*#__PURE__*/ jsxs(Fragment, {
104
+ children: [
105
+ /*#__PURE__*/ jsx("span", {
106
+ children: "..."
107
+ }),
108
+ /*#__PURE__*/ jsx("span", {
109
+ className: "fwe-chip",
110
+ children: overflowCount
111
+ })
112
+ ]
113
+ })
114
+ ]
115
+ }) : placeholder ?? ''
116
+ }),
117
+ /*#__PURE__*/ jsx("label", {
118
+ className: "fwe-select-label",
119
+ id: labelId,
120
+ htmlFor: id,
121
+ children: label || ''
122
+ }),
123
+ /*#__PURE__*/ jsx(ListboxOptions, {
124
+ className: "fwe-options-container fwe-options-container--multi-select",
125
+ as: "ul",
126
+ portal: false,
127
+ style: {
128
+ minWidth: 'var(--button-width)'
129
+ },
130
+ anchor: {
131
+ to: 'bottom start',
132
+ gap: 12,
133
+ padding: 8
134
+ },
135
+ children: options.map((option)=>/*#__PURE__*/ jsx(ListboxOption, {
136
+ value: option,
137
+ disabled: option.disabled,
138
+ as: "li",
139
+ style: {
140
+ cursor: option.disabled ? 'default' : 'pointer'
141
+ },
142
+ children: ({ selected })=>/*#__PURE__*/ jsxs("label", {
143
+ className: classnames('fwe-checkbox', {
144
+ 'fwe-disabled': option.disabled
145
+ }),
146
+ style: {
147
+ pointerEvents: 'none',
148
+ cursor: 'pointer'
149
+ },
150
+ children: [
151
+ /*#__PURE__*/ jsx("input", {
152
+ type: "checkbox",
153
+ checked: selected,
154
+ disabled: option.disabled,
155
+ readOnly: true,
156
+ tabIndex: -1,
157
+ style: {
158
+ pointerEvents: 'none',
159
+ cursor: 'pointer'
160
+ }
161
+ }),
162
+ /*#__PURE__*/ jsx("span", {
163
+ className: "fwe-checkbox-checkmark"
164
+ }),
165
+ /*#__PURE__*/ jsx("span", {
166
+ className: "fwe-checkbox-label-content",
167
+ children: option.label
168
+ })
169
+ ]
170
+ })
171
+ }, String(option.data)))
172
+ }),
173
+ hint && !error && /*#__PURE__*/ jsx("div", {
174
+ className: "fwe-select-description",
175
+ children: hint
176
+ }),
177
+ error && /*#__PURE__*/ jsx("div", {
178
+ className: "fwe-select-invalid",
179
+ children: error
180
+ })
181
+ ]
182
+ })
183
+ });
184
+ }
185
+ const MultiSelect = /*#__PURE__*/ forwardRef(MultiSelectComponent);
186
+ export { MultiSelect };
@@ -0,0 +1,8 @@
1
+ import "./MultiSelect_module.css";
2
+ const MultiSelect_module = {
3
+ "chip-container": "chip-container-VYPHrz",
4
+ chipContainer: "chip-container-VYPHrz",
5
+ "chip-ellipsis": "chip-ellipsis-AW26fc",
6
+ chipEllipsis: "chip-ellipsis-AW26fc"
7
+ };
8
+ export { MultiSelect_module as default };
@@ -0,0 +1,13 @@
1
+ .chip-container-VYPHrz {
2
+ flex-wrap: nowrap;
3
+ gap: 8px;
4
+ display: flex;
5
+ overflow: hidden;
6
+ }
7
+
8
+ .chip-ellipsis-AW26fc {
9
+ text-overflow: ellipsis;
10
+ white-space: nowrap;
11
+ overflow: hidden;
12
+ }
13
+
@@ -1,25 +1,24 @@
1
- import './Select.scss';
2
- import { type ComponentPropsWithoutRef, type Ref } from 'react';
3
- import type { SelectConfiguration } from '../../utils/types';
4
- import type { SelectOptionType } from './select-option/SelectOption';
5
- export interface SelectProps<T> extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue'> {
1
+ import type { ReactNode } from 'react';
2
+ import { type Ref } from 'react';
3
+ import type { ComponentBase } from '../../utils/types';
4
+ export interface SelectOption<T> {
5
+ readonly data: T;
6
+ readonly label: ReactNode;
7
+ readonly disabled?: boolean;
8
+ }
9
+ export interface SelectProps<T> extends ComponentBase {
6
10
  readonly defaultValue?: T;
7
- readonly defaultOpen?: boolean;
8
- readonly open?: boolean;
9
11
  readonly value?: T;
10
12
  readonly label?: string;
11
- readonly options?: SelectOptionType<T>[];
12
- readonly required?: boolean;
13
+ readonly options?: SelectOption<T>[];
13
14
  readonly onChange?: (value: T) => void;
14
- readonly config?: SelectConfiguration;
15
15
  readonly disabled?: boolean;
16
16
  readonly name?: string;
17
17
  readonly hint?: string;
18
18
  readonly error?: string;
19
- readonly onOpenChange?: (value: boolean) => void;
20
- readonly renderLabelContent?: (label?: string | string[]) => JSX.Element;
19
+ readonly placeholder?: string;
21
20
  }
22
- declare function SelectComponent<T>({ defaultValue, open, defaultOpen, value: controlled, label, options, onChange, required, config, disabled, name, id, children, hint, error, onOpenChange, renderLabelContent, ...props }: SelectProps<T>, ref: Ref<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
21
+ declare function SelectComponent<T>({ defaultValue, value: controlled, label, options, onChange, disabled, name, id: idProp, hint, error, placeholder, className, ...props }: SelectProps<T>, ref: Ref<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
23
22
  export declare const Select: <T>(props: SelectProps<T> & {
24
23
  ref?: Ref<HTMLDivElement>;
25
24
  }) => ReturnType<typeof SelectComponent>;
@@ -1,94 +1,86 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import "./Select.css";
3
- import { forwardRef, useRef } from "react";
4
- import react_dom from "react-dom";
2
+ import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from "@headlessui/react";
3
+ import classnames from "classnames";
4
+ import { forwardRef, useMemo } from "react";
5
5
  import { useControlled } from "../../utils/useControlled.js";
6
- import { useForkRef } from "../../utils/useForkRef.js";
7
- import { SelectButton, SelectLabel, SelectOptionsContainer, SelectWrapper } from "./internal/index.js";
8
- import { HiddenInput } from "./internal/HiddenInput.js";
9
- import { getChildren } from "./internal/utils.js";
10
- function SelectComponent({ defaultValue = '', open, defaultOpen = false, value: controlled, label, options, onChange, required = false, config, disabled, name, id, children, hint, error, onOpenChange, renderLabelContent, ...props }, ref) {
6
+ import { useId } from "../../utils/useId.js";
7
+ function SelectComponent({ defaultValue = '', value: controlled, label, options = [], onChange, disabled, name, id: idProp, hint, error, placeholder, className, ...props }, ref) {
8
+ const id = useId(idProp);
9
+ const labelId = `${id}-label`;
11
10
  const [value, setValue] = useControlled({
12
11
  controlled,
13
12
  default: defaultValue,
14
13
  onChange
15
14
  });
16
- const [focused, setFocused] = useControlled({
17
- controlled: open,
18
- default: defaultOpen,
19
- onChange: onOpenChange
20
- });
21
- const buttonEl = useRef(null);
22
- const usedOptions = options ?? getChildren(children).childrenList.map((child)=>child.props.option);
23
- const innerRef = useRef(null);
24
- const combinedRef = useForkRef(ref, innerRef);
25
- const multiple = Array.isArray(value);
26
- const refocusButton = ()=>{
27
- setFocused(false);
28
- buttonEl?.current?.focus();
29
- };
30
- const handleOptionChange = (newOption)=>{
31
- let newValue = newOption.data;
32
- if (Array.isArray(value)) newValue = value.includes(newValue) ? value.filter((item)=>item !== newValue) : [
33
- ...value,
34
- newValue
35
- ];
36
- setValue(newValue);
37
- if (!multiple) refocusButton();
38
- };
39
- const removeChip = (chipLabel)=>{
40
- const chipOption = usedOptions.find((option)=>option.label === chipLabel);
41
- if (chipOption) handleOptionChange(chipOption);
42
- };
43
- const selectedLabel = multiple ? usedOptions.filter((option)=>value.includes(option.data))?.map((option)=>option.label) : usedOptions.find((option)=>option.data === value)?.label;
44
- return /*#__PURE__*/ jsxs(SelectWrapper, {
15
+ const selectedOption = useMemo(()=>options.find((option)=>option.data === value && !option.disabled), [
16
+ options,
17
+ value
18
+ ]);
19
+ function handleChange(option) {
20
+ if (!option || option.disabled) return;
21
+ setValue(option.data);
22
+ }
23
+ return /*#__PURE__*/ jsx(Listbox, {
24
+ value: selectedOption ?? null,
25
+ onChange: handleChange,
45
26
  disabled: disabled,
46
- ref: combinedRef,
47
- ...props,
48
- children: [
49
- /*#__PURE__*/ jsx(HiddenInput, {
50
- onChange: handleOptionChange,
51
- options: usedOptions,
52
- value: value
53
- }),
54
- /*#__PURE__*/ jsx(SelectButton, {
55
- ref: buttonEl,
56
- onToggle: ()=>setFocused((prev)=>!prev),
57
- error: error,
58
- disabled: disabled,
59
- focused: focused,
60
- required: required,
61
- onChipClick: removeChip,
62
- label: selectedLabel,
63
- renderLabelContent: renderLabelContent
64
- }),
65
- /*#__PURE__*/ jsx(SelectLabel, {
66
- hideLabel: config?.hideLabel,
67
- label: label,
68
- id: id
69
- }),
70
- /*#__PURE__*/ jsx("div", {
71
- className: "fwe-select-underline"
72
- }),
73
- hint && !error && /*#__PURE__*/ jsx("div", {
74
- className: "fwe-select-description",
75
- children: hint
76
- }),
77
- error && /*#__PURE__*/ jsx("div", {
78
- className: "fwe-select-invalid",
79
- children: error
27
+ name: name,
28
+ children: /*#__PURE__*/ jsxs("div", {
29
+ className: classnames(className, 'fwe-select-wrapper', {
30
+ 'fwe-disabled': disabled
80
31
  }),
81
- focused && /*#__PURE__*/ react_dom.createPortal(/*#__PURE__*/ jsx(SelectOptionsContainer, {
82
- multiple: multiple,
83
- ref: innerRef,
84
- config: config,
85
- onClose: refocusButton,
86
- onOptionChange: handleOptionChange,
87
- options: options,
88
- label: selectedLabel,
89
- children: children
90
- }), document.body)
91
- ]
32
+ ref: ref,
33
+ ...props,
34
+ children: [
35
+ /*#__PURE__*/ jsx(ListboxButton, {
36
+ className: classnames('fwe-select', {
37
+ 'fwe-invalid': error
38
+ }),
39
+ id: id,
40
+ "aria-labelledby": label ? labelId : void 0,
41
+ disabled: disabled,
42
+ children: selectedOption ? selectedOption.label : placeholder ?? ''
43
+ }),
44
+ /*#__PURE__*/ jsx("label", {
45
+ className: "fwe-select-label",
46
+ id: labelId,
47
+ htmlFor: id,
48
+ children: label || ''
49
+ }),
50
+ /*#__PURE__*/ jsx(ListboxOptions, {
51
+ className: "fwe-options-container",
52
+ as: "ul",
53
+ portal: false,
54
+ style: {
55
+ minWidth: 'var(--button-width)'
56
+ },
57
+ anchor: {
58
+ to: 'bottom start',
59
+ gap: 12,
60
+ padding: 8
61
+ },
62
+ children: options.map((option)=>/*#__PURE__*/ jsx(ListboxOption, {
63
+ value: option,
64
+ disabled: option.disabled,
65
+ as: "li",
66
+ className: ({ focus, selected, disabled: isDisabled })=>classnames('fwe-combobox-option', {
67
+ 'fwe-selected': selected,
68
+ 'fwe-focus': focus,
69
+ 'fwe-disabled': isDisabled
70
+ }),
71
+ children: option.label
72
+ }, String(option.data)))
73
+ }),
74
+ hint && !error && /*#__PURE__*/ jsx("div", {
75
+ className: "fwe-select-description",
76
+ children: hint
77
+ }),
78
+ error && /*#__PURE__*/ jsx("div", {
79
+ className: "fwe-select-invalid",
80
+ children: error
81
+ })
82
+ ]
83
+ })
92
84
  });
93
85
  }
94
86
  const Select = /*#__PURE__*/ forwardRef(SelectComponent);
package/dist/index.d.ts CHANGED
@@ -46,12 +46,12 @@ export { TabPane, type TabPaneProps } from './components/tab/tab-pane/TabPane';
46
46
  export { TableHeaderCell, type TableHeaderCellProps, } from './components/table-header-cell/TableHeaderCell';
47
47
  export { Checkbox, type CheckboxProps } from './forms/checkbox/Checkbox';
48
48
  export { ComboBox, type ComboBoxOption, type ComboBoxProps, } from './forms/combobox/ComboBox';
49
+ export { MultiSelect, type MultiSelectProps, } from './forms/multi-select/MultiSelect';
49
50
  export { RadioButton, type RadioButtonProps, } from './forms/radio/RadioButton';
50
51
  export { RadioGroup, type RadioGroupProps } from './forms/radio/RadioGroup';
51
52
  export { Segment, type SegmentConfiguration, type SegmentProps, } from './forms/segment/Segment';
52
53
  export { SegmentControl, type SegmentControlProps, } from './forms/segment/segment-control/SegmentControl';
53
- export { Select, type SelectProps } from './forms/select/Select';
54
- export { SelectOption, type SelectOptionProps, type SelectOptionType, } from './forms/select/select-option/SelectOption';
54
+ export { Select, type SelectOption, type SelectProps, } from './forms/select/Select';
55
55
  export { Slider, type SliderProps } from './forms/slider/Slider';
56
56
  export { Switch, type SwitchProps } from './forms/switch/Switch';
57
57
  export { TextArea, type TextAreaProps } from './forms/text-area/TextArea';
package/dist/index.js CHANGED
@@ -46,15 +46,15 @@ import { TabPane } from "./components/tab/tab-pane/TabPane.js";
46
46
  import { TableHeaderCell } from "./components/table-header-cell/TableHeaderCell.js";
47
47
  import { Checkbox } from "./forms/checkbox/Checkbox.js";
48
48
  import { ComboBox } from "./forms/combobox/ComboBox.js";
49
+ import { MultiSelect } from "./forms/multi-select/MultiSelect.js";
49
50
  import { RadioButton } from "./forms/radio/RadioButton.js";
50
51
  import { RadioGroup } from "./forms/radio/RadioGroup.js";
51
52
  import { Segment } from "./forms/segment/Segment.js";
52
53
  import { SegmentControl } from "./forms/segment/segment-control/SegmentControl.js";
53
54
  import { Select } from "./forms/select/Select.js";
54
- import { SelectOption } from "./forms/select/select-option/SelectOption.js";
55
55
  import { Slider } from "./forms/slider/Slider.js";
56
56
  import { Switch } from "./forms/switch/Switch.js";
57
57
  import { TextArea } from "./forms/text-area/TextArea.js";
58
58
  import { TextInput } from "./forms/text-input/TextInput.js";
59
59
  import { TimePicker } from "./forms/time-picker/TimePicker.js";
60
- export { Accordion, AccordionHeader, AccordionItem, AccordionItemBody, AccordionItemHeader, AlertModal, BottomSheet, Breadcrumb, Button, Card, CardBody, CardHeader, CardNotification, Checkbox, Chip, ChipContainer, ChipType, ComboBox, ConfirmModal, CustomModal, ImageGallery, ImageGalleryContent, ImageGallerySwiper, ImageGalleryThumbsSwiper, Legend, LoadingIndicator, MobileFlyout, MobileFlyoutItem, MobileFlyoutPage, Pagination, Popover, PopoverMenu, PopoverMenuContext, PopoverMenuItem, Progress, Prompt, RadioButton, RadioGroup, SearchInput, SearchSuggestion, Segment, SegmentControl, Select, SelectOption, Slider, Snackbar, SnackbarProvider, StepHorizontal, StepVertical, StepperHorizontal, StepperVertical, Switch, TabPane, TableHeaderCell, Tabs, TextArea, TextInput, TimePicker, Tooltip, addSnackbar, useSnackbar };
60
+ export { Accordion, AccordionHeader, AccordionItem, AccordionItemBody, AccordionItemHeader, AlertModal, BottomSheet, Breadcrumb, Button, Card, CardBody, CardHeader, CardNotification, Checkbox, Chip, ChipContainer, ChipType, ComboBox, ConfirmModal, CustomModal, ImageGallery, ImageGalleryContent, ImageGallerySwiper, ImageGalleryThumbsSwiper, Legend, LoadingIndicator, MobileFlyout, MobileFlyoutItem, MobileFlyoutPage, MultiSelect, Pagination, Popover, PopoverMenu, PopoverMenuContext, PopoverMenuItem, Progress, Prompt, RadioButton, RadioGroup, SearchInput, SearchSuggestion, Segment, SegmentControl, Select, Slider, Snackbar, SnackbarProvider, StepHorizontal, StepVertical, StepperHorizontal, StepperVertical, Switch, TabPane, TableHeaderCell, Tabs, TextArea, TextInput, TimePicker, Tooltip, addSnackbar, useSnackbar };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@festo-ui/react",
3
- "version": "9.0.1-dev.772",
3
+ "version": "9.0.1-dev.776",
4
4
  "author": "Festo UI (styleguide@festo.com)",
5
5
  "copyright": "Copyright (c) 2025 Festo SE & Co. KG. All rights reserved.",
6
6
  "license": "apache-2.0",