forstok-ui-lib 6.18.3 → 6.19.0

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": "6.18.3",
3
+ "version": "6.19.0",
4
4
  "description": "Forstok UI Components Library",
5
5
  "path": "dist",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,189 @@
1
+ import { useRef } from 'react'
2
+ import ReactSelect, { ActionMeta, MultiValue, CSSObjectWithLabel, ControlProps, GroupBase } from 'react-select'
3
+ import type { CSSObject } from '@emotion/serialize'
4
+
5
+ import { TOption } from './typed'
6
+
7
+ type TSelect = {
8
+ mode?: string
9
+ isError?: boolean
10
+ 'data-qa-id'?: string
11
+ value: MultiValue<any>
12
+ options: TOption[] | null
13
+ evChange: (newValue: any[], actionMeta: ActionMeta<any>) => void
14
+ }
15
+
16
+ const SelectAll = (props: TSelect) => {
17
+ const {
18
+ isError=false,
19
+ value,
20
+ options,
21
+ mode,
22
+ evChange,
23
+ ...rest
24
+ } = props
25
+
26
+ const valueRef = useRef(value as MultiValue<any> | null)
27
+ valueRef.current = value
28
+
29
+ const placeholder = mode === 'store' ? 'Stores' : 'Categories'
30
+ const selectAllOption = {
31
+ value: "*",
32
+ label: "All "+placeholder
33
+ };
34
+ const isSelectAllSelected = () => valueRef.current?.length === options?.length
35
+ const getOptions = () => options ? [selectAllOption, ...options] : [selectAllOption]
36
+
37
+ const isOptionSelected = (option: { value: string }) => {
38
+ return valueRef.current?.some(({ value }: { value: string }) => value === option.value) || isSelectAllSelected()
39
+ }
40
+
41
+ const getValue = () => (valueRef.current && valueRef.current.length >= 5) ? [{
42
+ value: value,
43
+ label: `${valueRef.current?.length} ${placeholder}`}
44
+ ] : isSelectAllSelected() ? [selectAllOption] : value
45
+
46
+ const handleChange = (newValue: MultiValue<any>, actionMeta: ActionMeta<any>) => {
47
+ if (!options) {
48
+ return false
49
+ }
50
+ const { action, option, removedValue } = actionMeta
51
+ let _newValue = newValue ? [...newValue] : null
52
+ const mergeVal = (newValue && newValue.length && Array.isArray(newValue[0].value)) ? newValue[0].value : null
53
+ let result: any[] = []
54
+ if (action === "select-option" && option.value === selectAllOption.value) {
55
+ result = options
56
+ } else if ((action === "deselect-option" &&
57
+ option.value === selectAllOption.value) ||
58
+ (action === "remove-value" && removedValue.value === selectAllOption.value)) {
59
+ result = []
60
+ } else if (actionMeta.action === "deselect-option" && isSelectAllSelected()) {
61
+ result = options.filter(({ value }: { value: string }) => value !== option.value)
62
+ } else if (actionMeta.action === "remove-value" && mergeVal) {
63
+ valueRef.current = null
64
+ result = []
65
+ } else if (actionMeta.action === "deselect-option") {
66
+ if (mergeVal) {
67
+ _newValue = mergeVal.filter(({ value }: { value: string }) => value !== option.value)
68
+ valueRef.current = _newValue
69
+ } else {
70
+ _newValue = newValue.filter(({ value }: { value: string }) => value !== option.value)
71
+ }
72
+ result = _newValue || []
73
+ } else {
74
+ if (mergeVal) {
75
+ _newValue = [...mergeVal, newValue[1]]
76
+ valueRef.current = _newValue
77
+ }
78
+ result = _newValue || []
79
+ }
80
+ evChange(result, actionMeta)
81
+ }
82
+
83
+ const customStyles = {
84
+ container: (provided: CSSObject) => ({
85
+ ...provided,
86
+ display: 'inline-block',
87
+ minHeight: '1px',
88
+ textAlign: 'left',
89
+ border: 'none',
90
+ } as CSSObjectWithLabel),
91
+ control: (provided: CSSObjectWithLabel, state:ControlProps<{ value: string; }, true, GroupBase<TOption>>) => ({
92
+ ...provided,
93
+ borderRadius: '.5rem',
94
+ cursor: 'pointer',
95
+ minHeight: mode === 'store' ? '30px': '38px',
96
+ borderWidth: isError ? '1px' : '0',
97
+ boxShadow: (state.isFocused) ? '-.0625rem 0rem .0625rem 0rem rgba(26, 26, 26, .122) inset, .0625rem 0rem .0625rem 0rem rgba(26, 26, 26, .122) inset, 0rem .125rem .0625rem 0rem rgba(26, 26, 26, .2) inset' : '0rem -.0625rem 0rem 0rem #b5b5b5 inset,0rem 0rem 0rem .0625rem rgba(0, 0, 0, .1) inset,0rem .03125rem 0rem .09375rem #FFF inset',
98
+ borderColor: ((state.isFocused && mode !== 'filter') && !isError) ? 'var(--pri-clr-ln__fc)' : (isError ? 'var(--err-clr-ln)' : (mode ==='filter' ? '#ffffff' : ' var(--ck-clr-ln)' )),
99
+ background: state.isFocused ? 'rgba(247, 247, 247, 1)' : '#ffffff',
100
+ '&:hover': {
101
+ borderColor: ((state.isFocused && mode !== 'filter') && !isError) ? 'var(--pri-clr-ln__fc)' : (isError ? 'var(--err-clr-ln)' : (mode ==='filter' ? '#ffffff' : ' var(--ck-clr-ln)' )),
102
+ background: 'rgba(250, 250, 250, 1)',
103
+ color: 'rgba(48, 48, 48, 1)'
104
+ }
105
+ } as CSSObjectWithLabel),
106
+ placeholder: (provided: CSSObject) => ({
107
+ ...provided,
108
+ fontStyle: 'italic'
109
+ } as CSSObjectWithLabel),
110
+ input: (provided: CSSObject) => ({
111
+ ...provided,
112
+ minHeight: '1px',
113
+ margin: '0 2px',
114
+ padding: '0',
115
+ 'input': {
116
+ boxShadow: 'none !important'
117
+ }
118
+ } as CSSObjectWithLabel),
119
+ dropdownIndicator: (provided: CSSObject) => ({
120
+ ...provided,
121
+ minHeight: '1px',
122
+ paddingTop: '0',
123
+ paddingBottom: '0',
124
+ paddingLeft: '2px',
125
+ paddingRight: '2px',
126
+ color: '#757575',
127
+ } as CSSObjectWithLabel),
128
+ indicatorSeparator: (provided: CSSObject) => ({
129
+ ...provided,
130
+ minHeight: '1px',
131
+ height: '24px',
132
+ display: 'none'
133
+ } as CSSObjectWithLabel),
134
+ clearIndicator: (provided: CSSObject) => ({
135
+ ...provided,
136
+ minHeight: '1px',
137
+ marginRight: '-6px',
138
+ padding: '0'
139
+ } as CSSObjectWithLabel),
140
+ valueContainer: (provided: CSSObject) => ({
141
+ ...provided,
142
+ height: '30px',
143
+ overflow: 'auto',
144
+ paddingTop: '0',
145
+ paddingBottom: '0',
146
+ paddingRight: '2px',
147
+ } as CSSObjectWithLabel),
148
+ menuPortal: (provided: CSSObject) => ({
149
+ ...provided,
150
+ zIndex: 9999,
151
+ letterSpacing: 'normal',
152
+ lineHeight: 'normal',
153
+ } as CSSObjectWithLabel),
154
+ option: (provided: CSSObject, state: { isSelected: any }) => ({
155
+ ...provided,
156
+ color: state.isSelected ? '#ffffff' : '#000000',
157
+ backgroundColor: state.isSelected ? '#fc5c64' : 'transparent',
158
+ cursor: 'pointer',
159
+ '&:hover': {
160
+ backgroundColor: '#ec5b62',
161
+ color: '#ffffff'
162
+ }
163
+ } as CSSObjectWithLabel),
164
+ menu: (provided: CSSObject) => ({
165
+ ...provided,
166
+ borderRadius: '.75rem',
167
+ boxShadow: '0rem .5rem 1.5rem -.5rem rgba(0, 0, 0, .05), 0rem .5rem 1rem -.25rem rgba(0, 0, 0, .05), 0rem .1875rem .375rem 0rem rgba(0, 0, 0, .05), 0rem .125rem .25rem 0rem rgba(0, 0, 0, .05), 0rem .0625rem .125rem 0rem rgba(0, 0, 0, .05), 0rem 0rem 0rem .0625rem rgba(0, 0, 0, .06)',
168
+ border: 'none'
169
+ } as CSSObjectWithLabel)
170
+ }
171
+
172
+ return (
173
+ <div className='_refContainer' {...rest['data-qa-id'] && {'data-qa-id': rest['data-qa-id']}}>
174
+ <ReactSelect
175
+ isOptionSelected={isOptionSelected}
176
+ styles={customStyles}
177
+ menuPortalTarget={document.body}
178
+ options={getOptions()}
179
+ value={getValue()}
180
+ onChange={handleChange}
181
+ hideSelectedOptions={false}
182
+ closeMenuOnSelect={false}
183
+ isMulti
184
+ />
185
+ </div>
186
+ )
187
+ }
188
+
189
+ export default SelectAll