wini-web-components 2.8.2 → 2.8.5

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 (66) hide show
  1. package/dist/index.js.js +10 -10
  2. package/dist/index.js.mjs +198 -185
  3. package/package.json +6 -2
  4. package/src/component/button/button.module.css +210 -0
  5. package/src/component/button/button.tsx +57 -0
  6. package/src/component/calendar/calendar.module.css +153 -0
  7. package/src/component/calendar/calendar.tsx +389 -0
  8. package/src/component/carousel/carousel.css +622 -0
  9. package/src/component/carousel/carousel.tsx +91 -0
  10. package/src/component/checkbox/checkbox.module.css +48 -0
  11. package/src/component/checkbox/checkbox.tsx +80 -0
  12. package/src/component/ck-editor/ck-editor.css +206 -0
  13. package/src/component/ck-editor/ckeditor.tsx +522 -0
  14. package/src/component/component-status.tsx +53 -0
  15. package/src/component/date-time-picker/date-time-picker.module.css +94 -0
  16. package/src/component/date-time-picker/date-time-picker.tsx +663 -0
  17. package/src/component/dialog/dialog.module.css +111 -0
  18. package/src/component/dialog/dialog.tsx +109 -0
  19. package/src/component/import-file/import-file.module.css +83 -0
  20. package/src/component/import-file/import-file.tsx +174 -0
  21. package/src/component/infinite-scroll/infinite-scroll.module.css +34 -0
  22. package/src/component/infinite-scroll/infinite-scroll.tsx +35 -0
  23. package/src/component/input-multi-select/input-multi-select.module.css +121 -0
  24. package/src/component/input-multi-select/input-multi-select.tsx +263 -0
  25. package/src/component/input-otp/input-otp.module.css +41 -0
  26. package/src/component/input-otp/input-otp.tsx +110 -0
  27. package/src/component/number-picker/number-picker.module.css +137 -0
  28. package/src/component/number-picker/number-picker.tsx +107 -0
  29. package/src/component/pagination/pagination.module.css +48 -0
  30. package/src/component/pagination/pagination.tsx +88 -0
  31. package/src/component/popup/popup.css +136 -0
  32. package/src/component/popup/popup.tsx +125 -0
  33. package/src/component/progress-bar/progress-bar.module.css +42 -0
  34. package/src/component/progress-bar/progress-bar.tsx +33 -0
  35. package/src/component/progress-circle/progress-circle.css +0 -0
  36. package/src/component/progress-circle/progress-circle.tsx +25 -0
  37. package/src/component/radio-button/radio-button.module.css +51 -0
  38. package/src/component/radio-button/radio-button.tsx +60 -0
  39. package/src/component/rating/rating.module.css +11 -0
  40. package/src/component/rating/rating.tsx +65 -0
  41. package/src/component/select1/select1.module.css +108 -0
  42. package/src/component/select1/select1.tsx +271 -0
  43. package/src/component/switch/switch.module.css +53 -0
  44. package/src/component/switch/switch.tsx +68 -0
  45. package/src/component/table/table.css +74 -0
  46. package/src/component/table/table.tsx +108 -0
  47. package/src/component/tag/tag.module.css +108 -0
  48. package/src/component/tag/tag.tsx +31 -0
  49. package/src/component/text/text.css +27 -0
  50. package/src/component/text/text.tsx +24 -0
  51. package/src/component/text-area/text-area.module.css +57 -0
  52. package/src/component/text-area/text-area.tsx +65 -0
  53. package/src/component/text-field/text-field.module.css +71 -0
  54. package/src/component/text-field/text-field.tsx +102 -0
  55. package/src/component/toast-noti/toast-noti.css +866 -0
  56. package/src/component/toast-noti/toast-noti.tsx +22 -0
  57. package/src/component/wini-icon/winicon.module.css +110 -0
  58. package/src/component/wini-icon/winicon.tsx +9424 -0
  59. package/src/form/login/view.module.css +80 -0
  60. package/src/form/login/view.tsx +138 -0
  61. package/src/index.tsx +66 -0
  62. package/src/language/i18n.tsx +143 -0
  63. package/src/skin/layout.css +649 -0
  64. package/src/skin/root.css +294 -0
  65. package/src/skin/typography.css +314 -0
  66. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,389 @@
1
+ import React, { CSSProperties, ReactNode } from "react"
2
+ import styles from './calendar.module.css'
3
+ import { differenceInCalendarDays } from "date-fns"
4
+ import { WithTranslation, withTranslation } from 'react-i18next';
5
+ import { Winicon } from "../wini-icon/winicon";
6
+
7
+ export const today = new Date()
8
+ export const startDate = new Date(
9
+ today.getFullYear() - 100,
10
+ today.getMonth(),
11
+ today.getDate()
12
+ )
13
+ export const endDate = new Date(
14
+ today.getFullYear() + 100,
15
+ today.getMonth(),
16
+ today.getDate()
17
+ )
18
+
19
+ export const inRangeTime = (date: Date, startDate: Date, endDate: Date) => (differenceInCalendarDays(date, startDate) > -1 && differenceInCalendarDays(endDate, date) > -1)
20
+
21
+ enum CalendarTab {
22
+ DATE = 0,
23
+ MONTH = 1,
24
+ YEAR = 2,
25
+ }
26
+
27
+ interface CalendarProps extends WithTranslation {
28
+ id?: string,
29
+ value?: Date | { sTime: Date, eTime: Date },
30
+ range?: boolean,
31
+ min?: Date,
32
+ max?: Date,
33
+ onSelect?: (props: Date | { sTime: Date, eTime: Date }) => void,
34
+ disabled?: boolean,
35
+ helperText?: string,
36
+ helperTextColor?: string,
37
+ placeholder?: string,
38
+ className?: string,
39
+ style?: CSSProperties,
40
+ header?: ReactNode,
41
+ footer?: ReactNode,
42
+ }
43
+
44
+ interface CalendarState {
45
+ value?: Date | { sTime: Date, eTime: Date },
46
+ selectMonth: number,
47
+ selectYear: number,
48
+ tab: CalendarTab,
49
+ }
50
+
51
+ const stateValue = (minDate: Date, maxDate: Date, value?: Date | { sTime: Date, eTime: Date }, range?: boolean) => {
52
+ let defaultValue: Date | { sTime: Date, eTime: Date }
53
+ if (value) {
54
+ if (range) {
55
+ if (value instanceof Date) defaultValue = { sTime: value, eTime: value }
56
+ else defaultValue = value
57
+ if (defaultValue.sTime.getTime() < minDate.getTime()) defaultValue.sTime = minDate
58
+ if (defaultValue.eTime.getTime() > maxDate.getTime()) defaultValue.eTime = maxDate
59
+ } else {
60
+ if (value instanceof Date) defaultValue = value
61
+ else defaultValue = value.sTime
62
+ if (defaultValue.getTime() < minDate.getTime()) defaultValue = minDate
63
+ if (defaultValue.getTime() > maxDate.getTime()) defaultValue = maxDate
64
+ }
65
+ } else {
66
+ defaultValue = range ? { sTime: today, eTime: today } : today
67
+ }
68
+ const defaultMonth = defaultValue instanceof Date ? defaultValue.getMonth() : defaultValue.sTime.getMonth()
69
+ const defaultYear = defaultValue instanceof Date ? defaultValue.getFullYear() : defaultValue.sTime.getFullYear()
70
+ return {
71
+ value: value ? defaultValue : undefined,
72
+ selectMonth: defaultMonth,
73
+ selectYear: defaultYear,
74
+ tab: CalendarTab.DATE,
75
+ }
76
+ }
77
+
78
+ class TCalendar extends React.Component<CalendarProps, CalendarState> {
79
+ private minDate: Date;
80
+ private maxDate: Date;
81
+ constructor(props: CalendarProps) {
82
+ super(props);
83
+ this.minDate = !this.props.min || this.props.min.getTime() < startDate.getTime() ? startDate : this.props.min
84
+ this.maxDate = !this.props.max || this.props.max.getTime() > endDate.getTime() ? endDate : this.props.max
85
+ this.state = stateValue(this.minDate, this.maxDate, this.props.value, this.props.range)
86
+ this.showDateInMonth = this.showDateInMonth.bind(this)
87
+ this.showMonthInYear = this.showMonthInYear.bind(this)
88
+ this.showYearInRange = this.showYearInRange.bind(this)
89
+ this.getTitle = this.getTitle.bind(this)
90
+ }
91
+
92
+ componentDidUpdate(prevProps: Readonly<CalendarProps>, prevState: Readonly<CalendarState>, snapshot?: any): void {
93
+ if (prevProps.value !== this.props.value) {
94
+ this.setState(stateValue(this.minDate, this.maxDate, this.props.value, this.props.range))
95
+ }
96
+ }
97
+
98
+ private showDateInMonth() {
99
+ let firstDayOfMonth = new Date(this.state.selectYear, this.state.selectMonth, 1)
100
+ return <>
101
+ {Array.from({ length: 7 }).map((_, i) => {
102
+ switch (i) {
103
+ case 0:
104
+ var weekdayTitle = this.props.t("su")
105
+ break
106
+ case 1:
107
+ weekdayTitle = this.props.t("mo")
108
+ break
109
+ case 2:
110
+ weekdayTitle = this.props.t("tu")
111
+ break
112
+ case 3:
113
+ weekdayTitle = this.props.t("we")
114
+ break
115
+ case 4:
116
+ weekdayTitle = this.props.t("th")
117
+ break
118
+ case 5:
119
+ weekdayTitle = this.props.t("fr")
120
+ break
121
+ case 6:
122
+ weekdayTitle = this.props.t("sa")
123
+ break
124
+ default:
125
+ weekdayTitle = ''
126
+ break
127
+ }
128
+ return <div key={'dtwk-' + i} className={`${styles['date-picker-circle']} date-picker-circle`}><span className="label-4 row">{weekdayTitle}</span></div>
129
+ })}
130
+ {Array.from({ length: 42 }).map((_, i) => {
131
+ let dateNumber = (i % 7) + (Math.floor(i / 7) * 7) - firstDayOfMonth.getDay()
132
+ const timeValue = new Date(this.state.selectYear, this.state.selectMonth, dateNumber + 1)
133
+ let className = `${styles['date-picker-circle']} date-picker-circle`
134
+ let typoClassName = "body-3"
135
+ if (dateNumber + 1 === today.getDate() && this.state.selectMonth === today.getMonth() && this.state.selectYear === today.getFullYear()) {
136
+ className += ` ${styles['today']}`
137
+ }
138
+ let style: CSSProperties | undefined;
139
+ if (!inRangeTime(timeValue, this.minDate, this.maxDate)) {
140
+ className += ` ${styles['invalid']}`
141
+ } else if (this.state.value instanceof Date) {
142
+ if (this.state.value.getTime() === timeValue.getTime()) className += ` ${styles['selected']}`
143
+ } else if ((this.state.value?.sTime.getDate() === timeValue.getDate() && (Math.abs(differenceInCalendarDays(timeValue, this.state.value.sTime))) < 1) || (this.state.value?.eTime.getDate() === timeValue.getDate() && (Math.abs(differenceInCalendarDays(timeValue, this.state.value.eTime))) < 1)) {
144
+ className += ` ${styles['selected']} ${styles[`${this.state.value?.sTime.getDate() === timeValue.getDate() && (Math.abs(differenceInCalendarDays(timeValue, this.state.value.sTime))) < 1 ? "start" : "end"}-range`]}`
145
+ } else if (this.state.value && inRangeTime(timeValue, this.state.value.sTime, this.state.value.eTime)) {
146
+ className += ` ${styles['in-range']}`
147
+ }
148
+ if (timeValue.getMonth() !== this.state.selectMonth) {
149
+ typoClassName = "placeholder-2"
150
+ }
151
+ return <div key={timeValue.toString()} className={className} style={style}>
152
+ <button type="button" className={`${typoClassName} row`}
153
+ onClick={() => {
154
+ const currentValue = this.state.value as any
155
+ if (this.props.range) {
156
+ const newValue = (!currentValue || timeValue.getTime() < currentValue.sTime.getTime()) ? { sTime: timeValue, eTime: timeValue } : { sTime: currentValue.sTime, eTime: timeValue }
157
+ this.setState({ ...this.state, value: newValue })
158
+ if (this.props.onSelect) this.props.onSelect(newValue)
159
+ } else {
160
+ this.setState({ ...this.state, value: timeValue })
161
+ if (this.props.onSelect) this.props.onSelect(timeValue)
162
+ }
163
+ }} >
164
+ {timeValue.getDate()}
165
+ </button>
166
+ </div>
167
+ })}
168
+ </>
169
+ }
170
+
171
+ private showMonthInYear() {
172
+ return <>
173
+ {Array.from({ length: 12 }).map((_, i) => {
174
+ switch (i) {
175
+ case 0:
176
+ var monthTitle = this.props.i18n.language === "en" ? "Jan" : this.props.t('january')
177
+ break
178
+ case 1:
179
+ monthTitle = this.props.i18n.language === "en" ? "Feb" : this.props.t('february')
180
+ break
181
+ case 2:
182
+ monthTitle = this.props.i18n.language === "en" ? "Mar" : this.props.t('march')
183
+ break
184
+ case 3:
185
+ monthTitle = this.props.i18n.language === "en" ? "Apr" : this.props.t('april')
186
+ break
187
+ case 4:
188
+ monthTitle = this.props.i18n.language === "en" ? "May" : this.props.t('may')
189
+ break
190
+ case 5:
191
+ monthTitle = this.props.i18n.language === "en" ? "Jun" : this.props.t('june')
192
+ break
193
+ case 6:
194
+ monthTitle = this.props.i18n.language === "en" ? "Jul" : this.props.t('july')
195
+ break
196
+ case 7:
197
+ monthTitle = this.props.i18n.language === "en" ? "Aug" : this.props.t('august')
198
+ break
199
+ case 8:
200
+ monthTitle = this.props.i18n.language === "en" ? "Sep" : this.props.t('september')
201
+ break
202
+ case 9:
203
+ monthTitle = this.props.i18n.language === "en" ? "Oct" : this.props.t('october')
204
+ break
205
+ case 10:
206
+ monthTitle = this.props.i18n.language === "en" ? "Nov" : this.props.t('november')
207
+ break
208
+ case 11:
209
+ monthTitle = this.props.i18n.language === "en" ? "Dec" : this.props.t('december')
210
+ break
211
+ default:
212
+ monthTitle = ''
213
+ break
214
+ }
215
+ const timeValue = new Date(this.state.selectYear, i)
216
+ let className = `${styles['month-picker-circle']} month-picker-circle`
217
+ if (this.state.selectYear === today.getFullYear() && today.getMonth() === i) {
218
+ className += ` ${styles['today']}`
219
+ }
220
+ if (!inRangeTime(timeValue, this.minDate, this.maxDate)) {
221
+ className += ` ${styles['invalid']}`
222
+ } else if (this.state.value instanceof Date) {
223
+ if (this.state.selectYear === this.state.value.getFullYear() && i === this.state.value.getMonth()) className += ` ${styles['selected']}`
224
+ } else if (this.state.value && ((i === this.state.value.sTime.getMonth() && this.state.value.sTime.getFullYear() === this.state.selectYear) || (i === this.state.value.eTime.getMonth() && this.state.value.eTime.getFullYear() === this.state.selectYear))) {
225
+ className += ` ${styles['selected']} ${styles[`${i === this.state.value.sTime.getMonth() && this.state.value.sTime.getFullYear() === this.state.selectYear ? "start" : "end"}-range`]}`
226
+ } else if (this.state.value && inRangeTime(timeValue, this.state.value.sTime, this.state.value.eTime)) {
227
+ className += ` ${styles['in-range']}`
228
+ }
229
+ return <div key={timeValue.toString()} className={className}>
230
+ <button type="button" className="body-3 row" onClick={() => { this.setState({ ...this.state, selectMonth: i, tab: CalendarTab.DATE }) }}>
231
+ {monthTitle}
232
+ </button>
233
+ </div>
234
+ })}
235
+ </>
236
+ }
237
+
238
+ private showYearInRange() {
239
+ return Array.from({ length: 12 }).map((_, i) => {
240
+ let firstYearInTable = this.state.selectYear - ((this.state.selectYear - startDate.getFullYear()) % 12)
241
+ let yearNumber = i + firstYearInTable
242
+ let className = `${styles['year-picker-circle']} year-picker-circle`
243
+ if (yearNumber === today.getFullYear()) {
244
+ className += ` ${styles['today']}`
245
+ }
246
+ if (yearNumber < this.minDate.getFullYear() || yearNumber > this.maxDate.getFullYear()) {
247
+ className += ` ${styles['invalid']}`
248
+ } else if (this.state.value instanceof Date) {
249
+ if (yearNumber === this.state.value.getFullYear()) className += ` ${styles['selected']}`
250
+ } else if (yearNumber === this.state.value?.sTime.getFullYear() || yearNumber === this.state.value?.eTime.getFullYear()) {
251
+ className += ` ${styles['selected']} ${styles[`${yearNumber === this.state.value?.sTime.getFullYear() ? "start" : "end"}-range`]}`
252
+ } else if (this.state.value && yearNumber > this.state.value.sTime.getFullYear() && yearNumber < this.state.value.eTime.getFullYear()) {
253
+ className += ` ${styles['in-range']}`
254
+ }
255
+ return <div key={yearNumber.toString()} className={className}>
256
+ <button type="button" className="body-3 row" onClick={() => { this.setState({ ...this.state, tab: CalendarTab.MONTH, selectYear: yearNumber }) }}>
257
+ {yearNumber}
258
+ </button>
259
+ </div>
260
+ })
261
+ }
262
+
263
+ private getTitle() {
264
+ switch (this.state.tab) {
265
+ case CalendarTab.YEAR:
266
+ let firstYearInTable = this.state.selectYear - ((this.state.selectYear - startDate.getFullYear()) % 12)
267
+ return `${firstYearInTable}-${firstYearInTable + 11}`
268
+ case CalendarTab.MONTH:
269
+ return this.state.selectYear
270
+ default:
271
+ switch (this.state.selectMonth) {
272
+ case 0:
273
+ var monthName = this.props.t('january')
274
+ break
275
+ case 1:
276
+ monthName = this.props.t('february')
277
+ break
278
+ case 2:
279
+ monthName = this.props.t('march')
280
+ break
281
+ case 3:
282
+ monthName = this.props.t('april')
283
+ break
284
+ case 4:
285
+ monthName = this.props.t('may')
286
+ break
287
+ case 5:
288
+ monthName = this.props.t('june')
289
+ break
290
+ case 6:
291
+ monthName = this.props.t('july')
292
+ break
293
+ case 7:
294
+ monthName = this.props.t('august')
295
+ break
296
+ case 8:
297
+ monthName = this.props.t('september')
298
+ break
299
+ case 9:
300
+ monthName = this.props.t('october')
301
+ break
302
+ case 10:
303
+ monthName = this.props.t('november')
304
+ break
305
+ case 11:
306
+ monthName = this.props.t('december')
307
+ break
308
+ default:
309
+ monthName = ''
310
+ break
311
+ }
312
+ return `${monthName}${this.props.i18n.language === 'en' ? ' ' : '/'}${this.state.selectYear}`
313
+ }
314
+ }
315
+
316
+ render(): React.ReactNode {
317
+ return <div className={`${styles['calendar-container']} col ${this.props.className ?? ""}`} style={this.props.style}>
318
+ {this.props.header}
319
+ <div className={`${styles['picker-date-header']} row`}>
320
+ <button type='button'
321
+ onClick={() => {
322
+ switch (this.state.tab) {
323
+ case CalendarTab.YEAR:
324
+ if (this.state.selectYear - 10 < startDate.getFullYear()) {
325
+ this.setState({ ...this.state, selectYear: startDate.getFullYear() })
326
+ } else {
327
+ this.setState({ ...this.state, selectYear: this.state.selectYear - 10 })
328
+ }
329
+ break
330
+ case CalendarTab.MONTH:
331
+ const newTime = new Date(this.state.selectYear, this.state.selectMonth - 1)
332
+ if (newTime.getTime() >= startDate.getTime()) {
333
+ this.setState({ ...this.state, selectYear: this.state.selectYear - 1 })
334
+ }
335
+ break
336
+ default:
337
+ const newDataVl = new Date(this.state.selectYear, this.state.selectMonth - 1)
338
+ if (newDataVl.getTime() >= startDate.getTime()) {
339
+ this.setState({ ...this.state, selectMonth: newDataVl.getMonth(), selectYear: newDataVl.getFullYear() })
340
+ }
341
+ break
342
+ }
343
+ }}
344
+ >
345
+ <Winicon src={"fill/arrows/left-arrow"} size={'1.4rem'} />
346
+ </button>
347
+ <span className="heading-7" onClick={() => {
348
+ if (this.state.tab !== CalendarTab.YEAR)
349
+ this.setState({ ...this.state, tab: this.state.tab === CalendarTab.DATE ? CalendarTab.MONTH : CalendarTab.YEAR })
350
+ }}>
351
+ {this.getTitle()}
352
+ </span>
353
+ <button type='button'
354
+ onClick={() => {
355
+ switch (this.state.tab) {
356
+ case CalendarTab.YEAR:
357
+ if (this.state.selectYear + 10 > endDate.getFullYear()) {
358
+ this.setState({ ...this.state, selectYear: endDate.getFullYear() })
359
+ } else {
360
+ this.setState({ ...this.state, selectYear: this.state.selectYear + 10 })
361
+ }
362
+ break
363
+ case CalendarTab.MONTH:
364
+ const newTime = new Date(this.state.selectYear, this.state.selectMonth + 1)
365
+ if (newTime.getTime() <= endDate.getTime()) {
366
+ this.setState({ ...this.state, selectYear: this.state.selectYear + 1 })
367
+ }
368
+ break
369
+ default:
370
+ const newDataVl = new Date(this.state.selectYear, this.state.selectMonth + 1)
371
+ if (newDataVl.getTime() <= endDate.getTime()) {
372
+ this.setState({ ...this.state, selectMonth: newDataVl.getMonth(), selectYear: newDataVl.getFullYear() })
373
+ }
374
+ break
375
+ }
376
+ }}
377
+ >
378
+ <Winicon src={"fill/arrows/right-arrow"} size={'1.4rem'} />
379
+ </button>
380
+ </div>
381
+ <div className={`${styles['picker-date-body']} row`} >
382
+ {this.state.tab === CalendarTab.YEAR ? this.showYearInRange() : this.state.tab === CalendarTab.MONTH ? this.showMonthInYear() : this.showDateInMonth()}
383
+ </div>
384
+ {this.props.footer}
385
+ </div>
386
+ }
387
+ }
388
+
389
+ export const Calendar = withTranslation()(TCalendar)