1.1.0 • Published 3 years ago

@codewithkyle/postie v1.1.0

Weekly downloads
-
License
MIT
Repository
-
Last release
3 years ago

Postie

Postie helps you to perform simple CRUD operations using HTML Attributes. Postie is a smaller, simpler, version of htmx. If you need all the bells and whistles (like CSS transitions) I suggest you use the htmx library instead.

Install

Install via NPM:

npm i -S @codewithkyle/postie

Or via CDN:

<script src="https://cdn.jsdelivr.net/npm/@codewithkyle/postie@1/postie.min.js">

Usage

Interfaces

type RequestMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";

type AcceptHeader = "application/json" | "text/html";

type Prompt = "confirm" | "input" | null;

type Swap = "inner" | "outer" | "innerHTML" | "outerHTML";

type Headers = {
    [key:string]: string;
};

interface PostieSettings {
    endpoint: string;
    method?: RequestMethod; // POST
    accept?: AcceptHeader; // application/json
    data?: DOMStringMap; // {}
    prompt?: Prompt; // null
    promptLabel?: string;
    promptValue?: string;
    promptName?: string; // prompt
    success?: string | null;
    error?: string | null;
    preventDisable?: boolean; // false
    once?: boolean; // false
    target?: string; // this.el
    swap?: Swap; // innerHTML
    reset?: number; // 10
    headers?: Headers; // {}
};

Postie Element Anatomy

<!-- This is an HTML Element -->
<button></button>

<!-- This is a Postie HTML Element -->
<button postie></button>

<!-- These are the default HTML Attribute values -->
<button postie="idling" method="POST" accept="application/json" swap="innerHTML" reset="10" trigger="click"></button>

<!-- These are the required HTML Attributes -->
<button postie endpoint="/url/to/some/endpoint-or-page"></button>

Examples

Request Method & Body Controls

<!-- DELETE example -->
<button postie method="DELETE" endpoint="https://api.example.com/v1/user">Delete Account</button>

<!-- POST with data example: { "userId": "1234", "source": "demo" } -->
<button postie endpoint="https://api.example.com/v1/user/resend-verification" data-user-id="1234" data-source="demo">Resend Verification Email</button>

Handling Responses

<!-- Success handling -->
<button postie onsuccess="location.href = '/';" method="DELETE" endpoint="https://api.example.com/v1/user">Delete Account</button>

<!-- Error handling -->
<button postie onerror="alert('Failed to delete account.');" method="DELETE" endpoint="https://api.example.com/v1/user">Delete Account</button>

<!-- application/json responses (default) injects a "response" object into the error/success callback script -->
<button postie onsuccess="console.log(response);" onerror="console.log(response);" method="DELETE" endpoint="https://api.example.com/v1/user">Delete Account</button>

Trigger Event Options

<!-- Tell Postie to perform the action when the element is clicked (default) -->
<button postie trigger="click" method="GET" accept="text/html" endpoint="/ajax/demo.html">AJAX</button>

<!-- Tell Postie to perform the action when the element enters the viewport (observe only fires once) -->
<button postie trigger="observe" method="GET" accept="text/html" endpoint="/ajax/demo.html">AJAX</button>

<!-- Perform an action when the element has focus and the [key] is pressed -->
<button postie trigger="keypress" key="r" method="GET" accept="text/html" endpoint="/ajax/demo.html">AJAX</button>

AJAX

<!-- Fetch HTML and inject it into the element -->
<button postie method="GET" accept="text/html" endpoint="/ajax/demo.html">AJAX</button>

<!-- Fetch HTML and inject it into another element using a selector string -->
<div id="target-element"></div>
<button postie method="GET" accept="text/html" endpoint="/ajax/demo.html" target="#target-element">AJAX</button>

<!-- Fetch HTML and replace the elements outerHTML -->
<button postie method="GET" accept="text/html" endpoint="/ajax/demo.html" swap="outerHTML">Hotswap Element</button>

User Prompts

<!-- Prompt the user to confirm their action -->
<button postie prompt="confirm" prompt-label="Are you sure you want to delete your account? This action cannot be undone." method="DELETE" endpoint="https://api.example.com/v1/admin/user/1234" onsuccess="location.href = '/';" onerror="alert('Failed to delete account.');">Delete Account</button>

<!-- Prompt the user for an input before processing their action -->
<button postie prompt="input" prompt-label="Enter your password to confirm account deletion." method="DELETE" endpoint="https://api.example.com/v1/admin/user/1234" onsuccess="location.href = '/';" onerror="alert('Failed to delete account.');">Delete Account</button>

<!-- Control the prompts body param key: { "password": "" } -->
<button postie prompt-name="password" prompt="input" prompt-label="Enter your password to confirm account deletion." method="DELETE" endpoint="https://api.example.com/v1/admin/user/1234" onsuccess="location.href = '/';" onerror="alert('Failed to delete account.');">Delete Account</button>

<!-- Prefill the input prompts value -->
<button postie prompt-value="prefill prompt value" prompt-name="password" prompt="input" prompt-label="Enter your password to confirm account deletion." method="DELETE" endpoint="https://api.example.com/v1/admin/user/1234" onsuccess="location.href = '/';" onerror="alert('Failed to delete account.');">Delete Account</button>

Other Features

<!-- Prevent Postie from applying the [disabled] attribute to the element -->
<button postie prevent-disable method="GET" accept="text/html" endpoint="/ajax/demo.html">AJAX</button>
<button postie no-disable method="GET" accept="text/html" endpoint="/ajax/demo.html">AJAX</button>

<!-- Stop Postie from preventing the default event behavior -->
<button postie allow-default method="GET" accept="text/html" endpoint="/ajax/demo.html">AJAX</button>

<!-- Tell Postie the action can only be performed once -->
<button postie once method="GET" accept="text/html" endpoint="/ajax/demo.html">AJAX</button>

<!-- Change the reset timeout -- defaults to 10 (seconds) -->
<button postie reset="5" endpoint="https://api.example.com/v1/user/resend-verification" data-user-id="1234" data-source="demo">Resend Verification Email</button>

<!-- Tell Postie what headers you need added to the request -->
<button postie method="GET" accept="text/html" endpoint="/ajax/demo.html" headers="X-Requested-With: XMLHttpRequest; Authorization: bearer token;">AJAX</button>

<!-- Tell Postie what credentials should be sent with the request -- defaults to "same-origin" -->
<button postie method="GET" accept="text/html" endpoint="/ajax/demo.html" credentials="omit">AJAX</button>

Stateful Stylesheets

button{
    // Default postie element state.

    &[postie="processing"]{
        // Show a loading spinner or something.
    }

    &[postie="success"]{
        // Success!
    }

    &[postie="error"]{
        // Oh sh*t. Something bad happened.
    }

    &[disabled],
    &:disabled{
        // Postie disabled the element.
    }
}

Custom Events

The Custom Event's e.detail value will contain the fetch request response. The value will be null if the [accept] attribute was changed to text/html

document.addEventListener("postie:success", (e:CustomEvent) => {
    console.log(e.detail);
});
document.addEventListener("postie:error", (e:CustomEvent) => {
    console.error(e.detail);
    if (e.detail?.error){
        alert(e.detail.error);
    }
});

If you manually appended new elements with the [trigger="observe"] attribute you can tell Postie to update by dispatching a custom event on the document:

const event = new CustomEvent("postie:update");
document.dispatchEvent(event);