Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set Travelopia Coding Standards #76

Merged
merged 5 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": [ "plugin:@wordpress/eslint-plugin/recommended-with-formatting" ],
"extends": [ "plugin:@travelopia/eslint-plugin-wordpress-coding-standards/default" ],
"overrides": [
{
"files": ["*.ts"],
Expand Down
4,348 changes: 2,569 additions & 1,779 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
},
"homepage": "https://github.com/Travelopia/web-components#readme",
"devDependencies": {
"@wordpress/eslint-plugin": "^17.1.0",
"@travelopia/eslint-plugin-wordpress-coding-standards": "^1.0.0",
"css-loader": "^6.8.1",
"mini-css-extract-plugin": "^2.7.6",
"postcss-loader": "^7.3.3",
Expand Down
4 changes: 4 additions & 0 deletions src/accordion/tp-accordion-collapse-all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class TPAccordionCollapseAllElement extends HTMLElement {
* Constructor.
*/
constructor() {
// Initialize parent.
super();
this.querySelector( 'button' )?.addEventListener( 'click', () => this.collapseAll() );
}
Expand All @@ -21,7 +22,10 @@ export class TPAccordionCollapseAllElement extends HTMLElement {
collapseAll(): void {
// Get accordion element.
const accordion: TPAccordionElement | null = this.closest( 'tp-accordion' );

// Terminates the function if accordion is not available.
if ( ! accordion ) {
// Early return.
return;
}

Expand Down
4 changes: 4 additions & 0 deletions src/accordion/tp-accordion-expand-all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class TPAccordionExpandAllElement extends HTMLElement {
* Constructor.
*/
constructor() {
// Initialize parent.
super();
this.querySelector( 'button' )?.addEventListener( 'click', this.expandAll.bind( this ) );
}
Expand All @@ -21,7 +22,10 @@ export class TPAccordionExpandAllElement extends HTMLElement {
expandAll() {
// Get accordion.
const accordion: TPAccordionElement | null = this.closest( 'tp-accordion' );

// Terminates if accordion is not present.
if ( ! accordion ) {
// Early return.
return;
}

Expand Down
6 changes: 6 additions & 0 deletions src/accordion/tp-accordion-handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class TPAccordionHandleElement extends HTMLElement {
* Constructor.
*/
constructor() {
// Initialize parent.
super();
this.querySelector( 'button' )?.addEventListener( 'click', this.toggle.bind( this ) );
}
Expand All @@ -19,11 +20,16 @@ export class TPAccordionHandleElement extends HTMLElement {
* Toggle accordion.
*/
toggle(): void {
// Variables.
const accordionItem: TPAccordionItemElement | null = this.closest( 'tp-accordion-item' );

// Terminates if accordion item is not present.
if ( ! accordionItem ) {
//Early return.
return;
}

// If accordion item is open.
if ( 'yes' !== accordionItem.getAttribute( 'open' ) ) {
accordionItem.setAttribute( 'open', 'yes' );
} else {
Expand Down
15 changes: 15 additions & 0 deletions src/accordion/tp-accordion-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ export class TPAccordionItemElement extends HTMLElement {
* Constructor.
*/
constructor() {
// Initialize parent.
super();

// Check if by default accordion item is open.
if ( 'yes' === this.getAttribute( 'open-by-default' ) ) {
this.setAttribute( 'open', 'yes' );
}
Expand All @@ -25,6 +27,7 @@ export class TPAccordionItemElement extends HTMLElement {
* @return {Array} List of observed attributes.
*/
static get observedAttributes(): string[] {
// Attributes observed in the TPAccordionItemElement web-component.
return [ 'open' ];
}

Expand All @@ -38,24 +41,33 @@ export class TPAccordionItemElement extends HTMLElement {
* @param {string} newValue New Value.
*/
attributeChangedCallback( name: string, oldValue: string, newValue: string ): void {
// To check if observed attributes are changed.

//Early return if no change in attributes.
if ( oldValue === newValue || 'open' !== name ) {
// Early return.
return;
}

// Conditionally open or close based on changed value.
if ( 'yes' === newValue ) {
this.open();
} else {
this.close();
}

// Removing default value.
this.removeAttribute( 'open-by-default' );
}

/**
* Open accordion item.
*/
open(): void {
// Initializing variables.
const content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );

// Open the accordion.
if ( content ) {
this.dispatchEvent( new CustomEvent( 'before-open', { bubbles: true } ) );
slideElementDown( content, 600 );
Expand All @@ -67,7 +79,10 @@ export class TPAccordionItemElement extends HTMLElement {
* Close accordion item.
*/
close(): void {
// Initializing variables.
const content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );

// Close the accordion.
if ( content ) {
this.dispatchEvent( new CustomEvent( 'before-close', { bubbles: true } ) );
slideElementUp( content, 600 );
Expand Down
16 changes: 15 additions & 1 deletion src/accordion/tp-accordion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class TPAccordionElement extends HTMLElement {
* @return {Array} List of observed attributes.
*/
static get observedAttributes(): string[] {
// Attributes observed in the TPAccordionItemElement web-component.
return [ 'collapse-all', 'expand-all' ];
}

Expand All @@ -24,12 +25,18 @@ export class TPAccordionElement extends HTMLElement {
* @param {string} newValue New value.
*/
attributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {
// To check if observed attributes are changed.

//Early return if no change in attributes.
if ( oldValue === newValue ) {
// Early return.
return;
}

// Update initially according to the value present in expand-all or collapse all.
this.update();

// If attribute value is changed then open and close according to the name of event.
if ( 'yes' === newValue && ( 'collapse-all' === name || 'expand-all' === name ) ) {
this.dispatchEvent( new CustomEvent( name, { bubbles: true } ) );
}
Expand All @@ -41,12 +48,17 @@ export class TPAccordionElement extends HTMLElement {
update(): void {
// Get accordion items.
const accordionItems: NodeListOf<TPAccordionItemElement> = this.querySelectorAll( 'tp-accordion-item' );

//Early return if accordion items are not present.
if ( ! accordionItems ) {
// Early return.
return;
}

// Determine action.
// Initialize action variable.
let action: string = '';

// Determine action.
if ( 'yes' === this.getAttribute( 'expand-all' ) ) {
action = 'expand-all';
} else if ( 'yes' === this.getAttribute( 'collapse-all' ) ) {
Expand All @@ -55,11 +67,13 @@ export class TPAccordionElement extends HTMLElement {

// Check if we have an action.
if ( '' === action ) {
// Return if action is not present.
return;
}

// Expand or collapse accordion items.
accordionItems.forEach( ( accordionItem: TPAccordionItemElement ): void => {
// Conditionally expand or collapse each item.
if ( 'expand-all' === action ) {
accordionItem.setAttribute( 'open', 'yes' );
} else if ( 'collapse-all' === action ) {
Expand Down
1 change: 1 addition & 0 deletions src/form/definitions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface TPFormValidator {
* Window.
*/
declare global {
// Declare interface for validators and errors.
interface Window {
tpFormValidators: {
[ key: string ]: TPFormValidator;
Expand Down
6 changes: 5 additions & 1 deletion src/form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import './style.scss';
/**
* Validators.
*/

// Import validators.
import { TPFormValidator } from './definitions';
import * as required from './validators/required';
import * as email from './validators/email';
import * as minLength from './validators/min-length';
import * as maxLength from './validators/max-length';
import * as noEmptySpaces from './validators/no-empty-spaces';

// Prepare validators.
const validators = [
required,
email,
Expand All @@ -27,9 +30,11 @@ const validators = [
window.tpFormValidators = {};
window.tpFormErrors = {};

// Register validators.
validators.forEach( (
{ name, validator, errorMessage }: { name: string, validator: TPFormValidator, errorMessage: string }
): void => {
// Assigning validators and error messages to various fields.
window.tpFormValidators[ name ] = validator;
window.tpFormErrors[ name ] = errorMessage;
} );
Expand All @@ -49,4 +54,3 @@ customElements.define( 'tp-form', TPFormElement );
customElements.define( 'tp-form-field', TPFormFieldElement );
customElements.define( 'tp-form-error', TPFormErrorElement );
customElements.define( 'tp-form-submit', TPFormSubmitElement );

38 changes: 36 additions & 2 deletions src/form/tp-form-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ export class TPFormFieldElement extends HTMLElement {
* Constructor.
*/
constructor() {
// Initialize parent.
super();

// Get field.
const field = this.getField();

// Add event listeners.
field?.addEventListener( 'keyup', this.handleFieldChanged.bind( this ) );
field?.addEventListener( 'change', this.handleFieldChanged.bind( this ) );
}
Expand All @@ -21,6 +26,7 @@ export class TPFormFieldElement extends HTMLElement {
* Update validation when the field has changed.
*/
handleFieldChanged(): void {
// Validate the field again if 'valid' or 'error' attribute is present.
if ( this.getAttribute( 'valid' ) || this.getAttribute( 'error' ) ) {
this.validate();
}
Expand All @@ -32,6 +38,7 @@ export class TPFormFieldElement extends HTMLElement {
* @return {Array} List of observed attributes.
*/
static get observedAttributes(): string[] {
// Attributes observed in the TPFormFieldElement web-component.
return [ 'valid', 'error' ];
}

Expand All @@ -43,22 +50,34 @@ export class TPFormFieldElement extends HTMLElement {
* @param {string} newValue New value.
*/
attributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {
// Check if the observed attributes 'valid' or 'error' have changed.

// Dispatch a custom 'validate' event.
if ( ( 'valid' === name || 'error' === name ) && oldValue !== newValue ) {
this.dispatchEvent( new CustomEvent( 'validate', { bubbles: true } ) );
}

// Update the component after the attribute change.
this.update();
}

/**
* Update component.
*/
update(): void {
// Check if tpFormValidators exist in the window object.
const { tpFormValidators } = window;

// Exit the function if validators are not available.
if ( ! tpFormValidators ) {
//Early return
return;
}

// Get the 'error' attribute value.
const error: string = this.getAttribute( 'error' ) ?? '';

// Check if the error exists and has a corresponding error message function.
if ( '' !== error && error in tpFormValidators && 'function' === typeof tpFormValidators[ error ].getErrorMessage ) {
this.setErrorMessage( tpFormValidators[ error ].getErrorMessage( this ) );
} else {
Expand All @@ -72,6 +91,7 @@ export class TPFormFieldElement extends HTMLElement {
* @return {HTMLElement} The associated field for this component.
*/
getField(): HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null {
// Return the associated field by querying input, select, or textarea elements.
return this.querySelector( 'input,select,textarea' );
}

Expand All @@ -81,14 +101,18 @@ export class TPFormFieldElement extends HTMLElement {
* @return {boolean} Whether this field passed validation.
*/
validate(): boolean {
// Look for validators.
// Retrieve tpFormValidators from the window object.
const { tpFormValidators } = window;

// Exit the function if validators are not available.
if ( ! tpFormValidators ) {
// If no validators are found, return true indicating validation passed.
return true;
}

// Check if the field is not visible.
// Check if the field is visible.
if ( this.offsetWidth <= 0 || this.offsetHeight <= 0 ) {
// If the field is not visible, return true indicating validation passed.
return true;
}

Expand All @@ -99,6 +123,7 @@ export class TPFormFieldElement extends HTMLElement {

// Traverse all attributes to see if we find a matching validator.
allAttributes.every( ( attributeName: string ): boolean => {
// Check if the attribute is a validator.
if ( attributeName in tpFormValidators && 'function' === typeof tpFormValidators[ attributeName ].validate ) {
// We found one, lets validate the field.
const isValid: boolean = tpFormValidators[ attributeName ].validate( this );
Expand All @@ -107,6 +132,8 @@ export class TPFormFieldElement extends HTMLElement {
if ( false === isValid ) {
valid = false;
error = attributeName;

// return false;
return false;
}
}
Expand Down Expand Up @@ -134,7 +161,10 @@ export class TPFormFieldElement extends HTMLElement {
* @param {string} message Error message.
*/
setErrorMessage( message: string = '' ): void {
// Look for an existing tp-form-error element.
const error: TPFormErrorElement | null = this.querySelector( 'tp-form-error' );

// If found, update its innerHTML with the error message. Otherwise, create a new tp-form-error element and append it to the component.
if ( error ) {
error.innerHTML = message;
} else {
Expand All @@ -143,14 +173,18 @@ export class TPFormFieldElement extends HTMLElement {
this.appendChild( errorElement );
}

// Dispatch a custom 'validation-error' event.
this.dispatchEvent( new CustomEvent( 'validation-error' ) );
}

/**
* Remove the error message.
*/
removeErrorMessage(): void {
// Find and remove the tp-form-error element.
this.querySelector( 'tp-form-error' )?.remove();

// Dispatch a custom 'validation-success' event.
this.dispatchEvent( new CustomEvent( 'validation-success' ) );
}
}
Loading
Loading