@c2n/text-field 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +14 -0
- package/dist/chunks/text-field-DkffSesv.js +230 -0
- package/dist/text-field-clear.js +49 -0
- package/dist/text-field.js +2 -0
- package/package.json +63 -0
- package/types/src/text-field-clear.d.ts +28 -0
- package/types/src/text-field-clear.d.ts.map +1 -0
- package/types/src/text-field.d.ts +170 -0
- package/types/src/text-field.d.ts.map +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Nguyen Thai Vinh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# @c2n/text-field
|
|
2
|
+
|
|
3
|
+
`c2-text-field` is a single-line input in a themeable field: icon slots, an optional clear button, helper and error text, and a character counter.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<c2-text-field type="email" placeholder="you@example.com" help="We never share it." clearable>
|
|
7
|
+
<svg slot="prefix-icon" viewBox="0 0 24 24">…</svg>
|
|
8
|
+
</c2-text-field>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- Attributes: `type`, `name`, `autocomplete`, `placeholder`, `value`, `maxlength`, `minlength`, `pattern`, `required`, `disabled`, `readonly`, `error`, `error-text`, `help`, `clearable`.
|
|
12
|
+
- Slots: `prefix-icon`, `suffix-icon`, `clear-icon`, `help-icon`, `supporting-text`.
|
|
13
|
+
- Events: `input`, `change` (re-dispatched from the inner input), `clear`.
|
|
14
|
+
- Theming: `--c2-text-field--*` with `__hover`, `__focus`, `__error`, `__read-only`, `__disabled` states, plus `__icon`, `__clear-icon`, `__help-icon` and `__supporting-text` parts. Pair with `c2-label` for a caption.
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { LitElement, html, nothing, unsafeCSS } from "lit";
|
|
2
|
+
import { customElement, property, query, state } from "lit/decorators.js";
|
|
3
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
4
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
5
|
+
import { live } from "lit/directives/live.js";
|
|
6
|
+
import { addClasses } from "@c2n/core/css-helper.js";
|
|
7
|
+
import { redispatchEvent } from "@c2n/core/dom-helper.js";
|
|
8
|
+
//#region src/text-field.scss?inline
|
|
9
|
+
var text_field_default = "/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n:host {\n display: inline-flex;\n flex-direction: column;\n gap: var(--c2-text-field__supporting-text--gap,4px);\n vertical-align: middle;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.c2-text-field-row {\n display: flex;\n align-items: center;\n gap: var(--c2-text-field__help-icon--gap,8px);\n}\n\n.c2-text-field {\n display: flex;\n flex: 1;\n min-width: 0;\n align-items: center;\n box-sizing: border-box;\n position: relative;\n cursor: text;\n text-align: inherit;\n min-height: var(--c2-text-field--min-height,36px);\n gap: var(--c2-text-field--gap,8px);\n padding-top: var(--c2-text-field--padding-top,6px);\n padding-bottom: var(--c2-text-field--padding-bottom,6px);\n padding-right: var(--c2-text-field--padding-right,10px);\n padding-left: var(--c2-text-field--padding-left,12px);\n border-top: var(--c2-text-field--border-top,1px solid #bcbcc6);\n border-bottom: var(--c2-text-field--border-bottom,1px solid #bcbcc6);\n border-right: var(--c2-text-field--border-right,1px solid #bcbcc6);\n border-left: var(--c2-text-field--border-left,1px solid #bcbcc6);\n border-top-left-radius: var(--c2-text-field--border-top-left-radius,6px);\n border-top-right-radius: var(--c2-text-field--border-top-right-radius,6px);\n border-bottom-left-radius: var(--c2-text-field--border-bottom-left-radius,6px);\n border-bottom-right-radius: var(--c2-text-field--border-bottom-right-radius,6px);\n color: var(--c2-text-field--color,#18181b);\n background: var(--c2-text-field--background,#ffffff);\n font-size: var(--c2-text-field--font-size,14px);\n font-weight: var(--c2-text-field--font-weight);\n font-style: var(--c2-text-field--font-style);\n font-family: var(--c2-text-field--font-family);\n line-height: var(--c2-text-field--line-height,20px);\n outline: var(--c2-text-field__focus--outline,3px solid rgba(71, 110, 249, 0.2));\n outline-color: transparent;\n outline-offset: var(--c2-text-field__focus--outline-offset,0px);\n will-change: border, background, outline-color;\n transition: border 250ms cubic-bezier(0.2, 0, 0, 1), background 250ms cubic-bezier(0.2, 0, 0, 1), outline-color 250ms cubic-bezier(0.2, 0, 0, 1);\n}\n.c2-text-field .input {\n flex: 1;\n min-width: 0;\n width: 100%;\n margin: 0;\n padding: 0;\n border: none;\n outline: none;\n background: transparent;\n color: inherit;\n caret-color: inherit;\n font: inherit;\n line-height: inherit;\n text-align: inherit;\n}\n.c2-text-field .input::placeholder {\n font-weight: var(--c2-text-field__placeholder--font-weight);\n font-style: var(--c2-text-field__placeholder--font-style);\n color: var(--c2-text-field__placeholder--color,#71717a);\n opacity: var(--c2-text-field__placeholder--opacity,1);\n}\n.c2-text-field .input::-webkit-search-cancel-button, .c2-text-field .input::-webkit-search-decoration {\n appearance: none;\n}\n@media (forced-colors: active) {\n .c2-text-field .input {\n background: Field;\n }\n}\n.c2-text-field:hover {\n border-top: var(--c2-text-field__hover--border-top,var(--c2-text-field--border-top,1px solid #a1a1aa));\n border-bottom: var(--c2-text-field__hover--border-bottom,var(--c2-text-field--border-bottom,1px solid #a1a1aa));\n border-right: var(--c2-text-field__hover--border-right,var(--c2-text-field--border-right,1px solid #a1a1aa));\n border-left: var(--c2-text-field__hover--border-left,var(--c2-text-field--border-left,1px solid #a1a1aa));\n}\n.c2-text-field.focus-within {\n border-top: var(--c2-text-field__focus--border-top,var(--c2-text-field--border-top,1px solid #476ef9));\n border-bottom: var(--c2-text-field__focus--border-bottom,var(--c2-text-field--border-bottom,1px solid #476ef9));\n border-right: var(--c2-text-field__focus--border-right,var(--c2-text-field--border-right,1px solid #476ef9));\n border-left: var(--c2-text-field__focus--border-left,var(--c2-text-field--border-left,1px solid #476ef9));\n color: var(--c2-text-field__focus--color,var(--c2-text-field--color,#18181b));\n background: var(--c2-text-field__focus--background,var(--c2-text-field--background,#ffffff));\n outline: var(--c2-text-field__focus--outline,3px solid rgba(71, 110, 249, 0.2));\n outline-offset: var(--c2-text-field__focus--outline-offset,0px);\n}\n.c2-text-field.error {\n border-top: var(--c2-text-field__error--border-top,1px solid #dc2626);\n border-bottom: var(--c2-text-field__error--border-bottom,1px solid #dc2626);\n border-right: var(--c2-text-field__error--border-right,1px solid #dc2626);\n border-left: var(--c2-text-field__error--border-left,1px solid #dc2626);\n color: var(--c2-text-field__error--color,var(--c2-text-field--color,#18181b));\n background: var(--c2-text-field__error--background,var(--c2-text-field--background,#ffffff));\n}\n.c2-text-field.error.focus-within {\n outline: var(--c2-text-field__error__focus--outline,3px solid rgba(220, 38, 38, 0.2));\n}\n.c2-text-field.read-only {\n cursor: default;\n border-top: var(--c2-text-field__read-only--border-top,1px solid #e4e4e7);\n border-bottom: var(--c2-text-field__read-only--border-bottom,1px solid #e4e4e7);\n border-right: var(--c2-text-field__read-only--border-right,1px solid #e4e4e7);\n border-left: var(--c2-text-field__read-only--border-left,1px solid #e4e4e7);\n color: var(--c2-text-field__read-only--color,var(--c2-text-field--color,#18181b));\n background: var(--c2-text-field__read-only--background,#fafafa);\n}\n.c2-text-field.disabled {\n cursor: default;\n opacity: var(--c2-text-field__disabled--opacity,0.38);\n pointer-events: none;\n}\n\n::slotted([slot=prefix-icon]),\n::slotted([slot=suffix-icon]) {\n flex: none;\n width: var(--c2-text-field__icon--size,16px);\n height: var(--c2-text-field__icon--size,16px);\n color: var(--c2-text-field__icon--color,#71717a);\n --c2-feather-icon--size: var(--c2-text-field__icon--size,16px);\n --c2-mat-icon--font-size: var(--c2-text-field__icon--size,16px);\n}\n\n.clear-button {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n cursor: pointer;\n width: var(--c2-text-field__clear-icon--size,16px);\n height: var(--c2-text-field__clear-icon--size,16px);\n color: var(--c2-text-field__clear-icon--color,#a1a1aa);\n transition: color 250ms cubic-bezier(0.2, 0, 0, 1);\n}\n.clear-button:hover, .clear-button:focus-visible {\n color: var(--c2-text-field__clear-icon__hover--color,#18181b);\n}\n.clear-button:focus-visible {\n outline: var(--c2-text-field__focus--outline,3px solid rgba(71, 110, 249, 0.2));\n outline-offset: 2px;\n border-radius: 4px;\n}\n.clear-button svg,\n.clear-button ::slotted(*) {\n width: 100%;\n height: 100%;\n --c2-feather-icon--size: var(--c2-text-field__clear-icon--size,16px);\n --c2-mat-icon--font-size: var(--c2-text-field__clear-icon--size,16px);\n}\n\n::slotted([slot=help-icon]) {\n flex: none;\n width: var(--c2-text-field__help-icon--size,16px);\n height: var(--c2-text-field__help-icon--size,16px);\n color: var(--c2-text-field__help-icon--color,#71717a);\n --c2-feather-icon--size: var(--c2-text-field__help-icon--size,16px);\n --c2-mat-icon--font-size: var(--c2-text-field__help-icon--size,16px);\n}\n\n.supporting-text {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n font-size: var(--c2-text-field__supporting-text--font-size,12px);\n line-height: var(--c2-text-field__supporting-text--line-height,16px);\n color: var(--c2-text-field__supporting-text--color,#71717a);\n}\n.supporting-text.error {\n color: var(--c2-text-field__supporting-text__error--color,#dc2626);\n}\n.supporting-text .supporting-text__message {\n flex: 1;\n min-width: 0;\n}\n.supporting-text .supporting-text__counter {\n flex: none;\n font-variant-numeric: tabular-nums;\n}";
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region \0@oxc-project+runtime@0.148.0/helpers/esm/decorate.js
|
|
12
|
+
function __decorate(decorators, target, key, desc) {
|
|
13
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
14
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
15
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
16
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/text-field.ts
|
|
20
|
+
var TextField = class TextField extends LitElement {
|
|
21
|
+
constructor(..._args) {
|
|
22
|
+
super(..._args);
|
|
23
|
+
this.readOnly = false;
|
|
24
|
+
this.disabled = false;
|
|
25
|
+
this.error = false;
|
|
26
|
+
this.maxLength = -1;
|
|
27
|
+
this.minLength = -1;
|
|
28
|
+
this.pattern = "";
|
|
29
|
+
this.required = false;
|
|
30
|
+
this.type = "text";
|
|
31
|
+
this.name = "";
|
|
32
|
+
this.autocomplete = "";
|
|
33
|
+
this.placeholder = "";
|
|
34
|
+
this.value = "";
|
|
35
|
+
this.errorText = "";
|
|
36
|
+
this.help = "";
|
|
37
|
+
this.clearable = false;
|
|
38
|
+
this.dirty = false;
|
|
39
|
+
this.focused = false;
|
|
40
|
+
this.hasSupportingSlot = false;
|
|
41
|
+
this.handleFocus = () => {
|
|
42
|
+
this.focus();
|
|
43
|
+
};
|
|
44
|
+
this.handleClear = (event) => {
|
|
45
|
+
event.stopPropagation();
|
|
46
|
+
if (!this.input) return;
|
|
47
|
+
this.input.value = "";
|
|
48
|
+
this.value = "";
|
|
49
|
+
this.dirty = true;
|
|
50
|
+
this.input.focus();
|
|
51
|
+
this.dispatchEvent(new Event("clear", {
|
|
52
|
+
bubbles: true,
|
|
53
|
+
composed: true
|
|
54
|
+
}));
|
|
55
|
+
this.dispatchEvent(new Event("input", {
|
|
56
|
+
bubbles: true,
|
|
57
|
+
composed: true
|
|
58
|
+
}));
|
|
59
|
+
this.dispatchEvent(new Event("change", {
|
|
60
|
+
bubbles: true,
|
|
61
|
+
composed: true
|
|
62
|
+
}));
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
static {
|
|
66
|
+
this.styles = unsafeCSS(text_field_default);
|
|
67
|
+
}
|
|
68
|
+
/** Restores the initial value (the `value` attribute) and clears the dirty and error flags. */
|
|
69
|
+
reset() {
|
|
70
|
+
this.dirty = false;
|
|
71
|
+
this.value = this.getAttribute("value") ?? "";
|
|
72
|
+
this.error = false;
|
|
73
|
+
}
|
|
74
|
+
/** True once the user has typed in the field. */
|
|
75
|
+
isDirty() {
|
|
76
|
+
return this.dirty;
|
|
77
|
+
}
|
|
78
|
+
attributeChangedCallback(attribute, newValue, oldValue) {
|
|
79
|
+
if (attribute === "value" && this.dirty) return;
|
|
80
|
+
super.attributeChangedCallback(attribute, newValue, oldValue);
|
|
81
|
+
}
|
|
82
|
+
focus(options) {
|
|
83
|
+
this.input?.focus(options);
|
|
84
|
+
this.focused = true;
|
|
85
|
+
}
|
|
86
|
+
blur() {
|
|
87
|
+
this.input?.blur();
|
|
88
|
+
this.focused = false;
|
|
89
|
+
}
|
|
90
|
+
/** Selects the whole text. */
|
|
91
|
+
select() {
|
|
92
|
+
this.input?.select();
|
|
93
|
+
}
|
|
94
|
+
handleInput(event) {
|
|
95
|
+
this.dirty = true;
|
|
96
|
+
this.value = event.target.value;
|
|
97
|
+
redispatchEvent(this, event);
|
|
98
|
+
}
|
|
99
|
+
handleFocusin(event) {
|
|
100
|
+
this.focused = true;
|
|
101
|
+
redispatchEvent(this, event);
|
|
102
|
+
}
|
|
103
|
+
/** A click anywhere on the field (icons, padding) focuses the input. */
|
|
104
|
+
forwardFocusin(event) {
|
|
105
|
+
if (event.defaultPrevented || event.target === this.input) return;
|
|
106
|
+
this.input?.focus();
|
|
107
|
+
}
|
|
108
|
+
handleFocusout(event) {
|
|
109
|
+
this.focused = false;
|
|
110
|
+
redispatchEvent(this, event);
|
|
111
|
+
}
|
|
112
|
+
handleSupportingSlotChange(event) {
|
|
113
|
+
const slot = event.target;
|
|
114
|
+
this.hasSupportingSlot = slot.assignedNodes({ flatten: true }).length > 0;
|
|
115
|
+
}
|
|
116
|
+
renderPrefixSlot() {
|
|
117
|
+
return html`<slot name="prefix-icon"></slot>`;
|
|
118
|
+
}
|
|
119
|
+
renderSuffixSlot() {
|
|
120
|
+
return html`<slot name="suffix-icon"></slot>`;
|
|
121
|
+
}
|
|
122
|
+
renderHelpIconSlot() {
|
|
123
|
+
return html`<slot name="help-icon"></slot>`;
|
|
124
|
+
}
|
|
125
|
+
renderClearButton() {
|
|
126
|
+
if (!this.clearable || !this.value || this.disabled || this.readOnly) return nothing;
|
|
127
|
+
return html`<button class="clear-button" type="button" aria-label="Clear" tabindex="-1" @click=${this.handleClear}>
|
|
128
|
+
<slot name="clear-icon">
|
|
129
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
130
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
131
|
+
<line x1="15" y1="9" x2="9" y2="15"></line>
|
|
132
|
+
<line x1="9" y1="9" x2="15" y2="15"></line>
|
|
133
|
+
</svg>
|
|
134
|
+
</slot>
|
|
135
|
+
</button>`;
|
|
136
|
+
}
|
|
137
|
+
renderSupportingText() {
|
|
138
|
+
const message = this.error && !this.disabled && !!this.errorText ? this.errorText : this.help;
|
|
139
|
+
const counter = this.maxLength > 0 ? `${this.value.length} / ${this.maxLength}` : "";
|
|
140
|
+
if (!message && !counter && !this.hasSupportingSlot) return html`<slot name="supporting-text" hidden @slotchange=${this.handleSupportingSlotChange}></slot>`;
|
|
141
|
+
return html`<div class="supporting-text ${classMap({ error: this.error && !this.disabled })}">
|
|
142
|
+
<div class="supporting-text__message">
|
|
143
|
+
<slot name="supporting-text" @slotchange=${this.handleSupportingSlotChange}>${message}</slot>
|
|
144
|
+
</div>
|
|
145
|
+
${counter ? html`<span class="supporting-text__counter">${counter}</span>` : nothing}
|
|
146
|
+
</div>`;
|
|
147
|
+
}
|
|
148
|
+
redispatchEvent(event) {
|
|
149
|
+
redispatchEvent(this, event);
|
|
150
|
+
}
|
|
151
|
+
updated(changed) {
|
|
152
|
+
if (changed.has("disabled") || changed.has("error") || changed.has("readOnly") || changed.has("focused")) addClasses(this, this.stateClasses);
|
|
153
|
+
}
|
|
154
|
+
get stateClasses() {
|
|
155
|
+
return {
|
|
156
|
+
disabled: this.disabled,
|
|
157
|
+
error: !this.disabled && this.error,
|
|
158
|
+
"read-only": this.readOnly,
|
|
159
|
+
"focus-within": this.focused
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
render() {
|
|
163
|
+
const classes = this.stateClasses;
|
|
164
|
+
return html`<div class="c2-text-field-row">
|
|
165
|
+
<div class="c2-text-field ${classMap(classes)}" @click=${this.forwardFocusin}>
|
|
166
|
+
${this.renderPrefixSlot()}
|
|
167
|
+
<input
|
|
168
|
+
type=${this.type}
|
|
169
|
+
class="input"
|
|
170
|
+
name=${ifDefined(this.name || void 0)}
|
|
171
|
+
autocomplete=${ifDefined(this.autocomplete || void 0)}
|
|
172
|
+
maxlength=${ifDefined(this.maxLength > -1 ? this.maxLength : void 0)}
|
|
173
|
+
minlength=${ifDefined(this.minLength > -1 ? this.minLength : void 0)}
|
|
174
|
+
pattern=${ifDefined(this.pattern || void 0)}
|
|
175
|
+
?disabled=${this.disabled}
|
|
176
|
+
?readonly=${this.readOnly}
|
|
177
|
+
?required=${this.required}
|
|
178
|
+
aria-invalid=${this.error ? "true" : nothing}
|
|
179
|
+
placeholder=${this.placeholder || nothing}
|
|
180
|
+
.value=${live(this.value)}
|
|
181
|
+
@change=${this.redispatchEvent}
|
|
182
|
+
@select=${this.redispatchEvent}
|
|
183
|
+
@focusin=${this.handleFocusin}
|
|
184
|
+
@focusout=${this.handleFocusout}
|
|
185
|
+
@input=${this.handleInput}
|
|
186
|
+
/>
|
|
187
|
+
${this.renderClearButton()} ${this.renderSuffixSlot()}
|
|
188
|
+
</div>
|
|
189
|
+
${this.renderHelpIconSlot()}
|
|
190
|
+
</div>
|
|
191
|
+
${this.renderSupportingText()}`;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
__decorate([property({
|
|
195
|
+
type: Boolean,
|
|
196
|
+
reflect: true
|
|
197
|
+
})], TextField.prototype, "readOnly", void 0);
|
|
198
|
+
__decorate([property({
|
|
199
|
+
type: Boolean,
|
|
200
|
+
reflect: true
|
|
201
|
+
})], TextField.prototype, "disabled", void 0);
|
|
202
|
+
__decorate([property({
|
|
203
|
+
type: Boolean,
|
|
204
|
+
reflect: true
|
|
205
|
+
})], TextField.prototype, "error", void 0);
|
|
206
|
+
__decorate([property({ type: Number })], TextField.prototype, "maxLength", void 0);
|
|
207
|
+
__decorate([property({ type: Number })], TextField.prototype, "minLength", void 0);
|
|
208
|
+
__decorate([property({ type: String })], TextField.prototype, "pattern", void 0);
|
|
209
|
+
__decorate([property({
|
|
210
|
+
type: Boolean,
|
|
211
|
+
reflect: true
|
|
212
|
+
})], TextField.prototype, "required", void 0);
|
|
213
|
+
__decorate([property({ type: String })], TextField.prototype, "type", void 0);
|
|
214
|
+
__decorate([property({ type: String })], TextField.prototype, "name", void 0);
|
|
215
|
+
__decorate([property({ type: String })], TextField.prototype, "autocomplete", void 0);
|
|
216
|
+
__decorate([property({ type: String })], TextField.prototype, "placeholder", void 0);
|
|
217
|
+
__decorate([property({ type: String })], TextField.prototype, "value", void 0);
|
|
218
|
+
__decorate([property({ attribute: "error-text" })], TextField.prototype, "errorText", void 0);
|
|
219
|
+
__decorate([property({ type: String })], TextField.prototype, "help", void 0);
|
|
220
|
+
__decorate([property({
|
|
221
|
+
type: Boolean,
|
|
222
|
+
reflect: true
|
|
223
|
+
})], TextField.prototype, "clearable", void 0);
|
|
224
|
+
__decorate([state()], TextField.prototype, "dirty", void 0);
|
|
225
|
+
__decorate([state()], TextField.prototype, "focused", void 0);
|
|
226
|
+
__decorate([state()], TextField.prototype, "hasSupportingSlot", void 0);
|
|
227
|
+
__decorate([query(".input")], TextField.prototype, "input", void 0);
|
|
228
|
+
TextField = __decorate([customElement("c2-text-field")], TextField);
|
|
229
|
+
//#endregion
|
|
230
|
+
export { __decorate as n, TextField as t };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { n as __decorate, t as TextField } from "./chunks/text-field-DkffSesv.js";
|
|
2
|
+
import { html, nothing, unsafeCSS } from "lit";
|
|
3
|
+
import { customElement, state } from "lit/decorators.js";
|
|
4
|
+
//#region src/text-field-clear.scss?inline
|
|
5
|
+
var text_field_clear_default = "/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n.clear-icon {\n cursor: pointer;\n width: var(--c2-text-field-clear__clear-icon--size,24px);\n color: var(--c2-text-field-clear__clear-icon--color,rgb(70, 70, 70));\n display: flex;\n align-items: center;\n}";
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/text-field-clear.ts
|
|
8
|
+
var TextFieldClear = class TextFieldClear extends TextField {
|
|
9
|
+
constructor(..._args) {
|
|
10
|
+
super(..._args);
|
|
11
|
+
this.showClear = false;
|
|
12
|
+
this.clearHandle = () => {
|
|
13
|
+
this.value = "";
|
|
14
|
+
this.showClear = false;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
static {
|
|
18
|
+
this.styles = [unsafeCSS(text_field_clear_default), TextField.styles];
|
|
19
|
+
}
|
|
20
|
+
handleInput(event) {
|
|
21
|
+
super.handleInput(event);
|
|
22
|
+
this.showClear = !!this.value;
|
|
23
|
+
}
|
|
24
|
+
renderClearIcon() {
|
|
25
|
+
return this.showClear ? html`<div class="clear-icon" @click=${this.clearHandle}>
|
|
26
|
+
<slot name="clear-icon">
|
|
27
|
+
<svg
|
|
28
|
+
viewBox="0 0 24 24"
|
|
29
|
+
class="default-clear-icon"
|
|
30
|
+
fill="none"
|
|
31
|
+
stroke="currentColor"
|
|
32
|
+
stroke-width="2"
|
|
33
|
+
stroke-linecap="round"
|
|
34
|
+
stroke-linejoin="round"
|
|
35
|
+
>
|
|
36
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
37
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
38
|
+
</svg>
|
|
39
|
+
</slot>
|
|
40
|
+
</div>` : nothing;
|
|
41
|
+
}
|
|
42
|
+
renderSuffixSlot() {
|
|
43
|
+
return html`${this.renderClearIcon()} ${super.renderSuffixSlot()}`;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
__decorate([state()], TextFieldClear.prototype, "showClear", void 0);
|
|
47
|
+
TextFieldClear = __decorate([customElement("c2-text-field-clear")], TextFieldClear);
|
|
48
|
+
//#endregion
|
|
49
|
+
export { TextFieldClear };
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@c2n/text-field",
|
|
3
|
+
"version": "0.0.6",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/text-field.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"default": "./dist/text-field.js",
|
|
9
|
+
"types": "./types/src/text-field.d.ts"
|
|
10
|
+
},
|
|
11
|
+
"./text-field-clear.js": {
|
|
12
|
+
"default": "./dist/text-field-clear.js",
|
|
13
|
+
"types": "./types/src/text-field-clear.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./custom-elements.json": "./custom-elements.json"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"types"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"text-field",
|
|
23
|
+
"web component",
|
|
24
|
+
"lit"
|
|
25
|
+
],
|
|
26
|
+
"author": "code2nguyen@gmail.com",
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"registry": "https://registry.npmjs.org",
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/code2nguyen/web-components.git"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"dev": "vite",
|
|
37
|
+
"build": "wireit",
|
|
38
|
+
"type-check": "wireit"
|
|
39
|
+
},
|
|
40
|
+
"wireit": {
|
|
41
|
+
"type-check": {
|
|
42
|
+
"dependencies": [
|
|
43
|
+
"../../core:build"
|
|
44
|
+
],
|
|
45
|
+
"command": "tsc -p tsconfig.lib.json --composite false"
|
|
46
|
+
},
|
|
47
|
+
"build": {
|
|
48
|
+
"dependencies": [
|
|
49
|
+
"type-check"
|
|
50
|
+
],
|
|
51
|
+
"command": "vite build"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@c2n/core": "0.0.6",
|
|
56
|
+
"lit": "3.3.3"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@c2n/config": "*"
|
|
60
|
+
},
|
|
61
|
+
"customElements": "custom-elements.json",
|
|
62
|
+
"gitHead": "2921054bc75299da66dad11c1e374246ff88a51e"
|
|
63
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CSSResult, nothing } from 'lit';
|
|
2
|
+
import { TextField } from './text-field';
|
|
3
|
+
/**
|
|
4
|
+
* A `c2-text-field` that always shows a clear button while it has a value. Prefer `c2-text-field` with the
|
|
5
|
+
* `clearable` attribute; this element remains for markup that cannot toggle attributes. Inherits every attribute,
|
|
6
|
+
* slot, event and CSS variable of `c2-text-field`.
|
|
7
|
+
*
|
|
8
|
+
* @tag c2-text-field-clear
|
|
9
|
+
*
|
|
10
|
+
* @slot clear-icon - Replaces the default cross icon.
|
|
11
|
+
*
|
|
12
|
+
* @cssproperty {pixel} [--c2-text-field-clear__clear-icon--size=24px]
|
|
13
|
+
* @cssproperty {color} [--c2-text-field-clear__clear-icon--color=rgb(70, 70, 70)]
|
|
14
|
+
*/
|
|
15
|
+
export declare class TextFieldClear extends TextField {
|
|
16
|
+
static styles: CSSResult | CSSResult[];
|
|
17
|
+
showClear: boolean;
|
|
18
|
+
protected handleInput(event: InputEvent): void;
|
|
19
|
+
protected clearHandle: () => void;
|
|
20
|
+
renderClearIcon(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
21
|
+
protected renderSuffixSlot(): import("lit-html").TemplateResult<1>;
|
|
22
|
+
}
|
|
23
|
+
declare global {
|
|
24
|
+
interface HTMLElementTagNameMap {
|
|
25
|
+
'c2-text-field-clear': TextFieldClear;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=text-field-clear.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-field-clear.d.ts","sourceRoot":"","sources":["../../src/text-field-clear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAQ,OAAO,EAAa,MAAM,KAAK,CAAA;AAIzD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAExC;;;;;;;;;;;GAWG;AACH,qBACa,cAAe,SAAQ,SAAS;IAC3C,OAAgB,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,CAAqD;IAE3F,SAAS,UAAQ;cAEP,WAAW,CAAC,KAAK,EAAE,UAAU;IAKhD,SAAS,CAAC,WAAW,aAGpB;IAED,eAAe;cAqBI,gBAAgB;CAGpC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,qBAAqB,EAAE,cAAc,CAAA;KACtC;CACF"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { CSSResult, LitElement, nothing, type PropertyValues } from 'lit';
|
|
2
|
+
export type TextFieldType = 'text' | 'email' | 'password' | 'search' | 'tel' | 'url' | 'number';
|
|
3
|
+
/**
|
|
4
|
+
* A single-line input wrapped in a themeable field. The native `<input>` keeps its behaviour (`type`, `name`,
|
|
5
|
+
* `autocomplete`, `maxlength`, `pattern`, `input`/`change` events); the field adds `prefix-icon` / `suffix-icon` slots
|
|
6
|
+
* sized by `--c2-text-field__icon--size`, an optional clear button (`clearable`), helper text (`help`), an error
|
|
7
|
+
* message (`error` + `error-text`), a character counter when `maxlength` is set, and a `help-icon` slot beside the
|
|
8
|
+
* field. Pair it with `c2-label` for a caption. Give the host a `width`: the field fills it.
|
|
9
|
+
*
|
|
10
|
+
* @tag c2-text-field
|
|
11
|
+
*
|
|
12
|
+
* @slot prefix-icon - Icon (or short adornment text) at the start of the field: an inline SVG, a `c2-feather-*` icon or a `c2-mat-icon`.
|
|
13
|
+
* @slot suffix-icon - Icon or adornment at the end of the field, after the clear button.
|
|
14
|
+
* @slot clear-icon - Replaces the default cross of the clear button.
|
|
15
|
+
* @slot help-icon - Icon shown beside the field, outside the border, e.g. a tooltip trigger.
|
|
16
|
+
* @slot supporting-text - Rich helper content below the field. `help` and `error-text` are the plain-text shortcuts.
|
|
17
|
+
*
|
|
18
|
+
* @event {InputEvent} input - Re-dispatched from the inner input on every keystroke; `value` is already updated.
|
|
19
|
+
* @event {Event} change - Re-dispatched from the inner input when the value is committed (blur or Enter).
|
|
20
|
+
* @event {Event} clear - Fired after the clear button emptied the field (an `input` and a `change` event follow).
|
|
21
|
+
*
|
|
22
|
+
* @cssproperty {pixel} [--c2-text-field--min-height=36px]
|
|
23
|
+
* @cssproperty {pixel} [--c2-text-field--gap=8px] - Space between the icons and the text.
|
|
24
|
+
*
|
|
25
|
+
* @cssproperty {border-radius} [--c2-text-field--border-top-left-radius=6px]
|
|
26
|
+
* @cssproperty {border-radius} [--c2-text-field--border-top-right-radius=6px]
|
|
27
|
+
* @cssproperty {border-radius} [--c2-text-field--border-bottom-left-radius=6px]
|
|
28
|
+
* @cssproperty {border-radius} [--c2-text-field--border-bottom-right-radius=6px]
|
|
29
|
+
*
|
|
30
|
+
* @cssproperty {padding} [--c2-text-field--padding-top=6px]
|
|
31
|
+
* @cssproperty {padding} [--c2-text-field--padding-right=10px]
|
|
32
|
+
* @cssproperty {padding} [--c2-text-field--padding-bottom=6px]
|
|
33
|
+
* @cssproperty {padding} [--c2-text-field--padding-left=12px]
|
|
34
|
+
*
|
|
35
|
+
* @cssproperty {border} [--c2-text-field--border-top=1px solid #bcbcc6]
|
|
36
|
+
* @cssproperty {border} [--c2-text-field--border-right=1px solid #bcbcc6]
|
|
37
|
+
* @cssproperty {border} [--c2-text-field--border-bottom=1px solid #bcbcc6]
|
|
38
|
+
* @cssproperty {border} [--c2-text-field--border-left=1px solid #bcbcc6]
|
|
39
|
+
*
|
|
40
|
+
* @cssproperty {color} [--c2-text-field--color=#18181b]
|
|
41
|
+
* @cssproperty {color} [--c2-text-field--background=#ffffff]
|
|
42
|
+
*
|
|
43
|
+
* @cssproperty {font-size} [--c2-text-field--font-size=14px]
|
|
44
|
+
* @cssproperty {font-weight} --c2-text-field--font-weight
|
|
45
|
+
* @cssproperty {font-style} --c2-text-field--font-style
|
|
46
|
+
* @cssproperty {font-family} --c2-text-field--font-family
|
|
47
|
+
* @cssproperty {pixel} [--c2-text-field--line-height=20px]
|
|
48
|
+
*
|
|
49
|
+
* @cssproperty {color} [--c2-text-field__placeholder--color=#71717a]
|
|
50
|
+
* @cssproperty {opacity} [--c2-text-field__placeholder--opacity=1]
|
|
51
|
+
* @cssproperty {font-weight} --c2-text-field__placeholder--font-weight
|
|
52
|
+
* @cssproperty {font-style} --c2-text-field__placeholder--font-style
|
|
53
|
+
*
|
|
54
|
+
* @cssproperty {border} [--c2-text-field__hover--border-top=1px solid #a1a1aa]
|
|
55
|
+
* @cssproperty {border} [--c2-text-field__hover--border-right=1px solid #a1a1aa]
|
|
56
|
+
* @cssproperty {border} [--c2-text-field__hover--border-bottom=1px solid #a1a1aa]
|
|
57
|
+
* @cssproperty {border} [--c2-text-field__hover--border-left=1px solid #a1a1aa]
|
|
58
|
+
*
|
|
59
|
+
* @cssproperty {border} [--c2-text-field__focus--border-top=1px solid #476ef9]
|
|
60
|
+
* @cssproperty {border} [--c2-text-field__focus--border-right=1px solid #476ef9]
|
|
61
|
+
* @cssproperty {border} [--c2-text-field__focus--border-bottom=1px solid #476ef9]
|
|
62
|
+
* @cssproperty {border} [--c2-text-field__focus--border-left=1px solid #476ef9]
|
|
63
|
+
* @cssproperty {color} --c2-text-field__focus--color
|
|
64
|
+
* @cssproperty {color} --c2-text-field__focus--background
|
|
65
|
+
* @cssproperty {outline} [--c2-text-field__focus--outline=3px solid rgba(71, 110, 249, 0.2)]
|
|
66
|
+
* @cssproperty {pixel} [--c2-text-field__focus--outline-offset=0px]
|
|
67
|
+
*
|
|
68
|
+
* @cssproperty {border} [--c2-text-field__error--border-top=1px solid #dc2626]
|
|
69
|
+
* @cssproperty {border} [--c2-text-field__error--border-right=1px solid #dc2626]
|
|
70
|
+
* @cssproperty {border} [--c2-text-field__error--border-bottom=1px solid #dc2626]
|
|
71
|
+
* @cssproperty {border} [--c2-text-field__error--border-left=1px solid #dc2626]
|
|
72
|
+
* @cssproperty {color} --c2-text-field__error--color
|
|
73
|
+
* @cssproperty {color} --c2-text-field__error--background
|
|
74
|
+
* @cssproperty {outline} [--c2-text-field__error__focus--outline=3px solid rgba(220, 38, 38, 0.2)]
|
|
75
|
+
*
|
|
76
|
+
* @cssproperty {border} [--c2-text-field__read-only--border-top=1px solid #e4e4e7]
|
|
77
|
+
* @cssproperty {border} [--c2-text-field__read-only--border-right=1px solid #e4e4e7]
|
|
78
|
+
* @cssproperty {border} [--c2-text-field__read-only--border-bottom=1px solid #e4e4e7]
|
|
79
|
+
* @cssproperty {border} [--c2-text-field__read-only--border-left=1px solid #e4e4e7]
|
|
80
|
+
* @cssproperty {color} --c2-text-field__read-only--color
|
|
81
|
+
* @cssproperty {color} [--c2-text-field__read-only--background=#fafafa]
|
|
82
|
+
*
|
|
83
|
+
* @cssproperty {opacity} [--c2-text-field__disabled--opacity=0.38]
|
|
84
|
+
*
|
|
85
|
+
* @cssproperty {pixel} [--c2-text-field__icon--size=16px]
|
|
86
|
+
* @cssproperty {color} [--c2-text-field__icon--color=#71717a]
|
|
87
|
+
*
|
|
88
|
+
* @cssproperty {pixel} [--c2-text-field__clear-icon--size=16px]
|
|
89
|
+
* @cssproperty {color} [--c2-text-field__clear-icon--color=#a1a1aa]
|
|
90
|
+
* @cssproperty {color} [--c2-text-field__clear-icon__hover--color=#18181b]
|
|
91
|
+
*
|
|
92
|
+
* @cssproperty {pixel} [--c2-text-field__help-icon--size=16px]
|
|
93
|
+
* @cssproperty {color} [--c2-text-field__help-icon--color=#71717a]
|
|
94
|
+
* @cssproperty {pixel} [--c2-text-field__help-icon--gap=8px] - Space between the field and the help icon.
|
|
95
|
+
*
|
|
96
|
+
* @cssproperty {pixel} [--c2-text-field__supporting-text--gap=4px] - Space between the field and the helper line.
|
|
97
|
+
* @cssproperty {font-size} [--c2-text-field__supporting-text--font-size=12px]
|
|
98
|
+
* @cssproperty {pixel} [--c2-text-field__supporting-text--line-height=16px]
|
|
99
|
+
* @cssproperty {color} [--c2-text-field__supporting-text--color=#71717a]
|
|
100
|
+
* @cssproperty {color} [--c2-text-field__supporting-text__error--color=#dc2626]
|
|
101
|
+
*/
|
|
102
|
+
export declare class TextField extends LitElement {
|
|
103
|
+
static styles: CSSResult | CSSResult[];
|
|
104
|
+
/** Shows the value but refuses edits. Rendered on a light grey background. */
|
|
105
|
+
readOnly: boolean;
|
|
106
|
+
/** Disables the input and dims the field. */
|
|
107
|
+
disabled: boolean;
|
|
108
|
+
/** Marks the field invalid: red border and, when set, `error-text` replaces the helper text. */
|
|
109
|
+
error: boolean;
|
|
110
|
+
/** Maximum number of characters. Forwarded to the input and shown as a `n / max` counter under the field. */
|
|
111
|
+
maxLength: number;
|
|
112
|
+
/** Minimum number of characters, forwarded to the input. */
|
|
113
|
+
minLength: number;
|
|
114
|
+
/** Regular expression the value must match, forwarded to the input. */
|
|
115
|
+
pattern: string;
|
|
116
|
+
/** Marks the input required (native validation). Pair with a `required` `c2-label` to show the indicator. */
|
|
117
|
+
required: boolean;
|
|
118
|
+
/** Input type: `text`, `email`, `password`, `search`, `tel`, `url` or `number`. */
|
|
119
|
+
type: TextFieldType;
|
|
120
|
+
/** Form field name forwarded to the input. */
|
|
121
|
+
name: string;
|
|
122
|
+
/** `autocomplete` hint forwarded to the input, e.g. `email` or `current-password`. */
|
|
123
|
+
autocomplete: string;
|
|
124
|
+
/** Text shown while the field is empty. */
|
|
125
|
+
placeholder: string;
|
|
126
|
+
/** The current text. Setting the attribute after the user has typed no longer updates it, like a native input. */
|
|
127
|
+
value: string;
|
|
128
|
+
/** Message shown under the field while `error` is set. */
|
|
129
|
+
errorText: string;
|
|
130
|
+
/** Helper text shown under the field. */
|
|
131
|
+
help: string;
|
|
132
|
+
/** Shows a clear button at the end of the field while it has a value. */
|
|
133
|
+
clearable: boolean;
|
|
134
|
+
private dirty;
|
|
135
|
+
private focused;
|
|
136
|
+
private hasSupportingSlot;
|
|
137
|
+
private readonly input?;
|
|
138
|
+
/** Restores the initial value (the `value` attribute) and clears the dirty and error flags. */
|
|
139
|
+
reset(): void;
|
|
140
|
+
handleFocus: () => void;
|
|
141
|
+
/** True once the user has typed in the field. */
|
|
142
|
+
isDirty(): boolean;
|
|
143
|
+
attributeChangedCallback(attribute: string, newValue: string | null, oldValue: string | null): void;
|
|
144
|
+
focus(options?: FocusOptions | undefined): void;
|
|
145
|
+
blur(): void;
|
|
146
|
+
/** Selects the whole text. */
|
|
147
|
+
select(): void;
|
|
148
|
+
protected handleInput(event: InputEvent): void;
|
|
149
|
+
protected handleFocusin(event: Event): void;
|
|
150
|
+
/** A click anywhere on the field (icons, padding) focuses the input. */
|
|
151
|
+
protected forwardFocusin(event: Event): void;
|
|
152
|
+
protected handleFocusout(event: Event): void;
|
|
153
|
+
protected handleClear: (event: Event) => void;
|
|
154
|
+
private handleSupportingSlotChange;
|
|
155
|
+
protected renderPrefixSlot(): import("lit-html").TemplateResult<1>;
|
|
156
|
+
protected renderSuffixSlot(): import("lit-html").TemplateResult<1>;
|
|
157
|
+
protected renderHelpIconSlot(): import("lit-html").TemplateResult<1>;
|
|
158
|
+
protected renderClearButton(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
159
|
+
protected renderSupportingText(): import("lit-html").TemplateResult<1>;
|
|
160
|
+
private redispatchEvent;
|
|
161
|
+
protected updated(changed: PropertyValues): void;
|
|
162
|
+
private get stateClasses();
|
|
163
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
164
|
+
}
|
|
165
|
+
declare global {
|
|
166
|
+
interface HTMLElementTagNameMap {
|
|
167
|
+
'c2-text-field': TextField;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=text-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-field.d.ts","sourceRoot":"","sources":["../../src/text-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAQ,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAS1F,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAA;AAE/F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkGG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,OAAgB,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,CAAoB;IAInE,8EAA8E;IAClC,QAAQ,UAAQ;IAE5D,6CAA6C;IACD,QAAQ,UAAQ;IAE5D,gGAAgG;IACpD,KAAK,UAAQ;IAIzD,6GAA6G;IACjF,SAAS,SAAK;IAE1C,4DAA4D;IAChC,SAAS,SAAK;IAE1C,uEAAuE;IAC3C,OAAO,SAAK;IAExC,6GAA6G;IACjE,QAAQ,UAAQ;IAI5D,mFAAmF;IACvD,IAAI,EAAE,aAAa,CAAS;IAExD,8CAA8C;IAClB,IAAI,SAAK;IAErC,sFAAsF;IAC1D,YAAY,SAAK;IAE7C,2CAA2C;IACf,WAAW,SAAK;IAE5C,kHAAkH;IACtF,KAAK,SAAK;IAEtC,0DAA0D;IACnB,SAAS,SAAK;IAIrD,yCAAyC;IACb,IAAI,SAAK;IAErC,yEAAyE;IAC7B,SAAS,UAAQ;IAGpD,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,iBAAiB,CAAQ;IAGzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAyB;IAEjE,+FAA+F;IAC/F,KAAK;IAML,WAAW,aAEV;IAED,iDAAiD;IACjD,OAAO;IAIE,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAU5F,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI;IAK/C,IAAI,IAAI,IAAI;IAKrB,8BAA8B;IAC9B,MAAM,IAAI,IAAI;IAId,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU;IAMvC,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK;IAKpC,wEAAwE;IACxE,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK;IAKrC,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK;IAKrC,SAAS,CAAC,WAAW,GAAI,OAAO,KAAK,UAUpC;IAED,OAAO,CAAC,0BAA0B;IAKlC,SAAS,CAAC,gBAAgB;IAI1B,SAAS,CAAC,gBAAgB;IAI1B,SAAS,CAAC,kBAAkB;IAI5B,SAAS,CAAC,iBAAiB;IAa3B,SAAS,CAAC,oBAAoB;IAe9B,OAAO,CAAC,eAAe;cAIJ,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAMzD,OAAO,KAAK,YAAY,GAOvB;IAEQ,MAAM;CA+BhB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,SAAS,CAAA;KAC3B;CACF"}
|