diff --git a/index.html b/index.html
index c07670f..549341c 100644
--- a/index.html
+++ b/index.html
@@ -12,6 +12,7 @@
+ Test
Hello, world
diff --git a/packages/banners/src/index.js b/packages/banners/src/index.js
index 4d30d62..4099fb9 100644
--- a/packages/banners/src/index.js
+++ b/packages/banners/src/index.js
@@ -1,2 +1,97 @@
-// eslint-disable-next-line no-console
-console.log('Hello world from the package!');
+/**
+ * @typedef {import('./index.js').BannerObject} BannerObject
+ */
+import getLocalLayout from './layouts.js';
+
+/**
+ * @param {Readonly} string - The string to be converted.
+ * @param {Document} document - The document API to be used.
+ * @returns {HTMLElement} - The DOM of the string.
+ */
+function stringToHtml(string, document) {
+ const tmp = document.createElement('template');
+ tmp.innerHTML = string;
+ /** @type {HTMLElement} */
+ const dom = tmp.children[0];
+ return dom;
+}
+
+/**
+ * @param {HTMLElement} element - The element to be converted to string.
+ * @param {Document} document - The document API to be used.
+ * @returns {string} - The resulting string.
+ */
+function htmlToString(element, document) {
+ const tmp = document.createElement('template');
+ tmp.appendChild(element);
+ return tmp.innerHTML;
+}
+/**
+ * @typedef {{
+ * modify(query: string, callback: (el: Element | null) => T) => T
+ * }} DOMHelper
+ * @param {HTMLElement} element - The element to be manipulated.
+ * @returns {DOMHelper}
+ */
+function domHelper(element) {
+ return {
+ /**
+ * @template T
+ * @param {string} query - The query selector to find the element.
+ * @param {(el: Element | null) => T} callback - Callback to modify the element.
+ * @returns {T} - The return value of the callback.
+ * @throws {Error} - Throws if the element is not found.
+ */
+ modify(query, callback) {
+ const el = element.querySelector(query);
+
+ return callback(el);
+ },
+ };
+}
+
+/**
+ * @param {BannerObject} object - The Banner Object to be generated from.
+ * @returns {Promise} - The SVG of the banner.
+ */
+async function banner(object) {
+ /** @type {Document} */
+ // @ts-expect-error because Document is not compatible with Readonly
+ const doc = object.lib?.document ?? globalThis.document;
+ /** @type {Readonly} */
+ const svg = await getLocalLayout('vertical');
+
+ const dom = stringToHtml(svg, doc);
+ const helper = domHelper(dom);
+
+ helper.modify('[data-banner-class="title"] > tspan', (el) => {
+ if (!el) return;
+
+ el.innerHTML = object.title;
+ });
+ helper.modify('[data-banner-class="subtitle"] > tspan', (el) => {
+ if (!el) return;
+ el.innerHTML = object.subtitle ?? '';
+ });
+ return htmlToString(dom, doc);
+}
+/**
+ * Test function.
+ */
+async function test() {
+ const testBanner = await banner({
+ lib: {
+ // @ts-expect-error because Document is not DeepReadonly
+ document: new Document(),
+ fetch,
+ },
+ title: 'Hello, world',
+ });
+
+ const body = globalThis.document.getElementsByTagName('body')[0];
+ body.innerHTML = testBanner;
+}
+await test();
+
+export default banner;
+
diff --git a/packages/banners/src/layouts.js b/packages/banners/src/layouts.js
new file mode 100644
index 0000000..ed9f92e
--- /dev/null
+++ b/packages/banners/src/layouts.js
@@ -0,0 +1,27 @@
+
+/**
+ * Imports a local layout from the static folder.
+ *
+ * @param {import('./types.d.ts').BuiltinLayouts} layout - The banner layout.
+ * @param {boolean} [rtl] - Is the layout right-to-left?
+ * @returns {Promise} - The SVG string of the layout file.
+ */
+async function getLocalLayout(layout, rtl = false) {
+ let layoutFile;
+ /* eslint-disable import/no-relative-parent-imports */
+ switch (layout) {
+ case 'vertical': {
+ layoutFile = await import('../static/vertical.svg.js');
+ break;
+ }
+ default: {
+ if (rtl)
+ layoutFile = await import('../static/horizontal-rtl.svg.js');
+ layoutFile = await import('../static/horizontal.svg.js');
+ }
+ }
+ /* eslint-enable */
+
+ return layoutFile.default;
+}
+export default getLocalLayout;
diff --git a/packages/banners/test.html b/packages/banners/test.html
new file mode 100644
index 0000000..014bc7c
--- /dev/null
+++ b/packages/banners/test.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+