pns-component-library 1.5.9 → 1.5.10
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 +634 -70
- package/dist/pns-component-library.es.js +45 -25
- package/dist/pns-component-library.umd.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,79 +1,643 @@
|
|
|
1
|
-
# PNS Component Library
|
|
1
|
+
# PNS Component Library
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A comprehensive Vue 3 component library built with modern development practices, providing reusable UI components, composables, and directives for building robust web applications.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- **9 Production-Ready Components** - Form controls, layout components, and utility components
|
|
8
|
+
- **2 Powerful Composables** - Reusable logic for common patterns
|
|
9
|
+
- **2 Custom Directives** - Loading states and UI enhancements
|
|
10
|
+
- **Vue 3 Composition API** - Modern, performant, and type-safe
|
|
11
|
+
- **Responsive Design** - Mobile-first approach with breakpoint handling
|
|
12
|
+
- **Accessibility** - ARIA attributes and keyboard navigation support
|
|
13
|
+
- **Customizable Themes** - Multiple built-in color schemes
|
|
14
|
+
|
|
15
|
+
## 📦 Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
9
18
|
npm install pns-component-library
|
|
10
19
|
```
|
|
11
|
-
|
|
12
|
-
|
|
20
|
+
or
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install pns-component-library@latest
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 🎯 Quick Start
|
|
27
|
+
|
|
28
|
+
### 1. Install and Setup
|
|
29
|
+
|
|
30
|
+
First, import and register the library in your `main.js`:
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
// main.js
|
|
34
|
+
import { createApp } from 'vue'
|
|
35
|
+
import App from './App.vue'
|
|
36
|
+
import PnsComponentLibrary from 'pns-component-library'
|
|
37
|
+
import 'pns-component-library/style.css'
|
|
38
|
+
|
|
39
|
+
const app = createApp(App)
|
|
40
|
+
app.use(PnsComponentLibrary)
|
|
41
|
+
app.mount('#app')
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Use Components
|
|
45
|
+
|
|
46
|
+
```vue
|
|
47
|
+
<template>
|
|
48
|
+
<div>
|
|
49
|
+
<!-- Basic checkbox -->
|
|
50
|
+
<Checkbox v-model="isChecked" label="Accept terms" />
|
|
51
|
+
|
|
52
|
+
<!-- Phone input with country selection -->
|
|
53
|
+
<AreaCodePhoneInput v-model="phoneData" />
|
|
54
|
+
|
|
55
|
+
<!-- Responsive button -->
|
|
56
|
+
<ResponsiveButton @click="handleClick">
|
|
57
|
+
Click me
|
|
58
|
+
</ResponsiveButton>
|
|
59
|
+
</div>
|
|
60
|
+
</template>
|
|
61
|
+
|
|
62
|
+
<script setup>
|
|
63
|
+
import { ref } from 'vue'
|
|
64
|
+
|
|
65
|
+
const isChecked = ref(false)
|
|
66
|
+
const phoneData = ref({ area_code: '', phone_number: '' })
|
|
67
|
+
|
|
68
|
+
const handleClick = () => {
|
|
69
|
+
console.log('Button clicked!')
|
|
70
|
+
}
|
|
71
|
+
</script>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 📚 Components
|
|
75
|
+
|
|
76
|
+
### Form Components
|
|
77
|
+
|
|
78
|
+
#### Checkbox
|
|
79
|
+
Customizable checkbox with multiple themes and validation support.
|
|
80
|
+
|
|
81
|
+
##### Attributes
|
|
82
|
+
|
|
83
|
+
| Attribute | Description | Type | Default |
|
|
84
|
+
|-----------|-------------|------|---------|
|
|
85
|
+
| model-value / v-model | binding value - `true` when checked, `false` when unchecked | `boolean` | `false` |
|
|
86
|
+
| label | checkbox label | `string` | — |
|
|
87
|
+
| size | checkbox size | `'small' \| 'medium'` | `'medium'` |
|
|
88
|
+
| built-in-theme | color theme | `'green' \| 'primary-blue' \| 'secondary-blue' \| 'red'` | `'green'` |
|
|
89
|
+
| disabled | whether checkbox is disabled | `boolean` | `false` |
|
|
90
|
+
| indeterminate | whether checkbox is indeterminate | `boolean` | `false` |
|
|
91
|
+
|
|
92
|
+
##### Events
|
|
93
|
+
|
|
94
|
+
| Event | Description | Parameters |
|
|
95
|
+
|-------|-------------|------------|
|
|
96
|
+
| change | triggers when the binding value changes | `(value: boolean)` |
|
|
97
|
+
|
|
98
|
+
##### Exposes
|
|
99
|
+
|
|
100
|
+
| Method | Description | Type |
|
|
101
|
+
|--------|-------------|------|
|
|
102
|
+
| focus | focus the checkbox | `() => void` |
|
|
103
|
+
| blur | blur the checkbox | `() => void` |
|
|
104
|
+
| alert | show error message | `(message: string) => void` |
|
|
105
|
+
| removeAlertOrErrorEffect | clear error state | `() => void` |
|
|
106
|
+
|
|
107
|
+
```vue
|
|
108
|
+
<template>
|
|
109
|
+
<Checkbox
|
|
110
|
+
v-model="agreed"
|
|
111
|
+
label="I agree to terms"
|
|
112
|
+
built_in_theme="primary-blue"
|
|
113
|
+
@change="handleChange"
|
|
114
|
+
/>
|
|
115
|
+
</template>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### GroupCheckbox
|
|
119
|
+
Container for managing multiple related checkboxes as a group.
|
|
120
|
+
|
|
121
|
+
##### Attributes
|
|
122
|
+
|
|
123
|
+
| Attribute | Description | Type | Default |
|
|
124
|
+
|-----------|-------------|------|---------|
|
|
125
|
+
| model-value / v-model | binding value - array of selected checkbox labels from child Checkbox components | `array` | `[]` |
|
|
126
|
+
|
|
127
|
+
##### Events
|
|
128
|
+
|
|
129
|
+
| Event | Description | Parameters |
|
|
130
|
+
|-------|-------------|------------|
|
|
131
|
+
| change | triggers when the binding value changes | `(value: array)` |
|
|
132
|
+
|
|
133
|
+
```vue
|
|
134
|
+
<template>
|
|
135
|
+
<GroupCheckbox v-model="selectedItems">
|
|
136
|
+
<Checkbox v-for="item in options" :key="item" :label="item" />
|
|
137
|
+
</GroupCheckbox>
|
|
138
|
+
</template>
|
|
139
|
+
|
|
140
|
+
<script setup>
|
|
141
|
+
const selectedItems = ref(['option1'])
|
|
142
|
+
const options = ['option1', 'option2', 'option3']
|
|
143
|
+
</script>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### AreaCodePhoneInput
|
|
147
|
+
International phone number input with country selection and area code handling.
|
|
148
|
+
|
|
149
|
+
##### Attributes
|
|
150
|
+
|
|
151
|
+
| Attribute | Description | Type | Default |
|
|
152
|
+
|-----------|-------------|------|---------|
|
|
153
|
+
| model-value / v-model | binding value - object containing `area_code` (country code like "+1") and `phone_number` (local number) | `{area_code: string, phone_number: string}` | `{area_code: '', phone_number: ''}` |
|
|
154
|
+
| country-options | custom country list | `array` | — |
|
|
155
|
+
| enable-backup-country-options | use built-in country list | `boolean` | `true` |
|
|
156
|
+
| country-filterable | enable country search | `boolean` | `false` |
|
|
157
|
+
| disabled | whether input is disabled | `boolean` | `false` |
|
|
158
|
+
|
|
159
|
+
##### Events
|
|
160
|
+
|
|
161
|
+
| Event | Description | Parameters |
|
|
162
|
+
|-------|-------------|------------|
|
|
163
|
+
| change | triggers when the binding value changes | `(value: object)` |
|
|
164
|
+
| focus | triggers when input is focused | `(event: FocusEvent)` |
|
|
165
|
+
| blur | triggers when input is blurred | `(event: FocusEvent)` |
|
|
166
|
+
| clear | triggers when clear button is clicked | — |
|
|
167
|
+
|
|
168
|
+
```vue
|
|
169
|
+
<template>
|
|
170
|
+
<AreaCodePhoneInput
|
|
171
|
+
v-model="phoneData"
|
|
172
|
+
:country_filterable="true"
|
|
173
|
+
@change="handlePhoneChange"
|
|
174
|
+
/>
|
|
175
|
+
</template>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
#### InputBox
|
|
179
|
+
Versatile input field component with validation and styling options.
|
|
180
|
+
|
|
181
|
+
##### Attributes
|
|
182
|
+
|
|
183
|
+
| Attribute | Description | Type | Default |
|
|
184
|
+
|-----------|-------------|------|---------|
|
|
185
|
+
| model-value / v-model | binding value - the current input text value | `string` | — |
|
|
186
|
+
| type | input type | `string` | `'text'` |
|
|
187
|
+
| placeholder | placeholder text | `string` | — |
|
|
188
|
+
| clearable | whether to show clear button | `boolean` | `false` |
|
|
189
|
+
| disabled | whether input is disabled | `boolean` | `false` |
|
|
190
|
+
|
|
191
|
+
##### Events
|
|
192
|
+
|
|
193
|
+
| Event | Description | Parameters |
|
|
194
|
+
|-------|-------------|------------|
|
|
195
|
+
| input | triggers when input value changes | `(value: string)` |
|
|
196
|
+
| change | triggers when input value changes and loses focus | `(value: string)` |
|
|
197
|
+
| focus | triggers when input is focused | `(event: FocusEvent)` |
|
|
198
|
+
| blur | triggers when input is blurred | `(event: FocusEvent)` |
|
|
199
|
+
| clear | triggers when clear button is clicked | — |
|
|
200
|
+
|
|
201
|
+
##### Exposes
|
|
202
|
+
|
|
203
|
+
| Method | Description | Type |
|
|
204
|
+
|--------|-------------|------|
|
|
205
|
+
| focus | focus the input | `() => void` |
|
|
206
|
+
| blur | blur the input | `() => void` |
|
|
207
|
+
| alert | show alert message | `(message: string) => void` |
|
|
208
|
+
| error | show error message | `(message: string) => void` |
|
|
209
|
+
| removeAlertOrErrorEffect | clear alert/error state | `() => void` |
|
|
210
|
+
|
|
211
|
+
##### Slots
|
|
212
|
+
|
|
213
|
+
| Name | Description |
|
|
214
|
+
|------|-------------|
|
|
215
|
+
| prefix | content before input |
|
|
216
|
+
| suffix | content after input |
|
|
217
|
+
|
|
13
218
|
```vue
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
219
|
+
<InputBox
|
|
220
|
+
v-model="value"
|
|
221
|
+
type="text"
|
|
222
|
+
placeholder="Enter text"
|
|
223
|
+
clearable
|
|
224
|
+
>
|
|
225
|
+
<template #prefix>
|
|
226
|
+
<Icon name="search" />
|
|
227
|
+
</template>
|
|
228
|
+
</InputBox>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### Radio
|
|
232
|
+
Radio button component for single selection from multiple options.
|
|
233
|
+
|
|
234
|
+
##### Attributes
|
|
235
|
+
|
|
236
|
+
| Attribute | Description | Type | Default |
|
|
237
|
+
|-----------|-------------|------|---------|
|
|
238
|
+
| model-value / v-model | binding value - the `value` of the currently selected radio button in the group | `string` | — |
|
|
239
|
+
| value | radio value | `string` | — |
|
|
240
|
+
| label | radio label | `string` | — |
|
|
241
|
+
| name | group name for radio group | `string` | — |
|
|
242
|
+
| size | radio size | `'small' \| 'medium'` | `'medium'` |
|
|
243
|
+
| built-in-theme | color theme | `'primary-blue' \| 'secondary-blue' \| 'red'` | `'primary-blue'` |
|
|
244
|
+
| customized-class | custom CSS class | `string` | — |
|
|
245
|
+
| disabled | whether radio is disabled | `boolean` | `false` |
|
|
246
|
+
| autofocus | whether to auto focus | `boolean` | `false` |
|
|
247
|
+
|
|
248
|
+
##### Events
|
|
249
|
+
|
|
250
|
+
| Event | Description | Parameters |
|
|
251
|
+
|-------|-------------|------------|
|
|
252
|
+
| change | triggers when the binding value changes | `(value: string)` |
|
|
253
|
+
|
|
254
|
+
##### Exposes
|
|
255
|
+
|
|
256
|
+
| Method | Description | Type |
|
|
257
|
+
|--------|-------------|------|
|
|
258
|
+
| focus | focus the radio | `() => void` |
|
|
259
|
+
| blur | blur the radio | `() => void` |
|
|
260
|
+
| alert | show alert message | `(message: string) => void` |
|
|
261
|
+
| removeAlertOrErrorEffect | clear alert/error state | `() => void` |
|
|
262
|
+
|
|
263
|
+
```vue
|
|
264
|
+
<!-- Radio Group -->
|
|
265
|
+
<Radio v-model="selected" value="option1" name="group1" label="Option 1" />
|
|
266
|
+
<Radio v-model="selected" value="option2" name="group1" label="Option 2" />
|
|
267
|
+
|
|
268
|
+
<!-- Single Radio -->
|
|
269
|
+
<Radio v-model="single" value="yes" label="Agree to terms" />
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### SingleSelector
|
|
273
|
+
Dropdown selector component with filtering and search capabilities.
|
|
274
|
+
|
|
275
|
+
##### Attributes
|
|
276
|
+
|
|
277
|
+
| Attribute | Description | Type | Default |
|
|
278
|
+
|-----------|-------------|------|---------|
|
|
279
|
+
| model-value / v-model | binding value - the `value` property of the selected option from the options array | `string \| number \| boolean \| object \| array` | — |
|
|
280
|
+
| options | options array | `Array<{value: any, label: string}>` | `[]` |
|
|
281
|
+
| filterable | whether to enable filtering | `boolean` | `false` |
|
|
282
|
+
| remote-search | whether to enable remote search | `boolean` | `false` |
|
|
283
|
+
| disabled | whether selector is disabled | `boolean` | `false` |
|
|
284
|
+
| placeholder | placeholder text | `string` | `'Select'` |
|
|
285
|
+
| clearable | whether to show clear button | `boolean` | `false` |
|
|
286
|
+
| loading | loading state | `boolean` | `false` |
|
|
287
|
+
| loading-text | loading text | `string` | `'Loading'` |
|
|
288
|
+
| no-data-text | no data text | `string` | `'No data'` |
|
|
289
|
+
|
|
290
|
+
##### Events
|
|
291
|
+
|
|
292
|
+
| Event | Description | Parameters |
|
|
293
|
+
|-------|-------------|------------|
|
|
294
|
+
| change | triggers when the binding value changes | `(value: any)` |
|
|
295
|
+
| remote-search | triggers when remote search is performed | `(query: string)` |
|
|
296
|
+
| filter-change | triggers when filter text changes | `(query: string)` |
|
|
297
|
+
| visible-change | triggers when dropdown visibility changes | `(visible: boolean)` |
|
|
298
|
+
| focus | triggers when selector is focused | `(event: FocusEvent)` |
|
|
299
|
+
| blur | triggers when selector is blurred | `(event: FocusEvent)` |
|
|
300
|
+
| clear | triggers when clear button is clicked | — |
|
|
301
|
+
|
|
302
|
+
##### Exposes
|
|
303
|
+
|
|
304
|
+
| Method | Description | Type |
|
|
305
|
+
|--------|-------------|------|
|
|
306
|
+
| focus | focus the selector | `() => void` |
|
|
307
|
+
| blur | blur the selector | `() => void` |
|
|
308
|
+
| alert | show alert message | `(message: string) => void` |
|
|
309
|
+
| error | show error message | `(message: string) => void` |
|
|
310
|
+
| removeAlertOrErrorEffect | clear alert/error state | `() => void` |
|
|
311
|
+
| setDropdownContentLoading | set loading state | `(loading: boolean) => void` |
|
|
312
|
+
|
|
313
|
+
##### Slots
|
|
314
|
+
|
|
315
|
+
| Name | Description |
|
|
316
|
+
|------|-------------|
|
|
317
|
+
| prefix | content before selector |
|
|
318
|
+
| suffix | content after selector |
|
|
319
|
+
|
|
320
|
+
```vue
|
|
321
|
+
<SingleSelector
|
|
322
|
+
v-model="selected"
|
|
323
|
+
:options="options"
|
|
324
|
+
filterable
|
|
325
|
+
clearable
|
|
326
|
+
placeholder="Choose option"
|
|
327
|
+
>
|
|
328
|
+
<template #prefix>
|
|
329
|
+
<Icon name="search" />
|
|
330
|
+
</template>
|
|
331
|
+
</SingleSelector>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Layout Components
|
|
335
|
+
|
|
336
|
+
#### ResponsiveButton
|
|
337
|
+
Feature-rich button component with responsive behavior and multiple states.
|
|
338
|
+
|
|
339
|
+
##### Attributes
|
|
340
|
+
|
|
341
|
+
| Attribute | Description | Type | Default |
|
|
342
|
+
|-----------|-------------|------|---------|
|
|
343
|
+
| display-name | button text | `string` | `'button'` |
|
|
344
|
+
| size | button size | `'xsmall' \| 'small' \| 'medium' \| 'large'` | `'small'` |
|
|
345
|
+
| width-type | button width type | `'fill-whole' \| 'fit-content'` | `'fit-content'` |
|
|
346
|
+
| build-in-theme | color theme | `'outlined-primary' \| 'filled-primary' \| 'text-primary' \| 'outlined-secondary' \| 'filled-secondary' \| 'text-secondary'` | `'outlined-primary'` |
|
|
347
|
+
| customized-class | custom CSS class | `string` | — |
|
|
348
|
+
| hold | whether button is in hold state | `boolean` | `false` |
|
|
349
|
+
| disabled | whether button is disabled | `boolean` | `false` |
|
|
350
|
+
| dropdown-options | dropdown menu options | `array` | `[]` |
|
|
351
|
+
| is-dropdown-option | whether this is a dropdown item | `boolean` | `false` |
|
|
352
|
+
|
|
353
|
+
##### Events
|
|
354
|
+
|
|
355
|
+
| Event | Description | Parameters |
|
|
356
|
+
|-------|-------------|------------|
|
|
357
|
+
| click | triggers when button is clicked | `(event: MouseEvent)` |
|
|
358
|
+
| update-currently-hovered-dropdown-option | triggers when dropdown option is hovered | `(option: object)` |
|
|
359
|
+
| add-nested-dropdown-history-stack | triggers when nested dropdown is navigated | `(option: object)` |
|
|
360
|
+
| remove-nested-dropdown-history-stack | triggers when navigating back in nested dropdown | — |
|
|
361
|
+
|
|
362
|
+
##### Slots
|
|
363
|
+
|
|
364
|
+
| Name | Description |
|
|
365
|
+
|------|-------------|
|
|
366
|
+
| prefix | content before button text |
|
|
367
|
+
| suffix | content after button text |
|
|
368
|
+
|
|
44
369
|
```vue
|
|
45
|
-
|
|
46
|
-
|
|
370
|
+
<ResponsiveButton
|
|
371
|
+
display_name="Save Changes"
|
|
372
|
+
size="medium"
|
|
373
|
+
build_in_theme="filled-primary"
|
|
374
|
+
@click="handleSave"
|
|
375
|
+
>
|
|
376
|
+
<template #prefix>
|
|
377
|
+
<Icon name="save" />
|
|
47
378
|
</template>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
379
|
+
</ResponsiveButton>
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Utility Components
|
|
383
|
+
|
|
384
|
+
#### SimplifiedNotification
|
|
385
|
+
Toast notification component for user feedback.
|
|
386
|
+
|
|
387
|
+
##### Attributes
|
|
388
|
+
|
|
389
|
+
| Attribute | Description | Type | Default |
|
|
390
|
+
|-----------|-------------|------|---------|
|
|
391
|
+
| content | notification content | `string` | — |
|
|
392
|
+
| build-in-theme | color theme | `'blue' \| 'red' \| 'yellow' \| 'green'` | `'blue'` |
|
|
393
|
+
| title | notification title | `string` | — |
|
|
394
|
+
| customized-alert-icon-src | custom icon URL | `string` | — |
|
|
395
|
+
| customized-class | custom CSS class | `string` | — |
|
|
396
|
+
| with-close-btn | whether to show close button | `boolean` | `true` |
|
|
397
|
+
| mounted-programmatically | whether mounted programmatically | `boolean` | `false` |
|
|
398
|
+
| hide-after | auto-hide after milliseconds (0 = never) | `number` | `0` |
|
|
399
|
+
|
|
400
|
+
##### Events
|
|
401
|
+
|
|
402
|
+
| Event | Description | Parameters |
|
|
403
|
+
|-------|-------------|------------|
|
|
404
|
+
| close | triggers when notification is closed | — |
|
|
405
|
+
|
|
406
|
+
##### Slots
|
|
407
|
+
|
|
408
|
+
| Name | Description |
|
|
409
|
+
|------|-------------|
|
|
410
|
+
| content | custom notification content |
|
|
411
|
+
|
|
412
|
+
```vue
|
|
413
|
+
<SimplifiedNotification
|
|
414
|
+
title="Success!"
|
|
415
|
+
content="Operation completed successfully"
|
|
416
|
+
build_in_theme="green"
|
|
417
|
+
:hide_after="3000"
|
|
418
|
+
@close="handleClose"
|
|
419
|
+
/>
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
#### WholePageErrorPopup
|
|
423
|
+
Full-page error overlay for critical error states.
|
|
424
|
+
|
|
425
|
+
##### Attributes
|
|
426
|
+
|
|
427
|
+
| Attribute | Description | Type | Default |
|
|
428
|
+
|-----------|-------------|------|---------|
|
|
429
|
+
| title | error title | `string` | `'Error'` |
|
|
430
|
+
| content | error message | `string` | `'An error has occured'` |
|
|
431
|
+
|
|
432
|
+
##### Events
|
|
433
|
+
|
|
434
|
+
| Event | Description | Parameters |
|
|
435
|
+
|-------|-------------|------------|
|
|
436
|
+
| retry | triggers when retry button is clicked | — |
|
|
437
|
+
|
|
438
|
+
##### Slots
|
|
439
|
+
|
|
440
|
+
| Name | Description |
|
|
441
|
+
|------|-------------|
|
|
442
|
+
| content | custom error content |
|
|
443
|
+
|
|
444
|
+
```vue
|
|
445
|
+
<WholePageErrorPopup
|
|
446
|
+
title="Connection Error"
|
|
447
|
+
content="Unable to connect to server. Please check your internet connection."
|
|
448
|
+
@retry="handleRetry"
|
|
449
|
+
/>
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## 🔧 Composables
|
|
453
|
+
|
|
454
|
+
### FloatingNotification
|
|
455
|
+
Programmatically create floating notifications.
|
|
456
|
+
|
|
457
|
+
##### Parameters
|
|
458
|
+
|
|
459
|
+
| Parameter | Description | Type | Default |
|
|
460
|
+
|-----------|-------------|------|---------|
|
|
461
|
+
| type | notification type | `'success' \| 'error' \| 'warning' \| 'info'` | `'info'` |
|
|
462
|
+
| message | notification message | `string` | — |
|
|
463
|
+
| duration | auto-hide duration in milliseconds | `number` | `3000` |
|
|
464
|
+
| title | notification title | `string` | — |
|
|
465
|
+
|
|
466
|
+
##### Returns
|
|
467
|
+
|
|
468
|
+
| Type | Description |
|
|
469
|
+
|------|-------------|
|
|
470
|
+
| `void` | Creates and displays the notification |
|
|
471
|
+
|
|
472
|
+
```javascript
|
|
473
|
+
import { FloatingNotification } from 'pns-component-library/composables'
|
|
474
|
+
|
|
475
|
+
// Show notification
|
|
476
|
+
FloatingNotification({
|
|
477
|
+
type: 'success',
|
|
478
|
+
message: 'Operation completed!',
|
|
479
|
+
duration: 3000
|
|
480
|
+
})
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### useWindowSize
|
|
484
|
+
Reactive window size tracking composable.
|
|
485
|
+
|
|
486
|
+
##### Returns
|
|
487
|
+
|
|
488
|
+
| Property | Description | Type |
|
|
489
|
+
|----------|-------------|------|
|
|
490
|
+
| width | current window width | `Ref<number>` |
|
|
491
|
+
| height | current window height | `Ref<number>` |
|
|
492
|
+
|
|
493
|
+
```javascript
|
|
494
|
+
import { useWindowSize } from 'pns-component-library/composables'
|
|
495
|
+
|
|
496
|
+
const { width, height } = useWindowSize()
|
|
497
|
+
|
|
498
|
+
// Use in template or computed
|
|
499
|
+
watchEffect(() => {
|
|
500
|
+
console.log(`Window size: ${width.value}x${height.value}`)
|
|
501
|
+
})
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
## 🎨 Directives
|
|
505
|
+
|
|
506
|
+
### v-component-loading
|
|
507
|
+
Add loading state to any component with overlay spinner.
|
|
508
|
+
|
|
509
|
+
##### Usage
|
|
510
|
+
|
|
511
|
+
| Binding | Description | Type |
|
|
512
|
+
|---------|-------------|------|
|
|
513
|
+
| value | whether to show loading state | `boolean` |
|
|
514
|
+
|
|
515
|
+
```vue
|
|
516
|
+
<template>
|
|
517
|
+
<div v-component-loading="isLoading">
|
|
518
|
+
Content here
|
|
519
|
+
</div>
|
|
520
|
+
</template>
|
|
521
|
+
|
|
522
|
+
<script setup>
|
|
523
|
+
import { ref } from 'vue'
|
|
524
|
+
const isLoading = ref(false)
|
|
525
|
+
|
|
526
|
+
// Toggle loading
|
|
527
|
+
const startLoading = () => {
|
|
528
|
+
isLoading.value = true
|
|
529
|
+
setTimeout(() => {
|
|
530
|
+
isLoading.value = false
|
|
531
|
+
}, 2000)
|
|
532
|
+
}
|
|
533
|
+
</script>
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### v-whole-page-loading
|
|
537
|
+
Full-page loading overlay that covers the entire viewport.
|
|
538
|
+
|
|
539
|
+
##### Usage
|
|
540
|
+
|
|
541
|
+
| Binding | Description | Type |
|
|
542
|
+
|---------|-------------|------|
|
|
543
|
+
| value | whether to show full-page loading | `boolean` |
|
|
544
|
+
|
|
545
|
+
```vue
|
|
546
|
+
<template>
|
|
547
|
+
<div v-whole-page-loading="isPageLoading">
|
|
548
|
+
App content
|
|
549
|
+
</div>
|
|
550
|
+
</template>
|
|
551
|
+
|
|
552
|
+
<script setup>
|
|
553
|
+
import { ref } from 'vue'
|
|
554
|
+
const isPageLoading = ref(false)
|
|
555
|
+
|
|
556
|
+
// Show page loading
|
|
557
|
+
const loadPage = async () => {
|
|
558
|
+
isPageLoading.value = true
|
|
559
|
+
try {
|
|
560
|
+
await fetchData()
|
|
561
|
+
} finally {
|
|
562
|
+
isPageLoading.value = false
|
|
56
563
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
564
|
+
}
|
|
565
|
+
</script>
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
## 🎨 Theming
|
|
569
|
+
|
|
570
|
+
The library provides multiple built-in themes:
|
|
571
|
+
|
|
572
|
+
- **Green** (default) - Primary green theme
|
|
573
|
+
- **Primary Blue** - Professional blue theme
|
|
574
|
+
- **Secondary Blue** - Light blue accent theme
|
|
575
|
+
- **Red** - Error/warning red theme
|
|
576
|
+
|
|
577
|
+
```vue
|
|
578
|
+
<Checkbox built_in_theme="primary-blue" />
|
|
579
|
+
<ResponsiveButton variant="secondary-blue" />
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
## 📱 Responsive Design
|
|
583
|
+
|
|
584
|
+
Components automatically adapt to different screen sizes:
|
|
585
|
+
|
|
586
|
+
- **Desktop**: Full feature set with optimal spacing
|
|
587
|
+
- **Mobile**: Compact layouts with touch-friendly interactions
|
|
588
|
+
- **Breakpoint**: 767px for mobile/desktop switching
|
|
589
|
+
|
|
590
|
+
## ♿ Accessibility
|
|
591
|
+
|
|
592
|
+
All components include:
|
|
593
|
+
|
|
594
|
+
- ARIA attributes for screen readers
|
|
595
|
+
- Keyboard navigation support
|
|
596
|
+
- Focus management
|
|
597
|
+
- High contrast support
|
|
598
|
+
- Semantic HTML structure
|
|
599
|
+
|
|
600
|
+
## 🛠 Development
|
|
601
|
+
|
|
602
|
+
### Project Setup
|
|
603
|
+
|
|
604
|
+
```bash
|
|
605
|
+
npm install
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### Development Server
|
|
609
|
+
|
|
610
|
+
```bash
|
|
611
|
+
npm run dev
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Build for Production
|
|
615
|
+
|
|
616
|
+
```bash
|
|
617
|
+
npm run build
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Component Documentation
|
|
621
|
+
|
|
622
|
+
Visit the demo pages to see all components in action with interactive examples.
|
|
623
|
+
|
|
624
|
+
## 📄 License
|
|
625
|
+
|
|
626
|
+
MIT License - see LICENSE file for details.
|
|
627
|
+
|
|
628
|
+
## 🤝 Contributing
|
|
629
|
+
|
|
630
|
+
1. Fork the repository
|
|
631
|
+
2. Create a feature branch
|
|
632
|
+
3. Make your changes
|
|
633
|
+
4. Add tests and documentation
|
|
634
|
+
5. Submit a pull request
|
|
635
|
+
|
|
636
|
+
## 📞 Support
|
|
637
|
+
|
|
638
|
+
For questions and support, please open an issue on the GitHub repository.
|
|
639
|
+
|
|
640
|
+
---
|
|
641
|
+
|
|
642
|
+
Built with ❤️ using Vue 3 and modern web technologies.
|
|
79
643
|
|