nicklabs-ui 1.0.71 → 1.0.74
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 +219 -1
- package/dist/index.mjs +1735 -859
- package/dist/nicklabs-ui.css +1 -1
- package/dist/src/components/NAudioSelect.vue.d.ts +27 -0
- package/dist/src/components/NImageSelect.vue.d.ts +27 -0
- package/dist/src/components/NVideoSelect.vue.d.ts +27 -0
- package/dist/src/index.d.ts +10 -1
- package/dist/src/types/components/audioselect.d.ts +13 -0
- package/dist/src/types/components/imageselect.d.ts +14 -0
- package/dist/src/types/components/videoselect.d.ts +15 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A Vue 3 component library with glassmorphism design, built for modern web applications.
|
|
4
4
|
|
|
5
|
-
**Version**: 1.0.
|
|
5
|
+
**Version**: 1.0.73 | **Framework**: Vue 3.5+
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -18,6 +18,9 @@ A Vue 3 component library with glassmorphism design, built for modern web applic
|
|
|
18
18
|
- [NCheckbox](#ncheckbox)
|
|
19
19
|
- [NSelect](#nselect)
|
|
20
20
|
- [NFileSelect](#nfileselect)
|
|
21
|
+
- [NImageSelect](#nimageselect)
|
|
22
|
+
- [NVideoSelect](#nvideoselect)
|
|
23
|
+
- [NAudioSelect](#naudioselect)
|
|
21
24
|
- [NSwitch](#nswitch)
|
|
22
25
|
- [NDatePicker](#ndatepicker)
|
|
23
26
|
- [Data Display](#data-display)
|
|
@@ -539,6 +542,183 @@ function handleFiles(files: File[]) {
|
|
|
539
542
|
|
|
540
543
|
---
|
|
541
544
|
|
|
545
|
+
#### NImageSelect
|
|
546
|
+
|
|
547
|
+
A card-grid image uploader with drag-and-drop, multi-file support, automatic resolution probing, a built-in dark preview lightbox, and a confirm dialog before removal. Files are tracked as `NImageSelectItem[]` via `v-model`.
|
|
548
|
+
|
|
549
|
+
> Removal uses `useAlert` internally, so mount `<NAlert />` once at the app root (see [NAlert](#nalert)).
|
|
550
|
+
|
|
551
|
+
**Props**
|
|
552
|
+
|
|
553
|
+
| Prop | Type | Default | Description |
|
|
554
|
+
|------|------|---------|-------------|
|
|
555
|
+
| `modelValue` | `NImageSelectItem[]` | `[]` | Bound image list (v-model) |
|
|
556
|
+
| `accept` | `string` | `"image/*"` | Accepted types — used for both the file dialog and drop validation. Supports `image/*`, exact MIME (`image/png`), extensions (`.png`), and comma-separated combinations |
|
|
557
|
+
| `multiple` | `boolean` | `false` | Allow multiple images; when `false`, extra files are rejected with a `count` error |
|
|
558
|
+
| `maxSize` | `number` | `0` | Per-file size limit in **MB** (`0` = unlimited) |
|
|
559
|
+
| `disabled` | `boolean` | `false` | Disable adding and removing |
|
|
560
|
+
| `title` | `string` | `""` | Label above the grid |
|
|
561
|
+
| `showCount` | `boolean` | `false` | Show a count chip next to the title |
|
|
562
|
+
| `emptyTitle` | `string` | `"將圖片拖放到這裡"` | Empty-state heading |
|
|
563
|
+
| `emptyHint` | `string` | `"或點擊以選擇檔案 · 支援 JPG / PNG / WebP / GIF,可一次多張"` | Empty-state sub-text |
|
|
564
|
+
|
|
565
|
+
**Events**
|
|
566
|
+
|
|
567
|
+
| Event | Payload | Description |
|
|
568
|
+
|-------|---------|-------------|
|
|
569
|
+
| `update:modelValue` | `NImageSelectItem[]` | The full list changed (v-model) |
|
|
570
|
+
| `change` | `NImageSelectItem[]` | The full list changed |
|
|
571
|
+
| `add` | `NImageSelectItem[]` | Items just added (this batch only) |
|
|
572
|
+
| `remove` | `NImageSelectItem` | An item was removed (after confirm) |
|
|
573
|
+
| `error` | `NImageSelectError` | A file was rejected (`type` / `size` / `count`) |
|
|
574
|
+
|
|
575
|
+
**Usage**
|
|
576
|
+
|
|
577
|
+
```vue
|
|
578
|
+
<template>
|
|
579
|
+
<NImageSelect
|
|
580
|
+
v-model="images"
|
|
581
|
+
title="Product Photos"
|
|
582
|
+
multiple
|
|
583
|
+
:max-size="5"
|
|
584
|
+
show-count
|
|
585
|
+
@add="onAdd"
|
|
586
|
+
@error="onError"
|
|
587
|
+
/>
|
|
588
|
+
</template>
|
|
589
|
+
|
|
590
|
+
<script setup lang="ts">
|
|
591
|
+
import { ref } from 'vue'
|
|
592
|
+
import { NImageSelect } from 'nicklabs-ui'
|
|
593
|
+
import type { NImageSelectItem, NImageSelectError } from 'nicklabs-ui'
|
|
594
|
+
|
|
595
|
+
const images = ref<NImageSelectItem[]>([])
|
|
596
|
+
|
|
597
|
+
function onAdd(items: NImageSelectItem[]) {
|
|
598
|
+
console.log('Added', items.length, 'images')
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
function onError(err: NImageSelectError) {
|
|
602
|
+
console.warn('Rejected:', err.file.name, err.type)
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// Each item carries the native File for upload:
|
|
606
|
+
async function upload() {
|
|
607
|
+
const form = new FormData()
|
|
608
|
+
images.value.forEach((img) => img.file && form.append('files', img.file))
|
|
609
|
+
await api.upload(form)
|
|
610
|
+
}
|
|
611
|
+
</script>
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
> `width` / `height` are probed asynchronously after a file is added and written back into the item. The component creates object URLs for previews and revokes them on removal and unmount automatically.
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
618
|
+
#### NVideoSelect
|
|
619
|
+
|
|
620
|
+
A card-grid video uploader. Same interaction model as [NImageSelect](#nimageselect) — drag-and-drop, multi-file, confirm-before-remove, and a built-in preview modal — but items also carry `duration`, `width`, and `height`.
|
|
621
|
+
|
|
622
|
+
> Removal uses `useAlert` internally, so mount `<NAlert />` once at the app root (see [NAlert](#nalert)).
|
|
623
|
+
|
|
624
|
+
**Props**
|
|
625
|
+
|
|
626
|
+
| Prop | Type | Default | Description |
|
|
627
|
+
|------|------|---------|-------------|
|
|
628
|
+
| `modelValue` | `NVideoSelectItem[]` | `[]` | Bound video list (v-model) |
|
|
629
|
+
| `accept` | `string` | `"video/*"` | Accepted types — supports `video/*`, exact MIME (`video/mp4`), extensions (`.mp4`), and comma-separated combinations |
|
|
630
|
+
| `multiple` | `boolean` | `false` | Allow multiple videos |
|
|
631
|
+
| `maxSize` | `number` | `0` | Per-file size limit in **MB** (`0` = unlimited) |
|
|
632
|
+
| `disabled` | `boolean` | `false` | Disable adding and removing |
|
|
633
|
+
| `title` | `string` | `""` | Label above the grid |
|
|
634
|
+
| `showCount` | `boolean` | `false` | Show a count chip next to the title |
|
|
635
|
+
| `emptyTitle` | `string` | `"將影片拖放到這裡"` | Empty-state heading |
|
|
636
|
+
| `emptyHint` | `string` | `"或點擊以選擇檔案 · 支援 MP4 / MOV / WebM,可一次多支"` | Empty-state sub-text |
|
|
637
|
+
|
|
638
|
+
**Events**
|
|
639
|
+
|
|
640
|
+
| Event | Payload | Description |
|
|
641
|
+
|-------|---------|-------------|
|
|
642
|
+
| `update:modelValue` | `NVideoSelectItem[]` | The full list changed (v-model) |
|
|
643
|
+
| `change` | `NVideoSelectItem[]` | The full list changed |
|
|
644
|
+
| `add` | `NVideoSelectItem[]` | Items just added (this batch only) |
|
|
645
|
+
| `remove` | `NVideoSelectItem` | An item was removed (after confirm) |
|
|
646
|
+
| `error` | `NVideoSelectError` | A file was rejected (`type` / `size` / `count`) |
|
|
647
|
+
|
|
648
|
+
**Usage**
|
|
649
|
+
|
|
650
|
+
```vue
|
|
651
|
+
<template>
|
|
652
|
+
<NVideoSelect v-model="videos" title="Clips" multiple :max-size="200" @error="onError" />
|
|
653
|
+
</template>
|
|
654
|
+
|
|
655
|
+
<script setup lang="ts">
|
|
656
|
+
import { ref } from 'vue'
|
|
657
|
+
import { NVideoSelect } from 'nicklabs-ui'
|
|
658
|
+
import type { NVideoSelectItem, NVideoSelectError } from 'nicklabs-ui'
|
|
659
|
+
|
|
660
|
+
const videos = ref<NVideoSelectItem[]>([])
|
|
661
|
+
|
|
662
|
+
function onError(err: NVideoSelectError) {
|
|
663
|
+
console.warn('Rejected:', err.file.name, err.type)
|
|
664
|
+
}
|
|
665
|
+
</script>
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
---
|
|
669
|
+
|
|
670
|
+
#### NAudioSelect
|
|
671
|
+
|
|
672
|
+
An audio uploader that decodes each file with the Web Audio API to render a waveform, showing a skeleton row while decoding. Same drag-and-drop / multi-file / confirm-before-remove model as the other media selectors; items carry `duration`.
|
|
673
|
+
|
|
674
|
+
> Removal uses `useAlert` internally, so mount `<NAlert />` once at the app root (see [NAlert](#nalert)).
|
|
675
|
+
|
|
676
|
+
**Props**
|
|
677
|
+
|
|
678
|
+
| Prop | Type | Default | Description |
|
|
679
|
+
|------|------|---------|-------------|
|
|
680
|
+
| `modelValue` | `NAudioSelectItem[]` | `[]` | Bound audio list (v-model) |
|
|
681
|
+
| `accept` | `string` | `".mp3,.wav,.ogg,.m4a,.aac,.flac,audio/mpeg,audio/wav,audio/ogg,audio/aac,audio/flac"` | Accepted types. Defaults to an explicit extension + MIME list (rather than `audio/*`) so the dialog doesn't offer `.mp4`-style containers |
|
|
682
|
+
| `multiple` | `boolean` | `false` | Allow multiple files |
|
|
683
|
+
| `maxSize` | `number` | `0` | Per-file size limit in **MB** (`0` = unlimited) |
|
|
684
|
+
| `disabled` | `boolean` | `false` | Disable adding and removing |
|
|
685
|
+
| `title` | `string` | `""` | Label above the list |
|
|
686
|
+
| `showCount` | `boolean` | `false` | Show a count chip next to the title |
|
|
687
|
+
| `emptyTitle` | `string` | `"將音訊拖放到這裡"` | Empty-state heading |
|
|
688
|
+
| `emptyHint` | `string` | `"或點擊以選擇檔案 · 支援 MP3 / WAV / OGG / M4A,可一次多首"` | Empty-state sub-text |
|
|
689
|
+
|
|
690
|
+
**Events**
|
|
691
|
+
|
|
692
|
+
| Event | Payload | Description |
|
|
693
|
+
|-------|---------|-------------|
|
|
694
|
+
| `update:modelValue` | `NAudioSelectItem[]` | The full list changed (v-model) |
|
|
695
|
+
| `change` | `NAudioSelectItem[]` | The full list changed |
|
|
696
|
+
| `add` | `NAudioSelectItem[]` | Items just added (this batch only) |
|
|
697
|
+
| `remove` | `NAudioSelectItem` | An item was removed (after confirm) |
|
|
698
|
+
| `error` | `NAudioSelectError` | A file was rejected (`type` / `size` / `count`) |
|
|
699
|
+
|
|
700
|
+
**Usage**
|
|
701
|
+
|
|
702
|
+
```vue
|
|
703
|
+
<template>
|
|
704
|
+
<NAudioSelect v-model="tracks" title="Soundtrack" multiple @error="onError" />
|
|
705
|
+
</template>
|
|
706
|
+
|
|
707
|
+
<script setup lang="ts">
|
|
708
|
+
import { ref } from 'vue'
|
|
709
|
+
import { NAudioSelect } from 'nicklabs-ui'
|
|
710
|
+
import type { NAudioSelectItem, NAudioSelectError } from 'nicklabs-ui'
|
|
711
|
+
|
|
712
|
+
const tracks = ref<NAudioSelectItem[]>([])
|
|
713
|
+
|
|
714
|
+
function onError(err: NAudioSelectError) {
|
|
715
|
+
console.warn('Rejected:', err.file.name, err.type)
|
|
716
|
+
}
|
|
717
|
+
</script>
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
---
|
|
721
|
+
|
|
542
722
|
#### NSwitch
|
|
543
723
|
|
|
544
724
|
Animated toggle switch.
|
|
@@ -1992,8 +2172,46 @@ type NTagIntent = 'none' | 'primary' | 'success' | 'warning' | 'error' | 'info'
|
|
|
1992
2172
|
type NTagVariant = 'solid' | 'light' | 'outline'
|
|
1993
2173
|
type PaddingSize = 'none' | 'sm' | 'md' | 'lg'
|
|
1994
2174
|
type RadiusSize = 'none' | 'sm' | 'md' | 'lg' | 'xl'
|
|
2175
|
+
|
|
2176
|
+
// Media selectors (NImageSelect / NVideoSelect / NAudioSelect)
|
|
2177
|
+
type MediaSelectErrorType = 'size' | 'type' | 'count'
|
|
2178
|
+
|
|
2179
|
+
interface NImageSelectItem {
|
|
2180
|
+
id: string
|
|
2181
|
+
file: File | null // native File for upload; null for seed/preset items
|
|
2182
|
+
name: string
|
|
2183
|
+
size: number // bytes
|
|
2184
|
+
width: number | null
|
|
2185
|
+
height: number | null
|
|
2186
|
+
url: string // object URL for preview
|
|
2187
|
+
}
|
|
2188
|
+
interface NImageSelectError { type: MediaSelectErrorType; file: File }
|
|
2189
|
+
|
|
2190
|
+
interface NVideoSelectItem {
|
|
2191
|
+
id: string
|
|
2192
|
+
file: File | null
|
|
2193
|
+
name: string
|
|
2194
|
+
size: number // bytes
|
|
2195
|
+
duration: number | null // seconds
|
|
2196
|
+
width: number | null
|
|
2197
|
+
height: number | null
|
|
2198
|
+
url: string
|
|
2199
|
+
}
|
|
2200
|
+
interface NVideoSelectError { type: MediaSelectErrorType; file: File }
|
|
2201
|
+
|
|
2202
|
+
interface NAudioSelectItem {
|
|
2203
|
+
id: string
|
|
2204
|
+
file: File | null
|
|
2205
|
+
name: string
|
|
2206
|
+
size: number // bytes
|
|
2207
|
+
duration: number | null // seconds
|
|
2208
|
+
url: string
|
|
2209
|
+
}
|
|
2210
|
+
interface NAudioSelectError { type: MediaSelectErrorType; file: File }
|
|
1995
2211
|
```
|
|
1996
2212
|
|
|
2213
|
+
> `NImageSelectErrorType`, `NVideoSelectErrorType`, and `NAudioSelectErrorType` are each exported individually (all aliased to `'size' | 'type' | 'count'`).
|
|
2214
|
+
|
|
1997
2215
|
---
|
|
1998
2216
|
|
|
1999
2217
|
## CSS Variables
|