diff --git a/assets/ico_hint_20.svg b/assets/ico_hint_20.svg new file mode 100644 index 0000000..f93a76b --- /dev/null +++ b/assets/ico_hint_20.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/commons/SharedStyles.js b/src/components/commons/SharedStyles.js index fba85e0..55a0d12 100644 --- a/src/components/commons/SharedStyles.js +++ b/src/components/commons/SharedStyles.js @@ -11,8 +11,7 @@ class SharedStyles { font-weight: var(--bs-body-font-weight); line-height: var(--bs-body-line-height); color: var(--bs-body-color); - - background-color: var(--bs-body-bg); + -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; } diff --git a/src/components/commons/LLabelContainer.js b/src/components/group/InputContainer.js similarity index 64% rename from src/components/commons/LLabelContainer.js rename to src/components/group/InputContainer.js index 3000907..74d3a32 100644 --- a/src/components/commons/LLabelContainer.js +++ b/src/components/group/InputContainer.js @@ -1,6 +1,6 @@ import {css, html, LitElement} from 'lit'; -class LLabelContainer extends LitElement { +class InputContainer extends LitElement { static styles = [ // component css @@ -14,26 +14,26 @@ class LLabelContainer extends LitElement { ] ; - constructor({labelAlign}) { - super(); - this.labelAlign = labelAlign; - } - static get properties() { return { + width: {type: String}, labelAlign: {type: String}, }; } render() { let isLabelLeft = (this.labelAlign && this.labelAlign == 'left'); + return html` -
+
` } } -customElements.define('l-label-container', LLabelContainer); -export {LLabelContainer}; \ No newline at end of file +customElements.define('l-input-container', InputContainer); +export {InputContainer}; \ No newline at end of file diff --git a/src/components/input/Input.js b/src/components/input/Input.js index e5e3818..9a61278 100644 --- a/src/components/input/Input.js +++ b/src/components/input/Input.js @@ -21,80 +21,79 @@ class LInput extends LitParents { // component css , css` - *, ::after, ::before { - box-sizing: border-box; - } - - .l-input { - width: 100%; - padding: .375rem .75rem; - font-size: .875rem; - font-weight: 400; - line-height: 1.5; - color: var(--bs-body-color); - -webkit-appearance: none; - -moz-appearance: none; - border: var(--bs-border-width) solid var(--bs-border-color); - border-radius: 8px; - outline: none; - } - - .l-flex-input { - flex-grow: 1; - padding: .375rem .75rem; - font-size: .875rem; - font-weight: 400; - line-height: 1.5; - color: var(--bs-body-color); - -webkit-appearance: none; - -moz-appearance: none; - border: var(--bs-border-width) solid var(--bs-border-color); - border-radius: 8px; - outline: none; - transition: all 0.3s ease-in-out; - } - - .is-valid { - border-color: var(--bs-success); - padding-right: calc(1.5em + .75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%231b8835' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(.375em + .1875rem) center; - background-size: calc(.75em + .375rem) calc(.75em + .375rem) - } - - .is-invalid { - border-color: var(--bs-danger); - padding-right: calc(1.5em + .75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23df1414'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23df1414' stroke='none'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(.375em + .1875rem) center; - background-size: calc(.75em + .375rem) calc(.75em + .375rem) - } + *, ::after, ::before { + box-sizing: border-box; + } + + .l-input { + width: 100%; + padding: .375rem .75rem; + font-size: .875rem; + font-weight: 400; + line-height: 1.5; + color: var(--bs-body-color); + -webkit-appearance: none; + -moz-appearance: none; + border: var(--bs-border-width) solid var(--bs-border-color); + border-radius: 8px; + outline: none; + } + + .l-flex-input { + flex-grow: 1; + padding: .375rem .75rem; + font-size: .875rem; + font-weight: 400; + line-height: 1.5; + color: var(--bs-body-color); + -webkit-appearance: none; + -moz-appearance: none; + border: var(--bs-border-width) solid var(--bs-border-color); + border-radius: 8px; + outline: none; + transition: all 0.3s ease-in-out; + } + + .is-valid { + border-color: var(--bs-success); + padding-right: calc(1.5em + .75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%231b8835' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(.375em + .1875rem) center; + background-size: calc(.75em + .375rem) calc(.75em + .375rem) + } + + .is-invalid { + border-color: var(--bs-danger); + padding-right: calc(1.5em + .75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23df1414'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23df1414' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(.375em + .1875rem) center; + background-size: calc(.75em + .375rem) calc(.75em + .375rem) + } ` ]; - isValid = (pattern, value, required) => { - const regex = new RegExp(pattern); + formatValue(value) { + // 예시: 숫자 포맷팅 (쉼표 추가) + return value.replace(/\B(?=(\d{3})+(?!\d))/g, ","); + } - const isValueEmpty = value => !value; - const isPatternInvalid = (regex, value) => regex && !regex.test(value); + isValid() { + const regex = new RegExp(this.pattern); + const value = this.getValue(); - if (isValueEmpty(value) && required) { + if (!value && this.required) { return false; - } else { - return !isPatternInvalid(regex, value); - } - }; + } else return !(regex && !regex.test(value)); + } validate() { - const element = this.shadowRoot.querySelector(this.selector); - - if (this.isValid(this.pattern, this.getValue(), this.required)) { - element.classList.remove('is-invalid'); + if (this.isValid()) { + this.shadowRoot.querySelector(this.selector).classList.remove('is-invalid'); } else { - element.classList.add('is-invalid'); + this.shadowRoot.querySelector(this.selector).classList.add('is-invalid'); } } @@ -131,16 +130,15 @@ class LInput extends LitParents { style="width: ${this.width ? this.width : 'auto'}" > ${ - this.label === undefined ? '' : - new LLabel({ - label: `${this.label}`, - id: `${this.id}`, - labelAlign: `${this.labelAlign}`, - labelWidth: `${this.labelWidth}`, - labelTextAlign: `${this.labelTextAlign}`, - required: `${this.required}` - }) - } + this.label === undefined ? '' : + new LLabel({ + label: `${this.label}`, + id: `${this.id}`, + labelAlign: `${this.labelAlign}`, + labelWidth: `${this.labelWidth}`, + labelTextAlign: `${this.labelTextAlign}`, + required: `${this.required}` + })}
- ${ - this.feedback === undefined ? '' : - new LFeedback({ - feedback: `${this.feedback}`, - feedbackType: `${this.feedbackType}`, - width: `${this.width}`, - labelAlign: `${this.labelAlign}`, - labelWidth: `${this.labelWidth}`, - }) - } + ${new LFeedback({ + feedback: `${this.feedback}`, + feedbackType: `${this.feedbackType}`, + width: `${this.width}`, + labelAlign: `${this.labelAlign}`, + labelWidth: `${this.labelWidth}`, + })} `; } } diff --git a/src/components/text/Feedback.js b/src/components/text/Feedback.js index 1d1137f..6d9947e 100644 --- a/src/components/text/Feedback.js +++ b/src/components/text/Feedback.js @@ -21,21 +21,12 @@ class LFeedback extends LitElement { ] ; - constructor({feedback, width, labelAlign, labelWidth}) { - super(); - - this.feedback = feedback; - this.width = width; - this.labelAlign = labelAlign; - this.labelWidth = labelWidth; - } - static get properties() { return { feedback: {type: String}, width: {type: String}, labelAlign: {type: String}, - labelWidth: {type: String}, + leftMargin: {type: String}, }; } @@ -44,7 +35,7 @@ class LFeedback extends LitElement { return html`
diff --git a/src/components/text/Label.js b/src/components/text/Label.js index 827201b..6eb2666 100644 --- a/src/components/text/Label.js +++ b/src/components/text/Label.js @@ -23,16 +23,6 @@ class LLabel extends LitElement { ] ; - constructor({label, id, labelAlign, labelWidth, labelTextAlign, required}) { - super(); - - this.label = label; - this.id = id; - this.labelAlign = labelAlign; - this.labelWidth = labelWidth; - this.labelTextAlign = labelTextAlign; - this.required = required; - } static get properties() { return { diff --git a/src/index.html b/src/index.html index f9317a2..1e0c67f 100644 --- a/src/index.html +++ b/src/index.html @@ -10,6 +10,10 @@ + + + + diff --git a/stories/Input.stories.js b/stories/Input.stories.js index b5737e1..4b92256 100644 --- a/stories/Input.stories.js +++ b/stories/Input.stories.js @@ -18,10 +18,7 @@ export default { }, id: {table: {category: "attribures",}}, name: {table: {category: "attribures",}}, - width: { - control: {type: 'text'}, - table: {category: "attribures",} - }, + width: {table: {category: "attribures",}}, label: { table: { @@ -74,14 +71,12 @@ export default { } }, placeholder: { - control: {type: 'text'}, table: { category: "attribures", subcategory: "text", } }, value: { - control: {type: 'text'}, table: { category: "attribures", subcategory: "text", @@ -102,7 +97,6 @@ export default { } }, pattern: { - control: {type: 'text'}, table: { category: "attribures", subcategory: "validate", @@ -119,14 +113,16 @@ export default { } }, disabled: { - control: {type: 'boolean'}, + control: {type: 'select'}, + options: [false, true], table: { category: "attribures", defaultValue: {summary: false} } }, readonly: { - control: {type: 'boolean'}, + control: {type: 'select'}, + options: [false, true], table: { category: "attribures", defaultValue: {summary: false} @@ -195,7 +191,9 @@ const Template = (args) => { placeholder="${ifDefined(args.placeholder)}" pattern="${ifDefined(args.pattern)}" value="${ifDefined(args.value)}" - />` + > + + ` } export const InputWithTopLabelAndFeedback = Template.bind({}); @@ -203,14 +201,18 @@ InputWithTopLabelAndFeedback.args = { type: 'text', id: 'input01', name: 'name', + width: 'auto', label: 'label', + labelAlign: 'top', labelWidth: 'auto', labelTextAlign: 'left', feedback: 'feedback', required: false, disabled: false, readonly: false, - + value: '', + pattern: '', + placeholder: '', }; export const InputWithLeftLabelAndFeedback = Template.bind({}); @@ -218,6 +220,7 @@ InputWithLeftLabelAndFeedback.args = { type: 'text', id: 'input01', name: 'name', + width: 'auto', label: 'label : ', labelAlign: 'left', labelWidth: '50px', @@ -226,7 +229,9 @@ InputWithLeftLabelAndFeedback.args = { required: false, disabled: false, readonly: false, - + value: '', + pattern: '', + placeholder: '', }; @@ -241,5 +246,7 @@ Input.args = { required: false, disabled: false, readonly: false, - + value: '', + pattern: '', + placeholder: '', };