@konomi-app/ui 5.3.2 → 5.4.1

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/dist/index.js CHANGED
@@ -16,6 +16,14 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
16
16
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
17
17
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
18
18
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
19
+ var __privateWrapper = (obj, member, setter, getter) => ({
20
+ set _(value) {
21
+ __privateSet(obj, member, value, setter);
22
+ },
23
+ get _() {
24
+ return __privateGet(obj, member, getter);
25
+ }
26
+ });
19
27
 
20
28
  // src/types.ts
21
29
  var createInitialState = () => ({
@@ -2284,9 +2292,908 @@ ensureElement_fn = function() {
2284
2292
  __privateSet(this, _element, el);
2285
2293
  };
2286
2294
  var dialog = new DialogSingleton();
2295
+
2296
+ // src/toast/types.ts
2297
+ var createInitialToastState = () => ({
2298
+ items: [],
2299
+ position: "bottom-right",
2300
+ maxVisible: 3,
2301
+ defaultDuration: 4e3
2302
+ });
2303
+
2304
+ // src/toast/controller.ts
2305
+ var DISMISS_ANIMATION_MS = 400;
2306
+ var _state2, _listeners2, _timers, _timerStartedAt, _dismissTimers, _nextId, _ToastController_instances, emit_fn2, update_fn2, startTimer_fn, clearTimer_fn2, beginDismiss_fn, removeItem_fn, updateItem_fn, findItem_fn, enforceMaxVisible_fn;
2307
+ var ToastController = class {
2308
+ constructor() {
2309
+ __privateAdd(this, _ToastController_instances);
2310
+ __privateAdd(this, _state2);
2311
+ __privateAdd(this, _listeners2, /* @__PURE__ */ new Set());
2312
+ // ─── Per-toast timer management ─────────────────────────
2313
+ __privateAdd(this, _timers, /* @__PURE__ */ new Map());
2314
+ __privateAdd(this, _timerStartedAt, /* @__PURE__ */ new Map());
2315
+ __privateAdd(this, _dismissTimers, /* @__PURE__ */ new Map());
2316
+ __privateAdd(this, _nextId, 0);
2317
+ __privateSet(this, _state2, createInitialToastState());
2318
+ }
2319
+ // ─── Observable ─────────────────────────────────────────
2320
+ get state() {
2321
+ return __privateGet(this, _state2);
2322
+ }
2323
+ subscribe(fn) {
2324
+ __privateGet(this, _listeners2).add(fn);
2325
+ return () => __privateGet(this, _listeners2).delete(fn);
2326
+ }
2327
+ // ─── Configuration ──────────────────────────────────────
2328
+ configure(config) {
2329
+ const patch = {};
2330
+ if (config.position != null) patch.position = config.position;
2331
+ if (config.maxVisible != null) patch.maxVisible = config.maxVisible;
2332
+ if (config.defaultDuration != null) patch.defaultDuration = config.defaultDuration;
2333
+ if (Object.keys(patch).length > 0) __privateMethod(this, _ToastController_instances, update_fn2).call(this, patch);
2334
+ }
2335
+ // ─── Show ───────────────────────────────────────────────
2336
+ show(options) {
2337
+ const id = `toast-${++__privateWrapper(this, _nextId)._}`;
2338
+ const duration = options.duration ?? __privateGet(this, _state2).defaultDuration;
2339
+ const item = {
2340
+ id,
2341
+ type: options.type ?? "info",
2342
+ message: options.message,
2343
+ description: options.description ?? "",
2344
+ action: options.action ?? null,
2345
+ duration,
2346
+ remainingMs: duration,
2347
+ paused: false,
2348
+ dismissing: false
2349
+ };
2350
+ const items = [...__privateGet(this, _state2).items, item];
2351
+ __privateMethod(this, _ToastController_instances, update_fn2).call(this, { items });
2352
+ if (duration > 0) {
2353
+ __privateMethod(this, _ToastController_instances, startTimer_fn).call(this, id, duration);
2354
+ }
2355
+ __privateMethod(this, _ToastController_instances, enforceMaxVisible_fn).call(this);
2356
+ return id;
2357
+ }
2358
+ success(message, options) {
2359
+ return this.show({ ...options, type: "success", message });
2360
+ }
2361
+ error(message, options) {
2362
+ return this.show({ ...options, type: "error", message });
2363
+ }
2364
+ warning(message, options) {
2365
+ return this.show({ ...options, type: "warning", message });
2366
+ }
2367
+ info(message, options) {
2368
+ return this.show({ ...options, type: "info", message });
2369
+ }
2370
+ loading(message, options) {
2371
+ return this.show({ duration: 0, ...options, type: "loading", message });
2372
+ }
2373
+ // ─── Dismiss ────────────────────────────────────────────
2374
+ dismiss(id) {
2375
+ const item = __privateMethod(this, _ToastController_instances, findItem_fn).call(this, id);
2376
+ if (!item || item.dismissing) return;
2377
+ __privateMethod(this, _ToastController_instances, beginDismiss_fn).call(this, id);
2378
+ }
2379
+ dismissAll() {
2380
+ for (const item of __privateGet(this, _state2).items) {
2381
+ __privateMethod(this, _ToastController_instances, clearTimer_fn2).call(this, item.id);
2382
+ __privateGet(this, _timerStartedAt).delete(item.id);
2383
+ }
2384
+ const items = __privateGet(this, _state2).items.filter((i) => !i.dismissing).map((item) => ({ ...item, dismissing: true, paused: true }));
2385
+ __privateMethod(this, _ToastController_instances, update_fn2).call(this, { items });
2386
+ const timer = setTimeout(() => {
2387
+ __privateMethod(this, _ToastController_instances, update_fn2).call(this, { items: [] });
2388
+ __privateGet(this, _dismissTimers).clear();
2389
+ }, DISMISS_ANIMATION_MS);
2390
+ __privateGet(this, _dismissTimers).set("__all__", timer);
2391
+ }
2392
+ // ─── Update ─────────────────────────────────────────────
2393
+ update(id, patch) {
2394
+ const item = __privateMethod(this, _ToastController_instances, findItem_fn).call(this, id);
2395
+ if (!item || item.dismissing) return;
2396
+ const { duration: newDuration, ...rest } = patch;
2397
+ const isLeavingLoading = item.type === "loading" && rest.type != null && rest.type !== "loading";
2398
+ if (newDuration !== void 0) {
2399
+ __privateMethod(this, _ToastController_instances, clearTimer_fn2).call(this, id);
2400
+ __privateMethod(this, _ToastController_instances, updateItem_fn).call(this, id, { ...rest, duration: newDuration, remainingMs: newDuration, paused: false });
2401
+ if (newDuration > 0) {
2402
+ __privateMethod(this, _ToastController_instances, startTimer_fn).call(this, id, newDuration);
2403
+ }
2404
+ } else if (isLeavingLoading) {
2405
+ const autoMs = __privateGet(this, _state2).defaultDuration;
2406
+ __privateMethod(this, _ToastController_instances, updateItem_fn).call(this, id, { ...rest, duration: autoMs, remainingMs: autoMs, paused: false });
2407
+ if (autoMs > 0) {
2408
+ __privateMethod(this, _ToastController_instances, startTimer_fn).call(this, id, autoMs);
2409
+ }
2410
+ } else {
2411
+ __privateMethod(this, _ToastController_instances, updateItem_fn).call(this, id, rest);
2412
+ }
2413
+ }
2414
+ // ─── Timer control (called from component) ─────────────
2415
+ pauseTimer(id) {
2416
+ const item = __privateMethod(this, _ToastController_instances, findItem_fn).call(this, id);
2417
+ if (!item || item.paused || item.dismissing || item.duration <= 0) return;
2418
+ const startedAt = __privateGet(this, _timerStartedAt).get(id);
2419
+ if (startedAt == null) return;
2420
+ __privateMethod(this, _ToastController_instances, clearTimer_fn2).call(this, id);
2421
+ const elapsed = Date.now() - startedAt;
2422
+ const remainingMs = Math.max(0, item.remainingMs - elapsed);
2423
+ __privateGet(this, _timerStartedAt).delete(id);
2424
+ __privateMethod(this, _ToastController_instances, updateItem_fn).call(this, id, { paused: true, remainingMs });
2425
+ }
2426
+ resumeTimer(id) {
2427
+ const item = __privateMethod(this, _ToastController_instances, findItem_fn).call(this, id);
2428
+ if (!item || !item.paused || item.dismissing || item.duration <= 0) return;
2429
+ __privateMethod(this, _ToastController_instances, updateItem_fn).call(this, id, { paused: false });
2430
+ const updated = __privateMethod(this, _ToastController_instances, findItem_fn).call(this, id);
2431
+ if (updated && updated.remainingMs > 0) {
2432
+ __privateMethod(this, _ToastController_instances, startTimer_fn).call(this, id, updated.remainingMs);
2433
+ }
2434
+ }
2435
+ };
2436
+ _state2 = new WeakMap();
2437
+ _listeners2 = new WeakMap();
2438
+ _timers = new WeakMap();
2439
+ _timerStartedAt = new WeakMap();
2440
+ _dismissTimers = new WeakMap();
2441
+ _nextId = new WeakMap();
2442
+ _ToastController_instances = new WeakSet();
2443
+ emit_fn2 = function() {
2444
+ const snapshot = { ...__privateGet(this, _state2), items: [...__privateGet(this, _state2).items] };
2445
+ for (const fn of __privateGet(this, _listeners2)) fn(snapshot);
2446
+ };
2447
+ update_fn2 = function(patch) {
2448
+ Object.assign(__privateGet(this, _state2), patch);
2449
+ __privateMethod(this, _ToastController_instances, emit_fn2).call(this);
2450
+ };
2451
+ // ─── Internal ───────────────────────────────────────────
2452
+ startTimer_fn = function(id, durationMs) {
2453
+ __privateMethod(this, _ToastController_instances, clearTimer_fn2).call(this, id);
2454
+ __privateGet(this, _timerStartedAt).set(id, Date.now());
2455
+ __privateGet(this, _timers).set(
2456
+ id,
2457
+ setTimeout(() => {
2458
+ __privateGet(this, _timers).delete(id);
2459
+ __privateGet(this, _timerStartedAt).delete(id);
2460
+ __privateMethod(this, _ToastController_instances, beginDismiss_fn).call(this, id);
2461
+ }, durationMs)
2462
+ );
2463
+ };
2464
+ clearTimer_fn2 = function(id) {
2465
+ const timer = __privateGet(this, _timers).get(id);
2466
+ if (timer != null) {
2467
+ clearTimeout(timer);
2468
+ __privateGet(this, _timers).delete(id);
2469
+ }
2470
+ };
2471
+ beginDismiss_fn = function(id) {
2472
+ __privateMethod(this, _ToastController_instances, clearTimer_fn2).call(this, id);
2473
+ __privateGet(this, _timerStartedAt).delete(id);
2474
+ const item = __privateMethod(this, _ToastController_instances, findItem_fn).call(this, id);
2475
+ if (!item || item.dismissing) return;
2476
+ __privateMethod(this, _ToastController_instances, updateItem_fn).call(this, id, { dismissing: true, paused: true });
2477
+ __privateGet(this, _dismissTimers).set(
2478
+ id,
2479
+ setTimeout(() => {
2480
+ __privateMethod(this, _ToastController_instances, removeItem_fn).call(this, id);
2481
+ __privateGet(this, _dismissTimers).delete(id);
2482
+ }, DISMISS_ANIMATION_MS)
2483
+ );
2484
+ };
2485
+ removeItem_fn = function(id) {
2486
+ const items = __privateGet(this, _state2).items.filter((i) => i.id !== id);
2487
+ __privateMethod(this, _ToastController_instances, update_fn2).call(this, { items });
2488
+ };
2489
+ updateItem_fn = function(id, patch) {
2490
+ const items = __privateGet(this, _state2).items.map((item) => item.id === id ? { ...item, ...patch } : item);
2491
+ __privateMethod(this, _ToastController_instances, update_fn2).call(this, { items });
2492
+ };
2493
+ findItem_fn = function(id) {
2494
+ return __privateGet(this, _state2).items.find((i) => i.id === id);
2495
+ };
2496
+ enforceMaxVisible_fn = function() {
2497
+ const active = __privateGet(this, _state2).items.filter((i) => !i.dismissing);
2498
+ const excess = active.length - __privateGet(this, _state2).maxVisible;
2499
+ if (excess <= 0) return;
2500
+ for (let i = 0; i < excess; i++) {
2501
+ __privateMethod(this, _ToastController_instances, beginDismiss_fn).call(this, active[i].id);
2502
+ }
2503
+ };
2504
+
2505
+ // src/toast/toast-container.ts
2506
+ import { LitElement as LitElement2, html as html2, nothing as nothing2 } from "lit";
2507
+ import { customElement as customElement2, property as property2, state as state2 } from "lit/decorators.js";
2508
+ import { repeat } from "lit/directives/repeat.js";
2509
+
2510
+ // src/toast/styles.ts
2511
+ import { css as css2 } from "lit";
2512
+ var toastStyles = css2`
2513
+ :host {
2514
+ /* ─── Customizable CSS Variables ─── */
2515
+ --toast-font-family: var(
2516
+ --dialog-font-family,
2517
+ 'Yu Gothic Medium',
2518
+ '游ゴシック',
2519
+ YuGothic,
2520
+ 'メイリオ',
2521
+ 'Hiragino Kaku Gothic ProN',
2522
+ Meiryo,
2523
+ sans-serif
2524
+ );
2525
+ --toast-text-color: var(--dialog-text-color, #356);
2526
+ --toast-z-index: 1100;
2527
+
2528
+ /* Container */
2529
+ --toast-gap: 12px;
2530
+ --toast-padding: 16px;
2531
+ --toast-max-width: 420px;
2532
+
2533
+ /* Card */
2534
+ --toast-card-bg: #fff;
2535
+ --toast-card-border: #f3f4f6;
2536
+ --toast-card-shadow: 0 4px 12px rgb(0 0 0 / 0.08), 0 1px 3px rgb(0 0 0 / 0.06);
2537
+ --toast-card-radius: 8px;
2538
+ --toast-card-padding: 14px 16px;
2539
+
2540
+ /* Colors (inherit from dialog when available) */
2541
+ --toast-success: var(--dialog-success, #22c55e);
2542
+ --toast-error: var(--dialog-error, #ef4444);
2543
+ --toast-warning: var(--dialog-warning, #f59e0b);
2544
+ --toast-info: var(--dialog-info, #3b82f6);
2545
+ --toast-loading: var(--dialog-primary, #3b82f6);
2546
+ --toast-spinner-track: rgb(59 130 246 / 0.2);
2547
+ --toast-spinner-arc: var(--toast-loading);
2548
+
2549
+ /* Progress bar */
2550
+ --toast-progress-height: 3px;
2551
+
2552
+ /* Close button */
2553
+ --toast-close-color: #9ca3af;
2554
+ --toast-close-hover-color: #374151;
2555
+
2556
+ /* Timing */
2557
+ --toast-enter-duration: 350ms;
2558
+ --toast-exit-duration: 200ms;
2559
+ --toast-collapse-duration: 200ms;
2560
+
2561
+ display: contents;
2562
+ font-family: var(--toast-font-family);
2563
+ color: var(--toast-text-color);
2564
+ }
2565
+
2566
+ /* ─── Container ─── */
2567
+
2568
+ .container {
2569
+ position: fixed;
2570
+ z-index: var(--toast-z-index);
2571
+ display: flex;
2572
+ flex-direction: column;
2573
+ gap: var(--toast-gap);
2574
+ padding: var(--toast-padding);
2575
+ pointer-events: none;
2576
+ max-height: 100vh;
2577
+ max-width: var(--toast-max-width);
2578
+ box-sizing: border-box;
2579
+ }
2580
+
2581
+ /* Position variants */
2582
+ .container[data-position='top-right'] {
2583
+ top: 0;
2584
+ right: 0;
2585
+ }
2586
+ .container[data-position='top-left'] {
2587
+ top: 0;
2588
+ left: 0;
2589
+ }
2590
+ .container[data-position='top-center'] {
2591
+ top: 0;
2592
+ left: 50%;
2593
+ transform: translateX(-50%);
2594
+ }
2595
+ .container[data-position='bottom-right'] {
2596
+ bottom: 0;
2597
+ right: 0;
2598
+ flex-direction: column-reverse;
2599
+ }
2600
+ .container[data-position='bottom-left'] {
2601
+ bottom: 0;
2602
+ left: 0;
2603
+ flex-direction: column-reverse;
2604
+ }
2605
+ .container[data-position='bottom-center'] {
2606
+ bottom: 0;
2607
+ left: 50%;
2608
+ transform: translateX(-50%);
2609
+ flex-direction: column-reverse;
2610
+ }
2611
+
2612
+ /* Responsive: full-width on mobile */
2613
+ @media (max-width: 639px) {
2614
+ .container {
2615
+ max-width: 100%;
2616
+ width: 100%;
2617
+ left: 0;
2618
+ right: 0;
2619
+ transform: none;
2620
+ }
2621
+ .container[data-position^='top'] {
2622
+ top: 0;
2623
+ flex-direction: column;
2624
+ }
2625
+ .container[data-position^='bottom'] {
2626
+ bottom: 0;
2627
+ flex-direction: column-reverse;
2628
+ }
2629
+ }
2630
+
2631
+ /* ─── Direction-based transform variables ─── */
2632
+
2633
+ .container[data-position$='right'] {
2634
+ --_enter-x: 110%;
2635
+ --_exit-x: 110%;
2636
+ --_enter-y: 0;
2637
+ --_exit-y: 0;
2638
+ }
2639
+ .container[data-position$='left'] {
2640
+ --_enter-x: -110%;
2641
+ --_exit-x: -110%;
2642
+ --_enter-y: 0;
2643
+ --_exit-y: 0;
2644
+ }
2645
+ .container[data-position='top-center'] {
2646
+ --_enter-x: 0;
2647
+ --_exit-x: 0;
2648
+ --_enter-y: -100%;
2649
+ --_exit-y: -100%;
2650
+ }
2651
+ .container[data-position='bottom-center'] {
2652
+ --_enter-x: 0;
2653
+ --_exit-x: 0;
2654
+ --_enter-y: 100%;
2655
+ --_exit-y: 100%;
2656
+ }
2657
+
2658
+ @media (max-width: 639px) {
2659
+ .container[data-position^='top'] {
2660
+ --_enter-x: 0;
2661
+ --_exit-x: 0;
2662
+ --_enter-y: -100%;
2663
+ --_exit-y: -100%;
2664
+ }
2665
+ .container[data-position^='bottom'] {
2666
+ --_enter-x: 0;
2667
+ --_exit-x: 0;
2668
+ --_enter-y: 100%;
2669
+ --_exit-y: 100%;
2670
+ }
2671
+ }
2672
+
2673
+ /* ─── Toast Slot (height-collapsing wrapper) ─── */
2674
+
2675
+ .toast-slot {
2676
+ display: grid;
2677
+ grid-template-rows: 1fr;
2678
+ transition: grid-template-rows var(--toast-collapse-duration) ease var(--toast-exit-duration);
2679
+ pointer-events: auto;
2680
+ }
2681
+
2682
+ .toast-slot[data-dismissing] {
2683
+ grid-template-rows: 0fr;
2684
+ }
2685
+
2686
+ .toast-slot > .toast-card {
2687
+ overflow: hidden;
2688
+ min-height: 0;
2689
+ }
2690
+
2691
+ /* ─── Toast Card ─── */
2692
+
2693
+ .toast-card {
2694
+ background: var(--toast-card-bg);
2695
+ border: 1px solid var(--toast-card-border);
2696
+ border-radius: var(--toast-card-radius);
2697
+ box-shadow: var(--toast-card-shadow);
2698
+ position: relative;
2699
+ overflow: hidden;
2700
+ animation: toast-enter var(--toast-enter-duration) cubic-bezier(0.16, 1, 0.3, 1) both;
2701
+ }
2702
+
2703
+ .toast-card[data-dismissing] {
2704
+ animation: toast-exit var(--toast-exit-duration) ease both;
2705
+ pointer-events: none;
2706
+ }
2707
+
2708
+ /* Type-based left accent */
2709
+ .toast-card[data-type='success'] {
2710
+ border-left: 3px solid var(--toast-success);
2711
+ }
2712
+ .toast-card[data-type='error'] {
2713
+ border-left: 3px solid var(--toast-error);
2714
+ }
2715
+ .toast-card[data-type='warning'] {
2716
+ border-left: 3px solid var(--toast-warning);
2717
+ }
2718
+ .toast-card[data-type='info'] {
2719
+ border-left: 3px solid var(--toast-info);
2720
+ }
2721
+ .toast-card[data-type='loading'] {
2722
+ border-left: 3px solid var(--toast-loading);
2723
+ }
2724
+
2725
+ /* ─── Animations ─── */
2726
+
2727
+ @keyframes toast-enter {
2728
+ from {
2729
+ opacity: 0;
2730
+ transform: translateX(var(--_enter-x, 0)) translateY(var(--_enter-y, 0));
2731
+ filter: blur(4px);
2732
+ }
2733
+ to {
2734
+ opacity: 1;
2735
+ transform: translateX(0) translateY(0);
2736
+ filter: blur(0);
2737
+ }
2738
+ }
2739
+
2740
+ @keyframes toast-exit {
2741
+ from {
2742
+ opacity: 1;
2743
+ transform: translateX(0) translateY(0);
2744
+ filter: blur(0);
2745
+ }
2746
+ to {
2747
+ opacity: 0;
2748
+ transform: translateX(var(--_exit-x, 0)) translateY(var(--_exit-y, 0));
2749
+ filter: blur(3px);
2750
+ }
2751
+ }
2752
+
2753
+ /* ─── Body ─── */
2754
+
2755
+ .toast-body {
2756
+ display: flex;
2757
+ align-items: flex-start;
2758
+ gap: 12px;
2759
+ padding: var(--toast-card-padding);
2760
+ }
2761
+
2762
+ /* ─── Icon ─── */
2763
+
2764
+ .toast-icon {
2765
+ width: 20px;
2766
+ height: 20px;
2767
+ flex-shrink: 0;
2768
+ margin-top: 1px;
2769
+ display: flex;
2770
+ align-items: center;
2771
+ justify-content: center;
2772
+ }
2773
+
2774
+ .toast-icon svg {
2775
+ width: 20px;
2776
+ height: 20px;
2777
+ }
2778
+
2779
+ .icon-success {
2780
+ color: var(--toast-success);
2781
+ }
2782
+ .icon-error {
2783
+ color: var(--toast-error);
2784
+ }
2785
+ .icon-warning {
2786
+ color: var(--toast-warning);
2787
+ }
2788
+ .icon-info {
2789
+ color: var(--toast-info);
2790
+ }
2791
+ .icon-loading {
2792
+ color: var(--toast-loading);
2793
+ }
2794
+
2795
+ /* ─── Loading Spinner ─── */
2796
+
2797
+ @keyframes toast-spin {
2798
+ to {
2799
+ transform: rotate(360deg);
2800
+ }
2801
+ }
2802
+
2803
+ .toast-spinner {
2804
+ width: 20px;
2805
+ height: 20px;
2806
+ border-radius: 50%;
2807
+ box-shadow: inset 0 0 0 2px var(--toast-spinner-track);
2808
+ position: relative;
2809
+ animation: toast-spin 1.2s infinite linear;
2810
+ flex-shrink: 0;
2811
+ }
2812
+
2813
+ .toast-spinner-half {
2814
+ position: absolute;
2815
+ left: 50%;
2816
+ top: 50%;
2817
+ width: 10px;
2818
+ height: 20px;
2819
+ margin-left: -10px;
2820
+ margin-top: -10px;
2821
+ overflow: hidden;
2822
+ transform-origin: 10px 10px;
2823
+ mask-image: linear-gradient(to bottom, #000f, #0000);
2824
+ -webkit-mask-image: linear-gradient(to bottom, #000f, #0000);
2825
+ }
2826
+
2827
+ .toast-spinner-inner {
2828
+ width: 20px;
2829
+ height: 20px;
2830
+ border-radius: 50%;
2831
+ box-shadow: inset 0 0 0 2px var(--toast-spinner-arc);
2832
+ }
2833
+
2834
+ /* ─── Text ─── */
2835
+
2836
+ .toast-text {
2837
+ flex: 1;
2838
+ min-width: 0;
2839
+ display: flex;
2840
+ flex-direction: column;
2841
+ gap: 4px;
2842
+ }
2843
+
2844
+ .toast-message {
2845
+ font-size: 14px;
2846
+ font-weight: 500;
2847
+ color: #1f2937;
2848
+ margin: 0;
2849
+ word-break: break-word;
2850
+ line-height: 1.4;
2851
+ }
2852
+
2853
+ .toast-description {
2854
+ font-size: 13px;
2855
+ color: #6b7280;
2856
+ margin: 0;
2857
+ word-break: break-word;
2858
+ line-height: 1.5;
2859
+ }
2860
+
2861
+ /* ─── Action Button ─── */
2862
+
2863
+ .toast-action-btn {
2864
+ background: none;
2865
+ border: none;
2866
+ padding: 0;
2867
+ font-family: inherit;
2868
+ font-size: 13px;
2869
+ font-weight: 600;
2870
+ color: var(--toast-info);
2871
+ cursor: pointer;
2872
+ align-self: flex-start;
2873
+ text-decoration: underline;
2874
+ text-underline-offset: 2px;
2875
+ transition: color 150ms ease;
2876
+ }
2877
+
2878
+ .toast-action-btn:hover {
2879
+ color: var(--dialog-primary-hover, #2563eb);
2880
+ }
2881
+
2882
+ /* ─── Close Button ─── */
2883
+
2884
+ .toast-close {
2885
+ width: 20px;
2886
+ height: 20px;
2887
+ padding: 0;
2888
+ margin: 0;
2889
+ border: none;
2890
+ background: none;
2891
+ cursor: pointer;
2892
+ flex-shrink: 0;
2893
+ display: flex;
2894
+ align-items: center;
2895
+ justify-content: center;
2896
+ color: var(--toast-close-color);
2897
+ transition: color 150ms ease;
2898
+ border-radius: 4px;
2899
+ }
2900
+
2901
+ .toast-close svg {
2902
+ width: 14px;
2903
+ height: 14px;
2904
+ }
2905
+
2906
+ .toast-close:hover {
2907
+ color: var(--toast-close-hover-color);
2908
+ }
2909
+
2910
+ @media (min-width: 640px) {
2911
+ .toast-close {
2912
+ opacity: 0.5;
2913
+ transition:
2914
+ opacity 150ms ease,
2915
+ color 150ms ease;
2916
+ }
2917
+ .toast-card:hover .toast-close {
2918
+ opacity: 1;
2919
+ }
2920
+ }
2921
+
2922
+ /* ─── Progress Bar ─── */
2923
+
2924
+ .toast-progress {
2925
+ position: absolute;
2926
+ bottom: 0;
2927
+ left: 0;
2928
+ height: var(--toast-progress-height);
2929
+ width: 100%;
2930
+ border-radius: 0 0 var(--toast-card-radius) var(--toast-card-radius);
2931
+ animation: toast-progress-countdown linear forwards;
2932
+ animation-play-state: running;
2933
+ }
2934
+
2935
+ .toast-card[data-paused] .toast-progress {
2936
+ animation-play-state: paused;
2937
+ }
2938
+
2939
+ @keyframes toast-progress-countdown {
2940
+ from {
2941
+ width: 100%;
2942
+ }
2943
+ to {
2944
+ width: 0%;
2945
+ }
2946
+ }
2947
+
2948
+ .toast-progress[data-type='success'] {
2949
+ background-color: var(--toast-success);
2950
+ }
2951
+ .toast-progress[data-type='error'] {
2952
+ background-color: var(--toast-error);
2953
+ }
2954
+ .toast-progress[data-type='warning'] {
2955
+ background-color: var(--toast-warning);
2956
+ }
2957
+ .toast-progress[data-type='info'] {
2958
+ background-color: var(--toast-info);
2959
+ }
2960
+ `;
2961
+
2962
+ // src/toast/toast-container.ts
2963
+ var ToastContainer = class extends LitElement2 {
2964
+ constructor() {
2965
+ super(...arguments);
2966
+ this._state = createInitialToastState();
2967
+ }
2968
+ connectedCallback() {
2969
+ super.connectedCallback();
2970
+ if (this.controller) {
2971
+ this._state = { ...this.controller.state };
2972
+ this._unsubscribe = this.controller.subscribe((s) => {
2973
+ this._state = s;
2974
+ });
2975
+ }
2976
+ }
2977
+ disconnectedCallback() {
2978
+ super.disconnectedCallback();
2979
+ this._unsubscribe?.();
2980
+ }
2981
+ // ─── Icon Rendering ─────────────────────────────────────
2982
+ _renderIcon(type) {
2983
+ switch (type) {
2984
+ case "success":
2985
+ return html2`<svg
2986
+ viewBox="0 0 24 24"
2987
+ fill="none"
2988
+ stroke="currentColor"
2989
+ stroke-width="2"
2990
+ stroke-linecap="round"
2991
+ stroke-linejoin="round"
2992
+ >
2993
+ <circle cx="12" cy="12" r="10" />
2994
+ <polyline points="9,12 11,14 15,10" />
2995
+ </svg>`;
2996
+ case "error":
2997
+ return html2`<svg
2998
+ viewBox="0 0 24 24"
2999
+ fill="none"
3000
+ stroke="currentColor"
3001
+ stroke-width="2"
3002
+ stroke-linecap="round"
3003
+ stroke-linejoin="round"
3004
+ >
3005
+ <circle cx="12" cy="12" r="10" />
3006
+ <line x1="15" y1="9" x2="9" y2="15" />
3007
+ <line x1="9" y1="9" x2="15" y2="15" />
3008
+ </svg>`;
3009
+ case "warning":
3010
+ return html2`<svg
3011
+ viewBox="0 0 24 24"
3012
+ fill="none"
3013
+ stroke="currentColor"
3014
+ stroke-width="2"
3015
+ stroke-linecap="round"
3016
+ stroke-linejoin="round"
3017
+ >
3018
+ <path
3019
+ d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"
3020
+ />
3021
+ <line x1="12" y1="9" x2="12" y2="13" />
3022
+ <line x1="12" y1="17" x2="12.01" y2="17" />
3023
+ </svg>`;
3024
+ case "info":
3025
+ return html2`<svg
3026
+ viewBox="0 0 24 24"
3027
+ fill="none"
3028
+ stroke="currentColor"
3029
+ stroke-width="2"
3030
+ stroke-linecap="round"
3031
+ stroke-linejoin="round"
3032
+ >
3033
+ <circle cx="12" cy="12" r="10" />
3034
+ <line x1="12" y1="16" x2="12" y2="12" />
3035
+ <line x1="12" y1="8" x2="12.01" y2="8" />
3036
+ </svg>`;
3037
+ case "loading":
3038
+ return html2`
3039
+ <div class="toast-spinner">
3040
+ <div class="toast-spinner-half">
3041
+ <div class="toast-spinner-inner"></div>
3042
+ </div>
3043
+ </div>
3044
+ `;
3045
+ }
3046
+ }
3047
+ // ─── Toast Rendering ────────────────────────────────────
3048
+ _renderToast(item) {
3049
+ return html2`
3050
+ <div class="toast-slot" ?data-dismissing=${item.dismissing}>
3051
+ <div
3052
+ class="toast-card"
3053
+ data-type=${item.type}
3054
+ ?data-dismissing=${item.dismissing}
3055
+ ?data-paused=${item.paused}
3056
+ @mouseenter=${() => this.controller.pauseTimer(item.id)}
3057
+ @mouseleave=${() => this.controller.resumeTimer(item.id)}
3058
+ >
3059
+ <div class="toast-body">
3060
+ <span class="toast-icon icon-${item.type}"> ${this._renderIcon(item.type)} </span>
3061
+ <div class="toast-text">
3062
+ <p class="toast-message">${item.message}</p>
3063
+ ${item.description ? html2`<p class="toast-description">${item.description}</p>` : nothing2}
3064
+ ${item.action ? html2`<button
3065
+ class="toast-action-btn"
3066
+ @click=${() => {
3067
+ item.action.onClick();
3068
+ this.controller.dismiss(item.id);
3069
+ }}
3070
+ >
3071
+ ${item.action.label}
3072
+ </button>` : nothing2}
3073
+ </div>
3074
+ <button
3075
+ class="toast-close"
3076
+ @click=${() => this.controller.dismiss(item.id)}
3077
+ aria-label="閉じる"
3078
+ >
3079
+ <svg
3080
+ viewBox="0 0 24 24"
3081
+ fill="none"
3082
+ stroke="currentColor"
3083
+ stroke-width="2"
3084
+ stroke-linecap="round"
3085
+ stroke-linejoin="round"
3086
+ >
3087
+ <line x1="18" y1="6" x2="6" y2="18" />
3088
+ <line x1="6" y1="6" x2="18" y2="18" />
3089
+ </svg>
3090
+ </button>
3091
+ </div>
3092
+ ${item.duration > 0 && item.type !== "loading" ? html2`<div
3093
+ class="toast-progress"
3094
+ style="animation-duration:${item.duration}ms"
3095
+ data-type=${item.type}
3096
+ ></div>` : nothing2}
3097
+ </div>
3098
+ </div>
3099
+ `;
3100
+ }
3101
+ // ─── Main Render ────────────────────────────────────────
3102
+ render() {
3103
+ const s = this._state;
3104
+ return html2`
3105
+ <div class="container" data-position=${s.position} role="region" aria-label="通知">
3106
+ ${repeat(
3107
+ s.items,
3108
+ (item) => item.id,
3109
+ (item) => this._renderToast(item)
3110
+ )}
3111
+ </div>
3112
+ `;
3113
+ }
3114
+ };
3115
+ ToastContainer.styles = toastStyles;
3116
+ __decorateClass([
3117
+ property2({ attribute: false })
3118
+ ], ToastContainer.prototype, "controller", 2);
3119
+ __decorateClass([
3120
+ state2()
3121
+ ], ToastContainer.prototype, "_state", 2);
3122
+ ToastContainer = __decorateClass([
3123
+ customElement2("toast-container")
3124
+ ], ToastContainer);
3125
+
3126
+ // src/toast/toast.ts
3127
+ var _controller2, _element2, _ToastSingleton_instances, ensureElement_fn2;
3128
+ var ToastSingleton = class {
3129
+ constructor() {
3130
+ __privateAdd(this, _ToastSingleton_instances);
3131
+ __privateAdd(this, _controller2, new ToastController());
3132
+ __privateAdd(this, _element2, null);
3133
+ }
3134
+ // ─── Configuration ──────────────────────────────────────
3135
+ configure(config) {
3136
+ __privateGet(this, _controller2).configure(config);
3137
+ }
3138
+ // ─── Show Methods ───────────────────────────────────────
3139
+ show(options) {
3140
+ __privateMethod(this, _ToastSingleton_instances, ensureElement_fn2).call(this);
3141
+ return __privateGet(this, _controller2).show(options);
3142
+ }
3143
+ success(message, options) {
3144
+ __privateMethod(this, _ToastSingleton_instances, ensureElement_fn2).call(this);
3145
+ return __privateGet(this, _controller2).success(message, options);
3146
+ }
3147
+ error(message, options) {
3148
+ __privateMethod(this, _ToastSingleton_instances, ensureElement_fn2).call(this);
3149
+ return __privateGet(this, _controller2).error(message, options);
3150
+ }
3151
+ warning(message, options) {
3152
+ __privateMethod(this, _ToastSingleton_instances, ensureElement_fn2).call(this);
3153
+ return __privateGet(this, _controller2).warning(message, options);
3154
+ }
3155
+ info(message, options) {
3156
+ __privateMethod(this, _ToastSingleton_instances, ensureElement_fn2).call(this);
3157
+ return __privateGet(this, _controller2).info(message, options);
3158
+ }
3159
+ loading(message, options) {
3160
+ __privateMethod(this, _ToastSingleton_instances, ensureElement_fn2).call(this);
3161
+ return __privateGet(this, _controller2).loading(message, options);
3162
+ }
3163
+ // ─── Dismiss ────────────────────────────────────────────
3164
+ dismiss(id) {
3165
+ __privateGet(this, _controller2).dismiss(id);
3166
+ }
3167
+ dismissAll() {
3168
+ __privateGet(this, _controller2).dismissAll();
3169
+ }
3170
+ // ─── Update ─────────────────────────────────────────────
3171
+ update(id, patch) {
3172
+ __privateGet(this, _controller2).update(id, patch);
3173
+ }
3174
+ // ─── Advanced ───────────────────────────────────────────
3175
+ get controller() {
3176
+ return __privateGet(this, _controller2);
3177
+ }
3178
+ };
3179
+ _controller2 = new WeakMap();
3180
+ _element2 = new WeakMap();
3181
+ _ToastSingleton_instances = new WeakSet();
3182
+ ensureElement_fn2 = function() {
3183
+ if (__privateGet(this, _element2)) return;
3184
+ if (typeof document === "undefined") return;
3185
+ const el = document.createElement("toast-container");
3186
+ el.controller = __privateGet(this, _controller2);
3187
+ document.body.appendChild(el);
3188
+ __privateSet(this, _element2, el);
3189
+ };
3190
+ var toast = new ToastSingleton();
2287
3191
  export {
2288
3192
  DialogController,
2289
3193
  OverlayDialog,
2290
- dialog
3194
+ ToastContainer,
3195
+ ToastController,
3196
+ dialog,
3197
+ toast
2291
3198
  };
2292
3199
  //# sourceMappingURL=index.js.map