@yamato-daiwa/frontend-vue 0.2.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 (60) hide show
  1. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  2. package/.idea/inspectionProfiles/Project_Default.xml +5 -1
  3. package/README.md +5 -0
  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} +83 -59
  8. package/Source/GUI_Components/Badge/Badge.vue.ts +98 -63
  9. package/Source/GUI_Components/Badge/LoadingPlaceholder/Badge-LoadingPlaceholder.vue.ts +51 -32
  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.ts +217 -105
  17. package/Source/GUI_Components/Controls/Buttons/Plain/LoadingPlaceholder/Button-LoadingPlaceholder.vue.ts +38 -30
  18. package/Source/GUI_Components/Controls/ValidatableControlShell/ValidatableControlShell.vue.pug +33 -20
  19. package/Source/GUI_Components/Controls/ValidatableControlShell/ValidatableControlShell.vue.ts +303 -121
  20. package/Source/GUI_Components/Controls/Validatables/InputtableControl.vue.ts +233 -0
  21. package/Source/GUI_Components/Controls/Validatables/TextBox/TextBox.vue.pug +38 -0
  22. package/Source/GUI_Components/Controls/Validatables/TextBox/TextBox.vue.ts +538 -96
  23. package/Source/GUI_Components/Controls/Validatables/ValidatableControl.ts +63 -54
  24. package/Source/GUI_Components/Controls/Validatables/ValidatableControlsGroup.ts +176 -0
  25. package/Source/GUI_Components/OverflowSafeSingleLineLabel.vue +9 -2
  26. package/Source/GUI_Components/ThemesShowcase.vue +10 -5
  27. package/Source/GUI_Components/YDF_ComponentsCoordinator.ts +164 -5
  28. package/Source/GUI_Components/_Decorators/AccessibleFromTemplateAsNonReactive.ts +67 -0
  29. package/Source/GUI_Components/_Decorators/NonReactiveVueData.ts +26 -0
  30. package/Source/GUI_Components/_Decorators/{OptionalButNotNullableVueProperty.ts → preventNullForOptionalVueProperty.ts} +3 -4
  31. package/Source/GUI_Components/_Errors/InvalidVueProperty/InvalidVuePropertyError.ts +43 -0
  32. package/Source/GUI_Components/_Errors/InvalidVueProperty/InvalidVuePropertyErrorLocalization.english.ts +16 -0
  33. package/Source/GUI_Components/_VuePropertiesValidators/BooleanVuePropertyValidator.ts +25 -0
  34. package/Source/GUI_Components/_VuePropertiesValidators/DecorativeModifiersVuePropertyValidator.ts +22 -0
  35. package/Source/GUI_Components/_VuePropertiesValidators/DecorativeVariationVuePropertyValidator.ts +23 -0
  36. package/Source/GUI_Components/_VuePropertiesValidators/ElementOfEnumerationVuePropertyValidator.ts +29 -0
  37. package/Source/GUI_Components/_VuePropertiesValidators/GeometricModifiersVuePropertyValidator.ts +22 -0
  38. package/Source/GUI_Components/_VuePropertiesValidators/GeometricVariationVuePropertyValidator.ts +23 -0
  39. package/Source/GUI_Components/_VuePropertiesValidators/NaturalNumberOrZeroVuePropertyValidator.ts +25 -0
  40. package/Source/GUI_Components/_VuePropertiesValidators/NonEmptyStringVuePropertyValidator.ts +25 -0
  41. package/Source/GUI_Components/_VuePropertiesValidators/ThemeVuePropertyValidator.ts +23 -0
  42. package/Source/GUI_Components/_VuePropertiesValidators/VuePropertyValidator.ts +51 -0
  43. package/Source/index.ts +24 -8
  44. package/Workbenches/Source/Decorators/Decorators.workbench.pug +20 -0
  45. package/Workbenches/Source/Decorators/Decorators.workbench.ts +5 -0
  46. package/Workbenches/Source/Decorators/DecoratorsWorkbench.vue +69 -0
  47. package/Workbenches/Source/GUI_Components/AdmonitionBlock/AdmonitionBlockComponentTestSite.vue +9 -2
  48. package/Workbenches/Source/GUI_Components/Badge/BadgeBlockComponentTestSite.vue +9 -2
  49. package/Workbenches/Source/GUI_Components/Controls/Buttons/Plain/ButtonComponentTestSite.vue +19 -8
  50. package/Workbenches/Source/GUI_Components/Controls/Validatable/TextBox/TextBoxWorkbench.vue +45 -2
  51. package/Workbenches/Source/GUI_Components/Controls/ValidatableControlShell/ValidatableControlShellTestSite.vue +9 -2
  52. package/Workbenches/Source/GUI_Components/OverflowSafeSingleLineLabel/OverflowSafeSingleLineLabelComponentTestSite.vue +9 -2
  53. package/Workbenches/Source/Workbenches.pug +6 -0
  54. package/eslint.config.js +15 -0
  55. package/package.json +40 -48
  56. package/tsconfig.json +0 -3
  57. package/yda.config.yaml +1 -1
  58. package/Source/GUI_Components/AdmonitionBlock/AdmonitionBlock.vue.pug +0 -43
  59. package/Source/GUI_Components/Controls/Validatables/InputtableControl.ts +0 -134
  60. package/Source/GUI_Components/_Utils/validateVuePropertyAndLogIfInvalid.ts +0 -34
@@ -1,7 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/member-ordering -- The secondary members has been organized to the end of the class. */
2
2
 
3
- import type { InputtedValueValidation } from "@yamato-daiwa/frontend";
3
+ import type { InputtedValueValidation, ValidatableControl as CorePackageValidatableControl } from "@yamato-daiwa/frontend";
4
4
  import type { ComponentPublicInstance as VueComponentPublicInstance } from "vue";
5
+ import type { VueCons as VueClassComponent } from "vue-facing-decorator";
5
6
  import {
6
7
  Logger,
7
8
  UnexpectedEventError,
@@ -12,23 +13,11 @@ import {
12
13
  import VueComponentNotFoundError from "../../_Errors/VueComponentNotFound/VueComponentNotFoundError";
13
14
 
14
15
 
15
- interface ValidatableControl {
16
-
17
- highlightInvalidInput: () => this;
18
-
19
- getRootElementOffsetCoordinates: () => Element;
20
-
21
- focus: () => this;
22
-
23
- resetValidityHighlightingStateToInitial: () => ValidatableControl.RootElementOffsetCoordinates;
24
-
25
- }
16
+ type ValidatableControl = CorePackageValidatableControl;
26
17
 
27
18
 
28
19
  namespace ValidatableControl {
29
20
 
30
- export type RootElementOffsetCoordinates = Readonly<{ top: number; left: number; }>;
31
-
32
21
  export function isValidatableControl(potentialValidatableControl: unknown): potentialValidatableControl is ValidatableControl {
33
22
  return isArbitraryObject(potentialValidatableControl) &&
34
23
  isFunctionLike(potentialValidatableControl.highlightInvalidInput) &&
@@ -37,16 +26,17 @@ namespace ValidatableControl {
37
26
  isFunctionLike(potentialValidatableControl.resetValidityHighlightingStateToInitial);
38
27
  }
39
28
 
29
+
40
30
  export function getValidatableControlInstanceByVueReferenceID(
41
31
  compoundParameter: Readonly<{
42
- parentVueComponentInstance: VueComponentPublicInstance;
32
+ parentVueComponentInstance: VueComponentPublicInstance | VueClassComponent;
43
33
  vueReferenceID: string;
44
34
  }>
45
35
  ): ValidatableControl | null;
46
36
 
47
37
  export function getValidatableControlInstanceByVueReferenceID(
48
38
  compoundParameter: Readonly<{
49
- parentVueComponentInstance: VueComponentPublicInstance;
39
+ parentVueComponentInstance: VueComponentPublicInstance | VueClassComponent;
50
40
  vueReferenceID: string;
51
41
  mustThrowErrorIsNotFoundOrNotValidatableControl: true;
52
42
  }>
@@ -54,19 +44,22 @@ namespace ValidatableControl {
54
44
 
55
45
  export function getValidatableControlInstanceByVueReferenceID(
56
46
  compoundParameter: Readonly<{
57
- parentVueComponentInstance: VueComponentPublicInstance;
47
+ parentVueComponentInstance: VueComponentPublicInstance | VueClassComponent;
58
48
  vueReferenceID: string;
59
49
  mustThrowErrorIsNotFoundOrNotValidatableControl?: true;
60
50
  }>
61
51
  ): ValidatableControl | null {
62
52
 
63
- const potentialValidatableControl: unknown = compoundParameter.parentVueComponentInstance.
64
- $refs[compoundParameter.vueReferenceID];
53
+ const potentialValidatableControl: unknown =
54
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
55
+ * Types which `vue-facing-decorator` imports are not compatible with `VueComponentPublicInstance`, but actually
56
+ * class components will be transformed to valid option API. */
57
+ (compoundParameter.parentVueComponentInstance as VueComponentPublicInstance).$refs[compoundParameter.vueReferenceID];
65
58
 
66
59
  if (isUndefined(potentialValidatableControl)) {
67
60
 
68
61
  if (compoundParameter.mustThrowErrorIsNotFoundOrNotValidatableControl === true) {
69
- Logger.throwErrorAndLog({
62
+ Logger.throwErrorWithFormattedMessage({
70
63
  errorInstance: new VueComponentNotFoundError({ vueReferenceID: compoundParameter.vueReferenceID }),
71
64
  title: VueComponentNotFoundError.localization.defaultTitle,
72
65
  occurrenceLocation: "ValidatableControl.getValidatableControlInstanceByVueReferenceID(compoundParameter)"
@@ -82,11 +75,11 @@ namespace ValidatableControl {
82
75
  if (!isValidatableControl(potentialValidatableControl)) {
83
76
 
84
77
  if (compoundParameter.mustThrowErrorIsNotFoundOrNotValidatableControl === true) {
85
- Logger.throwErrorAndLog({
86
- errorType: "VueReferenceValueIsNotValidatableControl",
87
- title: "Vue reference value is not validatable control",
78
+ Logger.throwErrorWithFormattedMessage({
79
+ errorType: "VueReferenceValueIsNotValidatableControlError",
80
+ title: "Vue Reference Value is not the Validatable Control",
88
81
  description:
89
- `The Vue reference "${ compoundParameter.vueReferenceID }" is not referring to the component implementing ` +
82
+ `The Vue reference "${ compoundParameter.vueReferenceID }" does not refer to the component implementing ` +
90
83
  "the \"ValidatableControl\" interface.",
91
84
  occurrenceLocation: "ValidatableControl.getValidatableControlInstanceByVueReferenceID(compoundParameter)"
92
85
  });
@@ -105,6 +98,7 @@ namespace ValidatableControl {
105
98
 
106
99
  export class Payload<ValidValue, InvalidValue, Validation extends InputtedValueValidation> {
107
100
 
101
+ /* ━━━ Fields ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
108
102
  public readonly ID: string;
109
103
  public readonly VUE_REFERENCE_ID: string;
110
104
 
@@ -112,25 +106,32 @@ namespace ValidatableControl {
112
106
  public readonly validation: Validation;
113
107
  public readonly lastChangeSourceID?: string;
114
108
 
115
- private readonly validationResult: InputtedValueValidation.Result;
109
+ protected readonly validationResult: InputtedValueValidation.Result;
110
+ protected readonly asynchronousChecksStatus: InputtedValueValidation.AsynchronousChecks.Status | null = null;
116
111
 
117
112
 
113
+ /* ━━━ Public Static Methods ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
118
114
  public static createInitialInstance<ValidValue, InvalidValue, Validation extends InputtedValueValidation>(
119
- compoundParameter: Readonly<{
115
+ {
116
+ initialValue,
117
+ validation,
118
+ vueReferenceID
119
+ }: Readonly<{
120
120
  initialValue: ValidValue | InvalidValue;
121
121
  validation: Validation;
122
122
  vueReferenceID?: string;
123
123
  }>
124
124
  ): Payload<ValidValue, InvalidValue, Validation> {
125
125
  return new Payload<ValidValue, InvalidValue, Validation>({
126
- value: compoundParameter.initialValue,
127
- validation: compoundParameter.validation,
128
- vueReferenceID: compoundParameter.vueReferenceID
126
+ value: initialValue,
127
+ validation,
128
+ vueReferenceID
129
129
  });
130
130
  }
131
131
 
132
132
 
133
- private constructor(
133
+ /* ━━━ Constructor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
134
+ protected constructor(
134
135
  {
135
136
  ID,
136
137
  vueReferenceID,
@@ -155,7 +156,7 @@ namespace ValidatableControl {
155
156
  ) {
156
157
 
157
158
  this.ID = ID ?? Payload.generateSelfID();
158
- this.VUE_REFERENCE_ID = vueReferenceID ?? Payload.generateAssociatedComponentVueReferenceID();
159
+ this.VUE_REFERENCE_ID = vueReferenceID ?? Payload.generateVueReferenceID_ForAssociatedComponent();
159
160
 
160
161
  this.value = value;
161
162
  this.validation = validation;
@@ -180,6 +181,9 @@ namespace ValidatableControl {
180
181
 
181
182
  }
182
183
 
184
+
185
+ /* ━━━ Public Instance Methods ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
186
+ /* ─── Updating ───────────────────────────────────────────────────────────────────────────────────────────────── */
183
187
  public getComponentInstance(ownerComponent: VueComponentPublicInstance): ValidatableControl {
184
188
  return getValidatableControlInstanceByVueReferenceID({
185
189
  vueReferenceID: this.VUE_REFERENCE_ID,
@@ -188,45 +192,50 @@ namespace ValidatableControl {
188
192
  });
189
193
  }
190
194
 
191
- public get validationErrorsMessages(): Array<string> {
192
- return this.validationResult.isValid ? [] : [ ...this.validationResult.errorsMessages ];
193
- }
194
195
 
195
- public get isInvalid(): boolean {
196
- return !this.validationResult.isValid;
196
+ /* ─── Other ──────────────────────────────────────────────────────────────────────────────────────────────────── */
197
+ public updateImmutably(
198
+ {
199
+ newValue
200
+ }: {
201
+ newValue: ValidValue | InvalidValue;
202
+ }
203
+ ): Payload<ValidValue, InvalidValue, Validation> {
204
+ return new Payload<ValidValue, InvalidValue, Validation>({
205
+ value: newValue,
206
+ validation: this.validation
207
+ });
197
208
  }
198
209
 
199
210
 
211
+ /* ━━━ Public Getters and Getter-like Methods ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
200
212
  public getExpectedToBeValidValue(): ValidValue {
201
213
 
202
214
  if (this.isInvalid) {
203
- Logger.throwErrorAndLog({
204
- errorInstance: new UnexpectedEventError(
205
- "Contrary os expectations, the value of the validatable control payload is still invalid."
206
- ),
215
+ Logger.throwErrorWithFormattedMessage({
216
+ errorInstance: new UnexpectedEventError("Contrary to expectations, the value is still invalid."),
207
217
  title: UnexpectedEventError.localization.defaultTitle,
208
218
  occurrenceLocation: "ValidatableControl.Payload.getExpectedToBeValidValue()"
209
219
  });
210
220
  }
211
221
 
212
222
 
213
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-type-assertion --
214
- * In this case, we are guarantee the ValidValue by "this.isInvalid" check */
223
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
224
+ * In this case, we are guarantee the ValidValue by "this.isInvalid" check */
215
225
  return this.value as ValidValue;
216
226
 
217
227
  }
218
228
 
219
- public updateImmutably(
220
- {
221
- newValue
222
- }: {
223
- newValue: ValidValue | InvalidValue;
224
- }
225
- ): Payload<ValidValue, InvalidValue, Validation> {
226
- return new Payload<ValidValue, InvalidValue, Validation>({
227
- value: newValue,
228
- validation: this.validation
229
- });
229
+ public get isEmpty(): boolean {
230
+ return this.validation.hasValueBeenOmitted(this.value);
231
+ }
232
+
233
+ public get isInvalid(): boolean {
234
+ return !this.validationResult.isValid;
235
+ }
236
+
237
+ public get validationErrorsMessages(): Array<string> {
238
+ return this.validationResult.isValid ? [] : [ ...this.validationResult.errorsMessages ];
230
239
  }
231
240
 
232
241
 
@@ -241,7 +250,7 @@ namespace ValidatableControl {
241
250
 
242
251
  protected static counterForAssociatedComponentVueReferenceID_Generating: number = 0;
243
252
 
244
- protected static generateAssociatedComponentVueReferenceID(): string {
253
+ protected static generateVueReferenceID_ForAssociatedComponent(): string {
245
254
  Payload.counterForAssociatedComponentVueReferenceID_Generating++;
246
255
  return `VALIDATABLE_CONTROL-${ Payload.counterForAssociatedComponentVueReferenceID_Generating }`;
247
256
  }
@@ -0,0 +1,176 @@
1
+ import ValidatableControl from "./ValidatableControl";
2
+ import type { InputtedValueValidation } from "@yamato-daiwa/frontend";
3
+
4
+ import type { ComponentPublicInstance as VueComponentPublicInstance } from "vue";
5
+ import type { Vue as VueClassComponent } from "vue-facing-decorator";
6
+
7
+ import {
8
+ Logger,
9
+ UnexpectedEventError,
10
+ isNull,
11
+ isNotUndefined,
12
+ DOM_ElementRetrievingFailedError
13
+ } from "@yamato-daiwa/es-extensions";
14
+ import type { ArbitraryObject } from "@yamato-daiwa/es-extensions";
15
+ import { getExpectedToBeSingleDOM_Element } from "@yamato-daiwa/es-extensions-browserjs";
16
+
17
+
18
+ export default class ValidatableControlsGroup<ValidData extends ArbitraryObject | Array<unknown>> {
19
+
20
+ public readonly isInvalid: boolean;
21
+ public readonly payload: ValidData | null;
22
+ public readonly SCROLLING_CONTAINER_HTML_ID?: string;
23
+
24
+ protected readonly controlsPayload: ValidatableControlsGroup.GeneralizedControlsPayload;
25
+
26
+
27
+ /* ━━━ Public Static Methods ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
28
+ public static initialize<ValidData extends ArbitraryObject | Array<unknown>>(
29
+ compoundParameter: Readonly<{ scrollingContainerHTML_ID?: string; }>
30
+ ): ValidatableControlsGroup<ValidData> {
31
+ return new ValidatableControlsGroup<ValidData>({
32
+ isInvalid: true,
33
+ payload: null,
34
+ controlsPayload: {},
35
+ scrollingContainerHTML_ID: compoundParameter.scrollingContainerHTML_ID
36
+ });
37
+ }
38
+
39
+ public static hasInvalidInputs(
40
+ controlsPayload: ValidatableControlsGroup.GeneralizedControlsPayload
41
+ ): boolean {
42
+ return (Array.isArray(controlsPayload) ? controlsPayload : Object.values(controlsPayload)).
43
+ some(
44
+ (validatableControlPayload: ValidatableControl.Payload<unknown, unknown, InputtedValueValidation>): boolean =>
45
+ validatableControlPayload.isInvalid
46
+ );
47
+ }
48
+
49
+ public static pointOutValidationErrors(
50
+ {
51
+ controlsPayload,
52
+ parentVueComponentInstance,
53
+ scrollingContainerHTML_ID
54
+ }: Readonly<{
55
+ controlsPayload: ValidatableControlsGroup.GeneralizedControlsPayload;
56
+ parentVueComponentInstance: VueComponentPublicInstance | InstanceType<typeof VueClassComponent>;
57
+ scrollingContainerHTML_ID?: string;
58
+ }>
59
+ ): void {
60
+
61
+ let isCurrentControlTheFirstInvalidOne: boolean = true;
62
+
63
+ for (const validatableControlPayload of Array.isArray(controlsPayload) ? controlsPayload : Object.values(controlsPayload)) {
64
+
65
+ if (validatableControlPayload.isInvalid) {
66
+
67
+ const componentInstance: ValidatableControl | null = ValidatableControl.getValidatableControlInstanceByVueReferenceID({
68
+ parentVueComponentInstance, vueReferenceID: validatableControlPayload.VUE_REFERENCE_ID
69
+ });
70
+
71
+ if (isNull(componentInstance)) {
72
+
73
+ Logger.logError({
74
+ errorType: DOM_ElementRetrievingFailedError.NAME,
75
+ title: DOM_ElementRetrievingFailedError.localization.defaultTitle,
76
+ description: "Unable to retrieve the validatable control instance with Vue reference ID " +
77
+ `"${ validatableControlPayload.VUE_REFERENCE_ID }". Make sure that dedicated component has been mounted ` +
78
+ "and \"ref\" attribute has been explicitly specified.",
79
+ occurrenceLocation: "ValidatableControlsGroup.pointOutValidationErrors(compoundParameter)"
80
+ });
81
+
82
+ continue;
83
+
84
+ }
85
+
86
+
87
+ componentInstance.highlightInvalidInput();
88
+
89
+ if (isCurrentControlTheFirstInvalidOne) {
90
+
91
+ componentInstance.focus();
92
+
93
+ /* eslint-disable-next-line max-depth -- Here are all conditions are required. */
94
+ if (isNotUndefined(scrollingContainerHTML_ID)) {
95
+ getExpectedToBeSingleDOM_Element({ selector: `#${ scrollingContainerHTML_ID }` }).scroll({
96
+ top: componentInstance.getRootElementOffsetCoordinates().top,
97
+ behavior: "smooth"
98
+ });
99
+ }
100
+
101
+ isCurrentControlTheFirstInvalidOne = false;
102
+
103
+ }
104
+
105
+ }
106
+
107
+ }
108
+
109
+ }
110
+
111
+
112
+ /* ━━━ Instancing ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
113
+ public constructor(
114
+ compoundParameter:
115
+ Readonly<
116
+ (
117
+ {
118
+ isInvalid: false;
119
+ payload: ValidData;
120
+ } | {
121
+ isInvalid: true;
122
+ payload: null;
123
+ controlsPayload: ValidatableControlsGroup.GeneralizedControlsPayload;
124
+ }
125
+ ) & {
126
+ scrollingContainerHTML_ID?: string;
127
+ }
128
+ >
129
+ ) {
130
+
131
+ this.isInvalid = compoundParameter.isInvalid;
132
+ this.payload = compoundParameter.payload;
133
+
134
+ this.controlsPayload = "controlsPayload" in compoundParameter ? compoundParameter.controlsPayload : {};
135
+
136
+ if (isNotUndefined(this.SCROLLING_CONTAINER_HTML_ID)) {
137
+ this.SCROLLING_CONTAINER_HTML_ID = compoundParameter.scrollingContainerHTML_ID;
138
+ }
139
+
140
+ }
141
+
142
+
143
+ /* ━━━ Instance Methods ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
144
+ public getExpectedToBeValidPayload(): ValidData {
145
+
146
+ if (isNull(this.payload)) {
147
+ Logger.throwErrorWithFormattedMessage({
148
+ errorInstance: new UnexpectedEventError("Contrary to expectations the payload is still invalid."),
149
+ title: UnexpectedEventError.localization.defaultTitle,
150
+ occurrenceLocation: "validatableControlsGroup.getExpectedToBeValidPayload()"
151
+ });
152
+ }
153
+
154
+
155
+ return this.payload;
156
+
157
+ }
158
+
159
+ public pointOutValidationErrors(parentVueComponentInstance: VueComponentPublicInstance): void {
160
+ ValidatableControlsGroup.pointOutValidationErrors({
161
+ controlsPayload: this.controlsPayload,
162
+ parentVueComponentInstance,
163
+ scrollingContainerHTML_ID: this.SCROLLING_CONTAINER_HTML_ID
164
+ });
165
+ }
166
+
167
+ }
168
+
169
+
170
+ namespace ValidatableControlsGroup {
171
+
172
+ export type GeneralizedControlsPayload =
173
+ Readonly<{ [controlKey: string]: ValidatableControl.Payload<unknown, unknown, InputtedValueValidation>; }> |
174
+ Array<ValidatableControl.Payload<unknown, unknown, InputtedValueValidation>>;
175
+
176
+ }
@@ -11,15 +11,22 @@ component.OverflowSafeSingleLineLabel(
11
11
 
12
12
  <script lang="ts">
13
13
 
14
- import { Component as VueComponentOptions, Vue as VueComponent, Prop as VueProperty } from "vue-facing-decorator";
14
+ import {
15
+ Component as VueComponentOptions,
16
+ Vue as VueComponent,
17
+ Prop as VueProperty,
18
+ toNative as transformToOptionAPI_Component
19
+ } from "vue-facing-decorator";
15
20
 
16
21
 
17
22
  @VueComponentOptions({ name: "OverflowSafeSingleLineLabel--YDF" })
18
- export default class OverflowSafeSingleLineLabel extends VueComponent {
23
+ class OverflowSafeSingleLineLabel extends VueComponent {
19
24
 
20
25
  @VueProperty({ type: String, default: "div" })
21
26
  protected readonly rootElementTag!: string;
22
27
 
23
28
  }
24
29
 
30
+ export default transformToOptionAPI_Component(OverflowSafeSingleLineLabel);
31
+
25
32
  </script>
@@ -55,13 +55,16 @@ ul.ThemesShowcase--YDF
55
55
 
56
56
  <script lang="ts">
57
57
 
58
- import { Component as VueComponentOptions, Vue as VueComponent, Prop as VueProperty } from "vue-facing-decorator";
58
+ import {
59
+ Component as VueComponentOptions,
60
+ Vue as VueComponent,
61
+ Prop as VueProperty,
62
+ toNative as transformToOptionAPI_Component
63
+ } from "vue-facing-decorator";
59
64
 
60
65
 
61
- @VueComponentOptions({
62
- name: "ThemesShowcase--YDF"
63
- })
64
- export default class ThemesShowcase extends VueComponent {
66
+ @VueComponentOptions({ name: "ThemesShowcase--YDF" })
67
+ class ThemesShowcase extends VueComponent {
65
68
 
66
69
  @VueProperty({
67
70
  type: Object,
@@ -115,4 +118,6 @@ ul.ThemesShowcase--YDF
115
118
 
116
119
  }
117
120
 
121
+ export default transformToOptionAPI_Component(ThemesShowcase);
122
+
118
123
  </script>
@@ -1,7 +1,9 @@
1
1
  import {
2
2
  toUpperCamelCase,
3
3
  toLowerCamelCase,
4
- toScreamingSnakeCase
4
+ toScreamingSnakeCase,
5
+ isUndefined,
6
+ isNotUndefined
5
7
  } from "@yamato-daiwa/es-extensions";
6
8
 
7
9
 
@@ -54,6 +56,151 @@ export default abstract class YDF_ComponentsCoordinator {
54
56
 
55
57
  }
56
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
+
57
204
  public static generateRootElementModifierCSS_Classes(
58
205
  {
59
206
  CSS_Namespace,
@@ -62,8 +209,10 @@ export default abstract class YDF_ComponentsCoordinator {
62
209
  areThemesCSS_ClassesCommon,
63
210
  activeGeometricVariation,
64
211
  allGeometricVariations,
212
+ activeGeometricModifiers = [],
65
213
  activeDecorativeVariation,
66
- allDecorativeVariations,
214
+ allDecorativeVariations = {},
215
+ activeDecorativeModifiers = [],
67
216
  other = []
68
217
  }: Readonly<{
69
218
  CSS_Namespace: string;
@@ -72,8 +221,10 @@ export default abstract class YDF_ComponentsCoordinator {
72
221
  areThemesCSS_ClassesCommon: boolean;
73
222
  activeGeometricVariation: string;
74
223
  allGeometricVariations: Readonly<{ [geometricVariationKey: string]: string; }>;
75
- activeDecorativeVariation: string;
76
- allDecorativeVariations: Readonly<{ [decorativeVariationKey: string]: string; }>;
224
+ activeGeometricModifiers?: ReadonlyArray<string>;
225
+ activeDecorativeVariation?: string;
226
+ allDecorativeVariations?: Readonly<{ [decorativeVariationKey: string]: string; }>;
227
+ activeDecorativeModifiers?: ReadonlyArray<string>;
77
228
  other?: ReadonlyArray<string>;
78
229
  }>
79
230
  ): Array<string> {
@@ -82,8 +233,16 @@ export default abstract class YDF_ComponentsCoordinator {
82
233
  [ `${ CSS_Namespace }__${ toUpperCamelCase(activeTheme) }Theme` ] : [],
83
234
  ...Object.entries(allGeometricVariations).length > 1 ?
84
235
  [ `${ CSS_Namespace }__${ toUpperCamelCase(activeGeometricVariation) }GeometricVariation` ] : [],
85
- ...Object.entries(allDecorativeVariations).length > 1 ?
236
+ ...activeGeometricModifiers.map(
237
+ (geometricModifier: string): string =>
238
+ `${ CSS_Namespace }__${ toUpperCamelCase(geometricModifier) }GeometricModifier`
239
+ ),
240
+ ...Object.entries(allDecorativeVariations).length > 1 && isNotUndefined(activeDecorativeVariation) ?
86
241
  [ `${ CSS_Namespace }__${ toUpperCamelCase(activeDecorativeVariation) }DecorativeVariation` ] : [],
242
+ ...activeDecorativeModifiers.map(
243
+ (activeDecorativeModifier: string): string =>
244
+ `${ CSS_Namespace }__${ toUpperCamelCase(activeDecorativeModifier) }DecorativeModifier`
245
+ ),
87
246
  ...other
88
247
  ];
89
248
  }