forstok-ui-lib 7.1.0 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forstok-ui-lib",
3
- "version": "7.1.0",
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.0.0",
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: ['react', 'react-dom', 'react-router-dom', 'styled-components', '@wojtekmaj/react-daterange-picker', 'approvejs', 'html-to-text', 'moment', 'moment-range', 'react-datepicker', 'react-select', 'use-state-with-callback', 'frimousse'],
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
  `
@@ -0,0 +1,3 @@
1
+ import { TMoment } from '../../typeds/base.typed';
2
+
3
+ export type TModerateDateAntFunction = (startDateObj: TMoment, endDateObj: TMoment, callback?: () => void) => void
@@ -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,6 +23,8 @@ 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';
@@ -28,12 +32,14 @@ export { default as ListComponent } from './list';
28
32
  export { default as DropDownComponent } from './dropdown';
29
33
  export { default as ReactPortalComponent } from './portal';
30
34
  export { default as EmojiComponent } from './emoji';
35
+ export { default as TableComponent } from './table';
31
36
 
32
37
  export * from './message/typed';
33
38
  export * from './popup/typed';
34
39
  export * from './select/typed';
35
40
  export * from './link/typed';
36
41
  export * from './dropdown/typed';
42
+ export * from './date/typed';
37
43
 
38
44
  export * from './select/components';
39
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 SelectAll = (props: TSelect) => {
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 SelectAll
189
+ export default SelectAllComponent