@availity/mui-spaces 0.3.3 → 0.3.5
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 +4 -0
- package/dist/index.d.mts +9 -13
- package/dist/index.d.ts +9 -13
- package/dist/index.js +153 -553
- package/dist/index.mjs +144 -548
- package/package.json +12 -1
- package/src/lib/SpacesLink/SpacesLink.test.tsx +6 -49
- package/src/lib/SpacesLink/SpacesLink.tsx +70 -38
- package/src/lib/SpacesLink/spaces-link-types.tsx +7 -5
- package/src/lib/SpacesLink/useLink.test.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@availity/mui-spaces",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Availity MUI Spaces Component - part of the @availity/element design system",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -33,11 +33,17 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@availity/mui-button": "^0.6.8",
|
|
36
|
+
"@availity/mui-card": "^0.2.15",
|
|
37
|
+
"@availity/mui-chip": "^0.2.15",
|
|
36
38
|
"@availity/mui-dialog": "^0.1.9",
|
|
37
39
|
"@availity/mui-disclaimer": "^0.1.2",
|
|
40
|
+
"@availity/mui-favorites": "^0.1.1",
|
|
38
41
|
"@availity/mui-icon": "^0.9.0",
|
|
39
42
|
"@availity/mui-layout": "^0.1.6",
|
|
43
|
+
"@availity/mui-list": "^0.1.6",
|
|
40
44
|
"@availity/mui-modal": "^0.1.5",
|
|
45
|
+
"@availity/mui-paper": "^0.1.9",
|
|
46
|
+
"@availity/mui-progress": "^0.1.9",
|
|
41
47
|
"@availity/mui-typography": "^0.2.0",
|
|
42
48
|
"@mui/material": "^5.15.15",
|
|
43
49
|
"react": "18.2.0",
|
|
@@ -47,11 +53,16 @@
|
|
|
47
53
|
},
|
|
48
54
|
"peerDependencies": {
|
|
49
55
|
"@availity/mui-button": "^0.6.8",
|
|
56
|
+
"@availity/mui-card": "^0.2.15",
|
|
57
|
+
"@availity/mui-chip": "^0.2.15",
|
|
50
58
|
"@availity/mui-dialog": "^0.1.9",
|
|
51
59
|
"@availity/mui-disclaimer": "^0.1.2",
|
|
60
|
+
"@availity/mui-favorites": "^0.1.1",
|
|
52
61
|
"@availity/mui-icon": "^0.9.0",
|
|
53
62
|
"@availity/mui-layout": "^0.1.6",
|
|
63
|
+
"@availity/mui-list": "^0.1.6",
|
|
54
64
|
"@availity/mui-modal": "^0.1.5",
|
|
65
|
+
"@availity/mui-progress": "^0.1.9",
|
|
55
66
|
"@availity/mui-typography": "^0.2.0",
|
|
56
67
|
"@mui/material": "^5.11.9",
|
|
57
68
|
"react": ">=16.3.0"
|
|
@@ -3,7 +3,7 @@ import dayjs from 'dayjs';
|
|
|
3
3
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
4
4
|
import { SpacesLink } from './SpacesLink';
|
|
5
5
|
import { Spaces } from '../Spaces';
|
|
6
|
-
import { FileIcon
|
|
6
|
+
import { FileIcon } from '@availity/mui-icon';
|
|
7
7
|
|
|
8
8
|
describe('SpacesLink', () => {
|
|
9
9
|
afterEach(() => {
|
|
@@ -53,7 +53,6 @@ describe('SpacesLink', () => {
|
|
|
53
53
|
expect(container.tagName).toBe('DIV');
|
|
54
54
|
|
|
55
55
|
const linkHeader = await waitFor(() => container.querySelector('#app-title-1'));
|
|
56
|
-
expect(linkHeader?.attributes.getNamedItem('variant')?.value).toBe('h6');
|
|
57
56
|
expect(linkHeader?.attributes.getNamedItem('role')?.value).toBe('link');
|
|
58
57
|
expect(linkHeader?.attributes.getNamedItem('data-av-analytics-application-id')?.value).toBe('1');
|
|
59
58
|
expect(linkHeader?.attributes.getNamedItem('data-av-analytics-action')?.value).toBe('click');
|
|
@@ -134,7 +133,7 @@ describe('SpacesLink', () => {
|
|
|
134
133
|
|
|
135
134
|
const link3_header = await waitFor(() => container.querySelector('#app-title-3'));
|
|
136
135
|
|
|
137
|
-
expect(link3_header?.tagName).toBe('
|
|
136
|
+
expect(link3_header?.tagName).toBe('A');
|
|
138
137
|
});
|
|
139
138
|
|
|
140
139
|
it('renders link card from space with custom title class', async () => {
|
|
@@ -207,7 +206,7 @@ describe('SpacesLink', () => {
|
|
|
207
206
|
|
|
208
207
|
const link7_newBadge = await waitFor(() => container.querySelector('#app-new-badge-7'));
|
|
209
208
|
|
|
210
|
-
expect(link7_newBadge?.className.includes('MuiChip-
|
|
209
|
+
expect(link7_newBadge?.className.includes('MuiChip-colorSecondary')).toBeTruthy();
|
|
211
210
|
expect(link7_newBadge?.textContent).toBe('New!');
|
|
212
211
|
});
|
|
213
212
|
|
|
@@ -539,7 +538,7 @@ describe('SpacesLink', () => {
|
|
|
539
538
|
<Spaces clientId="my-client-id" spaces={[space]}>
|
|
540
539
|
<SpacesLink
|
|
541
540
|
id="application-link-14"
|
|
542
|
-
icon
|
|
541
|
+
icon={FileIcon}
|
|
543
542
|
space={space}
|
|
544
543
|
linkAttributes={{
|
|
545
544
|
spaceId: '14',
|
|
@@ -553,52 +552,10 @@ describe('SpacesLink', () => {
|
|
|
553
552
|
);
|
|
554
553
|
|
|
555
554
|
const link = await waitFor(() => container.getElementsByTagName('a'));
|
|
556
|
-
expect(link[0]?.getAttribute('href')).
|
|
557
|
-
const icon = await waitFor(() => container.getElementsByTagName('svg')[1]);
|
|
558
|
-
|
|
559
|
-
const { container: testContainer } = render(<FileIcon data-testid="icon" />);
|
|
560
|
-
|
|
561
|
-
expect(icon).toStrictEqual(testContainer.getElementsByTagName('svg')[0]);
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
it('renders icon for non file type when icon is true', async () => {
|
|
565
|
-
const space = {
|
|
566
|
-
id: 'encoded14',
|
|
567
|
-
configurationId: '14',
|
|
568
|
-
type: 'LINK',
|
|
569
|
-
name: 'file with link',
|
|
570
|
-
url: '/path/to/url',
|
|
571
|
-
icons: {
|
|
572
|
-
navigation: 'desktop',
|
|
573
|
-
},
|
|
574
|
-
description: 'This is a file',
|
|
575
|
-
link: {
|
|
576
|
-
url: '/path/to/url',
|
|
577
|
-
text: 'title',
|
|
578
|
-
target: '_self',
|
|
579
|
-
},
|
|
580
|
-
};
|
|
581
|
-
const queryClient = new QueryClient();
|
|
582
|
-
const { container } = render(
|
|
583
|
-
<QueryClientProvider client={queryClient}>
|
|
584
|
-
<Spaces clientId="my-client-id" spaces={[space]}>
|
|
585
|
-
<SpacesLink
|
|
586
|
-
id="application-link-14"
|
|
587
|
-
space={space}
|
|
588
|
-
linkAttributes={{
|
|
589
|
-
spaceId: '14',
|
|
590
|
-
}}
|
|
591
|
-
role="listitem"
|
|
592
|
-
clientId="my-client-id"
|
|
593
|
-
title={space.link.text}
|
|
594
|
-
/>
|
|
595
|
-
</Spaces>
|
|
596
|
-
</QueryClientProvider>
|
|
597
|
-
);
|
|
598
|
-
|
|
555
|
+
expect(link[0]?.getAttribute('href')).toBe(space.url);
|
|
599
556
|
const icon = await waitFor(() => container.getElementsByTagName('svg')[0]);
|
|
600
557
|
|
|
601
|
-
const { container: testContainer } = render(<
|
|
558
|
+
const { container: testContainer } = render(<FileIcon data-testid="icon" />);
|
|
602
559
|
|
|
603
560
|
expect(icon).toStrictEqual(testContainer.getElementsByTagName('svg')[0]);
|
|
604
561
|
});
|
|
@@ -1,38 +1,56 @@
|
|
|
1
|
+
import { ElementType } from 'react';
|
|
1
2
|
import dayjs from 'dayjs';
|
|
2
|
-
import { Card, CardContent
|
|
3
|
+
import { Card, CardContent } from '@availity/mui-card';
|
|
3
4
|
import { Typography } from '@availity/mui-typography';
|
|
4
|
-
import { NavigateTopIcon, FileIcon } from '@availity/mui-icon';
|
|
5
5
|
import { useMemo, cloneElement } from 'react';
|
|
6
|
-
import { StatusChip
|
|
6
|
+
import { StatusChip } from '@availity/mui-chip';
|
|
7
7
|
import { CircularProgress } from '@availity/mui-progress';
|
|
8
|
-
import
|
|
8
|
+
import Link from '@mui/material/Link';
|
|
9
9
|
import { FavoriteHeart } from '@availity/mui-favorites';
|
|
10
10
|
import { Grid, Box } from '@availity/mui-layout';
|
|
11
11
|
import { ListItem, ListItemText } from '@availity/mui-list';
|
|
12
12
|
import ReactMarkdown from 'react-markdown';
|
|
13
|
+
import { styled } from '@mui/material/styles';
|
|
13
14
|
import { useSpacesContext } from '../Spaces';
|
|
14
15
|
import { useLink } from './useLink';
|
|
15
16
|
import type { SpacesLinkWithSpace, SpacesLinkWithSpaceId, SpacesLinkVariants } from './spaces-link-types';
|
|
16
17
|
import { isFunction } from '../helpers';
|
|
17
18
|
|
|
19
|
+
const SpacesLinkContainer = styled(Box, { name: 'AvSpacesLink', slot: 'root' })({});
|
|
20
|
+
const DateInfo = styled(Grid, { name: 'AvSpacesLink', slot: 'AvDateInfo' })({});
|
|
21
|
+
const SpacesLinkFavoriteHeart = styled(Grid, { name: 'AvSpacesLink', slot: 'AvFavoriteHeart' })({});
|
|
22
|
+
const IconLink = styled(Link, { name: 'AvSpacesLink', slot: 'IconLink' })({});
|
|
23
|
+
|
|
18
24
|
const getDisplayDate = (date: string | null | undefined) => dayjs(date).format('MM/DD/YYYY');
|
|
19
25
|
|
|
20
|
-
const getContainerTag = (
|
|
26
|
+
const getContainerTag = (
|
|
27
|
+
propTag: ElementType<any, keyof JSX.IntrinsicElements> | undefined,
|
|
28
|
+
variant: SpacesLinkVariants
|
|
29
|
+
) => {
|
|
21
30
|
if (variant && variant !== 'default') return { card: Card, list: ListItem }[variant];
|
|
22
31
|
return propTag || 'div';
|
|
23
32
|
};
|
|
24
33
|
|
|
25
|
-
const getBodyTag = (
|
|
34
|
+
const getBodyTag = (
|
|
35
|
+
propTag: ElementType<any, keyof JSX.IntrinsicElements> | undefined,
|
|
36
|
+
variant: SpacesLinkVariants
|
|
37
|
+
) => {
|
|
26
38
|
if (variant && variant !== 'default') return { card: CardContent, list: 'div' }[variant];
|
|
27
39
|
return propTag || 'div';
|
|
28
40
|
};
|
|
29
41
|
|
|
30
|
-
const getTitleTag = (
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
const getTitleTag = (
|
|
43
|
+
propTag: ElementType<any, keyof JSX.IntrinsicElements> | undefined,
|
|
44
|
+
variant: SpacesLinkVariants
|
|
45
|
+
) => {
|
|
46
|
+
if (variant && variant !== 'default') return Link;
|
|
47
|
+
return propTag || Link;
|
|
33
48
|
};
|
|
34
49
|
|
|
35
|
-
const getTextTag = (
|
|
50
|
+
const getTextTag = (
|
|
51
|
+
propTag: ElementType<any, keyof JSX.IntrinsicElements> | undefined,
|
|
52
|
+
variant: SpacesLinkVariants
|
|
53
|
+
) => {
|
|
36
54
|
if (variant && variant !== 'default') return { card: Typography, list: ListItemText }[variant];
|
|
37
55
|
return propTag || 'div';
|
|
38
56
|
};
|
|
@@ -43,7 +61,7 @@ export const SpacesLink = ({
|
|
|
43
61
|
className,
|
|
44
62
|
children,
|
|
45
63
|
favorite,
|
|
46
|
-
icon,
|
|
64
|
+
icon: FileIcon,
|
|
47
65
|
showName = true,
|
|
48
66
|
showNew,
|
|
49
67
|
showDate,
|
|
@@ -79,11 +97,13 @@ export const SpacesLink = ({
|
|
|
79
97
|
() =>
|
|
80
98
|
linkSpace?.configurationId &&
|
|
81
99
|
favorite && (
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
100
|
+
<SpacesLinkFavoriteHeart>
|
|
101
|
+
<FavoriteHeart
|
|
102
|
+
id={`${idPrefix}${linkSpace?.configurationId}`}
|
|
103
|
+
name={linkSpace?.name}
|
|
104
|
+
onChange={(_, e) => e.stopPropagation()}
|
|
105
|
+
/>
|
|
106
|
+
</SpacesLinkFavoriteHeart>
|
|
87
107
|
),
|
|
88
108
|
[favorite, linkSpace?.configurationId, linkSpace?.name, idPrefix]
|
|
89
109
|
);
|
|
@@ -91,9 +111,9 @@ export const SpacesLink = ({
|
|
|
91
111
|
const dateInfo = useMemo(
|
|
92
112
|
() =>
|
|
93
113
|
(showNew || showDate) && (
|
|
94
|
-
<
|
|
114
|
+
<DateInfo textAlign={stacked ? 'center' : 'right'}>
|
|
95
115
|
{showNew && linkSpace?.isNew && (
|
|
96
|
-
<
|
|
116
|
+
<StatusChip id={`${idPrefix}app-new-badge-${linkSpace?.configurationId}`} label="New!" color="secondary" />
|
|
97
117
|
)}
|
|
98
118
|
{showDate && (
|
|
99
119
|
<Typography
|
|
@@ -104,7 +124,7 @@ export const SpacesLink = ({
|
|
|
104
124
|
{getDisplayDate(linkSpace?.activeDate)}
|
|
105
125
|
</Typography>
|
|
106
126
|
)}
|
|
107
|
-
</
|
|
127
|
+
</DateInfo>
|
|
108
128
|
),
|
|
109
129
|
[linkSpace?.activeDate, linkSpace?.isNew, showDate, showNew, stacked, linkSpace?.configurationId, idPrefix]
|
|
110
130
|
);
|
|
@@ -114,7 +134,7 @@ export const SpacesLink = ({
|
|
|
114
134
|
customBadgeText && (
|
|
115
135
|
<Box
|
|
116
136
|
textAlign={stacked ? 'center' : 'inherit'}
|
|
117
|
-
marginRight={variant !== 'card' && (showDate || (showNew && linkSpace?.isNew)) ?
|
|
137
|
+
marginRight={variant !== 'card' && (showDate || (showNew && linkSpace?.isNew)) ? 1 : undefined}
|
|
118
138
|
>
|
|
119
139
|
<StatusChip
|
|
120
140
|
color={customBadgeColor || 'info'}
|
|
@@ -165,27 +185,36 @@ export const SpacesLink = ({
|
|
|
165
185
|
}
|
|
166
186
|
};
|
|
167
187
|
return (
|
|
168
|
-
<
|
|
188
|
+
<SpacesLinkContainer
|
|
189
|
+
component={Tag}
|
|
169
190
|
title={linkSpace?.name}
|
|
170
191
|
className={className}
|
|
171
192
|
{...rest}
|
|
172
193
|
style={{ ...style }}
|
|
173
194
|
role={variant === 'list' ? 'listitem' : role}
|
|
174
195
|
>
|
|
175
|
-
<BodyTag>
|
|
176
|
-
<Grid
|
|
196
|
+
<BodyTag style={{ width: '100%' }}>
|
|
197
|
+
<Grid
|
|
198
|
+
alignItems={!showDescription || stacked ? 'center' : 'start'}
|
|
199
|
+
direction={stacked ? 'column' : 'row'}
|
|
200
|
+
container
|
|
201
|
+
flexWrap="nowrap"
|
|
202
|
+
>
|
|
177
203
|
{!stacked && favoriteIcon}
|
|
178
|
-
{
|
|
179
|
-
<
|
|
204
|
+
{FileIcon && linkSpace?.url && linkSpace?.type?.toUpperCase() === 'FILE' ? (
|
|
205
|
+
<IconLink
|
|
206
|
+
target="_blank"
|
|
207
|
+
href={linkSpace?.url}
|
|
208
|
+
role="link"
|
|
209
|
+
aria-labelledby={`${idPrefix}app-title-${linkSpace?.configurationId}`}
|
|
210
|
+
>
|
|
180
211
|
<FileIcon data-testid="icon" />
|
|
181
|
-
</
|
|
182
|
-
) :
|
|
183
|
-
<NavigateTopIcon data-testid="icon" />
|
|
184
|
-
)}
|
|
212
|
+
</IconLink>
|
|
213
|
+
) : null}
|
|
185
214
|
{children
|
|
186
215
|
? renderChildren()
|
|
187
216
|
: body && (
|
|
188
|
-
<Grid id={`${idPrefix}${linkSpace?.type}-${linkSpace?.configurationId}`}>
|
|
217
|
+
<Grid id={`${idPrefix}${linkSpace?.type}-${linkSpace?.configurationId}`} flexGrow={1}>
|
|
189
218
|
<Box
|
|
190
219
|
marginBottom={!customBadgeDisplay && (!showDescription || !linkSpace?.description) ? 0 : undefined}
|
|
191
220
|
paddingTop={stacked ? 3 : undefined}
|
|
@@ -216,15 +245,18 @@ export const SpacesLink = ({
|
|
|
216
245
|
{stacked && dateInfo}
|
|
217
246
|
{showDescription && linkSpace?.description && (
|
|
218
247
|
<TextTag
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
248
|
+
component={'div'}
|
|
249
|
+
style={{
|
|
250
|
+
marginTop: '.5rem',
|
|
251
|
+
textAlign: stacked ? 'center' : undefined,
|
|
252
|
+
overflow: 'hidden',
|
|
253
|
+
whiteSpace: maxDescriptionWidth ? 'nowrap' : undefined,
|
|
254
|
+
width: maxDescriptionWidth,
|
|
255
|
+
textOverflow: 'ellipsis',
|
|
256
|
+
}}
|
|
225
257
|
id={`${idPrefix}app-description-${linkSpace?.configurationId}`}
|
|
226
258
|
>
|
|
227
|
-
<ReactMarkdown
|
|
259
|
+
<ReactMarkdown>{linkSpace?.description}</ReactMarkdown>
|
|
228
260
|
</TextTag>
|
|
229
261
|
)}
|
|
230
262
|
{variant === 'card' && customBadgeDisplay}
|
|
@@ -234,6 +266,6 @@ export const SpacesLink = ({
|
|
|
234
266
|
{!stacked && dateInfo}
|
|
235
267
|
</Grid>
|
|
236
268
|
</BodyTag>
|
|
237
|
-
</
|
|
269
|
+
</SpacesLinkContainer>
|
|
238
270
|
);
|
|
239
271
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { StatusChipProps } from '@availity/mui-chip';
|
|
2
2
|
import type { Space } from '../spaces-types';
|
|
3
|
+
import { ElementType } from 'react';
|
|
4
|
+
import { SvgIconProps } from '@mui/material';
|
|
3
5
|
|
|
4
6
|
export type SpacesLinkVariants = 'card' | 'list' | 'default' | undefined;
|
|
5
7
|
|
|
@@ -31,24 +33,24 @@ export type SpacesLinkProps = {
|
|
|
31
33
|
/** Children can be a react child or render prop. */
|
|
32
34
|
children?: JSX.Element | ((props: any | undefined) => JSX.Element);
|
|
33
35
|
/** Tag to overwrite the root component rendered. */
|
|
34
|
-
tag?:
|
|
36
|
+
tag?: ElementType<any, keyof JSX.IntrinsicElements>;
|
|
35
37
|
/** Tag to overwrite the body component that renders the title, description and data values.
|
|
36
38
|
* It defaults to CardBody or div depending on the value of the variant prop.
|
|
37
39
|
*/
|
|
38
|
-
bodyTag?:
|
|
40
|
+
bodyTag?: ElementType<any, keyof JSX.IntrinsicElements>;
|
|
39
41
|
/** Tag to overwrite the title component. If variant prop is set to "card", defaults to CardTitle.
|
|
40
42
|
* If variant is set to "list", defaults to ListItemHeading. Overwise, defaults to div.
|
|
41
43
|
*/
|
|
42
|
-
titleTag?:
|
|
44
|
+
titleTag?: ElementType<any, keyof JSX.IntrinsicElements>;
|
|
43
45
|
/** Tag to overwrite the text component. If variant prop is set to "card", defaults to Card Text.
|
|
44
46
|
* If variant is set to "list", defaults to ListItemText. Otherwise, defaults to div.
|
|
45
47
|
*/
|
|
46
|
-
textTag?:
|
|
48
|
+
textTag?: ElementType<any, keyof JSX.IntrinsicElements>;
|
|
47
49
|
titleClassName?: string;
|
|
48
50
|
/** When true, utilizes the Card component for styling. */
|
|
49
51
|
card?: boolean;
|
|
50
52
|
/** When true, renders an @availity/mui-icon next to the title if present on the Space. */
|
|
51
|
-
icon?:
|
|
53
|
+
icon?: (props: SvgIconProps) => JSX.Element;
|
|
52
54
|
/** When true, renders the Spaces description beneath the title. */
|
|
53
55
|
description?: boolean;
|
|
54
56
|
/** When passed in, provides predefined styles for the component.
|