Skip to content

Commit

Permalink
Merge pull request #1519 from EnergySage/ced-1758-es-form-textarea
Browse files Browse the repository at this point in the history
feat: add EsFormTextarea v3
  • Loading branch information
hroth1994 authored Sep 13, 2024
2 parents 109387f + 9226741 commit 626a831
Show file tree
Hide file tree
Showing 3 changed files with 293 additions and 0 deletions.
124 changes: 124 additions & 0 deletions es-ds-components/components/es-form-textarea.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<script setup lang="ts">
// Prevents attributes from being applied to first <div>
// v-bind="$attr" is on the input instead
defineOptions({
inheritAttrs: false,
});
defineProps({
/**
* Required
*/
required: {
type: Boolean,
default: false,
},
/**
* Disabled
*/
disabled: {
type: Boolean,
default: false,
},
/**
* ID
* required
*/
id: {
type: String,
required: true,
},
/**
* state
*/
state: {
type: [Boolean, null],
default: null,
},
});
const model = defineModel<string>();
const slots = useSlots();
const hasSuccess = () => !!slots.successMessage;
const hasMessage = () => !!slots.message;
const hasError = () => !!slots.errorMessage;
</script>

<template>
<div
class="input-wrapper justify-content-end"
:required="required">
<!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->
<label
:for="id"
class="label justify-content-start">
<slot name="label" />

<span
v-if="required"
class="text-danger">
*
</span>
</label>

<div class="input-holder">
<textarea
:id="id"
v-model="model"
v-bind="$attrs"
class="es-form-textarea w-100 form-control"
:class="{ 'is-invalid': state === false }"
:disabled="disabled"
:invalid="state === false" />
<small
v-if="hasMessage() && ((!hasSuccess() && state) || state == null)"
class="text-muted">
<slot name="message" />
</small>
<small
v-if="state === false && (hasError() || required)"
class="text-danger">
<slot
v-if="hasError()"
name="errorMessage" />
<template v-else-if="required"> This field is required. </template>
</small>
<small
v-if="state && hasSuccess()"
class="text-success">
<slot name="successMessage" />
</small>
</div>
</div>
</template>

<style lang="scss" scoped>
@use '@energysage/es-ds-styles/scss/variables' as variables;
.es-form-textarea {
min-height: 8.125rem;
}
.es-form-textarea:disabled,
.es-form-textarea[readonly] {
border: 0;
}
.is-invalid {
color: variables.$danger;
}
.form-inline .input-wrapper {
display: flex;
flex: 0 0 100%;
label {
flex: 0 0 30%;
}
.input-holder {
flex: 0 0 70%;
}
}
</style>
3 changes: 3 additions & 0 deletions es-ds-docs/components/ds-molecules-list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
<li>
<ds-link to="/molecules/tabs"> Tabs </ds-link>
</li>
<li>
<ds-link to="/molecules/form-textarea"> Textarea </ds-link>
</li>
<li>
<ds-link to="/molecules/text-input"> Text input </ds-link>
</li>
Expand Down
166 changes: 166 additions & 0 deletions es-ds-docs/pages/molecules/form-textarea.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<script setup>
const docTextarea = ref('');
const successValue = ref('My experience was great!');
const { $prism } = useNuxtApp();
const compCode = ref('');
const docCode = ref('');
onMounted(async () => {
if ($prism) {
const compSource = await import('@energysage/es-ds-components/components/es-form-textarea.vue?raw');
// eslint-disable-next-line import/no-self-import
const docSource = await import('./form-textarea.vue?raw');
compCode.value = $prism.normalizeCode(compSource.default);
docCode.value = $prism.normalizeCode(docSource.default);
$prism.highlight();
}
});
const propTableRows = [
['id', 'String', 'n/a', 'Required. The id of the input.'],
['v-model', 'String', 'n/a', 'Required. The v-model directive binds the input to a data property.'],
['disabled', 'Boolean', 'false', 'Specifies that the input should be disabled.'],
['required', 'Boolean', 'false', 'Specifies that the input is required.'],
[
'state',
'Boolean',
'null',
'Specifies the validity of the input. Can be true (success), false (error), or null (default).',
],
];
</script>

<template>
<div>
<h1>Textarea</h1>
<p>
When using a form textarea, please ensure that the label style is
<nuxt-link
href="https://apastyle.apa.org/style-grammar-guidelines/capitalization/sentence-case"
target="_blank">
Sentence case.
</nuxt-link>
</p>

<b-row class="my-500">
<b-col
cols="12"
lg="6">
<h2>Basic example</h2>
<es-form-textarea
id="basic-example"
v-model="docTextarea">
<template #label> Notes </template>
</es-form-textarea>
</b-col>
</b-row>

<b-row class="my-500">
<b-col
cols="12"
lg="6">
<h2>Required</h2>
<es-form-textarea
id="required-example"
v-model="docTextarea"
required>
<template #label> Notes </template>
</es-form-textarea>
</b-col>
</b-row>

<b-row class="my-500">
<b-col
cols="12"
lg="6">
<h2>Error state</h2>
<es-form-textarea
id="error-example"
v-model="docTextarea"
required
:state="false">
<template #label> Notes </template>
<template #errorMessage> This field is required. </template>
</es-form-textarea>
</b-col>
</b-row>

<b-row class="my-500">
<b-col
cols="12"
lg="6">
<h2>Success state</h2>
<es-form-textarea
id="success-example"
v-model="successValue"
required
:state="true">
<template #label> Notes </template>
<template #errorMessage> This field is required. </template>
</es-form-textarea>
</b-col>
</b-row>

<b-row class="my-500">
<b-col
cols="12"
lg="6">
<h2>Success state with message</h2>
<es-form-textarea
id="success-message-example"
v-model="successValue"
required
:state="true">
<template #label> Notes </template>
<template #message> Please enter your notes. </template>
<template #errorMessage> This field is required. </template>
<template #successMessage> Your notes have been entered successfully. </template>
</es-form-textarea>
</b-col>
</b-row>

<b-row class="my-500">
<b-col
cols="12"
lg="6">
<h2>Disabled state</h2>
<es-form-textarea
id="disabled-example"
v-model="docTextarea"
disabled>
<template #label> Notes </template>
</es-form-textarea>
</b-col>
</b-row>

<b-row class="my-500">
<b-col
cols="12"
lg="6">
<h2>Context message</h2>
<es-form-textarea
id="context-message-example"
v-model="docTextarea"
required>
<template #label> Notes </template>
<template #message> Please enter your notes. </template>
<template #errorMessage> This field is required. </template>
<template #successMessage> Your notes have been entered successfully. </template>
</es-form-textarea>
</b-col>
</b-row>

<div class="mb-500">
<h2>EsFormTextarea props</h2>
<ds-prop-table :rows="propTableRows" />
</div>

<ds-doc-source
:comp-code="compCode"
comp-source="es-ds-components/components/es-form-textarea.vue"
:doc-code="docCode"
doc-source="es-ds-docs/pages/molecules/form-textarea.vue" />
</div>
</template>

0 comments on commit 626a831

Please sign in to comment.