@witchcraft/ui 0.3.1 → 0.3.3
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/module.json +1 -1
- package/dist/runtime/assets/animations.css +1 -0
- package/dist/runtime/assets/base.css +1 -1
- package/dist/runtime/assets/tailwind.css +1 -1
- package/dist/runtime/components/LibButton/LibButton.d.vue.ts +1 -1
- package/dist/runtime/components/LibButton/LibButton.vue.d.ts +1 -1
- package/dist/runtime/components/LibCheckbox/LibCheckbox.d.vue.ts +1 -1
- package/dist/runtime/components/LibCheckbox/LibCheckbox.vue.d.ts +1 -1
- package/dist/runtime/components/LibColorInput/LibColorInput.d.vue.ts +2 -2
- package/dist/runtime/components/LibColorInput/LibColorInput.vue.d.ts +2 -2
- package/dist/runtime/components/LibColorPicker/LibColorPicker.d.vue.ts +2 -2
- package/dist/runtime/components/LibColorPicker/LibColorPicker.vue.d.ts +2 -2
- package/dist/runtime/components/LibColorPicker/utils/safeConvertToHsva.d.ts +1 -1
- package/dist/runtime/components/LibColorPicker/utils/safeConvertToRgba.d.ts +1 -1
- package/dist/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.d.ts +1 -1
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.d.vue.ts +1 -1
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue.d.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibDatePicker.d.vue.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibDatePicker.vue.d.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.d.vue.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue.d.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.d.vue.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue.d.ts +1 -1
- package/dist/runtime/components/LibFileInput/LibFileInput.d.vue.ts +2 -2
- package/dist/runtime/components/LibFileInput/LibFileInput.vue.d.ts +2 -2
- package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.d.vue.ts +1 -1
- package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue.d.ts +1 -1
- package/dist/runtime/components/LibLabel/LibLabel.d.vue.ts +1 -1
- package/dist/runtime/components/LibLabel/LibLabel.vue.d.ts +1 -1
- package/dist/runtime/components/LibMultiValues/LibMultiValues.d.vue.ts +1 -1
- package/dist/runtime/components/LibMultiValues/LibMultiValues.vue.d.ts +1 -1
- package/dist/runtime/components/LibNotifications/LibNotification.d.vue.ts +17 -4
- package/dist/runtime/components/LibNotifications/LibNotification.vue +84 -25
- package/dist/runtime/components/LibNotifications/LibNotification.vue.d.ts +17 -4
- package/dist/runtime/components/LibNotifications/LibNotifications.d.vue.ts +2 -2
- package/dist/runtime/components/LibNotifications/LibNotifications.vue +110 -87
- package/dist/runtime/components/LibNotifications/LibNotifications.vue.d.ts +2 -2
- package/dist/runtime/components/LibPagination/LibPagination.d.vue.ts +1 -1
- package/dist/runtime/components/LibPagination/LibPagination.vue.d.ts +1 -1
- package/dist/runtime/components/LibPalette/LibPalette.d.vue.ts +1 -1
- package/dist/runtime/components/LibPalette/LibPalette.vue.d.ts +1 -1
- package/dist/runtime/components/LibPopup/LibPopup.d.vue.ts +4 -4
- package/dist/runtime/components/LibPopup/LibPopup.vue +2 -6
- package/dist/runtime/components/LibPopup/LibPopup.vue.d.ts +4 -4
- package/dist/runtime/components/LibProgressBar/LibProgressBar.d.vue.ts +2 -1
- package/dist/runtime/components/LibProgressBar/LibProgressBar.vue +1 -1
- package/dist/runtime/components/LibProgressBar/LibProgressBar.vue.d.ts +2 -1
- package/dist/runtime/components/LibRecorder/LibRecorder.d.vue.ts +1 -1
- package/dist/runtime/components/LibRecorder/LibRecorder.vue +1 -1
- package/dist/runtime/components/LibRecorder/LibRecorder.vue.d.ts +1 -1
- package/dist/runtime/components/LibRoot/LibRoot.d.vue.ts +2 -2
- package/dist/runtime/components/LibRoot/LibRoot.vue.d.ts +2 -2
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.d.vue.ts +1 -1
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue.d.ts +1 -1
- package/dist/runtime/components/LibSuggestions/LibSuggestions.d.vue.ts +1 -1
- package/dist/runtime/components/LibSuggestions/LibSuggestions.vue.d.ts +1 -1
- package/dist/runtime/components/LibTable/LibTable.d.vue.ts +2 -2
- package/dist/runtime/components/LibTable/LibTable.vue.d.ts +2 -2
- package/dist/runtime/components/Template/TemplateStory.d.ts +1 -1
- package/dist/runtime/components/index.d.ts +20 -20
- package/dist/runtime/components/shared/props.d.ts +1 -1
- package/dist/runtime/composables/index.d.ts +17 -15
- package/dist/runtime/composables/index.js +2 -0
- package/dist/runtime/composables/useDragWithThreshold.d.ts +1 -1
- package/dist/runtime/composables/useInjectedDarkMode.d.ts +1 -1
- package/dist/runtime/composables/useInjectedI18n.d.ts +1 -1
- package/dist/runtime/composables/useInjectedLocale.d.ts +1 -1
- package/dist/runtime/composables/useNotificationHandler.d.ts +1 -1
- package/dist/runtime/composables/useScrollNearContainerEdges.d.ts +1 -1
- package/dist/runtime/composables/useSetupDarkMode.d.ts +1 -1
- package/dist/runtime/composables/useSlotVars.d.ts +32 -0
- package/dist/runtime/composables/useSlotVars.js +12 -0
- package/dist/runtime/composables/useSuggestions.d.ts +1 -1
- package/dist/runtime/directives/index.d.ts +4 -4
- package/dist/runtime/globalResizeObserver.d.ts +1 -1
- package/dist/runtime/helpers/NotificationHandler.d.ts +11 -4
- package/dist/runtime/helpers/NotificationHandler.js +34 -16
- package/dist/runtime/helpers/index.d.ts +10 -10
- package/dist/runtime/helpers/resizeObserverWrapper.d.ts +1 -1
- package/dist/runtime/injectionKeys.d.ts +2 -2
- package/dist/runtime/main.lib.d.ts +10 -10
- package/dist/runtime/tailwind/index.d.ts +1 -1
- package/package.json +2 -2
- package/src/runtime/assets/animations.css +75 -0
- package/src/runtime/assets/base.css +0 -27
- package/src/runtime/assets/tailwind.css +1 -0
- package/src/runtime/components/LibColorPicker/LibColorPicker.stories.ts +1 -1
- package/src/runtime/components/LibNotifications/LibNotification.vue +86 -25
- package/src/runtime/components/LibNotifications/LibNotifications.stories.ts +4 -4
- package/src/runtime/components/LibNotifications/LibNotifications.vue +112 -90
- package/src/runtime/components/LibPopup/LibPopup.vue +2 -6
- package/src/runtime/components/LibProgressBar/LibProgressBar.vue +2 -1
- package/src/runtime/components/LibRecorder/LibRecorder.vue +1 -1
- package/src/runtime/composables/index.ts +2 -0
- package/src/runtime/composables/useSlotVars.ts +41 -0
- package/src/runtime/helpers/NotificationHandler.ts +44 -22
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Ref } from "vue";
|
|
2
|
-
import type { ScrollNearContainerEdgesOptions } from "../types/index.js
|
|
2
|
+
import type { ScrollNearContainerEdgesOptions } from "../types/index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Creates a function `scrollContainer` that allows scrolling a container manually when the coordinates are near it's edges.
|
|
5
5
|
* Supports scrolling faster the closer one is to the edge, and configuing an inner and outer margin.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper for managing props passed to slots and their fallbacks.
|
|
3
|
+
*
|
|
4
|
+
* Most slots have a default style but vue makes it hard to pass them both to the slot and the fallback content without repitition.
|
|
5
|
+
*
|
|
6
|
+
* This helper allows setting the variables from the template when creating the slot WHILE also using the created state without having to use any wrapper components, {@link https://github.com/vuejs/core/issues/1172 | see also this issue}.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```vue
|
|
10
|
+
* <template>
|
|
11
|
+
* <div>
|
|
12
|
+
* <slot
|
|
13
|
+
* v-bind="setSlotVar('title', {
|
|
14
|
+
* class: 'title focus-outline flex rounded-sm font-bold'
|
|
15
|
+
* someOtherProp: true
|
|
16
|
+
* })"
|
|
17
|
+
* >
|
|
18
|
+
* <FallbackComponent v-bind="slotVars.title"/>
|
|
19
|
+
* <slot/>
|
|
20
|
+
* </div>
|
|
21
|
+
* </template>
|
|
22
|
+
* <script setup lang="ts">
|
|
23
|
+
* import { useSlotVars } from "@witchcraft/ui/composables/useSlotVars"
|
|
24
|
+
* const { slotVars, setSlotVar } = useSlotVars()
|
|
25
|
+
* </script>
|
|
26
|
+
* ```
|
|
27
|
+
* The magic is that setSlotVar both sets and returns the value for the slot name passed. You can then access the state in a fallback component by accessing slotVars[slotName]. Unfortunately this is untyped unless you set the generic in useSlotsVars, but we usually don't need them to be typed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function useSlotVars<T extends Record<string, Record<string, any>>, TKey extends keyof T>(): {
|
|
30
|
+
slotVars: import("vue").Reactive<Record<TKey, Record<string, any>>>;
|
|
31
|
+
setSlotVar: <T_1 extends Record<string, any>>(name: TKey, obj: T_1) => T_1;
|
|
32
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AnyFunction } from "@alanscodelog/utils";
|
|
2
2
|
import { type Ref } from "vue";
|
|
3
|
-
import type { SuggestionsEmits, SuggestionsOptions } from "../components/shared/props.js
|
|
3
|
+
import type { SuggestionsEmits, SuggestionsOptions } from "../components/shared/props.js";
|
|
4
4
|
/**
|
|
5
5
|
* The logic for the suggestions component.
|
|
6
6
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { vDetectFlex } from "./vDetectFlex.js
|
|
2
|
-
export { vExtractRootEl } from "./vExtractRootEl.js
|
|
3
|
-
export { vResizableCols } from "./vResizableCols.js
|
|
4
|
-
export { vResizeObserver } from "./vResizeObserver.js
|
|
1
|
+
export { vDetectFlex } from "./vDetectFlex.js";
|
|
2
|
+
export { vExtractRootEl } from "./vExtractRootEl.js";
|
|
3
|
+
export { vResizableCols } from "./vResizableCols.js";
|
|
4
|
+
export { vResizeObserver } from "./vResizeObserver.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This is not inside helpers to avoid having it get dragged in by an import of /helpers.
|
|
3
3
|
*/
|
|
4
|
-
import { ResizeObserverWrapper } from "./helpers/resizeObserverWrapper.js
|
|
4
|
+
import { ResizeObserverWrapper } from "./helpers/resizeObserverWrapper.js";
|
|
5
5
|
export declare const globalResizeObserver: ResizeObserverWrapper;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { AnyFunction, MakeRequired } from "@alanscodelog/utils";
|
|
2
|
+
import { type Reactive } from "vue";
|
|
2
3
|
export declare class NotificationHandler<TRawEntry extends RawNotificationEntry<any, any> = RawNotificationEntry<any, any>, TEntry extends NotificationEntry<TRawEntry> = NotificationEntry<TRawEntry>> {
|
|
3
4
|
timeout: number;
|
|
4
5
|
debug: boolean;
|
|
5
6
|
private id;
|
|
6
|
-
readonly queue: TEntry[]
|
|
7
|
-
readonly history: TEntry[]
|
|
7
|
+
readonly queue: Reactive<TEntry[]>;
|
|
8
|
+
readonly history: Readonly<TEntry[]>;
|
|
8
9
|
maxHistory: number;
|
|
9
10
|
listeners: NotificationListener<TEntry>[];
|
|
10
11
|
stringifier?: NotificationStringifier<TEntry>;
|
|
@@ -16,12 +17,12 @@ export declare class NotificationHandler<TRawEntry extends RawNotificationEntry<
|
|
|
16
17
|
private _checkEntry;
|
|
17
18
|
protected _createEntry<TNotifyEntry extends RawNotificationEntry<any, any>>(rawEntry: TNotifyEntry): TEntry;
|
|
18
19
|
notify<TNotifyEntry extends RawNotificationEntry<any, any>>(rawEntry: TNotifyEntry): NotificationPromise<TNotifyEntry["options"][number] extends string ? TNotifyEntry["options"][number] : "Ok" | "Cancel">;
|
|
20
|
+
pause(notification: NotificationEntry): void;
|
|
21
|
+
resume(notification: NotificationEntry): void;
|
|
19
22
|
static resolveToDefault(notification: NotificationEntry): void;
|
|
20
23
|
static dismiss(notification: NotificationEntry): void;
|
|
21
24
|
stringify(notification: NotificationEntry): string;
|
|
22
25
|
clear(): void;
|
|
23
|
-
addNotificationListener(cb: NotificationListener<TEntry>): void;
|
|
24
|
-
removeNotificationListener(cb: NotificationListener<TEntry>): void;
|
|
25
26
|
}
|
|
26
27
|
export type NotificationPromise<TOption extends string = string> = Promise<TOption>;
|
|
27
28
|
export type RawNotificationEntry<TOptions extends string[] = ["Ok", "Cancel"], TCancellable extends boolean | TOptions[number] = "Cancel"> = {
|
|
@@ -48,6 +49,12 @@ export type NotificationEntry<TRawEntry extends RawNotificationEntry<any, any> =
|
|
|
48
49
|
timeout?: number;
|
|
49
50
|
resolution?: string;
|
|
50
51
|
id: number;
|
|
52
|
+
startTime: number;
|
|
53
|
+
isPaused: boolean;
|
|
54
|
+
_timer: {
|
|
55
|
+
id?: ReturnType<typeof setTimeout>;
|
|
56
|
+
elapsedBeforePause: number;
|
|
57
|
+
};
|
|
51
58
|
};
|
|
52
59
|
export type NotificationListener<TEntry extends NotificationEntry<any>> = (notification: TEntry, type: "added" | "resolved" | "deleted") => void;
|
|
53
60
|
export type NotificationStringifier<T extends NotificationEntry<any>> = (notification: T) => string;
|
|
@@ -4,12 +4,13 @@ import { indent } from "@alanscodelog/utils/indent";
|
|
|
4
4
|
import { isBlank } from "@alanscodelog/utils/isBlank";
|
|
5
5
|
import { pretty } from "@alanscodelog/utils/pretty";
|
|
6
6
|
import { setReadOnly } from "@alanscodelog/utils/setReadOnly";
|
|
7
|
+
import { reactive } from "vue";
|
|
7
8
|
export class NotificationHandler {
|
|
8
9
|
timeout = 5e3;
|
|
9
10
|
debug = false;
|
|
10
11
|
id = 0;
|
|
11
|
-
queue
|
|
12
|
-
history
|
|
12
|
+
queue;
|
|
13
|
+
history;
|
|
13
14
|
maxHistory = 100;
|
|
14
15
|
listeners = [];
|
|
15
16
|
stringifier;
|
|
@@ -18,6 +19,8 @@ export class NotificationHandler {
|
|
|
18
19
|
stringifier,
|
|
19
20
|
maxHistory
|
|
20
21
|
} = {}) {
|
|
22
|
+
this.queue = reactive([]);
|
|
23
|
+
this.history = reactive([]);
|
|
21
24
|
if (timeout) this.timeout = timeout;
|
|
22
25
|
if (maxHistory) this.maxHistory = maxHistory;
|
|
23
26
|
if (stringifier) this.stringifier = stringifier;
|
|
@@ -102,9 +105,10 @@ export class NotificationHandler {
|
|
|
102
105
|
entry.resolve = _resolve;
|
|
103
106
|
});
|
|
104
107
|
if (entry.timeout !== void 0) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
+
entry._timer = {
|
|
109
|
+
elapsedBeforePause: 0
|
|
110
|
+
};
|
|
111
|
+
this.resume(entry);
|
|
108
112
|
}
|
|
109
113
|
this.queue.push(entry);
|
|
110
114
|
for (const listener of this.listeners) {
|
|
@@ -115,8 +119,10 @@ export class NotificationHandler {
|
|
|
115
119
|
for (const listener of this.listeners) {
|
|
116
120
|
listener(entry, "resolved");
|
|
117
121
|
}
|
|
122
|
+
;
|
|
118
123
|
this.history.push(entry);
|
|
119
124
|
if (this.history.length > this.maxHistory) {
|
|
125
|
+
;
|
|
120
126
|
this.history.splice(0, 1);
|
|
121
127
|
for (const listener of this.listeners) {
|
|
122
128
|
listener(entry, "deleted");
|
|
@@ -126,6 +132,29 @@ export class NotificationHandler {
|
|
|
126
132
|
return res;
|
|
127
133
|
});
|
|
128
134
|
}
|
|
135
|
+
pause(notification) {
|
|
136
|
+
if (notification.timeout === void 0) {
|
|
137
|
+
throw new Error(`Cannot pause notification with no timeout: ${notification.id}`);
|
|
138
|
+
}
|
|
139
|
+
if (notification.isPaused) {
|
|
140
|
+
throw new Error(`Cannot pause notification that is already paused: ${notification.id}`);
|
|
141
|
+
}
|
|
142
|
+
notification.isPaused = true;
|
|
143
|
+
clearTimeout(notification._timer.id);
|
|
144
|
+
notification._timer.elapsedBeforePause += Date.now() - notification.startTime;
|
|
145
|
+
}
|
|
146
|
+
resume(notification) {
|
|
147
|
+
if (notification.timeout === void 0) {
|
|
148
|
+
throw new Error(`Cannot resume notification with no timeout: ${notification.id}`);
|
|
149
|
+
}
|
|
150
|
+
notification.isPaused = false;
|
|
151
|
+
notification.startTime = Date.now();
|
|
152
|
+
const remaining = notification.timeout - notification._timer.elapsedBeforePause;
|
|
153
|
+
clearTimeout(notification._timer.id);
|
|
154
|
+
notification._timer.id = setTimeout(() => {
|
|
155
|
+
notification.resolve(notification.cancellable);
|
|
156
|
+
}, remaining);
|
|
157
|
+
}
|
|
129
158
|
static resolveToDefault(notification) {
|
|
130
159
|
notification.resolve(notification.default);
|
|
131
160
|
}
|
|
@@ -148,15 +177,4 @@ export class NotificationHandler {
|
|
|
148
177
|
clear() {
|
|
149
178
|
setReadOnly(this, "history", []);
|
|
150
179
|
}
|
|
151
|
-
addNotificationListener(cb) {
|
|
152
|
-
this.listeners.push(cb);
|
|
153
|
-
}
|
|
154
|
-
removeNotificationListener(cb) {
|
|
155
|
-
const exists = this.listeners.indexOf(cb);
|
|
156
|
-
if (exists > -1) {
|
|
157
|
-
this.listeners.splice(exists, 1);
|
|
158
|
-
} else {
|
|
159
|
-
throw new Error(`Listener does not exist: ${cb.toString()}`);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
180
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { base64ToImg } from "./base64ToImg.js
|
|
2
|
-
export { copy } from "./copy.js
|
|
3
|
-
export { createNoonUtcDate } from "./createNoonUtcDate.js
|
|
4
|
-
export { createRecorderHandler } from "./storybook.js
|
|
5
|
-
export { defaultTranslationFunction } from "./defaultTranslationFunction.js
|
|
6
|
-
export { getTimeZoneList } from "./getTimeZoneList.js
|
|
7
|
-
export { hasModifiers } from "./hasModifiers.js
|
|
8
|
-
export { NotificationHandler } from "./NotificationHandler.js
|
|
9
|
-
export { readFile } from "./readFile.js
|
|
10
|
-
export { ResizeObserverWrapper } from "./resizeObserverWrapper.js
|
|
1
|
+
export { base64ToImg } from "./base64ToImg.js";
|
|
2
|
+
export { copy } from "./copy.js";
|
|
3
|
+
export { createNoonUtcDate } from "./createNoonUtcDate.js";
|
|
4
|
+
export { createRecorderHandler } from "./storybook.js";
|
|
5
|
+
export { defaultTranslationFunction } from "./defaultTranslationFunction.js";
|
|
6
|
+
export { getTimeZoneList } from "./getTimeZoneList.js";
|
|
7
|
+
export { hasModifiers } from "./hasModifiers.js";
|
|
8
|
+
export { NotificationHandler } from "./NotificationHandler.js";
|
|
9
|
+
export { readFile } from "./readFile.js";
|
|
10
|
+
export { ResizeObserverWrapper } from "./resizeObserverWrapper.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { InjectionKey, Ref } from "vue";
|
|
2
|
-
import type { DarkModeCommands, DarkModeState } from "./composables/useDarkMode.js
|
|
3
|
-
import type { TranslationFunction } from "./composables/useSetupI18n.js
|
|
2
|
+
import type { DarkModeCommands, DarkModeState } from "./composables/useDarkMode.js";
|
|
3
|
+
import type { TranslationFunction } from "./composables/useSetupI18n.js";
|
|
4
4
|
/** @deprecated */
|
|
5
5
|
export declare const isDarkModeInjectionKey: InjectionKey<Ref<boolean>>;
|
|
6
6
|
/** @deprecated */
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export * from "./types/index.js
|
|
2
|
-
export * as components from "./components/index.js
|
|
3
|
-
export * as helpers from "./helpers/index.js
|
|
4
|
-
export * as composables from "./composables/index.js
|
|
5
|
-
export * as directives from "./directives/index.js
|
|
6
|
-
export { registerDirectives } from "./vue/registerDirectives.js
|
|
7
|
-
export { registerComponents } from "./vue/registerComponents.js
|
|
8
|
-
export { VueComponentsPlugin } from "./vue/VueComponentsPlugin.js
|
|
9
|
-
export * from "./injectionKeys.js
|
|
10
|
-
import type * as components from "./components/index.js
|
|
1
|
+
export * from "./types/index.js";
|
|
2
|
+
export * as components from "./components/index.js";
|
|
3
|
+
export * as helpers from "./helpers/index.js";
|
|
4
|
+
export * as composables from "./composables/index.js";
|
|
5
|
+
export * as directives from "./directives/index.js";
|
|
6
|
+
export { registerDirectives } from "./vue/registerDirectives.js";
|
|
7
|
+
export { registerComponents } from "./vue/registerComponents.js";
|
|
8
|
+
export { VueComponentsPlugin } from "./vue/VueComponentsPlugin.js";
|
|
9
|
+
export * from "./injectionKeys.js";
|
|
10
|
+
import type * as components from "./components/index.js";
|
|
11
11
|
type Components = typeof components;
|
|
12
12
|
/**
|
|
13
13
|
* To get global typings, in a global declaration file (e.g. global.d.ts) do:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { themeConvertionOpts } from "./themeConvertionOpts.js
|
|
1
|
+
export { themeConvertionOpts } from "./themeConvertionOpts.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@witchcraft/ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Vue component library.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/runtime/main.lib.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"failOnWarn": false
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
|
-
"prepare": "husky && pnpm gen:theme && cd playground && pnpm i",
|
|
52
|
+
"prepare": "husky && pnpm gen:theme && cd playground && pnpm i --ignore-scripts",
|
|
53
53
|
"build": "nuxt-module-build prepare && nuxt-module-build build && nuxi generate playground",
|
|
54
54
|
"build:only": "nuxt-module-build build",
|
|
55
55
|
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
@theme {
|
|
2
|
+
--animate-blinkInf: blink 1s linear-infinite;
|
|
3
|
+
@keyframes blink {
|
|
4
|
+
0% {
|
|
5
|
+
opacity: 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
25% {
|
|
9
|
+
opacity: 1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
75% {
|
|
13
|
+
opacity: 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
100% {
|
|
17
|
+
opacity: 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
--animate-slideBgInf: slide-bg 10s linear-infinite;
|
|
22
|
+
@keyframes slide {
|
|
23
|
+
0% {
|
|
24
|
+
background-position:0%;
|
|
25
|
+
}
|
|
26
|
+
100% {
|
|
27
|
+
background-position: 100%;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
--animate-hide: hide 500ms ease-in;
|
|
32
|
+
@keyframes hide {
|
|
33
|
+
from {
|
|
34
|
+
opacity: 1;
|
|
35
|
+
}
|
|
36
|
+
to {
|
|
37
|
+
opacity: 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
--animate-slideIn: slideIn 500ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
42
|
+
@keyframes slideIn {
|
|
43
|
+
from {
|
|
44
|
+
transform: translateX(100%);
|
|
45
|
+
opacity: 0;
|
|
46
|
+
}
|
|
47
|
+
to {
|
|
48
|
+
transform: translateX(0);
|
|
49
|
+
opacity: 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
--animate-overlayShow: overlayShow 500ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
54
|
+
@keyframes overlayShow {
|
|
55
|
+
from {
|
|
56
|
+
opacity: 0;
|
|
57
|
+
}
|
|
58
|
+
to {
|
|
59
|
+
opacity: 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
--animate-contentShow: contentShow 500ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
64
|
+
@keyframes contentShow {
|
|
65
|
+
from {
|
|
66
|
+
opacity: 0;
|
|
67
|
+
transform: translate(0, -10%) scale(0.96);
|
|
68
|
+
}
|
|
69
|
+
to {
|
|
70
|
+
opacity: 1;
|
|
71
|
+
transform: scale(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
@@ -34,33 +34,6 @@ animations can be calculated correctly. */
|
|
|
34
34
|
user-select: none;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/* Animations */
|
|
38
|
-
@keyframes blink {
|
|
39
|
-
0% {
|
|
40
|
-
opacity: 0;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
25% {
|
|
44
|
-
opacity: 1;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
75% {
|
|
48
|
-
opacity: 1;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
100% {
|
|
52
|
-
opacity: 0;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
@keyframes slide {
|
|
57
|
-
0% {
|
|
58
|
-
background-position:0%;
|
|
59
|
-
}
|
|
60
|
-
100% {
|
|
61
|
-
background-position: 100%;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
37
|
|
|
65
38
|
a {
|
|
66
39
|
@apply link-like;
|
|
@@ -23,7 +23,7 @@ export const Primary: Story = {
|
|
|
23
23
|
components,
|
|
24
24
|
setup: () => {
|
|
25
25
|
const color = ref({ r: 0, g: 0, b: 0/* , a: 0.5 */, ...(args.modelValue) })
|
|
26
|
-
delete args.modelValue
|
|
26
|
+
delete (args as any).modelValue
|
|
27
27
|
const handleChange = (e: any) => {
|
|
28
28
|
color.value = { ...e }
|
|
29
29
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
|
|
3
|
+
v-if="notification"
|
|
4
|
+
:class="twMerge(`
|
|
5
|
+
notification
|
|
4
6
|
max-w-700px
|
|
5
7
|
bg-neutral-50
|
|
6
8
|
dark:bg-neutral-900
|
|
@@ -8,11 +10,15 @@
|
|
|
8
10
|
dark:text-bg
|
|
9
11
|
border
|
|
10
12
|
border-neutral-400
|
|
13
|
+
dark:border-neutral-700
|
|
11
14
|
rounded-sm
|
|
12
15
|
focus-outline
|
|
13
|
-
flex
|
|
16
|
+
flex
|
|
17
|
+
flex-col
|
|
14
18
|
gap-2
|
|
15
|
-
p-
|
|
19
|
+
p-1
|
|
20
|
+
text-sm
|
|
21
|
+
focus:border-accent-500
|
|
16
22
|
`,
|
|
17
23
|
($attrs as any).class)"
|
|
18
24
|
v-bind="{ ...$attrs, class: undefined }"
|
|
@@ -20,30 +26,59 @@
|
|
|
20
26
|
ref="notificationEl"
|
|
21
27
|
@keydown.enter.self="NotificationHandler.resolveToDefault(notification)"
|
|
22
28
|
>
|
|
23
|
-
<
|
|
24
|
-
|
|
29
|
+
<slot
|
|
30
|
+
name="top"
|
|
31
|
+
:notification="notification"
|
|
32
|
+
/>
|
|
33
|
+
<div
|
|
34
|
+
class="
|
|
35
|
+
notification--header
|
|
36
|
+
flex-reverse
|
|
37
|
+
flex
|
|
38
|
+
justify-between
|
|
39
|
+
items-center
|
|
40
|
+
"
|
|
41
|
+
>
|
|
42
|
+
<slot
|
|
25
43
|
v-if="notification.title"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
44
|
+
name="title"
|
|
45
|
+
v-bind="setSlotVar('title', {
|
|
46
|
+
title: notification.title,
|
|
47
|
+
class: `
|
|
48
|
+
notification--title
|
|
49
|
+
focus-outline
|
|
50
|
+
rounded-sm
|
|
51
|
+
font-bold
|
|
52
|
+
`,
|
|
53
|
+
tabindex: 0
|
|
54
|
+
})"
|
|
32
55
|
>
|
|
33
|
-
|
|
34
|
-
|
|
56
|
+
<div
|
|
57
|
+
v-bind="slotVars.title"
|
|
58
|
+
>
|
|
59
|
+
{{ notification.title }}
|
|
60
|
+
</div>
|
|
61
|
+
</slot>
|
|
35
62
|
<div class="notification--spacer flex-1"/>
|
|
36
63
|
<div class="actions flex">
|
|
37
64
|
<LibButton
|
|
38
65
|
:border="false"
|
|
39
|
-
class="
|
|
66
|
+
class="
|
|
67
|
+
notification--title-button
|
|
68
|
+
notification--copy-button
|
|
69
|
+
text-neutral-700
|
|
70
|
+
dark:text-neutral-300
|
|
71
|
+
"
|
|
40
72
|
@click="copy(handler ? handler.stringify(notification) : JSON.stringify(notification))"
|
|
41
73
|
>
|
|
42
74
|
<icon><i-fa6-regular-copy/></icon>
|
|
43
75
|
</LibButton>
|
|
44
76
|
<lib-button
|
|
45
77
|
v-if="notification.cancellable"
|
|
46
|
-
class="
|
|
78
|
+
class="
|
|
79
|
+
notification--title-button
|
|
80
|
+
notification--cancel-button
|
|
81
|
+
"
|
|
47
82
|
:border="false"
|
|
48
83
|
@click="NotificationHandler.dismiss(notification)"
|
|
49
84
|
>
|
|
@@ -51,12 +86,27 @@
|
|
|
51
86
|
</lib-button>
|
|
52
87
|
</div>
|
|
53
88
|
</div>
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
89
|
+
<slot
|
|
90
|
+
v-if="notification.message"
|
|
91
|
+
name="message"
|
|
92
|
+
v-bind="setSlotVar('message', {
|
|
93
|
+
class: `
|
|
94
|
+
notification--message
|
|
95
|
+
whitespace-pre-wrap
|
|
96
|
+
text-neutral-800
|
|
97
|
+
dark:text-neutral-200
|
|
98
|
+
mb-1
|
|
99
|
+
`,
|
|
100
|
+
message: notification.message,
|
|
101
|
+
tabindex: 0
|
|
102
|
+
})"
|
|
57
103
|
>
|
|
58
|
-
|
|
59
|
-
|
|
104
|
+
<div
|
|
105
|
+
v-bind="slotVars.message"
|
|
106
|
+
>
|
|
107
|
+
{{ notification.message }}
|
|
108
|
+
</div>
|
|
109
|
+
</slot>
|
|
60
110
|
<div class="notification--footer flex items-end justify-between">
|
|
61
111
|
<div
|
|
62
112
|
v-if="notification.code"
|
|
@@ -67,19 +117,23 @@
|
|
|
67
117
|
<div class="notification--footer-spacer flex-1 py-1"/>
|
|
68
118
|
<div
|
|
69
119
|
v-if="notification.options"
|
|
70
|
-
class="
|
|
71
|
-
|
|
120
|
+
class="
|
|
121
|
+
notification--options
|
|
122
|
+
flex
|
|
123
|
+
flex-wrap
|
|
124
|
+
justify-end
|
|
72
125
|
gap-2
|
|
73
126
|
"
|
|
74
127
|
>
|
|
75
128
|
<lib-button
|
|
76
129
|
:label="option"
|
|
77
130
|
:class="twMerge(`
|
|
131
|
+
notification--button
|
|
78
132
|
notification--option-button
|
|
133
|
+
px-2
|
|
79
134
|
`,
|
|
80
|
-
|
|
135
|
+
notification.default === option && `notification--default`
|
|
81
136
|
)"
|
|
82
|
-
:border="buttonColors[i] !== 'secondary'"
|
|
83
137
|
:color="buttonColors[i]"
|
|
84
138
|
v-for="option, i in notification.options"
|
|
85
139
|
:key="option"
|
|
@@ -91,11 +145,12 @@
|
|
|
91
145
|
</template>
|
|
92
146
|
|
|
93
147
|
<script setup lang="ts">
|
|
94
|
-
import { computed, type HTMLAttributes, ref, useAttrs } from "vue"
|
|
148
|
+
import { computed, type HTMLAttributes, onMounted, ref, useAttrs } from "vue"
|
|
95
149
|
|
|
96
150
|
import IFa6RegularCopy from "~icons/fa6-regular/copy"
|
|
97
151
|
import IFa6SolidXmark from "~icons/fa6-solid/xmark"
|
|
98
152
|
|
|
153
|
+
import { useSlotVars } from "../../composables/useSlotVars.js"
|
|
99
154
|
import { copy } from "../../helpers/copy.js"
|
|
100
155
|
import { type NotificationEntry, NotificationHandler } from "../../helpers/NotificationHandler.js"
|
|
101
156
|
import { twMerge } from "../../utils/twMerge.js"
|
|
@@ -109,6 +164,9 @@ defineOptions({
|
|
|
109
164
|
})
|
|
110
165
|
const $attrs = useAttrs()
|
|
111
166
|
|
|
167
|
+
const { setSlotVar, slotVars } = useSlotVars()
|
|
168
|
+
|
|
169
|
+
|
|
112
170
|
const props = withDefaults(defineProps<Props>(), {
|
|
113
171
|
handler: undefined
|
|
114
172
|
})
|
|
@@ -120,6 +178,9 @@ const getColor = (notification: NotificationEntry, option: string): "ok" | "prim
|
|
|
120
178
|
const buttonColors = computed(() => props.notification.options.map((option: any /* what ??? */) => getColor(props.notification, option)))
|
|
121
179
|
|
|
122
180
|
const notificationEl = ref<null | HTMLElement>(null)
|
|
181
|
+
onMounted(() => {
|
|
182
|
+
notificationEl.value?.focus()
|
|
183
|
+
})
|
|
123
184
|
defineExpose({
|
|
124
185
|
focus: () => {
|
|
125
186
|
notificationEl.value?.focus()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/vue3"
|
|
3
|
-
import {
|
|
3
|
+
import { ref } from "vue"
|
|
4
4
|
|
|
5
5
|
import LibNotifications from "./LibNotifications.vue"
|
|
6
6
|
|
|
@@ -23,7 +23,7 @@ export const Primary: Story = {
|
|
|
23
23
|
render: args => ({
|
|
24
24
|
components,
|
|
25
25
|
setup() {
|
|
26
|
-
const handler =
|
|
26
|
+
const handler = new NotificationHandler({})
|
|
27
27
|
|
|
28
28
|
let count = 0
|
|
29
29
|
|
|
@@ -76,7 +76,7 @@ export const Primary: Story = {
|
|
|
76
76
|
void handler.notify({
|
|
77
77
|
title: withTitle.value ? `Notification(${count})` : undefined,
|
|
78
78
|
message: `This is a notification. No action required.`,
|
|
79
|
-
timeout: disableTimeout.value ? false :
|
|
79
|
+
timeout: disableTimeout.value ? false : 5000
|
|
80
80
|
})
|
|
81
81
|
}
|
|
82
82
|
return {
|
|
@@ -97,7 +97,7 @@ export const Primary: Story = {
|
|
|
97
97
|
backgrounds: { disable: true },
|
|
98
98
|
// <lib-debug>{{args.handler}}</lib-debug>
|
|
99
99
|
template: `
|
|
100
|
-
<lib-root :outline="args.outline">
|
|
100
|
+
<lib-root :outline="args.outline" :notification-handler="handler">
|
|
101
101
|
<lib-button :label="'Notify Timeoutable'" @click="notifyTimeoutable()"></lib-button>
|
|
102
102
|
<lib-button :label="'Notify RequiresAction'" @click="notifyRequiresAction()"></lib-button>
|
|
103
103
|
<lib-button :label="'Notify Non-Cancellable that RequiresAction'" @click="notifyNonCancellableRequiresAction()"></lib-button>
|