sodialog 0.1.14 → 0.1.16
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 +119 -4
- package/dist/sodialog.css +1 -1
- package/dist/sodialog.es.js +456 -239
- package/dist/sodialog.umd.js +1 -1
- package/dist/types/lib.d.ts +39 -2
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
基于 HTML5 `dialog` 的可复用弹窗库,支持 **Modal** 与 **Offcanvas**,并通过 JavaScript 动态创建 HTML 元素。
|
|
4
4
|
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
- [安装](#安装)
|
|
8
|
+
- [使用](#使用)
|
|
9
|
+
- [API](#api)
|
|
10
|
+
- [Promise API](#promise-api)
|
|
11
|
+
- [Toast 常见示例](#toast-常见示例)
|
|
12
|
+
- [开发](#开发)
|
|
13
|
+
- [GitHub Pages 首页](#github-pages-首页)
|
|
14
|
+
- [文档体系](#文档体系)
|
|
15
|
+
- [发布到 NPM](#发布到-npm)
|
|
16
|
+
|
|
5
17
|
## 安装
|
|
6
18
|
|
|
7
19
|
```bash
|
|
@@ -11,7 +23,7 @@ npm install sodialog
|
|
|
11
23
|
## 使用
|
|
12
24
|
|
|
13
25
|
```ts
|
|
14
|
-
import { openModal, openOffcanvas } from 'sodialog'
|
|
26
|
+
import { openModal, openOffcanvas, confirmModal, promptModal, toast } from 'sodialog'
|
|
15
27
|
import 'sodialog/style.css'
|
|
16
28
|
|
|
17
29
|
openModal({
|
|
@@ -35,9 +47,6 @@ openOffcanvas({
|
|
|
35
47
|
content: '<p>这是 Offcanvas</p>',
|
|
36
48
|
})
|
|
37
49
|
|
|
38
|
-
// Toast
|
|
39
|
-
import { toast } from 'sodialog'
|
|
40
|
-
|
|
41
50
|
toast({
|
|
42
51
|
title: '保存成功',
|
|
43
52
|
content: '配置已更新',
|
|
@@ -46,6 +55,20 @@ toast({
|
|
|
46
55
|
duration: 2500,
|
|
47
56
|
maxVisible: 3,
|
|
48
57
|
})
|
|
58
|
+
|
|
59
|
+
const ok = await confirmModal({
|
|
60
|
+
title: '删除确认',
|
|
61
|
+
content: '<p>确定删除当前记录吗?</p>',
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
if (ok) {
|
|
65
|
+
const name = await promptModal({
|
|
66
|
+
title: '请输入备注',
|
|
67
|
+
placeholder: '操作备注',
|
|
68
|
+
validate: (value) => (value.length < 2 ? '至少输入 2 个字符' : true),
|
|
69
|
+
})
|
|
70
|
+
console.log('prompt result:', name)
|
|
71
|
+
}
|
|
49
72
|
```
|
|
50
73
|
|
|
51
74
|
## API
|
|
@@ -81,6 +104,11 @@ toast({
|
|
|
81
104
|
- `onConfirm?: () => void`
|
|
82
105
|
- `onCancel?: () => void`
|
|
83
106
|
- `onAction?: (context) => void`(监听所有 footer 按钮动作)
|
|
107
|
+
- `onBeforeOpen?: (context) => void`
|
|
108
|
+
- `onAfterOpen?: (context) => void`
|
|
109
|
+
- `onBeforeClose?: (context) => void`
|
|
110
|
+
- `onAfterClose?: (context) => void`
|
|
111
|
+
- `onLifecycle?: (context) => void`(统一监听所有生命周期阶段)
|
|
84
112
|
- `handle.setFooterButtons(buttons): void`(运行时整体替换 footer 按钮)
|
|
85
113
|
- `handle.updateFooterButton(id, updates): boolean`(按 id 更新某个 footer 按钮)
|
|
86
114
|
- `handle.onAction(listener): () => void`(追加动作监听,返回取消监听函数)
|
|
@@ -155,6 +183,22 @@ openOffcanvas({ title: 'Bottom', placement: 'bottom', animation: 'zoom', content
|
|
|
155
183
|
|
|
156
184
|
通用入口,`options.kind` 可为 `modal` 或 `offcanvas`。
|
|
157
185
|
|
|
186
|
+
## Promise API
|
|
187
|
+
|
|
188
|
+
### `SoDialog.confirm(options)` / `confirmModal(options)`
|
|
189
|
+
|
|
190
|
+
- 返回 `Promise<boolean>`
|
|
191
|
+
- 确认按钮 resolve `true`
|
|
192
|
+
- 取消、Esc、点击遮罩、关闭按钮 resolve `false`
|
|
193
|
+
|
|
194
|
+
### `SoDialog.prompt(options)` / `promptModal(options)`
|
|
195
|
+
|
|
196
|
+
- 返回 `Promise<string | null>`
|
|
197
|
+
- 确认返回输入值,取消返回 `null`
|
|
198
|
+
- 支持 `defaultValue`、`placeholder`、`inputType`
|
|
199
|
+
- 支持 `trimResult`(默认 `true`)
|
|
200
|
+
- 支持 `validate(value)`,返回 `string`/`false` 可阻止关闭并显示错误
|
|
201
|
+
|
|
158
202
|
### `toast(options)` / `SoToast.show(options)`
|
|
159
203
|
|
|
160
204
|
- `content: string | Node`
|
|
@@ -168,6 +212,11 @@ openOffcanvas({ title: 'Bottom', placement: 'bottom', animation: 'zoom', content
|
|
|
168
212
|
- `pauseOnHover?: boolean`(默认 `true`)
|
|
169
213
|
- `pauseOnWindowBlur?: boolean`(默认 `false`,切换窗口时暂停倒计时)
|
|
170
214
|
- `duplicateStrategy?: 'update' | 'ignore' | 'restart-timer' | 'stack'`(默认 `update`)
|
|
215
|
+
- `onBeforeOpen?: (context) => void`
|
|
216
|
+
- `onAfterOpen?: (context) => void`
|
|
217
|
+
- `onBeforeClose?: (context) => void`
|
|
218
|
+
- `onAfterClose?: (context) => void`
|
|
219
|
+
- `onLifecycle?: (context) => void`(统一监听所有生命周期阶段)
|
|
171
220
|
- `onShown?: (handle) => void`
|
|
172
221
|
- `onClose?: (reason, handle) => void`
|
|
173
222
|
|
|
@@ -184,6 +233,72 @@ openOffcanvas({ title: 'Bottom', placement: 'bottom', animation: 'zoom', content
|
|
|
184
233
|
- 可用 `SoToast.closeAll()` 清空全部 toast
|
|
185
234
|
- 便捷方法:`SoToast.success/error/info/warning`
|
|
186
235
|
|
|
236
|
+
### 统一生命周期 context
|
|
237
|
+
|
|
238
|
+
生命周期回调会收到统一结构:
|
|
239
|
+
|
|
240
|
+
- `component: 'modal' | 'offcanvas' | 'toast'`
|
|
241
|
+
- `phase: 'before-open' | 'after-open' | 'before-close' | 'after-close'`
|
|
242
|
+
- `id?: string`
|
|
243
|
+
- `reason?: string`
|
|
244
|
+
- `element: HTMLElement`
|
|
245
|
+
|
|
246
|
+
### `duplicateStrategy` 行为说明
|
|
247
|
+
|
|
248
|
+
- `update`:更新已有同 ID toast,保留单实例
|
|
249
|
+
- `ignore`:同 ID 已存在时直接忽略
|
|
250
|
+
- `restart-timer`:更新内容并重新开始倒计时
|
|
251
|
+
- `stack`:自动生成新 ID,允许同来源消息堆叠
|
|
252
|
+
|
|
253
|
+
## Toast 常见示例
|
|
254
|
+
|
|
255
|
+
### 1) 成功提示(默认 3 秒自动消失)
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
toast({
|
|
259
|
+
title: '保存成功',
|
|
260
|
+
content: '配置已同步到服务器',
|
|
261
|
+
variant: 'success',
|
|
262
|
+
})
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### 2) 错误提示(常驻 + 手动关闭)
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
toast({
|
|
269
|
+
title: '提交失败',
|
|
270
|
+
content: '网络连接异常,请稍后重试',
|
|
271
|
+
variant: 'danger',
|
|
272
|
+
duration: false,
|
|
273
|
+
placement: 'bottom-end',
|
|
274
|
+
})
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 3) 固定 ID 去重(重复触发时重置计时)
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
toast({
|
|
281
|
+
id: 'sync-job',
|
|
282
|
+
title: '同步任务',
|
|
283
|
+
content: '正在更新数据...',
|
|
284
|
+
duplicateStrategy: 'restart-timer',
|
|
285
|
+
duration: 2200,
|
|
286
|
+
})
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### 4) 全局默认配置
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
import { SoToast } from 'sodialog'
|
|
293
|
+
|
|
294
|
+
SoToast.configure({
|
|
295
|
+
placement: 'top-end',
|
|
296
|
+
maxVisible: 4,
|
|
297
|
+
pauseOnWindowBlur: true,
|
|
298
|
+
showProgress: true,
|
|
299
|
+
})
|
|
300
|
+
```
|
|
301
|
+
|
|
187
302
|
## 开发
|
|
188
303
|
|
|
189
304
|
```bash
|
package/dist/sodialog.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.sod-dialog{border:0;padding:0;margin:auto;background:transparent;max-width:none;max-height:none;overflow:visible}.sod-dialog::backdrop{background:#0000007f}.sod-panel{box-sizing:border-box;background:#fff;color:#212529;border-radius:.5rem;box-shadow:0 .5rem 1rem #00000040;min-width:min(520px,calc(100vw - 2rem));max-width:min(520px,calc(100vw - 2rem))}.sod-modal .sod-panel{position:relative;margin:0}.sod-modal[open]{width:100vw;height:100vh;display:flex;justify-content:center;align-items:center}.sod-modal[open].sod-modal-viewport-scroll{align-items:flex-start;overflow:auto;padding:1rem 0}.sod-modal .sod-panel.sod-modal-pos-center{align-self:center}.sod-modal .sod-panel.sod-modal-pos-top{align-self:flex-start;margin-top:1rem}.sod-modal .sod-panel.sod-modal-pos-bottom{align-self:flex-end;margin-bottom:1rem}.sod-modal .sod-panel.sod-modal-autofit{min-width:0;width:auto;height:auto;max-width:calc(100vw - 2rem);max-height:calc(100vh - 2rem);display:flex;flex-direction:column}.sod-modal .sod-panel.sod-modal-draggable{touch-action:none}.sod-modal .sod-panel.sod-is-dragging{animation:none!important;transition:none!important}.sod-modal .sod-panel .sod-drag-handle{cursor:move;-webkit-user-select:none;user-select:none}.sod-modal .sod-panel .sod-drag-handle.is-dragging{cursor:grabbing}.sod-modal .sod-panel.sod-modal-anim-fade{animation:sod-fade-in .18s ease-out}.sod-modal .sod-panel.sod-modal-anim-fade.is-closing{animation:sod-fade-out .18s ease-in forwards}.sod-modal .sod-panel.sod-modal-anim-zoom{animation:sod-modal-zoom-in .18s ease-out}.sod-modal .sod-panel.sod-modal-anim-zoom.is-closing{animation:sod-modal-zoom-out .18s ease-in forwards}.sod-modal .sod-panel.sod-modal-anim-slide{animation:sod-modal-slide-in .18s ease-out}.sod-modal .sod-panel.sod-modal-anim-slide.is-closing{animation:sod-modal-slide-out .18s ease-in forwards}.sod-header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1rem .75rem;border-bottom:1px solid #dee2e6}.sod-title{margin:0;font-size:1.1rem}.sod-close{border:0;background:transparent;color:#6c757d;font-size:1.5rem;line-height:1;cursor:pointer}.sod-body{box-sizing:border-box;padding:1rem;overflow-wrap:anywhere;word-break:break-word}.sod-body>*{max-width:100%}.sod-body input,.sod-body select,.sod-body textarea,.sod-body button{max-width:100%;box-sizing:border-box}.sod-body img,.sod-body video,.sod-body canvas,.sod-body iframe,.sod-body table{max-width:100%}.sod-modal .sod-panel.sod-modal-autofit .sod-body{flex:1 1 auto;min-height:0}.sod-body p{margin:0 0 .5rem}.sod-body ul{margin:.5rem 0 0;padding-left:1.2rem}.sod-footer{padding:.75rem 1rem 1rem;border-top:1px solid #dee2e6;display:flex;justify-content:flex-end;gap:.5rem}.sod-footer[data-align=start]{justify-content:flex-start}.sod-footer[data-align=center]{justify-content:center}.sod-footer[data-align=between]{justify-content:space-between}.sod-btn{display:inline-flex;align-items:center;justify-content:center;border-radius:.375rem;border:1px solid transparent;padding:.5rem 1rem;font-size:.95rem;font-weight:500;cursor:pointer;transition:all .15s ease-in-out}.sod-btn:focus-visible{outline:2px solid #86b7fe;outline-offset:1px}.sod-btn-primary{background:#0d6efd;color:#fff;border-color:#0d6efd}.sod-btn-primary:hover{background:#0b5ed7;border-color:#0a58ca}.sod-btn-outline{background:transparent;color:#6c757d;border-color:#6c757d}.sod-btn-outline:hover{color:#fff;background:#6c757d}.sod-btn-danger{background:#dc3545;color:#fff;border-color:#dc3545}.sod-btn-danger:hover{background:#bb2d3b;border-color:#b02a37}.sod-btn-success{background:#198754;color:#fff;border-color:#198754}.sod-btn-success:hover{background:#157347;border-color:#146c43}.sod-btn-ghost{background:transparent;color:#495057;border-color:transparent}.sod-btn-ghost:hover{background:#e9ecef}.sod-btn-link{background:transparent;color:#0d6efd;border-color:transparent;text-decoration:underline;text-underline-offset:2px}.sod-btn-link:hover{color:#0a58ca}.sod-offcanvas[open]{width:100vw;height:100vh}.sod-offcanvas .sod-panel{position:fixed;margin:0;min-width:0;max-width:none;border-radius:0;width:min(360px,90vw);height:100vh}.sod-offcanvas .sod-panel.sod-placement-start{left:0;top:0}.sod-offcanvas .sod-panel.sod-placement-end{right:0;top:0}.sod-offcanvas .sod-panel.sod-placement-top{top:0;left:0;width:100vw;height:300px}.sod-offcanvas .sod-panel.sod-placement-bottom{bottom:0;left:0;width:100vw;height:300px}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-start{animation:sod-slide-in-start .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-start.is-closing{animation:sod-slide-out-start .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-end{animation:sod-slide-in-end .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-end.is-closing{animation:sod-slide-out-end .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-top{animation:sod-slide-in-top .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-top.is-closing{animation:sod-slide-out-top .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-bottom{animation:sod-slide-in-bottom .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-bottom.is-closing{animation:sod-slide-out-bottom .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-fade{animation:sod-fade-in .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-fade.is-closing{animation:sod-fade-out .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-zoom{animation:sod-zoom-in .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-zoom.is-closing{animation:sod-zoom-out .18s ease-in forwards}@keyframes sod-modal-zoom-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}@keyframes sod-modal-zoom-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@keyframes sod-modal-slide-in{0%{opacity:0;transform:translateY(-16px)}to{opacity:1;transform:translateY(0)}}@keyframes sod-modal-slide-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-12px)}}@keyframes sod-slide-in-start{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes sod-slide-out-start{0%{transform:translate(0)}to{transform:translate(-100%)}}@keyframes sod-slide-in-end{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes sod-slide-out-end{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes sod-slide-in-top{0%{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes sod-slide-out-top{0%{transform:translateY(0)}to{transform:translateY(-100%)}}@keyframes sod-slide-in-bottom{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes sod-slide-out-bottom{0%{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes sod-fade-in{0%{opacity:0}to{opacity:1}}@keyframes sod-fade-out{0%{opacity:1}to{opacity:0}}@keyframes sod-zoom-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}.sod-toast-layer{position:fixed;z-index:1200;display:flex;flex-direction:column;gap:.5rem;width:min(360px,calc(100vw - 1.5rem));pointer-events:none}.sod-toast-layer-top-start{top:.75rem;left:.75rem;align-items:flex-start}.sod-toast-layer-top-center{top:.75rem;left:50%;transform:translate(-50%);align-items:center}.sod-toast-layer-top-end{top:.75rem;right:.75rem;align-items:flex-end}.sod-toast-layer-bottom-start{bottom:.75rem;left:.75rem;align-items:flex-start}.sod-toast-layer-bottom-center{bottom:.75rem;left:50%;transform:translate(-50%);align-items:center}.sod-toast-layer-bottom-end{bottom:.75rem;right:.75rem;align-items:flex-end}.sod-toast{--sod-toast-accent: #6c757d;pointer-events:auto;width:100%;box-sizing:border-box;border-radius:.5rem;border:1px solid #dee2e6;background:#fff;color:#212529;box-shadow:0 .5rem 1rem #0000002e;overflow:hidden;animation:sod-toast-enter .18s ease-out}.sod-toast.is-closing{animation:sod-toast-exit .18s ease-in forwards}.sod-toast-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.5rem .75rem 0}.sod-toast-title{font-size:.92rem;font-weight:700}.sod-toast-close{border:0;background:transparent;color:#6c757d;font-size:1.15rem;line-height:1;cursor:pointer;padding:0}.sod-toast-body{padding:.55rem .75rem .75rem;font-size:.92rem;line-height:1.45;overflow-wrap:anywhere;word-break:break-word}.sod-toast-progress{width:100%;height:3px;background:var(--sod-toast-accent);opacity:.9;transform-origin:left center;animation:sod-toast-progress-countdown 3s linear forwards}.sod-toast-default{--sod-toast-accent: #6c757d;border-left:4px solid #6c757d}.sod-toast-info{--sod-toast-accent: #0dcaf0;border-left:4px solid #0dcaf0}.sod-toast-success{--sod-toast-accent: #198754;border-left:4px solid #198754}.sod-toast-warning{--sod-toast-accent: #ffc107;border-left:4px solid #ffc107}.sod-toast-danger{--sod-toast-accent: #dc3545;border-left:4px solid #dc3545}@keyframes sod-toast-enter{0%{opacity:0;transform:translateY(-8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes sod-toast-exit{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@keyframes sod-toast-progress-countdown{0%{transform:scaleX(1)}to{transform:scaleX(0)}}@keyframes sod-zoom-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}}
|
|
1
|
+
.sod-dialog{border:0;padding:0;margin:auto;background:transparent;max-width:none;max-height:none;overflow:visible}.sod-dialog::backdrop{background:#0000007f}.sod-panel{box-sizing:border-box;background:#fff;color:#212529;border-radius:.5rem;box-shadow:0 .5rem 1rem #00000040;min-width:min(520px,calc(100vw - 2rem));max-width:min(520px,calc(100vw - 2rem))}.sod-modal .sod-panel{position:relative;margin:0}.sod-modal[open]{width:100vw;height:100vh;display:flex;justify-content:center;align-items:center}.sod-modal[open].sod-modal-viewport-scroll{align-items:flex-start;overflow:auto;padding:1rem 0}.sod-modal .sod-panel.sod-modal-pos-center{align-self:center}.sod-modal .sod-panel.sod-modal-pos-top{align-self:flex-start;margin-top:1rem}.sod-modal .sod-panel.sod-modal-pos-bottom{align-self:flex-end;margin-bottom:1rem}.sod-modal .sod-panel.sod-modal-autofit{min-width:0;width:auto;height:auto;max-width:calc(100vw - 2rem);max-height:calc(100vh - 2rem);display:flex;flex-direction:column}.sod-modal .sod-panel.sod-modal-draggable{touch-action:none}.sod-modal .sod-panel.sod-is-dragging{animation:none!important;transition:none!important}.sod-modal .sod-panel .sod-drag-handle{cursor:move;-webkit-user-select:none;user-select:none}.sod-modal .sod-panel .sod-drag-handle.is-dragging{cursor:grabbing}.sod-modal .sod-panel.sod-modal-anim-fade{animation:sod-fade-in .18s ease-out}.sod-modal .sod-panel.sod-modal-anim-fade.is-closing{animation:sod-fade-out .18s ease-in forwards}.sod-modal .sod-panel.sod-modal-anim-zoom{animation:sod-modal-zoom-in .18s ease-out}.sod-modal .sod-panel.sod-modal-anim-zoom.is-closing{animation:sod-modal-zoom-out .18s ease-in forwards}.sod-modal .sod-panel.sod-modal-anim-slide{animation:sod-modal-slide-in .18s ease-out}.sod-modal .sod-panel.sod-modal-anim-slide.is-closing{animation:sod-modal-slide-out .18s ease-in forwards}.sod-header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1rem .75rem;border-bottom:1px solid #dee2e6}.sod-title{margin:0;font-size:1.1rem}.sod-close{border:0;background:transparent;color:#6c757d;font-size:1.5rem;line-height:1;cursor:pointer}.sod-body{box-sizing:border-box;padding:1rem;overflow-wrap:anywhere;word-break:break-word}.sod-body>*{max-width:100%}.sod-body input,.sod-body select,.sod-body textarea,.sod-body button{max-width:100%;box-sizing:border-box}.sod-body img,.sod-body video,.sod-body canvas,.sod-body iframe,.sod-body table{max-width:100%}.sod-modal .sod-panel.sod-modal-autofit .sod-body{flex:1 1 auto;min-height:0}.sod-body p{margin:0 0 .5rem}.sod-prompt-wrap{display:grid;gap:.55rem}.sod-prompt-intro{display:grid;gap:.35rem}.sod-prompt-input{width:100%;min-height:2.3rem;border:1px solid #ced4da;border-radius:.4rem;font-size:.95rem;padding:.45rem .6rem}.sod-prompt-input:focus-visible{outline:2px solid #86b7fe;outline-offset:1px;border-color:#86b7fe}.sod-prompt-error{margin:0;color:#b02a37;font-size:.84rem}.sod-body ul{margin:.5rem 0 0;padding-left:1.2rem}.sod-footer{padding:.75rem 1rem 1rem;border-top:1px solid #dee2e6;display:flex;justify-content:flex-end;gap:.5rem}.sod-footer[data-align=start]{justify-content:flex-start}.sod-footer[data-align=center]{justify-content:center}.sod-footer[data-align=between]{justify-content:space-between}.sod-btn{display:inline-flex;align-items:center;justify-content:center;border-radius:.375rem;border:1px solid transparent;padding:.5rem 1rem;font-size:.95rem;font-weight:500;cursor:pointer;transition:all .15s ease-in-out}.sod-btn:focus-visible{outline:2px solid #86b7fe;outline-offset:1px}.sod-btn-primary{background:#0d6efd;color:#fff;border-color:#0d6efd}.sod-btn-primary:hover{background:#0b5ed7;border-color:#0a58ca}.sod-btn-outline{background:transparent;color:#6c757d;border-color:#6c757d}.sod-btn-outline:hover{color:#fff;background:#6c757d}.sod-btn-danger{background:#dc3545;color:#fff;border-color:#dc3545}.sod-btn-danger:hover{background:#bb2d3b;border-color:#b02a37}.sod-btn-success{background:#198754;color:#fff;border-color:#198754}.sod-btn-success:hover{background:#157347;border-color:#146c43}.sod-btn-ghost{background:transparent;color:#495057;border-color:transparent}.sod-btn-ghost:hover{background:#e9ecef}.sod-btn-link{background:transparent;color:#0d6efd;border-color:transparent;text-decoration:underline;text-underline-offset:2px}.sod-btn-link:hover{color:#0a58ca}.sod-offcanvas[open]{width:100vw;height:100vh}.sod-offcanvas .sod-panel{position:fixed;margin:0;min-width:0;max-width:none;border-radius:0;width:min(360px,90vw);height:100vh}.sod-offcanvas .sod-panel.sod-placement-start{left:0;top:0}.sod-offcanvas .sod-panel.sod-placement-end{right:0;top:0}.sod-offcanvas .sod-panel.sod-placement-top{top:0;left:0;width:100vw;height:300px}.sod-offcanvas .sod-panel.sod-placement-bottom{bottom:0;left:0;width:100vw;height:300px}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-start{animation:sod-slide-in-start .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-start.is-closing{animation:sod-slide-out-start .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-end{animation:sod-slide-in-end .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-end.is-closing{animation:sod-slide-out-end .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-top{animation:sod-slide-in-top .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-top.is-closing{animation:sod-slide-out-top .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-bottom{animation:sod-slide-in-bottom .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-slide.sod-placement-bottom.is-closing{animation:sod-slide-out-bottom .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-fade{animation:sod-fade-in .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-fade.is-closing{animation:sod-fade-out .18s ease-in forwards}.sod-offcanvas .sod-panel.sod-anim-zoom{animation:sod-zoom-in .18s ease-out}.sod-offcanvas .sod-panel.sod-anim-zoom.is-closing{animation:sod-zoom-out .18s ease-in forwards}@keyframes sod-modal-zoom-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}@keyframes sod-modal-zoom-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@keyframes sod-modal-slide-in{0%{opacity:0;transform:translateY(-16px)}to{opacity:1;transform:translateY(0)}}@keyframes sod-modal-slide-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-12px)}}@keyframes sod-slide-in-start{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes sod-slide-out-start{0%{transform:translate(0)}to{transform:translate(-100%)}}@keyframes sod-slide-in-end{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes sod-slide-out-end{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes sod-slide-in-top{0%{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes sod-slide-out-top{0%{transform:translateY(0)}to{transform:translateY(-100%)}}@keyframes sod-slide-in-bottom{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes sod-slide-out-bottom{0%{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes sod-fade-in{0%{opacity:0}to{opacity:1}}@keyframes sod-fade-out{0%{opacity:1}to{opacity:0}}@keyframes sod-zoom-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}.sod-toast-layer{position:fixed;z-index:1200;display:flex;flex-direction:column;gap:.5rem;width:min(360px,calc(100vw - 1.5rem));pointer-events:none}.sod-toast-layer-top-start{top:.75rem;left:.75rem;align-items:flex-start}.sod-toast-layer-top-center{top:.75rem;left:50%;transform:translate(-50%);align-items:center}.sod-toast-layer-top-end{top:.75rem;right:.75rem;align-items:flex-end}.sod-toast-layer-bottom-start{bottom:.75rem;left:.75rem;align-items:flex-start}.sod-toast-layer-bottom-center{bottom:.75rem;left:50%;transform:translate(-50%);align-items:center}.sod-toast-layer-bottom-end{bottom:.75rem;right:.75rem;align-items:flex-end}.sod-toast{--sod-toast-accent: #6c757d;pointer-events:auto;width:100%;box-sizing:border-box;border-radius:.5rem;border:1px solid #dee2e6;background:#fff;color:#212529;box-shadow:0 .5rem 1rem #0000002e;overflow:hidden;animation:sod-toast-enter .18s ease-out}.sod-toast.is-closing{animation:sod-toast-exit .18s ease-in forwards}.sod-toast-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.5rem .75rem 0}.sod-toast-title{font-size:.92rem;font-weight:700}.sod-toast-close{border:0;background:transparent;color:#6c757d;font-size:1.15rem;line-height:1;cursor:pointer;padding:0}.sod-toast-body{padding:.55rem .75rem .75rem;font-size:.92rem;line-height:1.45;overflow-wrap:anywhere;word-break:break-word}.sod-toast-progress{width:100%;height:3px;background:var(--sod-toast-accent);opacity:.9;transform-origin:left center;animation:sod-toast-progress-countdown 3s linear forwards}.sod-toast-default{--sod-toast-accent: #6c757d;border-left:4px solid #6c757d}.sod-toast-info{--sod-toast-accent: #0dcaf0;border-left:4px solid #0dcaf0}.sod-toast-success{--sod-toast-accent: #198754;border-left:4px solid #198754}.sod-toast-warning{--sod-toast-accent: #ffc107;border-left:4px solid #ffc107}.sod-toast-danger{--sod-toast-accent: #dc3545;border-left:4px solid #dc3545}@keyframes sod-toast-enter{0%{opacity:0;transform:translateY(-8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes sod-toast-exit{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@keyframes sod-toast-progress-countdown{0%{transform:scaleX(1)}to{transform:scaleX(0)}}@keyframes sod-zoom-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}}
|