@naptics/vue-collection 0.0.4 → 0.0.5
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/i18n/index.js +4 -4
- package/index.js +1 -1
- package/package.json +1 -1
- package/utils/breakpoints.js +21 -21
- package/utils/component.js +9 -17
- package/utils/deferred.js +12 -12
- package/utils/identifiable.js +29 -27
- package/utils/stringMaxLength.js +13 -8
- package/utils/tailwind.js +1 -1
- package/utils/utils.js +5 -5
- package/utils/vModel.js +73 -82
- package/utils/validation.js +81 -55
- package/utils/vue.js +5 -7
- package/components/NAlert.jsx +0 -69
- package/components/NBadge.jsx +0 -58
- package/components/NBreadcrub.jsx +0 -64
- package/components/NButton.jsx +0 -58
- package/components/NCheckbox.jsx +0 -38
- package/components/NCheckboxLabel.jsx +0 -42
- package/components/NCrudModal.jsx +0 -89
- package/components/NDialog.jsx +0 -144
- package/components/NDropdown.jsx +0 -92
- package/components/NDropzone.jsx +0 -211
- package/components/NForm.jsx +0 -26
- package/components/NFormModal.jsx +0 -48
- package/components/NIconButton.jsx +0 -71
- package/components/NIconCircle.jsx +0 -67
- package/components/NInput.jsx +0 -97
- package/components/NInputPhone.jsx +0 -32
- package/components/NInputSelect.jsx +0 -89
- package/components/NInputSuggestion.jsx +0 -48
- package/components/NLink.jsx +0 -58
- package/components/NList.jsx +0 -24
- package/components/NLoadingIndicator.jsx +0 -42
- package/components/NModal.jsx +0 -170
- package/components/NPagination.jsx +0 -104
- package/components/NSearchbar.jsx +0 -58
- package/components/NSearchbarList.jsx +0 -20
- package/components/NSelect.jsx +0 -81
- package/components/NSuggestionList.jsx +0 -157
- package/components/NTable.jsx +0 -146
- package/components/NTableAction.jsx +0 -35
- package/components/NTextArea.jsx +0 -108
- package/components/NTooltip.jsx +0 -161
- package/components/NValInput.jsx +0 -101
package/utils/validation.js
CHANGED
|
@@ -3,22 +3,17 @@ import { trsl } from '../i18n';
|
|
|
3
3
|
* Creates a valid result.
|
|
4
4
|
*/
|
|
5
5
|
export function validResult() {
|
|
6
|
-
|
|
7
|
-
isValid: true
|
|
8
|
-
};
|
|
6
|
+
return { isValid: true };
|
|
9
7
|
}
|
|
10
8
|
/**
|
|
11
9
|
* Creates an invalid result with the provided error message.
|
|
12
10
|
*/
|
|
13
11
|
export function invalidResult(errorMessage) {
|
|
14
|
-
|
|
15
|
-
isValid: false,
|
|
16
|
-
errorMessage
|
|
17
|
-
};
|
|
12
|
+
return { isValid: false, errorMessage };
|
|
18
13
|
}
|
|
19
14
|
const TRANSLATION_KEY_BASE = 'vue-collection.validation.rules';
|
|
20
15
|
function invalidResultInternal(key, params) {
|
|
21
|
-
|
|
16
|
+
return invalidResult(trsl(`${TRANSLATION_KEY_BASE}.${key}`, params));
|
|
22
17
|
}
|
|
23
18
|
/**
|
|
24
19
|
* Validates a given input with the specified rules.
|
|
@@ -30,11 +25,12 @@ function invalidResultInternal(key, params) {
|
|
|
30
25
|
* @returns an object containing the result of the validation.
|
|
31
26
|
*/
|
|
32
27
|
export function validate(input, rules) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
for (const rule of rules) {
|
|
29
|
+
const validationResult = rule(input);
|
|
30
|
+
if (!validationResult.isValid)
|
|
31
|
+
return validationResult;
|
|
32
|
+
}
|
|
33
|
+
return validResult();
|
|
38
34
|
}
|
|
39
35
|
/*
|
|
40
36
|
* ---------- Validation Rules ----------
|
|
@@ -43,14 +39,20 @@ export function validate(input, rules) {
|
|
|
43
39
|
* This rule expects the trimmed input-value to be truthy.
|
|
44
40
|
*/
|
|
45
41
|
export const required = input => {
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
const trimmed = input?.trim();
|
|
43
|
+
if (trimmed)
|
|
44
|
+
return validResult();
|
|
45
|
+
else
|
|
46
|
+
return invalidResultInternal('required');
|
|
48
47
|
};
|
|
49
48
|
/**
|
|
50
49
|
* This rule expects the input to be an integer.
|
|
51
50
|
*/
|
|
52
51
|
export const integer = input => {
|
|
53
|
-
|
|
52
|
+
if (!input || Number.isInteger(+input))
|
|
53
|
+
return validResult();
|
|
54
|
+
else
|
|
55
|
+
return invalidResultInternal('integer');
|
|
54
56
|
};
|
|
55
57
|
/**
|
|
56
58
|
* This rule expects the input to be in the specified length range. An empty input
|
|
@@ -59,18 +61,17 @@ export const integer = input => {
|
|
|
59
61
|
* @param max The maximum length of the string.
|
|
60
62
|
*/
|
|
61
63
|
export function length(min, max) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
};
|
|
64
|
+
return input => {
|
|
65
|
+
if (!input)
|
|
66
|
+
return validResult();
|
|
67
|
+
if (min !== undefined && max !== undefined && !(min <= input.length && input.length <= max))
|
|
68
|
+
return invalidResultInternal('length.min-max', { min, max });
|
|
69
|
+
else if (min !== undefined && !(min <= input.length))
|
|
70
|
+
return invalidResultInternal('length.min', { min });
|
|
71
|
+
else if (max !== undefined && !(input.length <= max))
|
|
72
|
+
return invalidResultInternal('length.max', { max });
|
|
73
|
+
return validResult();
|
|
74
|
+
};
|
|
74
75
|
}
|
|
75
76
|
/**
|
|
76
77
|
* This rule expects the input to be a number in the specified range.
|
|
@@ -78,34 +79,50 @@ export function length(min, max) {
|
|
|
78
79
|
* @param max the upper bound, if `undefined` there is no upper bound.
|
|
79
80
|
*/
|
|
80
81
|
export function numberRange(min, max) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
return input => {
|
|
83
|
+
if (!input)
|
|
84
|
+
return validResult();
|
|
85
|
+
const parsed = Number.parseFloat(input);
|
|
86
|
+
if (Number.isNaN(parsed))
|
|
87
|
+
return invalidResultInternal('number-range.nan');
|
|
88
|
+
if (min !== undefined && max !== undefined && !(min <= parsed && parsed <= max))
|
|
89
|
+
return invalidResultInternal('number-range.min-max', { min, max });
|
|
90
|
+
else if (min !== undefined && !(min <= parsed))
|
|
91
|
+
return invalidResultInternal('number-range.min', { min });
|
|
92
|
+
else if (max !== undefined && !(parsed <= max))
|
|
93
|
+
return invalidResultInternal('number-range.max', { max });
|
|
94
|
+
return validResult();
|
|
95
|
+
};
|
|
95
96
|
}
|
|
96
97
|
export const VALIDATION_FORMAT_EMAIL = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/;
|
|
97
98
|
/**
|
|
98
99
|
* This rule expects the input-value to be a valid email adress matching {@link VALIDATION_FORMAT_EMAIL}.
|
|
99
100
|
*/
|
|
100
101
|
export const email = input => {
|
|
101
|
-
|
|
102
|
+
if (!input || VALIDATION_FORMAT_EMAIL.test(input))
|
|
103
|
+
return validResult();
|
|
104
|
+
else
|
|
105
|
+
return invalidResultInternal('email');
|
|
102
106
|
};
|
|
103
107
|
export const VALIDATION_FORMAT_PASSWORD = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$^+\-=!*()@%&?]).{8,}$/;
|
|
104
108
|
/**
|
|
105
109
|
* This rule expects the input-value to be a password matching {@link VALIDATION_FORMAT_PASSWORD}.
|
|
106
110
|
*/
|
|
107
111
|
export const password = input => {
|
|
108
|
-
|
|
112
|
+
if (!input || VALIDATION_FORMAT_PASSWORD.test(input))
|
|
113
|
+
return validResult();
|
|
114
|
+
else if (input.length < 8)
|
|
115
|
+
return invalidResultInternal('password.to-short');
|
|
116
|
+
else if (!/[a-z]+/.test(input))
|
|
117
|
+
return invalidResultInternal('password.no-lowercase');
|
|
118
|
+
else if (!/[A-Z]+/.test(input))
|
|
119
|
+
return invalidResultInternal('password.no-uppercase');
|
|
120
|
+
else if (!/\d+/.test(input))
|
|
121
|
+
return invalidResultInternal('password.no-digits');
|
|
122
|
+
else if (!/[#$^+\-=!*()@%&?]+/.test(input))
|
|
123
|
+
return invalidResultInternal('password.no-special-chars');
|
|
124
|
+
else
|
|
125
|
+
return invalidResultInternal('password.unknown');
|
|
109
126
|
};
|
|
110
127
|
/**
|
|
111
128
|
* This rule expects the input-value to match another (input-) value.
|
|
@@ -114,27 +131,36 @@ export const password = input => {
|
|
|
114
131
|
* @param other the other value to match
|
|
115
132
|
*/
|
|
116
133
|
export function matches(other) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
134
|
+
return input => {
|
|
135
|
+
if (input === other)
|
|
136
|
+
return validResult();
|
|
137
|
+
else
|
|
138
|
+
return invalidResultInternal('matches');
|
|
139
|
+
};
|
|
120
140
|
}
|
|
121
141
|
/**
|
|
122
142
|
* This rule expects the input-value to match one option in an array.
|
|
123
143
|
* @param options the options which the input can match
|
|
124
144
|
*/
|
|
125
145
|
export function option(options) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
146
|
+
return input => {
|
|
147
|
+
if (!input || options.includes(input || ''))
|
|
148
|
+
return validResult();
|
|
149
|
+
else
|
|
150
|
+
return invalidResultInternal('option');
|
|
151
|
+
};
|
|
129
152
|
}
|
|
130
153
|
/**
|
|
131
154
|
* This rule expects the input-value to match the regex pattern
|
|
132
155
|
* @param pattern the pattern the input should match.
|
|
133
156
|
*/
|
|
134
157
|
export function regex(pattern) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
158
|
+
return input => {
|
|
159
|
+
if (!input || pattern.test(input || ''))
|
|
160
|
+
return validResult();
|
|
161
|
+
else
|
|
162
|
+
return invalidResultInternal('regex');
|
|
163
|
+
};
|
|
138
164
|
}
|
|
139
165
|
/**
|
|
140
166
|
* This rule can be used if the validation logic happens somewhere else.
|
|
@@ -143,5 +169,5 @@ export function regex(pattern) {
|
|
|
143
169
|
* Like always, a falsy input is always valid to not interefere with the {@link required} rule.
|
|
144
170
|
*/
|
|
145
171
|
export function external(isValid, errorMessage) {
|
|
146
|
-
|
|
147
|
-
}
|
|
172
|
+
return input => (!input || isValid ? validResult() : invalidResult(errorMessage));
|
|
173
|
+
}
|
package/utils/vue.js
CHANGED
|
@@ -5,11 +5,9 @@ import { watch } from 'vue';
|
|
|
5
5
|
* @param updater the updater funtion which provides the updates
|
|
6
6
|
*/
|
|
7
7
|
export function updateWith(ref, updater) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
immediate: true
|
|
12
|
-
});
|
|
8
|
+
watch(updater, newValue => {
|
|
9
|
+
ref.value = newValue;
|
|
10
|
+
}, { immediate: true });
|
|
13
11
|
}
|
|
14
12
|
/**
|
|
15
13
|
* Conveience function to create a watcher for a ref
|
|
@@ -17,5 +15,5 @@ export function updateWith(ref, updater) {
|
|
|
17
15
|
* @param onChange the function, which is executed on change of a value
|
|
18
16
|
*/
|
|
19
17
|
export function watchRef(ref, onChange) {
|
|
20
|
-
|
|
21
|
-
}
|
|
18
|
+
watch(() => ref.value, onChange);
|
|
19
|
+
}
|
package/components/NAlert.jsx
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { createComponent, createProps } from '../utils/component';
|
|
2
|
-
import { CheckCircleIcon, ExclamationCircleIcon, InformationCircleIcon, XMarkIcon } from '@heroicons/vue/24/solid';
|
|
3
|
-
import { computed } from 'vue';
|
|
4
|
-
import NIconButton from './NIconButton';
|
|
5
|
-
import NLoadingIndicator from './NLoadingIndicator';
|
|
6
|
-
export const nAlertProps = createProps({
|
|
7
|
-
/**
|
|
8
|
-
* The variant of the alert. This defines its color and icon.
|
|
9
|
-
*/
|
|
10
|
-
variant: {
|
|
11
|
-
type: String,
|
|
12
|
-
default: 'success',
|
|
13
|
-
},
|
|
14
|
-
/**
|
|
15
|
-
* The text of the alert.
|
|
16
|
-
*/
|
|
17
|
-
text: String,
|
|
18
|
-
/**
|
|
19
|
-
* If set to `true` the X-button of the alert is hidden.
|
|
20
|
-
*/
|
|
21
|
-
hideX: Boolean,
|
|
22
|
-
/**
|
|
23
|
-
* This is called, when the X-button is clicked.
|
|
24
|
-
*/
|
|
25
|
-
onDismiss: Function,
|
|
26
|
-
});
|
|
27
|
-
/**
|
|
28
|
-
* The `NAlert` is a fully styled alert with multiple variants.
|
|
29
|
-
* It can be used as a normal blocking element or as part of an alert queue.
|
|
30
|
-
*/
|
|
31
|
-
export default createComponent('NAlert', nAlertProps, props => {
|
|
32
|
-
const variant = computed(() => VARIANTS[props.variant]);
|
|
33
|
-
return () => (<div class={`rounded-md p-3 shadow-lg bg-${variant.value.color}-50`}>
|
|
34
|
-
<div class="flex items-center">
|
|
35
|
-
<div class="flex flex-shrink-0 items-center">{variant.value.icon()}</div>
|
|
36
|
-
|
|
37
|
-
<div class="ml-3 flex-grow">
|
|
38
|
-
<p class={`text-sm font-medium text-${variant.value.color}-900`}>{props.text}</p>
|
|
39
|
-
</div>
|
|
40
|
-
|
|
41
|
-
{!props.hideX && (<div class="flex items-center flex-shrink-0 ml-3">
|
|
42
|
-
<NIconButton color={variant.value.color} size={5} icon={XMarkIcon} onClick={props.onDismiss}/>
|
|
43
|
-
</div>)}
|
|
44
|
-
</div>
|
|
45
|
-
</div>);
|
|
46
|
-
});
|
|
47
|
-
const icon = (icon, color) => () => <icon class={`h-5 w-5 text-${color}-500`}/>;
|
|
48
|
-
const VARIANTS = {
|
|
49
|
-
success: {
|
|
50
|
-
icon: icon(CheckCircleIcon, 'green'),
|
|
51
|
-
color: 'green',
|
|
52
|
-
},
|
|
53
|
-
info: {
|
|
54
|
-
icon: icon(InformationCircleIcon, 'blue'),
|
|
55
|
-
color: 'blue',
|
|
56
|
-
},
|
|
57
|
-
warning: {
|
|
58
|
-
icon: icon(ExclamationCircleIcon, 'yellow'),
|
|
59
|
-
color: 'yellow',
|
|
60
|
-
},
|
|
61
|
-
error: {
|
|
62
|
-
icon: icon(ExclamationCircleIcon, 'red'),
|
|
63
|
-
color: 'red',
|
|
64
|
-
},
|
|
65
|
-
loading: {
|
|
66
|
-
icon: () => <NLoadingIndicator color="blue" size={7} shade={500}/>,
|
|
67
|
-
color: 'blue',
|
|
68
|
-
},
|
|
69
|
-
};
|
package/components/NBadge.jsx
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { createComponent, createProps } from '../utils/component';
|
|
2
|
-
import NTooltip, { mapTooltipProps, nToolTipPropsForImplementor } from './NTooltip';
|
|
3
|
-
export const nBadgeProps = createProps({
|
|
4
|
-
/**
|
|
5
|
-
* The text of the badge. Can alternatively be passed in the default slot.
|
|
6
|
-
*/
|
|
7
|
-
text: String,
|
|
8
|
-
/**
|
|
9
|
-
* The text size, a standard tailwind text-size class.
|
|
10
|
-
*/
|
|
11
|
-
textSize: {
|
|
12
|
-
type: String,
|
|
13
|
-
default: 'text-sm',
|
|
14
|
-
},
|
|
15
|
-
/**
|
|
16
|
-
* The color of the badge.
|
|
17
|
-
*/
|
|
18
|
-
color: {
|
|
19
|
-
type: String,
|
|
20
|
-
default: 'primary',
|
|
21
|
-
},
|
|
22
|
-
/**
|
|
23
|
-
* The background shade of the badge.
|
|
24
|
-
*/
|
|
25
|
-
shade: {
|
|
26
|
-
type: Number,
|
|
27
|
-
default: 200,
|
|
28
|
-
},
|
|
29
|
-
/**
|
|
30
|
-
* The text shade of the badge.
|
|
31
|
-
*/
|
|
32
|
-
textShade: {
|
|
33
|
-
type: Number,
|
|
34
|
-
default: 900,
|
|
35
|
-
},
|
|
36
|
-
/**
|
|
37
|
-
* If set to `true` the badges text is all-caps. Default is `true`.
|
|
38
|
-
*/
|
|
39
|
-
allCaps: {
|
|
40
|
-
type: Boolean,
|
|
41
|
-
default: true,
|
|
42
|
-
},
|
|
43
|
-
...nToolTipPropsForImplementor,
|
|
44
|
-
});
|
|
45
|
-
/**
|
|
46
|
-
* The `NBadge` is a styled element to wrap a text.
|
|
47
|
-
*/
|
|
48
|
-
export default createComponent('NBadge', nBadgeProps, (props, { slots }) => {
|
|
49
|
-
return () => (<NTooltip {...mapTooltipProps(props)}>
|
|
50
|
-
<div class={[
|
|
51
|
-
'px-2 py-1 rounded-md font-semibold shadow',
|
|
52
|
-
`${props.textSize} bg-${props.color}-${props.shade} text-${props.color}-${props.textShade}`,
|
|
53
|
-
props.allCaps ? 'uppercase' : '',
|
|
54
|
-
]}>
|
|
55
|
-
{slots.default?.() || props.text}
|
|
56
|
-
</div>
|
|
57
|
-
</NTooltip>);
|
|
58
|
-
});
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { createComponent, createProps } from '../utils/component';
|
|
2
|
-
import { ChevronRightIcon } from '@heroicons/vue/24/solid';
|
|
3
|
-
import NLink from './NLink';
|
|
4
|
-
export const nBreadcrumbProps = createProps({
|
|
5
|
-
/**
|
|
6
|
-
* The items of the breadcrumb.
|
|
7
|
-
*/
|
|
8
|
-
items: {
|
|
9
|
-
type: Array,
|
|
10
|
-
default: () => [],
|
|
11
|
-
},
|
|
12
|
-
/**
|
|
13
|
-
* The color of the breadcrumbs text and icons.
|
|
14
|
-
*/
|
|
15
|
-
color: {
|
|
16
|
-
type: String,
|
|
17
|
-
default: 'primary',
|
|
18
|
-
},
|
|
19
|
-
/**
|
|
20
|
-
* The text-size of the breadcrumb labels.
|
|
21
|
-
*/
|
|
22
|
-
textSize: {
|
|
23
|
-
type: String,
|
|
24
|
-
default: 'text-base',
|
|
25
|
-
},
|
|
26
|
-
/**
|
|
27
|
-
* The icon which is used as a seperator between two breadcrumb items.
|
|
28
|
-
*/
|
|
29
|
-
icon: {
|
|
30
|
-
type: Function,
|
|
31
|
-
default: ChevronRightIcon,
|
|
32
|
-
},
|
|
33
|
-
/**
|
|
34
|
-
* The size of the icon in tailwind units.
|
|
35
|
-
*/
|
|
36
|
-
iconSize: {
|
|
37
|
-
type: Number,
|
|
38
|
-
default: 5,
|
|
39
|
-
},
|
|
40
|
-
/**
|
|
41
|
-
* A slot the replace the breadcrumb labels.
|
|
42
|
-
*/
|
|
43
|
-
item: Function,
|
|
44
|
-
/**
|
|
45
|
-
* A slot to replace the separators between the breadcrumb labels.
|
|
46
|
-
* The passsed item is the item before the seperator.
|
|
47
|
-
*/
|
|
48
|
-
seperator: Function,
|
|
49
|
-
});
|
|
50
|
-
/**
|
|
51
|
-
* The `NBreadcrumb` is a styled breadcrumb which can be used as a navigation in hierarchical views.
|
|
52
|
-
*/
|
|
53
|
-
export default createComponent('NBreadcrumb', nBreadcrumbProps, props => {
|
|
54
|
-
return () => (<div class="flex flex-wrap items-center">
|
|
55
|
-
{props.items.map((item, index) => (<>
|
|
56
|
-
{props.item?.(item, index) || (<NLink textSize={props.textSize} route={item.route} color={props.color}>
|
|
57
|
-
{item.label}
|
|
58
|
-
</NLink>)}
|
|
59
|
-
|
|
60
|
-
{index < props.items.length - 1 &&
|
|
61
|
-
(props.seperator?.(item, index) || (<props.icon class={`mx-2 w-${props.iconSize} h-${props.iconSize} text-${props.color}-500`}/>))}
|
|
62
|
-
</>))}
|
|
63
|
-
</div>);
|
|
64
|
-
});
|
package/components/NButton.jsx
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { createComponent, createProps } from '../utils/component';
|
|
2
|
-
import { computed } from 'vue';
|
|
3
|
-
import NLoadingIndicator from './NLoadingIndicator';
|
|
4
|
-
import NTooltip, { mapTooltipProps, nToolTipPropsForImplementor } from './NTooltip';
|
|
5
|
-
export const nButtonProps = createProps({
|
|
6
|
-
/**
|
|
7
|
-
* The color of the button.
|
|
8
|
-
*/
|
|
9
|
-
color: {
|
|
10
|
-
type: String,
|
|
11
|
-
default: 'primary',
|
|
12
|
-
},
|
|
13
|
-
/**
|
|
14
|
-
* The html attribute, which indicates the type of the button.
|
|
15
|
-
*/
|
|
16
|
-
type: {
|
|
17
|
-
type: String,
|
|
18
|
-
default: 'button',
|
|
19
|
-
},
|
|
20
|
-
/**
|
|
21
|
-
* If set to `true` the button is disabled and no interaction is possible.
|
|
22
|
-
*/
|
|
23
|
-
disabled: Boolean,
|
|
24
|
-
/**
|
|
25
|
-
* If set to `true` the button will show a loading animation.
|
|
26
|
-
* Setting `loading` to `true` will also disable the button.
|
|
27
|
-
*/
|
|
28
|
-
loading: Boolean,
|
|
29
|
-
/**
|
|
30
|
-
* If set to `true` the button will appear smaller.
|
|
31
|
-
*/
|
|
32
|
-
small: Boolean,
|
|
33
|
-
/**
|
|
34
|
-
* This is called, when the button is clicked.
|
|
35
|
-
*/
|
|
36
|
-
onClick: Function,
|
|
37
|
-
...nToolTipPropsForImplementor,
|
|
38
|
-
});
|
|
39
|
-
/**
|
|
40
|
-
* The `NButton` is a styled button.
|
|
41
|
-
*/
|
|
42
|
-
export default createComponent('NButton', nButtonProps, (props, { slots }) => {
|
|
43
|
-
const isDisabled = computed(() => props.loading || props.disabled);
|
|
44
|
-
return () => (<NTooltip {...mapTooltipProps(props)}>
|
|
45
|
-
<button disabled={isDisabled.value} type={props.type} class={[
|
|
46
|
-
`block w-full font-medium rounded-md focus:outline-none focus-visible:ring-2 shadow text-${props.color}-900 relative`,
|
|
47
|
-
isDisabled.value
|
|
48
|
-
? `bg-${props.color}-100 text-opacity-20 cursor-default`
|
|
49
|
-
: `bg-${props.color}-200 hover:bg-${props.color}-300 focus-visible:ring-${props.color}-500`,
|
|
50
|
-
props.small ? 'py-1 px-2 text-xs' : 'py-2 px-4 text-sm',
|
|
51
|
-
]} onClick={props.onClick}>
|
|
52
|
-
<span class={{ 'opacity-10': props.loading }}>{slots.default?.()}</span>
|
|
53
|
-
{props.loading && (<div class="absolute inset-0 flex items-center justify-center opacity-50">
|
|
54
|
-
<NLoadingIndicator color={props.color} size={props.small ? 4 : 6} shade={600}/>
|
|
55
|
-
</div>)}
|
|
56
|
-
</button>
|
|
57
|
-
</NTooltip>);
|
|
58
|
-
});
|
package/components/NCheckbox.jsx
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { createComponent, createProps } from '../utils/component';
|
|
2
|
-
import { vModelProps } from '../utils/vModel';
|
|
3
|
-
import { nextTick, ref } from 'vue';
|
|
4
|
-
export const nCheckboxProps = createProps({
|
|
5
|
-
...vModelProps(Boolean),
|
|
6
|
-
/**
|
|
7
|
-
* The color of the checkbox.
|
|
8
|
-
*/
|
|
9
|
-
color: {
|
|
10
|
-
type: String,
|
|
11
|
-
default: 'primary',
|
|
12
|
-
},
|
|
13
|
-
/**
|
|
14
|
-
* If set to `true` the checkbox is disabled and no interaction is possible.
|
|
15
|
-
*/
|
|
16
|
-
disabled: Boolean,
|
|
17
|
-
});
|
|
18
|
-
/**
|
|
19
|
-
* The `NCheckbox` is a styled checkbox.
|
|
20
|
-
*/
|
|
21
|
-
export default createComponent('NCheckbox', nCheckboxProps, props => {
|
|
22
|
-
const toggle = () => {
|
|
23
|
-
props.onUpdateValue?.(!props.value);
|
|
24
|
-
forceUpdate();
|
|
25
|
-
};
|
|
26
|
-
const checkBoxRef = ref();
|
|
27
|
-
const updateKey = ref(0);
|
|
28
|
-
const forceUpdate = () => {
|
|
29
|
-
updateKey.value += 1;
|
|
30
|
-
nextTick(() => checkBoxRef.value?.focus());
|
|
31
|
-
};
|
|
32
|
-
return () => (<input type="checkbox" ref={checkBoxRef} checked={props.value} disabled={props.disabled} onClick={toggle} key={updateKey.value} class={[
|
|
33
|
-
`h-5 w-5 border-default-300 rounded focus:outline-none focus:ring-0 focus-visible:ring-2 focus-visible:ring-${props.color}-500`,
|
|
34
|
-
props.disabled
|
|
35
|
-
? `cursor-default bg-default-100 text-${props.color}-200`
|
|
36
|
-
: `cursor-pointer text-${props.color}-400`,
|
|
37
|
-
]}/>);
|
|
38
|
-
});
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { createComponent, createProps } from '../utils/component';
|
|
2
|
-
import NCheckbox, { nCheckboxProps } from './NCheckbox';
|
|
3
|
-
export const nCheckboxLabelProps = createProps({
|
|
4
|
-
...nCheckboxProps,
|
|
5
|
-
/**
|
|
6
|
-
* The title of the checkbox.
|
|
7
|
-
*/
|
|
8
|
-
title: String,
|
|
9
|
-
/**
|
|
10
|
-
* The description of the checkbox.
|
|
11
|
-
*/
|
|
12
|
-
description: String,
|
|
13
|
-
/**
|
|
14
|
-
* If set to `true`, a smaller margin is applied between the label and the checkbox.
|
|
15
|
-
*/
|
|
16
|
-
compact: Boolean,
|
|
17
|
-
});
|
|
18
|
-
/**
|
|
19
|
-
* The `NCheckboxLabel` is a checkbox with a title and a description.
|
|
20
|
-
*/
|
|
21
|
-
export default createComponent('NCheckboxLabel', nCheckboxLabelProps, props => {
|
|
22
|
-
const toggleValue = () => {
|
|
23
|
-
if (!props.disabled)
|
|
24
|
-
props.onUpdateValue?.(!props.value);
|
|
25
|
-
};
|
|
26
|
-
return () => (<div class="flex items-center">
|
|
27
|
-
<NCheckbox {...props}/>
|
|
28
|
-
<div class={`${props.compact ? 'ml-2' : 'ml-3'} text-sm`}>
|
|
29
|
-
<label onClick={toggleValue} class={[
|
|
30
|
-
'font-medium select-none',
|
|
31
|
-
props.disabled ? 'text-default-300' : 'text-default-700 cursor-pointer',
|
|
32
|
-
]}>
|
|
33
|
-
{props.title}
|
|
34
|
-
</label>
|
|
35
|
-
<p class={props.disabled ? 'text-default-300' : 'text-default-500'}>
|
|
36
|
-
<span onClick={toggleValue} class={['select-none', props.disabled ? '' : 'cursor-pointer']}>
|
|
37
|
-
{props.description}
|
|
38
|
-
</span>
|
|
39
|
-
</p>
|
|
40
|
-
</div>
|
|
41
|
-
</div>);
|
|
42
|
-
});
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { trsl } from '../i18n';
|
|
2
|
-
import { createComponent, createProps } from '../utils/component';
|
|
3
|
-
import { ref } from 'vue';
|
|
4
|
-
import NButton from './NButton';
|
|
5
|
-
import NDialog from './NDialog';
|
|
6
|
-
import NFormModal, { nFormModalProps } from './NFormModal';
|
|
7
|
-
export const nCrudModalProps = createProps({
|
|
8
|
-
...nFormModalProps,
|
|
9
|
-
/**
|
|
10
|
-
* The text of the remove-button.
|
|
11
|
-
*/
|
|
12
|
-
removeText: {
|
|
13
|
-
type: String,
|
|
14
|
-
default: trsl('vue-collection.action.remove'),
|
|
15
|
-
},
|
|
16
|
-
/**
|
|
17
|
-
* The color of the remove-button.
|
|
18
|
-
*/
|
|
19
|
-
removeColor: {
|
|
20
|
-
type: String,
|
|
21
|
-
default: 'red',
|
|
22
|
-
},
|
|
23
|
-
/**
|
|
24
|
-
* The title of the dialog which appears when clicking on the remove-button.
|
|
25
|
-
*/
|
|
26
|
-
removeDialogTitle: String,
|
|
27
|
-
/**
|
|
28
|
-
* The text of the dialog which appears when clicking on the remove-button.
|
|
29
|
-
*/
|
|
30
|
-
removeDialogText: String,
|
|
31
|
-
/**
|
|
32
|
-
* The variant of the dialog which appears when clicking on the remove-button. Default is `remove`.
|
|
33
|
-
*/
|
|
34
|
-
removeDialogVariant: {
|
|
35
|
-
type: String,
|
|
36
|
-
default: 'remove',
|
|
37
|
-
},
|
|
38
|
-
/**
|
|
39
|
-
* The text of the dialog's ok-button. Is already set by the `removeDialogVariant` but can be overridden.
|
|
40
|
-
*/
|
|
41
|
-
removeDialogOkText: String,
|
|
42
|
-
/**
|
|
43
|
-
* If set to `true` the modal will close itself when `onRemove` is called.
|
|
44
|
-
*/
|
|
45
|
-
closeOnRemove: {
|
|
46
|
-
type: Boolean,
|
|
47
|
-
default: true,
|
|
48
|
-
},
|
|
49
|
-
/**
|
|
50
|
-
* This is called, when the remove-button has been clicked and the dialog has been accepted.
|
|
51
|
-
*/
|
|
52
|
-
onRemove: Function,
|
|
53
|
-
});
|
|
54
|
-
/**
|
|
55
|
-
* The `NCrudModal` is a {@link NFormModal} which has some convenience features for a CRUD-scenario.
|
|
56
|
-
* It has an integrated remove-button with a user-dialog to remove the editing element.
|
|
57
|
-
* When the dialog is accepted `onRemove` is called.
|
|
58
|
-
*/
|
|
59
|
-
export default createComponent('NCrudModal', nCrudModalProps, (props, { slots }) => {
|
|
60
|
-
const removeDialog = ref();
|
|
61
|
-
const remove = () => {
|
|
62
|
-
removeDialog.value?.show().then(result => {
|
|
63
|
-
if (result) {
|
|
64
|
-
props.onRemove?.();
|
|
65
|
-
if (props.closeOnRemove)
|
|
66
|
-
props.onUpdateValue?.(false);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
return () => (<NFormModal {...props} footer={props.footer ||
|
|
71
|
-
(({ ok, cancel }) => (<div class="flex justify-between">
|
|
72
|
-
<div>
|
|
73
|
-
<NButton color={props.removeColor} onClick={remove}>
|
|
74
|
-
{props.removeText}
|
|
75
|
-
</NButton>
|
|
76
|
-
</div>
|
|
77
|
-
<div>
|
|
78
|
-
<NButton color={props.cancelColor} onClick={cancel}>
|
|
79
|
-
{props.cancelText}
|
|
80
|
-
</NButton>
|
|
81
|
-
<NButton color={props.okColor} onClick={ok} class="ml-2" disabled={props.okDisabled}>
|
|
82
|
-
{props.okText}
|
|
83
|
-
</NButton>
|
|
84
|
-
</div>
|
|
85
|
-
</div>))}>
|
|
86
|
-
{slots.default?.()}
|
|
87
|
-
<NDialog ref={removeDialog} variant={props.removeDialogVariant} title={props.removeDialogTitle} text={props.removeDialogText} okText={props.removeDialogOkText}/>
|
|
88
|
-
</NFormModal>);
|
|
89
|
-
});
|