Socket
Socket
Sign inDemoInstall

@desk-framework/frame-test

Package Overview
Dependencies
2
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.0.0-dev.18 to 4.0.0-dev.19

2

dist/app/TestContext.js

@@ -57,4 +57,4 @@ import { ConfigOptions, app, } from "@desk-framework/frame-core";

// create test renderer
app.theme = new TestTheme();
app.renderer = new TestRenderer(options);
app.theme = new TestTheme();
// create no-op viewport context

@@ -61,0 +61,0 @@ app.viewport = new TestViewportContext();

@@ -14,20 +14,20 @@ import { UIButton, UICell, UIContainer, UIImage, UILabel, UISeparator, UISpacer, UITextField, UIToggle, } from "@desk-framework/frame-core";

return (target instanceof UICell
? new UICellRenderer()
? new UICellRenderer(target)
: target instanceof UIContainer
? new UIContainerRenderer()
? new UIContainerRenderer(target)
: target instanceof UILabel
? new UILabelRenderer()
? new UILabelRenderer(target)
: target instanceof UIButton
? new UIButtonRenderer()
? new UIButtonRenderer(target)
: target instanceof UIImage
? new UIImageRenderer()
? new UIImageRenderer(target)
: target instanceof UISeparator
? new UISeparatorRenderer()
? new UISeparatorRenderer(target)
: target instanceof UISpacer
? new UISpacerRenderer()
? new UISpacerRenderer(target)
: target instanceof UITextField
? new UITextFieldRenderer()
? new UITextFieldRenderer(target)
: target instanceof UIToggle
? new UIToggleRenderer()
? new UIToggleRenderer(target)
: undefined);
}

@@ -1,2 +0,2 @@

import { ManagedEvent, Observer, UIStyle, app, } from "@desk-framework/frame-core";
import { ManagedEvent, ManagedObject, UIStyle, app, } from "@desk-framework/frame-core";
/** UI component event names that are used for basic platform events */

@@ -70,36 +70,38 @@ const _eventNames = {

}
/** @internal Abstract observer class for all `UIComponent` instances, to create output and call render callback; implemented for all types of UI components */
export class TestBaseObserver extends Observer {
observe(observed) {
/** @internal Abstract observer class for all `UIComponent` instances, to create output and call render callback; implemented for all types of UI components, created upon rendering, and attached to enable property bindings */
export class TestBaseObserver {
observed;
constructor(observed) {
this.observed = observed;
this._thisRenderedEvent = new ManagedEvent("Rendered", observed, undefined, undefined, undefined, true);
return super.observe(observed).observePropertyAsync("hidden", "position");
this.observeProperties("hidden", "position");
observed.listen((e) => {
let handler = this["on" + e.name];
if (typeof handler === "function")
handler.call(this, e);
});
}
_thisRenderedEvent;
/** Set up one or more property listeners, to call {@link propertyChange} on this observer */
observeProperties(...properties) {
ManagedObject.observe(this.observed, properties, (_, p, v) => this.propertyChange(p, v));
}
/** Handler for base property changes; must be overridden to handle other UI component properties */
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "hidden":
this._hidden = this.observed.hidden;
if (!this._hidden)
this.updateStyle(this.element);
if (this.updateCallback) {
this.updateCallback = this.updateCallback.call(undefined, this._hidden ? undefined : this.output);
}
return;
case "position":
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "hidden":
this.scheduleHide(value);
return;
case "position":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
}
/** Rendered element, if any; set by `onRender` handler based on return value of `getOutput()` method */
element;
/** Rendered output, if any; set by `onRender` handler based on return value of `getOutput()` method */
output;
/** Rendered element, if any; set by `onRender` handler based on return value of `getOutput()` method */
element;
/** Updates the specified output element with all properties of the UI component; called automatically before rendering (after `getOutput`), but can also be called when state properties change */
update(element) {
if (!this.observed)
return;
this._hidden = this.observed.hidden;

@@ -123,2 +125,4 @@ this._asyncContentUp = undefined;

app.renderer.schedule(() => {
if (this.observed.isUnlinked())
return;
this._asyncUp = false;

@@ -138,2 +142,16 @@ if (this._asyncContentUp)

_asyncStyleUp;
/** Schedules an asynchronous update to show or hide the output */
scheduleHide(hidden) {
app.renderer?.schedule(() => {
let elt = this.element;
if (!elt)
return;
this._hidden = hidden;
if (!hidden)
this.updateStyle(elt);
if (this._updateCallback) {
this._updateCallback = this._updateCallback.call(undefined, hidden ? undefined : this.output);
}
});
}
_hidden;

@@ -143,3 +161,3 @@ /** Handles platform events, invoked in response to `element.sendPlatformEvent()` */

let baseEvent = _eventNames[name];
if (baseEvent && this.observed && !this.observed.isUnlinked()) {
if (baseEvent && !this.observed.isUnlinked()) {
let event = new ManagedEvent(baseEvent, this.observed, data, undefined, undefined, baseEvent === "MouseEnter" || baseEvent === "MouseLeave");

@@ -166,3 +184,5 @@ this.observed.emit(event);

// call render callback with new element
this.updateCallback = event.data.render.call(undefined, this._hidden ? undefined : this.output, () => {
this._updateCallback = event.data.render.call(undefined, this._hidden ? undefined : this.output, () => {
if (this.observed.isUnlinked())
return;
// try to focus if requested

@@ -174,9 +194,6 @@ if (this._requestedFocus && this.element && !this._hidden) {

// emit Rendered event
if (this.observed && !this.observed.isUnlinked()) {
this.observed.emit(this._thisRenderedEvent);
}
this.observed.emit(this._thisRenderedEvent);
});
}
}
updateCallback;
/** Focus current element if possible */

@@ -222,2 +239,4 @@ onRequestFocus(event) {

}
_updateCallback;
_thisRenderedEvent;
}

@@ -1,2 +0,2 @@

import { Observer, RenderContext, View } from "@desk-framework/frame-core";
import { RenderContext, View } from "@desk-framework/frame-core";
import { OutputAssertion, OutputSelectFilter } from "../app/OutputAssertion.js";

@@ -51,3 +51,3 @@ import type { TestContextOptions } from "../app/TestContext.js";

/** Attaches a renderer to the the provided UI component (called internally) */
createObserver<T extends View>(target: T): Observer<T> | undefined;
createObserver(target: View): unknown;
/**

@@ -54,0 +54,0 @@ * Clears all existing output

@@ -1,2 +0,2 @@

import { RenderContext, ui, } from "@desk-framework/frame-core";
import { RenderContext, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -6,24 +6,23 @@ import { TestBaseObserver, applyElementStyle, getBaseStyleClass, } from "./TestBaseObserver.js";

export class UIButtonRenderer extends TestBaseObserver {
observe(observed) {
return super
.observe(observed)
.observePropertyAsync("label", "icon", "chevron", "disabled", "width", "pressed", "style");
constructor(observed) {
super(observed);
this.observeProperties("label", "icon", "chevron", "disabled", "width", "pressed", "style");
}
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "label":
case "icon":
case "chevron":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "pressed":
case "width":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "label":
case "icon":
case "chevron":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "pressed":
case "width":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}

@@ -41,4 +40,2 @@ handlePlatformEvent(name, data) {

getOutput() {
if (!this.observed)
throw ReferenceError();
let elt = new TestOutputElement("button");

@@ -51,27 +48,24 @@ let output = new RenderContext.Output(this.observed, elt);

updateStyle(element) {
// set state
let button = this.observed;
if (button) {
// set state
element.disabled = button.disabled;
element.pressed = button.pressed;
// set styles
element.styleClass =
getBaseStyleClass(button.style) ||
(button.primary ? ui.style.BUTTON_PRIMARY : ui.style.BUTTON);
applyElementStyle(element, [
button.style,
button.width !== undefined
? { width: button.width, minWidth: 0 }
: undefined,
], button.position);
}
element.disabled = !!button.disabled;
element.pressed = !!button.pressed;
// set styles
element.styleClass =
getBaseStyleClass(button.style) ||
(button.primary ? ui.style.BUTTON_PRIMARY : ui.style.BUTTON);
applyElementStyle(element, [
button.style,
button.width !== undefined
? { width: button.width, minWidth: 0 }
: undefined,
], button.position);
}
updateContent(element) {
if (!this.observed)
return;
element.text = String(this.observed.label || "");
element.icon = String(this.observed.icon || "");
element.chevron = String(this.observed.chevron || "");
let button = this.observed;
element.text = String(button.label || "");
element.icon = String(button.icon || "");
element.chevron = String(button.chevron || "");
element.focusable = true;
}
}

@@ -6,26 +6,25 @@ import { ui } from "@desk-framework/frame-core";

export class UICellRenderer extends UIContainerRenderer {
observe(observed) {
return super.observe(observed).observePropertyAsync(
constructor(observed) {
super(observed);
this.observeProperties(
// note some properties are handled by container (e.g. padding)
"textDirection", "margin", "borderRadius", "background", "textColor", "opacity", "style");
}
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "textDirection":
case "margin":
case "borderRadius":
case "background":
case "textColor":
case "opacity":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "textDirection":
case "margin":
case "borderRadius":
case "background":
case "textColor":
case "opacity":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed)
throw ReferenceError();
let output = super.getOutput();

@@ -38,4 +37,2 @@ if (this.observed.allowFocus || this.observed.allowKeyboardFocus)

let cell = this.observed;
if (!cell)
return;
super.updateContent(element);

@@ -47,4 +44,2 @@ if (cell.allowFocus || cell.allowKeyboardFocus)

let cell = this.observed;
if (!cell)
return;
// NOTE: margin, textDirection aren't applied in test renderer

@@ -51,0 +46,0 @@ super.updateStyle(element, getBaseStyleClass(cell.style) || ui.style.CELL, [

@@ -6,38 +6,41 @@ import { RenderContext, UICell, UIColumn, UIRow, UIScrollContainer, app, } from "@desk-framework/frame-core";

export class UIContainerRenderer extends TestBaseObserver {
observe(observed) {
let result = super
.observe(observed)
.observePropertyAsync("content", "layout", "padding");
constructor(observed) {
super(observed);
this.observeProperties("layout", "padding");
if (observed instanceof UIRow) {
result.observePropertyAsync("height", "align");
this.observeProperties("height", "align");
}
if (observed instanceof UIColumn) {
result.observePropertyAsync("width", "align");
this.observeProperties("width", "align");
}
return result;
// observe content changes
observed.content.listen((e) => {
if (this.element && e.source === observed.content) {
this.scheduleUpdate(this.element);
}
});
// observe unlink, to stop content updater right away
observed.listen({
unlinked: () => {
if (this.contentUpdater)
this.contentUpdater.stop();
this.contentUpdater = undefined;
},
});
}
handleUnlink() {
if (this.contentUpdater)
this.contentUpdater.stop();
this.contentUpdater = undefined;
super.handleUnlink();
}
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "content":
this.scheduleUpdate(this.element);
return;
case "layout":
case "padding":
case "align": // for rows and columns
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "layout":
case "padding":
case "align": // for rows and columns
case "height": // for rows
case "width": // for columns
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed)
throw ReferenceError();
let type;

@@ -70,4 +73,2 @@ if (this.observed.accessibleRole === "form")

let container = this.observed;
if (!container)
return;
if (!this.contentUpdater) {

@@ -83,23 +84,21 @@ this.contentUpdater = new ContentUpdater(container, element).setAsyncRendering(container.asyncContentRendering);

let container = this.observed;
if (container) {
let layout = container.layout;
if (container instanceof UIRow) {
styles = [{ height: container.height, padding: container.padding }];
if (container.align) {
layout = { ...layout, distribution: container.align };
}
let layout = container.layout;
if (container instanceof UIRow) {
styles = [{ height: container.height, padding: container.padding }];
if (container.align) {
layout = { ...layout, distribution: container.align };
}
else if (container instanceof UIColumn) {
styles = [{ width: container.width, padding: container.padding }];
if (container.align) {
layout = { ...layout, gravity: container.align };
}
}
else if (container instanceof UIColumn) {
styles = [{ width: container.width, padding: container.padding }];
if (container.align) {
layout = { ...layout, gravity: container.align };
}
else if (container instanceof UIScrollContainer) {
styles = [{ padding: container.padding }];
}
// apply styles
element.styleClass = BaseStyle;
applyElementStyle(element, styles, container.position, layout);
}
else if (container instanceof UIScrollContainer) {
styles = [{ padding: container.padding }];
}
// apply styles
element.styleClass = BaseStyle;
applyElementStyle(element, styles, container.position, layout);
}

@@ -106,0 +105,0 @@ }

@@ -1,2 +0,2 @@

import { RenderContext, ui, } from "@desk-framework/frame-core";
import { RenderContext, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -6,21 +6,20 @@ import { TestBaseObserver, applyElementStyle, getBaseStyleClass, } from "./TestBaseObserver.js";

export class UIImageRenderer extends TestBaseObserver {
observe(observed) {
return super.observe(observed).observePropertyAsync("url", "style");
constructor(observed) {
super(observed);
this.observeProperties("url", "style");
}
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "url":
this.scheduleUpdate(this.element);
return;
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "url":
this.scheduleUpdate(this.element);
return;
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed)
throw ReferenceError();
let elt = new TestOutputElement("image");

@@ -35,12 +34,8 @@ let output = new RenderContext.Output(this.observed, elt);

let image = this.observed;
if (image) {
element.styleClass = getBaseStyleClass(image.style) || ui.style.IMAGE;
applyElementStyle(element, [image.style, { width: image.width, height: image.height }], image.position);
}
element.styleClass = getBaseStyleClass(image.style) || ui.style.IMAGE;
applyElementStyle(element, [image.style, { width: image.width, height: image.height }], image.position);
}
updateContent(element) {
if (!this.observed)
return;
element.imageUrl = String(this.observed.url || "");
}
}

@@ -1,2 +0,2 @@

import { RenderContext, ui, } from "@desk-framework/frame-core";
import { RenderContext, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -6,29 +6,26 @@ import { TestBaseObserver, applyElementStyle, getBaseStyleClass, } from "./TestBaseObserver.js";

export class UILabelRenderer extends TestBaseObserver {
observe(observed) {
return super
.observe(observed)
.observePropertyAsync("text", "icon", "bold", "italic", "color", "width", "dim", "style");
constructor(observed) {
super(observed);
this.observeProperties("text", "icon", "bold", "italic", "color", "width", "dim", "style");
}
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "text":
case "icon":
this.scheduleUpdate(this.element);
return;
case "bold":
case "italic":
case "color":
case "width":
case "dim":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "text":
case "icon":
this.scheduleUpdate(this.element);
return;
case "bold":
case "italic":
case "color":
case "width":
case "dim":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed)
throw ReferenceError();
let elt = new TestOutputElement("label");

@@ -43,27 +40,23 @@ let output = new RenderContext.Output(this.observed, elt);

let label = this.observed;
if (label) {
element.styleClass =
getBaseStyleClass(label.style) ||
(label.title
? ui.style.LABEL_TITLE
: label.small
? ui.style.LABEL_SMALL
: ui.style.LABEL);
applyElementStyle(element, [
label.style,
{
width: label.width,
bold: label.bold,
italic: label.italic,
textColor: label.color,
opacity: label.dim === true ? 0.5 : label.dim === false ? 1 : label.dim,
lineBreakMode: label.wrap ? "pre-wrap" : undefined,
userSelect: label.selectable || undefined,
},
], label.position);
}
element.styleClass =
getBaseStyleClass(label.style) ||
(label.title
? ui.style.LABEL_TITLE
: label.small
? ui.style.LABEL_SMALL
: ui.style.LABEL);
applyElementStyle(element, [
label.style,
{
width: label.width,
bold: label.bold,
italic: label.italic,
textColor: label.color,
opacity: label.dim === true ? 0.5 : label.dim === false ? 1 : label.dim,
lineBreakMode: label.wrap ? "pre-wrap" : undefined,
userSelect: label.selectable || undefined,
},
], label.position);
}
updateContent(element) {
if (!this.observed)
return;
element.text = String(this.observed.text);

@@ -70,0 +63,0 @@ element.icon = String(this.observed.icon || "");

@@ -1,2 +0,2 @@

import { RenderContext, } from "@desk-framework/frame-core";
import { RenderContext } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -6,22 +6,19 @@ import { TestBaseObserver, applyElementStyle } from "./TestBaseObserver.js";

export class UISeparatorRenderer extends TestBaseObserver {
observe(observed) {
return super
.observe(observed)
.observePropertyAsync("color", "margin", "thickness");
constructor(observed) {
super(observed);
this.observeProperties("color", "margin", "thickness");
}
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "color":
case "margin":
case "thickness":
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "color":
case "margin":
case "thickness":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed)
throw ReferenceError();
let elt = new TestOutputElement("separator");

@@ -35,12 +32,10 @@ let output = new RenderContext.Output(this.observed, elt);

let sep = this.observed;
if (sep) {
// NOTE: margin is ignored in test renderer
applyElementStyle(element, [
{
borderColor: sep.color,
borderThickness: sep.thickness,
},
], sep.position);
}
// NOTE: margin is ignored in test renderer
applyElementStyle(element, [
{
borderColor: sep.color,
borderThickness: sep.thickness,
},
], sep.position);
}
}

@@ -1,2 +0,2 @@

import { RenderContext, } from "@desk-framework/frame-core";
import { RenderContext } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -6,23 +6,20 @@ import { TestBaseObserver, applyElementStyle } from "./TestBaseObserver.js";

export class UISpacerRenderer extends TestBaseObserver {
observe(observed) {
return super
.observe(observed)
.observePropertyAsync("width", "height", "minWidth", "minHeight");
constructor(observed) {
super(observed);
this.observeProperties("width", "height", "minWidth", "minHeight");
}
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "width":
case "height":
case "minWidth":
case "minHeight":
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "width":
case "height":
case "minWidth":
case "minHeight":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed)
throw ReferenceError();
let elt = new TestOutputElement("spacer");

@@ -36,18 +33,16 @@ let output = new RenderContext.Output(this.observed, elt);

let spacer = this.observed;
if (spacer) {
let { width, height, minWidth, minHeight } = spacer;
let hasMinimum = minWidth !== undefined || minHeight !== undefined;
let hasFixed = width !== undefined || height !== undefined;
applyElementStyle(element, [
{
width,
height,
minWidth,
minHeight,
grow: hasFixed ? 0 : 1,
shrink: hasMinimum ? 0 : 1,
},
], spacer.position);
}
let { width, height, minWidth, minHeight } = spacer;
let hasMinimum = minWidth !== undefined || minHeight !== undefined;
let hasFixed = width !== undefined || height !== undefined;
applyElementStyle(element, [
{
width,
height,
minWidth,
minHeight,
grow: hasFixed ? 0 : 1,
shrink: hasMinimum ? 0 : 1,
},
], spacer.position);
}
}

@@ -1,2 +0,2 @@

import { RenderContext, ui, } from "@desk-framework/frame-core";
import { RenderContext, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -6,27 +6,26 @@ import { TestBaseObserver, applyElementStyle, getBaseStyleClass, } from "./TestBaseObserver.js";

export class UITextFieldRenderer extends TestBaseObserver {
observe(observed) {
return super
.observe(observed)
.observePropertyAsync("placeholder", "value", "disabled", "readOnly", "width", "style");
constructor(observed) {
super(observed);
this.observeProperties("placeholder", "value", "disabled", "readOnly", "width", "style");
}
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "placeholder":
case "value":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "readOnly":
case "width":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "placeholder":
case "value":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "readOnly":
case "width":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
handlePlatformEvent(name, data) {
// update 'value' first, reflecting the element value
if (this.element && this.observed) {
if (this.element) {
this.observed.value = this.element.value || "";

@@ -38,4 +37,2 @@ }

// NOTE: ignoring multiline flag here
if (!this.observed)
throw ReferenceError();
let elt = new TestOutputElement("textfield");

@@ -49,20 +46,16 @@ let output = new RenderContext.Output(this.observed, elt);

let textField = this.observed;
if (textField) {
// set state
element.disabled = textField.disabled;
element.readOnly = textField.readOnly;
// set styles
element.styleClass =
getBaseStyleClass(textField.style) || ui.style.TEXTFIELD;
applyElementStyle(element, [
textField.style,
textField.width !== undefined
? { width: textField.width, minWidth: 0 }
: undefined,
], textField.position);
}
// set state
element.disabled = textField.disabled;
element.readOnly = textField.readOnly;
// set styles
element.styleClass =
getBaseStyleClass(textField.style) || ui.style.TEXTFIELD;
applyElementStyle(element, [
textField.style,
textField.width !== undefined
? { width: textField.width, minWidth: 0 }
: undefined,
], textField.position);
}
updateContent(element) {
if (!this.observed)
return;
element.text = String(this.observed.placeholder || "");

@@ -69,0 +62,0 @@ let value = this.observed.value;

@@ -1,2 +0,2 @@

import { RenderContext, ui, } from "@desk-framework/frame-core";
import { RenderContext, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -6,22 +6,21 @@ import { TestBaseObserver, applyElementStyle, getBaseStyleClass, } from "./TestBaseObserver.js";

export class UIToggleRenderer extends TestBaseObserver {
observe(observed) {
return super
.observe(observed)
.observePropertyAsync("label", "state", "disabled", "style", "labelStyle");
constructor(observed) {
super(observed);
this.observeProperties("label", "state", "disabled", "style", "labelStyle");
}
async handlePropertyChange(property, value, event) {
if (this.observed && this.element) {
switch (property) {
case "label":
case "state":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "style":
case "labelStyle":
this.scheduleUpdate(undefined, this.element);
return;
}
propertyChange(property, value) {
if (!this.element)
return;
switch (property) {
case "label":
case "state":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "style":
case "labelStyle":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}

@@ -37,4 +36,2 @@ handlePlatformEvent(name, data) {

getOutput() {
if (!this.observed)
throw ReferenceError();
let elt = new TestOutputElement("toggle");

@@ -48,13 +45,9 @@ let output = new RenderContext.Output(this.observed, elt);

let toggle = this.observed;
if (toggle) {
// set disabled state
element.disabled = toggle.disabled;
// set styles
element.styleClass = getBaseStyleClass(toggle.style) || ui.style.TOGGLE;
applyElementStyle(element, [toggle.style], toggle.position);
}
// set disabled state
element.disabled = toggle.disabled;
// set styles
element.styleClass = getBaseStyleClass(toggle.style) || ui.style.TOGGLE;
applyElementStyle(element, [toggle.style], toggle.position);
}
updateContent(element) {
if (!this.observed)
return;
element.text = String(this.observed.label || "");

@@ -61,0 +54,0 @@ element.checked = !!this.observed.state;

{
"name": "@desk-framework/frame-test",
"version": "4.0.0-dev.18",
"version": "4.0.0-dev.19",
"publishConfig": {

@@ -32,3 +32,3 @@ "tag": "next"

"peerDependencies": {
"@desk-framework/frame-core": "4.0.0-dev.18"
"@desk-framework/frame-core": "4.0.0-dev.19"
},

@@ -35,0 +35,0 @@ "devDependencies": {

@@ -78,4 +78,4 @@ import {

// create test renderer
app.renderer = new TestRenderer(options);
app.theme = new TestTheme();
(app as any).renderer = new TestRenderer(options);

@@ -82,0 +82,0 @@ // create no-op viewport context

import {
Observer,
UIButton,

@@ -23,28 +22,27 @@ UICell,

import { UIToggleRenderer } from "./UIToggleRenderer.js";
import { TestBaseObserver } from "./TestBaseObserver.js";
/** @internal */
export function makeObserver<T extends View>(
target: T,
): Observer<T> | undefined {
export function makeObserver(target: View): TestBaseObserver<any> | undefined {
return (
target instanceof UICell
? new UICellRenderer()
? new UICellRenderer(target)
: target instanceof UIContainer
? new UIContainerRenderer()
? new UIContainerRenderer(target)
: target instanceof UILabel
? new UILabelRenderer()
? new UILabelRenderer(target)
: target instanceof UIButton
? new UIButtonRenderer()
? new UIButtonRenderer(target)
: target instanceof UIImage
? new UIImageRenderer()
? new UIImageRenderer(target)
: target instanceof UISeparator
? new UISeparatorRenderer()
? new UISeparatorRenderer(target)
: target instanceof UISpacer
? new UISpacerRenderer()
? new UISpacerRenderer(target)
: target instanceof UITextField
? new UITextFieldRenderer()
? new UITextFieldRenderer(target)
: target instanceof UIToggle
? new UIToggleRenderer()
? new UIToggleRenderer(target)
: undefined
) as any;
}
import {
ManagedEvent,
Observer,
ManagedObject,
RenderContext,

@@ -87,7 +87,5 @@ UIComponent,

/** @internal Abstract observer class for all `UIComponent` instances, to create output and call render callback; implemented for all types of UI components */
export abstract class TestBaseObserver<
TUIComponent extends UIComponent,
> extends Observer<TUIComponent> {
override observe(observed: TUIComponent) {
/** @internal Abstract observer class for all `UIComponent` instances, to create output and call render callback; implemented for all types of UI components, created upon rendering, and attached to enable property bindings */
export abstract class TestBaseObserver<TUIComponent extends UIComponent> {
constructor(public observed: TUIComponent) {
this._thisRenderedEvent = new ManagedEvent(

@@ -101,45 +99,46 @@ "Rendered",

);
return super.observe(observed).observePropertyAsync("hidden", "position");
this.observeProperties("hidden", "position");
observed.listen((e) => {
let handler = (this as any)["on" + e.name];
if (typeof handler === "function") handler.call(this, e);
});
}
private _thisRenderedEvent?: ManagedEvent;
/** Set up one or more property listeners, to call {@link propertyChange} on this observer */
protected observeProperties(...properties: (keyof this["observed"])[]) {
ManagedObject.observe(this.observed, properties, (_, p, v) =>
this.propertyChange(p as any, v),
);
}
/** Handler for base property changes; must be overridden to handle other UI component properties */
protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "hidden":
this._hidden = this.observed.hidden;
if (!this._hidden) this.updateStyle(this.element);
if (this.updateCallback) {
this.updateCallback = this.updateCallback.call(
undefined,
this._hidden ? undefined : this.output,
);
}
return;
case "position":
this.scheduleUpdate(undefined, this.element);
return;
}
protected propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "hidden":
this.scheduleHide(value);
return;
case "position":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
}
/** Rendered element, if any; set by `onRender` handler based on return value of `getOutput()` method */
element?: TestOutputElement;
/** Rendered output, if any; set by `onRender` handler based on return value of `getOutput()` method */
output?: RenderContext.Output<TestOutputElement>;
/** Rendered element, if any; set by `onRender` handler based on return value of `getOutput()` method */
element?: TestOutputElement;
/** Creates test output (with element to render) for the observed UI component; called before rendering, must be overridden to create instances of `TestOutputElement` */
abstract getOutput(): RenderContext.Output & { element: TestOutputElement };
/** Updates the specified output element with content: either from properties (e.g. text content) or from other UI components; called automatically by `update()`, but can also be called when state properties change; must be overridden */
abstract updateContent(element: TestOutputElement): void;
/** Updates the specified output element with all style properties; called automatically by `update()`, but can also be called when state properties change; must be overridden to update test output element styles */
abstract updateStyle(element: TestOutputElement): void;
/** Updates the specified output element with all properties of the UI component; called automatically before rendering (after `getOutput`), but can also be called when state properties change */
update(element: TestOutputElement) {
if (!this.observed) return;
this._hidden = this.observed.hidden;

@@ -165,2 +164,3 @@ this._asyncContentUp = undefined;

app.renderer.schedule(() => {
if (this.observed.isUnlinked()) return;
this._asyncUp = false;

@@ -180,8 +180,18 @@ if (this._asyncContentUp) this.updateContent(this._asyncContentUp);

/** Updates the specified output element with content: either from properties (e.g. text content) or from other UI components; called automatically by `update()`, but can also be called when state properties change; must be overridden */
abstract updateContent(element: TestOutputElement): void;
/** Schedules an asynchronous update to show or hide the output */
scheduleHide(hidden?: boolean) {
app.renderer?.schedule(() => {
let elt = this.element;
if (!elt) return;
this._hidden = hidden;
if (!hidden) this.updateStyle(elt);
if (this._updateCallback) {
this._updateCallback = this._updateCallback.call(
undefined,
hidden ? undefined : this.output,
);
}
});
}
/** Updates the specified output element with all style properties; called automatically by `update()`, but can also be called when state properties change; must be overridden to update test output element styles */
abstract updateStyle(element: TestOutputElement): void;
private _hidden?: boolean;

@@ -192,3 +202,3 @@

let baseEvent = _eventNames[name];
if (baseEvent && this.observed && !this.observed.isUnlinked()) {
if (baseEvent && !this.observed.isUnlinked()) {
let event = new ManagedEvent(

@@ -229,6 +239,8 @@ baseEvent,

// call render callback with new element
this.updateCallback = event.data.render.call(
this._updateCallback = event.data.render.call(
undefined,
this._hidden ? undefined : this.output,
() => {
if (this.observed.isUnlinked()) return;
// try to focus if requested

@@ -241,5 +253,3 @@ if (this._requestedFocus && this.element && !this._hidden) {

// emit Rendered event
if (this.observed && !this.observed.isUnlinked()) {
this.observed.emit(this._thisRenderedEvent);
}
this.observed.emit(this._thisRenderedEvent);
},

@@ -250,4 +260,2 @@ );

updateCallback?: RenderContext.RenderCallback;
/** Focus current element if possible */

@@ -299,2 +307,5 @@ onRequestFocus(event: ManagedEvent) {

}
private _updateCallback?: RenderContext.RenderCallback;
private _thisRenderedEvent?: ManagedEvent;
}
import {
AsyncTaskQueue,
Observer,
RenderContext,

@@ -145,3 +144,3 @@ View,

/** Attaches a renderer to the the provided UI component (called internally) */
createObserver<T extends View>(target: T): Observer<T> | undefined {
createObserver(target: View): unknown {
return makeObserver(target);

@@ -148,0 +147,0 @@ }

@@ -1,7 +0,2 @@

import {
ManagedEvent,
RenderContext,
UIButton,
ui,
} from "@desk-framework/frame-core";
import { RenderContext, UIButton, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -16,37 +11,31 @@ import {

export class UIButtonRenderer extends TestBaseObserver<UIButton> {
override observe(observed: UIButton) {
return super
.observe(observed)
.observePropertyAsync(
"label",
"icon",
"chevron",
"disabled",
"width",
"pressed",
"style",
);
constructor(observed: UIButton) {
super(observed);
this.observeProperties(
"label",
"icon",
"chevron",
"disabled",
"width",
"pressed",
"style",
);
}
protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "label":
case "icon":
case "chevron":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "pressed":
case "width":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
protected override propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "label":
case "icon":
case "chevron":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "pressed":
case "width":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}

@@ -71,3 +60,2 @@

getOutput() {
if (!this.observed) throw ReferenceError();
let elt = new TestOutputElement("button");

@@ -81,32 +69,30 @@ let output = new RenderContext.Output(this.observed, elt);

override updateStyle(element: TestOutputElement) {
// set state
let button = this.observed;
if (button) {
// set state
element.disabled = button.disabled;
element.pressed = button.pressed;
element.disabled = !!button.disabled;
element.pressed = !!button.pressed;
// set styles
element.styleClass =
getBaseStyleClass(button.style) ||
(button.primary ? ui.style.BUTTON_PRIMARY : ui.style.BUTTON);
applyElementStyle(
element,
[
button.style,
button.width !== undefined
? { width: button.width, minWidth: 0 }
: undefined,
],
button.position,
);
}
// set styles
element.styleClass =
getBaseStyleClass(button.style) ||
(button.primary ? ui.style.BUTTON_PRIMARY : ui.style.BUTTON);
applyElementStyle(
element,
[
button.style,
button.width !== undefined
? { width: button.width, minWidth: 0 }
: undefined,
],
button.position,
);
}
updateContent(element: TestOutputElement) {
if (!this.observed) return;
element.text = String(this.observed.label || "");
element.icon = String(this.observed.icon || "");
element.chevron = String(this.observed.chevron || "");
let button = this.observed;
element.text = String(button.label || "");
element.icon = String(button.icon || "");
element.chevron = String(button.chevron || "");
element.focusable = true;
}
}

@@ -1,2 +0,2 @@

import { ManagedEvent, UICell, ui } from "@desk-framework/frame-core";
import { UICell, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -8,4 +8,5 @@ import { getBaseStyleClass } from "./TestBaseObserver.js";

export class UICellRenderer extends UIContainerRenderer<UICell> {
override observe(observed: UICell) {
return super.observe(observed).observePropertyAsync(
constructor(observed: UICell) {
super(observed);
this.observeProperties(
// note some properties are handled by container (e.g. padding)

@@ -22,25 +23,19 @@ "textDirection",

protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "textDirection":
case "margin":
case "borderRadius":
case "background":
case "textColor":
case "opacity":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
protected override propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "textDirection":
case "margin":
case "borderRadius":
case "background":
case "textColor":
case "opacity":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
override getOutput() {
if (!this.observed) throw ReferenceError();
let output = super.getOutput();

@@ -54,3 +49,2 @@ if (this.observed.allowFocus || this.observed.allowKeyboardFocus)

let cell = this.observed;
if (!cell) return;
super.updateContent(element);

@@ -62,3 +56,2 @@ if (cell.allowFocus || cell.allowKeyboardFocus) element.focusable = true;

let cell = this.observed;
if (!cell) return;

@@ -65,0 +58,0 @@ // NOTE: margin, textDirection aren't applied in test renderer

import {
ManagedEvent,
RenderContext,

@@ -20,43 +19,43 @@ UICell,

> extends TestBaseObserver<TContainer> {
override observe(observed: UIContainer) {
let result = super
.observe(observed as any)
.observePropertyAsync("content", "layout", "padding");
constructor(observed: TContainer) {
super(observed);
this.observeProperties("layout", "padding");
if (observed instanceof UIRow) {
result.observePropertyAsync("height" as any, "align" as any);
this.observeProperties("height" as any, "align" as any);
}
if (observed instanceof UIColumn) {
result.observePropertyAsync("width" as any, "align" as any);
this.observeProperties("width" as any, "align" as any);
}
return result;
}
override handleUnlink() {
if (this.contentUpdater) this.contentUpdater.stop();
this.contentUpdater = undefined;
super.handleUnlink();
// observe content changes
observed.content.listen((e) => {
if (this.element && e.source === observed.content) {
this.scheduleUpdate(this.element);
}
});
// observe unlink, to stop content updater right away
observed.listen({
unlinked: () => {
if (this.contentUpdater) this.contentUpdater.stop();
this.contentUpdater = undefined;
},
});
}
protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "content":
this.scheduleUpdate(this.element);
return;
case "layout":
case "padding":
case "align": // for rows and columns
this.scheduleUpdate(undefined, this.element);
return;
}
protected override propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "layout":
case "padding":
case "align": // for rows and columns
case "height": // for rows
case "width": // for columns
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed) throw ReferenceError();
let type: TestOutputElement.TypeString;

@@ -86,4 +85,2 @@ if (this.observed.accessibleRole === "form") type = "form";

let container = this.observed;
if (!container) return;
if (!this.contentUpdater) {

@@ -109,22 +106,20 @@ this.contentUpdater = new ContentUpdater(

let container = this.observed;
if (container) {
let layout = container.layout;
if (container instanceof UIRow) {
styles = [{ height: container.height, padding: container.padding }];
if (container.align) {
layout = { ...layout, distribution: container.align };
}
} else if (container instanceof UIColumn) {
styles = [{ width: container.width, padding: container.padding }];
if (container.align) {
layout = { ...layout, gravity: container.align };
}
} else if (container instanceof UIScrollContainer) {
styles = [{ padding: container.padding }];
let layout = container.layout;
if (container instanceof UIRow) {
styles = [{ height: container.height, padding: container.padding }];
if (container.align) {
layout = { ...layout, distribution: container.align };
}
} else if (container instanceof UIColumn) {
styles = [{ width: container.width, padding: container.padding }];
if (container.align) {
layout = { ...layout, gravity: container.align };
}
} else if (container instanceof UIScrollContainer) {
styles = [{ padding: container.padding }];
}
// apply styles
element.styleClass = BaseStyle;
applyElementStyle(element, styles, container.position, layout);
}
// apply styles
element.styleClass = BaseStyle;
applyElementStyle(element, styles, container.position, layout);
}

@@ -131,0 +126,0 @@ }

@@ -1,7 +0,2 @@

import {
ManagedEvent,
RenderContext,
UIImage,
ui,
} from "@desk-framework/frame-core";
import { RenderContext, UIImage, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -16,26 +11,21 @@ import {

export class UIImageRenderer extends TestBaseObserver<UIImage> {
override observe(observed: UIImage) {
return super.observe(observed).observePropertyAsync("url", "style");
constructor(observed: UIImage) {
super(observed);
this.observeProperties("url", "style");
}
protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "url":
this.scheduleUpdate(this.element);
return;
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
protected override propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "url":
this.scheduleUpdate(this.element);
return;
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed) throw ReferenceError();
let elt = new TestOutputElement("image");

@@ -51,16 +41,13 @@ let output = new RenderContext.Output(this.observed, elt);

let image = this.observed;
if (image) {
element.styleClass = getBaseStyleClass(image.style) || ui.style.IMAGE;
applyElementStyle(
element,
[image.style, { width: image.width, height: image.height }],
image.position,
);
}
element.styleClass = getBaseStyleClass(image.style) || ui.style.IMAGE;
applyElementStyle(
element,
[image.style, { width: image.width, height: image.height }],
image.position,
);
}
updateContent(element: TestOutputElement) {
if (!this.observed) return;
element.imageUrl = String(this.observed.url || "");
}
}

@@ -1,7 +0,2 @@

import {
ManagedEvent,
RenderContext,
UILabel,
ui,
} from "@desk-framework/frame-core";
import { RenderContext, UILabel, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -16,43 +11,36 @@ import {

export class UILabelRenderer extends TestBaseObserver<UILabel> {
override observe(observed: UILabel) {
return super
.observe(observed)
.observePropertyAsync(
"text",
"icon",
"bold",
"italic",
"color",
"width",
"dim",
"style",
);
constructor(observed: UILabel) {
super(observed);
this.observeProperties(
"text",
"icon",
"bold",
"italic",
"color",
"width",
"dim",
"style",
);
}
protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "text":
case "icon":
this.scheduleUpdate(this.element);
return;
case "bold":
case "italic":
case "color":
case "width":
case "dim":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
protected override propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "text":
case "icon":
this.scheduleUpdate(this.element);
return;
case "bold":
case "italic":
case "color":
case "width":
case "dim":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed) throw ReferenceError();
let elt = new TestOutputElement("label");

@@ -68,32 +56,29 @@ let output = new RenderContext.Output(this.observed, elt);

let label = this.observed;
if (label) {
element.styleClass =
getBaseStyleClass(label.style) ||
(label.title
? ui.style.LABEL_TITLE
: label.small
? ui.style.LABEL_SMALL
: ui.style.LABEL);
applyElementStyle(
element,
[
label.style,
{
width: label.width,
bold: label.bold,
italic: label.italic,
textColor: label.color,
opacity:
label.dim === true ? 0.5 : label.dim === false ? 1 : label.dim,
lineBreakMode: label.wrap ? "pre-wrap" : undefined,
userSelect: label.selectable || undefined,
},
],
label.position,
);
}
element.styleClass =
getBaseStyleClass(label.style) ||
(label.title
? ui.style.LABEL_TITLE
: label.small
? ui.style.LABEL_SMALL
: ui.style.LABEL);
applyElementStyle(
element,
[
label.style,
{
width: label.width,
bold: label.bold,
italic: label.italic,
textColor: label.color,
opacity:
label.dim === true ? 0.5 : label.dim === false ? 1 : label.dim,
lineBreakMode: label.wrap ? "pre-wrap" : undefined,
userSelect: label.selectable || undefined,
},
],
label.position,
);
}
updateContent(element: TestOutputElement) {
if (!this.observed) return;
element.text = String(this.observed.text);

@@ -100,0 +85,0 @@ element.icon = String(this.observed.icon || "");

@@ -1,6 +0,2 @@

import {
ManagedEvent,
RenderContext,
UISeparator,
} from "@desk-framework/frame-core";
import { RenderContext, UISeparator } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -11,27 +7,20 @@ import { TestBaseObserver, applyElementStyle } from "./TestBaseObserver.js";

export class UISeparatorRenderer extends TestBaseObserver<UISeparator> {
override observe(observed: UISeparator) {
return super
.observe(observed)
.observePropertyAsync("color", "margin", "thickness");
constructor(observed: UISeparator) {
super(observed);
this.observeProperties("color", "margin", "thickness");
}
protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "color":
case "margin":
case "thickness":
this.scheduleUpdate(undefined, this.element);
return;
}
protected override propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "color":
case "margin":
case "thickness":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed) throw ReferenceError();
let elt = new TestOutputElement("separator");

@@ -47,16 +36,14 @@ let output = new RenderContext.Output(this.observed, elt);

let sep = this.observed;
if (sep) {
// NOTE: margin is ignored in test renderer
applyElementStyle(
element,
[
{
borderColor: sep.color,
borderThickness: sep.thickness,
},
],
sep.position,
);
}
// NOTE: margin is ignored in test renderer
applyElementStyle(
element,
[
{
borderColor: sep.color,
borderThickness: sep.thickness,
},
],
sep.position,
);
}
}

@@ -1,6 +0,2 @@

import {
ManagedEvent,
RenderContext,
UISpacer,
} from "@desk-framework/frame-core";
import { RenderContext, UISpacer } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -11,28 +7,21 @@ import { TestBaseObserver, applyElementStyle } from "./TestBaseObserver.js";

export class UISpacerRenderer extends TestBaseObserver<UISpacer> {
override observe(observed: UISpacer) {
return super
.observe(observed)
.observePropertyAsync("width", "height", "minWidth", "minHeight");
constructor(observed: UISpacer) {
super(observed);
this.observeProperties("width", "height", "minWidth", "minHeight");
}
protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "width":
case "height":
case "minWidth":
case "minHeight":
this.scheduleUpdate(undefined, this.element);
return;
}
protected override propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "width":
case "height":
case "minWidth":
case "minHeight":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}
getOutput() {
if (!this.observed) throw ReferenceError();
let elt = new TestOutputElement("spacer");

@@ -48,22 +37,20 @@ let output = new RenderContext.Output(this.observed, elt);

let spacer = this.observed;
if (spacer) {
let { width, height, minWidth, minHeight } = spacer;
let hasMinimum = minWidth !== undefined || minHeight !== undefined;
let hasFixed = width !== undefined || height !== undefined;
applyElementStyle(
element,
[
{
width,
height,
minWidth,
minHeight,
grow: hasFixed ? 0 : 1,
shrink: hasMinimum ? 0 : 1,
},
],
spacer.position,
);
}
let { width, height, minWidth, minHeight } = spacer;
let hasMinimum = minWidth !== undefined || minHeight !== undefined;
let hasFixed = width !== undefined || height !== undefined;
applyElementStyle(
element,
[
{
width,
height,
minWidth,
minHeight,
grow: hasFixed ? 0 : 1,
shrink: hasMinimum ? 0 : 1,
},
],
spacer.position,
);
}
}

@@ -1,7 +0,2 @@

import {
ManagedEvent,
RenderContext,
UITextField,
ui,
} from "@desk-framework/frame-core";
import { RenderContext, UITextField, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -16,35 +11,29 @@ import {

export class UITextFieldRenderer extends TestBaseObserver<UITextField> {
override observe(observed: UITextField) {
return super
.observe(observed)
.observePropertyAsync(
"placeholder",
"value",
"disabled",
"readOnly",
"width",
"style",
);
constructor(observed: UITextField) {
super(observed);
this.observeProperties(
"placeholder",
"value",
"disabled",
"readOnly",
"width",
"style",
);
}
protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "placeholder":
case "value":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "readOnly":
case "width":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
protected override propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "placeholder":
case "value":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "readOnly":
case "width":
case "style":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}

@@ -57,3 +46,3 @@

// update 'value' first, reflecting the element value
if (this.element && this.observed) {
if (this.element) {
this.observed.value = this.element.value || "";

@@ -67,3 +56,2 @@ }

// NOTE: ignoring multiline flag here
if (!this.observed) throw ReferenceError();
let elt = new TestOutputElement("textfield");

@@ -78,25 +66,22 @@ let output = new RenderContext.Output(this.observed, elt);

let textField = this.observed;
if (textField) {
// set state
element.disabled = textField.disabled;
element.readOnly = textField.readOnly;
// set state
element.disabled = textField.disabled;
element.readOnly = textField.readOnly;
// set styles
element.styleClass =
getBaseStyleClass(textField.style) || ui.style.TEXTFIELD;
applyElementStyle(
element,
[
textField.style,
textField.width !== undefined
? { width: textField.width, minWidth: 0 }
: undefined,
],
textField.position,
);
}
// set styles
element.styleClass =
getBaseStyleClass(textField.style) || ui.style.TEXTFIELD;
applyElementStyle(
element,
[
textField.style,
textField.width !== undefined
? { width: textField.width, minWidth: 0 }
: undefined,
],
textField.position,
);
}
updateContent(element: TestOutputElement) {
if (!this.observed) return;
element.text = String(this.observed.placeholder || "");

@@ -103,0 +88,0 @@

@@ -1,7 +0,2 @@

import {
ManagedEvent,
RenderContext,
UIToggle,
ui,
} from "@desk-framework/frame-core";
import { RenderContext, UIToggle, ui } from "@desk-framework/frame-core";
import { TestOutputElement } from "../app/TestOutputElement.js";

@@ -16,33 +11,21 @@ import {

export class UIToggleRenderer extends TestBaseObserver<UIToggle> {
override observe(observed: UIToggle) {
return super
.observe(observed)
.observePropertyAsync(
"label",
"state",
"disabled",
"style",
"labelStyle",
);
constructor(observed: UIToggle) {
super(observed);
this.observeProperties("label", "state", "disabled", "style", "labelStyle");
}
protected override async handlePropertyChange(
property: string,
value: any,
event?: ManagedEvent,
) {
if (this.observed && this.element) {
switch (property) {
case "label":
case "state":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "style":
case "labelStyle":
this.scheduleUpdate(undefined, this.element);
return;
}
protected override propertyChange(property: string, value: any) {
if (!this.element) return;
switch (property) {
case "label":
case "state":
this.scheduleUpdate(this.element);
return;
case "disabled":
case "style":
case "labelStyle":
this.scheduleUpdate(undefined, this.element);
return;
}
await super.handlePropertyChange(property, value, event);
super.propertyChange(property, value);
}

@@ -64,3 +47,2 @@

getOutput() {
if (!this.observed) throw ReferenceError();
let elt = new TestOutputElement("toggle");

@@ -75,14 +57,12 @@ let output = new RenderContext.Output(this.observed, elt);

let toggle = this.observed;
if (toggle) {
// set disabled state
element.disabled = toggle.disabled;
// set styles
element.styleClass = getBaseStyleClass(toggle.style) || ui.style.TOGGLE;
applyElementStyle(element, [toggle.style], toggle.position);
}
// set disabled state
element.disabled = toggle.disabled;
// set styles
element.styleClass = getBaseStyleClass(toggle.style) || ui.style.TOGGLE;
applyElementStyle(element, [toggle.style], toggle.position);
}
updateContent(element: TestOutputElement) {
if (!this.observed) return;
element.text = String(this.observed.label || "");

@@ -89,0 +69,0 @@ element.checked = !!this.observed.state;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc