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