npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@psytech/react-render-engine

v0.0.8

Published

It is a server-driven client-side rendering system built with react which allows to render interfaces using templatised input data made up of individual template layout elements & styles received from the server-side.

Downloads

3

Readme

@psytech/react-render-engine

Server-Driven UI (SDUI) is a technique which allows to render dynamic user interfaces for the web & native apps using structured data received from the server which describes different parts of the user interface & the data contained inside it. In this case, we call this structured data, a "template".

Here's a good explanation of SDUI: https://www.judo.app/blog/server-driven-ui/

This package allows the rendering of templates using React with structured template data received from the server.

Here are some of the examples of cards that have been rendered using this package which you can access using this demo link, while the structured template data for rendering these cards can be accessed using this link: Template examples

Table of contents

Structure

Each template consists of the following key-value pairs:

  1. id: A unique identification string for recognising the template.

  2. topElementId: A unique identification string for recognising the topmost node element whose element data is stored in the element object.

  3. element: An object storing the template elements in the form of key-value pair, template_element_id: template_element_object.

  4. text: An object containing the textual style objects in the form of key-value pair, text_style_id: text_style_object, where each text_style_object stores the textual styles (e.g. font-weight, font-style, text-decoration) which will be used for styling the individual layout elements.

  5. design: An object containing non-textual style objects in the form of key-value pair, design_style_id: design_style_object, where each design_style_object stores the non-textual styles (e.g. height, width, background, color) which will be used by individual layout elements.

Each template will have the following form:

{
	id: <STRING>"UID",
	topElementId: <STRING>"UID",
	element: <OBJECT>{...},
	design: <OBJECT>{...},
	text: <OBJECT>{...}
}

An example of the design style object is:

{
	background: "#fc6a03"
	color: "#fff"
	height: "fit-content"
	id: "3d87f501-3941-474e-8ce2-5489faf99ba2"
	margin:	"0px"
	padding: "5px"
	width: "fit-content"
}

An example of the text style object is:

{
  "id": "d0f71ec4-095b-485a-b145-ac242defa74b",
  "fontFamily": "'Merriweather', serif",
  "fontWeight": "400",
  "fontStyle": "normal",
  "textAlign": "left",
  "textDecoration": "none"
}

NOTE: The obvious question here would be, why aren't we storing all the styles in a single style object instead of separating the styles for a single layout element into text & design properties, despite the fact that during the execution, these styles are eventually merged into a single object that is being passed to the style prop of the respective components?

The answer lies with the process of automating user interface styles, where any user interface can be generated by a combination of textual & non-textual properties which can be stored separately. Here's an example of the three cards with varying text & design properties from the demo link:

Combination of design x text styles

Each template element consists of the following the following key-value pairs or properties:

Structural properties

  1. id: It describes a unique identification string to recognise the layout element.

  2. type: It describes the type of layout element. For now, we only have three layout element types: container, text & image & this can be used to render any almost any static content.

    The reason this property has been used is that, in the end, each layout element has to be rendered or expressed in form of HTML tags (or JSX in case of react) & different tags have different relevant attributes. e.g. src attribute is relevant to an image tag, but it is not relevant to a div tag, similarly, href attribute is relevant to an anchor tag, but it is not relevant to an img tag.

  3. parent: It describes the unique identification string of the parent layout element. It can have two possible values, null or string of a valid parent node or element. This is required because every HTML document has a tree structure, where there’s a parent tag & each parent tag can have 0 to N child elements, but each HTML tag (except for <html>) only has one parent tag.

  4. children: It is a array of strings that describes the unique identification string of the child elements of any given layout element. If it is an empty array, then it means that a layout element has no child elements, or simply, “It is an empty tag”, which is the case with <img> tag.

Non-structural properties:

  1. text: It describes a unique identification string for the text style objects that contains textual styling properties such as font-size, font-weight, font-style, text-decoration etc.

    Using this string, the rendering script searches for the text style object present in the post data & once the required text style is found using the provided identification string, then it is added to an object which is assigned to a layout element’s style attributes.

  2. design: It describes a unique identification string for design style objects that contains non-textual styling properties such as color, margin, padding, border, etc. The above process for adding text style objects is also used for adding design style objects to a card’s elements.

  3. properties: It is a array of strings that describes the classes &/or the attributes of a layout element. Since both attributes & classes are described in the same way, the rendering script differentiates the class name & the attribute name-value pair is quite simple: the attribute name-value pairs are expressed as a string in the form attrName=attrValue, whereas class names are just plain text e.g. p1, h2.

So, each template element will have the following form:

{
	type: <STRING>"text"/<STRING>"container"/<STRING>"image"
	id: <STRING>"element_id",
	parent: <STRING>"parent_id"/null,
	children: <ARRAY>["child_id_1", ... , "child_id_n"],
	text: <STRING>"text_style_id",
	design: <STRING>"design_style_id",
	properties: <STRING>["class","attrName=attrVal"]
}

Styles

The package also comes with some styles such as:

  • m-card: To be used with a container with a height of 58vh & aspect ratio of 0.75.
  • m-rh-{5-100}: Defines relative height with respect to card with +5% increment.
  • m-rw-{5-100}: Defines relative width with respect to card with +5% increment.

Example

To underst& how this package works, let's look at this card structure & how it can be rendered using this package: Card DOM structure

The above card structure consists of 4 template elements & for simplicity we're not going to use any custom design & text style properties, rather we're using Bootstrap 5 classes:

A container template element containing other template elements of the card:

{
	id: "1",
	type: "container"
	design: "",
	text: "",
	parent: null,
	children: ["2","3","4"],
	properties: ["m-card","d-flex","flex-column","border"]
}

An image element contained in the above container element:

{
	id: "2",
	type: "image"
	design: "",
	text: "",
	parent: "1",
	children: [],
	properties: ["m-rh-40","m-rw-100","src=https://sm.mashable.com/mashable_sea/photo/default/man-fakes-death-cat-q6u_2z9w.png"]
}

An text element for heading contained in the above container element:

{
	id: "3",
	type: "text"
	design: "",
	text: "",
	parent: "1",
	children: ["Lorem ipsum dolor sit amet, consectetur"],
	properties: ["m-rh-90","h3"]
}

An text element for paragraph contained in the above container element:

{
	id: "4",
	type: "text"
	design: "",
	text: "",
	parent: "1",
	children: ["Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam mollis, mi sit amet lobortis iaculis, velit leo ultrices ipsum, vitae lobortis dui nibh vitae lacus. In commodo lacus a magna dapibus dignissim."],
	properties: ["m-rh-90","small"]
}

The above-mentioned layout elements will can be used to create template which will be rendered in the above form:

{
	id: 0,
	topElementId: 1,
	design: {},
	text: {},
	element: {
		1: {
			id: "1",
			type: "container"
			design: "",
			text: "",
			parent: null,
			children: ["2","3","4"],
			properties: ["m-card","d-flex","flex-column","border"]
		},
		2: {
			id: "2",
			type: "image"
			design: "",
			text: "",
			parent: "1",
			children: [],
			properties: ["m-rh-40","m-rw-100","src=https://sm.mashable.com/mashable_sea/photo/default/man-fakes-death-cat-q6u_2z9w.png"]
		},
		3: {
			id: "3",
			type: "text"
			design: "",
			text: "",
			parent: "1",
			children: ["Lorem ipsum dolor sit amet, consectetur"],
			properties: ["m-rh-90","h3"]
		},
		4: {
  			id: "4",
			type: "text"
  			design: "",
  			text: "",
			parent: "1",
			children: ["Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam mollis, mi sit amet lobortis iaculis, velit leo ultrices ipsum, vitae lobortis dui nibh vitae lacus. In commodo lacus a magna dapibus dignissim."],
			properties: ["m-rh-90","small"]
  		}
	}
}

Usage

The components can be imported and used using:

import {Container, Image, Text} from "@psytech/react-render-engine";
<Container id={id} template={template} inputStyle={inputStyle} />
<Image id={id} template={template} inputStyle={inputStyle} />
<Text id={id} template={template} inputStyle={inputStyle} />

Where id is the identification string of the template layout element which needs to be rendered, template is the structured template data which will be used to render the user interface & inputStyle is a style object which will be passed to all the child elements from a given node.

License

MIT

Credits

The template element structure was inspired by Notion's data model. Built from 🇮🇳, for the 🌐, by psytech.ai. For questions or suggestions drop us a mail at asxyzp-@-psytech-dot-ai.