Skip to content

useModals

A composable to manage modals inside an application.

ts
import useModals from '@leaflink/stash/useModals';

const modals = useModals();

API

modals.active

modals.active contains the list of currently open/active modals.

A single modal is defined as:

ts
export interface Modal<TAttributes = Record<string, unknown>> {
  /**
   * Import the modal that you want to use in your component,
   * then pass that to the composable
   */
  component: Component;

  /**
   * Optional identifier used to close a modal. The default value is `component.name` (if defined).
   */
  name?: string;

  /**
   * Props and listeners to passed through.
   *
   * Listeners need to be formatted as `onEventName`
   */
  attributes?: ToRecord<TAttributes>;

  /**
   * Dyanmic slots that you want rendered in the format of
   * { default: 'my slot content' }
   *
   * The Modals component which renders this list passes the value for slots through
   * a html sanitizer to avoid XSS attacks
   */
  slots?: Record<string, string>;

  /**
   * Custom options to use for the given modal.
   *
   * If options are not passed in, then useModals will set the following values as defaults
   *
   * {
   *  disableDefaultListeners: false
   * }
   */
  options?: {
    disableDefaultListeners?: boolean;
  };
}

modals.current

modals.current refers to the currently visible modal in the active list, at index 0.

modals.open

ts
modals.open(modal: Modal)

Adds a modal to the modals array. If you do not provide a name to the modal, the method will try to use the component's name property if one exists. This method will also set default options if they are not provided.

vue
modal.open({ component: MyModal });

Using a custom interface for Modal attributes with modal.open()

You can pass a custom interface through a generic type parameterization when opening a modal:

ts
interface ModalAttributes {
  foo: string,
  bar: boolean,
}
//
modal.open<ModalAttributes>({ component: MyModal, attributes: { foo: 'apple', bar: false } });

With this type argument specification, trying to pass any additional properties not specified in ModalAttributes to attributes would surface a typescript error.

modals.close

Close the current modal:

ts
modals.close();

Close the modal at index 1 within modals.active:

ts
modals.close({ index: 1 });

Close the modal with name 'myModal':

ts
modals.close({ name: 'myModal' });

modals.closeAll

ts
modals.closeAll();

Sets modals.active to an empty array, regardless of how many open modals there are, therefore closing all open/active modals.

Usage

Import the useModals composable into any component and call modals.open.

vue
<script setup lang="ts">
  import useModals from '@leaflink/stash/useModals';
  import MyModal from 'MyModal.vue';

  const modals = useModals();

  modals.open({
    component: MyModal,
    name: 'MyModalAltName',
    attributes: {
      id: 1,
      isFlexible: false,
      onSuccess: () => modals.close(),
    },
    slots: {
      default: '<p>My slot content</p>',
    },
    options: {
      disableDefaultListeners: true,
    },
  });
</script>