@naptics/vue-collection 1.0.0-beta.1 → 1.0.0-beta.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.
Files changed (200) hide show
  1. package/lib/components/NAlert.d.ts +29 -0
  2. package/lib/components/NAlert.js +84 -0
  3. package/lib/components/NBadge.d.ts +73 -0
  4. package/lib/components/NBadge.js +64 -0
  5. package/lib/components/NBreadcrub.d.ts +69 -0
  6. package/lib/components/NBreadcrub.js +71 -0
  7. package/lib/components/NButton.d.ts +64 -0
  8. package/lib/components/NButton.js +70 -0
  9. package/lib/components/NCheckbox.d.ts +20 -0
  10. package/lib/components/NCheckbox.js +43 -0
  11. package/lib/components/NCheckboxLabel.d.ts +26 -0
  12. package/lib/components/NCheckboxLabel.js +42 -0
  13. package/lib/components/NCrudModal.d.ts +118 -0
  14. package/lib/components/NCrudModal.js +120 -0
  15. package/lib/components/NDialog.d.ts +81 -0
  16. package/lib/components/NDialog.js +161 -0
  17. package/lib/components/NDropdown.d.ts +67 -0
  18. package/lib/components/NDropdown.js +115 -0
  19. package/lib/components/NDropzone.d.ts +61 -0
  20. package/lib/components/NDropzone.js +218 -0
  21. package/lib/components/NForm.d.ts +21 -0
  22. package/lib/components/NForm.js +29 -0
  23. package/lib/components/NFormModal.d.ts +75 -0
  24. package/lib/components/NFormModal.js +59 -0
  25. package/lib/components/NIconButton.d.ts +83 -0
  26. package/lib/components/NIconButton.js +88 -0
  27. package/lib/components/NIconCircle.d.ts +49 -0
  28. package/lib/components/NIconCircle.js +67 -0
  29. package/lib/components/NInput.d.ts +94 -0
  30. package/lib/components/NInput.js +110 -0
  31. package/lib/components/NInputPhone.d.ts +58 -0
  32. package/lib/components/NInputPhone.js +47 -0
  33. package/lib/components/NInputSelect.d.ts +103 -0
  34. package/lib/components/NInputSelect.js +115 -0
  35. package/lib/components/NInputSuggestion.d.ts +79 -0
  36. package/lib/components/NInputSuggestion.js +64 -0
  37. package/lib/components/NLink.d.ts +47 -0
  38. package/lib/components/NLink.js +67 -0
  39. package/lib/components/NList.d.ts +37 -0
  40. package/lib/components/NList.js +40 -0
  41. package/lib/components/NLoadingIndicator.d.ts +29 -0
  42. package/lib/components/NLoadingIndicator.js +54 -0
  43. package/lib/components/NModal.d.ts +133 -0
  44. package/lib/components/NModal.js +235 -0
  45. package/{src/lib → lib}/components/NPagination.css +1 -1
  46. package/lib/components/NPagination.d.ts +37 -0
  47. package/lib/components/NPagination.js +105 -0
  48. package/lib/components/NSearchbar.d.ts +39 -0
  49. package/lib/components/NSearchbar.js +64 -0
  50. package/lib/components/NSearchbarList.d.ts +33 -0
  51. package/lib/components/NSearchbarList.js +41 -0
  52. package/lib/components/NSelect.d.ts +82 -0
  53. package/lib/components/NSelect.js +101 -0
  54. package/lib/components/NSuggestionList.d.ts +153 -0
  55. package/lib/components/NSuggestionList.js +160 -0
  56. package/{src/lib → lib}/components/NTable.css +1 -1
  57. package/lib/components/NTable.d.ts +97 -0
  58. package/lib/components/NTable.js +128 -0
  59. package/lib/components/NTableAction.d.ts +30 -0
  60. package/lib/components/NTableAction.js +50 -0
  61. package/lib/components/NTextArea.d.ts +96 -0
  62. package/lib/components/NTextArea.js +133 -0
  63. package/{src/lib → lib}/components/NTooltip.css +1 -1
  64. package/lib/components/NTooltip.d.ts +152 -0
  65. package/lib/components/NTooltip.js +241 -0
  66. package/lib/components/NValInput.d.ts +156 -0
  67. package/lib/components/NValInput.js +113 -0
  68. package/lib/components/ValidatedForm.d.ts +39 -0
  69. package/lib/components/ValidatedForm.js +35 -0
  70. package/{src/lib/i18n/index.ts → lib/i18n/index.d.ts} +9 -23
  71. package/lib/i18n/index.js +31 -0
  72. package/lib/index.d.ts +2 -0
  73. package/lib/index.js +2 -0
  74. package/lib/utils/breakpoints.d.ts +18 -0
  75. package/lib/utils/breakpoints.js +40 -0
  76. package/lib/utils/component.d.ts +57 -0
  77. package/lib/utils/component.js +79 -0
  78. package/lib/utils/deferred.d.ts +13 -0
  79. package/lib/utils/deferred.js +17 -0
  80. package/lib/utils/identifiable.d.ts +56 -0
  81. package/lib/utils/identifiable.js +81 -0
  82. package/lib/utils/stringMaxLength.d.ts +14 -0
  83. package/lib/utils/stringMaxLength.js +23 -0
  84. package/lib/utils/tailwind.d.ts +4 -0
  85. package/lib/utils/tailwind.js +1 -0
  86. package/lib/utils/utils.d.ts +47 -0
  87. package/lib/utils/utils.js +56 -0
  88. package/{src/lib/utils/vModel.ts → lib/utils/vModel.d.ts} +48 -126
  89. package/lib/utils/vModel.js +224 -0
  90. package/lib/utils/validation.d.ts +90 -0
  91. package/lib/utils/validation.js +147 -0
  92. package/lib/utils/vue.d.ts +13 -0
  93. package/lib/utils/vue.js +21 -0
  94. package/package.json +6 -2
  95. package/.github/workflows/build.yml +0 -26
  96. package/.github/workflows/deploy-demo.yml +0 -46
  97. package/.github/workflows/deploy-lib.yml +0 -59
  98. package/.gitlab-ci.yml +0 -57
  99. package/.nvmrc +0 -1
  100. package/.prettierrc +0 -8
  101. package/.vscode/extensions.json +0 -10
  102. package/.vscode/launch.json +0 -23
  103. package/.vscode/settings.json +0 -13
  104. package/babel.config.json +0 -3
  105. package/env.d.ts +0 -15
  106. package/eslint.config.cjs +0 -27
  107. package/index.html +0 -13
  108. package/postcss.config.js +0 -3
  109. package/public/favicon.ico +0 -0
  110. package/scripts/build-lib.sh +0 -52
  111. package/scripts/sync-node-types.js +0 -70
  112. package/src/demo/App.css +0 -53
  113. package/src/demo/App.tsx +0 -5
  114. package/src/demo/components/ColorGrid.tsx +0 -26
  115. package/src/demo/components/ComponentGrid.tsx +0 -26
  116. package/src/demo/components/ComponentSection.tsx +0 -30
  117. package/src/demo/components/VariantSection.tsx +0 -18
  118. package/src/demo/i18n/de.ts +0 -7
  119. package/src/demo/i18n/en.ts +0 -7
  120. package/src/demo/i18n/index.ts +0 -24
  121. package/src/demo/main.ts +0 -13
  122. package/src/demo/router/index.ts +0 -21
  123. package/src/demo/views/HomeView.tsx +0 -94
  124. package/src/demo/views/NavigationView.tsx +0 -43
  125. package/src/demo/views/presentation/AlertView.tsx +0 -40
  126. package/src/demo/views/presentation/BadgeView.tsx +0 -61
  127. package/src/demo/views/presentation/BreadcrumbView.tsx +0 -52
  128. package/src/demo/views/presentation/ButtonView.tsx +0 -49
  129. package/src/demo/views/presentation/CheckboxView.tsx +0 -59
  130. package/src/demo/views/presentation/DropdownView.tsx +0 -59
  131. package/src/demo/views/presentation/DropzoneView.tsx +0 -39
  132. package/src/demo/views/presentation/IconButtonView.tsx +0 -47
  133. package/src/demo/views/presentation/IconCircleView.tsx +0 -38
  134. package/src/demo/views/presentation/InputView.tsx +0 -179
  135. package/src/demo/views/presentation/LinkView.tsx +0 -60
  136. package/src/demo/views/presentation/ListView.tsx +0 -29
  137. package/src/demo/views/presentation/LoadingIndicatorView.tsx +0 -38
  138. package/src/demo/views/presentation/ModalView.tsx +0 -210
  139. package/src/demo/views/presentation/PaginationView.tsx +0 -25
  140. package/src/demo/views/presentation/SearchbarView.tsx +0 -80
  141. package/src/demo/views/presentation/TableView.tsx +0 -146
  142. package/src/demo/views/presentation/TooltipView.tsx +0 -92
  143. package/src/lib/components/NAlert.tsx +0 -85
  144. package/src/lib/components/NBadge.tsx +0 -75
  145. package/src/lib/components/NBreadcrub.tsx +0 -97
  146. package/src/lib/components/NButton.tsx +0 -82
  147. package/src/lib/components/NCheckbox.tsx +0 -55
  148. package/src/lib/components/NCheckboxLabel.tsx +0 -51
  149. package/src/lib/components/NCrudModal.tsx +0 -133
  150. package/src/lib/components/NDialog.tsx +0 -182
  151. package/src/lib/components/NDropdown.tsx +0 -169
  152. package/src/lib/components/NDropzone.tsx +0 -265
  153. package/src/lib/components/NForm.tsx +0 -32
  154. package/src/lib/components/NFormModal.tsx +0 -66
  155. package/src/lib/components/NIconButton.tsx +0 -92
  156. package/src/lib/components/NIconCircle.tsx +0 -78
  157. package/src/lib/components/NInput.tsx +0 -139
  158. package/src/lib/components/NInputPhone.tsx +0 -53
  159. package/src/lib/components/NInputSelect.tsx +0 -126
  160. package/src/lib/components/NInputSuggestion.tsx +0 -80
  161. package/src/lib/components/NLink.tsx +0 -82
  162. package/src/lib/components/NList.tsx +0 -67
  163. package/src/lib/components/NLoadingIndicator.tsx +0 -63
  164. package/src/lib/components/NModal.tsx +0 -243
  165. package/src/lib/components/NPagination.tsx +0 -131
  166. package/src/lib/components/NSearchbar.tsx +0 -78
  167. package/src/lib/components/NSearchbarList.tsx +0 -47
  168. package/src/lib/components/NSelect.tsx +0 -128
  169. package/src/lib/components/NSuggestionList.tsx +0 -216
  170. package/src/lib/components/NTable.tsx +0 -247
  171. package/src/lib/components/NTableAction.tsx +0 -49
  172. package/src/lib/components/NTextArea.tsx +0 -159
  173. package/src/lib/components/NTooltip.tsx +0 -289
  174. package/src/lib/components/NValInput.tsx +0 -163
  175. package/src/lib/components/ValidatedForm.ts +0 -71
  176. package/src/lib/components/__tests__/NButton.spec.tsx +0 -26
  177. package/src/lib/components/__tests__/NCheckbox.spec.tsx +0 -39
  178. package/src/lib/index.ts +0 -2
  179. package/src/lib/jsx.d.ts +0 -13
  180. package/src/lib/utils/__tests__/identifiable.spec.ts +0 -72
  181. package/src/lib/utils/__tests__/validation.spec.ts +0 -92
  182. package/src/lib/utils/breakpoints.ts +0 -47
  183. package/src/lib/utils/component.tsx +0 -131
  184. package/src/lib/utils/deferred.ts +0 -28
  185. package/src/lib/utils/identifiable.ts +0 -87
  186. package/src/lib/utils/stringMaxLength.ts +0 -25
  187. package/src/lib/utils/tailwind.ts +0 -41
  188. package/src/lib/utils/utils.ts +0 -90
  189. package/src/lib/utils/validation.ts +0 -189
  190. package/src/lib/utils/vue.ts +0 -25
  191. package/tsconfig.config.json +0 -9
  192. package/tsconfig.demo.json +0 -19
  193. package/tsconfig.json +0 -16
  194. package/tsconfig.lib.json +0 -19
  195. package/tsconfig.vitest.json +0 -8
  196. package/vite.config.ts +0 -30
  197. /package/{src/lib → lib}/components/NInput.css +0 -0
  198. /package/{src/lib → lib}/components/NLoadingIndicator.css +0 -0
  199. /package/{src/lib → lib}/i18n/de/vue-collection.json +0 -0
  200. /package/{src/lib → lib}/i18n/en/vue-collection.json +0 -0
@@ -0,0 +1,224 @@
1
+ /*
2
+ * ---------- VModel as Props ----------
3
+ */
4
+ /**
5
+ * Creates props for a `v-model` of the given type.
6
+ * A `v-model` consits of a value-property and a update-function.
7
+ * @param propType The propType of the `v-model`.
8
+ * @returns An object containing the value-property and the update-function.
9
+ */
10
+ export function vModelProps(propType) {
11
+ return {
12
+ /**
13
+ * The value of the component.
14
+ */
15
+ value: propType,
16
+ /**
17
+ * This will be called, when the value of the component has changed.
18
+ */
19
+ onUpdateValue: Function
20
+ };
21
+ }
22
+ /**
23
+ * Creates props for a required `v-model` of the given type.
24
+ * @see {@link vModelProps}
25
+ */
26
+ export function vModelRequiredProps(propType) {
27
+ return {
28
+ /**
29
+ * The value of the component.
30
+ */
31
+ value: {
32
+ type: propType,
33
+ required: true
34
+ },
35
+ /**
36
+ * This will be called, when the value of the component has changed.
37
+ */
38
+ onUpdateValue: Function
39
+ };
40
+ }
41
+ /**
42
+ * Creates props for a `v-model` of the given type with a default value.
43
+ * @see {@link vModelProps}
44
+ */
45
+ export function vModelDefaultProps(propType, defaultValue) {
46
+ return {
47
+ /**
48
+ * The value of the component.
49
+ */
50
+ value: {
51
+ type: propType,
52
+ default: defaultValue
53
+ },
54
+ /**
55
+ * This will be called, when the value of the component has changed.
56
+ */
57
+ onUpdateValue: Function
58
+ };
59
+ }
60
+ /**
61
+ * Uses the given `ref` as a `v-model`, to create a two-way binding with the `ref`.
62
+ * @param ref The `ref` which should be used as the `v-model`.
63
+ * @returns An object of type {@link VModel}, which connects the `ref` to the `v-model`.
64
+ */
65
+ export function vModelForRef(ref) {
66
+ return {
67
+ value: ref.value,
68
+ onUpdateValue: newValue => {
69
+ ref.value = newValue;
70
+ }
71
+ };
72
+ }
73
+ /**
74
+ * This creates a `v-model` for a property of an object. The property of the object is taken as the
75
+ * value of the `v-model`, the `onUpdate` function, is called every time when the property is updated
76
+ * with the whole object and its updated property.
77
+ * @param object The object which contains the relevant property.
78
+ * @param key The key of the property which should be used as the v-model.
79
+ * @param onUpdate The updater function which is called with the entire object when the property has changed.
80
+ * @returns An object containing of type {@link VModel}.
81
+ * @example
82
+ * ```tsx
83
+ * // inside setup function
84
+ * const customer = ref({ firstName: 'Hansi', lastName: 'Halunk' })
85
+ *
86
+ * // This input needs a v-model for the `firstName` property.
87
+ * return () => (
88
+ * <NInput
89
+ * name="First Name"
90
+ * {...vModelForObjectProperty(customer.value, 'firstName', newVal => (customer.value = newValue))}
91
+ * />
92
+ * )
93
+ * ```
94
+ */
95
+ export function vModelForObjectProperty(object, key, onUpdate) {
96
+ return {
97
+ value: object[key],
98
+ onUpdateValue: newValue => {
99
+ onUpdate?.({
100
+ ...object,
101
+ [key]: newValue
102
+ });
103
+ }
104
+ };
105
+ }
106
+ /**
107
+ * This creates a `v-model` which operates on one property of a parent `v-model`. It takes the value of
108
+ * the property as the value of the `v-model` and calls the function `onUpdateValue` of the parent `v-model`
109
+ * whenever the property changes. This function can be seen as a kind of mapper for a `v-model`.
110
+ * @param vModel The parent `v-model`, which this function extracts a single property from.
111
+ * @param key The key of the relevant property.
112
+ * @returns An object of type {@link VModel}.
113
+ * @example
114
+ * ```tsx
115
+ * type Customer = { firstName: string, lastName: String }
116
+ *
117
+ * // inside setup function,
118
+ * // This vModel would normally be inside the props of a component e.g., `CustomerEditor`.
119
+ * const parentVModel = {
120
+ * value: { firstName: 'Hansi', lastName: 'Halunk' },
121
+ * onUpdateValue: (newValue: Customer) => {
122
+ * // update something
123
+ * }
124
+ * }
125
+ *
126
+ * // This input needs a v-model for the `firstName` property.
127
+ * return () => (
128
+ * <NInput
129
+ * name="First Name"
130
+ * {...vModelForVModelProperty(parentVModel, 'firstName'))}
131
+ * />
132
+ * )
133
+ * ```
134
+ */
135
+ export function vModelForVModelProperty(vModel, key) {
136
+ return {
137
+ value: vModel.value[key],
138
+ onUpdateValue: newValue => {
139
+ vModel.onUpdateValue?.({
140
+ ...vModel.value,
141
+ [key]: newValue
142
+ });
143
+ }
144
+ };
145
+ }
146
+ /**
147
+ * This function does the same thing as {@link vModelForVModelProperty},
148
+ * but can be provided with a mapper function for the modified property.
149
+ * @see {@link vModelForVModelProperty}
150
+ * @example
151
+ * ```tsx
152
+ * type Customer = { firstName: string, lastName: String, type: 'admin' | 'user' }
153
+ *
154
+ * // inside setup function,
155
+ * // This vModel would normally be inside the props of a component e.g., `CustomerEditor`.
156
+ * const parentVModel = {
157
+ * value: { firstName: 'Hansi', lastName: 'Halunk', type: 'user' },
158
+ * onUpdateValue: (newValue: Customer) => {
159
+ * // update something
160
+ * }
161
+ * }
162
+ *
163
+ * // This input needs a v-model for the `type` property.
164
+ * // Unfortunately the NSelect input expects an `onUpdateValue` with a
165
+ * // parameter of type `string`, not type `admin | user`.
166
+ * // So we have to provide a mapper function from `string` to `admin | user`.
167
+ * // In this example, we just cast the value.
168
+ * return () => (
169
+ * <NSelect
170
+ * name="Type"
171
+ * {...vModelForVModelPropertyMapType(parentVModel, 'type', newVal => newVal as 'admin' | 'user'))}
172
+ * />
173
+ * )
174
+ * ```
175
+ */
176
+ export function vModelForVModelPropertyMapType(vModel, key, mapType) {
177
+ return {
178
+ value: vModel.value[key],
179
+ onUpdateValue: newValue => {
180
+ vModel.onUpdateValue?.({
181
+ ...vModel.value,
182
+ [key]: mapType(newValue)
183
+ });
184
+ }
185
+ };
186
+ }
187
+ /**
188
+ * Creates an array of `v-models`, one for every element of an array. All changes in
189
+ * a `v-model` of any element, will call the `onUpdate` function, with the updated array.
190
+ * @param array The array to create `v-models` for.
191
+ * @param onUpdate The updater function, which is called whenever an element has changed.
192
+ * @returns An object of type {@link VModelForArray}.
193
+ * @example
194
+ * ```tsx
195
+ * // inside setup function
196
+ * const todos = ref([
197
+ * 'Create v-model helper functions.',
198
+ * 'Document them!'
199
+ * ])
200
+ *
201
+ * // For every todo, there should be an input to modifiy it.
202
+ * return () => (
203
+ * <div>
204
+ * {vModelsForArray(todos.value, newValue => (todos.value = newValue)).map(todoVModel => (
205
+ * <NInput name="Todo" {...todoVModel} />
206
+ * ))}
207
+ * </div>
208
+ * )
209
+ * ```
210
+ */
211
+ export function vModelsForArray(array, onUpdate) {
212
+ return array.map((entry, index) => ({
213
+ value: entry,
214
+ onUpdateValue: entry => {
215
+ const newArray = [...array];
216
+ newArray[index] = entry;
217
+ onUpdate?.(newArray);
218
+ },
219
+ remove: () => {
220
+ const newArray = [...array.slice(0, index), ...array.slice(index + 1)];
221
+ onUpdate?.(newArray);
222
+ }
223
+ }));
224
+ }
@@ -0,0 +1,90 @@
1
+ export type ValidationResultValid = {
2
+ isValid: true;
3
+ errorMessage?: undefined;
4
+ };
5
+ export type ValidationResultInvalid = {
6
+ isValid: false;
7
+ errorMessage: string;
8
+ };
9
+ export type InputValue = string | null | undefined;
10
+ export type ValidationResult = ValidationResultValid | ValidationResultInvalid;
11
+ /**
12
+ * A `ValidationRule` checks an input for a criteria and returns either
13
+ * a {@link ValidationResultValid} or a {@link ValidationResultInvalid}.
14
+ * A falsy input-value should always return a valid result to not interfere
15
+ * with the {@link required} rule.
16
+ */
17
+ export type ValidationRule = (input: InputValue) => ValidationResult;
18
+ /**
19
+ * Creates a valid result.
20
+ */
21
+ export declare function validResult(): ValidationResultValid;
22
+ /**
23
+ * Creates an invalid result with the provided error message.
24
+ */
25
+ export declare function invalidResult(errorMessage: string): ValidationResultInvalid;
26
+ /**
27
+ * Validates a given input with the specified rules.
28
+ * The rules are evaluated in the order they're in the array.
29
+ * The {@link ValidationResult} will either contain the errorMessage of the failed rule
30
+ * or a valid result if all rules passed.
31
+ * @param input the input to validate.
32
+ * @param rules the rules which should be vaildated, in the order of priority.
33
+ * @returns an object containing the result of the validation.
34
+ */
35
+ export declare function validate(input: InputValue, rules: ValidationRule[]): ValidationResult;
36
+ /**
37
+ * This rule expects the trimmed input-value to be truthy.
38
+ */
39
+ export declare const required: ValidationRule;
40
+ /**
41
+ * This rule expects the input to be an integer.
42
+ */
43
+ export declare const integer: ValidationRule;
44
+ /**
45
+ * This rule expects the input to be in the specified length range. An empty input
46
+ * will always be allowed by this rule to not interefere with the {@link required} rule.
47
+ * @param min The minimum length of the string.
48
+ * @param max The maximum length of the string.
49
+ */
50
+ export declare function length(min: number | undefined, max: number | undefined): ValidationRule;
51
+ /**
52
+ * This rule expects the input to be a number in the specified range.
53
+ * @param min the lower bound, if `undefined` there is no lower bound.
54
+ * @param max the upper bound, if `undefined` there is no upper bound.
55
+ */
56
+ export declare function numberRange(min: number | undefined, max: number | undefined): ValidationRule;
57
+ export declare const VALIDATION_FORMAT_EMAIL: RegExp;
58
+ /**
59
+ * This rule expects the input-value to be a valid email adress matching {@link VALIDATION_FORMAT_EMAIL}.
60
+ */
61
+ export declare const email: ValidationRule;
62
+ export declare const VALIDATION_FORMAT_PASSWORD: RegExp;
63
+ /**
64
+ * This rule expects the input-value to be a password matching {@link VALIDATION_FORMAT_PASSWORD}.
65
+ */
66
+ export declare const password: ValidationRule;
67
+ /**
68
+ * This rule expects the input-value to match another (input-) value.
69
+ * In difference to most other rules, this rule does not always return a valid result,
70
+ * when the input is falsy. The input is always required to match the other value.
71
+ * @param other the other value to match
72
+ */
73
+ export declare function matches(other: string | null | undefined): ValidationRule;
74
+ /**
75
+ * This rule expects the input-value to match one option in an array.
76
+ * @param options the options which the input can match
77
+ */
78
+ export declare function option(options: string[]): ValidationRule;
79
+ /**
80
+ * This rule expects the input-value to match the regex pattern
81
+ * @param pattern the pattern the input should match.
82
+ */
83
+ export declare function regex(pattern: RegExp): ValidationRule;
84
+ /**
85
+ * This rule can be used if the validation logic happens somewhere else.
86
+ * When `isValid = true` is passed, the function will return a valid result,
87
+ * otherwise it will return the invalid result with the passed `errorKey`.
88
+ * Like always, a falsy input is always valid to not interefere with the {@link required} rule.
89
+ */
90
+ export declare function external(isValid: boolean, errorMessage: string): ValidationRule;
@@ -0,0 +1,147 @@
1
+ import { trsl } from '../i18n';
2
+ /**
3
+ * Creates a valid result.
4
+ */
5
+ export function validResult() {
6
+ return {
7
+ isValid: true
8
+ };
9
+ }
10
+ /**
11
+ * Creates an invalid result with the provided error message.
12
+ */
13
+ export function invalidResult(errorMessage) {
14
+ return {
15
+ isValid: false,
16
+ errorMessage
17
+ };
18
+ }
19
+ const TRANSLATION_KEY_BASE = 'vue-collection.validation.rules';
20
+ function invalidResultInternal(key, params) {
21
+ return invalidResult(trsl(`${TRANSLATION_KEY_BASE}.${key}`, params));
22
+ }
23
+ /**
24
+ * Validates a given input with the specified rules.
25
+ * The rules are evaluated in the order they're in the array.
26
+ * The {@link ValidationResult} will either contain the errorMessage of the failed rule
27
+ * or a valid result if all rules passed.
28
+ * @param input the input to validate.
29
+ * @param rules the rules which should be vaildated, in the order of priority.
30
+ * @returns an object containing the result of the validation.
31
+ */
32
+ export function validate(input, rules) {
33
+ for (const rule of rules) {
34
+ const validationResult = rule(input);
35
+ if (!validationResult.isValid) return validationResult;
36
+ }
37
+ return validResult();
38
+ }
39
+ /*
40
+ * ---------- Validation Rules ----------
41
+ */
42
+ /**
43
+ * This rule expects the trimmed input-value to be truthy.
44
+ */
45
+ export const required = input => {
46
+ const trimmed = input?.trim();
47
+ if (trimmed) return validResult();else return invalidResultInternal('required');
48
+ };
49
+ /**
50
+ * This rule expects the input to be an integer.
51
+ */
52
+ export const integer = input => {
53
+ if (!input || Number.isInteger(+input)) return validResult();else return invalidResultInternal('integer');
54
+ };
55
+ /**
56
+ * This rule expects the input to be in the specified length range. An empty input
57
+ * will always be allowed by this rule to not interefere with the {@link required} rule.
58
+ * @param min The minimum length of the string.
59
+ * @param max The maximum length of the string.
60
+ */
61
+ export function length(min, max) {
62
+ return input => {
63
+ if (!input) return validResult();
64
+ if (min !== undefined && max !== undefined && !(min <= input.length && input.length <= max)) return invalidResultInternal('length.min-max', {
65
+ min,
66
+ max
67
+ });else if (min !== undefined && !(min <= input.length)) return invalidResultInternal('length.min', {
68
+ min
69
+ });else if (max !== undefined && !(input.length <= max)) return invalidResultInternal('length.max', {
70
+ max
71
+ });
72
+ return validResult();
73
+ };
74
+ }
75
+ /**
76
+ * This rule expects the input to be a number in the specified range.
77
+ * @param min the lower bound, if `undefined` there is no lower bound.
78
+ * @param max the upper bound, if `undefined` there is no upper bound.
79
+ */
80
+ export function numberRange(min, max) {
81
+ return input => {
82
+ if (!input) return validResult();
83
+ const parsed = Number.parseFloat(input);
84
+ if (Number.isNaN(parsed)) return invalidResultInternal('number-range.nan');
85
+ if (min !== undefined && max !== undefined && !(min <= parsed && parsed <= max)) return invalidResultInternal('number-range.min-max', {
86
+ min,
87
+ max
88
+ });else if (min !== undefined && !(min <= parsed)) return invalidResultInternal('number-range.min', {
89
+ min
90
+ });else if (max !== undefined && !(parsed <= max)) return invalidResultInternal('number-range.max', {
91
+ max
92
+ });
93
+ return validResult();
94
+ };
95
+ }
96
+ export const VALIDATION_FORMAT_EMAIL = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/;
97
+ /**
98
+ * This rule expects the input-value to be a valid email adress matching {@link VALIDATION_FORMAT_EMAIL}.
99
+ */
100
+ export const email = input => {
101
+ if (!input || VALIDATION_FORMAT_EMAIL.test(input)) return validResult();else return invalidResultInternal('email');
102
+ };
103
+ export const VALIDATION_FORMAT_PASSWORD = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$^+\-=!*()@%&?]).{8,}$/;
104
+ /**
105
+ * This rule expects the input-value to be a password matching {@link VALIDATION_FORMAT_PASSWORD}.
106
+ */
107
+ export const password = input => {
108
+ if (!input || VALIDATION_FORMAT_PASSWORD.test(input)) return validResult();else if (input.length < 8) return invalidResultInternal('password.to-short');else if (!/[a-z]+/.test(input)) return invalidResultInternal('password.no-lowercase');else if (!/[A-Z]+/.test(input)) return invalidResultInternal('password.no-uppercase');else if (!/\d+/.test(input)) return invalidResultInternal('password.no-digits');else if (!/[#$^+\-=!*()@%&?]+/.test(input)) return invalidResultInternal('password.no-special-chars');else return invalidResultInternal('password.unknown');
109
+ };
110
+ /**
111
+ * This rule expects the input-value to match another (input-) value.
112
+ * In difference to most other rules, this rule does not always return a valid result,
113
+ * when the input is falsy. The input is always required to match the other value.
114
+ * @param other the other value to match
115
+ */
116
+ export function matches(other) {
117
+ return input => {
118
+ if (input === other) return validResult();else return invalidResultInternal('matches');
119
+ };
120
+ }
121
+ /**
122
+ * This rule expects the input-value to match one option in an array.
123
+ * @param options the options which the input can match
124
+ */
125
+ export function option(options) {
126
+ return input => {
127
+ if (!input || options.includes(input || '')) return validResult();else return invalidResultInternal('option');
128
+ };
129
+ }
130
+ /**
131
+ * This rule expects the input-value to match the regex pattern
132
+ * @param pattern the pattern the input should match.
133
+ */
134
+ export function regex(pattern) {
135
+ return input => {
136
+ if (!input || pattern.test(input || '')) return validResult();else return invalidResultInternal('regex');
137
+ };
138
+ }
139
+ /**
140
+ * This rule can be used if the validation logic happens somewhere else.
141
+ * When `isValid = true` is passed, the function will return a valid result,
142
+ * otherwise it will return the invalid result with the passed `errorKey`.
143
+ * Like always, a falsy input is always valid to not interefere with the {@link required} rule.
144
+ */
145
+ export function external(isValid, errorMessage) {
146
+ return input => !input || isValid ? validResult() : invalidResult(errorMessage);
147
+ }
@@ -0,0 +1,13 @@
1
+ import { type Ref, type ComputedRef } from 'vue';
2
+ /**
3
+ * Creates a watcher on the updater function, which sets the value of the ref on every change.
4
+ * @param ref the ref to update
5
+ * @param updater the updater funtion which provides the updates
6
+ */
7
+ export declare function updateWith<T>(ref: Ref<T>, updater: () => T): void;
8
+ /**
9
+ * Conveience function to create a watcher for a ref
10
+ * @param ref the ref to watch
11
+ * @param onChange the function, which is executed on change of a value
12
+ */
13
+ export declare function watchRef<T>(ref: Ref<T> | ComputedRef<T>, onChange: (newValue: T) => void): void;
@@ -0,0 +1,21 @@
1
+ import { watch } from 'vue';
2
+ /**
3
+ * Creates a watcher on the updater function, which sets the value of the ref on every change.
4
+ * @param ref the ref to update
5
+ * @param updater the updater funtion which provides the updates
6
+ */
7
+ export function updateWith(ref, updater) {
8
+ watch(updater, newValue => {
9
+ ref.value = newValue;
10
+ }, {
11
+ immediate: true
12
+ });
13
+ }
14
+ /**
15
+ * Conveience function to create a watcher for a ref
16
+ * @param ref the ref to watch
17
+ * @param onChange the function, which is executed on change of a value
18
+ */
19
+ export function watchRef(ref, onChange) {
20
+ watch(() => ref.value, onChange);
21
+ }
package/package.json CHANGED
@@ -2,13 +2,17 @@
2
2
  "name": "@naptics/vue-collection",
3
3
  "author": "Timo Siegenthaler and Jonas Schoch",
4
4
  "description": "Vue Collection is a collection of styled and fully functional Vue components which can easily be integrated into our projects.",
5
- "version": "1.0.0-beta.1",
6
- "main": "./index.js",
5
+ "version": "1.0.0-beta.2",
6
+ "main": "./lib/index.js",
7
+ "files": [
8
+ "lib/"
9
+ ],
7
10
  "repository": {
8
11
  "type": "git",
9
12
  "url": "https://github.com/naptics/vue-collection"
10
13
  },
11
14
  "scripts": {
15
+ "prepack": "npm run build-lib",
12
16
  "dev": "vite",
13
17
  "lint": "eslint . --fix --ignore-pattern=.gitignore",
14
18
  "type-check": "run-p type-check-lib type-check-demo",
@@ -1,26 +0,0 @@
1
- name: Lint, Type-Check, Build & Test
2
-
3
- on:
4
- push:
5
- branches:
6
- - '**'
7
-
8
- jobs:
9
- build:
10
- name: Lint, Type-Check, Build & Test
11
- runs-on: ubuntu-latest
12
- steps:
13
- - name: Checkout repository
14
- uses: actions/checkout@v4
15
- - name: Read .nvmrc
16
- run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_OUTPUT
17
- id: nvm
18
- - name: Setup node environment
19
- uses: actions/setup-node@v4
20
- with:
21
- node-version: ${{ steps.nvm.outputs.NVMRC }}
22
- - run: npm ci
23
- - run: npm run lint
24
- - run: npm run build-lib
25
- - run: npm run build-demo
26
- - run: npm run test
@@ -1,46 +0,0 @@
1
- name: Deploy Demo App to Github Pages
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
-
8
- permissions:
9
- contents: read
10
- pages: write
11
- id-token: write
12
-
13
- env:
14
- VITE_BASE_PATH: vue-collection/
15
-
16
- jobs:
17
- build:
18
- name: Lint, Type-Check, Build & Test
19
- runs-on: ubuntu-latest
20
- steps:
21
- - name: Checkout repository
22
- uses: actions/checkout@v4
23
- - name: Setup Pages
24
- uses: actions/configure-pages@v5
25
- - name: Read .nvmrc
26
- run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_OUTPUT
27
- id: nvm
28
- - name: Setup node environment
29
- uses: actions/setup-node@v4
30
- with:
31
- node-version: ${{ steps.nvm.outputs.NVMRC }}
32
- - run: npm ci
33
- - run: npm run lint
34
- - run: npm run build-demo
35
- - run: npm run test
36
- - name: Upload demo as artifact
37
- uses: actions/upload-pages-artifact@v3
38
- with:
39
- path: 'dist'
40
- deploy:
41
- name: Deploy Demo App To Github Pages
42
- needs: build
43
- runs-on: ubuntu-latest
44
- steps:
45
- - name: Deploy to GitHub Pages
46
- uses: actions/deploy-pages@v4
@@ -1,59 +0,0 @@
1
- name: Deploy Library to npm
2
-
3
- on:
4
- push:
5
- tags:
6
- - v*
7
-
8
- jobs:
9
- build:
10
- name: Lint, Type-Check, Build & Test
11
- runs-on: ubuntu-latest
12
- steps:
13
- - name: Checkout repository
14
- uses: actions/checkout@v4
15
- - name: Read .nvmrc
16
- run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_OUTPUT
17
- id: nvm
18
- - name: Setup node environment
19
- uses: actions/setup-node@v4
20
- with:
21
- node-version: ${{ steps.nvm.outputs.NVMRC }}
22
- - run: npm ci
23
- - run: npm run lint
24
- - run: npm run build-lib
25
- - run: npm run test
26
- - name: Upload library as artifact
27
- uses: actions/upload-artifact@v4
28
- with:
29
- name: vue-collection-lib
30
- path: |
31
- lib
32
- .npmrc
33
- package.json
34
- README.md
35
- deploy:
36
- name: Deploy Library to npm
37
- needs: build
38
- runs-on: ubuntu-latest
39
- permissions:
40
- id-token: write # Required for OIDC
41
- contents: read
42
- steps:
43
- - name: Checkout repository
44
- uses: actions/checkout@v4
45
- - name: Read .nvmrc
46
- run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_OUTPUT
47
- id: nvm
48
- - name: Setup node environment
49
- uses: actions/setup-node@v4
50
- with:
51
- node-version: ${{ steps.nvm.outputs.NVMRC }}
52
- registry-url: https://registry.npmjs.org/
53
- - name: Download library artifact
54
- uses: actions/download-artifact@v4
55
- with:
56
- name: vue-collection-lib
57
- - name: Prepare folder structure
58
- run: mv ./lib/* .
59
- - run: npm publish --access=public