https://github.com/projectpenrose/paradox
Simple vanilla JavaScript library for beginners
https://github.com/projectpenrose/paradox
dom-manipulation javascript javascript-library pubsub state-management vanilla-javascript
Last synced: 11 months ago
JSON representation
Simple vanilla JavaScript library for beginners
- Host: GitHub
- URL: https://github.com/projectpenrose/paradox
- Owner: ProjectPenrose
- License: mit
- Created: 2023-03-11T21:19:34.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-01-24T20:04:12.000Z (over 2 years ago)
- Last Synced: 2025-07-18T20:08:40.467Z (11 months ago)
- Topics: dom-manipulation, javascript, javascript-library, pubsub, state-management, vanilla-javascript
- Language: JavaScript
- Homepage:
- Size: 428 KB
- Stars: 4
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.MD
- Changelog: CHANGELOG.md
- License: LICENSE
- Roadmap: ROADMAP.md
Awesome Lists containing this project
README
<Paradox/> Not another javascript framework!
Paradox is just a simple vanilla javascript library for DOM manipulation.
Hopefully it will ease your development while learning
·
Report Bugs
·
Request Features
IMPORTANT: Things are changing a lot right now, so please be patient, this is a work in progress
## Table of Contents
- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
- [Getting Started](#getting-started)
- [Requirements](#requirements)
- [Installation](#installation)
- [Paradox from npm](#paradox-from-npm)
- [Project structure example](#project-structure-example)
- [Webpack config](#webpack-config)
- [Paradox as a module in a simple html project](#paradox-as-a-module-in-a-simple-html-project)
- [Documentation](#documentation)
- [Build an element with `Paradox.buildElement`](#build-an-element-with-paradoxbuildelement)
- [Routes with `Paradox.Router`](#routes-with-paradoxrouter)
- [PubSub with `Paradox.pubsub`](#pubsub-with-paradoxpubsub)
- [Examples](#examples)
- [Contributing](#contributing)
- [License](#license)
- [Contact](#contact)
- [Roadmap](#roadmap)
- [Acknowledgements](#acknowledgements)
## About The Project
Working on cool stuff to say here. stay tuned and please be patient, this is a work in progress.
Contributions are welcome thogh xd, please [start a discussion](https://github.com/ProjectPenrose/paradox/discussions/categories/ideas) to discuss what you would like to change, add or remove and we can figure it out together.
**Link to the** npm package
## Getting Started
Paradox is a simple vanilla javascript library for DOM manipulation that also provides a simple router and PubSub implementation.
### Requirements
- [Node.js](https://nodejs.org/en/) >= v16.16.0 (For development mode)
### Installation
1. Clone the repo
```sh
git clone git@github.com:ProjectPenrose/paradox.git
```
2. Install NPM packages
```sh
cd penrose-paradox
npm install
```
## Usage
Now things can change depending on what you want to do, so here are some options:
### Paradox from npm
You can use paradox in a project that uses npm, all you need before getting started is to have webpack set with babel loader.
Then you can install it like this:
```sh
npm i penrose-paradox
```
Then you can import it like this:
```javascript
import Paradox from "penrose-paradox";
```
Now you'll have access to all the paradox features in your node projects.
#### Project structure example
Here's an example of a project structure that uses paradox:
```sh
. # root
├── app
│ ├── index.js
│ └── index.html
├── dist
│ ├── css
│ │ └── main.css
│ └── js
│ └── bundle.js
├── node_modules
├── package.json
├── package-lock.json
├── server
│ └── index.js
├── scss
│ └── main.scss
└── webpack.config.js
```
- The `app` folder contains the html project and the javascript entry point file where you can import paradox.
- The `dist` folder contains the built project and it's generated by webpack.
- The `node_modules` folder contains the npm packages for the project.
- The `package.json` file contains the project info and the npm scripts.
- The `package-lock.json` file contains the npm packages info.
- The `server` folder contains a simple Nodejs server that serves the `dist` folder and redirects all the requests to the `index.html` file.
- The `scss` folder contains a simple `main.scss` and it should be compiled to `dist/css/main.css`.
- The `webpack.config.js` file contains the webpack config.
#### Webpack config
```javascript
const path = require("path");
module.exports = {
entry: {
"js/bundle": "./app/index.js",
},
target: "web",
mode: "development",
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.(js)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
}
},
],
},
// ... other config
}
```
### Paradox as a module in a simple HTML project
If you want to use it as a module in a simple HTML project, you should import it in your script like this:
```html
import Paradox from "./path/to/penrose-paradox/build/index.js";
```
## Documentation
Paradox includes the following features:
### Build an element with `Paradox.buildElement`
Paradox provides a simple way to build an element with the `buildElement` function that takes the element name and an object with the element properties as arguments.
**Properties:**
| Property | Type | Description |
| --- | --- | --- |
| id | string | The element id |
| classList | string | The element class list separated by spaces |
| attributes | object | The element attributes (e.g. type, value, etc.) |
| events | object | The element events (e.g. click, change, etc.) |
| style | object | The element style (e.g. backgroundColor, color, etc.) |
| text | string | The element text |
| children | array | The element children |
```javascript
import Paradox from "penrose-paradox";
function handleButtonClick() {
alert("Hello World!");
}
const myButton = {
id: "myButton",
classList: "btn btn-primary",
attributes: {
type: "button",
},
events: {
click: handleButtonClick,
},
style: {
backgroundColor: "red",
},
text: "Click me!",
children: [
{
tag: "i",
options: {
id: "myButtonIcon",
classList: "fas fa-hand-pointer",
}
},
],
}
document.body.appendChild(Paradox.buildElement("button", myButton));
```
**NOTES:**
- The `buildElement` function will return a `HTMLElement` object.
- The `children` property is an array of objects with the `tag` and `options` properties. The `tag` property is the element name and the `options` property is the object with the element properties.
- The `options` property is optional, so you can pass just the `tag` property and it will return an element with no properties.
### Routes with `Paradox.Router`
Paradox provides a simple router to handle the navigation between pages.
```javascript
import Paradox from "penrose-paradox";
function Home(props) {
const { root } = props;
root.append(Paradox.buildElement("div", {
id: "home",
text: "Welcome to Paradox!",
}));
}
function About(props) {
const { name, root } = props;
root.append(Paradox.buildElement("div", {
id: "about",
text: `Paradox is a simple vanilla javascript library for DOM manipulation. This is the ${name} page.`,
}));
}
const root = document.getElementById("root");
const routes = [
{
path: "/",
component: Home,
props: {
root,
},
},
{
path: "/about",
component: About,
props: {
name: "About",
root,
},
},
];
const router = new Paradox.Router(routes);
router.init()
.then((path) => {
console.info(`The current path is: ${path}`);
})
.catch((error) => {
console.error(error);
});
```
**NOTES:**
- The router will look for the `#` in the url to handle the navigation. For example, if the url is `http://localhost:8080/#/about`, the router will navigate to the `/about` path.
- The router will inject the `props` object into the component function as an argument and it will contain, besides the properties that you pass, the following properties:
- `queryString`: A string with the query parameters. For example, if the url is `http://localhost:8080/about?name=Paradox`, the `queryString` will be `?name=Paradox`.
- `params`: An object with the path parameters. For example, if the url is `http://localhost:8080/about/Paradox`, and the path is `/about/:name`, the `params` object will be `{ name: "Paradox" }`.
- `query`: An object with the query parameters. For example, if the url is `http://localhost:8080/about?name=Paradox`, the `query` object will be `{ name: "Paradox" }`.
- `baseUrl`: A string with the base url. For example, if the url is `http://localhost:8080/about?name=Paradox`, the `baseUrl` will be `http://localhost:8080`.
### PubSub with `Paradox.pubsub`
Paradox provides a simple PubSub implementation to handle the communication between components.
In case you're not familiar, PubSub is a popular messaging pattern in software architecture. It stands for Publish-Subscribe pattern and is used for communication between different parts of an application or between different applications.
In the PubSub pattern, publishers send messages without knowing who the subscribers are. Subscribers, on the other hand, express interest in one or more events and only receive messages that are of interest, without knowing who sent them.
This pattern is widely used in event-driven programming and can help to decouple the components of an application, leading to code that is easier to maintain and extend. In the context of Paradox, it allows components to communicate with each other in a decoupled manner.
```javascript
import Paradox from "penrose-paradox";
Paradox.pubsub.subscribe("myEvent", (data) => {
console.log(data);
});
Paradox.pubsub.publish("myEvent", "Hello World!");
```
**NOTES:**
- You can use pubsub to communicate between components, for example, you can publish an event in a component and subscribe to it in another component. This way you can pass data between components without having to use props.
- Subscriptions are not persistent, so if you subscribe to an event and then navigate to another page, the subscription will be lost.
- You can use the `Paradox.pubsub.unsubscribe` method to unsubscribe from an event.
- You can not publish an event before subscribing to it xd.
### Examples
You can find some examples in the [`examples` folder.](https://github.com/ProjectPenrose/paradox/tree/main/examples/Readme.md)
## Contributing
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
## License
Distributed under the MIT License. See [`LICENSE`](https://github.com/ProjectPenrose/paradox?tab=MIT-1-ov-file) for more information.
## Contact
Santiago Rincon - [@alexsc6955](https://linkedin.com/in/alexsc6955)
## Roadmap
See the [ROADMAP.md](https://github.com/ProjectPenrose/paradox/ROADMAP.md) for a list of proposed features (and known issues).
If you have any ideas, please [start a discussion](https://github.com/ProjectPenrose/paradox/discussions/categories/ideas) and we can figure it out together.
## Acknowledgements
* [K2](https://github.com/k2con) - For not letting me use React in their projects xd.