@axinom/mosaic-ui 0.64.0-rc.6 → 0.64.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/dist/components/Explorer/BulkEdit/FormFieldsConfigConverter.d.ts +1 -1
- package/dist/components/Explorer/BulkEdit/GenerateMutation.d.ts.map +1 -1
- package/dist/components/Explorer/BulkEdit/index.d.ts +1 -0
- package/dist/components/Explorer/BulkEdit/index.d.ts.map +1 -1
- package/dist/components/Explorer/QuickEdit/useQuickEdit.d.ts.map +1 -1
- package/dist/components/Explorer/index.d.ts +1 -1
- package/dist/components/Explorer/index.d.ts.map +1 -1
- package/dist/components/InfoTooltip/InfoTooltip.d.ts.map +1 -1
- package/dist/components/InlineMenu/InlineMenu.d.ts.map +1 -1
- package/dist/components/List/List.d.ts +6 -1
- package/dist/components/List/List.d.ts.map +1 -1
- package/dist/components/List/ListRow/ListRow.d.ts +5 -20
- package/dist/components/List/ListRow/ListRow.d.ts.map +1 -1
- package/dist/components/List/ListRowRenderer/ListRowRenderer.d.ts +22 -0
- package/dist/components/List/ListRowRenderer/ListRowRenderer.d.ts.map +1 -0
- package/dist/index.es.js +4 -5
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +4 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Explorer/BulkEdit/FormFieldsConfigConverter.spec.tsx +158 -14
- package/src/components/Explorer/BulkEdit/FormFieldsConfigConverter.tsx +2 -2
- package/src/components/Explorer/BulkEdit/GenerateMutation.spec.tsx +209 -0
- package/src/components/Explorer/BulkEdit/GenerateMutation.tsx +78 -12
- package/src/components/Explorer/BulkEdit/index.ts +1 -0
- package/src/components/Explorer/QuickEdit/useQuickEdit.tsx +1 -0
- package/src/components/Explorer/index.ts +1 -0
- package/src/components/InfoTooltip/InfoTooltip.scss +65 -65
- package/src/components/InfoTooltip/InfoTooltip.tsx +35 -31
- package/src/components/InlineMenu/InlineMenu.tsx +39 -33
- package/src/components/List/List.spec.tsx +209 -1
- package/src/components/List/List.stories.tsx +76 -0
- package/src/components/List/List.tsx +52 -31
- package/src/components/List/ListRow/ListRow.scss +5 -0
- package/src/components/List/ListRow/ListRow.spec.tsx +97 -155
- package/src/components/List/ListRow/ListRow.tsx +31 -57
- package/src/components/List/ListRowRenderer/ListRowRenderer.spec.tsx +353 -0
- package/src/components/List/ListRowRenderer/ListRowRenderer.tsx +68 -0
- package/src/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroup.scss +32 -32
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { mount } from 'enzyme';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Column } from '../List.model';
|
|
4
|
+
import { ListRow } from '../ListRow/ListRow';
|
|
5
|
+
import { ListRowRenderer } from './ListRowRenderer';
|
|
6
|
+
|
|
7
|
+
interface TestData {
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
desc: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const mockColumns: Column<TestData>[] = [
|
|
14
|
+
{
|
|
15
|
+
propertyName: 'id',
|
|
16
|
+
size: '1fr',
|
|
17
|
+
label: 'ID',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
propertyName: 'title',
|
|
21
|
+
size: '2fr',
|
|
22
|
+
label: 'Title',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
propertyName: 'desc',
|
|
26
|
+
size: '1fr',
|
|
27
|
+
label: 'Description',
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const mockTestData: TestData = {
|
|
32
|
+
id: '1',
|
|
33
|
+
title: 'Test Item',
|
|
34
|
+
desc: 'Test Description',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const mockListRowProps = {
|
|
38
|
+
columns: mockColumns,
|
|
39
|
+
data: mockTestData,
|
|
40
|
+
itemSelected: false,
|
|
41
|
+
isTrigger: false,
|
|
42
|
+
isRowDisabled: false,
|
|
43
|
+
columnSizes: '1fr 2fr 1fr',
|
|
44
|
+
columnGap: '5px',
|
|
45
|
+
rowHeight: '44px',
|
|
46
|
+
actionSize: '50px',
|
|
47
|
+
horizontalTextAlign: 'left' as const,
|
|
48
|
+
verticalTextAlign: 'center' as const,
|
|
49
|
+
textWrap: false,
|
|
50
|
+
selectionMode: undefined,
|
|
51
|
+
showActionButton: false,
|
|
52
|
+
showCheckMark: false,
|
|
53
|
+
showItemCheckbox: false,
|
|
54
|
+
onItemClicked: jest.fn(),
|
|
55
|
+
onTriggered: jest.fn(),
|
|
56
|
+
onItemSelected: jest.fn(),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
describe('ListRowRenderer', () => {
|
|
60
|
+
const mountRowRenderer = (overrideProps = {}) => {
|
|
61
|
+
const defaultProps = {
|
|
62
|
+
listRowProps: mockListRowProps,
|
|
63
|
+
...overrideProps,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
return mount(<ListRowRenderer {...defaultProps} />);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
afterEach(() => {
|
|
70
|
+
jest.clearAllMocks();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('default behavior', () => {
|
|
74
|
+
it('should render default ListRow when no custom renderer provided', () => {
|
|
75
|
+
const wrapper = mountRowRenderer();
|
|
76
|
+
|
|
77
|
+
expect(wrapper.find(ListRow)).toHaveLength(1);
|
|
78
|
+
expect(wrapper.find(ListRow).prop('data')).toEqual(mockTestData);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should pass all props to default ListRow', () => {
|
|
82
|
+
const wrapper = mountRowRenderer();
|
|
83
|
+
const listRowProps = wrapper.find(ListRow).props();
|
|
84
|
+
|
|
85
|
+
expect(listRowProps).toEqual(expect.objectContaining(mockListRowProps));
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe('custom row renderer', () => {
|
|
90
|
+
it('should use custom renderer when provided', () => {
|
|
91
|
+
const customRenderer = jest.fn(() => (
|
|
92
|
+
<div data-test-id="custom-row">Custom Content</div>
|
|
93
|
+
));
|
|
94
|
+
|
|
95
|
+
const wrapper = mountRowRenderer({
|
|
96
|
+
customRowRenderer: customRenderer,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
expect(customRenderer).toHaveBeenCalledTimes(1);
|
|
100
|
+
expect(wrapper.find('[data-test-id="custom-row"]')).toHaveLength(1);
|
|
101
|
+
expect(wrapper.find(ListRow)).toHaveLength(0);
|
|
102
|
+
expect(wrapper.text()).toContain('Custom Content');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should pass complete ListRowProps to custom renderer', () => {
|
|
106
|
+
const customRenderer = jest.fn(() => (
|
|
107
|
+
<div data-test-id="custom-row">Custom</div>
|
|
108
|
+
));
|
|
109
|
+
|
|
110
|
+
const customListRowProps = {
|
|
111
|
+
...mockListRowProps,
|
|
112
|
+
itemSelected: true,
|
|
113
|
+
isRowDisabled: true,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
mountRowRenderer({
|
|
117
|
+
customRowRenderer: customRenderer,
|
|
118
|
+
listRowProps: customListRowProps,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
expect(customRenderer).toHaveBeenCalledWith(customListRowProps);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('should fallback to default ListRow when custom renderer returns null', () => {
|
|
125
|
+
const customRenderer = jest.fn(() => null);
|
|
126
|
+
|
|
127
|
+
const wrapper = mountRowRenderer({
|
|
128
|
+
customRowRenderer: customRenderer,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
expect(customRenderer).toHaveBeenCalledTimes(1);
|
|
132
|
+
expect(wrapper.find(ListRow)).toHaveLength(1);
|
|
133
|
+
expect(wrapper.find('[data-test-id="custom-row"]')).toHaveLength(0);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should fallback to default ListRow when custom renderer returns undefined', () => {
|
|
137
|
+
const customRenderer = jest.fn(() => undefined as any);
|
|
138
|
+
|
|
139
|
+
const wrapper = mountRowRenderer({
|
|
140
|
+
customRowRenderer: customRenderer,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
expect(customRenderer).toHaveBeenCalledTimes(1);
|
|
144
|
+
expect(wrapper.find(ListRow)).toHaveLength(1);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe('pagination trigger', () => {
|
|
149
|
+
const windowIntersectionObserver = window.IntersectionObserver;
|
|
150
|
+
const observe = jest.fn();
|
|
151
|
+
const disconnect = jest.fn();
|
|
152
|
+
|
|
153
|
+
beforeEach(() => {
|
|
154
|
+
window.IntersectionObserver = jest.fn().mockImplementation(() => ({
|
|
155
|
+
observe,
|
|
156
|
+
disconnect,
|
|
157
|
+
}));
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
afterEach(() => {
|
|
161
|
+
window.IntersectionObserver = windowIntersectionObserver;
|
|
162
|
+
jest.clearAllMocks();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
describe('default ListRow renderer', () => {
|
|
166
|
+
it('creates the IntersectionObserver when isTrigger===true', () => {
|
|
167
|
+
const onTriggeredSpy = jest.fn();
|
|
168
|
+
|
|
169
|
+
const wrapper = mountRowRenderer({
|
|
170
|
+
listRowProps: mockListRowProps,
|
|
171
|
+
isTrigger: true,
|
|
172
|
+
onTriggered: onTriggeredSpy,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
expect(window.IntersectionObserver).toHaveBeenCalledTimes(1);
|
|
176
|
+
expect(observe).toHaveBeenCalledWith(wrapper.getDOMNode());
|
|
177
|
+
expect(onTriggeredSpy).not.toHaveBeenCalled();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('does not create IntersectionObserver when isTrigger===false', () => {
|
|
181
|
+
const onTriggeredSpy = jest.fn();
|
|
182
|
+
|
|
183
|
+
mountRowRenderer({
|
|
184
|
+
listRowProps: mockListRowProps,
|
|
185
|
+
isTrigger: false,
|
|
186
|
+
onTriggered: onTriggeredSpy,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
expect(window.IntersectionObserver).not.toHaveBeenCalled();
|
|
190
|
+
expect(onTriggeredSpy).not.toHaveBeenCalled();
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('triggers onTriggered when IntersectionObserver observes entry', () => {
|
|
194
|
+
let intersectionFn: IntersectionObserverCallback = () => null;
|
|
195
|
+
const onTriggeredSpy = jest.fn();
|
|
196
|
+
|
|
197
|
+
(window.IntersectionObserver as jest.Mock).mockImplementation((fn) => {
|
|
198
|
+
intersectionFn = fn;
|
|
199
|
+
return { observe, disconnect };
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
mountRowRenderer({
|
|
203
|
+
listRowProps: mockListRowProps,
|
|
204
|
+
isTrigger: true,
|
|
205
|
+
onTriggered: onTriggeredSpy,
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// Manually trigger the intersection callback
|
|
209
|
+
intersectionFn(
|
|
210
|
+
[{ isIntersecting: true } as IntersectionObserverEntry],
|
|
211
|
+
{} as IntersectionObserver,
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
expect(onTriggeredSpy).toHaveBeenCalledTimes(1);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('does not trigger when entry is not intersecting', () => {
|
|
218
|
+
let intersectionFn: IntersectionObserverCallback = () => null;
|
|
219
|
+
const onTriggeredSpy = jest.fn();
|
|
220
|
+
|
|
221
|
+
(window.IntersectionObserver as jest.Mock).mockImplementation((fn) => {
|
|
222
|
+
intersectionFn = fn;
|
|
223
|
+
return { observe, disconnect };
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
mountRowRenderer({
|
|
227
|
+
listRowProps: mockListRowProps,
|
|
228
|
+
isTrigger: true,
|
|
229
|
+
onTriggered: onTriggeredSpy,
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// Manually trigger the intersection callback with non-intersecting entry
|
|
233
|
+
intersectionFn(
|
|
234
|
+
[{ isIntersecting: false } as IntersectionObserverEntry],
|
|
235
|
+
{} as IntersectionObserver,
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
expect(onTriggeredSpy).not.toHaveBeenCalled();
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it.todo('sets ref if row is trigger'); // https://github.com/airbnb/enzyme/issues/2215
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
describe('custom row renderer', () => {
|
|
245
|
+
it('creates the IntersectionObserver when isTrigger===true for custom renderer', () => {
|
|
246
|
+
const customRenderer = jest.fn(() => (
|
|
247
|
+
<div data-test-id="custom-row">Custom Content</div>
|
|
248
|
+
));
|
|
249
|
+
const onTriggeredSpy = jest.fn();
|
|
250
|
+
|
|
251
|
+
const wrapper = mountRowRenderer({
|
|
252
|
+
listRowProps: mockListRowProps,
|
|
253
|
+
isTrigger: true,
|
|
254
|
+
onTriggered: onTriggeredSpy,
|
|
255
|
+
customRowRenderer: customRenderer,
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
expect(window.IntersectionObserver).toHaveBeenCalledTimes(1);
|
|
259
|
+
expect(observe).toHaveBeenCalledWith(wrapper.getDOMNode());
|
|
260
|
+
expect(onTriggeredSpy).not.toHaveBeenCalled();
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('does not create IntersectionObserver when isTrigger===false for custom renderer', () => {
|
|
264
|
+
const customRenderer = jest.fn(() => (
|
|
265
|
+
<div data-test-id="custom-row">Custom Content</div>
|
|
266
|
+
));
|
|
267
|
+
const onTriggeredSpy = jest.fn();
|
|
268
|
+
|
|
269
|
+
mountRowRenderer({
|
|
270
|
+
listRowProps: mockListRowProps,
|
|
271
|
+
isTrigger: false,
|
|
272
|
+
onTriggered: onTriggeredSpy,
|
|
273
|
+
customRowRenderer: customRenderer,
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
expect(window.IntersectionObserver).not.toHaveBeenCalled();
|
|
277
|
+
expect(onTriggeredSpy).not.toHaveBeenCalled();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('triggers onTriggered when IntersectionObserver observes entry for custom renderer', () => {
|
|
281
|
+
let intersectionFn: IntersectionObserverCallback = () => null;
|
|
282
|
+
const customRenderer = jest.fn(() => (
|
|
283
|
+
<div data-test-id="custom-row">Custom Content</div>
|
|
284
|
+
));
|
|
285
|
+
const onTriggeredSpy = jest.fn();
|
|
286
|
+
|
|
287
|
+
(window.IntersectionObserver as jest.Mock).mockImplementation((fn) => {
|
|
288
|
+
// Remember the callback function
|
|
289
|
+
intersectionFn = fn;
|
|
290
|
+
// Return the mocked object
|
|
291
|
+
return { observe, disconnect };
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
mountRowRenderer({
|
|
295
|
+
listRowProps: mockListRowProps,
|
|
296
|
+
isTrigger: true,
|
|
297
|
+
onTriggered: onTriggeredSpy,
|
|
298
|
+
customRowRenderer: customRenderer,
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// Manually trigger the intersection callback
|
|
302
|
+
intersectionFn(
|
|
303
|
+
[{ isIntersecting: true } as IntersectionObserverEntry],
|
|
304
|
+
{} as IntersectionObserver,
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
expect(onTriggeredSpy).toHaveBeenCalledTimes(1);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it.todo('sets ref if row is trigger'); // https://github.com/airbnb/enzyme/issues/2215
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
describe('observer cleanup', () => {
|
|
314
|
+
it('disconnects observer when isTrigger changes from true to false', () => {
|
|
315
|
+
const onTriggeredSpy = jest.fn();
|
|
316
|
+
|
|
317
|
+
const wrapper = mountRowRenderer({
|
|
318
|
+
listRowProps: mockListRowProps,
|
|
319
|
+
isTrigger: true,
|
|
320
|
+
onTriggered: onTriggeredSpy,
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
expect(window.IntersectionObserver).toHaveBeenCalledTimes(1);
|
|
324
|
+
|
|
325
|
+
// Change isTrigger to false
|
|
326
|
+
wrapper.setProps({
|
|
327
|
+
listRowProps: {
|
|
328
|
+
...mockListRowProps,
|
|
329
|
+
},
|
|
330
|
+
isTrigger: false,
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
expect(disconnect).toHaveBeenCalledTimes(1);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('disconnects observer on component unmount', () => {
|
|
337
|
+
const onTriggeredSpy = jest.fn();
|
|
338
|
+
|
|
339
|
+
const wrapper = mountRowRenderer({
|
|
340
|
+
listRowProps: mockListRowProps,
|
|
341
|
+
isTrigger: true,
|
|
342
|
+
onTriggered: onTriggeredSpy,
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
expect(window.IntersectionObserver).toHaveBeenCalledTimes(1);
|
|
346
|
+
|
|
347
|
+
wrapper.unmount();
|
|
348
|
+
|
|
349
|
+
expect(disconnect).toHaveBeenCalledTimes(1);
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React, { useCallback, useRef } from 'react';
|
|
2
|
+
import { Data } from '../../../types/data';
|
|
3
|
+
import { ListRow, ListRowProps } from '../ListRow/ListRow';
|
|
4
|
+
|
|
5
|
+
interface RowRendererProps<T extends Data> {
|
|
6
|
+
/**
|
|
7
|
+
* Custom renderer for the list row.
|
|
8
|
+
* If provided, it will override the default ListRow rendering.
|
|
9
|
+
* In case it returns null, the default ListRow will not be rendered.
|
|
10
|
+
*/
|
|
11
|
+
customRowRenderer?: (props: ListRowProps<T>) => React.ReactElement | null;
|
|
12
|
+
/** Props passed to the ListRow and custom renderer */
|
|
13
|
+
listRowProps: ListRowProps<T>;
|
|
14
|
+
/** Whether or not the item is a trigger for pagination (default: false) */
|
|
15
|
+
isTrigger?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* A function that is getting called, when the element acts as a trigger (`isTrigger = true`) and gets into view.
|
|
18
|
+
*/
|
|
19
|
+
onTriggered?: () => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const ListRowRenderer = <T extends Data>({
|
|
23
|
+
listRowProps,
|
|
24
|
+
isTrigger = false,
|
|
25
|
+
customRowRenderer,
|
|
26
|
+
onTriggered,
|
|
27
|
+
}: RowRendererProps<T>): React.ReactElement<
|
|
28
|
+
T,
|
|
29
|
+
string | React.JSXElementConstructor<T>
|
|
30
|
+
> | null => {
|
|
31
|
+
// Pagination trigger logic
|
|
32
|
+
// Trigger based on: https://www.youtube.com/watch?v=NZKUirTtxcg
|
|
33
|
+
const onTriggeredHandler = useCallback(() => {
|
|
34
|
+
onTriggered && onTriggered();
|
|
35
|
+
}, [onTriggered]);
|
|
36
|
+
|
|
37
|
+
const observer = useRef<IntersectionObserver>();
|
|
38
|
+
const elementRef = useCallback(
|
|
39
|
+
(node: HTMLDivElement) => {
|
|
40
|
+
if (isTrigger === false) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (observer.current) {
|
|
44
|
+
observer.current.disconnect();
|
|
45
|
+
}
|
|
46
|
+
observer.current = new IntersectionObserver(([entry]) => {
|
|
47
|
+
if (entry.isIntersecting) {
|
|
48
|
+
onTriggeredHandler();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (node) {
|
|
53
|
+
observer.current.observe(node);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
[isTrigger, onTriggeredHandler],
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
if (customRowRenderer) {
|
|
60
|
+
const customElement = customRowRenderer(listRowProps);
|
|
61
|
+
|
|
62
|
+
if (customElement) {
|
|
63
|
+
return <div ref={isTrigger ? elementRef : null}>{customElement}</div>;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return <ListRow {...listRowProps} ref={isTrigger ? elementRef : null} />;
|
|
68
|
+
};
|
|
@@ -32,46 +32,46 @@
|
|
|
32
32
|
background-color: white;
|
|
33
33
|
|
|
34
34
|
z-index: 2;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
35
|
|
|
38
|
-
.dropDown {
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
.dropDown {
|
|
37
|
+
height: unset;
|
|
38
|
+
width: unset;
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
display: grid;
|
|
41
|
+
grid-template-columns: 1fr 40px;
|
|
42
|
+
grid-template-rows: 1fr;
|
|
45
43
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
// icon
|
|
45
|
+
div:first-child {
|
|
46
|
+
display: grid;
|
|
47
|
+
align-items: center;
|
|
48
|
+
grid-row: 1 / span 1;
|
|
49
|
+
justify-items: start;
|
|
50
|
+
grid-column: 2 / span 1;
|
|
51
|
+
padding: 0px;
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
svg,
|
|
54
|
+
img {
|
|
55
|
+
height: 30px;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
// label
|
|
60
|
+
div:last-child {
|
|
61
|
+
display: grid;
|
|
62
|
+
align-items: center;
|
|
63
|
+
grid-column: 1 / span 1;
|
|
64
|
+
justify-items: start;
|
|
67
65
|
|
|
68
|
-
|
|
66
|
+
padding: 0px 0px 0px 20px;
|
|
69
67
|
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
span {
|
|
69
|
+
height: 30px;
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
display: grid;
|
|
72
|
+
align-items: center;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|