@imaginario27/air-ui-ds 1.13.0 → 1.13.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/CHANGELOG.md CHANGED
@@ -5,6 +5,28 @@ All notable changes to this package are documented in this file.
5
5
  Historical releases were reconstructed from git history (GitHub repository) and npm publish dates.
6
6
  Future releases will include detailed entries generated with Changesets.
7
7
 
8
+ ## 1.13.1 - 2026-05-19
9
+
10
+ Release type: patch.
11
+ Commits found in range: 1.
12
+
13
+ ### Added
14
+
15
+ 1. make mobile breakpoint behavior configurable ([8cd4eb6](https://github.com/imaginario27/air-ui/commit/8cd4eb6047046ba64f96177f284e0ee2db910cc3))
16
+
17
+ - Package: @imaginario27/air-ui-ds.
18
+
19
+ ## 1.13.0 - 2026-04-22
20
+
21
+ Release type: minor.
22
+ Commits found in range: 1.
23
+
24
+ ### Added
25
+
26
+ 1. update MetricCard with new props ([4841cb3](https://github.com/imaginario27/air-ui/commit/4841cb3e6c0a8385825ff91f505b9e5ca732ca44))
27
+
28
+ - Package: @imaginario27/air-ui-ds.
29
+
8
30
  ## 1.12.2 - 2026-04-22
9
31
 
10
32
  Release type: patch.
@@ -20,11 +20,15 @@ const props = defineProps({
20
20
  type: Number as PropType<number>,
21
21
  default: 240,
22
22
  },
23
+ mobileBreakpoint: {
24
+ type: Number as PropType<number>,
25
+ default: 1024,
26
+ },
23
27
  })
24
28
 
25
29
  // Composables
26
30
  const { isMobileSidebarOpen } = useMobileSidebar()
27
- const { isMobile } = useIsMobile()
31
+ const { isMobile } = useIsMobile(() => props.mobileBreakpoint)
28
32
 
29
33
  // Computed dynamic style
30
34
  const containerStyle = computed(() => {
@@ -15,13 +15,17 @@
15
15
 
16
16
  <script setup lang="ts">
17
17
  // Props
18
- defineProps({
18
+ const props = defineProps({
19
19
  tocSidebarWidth: {
20
20
  type: Number as PropType<number>,
21
21
  default: 240
22
- }
22
+ },
23
+ mobileBreakpoint: {
24
+ type: Number as PropType<number>,
25
+ default: 1024,
26
+ },
23
27
  })
24
28
 
25
29
  // Composable
26
- const { isMobile } = useIsMobile()
30
+ const { isMobile } = useIsMobile(() => props.mobileBreakpoint)
27
31
  </script>
@@ -34,12 +34,12 @@
34
34
  && sidebarTogglePosition === SidebarTogglePosition.LOGO_LEFT_SIDE
35
35
  "
36
36
  >
37
- <ActionIconButton
37
+ <ActionIconButton
38
38
  :icon="isMobileSidebarOpen ? 'mdi:menu-open' : 'mdi:menu-close'"
39
- class="lg:hidden shadow-sm"
39
+ :class="['shadow-sm', !isMobile && 'hidden']"
40
40
  @click="toggleMobileSidebar"
41
41
  />
42
- </template>
42
+ </template>
43
43
 
44
44
  <slot name="header-logo" />
45
45
 
@@ -49,20 +49,20 @@
49
49
  && sidebarTogglePosition === SidebarTogglePosition.LOGO_RIGHT_SIDE
50
50
  "
51
51
  >
52
- <ActionIconButton
52
+ <ActionIconButton
53
53
  :icon="isMobileSidebarOpen ? 'mdi:menu-open' : 'mdi:menu-close'"
54
- class="lg:hidden shadow-sm"
54
+ :class="['shadow-sm', !isMobile && 'hidden']"
55
55
  @click="toggleMobileSidebar"
56
56
  />
57
- </template>
57
+ </template>
58
58
  </div>
59
59
 
60
60
  <!-- Navigation -->
61
61
  <div class="flex gap-3 items-center xs:w-auto">
62
62
  <!-- Horizontal menu -->
63
- <NavMenu
64
- v-if="navMenuItems.length"
65
- :menuItems="navMenuItems"
63
+ <NavMenu
64
+ v-if="navMenuItems.length && !isMobile"
65
+ :menuItems="navMenuItems"
66
66
  :detectActive="detectActiveMenuItem"
67
67
  :submenuYOffset
68
68
  :submenuDropdownClass
@@ -74,7 +74,7 @@
74
74
  <!-- Header actions -->
75
75
  <div
76
76
  v-if="$slots['header-actions']"
77
- class="gap-3 items-center hidden lg:flex"
77
+ :class="['gap-3 items-center', isMobile ? 'hidden' : 'flex']"
78
78
  >
79
79
  <slot name="header-actions" />
80
80
  </div>
@@ -117,9 +117,9 @@
117
117
  :positionYOffset="submenuYOffset"
118
118
  >
119
119
  <template #activator>
120
- <ActionIconButton
120
+ <ActionIconButton
121
121
  icon="mdi:menu"
122
- class="lg:hidden shadow-sm"
122
+ class="shadow-sm"
123
123
  />
124
124
  </template>
125
125
  <template #items>
@@ -197,6 +197,10 @@ const props = defineProps({
197
197
  type: Array as PropType<DropdownMenuItem[]>,
198
198
  default: () => [],
199
199
  },
200
+ mobileBreakpoint: {
201
+ type: Number as PropType<number>,
202
+ default: 1024,
203
+ },
200
204
  showMobileMenuToggle: {
201
205
  type: Boolean as PropType<boolean>,
202
206
  default: true,
@@ -232,18 +236,18 @@ const props = defineProps({
232
236
  },
233
237
  navMenuClass: {
234
238
  type: String as PropType<string>,
235
- default: 'hidden lg:flex'
239
+ default: ''
236
240
  },
237
241
  navMobileMenuClass: {
238
242
  type: String as PropType<string>,
239
- default: 'lg:hidden min-w-[280px]'
243
+ default: 'min-w-[280px]'
240
244
  },
241
245
  headerClass: String as PropType<string>,
242
246
  })
243
247
 
244
248
  // Composables
245
249
  const { isMobileSidebarOpen, toggleMobileSidebar } = useMobileSidebar()
246
- const { isMobile } = useIsMobile()
250
+ const { isMobile } = useIsMobile(() => props.mobileBreakpoint)
247
251
 
248
252
  const getSubmenuItems = (item: MenuItem): NonNullable<MenuItem['children']> => {
249
253
  return item.children ?? []
@@ -14,8 +14,7 @@
14
14
  'py-4',
15
15
  'border-r border-border-default',
16
16
  'transition-all duration-300 ease-in-out',
17
- isMobileSidebarOpen ? 'translate-x-0' : '-translate-x-full',
18
- 'lg:translate-x-0', // Always visible on large screens
17
+ (!isMobile || isMobileSidebarOpen) ? 'translate-x-0' : '-translate-x-full',
19
18
  ]"
20
19
  >
21
20
  <!-- Collapse & Close Buttons -->
@@ -32,7 +31,7 @@
32
31
  <ActionIconButton
33
32
  v-if="showMobileSidebarClose && isMobile && !isCollapsed"
34
33
  :icon="mobileSidebarCloseIcon"
35
- class="flex sm:hidden"
34
+ class="flex"
36
35
  :size="ButtonSize.SM"
37
36
  @click="toggleMobileSidebar()"
38
37
  />
@@ -294,6 +293,10 @@ const props = defineProps({
294
293
  type: String as PropType<string>,
295
294
  default: 'mdi:close-circle',
296
295
  },
296
+ mobileBreakpoint: {
297
+ type: Number as PropType<number>,
298
+ default: 1024,
299
+ },
297
300
  isFixed: {
298
301
  type: Boolean as PropType<boolean>,
299
302
  default: true,
@@ -354,7 +357,7 @@ const {
354
357
  setSidebarCollapsed,
355
358
  toggleSidebarState,
356
359
  } = useSidebar()
357
- const { isMobile } = useIsMobile()
360
+ const { isMobile } = useIsMobile(() => props.mobileBreakpoint)
358
361
 
359
362
  const MAX_NESTING_LEVEL = 3
360
363
 
@@ -5,8 +5,7 @@
5
5
  'justify-between',
6
6
  'items-center',
7
7
  'gap-3',
8
- 'flex-col-reverse',
9
- 'lg:flex-row',
8
+ isMobile ? 'flex-col-reverse' : 'flex-row',
10
9
  'w-full'
11
10
  ]"
12
11
  >
@@ -26,7 +25,7 @@
26
25
  v-model="itemsPerPage"
27
26
  :rowsLabel="rowsPerPageLabel"
28
27
  :rowsOptions="rowsPerPageOptions"
29
- class="flex lg:hidden"
28
+ :class="[isMobile ? 'flex' : 'hidden']"
30
29
  /> <!-- Mobile position -->
31
30
  </div>
32
31
 
@@ -35,10 +34,7 @@
35
34
  :class="[
36
35
  'flex',
37
36
  'gap-6',
38
- 'flex-col',
39
- 'w-full',
40
- 'lg:flex-row',
41
- 'lg:w-auto'
37
+ isMobile ? 'flex-col w-full' : 'flex-row w-auto'
42
38
  ]"
43
39
  >
44
40
  <RowsPerPage
@@ -46,7 +42,7 @@
46
42
  v-model="itemsPerPage"
47
43
  :rowsLabel="rowsPerPageLabel"
48
44
  :rowsOptions="rowsPerPageOptions"
49
- class="hidden lg:flex"
45
+ :class="[isMobile ? 'hidden' : 'flex']"
50
46
  />
51
47
  <nav
52
48
  v-if="totalItems > itemsPerPage"
@@ -168,10 +164,14 @@ const props = defineProps({
168
164
  type: String as PropType<string>,
169
165
  default: 'Showing {total} result',
170
166
  },
167
+ mobileBreakpoint: {
168
+ type: Number as PropType<number>,
169
+ default: 1024,
170
+ },
171
171
  })
172
172
 
173
173
  // Composables
174
- const { isMobile } = useIsMobile()
174
+ const { isMobile } = useIsMobile(() => props.mobileBreakpoint)
175
175
 
176
176
  // States
177
177
  const itemsPerPage = ref(props.itemsPerPage)
@@ -1,27 +1,32 @@
1
- export const useIsMobile = (breakpoint: number = 1024) => {
2
- const isMobile = ref(false) // Initial value for SSR
3
-
4
- // Function to update `isMobile`
5
- const updateIsMobile = () => {
6
- if (typeof window !== 'undefined') {
7
- isMobile.value = window.innerWidth < breakpoint
8
- }
9
- }
10
-
11
- // Attach resize listener on the client
12
- onMounted(() => {
13
- updateIsMobile() // Initialize the value
14
- window.addEventListener('resize', updateIsMobile)
15
- })
16
-
17
- // Cleanup listener when unmounted
18
- onUnmounted(() => {
19
- if (typeof window !== 'undefined') {
20
- window.removeEventListener('resize', updateIsMobile)
21
- }
22
- })
23
-
24
- return {
25
- isMobile,
26
- }
27
- }
1
+ import { toValue, type MaybeRefOrGetter } from 'vue'
2
+
3
+ export const useIsMobile = (breakpoint: MaybeRefOrGetter<number> = 1024) => {
4
+ const isMobile = ref(false) // Initial value for SSR
5
+
6
+ // Function to update `isMobile`
7
+ const updateIsMobile = () => {
8
+ if (typeof window !== 'undefined') {
9
+ isMobile.value = window.innerWidth < toValue(breakpoint)
10
+ }
11
+ }
12
+
13
+ // Attach resize listener on the client
14
+ onMounted(() => {
15
+ updateIsMobile() // Initialize the value
16
+ window.addEventListener('resize', updateIsMobile)
17
+ })
18
+
19
+ // Re-evaluate when the breakpoint itself changes
20
+ watch(() => toValue(breakpoint), updateIsMobile)
21
+
22
+ // Cleanup listener when unmounted
23
+ onUnmounted(() => {
24
+ if (typeof window !== 'undefined') {
25
+ window.removeEventListener('resize', updateIsMobile)
26
+ }
27
+ })
28
+
29
+ return {
30
+ isMobile,
31
+ }
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imaginario27/air-ui-ds",
3
- "version": "1.13.0",
3
+ "version": "1.13.2",
4
4
  "author": "imaginario27",
5
5
  "type": "module",
6
6
  "homepage": "https://air-ui.netlify.app/",
@@ -23,31 +23,31 @@
23
23
  "typecheck": "vue-tsc --noEmit -p tsconfig.typecheck.json"
24
24
  },
25
25
  "dependencies": {
26
- "@nuxt/content": "3.12.0",
26
+ "@nuxt/content": "3.14.0",
27
27
  "@nuxt/eslint": "1.15.2",
28
- "@nuxt/icon": "2.2.1",
28
+ "@nuxt/icon": "2.2.2",
29
29
  "@nuxt/image": "2.0.0",
30
- "@nuxtjs/i18n": "10.2.3",
31
- "@tailwindcss/vite": "4.2.2",
32
- "@vueuse/core": "14.2.1",
33
- "@vueuse/nuxt": "14.2.1",
34
- "nuxt": "4.4.2",
35
- "qrcode.vue": "3.8.0",
36
- "tailwindcss": "4.2.2",
37
- "vue": "3.5.30",
38
- "vue-router": "5.0.4",
30
+ "@nuxtjs/i18n": "10.3.0",
31
+ "@tailwindcss/vite": "4.3.0",
32
+ "@vueuse/core": "14.3.0",
33
+ "@vueuse/nuxt": "14.3.0",
34
+ "nuxt": "4.4.6",
35
+ "qrcode.vue": "3.9.1",
36
+ "tailwindcss": "4.3.0",
37
+ "vue": "3.5.34",
38
+ "vue-router": "5.0.7",
39
39
  "vue3-toastify": "0.2.9"
40
40
  },
41
41
  "devDependencies": {
42
- "@nuxt/test-utils": "4.0.0",
43
- "@vitest/coverage-v8": "4.1.0",
44
- "@vue/test-utils": "2.4.6",
45
- "eslint": "10.1.0",
46
- "happy-dom": "20.8.4",
47
- "playwright-core": "1.58.2",
48
- "prettier": "3.8.1",
42
+ "@nuxt/test-utils": "4.0.3",
43
+ "@vitest/coverage-v8": "4.1.7",
44
+ "@vue/test-utils": "2.4.10",
45
+ "eslint": "10.4.0",
46
+ "happy-dom": "20.9.0",
47
+ "playwright-core": "1.60.0",
48
+ "prettier": "3.8.3",
49
49
  "ts-node": "10.9.2",
50
- "typescript": "5.9.3",
51
- "vitest": "4.1.0"
50
+ "typescript": "6.0.3",
51
+ "vitest": "4.1.7"
52
52
  }
53
53
  }
package/.nuxtrc DELETED
@@ -1 +0,0 @@
1
- setups.@nuxt/test-utils="4.0.0"