{"id":15101604,"url":"https://github.com/zekenaulty/dominus","last_synced_at":"2026-02-28T05:37:27.029Z","repository":{"id":257299036,"uuid":"857852176","full_name":"zekenaulty/dominus","owner":"zekenaulty","description":"DOM API with Bootstrap 5 and Bootswatch.","archived":false,"fork":false,"pushed_at":"2024-09-16T06:04:43.000Z","size":48,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-10T21:43:13.961Z","etag":null,"topics":["bootstrap5","bootswatch-theme","domapi","html5"],"latest_commit_sha":null,"homepage":"https://zekenaulty.github.io/dominus/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zekenaulty.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-15T19:13:26.000Z","updated_at":"2024-09-16T06:04:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"423cf2c2-2f35-415b-b4d1-468c4d94cd40","html_url":"https://github.com/zekenaulty/dominus","commit_stats":null,"previous_names":["zekenaulty/dominus"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zekenaulty%2Fdominus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zekenaulty%2Fdominus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zekenaulty%2Fdominus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zekenaulty%2Fdominus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zekenaulty","download_url":"https://codeload.github.com/zekenaulty/dominus/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247325696,"owners_count":20920714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bootstrap5","bootswatch-theme","domapi","html5"],"created_at":"2024-09-25T18:26:14.638Z","updated_at":"2026-02-28T05:37:21.968Z","avatar_url":"https://github.com/zekenaulty.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dom.js\r\n\r\nA lightweight and comprehensive HTML5 DOM wrapper for building Bootstrap 5 components with ease. `dom.js` simplifies DOM manipulation and allows you to create dynamic, themeable web applications without writing verbose HTML.\r\n\r\n## Features\r\n\r\n- Simplifies DOM manipulation with a clean, consistent API.\r\n- Supports all Bootstrap 5 components.\r\n- Allows runtime switching between Bootswatch themes.\r\n- Facilitates the creation of complex UIs with minimal code.\r\n- **Includes `DomEvaluator` for reactive data binding and dynamic content updates.**\r\n- No dependencies other than Bootstrap and Bootswatch.\r\n\r\n## Installation\r\n(beta)\r\nInstall via npm:\r\n\r\n```bash\r\nnpm install dominus-api\r\n```\r\n\r\nAlternatively, you can include `dom.js` directly in your project by downloading the `dom.js` file and referencing it in your HTML.\r\n\r\n## Getting Started\r\n\r\nTo get started, include `dom.js` in your project and use it to build your web application's UI.\r\n\r\n### Including Bootstrap and Bootswatch\r\n\r\nEnsure that you include Bootstrap and the Bootswatch theme of your choice via CDN in your `index.html`:\r\n\r\n```html\r\n\u003c!-- Bootstrap CSS (will be overridden by Bootswatch theme) --\u003e\r\n\u003clink href=\"https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css\" rel=\"stylesheet\"\u003e\r\n\u003c!-- Bootswatch Theme Placeholder --\u003e\r\n\u003clink id=\"bootswatch-theme\" rel=\"stylesheet\" href=\"\"\u003e\r\n```\r\n\r\n### Including dom.js and domEvaluator.js\r\n\r\nInclude `dom.js`, `domEvaluator.js`, and your `main.js` in your `index.html`:\r\n\r\n```html\r\n\u003c!-- dom.js --\u003e\r\n\u003cscript type=\"module\" src=\"./dom.js\"\u003e\u003c/script\u003e\r\n\u003c!-- domEvaluator.js --\u003e\r\n\u003cscript type=\"module\" src=\"./domEvaluator.js\"\u003e\u003c/script\u003e\r\n\u003c!-- main.js --\u003e\r\n\u003cscript type=\"module\" src=\"./main.js\"\u003e\u003c/script\u003e\r\n```\r\n\r\n---\r\n\r\n## Examples\r\n\r\nBelow are examples demonstrating how to use `dom.js` and `domEvaluator.js` to create Bootstrap components, from simple buttons to complex forms with reactive data binding.\r\n\r\n### Example 1: Creating a Simple Button\r\n\r\n#### index.html\r\n\r\n```html\r\n\u003c!DOCTYPE html\u003e\r\n\u003chtml lang=\"en\"\u003e\r\n\u003chead\u003e\r\n  \u003cmeta charset=\"UTF-8\"\u003e\r\n  \u003ctitle\u003edom.js Button Example\u003c/title\u003e\r\n  \u003c!-- Bootstrap CSS --\u003e\r\n  \u003clink id=\"bootswatch-theme\" rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css\"\u003e\r\n\u003c/head\u003e\r\n\u003cbody\u003e\r\n  \u003c!-- Content will be injected by main.js --\u003e\r\n  \u003c!-- Bootstrap JS Bundle --\u003e\r\n  \u003cscript src=\"https://cdn.jsdelivr.net/npm/bootstrap@5/dist/js/bootstrap.bundle.min.js\"\u003e\u003c/script\u003e\r\n  \u003c!-- dom.js --\u003e\r\n  \u003cscript type=\"module\" src=\"./dom.js\"\u003e\u003c/script\u003e\r\n  \u003c!-- main.js --\u003e\r\n  \u003cscript type=\"module\" src=\"./main.js\"\u003e\u003c/script\u003e\r\n\u003c/body\u003e\r\n\u003c/html\u003e\r\n```\r\n\r\n#### main.js\r\n\r\n```javascript\r\nimport { DOM } from './dom.js';\r\n\r\n// Set default theme\r\nDOM.switchTheme('flatly');\r\n\r\n// Create a container\r\nconst container = DOM.container({ parent: DOM.body, classes: ['mt-5'] });\r\n\r\n// Create a button\r\nconst button = DOM.button({\r\n  parent: container,\r\n  text: 'Click Me',\r\n  classes: ['btn', 'btn-primary'],\r\n  events: {\r\n    click: () =\u003e alert('Button clicked!')\r\n  }\r\n});\r\n```\r\n\r\n**Explanation:**\r\n\r\n- **DOM.switchTheme('flatly')**: Sets the Bootswatch theme to 'Flatly'.\r\n- **DOM.container**: Creates a Bootstrap container.\r\n- **DOM.button**: Creates a Bootstrap button with text and an event listener.\r\n\r\n---\r\n\r\n### Example 2: Creating a Form with Reactive Data Binding\r\n\r\n#### index.html\r\n\r\n_Same as in Example 1._\r\n\r\n#### main.js\r\n\r\n```javascript\r\nimport { DOM } from './dom.js';\r\nimport { DomEvaluator } from './domEvaluator.js';\r\n\r\n// Set default theme\r\nDOM.switchTheme('darkly');\r\n\r\n// Initialize reactive data object\r\nconst data = {\r\n  user: {\r\n    name: '',\r\n    email: ''\r\n  }\r\n};\r\n\r\n// Create an instance of DomEvaluator\r\nconst evaluator = DomEvaluator.getInstance();\r\nevaluator.setData(data);\r\n\r\n// Create a container\r\nconst container = DOM.container({ parent: DOM.body, classes: ['mt-5'] });\r\n\r\n// Create a form\r\nconst form = DOM.form({ parent: container });\r\n\r\n// Name input\r\nconst nameGroup = DOM.formGroup({ parent: form });\r\nDOM.element('label', { parent: nameGroup, text: 'Name', attributes: { for: 'inputName' } });\r\nDOM.input({\r\n  parent: nameGroup,\r\n  attributes: {\r\n    type: 'text',\r\n    id: 'inputName',\r\n    placeholder: 'Enter your name',\r\n    value: data.user.name,\r\n  },\r\n  events: {\r\n    input: (e) =\u003e {\r\n      data.user.name = e.target.value;\r\n    },\r\n  },\r\n});\r\n\r\n// Email input\r\nconst emailGroup = DOM.formGroup({ parent: form });\r\nDOM.element('label', { parent: emailGroup, text: 'Email address', attributes: { for: 'inputEmail' } });\r\nDOM.input({\r\n  parent: emailGroup,\r\n  attributes: {\r\n    type: 'email',\r\n    id: 'inputEmail',\r\n    placeholder: 'Enter email',\r\n    value: data.user.email,\r\n  },\r\n  events: {\r\n    input: (e) =\u003e {\r\n      data.user.email = e.target.value;\r\n    },\r\n  },\r\n});\r\n\r\n// Display the data using {expressions}\r\nDOM.typography('h4', { parent: container, text: 'Live Preview', classes: ['mt-4'] });\r\nDOM.typography('p', { parent: container, text: 'Name: {user.name}' });\r\nDOM.typography('p', { parent: container, text: 'Email: {user.email}' });\r\n\r\n// Initial evaluation\r\nevaluator.evaluate();\r\n```\r\n\r\n**Explanation:**\r\n\r\n- **DomEvaluator**: Used for reactive data binding.\r\n- **Reactive Inputs**: Input fields update the `data` object on input events.\r\n- **Live Preview**: Displays data using `{expressions}`, which are updated automatically when `data` changes.\r\n- **evaluator.evaluate()**: Processes the DOM to replace `{expressions}` with actual data.\r\n\r\n---\r\n\r\n### Example 3: Creating a Navbar with Dynamic Data\r\n\r\n#### index.html\r\n\r\n_Same as in Example 1._\r\n\r\n#### main.js\r\n\r\n```javascript\r\nimport { DOM } from './dom.js';\r\nimport { DomEvaluator } from './domEvaluator.js';\r\n\r\n// Set default theme\r\nDOM.switchTheme('cerulean');\r\n\r\n// Initialize reactive data object\r\nconst data = {\r\n  user: {\r\n    name: 'John Doe'\r\n  }\r\n};\r\n\r\n// Create an instance of DomEvaluator\r\nconst evaluator = DomEvaluator.getInstance();\r\nevaluator.setData(data);\r\n\r\n// Create a navbar\r\nconst navbar = DOM.navbar({\r\n  parent: DOM.body,\r\n  brandText: '{user.name}',\r\n  brandHref: '#',\r\n  classes: ['navbar', 'navbar-expand-lg', 'navbar-dark', 'bg-dark'],\r\n  items: [\r\n    { text: 'Home', href: '#', active: true },\r\n    { text: 'Profile', href: '#' },\r\n    { text: 'Settings', href: '#' },\r\n  ],\r\n});\r\n\r\n// Initial evaluation\r\nevaluator.evaluate();\r\n\r\n// Simulate data change after 2 seconds\r\nsetTimeout(() =\u003e {\r\n  data.user.name = 'Jane Smith';\r\n  evaluator.evaluate();\r\n}, 2000);\r\n```\r\n\r\n**Explanation:**\r\n\r\n- **Dynamic Brand Text**: The navbar brand text uses `{user.name}` to display the user's name.\r\n- **DomEvaluator**: Updates the DOM when `data.user.name` changes.\r\n- **Simulated Data Change**: After 2 seconds, the user's name changes, and the navbar updates accordingly.\r\n\r\n---\r\n\r\n### Example 4: Creating Tabs and Tab Content\r\n\r\n#### index.html\r\n\r\n_Same as in Example 1._\r\n\r\n#### main.js\r\n\r\n```javascript\r\nimport { DOM } from './dom.js';\r\n\r\n// Set default theme\r\nDOM.switchTheme('darkly');\r\n\r\n// Create a container\r\nconst container = DOM.container({ parent: DOM.body, classes: ['mt-5'] });\r\n\r\n// Create tabs\r\nconst tabs = DOM.nav({\r\n  parent: container,\r\n  tabs: true,\r\n  items: [\r\n    { text: 'Home', href: '#home', active: true },\r\n    { text: 'Profile', href: '#profile' },\r\n    { text: 'Messages', href: '#messages' },\r\n  ],\r\n  attributes: { id: 'myTab', role: 'tablist' },\r\n});\r\n\r\n// Create tab content container\r\nconst tabContent = DOM.element('div', {\r\n  parent: container,\r\n  classes: ['tab-content'],\r\n  attributes: { id: 'myTabContent' },\r\n});\r\n\r\n// Tab panes\r\nconst homePane = DOM.element('div', {\r\n  parent: tabContent,\r\n  classes: ['tab-pane', 'fade', 'show', 'active'],\r\n  attributes: { id: 'home', role: 'tabpanel', 'aria-labelledby': 'home-tab' },\r\n  html: '\u003cp\u003eHome content goes here.\u003c/p\u003e',\r\n});\r\n\r\nconst profilePane = DOM.element('div', {\r\n  parent: tabContent,\r\n  classes: ['tab-pane', 'fade'],\r\n  attributes: { id: 'profile', role: 'tabpanel', 'aria-labelledby': 'profile-tab' },\r\n  html: '\u003cp\u003eProfile content goes here.\u003c/p\u003e',\r\n});\r\n\r\nconst messagesPane = DOM.element('div', {\r\n  parent: tabContent,\r\n  classes: ['tab-pane', 'fade'],\r\n  attributes: { id: 'messages', role: 'tabpanel', 'aria-labelledby': 'messages-tab' },\r\n  html: '\u003cp\u003eMessages content goes here.\u003c/p\u003e',\r\n});\r\n```\r\n\r\n**Explanation:**\r\n\r\n- **DOM.nav**: Creates a navigation element with tabs.\r\n- **DOM.element**: Used to create tab content panes.\r\n- **Data Attributes**: Used for proper Bootstrap tab functionality.\r\n\r\n---\r\n\r\n### Example 5: Dynamic Content with domEvaluator.js\r\n\r\n#### index.html\r\n\r\n_Same as in Example 1, but include a theme selector:_\r\n\r\n```html\r\n\u003c!-- Theme Selector --\u003e\r\n\u003cdiv class=\"container mt-3\"\u003e\r\n  \u003cdiv class=\"d-flex justify-content-end\"\u003e\r\n    \u003cselect id=\"theme-selector\" class=\"form-select w-auto\"\u003e\r\n      \u003coption value=\"darkly\"\u003eDarkly\u003c/option\u003e\r\n      \u003coption value=\"flatly\"\u003eFlatly\u003c/option\u003e\r\n      \u003coption value=\"cerulean\"\u003eCerulean\u003c/option\u003e\r\n      \u003c!-- Add more themes as desired --\u003e\r\n    \u003c/select\u003e\r\n  \u003c/div\u003e\r\n\u003c/div\u003e\r\n```\r\n\r\n#### main.js\r\n\r\n```javascript\r\nimport { DOM } from './dom.js';\r\nimport { DomEvaluator } from './domEvaluator.js';\r\n\r\n// Set default theme\r\nDOM.switchTheme('darkly');\r\n\r\n// Initialize reactive data object\r\nconst data = {\r\n  theme: 'darkly',\r\n  dynamicItems: ['Item 1', 'Item 2', 'Item 3'],\r\n};\r\n\r\n// Create an instance of DomEvaluator\r\nconst evaluator = DomEvaluator.getInstance();\r\nevaluator.setData(data);\r\n\r\n// Handle theme switching\r\nconst themeSelector = document.getElementById('theme-selector');\r\nthemeSelector.addEventListener('change', (e) =\u003e {\r\n  data.theme = e.target.value;\r\n  DOM.switchTheme(data.theme);\r\n});\r\n\r\n// Create a container\r\nconst container = DOM.container({ parent: DOM.body, classes: ['mt-4'] });\r\n\r\n// Add header\r\nDOM.typography('h1', {\r\n  parent: container,\r\n  text: 'Dynamic Content Example',\r\n  classes: ['text-center', 'mb-4'],\r\n});\r\n\r\n// Dynamic list rendering\r\nconst listContainer = DOM.element('ul', { parent: container, classes: ['list-group', 'mb-3'] });\r\n\r\nfunction renderList() {\r\n  listContainer.innerHTML = '';\r\n  data.dynamicItems.forEach((item) =\u003e {\r\n    DOM.element('li', {\r\n      parent: listContainer,\r\n      classes: ['list-group-item'],\r\n      text: item,\r\n    });\r\n  });\r\n  evaluator.evaluate(listContainer);\r\n}\r\n\r\nrenderList();\r\n\r\n// Add item button\r\nDOM.button({\r\n  parent: container,\r\n  text: 'Add Item',\r\n  classes: ['btn', 'btn-primary', 'me-2'],\r\n  events: {\r\n    click: () =\u003e {\r\n      const newItem = `Item ${data.dynamicItems.length + 1}`;\r\n      data.dynamicItems.push(newItem);\r\n      renderList();\r\n    },\r\n  },\r\n});\r\n\r\n// Remove item button\r\nDOM.button({\r\n  parent: container,\r\n  text: 'Remove Item',\r\n  classes: ['btn', 'btn-secondary'],\r\n  events: {\r\n    click: () =\u003e {\r\n      data.dynamicItems.pop();\r\n      renderList();\r\n    },\r\n  },\r\n});\r\n```\r\n\r\n**Explanation:**\r\n\r\n- **Theme Switching**: Allows users to switch between Bootswatch themes at runtime.\r\n- **Reactive Data Binding**: Uses `domEvaluator.js` to reactively update the list when items are added or removed.\r\n- **Dynamic List Rendering**: The `renderList` function re-renders the list whenever `data.dynamicItems` changes.\r\n\r\n---\r\n\r\n## API Reference\r\n\r\nThe `DOM` class provides methods to create and manipulate DOM elements easily.\r\n\r\n### Common Methods\r\n\r\n- **DOM.element(tag, options)**: Creates an HTML element.\r\n- **DOM.classes(element, classes)**: Adds classes to an element.\r\n- **DOM.attributes(element, attributes)**: Adds attributes to an element.\r\n- **DOM.events(element, events)**: Adds event listeners to an element.\r\n- **DOM.append(child, parent)**: Appends a child element to a parent.\r\n- **DOM.remove(element)**: Removes an element from the DOM.\r\n\r\n### Bootstrap-Specific Methods\r\n\r\n- **DOM.container(options)**: Creates a Bootstrap container.\r\n- **DOM.row(options)**: Creates a Bootstrap row.\r\n- **DOM.col(options)**: Creates a Bootstrap column.\r\n- **DOM.button(options)**: Creates a Bootstrap button.\r\n- **DOM.navbar(options)**: Creates a Bootstrap navbar.\r\n- **DOM.nav(options)**: Creates a Bootstrap nav (tabs or pills).\r\n- **DOM.modal(options)**: Creates a Bootstrap modal.\r\n- **DOM.alert(options)**: Creates a Bootstrap alert.\r\n- **DOM.form(options)**: Creates a form element.\r\n- **DOM.input(options)**: Creates an input element.\r\n- **DOM.checkbox(options)**: Creates a checkbox input.\r\n- **DOM.radio(options)**: Creates a radio input.\r\n- **DOM.typography(tag, options)**: Creates typography elements like headings, paragraphs, etc.\r\n\r\n### Theme Management\r\n\r\n- **DOM.switchTheme(themeName)**: Switches the Bootswatch theme at runtime.\r\n\r\n---\r\n\r\n## DomEvaluator\r\n\r\n`domEvaluator.js` provides a way to integrate dynamic data into your DOM using `{}` placeholders, similar to templating in Angular or React.\r\n\r\n### Features\r\n\r\n- **Reactive Data Binding**: Automatically updates the DOM when data changes.\r\n- **On-Demand Updates**: Manually trigger DOM updates when needed.\r\n- **Singleton Instance**: Ensures only one instance of `DomEvaluator` exists.\r\n- **Safe Expression Evaluation**: Evaluates expressions within the scope of the provided data object.\r\n\r\n### Usage\r\n\r\n#### Importing DomEvaluator\r\n\r\n```javascript\r\nimport { DomEvaluator } from './domEvaluator.js';\r\n```\r\n\r\n#### Setting Up Reactive Data\r\n\r\n```javascript\r\n// Initialize reactive data object\r\nconst data = {\r\n  user: {\r\n    name: 'John Doe',\r\n    email: 'john.doe@example.com',\r\n  },\r\n};\r\n\r\n// Get the singleton instance of DomEvaluator\r\nconst evaluator = DomEvaluator.getInstance();\r\n\r\n// Set the data in the evaluator (makes it reactive)\r\nevaluator.setData(data);\r\n```\r\n\r\n#### Using {expressions} in Your DOM\r\n\r\n```javascript\r\n// Create elements with placeholders\r\nDOM.typography('h1', {\r\n  parent: DOM.body,\r\n  text: 'Hello, {user.name}!',\r\n});\r\n\r\nDOM.typography('p', {\r\n  parent: DOM.body,\r\n  text: 'Email: {user.email}',\r\n});\r\n\r\n// Initial evaluation\r\nevaluator.evaluate();\r\n```\r\n\r\n#### Reactive Updates\r\n\r\nWhen you change the data object, the DOM updates automatically.\r\n\r\n```javascript\r\ndata.user.name = 'Jane Smith';\r\ndata.user.email = 'jane.smith@example.com';\r\n// The DOM automatically reflects these changes\r\n```\r\n\r\n---\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please submit a pull request or open an issue on GitHub.\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License.\r\n\r\n---\r\n\r\n## Conclusion\r\n\r\n`dom.js` provides a powerful and flexible way to build dynamic, themeable web applications using Bootstrap 5 components. By abstracting the DOM manipulation and Bootstrap component creation into simple methods, it allows developers to focus on building features rather than writing repetitive HTML and JavaScript code.\r\n\r\nWith the addition of `domEvaluator.js`, you can now integrate reactive data binding into your applications, enabling dynamic content updates and a more interactive user experience.\r\n\r\n---\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzekenaulty%2Fdominus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzekenaulty%2Fdominus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzekenaulty%2Fdominus/lists"}