@operato/popup 10.11.0 → 10.16.0
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/CHANGELOG.md +23 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +206 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +7985 -0
- package/dist/src/implementation.d.ts +13 -0
- package/dist/src/implementation.js +13 -0
- package/dist/src/implementation.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/open-popup.d.ts +37 -13
- package/dist/src/open-popup.js +79 -12
- package/dist/src/open-popup.js.map +1 -1
- package/dist/src/ox-floating-overlay.d.ts +4 -1
- package/dist/src/ox-floating-overlay.js +19 -2
- package/dist/src/ox-floating-overlay.js.map +1 -1
- package/dist/src/ox-popup-actions.d.ts +36 -0
- package/dist/src/ox-popup-actions.js +129 -0
- package/dist/src/ox-popup-actions.js.map +1 -0
- package/dist/src/ox-prompt.d.ts +25 -3
- package/dist/src/ox-prompt.js +74 -42
- package/dist/src/ox-prompt.js.map +1 -1
- package/dist/src/popup-result.d.ts +19 -0
- package/dist/src/popup-result.js +53 -0
- package/dist/src/popup-result.js.map +1 -0
- package/dist/test/office-control-height.test.d.ts +2 -0
- package/dist/test/office-control-height.test.js +102 -0
- package/dist/test/office-control-height.test.js.map +1 -0
- package/dist/test/ox-popup-actions.test.d.ts +3 -0
- package/dist/test/ox-popup-actions.test.js +104 -0
- package/dist/test/ox-popup-actions.test.js.map +1 -0
- package/dist/test/ox-prompt-actions.test.d.ts +1 -0
- package/dist/test/ox-prompt-actions.test.js +108 -0
- package/dist/test/ox-prompt-actions.test.js.map +1 -0
- package/dist/test/popup-result.test.d.ts +1 -0
- package/dist/test/popup-result.test.js +114 -0
- package/dist/test/popup-result.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -5
- package/test/office-control-height.test.ts +125 -0
- package/test/ox-popup-actions.test.ts +130 -0
- package/test/ox-prompt-actions.test.ts +136 -0
- package/test/popup-result.test.ts +150 -0
- package/translations/en.json +6 -1
- package/translations/ja.json +6 -0
- package/translations/ko.json +6 -1
- package/translations/ms.json +6 -0
- package/translations/zh.json +6 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* The row of commands at the bottom of a popup.
|
|
4
|
+
*
|
|
5
|
+
* Popups had nine different button rows (heights 28 to 44, radius 5 to pill, cancel left or right,
|
|
6
|
+
* one app painting cancel red) because every popup wrote its own markup and CSS. A written rule would
|
|
7
|
+
* have produced a tenth. So the row is an element and owns what the rule says:
|
|
8
|
+
*
|
|
9
|
+
* - **Order.** Whatever order the markup uses, it renders
|
|
10
|
+
* `[start] ··· [default slot] [cancel] [confirm]` - the main action is always the rightmost one,
|
|
11
|
+
* cancel always sits just before it, and a destructive side action (delete inside an editor) is
|
|
12
|
+
* pushed to the far left, away from the main action.
|
|
13
|
+
* - **Height and shape.** The height is --popup-action-height (32px by default, ADR-0060 decision 6),
|
|
14
|
+
* for mouse and finger alike. With a mouse the buttons are pills, because the container is a
|
|
15
|
+
* rounded card and controls follow the surface that holds them; with a finger the row becomes a
|
|
16
|
+
* full-width square action bar. Plain
|
|
17
|
+
* `<button>`s get the same height as Material buttons, so one row never mixes two heights.
|
|
18
|
+
* - **Destructive colour.** `destructive` on a slotted button paints it with the error colour. Cancel
|
|
19
|
+
* is never destructive, whatever attribute it carries.
|
|
20
|
+
*
|
|
21
|
+
* ```html
|
|
22
|
+
* <ox-popup-actions>
|
|
23
|
+
* <md-text-button slot="start" destructive @click=${remove}>delete</md-text-button>
|
|
24
|
+
* <md-text-button slot="cancel" @click=${() => closePopup(this)}>cancel</md-text-button>
|
|
25
|
+
* <md-filled-button slot="confirm" @click=${save}>save</md-filled-button>
|
|
26
|
+
* </ox-popup-actions>
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* A screen that must be bigger (a shop-floor terminal used with gloves) raises the height, not the
|
|
30
|
+
* markup: `--popup-action-height: 68px`, for mouse and finger alike. Shop-floor popups must declare it
|
|
31
|
+
* (e.g. `var(--ui-tap-glove)`): the default is sized for office screens.
|
|
32
|
+
*/
|
|
33
|
+
export declare class OxPopupActions extends LitElement {
|
|
34
|
+
static styles: import("lit").CSSResult;
|
|
35
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { css, html, LitElement } from 'lit';
|
|
3
|
+
import { customElement } from 'lit/decorators.js';
|
|
4
|
+
import { actionHeight } from '@operato/styles/action-heights.js';
|
|
5
|
+
/**
|
|
6
|
+
* The row of commands at the bottom of a popup.
|
|
7
|
+
*
|
|
8
|
+
* Popups had nine different button rows (heights 28 to 44, radius 5 to pill, cancel left or right,
|
|
9
|
+
* one app painting cancel red) because every popup wrote its own markup and CSS. A written rule would
|
|
10
|
+
* have produced a tenth. So the row is an element and owns what the rule says:
|
|
11
|
+
*
|
|
12
|
+
* - **Order.** Whatever order the markup uses, it renders
|
|
13
|
+
* `[start] ··· [default slot] [cancel] [confirm]` - the main action is always the rightmost one,
|
|
14
|
+
* cancel always sits just before it, and a destructive side action (delete inside an editor) is
|
|
15
|
+
* pushed to the far left, away from the main action.
|
|
16
|
+
* - **Height and shape.** The height is --popup-action-height (32px by default, ADR-0060 decision 6),
|
|
17
|
+
* for mouse and finger alike. With a mouse the buttons are pills, because the container is a
|
|
18
|
+
* rounded card and controls follow the surface that holds them; with a finger the row becomes a
|
|
19
|
+
* full-width square action bar. Plain
|
|
20
|
+
* `<button>`s get the same height as Material buttons, so one row never mixes two heights.
|
|
21
|
+
* - **Destructive colour.** `destructive` on a slotted button paints it with the error colour. Cancel
|
|
22
|
+
* is never destructive, whatever attribute it carries.
|
|
23
|
+
*
|
|
24
|
+
* ```html
|
|
25
|
+
* <ox-popup-actions>
|
|
26
|
+
* <md-text-button slot="start" destructive @click=${remove}>delete</md-text-button>
|
|
27
|
+
* <md-text-button slot="cancel" @click=${() => closePopup(this)}>cancel</md-text-button>
|
|
28
|
+
* <md-filled-button slot="confirm" @click=${save}>save</md-filled-button>
|
|
29
|
+
* </ox-popup-actions>
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* A screen that must be bigger (a shop-floor terminal used with gloves) raises the height, not the
|
|
33
|
+
* markup: `--popup-action-height: 68px`, for mouse and finger alike. Shop-floor popups must declare it
|
|
34
|
+
* (e.g. `var(--ui-tap-glove)`): the default is sized for office screens.
|
|
35
|
+
*/
|
|
36
|
+
let OxPopupActions = class OxPopupActions extends LitElement {
|
|
37
|
+
static { this.styles = css `
|
|
38
|
+
:host {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
gap: var(--spacing-small, 4px);
|
|
42
|
+
padding-top: var(--spacing-medium, 8px);
|
|
43
|
+
border-top: 1px solid var(--md-sys-color-outline-variant);
|
|
44
|
+
|
|
45
|
+
--_height: ${actionHeight('--popup-action-height')};
|
|
46
|
+
--_shape: var(--popup-control-radius, 999em);
|
|
47
|
+
|
|
48
|
+
--md-text-button-container-height: var(--_height);
|
|
49
|
+
--md-filled-button-container-height: var(--_height);
|
|
50
|
+
--md-outlined-button-container-height: var(--_height);
|
|
51
|
+
--md-text-button-container-shape: var(--_shape);
|
|
52
|
+
--md-filled-button-container-shape: var(--_shape);
|
|
53
|
+
--md-outlined-button-container-shape: var(--_shape);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
[spacer] {
|
|
57
|
+
flex: 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
::slotted(button) {
|
|
61
|
+
box-sizing: border-box;
|
|
62
|
+
min-height: var(--_height);
|
|
63
|
+
padding: 0 var(--spacing-large, 16px);
|
|
64
|
+
border-radius: var(--_shape);
|
|
65
|
+
font: inherit;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Destructive: the error colour, on the filled container or on the label. Never on cancel. */
|
|
69
|
+
::slotted(md-filled-button[destructive]:not([slot='cancel'])) {
|
|
70
|
+
--md-filled-button-container-color: var(--md-sys-color-error);
|
|
71
|
+
--md-filled-button-label-text-color: var(--md-sys-color-on-error);
|
|
72
|
+
--md-filled-button-hover-label-text-color: var(--md-sys-color-on-error);
|
|
73
|
+
--md-filled-button-focus-label-text-color: var(--md-sys-color-on-error);
|
|
74
|
+
--md-filled-button-pressed-label-text-color: var(--md-sys-color-on-error);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
::slotted(md-text-button[destructive]:not([slot='cancel'])),
|
|
78
|
+
::slotted(md-outlined-button[destructive]:not([slot='cancel'])) {
|
|
79
|
+
--md-text-button-label-text-color: var(--md-sys-color-error);
|
|
80
|
+
--md-text-button-hover-label-text-color: var(--md-sys-color-error);
|
|
81
|
+
--md-text-button-focus-label-text-color: var(--md-sys-color-error);
|
|
82
|
+
--md-text-button-pressed-label-text-color: var(--md-sys-color-error);
|
|
83
|
+
--md-outlined-button-label-text-color: var(--md-sys-color-error);
|
|
84
|
+
--md-outlined-button-hover-label-text-color: var(--md-sys-color-error);
|
|
85
|
+
--md-outlined-button-focus-label-text-color: var(--md-sys-color-error);
|
|
86
|
+
--md-outlined-button-pressed-label-text-color: var(--md-sys-color-error);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
::slotted(button[destructive]:not([slot='cancel'])) {
|
|
90
|
+
color: var(--md-sys-color-error);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/*
|
|
94
|
+
* Fingers: a full-width, square action bar. The line is still the card's bottom edge, so it takes
|
|
95
|
+
* the card's shape - square - and every button shares the width. 36 is a floor, not a ceiling:
|
|
96
|
+
* a terminal that declared 68 keeps 68.
|
|
97
|
+
*/
|
|
98
|
+
@media (pointer: coarse) {
|
|
99
|
+
:host {
|
|
100
|
+
gap: 0;
|
|
101
|
+
padding-top: 0;
|
|
102
|
+
|
|
103
|
+
--_shape: 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
[spacer] {
|
|
107
|
+
display: none;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
::slotted(*) {
|
|
111
|
+
flex: 1;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
`; }
|
|
115
|
+
render() {
|
|
116
|
+
return html `
|
|
117
|
+
<slot name="start"></slot>
|
|
118
|
+
<div spacer></div>
|
|
119
|
+
<slot></slot>
|
|
120
|
+
<slot name="cancel"></slot>
|
|
121
|
+
<slot name="confirm"></slot>
|
|
122
|
+
`;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
OxPopupActions = __decorate([
|
|
126
|
+
customElement('ox-popup-actions')
|
|
127
|
+
], OxPopupActions);
|
|
128
|
+
export { OxPopupActions };
|
|
129
|
+
//# sourceMappingURL=ox-popup-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ox-popup-actions.js","sourceRoot":"","sources":["../../src/ox-popup-actions.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAA;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,UAAU;aACrC,WAAM,GAAG,GAAG,CAAA;;;;;;;;mBAQF,YAAY,CAAC,uBAAuB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqErD,AA7EY,CA6EZ;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;;;;KAMV,CAAA;IACH,CAAC;;AAxFU,cAAc;IAD1B,aAAa,CAAC,kBAAkB,CAAC;GACrB,cAAc,CAyF1B","sourcesContent":["import { css, html, LitElement } from 'lit'\nimport { customElement } from 'lit/decorators.js'\n\nimport { actionHeight } from '@operato/styles/action-heights.js'\n\n/**\n * The row of commands at the bottom of a popup.\n *\n * Popups had nine different button rows (heights 28 to 44, radius 5 to pill, cancel left or right,\n * one app painting cancel red) because every popup wrote its own markup and CSS. A written rule would\n * have produced a tenth. So the row is an element and owns what the rule says:\n *\n * - **Order.** Whatever order the markup uses, it renders\n * `[start] ··· [default slot] [cancel] [confirm]` - the main action is always the rightmost one,\n * cancel always sits just before it, and a destructive side action (delete inside an editor) is\n * pushed to the far left, away from the main action.\n * - **Height and shape.** The height is --popup-action-height (32px by default, ADR-0060 decision 6),\n * for mouse and finger alike. With a mouse the buttons are pills, because the container is a\n * rounded card and controls follow the surface that holds them; with a finger the row becomes a\n * full-width square action bar. Plain\n * `<button>`s get the same height as Material buttons, so one row never mixes two heights.\n * - **Destructive colour.** `destructive` on a slotted button paints it with the error colour. Cancel\n * is never destructive, whatever attribute it carries.\n *\n * ```html\n * <ox-popup-actions>\n * <md-text-button slot=\"start\" destructive @click=${remove}>delete</md-text-button>\n * <md-text-button slot=\"cancel\" @click=${() => closePopup(this)}>cancel</md-text-button>\n * <md-filled-button slot=\"confirm\" @click=${save}>save</md-filled-button>\n * </ox-popup-actions>\n * ```\n *\n * A screen that must be bigger (a shop-floor terminal used with gloves) raises the height, not the\n * markup: `--popup-action-height: 68px`, for mouse and finger alike. Shop-floor popups must declare it\n * (e.g. `var(--ui-tap-glove)`): the default is sized for office screens.\n */\n@customElement('ox-popup-actions')\nexport class OxPopupActions extends LitElement {\n static styles = css`\n :host {\n display: flex;\n align-items: center;\n gap: var(--spacing-small, 4px);\n padding-top: var(--spacing-medium, 8px);\n border-top: 1px solid var(--md-sys-color-outline-variant);\n\n --_height: ${actionHeight('--popup-action-height')};\n --_shape: var(--popup-control-radius, 999em);\n\n --md-text-button-container-height: var(--_height);\n --md-filled-button-container-height: var(--_height);\n --md-outlined-button-container-height: var(--_height);\n --md-text-button-container-shape: var(--_shape);\n --md-filled-button-container-shape: var(--_shape);\n --md-outlined-button-container-shape: var(--_shape);\n }\n\n [spacer] {\n flex: 1;\n }\n\n ::slotted(button) {\n box-sizing: border-box;\n min-height: var(--_height);\n padding: 0 var(--spacing-large, 16px);\n border-radius: var(--_shape);\n font: inherit;\n }\n\n /* Destructive: the error colour, on the filled container or on the label. Never on cancel. */\n ::slotted(md-filled-button[destructive]:not([slot='cancel'])) {\n --md-filled-button-container-color: var(--md-sys-color-error);\n --md-filled-button-label-text-color: var(--md-sys-color-on-error);\n --md-filled-button-hover-label-text-color: var(--md-sys-color-on-error);\n --md-filled-button-focus-label-text-color: var(--md-sys-color-on-error);\n --md-filled-button-pressed-label-text-color: var(--md-sys-color-on-error);\n }\n\n ::slotted(md-text-button[destructive]:not([slot='cancel'])),\n ::slotted(md-outlined-button[destructive]:not([slot='cancel'])) {\n --md-text-button-label-text-color: var(--md-sys-color-error);\n --md-text-button-hover-label-text-color: var(--md-sys-color-error);\n --md-text-button-focus-label-text-color: var(--md-sys-color-error);\n --md-text-button-pressed-label-text-color: var(--md-sys-color-error);\n --md-outlined-button-label-text-color: var(--md-sys-color-error);\n --md-outlined-button-hover-label-text-color: var(--md-sys-color-error);\n --md-outlined-button-focus-label-text-color: var(--md-sys-color-error);\n --md-outlined-button-pressed-label-text-color: var(--md-sys-color-error);\n }\n\n ::slotted(button[destructive]:not([slot='cancel'])) {\n color: var(--md-sys-color-error);\n }\n\n /*\n * Fingers: a full-width, square action bar. The line is still the card's bottom edge, so it takes\n * the card's shape - square - and every button shares the width. 36 is a floor, not a ceiling:\n * a terminal that declared 68 keeps 68.\n */\n @media (pointer: coarse) {\n :host {\n gap: 0;\n padding-top: 0;\n\n --_shape: 0;\n }\n\n [spacer] {\n display: none;\n }\n\n ::slotted(*) {\n flex: 1;\n }\n }\n `\n\n render() {\n return html`\n <slot name=\"start\"></slot>\n <div spacer></div>\n <slot></slot>\n <slot name=\"cancel\"></slot>\n <slot name=\"confirm\"></slot>\n `\n }\n}\n"]}
|
package/dist/src/ox-prompt.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import '@material/web/button/filled-button.js';
|
|
2
|
-
import '@material/web/button/
|
|
2
|
+
import '@material/web/button/text-button.js';
|
|
3
|
+
import './ox-popup-actions.js';
|
|
3
4
|
import '@material/web/icon/icon.js';
|
|
4
5
|
import { LitElement } from 'lit';
|
|
5
6
|
/**
|
|
@@ -37,6 +38,7 @@ export declare class OxPrompt extends LitElement {
|
|
|
37
38
|
confirmButton?: {
|
|
38
39
|
text: string;
|
|
39
40
|
color?: string;
|
|
41
|
+
destructive?: boolean;
|
|
40
42
|
};
|
|
41
43
|
/**
|
|
42
44
|
* Specifies settings for the cancel button.
|
|
@@ -58,6 +60,7 @@ export declare class OxPrompt extends LitElement {
|
|
|
58
60
|
_parent?: Element;
|
|
59
61
|
private resolveFn;
|
|
60
62
|
render(): import("lit-html").TemplateResult<1>;
|
|
63
|
+
private renderButtons;
|
|
61
64
|
resolve(result: boolean): void;
|
|
62
65
|
/**
|
|
63
66
|
* Function called when the confirm button is clicked.
|
|
@@ -89,10 +92,12 @@ export declare class OxPrompt extends LitElement {
|
|
|
89
92
|
* @param {string} [options.footer] - Additional information to be displayed at the bottom of the popup.
|
|
90
93
|
* @param {object} [options.confirmButton] - Configuration for the confirmation button in the popup.
|
|
91
94
|
* @param {string} options.confirmButton.text - The text to be displayed on the confirmation button.
|
|
92
|
-
* @param {string} [options.confirmButton.color] - The
|
|
95
|
+
* @param {string} [options.confirmButton.color] - Not applied. The action row owns button colours.
|
|
96
|
+
* @param {boolean} [options.confirmButton.destructive] - The confirmation cannot be undone (delete, discard): the
|
|
97
|
+
* button takes the error colour and cancel gets the first focus.
|
|
93
98
|
* @param {object} [options.cancelButton] - Configuration for the cancel button in the popup.
|
|
94
99
|
* @param {string} options.cancelButton.text - The text to be displayed on the cancel button.
|
|
95
|
-
* @param {string} [options.cancelButton.color] -
|
|
100
|
+
* @param {string} [options.cancelButton.color] - Not applied. Cancel is never coloured.
|
|
96
101
|
* @param {number} [options.top] - The top position of the popup (in pixels).
|
|
97
102
|
* @param {number} [options.left] - The left position of the popup (in pixels).
|
|
98
103
|
* @param {number} [options.right] - The right position of the popup (in pixels).
|
|
@@ -114,6 +119,7 @@ export declare class OxPrompt extends LitElement {
|
|
|
114
119
|
confirmButton?: {
|
|
115
120
|
text: string;
|
|
116
121
|
color?: string;
|
|
122
|
+
destructive?: boolean;
|
|
117
123
|
};
|
|
118
124
|
cancelButton?: {
|
|
119
125
|
text: string;
|
|
@@ -131,6 +137,22 @@ export declare class OxPrompt extends LitElement {
|
|
|
131
137
|
value: boolean;
|
|
132
138
|
}) => void;
|
|
133
139
|
}): Promise<boolean>;
|
|
140
|
+
/**
|
|
141
|
+
* Asks before deleting — the modal replacement for `confirm('sure to delete?')`.
|
|
142
|
+
*
|
|
143
|
+
* Framework screens asked with the browser's own dialog (17 places, ADR-0060 decision 9): it
|
|
144
|
+
* blocks the page, cannot be styled or translated, and put "OK" where every other popup puts
|
|
145
|
+
* "cancel". This is the same question in the shared popup: a warning, "delete" painted as
|
|
146
|
+
* destructive on the right, "cancel" before it and focused.
|
|
147
|
+
*
|
|
148
|
+
* if (!(await OxPrompt.confirmDelete({ count: selected.length }))) return
|
|
149
|
+
*
|
|
150
|
+
* @returns {Promise<boolean>} true when the user chose delete.
|
|
151
|
+
*/
|
|
152
|
+
static confirmDelete({ count, parent }?: {
|
|
153
|
+
count?: number;
|
|
154
|
+
parent?: Element | null;
|
|
155
|
+
}): Promise<boolean>;
|
|
134
156
|
/**
|
|
135
157
|
* Static method to open an input popup — a modal replacement for the native `window.prompt()`.
|
|
136
158
|
*
|
package/dist/src/ox-prompt.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
var OxPrompt_1;
|
|
2
2
|
import { __decorate } from "tslib";
|
|
3
3
|
import '@material/web/button/filled-button.js';
|
|
4
|
-
import '@material/web/button/
|
|
4
|
+
import '@material/web/button/text-button.js';
|
|
5
|
+
import './ox-popup-actions.js';
|
|
5
6
|
import '@material/web/icon/icon.js';
|
|
6
7
|
import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles.js';
|
|
7
8
|
import { css, html, nothing, LitElement } from 'lit';
|
|
8
9
|
import { render } from 'lit-html';
|
|
9
10
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
11
|
+
import { i18next } from '@operato/i18n';
|
|
10
12
|
import { ScrollbarStyles } from '@operato/styles';
|
|
11
13
|
const TYPES_ICON = {
|
|
12
14
|
success: 'verified',
|
|
@@ -156,33 +158,25 @@ let OxPrompt = class OxPrompt extends LitElement {
|
|
|
156
158
|
color: var(--status-success-color, #35a24a);
|
|
157
159
|
}
|
|
158
160
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
161
|
+
/*
|
|
162
|
+
* The command row is the shared popup action row: confirm on the right, cancel just before it,
|
|
163
|
+
* pills of --popup-action-height with a mouse, a square full-width bar with a finger. Its own margins keep the row
|
|
164
|
+
* inside the card's padding with a mouse.
|
|
165
|
+
*/
|
|
166
|
+
ox-popup-actions {
|
|
167
|
+
margin: 0 var(--ox-prompt-buttons-padding, var(--spacing-medium)) var(--ox-prompt-buttons-padding, var(--spacing-medium));
|
|
166
168
|
}
|
|
167
169
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
--md-filled-button-container-shape: var(--md-sys-shape-corner-small);
|
|
174
|
-
--md-filled-button-leading-space: var(--spacing-large);
|
|
175
|
-
--md-filled-button-trailing-space: var(--spacing-large);
|
|
176
|
-
}
|
|
170
|
+
@media (pointer: coarse) {
|
|
171
|
+
/* The bar is the card's bottom edge: it reaches both sides, and the card clips its corners. */
|
|
172
|
+
:host {
|
|
173
|
+
overflow: hidden;
|
|
174
|
+
}
|
|
177
175
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
--md-outlined-button-container-height: var(--form-element-height-medium);
|
|
183
|
-
--md-outlined-button-container-shape: var(--md-sys-shape-corner-small);
|
|
184
|
-
--md-outlined-button-leading-space: var(--spacing-large);
|
|
185
|
-
--md-outlined-button-trailing-space: var(--spacing-large);
|
|
176
|
+
ox-popup-actions {
|
|
177
|
+
margin: var(--spacing-medium) calc(-1 * var(--ox-prompt-container-padding, var(--spacing-medium)))
|
|
178
|
+
calc(-1 * var(--ox-prompt-container-padding, var(--spacing-medium)));
|
|
179
|
+
}
|
|
186
180
|
}
|
|
187
181
|
`
|
|
188
182
|
]; }
|
|
@@ -197,23 +191,36 @@ let OxPrompt = class OxPrompt extends LitElement {
|
|
|
197
191
|
<slot> </slot>
|
|
198
192
|
${this.footer ? html ` <div footer class="md-typescale-body-large">${this.footer}</div> ` : nothing}
|
|
199
193
|
</div>
|
|
200
|
-
<
|
|
201
|
-
${this.
|
|
194
|
+
<ox-popup-actions>
|
|
195
|
+
${this.renderButtons()}
|
|
196
|
+
</ox-popup-actions>
|
|
197
|
+
`;
|
|
198
|
+
}
|
|
199
|
+
/*
|
|
200
|
+
* Markup order only decides which button gets the first focus; the row decides where they stand.
|
|
201
|
+
* A destructive confirmation focuses cancel, so a reflexive Enter does not delete anything.
|
|
202
|
+
*/
|
|
203
|
+
renderButtons() {
|
|
204
|
+
const confirm = this.confirmButton
|
|
202
205
|
? html `
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
206
|
+
<md-filled-button
|
|
207
|
+
id="confirm"
|
|
208
|
+
slot="confirm"
|
|
209
|
+
type="button"
|
|
210
|
+
?destructive=${!!this.confirmButton.destructive}
|
|
211
|
+
@click=${() => this.onConfirm()}
|
|
212
|
+
>${this.confirmButton.text}</md-filled-button
|
|
213
|
+
>
|
|
214
|
+
`
|
|
215
|
+
: nothing;
|
|
216
|
+
const cancel = this.cancelButton
|
|
209
217
|
? html `
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
: nothing
|
|
215
|
-
|
|
216
|
-
`;
|
|
218
|
+
<md-text-button id="cancel" slot="cancel" type="button" @click=${() => this.onCancel()}
|
|
219
|
+
>${this.cancelButton.text}</md-text-button
|
|
220
|
+
>
|
|
221
|
+
`
|
|
222
|
+
: nothing;
|
|
223
|
+
return this.confirmButton?.destructive ? html `${cancel}${confirm}` : html `${confirm}${cancel}`;
|
|
217
224
|
}
|
|
218
225
|
resolve(result) {
|
|
219
226
|
if (this.resolveFn) {
|
|
@@ -260,10 +267,12 @@ let OxPrompt = class OxPrompt extends LitElement {
|
|
|
260
267
|
* @param {string} [options.footer] - Additional information to be displayed at the bottom of the popup.
|
|
261
268
|
* @param {object} [options.confirmButton] - Configuration for the confirmation button in the popup.
|
|
262
269
|
* @param {string} options.confirmButton.text - The text to be displayed on the confirmation button.
|
|
263
|
-
* @param {string} [options.confirmButton.color] - The
|
|
270
|
+
* @param {string} [options.confirmButton.color] - Not applied. The action row owns button colours.
|
|
271
|
+
* @param {boolean} [options.confirmButton.destructive] - The confirmation cannot be undone (delete, discard): the
|
|
272
|
+
* button takes the error colour and cancel gets the first focus.
|
|
264
273
|
* @param {object} [options.cancelButton] - Configuration for the cancel button in the popup.
|
|
265
274
|
* @param {string} options.cancelButton.text - The text to be displayed on the cancel button.
|
|
266
|
-
* @param {string} [options.cancelButton.color] -
|
|
275
|
+
* @param {string} [options.cancelButton.color] - Not applied. Cancel is never coloured.
|
|
267
276
|
* @param {number} [options.top] - The top position of the popup (in pixels).
|
|
268
277
|
* @param {number} [options.left] - The left position of the popup (in pixels).
|
|
269
278
|
* @param {number} [options.right] - The right position of the popup (in pixels).
|
|
@@ -295,6 +304,29 @@ let OxPrompt = class OxPrompt extends LitElement {
|
|
|
295
304
|
}
|
|
296
305
|
return result;
|
|
297
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Asks before deleting — the modal replacement for `confirm('sure to delete?')`.
|
|
309
|
+
*
|
|
310
|
+
* Framework screens asked with the browser's own dialog (17 places, ADR-0060 decision 9): it
|
|
311
|
+
* blocks the page, cannot be styled or translated, and put "OK" where every other popup puts
|
|
312
|
+
* "cancel". This is the same question in the shared popup: a warning, "delete" painted as
|
|
313
|
+
* destructive on the right, "cancel" before it and focused.
|
|
314
|
+
*
|
|
315
|
+
* if (!(await OxPrompt.confirmDelete({ count: selected.length }))) return
|
|
316
|
+
*
|
|
317
|
+
* @returns {Promise<boolean>} true when the user chose delete.
|
|
318
|
+
*/
|
|
319
|
+
static async confirmDelete({ count, parent } = {}) {
|
|
320
|
+
return OxPrompt_1.open({
|
|
321
|
+
type: 'warning',
|
|
322
|
+
title: count && count > 1
|
|
323
|
+
? i18next.t('text.popup-confirm-delete-count', { count, defaultValue: 'delete the {count} selected items?' })
|
|
324
|
+
: i18next.t('text.popup-confirm-delete', { defaultValue: 'delete the selected item?' }),
|
|
325
|
+
confirmButton: { text: i18next.t('button.popup-delete', { defaultValue: 'delete' }), destructive: true },
|
|
326
|
+
cancelButton: { text: i18next.t('button.popup-cancel', { defaultValue: 'cancel' }) },
|
|
327
|
+
parent
|
|
328
|
+
});
|
|
329
|
+
}
|
|
298
330
|
/**
|
|
299
331
|
* Static method to open an input popup — a modal replacement for the native `window.prompt()`.
|
|
300
332
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-prompt.js","sourceRoot":"","sources":["../../src/ox-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/button/filled-button.js'\nimport '@material/web/button/outlined-button.js'\nimport '@material/web/icon/icon.js'\nimport { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles.js'\n\nimport { css, html, nothing, LitElement } from 'lit'\nimport { render } from 'lit-html'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { ScrollbarStyles } from '@operato/styles'\n\nconst TYPES_ICON = {\n success: 'verified',\n error: 'error',\n warning: 'warning',\n info: 'info',\n question: 'question_mark'\n}\n\n/**\n * The `ox-prompt` custom element represents a modal popup that provides information or options for the user, such as confirmation or cancellation.\n */\n@customElement('ox-prompt')\nexport class OxPrompt extends LitElement {\n static styles = [\n MDTypeScaleStyles,\n ScrollbarStyles,\n css`\n :host {\n position: absolute;\n display: flex;\n flex-direction: column;\n gap: var(--ox-prompt-gap, var(--spacing-medium));\n background-color: var(--ox-popup-list-background-color, var(--md-sys-color-surface));\n z-index: 1000;\n padding: var(--ox-prompt-container-padding, var(--spacing-medium));\n box-shadow: var(--ox-prompt-container-box-shadow, 2px 3px 10px 5px rgba(0, 0, 0, 0.15));\n border-radius: var(--ox-prompt-container-border-radius, var(--md-sys-shape-corner-medium));\n box-sizing: border-box;\n min-width: 300;\n line-height: initial;\n text-align: initial;\n }\n\n :host([active]) {\n display: block;\n }\n\n :host(*:focus) {\n outline: none;\n }\n\n [titler] {\n padding: var(--ox-prompt-title-padding, var(--spacing-medium));\n padding-bottom: 0;\n color: var(--ox-prompt-title-color, var(--md-sys-color-primary));\n font-size: var(--md-sys-typescale-title-large-size, 1.375rem);\n font-weight: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500));\n text-align: var(--ox-prompt-title-text-align, 'left');\n }\n\n [content] {\n display: flex;\n flex-direction: column;\n gap: var(--ox-prompt-content-gap, var(--spacing-medium));\n padding: var(--ox-prompt-content-padding, var(--spacing-medium));\n color: var(--ox-prompt-body-color, var(--md-sys-color-on-surface));\n word-break: keep-all;\n white-space: pre-line;\n text-align: var(--ox-prompt-content-text-align, 'left');\n\n md-icon {\n align-self: center;\n --md-icon-size: var(--icon-size-huge);\n color: var(--ox-prompt-body-color-variant, var(--md-sys-color-primary));\n }\n }\n\n [content].warning md-icon {\n color: var(--status-warning-color, #ee8d03);\n }\n\n [content].error md-icon {\n color: var(--md-sys-color-error, var(--md-sys-color-error));\n }\n\n [content].info md-icon {\n color: var(--status-info-color, #398ace);\n }\n\n [content].success md-icon {\n color: var(--status-success-color, #35a24a);\n }\n\n [buttons] {\n display: flex;\n border-top: 1px solid var(--md-sys-color-surface-variant);\n gap: var(--ox-prompt-buttons-spacing, var(--spacing-large));\n padding: var(--ox-prompt-buttons-padding, var(--spacing-medium));\n padding-top: var(--spacing-large);\n justify-content: center;\n }\n\n #confirm {\n --md-filled-button-container-color: var(--md-sys-color-primary);\n --md-filled-button-label-text-color: var(--md-sys-color-on-primary);\n --md-filled-button-label-text-size: var(--md-sys-typescale-label-large-size, 0.875rem);\n --md-filled-button-container-height: var(--form-element-height-medium);\n --md-filled-button-container-shape: var(--md-sys-shape-corner-small);\n --md-filled-button-leading-space: var(--spacing-large);\n --md-filled-button-trailing-space: var(--spacing-large);\n }\n\n #cancel {\n --md-outlined-button-container-color: var(--md-sys-color-surface-variant);\n --md-outlined-button-label-text-color: var(--md-sys-color-on-surface-variant);\n --md-outlined-button-label-text-size: var(--md-sys-typescale-label-large-size, 0.875rem);\n --md-outlined-button-container-height: var(--form-element-height-medium);\n --md-outlined-button-container-shape: var(--md-sys-shape-corner-small);\n --md-outlined-button-leading-space: var(--spacing-large);\n --md-outlined-button-trailing-space: var(--spacing-large);\n }\n `\n ]\n\n /**\n * Specifies the type of the popup. Possible values are 'success', 'error', 'warning', 'info', 'question'.\n */\n @property({ type: String }) type?: 'success' | 'error' | 'warning' | 'info' | 'question'\n\n /**\n * Specifies the icon of the popup.\n */\n @property({ type: String }) icon?: string\n\n /**\n * Specifies the title of the popup.\n */\n @property({ type: String }) titler?: string = ''\n\n /**\n * Specifies the text content of the popup.\n */\n @property({ type: String }) text?: string\n\n /**\n * Specifies the footer (additional information at the bottom) of the popup.\n */\n @property({ type: String }) footer?: string\n\n /**\n * Determines whether the popup is displayed as a toast.\n */\n @property({ type: Boolean }) toast?: boolean\n\n /**\n * Specifies settings for the confirmation button.\n */\n @property({ type: Object }) confirmButton?: { text: string; color?: string }\n\n /**\n * Specifies settings for the cancel button.\n */\n @property({ type: Object }) cancelButton?: { text: string; color?: string }\n\n /**\n * Prevents the popup from closing when it loses focus (blur event).\n */\n @property({ type: Boolean, attribute: 'prevent-close-on-blur' }) preventCloseOnBlur: boolean = false\n\n /**\n * A callback function called when the popup is closed, providing the result of the user's interaction.\n */\n @property({ type: Object }) callback?: (result: { value: boolean }) => void\n\n @state() _parent?: Element\n\n private resolveFn: ((value: boolean) => void) | null = null\n\n render() {\n return html`\n ${this.titler ? html` <div titler class=\"md-typescale-title-large\">${this.titler}</div> ` : nothing}\n <div content class=\"${this.type || 'info'} md-typescale-body-large\">\n ${this.icon || this.type\n ? html` <md-icon icon>${this.icon || TYPES_ICON[this.type || 'info']}</md-icon> `\n : nothing}\n ${this.text ? html` <div text>${this.text}</div> ` : nothing}\n <slot> </slot>\n ${this.footer ? html` <div footer class=\"md-typescale-body-large\">${this.footer}</div> ` : nothing}\n </div>\n <div buttons>\n ${this.confirmButton\n ? html`\n <md-filled-button id=\"confirm\" type=\"button\" @click=${(e: Event) => this.onConfirm()}\n >${this.confirmButton?.text}</md-filled-button\n >\n `\n : nothing}\n ${this.cancelButton\n ? html`\n <md-outlined-button id=\"cancel\" type=\"button\" @click=${(e: Event) => this.onCancel()}\n >${this.cancelButton?.text}</md-outlined-button\n >\n `\n : nothing}\n </div>\n `\n }\n\n resolve(result: boolean) {\n if (this.resolveFn) {\n this.resolveFn(result)\n this.resolveFn = null\n }\n }\n\n /**\n * Function called when the confirm button is clicked.\n */\n onConfirm() {\n this.resolve(true)\n this.close()\n }\n\n /**\n * Function called when the cancel button is clicked.\n */\n onCancel() {\n this.resolve(false)\n this.close()\n }\n\n protected _onfocusout: (e: FocusEvent) => void = function (this: OxPrompt, e: FocusEvent) {\n const to = e.relatedTarget as HTMLElement\n\n if (!this.contains(to)) {\n /* 분명히 내 범위가 아닌 엘리먼트로 포커스가 옮겨졌다면, ox-prompt은 닫혀야 한다. */\n // @ts-ignore for debug\n if (this.preventCloseOnBlur || window.POPUP_DEBUG) {\n return\n }\n\n this.resolve(false)\n this.close()\n }\n }.bind(this)\n\n protected _onkeydown: (e: KeyboardEvent) => void = function (this: OxPrompt, e: KeyboardEvent) {\n e.stopPropagation()\n\n switch (e.key) {\n case 'Esc': // for IE/Edge\n case 'Escape':\n this.resolve(false)\n this.close()\n break\n }\n }.bind(this)\n\n protected _onkeyup: (e: KeyboardEvent) => void = function (this: OxPrompt, e: KeyboardEvent) {\n e.stopPropagation()\n }.bind(this)\n\n protected _onmouseup: (e: MouseEvent) => void = function (this: OxPrompt, e: MouseEvent) {\n e.stopPropagation()\n }.bind(this)\n\n protected _onmousedown: (e: MouseEvent) => void = function (this: OxPrompt, e: MouseEvent) {\n e.stopPropagation()\n }.bind(this)\n\n protected _oncontextmenu: (e: Event) => void = function (this: OxPrompt, e: Event) {\n e.stopPropagation()\n }.bind(this)\n\n protected _onclick: (e: MouseEvent) => void = function (this: OxPrompt, e: MouseEvent) {\n e.stopPropagation()\n }.bind(this)\n\n protected _onclose: (e: Event) => void = function (this: OxPrompt, e: Event) {\n this.resolve(false)\n this.close()\n }.bind(this)\n\n protected _oncollapse: (e: Event) => void = function (this: OxPrompt, e: Event) {\n e.stopPropagation()\n\n this.resolve(false)\n this.close()\n }.bind(this)\n\n protected _onwindowblur: (e: Event) => void = function (this: OxPrompt, e: Event) {\n // @ts-ignore for debug\n if (this.preventCloseOnBlur || window.POPUP_DEBUG) {\n return\n }\n\n this.resolve(false)\n this.close()\n }.bind(this)\n\n connectedCallback() {\n super.connectedCallback()\n\n this.addEventListener('focusout', this._onfocusout)\n this.addEventListener('keydown', this._onkeydown)\n this.addEventListener('keyup', this._onkeyup)\n this.addEventListener('click', this._onclick)\n this.addEventListener('mouseup', this._onmouseup)\n this.addEventListener('mousedown', this._onmousedown)\n this.addEventListener('contextmenu', this._oncontextmenu)\n this.addEventListener('ox-close', this._onclose)\n this.addEventListener('ox-collapse', this._oncollapse)\n\n this.setAttribute('tabindex', '0') // make this element focusable\n this.guaranteeFocus()\n }\n\n /**\n * Static method to open the `ox-prompt` popup.\n * @param {object} options - An object containing popup options.\n * @param {unknown} [options.template] - An optional content template to render inside the popup.\n * @param {'success' | 'error' | 'warning' | 'info' | 'question'} [options.type] - The type of the popup, which can be one of: 'success', 'error', 'warning', 'info', 'question'.\n * @param {string} [options.icon] - The icon to be displayed in the popup header.\n * @param {string} [options.title] - The title to be displayed in the popup header.\n * @param {string} [options.text] - The main text content of the popup.\n * @param {string} [options.footer] - Additional information to be displayed at the bottom of the popup.\n * @param {object} [options.confirmButton] - Configuration for the confirmation button in the popup.\n * @param {string} options.confirmButton.text - The text to be displayed on the confirmation button.\n * @param {string} [options.confirmButton.color] - The color of the confirmation button (CSS color).\n * @param {object} [options.cancelButton] - Configuration for the cancel button in the popup.\n * @param {string} options.cancelButton.text - The text to be displayed on the cancel button.\n * @param {string} [options.cancelButton.color] - The color of the cancel button (CSS color).\n * @param {number} [options.top] - The top position of the popup (in pixels).\n * @param {number} [options.left] - The left position of the popup (in pixels).\n * @param {number} [options.right] - The right position of the popup (in pixels).\n * @param {number} [options.bottom] - The bottom position of the popup (in pixels).\n * @param {string} [options.width] - The maximum width of the popup (CSS string).\n * @param {string} [options.height] - The maximum height of the popup (CSS string).\n * @param {Element | null} [options.parent] - The parent element to which the popup should be attached. If not provided, it will be attached to the document body.\n * @param {boolean} [options.preventCloseOnBlur] - Prevents the popup from closing when it loses focus (blur event).\n * @param {(result: { value: boolean }) => void} [options.callback] - A callback function that will be invoked when the user interacts with the popup, providing the result of the interaction.\n * @returns {Promise<boolean>} A Promise that resolves based on user interaction with the popup.\n */\n public static async open({\n template,\n type,\n icon,\n title,\n text,\n footer,\n confirmButton,\n cancelButton,\n top,\n left,\n right,\n bottom,\n width,\n height,\n parent,\n preventCloseOnBlur,\n callback\n }: {\n template?: unknown\n type?: 'success' | 'error' | 'warning' | 'info' | 'question'\n icon?: string\n title?: string\n text?: string\n footer?: string\n confirmButton?: { text: string; color?: string }\n cancelButton?: { text: string; color?: string }\n top?: number\n left?: number\n right?: number\n bottom?: number\n width?: string\n height?: string\n parent?: Element | null\n preventCloseOnBlur?: boolean\n callback?: (result: { value: boolean }) => void\n }): Promise<boolean> {\n const owner = parent || document.body\n const target = document.createElement('ox-prompt') as OxPrompt\n\n target.type = type\n target.icon = icon\n target.text = text\n target.titler = title\n target.footer = footer\n target.confirmButton = confirmButton\n target.cancelButton = cancelButton\n target.preventCloseOnBlur = !!preventCloseOnBlur\n\n render(template, target)\n\n target._parent = owner\n owner.appendChild(target)\n\n const result = await target.open({ top, left, right, bottom, width, height })\n\n if (callback) {\n await callback.call(null, { value: result })\n }\n\n return result\n }\n\n /**\n * Static method to open an input popup — a modal replacement for the native `window.prompt()`.\n *\n * Benchmarks `prompt(message, defaultValue)`: shows a text field and resolves with the entered\n * string on confirm, or `null` on cancel/escape/blur. Single-line inputs also confirm on Enter.\n *\n * This is purely additive and does not change the behavior of `OxPrompt.open()`.\n *\n * @returns {Promise<string | null>} The entered text on confirm, or null on cancel.\n */\n public static async prompt({\n title,\n text,\n defaultValue = '',\n placeholder = '',\n type = 'question',\n icon,\n multiline = false,\n confirmButton,\n cancelButton,\n preventCloseOnBlur = true,\n top,\n left,\n right,\n bottom,\n width,\n height,\n parent\n }: {\n title?: string\n text?: string\n defaultValue?: string\n placeholder?: string\n type?: 'success' | 'error' | 'warning' | 'info' | 'question'\n icon?: string\n multiline?: boolean\n confirmButton?: { text: string; color?: string }\n cancelButton?: { text: string; color?: string }\n preventCloseOnBlur?: boolean\n top?: number\n left?: number\n right?: number\n bottom?: number\n width?: string\n height?: string\n parent?: Element | null\n }): Promise<string | null> {\n const holder = { value: defaultValue }\n\n const onInput = (e: Event) => {\n holder.value = (e.target as HTMLInputElement | HTMLTextAreaElement).value\n }\n const onKeydown = (e: KeyboardEvent) => {\n // 단일 라인: Enter 로 확정(native prompt 벤치마킹). multiline 은 개행 유지.\n if (!multiline && e.key === 'Enter') {\n e.preventDefault()\n const host = (e.target as HTMLElement).closest('ox-prompt') as OxPrompt | null\n host?.onConfirm()\n }\n }\n\n // 폭은 컨테이너를 최대로 채우고(min-width 로 최소 크기 보장), textarea 는 세로로만 리사이즈.\n const inputStyle =\n 'width: 100%; min-width: var(--ox-prompt-input-min-width, 320px); box-sizing: border-box; padding: 8px; font: inherit;'\n\n const template = multiline\n ? html`\n <textarea\n rows=\"3\"\n placeholder=${placeholder}\n .value=${defaultValue}\n style=\"${inputStyle} resize: vertical;\"\n @input=${onInput}\n @keydown=${onKeydown}\n ></textarea>\n `\n : html`\n <input\n type=\"text\"\n placeholder=${placeholder}\n .value=${defaultValue}\n style=\"${inputStyle} resize: none;\"\n @input=${onInput}\n @keydown=${onKeydown}\n />\n `\n\n const confirmed = await OxPrompt.open({\n template,\n type,\n icon,\n title,\n text,\n confirmButton: confirmButton || { text: 'OK' },\n cancelButton: cancelButton || { text: 'Cancel' },\n preventCloseOnBlur,\n top,\n left,\n right,\n bottom,\n width,\n height,\n parent\n })\n\n return confirmed ? holder.value : null\n }\n\n /**\n * Opens the popup with specified position and dimensions.\n * @param {object} options - An object specifying the position and dimensions of the popup.\n * @param {number} [options.left] - The left position of the popup (in pixels). If not provided, the popup will be horizontally centered.\n * @param {number} [options.top] - The top position of the popup (in pixels). If not provided, the popup will be vertically centered.\n * @param {number} [options.right] - The right position of the popup (in pixels). Overrides 'left' if both 'left' and 'right' are provided.\n * @param {number} [options.bottom] - The bottom position of the popup (in pixels). Overrides 'top' if both 'top' and 'bottom' are provided.\n * @param {string} [options.width] - The maximum width of the popup (CSS string). If not provided, no width restriction is applied.\n * @param {string} [options.height] - The maximum height of the popup (CSS string). If not provided, no height restriction is applied.\n * @param {boolean} [options.silent=false] - Determines whether to focus the popup automatically (true) or not (false).\n * @returns {Promise<boolean>} A Promise that resolves based on user interaction with the popup.\n */\n open({\n left,\n top,\n right,\n bottom,\n width,\n height,\n silent = false\n }: {\n left?: number\n top?: number\n right?: number\n bottom?: number\n width?: string\n height?: string\n silent?: boolean\n }): Promise<boolean> {\n if (width) {\n this.style.maxWidth = width\n this.style.overflowX = 'auto'\n }\n\n if (height) {\n this.style.maxHeight = height\n this.style.overflowY = 'auto'\n }\n\n if (left === undefined && top === undefined && right === undefined && bottom === undefined) {\n this.style.left = '50%'\n this.style.top = '50%'\n this.style.transform = 'translateX(-50%) translateY(-50%)'\n } else {\n if (left !== undefined) this.style.left = `${left}px`\n if (top !== undefined) this.style.top = `${top}px`\n if (right !== undefined) this.style.right = `${right}px`\n if (bottom !== undefined) this.style.bottom = `${bottom}px`\n }\n\n this.setAttribute('active', '')\n\n // adjust popup position\n requestAnimationFrame(() => {\n const vh = document.body.clientHeight\n const vw = document.body.clientWidth\n\n var bounding = this.getBoundingClientRect()\n\n var h = bounding.height\n var w = bounding.width\n var t = bounding.top\n var l = bounding.left\n\n // If the popup is too large, it will cause overflow scrolling.\n if (vh < h) {\n this.style.height = `${Math.min(Math.max(Math.floor((vh * 2) / 3), vh - (t + 20)), vh)}px`\n this.style.overflow = 'auto'\n h = vh\n }\n\n if (vw < w) {\n this.style.width = `${Math.min(Math.max(Math.floor((vw * 2) / 3), vw - (l + 20)), vw)}px`\n this.style.overflow = 'auto'\n w = vw\n }\n\n // To prevent pop-ups from crossing screen boundaries, use the\n const computedStyle = getComputedStyle(this)\n\n if (t < 0) {\n this.style.top = `calc(${computedStyle.top} + ${t}px)`\n this.style.bottom = ''\n } else if (vh <= t + h) {\n this.style.top = `calc(${computedStyle.top} - ${t + h - vh}px)`\n this.style.bottom = ''\n }\n\n if (l < 0) {\n this.style.left = `calc(${computedStyle.left} + ${l}px)`\n this.style.right = ''\n } else if (vw < l + w) {\n this.style.left = `calc(${computedStyle.left} - ${l + w - vw}px)`\n this.style.right = ''\n }\n })\n\n requestAnimationFrame(() => {\n // auto focusing\n !silent && this.guaranteeFocus()\n })\n\n /* When the window is out of focus, all pop-ups should disappear. */\n window.addEventListener('blur', this._onwindowblur)\n\n return new Promise(resolve => {\n this.resolveFn = resolve\n })\n }\n\n guaranteeFocus(target?: HTMLElement) {\n const focusible = (target || this.renderRoot)?.querySelector(\n ':host > button, :host > [href], :host > input, :host > select, :host > textarea, :host > [tabindex]:not([tabindex=\"-1\"]), :host [type=\"button\"]'\n )\n\n if (focusible) {\n ;(focusible as HTMLElement).focus()\n } else {\n this.focus()\n }\n }\n\n /**\n * Closes the popup.\n */\n close() {\n this.removeAttribute('active')\n\n window.removeEventListener('blur', this._onwindowblur)\n\n if (this._parent) {\n /* this case is when the popup is opened by OxPrompt.open(...) */\n this.removeEventListener('focusout', this._onfocusout)\n this.removeEventListener('keydown', this._onkeydown)\n this.removeEventListener('keyup', this._onkeyup)\n this.removeEventListener('click', this._onclick)\n this.removeEventListener('ox-close', this._onclose)\n this.removeEventListener('ox-collapse', this._oncollapse)\n this.removeEventListener('mouseup', this._onmouseup)\n this.removeEventListener('mousedown', this._onmousedown)\n this.removeEventListener('contextmenu', this._oncontextmenu)\n\n this._parent.removeChild(this)\n delete this._parent\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ox-prompt.js","sourceRoot":"","sources":["../../src/ox-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/button/filled-button.js'\nimport '@material/web/button/text-button.js'\nimport './ox-popup-actions.js'\nimport '@material/web/icon/icon.js'\nimport { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles.js'\n\nimport { css, html, nothing, LitElement } from 'lit'\nimport { render } from 'lit-html'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { i18next } from '@operato/i18n'\nimport { ScrollbarStyles } from '@operato/styles'\n\nconst TYPES_ICON = {\n success: 'verified',\n error: 'error',\n warning: 'warning',\n info: 'info',\n question: 'question_mark'\n}\n\n/**\n * The `ox-prompt` custom element represents a modal popup that provides information or options for the user, such as confirmation or cancellation.\n */\n@customElement('ox-prompt')\nexport class OxPrompt extends LitElement {\n static styles = [\n MDTypeScaleStyles,\n ScrollbarStyles,\n css`\n :host {\n position: absolute;\n display: flex;\n flex-direction: column;\n gap: var(--ox-prompt-gap, var(--spacing-medium));\n background-color: var(--ox-popup-list-background-color, var(--md-sys-color-surface));\n z-index: 1000;\n padding: var(--ox-prompt-container-padding, var(--spacing-medium));\n box-shadow: var(--ox-prompt-container-box-shadow, 2px 3px 10px 5px rgba(0, 0, 0, 0.15));\n border-radius: var(--ox-prompt-container-border-radius, var(--md-sys-shape-corner-medium));\n box-sizing: border-box;\n min-width: 300;\n line-height: initial;\n text-align: initial;\n }\n\n :host([active]) {\n display: block;\n }\n\n :host(*:focus) {\n outline: none;\n }\n\n [titler] {\n padding: var(--ox-prompt-title-padding, var(--spacing-medium));\n padding-bottom: 0;\n color: var(--ox-prompt-title-color, var(--md-sys-color-primary));\n font-size: var(--md-sys-typescale-title-large-size, 1.375rem);\n font-weight: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500));\n text-align: var(--ox-prompt-title-text-align, 'left');\n }\n\n [content] {\n display: flex;\n flex-direction: column;\n gap: var(--ox-prompt-content-gap, var(--spacing-medium));\n padding: var(--ox-prompt-content-padding, var(--spacing-medium));\n color: var(--ox-prompt-body-color, var(--md-sys-color-on-surface));\n word-break: keep-all;\n white-space: pre-line;\n text-align: var(--ox-prompt-content-text-align, 'left');\n\n md-icon {\n align-self: center;\n --md-icon-size: var(--icon-size-huge);\n color: var(--ox-prompt-body-color-variant, var(--md-sys-color-primary));\n }\n }\n\n [content].warning md-icon {\n color: var(--status-warning-color, #ee8d03);\n }\n\n [content].error md-icon {\n color: var(--md-sys-color-error, var(--md-sys-color-error));\n }\n\n [content].info md-icon {\n color: var(--status-info-color, #398ace);\n }\n\n [content].success md-icon {\n color: var(--status-success-color, #35a24a);\n }\n\n /*\n * The command row is the shared popup action row: confirm on the right, cancel just before it,\n * pills of --popup-action-height with a mouse, a square full-width bar with a finger. Its own margins keep the row\n * inside the card's padding with a mouse.\n */\n ox-popup-actions {\n margin: 0 var(--ox-prompt-buttons-padding, var(--spacing-medium)) var(--ox-prompt-buttons-padding, var(--spacing-medium));\n }\n\n @media (pointer: coarse) {\n /* The bar is the card's bottom edge: it reaches both sides, and the card clips its corners. */\n :host {\n overflow: hidden;\n }\n\n ox-popup-actions {\n margin: var(--spacing-medium) calc(-1 * var(--ox-prompt-container-padding, var(--spacing-medium)))\n calc(-1 * var(--ox-prompt-container-padding, var(--spacing-medium)));\n }\n }\n `\n ]\n\n /**\n * Specifies the type of the popup. Possible values are 'success', 'error', 'warning', 'info', 'question'.\n */\n @property({ type: String }) type?: 'success' | 'error' | 'warning' | 'info' | 'question'\n\n /**\n * Specifies the icon of the popup.\n */\n @property({ type: String }) icon?: string\n\n /**\n * Specifies the title of the popup.\n */\n @property({ type: String }) titler?: string = ''\n\n /**\n * Specifies the text content of the popup.\n */\n @property({ type: String }) text?: string\n\n /**\n * Specifies the footer (additional information at the bottom) of the popup.\n */\n @property({ type: String }) footer?: string\n\n /**\n * Determines whether the popup is displayed as a toast.\n */\n @property({ type: Boolean }) toast?: boolean\n\n /**\n * Specifies settings for the confirmation button.\n */\n @property({ type: Object }) confirmButton?: { text: string; color?: string; destructive?: boolean }\n\n /**\n * Specifies settings for the cancel button.\n */\n @property({ type: Object }) cancelButton?: { text: string; color?: string }\n\n /**\n * Prevents the popup from closing when it loses focus (blur event).\n */\n @property({ type: Boolean, attribute: 'prevent-close-on-blur' }) preventCloseOnBlur: boolean = false\n\n /**\n * A callback function called when the popup is closed, providing the result of the user's interaction.\n */\n @property({ type: Object }) callback?: (result: { value: boolean }) => void\n\n @state() _parent?: Element\n\n private resolveFn: ((value: boolean) => void) | null = null\n\n render() {\n return html`\n ${this.titler ? html` <div titler class=\"md-typescale-title-large\">${this.titler}</div> ` : nothing}\n <div content class=\"${this.type || 'info'} md-typescale-body-large\">\n ${this.icon || this.type\n ? html` <md-icon icon>${this.icon || TYPES_ICON[this.type || 'info']}</md-icon> `\n : nothing}\n ${this.text ? html` <div text>${this.text}</div> ` : nothing}\n <slot> </slot>\n ${this.footer ? html` <div footer class=\"md-typescale-body-large\">${this.footer}</div> ` : nothing}\n </div>\n <ox-popup-actions>\n ${this.renderButtons()}\n </ox-popup-actions>\n `\n }\n\n /*\n * Markup order only decides which button gets the first focus; the row decides where they stand.\n * A destructive confirmation focuses cancel, so a reflexive Enter does not delete anything.\n */\n private renderButtons() {\n const confirm = this.confirmButton\n ? html`\n <md-filled-button\n id=\"confirm\"\n slot=\"confirm\"\n type=\"button\"\n ?destructive=${!!this.confirmButton.destructive}\n @click=${() => this.onConfirm()}\n >${this.confirmButton.text}</md-filled-button\n >\n `\n : nothing\n const cancel = this.cancelButton\n ? html`\n <md-text-button id=\"cancel\" slot=\"cancel\" type=\"button\" @click=${() => this.onCancel()}\n >${this.cancelButton.text}</md-text-button\n >\n `\n : nothing\n\n return this.confirmButton?.destructive ? html`${cancel}${confirm}` : html`${confirm}${cancel}`\n }\n\n resolve(result: boolean) {\n if (this.resolveFn) {\n this.resolveFn(result)\n this.resolveFn = null\n }\n }\n\n /**\n * Function called when the confirm button is clicked.\n */\n onConfirm() {\n this.resolve(true)\n this.close()\n }\n\n /**\n * Function called when the cancel button is clicked.\n */\n onCancel() {\n this.resolve(false)\n this.close()\n }\n\n protected _onfocusout: (e: FocusEvent) => void = function (this: OxPrompt, e: FocusEvent) {\n const to = e.relatedTarget as HTMLElement\n\n if (!this.contains(to)) {\n /* 분명히 내 범위가 아닌 엘리먼트로 포커스가 옮겨졌다면, ox-prompt은 닫혀야 한다. */\n // @ts-ignore for debug\n if (this.preventCloseOnBlur || window.POPUP_DEBUG) {\n return\n }\n\n this.resolve(false)\n this.close()\n }\n }.bind(this)\n\n protected _onkeydown: (e: KeyboardEvent) => void = function (this: OxPrompt, e: KeyboardEvent) {\n e.stopPropagation()\n\n switch (e.key) {\n case 'Esc': // for IE/Edge\n case 'Escape':\n this.resolve(false)\n this.close()\n break\n }\n }.bind(this)\n\n protected _onkeyup: (e: KeyboardEvent) => void = function (this: OxPrompt, e: KeyboardEvent) {\n e.stopPropagation()\n }.bind(this)\n\n protected _onmouseup: (e: MouseEvent) => void = function (this: OxPrompt, e: MouseEvent) {\n e.stopPropagation()\n }.bind(this)\n\n protected _onmousedown: (e: MouseEvent) => void = function (this: OxPrompt, e: MouseEvent) {\n e.stopPropagation()\n }.bind(this)\n\n protected _oncontextmenu: (e: Event) => void = function (this: OxPrompt, e: Event) {\n e.stopPropagation()\n }.bind(this)\n\n protected _onclick: (e: MouseEvent) => void = function (this: OxPrompt, e: MouseEvent) {\n e.stopPropagation()\n }.bind(this)\n\n protected _onclose: (e: Event) => void = function (this: OxPrompt, e: Event) {\n this.resolve(false)\n this.close()\n }.bind(this)\n\n protected _oncollapse: (e: Event) => void = function (this: OxPrompt, e: Event) {\n e.stopPropagation()\n\n this.resolve(false)\n this.close()\n }.bind(this)\n\n protected _onwindowblur: (e: Event) => void = function (this: OxPrompt, e: Event) {\n // @ts-ignore for debug\n if (this.preventCloseOnBlur || window.POPUP_DEBUG) {\n return\n }\n\n this.resolve(false)\n this.close()\n }.bind(this)\n\n connectedCallback() {\n super.connectedCallback()\n\n this.addEventListener('focusout', this._onfocusout)\n this.addEventListener('keydown', this._onkeydown)\n this.addEventListener('keyup', this._onkeyup)\n this.addEventListener('click', this._onclick)\n this.addEventListener('mouseup', this._onmouseup)\n this.addEventListener('mousedown', this._onmousedown)\n this.addEventListener('contextmenu', this._oncontextmenu)\n this.addEventListener('ox-close', this._onclose)\n this.addEventListener('ox-collapse', this._oncollapse)\n\n this.setAttribute('tabindex', '0') // make this element focusable\n this.guaranteeFocus()\n }\n\n /**\n * Static method to open the `ox-prompt` popup.\n * @param {object} options - An object containing popup options.\n * @param {unknown} [options.template] - An optional content template to render inside the popup.\n * @param {'success' | 'error' | 'warning' | 'info' | 'question'} [options.type] - The type of the popup, which can be one of: 'success', 'error', 'warning', 'info', 'question'.\n * @param {string} [options.icon] - The icon to be displayed in the popup header.\n * @param {string} [options.title] - The title to be displayed in the popup header.\n * @param {string} [options.text] - The main text content of the popup.\n * @param {string} [options.footer] - Additional information to be displayed at the bottom of the popup.\n * @param {object} [options.confirmButton] - Configuration for the confirmation button in the popup.\n * @param {string} options.confirmButton.text - The text to be displayed on the confirmation button.\n * @param {string} [options.confirmButton.color] - Not applied. The action row owns button colours.\n * @param {boolean} [options.confirmButton.destructive] - The confirmation cannot be undone (delete, discard): the\n * button takes the error colour and cancel gets the first focus.\n * @param {object} [options.cancelButton] - Configuration for the cancel button in the popup.\n * @param {string} options.cancelButton.text - The text to be displayed on the cancel button.\n * @param {string} [options.cancelButton.color] - Not applied. Cancel is never coloured.\n * @param {number} [options.top] - The top position of the popup (in pixels).\n * @param {number} [options.left] - The left position of the popup (in pixels).\n * @param {number} [options.right] - The right position of the popup (in pixels).\n * @param {number} [options.bottom] - The bottom position of the popup (in pixels).\n * @param {string} [options.width] - The maximum width of the popup (CSS string).\n * @param {string} [options.height] - The maximum height of the popup (CSS string).\n * @param {Element | null} [options.parent] - The parent element to which the popup should be attached. If not provided, it will be attached to the document body.\n * @param {boolean} [options.preventCloseOnBlur] - Prevents the popup from closing when it loses focus (blur event).\n * @param {(result: { value: boolean }) => void} [options.callback] - A callback function that will be invoked when the user interacts with the popup, providing the result of the interaction.\n * @returns {Promise<boolean>} A Promise that resolves based on user interaction with the popup.\n */\n public static async open({\n template,\n type,\n icon,\n title,\n text,\n footer,\n confirmButton,\n cancelButton,\n top,\n left,\n right,\n bottom,\n width,\n height,\n parent,\n preventCloseOnBlur,\n callback\n }: {\n template?: unknown\n type?: 'success' | 'error' | 'warning' | 'info' | 'question'\n icon?: string\n title?: string\n text?: string\n footer?: string\n confirmButton?: { text: string; color?: string; destructive?: boolean }\n cancelButton?: { text: string; color?: string }\n top?: number\n left?: number\n right?: number\n bottom?: number\n width?: string\n height?: string\n parent?: Element | null\n preventCloseOnBlur?: boolean\n callback?: (result: { value: boolean }) => void\n }): Promise<boolean> {\n const owner = parent || document.body\n const target = document.createElement('ox-prompt') as OxPrompt\n\n target.type = type\n target.icon = icon\n target.text = text\n target.titler = title\n target.footer = footer\n target.confirmButton = confirmButton\n target.cancelButton = cancelButton\n target.preventCloseOnBlur = !!preventCloseOnBlur\n\n render(template, target)\n\n target._parent = owner\n owner.appendChild(target)\n\n const result = await target.open({ top, left, right, bottom, width, height })\n\n if (callback) {\n await callback.call(null, { value: result })\n }\n\n return result\n }\n\n /**\n * Asks before deleting — the modal replacement for `confirm('sure to delete?')`.\n *\n * Framework screens asked with the browser's own dialog (17 places, ADR-0060 decision 9): it\n * blocks the page, cannot be styled or translated, and put \"OK\" where every other popup puts\n * \"cancel\". This is the same question in the shared popup: a warning, \"delete\" painted as\n * destructive on the right, \"cancel\" before it and focused.\n *\n * if (!(await OxPrompt.confirmDelete({ count: selected.length }))) return\n *\n * @returns {Promise<boolean>} true when the user chose delete.\n */\n public static async confirmDelete({ count, parent }: { count?: number; parent?: Element | null } = {}): Promise<boolean> {\n return OxPrompt.open({\n type: 'warning',\n title:\n count && count > 1\n ? i18next.t('text.popup-confirm-delete-count', { count, defaultValue: 'delete the {count} selected items?' })\n : i18next.t('text.popup-confirm-delete', { defaultValue: 'delete the selected item?' }),\n confirmButton: { text: i18next.t('button.popup-delete', { defaultValue: 'delete' }), destructive: true },\n cancelButton: { text: i18next.t('button.popup-cancel', { defaultValue: 'cancel' }) },\n parent\n })\n }\n\n /**\n * Static method to open an input popup — a modal replacement for the native `window.prompt()`.\n *\n * Benchmarks `prompt(message, defaultValue)`: shows a text field and resolves with the entered\n * string on confirm, or `null` on cancel/escape/blur. Single-line inputs also confirm on Enter.\n *\n * This is purely additive and does not change the behavior of `OxPrompt.open()`.\n *\n * @returns {Promise<string | null>} The entered text on confirm, or null on cancel.\n */\n public static async prompt({\n title,\n text,\n defaultValue = '',\n placeholder = '',\n type = 'question',\n icon,\n multiline = false,\n confirmButton,\n cancelButton,\n preventCloseOnBlur = true,\n top,\n left,\n right,\n bottom,\n width,\n height,\n parent\n }: {\n title?: string\n text?: string\n defaultValue?: string\n placeholder?: string\n type?: 'success' | 'error' | 'warning' | 'info' | 'question'\n icon?: string\n multiline?: boolean\n confirmButton?: { text: string; color?: string }\n cancelButton?: { text: string; color?: string }\n preventCloseOnBlur?: boolean\n top?: number\n left?: number\n right?: number\n bottom?: number\n width?: string\n height?: string\n parent?: Element | null\n }): Promise<string | null> {\n const holder = { value: defaultValue }\n\n const onInput = (e: Event) => {\n holder.value = (e.target as HTMLInputElement | HTMLTextAreaElement).value\n }\n const onKeydown = (e: KeyboardEvent) => {\n // 단일 라인: Enter 로 확정(native prompt 벤치마킹). multiline 은 개행 유지.\n if (!multiline && e.key === 'Enter') {\n e.preventDefault()\n const host = (e.target as HTMLElement).closest('ox-prompt') as OxPrompt | null\n host?.onConfirm()\n }\n }\n\n // 폭은 컨테이너를 최대로 채우고(min-width 로 최소 크기 보장), textarea 는 세로로만 리사이즈.\n const inputStyle =\n 'width: 100%; min-width: var(--ox-prompt-input-min-width, 320px); box-sizing: border-box; padding: 8px; font: inherit;'\n\n const template = multiline\n ? html`\n <textarea\n rows=\"3\"\n placeholder=${placeholder}\n .value=${defaultValue}\n style=\"${inputStyle} resize: vertical;\"\n @input=${onInput}\n @keydown=${onKeydown}\n ></textarea>\n `\n : html`\n <input\n type=\"text\"\n placeholder=${placeholder}\n .value=${defaultValue}\n style=\"${inputStyle} resize: none;\"\n @input=${onInput}\n @keydown=${onKeydown}\n />\n `\n\n const confirmed = await OxPrompt.open({\n template,\n type,\n icon,\n title,\n text,\n confirmButton: confirmButton || { text: 'OK' },\n cancelButton: cancelButton || { text: 'Cancel' },\n preventCloseOnBlur,\n top,\n left,\n right,\n bottom,\n width,\n height,\n parent\n })\n\n return confirmed ? holder.value : null\n }\n\n /**\n * Opens the popup with specified position and dimensions.\n * @param {object} options - An object specifying the position and dimensions of the popup.\n * @param {number} [options.left] - The left position of the popup (in pixels). If not provided, the popup will be horizontally centered.\n * @param {number} [options.top] - The top position of the popup (in pixels). If not provided, the popup will be vertically centered.\n * @param {number} [options.right] - The right position of the popup (in pixels). Overrides 'left' if both 'left' and 'right' are provided.\n * @param {number} [options.bottom] - The bottom position of the popup (in pixels). Overrides 'top' if both 'top' and 'bottom' are provided.\n * @param {string} [options.width] - The maximum width of the popup (CSS string). If not provided, no width restriction is applied.\n * @param {string} [options.height] - The maximum height of the popup (CSS string). If not provided, no height restriction is applied.\n * @param {boolean} [options.silent=false] - Determines whether to focus the popup automatically (true) or not (false).\n * @returns {Promise<boolean>} A Promise that resolves based on user interaction with the popup.\n */\n open({\n left,\n top,\n right,\n bottom,\n width,\n height,\n silent = false\n }: {\n left?: number\n top?: number\n right?: number\n bottom?: number\n width?: string\n height?: string\n silent?: boolean\n }): Promise<boolean> {\n if (width) {\n this.style.maxWidth = width\n this.style.overflowX = 'auto'\n }\n\n if (height) {\n this.style.maxHeight = height\n this.style.overflowY = 'auto'\n }\n\n if (left === undefined && top === undefined && right === undefined && bottom === undefined) {\n this.style.left = '50%'\n this.style.top = '50%'\n this.style.transform = 'translateX(-50%) translateY(-50%)'\n } else {\n if (left !== undefined) this.style.left = `${left}px`\n if (top !== undefined) this.style.top = `${top}px`\n if (right !== undefined) this.style.right = `${right}px`\n if (bottom !== undefined) this.style.bottom = `${bottom}px`\n }\n\n this.setAttribute('active', '')\n\n // adjust popup position\n requestAnimationFrame(() => {\n const vh = document.body.clientHeight\n const vw = document.body.clientWidth\n\n var bounding = this.getBoundingClientRect()\n\n var h = bounding.height\n var w = bounding.width\n var t = bounding.top\n var l = bounding.left\n\n // If the popup is too large, it will cause overflow scrolling.\n if (vh < h) {\n this.style.height = `${Math.min(Math.max(Math.floor((vh * 2) / 3), vh - (t + 20)), vh)}px`\n this.style.overflow = 'auto'\n h = vh\n }\n\n if (vw < w) {\n this.style.width = `${Math.min(Math.max(Math.floor((vw * 2) / 3), vw - (l + 20)), vw)}px`\n this.style.overflow = 'auto'\n w = vw\n }\n\n // To prevent pop-ups from crossing screen boundaries, use the\n const computedStyle = getComputedStyle(this)\n\n if (t < 0) {\n this.style.top = `calc(${computedStyle.top} + ${t}px)`\n this.style.bottom = ''\n } else if (vh <= t + h) {\n this.style.top = `calc(${computedStyle.top} - ${t + h - vh}px)`\n this.style.bottom = ''\n }\n\n if (l < 0) {\n this.style.left = `calc(${computedStyle.left} + ${l}px)`\n this.style.right = ''\n } else if (vw < l + w) {\n this.style.left = `calc(${computedStyle.left} - ${l + w - vw}px)`\n this.style.right = ''\n }\n })\n\n requestAnimationFrame(() => {\n // auto focusing\n !silent && this.guaranteeFocus()\n })\n\n /* When the window is out of focus, all pop-ups should disappear. */\n window.addEventListener('blur', this._onwindowblur)\n\n return new Promise(resolve => {\n this.resolveFn = resolve\n })\n }\n\n guaranteeFocus(target?: HTMLElement) {\n const focusible = (target || this.renderRoot)?.querySelector(\n ':host > button, :host > [href], :host > input, :host > select, :host > textarea, :host > [tabindex]:not([tabindex=\"-1\"]), :host [type=\"button\"]'\n )\n\n if (focusible) {\n ;(focusible as HTMLElement).focus()\n } else {\n this.focus()\n }\n }\n\n /**\n * Closes the popup.\n */\n close() {\n this.removeAttribute('active')\n\n window.removeEventListener('blur', this._onwindowblur)\n\n if (this._parent) {\n /* this case is when the popup is opened by OxPrompt.open(...) */\n this.removeEventListener('focusout', this._onfocusout)\n this.removeEventListener('keydown', this._onkeydown)\n this.removeEventListener('keyup', this._onkeyup)\n this.removeEventListener('click', this._onclick)\n this.removeEventListener('ox-close', this._onclose)\n this.removeEventListener('ox-collapse', this._oncollapse)\n this.removeEventListener('mouseup', this._onmouseup)\n this.removeEventListener('mousedown', this._onmousedown)\n this.removeEventListener('contextmenu', this._oncontextmenu)\n\n this._parent.removeChild(this)\n delete this._parent\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a popup's result waits between "someone asked to close with this value" and "the popup is
|
|
3
|
+
* actually gone".
|
|
4
|
+
*
|
|
5
|
+
* There are two entrances for a value - the opener's `handle.close(value)` and the content's
|
|
6
|
+
* `closePopup(element, value)` - but only one place settles: the overlay leaving the document.
|
|
7
|
+
* Settling at an entrance would give two settling places. So entrances record, the first recorded
|
|
8
|
+
* value wins, and `openPopup` takes it when the implementation reports the popup gone.
|
|
9
|
+
*/
|
|
10
|
+
/** Called by `openPopup` when a popup opens. Overlays that are not popups never get a slot. */
|
|
11
|
+
export declare function beginPopupResult(name: string): void;
|
|
12
|
+
/** Records a close request's value. True when this call recorded it; false when one came first. */
|
|
13
|
+
export declare function recordPopupResult(name: string | undefined, value: unknown): boolean;
|
|
14
|
+
/** Undoes a record whose request turned out not to close anything, so it cannot become the result. */
|
|
15
|
+
export declare function forgetPopupResult(name: string): void;
|
|
16
|
+
/** Takes the value once, when the popup is gone. Undefined when it was only dismissed. */
|
|
17
|
+
export declare function takePopupResult(name: string): unknown;
|
|
18
|
+
/** True for the first request to go back for this overlay; false while that back is still pending. */
|
|
19
|
+
export declare function claimHistoryBack(name: string): boolean;
|