@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@availity/mui-spaces",
3
- "version": "0.3.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, NavigateTopIcon } from '@availity/mui-icon';
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('DIV');
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-colorDefault')).toBeTruthy();
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')).toContain('/public/apps/home/#!/loadApp?appUrl=%2Fpath%2Fto%2Furl');
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(<NavigateTopIcon data-testid="icon" />);
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, CardHeader } from '@availity/mui-card';
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, Chip } from '@availity/mui-chip';
6
+ import { StatusChip } from '@availity/mui-chip';
7
7
  import { CircularProgress } from '@availity/mui-progress';
8
- import { Link } from '@availity/mui-link';
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 = (propTag: string | undefined, variant: SpacesLinkVariants) => {
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 = (propTag: string | undefined, variant: SpacesLinkVariants) => {
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 = (propTag: string | undefined, variant: SpacesLinkVariants) => {
31
- if (variant && variant !== 'default') return { card: CardHeader, list: Typography }[variant];
32
- return propTag || 'div';
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 = (propTag: string | undefined, variant: SpacesLinkVariants) => {
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
- <FavoriteHeart
83
- id={`${idPrefix}${linkSpace?.configurationId}`}
84
- name={linkSpace?.name}
85
- onChange={(_, e) => e.stopPropagation()}
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
- <Grid textAlign={stacked ? 'center' : 'inherit'}>
114
+ <DateInfo textAlign={stacked ? 'center' : 'right'}>
95
115
  {showNew && linkSpace?.isNew && (
96
- <Chip id={`${idPrefix}app-new-badge-${linkSpace?.configurationId}`} label="New!" />
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
- </Grid>
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)) ? 2 : undefined}
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
- <Tag
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 alignItems={!showDescription || stacked ? 'center' : 'start'} direction={stacked ? 'column' : 'row'}>
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
- {icon && linkSpace?.url && linkSpace?.type?.toUpperCase() === 'FILE' ? (
179
- <Link target="_blank" href={linkSpace?.url}>
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
- </Link>
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
- marginTop={1}
220
- textAlign={stacked ? 'center' : undefined}
221
- overflow="hidden"
222
- whiteSpace={maxDescriptionWidth ? 'nowrap' : undefined}
223
- width={maxDescriptionWidth}
224
- textOverflow="ellipsis"
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 className="Card-text">{linkSpace?.description}</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
- </Tag>
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?: string;
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?: string;
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?: string;
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?: string;
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?: boolean;
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.
@@ -22,7 +22,7 @@ const buildSpacesLink = (space: Space | SsoTypeSpace, linkAttributes: Record<any
22
22
  space={space}
23
23
  linkAttributes={linkAttributes}
24
24
  clientId="my-client-id"
25
- linkStyle="card"
25
+ variant="card"
26
26
  title={space.link?.text}
27
27
  />
28
28
  </Spaces>