Created smart toggles for limited choice fields
This commit is contained in:
70
app/imports/client/ui/components/global/SmartToggle.vue
Normal file
70
app/imports/client/ui/components/global/SmartToggle.vue
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<outlined-input
|
||||||
|
:name="label"
|
||||||
|
class="mb-6 pt-1"
|
||||||
|
>
|
||||||
|
<v-btn-toggle
|
||||||
|
v-bind="$attrs"
|
||||||
|
mandatory
|
||||||
|
tile
|
||||||
|
group
|
||||||
|
:value="safeValue"
|
||||||
|
color="accent"
|
||||||
|
style="flex-wrap: wrap;"
|
||||||
|
>
|
||||||
|
<v-btn
|
||||||
|
v-for="(option, i) in options"
|
||||||
|
:key="`toggle-option-${i}`"
|
||||||
|
:value="option.value"
|
||||||
|
:disabled="isDisabled || (clickedValue != option.value && loading)"
|
||||||
|
:plain="clickedValue != option.value && loading"
|
||||||
|
:loading="clickedValue == option.value && loading"
|
||||||
|
height="42"
|
||||||
|
v-on="(value == option.value) ? {} : { click() { click(option.value) } }"
|
||||||
|
>
|
||||||
|
{{ option.name }}
|
||||||
|
</v-btn>
|
||||||
|
</v-btn-toggle>
|
||||||
|
<v-expand-transition>
|
||||||
|
<div
|
||||||
|
v-if="errors.length"
|
||||||
|
class="pa-2 error--text"
|
||||||
|
>
|
||||||
|
{{ errors.join('\n\n') }}
|
||||||
|
</div>
|
||||||
|
</v-expand-transition>
|
||||||
|
</outlined-input>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import SmartInput from '/imports/client/ui/components/global/SmartInputMixin.js';
|
||||||
|
import OutlinedInput from '/imports/client/ui/properties/viewers/shared/OutlinedInput.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
OutlinedInput,
|
||||||
|
},
|
||||||
|
mixins: [SmartInput],
|
||||||
|
props: {
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
clickedValue: undefined,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
click(val) {
|
||||||
|
this.clickedValue = val;
|
||||||
|
this.change(val);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -10,6 +10,7 @@ import SmartBtn from '/imports/client/ui/components/global/SmartBtn.vue';
|
|||||||
import SmartCombobox from '/imports/client/ui/components/global/SmartCombobox.vue';
|
import SmartCombobox from '/imports/client/ui/components/global/SmartCombobox.vue';
|
||||||
import SmartCheckbox from '/imports/client/ui/components/global/SmartCheckbox.vue';
|
import SmartCheckbox from '/imports/client/ui/components/global/SmartCheckbox.vue';
|
||||||
import SmartSwitch from '/imports/client/ui/components/global/SmartSwitch.vue';
|
import SmartSwitch from '/imports/client/ui/components/global/SmartSwitch.vue';
|
||||||
|
import SmartToggle from '/imports/client/ui/components/global/SmartToggle.vue';
|
||||||
import SvgIcon from '/imports/client/ui/components/global/SvgIcon.vue';
|
import SvgIcon from '/imports/client/ui/components/global/SvgIcon.vue';
|
||||||
import SmartSlider from '/imports/client/ui/components/global/SmartSlider.vue';
|
import SmartSlider from '/imports/client/ui/components/global/SmartSlider.vue';
|
||||||
|
|
||||||
@@ -24,4 +25,5 @@ Vue.component('SmartCombobox', SmartCombobox);
|
|||||||
Vue.component('SmartCheckbox', SmartCheckbox);
|
Vue.component('SmartCheckbox', SmartCheckbox);
|
||||||
Vue.component('SmartSlider', SmartSlider);
|
Vue.component('SmartSlider', SmartSlider);
|
||||||
Vue.component('SmartSwitch', SmartSwitch);
|
Vue.component('SmartSwitch', SmartSwitch);
|
||||||
|
Vue.component('SmartToggle', SmartToggle);
|
||||||
Vue.component('SvgIcon', SvgIcon);
|
Vue.component('SvgIcon', SvgIcon);
|
||||||
|
|||||||
@@ -63,19 +63,21 @@
|
|||||||
/>
|
/>
|
||||||
</v-slide-x-transition>
|
</v-slide-x-transition>
|
||||||
|
|
||||||
<smart-select
|
<smart-toggle
|
||||||
label="Target"
|
label="Target creature"
|
||||||
style="flex-basis: 300px;"
|
|
||||||
:items="targetOptions"
|
|
||||||
:value="model.target"
|
:value="model.target"
|
||||||
|
:options="[
|
||||||
|
{name: 'Single Target', value: 'singleTarget'},
|
||||||
|
{name: 'Multiple Targets', value: 'multipleTargets'},
|
||||||
|
{name: 'Self', value: 'self'},
|
||||||
|
]"
|
||||||
:error-messages="errors.target"
|
:error-messages="errors.target"
|
||||||
:menu-props="{auto: true, lazy: true}"
|
|
||||||
@change="change('target', ...arguments)"
|
@change="change('target', ...arguments)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<inline-computation-field
|
<inline-computation-field
|
||||||
label="Summary"
|
label="Summary"
|
||||||
hint="This will appear in the action card in the character sheet, summarise what the action does"
|
hint="This will appear in the action card in the character sheet, summarize what the action does"
|
||||||
:model="model.summary"
|
:model="model.summary"
|
||||||
:error-messages="errors.summary"
|
:error-messages="errors.summary"
|
||||||
@change="({path, value, ack}) =>
|
@change="({path, value, ack}) =>
|
||||||
|
|||||||
@@ -34,11 +34,14 @@
|
|||||||
cols="12"
|
cols="12"
|
||||||
md="6"
|
md="6"
|
||||||
>
|
>
|
||||||
<smart-select
|
<smart-toggle
|
||||||
label="Operation"
|
label="Operation"
|
||||||
hint="Should the attribute be damaged by the amount, or set to the amount"
|
hint="Should the attribute be damaged by the amount, or set to the amount"
|
||||||
:items="adjustmentOps"
|
|
||||||
:value="model.operation"
|
:value="model.operation"
|
||||||
|
:options="[
|
||||||
|
{ name: 'Damage', value: 'increment' },
|
||||||
|
{ name: 'Set', value: 'set' },
|
||||||
|
]"
|
||||||
:error-messages="errors.operation"
|
:error-messages="errors.operation"
|
||||||
@change="change('operation', ...arguments)"
|
@change="change('operation', ...arguments)"
|
||||||
/>
|
/>
|
||||||
@@ -47,14 +50,14 @@
|
|||||||
cols="12"
|
cols="12"
|
||||||
md="6"
|
md="6"
|
||||||
>
|
>
|
||||||
<smart-select
|
<smart-toggle
|
||||||
v-if="parentTarget !== 'self'"
|
label="Target creature"
|
||||||
label="Target"
|
|
||||||
:hint="targetOptionHint"
|
|
||||||
:items="targetOptions"
|
|
||||||
:value="model.target"
|
:value="model.target"
|
||||||
|
:options="[
|
||||||
|
{name: 'Action Target', value: 'target'},
|
||||||
|
{name: 'Self', value: 'self'},
|
||||||
|
]"
|
||||||
:error-messages="errors.target"
|
:error-messages="errors.target"
|
||||||
:menu-props="{auto: true, lazy: true}"
|
|
||||||
@change="change('target', ...arguments)"
|
@change="change('target', ...arguments)"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
@@ -85,58 +88,10 @@ import propertyFormMixin from '/imports/client/ui/properties/forms/shared/proper
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [propertyFormMixin, attributeListMixin],
|
mixins: [propertyFormMixin, attributeListMixin],
|
||||||
props: {
|
|
||||||
parentTarget: {
|
|
||||||
type: String,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
adjustmentOps: [
|
damageHint: 'The amount of damage to apply, negative values will heal',
|
||||||
{ text: 'Damage', value: 'increment' },
|
setHint: 'The value to set the stat to',
|
||||||
{ text: 'Set', value: 'set' },
|
|
||||||
],
|
|
||||||
damageHint: 'The amount of damage to apply to the selected stat, can be a calculation or roll. Negative values will restore the selected from previous damage. If the operation is set, this is the final value of the stat instead.',
|
|
||||||
setHint: 'The value of the stat after applying this adjustment. The stat\'s value can\'t exceed its total',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
targetOptions() {
|
|
||||||
if (this.parentTarget === 'singleTarget') {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
text: 'Self',
|
|
||||||
value: 'self',
|
|
||||||
}, {
|
|
||||||
text: 'Target',
|
|
||||||
value: 'every',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
text: 'Self',
|
|
||||||
value: 'self',
|
|
||||||
}, {
|
|
||||||
text: 'Target',
|
|
||||||
value: 'target',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
targetOptionHint() {
|
|
||||||
let hints = {
|
|
||||||
self: 'The damage will be applied to the character\'s own attribute when taking the action',
|
|
||||||
target: 'The damage will be applied to the target of the action',
|
|
||||||
each: 'The damage will be rolled separately for each of the targets of the action',
|
|
||||||
every: 'The damage will be rolled once and applied to each of the targets of the action',
|
|
||||||
};
|
|
||||||
if (this.parentTarget === 'singleTarget') {
|
|
||||||
hints.each = hints.target;
|
|
||||||
hints.every = hints.target;
|
|
||||||
}
|
|
||||||
return hints[this.model.target];
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,90 +79,115 @@
|
|||||||
v-if="model.attributeType === 'healthBar'"
|
v-if="model.attributeType === 'healthBar'"
|
||||||
name="Health Bar"
|
name="Health Bar"
|
||||||
>
|
>
|
||||||
<div
|
<div class="d-flex flex-column align-center mb-4">
|
||||||
class="d-flex flex-wrap align-center justify-start"
|
<div class="text-caption mb-4">
|
||||||
>
|
Damaged Colors
|
||||||
<div class="text-subtitle-1">
|
|
||||||
Damaged Colors:
|
|
||||||
</div>
|
</div>
|
||||||
<outlined-input
|
<div
|
||||||
name="Half"
|
class="d-flex flex-wrap align-center justify-start"
|
||||||
class="mb-4 ml-2"
|
|
||||||
>
|
>
|
||||||
<color-picker
|
<outlined-input
|
||||||
:value="model.healthBarColorMid"
|
name="Half"
|
||||||
:width="54"
|
class="mb-4"
|
||||||
:height="54"
|
>
|
||||||
@input="value => $emit('change', {path: ['healthBarColorMid'], value})"
|
<color-picker
|
||||||
/>
|
:value="model.healthBarColorMid"
|
||||||
</outlined-input>
|
:width="54"
|
||||||
<outlined-input
|
:height="54"
|
||||||
name="Empty"
|
@input="value => $emit('change', {path: ['healthBarColorMid'], value})"
|
||||||
class="mb-4 ml-2"
|
/>
|
||||||
>
|
</outlined-input>
|
||||||
<color-picker
|
<outlined-input
|
||||||
:value="model.healthBarColorLow"
|
name="Empty"
|
||||||
:width="54"
|
class="mb-4 ml-2"
|
||||||
:height="54"
|
>
|
||||||
@input="value => $emit('change', {path: ['healthBarColorLow'], value})"
|
<color-picker
|
||||||
/>
|
:value="model.healthBarColorLow"
|
||||||
</outlined-input>
|
:width="54"
|
||||||
|
:height="54"
|
||||||
|
@input="value => $emit('change', {path: ['healthBarColorLow'], value})"
|
||||||
|
/>
|
||||||
|
</outlined-input>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<v-layout
|
<v-row dense>
|
||||||
wrap
|
<v-col
|
||||||
class="mt-4"
|
cols="12"
|
||||||
>
|
md="4"
|
||||||
<text-field
|
>
|
||||||
label="Damage order"
|
<text-field
|
||||||
type="number"
|
label="Damage order"
|
||||||
style="max-width: 300px;"
|
type="number"
|
||||||
hint="Lower ordered health bars will take damage before higher ordered ones"
|
hint="Lower ordered health bars will take damage before higher ordered ones"
|
||||||
class="mr-4"
|
:disabled="model.healthBarNoDamage"
|
||||||
:disabled="model.healthBarNoDamage"
|
:value="model.healthBarDamageOrder"
|
||||||
:value="model.healthBarDamageOrder"
|
:error-messages="errors.healthBarDamageOrder"
|
||||||
:error-messages="errors.healthBarDamageOrder"
|
@change="change('healthBarDamageOrder', ...arguments)"
|
||||||
@change="change('healthBarDamageOrder', ...arguments)"
|
/>
|
||||||
/>
|
</v-col>
|
||||||
<smart-switch
|
<v-col
|
||||||
label="Ignore damage"
|
cols="12"
|
||||||
class="mr-4"
|
md="4"
|
||||||
:value="model.healthBarNoDamage"
|
sm="6"
|
||||||
:error-messages="errors.healthBarNoDamage"
|
>
|
||||||
@change="change('healthBarNoDamage', ...arguments)"
|
<smart-switch
|
||||||
/>
|
label="Ignore damage"
|
||||||
<smart-switch
|
:value="model.healthBarNoDamage"
|
||||||
label="Prevent damage overflow"
|
:error-messages="errors.healthBarNoDamage"
|
||||||
:value="model.healthBarNoDamageOverflow"
|
@change="change('healthBarNoDamage', ...arguments)"
|
||||||
:error-messages="errors.healthBarNoDamageOverflow"
|
/>
|
||||||
@change="change('healthBarNoDamageOverflow', ...arguments)"
|
</v-col>
|
||||||
/>
|
<v-col
|
||||||
</v-layout>
|
cols="12"
|
||||||
<v-layout wrap>
|
md="4"
|
||||||
<text-field
|
sm="6"
|
||||||
label="Healing order"
|
>
|
||||||
type="number"
|
<smart-switch
|
||||||
style="max-width: 300px;"
|
label="Prevent damage overflow"
|
||||||
hint="Lower ordered health bars will take healing before higher ordered ones"
|
:value="model.healthBarNoDamageOverflow"
|
||||||
class="mr-4"
|
:error-messages="errors.healthBarNoDamageOverflow"
|
||||||
:disabled="model.healthBarNoHealing"
|
@change="change('healthBarNoDamageOverflow', ...arguments)"
|
||||||
:value="model.healthBarHealingOrder"
|
/>
|
||||||
:error-messages="errors.healthBarHealingOrder"
|
</v-col>
|
||||||
@change="change('healthBarHealingOrder', ...arguments)"
|
<v-col
|
||||||
/>
|
cols="12"
|
||||||
<smart-switch
|
md="4"
|
||||||
label="Ignore healing"
|
>
|
||||||
class="mr-4"
|
<text-field
|
||||||
:value="model.healthBarNoHealing"
|
label="Healing order"
|
||||||
:error-messages="errors.healthBarNoHealing"
|
type="number"
|
||||||
@change="change('healthBarNoHealing', ...arguments)"
|
hint="Lower ordered health bars will take healing before higher ordered ones"
|
||||||
/>
|
:disabled="model.healthBarNoHealing"
|
||||||
<smart-switch
|
:value="model.healthBarHealingOrder"
|
||||||
label="Prevent healing overflow"
|
:error-messages="errors.healthBarHealingOrder"
|
||||||
:value="model.healthBarNoHealingOverflow"
|
@change="change('healthBarHealingOrder', ...arguments)"
|
||||||
:error-messages="errors.healthBarNoHealingOverflow"
|
/>
|
||||||
@change="change('healthBarNoHealingOverflow', ...arguments)"
|
</v-col>
|
||||||
/>
|
<v-col
|
||||||
</v-layout>
|
cols="12"
|
||||||
|
md="4"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<smart-switch
|
||||||
|
label="Ignore healing"
|
||||||
|
:value="model.healthBarNoHealing"
|
||||||
|
:error-messages="errors.healthBarNoHealing"
|
||||||
|
@change="change('healthBarNoHealing', ...arguments)"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
<v-col
|
||||||
|
cols="12"
|
||||||
|
md="4"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<smart-switch
|
||||||
|
label="Prevent healing overflow"
|
||||||
|
:value="model.healthBarNoHealingOverflow"
|
||||||
|
:error-messages="errors.healthBarNoHealingOverflow"
|
||||||
|
@change="change('healthBarNoHealingOverflow', ...arguments)"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
</form-section>
|
</form-section>
|
||||||
</v-expand-transition>
|
</v-expand-transition>
|
||||||
<form-section name="Damage">
|
<form-section name="Damage">
|
||||||
|
|||||||
@@ -18,16 +18,17 @@
|
|||||||
$emit('change', {path: ['duration', ...path], value, ack})"
|
$emit('change', {path: ['duration', ...path], value, ack})"
|
||||||
/>
|
/>
|
||||||
-->
|
-->
|
||||||
<v-expand-transition>
|
<smart-toggle
|
||||||
<smart-select
|
v-if="!model.applied"
|
||||||
v-if="!model.applied"
|
label="Target creature"
|
||||||
label="Target"
|
:value="model.target"
|
||||||
:items="targetOptions"
|
:options="[
|
||||||
:value="model.target"
|
{name: 'Action Target', value: 'target'},
|
||||||
:error-messages="errors.target"
|
{name: 'Self', value: 'self'},
|
||||||
:menu-props="{auto: true, lazy: true}"
|
]"
|
||||||
@change="change('target', ...arguments)"
|
:error-messages="errors.target"
|
||||||
/>
|
@change="change('target', ...arguments)"
|
||||||
|
/>
|
||||||
</v-expand-transition>
|
</v-expand-transition>
|
||||||
<form-sections>
|
<form-sections>
|
||||||
<form-section
|
<form-section
|
||||||
|
|||||||
@@ -28,14 +28,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
import PropertyIcon from '/imports/client/ui/properties/shared/PropertyIcon.vue';
|
|
||||||
import ColorPicker from '/imports/client/ui/components/ColorPicker.vue';
|
import ColorPicker from '/imports/client/ui/components/ColorPicker.vue';
|
||||||
import OutlinedInput from '/imports/client/ui/properties/viewers/shared/OutlinedInput.vue';
|
import OutlinedInput from '/imports/client/ui/properties/viewers/shared/OutlinedInput.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
OutlinedInput,
|
OutlinedInput,
|
||||||
PropertyIcon,
|
|
||||||
ColorPicker,
|
ColorPicker,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -49,4 +49,10 @@ export default {
|
|||||||
.outlined-input.theme--dark:not(.no-hover):hover {
|
.outlined-input.theme--dark:not(.no-hover):hover {
|
||||||
border-color: #fff;
|
border-color: #fff;
|
||||||
}
|
}
|
||||||
|
.outlined-input .name {
|
||||||
|
color: rgba(0,0,0,.6);
|
||||||
|
}
|
||||||
|
.outlined-input.theme--dark .name {
|
||||||
|
color: rgba(255,255,255,.7);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user