@axinom/mosaic-ui 0.29.0 → 0.30.0-rc.2

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 (32) hide show
  1. package/dist/components/Filters/Filter/Filter.d.ts.map +1 -1
  2. package/dist/components/Filters/Filters.model.d.ts +2 -0
  3. package/dist/components/Filters/Filters.model.d.ts.map +1 -1
  4. package/dist/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.d.ts +1 -1
  5. package/dist/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.d.ts.map +1 -1
  6. package/dist/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.d.ts +1 -1
  7. package/dist/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.d.ts.map +1 -1
  8. package/dist/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.d.ts +1 -1
  9. package/dist/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.d.ts.map +1 -1
  10. package/dist/components/Filters/SelectionTypes/SearcheableOptionsFilter/SearcheableOptionsFilter.d.ts.map +1 -1
  11. package/dist/helpers/storybook.d.ts +3 -0
  12. package/dist/helpers/storybook.d.ts.map +1 -1
  13. package/dist/index.es.js +3 -3
  14. package/dist/index.js +3 -3
  15. package/package.json +3 -3
  16. package/src/components/Filters/Filter/Filter.scss +20 -2
  17. package/src/components/Filters/Filter/Filter.spec.tsx +34 -1
  18. package/src/components/Filters/Filter/Filter.tsx +6 -12
  19. package/src/components/Filters/Filters.model.ts +3 -0
  20. package/src/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.scss +10 -2
  21. package/src/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.tsx +15 -17
  22. package/src/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.scss +1 -3
  23. package/src/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.tsx +9 -15
  24. package/src/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.scss +1 -3
  25. package/src/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.tsx +9 -15
  26. package/src/components/Filters/SelectionTypes/OptionsFilter/OptionsFilter.scss +0 -1
  27. package/src/components/Filters/SelectionTypes/SearcheableOptionsFilter/SearcheableOptionsFilter.scss +1 -3
  28. package/src/components/Filters/SelectionTypes/SearcheableOptionsFilter/SearcheableOptionsFilter.tsx +17 -6
  29. package/src/components/FormElements/Checkbox/Checkbox.scss +4 -1
  30. package/src/components/FormElements/TextArea/TextArea.scss +16 -0
  31. package/src/helpers/storybook.tsx +3 -0
  32. package/src/styles/variables.scss +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-ui",
3
- "version": "0.29.0",
3
+ "version": "0.30.0-rc.2",
4
4
  "description": "UI components for building Axinom Mosaic applications",
5
5
  "author": "Axinom",
6
6
  "license": "PROPRIETARY",
@@ -32,7 +32,7 @@
32
32
  "build-storybook": "build-storybook"
33
33
  },
34
34
  "dependencies": {
35
- "@axinom/mosaic-core": "^0.4.2",
35
+ "@axinom/mosaic-core": "^0.4.3-rc.1",
36
36
  "@faker-js/faker": "^7.4.0",
37
37
  "@popperjs/core": "^2.9.2",
38
38
  "clsx": "^1.1.0",
@@ -98,5 +98,5 @@
98
98
  "publishConfig": {
99
99
  "access": "public"
100
100
  },
101
- "gitHead": "539529319d7b39e57fb9832bfd23c07b023a50d0"
101
+ "gitHead": "6ac9f4a4eb6a4b0accaf5cbf645361ce96484e16"
102
102
  }
@@ -1,5 +1,9 @@
1
1
  @import '../../../styles/common.scss';
2
2
 
3
+ $border: 1px solid var(--filter-border-color, $filter-border-color);
4
+ $input-active: 3px solid var(--input-hover-color, $input-hover-color);
5
+ $input-inactive: 1px solid var(--input-border-color, $input-border-color);
6
+
3
7
  .container {
4
8
  @include boxSizing;
5
9
 
@@ -7,6 +11,10 @@
7
11
 
8
12
  cursor: pointer;
9
13
 
14
+ input {
15
+ border: $input-inactive;
16
+ }
17
+
10
18
  .title {
11
19
  display: grid;
12
20
  grid-template-columns: auto auto;
@@ -21,7 +29,7 @@
21
29
  transition: background-color 100ms linear;
22
30
 
23
31
  &:hover {
24
- border: 1px solid var(--input-hover-color, $input-hover-color);
32
+ border: $border;
25
33
  }
26
34
 
27
35
  &.expanded {
@@ -30,7 +38,7 @@
30
38
  $filter-background-selected-color
31
39
  );
32
40
 
33
- border: 1px solid var(--input-hover-color, $input-hover-color);
41
+ border: $border;
34
42
  }
35
43
 
36
44
  &.hasError {
@@ -86,4 +94,14 @@
86
94
  transition: max-height 100ms linear;
87
95
  overflow: hidden;
88
96
  max-height: fit-content !important;
97
+
98
+ .active {
99
+ border-right: $border;
100
+ border-bottom: $border;
101
+ border-left: $border;
102
+
103
+ input:focus {
104
+ border: $input-active;
105
+ }
106
+ }
89
107
  }
@@ -1,7 +1,7 @@
1
1
  import { mount, shallow } from 'enzyme';
2
2
  import React from 'react';
3
3
  import { Button } from '../../Buttons';
4
- import { FilterType, FilterTypes } from '../Filters.model';
4
+ import { CustomFilterProps, FilterType, FilterTypes } from '../Filters.model';
5
5
  import { FreeTextFilter } from '../SelectionTypes/FreeTextFilter/FreeTextFilter';
6
6
  import { OptionsFilter } from '../SelectionTypes/OptionsFilter/OptionsFilter';
7
7
  import { Filter, FilterProps } from './Filter';
@@ -29,6 +29,17 @@ const optionFilter: FilterType<FilterTestData> = {
29
29
  ],
30
30
  };
31
31
 
32
+ const CustomFilterComponent: React.FC<CustomFilterProps> = () => {
33
+ return <div></div>;
34
+ };
35
+
36
+ const customFilter: FilterType<{ custom: string }> = {
37
+ label: 'Custom Filter',
38
+ property: 'custom',
39
+ type: FilterTypes.Custom,
40
+ component: CustomFilterComponent,
41
+ };
42
+
32
43
  const sampleText = 'sample text';
33
44
  const spy = jest.fn();
34
45
  const onFilterClickedSpy = jest.fn();
@@ -82,6 +93,28 @@ describe('Filter', () => {
82
93
  expect(filterTitle.hasClass('expanded')).toBe(expected);
83
94
  });
84
95
 
96
+ it('passes active state to custom filter', () => {
97
+ const wrapper = shallow(
98
+ <Filter
99
+ onFilterChange={() => null}
100
+ onFilterClicked={() => null}
101
+ options={customFilter}
102
+ isActive={false}
103
+ />,
104
+ );
105
+
106
+ wrapper.find('.title').simulate('click');
107
+
108
+ let filter = wrapper.find(CustomFilterComponent);
109
+ expect(filter.prop('active')).toBe(false);
110
+
111
+ wrapper.setProps({ isActive: true });
112
+ wrapper.update();
113
+
114
+ filter = wrapper.find(CustomFilterComponent);
115
+ expect(filter.prop('active')).toBe(true);
116
+ });
117
+
85
118
  it(`selected filter raises 'onFilterClicked' when clicked`, () => {
86
119
  const wrapper = shallow(
87
120
  <Filter
@@ -47,7 +47,6 @@ export const Filter = <T extends Data>({
47
47
 
48
48
  const contentRef = useRef<HTMLDivElement>(null);
49
49
  const valueRef = useRef<HTMLDivElement>(null);
50
- const inputRef = useRef<HTMLInputElement>(null);
51
50
 
52
51
  useEffect(() => {
53
52
  setContentHeight(
@@ -56,12 +55,6 @@ export const Filter = <T extends Data>({
56
55
  );
57
56
  }, [isExpanded, hasError, value]);
58
57
 
59
- useEffect(() => {
60
- if (isExpanded) {
61
- inputRef.current?.focus();
62
- }
63
- }, [isExpanded]);
64
-
65
58
  const onFilterValueChange = (
66
59
  prop: keyof T,
67
60
  value: FilterValue,
@@ -97,7 +90,6 @@ export const Filter = <T extends Data>({
97
90
  case FilterTypes.FreeText:
98
91
  return (
99
92
  <FreeTextFilter
100
- ref={inputRef}
101
93
  value={value}
102
94
  onSelect={(value: FilterValue) =>
103
95
  onFilterValueChange(options.property, value)
@@ -110,7 +102,6 @@ export const Filter = <T extends Data>({
110
102
  case FilterTypes.Numeric:
111
103
  return (
112
104
  <NumericTextFilter
113
- ref={inputRef}
114
105
  value={value as number}
115
106
  onSelect={(value: FilterValue) =>
116
107
  onFilterValueChange(options.property, value)
@@ -147,7 +138,6 @@ export const Filter = <T extends Data>({
147
138
  case FilterTypes.Date:
148
139
  return (
149
140
  <DateTimeFilter
150
- ref={inputRef}
151
141
  value={value as string}
152
142
  onSelect={(value: FilterValue) =>
153
143
  onFilterValueChange(options.property, value)
@@ -161,7 +151,6 @@ export const Filter = <T extends Data>({
161
151
  case FilterTypes.DateTime:
162
152
  return (
163
153
  <DateTimeFilter
164
- ref={inputRef}
165
154
  value={value as string}
166
155
  onSelect={(value: FilterValue) =>
167
156
  onFilterValueChange(options.property, value)
@@ -176,6 +165,7 @@ export const Filter = <T extends Data>({
176
165
  return (
177
166
  <options.component
178
167
  value={value}
168
+ active={isActive}
179
169
  onSelect={(value: FilterValue, stringValue?: string) => {
180
170
  onFilterValueChange(options.property, value, stringValue);
181
171
  }}
@@ -245,7 +235,11 @@ export const Filter = <T extends Data>({
245
235
  </div>
246
236
  )}
247
237
  {isExpanded && (
248
- <div ref={contentRef} data-test-id="filter-content">
238
+ <div
239
+ ref={contentRef}
240
+ data-test-id="filter-content"
241
+ className={clsx({ [classes.active]: isActive })}
242
+ >
249
243
  {renderFilterContent()}
250
244
  </div>
251
245
  )}
@@ -61,6 +61,9 @@ export interface CustomFilterProps {
61
61
  /** Current Value of the filter */
62
62
  value?: FilterValue;
63
63
 
64
+ /** Wether or not the filter is active (default: false) */
65
+ active?: boolean;
66
+
64
67
  /** Callback triggered when a new filter value is selected */
65
68
  onSelect: (
66
69
  value: FilterValue,
@@ -1,4 +1,5 @@
1
1
  @import '../../../../styles/common.scss';
2
+ @import '../../Filter/Filter.scss';
2
3
 
3
4
  .container {
4
5
  display: grid;
@@ -9,10 +10,13 @@
9
10
  grid-template-columns: 1fr min-content;
10
11
 
11
12
  place-items: center;
12
-
13
- border: 3px solid var(--input-hover-color, $input-hover-color);
13
+ border: $input-inactive;
14
14
 
15
15
  .inputValue {
16
+ &:focus {
17
+ border: none;
18
+ }
19
+
16
20
  color: var(--input-color, $input-color);
17
21
  padding: 0 12px;
18
22
  border: none;
@@ -33,6 +37,10 @@
33
37
  }
34
38
  }
35
39
 
40
+ &:focus-within {
41
+ border: $input-active;
42
+ }
43
+
36
44
  &.hasError {
37
45
  border: 3px solid
38
46
  var(--input-invalid-border-color, $input-invalid-border-color);
@@ -33,20 +33,14 @@ export interface DateTimeFilterProps {
33
33
  className?: string;
34
34
  }
35
35
 
36
- export const DateTimeFilter = React.forwardRef<
37
- HTMLInputElement,
38
- DateTimeFilterProps
39
- >(function DateTimeFilter(
40
- {
41
- onSelect,
42
- modifyTime,
43
- value: initialValue,
44
- onError = noop,
45
- onValidate: customValidate,
46
- className = '',
47
- },
48
- ref,
49
- ) {
36
+ export const DateTimeFilter: React.FC<DateTimeFilterProps> = ({
37
+ onSelect,
38
+ modifyTime,
39
+ value: initialValue,
40
+ onError = noop,
41
+ onValidate: customValidate,
42
+ className = '',
43
+ }) => {
50
44
  const container = useRef<HTMLDivElement>(null);
51
45
  const [showPicker, setShowPicker] = useState(false);
52
46
  const [value, setValue] = useState<string>('');
@@ -109,11 +103,15 @@ export const DateTimeFilter = React.forwardRef<
109
103
  )}
110
104
  >
111
105
  <div
112
- className={clsx(classes.dateTimeInput, errorMsg && classes.hasError)}
106
+ className={clsx(
107
+ classes.dateTimeInput,
108
+ 'datetime-border-wrapper',
109
+ errorMsg && classes.hasError,
110
+ )}
113
111
  ref={container}
114
112
  >
115
113
  <input
116
- ref={ref}
114
+ autoFocus
117
115
  className={clsx(classes.inputValue)}
118
116
  onKeyDown={handleKeyDown}
119
117
  onChange={(e) => setValue(e.target.value)}
@@ -181,7 +179,7 @@ export const DateTimeFilter = React.forwardRef<
181
179
  )}
182
180
  </>
183
181
  );
184
- });
182
+ };
185
183
 
186
184
  const calculatePosition = (
187
185
  offsetTop?: number,
@@ -9,10 +9,8 @@
9
9
 
10
10
  .inputValue {
11
11
  color: var(--input-color, $input-color);
12
- border: 3px solid var(--input-hover-color, $input-hover-color);
13
12
  padding: 0 12px;
14
- // border: 3px solid
15
- // var(--filter-option-background-color, $filter-option-background-color);
13
+
16
14
  font-size: var(--label-font-size, $label-font-size);
17
15
  outline: none;
18
16
 
@@ -19,19 +19,13 @@ export interface FreeTextFilterProps {
19
19
  className?: string;
20
20
  }
21
21
 
22
- export const FreeTextFilter = React.forwardRef<
23
- HTMLInputElement,
24
- FreeTextFilterProps
25
- >(function FreeTextFilter(
26
- {
27
- value,
28
- onSelect,
29
- onError = noop,
30
- onValidate: customValidate,
31
- className = '',
32
- },
33
- ref,
34
- ) {
22
+ export const FreeTextFilter: React.FC<FreeTextFilterProps> = ({
23
+ value,
24
+ onSelect,
25
+ onError = noop,
26
+ onValidate: customValidate,
27
+ className = '',
28
+ }) => {
35
29
  const [errorMsg, setErrorMsg] = useState<string>();
36
30
  const ENTER_KEY = 'Enter';
37
31
 
@@ -61,7 +55,7 @@ export const FreeTextFilter = React.forwardRef<
61
55
  )}
62
56
  >
63
57
  <input
64
- ref={ref}
58
+ autoFocus
65
59
  className={clsx(classes.inputValue, errorMsg && classes.hasError)}
66
60
  onKeyDown={handleKeyDown}
67
61
  value={valueLocal as string}
@@ -70,4 +64,4 @@ export const FreeTextFilter = React.forwardRef<
70
64
  {errorMsg !== undefined && <small>{errorMsg}</small>}
71
65
  </div>
72
66
  );
73
- });
67
+ };
@@ -9,10 +9,8 @@
9
9
 
10
10
  .inputValue {
11
11
  color: var(--input-color, $input-color);
12
- border: 3px solid var(--input-hover-color, $input-hover-color);
13
12
  padding: 0 12px;
14
- // border: 3px solid
15
- // var(--filter-option-background-color, $filter-option-background-color);
13
+
16
14
  font-size: var(--label-font-size, $label-font-size);
17
15
  outline: none;
18
16
 
@@ -20,19 +20,13 @@ export interface NumericTextFilterProps {
20
20
  className?: string;
21
21
  }
22
22
 
23
- export const NumericTextFilter = React.forwardRef<
24
- HTMLInputElement,
25
- NumericTextFilterProps
26
- >(function NumericTextFilter(
27
- {
28
- value,
29
- onSelect,
30
- onError = noop,
31
- onValidate: customValidate,
32
- className = '',
33
- },
34
- ref,
35
- ) {
23
+ export const NumericTextFilter: React.FC<NumericTextFilterProps> = ({
24
+ value,
25
+ onSelect,
26
+ onError = noop,
27
+ onValidate: customValidate,
28
+ className = '',
29
+ }) => {
36
30
  const [errorMsg, setErrorMsg] = useState<string>();
37
31
  const ENTER_KEY = 'Enter';
38
32
 
@@ -70,7 +64,7 @@ export const NumericTextFilter = React.forwardRef<
70
64
  )}
71
65
  >
72
66
  <input
73
- ref={ref}
67
+ autoFocus
74
68
  value={valueLocal}
75
69
  className={clsx(classes.inputValue, errorMsg && classes.hasError)}
76
70
  onKeyDown={handleKeyDown}
@@ -80,4 +74,4 @@ export const NumericTextFilter = React.forwardRef<
80
74
  {errorMsg !== undefined && <small>{errorMsg}</small>}
81
75
  </div>
82
76
  );
83
- });
77
+ };
@@ -5,7 +5,6 @@
5
5
 
6
6
  display: grid;
7
7
  grid-auto-rows: 50px;
8
- border: 1px solid var(--input-hover-color, $input-hover-color);
9
8
  background-color: var(
10
9
  --filter-controller-background-color,
11
10
  $filter-controller-background-color
@@ -9,10 +9,8 @@
9
9
 
10
10
  .inputValue {
11
11
  color: var(--input-color, $input-color);
12
- border: 3px solid var(--input-hover-color, $input-hover-color);
13
12
  padding: 0 12px;
14
- // border: 3px solid
15
- // var(--filter-option-background-color, $filter-option-background-color);
13
+
16
14
  font-size: var(--label-font-size, $label-font-size);
17
15
  outline: none;
18
16
 
@@ -1,6 +1,6 @@
1
1
  import clsx from 'clsx';
2
2
  import { debounce } from 'lodash';
3
- import React, { ChangeEvent, useEffect, useState } from 'react';
3
+ import React, { ChangeEvent, useCallback, useEffect, useState } from 'react';
4
4
  import { Option } from '../../Filters.model';
5
5
  import {
6
6
  OptionFilterProps,
@@ -22,17 +22,21 @@ export const SearcheableOptionsFilter: React.FC<SearcheableOptionFilterProps> =
22
22
  searchInputPlaceholder = '',
23
23
  maxItems = 10,
24
24
  onSelect,
25
+ className,
25
26
  ...rest
26
27
  }) => {
27
28
  const [options, setOptions] = useState<Option[]>([]);
28
29
 
29
- const getOptions = async (value: string) => {
30
- setOptions(await optionsProvider(value));
31
- };
30
+ const getOptions = useCallback(
31
+ async (value: string) => {
32
+ setOptions(await optionsProvider(value));
33
+ },
34
+ [optionsProvider],
35
+ );
32
36
 
33
37
  useEffect(() => {
34
38
  getOptions('');
35
- }, []);
39
+ }, [getOptions]);
36
40
 
37
41
  const onChangeHandler = async (
38
42
  e: ChangeEvent<HTMLInputElement>,
@@ -43,8 +47,15 @@ export const SearcheableOptionsFilter: React.FC<SearcheableOptionFilterProps> =
43
47
 
44
48
  return (
45
49
  <>
46
- <div className={clsx(classes.container, 'free-text-filter-container')}>
50
+ <div
51
+ className={clsx(
52
+ classes.container,
53
+ 'free-text-filter-container',
54
+ className,
55
+ )}
56
+ >
47
57
  <input
58
+ autoFocus
48
59
  onChange={debounce(onChangeHandler, 500)}
49
60
  className={clsx(classes.inputValue, '' && classes.hasError)}
50
61
  placeholder={searchInputPlaceholder}
@@ -71,7 +71,10 @@
71
71
  input:checked:after {
72
72
  content: '\2714';
73
73
  font-size: 20px;
74
- padding-left: 6px;
74
+ display: grid;
75
+ height: 100%;
76
+ justify-content: center;
77
+ align-content: center;
75
78
  color: #ffffff;
76
79
  }
77
80
 
@@ -19,6 +19,16 @@
19
19
  }
20
20
  }
21
21
 
22
+ textarea:disabled {
23
+ background-color: var(
24
+ --input-disabled-background-color,
25
+ $input-disabled-background-color
26
+ );
27
+ color: var(--input-disabled-font-color, $input-disabled-font-color);
28
+ border: 1px solid
29
+ var(--input-disabled-border-color, $input-disabled-border-color);
30
+ }
31
+
22
32
  textarea:hover,
23
33
  textarea:focus {
24
34
  border: 1px solid var(--input-hover-color, $input-hover-color);
@@ -30,5 +40,11 @@
30
40
  box-shadow: 0 0 0 2px
31
41
  var(--input-invalid-hover-color, $input-invalid-hover-color);
32
42
  }
43
+
44
+ &:disabled {
45
+ border: 1px solid
46
+ var(--input-disabled-border-color, $input-disabled-border-color);
47
+ box-shadow: none;
48
+ }
33
49
  }
34
50
  }
@@ -69,6 +69,9 @@ export function getRandomInt(min: number, max: number): number {
69
69
  return Math.floor(Math.random() * (max - min + 1)) + min;
70
70
  }
71
71
 
72
+ /**
73
+ * @deprecated Use Storybook's 'ComponentStoryObj' and CSF3 instead
74
+ */
72
75
  export type Story = React.FC & {
73
76
  story?: {
74
77
  [key: string]: any;
@@ -70,6 +70,7 @@ $filter-title-color: $blue;
70
70
  $filter-font-size: 16px;
71
71
  $filter-width: 360px;
72
72
  $filter-controller-background-color: $light-gray-2;
73
+ $filter-border-color: $blue;
73
74
 
74
75
  /* Details vars */
75
76
  $details-background-color: #ffffff;