npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

v-native-dialog

v1.0.1

Published

A Vue 3 component using the native <dialog> element

Downloads

167

Readme

v-native-dialog

A Vue 3 component using the native <dialog> element. This e.g. provides more helpful events than <dialog/> itself.

This library also allows to imperatively show dialogs using a useDialog() composition function and (optionally) have dialogs "return" result values.

Docs

See the interactive StoryBook page and the documentation further down on this page.

Install

npm install v-native-dialog
pnpm add v-native-dialog

Usage

As a child Vue component

<script type="setup">
import { ref } from 'vue';
import { NativeDialog } from 'v-native-dialog';
const open = ref(true);
</script>
<template>
	<!-- ... other content ... -->
	<NativeDialog v-model:open="open" v-slot="{ closeDialog }">
		<p>The dialog content</p>
		<button type="button" @click="closeDialog('ok')">OK</button>
		<button type="button" @click="closeDialog('cancel')">Cancel</button>
	</NativeDialog>
</template>
<style>
@import "v-native-dialog/style.css";
</style>

As a dynamic dialog

You can render dialogs on the fly using useDialog() without including the dialog content in a parent Vue component. This allows to extract reusable dialogs.

Prerequisite: Render <DynamicDialogOutlet/> provided by this library somewhere in you app. This renders all dynamic dialogs.

// some-file.ts
import NumberDialog from "./number-dialog.vue";
async function askUser(question: string): Promise<number> {
	const { resultPromise } = useDialog(NumberDialog, { props: { question } });
	const { action, result } = await resultPromise;
	if (action == "ok") {
		return result;
	} else {
		// action is 'close' or 'cancel'
		return -1;
	}
	// alternatively: return result ?? -1;
}
<!-- number-dialog.vue -->
<script setup lang="ts">
import NativeDialog from "../native-dialog.vue";
import { ref } from "vue";

defineProps<{ question: string }>();
const number = ref(42);
</script>

<template>
	<NativeDialog v-slot="{ closeDialog }">
		<p>{{ question }}</p>
		<p>
			<input type="number" v-model="number" />
		</p>
		<button type="button" @click="closeDialog('ok', number)">OK</button>
		<button type="button" @click="closeDialog('cancel')">Cancel</button>
	</NativeDialog>
</template>

Docs: NativeDialog component

Props

nonModal

  • Type: boolean
  • Default: false, i.e. modal
  • Description: If true, the dialog will [https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/show](not be modal).

preventEscape

  • Type: boolean
  • Default: false
  • Description: If true, prevents the dialog from being closed using the 'esc' key (or other platform ways of closing dialogs). Some browsers allow this only a single time, then close anyway. Use this sparingly, to provide a good user experience.

displayDirective

  • Type: string ("if" | "show")
  • Default: "if"
  • Description: How the dialog shall be shown/hidden. By default, uses v-if, i.e., no rendering if hidden, re-rendering on show. If set to 'show', the rendered dialog is always in the DOM and will be shown/hidden using the 'open' attribute.

Default Slot

  • Slot Props:
    • closeDialog: Function to close the dialog and optionally provide the action and result for the result event.

Events

opened

  • Description: Triggers when the dialog is shown.
  • Payload:
    • dialog: HTMLDialogElement

closed

  • Description: Triggers when the dialog has closed.
  • Payload:
    • dialog: HTMLDialogElement | null

result

  • Description: Triggers when a result is emitted from the dialog (using closeDialog()).

  • Payload:

    • payload: {action: string, result?: any} aka ResultPayload

      • action is 'close' by default, but can be any string you specify in the closeDialog(action) call, e.g. 'ok' or 'cancel'.

        If closed via v-model:open the action is 'hide'.

      • result is undefined by default. You can specify the value using the closeDialog(action, result) call. Use this for the "return value" of the dialog.

CSS custom properties

Can be adapted using CSS.

--v-native-dialog-bg-color

  • Default: #fff
  • Description: Background color for the dialog content.

--v-native-dialog-backdrop

  • Default: rgba(0, 0, 0, 0.1)
  • Description: Color of the backdrop behind the dialog overlaying the page content.

--v-native-dialog-spacing

  • Default: 1rem
  • Description: Padding for the dialog content.

Docs: useDialog composition function

useDialog() creates (and by default opens) a dialog dynamically by adding it to the dialog list. This dialog list is rendered using the DynamicDialogOutlet component.

See Usage above.

Parameters

  • component (Component): A Vue component that uses the NativeDialog in its template.
  • options (Object, optional):
    • initiallyOpen (Boolean, default: true): Determines if the dialog should be open initially.
    • removeAfterClose (Boolean, default: true): Determines if the dialog should be removed from the dynamic list after it is closed. If you want to be able to re-open the dialog, set this to false.
    • props (Record<string, any>, default: {}): Props to pass to the dynamic dialog component.
    • dynamicDialogs (Ref<DialogInfo[]>, default: built-in global list): The list of dynamic dialogs.

Returns

  • result (Ref<ResultPayload<R> | undefined>): A ref holding the result payload of the dialog.
  • resultPromise (Promise<ResultPayload<R>>): A Promise that resolves with the result payload (close action and result) when the dialog is closed. Mostly helpful for one-shot dialogs.
  • show (Function): Opens the dialog.
  • close (Function): Closes the dialog.
  • destroy (Function): Closes the dialog and removes it from the dialog list. The dialog cannot be re-opened after this.

Docs: DynamicDialogOutlet component

This component should be rendered somewhere in your app. This is required for dialogs created dynamically using useDialog() to be shown.

Additional resources

Inspirations

Misc

Contribute

Run the interactive demo, which works as a nice testbed for changes.

npm run storybook