orio-ui 1.10.4 → 1.11.0
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/README.md +3 -2
- package/dist/module.json +1 -1
- package/dist/runtime/components/ControlElement.vue +14 -1
- package/dist/runtime/composables/index.d.ts +1 -0
- package/dist/runtime/composables/index.js +5 -0
- package/dist/runtime/composables/useValidation.d.ts +15 -0
- package/dist/runtime/composables/useValidation.js +42 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,12 +111,13 @@ function handleClick() {
|
|
|
111
111
|
|
|
112
112
|
- **Upload** - File upload component
|
|
113
113
|
|
|
114
|
-
### Composables (
|
|
114
|
+
### Composables (8)
|
|
115
115
|
|
|
116
116
|
- **useTheme** - Theme and color mode management
|
|
117
117
|
- **useModal** - Modal state with animation origin tracking
|
|
118
118
|
- **useFuzzySearch** - Fuzzy search powered by Fuse.js
|
|
119
119
|
- **useApi** - Type-safe API request wrapper
|
|
120
|
+
- **useValidation** - Form validation with error handling
|
|
120
121
|
- **useDecimalFormatter** - Number formatting utilities
|
|
121
122
|
- **usePressAndHold** - Press and hold interaction handler
|
|
122
123
|
- **useSound** - Audio playback with CDN-hosted sounds
|
|
@@ -184,7 +185,7 @@ orio-ui/
|
|
|
184
185
|
├── src/
|
|
185
186
|
│ ├── runtime/
|
|
186
187
|
│ │ ├── components/ # 26 Vue components
|
|
187
|
-
│ │ ├── composables/ #
|
|
188
|
+
│ │ ├── composables/ # 8 composables
|
|
188
189
|
│ │ ├── assets/css/ # Theme CSS files
|
|
189
190
|
│ │ └── utils/ # Icon registry
|
|
190
191
|
│ └── module.ts # Nuxt Module definition
|
package/dist/module.json
CHANGED
|
@@ -4,19 +4,25 @@ export interface ControlProps {
|
|
|
4
4
|
* Minimal will reset margin and remove border and box shadow from every element inside the slot
|
|
5
5
|
*/
|
|
6
6
|
appearance?: "normal" | "minimal";
|
|
7
|
+
/**
|
|
8
|
+
* Error message to display below the control
|
|
9
|
+
*/
|
|
10
|
+
error?: string | null;
|
|
7
11
|
}
|
|
8
12
|
|
|
9
13
|
withDefaults(defineProps<ControlProps>(), {
|
|
10
14
|
appearance: "normal",
|
|
15
|
+
error: null,
|
|
11
16
|
});
|
|
12
17
|
</script>
|
|
13
18
|
|
|
14
19
|
<template>
|
|
15
|
-
<div class="control" :class="[appearance]">
|
|
20
|
+
<div class="control" :class="[appearance, { 'has-error': error }]">
|
|
16
21
|
<label v-if="$attrs.label" class="control-label">{{ $attrs.label }}</label>
|
|
17
22
|
<div class="slot-wrapper" v-bind="$attrs">
|
|
18
23
|
<slot />
|
|
19
24
|
</div>
|
|
25
|
+
<span v-if="error" class="control-error">{{ error }}</span>
|
|
20
26
|
</div>
|
|
21
27
|
</template>
|
|
22
28
|
|
|
@@ -30,6 +36,13 @@ withDefaults(defineProps<ControlProps>(), {
|
|
|
30
36
|
.control .control-label {
|
|
31
37
|
user-select: none;
|
|
32
38
|
}
|
|
39
|
+
.control .control-error {
|
|
40
|
+
color: var(--color-danger);
|
|
41
|
+
font-size: 0.875rem;
|
|
42
|
+
}
|
|
43
|
+
.control.has-error .slot-wrapper :deep(*) {
|
|
44
|
+
border-color: var(--color-danger);
|
|
45
|
+
}
|
|
33
46
|
.control.minimal {
|
|
34
47
|
margin: 0;
|
|
35
48
|
}
|
|
@@ -5,3 +5,4 @@ export { useTheme } from "./useTheme.js";
|
|
|
5
5
|
export { useDecimalFormatter } from "./useDecimalFormatter.js";
|
|
6
6
|
export { usePressAndHold } from "./usePressAndHold.js";
|
|
7
7
|
export { useSound, type SoundOptions } from "./useSound.js";
|
|
8
|
+
export { useValidation, isFilled, isEmail, type ValidationRule, } from "./useValidation.js";
|
|
@@ -7,3 +7,8 @@ export { useTheme } from "./useTheme.js";
|
|
|
7
7
|
export { useDecimalFormatter } from "./useDecimalFormatter.js";
|
|
8
8
|
export { usePressAndHold } from "./usePressAndHold.js";
|
|
9
9
|
export { useSound } from "./useSound.js";
|
|
10
|
+
export {
|
|
11
|
+
useValidation,
|
|
12
|
+
isFilled,
|
|
13
|
+
isEmail
|
|
14
|
+
} from "./useValidation.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type MaybeRef } from "vue";
|
|
2
|
+
export interface ValidationRule {
|
|
3
|
+
model: MaybeRef<any>;
|
|
4
|
+
id: string;
|
|
5
|
+
validator: (model: MaybeRef<any>) => boolean;
|
|
6
|
+
message?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function isFilled(model: MaybeRef<string | []>): boolean;
|
|
9
|
+
export declare function isEmail(model: MaybeRef<string>): boolean;
|
|
10
|
+
export declare function useValidation(rules: ValidationRule[]): {
|
|
11
|
+
checkValidity: () => boolean;
|
|
12
|
+
errors: Record<string, string | null>;
|
|
13
|
+
clearError: (id: string) => void;
|
|
14
|
+
clearAllErrors: () => void;
|
|
15
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { reactive, isRef } from "vue";
|
|
2
|
+
export function isFilled(model) {
|
|
3
|
+
return isRef(model) ? !!model.value.length : !!model.length;
|
|
4
|
+
}
|
|
5
|
+
export function isEmail(model) {
|
|
6
|
+
const value = isRef(model) ? model.value : model;
|
|
7
|
+
if (!value) return true;
|
|
8
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
9
|
+
return emailRegex.test(value);
|
|
10
|
+
}
|
|
11
|
+
export function useValidation(rules) {
|
|
12
|
+
const errors = reactive({});
|
|
13
|
+
function validate({
|
|
14
|
+
model,
|
|
15
|
+
id,
|
|
16
|
+
validator,
|
|
17
|
+
message
|
|
18
|
+
}) {
|
|
19
|
+
if (!validator(model)) {
|
|
20
|
+
if (!errors[id]) {
|
|
21
|
+
errors[id] = message || "Error on this field";
|
|
22
|
+
}
|
|
23
|
+
document.getElementById(id)?.scrollIntoView({
|
|
24
|
+
behavior: "smooth",
|
|
25
|
+
block: "center"
|
|
26
|
+
});
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
function checkValidity() {
|
|
32
|
+
clearAllErrors();
|
|
33
|
+
return rules.reduceRight((valid, rule) => validate(rule) && valid, true);
|
|
34
|
+
}
|
|
35
|
+
function clearError(id) {
|
|
36
|
+
errors[id] = null;
|
|
37
|
+
}
|
|
38
|
+
function clearAllErrors() {
|
|
39
|
+
Object.keys(errors).forEach((key) => errors[key] = null);
|
|
40
|
+
}
|
|
41
|
+
return { checkValidity, errors, clearError, clearAllErrors };
|
|
42
|
+
}
|