diff --git a/.eslintrc.json b/.eslintrc.json
index 87bdb6a9..c061d105 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -12,6 +12,9 @@
}
}
},
+ "parserOptions": {
+ "ecmaVersion": 2024
+ },
"rules": {
"no-console": [
"warn",
diff --git a/src/components/TextArea/index.js b/src/components/TextArea/index.js
new file mode 100644
index 00000000..6730b85f
--- /dev/null
+++ b/src/components/TextArea/index.js
@@ -0,0 +1,83 @@
+import { Component } from 'pet-dex-utilities';
+import './index.scss';
+
+const events = [
+ 'name:change',
+ 'placeholder:change',
+ 'maxLength:change',
+ 'required:change',
+ 'error',
+];
+
+const html = `
+
+
+
+
+`;
+
+export default function TextArea({
+ name = '',
+ placeholder = '',
+ maxLength,
+ required = true,
+}) {
+ Component.call(this, { html, events });
+ const $textarea = this.selected.get('textarea');
+ const $resizeTrigger = this.selected.get('resize-trigger');
+
+ this.setName(name);
+ this.setPlaceholder(placeholder);
+ this.setRequired(required);
+ if (maxLength) this.setMaxLength(maxLength);
+
+ function autoResize() {
+ $resizeTrigger.innerText = $textarea.value;
+
+ $textarea.style.height = 'auto';
+ $textarea.style.height = `${$resizeTrigger.offsetHeight}px`;
+ }
+
+ this.listen('mount', () => {
+ $textarea.addEventListener('focus', () =>
+ $textarea.classList.remove('textarea__input--error'),
+ );
+ $textarea.addEventListener('input', autoResize);
+ window.addEventListener('resize', autoResize);
+ });
+
+ this.listen('unmount', () => {
+ $textarea.removeEventListener('focus', () =>
+ $textarea.classList.remove('textarea__input--error'),
+ );
+ $textarea.removeEventListener('input', autoResize);
+ window.removeEventListener('resize', autoResize);
+ });
+}
+
+TextArea.prototype = Object.assign(TextArea.prototype, Component.prototype, {
+ setName(name = '') {
+ this.selected.get('textarea').name = name;
+ this.emit('name:change', name);
+ },
+ setPlaceholder(placeholder = '') {
+ this.selected.get('textarea').placeholder = placeholder;
+ this.emit('placeholder:change', placeholder);
+ },
+ setMaxLength(maxLength) {
+ const $textArea = this.selected.get('textarea');
+
+ if (maxLength) $textArea.maxLength = maxLength;
+ else $textArea.removeAttribute('maxlength');
+
+ this.emit('maxLength:change', maxLength ?? Infinity);
+ },
+ setRequired(required = true) {
+ this.selected.get('textarea').required = required;
+ this.emit('required:change', required);
+ },
+ error() {
+ this.selected.get('textarea').classList.add('textarea__input--error');
+ this.emit('error');
+ },
+});
diff --git a/src/components/TextArea/index.scss b/src/components/TextArea/index.scss
new file mode 100644
index 00000000..f9912465
--- /dev/null
+++ b/src/components/TextArea/index.scss
@@ -0,0 +1,56 @@
+@use '~styles/fonts.scss' as fonts;
+@use '~styles/colors.scss' as colors;
+
+.textarea {
+ position: relative;
+
+ &__input,
+ &__trigger {
+ width: 100%;
+
+ font-family: fonts.$fifthFont;
+ font-size: fonts.$sm;
+ line-height: 1;
+ }
+
+ &__input {
+ overflow: hidden;
+
+ padding-bottom: 1.4rem;
+
+ border: unset;
+ border-bottom: 0.1rem solid colors.$gray400;
+
+ position: relative;
+ z-index: 1;
+
+ outline-color: transparent;
+
+ transition: 0.2s ease-in-out outline;
+
+ resize: none;
+
+ &::placeholder {
+ color: colors.$gray400;
+ }
+
+ &:focus {
+ outline-color: colors.$primary200;
+ }
+
+ &--error {
+ color: colors.$secondary100;
+
+ background: colors.$error100;
+ }
+ }
+
+ &__trigger {
+ display: block;
+
+ position: absolute;
+ top: 0;
+
+ visibility: hidden;
+ }
+}
diff --git a/src/stories/TextArea.stories.js b/src/stories/TextArea.stories.js
new file mode 100644
index 00000000..7d30561a
--- /dev/null
+++ b/src/stories/TextArea.stories.js
@@ -0,0 +1,26 @@
+import Textarea from '../components/TextArea';
+
+export default {
+ title: 'Components/TextArea',
+ render: (args) => {
+ const textarea = new Textarea(args);
+ const $container = document.createElement('div');
+ textarea.mount($container);
+
+ return $container;
+ },
+ argTypes: {
+ name: { control: 'text', default: '' },
+ placeholder: { control: 'text', default: '' },
+ maxLength: { control: 'number', default: 524288 },
+ required: { control: 'boolean', default: true },
+ },
+};
+
+export const Default = {
+ args: {
+ name: 'textarea',
+ placeholder: 'Escreva o cuidado especial',
+ required: true,
+ },
+};
diff --git a/src/styles/fonts.scss b/src/styles/fonts.scss
index 6c510fff..e63a9c76 100644
--- a/src/styles/fonts.scss
+++ b/src/styles/fonts.scss
@@ -2,6 +2,7 @@ $primaryFont: 'Montserrat', sans-serif;
$secondaryFont: 'Wix Madefor Display', sans-serif;
$tertiaryFont: 'Helvetica', sans-serif;
$fourthFont: 'Noto Sans', sans-serif;
+$fifthFont: 'Poppins', sans-serif;
$xs: 1.4rem;
$sm: 1.6rem;