@yamato-daiwa/frontend-vue 0.1.0 → 0.3.0-alpha.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.

Potentially problematic release.


This version of @yamato-daiwa/frontend-vue might be problematic. Click here for more details.

Files changed (70) hide show
  1. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  2. package/.idea/inspectionProfiles/Project_Default.xml +0 -1
  3. package/README.md +13 -2
  4. package/Source/Functions/getElementByVueReference.ts +105 -8
  5. package/Source/GUI_Components/AdmonitionBlock/AdmonitionBlock.vue +67 -0
  6. package/Source/GUI_Components/AdmonitionBlock/AdmonitionBlock.vue.d.ts +48 -0
  7. package/Source/GUI_Components/AdmonitionBlock/{AdmonitionBlock.vue.ts → AdmonitionBlockLogic.vue.ts} +88 -64
  8. package/Source/GUI_Components/Badge/Badge.vue.ts +103 -68
  9. package/Source/GUI_Components/Badge/LoadingPlaceholder/Badge-LoadingPlaceholder.vue.ts +52 -33
  10. package/Source/GUI_Components/Controls/Buttons/Closing/ClosingButton.vue.pug +1 -0
  11. package/Source/GUI_Components/Controls/Buttons/Closing/ClosingButton.vue.ts +224 -0
  12. package/Source/GUI_Components/Controls/Buttons/HamburgerMenu/HamburgerMenuButton-ForInheritance.vue.ts +253 -0
  13. package/Source/GUI_Components/Controls/Buttons/HamburgerMenu/HamburgerMenuButton.vue +24 -0
  14. package/Source/GUI_Components/Controls/Buttons/HamburgerMenu/HamburgerMenuButton.vue.d.ts +45 -0
  15. package/Source/GUI_Components/Controls/Buttons/HamburgerMenu/HamburgerMenuButton.vue.pug +0 -0
  16. package/Source/GUI_Components/Controls/Buttons/Plain/Button.vue.pug +5 -7
  17. package/Source/GUI_Components/Controls/Buttons/Plain/Button.vue.ts +257 -116
  18. package/Source/GUI_Components/Controls/Buttons/Plain/LoadingPlaceholder/Button-LoadingPlaceholder.vue.pug +1 -1
  19. package/Source/GUI_Components/Controls/Buttons/Plain/LoadingPlaceholder/Button-LoadingPlaceholder.vue.ts +42 -33
  20. package/Source/GUI_Components/Controls/ValidatableControlShell/ValidatableControlShell.vue.pug +64 -0
  21. package/Source/GUI_Components/Controls/ValidatableControlShell/ValidatableControlShell.vue.ts +478 -0
  22. package/Source/GUI_Components/Controls/Validatables/InputtableControl.vue.ts +233 -0
  23. package/Source/GUI_Components/Controls/Validatables/TextBox/TextBox.vue.pug +67 -0
  24. package/Source/GUI_Components/Controls/Validatables/TextBox/TextBox.vue.ts +702 -0
  25. package/Source/GUI_Components/Controls/{ValidatableControl.ts → Validatables/ValidatableControl.ts} +64 -55
  26. package/Source/GUI_Components/Controls/Validatables/ValidatableControlsGroup.ts +176 -0
  27. package/Source/GUI_Components/OverflowSafeSingleLineLabel.vue +9 -2
  28. package/Source/GUI_Components/ThemesShowcase.vue +10 -5
  29. package/Source/GUI_Components/YDF_ComponentsCoordinator.ts +317 -0
  30. package/Source/GUI_Components/_Decorators/AccessibleFromTemplateAsNonReactive.ts +67 -0
  31. package/Source/GUI_Components/_Decorators/NonReactiveVueData.ts +26 -0
  32. package/Source/GUI_Components/_Decorators/preventNullForOptionalVueProperty.ts +64 -0
  33. package/Source/GUI_Components/_Errors/ForbiddenNullValueOfOptionalVueProperty/ForbiddenNullValueOfOptionalVuePropertyError.ts +47 -0
  34. package/Source/GUI_Components/_Errors/ForbiddenNullValueOfOptionalVueProperty/ForbiddenNullValueOfOptionalVuePropertyErrorLocalization.english.ts +24 -0
  35. package/Source/GUI_Components/_Errors/InvalidVueProperty/InvalidVuePropertyError.ts +43 -0
  36. package/Source/GUI_Components/_Errors/InvalidVueProperty/InvalidVuePropertyErrorLocalization.english.ts +16 -0
  37. package/Source/GUI_Components/_VuePropertiesValidators/BooleanVuePropertyValidator.ts +25 -0
  38. package/Source/GUI_Components/_VuePropertiesValidators/DecorativeModifiersVuePropertyValidator.ts +22 -0
  39. package/Source/GUI_Components/_VuePropertiesValidators/DecorativeVariationVuePropertyValidator.ts +23 -0
  40. package/Source/GUI_Components/_VuePropertiesValidators/ElementOfEnumerationVuePropertyValidator.ts +29 -0
  41. package/Source/GUI_Components/_VuePropertiesValidators/GeometricModifiersVuePropertyValidator.ts +22 -0
  42. package/Source/GUI_Components/_VuePropertiesValidators/GeometricVariationVuePropertyValidator.ts +23 -0
  43. package/Source/GUI_Components/_VuePropertiesValidators/NaturalNumberOrZeroVuePropertyValidator.ts +25 -0
  44. package/Source/GUI_Components/_VuePropertiesValidators/NonEmptyStringVuePropertyValidator.ts +25 -0
  45. package/Source/GUI_Components/_VuePropertiesValidators/ThemeVuePropertyValidator.ts +23 -0
  46. package/Source/GUI_Components/_VuePropertiesValidators/VuePropertyValidator.ts +51 -0
  47. package/Source/index.ts +28 -5
  48. package/Workbenches/Source/Decorators/Decorators.workbench.pug +20 -0
  49. package/Workbenches/Source/Decorators/Decorators.workbench.ts +5 -0
  50. package/Workbenches/Source/Decorators/DecoratorsWorkbench.vue +69 -0
  51. package/Workbenches/Source/GUI_Components/AdmonitionBlock/AdmonitionBlockComponentTestSite.vue +24 -2
  52. package/Workbenches/Source/GUI_Components/Badge/BadgeBlockComponentTestSite.vue +24 -2
  53. package/Workbenches/Source/GUI_Components/Controls/Buttons/Plain/Button.workbench.pug +20 -0
  54. package/Workbenches/Source/GUI_Components/Controls/Buttons/Plain/Button.workbench.ts +5 -0
  55. package/Workbenches/Source/GUI_Components/Controls/Buttons/Plain/ButtonComponentTestSite.vue +60 -0
  56. package/Workbenches/Source/GUI_Components/Controls/Validatable/TextBox/TextBox.workbench.pug +20 -0
  57. package/Workbenches/Source/GUI_Components/Controls/Validatable/TextBox/TextBox.workbench.ts +5 -0
  58. package/Workbenches/Source/GUI_Components/Controls/Validatable/TextBox/TextBoxWorkbench.vue +86 -0
  59. package/Workbenches/Source/GUI_Components/Controls/ValidatableControlShell/ValidatableControlShell.workbench.pug +20 -0
  60. package/Workbenches/Source/GUI_Components/Controls/ValidatableControlShell/ValidatableControlShell.workbench.ts +5 -0
  61. package/Workbenches/Source/GUI_Components/Controls/ValidatableControlShell/ValidatableControlShellTestSite.vue +68 -0
  62. package/Workbenches/Source/GUI_Components/OverflowSafeSingleLineLabel/OverflowSafeSingleLineLabelComponentTestSite.vue +9 -2
  63. package/Workbenches/Source/Workbenches.pug +62 -0
  64. package/eslint.config.js +15 -0
  65. package/package.json +40 -48
  66. package/tsconfig.json +0 -3
  67. package/yda.config.yaml +65 -65
  68. package/Source/GUI_Components/AdmonitionBlock/AdmonitionBlock.vue.pug +0 -43
  69. package/Source/GUI_Components/ComponentsAuxiliaries.ts +0 -124
  70. package/Source/GUI_Components/Controls/InputtableControl.ts +0 -97
@@ -0,0 +1,317 @@
1
+ import {
2
+ toUpperCamelCase,
3
+ toLowerCamelCase,
4
+ toScreamingSnakeCase,
5
+ isUndefined,
6
+ isNotUndefined
7
+ } from "@yamato-daiwa/es-extensions";
8
+
9
+
10
+ export default abstract class YDF_ComponentsCoordinator {
11
+
12
+ public static areThemesCSS_ClassesCommon: boolean = false;
13
+
14
+ public static defineThemes<ComponentClass extends { Themes: { [themeName: string]: string; }; }>(
15
+ themesNames: ReadonlyArray<string>,
16
+ TargetComponentClass: ComponentClass
17
+ ): ComponentClass {
18
+
19
+ for (const themeName of themesNames) {
20
+ TargetComponentClass.Themes[toLowerCamelCase(themeName)] = toScreamingSnakeCase(themeName);
21
+ }
22
+
23
+ return TargetComponentClass;
24
+
25
+ }
26
+
27
+ public static defineGeometricVariations<
28
+ ComponentClass extends { GeometricVariations: { [decorativeVariationName: string]: string; }; }
29
+ >(
30
+ geometricVariationsNames: ReadonlyArray<string>,
31
+ TargetComponentClass: ComponentClass
32
+ ): ComponentClass {
33
+
34
+ for (const geometricVariationName of geometricVariationsNames) {
35
+ TargetComponentClass.GeometricVariations[toLowerCamelCase(geometricVariationName)] =
36
+ toScreamingSnakeCase(geometricVariationName);
37
+ }
38
+
39
+ return TargetComponentClass;
40
+
41
+ }
42
+
43
+ public static defineDecorativeVariations<
44
+ ComponentClass extends { DecorativeVariations: { [decorativeVariationName: string]: string; }; }
45
+ >(
46
+ decorativeVariationsNames: ReadonlyArray<string>,
47
+ TargetComponentClass: ComponentClass
48
+ ): ComponentClass {
49
+
50
+ for (const decorativeVariationName of decorativeVariationsNames) {
51
+ TargetComponentClass.DecorativeVariations[toLowerCamelCase(decorativeVariationName)] =
52
+ toScreamingSnakeCase(decorativeVariationName);
53
+ }
54
+
55
+ return TargetComponentClass;
56
+
57
+ }
58
+
59
+ public static defineThemesAndSetCorrespondenceWithOnesOfChildrenComponents<
60
+ ComponentClass extends {
61
+ Themes: { [themeKey: string]: string; };
62
+ selfAndChildrenComponentsThemesCorrespondence: { [childrenComponentKey: string]: { [ownThemeValue: string]: string; }; };
63
+ }
64
+ >(
65
+ ownAndChildrenThemesCorrespondenceDefinition: { [ ownThemeKey: string ]: { [ childrenComponentKey: string ]: string; }; },
66
+ TargetComponentClass: ComponentClass
67
+ ): ComponentClass {
68
+
69
+ YDF_ComponentsCoordinator.defineThemes(Object.keys(ownAndChildrenThemesCorrespondenceDefinition), TargetComponentClass);
70
+
71
+ for (
72
+ const [ ownThemeKey, correspondenceWithThemesOfChildrenComponents ] of
73
+ Object.entries(ownAndChildrenThemesCorrespondenceDefinition)
74
+ ) {
75
+
76
+ const ownThemeNameValue: string = toScreamingSnakeCase(ownThemeKey);
77
+
78
+ for (
79
+ const [ childComponentName, childComponent_sThemeName ] of
80
+ Object.entries(correspondenceWithThemesOfChildrenComponents)
81
+ ) {
82
+
83
+ if (isUndefined(TargetComponentClass.selfAndChildrenComponentsThemesCorrespondence[childComponentName])) {
84
+ TargetComponentClass.selfAndChildrenComponentsThemesCorrespondence[childComponentName] = {
85
+ [ownThemeNameValue]: toScreamingSnakeCase(childComponent_sThemeName)
86
+ };
87
+ } else {
88
+ TargetComponentClass.
89
+ selfAndChildrenComponentsThemesCorrespondence[childComponentName][ownThemeNameValue] =
90
+ toScreamingSnakeCase(childComponent_sThemeName);
91
+ }
92
+
93
+ }
94
+
95
+ }
96
+
97
+ return TargetComponentClass;
98
+
99
+ }
100
+
101
+ public static defineGeometricVariationsAndSetCorrespondenceWithOnesOfChildrenComponents<
102
+ ComponentClass extends {
103
+ GeometricVariations: { [geometricVariationKey: string]: string; };
104
+ selfAndChildrenComponentsGeometricVariationsCorrespondence:
105
+ { [childrenComponentKey: string]: { [ownGeometricVariationValue: string]: string; }; };
106
+ }
107
+ >(
108
+ geometricVariationsCorrespondenceDefinition:
109
+ { [ ownGeometricVariationKey: string ]: { [ childrenComponentKey: string ]: string; }; },
110
+ TargetComponentClass: ComponentClass
111
+ ): ComponentClass {
112
+
113
+ YDF_ComponentsCoordinator.defineGeometricVariations(
114
+ Object.keys(geometricVariationsCorrespondenceDefinition), TargetComponentClass
115
+ );
116
+
117
+ for (
118
+ const [ ownGeometricVariationKey, correspondenceWithGeometricVariationsOfChildrenComponents ] of
119
+ Object.entries(geometricVariationsCorrespondenceDefinition)
120
+ ) {
121
+
122
+ const ownGeometricVariationValue: string = toScreamingSnakeCase(ownGeometricVariationKey);
123
+
124
+ for (
125
+ const [ childComponentName, childComponent_sGeometricVariationsNames ] of
126
+ Object.entries(correspondenceWithGeometricVariationsOfChildrenComponents)
127
+ ) {
128
+
129
+ if (isUndefined(TargetComponentClass.selfAndChildrenComponentsGeometricVariationsCorrespondence[childComponentName])) {
130
+ TargetComponentClass.selfAndChildrenComponentsGeometricVariationsCorrespondence[childComponentName] = {
131
+ [ownGeometricVariationValue]: toScreamingSnakeCase(childComponent_sGeometricVariationsNames)
132
+ };
133
+ } else {
134
+ TargetComponentClass.
135
+ selfAndChildrenComponentsGeometricVariationsCorrespondence
136
+ /* eslint-disable no-unexpected-multiline --
137
+ * Allow line breaks for bracket notation and long fully qualified names. */
138
+ [childComponentName]
139
+ [ownGeometricVariationValue] =
140
+ /* eslint-enable no-unexpected-multiline */
141
+ toScreamingSnakeCase(childComponent_sGeometricVariationsNames);
142
+
143
+ }
144
+
145
+ }
146
+
147
+ }
148
+
149
+ return TargetComponentClass;
150
+
151
+ }
152
+
153
+ public static defineDecorativeVariationsAndSetCorrespondenceWithOnesOfChildrenComponents<
154
+ ComponentClass extends {
155
+ DecorativeVariations: { [decorativeVariationKey: string]: string; };
156
+ selfAndChildrenComponentsDecorativeVariationsCorrespondence:
157
+ { [childrenComponentKey: string]: { [ownDecorativeVariationValue: string]: string; }; };
158
+ }
159
+ >(
160
+ decorativeVariationsCorrespondenceDefinition:
161
+ { [ ownDecorativeVariationKey: string ]: { [ childrenComponentKey: string ]: string; }; },
162
+ TargetComponentClass: ComponentClass
163
+ ): ComponentClass {
164
+
165
+ YDF_ComponentsCoordinator.defineDecorativeVariations(
166
+ Object.keys(decorativeVariationsCorrespondenceDefinition), TargetComponentClass
167
+ );
168
+
169
+ for (
170
+ const [ ownDecorativeVariationKey, correspondenceWithDecorativeVariationsOfChildrenComponents ] of
171
+ Object.entries(decorativeVariationsCorrespondenceDefinition)
172
+ ) {
173
+
174
+ const ownDecorativeVariationValue: string = toScreamingSnakeCase(ownDecorativeVariationKey);
175
+
176
+ for (
177
+ const [ childComponentName, childComponent_sDecorativeVariationsNames ] of
178
+ Object.entries(correspondenceWithDecorativeVariationsOfChildrenComponents)
179
+ ) {
180
+
181
+ if (isUndefined(TargetComponentClass.selfAndChildrenComponentsDecorativeVariationsCorrespondence[childComponentName])) {
182
+ TargetComponentClass.selfAndChildrenComponentsDecorativeVariationsCorrespondence[childComponentName] = {
183
+ [ownDecorativeVariationValue]: toScreamingSnakeCase(childComponent_sDecorativeVariationsNames)
184
+ };
185
+ } else {
186
+ TargetComponentClass.
187
+ selfAndChildrenComponentsDecorativeVariationsCorrespondence
188
+ /* eslint-disable no-unexpected-multiline --
189
+ * Allow line breaks for bracket notation and long fully qualified names. */
190
+ [childComponentName]
191
+ [ownDecorativeVariationValue] =
192
+ /* eslint-enable no-unexpected-multiline */
193
+ toScreamingSnakeCase(childComponent_sDecorativeVariationsNames);
194
+ }
195
+
196
+ }
197
+
198
+ }
199
+
200
+ return TargetComponentClass;
201
+
202
+ }
203
+
204
+ public static generateRootElementModifierCSS_Classes(
205
+ {
206
+ CSS_Namespace,
207
+ activeTheme,
208
+ allThemes,
209
+ areThemesCSS_ClassesCommon,
210
+ activeGeometricVariation,
211
+ allGeometricVariations,
212
+ activeGeometricModifiers = [],
213
+ activeDecorativeVariation,
214
+ allDecorativeVariations = {},
215
+ activeDecorativeModifiers = [],
216
+ other = []
217
+ }: Readonly<{
218
+ CSS_Namespace: string;
219
+ activeTheme: string;
220
+ allThemes: Readonly<{ [themeKey: string]: string; }>;
221
+ areThemesCSS_ClassesCommon: boolean;
222
+ activeGeometricVariation: string;
223
+ allGeometricVariations: Readonly<{ [geometricVariationKey: string]: string; }>;
224
+ activeGeometricModifiers?: ReadonlyArray<string>;
225
+ activeDecorativeVariation?: string;
226
+ allDecorativeVariations?: Readonly<{ [decorativeVariationKey: string]: string; }>;
227
+ activeDecorativeModifiers?: ReadonlyArray<string>;
228
+ other?: ReadonlyArray<string>;
229
+ }>
230
+ ): Array<string> {
231
+ return [
232
+ ...Object.entries(allThemes).length > 1 && !areThemesCSS_ClassesCommon ?
233
+ [ `${ CSS_Namespace }__${ toUpperCamelCase(activeTheme) }Theme` ] : [],
234
+ ...Object.entries(allGeometricVariations).length > 1 ?
235
+ [ `${ CSS_Namespace }__${ toUpperCamelCase(activeGeometricVariation) }GeometricVariation` ] : [],
236
+ ...activeGeometricModifiers.map(
237
+ (geometricModifier: string): string =>
238
+ `${ CSS_Namespace }__${ toUpperCamelCase(geometricModifier) }GeometricModifier`
239
+ ),
240
+ ...Object.entries(allDecorativeVariations).length > 1 && isNotUndefined(activeDecorativeVariation) ?
241
+ [ `${ CSS_Namespace }__${ toUpperCamelCase(activeDecorativeVariation) }DecorativeVariation` ] : [],
242
+ ...activeDecorativeModifiers.map(
243
+ (activeDecorativeModifier: string): string =>
244
+ `${ CSS_Namespace }__${ toUpperCamelCase(activeDecorativeModifier) }DecorativeModifier`
245
+ ),
246
+ ...other
247
+ ];
248
+ }
249
+
250
+ public static addThemeCSS_ClassToArrayIfMust(
251
+ {
252
+ themeValue,
253
+ allThemes,
254
+ areThemesCSS_ClassesCommon,
255
+ CSS_Namespace
256
+ }: Readonly<{
257
+ themeValue: string;
258
+ allThemes: Readonly<{ [themeKey: string]: string; }>;
259
+ areThemesCSS_ClassesCommon: boolean;
260
+ CSS_Namespace: string;
261
+ }>
262
+ ): Array<string> {
263
+ return Object.entries(allThemes).length > 1 && !areThemesCSS_ClassesCommon ?
264
+ [ `${ CSS_Namespace }__${ toUpperCamelCase(themeValue) }Theme` ] : [];
265
+ }
266
+
267
+ public static addGeometricVariationCSS_ClassToArrayIfMust(
268
+ {
269
+ geometricVariation,
270
+ allGeometricVariations,
271
+ CSS_Namespace
272
+ }: Readonly<{
273
+ geometricVariation: string;
274
+ allGeometricVariations: Readonly<{ [geometricVariationKey: string]: string; }>;
275
+ CSS_Namespace: string;
276
+ }>
277
+ ): Array<string> {
278
+ return Object.entries(allGeometricVariations).length > 1 ?
279
+ [ `${ CSS_Namespace }__${ toUpperCamelCase(geometricVariation) }GeometricVariation` ] : [];
280
+ }
281
+
282
+ public static addDecorativeVariationCSS_ClassToArrayIfMust(
283
+ {
284
+ decorativeVariation,
285
+ allDecorativeVariations,
286
+ CSS_Namespace
287
+ }: Readonly<{
288
+ decorativeVariation: string;
289
+ allDecorativeVariations: Readonly<{ [decorativeVariationKey: string]: string; }>;
290
+ CSS_Namespace: string;
291
+ }>
292
+ ): Array<string> {
293
+ return Object.entries(allDecorativeVariations).length > 1 ?
294
+ [ `${ CSS_Namespace }__${ toUpperCamelCase(decorativeVariation) }DecorativeVariation` ] : [];
295
+ }
296
+
297
+ public static generateDemandedGeometricModifiersCSS_Classes(
298
+ CSS_Namespace: string,
299
+ demandedGeometricModifiersNames: ReadonlyArray<string>
300
+ ): Array<string> {
301
+ return demandedGeometricModifiersNames.map(
302
+ (geometricModifierName: string): string =>
303
+ `${ CSS_Namespace }__${ toUpperCamelCase(geometricModifierName) }GeometricModifier`
304
+ );
305
+ }
306
+
307
+ public static generateDemandedDecorativeModifiersCSS_Classes(
308
+ CSS_Namespace: string,
309
+ demandedDecorativeModifiersNames: ReadonlyArray<string>
310
+ ): Array<string> {
311
+ return demandedDecorativeModifiersNames.map(
312
+ (decorativeModifierName: string): string =>
313
+ `${ CSS_Namespace }__${ toUpperCamelCase(decorativeModifierName) }DecorativeModifier`
314
+ );
315
+ }
316
+
317
+ }
@@ -0,0 +1,67 @@
1
+ /* eslint no-underscore-dangle: [ "warn", { "allow": [ "_nonReactiveStaticFields__YDF"] } ] --
2
+ * According Vue guidelines, the private properties should be underscored. */
3
+
4
+ import { type ArbitraryObject } from "@yamato-daiwa/es-extensions";
5
+
6
+
7
+ type Constructor = {
8
+ prototype: Prototype;
9
+ _nonReactiveStaticFields__YDF?: Array<string>;
10
+ [newProperties: string]: unknown;
11
+ };
12
+
13
+ type Prototype = {
14
+ created?: () => unknown;
15
+ };
16
+
17
+
18
+ const AccessibleFromTemplateAsNonReactive: PropertyDecorator = (target: object, propertyKey: string | symbol): void => {
19
+
20
+ if (typeof target !== "function") {
21
+ throw new Error("@exposeForTemplateAsNonReactive can only be applied to static fields.");
22
+ }
23
+
24
+
25
+ if (typeof propertyKey === "symbol") {
26
+ throw new Error("@exposeForTemplateAsNonReactive does not support symbol-type properties.");
27
+ }
28
+
29
+
30
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- ※
31
+ * Although the `target` is a function, no need to call in here. Cast it to еру indexable type for accessing to static
32
+ * properties. */
33
+ const constructor: Constructor = target as unknown as Constructor;
34
+
35
+ let hasCreatedLifecycleHookBeenPatched: boolean;
36
+
37
+ if (Array.isArray(constructor._nonReactiveStaticFields__YDF)) {
38
+ hasCreatedLifecycleHookBeenPatched = true;
39
+ constructor._nonReactiveStaticFields__YDF.push(propertyKey);
40
+ } else {
41
+ constructor._nonReactiveStaticFields__YDF = [ propertyKey ];
42
+ hasCreatedLifecycleHookBeenPatched = false;
43
+ }
44
+
45
+ if (!hasCreatedLifecycleHookBeenPatched) {
46
+
47
+ const prototype: Prototype = constructor.prototype;
48
+ const originalCreatedMethod: (() => unknown) | undefined = prototype.created;
49
+
50
+ prototype.created = function patchCheatedHook(): void {
51
+
52
+ originalCreatedMethod?.call(this);
53
+
54
+ for (const key of constructor._nonReactiveStaticFields__YDF ?? []) {
55
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
56
+ * It is possible to assign the new properties to prototype. */
57
+ (this as ArbitraryObject)[key] = constructor[key];
58
+ }
59
+
60
+ };
61
+
62
+ }
63
+
64
+ };
65
+
66
+
67
+ export default AccessibleFromTemplateAsNonReactive;
@@ -0,0 +1,26 @@
1
+ import { createDecorator } from "vue-facing-decorator";
2
+ import type { ComponentOptions } from "vue";
3
+
4
+
5
+ export default function NonReactiveVueData(
6
+ value: unknown
7
+ ): (_arguments: unknown, decoratorContext: string | DecoratorContext) => void {
8
+ return createDecorator(
9
+ (componentOptions: ComponentOptions, key: string): void => {
10
+
11
+ /* eslint-disable-next-line @typescript-eslint/unbound-method --
12
+ * The binding of the correct context will be executed inside the `patchCheatedHook` function. */
13
+ const originalCreatedHook: (() => unknown) | undefined = componentOptions.created;
14
+
15
+ componentOptions.created = function patchCheatedHook(): void {
16
+
17
+ originalCreatedHook?.call(this);
18
+
19
+ this[key] = value;
20
+
21
+ };
22
+
23
+ },
24
+ { preserve: true }
25
+ );
26
+ }
@@ -0,0 +1,64 @@
1
+ import { createDecorator } from "vue-facing-decorator";
2
+ import type { ComponentOptions } from "vue";
3
+ import { Logger, isUndefined } from "@yamato-daiwa/es-extensions";
4
+ import ForbiddenNullValueOfOptionalVuePropertyError from
5
+ "../_Errors/ForbiddenNullValueOfOptionalVueProperty/ForbiddenNullValueOfOptionalVuePropertyError";
6
+
7
+
8
+ const preventNullForOptionalVueProperty: (_arguments: unknown, decoratorContext: string | DecoratorContext) => void =
9
+ createDecorator(
10
+ (componentOptions: ComponentOptions, key: string): void => {
11
+
12
+ /* eslint-disable no-underscore-dangle -- [ CONVENTION ]
13
+ * Vue uses the `_` prefix to define its own private properties. */
14
+ if (isUndefined(componentOptions._nonNullOptionalProperties__YDF)) {
15
+ componentOptions._nonNullOptionalProperties__YDF = [];
16
+ }
17
+
18
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
19
+ * The componentOptions` allows to add custom properties (do not be confused with ones called "props").
20
+ * Maybe they can be specified via generic parameter, but `ComponentOptions` have many generic parameters which
21
+ * can not be specified selectively. */
22
+ ((componentOptions._nonNullOptionalProperties__YDF as Array<string>)).push(key);
23
+
24
+ patchLifecycleHook("beforeCreate", componentOptions);
25
+ patchLifecycleHook("beforeUpdate", componentOptions);
26
+
27
+ }
28
+ );
29
+
30
+
31
+ function patchLifecycleHook(
32
+ targetHookName: "beforeCreate" | "beforeUpdate",
33
+ componentOptions: ComponentOptions
34
+ ): void {
35
+
36
+ const originalLifecycleHook: (() => unknown) | undefined = componentOptions[targetHookName];
37
+
38
+ componentOptions[targetHookName] = function lifecycleHookWrapper(): void {
39
+
40
+ const nonNullOptionalProperties: ReadonlyArray<string> = componentOptions._nonNullOptionalProperties__YDF;
41
+ /* eslint-enable no-underscore-dangle */
42
+
43
+ for (const nonNullOptionalProperty of nonNullOptionalProperties) {
44
+ if (this[nonNullOptionalProperty] === null) {
45
+ Logger.throwErrorWithFormattedMessage({
46
+ errorInstance: new ForbiddenNullValueOfOptionalVuePropertyError({
47
+ targetComponentName: componentOptions.name,
48
+ targetPropertyName: nonNullOptionalProperty
49
+ }),
50
+ title: ForbiddenNullValueOfOptionalVuePropertyError.localization.defaultTitle,
51
+ occurrenceLocation:
52
+ `${ componentOptions.name ?? "(Anonymous Component)" }.[prop]${ nonNullOptionalProperty }` +
53
+ "@OptionalButNotNullableVueProperty"
54
+ });
55
+ }
56
+ }
57
+
58
+ originalLifecycleHook?.call(this);
59
+
60
+ };
61
+ }
62
+
63
+
64
+ export default preventNullForOptionalVueProperty;
@@ -0,0 +1,47 @@
1
+ import forbiddenNullValueOfOptionalVuePropertyErrorLocalization__english from
2
+ "./ForbiddenNullValueOfOptionalVuePropertyErrorLocalization.english";
3
+
4
+
5
+ class ForbiddenNullValueOfOptionalVuePropertyError extends Error {
6
+
7
+ public static readonly NAME: string = "ForbiddenNullValueOfOptionalVuePropertyError";
8
+
9
+ public static localization: ForbiddenNullValueOfOptionalVuePropertyError.Localization =
10
+ forbiddenNullValueOfOptionalVuePropertyErrorLocalization__english;
11
+
12
+
13
+ public constructor(constructorParameter: ForbiddenNullValueOfOptionalVuePropertyError.ConstructorParameter) {
14
+
15
+ super();
16
+
17
+ this.name = ForbiddenNullValueOfOptionalVuePropertyError.NAME;
18
+
19
+ this.message = ForbiddenNullValueOfOptionalVuePropertyError.localization.generateMessage(constructorParameter);
20
+
21
+ }
22
+
23
+ }
24
+
25
+
26
+ namespace ForbiddenNullValueOfOptionalVuePropertyError {
27
+
28
+ export type ConstructorParameter = Localization.DescriptionTemplateParameters;
29
+
30
+ export type Localization = Readonly<{
31
+ defaultTitle: string;
32
+ generateMessage: (
33
+ templateParameters: Localization.DescriptionTemplateParameters
34
+ ) => string;
35
+ }>;
36
+
37
+ export namespace Localization {
38
+ export type DescriptionTemplateParameters = Readonly<{
39
+ targetComponentName?: string;
40
+ targetPropertyName: string;
41
+ }>;
42
+ }
43
+
44
+ }
45
+
46
+
47
+ export default ForbiddenNullValueOfOptionalVuePropertyError;
@@ -0,0 +1,24 @@
1
+ import type ForbiddenNullValueOfOptionalVuePropertyError from "./ForbiddenNullValueOfOptionalVuePropertyError";
2
+ import { isNonEmptyString } from "@yamato-daiwa/es-extensions";
3
+
4
+
5
+ const forbiddenVuePropertyNullValueErrorLocalization__english: ForbiddenNullValueOfOptionalVuePropertyError.Localization = {
6
+ defaultTitle: "Forbidden Null Value of Optional Vue Property Error",
7
+ generateMessage(
8
+ {
9
+ targetPropertyName,
10
+ targetComponentName
11
+ }: ForbiddenNullValueOfOptionalVuePropertyError.Localization.DescriptionTemplateParameters
12
+ ): string {
13
+ return `Although the "${ targetPropertyName }" property is optional ` +
14
+ (
15
+ isNonEmptyString(targetComponentName) ?
16
+ `for "${ targetComponentName }" component or its inheritor` :
17
+ "(`name` not specified for target component)"
18
+ ) +
19
+ ", the `null` value is not allowed because it neither accessible from `validator` nor substitutable by `default`.";
20
+ }
21
+ };
22
+
23
+
24
+ export default forbiddenVuePropertyNullValueErrorLocalization__english;
@@ -0,0 +1,43 @@
1
+ import invalidVuePropertyErrorLocalization__english from "./InvalidVuePropertyErrorLocalization.english";
2
+
3
+
4
+ class InvalidVuePropertyError extends Error {
5
+
6
+ public static readonly NAME: string = "InvalidVuePropertyError";
7
+
8
+ public static localization: InvalidVuePropertyError.Localization = invalidVuePropertyErrorLocalization__english;
9
+
10
+
11
+ public constructor(compoundParameter: InvalidVuePropertyError.ConstructorParameter) {
12
+
13
+ super();
14
+
15
+ this.name = InvalidVuePropertyError.NAME;
16
+ this.message = InvalidVuePropertyError.localization.generateDescription(compoundParameter);
17
+
18
+ }
19
+
20
+ }
21
+
22
+
23
+ namespace InvalidVuePropertyError {
24
+
25
+ export type ConstructorParameter = Localization.DescriptionTemplateVariables;
26
+
27
+ export type Localization = Readonly<{
28
+ defaultTitle: string;
29
+ generateDescription: (templateVariables: Localization.DescriptionTemplateVariables) => string;
30
+ }>;
31
+
32
+ export namespace Localization {
33
+ export type DescriptionTemplateVariables = Readonly<{
34
+ componentName: string;
35
+ propertyName: string;
36
+ messageSpecificPart: string;
37
+ }>;
38
+ }
39
+
40
+ }
41
+
42
+
43
+ export default InvalidVuePropertyError;
@@ -0,0 +1,16 @@
1
+ import type InvalidVuePropertyError from "./InvalidVuePropertyError";
2
+
3
+
4
+ export const invalidVuePropertyErrorLocalization__english: InvalidVuePropertyError.Localization = {
5
+ defaultTitle: "Invalid Vue Property",
6
+ generateDescription: (
7
+ {
8
+ propertyName,
9
+ componentName,
10
+ messageSpecificPart
11
+ }: InvalidVuePropertyError.Localization.DescriptionTemplateVariables
12
+ ): string => `Invalid Vue property "${ propertyName }"of "${ componentName }" Vue component.\n${ messageSpecificPart }`
13
+ };
14
+
15
+
16
+ export default invalidVuePropertyErrorLocalization__english;
@@ -0,0 +1,25 @@
1
+ import VuePropertyValidator from "./VuePropertyValidator";
2
+ import { isBoolean } from "@yamato-daiwa/es-extensions";
3
+
4
+
5
+ export default function BooleanVuePropertyValidator(
6
+ {
7
+ componentName,
8
+ propertyName,
9
+ isPropertyRequired
10
+ }: Readonly<{
11
+ componentName: string;
12
+ propertyName: string;
13
+ isPropertyRequired: boolean;
14
+ }>
15
+ ): (targetVueProperty: Exclude<unknown, undefined>) => boolean {
16
+ return VuePropertyValidator.create({
17
+ checker: isBoolean,
18
+ messageSpecificPart:
19
+ isPropertyRequired ?
20
+ "Must be the boolean." :
21
+ "Must be either boolean or undefined (explicit or omitted).",
22
+ propertyName,
23
+ componentName
24
+ });
25
+ }
@@ -0,0 +1,22 @@
1
+ import VuePropertyValidator from "./VuePropertyValidator";
2
+ import { isString, isElementOfEnumeration } from "@yamato-daiwa/es-extensions";
3
+
4
+
5
+ export default function DecorativeModifiersVuePropertyValidator(
6
+ {
7
+ DecorativeModifiers,
8
+ CSS_NAMESPACE: componentName
9
+ }: Readonly<{
10
+ DecorativeModifiers: Readonly<{ [key: string]: string; }>;
11
+ CSS_NAMESPACE: string;
12
+ }>
13
+ ): (targetVueProperty: unknown) => boolean {
14
+ return VuePropertyValidator.create({
15
+ checker: (rawValue: unknown): boolean => Array.isArray(rawValue) && rawValue.every(
16
+ (element: unknown): boolean => isString(element) && isElementOfEnumeration(element, DecorativeModifiers)
17
+ ),
18
+ messageSpecificPart: `Each array element must the member of \`${ componentName }.DecorativeModifiers\` enumeration.`,
19
+ propertyName: "decorativeModifiers",
20
+ componentName
21
+ });
22
+ }
@@ -0,0 +1,23 @@
1
+ import VuePropertyValidator from "./VuePropertyValidator";
2
+ import { isString, isElementOfEnumeration } from "@yamato-daiwa/es-extensions";
3
+
4
+
5
+ export default function DecorativeVariationVuePropertyValidator(
6
+ {
7
+ DecorativeVariations,
8
+ CSS_NAMESPACE: componentName
9
+ }: Readonly<{
10
+ DecorativeVariations: Readonly<{ [key: string]: string; }>;
11
+ CSS_NAMESPACE: string;
12
+ }>
13
+ ): (targetVueProperty: Exclude<unknown, undefined>) => boolean {
14
+ return VuePropertyValidator.create({
15
+ checker: (rawValue: Exclude<unknown, undefined>): boolean =>
16
+ isString(rawValue) && isElementOfEnumeration(rawValue, DecorativeVariations),
17
+ messageSpecificPart:
18
+ `Must be the string herewith one among values of \`${ componentName }.DecorativeVariations\` associative array ` +
19
+ `including the ones defined via \`${ componentName }.defineDecorativeVariations()\`.`,
20
+ propertyName: "decorativeVariation",
21
+ componentName
22
+ });
23
+ }