@firecms/ui 3.0.0-beta.11 → 3.0.0-beta.13
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/dist/components/Avatar.d.ts +1 -0
- package/dist/components/BooleanSwitch.d.ts +1 -1
- package/dist/components/BooleanSwitchWithLabel.d.ts +1 -1
- package/dist/components/Button.d.ts +6 -4
- package/dist/components/CircularProgress.d.ts +1 -1
- package/dist/components/DateTimeField.d.ts +1 -1
- package/dist/components/Dialog.d.ts +2 -1
- package/dist/components/Menu.d.ts +4 -1
- package/dist/components/MultiSelect.d.ts +14 -22
- package/dist/components/Select.d.ts +10 -9
- package/dist/components/Sheet.d.ts +2 -0
- package/dist/components/TextField.d.ts +38 -3
- package/dist/index.es.js +788 -684
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +788 -684
- package/dist/index.umd.js.map +1 -1
- package/package.json +30 -29
- package/src/components/Avatar.tsx +4 -1
- package/src/components/BooleanSwitch.tsx +1 -1
- package/src/components/BooleanSwitchWithLabel.tsx +7 -2
- package/src/components/Button.tsx +16 -17
- package/src/components/Chip.tsx +1 -0
- package/src/components/CircularProgress.tsx +7 -3
- package/src/components/DateTimeField.tsx +29 -23
- package/src/components/Dialog.tsx +3 -1
- package/src/components/DialogContent.tsx +1 -1
- package/src/components/FileUpload.tsx +2 -1
- package/src/components/Menu.tsx +13 -4
- package/src/components/Menubar.tsx +1 -1
- package/src/components/MultiSelect.tsx +54 -51
- package/src/components/SearchBar.tsx +1 -1
- package/src/components/Select.tsx +70 -55
- package/src/components/Sheet.tsx +9 -1
- package/src/components/Tabs.tsx +3 -1
- package/src/components/TextField.tsx +190 -153
- package/src/components/TextareaAutosize.tsx +2 -2
- package/src/components/Tooltip.tsx +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { ForwardedRef, forwardRef, useEffect, useRef } from "react";
|
|
3
3
|
|
|
4
4
|
import { TextareaAutosize } from "./TextareaAutosize";
|
|
5
5
|
import {
|
|
@@ -13,7 +13,7 @@ import { InputLabel } from "./InputLabel";
|
|
|
13
13
|
import { cls } from "../util";
|
|
14
14
|
|
|
15
15
|
export type InputType =
|
|
16
|
-
"text"
|
|
16
|
+
| "text"
|
|
17
17
|
| "number"
|
|
18
18
|
| "phone"
|
|
19
19
|
| "email"
|
|
@@ -28,156 +28,193 @@ export type InputType =
|
|
|
28
28
|
| "color";
|
|
29
29
|
|
|
30
30
|
export type TextFieldProps<T extends string | number> = {
|
|
31
|
-
type?: InputType
|
|
32
|
-
value?: T
|
|
33
|
-
onChange?: (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void
|
|
34
|
-
label?: React.ReactNode
|
|
35
|
-
multiline?: boolean
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
31
|
+
type?: InputType;
|
|
32
|
+
value?: T;
|
|
33
|
+
onChange?: (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
34
|
+
label?: React.ReactNode;
|
|
35
|
+
multiline?: boolean;
|
|
36
|
+
disabled?: boolean;
|
|
37
|
+
invisible?: boolean;
|
|
38
|
+
error?: boolean;
|
|
39
|
+
endAdornment?: React.ReactNode;
|
|
40
|
+
autoFocus?: boolean;
|
|
41
|
+
placeholder?: string;
|
|
42
|
+
size?: "smallest" | "small" | "medium" | "large";
|
|
43
|
+
className?: string;
|
|
44
|
+
style?: React.CSSProperties;
|
|
45
|
+
inputClassName?: string;
|
|
46
|
+
inputStyle?: React.CSSProperties;
|
|
47
|
+
inputRef?: React.ForwardedRef<any>;
|
|
48
|
+
/**
|
|
49
|
+
* Maximum number of rows to display.
|
|
50
|
+
*/
|
|
51
|
+
maxRows?: number | string;
|
|
52
|
+
/**
|
|
53
|
+
* Minimum number of rows to display.
|
|
54
|
+
* @default 1
|
|
55
|
+
*/
|
|
56
|
+
minRows?: number | string;
|
|
49
57
|
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">;
|
|
50
58
|
|
|
51
|
-
export
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
:
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
59
|
+
export const TextField = forwardRef<HTMLDivElement, TextFieldProps<string | number>>(
|
|
60
|
+
<T extends string | number>(
|
|
61
|
+
{
|
|
62
|
+
value,
|
|
63
|
+
onChange,
|
|
64
|
+
label,
|
|
65
|
+
type = "text",
|
|
66
|
+
multiline = false,
|
|
67
|
+
invisible,
|
|
68
|
+
maxRows,
|
|
69
|
+
minRows,
|
|
70
|
+
disabled,
|
|
71
|
+
error,
|
|
72
|
+
endAdornment,
|
|
73
|
+
autoFocus,
|
|
74
|
+
placeholder,
|
|
75
|
+
size = "large",
|
|
76
|
+
className,
|
|
77
|
+
style,
|
|
78
|
+
inputClassName,
|
|
79
|
+
inputStyle,
|
|
80
|
+
inputRef: inputRefProp,
|
|
81
|
+
...inputProps
|
|
82
|
+
}: TextFieldProps<T>,
|
|
83
|
+
ref: ForwardedRef<HTMLDivElement>
|
|
84
|
+
) => {
|
|
85
|
+
|
|
86
|
+
const inputRef = inputRefProp ?? useRef(null);
|
|
87
|
+
|
|
88
|
+
// @ts-ignore
|
|
89
|
+
const [focused, setFocused] = React.useState(document.activeElement === inputRef.current);
|
|
90
|
+
const hasValue = value !== undefined && value !== null && value !== "";
|
|
91
|
+
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (type !== "number") return;
|
|
94
|
+
const handleWheel = (event: any) => {
|
|
95
|
+
if (event.target instanceof HTMLElement) event.target.blur();
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const element = "current" in inputRef ? inputRef.current : inputRef;
|
|
99
|
+
|
|
100
|
+
element?.addEventListener("wheel", handleWheel);
|
|
101
|
+
|
|
102
|
+
return () => {
|
|
103
|
+
element?.removeEventListener("wheel", handleWheel);
|
|
104
|
+
};
|
|
105
|
+
}, [inputRef, type]);
|
|
106
|
+
|
|
107
|
+
const input = multiline ? (
|
|
108
|
+
<TextareaAutosize
|
|
109
|
+
{...(inputProps as any)}
|
|
110
|
+
ref={inputRef}
|
|
111
|
+
placeholder={focused || hasValue || !label ? placeholder : undefined}
|
|
112
|
+
autoFocus={autoFocus}
|
|
113
|
+
minRows={minRows}
|
|
114
|
+
maxRows={maxRows}
|
|
115
|
+
value={value ?? ""}
|
|
116
|
+
onChange={onChange}
|
|
117
|
+
style={inputStyle}
|
|
118
|
+
className={cls(
|
|
119
|
+
invisible ? focusedInvisibleMixin : "",
|
|
120
|
+
"rounded-md resize-none w-full outline-none p-[32px] text-base bg-transparent min-h-[64px] px-3 pt-8",
|
|
121
|
+
disabled && "outline-none opacity-50 text-surface-accent-600 dark:text-surface-accent-500",
|
|
122
|
+
inputClassName
|
|
123
|
+
)}
|
|
124
|
+
/>
|
|
125
|
+
) : (
|
|
126
|
+
<input
|
|
127
|
+
{...inputProps}
|
|
128
|
+
ref={inputRef}
|
|
129
|
+
disabled={disabled}
|
|
130
|
+
style={inputStyle}
|
|
131
|
+
className={cls(
|
|
132
|
+
"w-full outline-none bg-transparent leading-normal px-3",
|
|
133
|
+
"rounded-md",
|
|
134
|
+
"focused:text-text-primary focused:dark:text-text-primary-dark",
|
|
135
|
+
invisible ? focusedInvisibleMixin : "",
|
|
136
|
+
disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
|
|
137
|
+
{
|
|
138
|
+
"min-h-[28px]": size === "smallest",
|
|
139
|
+
"min-h-[32px]": size === "small",
|
|
140
|
+
"min-h-[42px]": size === "medium",
|
|
141
|
+
"min-h-[64px]": size === "large",
|
|
142
|
+
},
|
|
143
|
+
label
|
|
144
|
+
? size === "large"
|
|
145
|
+
? "pt-8 pb-2"
|
|
146
|
+
: "pt-4 pb-2"
|
|
147
|
+
: "py-2",
|
|
148
|
+
endAdornment ? "pr-10" : "pr-3",
|
|
149
|
+
disabled &&
|
|
150
|
+
"outline-none opacity-50 dark:opacity-50 text-surface-accent-800 dark:text-white",
|
|
151
|
+
inputClassName
|
|
152
|
+
)}
|
|
153
|
+
placeholder={focused || hasValue || !label ? placeholder : undefined}
|
|
154
|
+
autoFocus={autoFocus}
|
|
155
|
+
onFocus={() => setFocused(true)}
|
|
156
|
+
onBlur={() => setFocused(false)}
|
|
157
|
+
type={type}
|
|
158
|
+
value={type === "number" && Number.isNaN(value) ? "" : value ?? ""}
|
|
159
|
+
onChange={onChange}
|
|
160
|
+
/>
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<div
|
|
165
|
+
ref={ref}
|
|
166
|
+
className={cls(
|
|
167
|
+
"rounded-md relative max-w-full",
|
|
168
|
+
invisible ? fieldBackgroundInvisibleMixin : fieldBackgroundMixin,
|
|
169
|
+
disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
|
|
170
|
+
error ? "border border-red-500 dark:border-red-600" : "",
|
|
171
|
+
{
|
|
172
|
+
"min-h-[28px]": size === "smallest",
|
|
173
|
+
"min-h-[32px]": size === "small",
|
|
174
|
+
"min-h-[42px]": size === "medium",
|
|
175
|
+
"min-h-[64px]": size === "large",
|
|
176
|
+
},
|
|
177
|
+
className
|
|
178
|
+
)}
|
|
179
|
+
style={style}
|
|
180
|
+
>
|
|
181
|
+
{label && (
|
|
182
|
+
<InputLabel
|
|
183
|
+
className={cls(
|
|
184
|
+
"pointer-events-none absolute",
|
|
185
|
+
size === "large" ? "top-1" : "top-[-1px]",
|
|
186
|
+
!error
|
|
187
|
+
? focused
|
|
188
|
+
? "text-primary dark:text-primary"
|
|
189
|
+
: "text-text-secondary dark:text-text-secondary-dark"
|
|
190
|
+
: "text-red-500 dark:text-red-600",
|
|
191
|
+
disabled ? "opacity-50" : ""
|
|
192
|
+
)}
|
|
193
|
+
shrink={hasValue || focused}
|
|
194
|
+
>
|
|
195
|
+
{label}
|
|
196
|
+
</InputLabel>
|
|
197
|
+
)}
|
|
198
|
+
|
|
199
|
+
{input}
|
|
200
|
+
|
|
201
|
+
{endAdornment && (
|
|
202
|
+
<div
|
|
203
|
+
className={cls(
|
|
204
|
+
"flex flex-row justify-center items-center absolute h-full right-0 top-0",
|
|
205
|
+
{
|
|
206
|
+
"mr-4": size === "large",
|
|
207
|
+
"mr-3": size === "medium",
|
|
208
|
+
"mr-2": size === "small" || size === "smallest",
|
|
209
|
+
}
|
|
210
|
+
)}
|
|
211
|
+
>
|
|
212
|
+
{endAdornment}
|
|
213
|
+
</div>
|
|
214
|
+
)}
|
|
215
|
+
</div>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
TextField.displayName = "TextField";
|
|
@@ -270,7 +270,7 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
|
|
|
270
270
|
// Need a large enough difference to allow scrolling.
|
|
271
271
|
// This prevents infinite rendering loop.
|
|
272
272
|
overflow: state.overflow ? "hidden" : undefined,
|
|
273
|
-
...style
|
|
273
|
+
...style,
|
|
274
274
|
}}
|
|
275
275
|
onScroll={onScroll}
|
|
276
276
|
{...other}
|
|
@@ -282,9 +282,9 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
|
|
|
282
282
|
ref={shadowRef}
|
|
283
283
|
tabIndex={-1}
|
|
284
284
|
style={{
|
|
285
|
+
padding: 0,
|
|
285
286
|
...styles.shadow,
|
|
286
287
|
...style,
|
|
287
|
-
padding: 0
|
|
288
288
|
}}
|
|
289
289
|
/>
|
|
290
290
|
</React.Fragment>
|