@availity/mui-link 0.2.9 → 0.4.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 CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [0.4.0](https://github.com/Availity/element/compare/@availity/mui-link@0.3.0...@availity/mui-link@0.4.0) (2024-06-10)
6
+
7
+
8
+ ### Features
9
+
10
+ * **mui-link:** allow link icon to display at the end ([f101b52](https://github.com/Availity/element/commit/f101b52edb293f16ee32fa942ec8e71675ee28c1))
11
+
12
+ ## [0.3.0](https://github.com/Availity/element/compare/@availity/mui-link@0.2.9...@availity/mui-link@0.3.0) (2024-05-02)
13
+
14
+
15
+ ### Features
16
+
17
+ * **mui-link:** inline link styles ([7ee4587](https://github.com/Availity/element/commit/7ee458780be5cbb5ca97595aa7bf8bb7e3c36423))
18
+
5
19
  ## [0.2.9](https://github.com/Availity/element/compare/@availity/mui-link@0.2.8...@availity/mui-link@0.2.9) (2024-04-19)
6
20
 
7
21
  ### Dependency Updates
package/dist/index.d.mts CHANGED
@@ -15,7 +15,11 @@ type LinkProps = {
15
15
  onClick?: (event: React.MouseEvent, url: string) => void;
16
16
  children?: ReactNode;
17
17
  rel?: string;
18
- } & Omit<LinkProps$1, 'underline' | 'noWrap' | 'variantMapping' | 'variant'>;
18
+ /** The position of the icon relative to the text when target is `_blank`
19
+ *
20
+ * @default 'start' */
21
+ iconPosition?: 'start' | 'end';
22
+ } & Omit<LinkProps$1, 'underline' | 'noWrap' | 'variantMapping'>;
19
23
  declare const Link: react.ForwardRefExoticComponent<Omit<LinkProps, "ref"> & react.RefAttributes<HTMLAnchorElement>>;
20
24
 
21
25
  export { Link, type LinkProps };
package/dist/index.d.ts CHANGED
@@ -15,7 +15,11 @@ type LinkProps = {
15
15
  onClick?: (event: React.MouseEvent, url: string) => void;
16
16
  children?: ReactNode;
17
17
  rel?: string;
18
- } & Omit<LinkProps$1, 'underline' | 'noWrap' | 'variantMapping' | 'variant'>;
18
+ /** The position of the icon relative to the text when target is `_blank`
19
+ *
20
+ * @default 'start' */
21
+ iconPosition?: 'start' | 'end';
22
+ } & Omit<LinkProps$1, 'underline' | 'noWrap' | 'variantMapping'>;
19
23
  declare const Link: react.ForwardRefExoticComponent<Omit<LinkProps, "ref"> & react.RefAttributes<HTMLAnchorElement>>;
20
24
 
21
25
  export { Link, type LinkProps };
package/dist/index.js CHANGED
@@ -94,25 +94,28 @@ var setRel = (url, target, absolute) => {
94
94
  return void 0;
95
95
  };
96
96
  var Link = (0, import_react.forwardRef)((props, ref) => {
97
- const _a = props, { href, target = "_self", children, onClick, loadApp = true, rel } = _a, rest = __objRest(_a, ["href", "target", "children", "onClick", "loadApp", "rel"]);
97
+ const _a = props, { href, target = "_self", children, onClick, loadApp = true, rel, iconPosition = "start" } = _a, rest = __objRest(_a, ["href", "target", "children", "onClick", "loadApp", "rel", "iconPosition"]);
98
98
  const absolute = isAbsoluteUrl(href);
99
99
  const encode = !(absolute || !loadApp);
100
100
  const url = encode ? getUrl(href) : href;
101
101
  const NewWindowIcon = target === "_blank" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_mui_icon.OpenInNewIcon, {}) : null;
102
+ const startIcon = iconPosition === "start";
103
+ const endIcon = iconPosition === "end";
102
104
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
103
105
  import_Link.default,
104
106
  __spreadProps(__spreadValues({
105
107
  href: url,
106
108
  target,
107
109
  onClick: (event) => onClick && onClick(event, url),
108
- rel: rel || setRel(url, target, absolute),
109
- underline: "hover"
110
+ rel: rel || setRel(url, target, absolute)
110
111
  }, rest), {
111
112
  ref,
112
113
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
114
+ startIcon && NewWindowIcon,
115
+ " ",
113
116
  children,
114
117
  " ",
115
- NewWindowIcon
118
+ endIcon && NewWindowIcon
116
119
  ] })
117
120
  })
118
121
  );
package/dist/index.mjs CHANGED
@@ -61,25 +61,28 @@ var setRel = (url, target, absolute) => {
61
61
  return void 0;
62
62
  };
63
63
  var Link = forwardRef((props, ref) => {
64
- const _a = props, { href, target = "_self", children, onClick, loadApp = true, rel } = _a, rest = __objRest(_a, ["href", "target", "children", "onClick", "loadApp", "rel"]);
64
+ const _a = props, { href, target = "_self", children, onClick, loadApp = true, rel, iconPosition = "start" } = _a, rest = __objRest(_a, ["href", "target", "children", "onClick", "loadApp", "rel", "iconPosition"]);
65
65
  const absolute = isAbsoluteUrl(href);
66
66
  const encode = !(absolute || !loadApp);
67
67
  const url = encode ? getUrl(href) : href;
68
68
  const NewWindowIcon = target === "_blank" ? /* @__PURE__ */ jsx(OpenInNewIcon, {}) : null;
69
+ const startIcon = iconPosition === "start";
70
+ const endIcon = iconPosition === "end";
69
71
  return /* @__PURE__ */ jsx(
70
72
  MuiLink,
71
73
  __spreadProps(__spreadValues({
72
74
  href: url,
73
75
  target,
74
76
  onClick: (event) => onClick && onClick(event, url),
75
- rel: rel || setRel(url, target, absolute),
76
- underline: "hover"
77
+ rel: rel || setRel(url, target, absolute)
77
78
  }, rest), {
78
79
  ref,
79
80
  children: /* @__PURE__ */ jsxs("span", { children: [
81
+ startIcon && NewWindowIcon,
82
+ " ",
80
83
  children,
81
84
  " ",
82
- NewWindowIcon
85
+ endIcon && NewWindowIcon
83
86
  ] })
84
87
  })
85
88
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@availity/mui-link",
3
- "version": "0.2.9",
3
+ "version": "0.4.0",
4
4
  "description": "Availity MUI Link Component - part of the @availity/element design system",
5
5
  "keywords": [
6
6
  "react",
@@ -3,6 +3,8 @@ import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { SystemPropsList } from '../../../../data/MuiSystemProperties';
4
4
  import { Link, LinkProps } from './Link';
5
5
 
6
+ const excludedProps = [...SystemPropsList, 'align'];
7
+
6
8
  /**
7
9
  * Simple link component that renders an `<a>` tag with the href formatted to leverage loadApp so the link gets loaded inside the home page's iframe
8
10
  *
@@ -15,12 +17,12 @@ const meta: Meta<typeof Link> = {
15
17
  parameters: {
16
18
  docs: {
17
19
  controls: {
18
- exclude: SystemPropsList,
20
+ exclude: excludedProps,
19
21
  },
20
22
  },
21
23
  canvas: {
22
24
  controls: {
23
- exclude: SystemPropsList,
25
+ exclude: excludedProps,
24
26
  },
25
27
  },
26
28
  },
@@ -39,6 +41,25 @@ export const _Link: StoryObj<typeof Link> = {
39
41
  },
40
42
  };
41
43
 
44
+ /** Inline styling is achieved with the `inherit` variant. */
45
+ export const _Variants: StoryObj<typeof Link> = {
46
+ render: () => (
47
+ <div>
48
+ <Link href="#" gutterBottom>
49
+ Medium standalone link (default)
50
+ </Link>
51
+ <br />
52
+ <Link href="#" gutterBottom variant="body2">
53
+ Small standalone link
54
+ </Link>
55
+ <br />
56
+ <Link href="#" gutterBottom variant="inherit">
57
+ Inline link
58
+ </Link>
59
+ </div>
60
+ ),
61
+ };
62
+
42
63
  /** The `OpenInNewIcon` has an accessible name to tell screenreaders that it opens in a new window. */
43
64
  export const _NewWindow: StoryObj<typeof Link> = {
44
65
  render: (args: LinkProps) => <Link {...args} loadApp={false} target="_blank" />,
@@ -47,6 +68,13 @@ export const _NewWindow: StoryObj<typeof Link> = {
47
68
  },
48
69
  };
49
70
 
71
+ export const _NewWindowEndIcon: StoryObj<typeof Link> = {
72
+ render: (args: LinkProps) => <Link {...args} loadApp={false} target="_blank" iconPosition="end" />,
73
+ args: {
74
+ children: 'Link opens in new window',
75
+ },
76
+ };
77
+
50
78
  export const _AbsoluteUrl: StoryObj<typeof Link> = {
51
79
  render: (args: LinkProps) => <Link {...args} href="https://github.com/Availity" target="_blank" />,
52
80
  args: {
@@ -61,3 +89,35 @@ export const _RelativeUrl: StoryObj<typeof Link> = {
61
89
  children: 'Portal App',
62
90
  },
63
91
  };
92
+
93
+ /** The `gutterBottom` prop achieves correct spacing for a list of links. */
94
+ export const _Lists: StoryObj<typeof Link> = {
95
+ render: () => (
96
+ <div>
97
+ <Link href="#" gutterBottom>
98
+ Link 1
99
+ </Link>
100
+ <br />
101
+ <Link href="#" gutterBottom>
102
+ Link 2
103
+ </Link>
104
+ <br />
105
+ <Link href="#" gutterBottom>
106
+ Link 3
107
+ </Link>
108
+ <br />
109
+ <Link href="#" gutterBottom>
110
+ Link 4
111
+ </Link>
112
+ <br />
113
+ <Link href="#" gutterBottom>
114
+ Link 5
115
+ </Link>
116
+ <br />
117
+ <Link href="#" gutterBottom>
118
+ Link 6
119
+ </Link>
120
+ <br />
121
+ </div>
122
+ ),
123
+ };
@@ -8,6 +8,42 @@ describe('Link', () => {
8
8
  expect(getByText('Test')).toBeTruthy();
9
9
  });
10
10
 
11
+ test('should render icon on left if no iconPosition passed', () => {
12
+ const { container } = render(
13
+ <Link target="_blank" href="#">
14
+ Test
15
+ </Link>
16
+ );
17
+
18
+ const spanChildren = container.getElementsByTagName('span')[0].children;
19
+
20
+ expect(spanChildren[0].tagName).toBe('svg');
21
+ });
22
+
23
+ test('should render icon on left if iconPosition is set to `start` passed', () => {
24
+ const { container } = render(
25
+ <Link target="_blank" href="#" iconPosition="start">
26
+ Test
27
+ </Link>
28
+ );
29
+
30
+ const spanChildren = container.getElementsByTagName('span')[0].children;
31
+
32
+ expect(spanChildren[0].tagName).toBe('svg');
33
+ });
34
+
35
+ test('should render icon on right if iconPosition is set to `end` passed', () => {
36
+ const { container } = render(
37
+ <Link target="_blank" href="#" iconPosition="end">
38
+ Test
39
+ </Link>
40
+ );
41
+
42
+ const spanChildren = container.getElementsByTagName('span')[0].children;
43
+
44
+ expect(spanChildren[spanChildren.length - 1].tagName).toBe('svg');
45
+ });
46
+
11
47
  test('should render absolute url', () => {
12
48
  const { getByRole } = render(<Link href="https://github.com/Availity">Test</Link>);
13
49
 
package/src/lib/Link.tsx CHANGED
@@ -53,14 +53,20 @@ export type LinkProps = {
53
53
  onClick?: (event: React.MouseEvent, url: string) => void;
54
54
  children?: ReactNode;
55
55
  rel?: string;
56
- } & Omit<MuiLinkProps, 'underline' | 'noWrap' | 'variantMapping' | 'variant'>;
56
+ /** The position of the icon relative to the text when target is `_blank`
57
+ *
58
+ * @default 'start' */
59
+ iconPosition?: 'start' | 'end';
60
+ } & Omit<MuiLinkProps, 'underline' | 'noWrap' | 'variantMapping'>;
57
61
 
58
62
  export const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
59
- const { href, target = '_self', children, onClick, loadApp = true, rel, ...rest } = props;
63
+ const { href, target = '_self', children, onClick, loadApp = true, rel, iconPosition = 'start', ...rest } = props;
60
64
  const absolute = isAbsoluteUrl(href);
61
65
  const encode = !(absolute || !loadApp);
62
66
  const url = encode ? getUrl(href) : href;
63
67
  const NewWindowIcon = target === '_blank' ? <OpenInNewIcon /> : null;
68
+ const startIcon = iconPosition === 'start';
69
+ const endIcon = iconPosition === 'end';
64
70
 
65
71
  return (
66
72
  <MuiLink
@@ -68,12 +74,11 @@ export const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
68
74
  target={target}
69
75
  onClick={(event: React.MouseEvent) => onClick && onClick(event, url)}
70
76
  rel={rel || setRel(url, target, absolute)}
71
- underline="hover"
72
77
  {...rest}
73
78
  ref={ref}
74
79
  >
75
80
  <span>
76
- {children} {NewWindowIcon}
81
+ {startIcon && NewWindowIcon} {children} {endIcon && NewWindowIcon}
77
82
  </span>
78
83
  </MuiLink>
79
84
  );