@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.
Files changed (118) hide show
  1. package/README.md +20 -0
  2. package/dist/cjs/index.js +2 -2
  3. package/dist/cjs/index.js.map +3 -3
  4. package/dist/esm/index.js +2 -2
  5. package/dist/esm/index.js.map +3 -3
  6. package/dist/types/ActionBar/ActionBar.d.ts +1 -0
  7. package/dist/types/ActionBar/context.d.ts +6 -3
  8. package/dist/types/Autocomplete/Autocomplete.d.ts +23 -0
  9. package/dist/types/Autocomplete/Autocomplete.stories.d.ts +5 -0
  10. package/dist/types/Autocomplete/fixtures.d.ts +4 -0
  11. package/dist/types/Autocomplete/index.d.ts +1 -0
  12. package/dist/types/Autocomplete/styles.d.ts +2 -0
  13. package/dist/types/Chip/Chip.d.ts +8 -0
  14. package/dist/types/Chip/ChipAdornment.d.ts +6 -0
  15. package/dist/types/Chip/ChipMovable.d.ts +5 -0
  16. package/dist/types/Chip/ChipRemovable.d.ts +6 -0
  17. package/dist/types/Chip/ChipSwatch.d.ts +7 -0
  18. package/dist/types/Chip/index.d.ts +5 -0
  19. package/dist/types/Chip/private/ColorSwatch.d.ts +6 -0
  20. package/dist/types/Chip/styles.d.ts +2 -0
  21. package/dist/types/CircleIndicator/index.d.ts +1 -1
  22. package/dist/types/Filter/FilterField/AutocompleteFilterField.d.ts +6 -0
  23. package/dist/types/Filter/FilterField/MultipleValueAutocompleteFilterField.d.ts +6 -0
  24. package/dist/types/Filter/stories/Filter.stories.d.ts +5 -0
  25. package/dist/types/Filter/stories/FilterInteractive.stories.d.ts +4 -0
  26. package/dist/types/Filter/stories/labels.d.ts +8 -0
  27. package/dist/types/Filter/styles.d.ts +1 -1
  28. package/dist/types/Filter/types.d.ts +8 -2
  29. package/dist/types/Filter/utils.d.ts +4 -1
  30. package/dist/types/IconButton/IconButton.d.ts +2 -0
  31. package/dist/types/IconButton/partials.d.ts +1 -1
  32. package/dist/types/IconButton/styles.d.ts +1 -1
  33. package/dist/types/MultipleValueAutocomplete/MultipleValueAutocomplete.d.ts +26 -0
  34. package/dist/types/MultipleValueAutocomplete/MultipleValueAutocomplete.stories.d.ts +6 -0
  35. package/dist/types/MultipleValueAutocomplete/fixtures.d.ts +4 -0
  36. package/dist/types/MultipleValueAutocomplete/index.d.ts +1 -0
  37. package/dist/types/MultipleValueAutocomplete/styles.d.ts +2 -0
  38. package/dist/types/MultipleValueAutocomplete/useMultipleValueAutocomplete.d.ts +32 -0
  39. package/dist/types/Savebar/Savebar.d.ts +1 -0
  40. package/dist/types/Sidebar/MenuItem.d.ts +9 -3
  41. package/dist/types/Sidebar/types.d.ts +8 -0
  42. package/dist/types/Sidebar/utils.d.ts +12 -0
  43. package/dist/types/SidebarDrawer/MenuItemBtn.d.ts +2 -1
  44. package/dist/types/SwitchSelector/SwitchSelector.d.ts +2 -0
  45. package/dist/types/SwitchSelector/SwitchSelector.stories.d.ts +4 -0
  46. package/dist/types/SwitchSelector/SwitchSelectorButton.d.ts +8 -0
  47. package/dist/types/SwitchSelector/index.d.ts +2 -0
  48. package/dist/types/index.d.ts +3 -0
  49. package/dist/types/theme/ThemeProvider.d.ts +4 -0
  50. package/dist/types/theme/types.d.ts +1 -0
  51. package/dist/types/tools/useTextWidth.d.ts +2 -0
  52. package/dist/types/utils/guideStyles.d.ts +1 -1
  53. package/dist/types/utils/mergeRefs.d.ts +2 -0
  54. package/dist/types/utils/useMockAutocomplete.d.ts +10 -0
  55. package/package.json +11 -13
  56. package/src/ActionBar/ActionBar.tsx +8 -11
  57. package/src/ActionBar/context.tsx +15 -6
  58. package/src/ActionBar/styles.ts +1 -1
  59. package/src/Autocomplete/Autocomplete.stories.tsx +43 -0
  60. package/src/Autocomplete/Autocomplete.tsx +187 -0
  61. package/src/Autocomplete/fixtures.ts +122 -0
  62. package/src/Autocomplete/index.ts +1 -0
  63. package/src/Autocomplete/styles.ts +19 -0
  64. package/src/Backlink/Backlink.tsx +3 -1
  65. package/src/Chip/Chip.tsx +52 -0
  66. package/src/Chip/ChipAdornment.tsx +53 -0
  67. package/src/Chip/ChipMovable.tsx +40 -0
  68. package/src/Chip/ChipRemovable.tsx +29 -0
  69. package/src/Chip/ChipSwatch.tsx +42 -0
  70. package/src/Chip/index.ts +5 -0
  71. package/src/Chip/private/ColorSwatch.tsx +21 -0
  72. package/src/Chip/styles.ts +46 -0
  73. package/src/CircleIndicator/CircleIndicator.stories.tsx +6 -6
  74. package/src/CircleIndicator/index.ts +1 -1
  75. package/src/Filter/Filter.tsx +88 -44
  76. package/src/Filter/FilterBar.tsx +15 -9
  77. package/src/Filter/FilterContent.tsx +8 -1
  78. package/src/Filter/FilterField/AutocompleteFilterField.tsx +61 -0
  79. package/src/Filter/FilterField/MultipleSelectFilterField.tsx +9 -3
  80. package/src/Filter/FilterField/MultipleValueAutocompleteFilterField.tsx +60 -0
  81. package/src/Filter/context.tsx +1 -1
  82. package/src/Filter/{Filter.stories.tsx → stories/Filter.stories.tsx} +47 -13
  83. package/src/Filter/stories/FilterInteractive.stories.tsx +97 -0
  84. package/src/Filter/stories/labels.ts +8 -0
  85. package/src/Filter/styles.ts +37 -6
  86. package/src/Filter/types.ts +8 -1
  87. package/src/Filter/utils.ts +71 -5
  88. package/src/IconButton/IconButton.tsx +17 -2
  89. package/src/IconButton/partials.ts +1 -1
  90. package/src/IconButton/styles.ts +38 -16
  91. package/src/MultipleValueAutocomplete/MultipleValueAutocomplete.stories.tsx +76 -0
  92. package/src/MultipleValueAutocomplete/MultipleValueAutocomplete.tsx +185 -0
  93. package/src/MultipleValueAutocomplete/fixtures.ts +122 -0
  94. package/src/MultipleValueAutocomplete/index.ts +1 -0
  95. package/src/MultipleValueAutocomplete/styles.ts +39 -0
  96. package/src/MultipleValueAutocomplete/useMultipleValueAutocomplete.ts +172 -0
  97. package/src/Savebar/Savebar.tsx +3 -4
  98. package/src/Sidebar/MenuItem.tsx +35 -14
  99. package/src/Sidebar/Sidebar.tsx +27 -11
  100. package/src/Sidebar/types.ts +9 -0
  101. package/src/Sidebar/utils.ts +23 -0
  102. package/src/SidebarDrawer/MenuItemBtn.tsx +12 -6
  103. package/src/SidebarDrawer/SidebarDrawer.tsx +8 -2
  104. package/src/SwitchSelector/SwitchSelector.stories.tsx +63 -0
  105. package/src/SwitchSelector/SwitchSelector.tsx +19 -0
  106. package/src/SwitchSelector/SwitchSelectorButton.tsx +59 -0
  107. package/src/SwitchSelector/index.ts +2 -0
  108. package/src/index.tsx +4 -1
  109. package/src/theme/ThemeProvider.tsx +6 -0
  110. package/src/theme/createSaleorTheme/createSaleorTheme.tsx +2 -1
  111. package/src/theme/createSaleorTheme/overrides/controls.ts +4 -1
  112. package/src/theme/createSaleorTheme/overrides/inputs.ts +1 -1
  113. package/src/theme/themes.ts +1 -1
  114. package/src/theme/types.ts +1 -0
  115. package/src/tools/useTextWidth.ts +20 -0
  116. package/src/utils/guideStyles.ts +5 -0
  117. package/src/utils/mergeRefs.ts +14 -0
  118. 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 "./Filter";
6
- import { FilterBar } from "./FilterBar";
7
- import { FilterType } from "./types";
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;
@@ -0,0 +1,8 @@
1
+ export const labels = {
2
+ addButton: "Add Filter",
3
+ header: "Filters",
4
+ where: "Where",
5
+ and: "and",
6
+ is: "is",
7
+ range: "between",
8
+ };
@@ -14,11 +14,16 @@ const useStyles = makeStyles(
14
14
  },
15
15
 
16
16
  filter: {
17
- alignItems: "center",
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
- columnGap: theme.spacing(1),
34
+ flexWrap: "wrap",
35
+ gap: theme.spacing(1),
30
36
  },
31
- filterDelete: {
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
- height: 51,
39
- width: 400,
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: 600,
93
+ minWidth: 100,
94
+ },
95
+ barAddBtn: {
96
+ "& svg": {
97
+ marginLeft: theme.spacing(1),
98
+ marginRight: 0,
99
+ },
69
100
  },
70
101
 
71
102
  selectPaper: {
@@ -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?: Array<Record<"label" | "value", string>>;
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[],
@@ -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 getAvailableFilters(filterData: FilterData[]) {
12
- return filterData.filter((filter) => !filter.active);
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.find((filter) => filter.name === name)!;
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 === 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
- { className, error, hoverOutline = true, variant = "primary", ...props },
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": {
@@ -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
- borderColor: theme.palette.saleor.errorAction[4],
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
- secondary: getSecondaryButtonStyles(theme.palette.saleor),
26
- hoverOutline: {
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;