@innovaccer/design-system 2.12.0-0 → 2.13.1-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.
Files changed (66) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/core/components/atoms/metricInput/__stories__/DefaultMetric.story.jsx +1 -1
  3. package/core/components/atoms/popperWrapper/PopperWrapper.tsx +25 -3
  4. package/core/components/molecules/inputMask/InputMask.tsx +26 -10
  5. package/core/components/molecules/modal/__stories__/Scrolling.story.jsx +4 -4
  6. package/core/components/molecules/popover/__stories__/variants/boundaryElement.story.jsx +2 -2
  7. package/core/components/organisms/datePicker/DatePicker.tsx +2 -2
  8. package/core/components/organisms/datePicker/Trigger.tsx +17 -4
  9. package/core/components/organisms/datePicker/__tests__/DatePicker.test.tsx +7 -39
  10. package/core/components/organisms/dateRangePicker/SingleInputTrigger.tsx +22 -1
  11. package/core/components/organisms/dateRangePicker/Trigger.tsx +19 -2
  12. package/core/components/organisms/grid/GridBody.tsx +25 -8
  13. package/core/components/organisms/grid/__stories__/variants/loading.story.jsx +2 -2
  14. package/core/components/organisms/grid/__tests__/__snapshots__/Grid.test.tsx.snap +109597 -1053
  15. package/core/components/organisms/table/__tests__/__snapshots__/Table.test.tsx.snap +6476 -1020
  16. package/core/components/organisms/timePicker/TimePicker.tsx +1 -0
  17. package/core/components/organisms/timePicker/__tests__/TimePicker.test.tsx +20 -0
  18. package/core/utils/masks.ts +3 -3
  19. package/css/dist/index.css +26 -26
  20. package/css/dist/index.css.map +1 -1
  21. package/css/src/components/modal.css +6 -6
  22. package/css/src/components/tooltip.css +8 -8
  23. package/dist/core/components/atoms/popperWrapper/PopperWrapper.d.ts +1 -0
  24. package/dist/core/components/organisms/datePicker/DatePicker.d.ts +1 -1
  25. package/dist/index.esm.js +149 -38
  26. package/dist/index.js +139 -27
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.umd.js +1 -1
  29. package/dist/index.umd.js.br +0 -0
  30. package/dist/index.umd.js.gz +0 -0
  31. package/docs/package.json +1 -1
  32. package/docs/src/data/components/images/Helptext2.png +0 -0
  33. package/docs/src/data/components/index.js +12 -0
  34. package/docs/src/data/components/mobile.js +2 -2
  35. package/docs/src/data/nav/components.yaml +4 -0
  36. package/docs/src/pages/components/chips/images/chips-1.png +0 -0
  37. package/docs/src/pages/components/chips/usage.mdx +7 -1
  38. package/docs/src/pages/components/helpText/images/helpText-1.png +0 -0
  39. package/docs/src/pages/components/helpText/images/helpText-2.png +0 -0
  40. package/docs/src/pages/components/helpText/images/helpText-3.png +0 -0
  41. package/docs/src/pages/components/helpText/images/helpText-4.png +0 -0
  42. package/docs/src/pages/components/helpText/images/helpText-5.png +0 -0
  43. package/docs/src/pages/components/helpText/usage.mdx +74 -0
  44. package/docs/src/pages/components/pills/images/pills-1.png +0 -0
  45. package/docs/src/pages/components/pills/usage.mdx +7 -1
  46. package/docs/src/pages/components/radio/images/radio-1.png +0 -0
  47. package/docs/src/pages/components/radio/usage.mdx +7 -1
  48. package/docs/src/pages/components/switch/images/switch-4.png +0 -0
  49. package/docs/src/pages/components/switch/images/switch-5.png +0 -0
  50. package/docs/src/pages/components/switch/images/switch-6.png +0 -0
  51. package/docs/src/pages/components/switch/usage.mdx +10 -3
  52. package/docs/src/pages/mobile/components/bottomSheet/images/bottomsheet-8.png +0 -0
  53. package/docs/src/pages/mobile/components/bottomSheet/usage.mdx +4 -1
  54. package/docs/src/pages/mobile/components/checkbox/images/checkbox-1.png +0 -0
  55. package/docs/src/pages/mobile/components/checkbox/images/checkbox-10.png +0 -0
  56. package/docs/src/pages/mobile/components/checkbox/images/checkbox-11.png +0 -0
  57. package/docs/src/pages/mobile/components/checkbox/images/checkbox-2.png +0 -0
  58. package/docs/src/pages/mobile/components/checkbox/images/checkbox-3.png +0 -0
  59. package/docs/src/pages/mobile/components/checkbox/images/checkbox-4.png +0 -0
  60. package/docs/src/pages/mobile/components/checkbox/images/checkbox-5.png +0 -0
  61. package/docs/src/pages/mobile/components/checkbox/images/checkbox-6.png +0 -0
  62. package/docs/src/pages/mobile/components/checkbox/images/checkbox-7.png +0 -0
  63. package/docs/src/pages/mobile/components/checkbox/images/checkbox-8.png +0 -0
  64. package/docs/src/pages/mobile/components/checkbox/images/checkbox-9.png +0 -0
  65. package/docs/src/pages/mobile/components/checkbox/usage.mdx +122 -0
  66. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,4 +1,82 @@
1
1
 
2
+ ## 2.13.0 (2022-06-21)
3
+
4
+ ### Highlights
5
+ NA
6
+
7
+ ### Breaking changes
8
+ NA
9
+
10
+ ### Migration guide
11
+ NA
12
+
13
+ ### Deprecations
14
+ NA
15
+
16
+ ### Features
17
+ NA
18
+
19
+ ### Fixes
20
+ * fix(timepicker): fix placeholder value getting disappear (1ac69560)
21
+ * fix(modal): fix modal closing animation (d0236cfe)
22
+ * fix(popover): fix popover animation flickering issue (3c01529b)
23
+ * fix(inputMask): fix cursor position on input mask (cbd7f31a)
24
+ * fix(grid): fix grid loading state (aa3672bb)
25
+ * fix(grid): fix loading state in grid (0a8719d5)
26
+ * fix(datepicker): reset to default on blur state (d5565fd2)
27
+ * fix(docs): remove checkbox from mobile nav (3d4aa0f1)
28
+ * fix(datePicker): fix event handlers for datepicker (f79e3c29)
29
+ * fix(docs): fix links on mobile overview page (17e621ba)
30
+ * fix(docs): add missing images (17483411)
31
+
32
+ ### Improvements
33
+ NA
34
+
35
+ ### Documentation
36
+ * docs(docs): add checkbox in mobile (929861d6)
37
+ * docs(docs): add help text in web components (c5e9fd8a)
38
+
39
+ -------------------
40
+
41
+ ## 2.13.0-0 (2022-06-20)
42
+
43
+ ### Highlights
44
+ NA
45
+
46
+ ### Breaking changes
47
+ NA
48
+
49
+ ### Migration guide
50
+ NA
51
+
52
+ ### Deprecations
53
+ NA
54
+
55
+ ### Features
56
+ NA
57
+
58
+ ### Fixes
59
+ * fix(timepicker): fix placeholder value getting disappear (1ac69560)
60
+ * fix(modal): fix modal closing animation (d0236cfe)
61
+ * fix(popover): fix popover animation flickering issue (3c01529b)
62
+ * fix(inputMask): fix cursor position on input mask (cbd7f31a)
63
+ * fix(grid): fix grid loading state (aa3672bb)
64
+ * fix(grid): fix loading state in grid (0a8719d5)
65
+ * fix(datepicker): reset to default on blur state (d5565fd2)
66
+ * fix(docs): remove checkbox from mobile nav (3d4aa0f1)
67
+ * fix(datePicker): fix event handlers for datepicker (f79e3c29)
68
+ * fix(docs): fix links on mobile overview page (17e621ba)
69
+ * fix(docs): add missing images (17483411)
70
+
71
+ ### Improvements
72
+ NA
73
+
74
+ ### Documentation
75
+ * docs(docs): add checkbox in mobile (929861d6)
76
+ * docs(docs): add help text in web components (c5e9fd8a)
77
+
78
+ -------------------
79
+
2
80
  ## 2.10.0-0 (2022-03-30)
3
81
 
4
82
  ### Highlights
@@ -30,7 +30,7 @@ const customCode = `() => {
30
30
 
31
31
  return (
32
32
  <div className="d-flex align-items-center">
33
- <Label htmlFor="metric-input" className="mr-5">
33
+ <Label htmlFor="metric-input" className="mr-5"> No. of Days </Label>
34
34
  <div style={{ width: 'var(--spacing-6)' }}>
35
35
  <MetricInput
36
36
  id="metric-input"
@@ -102,6 +102,7 @@ interface PopperWrapperState {
102
102
  animationKeyframe: string;
103
103
  isOpen: boolean;
104
104
  uniqueKey: string;
105
+ showClosingAnimation: boolean;
105
106
  }
106
107
 
107
108
  export class PopperWrapper extends React.Component<PopperWrapperProps, PopperWrapperState> {
@@ -124,7 +125,12 @@ export class PopperWrapper extends React.Component<PopperWrapperProps, PopperWra
124
125
  constructor(props: PopperWrapperProps) {
125
126
  super(props);
126
127
 
127
- this.state = { animationKeyframe: '', isOpen: this.props.open || false, uniqueKey: '' };
128
+ this.state = {
129
+ animationKeyframe: '',
130
+ isOpen: this.props.open || false,
131
+ uniqueKey: '',
132
+ showClosingAnimation: false,
133
+ };
128
134
 
129
135
  this.hoverableDelay = 100;
130
136
  this.offsetMapping = {
@@ -213,6 +219,9 @@ export class PopperWrapper extends React.Component<PopperWrapperProps, PopperWra
213
219
  const { onToggle } = this.props;
214
220
 
215
221
  onToggle(true, 'mouseEnter');
222
+ this.setState(() => {
223
+ return { isOpen: true };
224
+ });
216
225
  }
217
226
  }
218
227
 
@@ -224,6 +233,19 @@ export class PopperWrapper extends React.Component<PopperWrapperProps, PopperWra
224
233
  this.mouseMoveHandler();
225
234
  } else {
226
235
  onToggle(false, 'mouseLeave');
236
+ this.setState(
237
+ {
238
+ showClosingAnimation: true,
239
+ },
240
+ () => {
241
+ window.setTimeout(() => {
242
+ this.setState({
243
+ showClosingAnimation: false,
244
+ isOpen: false,
245
+ });
246
+ }, 120);
247
+ }
248
+ );
227
249
  }
228
250
  }
229
251
  }
@@ -370,8 +392,8 @@ export class PopperWrapper extends React.Component<PopperWrapperProps, PopperWra
370
392
  } else {
371
393
  classes = classNames(
372
394
  {
373
- [`${animationClass.open}`]: open,
374
- [`${animationClass.close}`]: !open,
395
+ [`${animationClass.open}`]: this.state.isOpen,
396
+ [`${animationClass.close}`]: this.state.showClosingAnimation,
375
397
  },
376
398
  children.props.className
377
399
  );
@@ -79,6 +79,7 @@ const InputMask = React.forwardRef<HTMLInputElement, InputMaskProps>((props, for
79
79
  onFocus,
80
80
  onClear,
81
81
  className,
82
+ id,
82
83
  ...rest
83
84
  } = props;
84
85
 
@@ -216,16 +217,18 @@ const InputMask = React.forwardRef<HTMLInputElement, InputMaskProps>((props, for
216
217
 
217
218
  enteredVal = inputVal.slice(start, end);
218
219
  updatedVal = insertAtIndex(enteredVal, start);
220
+ let oldValue = value;
221
+ if (oldValue.length === 0 && id === 'parent-TimePicker') {
222
+ oldValue = defaultPlaceholderValue;
223
+ }
219
224
  insertedStringLength = updatedVal.length;
220
225
  if (currSelection.end > selectionPos.current.end) {
221
226
  removedLength = insertedStringLength ? getSelectionLength(selectionPos.current) : 0;
222
- } else if (inputVal.length < value.length) {
223
- removedLength = value.length - inputVal.length;
227
+ } else if (inputVal.length < oldValue.length) {
228
+ removedLength = oldValue.length - inputVal.length;
224
229
  }
225
230
 
226
- cursorPosition += insertedStringLength;
227
-
228
- const maskedVal = value.split('');
231
+ const maskedVal = oldValue.split('');
229
232
  for (let i = 0; i < insertedStringLength; i++) {
230
233
  maskedVal[start + i] = updatedVal[i];
231
234
  }
@@ -234,6 +237,16 @@ const InputMask = React.forwardRef<HTMLInputElement, InputMaskProps>((props, for
234
237
  maskedVal[index] = getPlaceholderValue(index, index);
235
238
  }
236
239
 
240
+ const enteredValue = maskedVal.slice(0, mask.length).join('');
241
+ if (
242
+ updatedVal !== placeholderChar &&
243
+ updatedVal !== '' &&
244
+ !updatedVal.includes(placeholderChar) &&
245
+ Utils.validators.isValid(validators, enteredValue)
246
+ ) {
247
+ cursorPosition += insertedStringLength;
248
+ }
249
+
237
250
  const newCursorPosition = getNewCursorPosition(removedLength ? 'left' : 'right', cursorPosition);
238
251
  if (removedLength === 1 && !updatedVal.length && !isEditable(cursorPosition) && newCursorPosition > 0) {
239
252
  cursorPosition = newCursorPosition;
@@ -245,10 +258,14 @@ const InputMask = React.forwardRef<HTMLInputElement, InputMaskProps>((props, for
245
258
 
246
259
  const newValue = maskedVal.slice(0, mask.length).join('');
247
260
  newSelectionPos.current = cursorPosition;
248
-
249
- if (newValue !== value && Utils.validators.isValid(validators, newValue)) {
250
- setValue(newValue);
251
- onChange?.(e, newValue);
261
+ if (newValue !== oldValue && Utils.validators.isValid(validators, newValue)) {
262
+ if (defaultPlaceholderValue === '__:__ _M') {
263
+ setValue(newValue.toUpperCase());
264
+ onChange?.(e, newValue.toUpperCase());
265
+ } else {
266
+ setValue(newValue);
267
+ onChange?.(e, newValue);
268
+ }
252
269
  } else {
253
270
  window.requestAnimationFrame(() => setCursorPosition(newSelectionPos.current));
254
271
  }
@@ -271,7 +288,6 @@ const InputMask = React.forwardRef<HTMLInputElement, InputMaskProps>((props, for
271
288
  const onBlurHandler = React.useCallback(
272
289
  (e: React.ChangeEvent<HTMLInputElement>) => {
273
290
  let inputVal = e.currentTarget.value;
274
-
275
291
  if (clearOnEmptyBlur) {
276
292
  if (inputVal === defaultPlaceholderValue) {
277
293
  setValue('');
@@ -88,8 +88,8 @@ export const scrolling = () => {
88
88
  }}
89
89
  footer={
90
90
  <>
91
- <Button onClick={action('Cancel button click')}>Cancel</Button>
92
- <Button appearance="primary" className="ml-4" onClick={action('Next button click')}>
91
+ <Button onClick={() => action('Cancel button click')}>Cancel</Button>
92
+ <Button appearance="primary" className="ml-4" onClick={() => action('Next button click')}>
93
93
  Next
94
94
  </Button>
95
95
  </>
@@ -162,8 +162,8 @@ const customCode = `() => {
162
162
  }}
163
163
  footer={(
164
164
  <>
165
- <Button onClick={console.log('Cancel button click')}>Cancel</Button>
166
- <Button appearance="primary" className="ml-4" onClick={console.log('Next button click')}>Next</Button>
165
+ <Button onClick={() => console.log('Cancel button click')}>Cancel</Button>
166
+ <Button appearance="primary" className="ml-4" onClick={() => console.log('Next button click')}>Next</Button>
167
167
  </>
168
168
  )}
169
169
  seperator={true}
@@ -38,8 +38,8 @@ export const boundaryElement = () => {
38
38
  const ref = React.useRef<HTMLDivElement>(null);
39
39
 
40
40
  return (
41
- <div ref={ref} style={{ height: 150, border: '1px dashed', padding: 20, overflow: 'auto' }}>
42
- <Popover {...options} boundaryElement={ref}>
41
+ <div ref={ref.current} style={{ height: 150, border: '1px dashed', padding: 20, overflow: 'auto' }}>
42
+ <Popover {...options} boundaryElement={ref.current}>
43
43
  <div style={{ width: 100 }} className="mx-6 my-6">
44
44
  <Text>Popup</Text>
45
45
  <Button className="mt-4" appearance="primary" onClick={action('button clicked inside popover')}>
@@ -47,7 +47,7 @@ export type DatePickerProps = SharedProps & {
47
47
  /**
48
48
  * Props to be used for `InputMask`
49
49
  */
50
- inputOptions: Omit<InputMaskProps, 'mask' | 'value' | 'onChange' | 'onBlur' | 'onClear'>;
50
+ inputOptions: Omit<InputMaskProps, 'mask' | 'value'>;
51
51
  /**
52
52
  * custom Validator for `DatePicker`
53
53
  *
@@ -146,7 +146,7 @@ export class DatePicker extends React.Component<DatePickerProps, DatePickerState
146
146
  const { year: daYear, month: daMonth, date: daDate } = getDateInfo(disabledAfter);
147
147
 
148
148
  return !date
149
- ? true
149
+ ? false
150
150
  : compareDate(date, 'less', dbYear, dbMonth, dbDate) || compareDate(date, 'more', daYear, daMonth, daDate);
151
151
  };
152
152
 
@@ -19,6 +19,7 @@ export const Trigger = (props: TriggerProps) => {
19
19
  const { placeholderChar = '_' } = inputOptions;
20
20
 
21
21
  const onChangeHandler = (_e: React.ChangeEvent<HTMLInputElement>, val?: string) => {
22
+ const { onChange } = inputOptions;
22
23
  setState({
23
24
  open: true,
24
25
  });
@@ -27,23 +28,35 @@ export const Trigger = (props: TriggerProps) => {
27
28
  const d = translateToDate(inputFormat, val, validators);
28
29
  setState({ date: d });
29
30
  }
31
+
32
+ if (onChange) onChange(_e);
30
33
  };
31
34
 
32
35
  const onBlurHandler = (_e: React.ChangeEvent<HTMLInputElement>, val?: string) => {
36
+ const { onBlur } = inputOptions;
33
37
  setState({
34
38
  init: true,
35
39
  });
36
40
 
37
- if (!val || val.includes(placeholderChar)) {
38
- setState({ date: undefined });
41
+ const hasNumber = /\d/;
42
+
43
+ if (val && hasNumber.test(val) && val.includes(placeholderChar)) {
44
+ setState({ error: true });
45
+ } else if ((val && !hasNumber.test(val)) || !val) {
46
+ setState({ error: false });
39
47
  }
48
+
49
+ if (onBlur) onBlur(_e, val || '');
40
50
  };
41
51
 
42
- const onClearHandler = () => {
52
+ const onClearHandler = (e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => {
53
+ const { onClear } = inputOptions;
43
54
  setState({
44
55
  init: true,
45
56
  date: undefined,
46
57
  });
58
+
59
+ if (onClear) onClear(e);
47
60
  };
48
61
 
49
62
  const showError = inputOptions.error || (inputOptions.required && error && init);
@@ -68,7 +81,7 @@ export const Trigger = (props: TriggerProps) => {
68
81
  onClear={onClearHandler}
69
82
  caption={showError ? errorMessage : ''}
70
83
  validators={[inputValidator]}
71
- clearOnEmptyBlur={false}
84
+ clearOnEmptyBlur={true}
72
85
  />
73
86
  );
74
87
  };
@@ -112,42 +112,6 @@ describe('renders DatePicker component Event Handlers ', () => {
112
112
  expect(getByTestId('DesignSystem-Popover')).toBeInTheDocument();
113
113
  });
114
114
 
115
- it('checks onCancel Event in case of required:true', () => {
116
- const { getByTestId, getAllByTestId } = render(
117
- <DatePicker
118
- onDateChange={FunctionValue}
119
- withInput={true}
120
- date={newDate}
121
- inputOptions={{
122
- required: true,
123
- }}
124
- />
125
- );
126
- const closeIcon = getByTestId('DesignSystem-Input--closeIcon');
127
- expect(closeIcon).toBeInTheDocument();
128
- fireEvent.click(closeIcon);
129
- expect(getByTestId('DesignSystem-Caption')).toBeInTheDocument();
130
- expect(getAllByTestId('DesignSystem-Text')[0]).toHaveTextContent('Invalid value');
131
- });
132
-
133
- it('checks for custom caption onCancel Event', () => {
134
- const { getByTestId, getAllByTestId } = render(
135
- <DatePicker
136
- onDateChange={FunctionValue}
137
- withInput={true}
138
- date={newDate}
139
- inputOptions={{
140
- required: true,
141
- caption: 'Invalid Date Entered',
142
- }}
143
- />
144
- );
145
- const closeIcon = getByTestId('DesignSystem-Input--closeIcon');
146
- fireEvent.click(closeIcon);
147
- expect(getByTestId('DesignSystem-Caption')).toBeInTheDocument();
148
- expect(getAllByTestId('DesignSystem-Text')[0]).toHaveTextContent('Invalid Date Entered');
149
- });
150
-
151
115
  it('checks for custom placeholderChar option onClose Event', () => {
152
116
  const { getByTestId } = render(
153
117
  <DatePicker
@@ -166,11 +130,15 @@ describe('renders DatePicker component Event Handlers ', () => {
166
130
  });
167
131
 
168
132
  it('checks onBlur Event', () => {
169
- const { getByTestId } = render(<DatePicker onDateChange={FunctionValue} withInput={true} date={newDate} />);
170
- const closeIcon = getByTestId('DesignSystem-Input--closeIcon');
133
+ const { getByTestId } = render(<DatePicker onDateChange={FunctionValue} withInput={true} />);
171
134
  const input = getByTestId('DesignSystem-Input');
172
- fireEvent.click(closeIcon);
173
135
  fireEvent.blur(input);
174
136
  expect(input).toHaveValue('__/__/____');
175
137
  });
138
+ it('checks onFocus Event', () => {
139
+ const { getByTestId } = render(<DatePicker onDateChange={FunctionValue} withInput={true} />);
140
+ const input = getByTestId('DesignSystem-Input');
141
+ fireEvent.focus(input);
142
+ expect(input).toHaveValue('__/__/____');
143
+ });
176
144
  });
@@ -76,6 +76,20 @@ export const SingleInputTrigger = (props: TriggerProps) => {
76
76
  });
77
77
  };
78
78
 
79
+ const getErrorState = (currentVal: string, siblingVal: string) => {
80
+ const hasNumber = /\d/;
81
+
82
+ if (currentVal && siblingVal && !currentVal.includes(placeholderChar) && siblingVal.includes(placeholderChar)) {
83
+ return true;
84
+ } else if (currentVal && hasNumber.test(currentVal) && currentVal.includes(placeholderChar)) {
85
+ return true;
86
+ } else if ((currentVal && !hasNumber.test(currentVal)) || !currentVal) {
87
+ return false;
88
+ }
89
+
90
+ return null;
91
+ };
92
+
79
93
  const onBlurHandler = (_e: React.ChangeEvent<HTMLInputElement>, val: string) => {
80
94
  setState({
81
95
  init: true,
@@ -85,6 +99,13 @@ export const SingleInputTrigger = (props: TriggerProps) => {
85
99
  const startVal = date[0];
86
100
  const endVal = date[1];
87
101
 
102
+ const startErr = getErrorState(startVal, endVal);
103
+ const endErr = getErrorState(endVal, startVal);
104
+
105
+ if (startErr !== null && endErr !== null) {
106
+ setState({ startError: startErr, endError: endErr });
107
+ }
108
+
88
109
  if (!startVal || startVal.includes(placeholderChar)) setState({ startDate: undefined });
89
110
  if (!endVal || endVal.includes(placeholderChar)) setState({ endDate: undefined });
90
111
  };
@@ -123,7 +144,7 @@ export const SingleInputTrigger = (props: TriggerProps) => {
123
144
  error={showError}
124
145
  caption={showError ? errorMessage : ''}
125
146
  validators={[inputValidator]}
126
- clearOnEmptyBlur={false}
147
+ clearOnEmptyBlur={true}
127
148
  />
128
149
  </Column>
129
150
  </Row>
@@ -66,12 +66,29 @@ export const Trigger = (props: TriggerProps) => {
66
66
  setState({
67
67
  init: true,
68
68
  });
69
+ const hasNumber = /\d/;
70
+
69
71
  if (type === 'start') {
70
72
  const { placeholderChar = '_' } = startInputOptions;
73
+
74
+ if (val && hasNumber.test(val) && val.includes(placeholderChar)) {
75
+ setState({ startError: true });
76
+ } else if ((val && !hasNumber.test(val)) || !val) {
77
+ setState({ startError: false });
78
+ }
79
+
71
80
  if (!val || val.includes(placeholderChar)) setState({ startDate: undefined });
72
81
  }
82
+
73
83
  if (type === 'end') {
74
84
  const { placeholderChar = '_' } = endInputOptions;
85
+
86
+ if (val && hasNumber.test(val) && val.includes(placeholderChar)) {
87
+ setState({ endError: true });
88
+ } else if ((val && !hasNumber.test(val)) || !val) {
89
+ setState({ endError: false });
90
+ }
91
+
75
92
  if (!val || val.includes(placeholderChar)) setState({ endDate: undefined });
76
93
  }
77
94
  };
@@ -145,7 +162,7 @@ export const Trigger = (props: TriggerProps) => {
145
162
  error={showStartError}
146
163
  caption={showStartError ? startErrorMessage : ''}
147
164
  validators={[inputValidator]}
148
- clearOnEmptyBlur={false}
165
+ clearOnEmptyBlur={true}
149
166
  />
150
167
  </Column>
151
168
  <Column size={'6'} sizeXS={'12'} className="DateRangePicker-input DateRangePicker-input--endDate">
@@ -177,7 +194,7 @@ export const Trigger = (props: TriggerProps) => {
177
194
  error={showEndError}
178
195
  caption={showEndError ? endErrorMessage : ''}
179
196
  validators={[inputValidator]}
180
- clearOnEmptyBlur={false}
197
+ clearOnEmptyBlur={true}
181
198
  />
182
199
  </Column>
183
200
  </Row>
@@ -1,6 +1,8 @@
1
1
  import * as React from 'react';
2
+ // import VirtualScroll from 'react-dynamic-virtual-scroll';
2
3
  import { GridRow } from './GridRow';
3
4
  import { GridState, onSelectFn, Schema, updatePrevPageInfoFunction } from './Grid';
5
+ // import { GridProps } from '@/index.type';
4
6
  import GridContext from './GridContext';
5
7
 
6
8
  export interface GridBodyProps {
@@ -13,7 +15,7 @@ export interface GridBodyProps {
13
15
  export const GridBody = (props: GridBodyProps) => {
14
16
  const context = React.useContext(GridContext);
15
17
 
16
- const { data, ref, loading, error, page, errorTemplate } = context;
18
+ const { data, ref, loading, error, withPagination, page, pageSize, totalRecords, errorTemplate } = context;
17
19
 
18
20
  if (!loading && error) {
19
21
  return errorTemplate ? (typeof errorTemplate === 'function' ? errorTemplate({}) : errorTemplate) : null;
@@ -38,6 +40,16 @@ export const GridBody = (props: GridBodyProps) => {
38
40
  };
39
41
  }, []);
40
42
 
43
+ const totalPages = Math.ceil(totalRecords / pageSize);
44
+ const isLastPage = withPagination && page === totalPages;
45
+ const dataLength = isLastPage
46
+ ? totalRecords - (page - 1) * pageSize
47
+ : loading
48
+ ? pageSize
49
+ : withPagination
50
+ ? Math.min(totalRecords, pageSize)
51
+ : totalRecords;
52
+
41
53
  const renderRow = (rowIndex: number, item: object) => {
42
54
  return (
43
55
  <GridRow
@@ -50,14 +62,19 @@ export const GridBody = (props: GridBodyProps) => {
50
62
  );
51
63
  };
52
64
 
65
+ const getArrayList = () => {
66
+ if (loading && !data.length) {
67
+ return [...Array(dataLength).map((x) => x)];
68
+ }
69
+ return data;
70
+ };
71
+
53
72
  return (
54
- <>
55
- <div className="Grid-body">
56
- {data.map((item, i) => {
57
- return renderRow(i, item);
58
- })}
59
- </div>
60
- </>
73
+ <div className="Grid-body">
74
+ {getArrayList().map((item, i) => {
75
+ return renderRow(i, item);
76
+ })}
77
+ </div>
61
78
  );
62
79
  };
63
80
 
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Grid } from '@/index';
3
3
 
4
- export const loading = () => {
4
+ export const GridLoadingState = () => {
5
5
  const schema = [
6
6
  {
7
7
  name: 'name',
@@ -44,7 +44,7 @@ const customCode = `() => {
44
44
  `;
45
45
 
46
46
  export default {
47
- title: 'Components/Grid/Variants/Loading',
47
+ title: 'Components/Grid/Variants/Grid Loading State',
48
48
  parameters: {
49
49
  docs: {
50
50
  docPage: {