forstok-ui-lib 7.0.1 → 7.2.1
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.d.ts +119 -6
- package/dist/index.js +651 -444
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +632 -425
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
- package/rollup.config.js +21 -1
- package/src/components/date/range.tsx +138 -0
- package/src/components/date/ref.tsx +109 -0
- package/src/components/date/{styles.tsx → styles.ts} +65 -1
- package/src/components/date/typed.ts +3 -0
- package/src/components/index.ts +9 -0
- package/src/components/select/all.tsx +2 -2
- package/src/components/select/asyncPaginate.tsx +273 -0
- package/src/components/select/function.ts +8 -0
- package/src/components/table/index.tsx +120 -0
- package/src/components/table/style.ts +178 -0
- package/src/components/table/type.ts +15 -0
- package/src/maps/common.ts +8 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forstok-ui-lib",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.2.1",
|
|
4
4
|
"description": "Forstok UI Components Library",
|
|
5
5
|
"path": "dist",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -46,11 +46,13 @@
|
|
|
46
46
|
"moment": "^2.30.1",
|
|
47
47
|
"moment-range": "^4.0.2",
|
|
48
48
|
"npm-force-resolutions": "^0.0.10",
|
|
49
|
+
"rc-picker": "^4.11.3",
|
|
49
50
|
"react": "^19.0.0",
|
|
50
51
|
"react-content-loader": "^7.0.2",
|
|
51
|
-
"react-datepicker": "^8.
|
|
52
|
+
"react-datepicker": "^8.1.0",
|
|
52
53
|
"react-router-dom": "^7.1.1",
|
|
53
54
|
"react-select": "^5.10.0",
|
|
55
|
+
"react-select-async-paginate": "^0.7.9",
|
|
54
56
|
"rollup-plugin-dts": "^6.1.1",
|
|
55
57
|
"rollup-plugin-import-css": "^3.5.8",
|
|
56
58
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
package/rollup.config.js
CHANGED
|
@@ -74,7 +74,27 @@ export default [
|
|
|
74
74
|
exclude: 'node_modules/**'
|
|
75
75
|
})
|
|
76
76
|
],
|
|
77
|
-
external: [
|
|
77
|
+
external: [
|
|
78
|
+
'react',
|
|
79
|
+
'react-dom',
|
|
80
|
+
'react-router-dom',
|
|
81
|
+
'styled-components',
|
|
82
|
+
'@wojtekmaj/react-daterange-picker',
|
|
83
|
+
'approvejs',
|
|
84
|
+
'html-to-text',
|
|
85
|
+
'moment',
|
|
86
|
+
'moment-range',
|
|
87
|
+
'react-datepicker',
|
|
88
|
+
'react-select',
|
|
89
|
+
'use-state-with-callback',
|
|
90
|
+
'frimousse',
|
|
91
|
+
'react-select-async-paginate',
|
|
92
|
+
'rc-picker',
|
|
93
|
+
'rc-picker/lib/interface',
|
|
94
|
+
'rc-picker/lib/locale/en_US',
|
|
95
|
+
'rc-picker/lib/generate/moment',
|
|
96
|
+
'moment'
|
|
97
|
+
],
|
|
78
98
|
},
|
|
79
99
|
{
|
|
80
100
|
input: 'src/index.ts',
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from 'react'
|
|
2
|
+
import moment, { Moment } from 'moment'
|
|
3
|
+
import { RangePicker } from 'rc-picker'
|
|
4
|
+
import { RangePickerRef } from 'rc-picker/lib/interface'
|
|
5
|
+
import enUS from 'rc-picker/lib/locale/en_US'
|
|
6
|
+
import momentGenerateConfig from 'rc-picker/lib/generate/moment'
|
|
7
|
+
|
|
8
|
+
import IconComponent from '../icon'
|
|
9
|
+
|
|
10
|
+
import 'rc-picker/assets/index.css'
|
|
11
|
+
import { RangeContainer } from './styles'
|
|
12
|
+
|
|
13
|
+
import { TMoment, TState } from '../../typeds/base.typed'
|
|
14
|
+
import { TModerateDateAntFunction } from './typed'
|
|
15
|
+
|
|
16
|
+
import { configDateRangeAnt } from '../../maps/common'
|
|
17
|
+
|
|
18
|
+
type TDateRange = {
|
|
19
|
+
$mode?: 'white'
|
|
20
|
+
startDate?: TMoment
|
|
21
|
+
endDate?: TMoment
|
|
22
|
+
minDate?: TMoment
|
|
23
|
+
maxDate?: TMoment
|
|
24
|
+
evModDate: TModerateDateAntFunction
|
|
25
|
+
isForceUpdate?: boolean
|
|
26
|
+
setForceUpdate?: TState<boolean | undefined>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const DateRangeComponent = (props: TDateRange) => {
|
|
30
|
+
const {
|
|
31
|
+
$mode,
|
|
32
|
+
startDate,
|
|
33
|
+
endDate,
|
|
34
|
+
minDate,
|
|
35
|
+
maxDate,
|
|
36
|
+
evModDate,
|
|
37
|
+
isForceUpdate,
|
|
38
|
+
setForceUpdate
|
|
39
|
+
} = props
|
|
40
|
+
|
|
41
|
+
const _minDate: Moment = minDate || configDateRangeAnt.minDate
|
|
42
|
+
let _startDate: Moment = startDate || configDateRangeAnt.startDate
|
|
43
|
+
let _endDate: Moment = endDate || configDateRangeAnt.endDate
|
|
44
|
+
|
|
45
|
+
_minDate > _startDate && (_startDate = _minDate);
|
|
46
|
+
(maxDate && (maxDate < _endDate)) && (_endDate = maxDate);
|
|
47
|
+
|
|
48
|
+
const [value, setValue] = useState<[TMoment, TMoment]>([_startDate, _endDate])
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (isForceUpdate) {
|
|
52
|
+
_startDate && _endDate && setValue([_startDate, _endDate]);
|
|
53
|
+
setForceUpdate && setForceUpdate(false)
|
|
54
|
+
}
|
|
55
|
+
},[isForceUpdate, setForceUpdate, _startDate, _endDate])
|
|
56
|
+
|
|
57
|
+
const onChange = (newValue: [TMoment, TMoment] | null, formatStrings?: string[]) => {
|
|
58
|
+
// console.log('Change:', newValue, formatStrings)
|
|
59
|
+
if (newValue) {
|
|
60
|
+
setValue(newValue)
|
|
61
|
+
evModDate(newValue[0], newValue[1])
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// can detect start and end action
|
|
66
|
+
// const onCalendarChange = (
|
|
67
|
+
// newValue: [TMoment, TMoment] | null,
|
|
68
|
+
// formatStrings?: string[],
|
|
69
|
+
// ) => {
|
|
70
|
+
// console.log('Calendar Change:', newValue, formatStrings)
|
|
71
|
+
// }
|
|
72
|
+
|
|
73
|
+
const rest = {
|
|
74
|
+
generateConfig: momentGenerateConfig,
|
|
75
|
+
value,
|
|
76
|
+
onChange,
|
|
77
|
+
// onCalendarChange,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const rangePickerRef = useRef<RangePickerRef>(null)
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<RangeContainer className='_refRangeContainer' $mode={$mode}>
|
|
84
|
+
<RangePicker
|
|
85
|
+
onOpenChange={open => {
|
|
86
|
+
const parentEl = rangePickerRef.current?.nativeElement?.closest('._refRangeContainer')
|
|
87
|
+
if (parentEl) {
|
|
88
|
+
if (open) {
|
|
89
|
+
parentEl.classList.add('is-actived')
|
|
90
|
+
} else {
|
|
91
|
+
parentEl.classList.remove('is-actived')
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}}
|
|
95
|
+
allowEmpty
|
|
96
|
+
allowClear={false}
|
|
97
|
+
locale={enUS}
|
|
98
|
+
ref={rangePickerRef}
|
|
99
|
+
separator='-'
|
|
100
|
+
format="MMM D, YYYY"
|
|
101
|
+
placeholder={['Start Date', 'End Date']}
|
|
102
|
+
minDate={_minDate}
|
|
103
|
+
maxDate={maxDate || moment().clone()}
|
|
104
|
+
defaultValue={value}
|
|
105
|
+
suffixIcon={<IconComponent $width='14px' $name='calendar' />}
|
|
106
|
+
prevIcon={<IconComponent $width='12px' $name='arrow-left' />}
|
|
107
|
+
nextIcon={<IconComponent $width='12px' $name='arrow-right' />}
|
|
108
|
+
superPrevIcon={<IconComponent $width='12px' $name='arrow-left-double' />}
|
|
109
|
+
superNextIcon={<IconComponent $width='12px' $name='arrow-right-double' />}
|
|
110
|
+
presets={[
|
|
111
|
+
{
|
|
112
|
+
label: 'Today',
|
|
113
|
+
value: [moment().clone(), moment()],
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
label: 'Last 7 days',
|
|
117
|
+
value: [moment().subtract(6, 'days'), moment()],
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
label: 'Last 14 days',
|
|
121
|
+
value: [moment().subtract(13, 'days'), moment()],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
label: 'Last 30 days',
|
|
125
|
+
value: [moment().subtract(29, 'days'), moment()],
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
label: 'Last 90 days',
|
|
129
|
+
value: [moment().subtract(89, 'days'), moment()],
|
|
130
|
+
},
|
|
131
|
+
]}
|
|
132
|
+
{...rest}
|
|
133
|
+
/>
|
|
134
|
+
</RangeContainer>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export default DateRangeComponent
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { forwardRef, useState, useEffect } from 'react'
|
|
2
|
+
import DatePicker from 'react-datepicker'
|
|
3
|
+
import moment from 'moment'
|
|
4
|
+
|
|
5
|
+
import IconComponent from '../icon'
|
|
6
|
+
|
|
7
|
+
import 'react-datepicker/dist/react-datepicker.css'
|
|
8
|
+
import { DateContainer, DateIndicatorContainer } from './styles'
|
|
9
|
+
import { TState } from '../../typeds/base.typed'
|
|
10
|
+
|
|
11
|
+
type TDate = {
|
|
12
|
+
dateFormat?: string
|
|
13
|
+
name: string
|
|
14
|
+
evChange?: (name: string, value: any) => void
|
|
15
|
+
isField?: boolean
|
|
16
|
+
evChangeCustom? : (key: string, value: any) => void
|
|
17
|
+
saveFormat?: string
|
|
18
|
+
showFormat?: string
|
|
19
|
+
isForceUpdate?: boolean
|
|
20
|
+
reset?: boolean
|
|
21
|
+
setReset?: TState<boolean>
|
|
22
|
+
value?: Date | null
|
|
23
|
+
isError?: boolean
|
|
24
|
+
allowEmpty?: boolean
|
|
25
|
+
setForceUpdate?: TState<boolean>
|
|
26
|
+
showTimeInput?: boolean
|
|
27
|
+
placeholderText?: string
|
|
28
|
+
portalId?: string
|
|
29
|
+
isIcon?: boolean
|
|
30
|
+
'data-qa-id'?: string
|
|
31
|
+
'data-tip'?: string
|
|
32
|
+
'data-place'?: string
|
|
33
|
+
'data-type'?: string
|
|
34
|
+
disabled?: boolean
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const DateRefComponent = forwardRef((props:TDate, ref) => {
|
|
38
|
+
const {
|
|
39
|
+
dateFormat='MMM dd, yyyy',
|
|
40
|
+
name,
|
|
41
|
+
evChange,
|
|
42
|
+
isField,
|
|
43
|
+
saveFormat,
|
|
44
|
+
showFormat,
|
|
45
|
+
evChangeCustom,
|
|
46
|
+
value,
|
|
47
|
+
reset,
|
|
48
|
+
setReset,
|
|
49
|
+
isForceUpdate,
|
|
50
|
+
setForceUpdate,
|
|
51
|
+
isError=false,
|
|
52
|
+
showTimeInput=false,
|
|
53
|
+
allowEmpty=false,
|
|
54
|
+
placeholderText,
|
|
55
|
+
portalId,
|
|
56
|
+
isIcon,
|
|
57
|
+
disabled,
|
|
58
|
+
...rest
|
|
59
|
+
} = props
|
|
60
|
+
|
|
61
|
+
const [_date , setDate] = useState<Date | null>(value !== undefined ? value : (allowEmpty ? null : new Date()))
|
|
62
|
+
|
|
63
|
+
const handleChange = (value: Date | null) => {
|
|
64
|
+
setDate(value)
|
|
65
|
+
evChange && evChange(name, value);
|
|
66
|
+
(isField && evChangeCustom) && evChangeCustom(name, value ? moment(value).format(saveFormat) : value);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if(reset) {
|
|
71
|
+
setDate(null)
|
|
72
|
+
setReset && setReset(false)
|
|
73
|
+
}
|
|
74
|
+
if (isForceUpdate) {
|
|
75
|
+
const newValue = value ? value : (allowEmpty ? null : new Date())
|
|
76
|
+
setDate(newValue)
|
|
77
|
+
setForceUpdate && setForceUpdate(false)
|
|
78
|
+
}
|
|
79
|
+
}, [isForceUpdate, setForceUpdate, value, allowEmpty, reset, setReset])
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<DateContainer
|
|
83
|
+
$isError={isError}
|
|
84
|
+
{...rest['data-tip'] && {'data-tip': rest['data-tip'], 'data-place': rest['data-place'], 'data-type': rest['data-type'] }}
|
|
85
|
+
{...rest['data-qa-id'] && {'data-qa-id': rest['data-qa-id']}}
|
|
86
|
+
>
|
|
87
|
+
{ isIcon && <IconComponent $name='calendar' $width='20px' /> }
|
|
88
|
+
<DatePicker
|
|
89
|
+
selected={_date}
|
|
90
|
+
name={name}
|
|
91
|
+
dateFormat={dateFormat}
|
|
92
|
+
onChange={handleChange}
|
|
93
|
+
showTimeInput={showTimeInput}
|
|
94
|
+
onKeyDown={(e) => e.preventDefault()}
|
|
95
|
+
placeholderText={placeholderText}
|
|
96
|
+
ref={ref as any}
|
|
97
|
+
{...disabled && { disabled: true }}
|
|
98
|
+
{...(portalId && { portalId: portalId })}
|
|
99
|
+
/>
|
|
100
|
+
{(allowEmpty && _date) ? (
|
|
101
|
+
<DateIndicatorContainer onClick={() => handleChange(null)} title='clear'>
|
|
102
|
+
<svg height="20" width="20" viewBox="0 0 20 20" aria-hidden="true" focusable="false"><path d="M14.348 14.849c-0.469 0.469-1.229 0.469-1.697 0l-2.651-3.030-2.651 3.029c-0.469 0.469-1.229 0.469-1.697 0-0.469-0.469-0.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-0.469-0.469-0.469-1.228 0-1.697s1.228-0.469 1.697 0l2.652 3.031 2.651-3.031c0.469-0.469 1.228-0.469 1.697 0s0.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c0.469 0.469 0.469 1.229 0 1.698z"></path></svg>
|
|
103
|
+
</DateIndicatorContainer>
|
|
104
|
+
) : null}
|
|
105
|
+
</DateContainer>
|
|
106
|
+
)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
export default DateRefComponent
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import styled, { css } from 'styled-components';
|
|
2
|
-
import { dropBase } from '../../assets';
|
|
2
|
+
import { dropBase, buttonStyle, buttonActiveStyle } from '../../assets/stylesheets/bases.styles';
|
|
3
3
|
|
|
4
4
|
const DateRangeWrapperStyles = css`
|
|
5
5
|
align-items: center;
|
|
@@ -353,6 +353,15 @@ export const DateContainer = styled.div<{ $isError?: boolean }>`
|
|
|
353
353
|
.react-datepicker-wrapper {
|
|
354
354
|
width: 100%;
|
|
355
355
|
}
|
|
356
|
+
> i {
|
|
357
|
+
position: absolute;
|
|
358
|
+
top: 5px;
|
|
359
|
+
left: 10px;
|
|
360
|
+
z-index: 1;
|
|
361
|
+
& + div > div > input {
|
|
362
|
+
padding-left: 35px !important;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
356
365
|
${getDatePickerContainerModifiedStyled}
|
|
357
366
|
`
|
|
358
367
|
export const DateIndicatorContainer = styled.div`
|
|
@@ -398,4 +407,59 @@ export const DateRangePortalContainer = styled.div`
|
|
|
398
407
|
export const DateRangeIconContainer = styled.div`
|
|
399
408
|
display: flex;
|
|
400
409
|
padding: 0 0 0 12px;
|
|
410
|
+
`
|
|
411
|
+
export const RangeContainer = styled.div<{ $mode?: 'white' }>`
|
|
412
|
+
${buttonStyle}
|
|
413
|
+
border: 0;
|
|
414
|
+
width: 240px;
|
|
415
|
+
&.is-actived {
|
|
416
|
+
${buttonActiveStyle}
|
|
417
|
+
}
|
|
418
|
+
.rc-picker-range {
|
|
419
|
+
width: 100%;
|
|
420
|
+
gap: 6px;
|
|
421
|
+
align-content: center;
|
|
422
|
+
align-items: center;
|
|
423
|
+
padding: 0 22px 0 10px;
|
|
424
|
+
.rc-picker-active-bar {
|
|
425
|
+
background-color: #fc5c64;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
.rc-picker-focused {
|
|
429
|
+
border: none !important;
|
|
430
|
+
}
|
|
431
|
+
.rc-picker-input {
|
|
432
|
+
width: auto;
|
|
433
|
+
input:not(:disabled):not([type=submit]):focus,
|
|
434
|
+
input:not(:disabled):not([type=submit]):active,
|
|
435
|
+
input:not(:disabled):not([type=submit]):active:focus,
|
|
436
|
+
textarea:not(:disabled):not([type=submit]):focus,
|
|
437
|
+
textarea:not(:disabled):not([type=submit]):active,
|
|
438
|
+
textarea:not(:disabled):not([type=submit]):active:focus {
|
|
439
|
+
border: 0;
|
|
440
|
+
}
|
|
441
|
+
input {
|
|
442
|
+
background: transparent;
|
|
443
|
+
border: 0;
|
|
444
|
+
text-align: left;
|
|
445
|
+
padding-left: 0;
|
|
446
|
+
padding-right: 0;
|
|
447
|
+
&::placeholder {
|
|
448
|
+
font-style: normal;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
.rc-picker-cell-in-range > .rc-picker-cell-inner {
|
|
453
|
+
background-color: rgba(#fc5c64, .75);
|
|
454
|
+
}
|
|
455
|
+
.rc-picker-input-active > input {
|
|
456
|
+
background: rgba(#fc5c64, 0.05);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
${({ $mode }) => $mode === 'white' && css`
|
|
461
|
+
background-color: var(--pri-clr-bg);
|
|
462
|
+
border: 1px solid var(--ck-clr-ln);
|
|
463
|
+
border-radius: var(--ter-rd);
|
|
464
|
+
`}
|
|
401
465
|
`
|
package/src/components/index.ts
CHANGED
|
@@ -14,6 +14,8 @@ export { default as PopupComponent } from './popup';
|
|
|
14
14
|
export { default as ImageComponent } from './image';
|
|
15
15
|
export { default as ImageChannelComponent } from './image/channel';
|
|
16
16
|
export { default as SelectComponent } from './select';
|
|
17
|
+
export { default as SelectAllComponent } from './select/all';
|
|
18
|
+
export { default as SelectAsyncPaginateComponent } from './select/asyncPaginate';
|
|
17
19
|
export { default as MenuList } from './select/menulist';
|
|
18
20
|
export { default as ErrorComponent } from './error';
|
|
19
21
|
export { default as UploadComponent } from './upload';
|
|
@@ -21,16 +23,23 @@ export { default as UploadDragDropComponent } from './upload/drag.drop';
|
|
|
21
23
|
export { default as TextAreaComponent } from './textarea';
|
|
22
24
|
export { default as TextAreaRefComponent } from './textarea/ref';
|
|
23
25
|
export { default as DateComponent } from './date';
|
|
26
|
+
export { default as DateRangeComponent } from './date/range';
|
|
27
|
+
export { default as DateRefComponent } from './date/ref';
|
|
24
28
|
export { default as DateTimeComponent } from './datetime';
|
|
25
29
|
export { default as RadioComponent } from './radio';
|
|
26
30
|
export { default as SwitchComponent } from './switch';
|
|
27
31
|
export { default as ListComponent } from './list';
|
|
32
|
+
export { default as DropDownComponent } from './dropdown';
|
|
33
|
+
export { default as ReactPortalComponent } from './portal';
|
|
34
|
+
export { default as EmojiComponent } from './emoji';
|
|
35
|
+
export { default as TableComponent } from './table';
|
|
28
36
|
|
|
29
37
|
export * from './message/typed';
|
|
30
38
|
export * from './popup/typed';
|
|
31
39
|
export * from './select/typed';
|
|
32
40
|
export * from './link/typed';
|
|
33
41
|
export * from './dropdown/typed';
|
|
42
|
+
export * from './date/typed';
|
|
34
43
|
|
|
35
44
|
export * from './select/components';
|
|
36
45
|
export * from './form/styles';
|
|
@@ -13,7 +13,7 @@ type TSelect = {
|
|
|
13
13
|
evChange: (newValue: any[], actionMeta: ActionMeta<any>) => void
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const SelectAllComponent = (props: TSelect) => {
|
|
17
17
|
const {
|
|
18
18
|
isError=false,
|
|
19
19
|
value,
|
|
@@ -186,4 +186,4 @@ const SelectAll = (props: TSelect) => {
|
|
|
186
186
|
)
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
export default
|
|
189
|
+
export default SelectAllComponent
|