@imaginario27/air-ui-ds 1.0.15 → 1.0.16

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.
@@ -47,11 +47,11 @@
47
47
  v-if="icon && !svgIcon"
48
48
  :icon
49
49
  preserveAspectRatio="xMidYMid meet"
50
- :class="iconSizeClass"
50
+ :class="[iconSizeClass, iconClass ]"
51
51
  />
52
52
  <span
53
53
  v-else-if="svgIcon"
54
- :class="iconSizeClass"
54
+ :class="[iconSizeClass, iconClass ]"
55
55
  >
56
56
  <SVGImage
57
57
  :src="svgIcon"
@@ -70,11 +70,11 @@
70
70
  v-if="icon"
71
71
  :icon="icon"
72
72
  preserveAspectRatio="xMidYMid meet"
73
- :class="iconSizeClass"
73
+ :class="[iconSizeClass, iconClass]"
74
74
  />
75
75
  <span
76
76
  v-else-if="svgIcon"
77
- :class="iconSizeClass"
77
+ :class="[iconSizeClass, iconClass]"
78
78
  >
79
79
  <SVGImage
80
80
  :src="svgIcon"
@@ -117,6 +117,7 @@ const props = defineProps({
117
117
  type: String as PropType<string>,
118
118
  default: 'Button text'
119
119
  },
120
+ textClass: String as PropType<string>,
120
121
  size: {
121
122
  type: String as PropType<ButtonSize>,
122
123
  default: ButtonSize.LG,
@@ -136,6 +137,7 @@ const props = defineProps({
136
137
  type: Boolean as PropType<boolean>,
137
138
  default: false,
138
139
  },
140
+ iconClass: String as PropType<string>,
139
141
  disabled: {
140
142
  type: Boolean as PropType<boolean>,
141
143
  default: false,
@@ -169,7 +171,6 @@ const props = defineProps({
169
171
  default: 'Processing...',
170
172
  },
171
173
  id: String as PropType<string>,
172
- textClass: String as PropType<string>,
173
174
  })
174
175
 
175
176
  // Emits
@@ -22,11 +22,11 @@
22
22
  v-if="icon && !svgIcon"
23
23
  :icon
24
24
  preserveAspectRatio="xMidYMid meet"
25
- :class="iconSizeClass"
25
+ :class="[iconSizeClass, iconClass]"
26
26
  />
27
27
  <span
28
28
  v-else-if="svgIcon"
29
- :class="iconSizeClass"
29
+ :class="[iconSizeClass, iconClass]"
30
30
  >
31
31
  <SVGImage
32
32
  :src="svgIcon"
@@ -77,6 +77,7 @@ const props = defineProps({
77
77
  type: Boolean as PropType<boolean>,
78
78
  default: false
79
79
  },
80
+ iconClass: String as PropType<string>,
80
81
  disabled: {
81
82
  type: Boolean as PropType<boolean>,
82
83
  default: false,
@@ -0,0 +1,158 @@
1
+ <template>
2
+ <ActionIconButton
3
+ v-if="buttonType === ButtonType.ACTION_ICON_BUTTON"
4
+ :styleType
5
+ :size
6
+ :icon="currentCopyButtonIcon"
7
+ :iconClass="currentIconClass"
8
+ :disabled
9
+ @click="handleCopy"
10
+ />
11
+ <ActionButton
12
+ v-else
13
+ :styleType
14
+ :size
15
+ :text="currentCopyButtonText"
16
+ :icon="currentCopyButtonIcon"
17
+ :iconPosition
18
+ :iconClass="currentIconClass"
19
+ :disabled
20
+ @click="handleCopy"
21
+ />
22
+ </template>
23
+ <script setup lang="ts">
24
+ // Props
25
+ const props = defineProps({
26
+ textToCopy: {
27
+ type: String as PropType<string>,
28
+ required: true,
29
+ },
30
+ copySuccessText: {
31
+ type: String as PropType<string>,
32
+ default: 'Copied to clipboard!',
33
+ },
34
+ copyErrorText: {
35
+ type: String as PropType<string>,
36
+ default: 'Failed to copy to clipboard.',
37
+ },
38
+ showToast: {
39
+ type: Boolean as PropType<boolean>,
40
+ default: true,
41
+ },
42
+ resetAfter: {
43
+ type: Number as PropType<number>,
44
+ default: 1500,
45
+ },
46
+ buttonType: {
47
+ type: String as PropType<ButtonType>,
48
+ default: ButtonType.ACTION_ICON_BUTTON,
49
+ validator: (value: ButtonType) => Object.values(ButtonType).includes(value),
50
+ },
51
+ styleType: {
52
+ type: String as PropType<
53
+ ButtonStyleType.NEUTRAL_FILLED
54
+ | ButtonStyleType.NEUTRAL_OUTLINED
55
+ | ButtonStyleType.NEUTRAL_TRANSPARENT
56
+ | ButtonStyleType.NEUTRAL_TRANSPARENT_SUBTLE
57
+ | ButtonStyleType.PRIMARY_BRAND_FILLED
58
+ | ButtonStyleType.PRIMARY_BRAND_SOFT
59
+ | ButtonStyleType.PRIMARY_BRAND_TRANSPARENT
60
+ | ButtonStyleType.SECONDARY_BRAND_FILLED
61
+ >,
62
+ default: ButtonStyleType.NEUTRAL_OUTLINED,
63
+ validator: (value: unknown) =>
64
+ typeof value === 'string' &&
65
+ [
66
+ ButtonStyleType.NEUTRAL_FILLED,
67
+ ButtonStyleType.NEUTRAL_OUTLINED,
68
+ ButtonStyleType.NEUTRAL_TRANSPARENT,
69
+ ButtonStyleType.NEUTRAL_TRANSPARENT_SUBTLE,
70
+ ButtonStyleType.PRIMARY_BRAND_FILLED,
71
+ ButtonStyleType.PRIMARY_BRAND_SOFT,
72
+ ButtonStyleType.PRIMARY_BRAND_TRANSPARENT,
73
+ ButtonStyleType.SECONDARY_BRAND_FILLED,
74
+ ].includes(value as ButtonStyleType),
75
+ },
76
+ text: {
77
+ type: String as PropType<string>,
78
+ default: 'Copy'
79
+ },
80
+ size: {
81
+ type: String as PropType<ButtonSize>,
82
+ default: ButtonSize.SM,
83
+ validator: (value: ButtonSize) => Object.values(ButtonSize).includes(value),
84
+ },
85
+ icon: {
86
+ type: String as PropType<any>,
87
+ default: "mdiContentCopy",
88
+ },
89
+ iconPosition: {
90
+ type: String as PropType<IconPosition>,
91
+ default: IconPosition.RIGHT,
92
+ validator: (value: IconPosition) => Object.values(IconPosition).includes(value),
93
+ },
94
+ disabled: {
95
+ type: Boolean as PropType<boolean>,
96
+ default: false,
97
+ },
98
+ })
99
+
100
+ // States
101
+ const currentCopyButtonIcon = ref<any>(props.icon)
102
+ const currentCopyButtonText = ref<string>(props.text)
103
+ const currentIconClass = ref<string | undefined>(undefined)
104
+
105
+ // Emits
106
+ const emit = defineEmits(['success', 'error'])
107
+
108
+ // Initialize toast
109
+ const { $toast } = useNuxtApp()
110
+
111
+ // Methods
112
+ const handleCopy = useThrottleFn(
113
+ async () => {
114
+ const success = await copyToClipboard(props.textToCopy)
115
+
116
+ if (success) {
117
+ currentCopyButtonIcon.value = 'mdiCheck'
118
+ currentCopyButtonText.value = props.copySuccessText
119
+
120
+ if (
121
+ props.styleType === ButtonStyleType.NEUTRAL_OUTLINED ||
122
+ props.styleType === ButtonStyleType.NEUTRAL_TRANSPARENT ||
123
+ props.styleType === ButtonStyleType.NEUTRAL_TRANSPARENT_SUBTLE
124
+ ) {
125
+ currentIconClass.value = 'text-icon-success'
126
+ }
127
+
128
+ if (props.showToast) {
129
+ $toast.success(props.copySuccessText, {
130
+ toastId: 'copy-button-success',
131
+ })
132
+ }
133
+
134
+ emit('success')
135
+ } else {
136
+ currentCopyButtonIcon.value = 'mdiAlertCircleOutline'
137
+ currentCopyButtonText.value = props.copyErrorText
138
+
139
+ if (props.showToast) {
140
+ $toast.error(props.copyErrorText, {
141
+ toastId: 'copy-button-error',
142
+ })
143
+ }
144
+
145
+ emit('error')
146
+ }
147
+
148
+ // Reset UI after delay
149
+ setTimeout(() => {
150
+ currentCopyButtonIcon.value = props.icon
151
+ currentCopyButtonText.value = props.text
152
+ currentIconClass.value = undefined
153
+ }, props.resetAfter)
154
+ },
155
+ props.resetAfter,
156
+ true, // trailing only
157
+ )
158
+ </script>
@@ -4,7 +4,7 @@
4
4
  'flex',
5
5
  'flex-col',
6
6
  'gap-4',
7
- dividedRows && '!gap-0 divide-y divide-border-neutral-subtle border-b border-border-neutral-subtle'
7
+ 'mt-2',
8
8
  ]"
9
9
  >
10
10
  <h3
@@ -12,7 +12,6 @@
12
12
  'form-field-group-title',
13
13
  'font-semibold',
14
14
  'text-text-neutral-subtle',
15
- dividedRows && 'mb-4'
16
15
  ]"
17
16
  >
18
17
  {{ title }}
@@ -27,9 +26,5 @@ defineProps({
27
26
  type: String as PropType<string>,
28
27
  default: 'Group title',
29
28
  },
30
- dividedRows: {
31
- type: Boolean as PropType<boolean>,
32
- default: false,
33
- },
34
29
  })
35
30
  </script>
@@ -4,7 +4,7 @@
4
4
  'flex',
5
5
  'flex-col',
6
6
  'gap-4',
7
- dividedRows && '!gap-0 divide-y divide-border-neutral-subtle border-b border-border-neutral-subtle'
7
+ 'mt-2',
8
8
  ]"
9
9
  >
10
10
  <h3
@@ -12,7 +12,6 @@
12
12
  'form-field-group-title',
13
13
  'font-semibold',
14
14
  'text-text-neutral-subtle',
15
- dividedRows && 'mb-4'
16
15
  ]"
17
16
  >
18
17
  {{ title }}
@@ -27,9 +26,5 @@ defineProps({
27
26
  type: String as PropType<string>,
28
27
  default: 'Group title',
29
28
  },
30
- dividedRows: {
31
- type: Boolean as PropType<boolean>,
32
- default: false,
33
- },
34
29
  })
35
30
  </script>
@@ -23,7 +23,7 @@
23
23
  'bg-background-surface/30 dark:bg-background-surface/85',
24
24
  ],
25
25
  hasBorder && 'border-b border-border-default',
26
- innerContainerClass,
26
+ headerClass,
27
27
  ]"
28
28
  >
29
29
  <!-- Logo -->
@@ -154,10 +154,10 @@
154
154
 
155
155
  <script setup lang="ts">
156
156
  // Props
157
- defineProps({
158
- pageTitleType: {
159
- type: String as PropType<PageTitleType>,
160
- default: PageTitleType.SIMPLE,
157
+ const props = defineProps({
158
+ pageTitleFormat: {
159
+ type: String as PropType<PageTitleFormat>,
160
+ default: PageTitleFormat.SIMPLE,
161
161
  },
162
162
  navMenuItems: {
163
163
  type: Array as PropType<MenuItem[]>,
@@ -206,7 +206,7 @@ defineProps({
206
206
  type: String as PropType<string>,
207
207
  default: 'lg:hidden min-w-[280px]'
208
208
  },
209
- innerContainerClass: String as PropType<string>,
209
+ headerClass: String as PropType<string>,
210
210
  })
211
211
 
212
212
  // Composables
@@ -221,6 +221,6 @@ const currentPageTitle = computed<string>(() =>
221
221
 
222
222
  // Dynamically set the page title
223
223
  useHead(() => ({
224
- title: pageTitle(currentPageTitle.value, App.NAME),
224
+ title: pageTitle(currentPageTitle.value, App.NAME, props.pageTitleFormat),
225
225
  }))
226
226
  </script>
@@ -8,7 +8,7 @@
8
8
  hasSidePadding && 'px-content-side-padding-mobile md:px-content-side-padding',
9
9
  'pt-12',
10
10
  'pb-8',
11
- 'border-b border-border-default'
11
+ hasSeparator && 'border-b border-border-default'
12
12
  ]"
13
13
  >
14
14
  <NavLink
@@ -43,7 +43,7 @@
43
43
  </h1>
44
44
 
45
45
  <p
46
- v-if="pageDescription || description"
46
+ v-if="showDescription && (pageDescription || description)"
47
47
  class="text-text-neutral-subtle text-lg max-w-[800px]"
48
48
  >
49
49
  {{ description ? description : pageDescription }}
@@ -60,13 +60,14 @@ defineProps({
60
60
  },
61
61
  title: String as PropType<string>,
62
62
  overtitle: String as PropType<string>,
63
- overtitleClass: String as PropType<string>,
64
- description: String as PropType<string>,
65
63
  isOverTitleUppercase: Boolean as PropType<boolean>,
66
- hasSidePadding: {
64
+ overtitleClass: String as PropType<string>,
65
+ showDescription: {
67
66
  type: Boolean as PropType<boolean>,
68
67
  default: true,
69
68
  },
69
+ description: String as PropType<string>,
70
+
70
71
  hasGoBackLink: {
71
72
  type: Boolean as PropType<boolean>,
72
73
  default: false,
@@ -79,6 +80,14 @@ defineProps({
79
80
  type: String as PropType<string>,
80
81
  default: '',
81
82
  },
83
+ hasSeparator: {
84
+ type: Boolean as PropType<boolean>,
85
+ default: true,
86
+ },
87
+ hasSidePadding: {
88
+ type: Boolean as PropType<boolean>,
89
+ default: true,
90
+ },
82
91
  })
83
92
 
84
93
  // Page title
@@ -36,3 +36,8 @@ export enum ButtonPaginationStyle {
36
36
  BUTTON = 'button',
37
37
  OVERLINE = 'overline',
38
38
  }
39
+
40
+ export enum ButtonType {
41
+ ACTION_BUTTON = 'action-button',
42
+ ACTION_ICON_BUTTON = 'action-icon-button',
43
+ }
@@ -0,0 +1,4 @@
1
+ export enum NotificationType {
2
+ INLINE = 'inline',
3
+ TOAST = 'toast',
4
+ }
@@ -1,7 +1,7 @@
1
1
  export enum PageTitleType {
2
2
  SIMPLE = 'simple',
3
- WITH_OVERTITLE = 'withOvertitle',
4
- WITH_BREADCRUMBS = 'withBreadcrumbs',
3
+ WITH_OVERTITLE = 'with-overtitle',
4
+ WITH_BREADCRUMBS = 'with-breadcrumbs',
5
5
  }
6
6
 
7
7
  export enum PageTitleFormat {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imaginario27/air-ui-ds",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "author": "imaginario27",
5
5
  "type": "module",
6
6
  "homepage": "https://air-ui.netlify.app/",