scriptable-testlab
Version:
A lightweight, efficient tool designed to manage and update scripts for Scriptable.
268 lines (230 loc) • 6 kB
text/typescript
import {AbsWidgetDate} from 'scriptable-abstract';
import {MockColor} from '../color';
import {MockFont} from '../font';
/**
* Represents the date format options.
*/
type DateFormat = 'time' | 'date' | 'relative' | 'offset' | 'timer';
/**
* Represents the text alignment options.
*/
type TextAlignment = 'left' | 'center' | 'right';
/**
* Represents the state of a widget date element.
*/
interface WidgetDateMockState {
readonly date: Date;
readonly textColor: Color;
readonly font: Font;
readonly textOpacity: number;
readonly lineLimit: number;
readonly minimumScaleFactor: number;
readonly shadowColor: Color;
readonly shadowRadius: number;
readonly shadowOffset: Readonly<Point>;
readonly url: string;
readonly dateFormat: DateFormat;
readonly textAlignment: TextAlignment;
readonly appliedStyles: ReadonlyArray<string>;
}
/**
* Default state for a new widget date element.
*/
const DEFAULT_STATE: WidgetDateMockState = {
date: new Date(),
textColor: new MockColor('#000000'),
font: MockFont.systemFont(16),
textOpacity: 1,
lineLimit: 0,
minimumScaleFactor: 1,
shadowColor: new MockColor('#000000'),
shadowRadius: 0,
shadowOffset: {x: 0, y: 0},
url: '',
dateFormat: 'date',
textAlignment: 'left',
appliedStyles: [],
};
/**
* Mock implementation of Scriptable's WidgetDate.
* Provides a date element for displaying dates in widgets.
*
* @example
* ```typescript
* const date = new Date();
* const widgetDate = new MockWidgetDate(date);
* widgetDate.applyTimeStyle();
* widgetDate.centerAlignText();
* ```
*/
export class MockWidgetDate extends AbsWidgetDate<WidgetDateMockState> {
/**
* Creates a new widget date element with the specified date.
*/
constructor(date: Date) {
super({
...DEFAULT_STATE,
date,
});
}
// Property accessors
get date(): Date {
return new Date(this.state.date);
}
set date(value: Date) {
this.setState({date: new Date(value)});
}
get textColor(): Color {
return this.state.textColor;
}
set textColor(value: Color) {
this.setState({textColor: value});
}
get font(): Font {
return this.state.font;
}
set font(value: Font) {
this.setState({font: value});
}
get textOpacity(): number {
return this.state.textOpacity;
}
set textOpacity(value: number) {
const numValue = Number(value);
const clampedValue = isNaN(numValue) ? 0 : Math.max(0, Math.min(1, numValue));
this.setState({textOpacity: clampedValue});
}
get lineLimit(): number {
return this.state.lineLimit;
}
set lineLimit(value: number) {
const numValue = Number(value);
const validValue = isNaN(numValue) || numValue < 0 ? 0 : numValue;
this.setState({lineLimit: validValue});
}
get minimumScaleFactor(): number {
return this.state.minimumScaleFactor;
}
set minimumScaleFactor(value: number) {
const numValue = Number(value);
const clampedValue = isNaN(numValue) ? 0 : Math.max(0, Math.min(1, numValue));
this.setState({minimumScaleFactor: clampedValue});
}
get shadowColor(): Color {
return this.state.shadowColor;
}
set shadowColor(value: Color) {
this.setState({shadowColor: value});
}
get shadowRadius(): number {
return this.state.shadowRadius;
}
set shadowRadius(value: number) {
const numValue = Number(value);
const validValue = isNaN(numValue) || numValue < 0 ? 0 : numValue;
this.setState({shadowRadius: validValue});
}
get shadowOffset(): Point {
return {...this.state.shadowOffset};
}
set shadowOffset(value: Point) {
this.setState({shadowOffset: {...value}});
}
get url(): string {
return this.state.url;
}
set url(value: string) {
this.setState({url: value});
}
// Style methods
/**
* Applies the time style to the date element.
*/
applyTimeStyle(): void {
this.setState({
font: MockFont.systemFont(16),
dateFormat: 'time',
appliedStyles: [...this.state.appliedStyles, 'time'],
});
}
/**
* Applies the date style to the date element.
*/
applyDateStyle(): void {
this.setState({
font: MockFont.systemFont(16),
dateFormat: 'date',
appliedStyles: [...this.state.appliedStyles, 'date'],
});
}
/**
* Applies the relative style to the date element.
*/
applyRelativeStyle(): void {
this.setState({
font: MockFont.systemFont(16),
dateFormat: 'relative',
appliedStyles: [...this.state.appliedStyles, 'relative'],
});
}
/**
* Applies the offset style to the date element.
*/
applyOffsetStyle(): void {
this.setState({
font: MockFont.systemFont(16),
dateFormat: 'offset',
appliedStyles: [...this.state.appliedStyles, 'offset'],
});
}
/**
* Applies the timer style to the date element.
*/
applyTimerStyle(): void {
this.setState({
font: MockFont.systemFont(16),
dateFormat: 'timer',
appliedStyles: [...this.state.appliedStyles, 'timer'],
});
}
// Alignment methods
/**
* Centers the text in its container.
*/
centerAlignText(): void {
this.setState({textAlignment: 'center'});
}
/**
* Aligns the text to the left of its container.
*/
leftAlignText(): void {
this.setState({textAlignment: 'left'});
}
/**
* Aligns the text to the right of its container.
*/
rightAlignText(): void {
this.setState({textAlignment: 'right'});
}
/**
* Gets the current date format.
* @returns The current date format.
*/
getDateFormat(): DateFormat {
return this.state.dateFormat;
}
/**
* Gets the current text alignment.
* @returns The current text alignment.
*/
getTextAlignment(): TextAlignment {
return this.state.textAlignment;
}
/**
* Gets the list of applied styles.
* @returns A copy of the applied styles array.
*/
getAppliedStyles(): ReadonlyArray<string> {
return this.state.appliedStyles;
}
}