@phila/phila-ui-button 2.0.3 → 2.1.0-beta.3
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 +124 -20
- package/dist/index.d.ts +80 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +77 -9
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -1,48 +1,152 @@
|
|
|
1
1
|
# Phila Button Component
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A flexible, accessible button component built with Vue 3 and TypeScript, implementing the Philadelphia Design System.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- 🎨 Multiple variants: primary, secondary, destructive, standard
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- ♿
|
|
7
|
+
- 🎨 Multiple variants: primary, secondary, destructive, standard
|
|
8
|
+
- 📐 Multiple sizes: extra-large, large, medium (default), small, extra-small
|
|
9
|
+
- 🎯 Icon support: left icons, right icons, and icon-only buttons
|
|
10
|
+
- ♿ Full accessibility: ARIA attributes, focus states, disabled state
|
|
11
|
+
- 🔧 Flexible API: Props or slots for content
|
|
12
|
+
- 💅 Design system integration: Uses Core package styles
|
|
11
13
|
|
|
12
14
|
## Installation
|
|
13
15
|
|
|
14
|
-
Note: Button styles are included in the core package, so installation of the button vue component is optional.
|
|
15
|
-
|
|
16
16
|
```bash
|
|
17
|
-
npm install @phila/core
|
|
18
|
-
npm install @phila/phila-ui-button
|
|
17
|
+
npm install @phila/phila-ui-button @phila/phila-ui-core
|
|
19
18
|
# or
|
|
20
|
-
pnpm add @phila/core
|
|
21
|
-
pnpm add @phila/phila-ui-button
|
|
19
|
+
pnpm add @phila/phila-ui-button @phila/phila-ui-core
|
|
22
20
|
```
|
|
23
21
|
|
|
24
|
-
Import core styles
|
|
22
|
+
Import core styles in your main entry file (e.g., `main.js|ts`):
|
|
25
23
|
|
|
26
24
|
```typescript
|
|
27
|
-
import "@phila/core/styles/template-light.css";
|
|
25
|
+
import "@phila/phila-ui-core/styles/template-light.css";
|
|
28
26
|
```
|
|
29
27
|
|
|
30
|
-
## Usage
|
|
28
|
+
## Vue Component Usage
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
### Basic Usage
|
|
33
31
|
|
|
34
32
|
```vue
|
|
33
|
+
<script setup lang="ts">
|
|
34
|
+
import { PhilaButton } from "@phila/phila-ui-button";
|
|
35
|
+
|
|
36
|
+
const handleClick = () => {
|
|
37
|
+
console.log("Button clicked!");
|
|
38
|
+
};
|
|
39
|
+
</script>
|
|
40
|
+
|
|
35
41
|
<template>
|
|
36
|
-
<
|
|
42
|
+
<PhilaButton variant="primary" @click="handleClick"> Click Me </PhilaButton>
|
|
43
|
+
</template>
|
|
44
|
+
```
|
|
37
45
|
|
|
38
|
-
|
|
46
|
+
### With Props
|
|
47
|
+
|
|
48
|
+
```vue
|
|
49
|
+
<PhilaButton variant="primary" size="medium" text="Click Me" @click="handleClick" />
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### With Icons
|
|
53
|
+
|
|
54
|
+
```vue
|
|
55
|
+
<script setup lang="ts">
|
|
56
|
+
import { PhilaButton } from "@phila/phila-ui-button";
|
|
57
|
+
import { faPencil, faArrowRight } from "@fortawesome/pro-solid-svg-icons";
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<template>
|
|
61
|
+
<!-- Left Icon -->
|
|
62
|
+
<PhilaButton variant="primary" :icon="faPencil" text="Edit" />
|
|
63
|
+
|
|
64
|
+
<!-- Right Icon -->
|
|
65
|
+
<PhilaButton variant="primary" :icon="faArrowRight" icon-right text="Continue" />
|
|
66
|
+
|
|
67
|
+
<!-- Icon Only -->
|
|
68
|
+
<PhilaButton variant="primary" icon-only :icon="faPencil" />
|
|
39
69
|
</template>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Props
|
|
73
|
+
|
|
74
|
+
| Prop | Type | Default | Description |
|
|
75
|
+
| ----------- | ------------------------------------------------------------------ | ----------- | ------------------------------------------------------------- |
|
|
76
|
+
| `variant` | `"primary" \| "secondary" \| "destructive" \| "standard"` | `"primary"` | Button style variant |
|
|
77
|
+
| `size` | `"extra-large" \| "large" \| "medium" \| "small" \| "extra-small"` | `"medium"` | Button size |
|
|
78
|
+
| `disabled` | `boolean` | `false` | Whether the button is disabled |
|
|
79
|
+
| `iconOnly` | `boolean` | `false` | Whether to display only an icon |
|
|
80
|
+
| `icon` | `IconDefinition` | `undefined` | FontAwesome icon definition |
|
|
81
|
+
| `iconClass` | `string` | `undefined` | FontAwesome icon class name |
|
|
82
|
+
| `iconRight` | `boolean` | `false` | Whether to position the icon on the right side |
|
|
83
|
+
| `text` | `string` | `undefined` | Button text (alternative to slot) |
|
|
84
|
+
| `className` | `string` | `undefined` | Additional CSS classes |
|
|
85
|
+
| `href` | `string` | `undefined` | URL for link buttons (renders as `<a>` instead of `<button>`) |
|
|
86
|
+
| `target` | `string` | `undefined` | Link target attribute (e.g., "\_blank") |
|
|
87
|
+
| `rel` | `string` | `undefined` | Link rel attribute (e.g., "noopener noreferrer") |
|
|
88
|
+
|
|
89
|
+
### Variants
|
|
90
|
+
|
|
91
|
+
```vue
|
|
92
|
+
<PhilaButton variant="primary">Primary</PhilaButton>
|
|
93
|
+
<PhilaButton variant="secondary">Secondary</PhilaButton>
|
|
94
|
+
<PhilaButton variant="destructive">Destructive</PhilaButton>
|
|
95
|
+
<PhilaButton variant="standard" icon-only :left-icon="faSearch">Standard Icon</PhilaButton>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Sizes
|
|
99
|
+
|
|
100
|
+
```vue
|
|
101
|
+
<PhilaButton size="extra-large">Extra Large</PhilaButton>
|
|
102
|
+
<PhilaButton size="large">Large</PhilaButton>
|
|
103
|
+
<PhilaButton size="medium">Medium (default)</PhilaButton>
|
|
104
|
+
<PhilaButton size="small">Small</PhilaButton>
|
|
105
|
+
<PhilaButton size="extra-small">Extra Small</PhilaButton>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Link Buttons
|
|
109
|
+
|
|
110
|
+
Buttons can also render as links by providing an `href` prop:
|
|
40
111
|
|
|
112
|
+
```vue
|
|
41
113
|
<script setup lang="ts">
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
};
|
|
114
|
+
import { PhilaButton } from "@phila/phila-ui-button";
|
|
115
|
+
import { faArrowRight } from "@fortawesome/pro-solid-svg-icons";
|
|
45
116
|
</script>
|
|
117
|
+
|
|
118
|
+
<template>
|
|
119
|
+
<!-- Internal link -->
|
|
120
|
+
<PhilaButton href="/about" text="Learn More" />
|
|
121
|
+
|
|
122
|
+
<!-- External link -->
|
|
123
|
+
<PhilaButton
|
|
124
|
+
href="https://example.com"
|
|
125
|
+
target="_blank"
|
|
126
|
+
rel="noopener noreferrer"
|
|
127
|
+
text="Visit Site"
|
|
128
|
+
:icon="faArrowRight"
|
|
129
|
+
icon-right
|
|
130
|
+
/>
|
|
131
|
+
</template>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### States
|
|
135
|
+
|
|
136
|
+
```vue
|
|
137
|
+
<PhilaButton disabled>Disabled Button</PhilaButton>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Using CSS Classes Directly
|
|
141
|
+
|
|
142
|
+
You can also use the button styles directly without the Vue component by applying CSS classes to any element:
|
|
143
|
+
|
|
144
|
+
```vue
|
|
145
|
+
<template>
|
|
146
|
+
<button class="phila-button phila-button--primary is-medium" @click="handleClick">Medium primary button</button>
|
|
147
|
+
|
|
148
|
+
<a class="phila-button phila-button--primary" href="#" @click.prevent="handleClick"> Link as a button </a>
|
|
149
|
+
</template>
|
|
46
150
|
```
|
|
47
151
|
|
|
48
152
|
## Button Classes
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { BaseIconProps } from '@phila/phila-ui-core';
|
|
2
|
+
import { BaseProps } from '@phila/phila-ui-core';
|
|
3
|
+
import { ComponentSize } from '@phila/phila-ui-core';
|
|
4
|
+
import { DefineSetupFnComponent } from 'vue';
|
|
5
|
+
import { PublicProps } from 'vue';
|
|
6
|
+
import { RouteLocationRaw } from '@phila/phila-ui-core';
|
|
7
|
+
|
|
8
|
+
declare const __VLS_component: DefineSetupFnComponent<Record<string, any>, {}, {}, Record<string, any> & {}, PublicProps>;
|
|
9
|
+
|
|
10
|
+
declare function __VLS_template(): {
|
|
11
|
+
default?(_: {}): any;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
declare type __VLS_WithTemplateSlots<T, S> = T & {
|
|
15
|
+
new (): {
|
|
16
|
+
$slots: S;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
declare interface BaseButtonProps extends BaseProps, BaseIconProps {
|
|
21
|
+
/** Button variant type */
|
|
22
|
+
variant?: ButtonVariant;
|
|
23
|
+
/** Button size */
|
|
24
|
+
size?: ComponentSize;
|
|
25
|
+
/** Whether the button is an icon-only button */
|
|
26
|
+
iconOnly?: boolean;
|
|
27
|
+
/** Whether to position the icon on the right side */
|
|
28
|
+
iconRight?: boolean;
|
|
29
|
+
/** Button text content (alternative to using slot) */
|
|
30
|
+
text?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export declare type ButtonProps = EventButtonProps | LinkButtonProps;
|
|
34
|
+
|
|
35
|
+
export declare type ButtonVariant = "primary" | "secondary" | "destructive" | "standard";
|
|
36
|
+
|
|
37
|
+
export declare interface EventButtonProps extends BaseButtonProps {
|
|
38
|
+
/** No href or to - renders as <button> */
|
|
39
|
+
href?: never;
|
|
40
|
+
to?: never;
|
|
41
|
+
/** Link target - not available for buttons */
|
|
42
|
+
target?: never;
|
|
43
|
+
/** Link rel - not available for buttons */
|
|
44
|
+
rel?: never;
|
|
45
|
+
/** Whether the button is disabled */
|
|
46
|
+
disabled?: boolean;
|
|
47
|
+
clickTarget?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export declare interface HtmlLinkButtonProps extends BaseButtonProps {
|
|
51
|
+
/** URL for link buttons */
|
|
52
|
+
href: string;
|
|
53
|
+
/** No to prop for HTML buttons */
|
|
54
|
+
to?: never;
|
|
55
|
+
/** Link target attribute (e.g., "_blank") */
|
|
56
|
+
target?: string;
|
|
57
|
+
/** Link rel attribute (e.g., "noopener noreferrer") */
|
|
58
|
+
rel?: string;
|
|
59
|
+
/** Whether the button is disabled */
|
|
60
|
+
disabled?: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export declare type LinkButtonProps = HtmlLinkButtonProps | RouterLinkButtonProps;
|
|
64
|
+
|
|
65
|
+
export declare const PhilaButton: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
|
|
66
|
+
|
|
67
|
+
export declare interface RouterLinkButtonProps extends BaseButtonProps {
|
|
68
|
+
/** Vue Router route location */
|
|
69
|
+
to: RouteLocationRaw;
|
|
70
|
+
/** No href for router buttons */
|
|
71
|
+
href?: never;
|
|
72
|
+
/** No target for router buttons */
|
|
73
|
+
target?: never;
|
|
74
|
+
/** No rel for router buttons */
|
|
75
|
+
rel?: never;
|
|
76
|
+
/** Whether the button is disabled */
|
|
77
|
+
disabled?: boolean;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export { }
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),o=require("@phila/phila-ui-core"),c=["disabled"],u=e.defineComponent({inheritAttrs:!1,__name:"PhlButton",props:{href:{},to:{},target:{},rel:{},disabled:{type:Boolean,default:!1},clickTarget:{},variant:{default:"primary"},size:{default:"medium"},iconOnly:{type:Boolean,default:!1},iconRight:{type:Boolean},text:{},className:{},iconDefinition:{},iconClass:{},src:{},svgRaw:{}},setup(s){const t=s,a=n=>"href"in n&&n.href!==void 0||"to"in n&&n.to!==void 0,i=e.computed(()=>o.cn("phila-button",`phila-button--${t.variant}`,t.size&&`is-${t.size}`,t.iconOnly&&"icon-button",t.iconOnly&&t.variant==="standard"&&"icon-button--standard",t.className)),l=e.computed(()=>a(t)?"to"in t&&t.to!==void 0?{to:t.to,disabled:t.disabled,className:i.value}:{href:t.href,target:t.target,rel:t.rel,disabled:t.disabled,className:i.value}:{}),r=e.computed(()=>({iconDefinition:t.iconDefinition,iconClass:t.iconClass,src:t.src,iconRight:t.iconRight,iconOnly:t.iconOnly,text:t.text,size:t.size}));return(n,d)=>a(t)?(e.openBlock(),e.createBlock(e.unref(o.BaseLink),e.mergeProps({key:0},{...l.value,...n.$attrs},{role:"button"}),{default:e.withCtx(()=>[e.createVNode(e.unref(o.ActionContent),e.normalizeProps(e.guardReactiveProps(r.value)),{default:e.withCtx(()=>[e.renderSlot(n.$slots,"default",{},()=>[e.createTextVNode(e.toDisplayString(t.text),1)])]),_:3},16)]),_:3},16)):(e.openBlock(),e.createElementBlock("button",e.mergeProps({key:1,type:"button",disabled:t.disabled,class:i.value},n.$attrs),[e.createVNode(e.unref(o.ActionContent),e.normalizeProps(e.guardReactiveProps(r.value)),{default:e.withCtx(()=>[e.renderSlot(n.$slots,"default",{},()=>[e.createTextVNode(e.toDisplayString(t.text),1)])]),_:3},16)],16,c))}});exports.PhilaButton=u;
|
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,84 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
|
|
1
|
+
import { defineComponent as g, computed as o, createBlock as B, createElementBlock as k, openBlock as r, unref as a, mergeProps as c, withCtx as i, createVNode as d, normalizeProps as u, guardReactiveProps as f, renderSlot as m, createTextVNode as p, toDisplayString as b } from "vue";
|
|
2
|
+
import { cn as C, BaseLink as P, ActionContent as h } from "@phila/phila-ui-core";
|
|
3
|
+
const _ = ["disabled"], x = /* @__PURE__ */ g({
|
|
4
|
+
inheritAttrs: !1,
|
|
3
5
|
__name: "PhlButton",
|
|
4
6
|
props: {
|
|
5
|
-
|
|
7
|
+
href: {},
|
|
8
|
+
to: {},
|
|
9
|
+
target: {},
|
|
10
|
+
rel: {},
|
|
11
|
+
disabled: { type: Boolean, default: !1 },
|
|
12
|
+
clickTarget: {},
|
|
13
|
+
variant: { default: "primary" },
|
|
14
|
+
size: { default: "medium" },
|
|
15
|
+
iconOnly: { type: Boolean, default: !1 },
|
|
16
|
+
iconRight: { type: Boolean },
|
|
17
|
+
text: {},
|
|
18
|
+
className: {},
|
|
19
|
+
iconDefinition: {},
|
|
20
|
+
iconClass: {},
|
|
21
|
+
src: {},
|
|
22
|
+
svgRaw: {}
|
|
6
23
|
},
|
|
7
|
-
setup(
|
|
8
|
-
const t = e
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
24
|
+
setup(v) {
|
|
25
|
+
const t = v, s = (e) => "href" in e && e.href !== void 0 || "to" in e && e.to !== void 0, n = o(() => C(
|
|
26
|
+
"phila-button",
|
|
27
|
+
`phila-button--${t.variant}`,
|
|
28
|
+
t.size && `is-${t.size}`,
|
|
29
|
+
t.iconOnly && "icon-button",
|
|
30
|
+
t.iconOnly && t.variant === "standard" && "icon-button--standard",
|
|
31
|
+
t.className
|
|
32
|
+
)), y = o(() => s(t) ? "to" in t && t.to !== void 0 ? {
|
|
33
|
+
to: t.to,
|
|
34
|
+
disabled: t.disabled,
|
|
35
|
+
className: n.value
|
|
36
|
+
} : {
|
|
37
|
+
href: t.href,
|
|
38
|
+
target: t.target,
|
|
39
|
+
rel: t.rel,
|
|
40
|
+
disabled: t.disabled,
|
|
41
|
+
className: n.value
|
|
42
|
+
} : {}), l = o(
|
|
43
|
+
() => ({
|
|
44
|
+
iconDefinition: t.iconDefinition,
|
|
45
|
+
iconClass: t.iconClass,
|
|
46
|
+
src: t.src,
|
|
47
|
+
iconRight: t.iconRight,
|
|
48
|
+
iconOnly: t.iconOnly,
|
|
49
|
+
text: t.text,
|
|
50
|
+
size: t.size
|
|
51
|
+
})
|
|
52
|
+
);
|
|
53
|
+
return (e, z) => s(t) ? (r(), B(a(P), c({ key: 0 }, { ...y.value, ...e.$attrs }, { role: "button" }), {
|
|
54
|
+
default: i(() => [
|
|
55
|
+
d(a(h), u(f(l.value)), {
|
|
56
|
+
default: i(() => [
|
|
57
|
+
m(e.$slots, "default", {}, () => [
|
|
58
|
+
p(b(t.text), 1)
|
|
59
|
+
])
|
|
60
|
+
]),
|
|
61
|
+
_: 3
|
|
62
|
+
}, 16)
|
|
63
|
+
]),
|
|
64
|
+
_: 3
|
|
65
|
+
}, 16)) : (r(), k("button", c({
|
|
66
|
+
key: 1,
|
|
67
|
+
type: "button",
|
|
68
|
+
disabled: t.disabled,
|
|
69
|
+
class: n.value
|
|
70
|
+
}, e.$attrs), [
|
|
71
|
+
d(a(h), u(f(l.value)), {
|
|
72
|
+
default: i(() => [
|
|
73
|
+
m(e.$slots, "default", {}, () => [
|
|
74
|
+
p(b(t.text), 1)
|
|
75
|
+
])
|
|
76
|
+
]),
|
|
77
|
+
_: 3
|
|
78
|
+
}, 16)
|
|
79
|
+
], 16, _));
|
|
12
80
|
}
|
|
13
81
|
});
|
|
14
82
|
export {
|
|
15
|
-
|
|
83
|
+
x as PhilaButton
|
|
16
84
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phila/phila-ui-button",
|
|
3
|
-
"version": "2.0.3",
|
|
3
|
+
"version": "2.1.0-beta.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Button component for Phila UI library",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,10 +25,12 @@
|
|
|
25
25
|
"author": "",
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"vue": "^3.0.0"
|
|
28
|
+
"vue": "^3.0.0",
|
|
29
|
+
"@fortawesome/fontawesome-svg-core": "^7.1.0",
|
|
30
|
+
"@fortawesome/vue-fontawesome": "^3.1.2"
|
|
29
31
|
},
|
|
30
32
|
"dependencies": {
|
|
31
|
-
"@phila/phila-ui-core": "2.
|
|
33
|
+
"@phila/phila-ui-core": "2.2.0-beta.3"
|
|
32
34
|
},
|
|
33
35
|
"devDependencies": {
|
|
34
36
|
"@types/node": "^24.0.0",
|