vueless 1.3.5-beta.2 → 1.3.5
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/composables/useBreakpoint.ts +97 -42
- package/index.d.ts +1 -1
- package/index.ts +1 -1
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { onMounted, ref, watch, computed, onBeforeUnmount } from "vue";
|
|
2
2
|
import { isSSR } from "../utils/helper";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
type ResponsiveConfig<T> = Partial<Record<BreakpointName, T>>;
|
|
5
5
|
|
|
6
6
|
enum BreakpointName {
|
|
7
7
|
Xs = "xs",
|
|
@@ -21,12 +21,16 @@ enum BreakpointWidth {
|
|
|
21
21
|
"2xl" = 1536,
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
let isInitialized = false;
|
|
25
|
+
let animationId: number | undefined;
|
|
26
|
+
|
|
27
|
+
const windowWidth = ref(0);
|
|
28
|
+
const currentBreakpoint = ref(BreakpointName.Xs);
|
|
29
|
+
const BREAKPOINT_KEYS = Object.keys(BreakpointName) as (keyof typeof BreakpointName)[];
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
const currentBreakpoint: Ref<BreakpointName> = ref(BreakpointName.Xs);
|
|
31
|
+
watch(windowWidth, setBreakpoint, { immediate: true });
|
|
29
32
|
|
|
33
|
+
export function useBreakpoint() {
|
|
30
34
|
const isPhone = computed(() => {
|
|
31
35
|
return currentBreakpoint.value === BreakpointName.Xs;
|
|
32
36
|
});
|
|
@@ -63,50 +67,14 @@ export function useBreakpoint() {
|
|
|
63
67
|
return isDesktop.value || isLargeDesktop.value;
|
|
64
68
|
});
|
|
65
69
|
|
|
66
|
-
watch(windowWidth, setBreakpoint, { immediate: true });
|
|
67
|
-
|
|
68
70
|
onMounted(() => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
windowWidth.value = window.innerWidth;
|
|
72
|
-
|
|
73
|
-
window.addEventListener("resize", resizeListener, { passive: true });
|
|
71
|
+
initBreakpointListener();
|
|
74
72
|
});
|
|
75
73
|
|
|
76
74
|
onBeforeUnmount(() => {
|
|
77
|
-
if (isSSR) return;
|
|
78
|
-
|
|
79
75
|
window.removeEventListener("resize", resizeListener);
|
|
80
76
|
});
|
|
81
77
|
|
|
82
|
-
function resizeListener() {
|
|
83
|
-
if (isSSR) return;
|
|
84
|
-
|
|
85
|
-
if (animationId) {
|
|
86
|
-
window.cancelAnimationFrame(animationId);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
animationId = window.requestAnimationFrame(() => {
|
|
90
|
-
windowWidth.value = window.innerWidth;
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function setBreakpoint(newWindowWidth: number) {
|
|
95
|
-
if (newWindowWidth === undefined) return;
|
|
96
|
-
|
|
97
|
-
const breakpoints = [
|
|
98
|
-
{ width: BreakpointWidth["2xl"], name: BreakpointName["2xl"] },
|
|
99
|
-
{ width: BreakpointWidth.Xl, name: BreakpointName.Xl },
|
|
100
|
-
{ width: BreakpointWidth.Lg, name: BreakpointName.Lg },
|
|
101
|
-
{ width: BreakpointWidth.Md, name: BreakpointName.Md },
|
|
102
|
-
{ width: BreakpointWidth.Sm, name: BreakpointName.Sm },
|
|
103
|
-
];
|
|
104
|
-
|
|
105
|
-
currentBreakpoint.value =
|
|
106
|
-
breakpoints.find((breakpoint) => newWindowWidth >= breakpoint.width)?.name ||
|
|
107
|
-
BreakpointName.Xs;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
78
|
return {
|
|
111
79
|
isPhone,
|
|
112
80
|
isLargePhone,
|
|
@@ -120,3 +88,90 @@ export function useBreakpoint() {
|
|
|
120
88
|
breakpoint: currentBreakpoint,
|
|
121
89
|
};
|
|
122
90
|
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Shorthand function that can be used directly in templates.
|
|
94
|
+
* Returns the appropriate value based on the current breakpoint.
|
|
95
|
+
* Vue will track the reactive dependency and re-render when the breakpoint changes.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```vue
|
|
99
|
+
* <template>
|
|
100
|
+
* <UButton :size="r({ sm: 'sm', md: 'md' })">Click me</UButton>
|
|
101
|
+
* </template>
|
|
102
|
+
*
|
|
103
|
+
* <script setup>
|
|
104
|
+
* import { r } from "vueless";
|
|
105
|
+
* </script>
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export function r<T>(config: ResponsiveConfig<T>): T {
|
|
109
|
+
initBreakpointListener();
|
|
110
|
+
|
|
111
|
+
const definedKeys = BREAKPOINT_KEYS.filter((key) => BreakpointName[key] in config);
|
|
112
|
+
|
|
113
|
+
if (!definedKeys.length) {
|
|
114
|
+
return undefined as T;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const currentIndex = BREAKPOINT_KEYS.findIndex(
|
|
118
|
+
(key) => BreakpointName[key] === currentBreakpoint.value,
|
|
119
|
+
);
|
|
120
|
+
const smallestDefinedIndex = BREAKPOINT_KEYS.indexOf(definedKeys[0]);
|
|
121
|
+
const largestDefinedIndex = BREAKPOINT_KEYS.indexOf(definedKeys[definedKeys.length - 1]);
|
|
122
|
+
|
|
123
|
+
if (currentIndex <= smallestDefinedIndex) {
|
|
124
|
+
return config[BreakpointName[definedKeys[0]]] as T;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (currentIndex >= largestDefinedIndex) {
|
|
128
|
+
return config[BreakpointName[definedKeys[definedKeys.length - 1]]] as T;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
for (let i = currentIndex; i >= 0; i--) {
|
|
132
|
+
const bp = BreakpointName[BREAKPOINT_KEYS[i]];
|
|
133
|
+
|
|
134
|
+
if (bp in config) {
|
|
135
|
+
return config[bp] as T;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return config[BreakpointName[definedKeys[0]]] as T;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function setBreakpoint(newWindowWidth: number) {
|
|
143
|
+
if (newWindowWidth === undefined) return;
|
|
144
|
+
|
|
145
|
+
for (let i = BREAKPOINT_KEYS.length - 1; i >= 0; i--) {
|
|
146
|
+
const key = BREAKPOINT_KEYS[i];
|
|
147
|
+
|
|
148
|
+
if (newWindowWidth >= BreakpointWidth[key]) {
|
|
149
|
+
currentBreakpoint.value = BreakpointName[key];
|
|
150
|
+
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
currentBreakpoint.value = BreakpointName.Xs;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function resizeListener() {
|
|
159
|
+
if (isSSR) return;
|
|
160
|
+
|
|
161
|
+
if (animationId) {
|
|
162
|
+
window.cancelAnimationFrame(animationId);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
animationId = window.requestAnimationFrame(() => {
|
|
166
|
+
windowWidth.value = window.innerWidth;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function initBreakpointListener() {
|
|
171
|
+
if (isInitialized || isSSR) return;
|
|
172
|
+
|
|
173
|
+
isInitialized = true;
|
|
174
|
+
windowWidth.value = window.innerWidth;
|
|
175
|
+
|
|
176
|
+
window.addEventListener("resize", resizeListener, { passive: true });
|
|
177
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export { useLocale } from "./composables/useLocale";
|
|
|
29
29
|
export { useUI } from "./composables/useUI";
|
|
30
30
|
export { useDarkMode } from "./composables/useDarkMode";
|
|
31
31
|
export { useRequestQueue } from "./composables/useRequestQueue";
|
|
32
|
-
export { useBreakpoint } from "./composables/useBreakpoint";
|
|
32
|
+
export { useBreakpoint, r } from "./composables/useBreakpoint";
|
|
33
33
|
export { useLoaderOverlay } from "./ui.loader-overlay/useLoaderOverlay";
|
|
34
34
|
export { useLoaderProgress } from "./ui.loader-progress/useLoaderProgress";
|
|
35
35
|
export { useMutationObserver } from "./composables/useMutationObserver";
|
package/index.ts
CHANGED
|
@@ -35,7 +35,7 @@ export { useLocale } from "./composables/useLocale";
|
|
|
35
35
|
export { useUI } from "./composables/useUI";
|
|
36
36
|
export { useDarkMode } from "./composables/useDarkMode";
|
|
37
37
|
export { useRequestQueue } from "./composables/useRequestQueue";
|
|
38
|
-
export { useBreakpoint } from "./composables/useBreakpoint";
|
|
38
|
+
export { useBreakpoint, r } from "./composables/useBreakpoint";
|
|
39
39
|
export { useLoaderOverlay } from "./ui.loader-overlay/useLoaderOverlay";
|
|
40
40
|
export { useLoaderProgress } from "./ui.loader-progress/useLoaderProgress";
|
|
41
41
|
export { useMutationObserver } from "./composables/useMutationObserver";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vueless",
|
|
3
|
-
"version": "1.3.5
|
|
3
|
+
"version": "1.3.5",
|
|
4
4
|
"description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
|
|
5
5
|
"author": "Johnny Grid <hello@vueless.com> (https://vueless.com)",
|
|
6
6
|
"homepage": "https://vueless.com",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"@vue/eslint-config-typescript": "^14.6.0",
|
|
58
58
|
"@vue/test-utils": "^2.4.6",
|
|
59
59
|
"@vue/tsconfig": "^0.7.0",
|
|
60
|
-
"@vueless/storybook": "^1.3.
|
|
60
|
+
"@vueless/storybook": "^1.3.4",
|
|
61
61
|
"eslint": "^9.32.0",
|
|
62
62
|
"eslint-plugin-storybook": "^10.0.2",
|
|
63
63
|
"eslint-plugin-vue": "^10.3.0",
|