react-artasys-ui 0.1.21 → 0.1.22

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 (132) hide show
  1. package/dist/index.js +2 -2
  2. package/dist/index.js.map +1 -1
  3. package/lib/Button/Button.d.ts +12 -10
  4. package/lib/Button/index.d.ts +3 -2
  5. package/lib/Checkbox/Checkbox.d.ts +7 -7
  6. package/lib/Components/Arrow/Arrow.d.ts +6 -6
  7. package/lib/Dropdown/Dropdown.d.ts +18 -17
  8. package/lib/Dropdown/Item.d.ts +11 -11
  9. package/lib/Dropdown/Items.d.ts +6 -6
  10. package/lib/File/File.d.ts +18 -17
  11. package/lib/FileInput/FileInput.d.ts +13 -0
  12. package/lib/FileInput/index.d.ts +3 -0
  13. package/lib/Form/Element/Element.d.ts +16 -15
  14. package/lib/Form/Form.d.ts +10 -11
  15. package/lib/Input/Input.d.ts +11 -8
  16. package/lib/Loading/Loading.d.ts +6 -0
  17. package/lib/Loading/index.d.ts +3 -0
  18. package/lib/Progress/Progress.d.ts +7 -7
  19. package/lib/Provider/Provider.d.ts +7 -0
  20. package/lib/Provider/ProviderContext.d.ts +1 -0
  21. package/lib/Provider/index.d.ts +2 -0
  22. package/lib/Select/Optgroup.d.ts +7 -8
  23. package/lib/Select/Option.d.ts +8 -8
  24. package/lib/Select/Select.d.ts +18 -18
  25. package/lib/Spinner/Spinner.d.ts +8 -7
  26. package/lib/Spinner/index.d.ts +3 -3
  27. package/lib/TextArea/TextArea.d.ts +10 -7
  28. package/lib/UploadImages/Image.d.ts +16 -16
  29. package/lib/UploadImages/UploadImages.d.ts +9 -9
  30. package/lib/index.d.ts +19 -16
  31. package/lib/src/Button/Button.d.ts +12 -0
  32. package/lib/src/Button/index.d.ts +3 -0
  33. package/lib/src/Checkbox/Checkbox.d.ts +7 -0
  34. package/{src/Checkbox/index.tsx → lib/src/Checkbox/index.d.ts} +2 -2
  35. package/lib/src/Components/Arrow/Arrow.d.ts +6 -0
  36. package/{src/Components/Arrow/index.tsx → lib/src/Components/Arrow/index.d.ts} +2 -3
  37. package/lib/src/Dropdown/Dropdown.d.ts +18 -0
  38. package/lib/src/Dropdown/Item.d.ts +11 -0
  39. package/lib/src/Dropdown/Items.d.ts +6 -0
  40. package/lib/src/Dropdown/index.d.ts +9 -0
  41. package/lib/src/File/File.d.ts +18 -0
  42. package/lib/src/File/index.d.ts +3 -0
  43. package/lib/src/FileInput/FileInput.d.ts +14 -0
  44. package/lib/src/FileInput/index.d.ts +3 -0
  45. package/lib/src/Form/Element/Element.d.ts +16 -0
  46. package/lib/src/Form/Element/index.d.ts +3 -0
  47. package/lib/src/Form/Form.d.ts +10 -0
  48. package/{src/Form/index.tsx → lib/src/Form/index.d.ts} +5 -8
  49. package/{src/Form/types.ts → lib/src/Form/types.d.ts} +11 -17
  50. package/lib/src/Form/useForm.d.ts +17 -0
  51. package/lib/src/Input/Input.d.ts +11 -0
  52. package/{src/Input/index.tsx → lib/src/Input/index.d.ts} +2 -3
  53. package/lib/src/Loading/Loading.d.ts +6 -0
  54. package/lib/src/Loading/index.d.ts +3 -0
  55. package/lib/src/Progress/Progress.d.ts +7 -0
  56. package/{src/Progress/index.tsx → lib/src/Progress/index.d.ts} +2 -3
  57. package/lib/src/Provider/Provider.d.ts +7 -0
  58. package/lib/src/Provider/ProviderContext.d.ts +1 -0
  59. package/lib/src/Provider/index.d.ts +2 -0
  60. package/lib/src/Select/Optgroup.d.ts +7 -0
  61. package/lib/src/Select/Option.d.ts +8 -0
  62. package/lib/src/Select/Select.d.ts +18 -0
  63. package/lib/src/Select/index.d.ts +11 -0
  64. package/lib/src/Spinner/Spinner.d.ts +8 -0
  65. package/lib/src/Spinner/index.d.ts +3 -0
  66. package/lib/src/TextArea/TextArea.d.ts +9 -0
  67. package/{src/TextArea/index.tsx → lib/src/TextArea/index.d.ts} +2 -3
  68. package/lib/src/UploadImages/Image.d.ts +16 -0
  69. package/lib/src/UploadImages/UploadImages.d.ts +9 -0
  70. package/lib/src/UploadImages/index.d.ts +5 -0
  71. package/lib/src/index.d.ts +19 -0
  72. package/lib/src/ui-types.d.ts +3 -0
  73. package/lib/stories/Button.stories.d.ts +6 -0
  74. package/lib/stories/Checkbox.stories.d.ts +6 -0
  75. package/lib/stories/Dropdown/Dropdown.stories.d.ts +6 -0
  76. package/lib/stories/Dropdown/Item.stories.d.ts +6 -0
  77. package/lib/stories/Dropdown/Items.stories.d.ts +6 -0
  78. package/lib/stories/File.stories.d.ts +6 -0
  79. package/lib/stories/FileInput.stories.d.ts +9 -0
  80. package/lib/stories/Form/Element/Element.stories.d.ts +6 -0
  81. package/lib/stories/Form/Form.stories.d.ts +6 -0
  82. package/lib/stories/Input.stories.d.ts +6 -0
  83. package/lib/stories/Loading.stories.d.ts +6 -0
  84. package/lib/stories/Progress.stories.d.ts +6 -0
  85. package/lib/stories/Select/Select.stories.d.ts +6 -0
  86. package/lib/stories/Spinner.stories.d.ts +6 -0
  87. package/lib/stories/TextArea.stories.d.ts +6 -0
  88. package/lib/ui-types.d.ts +3 -0
  89. package/package.json +26 -5
  90. package/__tests__/static.test.js +0 -0
  91. package/babel.config.json +0 -3
  92. package/src/Button/Button.tsx +0 -29
  93. package/src/Button/index.tsx +0 -3
  94. package/src/Button/style.module.css +0 -45
  95. package/src/Checkbox/Checkbox.tsx +0 -22
  96. package/src/Checkbox/style.module.css +0 -74
  97. package/src/Components/Arrow/Arrow.tsx +0 -18
  98. package/src/Components/Arrow/style.module.css +0 -40
  99. package/src/Dropdown/Dropdown.tsx +0 -114
  100. package/src/Dropdown/Item.tsx +0 -42
  101. package/src/Dropdown/Items.tsx +0 -38
  102. package/src/Dropdown/index.tsx +0 -28
  103. package/src/Dropdown/style.module.css +0 -89
  104. package/src/File/File.tsx +0 -85
  105. package/src/File/index.tsx +0 -9
  106. package/src/Form/Element/Element.tsx +0 -54
  107. package/src/Form/Element/index.tsx +0 -7
  108. package/src/Form/Element/style.module.css +0 -119
  109. package/src/Form/Form.tsx +0 -40
  110. package/src/Form/style.module.css +0 -30
  111. package/src/Form/useForm.tsx +0 -76
  112. package/src/Input/Input.tsx +0 -49
  113. package/src/Input/style.module.css +0 -16
  114. package/src/Progress/Progress.tsx +0 -28
  115. package/src/Progress/style.module.css +0 -72
  116. package/src/Select/Optgroup.tsx +0 -19
  117. package/src/Select/Option.tsx +0 -47
  118. package/src/Select/Select.tsx +0 -143
  119. package/src/Select/index.tsx +0 -33
  120. package/src/Select/style.module.css +0 -117
  121. package/src/Spinner/Spinner.tsx +0 -21
  122. package/src/Spinner/index.tsx +0 -8
  123. package/src/Spinner/style.module.css +0 -65
  124. package/src/TextArea/TextArea.tsx +0 -57
  125. package/src/UploadImages/Image.tsx +0 -86
  126. package/src/UploadImages/UploadImages.tsx +0 -57
  127. package/src/UploadImages/index.tsx +0 -13
  128. package/src/UploadImages/style.module.css +0 -108
  129. package/src/index.ts +0 -62
  130. package/tsconfig.json +0 -118
  131. package/types.d.ts +0 -1
  132. package/webpack.config.js +0 -59
@@ -1,119 +0,0 @@
1
- /* Input */
2
-
3
- .container {
4
- display: flex;
5
- align-items: center;
6
- width: 100%;
7
- position: relative;
8
- border: 1px solid #CCCCCC;
9
- border-radius: 3px;
10
- z-index: 0;
11
- }
12
-
13
- .container.hidden {
14
- border: 0;
15
- }
16
-
17
- .element {
18
- align-self: stretch;
19
- width: 100%;
20
- }
21
-
22
- .element > input, .element > textarea {
23
- width: 100%;
24
- height: 100%;
25
- min-height: 45px;
26
- max-height: 500px;
27
- max-height: 50dvh;
28
- margin: 0;
29
- padding: 10px;
30
- font-size: 20px;
31
- border: 0;
32
- box-sizing: border-box;
33
- background-color: transparent;
34
- outline: none;
35
- resize: none;
36
- }
37
-
38
- .container.disabled {
39
- background-color: #EFEFEF;
40
- }
41
-
42
- .element > input:-webkit-autofill,
43
- .element > input:-webkit-autofill:hover,
44
- .element > input:-webkit-autofill:focus,
45
- .element > input:-webkit-autofill:active{
46
- -webkit-background-clip: text;
47
- }
48
-
49
- .element > input:focus {
50
- outline: none;
51
- }
52
-
53
- .element > .placeholder {
54
- position: absolute;
55
- display: flex;
56
- justify-content: center;
57
- align-items: center;
58
- top: 0;
59
- margin-left: 5px;
60
- height: 100%;
61
- color: #7A7A73;
62
- font-size: 1.2rem;
63
- z-index: -1;
64
- user-select: none;
65
- transition: transform 0.3s;
66
- }
67
-
68
- .element > textarea ~ .placeholder {
69
- max-height: 2em;
70
- }
71
-
72
- .element > .placeholder::before {
73
- content: "";
74
- position: absolute;
75
- display: block;
76
- width: 100%;
77
- height: 5px;
78
- background-color: #FFFFFF;
79
- z-index: -1;
80
- }
81
-
82
- .element > input:required ~ .placeholder::after {
83
- content: "*";
84
- }
85
-
86
- /* Date */
87
- .element > input[type="date"]::-webkit-calendar-picker-indicator {
88
- cursor: pointer;
89
- border-radius: 4px;
90
- margin-right: 2px;
91
- opacity: 0.7;
92
- filter: invert(0.8);
93
- }
94
-
95
- .element > input[type="date"]::-webkit-calendar-picker-indicator:hover {
96
- opacity: 1
97
- }
98
-
99
- .element > input[type="date"] ~ .placeholder,
100
- .element > input:focus ~ .placeholder,
101
- .element > textarea:focus ~ .placeholder,
102
- .element > input:not([value=""]) ~ .placeholder,
103
- .element > textarea:not(:empty) ~ .placeholder,
104
- .element > input:not(:empty) ~ .placeholder {
105
- transform: translate(-10%, -50%) scale(0.8);
106
- z-index: 0;
107
- }
108
-
109
- .container.error {
110
- border-color: #FF6D6D;
111
- }
112
-
113
- .container.error .placeholder {
114
- color: #FF6D6D;
115
- }
116
-
117
- .error {
118
- color: #FF6D6D;
119
- }
package/src/Form/Form.tsx DELETED
@@ -1,40 +0,0 @@
1
- import { FormHTMLAttributes, ReactNode, FormEvent } from 'react';
2
- import styles from './style.module.css';
3
-
4
- import Spinner,{
5
- TSpinner
6
- } from '../Spinner';
7
- import Progress from '../Progress';
8
-
9
- interface IForm extends FormHTMLAttributes<HTMLFormElement> {
10
- children: ReactNode;
11
- wait?: boolean;
12
- progress?: number;
13
- progressRadius?: boolean;
14
- spinnerColor?: TSpinner['color'];
15
- }
16
-
17
- const Form = ({children, wait, progress, progressRadius = true, className, spinnerColor, onSubmit, ...props}: IForm) => {
18
-
19
- const submit = (e: FormEvent<HTMLFormElement>) => {
20
- e.preventDefault();
21
- if (typeof onSubmit === 'function') {
22
- onSubmit(e);
23
- }
24
- };
25
-
26
- const classes = [];
27
-
28
- classes.push(styles['container']);
29
- if (wait) classes.push(styles['wait']);
30
- if (className) classes.push(className);
31
-
32
- return(<form {...props} onSubmit={submit} className={classes.join(' ')}>
33
- {children}
34
- <div className={styles['wait-indicator']}>
35
- {typeof progress === 'number' ? <Progress radius={progressRadius} value={progress}/> : <Spinner color={spinnerColor}/>}
36
- </div>
37
- </form>);
38
- };
39
-
40
- export default Form;
@@ -1,30 +0,0 @@
1
- /* Form */
2
-
3
- .container {
4
- flex: 1;
5
- display: flex;
6
- flex-direction: column;
7
- align-items: center;
8
- gap: 10px;
9
- }
10
-
11
- .container > .wait-indicator {
12
- display: flex;
13
- justify-content: center;
14
- align-items: center;
15
- position: absolute;
16
- top: 0;
17
- left: 0;
18
- width: 100%;
19
- height: 100%;
20
- background-color: #FFFFFF9F;
21
- backdrop-filter: blur(2px);
22
- z-index: -1;
23
- opacity: 0;
24
- transition: opacity 0.3s;
25
- }
26
-
27
- .container.wait > .wait-indicator {
28
- z-index: 1;
29
- opacity: 1;
30
- }
@@ -1,76 +0,0 @@
1
- import { useState, FunctionComponent } from "react";
2
- import type { TError, TUseFormRegisterReturn } from "./types";
3
- import styles from "./style.module.css";
4
-
5
- import {
6
- useForm as useHookForm,
7
- UseFormReturn,
8
- RegisterOptions,
9
- UseFormRegisterReturn,
10
- FieldValues,
11
- SetValueConfig,
12
- FieldPathValue,
13
- FieldPath
14
- } from "react-hook-form";
15
-
16
- type TuseErrors<TFieldValues extends FieldValues = FieldValues> = UseFormReturn<TFieldValues> & {
17
- GlobalError: FunctionComponent;
18
- setErrors: (e: TError<TFieldValues>) => void;
19
- };
20
-
21
- const useForm = <TFieldValues extends FieldValues = FieldValues>(): TuseErrors<TFieldValues> => {
22
- const [globalError, setGlobalError] = useState<TError<TFieldValues> | null>();
23
-
24
- const form = useHookForm<TFieldValues>({
25
- reValidateMode: 'onChange'
26
- });
27
-
28
- const register = <TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>(name: TFieldName, options?: RegisterOptions<TFieldValues, TFieldName>): TUseFormRegisterReturn<TFieldValues, TFieldName> => {
29
- const inputRegister = form.register<TFieldName>(name, options);
30
- const onChange = (e: {
31
- target: any;
32
- type?: any;
33
- }) => {
34
- setGlobalError(null);
35
- form.clearErrors(name);
36
- return inputRegister.onChange(e);
37
- };
38
- const formValue = form.watch(name);
39
- const errors = form?.formState.errors;
40
-
41
- return {
42
- ...inputRegister,
43
- onChange,
44
- formValue,
45
- error: errors?.[name]?.message?.toString()
46
- };
47
- };
48
-
49
- const setErrors = (e: TError<TFieldValues>) => {
50
- if (e.errors) {
51
- Object.keys(e.errors).forEach((field) => form.setError(field as FieldPath<TFieldValues>, {message: e.errors?.[field]?.[0]}));
52
- }else{
53
- setGlobalError(e);
54
- }
55
- };
56
-
57
- const GlobalError = () => (<>{(globalError && !globalError.errors) && <div className={styles['global-error']}>{globalError.message}</div>}</>);
58
-
59
- return {
60
- ...form,
61
- register,
62
- GlobalError,
63
- setErrors
64
- };
65
- };
66
-
67
- export const validate = {
68
- email: {
69
- pattern: {
70
- value: /\S+@\S+\.\S+/,
71
- message: "Неверный адрес электронной почты",
72
- }
73
- }
74
- };
75
-
76
- export default useForm;
@@ -1,49 +0,0 @@
1
- import {
2
- forwardRef,
3
- useState,
4
- ChangeEvent,
5
- useEffect,
6
- type HTMLInputTypeAttribute
7
- } from "react";
8
- import Element,{
9
- IElement
10
- } from "../Form/Element";
11
-
12
-
13
- interface IInput extends IElement<HTMLInputElement> {
14
- onChangeText?: (text: string) => void;
15
- type?: HTMLInputTypeAttribute;
16
- }
17
-
18
- const Input = forwardRef<HTMLInputElement, IInput>(({onChange, onInput, onChangeText, formValue, ...props}, ref) => {
19
- const [currentValue, setCurrentValue] = useState('');
20
-
21
- const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
22
- if (typeof onChange === 'function') {
23
- onChange(e);
24
- }
25
-
26
- if (typeof onChangeText === 'function') {
27
- onChangeText(e.target.value);
28
- }
29
- };
30
-
31
- const handleInput = (e: ChangeEvent<HTMLInputElement>) => {
32
- if (props.disabled) return;
33
- if (typeof onInput === 'function') {
34
- onInput(e);
35
- }
36
- setCurrentValue(e.target.value);
37
- };
38
-
39
- useEffect(() => {
40
- const value = props.value ?? formValue;
41
- setCurrentValue(value ? String(value) : '');
42
- }, [props.value, formValue]);
43
-
44
- return(<Element {...props}>
45
- { (props) => <input {...props} placeholder="" onChange={handleChange} value={currentValue} onInput={handleInput} ref={ref}/> }
46
- </Element>);
47
- });
48
-
49
- export default Input;
@@ -1,16 +0,0 @@
1
- .container > input {
2
- width: calc(100% - 10px);
3
- margin: 15px 0 15px 0;
4
- font-size: 18px;
5
- padding: 10px 0 10px 15px;
6
- border: 2px solid #E2E8F2;
7
- resize: none;
8
- outline: none;
9
- transition: 0.2s;
10
- -webkit-transition: 0.2s;
11
- }
12
-
13
- .container > input[type="text"]:focus {
14
- border: 2px solid #FBA31D;
15
- border-bottom: 2px solid #000;
16
- }
@@ -1,28 +0,0 @@
1
- import styles from "./style.module.css";
2
-
3
- interface IProgress {
4
- value?: number | string;
5
- size?: 'small' | 'middle' | 'large';
6
- radius?: boolean;
7
- };
8
-
9
- const Progress = ({value = 0, size, radius = false}: IProgress) => {
10
- value = Math.ceil(Number(value) * 10) / 10;
11
- if (value > 100) {
12
- value = 100;
13
- }
14
- if (value < 0) {
15
- value = 0;
16
- }
17
-
18
- const progress = radius ? (360 / 100 * value) + 'deg' : value + '%';
19
-
20
- const classes = ['ui-progress'];
21
- classes.push(styles['container']);
22
- if (size) classes.push(styles[size]);
23
- if (radius) classes.push(styles['radius']);
24
-
25
- return(<div className={classes.join(' ')} data-progress={value} style={{'--progress': progress} as React.CSSProperties}/>);
26
- };
27
-
28
- export default Progress;
@@ -1,72 +0,0 @@
1
- /* Progress */
2
-
3
- .container {
4
- --size: 150px;
5
- --color-rgb: 94, 190, 214;
6
- position: relative;
7
- display: flex;
8
- justify-content: center;
9
- align-items: center;
10
- width: 100%;
11
- min-width: var(--size);
12
- max-width: var(--size);
13
- box-sizing: content-box !important;
14
- aspect-ratio: 10/1;
15
- border-radius: 2px;
16
- padding: 5px 0;
17
- overflow: hidden;
18
- }
19
-
20
- .container::before {
21
- content: "";
22
- position: absolute;
23
- display: block;
24
- width: 100%;
25
- height: 100%;
26
- max-width: 100%;
27
- max-height: 100%;
28
- background: linear-gradient(to right, #5EBED6 var(--progress), #BED4DB 0);
29
- }
30
-
31
- .container.radius {
32
- aspect-ratio: 1/1;
33
- border-radius: 50%;
34
- padding: unset;
35
- }
36
-
37
- .container.radius::before {
38
- --border-width: clamp(0.2em, 10%, 0.5em);
39
- border-radius: 50%;
40
- aspect-ratio: 1/1;
41
- mask: radial-gradient(
42
- farthest-side,
43
- transparent calc(100% - var(--border-width) - 0.5px),
44
- #000 calc(100% - var(--border-width) + 0.5px)
45
- );
46
- background: conic-gradient(#5EBED6 var(--progress), #BED4DB 0deg);
47
- }
48
-
49
- .container::after {
50
- content: attr(data-progress) '%';
51
- font-size: 1.5em;
52
- color: #FFFFFF;
53
- mix-blend-mode: lighten;
54
- z-index: 1;
55
- }
56
-
57
- .container.radius::after {
58
- mix-blend-mode: unset;
59
- color: #1D1D1B;
60
- }
61
-
62
- .container.small {
63
- --size: 30px;
64
- }
65
-
66
- .container.middle {
67
- --size: 60px;
68
- }
69
-
70
- .container.large {
71
- --size: 120px;
72
- }
@@ -1,19 +0,0 @@
1
- import styles from "./style.module.css";
2
- import type { TOptionElement } from "./Select";
3
-
4
- export interface IOptgroup {
5
- children?: TOptionElement;
6
- label?: string | React.ReactElement;
7
- };
8
-
9
- const Optgroup = ({children, label}: IOptgroup) => {
10
-
11
- return(<li>
12
- <ul className={styles['optgpoup']}>
13
- {label && <li className={styles['label']}>{label}</li>}
14
- {children}
15
- </ul>
16
- </li>);
17
- };
18
-
19
- export default Optgroup;
@@ -1,47 +0,0 @@
1
- import {
2
- LiHTMLAttributes,
3
- MouseEvent,
4
- useContext,
5
- useEffect
6
- } from "react";
7
- import { Context } from "./Select";
8
- import styles from "./style.module.css";
9
-
10
- export interface IOption extends LiHTMLAttributes<HTMLLIElement> {
11
- value?: string;
12
- disabled?: boolean;
13
- children?: string | React.ReactElement;
14
- };
15
-
16
- const Option = ({children, value, disabled, hidden, onClick, ...props}: IOption) => {
17
- const context = useContext(Context);
18
-
19
- const handleClick = (e: MouseEvent<HTMLLIElement>) => {
20
- if (typeof value === 'undefined' || disabled) return;
21
- context.setSelect(value);
22
- if (typeof onClick === 'function') {
23
- onClick(e);
24
- }
25
- };
26
-
27
- useEffect(() => {
28
- if (children && (value === context.selected || !context.emptyValue.current)) {
29
- context.setTitle(children);
30
- if (!context.emptyValue.current && value) {
31
- context.setSelected(value);
32
- }
33
- context.emptyValue.current = true;
34
- }
35
- }, [context.selected]);
36
-
37
- if (hidden) return(null);
38
-
39
- const classes = ['ui-select-option'];
40
- classes.push(styles['option']);
41
- if (context.selected === value) classes.push(styles['active'], 'active');
42
- if (disabled) classes.push(styles['disabled'], 'disabled');
43
-
44
- return(<li {...props} onClick={handleClick} className={classes.join(' ')}>{children}</li>);
45
- };
46
-
47
- export default Option;
@@ -1,143 +0,0 @@
1
- import {
2
- forwardRef,
3
- createContext,
4
- useState,
5
- useEffect,
6
- useRef,
7
- ChangeEvent,
8
- useImperativeHandle,
9
- FunctionComponentElement,
10
- ReactNode
11
- } from "react";
12
- import Element,{
13
- IElement
14
- } from "../Form/Element";
15
- import type { IOptgroup } from "./Optgroup";
16
- import type { IOption } from "./Option";
17
- import Arrow from "../Components/Arrow";
18
- import styles from "./style.module.css";
19
-
20
- export const Context = createContext({
21
- selected: '',
22
- emptyValue: {current:{}} as React.MutableRefObject<boolean>,
23
- setSelect: (value: string) => {},
24
- setSelected: (value: string) => {},
25
- setTitle: (title: IOption['children']) => {},
26
- });
27
-
28
- export type TOptionElement = FunctionComponentElement<IOption> | FunctionComponentElement<IOption>[] | ReactNode;
29
-
30
- export interface ISelect extends Omit<IElement, 'children'> {
31
- children?: TOptionElement | FunctionComponentElement<IOptgroup> | FunctionComponentElement<IOptgroup>[];
32
- onChangeSelect?: (value: string) => void;
33
- };
34
-
35
- const Select = forwardRef<HTMLInputElement, ISelect>(({children, onChangeSelect, value, formValue, ...props}, ref) => {
36
- const containerRef = useRef<HTMLDivElement>(null);
37
- const inputRef = useRef<HTMLInputElement>(null);
38
- const emptyValue = useRef(false);
39
-
40
- const [isOpen, setOpen] = useState(false);
41
- const [selected, setSelected] = useState('');
42
- const [title, setTitle] = useState<IOption['children']>();
43
-
44
- const open = () => {
45
- if (props.disabled) return;
46
- setOpen(true);
47
- };
48
-
49
- const close = () => {
50
- setOpen(false);
51
- };
52
-
53
- const handleClick = () => {
54
- isOpen ? close() : open();
55
- };
56
-
57
- const triggerNativeEvent = (value: string) => {
58
- const nativeInputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
59
- nativeInputValueSetter?.call(inputRef.current, value);
60
-
61
- const event = new Event('input', { bubbles: true});
62
- inputRef.current!.dispatchEvent(event);
63
- };
64
-
65
- const setSelect = (val: string) => {
66
- if (typeof onChangeSelect === 'function') {
67
- onChangeSelect(val);
68
- }
69
- if (typeof value === 'undefined') {
70
- setSelected(val);
71
- }
72
- close();
73
- };
74
-
75
- const handleInput = (e: ChangeEvent<HTMLInputElement>) => {
76
- if (props.disabled) return;
77
- if (typeof props.onInput === 'function') {
78
- props.onInput(e);
79
- }
80
-
81
- if (typeof props.onChange === 'function') {
82
- props.onChange(e);
83
- }
84
- setSelected(e.target.value);
85
- };
86
-
87
- useEffect(() => {
88
- if (!selected) return;
89
- triggerNativeEvent(selected);
90
- }, [selected]);
91
-
92
- useEffect(() => {
93
- setSelected(String(value ?? formValue));
94
- }, [value, formValue]);
95
-
96
- useEffect(() => {
97
- const element = containerRef.current;
98
- const classList = element!.classList;
99
- if (isOpen) {
100
- classList.remove(styles['hidden']);
101
- requestAnimationFrame(() => {
102
- classList.add(styles['opened']);
103
- element?.focus();
104
- });
105
- }else{
106
- if (classList.contains(styles['opened'])) {
107
- element!.ontransitionend = () => {
108
- classList.add(styles['hidden']);
109
- element!.ontransitionend = null;
110
- };
111
- }
112
- classList.remove(styles['opened']);
113
- }
114
- }, [isOpen]);
115
-
116
- useImperativeHandle(ref, () => inputRef.current as HTMLInputElement, []);
117
-
118
- const classes = [''];
119
- classes.push(styles['container'], styles['hidden']);
120
-
121
- return(<Element {...props} classNameContainer={styles['container-element']}>
122
- { (props) => <Context.Provider value={{
123
- selected,
124
- emptyValue: emptyValue,
125
- setSelect,
126
- setSelected,
127
- setTitle
128
- }}>
129
- <input {...props} type="hidden" value={selected} onInput={handleInput} ref={inputRef}/>
130
- <div className={classes.join(' ')} ref={containerRef} tabIndex={1} onBlur={close}>
131
- <div className={styles['select']} onClick={handleClick}>
132
- <span className={styles['title']}>{title}</span>
133
- <Arrow className={styles['arrow']}/>
134
- </div>
135
- <ul className={styles['select-list']}>
136
- {children}
137
- </ul>
138
- </div>
139
- </Context.Provider> }
140
- </Element>);
141
- });
142
-
143
- export default Select;
@@ -1,33 +0,0 @@
1
- import {
2
- forwardRef,
3
- ForwardRefExoticComponent,
4
- FC,
5
- RefAttributes
6
- } from "react";
7
- import {
8
- default as SelectUI,
9
- ISelect
10
- } from "./Select";
11
- import Option,{
12
- IOption
13
- } from "./Option";
14
- import Optgroup,{
15
- IOptgroup
16
- } from "./Optgroup";
17
-
18
- interface StaticComponent extends ForwardRefExoticComponent<ISelect & RefAttributes<HTMLInputElement>> {
19
- Option: FC<IOption>;
20
- Optgroup: FC<IOptgroup>;
21
- };
22
-
23
- const Select: StaticComponent = {
24
- ...forwardRef<HTMLInputElement, ISelect>(({...args}, ref): JSX.Element => <SelectUI {...args} ref={ref}/>),
25
- Option,
26
- Optgroup
27
- } as StaticComponent;
28
-
29
- export {
30
- Option as SelectOption,
31
- Optgroup as SelectOptgroup
32
- };
33
- export default Select;