ding-react-admin 1.0.2 → 1.0.4

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 (86) hide show
  1. package/README.md +36 -5
  2. package/dist/index.js +712 -723
  3. package/dist/src/crud/InlineFormSet.d.ts +13 -11
  4. package/dist/src/crud/InlineFormSet.d.ts.map +1 -1
  5. package/dist/src/crud/ResourceForm.d.ts +10 -2
  6. package/dist/src/crud/ResourceForm.d.ts.map +1 -1
  7. package/dist/src/crud/ResourceFormModal.d.ts.map +1 -1
  8. package/dist/src/crud/ResourceList.d.ts.map +1 -1
  9. package/dist/src/crud/context/SubmitFieldsContext.d.ts +18 -0
  10. package/dist/src/crud/context/SubmitFieldsContext.d.ts.map +1 -0
  11. package/dist/src/crud/fields/BooleanField.d.ts +3 -1
  12. package/dist/src/crud/fields/BooleanField.d.ts.map +1 -1
  13. package/dist/src/crud/fields/DateField.d.ts +3 -1
  14. package/dist/src/crud/fields/DateField.d.ts.map +1 -1
  15. package/dist/src/crud/fields/FieldWrapper.d.ts +7 -14
  16. package/dist/src/crud/fields/FieldWrapper.d.ts.map +1 -1
  17. package/dist/src/crud/fields/NumberField.d.ts +5 -3
  18. package/dist/src/crud/fields/NumberField.d.ts.map +1 -1
  19. package/dist/src/crud/fields/PasswordField.d.ts +5 -3
  20. package/dist/src/crud/fields/PasswordField.d.ts.map +1 -1
  21. package/dist/src/crud/fields/ReferenceField.d.ts +6 -5
  22. package/dist/src/crud/fields/ReferenceField.d.ts.map +1 -1
  23. package/dist/src/crud/fields/ReferenceManyField.d.ts +3 -1
  24. package/dist/src/crud/fields/ReferenceManyField.d.ts.map +1 -1
  25. package/dist/src/crud/fields/SelectField.d.ts +3 -1
  26. package/dist/src/crud/fields/SelectField.d.ts.map +1 -1
  27. package/dist/src/crud/fields/TextField.d.ts +5 -3
  28. package/dist/src/crud/fields/TextField.d.ts.map +1 -1
  29. package/dist/src/crud/index.d.ts +8 -4
  30. package/dist/src/crud/index.d.ts.map +1 -1
  31. package/dist/src/crud/types.d.ts +21 -20
  32. package/dist/src/crud/types.d.ts.map +1 -1
  33. package/dist/src/crud/utils/inlineFieldName.d.ts +3 -0
  34. package/dist/src/crud/utils/inlineFieldName.d.ts.map +1 -0
  35. package/dist/src/crud/utils/useAbortableEffect.d.ts +7 -0
  36. package/dist/src/crud/utils/useAbortableEffect.d.ts.map +1 -0
  37. package/dist/src/crud/utils/useResourceFormData.d.ts +47 -0
  38. package/dist/src/crud/utils/useResourceFormData.d.ts.map +1 -0
  39. package/dist/src/data/abortError.d.ts +3 -0
  40. package/dist/src/data/abortError.d.ts.map +1 -0
  41. package/dist/src/data/abortError.test.d.ts +2 -0
  42. package/dist/src/data/abortError.test.d.ts.map +1 -0
  43. package/dist/src/data/createRestResourceHandlers.d.ts +2 -2
  44. package/dist/src/data/createRestResourceHandlers.d.ts.map +1 -1
  45. package/dist/src/data/dataProviderTypes.d.ts +7 -1
  46. package/dist/src/data/dataProviderTypes.d.ts.map +1 -1
  47. package/dist/src/data/resourceHandlers.d.ts +2 -2
  48. package/dist/src/data/resourceHandlers.d.ts.map +1 -1
  49. package/dist/src/index.d.ts +4 -3
  50. package/dist/src/index.d.ts.map +1 -1
  51. package/package.json +59 -59
  52. package/src/crud/InlineFormSet.tsx +77 -89
  53. package/src/crud/ResourceForm.tsx +87 -202
  54. package/src/crud/ResourceFormModal.tsx +37 -25
  55. package/src/crud/ResourceList.tsx +35 -26
  56. package/src/crud/context/SubmitFieldsContext.tsx +62 -0
  57. package/src/crud/fields/BooleanField.tsx +22 -16
  58. package/src/crud/fields/DateField.tsx +32 -26
  59. package/src/crud/fields/FieldWrapper.tsx +32 -54
  60. package/src/crud/fields/NumberField.tsx +36 -34
  61. package/src/crud/fields/PasswordField.tsx +41 -40
  62. package/src/crud/fields/ReferenceField.tsx +35 -130
  63. package/src/crud/fields/ReferenceManyField.tsx +31 -25
  64. package/src/crud/fields/SelectField.tsx +6 -0
  65. package/src/crud/fields/TextField.tsx +32 -30
  66. package/src/crud/index.ts +19 -2
  67. package/src/crud/types.ts +132 -130
  68. package/src/crud/utils/inlineFieldName.ts +8 -0
  69. package/src/crud/utils/useAbortableEffect.ts +17 -0
  70. package/src/crud/utils/useResourceFormData.ts +231 -0
  71. package/src/data/abortError.test.ts +19 -0
  72. package/src/data/abortError.ts +10 -0
  73. package/src/data/createMemoryResourceHandlers.ts +1 -1
  74. package/src/data/createRestResourceHandlers.ts +4 -4
  75. package/src/data/dataProviderTypes.ts +8 -0
  76. package/src/data/resourceHandlers.ts +4 -3
  77. package/src/index.ts +14 -1
  78. package/dist/src/crud/context/FormFieldsContext.d.ts +0 -14
  79. package/dist/src/crud/context/FormFieldsContext.d.ts.map +0 -1
  80. package/dist/src/crud/context/InlineFormContext.d.ts +0 -16
  81. package/dist/src/crud/context/InlineFormContext.d.ts.map +0 -1
  82. package/dist/src/crud/fields/useInlineOrFormField.d.ts +0 -10
  83. package/dist/src/crud/fields/useInlineOrFormField.d.ts.map +0 -1
  84. package/src/crud/context/FormFieldsContext.tsx +0 -76
  85. package/src/crud/context/InlineFormContext.tsx +0 -71
  86. package/src/crud/fields/useInlineOrFormField.tsx +0 -91
@@ -1,47 +1,53 @@
1
1
  import { DatePicker } from "antd";
2
2
  import dayjs from "dayjs";
3
3
  import type { BaseSourceProps, FieldRules } from "../types";
4
- import { useInlineOrFormField } from "./useInlineOrFormField";
4
+ import { FieldWrapper } from "./FieldWrapper";
5
5
 
6
6
  const DATE_FORMAT = "YYYY-MM-DD";
7
7
 
8
8
  export type DateFieldProps = BaseSourceProps & {
9
+ name?: string;
9
10
  required?: boolean;
10
11
  rules?: FieldRules;
11
12
  showTime?: boolean;
13
+ hideLabel?: boolean;
12
14
  };
13
15
 
14
16
  export function DateField({
15
17
  source,
18
+ name,
16
19
  label,
17
20
  required,
18
21
  rules,
19
22
  showTime,
23
+ hideLabel,
20
24
  }: DateFieldProps) {
21
- const field = useInlineOrFormField(
22
- source,
23
- label,
24
- required,
25
- rules,
26
- ({ value, onChange, onBlur, disabled }) => (
27
- <DatePicker
28
- value={value ? dayjs(String(value)) : null}
29
- onChange={(d) =>
30
- onChange(
31
- d
32
- ? d.format(showTime ? `${DATE_FORMAT} HH:mm:ss` : DATE_FORMAT)
33
- : null,
34
- )
35
- }
36
- onBlur={onBlur}
37
- showTime={showTime}
38
- disabled={disabled}
39
- format={showTime ? `${DATE_FORMAT} HH:mm:ss` : DATE_FORMAT}
40
- style={{ width: "100%" }}
41
- />
42
- ),
25
+ return (
26
+ <FieldWrapper
27
+ source={source}
28
+ name={name}
29
+ label={label}
30
+ required={required}
31
+ rules={rules}
32
+ hideLabel={hideLabel}
33
+ >
34
+ {({ value, onChange, onBlur, disabled }) => (
35
+ <DatePicker
36
+ value={value ? dayjs(String(value)) : null}
37
+ onChange={(d) =>
38
+ onChange(
39
+ d
40
+ ? d.format(showTime ? `${DATE_FORMAT} HH:mm:ss` : DATE_FORMAT)
41
+ : null,
42
+ )
43
+ }
44
+ onBlur={onBlur}
45
+ showTime={showTime}
46
+ disabled={disabled}
47
+ format={showTime ? `${DATE_FORMAT} HH:mm:ss` : DATE_FORMAT}
48
+ style={{ width: "100%" }}
49
+ />
50
+ )}
51
+ </FieldWrapper>
43
52
  );
44
-
45
- if (field.mode === "inline") return null;
46
- return field.element;
47
53
  }
@@ -3,87 +3,63 @@ import { Controller, useFormContext, type FieldValues } from "react-hook-form";
3
3
  import type { ReactNode } from "react";
4
4
  import type { FieldRules } from "../types";
5
5
  import { useFormMetaOptional } from "../context/FormContext";
6
- import { useRegisterFormSource } from "../context/FormFieldsContext";
6
+ import {
7
+ useSectionField,
8
+ useSubmitField,
9
+ } from "../context/SubmitFieldsContext";
7
10
 
8
11
  export type FieldWrapperProps = {
12
+ /** Logical field name — used for submit payload tracking on top-level fields. */
9
13
  source: string;
14
+ /** Full RHF path. Defaults to `source`. Inline cells pass e.g. `lines.0.label`. */
15
+ name?: string;
10
16
  label?: string;
11
17
  required?: boolean;
12
18
  rules?: FieldRules;
19
+ /** Tabular inline cells: column header replaces the label. */
20
+ hideLabel?: boolean;
13
21
  children: (props: {
14
22
  value: unknown;
15
23
  onChange: (value: unknown) => void;
16
24
  onBlur: () => void;
17
25
  disabled?: boolean;
26
+ name: string;
18
27
  }) => ReactNode;
19
28
  };
20
29
 
21
30
  export function FieldWrapper({
22
31
  source,
32
+ name,
23
33
  label,
24
34
  required,
25
35
  rules,
36
+ hideLabel,
26
37
  children,
27
38
  }: FieldWrapperProps) {
39
+ const fieldName = name ?? source;
40
+ const isTopLevel = !fieldName.includes(".");
41
+
42
+ // react-hook-form: connect this field to the form from <ResourceForm>'s FormProvider.
43
+ // `control` is passed to <Controller> below so value, onChange, and validation work.
28
44
  const { control } = useFormContext<FieldValues>();
45
+
46
+ // ding-react-admin: optional form-wide flags from <FormMetaProvider> (inside ResourceForm).
47
+ // Used here for `disabled` on inputs (e.g. read-only view mode). Returns null outside a form page.
29
48
  const meta = useFormMetaOptional();
30
- const fieldLabel = label ?? source;
31
- useRegisterFormSource(source);
49
+ const fieldLabel = hideLabel ? undefined : (label ?? source);
50
+ const requiredMessage = label ?? source;
32
51
 
33
- return (
34
- <Controller
35
- name={source}
36
- control={control}
37
- rules={{
38
- required: required ? `${fieldLabel} is required` : false,
39
- ...rules,
40
- }}
41
- render={({ field, fieldState }) => (
42
- <Form.Item
43
- label={fieldLabel}
44
- validateStatus={fieldState.error ? "error" : undefined}
45
- help={fieldState.error?.message}
46
- required={required}
47
- >
48
- {children({
49
- value: field.value,
50
- onChange: field.onChange,
51
- onBlur: field.onBlur,
52
- disabled: meta?.disabled,
53
- })}
54
- </Form.Item>
55
- )}
56
- />
57
- );
58
- }
52
+ // ding-react-admin: remember this `source` so Save sends only fields you rendered in JSX
53
+ // (see pickBySources in ResourceForm). Skipped for inline row cells — nested `name` paths.
54
+ useSubmitField(source, isTopLevel);
59
55
 
60
- export function InlineFieldWrapper({
61
- name,
62
- label,
63
- required,
64
- rules,
65
- hideLabel,
66
- children,
67
- }: {
68
- name: string;
69
- label?: string;
70
- required?: boolean;
71
- rules?: FieldRules;
72
- /** Tabular inlines use column headers — suppress per-cell labels. */
73
- hideLabel?: boolean;
74
- children: (props: {
75
- value: unknown;
76
- onChange: (value: unknown) => void;
77
- onBlur: () => void;
78
- }) => ReactNode;
79
- }) {
80
- const { control } = useFormContext<FieldValues>();
81
- const fieldLabel = hideLabel ? undefined : label;
82
- const requiredMessage = label ?? "This field";
56
+ // ding-react-admin: group this field with the current FormTab / FormStep for error highlighting
57
+ // and "jump to first invalid tab" on Save. No-op outside tabs/steps.
58
+ useSectionField(source, isTopLevel);
83
59
 
84
60
  return (
85
61
  <Controller
86
- name={name}
62
+ name={fieldName}
87
63
  control={control}
88
64
  rules={{
89
65
  required: required ? `${requiredMessage} is required` : false,
@@ -95,12 +71,14 @@ export function InlineFieldWrapper({
95
71
  validateStatus={fieldState.error ? "error" : undefined}
96
72
  help={fieldState.error?.message}
97
73
  required={required && !hideLabel}
98
- style={{ marginBottom: 0 }}
74
+ style={hideLabel ? { marginBottom: 0 } : undefined}
99
75
  >
100
76
  {children({
101
77
  value: field.value,
102
78
  onChange: field.onChange,
103
79
  onBlur: field.onBlur,
80
+ disabled: meta?.disabled,
81
+ name: fieldName,
104
82
  })}
105
83
  </Form.Item>
106
84
  )}
@@ -1,50 +1,52 @@
1
1
  import { InputNumber } from "antd";
2
2
  import type { CSSProperties } from "react";
3
- import type { BaseSourceProps, FieldRules, InlineFieldOptions } from "../types";
4
- import { useInlineOrFormField } from "./useInlineOrFormField";
3
+ import type { BaseSourceProps, FieldRules } from "../types";
4
+ import { FieldWrapper } from "./FieldWrapper";
5
5
 
6
- export type NumberFieldProps = BaseSourceProps &
7
- InlineFieldOptions & {
8
- required?: boolean;
9
- rules?: FieldRules;
10
- min?: number;
11
- max?: number;
12
- step?: number;
13
- inputStyle?: CSSProperties;
14
- };
6
+ export type NumberFieldProps = BaseSourceProps & {
7
+ name?: string;
8
+ required?: boolean;
9
+ rules?: FieldRules;
10
+ min?: number;
11
+ max?: number;
12
+ step?: number;
13
+ inputStyle?: CSSProperties;
14
+ hideLabel?: boolean;
15
+ };
15
16
 
16
17
  export function NumberField({
17
18
  source,
19
+ name,
18
20
  label,
19
21
  required,
20
22
  rules,
21
23
  min,
22
24
  max,
23
25
  step,
24
- width: inlineWidth,
25
- minWidth: inlineMinWidth,
26
26
  inputStyle,
27
+ hideLabel,
27
28
  }: NumberFieldProps) {
28
- const field = useInlineOrFormField(
29
- source,
30
- label,
31
- required,
32
- rules,
33
- ({ value, onChange, onBlur, disabled }) => (
34
- <InputNumber
35
- value={value as number | undefined}
36
- onChange={(v) => onChange(v)}
37
- onBlur={onBlur}
38
- min={min}
39
- max={max}
40
- step={step}
41
- disabled={disabled}
42
- style={{ width: "100%", ...inputStyle }}
43
- />
44
- ),
45
- { width: inlineWidth, minWidth: inlineMinWidth },
29
+ return (
30
+ <FieldWrapper
31
+ source={source}
32
+ name={name}
33
+ label={label}
34
+ required={required}
35
+ rules={rules}
36
+ hideLabel={hideLabel}
37
+ >
38
+ {({ value, onChange, onBlur, disabled }) => (
39
+ <InputNumber
40
+ value={value as number | undefined}
41
+ onChange={(v) => onChange(v)}
42
+ onBlur={onBlur}
43
+ min={min}
44
+ max={max}
45
+ step={step}
46
+ disabled={disabled}
47
+ style={{ width: "100%", ...inputStyle }}
48
+ />
49
+ )}
50
+ </FieldWrapper>
46
51
  );
47
-
48
- if (field.mode === "inline") return null;
49
- return field.element;
50
52
  }
@@ -1,71 +1,73 @@
1
1
  import { Input } from "antd";
2
2
  import { useWatch } from "react-hook-form";
3
- import type { BaseSourceProps, FieldRules, InlineFieldOptions } from "../types";
4
- import { useInlineOrFormField } from "./useInlineOrFormField";
3
+ import type { BaseSourceProps, FieldRules } from "../types";
4
+ import { FieldWrapper } from "./FieldWrapper";
5
5
 
6
- export type PasswordFieldProps = BaseSourceProps &
7
- InlineFieldOptions & {
8
- required?: boolean;
9
- rules?: FieldRules;
10
- /** When set, renders a second field and validates it matches `source`. */
11
- confirmSource?: string;
12
- confirmLabel?: string;
13
- autoComplete?: string;
14
- };
6
+ export type PasswordFieldProps = BaseSourceProps & {
7
+ name?: string;
8
+ required?: boolean;
9
+ rules?: FieldRules;
10
+ /** When set, renders a second field and validates it matches `source`. */
11
+ confirmSource?: string;
12
+ confirmLabel?: string;
13
+ autoComplete?: string;
14
+ hideLabel?: boolean;
15
+ };
15
16
 
16
17
  function PasswordInputField({
17
18
  source,
19
+ name,
18
20
  label,
19
21
  required,
20
22
  rules,
21
23
  autoComplete,
22
- width: inlineWidth,
23
- minWidth: inlineMinWidth,
24
+ hideLabel,
24
25
  }: PasswordFieldProps) {
25
- const field = useInlineOrFormField(
26
- source,
27
- label,
28
- required,
29
- rules,
30
- ({ value, onChange, onBlur, disabled }) => (
31
- <Input.Password
32
- value={value as string | undefined}
33
- onChange={(e) => onChange(e.target.value)}
34
- onBlur={onBlur}
35
- disabled={disabled}
36
- autoComplete={autoComplete}
37
- />
38
- ),
39
- { width: inlineWidth, minWidth: inlineMinWidth },
26
+ return (
27
+ <FieldWrapper
28
+ source={source}
29
+ name={name}
30
+ label={label}
31
+ required={required}
32
+ rules={rules}
33
+ hideLabel={hideLabel}
34
+ >
35
+ {({ value, onChange, onBlur, disabled }) => (
36
+ <Input.Password
37
+ value={value as string | undefined}
38
+ onChange={(e) => onChange(e.target.value)}
39
+ onBlur={onBlur}
40
+ disabled={disabled}
41
+ autoComplete={autoComplete}
42
+ />
43
+ )}
44
+ </FieldWrapper>
40
45
  );
41
-
42
- if (field.mode === "inline") return null;
43
- return field.element;
44
46
  }
45
47
 
46
48
  export function PasswordField({
47
49
  source,
50
+ name,
48
51
  label,
49
52
  required,
50
53
  rules,
51
54
  confirmSource,
52
55
  confirmLabel = "Confirm password",
53
56
  autoComplete = "new-password",
54
- width,
55
- minWidth,
57
+ hideLabel,
56
58
  }: PasswordFieldProps) {
57
- const password = useWatch({ name: source, disabled: !confirmSource });
59
+ const password = useWatch({ name: name ?? source, disabled: !confirmSource });
58
60
 
59
61
  if (!confirmSource) {
60
62
  return (
61
63
  <PasswordInputField
62
64
  source={source}
65
+ name={name}
63
66
  label={label}
64
67
  required={required}
65
68
  rules={rules}
66
69
  autoComplete={autoComplete}
67
- width={width}
68
- minWidth={minWidth}
70
+ hideLabel={hideLabel}
69
71
  />
70
72
  );
71
73
  }
@@ -74,20 +76,19 @@ export function PasswordField({
74
76
  <>
75
77
  <PasswordInputField
76
78
  source={source}
79
+ name={name}
77
80
  label={label}
78
81
  required={required}
79
82
  rules={rules}
80
83
  autoComplete={autoComplete}
81
- width={width}
82
- minWidth={minWidth}
84
+ hideLabel={hideLabel}
83
85
  />
84
86
  <PasswordInputField
85
87
  source={confirmSource}
86
88
  label={confirmLabel}
87
89
  required={required}
88
90
  autoComplete={autoComplete}
89
- width={width}
90
- minWidth={minWidth}
91
+ hideLabel={hideLabel}
91
92
  rules={{
92
93
  validate: (value: string) =>
93
94
  !password || value === password || "Passwords do not match",
@@ -1,191 +1,96 @@
1
1
  import { Select } from "antd";
2
-
3
2
  import type { CSSProperties } from "react";
4
-
5
3
  import { useMemo, useState } from "react";
6
-
7
4
  import type {
8
-
9
5
  BaseSourceProps,
10
-
11
6
  ChoiceOption,
12
-
13
7
  FieldRules,
14
-
15
- InlineFieldOptions,
16
-
17
8
  ReferenceProps,
18
-
19
9
  } from "../types";
20
-
21
10
  import { useChoices } from "../utils/useChoices";
22
-
23
- import { useInlineOrFormField } from "./useInlineOrFormField";
24
-
25
-
11
+ import { FieldWrapper } from "./FieldWrapper";
26
12
 
27
13
  export type ReferenceFieldProps = BaseSourceProps &
28
-
29
- ReferenceProps &
30
-
31
- InlineFieldOptions & {
32
-
14
+ ReferenceProps & {
15
+ name?: string;
33
16
  required?: boolean;
34
-
35
17
  rules?: FieldRules;
36
-
37
18
  search?: boolean;
38
-
39
19
  allowClear?: boolean;
40
-
41
20
  disabled?: boolean;
42
-
21
+ hideLabel?: boolean;
43
22
  /** Applied to the underlying Select / input control. */
44
-
45
23
  inputStyle?: CSSProperties;
46
-
47
24
  /** Called after the value changes (e.g. to update dependent fields). */
48
-
49
25
  onValueChange?: (
50
-
51
26
  value: unknown,
52
-
53
27
  option: ChoiceOption | undefined,
54
-
55
- meta: { name?: string; index?: number },
56
-
28
+ meta: { name: string },
57
29
  ) => void;
58
-
59
30
  };
60
31
 
61
-
62
-
63
32
  export function ReferenceField({
64
-
65
33
  source,
66
-
34
+ name,
67
35
  label,
68
-
69
36
  reference,
70
-
71
37
  choices,
72
-
73
38
  optionLabel = "name",
74
-
75
39
  optionValue = "id",
76
-
77
40
  required,
78
-
79
41
  rules,
80
-
81
42
  search,
82
-
83
43
  allowClear,
84
-
85
44
  disabled: disabledProp,
86
-
87
- width: inlineWidth,
88
-
89
- minWidth: inlineMinWidth,
90
-
45
+ hideLabel,
91
46
  inputStyle,
92
-
93
47
  onValueChange,
94
-
95
48
  }: ReferenceFieldProps) {
96
-
97
49
  const [searchText, setSearchText] = useState<string | undefined>();
98
-
99
50
  const { options, loading, optionForValue } = useChoices(
100
-
101
51
  choices,
102
-
103
52
  reference,
104
-
105
53
  optionLabel,
106
-
107
54
  optionValue,
108
-
109
55
  search ? searchText : undefined,
110
-
111
56
  );
112
57
 
113
-
114
-
115
58
  const selectOptions = useMemo(
116
-
117
59
  () =>
118
-
119
60
  options.map((o) => ({
120
-
121
61
  label: o.label,
122
-
123
62
  value: o.value as string | number,
124
-
125
63
  })),
126
-
127
64
  [options],
128
-
129
65
  );
130
66
 
131
-
132
-
133
- const field = useInlineOrFormField(
134
-
135
- source,
136
-
137
- label,
138
-
139
- required,
140
-
141
- rules,
142
-
143
- ({ value, onChange, disabled, name, index }) => (
144
-
145
- <Select
146
-
147
- value={value as string | number | undefined}
148
-
149
- onChange={(next) => {
150
-
151
- onChange(next);
152
-
153
- onValueChange?.(next, optionForValue(next), { name, index });
154
-
155
- }}
156
-
157
- options={selectOptions}
158
-
159
- loading={loading && options.length === 0}
160
-
161
- showSearch={search}
162
-
163
- filterOption={search ? false : undefined}
164
-
165
- onSearch={search ? setSearchText : undefined}
166
-
167
- allowClear={allowClear}
168
-
169
- disabled={disabled || disabledProp}
170
-
171
- optionFilterProp="label"
172
-
173
- style={{ width: "100%", minWidth: 160, ...inputStyle }}
174
-
175
- />
176
-
177
- ),
178
-
179
- { width: inlineWidth, minWidth: inlineMinWidth },
180
-
67
+ return (
68
+ <FieldWrapper
69
+ source={source}
70
+ name={name}
71
+ label={label}
72
+ required={required}
73
+ rules={rules}
74
+ hideLabel={hideLabel}
75
+ >
76
+ {({ value, onChange, disabled, name: fieldName }) => (
77
+ <Select
78
+ value={value as string | number | undefined}
79
+ onChange={(next) => {
80
+ onChange(next);
81
+ onValueChange?.(next, optionForValue(next), { name: fieldName });
82
+ }}
83
+ options={selectOptions}
84
+ loading={loading && options.length === 0}
85
+ showSearch={search}
86
+ filterOption={search ? false : undefined}
87
+ onSearch={search ? setSearchText : undefined}
88
+ allowClear={allowClear}
89
+ disabled={disabled || disabledProp}
90
+ optionFilterProp="label"
91
+ style={{ width: "100%", minWidth: 160, ...inputStyle }}
92
+ />
93
+ )}
94
+ </FieldWrapper>
181
95
  );
182
-
183
-
184
-
185
- if (field.mode === "inline") return null;
186
-
187
- return field.element;
188
-
189
96
  }
190
-
191
-