@imaginario27/air-ui-ds 1.0.0 → 1.0.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
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @imaginario27/air-ui-ds
|
|
2
|
+
|
|
3
|
+
A modular Design System and UI component library built for Vue and Nuxt. It provides a scalable architecture for building consistent interfaces, theme management, and reusable components powered by Tailwind CSS and TypeScript.
|
|
4
|
+
|
|
5
|
+
Documentation: [https://air-ui.netlify.app/](https://air-ui.netlify.app/)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
* Vue and Nuxt compatibility
|
|
10
|
+
* Design System tokens for colors, spacing, typography, and themes
|
|
11
|
+
* Reusable and typed UI components
|
|
12
|
+
* Light and dark theme system with automatic CSS variable generation
|
|
13
|
+
* Tailwind CSS latest version integration
|
|
14
|
+
* Auto-import support for components and composables in Nuxt
|
|
15
|
+
* Utilities for i18n, file uploads, images, PDF generation, and QR codes
|
|
16
|
+
* Full testing setup with Vitest, Vue Test Utils, and Nuxt Test Utils
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
Install using npm:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @imaginario27/air-ui-ds
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Using pnpm:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add @imaginario27/air-ui-ds
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Using yarn:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
yarn add @imaginario27/air-ui-ds
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Theme Generation
|
|
40
|
+
|
|
41
|
+
You can generate theme tokens and CSS variables using the built-in script:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm run generate-theme
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This regenerates the theme files used by Tailwind CSS and the Design System.
|
|
48
|
+
|
|
49
|
+
## Testing
|
|
50
|
+
|
|
51
|
+
This package includes a complete testing environment using:
|
|
52
|
+
|
|
53
|
+
* Vitest
|
|
54
|
+
* Vue Test Utils
|
|
55
|
+
* Nuxt Test Utils
|
|
56
|
+
* Happy DOM
|
|
57
|
+
|
|
58
|
+
Run the tests with:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm run test
|
|
62
|
+
```
|
|
@@ -1,32 +1,60 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<header
|
|
3
3
|
:class="[
|
|
4
|
-
isSticky && 'sticky top-0 z-50'
|
|
4
|
+
isSticky && 'sticky top-0 z-50',
|
|
5
5
|
]"
|
|
6
6
|
>
|
|
7
7
|
<slot name="top-header" />
|
|
8
|
+
|
|
8
9
|
<!-- Main header wrapper -->
|
|
9
10
|
<div
|
|
10
11
|
:class="[
|
|
12
|
+
'w-full',
|
|
11
13
|
'flex',
|
|
12
14
|
'items-center',
|
|
13
15
|
'justify-between',
|
|
14
16
|
'gap-3',
|
|
17
|
+
'mx-auto',
|
|
15
18
|
'px-content-side-padding-mobile md:px-content-side-padding',
|
|
16
19
|
'py-4',
|
|
17
20
|
'bg-background-surface',
|
|
18
|
-
hasBorder && 'border-b border-border-default',
|
|
19
|
-
isSticky && 'sticky top-0 z-50',
|
|
20
21
|
hasGlassEffect && [
|
|
21
22
|
'backdrop-blur-md',
|
|
22
23
|
'bg-background-surface/30 dark:bg-background-surface/85',
|
|
23
24
|
],
|
|
24
|
-
|
|
25
|
+
hasBorder && 'border-b border-border-default',
|
|
26
|
+
innerContainerClass,
|
|
25
27
|
]"
|
|
26
28
|
>
|
|
27
29
|
<!-- Logo -->
|
|
28
30
|
<div class="flex gap-4">
|
|
31
|
+
<template
|
|
32
|
+
v-if="
|
|
33
|
+
showMobileSidebarToggle
|
|
34
|
+
&& sidebarTogglePosition === SidebarTogglePosition.LOGO_LEFT_SIDE
|
|
35
|
+
"
|
|
36
|
+
>
|
|
37
|
+
<ActionIconButton
|
|
38
|
+
:icon="isMobileSidebarOpen ? 'mdiMenuOpen' : 'mdiMenuClose'"
|
|
39
|
+
class="lg:hidden shadow-sm"
|
|
40
|
+
@click="toggleMobileSidebar"
|
|
41
|
+
/>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
29
44
|
<slot name="header-logo" />
|
|
45
|
+
|
|
46
|
+
<template
|
|
47
|
+
v-if="
|
|
48
|
+
showMobileSidebarToggle
|
|
49
|
+
&& sidebarTogglePosition === SidebarTogglePosition.LOGO_RIGHT_SIDE
|
|
50
|
+
"
|
|
51
|
+
>
|
|
52
|
+
<ActionIconButton
|
|
53
|
+
:icon="isMobileSidebarOpen ? 'mdiMenuOpen' : 'mdiMenuClose'"
|
|
54
|
+
class="lg:hidden shadow-sm"
|
|
55
|
+
@click="toggleMobileSidebar"
|
|
56
|
+
/>
|
|
57
|
+
</template>
|
|
30
58
|
</div>
|
|
31
59
|
|
|
32
60
|
<!-- Navigation -->
|
|
@@ -51,6 +79,7 @@
|
|
|
51
79
|
<DropdownMenu
|
|
52
80
|
v-if="userMenuItems.length && userFullname"
|
|
53
81
|
class="min-w-[200px]"
|
|
82
|
+
:positionYOffset="8"
|
|
54
83
|
>
|
|
55
84
|
<template #activator="{ onClick }">
|
|
56
85
|
<Avatar
|
|
@@ -78,8 +107,11 @@
|
|
|
78
107
|
</DropdownMenu>
|
|
79
108
|
|
|
80
109
|
<!-- Mobile menu -->
|
|
81
|
-
<template v-if="isMobile &&
|
|
82
|
-
<DropdownMenu
|
|
110
|
+
<template v-if="isMobile && showMobileMenuToggle">
|
|
111
|
+
<DropdownMenu
|
|
112
|
+
:class="navMobileMenuClass"
|
|
113
|
+
:positionYOffset="8"
|
|
114
|
+
>
|
|
83
115
|
<template #activator="{ onClick }">
|
|
84
116
|
<ActionIconButton
|
|
85
117
|
icon="mdiMenu"
|
|
@@ -101,7 +133,12 @@
|
|
|
101
133
|
</DropdownMenu>
|
|
102
134
|
</template>
|
|
103
135
|
|
|
104
|
-
<template
|
|
136
|
+
<template
|
|
137
|
+
v-else-if="
|
|
138
|
+
showMobileSidebarToggle
|
|
139
|
+
&& sidebarTogglePosition === SidebarTogglePosition.RIGHT_SIDE
|
|
140
|
+
"
|
|
141
|
+
>
|
|
105
142
|
<ActionIconButton
|
|
106
143
|
:icon="isMobileSidebarOpen ? 'mdiMenuOpen' : 'mdiMenuClose'"
|
|
107
144
|
class="lg:hidden shadow-sm"
|
|
@@ -132,10 +169,18 @@ defineProps({
|
|
|
132
169
|
type: Array as PropType<DropdownMenuItem[]>,
|
|
133
170
|
default: () => [],
|
|
134
171
|
},
|
|
135
|
-
|
|
136
|
-
type:
|
|
137
|
-
default:
|
|
138
|
-
|
|
172
|
+
showMobileMenuToggle: {
|
|
173
|
+
type: Boolean as PropType<boolean>,
|
|
174
|
+
default: true,
|
|
175
|
+
},
|
|
176
|
+
showMobileSidebarToggle: {
|
|
177
|
+
type: Boolean as PropType<boolean>,
|
|
178
|
+
default: true,
|
|
179
|
+
},
|
|
180
|
+
sidebarTogglePosition: {
|
|
181
|
+
type: String as PropType<SidebarTogglePosition>,
|
|
182
|
+
default: SidebarTogglePosition.RIGHT_SIDE,
|
|
183
|
+
validator: (value: SidebarTogglePosition) => Object.values(SidebarTogglePosition).includes(value),
|
|
139
184
|
},
|
|
140
185
|
hasBorder: {
|
|
141
186
|
type: Boolean as PropType<boolean>,
|
|
@@ -161,7 +206,7 @@ defineProps({
|
|
|
161
206
|
type: String as PropType<string>,
|
|
162
207
|
default: 'lg:hidden min-w-[280px]'
|
|
163
208
|
},
|
|
164
|
-
|
|
209
|
+
innerContainerClass: String as PropType<string>,
|
|
165
210
|
})
|
|
166
211
|
|
|
167
212
|
// Composables
|
|
@@ -54,37 +54,36 @@ const props = defineProps({
|
|
|
54
54
|
const spacingClass = computed(() => {
|
|
55
55
|
const variant = {
|
|
56
56
|
[SectionSpacing.NONE]: 'py-0',
|
|
57
|
-
[SectionSpacing.XS]: 'py-section-xs',
|
|
58
|
-
[SectionSpacing.SM]: 'py-section-sm',
|
|
59
|
-
[SectionSpacing.MD]: 'py-section-md',
|
|
60
|
-
[SectionSpacing.LG]: 'py-section-lg',
|
|
61
|
-
[SectionSpacing.XL]: 'py-section-xl',
|
|
57
|
+
[SectionSpacing.XS]: 'py-[2vh] sm:py-section-xs lg:py-section-xs',
|
|
58
|
+
[SectionSpacing.SM]: 'py-[4vh] sm:py-section-sm lg:py-section-sm',
|
|
59
|
+
[SectionSpacing.MD]: 'py-[6vh] sm:py-section-md lg:py-section-md',
|
|
60
|
+
[SectionSpacing.LG]: 'py-[8vh] sm:py-section-lg lg:py-section-lg',
|
|
61
|
+
[SectionSpacing.XL]: 'py-[10vh] sm:py-section-xl lg:py-section-xl',
|
|
62
62
|
}
|
|
63
|
-
return variant[props.spacing as SectionSpacing] ||
|
|
63
|
+
return variant[props.spacing as SectionSpacing] || variant[SectionSpacing.XS]
|
|
64
64
|
})
|
|
65
65
|
|
|
66
66
|
const topSpacingClass = computed(() => {
|
|
67
67
|
const variant = {
|
|
68
|
-
[SectionSpacing.NONE]: '
|
|
69
|
-
[SectionSpacing.XS]: 'pt-section-xs',
|
|
70
|
-
[SectionSpacing.SM]: 'pt-section-sm',
|
|
71
|
-
[SectionSpacing.MD]: 'pt-section-md',
|
|
72
|
-
[SectionSpacing.LG]: 'pt-section-lg',
|
|
73
|
-
[SectionSpacing.XL]: 'pt-section-xl',
|
|
68
|
+
[SectionSpacing.NONE]: 'pt-0',
|
|
69
|
+
[SectionSpacing.XS]: 'pt-[2vh] sm:pt-section-xs lg:pt-section-xs',
|
|
70
|
+
[SectionSpacing.SM]: 'pt-[4vh] sm:pt-section-sm lg:pt-section-sm',
|
|
71
|
+
[SectionSpacing.MD]: 'pt-[6vh] sm:pt-section-md lg:pt-section-md',
|
|
72
|
+
[SectionSpacing.LG]: 'pt-[8vh] sm:pt-section-lg lg:pt-section-lg',
|
|
73
|
+
[SectionSpacing.XL]: 'pt-[10vh] sm:pt-section-xl lg:pt-section-xl',
|
|
74
74
|
}
|
|
75
|
-
return variant[props.topSpacing as SectionSpacing]
|
|
75
|
+
return variant[props.topSpacing as SectionSpacing]
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
const bottomSpacingClass = computed(() => {
|
|
79
79
|
const variant = {
|
|
80
80
|
[SectionSpacing.NONE]: '!pb-0',
|
|
81
|
-
[SectionSpacing.XS]: '
|
|
82
|
-
[SectionSpacing.SM]: '
|
|
83
|
-
[SectionSpacing.MD]: '
|
|
84
|
-
[SectionSpacing.LG]: 'pb-section-lg',
|
|
85
|
-
[SectionSpacing.XL]: 'pb-section-xl',
|
|
81
|
+
[SectionSpacing.XS]: 'pb-[2vh] sm:!pb-section-xs lg:!pb-section-xs',
|
|
82
|
+
[SectionSpacing.SM]: 'pb-[4vh] sm:!pb-section-sm lg:!pb-section-sm',
|
|
83
|
+
[SectionSpacing.MD]: 'pb-[6vh] sm:!pb-section-md lg:!pb-section-md',
|
|
84
|
+
[SectionSpacing.LG]: 'pb-[8vh] sm:pb-section-lg lg:pb-section-lg',
|
|
85
|
+
[SectionSpacing.XL]: 'pb-[10vh] sm:pb-section-xl lg:pb-section-xl',
|
|
86
86
|
}
|
|
87
|
-
return variant[props.bottomSpacing as SectionSpacing]
|
|
87
|
+
return variant[props.bottomSpacing as SectionSpacing]
|
|
88
88
|
})
|
|
89
|
-
|
|
90
89
|
</script>
|
|
@@ -14,6 +14,12 @@ export enum DropdownPosition {
|
|
|
14
14
|
BOTTOM_RIGHT = 'bottom-right',
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
export enum SidebarTogglePosition {
|
|
18
|
+
RIGHT_SIDE = 'right-side',
|
|
19
|
+
LOGO_LEFT_SIDE = 'logo-left-side',
|
|
20
|
+
LOGO_RIGHT_SIDE = 'logo-right-side',
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
export enum Align {
|
|
18
24
|
LEFT = 'left',
|
|
19
25
|
CENTER = 'center',
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imaginario27/air-ui-ds",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"author": "imaginario27",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"homepage": "https://air-ui.netlify.app/",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
8
9
|
"url": "git+https://github.com/imaginario27/air-ui.git"
|
|
@@ -17,10 +18,7 @@
|
|
|
17
18
|
"preview": "nuxt preview",
|
|
18
19
|
"postinstall": "nuxt prepare",
|
|
19
20
|
"test": "vitest",
|
|
20
|
-
"generate-theme": "ts-node scripts/generate-theme.ts"
|
|
21
|
-
"publish:patch": "npm version patch --no-git-tag-version && npm publish",
|
|
22
|
-
"publish:minor": "npm version minor --no-git-tag-version && npm publish",
|
|
23
|
-
"publish:major": "npm version major --no-git-tag-version && npm publish"
|
|
21
|
+
"generate-theme": "ts-node scripts/generate-theme.ts"
|
|
24
22
|
},
|
|
25
23
|
"dependencies": {
|
|
26
24
|
"@jaxtheprime/vue3-dropzone": "^3.4.0",
|