@smurfox/proxy-ui 0.2.0 → 0.2.2
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
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
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
|
|
31
31
|
<script setup>
|
|
32
32
|
const sizes = {
|
|
33
|
-
sm: "text-xs min-w-
|
|
34
|
-
md: "text-xs min-w-
|
|
35
|
-
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"
|
|
36
36
|
};
|
|
37
37
|
const variantClasses = {
|
|
38
38
|
default: "",
|
|
@@ -9,6 +9,11 @@ declare const roundedClasses: {
|
|
|
9
9
|
readonly '3xl': "rounded-3xl";
|
|
10
10
|
readonly full: "rounded-full";
|
|
11
11
|
};
|
|
12
|
+
declare const sizes: {
|
|
13
|
+
readonly sm: "py-2";
|
|
14
|
+
readonly md: "py-4";
|
|
15
|
+
readonly lg: "py-6";
|
|
16
|
+
};
|
|
12
17
|
type __VLS_Props = {
|
|
13
18
|
items?: Array<{
|
|
14
19
|
id: string | number;
|
|
@@ -21,16 +26,18 @@ type __VLS_Props = {
|
|
|
21
26
|
}[];
|
|
22
27
|
rounded?: keyof typeof roundedClasses;
|
|
23
28
|
isBordered?: boolean;
|
|
29
|
+
isSelectable?: boolean;
|
|
24
30
|
headerColor?: string;
|
|
25
31
|
bodyColor?: string;
|
|
32
|
+
itemsSize?: keyof typeof sizes;
|
|
26
33
|
};
|
|
27
|
-
declare var
|
|
34
|
+
declare var __VLS_10: `cell-${string}`, __VLS_11: {
|
|
28
35
|
item: {
|
|
29
36
|
[key: string]: unknown;
|
|
30
37
|
id: string | number;
|
|
31
38
|
};
|
|
32
39
|
value: unknown;
|
|
33
|
-
},
|
|
40
|
+
}, __VLS_21: {
|
|
34
41
|
item: {
|
|
35
42
|
[key: string]: unknown;
|
|
36
43
|
id: string | number;
|
|
@@ -40,7 +47,7 @@ declare var __VLS_2: `cell-${string}`, __VLS_3: {
|
|
|
40
47
|
id: string;
|
|
41
48
|
width?: string;
|
|
42
49
|
}[];
|
|
43
|
-
},
|
|
50
|
+
}, __VLS_24: `cell-${string}`, __VLS_25: {
|
|
44
51
|
item: {
|
|
45
52
|
[key: string]: unknown;
|
|
46
53
|
id: string | number;
|
|
@@ -48,13 +55,23 @@ declare var __VLS_2: `cell-${string}`, __VLS_3: {
|
|
|
48
55
|
value: unknown;
|
|
49
56
|
};
|
|
50
57
|
type __VLS_Slots = {} & {
|
|
51
|
-
[K in NonNullable<typeof
|
|
58
|
+
[K in NonNullable<typeof __VLS_10>]?: (props: typeof __VLS_11) => any;
|
|
52
59
|
} & {
|
|
53
|
-
[K in NonNullable<typeof
|
|
60
|
+
[K in NonNullable<typeof __VLS_24>]?: (props: typeof __VLS_25) => any;
|
|
54
61
|
} & {
|
|
55
|
-
'mobile-card'?: (props: typeof
|
|
62
|
+
'mobile-card'?: (props: typeof __VLS_21) => any;
|
|
56
63
|
};
|
|
57
|
-
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
64
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
65
|
+
"row-click": (item: {
|
|
66
|
+
[key: string]: unknown;
|
|
67
|
+
id: string | number;
|
|
68
|
+
}) => any;
|
|
69
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
70
|
+
"onRow-click"?: ((item: {
|
|
71
|
+
[key: string]: unknown;
|
|
72
|
+
id: string | number;
|
|
73
|
+
}) => any) | undefined;
|
|
74
|
+
}>, {
|
|
58
75
|
rounded: keyof typeof roundedClasses;
|
|
59
76
|
columns: {
|
|
60
77
|
name: string;
|
|
@@ -66,8 +83,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
66
83
|
id: string | number;
|
|
67
84
|
[key: string]: unknown;
|
|
68
85
|
}>;
|
|
86
|
+
isSelectable: boolean;
|
|
69
87
|
headerColor: string;
|
|
70
88
|
bodyColor: string;
|
|
89
|
+
itemsSize: keyof typeof sizes;
|
|
71
90
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
72
91
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
73
92
|
declare const _default: typeof __VLS_export;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="relative w-full">
|
|
3
3
|
<!-- Vista de tabla para pantallas medianas y grandes -->
|
|
4
4
|
<div
|
|
5
|
-
class="hidden md:block overflow-
|
|
5
|
+
class="hidden md:block overflow-clip"
|
|
6
6
|
:class="[
|
|
7
7
|
roundedClasses[props.rounded],
|
|
8
8
|
isBordered ? 'border border-gray-200 dark:border-white/10 ' : ''
|
|
@@ -29,15 +29,20 @@
|
|
|
29
29
|
|
|
30
30
|
<tbody :class="props.bodyColor">
|
|
31
31
|
<template v-if="items.length > 0">
|
|
32
|
-
<tr
|
|
32
|
+
<motion.tr
|
|
33
33
|
v-for="item in items"
|
|
34
34
|
:key="item.id"
|
|
35
|
+
:while-hover="props.isSelectable ? { scale: 1.01 } : {}"
|
|
36
|
+
:transition="{ type: 'spring', stiffness: 400, damping: 30 }"
|
|
37
|
+
:class="props.isSelectable ? 'cursor-pointer hover:bg-gray-100 dark:hover:bg-white/5' : ''"
|
|
38
|
+
@click="props.isSelectable && emit('row-click', item)"
|
|
35
39
|
>
|
|
36
40
|
<td
|
|
37
41
|
v-for="column in columns"
|
|
38
42
|
:key="column.id"
|
|
39
43
|
:style="{ width: column.width || 'auto' }"
|
|
40
|
-
class="px-4
|
|
44
|
+
class="px-4 text-gray-900 dark:text-white break-words"
|
|
45
|
+
:class="sizes[props.itemsSize]"
|
|
41
46
|
>
|
|
42
47
|
<slot
|
|
43
48
|
:name="`cell-${column.id}`"
|
|
@@ -47,7 +52,7 @@
|
|
|
47
52
|
{{ item[column.id] }}
|
|
48
53
|
</slot>
|
|
49
54
|
</td>
|
|
50
|
-
</tr>
|
|
55
|
+
</motion.tr>
|
|
51
56
|
</template>
|
|
52
57
|
|
|
53
58
|
<tr v-else>
|
|
@@ -64,10 +69,14 @@
|
|
|
64
69
|
|
|
65
70
|
<!-- Vista de tarjetas para dispositivos móviles -->
|
|
66
71
|
<div class="block md:hidden space-y-4 p-1">
|
|
67
|
-
<div
|
|
72
|
+
<motion.div
|
|
68
73
|
v-for="item in items"
|
|
69
74
|
:key="item.id"
|
|
75
|
+
:while-hover="props.isSelectable ? { y: -3 } : {}"
|
|
76
|
+
:transition="{ type: 'spring', stiffness: 400, damping: 25 }"
|
|
70
77
|
class="bg-white dark:bg-[#18181B] border border-gray-200 dark:border-white/10 rounded-lg p-4 shadow-sm"
|
|
78
|
+
:class="props.isSelectable ? 'cursor-pointer hover:bg-gray-50 dark:hover:bg-white/5 hover:shadow-md' : ''"
|
|
79
|
+
@click="props.isSelectable && emit('row-click', item)"
|
|
71
80
|
>
|
|
72
81
|
<slot
|
|
73
82
|
name="mobile-card"
|
|
@@ -98,7 +107,7 @@
|
|
|
98
107
|
</div>
|
|
99
108
|
</div>
|
|
100
109
|
</slot>
|
|
101
|
-
</div>
|
|
110
|
+
</motion.div>
|
|
102
111
|
|
|
103
112
|
<!-- Mensaje cuando no hay items -->
|
|
104
113
|
<div
|
|
@@ -112,6 +121,7 @@
|
|
|
112
121
|
</template>
|
|
113
122
|
|
|
114
123
|
<script setup>
|
|
124
|
+
import { motion } from "motion-v";
|
|
115
125
|
const roundedClasses = {
|
|
116
126
|
"none": "rounded-none",
|
|
117
127
|
"xs": "rounded-xs",
|
|
@@ -167,12 +177,20 @@ const roundedTopEndClasses = {
|
|
|
167
177
|
"3xl": "rounded-se-3xl",
|
|
168
178
|
"full": "rounded-se-full"
|
|
169
179
|
};
|
|
180
|
+
const sizes = {
|
|
181
|
+
sm: "py-2",
|
|
182
|
+
md: "py-4",
|
|
183
|
+
lg: "py-6"
|
|
184
|
+
};
|
|
170
185
|
const props = defineProps({
|
|
171
186
|
items: { type: Array, required: false, default: () => [] },
|
|
172
187
|
columns: { type: Array, required: false, default: () => [] },
|
|
173
188
|
rounded: { type: null, required: false, default: "lg" },
|
|
174
189
|
isBordered: { type: Boolean, required: false, default: false },
|
|
190
|
+
isSelectable: { type: Boolean, required: false, default: false },
|
|
175
191
|
headerColor: { type: String, required: false, default: "bg-[#F4F4F5] text-[#71717A] dark:bg-[#27272A] dark:text-[#A1A1AA]" },
|
|
176
|
-
bodyColor: { type: String, required: false, default: "" }
|
|
192
|
+
bodyColor: { type: String, required: false, default: "" },
|
|
193
|
+
itemsSize: { type: null, required: false, default: "md" }
|
|
177
194
|
});
|
|
195
|
+
const emit = defineEmits(["row-click"]);
|
|
178
196
|
</script>
|
|
@@ -9,6 +9,11 @@ declare const roundedClasses: {
|
|
|
9
9
|
readonly '3xl': "rounded-3xl";
|
|
10
10
|
readonly full: "rounded-full";
|
|
11
11
|
};
|
|
12
|
+
declare const sizes: {
|
|
13
|
+
readonly sm: "py-2";
|
|
14
|
+
readonly md: "py-4";
|
|
15
|
+
readonly lg: "py-6";
|
|
16
|
+
};
|
|
12
17
|
type __VLS_Props = {
|
|
13
18
|
items?: Array<{
|
|
14
19
|
id: string | number;
|
|
@@ -21,16 +26,18 @@ type __VLS_Props = {
|
|
|
21
26
|
}[];
|
|
22
27
|
rounded?: keyof typeof roundedClasses;
|
|
23
28
|
isBordered?: boolean;
|
|
29
|
+
isSelectable?: boolean;
|
|
24
30
|
headerColor?: string;
|
|
25
31
|
bodyColor?: string;
|
|
32
|
+
itemsSize?: keyof typeof sizes;
|
|
26
33
|
};
|
|
27
|
-
declare var
|
|
34
|
+
declare var __VLS_10: `cell-${string}`, __VLS_11: {
|
|
28
35
|
item: {
|
|
29
36
|
[key: string]: unknown;
|
|
30
37
|
id: string | number;
|
|
31
38
|
};
|
|
32
39
|
value: unknown;
|
|
33
|
-
},
|
|
40
|
+
}, __VLS_21: {
|
|
34
41
|
item: {
|
|
35
42
|
[key: string]: unknown;
|
|
36
43
|
id: string | number;
|
|
@@ -40,7 +47,7 @@ declare var __VLS_2: `cell-${string}`, __VLS_3: {
|
|
|
40
47
|
id: string;
|
|
41
48
|
width?: string;
|
|
42
49
|
}[];
|
|
43
|
-
},
|
|
50
|
+
}, __VLS_24: `cell-${string}`, __VLS_25: {
|
|
44
51
|
item: {
|
|
45
52
|
[key: string]: unknown;
|
|
46
53
|
id: string | number;
|
|
@@ -48,13 +55,23 @@ declare var __VLS_2: `cell-${string}`, __VLS_3: {
|
|
|
48
55
|
value: unknown;
|
|
49
56
|
};
|
|
50
57
|
type __VLS_Slots = {} & {
|
|
51
|
-
[K in NonNullable<typeof
|
|
58
|
+
[K in NonNullable<typeof __VLS_10>]?: (props: typeof __VLS_11) => any;
|
|
52
59
|
} & {
|
|
53
|
-
[K in NonNullable<typeof
|
|
60
|
+
[K in NonNullable<typeof __VLS_24>]?: (props: typeof __VLS_25) => any;
|
|
54
61
|
} & {
|
|
55
|
-
'mobile-card'?: (props: typeof
|
|
62
|
+
'mobile-card'?: (props: typeof __VLS_21) => any;
|
|
56
63
|
};
|
|
57
|
-
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
64
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
65
|
+
"row-click": (item: {
|
|
66
|
+
[key: string]: unknown;
|
|
67
|
+
id: string | number;
|
|
68
|
+
}) => any;
|
|
69
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
70
|
+
"onRow-click"?: ((item: {
|
|
71
|
+
[key: string]: unknown;
|
|
72
|
+
id: string | number;
|
|
73
|
+
}) => any) | undefined;
|
|
74
|
+
}>, {
|
|
58
75
|
rounded: keyof typeof roundedClasses;
|
|
59
76
|
columns: {
|
|
60
77
|
name: string;
|
|
@@ -66,8 +83,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
66
83
|
id: string | number;
|
|
67
84
|
[key: string]: unknown;
|
|
68
85
|
}>;
|
|
86
|
+
isSelectable: boolean;
|
|
69
87
|
headerColor: string;
|
|
70
88
|
bodyColor: string;
|
|
89
|
+
itemsSize: keyof typeof sizes;
|
|
71
90
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
72
91
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
73
92
|
declare const _default: typeof __VLS_export;
|