HystModal

repository·master·Indexed 42 days ago

https://github.com/addmorescripts/hystmodal

A lightweight (3kB gzipped), dependency-free JavaScript library for creating flexible, accessible, and highly customizable modal windows. Version 1.0.1 provides programmatic control via open(), close(), and closeAll() methods, focus trapping, and support for stacked modals.

Tokens
3.2K
Snippets
7
Records
11
Agent score
52%

What's inside HystModal

  1. Understand HystModal HTML structure and attributes

    master

    HystModal relies on specific CSS classes and data attributes to function correctly:

    • .hystmodal: The main modal container. Must have a unique id. It uses visibility:hidden when closed to prevent focus issues and automatically toggles the aria-hidden attribute.
    • .hystmodal__wrap: The scrollable area/overlay behind the modal. This element can trigger closing if closeOnOverlay is enabled.
    • .hystmodal__window: The actual modal content block. It is recommended to add aria-labelledby for accessibility.
    • [data-hystclose]: Any element inside .hystmodal__window with this attribute will close the modal when clicked (if closeOnButton is enabled).
    • .hystmodal__shadow: A shadow element that dims the background. This is automatically inserted by the script before the closing </body> tag.
  2. How HystModal HTML structure works

    master

    HystModal relies on specific class names and attributes to manage UX and accessibility:

    • .hystmodal: The main container. It must have a unique id. It uses visibility:hidden via CSS to ensure it doesn't receive focus when closed. The aria-hidden attribute is toggled automatically.
    • .hystmodal__wrap: The overlay/scrolled area. It can be configured to close the modal on click/tap. It does not have a background by default.
    • .hystmodal__window: The actual modal box. For better accessibility, it is recommended to add an aria-labelledby attribute pointing to a title inside the window.
    • [data-hystclose]: Any element inside .hystmodal__window with this attribute will close the modal when clicked (if closeOnButton is true).
  3. Install and set up HystModal

    master

    To use HystModal, follow these steps:

    1. Download and Unpack: Get the latest version of HystModal.
    2. Include Assets: Connect the CSS and JS files from the dist folder to your HTML page:
      <link rel="stylesheet" href="hystmodal.min.css">
      <script src="hystmodal.min.js"></script>
    3. Add HTML Markup: Create the modal structure in your document. The main container must have a unique id and the class hystmodal.
      <div class="hystmodal" id="myModal" aria-hidden="true">
          <div class="hystmodal__wrap">
              <div class="hystmodal__window" role="dialog" aria-modal="true">
                  <button data-hystclose class="hystmodal__close">Close</button>  
                  <!-- Your modal HTML markup -->
              </div>
          </div> 
      </div>
    4. Initialize via JavaScript: Create a new instance of HystModal.
      const myModal = new HystModal({
          linkAttributeName: "data-hystmodal"
      });
    5. Trigger the Modal: Add the attribute defined in linkAttributeName (default is data-hystmodal) to the element that should open the modal. The value must be the CSS selector for the modal window.
      <a href="#" data-hystmodal="#myModal">Open modal with id=myModal</a>
    <link rel="stylesheet" href="hystmodal.min.css">
    <script src="hystmodal.min.js"></script>
    
    <div class="hystmodal" id="myModal" aria-hidden="true">
        <div class="hystmodal__wrap">
            <div class="hystmodal__window" role="dialog" aria-modal="true">
                <button data-hystclose class="hystmodal__close">Close</button>  
            </div>
        </div> 
    </div>
    
    <script>
    const myModal = new HystModal({
        linkAttributeName: "data-hystmodal"
    });
    </script>
    
    <a href="#" data-hystmodal="#myModal">Open modal</a>
  4. Configure HystModal options

    master

    When instantiating new HystModal({ ... }), you can pass a configuration object to customize behavior.

    Configuration Options

    PropertyTypeDefaultDescription
    linkAttributeNameString"data-hystmodal"The data attribute on elements that triggers the modal. If set to false, automatic event handling is disabled.
    closeOnOverlaybooleantrueAllows/disallows closing the modal by clicking/tapping the overlay (.hystmodal__wrap).
    closeOnEscbooleantrueAllows/disallows closing the modal via the ESC key.
    closeOnButtonbooleantrueAllows/disallows closing via elements with the data-hystclose attribute.
    waitTransitionsbooleanfalseIf true, the modal waits for CSS transitions on .hystmodal__window to finish before closing.
    catchFocusbooleantrueIf true, focus is trapped within the modal while open and returned to the trigger element upon closing.
    fixedSelectorsstring"*[data-hystfixed]"CSS selector for elements that should receive a scrollbar-width offset to prevent shifting when backscroll is active.
    backscrollbooleantrueIf true, prevents page scrolling while the modal is open.
    beforeOpenfunctionfunction(){}Callback executed before the modal opens. Receives the modal object as an argument.
    afterClosefunctionfunction(){}Callback executed after the modal closes. Receives the last opened modal object as an argument.
    const myModal = new HystModal({
        linkAttributeName: 'data-hystmodal',
        catchFocus: true,
        waitTransitions: true,
        closeOnEsc: false,
        fixedSelectors: ".my-fixed-elems",
        beforeOpen: function(modal){
            console.log('Message before opening the modal');
            console.log(modal); // modal window object
        },
        afterClose: function(modal){
            console.log('Message after modal has closed');
            console.log(modal); // modal window object
        },
    });
  5. Initialize HystModal

    master

    To use HystModal, instantiate the HystModal class with a configuration object. Upon instantiation, the library automatically attaches event listeners to the document to handle modal triggers via data attributes, keyboard events (Esc, Tab), and overlay clicks.

    By default, HystModal looks for elements with the data-hystmodal attribute to trigger opening. You can customize this attribute using the linkAttributeName option.

    import HystModal from 'hystmodal';
    
    const modal = new HystModal({
      linkAttributeName: 'data-hystmodal',
      closeOnEsc: true,
      closeOnOverlay: true,
      // ... other config options
    });
  6. Use the HystModal API

    master

    The HystModal instance provides properties to inspect state and methods to control the modals programmatically.

    ### Properties
    - `isOpened` (boolean): Indicates if a modal is currently open. Default: `false`.
    - `openedWindow` (DOM node): The selector of the currently open window. If closed, contains the selector of the last opened window.
    - `starter` (DOM node): The element that triggered the modal (used for returning focus).
    - `config` (object): The configuration object used for this instance.
    
    ### Methods
    - `init()`: Initializes modal functionality and event listeners. If `linkAttributeName` is not `false`, this is called automatically during instantiation. Can only be called once.
    - `open(selector)`: Opens a modal. `selector` is a string (e.g., `"#modal-1"`). If no selector is provided, it opens the last opened modal. If a new modal is opened while one is already open, the current one is closed first.
    - `close()`: Closes the currently open modal.
  7. HystModal API: Properties and Methods

    master

    The HystModal instance provides access to the current state and methods for controlling modals programmatically.

    Properties

    PropertyTypeDescription
    isOpenedBooleanIndicates if a modal is currently open.
    openedWindowDOM nodeThe DOM node of the currently opened modal. If closed, contains the last opened window.
    starterDOM nodeThe element that triggered the modal (used for focus return).
    configObjectThe configuration object used for this instance.

    Methods

    MethodDescription
    init()Initializes functionality and enables event handling. If linkAttributeName is set, this runs automatically on creation. If linkAttributeName was set to false, you must call this manually after updating the config.
    open(selector)Opens a modal window. selector is a CSS selector string (e.g., "#myModal"). If omitted, it opens the last opened window. If a window is already open, it closes the current one before opening the new one.
    close()Closes the currently open modal window.
  8. Close a modal programmatically with close()

    master

    Use the close() method to close modals.

    Arguments:

    • modalElem (HTMLElement, optional): The specific modal element to close. If not provided, closeAll() is called instead, closing all currently open modals.

    Returns:

    • A Promise resolving to the HystModalInstance that was closed, or null if no modal was found.
    // Close a specific modal element
    const modalEl = document.querySelector('#my-modal');
    await modal.close(modalEl as HTMLElement);
    
    // Close all open modals
    await modal.close();
  9. Close all open modals with closeAll()

    master

    The closeAll() method closes every currently open modal in the stack. It returns a Promise that resolves to an array of all HystModalInstance objects that were closed.

    const closedModals = await modal.closeAll();
    console.log(`Closed ${closedModals.length} modals`);
  10. Open a modal programmatically with open()

    master

    Use the open() method to trigger a modal manually.

    Arguments:

    • selectorName (string): The CSS selector for the modal element (ID is recommended).
    • isStack (boolean, optional): If true, the new modal opens on top of the current one without closing it. Defaults to the instance's isStacked config.
    • starter (HTMLElement, optional): The element that triggered the modal (useful for returning focus on close).
    // Open a modal with ID 'my-modal'
    await modal.open('#my-modal');
    
    // Open a modal as a stack (on top of current)
    await modal.open('#secondary-modal', true);
  11. HystModalInstance interface

    master

    When a modal is opened, HystModal manages it as a HystModalInstance. This object contains metadata about the active modal.

    PropertyTypeDescription
    elementHTMLElementThe root element of the modal window.
    zIndexnumberThe calculated z-index for this modal instance.
    starterHTMLElement | nullThe element that triggered the modal (used for focus restoration).
    configHystModalConfigThe configuration used by this instance.
    isOpenedbooleanDeprecated: Use element or check openedModals array.
    openedWindowHTMLElementDeprecated: Use element property instead.