@imaginario27/air-ui-ds 1.14.0 → 1.14.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.14.1 - 2026-06-22
9
+
10
+ Release type: patch.
11
+ Commits found in range: 1.
12
+
13
+ ### Added
14
+
15
+ 1. add transparent, isSticky, and grid layout props ([f730d67](https://github.com/imaginario27/air-ui/commit/f730d67ad16ecbf8610946a88728529f71a41c0a))
16
+
17
+ - Package: @imaginario27/air-ui-ds.
18
+
19
+ ## 1.14.0 - 2026-06-16
20
+
21
+ Release type: minor.
22
+ Commits found in range: 1.
23
+
24
+ ### Added
25
+
26
+ 1. add CheckboxGroupField and refactor checkbox components ([da239fc](https://github.com/imaginario27/air-ui/commit/da239fcfb515038233a56089fcee4924081826f5))
27
+
28
+ - Package: @imaginario27/air-ui-ds.
29
+
8
30
  ## 1.13.13 - 2026-06-16
9
31
 
10
32
  Release type: patch.
@@ -13,6 +13,7 @@
13
13
  gapClass,
14
14
  disabled ? 'opacity-disabled cursor-not-allowed' : '',
15
15
  'self-start',
16
+ !transparent && 'bg-background-container-surface',
16
17
  ]"
17
18
  @click="emitClick"
18
19
  >
@@ -63,6 +64,10 @@ const props = defineProps({
63
64
  default: false,
64
65
  },
65
66
  ariaLabel: String as PropType<string>,
67
+ transparent: {
68
+ type: Boolean as PropType<boolean>,
69
+ default: false,
70
+ },
66
71
  })
67
72
 
68
73
  // Emits
@@ -5,7 +5,7 @@
5
5
  :aria-label="ariaLabel || 'Toggle options'"
6
6
  :class="[
7
7
  'flex',
8
- groupStyle === ToggleButtonGroupStyle.GROUPED ? 'border border-border-default' : 'flex-wrap gap-3',
8
+ groupStyle === ToggleButtonGroupStyle.GROUPED ? '' : 'flex-wrap gap-3',
9
9
  'w-fit',
10
10
  'rounded-button'
11
11
  ]"
@@ -21,11 +21,8 @@
21
21
  :icon="button.icon"
22
22
  :iconPosition="'iconPosition' in button ? button.iconPosition : undefined"
23
23
  :disabled
24
- :class="[
25
- groupStyle === ToggleButtonGroupStyle.SEGMENTED && hasButtonBorder && 'border border-border-default rounded-button',
26
- groupStyle === ToggleButtonGroupStyle.SEGMENTED && button.active && '!border-border-primary-brand-active',
27
- !hasButtonBorder && 'rounded-button',
28
- ]"
24
+ :transparent
25
+ :class="buttonItemClass(button)"
29
26
  @click="!disabled && handleButtonClick(button)"
30
27
  />
31
28
  </template>
@@ -38,11 +35,8 @@
38
35
  :size="button.size"
39
36
  :icon="button.icon"
40
37
  :disabled
41
- :class="[
42
- groupStyle === ToggleButtonGroupStyle.SEGMENTED && hasButtonBorder && 'border border-border-default rounded-button',
43
- groupStyle === ToggleButtonGroupStyle.SEGMENTED && button.active && '!border-border-primary-brand-active',
44
- !hasButtonBorder && 'rounded-button',
45
- ]"
38
+ :transparent
39
+ :class="buttonItemClass(button)"
46
40
  @click="!disabled && handleButtonClick(button)"
47
41
  />
48
42
  </template>
@@ -51,7 +45,7 @@
51
45
 
52
46
  <script setup lang="ts">
53
47
  // Props
54
- defineProps({
48
+ const props = defineProps({
55
49
  id: String as PropType<string>,
56
50
  ariaLabel: String as PropType<string>,
57
51
  modelValue: {
@@ -90,11 +84,35 @@ defineProps({
90
84
  type: Boolean as PropType<boolean>,
91
85
  default: false,
92
86
  },
87
+ transparent: {
88
+ type: Boolean as PropType<boolean>,
89
+ default: false,
90
+ },
93
91
  })
94
92
 
95
93
  // Emits
96
94
  const emit = defineEmits(['update:modelValue'])
97
95
 
96
+ // Computed classes
97
+ const groupedButtonClass = computed(() =>
98
+ props.groupStyle === ToggleButtonGroupStyle.GROUPED
99
+ ? 'border-y border-r border-border-default rounded-none first:border-l first:rounded-l-button last:rounded-r-button'
100
+ : false
101
+ )
102
+
103
+ const segmentedButtonClass = computed(() =>
104
+ props.groupStyle === ToggleButtonGroupStyle.SEGMENTED && props.hasButtonBorder
105
+ ? 'border border-border-default rounded-button'
106
+ : false
107
+ )
108
+
109
+ const buttonItemClass = (button: ToggleButtonItem) => [
110
+ groupedButtonClass.value,
111
+ segmentedButtonClass.value,
112
+ props.groupStyle === ToggleButtonGroupStyle.SEGMENTED && button.active && '!border-border-primary-brand-active',
113
+ !props.hasButtonBorder && 'rounded-button',
114
+ ]
115
+
98
116
  // Handlers
99
117
  const handleButtonClick = (button: ToggleButtonItem) => {
100
118
  if (button?.action) {
@@ -11,6 +11,7 @@
11
11
  buttonSizeClass,
12
12
  disabled ? 'opacity-disabled cursor-not-allowed' : '',
13
13
  'self-start',
14
+ !transparent && 'bg-background-container-surface',
14
15
  ]"
15
16
  @click="emitClick"
16
17
  >
@@ -42,6 +43,10 @@ const props = defineProps({
42
43
  default: false,
43
44
  },
44
45
  ariaLabel: String as PropType<string>,
46
+ transparent: {
47
+ type: Boolean as PropType<boolean>,
48
+ default: false,
49
+ },
45
50
  })
46
51
 
47
52
  // Emits
@@ -45,7 +45,7 @@
45
45
  ]"
46
46
  :style="{
47
47
  ...computedTeleportStyle,
48
- zIndex: props.zIndex
48
+ zIndex: zIndex
49
49
  }"
50
50
  @mouseenter="onDropdownMouseEnter"
51
51
  @mouseleave="onDropdownMouseLeave"
@@ -151,7 +151,7 @@
151
151
  ]"
152
152
  :style="{
153
153
  ...(!positionClass ? positionOffsetStyle : {}),
154
- zIndex: props.zIndex
154
+ zIndex: zIndex
155
155
  }"
156
156
  @mouseenter="onDropdownMouseEnter"
157
157
  @mouseleave="onDropdownMouseLeave"
@@ -304,6 +304,10 @@ const props = defineProps({
304
304
  type: [String, Object] as PropType<PrefetchOnStrategy>,
305
305
  default: PrefetchOn.VISIBILITY,
306
306
  },
307
+ isSticky: {
308
+ type: Boolean as PropType<boolean>,
309
+ default: false,
310
+ },
307
311
  })
308
312
 
309
313
  // Refs
@@ -491,14 +495,23 @@ const computedTeleportStyle = computed<CSSProperties>(() => {
491
495
  if (secondary === 'top') top = a.top
492
496
  if (secondary === 'bottom') top = a.bottom - d.height
493
497
 
494
- return {
495
- position: 'absolute',
496
- top: `${top + window.scrollY}px`,
497
- left: `${left + window.scrollX}px`,
498
- width: `${a.width}px`,
499
- visibility: 'visible',
500
- zIndex: props.zIndex,
501
- }
498
+ return props.isSticky
499
+ ? {
500
+ position: 'fixed',
501
+ top: `${top}px`,
502
+ left: `${left}px`,
503
+ width: `${a.width}px`,
504
+ visibility: 'visible',
505
+ zIndex: props.zIndex,
506
+ }
507
+ : {
508
+ position: 'absolute',
509
+ top: `${top + window.scrollY}px`,
510
+ left: `${left + window.scrollX}px`,
511
+ width: `${a.width}px`,
512
+ visibility: 'visible',
513
+ zIndex: props.zIndex,
514
+ }
502
515
  })
503
516
 
504
517
  // Styles for non-teleported dropdown
@@ -33,6 +33,7 @@
33
33
  :groupStyle
34
34
  :disabled
35
35
  :onlyIcon
36
+ :transparent
36
37
  @update:modelValue="emit('update:modelValue', $event)"
37
38
  />
38
39
 
@@ -73,6 +74,10 @@ defineProps({
73
74
  type: Boolean as PropType<boolean>,
74
75
  default: false,
75
76
  },
77
+ transparent: {
78
+ type: Boolean as PropType<boolean>,
79
+ default: false,
80
+ },
76
81
  })
77
82
 
78
83
  // Emits
@@ -20,17 +20,12 @@
20
20
  :error="error"
21
21
  />
22
22
 
23
- <div
24
- :class="[
25
- orientation === Orientation.VERTICAL
26
- ? 'flex flex-col gap-4'
27
- : [
28
- 'w-full',
29
- 'grid gap-4',
30
- 'grid-cols-1',
31
- 'sm:grid-cols-2',
32
- ]
33
- ]"
23
+ <Grid
24
+ v-if="layout === ListLayout.GRID"
25
+ :cols="gridCols"
26
+ :tabletCols="gridTabletCols"
27
+ :mobileCols="gridMobileCols"
28
+ :gapClass="gridGapClass"
34
29
  >
35
30
  <CheckboxField
36
31
  v-for="option in options"
@@ -43,8 +38,35 @@
43
38
  :disabled="option.disabled ? option.disabled : disabled"
44
39
  :helpText="option.helpText"
45
40
  :inverse="inverse"
46
- @update:modelValue="handleChange(option.value, $event)"
41
+ @update:model-value="handleChange(option.value, $event)"
47
42
  />
43
+ </Grid>
44
+
45
+ <div
46
+ v-else
47
+ :class="[
48
+ orientation === Orientation.VERTICAL
49
+ ? ['flex flex-col gap-4', listClass]
50
+ : ['flex flex-wrap gap-6', listClass]
51
+ ]"
52
+ >
53
+ <div
54
+ v-for="option in options"
55
+ :key="option.id"
56
+ :class="orientation === Orientation.HORIZONTAL ? 'w-fit' : 'w-full'"
57
+ >
58
+ <CheckboxField
59
+ :id="option.id.toString()"
60
+ :modelValue="isChecked(option.value)"
61
+ :label="option.label"
62
+ :ariaLabel="option.ariaLabel"
63
+ :required
64
+ :disabled="option.disabled ? option.disabled : disabled"
65
+ :helpText="option.helpText"
66
+ :inverse="inverse"
67
+ @update:model-value="handleChange(option.value, $event)"
68
+ />
69
+ </div>
48
70
  </div>
49
71
 
50
72
  <!-- Help Text or Error Message (bottom) -->
@@ -101,6 +123,28 @@ const props = defineProps({
101
123
  default: Orientation.VERTICAL,
102
124
  validator: (value: Orientation) => Object.values(Orientation).includes(value),
103
125
  },
126
+ layout: {
127
+ type: String as PropType<ListLayout>,
128
+ default: ListLayout.LIST,
129
+ validator: (value: ListLayout) => Object.values(ListLayout).includes(value),
130
+ },
131
+ gridCols: {
132
+ type: Number as PropType<number>,
133
+ default: 3,
134
+ },
135
+ gridTabletCols: {
136
+ type: Number as PropType<number>,
137
+ default: 2,
138
+ },
139
+ gridMobileCols: {
140
+ type: Number as PropType<number>,
141
+ default: 1,
142
+ },
143
+ gridGapClass: {
144
+ type: String as PropType<string>,
145
+ default: 'gap-4',
146
+ },
147
+ listClass: String as PropType<string>,
104
148
  })
105
149
 
106
150
  // Emits
@@ -1,8 +1,9 @@
1
1
  <template>
2
- <header
2
+ <header
3
3
  :class="[
4
- isSticky && 'sticky top-0 z-50',
4
+ isSticky && `sticky top-0`,
5
5
  ]"
6
+ :style="isSticky ? { zIndex } : {}"
6
7
  >
7
8
  <slot name="top-header" />
8
9
 
@@ -70,6 +71,8 @@
70
71
  :submenuDropdownClass
71
72
  :submenuTrigger
72
73
  :prefetchOn
74
+ :isSticky
75
+ :dropdownZIndex="zIndex"
73
76
  :class="navMenuClass"
74
77
  />
75
78
 
@@ -82,10 +85,12 @@
82
85
  </div>
83
86
 
84
87
  <!-- User Menu -->
85
- <DropdownMenu
88
+ <DropdownMenu
86
89
  v-if="userMenuItems.length && userFullname"
87
90
  class="min-w-[200px]"
88
91
  :positionYOffset="submenuYOffset"
92
+ :isSticky
93
+ :zIndex="zIndex"
89
94
  >
90
95
  <template #activator>
91
96
  <Avatar
@@ -114,9 +119,11 @@
114
119
 
115
120
  <!-- Mobile menu -->
116
121
  <template v-if="isMobile && showMobileMenuToggle">
117
- <DropdownMenu
122
+ <DropdownMenu
118
123
  :class="navMobileMenuClass"
119
124
  :positionYOffset="submenuYOffset"
125
+ :isSticky
126
+ :zIndex="zIndex"
120
127
  >
121
128
  <template #activator>
122
129
  <ActionIconButton
@@ -246,6 +253,10 @@ const props = defineProps({
246
253
  type: String as PropType<string>,
247
254
  default: 'min-w-[280px]'
248
255
  },
256
+ zIndex: {
257
+ type: String as PropType<string>,
258
+ default: '50',
259
+ },
249
260
  headerClass: String as PropType<string>,
250
261
  sidebarOpenAriaLabel: {
251
262
  type: String as PropType<string>,
@@ -6,6 +6,8 @@
6
6
  :positionYOffset="submenuYOffset"
7
7
  :trigger="submenuTrigger"
8
8
  :dropdownClass="getDropdownClass(item)"
9
+ :isSticky
10
+ :zIndex="dropdownZIndex"
9
11
  >
10
12
  <template #activator="{ isOpen }">
11
13
  <button
@@ -89,6 +91,14 @@ const props = defineProps({
89
91
  type: [String, Object] as PropType<PrefetchOnStrategy>,
90
92
  default: PrefetchOn.VISIBILITY,
91
93
  },
94
+ isSticky: {
95
+ type: Boolean as PropType<boolean>,
96
+ default: false,
97
+ },
98
+ dropdownZIndex: {
99
+ type: String as PropType<string>,
100
+ default: '50',
101
+ },
92
102
  })
93
103
 
94
104
  // Composables
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imaginario27/air-ui-ds",
3
- "version": "1.14.0",
3
+ "version": "1.14.2",
4
4
  "author": "imaginario27",
5
5
  "type": "module",
6
6
  "homepage": "https://air-ui.netlify.app/",