@arundeep_bhardwaj/r-lite 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/index.css +155 -0
- package/index.html +11 -0
- package/index.js +80 -0
- package/package.json +18 -0
- package/r_lite/core.js +45 -0
- package/r_lite/hooks.js +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# r-lite ⚡
|
|
2
|
+
|
|
3
|
+
A lightweight UI library built in pure JavaScript, designed for
|
|
4
|
+
micro-frontend architectures and performance-critical applications.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- Function components
|
|
9
|
+
- Hooks (`useState`, `useEffect`)
|
|
10
|
+
- Minimal runtime
|
|
11
|
+
- No virtual DOM complexity
|
|
12
|
+
- Micro-frontend friendly
|
|
13
|
+
- Pure JavaScript
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install r-lite
|
package/index.css
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
|
|
2
|
+
* {
|
|
3
|
+
box-sizing: border-box;
|
|
4
|
+
font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body {
|
|
8
|
+
margin: 0;
|
|
9
|
+
background: radial-gradient(circle at top, #020617, #020617 60%);
|
|
10
|
+
color: #e5e7eb;
|
|
11
|
+
min-height: 100vh;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
.app-container {
|
|
16
|
+
max-width: 1200px;
|
|
17
|
+
margin: auto;
|
|
18
|
+
padding: 32px 20px 80px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
.header {
|
|
23
|
+
margin-bottom: 56px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.header h1 {
|
|
27
|
+
font-size: 3rem;
|
|
28
|
+
font-weight: 800;
|
|
29
|
+
letter-spacing: -1px;
|
|
30
|
+
margin-bottom: 10px;
|
|
31
|
+
background: linear-gradient(90deg, #49acd6, #60a5fa);
|
|
32
|
+
-webkit-background-clip: text;
|
|
33
|
+
-webkit-text-fill-color: transparent;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.tagline {
|
|
37
|
+
max-width: 700px;
|
|
38
|
+
font-size: 1.05rem;
|
|
39
|
+
color: #f2f3f4;
|
|
40
|
+
line-height: 1.6;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* badges */
|
|
44
|
+
.badges {
|
|
45
|
+
margin-top: 18px;
|
|
46
|
+
display: flex;
|
|
47
|
+
gap: 12px;
|
|
48
|
+
flex-wrap: wrap;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.badges span {
|
|
52
|
+
padding: 6px 14px;
|
|
53
|
+
border-radius: 999px;
|
|
54
|
+
background: rgba(56, 189, 248, 0.12);
|
|
55
|
+
color: #38bdf8;
|
|
56
|
+
font-size: 0.85rem;
|
|
57
|
+
border: 1px solid rgba(56, 189, 248, 0.35);
|
|
58
|
+
backdrop-filter: blur(6px);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
.card {
|
|
63
|
+
background:
|
|
64
|
+
linear-gradient(
|
|
65
|
+
145deg,
|
|
66
|
+
rgba(38, 52, 120, 0.85),
|
|
67
|
+
rgba(15, 23, 42, 0.95)
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
border-radius: 18px;
|
|
71
|
+
padding: 24px;
|
|
72
|
+
margin-bottom: 48px;
|
|
73
|
+
|
|
74
|
+
border: 1px solid rgba(148, 163, 184, 0.18);
|
|
75
|
+
|
|
76
|
+
box-shadow:
|
|
77
|
+
0 20px 45px rgba(0, 0, 0, 0.55),
|
|
78
|
+
0 6px 14px rgba(56, 189, 248, 0.12),
|
|
79
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
.card h2 {
|
|
85
|
+
margin-top: 0;
|
|
86
|
+
font-size: 1.4rem;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
.card button {
|
|
91
|
+
margin-top: 16px;
|
|
92
|
+
padding: 10px 20px;
|
|
93
|
+
font-weight: 600;
|
|
94
|
+
border-radius: 10px;
|
|
95
|
+
border: none;
|
|
96
|
+
cursor: pointer;
|
|
97
|
+
|
|
98
|
+
background: linear-gradient(135deg, #ebcf1a, #ead308);
|
|
99
|
+
color: #020617;
|
|
100
|
+
|
|
101
|
+
box-shadow:
|
|
102
|
+
0 8px 20px rgba(206, 181, 39, 0.45),
|
|
103
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.card button:hover {
|
|
107
|
+
box-shadow:
|
|
108
|
+
0 12px 26px rgba(234, 170, 33, 0.6),
|
|
109
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.7);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.users-section {
|
|
113
|
+
margin-bottom: 48px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.grid {
|
|
117
|
+
display: grid;
|
|
118
|
+
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
|
119
|
+
gap: 20px;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
.user-card {
|
|
124
|
+
background: rgba(2, 6, 23, 0.85);
|
|
125
|
+
border-radius: 14px;
|
|
126
|
+
padding: 18px;
|
|
127
|
+
border: 1px solid rgba(148, 163, 184, 0.12);
|
|
128
|
+
|
|
129
|
+
box-shadow:
|
|
130
|
+
0 10px 24px rgba(0, 0, 0, 0.5),
|
|
131
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
.user-card h3 {
|
|
136
|
+
margin: 0 0 8px;
|
|
137
|
+
font-size: 1.05rem;
|
|
138
|
+
color: #38bdf8;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.user-card p {
|
|
142
|
+
margin: 4px 0;
|
|
143
|
+
font-size: 0.9rem;
|
|
144
|
+
color: #cbd5f5;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.card ul {
|
|
148
|
+
margin-top: 12px;
|
|
149
|
+
padding-left: 18px;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.card li {
|
|
153
|
+
margin: 6px 0;
|
|
154
|
+
color: #cbd5f5;
|
|
155
|
+
}
|
package/index.html
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { h, render } from "./r_lite/core.js";
|
|
2
|
+
import { useState, useEffect } from "./r_lite/hooks.js";
|
|
3
|
+
|
|
4
|
+
function App() {
|
|
5
|
+
const [count, setCount] = useState(0);
|
|
6
|
+
const [users, setUsers] = useState([]);
|
|
7
|
+
|
|
8
|
+
// API CALL
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
fetch("https://jsonplaceholder.typicode.com/users")
|
|
11
|
+
.then(res => res.json())
|
|
12
|
+
.then(data => {
|
|
13
|
+
setUsers(data);
|
|
14
|
+
});
|
|
15
|
+
}, []);
|
|
16
|
+
|
|
17
|
+
return h(
|
|
18
|
+
"div",
|
|
19
|
+
{ className: "app-container" },
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
h(
|
|
23
|
+
"header",
|
|
24
|
+
{ className: "header" },
|
|
25
|
+
h("h1", null, "r_lite"),
|
|
26
|
+
h(
|
|
27
|
+
"p",
|
|
28
|
+
{ className: "tagline" },
|
|
29
|
+
"A fast, lightweight UI library designed for micro-frontend architectures"
|
|
30
|
+
),
|
|
31
|
+
h(
|
|
32
|
+
"div",
|
|
33
|
+
{ className: "badges" },
|
|
34
|
+
h("span", null, "⚡ Fast"),
|
|
35
|
+
h("span", null, "📦 Lightweight"),
|
|
36
|
+
h("span", null, "🧩 Micro-Frontend Ready"),
|
|
37
|
+
h("span", null, "🧠 Hooks Based")
|
|
38
|
+
)
|
|
39
|
+
),
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
h(
|
|
43
|
+
"section",
|
|
44
|
+
{ className: "card" },
|
|
45
|
+
h("h2", null, "Counter Demo"),
|
|
46
|
+
h("p", null, `Current Count: ${count}`),
|
|
47
|
+
h(
|
|
48
|
+
"button",
|
|
49
|
+
{ onclick: () => setCount(c => c + 1) },
|
|
50
|
+
"Increment"
|
|
51
|
+
)
|
|
52
|
+
),
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
h(
|
|
56
|
+
"section",
|
|
57
|
+
{ className: "users-section" },
|
|
58
|
+
h("h2", null, "Users (API Data)"),
|
|
59
|
+
|
|
60
|
+
h(
|
|
61
|
+
"div",
|
|
62
|
+
{ className: "grid" },
|
|
63
|
+
|
|
64
|
+
...users.map(user =>
|
|
65
|
+
h(
|
|
66
|
+
"div",
|
|
67
|
+
{ className: "user-card", key: user.id },
|
|
68
|
+
|
|
69
|
+
h("h3", null, user.name),
|
|
70
|
+
h("p", null, `📧 ${user.email}`),
|
|
71
|
+
h("p", null, `🏙 ${user.address.city}`),
|
|
72
|
+
h("p", null, `📞 ${user.phone}`)
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
),
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
render(App, document.getElementById("root"));
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@arundeep_bhardwaj/r-lite",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "A lightweight UI library for micro-frontend architectures",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"ui",
|
|
9
|
+
"react",
|
|
10
|
+
"hooks",
|
|
11
|
+
"micro-frontend",
|
|
12
|
+
"frontend",
|
|
13
|
+
"framework",
|
|
14
|
+
"lightweight"
|
|
15
|
+
],
|
|
16
|
+
"author": "Arundeep Bhardwaj",
|
|
17
|
+
"license": "MIT"
|
|
18
|
+
}
|
package/r_lite/core.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { resetHooks, runEffects } from "./hooks.js";
|
|
2
|
+
|
|
3
|
+
let RootComponent = null;
|
|
4
|
+
let RootElement = null;
|
|
5
|
+
|
|
6
|
+
export function h(type, props = {}, ...children) {
|
|
7
|
+
return { type, props, children };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function createDom(vnode) {
|
|
11
|
+
if (typeof vnode === "string" || typeof vnode === "number") {
|
|
12
|
+
return document.createTextNode(vnode);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (typeof vnode.type === "function") {
|
|
16
|
+
return createDom(vnode.type(vnode.props));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const el = document.createElement(vnode.type);
|
|
20
|
+
|
|
21
|
+
Object.entries(vnode.props || {}).forEach(([key, value]) => {
|
|
22
|
+
el[key] = value;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
vnode.children.forEach(child => {
|
|
26
|
+
el.appendChild(createDom(child));
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return el;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function render(App, container) {
|
|
33
|
+
RootComponent = App;
|
|
34
|
+
RootElement = container;
|
|
35
|
+
|
|
36
|
+
resetHooks();
|
|
37
|
+
container.innerHTML = "";
|
|
38
|
+
container.appendChild(createDom(App()));
|
|
39
|
+
|
|
40
|
+
runEffects();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function rerender() {
|
|
44
|
+
render(RootComponent, RootElement);
|
|
45
|
+
}
|
package/r_lite/hooks.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { rerender } from "./core.js";
|
|
2
|
+
|
|
3
|
+
let hooks = [];
|
|
4
|
+
let effects = [];
|
|
5
|
+
let index = 0;
|
|
6
|
+
|
|
7
|
+
export function resetHooks() {
|
|
8
|
+
index = 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function useState(initialValue) {
|
|
12
|
+
const i = index;
|
|
13
|
+
|
|
14
|
+
hooks[i] = hooks[i] ?? initialValue;
|
|
15
|
+
|
|
16
|
+
const setState = value => {
|
|
17
|
+
hooks[i] =
|
|
18
|
+
typeof value === "function" ? value(hooks[i]) : value;
|
|
19
|
+
|
|
20
|
+
rerender();
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
index++;
|
|
24
|
+
return [hooks[i], setState];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function useEffect(callback, deps) {
|
|
28
|
+
const i = index;
|
|
29
|
+
const oldDeps = hooks[i];
|
|
30
|
+
|
|
31
|
+
let hasChanged = true;
|
|
32
|
+
|
|
33
|
+
if (oldDeps) {
|
|
34
|
+
hasChanged = deps
|
|
35
|
+
? !deps.every((dep, j) => dep === oldDeps[j])
|
|
36
|
+
: true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (hasChanged) {
|
|
40
|
+
effects.push(() => callback());
|
|
41
|
+
hooks[i] = deps;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
index++;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
export function runEffects() {
|
|
49
|
+
effects.forEach(effect => effect());
|
|
50
|
+
effects = [];
|
|
51
|
+
}
|