Skip to content

Commit 626fbd8

Browse files
committed
feat: add button, icon, and input components with documentation and configuration
1 parent 2d21c73 commit 626fbd8

16 files changed

+447
-142
lines changed

config/vite.base.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { defineConfig } from 'vite';
2+
import vue from '@vitejs/plugin-vue';
3+
import dts from 'vite-plugin-dts';
4+
import { resolve } from 'path';
5+
6+
/**
7+
* Create a base Vite configuration for component packages
8+
* @param {Object} options Configuration options
9+
* @param {string} options.name Package name for library build
10+
* @param {string} options.entry Entry point path
11+
* @param {string[]} options.externals External dependencies
12+
* @returns {import('vite').UserConfig}
13+
*/
14+
export function createBaseConfig(options) {
15+
const { name, entry = 'src/index.ts', externals = ['vue'] } = options;
16+
17+
// Add all vue-web-component-library packages to externals
18+
const allExternals = [
19+
...externals,
20+
/@vue-web-component-library\/.*/
21+
];
22+
23+
return defineConfig({
24+
plugins: [
25+
vue({
26+
customElement: true, // Enable Vue custom elements mode
27+
}),
28+
dts({
29+
include: ['src/**/*.ts', 'src/**/*.vue'],
30+
outDir: 'dist/types',
31+
}),
32+
],
33+
build: {
34+
lib: {
35+
entry: resolve(process.cwd(), entry),
36+
name,
37+
fileName: (format) => `index.${format === 'es' ? 'mjs' : 'js'}`,
38+
formats: ['es', 'cjs'],
39+
},
40+
rollupOptions: {
41+
external: allExternals,
42+
output: {
43+
exports: 'named', // Prevent warnings about mixed exports
44+
globals: {
45+
vue: 'Vue',
46+
},
47+
},
48+
},
49+
},
50+
});
51+
}

packages/components/button/README.md

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Button Component
2+
3+
An accessible, customizable button component for Vue applications, built as a web component.
4+
5+
## Installation
6+
7+
```bash
8+
npm install @vue-web-component-library/button
9+
# or
10+
pnpm add @vue-web-component-library/button
11+
# or
12+
yarn add @vue-web-component-library/button
13+
```
14+
15+
## Usage
16+
17+
```html
18+
<!-- Import the component -->
19+
<script>
20+
import '@vue-web-component-library/button';
21+
</script>
22+
23+
<!-- Basic usage -->
24+
<vwc-button>Click me</vwc-button>
25+
26+
<!-- With variants -->
27+
<vwc-button variant="primary">Primary Button</vwc-button>
28+
<vwc-button variant="secondary">Secondary Button</vwc-button>
29+
<vwc-button variant="outline">Outline Button</vwc-button>
30+
<vwc-button variant="ghost">Ghost Button</vwc-button>
31+
32+
<!-- With sizes -->
33+
<vwc-button size="sm">Small Button</vwc-button>
34+
<vwc-button size="md">Medium Button</vwc-button>
35+
<vwc-button size="lg">Large Button</vwc-button>
36+
37+
<!-- Disabled state -->
38+
<vwc-button disabled>Disabled Button</vwc-button>
39+
40+
<!-- Using slots for complex content -->
41+
<vwc-button>
42+
<span slot="before">🔍</span>
43+
Search
44+
<span slot="after">→</span>
45+
</vwc-button>
46+
```
47+
48+
## Props
49+
50+
| Prop | Type | Default | Description |
51+
|-----------|-------------------------------------|------------|--------------------------------|
52+
| `variant` | `'primary' \| 'secondary' \| 'outline' \| 'ghost'` | `'primary'` | The visual style of the button |
53+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | The size of the button |
54+
| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | The button type attribute |
55+
| `disabled`| `boolean` | `false` | Disables the button when true |
56+
| `id` | `string` | `undefined`| Optional ID for the button |
57+
58+
## Events
59+
60+
| Event | Description |
61+
|---------|---------------------------------------------|
62+
| `click` | Emitted when the button is clicked |
63+
64+
## Slots
65+
66+
| Slot | Description |
67+
|-----------|----------------------------------------|
68+
| (default) | The button text or content |
69+
| `before` | Content to place before the main text |
70+
| `after` | Content to place after the main text |
71+
72+
## Customization
73+
74+
You can customize the appearance of the button by overriding CSS variables:
75+
76+
```css
77+
:root {
78+
/* Base styles */
79+
--vwc-button-gap: 0.75rem;
80+
--vwc-button-font-family: system-ui, sans-serif;
81+
--vwc-button-font-weight: 500;
82+
--vwc-button-radius: 4px;
83+
--vwc-button-border: 1px solid transparent;
84+
--vwc-button-transition: all 0.2s ease-in-out;
85+
--vwc-button-focus-outline: 2px solid currentColor;
86+
--vwc-button-focus-outline-offset: 2px;
87+
--vwc-button-disabled-opacity: 0.5;
88+
89+
/* Size variants */
90+
--vwc-button-sm-font-size: 0.875rem;
91+
--vwc-button-sm-padding: 0.375rem 0.75rem;
92+
--vwc-button-sm-height: 2rem;
93+
94+
--vwc-button-md-font-size: 1rem;
95+
--vwc-button-md-padding: 0.5rem 1rem;
96+
--vwc-button-md-height: 2.5rem;
97+
98+
--vwc-button-lg-font-size: 1.125rem;
99+
--vwc-button-lg-padding: 0.625rem 1.25rem;
100+
--vwc-button-lg-height: 3rem;
101+
102+
/* Primary variant */
103+
--vwc-button-primary-bg: #3b82f6;
104+
--vwc-button-primary-text: white;
105+
--vwc-button-primary-hover-bg: #2563eb;
106+
107+
/* Secondary variant */
108+
--vwc-button-secondary-bg: #9ca3af;
109+
--vwc-button-secondary-text: white;
110+
--vwc-button-secondary-hover-bg: #6b7280;
111+
112+
/* Outline variant */
113+
--vwc-button-outline-bg: transparent;
114+
--vwc-button-outline-text: #3b82f6;
115+
--vwc-button-outline-border: currentColor;
116+
--vwc-button-outline-hover-bg: rgb(59 130 246 / 0.1);
117+
118+
/* Ghost variant */
119+
--vwc-button-ghost-bg: transparent;
120+
--vwc-button-ghost-text: #3b82f6;
121+
--vwc-button-ghost-border: transparent;
122+
--vwc-button-ghost-hover-bg: rgb(59 130 246 / 0.1);
123+
}
124+
```
125+
126+
## Accessibility
127+
128+
- Uses native `<button>` element
129+
- Maintains proper focus states
130+
- Uses `aria-disabled` for disabled state
131+
- Ensures proper color contrast for text/background

packages/components/button/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Accessible Button web component for Vue",
55
"main": "dist/index.js",
66
"module": "dist/index.mjs",
7-
"types": "dist/index.d.ts",
7+
"types": "dist/types/index.d.ts",
88
"files": [
99
"dist"
1010
],

packages/components/button/src/Button.ce.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import { defineProps, defineEmits } from 'vue';
1818
import { BaseProps, Size, Variant } from '@vue-web-component-library/core';
1919
20-
export interface ButtonProps extends BaseProps {
20+
export interface ButtonProps extends /* @vue-ignore */ BaseProps {
2121
/**
2222
* The type of button
2323
*/
+3-27
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,5 @@
1-
import { defineConfig } from 'vite';
2-
import vue from '@vitejs/plugin-vue';
3-
import dts from 'vite-plugin-dts';
4-
import { resolve } from 'path';
1+
import { createBaseConfig } from '../../../config/vite.base.js';
52

6-
export default defineConfig({
7-
plugins: [
8-
vue({
9-
customElement: true, // Enable Vue custom elements mode
10-
}),
11-
dts({ include: ['src/**/*.ts', 'src/**/*.vue'] }),
12-
],
13-
build: {
14-
lib: {
15-
entry: resolve(__dirname, 'src/index.ts'),
16-
name: 'button',
17-
fileName: (format) => `index.${format === 'es' ? 'mjs' : 'js'}`,
18-
formats: ['es', 'cjs'],
19-
},
20-
rollupOptions: {
21-
external: ['vue', /@vue-web-component-library\/*/],
22-
output: {
23-
globals: {
24-
vue: 'Vue',
25-
},
26-
},
27-
},
28-
},
3+
export default createBaseConfig({
4+
name: 'vwcButton',
295
});

packages/components/icon/README.md

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Icon Component
2+
3+
An accessible, customizable icon component for Vue applications using Google Material Icons, built as a web component.
4+
5+
## Installation
6+
7+
```bash
8+
npm install @vue-web-component-library/icon
9+
# or
10+
pnpm add @vue-web-component-library/icon
11+
# or
12+
yarn add @vue-web-component-library/icon
13+
```
14+
15+
## Usage
16+
17+
```html
18+
<!-- Import the component -->
19+
<script>
20+
import '@vue-web-component-library/icon';
21+
</script>
22+
23+
<!-- Basic usage -->
24+
<vwc-icon name="home"></vwc-icon>
25+
26+
<!-- With different sizes -->
27+
<vwc-icon name="star" size="sm"></vwc-icon>
28+
<vwc-icon name="star" size="md"></vwc-icon>
29+
<vwc-icon name="star" size="lg"></vwc-icon>
30+
31+
<!-- With custom color -->
32+
<vwc-icon name="favorite" color="#FF0000"></vwc-icon>
33+
34+
<!-- With animation -->
35+
<vwc-icon name="refresh" spin></vwc-icon>
36+
37+
<!-- With accessibility label -->
38+
<vwc-icon name="delete" label="Delete item"></vwc-icon>
39+
```
40+
41+
## Available Icons
42+
43+
This component uses Google Material Icons. You can find all available icons in the [Material Icons Library](https://fonts.google.com/icons?selected=Material+Icons).
44+
45+
## Props
46+
47+
| Prop | Type | Default | Description |
48+
|-----------|--------------------------|------------|------------------------------------------|
49+
| `name` | `string` | (required) | The name of the Material Icon |
50+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | The size of the icon |
51+
| `color` | `string` | `currentColor` | The color of the icon (CSS color) |
52+
| `label` | `string` | `undefined`| Accessibility label for screen readers |
53+
| `spin` | `boolean` | `false` | Whether the icon should spin |
54+
| `disabled`| `boolean` | `false` | Visually disables the icon when true |
55+
| `id` | `string` | `undefined`| Optional ID for the icon element |
56+
57+
## Accessibility
58+
59+
- Uses appropriate `aria-*` attributes
60+
- Hides decorative icons from screen readers with `aria-hidden="true"`
61+
- Uses `role="img"` and `aria-label` when a label is provided
62+
63+
## Customization
64+
65+
You can customize the appearance of icons by overriding CSS variables:
66+
67+
```css
68+
:root {
69+
/* Base styles */
70+
--vwc-icon-color: currentColor;
71+
--vwc-icon-size: auto;
72+
73+
/* Size variants */
74+
--vwc-icon-sm-size: 1rem;
75+
--vwc-icon-md-size: 1.5rem;
76+
--vwc-icon-lg-size: 2rem;
77+
78+
/* Animation */
79+
--vwc-icon-spin-duration: 2s;
80+
}
81+
```

packages/components/icon/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Accessible Icon web component for Vue using Google Material Icons",
55
"main": "dist/index.js",
66
"module": "dist/index.mjs",
7-
"types": "dist/index.d.ts",
7+
"types": "dist/types/index.d.ts",
88
"files": [
99
"dist"
1010
],

packages/components/icon/src/Icon.ce.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import { defineProps, computed } from 'vue';
1616
import { BaseProps, Size } from '@vue-web-component-library/core';
1717
18-
export interface IconProps extends BaseProps {
18+
export interface IconProps extends /* @vue-ignore */ BaseProps {
1919
/**
2020
* The name of the Material Icon
2121
*/
+3-27
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,5 @@
1-
import { defineConfig } from 'vite';
2-
import vue from '@vitejs/plugin-vue';
3-
import dts from 'vite-plugin-dts';
4-
import { resolve } from 'path';
1+
import { createBaseConfig } from '../../../config/vite.base.js';
52

6-
export default defineConfig({
7-
plugins: [
8-
vue({
9-
customElement: true, // Enable Vue custom elements mode
10-
}),
11-
dts({ include: ['src/**/*.ts', 'src/**/*.vue'] }),
12-
],
13-
build: {
14-
lib: {
15-
entry: resolve(__dirname, 'src/index.ts'),
16-
name: 'icon',
17-
fileName: (format) => `index.${format === 'es' ? 'mjs' : 'js'}`,
18-
formats: ['es', 'cjs'],
19-
},
20-
rollupOptions: {
21-
external: ['vue', /@vue-web-component-library\/*/],
22-
output: {
23-
globals: {
24-
vue: 'Vue',
25-
},
26-
},
27-
},
28-
},
3+
export default createBaseConfig({
4+
name: 'vwcIcon',
295
});

0 commit comments

Comments
 (0)