@cybertale/form 2.0.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -5
- package/src/formComponents/ButtonComponent.vue +96 -44
- package/src/formComponents/FieldComponent.vue +76 -61
- package/src/index.ts +1 -10
- package/src/primitives/alert.ts +8 -0
- package/src/primitives/button.ts +48 -0
- package/src/primitives/checkBox.ts +25 -0
- package/src/primitives/dataList.ts +35 -0
- package/src/primitives/field.ts +30 -0
- package/src/primitives/index.ts +13 -0
- package/src/primitives/input.ts +26 -0
- package/src/primitives/label.ts +87 -0
- package/src/primitives/markdown.ts +16 -0
- package/src/primitives/modalList.ts +34 -0
- package/src/primitives/radio.ts +26 -0
- package/src/primitives/select.ts +32 -0
- package/src/primitives/shared.ts +26 -0
- package/src/primitives/textArea.ts +14 -0
- package/src/primitives/types.ts +28 -0
- package/src/scripts/alertComponentLogic.ts +5 -0
- package/src/scripts/radioComponentLogic.ts +19 -0
- package/src/scripts/textAreaComponentLogic.ts +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cybertale/form",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "ECS interface for Web Development, CyberTale edition.",
|
|
5
5
|
"author": "Joso Marich <jspmari@proton.me>",
|
|
6
6
|
"license": "GPL-3.0-only",
|
|
@@ -30,13 +30,9 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@cybertale/interface": "^2.0.6",
|
|
32
32
|
"typescript": "^5.5.3",
|
|
33
|
-
"vue": "^3.4.33",
|
|
34
|
-
"vue-facing-decorator": "^3.0.4",
|
|
35
33
|
"prompt-sync": "^4.2.0"
|
|
36
34
|
},
|
|
37
35
|
"devDependencies": {
|
|
38
|
-
"@vitejs/plugin-vue": "^5.0.5",
|
|
39
|
-
"@vue/compiler-sfc": "^3.4.33",
|
|
40
36
|
"vite": "^5.3.4"
|
|
41
37
|
},
|
|
42
38
|
"scripts": {
|
|
@@ -1,73 +1,125 @@
|
|
|
1
1
|
<template v-if="renderComponent">
|
|
2
|
-
<button
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
<button
|
|
3
|
+
data-bs-toggle="tooltip"
|
|
4
|
+
data-bs-placement="top"
|
|
5
|
+
:data-bs-title="tooltipText"
|
|
6
|
+
:hidden="isHidden"
|
|
7
|
+
:disabled="isDisabled"
|
|
8
|
+
:class="buttonClass"
|
|
9
|
+
@click.prevent="handleClick"
|
|
10
|
+
>
|
|
11
|
+
<span class="order-2">{{ buttonLabel }}</span>
|
|
12
|
+
<i v-if="showIcon" :class="iconClass"></i>
|
|
9
13
|
</button>
|
|
10
14
|
<slot></slot>
|
|
11
15
|
</template>
|
|
12
16
|
|
|
17
|
+
|
|
13
18
|
<script lang="ts">
|
|
14
19
|
import { Component, Prop, Vue } from 'vue-facing-decorator'
|
|
15
|
-
import { ObjectTemplate,
|
|
20
|
+
import { ObjectTemplate, ObjectTypeEnum, RegionEnum, RegionType, StatTypeEnum } from '@cybertale/interface'
|
|
21
|
+
|
|
22
|
+
interface LabelData {
|
|
23
|
+
iconClass: string;
|
|
24
|
+
title: string;
|
|
25
|
+
}
|
|
16
26
|
@Component
|
|
17
27
|
export default class ButtonComponent extends Vue {
|
|
18
28
|
@Prop() object!: ObjectTemplate
|
|
19
29
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
// Enums
|
|
31
|
+
StatTypeEnum = StatTypeEnum
|
|
32
|
+
ObjectTypeEnum = ObjectTypeEnum
|
|
33
|
+
RegionEnum = RegionEnum
|
|
34
|
+
btnClass = ''
|
|
35
|
+
|
|
36
|
+
renderComponent = false
|
|
37
|
+
|
|
38
|
+
// Computed properties
|
|
39
|
+
get tooltipText(): string | undefined {
|
|
40
|
+
return this.getStatData(StatTypeEnum.Tooltip)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get isHidden(): boolean {
|
|
44
|
+
return this.getStatData(StatTypeEnum.ElementType) === 'hidden'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get isDisabled(): boolean {
|
|
48
|
+
return !!this.getStatData(StatTypeEnum.Disabled, 'boolean')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get buttonClass(): string {
|
|
52
|
+
const temp = this.getValue(StatTypeEnum.Design) as string
|
|
53
|
+
return temp
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get buttonLabel(): string {
|
|
57
|
+
if(this.showIcon){
|
|
58
|
+
const value = this.getValue(StatTypeEnum.Label) as LabelData
|
|
59
|
+
return value.title
|
|
35
60
|
}
|
|
36
|
-
return
|
|
61
|
+
return this.getValue(StatTypeEnum.Label) as string
|
|
37
62
|
}
|
|
38
63
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
64
|
+
get showIcon(): boolean {
|
|
65
|
+
return this.getStatData(StatTypeEnum.ElementType) === 'icon'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get iconClass(): string {
|
|
69
|
+
if(this.showIcon){
|
|
70
|
+
const value = this.getValue(StatTypeEnum.Label) as LabelData
|
|
71
|
+
return value.iconClass
|
|
45
72
|
}
|
|
46
|
-
return
|
|
73
|
+
return this.getValue(StatTypeEnum.Label)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Methods
|
|
77
|
+
handleClick(): void {
|
|
78
|
+
const { Region, ObjectEnum } = this.object
|
|
79
|
+
RegionType.RegionTypes[Region].ObjectTypes[ObjectEnum].ChooseSubType(this.object)
|
|
47
80
|
}
|
|
48
81
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
82
|
+
getValue( statEnum: StatTypeEnum, indexStatTypeEnum = StatTypeEnum.Option): string | LabelData {
|
|
83
|
+
const tempData:string = this.getStatData(statEnum) as string
|
|
84
|
+
if (!tempData) return '';
|
|
85
|
+
|
|
86
|
+
if (this.statIsDefined(indexStatTypeEnum) && this.isJSON(tempData)) {
|
|
87
|
+
const data = JSON.parse(tempData);
|
|
88
|
+
const optionData = this.getStatData(indexStatTypeEnum) as string
|
|
89
|
+
if(this.isJSON(optionData)){
|
|
90
|
+
const parsedOptionData = JSON.parse(optionData)[Number(this.object.Stats[StatTypeEnum.OptionIndices].Data)]
|
|
91
|
+
return data[Number(parsedOptionData)] || '';
|
|
53
92
|
}
|
|
93
|
+
return data[Number(this.getStatData(indexStatTypeEnum))] || '';
|
|
54
94
|
}
|
|
95
|
+
|
|
96
|
+
return tempData;
|
|
55
97
|
}
|
|
56
98
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return this.object.Stats[this.statTypeEnum.ElementType].Data === 'hidden'
|
|
99
|
+
statIsDefined (statType: StatTypeEnum): boolean {
|
|
100
|
+
return !!this.object.Stats[statType]
|
|
60
101
|
}
|
|
61
102
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
103
|
+
getStatData(statType: StatTypeEnum, returnType: 'boolean' | 'string' = 'string'): boolean | string {
|
|
104
|
+
try {
|
|
105
|
+
const data = this.object.Stats[statType]?.Data ?? ''
|
|
106
|
+
return returnType === 'boolean' ? !!data : data
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error(`Error accessing data for statType ${statType}:`, error)
|
|
109
|
+
return returnType === 'boolean' ? false : ''
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
isJSON(str: string): boolean {
|
|
114
|
+
try {
|
|
115
|
+
return Array.isArray(JSON.parse(str))
|
|
116
|
+
} catch {
|
|
117
|
+
return false
|
|
118
|
+
}
|
|
66
119
|
}
|
|
67
120
|
}
|
|
68
121
|
</script>
|
|
69
122
|
|
|
70
|
-
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
71
123
|
<style scoped>
|
|
72
|
-
|
|
124
|
+
/* Add your scoped styles here */
|
|
73
125
|
</style>
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<input
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
<input
|
|
3
|
+
class="form-control"
|
|
4
|
+
:id="getStatData(StatTypeEnum.Tag)"
|
|
5
|
+
:required="getStatData(StatTypeEnum.Required, 'boolean')"
|
|
6
|
+
:disabled="getStatData(StatTypeEnum.Disabled, 'boolean')"
|
|
7
|
+
:autocomplete="getStatData(StatTypeEnum.AutoComplete)"
|
|
8
|
+
:class="[getStatData(StatTypeEnum.Design), validationClass]"
|
|
9
|
+
:type="getInputType()"
|
|
10
|
+
:value="computedValue"
|
|
11
|
+
:placeholder="getStatData(StatTypeEnum.Placeholder)"
|
|
12
|
+
@input="handleInput"
|
|
13
|
+
/>
|
|
14
|
+
<div v-if="showErrorMessage" class="invalid-feedback">
|
|
15
|
+
{{ getStatData(StatTypeEnum.ErrorMessage) }}
|
|
16
|
+
</div>
|
|
13
17
|
</template>
|
|
14
18
|
|
|
15
19
|
<script lang="ts">
|
|
@@ -20,74 +24,85 @@ import { ObjectTemplate, ObjectType, ObjectTypeEnum, RegionEnum, RegionType, Sta
|
|
|
20
24
|
export default class FieldComponent extends Vue {
|
|
21
25
|
@Prop() object!: ObjectTemplate
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
regionEnum = RegionEnum
|
|
27
|
+
// Enums
|
|
28
|
+
StatTypeEnum = StatTypeEnum
|
|
29
|
+
ObjectTypeEnum = ObjectTypeEnum
|
|
30
|
+
RegionEnum = RegionEnum
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
// Computed properties
|
|
33
|
+
get computedValue(): string {
|
|
34
|
+
if (this.isLabelDisabled) {
|
|
35
|
+
return this.getStatData(StatTypeEnum.Label)
|
|
32
36
|
}
|
|
33
37
|
return this.getValue(StatTypeEnum.Value, StatTypeEnum.ValueIndices)
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
get isLabelDisabled(): boolean {
|
|
41
|
+
return this.getStatData(StatTypeEnum.Tag).includes('label') &&
|
|
42
|
+
this.getStatData(StatTypeEnum.Disabled, 'boolean')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get validationClass(): string {
|
|
46
|
+
const isValid = this.getStatData(StatTypeEnum.IsValid, 'boolean')
|
|
47
|
+
const errorMessage = this.getStatData(StatTypeEnum.ErrorMessage)
|
|
48
|
+
|
|
49
|
+
if (isValid === undefined || isValid === '') return ''
|
|
50
|
+
if (isValid) return 'is-valid'
|
|
51
|
+
if (errorMessage) return 'is-invalid'
|
|
45
52
|
return ''
|
|
46
53
|
}
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
get showErrorMessage(): boolean {
|
|
56
|
+
return this.validationClass === 'is-invalid'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Methods
|
|
60
|
+
getInputType(): string {
|
|
61
|
+
return this.getValue(StatTypeEnum.ElementType)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
handleInput(event: Event): void {
|
|
65
|
+
const target = event.target as HTMLInputElement
|
|
66
|
+
const { Region, ObjectEnum } = this.object
|
|
67
|
+
console.log(target.value)
|
|
68
|
+
RegionType.RegionTypes[Region].ObjectTypes[ObjectEnum].ChooseSubType(this.object, target.value)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getValue( statEnum: StatTypeEnum, indexStatTypeEnum = StatTypeEnum.Option): string {
|
|
72
|
+
const tempData:string = this.getStatData(statEnum)
|
|
73
|
+
if (!tempData) return '';
|
|
74
|
+
|
|
75
|
+
if (this.statIsDefined(indexStatTypeEnum) && this.isJSON(tempData)) {
|
|
76
|
+
const data = JSON.parse(tempData);
|
|
77
|
+
return data[Number(this.getStatData(indexStatTypeEnum))] || '';
|
|
54
78
|
}
|
|
79
|
+
|
|
80
|
+
return tempData;
|
|
55
81
|
}
|
|
56
82
|
|
|
57
|
-
|
|
58
|
-
return this.object.Stats[
|
|
83
|
+
statIsDefined (statType: StatTypeEnum): boolean {
|
|
84
|
+
return !!this.object.Stats[statType]
|
|
59
85
|
}
|
|
60
86
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
87
|
+
getStatData(statType: StatTypeEnum, returnType: 'boolean' | 'string' = 'string'): boolean | string {
|
|
88
|
+
try {
|
|
89
|
+
const data = this.object.Stats[statType]?.Data ?? ''
|
|
90
|
+
return returnType === 'boolean' ? !!data : data
|
|
91
|
+
} catch (error) {
|
|
92
|
+
return returnType === 'boolean' ? false : ''
|
|
93
|
+
}
|
|
68
94
|
}
|
|
69
95
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
96
|
+
isJSON(str: string): boolean {
|
|
97
|
+
try {
|
|
98
|
+
return Array.isArray(JSON.parse(str))
|
|
99
|
+
} catch {
|
|
100
|
+
return false
|
|
101
|
+
}
|
|
74
102
|
}
|
|
75
103
|
|
|
76
104
|
tooltipCase(): string | undefined {
|
|
77
|
-
return this.object?.Stats[
|
|
105
|
+
return this.object?.Stats[StatTypeEnum.Tooltip]?.Data
|
|
78
106
|
}
|
|
79
107
|
}
|
|
80
108
|
</script>
|
|
81
|
-
|
|
82
|
-
<style scoped>
|
|
83
|
-
.form-check .form-check-input {
|
|
84
|
-
float: none;
|
|
85
|
-
}
|
|
86
|
-
.form-check-input {
|
|
87
|
-
margin-right: 1%;
|
|
88
|
-
}
|
|
89
|
-
.form-check-input:checked {
|
|
90
|
-
background-color: #606467;
|
|
91
|
-
border-color: #606467;
|
|
92
|
-
}
|
|
93
|
-
</style>
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import ButtonComponent from './formComponents/ButtonComponent.vue'
|
|
3
|
-
import CheckBoxComponent from './formComponents/CheckBoxComponent.vue'
|
|
4
|
-
import DataListComponent from './formComponents/DataListComponent.vue'
|
|
5
|
-
import FieldComponent from './formComponents/FieldComponent.vue'
|
|
6
|
-
import LabelComponent from './formComponents/LabelComponent.vue'
|
|
7
|
-
import RadioComponent from './formComponents/RadioComponent.vue'
|
|
8
|
-
import SelectListComponent from './formComponents/SelectListComponent.vue'
|
|
9
|
-
|
|
10
|
-
export { AlertComponent, ButtonComponent, CheckBoxComponent, DataListComponent, FieldComponent, LabelComponent, RadioComponent, SelectListComponent }
|
|
1
|
+
export * from './primitives'
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { GetStringStat, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
export function buildAlertModel(object: ObjectTemplate) {
|
|
4
|
+
return {
|
|
5
|
+
className: GetStringStat(object, StatTypeEnum.Design),
|
|
6
|
+
text: GetStringStat(object, StatTypeEnum.Label)
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { GetStatData, GetStringStat, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
import { getLabelData } from './shared'
|
|
4
|
+
import { TooltipData } from './types'
|
|
5
|
+
|
|
6
|
+
export function buildButtonModel(object: ObjectTemplate, currentPath = '') {
|
|
7
|
+
const tooltip = GetValue(object, StatTypeEnum.Tooltip) as TooltipData | string
|
|
8
|
+
const tooltipToggleBy = typeof tooltip === 'string' ? 'tooltip' : tooltip.toggleBy
|
|
9
|
+
const tooltipText = typeof tooltip === 'string' ? tooltip : tooltip.value
|
|
10
|
+
const labelValue = GetValue(object, StatTypeEnum.Label)
|
|
11
|
+
const labelData = getLabelData(labelValue)
|
|
12
|
+
const tag = GetStringStat(object, StatTypeEnum.Tag)
|
|
13
|
+
|
|
14
|
+
let label = ''
|
|
15
|
+
if (labelData && 'title' in labelData) {
|
|
16
|
+
label = labelData.title
|
|
17
|
+
} else {
|
|
18
|
+
label = labelValue as string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const lowerLabel = label.toLowerCase()
|
|
22
|
+
if ((tag === 'buttonDelete' || lowerLabel.includes('delete') || lowerLabel.includes('izbri\u0161i')) && !currentPath.includes('add')) {
|
|
23
|
+
label = '<i class="fa-solid fa-trash-alt"></i> ' + label
|
|
24
|
+
} else if (tag === 'buttonEdit' || lowerLabel.includes('edit') || lowerLabel.includes('uredi')) {
|
|
25
|
+
label = '<i class="fa-solid fa-edit"></i> ' + label
|
|
26
|
+
} else if (tag === 'buttonMap' || lowerLabel.includes('kart')) {
|
|
27
|
+
label = '<i class="fa-solid fa-map-marker-alt"></i> ' + label
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const showIcon = GetStatData(object, StatTypeEnum.ElementType) === 'icon'
|
|
31
|
+
const iconClass = showIcon && labelData ? labelData.iconClass : (labelValue as string)
|
|
32
|
+
const styleData = showIcon && labelData ? labelData.styleData : (labelValue as string)
|
|
33
|
+
const contentClass = showIcon && labelData ? labelData.contentClass : ''
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
tooltipToggleBy,
|
|
37
|
+
tooltipText,
|
|
38
|
+
isHidden: GetStatData(object, StatTypeEnum.ElementType) === 'hidden',
|
|
39
|
+
isDisabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
|
|
40
|
+
buttonClass: GetValue(object, StatTypeEnum.Design) as string,
|
|
41
|
+
buttonLabel: label,
|
|
42
|
+
showIcon,
|
|
43
|
+
iconClass,
|
|
44
|
+
styleData,
|
|
45
|
+
contentClass,
|
|
46
|
+
contentValue: ''
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetStatData,
|
|
3
|
+
GetStringStat,
|
|
4
|
+
GetValidationClass,
|
|
5
|
+
GetValue,
|
|
6
|
+
ObjectTemplate,
|
|
7
|
+
StatTypeEnum
|
|
8
|
+
} from '@cybertale/interface'
|
|
9
|
+
|
|
10
|
+
import { applyValue } from './shared'
|
|
11
|
+
|
|
12
|
+
export function buildCheckBoxModel(object: ObjectTemplate) {
|
|
13
|
+
return {
|
|
14
|
+
designClass: GetStringStat(object, StatTypeEnum.Design),
|
|
15
|
+
checked: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices),
|
|
16
|
+
name: GetStringStat(object, StatTypeEnum.Tag),
|
|
17
|
+
id: GetStringStat(object, StatTypeEnum.Tag),
|
|
18
|
+
required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
|
|
19
|
+
disabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
|
|
20
|
+
label: GetStringStat(object, StatTypeEnum.Label),
|
|
21
|
+
validationClass: GetValidationClass(object),
|
|
22
|
+
errorMessage: GetStringStat(object, StatTypeEnum.ErrorMessage),
|
|
23
|
+
select: (checked: boolean) => applyValue(object, checked)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetRawStat,
|
|
3
|
+
GetStatData,
|
|
4
|
+
GetStringStat,
|
|
5
|
+
GetValidationClass,
|
|
6
|
+
GetValue,
|
|
7
|
+
ObjectTemplate,
|
|
8
|
+
StatTypeEnum
|
|
9
|
+
} from '@cybertale/interface'
|
|
10
|
+
|
|
11
|
+
import { applyValue } from './shared'
|
|
12
|
+
|
|
13
|
+
export function buildDataListModel(object: ObjectTemplate) {
|
|
14
|
+
return {
|
|
15
|
+
belongsTo: GetStringStat(object, StatTypeEnum.BelongsTo),
|
|
16
|
+
tag: GetStringStat(object, StatTypeEnum.Tag),
|
|
17
|
+
name: GetStringStat(object, StatTypeEnum.Name),
|
|
18
|
+
designClass: GetStringStat(object, StatTypeEnum.Design),
|
|
19
|
+
required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
|
|
20
|
+
disabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
|
|
21
|
+
type: GetStringStat(object, StatTypeEnum.ElementType),
|
|
22
|
+
placeholder: GetStringStat(object, StatTypeEnum.Placeholder),
|
|
23
|
+
validationClass: GetValidationClass(object),
|
|
24
|
+
errorMessage: GetStringStat(object, StatTypeEnum.ErrorMessage),
|
|
25
|
+
rawValue: GetRawStat(object, StatTypeEnum.Value),
|
|
26
|
+
selectedValue: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices),
|
|
27
|
+
itemListRaw: GetStringStat(object, StatTypeEnum.ItemList),
|
|
28
|
+
setItemListRaw: (value: string) => {
|
|
29
|
+
if (object.Stats?.[StatTypeEnum.ItemList]) {
|
|
30
|
+
object.Stats[StatTypeEnum.ItemList].Data = value
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
select: (value: string) => applyValue(object, value)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { GetStatData, GetValidationClass, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
import { applyValue } from './shared'
|
|
4
|
+
|
|
5
|
+
export function buildFieldModel(object: ObjectTemplate) {
|
|
6
|
+
return {
|
|
7
|
+
tag: GetStatData(object, StatTypeEnum.Tag) as string,
|
|
8
|
+
label: GetStatData(object, StatTypeEnum.Label) as string,
|
|
9
|
+
required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
|
|
10
|
+
disabled: !!GetValue(object, StatTypeEnum.Disabled),
|
|
11
|
+
readOnly: GetStatData(object, StatTypeEnum.ReadOnly, 'boolean') as boolean,
|
|
12
|
+
autocomplete: GetStatData(object, StatTypeEnum.AutoComplete) as string,
|
|
13
|
+
type: GetValue(object, StatTypeEnum.ElementType) as string,
|
|
14
|
+
value: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices) as string,
|
|
15
|
+
placeholder: GetStatData(object, StatTypeEnum.Placeholder) as string,
|
|
16
|
+
maxLength: GetStatData(object, StatTypeEnum.MaxLength) as string,
|
|
17
|
+
minLength: GetStatData(object, StatTypeEnum.MinLength) as string,
|
|
18
|
+
min: GetStatData(object, StatTypeEnum.Min) as string,
|
|
19
|
+
max: GetStatData(object, StatTypeEnum.Max) as string,
|
|
20
|
+
step: GetStatData(object, StatTypeEnum.Step) as string,
|
|
21
|
+
pattern: GetStatData(object, StatTypeEnum.Pattern) as string,
|
|
22
|
+
helpText: GetStatData(object, StatTypeEnum.HelpText) as string,
|
|
23
|
+
leadingIcon: GetStatData(object, StatTypeEnum.LeadingIcon) as string,
|
|
24
|
+
trailingIcon: GetStatData(object, StatTypeEnum.TrailingIcon) as string,
|
|
25
|
+
validationClass: GetValidationClass(object),
|
|
26
|
+
bootstrapClass: GetValue(object, StatTypeEnum.Design) as string,
|
|
27
|
+
errorMessage: GetStatData(object, StatTypeEnum.ErrorMessage) as string,
|
|
28
|
+
select: (value: string) => applyValue(object, value)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './types'
|
|
2
|
+
export * from './alert'
|
|
3
|
+
export * from './textArea'
|
|
4
|
+
export * from './radio'
|
|
5
|
+
export * from './checkBox'
|
|
6
|
+
export * from './select'
|
|
7
|
+
export * from './label'
|
|
8
|
+
export * from './button'
|
|
9
|
+
export * from './input'
|
|
10
|
+
export * from './dataList'
|
|
11
|
+
export * from './field'
|
|
12
|
+
export * from './markdown'
|
|
13
|
+
export * from './modalList'
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetStatData,
|
|
3
|
+
GetStringStat,
|
|
4
|
+
GetValidationClass,
|
|
5
|
+
GetValue,
|
|
6
|
+
ObjectTemplate,
|
|
7
|
+
StatTypeEnum
|
|
8
|
+
} from '@cybertale/interface'
|
|
9
|
+
|
|
10
|
+
import { applyValue } from './shared'
|
|
11
|
+
|
|
12
|
+
export function buildInputModel(object: ObjectTemplate) {
|
|
13
|
+
return {
|
|
14
|
+
id: GetStringStat(object, StatTypeEnum.Tag),
|
|
15
|
+
name: GetStringStat(object, StatTypeEnum.Tag),
|
|
16
|
+
type: (GetValue(object, StatTypeEnum.ElementType) as string) || 'text',
|
|
17
|
+
placeholder: GetStringStat(object, StatTypeEnum.Placeholder),
|
|
18
|
+
required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
|
|
19
|
+
disabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
|
|
20
|
+
readOnly: GetStatData(object, StatTypeEnum.ReadOnly, 'boolean') as boolean,
|
|
21
|
+
autocomplete: GetStringStat(object, StatTypeEnum.AutoComplete),
|
|
22
|
+
value: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices),
|
|
23
|
+
validationClass: GetValidationClass(object),
|
|
24
|
+
select: (value: string) => applyValue(object, value)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { GetStatData, GetStringStat, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
import { getLabelData } from './shared'
|
|
4
|
+
|
|
5
|
+
function hexToRgb(hex: string) {
|
|
6
|
+
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i
|
|
7
|
+
hex = hex.replace(shorthandRegex, (_m, r, g, b) => r + r + g + g + b + b)
|
|
8
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
|
9
|
+
return result
|
|
10
|
+
? {
|
|
11
|
+
r: parseInt(result[1], 16),
|
|
12
|
+
g: parseInt(result[2], 16),
|
|
13
|
+
b: parseInt(result[3], 16)
|
|
14
|
+
}
|
|
15
|
+
: null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getLuminance(rgb: { r: number; g: number; b: number }) {
|
|
19
|
+
const a = [rgb.r, rgb.g, rgb.b].map((v) => {
|
|
20
|
+
v /= 255
|
|
21
|
+
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4)
|
|
22
|
+
})
|
|
23
|
+
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getContrastRatio(luminance1: number, luminance2: number) {
|
|
27
|
+
const lightest = Math.max(luminance1, luminance2)
|
|
28
|
+
const darkest = Math.min(luminance1, luminance2)
|
|
29
|
+
return (lightest + 0.05) / (darkest + 0.05)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function isDarkBackground(bgHex: string) {
|
|
33
|
+
const bgRgb = hexToRgb(bgHex)
|
|
34
|
+
if (!bgRgb) return false
|
|
35
|
+
const bgLuminance = getLuminance(bgRgb)
|
|
36
|
+
const whiteLuminance = getLuminance({ r: 255, g: 255, b: 255 })
|
|
37
|
+
const blackLuminance = getLuminance({ r: 0, g: 0, b: 0 })
|
|
38
|
+
|
|
39
|
+
const whiteContrast = getContrastRatio(bgLuminance, whiteLuminance)
|
|
40
|
+
const blackContrast = getContrastRatio(bgLuminance, blackLuminance)
|
|
41
|
+
|
|
42
|
+
return whiteContrast > blackContrast
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function extractHexColor(styleData: string): string {
|
|
46
|
+
const match = styleData.match(/background-color:\s*(#[0-9a-fA-F]{3,6})/)
|
|
47
|
+
return match ? match[1] : ''
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function buildLabelModel(object: ObjectTemplate) {
|
|
51
|
+
const showIcon = GetStatData(object, StatTypeEnum.ElementType) === 'icon'
|
|
52
|
+
const labelValue = GetValue(object, StatTypeEnum.Label)
|
|
53
|
+
const labelData = getLabelData(labelValue)
|
|
54
|
+
const tooltip = GetStringStat(object, StatTypeEnum.Tooltip)
|
|
55
|
+
const designClass = GetValue(object, StatTypeEnum.Design) as string
|
|
56
|
+
|
|
57
|
+
const label = showIcon && labelData ? labelData.title : (labelValue as string)
|
|
58
|
+
const iconClass = showIcon && labelData ? labelData.iconClass : ''
|
|
59
|
+
const markValue = showIcon && labelData ? labelData.markValue : ''
|
|
60
|
+
const styleData = showIcon && labelData ? labelData.styleData : ''
|
|
61
|
+
const contentClass = showIcon && labelData ? labelData.contentClass : ''
|
|
62
|
+
const contentValue = ''
|
|
63
|
+
|
|
64
|
+
let markClass = ''
|
|
65
|
+
if (showIcon && labelData) {
|
|
66
|
+
const backgroundColor = labelData.styleData
|
|
67
|
+
if (isDarkBackground(extractHexColor(backgroundColor))) {
|
|
68
|
+
markClass = labelData.markClass + ' text-white'
|
|
69
|
+
} else {
|
|
70
|
+
markClass = labelData.markClass
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
showIcon,
|
|
76
|
+
designClass,
|
|
77
|
+
label,
|
|
78
|
+
iconClass,
|
|
79
|
+
markValue,
|
|
80
|
+
markClass,
|
|
81
|
+
styleData,
|
|
82
|
+
contentValue,
|
|
83
|
+
contentClass,
|
|
84
|
+
hidden: GetValue(object, StatTypeEnum.ElementType) === 'hidden',
|
|
85
|
+
tooltip: tooltip || undefined
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { GetValidationClass, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
import { applyValue, buildParsedStats } from './shared'
|
|
4
|
+
|
|
5
|
+
export function buildMarkdownModel(object: ObjectTemplate) {
|
|
6
|
+
const parsedStats = buildParsedStats(object)
|
|
7
|
+
return {
|
|
8
|
+
design: parsedStats[StatTypeEnum.Design],
|
|
9
|
+
placeholder: parsedStats[StatTypeEnum.Placeholder],
|
|
10
|
+
required: parsedStats[StatTypeEnum.Required],
|
|
11
|
+
disabled: parsedStats[StatTypeEnum.Disabled],
|
|
12
|
+
validationClass: GetValidationClass(object),
|
|
13
|
+
value: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices),
|
|
14
|
+
select: (value: unknown) => applyValue(object, value)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { GetValidationClass, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
import { applyValue, buildParsedStats } from './shared'
|
|
4
|
+
|
|
5
|
+
export function buildModalListModel(object: ObjectTemplate) {
|
|
6
|
+
const parsedStats = buildParsedStats(object)
|
|
7
|
+
const value = GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices)
|
|
8
|
+
const valueName = value && typeof value === 'object' && 'name' in value
|
|
9
|
+
? (value as { name: string }).name
|
|
10
|
+
: (value as string)
|
|
11
|
+
const valueIcon = value && typeof value === 'object' && 'id' in value
|
|
12
|
+
? (value as { id: string }).id
|
|
13
|
+
: (value as string)
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
design: parsedStats[StatTypeEnum.Design],
|
|
17
|
+
placeholder: parsedStats[StatTypeEnum.Placeholder],
|
|
18
|
+
required: parsedStats[StatTypeEnum.Required],
|
|
19
|
+
disabled: parsedStats[StatTypeEnum.Disabled],
|
|
20
|
+
elementType: parsedStats[StatTypeEnum.ElementType],
|
|
21
|
+
itemList: parsedStats[StatTypeEnum.ItemList],
|
|
22
|
+
name: parsedStats[StatTypeEnum.Name],
|
|
23
|
+
validationClass: GetValidationClass(object),
|
|
24
|
+
value,
|
|
25
|
+
valueName,
|
|
26
|
+
valueIcon,
|
|
27
|
+
setItemListRaw: (raw: string) => {
|
|
28
|
+
if (object.Stats?.[StatTypeEnum.ItemList]) {
|
|
29
|
+
object.Stats[StatTypeEnum.ItemList].Data = raw
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
select: (next: string) => applyValue(object, next)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { GetRawStat, GetStringStat, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
import { applyValue } from './shared'
|
|
4
|
+
import { RadioOption } from './types'
|
|
5
|
+
|
|
6
|
+
export function buildRadioModel(object: ObjectTemplate) {
|
|
7
|
+
const itemListRaw = GetStringStat(object, StatTypeEnum.ItemList)
|
|
8
|
+
const name = GetStringStat(object, StatTypeEnum.Name)
|
|
9
|
+
const tag = GetStringStat(object, StatTypeEnum.Tag)
|
|
10
|
+
const isGroup = itemListRaw !== '' && name === ''
|
|
11
|
+
const items = isGroup ? (JSON.parse(itemListRaw) as RadioOption[]) : []
|
|
12
|
+
|
|
13
|
+
const isChecked = (candidate: unknown) => GetRawStat(object, StatTypeEnum.Value) === candidate
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
className: GetStringStat(object, StatTypeEnum.Design),
|
|
17
|
+
isGroup,
|
|
18
|
+
items,
|
|
19
|
+
groupName: tag,
|
|
20
|
+
name,
|
|
21
|
+
singleValue: itemListRaw,
|
|
22
|
+
singleLabel: itemListRaw,
|
|
23
|
+
isChecked,
|
|
24
|
+
select: (value: unknown) => applyValue(object, value)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetStatData,
|
|
3
|
+
GetStringStat,
|
|
4
|
+
GetValidationClass,
|
|
5
|
+
GetValue,
|
|
6
|
+
ObjectTemplate,
|
|
7
|
+
ParseJSON,
|
|
8
|
+
StatTypeEnum
|
|
9
|
+
} from '@cybertale/interface'
|
|
10
|
+
|
|
11
|
+
import { applyValue } from './shared'
|
|
12
|
+
import { SelectOption } from './types'
|
|
13
|
+
|
|
14
|
+
export function buildSelectModel(object: ObjectTemplate) {
|
|
15
|
+
const itemListRaw = GetStringStat(object, StatTypeEnum.ItemList)
|
|
16
|
+
const items = ParseJSON<SelectOption[]>(itemListRaw) ?? []
|
|
17
|
+
const selected = GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices)
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
name: GetStringStat(object, StatTypeEnum.Tag),
|
|
21
|
+
hidden: GetValue(object, StatTypeEnum.ElementType) === 'hidden',
|
|
22
|
+
required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
|
|
23
|
+
disabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
|
|
24
|
+
autocomplete: GetStringStat(object, StatTypeEnum.AutoComplete),
|
|
25
|
+
validationClass: GetValidationClass(object),
|
|
26
|
+
errorMessage: GetStringStat(object, StatTypeEnum.ErrorMessage),
|
|
27
|
+
items,
|
|
28
|
+
isSelected: (id: string | number) => selected === id.toString(),
|
|
29
|
+
placeholderSelected: GetStatData(object, StatTypeEnum.Value, 'boolean') as boolean,
|
|
30
|
+
select: (value: string) => applyValue(object, value)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ObjectTemplate, ParseJSON, RegionType, StatTypeEnum } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
import { LabelData } from './types'
|
|
4
|
+
|
|
5
|
+
export function applyValue(object: ObjectTemplate, value: unknown) {
|
|
6
|
+
RegionType.RegionTypes[object.Region]
|
|
7
|
+
.ObjectTypes[object.ObjectEnum]
|
|
8
|
+
.ChooseSubType(object, value)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function buildParsedStats(object: ObjectTemplate): Record<number, any> {
|
|
12
|
+
const parsed: Record<number, any> = {}
|
|
13
|
+
const stats = object.Stats ?? {}
|
|
14
|
+
Object.entries(stats).forEach(([key, stat]) => {
|
|
15
|
+
const parsedValue = ParseJSON(stat.Data as string | null | undefined)
|
|
16
|
+
parsed[Number(key)] = parsedValue == null ? stat.Data : parsedValue
|
|
17
|
+
})
|
|
18
|
+
return parsed
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getLabelData(value: unknown): LabelData | null {
|
|
22
|
+
if (typeof value === 'object' && value !== null) {
|
|
23
|
+
return value as LabelData
|
|
24
|
+
}
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GetStringStat, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
export function buildTextAreaModel(object: ObjectTemplate) {
|
|
4
|
+
return {
|
|
5
|
+
label: GetStringStat(object, StatTypeEnum.Label),
|
|
6
|
+
tooltip: GetStringStat(object, StatTypeEnum.Tooltip),
|
|
7
|
+
value: GetStringStat(object, StatTypeEnum.Value),
|
|
8
|
+
setValue: (next: string) => {
|
|
9
|
+
if (object.Stats?.[StatTypeEnum.Value]) {
|
|
10
|
+
object.Stats[StatTypeEnum.Value].Data = next
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface LabelData {
|
|
2
|
+
styleData: string
|
|
3
|
+
iconClass: string
|
|
4
|
+
title: string
|
|
5
|
+
markValue: string
|
|
6
|
+
markClass: string
|
|
7
|
+
contentValue: string
|
|
8
|
+
contentClass: string
|
|
9
|
+
distanceFromSea: string
|
|
10
|
+
translate: string
|
|
11
|
+
number: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface TooltipData {
|
|
15
|
+
toggleBy: string
|
|
16
|
+
value: string
|
|
17
|
+
translate?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SelectOption {
|
|
21
|
+
id: string | number
|
|
22
|
+
name: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface RadioOption {
|
|
26
|
+
id: string | number
|
|
27
|
+
name: string
|
|
28
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ObjectTemplate, ObjectType, ObjectTypeEnum, RegionType, RegionEnum, StatTypeEnum, GetStringStat } from '@cybertale/interface'
|
|
2
|
+
|
|
3
|
+
export class RadioComponentLogic {
|
|
4
|
+
statTypeEnum = StatTypeEnum
|
|
5
|
+
objectTypeEnum = ObjectTypeEnum
|
|
6
|
+
objectType = ObjectType
|
|
7
|
+
regionType = RegionType
|
|
8
|
+
regionEnum = RegionEnum
|
|
9
|
+
|
|
10
|
+
returnIfExists(object: ObjectTemplate, tag: number): string {
|
|
11
|
+
return GetStringStat(object, tag as StatTypeEnum)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
handleInput(object: ObjectTemplate, value: string) {
|
|
15
|
+
this.regionType.RegionTypes[object.Region]
|
|
16
|
+
.ObjectTypes[object.ObjectEnum]
|
|
17
|
+
.ChooseSubType(object as ObjectTemplate, value)
|
|
18
|
+
}
|
|
19
|
+
}
|