windly-ui 1.0.1 → 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.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -33
  3. package/package.json +47 -15
  4. package/ui-library/dist/module.d.mts +3 -0
  5. package/ui-library/dist/module.json +8 -0
  6. package/ui-library/dist/module.mjs +22 -0
  7. package/ui-library/dist/types.d.mts +7 -0
  8. package/ui-library/components/Accordion.vue +0 -118
  9. package/ui-library/components/Avatar.vue +0 -121
  10. package/ui-library/components/Badge.vue +0 -116
  11. package/ui-library/components/Breadcrumbs.vue +0 -138
  12. package/ui-library/components/Button.vue +0 -154
  13. package/ui-library/components/Card.vue +0 -84
  14. package/ui-library/components/Checkbox.vue +0 -148
  15. package/ui-library/components/CodeBlock.vue +0 -99
  16. package/ui-library/components/ColorPicker.vue +0 -302
  17. package/ui-library/components/Date.vue +0 -240
  18. package/ui-library/components/Dialog.vue +0 -187
  19. package/ui-library/components/Divider.vue +0 -78
  20. package/ui-library/components/Drawer.vue +0 -67
  21. package/ui-library/components/Dropdown.vue +0 -248
  22. package/ui-library/components/FileUploader.vue +0 -330
  23. package/ui-library/components/Icon.vue +0 -82
  24. package/ui-library/components/Image.vue +0 -78
  25. package/ui-library/components/Input.vue +0 -531
  26. package/ui-library/components/Radio.vue +0 -356
  27. package/ui-library/components/ScrollArea.vue +0 -43
  28. package/ui-library/components/Select.vue +0 -309
  29. package/ui-library/components/Stepper.vue +0 -361
  30. package/ui-library/components/TabPanel.vue +0 -25
  31. package/ui-library/components/Table.vue +0 -152
  32. package/ui-library/components/Tabs.vue +0 -71
  33. package/ui-library/components/Textarea.vue +0 -233
  34. package/ui-library/components/Toggle.vue +0 -319
  35. package/ui-library/components/Tooltip.vue +0 -200
  36. package/ui-library/components/plugin.ts +0 -8
  37. package/ui-library/components/uiProps.ts +0 -11
  38. package/ui-library/components/useUiClasses.ts +0 -159
  39. package/ui-library/module.ts +0 -20
@@ -1,200 +0,0 @@
1
- <script setup lang="ts">
2
- defineOptions({
3
- name: 'UITooltip',
4
- inheritAttrs: false,
5
- })
6
-
7
- import { computed, ref } from 'vue'
8
-
9
- type TooltipPlacement =
10
- | 'top'
11
- | 'right'
12
- | 'bottom'
13
- | 'left'
14
-
15
- const props = defineProps({
16
- text: {
17
- type: String,
18
- required: true,
19
- },
20
- placement: {
21
- type: String as () => TooltipPlacement,
22
- default: 'top',
23
-
24
- validator: (v: string) =>
25
- ['top', 'right', 'bottom', 'left'].includes(v),
26
- },
27
- arrow: {
28
- type: Boolean,
29
- default: true,
30
- },
31
- color: {
32
- type: String,
33
- default: 'gray-800',
34
- },
35
- textColor: {
36
- type: String,
37
- default: 'white',
38
- },
39
- })
40
-
41
- const baseClasses = computed(() => ('px-3 py-2 text-sm rounded-lg shadow-lg whitespace-nowrap'))
42
-
43
- const visible = ref(false)
44
-
45
- const isHex = (val: string) => val.startsWith('#')
46
-
47
- const showTooltip = () => {
48
- visible.value = true
49
- }
50
-
51
- const hideTooltip = () => {
52
- visible.value = false
53
- }
54
-
55
- const tooltipStyle = computed(() => {
56
- const style: Record<string, string> = {}
57
-
58
- if (isHex(props.color)) {
59
- style.backgroundColor = props.color
60
- }
61
-
62
- if (isHex(props.textColor)) {
63
- style.color = props.textColor
64
- }
65
-
66
- return style
67
- })
68
-
69
- const tooltipClasses = computed(() => [
70
- baseClasses.value,
71
-
72
- !isHex(props.color)
73
- ? `bg-${props.color}`
74
- : '',
75
-
76
- !isHex(props.textColor)
77
- ? `text-${props.textColor}`
78
- : '',
79
- ])
80
-
81
- const placementClasses = computed(() => {
82
- switch (props.placement) {
83
- case 'top':
84
- return 'bottom-full left-1/2 -translate-x-1/2 mb-3'
85
-
86
- case 'right':
87
- return 'left-full top-1/2 -translate-y-1/2 ml-3'
88
-
89
- case 'bottom':
90
- return 'top-full left-1/2 -translate-x-1/2 mt-3'
91
-
92
- case 'left':
93
- return 'right-full top-1/2 -translate-y-1/2 mr-3'
94
-
95
- default:
96
- return ''
97
- }
98
- })
99
-
100
- const arrowClasses = computed(() => {
101
- switch (props.placement) {
102
- case 'top':
103
- return 'left-1/2 -translate-x-1/2 bottom-0 -mb-3.5'
104
-
105
- case 'right':
106
- return 'top-1/2 -translate-y-1/2 left-0 -ml-3.5'
107
-
108
- case 'bottom':
109
- return 'left-1/2 -translate-x-1/2 top-0 -mt-3.5'
110
-
111
- case 'left':
112
- return 'top-1/2 -translate-y-1/2 right-0 -mr-3.5'
113
-
114
- default:
115
- return ''
116
- }
117
- })
118
-
119
- const arrowIcon = computed(() => {
120
- switch (props.placement) {
121
- case 'top':
122
- return 'arrow_drop_down'
123
-
124
- case 'right':
125
- return 'arrow_left'
126
-
127
- case 'bottom':
128
- return 'arrow_drop_up'
129
-
130
- case 'left':
131
- return 'arrow_right'
132
-
133
- default:
134
- return ''
135
- }
136
- })
137
-
138
- const arrowStyle = computed(() => {
139
- const style: Record<string, string> = {}
140
- if (isHex(props.color))
141
- style.color = props.color
142
- return style
143
- })
144
- </script>
145
-
146
- <template>
147
- <div
148
- class="relative inline-block"
149
- tabindex="0"
150
- @mouseenter="showTooltip"
151
- @mouseleave="hideTooltip"
152
- @focus="showTooltip"
153
- @blur="hideTooltip"
154
- >
155
- <!-- Trigger -->
156
- <slot />
157
-
158
- <!-- Tooltip -->
159
- <transition name="fade">
160
- <div
161
- v-if="visible"
162
- role="tooltip"
163
- class="absolute z-50"
164
- :class="[tooltipClasses, placementClasses]"
165
- :style="tooltipStyle"
166
- v-bind="$attrs"
167
- >
168
- <!-- Arrow -->
169
- <i
170
- v-if="arrow"
171
- class="material-icons tooltip-arrow"
172
- :class="[ arrowClasses, !isHex(props.color) ? `text-${props.color}` : '', ]"
173
- :style="arrowStyle"
174
- >
175
- {{ arrowIcon }}
176
- </i>
177
-
178
- {{ text }}
179
- </div>
180
- </transition>
181
- </div>
182
- </template>
183
-
184
- <style scoped>
185
- .fade-enter-active,
186
- .fade-leave-active {
187
- transition: opacity 0.2s ease;
188
- }
189
-
190
- .fade-enter-from,
191
- .fade-leave-to {
192
- opacity: 0;
193
- }
194
-
195
- .tooltip-arrow {
196
- position: absolute;
197
- font-size: 1.5rem;
198
- line-height: 1;
199
- }
200
- </style>
@@ -1,8 +0,0 @@
1
- import { defineNuxtPlugin } from '#app'
2
- import Button from './Button.vue'
3
- import Accordian from './Accordion.vue'
4
-
5
- export default defineNuxtPlugin((nuxtApp) => {
6
- nuxtApp.vueApp.component('UIButton', Button)
7
- nuxtApp.vueApp.component('UIAccordian', Accordian)
8
- })
@@ -1,11 +0,0 @@
1
- export const uiProps = {
2
- contentClass: { type: String, default: "" },
3
- contentStyle: { type: String, default: "" },
4
- textColor: { type: String, default: "" },
5
- disable: { type: Boolean, default: false },
6
- loading: { type: Boolean, default: false },
7
- color: { type: String, default: "blue-900" },
8
- rounded: { type: String, default: "md" },
9
- size: { type: String, default: "md" },
10
- iconSize: { type: String, default: "lg" },
11
- } as const;
@@ -1,159 +0,0 @@
1
- import { computed, toRefs } from "vue";
2
- import type { ExtractPropTypes } from "vue";
3
- import { uiProps } from "./uiProps";
4
-
5
- type UiProps = ExtractPropTypes<typeof uiProps>;
6
-
7
- export function useUiClasses(props: Partial<UiProps>) {
8
- const safeProps = {
9
- contentClass: "",
10
- contentStyle: "",
11
- textColor: "",
12
- disable: false,
13
- loading: false,
14
- color: "",
15
- rounded: "md",
16
- size: "md",
17
- iconSize: "md",
18
- ...props,
19
- };
20
-
21
- const {
22
- contentClass,
23
- contentStyle,
24
- textColor,
25
- disable,
26
- loading,
27
- color,
28
- rounded,
29
- size,
30
- iconSize,
31
- } = toRefs(safeProps);
32
-
33
- // Classes maps
34
- const roundedClass = {
35
- none: "rounded-none",
36
- xs: "rounded-xs",
37
- sm: "rounded-sm",
38
- md: "rounded",
39
- lg: "rounded-lg",
40
- xl: "rounded-xl",
41
- full: "rounded-full",
42
- };
43
-
44
- const sizeClass = {
45
- sm: "text-xs",
46
- md: "text-base",
47
- lg: "text-xl",
48
- };
49
-
50
- const iconSizeClasses = {
51
- xs: "text-xs",
52
- sm: "text-sm",
53
- md: "text-base",
54
- lg: "text-lg",
55
- xl: "text-xl",
56
- };
57
-
58
- // Computed for color class
59
- const colorClass = computed(() => {
60
- if (!color.value) return "";
61
- return color.value.includes("#") ? `[${color.value}]` : color.value;
62
- });
63
-
64
- // Computed for content class with ! prefix
65
- const computedContentClass = computed(() => {
66
- if (!contentClass.value) return "";
67
- return contentClass.value
68
- .split(" ")
69
- .map((cls: string) => (cls.startsWith("!") ? cls : `!${cls}`))
70
- .join(" ");
71
- });
72
-
73
- function isTailwindColorDark(color: string): boolean {
74
- const match = color.match(/-(\d{2,3})$/);
75
- if (!match) return false;
76
- return Number(match[1]) >= 400;
77
- }
78
-
79
- function isHexColorDark(hex: string): boolean {
80
- let c = hex.replace("#", "");
81
-
82
- if (c.length === 3) {
83
- c = c.split("").map(x => x + x).join("");
84
- }
85
-
86
- const r = parseInt(c.substring(0, 2), 16);
87
- const g = parseInt(c.substring(2, 4), 16);
88
- const b = parseInt(c.substring(4, 6), 16);
89
-
90
- const luminance = 0.299 * r + 0.587 * g + 0.114 * b;
91
- return luminance < 140;
92
- }
93
-
94
- function isHex(color: string) {
95
- return /^#([0-9A-F]{3}){1,2}$/i.test(color);
96
- }
97
-
98
- function isTailwindColor(color: string) {
99
- return /^[a-z]+-\d{2,3}$/.test(color);
100
- }
101
-
102
- const isColorDark = (color: string): boolean => {
103
- if (!color) return false;
104
- return color.startsWith("#")
105
- ? isHexColorDark(color)
106
- : isTailwindColorDark(color);
107
- };
108
-
109
- function shadeTailwind(color: string, delta = 100) {
110
- const [name, shade] = color.split("-");
111
- const nextShade = Math.min(900, Math.max(100, Number(shade) + delta));
112
- return `${name}-${nextShade}`;
113
- }
114
-
115
- function shadeHex(hex: string, amount = -10) {
116
- let c = hex.substring(1);
117
- if (c.length === 3) {
118
- c = c.split("").map(x => x + x).join("");
119
- }
120
-
121
- const num = parseInt(c, 16);
122
- let r = (num >> 16) & 255;
123
- let g = (num >> 8) & 255;
124
- let b = num & 255;
125
-
126
- r = Math.min(255, Math.max(0, r + amount));
127
- g = Math.min(255, Math.max(0, g + amount));
128
- b = Math.min(255, Math.max(0, b + amount));
129
-
130
- return `#${((1 << 24) + (r << 16) + (g << 8) + b)
131
- .toString(16)
132
- .slice(1)}`;
133
- }
134
-
135
- return {
136
- // props
137
- contentClass,
138
- contentStyle,
139
- textColor,
140
- disable,
141
- loading,
142
- color,
143
- rounded,
144
- size,
145
- iconSize,
146
- // class maps
147
- roundedClass,
148
- sizeClass,
149
- iconSizeClasses,
150
- // computed
151
- colorClass,
152
- computedContentClass,
153
- isColorDark,
154
- isHex,
155
- isTailwindColor,
156
- shadeTailwind,
157
- shadeHex
158
- };
159
- }
@@ -1,20 +0,0 @@
1
- import { defineNuxtModule, addComponentsDir, createResolver } from '@nuxt/kit'
2
-
3
- export default defineNuxtModule({
4
- meta: {
5
- name: 'ui-library',
6
- configKey: 'uiLibrary'
7
- },
8
- setup(_, nuxt) {
9
- const resolver = createResolver(import.meta.url)
10
-
11
- // Auto-register all components from the ui-library/components folder
12
- addComponentsDir({
13
- path: resolver.resolve('./components'),
14
- prefix: 'UI', // This will prefix components with <UIButton />, <UICard /> etc.
15
- pathPrefix: false, // Don't include folder names as prefix
16
- extensions: ['vue'],
17
- watch: nuxt.options.dev
18
- })
19
- }
20
- })