Skip to content

Commit a7505cf

Browse files
committed
Buttons on input number
1 parent 44c191e commit a7505cf

5 files changed

Lines changed: 93 additions & 16 deletions

File tree

src/components/pg/buttonIncrement/buttonIncrement.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, normalizeInt, Part, Prop } from '@pictogrammers/element';
1+
import { Component, normalizeInt, Prop } from '@pictogrammers/element';
22

33
import template from './buttonIncrement.html';
44
import style from './buttonIncrement.css';
@@ -32,8 +32,16 @@ export default class PgButtonIncrement extends PgButton {
3232
this.dispatchEvent(new CustomEvent('increment'));
3333
}, this.incrementStepDelay);
3434
}, this.incrementDelay);
35+
const pointerLeave = () => {
36+
this.dispatchEvent(new CustomEvent('finish'));
37+
clearTimers();
38+
this.$button.removeEventListener('pointerleave', pointerLeave);
39+
};
40+
this.$button.addEventListener('pointerleave', pointerLeave);
41+
});
42+
this.$button.addEventListener('pointerup', () => {
43+
this.dispatchEvent(new CustomEvent('finish'));
44+
clearTimers();
3545
});
36-
this.$button.addEventListener('pointerup', clearTimers);
37-
this.$button.addEventListener('pointerleave', clearTimers);
3846
}
3947
}

src/components/pg/inputNumber/__examples__/basic/basic.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ export default class XPgInputNumberBasic extends HTMLElement {
2626
#handleInput(e: CustomEvent) {
2727
const { value } = e.detail;
2828
this.$value2.textContent = value;
29+
this.$input.value = value;
2930
}
3031
}

src/components/pg/inputNumber/inputNumber.css

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
[part=input] {
77
border: 1px solid var(--pg-input-text-border-color, #453C4F);
88
border-radius: 0.125rem;
9-
padding: var(--pg-input-text-padding, calc(0.5rem - 1px) 0.75rem);
9+
padding-inline-start: var(--pg-input-number-padding-inline, var(--pg-input-number-padding-inline-start, 0.5rem));
10+
padding-inline-end: var(--pg-input-number-padding-inline, var(--pg-input-number-padding-inline-end, 0.5rem));
11+
padding-block-start: var(--pg-input-number-padding-block, var(--pg-input-number-padding-block-start, 0.25rem));
12+
padding-block-end: var(--pg-input-number-padding-block, var(--pg-input-number-padding-block-start, 0.25rem));
1013
font-family: var(--pg-input-number-font-family, var(--pg-font-family));
1114
font-size: 1rem;
1215
outline: none;
1316
field-sizing: content;
14-
min-width: calc(100% - 0.5rem - 2px);
15-
max-width: calc(var(--pg-input-text-max-width, 100%) - 0.5rem - 2px);
17+
min-width: calc(100% - 1rem - 2px);
18+
max-width: calc(var(--pg-input-number-max-width, 100%) - 1.5rem - 2px);
1619
background-color: transparent;
1720
appearance: textfield;
1821
}
@@ -29,6 +32,32 @@
2932
[part=input]:active {
3033
box-shadow: 0 0 0 3px var(--pg-input-text-active-glow, rgb(79, 143, 249, 0.6));
3134
}
35+
3236
[part=input]:focus {
3337
box-shadow: 0 0 0 3px var(--pg-input-text-focus-glow, rgb(79, 143, 249, 0.5));
38+
z-index: 1;
39+
}
40+
41+
[part=layout] {
42+
display: grid;
43+
grid-template-columns: 1fr auto auto;
44+
}
45+
46+
[part=input]:has(+ [part=buttonMinus]) {
47+
border-right: 0;
48+
border-top-right-radius: 0;
49+
border-bottom-right-radius: 0;
50+
}
51+
52+
[part=buttonMinus] {
53+
--pg-button-border-radius: 0;
54+
margin-left: -1px;
55+
--pg-button-padding-block: var(--pg-input-number-padding-block, unset);
56+
--pg-button-padding-block-start: var(--pg-input-number-padding-block-start, unset);
57+
--pg-button-padding-block-end: var(--pg-input-number-padding-block-end, unset);
3458
}
59+
60+
[part=buttonPlus] {
61+
--pg-button-border-radius: 0 0.25rem 0.25rem 0;
62+
margin-left: -1px;
63+
}
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
1-
<input part="input" type="number" />
1+
<div part="layout">
2+
<input part="input" type="number" />
3+
<pg-button-increment part="buttonMinus">
4+
<pg-icon path="M19,13H5V11H19V13Z"></pg-icon>
5+
</pg-button-increment>
6+
<pg-button-increment part="buttonPlus">
7+
<pg-icon path="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z"></pg-icon>
8+
</pg-button-increment>
9+
</div>

src/components/pg/inputNumber/inputNumber.ts

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { Component, Prop, Part } from '@pictogrammers/element';
1+
import { Component, Prop, Part, normalizeFloat } from '@pictogrammers/element';
22

33
import template from './inputNumber.html';
44
import style from './inputNumber.css';
5+
import PgButtonIncrement from '../buttonIncrement/buttonIncrement';
56

67
@Component({
78
selector: 'pg-input-number',
@@ -10,22 +11,48 @@ import style from './inputNumber.css';
1011
})
1112
export default class PgInputNumber extends HTMLElement {
1213
@Prop() name: string = '';
13-
@Prop() value: string = '';
14+
@Prop(normalizeFloat) value: number = 0;
15+
@Prop(normalizeFloat) min: number = 0;
16+
@Prop(normalizeFloat) max: number = 100;
17+
@Prop(normalizeFloat) step: number = 1;
1418
@Prop() placeholder: string = '';
1519
@Prop() readOnly: boolean = false;
20+
@Prop() disableButtons: boolean = false;
1621

1722
@Part() $input: HTMLInputElement;
23+
@Part() $buttonMinus: PgButtonIncrement;
24+
@Part() $buttonPlus: PgButtonIncrement;
1825

1926
connectedCallback() {
2027
this.$input.addEventListener('input', this.handleInput.bind(this));
2128
this.$input.addEventListener('change', this.handleChange.bind(this));
29+
this.$buttonMinus.addEventListener('increment', (e: any) => {
30+
this.#triggerInput(this.value - this.step);
31+
});
32+
this.$buttonPlus.addEventListener('increment', (e: any) => {
33+
this.#triggerInput(this.value + this.step);
34+
});
35+
this.$buttonMinus.addEventListener('finish', (e: any) => {
36+
this.dispatchEvent(new CustomEvent('change', {
37+
detail: {
38+
value: this.value,
39+
},
40+
}));
41+
});
42+
this.$buttonPlus.addEventListener('finish', (e: any) => {
43+
this.dispatchEvent(new CustomEvent('change', {
44+
detail: {
45+
value: this.value,
46+
},
47+
}));
48+
});
2249
}
2350

2451
skipValue = false;
2552

2653
render(changes) {
2754
if (changes.value && !this.skipValue) {
28-
this.$input.value = this.value;
55+
this.$input.value = `${this.value}`;
2956
}
3057
if (changes.placeholder) {
3158
this.$input.placeholder = this.placeholder;
@@ -36,20 +63,24 @@ export default class PgInputNumber extends HTMLElement {
3663
this.skipValue = false;
3764
}
3865

39-
handleInput(e) {
40-
e.stopPropagation();
41-
this.skipValue = true;
42-
this.value = e.target.value;
66+
#triggerInput(value) {
4367
this.dispatchEvent(
4468
new CustomEvent('input', {
4569
detail: {
46-
value: e.target.value,
47-
name: e.name
70+
value: value,
71+
name: this.name,
4872
}
4973
})
5074
);
5175
}
5276

77+
handleInput(e) {
78+
e.stopPropagation();
79+
this.skipValue = true;
80+
const value = parseInt(e.target.value ?? '0', 10);
81+
this.#triggerInput(value);
82+
}
83+
5384
handleChange(e) {
5485
this.dispatchEvent(
5586
new CustomEvent('change', {

0 commit comments

Comments
 (0)