|
| 1 | +# BsElements |
| 2 | + |
| 3 | +A **Bootstrap 5–based, framework-agnostic Web Component library** built around the Bootstrap philosophy: **class-first markup, minimal abstraction, and a thin DOM wrapper**. |
| 4 | + |
| 5 | +BsElements augments existing Bootstrap HTML and JavaScript with a **declarative Custom Element API** — without hiding, replacing, or reinventing Bootstrap. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## 🎯 Goals |
| 10 | + |
| 11 | +- Expose Bootstrap 5 components as **Custom Elements** |
| 12 | +- Work everywhere: **Vanilla JS, React, Vue, Svelte** |
| 13 | +- Preserve **full Bootstrap compatibility** (HTML, JS API, events) |
| 14 | +- Reduce boilerplate while adding behavior |
| 15 | + |
| 16 | +Explicitly not a goal: |
| 17 | + |
| 18 | +- Inventing a new design system |
| 19 | +- Replacing Bootstrap CSS |
| 20 | +- Shadow DOM isolation |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## 🚀 Getting started |
| 25 | + |
| 26 | +Good old way |
| 27 | + |
| 28 | +1. Follow the [official guide](https://getbootstrap.com/docs/5.3/getting-started/introduction/) |
| 29 | +2. replace `bootstrap.boundle.min.js` with `bs-elements.boundle.min.js` |
| 30 | +3. or add the `<script src="bs-elements.min.js"></script>` next to it |
| 31 | + |
| 32 | +ES Modules |
| 33 | + |
| 34 | +- Use the `<script src="bs-elements.esm.js" type="module"></script>` |
| 35 | +- or install it with the command: `npm i programmerg/bs-elements` |
| 36 | +- then you can import it as `import * from 'bs-elements'` |
| 37 | + |
| 38 | +--- |
| 39 | + |
| 40 | +## 🧠 Design Principles |
| 41 | + |
| 42 | +### Bootstrap-first |
| 43 | + |
| 44 | +- Bootstrap documentation is the **single source of truth** |
| 45 | +- DOM structure follows Bootstrap, not the component |
| 46 | +- Classes are primary; properties are secondary |
| 47 | +- The original Bootstrap JS API must continue to work unchanged |
| 48 | + |
| 49 | +### Thin DOM wrapper |
| 50 | + |
| 51 | +- No custom markup generation |
| 52 | +- The Custom Element **is the root element**, not an extra wrapper |
| 53 | +- Components enhance existing DOM with behavior |
| 54 | +- Child markup may be intelligently assisted when missing |
| 55 | + |
| 56 | +### Light DOM only |
| 57 | + |
| 58 | +- No Shadow DOM |
| 59 | +- Bootstrap CSS, utilities, and overrides work exactly as expected |
| 60 | + |
| 61 | +### Attribute → state → option mapping |
| 62 | + |
| 63 | +- Attributes initialize internal state |
| 64 | +- Attribute changes update state |
| 65 | +- The imperative JS API is optional and secondary |
| 66 | +- State changes re-initialize the underlying Bootstrap instance |
| 67 | + |
| 68 | +```html |
| 69 | +<bs-modal class="modal" data-bs-backdrop="static" open></bs-modal> |
| 70 | +``` |
| 71 | + |
| 72 | +### Event compatibility |
| 73 | + |
| 74 | +Event names are identical to Bootstrap events |
| 75 | + |
| 76 | +`show.bs.modal`, `shown.bs.modal`, ... |
| 77 | + |
| 78 | +### Idempotent DOM manipulation |
| 79 | + |
| 80 | +- Synchronization is repeatable and safe |
| 81 | +- No duplicated nodes |
| 82 | +- No destructive re-rendering |
| 83 | +- The same HTML remains stable across updates |
| 84 | + |
| 85 | +--- |
| 86 | + |
| 87 | +## 🛠️ Technical Decisions |
| 88 | + |
| 89 | +### Custom Elements |
| 90 | + |
| 91 | +- Not exposed as part of the public API surface |
| 92 | +- Chosen for: |
| 93 | + - reactive attribute handling |
| 94 | + - lifecycle hooks |
| 95 | + - reduced boilerplate |
| 96 | + |
| 97 | +### Bootstrap |
| 98 | + |
| 99 | +- Bootstrap 5 CSS is an external dependency |
| 100 | +- Bootstrap 5 JS is an internal dependency, |
| 101 | + |
| 102 | +We wrap it — we do not reimplement it! |
| 103 | + |
| 104 | +--- |
| 105 | + |
| 106 | +## 📦 Component Categories |
| 107 | + |
| 108 | +### Base components |
| 109 | + |
| 110 | +_Wrappers around native Bootstrap JS behavior:_ |
| 111 | + |
| 112 | +`bs-alert`, `bs-button`, `bs-carousel`, `bs-collapse`, `bs-dropdown`, `bs-modal`, `bs-offcanvas`, `bs-popover`, `bs-tab`, `bs-toast`, `bs-tooltip` |
| 113 | + |
| 114 | +Responsibilities: |
| 115 | + |
| 116 | +- Attribute → option mapping |
| 117 | +- Lifecycle synchronization |
| 118 | +- Event forwarding |
| 119 | + |
| 120 | +### Extra components |
| 121 | + |
| 122 | +_Components not provided by Bootstrap itself._ |
| 123 | + |
| 124 | +Responsibilities: |
| 125 | + |
| 126 | +- Encapsulate higher-level or domain-specific behavior |
| 127 | + |
| 128 | +--- |
| 129 | + |
| 130 | +## 🔁 Content Routing |
| 131 | + |
| 132 | +- Components do not render templates |
| 133 | +- All children stay in the light DOM |
| 134 | +- The component may: |
| 135 | + - recognize child roles |
| 136 | + - add required classes |
| 137 | + - move nodes when structurally necessary |
| 138 | + |
| 139 | +**Auto boilerplate generation** |
| 140 | + |
| 141 | +If required Bootstrap structure is missing, BsElements fills the gap. |
| 142 | + |
| 143 | +```html |
| 144 | +<bs-modal> |
| 145 | + <div class="modal-header">Title</div> |
| 146 | + <p>This will automatically become the modal-body</p> |
| 147 | +</bs-modal> |
| 148 | +``` |
| 149 | + |
| 150 | +--- |
| 151 | + |
| 152 | +## 📡 Lifecycle |
| 153 | + |
| 154 | +- `connectedCallback` → initialize Bootstrap instance |
| 155 | +- Attribute changes → synchronize options |
| 156 | +- `disconnectedCallback` → clean up |
0 commit comments