|
1 | 1 | import type { ChangeEvent } from "react" |
2 | 2 | import { useCallback, useEffect } from "react" |
3 | | -import type { InputProps } from "antd" |
4 | 3 | import { Input, Form } from "antd" |
5 | 4 | import { QuestionCircleOutlined } from "@ant-design/icons" |
6 | 5 | import type { Rule } from "antd/es/form" |
7 | | -import type { TextAreaProps } from "antd/es/input" |
8 | 6 | import type { ControlProps } from "@jsonforms/core" |
9 | 7 |
|
10 | | -import type { TextControlOptions, TextControlType } from "../ui-schema" |
| 8 | +import type { TextControlOptions } from "../ui-schema" |
11 | 9 | import { assertNever } from "../common/assert-never" |
12 | 10 | import { withJsonFormsControlProps } from "@jsonforms/react" |
13 | 11 | interface TextControlProps extends ControlProps { |
@@ -40,7 +38,6 @@ export function TextControl({ |
40 | 38 | const ariaLabel = label || schema.description |
41 | 39 | const options: TextControlOptions = |
42 | 40 | (uischema.options as TextControlOptions) ?? {} |
43 | | - const textControlType: TextControlType = options.type ?? "singleline" |
44 | 41 | const tooltip = options.tooltip |
45 | 42 | const placeholderText = options.placeholderText |
46 | 43 | const form = Form.useFormInstance() |
@@ -73,41 +70,52 @@ export function TextControl({ |
73 | 70 | : {})} |
74 | 71 | > |
75 | 72 | <TextControlInput |
76 | | - type={textControlType} |
77 | 73 | aria-label={ariaLabel} |
78 | 74 | disabled={!enabled} |
79 | 75 | autoComplete="off" |
80 | 76 | onChange={(e: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => |
81 | 77 | handleChange(path, e.target.value) |
82 | 78 | } |
83 | | - placeholder={`Enter ${ |
84 | | - placeholderText ?? (label.toLowerCase() || "value") |
85 | | - }`} |
| 79 | + placeholder={placeholderText ?? (label.toLowerCase() || "value")} |
| 80 | + textControlOptions={options} |
86 | 81 | /> |
87 | 82 | </Form.Item> |
88 | 83 | ) |
89 | 84 | } |
90 | 85 |
|
91 | | -type TextControlInputProps = |
92 | | - | (InputProps & { type: "singleline" }) |
93 | | - | (TextAreaProps & { type: "multiline" }) |
94 | | - | (InputProps & { type: "password" }) |
| 86 | +type TextControlInputProps = { |
| 87 | + "aria-label": string | undefined |
| 88 | + disabled: boolean |
| 89 | + autoComplete: string |
| 90 | + onChange: (e: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => void |
| 91 | + placeholder: string |
| 92 | + textControlOptions: TextControlOptions |
| 93 | +} |
| 94 | + |
| 95 | +function TextControlInput({ |
| 96 | + textControlOptions, |
| 97 | + ...rest |
| 98 | +}: TextControlInputProps) { |
| 99 | + if ( |
| 100 | + !(`type` in textControlOptions) || |
| 101 | + textControlOptions.type === undefined |
| 102 | + ) { |
| 103 | + return <Input {...{ ...rest, ...textControlOptions }} /> |
| 104 | + } |
95 | 105 |
|
96 | | -function TextControlInput({ type, ...rest }: TextControlInputProps) { |
97 | | - switch (type) { |
| 106 | + switch (textControlOptions.type) { |
98 | 107 | case "multiline": |
99 | | - // idk why type isn't getting narrowed properly here, but cast seems safe |
100 | | - return <Input.TextArea {...(rest as TextAreaProps)} /> |
| 108 | + return <Input.TextArea {...{ ...rest, ...textControlOptions }} /> |
101 | 109 | case "singleline": |
102 | | - // idk why type isn't getting narrowed properly here, but cast seems safe |
103 | | - return <Input {...(rest as InputProps)} /> |
| 110 | + return <Input {...{ ...rest, ...textControlOptions }} /> |
104 | 111 | case "password": |
105 | | - return <Input.Password {...(rest as InputProps)} /> |
| 112 | + return <Input.Password {...{ ...rest, ...textControlOptions }} /> |
| 113 | + |
106 | 114 | default: |
107 | 115 | try { |
108 | | - assertNever(type) |
| 116 | + assertNever(textControlOptions.type) |
109 | 117 | } catch (e) { |
110 | | - return <Input {...(rest as InputProps)} /> |
| 118 | + return <Input {...{ ...rest, ...textControlOptions }} /> |
111 | 119 | } |
112 | 120 | } |
113 | 121 | } |
|
0 commit comments