@centreon/ui 24.4.1-MON-21276.7 → 24.4.1-MON-32852.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "24.4.1-MON-21276.7",
3
+ "version": "24.4.1-MON-32852.0",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -2,7 +2,7 @@ import { any, isEmpty, isNil, not, or, pipe } from 'ramda';
2
2
  import { makeStyles } from 'tss-react/mui';
3
3
 
4
4
  import { Theme, Tooltip, TypographyProps } from '@mui/material';
5
- import { LoadingButton, LoadingButtonProps } from '@mui/lab';
5
+ import { LoadingButton } from '@mui/lab';
6
6
 
7
7
  import { getNormalizedId } from '../../utils';
8
8
 
@@ -15,7 +15,7 @@ const useStyles = makeStyles()((theme: Theme) => ({
15
15
  }
16
16
  }));
17
17
 
18
- interface Props {
18
+ interface Props extends Record<string, unknown> {
19
19
  className?: string;
20
20
  labelLoading?: string;
21
21
  labelProps?: TypographyProps;
@@ -50,7 +50,7 @@ const SaveButton = ({
50
50
  startIcon = true,
51
51
  labelProps,
52
52
  ...rest
53
- }: Props & LoadingButtonProps): JSX.Element => {
53
+ }: Props): JSX.Element => {
54
54
  const { classes, cx } = useStyles();
55
55
  const hasLabel = hasValue([labelLoading, labelSave, labelSucceeded]);
56
56
 
@@ -43,7 +43,7 @@ export type Props = {
43
43
  dialogTitleClassName?: string;
44
44
  labelCancel?: string | null;
45
45
  labelConfirm?: string | null;
46
- labelTitle?: ReactNode;
46
+ labelTitle?: string | null;
47
47
  onCancel?: () => void;
48
48
  onClose?: () => void;
49
49
  onConfirm: (event, value?) => void;
@@ -0,0 +1,85 @@
1
+ import NumberField, { NumberProps } from './Number';
2
+
3
+ const initialize = (props: NumberProps): void => {
4
+ cy.mount({
5
+ Component: <NumberField {...props} />
6
+ });
7
+ };
8
+
9
+ describe('Number field', () => {
10
+ it('displays the placeholder when the field has no default or fallback values', () => {
11
+ initialize({ dataTestId: 'test', onChange: cy.stub() });
12
+
13
+ cy.get('input').should('have.value', '');
14
+ cy.get('input').should('have.attr', 'placeholder', '0');
15
+
16
+ cy.makeSnapshot();
17
+ });
18
+
19
+ it('displays the fallback value as placeholder when the field as no default value', () => {
20
+ initialize({ dataTestId: 'test', fallbackValue: 25, onChange: cy.stub() });
21
+
22
+ cy.get('input').should('have.value', '');
23
+ cy.get('input').should('have.attr', 'placeholder', '25');
24
+
25
+ cy.makeSnapshot();
26
+ });
27
+
28
+ it('displays the default value as placeholder when the field as default value', () => {
29
+ initialize({ dataTestId: 'test', defaultValue: 25, onChange: cy.stub() });
30
+
31
+ cy.get('input').should('have.value', '25');
32
+
33
+ cy.makeSnapshot();
34
+ });
35
+
36
+ it('displays the fallback value when the field is cleared out', () => {
37
+ initialize({
38
+ dataTestId: 'test',
39
+ defaultValue: 25,
40
+ fallbackValue: 10,
41
+ onChange: cy.stub()
42
+ });
43
+
44
+ cy.get('input').should('have.value', '25');
45
+ cy.get('input').clear();
46
+ cy.get('input').should('have.value', '');
47
+ cy.get('input').should('have.attr', 'placeholder', '10');
48
+
49
+ cy.makeSnapshot();
50
+ });
51
+
52
+ it('displays the field using auto size', () => {
53
+ initialize({
54
+ autoSize: true,
55
+ dataTestId: 'test',
56
+ defaultValue: 25,
57
+ onChange: cy.stub()
58
+ });
59
+
60
+ cy.get('input').should('have.value', '25');
61
+
62
+ cy.get('input').type('0');
63
+
64
+ cy.makeSnapshot();
65
+ });
66
+
67
+ it('sets the value to the minimum value configured when a value less than the minimum value is typed in the field', () => {
68
+ initialize({
69
+ dataTestId: 'test',
70
+ defaultValue: 25,
71
+ inputProps: {
72
+ min: 2
73
+ },
74
+ onChange: cy.stub()
75
+ });
76
+
77
+ cy.get('input').should('have.value', '25');
78
+
79
+ cy.get('input').clear().type('-1');
80
+
81
+ cy.get('input').should('have.value', '2');
82
+
83
+ cy.makeSnapshot();
84
+ });
85
+ });
@@ -0,0 +1,66 @@
1
+ /* eslint-disable no-console */
2
+ import { Meta, StoryObj } from '@storybook/react';
3
+
4
+ import NumberField from './Number';
5
+
6
+ const meta: Meta<typeof NumberField> = {
7
+ argTypes: {
8
+ defaultValue: {
9
+ defaultValue: 0,
10
+ description:
11
+ 'The initial value which will be used by the input for the first render',
12
+ type: 'number'
13
+ },
14
+ fallbackValue: {
15
+ defaultValue: 0,
16
+ description: 'This value will be used when the input is cleared',
17
+ type: 'number'
18
+ },
19
+ onChange: {
20
+ description:
21
+ 'The change function with the actual value as parameter. This parameter will be the value when the input is filled but it will be the fallbackValue when the input is cleared out',
22
+ type: 'function'
23
+ }
24
+ },
25
+ component: NumberField
26
+ };
27
+
28
+ export default meta;
29
+ type Story = StoryObj<typeof NumberField>;
30
+
31
+ export const Default: Story = {
32
+ args: {
33
+ onChange: console.log
34
+ }
35
+ };
36
+
37
+ export const WithDefaultValue: Story = {
38
+ args: {
39
+ defaultValue: 25,
40
+ onChange: console.log
41
+ }
42
+ };
43
+
44
+ export const WithFallbackValue: Story = {
45
+ args: {
46
+ fallbackValue: 25,
47
+ onChange: console.log
48
+ }
49
+ };
50
+
51
+ export const WithFallbackValueAndDefaultValue: Story = {
52
+ args: {
53
+ defaultValue: 10,
54
+ fallbackValue: 25,
55
+ onChange: console.log
56
+ }
57
+ };
58
+
59
+ export const WithFallbackValueAndDefaultValueAutoSize: Story = {
60
+ args: {
61
+ autoSize: true,
62
+ defaultValue: 10,
63
+ fallbackValue: 25,
64
+ onChange: console.log
65
+ }
66
+ };
@@ -0,0 +1,74 @@
1
+ import { ChangeEvent, useState } from 'react';
2
+
3
+ import { T, always, cond, isEmpty, isNil } from 'ramda';
4
+
5
+ import TextField, { TextProps } from '../Text';
6
+
7
+ export interface NumberProps
8
+ extends Omit<TextProps, 'defaultValue' | 'onChange'> {
9
+ /**
10
+ * The initial value which will be used by the input for the first render
11
+ */
12
+ defaultValue?: number;
13
+ /**
14
+ * This value will be used when the input is cleared
15
+ */
16
+ fallbackValue?: number;
17
+ /**
18
+ * The change function with the actual value as parameter. This parameter will be the value when the input is filled but it will be the fallbackValue when the input is cleared out
19
+ */
20
+ onChange: (actualValue: number) => void;
21
+ }
22
+
23
+ const NumberField = ({
24
+ fallbackValue = 0,
25
+ defaultValue,
26
+ onChange,
27
+ ...props
28
+ }: NumberProps): JSX.Element => {
29
+ const [placeholder, setPlaceholder] = useState<string | undefined>();
30
+ const [actualValue, setActualValue] = useState(
31
+ defaultValue ? `${defaultValue}` : ''
32
+ );
33
+
34
+ const { inputProps } = props;
35
+
36
+ const changeValue = (event: ChangeEvent<HTMLInputElement>): void => {
37
+ const inputValue = event.target.value;
38
+
39
+ const number = Number(inputValue);
40
+ const campledNumber = cond([
41
+ [() => isEmpty(inputValue), always(fallbackValue)],
42
+ [() => Number.isNaN(number), always(number)],
43
+ [
44
+ T,
45
+ always(
46
+ Math.max(
47
+ !isNil(inputProps?.min) ? inputProps?.min : -Infinity,
48
+ number
49
+ )
50
+ )
51
+ ]
52
+ ])();
53
+
54
+ onChange(campledNumber);
55
+ setPlaceholder(isEmpty(inputValue) ? `${fallbackValue}` : undefined);
56
+ setActualValue(isEmpty(inputValue) ? inputValue : `${campledNumber}`);
57
+ };
58
+
59
+ return (
60
+ <TextField
61
+ defaultValue={defaultValue}
62
+ type="number"
63
+ value={actualValue}
64
+ onChange={changeValue}
65
+ {...props}
66
+ inputProps={inputProps}
67
+ placeholder={
68
+ placeholder || (!defaultValue ? `${fallbackValue}` : undefined)
69
+ }
70
+ />
71
+ );
72
+ };
73
+
74
+ export default NumberField;
@@ -1,8 +1,8 @@
1
1
  import IconSearch from '@mui/icons-material/Search';
2
2
 
3
- import TextField, { Props as TextFieldProps } from '../Text';
3
+ import TextField, { TextProps } from '../Text';
4
4
 
5
- type Props = Omit<TextFieldProps, 'StartAdornment'>;
5
+ type Props = Omit<TextProps, 'StartAdornment'>;
6
6
 
7
7
  const SearchAdornment = (): JSX.Element => <IconSearch />;
8
8
 
@@ -141,132 +141,126 @@ type Multiple = boolean;
141
141
  type DisableClearable = boolean;
142
142
  type FreeSolo = boolean;
143
143
 
144
- const AutocompleteField = React.forwardRef(
145
- (
146
- {
147
- options,
148
- label,
149
- placeholder,
150
- loading = false,
151
- onTextChange = (): void => undefined,
152
- endAdornment = undefined,
153
- inputValue,
154
- displayOptionThumbnail = false,
155
- required = false,
156
- error,
157
- displayPopupIcon = true,
158
- autoFocus = false,
159
- hideInput = false,
160
- dataTestId,
161
- autoSize = false,
162
- autoSizeDefaultWidth = 0,
163
- autoSizeCustomPadding,
164
- getOptionItemLabel = (option) => option.name,
165
- ...autocompleteProps
166
- }: Props,
167
- ref?: React.ForwardedRef<HTMLDivElement>
168
- ): JSX.Element => {
169
- const { classes, cx } = useStyles({ hideInput });
170
- const { t } = useTranslation();
171
- const theme = useTheme();
144
+ const AutocompleteField = ({
145
+ options,
146
+ label,
147
+ placeholder,
148
+ loading = false,
149
+ onTextChange = (): void => undefined,
150
+ endAdornment = undefined,
151
+ inputValue,
152
+ displayOptionThumbnail = false,
153
+ required = false,
154
+ error,
155
+ displayPopupIcon = true,
156
+ autoFocus = false,
157
+ hideInput = false,
158
+ dataTestId,
159
+ autoSize = false,
160
+ autoSizeDefaultWidth = 0,
161
+ autoSizeCustomPadding,
162
+ getOptionItemLabel = (option) => option.name,
163
+ ...autocompleteProps
164
+ }: Props): JSX.Element => {
165
+ const { classes, cx } = useStyles({ hideInput });
166
+ const { t } = useTranslation();
167
+ const theme = useTheme();
172
168
 
173
- const areSelectEntriesEqual = (option, value): boolean => {
174
- const identifyingProps = ['id', 'name'];
169
+ const areSelectEntriesEqual = (option, value): boolean => {
170
+ const identifyingProps = ['id', 'name'];
175
171
 
176
- return equals(
177
- pick(identifyingProps, option),
178
- pick(identifyingProps, value)
179
- );
180
- };
181
-
182
- const renderInput = (params): JSX.Element => (
183
- <TextField
184
- {...params}
185
- InputLabelProps={{
186
- classes: {
187
- marginDense: classes.inputLabel,
188
- shrink: classes.inputLabelShrink
189
- }
190
- }}
191
- InputProps={{
192
- ...params.InputProps,
193
- endAdornment: (
194
- <>
195
- {endAdornment && (
196
- <InputAdornment position="end">{endAdornment}</InputAdornment>
197
- )}
198
- {params.InputProps.endAdornment}
199
- </>
200
- ),
201
- style: {
202
- background: 'transparent',
203
- paddingRight: theme.spacing(5)
204
- }
205
- }}
206
- autoFocus={autoFocus}
207
- autoSize={autoSize}
208
- autoSizeCustomPadding={7 + (autoSizeCustomPadding || 0)}
209
- autoSizeDefaultWidth={autoSizeDefaultWidth}
210
- classes={{
211
- root: classes.textfield
212
- }}
213
- error={error}
214
- externalValueForAutoSize={autocompleteProps?.value?.name}
215
- inputProps={{
216
- ...params.inputProps,
217
- 'aria-label': label,
218
- 'data-testid': dataTestId || label,
219
- id: getNormalizedId(label || '')
220
- }}
221
- label={label}
222
- placeholder={isNil(placeholder) ? t(searchLabel) : placeholder}
223
- required={required}
224
- value={inputValue || undefined}
225
- onChange={onTextChange}
226
- />
172
+ return equals(
173
+ pick(identifyingProps, option),
174
+ pick(identifyingProps, value)
227
175
  );
176
+ };
228
177
 
229
- return (
230
- <Autocomplete
231
- disableClearable
232
- classes={{
233
- groupLabel: classes.inputLabel,
234
- inputRoot: cx([
235
- classes.input,
236
- label ? classes.inputWithLabel : classes.inputWithoutLabel
237
- ]),
238
- popper: classes.popper,
239
- root: classes.textfield
240
- }}
241
- forcePopupIcon={displayPopupIcon}
242
- getOptionLabel={(option): string =>
243
- (option as SelectEntry)?.name?.toString() || ''
178
+ const renderInput = (params): JSX.Element => (
179
+ <TextField
180
+ {...params}
181
+ InputLabelProps={{
182
+ classes: {
183
+ marginDense: classes.inputLabel,
184
+ shrink: classes.inputLabelShrink
185
+ }
186
+ }}
187
+ InputProps={{
188
+ ...params.InputProps,
189
+ endAdornment: (
190
+ <>
191
+ {endAdornment && (
192
+ <InputAdornment position="end">{endAdornment}</InputAdornment>
193
+ )}
194
+ {params.InputProps.endAdornment}
195
+ </>
196
+ ),
197
+ style: {
198
+ background: 'transparent',
199
+ paddingRight: theme.spacing(5)
244
200
  }
245
- isOptionEqualToValue={areSelectEntriesEqual}
246
- loading={loading}
247
- loadingText={<LoadingIndicator />}
248
- options={options}
249
- ref={ref}
250
- renderInput={renderInput}
251
- renderOption={(props, option): JSX.Element => {
252
- return (
253
- <li
254
- className={classes.options}
255
- {...(props as React.HTMLAttributes<HTMLLIElement>)}
201
+ }}
202
+ autoFocus={autoFocus}
203
+ autoSize={autoSize}
204
+ autoSizeCustomPadding={7 + (autoSizeCustomPadding || 0)}
205
+ autoSizeDefaultWidth={autoSizeDefaultWidth}
206
+ classes={{
207
+ root: classes.textfield
208
+ }}
209
+ error={error}
210
+ externalValueForAutoSize={autocompleteProps?.value?.name}
211
+ inputProps={{
212
+ ...params.inputProps,
213
+ 'aria-label': label,
214
+ 'data-testid': dataTestId || label,
215
+ id: getNormalizedId(label || '')
216
+ }}
217
+ label={label}
218
+ placeholder={isNil(placeholder) ? t(searchLabel) : placeholder}
219
+ required={required}
220
+ value={inputValue || undefined}
221
+ onChange={onTextChange}
222
+ />
223
+ );
224
+
225
+ return (
226
+ <Autocomplete
227
+ disableClearable
228
+ classes={{
229
+ groupLabel: classes.inputLabel,
230
+ inputRoot: cx([
231
+ classes.input,
232
+ label ? classes.inputWithLabel : classes.inputWithoutLabel
233
+ ]),
234
+ popper: classes.popper,
235
+ root: classes.textfield
236
+ }}
237
+ forcePopupIcon={displayPopupIcon}
238
+ getOptionLabel={(option): string =>
239
+ (option as SelectEntry)?.name?.toString() || ''
240
+ }
241
+ isOptionEqualToValue={areSelectEntriesEqual}
242
+ loading={loading}
243
+ loadingText={<LoadingIndicator />}
244
+ options={options}
245
+ renderInput={renderInput}
246
+ renderOption={(props, option): JSX.Element => {
247
+ return (
248
+ <li
249
+ className={classes.options}
250
+ {...(props as React.HTMLAttributes<HTMLLIElement>)}
251
+ >
252
+ <Option
253
+ thumbnailUrl={displayOptionThumbnail ? option.url : undefined}
256
254
  >
257
- <Option
258
- thumbnailUrl={displayOptionThumbnail ? option.url : undefined}
259
- >
260
- {getOptionItemLabel(option)}
261
- </Option>
262
- </li>
263
- );
264
- }}
265
- size="small"
266
- {...autocompleteProps}
267
- />
268
- );
269
- }
270
- );
255
+ {getOptionItemLabel(option)}
256
+ </Option>
257
+ </li>
258
+ );
259
+ }}
260
+ size="small"
261
+ {...autocompleteProps}
262
+ />
263
+ );
264
+ };
271
265
 
272
266
  export default AutocompleteField;
@@ -17,38 +17,36 @@ import { getNormalizedId } from '../../utils';
17
17
 
18
18
  import useAutoSize from './useAutoSize';
19
19
 
20
- const useStyles = makeStyles<{ displayAsBlock: boolean }>()(
21
- (theme: Theme, { displayAsBlock }) => ({
22
- autoSizeCompact: {
23
- paddingRight: theme.spacing(1),
24
- paddingTop: theme.spacing(0.6)
25
- },
26
- hiddenText: {
27
- display: 'table',
28
- lineHeight: 0,
29
- transform: 'scaleY(0)'
30
- },
31
- input: {
32
- fontSize: theme.typography.body1.fontSize
33
- },
34
- inputBase: {
35
- display: displayAsBlock ? 'block' : 'inline-flex',
36
- justifyItems: 'start',
37
- paddingRight: theme.spacing(1)
38
- },
39
- noLabelInput: {
40
- padding: theme.spacing(1)
41
- },
42
- textField: {
43
- transition: theme.transitions.create(['width'], {
44
- duration: theme.transitions.duration.shortest
45
- })
46
- },
47
- transparent: {
48
- backgroundColor: 'transparent'
49
- }
50
- })
51
- );
20
+ const useStyles = makeStyles()((theme: Theme) => ({
21
+ autoSizeCompact: {
22
+ paddingRight: theme.spacing(1),
23
+ paddingTop: theme.spacing(0.6)
24
+ },
25
+ hiddenText: {
26
+ display: 'table',
27
+ lineHeight: 0,
28
+ transform: 'scaleY(0)'
29
+ },
30
+ input: {
31
+ fontSize: theme.typography.body1.fontSize
32
+ },
33
+ inputBase: {
34
+ display: 'inline-flex',
35
+ justifyItems: 'start',
36
+ paddingRight: theme.spacing(1)
37
+ },
38
+ noLabelInput: {
39
+ padding: theme.spacing(1)
40
+ },
41
+ textField: {
42
+ transition: theme.transitions.create(['width'], {
43
+ duration: theme.transitions.duration.shortest
44
+ })
45
+ },
46
+ transparent: {
47
+ backgroundColor: 'transparent'
48
+ }
49
+ }));
52
50
 
53
51
  interface OptionalLabelInputAdornmentProps {
54
52
  children: React.ReactNode;
@@ -72,7 +70,7 @@ const OptionalLabelInputAdornment = ({
72
70
 
73
71
  type SizeVariant = 'large' | 'medium' | 'small' | 'compact';
74
72
 
75
- export type Props = {
73
+ export type TextProps = {
76
74
  EndAdornment?: React.FC;
77
75
  StartAdornment?: React.FC;
78
76
  ariaLabel?: string;
@@ -114,17 +112,18 @@ const TextField = forwardRef(
114
112
  defaultValue,
115
113
  required = false,
116
114
  containerClassName,
115
+ type,
117
116
  ...rest
118
- }: Props,
117
+ }: TextProps,
119
118
  ref: React.ForwardedRef<HTMLDivElement>
120
119
  ): JSX.Element => {
121
- const { classes, cx } = useStyles({
122
- displayAsBlock: autoSize && isNil(StartAdornment) && isNil(EndAdornment)
123
- });
120
+ const { classes, cx } = useStyles();
124
121
 
125
122
  const { inputRef, width, changeInputValue, innerValue } = useAutoSize({
126
123
  autoSize,
127
- autoSizeCustomPadding,
124
+ autoSizeCustomPadding: equals(type, 'number')
125
+ ? Math.max(6, autoSizeCustomPadding || 0)
126
+ : autoSizeCustomPadding,
128
127
  autoSizeDefaultWidth,
129
128
  value: externalValueForAutoSize || rest.value
130
129
  });
@@ -155,9 +154,9 @@ const TextField = forwardRef(
155
154
  helperText={displayErrorInTooltip ? undefined : error}
156
155
  id={getNormalizedId(dataTestId || '')}
157
156
  inputProps={{
157
+ ...rest.inputProps,
158
158
  'aria-label': ariaLabel,
159
- 'data-testid': dataTestId,
160
- ...rest.inputProps
159
+ 'data-testid': dataTestId
161
160
  }}
162
161
  label={label}
163
162
  ref={ref}
@@ -196,6 +195,7 @@ const TextField = forwardRef(
196
195
  width: autoSize ? width : undefined,
197
196
  ...rest?.sx
198
197
  }}
198
+ type={type}
199
199
  />
200
200
  </Tooltip>
201
201
  {autoSize && (
@@ -4,11 +4,7 @@ import dayjs, { Dayjs } from 'dayjs';
4
4
  import { useAtomValue } from 'jotai';
5
5
  import { equals } from 'ramda';
6
6
 
7
- import {
8
- DateTimePicker,
9
- DateTimePickerProps,
10
- LocalizationProvider
11
- } from '@mui/x-date-pickers';
7
+ import { DateTimePicker, LocalizationProvider } from '@mui/x-date-pickers';
12
8
  import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
13
9
 
14
10
  import { userAtom } from '@centreon/ui-context';
@@ -27,7 +23,6 @@ interface Props {
27
23
  disabled?: boolean;
28
24
  maxDate?: Date;
29
25
  minDate?: Date;
30
- minDateTime?: Date;
31
26
  property: CustomTimePeriodProperty | string;
32
27
  }
33
28
 
@@ -35,13 +30,11 @@ const DateTimePickerInput = ({
35
30
  date,
36
31
  maxDate,
37
32
  minDate,
38
- minDateTime,
39
33
  property,
40
34
  changeDate,
41
35
  disabled = false,
42
- desktopMediaQuery,
43
- ...rest
44
- }: Props & DateTimePickerProps<dayjs.Dayjs>): JSX.Element => {
36
+ desktopMediaQuery
37
+ }: Props): JSX.Element => {
45
38
  const desktopPickerMediaQuery =
46
39
  '@media (min-width: 1024px) or (pointer: fine)';
47
40
 
@@ -74,10 +67,8 @@ const DateTimePickerInput = ({
74
67
  disabled={disabled}
75
68
  maxDate={maxDate && formatDate(maxDate)}
76
69
  minDate={minDate && formatDate(minDate)}
77
- minDateTime={minDateTime && formatDate(minDateTime)}
78
70
  value={formatDate(date)}
79
71
  onChange={changeTime}
80
- {...rest}
81
72
  />
82
73
  </LocalizationProvider>
83
74
  );
package/src/index.ts CHANGED
@@ -23,6 +23,7 @@ export { default as RegexpHelpTooltip } from './InputField/Search/RegexpHelpTool
23
23
 
24
24
  export { default as TextField } from './InputField/Text';
25
25
  export type { Props as TextFieldProps } from './InputField/Text';
26
+ export { default as NumberField } from './InputField/Number/Number';
26
27
 
27
28
  export type { SelectEntry } from './InputField/Select';
28
29
  export { default as SelectField } from './InputField/Select';