Skip to content

Commit

Permalink
fix: correct style object handling in createElement function
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaucau committed Nov 22, 2023
1 parent afcb260 commit 3f66d1e
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 25 deletions.
7 changes: 7 additions & 0 deletions .changeset/plenty-sheep-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'ts-dom-utils': minor
---

- Simplified `createElement` to handle all object properties, including style.
- Fixed issue with styles not applying correctly.
- Updated style type in `SpecialAttributes` to `Partial<CSSStyleDeclaration>` for editor hints and flexibility.
21 changes: 21 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Publish Package to npmjs
on:
release:
types: [published]
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ const button = createElement('button', {
id: 'my-button',
class: ['btn', 'btn-primary'],
text: 'Click me',
onclick: (event) => {
console.log('clicked!', event)
},
dataset: {
action: 'open-menu',
},
Expand All @@ -55,11 +58,11 @@ document.body.appendChild(button);
// <button id="my-button" class="btn btn-primary" data-action="open-menu" aria-expandended="false">Click me</button>
```

| Param | Default | Description |
|---------|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| tagName | undefined | The tag name of the element type to create. |
| options | {} | The options to use when creating the element. Options can include any attributes that can be passed to `setAttribute`, with `class`, `dataset`, and `text` as special options for enhancement. |
| target | document | The Document in which to create the element. |
| Param | Default | Description |
|---------|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| tagName | undefined | The tag name of the element type to create. |
| options | {} | The options to use when creating the element. Options can include any attributes that can be passed to `setAttribute`, with `class`, and `text` as special options for enhancement. |
| target | document | The Document in which to create the element. |
---

## `DOMisReady`
Expand Down
47 changes: 27 additions & 20 deletions src/createElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
* id: 'my-button',
* class: ['btn', 'btn-primary'],
* text: 'Click me',
* onclick: (event) => {
* console.log('clicked!', event)
* },
* dataset: {
* action: 'open-menu',
* },
Expand All @@ -27,30 +30,34 @@ export default function createElement<K extends keyof HTMLElementTagNameMap>(
): HTMLElementTagNameMap[K] {
const element = target.createElement(tagName);
Object.entries(options).forEach(([key, value]) => {
if (value === undefined || value === null) return;

// class key
if (key === 'class') {
// class can be a string or an array of strings
if (Array.isArray(value)) {
element.classList.add(...value);
} else if (typeof value === 'string') {
element.classList.add(value);
}
}
// text key
else if (key === 'text') {
element.textContent = value;
}
// any other key
else if (key in element) {
if (typeof value === 'object' && !Array.isArray(value)) {
Object.entries(value).forEach(([subKey, subValue]) => {
(element as any)[key][subKey] = subValue;
});
} else {
element.classList.add(value as string);
(element as any)[key] = value;
}
} else if (
key === 'dataset' &&
typeof value === 'object' &&
value !== null
) {
Object.entries(value as Record<string, string>).forEach(
([dataKey, dataValue]) => {
element.dataset[dataKey] = dataValue;
},
);
} else if (key === 'text') {
element.textContent = value as string;
return;
} else if (key in element) {
(element as any)[key] = value;
return;
} else {
element.setAttribute(key, value as string);
}
// any other attribute
else {
element.setAttribute(key, value);
}
});

Expand All @@ -59,8 +66,8 @@ export default function createElement<K extends keyof HTMLElementTagNameMap>(

type SpecialAttributes = {
class?: string | string[];
dataset?: Record<string, string>;
text?: string;
style?: Partial<CSSStyleDeclaration>;
};

export type CreateElementOptions<K extends keyof HTMLElementTagNameMap> =
Expand Down

0 comments on commit 3f66d1e

Please sign in to comment.