Hype Reactive Content

The intention of this project is to provide a way to bind the content of an element to a variable using data-content, as well as set the value of a variable by assigning a value to a key in the customData object. Additionally, you can bind the visibility of an element to a variable by adding the data-visibility attribute to the element and setting it to a condition. Reactivity is the concept of a value being automatically updated when its dependencies change. In the context of this project, a visibility and content is automatically updated when the variable it is bound to is updated.

I used some of this concepts in an older and more complex extension, Hype Data Magic, but this extension, is a more bare-bones version of it and should do the trick for many setups. It lacks a live preview for that matter.


HypeReactiveContent-example.hype.zip (200,4 KB)


Installation

Visit the the repo on GitHub and copy the the JsDeliver code.

Alternatively, you can download the code. Then just add the minified version to your project by selecting the file and dragging it into the resources section of your project.

Include the file in your document and make sure that "Include in HTML" checkbox is checked in the resource Inspector (it is usually enabled by default). Alternatively, you can also add it via a script tag in the HTML head of your project by yourself:

<script src="${resourcesFolderName}/HypeReactiveContent.min.js"></script>

In that case, uncheck the "Include in HTML" checkbox.

Binding using the additional attributes panel

You can bind the content of an element to a variable by adding the data-content attribute to the element and setting it to the name of the variable.

For example, if you have a variable named hello you can bind the content of an element to it by adding the data-content attribute to the element and setting it to hello:

key value
data-content hello

Binding using defining data-content on element in innerHTML

You can bind the content of an element to a variable by adding the data-content attribute to the element and setting it to the name of the variable.

For example, if you have a variable named hello you can bind the content of an element to it by adding the data-content attribute to the element and setting it to hello:

<div data-content="hello">This element's content will be set to the value of the hello variable.</div>

Setting data is as easy as assigning something to hypeDocument.customData

You can set the value of a variable by assigning a value to it in the customData object.

For example, if you have a variable named hello you can set its value by assigning a value to it in the customData object:

hypeDocument.customData.hello = "world";

Setting data using Trigger Custom Behavior

You can set the value of a variable by assigning a value to it in the actions panel, timeline actions or scene/symbol actions.

For example, if you have a variable named hello you can set its value by assigning a value to it in the the Trigger Custom Behavior field:

hello = "world"

As you can see, in that case there is no hypeDocument.customData precursor necessary as these calls are already scoped to this data branch. You can use the precursor if you like, but I thought it would be more efficient with the scoping to reduce the amount of code in those small fields. Another benefit… it's easier to read.

Using data-visibility to show and hide elements

You can bind the visibility of an element to a variable by adding the data-visibility attribute to the element and setting it to a condition. If the condition returns true the element will be visible and if the return value is false it will be hidden.

key value
data-visibility hello == "world"

Listening to assignment patterns to trigger actions

In Hype, you can listen to custom behavior. If you listen to a condition string, it gets triggered. Hence, in scenes or symbols, you can set up a listener like hello == "world" and trigger actions. Beware that this is only a listener. This isn't really evaluated, but rather when a value is being set the string is being constructed in this case. Hence, you can only use double quotes and need to make sure to match the expected string. Some example string would be:

  • hello equals "world" for listening for hello being set to the string world
  • hello equals true for listening for hello being set to the boolean true
  • hello equals 2 for listening for hello being set to the number 2

You can also listen to general updates:

  • hello was updated for listening to any updates made on hello
7 Likes

↑ look at project
1.0.4 Fixed falsy values not being updated

More advanced use-cases

Using Trigger Custom Behavior to increment a variable

Make sure to either initialize it in HypeReactiveContent() (Hype function called at Hype Document Load) or set it on Scene Load, either using Trigger Custom Behavior or a Hype function to an initial value. After that, you are free to increase it …

counter += 1

data-content can be an expression and contain math or operations, only make sure there is a value that can be returned

For example, if you have a variable named counter you can do a division by adding the data-content attribute to the element and setting it to counter%2 (modulo):

key value
data-content counter%2

data-visibility can be any conditional test, only thing important is that it returns true or false

For example, if you have a variable named counter you can do a division by adding the data-visibility attribute to the element and setting it to counter%2 == 1 (odd) or counter%2 == 0 (even):

key value
data-visibility counter%2 == 1
key value
data-visibility counter%2 == 0

CleanShot 2022-06-21 at 15.16.41

HypeReactiveContent-example-inc.hype.zip (32,5 KB)

↑ look at project
1.0.5 Added Hype Action Events support running code through triggerAction

This means if you also load/use Hype Action Events in your project, it will run the code execution through triggerAction (with all the usual context benefits) and not fall back to its simple runCode function. This is rather a consolidation and compatibility notice.

↑ look at project
1.0.6 Added Hype Data Magic support, disable with HypeDataMagic.setDefault('refreshOnCustomData', false), Added and exposed HypeReactiveContent.disableReactiveObject, Exposed HypeReactiveContent.enableReactiveObject, Improved runCode running in hypeDocument scope while still accessing customData

This release creates compability with Hype Data Magic and streamlines runCode

1 Like

↑ look at project
1.0.7 Fixed small regression in the runCode enclosure for has probes

Added YouTube videos to the description

1 Like

Using functions to transform and generate dynamic content

example_price.hype.zip (24,8 KB)

You can put your helper function in either

hypeDocument.myFunction = function(){…

or

hypeDocument.customData.myFunction = function(){…

it is up to you… either can be addressed directly as myFunction in the trigger custom behavior context.

6 Likes

How does this extension compare to SolidJS which currently promotes itself as a small, performant and framework-independent way to achieve reactive user interfaces.

There are many (much more) powerful solutions out there. Starting with React and VUE, and some do need a build pipeline. Then there is AlpineJS or PetiteVue, that can be used in any project if you are knowledgeable enough to integrate them.

The goal behind this, although it came together rather spontaneous, was to keep it:

  • Hype integrated right out of the box (just link it or drop it in)
  • small in size (currently 2.5kb)
  • dead simple to use (two data attributes, and listener)
2 Likes

↑ look at project
1.0.8 Visibility changes display none to block if needed, debounced HypeTriggerCustomBehavior, Added compatibility with Hype Global Behavior

↑ look at project
1.0.9 Added isCode and setting a function in customData will not trigger and 'equals' behavior anymore, Added setDefault and getDefault, added customDataUpdate (callback) as default possibility
1.1.0 Added hypeDocument.enableReactiveCustomData and the default customData

Example of combining it with local storage (clear the cache to make sure you're on the latest version)
example_local_storage.hype.zip (43,3 KB)


I was exploring borders and feedback bubbles on the data-content and data-visibility attributes in the IDE. This isn't part of Hype Reactive Code (yet). More a trial on providing feedback that disappears outside the IDE. It adds a little CSS to the project and gives you this:

Update: This is now part of the extension since version 1.1.1

Very cool Max, this would be ideal for those in the retail industry, where manufacturers control map prices and retailers need to adhere to prices unless, there are circumstances when they can tamper with the map price case being, where upon a click of a button the price could change but not for everyone.

It be cool to see if there was a strike though on the main price, and a new price is generated below with a different color via click of a button which could say "click for better price".

Example that shows how you can combine it with Hype Data Magic.

CleanShot 2022-07-04 at 11.43.21

example_combining_reactive_content_with_data_magic.hype.zip (43,1 KB)

4 Likes

Thank you for the videos @MaxZieb. Really helpful.

1 Like

↑ look at project
1.1.1 Fixed null case and added reactive highlighting in IDE, Added data-scope and scope indicator at beginning of expressions with the arrow symbol (⇢), Added the ability to inline the scope in data-content before the arrow symbol (⇢)
1.1.2 Minor cleanups and fixes
1.1.3 Fixed another falsy type bug that forwarded undefined data-scopes to the default scope


I used some spare time to add some features and make it more robust. Also, from now on, there is some feedback in the IDE, but there is also a production version if you want the smaller code without any highlights and feedback in the IDE.

3 Likes

BTW you can change the scope symbol from ⇢ to something else using HypeReactive.setDefault("scopeSymbol", "@") (example changing it to an @-Symbol). Currently only a single character, but with the next release I am thinking to allow multi character scope Symbol indication and change the default to --> or —>. Just to make it more convenient and not rely on symbols not directly on the keyboard. Thoughts and feedback welcome? Has anybody tried using Hype Reactive Content yet? I used it in two projects already.


↑ look at project
1.1.4 Added support for an arbitrary scopeSymbol with arbitrary length, default is still ⇢

After playing around with arrows today. I think the control/command/space option is easy enough to learn. One can even add a shortcut in macOS Settingskeyboardtext to convert ---> into ⇢. So, I am keeping the arrow as it only consumes a single char and not 2-3 chars. But, setting custom chars and multi chars will be included going forward. So, having --> or –> is still an option if you like it more. If you prefer simple ASCII arrows, use either of these:
HypeReactive.setDefault("scopeSymbol", "-->")
HypeReactive.setDefault("scopeSymbol", "–>")

—-

The only annoying thing is that Hype still changes > symbols used in head HTML into &gt; in the Hype IDE so beware of that and put code that contains the symbol in an external JS file. I hope this annoyance gets “fixed” one day.

2 Likes

↑ look at project
1.1.5 Added the _key getter in the proxy to return a simple object string path, This fixes custom behavior notifications for nested keys as a full pseudo key is returned

updating nested.child = "test" will now trigger the custom behaviors

nested.child equals "test"
nested.child was updated

instead of the old

child equals "test"
child was updated

Hence, the full path will be rendered as pseudo notation. Here are some examples of the edge cases when setting arrays indexes and keys with spaces like nested[0]['Hello World'] = "test" would lead to:

nested.0.Hello World equals "test"
nested.0.Hello World was updated

↑ look at project
1.1.6 Added bubble type listener for action and behavior as data-content-changed-action, data-content-changed-behavior, data-visibility-changed-action and data-visibility-changed-behavior. Added $elm and element to code execution even if not used in conjunction with Hype Action Events


In addition to the custom behavior listener approach, you can now listen to content or visibility changes based on setting a data attribute. These attributes are now supported data-content-changed-action, data-content-changed-behavior, data-visibility-changed-action and data-visibility-changed-behavior. The action version run the code if a change is registered on any DOM element below the declaration (hence, bubble type). The same is true for the behavior versions. These new listeners react to DOM changes vs. the already existing behavior listeners that react to data changes.

The other new thing is that code executed now supports $elm or element even without loading Hype Action Events.

1 Like

Amazing work Max!

1 Like

3 posts were split to a new topic: Using Hype Reactive Content to set images

↑ look at project
1.1.8 Updated visibility handling in conjunction with scope in content processing


This commit addresses an issue with the way scope in content and visibility were handled.

Changes made:
Modified the function to handle the "starts with" pattern more accurately.
Updated the data-visibility function to improve visibility handling reflecting the scope of content correctly.

To illustrate what this is about:

  1. data-content is a HTML attribute that is set to ⇢name, where the symbol signifies that the value of this property should be extracted from the current scope. This attribute allows for dynamic content binding, where the value of name will be resolved based on the current scope context.

  2. The data-scope attribute is used to define a scope for elements in HTML. This attribute can be placed on an ancestor element, allowing it to encompass and affect the behavior of nested elements within its scope. It can also be applied to elements "outside" of a symbol or group, providing a broader context for the contained elements.

  3. In a recent commit, an update was made to the data-visibility attribute. This modification was necessary due to a bug that affected the correct resolution of the attribute's value to the intended scope. The bug has been addressed and fixed, ensuring that the data-visibility attribute now functions as intended in resolving its value within the scope it belongs to.

4 Likes