scriptable-testlab
Version:
A lightweight, efficient tool designed to manage and update scripts for Scriptable.
230 lines (189 loc) • 5.54 kB
text/typescript
import {AbsWidgetStack} from 'scriptable-abstract';
import {MockImage} from '../../media/image';
import {MockColor} from '../color';
import {MockLinearGradient} from '../gradient';
import {MockWidgetDate} from './date';
import {MockWidgetImage} from './image';
import {MockWidgetText} from './text';
/**
* Represents the state of a widget stack.
*/
interface WidgetStackMockState {
readonly alignment: 'leading' | 'center' | 'trailing';
readonly spacing: number;
readonly size: Readonly<{width: number; height: number}>;
readonly backgroundColor: Color;
readonly backgroundImage: Image;
readonly backgroundGradient: LinearGradient;
readonly cornerRadius: number;
readonly borderWidth: number;
readonly borderColor: Color;
readonly url: string;
readonly padding: Readonly<{top: number; leading: number; bottom: number; trailing: number}>;
readonly items: ReadonlyArray<WidgetItem>;
readonly layout: 'horizontal' | 'vertical';
}
/**
* Represents any item that can be added to a widget stack.
*/
type WidgetItem = WidgetText | WidgetDate | WidgetImage | WidgetSpacer | WidgetStack;
/**
* Default state for a new widget stack.
*/
const DEFAULT_STATE: WidgetStackMockState = {
alignment: 'leading',
spacing: 0,
size: {width: 0, height: 0},
backgroundColor: new MockColor('#000000'),
backgroundImage: MockImage.fromFile(''),
backgroundGradient: new MockLinearGradient(),
cornerRadius: 0,
borderWidth: 0,
borderColor: new MockColor('#000000'),
url: '',
padding: {top: 0, leading: 0, bottom: 0, trailing: 0},
items: [],
layout: 'vertical',
};
/**
* Mock implementation of Scriptable's WidgetStack.
* Provides a container for organizing widget elements in a vertical or horizontal layout.
*/
export class MockWidgetStack extends AbsWidgetStack<WidgetStackMockState> {
constructor() {
super(DEFAULT_STATE);
}
/**
* Creates a new widget stack instance.
*/
static create(): WidgetStack {
return new MockWidgetStack();
}
// Property accessors
get alignment(): 'leading' | 'center' | 'trailing' {
return this.state.alignment;
}
set alignment(value: 'leading' | 'center' | 'trailing') {
this.setState({alignment: value});
}
get spacing(): number {
return this.state.spacing;
}
set spacing(value: number) {
this.setState({spacing: value});
}
get size(): {width: number; height: number} {
return {...this.state.size};
}
set size(value: {width: number; height: number}) {
this.setState({size: {...value}});
}
get backgroundColor(): Color {
return this.state.backgroundColor;
}
set backgroundColor(value: Color) {
this.setState({backgroundColor: value});
}
get backgroundImage(): Image {
return this.state.backgroundImage;
}
set backgroundImage(value: Image) {
this.setState({backgroundImage: value});
}
get backgroundGradient(): LinearGradient {
return this.state.backgroundGradient;
}
set backgroundGradient(value: LinearGradient) {
this.setState({backgroundGradient: value});
}
get cornerRadius(): number {
return this.state.cornerRadius;
}
set cornerRadius(value: number) {
this.setState({cornerRadius: value});
}
get borderWidth(): number {
return this.state.borderWidth;
}
set borderWidth(value: number) {
this.setState({borderWidth: value});
}
get borderColor(): Color {
return this.state.borderColor;
}
set borderColor(value: Color) {
this.setState({borderColor: value});
}
get url(): string {
return this.state.url;
}
set url(value: string) {
this.setState({url: value});
}
// Widget element management methods
addText(text: string): WidgetText {
const textItem = new MockWidgetText(text);
this.setState(prevState => ({
items: [...prevState.items, textItem],
}));
return textItem;
}
addDate(date: Date): WidgetDate {
const dateItem = new MockWidgetDate(date);
this.setState(prevState => ({
items: [...prevState.items, dateItem],
}));
return dateItem;
}
addImage(image: Image): WidgetImage {
const imageItem = MockWidgetImage.create(image);
this.setState(prevState => ({
items: [...prevState.items, imageItem],
}));
return imageItem;
}
addSpacer(length?: number): WidgetSpacer {
const spacer = {type: 'spacer', length: length ?? 0} as WidgetSpacer;
this.setState(prevState => ({
items: [...prevState.items, spacer],
}));
return spacer;
}
addStack(): WidgetStack {
const stack = MockWidgetStack.create();
this.setState(prevState => ({
items: [...prevState.items, stack],
}));
return stack;
}
// Layout methods
setPadding(top: number, leading: number, bottom: number, trailing: number): void {
this.setState({
padding: {top, leading, bottom, trailing},
});
}
getPadding(): {top: number; leading: number; bottom: number; trailing: number} {
return {...this.state.padding};
}
getItems(): ReadonlyArray<WidgetItem> {
return [...this.state.items];
}
useDefaultPadding(): void {
this.setPadding(8, 8, 8, 8);
}
topAlignContent(): void {
this.setState({alignment: 'leading'});
}
centerAlignContent(): void {
this.setState({alignment: 'center'});
}
bottomAlignContent(): void {
this.setState({alignment: 'trailing'});
}
layoutHorizontally(): void {
this.setState({layout: 'horizontal'});
}
layoutVertically(): void {
this.setState({layout: 'vertical'});
}
}