@phila/phila-ui-modal
v0.1.1
Published
A modal component for Phila UI.
Downloads
569
Readme
Modal Component
Component Status
| Component | Status |
| ----------------- | ----------------------------------------------------------- |
| AlertModal | |
| AnnouncementModal |
|
| ConfirmModal |
|
| EventModal |
|
| MultiModals |
|
| TaskModal |
|
A visibility-driven, teleported modal dialog, plus five pre-configured variants for common patterns (alerts, confirmations, announcements, events, and tasks).
Installation
pnpm add @phila/phila-ui-modal @phila/phila-ui-core
# or
npm install @phila/phila-ui-modal @phila/phila-ui-coreImport core styles in your main entry file (e.g., main.js|ts):
import "@phila/phila-ui-core/styles/template-light.css";The moving pieces
Modal— the base component every variant below wraps. Use it directly if none of the variants fit.AlertModal/ConfirmModal/AnnouncementModal/EventModal/TaskModal— pre-configuredModals for common cases (see Variants below).ModalTarget— required. Every modal renders viaTeleportinto a target element with idphila-modal-target-<id>. Render<ModalTarget />once, anywhere in your app (it renders one target<div>per currently-registered modal) — without it, opening a modal does nothing visible.
Usage
Modals are opened/closed via @phila/phila-ui-core's useVisibility, not a v-model or open
prop — toggleProps spreads onto whatever should open the modal:
<script setup lang="ts">
import { ref } from "vue";
import { ConfirmModal, ModalTarget } from "@phila/phila-ui-modal";
import { PhilaButton } from "@phila/phila-ui-button";
import { useVisibility } from "@phila/phila-ui-core";
const { toggleProps, isVisible, setVisibility } = useVisibility({ id: "confirm-modal", group: "modals" });
const submitting = ref(false);
async function onSubmit() {
submitting.value = true;
await doTheThing();
submitting.value = false;
setVisibility(false);
}
</script>
<template>
<PhilaButton v-bind="toggleProps">{{ isVisible("confirm-modal") ? "Close" : "Open" }} Confirm Modal</PhilaButton>
<ConfirmModal
id="confirm-modal"
title="Delete address?"
action-label="Accept"
:submitting="submitting"
@submit="onSubmit"
>
<p>It will be permanently removed from your profile.</p>
</ConfirmModal>
<ModalTarget />
</template>Variants
| Variant | Actions rendered | Dismissible by default | Notes |
| ------------------- | ----------------------------------------------------------- | ---------------------- | --------------------------------------- |
| AlertModal | Single primary action | No | Simplest case — inform + acknowledge. |
| ConfirmModal | Cancel (secondary) + primary action (destructive variant) | No | Confirm a destructive action. |
| AnnouncementModal | None (hideActions) | Yes | Has a footer slot for custom actions. |
| EventModal | None (hideActions) | Yes | Has a footer slot for custom actions. |
| TaskModal | Cancel + primary action | Yes | Same action layout as the base Modal. |
All variants accept the same props/slots/events as the base Modal below (minus the ones they
fix, like hideActions on AnnouncementModal/EventModal).
Props
ModalProps extends core's UseVisibilityProps (blurHide, showSingle, outsideClickHide,
escapeKeyHide, mouseOverToggle, visibleOnMount — see
packages/core/README.md).
| Prop | Type | Default | Description |
| ------------------- | ------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| id | string | "default-modal" | Unique id — also used to derive the ModalTarget teleport target and the useVisibility id. |
| group | string | "modals" | Visibility group (see useVisibility). Leave as the default unless you need isolated groups. |
| title | string | undefined | Header title. Renders a header region only if this or dissmissible is set. |
| content | string | undefined | Default body text, used if the default slot is empty. |
| dissmissible | boolean | false | Shows a close (X) button in the header. Note: this is the actual prop name in source — it's misspelled ("dissmissible", not "dismissible"). |
| hasOverlay | boolean | true | Shows the dark background overlay. |
| cancellable | boolean | false | Shows a secondary Cancel button alongside the primary action. |
| hideActions | boolean | false | Hides the entire actions row (used by AnnouncementModal/EventModal). |
| actionLabel | string | "Submit" | Label for the primary action button. |
| actionButtonProps | ButtonProps | undefined | Extra props forwarded to the primary action's PhilaButton (e.g. { variant: 'destructive' }). |
| submitting | boolean | false | Shows "Loading..." on the primary action and disables both action buttons. |
| cancelling | boolean | false | Shows "Loading..." on the Cancel button and disables both action buttons. |
| className | string | undefined | Additional CSS classes. |
cancelLabel and cancelButtonProps exist on the TypeScript type but aren't currently read by
Modal.vue — the Cancel button always renders the literal text "Cancel" with variant="secondary".
Slots
All slots receive { open, close }; close calls setVisibility(id, false) for you.
| Slot | Description |
| --------- | ----------------------------------------------------------------------------------------------------- |
| default | Body content. Replaces content when provided. |
| header | Replaces the entire header (title + close button). Only rendered if title or dissmissible is set. |
| actions | Replaces the entire actions row. Only rendered if hideActions is false. |
| footer | Extra content below the actions row. Only rendered if provided. |
Events
| Event | Payload | Description |
| -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| submit | — | Emitted when the primary action button is clicked. |
| cancel | — | Emitted when the Cancel button is clicked (cancellable variants). |
| close | — | Emitted whenever the modal transitions from open to closed (dismiss button, outside click, Escape, or programmatic setVisibility(id, false)). |
Development
Install Dependencies
pnpm installRun Demo
pnpm devBuild Library
pnpm buildType Check
pnpm type-checkPublishing to NPM
Follow the release instructions using changesets.
License
MIT
