windly-ui 1.0.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 +208 -0
- package/app/app.vue +10 -0
- package/app/assets/css/tailwind.css +3 -0
- package/app/components/doc/component.vue +34 -0
- package/app/components/doc/megaSection.vue +56 -0
- package/app/components/doc/section.vue +56 -0
- package/app/pages/_docs.vue +2420 -0
- package/app/pages/index.vue +137 -0
- package/nuxt.config.ts +19 -0
- package/package.json +21 -0
- package/public/doc/avatar.avif +0 -0
- package/public/favicon.ico +0 -0
- package/public/robots.txt +2 -0
- package/tailwind.config.ts +28 -0
- package/tsconfig.json +18 -0
- package/ui-library/components/Accordion.vue +118 -0
- package/ui-library/components/Avatar.vue +121 -0
- package/ui-library/components/Badge.vue +116 -0
- package/ui-library/components/Breadcrumbs.vue +138 -0
- package/ui-library/components/Button.vue +154 -0
- package/ui-library/components/Card.vue +84 -0
- package/ui-library/components/Checkbox.vue +148 -0
- package/ui-library/components/CodeBlock.vue +99 -0
- package/ui-library/components/ColorPicker.vue +302 -0
- package/ui-library/components/Date.vue +240 -0
- package/ui-library/components/Dialog.vue +187 -0
- package/ui-library/components/Divider.vue +78 -0
- package/ui-library/components/Drawer.vue +67 -0
- package/ui-library/components/Dropdown.vue +248 -0
- package/ui-library/components/FileUploader.vue +330 -0
- package/ui-library/components/Icon.vue +82 -0
- package/ui-library/components/Image.vue +78 -0
- package/ui-library/components/Input.vue +531 -0
- package/ui-library/components/Radio.vue +356 -0
- package/ui-library/components/ScrollArea.vue +43 -0
- package/ui-library/components/Select.vue +309 -0
- package/ui-library/components/Stepper.vue +361 -0
- package/ui-library/components/TabPanel.vue +25 -0
- package/ui-library/components/Table.vue +152 -0
- package/ui-library/components/Tabs.vue +71 -0
- package/ui-library/components/Textarea.vue +233 -0
- package/ui-library/components/Toggle.vue +319 -0
- package/ui-library/components/Tooltip.vue +200 -0
- package/ui-library/components/plugin.ts +8 -0
- package/ui-library/components/uiProps.ts +11 -0
- package/ui-library/components/useUiClasses.ts +159 -0
- package/ui-library/module.ts +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Tailwind-Based UI Library for Nuxt 4
|
|
2
|
+
|
|
3
|
+
A lightweight, modular UI component library built specifically for Nuxt 4 applications, powered by Tailwind CSS.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This UI library is designed to accelerate frontend development by providing reusable, customizable, and auto-imported components. It focuses on simplicity, flexibility, and a smooth developer experience while staying fully aligned with Tailwind CSS principles.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Key Features
|
|
14
|
+
|
|
15
|
+
### Tailwind-First Design
|
|
16
|
+
|
|
17
|
+
All components accept Tailwind utility classes directly via:
|
|
18
|
+
|
|
19
|
+
* `class`
|
|
20
|
+
* `:class`
|
|
21
|
+
|
|
22
|
+
This gives full control over styling without requiring overrides or complex theming systems.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
### Auto Import (Nuxt 4 Native)
|
|
27
|
+
|
|
28
|
+
Components are automatically available across your application.
|
|
29
|
+
|
|
30
|
+
Example:
|
|
31
|
+
|
|
32
|
+
```vue
|
|
33
|
+
<UIButton label="Click Me" />
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### Fully Reactive Components
|
|
39
|
+
|
|
40
|
+
Built using the Vue 3 Composition API:
|
|
41
|
+
|
|
42
|
+
* `ref`
|
|
43
|
+
* `computed`
|
|
44
|
+
* `watch`
|
|
45
|
+
* `provide / inject`
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
### Consistent API Design
|
|
50
|
+
|
|
51
|
+
All components follow predictable and consistent patterns:
|
|
52
|
+
|
|
53
|
+
* `v-model` support where applicable
|
|
54
|
+
* Props for variants such as color, size, and state
|
|
55
|
+
* Slots for flexible customization
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Component Categories
|
|
60
|
+
|
|
61
|
+
### Form Controls
|
|
62
|
+
|
|
63
|
+
* UIInput
|
|
64
|
+
* UITextarea
|
|
65
|
+
* UIButton
|
|
66
|
+
* UIToggle
|
|
67
|
+
* UICheckbox
|
|
68
|
+
* UIRadio
|
|
69
|
+
* UIDropdown
|
|
70
|
+
* UIChip
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### Navigation
|
|
75
|
+
|
|
76
|
+
* UIBreadcrumbs
|
|
77
|
+
* UITabs + UITabPanel
|
|
78
|
+
* UIAccordion
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### Feedback and Popups
|
|
83
|
+
|
|
84
|
+
* UITooltip
|
|
85
|
+
* UIDialog
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### Data Display
|
|
90
|
+
|
|
91
|
+
* UICard
|
|
92
|
+
* UIAvatar
|
|
93
|
+
* UIBadge
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### Planned Components
|
|
98
|
+
|
|
99
|
+
* UIList
|
|
100
|
+
* UITable
|
|
101
|
+
* UIScrollArea
|
|
102
|
+
* UIImage
|
|
103
|
+
* UIIcon
|
|
104
|
+
* UIDivider
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Design Philosophy
|
|
109
|
+
|
|
110
|
+
### Minimal but Powerful
|
|
111
|
+
|
|
112
|
+
Components are intentionally lightweight while still supporting complex use cases through composition.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### Developer Control First
|
|
117
|
+
|
|
118
|
+
There is no rigid styling system. Tailwind utilities are used directly for full flexibility.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### Composition over Configuration
|
|
123
|
+
|
|
124
|
+
Instead of relying on large sets of props, the library encourages:
|
|
125
|
+
|
|
126
|
+
* Slots
|
|
127
|
+
* Composition patterns
|
|
128
|
+
* Vue reactivity
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
### Framework-Native Experience
|
|
133
|
+
|
|
134
|
+
Built specifically for:
|
|
135
|
+
|
|
136
|
+
* Nuxt 4
|
|
137
|
+
* Vue 3
|
|
138
|
+
|
|
139
|
+
No unnecessary abstractions or overhead.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Example Usage
|
|
144
|
+
|
|
145
|
+
```vue
|
|
146
|
+
<template>
|
|
147
|
+
<UICard bordered>
|
|
148
|
+
<template #header>
|
|
149
|
+
<h3 class="text-lg font-semibold">Welcome</h3>
|
|
150
|
+
</template>
|
|
151
|
+
|
|
152
|
+
<p>This is a simple card using the UI library.</p>
|
|
153
|
+
|
|
154
|
+
<template #footer>
|
|
155
|
+
<UIButton label="Action" />
|
|
156
|
+
</template>
|
|
157
|
+
</UICard>
|
|
158
|
+
</template>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Advanced Example
|
|
164
|
+
|
|
165
|
+
```vue
|
|
166
|
+
<UITabs v-model="activeTab">
|
|
167
|
+
<UITabPanel name="first" label="Overview">
|
|
168
|
+
<p>Overview content</p>
|
|
169
|
+
</UITabPanel>
|
|
170
|
+
|
|
171
|
+
<UITabPanel name="second" label="Details">
|
|
172
|
+
<p>Details content</p>
|
|
173
|
+
</UITabPanel>
|
|
174
|
+
</UITabs>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Goals
|
|
180
|
+
|
|
181
|
+
* Provide a clean alternative to heavy UI frameworks
|
|
182
|
+
* Showcase advanced Vue patterns in a simple way
|
|
183
|
+
* Enable rapid prototyping with Tailwind
|
|
184
|
+
* Keep the system small, composable, and extensible
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Future Improvements
|
|
189
|
+
|
|
190
|
+
* Theme system (dark mode, tokens)
|
|
191
|
+
* Component playground with live prop editing
|
|
192
|
+
* Accessibility improvements (ARIA support)
|
|
193
|
+
* Animation utilities
|
|
194
|
+
* Plugin system for extending components
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Summary
|
|
199
|
+
|
|
200
|
+
This UI library is a developer-focused toolkit for building modern Nuxt applications quickly without sacrificing flexibility or control.
|
|
201
|
+
|
|
202
|
+
It combines:
|
|
203
|
+
|
|
204
|
+
* Vue 3 reactivity
|
|
205
|
+
* Tailwind CSS flexibility
|
|
206
|
+
* Clean and consistent component design
|
|
207
|
+
|
|
208
|
+
Build fast, customize freely, and stay in control.
|
package/app/app.vue
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
title: {
|
|
4
|
+
type: String
|
|
5
|
+
},
|
|
6
|
+
caption: {
|
|
7
|
+
type: String,
|
|
8
|
+
default: ""
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
const sectionId = props.title.split(' ').join('-').toLocaleLowerCase()
|
|
12
|
+
const copySectionLink = async () => {
|
|
13
|
+
const url = `${window.location.origin}${window.location.pathname}#${sectionId}`
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
await navigator.clipboard.writeText(url)
|
|
17
|
+
console.log('Link copied:', url)
|
|
18
|
+
} catch (err) {
|
|
19
|
+
console.error('Failed to copy link', err)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
23
|
+
<template>
|
|
24
|
+
<div :id="sectionId" class="flex flex-col my-10">
|
|
25
|
+
<h4 class="text-3xl font-semibold text-gray-700 cursor-pointer" @click="copySectionLink"># {{title}}</h4>
|
|
26
|
+
<div v-if="caption" class="text-md font-light mt-2 text-gray-800 pl-7">{{caption}}</div>
|
|
27
|
+
<div class="my-6">
|
|
28
|
+
<UICodeBlock :title="title">
|
|
29
|
+
<slot />
|
|
30
|
+
</UICodeBlock>
|
|
31
|
+
</div>
|
|
32
|
+
<hr/>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
title: {
|
|
6
|
+
type: String,
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
subTitle: {
|
|
10
|
+
type: String,
|
|
11
|
+
default: ""
|
|
12
|
+
},
|
|
13
|
+
caption: {
|
|
14
|
+
type: String,
|
|
15
|
+
default: ""
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const sectionId = computed(() =>
|
|
20
|
+
props.title.split(' ').join('-').toLowerCase()
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const copySectionLink = async (e) => {
|
|
24
|
+
e.stopPropagation()
|
|
25
|
+
|
|
26
|
+
const url = `${window.location.origin}${window.location.pathname}#${sectionId.value}`
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
await navigator.clipboard.writeText(url)
|
|
30
|
+
console.log('Link copied:', url)
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error('Failed to copy link', err)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
<template>
|
|
37
|
+
<section :id="sectionId">
|
|
38
|
+
<div class="flex flex-col my-10">
|
|
39
|
+
<UIAccordion class="!border-0" :default-open="true" :margin="false">
|
|
40
|
+
<template #header>
|
|
41
|
+
<h3 class="flex items-center gap-2 text-5xl font-semibold text-sky-500 group select-none">
|
|
42
|
+
{{ title }}
|
|
43
|
+
<span class="hidden group-hover:block text-xl hover:opacity-100" @click="copySectionLink">
|
|
44
|
+
#
|
|
45
|
+
</span>
|
|
46
|
+
</h3>
|
|
47
|
+
<div class="font-light text-gray-700">{{ subTitle }}</div>
|
|
48
|
+
</template>
|
|
49
|
+
<p v-if="caption" class="text-md font-light mt-2 text-gray-800 pl-7">
|
|
50
|
+
{{ caption }}
|
|
51
|
+
</p>
|
|
52
|
+
<slot />
|
|
53
|
+
</UIAccordion>
|
|
54
|
+
</div>
|
|
55
|
+
</section>
|
|
56
|
+
</template>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
title: {
|
|
6
|
+
type: String,
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
subTitle: {
|
|
10
|
+
type: String,
|
|
11
|
+
default: ""
|
|
12
|
+
},
|
|
13
|
+
caption: {
|
|
14
|
+
type: String,
|
|
15
|
+
default: ""
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const sectionId = computed(() =>
|
|
20
|
+
props.title.split(' ').join('-').toLowerCase()
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const copySectionLink = async (e) => {
|
|
24
|
+
e.stopPropagation()
|
|
25
|
+
|
|
26
|
+
const url = `${window.location.origin}${window.location.pathname}#${sectionId.value}`
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
await navigator.clipboard.writeText(url)
|
|
30
|
+
console.log('Link copied:', url)
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error('Failed to copy link', err)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
<template>
|
|
37
|
+
<section :id="sectionId">
|
|
38
|
+
<div class="flex flex-col my-10">
|
|
39
|
+
<UIAccordion :default-open="true">
|
|
40
|
+
<template #header>
|
|
41
|
+
<h3 class="flex items-center gap-2 text-5xl font-semibold text-sky-500 group select-none">
|
|
42
|
+
{{ title }}
|
|
43
|
+
<span class="hidden group-hover:block text-xl hover:opacity-100" @click="copySectionLink">
|
|
44
|
+
#
|
|
45
|
+
</span>
|
|
46
|
+
</h3>
|
|
47
|
+
<div class="font-light text-gray-700">{{ subTitle }}</div>
|
|
48
|
+
</template>
|
|
49
|
+
<p v-if="caption" class="text-md font-light mt-2 text-gray-800 pl-7">
|
|
50
|
+
{{ caption }}
|
|
51
|
+
</p>
|
|
52
|
+
<slot />
|
|
53
|
+
</UIAccordion>
|
|
54
|
+
</div>
|
|
55
|
+
</section>
|
|
56
|
+
</template>
|