@availity/mui-favorites 0.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.
- package/CHANGELOG.md +15 -0
- package/README.md +59 -0
- package/dist/index.d.mts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +356 -0
- package/dist/index.mjs +320 -0
- package/introduction.stories.mdx +7 -0
- package/jest.config.js +7 -0
- package/package.json +59 -0
- package/project.json +41 -0
- package/src/index.ts +2 -0
- package/src/lib/FavoriteHeart.tsx +133 -0
- package/src/lib/Favorites.stories.tsx +43 -0
- package/src/lib/Favorites.test.tsx +273 -0
- package/src/lib/Favorites.tsx +168 -0
- package/src/lib/constants.tsx +9 -0
- package/src/lib/utils.ts +61 -0
- package/tsconfig.json +5 -0
- package/tsconfig.spec.json +10 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
|
+
|
|
5
|
+
## 0.1.0 (2024-06-27)
|
|
6
|
+
|
|
7
|
+
### Dependency Updates
|
|
8
|
+
|
|
9
|
+
* `mui-icon` updated to version `0.1.0`
|
|
10
|
+
* `mui-progress` updated to version `0.1.0`
|
|
11
|
+
* `mui-tooltip` updated to version `0.1.0`
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **mui-favorites:** init commit ([9cab4fa](https://github.com/Availity/element/commit/9cab4fab7f8611407d12042f6ad60a4b247dcad9))
|
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @availity/mui-favorites
|
|
2
|
+
|
|
3
|
+
> Availity MUI Favorites component to be used with @availity/element design system.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@availity/mui-favorites)
|
|
6
|
+
[](https://www.npmjs.com/package/@availity/mui-favorites)
|
|
7
|
+
[](https://github.com/Availity/element/blob/main/packages/mui-favorites/package.json)
|
|
8
|
+
|
|
9
|
+
## Documentation
|
|
10
|
+
|
|
11
|
+
Live demo and documentation in our [Storybook](https://availity.github.io/element/?path=/docs/components-favorites-introduction--docs)
|
|
12
|
+
|
|
13
|
+
Availity standards for design and usage can be found in the [Availity Design Guide](https://zeroheight.com/2e36e50c7)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### Import Through @availity/element (Recommended)
|
|
18
|
+
|
|
19
|
+
#### NPM
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @availity/element
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
#### Yarn
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
yarn add @availity/element
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Direct Import
|
|
32
|
+
|
|
33
|
+
#### NPM
|
|
34
|
+
|
|
35
|
+
_This package has a few peer dependencies. Add `@mui/material` & `@emotion/react` to your project if not already installed._
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install @availity/mui-favorites
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
#### Yarn
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
yarn add @availity/mui-favorites
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Usage
|
|
48
|
+
|
|
49
|
+
#### Import through @availity/element
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { FavoritesProvider, FavoriteHeart, useFavorites } from '@availity/element';
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### Direct import
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { FavoritesProvider, FavoriteHeart, useFavorites } from '@availity/mui-favorites';
|
|
59
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React$1 from 'react';
|
|
2
|
+
|
|
3
|
+
type Favorite = {
|
|
4
|
+
id: string;
|
|
5
|
+
pos: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
declare const FavoritesProvider: ({ children, onFavoritesChange, }: {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
onFavoritesChange?: (favorites: Favorite[]) => void;
|
|
11
|
+
}) => JSX.Element;
|
|
12
|
+
type MergedStatusUnion = 'initLoading' | 'reloading' | 'error' | 'success';
|
|
13
|
+
declare const useFavorites: (id: string) => {
|
|
14
|
+
isFavorited: boolean;
|
|
15
|
+
status: MergedStatusUnion;
|
|
16
|
+
isLastClickedFavorite: boolean;
|
|
17
|
+
toggleFavorite: () => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type FavoriteHeartProps = {
|
|
21
|
+
/** The configuration's id */
|
|
22
|
+
id: string;
|
|
23
|
+
/** The name of the configuration */
|
|
24
|
+
name: string;
|
|
25
|
+
/** What to do on Favorite Toggle */
|
|
26
|
+
onChange?: (isFavorited: boolean, event: React$1.ChangeEvent<HTMLInputElement> | React$1.KeyboardEvent<HTMLInputElement>) => void;
|
|
27
|
+
/** What to do on click */
|
|
28
|
+
onMouseDown?: (event: React$1.MouseEvent<HTMLInputElement, MouseEvent>) => void;
|
|
29
|
+
/** Whether or not the Favorite is disabled
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
};
|
|
34
|
+
declare const FavoriteHeart: ({ id, name, onChange, onMouseDown, disabled, }: FavoriteHeartProps) => JSX.Element;
|
|
35
|
+
|
|
36
|
+
export { FavoriteHeart, FavoritesProvider, useFavorites };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React$1 from 'react';
|
|
2
|
+
|
|
3
|
+
type Favorite = {
|
|
4
|
+
id: string;
|
|
5
|
+
pos: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
declare const FavoritesProvider: ({ children, onFavoritesChange, }: {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
onFavoritesChange?: (favorites: Favorite[]) => void;
|
|
11
|
+
}) => JSX.Element;
|
|
12
|
+
type MergedStatusUnion = 'initLoading' | 'reloading' | 'error' | 'success';
|
|
13
|
+
declare const useFavorites: (id: string) => {
|
|
14
|
+
isFavorited: boolean;
|
|
15
|
+
status: MergedStatusUnion;
|
|
16
|
+
isLastClickedFavorite: boolean;
|
|
17
|
+
toggleFavorite: () => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type FavoriteHeartProps = {
|
|
21
|
+
/** The configuration's id */
|
|
22
|
+
id: string;
|
|
23
|
+
/** The name of the configuration */
|
|
24
|
+
name: string;
|
|
25
|
+
/** What to do on Favorite Toggle */
|
|
26
|
+
onChange?: (isFavorited: boolean, event: React$1.ChangeEvent<HTMLInputElement> | React$1.KeyboardEvent<HTMLInputElement>) => void;
|
|
27
|
+
/** What to do on click */
|
|
28
|
+
onMouseDown?: (event: React$1.MouseEvent<HTMLInputElement, MouseEvent>) => void;
|
|
29
|
+
/** Whether or not the Favorite is disabled
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
};
|
|
34
|
+
declare const FavoriteHeart: ({ id, name, onChange, onMouseDown, disabled, }: FavoriteHeartProps) => JSX.Element;
|
|
35
|
+
|
|
36
|
+
export { FavoriteHeart, FavoritesProvider, useFavorites };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __objRest = (source, exclude) => {
|
|
23
|
+
var target = {};
|
|
24
|
+
for (var prop in source)
|
|
25
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
26
|
+
target[prop] = source[prop];
|
|
27
|
+
if (source != null && __getOwnPropSymbols)
|
|
28
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
29
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
30
|
+
target[prop] = source[prop];
|
|
31
|
+
}
|
|
32
|
+
return target;
|
|
33
|
+
};
|
|
34
|
+
var __export = (target, all) => {
|
|
35
|
+
for (var name in all)
|
|
36
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
37
|
+
};
|
|
38
|
+
var __copyProps = (to, from, except, desc) => {
|
|
39
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
40
|
+
for (let key of __getOwnPropNames(from))
|
|
41
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
42
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
43
|
+
}
|
|
44
|
+
return to;
|
|
45
|
+
};
|
|
46
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
47
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
48
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
49
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
50
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
51
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
52
|
+
mod
|
|
53
|
+
));
|
|
54
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
55
|
+
var __async = (__this, __arguments, generator) => {
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
var fulfilled = (value) => {
|
|
58
|
+
try {
|
|
59
|
+
step(generator.next(value));
|
|
60
|
+
} catch (e) {
|
|
61
|
+
reject(e);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var rejected = (value) => {
|
|
65
|
+
try {
|
|
66
|
+
step(generator.throw(value));
|
|
67
|
+
} catch (e) {
|
|
68
|
+
reject(e);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
72
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// src/index.ts
|
|
77
|
+
var src_exports = {};
|
|
78
|
+
__export(src_exports, {
|
|
79
|
+
FavoriteHeart: () => FavoriteHeart,
|
|
80
|
+
FavoritesProvider: () => FavoritesProvider,
|
|
81
|
+
useFavorites: () => useFavorites
|
|
82
|
+
});
|
|
83
|
+
module.exports = __toCommonJS(src_exports);
|
|
84
|
+
|
|
85
|
+
// src/lib/Favorites.tsx
|
|
86
|
+
var import_react = require("react");
|
|
87
|
+
var import_react_query2 = require("@tanstack/react-query");
|
|
88
|
+
var import_message_core2 = __toESM(require("@availity/message-core"));
|
|
89
|
+
|
|
90
|
+
// src/lib/utils.ts
|
|
91
|
+
var import_message_core = __toESM(require("@availity/message-core"));
|
|
92
|
+
var import_api_axios = require("@availity/api-axios");
|
|
93
|
+
var import_react_query = require("@tanstack/react-query");
|
|
94
|
+
|
|
95
|
+
// src/lib/constants.tsx
|
|
96
|
+
var MAX_FAVORITES = 60;
|
|
97
|
+
var NAV_APP_ID = "Gateway-AvNavigation";
|
|
98
|
+
var AV_INTERNAL_GLOBALS = {
|
|
99
|
+
FAVORITES_UPDATE: "av:favorites:update",
|
|
100
|
+
FAVORITES_CHANGED: "av:favorites:changed",
|
|
101
|
+
MAX_FAVORITES: "av:favorites:maxed",
|
|
102
|
+
MY_TOP_APPS_UPDATED: "av:topApps:updated"
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// src/lib/utils.ts
|
|
106
|
+
var isFavorite = (arg) => Boolean(typeof (arg == null ? void 0 : arg.id) === "string" && typeof (arg == null ? void 0 : arg.pos) === "number");
|
|
107
|
+
var validateFavorites = (unvalidatedFavorites) => {
|
|
108
|
+
const validatedFavorites = Array.isArray(unvalidatedFavorites) ? unvalidatedFavorites == null ? void 0 : unvalidatedFavorites.filter(isFavorite) : [];
|
|
109
|
+
return validatedFavorites;
|
|
110
|
+
};
|
|
111
|
+
var submit = (_0) => __async(void 0, [_0], function* ({ favorites, targetFavoriteId }) {
|
|
112
|
+
const response = yield import_api_axios.avSettingsApi.setApplication(NAV_APP_ID, { favorites });
|
|
113
|
+
return { favorites: response.data.favorites, targetFavoriteId };
|
|
114
|
+
});
|
|
115
|
+
var getFavorites = () => __async(void 0, null, function* () {
|
|
116
|
+
var _a, _b, _c;
|
|
117
|
+
const result = yield import_api_axios.avSettingsApi.getApplication(NAV_APP_ID);
|
|
118
|
+
const unvalidatedFavorites = (_c = (_b = (_a = result == null ? void 0 : result.data) == null ? void 0 : _a.settings) == null ? void 0 : _b[0]) == null ? void 0 : _c.favorites;
|
|
119
|
+
const validatedFavorites = validateFavorites(unvalidatedFavorites);
|
|
120
|
+
return validatedFavorites;
|
|
121
|
+
});
|
|
122
|
+
var useFavoritesQuery = () => (0, import_react_query.useQuery)(["favorites"], getFavorites);
|
|
123
|
+
var useSubmitFavorites = ({ onMutationStart }) => {
|
|
124
|
+
const queryClient = (0, import_react_query.useQueryClient)();
|
|
125
|
+
const _a = (0, import_react_query.useMutation)(submit, {
|
|
126
|
+
onMutate(variables) {
|
|
127
|
+
onMutationStart == null ? void 0 : onMutationStart(variables.targetFavoriteId);
|
|
128
|
+
},
|
|
129
|
+
onSuccess(data) {
|
|
130
|
+
queryClient.setQueryData(["favorites"], data.favorites);
|
|
131
|
+
}
|
|
132
|
+
}), { mutateAsync: submitFavorites } = _a, rest = __objRest(_a, ["mutateAsync"]);
|
|
133
|
+
return __spreadValues({ submitFavorites }, rest);
|
|
134
|
+
};
|
|
135
|
+
var sendUpdateMessage = (favorites) => {
|
|
136
|
+
import_message_core.default.send({ favorites, event: AV_INTERNAL_GLOBALS.FAVORITES_UPDATE });
|
|
137
|
+
};
|
|
138
|
+
var openMaxModal = () => import_message_core.default.send(AV_INTERNAL_GLOBALS.MAX_FAVORITES);
|
|
139
|
+
|
|
140
|
+
// src/lib/Favorites.tsx
|
|
141
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
142
|
+
var FavoritesContext = (0, import_react.createContext)(null);
|
|
143
|
+
var FavoritesProvider = ({
|
|
144
|
+
children,
|
|
145
|
+
onFavoritesChange
|
|
146
|
+
}) => {
|
|
147
|
+
const [lastClickedFavoriteId, setLastClickedFavoriteId] = (0, import_react.useState)("");
|
|
148
|
+
const queryClient = (0, import_react_query2.useQueryClient)();
|
|
149
|
+
const { data: favorites, status: queryStatus } = useFavoritesQuery();
|
|
150
|
+
const { submitFavorites, status: mutationStatus } = useSubmitFavorites({
|
|
151
|
+
onMutationStart(targetFavoriteId) {
|
|
152
|
+
setLastClickedFavoriteId(targetFavoriteId);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
(0, import_react.useEffect)(() => {
|
|
156
|
+
const unsubscribeFavoritesChanged = import_message_core2.default.subscribe(
|
|
157
|
+
AV_INTERNAL_GLOBALS.FAVORITES_CHANGED,
|
|
158
|
+
(data) => {
|
|
159
|
+
if (data == null ? void 0 : data.favorites) {
|
|
160
|
+
queryClient.setQueryData(["favorites"], data == null ? void 0 : data.favorites);
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
{ ignoreSameWindow: false }
|
|
164
|
+
);
|
|
165
|
+
const unsubscribeFavoritesUpdate = import_message_core2.default.subscribe(
|
|
166
|
+
AV_INTERNAL_GLOBALS.FAVORITES_UPDATE,
|
|
167
|
+
(data) => {
|
|
168
|
+
if (data == null ? void 0 : data.favorites) {
|
|
169
|
+
queryClient.setQueryData(["favorites"], data == null ? void 0 : data.favorites);
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
{ ignoreSameWindow: false }
|
|
173
|
+
);
|
|
174
|
+
return () => {
|
|
175
|
+
unsubscribeFavoritesChanged();
|
|
176
|
+
unsubscribeFavoritesUpdate();
|
|
177
|
+
};
|
|
178
|
+
}, [queryClient]);
|
|
179
|
+
const deleteFavorite = (id) => __async(void 0, null, function* () {
|
|
180
|
+
if (favorites) {
|
|
181
|
+
const response = yield submitFavorites({
|
|
182
|
+
favorites: favorites.filter((favorite) => favorite.id !== id),
|
|
183
|
+
targetFavoriteId: id
|
|
184
|
+
});
|
|
185
|
+
sendUpdateMessage(response.favorites);
|
|
186
|
+
onFavoritesChange == null ? void 0 : onFavoritesChange(response.favorites);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
const addFavorite = (id) => __async(void 0, null, function* () {
|
|
190
|
+
if (!favorites)
|
|
191
|
+
return false;
|
|
192
|
+
if (favorites.length >= MAX_FAVORITES) {
|
|
193
|
+
openMaxModal();
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
const maxFavorite = favorites.reduce((accum, fave) => {
|
|
197
|
+
if (!accum || fave.pos > accum.pos) {
|
|
198
|
+
accum = fave;
|
|
199
|
+
}
|
|
200
|
+
return accum;
|
|
201
|
+
}, null);
|
|
202
|
+
const newFavPos = maxFavorite ? maxFavorite.pos + 1 : 0;
|
|
203
|
+
const response = yield submitFavorites({
|
|
204
|
+
favorites: [...favorites, { id, pos: newFavPos }],
|
|
205
|
+
targetFavoriteId: id
|
|
206
|
+
});
|
|
207
|
+
sendUpdateMessage(response.favorites);
|
|
208
|
+
onFavoritesChange == null ? void 0 : onFavoritesChange(response.favorites);
|
|
209
|
+
const isFavorited = response.favorites.find((f) => f.id === id);
|
|
210
|
+
return !!isFavorited;
|
|
211
|
+
});
|
|
212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
213
|
+
FavoritesContext.Provider,
|
|
214
|
+
{
|
|
215
|
+
value: {
|
|
216
|
+
favorites,
|
|
217
|
+
queryStatus,
|
|
218
|
+
mutationStatus,
|
|
219
|
+
lastClickedFavoriteId,
|
|
220
|
+
deleteFavorite,
|
|
221
|
+
addFavorite
|
|
222
|
+
},
|
|
223
|
+
children
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
};
|
|
227
|
+
var noOp = () => {
|
|
228
|
+
};
|
|
229
|
+
var useFavorites = (id) => {
|
|
230
|
+
const context = (0, import_react.useContext)(FavoritesContext);
|
|
231
|
+
if (context === null) {
|
|
232
|
+
throw new Error("useFavorites must be used within a FavoritesProvider");
|
|
233
|
+
}
|
|
234
|
+
const { favorites, queryStatus, mutationStatus, lastClickedFavoriteId, deleteFavorite, addFavorite } = context;
|
|
235
|
+
const isLastClickedFavorite = lastClickedFavoriteId === id;
|
|
236
|
+
const isFavorited = (0, import_react.useMemo)(() => {
|
|
237
|
+
const fav = favorites == null ? void 0 : favorites.find((f) => f.id === id);
|
|
238
|
+
return !!fav;
|
|
239
|
+
}, [favorites, id]);
|
|
240
|
+
const toggleFavorite = () => isFavorited ? deleteFavorite(id) : addFavorite(id);
|
|
241
|
+
const isDisabled = queryStatus === "loading" || queryStatus === "idle" || mutationStatus === "loading";
|
|
242
|
+
let status = "initLoading";
|
|
243
|
+
if (queryStatus === "loading")
|
|
244
|
+
status = "initLoading";
|
|
245
|
+
if (mutationStatus === "loading")
|
|
246
|
+
status = "reloading";
|
|
247
|
+
if (queryStatus === "error" || mutationStatus === "error")
|
|
248
|
+
status = "error";
|
|
249
|
+
if (queryStatus === "success" && (mutationStatus === "success" || mutationStatus === "idle"))
|
|
250
|
+
status = "success";
|
|
251
|
+
return {
|
|
252
|
+
isFavorited,
|
|
253
|
+
status,
|
|
254
|
+
isLastClickedFavorite,
|
|
255
|
+
toggleFavorite: isDisabled ? noOp : toggleFavorite
|
|
256
|
+
};
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// src/lib/FavoriteHeart.tsx
|
|
260
|
+
var import_mui_tooltip = require("@availity/mui-tooltip");
|
|
261
|
+
var import_mui_icon = require("@availity/mui-icon");
|
|
262
|
+
var import_mui_progress = require("@availity/mui-progress");
|
|
263
|
+
var import_styles = require("@mui/material/styles");
|
|
264
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
265
|
+
var icons = {
|
|
266
|
+
spinner: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_progress.CircularProgress, { "aria-hidden": true, size: "small", loadingCaption: false }),
|
|
267
|
+
unknownDisabledHeart: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_icon.HeartIcon, { "aria-hidden": true, color: "disabled" }),
|
|
268
|
+
favoritedDisabledHeart: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_icon.HeartIcon, { "aria-hidden": true, color: "error", opacity: "0.6" }),
|
|
269
|
+
unfavoritedDisabledHeart: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_icon.HeartEmptyIcon, { "aria-hidden": true, color: "disabled", opacity: "0.6" }),
|
|
270
|
+
favoritedHeart: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_icon.HeartIcon, { "aria-hidden": true, color: "error" }),
|
|
271
|
+
unfavoritedHeart: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_icon.HeartEmptyIcon, { "aria-hidden": true, color: "secondary" })
|
|
272
|
+
};
|
|
273
|
+
var FavoriteHeartContainer = (0, import_styles.styled)("div", { name: "AvFavoriteHeart", slot: "root" })({});
|
|
274
|
+
var FavoriteInput = (0, import_styles.styled)("input", {
|
|
275
|
+
name: "AvFavoriteHeart",
|
|
276
|
+
slot: "input"
|
|
277
|
+
})({});
|
|
278
|
+
var FavoriteIcon = (0, import_styles.styled)("div", {
|
|
279
|
+
name: "AvFavoriteHeart",
|
|
280
|
+
slot: "icon"
|
|
281
|
+
})({});
|
|
282
|
+
var FavoriteHeart = ({
|
|
283
|
+
id,
|
|
284
|
+
name,
|
|
285
|
+
onChange,
|
|
286
|
+
onMouseDown,
|
|
287
|
+
disabled = false
|
|
288
|
+
}) => {
|
|
289
|
+
const { isFavorited, isLastClickedFavorite, status, toggleFavorite } = useFavorites(id);
|
|
290
|
+
const handleChange = (event) => {
|
|
291
|
+
onChange == null ? void 0 : onChange(isFavorited, event);
|
|
292
|
+
toggleFavorite();
|
|
293
|
+
};
|
|
294
|
+
const handleKeyPress = (event) => {
|
|
295
|
+
if (event.code === "Enter" || event.key === "Enter") {
|
|
296
|
+
onChange == null ? void 0 : onChange(isFavorited, event);
|
|
297
|
+
toggleFavorite();
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
const iconKey = (() => {
|
|
301
|
+
if (status === "initLoading")
|
|
302
|
+
return "unknownDisabledHeart";
|
|
303
|
+
if (status === "reloading") {
|
|
304
|
+
if (isLastClickedFavorite)
|
|
305
|
+
return "spinner";
|
|
306
|
+
return isFavorited ? "favoritedDisabledHeart" : "unfavoritedDisabledHeart";
|
|
307
|
+
}
|
|
308
|
+
if (disabled) {
|
|
309
|
+
return isFavorited ? "favoritedDisabledHeart" : "unfavoritedDisabledHeart";
|
|
310
|
+
}
|
|
311
|
+
if (isFavorited)
|
|
312
|
+
return "favoritedHeart";
|
|
313
|
+
return "unfavoritedHeart";
|
|
314
|
+
})();
|
|
315
|
+
const cursor = disabled || !isLastClickedFavorite && (status === "initLoading" || status === "reloading") ? "not-allowed" : void 0;
|
|
316
|
+
const tooltipContent = `${isFavorited ? "Remove from" : "Add to"} My Favorites`;
|
|
317
|
+
const favoriteInputProps = {
|
|
318
|
+
onKeyDown: handleKeyPress,
|
|
319
|
+
type: "checkbox",
|
|
320
|
+
"aria-label": `Favorite ${name}`,
|
|
321
|
+
id: `av-favorite-heart-${id}`,
|
|
322
|
+
disabled,
|
|
323
|
+
checked: isFavorited,
|
|
324
|
+
onChange: handleChange,
|
|
325
|
+
onMouseDown,
|
|
326
|
+
style: { cursor }
|
|
327
|
+
};
|
|
328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(FavoriteHeartContainer, { children: [
|
|
329
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FavoriteIcon, { children: icons[iconKey] }),
|
|
330
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
331
|
+
"span",
|
|
332
|
+
{
|
|
333
|
+
style: {
|
|
334
|
+
position: "absolute",
|
|
335
|
+
width: "1px",
|
|
336
|
+
height: "1px",
|
|
337
|
+
padding: 0,
|
|
338
|
+
margin: "-1px",
|
|
339
|
+
overflow: "hidden",
|
|
340
|
+
clip: "rect(0,0,0,0)",
|
|
341
|
+
whiteSpace: "nowrap",
|
|
342
|
+
border: 0
|
|
343
|
+
},
|
|
344
|
+
"aria-live": isLastClickedFavorite && (status === "reloading" || status === "error") ? "polite" : "off",
|
|
345
|
+
children: isLastClickedFavorite && status === "reloading" ? "Loading..." : isLastClickedFavorite && status === "error" ? "An error has occurred. Please try again." : ""
|
|
346
|
+
}
|
|
347
|
+
),
|
|
348
|
+
disabled ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FavoriteInput, __spreadValues({}, favoriteInputProps)) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_tooltip.Tooltip, { title: tooltipContent, placement: "top", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FavoriteInput, __spreadValues({}, favoriteInputProps)) })
|
|
349
|
+
] });
|
|
350
|
+
};
|
|
351
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
352
|
+
0 && (module.exports = {
|
|
353
|
+
FavoriteHeart,
|
|
354
|
+
FavoritesProvider,
|
|
355
|
+
useFavorites
|
|
356
|
+
});
|