@availity/mui-link 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 ADDED
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
+
5
+ ## 0.1.0 (2023-06-05)
6
+
7
+
8
+ ### Features
9
+
10
+ * **mui-link:** add link package ([dbcf569](https://github.com/Availity/element/commit/dbcf569191cd0525b2c474eab0d2b487feb473ee))
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @availity/mui-link
2
+
3
+ > Availity MUI Link component to be used with @availity/element design system.
4
+
5
+ [![Version](https://img.shields.io/npm/v/@availity/mui-link.svg?style=for-the-badge)](https://www.npmjs.com/package/@availity/mui-link)
6
+ [![NPM Downloads](https://img.shields.io/npm/dt/@availity/mui-link.svg?style=for-the-badge)](https://www.npmjs.com/package/@availity/mui-link)
7
+ [![Dependency Status](https://img.shields.io/librariesio/release/npm/@availity/mui-link?style=for-the-badge)](https://github.com/Availity/element/blob/main/packages/mui-link/package.json)
8
+
9
+ ## Documentation
10
+
11
+ This package extends the MUI Link component: [MUI Link Docs](https://mui.com/components/link/)
12
+
13
+ Live demo and documentation in our [Storybook](https://availity.github.io/element/?path=/docs/components-link-introduction--docs)
14
+
15
+ Availity standards for design and usage can be found in the [Availity Design Guide](https://zeroheight.com/2e36e50c7)
16
+
17
+ ## Installation
18
+
19
+ ### Import Through @availity/element (Recommended)
20
+
21
+ #### NPM
22
+
23
+ ```bash
24
+ npm install @availity/element
25
+ ```
26
+
27
+ #### Yarn
28
+
29
+ ```bash
30
+ yarn add @availity/element
31
+ ```
32
+
33
+ ### Direct Import
34
+
35
+ _This package has a few peer dependencies. Install `@mui/material`, `@emotion/react`, & `@mui/system` if it is not in your application already._
36
+
37
+ #### NPM
38
+
39
+ ```bash
40
+ npm install @availity/mui-link
41
+ ```
42
+
43
+ #### Yarn
44
+
45
+ ```bash
46
+ yarn add @availity/mui-link
47
+ ```
48
+
49
+ ### Usage
50
+
51
+ #### Import through @availity/element
52
+
53
+ ```tsx
54
+ import { Link } from '@availity/element';
55
+ ```
56
+
57
+ #### Direct import
58
+
59
+ ```tsx
60
+ import { Link } from '@availity/mui-link';
61
+ ```
@@ -0,0 +1,23 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import * as _mui_material_OverridableComponent from '@mui/material/OverridableComponent';
4
+ import { LinkProps as LinkProps$1 } from '@mui/material';
5
+ import { SystemProps } from '@mui/system';
6
+
7
+ type LinkProps = {
8
+ /** Url of the page the link goes to */
9
+ href: string;
10
+ /** format href to leverage loadApp within home iframe when relative url used.
11
+ *
12
+ * @default true */
13
+ loadApp?: boolean;
14
+ /** Where to open the linked document. Adds `OpenInNewIcon` when target is `_blank` */
15
+ target?: string;
16
+ /** Function to run onClick of the link. The first argument passed to onClick is the event. The second argument is the processed url. */
17
+ onClick?: (event: React.MouseEvent, url: string) => void;
18
+ children?: ReactNode;
19
+ rel?: string;
20
+ } & Omit<LinkProps$1, 'underline' | 'noWrap' | 'variantMapping' | 'variant' | keyof SystemProps>;
21
+ declare const Link: react.ForwardRefExoticComponent<Pick<LinkProps, keyof _mui_material_OverridableComponent.CommonProps | "children" | "sx" | "slot" | "title" | "id" | "lang" | "media" | "target" | "type" | "role" | "tabIndex" | "href" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onResize" | "onResizeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "nonce" | "placeholder" | "spellCheck" | "translate" | "radioGroup" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "download" | "hrefLang" | "ping" | "rel" | "referrerPolicy" | "align" | "gutterBottom" | "paragraph" | "TypographyClasses" | "loadApp"> & react.RefAttributes<HTMLAnchorElement>>;
22
+
23
+ export { Link, LinkProps };
package/dist/index.js ADDED
@@ -0,0 +1,226 @@
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 __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __commonJS = (cb, mod) => function __require() {
12
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
13
+ };
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
30
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
+
32
+ // node_modules/tsup/assets/cjs_shims.js
33
+ var init_cjs_shims = __esm({
34
+ "node_modules/tsup/assets/cjs_shims.js"() {
35
+ }
36
+ });
37
+
38
+ // ../../node_modules/@fortawesome/free-solid-svg-icons/faArrowUpRightFromSquare.js
39
+ var require_faArrowUpRightFromSquare = __commonJS({
40
+ "../../node_modules/@fortawesome/free-solid-svg-icons/faArrowUpRightFromSquare.js"(exports) {
41
+ "use strict";
42
+ init_cjs_shims();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ var prefix = "fas";
45
+ var iconName = "arrow-up-right-from-square";
46
+ var width = 512;
47
+ var height = 512;
48
+ var aliases = ["external-link"];
49
+ var unicode = "f08e";
50
+ var svgPathData = "M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z";
51
+ exports.definition = {
52
+ prefix,
53
+ iconName,
54
+ icon: [
55
+ width,
56
+ height,
57
+ aliases,
58
+ unicode,
59
+ svgPathData
60
+ ]
61
+ };
62
+ exports.faArrowUpRightFromSquare = exports.definition;
63
+ exports.prefix = prefix;
64
+ exports.iconName = iconName;
65
+ exports.width = width;
66
+ exports.height = height;
67
+ exports.ligatures = aliases;
68
+ exports.unicode = unicode;
69
+ exports.svgPathData = svgPathData;
70
+ exports.aliases = aliases;
71
+ }
72
+ });
73
+
74
+ // ../../node_modules/@fortawesome/free-solid-svg-icons/faExternalLink.js
75
+ var require_faExternalLink = __commonJS({
76
+ "../../node_modules/@fortawesome/free-solid-svg-icons/faExternalLink.js"(exports) {
77
+ "use strict";
78
+ init_cjs_shims();
79
+ Object.defineProperty(exports, "__esModule", { value: true });
80
+ var source = require_faArrowUpRightFromSquare();
81
+ exports.definition = {
82
+ prefix: source.prefix,
83
+ iconName: source.iconName,
84
+ icon: [
85
+ source.width,
86
+ source.height,
87
+ source.aliases,
88
+ source.unicode,
89
+ source.svgPathData
90
+ ]
91
+ };
92
+ exports.faExternalLink = exports.definition;
93
+ exports.prefix = source.prefix;
94
+ exports.iconName = source.iconName;
95
+ exports.width = source.width;
96
+ exports.height = source.height;
97
+ exports.ligatures = source.aliases;
98
+ exports.unicode = source.unicode;
99
+ exports.svgPathData = source.svgPathData;
100
+ exports.aliases = source.aliases;
101
+ }
102
+ });
103
+
104
+ // src/index.ts
105
+ var src_exports = {};
106
+ __export(src_exports, {
107
+ Link: () => Link
108
+ });
109
+ module.exports = __toCommonJS(src_exports);
110
+ init_cjs_shims();
111
+
112
+ // src/lib/Link.tsx
113
+ init_cjs_shims();
114
+ var import_react = require("react");
115
+ var import_material2 = require("@mui/material");
116
+
117
+ // ../icon/src/index.ts
118
+ init_cjs_shims();
119
+
120
+ // ../icon/src/lib/Icons/Actions.tsx
121
+ init_cjs_shims();
122
+
123
+ // ../icon/src/lib/FaSvgIcon.tsx
124
+ init_cjs_shims();
125
+ var React = __toESM(require("react"));
126
+ var import_material = require("@mui/material");
127
+ var import_jsx_runtime = require("react/jsx-runtime");
128
+ var FaSvgIcon = React.forwardRef((props, ref) => {
129
+ const { icon, ...svgProps } = props;
130
+ const {
131
+ icon: [width, height, , , svgPathData]
132
+ } = icon;
133
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_material.SvgIcon, {
134
+ ref,
135
+ viewBox: `0 0 ${width} ${height}`,
136
+ ...svgProps,
137
+ children: typeof svgPathData === "string" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
138
+ d: svgPathData
139
+ }) : null
140
+ });
141
+ });
142
+
143
+ // ../icon/src/lib/Icons/Actions.tsx
144
+ var import_jsx_runtime = require("react/jsx-runtime");
145
+
146
+ // ../icon/src/lib/Icons/Common.tsx
147
+ init_cjs_shims();
148
+ var import_faExternalLink = __toESM(require_faExternalLink());
149
+ var import_jsx_runtime = require("react/jsx-runtime");
150
+ var OpenInNewIcon = ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FaSvgIcon, {
151
+ icon: import_faExternalLink.faExternalLink,
152
+ "aria-hidden": false,
153
+ titleAccess: "(opens in new window)",
154
+ ...props
155
+ });
156
+
157
+ // ../icon/src/lib/Icons/Files.tsx
158
+ init_cjs_shims();
159
+ var import_jsx_runtime = require("react/jsx-runtime");
160
+
161
+ // ../icon/src/lib/Icons/Form.tsx
162
+ init_cjs_shims();
163
+ var import_jsx_runtime = require("react/jsx-runtime");
164
+
165
+ // ../icon/src/lib/Icons/Navigation.tsx
166
+ init_cjs_shims();
167
+ var import_jsx_runtime = require("react/jsx-runtime");
168
+
169
+ // ../icon/src/lib/Icons/Payment.tsx
170
+ init_cjs_shims();
171
+ var import_jsx_runtime = require("react/jsx-runtime");
172
+
173
+ // src/lib/Link.tsx
174
+ var import_jsx_runtime = require("react/jsx-runtime");
175
+ var ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/;
176
+ var WINDOWS_PATH_REGEX = /^[a-zA-Z]:\\/;
177
+ function isAbsoluteUrl(url) {
178
+ if (WINDOWS_PATH_REGEX.test(url)) {
179
+ return false;
180
+ }
181
+ return ABSOLUTE_URL_REGEX.test(url);
182
+ }
183
+ var getUrl = (url = "") => {
184
+ return `/public/apps/home/#!/loadApp?appUrl=${encodeURIComponent(url)}`;
185
+ };
186
+ var getLocation = (href) => {
187
+ const location = document.createElement("a");
188
+ location.href = href;
189
+ return location;
190
+ };
191
+ var setRel = (url, target, absolute) => {
192
+ if (target === "_blank" && absolute) {
193
+ const dest = getLocation(url);
194
+ if (dest.hostname !== window.location.hostname) {
195
+ return "noopener noreferrer";
196
+ }
197
+ }
198
+ return void 0;
199
+ };
200
+ var Link = (0, import_react.forwardRef)((props, ref) => {
201
+ const { href, target = "_self", children, onClick, loadApp = true, rel, ...rest } = props;
202
+ const absolute = isAbsoluteUrl(href);
203
+ const encode = !(absolute || !loadApp);
204
+ const url = encode ? getUrl(href) : href;
205
+ const NewWindowIcon = target === "_blank" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OpenInNewIcon, {}) : null;
206
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_material2.Link, {
207
+ href: url,
208
+ target,
209
+ onClick: (event) => onClick && onClick(event, url),
210
+ rel: rel || setRel(url, target, absolute),
211
+ underline: "hover",
212
+ ...rest,
213
+ ref,
214
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
215
+ children: [
216
+ children,
217
+ " ",
218
+ NewWindowIcon
219
+ ]
220
+ })
221
+ });
222
+ });
223
+ // Annotate the CommonJS export names for ESM import in node:
224
+ 0 && (module.exports = {
225
+ Link
226
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,214 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __esm = (fn, res) => function __init() {
8
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ };
10
+ var __commonJS = (cb, mod) => function __require() {
11
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // node_modules/tsup/assets/esm_shims.js
27
+ var init_esm_shims = __esm({
28
+ "node_modules/tsup/assets/esm_shims.js"() {
29
+ }
30
+ });
31
+
32
+ // ../../node_modules/@fortawesome/free-solid-svg-icons/faArrowUpRightFromSquare.js
33
+ var require_faArrowUpRightFromSquare = __commonJS({
34
+ "../../node_modules/@fortawesome/free-solid-svg-icons/faArrowUpRightFromSquare.js"(exports) {
35
+ "use strict";
36
+ init_esm_shims();
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ var prefix = "fas";
39
+ var iconName = "arrow-up-right-from-square";
40
+ var width = 512;
41
+ var height = 512;
42
+ var aliases = ["external-link"];
43
+ var unicode = "f08e";
44
+ var svgPathData = "M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z";
45
+ exports.definition = {
46
+ prefix,
47
+ iconName,
48
+ icon: [
49
+ width,
50
+ height,
51
+ aliases,
52
+ unicode,
53
+ svgPathData
54
+ ]
55
+ };
56
+ exports.faArrowUpRightFromSquare = exports.definition;
57
+ exports.prefix = prefix;
58
+ exports.iconName = iconName;
59
+ exports.width = width;
60
+ exports.height = height;
61
+ exports.ligatures = aliases;
62
+ exports.unicode = unicode;
63
+ exports.svgPathData = svgPathData;
64
+ exports.aliases = aliases;
65
+ }
66
+ });
67
+
68
+ // ../../node_modules/@fortawesome/free-solid-svg-icons/faExternalLink.js
69
+ var require_faExternalLink = __commonJS({
70
+ "../../node_modules/@fortawesome/free-solid-svg-icons/faExternalLink.js"(exports) {
71
+ "use strict";
72
+ init_esm_shims();
73
+ Object.defineProperty(exports, "__esModule", { value: true });
74
+ var source = require_faArrowUpRightFromSquare();
75
+ exports.definition = {
76
+ prefix: source.prefix,
77
+ iconName: source.iconName,
78
+ icon: [
79
+ source.width,
80
+ source.height,
81
+ source.aliases,
82
+ source.unicode,
83
+ source.svgPathData
84
+ ]
85
+ };
86
+ exports.faExternalLink = exports.definition;
87
+ exports.prefix = source.prefix;
88
+ exports.iconName = source.iconName;
89
+ exports.width = source.width;
90
+ exports.height = source.height;
91
+ exports.ligatures = source.aliases;
92
+ exports.unicode = source.unicode;
93
+ exports.svgPathData = source.svgPathData;
94
+ exports.aliases = source.aliases;
95
+ }
96
+ });
97
+
98
+ // src/index.ts
99
+ init_esm_shims();
100
+
101
+ // src/lib/Link.tsx
102
+ init_esm_shims();
103
+ import { forwardRef as forwardRef2 } from "react";
104
+ import { Link as MuiLink } from "@mui/material";
105
+
106
+ // ../icon/src/index.ts
107
+ init_esm_shims();
108
+
109
+ // ../icon/src/lib/Icons/Actions.tsx
110
+ init_esm_shims();
111
+
112
+ // ../icon/src/lib/FaSvgIcon.tsx
113
+ init_esm_shims();
114
+ import * as React from "react";
115
+ import { SvgIcon } from "@mui/material";
116
+ import { jsx } from "react/jsx-runtime";
117
+ var FaSvgIcon = React.forwardRef((props, ref) => {
118
+ const { icon, ...svgProps } = props;
119
+ const {
120
+ icon: [width, height, , , svgPathData]
121
+ } = icon;
122
+ return /* @__PURE__ */ jsx(SvgIcon, {
123
+ ref,
124
+ viewBox: `0 0 ${width} ${height}`,
125
+ ...svgProps,
126
+ children: typeof svgPathData === "string" ? /* @__PURE__ */ jsx("path", {
127
+ d: svgPathData
128
+ }) : null
129
+ });
130
+ });
131
+
132
+ // ../icon/src/lib/Icons/Actions.tsx
133
+ import { jsx as jsx2 } from "react/jsx-runtime";
134
+
135
+ // ../icon/src/lib/Icons/Common.tsx
136
+ init_esm_shims();
137
+ var import_faExternalLink = __toESM(require_faExternalLink());
138
+ import { jsx as jsx3 } from "react/jsx-runtime";
139
+ var OpenInNewIcon = ({ ...props }) => /* @__PURE__ */ jsx3(FaSvgIcon, {
140
+ icon: import_faExternalLink.faExternalLink,
141
+ "aria-hidden": false,
142
+ titleAccess: "(opens in new window)",
143
+ ...props
144
+ });
145
+
146
+ // ../icon/src/lib/Icons/Files.tsx
147
+ init_esm_shims();
148
+ import { jsx as jsx4 } from "react/jsx-runtime";
149
+
150
+ // ../icon/src/lib/Icons/Form.tsx
151
+ init_esm_shims();
152
+ import { jsx as jsx5 } from "react/jsx-runtime";
153
+
154
+ // ../icon/src/lib/Icons/Navigation.tsx
155
+ init_esm_shims();
156
+ import { jsx as jsx6 } from "react/jsx-runtime";
157
+
158
+ // ../icon/src/lib/Icons/Payment.tsx
159
+ init_esm_shims();
160
+ import { jsx as jsx7 } from "react/jsx-runtime";
161
+
162
+ // src/lib/Link.tsx
163
+ import { jsx as jsx8, jsxs } from "react/jsx-runtime";
164
+ var ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/;
165
+ var WINDOWS_PATH_REGEX = /^[a-zA-Z]:\\/;
166
+ function isAbsoluteUrl(url) {
167
+ if (WINDOWS_PATH_REGEX.test(url)) {
168
+ return false;
169
+ }
170
+ return ABSOLUTE_URL_REGEX.test(url);
171
+ }
172
+ var getUrl = (url = "") => {
173
+ return `/public/apps/home/#!/loadApp?appUrl=${encodeURIComponent(url)}`;
174
+ };
175
+ var getLocation = (href) => {
176
+ const location = document.createElement("a");
177
+ location.href = href;
178
+ return location;
179
+ };
180
+ var setRel = (url, target, absolute) => {
181
+ if (target === "_blank" && absolute) {
182
+ const dest = getLocation(url);
183
+ if (dest.hostname !== window.location.hostname) {
184
+ return "noopener noreferrer";
185
+ }
186
+ }
187
+ return void 0;
188
+ };
189
+ var Link = forwardRef2((props, ref) => {
190
+ const { href, target = "_self", children, onClick, loadApp = true, rel, ...rest } = props;
191
+ const absolute = isAbsoluteUrl(href);
192
+ const encode = !(absolute || !loadApp);
193
+ const url = encode ? getUrl(href) : href;
194
+ const NewWindowIcon = target === "_blank" ? /* @__PURE__ */ jsx8(OpenInNewIcon, {}) : null;
195
+ return /* @__PURE__ */ jsx8(MuiLink, {
196
+ href: url,
197
+ target,
198
+ onClick: (event) => onClick && onClick(event, url),
199
+ rel: rel || setRel(url, target, absolute),
200
+ underline: "hover",
201
+ ...rest,
202
+ ref,
203
+ children: /* @__PURE__ */ jsxs("span", {
204
+ children: [
205
+ children,
206
+ " ",
207
+ NewWindowIcon
208
+ ]
209
+ })
210
+ });
211
+ });
212
+ export {
213
+ Link
214
+ };
@@ -0,0 +1,7 @@
1
+ import { Markdown } from '@storybook/blocks';
2
+ import { Meta } from '@storybook/addon-docs';
3
+ import ReadMe from './README.md?raw';
4
+
5
+ <Meta title="Components/Link/Introduction" />
6
+
7
+ <Markdown>{ReadMe}</Markdown>
package/jest.config.js ADDED
@@ -0,0 +1,7 @@
1
+ const global = require('../../jest.config.global');
2
+
3
+ module.exports = {
4
+ ...global,
5
+ displayName: 'link',
6
+ coverageDirectory: '../../coverage/link',
7
+ };
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@availity/mui-link",
3
+ "version": "0.1.0",
4
+ "description": "Availity MUI Link Component - part of the @availity/element design system",
5
+ "keywords": [
6
+ "react",
7
+ "typescript",
8
+ "availity",
9
+ "mui"
10
+ ],
11
+ "homepage": "https://availity.github.io/element/?path=/docs/components-link-introduction--docs",
12
+ "bugs": {
13
+ "url": "https://github.com/Availity/element/issues"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/Availity/element.git",
18
+ "directory": "packages/link"
19
+ },
20
+ "license": "MIT",
21
+ "author": "Availity Developers <AVOSS@availity.com>",
22
+ "browser": "./dist/index.js",
23
+ "main": "./dist/index.js",
24
+ "module": "./dist/index.mjs",
25
+ "types": "./dist/index.d.ts",
26
+ "scripts": {
27
+ "build": "tsup src/index.ts --format esm,cjs --dts",
28
+ "dev": "tsup src/index.ts --format esm,cjs --watch --dts",
29
+ "clean": "rm -rf dist",
30
+ "clean:nm": "rm -rf node_modules",
31
+ "bundlesize": "bundlesize",
32
+ "publish": "yarn npm publish --tolerate-republish --access public",
33
+ "publish:canary": "yarn npm publish --access public --tag canary"
34
+ },
35
+ "devDependencies": {
36
+ "@mui/material": "^5.11.9",
37
+ "@mui/system": "^5.11.9",
38
+ "react": "18.2.0",
39
+ "react-dom": "18.2.0",
40
+ "tsup": "^5.12.7",
41
+ "typescript": "^4.6.4"
42
+ },
43
+ "peerDependencies": {
44
+ "@mui/material": "^5.11.9",
45
+ "@mui/system": "^5.11.9",
46
+ "react": ">=16.3.0"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ }
51
+ }
package/project.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "mui-link",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "packages/link/src",
5
+ "projectType": "library",
6
+ "tags": [],
7
+ "targets": {
8
+ "lint": {
9
+ "executor": "@nrwl/linter:eslint",
10
+ "options": {
11
+ "eslintConfig": ".eslintrc.json",
12
+ "lintFilePatterns": ["packages/link/**/*.{js,ts}"],
13
+ "silent": false,
14
+ "fix": false,
15
+ "cache": true,
16
+ "cacheLocation": "./node_modules/.cache/link/.eslintcache",
17
+ "maxWarnings": -1,
18
+ "quiet": false,
19
+ "noEslintrc": false,
20
+ "hasTypeAwareRules": true,
21
+ "cacheStrategy": "metadata"
22
+ }
23
+ },
24
+ "test": {
25
+ "executor": "@nrwl/jest:jest",
26
+ "outputs": ["coverage/link"],
27
+ "options": {
28
+ "jestConfig": "packages/link/jest.config.js",
29
+ "passWithNoTests": true
30
+ }
31
+ },
32
+ "version": {
33
+ "executor": "@jscutlery/semver:version",
34
+ "options": {
35
+ "preset": "conventional",
36
+ "commitMessageFormat": "chore(${projectName}): release version ${version} [skip ci]",
37
+ "tagPrefix": "@availity/${projectName}@"
38
+ }
39
+ }
40
+ }
41
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './lib/Link';
@@ -0,0 +1,47 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Link, LinkProps } from './Link';
3
+
4
+ /**
5
+ * 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
6
+ */
7
+ const meta: Meta<typeof Link> = {
8
+ title: 'Components/Link/Link',
9
+ component: Link,
10
+ tags: ['autodocs'],
11
+ args: {
12
+ href: '#',
13
+ },
14
+ };
15
+
16
+ export default meta;
17
+
18
+ export const _Link: StoryObj<typeof Link> = {
19
+ render: (args: LinkProps) => <Link {...args} />,
20
+ args: {
21
+ loadApp: true,
22
+ children: 'This text is a child of Link',
23
+ },
24
+ };
25
+
26
+ /** The `OpenInNewIcon` has an accessible name to tell screenreaders that it opens in a new window. */
27
+ export const _NewWindow: StoryObj<typeof Link> = {
28
+ render: (args: LinkProps) => <Link {...args} loadApp={false} target="_blank" />,
29
+ args: {
30
+ children: 'Link opens in new window',
31
+ },
32
+ };
33
+
34
+ export const _AbsoluteUrl: StoryObj<typeof Link> = {
35
+ render: (args: LinkProps) => <Link {...args} href="https://github.com/Availity" target="_blank" />,
36
+ args: {
37
+ children: 'Availity Github',
38
+ },
39
+ };
40
+
41
+ /** Inspect the link to see the `loadApp` url transformation in action. */
42
+ export const _RelativeUrl: StoryObj<typeof Link> = {
43
+ render: (args: LinkProps) => <Link {...args} href="/public/apps/portal-app" />,
44
+ args: {
45
+ children: 'Portal App',
46
+ },
47
+ };
@@ -0,0 +1,93 @@
1
+ import { render, fireEvent } from '@testing-library/react';
2
+ import { Link } from './Link';
3
+
4
+ describe('Link', () => {
5
+ test('should render successfully', () => {
6
+ const { getByText } = render(<Link href="#">Test</Link>);
7
+
8
+ expect(getByText('Test')).toBeTruthy();
9
+ });
10
+
11
+ test('should render absolute url', () => {
12
+ const { getByRole } = render(<Link href="https://github.com/Availity">Test</Link>);
13
+
14
+ const link = getByRole('link');
15
+
16
+ expect(link.getAttribute('href')).toBe('https://github.com/Availity');
17
+ });
18
+
19
+ test('should render formatted url when url prop is relative', () => {
20
+ const { getByRole } = render(<Link href="/public/apps/my-app">My App</Link>);
21
+
22
+ const link = getByRole('link');
23
+ const expected = '/public/apps/home/#!/loadApp?appUrl=%2Fpublic%2Fapps%2Fmy-app';
24
+
25
+ expect(link.getAttribute('href')).toBe(expected);
26
+ });
27
+
28
+ test('should render url prop as is when loadApp is false', () => {
29
+ const { getByRole } = render(
30
+ <Link loadApp={false} href="/public/apps/my-app">
31
+ My App
32
+ </Link>
33
+ );
34
+
35
+ const link = getByRole('link');
36
+ const expected = '/public/apps/my-app';
37
+
38
+ expect(link.getAttribute('href')).toBe(expected);
39
+ });
40
+
41
+ test('should default rel prop if none provided when linking to external site', () => {
42
+ const { getByRole } = render(
43
+ <Link loadApp={false} href="https://github.com/Availity" target="_blank">
44
+ Github
45
+ </Link>
46
+ );
47
+
48
+ const link = getByRole('link');
49
+ const expected = 'noopener noreferrer';
50
+
51
+ expect(link.getAttribute('rel')).toBe(expected);
52
+ });
53
+
54
+ test('should respect rel prop if provided when linking to external site', () => {
55
+ const { getByRole } = render(
56
+ <Link loadApp={false} href="https://github.com/Availity" target="_blank" rel="nofollow">
57
+ Github
58
+ </Link>
59
+ );
60
+
61
+ const link = getByRole('link');
62
+ const expected = 'nofollow';
63
+
64
+ expect(link.getAttribute('rel')).toBe(expected);
65
+ });
66
+
67
+ test('should call onClick', () => {
68
+ const onClick = jest.fn();
69
+
70
+ const { getByRole } = render(
71
+ <Link loadApp={false} href="/public/apps/my-app" onClick={onClick}>
72
+ My App
73
+ </Link>
74
+ );
75
+
76
+ const link = getByRole('link');
77
+ fireEvent.click(link);
78
+
79
+ expect(onClick.mock.calls[0][1]).toBe('/public/apps/my-app');
80
+ });
81
+
82
+ test('should render link with proper styling', () => {
83
+ const { getByRole } = render(
84
+ <Link href="/public/apps/my-app" className="card-link">
85
+ My App
86
+ </Link>
87
+ );
88
+
89
+ const link = getByRole('link');
90
+
91
+ expect(link.getAttribute('class')).toContain('card-link');
92
+ });
93
+ });
@@ -0,0 +1,81 @@
1
+ import { ReactNode, forwardRef } from 'react';
2
+ import { Link as MuiLink, LinkProps as MuiLinkProps } from '@mui/material';
3
+ import { SystemProps } from '@mui/system';
4
+ import { OpenInNewIcon } from '@availity/mui-icon';
5
+
6
+ // Scheme: https://tools.ietf.org/html/rfc3986#section-3.1
7
+ // Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3
8
+ const ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/;
9
+
10
+ // Windows paths like `c:\`
11
+ const WINDOWS_PATH_REGEX = /^[a-zA-Z]:\\/;
12
+
13
+ function isAbsoluteUrl(url: string) {
14
+ if (WINDOWS_PATH_REGEX.test(url)) {
15
+ return false;
16
+ }
17
+
18
+ return ABSOLUTE_URL_REGEX.test(url);
19
+ }
20
+
21
+ // if absolute or loadApp is disabled, return url. otherwise loadappify the url
22
+ const getUrl = (url = '') => {
23
+ return `/public/apps/home/#!/loadApp?appUrl=${encodeURIComponent(url)}`;
24
+ };
25
+
26
+ // takes href and transforms it so that we can compare hostnames and other properties
27
+ const getLocation = (href: string) => {
28
+ const location = document.createElement('a');
29
+ location.href = href;
30
+ return location;
31
+ };
32
+
33
+ const setRel = (url: string, target: string, absolute: boolean) => {
34
+ if (target === '_blank' && absolute) {
35
+ const dest = getLocation(url);
36
+ if (dest.hostname !== window.location.hostname) {
37
+ // default rel when linking to external destinations for performance and security
38
+ return 'noopener noreferrer';
39
+ }
40
+ }
41
+ return undefined;
42
+ };
43
+
44
+ export type LinkProps = {
45
+ /** Url of the page the link goes to */
46
+ href: string;
47
+ /** format href to leverage loadApp within home iframe when relative url used.
48
+ *
49
+ * @default true */
50
+ loadApp?: boolean;
51
+ /** Where to open the linked document. Adds `OpenInNewIcon` when target is `_blank` */
52
+ target?: string;
53
+ /** Function to run onClick of the link. The first argument passed to onClick is the event. The second argument is the processed url. */
54
+ onClick?: (event: React.MouseEvent, url: string) => void;
55
+ children?: ReactNode;
56
+ rel?: string;
57
+ } & Omit<MuiLinkProps, 'underline' | 'noWrap' | 'variantMapping' | 'variant' | keyof SystemProps>;
58
+
59
+ export const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
60
+ const { href, target = '_self', children, onClick, loadApp = true, rel, ...rest } = props;
61
+ const absolute = isAbsoluteUrl(href);
62
+ const encode = !(absolute || !loadApp);
63
+ const url = encode ? getUrl(href) : href;
64
+ const NewWindowIcon = target === '_blank' ? <OpenInNewIcon /> : null;
65
+
66
+ return (
67
+ <MuiLink
68
+ href={url}
69
+ target={target}
70
+ onClick={(event: React.MouseEvent) => onClick && onClick(event, url)}
71
+ rel={rel || setRel(url, target, absolute)}
72
+ underline="hover"
73
+ {...rest}
74
+ ref={ref}
75
+ >
76
+ <span>
77
+ {children} {NewWindowIcon}
78
+ </span>
79
+ </MuiLink>
80
+ );
81
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "include": ["."],
4
+ "exclude": ["dist", "build", "node_modules"]
5
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "module": "commonjs",
6
+ "types": ["jest", "node", "@testing-library/jest-dom"],
7
+ "allowJs": true
8
+ },
9
+ "include": ["**/*.test.js", "**/*.test.ts", "**/*.test.tsx", "**/*.d.ts"]
10
+ }