@saleor/macaw-ui 0.3.2 → 0.5.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/README.md +20 -0
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/index.js.map +3 -3
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +3 -3
- package/dist/types/ActionBar/ActionBar.d.ts +1 -0
- package/dist/types/ActionBar/context.d.ts +6 -3
- package/dist/types/Autocomplete/Autocomplete.d.ts +23 -0
- package/dist/types/Autocomplete/Autocomplete.stories.d.ts +5 -0
- package/dist/types/Autocomplete/fixtures.d.ts +4 -0
- package/dist/types/Autocomplete/index.d.ts +1 -0
- package/dist/types/Autocomplete/styles.d.ts +2 -0
- package/dist/types/Chip/Chip.d.ts +8 -0
- package/dist/types/Chip/ChipAdornment.d.ts +6 -0
- package/dist/types/Chip/ChipMovable.d.ts +5 -0
- package/dist/types/Chip/ChipRemovable.d.ts +6 -0
- package/dist/types/Chip/ChipSwatch.d.ts +7 -0
- package/dist/types/Chip/index.d.ts +5 -0
- package/dist/types/Chip/private/ColorSwatch.d.ts +6 -0
- package/dist/types/Chip/styles.d.ts +2 -0
- package/dist/types/CircleIndicator/index.d.ts +1 -1
- package/dist/types/Filter/FilterField/AutocompleteFilterField.d.ts +6 -0
- package/dist/types/Filter/FilterField/MultipleValueAutocompleteFilterField.d.ts +6 -0
- package/dist/types/Filter/stories/Filter.stories.d.ts +5 -0
- package/dist/types/Filter/stories/FilterInteractive.stories.d.ts +4 -0
- package/dist/types/Filter/stories/labels.d.ts +8 -0
- package/dist/types/Filter/styles.d.ts +1 -1
- package/dist/types/Filter/types.d.ts +8 -2
- package/dist/types/Filter/utils.d.ts +4 -1
- package/dist/types/IconButton/IconButton.d.ts +2 -0
- package/dist/types/IconButton/partials.d.ts +1 -1
- package/dist/types/IconButton/styles.d.ts +1 -1
- package/dist/types/MultipleValueAutocomplete/MultipleValueAutocomplete.d.ts +26 -0
- package/dist/types/MultipleValueAutocomplete/MultipleValueAutocomplete.stories.d.ts +6 -0
- package/dist/types/MultipleValueAutocomplete/fixtures.d.ts +4 -0
- package/dist/types/MultipleValueAutocomplete/index.d.ts +1 -0
- package/dist/types/MultipleValueAutocomplete/styles.d.ts +2 -0
- package/dist/types/MultipleValueAutocomplete/useMultipleValueAutocomplete.d.ts +32 -0
- package/dist/types/Savebar/Savebar.d.ts +1 -0
- package/dist/types/Sidebar/MenuItem.d.ts +9 -3
- package/dist/types/Sidebar/types.d.ts +8 -0
- package/dist/types/Sidebar/utils.d.ts +12 -0
- package/dist/types/SidebarDrawer/MenuItemBtn.d.ts +2 -1
- package/dist/types/SwitchSelector/SwitchSelector.d.ts +2 -0
- package/dist/types/SwitchSelector/SwitchSelector.stories.d.ts +4 -0
- package/dist/types/SwitchSelector/SwitchSelectorButton.d.ts +8 -0
- package/dist/types/SwitchSelector/index.d.ts +2 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/theme/ThemeProvider.d.ts +4 -0
- package/dist/types/theme/types.d.ts +1 -0
- package/dist/types/tools/useTextWidth.d.ts +2 -0
- package/dist/types/utils/guideStyles.d.ts +1 -1
- package/dist/types/utils/mergeRefs.d.ts +2 -0
- package/dist/types/utils/useMockAutocomplete.d.ts +10 -0
- package/package.json +11 -13
- package/src/ActionBar/ActionBar.tsx +8 -11
- package/src/ActionBar/context.tsx +15 -6
- package/src/ActionBar/styles.ts +1 -1
- package/src/Autocomplete/Autocomplete.stories.tsx +43 -0
- package/src/Autocomplete/Autocomplete.tsx +187 -0
- package/src/Autocomplete/fixtures.ts +122 -0
- package/src/Autocomplete/index.ts +1 -0
- package/src/Autocomplete/styles.ts +19 -0
- package/src/Backlink/Backlink.tsx +3 -1
- package/src/Chip/Chip.tsx +52 -0
- package/src/Chip/ChipAdornment.tsx +53 -0
- package/src/Chip/ChipMovable.tsx +40 -0
- package/src/Chip/ChipRemovable.tsx +29 -0
- package/src/Chip/ChipSwatch.tsx +42 -0
- package/src/Chip/index.ts +5 -0
- package/src/Chip/private/ColorSwatch.tsx +21 -0
- package/src/Chip/styles.ts +46 -0
- package/src/CircleIndicator/CircleIndicator.stories.tsx +6 -6
- package/src/CircleIndicator/index.ts +1 -1
- package/src/Filter/Filter.tsx +88 -44
- package/src/Filter/FilterBar.tsx +15 -9
- package/src/Filter/FilterContent.tsx +8 -1
- package/src/Filter/FilterField/AutocompleteFilterField.tsx +61 -0
- package/src/Filter/FilterField/MultipleSelectFilterField.tsx +9 -3
- package/src/Filter/FilterField/MultipleValueAutocompleteFilterField.tsx +60 -0
- package/src/Filter/context.tsx +1 -1
- package/src/Filter/{Filter.stories.tsx → stories/Filter.stories.tsx} +47 -13
- package/src/Filter/stories/FilterInteractive.stories.tsx +97 -0
- package/src/Filter/stories/labels.ts +8 -0
- package/src/Filter/styles.ts +37 -6
- package/src/Filter/types.ts +8 -1
- package/src/Filter/utils.ts +71 -5
- package/src/IconButton/IconButton.tsx +17 -2
- package/src/IconButton/partials.ts +1 -1
- package/src/IconButton/styles.ts +38 -16
- package/src/MultipleValueAutocomplete/MultipleValueAutocomplete.stories.tsx +76 -0
- package/src/MultipleValueAutocomplete/MultipleValueAutocomplete.tsx +185 -0
- package/src/MultipleValueAutocomplete/fixtures.ts +122 -0
- package/src/MultipleValueAutocomplete/index.ts +1 -0
- package/src/MultipleValueAutocomplete/styles.ts +39 -0
- package/src/MultipleValueAutocomplete/useMultipleValueAutocomplete.ts +172 -0
- package/src/Savebar/Savebar.tsx +3 -4
- package/src/Sidebar/MenuItem.tsx +35 -14
- package/src/Sidebar/Sidebar.tsx +27 -11
- package/src/Sidebar/types.ts +9 -0
- package/src/Sidebar/utils.ts +23 -0
- package/src/SidebarDrawer/MenuItemBtn.tsx +12 -6
- package/src/SidebarDrawer/SidebarDrawer.tsx +8 -2
- package/src/SwitchSelector/SwitchSelector.stories.tsx +63 -0
- package/src/SwitchSelector/SwitchSelector.tsx +19 -0
- package/src/SwitchSelector/SwitchSelectorButton.tsx +59 -0
- package/src/SwitchSelector/index.ts +2 -0
- package/src/index.tsx +4 -1
- package/src/theme/ThemeProvider.tsx +6 -0
- package/src/theme/createSaleorTheme/createSaleorTheme.tsx +2 -1
- package/src/theme/createSaleorTheme/overrides/controls.ts +4 -1
- package/src/theme/createSaleorTheme/overrides/inputs.ts +1 -1
- package/src/theme/themes.ts +1 -1
- package/src/theme/types.ts +1 -0
- package/src/tools/useTextWidth.ts +20 -0
- package/src/utils/guideStyles.ts +5 -0
- package/src/utils/mergeRefs.ts +14 -0
- package/src/utils/useMockAutocomplete.ts +37 -0
|
@@ -2,18 +2,10 @@ import { Meta, Story } from "@storybook/react";
|
|
|
2
2
|
import { debounce } from "lodash";
|
|
3
3
|
import React from "react";
|
|
4
4
|
|
|
5
|
-
import { Filter } from "
|
|
6
|
-
import { FilterBar } from "
|
|
7
|
-
import { FilterType } from "
|
|
8
|
-
|
|
9
|
-
const labels = {
|
|
10
|
-
addButton: "Add Filter",
|
|
11
|
-
header: "Filters",
|
|
12
|
-
where: "Where",
|
|
13
|
-
and: "and",
|
|
14
|
-
is: "is",
|
|
15
|
-
range: "between",
|
|
16
|
-
};
|
|
5
|
+
import { Filter } from "../Filter";
|
|
6
|
+
import { FilterBar } from "../FilterBar";
|
|
7
|
+
import { FilterType } from "../types";
|
|
8
|
+
import { labels } from "./labels";
|
|
17
9
|
|
|
18
10
|
export const Default: Story = () => (
|
|
19
11
|
<FilterBar
|
|
@@ -63,6 +55,11 @@ export const Default: Story = () => (
|
|
|
63
55
|
/>
|
|
64
56
|
</FilterBar>
|
|
65
57
|
);
|
|
58
|
+
|
|
59
|
+
const attributeGroup = {
|
|
60
|
+
label: "Attribute",
|
|
61
|
+
name: "attribute",
|
|
62
|
+
};
|
|
66
63
|
export const WithInitialState: Story = () => (
|
|
67
64
|
<FilterBar
|
|
68
65
|
labels={labels}
|
|
@@ -78,6 +75,11 @@ export const WithInitialState: Story = () => (
|
|
|
78
75
|
value: "no",
|
|
79
76
|
values: null,
|
|
80
77
|
},
|
|
78
|
+
{
|
|
79
|
+
name: "status",
|
|
80
|
+
values: ["published"],
|
|
81
|
+
value: null,
|
|
82
|
+
},
|
|
81
83
|
]}
|
|
82
84
|
onClose={() => undefined}
|
|
83
85
|
>
|
|
@@ -101,9 +103,41 @@ export const WithInitialState: Story = () => (
|
|
|
101
103
|
{ label: "Not Available", value: "no" },
|
|
102
104
|
]}
|
|
103
105
|
/>
|
|
106
|
+
<Filter
|
|
107
|
+
name="status"
|
|
108
|
+
label="Status"
|
|
109
|
+
type={FilterType.Choice}
|
|
110
|
+
default="scheduled"
|
|
111
|
+
choices={[
|
|
112
|
+
{ label: "Published", value: "published" },
|
|
113
|
+
{ label: "Scheduled for publishing", value: "scheduled" },
|
|
114
|
+
{ label: "Not Published", value: "unpublished" },
|
|
115
|
+
]}
|
|
116
|
+
multiple
|
|
117
|
+
/>
|
|
118
|
+
<Filter
|
|
119
|
+
name="color"
|
|
120
|
+
label="Color"
|
|
121
|
+
group={attributeGroup}
|
|
122
|
+
type={FilterType.Choice}
|
|
123
|
+
choices={[
|
|
124
|
+
{ label: "Green", value: "green" },
|
|
125
|
+
{ label: "Red", value: "red" },
|
|
126
|
+
]}
|
|
127
|
+
/>
|
|
128
|
+
<Filter
|
|
129
|
+
name="size"
|
|
130
|
+
label="Size"
|
|
131
|
+
group={attributeGroup}
|
|
132
|
+
type={FilterType.Choice}
|
|
133
|
+
choices={[
|
|
134
|
+
{ label: "XL", value: "xl" },
|
|
135
|
+
{ label: "L", value: "l" },
|
|
136
|
+
]}
|
|
137
|
+
/>
|
|
104
138
|
</FilterBar>
|
|
105
139
|
);
|
|
106
140
|
|
|
107
141
|
export default {
|
|
108
|
-
title: "Filter",
|
|
142
|
+
title: "Filter / Dummy",
|
|
109
143
|
} as Meta;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Meta, Story } from "@storybook/react";
|
|
2
|
+
import { debounce } from "lodash";
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
import { useMockAutocomplete } from "../../utils/useMockAutocomplete";
|
|
6
|
+
import { Filter } from "../Filter";
|
|
7
|
+
import { FilterBar } from "../FilterBar";
|
|
8
|
+
import { FilterType } from "../types";
|
|
9
|
+
import { labels } from "./labels";
|
|
10
|
+
|
|
11
|
+
const choices = [
|
|
12
|
+
{ label: "Awesome Chair", value: "awesome chair" },
|
|
13
|
+
{ label: "Ergonomic Chair", value: "ergonomic chair" },
|
|
14
|
+
{ label: "Fantastic Bacon", value: "fantastic bacon" },
|
|
15
|
+
{ label: "Fantastic Gloves", value: "fantastic gloves" },
|
|
16
|
+
{ label: "Fantastic Hat", value: "fantastic hat" },
|
|
17
|
+
{ label: "Fantastic Pants", value: "fantastic pants" },
|
|
18
|
+
{ label: "Generic Bacon", value: "generic bacon" },
|
|
19
|
+
{ label: "Gorgeous Bacon", value: "gorgeous bacon" },
|
|
20
|
+
{ label: "Handcrafted Chair", value: "handcrafted chair" },
|
|
21
|
+
{ label: "Handmade Computer", value: "handmade computer" },
|
|
22
|
+
{ label: "Handmade Pizza", value: "handmade pizza" },
|
|
23
|
+
{ label: "Incredible Shirt", value: "incredible shirt" },
|
|
24
|
+
{ label: "Incredible Soap", value: "incredible soap" },
|
|
25
|
+
{ label: "Incredible Table", value: "incredible table" },
|
|
26
|
+
{ label: "Intelligent Hat", value: "intelligent hat" },
|
|
27
|
+
{ label: "Intelligent Mouse", value: "intelligent mouse" },
|
|
28
|
+
{ label: "Intelligent Sausages", value: "intelligent sausages" },
|
|
29
|
+
{ label: "Licensed Chair", value: "licensed chair" },
|
|
30
|
+
{ label: "Practical Hat", value: "practical hat" },
|
|
31
|
+
{ label: "Practical Shoes", value: "practical shoes" },
|
|
32
|
+
{ label: "Refined Ball", value: "refined ball" },
|
|
33
|
+
{ label: "Refined Table", value: "refined table" },
|
|
34
|
+
{ label: "Rustic Cheese", value: "rustic cheese" },
|
|
35
|
+
{ label: "Rustic Shoes", value: "rustic shoes" },
|
|
36
|
+
{ label: "Sleek Car", value: "sleek car" },
|
|
37
|
+
{ label: "Small Ball", value: "small ball" },
|
|
38
|
+
{ label: "Small Bike", value: "small bike" },
|
|
39
|
+
{ label: "Tasty Gloves", value: "tasty gloves" },
|
|
40
|
+
{ label: "Tasty Table", value: "tasty table" },
|
|
41
|
+
{ label: "Unbranded Gloves", value: "unbranded gloves" },
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
export const Autocomplete: Story = () => {
|
|
45
|
+
const { results, search } = useMockAutocomplete(choices);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<FilterBar
|
|
49
|
+
labels={labels}
|
|
50
|
+
onChange={debounce((fd) => console.log(fd), 1000)}
|
|
51
|
+
initial={[
|
|
52
|
+
{
|
|
53
|
+
name: "name",
|
|
54
|
+
value: "Lorem Ipsum",
|
|
55
|
+
values: null,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "product",
|
|
59
|
+
value: choices[0].value,
|
|
60
|
+
values: null,
|
|
61
|
+
},
|
|
62
|
+
]}
|
|
63
|
+
onClose={() => undefined}
|
|
64
|
+
>
|
|
65
|
+
<Filter name="name" label="Name" type={FilterType.Text} />
|
|
66
|
+
<Filter
|
|
67
|
+
name="price"
|
|
68
|
+
label="Price"
|
|
69
|
+
type={FilterType.Range}
|
|
70
|
+
InputProps={{
|
|
71
|
+
InputProps: {
|
|
72
|
+
endAdornment: "USD",
|
|
73
|
+
},
|
|
74
|
+
}}
|
|
75
|
+
/>
|
|
76
|
+
<Filter
|
|
77
|
+
name="product"
|
|
78
|
+
label="Product"
|
|
79
|
+
type={FilterType.Autocomplete}
|
|
80
|
+
choices={results}
|
|
81
|
+
onInputChange={search}
|
|
82
|
+
/>
|
|
83
|
+
<Filter
|
|
84
|
+
name="references"
|
|
85
|
+
label="Product references"
|
|
86
|
+
type={FilterType.Autocomplete}
|
|
87
|
+
multiple
|
|
88
|
+
choices={results}
|
|
89
|
+
onInputChange={search}
|
|
90
|
+
/>
|
|
91
|
+
</FilterBar>
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export default {
|
|
96
|
+
title: "Filter / Interactive",
|
|
97
|
+
} as Meta;
|
package/src/Filter/styles.ts
CHANGED
|
@@ -14,11 +14,16 @@ const useStyles = makeStyles(
|
|
|
14
14
|
},
|
|
15
15
|
|
|
16
16
|
filter: {
|
|
17
|
-
alignItems: "
|
|
17
|
+
alignItems: "flex-start",
|
|
18
18
|
display: "flex",
|
|
19
19
|
columnGap: theme.spacing(2),
|
|
20
20
|
marginBottom: theme.spacing(2),
|
|
21
21
|
},
|
|
22
|
+
filterOptions: {
|
|
23
|
+
alignItems: "center",
|
|
24
|
+
columnGap: theme.spacing(2),
|
|
25
|
+
display: "flex",
|
|
26
|
+
},
|
|
22
27
|
filterChip: {
|
|
23
28
|
borderRadius: 8,
|
|
24
29
|
background: theme.palette.primary.main,
|
|
@@ -26,17 +31,30 @@ const useStyles = makeStyles(
|
|
|
26
31
|
},
|
|
27
32
|
filterChipContainer: {
|
|
28
33
|
display: "flex",
|
|
29
|
-
|
|
34
|
+
flexWrap: "wrap",
|
|
35
|
+
gap: theme.spacing(1),
|
|
30
36
|
},
|
|
31
|
-
|
|
37
|
+
filterDeleteContainer: {
|
|
38
|
+
alignItems: "center",
|
|
39
|
+
columnGap: theme.spacing(2),
|
|
40
|
+
display: "flex",
|
|
41
|
+
height: 51,
|
|
32
42
|
marginLeft: "auto",
|
|
33
43
|
},
|
|
44
|
+
filterDelete: {
|
|
45
|
+
position: "relative",
|
|
46
|
+
left: 6,
|
|
47
|
+
},
|
|
34
48
|
filterName: {
|
|
35
49
|
width: 180,
|
|
36
50
|
},
|
|
37
51
|
filterValue: {
|
|
38
|
-
|
|
39
|
-
|
|
52
|
+
"& .MuiSelect-root": {
|
|
53
|
+
boxSizing: "border-box",
|
|
54
|
+
},
|
|
55
|
+
boxSizing: "border-box",
|
|
56
|
+
minHeight: 51,
|
|
57
|
+
width: "100%",
|
|
40
58
|
},
|
|
41
59
|
filterRange: {
|
|
42
60
|
width: 115,
|
|
@@ -46,6 +64,13 @@ const useStyles = makeStyles(
|
|
|
46
64
|
padding: theme.spacing(2),
|
|
47
65
|
},
|
|
48
66
|
},
|
|
67
|
+
filterMultipleValueInputInner: {
|
|
68
|
+
"&&": {
|
|
69
|
+
minHeight: 51,
|
|
70
|
+
padding: theme.spacing(1),
|
|
71
|
+
paddingRight: theme.spacing(8),
|
|
72
|
+
},
|
|
73
|
+
},
|
|
49
74
|
filterConjunction: {
|
|
50
75
|
minWidth: 80,
|
|
51
76
|
},
|
|
@@ -65,7 +90,13 @@ const useStyles = makeStyles(
|
|
|
65
90
|
},
|
|
66
91
|
|
|
67
92
|
bar: {
|
|
68
|
-
minWidth:
|
|
93
|
+
minWidth: 100,
|
|
94
|
+
},
|
|
95
|
+
barAddBtn: {
|
|
96
|
+
"& svg": {
|
|
97
|
+
marginLeft: theme.spacing(1),
|
|
98
|
+
marginRight: 0,
|
|
99
|
+
},
|
|
69
100
|
},
|
|
70
101
|
|
|
71
102
|
selectPaper: {
|
package/src/Filter/types.ts
CHANGED
|
@@ -4,14 +4,20 @@ export enum FilterType {
|
|
|
4
4
|
Text,
|
|
5
5
|
Choice,
|
|
6
6
|
Range,
|
|
7
|
+
Autocomplete,
|
|
7
8
|
}
|
|
8
9
|
|
|
10
|
+
export type Choice = Record<"label" | "value", string>;
|
|
11
|
+
|
|
9
12
|
export interface FilterDetailedOptions {
|
|
10
13
|
type: FilterType;
|
|
11
|
-
choices?:
|
|
14
|
+
choices?: Choice[];
|
|
12
15
|
default?: string;
|
|
13
16
|
multiple?: boolean;
|
|
14
17
|
InputProps?: Partial<TextFieldProps>;
|
|
18
|
+
group?: Record<"label" | "name", string>;
|
|
19
|
+
displayValues?: Choice[];
|
|
20
|
+
onInputChange?: (value: string) => void;
|
|
15
21
|
}
|
|
16
22
|
export interface FilterOptions {
|
|
17
23
|
name: string;
|
|
@@ -52,6 +58,7 @@ export interface FilterContextType {
|
|
|
52
58
|
toggle: (name: string) => void;
|
|
53
59
|
toggleRange: (name: string) => void;
|
|
54
60
|
unregister: (name: string) => void;
|
|
61
|
+
swap: (previousFilterName: string, nextFilterName: string) => void;
|
|
55
62
|
onChange: (
|
|
56
63
|
name: string,
|
|
57
64
|
value: string | string[],
|
package/src/Filter/utils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { uniqBy } from "lodash";
|
|
1
|
+
import { sortBy, uniqBy } from "lodash";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
FilterData,
|
|
@@ -8,8 +8,36 @@ import {
|
|
|
8
8
|
OnFilterChangeOpts,
|
|
9
9
|
} from "./types";
|
|
10
10
|
|
|
11
|
-
export function
|
|
12
|
-
|
|
11
|
+
export function getFilterName(
|
|
12
|
+
name: string,
|
|
13
|
+
options: FilterDetailedOptions
|
|
14
|
+
): string {
|
|
15
|
+
return options.group ? `${options.group.name}:${name}` : name;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getAvailableFilterGroups(
|
|
19
|
+
filterData: FilterData[]
|
|
20
|
+
): Array<Record<"name" | "label", string>> {
|
|
21
|
+
return uniqBy(
|
|
22
|
+
filterData
|
|
23
|
+
.filter((filter) => !filter.active && filter.options.group)
|
|
24
|
+
.map((filter) => filter.options.group!),
|
|
25
|
+
"name"
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getAvailableFilters(
|
|
30
|
+
filterData: FilterData[]
|
|
31
|
+
): Array<Record<"name" | "label", string>> {
|
|
32
|
+
return sortBy(
|
|
33
|
+
[
|
|
34
|
+
...filterData.filter(
|
|
35
|
+
(filter) => !(filter.active || filter.options.group)
|
|
36
|
+
),
|
|
37
|
+
...getAvailableFilterGroups(filterData),
|
|
38
|
+
],
|
|
39
|
+
"label"
|
|
40
|
+
);
|
|
13
41
|
}
|
|
14
42
|
export function getActiveFilters(filterData: FilterData[]) {
|
|
15
43
|
return filterData.filter((filter) => filter.active);
|
|
@@ -107,15 +135,29 @@ export function change(
|
|
|
107
135
|
);
|
|
108
136
|
}
|
|
109
137
|
|
|
138
|
+
function getFilterOrGroup(filterData: FilterData[], name: string): FilterData {
|
|
139
|
+
let selectedFilter = filterData.find((filter) => filter.name === name);
|
|
140
|
+
|
|
141
|
+
if (!selectedFilter) {
|
|
142
|
+
selectedFilter = filterData.find(
|
|
143
|
+
(filter) => !filter.active && filter.options.group?.name === name
|
|
144
|
+
)!;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return selectedFilter;
|
|
148
|
+
}
|
|
149
|
+
|
|
110
150
|
export function toggle(filterData: FilterData[], name: string): FilterData[] {
|
|
111
|
-
const selectedFilter = filterData
|
|
151
|
+
const selectedFilter = getFilterOrGroup(filterData, name);
|
|
152
|
+
const { name: filterName } = selectedFilter;
|
|
153
|
+
|
|
112
154
|
const sortIndex = selectedFilter.active
|
|
113
155
|
? selectedFilter.sortIndex
|
|
114
156
|
: getActiveFilters(filterData).length;
|
|
115
157
|
const value = selectedFilter.active ? getDefaultValue(selectedFilter) : {};
|
|
116
158
|
|
|
117
159
|
return filterData.map((filter) =>
|
|
118
|
-
filter.name ===
|
|
160
|
+
filter.name === filterName
|
|
119
161
|
? {
|
|
120
162
|
...filter,
|
|
121
163
|
active: !filter.active,
|
|
@@ -148,3 +190,27 @@ export function toggleRange(
|
|
|
148
190
|
: filter
|
|
149
191
|
);
|
|
150
192
|
}
|
|
193
|
+
|
|
194
|
+
export function swap(
|
|
195
|
+
filterData: FilterData[],
|
|
196
|
+
previousFilterName: string,
|
|
197
|
+
nextFilterName: string
|
|
198
|
+
): FilterData[] {
|
|
199
|
+
const previousFilter = getFilterOrGroup(filterData, previousFilterName);
|
|
200
|
+
const nextFilter = getFilterOrGroup(filterData, nextFilterName);
|
|
201
|
+
|
|
202
|
+
return filterData.map((filter) =>
|
|
203
|
+
filter.name === previousFilter.name
|
|
204
|
+
? {
|
|
205
|
+
...filter,
|
|
206
|
+
active: false,
|
|
207
|
+
}
|
|
208
|
+
: filter.name === nextFilter.name
|
|
209
|
+
? {
|
|
210
|
+
...filter,
|
|
211
|
+
active: true,
|
|
212
|
+
sortIndex: previousFilter.sortIndex,
|
|
213
|
+
}
|
|
214
|
+
: filter
|
|
215
|
+
);
|
|
216
|
+
}
|
|
@@ -5,6 +5,7 @@ import MuiIconButton, {
|
|
|
5
5
|
import clsx from "clsx";
|
|
6
6
|
import React from "react";
|
|
7
7
|
|
|
8
|
+
import { UserInteraction } from "../../types/utils";
|
|
8
9
|
import useStyles from "./styles";
|
|
9
10
|
|
|
10
11
|
export type IconButtonProps<T extends React.ElementType = "button"> = Omit<
|
|
@@ -13,12 +14,20 @@ export type IconButtonProps<T extends React.ElementType = "button"> = Omit<
|
|
|
13
14
|
> & {
|
|
14
15
|
error?: boolean;
|
|
15
16
|
hoverOutline?: boolean;
|
|
17
|
+
state?: UserInteraction;
|
|
16
18
|
variant?: "primary" | "secondary";
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
export const IconButton: React.FC<IconButtonProps> = React.forwardRef(
|
|
20
22
|
(
|
|
21
|
-
{
|
|
23
|
+
{
|
|
24
|
+
className,
|
|
25
|
+
error,
|
|
26
|
+
hoverOutline = true,
|
|
27
|
+
variant = "primary",
|
|
28
|
+
state = "default",
|
|
29
|
+
...props
|
|
30
|
+
},
|
|
22
31
|
ref
|
|
23
32
|
) => {
|
|
24
33
|
const classes = useStyles();
|
|
@@ -29,6 +38,10 @@ export const IconButton: React.FC<IconButtonProps> = React.forwardRef(
|
|
|
29
38
|
ref={ref}
|
|
30
39
|
className={clsx(classes.secondary, className, {
|
|
31
40
|
[classes.hoverOutline]: hoverOutline && !props.disabled,
|
|
41
|
+
[classes.hover]: state === "hover" && !props.disabled,
|
|
42
|
+
[classes.active]: state === "active" && !props.disabled,
|
|
43
|
+
[classes.error]: error,
|
|
44
|
+
[classes.disabledError]: error && props.disabled,
|
|
32
45
|
})}
|
|
33
46
|
disableRipple
|
|
34
47
|
{...props}
|
|
@@ -39,7 +52,9 @@ export const IconButton: React.FC<IconButtonProps> = React.forwardRef(
|
|
|
39
52
|
return (
|
|
40
53
|
<MuiIconButton
|
|
41
54
|
ref={ref}
|
|
42
|
-
className={clsx(className, {
|
|
55
|
+
className={clsx(classes.primary, className, {
|
|
56
|
+
[classes.hover]: state === "hover" && !props.disabled,
|
|
57
|
+
[classes.active]: state === "active" && !props.disabled,
|
|
43
58
|
[classes.error]: error,
|
|
44
59
|
[classes.disabledError]: error && props.disabled,
|
|
45
60
|
})}
|
|
@@ -3,7 +3,7 @@ import type { SaleorThemeColors } from "..";
|
|
|
3
3
|
// Extracting it to separate file to avoid circular imports
|
|
4
4
|
export function getSecondaryButtonStyles(colors: SaleorThemeColors) {
|
|
5
5
|
return {
|
|
6
|
-
"&:hover, &.Mui-focusVisible": {
|
|
6
|
+
"&:hover, &.Mui-focusVisible, &$hover, &$active": {
|
|
7
7
|
color: colors.active[1],
|
|
8
8
|
},
|
|
9
9
|
"&:disabled": {
|
package/src/IconButton/styles.ts
CHANGED
|
@@ -3,17 +3,49 @@ import { getSecondaryButtonStyles } from "./partials";
|
|
|
3
3
|
|
|
4
4
|
const useStyles = makeStyles(
|
|
5
5
|
(theme) => ({
|
|
6
|
+
primary: {
|
|
7
|
+
"&:hover, &.Mui-focusVisible, &$hover, &$active": {
|
|
8
|
+
color: theme.palette.saleor.active[1],
|
|
9
|
+
borderColor: theme.palette.saleor.active[1],
|
|
10
|
+
},
|
|
11
|
+
"&:active, &$active": {
|
|
12
|
+
background: theme.palette.saleor.active[5],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
secondary: getSecondaryButtonStyles(theme.palette.saleor),
|
|
16
|
+
hoverOutline: {
|
|
17
|
+
"&$secondary": {
|
|
18
|
+
"&:hover, &:focus-visible, &$hover": {
|
|
19
|
+
background: theme.palette.saleor.active[5],
|
|
20
|
+
borderColor: theme.palette.saleor.active[4],
|
|
21
|
+
},
|
|
22
|
+
"&:active, &$active": {
|
|
23
|
+
background: theme.palette.saleor.active[4],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
6
27
|
error: {
|
|
7
|
-
"
|
|
8
|
-
"&:hover, &.Mui-focusVisible": {
|
|
28
|
+
"&&&": {
|
|
29
|
+
"&:hover, &.Mui-focusVisible, &$hover": {
|
|
9
30
|
borderColor: theme.palette.saleor.errorAction[1],
|
|
10
31
|
color: theme.palette.saleor.errorAction[1],
|
|
11
32
|
},
|
|
12
|
-
"&:active": {
|
|
33
|
+
"&:active, &$active": {
|
|
13
34
|
background: theme.palette.saleor.errorAction[5],
|
|
35
|
+
color: theme.palette.saleor.errorAction[1],
|
|
36
|
+
borderColor: theme.palette.saleor.errorAction[2],
|
|
37
|
+
},
|
|
38
|
+
"&$secondary": {
|
|
39
|
+
"&:hover, &.Mui-focusVisible, &$hover": {
|
|
40
|
+
background: theme.palette.saleor.errorAction[5],
|
|
41
|
+
},
|
|
42
|
+
"&:active, &$active": {
|
|
43
|
+
background: theme.palette.saleor.errorAction[4],
|
|
44
|
+
color: theme.palette.saleor.errorAction[1],
|
|
45
|
+
},
|
|
14
46
|
},
|
|
15
47
|
},
|
|
16
|
-
|
|
48
|
+
|
|
17
49
|
color: theme.palette.saleor.errorAction[2],
|
|
18
50
|
},
|
|
19
51
|
disabledError: {
|
|
@@ -22,18 +54,8 @@ const useStyles = makeStyles(
|
|
|
22
54
|
color: theme.palette.saleor.errorAction[5],
|
|
23
55
|
},
|
|
24
56
|
},
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"&$secondary": {
|
|
28
|
-
"&:hover,&:focus-visible": {
|
|
29
|
-
background: theme.palette.saleor.active[5],
|
|
30
|
-
borderColor: theme.palette.saleor.active[4],
|
|
31
|
-
},
|
|
32
|
-
"&:active": {
|
|
33
|
-
background: theme.palette.saleor.active[4],
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
},
|
|
57
|
+
active: {},
|
|
58
|
+
hover: {},
|
|
37
59
|
}),
|
|
38
60
|
{
|
|
39
61
|
name: "IconButton",
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { MenuItem } from "@material-ui/core";
|
|
2
|
+
import { Meta, Story } from "@storybook/react";
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
import { Decorator, GuideDecorator } from "../utils/Decorator";
|
|
6
|
+
import { useMockAutocomplete } from "../utils/useMockAutocomplete";
|
|
7
|
+
import { choices } from "./fixtures";
|
|
8
|
+
import { MultipleValueAutocomplete } from "./MultipleValueAutocomplete";
|
|
9
|
+
|
|
10
|
+
export const Default: Story = () => {
|
|
11
|
+
const { results, search } = useMockAutocomplete(choices);
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<MultipleValueAutocomplete
|
|
15
|
+
fullWidth
|
|
16
|
+
choices={results}
|
|
17
|
+
label="Employees of the month"
|
|
18
|
+
onInputChange={search}
|
|
19
|
+
onChange={console.log}
|
|
20
|
+
>
|
|
21
|
+
{({ choices, getItemProps }) =>
|
|
22
|
+
choices.map((choice, choiceIndex) => (
|
|
23
|
+
<MenuItem {...getItemProps({ item: choice, index: choiceIndex })}>
|
|
24
|
+
{choice.label}
|
|
25
|
+
</MenuItem>
|
|
26
|
+
))
|
|
27
|
+
}
|
|
28
|
+
</MultipleValueAutocomplete>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const Loading: Story = () => (
|
|
33
|
+
<MultipleValueAutocomplete
|
|
34
|
+
fullWidth
|
|
35
|
+
choices={[]}
|
|
36
|
+
label="Employees of the month"
|
|
37
|
+
loading
|
|
38
|
+
>
|
|
39
|
+
{({ choices, getItemProps }) =>
|
|
40
|
+
choices.map((choice, choiceIndex) => (
|
|
41
|
+
<MenuItem {...getItemProps({ item: choice, index: choiceIndex })}>
|
|
42
|
+
{choice.label}
|
|
43
|
+
</MenuItem>
|
|
44
|
+
))
|
|
45
|
+
}
|
|
46
|
+
</MultipleValueAutocomplete>
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export const WithInitialState: Story = () => {
|
|
50
|
+
const { results, search, more } = useMockAutocomplete(choices);
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<MultipleValueAutocomplete
|
|
54
|
+
fullWidth
|
|
55
|
+
choices={results}
|
|
56
|
+
label="Employees of the month"
|
|
57
|
+
onInputChange={search}
|
|
58
|
+
initialValue={[results[1], results[4]]}
|
|
59
|
+
onScrollToBottom={more}
|
|
60
|
+
onChange={console.log}
|
|
61
|
+
>
|
|
62
|
+
{({ choices, getItemProps }) =>
|
|
63
|
+
choices.map((choice, choiceIndex) => (
|
|
64
|
+
<MenuItem {...getItemProps({ item: choice, index: choiceIndex })}>
|
|
65
|
+
{choice.label}
|
|
66
|
+
</MenuItem>
|
|
67
|
+
))
|
|
68
|
+
}
|
|
69
|
+
</MultipleValueAutocomplete>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default {
|
|
74
|
+
decorators: [Decorator, GuideDecorator],
|
|
75
|
+
title: "Autocomplete / Multiple choices",
|
|
76
|
+
} as Meta;
|