ant-float-label 1.0.7 → 1.1.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/README.md CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  FloatTreeSelect,
16
16
  FloatAutoComplete,
17
17
  FloatTimePicker,
18
+ FloatPassword
18
19
  } from "ant-float-label";
19
20
  ```
20
21
 
package/dist/README.md CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  FloatTreeSelect,
16
16
  FloatAutoComplete,
17
17
  FloatTimePicker,
18
+ FloatPassword
18
19
  } from "ant-float-label";
19
20
  ```
20
21
 
@@ -1,5 +1,6 @@
1
1
  import { AutoCompleteProps } from "antd";
2
2
  import "./index.css";
3
3
  export interface FloatAutoCompleteProps extends AutoCompleteProps {
4
+ required?: boolean;
4
5
  }
5
- export declare function FloatAutoComplete({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }: FloatAutoCompleteProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function FloatAutoComplete({ placeholder, onFocus, onBlur, value, defaultValue, style, onChange, required, ...restProps }: FloatAutoCompleteProps): import("react/jsx-runtime").JSX.Element;
@@ -1,3 +1,5 @@
1
1
  import { CascaderProps } from "antd";
2
- export type FloatCascadertProps = CascaderProps;
3
- export declare function FloatCascader({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }: FloatCascadertProps): import("react/jsx-runtime").JSX.Element;
2
+ export type FloatCascadertProps = CascaderProps & {
3
+ required?: boolean;
4
+ };
5
+ export declare function FloatCascader({ placeholder, onFocus, onBlur, value, defaultValue, style, required, onChange, ...restProps }: FloatCascadertProps): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,6 @@
1
1
  import { DatePickerProps } from "antd";
2
2
  import "./index.css";
3
3
  export interface FloatDatePickerProps extends DatePickerProps {
4
+ required?: boolean;
4
5
  }
5
- export declare function FloatDatePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }: FloatDatePickerProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function FloatDatePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, required, onChange, ...restProps }: FloatDatePickerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" />
2
+ import { FormItemProps } from "antd";
3
+ export interface FloatFormItemProps extends FormItemProps {
4
+ children?: JSX.Element;
5
+ }
6
+ export declare function FloatFormItem({ children, label, rules, required, ...restProps }: FloatFormItemProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import { InputProps } from "antd";
2
2
  export interface FloatInputProps extends InputProps {
3
+ required?: boolean;
3
4
  }
4
- export declare function FloatInput({ placeholder, onFocus, onBlur, value, defaultValue, style, size, ...restProps }: FloatInputProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare function FloatInput({ placeholder, onFocus, onBlur, onChange, value, defaultValue, style, size, required, ...restProps }: FloatInputProps): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,6 @@
1
1
  import { InputNumberProps } from "antd";
2
2
  import "./index.css";
3
3
  export interface FloatInputNumberProps extends InputNumberProps {
4
+ required?: boolean;
4
5
  }
5
- export declare function FloatInputNumber({ placeholder, onFocus, onBlur, value, defaultValue, style, size, ...restProps }: FloatInputNumberProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function FloatInputNumber({ placeholder, onFocus, onBlur, value, defaultValue, style, onChange, required, ...restProps }: FloatInputNumberProps): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,6 @@
1
1
  import { PasswordProps } from "antd/es/input";
2
2
  import "./index.css";
3
3
  export interface FloatPasswordProps extends PasswordProps {
4
+ required?: boolean;
4
5
  }
5
- export declare function FloatPassword({ placeholder, onFocus, onBlur, value, defaultValue, style, size, ...restProps }: FloatPasswordProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function FloatPassword({ placeholder, onFocus, onBlur, value, defaultValue, style, onChange, required, ...restProps }: FloatPasswordProps): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,6 @@
1
1
  import "./index.css";
2
2
  import { RangePickerProps } from "antd/es/date-picker";
3
3
  export interface FloatRangePickerProps extends RangePickerProps {
4
+ required?: boolean;
4
5
  }
5
- export declare function FloatRangePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }: FloatRangePickerProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function FloatRangePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, onChange, required, ...restProps }: FloatRangePickerProps): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,6 @@
1
1
  import { SelectProps } from "antd";
2
2
  import "./index.css";
3
3
  export interface FloatSelectProps extends SelectProps {
4
+ required?: boolean;
4
5
  }
5
- export declare function FloatSelect({ placeholder, onFocus, onBlur, value, defaultValue, style, size, mode, onChange, ...restProps }: FloatSelectProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function FloatSelect({ placeholder, onFocus, onBlur, value, defaultValue, style, size, mode, onChange, required, ...restProps }: FloatSelectProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import { TimePickerProps } from "antd";
2
2
  export interface FloatTimePickerProps extends TimePickerProps {
3
+ required?: boolean;
3
4
  }
4
- export declare function FloatTimePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, size, mode, onChange, ...restProps }: FloatTimePickerProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare function FloatTimePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, size, mode, onChange, required, ...restProps }: FloatTimePickerProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import { TreeSelectProps } from "antd";
2
2
  export interface FloatTreeSelectProps extends TreeSelectProps {
3
+ required?: boolean;
3
4
  }
4
- export declare function FloatTreeSelect({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }: FloatTreeSelectProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare function FloatTreeSelect({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, required, ...restProps }: FloatTreeSelectProps): import("react/jsx-runtime").JSX.Element;
@@ -9,5 +9,6 @@ export interface FloattingLabelBoxProps {
9
9
  width?: string | number;
10
10
  height?: string | number;
11
11
  status?: InputStatus;
12
+ required?: boolean;
12
13
  }
13
- export declare function FloattingLabelBox({ focused, haveValue, label, children, width, height, status, }: FloattingLabelBoxProps): import("react/jsx-runtime").JSX.Element;
14
+ export declare function FloattingLabelBox({ focused, haveValue, label, children, width, height, status, required, }: FloattingLabelBoxProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ /// <reference types="react" />
2
+ export declare function useValueHandle({ defaultValue, value, id, onFocus, onBlur }: {
3
+ defaultValue?: any;
4
+ value?: any;
5
+ id?: string;
6
+ onFocus?: (...args: any) => void;
7
+ onBlur?: (...args: any) => void;
8
+ }): {
9
+ hasValue: boolean;
10
+ handleChange: import("react").Dispatch<any>;
11
+ handleFocus: (...args: any) => void;
12
+ handleBlur: (...args: any) => void;
13
+ isFocus: boolean;
14
+ };
package/dist/index.css CHANGED
@@ -1,4 +1,4 @@
1
- .ant-float-label-box{position:relative;line-height:normal;}.ant-float-label-box-label{position:absolute;max-width:99%;overflow:hidden;text-overflow:ellipsis;left:0;top:0;font-size:0.85rem;white-space:nowrap;font-weight:400;transform-origin:top left;pointer-events:none;height:100%;display:flex;align-items:center;transition:color 200ms cubic-bezier(0,0,0.2,1) 0ms,transform 200ms cubic-bezier(0,0,0.2,1) 0ms,max-width 200ms cubic-bezier(0,0,0.2,1) 0ms;}.ant-float-label-box-fieldset{padding:0 8px;position:absolute;top:-5px;left:0;right:0;bottom:0;margin:0;pointer-events:none;text-align:left;box-sizing:border-box;min-width:0%;}.ant-float-label-box-legend{width:auto!important;overflow:hidden;display:block;padding:0!important;height:11px!important;font-size:0.85rem!important;visibility:hidden;transition:max-width 100ms cubic-bezier(0.0,0,0.2,1) 50ms;white-space:nowrap;padding-inline:0!important;}
1
+ .ant-float-label-box{position:relative;line-height:normal;}.ant-float-label-box-label{position:absolute;max-width:99%;overflow:hidden;text-overflow:ellipsis;left:0;top:0;font-size:0.85rem;white-space:nowrap;font-weight:400;transform-origin:top left;pointer-events:none;height:100%;display:flex;align-items:center;transition:color 200ms cubic-bezier(0,0,0.2,1) 0ms,transform 200ms cubic-bezier(0,0,0.2,1) 0ms,max-width 200ms cubic-bezier(0,0,0.2,1) 0ms;}.ant-float-label-box-fieldset{padding:0 8px;position:absolute;top:-5px;left:0;right:0;bottom:0;margin:0;pointer-events:none;text-align:left;box-sizing:border-box;min-width:0%;}.ant-float-label-box-legend{width:auto!important;overflow:hidden;display:block;padding:0!important;height:11px!important;font-size:0.85rem!important;visibility:hidden;transition:max-width 100ms cubic-bezier(0,0,0.2,1) 50ms;white-space:nowrap;padding-inline:0!important;}
2
2
  .ant-float-label-form-auto-complete .ant-select-selector {border:none!important;box-shadow:none!important;}
3
3
  .ant-float-label-form-picker {border:none!important;box-shadow:none!important;}
4
4
  .ant-float-label-form-input-number {border:none!important;box-shadow:none!important;}
package/dist/index.d.ts CHANGED
@@ -9,3 +9,4 @@ export * from "./component/FloatTimePicker";
9
9
  export * from "./component/FloattingLabelBox";
10
10
  export * from "./component/FloatTreeSelect";
11
11
  export * from "./component/FloatPassword";
12
+ export * from "./component/FloatFormItem";
package/dist/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import "./index.css"
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { theme, AutoComplete, Cascader, DatePicker, Input, InputNumber, Select, TimePicker, TreeSelect } from 'antd';
4
- import { useMemo, useRef, useState, useCallback, useEffect } from 'react';
3
+ import { theme, Form, AutoComplete, Cascader, DatePicker, Input, InputNumber, Select, TimePicker, TreeSelect } from 'antd';
4
+ import React, { useMemo, useRef, useState, useContext, useCallback, useEffect } from 'react';
5
+ import { FormContext } from 'antd/es/form/context';
5
6
 
6
7
  const { useToken } = theme;
7
- function FloattingLabelBox({ focused, haveValue, label, children, width, height, status, }) {
8
+ function FloattingLabelBox({ focused, haveValue, label, children, width, height, status, required, }) {
8
9
  const { token } = useToken();
9
10
  const statusColor = useMemo(() => {
10
11
  const colors = {
@@ -41,7 +42,7 @@ function FloattingLabelBox({ focused, haveValue, label, children, width, height,
41
42
  transform: focused || haveValue
42
43
  ? "translate(14px, -9px) scale(0.75)"
43
44
  : `translate(1em, 0px) scale(1)`,
44
- }, children: label }), jsx("fieldset", { style: {
45
+ }, children: required ? (jsxs("div", { style: { display: "flex", gap: "0.3em", alignItems: "center" }, children: [jsx("span", { children: label }), jsx("span", { style: { marginTop: "3px" }, children: "*" })] })) : (label) }), jsx("fieldset", { style: {
45
46
  border: focused
46
47
  ? `2px solid ${statusColor.borderColorActive}`
47
48
  : `1px solid ${statusColor.borderColor}`,
@@ -51,29 +52,24 @@ function FloattingLabelBox({ focused, haveValue, label, children, width, height,
51
52
  }, children: label }) })] }));
52
53
  }
53
54
 
54
- function FloatAutoComplete({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }) {
55
+ function useValueHandle({ defaultValue, value, id, onFocus, onBlur }) {
55
56
  const initFlag = useRef(false);
56
57
  const [isFocus, setIsFocus] = useState(false);
58
+ const { form, name: formName } = useContext(FormContext);
57
59
  const [inputValue, setInputValue] = useState(defaultValue ?? value);
58
- const handleFocus = useCallback((e) => {
60
+ const changeValue = Form.useWatch(formName ? id?.replace(formName + "_", "") : id, form);
61
+ const handleFocus = useCallback((...args) => {
59
62
  setIsFocus(true);
60
- if (onFocus) {
61
- onFocus(e);
63
+ if (typeof onFocus === "function") {
64
+ onFocus(...args);
62
65
  }
63
66
  }, [onFocus]);
64
- const handleBlur = useCallback((e) => {
67
+ const handleBlur = useCallback((...args) => {
65
68
  setIsFocus(false);
66
- setInputValue(e.target.value);
67
- if (onBlur) {
68
- onBlur(e);
69
+ if (typeof onBlur === "function") {
70
+ onBlur(args);
69
71
  }
70
72
  }, [onBlur]);
71
- const handleChange = useCallback((value, option) => {
72
- setInputValue(value);
73
- if (onChange) {
74
- onChange(value, option);
75
- }
76
- }, [onChange]);
77
73
  useEffect(() => {
78
74
  if (initFlag.current) {
79
75
  setInputValue(value);
@@ -83,339 +79,219 @@ function FloatAutoComplete({ placeholder, onFocus, onBlur, value, defaultValue,
83
79
  initFlag.current = false;
84
80
  };
85
81
  }, [value]);
86
- return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: !!inputValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(AutoComplete, { style: {
82
+ useEffect(() => {
83
+ if (form && id) {
84
+ setInputValue(changeValue);
85
+ }
86
+ }, [changeValue, form]);
87
+ return {
88
+ hasValue: Array.isArray(inputValue) ? inputValue.length > 0 : typeof value === "number" ? true : !!inputValue,
89
+ handleChange: setInputValue,
90
+ handleFocus,
91
+ handleBlur,
92
+ isFocus
93
+ };
94
+ }
95
+
96
+ function FloatAutoComplete({ placeholder, onFocus, onBlur, value, defaultValue, style, onChange, required, ...restProps }) {
97
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
98
+ id: restProps.id,
99
+ defaultValue,
100
+ value,
101
+ onFocus,
102
+ onBlur,
103
+ });
104
+ const changeHandler = useCallback((value, option) => {
105
+ handleChange(value);
106
+ if (onChange) {
107
+ onChange(value, option);
108
+ }
109
+ }, [onChange]);
110
+ return (jsx(FloattingLabelBox, { label: placeholder, required: required, focused: isFocus, haveValue: hasValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(AutoComplete, { style: {
87
111
  width: "100%",
88
112
  ...style,
89
113
  border: "none",
90
- }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: handleChange, rootClassName: "ant-float-label-form-auto-complete" }) }));
114
+ }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, onChange: changeHandler, rootClassName: "ant-float-label-form-auto-complete" }) }));
91
115
  }
92
116
 
93
- function FloatCascader({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }) {
94
- const initFlag = useRef(false);
95
- const [isFocus, setIsFocus] = useState(false);
96
- const [inputValue, setInputValue] = useState(defaultValue ?? value);
97
- const handleFocus = useCallback((e) => {
98
- setIsFocus(true);
99
- if (onFocus) {
100
- onFocus(e);
101
- }
102
- }, [onFocus]);
103
- const handleBlur = useCallback((e) => {
104
- setIsFocus(false);
105
- if (onBlur) {
106
- onBlur(e);
107
- }
108
- }, [onBlur]);
109
- const handleChange = useCallback((value, selectedOptions) => {
110
- setInputValue(value);
117
+ function FloatCascader({ placeholder, onFocus, onBlur, value, defaultValue, style, required, onChange, ...restProps }) {
118
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
119
+ id: restProps.id,
120
+ defaultValue,
121
+ value,
122
+ onFocus,
123
+ onBlur,
124
+ });
125
+ const changehandler = useCallback((value, selectedOptions) => {
126
+ handleChange(value);
111
127
  if (onChange) {
112
128
  onChange(value, selectedOptions);
113
129
  }
114
130
  }, [onChange]);
115
- useEffect(() => {
116
- if (initFlag.current) {
117
- setInputValue(value);
118
- }
119
- initFlag.current = true;
120
- return () => {
121
- initFlag.current = false;
122
- };
123
- }, [value]);
124
- const haveValue = useMemo(() => {
125
- const currValue = Array.isArray(inputValue) && inputValue.length === 0
126
- ? undefined
127
- : inputValue;
128
- return !!currValue;
129
- }, [inputValue]);
130
- return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: haveValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(Cascader, { style: { ...style, width: "100%", border: "none" }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: handleChange, rootClassName: "ant-float-label-form-select" }) }));
131
+ return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: hasValue, width: style?.width, height: style?.height, required: required, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(Cascader, { style: { ...style, width: "100%", border: "none" }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, onChange: changehandler, rootClassName: "ant-float-label-form-select" }) }));
131
132
  }
132
133
 
133
- function FloatDatePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }) {
134
- const initFlag = useRef(false);
135
- const [isFocus, setIsFocus] = useState(false);
136
- const [inputValue, setInputValue] = useState(defaultValue ?? value);
137
- const handleFocus = useCallback((event, info) => {
138
- setIsFocus(true);
139
- if (onFocus) {
140
- onFocus(event, info);
141
- }
142
- }, [onFocus]);
143
- const handleBlur = useCallback((event, info) => {
144
- setIsFocus(false);
145
- if (onBlur) {
146
- onBlur(event, info);
147
- }
148
- }, [onBlur]);
149
- const handleChange = useCallback((value, dateString) => {
150
- setInputValue(value);
134
+ function FloatDatePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, required, onChange, ...restProps }) {
135
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
136
+ id: restProps.id,
137
+ defaultValue,
138
+ value,
139
+ onFocus,
140
+ onBlur,
141
+ });
142
+ const changeHandler = useCallback((value, dateString) => {
143
+ handleChange(value);
151
144
  if (onChange) {
152
145
  onChange(value, dateString);
153
146
  }
154
147
  }, [onChange]);
155
- useEffect(() => {
156
- if (initFlag.current) {
157
- setInputValue(value);
158
- }
159
- initFlag.current = true;
160
- return () => {
161
- initFlag.current = false;
162
- };
163
- }, [value]);
164
- return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: !!inputValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(DatePicker, { style: { ...style, width: "100%", border: "none" }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: handleChange, rootClassName: "ant-float-label-form-picker", placeholder: "" }) }));
148
+ return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: hasValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), required: required, children: jsx(DatePicker, { style: { ...style, width: "100%", border: "none" }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, onChange: changeHandler, rootClassName: "ant-float-label-form-picker", placeholder: "" }) }));
165
149
  }
166
150
 
167
- function FloatInput({ placeholder, onFocus, onBlur, value, defaultValue, style, size, ...restProps }) {
168
- const initFlag = useRef(false);
169
- const [isFocus, setIsFocus] = useState(false);
170
- const [inputValue, setInputValue] = useState(defaultValue ?? value);
171
- const handleFocus = useCallback((e) => {
172
- setIsFocus(true);
173
- if (onFocus) {
174
- onFocus(e);
175
- }
176
- }, [onFocus]);
177
- const handleBlur = useCallback((e) => {
178
- setIsFocus(false);
179
- setInputValue(e.target.value);
180
- if (onBlur) {
181
- onBlur(e);
182
- }
183
- }, [onBlur]);
184
- useEffect(() => {
185
- if (initFlag.current) {
186
- setInputValue(value);
151
+ function FloatInput({ placeholder, onFocus, onBlur, onChange, value, defaultValue, style, size, required, ...restProps }) {
152
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
153
+ id: restProps.id,
154
+ defaultValue,
155
+ value,
156
+ onFocus,
157
+ onBlur,
158
+ });
159
+ const changeHandler = useCallback((e) => {
160
+ handleChange(e.target.value);
161
+ if (onChange) {
162
+ onChange(e);
187
163
  }
188
- initFlag.current = true;
189
- return () => {
190
- initFlag.current = false;
191
- };
192
- }, [value]);
193
- return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: !!inputValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(Input, { style: { ...style, width: "100%", border: "none" }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size }) }));
164
+ }, [onChange]);
165
+ return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: hasValue, width: style?.width, height: style?.height, required: required, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(Input, { style: { ...style, width: "100%", border: "none" }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, onChange: changeHandler, size: size }) }));
194
166
  }
195
167
 
196
- function FloatInputNumber({ placeholder, onFocus, onBlur, value, defaultValue, style, size, ...restProps }) {
197
- const initFlag = useRef(false);
198
- const [isFocus, setIsFocus] = useState(false);
199
- const [inputValue, setInputValue] = useState(defaultValue ?? value);
200
- const handleFocus = useCallback((e) => {
201
- setIsFocus(true);
202
- if (onFocus) {
203
- onFocus(e);
204
- }
205
- }, [onFocus]);
206
- const handleBlur = useCallback((e) => {
207
- setIsFocus(false);
208
- setInputValue(e.target.value);
209
- if (onBlur) {
210
- onBlur(e);
211
- }
212
- }, [onBlur]);
213
- useEffect(() => {
214
- if (initFlag.current) {
215
- setInputValue(value);
168
+ function FloatInputNumber({ placeholder, onFocus, onBlur, value, defaultValue, style, onChange, required, ...restProps }) {
169
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
170
+ id: restProps.id,
171
+ defaultValue,
172
+ value,
173
+ onFocus,
174
+ onBlur,
175
+ });
176
+ const changeHanlder = useCallback((value) => {
177
+ handleChange(value);
178
+ if (onChange) {
179
+ onChange(value);
216
180
  }
217
- initFlag.current = true;
218
- return () => {
219
- initFlag.current = false;
220
- };
221
- }, [value]);
222
- return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: !!inputValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(InputNumber, { style: { ...style, width: "100%", border: "none" }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, rootClassName: "ant-float-label-form-input-number" }) }));
181
+ }, [onChange]);
182
+ return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: hasValue, width: style?.width, height: style?.height, required: required, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(InputNumber, { style: { ...style, width: "100%", border: "none" }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, onChange: changeHanlder, rootClassName: "ant-float-label-form-input-number" }) }));
223
183
  }
224
184
 
225
185
  const { RangePicker } = DatePicker;
226
- function FloatRangePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }) {
227
- const initFlag = useRef(false);
228
- const [isFocus, setIsFocus] = useState(false);
229
- const [inputValue, setInputValue] = useState(defaultValue ?? value);
230
- const handleFocus = useCallback((event, info) => {
231
- setIsFocus(true);
232
- if (onFocus) {
233
- onFocus(event, info);
234
- }
235
- }, [onFocus]);
236
- const handleBlur = useCallback((event, info) => {
237
- setIsFocus(false);
238
- if (onBlur) {
239
- onBlur(event, info);
240
- }
241
- }, [onBlur]);
242
- const handleChange = useCallback((value, dateString) => {
243
- setInputValue(value);
186
+ function FloatRangePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, onChange, required, ...restProps }) {
187
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
188
+ id: restProps.id?.toString(),
189
+ defaultValue,
190
+ value,
191
+ onFocus,
192
+ onBlur,
193
+ });
194
+ const changeHandler = useCallback((value, dateString) => {
195
+ handleChange(value);
244
196
  if (onChange) {
245
197
  onChange(value, dateString);
246
198
  }
247
199
  }, [onChange]);
248
- useEffect(() => {
249
- if (initFlag.current) {
250
- setInputValue(value);
251
- }
252
- initFlag.current = true;
253
- return () => {
254
- initFlag.current = false;
255
- };
256
- }, [value]);
257
200
  const haveValue = useMemo(() => {
258
- return !!(isFocus || inputValue);
259
- }, [inputValue, isFocus]);
260
- return (jsx(FloattingLabelBox, { label: haveValue && placeholder ? placeholder.join(" - ") : "", focused: isFocus, haveValue: haveValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(RangePicker, { style: { ...style, width: "100%", border: "none" }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: handleChange, rootClassName: "ant-float-label-form-picker", placeholder: haveValue ? ["", ""] : placeholder }) }));
201
+ return isFocus || hasValue;
202
+ }, [hasValue, isFocus]);
203
+ return (jsx(FloattingLabelBox, { label: haveValue && placeholder ? placeholder.join(" - ") : "", focused: isFocus, haveValue: haveValue, width: style?.width, height: style?.height, required: required, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(RangePicker, { style: { ...style, width: "100%", border: "none" }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, onChange: changeHandler, rootClassName: "ant-float-label-form-picker", placeholder: hasValue ? ["", ""] : placeholder }) }));
261
204
  }
262
205
 
263
- function FloatSelect({ placeholder, onFocus, onBlur, value, defaultValue, style, size, mode, onChange, ...restProps }) {
264
- const initFlag = useRef(false);
265
- const [isFocus, setIsFocus] = useState(false);
266
- const [inputValue, setInputValue] = useState(defaultValue ?? value);
267
- const handleFocus = useCallback((e) => {
268
- setIsFocus(true);
269
- if (onFocus) {
270
- onFocus(e);
271
- }
272
- }, [onFocus]);
273
- const handleBlur = useCallback((e) => {
274
- setIsFocus(false);
275
- if (onBlur) {
276
- onBlur(e);
277
- }
278
- }, [onBlur]);
279
- const handleChange = useCallback((value, option) => {
280
- setInputValue(value);
206
+ function FloatSelect({ placeholder, onFocus, onBlur, value, defaultValue, style, size, mode, onChange, required, ...restProps }) {
207
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
208
+ id: restProps.id?.toString(),
209
+ defaultValue,
210
+ value,
211
+ onFocus,
212
+ onBlur,
213
+ });
214
+ const changeHandler = useCallback((value, option) => {
215
+ handleChange(value);
281
216
  if (onChange) {
282
217
  onChange(value, option);
283
218
  }
284
219
  }, [onChange]);
285
- useEffect(() => {
286
- if (initFlag.current) {
287
- setInputValue(value);
288
- }
289
- initFlag.current = true;
290
- return () => {
291
- initFlag.current = false;
292
- };
293
- }, [value]);
294
- const haveValue = useMemo(() => {
295
- const currValue = Array.isArray(inputValue) && inputValue.length === 0
296
- ? undefined
297
- : inputValue;
298
- return !!currValue;
299
- }, [inputValue]);
300
- return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: haveValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(Select, { style: { ...style, width: "100%", border: "none" }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: handleChange, mode: mode, rootClassName: "ant-float-label-form-select" }) }));
220
+ return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: hasValue, width: style?.width, height: style?.height, required: required, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(Select, { style: { ...style, width: "100%", border: "none" }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: changeHandler, mode: mode, rootClassName: "ant-float-label-form-select" }) }));
301
221
  }
302
222
 
303
- function FloatTimePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, size, mode, onChange, ...restProps }) {
304
- const initFlag = useRef(false);
305
- const [isFocus, setIsFocus] = useState(false);
306
- const [inputValue, setInputValue] = useState(defaultValue ?? value);
307
- const handleFocus = useCallback((e, info) => {
308
- setIsFocus(true);
309
- if (onFocus) {
310
- onFocus(e, info);
311
- }
312
- }, [onFocus]);
313
- const handleBlur = useCallback((e, info) => {
314
- setIsFocus(false);
315
- if (onBlur) {
316
- onBlur(e, info);
317
- }
318
- }, [onBlur]);
319
- const handleChange = useCallback((value, option) => {
320
- setInputValue(value);
223
+ function FloatTimePicker({ placeholder, onFocus, onBlur, value, defaultValue, style, size, mode, onChange, required, ...restProps }) {
224
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
225
+ id: restProps.id?.toString(),
226
+ defaultValue,
227
+ value,
228
+ onFocus,
229
+ onBlur,
230
+ });
231
+ const changeHandler = useCallback((value, option) => {
232
+ handleChange(value);
321
233
  if (onChange) {
322
234
  onChange(value, option);
323
235
  }
324
236
  }, [onChange]);
325
- useEffect(() => {
326
- if (initFlag.current) {
327
- setInputValue(value);
328
- }
329
- initFlag.current = true;
330
- return () => {
331
- initFlag.current = false;
332
- };
333
- }, [value]);
334
- const haveValue = useMemo(() => {
335
- const currValue = Array.isArray(inputValue) && inputValue.length === 0
336
- ? undefined
337
- : inputValue;
338
- return !!currValue;
339
- }, [inputValue]);
340
- return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: haveValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(TimePicker, { style: {
237
+ return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: hasValue, width: style?.width, height: style?.height, required: required, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(TimePicker, { style: {
341
238
  ...style,
342
239
  width: "100%",
343
240
  border: "none",
344
- }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: handleChange, mode: mode, rootClassName: "ant-float-label-form-select", placeholder: "" }) }));
241
+ }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: changeHandler, mode: mode, rootClassName: "ant-float-label-form-select", placeholder: "" }) }));
345
242
  }
346
243
 
347
- function FloatTreeSelect({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, ...restProps }) {
348
- const initFlag = useRef(false);
349
- const [isFocus, setIsFocus] = useState(false);
350
- const [inputValue, setInputValue] = useState(defaultValue ?? value);
351
- const handleFocus = useCallback((e) => {
352
- setIsFocus(true);
353
- if (onFocus) {
354
- onFocus(e);
355
- }
356
- }, [onFocus]);
357
- const handleBlur = useCallback((e) => {
358
- setIsFocus(false);
359
- if (onBlur) {
360
- onBlur(e);
361
- }
362
- }, [onBlur]);
363
- const handleChange = useCallback((value, labelList, extra) => {
364
- setInputValue(value);
244
+ function FloatTreeSelect({ placeholder, onFocus, onBlur, value, defaultValue, style, size, onChange, required, ...restProps }) {
245
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
246
+ id: restProps.id?.toString(),
247
+ defaultValue,
248
+ value,
249
+ onFocus,
250
+ onBlur,
251
+ });
252
+ const changeHandler = useCallback((value, labelList, extra) => {
253
+ handleChange(value);
365
254
  if (onChange) {
366
255
  onChange(value, labelList, extra);
367
256
  }
368
257
  }, [onChange]);
369
- useEffect(() => {
370
- if (initFlag.current) {
371
- setInputValue(value);
372
- }
373
- initFlag.current = true;
374
- return () => {
375
- initFlag.current = false;
376
- };
377
- }, [value]);
378
- const haveValue = useMemo(() => {
379
- const currValue = Array.isArray(inputValue) && inputValue.length === 0
380
- ? undefined
381
- : inputValue;
382
- return !!currValue;
383
- }, [inputValue]);
384
- return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: haveValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(TreeSelect, { style: {
258
+ return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: hasValue, width: style?.width, height: style?.height, required: required, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(TreeSelect, { style: {
385
259
  ...style,
386
260
  width: "100%",
387
261
  border: "none",
388
- }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: handleChange, rootClassName: "ant-float-label-form-select" }) }));
262
+ }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, onChange: changeHandler, rootClassName: "ant-float-label-form-select" }) }));
389
263
  }
390
264
 
391
265
  const { Password } = Input;
392
- function FloatPassword({ placeholder, onFocus, onBlur, value, defaultValue, style, size, ...restProps }) {
393
- const initFlag = useRef(false);
394
- const [isFocus, setIsFocus] = useState(false);
395
- const [inputValue, setInputValue] = useState(defaultValue ?? value);
396
- const handleFocus = useCallback((e) => {
397
- setIsFocus(true);
398
- if (onFocus) {
399
- onFocus(e);
400
- }
401
- }, [onFocus]);
402
- const handleBlur = useCallback((e) => {
403
- setIsFocus(false);
404
- setInputValue(e.target.value);
405
- if (onBlur) {
406
- onBlur(e);
407
- }
408
- }, [onBlur]);
409
- useEffect(() => {
410
- if (initFlag.current) {
411
- setInputValue(value);
266
+ function FloatPassword({ placeholder, onFocus, onBlur, value, defaultValue, style, onChange, required, ...restProps }) {
267
+ const { hasValue, handleChange, handleBlur, handleFocus, isFocus } = useValueHandle({
268
+ id: restProps.id,
269
+ defaultValue,
270
+ value,
271
+ onFocus,
272
+ onBlur,
273
+ });
274
+ const changeHanlder = useCallback((value) => {
275
+ handleChange(value);
276
+ if (onChange) {
277
+ onChange(value);
412
278
  }
413
- initFlag.current = true;
414
- return () => {
415
- initFlag.current = false;
416
- };
417
- }, [value]);
418
- return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: !!inputValue, width: style?.width, height: style?.height, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(Password, { style: { ...style, width: "100%", border: "none" }, ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, size: size, rootClassName: "ant-float-label-form-input-password" }) }));
279
+ }, [onChange]);
280
+ return (jsx(FloattingLabelBox, { label: placeholder, focused: isFocus, haveValue: hasValue, width: style?.width, height: style?.height, required: required, status: restProps.status || (restProps["aria-invalid"] ? "error" : undefined), children: jsx(Password, { style: { ...style, width: "100%", border: "none" }, variant: "borderless", ...restProps, onFocus: handleFocus, onBlur: handleBlur, value: value, defaultValue: defaultValue, onChange: changeHanlder, rootClassName: "ant-float-label-form-input-password" }) }));
281
+ }
282
+
283
+ function FloatFormItem({ children, label = "", rules, required, ...restProps }) {
284
+ const isRequired = useMemo(() => {
285
+ if (required)
286
+ return required;
287
+ return rules?.some((value) => value.required !== undefined && value.required !== false);
288
+ }, [required, rules]);
289
+ return (jsx(Form.Item, { required: required, rules: rules, ...restProps, children: children
290
+ ? React.cloneElement(children, {
291
+ placeholder: label,
292
+ required: isRequired,
293
+ })
294
+ : children }));
419
295
  }
420
296
 
421
- export { FloatAutoComplete, FloatCascader, FloatDatePicker, FloatInput, FloatInputNumber, FloatPassword, FloatRangePicker, FloatSelect, FloatTimePicker, FloatTreeSelect, FloattingLabelBox };
297
+ export { FloatAutoComplete, FloatCascader, FloatDatePicker, FloatFormItem, FloatInput, FloatInputNumber, FloatPassword, FloatRangePicker, FloatSelect, FloatTimePicker, FloatTreeSelect, FloattingLabelBox };
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ant-float-label",
3
- "version": "1.0.7",
3
+ "version": "1.1.0",
4
4
  "description": "Antd 5 form style similar to MUI",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ant-float-label",
3
- "version": "1.0.7",
3
+ "version": "1.1.0",
4
4
  "description": "Antd 5 form style similar to MUI",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",