Skip to content

Commit

Permalink
v4.14.0: bump deps, overlay onCallback support w/ cancel removal support
Browse files Browse the repository at this point in the history
  • Loading branch information
fergusean committed Jun 23, 2024
1 parent 3ddb257 commit 0a306f6
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 144 deletions.
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@signal24/vue-foundation",
"type": "module",
"version": "4.13.9",
"version": "4.14.0",
"description": "Common components, directives, and helpers for Vue 3 apps",
"module": "./dist/vue-foundation.es.js",
"exports": {
Expand Down Expand Up @@ -52,16 +52,16 @@
"@types/node": "^20.10.5",
"@types/uuid": "^9.0.7",
"@vitejs/plugin-vue": "^5.0.0",
"@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^12.0.0",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/test-utils": "^2.4.3",
"@vue/tsconfig": "^0.5.1",
"cypress": "^13.6.2",
"date-fns": "^3.0.6",
"eslint": "^8.56.0",
"eslint-plugin-cypress": "^2.15.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
"eslint-plugin-unused-imports": "^3.0.0",
"eslint-plugin-cypress": "^3.3.0",
"eslint-plugin-simple-import-sort": "^12.1.0",
"eslint-plugin-unused-imports": "^4.0.0",
"eslint-plugin-vue": "^9.19.2",
"jsdom": "^23.0.1",
"lodash": "^4.17.21",
Expand Down
36 changes: 24 additions & 12 deletions src/components/overlay-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,22 @@ import {
import OverlayAnchor from './overlay-anchor.vue';
import type { OverlayAnchorOptions } from './overlay-types';

interface OverlayOptions {
interface OverlayOptions<C extends OverlayComponent, R extends ComponentReturn<C>> {
anchor?: OverlayAnchorOptions;
onCallback?: (result: R) => void | Promise<boolean>;
}

export interface OverlayInjection<C extends OverlayComponent> {
export interface OverlayInjection<C extends OverlayComponent, R extends ComponentReturn<C>> {
id: string;
component: OverlayComponentUnwrapped<C>;
props: OverlayComponentProps<C>;
options: OverlayOptions;
options: OverlayOptions<C, R>;
vnode: VNode;
wrapperVnode?: VNode;
}

let overlayCount = 0;
const OverlayInjections: OverlayInjection<any>[] = reactive([]);
const OverlayInjections: OverlayInjection<any, any>[] = reactive([]);

export const OverlayContainer = defineComponent({
setup() {
Expand Down Expand Up @@ -92,11 +93,11 @@ type ComponentReturn<M extends OverlayComponent> = OverlayComponentProps<M> exte

export type AnyComponentPublicInstance = { $?: ComponentInternalInstance };

export function createOverlayInjection<C extends OverlayComponent>(
export function createOverlayInjection<C extends OverlayComponent, R extends ComponentReturn<C>>(
component: C,
props: OverlayComponentProps<C>,
options?: OverlayOptions
): OverlayInjection<C> {
options?: OverlayOptions<C, R>
): OverlayInjection<C, R> {
// create or reconfigure the existing overlay target
// re-injecting every time keeps the overlay container at the very end of the DOM
const targetEl = document.getElementById('vf-overlay-target') ?? document.createElement('div');
Expand All @@ -110,7 +111,7 @@ export function createOverlayInjection<C extends OverlayComponent>(
const wrapperVnode = options?.anchor ? h(OverlayAnchor, { overlayId, anchor: options.anchor }, () => [vnode]) : undefined;

// todo: dunno what's going on with types here
const injection: OverlayInjection<C> = {
const injection: OverlayInjection<C, R> = {
id: overlayId,
component: rawComponent as any,
props,
Expand Down Expand Up @@ -152,7 +153,7 @@ export function dismissOverlayInjectionById(id: string) {
return false;
}

export function removeOverlayInjection(injection: OverlayInjection<any>) {
export function removeOverlayInjection(injection: OverlayInjection<any, any>) {
const index = OverlayInjections.indexOf(injection);
if (index >= 0) {
OverlayInjections.splice(index, 1);
Expand All @@ -162,11 +163,22 @@ export function removeOverlayInjection(injection: OverlayInjection<any>) {
export async function presentOverlay<C extends OverlayComponent, R extends ComponentReturn<C>>(
component: C,
props: Omit<OverlayComponentProps<C>, 'callback'>,
options?: OverlayOptions
options?: OverlayOptions<C, R>
): Promise<R | undefined> {
return new Promise<R>(resolve => {
let overlayInjection: OverlayInjection<C> | null = null;
const callback = (result: R) => {
let overlayInjection: OverlayInjection<C, R> | null = null;
const callback = async (result: R) => {
if (options?.onCallback) {
const hookResult = options.onCallback(result);
if (typeof hookResult === 'object' && 'then' in hookResult && typeof hookResult.then === 'function') {
// ^ hack for ZoneAwarePromise
const hookResultValue = await hookResult;
if (hookResultValue === false) {
return;
}
}
}

removeOverlayInjection(overlayInjection!);
resolve(result);
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/toast-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createOverlayInjection, type OverlayInjection, removeOverlayInjection }
import Toast, { type IToastOptions } from './toast.vue';

export function showToast(options: IToastOptions) {
const injection: OverlayInjection<typeof Toast> = createOverlayInjection(Toast, {
const injection: OverlayInjection<typeof Toast, unknown> = createOverlayInjection(Toast, {
...options,
callback: () => removeOverlayInjection(injection)
});
Expand Down
Loading

0 comments on commit 0a306f6

Please sign in to comment.