@pictogrammers/components 0.5.13 → 0.5.14

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pictogrammers/components",
3
3
  "type": "module",
4
- "version": "0.5.13",
4
+ "version": "0.5.14",
5
5
  "license": "MIT",
6
6
  "author": "Austin Andrews",
7
7
  "scripts": {
@@ -80,7 +80,7 @@
80
80
 
81
81
  [part=button].active {
82
82
  box-shadow: 0 1px 0.25rem rgba(0, 0, 0, 0.5) inset;
83
- background-color: rgba(69, 60, 79, 0.1);
83
+ background-color: rgb(236, 235, 237);
84
84
  color: var(--pg-button-color, #453C4F);
85
85
  }
86
86
  [part=button].active:hover {
@@ -1,4 +1,4 @@
1
- import { Component, normalizeInt, Part, Prop } from '@pictogrammers/element';
1
+ import { Component, normalizeInt, Prop } from '@pictogrammers/element';
2
2
 
3
3
  import template from './buttonIncrement.html';
4
4
  import style from './buttonIncrement.css';
@@ -32,8 +32,16 @@ export default class PgButtonIncrement extends PgButton {
32
32
  this.dispatchEvent(new CustomEvent('increment'));
33
33
  }, this.incrementStepDelay);
34
34
  }, 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();
35
45
  });
36
- this.$button.addEventListener('pointerup', clearTimers);
37
- this.$button.addEventListener('pointerleave', clearTimers);
38
46
  }
39
47
  }
@@ -26,5 +26,6 @@ export default class XPgInputNumberBasic extends HTMLElement {
26
26
  #handleInput(e: CustomEvent) {
27
27
  const { value } = e.detail;
28
28
  this.$value2.textContent = value;
29
+ this.$input.value = value;
29
30
  }
30
31
  }
@@ -0,0 +1,3 @@
1
+ import PgInputNumber from './inputNumber';
2
+
3
+ export default PgInputNumber;
@@ -4,15 +4,28 @@
4
4
  }
5
5
 
6
6
  [part=input] {
7
- border: 1px solid var(--pg-input-text-border-color, #453C4F);
7
+ border: 1px solid var(--pg-input-number-border-color, #453C4F);
8
8
  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-start, var(--pg-input-number-padding-inline, 0.5rem));
10
+ padding-inline-end: var(--pg-input-number-padding-inline-end, var(--pg-input-number-padding-inline, 0.5rem));
11
+ padding-block-start: var(--pg-input-number-padding-block-start, var(--pg-input-number-padding-block, 0.25rem));
12
+ padding-block-end: var(--pg-input-number-padding-block-start, var(--pg-input-number-padding-block, 0.25rem));
10
13
  font-family: var(--pg-input-number-font-family, var(--pg-font-family));
11
14
  font-size: 1rem;
12
15
  outline: none;
13
16
  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(
18
+ 100%
19
+ - var(--pg-input-number-padding-inline-start, var(--pg-input-number-padding-inline, 0.5rem))
20
+ - var(--pg-input-number-padding-inline-end, var(--pg-input-number-padding-inline, 0.5rem))
21
+ - 2px
22
+ );
23
+ max-width: calc(
24
+ var(--pg-input-number-max-width, 100%)
25
+ - var(--pg-input-number-padding-inline-start, var(--pg-input-number-padding-inline, 0.5rem))
26
+ - var(--pg-input-number-padding-inline-end, var(--pg-input-number-padding-inline, 0.5rem))
27
+ - 2px
28
+ );
16
29
  background-color: transparent;
17
30
  appearance: textfield;
18
31
  }
@@ -29,6 +42,40 @@
29
42
  [part=input]:active {
30
43
  box-shadow: 0 0 0 3px var(--pg-input-text-active-glow, rgb(79, 143, 249, 0.6));
31
44
  }
45
+
32
46
  [part=input]:focus {
33
47
  box-shadow: 0 0 0 3px var(--pg-input-text-focus-glow, rgb(79, 143, 249, 0.5));
48
+ z-index: 1;
49
+ }
50
+
51
+ [part=layout] {
52
+ display: grid;
53
+ grid-template-columns: 1fr auto auto;
54
+ gap: var(--pg-input-number-gap, 0);
55
+ }
56
+
57
+ [part=input]:has(+ [part=buttonMinus]) {
58
+ border-right: 0;
59
+ border-top-right-radius: var(--pg-input-number-minus-border-radius, var(--pg-input-number-minus-border-top-right-radius, 0));
60
+ border-bottom-right-radius: var(--pg-input-number-minus-border-radius, var(--pg-input-number-minus-border-top-right-radius, 0));;
61
+ }
62
+
63
+ [part=buttonMinus] {
64
+ --pg-button-border-radius: var(--pg-input-number-minus-border-radius, var(--pg-input-number-minus-border-top-right-radius, 0));;
65
+ margin-left: -1px;
66
+ --pg-button-padding-inline: var(--pg-input-number-minus-padding-inline, unset);
67
+ --pg-button-padding-block: var(--pg-input-number-minus-padding-block, unset);
34
68
  }
69
+
70
+ [part=buttonPlus] {
71
+ --pg-button-border-radius: var(
72
+ --pg-input-number-plus-border-radius,
73
+ var(--pg-input-number-plus-border-top-right-radius, 0)
74
+ var(--pg-input-number-plus-border-bottom-right-radius, 0.25rem)
75
+ var(--pg-input-number-plus-border-bottom-left-radius, 0.25rem)
76
+ var(--pg-input-number-plus-border-top-left-radius, 0)
77
+ );
78
+ margin-left: -1px;
79
+ --pg-button-padding-inline: var(--pg-input-number-plus-padding-inline, unset);
80
+ --pg-button-padding-block: var(--pg-input-number-plus-padding-block, unset);
81
+ }
@@ -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>
@@ -1,7 +1,8 @@
1
- import { Component, Prop, Part } from '@pictogrammers/element';
1
+ import { Component, Prop, Part, normalizeFloat } from '@pictogrammers/element';
2
2
 
3
3
  import template from './inputNumber.html';
4
4
  import style from './inputNumber.css';
5
+ import PgButtonIncrement from '../buttonIncrement/buttonIncrement';
5
6
 
6
7
  @Component({
7
8
  selector: 'pg-input-number',
@@ -10,22 +11,48 @@ import style from './inputNumber.css';
10
11
  })
11
12
  export default class PgInputNumber extends HTMLElement {
12
13
  @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;
14
18
  @Prop() placeholder: string = '';
15
19
  @Prop() readOnly: boolean = false;
20
+ @Prop() disableButtons: boolean = false;
16
21
 
17
22
  @Part() $input: HTMLInputElement;
23
+ @Part() $buttonMinus: PgButtonIncrement;
24
+ @Part() $buttonPlus: PgButtonIncrement;
18
25
 
19
26
  connectedCallback() {
20
27
  this.$input.addEventListener('input', this.handleInput.bind(this));
21
28
  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
+ });
22
49
  }
23
50
 
24
51
  skipValue = false;
25
52
 
26
53
  render(changes) {
27
54
  if (changes.value && !this.skipValue) {
28
- this.$input.value = this.value;
55
+ this.$input.value = `${this.value}`;
29
56
  }
30
57
  if (changes.placeholder) {
31
58
  this.$input.placeholder = this.placeholder;
@@ -36,20 +63,24 @@ export default class PgInputNumber extends HTMLElement {
36
63
  this.skipValue = false;
37
64
  }
38
65
 
39
- handleInput(e) {
40
- e.stopPropagation();
41
- this.skipValue = true;
42
- this.value = e.target.value;
66
+ #triggerInput(value) {
43
67
  this.dispatchEvent(
44
68
  new CustomEvent('input', {
45
69
  detail: {
46
- value: e.target.value,
47
- name: e.name
70
+ value: value,
71
+ name: this.name,
48
72
  }
49
73
  })
50
74
  );
51
75
  }
52
76
 
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
+
53
84
  handleChange(e) {
54
85
  this.dispatchEvent(
55
86
  new CustomEvent('change', {
@@ -0,0 +1,3 @@
1
+ # `<pg-input-radio>`
2
+
3
+ The `pg-input-radio` creates a radio list of options a user can pick from.
@@ -0,0 +1,6 @@
1
+ <div class="example">
2
+ <pg-input-radio part="input" value="item1"></pg-input-radio>
3
+ <div>
4
+ <code>onchange: <span part="value"></span></code>
5
+ </div>
6
+ </div>
@@ -0,0 +1,31 @@
1
+ import { Component, Part, Prop } from '@pictogrammers/element';
2
+ import PgInputRadio from '../../inputRadio';
3
+
4
+ import template from './basic.html';
5
+
6
+ @Component({
7
+ selector: 'x-pg-input-radio-basic',
8
+ template,
9
+ })
10
+ export default class XPgInputRadioBasic extends HTMLElement {
11
+
12
+ @Part() $input: PgInputRadio;
13
+ @Part() $value: HTMLSpanElement;
14
+
15
+ connectedCallback() {
16
+ this.$input.items.push({
17
+ label: 'Item 1',
18
+ value: 'item1',
19
+ }, {
20
+ label: 'Item 2',
21
+ value: 'item2',
22
+ });
23
+ this.$input.addEventListener('change', this.handleChange.bind(this));
24
+ }
25
+
26
+ handleChange(e: any) {
27
+ const { value } = e.detail;
28
+ this.$input.value = value;
29
+ this.$value.textContent = value;
30
+ }
31
+ }
@@ -0,0 +1,8 @@
1
+ <div class="example">
2
+ <pg-input-radio part="input" value="item1"></pg-input-check>
3
+ <pg-input-radio disabled></pg-input-check>
4
+ <pg-input-radio value="item2" disabled></pg-input-check>
5
+ <div>
6
+ <code>onchange: <span part="value"></span></code>
7
+ </div>
8
+ </div>
@@ -0,0 +1,23 @@
1
+ import { Component, Part, Prop } from '@pictogrammers/element';
2
+ import PgInputRadio from '../inputRadio';
3
+
4
+ import template from './basic.html';
5
+
6
+ @Component({
7
+ selector: 'x-pg-input-radio-basic',
8
+ template,
9
+ })
10
+ export default class XPgInputRadioBasic extends HTMLElement {
11
+
12
+ @Part() $input: PgInputRadio;
13
+ @Part() $value: HTMLSpanElement;
14
+
15
+ connectedCallback() {
16
+ this.$input.addEventListener('change', this.handleChange.bind(this));
17
+ }
18
+
19
+ handleChange(e) {
20
+ var value = e.target.value;
21
+ this.$value.innerText = value;
22
+ }
23
+ }
@@ -0,0 +1,3 @@
1
+ import PgInputRadio from './inputRadio';
2
+
3
+ export default PgInputRadio;
@@ -0,0 +1,5 @@
1
+ [part=items] {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 0.25rem;
5
+ }
@@ -0,0 +1 @@
1
+ <div part="items"></div>
@@ -0,0 +1,60 @@
1
+ import { Component, Prop, Part, normalizeBoolean, forEach } from '@pictogrammers/element';
2
+
3
+ import template from './inputRadio.html';
4
+ import style from './inputRadio.css';
5
+ import PgInputRadioItem from '../inputRadioItem/inputRadioItem';
6
+
7
+ @Component({
8
+ selector: 'pg-input-radio',
9
+ style,
10
+ template,
11
+ })
12
+ export default class PgInputRadio extends HTMLElement {
13
+ @Prop() name: string = '';
14
+ @Prop() value: string = '';
15
+ @Prop(normalizeBoolean) readOnly: boolean = false;
16
+ @Prop(normalizeBoolean) disabled: boolean = false;
17
+ @Prop() items: any[] = [];
18
+
19
+ @Part() $items: HTMLInputElement;
20
+
21
+ connectedCallback() {
22
+ forEach({
23
+ container: this.$items,
24
+ items: this.items,
25
+ type: () => PgInputRadioItem,
26
+ create: ($item: PgInputRadioItem, item) => {
27
+ $item.addEventListener('change', () => {
28
+ Array.from(this.$items.children).forEach(($ele: PgInputRadioItem) => {
29
+ if ($ele === $item) {
30
+ $ele.checked = true;
31
+ } else {
32
+ $ele.checked = false;
33
+ }
34
+ });
35
+ this.dispatchEvent(new CustomEvent('change', {
36
+ detail: {
37
+ value: item.value,
38
+ }
39
+ }))
40
+ });
41
+ // set initial checked
42
+ if (item.value === this.value) {
43
+ $item.checked = true;
44
+ }
45
+ }
46
+ });
47
+ }
48
+
49
+ render(changes) {
50
+ if (changes.value && this.items.length) {
51
+ Array.from(this.$items.children).forEach(($ele: PgInputRadioItem) => {
52
+ if ($ele.value === this.value) {
53
+ $ele.checked = true;
54
+ } else {
55
+ $ele.checked = false;
56
+ }
57
+ });
58
+ }
59
+ }
60
+ }
@@ -0,0 +1,3 @@
1
+ # `<pg-input-radio>`
2
+
3
+ The `pg-input-radio` creates a radio list of options a user can pick from.
File without changes
@@ -0,0 +1 @@
1
+ <div part="list"></div>
@@ -0,0 +1,19 @@
1
+ import { Component, Prop, Part, normalizeBoolean } from '@pictogrammers/element';
2
+
3
+ import template from './inputRadio.html';
4
+ import style from './inputRadio.css';
5
+
6
+ @Component({
7
+ selector: 'pg-input-radio',
8
+ style,
9
+ template,
10
+ })
11
+ export default class PgInputRadio extends HTMLElement {
12
+ @Prop() name: string = '';
13
+ @Prop() value: string = '';
14
+ @Prop(normalizeBoolean) readOnly: boolean = false;
15
+ @Prop(normalizeBoolean) disabled: boolean = false;
16
+ @Prop() items: any[] = [];
17
+
18
+ @Part() $input: HTMLInputElement;
19
+ }
@@ -0,0 +1,3 @@
1
+ # `PgInputRadioItem`
2
+
3
+ The `PgInputRadioItem` is used internally as options are added to the `pg-input-radio`.
@@ -0,0 +1,27 @@
1
+ svg:hover [part="path"] {
2
+ fill: #4f8ff9;
3
+ }
4
+
5
+ label {
6
+ display: flex;
7
+ flex-direction: row;
8
+ gap: 0.5rem;
9
+ align-items: center;
10
+ }
11
+
12
+ [part="input"] {
13
+ visibility: hidden;
14
+ width: 0;
15
+ height: 0;
16
+ margin: 0;
17
+ }
18
+
19
+ [part="input"]:not(:checked) + svg [part="check"] {
20
+ display: none;
21
+ }
22
+
23
+ svg {
24
+ width: 1.5rem;
25
+ height: 1.5rem;
26
+ margin-left: -0.5rem;
27
+ }
@@ -0,0 +1,8 @@
1
+ <label>
2
+ <input part="input" type="radio" />
3
+ <svg viewBox="0 0 24 24">
4
+ <path part="path" d="M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"></path>
5
+ <path part="check" d="M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7Z"></path>
6
+ </svg>
7
+ <span part="label"></span>
8
+ </label>
@@ -0,0 +1,36 @@
1
+ import { Component, Prop, Part, normalizeBoolean } from '@pictogrammers/element';
2
+
3
+ import template from './inputRadioItem.html';
4
+ import style from './inputRadioItem.css';
5
+
6
+ @Component({
7
+ selector: 'pg-input-radio-item',
8
+ style,
9
+ template,
10
+ })
11
+ export default class PgInputRadioItem extends HTMLElement {
12
+ @Prop() label: string = '';
13
+ @Prop() value: string = '';
14
+ @Prop() checked: boolean = false;
15
+
16
+ @Part() $input: HTMLInputElement;
17
+ @Part() $label: HTMLSpanElement;
18
+
19
+ connectedCallback() {
20
+ this.$input.addEventListener('change', () => {
21
+ this.dispatchEvent(new CustomEvent('change'));
22
+ });
23
+ }
24
+
25
+ render(changes) {
26
+ if (changes.label) {
27
+ this.$label.textContent = this.label;
28
+ }
29
+ if (changes.value) {
30
+ this.$input.textContent = this.label;
31
+ }
32
+ if (changes.checked) {
33
+ this.$input.checked = this.checked;
34
+ }
35
+ }
36
+ }
@@ -6,16 +6,26 @@
6
6
  [part=input] {
7
7
  border: 1px solid var(--pg-input-text-border-color, #453C4F);
8
8
  border-radius: 0.125rem;
9
- padding-inline-start: var(--pg-input-text-padding-inline, var(--pg-input-text-padding-inline-start, 0.5rem));
10
- padding-inline-end: var(--pg-input-text-padding-inline, var(--pg-input-text-padding-inline-end, 0.5rem));
11
- padding-block-start: var(--pg-input-text-padding-block, var(--pg-input-text-padding-block-start, 0.25rem));
12
- padding-block-end: var(--pg-input-text-padding-block, var(--pg-input-text-padding-block-start, 0.25rem));
9
+ padding-inline-start: var(--pg-input-text-padding-inline-start, var(--pg-input-text-padding-inline, 0.5rem));
10
+ padding-inline-end: var(--pg-input-text-padding-inline-end, var(--pg-input-text-padding-inline, 0.5rem));
11
+ padding-block-start: var(--pg-input-text-padding-block-start, var(--pg-input-text-padding-block, 0.25rem));
12
+ padding-block-end: var(--pg-input-text-padding-block-start, var(--pg-input-text-padding-block, 0.25rem));
13
13
  font-family: var(--pg-input-text-font-family, var(--pg-font-family));
14
14
  font-size: 1rem;
15
15
  outline: none;
16
16
  field-sizing: content;
17
- min-width: calc(100% - 1rem - 2px);
18
- max-width: calc(var(--pg-input-text-max-width, 100%) - 1.5rem - 2px);
17
+ min-width: calc(
18
+ 100%
19
+ - var(--pg-input-text-padding-inline-start, var(--pg-input-text-padding-inline, 0.5rem))
20
+ - var(--pg-input-text-padding-inline-end, var(--pg-input-text-padding-inline, 0.5rem))
21
+ - 2px
22
+ );
23
+ max-width: calc(
24
+ var(--pg-input-text-max-width, 100%)
25
+ - var(--pg-input-text-padding-inline-start, var(--pg-input-text-padding-inline, 0.5rem))
26
+ - var(--pg-input-text-padding-inline-end, var(--pg-input-text-padding-inline, 0.5rem))
27
+ - 2px
28
+ );
19
29
  background-color: transparent;
20
30
  }
21
31
 
@@ -10,9 +10,19 @@
10
10
 
11
11
  [part=value] {
12
12
  user-select: text;
13
- --pg-input-text-padding-inline: 0.25rem;
14
- --pg-input-text-border-color: transparent;
13
+ --pg-input-number-border-color: transparent;
15
14
  --pg-input-number-font-family: var(--pg-json-font-family);
15
+ --pg-input-number-padding-block: 0;
16
+ --pg-input-number-padding-inline: 0.25rem;
17
+ --pg-input-number-gap: 0.5rem;
18
+ --pg-input-number-minus-padding-inline: 0;
19
+ --pg-input-number-minus-padding-block: 0;
20
+ --pg-input-number-plus-padding-inline: 0;
21
+ --pg-input-number-plus-padding-block: 0;
22
+ --pg-icon-width: 1rem;
23
+ --pg-icon-height: 1rem;
24
+ --pg-input-number-plus-border-radius: 0.25rem;
25
+ --pg-input-number-minus-border-radius: 0.25rem;
16
26
  display: inline-flex;
17
27
  vertical-align: middle;
18
28
  margin: 0 -0.25rem;
@@ -19,6 +19,7 @@ export default class PgJsonNumber extends HTMLElement {
19
19
 
20
20
  connectedCallback() {
21
21
  this.$value.addEventListener('input', (e: any) => {
22
+ this.$value.value = e.detail.value;
22
23
  this.dispatchEvent(
23
24
  new CustomEvent('update', {
24
25
  detail: {
@@ -36,7 +37,7 @@ export default class PgJsonNumber extends HTMLElement {
36
37
  this.$key.textContent = this.key;
37
38
  }
38
39
  if (changes.value) {
39
- this.$value.value = `${this.value}`;
40
+ this.$value.value = this.value;
40
41
  }
41
42
  }
42
43
  }
@@ -10,9 +10,10 @@
10
10
 
11
11
  [part=value] {
12
12
  user-select: text;
13
- --pg-input-text-padding-inline: 0.25rem;
14
13
  --pg-input-text-border-color: transparent;
15
14
  --pg-input-text-font-family: var(--pg-json-font-family);
15
+ --pg-input-text-padding-block: 0;
16
+ --pg-input-text-padding-inline: 0.25rem;
16
17
  display: inline-flex;
17
18
  vertical-align: middle;
18
19
  margin: 0 -0.25rem;