uni-textarea-field 1.0.0 → 1.0.2
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/index.html +1 -11
- package/mjs/wc-uni-textarea-field.js +85 -33
- package/mjs/wc-uni-textarea-field.min.js +40 -25
- package/package.json +1 -1
package/index.html
CHANGED
|
@@ -40,10 +40,8 @@ body{position:relative;inline-size:100vw;block-size:100vh;margin:0;}
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
uni-textarea-field {
|
|
43
|
-
inline-size: 300px;
|
|
44
|
-
|
|
45
43
|
&::part(icon-subject) {
|
|
46
|
-
/*
|
|
44
|
+
/* style icon here */
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
&[data-hide-icon]::part(icon-subject) {
|
|
@@ -415,29 +413,21 @@ const handler = (evt) => {
|
|
|
415
413
|
} else {
|
|
416
414
|
textarea.removeAttribute('maxlength');
|
|
417
415
|
}
|
|
418
|
-
|
|
419
|
-
uniTextareaField.refresh();
|
|
420
416
|
break;
|
|
421
417
|
}
|
|
422
418
|
|
|
423
419
|
case 'required': {
|
|
424
420
|
textarea.required = fd['required'] === 'y';
|
|
425
|
-
|
|
426
|
-
uniTextareaField.refresh();
|
|
427
421
|
break;
|
|
428
422
|
}
|
|
429
423
|
|
|
430
424
|
case 'disabled': {
|
|
431
425
|
textarea.disabled = fd['disabled'] === 'y';
|
|
432
|
-
|
|
433
|
-
uniTextareaField.refresh();
|
|
434
426
|
break;
|
|
435
427
|
}
|
|
436
428
|
|
|
437
429
|
case 'readonly': {
|
|
438
430
|
textarea.readOnly = fd['readonly'] === 'y';
|
|
439
|
-
|
|
440
|
-
uniTextareaField.refresh();
|
|
441
431
|
break;
|
|
442
432
|
}
|
|
443
433
|
|
|
@@ -82,34 +82,15 @@ ${_uniColorPalette}
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
:host {
|
|
85
|
-
|
|
86
|
-
.main__subject__span::after {
|
|
87
|
-
content: '*';
|
|
88
|
-
color: var(--ct_icon_moderate_strong);
|
|
89
|
-
margin-inline-start: 4px;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
&:has([slot="textarea"][maxlength]) {
|
|
94
|
-
.main {
|
|
95
|
-
--counter-display: block;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
&:has([slot="textarea"][readonly]) {
|
|
85
|
+
@container style(--show-required-sign: 'true') {
|
|
100
86
|
.main {
|
|
101
|
-
--
|
|
102
|
-
--border-color: var(--border-color-readonly);
|
|
87
|
+
--required-sign-display: inline;
|
|
103
88
|
}
|
|
104
89
|
}
|
|
105
90
|
|
|
106
|
-
|
|
91
|
+
@container style(--show-counter: 'true') {
|
|
107
92
|
.main {
|
|
108
|
-
--
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
slot[name="textarea"] {
|
|
112
|
-
interactivity: inert;
|
|
93
|
+
--counter-display: block;
|
|
113
94
|
}
|
|
114
95
|
}
|
|
115
96
|
|
|
@@ -158,6 +139,7 @@ ${_uniColorPalette}
|
|
|
158
139
|
--counter-color: var(--uni-textarea-field-counter-color, var(--ct_text_main_subtle));
|
|
159
140
|
--caret-color: var(--uni-textarea-field-caret-color, var(--ct_input-caret_main_general));
|
|
160
141
|
|
|
142
|
+
--required-sign-display: none;
|
|
161
143
|
--min-block-size: var(--uni-textarea-field-min-block-size, 100px);
|
|
162
144
|
|
|
163
145
|
/* size */
|
|
@@ -189,6 +171,13 @@ ${_uniColorPalette}
|
|
|
189
171
|
font-size: 12px;
|
|
190
172
|
color: var(--subject-color);
|
|
191
173
|
line-height: 1.667;
|
|
174
|
+
|
|
175
|
+
&::after {
|
|
176
|
+
content: '*';
|
|
177
|
+
color: var(--ct_icon_moderate_strong);
|
|
178
|
+
margin-inline-start: 4px;
|
|
179
|
+
display: var(--required-sign-display);
|
|
180
|
+
}
|
|
192
181
|
}
|
|
193
182
|
|
|
194
183
|
em {
|
|
@@ -269,6 +258,15 @@ ${_uniColorPalette}
|
|
|
269
258
|
color: var(--placeholder-color);
|
|
270
259
|
}
|
|
271
260
|
}
|
|
261
|
+
|
|
262
|
+
::slotted(textarea[readonly]) {
|
|
263
|
+
--background-color: transparent;
|
|
264
|
+
--border-color: var(--border-color-readonly);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
::slotted(textarea:is([disabled],[inert])) {
|
|
268
|
+
--text-color: var(--text-color-disabled);
|
|
269
|
+
}
|
|
272
270
|
}
|
|
273
271
|
</style>
|
|
274
272
|
|
|
@@ -285,6 +283,40 @@ ${_uniColorPalette}
|
|
|
285
283
|
</div>
|
|
286
284
|
`;
|
|
287
285
|
|
|
286
|
+
/* style injection */
|
|
287
|
+
const styleInjection = `
|
|
288
|
+
uni-textarea-field {
|
|
289
|
+
--show-required-sign: 'false';
|
|
290
|
+
--show-counter: 'false';
|
|
291
|
+
|
|
292
|
+
&:has(textarea[required]) {
|
|
293
|
+
--show-required-sign: 'true';
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
&:not([data-hide-counter]):has(textarea[maxlength]) {
|
|
297
|
+
--show-counter: 'true';
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
[inert] uni-textarea-field {
|
|
302
|
+
--interactivity: inert;
|
|
303
|
+
}
|
|
304
|
+
`;
|
|
305
|
+
|
|
306
|
+
const INJECT_KEY = Symbol.for('uni.textarea.field.ui.injected');
|
|
307
|
+
const uiInit = () => {
|
|
308
|
+
if (window[INJECT_KEY]) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const sheet = new CSSStyleSheet();
|
|
313
|
+
sheet.replaceSync(styleInjection);
|
|
314
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
|
|
315
|
+
|
|
316
|
+
window[INJECT_KEY] = true;
|
|
317
|
+
};
|
|
318
|
+
uiInit();
|
|
319
|
+
|
|
288
320
|
export class UniTextareaField extends HTMLElement {
|
|
289
321
|
#data;
|
|
290
322
|
#nodes;
|
|
@@ -299,7 +331,8 @@ export class UniTextareaField extends HTMLElement {
|
|
|
299
331
|
|
|
300
332
|
// data
|
|
301
333
|
this.#data = {
|
|
302
|
-
controller: ''
|
|
334
|
+
controller: '',
|
|
335
|
+
elementController: ''
|
|
303
336
|
};
|
|
304
337
|
|
|
305
338
|
// nodes
|
|
@@ -309,6 +342,7 @@ export class UniTextareaField extends HTMLElement {
|
|
|
309
342
|
subject: this.shadowRoot.querySelector('.main__subject__span'),
|
|
310
343
|
message: this.shadowRoot.querySelector('.main__info__message'),
|
|
311
344
|
counter: this.shadowRoot.querySelector('.main__info__counter'),
|
|
345
|
+
slot: this.shadowRoot.querySelector('slot[name=textarea]'),
|
|
312
346
|
};
|
|
313
347
|
|
|
314
348
|
// config
|
|
@@ -320,11 +354,12 @@ export class UniTextareaField extends HTMLElement {
|
|
|
320
354
|
// evts
|
|
321
355
|
this._onInput = this._onInput.bind(this);
|
|
322
356
|
this._onKeydown = this._onKeydown.bind(this);
|
|
357
|
+
this._onSlotchange = this._onSlotchange.bind(this);
|
|
323
358
|
}
|
|
324
359
|
|
|
325
360
|
async connectedCallback() {
|
|
326
361
|
const { config, error } = await _wcl.getWCConfig(this);
|
|
327
|
-
const {
|
|
362
|
+
const { slot } = this.#nodes;
|
|
328
363
|
|
|
329
364
|
if (error) {
|
|
330
365
|
console.warn(`${_wcl.classToTagName(this.constructor.name)}: ${error}`);
|
|
@@ -343,17 +378,14 @@ export class UniTextareaField extends HTMLElement {
|
|
|
343
378
|
// evts
|
|
344
379
|
this.#data.controller = new AbortController();
|
|
345
380
|
const signal = this.#data.controller.signal;
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
// init
|
|
350
|
-
this._onInput();
|
|
381
|
+
slot.addEventListener('slotchange', this._onSlotchange, { signal });
|
|
382
|
+
|
|
383
|
+
this.#setupEventListeners();
|
|
351
384
|
}
|
|
352
385
|
|
|
353
386
|
disconnectedCallback() {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
387
|
+
this.#data.controller.abort?.();
|
|
388
|
+
this.#data.elementController.abort?.();
|
|
357
389
|
}
|
|
358
390
|
|
|
359
391
|
#format(attrName, oldValue, newValue) {
|
|
@@ -444,6 +476,22 @@ export class UniTextareaField extends HTMLElement {
|
|
|
444
476
|
}
|
|
445
477
|
}
|
|
446
478
|
|
|
479
|
+
#setupEventListeners() {
|
|
480
|
+
this.#data.elementController.abort?.();
|
|
481
|
+
|
|
482
|
+
this.#nodes.textarea = this.querySelector('[slot=textarea]');
|
|
483
|
+
|
|
484
|
+
if (this.#nodes.textarea) {
|
|
485
|
+
this.#data.elementController = new AbortController();
|
|
486
|
+
const signal = this.#data.elementController.signal;
|
|
487
|
+
|
|
488
|
+
this.#nodes.textarea.addEventListener('input', this._onInput, { signal });
|
|
489
|
+
this.#nodes.textarea.addEventListener('keydown', this._onKeydown, { signal });
|
|
490
|
+
|
|
491
|
+
this._onInput();
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
447
495
|
set subject(value) {
|
|
448
496
|
if (value) {
|
|
449
497
|
this.setAttribute('subject', value);
|
|
@@ -523,6 +571,10 @@ export class UniTextareaField extends HTMLElement {
|
|
|
523
571
|
}
|
|
524
572
|
}
|
|
525
573
|
|
|
574
|
+
_onSlotchange() {
|
|
575
|
+
this.#setupEventListeners();
|
|
576
|
+
}
|
|
577
|
+
|
|
526
578
|
refresh() {
|
|
527
579
|
this.hidden = true;
|
|
528
580
|
this.offsetHeight;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_wcl}from"./common-lib.js";import{_wccss}from"./common-css.js";import{colorPalette as _uniColorPalette}from"https://unpkg.com/uni-input-field/mjs/uni-css.js";const defaults={subject:"",message:"",stat:"",appearance:"filled",size:"medium"},booleanAttrs=[],objectAttrs=[],custumEvents={},template=document.createElement("template")
|
|
1
|
+
import{_wcl}from"./common-lib.js";import{_wccss}from"./common-css.js";import{colorPalette as _uniColorPalette}from"https://unpkg.com/uni-input-field/mjs/uni-css.js";const defaults={subject:"",message:"",stat:"",appearance:"filled",size:"medium"},booleanAttrs=[],objectAttrs=[],custumEvents={},template=document.createElement("template"),styleInjection=(template.innerHTML=`
|
|
2
2
|
<style>
|
|
3
3
|
${_wccss}
|
|
4
4
|
${_uniColorPalette}
|
|
@@ -63,34 +63,15 @@ ${_uniColorPalette}
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
:host {
|
|
66
|
-
|
|
67
|
-
.main__subject__span::after {
|
|
68
|
-
content: '*';
|
|
69
|
-
color: var(--ct_icon_moderate_strong);
|
|
70
|
-
margin-inline-start: 4px;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
&:has([slot="textarea"][maxlength]) {
|
|
75
|
-
.main {
|
|
76
|
-
--counter-display: block;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
&:has([slot="textarea"][readonly]) {
|
|
66
|
+
@container style(--show-required-sign: 'true') {
|
|
81
67
|
.main {
|
|
82
|
-
--
|
|
83
|
-
--border-color: var(--border-color-readonly);
|
|
68
|
+
--required-sign-display: inline;
|
|
84
69
|
}
|
|
85
70
|
}
|
|
86
71
|
|
|
87
|
-
|
|
72
|
+
@container style(--show-counter: 'true') {
|
|
88
73
|
.main {
|
|
89
|
-
--
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
slot[name="textarea"] {
|
|
93
|
-
interactivity: inert;
|
|
74
|
+
--counter-display: block;
|
|
94
75
|
}
|
|
95
76
|
}
|
|
96
77
|
|
|
@@ -139,6 +120,7 @@ ${_uniColorPalette}
|
|
|
139
120
|
--counter-color: var(--uni-textarea-field-counter-color, var(--ct_text_main_subtle));
|
|
140
121
|
--caret-color: var(--uni-textarea-field-caret-color, var(--ct_input-caret_main_general));
|
|
141
122
|
|
|
123
|
+
--required-sign-display: none;
|
|
142
124
|
--min-block-size: var(--uni-textarea-field-min-block-size, 100px);
|
|
143
125
|
|
|
144
126
|
/* size */
|
|
@@ -170,6 +152,13 @@ ${_uniColorPalette}
|
|
|
170
152
|
font-size: 12px;
|
|
171
153
|
color: var(--subject-color);
|
|
172
154
|
line-height: 1.667;
|
|
155
|
+
|
|
156
|
+
&::after {
|
|
157
|
+
content: '*';
|
|
158
|
+
color: var(--ct_icon_moderate_strong);
|
|
159
|
+
margin-inline-start: 4px;
|
|
160
|
+
display: var(--required-sign-display);
|
|
161
|
+
}
|
|
173
162
|
}
|
|
174
163
|
|
|
175
164
|
em {
|
|
@@ -250,6 +239,15 @@ ${_uniColorPalette}
|
|
|
250
239
|
color: var(--placeholder-color);
|
|
251
240
|
}
|
|
252
241
|
}
|
|
242
|
+
|
|
243
|
+
::slotted(textarea[readonly]) {
|
|
244
|
+
--background-color: transparent;
|
|
245
|
+
--border-color: var(--border-color-readonly);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
::slotted(textarea:is([disabled],[inert])) {
|
|
249
|
+
--text-color: var(--text-color-disabled);
|
|
250
|
+
}
|
|
253
251
|
}
|
|
254
252
|
</style>
|
|
255
253
|
|
|
@@ -264,4 +262,21 @@ ${_uniColorPalette}
|
|
|
264
262
|
<p class="main__info__counter" data-maxlength="?">0</p>
|
|
265
263
|
</div>
|
|
266
264
|
</div>
|
|
267
|
-
|
|
265
|
+
`,`
|
|
266
|
+
uni-textarea-field {
|
|
267
|
+
--show-required-sign: 'false';
|
|
268
|
+
--show-counter: 'false';
|
|
269
|
+
|
|
270
|
+
&:has(textarea[required]) {
|
|
271
|
+
--show-required-sign: 'true';
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
&:not([data-hide-counter]):has(textarea[maxlength]) {
|
|
275
|
+
--show-counter: 'true';
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
[inert] uni-textarea-field {
|
|
280
|
+
--interactivity: inert;
|
|
281
|
+
}
|
|
282
|
+
`),INJECT_KEY=Symbol.for("uni.textarea.field.ui.injected"),uiInit=()=>{var e;window[INJECT_KEY]||((e=new CSSStyleSheet).replaceSync(styleInjection),document.adoptedStyleSheets=[...document.adoptedStyleSheets,e],window[INJECT_KEY]=!0)};uiInit();class UniTextareaField extends HTMLElement{#data;#nodes;#config;constructor(e){super(),this.attachShadow({mode:"open",delegatesFocus:!0}),this.shadowRoot.appendChild(template.content.cloneNode(!0)),this.#data={controller:"",elementController:""},this.#nodes={styleSheet:this.shadowRoot.querySelector("style"),textarea:this.querySelector("[slot=textarea]"),subject:this.shadowRoot.querySelector(".main__subject__span"),message:this.shadowRoot.querySelector(".main__info__message"),counter:this.shadowRoot.querySelector(".main__info__counter"),slot:this.shadowRoot.querySelector("slot[name=textarea]")},this.#config={...defaults,...e},this._onInput=this._onInput.bind(this),this._onKeydown=this._onKeydown.bind(this),this._onSlotchange=this._onSlotchange.bind(this)}async connectedCallback(){var{config:e,error:t}=await _wcl.getWCConfig(this),a=this.#nodes["slot"];t?(console.warn(_wcl.classToTagName(this.constructor.name)+": "+t),this.remove()):(this.#config={...this.#config,...e},Object.keys(defaults).forEach(e=>this.#upgradeProperty(e)),this.#data.controller=new AbortController,t=this.#data.controller.signal,a.addEventListener("slotchange",this._onSlotchange,{signal:t}),this.#setupEventListeners())}disconnectedCallback(){this.#data.controller.abort?.(),this.#data.elementController.abort?.()}#format(e,t,a){if(null!==a)switch(e){case"subject":case"message":this.#config[e]=a;break;case"stat":this.#config[e]=["","valid","invalid"].includes(a)?a:defaults.state;break;case"appearance":this.#config[e]=["filled","outlined"].includes(a)?a:defaults.appearance;break;case"size":this.#config[e]=["large","medium","small"].includes(a)?a:defaults.size}else booleanAttrs.includes(e)?this.#config[e]=!1:this.#config[e]=defaults[e]}attributeChangedCallback(e,t,a){if(UniTextareaField.observedAttributes.includes(e))switch(this.#format(e,t,a),e){case"subject":this.#nodes.subject.textContent=this.subject;break;case"message":this.#nodes.message.textContent=this.message}}static get observedAttributes(){return Object.keys(defaults)}static get supportedEvents(){return Object.keys(custumEvents).map(e=>custumEvents[e])}#upgradeProperty(e){let t;UniTextareaField.observedAttributes.includes(e)&&(Object.prototype.hasOwnProperty.call(this,e)?(t=this[e],delete this[e]):t=booleanAttrs.includes(e)?!(!this.hasAttribute(e)&&!this.#config[e]):objectAttrs.includes(e)?this.hasAttribute(e)?this.getAttribute(e):JSON.stringify(this.#config[e]):this.hasAttribute(e)?this.getAttribute(e):this.#config[e],this[e]=t)}#setupEventListeners(){var e;this.#data.elementController.abort?.(),this.#nodes.textarea=this.querySelector("[slot=textarea]"),this.#nodes.textarea&&(this.#data.elementController=new AbortController,e=this.#data.elementController.signal,this.#nodes.textarea.addEventListener("input",this._onInput,{signal:e}),this.#nodes.textarea.addEventListener("keydown",this._onKeydown,{signal:e}),this._onInput())}set subject(e){e?this.setAttribute("subject",e):this.removeAttribute("subject")}get subject(){return this.#config.subject}set message(e){e?this.setAttribute("message",e):this.removeAttribute("message")}get message(){return this.#config.message}set stat(e){e?this.setAttribute("stat",e):this.removeAttribute("stat")}get stat(){return this.#config.stat}set appearance(e){e?this.setAttribute("appearance",e):this.removeAttribute("appearance")}get appearance(){return this.#config.appearance}set size(e){e?this.setAttribute("size",e):this.removeAttribute("size")}get size(){return this.#config.size}_onInput(e){var{textarea:t,counter:a}=this.#nodes;a.dataset.maxlength=t.maxLength,a.textContent=t.value.length,e&&"invalid"===this.stat&&(this.stat="")}_onKeydown(e){var{key:e,isComposing:t}=e;"Enter"===e&&t&&event.preventDefault()}_onSlotchange(){this.#setupEventListeners()}refresh(){this.hidden=!0,this.offsetHeight,this.hidden=!1}}const S=_wcl.supports(),T=_wcl.classToTagName("UniTextareaField");S.customElements&&S.shadowDOM&&S.template&&!window.customElements.get(T)&&window.customElements.define(_wcl.classToTagName("UniTextareaField"),UniTextareaField);export{UniTextareaField};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uni-textarea-field",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "<uni-textarea-field /> is an encapsulated Web Component built upon the foundation of the uniopen design language. Implementation is straightforward: simply slot a standard textarea element inside <uni-textarea-field />. The component instantly applies a user interface that aligns seamlessly with the uniopen design language guidelines. Furthermore, its visual styles can be dynamically adapted via native HTML attributes or JavaScript properties. The component also exposes comprehensive character count and textarea length metadata, providing users with a clear and intuitive understanding of predefined character constraints.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web"
|