react-artasys-ui 0.1.5 → 0.1.7
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/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/lib/Form/Element/Element.d.ts +1 -1
- package/lib/Select/Select.d.ts +4 -2
- package/package.json +1 -1
- package/src/Form/Element/Element.tsx +2 -2
- package/src/Input/Input.tsx +1 -0
- package/src/Select/Option.tsx +5 -1
- package/src/Select/Select.tsx +78 -16
- package/src/Select/style.module.css +17 -2
|
@@ -10,5 +10,5 @@ export interface IElement<T = any> extends Omit<AllHTMLAttributes<T>, 'children'
|
|
|
10
10
|
afterElement?: React.ReactElement;
|
|
11
11
|
hiddenContainer?: boolean;
|
|
12
12
|
}
|
|
13
|
-
declare const Element: ({ children, beforeElement, afterElement, error, placeholder,
|
|
13
|
+
declare const Element: ({ children, beforeElement, afterElement, error, placeholder, styleContainer, classNameContainer, hiddenContainer, ...props }: IElement) => JSX.Element;
|
|
14
14
|
export default Element;
|
package/lib/Select/Select.d.ts
CHANGED
|
@@ -3,12 +3,14 @@ import { IElement } from "../Form/Element";
|
|
|
3
3
|
import type { IOption } from "./Option";
|
|
4
4
|
export declare const Context: import("react").Context<{
|
|
5
5
|
selected: string;
|
|
6
|
+
emptyValue: import("react").MutableRefObject<boolean>;
|
|
6
7
|
setSelect: (value: string) => void;
|
|
8
|
+
setSelected: (value: string) => void;
|
|
7
9
|
setTitle: (title: string) => void;
|
|
8
10
|
}>;
|
|
9
|
-
export interface ISelect extends Omit<IElement, 'children'
|
|
11
|
+
export interface ISelect extends Omit<IElement, 'children'> {
|
|
10
12
|
children?: React.FunctionComponentElement<IOption>[];
|
|
11
|
-
|
|
13
|
+
onChangeSelect?: (value: string) => void;
|
|
12
14
|
}
|
|
13
15
|
declare const Select: import("react").ForwardRefExoticComponent<ISelect & import("react").RefAttributes<HTMLInputElement>>;
|
|
14
16
|
export default Select;
|
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@ export interface IElement<T = any> extends Omit<AllHTMLAttributes<T>, 'children'
|
|
|
19
19
|
hiddenContainer?: boolean;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const Element = ({children, beforeElement, afterElement, error, placeholder,
|
|
22
|
+
const Element = ({children, beforeElement, afterElement, error, placeholder, styleContainer, classNameContainer, hiddenContainer, ...props}: IElement) => {
|
|
23
23
|
const [currentError, setCurrentError] = useState('');
|
|
24
24
|
|
|
25
25
|
useEffect(() => {
|
|
@@ -30,7 +30,7 @@ const Element = ({children, beforeElement, afterElement, error, placeholder, dis
|
|
|
30
30
|
|
|
31
31
|
classes.push(styles['container']);
|
|
32
32
|
if (currentError) classes.push(styles['error']);
|
|
33
|
-
if (disabled) classes.push(styles['disabled']);
|
|
33
|
+
if (props.disabled) classes.push(styles['disabled']);
|
|
34
34
|
if (hiddenContainer) classes.push(styles['hidden']);
|
|
35
35
|
if (classNameContainer) classes.push(classNameContainer);
|
|
36
36
|
|
package/src/Input/Input.tsx
CHANGED
package/src/Select/Option.tsx
CHANGED
|
@@ -24,8 +24,12 @@ const Option = ({children, value, onClick, ...props}: IOption) => {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
useEffect(() => {
|
|
27
|
-
if (value === context.selected
|
|
27
|
+
if (children && (value === context.selected || !context.emptyValue.current)) {
|
|
28
28
|
context.setTitle(children?.toString());
|
|
29
|
+
if (!context.emptyValue.current && value) {
|
|
30
|
+
context.setSelected(value);
|
|
31
|
+
}
|
|
32
|
+
context.emptyValue.current = true;
|
|
29
33
|
}
|
|
30
34
|
}, [context.selected]);
|
|
31
35
|
|
package/src/Select/Select.tsx
CHANGED
|
@@ -3,7 +3,9 @@ import {
|
|
|
3
3
|
createContext,
|
|
4
4
|
useState,
|
|
5
5
|
useEffect,
|
|
6
|
-
useRef
|
|
6
|
+
useRef,
|
|
7
|
+
ChangeEvent,
|
|
8
|
+
useImperativeHandle
|
|
7
9
|
} from "react";
|
|
8
10
|
import Element,{
|
|
9
11
|
IElement
|
|
@@ -13,54 +15,114 @@ import styles from "./style.module.css";
|
|
|
13
15
|
|
|
14
16
|
export const Context = createContext({
|
|
15
17
|
selected: '',
|
|
18
|
+
emptyValue: {current:{}} as React.MutableRefObject<boolean>,
|
|
16
19
|
setSelect: (value: string) => {},
|
|
17
|
-
|
|
20
|
+
setSelected: (value: string) => {},
|
|
21
|
+
setTitle: (title: string) => {},
|
|
18
22
|
});
|
|
19
23
|
|
|
20
|
-
export interface ISelect extends Omit<IElement, 'children'
|
|
24
|
+
export interface ISelect extends Omit<IElement, 'children'> {
|
|
21
25
|
children?: React.FunctionComponentElement<IOption>[];
|
|
22
|
-
|
|
26
|
+
onChangeSelect?: (value: string) => void;
|
|
23
27
|
};
|
|
24
28
|
|
|
25
|
-
const Select = forwardRef<HTMLInputElement, ISelect>(({children,
|
|
29
|
+
const Select = forwardRef<HTMLInputElement, ISelect>(({children, onChangeSelect, value, ...props}, ref) => {
|
|
26
30
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
31
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
32
|
+
const emptyValue = useRef(false);
|
|
27
33
|
|
|
34
|
+
const [isOpen, setOpen] = useState(false);
|
|
28
35
|
const [selected, setSelected] = useState('');
|
|
29
36
|
const [title, setTitle] = useState<string>();
|
|
30
37
|
|
|
31
38
|
const open = () => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
element?.focus();
|
|
39
|
+
if (props.disabled) return;
|
|
40
|
+
setOpen(true);
|
|
35
41
|
};
|
|
36
42
|
|
|
37
43
|
const close = () => {
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
setOpen(false);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleClick = () => {
|
|
48
|
+
isOpen ? close() : open();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const triggerNativeEvent = (value: string) => {
|
|
52
|
+
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
|
|
53
|
+
nativeInputValueSetter?.call(inputRef.current, value);
|
|
54
|
+
|
|
55
|
+
const event = new Event('input', { bubbles: true});
|
|
56
|
+
inputRef.current!.dispatchEvent(event);
|
|
40
57
|
};
|
|
41
58
|
|
|
42
59
|
const setSelect = (value: string) => {
|
|
43
|
-
if (typeof
|
|
44
|
-
|
|
60
|
+
if (typeof onChangeSelect === 'function') {
|
|
61
|
+
onChangeSelect(value);
|
|
45
62
|
}
|
|
63
|
+
|
|
46
64
|
setSelected(value);
|
|
47
65
|
close();
|
|
48
66
|
};
|
|
49
67
|
|
|
68
|
+
const handleInput = (e: ChangeEvent<HTMLInputElement>) => {
|
|
69
|
+
if (props.disabled) return;
|
|
70
|
+
if (typeof props.onInput === 'function') {
|
|
71
|
+
props.onInput(e);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (typeof props.onChange === 'function') {
|
|
75
|
+
props.onChange(e);
|
|
76
|
+
}
|
|
77
|
+
setSelected(e.target.value);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (!selected) return;
|
|
82
|
+
triggerNativeEvent(selected);
|
|
83
|
+
}, [selected]);
|
|
84
|
+
|
|
50
85
|
useEffect(() => {
|
|
51
86
|
if (typeof value === 'undefined') return;
|
|
52
87
|
setSelected(String(value));
|
|
53
88
|
}, [value]);
|
|
89
|
+
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
const element = containerRef.current;
|
|
92
|
+
const classList = element!.classList;
|
|
93
|
+
if (isOpen) {
|
|
94
|
+
classList.remove(styles['hidden']);
|
|
95
|
+
requestAnimationFrame(() => {
|
|
96
|
+
classList.add(styles['opened']);
|
|
97
|
+
element?.focus();
|
|
98
|
+
});
|
|
99
|
+
}else{
|
|
100
|
+
if (classList.contains(styles['opened'])) {
|
|
101
|
+
element!.ontransitionend = () => {
|
|
102
|
+
classList.add(styles['hidden']);
|
|
103
|
+
element!.ontransitionend = null;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
classList.remove(styles['opened']);
|
|
107
|
+
}
|
|
108
|
+
}, [isOpen]);
|
|
109
|
+
|
|
110
|
+
useImperativeHandle(ref, () => inputRef.current as HTMLInputElement, []);
|
|
111
|
+
|
|
112
|
+
const classes = [''];
|
|
113
|
+
classes.push(styles['container'], styles['hidden']);
|
|
54
114
|
|
|
55
|
-
return(<Element {...props}
|
|
115
|
+
return(<Element {...props} classNameContainer={styles['container-element']}>
|
|
56
116
|
{ (props) => <Context.Provider value={{
|
|
57
117
|
selected,
|
|
118
|
+
emptyValue: emptyValue,
|
|
58
119
|
setSelect,
|
|
120
|
+
setSelected,
|
|
59
121
|
setTitle
|
|
60
122
|
}}>
|
|
61
|
-
<input {...props} type="hidden" value={selected} ref={
|
|
62
|
-
<div className={
|
|
63
|
-
<div className={styles['select']} onClick={
|
|
123
|
+
<input {...props} type="hidden" value={selected} onInput={handleInput} ref={inputRef}/>
|
|
124
|
+
<div className={classes.join(' ')} ref={containerRef} tabIndex={1} onBlur={close}>
|
|
125
|
+
<div className={styles['select']} onClick={handleClick}>
|
|
64
126
|
<span className={styles['title']}>{title}</span>
|
|
65
127
|
</div>
|
|
66
128
|
<ul className={styles['select-list']}>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/* Select */
|
|
2
2
|
|
|
3
|
+
.container-element {
|
|
4
|
+
z-index: 1;
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
.container {
|
|
4
8
|
position: relative;
|
|
5
9
|
display: flex;
|
|
@@ -13,7 +17,8 @@
|
|
|
13
17
|
display: flex;
|
|
14
18
|
flex-direction: row;
|
|
15
19
|
align-items: center;
|
|
16
|
-
min-height:
|
|
20
|
+
min-height: 45px;
|
|
21
|
+
box-sizing: border-box;
|
|
17
22
|
padding: 10px;
|
|
18
23
|
}
|
|
19
24
|
|
|
@@ -28,6 +33,10 @@
|
|
|
28
33
|
transition: rotate 0.3s;
|
|
29
34
|
}
|
|
30
35
|
|
|
36
|
+
.container-element:has(input[type="hidden"]:disabled) .select::after {
|
|
37
|
+
border-top-color: #CCCCCC;
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
.container.opened > .select::after {
|
|
32
41
|
rotate: 180deg;
|
|
33
42
|
}
|
|
@@ -37,6 +46,8 @@
|
|
|
37
46
|
display: flex;
|
|
38
47
|
flex-direction: column;
|
|
39
48
|
width: 100%;
|
|
49
|
+
max-height: 40vh;
|
|
50
|
+
max-height: 40dvh;
|
|
40
51
|
top: calc(100% - 1px);
|
|
41
52
|
left: -1px;
|
|
42
53
|
margin: 0;
|
|
@@ -44,8 +55,8 @@
|
|
|
44
55
|
list-style-type: none;
|
|
45
56
|
background-color: #FFFFFF;
|
|
46
57
|
box-shadow: 0px 4px 5px 0px rgb(0 0 0 / 10%);
|
|
47
|
-
box-shadow: 0px 4px 5px 0px rgb(0 0 0 / 10%);
|
|
48
58
|
border: 1px solid #CCCCCC;
|
|
59
|
+
overflow: auto;
|
|
49
60
|
border-top: 0;
|
|
50
61
|
opacity: 0;
|
|
51
62
|
visibility: hidden;
|
|
@@ -53,6 +64,10 @@
|
|
|
53
64
|
transition: transform 0.3s ease-in-out, opacity 0.3s, visibility 0.3s;
|
|
54
65
|
}
|
|
55
66
|
|
|
67
|
+
.container.hidden > .select-list {
|
|
68
|
+
display: none;
|
|
69
|
+
}
|
|
70
|
+
|
|
56
71
|
.container.opened > .select-list {
|
|
57
72
|
opacity: 1;
|
|
58
73
|
transform: translateY(0);
|