npm package: @nicquid/dom-factory
Description: The DOM Factory is a utility class that adds a shorthand way of creating DOM elements on the fly.
Author: Bee Hudson
Latest version: 1.1.2

# DOM Factory

The DOM Factory is a utility class that adds a shorthand way of creating DOM elements on the fly.

The heart of the DOM Factory is the `build` function. This function will create a `HTMLElement` with any provided tag, and assign it the given properties, CSS classes, and text content.

By leveraging the use of a [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) for the class's initializer, we give it the ability to accept any HTML tag as a method name, and thus skip the need for the full build method.

Due to the nature of HTML, almost any possible string is accepted as a tag name, though some limitations are enforced by the DOM Factory. Those limitations are:
* The tag name must start with an ASCII letter in the range `A-Z`
* The tag name must only contain characters in the ranges of `A-Z`, `0-9`, or a hypen
* The tag name must end with a character in the ranges of `A-Z`, or `0-9`

On account of limitations with JavaScript, custom tags with name containing hyphens **must** be created using the `build` function.

## Documentation

### `build`

#### Summary
Build an HTML element

#### Description
A shorthand call for `document.createElement()`, while providing the added benefit of being able to assign properties and attributes to the element during the creation process. 

Must be used for elements that contain a hyphen in their tag name.

#### Parameters
* `tag: string` - The name of the HTML tag to build.
* `properties?: object` - An object of n-depth containing properties and attributes to assign the element. This may include things like an `id`, a `type` attribute, or even `data-` attributes.
* `classes?: string[]` - An array of CSS classes to assign to the element.
* `textContent?: string` - The initial text content of the element

#### Returns
* `HTMLElement` - An HTMLElement object of the given HTML tag name with the provided attributes and properties.

#### Example
```JavaScript
const header = factory.build("h2", { id: "intro-to-computer-science" }, ["section-header"], "Intro to Computer Science");
```

### `text`

#### Summary
Build a text node

#### Description
A shorthand call for `document.createTextNode()`.

#### Parameters
* `textContent?: string` - The text to initialize the text node with

#### Returns
* `TextNode` - A text node with the given content

#### Example
```JavaScript
const modal = factory.build("dialog");

const modalBody = factory.text("Do you wish to proceed?");

modal.appendChild(modalBody);
```

### `<any non-hypthenated tag name>`

#### Summary
Build an HTMLElement with the tag name of the function name used

#### Description
A shorthand call for `build()` for any non-hyphenated HTML tag. Creates an HTML element with the same name as the called function.

#### Parameters
* `properties?: object` - An object of n-depth containing properties and attributes to assign the element. This may include things like an `id`, a `type` attribute, or even `data-` attributes.
* `classes?: string[]` - An array of CSS classes to assign to the element.
* `textContent?: string` - The initial text content of the element

#### Returns
* `HTMLElement` - An HTMLElement object of the given HTML tag name with the provided attributes and properties.

#### Example
```JavaScript
/**
 * Display an alert to the user
 *
 * Builds an alert component and appends it to the main element
 * of the document
 *
 * @param alertText The text to display to the user
 */
function displayAlert(alertText) {
    const alertBody = factory.div({ id: `alert-${Date.now()}`}, ["alert"]);
    const alertTitle = factory.p({}, ["alert", "alert-title"], "Alert!");
    const alertMessage = factory.p({}, ["alert", "alert-message"], alertText);
    const alertClose = factory.build("alert-close", {}, ["alert", "alert-close"], "x");

    alertBody.append(alertClose, alertTitle, alertMessage);

    document.getElementById("main")?.appendChild(alertBody);
}
```

## Assigning `data-` Attributes

The properties parameter can be used to add properties and attributes to the create element. A common "gotcha" seen when using the DOM Factory is that when trying to add a data attribute to an element, e.g. `data-opened-by="button-4321"`, one might assume that the property should look something like the following,

```JavaScript
function ShowDialog(openerID) {
    const myDialog = factory.dialog({
        data: {
            openedBy: openerID
        }
    },/* ... */);
}
```

[Per the documentation](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset), though, the correct property to reference is `dataset`. Thus, the correct version of the above would be:

```JavaScript
function ShowDialog(openerID) {
    const myDialog = factory.dialog({
        dataset: {
            openedBy: openerID
        }
    },/* ... */);
}
```

## Acknowledgements

[tsconfig created using Matt Pocock's TSConfig Cheat Sheet](https://www.totaltypescript.com/tsconfig-cheat-sheet)