summaryrefslogtreecommitdiff
path: root/src/plugins/toast.js
blob: 8a6e2d37b815c4395dfdd3d2064f422a264ef6d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { useToast } from 'bootstrap-vue-next';

// Global toast plugin for Options API components
// Bootstrap Vue Next's useToast is a composable that needs setup() context
// This plugin makes it accessible globally via app.config.globalProperties

let toastController = null;

export const ToastPlugin = {
  install(app) {
    // Initialize toast controller in the app context
    // This will be called once during app setup
    app.mixin({
      beforeCreate() {
        // Only initialize once at the root
        if (!toastController && this === this.$root) {
          try {
            toastController = useToast();
          } catch (e) {
            console.warn('Failed to initialize toast controller:', e);
          }
        }
      },
    });

    // Provide global toast methods
    app.config.globalProperties.$toast = {
      show(options) {
        if (toastController?.create) {
          toastController.create(options);
        } else {
          console.warn('Toast controller not available:', options);
        }
      },
      info(body, options = {}) {
        this.show({
          ...options,
          body,
          props: {
            variant: 'info',
            isStatus: true,
            ...options.props,
          },
        });
      },
      success(body, options = {}) {
        this.show({
          ...options,
          body,
          props: {
            variant: 'success',
            isStatus: true,
            modelValue: 10000, // Auto-close after 10s
            // Note: Progress bar hidden via CSS in _toasts.scss (JS props don't work as documented in Bootstrap Vue Next 0.40.8)
            ...options.props,
          },
        });
      },
      warning(body, options = {}) {
        this.show({
          ...options,
          body,
          props: {
            variant: 'warning',
            isStatus: true,
            ...options.props,
          },
        });
      },
      danger(body, options = {}) {
        this.show({
          ...options,
          body,
          props: {
            variant: 'danger',
            isStatus: true,
            modelValue: false, // No auto-close; stays until X clicked
            ...options.props,
          },
        });
      },
    };
  },
};