wini-web-components 2.8.5 → 2.8.6

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 (129) hide show
  1. package/dist/index.js.js +9 -9
  2. package/dist/index.js.mjs +745 -895
  3. package/global.d.ts +6 -0
  4. package/package.json +3 -4
  5. package/dist/component/button/button.d.ts +0 -22
  6. package/dist/component/button/button.d.ts.map +0 -1
  7. package/dist/component/calendar/calendar.d.ts +0 -31
  8. package/dist/component/calendar/calendar.d.ts.map +0 -1
  9. package/dist/component/carousel/carousel.d.ts +0 -32
  10. package/dist/component/carousel/carousel.d.ts.map +0 -1
  11. package/dist/component/checkbox/checkbox.d.ts +0 -25
  12. package/dist/component/checkbox/checkbox.d.ts.map +0 -1
  13. package/dist/component/ck-editor/ckeditor.d.ts +0 -36
  14. package/dist/component/ck-editor/ckeditor.d.ts.map +0 -1
  15. package/dist/component/component-status.d.ts +0 -8
  16. package/dist/component/component-status.d.ts.map +0 -1
  17. package/dist/component/date-time-picker/date-time-picker.d.ts +0 -36
  18. package/dist/component/date-time-picker/date-time-picker.d.ts.map +0 -1
  19. package/dist/component/dialog/dialog.d.ts +0 -18
  20. package/dist/component/dialog/dialog.d.ts.map +0 -1
  21. package/dist/component/import-file/import-file.d.ts +0 -34
  22. package/dist/component/import-file/import-file.d.ts.map +0 -1
  23. package/dist/component/infinite-scroll/infinite-scroll.d.ts +0 -18
  24. package/dist/component/infinite-scroll/infinite-scroll.d.ts.map +0 -1
  25. package/dist/component/input-multi-select/input-multi-select.d.ts +0 -22
  26. package/dist/component/input-multi-select/input-multi-select.d.ts.map +0 -1
  27. package/dist/component/input-otp/input-otp.d.ts +0 -23
  28. package/dist/component/input-otp/input-otp.d.ts.map +0 -1
  29. package/dist/component/number-picker/number-picker.d.ts +0 -24
  30. package/dist/component/number-picker/number-picker.d.ts.map +0 -1
  31. package/dist/component/pagination/pagination.d.ts +0 -14
  32. package/dist/component/pagination/pagination.d.ts.map +0 -1
  33. package/dist/component/popup/popup.d.ts +0 -40
  34. package/dist/component/popup/popup.d.ts.map +0 -1
  35. package/dist/component/progress-bar/progress-bar.d.ts +0 -16
  36. package/dist/component/progress-bar/progress-bar.d.ts.map +0 -1
  37. package/dist/component/progress-circle/progress-circle.d.ts +0 -13
  38. package/dist/component/progress-circle/progress-circle.d.ts.map +0 -1
  39. package/dist/component/radio-button/radio-button.d.ts +0 -21
  40. package/dist/component/radio-button/radio-button.d.ts.map +0 -1
  41. package/dist/component/rating/rating.d.ts +0 -24
  42. package/dist/component/rating/rating.d.ts.map +0 -1
  43. package/dist/component/select1/select1.d.ts +0 -32
  44. package/dist/component/select1/select1.d.ts.map +0 -1
  45. package/dist/component/switch/switch.d.ts +0 -24
  46. package/dist/component/switch/switch.d.ts.map +0 -1
  47. package/dist/component/table/table.d.ts +0 -51
  48. package/dist/component/table/table.d.ts.map +0 -1
  49. package/dist/component/tag/tag.d.ts +0 -23
  50. package/dist/component/tag/tag.d.ts.map +0 -1
  51. package/dist/component/text/text.d.ts +0 -16
  52. package/dist/component/text/text.d.ts.map +0 -1
  53. package/dist/component/text-area/text-area.d.ts +0 -28
  54. package/dist/component/text-area/text-area.d.ts.map +0 -1
  55. package/dist/component/text-field/text-field.d.ts +0 -37
  56. package/dist/component/text-field/text-field.d.ts.map +0 -1
  57. package/dist/component/toast-noti/toast-noti.d.ts +0 -5
  58. package/dist/component/toast-noti/toast-noti.d.ts.map +0 -1
  59. package/dist/component/wini-icon/winicon.d.ts +0 -27
  60. package/dist/component/wini-icon/winicon.d.ts.map +0 -1
  61. package/dist/form/login/view.d.ts +0 -41
  62. package/dist/form/login/view.d.ts.map +0 -1
  63. package/dist/index.d.ts +0 -34
  64. package/dist/index.d.ts.map +0 -1
  65. package/dist/language/i18n.d.ts +0 -3
  66. package/dist/language/i18n.d.ts.map +0 -1
  67. package/src/component/button/button.module.css +0 -210
  68. package/src/component/button/button.tsx +0 -57
  69. package/src/component/calendar/calendar.module.css +0 -153
  70. package/src/component/calendar/calendar.tsx +0 -389
  71. package/src/component/carousel/carousel.css +0 -622
  72. package/src/component/carousel/carousel.tsx +0 -91
  73. package/src/component/checkbox/checkbox.module.css +0 -48
  74. package/src/component/checkbox/checkbox.tsx +0 -80
  75. package/src/component/ck-editor/ck-editor.css +0 -206
  76. package/src/component/ck-editor/ckeditor.tsx +0 -522
  77. package/src/component/component-status.tsx +0 -53
  78. package/src/component/date-time-picker/date-time-picker.module.css +0 -94
  79. package/src/component/date-time-picker/date-time-picker.tsx +0 -663
  80. package/src/component/dialog/dialog.module.css +0 -111
  81. package/src/component/dialog/dialog.tsx +0 -109
  82. package/src/component/import-file/import-file.module.css +0 -83
  83. package/src/component/import-file/import-file.tsx +0 -174
  84. package/src/component/infinite-scroll/infinite-scroll.module.css +0 -34
  85. package/src/component/infinite-scroll/infinite-scroll.tsx +0 -35
  86. package/src/component/input-multi-select/input-multi-select.module.css +0 -121
  87. package/src/component/input-multi-select/input-multi-select.tsx +0 -263
  88. package/src/component/input-otp/input-otp.module.css +0 -41
  89. package/src/component/input-otp/input-otp.tsx +0 -110
  90. package/src/component/number-picker/number-picker.module.css +0 -137
  91. package/src/component/number-picker/number-picker.tsx +0 -107
  92. package/src/component/pagination/pagination.module.css +0 -48
  93. package/src/component/pagination/pagination.tsx +0 -88
  94. package/src/component/popup/popup.css +0 -136
  95. package/src/component/popup/popup.tsx +0 -125
  96. package/src/component/progress-bar/progress-bar.module.css +0 -42
  97. package/src/component/progress-bar/progress-bar.tsx +0 -33
  98. package/src/component/progress-circle/progress-circle.css +0 -0
  99. package/src/component/progress-circle/progress-circle.tsx +0 -25
  100. package/src/component/radio-button/radio-button.module.css +0 -51
  101. package/src/component/radio-button/radio-button.tsx +0 -60
  102. package/src/component/rating/rating.module.css +0 -11
  103. package/src/component/rating/rating.tsx +0 -65
  104. package/src/component/select1/select1.module.css +0 -108
  105. package/src/component/select1/select1.tsx +0 -271
  106. package/src/component/switch/switch.module.css +0 -53
  107. package/src/component/switch/switch.tsx +0 -68
  108. package/src/component/table/table.css +0 -74
  109. package/src/component/table/table.tsx +0 -108
  110. package/src/component/tag/tag.module.css +0 -108
  111. package/src/component/tag/tag.tsx +0 -31
  112. package/src/component/text/text.css +0 -27
  113. package/src/component/text/text.tsx +0 -24
  114. package/src/component/text-area/text-area.module.css +0 -57
  115. package/src/component/text-area/text-area.tsx +0 -65
  116. package/src/component/text-field/text-field.module.css +0 -71
  117. package/src/component/text-field/text-field.tsx +0 -102
  118. package/src/component/toast-noti/toast-noti.css +0 -866
  119. package/src/component/toast-noti/toast-noti.tsx +0 -22
  120. package/src/component/wini-icon/winicon.module.css +0 -110
  121. package/src/component/wini-icon/winicon.tsx +0 -9424
  122. package/src/form/login/view.module.css +0 -80
  123. package/src/form/login/view.tsx +0 -138
  124. package/src/index.tsx +0 -66
  125. package/src/language/i18n.tsx +0 -143
  126. package/src/skin/layout.css +0 -649
  127. package/src/skin/root.css +0 -294
  128. package/src/skin/typography.css +0 -314
  129. package/src/vite-env.d.ts +0 -1
@@ -1,263 +0,0 @@
1
- import React, { createRef, CSSProperties } from 'react'
2
- import styles from './input-multi-select.module.css'
3
- import { OptionsItem } from '../select1/select1'
4
- import { Checkbox } from '../checkbox/checkbox'
5
- import { Text } from '../text/text'
6
- import { Winicon } from '../wini-icon/winicon'
7
- import { WithTranslation, withTranslation } from 'react-i18next';
8
- import { PopupOverlay } from '../popup/popup'
9
-
10
- interface SelectMultipleProps extends WithTranslation {
11
- id?: string,
12
- value?: Array<string | number>,
13
- options: Required<Array<OptionsItem>>,
14
- onChange?: (value?: Array<string | number>) => void,
15
- placeholder?: string,
16
- disabled?: boolean,
17
- className?: string,
18
- helperText?: string,
19
- helperTextColor?: string,
20
- style?: CSSProperties,
21
- handleSearch?: (e: string) => Promise<Array<OptionsItem>>,
22
- handleLoadmore?: (onLoadMore: boolean, ev: React.UIEvent<HTMLDivElement, UIEvent>) => void,
23
- showClearValueButton?: boolean,
24
- popupClassName?: string
25
- }
26
-
27
- interface SelectMultipleState {
28
- value: Array<string | number>,
29
- options: Required<Array<OptionsItem>>,
30
- offset: DOMRect,
31
- isOpen: boolean,
32
- onSelect: any,
33
- search?: Array<OptionsItem>,
34
- style?: Object
35
- };
36
-
37
- class TSelectMultiple extends React.Component<SelectMultipleProps, SelectMultipleState> {
38
- private containerRef = createRef<HTMLDivElement>()
39
- private inputRef = createRef<HTMLInputElement>()
40
- constructor(props: SelectMultipleProps) {
41
- super(props)
42
- this.state = {
43
- value: props.value ?? [],
44
- options: props.options,
45
- offset: {
46
- x: 0,
47
- y: 0,
48
- height: 0,
49
- width: 0,
50
- bottom: 0,
51
- left: 0,
52
- right: 0,
53
- top: 0,
54
- toJSON: function () {
55
- throw new Error('Function not implemented.')
56
- }
57
- },
58
- isOpen: false,
59
- onSelect: null,
60
- }
61
- this.onCheck = this.onCheck.bind(this)
62
- this.search = this.search.bind(this)
63
- this.onClickItem = this.onClickItem.bind(this)
64
- }
65
-
66
- private onCheck(value: boolean, list: Array<OptionsItem>) {
67
- let newValue: Array<string | number> = []
68
- if (value) {
69
- newValue = [...this.state.value, ...list.map(e => e.id)]
70
- } else {
71
- newValue = this.state.value.filter(vl => list.every(e => vl !== e.id))
72
- }
73
- this.setState({ ...this.state, value: newValue })
74
- if (this.props.onChange) this.props.onChange(newValue)
75
- }
76
-
77
- private async search(ev: React.ChangeEvent<HTMLInputElement>) {
78
- if (ev.target.value.trim().length) {
79
- if (this.props?.handleSearch) {
80
- const res = await this.props.handleSearch(ev.target.value.trim())
81
- this.setState({ ...this.state, search: res })
82
- } else {
83
- this.setState({
84
- ...this.state,
85
- search: this.props.options.filter(e => typeof e.name === "string" && e.name.toLowerCase().includes(ev.target.value.trim().toLowerCase()))
86
- })
87
- }
88
- } else {
89
- this.setState({ ...this.state, search: undefined })
90
- }
91
- }
92
-
93
- private onClickItem(ev: React.MouseEvent<HTMLDivElement>, item: string | number) {
94
- ev.stopPropagation()
95
- let newValue = this.state.value.filter(vl => vl !== item)
96
- this.setState({
97
- ...this.state,
98
- value: newValue,
99
- ...(this.state.isOpen ? {} : {
100
- isOpen: true,
101
- style: undefined,
102
- offset: this.containerRef?.current?.getBoundingClientRect() as any,
103
- })
104
- })
105
- if (this.props.onChange) this.props.onChange(newValue)
106
- }
107
-
108
- private renderOptions(item: OptionsItem) {
109
- let children: Array<OptionsItem> = []
110
- if (!item.parentId) children = (this.state.search ?? this.state.options).filter(e => e.parentId === item.id)
111
- //
112
- return <div key={item.id} className='col' style={{ width: '100%' }}>
113
- <div className={`${styles['select-tile']} row ${item.disabled ? styles["disabled"] : ""}`} style={{ paddingLeft: item.parentId ? '4.4rem' : undefined }} onClick={children.length ? () => {
114
- if (this.state.search) {
115
- this.setState({
116
- ...this.state, search: this.state.search.map(e => {
117
- if (e.id === item.id) return { ...e, isOpen: !(item as any).isOpen } as any
118
- else return e
119
- })
120
- })
121
- } else {
122
- this.setState({
123
- ...this.state, options: this.state.options.map(e => {
124
- if (e.id === item.id) return { ...e, isOpen: !(item as any).isOpen } as any
125
- else return e
126
- })
127
- })
128
- }
129
- } : undefined}>
130
- {(this.state.search ?? this.state.options).some(e => e.parentId) && <div className='row' style={{ width: '1.4rem', height: '1.4rem' }}>
131
- {children.length ? <Winicon src={(item as any).isOpen ? 'fill/arrows/triangle-down' : 'fill/arrows/triangle-right'} size={'1.2rem'} /> : null}
132
- </div>}
133
- <Checkbox disabled={item.disabled} value={children.length ? (children.every((e) => this.state.value.includes(e.id)) ? true : children.some((e) => this.state.value.includes(e.id)) ? undefined : false) : this.state.value.includes(item.id)} onChange={(v) => { this.onCheck(v, [item, ...children]) }} size={'2rem'} />
134
- <Text className='body-3'>{item.name}</Text>
135
- </div>
136
- <div className='col' style={{ display: (item as any).isOpen ? "flex" : "none", width: '100%' }}>{children.map(e => this.renderOptions(e))}</div>
137
- </div>
138
- }
139
-
140
- componentDidUpdate(prevProps: SelectMultipleProps, prevState: SelectMultipleState) {
141
- if (prevProps.options !== this.props.options) this.setState({ ...this.state, options: this.props.options })
142
- if (prevProps.value !== this.props.value) this.setState({ ...this.state, value: this.props.value ?? [] })
143
- //
144
- if (this.state.isOpen && (prevState.isOpen !== this.state.isOpen || prevState.value.length !== this.state.value.length)) {
145
- const thisPopupRect = this.containerRef.current!.querySelector(`.select-multi-popup`)?.getBoundingClientRect()
146
- if (thisPopupRect) {
147
- let style: { top?: string, left?: string, right?: string, bottom?: string, width?: string, height?: string } | undefined;
148
- if (prevState.isOpen !== this.state.isOpen && thisPopupRect.right > document.body.offsetWidth) {
149
- style = {
150
- top: this.state.offset.y + this.state.offset.height + 2 + 'px',
151
- right: document.body.offsetWidth - this.state.offset.right + 'px'
152
- }
153
- }
154
- let _bottom = thisPopupRect.bottom - 8
155
- const thisContainerRect = this.containerRef.current?.getBoundingClientRect()
156
- if (thisContainerRect) {
157
- if (prevState.value.length !== this.state.value.length) {
158
- _bottom = thisContainerRect.bottom + 2 + thisPopupRect.height
159
- style = { ...(style ?? {}), top: `${thisContainerRect.bottom + 2}px` }
160
- }
161
- if (_bottom > document.body.offsetHeight) {
162
- style = { ...(style ?? {}), top: `${thisContainerRect.y - 2 - thisPopupRect.height}px` }
163
- }
164
- }
165
- if (style) {
166
- style.left ??= (style.right ? undefined : `${this.state.offset.x}px`)
167
- style.width ??= `${this.state.offset.width}px`
168
- this.setState({ ...this.state, style: style })
169
- }
170
- }
171
- }
172
- }
173
-
174
- render() {
175
- const { t } = this.props;
176
- return <div
177
- id={this.props.id}
178
- ref={this.containerRef}
179
- className={`${styles['select-multi-container']} row ${this.props.disabled ? styles['disabled'] : ''} ${this.props.helperText?.length && styles['helper-text']} ${this.props.className ?? 'body-3'}`}
180
- helper-text={this.props.helperText}
181
- style={this.props.style ? { ...({ '--helper-text-color': this.props.helperTextColor ?? '#e14337' } as CSSProperties), ...this.props.style } : ({ '--helper-text-color': this.props.helperTextColor ?? '#e14337' } as CSSProperties)}
182
- onClick={() => {
183
- if (!this.state.isOpen) this.setState({
184
- ...this.state,
185
- isOpen: true,
186
- style: undefined,
187
- offset: this.containerRef?.current?.getBoundingClientRect() as any,
188
- })
189
- }}
190
- >
191
- <div className='row' style={{ flexWrap: 'wrap', flex: 1, width: '100%', gap: '0.6rem 0.4rem' }}>
192
- {this.state.value.map(item => {
193
- const optionItem = this.props.options.find(e => e.id === item)
194
- return <div key={item} className={`row ${styles['selected-item-value']}`} onClick={optionItem?.disabled ? undefined : (ev) => this.onClickItem(ev, item)}>
195
- <Text style={{ color: "var(--neutral-text-title-color)", fontSize: '1.2rem', lineHeight: '1.4rem' }} >{optionItem?.name}</Text>
196
- <Winicon src={"outline/user interface/e-remove"} size={'1.2rem'} />
197
- </div>
198
- })}
199
- {(!this.state.value.length || this.state.isOpen) && <input ref={this.inputRef} autoFocus={this.state.value.length > 0} onChange={this.search} placeholder={this.state.value.length ? undefined : this.props.placeholder}
200
- onBlur={ev => {
201
- if (this.state.isOpen) ev.target.focus()
202
- }}
203
- />}
204
- </div>
205
- {this.props.showClearValueButton && this.state.value.length ? <button type='button' className='row' style={{ padding: '0.4rem' }} onClick={(ev) => {
206
- ev.stopPropagation()
207
- if (this.state.value.length) this.setState({ ...this.state, isOpen: true, value: [] })
208
- }}>
209
- <Winicon src={"outline/user interface/c-remove"} size={'1.6rem'} />
210
- </button> : <div ref={iconRef => {
211
- if (iconRef?.parentElement && iconRef.parentElement.getBoundingClientRect().width < 100) iconRef.style.display = "none"
212
- }} className='row' >
213
- <Winicon src={this.state.isOpen ? "fill/arrows/up-arrow" : "fill/arrows/down-arrow"} size={'1.2rem'} />
214
- </div>}
215
- {this.state.isOpen && <PopupOverlay
216
- className={`hidden-overlay`}
217
- onClose={(ev) => {
218
- if (ev.target !== this.inputRef.current) this.setState({ ...this.state, isOpen: false })
219
- }}
220
- >
221
- <div className={`${styles['select-multi-popup']} select-multi-popup col ${this.props.popupClassName ?? ""}`}
222
- style={this.state.style ?? {
223
- top: this.state.offset.y + this.state.offset.height + 2 + 'px',
224
- left: this.state.offset.x + 'px',
225
- width: this.state.offset.width,
226
- }}>
227
- <div style={{ padding: '1.2rem 1.6rem', width: '100%', borderBottom: "var(--neutral-main-border)" }}>
228
- {(() => {
229
- const _list = (this.state.search ?? this.props.options ?? [])
230
- const isSelectedAll = _list.every(item => this.state.value.some(vl => vl === item.id))
231
- return <Text onClick={() => {
232
- let newValue: Array<string | number> = []
233
- if (_list.length) {
234
- if (isSelectedAll) {
235
- newValue = this.state.value.filter(vl => _list.every(item => vl !== item.id || item.disabled))
236
- } else {
237
- newValue = [...this.state.value, ..._list.filter(item => this.state.value.every(vl => vl !== item.id) && !item.disabled).map(e => e.id)]
238
- }
239
- }
240
- this.setState({ ...this.state, value: newValue })
241
- if (this.props.onChange) this.props.onChange(newValue)
242
- }} className='button-text-3' style={{ color: _list.length ? undefined : 'var(--neutral-text-title-color)' }}>{_list.length && isSelectedAll ? `${t("remove")} ${t("all").toLowerCase()}` : `${t("select")} ${t("all").toLowerCase()}`}</Text>
243
- })()}
244
- </div>
245
- <div className={`col ${styles['select-body']}`} onScroll={this.props.handleLoadmore ? (ev) => {
246
- if (this.props.handleLoadmore) {
247
- let scrollElement = ev.target as HTMLDivElement
248
- this.props.handleLoadmore(Math.round(scrollElement.offsetHeight + scrollElement.scrollTop) >= (scrollElement.scrollHeight - 1), ev)
249
- }
250
- } : undefined}>
251
- {(this.state.search ?? this.state.options).filter(e => !e.parentId).map(item => this.renderOptions(item))}
252
- {(!this.state.search?.length && !this.props.options?.length) && (
253
- <div className={styles['no-results-found']}>{t("noResultFound")}</div>
254
- )}
255
- </div>
256
- </div>
257
- </PopupOverlay>}
258
- </div>
259
- }
260
- }
261
-
262
- export const SelectMultiple = withTranslation()(TSelectMultiple)
263
-
@@ -1,41 +0,0 @@
1
- .input-opt-container {
2
- height: 4.8rem;
3
- gap: 0.8rem;
4
- }
5
-
6
- .input-opt-container>input {
7
- border: var(--neutral-bolder-border);
8
- height: 100%;
9
- aspect-ratio: 1 / 1;
10
- border-radius: 0.8rem;
11
- text-align: center;
12
- min-width: 3.2rem;
13
- font: inherit;
14
- font-size: inherit;
15
- font-family: inherit;
16
- font-weight: inherit;
17
- line-height: inherit;
18
- font-style: inherit;
19
- }
20
-
21
- .input-opt-container:focus-within>input {
22
- border-color: var(--primary-main-color);
23
- }
24
-
25
- .input-opt-container.helper-text {
26
- overflow: visible !important;
27
- border-color: var(--helper-text-color) !important;
28
- }
29
-
30
- .input-opt-container.helper-text::after {
31
- content: attr(helper-text);
32
- color: var(--helper-text-color);
33
- position: absolute;
34
- left: 0;
35
- bottom: -0.4rem;
36
- width: max-content;
37
- font-size: 1.2rem;
38
- line-height: 1.6rem;
39
- font-family: inherit;
40
- transform: translateY(100%);
41
- }
@@ -1,110 +0,0 @@
1
- import React, { createRef, CSSProperties, ReactNode } from "react";
2
- import styles from './input-otp.module.css'
3
-
4
- interface Props {
5
- id?: string,
6
- onChange?: (value: string, target: HTMLDivElement) => void
7
- disabled?: boolean,
8
- value?: string,
9
- length?: number,
10
- inputStyle?: CSSProperties,
11
- style?: CSSProperties,
12
- className?: string,
13
- helperText?: string,
14
- helperTextColor?: string,
15
- autoFocus?: boolean
16
- }
17
-
18
- export class InputOtp extends React.Component<Props> {
19
- private containerRef = createRef<HTMLDivElement>()
20
- constructor(props: Props | Readonly<Props>) {
21
- super(props);
22
- this.getValue = this.getValue.bind(this)
23
- }
24
-
25
- getValue = () => {
26
- if (this.containerRef.current)
27
- return [...(this.containerRef.current.querySelectorAll("input") as any)].map(v => v.value).join("")
28
- else return this.props.value ?? ""
29
- }
30
-
31
- componentDidUpdate(prevProps: Readonly<Props>): void {
32
- if (prevProps.value !== this.props.value && this.containerRef.current) {
33
- const inputList = [...(this.containerRef.current.querySelectorAll("input") as any)]
34
- if (this.props.value?.length) {
35
- for (let i = 0; i < inputList.length; i++) inputList[i].value = this.props.value[i]
36
- } else {
37
- for (let i = 0; i < inputList.length; i++) inputList[i].value = ""
38
- }
39
- }
40
- }
41
-
42
- render(): ReactNode {
43
- return <div
44
- id={this.props.id}
45
- ref={this.containerRef}
46
- helper-text={this.props.helperText}
47
- style={this.props.style ? { ...({ '--helper-text-color': this.props.helperTextColor ?? '#e14337' } as CSSProperties), ...this.props.style } : ({ '--helper-text-color': this.props.helperTextColor ?? '#e14337' } as CSSProperties)}
48
- className={`row body-1 ${styles['input-opt-container']} ${this.props.helperText?.length && 'helper-text'} ${this.props.className ?? ''}`}
49
- onMouseDown={(ev: any) => {
50
- ev.stopPropagation()
51
- ev.preventDefault()
52
- const inputList: any = [...ev.target.closest("div").childNodes]
53
- for (const [index, input] of inputList.entries()) {
54
- if (!input.value.length || index === (inputList.length - 1)) {
55
- input.focus()
56
- break;
57
- }
58
- continue;
59
- }
60
- }}
61
- >
62
- {Array.from({ length: this.props.length ?? 6 }).map((_, i) => <input
63
- key={"opt-" + i}
64
- autoFocus={i === 0 && this.props.autoFocus}
65
- disabled={this.props.disabled}
66
- style={this.props.inputStyle}
67
- onKeyDown={(ev: any) => {
68
- const key = ev.key.toLowerCase()
69
- switch (key) {
70
- case "backspace":
71
- if (ev.target.value.length) ev.target.value = ""
72
- else if (ev.target.previousSibling?.localName === "input") ev.target.previousSibling.focus()
73
- else ev.target.blur()
74
- break;
75
- case "delete":
76
- ev.target.value = ""
77
- break;
78
- default:
79
- ev.preventDefault()
80
- ev.stopPropagation()
81
- if (key === "v" && ev.ctrlKey) {
82
- return navigator.clipboard.readText().then(text => {
83
- const otpRegex = /^\d{6}$/g
84
- if (otpRegex.test(text)) {
85
- const inputList: any = [...ev.target.closest("div").childNodes]
86
- inputList.forEach((input: any, i: number) => {
87
- input.value = text[i]
88
- input.focus()
89
- })
90
- }
91
- })
92
- } else {
93
- const numberCheck = /[0-9]/g
94
- if (numberCheck.test(key) && !key.startsWith("f")) {
95
- if (!ev.target.value.length) ev.target.value = key
96
- if (ev.target.nextSibling?.localName === "input" && !ev.target.nextSibling.value.length) ev.target.nextSibling.focus()
97
- else ev.target.blur()
98
- }
99
- }
100
- break;
101
- }
102
- }}
103
- onBlur={() => {
104
- if (this.props.onChange) this.props.onChange(this.getValue(), this.containerRef.current!)
105
- }}
106
- />)}
107
- </div>
108
- }
109
- }
110
-
@@ -1,137 +0,0 @@
1
- .number-picker-container {
2
- position: relative;
3
- align-items: stretch;
4
- gap: 0.4rem;
5
- }
6
-
7
- .number-picker-container[number-picker-type="outline"] {
8
- border-radius: 0.8rem;
9
- padding: 0 0.6rem;
10
- border: var(--neutral-bolder-border);
11
- }
12
-
13
- .number-picker-container>div:has(>svg) {
14
- padding: 0.7rem;
15
- border: var(--neutral-bolder-border);
16
- border-radius: 50%;
17
- aspect-ratio: 1 / 1;
18
- height: 100%;
19
- cursor: pointer;
20
- }
21
-
22
- .number-picker-container[number-picker-type="outline"]>div:has(>svg) {
23
- padding: 0.6rem;
24
- }
25
-
26
- .number-picker-container[class~="size40"]>div>svg {
27
- width: 1.6rem;
28
- height: 1.6rem;
29
- }
30
-
31
- .number-picker-container[class~="size40"]>div:has(>svg) {
32
- padding: 1.1rem;
33
- }
34
-
35
- .number-picker-container[class~="size40"][number-picker-type="outline"]>div:has(>svg) {
36
- padding: 1rem;
37
- }
38
-
39
- .number-picker-container[class~="size24"]>div:has(>svg) {
40
- padding: 0.5rem;
41
- }
42
-
43
- .number-picker-container[class~="size24"][number-picker-type="outline"]>div:has(>svg) {
44
- padding: 0.4rem;
45
- }
46
-
47
- .number-picker-container[class~="size24"]>div>svg {
48
- width: 1.2rem;
49
- height: 1.2rem;
50
- }
51
-
52
- .number-picker-container[number-picker-type="outline"]>div:has(>svg) {
53
- border-color: transparent;
54
- border-radius: 0;
55
- }
56
-
57
- .number-picker-container>div>svg {
58
- height: 100%;
59
- flex: 1;
60
- aspect-ratio: 1 / 1;
61
- }
62
-
63
- .number-picker-container>div>svg * {
64
- fill: var(--neutral-text-subtitle-color);
65
- }
66
-
67
- .number-picker-container>input {
68
- flex: 1;
69
- width: 100%;
70
- min-width: 5.6rem;
71
- border: var(--neutral-bolder-border);
72
- border-color: transparent;
73
- outline: none;
74
- padding: 0 0.4rem;
75
- background-color: transparent !important;
76
- font: inherit;
77
- color: inherit;
78
- font-size: inherit;
79
- font-family: inherit;
80
- font-weight: inherit;
81
- line-height: inherit;
82
- text-align: center;
83
- text-overflow: inherit;
84
- }
85
-
86
- .number-picker-container>input:focus {
87
- border-color: var(--primary-main-color);
88
- border-radius: 0.8rem;
89
- }
90
-
91
- .number-picker-container[number-picker-type="outline"] input {
92
- border: none;
93
- }
94
-
95
- .number-picker-container[number-picker-type="outline"]:focus-within {
96
- border-color: var(--primary-main-color);
97
- }
98
-
99
- .number-picker-container:has(>input:disabled) {
100
- pointer-events: none !important;
101
- color: var(--neutral-text-disabled-color);
102
- }
103
-
104
- .number-picker-container[number-picker-type="outline"]:has(>input:disabled) {
105
- background-color: var(--neutral-disable-background-color);
106
- }
107
-
108
- .number-picker-container:has(>input:disabled)>div:has(>svg) {
109
- background-color: var(--neutral-disable-background-color);
110
- }
111
-
112
- .number-picker-container:has(>input:disabled) svg * {
113
- fill: var(--neutral-text-disabled-color);
114
- }
115
-
116
- .number-picker-container.helper-text {
117
- overflow: visible !important;
118
- border-color: var(--helper-text-color) !important;
119
- }
120
-
121
- .number-picker-container.helper-text {
122
- overflow: visible !important;
123
- border-color: var(--helper-text-color) !important;
124
- }
125
-
126
- .number-picker-container.helper-text::after {
127
- content: attr(helper-text);
128
- color: var(--helper-text-color);
129
- position: absolute;
130
- left: 0;
131
- bottom: -0.4rem;
132
- width: max-content;
133
- font-size: 1.2rem;
134
- line-height: 1.6rem;
135
- font-family: inherit;
136
- transform: translateY(100%);
137
- }
@@ -1,107 +0,0 @@
1
- import { CSSProperties, useEffect, useRef, useState } from "react";
2
- import styles from './number-picker.module.css'
3
-
4
- interface Props {
5
- id?: string,
6
- value?: number,
7
- onChange?: (ev: number) => void,
8
- disabled?: boolean,
9
- readOnly?: boolean,
10
- /**
11
- * default: size32: body-3 \
12
- * recommend: size40: body-2 | size24: body-3
13
- * */
14
- className?: string,
15
- helperText?: string,
16
- helperTextColor?: string,
17
- /** default: 1 */
18
- volume?: number,
19
- style?: CSSProperties,
20
- min?: number,
21
- max?: number,
22
- type?: "outline" | "icon-button",
23
- }
24
-
25
- export const NumberPicker = ({ id, value, onChange, disabled, readOnly, className, helperText, helperTextColor, max, min, style, type = "icon-button", volume = 1 }: Props) => {
26
- const [val, setValue] = useState<number>(0);
27
- const inputRef = useRef<HTMLInputElement>(null)
28
-
29
- useEffect(() => {
30
- if (inputRef.current) {
31
- setValue(value ?? 0)
32
- inputRef.current.value = `${value ?? 0}`
33
- }
34
- }, [value, inputRef])
35
-
36
- return <div id={id}
37
- className={`row ${styles["number-picker-container"]} ${className ?? "body-2"} ${helperText?.length && styles['helper-text']}`}
38
- number-picker-type={type ?? "icon-button"}
39
- helper-text={helperText}
40
- style={style ? { ...({ '--helper-text-color': helperTextColor ?? '#e14337' } as CSSProperties), ...style } : ({ '--helper-text-color': helperTextColor ?? '#e14337' } as CSSProperties)}
41
- >
42
- <div className="row" onClick={() => {
43
- let newValue = val - volume
44
- if (min === undefined || newValue >= min) {
45
- if (volume % 1 === 0) newValue = Math.round(newValue)
46
- else newValue = parseFloat(newValue.toFixed(1))
47
- setValue(newValue)
48
- if (inputRef.current) inputRef.current.value = `${newValue}`
49
- if (onChange) onChange(newValue)
50
- }
51
- }}>
52
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
53
- <path fillRule="evenodd" clipRule="evenodd" d="M1.3335 7.93907C1.3335 7.60435 1.60484 7.33301 1.93956 7.33301H14.0608C14.3955 7.33301 14.6668 7.60435 14.6668 7.93907C14.6668 8.27379 14.3955 8.54513 14.0608 8.54513H1.93956C1.60484 8.54513 1.3335 8.27379 1.3335 7.93907Z" />
54
- </svg>
55
- </div>
56
- <input
57
- ref={inputRef}
58
- readOnly={readOnly}
59
- disabled={disabled}
60
- onKeyDown={(ev) => {
61
- switch (ev.key.toLowerCase()) {
62
- case "enter":
63
- (ev.target as HTMLInputElement).blur()
64
- break;
65
- default:
66
- break;
67
- }
68
- }}
69
- onFocus={(ev) => { (ev.target as HTMLInputElement).select() }}
70
- onBlur={(ev) => {
71
- let newValue = volume % 1 === 0 ? parseInt(ev.target.value.trim()) : parseFloat(ev.target.value.trim())
72
- if (isNaN(newValue)) ev.target.value = `${val}`
73
- else {
74
- if (volume % 1 === 0) newValue = Math.round(newValue)
75
- else newValue = parseFloat(newValue.toFixed(1))
76
- if (min !== undefined && newValue < min) {
77
- setValue(min)
78
- if (inputRef.current) inputRef.current.value = `${min}`
79
- if (onChange) onChange(min)
80
- } else if (max !== undefined && newValue > max) {
81
- setValue(max)
82
- if (inputRef.current) inputRef.current.value = `${max}`
83
- if (onChange) onChange(max)
84
- } else {
85
- setValue(newValue)
86
- if (inputRef.current) inputRef.current.value = `${newValue}`
87
- if (onChange) onChange(newValue)
88
- }
89
- }
90
- }}
91
- />
92
- <div className="row" onClick={() => {
93
- let newValue = val + volume
94
- if (max === undefined || newValue <= max) {
95
- if (volume % 1 === 0) newValue = Math.round(newValue)
96
- else newValue = parseFloat(newValue.toFixed(1))
97
- setValue(newValue)
98
- if (inputRef.current) inputRef.current.value = `${newValue}`
99
- if (onChange) onChange(newValue)
100
- }
101
- }}>
102
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
103
- <path d="M8.60622 1.93907C8.60622 1.60435 8.33488 1.33301 8.00016 1.33301C7.66544 1.33301 7.3941 1.60435 7.3941 1.93907V7.39361H1.93956C1.60484 7.39361 1.3335 7.66496 1.3335 7.99967C1.3335 8.33439 1.60484 8.60574 1.93956 8.60574H7.3941V14.0603C7.3941 14.395 7.66544 14.6663 8.00016 14.6663C8.33488 14.6663 8.60622 14.395 8.60622 14.0603V8.60574H14.0608C14.3955 8.60574 14.6668 8.33439 14.6668 7.99967C14.6668 7.66496 14.3955 7.39361 14.0608 7.39361H8.60622V1.93907Z" />
104
- </svg>
105
- </div>
106
- </div>
107
- }