@smurfox/proxy-ui 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 ADDED
@@ -0,0 +1,159 @@
1
+ # ProxyUI
2
+
3
+ A component library built for **Nuxt 4**, designed with a clean and consistent API. All components are prefixed with `PU`.
4
+
5
+ ## Features
6
+
7
+ - 🎨 Built with **Tailwind CSS v4**
8
+ - ✨ Smooth animations powered by **motion-v**
9
+ - 🔷 Icons via **@nuxt/icon** (Iconify)
10
+ - 🔤 **Inter** font loaded automatically
11
+ - 🌙 Dark mode ready
12
+ - 📦 TypeScript support out of the box
13
+
14
+ ---
15
+
16
+ ## Requirements
17
+
18
+ - Nuxt `^4.0.0`
19
+ - Tailwind CSS `^4.0.0`
20
+
21
+ ---
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install proxy-ui
27
+ ```
28
+
29
+ Add the module to your `nuxt.config.ts`:
30
+
31
+ ```ts
32
+ export default defineNuxtConfig({
33
+ modules: ["proxy-ui"],
34
+ });
35
+ ```
36
+
37
+ Add Tailwind to your CSS entry file:
38
+
39
+ ```css
40
+ @import "tailwindcss";
41
+ ```
42
+
43
+ That's it. All `PU` components are auto-imported and ready to use.
44
+
45
+ ---
46
+
47
+ ## Theming
48
+
49
+ ProxyUI uses CSS variables for colors. Add them to your CSS file to customize:
50
+
51
+ ```css
52
+ @import "tailwindcss";
53
+
54
+ @theme {
55
+ --color-primary: #376fff;
56
+ --color-success: #22c55e;
57
+ --color-warning: #f59e0b;
58
+ --color-danger: #ef4444;
59
+ }
60
+ ```
61
+
62
+ **Default values:**
63
+
64
+ | Variable | Default |
65
+ | ----------------- | --------- |
66
+ | `--color-primary` | `#376fff` |
67
+ | `--color-success` | `#2bd994` |
68
+ | `--color-warning` | `#f3a952` |
69
+ | `--color-danger` | `#fb2c56` |
70
+
71
+ ---
72
+
73
+ ## Components
74
+
75
+ ### PUButton
76
+
77
+ A button component powered by `motion-v` for smooth press animations.
78
+
79
+ ```vue
80
+ <PUButton label="Click me" />
81
+ ```
82
+
83
+ **Props**
84
+
85
+ | Prop | Type | Default | Description |
86
+ | ------------- | ----------------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------- |
87
+ | `label` | `string` | — | Text shown inside the button. If omitted, uses the default slot. |
88
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Controls padding and font size. |
89
+ | `variant` | `'default' \| 'secondary' \| 'outline' \| 'ghost' \| 'flat'` | `'default'` | Visual style of the button. |
90
+ | `color` | `'default' \| 'ios' \| 'primary' \| 'danger' \| 'success' \| 'warning' \| 'custom'` | `'default'` | Color scheme applied on top of the variant. |
91
+ | `rounded` | `'none' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | `'lg'` | Border radius. |
92
+ | `disabled` | `boolean` | `false` | Disables the button. |
93
+ | `loading` | `boolean` | `false` | Shows a spinner and disables interaction. |
94
+ | `startIcon` | `string` | — | Iconify icon name rendered before the label. |
95
+ | `endIcon` | `string` | — | Iconify icon name rendered after the label. |
96
+ | `customClass` | `string` | — | Tailwind classes applied when `color="custom"`. |
97
+
98
+ **Examples**
99
+
100
+ ```vue
101
+ <!-- Variants -->
102
+ <PUButton variant="default" label="Default" />
103
+ <PUButton variant="secondary" label="Secondary" />
104
+ <PUButton variant="outline" label="Outline" />
105
+ <PUButton variant="ghost" label="Ghost" />
106
+ <PUButton variant="flat" label="Flat" />
107
+
108
+ <!-- Colors -->
109
+ <PUButton color="primary" label="Primary" />
110
+ <PUButton color="danger" label="Danger" />
111
+ <PUButton color="success" label="Success" />
112
+ <PUButton color="warning" label="Warning" />
113
+
114
+ <!-- Sizes -->
115
+ <PUButton size="sm" label="Small" />
116
+ <PUButton size="md" label="Medium" />
117
+ <PUButton size="lg" label="Large" />
118
+
119
+ <!-- Icons -->
120
+ <PUButton start-icon="lucide:plus" label="New item" />
121
+ <PUButton end-icon="lucide:arrow-right" label="Continue" />
122
+
123
+ <!-- States -->
124
+ <PUButton disabled label="Disabled" />
125
+ <PUButton loading label="Saving..." />
126
+
127
+ <!-- Custom color -->
128
+ <PUButton
129
+ color="custom"
130
+ custom-class="bg-purple-500 text-white hover:bg-purple-600"
131
+ label="Custom"
132
+ />
133
+
134
+ <!-- Slot -->
135
+ <PUButton>
136
+ <span>Custom content</span>
137
+ </PUButton>
138
+ ```
139
+
140
+ ---
141
+
142
+ ## TypeScript
143
+
144
+ ProxyUI exports all component types:
145
+
146
+ ```ts
147
+ import type {
148
+ ButtonProps,
149
+ ButtonColor,
150
+ ButtonVariant,
151
+ ButtonSize,
152
+ } from "proxy-ui";
153
+ ```
154
+
155
+ ---
156
+
157
+ ## License
158
+
159
+ [MIT](./LICENSE)
@@ -0,0 +1,9 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ export * from '../dist/runtime/types/index.js';
3
+
4
+ interface ModuleOptions {
5
+ }
6
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
7
+
8
+ export { _default as default };
9
+ export type { ModuleOptions };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "proxy-ui",
3
+ "configKey": "proxyUI",
4
+ "version": "0.1.0",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "3.6.1"
8
+ }
9
+ }
@@ -0,0 +1,42 @@
1
+ import { defineNuxtModule, createResolver, addComponentsDir } from '@nuxt/kit';
2
+ export * from '../dist/runtime/types/index.js';
3
+
4
+ const module$1 = defineNuxtModule({
5
+ meta: {
6
+ name: "proxy-ui",
7
+ configKey: "proxyUI"
8
+ },
9
+ defaults: {},
10
+ async setup(options, nuxt) {
11
+ const resolver = createResolver(import.meta.url);
12
+ if (nuxt.options.fonts !== false) {
13
+ nuxt.options.fonts = nuxt.options.fonts ?? {};
14
+ nuxt.options.fonts.families = [
15
+ ...nuxt.options.fonts.families ?? [],
16
+ {
17
+ name: "Inter",
18
+ provider: "google",
19
+ weights: [400, 500, 600, 700]
20
+ }
21
+ ];
22
+ }
23
+ nuxt.options.app.head = nuxt.options.app.head ?? {};
24
+ nuxt.options.app.head.style = [
25
+ ...nuxt.options.app.head.style ?? [],
26
+ {
27
+ innerHTML: `
28
+ :root {
29
+ --shadow-ios: 0 10px 30px rgba(0, 0, 0, 0.05);
30
+ }
31
+ `
32
+ }
33
+ ];
34
+ addComponentsDir({
35
+ path: resolver.resolve("./runtime/components"),
36
+ prefix: "PU",
37
+ global: true
38
+ });
39
+ }
40
+ });
41
+
42
+ export { module$1 as default };
@@ -0,0 +1,14 @@
1
+ import type { AvatarSize, AvatarRounded } from "../types/index.js";
2
+ type __VLS_Props = {
3
+ label?: string;
4
+ icon?: string;
5
+ image?: string;
6
+ size?: AvatarSize;
7
+ rounded?: AvatarRounded;
8
+ };
9
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ size: AvatarSize;
11
+ rounded: AvatarRounded;
12
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: typeof __VLS_export;
14
+ export default _default;
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div
3
+ class="flex items-center justify-center bg-gray-200 dark:bg-white/10"
4
+ :class="[
5
+ !hasText ? 'text-black dark:text-white' : '',
6
+ sizes[props.size],
7
+ rounded[props.rounded]
8
+ ]"
9
+ >
10
+ <h1 v-if="props.label">{{ props.label }}</h1>
11
+ <Icon v-else-if="props.icon" :name="props.icon" />
12
+ <img
13
+ v-else-if="props.image"
14
+ :src="props.image"
15
+ alt="Avatar"
16
+ class="object-cover w-full h-full"
17
+ :class="rounded[props.rounded]"
18
+ />
19
+ </div>
20
+ </template>
21
+
22
+ <script setup>
23
+ import { computed, useAttrs } from "vue";
24
+ const attrs = useAttrs();
25
+ const sizes = {
26
+ sm: "w-11 h-11",
27
+ md: "w-13 h-13",
28
+ lg: "w-15 h-15",
29
+ full: "w-full h-full"
30
+ };
31
+ const rounded = {
32
+ none: "rounded-none",
33
+ sm: "rounded-sm",
34
+ md: "rounded-md",
35
+ lg: "rounded-lg",
36
+ xl: "rounded-xl",
37
+ "2xl": "rounded-2xl",
38
+ full: "rounded-full"
39
+ };
40
+ const props = defineProps({
41
+ label: { type: String, required: false },
42
+ icon: { type: String, required: false },
43
+ image: { type: String, required: false },
44
+ size: { type: String, required: false, default: "md" },
45
+ rounded: { type: String, required: false, default: "full" }
46
+ });
47
+ const textSizes = /(?:^|:)text-(xs|sm|base|lg|xl|\d*xl|wrap|nowrap|pretty|balance)$/;
48
+ const hasText = computed(() => {
49
+ const cls = typeof attrs.class === "string" ? attrs.class : "";
50
+ return cls.split(" ").some((c) => /(?:^|:)text-/.test(c) && !textSizes.test(c));
51
+ });
52
+ </script>
@@ -0,0 +1,14 @@
1
+ import type { AvatarSize, AvatarRounded } from "../types/index.js";
2
+ type __VLS_Props = {
3
+ label?: string;
4
+ icon?: string;
5
+ image?: string;
6
+ size?: AvatarSize;
7
+ rounded?: AvatarRounded;
8
+ };
9
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ size: AvatarSize;
11
+ rounded: AvatarRounded;
12
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: typeof __VLS_export;
14
+ export default _default;
@@ -0,0 +1,35 @@
1
+ import type { ButtonSize, ButtonVariant, ButtonColor, ButtonRounded } from "../types/index.js";
2
+ type __VLS_Props = {
3
+ label?: string;
4
+ size?: ButtonSize;
5
+ variant?: ButtonVariant;
6
+ color?: ButtonColor;
7
+ rounded?: ButtonRounded;
8
+ disabled?: boolean;
9
+ loading?: boolean;
10
+ isIconOnly?: boolean;
11
+ icon?: string;
12
+ startIcon?: string;
13
+ endIcon?: string;
14
+ iconSize?: string;
15
+ iconColor?: string;
16
+ customClass?: string;
17
+ };
18
+ declare var __VLS_30: {};
19
+ type __VLS_Slots = {} & {
20
+ default?: (props: typeof __VLS_30) => any;
21
+ };
22
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
23
+ size: ButtonSize;
24
+ rounded: ButtonRounded;
25
+ variant: ButtonVariant;
26
+ color: ButtonColor;
27
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
29
+ declare const _default: typeof __VLS_export;
30
+ export default _default;
31
+ type __VLS_WithSlots<T, S> = T & {
32
+ new (): {
33
+ $slots: S;
34
+ };
35
+ };
@@ -0,0 +1,137 @@
1
+ <template>
2
+ <motion.button
3
+ :class="[
4
+ isIconOnly ? iconOnlySizes[size] : sizes[size],
5
+ variantClasses[variant],
6
+ isIconOnly && customClass ? customClass : getColorBtn(variant, color),
7
+ roundedClasses[rounded],
8
+ {
9
+ 'opacity-50': disabled || loading,
10
+ 'cursor-pointer': !disabled && !loading,
11
+ 'pointer-events-none': disabled || loading
12
+ }
13
+ ]"
14
+ :while-press="disabled || loading ? {} : { scale: 0.95 }"
15
+ class="flex items-center justify-center select-none transition-[color,background-color,opacity,filter] duration-200"
16
+ @click="$emit('click')"
17
+ >
18
+ <template v-if="isIconOnly">
19
+ <Icon v-if="loading" name="svg-spinners:ring-resize" />
20
+ <Icon
21
+ v-else-if="icon"
22
+ :name="icon"
23
+ :size="iconSize"
24
+ :class="iconColor ? `text-${iconColor}` : ''"
25
+ />
26
+ </template>
27
+ <template v-else>
28
+ <Icon v-if="loading" name="svg-spinners:ring-resize" class="mr-2" />
29
+ <Icon v-if="startIcon" :name="startIcon" class="mr-2" />
30
+ <slot v-if="!label" />
31
+ <span v-else class="font-medium">{{ label }}</span>
32
+ <Icon v-if="endIcon" :name="endIcon" class="ml-2" />
33
+ </template>
34
+ </motion.button>
35
+ </template>
36
+
37
+ <script setup>
38
+ import { motion } from "motion-v";
39
+ const sizes = {
40
+ sm: "text-xs min-w-20 py-1.5 px-2",
41
+ md: "text-sm min-w-24 py-2 px-4",
42
+ lg: "text-base min-w-32 py-3 px-6"
43
+ };
44
+ const iconOnlySizes = {
45
+ sm: "size-7 text-xs",
46
+ md: "size-9 text-sm",
47
+ lg: "size-11 text-base"
48
+ };
49
+ const variantClasses = {
50
+ default: "",
51
+ secondary: "",
52
+ outline: "",
53
+ ghost: "",
54
+ flat: ""
55
+ };
56
+ 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",
63
+ "2xl": "rounded-2xl",
64
+ full: "rounded-full"
65
+ };
66
+ const props = defineProps({
67
+ label: { type: String, required: false },
68
+ size: { type: String, required: false, default: "md" },
69
+ variant: { type: String, required: false, default: "default" },
70
+ color: { type: String, required: false, default: "default" },
71
+ rounded: { type: String, required: false, default: "lg" },
72
+ disabled: { type: Boolean, required: false },
73
+ loading: { type: Boolean, required: false },
74
+ isIconOnly: { type: Boolean, required: false },
75
+ icon: { type: String, required: false },
76
+ startIcon: { type: String, required: false },
77
+ endIcon: { type: String, required: false },
78
+ iconSize: { type: String, required: false },
79
+ iconColor: { type: String, required: false },
80
+ customClass: { type: String, required: false }
81
+ });
82
+ const defaultColorClasses = {
83
+ default: "bg-gray-200/80 dark:bg-white/10 text-black dark:text-white hover:bg-gray-300/80 dark:hover:bg-white/20",
84
+ ios: "bg-blue-500 text-white hover:brightness-110",
85
+ primary: "bg-primary text-white hover:brightness-110",
86
+ danger: "bg-danger text-black hover:brightness-110",
87
+ success: "bg-success text-black hover:brightness-110",
88
+ warning: "bg-warning text-black hover:brightness-110"
89
+ };
90
+ const secondaryColorClasses = {
91
+ default: "bg-gray-100 dark:bg-white/5 text-black dark:text-white hover:bg-gray-200/80 dark:hover:bg-white/10",
92
+ ios: "bg-gray-200/60 dark:bg-white/7 text-blue-500 hover:bg-gray-200 dark:hover:bg-white/10",
93
+ primary: "bg-gray-200/60 dark:bg-white/7 text-primary hover:bg-gray-200 dark:hover:bg-white/10",
94
+ danger: "bg-gray-200/60 dark:bg-white/7 text-danger hover:bg-gray-200 dark:hover:bg-white/10",
95
+ success: "bg-gray-200/60 dark:bg-white/7 text-success hover:bg-gray-200 dark:hover:bg-white/10",
96
+ warning: "bg-gray-200/60 dark:bg-white/7 text-warning hover:bg-gray-200 dark:hover:bg-white/10"
97
+ };
98
+ const outlineColorClasses = {
99
+ default: "border border-gray-300 text-black dark:border-white/15 dark:text-white hover:bg-gray-100/80 dark:hover:bg-white/10",
100
+ ios: "border border-blue-500 text-blue-500 hover:bg-blue-500/15 dark:hover:bg-blue-500/25",
101
+ primary: "border border-primary text-primary hover:bg-primary/15 dark:hover:bg-primary/25",
102
+ danger: "border border-danger text-danger hover:bg-danger/15 dark:hover:bg-danger/25",
103
+ success: "border border-success text-success hover:bg-success/15 dark:hover:bg-success/25",
104
+ warning: "border border-warning text-warning hover:bg-warning/15 dark:hover:bg-warning/25"
105
+ };
106
+ const ghostColorClasses = {
107
+ default: "text-black dark:text-white hover:bg-gray-200/60 dark:hover:bg-white/10",
108
+ ios: "text-blue-500 hover:bg-blue-100 dark:hover:bg-blue-500/20",
109
+ primary: "text-primary hover:bg-primary/20 dark:hover:bg-primary/30",
110
+ danger: "text-danger hover:bg-danger/20 dark:hover:bg-danger/30",
111
+ success: "text-success hover:bg-success/20 dark:hover:bg-success/30",
112
+ warning: "text-warning hover:bg-warning/20 dark:hover:bg-warning/30"
113
+ };
114
+ const flatColorClasses = {
115
+ default: "bg-gray-100 dark:bg-white/5 text-black dark:text-white hover:bg-gray-200/80 dark:hover:bg-white/10",
116
+ ios: "bg-blue-500/15 text-blue-500 hover:bg-blue-500/25",
117
+ primary: "bg-primary/15 text-primary hover:bg-primary/25 dark:hover:bg-primary/30",
118
+ danger: "bg-danger/15 text-danger hover:bg-danger/25 dark:hover:bg-danger/30",
119
+ success: "bg-success/15 text-success hover:bg-success/25 dark:hover:bg-success/30",
120
+ warning: "bg-warning/15 text-warning hover:bg-warning/25 dark:hover:bg-warning/30"
121
+ };
122
+ function getColorBtn(variant, color) {
123
+ if (color === "custom") return props.customClass ?? "";
124
+ switch (variant) {
125
+ case "secondary":
126
+ return secondaryColorClasses[color];
127
+ case "outline":
128
+ return outlineColorClasses[color];
129
+ case "ghost":
130
+ return ghostColorClasses[color];
131
+ case "flat":
132
+ return flatColorClasses[color];
133
+ default:
134
+ return defaultColorClasses[color];
135
+ }
136
+ }
137
+ </script>
@@ -0,0 +1,35 @@
1
+ import type { ButtonSize, ButtonVariant, ButtonColor, ButtonRounded } from "../types/index.js";
2
+ type __VLS_Props = {
3
+ label?: string;
4
+ size?: ButtonSize;
5
+ variant?: ButtonVariant;
6
+ color?: ButtonColor;
7
+ rounded?: ButtonRounded;
8
+ disabled?: boolean;
9
+ loading?: boolean;
10
+ isIconOnly?: boolean;
11
+ icon?: string;
12
+ startIcon?: string;
13
+ endIcon?: string;
14
+ iconSize?: string;
15
+ iconColor?: string;
16
+ customClass?: string;
17
+ };
18
+ declare var __VLS_30: {};
19
+ type __VLS_Slots = {} & {
20
+ default?: (props: typeof __VLS_30) => any;
21
+ };
22
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
23
+ size: ButtonSize;
24
+ rounded: ButtonRounded;
25
+ variant: ButtonVariant;
26
+ color: ButtonColor;
27
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
29
+ declare const _default: typeof __VLS_export;
30
+ export default _default;
31
+ type __VLS_WithSlots<T, S> = T & {
32
+ new (): {
33
+ $slots: S;
34
+ };
35
+ };
@@ -0,0 +1,21 @@
1
+ import type { CardVariant } from "../types/index.js";
2
+ type __VLS_Props = {
3
+ variant?: CardVariant;
4
+ customClass?: string;
5
+ isBordered?: boolean;
6
+ };
7
+ declare var __VLS_1: {};
8
+ type __VLS_Slots = {} & {
9
+ default?: (props: typeof __VLS_1) => any;
10
+ };
11
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
12
+ isBordered: boolean;
13
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,35 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ !hasBg ? 'bg-white dark:bg-white/5' : '',
5
+ !hasPadding ? 'p-4' : '',
6
+ !hasShadow ? 'shadow-(--shadow-ios)' : '',
7
+ !hasRounded ? 'rounded-2xl' : '',
8
+ customClass,
9
+ isBordered ? 'border border-gray-200 dark:border-white/5' : ''
10
+ ]"
11
+ >
12
+ <slot />
13
+ </div>
14
+ </template>
15
+
16
+ <script setup>
17
+ import { computed } from "vue";
18
+ const props = defineProps({
19
+ variant: { type: String, required: false },
20
+ customClass: { type: String, required: false },
21
+ isBordered: { type: Boolean, required: false, default: false }
22
+ });
23
+ const hasBg = computed(
24
+ () => props.customClass?.split(" ").some((c) => c.startsWith("bg-"))
25
+ );
26
+ const hasPadding = computed(
27
+ () => props.customClass?.split(" ").some((c) => /^p[xytblrse]?-/.test(c))
28
+ );
29
+ const hasShadow = computed(
30
+ () => props.customClass?.split(" ").some((c) => c.startsWith("shadow-"))
31
+ );
32
+ const hasRounded = computed(
33
+ () => props.customClass?.split(" ").some((c) => c.startsWith("rounded-"))
34
+ );
35
+ </script>
@@ -0,0 +1,21 @@
1
+ import type { CardVariant } from "../types/index.js";
2
+ type __VLS_Props = {
3
+ variant?: CardVariant;
4
+ customClass?: string;
5
+ isBordered?: boolean;
6
+ };
7
+ declare var __VLS_1: {};
8
+ type __VLS_Slots = {} & {
9
+ default?: (props: typeof __VLS_1) => any;
10
+ };
11
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
12
+ isBordered: boolean;
13
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,30 @@
1
+ import type { ChipSize, ChipVariant, ChipColor, ChipRounded } from "../types/index.js";
2
+ type __VLS_Props = {
3
+ label?: string;
4
+ size?: ChipSize;
5
+ variant?: ChipVariant;
6
+ color?: ChipColor;
7
+ rounded?: ChipRounded;
8
+ startIcon?: string;
9
+ endIcon?: string;
10
+ customClass?: string;
11
+ iconSize?: string;
12
+ };
13
+ declare var __VLS_6: {};
14
+ type __VLS_Slots = {} & {
15
+ default?: (props: typeof __VLS_6) => any;
16
+ };
17
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
18
+ size: ChipSize;
19
+ rounded: ChipRounded;
20
+ variant: ChipVariant;
21
+ color: ChipColor;
22
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
24
+ declare const _default: typeof __VLS_export;
25
+ export default _default;
26
+ type __VLS_WithSlots<T, S> = T & {
27
+ new (): {
28
+ $slots: S;
29
+ };
30
+ };
@@ -0,0 +1,97 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ sizes[size],
5
+ variantClasses[variant],
6
+ getColorBtn(variant, color),
7
+ roundedClasses[rounded]
8
+ ]"
9
+ class="flex items-center justify-center"
10
+ >
11
+ <Icon v-if="startIcon" :name="startIcon" :size="iconSize" class="mr-1" />
12
+ <slot v-if="!label" />
13
+ <span v-else class="font-medium">{{ label }}</span>
14
+ <Icon v-if="endIcon" :name="endIcon" :size="iconSize" class="ml-1" />
15
+ </div>
16
+ </template>
17
+
18
+ <script setup>
19
+ import { motion } from "motion-v";
20
+ const sizes = {
21
+ sm: "text-xs min-w-18 py-1 px-2",
22
+ md: "text-xs min-w-20 py-1.5 px-2",
23
+ lg: "text-sm min-w-24 py-2 px-4"
24
+ };
25
+ const variantClasses = {
26
+ default: "",
27
+ secondary: "",
28
+ outline: "",
29
+ ghost: "",
30
+ flat: ""
31
+ };
32
+ const roundedClasses = {
33
+ none: "rounded-none",
34
+ sm: "rounded-sm",
35
+ md: "rounded-md",
36
+ lg: "rounded-lg",
37
+ xl: "rounded-xl",
38
+ "2xl": "rounded-2xl",
39
+ full: "rounded-full"
40
+ };
41
+ const props = defineProps({
42
+ label: { type: String, required: false },
43
+ size: { type: String, required: false, default: "md" },
44
+ variant: { type: String, required: false, default: "default" },
45
+ color: { type: String, required: false, default: "default" },
46
+ rounded: { type: String, required: false, default: "full" },
47
+ startIcon: { type: String, required: false },
48
+ endIcon: { type: String, required: false },
49
+ customClass: { type: String, required: false },
50
+ iconSize: { type: String, required: false }
51
+ });
52
+ const defaultColorClasses = {
53
+ default: "bg-gray-200/80 dark:bg-white/10 text-black dark:text-white",
54
+ ios: "bg-blue-500 text-white",
55
+ primary: "bg-primary text-white",
56
+ danger: "bg-danger text-black",
57
+ success: "bg-success text-black",
58
+ warning: "bg-warning text-black"
59
+ };
60
+ const secondaryColorClasses = {
61
+ default: "bg-gray-100 dark:bg-white/5 text-black dark:text-white",
62
+ ios: "bg-gray-200/60 dark:bg-white/7 text-blue-500",
63
+ primary: "bg-gray-200/60 dark:bg-white/7 text-primary",
64
+ danger: "bg-gray-200/60 dark:bg-white/7 text-danger",
65
+ success: "bg-gray-200/60 dark:bg-white/7 text-success",
66
+ warning: "bg-gray-200/60 dark:bg-white/7 text-warning"
67
+ };
68
+ const outlineColorClasses = {
69
+ default: "border border-gray-300 text-black dark:border-white/15 dark:text-white",
70
+ ios: "border border-blue-500 text-blue-500",
71
+ primary: "border border-primary text-primary",
72
+ danger: "border border-danger text-danger",
73
+ success: "border border-success text-success",
74
+ warning: "border border-warning text-warning"
75
+ };
76
+ const flatColorClasses = {
77
+ default: "bg-gray-100 dark:bg-white/5 text-black dark:text-white",
78
+ ios: "bg-blue-500/15 text-blue-500",
79
+ primary: "bg-primary/15 text-primary",
80
+ danger: "bg-danger/15 text-danger",
81
+ success: "bg-success/15 text-success",
82
+ warning: "bg-warning/15 text-warning"
83
+ };
84
+ function getColorBtn(variant, color) {
85
+ if (color === "custom") return props.customClass ?? "";
86
+ switch (variant) {
87
+ case "secondary":
88
+ return secondaryColorClasses[color];
89
+ case "outline":
90
+ return outlineColorClasses[color];
91
+ case "flat":
92
+ return flatColorClasses[color];
93
+ default:
94
+ return defaultColorClasses[color];
95
+ }
96
+ }
97
+ </script>
@@ -0,0 +1,30 @@
1
+ import type { ChipSize, ChipVariant, ChipColor, ChipRounded } from "../types/index.js";
2
+ type __VLS_Props = {
3
+ label?: string;
4
+ size?: ChipSize;
5
+ variant?: ChipVariant;
6
+ color?: ChipColor;
7
+ rounded?: ChipRounded;
8
+ startIcon?: string;
9
+ endIcon?: string;
10
+ customClass?: string;
11
+ iconSize?: string;
12
+ };
13
+ declare var __VLS_6: {};
14
+ type __VLS_Slots = {} & {
15
+ default?: (props: typeof __VLS_6) => any;
16
+ };
17
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
18
+ size: ChipSize;
19
+ rounded: ChipRounded;
20
+ variant: ChipVariant;
21
+ color: ChipColor;
22
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
24
+ declare const _default: typeof __VLS_export;
25
+ export default _default;
26
+ type __VLS_WithSlots<T, S> = T & {
27
+ new (): {
28
+ $slots: S;
29
+ };
30
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
2
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import { defineNuxtPlugin } from "#app";
2
+ export default defineNuxtPlugin((_nuxtApp) => {
3
+ console.log("Plugin injected by my-module!");
4
+ });
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "../../../.nuxt/tsconfig.server.json",
3
+ }
@@ -0,0 +1,40 @@
1
+ export type ButtonSize = "sm" | "md" | "lg";
2
+ export type ButtonVariant = "default" | "secondary" | "outline" | "ghost" | "flat";
3
+ export type ButtonColor = "default" | "ios" | "primary" | "danger" | "success" | "warning" | "custom";
4
+ export type ButtonRounded = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "full";
5
+ export interface ButtonProps {
6
+ label?: string;
7
+ size?: ButtonSize;
8
+ variant?: ButtonVariant;
9
+ color?: ButtonColor;
10
+ rounded?: ButtonRounded;
11
+ disabled?: boolean;
12
+ loading?: boolean;
13
+ isIconOnly?: boolean;
14
+ icon?: string;
15
+ startIcon?: string;
16
+ endIcon?: string;
17
+ customClass?: string;
18
+ }
19
+ export type ChipSize = "sm" | "md" | "lg";
20
+ export type ChipVariant = "default" | "secondary" | "outline" | "flat";
21
+ export type ChipColor = "default" | "ios" | "primary" | "danger" | "success" | "warning" | "custom";
22
+ export type ChipRounded = "none" | "sm" | "md" | "lg" | "xl" | "2xl" | "full";
23
+ export interface ChipProps {
24
+ label?: string;
25
+ size?: ChipSize;
26
+ variant?: ChipVariant;
27
+ color?: ChipColor;
28
+ rounded?: ChipRounded;
29
+ startIcon?: string;
30
+ endIcon?: string;
31
+ customClass?: string;
32
+ }
33
+ export type CardVariant = "default" | "liquidGlass";
34
+ export interface CardProps {
35
+ variant?: CardVariant;
36
+ customClass?: string;
37
+ isBordered?: boolean;
38
+ }
39
+ export type AvatarSize = "sm" | "md" | "lg" | "full";
40
+ export type AvatarRounded = "none" | "sm" | "md" | "lg" | "xl" | "2xl" | "full";
File without changes
@@ -0,0 +1,5 @@
1
+ export { default } from './module.mjs'
2
+
3
+ export { type ModuleOptions } from './module.mjs'
4
+
5
+ export * from '../dist/runtime/types/index.js'
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@smurfox/proxy-ui",
3
+ "version": "0.1.0",
4
+ "description": "A UI component library built for Nuxt 4",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/Smurfox/proxy-ui"
8
+ },
9
+ "homepage": "https://github.com/Smurfox/proxy-ui",
10
+ "bugs": {
11
+ "url": "https://github.com/Smurfox/proxy-ui/issues"
12
+ },
13
+ "author": "Smurfox",
14
+ "license": "MIT",
15
+ "type": "module",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/types.d.mts",
19
+ "import": "./dist/module.mjs"
20
+ }
21
+ },
22
+ "main": "./dist/module.mjs",
23
+ "typesVersions": {
24
+ "*": {
25
+ ".": [
26
+ "./dist/types.d.mts"
27
+ ]
28
+ }
29
+ },
30
+ "files": [
31
+ "dist"
32
+ ],
33
+ "keywords": [
34
+ "nuxt",
35
+ "nuxt4",
36
+ "ui",
37
+ "components",
38
+ "tailwindcss",
39
+ "motion-v"
40
+ ],
41
+ "workspaces": [
42
+ "playground"
43
+ ],
44
+ "scripts": {
45
+ "prepack": "nuxt-module-build build",
46
+ "dev": "npm run dev:prepare && nuxt dev playground",
47
+ "dev:build": "nuxt build playground",
48
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt prepare playground",
49
+ "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
50
+ "lint": "eslint .",
51
+ "test": "vitest run",
52
+ "test:watch": "vitest watch",
53
+ "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
54
+ },
55
+ "dependencies": {
56
+ "@nuxt/fonts": "^0.14.0",
57
+ "@nuxt/icon": "^2.2.1",
58
+ "@nuxt/kit": "^4.4.2",
59
+ "motion-v": "^1.0.0"
60
+ },
61
+ "peerDependencies": {
62
+ "nuxt": "^4.0.0",
63
+ "tailwindcss": "^4.0.0"
64
+ },
65
+ "devDependencies": {
66
+ "@nuxt/devtools": "^3.2.4",
67
+ "@nuxt/eslint-config": "^1.15.2",
68
+ "@nuxt/module-builder": "^1.0.2",
69
+ "@nuxt/schema": "^4.4.2",
70
+ "@nuxt/test-utils": "^4.0.0",
71
+ "@types/node": "latest",
72
+ "changelogen": "^0.6.2",
73
+ "eslint": "^10.1.0",
74
+ "nuxt": "^4.4.2",
75
+ "typescript": "~6.0.2",
76
+ "vitest": "^4.1.1",
77
+ "vue-tsc": "^3.2.6"
78
+ }
79
+ }