@phila/phila-ui-link 1.0.0-beta.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/README.md +150 -0
- package/dist/Link.vue.d.ts +18 -0
- package/dist/Link.vue.d.ts.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +77 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Link Component
|
|
2
|
+
|
|
3
|
+
A versatile Vue 3 Link component with TypeScript support, Vue Router integration, and external link icon support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎯 TypeScript support with full type definitions
|
|
8
|
+
- 🔗 Supports both Vue Router links and HTML anchor links
|
|
9
|
+
- 🌐 External link icon support via `isExternal` prop
|
|
10
|
+
- 🎨 Multiple variants and sizes
|
|
11
|
+
- ♿ Full accessibility support
|
|
12
|
+
- 🎭 Icon support (left, right, or icon-only)
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @phila/phila-ui-link
|
|
18
|
+
# or
|
|
19
|
+
yarn add @phila/phila-ui-link
|
|
20
|
+
# or
|
|
21
|
+
pnpm add @phila/phila-ui-link
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Basic HTML Link
|
|
27
|
+
|
|
28
|
+
```vue
|
|
29
|
+
<script setup lang="ts">
|
|
30
|
+
import { PhilaLink } from "@phila/phila-ui-link";
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<PhilaLink href="https://www.phila.gov" text="Visit Philadelphia" />
|
|
35
|
+
</template>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Vue Router Link
|
|
39
|
+
|
|
40
|
+
```vue
|
|
41
|
+
<template>
|
|
42
|
+
<PhilaLink to="/dashboard" text="Go to Dashboard" />
|
|
43
|
+
</template>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Links with External Icon
|
|
47
|
+
|
|
48
|
+
Add an external link icon to links that go to external domains by setting the `isExternal` prop:
|
|
49
|
+
|
|
50
|
+
```vue
|
|
51
|
+
<template>
|
|
52
|
+
<!-- Link to external domain with icon -->
|
|
53
|
+
<PhilaLink href="https://www.google.com" text="Visit Google" isExternal />
|
|
54
|
+
|
|
55
|
+
<!-- Link to same domain without icon -->
|
|
56
|
+
<PhilaLink href="/about" text="About Us" />
|
|
57
|
+
</template>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Props
|
|
61
|
+
|
|
62
|
+
| Prop | Type | Default | Description |
|
|
63
|
+
| ---------------- | --------------------------- | ----------- | ------------------------------------------------------------ |
|
|
64
|
+
| `to` | `RouteLocationRaw` | - | Vue Router route destination. Mutually exclusive with `href` |
|
|
65
|
+
| `href` | `string` | - | HTML anchor href attribute. Mutually exclusive with `to` |
|
|
66
|
+
| `text` | `string` | - | Link text content |
|
|
67
|
+
| `variant` | `'default' \| 'on-primary'` | `'default'` | Link variant style |
|
|
68
|
+
| `size` | `ComponentSize` | - | Link size |
|
|
69
|
+
| `disabled` | `boolean` | `false` | Whether the link is disabled |
|
|
70
|
+
| `target` | `string` | - | Link target (e.g., `_blank`) |
|
|
71
|
+
| `rel` | `string` | - | Link rel attribute |
|
|
72
|
+
| `iconDefinition` | `IconDefinition` | - | FontAwesome icon definition |
|
|
73
|
+
| `iconClass` | `string` | - | FontAwesome icon class name |
|
|
74
|
+
| `iconRight` | `boolean` | `false` | Position icon on the right |
|
|
75
|
+
| `iconOnly` | `boolean` | `false` | Show only icon (no text) |
|
|
76
|
+
| `isExternal` | `boolean` | `false` | Show external link icon |
|
|
77
|
+
| `ariaLabel` | `string` | - | Accessible label for screen readers (required for icon-only) |
|
|
78
|
+
| `className` | `string` | - | Additional CSS classes (from `BaseProps`) |
|
|
79
|
+
|
|
80
|
+
## Examples
|
|
81
|
+
|
|
82
|
+
### With Icons
|
|
83
|
+
|
|
84
|
+
```vue
|
|
85
|
+
<template>
|
|
86
|
+
<!-- Icon on the left -->
|
|
87
|
+
<PhilaLink href="/" text="Home" :iconDefinition="faHome" />
|
|
88
|
+
|
|
89
|
+
<!-- Icon on the right -->
|
|
90
|
+
<PhilaLink href="/next" text="Continue" :iconDefinition="faArrowRight" iconRight />
|
|
91
|
+
|
|
92
|
+
<!-- Icon only (requires ariaLabel for accessibility) -->
|
|
93
|
+
<PhilaLink href="/settings" :iconDefinition="faGear" iconOnly ariaLabel="Settings" />
|
|
94
|
+
</template>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Links with Target Attribute
|
|
98
|
+
|
|
99
|
+
```vue
|
|
100
|
+
<template>
|
|
101
|
+
<PhilaLink href="https://example.com" text="Open in New Tab" target="_blank" rel="noopener noreferrer" />
|
|
102
|
+
</template>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Different Sizes
|
|
106
|
+
|
|
107
|
+
```vue
|
|
108
|
+
<template>
|
|
109
|
+
<PhilaLink href="/" text="Large Link" size="large" />
|
|
110
|
+
<PhilaLink href="/" text="Small Link" size="small" />
|
|
111
|
+
</template>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Disabled State
|
|
115
|
+
|
|
116
|
+
```vue
|
|
117
|
+
<template>
|
|
118
|
+
<PhilaLink href="/" text="Disabled Link" disabled />
|
|
119
|
+
</template>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Development
|
|
123
|
+
|
|
124
|
+
### Install Dependencies
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pnpm install
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Run Demo
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
pnpm dev
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Build Library
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
pnpm build
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Type Check
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
pnpm type-check
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare function __VLS_template(): {
|
|
2
|
+
attrs: Partial<{}>;
|
|
3
|
+
slots: {
|
|
4
|
+
default?(_: {}): any;
|
|
5
|
+
};
|
|
6
|
+
refs: {};
|
|
7
|
+
rootEl: any;
|
|
8
|
+
};
|
|
9
|
+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
10
|
+
declare const __VLS_component: import('vue').DefineSetupFnComponent<Record<string, any>, {}, {}, Record<string, any> & {}, import('vue').PublicProps>;
|
|
11
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
12
|
+
export default _default;
|
|
13
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
14
|
+
new (): {
|
|
15
|
+
$slots: S;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=Link.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Link.vue.d.ts","sourceRoot":"","sources":["../src/Link.vue"],"names":[],"mappings":"AAoLA,iBAAS,cAAc;WA4CT,OAAO,IAA6B;;yBAVpB,GAAG;;;;EAehC;AAaD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe,wHAOnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAapG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ActionContentProps, RouterLinkProps as BaseRouterLinkProps, HtmlLinkProps as BaseHtmlLinkProps } from '@phila/phila-ui-core';
|
|
2
|
+
export { default as PhilaLink } from './Link.vue';
|
|
3
|
+
export type LinkProps = RouterLinkProps | HtmlLinkProps;
|
|
4
|
+
export type LinkVariant = "default" | "on-primary";
|
|
5
|
+
interface LinkSpecificProps {
|
|
6
|
+
/** Link variant type */
|
|
7
|
+
variant?: LinkVariant;
|
|
8
|
+
/** Show external link icon (for links to external sites) */
|
|
9
|
+
isExternal?: boolean;
|
|
10
|
+
/** Accessible label for screen readers (required for icon-only links) */
|
|
11
|
+
ariaLabel?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface RouterLinkProps extends BaseRouterLinkProps, ActionContentProps, LinkSpecificProps {
|
|
14
|
+
}
|
|
15
|
+
export interface HtmlLinkProps extends BaseHtmlLinkProps, ActionContentProps, LinkSpecificProps {
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,IAAI,mBAAmB,EACtC,aAAa,IAAI,iBAAiB,EACnC,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,aAAa,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,YAAY,CAAC;AAEnD,UAAU,iBAAiB;IACzB,wBAAwB;IACxB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB;CAAG;AAEtG,MAAM,WAAW,aAAc,SAAQ,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB;CAAG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue"),a=require("@phila/phila-ui-core"),c=t.defineComponent({inheritAttrs:!1,__name:"Link",props:{to:{},href:{},target:{},rel:{},disabled:{type:Boolean,default:!1},ariaLabel:{},className:{},iconRight:{type:Boolean},iconOnly:{type:Boolean,default:!1},text:{},size:{},iconDefinition:{},iconClass:{},src:{},svgRaw:{},variant:{default:"default"},isExternal:{type:Boolean,default:!1}},setup(o){const e=o,n=t.computed(()=>!(!e.isExternal||e.iconDefinition||e.iconClass||e.src||e.svgRaw)),s=t.computed(()=>a.cn("phila-link",e.variant&&`phila-link--${e.variant}`,e.size&&`is-${e.size}`,e.iconOnly&&"icon-link",e.disabled&&"is-disabled",e.className)),r=t.computed(()=>{const i={disabled:e.disabled,ariaLabel:e.ariaLabel,className:s.value};return a.isRouterLink(e)?{to:e.to,...i}:{href:e.href,target:e.target,rel:e.rel,...i}}),l=t.computed(()=>({iconDefinition:e.iconDefinition,iconClass:e.iconClass||(n.value?"external-link":void 0),src:e.src,svgRaw:e.svgRaw,iconRight:n.value?!0:e.iconRight,iconOnly:e.iconOnly,text:e.text,size:e.size}));return(i,u)=>(t.openBlock(),t.createBlock(t.unref(a.BaseLink),t.normalizeProps(t.guardReactiveProps({...r.value,...i.$attrs})),{default:t.withCtx(()=>[t.createVNode(t.unref(a.ActionContent),t.normalizeProps(t.guardReactiveProps(l.value)),{default:t.withCtx(()=>[t.renderSlot(i.$slots,"default",{},()=>[t.createTextVNode(t.toDisplayString(e.text),1)])]),_:3},16)]),_:3},16))}});exports.PhilaLink=c;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { defineComponent as d, computed as a, createBlock as p, openBlock as h, unref as i, normalizeProps as s, guardReactiveProps as o, withCtx as l, createVNode as v, renderSlot as g, createTextVNode as k, toDisplayString as m } from "vue";
|
|
2
|
+
import { cn as b, isRouterLink as x, BaseLink as y, ActionContent as R } from "@phila/phila-ui-core";
|
|
3
|
+
const w = /* @__PURE__ */ d({
|
|
4
|
+
inheritAttrs: !1,
|
|
5
|
+
__name: "Link",
|
|
6
|
+
props: {
|
|
7
|
+
to: {},
|
|
8
|
+
href: {},
|
|
9
|
+
target: {},
|
|
10
|
+
rel: {},
|
|
11
|
+
disabled: { type: Boolean, default: !1 },
|
|
12
|
+
ariaLabel: {},
|
|
13
|
+
className: {},
|
|
14
|
+
iconRight: { type: Boolean },
|
|
15
|
+
iconOnly: { type: Boolean, default: !1 },
|
|
16
|
+
text: {},
|
|
17
|
+
size: {},
|
|
18
|
+
iconDefinition: {},
|
|
19
|
+
iconClass: {},
|
|
20
|
+
src: {},
|
|
21
|
+
svgRaw: {},
|
|
22
|
+
variant: { default: "default" },
|
|
23
|
+
isExternal: { type: Boolean, default: !1 }
|
|
24
|
+
},
|
|
25
|
+
setup(r) {
|
|
26
|
+
const e = r, n = a(() => !(!e.isExternal || e.iconDefinition || e.iconClass || e.src || e.svgRaw)), c = a(() => b(
|
|
27
|
+
"phila-link",
|
|
28
|
+
e.variant && `phila-link--${e.variant}`,
|
|
29
|
+
e.size && `is-${e.size}`,
|
|
30
|
+
e.iconOnly && "icon-link",
|
|
31
|
+
e.disabled && "is-disabled",
|
|
32
|
+
e.className
|
|
33
|
+
)), f = a(() => {
|
|
34
|
+
const t = {
|
|
35
|
+
disabled: e.disabled,
|
|
36
|
+
ariaLabel: e.ariaLabel,
|
|
37
|
+
className: c.value
|
|
38
|
+
};
|
|
39
|
+
return x(e) ? {
|
|
40
|
+
to: e.to,
|
|
41
|
+
...t
|
|
42
|
+
} : {
|
|
43
|
+
href: e.href,
|
|
44
|
+
target: e.target,
|
|
45
|
+
rel: e.rel,
|
|
46
|
+
...t
|
|
47
|
+
};
|
|
48
|
+
}), u = a(
|
|
49
|
+
() => ({
|
|
50
|
+
iconDefinition: e.iconDefinition,
|
|
51
|
+
iconClass: e.iconClass || (n.value ? "external-link" : void 0),
|
|
52
|
+
src: e.src,
|
|
53
|
+
svgRaw: e.svgRaw,
|
|
54
|
+
iconRight: n.value ? !0 : e.iconRight,
|
|
55
|
+
iconOnly: e.iconOnly,
|
|
56
|
+
text: e.text,
|
|
57
|
+
size: e.size
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
return (t, C) => (h(), p(i(y), s(o({ ...f.value, ...t.$attrs })), {
|
|
61
|
+
default: l(() => [
|
|
62
|
+
v(i(R), s(o(u.value)), {
|
|
63
|
+
default: l(() => [
|
|
64
|
+
g(t.$slots, "default", {}, () => [
|
|
65
|
+
k(m(e.text), 1)
|
|
66
|
+
])
|
|
67
|
+
]),
|
|
68
|
+
_: 3
|
|
69
|
+
}, 16)
|
|
70
|
+
]),
|
|
71
|
+
_: 3
|
|
72
|
+
}, 16));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
export {
|
|
76
|
+
w as PhilaLink
|
|
77
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@phila/phila-ui-link",
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Link component with suppport for Vue Router",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"require": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"ui",
|
|
21
|
+
"link",
|
|
22
|
+
"vue",
|
|
23
|
+
"component"
|
|
24
|
+
],
|
|
25
|
+
"author": "",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"vue": "^3.0.0",
|
|
29
|
+
"vue-router": "^4.0.0",
|
|
30
|
+
"@fortawesome/fontawesome-svg-core": "^7.1.0",
|
|
31
|
+
"@fortawesome/vue-fontawesome": "^3.1.2"
|
|
32
|
+
},
|
|
33
|
+
"peerDependenciesMeta": {
|
|
34
|
+
"vue-router": {
|
|
35
|
+
"optional": true
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@phila/phila-ui-core": "2.2.0-beta.2"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^24.0.0",
|
|
43
|
+
"@vitejs/plugin-vue": "^6.0.1",
|
|
44
|
+
"eslint": "^9.0.0",
|
|
45
|
+
"typescript": "^5.8.3",
|
|
46
|
+
"vite": "^7.0.6",
|
|
47
|
+
"vite-plugin-dts": "^4.5.4",
|
|
48
|
+
"vite-plugin-lib-inject-css": "^2.2.2"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "vite build",
|
|
52
|
+
"build-win": "vite build",
|
|
53
|
+
"dev": "vite build --watch",
|
|
54
|
+
"lint": "eslint src --ext .ts,.tsx,.vue",
|
|
55
|
+
"lint:fix": "eslint src --ext .ts,.tsx,.vue --fix",
|
|
56
|
+
"type-check": "tsc --noEmit",
|
|
57
|
+
"clean": "rm -rf dist",
|
|
58
|
+
"format": "prettier --write .",
|
|
59
|
+
"format:check": "prettier --check ."
|
|
60
|
+
}
|
|
61
|
+
}
|