Skip to content

Commit

Permalink
feat: Add <my-paste-target> custom element (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
nfreear committed Nov 1, 2023
1 parent 5cebbe2 commit 4056df9
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 4 deletions.
4 changes: 2 additions & 2 deletions demo/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @copyright © Nick Freear, 27-Jan-2022.
*/

import '../index.js';
import * as MY from '../index.js';

// For "my-speech.html" ~ <my-text-to-speech>
const queryString = window.location.href;
Expand All @@ -15,4 +15,4 @@ const LANG = mtLang ? mtLang[1] + (mtLang[2] || '') : 'en';

document.body.setAttribute('data-tts-lang', LANG);

console.debug('app.js (index.js)');
console.debug('app.js (index.js):', MY);
20 changes: 18 additions & 2 deletions demo/style/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,21 @@ pre {
padding: .5rem;
}

button {
cursor: pointer;
button,
input {
font: inherit;
padding: .3rem 2rem;
}

input:focus {
background: #ffff9d;
}

fieldset {
border: 2px solid #aaa;
padding: 1rem;
}

my-lorem-ipsum,
my-star-rating {
display: block;
Expand Down Expand Up @@ -94,6 +103,13 @@ my-feed::part(i) {
min-width: 5.5rem;
}

my-paste-target input {
font-size: larger;
text-align: center;
margin-right: .7rem;
width: 3rem;
}

/* The <p> in the <slot> within the Web Component !!
*/
my-star-rating p {
Expand Down
91 changes: 91 additions & 0 deletions src/components/MyPasteTargetElement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* My Paste Target.
*
* @copyright © Nick Freear, 01-Nov-2023.
*
* @see https://codepen.io/nfreear/pen/jOXJjgW
* @see https://w3.org/TR/WCAG22/#accessible-authentication-minimum
* @see https://w3.org/WAI/WCAG22/Techniques/failures/F109
* @status
* @since
*/

const { customElements, HTMLElement } = window || globalThis;

/**
* @class MyPasteTargetElement
* @property {number} length - Required. The expected length of pasted data.
* @property {string} selector - Optional. CSS selector (Default: 'input')
* @property {string} value - The `value` is set on a paste event.
* @event paste - Listens for the `paste` event.
*/
export class MyPasteTargetElement extends HTMLElement {
static getTag () {
return 'my-paste-target';
}

get length () { return parseInt(this.getAttribute('length')); }

get selector () { return this.getAttribute('selector') || 'input'; }

set value (val) { this._setValue(val); }

get value () { return this._value; }

connectedCallback () {
this._inputs = this.querySelectorAll(this.selector);
if (!this._inputs.length) {
throw new Error('No <input> elements found.');
}
if (!this.length) {
throw new Error('Attribute `length` is required and numeric.');
}
// const PER = this.length / this._inputs.length;
// TODO: Check for an integer value!

this.addEventListener('paste', (ev) => this._handlePasteEvent(ev));

console.debug('my-paste-target:', this);
}

_setValue (value) {
/* TODO: validate length, format, etc.!! */
const PER = this.length / this._inputs.length;
const PARTS = this._equalSplit(value, PER);

PARTS.forEach((part, idx) => {
this._inputs[idx].value = part;
});

this._value = value;
this.setAttribute('value', value);

return PARTS;
}

_handlePasteEvent (ev) {
const DATA = ev.clipboardData.getData('text');
// TODO: validate length, format, etc.!!

const PARTS = this._setValue(DATA);

console.debug('Paste:', PARTS, ev);

// INPUTS[0].setCustomValidity('Invalid');
// INPUTS[0].reportValidity();

ev.preventDefault();
}

/**
* @see https://stackoverflow.com/questions/7033639/split-large-string-in-n-size-chunks-in-javascript,
*/
_equalSplit (inputData, size) {
size = parseInt(size);
return inputData.match(new RegExp(`.{1,${size}}`, 'g'));
}
}

customElements.define('my-paste-target', MyPasteTargetElement);

// End.
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ export { MyLocalStorageElement } from './MyLocalStorageElement.js';
export { MySiteCounterElement } from './MySiteCounterElement.js';
// export { MyEditorElement } from './MyEditorElement.js';
export { MyMathElement } from './MyMathElement.js';
export * from './MyPasteTargetElement.js';

// export { MyFoobarElement } from './MyFoobarElement.js';

0 comments on commit 4056df9

Please sign in to comment.