@pictogrammers/components 0.5.20 → 0.5.22

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.20",
4
+ "version": "0.5.22",
5
5
  "license": "MIT",
6
6
  "author": "Austin Andrews",
7
7
  "scripts": {
@@ -1,11 +1,21 @@
1
1
  import { Component, Part, Prop } from '@pictogrammers/element';
2
2
  import PgModal from '../../modal';
3
3
 
4
+ import '../../../modalHeader/modalHeader';
5
+ import '../../../modalBody/modalBody';
6
+ import '../../../modalFooter/modalFooter';
7
+
4
8
  import template from './basic.html';
5
9
 
6
10
  @Component({
7
11
  selector: 'x-my-modal',
8
- template: `<main>Hello! <button part="close">Close</button></main>`
12
+ template: `
13
+ <pg-modal-header>My Modal</pg-modal-header>
14
+ <pg-modal-body>Hello!</pg-modal-body>
15
+ <pg-modal-footer>
16
+ <button part="close">Close</button>
17
+ </pg-modal-footer>
18
+ `
9
19
  })
10
20
  export class XMyModal extends PgModal {
11
21
 
@@ -16,25 +16,8 @@
16
16
  overflow: hidden;
17
17
  min-width: 15rem;
18
18
  }
19
- header {
20
- border-bottom: 1px solid #ccc;
21
- background: #f1f1f1;
22
- padding: 0.75rem 1rem;
23
- }
24
- header h2 {
19
+ [part="headerText"] {
25
20
  font-size: 1.25rem;
26
21
  margin: 0;
27
22
  font-weight: normal;
28
- }
29
- main {
30
- padding: 0.5rem 1rem;
31
- }
32
- footer {
33
- display: flex;
34
- flex-direction: row;
35
- padding: 0.75rem 1rem;
36
- border-top: 1px solid #ccc;
37
- background: #f1f1f1;
38
- justify-content: flex-end;
39
- gap: 0.5rem;
40
23
  }
@@ -4,18 +4,18 @@
4
4
  id="dialog1"
5
5
  aria-labelledby="dialog_label"
6
6
  aria-modal="true">
7
- <header part="header">
7
+ <pg-modal-header part="header">
8
8
  <h2 id="dialog_label"
9
9
  class="dialog_label"
10
10
  part="headerText">
11
11
  Alert
12
12
  </h2>
13
- </header>
14
- <main>
13
+ </pg-modal-header>
14
+ <pg-modal-body>
15
15
  <p part="message"></p>
16
- </main>
17
- <footer>
16
+ </pg-modal-body>
17
+ <pg-modal-footer>
18
18
  <pg-button part="okay" variant="brand">Okay</pg-button>
19
- </footer>
19
+ </pg-modal-footer>
20
20
  </div>
21
21
  </div>
@@ -5,6 +5,10 @@ import style from './modalAlert.css';
5
5
 
6
6
  import PgOverlay from '../overlay/overlay';
7
7
  import PgButton from '../button/button';
8
+ import PgModalHeader from '../modalHeader/modalHeader';
9
+
10
+ import '../modalBody/modalBody';
11
+ import '../modalFooter/modalFooter';
8
12
 
9
13
  @Component({
10
14
  selector: 'pg-modal-alert',
@@ -15,7 +19,7 @@ export default class PgModalAlert extends PgOverlay {
15
19
  @Prop() header: string = 'Are you sure?';
16
20
  @Prop() message: string = 'Are you sure?';
17
21
 
18
- @Part() $header: HTMLDivElement;
22
+ @Part() $header: PgModalHeader;
19
23
  @Part() $headerText: HTMLHeadingElement;
20
24
  @Part() $message: HTMLDivElement;
21
25
  @Part() $okay: PgButton;
@@ -0,0 +1,17 @@
1
+ # `<pg-modal-body>`
2
+
3
+ The `pg-modal-body` component is a presentational component for the body section of a `PgModal`.
4
+
5
+ ```typescript
6
+ import '@pictogrammers/components/pg/modalBody';
7
+ ```
8
+
9
+ ```html
10
+ <pg-modal-body>Content</pg-modal-body>
11
+ ```
12
+
13
+ ## CSS Variables
14
+
15
+ | CSS Variables | Default | Description |
16
+ | ------------------------- | --------------- | ----------- |
17
+ | `--pg-modal-body-padding` | `0.5rem 1rem` | Padding |
@@ -0,0 +1,3 @@
1
+ import PgModalBody from './modalBody';
2
+
3
+ export default PgModalBody;
@@ -0,0 +1,6 @@
1
+ :host {
2
+ display: block;
3
+ }
4
+ [part="body"] {
5
+ padding: var(--pg-modal-body-padding, 0.5rem 1rem);
6
+ }
@@ -0,0 +1,3 @@
1
+ <main part="body">
2
+ <slot></slot>
3
+ </main>
@@ -0,0 +1,13 @@
1
+ import { Component } from '@pictogrammers/element';
2
+
3
+ import template from './modalBody.html';
4
+ import style from './modalBody.css';
5
+
6
+ @Component({
7
+ selector: 'pg-modal-body',
8
+ style,
9
+ template
10
+ })
11
+ export default class PgModalBody extends HTMLElement {
12
+
13
+ }
@@ -0,0 +1,23 @@
1
+ # `<pg-modal-footer>`
2
+
3
+ The `pg-modal-footer` component is a presentational component for the footer section of a `PgModal`.
4
+
5
+ ```typescript
6
+ import '@pictogrammers/components/pg/modalFooter';
7
+ ```
8
+
9
+ ```html
10
+ <pg-modal-footer>
11
+ <button>Close</button>
12
+ </pg-modal-footer>
13
+ ```
14
+
15
+ ## CSS Variables
16
+
17
+ | CSS Variables | Default | Description |
18
+ | ------------------------------------- | --------------- | --------------- |
19
+ | `--pg-modal-footer-background` | `#f1f1f1` | Background |
20
+ | `--pg-modal-footer-border-color` | `#ccc` | Border Color |
21
+ | `--pg-modal-footer-padding` | `0.75rem 1rem` | Padding |
22
+ | `--pg-modal-footer-justify-content` | `flex-end` | Justify Content |
23
+ | `--pg-modal-footer-gap` | `0.5rem` | Gap Between Items |
@@ -0,0 +1,3 @@
1
+ import PgModalFooter from './modalFooter';
2
+
3
+ export default PgModalFooter;
@@ -0,0 +1,12 @@
1
+ :host {
2
+ display: block;
3
+ }
4
+ [part="footer"] {
5
+ display: flex;
6
+ flex-direction: row;
7
+ padding: var(--pg-modal-footer-padding, 0.75rem 1rem);
8
+ border-top: 1px solid var(--pg-modal-footer-border-color, #ccc);
9
+ background: var(--pg-modal-footer-background, #f1f1f1);
10
+ justify-content: var(--pg-modal-footer-justify-content, flex-end);
11
+ gap: var(--pg-modal-footer-gap, 0.5rem);
12
+ }
@@ -0,0 +1,3 @@
1
+ <footer part="footer">
2
+ <slot></slot>
3
+ </footer>
@@ -0,0 +1,13 @@
1
+ import { Component } from '@pictogrammers/element';
2
+
3
+ import template from './modalFooter.html';
4
+ import style from './modalFooter.css';
5
+
6
+ @Component({
7
+ selector: 'pg-modal-footer',
8
+ style,
9
+ template
10
+ })
11
+ export default class PgModalFooter extends HTMLElement {
12
+
13
+ }
@@ -0,0 +1,19 @@
1
+ # `<pg-modal-header>`
2
+
3
+ The `pg-modal-header` component is a presentational component for the header section of a `PgModal`.
4
+
5
+ ```typescript
6
+ import '@pictogrammers/components/pg/modalHeader';
7
+ ```
8
+
9
+ ```html
10
+ <pg-modal-header>Title</pg-modal-header>
11
+ ```
12
+
13
+ ## CSS Variables
14
+
15
+ | CSS Variables | Default | Description |
16
+ | ---------------------------------- | ----------- | ------------ |
17
+ | `--pg-modal-header-background` | `#f1f1f1` | Background |
18
+ | `--pg-modal-header-border-color` | `#ccc` | Border Color |
19
+ | `--pg-modal-header-padding` | `0.75rem 1rem` | Padding |
@@ -0,0 +1,3 @@
1
+ import PgModalHeader from './modalHeader';
2
+
3
+ export default PgModalHeader;
@@ -0,0 +1,9 @@
1
+ :host {
2
+ display: block;
3
+ }
4
+ [part="header"] {
5
+ border-bottom: 1px solid var(--pg-modal-header-border-color, #ccc);
6
+ background: var(--pg-modal-header-background, #f1f1f1);
7
+ padding: var(--pg-modal-header-padding, 0.75rem 1rem);
8
+ font-size: 1.25rem;
9
+ }
@@ -0,0 +1,3 @@
1
+ <header part="header">
2
+ <slot></slot>
3
+ </header>
@@ -0,0 +1,13 @@
1
+ import { Component } from '@pictogrammers/element';
2
+
3
+ import template from './modalHeader.html';
4
+ import style from './modalHeader.css';
5
+
6
+ @Component({
7
+ selector: 'pg-modal-header',
8
+ style,
9
+ template
10
+ })
11
+ export default class PgModalHeader extends HTMLElement {
12
+
13
+ }
@@ -0,0 +1,34 @@
1
+ # `PgModalPrompt`
2
+
3
+ The `PgModalPrompt` creates a dialog with a single text field, an okay button, and a cancel button. For a message only dialog use `PgModalAlert`. For okay/cancel without a field use `PgModalConfirm`.
4
+
5
+ ```typescript
6
+ import PgModalPrompt from '@pictogrammers/components/pg/modalPrompt';
7
+ ```
8
+
9
+ ```typescript
10
+ const result = await PgModalPrompt.open({
11
+ header: 'Rename Item',
12
+ message: 'Enter a new name for the item.',
13
+ value: 'Untitled',
14
+ placeholder: 'Name',
15
+ });
16
+ if (result === null) {
17
+ console.log('Cancelled');
18
+ } else {
19
+ console.log('New name:', result);
20
+ }
21
+ ```
22
+
23
+ ## Props
24
+
25
+ | Props | Default | Description |
26
+ | ----------- | --------------------------- | ----------- |
27
+ | header | `'Please provide a value'` | Dialog title |
28
+ | message | `''` | Optional message shown above the field |
29
+ | value | `''` | Initial value of the field |
30
+ | placeholder | `''` | Placeholder text for the field |
31
+ | okay | `'Okay'` | Okay button label |
32
+ | cancel | `'Cancel'` | Cancel button label |
33
+
34
+ `close()` resolves with the field's value when `Okay` is clicked (or `Enter` is pressed), and `null` when `Cancel` is clicked or `Escape` is pressed.
@@ -0,0 +1,4 @@
1
+ <div class="example">
2
+ <button part="button">Launch Prompt Modal</button>
3
+ <div><code>Result: </code><code part="result"></code></div>
4
+ </div>
@@ -0,0 +1,33 @@
1
+ import { Component, Part } from '@pictogrammers/element';
2
+ import PgModalPrompt from '../../modalPrompt';
3
+
4
+ import template from './basic.html';
5
+
6
+ @Component({
7
+ selector: 'x-pg-modal-prompt-basic',
8
+ template
9
+ })
10
+ export default class XPgModalPromptBasic extends HTMLElement {
11
+
12
+ @Part() $button: HTMLButtonElement;
13
+ @Part() $result: HTMLSpanElement;
14
+
15
+ currentValue = 'Hello World!';
16
+
17
+ connectedCallback() {
18
+ this.$result.textContent = `${this.currentValue}`;
19
+ this.$button.addEventListener('click', this.handleClick.bind(this));
20
+ }
21
+
22
+ async handleClick() {
23
+ const result = await PgModalPrompt.open({
24
+ header: 'Rename Item',
25
+ message: 'Enter a new name for the item.',
26
+ value: this.currentValue,
27
+ placeholder: 'Name',
28
+ });
29
+ this.currentValue = result;
30
+ this.$result.textContent = `${result}`;
31
+ }
32
+
33
+ }
@@ -0,0 +1,3 @@
1
+ import PgModalPrompt from './modalPrompt';
2
+
3
+ export default PgModalPrompt;
@@ -0,0 +1,32 @@
1
+ .backdrop {
2
+ display: flex;
3
+ position: fixed;
4
+ top: 0;
5
+ left: 0;
6
+ right: 0;
7
+ bottom: 0;
8
+ background: rgba(0, 0, 0, 0.6);
9
+ justify-content: center;
10
+ align-items: center;
11
+ }
12
+ .dialog {
13
+ background: #fff;
14
+ border-radius: 0.5rem;
15
+ box-shadow: 0 1px 1rem rgba(0, 0, 0, 0.5);
16
+ overflow: hidden;
17
+ min-width: 15rem;
18
+ }
19
+ [part="headerText"] {
20
+ font-size: 1.25rem;
21
+ margin: 0;
22
+ font-weight: normal;
23
+ }
24
+ [part="message"] {
25
+ margin-block: 0.5rem 1rem;
26
+ }
27
+ [part="message"]:empty {
28
+ display: none;
29
+ }
30
+ [part="input"] {
31
+ margin-block-end: 0.5rem;
32
+ }
@@ -0,0 +1,23 @@
1
+ <div class="backdrop">
2
+ <div class="dialog"
3
+ role="dialog"
4
+ id="dialog1"
5
+ aria-labelledby="dialog_label"
6
+ aria-modal="true">
7
+ <pg-modal-header part="header">
8
+ <h2 id="dialog_label"
9
+ class="dialog_label"
10
+ part="headerText">
11
+ Prompt
12
+ </h2>
13
+ </pg-modal-header>
14
+ <pg-modal-body>
15
+ <p part="message"></p>
16
+ <pg-input-text part="input"></pg-input-text>
17
+ </pg-modal-body>
18
+ <pg-modal-footer>
19
+ <pg-button part="cancel">Cancel</pg-button>
20
+ <pg-button part="okay" variant="brand">Okay</pg-button>
21
+ </pg-modal-footer>
22
+ </div>
23
+ </div>
@@ -0,0 +1,89 @@
1
+ import { Component, Prop, Part } from '@pictogrammers/element';
2
+
3
+ import template from './modalPrompt.html';
4
+ import style from './modalPrompt.css';
5
+
6
+ import PgOverlay from '../overlay/overlay';
7
+ import PgButton from '../button/button';
8
+ import PgInputText from '../inputText/inputText';
9
+ import PgModalHeader from '../modalHeader/modalHeader';
10
+
11
+ import '../modalBody/modalBody';
12
+ import '../modalFooter/modalFooter';
13
+
14
+ @Component({
15
+ selector: 'pg-modal-prompt',
16
+ template,
17
+ style
18
+ })
19
+ export default class PgModalPrompt extends PgOverlay {
20
+ @Prop() header: string = 'Please provide a value';
21
+ @Prop() message: string = '';
22
+ @Prop() value: string = '';
23
+ @Prop() placeholder: string = '';
24
+ @Prop() cancel: string = 'Cancel';
25
+ @Prop() okay: string = 'Okay';
26
+
27
+ @Part() $header: PgModalHeader;
28
+ @Part() $headerText: HTMLHeadingElement;
29
+ @Part() $message: HTMLParagraphElement;
30
+ @Part() $input: PgInputText;
31
+ @Part() $okay: PgButton;
32
+ @Part() $cancel: PgButton;
33
+
34
+ #cacheKeydownHandler: any;
35
+
36
+ connectedCallback() {
37
+ this.$okay.addEventListener('click', this.#handleOkay.bind(this));
38
+ this.$cancel.addEventListener('click', this.#handleCancel.bind(this));
39
+ this.$input.addEventListener('keydown', this.#handleInputKeyDown.bind(this));
40
+ this.#cacheKeydownHandler ??= this.#handleKeyDown.bind(this);
41
+ document.addEventListener('keydown', this.#cacheKeydownHandler);
42
+ this.$input.focus();
43
+ }
44
+
45
+ disconnectedCallback() {
46
+ document.removeEventListener('keydown', this.#cacheKeydownHandler);
47
+ }
48
+
49
+ #handleKeyDown(e: KeyboardEvent) {
50
+ if (e.key === 'Escape') {
51
+ this.close(null);
52
+ }
53
+ }
54
+
55
+ #handleInputKeyDown(e: KeyboardEvent) {
56
+ if (e.key === 'Enter') {
57
+ this.#handleOkay();
58
+ }
59
+ }
60
+
61
+ #handleOkay() {
62
+ this.close(this.$input.value);
63
+ }
64
+
65
+ #handleCancel() {
66
+ this.close(null);
67
+ }
68
+
69
+ render(changes) {
70
+ if (changes.header) {
71
+ this.$headerText.textContent = this.header;
72
+ }
73
+ if (changes.message) {
74
+ this.$message.textContent = this.message;
75
+ }
76
+ if (changes.value) {
77
+ this.$input.value = this.value;
78
+ }
79
+ if (changes.placeholder) {
80
+ this.$input.placeholder = this.placeholder;
81
+ }
82
+ if (changes.okay) {
83
+ this.$okay.textContent = this.okay;
84
+ }
85
+ if (changes.cancel) {
86
+ this.$cancel.textContent = this.cancel;
87
+ }
88
+ }
89
+ }