@robuust-digital/vue-components 1.0.0-rc.1
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/LICENSE +21 -0
- package/README.md +193 -0
- package/dist/favicon.ico +0 -0
- package/dist/nuxt-module.js +26 -0
- package/dist/tailwind/components/button.js +270 -0
- package/dist/tailwind/index.js +20 -0
- package/dist/vue-components.es.js +80 -0
- package/dist/vue-components.umd.js +1 -0
- package/package.json +78 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Robuust Digital
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Robuust Vue 3 Components
|
|
2
|
+
|
|
3
|
+
A modern and customizable component library built with **Vue 3** and **Tailwind CSS**, designed to deliver a flexible, cohesive UI experience across all projects. Quickly integrate reusable components with ease, and customize them to suit your unique branding needs.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✨ **Vue 3 Components**: Carefully crafted components that work seamlessly with Vue 3
|
|
8
|
+
- 💎 **Tailwind CSS Integration**: Leverage Tailwind CSS for styling, with full theme customization support
|
|
9
|
+
- 🎨 **Theming & Customization**: Tailor components to your project’s branding directly from the `tailwind.config.js`
|
|
10
|
+
- 🖖🏽 **Accessibility First**: Components are designed with accessibility in mind, ensuring compliance with best practices
|
|
11
|
+
- 📦 **Nuxt 3 module available**: Easily integrate with Nuxt 3 projects for seamless server-side rendering and enhanced performance
|
|
12
|
+
|
|
13
|
+
## Docs
|
|
14
|
+
|
|
15
|
+
[**See online docs**](https://robuust-vue-components.netlify.app/)
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
1. **Install the component library via yarn:**
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
yarn add @robuust/vue-components
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
2. **Add the component library plugin to your `tailwind.config.js`:**
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
// tailwind.config.js
|
|
29
|
+
import components from '@robuust/vue-components/src/tailwind';
|
|
30
|
+
|
|
31
|
+
export default {
|
|
32
|
+
theme: {
|
|
33
|
+
extend: {
|
|
34
|
+
// Customize component styles here
|
|
35
|
+
components: (theme) => ({
|
|
36
|
+
button: {
|
|
37
|
+
primary: {
|
|
38
|
+
backgroundColor: theme('colors.yellow.500'),
|
|
39
|
+
color: '#000',
|
|
40
|
+
},
|
|
41
|
+
secondary: {
|
|
42
|
+
backgroundColor: theme('colors.blue.500'),
|
|
43
|
+
color: '#fff',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
plugins: [components],
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## For Nuxt 3 Projects
|
|
54
|
+
|
|
55
|
+
**Add the module to your `nuxt.config.ts` or `nuxt.config.js`:**
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
export default defineNuxtConfig({
|
|
59
|
+
modules: ['@robuust/vue-components/nuxt'],
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
This will automatically register all components globally in your Nuxt application, making them available for immediate use.
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
Import and use components in your Vue 3 project with ease. Here’s an example of how to use the `ButtonBase` component:
|
|
68
|
+
|
|
69
|
+
```vue
|
|
70
|
+
<template>
|
|
71
|
+
<ButtonBase color="primary" label="Click Me" />
|
|
72
|
+
</template>
|
|
73
|
+
|
|
74
|
+
<script setup>
|
|
75
|
+
import { ButtonBase } from '@robuust/vue-components';
|
|
76
|
+
</script>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Props
|
|
80
|
+
|
|
81
|
+
- `label`: `String` – Button text label. Default is an empty string.
|
|
82
|
+
- `color`: `String` – Button color, accepts primary, secondary, or light. Default is primary.
|
|
83
|
+
- `as`: `String | Object | Function` – Render as a different component (e.g., NuxtLink or a). Default is `button`.
|
|
84
|
+
|
|
85
|
+
## Customizing with Tailwind CSS
|
|
86
|
+
|
|
87
|
+
Tailor component styles by overriding default values in `tailwind.config.js`. This allows you to establish a consistent design system across projects:
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
// tailwind.config.js
|
|
91
|
+
module.exports = {
|
|
92
|
+
theme: {
|
|
93
|
+
extend: {
|
|
94
|
+
components: (theme) => ({
|
|
95
|
+
button: {
|
|
96
|
+
primary: {
|
|
97
|
+
backgroundColor: theme('colors.yellow.500'),
|
|
98
|
+
color: '#000',
|
|
99
|
+
},
|
|
100
|
+
secondary: {
|
|
101
|
+
backgroundColor: theme('colors.blue.500'),
|
|
102
|
+
color: '#fff',
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
}),
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Example Tailwind Configuration
|
|
112
|
+
|
|
113
|
+
With this configuration, you can create a custom theme for buttons and other components. Each project can apply its own colors and style variants by simply adjusting these values.
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
### Setup custom button classes and styling
|
|
117
|
+
|
|
118
|
+
You also can define **custom** color button classes and styling. You can set `backgroundColor`, `color`, `hoverBackgroundColor`, `hoverColor` and additional `styles: {}` and `hoverStyles: {}` within the `custom` key:
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
// tailwind.config.js
|
|
122
|
+
module.exports = {
|
|
123
|
+
theme: {
|
|
124
|
+
extend: {
|
|
125
|
+
components: (theme) => ({
|
|
126
|
+
button: {
|
|
127
|
+
custom: {
|
|
128
|
+
foo: {
|
|
129
|
+
backgroundColor: theme('colors.pink.500'),
|
|
130
|
+
color: theme('colors.white'),
|
|
131
|
+
hoverBackgroundColor: theme('colors.pink.600'),
|
|
132
|
+
hoverColor: theme('colors.white'),
|
|
133
|
+
styles: {},
|
|
134
|
+
hoverStyles: {},
|
|
135
|
+
},
|
|
136
|
+
bar: {
|
|
137
|
+
backgroundColor: theme('colors.teal.500'),
|
|
138
|
+
color: theme('colors.white'),
|
|
139
|
+
hoverBackgroundColor: theme('colors.teal.600'),
|
|
140
|
+
hoverColor: theme('colors.white'),
|
|
141
|
+
styles: {},
|
|
142
|
+
hoverStyles: {},
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
}),
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```vue
|
|
153
|
+
<template>
|
|
154
|
+
<ButtonBase color="custom-foo" label="Custom Foo Button" />
|
|
155
|
+
<ButtonBase color="custom-bar" label="Custom Bar Button" />
|
|
156
|
+
</template>
|
|
157
|
+
|
|
158
|
+
<script setup>
|
|
159
|
+
import { ButtonBase } from '@robuust/vue-components';
|
|
160
|
+
</script>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Development
|
|
164
|
+
|
|
165
|
+
To contribute or make adjustments:
|
|
166
|
+
|
|
167
|
+
1. **Clone the repository** and install dependencies:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
git clone https://github.com/robuust/vue-components.git
|
|
171
|
+
cd component-library
|
|
172
|
+
yarn install
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
2. **Run the development server** to preview components:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
yarn dev
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
3. **Build for production**:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
yarn build
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
## License
|
|
189
|
+
|
|
190
|
+
MIT © Robuust Digital
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
*With `@robuust/vue-components`, bring consistency, flexibility, and a polished look to all your Vue 3 applications.*
|
package/dist/favicon.ico
ADDED
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { defineNuxtModule, addComponent } from '@nuxt/kit';
|
|
2
|
+
import * as components from '@robuust/vue-components';
|
|
3
|
+
import pkg from '../package.json';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Nuxt module to register Vue components globally.
|
|
7
|
+
*
|
|
8
|
+
* @type {import('@nuxt/kit').NuxtModule}
|
|
9
|
+
*/
|
|
10
|
+
export default defineNuxtModule({
|
|
11
|
+
meta: {
|
|
12
|
+
name: pkg.name,
|
|
13
|
+
configKey: 'vueComponents',
|
|
14
|
+
version: pkg.version,
|
|
15
|
+
},
|
|
16
|
+
setup() {
|
|
17
|
+
Object.keys(components).forEach((name) => {
|
|
18
|
+
addComponent({
|
|
19
|
+
name,
|
|
20
|
+
filePath: '@robuust/vue-components',
|
|
21
|
+
export: name,
|
|
22
|
+
global: true,
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Button component
|
|
3
|
+
*
|
|
4
|
+
* @param {Object} theme - The global theme object
|
|
5
|
+
*/
|
|
6
|
+
export default (theme) => {
|
|
7
|
+
const customColors = theme('components.button.custom') || {};
|
|
8
|
+
const customColorStyles = Object.keys(customColors).reduce((acc, colorName) => {
|
|
9
|
+
acc[`&.button-custom-${colorName}`] = {
|
|
10
|
+
backgroundColor: customColors[colorName].backgroundColor,
|
|
11
|
+
color: customColors[colorName].color,
|
|
12
|
+
...customColors[colorName].styles,
|
|
13
|
+
'&:hover': {
|
|
14
|
+
backgroundColor: customColors[colorName].hoverBackgroundColor,
|
|
15
|
+
color: customColors[colorName].hoverColor,
|
|
16
|
+
...customColors[colorName].hoverStyles,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
return acc;
|
|
20
|
+
}, {});
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
'.button': {
|
|
24
|
+
'@apply inline-flex items-center justify-center text-center h-fit border border-transparent relative': {},
|
|
25
|
+
paddingTop: theme('padding.2'),
|
|
26
|
+
paddingRight: theme('padding.4'),
|
|
27
|
+
paddingBottom: theme('padding.2'),
|
|
28
|
+
paddingLeft: theme('padding.4'),
|
|
29
|
+
gap: theme('gap.2'),
|
|
30
|
+
borderRadius: theme('borderRadius.xl'),
|
|
31
|
+
fontWeight: theme('fontWeight.medium'),
|
|
32
|
+
fontSize: theme('fontSize.base'),
|
|
33
|
+
whiteSpace: theme('whitespace.normal'),
|
|
34
|
+
transitionProperty: theme('transitionProperty.colors'),
|
|
35
|
+
transitionDuration: theme('transitionDuration.300'),
|
|
36
|
+
transitionTimingFunction: theme('transitionTimingFunction.DEFAULT'),
|
|
37
|
+
...theme('components.button'),
|
|
38
|
+
|
|
39
|
+
// Icon styling
|
|
40
|
+
'.button-icon': {
|
|
41
|
+
'@apply block': {},
|
|
42
|
+
width: theme('width.5'),
|
|
43
|
+
height: theme('height.5'),
|
|
44
|
+
flexShrink: theme('flexShrink.0'),
|
|
45
|
+
...theme('components.button.icon'),
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
// Color variants
|
|
49
|
+
'&.button-primary': {
|
|
50
|
+
backgroundColor: theme('colors.lime.400'),
|
|
51
|
+
color: theme('colors.black'),
|
|
52
|
+
...theme('components.button.primary'),
|
|
53
|
+
|
|
54
|
+
'&:hover': {
|
|
55
|
+
backgroundColor: theme('colors.lime.600'),
|
|
56
|
+
color: theme('colors.black'),
|
|
57
|
+
...theme('components.button.primary.hover'),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
'&.button-primary-soft': {
|
|
61
|
+
backgroundColor: theme('colors.lime.200'),
|
|
62
|
+
color: theme('colors.lime.600'),
|
|
63
|
+
...theme('components.button.primary-soft'),
|
|
64
|
+
|
|
65
|
+
'&:hover': {
|
|
66
|
+
backgroundColor: theme('colors.lime.300'),
|
|
67
|
+
color: theme('colors.700'),
|
|
68
|
+
...theme('components.button.primary-soft.hover'),
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
'&.button-secondary': {
|
|
72
|
+
backgroundColor: theme('colors.indigo.400'),
|
|
73
|
+
color: theme('colors.white'),
|
|
74
|
+
...theme('components.button.secondary'),
|
|
75
|
+
|
|
76
|
+
'&:hover': {
|
|
77
|
+
backgroundColor: theme('colors.indigo.600'),
|
|
78
|
+
color: theme('colors.white'),
|
|
79
|
+
...theme('components.button.secondary.hover'),
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
'&.button-secondary-soft': {
|
|
83
|
+
backgroundColor: theme('colors.indigo.200'),
|
|
84
|
+
color: theme('colors.indigo.600'),
|
|
85
|
+
...theme('components.button.secondary-soft'),
|
|
86
|
+
|
|
87
|
+
'&:hover': {
|
|
88
|
+
backgroundColor: theme('colors.indigo.300'),
|
|
89
|
+
color: theme('colors.700'),
|
|
90
|
+
...theme('components.button.secondary-soft.hover'),
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
'&.button-tertiary': {
|
|
94
|
+
backgroundColor: theme('colors.orange.400'),
|
|
95
|
+
color: theme('colors.black'),
|
|
96
|
+
...theme('components.button.tertiary'),
|
|
97
|
+
|
|
98
|
+
'&:hover': {
|
|
99
|
+
backgroundColor: theme('colors.orange.600'),
|
|
100
|
+
color: theme('colors.black'),
|
|
101
|
+
...theme('components.button.tertiary.hover'),
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
'&.button-tertiary-soft': {
|
|
105
|
+
backgroundColor: theme('colors.orange.200'),
|
|
106
|
+
color: theme('colors.orange.600'),
|
|
107
|
+
...theme('components.button.tertiary-soft'),
|
|
108
|
+
|
|
109
|
+
'&:hover': {
|
|
110
|
+
backgroundColor: theme('colors.orange.300'),
|
|
111
|
+
color: theme('colors.700'),
|
|
112
|
+
...theme('components.button.tertiary-soft.hover'),
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
'&.button-light': {
|
|
116
|
+
backgroundColor: theme('colors.white'),
|
|
117
|
+
color: theme('colors.stone.800'),
|
|
118
|
+
borderColor: theme('colors.stone.300'),
|
|
119
|
+
...theme('components.button.light'),
|
|
120
|
+
|
|
121
|
+
'&:hover': {
|
|
122
|
+
backgroundColor: theme('colors.stone.100'),
|
|
123
|
+
color: theme('colors.stone.900'),
|
|
124
|
+
...theme('components.button.light.hover'),
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
'&.button-dark': {
|
|
128
|
+
backgroundColor: theme('colors.black'),
|
|
129
|
+
color: theme('colors.white'),
|
|
130
|
+
...theme('components.button.dark'),
|
|
131
|
+
|
|
132
|
+
'&:hover': {
|
|
133
|
+
backgroundColor: theme('colors.stone.800'),
|
|
134
|
+
color: theme('colors.white'),
|
|
135
|
+
...theme('components.button.dark.hover'),
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
'&.button-danger': {
|
|
139
|
+
backgroundColor: theme('colors.red.600'),
|
|
140
|
+
color: theme('colors.white'),
|
|
141
|
+
...theme('components.button.danger'),
|
|
142
|
+
|
|
143
|
+
'&:hover': {
|
|
144
|
+
backgroundColor: theme('colors.red.700'),
|
|
145
|
+
color: theme('colors.white'),
|
|
146
|
+
...theme('components.button.danger.hover'),
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
'&.button-danger-soft': {
|
|
150
|
+
backgroundColor: theme('colors.red.200'),
|
|
151
|
+
color: theme('colors.red.600'),
|
|
152
|
+
...theme('components.button.danger-soft'),
|
|
153
|
+
|
|
154
|
+
'&:hover': {
|
|
155
|
+
backgroundColor: theme('colors.red.300'),
|
|
156
|
+
color: theme('colors.700'),
|
|
157
|
+
...theme('components.button.danger-soft.hover'),
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
'&.button-warning': {
|
|
161
|
+
backgroundColor: theme('colors.yellow.400'),
|
|
162
|
+
color: theme('colors.black'),
|
|
163
|
+
...theme('components.button.warning'),
|
|
164
|
+
|
|
165
|
+
'&:hover': {
|
|
166
|
+
backgroundColor: theme('colors.yellow.300'),
|
|
167
|
+
color: theme('colors.black'),
|
|
168
|
+
...theme('components.button.warning.hover'),
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
'&.button-warning-soft': {
|
|
172
|
+
backgroundColor: theme('colors.yellow.200'),
|
|
173
|
+
color: theme('colors.yellow.600'),
|
|
174
|
+
...theme('components.button.warning-soft'),
|
|
175
|
+
|
|
176
|
+
'&:hover': {
|
|
177
|
+
backgroundColor: theme('colors.yellow.300'),
|
|
178
|
+
color: theme('colors.700'),
|
|
179
|
+
...theme('components.button.warning-soft.hover'),
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
'&.button-success': {
|
|
183
|
+
backgroundColor: theme('colors.green.500'),
|
|
184
|
+
color: theme('colors.white'),
|
|
185
|
+
...theme('components.button.success'),
|
|
186
|
+
|
|
187
|
+
'&:hover': {
|
|
188
|
+
backgroundColor: theme('colors.green.700'),
|
|
189
|
+
color: theme('colors.white'),
|
|
190
|
+
...theme('components.button.success.hover'),
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
'&.button-success-soft': {
|
|
194
|
+
backgroundColor: theme('colors.green.200'),
|
|
195
|
+
color: theme('colors.green.600'),
|
|
196
|
+
...theme('components.button.success-soft'),
|
|
197
|
+
|
|
198
|
+
'&:hover': {
|
|
199
|
+
backgroundColor: theme('colors.green.300'),
|
|
200
|
+
color: theme('colors.700'),
|
|
201
|
+
...theme('components.button.success-soft.hover'),
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
'&.button-clear': {
|
|
205
|
+
'@apply bg-transparent px-0': {},
|
|
206
|
+
color: theme('colors.stone.600'),
|
|
207
|
+
...theme('components.button.clear'),
|
|
208
|
+
|
|
209
|
+
'&:hover': {
|
|
210
|
+
color: theme('colors.stone.800'),
|
|
211
|
+
...theme('components.button.clear.hover'),
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
...customColorStyles,
|
|
215
|
+
|
|
216
|
+
// Size variants
|
|
217
|
+
'&.button-xs': {
|
|
218
|
+
paddingTop: theme('padding.1'),
|
|
219
|
+
paddingRight: theme('padding.2'),
|
|
220
|
+
paddingBottom: theme('padding.1'),
|
|
221
|
+
paddingLeft: theme('padding.2'),
|
|
222
|
+
gap: theme('gap[1.5]'),
|
|
223
|
+
borderRadius: theme('borderRadius.md'),
|
|
224
|
+
fontWeight: theme('fontWeight.medium'),
|
|
225
|
+
fontSize: theme('fontSize.xs'),
|
|
226
|
+
...theme('components.button.xs'),
|
|
227
|
+
|
|
228
|
+
'.button-icon': {
|
|
229
|
+
width: theme('width.3'),
|
|
230
|
+
height: theme('height.3'),
|
|
231
|
+
...theme('components.button.xs.icon'),
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
'&.button-sm': {
|
|
235
|
+
paddingTop: theme('padding[1.5]'),
|
|
236
|
+
paddingRight: theme('padding.3'),
|
|
237
|
+
paddingBottom: theme('padding[1.5]'),
|
|
238
|
+
paddingLeft: theme('padding.3'),
|
|
239
|
+
gap: theme('gap.2'),
|
|
240
|
+
borderRadius: theme('borderRadius.lg'),
|
|
241
|
+
fontWeight: theme('fontWeight.medium'),
|
|
242
|
+
fontSize: theme('fontSize.sm'),
|
|
243
|
+
...theme('components.button.sm'),
|
|
244
|
+
|
|
245
|
+
'.button-icon': {
|
|
246
|
+
width: theme('width.4'),
|
|
247
|
+
height: theme('height.4'),
|
|
248
|
+
...theme('components.button.sm.icon'),
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
'&.button-lg': {
|
|
252
|
+
paddingTop: theme('padding[2.5]'),
|
|
253
|
+
paddingRight: theme('padding.6'),
|
|
254
|
+
paddingBottom: theme('padding[2.5]'),
|
|
255
|
+
paddingLeft: theme('padding.6'),
|
|
256
|
+
gap: theme('gap.4'),
|
|
257
|
+
borderRadius: theme('borderRadius.2xl'),
|
|
258
|
+
fontWeight: theme('fontWeight.medium'),
|
|
259
|
+
fontSize: theme('fontSize.lg'),
|
|
260
|
+
...theme('components.button.lg'),
|
|
261
|
+
|
|
262
|
+
'.button-icon': {
|
|
263
|
+
width: theme('width.6'),
|
|
264
|
+
height: theme('height.6'),
|
|
265
|
+
...theme('components.button.lg.icon'),
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin';
|
|
2
|
+
|
|
3
|
+
// Components
|
|
4
|
+
import button from './components/button.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Tailwind Theme plugin
|
|
8
|
+
*
|
|
9
|
+
* @type {import('tailwindcss').Plugin}
|
|
10
|
+
*
|
|
11
|
+
* @param {import('tailwindcss').AddComponents} addComponents
|
|
12
|
+
* @param {import('tailwindcss').Theme} theme
|
|
13
|
+
*
|
|
14
|
+
* @returns {void}
|
|
15
|
+
*/
|
|
16
|
+
export default plugin.withOptions(() => ({ addComponents, theme }) => {
|
|
17
|
+
addComponents({
|
|
18
|
+
...button(theme),
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { openBlock as n, createElementBlock as s, createElementVNode as r, createBlock as o, resolveDynamicComponent as l, normalizeClass as c, withCtx as u, createTextVNode as d, toDisplayString as m, renderSlot as i, createCommentVNode as a, unref as y } from "vue";
|
|
2
|
+
const f = {
|
|
3
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4
|
+
fill: "none",
|
|
5
|
+
viewBox: "0 0 24 24"
|
|
6
|
+
};
|
|
7
|
+
function g(t, e) {
|
|
8
|
+
return n(), s("svg", f, e[0] || (e[0] = [
|
|
9
|
+
r("circle", {
|
|
10
|
+
cx: "12",
|
|
11
|
+
cy: "12",
|
|
12
|
+
r: "10",
|
|
13
|
+
stroke: "currentColor",
|
|
14
|
+
"stroke-width": "4",
|
|
15
|
+
style: { opacity: ".25" }
|
|
16
|
+
}, null, -1),
|
|
17
|
+
r("path", {
|
|
18
|
+
fill: "currentColor",
|
|
19
|
+
d: "M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12zm2 5.291A7.96 7.96 0 0 1 4 12H0c0 3.042 1.135 5.824 3 7.938z"
|
|
20
|
+
}, null, -1)
|
|
21
|
+
]));
|
|
22
|
+
}
|
|
23
|
+
const b = { render: g }, w = {
|
|
24
|
+
__name: "ButtonBase",
|
|
25
|
+
props: {
|
|
26
|
+
as: {
|
|
27
|
+
type: [String, Object, Function],
|
|
28
|
+
default: "button"
|
|
29
|
+
},
|
|
30
|
+
label: {
|
|
31
|
+
type: String,
|
|
32
|
+
default: ""
|
|
33
|
+
},
|
|
34
|
+
icon: {
|
|
35
|
+
type: [Object, Function],
|
|
36
|
+
default: null
|
|
37
|
+
},
|
|
38
|
+
iconLeft: {
|
|
39
|
+
type: Boolean
|
|
40
|
+
},
|
|
41
|
+
size: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: "base",
|
|
44
|
+
validator: (t) => ["xs", "sm", "base", "lg"].includes(t)
|
|
45
|
+
},
|
|
46
|
+
spinning: {
|
|
47
|
+
type: Boolean
|
|
48
|
+
},
|
|
49
|
+
color: {
|
|
50
|
+
type: String,
|
|
51
|
+
default: "primary",
|
|
52
|
+
validator: (t) => /^(primary|secondary|tertiary|light|dark|danger|warning|success)(-soft)?$/.test(t) || t.startsWith("custom-") || "clear"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
setup(t) {
|
|
56
|
+
return (e, p) => (n(), o(l(t.as), {
|
|
57
|
+
class: c(["button", `button-${t.color}`, `button-${t.size}`, { "flex-row-reverse": t.iconLeft }])
|
|
58
|
+
}, {
|
|
59
|
+
default: u(() => [
|
|
60
|
+
d(m(t.label) + " ", 1),
|
|
61
|
+
i(e.$slots, "icon", {}, () => [
|
|
62
|
+
t.icon && !t.spinning ? (n(), o(l(t.icon), {
|
|
63
|
+
key: 0,
|
|
64
|
+
class: "button-icon"
|
|
65
|
+
})) : a("", !0)
|
|
66
|
+
]),
|
|
67
|
+
i(e.$slots, "spinner", {}, () => [
|
|
68
|
+
t.spinning ? (n(), o(y(b), {
|
|
69
|
+
key: 0,
|
|
70
|
+
class: "button-icon animate-spin"
|
|
71
|
+
})) : a("", !0)
|
|
72
|
+
])
|
|
73
|
+
]),
|
|
74
|
+
_: 3
|
|
75
|
+
}, 8, ["class"]));
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
export {
|
|
79
|
+
w as ButtonBase
|
|
80
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(n,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(n=typeof globalThis<"u"?globalThis:n||self,e(n.VueComponents={},n.Vue))})(this,function(n,e){"use strict";const i={xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24"};function r(t,o){return e.openBlock(),e.createElementBlock("svg",i,o[0]||(o[0]=[e.createElementVNode("circle",{cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4",style:{opacity:".25"}},null,-1),e.createElementVNode("path",{fill:"currentColor",d:"M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12zm2 5.291A7.96 7.96 0 0 1 4 12H0c0 3.042 1.135 5.824 3 7.938z"},null,-1)]))}const l={render:r},c={__name:"ButtonBase",props:{as:{type:[String,Object,Function],default:"button"},label:{type:String,default:""},icon:{type:[Object,Function],default:null},iconLeft:{type:Boolean},size:{type:String,default:"base",validator:t=>["xs","sm","base","lg"].includes(t)},spinning:{type:Boolean},color:{type:String,default:"primary",validator:t=>/^(primary|secondary|tertiary|light|dark|danger|warning|success)(-soft)?$/.test(t)||t.startsWith("custom-")||"clear"}},setup(t){return(o,s)=>(e.openBlock(),e.createBlock(e.resolveDynamicComponent(t.as),{class:e.normalizeClass(["button",`button-${t.color}`,`button-${t.size}`,{"flex-row-reverse":t.iconLeft}])},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.label)+" ",1),e.renderSlot(o.$slots,"icon",{},()=>[t.icon&&!t.spinning?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(t.icon),{key:0,class:"button-icon"})):e.createCommentVNode("",!0)]),e.renderSlot(o.$slots,"spinner",{},()=>[t.spinning?(e.openBlock(),e.createBlock(e.unref(l),{key:0,class:"button-icon animate-spin"})):e.createCommentVNode("",!0)])]),_:3},8,["class"]))}};n.ButtonBase=c,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@robuust-digital/vue-components",
|
|
3
|
+
"version": "1.0.0-rc.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "A modern and customizable component library built with **Vue 3** and **Tailwind CSS**, designed to deliver a flexible, cohesive UI experience across all projects. Quickly integrate reusable components with ease, and customize them to suit your unique branding needs.",
|
|
6
|
+
"directories": {
|
|
7
|
+
"doc": "docs",
|
|
8
|
+
"test": "tests"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/robuust/vue-components.git"
|
|
13
|
+
},
|
|
14
|
+
"author": "Robuust Digital",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/robuust/vue-components/issues"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/robuust/vue-components#readme",
|
|
20
|
+
"main": "dist/vue-components.umd.js",
|
|
21
|
+
"module": "dist/vue-components.es.js",
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"import": "./dist/vue-components.es.js",
|
|
30
|
+
"require": "./dist/vue-components.umd.js"
|
|
31
|
+
},
|
|
32
|
+
"./tailwind": "./dist/tailwind/index.js",
|
|
33
|
+
"./nuxt": "./dist/nuxt-module.js"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"dev": "nodemon --watch 'tailwind.config.js' --exec 'vite'",
|
|
37
|
+
"build": "vite build",
|
|
38
|
+
"preview": "vite preview",
|
|
39
|
+
"test:unit": "vitest run",
|
|
40
|
+
"lint": "eslint . --fix",
|
|
41
|
+
"npm:login": "npm login",
|
|
42
|
+
"npm:publish": "npm publish --access public",
|
|
43
|
+
"docs:dev": "vitepress dev docs",
|
|
44
|
+
"docs:build": "vitepress build docs",
|
|
45
|
+
"docs:preview": "vitepress preview docs"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@heroicons/vue": "^2.1.5",
|
|
49
|
+
"@nuxt/kit": "^3.13.2",
|
|
50
|
+
"tailwindcss": "^3.4.14",
|
|
51
|
+
"vue": "^3.5.12"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@eslint/eslintrc": "^3.1.0",
|
|
55
|
+
"@eslint/js": "^9.13.0",
|
|
56
|
+
"@vitejs/plugin-vue": "^5.1.4",
|
|
57
|
+
"@vitest/coverage-v8": "^2.1.4",
|
|
58
|
+
"@vue/eslint-config-airbnb": "^8.0.0",
|
|
59
|
+
"@vue/test-utils": "^2.4.6",
|
|
60
|
+
"autoprefixer": "^10.4.20",
|
|
61
|
+
"eslint": "^9.13.0",
|
|
62
|
+
"eslint-plugin-vue": "^9.29.0",
|
|
63
|
+
"jsdom": "^25.0.1",
|
|
64
|
+
"nodemon": "^3.1.7",
|
|
65
|
+
"postcss": "^8.4.47",
|
|
66
|
+
"vite": "^5.4.10",
|
|
67
|
+
"vite-plugin-eslint": "^1.8.1",
|
|
68
|
+
"vite-plugin-static-copy": "^2.0.0",
|
|
69
|
+
"vite-plugin-vue-devtools": "^7.5.3",
|
|
70
|
+
"vite-svg-loader": "^5.1.0",
|
|
71
|
+
"vitepress": "^1.5.0",
|
|
72
|
+
"vitest": "^2.1.4"
|
|
73
|
+
},
|
|
74
|
+
"resolutions": {
|
|
75
|
+
"string-width": "^4.2.0",
|
|
76
|
+
"wrap-ansi": "^7.0.0"
|
|
77
|
+
}
|
|
78
|
+
}
|