@velkymx/vibeui 0.8.1 → 0.9.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.
Files changed (40) hide show
  1. package/README.md +171 -9
  2. package/dist/components/VibeAlert.vue.d.ts +12 -2
  3. package/dist/components/VibeAutocomplete.vue.d.ts +46 -0
  4. package/dist/components/VibeButton.vue.d.ts +4 -4
  5. package/dist/components/VibeDataTable.vue.d.ts +6 -6
  6. package/dist/components/VibeDatePicker.vue.d.ts +122 -0
  7. package/dist/components/VibeDraggable.vue.d.ts +81 -0
  8. package/dist/components/VibeDroppable.vue.d.ts +74 -0
  9. package/dist/components/VibeFileInput.vue.d.ts +133 -0
  10. package/dist/components/VibeFormCheckbox.vue.d.ts +1 -1
  11. package/dist/components/VibeFormDatepicker.vue.d.ts +1 -1
  12. package/dist/components/VibeFormGroup.vue.d.ts +1 -1
  13. package/dist/components/VibeFormInput.vue.d.ts +1 -1
  14. package/dist/components/VibeFormRadio.vue.d.ts +1 -1
  15. package/dist/components/VibeFormSelect.vue.d.ts +1 -1
  16. package/dist/components/VibeFormSpinbutton.vue.d.ts +1 -1
  17. package/dist/components/VibeFormSwitch.vue.d.ts +1 -1
  18. package/dist/components/VibeFormTextarea.vue.d.ts +1 -1
  19. package/dist/components/VibeFormWysiwyg.vue.d.ts +2 -2
  20. package/dist/components/VibeResizable.vue.d.ts +144 -0
  21. package/dist/components/VibeSkeleton.vue.d.ts +53 -0
  22. package/dist/components/VibeSlider.vue.d.ts +78 -0
  23. package/dist/components/VibeSortable.vue.d.ts +40 -0
  24. package/dist/components/VibeStepper.vue.d.ts +132 -0
  25. package/dist/components/VibeTab.vue.d.ts +45 -0
  26. package/dist/components/VibeTabs.vue.d.ts +82 -0
  27. package/dist/components/VibeToast.vue.d.ts +11 -0
  28. package/dist/components/VibeToastHost.vue.d.ts +15 -0
  29. package/dist/components/dndStore.d.ts +6 -0
  30. package/dist/components/index.d.ts +14 -1
  31. package/dist/composables/useForm.d.ts +22 -0
  32. package/dist/composables/usePosition.d.ts +20 -0
  33. package/dist/composables/useToast.d.ts +52 -0
  34. package/dist/directives/vTooltip.d.ts +25 -0
  35. package/dist/index.d.ts +6 -0
  36. package/dist/types.d.ts +11 -4
  37. package/dist/vibeui.css +1 -1
  38. package/dist/vibeui.es.js +4257 -1827
  39. package/dist/vibeui.umd.js +1 -1
  40. package/package.json +3 -1
@@ -0,0 +1,132 @@
1
+ import { PropType } from 'vue';
2
+ export interface StepperStep {
3
+ label: string;
4
+ description?: string;
5
+ disabled?: boolean;
6
+ icon?: string;
7
+ }
8
+ type StepperGuard = (currentIndex: number, direction: 'next' | 'prev') => boolean | Promise<boolean>;
9
+ declare function __VLS_template(): {
10
+ attrs: Partial<{}>;
11
+ slots: {
12
+ marker?(_: {
13
+ index: number;
14
+ step: StepperStep;
15
+ active: boolean;
16
+ }): any;
17
+ label?(_: {
18
+ index: number;
19
+ step: StepperStep;
20
+ }): any;
21
+ step?(_: {
22
+ index: number;
23
+ step: StepperStep;
24
+ }): any;
25
+ actions?(_: {
26
+ next: () => Promise<void>;
27
+ prev: () => Promise<void>;
28
+ isFirst: boolean;
29
+ isLast: boolean;
30
+ }): any;
31
+ };
32
+ refs: {};
33
+ rootEl: HTMLDivElement;
34
+ };
35
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
36
+ declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
37
+ modelValue: {
38
+ type: NumberConstructor;
39
+ default: number;
40
+ };
41
+ steps: {
42
+ type: PropType<StepperStep[]>;
43
+ required: true;
44
+ };
45
+ linear: {
46
+ type: BooleanConstructor;
47
+ default: boolean;
48
+ };
49
+ vertical: {
50
+ type: BooleanConstructor;
51
+ default: boolean;
52
+ };
53
+ beforeNext: {
54
+ type: PropType<StepperGuard>;
55
+ default: undefined;
56
+ };
57
+ beforePrev: {
58
+ type: PropType<StepperGuard>;
59
+ default: undefined;
60
+ };
61
+ nextText: {
62
+ type: StringConstructor;
63
+ default: string;
64
+ };
65
+ prevText: {
66
+ type: StringConstructor;
67
+ default: string;
68
+ };
69
+ finishText: {
70
+ type: StringConstructor;
71
+ default: string;
72
+ };
73
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
74
+ "update:modelValue": (index: number) => any;
75
+ finish: () => any;
76
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
77
+ modelValue: {
78
+ type: NumberConstructor;
79
+ default: number;
80
+ };
81
+ steps: {
82
+ type: PropType<StepperStep[]>;
83
+ required: true;
84
+ };
85
+ linear: {
86
+ type: BooleanConstructor;
87
+ default: boolean;
88
+ };
89
+ vertical: {
90
+ type: BooleanConstructor;
91
+ default: boolean;
92
+ };
93
+ beforeNext: {
94
+ type: PropType<StepperGuard>;
95
+ default: undefined;
96
+ };
97
+ beforePrev: {
98
+ type: PropType<StepperGuard>;
99
+ default: undefined;
100
+ };
101
+ nextText: {
102
+ type: StringConstructor;
103
+ default: string;
104
+ };
105
+ prevText: {
106
+ type: StringConstructor;
107
+ default: string;
108
+ };
109
+ finishText: {
110
+ type: StringConstructor;
111
+ default: string;
112
+ };
113
+ }>> & Readonly<{
114
+ "onUpdate:modelValue"?: ((index: number) => any) | undefined;
115
+ onFinish?: (() => any) | undefined;
116
+ }>, {
117
+ modelValue: number;
118
+ vertical: boolean;
119
+ prevText: string;
120
+ nextText: string;
121
+ linear: boolean;
122
+ beforeNext: StepperGuard;
123
+ beforePrev: StepperGuard;
124
+ finishText: string;
125
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
126
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
127
+ export default _default;
128
+ type __VLS_WithTemplateSlots<T, S> = T & {
129
+ new (): {
130
+ $slots: S;
131
+ };
132
+ };
@@ -0,0 +1,45 @@
1
+ declare function __VLS_template(): {
2
+ attrs: Partial<{}>;
3
+ slots: {
4
+ default?(_: {}): any;
5
+ };
6
+ refs: {};
7
+ rootEl: any;
8
+ };
9
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
10
+ declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
11
+ name: {
12
+ type: StringConstructor;
13
+ required: true;
14
+ };
15
+ label: {
16
+ type: StringConstructor;
17
+ required: true;
18
+ };
19
+ disabled: {
20
+ type: BooleanConstructor;
21
+ default: boolean;
22
+ };
23
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
24
+ name: {
25
+ type: StringConstructor;
26
+ required: true;
27
+ };
28
+ label: {
29
+ type: StringConstructor;
30
+ required: true;
31
+ };
32
+ disabled: {
33
+ type: BooleanConstructor;
34
+ default: boolean;
35
+ };
36
+ }>> & Readonly<{}>, {
37
+ disabled: boolean;
38
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
39
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
40
+ export default _default;
41
+ type __VLS_WithTemplateSlots<T, S> = T & {
42
+ new (): {
43
+ $slots: S;
44
+ };
45
+ };
@@ -0,0 +1,82 @@
1
+ import { PropType } from 'vue';
2
+ type TabsVariant = 'tabs' | 'pills' | 'underline';
3
+ declare function __VLS_template(): {
4
+ attrs: Partial<{}>;
5
+ slots: {
6
+ default?(_: {}): any;
7
+ };
8
+ refs: {};
9
+ rootEl: HTMLDivElement;
10
+ };
11
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
12
+ declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
13
+ modelValue: {
14
+ type: StringConstructor;
15
+ default: undefined;
16
+ };
17
+ variant: {
18
+ type: PropType<TabsVariant>;
19
+ default: string;
20
+ };
21
+ fill: {
22
+ type: BooleanConstructor;
23
+ default: boolean;
24
+ };
25
+ justified: {
26
+ type: BooleanConstructor;
27
+ default: boolean;
28
+ };
29
+ vertical: {
30
+ type: BooleanConstructor;
31
+ default: boolean;
32
+ };
33
+ lazy: {
34
+ type: BooleanConstructor;
35
+ default: boolean;
36
+ };
37
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
38
+ "update:modelValue": (name: string) => any;
39
+ change: (name: string) => any;
40
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
41
+ modelValue: {
42
+ type: StringConstructor;
43
+ default: undefined;
44
+ };
45
+ variant: {
46
+ type: PropType<TabsVariant>;
47
+ default: string;
48
+ };
49
+ fill: {
50
+ type: BooleanConstructor;
51
+ default: boolean;
52
+ };
53
+ justified: {
54
+ type: BooleanConstructor;
55
+ default: boolean;
56
+ };
57
+ vertical: {
58
+ type: BooleanConstructor;
59
+ default: boolean;
60
+ };
61
+ lazy: {
62
+ type: BooleanConstructor;
63
+ default: boolean;
64
+ };
65
+ }>> & Readonly<{
66
+ "onUpdate:modelValue"?: ((name: string) => any) | undefined;
67
+ onChange?: ((name: string) => any) | undefined;
68
+ }>, {
69
+ variant: TabsVariant;
70
+ modelValue: string;
71
+ fill: boolean;
72
+ lazy: boolean;
73
+ vertical: boolean;
74
+ justified: boolean;
75
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
76
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
77
+ export default _default;
78
+ type __VLS_WithTemplateSlots<T, S> = T & {
79
+ new (): {
80
+ $slots: S;
81
+ };
82
+ };
@@ -8,6 +8,8 @@ declare function __VLS_template(): {
8
8
  attrs: Partial<{}>;
9
9
  slots: {
10
10
  header?(_: {}): any;
11
+ header?(_: {}): any;
12
+ default?(_: {}): any;
11
13
  default?(_: {}): any;
12
14
  };
13
15
  refs: {
@@ -49,6 +51,10 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
49
51
  type: () => ToastPlacement;
50
52
  default: string;
51
53
  };
54
+ noContainer: {
55
+ type: BooleanConstructor;
56
+ default: boolean;
57
+ };
52
58
  }>, {
53
59
  show: () => void | undefined;
54
60
  hide: () => void | undefined;
@@ -101,6 +107,10 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
101
107
  type: () => ToastPlacement;
102
108
  default: string;
103
109
  };
110
+ noContainer: {
111
+ type: BooleanConstructor;
112
+ default: boolean;
113
+ };
104
114
  }>> & Readonly<{
105
115
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
106
116
  "onComponent-error"?: ((...args: any[]) => any) | undefined;
@@ -117,6 +127,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
117
127
  placement: ToastPlacement;
118
128
  autohide: boolean;
119
129
  delay: number;
130
+ noContainer: boolean;
120
131
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
121
132
  toastRef: HTMLDivElement;
122
133
  }, any>;
@@ -0,0 +1,15 @@
1
+ import { ToastPlacement } from '../types';
2
+ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
3
+ defaultPlacement: {
4
+ type: () => ToastPlacement;
5
+ default: string;
6
+ };
7
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
8
+ defaultPlacement: {
9
+ type: () => ToastPlacement;
10
+ default: string;
11
+ };
12
+ }>> & Readonly<{}>, {
13
+ defaultPlacement: ToastPlacement;
14
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
15
+ export default _default;
@@ -0,0 +1,6 @@
1
+ export declare const setActiveDrag: (payload: unknown, group: string) => void;
2
+ export declare const clearActiveDrag: () => void;
3
+ export declare const getActiveDrag: () => {
4
+ payload: unknown;
5
+ group: string;
6
+ } | null;
@@ -5,6 +5,7 @@ import { default as VibeButtonGroup } from './VibeButtonGroup.vue';
5
5
  import { default as VibeCloseButton } from './VibeCloseButton.vue';
6
6
  import { default as VibeSpinner } from './VibeSpinner.vue';
7
7
  import { default as VibePlaceholder } from './VibePlaceholder.vue';
8
+ import { default as VibeSkeleton } from './VibeSkeleton.vue';
8
9
  import { default as VibeContainer } from './VibeContainer.vue';
9
10
  import { default as VibeRow } from './VibeRow.vue';
10
11
  import { default as VibeCol } from './VibeCol.vue';
@@ -17,6 +18,8 @@ import { default as VibeNavbarToggle } from './VibeNavbarToggle.vue';
17
18
  import { default as VibeNavbarNav } from './VibeNavbarNav.vue';
18
19
  import { default as VibePagination } from './VibePagination.vue';
19
20
  import { default as VibeTabContent } from './VibeTabContent.vue';
21
+ import { default as VibeTabs } from './VibeTabs.vue';
22
+ import { default as VibeTab } from './VibeTab.vue';
20
23
  import { default as VibeListGroup } from './VibeListGroup.vue';
21
24
  import { default as VibeProgress } from './VibeProgress.vue';
22
25
  import { default as VibeAccordion } from './VibeAccordion.vue';
@@ -25,6 +28,7 @@ import { default as VibeDropdown } from './VibeDropdown.vue';
25
28
  import { default as VibeModal } from './VibeModal.vue';
26
29
  import { default as VibeOffcanvas } from './VibeOffcanvas.vue';
27
30
  import { default as VibeToast } from './VibeToast.vue';
31
+ import { default as VibeToastHost } from './VibeToastHost.vue';
28
32
  import { default as VibeCarousel } from './VibeCarousel.vue';
29
33
  import { default as VibeTooltip } from './VibeTooltip.vue';
30
34
  import { default as VibePopover } from './VibePopover.vue';
@@ -36,6 +40,15 @@ import { default as VibeFormSelect } from './VibeFormSelect.vue';
36
40
  import { default as VibeFormTextarea } from './VibeFormTextarea.vue';
37
41
  import { default as VibeFormSpinbutton } from './VibeFormSpinbutton.vue';
38
42
  import { default as VibeFormDatepicker } from './VibeFormDatepicker.vue';
43
+ import { default as VibeFileInput } from './VibeFileInput.vue';
44
+ import { default as VibeSlider } from './VibeSlider.vue';
45
+ import { default as VibeStepper } from './VibeStepper.vue';
46
+ import { default as VibeAutocomplete } from './VibeAutocomplete.vue';
47
+ import { default as VibeSortable } from './VibeSortable.vue';
48
+ import { default as VibeDraggable } from './VibeDraggable.vue';
49
+ import { default as VibeDroppable } from './VibeDroppable.vue';
50
+ import { default as VibeResizable } from './VibeResizable.vue';
51
+ import { default as VibeDatePicker } from './VibeDatePicker.vue';
39
52
  import { default as VibeFormCheckbox } from './VibeFormCheckbox.vue';
40
53
  import { default as VibeFormRadio } from './VibeFormRadio.vue';
41
54
  import { default as VibeFormSwitch } from './VibeFormSwitch.vue';
@@ -44,6 +57,6 @@ import { default as VibeFormWysiwyg } from './VibeFormWysiwyg.vue';
44
57
  import { default as VibeInputGroup } from './VibeInputGroup.vue';
45
58
  import { default as VibeLink } from './VibeLink.vue';
46
59
  import { Plugin } from 'vue';
47
- export { VibeAlert, VibeBadge, VibeButton, VibeButtonGroup, VibeCloseButton, VibeSpinner, VibePlaceholder, VibeContainer, VibeRow, VibeCol, VibeCard, VibeBreadcrumb, VibeNav, VibeNavbar, VibeNavbarBrand, VibeNavbarToggle, VibeNavbarNav, VibePagination, VibeTabContent, VibeListGroup, VibeProgress, VibeAccordion, VibeCollapse, VibeDropdown, VibeModal, VibeOffcanvas, VibeToast, VibeCarousel, VibeTooltip, VibePopover, VibeScrollspy, VibeIcon, VibeDataTable, VibeFormInput, VibeFormSelect, VibeFormTextarea, VibeFormSpinbutton, VibeFormDatepicker, VibeFormCheckbox, VibeFormRadio, VibeFormSwitch, VibeFormGroup, VibeFormWysiwyg, VibeInputGroup, VibeLink };
60
+ export { VibeAlert, VibeBadge, VibeButton, VibeButtonGroup, VibeCloseButton, VibeSpinner, VibePlaceholder, VibeSkeleton, VibeContainer, VibeRow, VibeCol, VibeCard, VibeBreadcrumb, VibeNav, VibeNavbar, VibeNavbarBrand, VibeNavbarToggle, VibeNavbarNav, VibePagination, VibeTabContent, VibeTabs, VibeTab, VibeListGroup, VibeProgress, VibeAccordion, VibeCollapse, VibeDropdown, VibeModal, VibeOffcanvas, VibeToast, VibeToastHost, VibeCarousel, VibeTooltip, VibePopover, VibeScrollspy, VibeIcon, VibeDataTable, VibeFormInput, VibeFormSelect, VibeFormTextarea, VibeFormSpinbutton, VibeFormDatepicker, VibeFileInput, VibeSlider, VibeStepper, VibeAutocomplete, VibeSortable, VibeDraggable, VibeDroppable, VibeResizable, VibeDatePicker, VibeFormCheckbox, VibeFormRadio, VibeFormSwitch, VibeFormGroup, VibeFormWysiwyg, VibeInputGroup, VibeLink };
48
61
  declare const VibeUIPlugin: Plugin;
49
62
  export default VibeUIPlugin;
@@ -0,0 +1,22 @@
1
+ import { ComputedRef } from 'vue';
2
+ import { ValidationRule, ValidatorFunction } from '../types';
3
+ export type FormFieldRules<T> = Partial<Record<keyof T, ValidationRule[] | ValidatorFunction>>;
4
+ export interface FormValidateResult<T> {
5
+ valid: boolean;
6
+ errors: Partial<Record<keyof T, string>>;
7
+ }
8
+ export interface UseFormReturn<T extends Record<string, unknown>> {
9
+ fields: T;
10
+ errors: Record<keyof T, string>;
11
+ touched: Record<keyof T, boolean>;
12
+ isDirty: ComputedRef<boolean>;
13
+ isValid: ComputedRef<boolean>;
14
+ values: ComputedRef<T>;
15
+ validate: (rules: FormFieldRules<T>) => Promise<FormValidateResult<T>>;
16
+ validateField: <K extends keyof T>(key: K, rule: ValidationRule[] | ValidatorFunction) => Promise<string>;
17
+ reset: () => void;
18
+ markTouched: <K extends keyof T>(key: K) => void;
19
+ markAllTouched: () => void;
20
+ setField: <K extends keyof T>(key: K, value: T[K]) => void;
21
+ }
22
+ export declare function useForm<T extends Record<string, unknown>>(initial: T): UseFormReturn<T>;
@@ -0,0 +1,20 @@
1
+ import { Placement } from '@floating-ui/dom';
2
+ import { Ref, ComputedRef } from 'vue';
3
+ type AnchorPoint = 'top start' | 'top center' | 'top end' | 'center start' | 'center center' | 'center end' | 'bottom start' | 'bottom center' | 'bottom end';
4
+ export interface UsePositionOptions {
5
+ my?: AnchorPoint;
6
+ at?: AnchorPoint;
7
+ offset?: [number, number];
8
+ collision?: 'flip' | 'shift' | 'flip+shift' | 'none';
9
+ autoUpdate?: boolean;
10
+ strategy?: 'absolute' | 'fixed';
11
+ }
12
+ export interface UsePositionReturn {
13
+ x: Ref<number>;
14
+ y: Ref<number>;
15
+ placement: Ref<Placement>;
16
+ update: () => Promise<void>;
17
+ stop: () => void;
18
+ }
19
+ export declare function usePosition(target: Ref<HTMLElement | null> | ComputedRef<HTMLElement | null>, anchor: Ref<HTMLElement | null> | ComputedRef<HTMLElement | null>, options?: UsePositionOptions | (() => UsePositionOptions)): UsePositionReturn;
20
+ export {};
@@ -0,0 +1,52 @@
1
+ import { DeepReadonly } from 'vue';
2
+ import { Variant, ToastPlacement } from '../types';
3
+ export interface ToastSpec {
4
+ id: string;
5
+ title?: string;
6
+ body: string;
7
+ variant?: Variant;
8
+ placement?: ToastPlacement;
9
+ autohide?: boolean;
10
+ delay?: number;
11
+ }
12
+ export interface ToastShowOptions {
13
+ id?: string;
14
+ title?: string;
15
+ variant?: Variant;
16
+ placement?: ToastPlacement;
17
+ autohide?: boolean;
18
+ delay?: number;
19
+ }
20
+ export interface UseToastReturn {
21
+ toasts: DeepReadonly<ToastSpec[]>;
22
+ show: (body: string, options?: ToastShowOptions) => ToastSpec;
23
+ success: (body: string, options?: Omit<ToastShowOptions, 'variant'>) => ToastSpec;
24
+ error: (body: string, options?: Omit<ToastShowOptions, 'variant'>) => ToastSpec;
25
+ warn: (body: string, options?: Omit<ToastShowOptions, 'variant'>) => ToastSpec;
26
+ info: (body: string, options?: Omit<ToastShowOptions, 'variant'>) => ToastSpec;
27
+ dismiss: (id: string) => boolean;
28
+ clear: () => void;
29
+ }
30
+ export declare function useToast(): UseToastReturn;
31
+ export declare const __resetToastStoreForTests: () => void;
32
+ /**
33
+ * Resets the toast store between SSR requests. The toast queue is a module
34
+ * singleton, so the same instance is shared across requests in an SSR runtime.
35
+ * Call this in your server entry's per-request reset hook to avoid leaking
36
+ * one request's pending toasts into another's render output.
37
+ *
38
+ * Multi-app browser usage shares the same queue; if this is undesirable, use
39
+ * the component-form `<VibeToast v-model="...">` for app-local toasts.
40
+ */
41
+ export declare const resetToastStoreForSSR: () => void;
42
+ export declare const __toastStore: {
43
+ toasts: {
44
+ id: string;
45
+ title?: string | undefined;
46
+ body: string;
47
+ variant?: Variant | undefined;
48
+ placement?: ToastPlacement | undefined;
49
+ autohide?: boolean | undefined;
50
+ delay?: number | undefined;
51
+ }[];
52
+ };
@@ -0,0 +1,25 @@
1
+ import { Directive } from 'vue';
2
+ import { Placement } from '../types';
3
+ interface BootstrapTooltipInstance {
4
+ dispose: () => void;
5
+ setContent: (content: Record<string, string>) => void;
6
+ }
7
+ interface TooltipOptions {
8
+ title?: string;
9
+ text?: string;
10
+ content?: string;
11
+ placement?: Placement;
12
+ trigger?: string;
13
+ html?: boolean;
14
+ }
15
+ type TooltipBindingValue = string | TooltipOptions | undefined;
16
+ declare const INSTANCE_KEY: unique symbol;
17
+ declare const PENDING_KEY: unique symbol;
18
+ declare const OPTS_KEY: unique symbol;
19
+ interface AugmentedElement extends HTMLElement {
20
+ [INSTANCE_KEY]?: BootstrapTooltipInstance | null;
21
+ [PENDING_KEY]?: boolean;
22
+ [OPTS_KEY]?: TooltipOptions;
23
+ }
24
+ export declare const vTooltip: Directive<AugmentedElement, TooltipBindingValue>;
25
+ export default vTooltip;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,12 @@ import { default as VibeUIPlugin } from './components';
2
2
  export * from './components';
3
3
  export * from './types';
4
4
  export * from './composables/useFormValidation';
5
+ export * from './composables/useForm';
6
+ export { vTooltip } from './directives/vTooltip';
7
+ export { useToast, resetToastStoreForSSR } from './composables/useToast';
8
+ export type { ToastSpec, ToastShowOptions, UseToastReturn } from './composables/useToast';
9
+ export { usePosition } from './composables/usePosition';
10
+ export type { UsePositionOptions, UsePositionReturn } from './composables/usePosition';
5
11
  export { useId } from './composables/useId';
6
12
  export { useColorMode } from './composables/useColorMode';
7
13
  export { useBreakpoints } from './composables/useBreakpoints';
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export type ColorMode = 'light' | 'dark' | 'auto';
2
2
  export type Variant = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark';
3
+ export type ButtonVariant = Variant | 'link';
3
4
  export type Size = 'sm' | 'lg';
4
5
  export type ButtonType = 'button' | 'submit' | 'reset';
5
6
  export type Placement = 'top' | 'bottom' | 'start' | 'end';
@@ -18,17 +19,22 @@ export type OrderValue = 0 | 1 | 2 | 3 | 4 | 5 | 'first' | 'last';
18
19
  export type AlignItems = 'start' | 'center' | 'end' | 'baseline' | 'stretch';
19
20
  export type JustifyContent = 'start' | 'center' | 'end' | 'around' | 'between' | 'evenly';
20
21
  export type SortDirection = 'asc' | 'desc' | null;
21
- export interface DataTableColumn {
22
- key: string;
22
+ export interface DataTableColumn<T extends Record<string, unknown> = Record<string, unknown>> {
23
+ key: keyof T & string;
23
24
  label: string;
24
25
  sortable?: boolean;
25
26
  searchable?: boolean;
26
- formatter?: (value: any, row: any) => string | number;
27
+ formatter?: (value: T[keyof T], row: T) => string | number;
27
28
  class?: string;
28
29
  headerClass?: string;
29
30
  thStyle?: Record<string, string>;
30
31
  tdStyle?: Record<string, string>;
31
32
  }
33
+ export interface DataTableCellSlotProps<T extends Record<string, unknown> = Record<string, unknown>> {
34
+ item: T;
35
+ value: T[keyof T];
36
+ index: number;
37
+ }
32
38
  export interface DataTableSort {
33
39
  key: string;
34
40
  direction: 'asc' | 'desc';
@@ -111,8 +117,9 @@ export interface FormValidationResult {
111
117
  valid: boolean;
112
118
  message?: string;
113
119
  }
120
+ export type FormSelectOptionValue = string | number | boolean | null | undefined;
114
121
  export interface FormSelectOption {
115
- value: string | number;
122
+ value: FormSelectOptionValue;
116
123
  text: string;
117
124
  disabled?: boolean;
118
125
  }
package/dist/vibeui.css CHANGED
@@ -1 +1 @@
1
- .navbar.fixed-top[data-v-8228b170],.navbar.sticky-top[data-v-8228b170]{padding-top:env(safe-area-inset-top,0)}.navbar.fixed-bottom[data-v-8228b170]{padding-bottom:env(safe-area-inset-bottom,0)}.modal.show .modal-dialog.modal-fullscreen[data-v-c11ac690],.modal.show .modal-dialog.modal-fullscreen .modal-content[data-v-c11ac690]{height:100dvh}.modal-header[data-v-c11ac690]{padding-top:calc(1rem + env(safe-area-inset-top,0))}.modal-footer[data-v-c11ac690]{padding-bottom:calc(.75rem + env(safe-area-inset-bottom,0))}.offcanvas.offcanvas-start[data-v-f03bd194],.offcanvas.offcanvas-end[data-v-f03bd194]{height:100dvh}.offcanvas.offcanvas-top[data-v-f03bd194],.offcanvas.offcanvas-bottom[data-v-f03bd194]{max-height:100dvh}.offcanvas-header[data-v-f03bd194]{padding-top:calc(1rem + env(safe-area-inset-top,0))}.offcanvas-body[data-v-f03bd194]{padding-bottom:calc(1rem + env(safe-area-inset-bottom,0))}.vibe-datatable[data-v-c496dc70]{width:100%}.datatable-info[data-v-c496dc70]{padding:.5rem 0;color:var(--bs-secondary-color)}@media(max-width:767.98px){.vibe-table-stack[data-v-c496dc70],.vibe-table-stack tbody[data-v-c496dc70],.vibe-table-stack tr[data-v-c496dc70],.vibe-table-stack td[data-v-c496dc70]{display:block;width:100%}.vibe-table-stack thead[data-v-c496dc70]{display:none}.vibe-table-stack tr[data-v-c496dc70]{margin-bottom:1rem;border:1px solid var(--bs-border-color);border-radius:.375rem;background-color:var(--bs-body-bg)}.vibe-table-stack td[data-v-c496dc70]{text-align:right;padding:.5rem 1rem;position:relative;padding-left:50%;border-top:none;border-bottom:1px solid var(--bs-border-color)}.vibe-table-stack td[data-v-c496dc70]:last-child{border-bottom:none}.vibe-table-stack td[data-v-c496dc70]:before{content:attr(data-label);position:absolute;left:1rem;width:45%;text-align:left;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}.input-group-vertical[data-v-49746a62]{flex-direction:column}.input-group-vertical[data-v-49746a62]>*{width:100%}.vibe-wysiwyg-container[data-v-952f7269]{border:1px solid var(--bs-border-color);border-radius:.375rem}.vibe-wysiwyg-container.is-valid[data-v-952f7269]{border-color:var(--bs-success)}.vibe-wysiwyg-container.is-invalid[data-v-952f7269]{border-color:var(--bs-danger)}.vibe-wysiwyg-container.disabled[data-v-952f7269]{background-color:var(--bs-secondary-bg);opacity:.6;cursor:not-allowed}.vibe-wysiwyg-container[data-v-952f7269] .ql-container{border:none;font-size:1rem}.vibe-wysiwyg-container[data-v-952f7269] .ql-toolbar{border:none;border-bottom:1px solid var(--bs-border-color);border-top-left-radius:.375rem;border-top-right-radius:.375rem}.vibe-wysiwyg-container[data-v-952f7269] .ql-editor{min-height:150px}
1
+ .vibe-skeleton[data-v-37d19d6e]{display:block;background-color:var(--bs-secondary-bg, #e9ecef);border-radius:.25rem;position:relative;overflow:hidden}.vibe-skeleton-text[data-v-37d19d6e]{height:.875rem;margin-bottom:.5rem;width:100%}.vibe-skeleton-text[data-v-37d19d6e]:last-child{margin-bottom:0}.vibe-skeleton-rect[data-v-37d19d6e]{width:100%;height:1rem}.vibe-skeleton-circle[data-v-37d19d6e]{border-radius:50%;width:2.5rem;height:2.5rem}.vibe-skeleton-card[data-v-37d19d6e]{display:flex;flex-direction:column;gap:.5rem}.vibe-skeleton-animated[data-v-37d19d6e]:after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.45) 50%,transparent 100%);transform:translate(-100%);animation:vibe-skeleton-shimmer-37d19d6e 1.4s infinite}@keyframes vibe-skeleton-shimmer-37d19d6e{to{transform:translate(100%)}}@media(prefers-color-scheme:dark){.vibe-skeleton[data-v-37d19d6e]{background-color:var(--bs-secondary-bg, #2b3035)}.vibe-skeleton-animated[data-v-37d19d6e]:after{background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.08) 50%,transparent 100%)}}@media(prefers-reduced-motion:reduce){.vibe-skeleton-animated[data-v-37d19d6e]:after{animation:none}}.navbar.fixed-top[data-v-8228b170],.navbar.sticky-top[data-v-8228b170]{padding-top:env(safe-area-inset-top,0)}.navbar.fixed-bottom[data-v-8228b170]{padding-bottom:env(safe-area-inset-bottom,0)}.modal.show .modal-dialog.modal-fullscreen[data-v-c11ac690],.modal.show .modal-dialog.modal-fullscreen .modal-content[data-v-c11ac690]{height:100dvh}.modal-header[data-v-c11ac690]{padding-top:calc(1rem + env(safe-area-inset-top,0))}.modal-footer[data-v-c11ac690]{padding-bottom:calc(.75rem + env(safe-area-inset-bottom,0))}.offcanvas.offcanvas-start[data-v-f03bd194],.offcanvas.offcanvas-end[data-v-f03bd194]{height:100dvh}.offcanvas.offcanvas-top[data-v-f03bd194],.offcanvas.offcanvas-bottom[data-v-f03bd194]{max-height:100dvh}.offcanvas-header[data-v-f03bd194]{padding-top:calc(1rem + env(safe-area-inset-top,0))}.offcanvas-body[data-v-f03bd194]{padding-bottom:calc(1rem + env(safe-area-inset-bottom,0))}.vibe-datatable[data-v-3d846265]{width:100%}.datatable-info[data-v-3d846265]{padding:.5rem 0;color:var(--bs-secondary-color)}@media(max-width:767.98px){.vibe-table-stack[data-v-3d846265],.vibe-table-stack tbody[data-v-3d846265],.vibe-table-stack tr[data-v-3d846265],.vibe-table-stack td[data-v-3d846265]{display:block;width:100%}.vibe-table-stack thead[data-v-3d846265]{display:none}.vibe-table-stack tr[data-v-3d846265]{margin-bottom:1rem;border:1px solid var(--bs-border-color);border-radius:.375rem;background-color:var(--bs-body-bg)}.vibe-table-stack td[data-v-3d846265]{text-align:right;padding:.5rem 1rem;position:relative;padding-left:50%;border-top:none;border-bottom:1px solid var(--bs-border-color)}.vibe-table-stack td[data-v-3d846265]:last-child{border-bottom:none}.vibe-table-stack td[data-v-3d846265]:before{content:attr(data-label);position:absolute;left:1rem;width:45%;text-align:left;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}.input-group-vertical[data-v-49746a62]{flex-direction:column}.input-group-vertical[data-v-49746a62]>*{width:100%}.vibe-file-input-dropzone[data-v-258bd632]{border:2px dashed var(--bs-border-color, #ced4da);border-radius:.375rem;padding:1.5rem;text-align:center;cursor:pointer;transition:border-color .15s ease,background-color .15s ease}.vibe-file-input-dropzone-active[data-v-258bd632]{border-color:var(--bs-primary, #0d6efd);background-color:var(--bs-primary-bg-subtle, rgba(13, 110, 253, .05))}.vibe-file-input-dropzone-disabled[data-v-258bd632]{cursor:not-allowed;opacity:.65}.vibe-slider[data-v-5b520fda]{--vibe-slider-track-height: 6px;--vibe-slider-handle-size: 18px;position:relative;width:100%;padding:calc(var(--vibe-slider-handle-size) / 2) 0;-webkit-user-select:none;user-select:none}.vibe-slider-vertical[data-v-5b520fda]{width:var(--vibe-slider-handle-size);height:200px;padding:0 calc(var(--vibe-slider-handle-size) / 2)}.vibe-slider-track[data-v-5b520fda]{position:relative;width:100%;height:var(--vibe-slider-track-height);background-color:var(--bs-secondary-bg, #e9ecef);border-radius:calc(var(--vibe-slider-track-height) / 2)}.vibe-slider-vertical .vibe-slider-track[data-v-5b520fda]{width:var(--vibe-slider-track-height);height:100%}.vibe-slider-fill[data-v-5b520fda]{position:absolute;inset:0;background-color:var(--bs-primary, #0d6efd);border-radius:inherit}.vibe-slider-handle[data-v-5b520fda]{position:absolute;width:var(--vibe-slider-handle-size);height:var(--vibe-slider-handle-size);background-color:#fff;border:2px solid var(--bs-primary, #0d6efd);border-radius:50%;top:50%;transform:translate(-50%,-50%);cursor:grab;touch-action:none}.vibe-slider-vertical .vibe-slider-handle[data-v-5b520fda]{top:auto;left:50%;transform:translate(-50%,50%)}.vibe-slider-handle[data-v-5b520fda]:focus-visible{outline:2px solid var(--bs-primary, #0d6efd);outline-offset:2px}.vibe-slider-handle[data-v-5b520fda]:active{cursor:grabbing}.vibe-slider-disabled[data-v-5b520fda]{opacity:.55;pointer-events:none}.vibe-stepper-header[data-v-c693b42b]{display:flex;list-style:none;padding:0;margin:0 0 1.5rem;gap:0}.vibe-stepper-vertical .vibe-stepper-header[data-v-c693b42b]{flex-direction:column;gap:.5rem}.vibe-stepper-step[data-v-c693b42b]{display:flex;align-items:center;gap:.5rem;flex:1;cursor:pointer;padding:.5rem .75rem;position:relative;color:var(--bs-secondary-color, #6c757d)}.vibe-stepper-step[data-v-c693b42b]:not(:last-child):after{content:"";flex:1;height:1px;background-color:var(--bs-border-color, #dee2e6);margin-left:.75rem}.vibe-stepper-vertical .vibe-stepper-step[data-v-c693b42b]:not(:last-child):after{display:none}.vibe-stepper-marker[data-v-c693b42b]{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border-radius:50%;background-color:var(--bs-secondary-bg, #e9ecef);font-weight:600;flex-shrink:0}.vibe-stepper-active .vibe-stepper-marker[data-v-c693b42b]{background-color:var(--bs-primary, #0d6efd);color:#fff}.vibe-stepper-completed .vibe-stepper-marker[data-v-c693b42b]{background-color:var(--bs-success, #198754);color:#fff}.vibe-stepper-active[data-v-c693b42b]{color:var(--bs-body-color, inherit);font-weight:600}.vibe-stepper-locked[data-v-c693b42b],.vibe-stepper-disabled[data-v-c693b42b]{cursor:not-allowed;opacity:.6}.vibe-stepper-label[data-v-c693b42b]{display:flex;flex-direction:column}.vibe-stepper-description[data-v-c693b42b]{font-size:.85em;color:var(--bs-secondary-color, #6c757d);font-weight:400}.vibe-stepper-body[data-v-c693b42b]{margin-bottom:1.5rem}.vibe-stepper-actions[data-v-c693b42b]{display:flex;justify-content:space-between;gap:.5rem}.vibe-autocomplete[data-v-ccd7df7d]{position:relative}.vibe-autocomplete-menu[data-v-ccd7df7d]{position:absolute;top:100%;left:0;right:0;z-index:1050;list-style:none;margin:0;padding:.25rem 0;background-color:var(--bs-body-bg, white);border:1px solid var(--bs-border-color, #dee2e6);border-radius:.375rem;box-shadow:0 .5rem 1rem #00000026;max-height:240px;overflow-y:auto}.vibe-autocomplete-item[data-v-ccd7df7d]{padding:.375rem .75rem;cursor:pointer}.vibe-autocomplete-item-highlighted[data-v-ccd7df7d]{background-color:var(--bs-primary-bg-subtle, #cfe2ff)}.vibe-autocomplete-empty[data-v-ccd7df7d]{padding:.5rem .75rem;color:var(--bs-secondary-color, #6c757d);font-style:italic}.vibe-sortable-item[data-v-651679ac]{cursor:grab}.vibe-sortable-item.vibe-sortable-dragging[data-v-651679ac]{opacity:.4;cursor:grabbing}.vibe-draggable[data-v-633735d3]{cursor:grab}.vibe-draggable-dragging[data-v-633735d3]{opacity:.5;cursor:grabbing}.vibe-draggable-disabled[data-v-633735d3]{cursor:not-allowed}.vibe-droppable-over[data-v-b75c06d6]{outline:2px dashed var(--bs-primary, #0d6efd);outline-offset:-2px}.vibe-droppable-disabled[data-v-b75c06d6]{opacity:.6}.vibe-resizable[data-v-cf1014a7]{position:relative;display:inline-block;box-sizing:border-box}.vibe-resizable-handle[data-v-cf1014a7]{position:absolute;background-color:transparent;z-index:10}.vibe-resizable-active[data-v-cf1014a7]{-webkit-user-select:none;user-select:none}.vibe-resizable-disabled .vibe-resizable-handle[data-v-cf1014a7]{pointer-events:none}.vibe-resizable-handle-n[data-v-cf1014a7],.vibe-resizable-handle-s[data-v-cf1014a7]{left:0;right:0;height:6px;cursor:ns-resize}.vibe-resizable-handle-n[data-v-cf1014a7]{top:-3px}.vibe-resizable-handle-s[data-v-cf1014a7]{bottom:-3px}.vibe-resizable-handle-e[data-v-cf1014a7],.vibe-resizable-handle-w[data-v-cf1014a7]{top:0;bottom:0;width:6px;cursor:ew-resize}.vibe-resizable-handle-e[data-v-cf1014a7]{right:-3px}.vibe-resizable-handle-w[data-v-cf1014a7]{left:-3px}.vibe-resizable-handle-ne[data-v-cf1014a7],.vibe-resizable-handle-nw[data-v-cf1014a7],.vibe-resizable-handle-se[data-v-cf1014a7],.vibe-resizable-handle-sw[data-v-cf1014a7]{width:12px;height:12px;z-index:11}.vibe-resizable-handle-ne[data-v-cf1014a7]{top:-6px;right:-6px;cursor:nesw-resize}.vibe-resizable-handle-nw[data-v-cf1014a7]{top:-6px;left:-6px;cursor:nwse-resize}.vibe-resizable-handle-se[data-v-cf1014a7]{bottom:-6px;right:-6px;cursor:nwse-resize}.vibe-resizable-handle-sw[data-v-cf1014a7]{bottom:-6px;left:-6px;cursor:nesw-resize}.vibe-datepicker[data-v-d18ee62c]{position:relative;display:inline-block;width:100%}.vibe-datepicker-popover[data-v-d18ee62c]{position:absolute;top:100%;left:0;z-index:1050;margin-top:.25rem;padding:.75rem;background-color:var(--bs-body-bg, white);border:1px solid var(--bs-border-color, #dee2e6);border-radius:.375rem;box-shadow:0 .5rem 1rem #00000026;min-width:280px}.vibe-datepicker-header[data-v-d18ee62c]{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.vibe-datepicker-nav[data-v-d18ee62c]{background:none;border:0;font-size:1.25rem;cursor:pointer;padding:.25rem .5rem}.vibe-datepicker-title[data-v-d18ee62c]{font-weight:600}.vibe-datepicker-weekdays[data-v-d18ee62c],.vibe-datepicker-grid[data-v-d18ee62c]{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.vibe-datepicker-weekday[data-v-d18ee62c]{text-align:center;font-size:.75rem;color:var(--bs-secondary-color, #6c757d);padding:.25rem 0}.vibe-datepicker-day[data-v-d18ee62c]{background:none;border:0;border-radius:.25rem;padding:.4rem 0;cursor:pointer;font-size:.875rem}.vibe-datepicker-day[data-v-d18ee62c]:hover:not(:disabled){background-color:var(--bs-secondary-bg, #e9ecef)}.vibe-datepicker-day-outside[data-v-d18ee62c]{opacity:.4}.vibe-datepicker-day-disabled[data-v-d18ee62c]{opacity:.3;cursor:not-allowed}.vibe-datepicker-day-today[data-v-d18ee62c]{font-weight:700;text-decoration:underline}.vibe-datepicker-day-selected[data-v-d18ee62c],.vibe-datepicker-day-range-start[data-v-d18ee62c],.vibe-datepicker-day-range-end[data-v-d18ee62c]{background-color:var(--bs-primary, #0d6efd);color:#fff}.vibe-datepicker-day-in-range[data-v-d18ee62c]{background-color:var(--bs-primary-bg-subtle, #cfe2ff)}.vibe-wysiwyg-container[data-v-10ea0dd0]{border:1px solid var(--bs-border-color);border-radius:.375rem}.vibe-wysiwyg-container.is-valid[data-v-10ea0dd0]{border-color:var(--bs-success)}.vibe-wysiwyg-container.is-invalid[data-v-10ea0dd0]{border-color:var(--bs-danger)}.vibe-wysiwyg-container.disabled[data-v-10ea0dd0]{background-color:var(--bs-secondary-bg);opacity:.6;cursor:not-allowed}.vibe-wysiwyg-container[data-v-10ea0dd0] .ql-container{border:none;font-size:1rem}.vibe-wysiwyg-container[data-v-10ea0dd0] .ql-toolbar{border:none;border-bottom:1px solid var(--bs-border-color);border-top-left-radius:.375rem;border-top-right-radius:.375rem}.vibe-wysiwyg-container[data-v-10ea0dd0] .ql-editor{min-height:150px}