@codeleap/web 3.18.2 → 3.18.3

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": "@codeleap/web",
3
- "version": "3.18.2",
3
+ "version": "3.18.3",
4
4
  "main": "src/index.ts",
5
5
  "repository": {
6
6
  "url": "https://github.com/codeleap-uk/internal-libs-monorepo.git",
@@ -28,6 +28,7 @@
28
28
  "masonic": "^3.7.0",
29
29
  "rc-slider": "^9.7.5",
30
30
  "react-autosize-textarea": "^7.1.0",
31
+ "react-datepicker": "^4.20.0",
31
32
  "react-circular-progressbar": "^2.1.0",
32
33
  "react-dropzone": "^14.2.3",
33
34
  "react-image-crop": "^10.1.8",
@@ -0,0 +1,87 @@
1
+ import {
2
+ IconPlaceholder,
3
+ TypeGuards,
4
+ getNestedStylesByKey,
5
+ } from '@codeleap/common'
6
+ import { ActionIcon, Text, View } from '../../components'
7
+ import { DatePickerArrowProps, DatePickerHeaderComponent } from '../types'
8
+ import { format, getYear } from 'date-fns'
9
+
10
+ export const ArrowLabel: React.FC<DatePickerArrowProps> = ({
11
+ name,
12
+ direction,
13
+ ...props
14
+ }) => {
15
+ return (
16
+ <ActionIcon
17
+ name={name ?? (`chevron-${direction}` as IconPlaceholder)}
18
+ debugName={'Calendar arrowLabel'}
19
+ {...props}
20
+ />
21
+ )
22
+ }
23
+
24
+ export const Header = (props: DatePickerHeaderComponent) => {
25
+ const {
26
+ date,
27
+ decreaseMonth,
28
+ increaseMonth,
29
+ prevMonthButtonDisabled,
30
+ decreaseYear,
31
+ increaseYear,
32
+ prevYearButtonDisabled,
33
+ nextYearButtonDisabled,
34
+ nextMonthButtonDisabled,
35
+ setYearShow,
36
+ styles,
37
+ formatHeaderTitle,
38
+ } = props
39
+
40
+ const month = format(date, 'MMMM')
41
+ const year = getYear(date)
42
+
43
+ const title = TypeGuards.isFunction(formatHeaderTitle)
44
+ ? formatHeaderTitle(date)
45
+ : `${month} ${year}`
46
+
47
+ const prevArrow = getNestedStylesByKey('prevButton', styles)
48
+ const nextArrow = getNestedStylesByKey('nextButton', styles)
49
+
50
+ return (
51
+ <View style={styles.wrapper}>
52
+ <View style={styles.buttonsWrapper}>
53
+ <ArrowLabel
54
+ direction='left'
55
+ styles={prevArrow}
56
+ onPress={decreaseYear}
57
+ disabled={prevYearButtonDisabled}
58
+ />
59
+ <Text
60
+ onPress={() => setYearShow((curr) => !curr)}
61
+ style={styles.title}
62
+ text={title}
63
+ />
64
+ <ArrowLabel
65
+ direction='right'
66
+ styles={nextArrow}
67
+ onPress={increaseYear}
68
+ disabled={nextYearButtonDisabled}
69
+ />
70
+ </View>
71
+ <View style={styles.buttonsWrapper}>
72
+ <ArrowLabel
73
+ direction='left'
74
+ styles={prevArrow}
75
+ onPress={decreaseMonth}
76
+ disabled={prevMonthButtonDisabled}
77
+ />
78
+ <ArrowLabel
79
+ direction='right'
80
+ styles={nextArrow}
81
+ onPress={increaseMonth}
82
+ disabled={nextMonthButtonDisabled}
83
+ />
84
+ </View>
85
+ </View>
86
+ )
87
+ }
@@ -0,0 +1,28 @@
1
+ import { TextInput } from '../../components'
2
+ import { DatePickerProps } from '../types'
3
+
4
+ export const OuterInput: DatePickerProps['outerInputComponent'] = ({
5
+ valueLabel,
6
+ focused,
7
+ hideInput,
8
+ ...props
9
+ }) => {
10
+ return hideInput ? null : (
11
+ <TextInput
12
+ validate={!focused && props?.validate}
13
+ debugName='DatePicker - OuterInputComponent'
14
+ masking={{
15
+ type: 'custom',
16
+ options: {
17
+ mask: 'xx/xx/xxxx',
18
+ placeholder: props.placeholder,
19
+ formatChars: {
20
+ x: '[0123456789]',
21
+ },
22
+ maskChar: '',
23
+ },
24
+ }}
25
+ {...props}
26
+ />
27
+ )
28
+ }
@@ -0,0 +1,2 @@
1
+ export * from './OuterInput'
2
+ export * from './Header'
@@ -0,0 +1,232 @@
1
+ import {
2
+ TypeGuards,
3
+ getNestedStylesByKey,
4
+ useCallback,
5
+ useDefaultComponentStyle,
6
+ useState,
7
+ } from '@codeleap/common'
8
+ import { Text, View } from '../components'
9
+ import { DatePickerPresets } from './styles'
10
+ import { DatePickerProps, DayComponentProps } from './types'
11
+ import _DatePicker from 'react-datepicker'
12
+ import { Header, OuterInput } from './defaultComponents'
13
+ import { format, isBefore, isAfter } from 'date-fns'
14
+
15
+ export * from './styles'
16
+ export * from './types'
17
+ export * from './defaultComponents'
18
+
19
+ const defaultProps = {
20
+ variants: [],
21
+ styles: {},
22
+ minDate: new Date(1910, 0, 1),
23
+ maxDate: new Date(),
24
+ startDate: new Date(1923, 0, 1),
25
+ outerInputComponent: OuterInput,
26
+ headerComponent: Header,
27
+ }
28
+
29
+ export function DatePicker(props: DatePickerProps) {
30
+ const allProps = {
31
+ ...DatePicker.defaultProps,
32
+ ...props,
33
+ }
34
+
35
+ const {
36
+ hideInput,
37
+ value,
38
+ onValueChange,
39
+ variants,
40
+ styles,
41
+ style,
42
+ responsiveVariants,
43
+ defaultValue,
44
+ outerInputComponent: OuterInputComponent,
45
+ headerComponent: HeaderComponent,
46
+ headerProps: _headerProps,
47
+ dayComponent: DayComponent,
48
+ dayProps,
49
+ yearComponent: YearComponent,
50
+ yearProps,
51
+ datePickerProps,
52
+ minDate,
53
+ maxDate,
54
+ startDate,
55
+ visible: _visible,
56
+ toggle: _toggle,
57
+ yearShow: _yearShow,
58
+ setYearShow: _setYearShow,
59
+ disabled = false,
60
+ ...otherProps
61
+ } = allProps
62
+
63
+ const [visible, toggle] =
64
+ TypeGuards.isBoolean(_visible) && TypeGuards.isFunction(_toggle)
65
+ ? [_visible, _toggle]
66
+ : useState(false)
67
+ const [yearShow, setYearShow] =
68
+ TypeGuards.isBoolean(_yearShow) && TypeGuards.isFunction(_setYearShow)
69
+ ? [_yearShow, _setYearShow]
70
+ : useState(false)
71
+
72
+ const variantStyles = useDefaultComponentStyle<
73
+ 'u:DatePicker',
74
+ typeof DatePickerPresets
75
+ >('u:DatePicker', {
76
+ variants,
77
+ responsiveVariants,
78
+ styles,
79
+ })
80
+
81
+ const DayContentComponent = useCallback(
82
+ (_param: DayComponentProps) => {
83
+ const param = {
84
+ ..._param,
85
+ ...dayProps,
86
+ }
87
+
88
+ const { day, date: _date } = param
89
+
90
+ const date = format(new Date(_date), 'dd MMM yyyy')
91
+ const dateValue = value ? format(new Date(value), 'dd MMM yyyy') : ''
92
+
93
+ const isSelected = date === dateValue
94
+
95
+ const isDisabled = [
96
+ isBefore(_date, minDate),
97
+ isAfter(_date, maxDate),
98
+ ].some(Boolean)
99
+
100
+ const getStyles = (key) => {
101
+ return {
102
+ ...variantStyles[key],
103
+ ...(isSelected && variantStyles[`${key}:selected`]),
104
+ ...(!isSelected && isDisabled && variantStyles[`${key}:disabled`]),
105
+ }
106
+ }
107
+
108
+ if (TypeGuards.isFunction(DayComponent)) {
109
+ return (
110
+ <DayComponent
111
+ {...param}
112
+ value={value}
113
+ disabled={isDisabled}
114
+ selected={isSelected}
115
+ variantStyles={variantStyles}
116
+ />
117
+ )
118
+ }
119
+
120
+ return (
121
+ <View css={getStyles('dayWrapper')}>
122
+ <Text style={getStyles('day')} disabled={isDisabled} text={day} />
123
+ </View>
124
+ )
125
+ },
126
+ [value],
127
+ )
128
+
129
+ const YearContentComponent = useCallback(
130
+ (_param) => {
131
+ const param = {
132
+ ..._param,
133
+ ...yearProps,
134
+ }
135
+
136
+ const { year } = param
137
+
138
+ const isSelected = String(value)?.includes(year)
139
+
140
+ const getStyles = (key) => {
141
+ return {
142
+ ...variantStyles[key],
143
+ ...(isSelected && variantStyles[`${key}:selected`]),
144
+ }
145
+ }
146
+
147
+ if (TypeGuards.isFunction(YearComponent)) {
148
+ return (
149
+ <YearComponent
150
+ {...param}
151
+ value={value}
152
+ selected={isSelected}
153
+ variantStyles={variantStyles}
154
+ />
155
+ )
156
+ }
157
+
158
+ return (
159
+ <View css={getStyles('yearWrapper')}>
160
+ <Text style={getStyles('year')} text={year} />
161
+ </View>
162
+ )
163
+ },
164
+ [value],
165
+ )
166
+
167
+ const inputStyles = getNestedStylesByKey('outerInput', variantStyles)
168
+ const headerStyles = getNestedStylesByKey('header', variantStyles)
169
+
170
+ return (
171
+ <View css={variantStyles.wrapper}>
172
+ <_DatePicker
173
+ onChange={onValueChange}
174
+ open={visible}
175
+ selected={value}
176
+ todayButton={null}
177
+ shouldCloseOnSelect={false}
178
+ openToDate={defaultValue ?? value}
179
+ dateFormat='dd/MM/yyyy'
180
+ formatWeekDay={(t) => t[0]}
181
+ calendarStartDay={1}
182
+ placeholderText={otherProps?.placeholder}
183
+ disabled={disabled}
184
+ renderDayContents={(day, date) => (
185
+ <DayContentComponent day={day} date={date} />
186
+ )}
187
+ customInput={
188
+ <OuterInputComponent
189
+ styles={inputStyles}
190
+ focused={visible}
191
+ hideInput={hideInput}
192
+ {...otherProps}
193
+ />
194
+ }
195
+ renderCustomHeader={(headerProps) => (
196
+ <HeaderComponent
197
+ styles={headerStyles}
198
+ setYearShow={setYearShow}
199
+ prevYearButtonDisabled={yearShow}
200
+ nextYearButtonDisabled={yearShow}
201
+ {...headerProps}
202
+ {..._headerProps}
203
+ />
204
+ )}
205
+ onFocus={() => toggle(true)}
206
+ onSelect={() => (yearShow ? setYearShow(false) : toggle(false))}
207
+ onClickOutside={() => {
208
+ toggle(false)
209
+ setYearShow(false)
210
+ }}
211
+ minDate={minDate}
212
+ maxDate={maxDate}
213
+ endDate={maxDate}
214
+ startDate={startDate}
215
+ onYearChange={() => setYearShow(false)}
216
+ yearItemNumber={maxDate.getFullYear() - minDate.getFullYear()}
217
+ showYearPicker={yearShow}
218
+ renderYearContent={(year) => {
219
+ if (year < startDate.getFullYear() || year > maxDate.getFullYear()) return null
220
+ return <YearContentComponent year={year} />
221
+ }}
222
+ filterDate={(date) => {
223
+ if (date.getFullYear() < startDate.getFullYear() || date.getFullYear() > maxDate.getFullYear()) return false
224
+ return true
225
+ }}
226
+ {...datePickerProps}
227
+ />
228
+ </View>
229
+ )
230
+ }
231
+
232
+ DatePicker.defaultProps = defaultProps
@@ -0,0 +1,34 @@
1
+ import {
2
+ TextInputComposition,
3
+ createDefaultVariantFactory,
4
+ includePresets,
5
+ } from '@codeleap/common'
6
+ import { ActionIconComposition } from '../ActionIcon'
7
+
8
+ export type DatePickerStates = ':selected' | ':disabled' | ''
9
+
10
+ export type DatePickerParts =
11
+ | 'wrapper'
12
+ | `dayWrapper${DatePickerStates}`
13
+ | `day${DatePickerStates}`
14
+ | `yearWrapper${DatePickerStates}`
15
+ | `year${DatePickerStates}`
16
+
17
+ export type DatePickerHeaderComposition =
18
+ | 'wrapper'
19
+ | 'buttonsWrapper'
20
+ | `prevButton${Capitalize<ActionIconComposition>}`
21
+ | `nextButton${Capitalize<ActionIconComposition>}`
22
+ | 'title'
23
+
24
+ export type DatePickerComposition =
25
+ | DatePickerParts
26
+ | `outerInput${Capitalize<TextInputComposition>}`
27
+ | `header${Capitalize<DatePickerHeaderComposition>}`
28
+
29
+ const createDatePickerStyle =
30
+ createDefaultVariantFactory<DatePickerComposition>()
31
+
32
+ export const DatePickerPresets = includePresets(
33
+ (style) => createDatePickerStyle(() => ({ wrapper: style })),
34
+ )
@@ -0,0 +1,78 @@
1
+ import { ComponentVariants, FormTypes, StylesOf } from '@codeleap/common'
2
+ import {
3
+ ReactDatePickerCustomHeaderProps,
4
+ ReactDatePickerProps,
5
+ } from 'react-datepicker'
6
+ import { ActionIconProps, TextInputProps } from '../components'
7
+ import {
8
+ DatePickerComposition,
9
+ DatePickerHeaderComposition,
10
+ DatePickerPresets,
11
+ } from './styles'
12
+
13
+ export type DatePickerOuterInputProps = TextInputProps & {
14
+ valueLabel: FormTypes.Label
15
+ hideInput?: boolean
16
+ }
17
+
18
+ export type DatePickerHeaderComponent = ReactDatePickerCustomHeaderProps & {
19
+ styles?: DatePickerHeaderComposition
20
+ formatHeaderTitle?: (date: Date) => string
21
+ }
22
+
23
+ export type DatePickerArrowProps = Partial<ActionIconProps> & {
24
+ direction: 'left' | 'right'
25
+ }
26
+
27
+ type RootStyles = ComponentVariants<typeof DatePickerPresets>
28
+
29
+ export type DayComponentProps = {
30
+ day: string | number
31
+ value: Date
32
+ date: Date
33
+ disabled: boolean
34
+ selected: boolean
35
+ variantStyles: any
36
+ }
37
+
38
+ export type YearComponentProps = {
39
+ year: string | number
40
+ value: Date
41
+ selected: boolean
42
+ variantStyles: any
43
+ }
44
+
45
+ type RootDatePickerProps = 'startDate' | 'minDate' | 'maxDate'
46
+
47
+ export type DatePickerProps = Partial<
48
+ Pick<Partial<ReactDatePickerProps>, RootDatePickerProps>
49
+ > &
50
+ RootStyles & {
51
+ styles?: StylesOf<DatePickerComposition>
52
+ style?: React.CSSProperties
53
+ hideInput?: boolean
54
+ value: Date
55
+ outerInputComponent?: React.ComponentType<
56
+ Partial<DatePickerOuterInputProps>
57
+ >
58
+ headerComponent?: React.ComponentType<Partial<DatePickerHeaderComponent>>
59
+ headerProps?: Partial<DatePickerHeaderComponent>
60
+ dayComponent?: React.ComponentType<Partial<DayComponentProps>>
61
+ dayProps?: Partial<DayComponentProps>
62
+ yearComponent?: React.ComponentType<Partial<YearComponentProps>>
63
+ yearProps?: Partial<YearComponentProps>
64
+ formatDate?: (date: Date | string) => FormTypes.Label
65
+ datePickerProps?: Omit<
66
+ Partial<ReactDatePickerProps>,
67
+ 'customInput' | 'renderCustomHeader' | RootDatePickerProps
68
+ >
69
+ onValueChange: (date: Date) => void
70
+ defaultValue?: Date
71
+ visible?: boolean
72
+ toggle?: () => void
73
+ yearShow?: boolean
74
+ setYearShow?: () => void
75
+ } & Omit<
76
+ TextInputProps,
77
+ 'defaultValue' | 'styles' | 'variants' | 'responsiveVariants'
78
+ >
@@ -31,6 +31,7 @@ export * from './EmptyPlaceholder'
31
31
  export * from './Grid'
32
32
  export * from './Badge'
33
33
  export * from './CropPicker'
34
+ export * from './DatePicker'
34
35
  export * from './Dropzone'
35
36
  export * from './Progress'
36
37
  export * from './Tag'