@smurfox/proxy-ui 0.1.35 → 0.2.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/README.md +253 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +3 -2
- package/dist/runtime/components/Avatar.d.vue.ts +1 -1
- package/dist/runtime/components/Avatar.vue +18 -13
- package/dist/runtime/components/Avatar.vue.d.ts +1 -1
- package/dist/runtime/components/Button.d.vue.ts +1 -1
- package/dist/runtime/components/Button.vue +30 -12
- package/dist/runtime/components/Button.vue.d.ts +1 -1
- package/dist/runtime/components/Card.d.vue.ts +1 -1
- package/dist/runtime/components/Card.vue.d.ts +1 -1
- package/dist/runtime/components/Chip.d.vue.ts +1 -1
- package/dist/runtime/components/Chip.vue +25 -13
- package/dist/runtime/components/Chip.vue.d.ts +1 -1
- package/dist/runtime/components/Dropdown.d.vue.ts +12 -0
- package/dist/runtime/components/Dropdown.vue +51 -0
- package/dist/runtime/components/Dropdown.vue.d.ts +12 -0
- package/dist/runtime/components/Input.d.vue.ts +2 -2
- package/dist/runtime/components/Input.vue +25 -13
- package/dist/runtime/components/Input.vue.d.ts +2 -2
- package/dist/runtime/components/Select.d.vue.ts +2 -2
- package/dist/runtime/components/Select.vue +104 -86
- package/dist/runtime/components/Select.vue.d.ts +2 -2
- package/dist/runtime/components/Table.d.vue.ts +98 -0
- package/dist/runtime/components/Table.vue +196 -0
- package/dist/runtime/components/Table.vue.d.ts +98 -0
- package/dist/runtime/components/Tabs.d.vue.ts +2 -2
- package/dist/runtime/components/Tabs.vue +8 -8
- package/dist/runtime/components/Tabs.vue.d.ts +2 -2
- package/dist/runtime/components/TextArea.d.vue.ts +1 -1
- package/dist/runtime/components/TextArea.vue +51 -51
- package/dist/runtime/components/TextArea.vue.d.ts +1 -1
- package/dist/runtime/types/index.d.ts +15 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -204,6 +204,122 @@ A flexible input component with validation and state management.
|
|
|
204
204
|
|
|
205
205
|
---
|
|
206
206
|
|
|
207
|
+
### PUTextArea
|
|
208
|
+
|
|
209
|
+
A multi-line text input. Shares the look and feel of `PUInput`, with extra props for `rows` and resize behavior.
|
|
210
|
+
|
|
211
|
+
```vue
|
|
212
|
+
<PUTextArea v-model="message" label="Message" placeholder="Write your message" />
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Props**
|
|
216
|
+
|
|
217
|
+
| Prop | Type | Default | Description |
|
|
218
|
+
| ------------- | ----------------------------------------------------------- | ------------------------- | ---------------------------------------------------- |
|
|
219
|
+
| `modelValue` | `string \| number` | — | Bound value (v-model). |
|
|
220
|
+
| `label` | `string` | — | Label displayed above the textarea. |
|
|
221
|
+
| `labelClass` | `string` | `'text-sm font-semibold'` | Custom classes for the label. |
|
|
222
|
+
| `placeholder` | `string` | — | Placeholder text. |
|
|
223
|
+
| `description` | `string` | — | Helper text displayed below. |
|
|
224
|
+
| `rounded` | `'none' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | `'xl'` | Border radius. |
|
|
225
|
+
| `variant` | `'default' \| 'secondary'` | `'default'` | Visual style. |
|
|
226
|
+
| `rows` | `number \| string` | `4` | Initial number of visible rows. |
|
|
227
|
+
| `resize` | `'none' \| 'both' \| 'horizontal' \| 'vertical'` | `'vertical'` | Resize behavior. |
|
|
228
|
+
| `required` | `boolean` | `false` | Shows a red asterisk on the label. |
|
|
229
|
+
| `error` | `string` | — | Error message to display. Changes styling to danger. |
|
|
230
|
+
| `disabled` | `boolean` | `false` | Disables the textarea. |
|
|
231
|
+
|
|
232
|
+
**Slots**
|
|
233
|
+
|
|
234
|
+
| Slot | Description |
|
|
235
|
+
| -------------- | ----------------------------- |
|
|
236
|
+
| `startContent` | Icon or content at the start. |
|
|
237
|
+
| `endContent` | Icon or content at the end. |
|
|
238
|
+
|
|
239
|
+
**Examples**
|
|
240
|
+
|
|
241
|
+
```vue
|
|
242
|
+
<!-- Basic -->
|
|
243
|
+
<PUTextArea v-model="message" label="Message" placeholder="Write your message" />
|
|
244
|
+
|
|
245
|
+
<!-- Fixed size, no resize -->
|
|
246
|
+
<PUTextArea label="Comment" :rows="6" resize="none" />
|
|
247
|
+
|
|
248
|
+
<!-- With error -->
|
|
249
|
+
<PUTextArea label="Bio" error="Bio is required" required />
|
|
250
|
+
|
|
251
|
+
<!-- With icon -->
|
|
252
|
+
<PUTextArea label="Notes">
|
|
253
|
+
<template #startContent>
|
|
254
|
+
<Icon name="lucide:notebook-pen" />
|
|
255
|
+
</template>
|
|
256
|
+
</PUTextArea>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
### PUSelect
|
|
262
|
+
|
|
263
|
+
A custom select with an animated dropdown panel teleported to `body`. Dark-mode aware, supports `v-model`, and emits both `update:modelValue` and `change`.
|
|
264
|
+
|
|
265
|
+
```vue
|
|
266
|
+
<PUSelect
|
|
267
|
+
v-model="role"
|
|
268
|
+
label="Role"
|
|
269
|
+
:options="[
|
|
270
|
+
{ label: 'Admin', value: 'admin' },
|
|
271
|
+
{ label: 'Editor', value: 'editor' },
|
|
272
|
+
{ label: 'Viewer', value: 'viewer' },
|
|
273
|
+
]"
|
|
274
|
+
/>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**Props**
|
|
278
|
+
|
|
279
|
+
| Prop | Type | Default | Description |
|
|
280
|
+
| ------------- | ----------------------------------------------------------- | ------------------------- | ---------------------------------------------------- |
|
|
281
|
+
| `modelValue` | `string \| number \| null` | `null` | Selected value (v-model). |
|
|
282
|
+
| `options` | `{ label: string, value: string \| number }[]` | `[]` | Items shown in the dropdown. |
|
|
283
|
+
| `label` | `string` | — | Label displayed above the select. |
|
|
284
|
+
| `labelClass` | `string` | `'text-sm font-semibold'` | Custom classes for the label. |
|
|
285
|
+
| `placeholder` | `string` | `'Seleccionar'` | Text shown when nothing is selected. |
|
|
286
|
+
| `description` | `string` | — | Helper text displayed below. |
|
|
287
|
+
| `rounded` | `'none' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | `'xl'` | Border radius. |
|
|
288
|
+
| `variant` | `'default' \| 'secondary'` | `'default'` | Visual style. |
|
|
289
|
+
| `required` | `boolean` | `false` | Shows a red asterisk on the label. |
|
|
290
|
+
| `error` | `string` | `''` | Error message to display. Changes styling to danger. |
|
|
291
|
+
| `disabled` | `boolean` | `false` | Disables the select. |
|
|
292
|
+
|
|
293
|
+
**Events**
|
|
294
|
+
|
|
295
|
+
| Event | Payload | Description |
|
|
296
|
+
| ------------------- | ------------------ | -------------------------------------- |
|
|
297
|
+
| `update:modelValue` | `string \| number` | Emitted when an option is picked. |
|
|
298
|
+
| `change` | `string \| number` | Emitted alongside `update:modelValue`. |
|
|
299
|
+
|
|
300
|
+
**Examples**
|
|
301
|
+
|
|
302
|
+
```vue
|
|
303
|
+
<!-- Basic -->
|
|
304
|
+
<PUSelect v-model="country" :options="countries" label="Country" />
|
|
305
|
+
|
|
306
|
+
<!-- With description -->
|
|
307
|
+
<PUSelect
|
|
308
|
+
v-model="plan"
|
|
309
|
+
:options="plans"
|
|
310
|
+
label="Plan"
|
|
311
|
+
description="You can change this later"
|
|
312
|
+
/>
|
|
313
|
+
|
|
314
|
+
<!-- With error -->
|
|
315
|
+
<PUSelect v-model="status" :options="statuses" error="Pick a status" required />
|
|
316
|
+
|
|
317
|
+
<!-- Disabled -->
|
|
318
|
+
<PUSelect :options="statuses" disabled label="Locked" />
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
207
323
|
### PUCard
|
|
208
324
|
|
|
209
325
|
A flexible card component with customizable styling and borders.
|
|
@@ -451,17 +567,152 @@ const activeTab = ref("dashboard");
|
|
|
451
567
|
|
|
452
568
|
---
|
|
453
569
|
|
|
570
|
+
### PUDropdown
|
|
571
|
+
|
|
572
|
+
A floating panel anchored to an activator element. Opens on click and closes on outside click. Provides a `closeDropdown` function (via `inject`) so child items can close the panel after acting.
|
|
573
|
+
|
|
574
|
+
```vue
|
|
575
|
+
<PUDropdown>
|
|
576
|
+
<template #activator>
|
|
577
|
+
<PUButton label="Options" end-icon="lucide:chevron-down" />
|
|
578
|
+
</template>
|
|
579
|
+
<template #content>
|
|
580
|
+
<ul class="p-2">
|
|
581
|
+
<li class="px-3 py-2 hover:bg-gray-100 dark:hover:bg-white/10 rounded-lg cursor-pointer">
|
|
582
|
+
Profile
|
|
583
|
+
</li>
|
|
584
|
+
<li class="px-3 py-2 hover:bg-gray-100 dark:hover:bg-white/10 rounded-lg cursor-pointer">
|
|
585
|
+
Settings
|
|
586
|
+
</li>
|
|
587
|
+
</ul>
|
|
588
|
+
</template>
|
|
589
|
+
</PUDropdown>
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
**Slots**
|
|
593
|
+
|
|
594
|
+
| Slot | Description |
|
|
595
|
+
| ----------- | -------------------------------------------------------- |
|
|
596
|
+
| `activator` | The element the user clicks to open the dropdown. |
|
|
597
|
+
| `content` | The floating panel contents (rendered when open). |
|
|
598
|
+
|
|
599
|
+
**Provides**
|
|
600
|
+
|
|
601
|
+
| Key | Type | Description |
|
|
602
|
+
| --------------- | ------------ | ------------------------------------------------------------------------ |
|
|
603
|
+
| `closeDropdown` | `() => void` | Call from inside `content` to close the dropdown (e.g. after an action). |
|
|
604
|
+
|
|
605
|
+
```vue
|
|
606
|
+
<!-- Closing the dropdown from a child item -->
|
|
607
|
+
<script setup>
|
|
608
|
+
import { inject } from "vue";
|
|
609
|
+
const closeDropdown = inject("closeDropdown");
|
|
610
|
+
</script>
|
|
611
|
+
|
|
612
|
+
<template>
|
|
613
|
+
<button @click="handleAction(); closeDropdown?.()">Action</button>
|
|
614
|
+
</template>
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
### PUTable
|
|
620
|
+
|
|
621
|
+
A responsive data table that renders as a normal `<table>` on `md+` viewports and switches to a stack of cards on mobile. Cells are rendered through per-column scoped slots so you can fully customize their content.
|
|
622
|
+
|
|
623
|
+
```vue
|
|
624
|
+
<PUTable :columns="columns" :items="items" />
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
**Props**
|
|
628
|
+
|
|
629
|
+
| Prop | Type | Default | Description |
|
|
630
|
+
| ------------- | --------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------ |
|
|
631
|
+
| `items` | `Array<{ id: string \| number, [key: string]: unknown }>` | `[]` | Row data. Each item must have an `id` used as the Vue key. |
|
|
632
|
+
| `columns` | `{ name: string, id: string, width?: string }[]` | `[]` | Column definitions. `id` is the row key to read, `width` is CSS width. |
|
|
633
|
+
| `rounded` | `'none' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| '3xl' \| 'full'` | `'lg'` | Border radius of the outer container. |
|
|
634
|
+
| `isBordered` | `boolean` | `false` | Adds an outer border around the table. |
|
|
635
|
+
| `isSelectable` | `boolean` | `false` | Enables row click + hover effects (cursor, bg highlight, motion-v lift). Emits `row-click`. |
|
|
636
|
+
| `itemsSize` | `'sm' \| 'md' \| 'lg'` | `'md'` | Vertical padding of body rows. `sm` → `py-2`, `md` → `py-4`, `lg` → `py-6`. |
|
|
637
|
+
| `headerColor` | `string` | `bg-[#F4F4F5] text-[#71717A] dark:bg-[#27272A] dark:text-[#A1A1AA]` | Tailwind classes applied to `<thead>`. |
|
|
638
|
+
| `bodyColor` | `string` | `''` | Tailwind classes applied to `<tbody>`. |
|
|
639
|
+
|
|
640
|
+
**Events**
|
|
641
|
+
|
|
642
|
+
| Event | Payload | Description |
|
|
643
|
+
| ----------- | -------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
644
|
+
| `row-click` | `item: { id: string \| number, [key: string]: unknown }` | Emitted when a row is clicked (only when `isSelectable` is `true`). |
|
|
645
|
+
|
|
646
|
+
**Slots**
|
|
647
|
+
|
|
648
|
+
| Slot | Scope | Description |
|
|
649
|
+
| --------------- | -------------------------------------- | ---------------------------------------------------------------------------- |
|
|
650
|
+
| `cell-{id}` | `{ item, value }` | Customize the cell for the column with `id` = `{id}`. Falls back to `value`. |
|
|
651
|
+
| `mobile-card` | `{ item, columns }` | Replace the default mobile card layout for an entire row. |
|
|
652
|
+
|
|
653
|
+
**Examples**
|
|
654
|
+
|
|
655
|
+
```vue
|
|
656
|
+
<template>
|
|
657
|
+
<!-- Basic table -->
|
|
658
|
+
<PUTable :columns="columns" :items="items" />
|
|
659
|
+
|
|
660
|
+
<!-- Custom cell rendering -->
|
|
661
|
+
<PUTable :columns="columns" :items="items" rounded="2xl" is-bordered>
|
|
662
|
+
<template #cell-status="{ value }">
|
|
663
|
+
<PUChip :label="value" :color="value === 'Active' ? 'success' : 'danger'" variant="flat" size="sm" />
|
|
664
|
+
</template>
|
|
665
|
+
<template #cell-actions="{ item }">
|
|
666
|
+
<div class="flex gap-2 justify-end">
|
|
667
|
+
<PUButton is-icon-only icon="lucide:pencil" variant="ghost" size="sm" @click.stop="edit(item)" />
|
|
668
|
+
<PUButton is-icon-only icon="lucide:trash-2" variant="ghost" color="danger" size="sm" @click.stop="remove(item)" />
|
|
669
|
+
</div>
|
|
670
|
+
</template>
|
|
671
|
+
</PUTable>
|
|
672
|
+
|
|
673
|
+
<!-- Selectable rows with row-click -->
|
|
674
|
+
<PUTable
|
|
675
|
+
:columns="columns"
|
|
676
|
+
:items="items"
|
|
677
|
+
is-selectable
|
|
678
|
+
@row-click="onRowClick"
|
|
679
|
+
/>
|
|
680
|
+
</template>
|
|
681
|
+
|
|
682
|
+
<script setup>
|
|
683
|
+
const columns = [
|
|
684
|
+
{ name: "Name", id: "name", width: "40%" },
|
|
685
|
+
{ name: "Status", id: "status", width: "30%" },
|
|
686
|
+
{ name: "", id: "actions", width: "30%" },
|
|
687
|
+
];
|
|
688
|
+
const items = [
|
|
689
|
+
{ id: 1, name: "Ada Lovelace", status: "Active" },
|
|
690
|
+
{ id: 2, name: "Alan Turing", status: "Inactive" },
|
|
691
|
+
];
|
|
692
|
+
|
|
693
|
+
function onRowClick(item) {
|
|
694
|
+
console.log("clicked row:", item);
|
|
695
|
+
}
|
|
696
|
+
</script>
|
|
697
|
+
|
|
698
|
+
> When `isSelectable` is enabled, clicks on interactive children (buttons, links) propagate to the row. Use `@click.stop` on those children if you don't want them to fire `row-click`.
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
---
|
|
702
|
+
|
|
454
703
|
## TypeScript
|
|
455
704
|
|
|
456
705
|
ProxyUI exports all component types:
|
|
457
706
|
|
|
458
707
|
```ts
|
|
459
708
|
import type {
|
|
709
|
+
GlobalRounded,
|
|
460
710
|
ButtonProps,
|
|
461
711
|
ButtonColor,
|
|
462
712
|
ButtonVariant,
|
|
463
713
|
ButtonSize,
|
|
464
714
|
ButtonRounded,
|
|
715
|
+
InputProps,
|
|
465
716
|
InputVariant,
|
|
466
717
|
InputRounded,
|
|
467
718
|
ChipProps,
|
|
@@ -479,6 +730,8 @@ import type {
|
|
|
479
730
|
} from "proxy-ui";
|
|
480
731
|
```
|
|
481
732
|
|
|
733
|
+
> `PUTextArea`, `PUSelect`, `PUDropdown`, and `PUTable` define their props inline and do not export dedicated `Props` types. They reuse `InputVariant` and `InputRounded` from the same package.
|
|
734
|
+
|
|
482
735
|
---
|
|
483
736
|
|
|
484
737
|
## License
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -11,8 +11,9 @@ const module$1 = defineNuxtModule({
|
|
|
11
11
|
const resolver = createResolver(import.meta.url);
|
|
12
12
|
if (nuxt.options.fonts !== false) {
|
|
13
13
|
nuxt.options.fonts = nuxt.options.fonts ?? {};
|
|
14
|
-
nuxt.options.fonts
|
|
15
|
-
|
|
14
|
+
const fonts = nuxt.options.fonts;
|
|
15
|
+
fonts.families = [
|
|
16
|
+
...fonts.families ?? [],
|
|
16
17
|
{
|
|
17
18
|
name: "Inter",
|
|
18
19
|
provider: "google",
|
|
@@ -4,18 +4,23 @@
|
|
|
4
4
|
:class="[
|
|
5
5
|
!hasText ? 'text-black dark:text-white' : '',
|
|
6
6
|
sizes[props.size],
|
|
7
|
-
|
|
7
|
+
roundedClasses[props.rounded]
|
|
8
8
|
]"
|
|
9
9
|
>
|
|
10
|
-
<h1 v-if="props.label">
|
|
11
|
-
|
|
10
|
+
<h1 v-if="props.label">
|
|
11
|
+
{{ props.label }}
|
|
12
|
+
</h1>
|
|
13
|
+
<Icon
|
|
14
|
+
v-else-if="props.icon"
|
|
15
|
+
:name="props.icon"
|
|
16
|
+
/>
|
|
12
17
|
<img
|
|
13
18
|
v-else-if="props.image"
|
|
14
19
|
:src="props.image"
|
|
15
20
|
alt="Avatar"
|
|
16
21
|
class="object-cover w-full h-full"
|
|
17
|
-
:class="
|
|
18
|
-
|
|
22
|
+
:class="roundedClasses[props.rounded]"
|
|
23
|
+
>
|
|
19
24
|
</div>
|
|
20
25
|
</template>
|
|
21
26
|
|
|
@@ -28,14 +33,14 @@ const sizes = {
|
|
|
28
33
|
lg: "w-15 h-15",
|
|
29
34
|
full: "w-full h-full"
|
|
30
35
|
};
|
|
31
|
-
const
|
|
32
|
-
none: "rounded-none",
|
|
33
|
-
sm: "rounded-sm",
|
|
34
|
-
md: "rounded-md",
|
|
35
|
-
lg: "rounded-lg",
|
|
36
|
-
xl: "rounded-xl",
|
|
36
|
+
const roundedClasses = {
|
|
37
|
+
"none": "rounded-none",
|
|
38
|
+
"sm": "rounded-sm",
|
|
39
|
+
"md": "rounded-md",
|
|
40
|
+
"lg": "rounded-lg",
|
|
41
|
+
"xl": "rounded-xl",
|
|
37
42
|
"2xl": "rounded-2xl",
|
|
38
|
-
full: "rounded-full"
|
|
43
|
+
"full": "rounded-full"
|
|
39
44
|
};
|
|
40
45
|
const props = defineProps({
|
|
41
46
|
label: { type: String, required: false },
|
|
@@ -44,7 +49,7 @@ const props = defineProps({
|
|
|
44
49
|
size: { type: String, required: false, default: "md" },
|
|
45
50
|
rounded: { type: String, required: false, default: "full" }
|
|
46
51
|
});
|
|
47
|
-
const textSizes = /(?:^|:)text-(xs|sm|base|lg
|
|
52
|
+
const textSizes = /(?:^|:)text-(?:xs|sm|base|lg|\d*xl|wrap|nowrap|pretty|balance)$/;
|
|
48
53
|
const hasText = computed(() => {
|
|
49
54
|
const cls = typeof attrs.class === "string" ? attrs.class : "";
|
|
50
55
|
return cls.split(" ").some((c) => /(?:^|:)text-/.test(c) && !textSizes.test(c));
|
|
@@ -16,7 +16,10 @@
|
|
|
16
16
|
@click="emit('click', $event)"
|
|
17
17
|
>
|
|
18
18
|
<template v-if="isIconOnly">
|
|
19
|
-
<Icon
|
|
19
|
+
<Icon
|
|
20
|
+
v-if="loading"
|
|
21
|
+
name="svg-spinners:ring-resize"
|
|
22
|
+
/>
|
|
20
23
|
<Icon
|
|
21
24
|
v-else-if="icon"
|
|
22
25
|
:name="icon"
|
|
@@ -25,11 +28,26 @@
|
|
|
25
28
|
/>
|
|
26
29
|
</template>
|
|
27
30
|
<template v-else>
|
|
28
|
-
<Icon
|
|
29
|
-
|
|
31
|
+
<Icon
|
|
32
|
+
v-if="loading"
|
|
33
|
+
name="svg-spinners:ring-resize"
|
|
34
|
+
class="mr-2"
|
|
35
|
+
/>
|
|
36
|
+
<Icon
|
|
37
|
+
v-if="startIcon"
|
|
38
|
+
:name="startIcon"
|
|
39
|
+
class="mr-2"
|
|
40
|
+
/>
|
|
30
41
|
<slot v-if="!label" />
|
|
31
|
-
<span
|
|
32
|
-
|
|
42
|
+
<span
|
|
43
|
+
v-else
|
|
44
|
+
class="font-medium"
|
|
45
|
+
>{{ label }}</span>
|
|
46
|
+
<Icon
|
|
47
|
+
v-if="endIcon"
|
|
48
|
+
:name="endIcon"
|
|
49
|
+
class="ml-2"
|
|
50
|
+
/>
|
|
33
51
|
</template>
|
|
34
52
|
</motion.button>
|
|
35
53
|
</template>
|
|
@@ -54,14 +72,14 @@ const variantClasses = {
|
|
|
54
72
|
flat: ""
|
|
55
73
|
};
|
|
56
74
|
const roundedClasses = {
|
|
57
|
-
none: "rounded-none",
|
|
58
|
-
xs: "rounded-xs",
|
|
59
|
-
sm: "rounded-sm",
|
|
60
|
-
md: "rounded-md",
|
|
61
|
-
lg: "rounded-lg",
|
|
62
|
-
xl: "rounded-xl",
|
|
75
|
+
"none": "rounded-none",
|
|
76
|
+
"xs": "rounded-xs",
|
|
77
|
+
"sm": "rounded-sm",
|
|
78
|
+
"md": "rounded-md",
|
|
79
|
+
"lg": "rounded-lg",
|
|
80
|
+
"xl": "rounded-xl",
|
|
63
81
|
"2xl": "rounded-2xl",
|
|
64
|
-
full: "rounded-full"
|
|
82
|
+
"full": "rounded-full"
|
|
65
83
|
};
|
|
66
84
|
const emit = defineEmits(["click"]);
|
|
67
85
|
const props = defineProps({
|
|
@@ -8,19 +8,31 @@
|
|
|
8
8
|
]"
|
|
9
9
|
class="flex items-center justify-center"
|
|
10
10
|
>
|
|
11
|
-
<Icon
|
|
11
|
+
<Icon
|
|
12
|
+
v-if="startIcon"
|
|
13
|
+
:name="startIcon"
|
|
14
|
+
:size="iconSize"
|
|
15
|
+
class="mr-1"
|
|
16
|
+
/>
|
|
12
17
|
<slot v-if="!label" />
|
|
13
|
-
<span
|
|
14
|
-
|
|
18
|
+
<span
|
|
19
|
+
v-else
|
|
20
|
+
class="font-medium"
|
|
21
|
+
>{{ label }}</span>
|
|
22
|
+
<Icon
|
|
23
|
+
v-if="endIcon"
|
|
24
|
+
:name="endIcon"
|
|
25
|
+
:size="iconSize"
|
|
26
|
+
class="ml-1"
|
|
27
|
+
/>
|
|
15
28
|
</div>
|
|
16
29
|
</template>
|
|
17
30
|
|
|
18
31
|
<script setup>
|
|
19
|
-
import { motion } from "motion-v";
|
|
20
32
|
const sizes = {
|
|
21
|
-
sm: "text-xs min-w-
|
|
22
|
-
md: "text-xs min-w-
|
|
23
|
-
lg: "text-sm min-w-
|
|
33
|
+
sm: "text-xs min-w-8 py-1 px-2",
|
|
34
|
+
md: "text-xs min-w-12 py-1.5 px-2",
|
|
35
|
+
lg: "text-sm min-w-14 py-2 px-4"
|
|
24
36
|
};
|
|
25
37
|
const variantClasses = {
|
|
26
38
|
default: "",
|
|
@@ -30,13 +42,13 @@ const variantClasses = {
|
|
|
30
42
|
flat: ""
|
|
31
43
|
};
|
|
32
44
|
const roundedClasses = {
|
|
33
|
-
none: "rounded-none",
|
|
34
|
-
sm: "rounded-sm",
|
|
35
|
-
md: "rounded-md",
|
|
36
|
-
lg: "rounded-lg",
|
|
37
|
-
xl: "rounded-xl",
|
|
45
|
+
"none": "rounded-none",
|
|
46
|
+
"sm": "rounded-sm",
|
|
47
|
+
"md": "rounded-md",
|
|
48
|
+
"lg": "rounded-lg",
|
|
49
|
+
"xl": "rounded-xl",
|
|
38
50
|
"2xl": "rounded-2xl",
|
|
39
|
-
full: "rounded-full"
|
|
51
|
+
"full": "rounded-full"
|
|
40
52
|
};
|
|
41
53
|
const props = defineProps({
|
|
42
54
|
label: { type: String, required: false },
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
4
|
+
type __VLS_WithSlots<T, S> = T & (new () => {
|
|
5
|
+
$slots: S;
|
|
6
|
+
});
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
8
|
+
type __VLS_Slots = {
|
|
9
|
+
activator?: ((props: {}) => any) | undefined;
|
|
10
|
+
} & {
|
|
11
|
+
content?: ((props: {}) => any) | undefined;
|
|
12
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="dropdownRef"
|
|
4
|
+
class="relative inline-block text-left"
|
|
5
|
+
>
|
|
6
|
+
<div @click="toggle">
|
|
7
|
+
<slot name="activator" />
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<AnimatePresence>
|
|
11
|
+
<motion.div
|
|
12
|
+
v-if="isOpen"
|
|
13
|
+
:initial="{ scale: 0.9, opacity: 0, y: -10 }"
|
|
14
|
+
:exit="{ opacity: 0 }"
|
|
15
|
+
:animate="{ scale: 1, opacity: 1, y: 0 }"
|
|
16
|
+
class="absolute right-0 z-50 mt-2 min-w-52 origin-top-right bg-white border border-gray-100 rounded-xl shadow-xl dark:bg-[#18181B] dark:border-black/40"
|
|
17
|
+
@click="handleContentClick"
|
|
18
|
+
>
|
|
19
|
+
<slot name="content" />
|
|
20
|
+
</motion.div>
|
|
21
|
+
</AnimatePresence>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup>
|
|
26
|
+
import { AnimatePresence, motion } from "motion-v";
|
|
27
|
+
import { ref, onMounted, onUnmounted, provide } from "vue";
|
|
28
|
+
const isOpen = ref(false);
|
|
29
|
+
const dropdownRef = ref(null);
|
|
30
|
+
const toggle = () => {
|
|
31
|
+
isOpen.value = !isOpen.value;
|
|
32
|
+
};
|
|
33
|
+
const close = () => {
|
|
34
|
+
isOpen.value = false;
|
|
35
|
+
};
|
|
36
|
+
provide("closeDropdown", close);
|
|
37
|
+
const onClickOutside = (event) => {
|
|
38
|
+
if (dropdownRef.value && !dropdownRef.value.contains(event.target)) {
|
|
39
|
+
setTimeout(() => close(), 10);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const handleContentClick = (event) => {
|
|
43
|
+
event.stopPropagation();
|
|
44
|
+
};
|
|
45
|
+
onMounted(() => {
|
|
46
|
+
document.addEventListener("click", onClickOutside);
|
|
47
|
+
});
|
|
48
|
+
onUnmounted(() => {
|
|
49
|
+
document.removeEventListener("click", onClickOutside);
|
|
50
|
+
});
|
|
51
|
+
</script>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
4
|
+
type __VLS_WithSlots<T, S> = T & (new () => {
|
|
5
|
+
$slots: S;
|
|
6
|
+
});
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
8
|
+
type __VLS_Slots = {
|
|
9
|
+
activator?: ((props: {}) => any) | undefined;
|
|
10
|
+
} & {
|
|
11
|
+
content?: ((props: {}) => any) | undefined;
|
|
12
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InputVariant, InputRounded } from
|
|
1
|
+
import type { InputVariant, InputRounded } from '../types/index.js';
|
|
2
2
|
type __VLS_Props = {
|
|
3
3
|
modelValue?: string | number;
|
|
4
4
|
type?: string;
|
|
@@ -27,8 +27,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
27
27
|
type: string;
|
|
28
28
|
variant: InputVariant;
|
|
29
29
|
disabled: boolean;
|
|
30
|
-
labelClass: string;
|
|
31
30
|
required: boolean;
|
|
31
|
+
labelClass: string;
|
|
32
32
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
33
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
34
34
|
declare const _default: typeof __VLS_export;
|