forstok-ui-lib 1.0.3 → 1.0.4
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/package.json
CHANGED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components'
|
|
2
|
+
|
|
3
|
+
const SubmitStyles = css`
|
|
4
|
+
border: 0;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
font-weight: 400;
|
|
7
|
+
color: var(--sec-clr);
|
|
8
|
+
background-color: var(--act-clr-bg);
|
|
9
|
+
`
|
|
10
|
+
const getInputModifiedStyled = ({ width, height, $iconLeft, $iconRight, $isError, mode, type }:{ width?: string | number, height?: string | number, $iconLeft?: boolean, $iconRight?: boolean, $isError?: boolean, mode?: string, type?: string }) => {
|
|
11
|
+
let style = ""
|
|
12
|
+
if ($iconLeft) {
|
|
13
|
+
style += `
|
|
14
|
+
padding-left: 35px;
|
|
15
|
+
`
|
|
16
|
+
}
|
|
17
|
+
if ($iconRight) {
|
|
18
|
+
style += `
|
|
19
|
+
padding-right: 35px;
|
|
20
|
+
`
|
|
21
|
+
}
|
|
22
|
+
if ($isError) {
|
|
23
|
+
style += `
|
|
24
|
+
border:1px solid var(--err-clr-ln) !important;
|
|
25
|
+
`
|
|
26
|
+
}
|
|
27
|
+
if (height) {
|
|
28
|
+
style += `
|
|
29
|
+
height: ${height}px
|
|
30
|
+
max-height: ${height}px
|
|
31
|
+
`
|
|
32
|
+
}
|
|
33
|
+
if (mode === 'search') {
|
|
34
|
+
style += `
|
|
35
|
+
background-color: transparent;
|
|
36
|
+
&, &:not([type="submit"]):focus, &:active, &:active:focus {
|
|
37
|
+
border: 1px solid transparent !important;
|
|
38
|
+
outline: none !important;
|
|
39
|
+
box-shadow: none !important;
|
|
40
|
+
}
|
|
41
|
+
`
|
|
42
|
+
if ($iconLeft) {
|
|
43
|
+
style += `
|
|
44
|
+
padding-left: 39px;
|
|
45
|
+
`
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (mode === 'transaction') {
|
|
49
|
+
style += `
|
|
50
|
+
padding-left: 45px;
|
|
51
|
+
`
|
|
52
|
+
}
|
|
53
|
+
if (width) {
|
|
54
|
+
style += `
|
|
55
|
+
width: ${width}px
|
|
56
|
+
`
|
|
57
|
+
}
|
|
58
|
+
if (type === 'submit') {
|
|
59
|
+
style += SubmitStyles
|
|
60
|
+
}
|
|
61
|
+
return style;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const InputContainer = styled.input<{ width?: string | number, height?: string | number, $iconLeft?: boolean, $iconRight?: boolean, $isError?: boolean, mode?: string, type?: string }>`
|
|
65
|
+
&._refQuantitiyInput {
|
|
66
|
+
width: 55px;
|
|
67
|
+
text-align: center;
|
|
68
|
+
}
|
|
69
|
+
${getInputModifiedStyled}
|
|
70
|
+
`
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { useState, useEffect, type InputHTMLAttributes, type ChangeEvent, type FocusEvent, type KeyboardEvent, type ClipboardEvent } from 'react';
|
|
2
|
+
import { InputContainer } from './input.styles';
|
|
3
|
+
import type { TEnterEvent, TKeyboadEvent, TState } from '../../typeds/base.typed';
|
|
4
|
+
|
|
5
|
+
type TInput = InputHTMLAttributes<HTMLInputElement> & {
|
|
6
|
+
mode?: string
|
|
7
|
+
$isError?: boolean
|
|
8
|
+
$iconLeft?: boolean
|
|
9
|
+
$iconRight?: boolean
|
|
10
|
+
reset?: boolean
|
|
11
|
+
setReset?: TState<boolean>
|
|
12
|
+
isForceUpdate?: boolean
|
|
13
|
+
setForceUpdate?: TState<boolean>
|
|
14
|
+
evChange?: (e: ChangeEvent<HTMLInputElement>) => void
|
|
15
|
+
evBlur?: (e: FocusEvent<HTMLInputElement>) => void
|
|
16
|
+
isField?: boolean
|
|
17
|
+
evChangeCustom? : (key: string, value: any) => void
|
|
18
|
+
evEnter?: TEnterEvent
|
|
19
|
+
evKeyUp?: TKeyboadEvent
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const InputComponent = ({ mode, $isError, $iconLeft, $iconRight, reset, setReset, isForceUpdate, setForceUpdate, evChange, evBlur, isField, evChangeCustom, evEnter, evKeyUp, ...props }: TInput) => {
|
|
23
|
+
const { type, name, defaultValue, defaultChecked } = props;
|
|
24
|
+
const _value = defaultValue?.toString() ?? '';
|
|
25
|
+
const [inputValue, evInputValue] = useState<string>(_value);
|
|
26
|
+
const [inputChecked, evInputChecked] = useState<boolean>(defaultChecked||false);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (isForceUpdate) {
|
|
30
|
+
const _value = defaultValue?.toString() ?? '';
|
|
31
|
+
evInputValue(_value);
|
|
32
|
+
evInputChecked(defaultChecked||false);
|
|
33
|
+
setForceUpdate && setForceUpdate(false);
|
|
34
|
+
}
|
|
35
|
+
if (reset) {
|
|
36
|
+
evInputValue('');
|
|
37
|
+
evInputChecked(false);
|
|
38
|
+
setReset && setReset(false);
|
|
39
|
+
}
|
|
40
|
+
}, [isForceUpdate, setForceUpdate, reset, setReset, defaultValue, defaultChecked, evInputChecked, mode]);
|
|
41
|
+
|
|
42
|
+
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
43
|
+
const _value = e.target.value;
|
|
44
|
+
evInputValue(_value);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const _evKeyUp = (e: KeyboardEvent<HTMLInputElement>) => {
|
|
48
|
+
if (e.key === 'Enter') {
|
|
49
|
+
e.preventDefault();
|
|
50
|
+
(isField && evEnter) && evEnter(e);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const _evKeyPress = (e: KeyboardEvent<HTMLInputElement>) => {
|
|
55
|
+
if (type === 'number') {
|
|
56
|
+
if(!(!(isNaN(Number(e.key)) || typeof e.key === 'undefined' || e.key === ''))) {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const _evBlur = (e: FocusEvent<HTMLInputElement>) => {
|
|
64
|
+
evBlur && evBlur(e);
|
|
65
|
+
(isField && evEnter) && evEnter(e);
|
|
66
|
+
if (isField && name) {
|
|
67
|
+
const value = type === 'number' ? parseInt(e.target.value) : e.target.value.trim();
|
|
68
|
+
evChangeCustom && evChangeCustom(name, value);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
let parseProps = {...props};
|
|
73
|
+
delete parseProps.defaultValue;
|
|
74
|
+
delete parseProps.defaultChecked;
|
|
75
|
+
|
|
76
|
+
const inputEl = <InputContainer
|
|
77
|
+
mode={mode}
|
|
78
|
+
$isError={$isError}
|
|
79
|
+
$iconLeft={$iconLeft}
|
|
80
|
+
$iconRight={$iconRight}
|
|
81
|
+
checked={inputChecked}
|
|
82
|
+
value={inputValue}
|
|
83
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
|
84
|
+
handleChange(e);
|
|
85
|
+
evChange && evChange(e);
|
|
86
|
+
}}
|
|
87
|
+
onBlur={(e: FocusEvent<HTMLInputElement>) => {
|
|
88
|
+
handleChange(e);
|
|
89
|
+
_evBlur(e);
|
|
90
|
+
}}
|
|
91
|
+
onKeyUp={(e: KeyboardEvent<HTMLInputElement>) => {
|
|
92
|
+
evKeyUp && evKeyUp(e);
|
|
93
|
+
_evKeyUp(e);
|
|
94
|
+
}}
|
|
95
|
+
{...(type ==='number' && { onKeyPress: _evKeyPress } )}
|
|
96
|
+
{...(type ==='number' && { onPaste: (e: ClipboardEvent<HTMLInputElement>) => {
|
|
97
|
+
const pasteVal = (e.clipboardData || (window as any).clipboardData).getData('text')
|
|
98
|
+
const _value = pasteVal.replace(/[^0-9]/g, '')
|
|
99
|
+
e.preventDefault()
|
|
100
|
+
document.execCommand('insertText', false, _value)
|
|
101
|
+
} })}
|
|
102
|
+
{...(type ==='number' && { onFocus: (e: FocusEvent<HTMLInputElement>) => e.target.addEventListener("wheel", function (e) { e.preventDefault() }, { passive: false })} )}
|
|
103
|
+
{...(type ==='number' && { min: "0" })}
|
|
104
|
+
{...parseProps} />
|
|
105
|
+
|
|
106
|
+
return inputEl;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export default InputComponent
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { MouseEvent, ChangeEvent, DragEvent, Dispatch, SetStateAction, KeyboardEvent, FocusEvent } from 'react';
|
|
2
|
+
|
|
3
|
+
type RemoveUnderscoreFirstLetter<S extends string> =
|
|
4
|
+
S extends `${infer FirstLetter}${infer U}`
|
|
5
|
+
? `${FirstLetter extends "_" ? U : `${FirstLetter}${U}`}`
|
|
6
|
+
: S;
|
|
7
|
+
type CamelToSnakeCase<S extends string> =
|
|
8
|
+
S extends `${infer T}${infer U}`
|
|
9
|
+
? `${T extends Capitalize<T> ? "_" : ""}${RemoveUnderscoreFirstLetter<
|
|
10
|
+
Lowercase<T>
|
|
11
|
+
>}${CamelToSnakeCase<U>}`
|
|
12
|
+
: S;
|
|
13
|
+
|
|
14
|
+
export type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
|
|
15
|
+
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
16
|
+
export type KeysToSnakeCase<T extends object> = {
|
|
17
|
+
[K in keyof T as CamelToSnakeCase<K & string>]: T[K];
|
|
18
|
+
};
|
|
19
|
+
export type TIdNum = { id: number };
|
|
20
|
+
export type TIdStr = { id: string };
|
|
21
|
+
export type TObject = { [key: string]: any };
|
|
22
|
+
export type TMouseEvent = (e: MouseEvent) => void;
|
|
23
|
+
export type TChangeEvent = (e: ChangeEvent) => void;
|
|
24
|
+
export type TDragEvent = (e:DragEvent) => void;
|
|
25
|
+
export type TEnterEvent = (e:KeyboardEvent<HTMLInputElement | HTMLElement> | FocusEvent<HTMLInputElement | HTMLElement | Element> | MouseEvent<HTMLElement>) => void;
|
|
26
|
+
export type TKeyboadEvent = (e: KeyboardEvent<HTMLInputElement>) => void;
|
|
27
|
+
export type TPage = {
|
|
28
|
+
totalCount: number
|
|
29
|
+
totalPageCount: number
|
|
30
|
+
pageInfo: {
|
|
31
|
+
endCursor?: string | null
|
|
32
|
+
hasNextPage: boolean
|
|
33
|
+
hasPreviousPage: boolean
|
|
34
|
+
startCursor?: string | null
|
|
35
|
+
}
|
|
36
|
+
pageCursors?: {
|
|
37
|
+
page: number
|
|
38
|
+
startCursor: string
|
|
39
|
+
endCursor: string
|
|
40
|
+
}[] | null
|
|
41
|
+
};
|
|
42
|
+
export type TFile = {
|
|
43
|
+
name: string
|
|
44
|
+
file: File
|
|
45
|
+
};
|
|
46
|
+
export type TFileImage = TFile & {
|
|
47
|
+
src: string
|
|
48
|
+
url?: string
|
|
49
|
+
};
|
|
50
|
+
export type TState<T> = Dispatch<SetStateAction<T>>;
|