@allsrvsonline/vue-component-library 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/README.md +242 -0
- package/dist/index.d.ts +1 -0
- package/dist/vite.svg +1 -0
- package/dist/vue-component-library.css +1 -0
- package/dist/vue-component-library.es.js +182 -0
- package/dist/vue-component-library.umd.js +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Vue Component Library
|
|
2
|
+
|
|
3
|
+
A modern, type-safe Vue 3 component library built with TypeScript and Vite. This library provides reusable, well-tested components that follow best practices and strict coding standards.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **TypeScript First** - Full TypeScript support with strict type checking
|
|
8
|
+
- ✅ **Vue 3 Composition API** - Built with modern Vue patterns using `<script setup>`
|
|
9
|
+
- ✅ **Tree-shakeable** - Only import what you need
|
|
10
|
+
- ✅ **Fully Tested** - Comprehensive test coverage with Vitest
|
|
11
|
+
- ✅ **ESLint & Prettier** - Enforced code quality and formatting
|
|
12
|
+
- ✅ **Type Definitions** - Auto-generated `.d.ts` files
|
|
13
|
+
- ✅ **Documented** - JSDoc comments on all public APIs
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @your-org/vue-component-library
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Importing Components
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { BaseButton, BaseInput, BaseCard } from '@your-org/vue-component-library'
|
|
27
|
+
import '@your-org/vue-component-library/style.css'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Component Examples
|
|
31
|
+
|
|
32
|
+
#### BaseButton
|
|
33
|
+
|
|
34
|
+
```vue
|
|
35
|
+
<template>
|
|
36
|
+
<BaseButton variant="primary" size="medium" @click="handleClick"> Click Me </BaseButton>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script setup lang="ts">
|
|
40
|
+
import { BaseButton } from '@your-org/vue-component-library'
|
|
41
|
+
|
|
42
|
+
const handleClick = () => {
|
|
43
|
+
console.log('Button clicked!')
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Props:**
|
|
49
|
+
|
|
50
|
+
- `variant`: `'primary' | 'secondary' | 'success' | 'danger' | 'warning'` (default: `'primary'`)
|
|
51
|
+
- `size`: `'small' | 'medium' | 'large'` (default: `'medium'`)
|
|
52
|
+
- `disabled`: `boolean` (default: `false`)
|
|
53
|
+
- `loading`: `boolean` (default: `false`)
|
|
54
|
+
- `fullWidth`: `boolean` (default: `false`)
|
|
55
|
+
|
|
56
|
+
#### BaseInput
|
|
57
|
+
|
|
58
|
+
```vue
|
|
59
|
+
<template>
|
|
60
|
+
<BaseInput
|
|
61
|
+
v-model="email"
|
|
62
|
+
type="email"
|
|
63
|
+
label="Email Address"
|
|
64
|
+
placeholder="Enter your email"
|
|
65
|
+
:error="emailError"
|
|
66
|
+
required
|
|
67
|
+
/>
|
|
68
|
+
</template>
|
|
69
|
+
|
|
70
|
+
<script setup lang="ts">
|
|
71
|
+
import { ref } from 'vue'
|
|
72
|
+
import { BaseInput } from '@your-org/vue-component-library'
|
|
73
|
+
|
|
74
|
+
const email = ref('')
|
|
75
|
+
const emailError = ref('')
|
|
76
|
+
</script>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Props:**
|
|
80
|
+
|
|
81
|
+
- `modelValue`: `string` - The input value (v-model)
|
|
82
|
+
- `type`: `'text' | 'email' | 'password' | 'number' | 'tel' | 'url'` (default: `'text'`)
|
|
83
|
+
- `label`: `string` - Input label
|
|
84
|
+
- `placeholder`: `string` - Placeholder text
|
|
85
|
+
- `error`: `string` - Error message to display
|
|
86
|
+
- `disabled`: `boolean` (default: `false`)
|
|
87
|
+
- `required`: `boolean` (default: `false`)
|
|
88
|
+
|
|
89
|
+
#### BaseCard
|
|
90
|
+
|
|
91
|
+
```vue
|
|
92
|
+
<template>
|
|
93
|
+
<BaseCard title="User Profile" elevated>
|
|
94
|
+
<p>Card content goes here</p>
|
|
95
|
+
|
|
96
|
+
<template #footer>
|
|
97
|
+
<BaseButton variant="primary">Save</BaseButton>
|
|
98
|
+
</template>
|
|
99
|
+
</BaseCard>
|
|
100
|
+
</template>
|
|
101
|
+
|
|
102
|
+
<script setup lang="ts">
|
|
103
|
+
import { BaseCard, BaseButton } from '@your-org/vue-component-library'
|
|
104
|
+
</script>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Using Composables
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { useValidation, useClickOutside } from '@your-org/vue-component-library'
|
|
111
|
+
|
|
112
|
+
// Form validation
|
|
113
|
+
const { value, error, validate } = useValidation('', (val) =>
|
|
114
|
+
val.length > 0 ? null : 'Field is required'
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
// Click outside detection
|
|
118
|
+
const dropdownRef = ref<HTMLElement>()
|
|
119
|
+
useClickOutside(dropdownRef, () => {
|
|
120
|
+
// Close dropdown
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Using Utilities
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { cn, debounce, generateId } from '@your-org/vue-component-library'
|
|
128
|
+
|
|
129
|
+
// Combine class names
|
|
130
|
+
const classes = cn('btn', isActive && 'btn--active')
|
|
131
|
+
|
|
132
|
+
// Debounce function calls
|
|
133
|
+
const debouncedSearch = debounce(search, 300)
|
|
134
|
+
|
|
135
|
+
// Generate unique IDs
|
|
136
|
+
const id = generateId('input')
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
|
|
141
|
+
### Prerequisites
|
|
142
|
+
|
|
143
|
+
- Node.js 18+
|
|
144
|
+
- npm or pnpm
|
|
145
|
+
|
|
146
|
+
### Setup
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Install dependencies
|
|
150
|
+
npm install
|
|
151
|
+
|
|
152
|
+
# Run development server
|
|
153
|
+
npm run dev
|
|
154
|
+
|
|
155
|
+
# Run tests
|
|
156
|
+
npm run test
|
|
157
|
+
|
|
158
|
+
# Run tests with UI
|
|
159
|
+
npm run test:ui
|
|
160
|
+
|
|
161
|
+
# Build library
|
|
162
|
+
npm run build:lib
|
|
163
|
+
|
|
164
|
+
# Lint code
|
|
165
|
+
npm run lint
|
|
166
|
+
|
|
167
|
+
# Format code
|
|
168
|
+
npm run format
|
|
169
|
+
|
|
170
|
+
# Type check
|
|
171
|
+
npm run type-check
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Project Structure
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
src/
|
|
178
|
+
├── components/ # Vue components
|
|
179
|
+
│ ├── BaseButton.vue
|
|
180
|
+
│ ├── BaseButton.spec.ts
|
|
181
|
+
│ ├── BaseInput.vue
|
|
182
|
+
│ ├── BaseInput.spec.ts
|
|
183
|
+
│ └── BaseCard.vue
|
|
184
|
+
├── composables/ # Composable functions
|
|
185
|
+
│ ├── useValidation.ts
|
|
186
|
+
│ └── useClickOutside.ts
|
|
187
|
+
├── utils/ # Utility functions
|
|
188
|
+
│ └── index.ts
|
|
189
|
+
├── types/ # TypeScript definitions
|
|
190
|
+
│ └── index.ts
|
|
191
|
+
└── index.ts # Main export file
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Design Patterns & Best Practices
|
|
195
|
+
|
|
196
|
+
This library follows strict coding standards:
|
|
197
|
+
|
|
198
|
+
### Component Patterns
|
|
199
|
+
|
|
200
|
+
1. **Composition API with `<script setup>`** - All components use the modern Composition API
|
|
201
|
+
2. **TypeScript Strict Mode** - Full type safety with no `any` types
|
|
202
|
+
3. **Props Validation** - All props are properly typed with interfaces
|
|
203
|
+
4. **Typed Events** - Event emitters use TypeScript interfaces
|
|
204
|
+
5. **Single Responsibility** - Each component has a clear, focused purpose
|
|
205
|
+
|
|
206
|
+
### Code Quality
|
|
207
|
+
|
|
208
|
+
- **ESLint** - Enforces code quality rules
|
|
209
|
+
- **Prettier** - Consistent code formatting
|
|
210
|
+
- **Vitest** - Unit testing with good coverage
|
|
211
|
+
- **JSDoc** - Comprehensive documentation
|
|
212
|
+
|
|
213
|
+
### Naming Conventions
|
|
214
|
+
|
|
215
|
+
- Components: `PascalCase` (e.g., `BaseButton`)
|
|
216
|
+
- Composables: `camelCase` starting with `use` (e.g., `useValidation`)
|
|
217
|
+
- Utilities: `camelCase` (e.g., `generateId`)
|
|
218
|
+
- Types: `PascalCase` (e.g., `ButtonVariant`)
|
|
219
|
+
|
|
220
|
+
## Contributing
|
|
221
|
+
|
|
222
|
+
When contributing components:
|
|
223
|
+
|
|
224
|
+
1. Follow the existing patterns
|
|
225
|
+
2. Add TypeScript types
|
|
226
|
+
3. Write unit tests
|
|
227
|
+
4. Document with JSDoc
|
|
228
|
+
5. Run linting and formatting
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
MIT
|
|
233
|
+
|
|
234
|
+
## Publishing
|
|
235
|
+
|
|
236
|
+
To publish to npm:
|
|
237
|
+
|
|
238
|
+
1. Update version in `package.json`
|
|
239
|
+
2. Build the library: `npm run build:lib`
|
|
240
|
+
3. Publish: `npm publish --access public`
|
|
241
|
+
|
|
242
|
+
Make sure to update `@your-org/vue-component-library` in package.json with your actual organization/package name.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/vite.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--base-button-primary-bg: #3b82f6;--base-button-primary-bg-hover: #2563eb;--base-button-primary-text: white;--base-button-secondary-bg: #6b7280;--base-button-secondary-bg-hover: #4b5563;--base-button-secondary-text: white;--base-button-success-bg: #10b981;--base-button-success-bg-hover: #059669;--base-button-success-text: white;--base-button-danger-bg: #ef4444;--base-button-danger-bg-hover: #dc2626;--base-button-danger-text: white;--base-button-warning-bg: #f59e0b;--base-button-warning-bg-hover: #d97706;--base-button-warning-text: white;--base-button-disabled-opacity: .6;--base-button-loading-opacity: .7}.base-button[data-v-a4a5350a]{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;border:none;border-radius:.375rem;font-weight:500;cursor:pointer;transition:all .2s ease-in-out;font-family:inherit;position:relative}.base-button[data-v-a4a5350a]:focus-visible{outline:2px solid currentColor;outline-offset:2px}.base-button--small[data-v-a4a5350a]{padding:.375rem .75rem;font-size:.875rem}.base-button--medium[data-v-a4a5350a]{padding:.5rem 1rem;font-size:1rem}.base-button--large[data-v-a4a5350a]{padding:.75rem 1.5rem;font-size:1.125rem}.base-button--primary[data-v-a4a5350a]{background-color:var(--base-button-primary-bg);color:var(--base-button-primary-text)}.base-button--primary[data-v-a4a5350a]:hover:not(:disabled){background-color:var(--base-button-primary-bg-hover)}.base-button--secondary[data-v-a4a5350a]{background-color:var(--base-button-secondary-bg);color:var(--base-button-secondary-text)}.base-button--secondary[data-v-a4a5350a]:hover:not(:disabled){background-color:var(--base-button-secondary-bg-hover)}.base-button--success[data-v-a4a5350a]{background-color:var(--base-button-success-bg);color:var(--base-button-success-text)}.base-button--success[data-v-a4a5350a]:hover:not(:disabled){background-color:var(--base-button-success-bg-hover)}.base-button--danger[data-v-a4a5350a]{background-color:var(--base-button-danger-bg);color:var(--base-button-danger-text)}.base-button--danger[data-v-a4a5350a]:hover:not(:disabled){background-color:var(--base-button-danger-bg-hover)}.base-button--warning[data-v-a4a5350a]{background-color:var(--base-button-warning-bg);color:var(--base-button-warning-text)}.base-button--warning[data-v-a4a5350a]:hover:not(:disabled){background-color:var(--base-button-warning-bg-hover)}.base-button--full-width[data-v-a4a5350a]{width:100%}.base-button--disabled[data-v-a4a5350a],.base-button[data-v-a4a5350a]:disabled{opacity:var(--base-button-disabled-opacity);cursor:not-allowed}.base-button--loading[data-v-a4a5350a]{cursor:wait}.base-button__spinner[data-v-a4a5350a]{width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin-a4a5350a .6s linear infinite}.base-button__content--loading[data-v-a4a5350a]{opacity:var(--base-button-loading-opacity)}@keyframes spin-a4a5350a{to{transform:rotate(360deg)}}:root{--base-input-label-color: #374151;--base-input-required-color: #ef4444;--base-input-border: #d1d5db;--base-input-border-focus: #3b82f6;--base-input-border-error: #ef4444;--base-input-bg-disabled: #f3f4f6;--base-input-placeholder-color: #9ca3af;--base-input-focus-shadow: 0 0 0 3px rgba(59, 130, 246, .1);--base-input-error-focus-shadow: 0 0 0 3px rgba(239, 68, 68, .1);--base-input-error-color: #ef4444;--base-input-disabled-opacity: .6}.base-input[data-v-52f8a6e5]{display:flex;flex-direction:column;gap:.375rem}.base-input__label[data-v-52f8a6e5]{font-size:.875rem;font-weight:500;color:var(--base-input-label-color)}.base-input__required[data-v-52f8a6e5]{color:var(--base-input-required-color)}.base-input__field[data-v-52f8a6e5]{padding:.5rem .75rem;font-size:1rem;border:1px solid var(--base-input-border);border-radius:.375rem;transition:all .2s ease-in-out;font-family:inherit}.base-input__field[data-v-52f8a6e5]:focus{outline:none;border-color:var(--base-input-border-focus);box-shadow:var(--base-input-focus-shadow)}.base-input__field[data-v-52f8a6e5]::placeholder{color:var(--base-input-placeholder-color)}.base-input__field--error[data-v-52f8a6e5]{border-color:var(--base-input-border-error)}.base-input__field--error[data-v-52f8a6e5]:focus{border-color:var(--base-input-border-error);box-shadow:var(--base-input-error-focus-shadow)}.base-input__field--disabled[data-v-52f8a6e5],.base-input__field[data-v-52f8a6e5]:disabled{background-color:var(--base-input-bg-disabled);cursor:not-allowed;opacity:var(--base-input-disabled-opacity)}.base-input__error[data-v-52f8a6e5]{font-size:.875rem;color:var(--base-input-error-color)}:root{--base-card-bg: white;--base-card-footer-bg: #f9fafb;--base-card-border: #e5e7eb;--base-card-title-color: #111827;--base-card-shadow: 0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06)}.base-card[data-v-80b8fdda]{background-color:var(--base-card-bg);border-radius:.5rem;border:1px solid var(--base-card-border);overflow:hidden}.base-card--elevated[data-v-80b8fdda]{box-shadow:var(--base-card-shadow);border:none}.base-card__header[data-v-80b8fdda]{padding:1rem 1.5rem;border-bottom:1px solid var(--base-card-border)}.base-card__title[data-v-80b8fdda]{margin:0;font-size:1.125rem;font-weight:600;color:var(--base-card-title-color)}.base-card__body[data-v-80b8fdda]{padding:1.5rem}.base-card--no-padding .base-card__body[data-v-80b8fdda]{padding:0}.base-card__footer[data-v-80b8fdda]{padding:1rem 1.5rem;border-top:1px solid var(--base-card-border);background-color:var(--base-card-footer-bg)}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { defineComponent as m, computed as p, createElementBlock as l, openBlock as o, normalizeClass as b, createCommentVNode as i, createElementVNode as f, renderSlot as c, unref as g, createTextVNode as C, toDisplayString as v, ref as $, onMounted as I, onUnmounted as V } from "vue";
|
|
2
|
+
function _(...e) {
|
|
3
|
+
return e.filter(Boolean).join(" ");
|
|
4
|
+
}
|
|
5
|
+
function A(e, s) {
|
|
6
|
+
let t;
|
|
7
|
+
return function(...a) {
|
|
8
|
+
clearTimeout(t), t = setTimeout(() => e.apply(this, a), s);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function q(e = "id") {
|
|
12
|
+
return `${e}-${Math.random().toString(36).substr(2, 9)}`;
|
|
13
|
+
}
|
|
14
|
+
const E = ["disabled", "type"], z = {
|
|
15
|
+
key: 0,
|
|
16
|
+
class: "base-button__spinner"
|
|
17
|
+
}, N = /* @__PURE__ */ m({
|
|
18
|
+
__name: "BaseButton",
|
|
19
|
+
props: {
|
|
20
|
+
variant: { default: "primary" },
|
|
21
|
+
size: { default: "medium" },
|
|
22
|
+
disabled: { type: Boolean, default: !1 },
|
|
23
|
+
fullWidth: { type: Boolean, default: !1 },
|
|
24
|
+
loading: { type: Boolean, default: !1 },
|
|
25
|
+
type: { default: "button" }
|
|
26
|
+
},
|
|
27
|
+
emits: ["click"],
|
|
28
|
+
setup(e, { emit: s }) {
|
|
29
|
+
const t = e, a = s, n = p(
|
|
30
|
+
() => _(
|
|
31
|
+
"base-button",
|
|
32
|
+
`base-button--${t.variant}`,
|
|
33
|
+
`base-button--${t.size}`,
|
|
34
|
+
t.fullWidth && "base-button--full-width",
|
|
35
|
+
t.loading && "base-button--loading",
|
|
36
|
+
t.disabled && "base-button--disabled"
|
|
37
|
+
)
|
|
38
|
+
), r = (d) => {
|
|
39
|
+
!t.disabled && !t.loading && a("click", d);
|
|
40
|
+
};
|
|
41
|
+
return (d, y) => (o(), l("button", {
|
|
42
|
+
class: b(n.value),
|
|
43
|
+
disabled: e.disabled || e.loading,
|
|
44
|
+
type: e.type,
|
|
45
|
+
onClick: r
|
|
46
|
+
}, [
|
|
47
|
+
e.loading ? (o(), l("span", z)) : i("", !0),
|
|
48
|
+
f("span", {
|
|
49
|
+
class: b({ "base-button__content--loading": e.loading })
|
|
50
|
+
}, [
|
|
51
|
+
c(d.$slots, "default", {}, void 0, !0)
|
|
52
|
+
], 2)
|
|
53
|
+
], 10, E));
|
|
54
|
+
}
|
|
55
|
+
}), h = (e, s) => {
|
|
56
|
+
const t = e.__vccOpts || e;
|
|
57
|
+
for (const [a, n] of s)
|
|
58
|
+
t[a] = n;
|
|
59
|
+
return t;
|
|
60
|
+
}, G = /* @__PURE__ */ h(N, [["__scopeId", "data-v-a4a5350a"]]), S = { class: "base-input" }, T = ["for"], F = {
|
|
61
|
+
key: 0,
|
|
62
|
+
class: "base-input__required"
|
|
63
|
+
}, L = ["id", "value", "type", "placeholder", "disabled", "required"], M = {
|
|
64
|
+
key: 1,
|
|
65
|
+
class: "base-input__error"
|
|
66
|
+
}, O = /* @__PURE__ */ m({
|
|
67
|
+
__name: "BaseInput",
|
|
68
|
+
props: {
|
|
69
|
+
modelValue: { default: "" },
|
|
70
|
+
type: { default: "text" },
|
|
71
|
+
placeholder: {},
|
|
72
|
+
disabled: { type: Boolean, default: !1 },
|
|
73
|
+
required: { type: Boolean, default: !1 },
|
|
74
|
+
label: {},
|
|
75
|
+
error: {}
|
|
76
|
+
},
|
|
77
|
+
emits: ["update:modelValue", "focus", "blur"],
|
|
78
|
+
setup(e, { emit: s }) {
|
|
79
|
+
const t = e, a = s, n = q("base-input"), r = p(
|
|
80
|
+
() => _(
|
|
81
|
+
"base-input__field",
|
|
82
|
+
t.error && "base-input__field--error",
|
|
83
|
+
t.disabled && "base-input__field--disabled"
|
|
84
|
+
)
|
|
85
|
+
), d = (u) => {
|
|
86
|
+
const B = u.target;
|
|
87
|
+
a("update:modelValue", B.value);
|
|
88
|
+
}, y = (u) => {
|
|
89
|
+
a("focus", u);
|
|
90
|
+
}, k = (u) => {
|
|
91
|
+
a("blur", u);
|
|
92
|
+
};
|
|
93
|
+
return (u, B) => (o(), l("div", S, [
|
|
94
|
+
e.label ? (o(), l("label", {
|
|
95
|
+
key: 0,
|
|
96
|
+
for: g(n),
|
|
97
|
+
class: "base-input__label"
|
|
98
|
+
}, [
|
|
99
|
+
C(v(e.label) + " ", 1),
|
|
100
|
+
e.required ? (o(), l("span", F, "*")) : i("", !0)
|
|
101
|
+
], 8, T)) : i("", !0),
|
|
102
|
+
f("input", {
|
|
103
|
+
id: g(n),
|
|
104
|
+
value: e.modelValue,
|
|
105
|
+
type: e.type,
|
|
106
|
+
placeholder: e.placeholder,
|
|
107
|
+
disabled: e.disabled,
|
|
108
|
+
required: e.required,
|
|
109
|
+
class: b(r.value),
|
|
110
|
+
onInput: d,
|
|
111
|
+
onFocus: y,
|
|
112
|
+
onBlur: k
|
|
113
|
+
}, null, 42, L),
|
|
114
|
+
e.error ? (o(), l("span", M, v(e.error), 1)) : i("", !0)
|
|
115
|
+
]));
|
|
116
|
+
}
|
|
117
|
+
}), H = /* @__PURE__ */ h(O, [["__scopeId", "data-v-52f8a6e5"]]), W = {
|
|
118
|
+
key: 0,
|
|
119
|
+
class: "base-card__header"
|
|
120
|
+
}, j = { class: "base-card__title" }, w = { class: "base-card__body" }, x = {
|
|
121
|
+
key: 1,
|
|
122
|
+
class: "base-card__footer"
|
|
123
|
+
}, D = /* @__PURE__ */ m({
|
|
124
|
+
__name: "BaseCard",
|
|
125
|
+
props: {
|
|
126
|
+
title: {},
|
|
127
|
+
elevated: { type: Boolean, default: !1 },
|
|
128
|
+
padding: { type: Boolean, default: !0 }
|
|
129
|
+
},
|
|
130
|
+
setup(e) {
|
|
131
|
+
const s = e, t = p(
|
|
132
|
+
() => _(s.elevated && "base-card--elevated", !s.padding && "base-card--no-padding")
|
|
133
|
+
);
|
|
134
|
+
return (a, n) => (o(), l("div", {
|
|
135
|
+
class: b(["base-card", t.value])
|
|
136
|
+
}, [
|
|
137
|
+
a.$slots.header || e.title ? (o(), l("div", W, [
|
|
138
|
+
c(a.$slots, "header", {}, () => [
|
|
139
|
+
f("h3", j, v(e.title), 1)
|
|
140
|
+
], !0)
|
|
141
|
+
])) : i("", !0),
|
|
142
|
+
f("div", w, [
|
|
143
|
+
c(a.$slots, "default", {}, void 0, !0)
|
|
144
|
+
]),
|
|
145
|
+
a.$slots.footer ? (o(), l("div", x, [
|
|
146
|
+
c(a.$slots, "footer", {}, void 0, !0)
|
|
147
|
+
])) : i("", !0)
|
|
148
|
+
], 2));
|
|
149
|
+
}
|
|
150
|
+
}), J = /* @__PURE__ */ h(D, [["__scopeId", "data-v-80b8fdda"]]);
|
|
151
|
+
function K(e, s) {
|
|
152
|
+
const t = $(e), a = $(null), n = p(() => a.value === null);
|
|
153
|
+
return {
|
|
154
|
+
value: t,
|
|
155
|
+
error: a,
|
|
156
|
+
isValid: n,
|
|
157
|
+
validate: () => (a.value = s(t.value), n.value),
|
|
158
|
+
reset: () => {
|
|
159
|
+
t.value = e, a.value = null;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function P(e, s) {
|
|
164
|
+
const t = (a) => {
|
|
165
|
+
e.value && !e.value.contains(a.target) && s();
|
|
166
|
+
};
|
|
167
|
+
I(() => {
|
|
168
|
+
document.addEventListener("click", t);
|
|
169
|
+
}), V(() => {
|
|
170
|
+
document.removeEventListener("click", t);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
export {
|
|
174
|
+
G as BaseButton,
|
|
175
|
+
J as BaseCard,
|
|
176
|
+
H as BaseInput,
|
|
177
|
+
_ as cn,
|
|
178
|
+
A as debounce,
|
|
179
|
+
q as generateId,
|
|
180
|
+
P as useClickOutside,
|
|
181
|
+
K as useValidation
|
|
182
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(o,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(o=typeof globalThis<"u"?globalThis:o||self,e(o.VueComponentLibrary={},o.Vue))})(this,(function(o,e){"use strict";function i(...t){return t.filter(Boolean).join(" ")}function p(t,l){let a;return function(...n){clearTimeout(a),a=setTimeout(()=>t.apply(this,n),l)}}function f(t="id"){return`${t}-${Math.random().toString(36).substr(2,9)}`}const B=["disabled","type"],_={key:0,class:"base-button__spinner"},h=e.defineComponent({__name:"BaseButton",props:{variant:{default:"primary"},size:{default:"medium"},disabled:{type:Boolean,default:!1},fullWidth:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},type:{default:"button"}},emits:["click"],setup(t,{emit:l}){const a=t,n=l,s=e.computed(()=>i("base-button",`base-button--${a.variant}`,`base-button--${a.size}`,a.fullWidth&&"base-button--full-width",a.loading&&"base-button--loading",a.disabled&&"base-button--disabled")),r=d=>{!a.disabled&&!a.loading&&n("click",d)};return(d,m)=>(e.openBlock(),e.createElementBlock("button",{class:e.normalizeClass(s.value),disabled:t.disabled||t.loading,type:t.type,onClick:r},[t.loading?(e.openBlock(),e.createElementBlock("span",_)):e.createCommentVNode("",!0),e.createElementVNode("span",{class:e.normalizeClass({"base-button__content--loading":t.loading})},[e.renderSlot(d.$slots,"default",{},void 0,!0)],2)],10,B))}}),u=(t,l)=>{const a=t.__vccOpts||t;for(const[n,s]of l)a[n]=s;return a},k=u(h,[["__scopeId","data-v-a4a5350a"]]),y={class:"base-input"},C=["for"],g={key:0,class:"base-input__required"},V=["id","value","type","placeholder","disabled","required"],$={key:1,class:"base-input__error"},E=u(e.defineComponent({__name:"BaseInput",props:{modelValue:{default:""},type:{default:"text"},placeholder:{},disabled:{type:Boolean,default:!1},required:{type:Boolean,default:!1},label:{},error:{}},emits:["update:modelValue","focus","blur"],setup(t,{emit:l}){const a=t,n=l,s=f("base-input"),r=e.computed(()=>i("base-input__field",a.error&&"base-input__field--error",a.disabled&&"base-input__field--disabled")),d=c=>{const b=c.target;n("update:modelValue",b.value)},m=c=>{n("focus",c)},j=c=>{n("blur",c)};return(c,b)=>(e.openBlock(),e.createElementBlock("div",y,[t.label?(e.openBlock(),e.createElementBlock("label",{key:0,for:e.unref(s),class:"base-input__label"},[e.createTextVNode(e.toDisplayString(t.label)+" ",1),t.required?(e.openBlock(),e.createElementBlock("span",g,"*")):e.createCommentVNode("",!0)],8,C)):e.createCommentVNode("",!0),e.createElementVNode("input",{id:e.unref(s),value:t.modelValue,type:t.type,placeholder:t.placeholder,disabled:t.disabled,required:t.required,class:e.normalizeClass(r.value),onInput:d,onFocus:m,onBlur:j},null,42,V),t.error?(e.openBlock(),e.createElementBlock("span",$,e.toDisplayString(t.error),1)):e.createCommentVNode("",!0)]))}}),[["__scopeId","data-v-52f8a6e5"]]),I={key:0,class:"base-card__header"},N={class:"base-card__title"},S={class:"base-card__body"},q={key:1,class:"base-card__footer"},z=u(e.defineComponent({__name:"BaseCard",props:{title:{},elevated:{type:Boolean,default:!1},padding:{type:Boolean,default:!0}},setup(t){const l=t,a=e.computed(()=>i(l.elevated&&"base-card--elevated",!l.padding&&"base-card--no-padding"));return(n,s)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["base-card",a.value])},[n.$slots.header||t.title?(e.openBlock(),e.createElementBlock("div",I,[e.renderSlot(n.$slots,"header",{},()=>[e.createElementVNode("h3",N,e.toDisplayString(t.title),1)],!0)])):e.createCommentVNode("",!0),e.createElementVNode("div",S,[e.renderSlot(n.$slots,"default",{},void 0,!0)]),n.$slots.footer?(e.openBlock(),e.createElementBlock("div",q,[e.renderSlot(n.$slots,"footer",{},void 0,!0)])):e.createCommentVNode("",!0)],2))}}),[["__scopeId","data-v-80b8fdda"]]);function T(t,l){const a=e.ref(t),n=e.ref(null),s=e.computed(()=>n.value===null);return{value:a,error:n,isValid:s,validate:()=>(n.value=l(a.value),s.value),reset:()=>{a.value=t,n.value=null}}}function O(t,l){const a=n=>{t.value&&!t.value.contains(n.target)&&l()};e.onMounted(()=>{document.addEventListener("click",a)}),e.onUnmounted(()=>{document.removeEventListener("click",a)})}o.BaseButton=k,o.BaseCard=z,o.BaseInput=E,o.cn=i,o.debounce=p,o.generateId=f,o.useClickOutside=O,o.useValidation=T,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@allsrvsonline/vue-component-library",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/vue-component-library.umd.js",
|
|
6
|
+
"module": "./dist/vue-component-library.es.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/vue-component-library.es.js",
|
|
12
|
+
"require": "./dist/vue-component-library.umd.js"
|
|
13
|
+
},
|
|
14
|
+
"./style.css": "./dist/style.css"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"dev": "vite",
|
|
21
|
+
"build": "vue-tsc -b && vite build",
|
|
22
|
+
"build:lib": "vue-tsc -b && vite build --mode lib",
|
|
23
|
+
"preview": "vite preview",
|
|
24
|
+
"lint": "eslint . --ext .vue,.ts,.tsx --fix",
|
|
25
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,vue,json}\"",
|
|
26
|
+
"test": "vitest",
|
|
27
|
+
"test:ui": "vitest --ui",
|
|
28
|
+
"type-check": "vue-tsc --noEmit"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"vue": "^3.5.24"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^24.10.1",
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "^8.51.0",
|
|
36
|
+
"@typescript-eslint/parser": "^8.51.0",
|
|
37
|
+
"@vitejs/plugin-vue": "^6.0.1",
|
|
38
|
+
"@vue/test-utils": "^2.4.6",
|
|
39
|
+
"@vue/tsconfig": "^0.8.1",
|
|
40
|
+
"eslint": "^8.57.1",
|
|
41
|
+
"eslint-config-prettier": "^10.1.8",
|
|
42
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
43
|
+
"eslint-plugin-vue": "^10.6.2",
|
|
44
|
+
"happy-dom": "^20.0.11",
|
|
45
|
+
"prettier": "^3.7.4",
|
|
46
|
+
"typescript": "~5.9.3",
|
|
47
|
+
"vite": "^7.2.4",
|
|
48
|
+
"vite-plugin-dts": "^4.5.4",
|
|
49
|
+
"vitest": "^4.0.16",
|
|
50
|
+
"vue-eslint-parser": "^10.2.0",
|
|
51
|
+
"vue-tsc": "^3.1.4"
|
|
52
|
+
}
|
|
53
|
+
}
|