Skip to content
Merged

Dev #23

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
24a863f
chore: add funding information
TheVolpeDev May 26, 2026
c07f7d1
Merge pull request #18 from FabioGaming/chore/add-funding-information
TheVolpeDev May 26, 2026
f714925
chore: finalize package.json and package-lock.json for publish
TheVolpeDev May 26, 2026
802eba2
chore: add publishConfig to package.json
TheVolpeDev May 26, 2026
de857a0
Potential fix for pull request finding
TheVolpeDev May 26, 2026
ca0301c
Merge pull request #19 from FabioGaming/chore/finalize-package.json-f…
TheVolpeDev May 26, 2026
2c9792f
docs: add documentation comments for For component
TheVolpeDev May 26, 2026
568e2c0
docs: add documentation comments for Match component
TheVolpeDev May 26, 2026
d7297e3
docs: add documentation comments for Show component
TheVolpeDev May 26, 2026
231a526
docs: add documentation comments for Switch component
TheVolpeDev May 26, 2026
c5b0bd2
docs: update documentation comments for Match component
TheVolpeDev May 26, 2026
f412931
Potential fix for pull request finding
TheVolpeDev May 26, 2026
54be1e9
Merge pull request #20 from FabioGaming/docs/add-documentation-comments
TheVolpeDev May 26, 2026
fcfdd55
docs: enhance README with detailed library information
TheVolpeDev May 26, 2026
89a035f
Merge pull request #21 from FabioGaming/docs/add-proper-readme
TheVolpeDev May 26, 2026
adcdb79
Update README.md
TheVolpeDev May 26, 2026
18cb1a9
Update README.md
TheVolpeDev May 26, 2026
19ccbaa
Update README.md
TheVolpeDev May 26, 2026
c0ab34d
chore: update package name in package.json
TheVolpeDev May 26, 2026
b4e70fd
docs: update installation instructions in README.md
TheVolpeDev May 26, 2026
5ccb3f1
ci: add release publish workflow
TheVolpeDev May 26, 2026
5dfece1
Merge pull request #22 from FabioGaming/ci/add-autopublish-ci-
TheVolpeDev May 26, 2026
45629dd
renamed funding file
TheVolpeDev May 26, 2026
9bdb72a
Merge branch 'dev' of https://github.com/FabioGaming/jsx-utils into dev
TheVolpeDev May 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
github: FabioGaming
Comment thread
TheVolpeDev marked this conversation as resolved.
ko_fi: fabiothefox
custom: https://paypal.me/fabiothefox
53 changes: 53 additions & 0 deletions .github/workflows/release-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Release Publish

on:
release:
types: [published]

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- run: npm ci
- run: npm run format:check
- run: npm run build
- run: npm run test:run

- name: Pack release zip
id: pack
run: |
PACKAGE_TGZ=$(npm pack --silent)
PACKAGE_ZIP="${PACKAGE_TGZ%.tgz}.zip"
zip -9 "$PACKAGE_ZIP" "$PACKAGE_TGZ"
echo "package_zip=$PACKAGE_ZIP" >> "$GITHUB_OUTPUT"

- name: Upload release asset
uses: softprops/action-gh-release@v2
with:
files: ${{ steps.pack.outputs.package_zip }}

- name: Setup GitHub Packages registry
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://npm.pkg.github.com
scope: "@fabiogaming"

- name: Set GitHub Packages scope
run: npm pkg set name=@fabiogaming/jsx-utils

- name: Publish to GitHub Packages
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
179 changes: 177 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,177 @@
# .
SolidJS inspired JSX nodes for React ecosystems
# JSX Utils

A zero dependency React library that adds [SolidJS](https://www.solidjs.com/) JSX-Node based control flow for UI designed to work in any React ecosystem by being platform & framework-agnostic

---

### Table of Contents

- [Basic Information](#1-basic-information)
- [Documentation](#2-documentation)
- [Getting Started](#21-getting-started)
- [Added JSX-Nodes with Examples](#22-added-jsx-nodes-with-examples)
- [Examples](#23-examples)
- [AI Usage & Transparency](#3-ai-usage--transparency)

---

## 1. Basic Information

JSX Utils is designed to be a framework-agnostic, zero dependency library you can drop into any React project, be it React through a bundler like Vite or Webpack, NextJS or React Native, these components are pure React logic components and do not contain any platform specific UI nodes

JSX Utils was made to get rid of the annoying ternary based control flow in the UI, which just makes the JSX layer of React applications unreadable, instead JSX Utils sets on Solid's JSX-Node based UI control flow, as it is much more readable, easier to modify and overall better in terms of developer experience

---

## 2. Documentation

JSX-Utils features both this, as well as a built in documentation that you can view in any modern editor by hovering over the JSX-Nodes

### 2.1 Getting Started

To get started with JSX Utils you can install it both through NPM as well as GitHub's package registry

NPM Install (recommended): `npm install @fabiothefox/jsx-utils`

GitHub Install: `npm install @fabiogaming/jsx-utils --registry=https://npm.pkg.github.com`

**Note**
For GitHub the installation might require some additional steps, such as:

- Creating an `.npmrc` file with the following content: `@fabiogaming:registry=https://npm.pkg.github.com` at the root of your project
- Logging into the GitHub package registry: `npm login --registry=https://npm.pkg.github.com`

### 2.2 Added JSX-Nodes With Examples

#### Show

Conditionally renders children when `when` is truthy, otherwise renders `fallback`

```tsx
<Show when={user} fallback={<p>Loading...</p>}>
<p>Welcome back!</p>
...
</Show>
```

#### Match

Renders children only when `when` is truthy.
**Note:** [Match](#match) is typically used inside [Switch](#switch). For standalone conditional rendering, consider [Show](#show).

```tsx
<Match when={isAdmin}>
<p>Admin panel</p>
...
</Match>
```

#### Switch

Renders the children of the first [Match](#match) child whose `when` prop is truthy.

```tsx
<Switch>
<Match when={status === "loading"}>Loading...</Match>
<Match when={status === "success"}>Done!</Match>
<Match when={status === "error"}>Something went wrong.</Match>
</Switch>
```

#### For

Renders a list by mapping each item to JSX with a render function.

```tsx
<For each={users}>
{(user, index) => (
<li key={user.id}>
{index + 1}. {user.name}
</li>
)}
</For>
```

### 2.3 Examples

#### User Profile with Status

Display different UI based on fetch state without nested ternaries:

```tsx
function UserProfile({ userId }) {
const [state, setState] = useState("loading");
const [user, setUser] = useState(null);
const [error, setError] = useState(null);

useEffect(() => {
fetchUser(userId)
.then((data) => {
setUser(data);
setState("success");
})
.catch((err) => {
setError(err);
setState("error");
});
}, [userId]);

return (
<div>
<Switch>
<Match when={state === "loading"}>
<p>Loading profile...</p>
</Match>
<Match when={state === "success"}>
<h2>{user.name}</h2>
<p>{user.bio}</p>
</Match>
<Match when={state === "error"}>
<p>Failed to load profile: {error.message}</p>
</Match>
</Switch>
</div>
);
}
```

#### Task List with Empty State

Render a list with a fallback when empty:

```tsx
function TaskList({ tasks, filter }) {
const filtered = tasks.filter((t) => t.status === filter);

return (
<div>
<h3>Tasks ({filtered.length})</h3>
<Show when={filtered.length > 0} fallback={<p>No tasks yet.</p>}>
<ul>
<For each={filtered}>
{(task) => (
<li key={task.id} className={task.completed ? "done" : ""}>
{task.title}
</li>
)}
</For>
</ul>
</Show>
</div>
);
}
```

---

## 3. AI Usage & Transparency

Copilot has been utilized throughout this project to assist in:

- Code Reviews on Pull Requests as well as minor adjustments when issues were found in said PRs
- Writing parts of the documentation
- Clearing up confusions about concepts
- Writing the CI
- Slight assistance with mock data for Tests

All other code as well as test logic has been **hand rolled**
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 56 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,62 @@
{
"name": "@fabi-dev/jsx-utils",
"name": "@fabiothefox/jsx-utils",
Comment thread
TheVolpeDev marked this conversation as resolved.
"version": "1.0.0",
"description": "",
"main": "index.js",
"description": "SolidJS-inspired JSX control flow utilities for React ecosystems",
"license": "MIT",
"author": "FabioTheFox@Fabidev",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
},
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "git+https://github.com/FabioGaming/jsx-utils.git"
},
"homepage": "https://github.com/FabioGaming/jsx-utils#readme",
"bugs": {
"url": "https://github.com/FabioGaming/jsx-utils/issues"
},
"keywords": [
"react",
"react-native",
"nextjs",
"tsx",
"jsx",
"solidjs",
"solid",
"control-flow",
"show",
"switch",
"match",
"for",
"typescript",
"utility"
],
"funding": {
"type": "github",
"url": "https://github.com/sponsors/FabioGaming"
},
"sideEffects": false,
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "tsup",
"test": "vitest",
"test:run": "vitest run",
"build": "tsup",
"format:check": "prettier src/ --check",
"format:write": "prettier src/ --write"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"peerDependencies": {
"react": ">=17.0.0"
},
Expand All @@ -25,13 +68,14 @@
"jsdom": "^29.1.1",
"prettier": "^3.8.3",
"publint": "^0.3.21",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"tsup": "^8.5.1",
"typescript": "^6.0.3",
"vitest": "^4.1.7"
},
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24.0.0"
}
"node": "^20.19.0 || >=22.12.0"
},
"packageManager": "npm@11.6.2"
}
14 changes: 14 additions & 0 deletions src/components/For.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ export type ForProps<T> = {
children: (item: T, index: number) => React.ReactNode;
};

/**
* Renders a list by mapping each item to JSX with a render function.
*
* @example
* ```tsx
* <For each={users}>
* {(user, index) => (
* <li key={user.id}>
* {index + 1}. {user.name}
* </li>
* )}
* </For>
* ```
*/
export function For<T>(props: ForProps<T>) {
return <>{props.each.map((item, i) => props.children(item, i))}</>;
}
Loading
Loading