@operato/popup 10.15.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 +14 -0
- package/coverage/lcov-report/index.html +27 -27
- package/coverage/lcov.info +1385 -1075
- package/dist/src/ox-prompt.d.ts +16 -0
- package/dist/src/ox-prompt.js +24 -0
- package/dist/src/ox-prompt.js.map +1 -1
- package/dist/test/office-control-height.test.d.ts +2 -1
- package/dist/test/office-control-height.test.js +84 -30
- package/dist/test/office-control-height.test.js.map +1 -1
- package/dist/test/ox-popup-actions.test.js +4 -4
- package/dist/test/ox-popup-actions.test.js.map +1 -1
- package/dist/test/ox-prompt-actions.test.js +33 -2
- package/dist/test/ox-prompt-actions.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/test/office-control-height.test.ts +98 -31
- package/test/ox-popup-actions.test.ts +4 -4
- package/test/ox-prompt-actions.test.ts +39 -2
- 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
package/dist/src/ox-prompt.d.ts
CHANGED
|
@@ -137,6 +137,22 @@ export declare class OxPrompt extends LitElement {
|
|
|
137
137
|
value: boolean;
|
|
138
138
|
}) => void;
|
|
139
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>;
|
|
140
156
|
/**
|
|
141
157
|
* Static method to open an input popup — a modal replacement for the native `window.prompt()`.
|
|
142
158
|
*
|
package/dist/src/ox-prompt.js
CHANGED
|
@@ -8,6 +8,7 @@ import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typesca
|
|
|
8
8
|
import { css, html, nothing, LitElement } from 'lit';
|
|
9
9
|
import { render } from 'lit-html';
|
|
10
10
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
11
|
+
import { i18next } from '@operato/i18n';
|
|
11
12
|
import { ScrollbarStyles } from '@operato/styles';
|
|
12
13
|
const TYPES_ICON = {
|
|
13
14
|
success: 'verified',
|
|
@@ -303,6 +304,29 @@ let OxPrompt = class OxPrompt extends LitElement {
|
|
|
303
304
|
}
|
|
304
305
|
return result;
|
|
305
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
|
+
}
|
|
306
330
|
/**
|
|
307
331
|
* Static method to open an input popup — a modal replacement for the native `window.prompt()`.
|
|
308
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/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 { 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 * 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"]}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import '@material/web/button/filled-button.js';
|
|
2
|
+
import '../src/ox-popup-actions.js';
|
|
@@ -1,48 +1,102 @@
|
|
|
1
|
-
import
|
|
1
|
+
import '@material/web/button/filled-button.js';
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
3
|
+
import { css, html, LitElement } from 'lit';
|
|
2
4
|
import { ACTION_HEIGHT_TOKENS, ButtonContainerStyles, CommonHeaderStyles, CommonPopupStyles } from '@operato/styles';
|
|
5
|
+
import '../src/ox-popup-actions.js';
|
|
3
6
|
import { OxPopupActions } from '../src/ox-popup-actions.js';
|
|
4
7
|
/**
|
|
5
|
-
*
|
|
6
|
-
* 26px in a grid cell, the same for mouse and finger (WCAG 2.2 AA, user decision 2026-09-17).
|
|
8
|
+
* Button heights (ADR-0060 decisions 6 and 6-1).
|
|
7
9
|
*
|
|
8
|
-
* The
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* The **platform** keeps the heights every application had before the operato standardization, so
|
|
11
|
+
* dssp, fmsim and the rest do not change when they upgrade. The **operato products** are compact: the
|
|
12
|
+
* shell theme opens each token as `var(--suite-<token>, <platform>)` and operato-suite fills the slot.
|
|
13
|
+
*
|
|
14
|
+
* These render both worlds with a mouse (the test browser). The finger branches cannot be emulated,
|
|
15
|
+
* so those are read from the stylesheets.
|
|
11
16
|
*/
|
|
17
|
+
const PLATFORM_TOKENS = `
|
|
18
|
+
--context-action-height: var(--suite-context-action-height, 32px);
|
|
19
|
+
--popup-action-height: var(--suite-popup-action-height, 30px);
|
|
20
|
+
--form-action-height: var(--suite-form-action-height, 40px);
|
|
21
|
+
`;
|
|
22
|
+
const SUITE_SLOTS = `
|
|
23
|
+
--suite-context-action-height: 32px;
|
|
24
|
+
--suite-popup-action-height: 32px;
|
|
25
|
+
--suite-form-action-height: 32px;
|
|
26
|
+
`;
|
|
27
|
+
class StyledRows extends LitElement {
|
|
28
|
+
static { this.styles = [CommonPopupStyles, CommonHeaderStyles, ButtonContainerStyles, css ``]; }
|
|
29
|
+
render() {
|
|
30
|
+
return html `
|
|
31
|
+
<div class="buttons"><md-filled-button id="popup-md">save</md-filled-button></div>
|
|
32
|
+
<div class="footer"><button id="footer">save</button></div>
|
|
33
|
+
<div class="button-container">
|
|
34
|
+
<button id="bar">export</button>
|
|
35
|
+
<md-filled-button id="bar-md">publish</md-filled-button>
|
|
36
|
+
</div>
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
customElements.define('test-styled-rows', StyledRows);
|
|
41
|
+
const height = (el) => Math.round(el.getBoundingClientRect().height);
|
|
12
42
|
const text = (styles) => (Array.isArray(styles) ? styles : [styles]).map(s => String(s.cssText ?? s)).join('\n');
|
|
13
|
-
const coarse = (
|
|
43
|
+
const coarse = (cssText) => cssText.slice(cssText.indexOf('(pointer: coarse)'));
|
|
44
|
+
async function rows(style) {
|
|
45
|
+
const host = await fixture(html `
|
|
46
|
+
<div style="${style}">
|
|
47
|
+
<test-styled-rows></test-styled-rows>
|
|
48
|
+
<ox-popup-actions>
|
|
49
|
+
<md-filled-button slot="confirm" id="prompt-md">ok</md-filled-button>
|
|
50
|
+
</ox-popup-actions>
|
|
51
|
+
</div>
|
|
52
|
+
`);
|
|
53
|
+
const styled = host.querySelector('test-styled-rows');
|
|
54
|
+
await styled.updateComplete;
|
|
55
|
+
const actions = host.querySelector('ox-popup-actions');
|
|
56
|
+
await actions.updateComplete;
|
|
57
|
+
const buttons = [...Array.from(styled.shadowRoot.querySelectorAll('md-filled-button')), host.querySelector('#prompt-md')];
|
|
58
|
+
await Promise.all(buttons.map(b => b.updateComplete));
|
|
59
|
+
return { root: styled.shadowRoot, host };
|
|
60
|
+
}
|
|
14
61
|
describe('office control height', () => {
|
|
15
|
-
it('the defaults are
|
|
62
|
+
it('the platform defaults are the heights before the standardization', () => {
|
|
16
63
|
expect(ACTION_HEIGHT_TOKENS).to.deep.equal({
|
|
17
64
|
'--context-action-height': 32,
|
|
18
|
-
'--popup-action-height':
|
|
19
|
-
'--form-action-height':
|
|
65
|
+
'--popup-action-height': 30,
|
|
66
|
+
'--form-action-height': 40,
|
|
20
67
|
'--cell-action-height': 26
|
|
21
68
|
});
|
|
22
69
|
});
|
|
23
|
-
it('
|
|
24
|
-
const
|
|
25
|
-
expect(
|
|
26
|
-
expect(
|
|
27
|
-
expect(
|
|
70
|
+
it('★ platform: nothing changes for applications outside the operato suite', async () => {
|
|
71
|
+
const { root, host } = await rows(PLATFORM_TOKENS);
|
|
72
|
+
expect(height(root.querySelector('#popup-md'))).to.equal(40); // CommonPopupStyles .buttons
|
|
73
|
+
expect(height(root.querySelector('#footer'))).to.be.at.least(30); // older footer
|
|
74
|
+
expect(height(root.querySelector('#bar'))).to.equal(32); // page action bar
|
|
75
|
+
expect(height(root.querySelector('#bar-md'))).to.equal(40); // Material keeps its own in the bar
|
|
76
|
+
expect(height(host.querySelector('#prompt-md'))).to.equal(30); // OxPrompt row, as before
|
|
77
|
+
});
|
|
78
|
+
it('★ suite: every action button in the operato products is 32px', async () => {
|
|
79
|
+
const { root, host } = await rows(SUITE_SLOTS + PLATFORM_TOKENS);
|
|
80
|
+
expect(height(root.querySelector('#popup-md'))).to.equal(32);
|
|
81
|
+
expect(height(root.querySelector('#bar'))).to.equal(32);
|
|
82
|
+
expect(height(root.querySelector('#bar-md'))).to.equal(32);
|
|
83
|
+
expect(height(host.querySelector('#prompt-md'))).to.equal(32);
|
|
28
84
|
});
|
|
29
|
-
it('
|
|
30
|
-
const
|
|
31
|
-
expect(
|
|
32
|
-
expect(coarse(css)).to.contain('min-height: var(--popup-action-height, 32px)');
|
|
33
|
-
expect(css).to.not.match(/max\(\d+px/);
|
|
85
|
+
it('a shop-floor screen still raises the popup row above both', async () => {
|
|
86
|
+
const { root } = await rows(SUITE_SLOTS + PLATFORM_TOKENS + '--popup-action-height: 64px;');
|
|
87
|
+
expect(height(root.querySelector('#popup-md'))).to.equal(64);
|
|
34
88
|
});
|
|
35
|
-
it('
|
|
36
|
-
const
|
|
37
|
-
expect(
|
|
38
|
-
|
|
89
|
+
it('finger: the platform keeps 44px for the page bar and a 48px floor for the popup row', () => {
|
|
90
|
+
const bar = coarse(text(ButtonContainerStyles));
|
|
91
|
+
expect(bar).to.contain('var(--suite-context-action-height, 44px)');
|
|
92
|
+
const popup = coarse(text(CommonPopupStyles));
|
|
93
|
+
expect(popup).to.contain('var(--suite-popup-action-height, 48px)');
|
|
94
|
+
expect(popup).to.contain('var(--popup-action-height, 30px)');
|
|
39
95
|
});
|
|
40
|
-
it('
|
|
41
|
-
const
|
|
42
|
-
expect(
|
|
43
|
-
expect(
|
|
44
|
-
expect(css).to.not.contain('--context-action-height-touch');
|
|
45
|
-
expect(css).to.not.contain('(pointer: coarse)');
|
|
96
|
+
it('ox-popup-actions has no finger height of its own', () => {
|
|
97
|
+
const cssText = text(OxPopupActions.styles);
|
|
98
|
+
expect(cssText).to.contain('--_height: var(--popup-action-height, 30px)');
|
|
99
|
+
expect(coarse(cssText)).to.not.contain('--_height:');
|
|
46
100
|
});
|
|
47
101
|
});
|
|
48
102
|
//# sourceMappingURL=office-control-height.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"office-control-height.test.js","sourceRoot":"","sources":["../../test/office-control-height.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"office-control-height.test.js","sourceRoot":"","sources":["../../test/office-control-height.test.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/button/filled-button.js'\n\nimport { expect, fixture } from '@open-wc/testing'\nimport { css, html, LitElement } from 'lit'\n\nimport {\n ACTION_HEIGHT_TOKENS,\n ButtonContainerStyles,\n CommonHeaderStyles,\n CommonPopupStyles\n} from '@operato/styles'\n\nimport '../src/ox-popup-actions.js'\nimport { OxPopupActions } from '../src/ox-popup-actions.js'\n\n/**\n * Button heights (ADR-0060 decisions 6 and 6-1).\n *\n * The **platform** keeps the heights every application had before the operato standardization, so\n * dssp, fmsim and the rest do not change when they upgrade. The **operato products** are compact: the\n * shell theme opens each token as `var(--suite-<token>, <platform>)` and operato-suite fills the slot.\n *\n * These render both worlds with a mouse (the test browser). The finger branches cannot be emulated,\n * so those are read from the stylesheets.\n */\n\nconst PLATFORM_TOKENS = `\n --context-action-height: var(--suite-context-action-height, 32px);\n --popup-action-height: var(--suite-popup-action-height, 30px);\n --form-action-height: var(--suite-form-action-height, 40px);\n`\nconst SUITE_SLOTS = `\n --suite-context-action-height: 32px;\n --suite-popup-action-height: 32px;\n --suite-form-action-height: 32px;\n`\n\nclass StyledRows extends LitElement {\n static styles = [CommonPopupStyles, CommonHeaderStyles, ButtonContainerStyles, css``]\n\n render() {\n return html`\n <div class=\"buttons\"><md-filled-button id=\"popup-md\">save</md-filled-button></div>\n <div class=\"footer\"><button id=\"footer\">save</button></div>\n <div class=\"button-container\">\n <button id=\"bar\">export</button>\n <md-filled-button id=\"bar-md\">publish</md-filled-button>\n </div>\n `\n }\n}\ncustomElements.define('test-styled-rows', StyledRows)\n\nconst height = (el: Element | null | undefined) => Math.round(el!.getBoundingClientRect().height)\nconst text = (styles: unknown) =>\n (Array.isArray(styles) ? styles : [styles]).map(s => String((s as { cssText?: string }).cssText ?? s)).join('\\n')\nconst coarse = (cssText: string) => cssText.slice(cssText.indexOf('(pointer: coarse)'))\n\nasync function rows(style: string) {\n const host = await fixture<HTMLElement>(html`\n <div style=\"${style}\">\n <test-styled-rows></test-styled-rows>\n <ox-popup-actions>\n <md-filled-button slot=\"confirm\" id=\"prompt-md\">ok</md-filled-button>\n </ox-popup-actions>\n </div>\n `)\n const styled = host.querySelector('test-styled-rows') as StyledRows\n await styled.updateComplete\n const actions = host.querySelector('ox-popup-actions') as OxPopupActions\n await actions.updateComplete\n const buttons = [...Array.from(styled.shadowRoot!.querySelectorAll('md-filled-button')), host.querySelector('#prompt-md')]\n await Promise.all(buttons.map(b => (b as LitElement).updateComplete))\n return { root: styled.shadowRoot!, host }\n}\n\ndescribe('office control height', () => {\n it('the platform defaults are the heights before the standardization', () => {\n expect(ACTION_HEIGHT_TOKENS).to.deep.equal({\n '--context-action-height': 32,\n '--popup-action-height': 30,\n '--form-action-height': 40,\n '--cell-action-height': 26\n })\n })\n\n it('★ platform: nothing changes for applications outside the operato suite', async () => {\n const { root, host } = await rows(PLATFORM_TOKENS)\n\n expect(height(root.querySelector('#popup-md'))).to.equal(40) // CommonPopupStyles .buttons\n expect(height(root.querySelector('#footer'))).to.be.at.least(30) // older footer\n expect(height(root.querySelector('#bar'))).to.equal(32) // page action bar\n expect(height(root.querySelector('#bar-md'))).to.equal(40) // Material keeps its own in the bar\n expect(height(host.querySelector('#prompt-md'))).to.equal(30) // OxPrompt row, as before\n })\n\n it('★ suite: every action button in the operato products is 32px', async () => {\n const { root, host } = await rows(SUITE_SLOTS + PLATFORM_TOKENS)\n\n expect(height(root.querySelector('#popup-md'))).to.equal(32)\n expect(height(root.querySelector('#bar'))).to.equal(32)\n expect(height(root.querySelector('#bar-md'))).to.equal(32)\n expect(height(host.querySelector('#prompt-md'))).to.equal(32)\n })\n\n it('a shop-floor screen still raises the popup row above both', async () => {\n const { root } = await rows(SUITE_SLOTS + PLATFORM_TOKENS + '--popup-action-height: 64px;')\n expect(height(root.querySelector('#popup-md'))).to.equal(64)\n })\n\n it('finger: the platform keeps 44px for the page bar and a 48px floor for the popup row', () => {\n const bar = coarse(text(ButtonContainerStyles))\n expect(bar).to.contain('var(--suite-context-action-height, 44px)')\n\n const popup = coarse(text(CommonPopupStyles))\n expect(popup).to.contain('var(--suite-popup-action-height, 48px)')\n expect(popup).to.contain('var(--popup-action-height, 30px)')\n })\n\n it('ox-popup-actions has no finger height of its own', () => {\n const cssText = text(OxPopupActions.styles)\n expect(cssText).to.contain('--_height: var(--popup-action-height, 30px)')\n expect(coarse(cssText)).to.not.contain('--_height:')\n })\n})\n"]}
|
|
@@ -8,7 +8,7 @@ import '../src/ox-popup-actions.js';
|
|
|
8
8
|
* wrong by writing its markup differently. These run with a mouse pointer (the test browser); the
|
|
9
9
|
* finger bar is a media query of the same element.
|
|
10
10
|
*
|
|
11
|
-
* The expected numbers are written out (
|
|
11
|
+
* The expected numbers are written out (30, 68, 999em) rather than read from the stylesheet, so a
|
|
12
12
|
* change to the stylesheet shows up here as a decision, not as a silent follow.
|
|
13
13
|
*/
|
|
14
14
|
const left = (el) => el.getBoundingClientRect().left;
|
|
@@ -45,15 +45,15 @@ describe('ox-popup-actions', () => {
|
|
|
45
45
|
const confirm = actions.querySelector('#confirm');
|
|
46
46
|
expect(Math.round(confirm.getBoundingClientRect().right)).to.equal(Math.round(actions.getBoundingClientRect().right));
|
|
47
47
|
});
|
|
48
|
-
it('gives Material buttons and plain buttons the same
|
|
48
|
+
it('gives Material buttons and plain buttons the same height (30px, the platform default)', async () => {
|
|
49
49
|
const actions = await row(html `
|
|
50
50
|
<ox-popup-actions>
|
|
51
51
|
<button slot="cancel" id="plain">cancel</button>
|
|
52
52
|
<md-filled-button slot="confirm" id="md">save</md-filled-button>
|
|
53
53
|
</ox-popup-actions>
|
|
54
54
|
`);
|
|
55
|
-
expect(height(actions.querySelector('#md'))).to.equal(
|
|
56
|
-
expect(height(actions.querySelector('#plain'))).to.equal(
|
|
55
|
+
expect(height(actions.querySelector('#md'))).to.equal(30);
|
|
56
|
+
expect(height(actions.querySelector('#plain'))).to.equal(30);
|
|
57
57
|
});
|
|
58
58
|
it('uses pill shapes inside the popup card', async () => {
|
|
59
59
|
const actions = await row(html `
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-popup-actions.test.js","sourceRoot":"","sources":["../../test/ox-popup-actions.test.ts"],"names":[],"mappings":"AAAA,OAAO,uCAAuC,CAAA;AAC9C,OAAO,qCAAqC,CAAA;AAE5C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,OAAO,4BAA4B,CAAA;AAEnC;;;;;;;GAOG;AAEH,MAAM,IAAI,GAAG,CAAC,EAAW,EAAE,EAAE,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,IAAI,CAAA;AAC7D,MAAM,MAAM,GAAG,CAAC,EAAW,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,MAAM,CAAC,CAAA;AAE7E,KAAK,UAAU,GAAG,CAAC,QAAiC;IAClD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAc,IAAI,CAAA,6BAA6B,QAAQ,QAAQ,CAAC,CAAA;IAC1F,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAuD,CAAA;IAC5G,MAAM,OAAO,CAAC,cAAc,CAAA;IAC5B,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,kCAAkC,CAAC,CAAC,CAAC,GAAG,CAC1E,CAAC,CAAC,EAAE,CAAE,CAAwD,CAAC,cAAc,CAC9E,CACF,CAAA;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,CAAA;;;;;;KAM7B,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAE,CAAA;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,SAAS,CAAE,CAAA;QAChD,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,UAAU,CAAE,CAAA;QAElD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QAChD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;IACpD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,CAAA;;;;;KAK7B,CAAC,CAAA;QAEF,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,UAAU,CAAE,CAAA;QAClD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IACvH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC
|
|
1
|
+
{"version":3,"file":"ox-popup-actions.test.js","sourceRoot":"","sources":["../../test/ox-popup-actions.test.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/button/filled-button.js'\nimport '@material/web/button/text-button.js'\n\nimport { expect, fixture } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport '../src/ox-popup-actions.js'\n\n/**\n * The action row owns order, height, shape and the destructive colour - so a popup cannot get them\n * wrong by writing its markup differently. These run with a mouse pointer (the test browser); the\n * finger bar is a media query of the same element.\n *\n * The expected numbers are written out (30, 68, 999em) rather than read from the stylesheet, so a\n * change to the stylesheet shows up here as a decision, not as a silent follow.\n */\n\nconst left = (el: Element) => el.getBoundingClientRect().left\nconst height = (el: Element) => Math.round(el.getBoundingClientRect().height)\n\nasync function row(template: ReturnType<typeof html>) {\n const host = await fixture<HTMLElement>(html`<div style=\"width: 600px\">${template}</div>`)\n const actions = host.querySelector('ox-popup-actions') as HTMLElement & { updateComplete: Promise<unknown> }\n await actions.updateComplete\n await Promise.all(\n Array.from(actions.querySelectorAll('md-filled-button, md-text-button')).map(\n b => (b as HTMLElement & { updateComplete: Promise<unknown> }).updateComplete\n )\n )\n return actions\n}\n\ndescribe('ox-popup-actions', () => {\n it('renders start, cancel, confirm in that order whatever the markup order', async () => {\n const actions = await row(html`\n <ox-popup-actions>\n <md-filled-button slot=\"confirm\" id=\"confirm\">save</md-filled-button>\n <md-text-button slot=\"cancel\" id=\"cancel\">cancel</md-text-button>\n <md-text-button slot=\"start\" id=\"start\">delete</md-text-button>\n </ox-popup-actions>\n `)\n\n const start = actions.querySelector('#start')!\n const cancel = actions.querySelector('#cancel')!\n const confirm = actions.querySelector('#confirm')!\n\n expect(left(start)).to.be.lessThan(left(cancel))\n expect(left(cancel)).to.be.lessThan(left(confirm))\n })\n\n it('keeps the confirm button at the right edge', async () => {\n const actions = await row(html`\n <ox-popup-actions>\n <md-filled-button slot=\"confirm\" id=\"confirm\">save</md-filled-button>\n <md-text-button slot=\"cancel\">cancel</md-text-button>\n </ox-popup-actions>\n `)\n\n const confirm = actions.querySelector('#confirm')!\n expect(Math.round(confirm.getBoundingClientRect().right)).to.equal(Math.round(actions.getBoundingClientRect().right))\n })\n\n it('gives Material buttons and plain buttons the same height (30px, the platform default)', async () => {\n const actions = await row(html`\n <ox-popup-actions>\n <button slot=\"cancel\" id=\"plain\">cancel</button>\n <md-filled-button slot=\"confirm\" id=\"md\">save</md-filled-button>\n </ox-popup-actions>\n `)\n\n expect(height(actions.querySelector('#md')!)).to.equal(30)\n expect(height(actions.querySelector('#plain')!)).to.equal(30)\n })\n\n it('uses pill shapes inside the popup card', async () => {\n const actions = await row(html`\n <ox-popup-actions>\n <button slot=\"cancel\" id=\"plain\">cancel</button>\n <md-filled-button slot=\"confirm\" id=\"md\">save</md-filled-button>\n </ox-popup-actions>\n `)\n\n const md = actions.querySelector('#md')!\n expect(getComputedStyle(md).getPropertyValue('--md-filled-button-container-shape').trim()).to.equal('999em')\n expect(getComputedStyle(actions.querySelector('#plain')!).borderTopLeftRadius).to.not.equal('0px')\n })\n\n it('lets a screen raise the height through --popup-action-height', async () => {\n const actions = await row(html`\n <ox-popup-actions style=\"--popup-action-height: 68px\">\n <button slot=\"cancel\" id=\"plain\">cancel</button>\n <md-filled-button slot=\"confirm\" id=\"md\">save</md-filled-button>\n </ox-popup-actions>\n `)\n\n expect(height(actions.querySelector('#md')!)).to.equal(68)\n expect(height(actions.querySelector('#plain')!)).to.equal(68)\n })\n\n it('paints a destructive action with the error colour', async () => {\n const actions = await row(html`\n <ox-popup-actions style=\"--md-sys-color-error: rgb(190, 12, 20)\">\n <md-text-button slot=\"start\" destructive id=\"side\">delete</md-text-button>\n <md-filled-button slot=\"confirm\" destructive id=\"main\">delete all</md-filled-button>\n <button slot=\"cancel\" id=\"plain\" destructive>cancel</button>\n </ox-popup-actions>\n `)\n\n const side = getComputedStyle(actions.querySelector('#side')!)\n const main = getComputedStyle(actions.querySelector('#main')!)\n\n expect(side.getPropertyValue('--md-text-button-label-text-color').trim()).to.equal('rgb(190, 12, 20)')\n expect(main.getPropertyValue('--md-filled-button-container-color').trim()).to.equal('rgb(190, 12, 20)')\n })\n\n it('never paints cancel as destructive', async () => {\n const actions = await row(html`\n <ox-popup-actions style=\"--md-sys-color-error: rgb(190, 12, 20)\">\n <md-text-button slot=\"cancel\" destructive id=\"cancel\">cancel</md-text-button>\n <button slot=\"cancel\" destructive id=\"plain\">cancel</button>\n <md-filled-button slot=\"confirm\">save</md-filled-button>\n </ox-popup-actions>\n `)\n\n expect(getComputedStyle(actions.querySelector('#cancel')!).getPropertyValue('--md-text-button-label-text-color').trim()).to.not.equal(\n 'rgb(190, 12, 20)'\n )\n expect(getComputedStyle(actions.querySelector('#plain')!).color).to.not.equal('rgb(190, 12, 20)')\n })\n})\n"]}
|
|
@@ -48,8 +48,8 @@ describe('OxPrompt uses the shared action row', () => {
|
|
|
48
48
|
expect(confirm.getAttribute('slot')).to.equal('confirm');
|
|
49
49
|
expect(cancel.getAttribute('slot')).to.equal('cancel');
|
|
50
50
|
expect(cancel.getBoundingClientRect().left).to.be.lessThan(confirm.getBoundingClientRect().left);
|
|
51
|
-
expect(Math.round(confirm.getBoundingClientRect().height)).to.equal(
|
|
52
|
-
expect(Math.round(cancel.getBoundingClientRect().height)).to.equal(
|
|
51
|
+
expect(Math.round(confirm.getBoundingClientRect().height)).to.equal(30);
|
|
52
|
+
expect(Math.round(cancel.getBoundingClientRect().height)).to.equal(30);
|
|
53
53
|
cancel.click();
|
|
54
54
|
expect(await within(answer)).to.equal(false);
|
|
55
55
|
});
|
|
@@ -74,4 +74,35 @@ describe('OxPrompt uses the shared action row', () => {
|
|
|
74
74
|
expect(await within(answer)).to.equal(false);
|
|
75
75
|
});
|
|
76
76
|
});
|
|
77
|
+
describe('OxPrompt.confirmDelete', () => {
|
|
78
|
+
afterEach(() => {
|
|
79
|
+
document.body.querySelectorAll('ox-prompt').forEach(p => p.close());
|
|
80
|
+
});
|
|
81
|
+
async function opened(count) {
|
|
82
|
+
const before = document.body.querySelectorAll('ox-prompt').length;
|
|
83
|
+
const answer = OxPrompt.confirmDelete({ count });
|
|
84
|
+
for (let i = 0; i < 40 && document.body.querySelectorAll('ox-prompt').length <= before; i++)
|
|
85
|
+
await settle();
|
|
86
|
+
const prompts = document.body.querySelectorAll('ox-prompt');
|
|
87
|
+
const prompt = prompts[prompts.length - 1];
|
|
88
|
+
await prompt.updateComplete;
|
|
89
|
+
const root = prompt.renderRoot;
|
|
90
|
+
const confirm = root.querySelector('#confirm');
|
|
91
|
+
await confirm?.updateComplete;
|
|
92
|
+
return { answer, prompt, root, confirm };
|
|
93
|
+
}
|
|
94
|
+
it('asks in the shared popup with a destructive delete, and answers true on delete', async () => {
|
|
95
|
+
const { answer, prompt, confirm } = await opened();
|
|
96
|
+
expect(prompt.titler).to.equal('delete the selected item?');
|
|
97
|
+
expect(confirm.hasAttribute('destructive')).to.equal(true);
|
|
98
|
+
expect(confirm.textContent?.trim()).to.equal('delete');
|
|
99
|
+
confirm.click();
|
|
100
|
+
expect(await within(answer)).to.equal(true);
|
|
101
|
+
});
|
|
102
|
+
it('names how many are selected when more than one', async () => {
|
|
103
|
+
const { prompt, root } = await opened(3);
|
|
104
|
+
expect(prompt.titler).to.equal('delete the 3 selected items?');
|
|
105
|
+
root.querySelector('#cancel').click();
|
|
106
|
+
});
|
|
107
|
+
});
|
|
77
108
|
//# sourceMappingURL=ox-prompt-actions.test.js.map
|