{"_id":"@ankabit/rui","_rev":"7-9dbc0cceaed28a8c83a06009ca641bab","name":"@ankabit/rui","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@ankabit/rui","version":"1.0.0","keywords":["web-components","frontend","framework","reactive","templates","handlebars","mustache","spa","ui","components","lightweight","hot-reload","plugins","modules","liquidjs"],"author":{"url":"https://ankabit.com","name":"Ankabit Technologies"},"license":"MIT","_id":"@ankabit/rui@1.0.0","maintainers":[{"name":"ankabit","email":"npm@ankabit.com"}],"homepage":"https://github.com/ankabit/rui#readme","bugs":{"url":"https://github.com/ankabit/rui/issues"},"dist":{"shasum":"6f73a1c880a1bc1d9e7b51168b899958ad0cfaa4","tarball":"https://registry.npmjs.org/@ankabit/rui/-/rui-1.0.0.tgz","fileCount":5,"integrity":"sha512-88yVQsyQFl8xzkp5SjmofHXDClQaedai7jcAarnJ1+1Ya/iBWXfulaLkdRUDx1lQLZAlHJg4kCAh4l8Y02HPow==","signatures":[{"sig":"MEQCIH+T87cB+IvxOfwqp9Djg7dsFvXuJAywJObrKAcHOBm1AiBZn9bsd00n9YtejZDMb3Z1HQt0ruQR7JnR80fEi1ZNZQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62504},"main":"dist/rui.min.js","type":"module","module":"src/rui.js","browser":"dist/rui.min.js","engines":{"node":">=14.0.0"},"exports":{".":{"import":"./src/rui.js","browser":"./dist/rui.min.js","require":"./dist/rui.min.js"},"./src":"./src/rui.js","./dist":"./dist/rui.min.js"},"gitHead":"0c944ed1ab05ed76086353f8bb021a2ca5372bc2","scripts":{"dev":"vite","build":"yarn build:external && yarn build:full","serve":"http-server . -p 3000","build:full":"vite build --config vite.config.js","build:external":"MODE=external vite build --config vite.config.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"ankabit","email":"npm@ankabit.com"},"repository":{"url":"git+https://github.com/ankabit/rui.git","type":"git"},"_npmVersion":"10.9.0","description":"A lightweight, reactive, template-driven web component framework with hot-reloadable templates and plugin system","directories":{},"_nodeVersion":"23.2.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","terser":"^5.43.1","http-server":"^14.1.1"},"_npmOperationalInternal":{"tmp":"tmp/rui_1.0.0_1753967879263_0.6352627828791366","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@ankabit/rui","version":"1.0.1","keywords":["web-components","frontend","framework","reactive","templates","handlebars","mustache","spa","ui","components","lightweight","hot-reload","plugins","modules","liquidjs"],"author":{"url":"https://ankabit.com","name":"Ankabit Technologies"},"license":"MIT","_id":"@ankabit/rui@1.0.1","maintainers":[{"name":"ankabit","email":"npm@ankabit.com"}],"homepage":"https://github.com/ankabit/rui#readme","bugs":{"url":"https://github.com/ankabit/rui/issues"},"dist":{"shasum":"dc21c0a89b618f37c1742cd97de0263eac404647","tarball":"https://registry.npmjs.org/@ankabit/rui/-/rui-1.0.1.tgz","fileCount":5,"integrity":"sha512-TWPentl/uDctqwrDx5x2WrNFhLVMiN/sPAO5QGjV2WvKtMTbRrkKiZKVTBWUDxa7juvAGRwiaAm42BgC2cM8+g==","signatures":[{"sig":"MEUCIEypOG9hE7cQeI7Q7aAaFaH5QEfqBOuL80+C4T4zoZBhAiEAtWHX+deNpfp2j/5WOHzZQpEtAuW1Cg3MNaWKmzcpjrY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63094},"main":"dist/rui.min.js","type":"module","module":"src/rui.js","browser":"dist/rui.min.js","engines":{"node":">=14.0.0"},"exports":{".":{"import":"./src/rui.js","browser":"./dist/rui.min.js","require":"./dist/rui.min.js"},"./src":"./src/rui.js","./dist":"./dist/rui.min.js"},"gitHead":"f0eac38342eb1e20a541c58f524ae723ef8ddf2d","scripts":{"dev":"vite","build":"yarn build:external && yarn build:full","serve":"http-server . -p 3000","build:full":"vite build --config vite.config.js","build:external":"MODE=external vite build --config vite.config.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"ankabit","email":"npm@ankabit.com"},"repository":{"url":"git+https://github.com/ankabit/rui.git","type":"git"},"_npmVersion":"10.9.0","description":"A lightweight, reactive, template-driven web component framework with hot-reloadable templates and plugin system","directories":{},"_nodeVersion":"23.2.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","terser":"^5.43.1","http-server":"^14.1.1"},"_npmOperationalInternal":{"tmp":"tmp/rui_1.0.1_1753969287577_0.9880235951870835","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@ankabit/rui","version":"1.0.2","keywords":["web-components","frontend","framework","reactive","templates","handlebars","mustache","spa","ui","components","lightweight","hot-reload","plugins","modules","liquidjs"],"author":{"url":"https://ankabit.com","name":"Ankabit Technologies"},"license":"MIT","_id":"@ankabit/rui@1.0.2","maintainers":[{"name":"ankabit","email":"npm@ankabit.com"}],"homepage":"https://github.com/ankabit/rui#readme","bugs":{"url":"https://github.com/ankabit/rui/issues"},"dist":{"shasum":"b5b9e7da29244fd31862b3505885f4fb6ded7e0c","tarball":"https://registry.npmjs.org/@ankabit/rui/-/rui-1.0.2.tgz","fileCount":5,"integrity":"sha512-qhNRpmglr/5eww2hsxIQWbFAx5l2CYlqHq9Acup+j6uSPc27KjuKmN+T/UNYRiZ0YlEmwugMqGdeewoGV3sj2g==","signatures":[{"sig":"MEYCIQDOyzcW+HYuiN+nXIbscFKNwpCk5wOTjbXhjgMF7G0L7wIhAMMgdBcbzAGc0Nrjqfej+/UvcjBuSFFNei080O5+FR+c","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63306},"main":"dist/rui.min.js","type":"module","module":"src/rui.js","browser":"dist/rui.min.js","engines":{"node":">=14.0.0"},"exports":{".":{"import":"./src/rui.js","browser":"./dist/rui.min.js","require":"./dist/rui.min.js"},"./src":"./src/rui.js","./dist":"./dist/rui.min.js"},"gitHead":"ba5bef76938192239117989b9980e40addcdf3f7","scripts":{"dev":"vite","build":"yarn build:external && yarn build:full","serve":"http-server . -p 3000","build:full":"vite build --config vite.config.js","build:external":"MODE=external vite build --config vite.config.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"ankabit","email":"npm@ankabit.com"},"repository":{"url":"git+https://github.com/ankabit/rui.git","type":"git"},"_npmVersion":"10.9.0","description":"A lightweight, reactive, template-driven web component framework with hot-reloadable templates and plugin system","directories":{},"_nodeVersion":"23.2.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","terser":"^5.43.1","http-server":"^14.1.1"},"_npmOperationalInternal":{"tmp":"tmp/rui_1.0.2_1753971152085_0.1541554400435694","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@ankabit/rui","version":"1.0.3","keywords":["web-components","frontend","framework","reactive","templates","handlebars","mustache","spa","ui","components","lightweight","hot-reload","plugins","modules","liquidjs"],"author":{"url":"https://ankabit.com","name":"Ankabit Technologies"},"license":"MIT","_id":"@ankabit/rui@1.0.3","maintainers":[{"name":"ankabit","email":"npm@ankabit.com"}],"homepage":"https://github.com/ankabit/rui#readme","bugs":{"url":"https://github.com/ankabit/rui/issues"},"dist":{"shasum":"e6b1cb355f1b7fa049654ee3cdff8da6facfa81e","tarball":"https://registry.npmjs.org/@ankabit/rui/-/rui-1.0.3.tgz","fileCount":5,"integrity":"sha512-lARVLPIYDcra0HfLCPipuUuSf9tVUf6vTIY9aNCe73kAbv107hgh1Amh2Jo8hMPCejLRgnq2BSR4mofCQMTwaQ==","signatures":[{"sig":"MEYCIQCIZF5FjZLkBpDgcUs4eGV8amT191OSm6NUB2U23yq1PAIhALTVTDjFITb94852lardO9c0Ty3jnt9OX81WehNWgYvk","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":68850},"main":"dist/rui.min.js","type":"module","module":"src/rui.js","browser":"dist/rui.min.js","engines":{"node":">=14.0.0"},"exports":{".":{"import":"./src/rui.js","browser":"./dist/rui.min.js","require":"./dist/rui.min.js"},"./src":"./src/rui.js","./dist":"./dist/rui.min.js"},"gitHead":"3bc76b5911aa978be8612ba58588cc9e4206db12","scripts":{"dev":"vite","build":"yarn build:external && yarn build:full","serve":"http-server . -p 3000","build:full":"vite build --config vite.config.js","build:external":"MODE=external vite build --config vite.config.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"ankabit","email":"npm@ankabit.com"},"repository":{"url":"git+https://github.com/ankabit/rui.git","type":"git"},"_npmVersion":"10.9.0","description":"A lightweight, reactive, template-driven web component framework with hot-reloadable templates and plugin system","directories":{},"_nodeVersion":"23.2.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","terser":"^5.43.1","http-server":"^14.1.1"},"_npmOperationalInternal":{"tmp":"tmp/rui_1.0.3_1754063035293_0.14679030237626178","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@ankabit/rui","version":"1.0.4","keywords":["web-components","frontend","framework","reactive","templates","handlebars","mustache","spa","ui","components","lightweight","hot-reload","plugins","modules","liquidjs"],"author":{"url":"https://ankabit.com","name":"Ankabit Technologies"},"license":"MIT","_id":"@ankabit/rui@1.0.4","maintainers":[{"name":"ankabit","email":"npm@ankabit.com"}],"homepage":"https://github.com/ankabit/rui#readme","bugs":{"url":"https://github.com/ankabit/rui/issues"},"dist":{"shasum":"764f3cdefa50c809cf8593e8b10e4aa63c06a22e","tarball":"https://registry.npmjs.org/@ankabit/rui/-/rui-1.0.4.tgz","fileCount":5,"integrity":"sha512-lgDZ7xrz6ry5g1KulSw/zvIetBNgoPxzn8ZVkx6egCFXzP6GEKCJIYBwXXkgGd+/0WDOquF0+o65YEY/VauMng==","signatures":[{"sig":"MEUCICyvagu7vfC27nbt4MkFREN1nmY/3TgMo8/mlcS1PB8lAiEAtgB0SU8vCMGgwBM1dtUsTFdCy+WnZg4Vh/tWrtf+PkA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":68931},"main":"dist/rui.min.js","type":"module","module":"src/rui.js","browser":"dist/rui.min.js","engines":{"node":">=14.0.0"},"exports":{".":{"import":"./src/rui.js","browser":"./dist/rui.min.js","require":"./dist/rui.min.js"},"./src":"./src/rui.js","./dist":"./dist/rui.min.js"},"gitHead":"5d5a46d84bfe3dc5d443b2f831f26d2ce71bd1eb","scripts":{"dev":"vite","build":"yarn build:external && yarn build:full","serve":"http-server . -p 3000","build:full":"vite build --config vite.config.js","build:external":"MODE=external vite build --config vite.config.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"ankabit","email":"npm@ankabit.com"},"repository":{"url":"git+https://github.com/ankabit/rui.git","type":"git"},"_npmVersion":"10.9.0","description":"A lightweight, reactive, template-driven web component framework with hot-reloadable templates and plugin system","directories":{},"_nodeVersion":"23.2.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","terser":"^5.43.1","http-server":"^14.1.1"},"_npmOperationalInternal":{"tmp":"tmp/rui_1.0.4_1754488660899_0.11982203610305442","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@ankabit/rui","version":"1.0.5","keywords":["web-components","frontend","framework","reactive","templates","handlebars","mustache","spa","ui","components","lightweight","hot-reload","plugins","modules","liquidjs"],"author":{"url":"https://ankabit.com","name":"Ankabit Technologies"},"license":"MIT","_id":"@ankabit/rui@1.0.5","maintainers":[{"name":"ankabit","email":"npm@ankabit.com"}],"homepage":"https://github.com/ankabit/rui#readme","bugs":{"url":"https://github.com/ankabit/rui/issues"},"dist":{"shasum":"0ec74eeed00758de062e811685e19181207b058b","tarball":"https://registry.npmjs.org/@ankabit/rui/-/rui-1.0.5.tgz","fileCount":5,"integrity":"sha512-aM56jlqB3juEt4NFdGSSHSuvSYj73lRTdcGUucFD0GnhVF6GOvo5IwrDMZaTIDUsSRuFUYRVnS5UF/8pyFnYCg==","signatures":[{"sig":"MEUCIQDW9uZKjtQAkzjtlfhyYFQp3XmrU+NTmoQX2U0eiVswFwIgatU/qCPsRnOVqzSR27LpAhoxFH4DXRzu0+w1sGrvN/A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69821},"main":"dist/rui.min.js","type":"module","module":"src/rui.js","browser":"dist/rui.min.js","engines":{"node":">=14.0.0"},"exports":{".":{"import":"./src/rui.js","browser":"./dist/rui.min.js","require":"./dist/rui.min.js"},"./src":"./src/rui.js","./dist":"./dist/rui.min.js"},"gitHead":"5f0dd38d7540f7ccf0fba333109c532fa1ee3976","scripts":{"dev":"vite","build":"yarn build:external && yarn build:full","serve":"http-server . -p 3000","build:full":"vite build --config vite.config.js","publish:major":"npm version major && npm publish","publish:minor":"npm version minor && npm publish","publish:patch":"npm version patch && npm publish","build:external":"MODE=external vite build --config vite.config.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"ankabit","email":"npm@ankabit.com"},"repository":{"url":"git+https://github.com/ankabit/rui.git","type":"git"},"_npmVersion":"10.9.0","description":"A lightweight, reactive, template-driven web component framework with hot-reloadable templates and plugin system","directories":{},"_nodeVersion":"23.2.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","terser":"^5.43.1","http-server":"^14.1.1"},"_npmOperationalInternal":{"tmp":"tmp/rui_1.0.5_1764870984470_0.8123463680884606","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@ankabit/rui","version":"1.1.0","description":"A lightweight, reactive, template-driven web component framework with hot-reloadable templates and plugin system","type":"module","main":"dist/rui.min.js","module":"src/rui.js","browser":"dist/rui.min.js","exports":{".":{"import":"./src/rui.js","require":"./dist/rui.min.js","browser":"./dist/rui.min.js"},"./dist":"./dist/rui.min.js","./src":"./src/rui.js"},"keywords":["web-components","frontend","framework","reactive","templates","handlebars","mustache","spa","ui","components","lightweight","hot-reload","plugins","modules","liquidjs"],"author":{"name":"Ankabit Technologies","url":"https://ankabit.com"},"license":"MIT","homepage":"https://github.com/ankabit/rui#readme","repository":{"type":"git","url":"git+https://github.com/ankabit/rui.git"},"bugs":{"url":"https://github.com/ankabit/rui/issues"},"engines":{"node":">=14.0.0"},"scripts":{"dev":"vite","build:external":"MODE=external vite build --config vite.config.js","build:full":"vite build --config vite.config.js","build":"yarn build:external && yarn build:full","serve":"http-server . -p 3000","prepublishOnly":"npm run build","publish:patch":"npm version patch && npm publish","publish:minor":"npm version minor && npm publish","publish:major":"npm version major && npm publish"},"devDependencies":{"http-server":"^14.1.1","terser":"^5.43.1","vite":"^5.0.0"},"dependencies":{},"publishConfig":{"access":"public"},"_id":"@ankabit/rui@1.1.0","gitHead":"6142da5027fe315f87b6d1de7a641fb74496471f","_nodeVersion":"23.2.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-01x7ZR5E3WownENwDtIL/mljBp8z1AYODv9PwXpr3QOYxgjdCeNFw0n/mLeN8wVNkmMlr0G8ygCpGXqJK2YTpA==","shasum":"61f994d6f95c4cc2085b398724686851c9c30890","tarball":"https://registry.npmjs.org/@ankabit/rui/-/rui-1.1.0.tgz","fileCount":5,"unpackedSize":76516,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDbt1ZVSilflehCkzPX4CVhLcNI8LtvvHUgZDXr+qkTrAIhAM9LAaMDFOLhn583k1Depq0P6qCnEoHOQkn+98IG7+68"}]},"_npmUser":{"name":"ankabit","email":"npm@ankabit.com"},"directories":{},"maintainers":[{"name":"ankabit","email":"npm@ankabit.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rui_1.1.0_1766183616895_0.6316775643706782"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-31T13:17:59.150Z","modified":"2025-12-19T22:33:37.230Z","1.0.0":"2025-07-31T13:17:59.452Z","1.0.1":"2025-07-31T13:41:27.798Z","1.0.2":"2025-07-31T14:12:32.279Z","1.0.3":"2025-08-01T15:43:55.535Z","1.0.4":"2025-08-06T13:57:41.080Z","1.0.5":"2025-12-04T17:56:24.644Z","1.1.0":"2025-12-19T22:33:37.053Z"},"bugs":{"url":"https://github.com/ankabit/rui/issues"},"author":{"name":"Ankabit Technologies","url":"https://ankabit.com"},"license":"MIT","homepage":"https://github.com/ankabit/rui#readme","keywords":["web-components","frontend","framework","reactive","templates","handlebars","mustache","spa","ui","components","lightweight","hot-reload","plugins","modules","liquidjs"],"repository":{"type":"git","url":"git+https://github.com/ankabit/rui.git"},"description":"A lightweight, reactive, template-driven web component framework with hot-reloadable templates and plugin system","maintainers":[{"name":"ankabit","email":"npm@ankabit.com"}],"readme":"## 📖 RUI (Reusable UI) Framework — Comprehensive Developer Documentation\n\nWelcome to the RUI frontend framework documentation — a lightweight, reactive, template-driven web component system built for modern, scalable frontend applications.\n\n**Important:** RUI is built to run without requiring a build step or bundler. You can drop `rui.js` or `rui.min.js` directly into your project and start using it immediately in your browser, or optionally use a modern dev server like Vite for hot reload convenience.\n\n---\n\n# 📚 Overview\n\nRUI offers a minimal but extensible system for building and managing Web Components using native browser APIs, supporting reactive state management, hot-reloadable templates, plugin hooks, and pluggable template engines (Handlebars, Mustache, or custom functions).\n\n**Features:**\n\n- Lightweight web component base class.\n- Hot-reloadable template system (inline or remote).\n- Reactive state.\n- Plugin management with priority queue, versioning, and enable/disable support.\n- SPA-friendly and router-agnostic.\n- Zero build tools required — works natively in the browser.\n\n---\n\n# ⚙️ Getting Started\n\n## 1️⃣ Include RUI In Your Project\n\nYou can either:\n\n- **Use via CDN:**\n\n```html\n<script src=\"https://unpkg.com/@ankabit/rui@1.0.2/dist/rui.min.js\"></script>\n```\n\n- **Or download `rui.js` / `rui.min.js`** from the repo and include locally.\n\n**Example Project Structure:**\n\n```\n/my-rui-project/\n  /templates/\n  /src/\n  rui.min.js\n  index.html\n```\n\n**Important:** No bundler is required — RUI is native ES module compatible.\n\n---\n\n## 2️⃣ Dev Server & Hot Reload Setup Options\n\n### 🔥 Option 1: Vite Dev Server (Recommended)\n\n**Install Vite locally:**\n\n```bash\nnpm install vite --save-dev\n```\n\n**Add a `dev` script in `package.json`:**\n\n```json\n{\n  \"scripts\": {\n    \"dev\": \"vite\"\n  }\n}\n```\n\n**Create `vite.config.js` if desired:**\n\n```js\nexport default {\n  root: '.',\n  server: {\n    open: true,\n    port: 3000,\n  },\n};\n```\n\n**Run your dev server:**\n\n```bash\nnpm run dev\n```\n\n**Notes:**\n\n- Ensure your `index.html` is in the project root.\n- Templates fetched by RUI must be inside the dev server’s accessible directory.\n- Vite hot reloads JS modules, template fetches, and static assets.\n\n### 🔥 Option 2: Native Browser with Live Server Extension (Zero Config)\n\n- Install the **Live Server** VS Code extension (or any browser live reload plugin).\n- Open your project folder and click **Go Live**.\n- Your `index.html` and templates are served over `localhost`.\n- No NPM, no build tools.\n\n### 🔥 Option 3: Simple Static HTTP Server\n\n- Install a basic static HTTP server:\n\n```bash\nnpm install -g http-server\n```\n\n- Serve your project:\n\n```bash\nhttp-server . -p 3000\n```\n\n**Benefit:** Zero config, zero build steps. Great for demos or local development.\n\n---\n\n# 📦 Defining Components\n\n## Base Component Class\n\nExtend `RUI.BaseComponent` to create new custom components:\n\n```js\nclass AlertBox extends RUI.BaseComponent {\n  static tag = 'alert-box';\n\n  getInitialData() {\n    return {\n      message: 'Hello World!',\n      extraMessage: '', // This will automatically be set to the atribute passed at first i.e extra-message\n    };\n  }\n\n  onConnected() {\n    console.log('AlertBox connected!', this.data.extraMessage, this.getAttribute('extra-message'));\n  }\n}\n\nRUI.ComponentRegistry.register(AlertBox);\n```\n\n**Usage:**\n\n```html\n<rui-alert-box extra-message=\"Some text\"></rui-alert-box>\n```\n\n## kebab case attributes are auto read as camel case i.e extra-message will be used in JS scope as extraMessage . This will be handled automatically by the library.\n\n# 🎨 Templates\n\n## Inline Template:\n\n```html\n<script type=\"text/template\" data-tag-template=\"alert-box\">\n  <div class='alert'>{{message}}</div>\n</script>\n```\n\n## Remote Template:\n\nSave as `/templates/alert-box.hbs`:\n\n```html\n<div class=\"alert\">{{message}}</div>\n```\n\n## Custom Template URL Resolution\n\nYou can customize how templates are resolved by providing a `templateUrlResolver` function:\n\n```js\nRUI.Config.templateUrlResolver = async (key) => {\n  // Custom logic to resolve template URLs\n  return [`/custom-templates/${key}.hbs`, `/fallback/${key}.html`];\n};\n```\n\nThe resolver function receives the template key and should return an array of URLs to try in order. If no resolver is provided, RUI will use the default behavior of searching through `templateFolders` with the configured `extensions`.\n\n---\n\n## 🎯 Slots\n\nRUI supports **named slots** for flexible content composition, similar to Vue.js or Web Components.\n\n### Template Slots\n\nDefine slots in your templates using `<slot>` elements:\n\n```html\n<!-- card.hbs -->\n<div class=\"card\">\n  <slot name=\"header\"></slot>\n  <div class=\"content\">\n    <slot name=\"content\"></slot>\n  </div>\n  <slot></slot>\n  <!-- default/unnamed slot -->\n</div>\n```\n\n### Using Slots\n\nInsert content into specific slots using the `slot` attribute:\n\n```html\n<rui-card title=\"My Card\">\n  <!-- Named slot: header -->\n  <div slot=\"header\">\n    <h3>Card Header</h3>\n  </div>\n\n  <!-- Named slot: content -->\n  <p slot=\"content\">This goes in the content slot</p>\n\n  <!-- Default slot (no slot attribute) -->\n  <button>Default slot content</button>\n</rui-card>\n```\n\n### Slot Features\n\n✅ **Named slots** - Target specific areas with `slot=\"name\"`  \n✅ **Default slot** - Content without `slot` attribute goes to `<slot></slot>`  \n✅ **Raw HTML** - Slot content stays exactly as written (no template processing)  \n✅ **Component isolation** - Each component manages its own slots independently\n\n### Example\n\n```js\nclass CardComponent extends RUI.BaseComponent {\n  static tag = 'card';\n}\n```\n\n```html\n<!-- Template: templates/card.hbs -->\n<div class=\"card\">\n  <header><slot name=\"header\"></slot></header>\n  <main><slot name=\"content\"></slot></main>\n  <footer><slot></slot></footer>\n</div>\n\n<!-- Usage -->\n<rui-card>\n  <h2 slot=\"header\">Welcome</h2>\n  <p slot=\"content\">Card content here</p>\n  <small>Footer content</small>\n</rui-card>\n```\n\n## 📖 📂 Table of Contents\n\n```\n# RUI Documentation\n\n- Introduction\n- Getting Started\n- Configuration\n- Template Engine\n- 🔒 Template Sanitizing (this new section)\n- Plugin Manager\n- BaseComponent API\n- Hot Reloading\n- Example Projects\n- Development Setup\n- Contributing\n```\n\n---\n\n## 📑 📦 Sanitizing Rendered Templates\n\n### 🔒 Template Sanitizing\n\nBy default, RUI does **not sanitize rendered templates** to give you full control over security strategy for your environment.\nTo prevent XSS attacks or unsafe HTML rendering, you can configure a **sanitizer function** via `RUI.Config.templateSanitizer` and or via `RUI.Config.renderedTemplateSanitizer`.\n\nThe former will sanitize loaded template from inline script or URL and later will santizer rendering engine output.\n\nIf configured, this function will automatically process every rendered template string before it's inserted into the DOM.\n\n---\n\n### 📌 Configuring a Sanitizer\n\n#### Example 1: Using [DOMPurify](https://github.com/cure53/DOMPurify)\n\n```html\n<script src=\"https://cdn.jsdelivr.net/npm/dompurify@3.0.5/dist/purify.min.js\"></script>\n<script>\n  RUI.Config.templateSanitizer = (html) => DOMPurify.sanitize(html);\n</script>\n```\n\n---\n\n#### Example 2: Custom Regex Sanitizer\n\n_(Note: Regex sanitizers can be brittle — use with care)_\n\n```js\nRUI.Config.templateSanitizer = (html) => html.replace(/<script.*?>.*?<\\/script>/gi, '');\n```\n\n---\n\n#### Example 3: Disable Sanitizing\n\nIf your templates are trusted or pre-sanitized:\n\n```js\nRUI.Config.templateSanitizer = null;\n```\n\nAlways use `RUI.Config.renderedTemplateSanitizer` if you are parsing content from user input for safety.\n\n---\n\n### 📌 When Does the Sanitizer Run?\n\nThe sanitizer function runs **after the template is loaded of fectched**, **after the template engine renders HTML**, but **before it’s inserted into the DOM**:\n\n```\nTemplate → Load → Sanitizer(RUI.Config.templateSanitizer) → Render (Handlebars/Mustache/custom) → Sanitizer(RUI.Config.renderedTemplateSanitizer) → Inject into DOM\n```\n\nThe later `RUI.Config.renderedTemplateSanitizer` ensures even partials or user-provided data are filtered safely.\n\n---\n\n### 📌 Tip: You Can Also Sanitize via a Plugin\n\nIf you'd prefer a plugin-based approach:\n\n```js\nRUI.PluginManager.register({\n  name: 'SanitizerPlugin',\n  priority: 0, // we want this to be the last to run\n  onRegister: () => {\n    RUI.PluginManager.on('template:loaded', (html) => DOMPurify.sanitize(html));\n  },\n});\n```\n\n---\n\n### 📌 Recommendation\n\nIf your app handles untrusted template content (user submissions, CMS-generated, etc), **always enable sanitizing** via one of these approaches.\n\n---\n\n# 🔄 Hot Reloading\n\nTo reload all templates:\n\n```js\nRUI.reloadAllComponents();\n```\n\nOr for a specific tag:\n\n```js\nRUI.PluginManager.hotReload('rui-alert-box');\n```\n\n---\n\n# 🔌 Plugin API\n\nPlugins can hook into component lifecycle events.\n\n## Example Logger Plugin:\n\n```js\nRUI.PluginManager.register({\n  name: 'LoggerPlugin',\n  version: '1.0.0',\n  priority: 10,\n\n  onComponentConnected(component) {\n    console.log(`[Connected] ${component.constructor.tagName}`);\n  },\n\n  onComponentDisconnected(component) {\n    console.log(`[Disconnected] ${component.constructor.tagName}`);\n  },\n});\n```\n\n## Managing Plugins\n\n```js\nRUI.PluginManager.disable('LoggerPlugin');\nRUI.PluginManager.enable('LoggerPlugin');\nRUI.PluginManager.list();\n```\n\n---\n\n# 🔍 DOM Utilities\n\n- `qs(selector)` — querySelector within component root.\n- `qsa(selector)` — querySelectorAll within component root.\n\n---\n\n# 🖥️ SPA & Routing\n\nRUI is router-agnostic. You can use any lightweight router like [Navigo](https://github.com/krasimir/navigo) or [tiny-router](https://github.com/alexanderGugel/mini-router).\n\n**Example SPA Setup:**\n\n```js\nconst router = new Navigo('/');\n\nrouter\n  .on('/about', () => {\n    document.querySelector('#view').innerHTML = '<rui-about-page></rui-about-page>';\n  })\n  .resolve();\n```\n\n---\n\n# 📦 Nested Components Example\n\n```html\n<rui-card>\n  <rui-button label=\"Click me!\"></rui-button>\n</rui-card>\n```\n\nEach can render individually with their own templates and data.\n\n---\n\n# 📝 Real-world Mini Project Idea\n\n**A simple SPA dashboard:**\n\n- `/templates/default/dashboard.hbs`\n- `<rui-navbar>` with inline template.\n- `<rui-dashboard>` with cards and buttons.\n- Navigo for routing.\n\n---\n\n# 📖 Full API Reference\n\n## RUI.Config\n\n- `tagPrefix` - Custom element tag prefix (default: 'rui')\n- `templateFolders` - Array of folder paths to search for templates (default: ['/templates'])\n- `templateUrlResolver` - Optional function to customize template URL resolution (default: null)\n- `extensions` - Array of allowed template file extensions (default: ['.hbs'])\n- `templateEngine` - Template engine ('handlebars', 'mustache', 'liquidjs', or custom function)\n- `debug` - Enable debug logging (default: false)\n- `templateSanitizer` - Function to sanitize loaded templates (default: null)\n- `renderedTemplateSanitizer` - Function to sanitize rendered templates (default: null)\n\n## RUI.ComponentRegistry\n\n- `register(componentClass)`\n\n## RUI.TemplateLoader\n\n- `load(key)`\n- `normalizeKey(tagName)`\n\n## RUI.TemplateEngine\n\n- `parse(template, data, partials)`\n\n## RUI.PluginManager\n\n- `register(plugin)`\n- `notifyConnected(component)`\n- `notifyDisconnected(component)`\n- `hotReload(tagName?)`\n- `enable(name)`\n- `disable(name)`\n- `list()`\n\n## RUI.BaseComponent\n\n- `tag`\n- `templateNamespace`\n- `static get observedAttributes()`\n- `getInitialData()`\n- `getPartials()`\n- `getTemplateKey()`\n- `parseTemplate(template, data, partials)`\n- `onBeforeConnected()`\n- `onConnected()`\n- `onAttributeChanged(name, oldValue, newValue)`\n- `onBeforeDisconnected()`\n- `onDisconnected()`\n- `reloadTemplate()`\n- `qs(selector)`\n- `qsa(selector)`\n- `bindEvent(el, type, handler)`\n- `bindRootEvent(type, handler)`\n- `unbindAllEvents()`\n- `emit(event, detail)`\n- `on(event, handler)`\n- `off(event, handler)`\n\n## Global\n\n- `RUI.reloadAllComponents()`\n\n---\n\n# 🙏 Acknowledgments\n\nRUI draws inspiration from several excellent frameworks and libraries:\n\n- **[Lit](https://lit.dev/)** - Web Components best practices and modern browser APIs\n- **[Ractive](https://ractive.js.org/)** - Template-driven development and data binding concepts\n- **[Reef](https://reefjs.com/)** - Lightweight reactive rendering and simple API design\n- **[React](https://reactjs.org/)** - Component-based architecture and reactive state management patterns\n\nWe're grateful to these projects and their communities for paving the way for modern frontend development.\n\n---\n\n# 📌 Final Notes\n\n- Works with Handlebars, Mustache, LiquidJS (via window.liquidEngine), or any custom template parser.\n- Zero dependencies.\n- Plugin system is priority-aware and can be toggled.\n- Uses Light DOM for simple, accessible components.\n- No build tool required — use native browser modules.\n- Dev server is optional for hot reloading.\n","readmeFilename":"README.md"}