htmv 0.0.44 → 0.0.46
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 +49 -0
- package/dist/cli/commands/new.js +6 -0
- package/dist/compiler/parser.js +8 -6
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -108,6 +108,55 @@ However, note that if you have changed the name of your folders HTMV will be una
|
|
|
108
108
|
bunx htmv@latest gen view MyCoolView --path cool_stuff/my_custom_views_folder
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
# Interpolation
|
|
112
|
+
As mentioned briefly at the start of the docs. One of HTMV's main features is interpolation.
|
|
113
|
+
|
|
114
|
+
What's that? Put simply, have a value on the backend you wish to show when rendering the view? Just use interpolation!
|
|
115
|
+
|
|
116
|
+
Here's a simple example which lets you randomly show different strings on page load:
|
|
117
|
+
```ts
|
|
118
|
+
// index.ts route
|
|
119
|
+
import { view } from 'htmv'
|
|
120
|
+
|
|
121
|
+
export default () => {
|
|
122
|
+
const messages = ["Welcome back!", "How was your day?", "We're glad you're back."]
|
|
123
|
+
|
|
124
|
+
return view('example', {
|
|
125
|
+
message: getRandomValue(messages) // the message variable will get sent to the view for you to use freely.
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function getRandomValue(arr: Array) {
|
|
130
|
+
return arr[Math.floor(Math.random() * arr.length)]
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
```html
|
|
134
|
+
<!-- example.html view -->
|
|
135
|
+
<p>{message}</p> <!-- here we are accessing the message variable -->
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
# Attribute binding
|
|
139
|
+
Although being able to interpolate values is nice, sometimes you need *just a bit* more than that.
|
|
140
|
+
|
|
141
|
+
For example, let's say you have a task you wish to show if it's done or not:
|
|
142
|
+
|
|
143
|
+
The first step would be to pass the `{task.done}` value to the view.
|
|
144
|
+
|
|
145
|
+
After that, you should have an `<input type="checkbox">` element inside your view.
|
|
146
|
+
|
|
147
|
+
Next to that, one would think *"I'll just add a checked={task.done} attribute to it!"*
|
|
148
|
+
|
|
149
|
+
Like so: `<input type="checkbox" checked={task.done}>`
|
|
150
|
+
|
|
151
|
+
However, on opening your web page you'll realize the input is always checked. No matter whether `task.done` is truthy or not. This is because for attributes like `checked`, HTML doesn't care if the value for the attribute is truthy or not. It only checks if the attribute is present or not. Therefore, it is impossible to solve this with simple interpolation.
|
|
152
|
+
|
|
153
|
+
For this, you'll need attribute binding. And HTMV has got your back! Simply add a `:` before the attribute. That's it!
|
|
154
|
+
|
|
155
|
+
`<input type="checkbox" :checked={task.done}>`
|
|
156
|
+
|
|
157
|
+
This tells HTMV's compiler: *"Don't add the attribute AND value, just add the attribute alone IF the value is truthy!"*
|
|
158
|
+
|
|
159
|
+
|
|
111
160
|
# Hot reloading
|
|
112
161
|
Having to restart the server every time you make a change can be quite tedious. HTMV takes care of this thanks to Bun. Just develop with `bun dev` and it should work out of the box! Note that this does not include hot reloading in the browser. As of now, you have to refresh the page to see new changes. It doesn't update in real time.
|
|
113
162
|
|
package/dist/cli/commands/new.js
CHANGED
|
@@ -65,6 +65,12 @@ export default async (_params: RouteParams) => {
|
|
|
65
65
|
await runCommand(`npm pkg set scripts.start="bun index.ts"`, {
|
|
66
66
|
cwd: fullPath,
|
|
67
67
|
});
|
|
68
|
+
console.log("6. Rewriting tsconfig.json...");
|
|
69
|
+
const tsconfig = await fs.readFile(path.join(fullPath, "tsconfig.json"), "utf-8");
|
|
70
|
+
let tsconfigWithoutStartingBracket = tsconfig.split("\n").slice(1).join("\n");
|
|
71
|
+
tsconfigWithoutStartingBracket = `{
|
|
72
|
+
"exclude": ["public"],
|
|
73
|
+
${tsconfigWithoutStartingBracket}`;
|
|
68
74
|
console.log(`All done! Project ${name} created.`);
|
|
69
75
|
console.log(`Now run cd ${name} and start building your next big project!`);
|
|
70
76
|
};
|
package/dist/compiler/parser.js
CHANGED
|
@@ -79,12 +79,14 @@ export function parse(tokens) {
|
|
|
79
79
|
text: `<${tag} `,
|
|
80
80
|
});
|
|
81
81
|
let nextToken = tokens[i];
|
|
82
|
-
while (nextToken?.type === "arguments"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
while (nextToken?.type === "arguments" ||
|
|
83
|
+
nextToken?.type === "attr-binding") {
|
|
84
|
+
if (nextToken.type === "arguments") {
|
|
85
|
+
parseArgs(nextToken.value);
|
|
86
|
+
i++;
|
|
87
|
+
nextToken = tokens[i];
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
88
90
|
nodes.push({
|
|
89
91
|
type: "attr-binding",
|
|
90
92
|
name: nextToken.name,
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "htmv",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.46",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"@biomejs/biome": "2.3.3",
|
|
8
8
|
"@types/bun": "latest"
|
|
@@ -21,7 +21,11 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "tsc",
|
|
23
23
|
"lint": "biome check",
|
|
24
|
-
"prepublishOnly": "
|
|
24
|
+
"prepublishOnly": "bun run build",
|
|
25
|
+
"test": "bun test",
|
|
26
|
+
"test:gen:tokenizer": "bun run src/compiler/tests/tokenizer/gen.ts",
|
|
27
|
+
"test:gen:renderer": "bun run src/compiler/tests/renderer/gen.ts",
|
|
28
|
+
"test:gen:parser": "bun run src/compiler/tests/parser/gen.ts"
|
|
25
29
|
},
|
|
26
30
|
"repository": {
|
|
27
31
|
"type": "git",
|