@imaginario27/air-ui-utils 1.1.1 → 1.2.1

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 ADDED
@@ -0,0 +1,203 @@
1
+ # Changelog
2
+
3
+ All notable changes to this package are documented in this file.
4
+
5
+ Historical releases were reconstructed from git history (GitHub repository) and npm publish dates.
6
+ Future releases will include detailed entries generated with Changesets.
7
+
8
+ ## 1.2.0 - 2026-03-18
9
+
10
+ Release type: minor.
11
+ Commits found in range: 1.
12
+
13
+ ### Changed
14
+
15
+ 1. update dependencies and improve toggles ([a119bf4](https://github.com/imaginario27/air-ui/commit/a119bf4396147b8e24652682ada438744416c0b1))
16
+
17
+ - Package: @imaginario27/air-ui-utils.
18
+
19
+ ## 1.1.1 - 2026-02-18
20
+
21
+ Release type: minor.
22
+ Commits found in range: 1.
23
+
24
+ ### Added
25
+
26
+ 1. Improves breadcrumbs, fixes tab styling issues and adds new functionalities to tabs an tables. ([6f35018](https://github.com/imaginario27/air-ui/commit/6f35018388a750e726ce95570c77d6b9c05deb8f))
27
+
28
+ - Package: @imaginario27/air-ui-utils.
29
+
30
+ ## 1.0.14 - 2026-02-09
31
+
32
+ Release type: patch.
33
+ Commits found in range: 1.
34
+
35
+ ### Added
36
+
37
+ 1. add transitions to dropdowns and modals ([9c837a5](https://github.com/imaginario27/air-ui/commit/9c837a567265118b6607e9633632ed8e7a216fad))
38
+
39
+ - Package: @imaginario27/air-ui-utils.
40
+
41
+ ## 1.0.13 - 2026-02-06
42
+
43
+ Release type: patch.
44
+ Commits found in range: 1.
45
+
46
+ ### Added
47
+
48
+ 1. adds missing utils docs pages and fixes general issues ([3f31a47](https://github.com/imaginario27/air-ui/commit/3f31a477d1bb1c04b2065b940093cfa59c6089ae))
49
+
50
+ - Package: @imaginario27/air-ui-utils.
51
+
52
+ ## 1.0.12 - 2026-02-05
53
+
54
+ Release type: patch.
55
+ Commits found in range: 0.
56
+
57
+ ### Changed
58
+
59
+ 1. Historical release reconstructed from npm publish metadata (no package commits found in this publish window).
60
+
61
+ - Package: @imaginario27/air-ui-utils.
62
+
63
+ ## 1.0.11 - 2026-02-04
64
+
65
+ Release type: patch.
66
+ Commits found in range: 1.
67
+
68
+ ### Fixed
69
+
70
+ 1. removes export depedencies and jsPDF + bumps package versions ([9139e12](https://github.com/imaginario27/air-ui/commit/9139e1221a00638c4cdb8021006c7276d2ccaed5))
71
+
72
+ - Package: @imaginario27/air-ui-utils.
73
+
74
+ ## 1.0.10 - 2026-02-02
75
+
76
+ Release type: patch.
77
+ Commits found in range: 0.
78
+
79
+ ### Changed
80
+
81
+ 1. Historical release reconstructed from npm publish metadata (no package commits found in this publish window).
82
+
83
+ - Package: @imaginario27/air-ui-utils.
84
+
85
+ ## 1.0.9 - 2026-02-02
86
+
87
+ Release type: patch.
88
+ Commits found in range: 1.
89
+
90
+ ### Added
91
+
92
+ 1. Add utils docs pages + Updates components props ([6f65f04](https://github.com/imaginario27/air-ui/commit/6f65f044b0ccc85dcc00f3ba6735232ce957a02b))
93
+
94
+ - Package: @imaginario27/air-ui-utils.
95
+
96
+ ## 1.0.8 - 2026-01-31
97
+
98
+ Release type: patch.
99
+ Commits found in range: 4.
100
+
101
+ ### Added
102
+
103
+ 1. Replaces the Nuxt MDI icon module with Nuxt Icon module ([b3343f1](https://github.com/imaginario27/air-ui/commit/b3343f152ee8726f4312059428bec15097b64ce8))
104
+ 2. improve getting started pages and UI components ([999f965](https://github.com/imaginario27/air-ui/commit/999f9654e821630af762593dc712d47a46913e35))
105
+
106
+ ### Fixed
107
+
108
+ 1. Fixes packages bump version ([7fe0732](https://github.com/imaginario27/air-ui/commit/7fe0732ec573c05b08c687f802c7c4e5c3a78c24))
109
+
110
+ ### Changed
111
+
112
+ 1. Bumps package version ([0eaefbc](https://github.com/imaginario27/air-ui/commit/0eaefbcbe5fe8cbcf3b6297a80873687a631258b))
113
+
114
+ - Package: @imaginario27/air-ui-utils.
115
+
116
+ ## 1.0.7 - 2025-12-10
117
+
118
+ Release type: patch.
119
+ Commits found in range: 0.
120
+
121
+ ### Changed
122
+
123
+ 1. Historical release reconstructed from npm publish metadata (no package commits found in this publish window).
124
+
125
+ - Package: @imaginario27/air-ui-utils.
126
+
127
+ ## 1.0.6 - 2025-12-10
128
+
129
+ Release type: patch.
130
+ Commits found in range: 0.
131
+
132
+ ### Changed
133
+
134
+ 1. Historical release reconstructed from npm publish metadata (no package commits found in this publish window).
135
+
136
+ - Package: @imaginario27/air-ui-utils.
137
+
138
+ ## 1.0.5 - 2025-12-09
139
+
140
+ Release type: patch.
141
+ Commits found in range: 0.
142
+
143
+ ### Changed
144
+
145
+ 1. Historical release reconstructed from npm publish metadata (no package commits found in this publish window).
146
+
147
+ - Package: @imaginario27/air-ui-utils.
148
+
149
+ ## 1.0.4 - 2025-12-09
150
+
151
+ Release type: patch.
152
+ Commits found in range: 0.
153
+
154
+ ### Changed
155
+
156
+ 1. Historical release reconstructed from npm publish metadata (no package commits found in this publish window).
157
+
158
+ - Package: @imaginario27/air-ui-utils.
159
+
160
+ ## 1.0.3 - 2025-12-09
161
+
162
+ Release type: patch.
163
+ Commits found in range: 0.
164
+
165
+ ### Changed
166
+
167
+ 1. Historical release reconstructed from npm publish metadata (no package commits found in this publish window).
168
+
169
+ - Package: @imaginario27/air-ui-utils.
170
+
171
+ ## 1.0.2 - 2025-12-07
172
+
173
+ Release type: patch.
174
+ Commits found in range: 0.
175
+
176
+ ### Changed
177
+
178
+ 1. Historical release reconstructed from npm publish metadata (no package commits found in this publish window).
179
+
180
+ - Package: @imaginario27/air-ui-utils.
181
+
182
+ ## 1.0.1 - 2025-12-07
183
+
184
+ Release type: patch.
185
+ Commits found in range: 1.
186
+
187
+ ### Changed
188
+
189
+ 1. Init ([f153db6](https://github.com/imaginario27/air-ui/commit/f153db6d125daee38fd029ac4bcdb81190893024))
190
+
191
+ - Package: @imaginario27/air-ui-utils.
192
+
193
+ ## 1.0.0 - 2025-12-05
194
+
195
+ Release type: initial.
196
+ Commits found in range: 0.
197
+
198
+ ### Changed
199
+
200
+ 1. Historical release reconstructed from npm publish metadata (no package commits found in this publish window).
201
+
202
+ - Package: @imaginario27/air-ui-utils.
203
+
@@ -0,0 +1,21 @@
1
+ export type RuleValidationValue = string | number | null
2
+
3
+ export interface RuleValidationItem {
4
+ item: RuleValidationValue
5
+ operator: RuleValidationValue
6
+ value: RuleValidationValue
7
+ }
8
+
9
+ export type ArrayValidator<T> = (value: T[]) => string | null
10
+
11
+ /**
12
+ * Configuration options for the ready-to-use RulesField validator factory.
13
+ */
14
+ export interface CreateRulesFieldValidatorOptions {
15
+ required?: boolean
16
+ requiredFieldMessage?: string
17
+ incompleteRuleMessage?: string
18
+ maxRules?: number
19
+ maxRulesMessage?: string
20
+ validators?: ArrayValidator<RuleValidationItem>[]
21
+ }
@@ -1,6 +1,6 @@
1
- export interface HeaderConfig {
2
- field: string
3
- callback?: (value: any) => string
4
- }
5
-
1
+ export interface HeaderConfig {
2
+ field: string
3
+ callback?: (value: any) => string
4
+ }
5
+
6
6
  export type Headers = Record<string, string | HeaderConfig>
package/nuxt.config.ts CHANGED
@@ -1,13 +1,13 @@
1
- // https://nuxt.com/docs/api/configuration/nuxt-config
2
-
3
- export default defineNuxtConfig({
4
- compatibilityDate: "2024-11-01",
5
- devtools: { enabled: false },
6
- ssr: false,
7
-
8
- imports: {
9
- dirs: [
10
- "models/**"
11
- ],
12
- },
1
+ // https://nuxt.com/docs/api/configuration/nuxt-config
2
+
3
+ export default defineNuxtConfig({
4
+ compatibilityDate: "2024-11-01",
5
+ devtools: { enabled: false },
6
+ ssr: false,
7
+
8
+ imports: {
9
+ dirs: [
10
+ "models/**"
11
+ ],
12
+ },
13
13
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imaginario27/air-ui-utils",
3
- "version": "1.1.1",
3
+ "version": "1.2.1",
4
4
  "author": "imaginario27",
5
5
  "type": "module",
6
6
  "homepage": "https://air-ui.netlify.app/",
@@ -21,17 +21,17 @@
21
21
  "typecheck": "vue-tsc --noEmit -p tsconfig.typecheck.json"
22
22
  },
23
23
  "dependencies": {
24
- "nuxt": "4.3.1",
25
- "vue": "3.5.28",
26
- "vue-router": "5.0.2"
24
+ "nuxt": "4.4.2",
25
+ "vue": "3.5.30",
26
+ "vue-router": "5.0.4"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@nuxt/test-utils": "4.0.0",
30
- "@vitest/coverage-v8": "4.0.18",
31
- "happy-dom": "20.6.2",
30
+ "@vitest/coverage-v8": "4.1.0",
31
+ "happy-dom": "20.8.4",
32
32
  "prettier": "3.8.1",
33
33
  "ts-node": "10.9.2",
34
34
  "typescript": "5.9.3",
35
- "vitest": "4.0.18"
35
+ "vitest": "4.1.0"
36
36
  }
37
37
  }
package/tsconfig.json CHANGED
@@ -1,7 +1,7 @@
1
- {
2
- // https://nuxt.com/docs/guide/concepts/typescript
3
- "extends": "./.nuxt/tsconfig.json",
4
- "compilerOptions": {
5
- "types": ["vitest/globals"],
6
- }
7
- }
1
+ {
2
+ // https://nuxt.com/docs/guide/concepts/typescript
3
+ "extends": "./.nuxt/tsconfig.json",
4
+ "compilerOptions": {
5
+ "types": ["vitest/globals"],
6
+ }
7
+ }
@@ -1,4 +1,12 @@
1
1
 
2
+ import { FieldError } from '../models/constants/form'
3
+ import type {
4
+ ArrayValidator,
5
+ CreateRulesFieldValidatorOptions,
6
+ RuleValidationItem,
7
+ RuleValidationValue,
8
+ } from '../models/types/formValidation'
9
+
2
10
  /**
3
11
  * Validates a field value to ensure it is not empty, null, or undefined.
4
12
  *
@@ -102,7 +110,7 @@ export const validateDateRange = (
102
110
  const start = new Date(startDate)
103
111
  const end = new Date(endDate)
104
112
 
105
- if (isNaN(start.getTime()) || isNaN(end.getTime()) || start > end) {
113
+ if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime()) || start > end) {
106
114
  return invalidRangeMessage
107
115
  }
108
116
 
@@ -197,3 +205,160 @@ export const validateArrayField = (
197
205
 
198
206
  return null
199
207
  }
208
+
209
+ /**
210
+ * Composes multiple array validators into a single validator function.
211
+ *
212
+ * Validators run in order and validation stops at the first error found.
213
+ *
214
+ * @typeParam T - Item type in the validated array.
215
+ * @param validators - List of validators to execute sequentially.
216
+ * @returns A validator function that returns the first error message, or null if all validators pass.
217
+ */
218
+ export const composeArrayValidators = <T>(
219
+ validators: ArrayValidator<T>[],
220
+ ): ArrayValidator<T> => {
221
+ return (value: T[]) => {
222
+ for (const validator of validators) {
223
+ const error = validator(value)
224
+ if (error) {
225
+ return error
226
+ }
227
+ }
228
+
229
+ return null
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Validates that the array contains at least one complete rule.
235
+ *
236
+ * A rule is considered complete when item, operator, and value are all present.
237
+ *
238
+ * @param value - Rules array to validate.
239
+ * @param requiredFieldMessage - Optional custom message returned when no complete rule exists.
240
+ * @returns Validation error message or null.
241
+ */
242
+ export const validateAtLeastOneRule = (
243
+ value: RuleValidationItem[],
244
+ requiredFieldMessage = 'Add at least one complete rule.',
245
+ ): string | null => {
246
+ const hasCompleteRule = value.some(rule => isRuleComplete(rule))
247
+
248
+ if (!hasCompleteRule) {
249
+ return requiredFieldMessage
250
+ }
251
+
252
+ return null
253
+ }
254
+
255
+ /**
256
+ * Validates that no rule is partially filled.
257
+ *
258
+ * Empty rows are allowed. Rows with some data must be fully complete.
259
+ *
260
+ * @param value - Rules array to validate.
261
+ * @param incompleteRuleMessage - Optional custom message returned when incomplete rows are found.
262
+ * @returns Validation error message or null.
263
+ */
264
+ export const validateRuleCompleteness = (
265
+ value: RuleValidationItem[],
266
+ incompleteRuleMessage = 'Complete all rule fields before continuing.',
267
+ ): string | null => {
268
+ const hasIncompleteRule = value.some(rule => !isRuleEmpty(rule) && !isRuleComplete(rule))
269
+
270
+ if (hasIncompleteRule) {
271
+ return incompleteRuleMessage
272
+ }
273
+
274
+ return null
275
+ }
276
+
277
+ /**
278
+ * Validates that the number of rules does not exceed the specified limit.
279
+ *
280
+ * @param value - Rules array to validate.
281
+ * @param maxRules - Maximum number of allowed rules.
282
+ * @param maxRulesMessage - Optional custom message returned when max is exceeded.
283
+ * @returns Validation error message or null.
284
+ */
285
+ export const validateMaxRules = (
286
+ value: RuleValidationItem[],
287
+ maxRules: number,
288
+ maxRulesMessage?: string,
289
+ ): string | null => {
290
+ const normalizedMax = Math.floor(maxRules)
291
+ if (normalizedMax <= 0) {
292
+ return null
293
+ }
294
+
295
+ if (value.length > normalizedMax) {
296
+ return maxRulesMessage ?? `No more than ${normalizedMax} rule${normalizedMax > 1 ? 's' : ''} allowed.`
297
+ }
298
+
299
+ return null
300
+ }
301
+
302
+ /**
303
+ * Creates a ready-to-use validator function for RulesField values.
304
+ *
305
+ * By default, this validator:
306
+ * 1) Rejects incomplete rows
307
+ * 2) Requires at least one complete row
308
+ *
309
+ * You can add extra custom validators that run after the built-in checks.
310
+ *
311
+ * @param options - Validation behavior options.
312
+ * @param options.required - Whether at least one complete rule is required.
313
+ * @param options.requiredFieldMessage - Custom message for missing complete rules.
314
+ * @param options.incompleteRuleMessage - Custom message for incomplete rows.
315
+ * @param options.validators - Additional custom validators.
316
+ * @returns A validator compatible with form field validator APIs.
317
+ */
318
+ export const createRulesFieldValidator = (
319
+ options: CreateRulesFieldValidatorOptions = {},
320
+ ): ArrayValidator<RuleValidationItem> => {
321
+ const {
322
+ required = true,
323
+ requiredFieldMessage,
324
+ incompleteRuleMessage,
325
+ maxRules,
326
+ maxRulesMessage,
327
+ validators = [],
328
+ } = options
329
+
330
+ const baseValidators: ArrayValidator<RuleValidationItem>[] = []
331
+
332
+ if (incompleteRuleMessage) {
333
+ baseValidators.push(value => validateRuleCompleteness(value, incompleteRuleMessage))
334
+ } else {
335
+ baseValidators.push(validateRuleCompleteness)
336
+ }
337
+
338
+ if (required) {
339
+ baseValidators.push(value => validateAtLeastOneRule(value, requiredFieldMessage))
340
+ }
341
+
342
+ if (typeof maxRules === 'number') {
343
+ baseValidators.push(value => validateMaxRules(value, maxRules, maxRulesMessage))
344
+ }
345
+
346
+ return composeArrayValidators([...baseValidators, ...validators])
347
+ }
348
+
349
+ // Helper functions for rule validation
350
+ const hasValue = (value: RuleValidationValue): boolean => {
351
+ if (typeof value === 'string') {
352
+ return value.trim() !== ''
353
+ }
354
+
355
+ return value !== null
356
+ }
357
+
358
+ const isRuleEmpty = (rule: RuleValidationItem): boolean => {
359
+ return !hasValue(rule.item) && !hasValue(rule.operator) && !hasValue(rule.value)
360
+ }
361
+
362
+ const isRuleComplete = (rule: RuleValidationItem): boolean => {
363
+ return hasValue(rule.item) && hasValue(rule.operator) && hasValue(rule.value)
364
+ }