From 486af43209364e433e4cab8de2a6cf3c81ff2a88 Mon Sep 17 00:00:00 2001 From: Stu Cork Date: Wed, 13 Oct 2021 18:40:38 +0800 Subject: [PATCH] Designer Readme: some tweaks and add info about exporting. --- js/designer_components/README.md | 51 ++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/js/designer_components/README.md b/js/designer_components/README.md index 7006deb0..bc0e0e74 100644 --- a/js/designer_components/README.md +++ b/js/designer_components/README.md @@ -3,27 +3,26 @@ ## Intro -So you want to make a Designer Component that updates dynamically in the Desginer? +So you want to make a Designer Component that updates dynamically in the Designer? First - this relies on Javascript. It also plays around with Skulpt. It's not officially supported. It may need updating in the future since it relies on some hackery and implementation details that may change in the future. -BUT it is isolated to the Desiner so if does stop working - the actual python won't be affected. +BUT it is isolated to the Designer, so if it does stop working - the actual Python code won't be affected. ### Notes Your custom component must be an HTMLPanel. We essentially create a Javascript version of our CustomComponent. -Anvil never calls the Python class in the Designer so that's why we need to inject our own Javascript version. -In the Python code we remove the script tags in the `__init__` method so that the Javascript version is never injected. - +Anvil never calls the Python class in the Designer, so that's why we need to inject our Javascript version. +In the Python code, we remove the script tags in the `__init__` method. This way we do not inject the Javascript version into Python. ## Where to start? -Write the python version first! +Write the Python version first! -When you want to create a Designer version look at the comments in `DesignerComponent.ts`. -Anything that is marked as `private` should NOT be overriden. +When you want to create a Designer version, first look at the comments in `DesignerComponent.ts`. +Anything marked as `private` should NOT be overridden. - Does your Python class have injected `css`? - *override the `static css` property* @@ -37,7 +36,7 @@ Anything that is marked as `private` should NOT be overriden. You must override the `init()` method and then call `super.init()` -The custom component html must have a domNode with an identifiable selector. +The custom component HTML must have a domNode with an identifiable selector. e.g. ```html @@ -51,9 +50,9 @@ The first argument to `super.init()` should be the selector to identify your cus } ``` -An optional second argument can be used. Which is a className. This className will be added to the HTMLPanel dom node. -In the Designer world its purpose is to be a flag to prevent instantiating the same domNode multiple times. -But it can be used to add classes to the HTMLPanel you would otherwise have added in your python init method. +An optional second argument can be used, which is a className. This className will be added to the HTMLPanel's domNode. +In the Designer world, its purpose is to be a flag to prevent instantiating the same domNode multiple times. +The second argument can be used to add a class to the HTMLPanel you would otherwise have added in your Python `__init__` method. ```typescript static init() { @@ -69,22 +68,28 @@ After the `init` method is called we call the constructor. There is no need to override the `constructor()` method - but you may want to if you want to add attributes to your `this` argument. The arguments to the `constructor()` will be: - the HTMLPanel's domNode for your custom component. -- the python Component as a Skulpt object. - (A Skulpt object is what your client side Python object looks like in Javacsript) +- the Python Component as a Skulpt object. + (A Skulpt object is what your client-side Python object looks like in Javascript) - the domNode of the element found from the querySelector used in the `init()` method -### `setProp(propName, propVal, props)` +### `setProp(propName, propVal, props)`, `update(props, propName, propVal)` + +You will need to override `setProp` or `update` (but not both). -You will need to override `setProp` or `update` (but not both). It's probably better to override `setProp`. -(`update` was used in the initial versions and `setProp` was later added as a better implementation). -In `setProp` you get the `propName` and the `propVal` as well as all the current `props`. +In `setProp` you get the `propName` and the `propVal`, as well as all the current `props`. These are the raw Javascript values. You can either update the dom directly or work with the Skulpt Python objects. There are some helper methods for common properties like `visible` and working with `color`. -The DesignerChips component is an example that uses `setProp` and works with both Skulpt objects and the dom to update itself when a property changes. +The `DesignerChips` component is an example that uses `setProp` and works with both Skulpt objects and the dom to update itself when a property changes. + +`update` is typically in place of `setProp` when you update your entire component whenever a property changes. +The advantage of `update` is that it is only called once on the first load, whereas `setProp` is called once per prop on the first load. + +## Exporting your Designer class +- To make your class available you need to export it in `js/designer_components/index.ts` ## Bundling the javascript - Install deno @@ -96,7 +101,7 @@ The DesignerChips component is an example that uses `setProp` and works with bot ## Hacking -In each designer component you'll see code like +In each designer component, you'll see code like ```html ``` -You'll need equivalent code in your custom component's html. +You'll need equivalent code in your custom component's HTML. When hacking, there's no need to worry about the deno link. Instead: - bundle the Javascript (see above instructions) - Copy the bundled file into your theme assets. -- Replace the deno url with a relative theme url: `_/theme/bundle.js` +- Replace the deno URL with a relative theme URL: `./_/theme/bundle.js` -Whenever you change the local files re-bundle and repeat. +Whenever you change the local files, re-bundle and repeat.