Drayman is a server-side component framework that allows you to use any available HTML element, web component or custom Drayman third-party component together with server-side code in a single script.
With Drayman, the browser only renders what the user should see - all logic and calculations happen server-side and UI is written using JSX syntax.
The best way to show Drayman capabilities is to create something with it. So let's get started.
File viewer component
Let's build a component that allows the user to select a file from the file system and view it's contents.
First, you need to install Drayman. It can be done by running these commands:
npx @drayman/framework-init@latest my-app
cd my-app
npm start
The website will be available at http://localhost:3033.
If you don't want install anything, you can always try Drayman inside CodeSandbox by visiting new.drayman.io.
Initial component template
Go to src/components/home.tsx
and replace its contents with this code:
export const component: DraymanComponent = async () => {
return async () => {
return (
<>
<p>Select a file to view it directly from file system</p>
<select></select>
<br />
<pre></pre>
</>
);
};
};
You will see an initial skeleton of our component. Further <select>
will be used to show available files and <pre>
will show contents of the selected file.
Filling select with options
Because Drayman runs a component server-side, we can use any Node.js library. In our case we will use the fs
module.
Let's read file names from the project root directory and fill <select>
options with them:
import { promises as fs } from "fs";
export const component: DraymanComponent = async () => {
const files = (await fs.readdir("./")).filter((x) => x.includes("."));
return async () => {
return (
<>
<p>Select a file to view it directly from file system</p>
<select>
{files.map((fileName) => (
<option>{fileName}</option>
))}
</select>
<br />
<pre></pre>
</>
);
};
};
Right now our component is only showing some elements without any interactivity. Our next step will be to add it.
Reacting to user actions
We need to remember which file the user has selected to show its contents. It can be done by using the onchange
event attribute and attaching a function that will be executed server-side. We also need to add the value
attribute to each option
so that select
would know which option was selected.
Let's also add the fs.readFile
function inside the <pre>
tag so that Drayman would read file contents during re-render. We won't show the pre
until a file is actually selected:
import { promises as fs } from "fs";
export const component: DraymanComponent = async () => {
const files = (await fs.readdir("./")).filter((x) => x.includes("."));
let selectedFile;
return async () => {
return (
<>
<p>Select a file to view it directly from file system</p>
<select
onchange={async ({ value }) => {
selectedFile = value;
}}
>
{files.map((fileName) => (
<option value={fileName}>{fileName}</option>
))}
</select>
<br />
{selectedFile && <pre>{await fs.readFile(selectedFile, "utf-8")}</pre>}
</>
);
};
};
If you make a selection from the dropdown, you will see that nothing happens on the page - file contents don't appear. That is because with Drayman you must strictly tell when a component needs to be re-rendered. It can be done by using a special helper function forceUpdate
.
Import it and add to the onchange
event after the selected file was saved:
import { promises as fs } from "fs";
export const component: DraymanComponent = async ({ forceUpdate, }) => {
const files = (await fs.readdir("./")).filter((x) => x.includes("."));
let selectedFile;
return async () => {
return (
<>
<p>Select a file to view it directly from file system</p>
<select
onchange={async ({ value }) => {
selectedFile = value;
await forceUpdate();
}}
>
{files.map((fileName) => (
<option value={fileName}>{fileName}</option>
))}
</select>
<br />
{selectedFile && <pre>{await fs.readFile(selectedFile, "utf-8")}</pre>}
</>
);
};
};
Now our component is complete and file contents are shown on select:
Conclusion
We have built a component that combines server-side logic and client-side view in a single script.
If this felt interesting to you, visit the official docs to deep-dive into Drayman framework!
Top comments (0)