@digitalwalletcorp/vue-core 1.2.0 โ 1.3.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/README.md +95 -8
- package/lib/accordion-fieldset.d.cts +14 -4
- package/lib/accordion-fieldset.d.ts +14 -4
- package/lib/accordion-section.d.cts +20 -10
- package/lib/accordion-section.d.ts +20 -10
- package/lib/components-2zQ2SZuY.js +26 -0
- package/lib/components-HaiHcseF.cjs +1 -0
- package/lib/components.d.cts +10 -0
- package/lib/components.d.ts +10 -0
- package/lib/copy-button.d.cts +34 -0
- package/lib/copy-button.d.ts +34 -0
- package/lib/dark-mode-selector.d.cts +32 -0
- package/lib/dark-mode-selector.d.ts +32 -0
- package/lib/data-table.d.cts +30 -0
- package/lib/data-table.d.ts +30 -0
- package/lib/help-button.d.cts +39 -0
- package/lib/help-button.d.ts +39 -0
- package/lib/help-popper.d.cts +39 -0
- package/lib/help-popper.d.ts +39 -0
- package/lib/helpers/data-table-csv.d.cts +17 -0
- package/lib/helpers/data-table-csv.d.ts +17 -0
- package/lib/helpers/show-floating-component.d.cts +82 -0
- package/lib/helpers/show-floating-component.d.ts +82 -0
- package/lib/helpers/show-modal-dialog.d.cts +73 -0
- package/lib/helpers/show-modal-dialog.d.ts +73 -0
- package/lib/helpers/show-overlay-box.d.cts +53 -0
- package/lib/helpers/show-overlay-box.d.ts +53 -0
- package/lib/helpers/show-screen-loading.d.cts +20 -0
- package/lib/helpers/show-screen-loading.d.ts +20 -0
- package/lib/helpers/show-snackbar.d.cts +47 -0
- package/lib/helpers/show-snackbar.d.ts +47 -0
- package/lib/hourglass-loading.d.cts +1 -1
- package/lib/hourglass-loading.d.ts +1 -1
- package/lib/index.cjs +1 -1
- package/lib/index.d.cts +34 -0
- package/lib/index.d.ts +34 -0
- package/lib/index.js +445 -18
- package/lib/internal/anchored-popover.d.cts +35 -0
- package/lib/internal/anchored-popover.d.ts +35 -0
- package/lib/internal/anchored-position.d.cts +50 -0
- package/lib/internal/anchored-position.d.ts +50 -0
- package/lib/internal/data-table-controls.d.cts +42 -0
- package/lib/internal/data-table-controls.d.ts +42 -0
- package/lib/internal/data-table-value.d.cts +32 -0
- package/lib/internal/data-table-value.d.ts +32 -0
- package/lib/internal/floating-component.d.cts +52 -0
- package/lib/internal/floating-component.d.ts +52 -0
- package/lib/internal/icon-popper.d.cts +32 -0
- package/lib/internal/icon-popper.d.ts +32 -0
- package/lib/internal/mount-window.d.cts +39 -0
- package/lib/internal/mount-window.d.ts +39 -0
- package/lib/internal/movable-window.d.cts +55 -0
- package/lib/internal/movable-window.d.ts +55 -0
- package/lib/internal/opened-overlay-boxes.d.cts +2 -0
- package/lib/internal/opened-overlay-boxes.d.ts +2 -0
- package/lib/internal/pagination.d.cts +22 -0
- package/lib/internal/pagination.d.ts +22 -0
- package/lib/internal/snackbar-container.d.cts +20 -0
- package/lib/internal/snackbar-container.d.ts +20 -0
- package/lib/internal/snackbar-item.d.cts +17 -0
- package/lib/internal/snackbar-item.d.ts +17 -0
- package/lib/internal/tab-group-context.d.cts +4 -2
- package/lib/internal/tab-group-context.d.ts +4 -2
- package/lib/internal/use-movable-window.d.cts +44 -0
- package/lib/internal/use-movable-window.d.ts +44 -0
- package/lib/internal/window-order.d.cts +6 -0
- package/lib/internal/window-order.d.ts +6 -0
- package/lib/intersection-lazy-component.d.cts +32 -0
- package/lib/intersection-lazy-component.d.ts +32 -0
- package/lib/label-button.d.cts +2 -2
- package/lib/label-button.d.ts +2 -2
- package/lib/label-icon.d.cts +2 -2
- package/lib/label-icon.d.ts +2 -2
- package/lib/modal-dialog.d.cts +67 -0
- package/lib/modal-dialog.d.ts +67 -0
- package/lib/nuxt.cjs +1 -1
- package/lib/nuxt.js +1 -1
- package/lib/overlay-box.d.cts +52 -0
- package/lib/overlay-box.d.ts +52 -0
- package/lib/page-section.d.cts +2 -2
- package/lib/page-section.d.ts +2 -2
- package/lib/page-title.d.cts +2 -2
- package/lib/page-title.d.ts +2 -2
- package/lib/register.cjs +1 -1
- package/lib/register.js +1 -1
- package/lib/screen-loading.d.cts +7 -0
- package/lib/screen-loading.d.ts +7 -0
- package/lib/style.css +1 -1
- package/lib/tab-content.d.cts +5 -5
- package/lib/tab-content.d.ts +5 -5
- package/lib/tab-group.d.cts +7 -10
- package/lib/tab-group.d.ts +7 -10
- package/lib/types/data-table.d.cts +185 -0
- package/lib/types/data-table.d.ts +185 -0
- package/lib/types/modal-dialog.d.cts +13 -0
- package/lib/types/modal-dialog.d.ts +13 -0
- package/lib/types/movable-window.d.cts +16 -0
- package/lib/types/movable-window.d.ts +16 -0
- package/lib/warning-popper.d.cts +39 -0
- package/lib/warning-popper.d.ts +39 -0
- package/lib/warning-popper.vue_vue_type_style_index_0_lang-CxVzqsbn.cjs +1 -0
- package/lib/warning-popper.vue_vue_type_style_index_0_lang-zt-jCsvz.js +1833 -0
- package/package.json +43 -16
- package/src/accordion-fieldset.vue +29 -19
- package/src/accordion-section.vue +41 -26
- package/src/components.ts +10 -0
- package/src/copy-button.vue +89 -0
- package/src/dark-mode-selector.vue +212 -0
- package/src/data-table.vue +643 -0
- package/src/help-button.vue +128 -0
- package/src/help-popper.vue +70 -0
- package/src/helpers/data-table-csv.ts +55 -0
- package/src/helpers/show-floating-component.ts +169 -0
- package/src/helpers/show-modal-dialog.ts +121 -0
- package/src/helpers/show-overlay-box.ts +106 -0
- package/src/helpers/show-screen-loading.ts +37 -0
- package/src/helpers/show-snackbar.ts +153 -0
- package/src/hourglass-loading.vue +1 -1
- package/src/index.ts +34 -0
- package/src/internal/anchored-popover.vue +192 -0
- package/src/internal/anchored-position.ts +135 -0
- package/src/internal/data-table-controls.vue +203 -0
- package/src/internal/data-table-value.ts +99 -0
- package/src/internal/floating-component.vue +202 -0
- package/src/internal/icon-popper.vue +185 -0
- package/src/internal/mount-window.ts +110 -0
- package/src/internal/movable-window.vue +315 -0
- package/src/internal/opened-overlay-boxes.ts +2 -0
- package/src/internal/pagination.vue +325 -0
- package/src/internal/snackbar-container.vue +258 -0
- package/src/internal/snackbar-item.ts +20 -0
- package/src/internal/tab-group-context.ts +4 -2
- package/src/internal/use-movable-window.ts +208 -0
- package/src/internal/window-order.ts +11 -0
- package/src/intersection-lazy-component.vue +84 -0
- package/src/label-button.vue +37 -3
- package/src/label-icon.vue +2 -2
- package/src/modal-dialog.vue +287 -0
- package/src/overlay-box.vue +218 -0
- package/src/page-section.vue +7 -7
- package/src/page-title.vue +5 -5
- package/src/screen-loading.vue +90 -0
- package/src/tab-content.vue +17 -16
- package/src/tab-group.vue +55 -46
- package/src/types/data-table.ts +196 -0
- package/src/types/modal-dialog.ts +16 -0
- package/src/types/movable-window.ts +18 -0
- package/src/warning-popper.vue +70 -0
- package/lib/accordion-fieldset.cjs +0 -1
- package/lib/accordion-fieldset.js +0 -4
- package/lib/accordion-fieldset.vue_vue_type_style_index_0_lang-n-IZxUiu.js +0 -66
- package/lib/accordion-fieldset.vue_vue_type_style_index_0_lang-t9NqmoZW.cjs +0 -1
- package/lib/accordion-section.cjs +0 -1
- package/lib/accordion-section.js +0 -4
- package/lib/accordion-section.vue_vue_type_style_index_0_lang-CFDdUEnn.cjs +0 -1
- package/lib/accordion-section.vue_vue_type_style_index_0_lang-Gvjjx02P.js +0 -78
- package/lib/components-CNOeuZPu.cjs +0 -1
- package/lib/components-DBK8NUBh.js +0 -24
- package/lib/hourglass-loading.cjs +0 -1
- package/lib/hourglass-loading.js +0 -4
- package/lib/hourglass-loading.vue_vue_type_style_index_0_lang-C72UVA9W.cjs +0 -1
- package/lib/hourglass-loading.vue_vue_type_style_index_0_lang-DkUGIxQ2.js +0 -22
- package/lib/label-button.cjs +0 -1
- package/lib/label-button.js +0 -4
- package/lib/label-button.vue_vue_type_script_setup_true_lang-BwVOxaJP.cjs +0 -1
- package/lib/label-button.vue_vue_type_script_setup_true_lang-DorC4pKz.js +0 -44
- package/lib/label-icon.cjs +0 -1
- package/lib/label-icon.js +0 -4
- package/lib/label-icon.vue_vue_type_style_index_0_lang-D9Cimu20.cjs +0 -1
- package/lib/label-icon.vue_vue_type_style_index_0_lang-me52HE2V.js +0 -38
- package/lib/page-section.cjs +0 -1
- package/lib/page-section.js +0 -4
- package/lib/page-section.vue_vue_type_style_index_0_lang-DEAkTLxd.cjs +0 -1
- package/lib/page-section.vue_vue_type_style_index_0_lang-DpVQe_rV.js +0 -54
- package/lib/page-title.cjs +0 -1
- package/lib/page-title.js +0 -4
- package/lib/page-title.vue_vue_type_style_index_0_lang-BqIsIks5.cjs +0 -1
- package/lib/page-title.vue_vue_type_style_index_0_lang-ChZot85K.js +0 -36
- package/lib/tab-content.cjs +0 -1
- package/lib/tab-content.js +0 -4
- package/lib/tab-content.vue_vue_type_style_index_0_lang-BeCi7Xkp.cjs +0 -1
- package/lib/tab-content.vue_vue_type_style_index_0_lang-CcQLHmIF.js +0 -44
- package/lib/tab-group.cjs +0 -1
- package/lib/tab-group.js +0 -4
- package/lib/tab-group.vue_vue_type_style_index_0_lang-C84mDEOC.js +0 -103
- package/lib/tab-group.vue_vue_type_style_index_0_lang-CMaufRJV.cjs +0 -1
- package/lib/use-shrinkable-CS2bmsJJ.js +0 -17
- package/lib/use-shrinkable-Cu9JQZll.cjs +0 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { onBeforeUnmount, reactive, ref } from 'vue';
|
|
2
|
+
import type { Ref } from 'vue';
|
|
3
|
+
import type { MovableWindowDragMode } from '@/types/movable-window';
|
|
4
|
+
|
|
5
|
+
/** ใชใตใคใบใงๆดใใงใใ่ง */
|
|
6
|
+
export type MovableWindowCorner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
7
|
+
|
|
8
|
+
interface MovableWindowOptions<T extends HTMLElement = HTMLElement> {
|
|
9
|
+
/** ใฆใฃใณใใฆๆฌไฝใฎ่ฆ็ด ใใใฉใใฐ็ตไบๆใซ็ป้ขๅ
ใธๆปใๅคๅฎใจใใชใตใคใบใฎ่ตท็นใฎๅฏธๆณใซไฝฟใ */
|
|
10
|
+
target: Ref<T | undefined>;
|
|
11
|
+
/** ใใฉใใฐใขใผใใ่ฟใ้ขๆฐใ'body' / 'header' ใฎใฉใกใใงใใชใๅ ดๅใฏใใฉใใฐใงใใชใ */
|
|
12
|
+
dragMode: () => MovableWindowDragMode | undefined;
|
|
13
|
+
/** ใชใตใคใบๆใฎๆๅฐๅน
(px) */
|
|
14
|
+
minWidth?: number;
|
|
15
|
+
/** ใชใตใคใบๆใฎๆๅฐ้ซใ(px) */
|
|
16
|
+
minHeight?: number;
|
|
17
|
+
/**
|
|
18
|
+
* ใใฉใใฐ็ตไบๆใซไธ็ซฏใ็ป้ขๅ
ใธๆปใใใ
|
|
19
|
+
* ในใฏใญใผใซใง้ ๅใๅบใใ้ๅธธใฎใใผใธไธใงใฏ falseใ็ป้ขใซๅบๅฎใใใฆใฃใณใใฆใงใฏ true ใซใใ
|
|
20
|
+
*/
|
|
21
|
+
clampBottom?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* ใฆใฃใณใใฆใฎใใฉใใฐใซใใ็งปๅใจใ่งใฎใคใพใฟใซใใใชใตใคใบใๆฑใใ
|
|
26
|
+
* ใใฆในใปใฟใใใปใใณใ Pointer Events ใงใพใจใใฆๆฑใใ
|
|
27
|
+
* ไฝ็ฝฎใปใตใคใบใฎใชใขใฏใใฃใใช็ถๆ
ใจใใใณใใฌใผใใฎ pointerdown ใซ็ตใณไปใใ้ๅงใใณใใฉใ่ฟใใ
|
|
28
|
+
* ๅๆไฝ็ฝฎใปๅๆใตใคใบใฏๅผใณๅบใๅดใๆฑบใใ
|
|
29
|
+
*
|
|
30
|
+
* @param {MovableWindowOptions<T>} options
|
|
31
|
+
*/
|
|
32
|
+
export function useMovableWindow<T extends HTMLElement = HTMLElement>(options: MovableWindowOptions<T>) {
|
|
33
|
+
const minWidth = options.minWidth ?? 20;
|
|
34
|
+
const minHeight = options.minHeight ?? 20;
|
|
35
|
+
|
|
36
|
+
const moving = ref(false);
|
|
37
|
+
const resizing = ref(false);
|
|
38
|
+
|
|
39
|
+
const currentPosition = reactive({
|
|
40
|
+
x: 0,
|
|
41
|
+
y: 0
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
/** ๅน
ใป้ซใ(px)ใ-1 ใฏๅฏธๆณใๆๅฎใใไธญ่บซใซๅใใใ */
|
|
45
|
+
const currentRect = reactive({
|
|
46
|
+
width: -1,
|
|
47
|
+
height: -1
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
/** ๆไฝไธญใฎใใคใณใฟใ2ๆฌ็ฎใฎๆใชใฉใๅฅใฎใใคใณใฟใฎๅใใๆพใใชใใใใซใใ */
|
|
51
|
+
let activePointerId: number | null = null;
|
|
52
|
+
let resizingCorner: MovableWindowCorner = 'bottom-right';
|
|
53
|
+
let previousPointer = {
|
|
54
|
+
x: 0,
|
|
55
|
+
y: 0
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const onPointerMove = (event: PointerEvent): void => {
|
|
59
|
+
if (event.pointerId !== activePointerId) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
event.preventDefault();
|
|
63
|
+
const movementX = event.clientX - previousPointer.x;
|
|
64
|
+
const movementY = event.clientY - previousPointer.y;
|
|
65
|
+
previousPointer = {
|
|
66
|
+
x: event.clientX,
|
|
67
|
+
y: event.clientY
|
|
68
|
+
};
|
|
69
|
+
if (moving.value) {
|
|
70
|
+
currentPosition.x += movementX;
|
|
71
|
+
currentPosition.y += movementY;
|
|
72
|
+
} else if (resizing.value) {
|
|
73
|
+
// ๅทฆใปไธใฎ่พบใๆดใใงใใใจใใฏใๅฎ้ใซ็ธฎใใ ๅใ ใไฝ็ฝฎใใใใใๆๅฐใตใคใบใซๅฝใใฃใใไฝ็ฝฎใๆญขใพใ
|
|
74
|
+
if (resizingCorner.endsWith('left')) {
|
|
75
|
+
const width = Math.max(minWidth, currentRect.width - movementX);
|
|
76
|
+
currentPosition.x += currentRect.width - width;
|
|
77
|
+
currentRect.width = width;
|
|
78
|
+
} else {
|
|
79
|
+
currentRect.width = Math.max(minWidth, currentRect.width + movementX);
|
|
80
|
+
}
|
|
81
|
+
if (resizingCorner.startsWith('top')) {
|
|
82
|
+
const height = Math.max(minHeight, currentRect.height - movementY);
|
|
83
|
+
currentPosition.y += currentRect.height - height;
|
|
84
|
+
currentRect.height = height;
|
|
85
|
+
} else {
|
|
86
|
+
currentRect.height = Math.max(minHeight, currentRect.height + movementY);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* ใใฉใใฐใง็ป้ขใฎๅคใธๅบใใใใใฆใฃใณใใฆใใๆดใใไฝ็ฝฎใพใงๆปใ
|
|
93
|
+
*/
|
|
94
|
+
const clampPosition = (): void => {
|
|
95
|
+
const width = options.target.value?.getBoundingClientRect().width || 0;
|
|
96
|
+
if (currentPosition.x < 40 - width) {
|
|
97
|
+
currentPosition.x = 40 - width;
|
|
98
|
+
}
|
|
99
|
+
if (window.innerWidth - 40 < currentPosition.x) {
|
|
100
|
+
currentPosition.x = window.innerWidth - 40;
|
|
101
|
+
}
|
|
102
|
+
if (currentPosition.y < 0) {
|
|
103
|
+
currentPosition.y = 0;
|
|
104
|
+
}
|
|
105
|
+
if (options.clampBottom && window.innerHeight - 20 < currentPosition.y) {
|
|
106
|
+
currentPosition.y = window.innerHeight - 20;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const onPointerEnd = (event: PointerEvent): void => {
|
|
111
|
+
if (event.pointerId !== activePointerId) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const wasMoving = moving.value;
|
|
115
|
+
teardown();
|
|
116
|
+
if (wasMoving) {
|
|
117
|
+
clampPosition();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* ็ป้ฒไธญใฎใใฉใใฐใปใชใตใคใบใฎใชในใใผใใในใฆ่งฃ้คใใใ
|
|
123
|
+
* ใขใณใใฆใณใใๅพ
ใใใซ่งฃ้คใใใใจใ(ใฆใฃใณใใฆใ้ใใใจใใชใฉ)ใซๅผใถ
|
|
124
|
+
*/
|
|
125
|
+
const teardown = (): void => {
|
|
126
|
+
document.removeEventListener('pointermove', onPointerMove, true);
|
|
127
|
+
document.removeEventListener('pointerup', onPointerEnd, true);
|
|
128
|
+
document.removeEventListener('pointercancel', onPointerEnd, true);
|
|
129
|
+
activePointerId = null;
|
|
130
|
+
moving.value = false;
|
|
131
|
+
resizing.value = false;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const start = (event: PointerEvent): void => {
|
|
135
|
+
teardown();
|
|
136
|
+
activePointerId = event.pointerId;
|
|
137
|
+
// ๆผใใไฝ็ฝฎใ็งปๅ้ใฎ่ตท็นใซใใใ่ตท็นใ็กใใจๆๅใฎ็งปๅ้ใๆจใฆใใใ
|
|
138
|
+
previousPointer = {
|
|
139
|
+
x: event.clientX,
|
|
140
|
+
y: event.clientY
|
|
141
|
+
};
|
|
142
|
+
document.addEventListener('pointermove', onPointerMove, true);
|
|
143
|
+
document.addEventListener('pointerup', onPointerEnd, true);
|
|
144
|
+
document.addEventListener('pointercancel', onPointerEnd, true);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* ใฆใฃใณใใฆๅ
จไฝใๆดใใ ใจใใฎใใฉใใฐ้ๅง
|
|
149
|
+
*
|
|
150
|
+
* @param {PointerEvent} event
|
|
151
|
+
*/
|
|
152
|
+
const onDragStart = (event: PointerEvent): void => {
|
|
153
|
+
if (event.isPrimary && options.dragMode() === 'body') {
|
|
154
|
+
start(event);
|
|
155
|
+
moving.value = true;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* ใใใใๆดใใ ใจใใฎใใฉใใฐ้ๅง
|
|
161
|
+
*
|
|
162
|
+
* @param {PointerEvent} event
|
|
163
|
+
*/
|
|
164
|
+
const onDragHeaderStart = (event: PointerEvent): void => {
|
|
165
|
+
if (event.isPrimary && options.dragMode() === 'header') {
|
|
166
|
+
start(event);
|
|
167
|
+
moving.value = true;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* ใชใตใคใบ้ๅง
|
|
173
|
+
*
|
|
174
|
+
* @param {PointerEvent} event
|
|
175
|
+
* @param {MovableWindowCorner} [corner] ๆดใใ ่งใๆขๅฎใฏๅณไธ
|
|
176
|
+
*/
|
|
177
|
+
const onResizeStart = (event: PointerEvent, corner: MovableWindowCorner = 'bottom-right'): void => {
|
|
178
|
+
if (!event.isPrimary) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
resizingCorner = corner;
|
|
182
|
+
// ๅน
ใป้ซใใๆชๆๅฎ(-1)ใฎใพใพใ ใจ็งปๅ้ใ่ถณใ่ตท็นใ็กใๆๅฐใตใคใบใซๆฝฐใใใใใๅฎๅฏธใ่ตท็นใซใใ
|
|
183
|
+
const rect = options.target.value?.getBoundingClientRect();
|
|
184
|
+
if (rect) {
|
|
185
|
+
if (currentRect.width < 0) {
|
|
186
|
+
currentRect.width = rect.width;
|
|
187
|
+
}
|
|
188
|
+
if (currentRect.height < 0) {
|
|
189
|
+
currentRect.height = rect.height;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
start(event);
|
|
193
|
+
resizing.value = true;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
onBeforeUnmount(teardown);
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
moving,
|
|
200
|
+
resizing,
|
|
201
|
+
currentPosition,
|
|
202
|
+
currentRect,
|
|
203
|
+
onDragStart,
|
|
204
|
+
onDragHeaderStart,
|
|
205
|
+
onResizeStart,
|
|
206
|
+
teardown
|
|
207
|
+
};
|
|
208
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
let lastOrder = 0;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ใฆใฃใณใใฆ(OverlayBox / FloatingComponent)ใฎ้ใชใ้ ใ่ฟใใๅพใใๅผใใ ใใฎใปใฉๅคงใใใๅ้ขใซๅบใ
|
|
5
|
+
*
|
|
6
|
+
* @returns {number}
|
|
7
|
+
*/
|
|
8
|
+
export const nextWindowOrder = (): number => {
|
|
9
|
+
lastOrder += 1;
|
|
10
|
+
return lastOrder;
|
|
11
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
ในใฏใญใผใซใซๅฟใใฆใๅฝ่ฉฒ้ ๅใ็ป้ข่กจ็คบ้ ๅใซใชใฃใใจใใซใณใณใใณใใๆ็ปใใใณใณใใผใใณใ
|
|
3
|
+
ไธๅบฆๆ็ปใใใใ่กจ็คบ้ ๅใใๅคใใฆใๆ็ปใใใพใพใซใใใ
|
|
4
|
+
IntersectionObserver ใฏใใฉใฆใถใซใใ็กใใฎใงใใใฆใณใๅพใซ็ๆใใใ
|
|
5
|
+
root ใซใใณใใฌใผใๅ็
งใๆธกใใจใใใฎใณใณใใผใใณใใฎใใฆใณใๆใซใฏใพใ ่ฆ็ด ใๅ
ฅใฃใฆใใชใใใใใชใใทใงใณใๅคใใฃใใ็ฃ่ฆใใใ็ดใใ
|
|
6
|
+
-->
|
|
7
|
+
<template>
|
|
8
|
+
<div
|
|
9
|
+
ref="refTarget"
|
|
10
|
+
class="dwui-intersection-lazy-component"
|
|
11
|
+
>
|
|
12
|
+
<slot v-if="visible" />
|
|
13
|
+
<slot
|
|
14
|
+
v-else
|
|
15
|
+
name="placeholder"
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script setup lang="ts">
|
|
21
|
+
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
|
22
|
+
|
|
23
|
+
export interface Props {
|
|
24
|
+
/** ไบคๅทฎใๅคๅฎใใในใฏใญใผใซ้ ๅใฎ่ฆ็ด ใๆชๆๅฎใชใใใฅใผใใผใ */
|
|
25
|
+
root?: Element | null;
|
|
26
|
+
/** ๅคๅฎใใ้ ๅใ root ใฎ็ซฏใใๅบใใใใพใใฏ็ญใใ้ใCSS ใฎ margin ใจๅใๆธๅผ */
|
|
27
|
+
rootMargin?: string;
|
|
28
|
+
/** ไธญ่บซใๆ็ปใใไบคๅทฎใฎๅฒๅ(0ใ1)ใ้
ๅใๆธกใใ */
|
|
29
|
+
threshold?: number | number[];
|
|
30
|
+
}
|
|
31
|
+
const props = defineProps<Props>();
|
|
32
|
+
|
|
33
|
+
export interface Emits {
|
|
34
|
+
/** ๅใใฆ็ป้ขใซๅ
ฅใฃใฆไธญ่บซใๆ็ปใใใจใใซ็บ่กใใ */
|
|
35
|
+
(e: 'emit:visible'): void;
|
|
36
|
+
}
|
|
37
|
+
const emit = defineEmits<Emits>();
|
|
38
|
+
|
|
39
|
+
export interface Slots {
|
|
40
|
+
/** ็ป้ขใซๅ
ฅใฃใฆใใๆ็ปใใไธญ่บซ */
|
|
41
|
+
default?(): unknown;
|
|
42
|
+
/** ็ป้ขใซๅ
ฅใใพใงใฎ้ใซ่กจ็คบใใไธญ่บซ */
|
|
43
|
+
placeholder?(): unknown;
|
|
44
|
+
}
|
|
45
|
+
defineSlots<Slots>();
|
|
46
|
+
|
|
47
|
+
const refTarget = ref<HTMLElement>();
|
|
48
|
+
const visible = ref(false);
|
|
49
|
+
|
|
50
|
+
let observer: IntersectionObserver | undefined;
|
|
51
|
+
|
|
52
|
+
const observe = (): void => {
|
|
53
|
+
observer?.disconnect();
|
|
54
|
+
observer = undefined;
|
|
55
|
+
if (!refTarget.value || visible.value) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
observer = new IntersectionObserver((entries) => {
|
|
59
|
+
if (entries.some((entry) => entry.isIntersecting)) {
|
|
60
|
+
visible.value = true;
|
|
61
|
+
observer?.disconnect();
|
|
62
|
+
observer = undefined;
|
|
63
|
+
emit('emit:visible');
|
|
64
|
+
}
|
|
65
|
+
}, {
|
|
66
|
+
root: props.root,
|
|
67
|
+
rootMargin: props.rootMargin,
|
|
68
|
+
threshold: props.threshold
|
|
69
|
+
});
|
|
70
|
+
observer.observe(refTarget.value);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
onMounted(() => {
|
|
74
|
+
observe();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
onBeforeUnmount(() => {
|
|
78
|
+
observer?.disconnect();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
watch(() => [props.root, props.rootMargin, props.threshold], () => {
|
|
82
|
+
observe();
|
|
83
|
+
}, { flush: 'post' });
|
|
84
|
+
</script>
|
package/src/label-button.vue
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
ใขใคใณใณใจใฉใใซใๆใคใใฟใณ
|
|
3
3
|
-->
|
|
4
4
|
<template>
|
|
5
|
-
<button
|
|
5
|
+
<button
|
|
6
|
+
type="button"
|
|
7
|
+
class="dwui-label-button"
|
|
8
|
+
>
|
|
6
9
|
<LabelIcon
|
|
7
10
|
:preset="props.preset"
|
|
8
11
|
:gap="props.gap"
|
|
@@ -33,7 +36,7 @@ import type { ClassValue, StyleValue } from 'vue';
|
|
|
33
36
|
import LabelIcon from '@/label-icon.vue';
|
|
34
37
|
import type { LabelPreset } from '@/types/label-preset';
|
|
35
38
|
|
|
36
|
-
interface Props {
|
|
39
|
+
export interface Props {
|
|
37
40
|
/** ใขใคใณใณใจใฉใใซใฎ็ตใฟๅใใ */
|
|
38
41
|
preset?: LabelPreset;
|
|
39
42
|
/** ใขใคใณใณใจใฉใใซใฎ้้ใๆชๆๅฎใชใLabelIconใฎๆขๅฎๅค(0.25em) */
|
|
@@ -49,9 +52,40 @@ interface Props {
|
|
|
49
52
|
}
|
|
50
53
|
const props = defineProps<Props>();
|
|
51
54
|
|
|
52
|
-
interface Slots {
|
|
55
|
+
export interface Slots {
|
|
53
56
|
icon?(): unknown;
|
|
54
57
|
default?(): unknown;
|
|
55
58
|
}
|
|
56
59
|
const slots = defineSlots<Slots>();
|
|
57
60
|
</script>
|
|
61
|
+
|
|
62
|
+
<style>
|
|
63
|
+
:where(.dwui-label-button) {
|
|
64
|
+
display: inline-block;
|
|
65
|
+
padding: 0.17em 0.5em;
|
|
66
|
+
border: 1px solid var(--dwui-border-color-label-button, light-dark(#8f8f8f, #6b6f76));
|
|
67
|
+
border-radius: 3px;
|
|
68
|
+
background: var(--dwui-background-label-button, light-dark(#f4f4f4, #3a3c40));
|
|
69
|
+
color: var(--dwui-color-text-label-button, light-dark(#1a1a1a, #e6e6e6));
|
|
70
|
+
font: inherit;
|
|
71
|
+
cursor: pointer;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
:where(.dwui-label-button:not(:disabled):hover) {
|
|
75
|
+
background: var(--dwui-background-label-button-hover, light-dark(#e6e6e6, #474a50));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
:where(.dwui-label-button:not(:disabled):active) {
|
|
79
|
+
background: var(--dwui-background-label-button-active, light-dark(#d6d6d6, #2f3135));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
:where(.dwui-label-button:disabled) {
|
|
83
|
+
opacity: 0.6;
|
|
84
|
+
cursor: not-allowed;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:where(.dwui-label-button:focus-visible) {
|
|
88
|
+
outline: var(--dwui-outline-width-focus-ring, 2px) solid var(--dwui-outline-color-focus-ring, Highlight);
|
|
89
|
+
outline-offset: var(--dwui-outline-offset-focus-ring, 2px);
|
|
90
|
+
}
|
|
91
|
+
</style>
|
package/src/label-icon.vue
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
import type { ClassValue, StyleValue } from 'vue';
|
|
32
32
|
import type { LabelPreset } from '@/types/label-preset';
|
|
33
33
|
|
|
34
|
-
interface Props {
|
|
34
|
+
export interface Props {
|
|
35
35
|
/** ใขใคใณใณใจใฉใใซใฎ็ตใฟๅใใ */
|
|
36
36
|
preset?: LabelPreset;
|
|
37
37
|
/** ใขใคใณใณใจใฉใใซใฎ้้ใๆชๆๅฎใชใๆขๅฎๅค(0.25em) */
|
|
@@ -47,7 +47,7 @@ interface Props {
|
|
|
47
47
|
}
|
|
48
48
|
const props = defineProps<Props>();
|
|
49
49
|
|
|
50
|
-
interface Slots {
|
|
50
|
+
export interface Slots {
|
|
51
51
|
icon?(): unknown;
|
|
52
52
|
default?(): unknown;
|
|
53
53
|
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
ใขใผใใซใใคใขใญใฐ
|
|
3
|
+
ใใฉใฆใถๆจๆบใฎ <dialog> ใ showModal() ใง้ใใใกใใปใผใธใจ OKใใพใใฏ Yes / No ใฎใใฟใณใ่กจ็คบใใใ
|
|
4
|
+
ใใฟใณใ Esc ใง้ใใ้ใใใใฟใณใ close ใคใใณใใง็ฅใใใใ
|
|
5
|
+
-->
|
|
6
|
+
<template>
|
|
7
|
+
<dialog
|
|
8
|
+
ref="refDialog"
|
|
9
|
+
class="dwui-modal-dialog"
|
|
10
|
+
:class="`dwui-modal-dialog-${props.type}`"
|
|
11
|
+
:aria-labelledby="props.title ? titleId : undefined"
|
|
12
|
+
:aria-describedby="bodyId"
|
|
13
|
+
@cancel="onCancelDialog"
|
|
14
|
+
@keydown="onKeydownDialog"
|
|
15
|
+
>
|
|
16
|
+
<div class="dwui-modal-dialog-header">
|
|
17
|
+
<span class="dwui-modal-dialog-icon">
|
|
18
|
+
<slot name="icon">
|
|
19
|
+
<component :is="icons[props.type]" />
|
|
20
|
+
</slot>
|
|
21
|
+
</span>
|
|
22
|
+
<template v-if="props.title">
|
|
23
|
+
<span
|
|
24
|
+
v-if="props.html"
|
|
25
|
+
:id="titleId"
|
|
26
|
+
class="dwui-modal-dialog-title"
|
|
27
|
+
v-html="props.title"
|
|
28
|
+
/>
|
|
29
|
+
<span
|
|
30
|
+
v-else
|
|
31
|
+
:id="titleId"
|
|
32
|
+
class="dwui-modal-dialog-title"
|
|
33
|
+
>
|
|
34
|
+
{{ props.title }}
|
|
35
|
+
</span>
|
|
36
|
+
</template>
|
|
37
|
+
</div>
|
|
38
|
+
<div
|
|
39
|
+
:id="bodyId"
|
|
40
|
+
class="dwui-modal-dialog-body"
|
|
41
|
+
>
|
|
42
|
+
<slot>
|
|
43
|
+
<template
|
|
44
|
+
v-for="(text, index) in messages"
|
|
45
|
+
:key="index"
|
|
46
|
+
>
|
|
47
|
+
<p
|
|
48
|
+
v-if="props.html"
|
|
49
|
+
v-html="text"
|
|
50
|
+
/>
|
|
51
|
+
<p v-else>{{ text }}</p>
|
|
52
|
+
</template>
|
|
53
|
+
<div
|
|
54
|
+
v-if="images.length"
|
|
55
|
+
class="dwui-modal-dialog-images"
|
|
56
|
+
>
|
|
57
|
+
<img
|
|
58
|
+
v-for="(item, index) in images"
|
|
59
|
+
:key="index"
|
|
60
|
+
:src="item.src"
|
|
61
|
+
:alt="item.alt"
|
|
62
|
+
>
|
|
63
|
+
</div>
|
|
64
|
+
</slot>
|
|
65
|
+
</div>
|
|
66
|
+
<div
|
|
67
|
+
ref="refButtons"
|
|
68
|
+
class="dwui-modal-dialog-buttons"
|
|
69
|
+
>
|
|
70
|
+
<button
|
|
71
|
+
v-for="button in buttons"
|
|
72
|
+
:key="button"
|
|
73
|
+
type="button"
|
|
74
|
+
class="dwui-modal-dialog-button"
|
|
75
|
+
:class="`dwui-modal-dialog-button-${button}`"
|
|
76
|
+
@click="onClickButton(button)"
|
|
77
|
+
>
|
|
78
|
+
{{ labels[button] }}
|
|
79
|
+
</button>
|
|
80
|
+
</div>
|
|
81
|
+
</dialog>
|
|
82
|
+
</template>
|
|
83
|
+
|
|
84
|
+
<script setup lang="ts">
|
|
85
|
+
import { computed, onMounted, ref, useId, watch } from 'vue';
|
|
86
|
+
import { SvgCritical, SvgInfo, SvgQuestion, SvgWarningSign } from '@digitalwalletcorp/vue-svg-icons';
|
|
87
|
+
import type { ModalDialogButton, ModalDialogImage, ModalDialogResult, ModalDialogType } from '@/types/modal-dialog';
|
|
88
|
+
|
|
89
|
+
export interface Props {
|
|
90
|
+
/** ใใคใขใญใฐใฎ็จฎ้ก */
|
|
91
|
+
type?: ModalDialogType;
|
|
92
|
+
/** ่ฆๅบใ */
|
|
93
|
+
title?: string;
|
|
94
|
+
/** ่กจ็คบใใๆๅญๅใ้
ๅใชใ1่ฆ็ด ใ1ๆฎต่ฝใจใใฆ่กจ็คบใใ */
|
|
95
|
+
message?: string | string[];
|
|
96
|
+
/** true ใฎๅ ดๅใ่ฆๅบใใจใกใใปใผใธใ HTML ใจใใฆ่กจ็คบใใ */
|
|
97
|
+
html?: boolean;
|
|
98
|
+
/** ใกใใปใผใธใฎไธใซไธฆในใ็ปๅ */
|
|
99
|
+
image?: ModalDialogImage | ModalDialogImage[];
|
|
100
|
+
/** ๅทฆใใ้ ใซไธฆในใใใฟใณใๆชๆๅฎใชใ confirm ใฏ Yes ใจ Noใใใไปฅๅคใฏ OK */
|
|
101
|
+
buttons?: ModalDialogButton[];
|
|
102
|
+
/** OK ใใฟใณใฎๆๅญ */
|
|
103
|
+
okLabel?: string;
|
|
104
|
+
/** Yes ใใฟใณใฎๆๅญ */
|
|
105
|
+
yesLabel?: string;
|
|
106
|
+
/** No ใใฟใณใฎๆๅญ */
|
|
107
|
+
noLabel?: string;
|
|
108
|
+
/** Cancel ใใฟใณใฎๆๅญ */
|
|
109
|
+
cancelLabel?: string;
|
|
110
|
+
}
|
|
111
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
112
|
+
type: 'info',
|
|
113
|
+
title: undefined,
|
|
114
|
+
message: undefined,
|
|
115
|
+
html: false,
|
|
116
|
+
image: undefined,
|
|
117
|
+
buttons: undefined,
|
|
118
|
+
okLabel: 'OK',
|
|
119
|
+
yesLabel: 'Yes',
|
|
120
|
+
noLabel: 'No',
|
|
121
|
+
cancelLabel: 'Cancel'
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
export interface Emits {
|
|
125
|
+
/** ใใฟใณใ Esc ใงใใคใขใญใฐใ้ใใ */
|
|
126
|
+
(e: 'emit:close', result: ModalDialogResult): void;
|
|
127
|
+
}
|
|
128
|
+
const emit = defineEmits<Emits>();
|
|
129
|
+
|
|
130
|
+
export interface Slots {
|
|
131
|
+
/** ่ฆๅบใใฎๅทฆใซๅบใใขใคใณใณ */
|
|
132
|
+
icon?(): unknown;
|
|
133
|
+
/** ใกใใปใผใธใจ็ปๅใซไปฃใใฆ่กจ็คบใใไธญ่บซ */
|
|
134
|
+
default?(): unknown;
|
|
135
|
+
}
|
|
136
|
+
defineSlots<Slots>();
|
|
137
|
+
|
|
138
|
+
/** ่กจ็คบใใใใใใฟใณใ Esc ใง้ใใใจ false ใซใชใ */
|
|
139
|
+
const open = defineModel<boolean>('open', { default: false });
|
|
140
|
+
|
|
141
|
+
const refDialog = ref<HTMLDialogElement>();
|
|
142
|
+
const refButtons = ref<HTMLElement>();
|
|
143
|
+
|
|
144
|
+
const titleId = useId();
|
|
145
|
+
const bodyId = useId();
|
|
146
|
+
const icons = {
|
|
147
|
+
info: SvgInfo,
|
|
148
|
+
confirm: SvgQuestion,
|
|
149
|
+
warn: SvgWarningSign,
|
|
150
|
+
error: SvgCritical
|
|
151
|
+
};
|
|
152
|
+
/** ้ใใใจใใซใใฉใผใซในใใใใฟใณใฎๅชๅ
้ ใๆไฝใๅใๆถใๅดใฎใใฟใณใๅชๅ
ใใ */
|
|
153
|
+
const focusOrder: ModalDialogButton[] = ['cancel', 'no', 'yes', 'ok'];
|
|
154
|
+
|
|
155
|
+
const buttons = computed((): ModalDialogButton[] => props.buttons ?? (props.type === 'confirm' ? ['yes', 'no'] : ['ok']));
|
|
156
|
+
|
|
157
|
+
const labels = computed((): Record<ModalDialogButton, string> => ({
|
|
158
|
+
ok: props.okLabel,
|
|
159
|
+
yes: props.yesLabel,
|
|
160
|
+
no: props.noLabel,
|
|
161
|
+
cancel: props.cancelLabel
|
|
162
|
+
}));
|
|
163
|
+
|
|
164
|
+
const messages = computed((): string[] => props.message == null ? [] : [props.message].flat());
|
|
165
|
+
|
|
166
|
+
const images = computed((): Exclude<ModalDialogImage, string>[] => [props.image ?? []].flat().map((image) => {
|
|
167
|
+
if (typeof image === 'string') {
|
|
168
|
+
return {
|
|
169
|
+
src: image,
|
|
170
|
+
alt: ''
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return image;
|
|
174
|
+
}));
|
|
175
|
+
|
|
176
|
+
const onClickButton = (result: ModalDialogResult): void => {
|
|
177
|
+
closeDialog(result);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const onCancelDialog = (event: Event): void => {
|
|
181
|
+
event.preventDefault();
|
|
182
|
+
closeDialog('cancel');
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const onKeydownDialog = (event: KeyboardEvent): void => {
|
|
186
|
+
if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const elements = [...refButtons.value?.children ?? []] as HTMLElement[];
|
|
190
|
+
const index = elements.indexOf(document.activeElement as HTMLElement);
|
|
191
|
+
if (index < 0) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
elements[event.key === 'ArrowRight' ? index + 1 : index - 1]?.focus();
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const showDialog = (): void => {
|
|
198
|
+
refDialog.value?.showModal();
|
|
199
|
+
const focused = focusOrder.find((button) => buttons.value.includes(button));
|
|
200
|
+
const index = focused ? buttons.value.indexOf(focused) : -1;
|
|
201
|
+
(refButtons.value?.children[index] as HTMLElement | undefined)?.focus();
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const closeDialog = (result: ModalDialogResult): void => {
|
|
205
|
+
// close ใๅใใฆใใใซใขใณใใฆใณใใใใฆใใใใคใขใญใฐใ้ใใฆใใฉใผใซในใๆปใใใๅ
ใซ้ใใ
|
|
206
|
+
refDialog.value?.close();
|
|
207
|
+
open.value = false;
|
|
208
|
+
emit('emit:close', result);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
onMounted(() => {
|
|
212
|
+
if (open.value) {
|
|
213
|
+
showDialog();
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
watch(open, (newValue) => {
|
|
218
|
+
if (newValue) {
|
|
219
|
+
showDialog();
|
|
220
|
+
} else {
|
|
221
|
+
refDialog.value?.close();
|
|
222
|
+
}
|
|
223
|
+
}, { flush: 'post' });
|
|
224
|
+
</script>
|
|
225
|
+
|
|
226
|
+
<style>
|
|
227
|
+
:where(.dwui-modal-dialog) {
|
|
228
|
+
box-sizing: border-box;
|
|
229
|
+
width: var(--dwui-width-modal-dialog, 50vw);
|
|
230
|
+
min-width: min(320px, 100%);
|
|
231
|
+
padding: var(--dwui-padding-modal-dialog, 1.67em 2.5em);
|
|
232
|
+
border: 1px solid var(--dwui-border-color-modal-dialog, light-dark(#8f8f8f, #6b6f76));
|
|
233
|
+
border-radius: var(--dwui-radius-modal-dialog, 4px);
|
|
234
|
+
background: var(--dwui-background-modal-dialog, Canvas);
|
|
235
|
+
color: var(--dwui-color-text-modal-dialog, CanvasText);
|
|
236
|
+
box-shadow: var(--dwui-box-shadow-modal-dialog, 0 2px 8px rgba(0, 0, 0, 0.33));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
:where(.dwui-modal-dialog)::backdrop {
|
|
240
|
+
background: var(--dwui-background-modal-dialog-backdrop, rgba(0, 0, 0, 0.5));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
:where(.dwui-modal-dialog-header) {
|
|
244
|
+
display: flex;
|
|
245
|
+
align-items: center;
|
|
246
|
+
gap: 0.33em;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
:where(.dwui-modal-dialog-icon) {
|
|
250
|
+
display: flex;
|
|
251
|
+
flex: none;
|
|
252
|
+
font-size: var(--dwui-font-size-modal-dialog-icon, 1.83em);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
:where(.dwui-modal-dialog-body) {
|
|
256
|
+
padding: 0.83em;
|
|
257
|
+
overflow-wrap: anywhere;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
:where(.dwui-modal-dialog-body p) {
|
|
261
|
+
margin: 0;
|
|
262
|
+
white-space: pre-wrap;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
:where(.dwui-modal-dialog-images) {
|
|
266
|
+
display: flex;
|
|
267
|
+
flex-wrap: wrap;
|
|
268
|
+
gap: 0.33em;
|
|
269
|
+
margin-top: 0.67em;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
:where(.dwui-modal-dialog-images img) {
|
|
273
|
+
width: var(--dwui-width-modal-dialog-image, 200px);
|
|
274
|
+
max-width: 100%;
|
|
275
|
+
height: auto;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
:where(.dwui-modal-dialog-buttons) {
|
|
279
|
+
display: flex;
|
|
280
|
+
justify-content: space-evenly;
|
|
281
|
+
padding: 0.83em;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
:where(.dwui-modal-dialog-button) {
|
|
285
|
+
min-width: var(--dwui-min-width-modal-dialog-button, 80px);
|
|
286
|
+
}
|
|
287
|
+
</style>
|