@festo-ui/react 9.0.1-dev.763 → 9.0.1-dev.766

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.
@@ -46,7 +46,7 @@
46
46
 
47
47
  .fr-combobox-button {
48
48
  cursor: pointer;
49
- background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgyNHYyNEgweiIgZGF0YS1uYW1lPSJ3aGl0ZSBiYWNrZ3JvdW5kIi8+PHBhdGggZmlsbD0iIzMzMyIgZD0iTTUuNjM2IDkuMTcyIDEyIDE1LjUzNmw2LjM2NC02LjM2NC0uNzA3LS43MDhMMTIgMTQuMTIxIDYuMzQzIDguNDY0bC0uNzA3LjcwOHoiIGRhdGEtbmFtZT0iY29udGVudCIvPjwvc3ZnPg==) center / 24px 24px no-repeat;
49
+ background-color: var(--fwe-text);
50
50
  border: none;
51
51
  width: 24px;
52
52
  height: 24px;
@@ -55,10 +55,11 @@
55
55
  top: 50%;
56
56
  right: 0;
57
57
  transform: translateY(-50%);
58
+ mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgyNHYyNEgweiIgZGF0YS1uYW1lPSJ3aGl0ZSBiYWNrZ3JvdW5kIi8+PHBhdGggZmlsbD0iIzMzMyIgZD0iTTUuNjM2IDkuMTcyIDEyIDE1LjUzNmw2LjM2NC02LjM2NC0uNzA3LS43MDhMMTIgMTQuMTIxIDYuMzQzIDguNDY0bC0uNzA3LjcwOHoiIGRhdGEtbmFtZT0iY29udGVudCIvPjwvc3ZnPg==) center / 24px 24px no-repeat;
58
59
  }
59
60
 
60
- .fr-combobox-button:hover {
61
- background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgyNHYyNEgweiIgZGF0YS1uYW1lPSJ3aGl0ZSBiYWNrZ3JvdW5kIi8+PHBhdGggZmlsbD0iIzAwOTFkYyIgZD0iTTUuNjM2IDkuMTcyIDEyIDE1LjUzNmw2LjM2NC02LjM2NC0uNzA3LS43MDhMMTIgMTQuMTIxIDYuMzQzIDguNDY0bC0uNzA3LjcwOHoiIGRhdGEtbmFtZT0iY29udGVudCIvPjwvc3ZnPg==) center / 24px 24px no-repeat;
61
+ .fr-combobox-button[aria-expanded="true"] {
62
+ transform: translateY(-50%)rotate(180deg);
62
63
  }
63
64
 
64
65
  .fr-combobox-description, .fr-combobox-invalid {
@@ -88,6 +89,11 @@
88
89
  color: var(--fwe-text-disabled);
89
90
  }
90
91
 
92
+ .fr-combobox-wrapper.fr-disabled .fr-combobox-button {
93
+ background-color: var(--fwe-text-disabled);
94
+ cursor: default;
95
+ }
96
+
91
97
  .fr-combobox-wrapper.fr-invalid .fr-combobox-input {
92
98
  border-color: var(--fwe-red);
93
99
  }
@@ -101,10 +107,10 @@
101
107
  }
102
108
 
103
109
  .fr-combobox-options-container {
104
- min-width: var(--input-width, 100%);
105
110
  background-color: var(--fwe-white);
106
111
  border: 1px solid var(--fwe-gray-200);
107
112
  border-radius: 4px;
113
+ max-width: 100%;
108
114
  margin: 0;
109
115
  padding: 8px;
110
116
  list-style: none;
@@ -119,7 +125,7 @@
119
125
  position: relative;
120
126
  }
121
127
 
122
- .fr-combobox-option:hover, .fr-combobox-option:focus {
128
+ .fr-combobox-option:hover, .fr-combobox-option.fr-focus, .fr-combobox-option.fr-selected {
123
129
  background-color: var(--fwe-gray-100);
124
130
  outline: none;
125
131
  }
@@ -133,6 +139,10 @@
133
139
  cursor: default;
134
140
  }
135
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
+
136
146
  .fr-combobox-option-content {
137
147
  white-space: nowrap;
138
148
  text-overflow: ellipsis;
@@ -1,15 +1,16 @@
1
1
  import './ComboBox.scss';
2
- import { type ComponentPropsWithoutRef, type Ref } from 'react';
3
- export interface ComboBoxOptionType<T> {
2
+ import { type Ref } from 'react';
3
+ import type { ComponentBase } from '../../utils/types';
4
+ export interface ComboBoxOption<T> {
4
5
  readonly label: string;
5
6
  readonly data: T;
6
7
  readonly disabled?: boolean;
7
8
  }
8
- export interface ComboBoxProps<T> extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue'> {
9
+ export interface ComboBoxProps<T> extends ComponentBase {
9
10
  readonly defaultValue?: T;
10
11
  readonly value?: T;
11
12
  readonly label?: string;
12
- readonly options?: ComboBoxOptionType<T>[];
13
+ readonly options?: ComboBoxOption<T>[];
13
14
  readonly required?: boolean;
14
15
  readonly onChange?: (value: T) => void;
15
16
  readonly disabled?: boolean;
@@ -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, useState } from "react";
5
+ import { forwardRef, useMemo, useRef, 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,13 +39,14 @@ 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);
42
43
  const [value, setValue] = useControlled({
43
44
  controlled,
44
45
  default: defaultValue,
45
46
  onChange
46
47
  });
47
48
  const [query, setQuery] = useState('');
48
- const selectedOption = useMemo(()=>options.find((option)=>option.data === value), [
49
+ const selectedOption = useMemo(()=>options.find((option)=>option.data === value && !option.disabled), [
49
50
  options,
50
51
  value
51
52
  ]);
@@ -57,8 +58,8 @@ function ComboBoxComponent({ defaultValue = '', value: controlled, label, option
57
58
  options,
58
59
  query
59
60
  ]);
60
- function handleSelect(option) {
61
- if (!option) return;
61
+ function handleChange(option) {
62
+ if (!option || option.disabled) return;
62
63
  setValue(option.data);
63
64
  setQuery('');
64
65
  }
@@ -74,15 +75,15 @@ function ComboBoxComponent({ defaultValue = '', value: controlled, label, option
74
75
  });
75
76
  return /*#__PURE__*/ jsx(Combobox, {
76
77
  value: selectedOption ?? null,
77
- onChange: handleSelect,
78
+ onChange: handleChange,
78
79
  disabled: disabled,
79
80
  immediate: true,
80
81
  children: /*#__PURE__*/ jsxs("div", {
81
- className: classnames('fr-combobox-wrapper', {
82
+ className: classnames(className, 'fr-combobox-wrapper', {
82
83
  'fr-disabled': disabled,
83
84
  'fr-invalid': error,
84
85
  'fr-required': required
85
- }, className),
86
+ }),
86
87
  ref: ref,
87
88
  ...props,
88
89
  children: [
@@ -93,6 +94,7 @@ function ComboBoxComponent({ defaultValue = '', value: controlled, label, option
93
94
  }),
94
95
  /*#__PURE__*/ jsxs("div", {
95
96
  className: "fr-combobox-control",
97
+ ref: controlRef,
96
98
  children: [
97
99
  /*#__PURE__*/ jsx(ComboboxInput, {
98
100
  className: inputClasses,
@@ -107,13 +109,15 @@ function ComboBoxComponent({ defaultValue = '', value: controlled, label, option
107
109
  }),
108
110
  /*#__PURE__*/ jsx(ComboboxButton, {
109
111
  className: "fr-combobox-button",
112
+ disabled: disabled,
110
113
  "aria-label": "Optionen anzeigen"
111
114
  })
112
115
  ]
113
116
  }),
114
117
  /*#__PURE__*/ jsxs(ComboboxOptions, {
115
- className: classnames('fr-combobox-options-container', 'fr-combobox-options'),
118
+ className: "fr-combobox-options-container",
116
119
  as: "ul",
120
+ portal: false,
117
121
  anchor: {
118
122
  to: 'bottom start',
119
123
  gap: 20,
@@ -133,7 +137,7 @@ function ComboBoxComponent({ defaultValue = '', value: controlled, label, option
133
137
  as: "li",
134
138
  className: ({ focus, selected, disabled: isDisabled })=>classnames('fr-combobox-option', {
135
139
  'fr-selected': selected,
136
- 'fr-active': focus,
140
+ 'fr-focus': focus,
137
141
  'fr-disabled': isDisabled
138
142
  }),
139
143
  children: /*#__PURE__*/ jsx("span", {
package/dist/index.d.ts CHANGED
@@ -45,8 +45,8 @@ export { type TabItemAppearance, Tabs, type TabsConfiguration, type TabsProps, t
45
45
  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
- export { ComboBox, type ComboBoxOptionType, type ComboBoxProps, } from './forms/combobox/ComboBox';
49
- export { RadioButton, type RadioButtonProps as RadioProps, } from './forms/radio/RadioButton';
48
+ export { ComboBox, type ComboBoxOption, type ComboBoxProps, } from './forms/combobox/ComboBox';
49
+ export { RadioButton, type RadioButtonProps, } from './forms/radio/RadioButton';
50
50
  export { RadioGroup, type RadioGroupProps } from './forms/radio/RadioGroup';
51
51
  export { Segment, type SegmentConfiguration, type SegmentProps, } from './forms/segment/Segment';
52
52
  export { SegmentControl, type SegmentControlProps, } from './forms/segment/segment-control/SegmentControl';
@@ -1,3 +1,10 @@
1
+ import type { CSSProperties } from 'react';
2
+ export interface ComponentBase {
3
+ className?: string;
4
+ style?: CSSProperties;
5
+ 'data-testid'?: string;
6
+ id?: string;
7
+ }
1
8
  export interface ClassNameProps {
2
9
  className?: string;
3
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@festo-ui/react",
3
- "version": "9.0.1-dev.763",
3
+ "version": "9.0.1-dev.766",
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",
@@ -84,7 +84,7 @@
84
84
  },
85
85
  "peerDependencies": {
86
86
  "@festo-ui/web-essentials": "*",
87
- "react": ">=17.0.0",
88
- "react-dom": ">=17.0.0"
87
+ "react": ">=18.0.0",
88
+ "react-dom": ">=18.0.0"
89
89
  }
90
90
  }