Skip to content

Commit

Permalink
feat: add text area component (devhatt#276)
Browse files Browse the repository at this point in the history
* feat: add text area component

* refactor: use existing color from color file

* refactor: remove container class

* refactor: add default values ​​for parameters

* refactor: fix object assign

* refactor: clear events

* refactor: add the font family to the font style file

* refactor: fix storybook argTypes

* refactor: fix default args to max length

* refactor: change event names to follow the pattern

* refactor: fix BEM

* refactor: remove public method

* refactor: remove max length check

* refactor: add require to true by default

* refactor: add default max length value for Infinity

* refactor: remove infinite as maximum size for textarea

* chore: fix parsing error eslint

* refactor: fix logic to set maximum input size

---------

Co-authored-by: Alexandre Gomes <[email protected]>
  • Loading branch information
Mathh19 and Alecell authored Jul 9, 2024
1 parent 105a031 commit 68eab61
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
}
}
},
"parserOptions": {
"ecmaVersion": 2024
},
"rules": {
"no-console": [
"warn",
Expand Down
83 changes: 83 additions & 0 deletions src/components/TextArea/index.js
Original file line number Diff line number Diff line change
@@ -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 = `
<div class="textarea">
<textarea class="textarea__input" data-select="textarea" rows="1" cols="1"></textarea>
<span class="textarea__trigger" data-select="resize-trigger" contenteditable></span>
</div>
`;

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');
},
});
56 changes: 56 additions & 0 deletions src/components/TextArea/index.scss
Original file line number Diff line number Diff line change
@@ -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;
}
}
26 changes: 26 additions & 0 deletions src/stories/TextArea.stories.js
Original file line number Diff line number Diff line change
@@ -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,
},
};
1 change: 1 addition & 0 deletions src/styles/fonts.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 68eab61

Please sign in to comment.