Skip to content
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
45 changes: 45 additions & 0 deletions src/number-spinner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Form

<table width="100%">
<tr>
<td align="left" width="70%">
<p>Built by the super talented team at <strong><a href="https://www.travelopia.com/work-with-us/">Travelopia</a></strong>.</p>
</td>
<td align="center" width="30%">
<img src="https://www.travelopia.com/wp-content/themes/travelopia/assets/svg/logo-travelopia-circle.svg" width="50" />
</td>
</tr>
</table>

## Sample Usage

This is a number spinner component that is designed to be highly extendable.

Example:

```js
// Import the component as needed:
import '@travelopia/web-components/dist/number-spinner';

// TypeScript usage:
import { TPNumberSpinner, TPNumberSpinnerInput, TPNumberSpinnerIncrement, TPNumberSpinnerDecrement } from '@travelopia/web-components';

```

```html
<tp-number-spinner min="0" max="10" step="2">
<tp-number-spinner-decrement><button type="button">-</button></tp-number-spinner-decrement>
<tp-number-spinner-input>
<input type="number" value="0" readonly />
</tp-number-spinner-input>
<tp-number-spinner-increment><button type="button">+</button></tp-number-spinner-increment>
</tp-number-spinner>
```

## Attributes

| Attribute | Required | Values | Notes |
|-----------|----------|-----------------------|----------------------------------------|
| min | No | <integer> | The minimum value of the spinner |
| max | No | <integer> | The maxium value of the spinner |
| step | No | <integer> | The step of the spinner. Defaults to 1 |
44 changes: 44 additions & 0 deletions src/number-spinner/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Web Component: Number Spinner</title>

<link rel="stylesheet" href="../../dist/number-spinner/style.css" media="all">
<script type="module" src="../../dist/number-spinner/index.js"></script>
</head>

<body>
<main>
<tp-number-spinner>
<tp-number-spinner-decrement><button type="button">-</button></tp-number-spinner-decrement>
<tp-number-spinner-input>
<input type="number" value="0" readonly />
</tp-number-spinner-input>
<tp-number-spinner-increment><button type="button">+</button></tp-number-spinner-increment>
</tp-number-spinner>

<br><br>

<tp-number-spinner min="0" max="10" step="1">
<tp-number-spinner-decrement><button type="button">-</button></tp-number-spinner-decrement>
<tp-number-spinner-input>
<input type="number" value="0" readonly />
</tp-number-spinner-input>
<tp-number-spinner-increment><button type="button">+</button></tp-number-spinner-increment>
</tp-number-spinner>

<br><br>

<tp-number-spinner min="2" max="10" step="2">
<tp-number-spinner-decrement><button type="button">-</button></tp-number-spinner-decrement>
<tp-number-spinner-input>
<input type="number" value="4" readonly />
</tp-number-spinner-input>
<tp-number-spinner-increment><button type="button">+</button></tp-number-spinner-increment>
</tp-number-spinner>
</main>
</body>
</html>
20 changes: 20 additions & 0 deletions src/number-spinner/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Styles.
*/
import './style.scss';

/**
* Components.
*/
import { TPNumberSpinnerInput } from './tp-number-spinner-input';
import { TPNumberSpinnerIncrement } from './tp-number-spinner-increment';
import { TPNumberSpinnerDecrement } from './tp-number-spinner-decrement';
import { TPNumberSpinner } from './tp-number-spinner';

/**
* Register Components.
*/
customElements.define( 'tp-number-spinner-input', TPNumberSpinnerInput );
customElements.define( 'tp-number-spinner-increment', TPNumberSpinnerIncrement );
customElements.define( 'tp-number-spinner-decrement', TPNumberSpinnerDecrement );
customElements.define( 'tp-number-spinner', TPNumberSpinner );
3 changes: 3 additions & 0 deletions src/number-spinner/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tp-number-spinner {
display: contents;
}
29 changes: 29 additions & 0 deletions src/number-spinner/tp-number-spinner-decrement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Internal dependencies.
*/
import { TPNumberSpinner } from './tp-number-spinner';

/**
* TP Number Spinner Decrement Element.
*/
export class TPNumberSpinnerDecrement extends HTMLElement {
/**
* Constructor.
*/
constructor() {
// Initialize parent.
super();

// Attach click event for decrement.
this.querySelector( 'button' )?.addEventListener( 'click', this.decrement.bind( this ) );
}

/**
* Decrement the value.
*/
decrement(): void {
// Run function on parent.
const numberSpinner: TPNumberSpinner | null = this.closest( 'tp-number-spinner' );
numberSpinner?.decrement();
}
}
29 changes: 29 additions & 0 deletions src/number-spinner/tp-number-spinner-increment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Internal dependencies.
*/
import { TPNumberSpinner } from './tp-number-spinner';

/**
* TP Number Spinner Increment Element.
*/
export class TPNumberSpinnerIncrement extends HTMLElement {
/**
* Constructor.
*/
constructor() {
// Initialize parent.
super();

// Attach click event for increment.
this.querySelector( 'button' )?.addEventListener( 'click', this.increment.bind( this ) );
}

/**
* Increment the value.
*/
increment(): void {
// Run function on parent.
const numberSpinner: TPNumberSpinner | null = this.closest( 'tp-number-spinner' );
numberSpinner?.increment();
}
}
5 changes: 5 additions & 0 deletions src/number-spinner/tp-number-spinner-input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* TP Number Spinner Input.
*/
export class TPNumberSpinnerInput extends HTMLElement {
}
140 changes: 140 additions & 0 deletions src/number-spinner/tp-number-spinner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/**
* TP Number Spinner Element.
*/
export class TPNumberSpinner extends HTMLElement {
/**
* Get minimum value.
*
* @return {number|null} The minimum value.
*/
get min(): number | null {
// Get minimum attribute.
const min: string | null = this.getAttribute( 'min' );

// Check if we have an attribute.
if ( min ) {
// Yep, return its value.
return parseInt( min );
}

// Nope, return null.
return null;
}

/**
* Set minimum value.
*
* @param {number} min Minimum value.
*/
set min( min: number ) {
// Set attribute.
this.setAttribute( 'min', min.toString() );
}

/**
* Get maximum value.
*
* @return {number|null} The maximum value.
*/
get max(): number | null {
// Get maximum attribute.
const max: string | null = this.getAttribute( 'max' );

// Check if we have an attribute.
if ( max ) {
// Yep, return its value.
return parseInt( max );
}

// Nope, return null.
return null;
}

/**
* Set maximum value.
*
* @param {number} max Maximum value.
*/
set max( max: number ) {
// Set attribute.
this.setAttribute( 'max', max.toString() );
}

/**
* Get current step.
*
* @return {number} Current step.
*/
get step(): number {
// Get step from attribute.
return parseInt( this.getAttribute( 'step' ) ?? '1' );
}

/**
* Set current step.
*
* @param {number} step Current step.
*/
set step( step: number ) {
// Set attribute.
this.setAttribute( 'step', step.toString() );
}

/**
* Get value.
*
* @return {number} The value.
*/
get value(): number {
// Get value from input.
return parseInt( this.querySelector( 'tp-number-spinner-input input' )?.getAttribute( 'value' ) ?? '0' );
}

/**
* Set current value.
*
* @param {number} value Current value.
*/
set value( value: number ) {
// Set input's value.
this.querySelector( 'tp-number-spinner-input input' )?.setAttribute( 'value', value.toString() );
}

/**
* Increment.
*/
increment(): void {
// Calculate new value.
const currentValue: number = this.value;
const max: number | null = this.max;
const newValue: number = currentValue + this.step;

// Check if new value is greater than the maximum.
if ( max && newValue > max ) {
// Yes, that's not allowed.
return;
}

// No, set its value.
this.value = newValue;
}

/**
* Decrement.
*/
decrement(): void {
// Calculate new value.
const currentValue: number = this.value;
const min: number | null = this.min;
const newValue: number = currentValue - this.step;

// Check if new value is less than the minumum.
if ( min && newValue < min ) {
// Yes, that's not allowed.
return;
}

// No, set its value.
this.value = newValue;
}
}
1 change: 1 addition & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ module.exports = ( env ) => {
'multi-select': './src/multi-select/index.ts',
lightbox: './src/lightbox/index.ts',
'toggle-attribute': './src/toggle-attribute/index.ts',
'number-spinner': './src/number-spinner/index.ts',
},
module: {
rules: [
Expand Down
Loading