<template lang="pug">
.smart-form
span.hint(v-text="hint" v-if="hint")
input.input(:type="type" :name="attr" :placeholder="placeholder" v-model="value" v-bind:class="{ '-error': error }" v-if="isInputTag")
textarea.input(:name="attr" :placeholder="placeholder" v-model="value" v-bind:class="{ '-error': error }" :rows="rows" v-if="isTextareaTag")
label.label(:for="attr" v-text="i18nName + (required ? requiredText : '')")
span.errors(v-text="errors")
</template>
<script lang="coffee">
export default
props:
models:
type: Array
required: true
coerce: (val) ->
if _.isArray val
val
else
_.toPath(val)
attr:
type: String
required: true
coerce: (val) -> _.camelCase(val)
type:
type: String
required: true
name:
type: String
required: false
default: null
placeholder:
type: String
required: false
default: ''
required:
type: Boolean
required: false
default: false
defaultValue:
type: [String, Number]
required: false
default: null
hint:
type: String
required: false
default: ''
data: ->
requiredText: '*'
computed:
ownerModal: -> _.last @models
i18nName: ->
if @name?
@name
else
i18n.t("activerecord.attributes.#{_.snakeCase(@ownerModal)}.#{_.snakeCase(@attr)}")
value:
get: -> _.get @$store.state.form, @models.concat([@attr])
set: (value) -> @$store.dispatch('SET_FORM_VALUE', @models.concat([@attr]), value)
errors: ->
errors = _.get(@$store.state.errors, @models.concat([@attr]))
if errors? then _.join errors else null
isInputTag: -> _.includes(['text', 'number', 'checkbox'], @type)
isTextareaTag: -> _.includes(['textarea'], @type)
rows: ->
num = if @value? then @value.split("\n").length else 0
_.max([2, num])
</script>
<style lang="scss" scoped>
.smart-form {
display: flex;
flex-direction: column-reverse;
> .hint {
font-size: $small-font-size;
color: $warn-color;
}
> .label {
font-size: $small-font-size;
}
> .input {
border-bottom: $base-border-height solid $base-font-color;
&:focus {
border-bottom: $base-border-height solid $action-color;
+ .label {
color: $action-color;
}
}
&.-error {
border-bottom: $base-border-height solid $error-color;
+ .label {
color: $error-color;
}
}
}
> .errors {
color: $error-color;
font-size: $small-font-size;
}
}
</style>