mirror of
https://github.com/pebble-dev/clay.git
synced 2026-08-30 05:46:57 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
627d35fd0a | ||
|
|
ac5bb205aa | ||
|
|
3386e609a8 | ||
|
|
847c651c2b | ||
|
|
f66cba1816 | ||
|
|
2583effe5e | ||
|
|
2e1e5d5d44 | ||
|
|
6c1bcbdb7d | ||
|
|
c5e29ce638 | ||
|
|
7512b6436b | ||
|
|
1b362a366c | ||
|
|
1a8301b0cc |
@@ -22,7 +22,8 @@ jobs:
|
|||||||
- run: uv tool install pebble-tool
|
- run: uv tool install pebble-tool
|
||||||
- run: npm install
|
- run: npm install
|
||||||
- run: npm run build
|
- run: npm run build
|
||||||
|
- run: pebble sdk install 4.9.127
|
||||||
- run: pebble build
|
- run: pebble build
|
||||||
- name: Update npm
|
- name: Update npm
|
||||||
run: npm install -g npm@latest
|
run: npm install -g npm@next-11
|
||||||
- run: npm publish
|
- run: npm publish
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
name: Typecheck CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "main" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
typecheck:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
cache: 'npm'
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run check:types
|
||||||
@@ -15,3 +15,4 @@
|
|||||||
/dist.zip
|
/dist.zip
|
||||||
/dist/
|
/dist/
|
||||||
/build/
|
/build/
|
||||||
|
/dist-types/
|
||||||
|
|||||||
@@ -3,3 +3,4 @@
|
|||||||
!/dist.zip
|
!/dist.zip
|
||||||
!/src/**/*
|
!/src/**/*
|
||||||
!/index.js
|
!/index.js
|
||||||
|
!/index.d.ts
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ Standard text input field.
|
|||||||
| messageKey | string (unique) | The AppMessage key matching the `messageKey` item defined in your `package.json`. Set this to a unique string to allow this item to be looked up using `Clay.getItemsByMessageKey()` in your custom function. You must set this if you wish for the value of this item to be persisted after the user closes the config page. |
|
| messageKey | string (unique) | The AppMessage key matching the `messageKey` item defined in your `package.json`. Set this to a unique string to allow this item to be looked up using `Clay.getItemsByMessageKey()` in your custom function. You must set this if you wish for the value of this item to be persisted after the user closes the config page. |
|
||||||
| label | string | The label that should appear next to this item. |
|
| label | string | The label that should appear next to this item. |
|
||||||
| defaultValue | string | The default value of the input field. |
|
| defaultValue | string | The default value of the input field. |
|
||||||
|
| serializeValueAs | string | target type to serialize value as. `string` means as is via cstring. `integer` means converted with `Math.trunc(Number.parseInt(value, 10))` as int32 (0 if NaN) |
|
||||||
| description | string | Optional sub-text to include below the component |
|
| description | string | Optional sub-text to include below the component |
|
||||||
| attributes | object | An object containing HTML attributes to set on the input field. Set `type` to values such as "email", "time", "date" etc to adjust the behavior of the component. |
|
| attributes | object | An object containing HTML attributes to set on the input field. Set `type` to values such as "email", "time", "date" etc to adjust the behavior of the component. |
|
||||||
| capabilities | array | Array of features that the connected watch must have for this item to be present |
|
| capabilities | array | Array of features that the connected watch must have for this item to be present |
|
||||||
@@ -243,6 +244,7 @@ A dropdown menu containing multiple options.
|
|||||||
| defaultValue | string | The default value of the dropdown menu. Must match a value in the `options` array. |
|
| defaultValue | string | The default value of the dropdown menu. Must match a value in the `options` array. |
|
||||||
| description | string | Optional sub-text to include below the component |
|
| description | string | Optional sub-text to include below the component |
|
||||||
| options | array of objects | The options you want to appear in the dropdown menu. Each option is an object with a `label` and `value` property. |
|
| options | array of objects | The options you want to appear in the dropdown menu. Each option is an object with a `label` and `value` property. |
|
||||||
|
| serializeValueAs | string | target type to serialize value as. `string` means as is via cstring. `integer` means converted with `Math.trunc(Number.parseInt(value, 10))` as int32 (0 if NaN) |
|
||||||
| capabilities | array | Array of features that the connected watch must have for this item to be present |
|
| capabilities | array | Array of features that the connected watch must have for this item to be present |
|
||||||
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
|
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
|
||||||
|
|
||||||
@@ -417,6 +419,7 @@ A list of options allowing the user can only choose one option to submit.
|
|||||||
| defaultValue | string | The default selected item. Must match a value in the `options` array. |
|
| defaultValue | string | The default selected item. Must match a value in the `options` array. |
|
||||||
| description | string | Optional sub-text to include below the component |
|
| description | string | Optional sub-text to include below the component |
|
||||||
| options | array of objects | The options you want to appear in the radio group. Each option is an object with a `label` and `value` property. |
|
| options | array of objects | The options you want to appear in the radio group. Each option is an object with a `label` and `value` property. |
|
||||||
|
| serializeValueAs | string | target type to serialize value as. `string` means as is via cstring. `integer` means converted with `Math.trunc(Number.parseInt(value, 10))` as int32. (0 if NaN) |
|
||||||
| capabilities | array | Array of features that the connected watch must have for this item to be present |
|
| capabilities | array | Array of features that the connected watch must have for this item to be present |
|
||||||
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
|
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
|
||||||
|
|
||||||
@@ -668,9 +671,13 @@ Below is the full list of capabilities
|
|||||||
| PLATFORM_GABBRO | Running on Core Time Round 2 |
|
| PLATFORM_GABBRO | Running on Core Time Round 2 |
|
||||||
| BW | Running on hardware that supports only black and white. |
|
| BW | Running on hardware that supports only black and white. |
|
||||||
| COLOR | Running on hardware that supports 64 colors. |
|
| COLOR | Running on hardware that supports 64 colors. |
|
||||||
|
| COMPASS | Running on hardware that includes a compass. |
|
||||||
| MICROPHONE | Running on hardware that includes a microphone. |
|
| MICROPHONE | Running on hardware that includes a microphone. |
|
||||||
|
| RGB_BACKLIGHT | Running on hardware that includes a RGB backlight. |
|
||||||
| SMARTSTRAP | Running on hardware that includes a smartstrap connector. |
|
| SMARTSTRAP | Running on hardware that includes a smartstrap connector. |
|
||||||
| SMARTSTRAP_POWER | Running on hardware that includes a powered smartstrap connector. |
|
| SMARTSTRAP_POWER | Running on hardware that includes a powered smartstrap connector. |
|
||||||
|
| SPEAKER | Running on hardware that includes a speaker. |
|
||||||
|
| TOUCH | Running on hardware that includes a touch screen. |
|
||||||
| HEALTH | Running on hardware that supports Pebble Health and the HealthService API. |
|
| HEALTH | Running on hardware that supports Pebble Health and the HealthService API. |
|
||||||
| RECT | Running on hardware with a rectangular display. |
|
| RECT | Running on hardware with a rectangular display. |
|
||||||
| ROUND | Running on hardware with a round display. |
|
| ROUND | Running on hardware with a round display. |
|
||||||
|
|||||||
+12
-1
@@ -114,6 +114,17 @@ function taskClay() {
|
|||||||
|
|
||||||
gulp.task('clay', gulp.series('inlineHtml', taskClay));
|
gulp.task('clay', gulp.series('inlineHtml', taskClay));
|
||||||
|
|
||||||
|
// Validates the curated index.d.ts against test/type-checks.ts.
|
||||||
|
// For per-file reference declarations in dist-types/, run: npm run build:types
|
||||||
|
gulp.task('types', function(done) {
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
exec('npx tsc -p tsconfig.typecheck.json', function(err, stdout, stderr) {
|
||||||
|
if (stdout) { console.log(stdout); }
|
||||||
|
if (stderr) { console.error(stderr); }
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
@@ -130,7 +141,7 @@ function taskDevJs() {
|
|||||||
|
|
||||||
gulp.task('dev-js', gulp.series('js', 'sass', taskDevJs));
|
gulp.task('dev-js', gulp.series('js', 'sass', taskDevJs));
|
||||||
|
|
||||||
gulp.task('default', gulp.series('clay'));
|
gulp.task('default', gulp.series('clay', 'types'));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
|||||||
Vendored
+313
@@ -0,0 +1,313 @@
|
|||||||
|
/**
|
||||||
|
* TypeScript declarations for @rebble/clay
|
||||||
|
*
|
||||||
|
* A Pebble configuration framework that provides a simple way to generate a
|
||||||
|
* configuration page for Pebble watchapps and watchfaces.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Minimal DOM wrapper type from minified.js */
|
||||||
|
interface M {
|
||||||
|
[index: number]: HTMLElement;
|
||||||
|
length: number;
|
||||||
|
add(child: M | string): M;
|
||||||
|
set(property: string, value?: unknown): M;
|
||||||
|
get(property: string): unknown;
|
||||||
|
select(selector: string): M;
|
||||||
|
on(events: string, handler: (...args: unknown[]) => void): M;
|
||||||
|
each(callback: (element: HTMLElement, index: number) => void): M;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A Clay config item as provided in the config array */
|
||||||
|
interface ClayConfigItem {
|
||||||
|
type: string;
|
||||||
|
defaultValue?: string | boolean | number;
|
||||||
|
messageKey?: string;
|
||||||
|
id?: string;
|
||||||
|
label?: string;
|
||||||
|
attributes?: Record<string, unknown>;
|
||||||
|
options?: unknown[];
|
||||||
|
serializeValueAs?: string,
|
||||||
|
items?: ClayConfigItem[];
|
||||||
|
capabilities?: string[];
|
||||||
|
group?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A Clay component definition */
|
||||||
|
interface ClayComponent {
|
||||||
|
name: string;
|
||||||
|
template: string;
|
||||||
|
manipulator: string | ClayManipulator;
|
||||||
|
defaults?: Record<string, unknown>;
|
||||||
|
style?: string;
|
||||||
|
initialize?: (this: ClayItem, minified: unknown, clay: ClayConfig) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A manipulator with get and set methods */
|
||||||
|
interface ClayManipulator {
|
||||||
|
get: (this: ClayItem) => unknown;
|
||||||
|
set: (this: ClayItem, value: unknown) => ClayItem;
|
||||||
|
disable?: (this: ClayItem) => ClayItem;
|
||||||
|
enable?: (this: ClayItem) => ClayItem;
|
||||||
|
hide?: (this: ClayItem) => ClayItem;
|
||||||
|
show?: (this: ClayItem) => ClayItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Clay meta information populated from the Pebble object */
|
||||||
|
interface ClayMeta {
|
||||||
|
activeWatchInfo: PebbleActiveWatchInfo | null;
|
||||||
|
accountToken: string;
|
||||||
|
watchToken: string;
|
||||||
|
userData: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Watch info from the Pebble API */
|
||||||
|
interface PebbleActiveWatchInfo {
|
||||||
|
platform: string;
|
||||||
|
model: string;
|
||||||
|
language: string;
|
||||||
|
firmware: {
|
||||||
|
major: number;
|
||||||
|
minor: number;
|
||||||
|
patch: number;
|
||||||
|
suffix: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Options for the Clay constructor */
|
||||||
|
interface ClayOptions {
|
||||||
|
autoHandleEvents?: boolean;
|
||||||
|
userData?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Event methods mixed in by ClayEvents */
|
||||||
|
interface ClayEvents {
|
||||||
|
/**
|
||||||
|
* Attach an event listener.
|
||||||
|
* @param events - a space-separated list of events
|
||||||
|
* @param handler - the event handler
|
||||||
|
*/
|
||||||
|
on(events: string, handler: (...args: unknown[]) => void): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the given event handler from all registered events.
|
||||||
|
* @param handler - the handler to remove
|
||||||
|
*/
|
||||||
|
off(handler: (...args: unknown[]) => void): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger an event.
|
||||||
|
* @param name - a single event name to trigger
|
||||||
|
* @param eventObj - an object to pass to the event handler
|
||||||
|
*/
|
||||||
|
trigger(name: string, eventObj?: unknown): this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A ClayItem represents a single config component in the config page */
|
||||||
|
interface ClayItem extends ClayEvents {
|
||||||
|
/** The item's id from the config, or null */
|
||||||
|
id: string | null;
|
||||||
|
|
||||||
|
/** The item's messageKey from the config, or null */
|
||||||
|
messageKey: string | null;
|
||||||
|
|
||||||
|
/** The raw config for this item */
|
||||||
|
config: ClayConfigItem;
|
||||||
|
|
||||||
|
/** The root DOM element wrapper */
|
||||||
|
$element: M;
|
||||||
|
|
||||||
|
/** The manipulator target DOM element wrapper */
|
||||||
|
$manipulatorTarget: M;
|
||||||
|
|
||||||
|
/** The precision for numeric values */
|
||||||
|
precision?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the component initialiser.
|
||||||
|
* @param clay - the ClayConfig instance
|
||||||
|
*/
|
||||||
|
initialize(clay: ClayConfig): ClayItem;
|
||||||
|
|
||||||
|
/** Get the current value of the item via its manipulator */
|
||||||
|
get(): unknown;
|
||||||
|
|
||||||
|
/** Set the value of the item via its manipulator */
|
||||||
|
set(value: unknown): ClayItem;
|
||||||
|
|
||||||
|
/** Disable the item */
|
||||||
|
disable(): ClayItem;
|
||||||
|
|
||||||
|
/** Enable the item */
|
||||||
|
enable(): ClayItem;
|
||||||
|
|
||||||
|
/** Hide the item */
|
||||||
|
hide(): ClayItem;
|
||||||
|
|
||||||
|
/** Show the item */
|
||||||
|
show(): ClayItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ClayConfig lifecycle event names */
|
||||||
|
interface ClayConfigEvents {
|
||||||
|
readonly BEFORE_BUILD: 'BEFORE_BUILD';
|
||||||
|
readonly AFTER_BUILD: 'AFTER_BUILD';
|
||||||
|
readonly BEFORE_DESTROY: 'BEFORE_DESTROY';
|
||||||
|
readonly AFTER_DESTROY: 'AFTER_DESTROY';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ClayConfig manages the config page and its items */
|
||||||
|
interface ClayConfig extends ClayEvents {
|
||||||
|
/** Meta information from the Pebble object */
|
||||||
|
meta: ClayMeta;
|
||||||
|
|
||||||
|
/** The root container element */
|
||||||
|
$rootContainer: M;
|
||||||
|
|
||||||
|
/** Lifecycle event name constants */
|
||||||
|
EVENTS: ClayConfigEvents;
|
||||||
|
|
||||||
|
/** The config array (may be modified before build) */
|
||||||
|
config: ClayConfigItem | ClayConfigItem[];
|
||||||
|
|
||||||
|
/** Get all items. Must call build() first. */
|
||||||
|
getAllItems(): ClayItem[];
|
||||||
|
|
||||||
|
/** Get an item by its messageKey. Must call build() first. */
|
||||||
|
getItemByMessageKey(messageKey: string): ClayItem;
|
||||||
|
|
||||||
|
/** Get an item by its id. Must call build() first. */
|
||||||
|
getItemById(id: string): ClayItem;
|
||||||
|
|
||||||
|
/** Get all items of a given type. Must call build() first. */
|
||||||
|
getItemsByType(type: string): ClayItem[];
|
||||||
|
|
||||||
|
/** Get all items belonging to a given group. Must call build() first. */
|
||||||
|
getItemsByGroup(group: string): ClayItem[];
|
||||||
|
|
||||||
|
/** Serialise the current settings. Must call build() first. */
|
||||||
|
serialize(): Record<string, { value: unknown; precision?: number }>;
|
||||||
|
|
||||||
|
/** Register a component. Alias for ClayConfig.registerComponent. */
|
||||||
|
registerComponent(component: ClayComponent): boolean;
|
||||||
|
|
||||||
|
/** Destroy the config page and reset items. */
|
||||||
|
destroy(): ClayConfig;
|
||||||
|
|
||||||
|
/** Build the config page. Must be called before get methods. */
|
||||||
|
build(): ClayConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ClayConfigConstructor {
|
||||||
|
new (
|
||||||
|
settings: Record<string, unknown>,
|
||||||
|
config: ClayConfigItem | ClayConfigItem[],
|
||||||
|
$rootContainer: M,
|
||||||
|
meta: ClayMeta
|
||||||
|
): ClayConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a component to Clay. Must be called before build().
|
||||||
|
*/
|
||||||
|
registerComponent(component: ClayComponent): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main Clay constructor.
|
||||||
|
*
|
||||||
|
* @param config - the Clay config array
|
||||||
|
* @param customFn - custom code to run from the config page
|
||||||
|
* @param options - additional options
|
||||||
|
*/
|
||||||
|
declare class Clay {
|
||||||
|
constructor(
|
||||||
|
config: ClayConfigItem[],
|
||||||
|
customFn?: ((this: ClayConfig) => void) | null,
|
||||||
|
options?: ClayOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The Clay config array */
|
||||||
|
config: ClayConfigItem[];
|
||||||
|
|
||||||
|
/** The custom function */
|
||||||
|
customFn: (this: ClayConfig) => void;
|
||||||
|
|
||||||
|
/** Registered components */
|
||||||
|
components: Record<string, ClayComponent>;
|
||||||
|
|
||||||
|
/** Meta information populated from the Pebble object */
|
||||||
|
meta: ClayMeta;
|
||||||
|
|
||||||
|
/** The Clay version string */
|
||||||
|
version: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a component to Clay.
|
||||||
|
* @param component - the clay component to register
|
||||||
|
*/
|
||||||
|
registerComponent(component: ClayComponent): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the Data URI used by the config page with settings injected.
|
||||||
|
*/
|
||||||
|
generateUrl(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the response from the webviewclosed event data.
|
||||||
|
* @param response - the response string
|
||||||
|
* @param convert - if false, return raw settings without conversion
|
||||||
|
*/
|
||||||
|
getSettings(response: string, convert?: boolean): Record<string, unknown>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update settings with the given key/value pair.
|
||||||
|
* @param key - the setting key
|
||||||
|
* @param value - the setting value
|
||||||
|
*/
|
||||||
|
setSettings(key: string, value: unknown): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update settings with the given object.
|
||||||
|
* @param settings - an object of key/value pairs to set
|
||||||
|
*/
|
||||||
|
setSettings(settings: Record<string, unknown>): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode content as a data URI.
|
||||||
|
* @param input - the content to encode
|
||||||
|
* @param prefix - the URI prefix
|
||||||
|
*/
|
||||||
|
static encodeDataUri(input: string, prefix?: string): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a value to a type compatible with Pebble.sendAppMessage().
|
||||||
|
*/
|
||||||
|
static prepareForAppMessage(
|
||||||
|
val: unknown
|
||||||
|
): number | string | (number | string)[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert Clay settings to a format compatible with Pebble.sendAppMessage().
|
||||||
|
*/
|
||||||
|
static prepareSettingsForAppMessage(
|
||||||
|
settings: Record<string, unknown>
|
||||||
|
): Record<number, number | string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare namespace Clay {
|
||||||
|
export {
|
||||||
|
ClayConfigItem,
|
||||||
|
ClayComponent,
|
||||||
|
ClayManipulator,
|
||||||
|
ClayMeta,
|
||||||
|
PebbleActiveWatchInfo,
|
||||||
|
ClayOptions,
|
||||||
|
ClayEvents,
|
||||||
|
ClayItem,
|
||||||
|
ClayConfig,
|
||||||
|
ClayConfigEvents,
|
||||||
|
ClayConfigConstructor,
|
||||||
|
M,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export = Clay;
|
||||||
Generated
+413
-363
File diff suppressed because it is too large
Load Diff
+6
-2
@@ -1,13 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "@rebble/clay",
|
"name": "@rebble/clay",
|
||||||
"version": "1.0.7",
|
"version": "1.1.0",
|
||||||
"description": "Pebble Config Framework",
|
"description": "Pebble Config Framework",
|
||||||
|
"types": "index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test-travis": "./node_modules/.bin/gulp && ./node_modules/.bin/karma start ./test/karma.conf.js --single-run --browsers chromeTravisCI",
|
"test-travis": "./node_modules/.bin/gulp && ./node_modules/.bin/karma start ./test/karma.conf.js --single-run --browsers chromeTravisCI",
|
||||||
"test-debug": "(export DEBUG=true && ./node_modules/.bin/gulp && ./node_modules/.bin/karma start ./test/karma.conf.js --no-single-run)",
|
"test-debug": "(export DEBUG=true && ./node_modules/.bin/gulp && ./node_modules/.bin/karma start ./test/karma.conf.js --no-single-run)",
|
||||||
"test": "./node_modules/.bin/gulp && ./node_modules/.bin/karma start ./test/karma.conf.js --single-run",
|
"test": "./node_modules/.bin/gulp && ./node_modules/.bin/karma start ./test/karma.conf.js --single-run",
|
||||||
"lint": "./node_modules/.bin/eslint ./",
|
"lint": "./node_modules/.bin/eslint ./",
|
||||||
"build": "gulp",
|
"build": "gulp",
|
||||||
|
"build:types": "tsc -p tsconfig.declarations.json",
|
||||||
|
"check:types": "tsc -p tsconfig.typecheck.json",
|
||||||
"dev": "gulp dev",
|
"dev": "gulp dev",
|
||||||
"pebble-clean": "rm -rf tmp src/js/index.js && pebble clean",
|
"pebble-clean": "rm -rf tmp src/js/index.js && pebble clean",
|
||||||
"pebble-publish": "npm run pebble-clean && npm run build && pebble build && pebble package publish && npm run pebble-clean",
|
"pebble-publish": "npm run pebble-clean && npm run build && pebble build && pebble package publish && npm run pebble-clean",
|
||||||
@@ -78,13 +81,14 @@
|
|||||||
"karma-source-map-support": "^1.4.0",
|
"karma-source-map-support": "^1.4.0",
|
||||||
"karma-threshold-reporter": "^0.1.15",
|
"karma-threshold-reporter": "^0.1.15",
|
||||||
"mocha": "^11.7.5",
|
"mocha": "^11.7.5",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "8.5.6",
|
||||||
"require-from-string": "^2.0.2",
|
"require-from-string": "^2.0.2",
|
||||||
"sass": "^1.94.2",
|
"sass": "^1.94.2",
|
||||||
"sinon": "^1.17.3",
|
"sinon": "^1.17.3",
|
||||||
"stringify": "^3.2.0",
|
"stringify": "^3.2.0",
|
||||||
"through": "^2.3.8",
|
"through": "^2.3.8",
|
||||||
"tosource": "^1.0.0",
|
"tosource": "^1.0.0",
|
||||||
|
"typescript": "6.0.2",
|
||||||
"vinyl-buffer": "^1.0.0",
|
"vinyl-buffer": "^1.0.0",
|
||||||
"vinyl-source-stream": "^2.0.0",
|
"vinyl-source-stream": "^2.0.0",
|
||||||
"watchify": "^3.11.1"
|
"watchify": "^3.11.1"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ module.exports = {
|
|||||||
manipulator: 'val',
|
manipulator: 'val',
|
||||||
defaults: {
|
defaults: {
|
||||||
label: '',
|
label: '',
|
||||||
|
serializeValueAs: 'string',
|
||||||
description: '',
|
description: '',
|
||||||
attributes: {}
|
attributes: {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ module.exports = {
|
|||||||
defaults: {
|
defaults: {
|
||||||
label: '',
|
label: '',
|
||||||
options: [],
|
options: [],
|
||||||
|
serializeValueAs: 'string',
|
||||||
description: '',
|
description: '',
|
||||||
attributes: {}
|
attributes: {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ module.exports = {
|
|||||||
defaults: {
|
defaults: {
|
||||||
label: '',
|
label: '',
|
||||||
options: [],
|
options: [],
|
||||||
|
serializeValueAs: 'string',
|
||||||
description: '',
|
description: '',
|
||||||
attributes: {}
|
attributes: {}
|
||||||
},
|
},
|
||||||
@@ -17,7 +18,7 @@ module.exports = {
|
|||||||
var $value = self.$element.select('.value');
|
var $value = self.$element.select('.value');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the HTML value of the component to match the slected option's label
|
* Updates the HTML value of the component to match the selected option's label
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function setValueDisplay() {
|
function setValueDisplay() {
|
||||||
|
|||||||
@@ -73,10 +73,19 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
val: {
|
val: {
|
||||||
get: function() {
|
get: function() {
|
||||||
return this.$manipulatorTarget.get('value');
|
let value = this.$manipulatorTarget.get('value');
|
||||||
|
switch (this.config.serializeValueAs) {
|
||||||
|
case 'integer':
|
||||||
|
let integerValue = Math.trunc(Number.parseInt(value, 10));
|
||||||
|
return Number.isNaN(integerValue) ? 0 : integerValue;
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
set: function(value) {
|
set: function(value) {
|
||||||
if (this.get() === value.toString(10)) { return this; }
|
let currentValue = this.$manipulatorTarget.get('value');
|
||||||
|
if (typeof currentValue !== 'undefined' &&
|
||||||
|
currentValue === value.toString(10)) { return this; }
|
||||||
this.$manipulatorTarget.set('value', value);
|
this.$manipulatorTarget.set('value', value);
|
||||||
return this.trigger('change');
|
return this.trigger('change');
|
||||||
},
|
},
|
||||||
@@ -116,12 +125,21 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
radiogroup: {
|
radiogroup: {
|
||||||
get: function() {
|
get: function() {
|
||||||
return this.$element.select('input:checked').get('value');
|
let value = this.$element.select('input:checked').get('value');
|
||||||
|
switch (this.config.serializeValueAs) {
|
||||||
|
case 'integer':
|
||||||
|
let integerValue = Math.trunc(Number.parseInt(value, 10));
|
||||||
|
return Number.isNaN(integerValue) ? 0 : integerValue;
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
set: function(value) {
|
set: function(value) {
|
||||||
if (this.get() === value.toString(10)) { return this; }
|
let currentValue = this.$element.select('input:checked').get('value');
|
||||||
|
if (typeof currentValue !== 'undefined' &&
|
||||||
|
currentValue === value.toString(10)) { return this; }
|
||||||
this.$element
|
this.$element
|
||||||
.select('input[value="' + value.replace('"', '\\"') + '"]')
|
.select('input[value="' + value.toString(10).replace('"', '\\"') + '"]')
|
||||||
.set('checked', true);
|
.set('checked', true);
|
||||||
return this.trigger('change');
|
return this.trigger('change');
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -64,11 +64,21 @@ module.exports.capabilityMap = {
|
|||||||
minFwMajor: 0,
|
minFwMajor: 0,
|
||||||
minFwMinor: 0
|
minFwMinor: 0
|
||||||
},
|
},
|
||||||
|
COMPASS: {
|
||||||
|
platforms: ['aplite', 'basalt', 'chalk', 'emery', 'flint', 'gabbro'],
|
||||||
|
minFwMajor: 0,
|
||||||
|
minFwMinor: 0
|
||||||
|
},
|
||||||
MICROPHONE: {
|
MICROPHONE: {
|
||||||
platforms: ['basalt', 'chalk', 'diorite', 'emery', 'flint', 'gabbro'],
|
platforms: ['basalt', 'chalk', 'diorite', 'emery', 'flint', 'gabbro'],
|
||||||
minFwMajor: 0,
|
minFwMajor: 0,
|
||||||
minFwMinor: 0
|
minFwMinor: 0
|
||||||
},
|
},
|
||||||
|
RGB_BACKLIGHT: {
|
||||||
|
platforms: ['emery'],
|
||||||
|
minFwMajor: 4,
|
||||||
|
minFwMinor: 9
|
||||||
|
},
|
||||||
SMARTSTRAP: {
|
SMARTSTRAP: {
|
||||||
platforms: ['basalt', 'chalk', 'diorite', 'emery'],
|
platforms: ['basalt', 'chalk', 'diorite', 'emery'],
|
||||||
minFwMajor: 3,
|
minFwMajor: 3,
|
||||||
@@ -79,6 +89,16 @@ module.exports.capabilityMap = {
|
|||||||
minFwMajor: 3,
|
minFwMajor: 3,
|
||||||
minFwMinor: 4
|
minFwMinor: 4
|
||||||
},
|
},
|
||||||
|
SPEAKER: {
|
||||||
|
platforms: ['emery', 'flint'],
|
||||||
|
minFwMajor: 4,
|
||||||
|
minFwMinor: 9
|
||||||
|
},
|
||||||
|
TOUCH: {
|
||||||
|
platforms: ['emery', 'gabbro'],
|
||||||
|
minFwMajor: 4,
|
||||||
|
minFwMinor: 9
|
||||||
|
},
|
||||||
HEALTH: {
|
HEALTH: {
|
||||||
platforms: ['basalt', 'chalk', 'diorite', 'emery', 'flint', 'gabbro'],
|
platforms: ['basalt', 'chalk', 'diorite', 'emery', 'flint', 'gabbro'],
|
||||||
minFwMajor: 3,
|
minFwMajor: 3,
|
||||||
|
|||||||
@@ -78,9 +78,13 @@ describe('ClayConfig', function() {
|
|||||||
describe('capability filtering', function() {
|
describe('capability filtering', function() {
|
||||||
testCapabilities('aplite', 2, 9, ['BW'], 1);
|
testCapabilities('aplite', 2, 9, ['BW'], 1);
|
||||||
testCapabilities('aplite', 2, 9, ['COLOR'], 0);
|
testCapabilities('aplite', 2, 9, ['COLOR'], 0);
|
||||||
|
testCapabilities('aplite', 2, 9, ['COMPASS'], 1);
|
||||||
testCapabilities('aplite', 2, 9, ['MICROPHONE'], 0);
|
testCapabilities('aplite', 2, 9, ['MICROPHONE'], 0);
|
||||||
|
testCapabilities('aplite', 2, 9, ['RGB_BACKLIGHT'], 0);
|
||||||
testCapabilities('aplite', 2, 9, ['SMARTSTRAP'], 0);
|
testCapabilities('aplite', 2, 9, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('aplite', 2, 9, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('aplite', 2, 9, ['SMARTSTRAP_POWER'], 0);
|
||||||
|
testCapabilities('aplite', 2, 9, ['SPEAKER'], 0);
|
||||||
|
testCapabilities('aplite', 2, 9, ['TOUCH'], 0);
|
||||||
testCapabilities('aplite', 2, 9, ['HEALTH'], 0);
|
testCapabilities('aplite', 2, 9, ['HEALTH'], 0);
|
||||||
testCapabilities('aplite', 2, 9, ['RECT'], 1);
|
testCapabilities('aplite', 2, 9, ['RECT'], 1);
|
||||||
testCapabilities('aplite', 2, 9, ['ROUND'], 0);
|
testCapabilities('aplite', 2, 9, ['ROUND'], 0);
|
||||||
@@ -98,11 +102,15 @@ describe('ClayConfig', function() {
|
|||||||
|
|
||||||
testCapabilities('aplite', 3, 10, ['BW'], 1);
|
testCapabilities('aplite', 3, 10, ['BW'], 1);
|
||||||
testCapabilities('aplite', 3, 10, ['COLOR'], 0);
|
testCapabilities('aplite', 3, 10, ['COLOR'], 0);
|
||||||
|
testCapabilities('aplite', 3, 10, ['COMPASS'], 1);
|
||||||
testCapabilities('aplite', 3, 10, ['MICROPHONE'], 0);
|
testCapabilities('aplite', 3, 10, ['MICROPHONE'], 0);
|
||||||
|
testCapabilities('aplite', 3, 10, ['RGB_BACKLIGHT'], 0);
|
||||||
testCapabilities('aplite', 3, 10, ['SMARTSTRAP'], 0);
|
testCapabilities('aplite', 3, 10, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('aplite', 3, 4, ['SMARTSTRAP'], 0);
|
testCapabilities('aplite', 3, 4, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('aplite', 3, 3, ['SMARTSTRAP'], 0);
|
testCapabilities('aplite', 3, 3, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('aplite', 3, 10, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('aplite', 3, 10, ['SMARTSTRAP_POWER'], 0);
|
||||||
|
testCapabilities('aplite', 3, 10, ['SPEAKER'], 0);
|
||||||
|
testCapabilities('aplite', 3, 10, ['TOUCH'], 0);
|
||||||
testCapabilities('aplite', 3, 10, ['HEALTH'], 0);
|
testCapabilities('aplite', 3, 10, ['HEALTH'], 0);
|
||||||
testCapabilities('aplite', 3, 9, ['HEALTH'], 0);
|
testCapabilities('aplite', 3, 9, ['HEALTH'], 0);
|
||||||
testCapabilities('aplite', 3, 10, ['RECT'], 1);
|
testCapabilities('aplite', 3, 10, ['RECT'], 1);
|
||||||
@@ -121,13 +129,17 @@ describe('ClayConfig', function() {
|
|||||||
|
|
||||||
testCapabilities('basalt', 3, 10, ['BW'], 0);
|
testCapabilities('basalt', 3, 10, ['BW'], 0);
|
||||||
testCapabilities('basalt', 3, 10, ['COLOR'], 1);
|
testCapabilities('basalt', 3, 10, ['COLOR'], 1);
|
||||||
|
testCapabilities('basalt', 3, 10, ['COMPASS'], 1);
|
||||||
testCapabilities('basalt', 3, 10, ['MICROPHONE'], 1);
|
testCapabilities('basalt', 3, 10, ['MICROPHONE'], 1);
|
||||||
|
testCapabilities('basalt', 3, 3, ['RGB_BACKLIGHT'], 0);
|
||||||
testCapabilities('basalt', 3, 10, ['SMARTSTRAP'], 1);
|
testCapabilities('basalt', 3, 10, ['SMARTSTRAP'], 1);
|
||||||
testCapabilities('basalt', 3, 4, ['SMARTSTRAP'], 1);
|
testCapabilities('basalt', 3, 4, ['SMARTSTRAP'], 1);
|
||||||
testCapabilities('basalt', 3, 3, ['SMARTSTRAP'], 0);
|
testCapabilities('basalt', 3, 3, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('basalt', 3, 10, ['SMARTSTRAP_POWER'], 1);
|
testCapabilities('basalt', 3, 10, ['SMARTSTRAP_POWER'], 1);
|
||||||
testCapabilities('basalt', 3, 4, ['SMARTSTRAP_POWER'], 1);
|
testCapabilities('basalt', 3, 4, ['SMARTSTRAP_POWER'], 1);
|
||||||
testCapabilities('basalt', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('basalt', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
||||||
|
testCapabilities('basalt', 3, 3, ['SPEAKER'], 0);
|
||||||
|
testCapabilities('basalt', 3, 3, ['TOUCH'], 0);
|
||||||
testCapabilities('basalt', 3, 10, ['HEALTH'], 1);
|
testCapabilities('basalt', 3, 10, ['HEALTH'], 1);
|
||||||
testCapabilities('basalt', 3, 9, ['HEALTH'], 0);
|
testCapabilities('basalt', 3, 9, ['HEALTH'], 0);
|
||||||
testCapabilities('basalt', 3, 10, ['RECT'], 1);
|
testCapabilities('basalt', 3, 10, ['RECT'], 1);
|
||||||
@@ -146,13 +158,17 @@ describe('ClayConfig', function() {
|
|||||||
|
|
||||||
testCapabilities('chalk', 3, 10, ['BW'], 0);
|
testCapabilities('chalk', 3, 10, ['BW'], 0);
|
||||||
testCapabilities('chalk', 3, 10, ['COLOR'], 1);
|
testCapabilities('chalk', 3, 10, ['COLOR'], 1);
|
||||||
|
testCapabilities('chalk', 3, 10, ['COMPASS'], 1);
|
||||||
testCapabilities('chalk', 3, 10, ['MICROPHONE'], 1);
|
testCapabilities('chalk', 3, 10, ['MICROPHONE'], 1);
|
||||||
|
testCapabilities('chalk', 3, 3, ['RGB_BACKLIGHT'], 0);
|
||||||
testCapabilities('chalk', 3, 10, ['SMARTSTRAP'], 1);
|
testCapabilities('chalk', 3, 10, ['SMARTSTRAP'], 1);
|
||||||
testCapabilities('chalk', 3, 4, ['SMARTSTRAP'], 1);
|
testCapabilities('chalk', 3, 4, ['SMARTSTRAP'], 1);
|
||||||
testCapabilities('chalk', 3, 3, ['SMARTSTRAP'], 0);
|
testCapabilities('chalk', 3, 3, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('chalk', 3, 10, ['SMARTSTRAP_POWER'], 1);
|
testCapabilities('chalk', 3, 10, ['SMARTSTRAP_POWER'], 1);
|
||||||
testCapabilities('chalk', 3, 4, ['SMARTSTRAP_POWER'], 1);
|
testCapabilities('chalk', 3, 4, ['SMARTSTRAP_POWER'], 1);
|
||||||
testCapabilities('chalk', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('chalk', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
||||||
|
testCapabilities('chalk', 3, 3, ['SPEAKER'], 0);
|
||||||
|
testCapabilities('chalk', 3, 3, ['TOUCH'], 0);
|
||||||
testCapabilities('chalk', 3, 10, ['HEALTH'], 1);
|
testCapabilities('chalk', 3, 10, ['HEALTH'], 1);
|
||||||
testCapabilities('chalk', 3, 9, ['HEALTH'], 0);
|
testCapabilities('chalk', 3, 9, ['HEALTH'], 0);
|
||||||
testCapabilities('chalk', 3, 10, ['RECT'], 0);
|
testCapabilities('chalk', 3, 10, ['RECT'], 0);
|
||||||
@@ -171,13 +187,17 @@ describe('ClayConfig', function() {
|
|||||||
|
|
||||||
testCapabilities('diorite', 3, 10, ['BW'], 1);
|
testCapabilities('diorite', 3, 10, ['BW'], 1);
|
||||||
testCapabilities('diorite', 3, 10, ['COLOR'], 0);
|
testCapabilities('diorite', 3, 10, ['COLOR'], 0);
|
||||||
|
testCapabilities('diorite', 3, 10, ['COMPASS'], 0);
|
||||||
testCapabilities('diorite', 3, 10, ['MICROPHONE'], 1);
|
testCapabilities('diorite', 3, 10, ['MICROPHONE'], 1);
|
||||||
|
testCapabilities('diorite', 3, 3, ['RGB_BACKLIGHT'], 0);
|
||||||
testCapabilities('diorite', 3, 10, ['SMARTSTRAP'], 1);
|
testCapabilities('diorite', 3, 10, ['SMARTSTRAP'], 1);
|
||||||
testCapabilities('diorite', 3, 4, ['SMARTSTRAP'], 1);
|
testCapabilities('diorite', 3, 4, ['SMARTSTRAP'], 1);
|
||||||
testCapabilities('diorite', 3, 3, ['SMARTSTRAP'], 0);
|
testCapabilities('diorite', 3, 3, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('diorite', 3, 10, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('diorite', 3, 10, ['SMARTSTRAP_POWER'], 0);
|
||||||
testCapabilities('diorite', 3, 4, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('diorite', 3, 4, ['SMARTSTRAP_POWER'], 0);
|
||||||
testCapabilities('diorite', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('diorite', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
||||||
|
testCapabilities('diorite', 3, 3, ['SPEAKER'], 0);
|
||||||
|
testCapabilities('diorite', 3, 3, ['TOUCH'], 0);
|
||||||
testCapabilities('diorite', 3, 10, ['HEALTH'], 1);
|
testCapabilities('diorite', 3, 10, ['HEALTH'], 1);
|
||||||
testCapabilities('diorite', 3, 9, ['HEALTH'], 0);
|
testCapabilities('diorite', 3, 9, ['HEALTH'], 0);
|
||||||
testCapabilities('diorite', 3, 10, ['RECT'], 1);
|
testCapabilities('diorite', 3, 10, ['RECT'], 1);
|
||||||
@@ -196,13 +216,17 @@ describe('ClayConfig', function() {
|
|||||||
|
|
||||||
testCapabilities('emery', 3, 10, ['BW'], 0);
|
testCapabilities('emery', 3, 10, ['BW'], 0);
|
||||||
testCapabilities('emery', 3, 10, ['COLOR'], 1);
|
testCapabilities('emery', 3, 10, ['COLOR'], 1);
|
||||||
|
testCapabilities('emery', 3, 10, ['COMPASS'], 1);
|
||||||
testCapabilities('emery', 3, 10, ['MICROPHONE'], 1);
|
testCapabilities('emery', 3, 10, ['MICROPHONE'], 1);
|
||||||
|
testCapabilities('emery', 4, 10, ['RGB_BACKLIGHT'], 1);
|
||||||
testCapabilities('emery', 3, 10, ['SMARTSTRAP'], 1);
|
testCapabilities('emery', 3, 10, ['SMARTSTRAP'], 1);
|
||||||
testCapabilities('emery', 3, 4, ['SMARTSTRAP'], 1);
|
testCapabilities('emery', 3, 4, ['SMARTSTRAP'], 1);
|
||||||
testCapabilities('emery', 3, 3, ['SMARTSTRAP'], 0);
|
testCapabilities('emery', 3, 3, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('emery', 3, 10, ['SMARTSTRAP_POWER'], 1);
|
testCapabilities('emery', 3, 10, ['SMARTSTRAP_POWER'], 1);
|
||||||
testCapabilities('emery', 3, 4, ['SMARTSTRAP_POWER'], 1);
|
testCapabilities('emery', 3, 4, ['SMARTSTRAP_POWER'], 1);
|
||||||
testCapabilities('emery', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('emery', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
||||||
|
testCapabilities('emery', 4, 10, ['SPEAKER'], 1);
|
||||||
|
testCapabilities('emery', 4, 10, ['TOUCH'], 1);
|
||||||
testCapabilities('emery', 3, 10, ['HEALTH'], 1);
|
testCapabilities('emery', 3, 10, ['HEALTH'], 1);
|
||||||
testCapabilities('emery', 3, 9, ['HEALTH'], 0);
|
testCapabilities('emery', 3, 9, ['HEALTH'], 0);
|
||||||
testCapabilities('emery', 3, 10, ['RECT'], 1);
|
testCapabilities('emery', 3, 10, ['RECT'], 1);
|
||||||
@@ -221,13 +245,17 @@ describe('ClayConfig', function() {
|
|||||||
|
|
||||||
testCapabilities('flint', 3, 10, ['BW'], 1);
|
testCapabilities('flint', 3, 10, ['BW'], 1);
|
||||||
testCapabilities('flint', 3, 10, ['COLOR'], 0);
|
testCapabilities('flint', 3, 10, ['COLOR'], 0);
|
||||||
|
testCapabilities('flint', 3, 10, ['COMPASS'], 1);
|
||||||
testCapabilities('flint', 3, 10, ['MICROPHONE'], 1);
|
testCapabilities('flint', 3, 10, ['MICROPHONE'], 1);
|
||||||
|
testCapabilities('flint', 3, 3, ['RGB_BACKLIGHT'], 0);
|
||||||
testCapabilities('flint', 3, 10, ['SMARTSTRAP'], 0);
|
testCapabilities('flint', 3, 10, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('flint', 3, 4, ['SMARTSTRAP'], 0);
|
testCapabilities('flint', 3, 4, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('flint', 3, 3, ['SMARTSTRAP'], 0);
|
testCapabilities('flint', 3, 3, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('flint', 3, 10, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('flint', 3, 10, ['SMARTSTRAP_POWER'], 0);
|
||||||
testCapabilities('flint', 3, 4, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('flint', 3, 4, ['SMARTSTRAP_POWER'], 0);
|
||||||
testCapabilities('flint', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('flint', 3, 3, ['SMARTSTRAP_POWER'], 0);
|
||||||
|
testCapabilities('flint', 4, 10, ['SPEAKER'], 1);
|
||||||
|
testCapabilities('flint', 4, 10, ['TOUCH'], 0);
|
||||||
testCapabilities('flint', 3, 10, ['HEALTH'], 1);
|
testCapabilities('flint', 3, 10, ['HEALTH'], 1);
|
||||||
testCapabilities('flint', 3, 9, ['HEALTH'], 0);
|
testCapabilities('flint', 3, 9, ['HEALTH'], 0);
|
||||||
testCapabilities('flint', 3, 10, ['RECT'], 1);
|
testCapabilities('flint', 3, 10, ['RECT'], 1);
|
||||||
@@ -246,9 +274,13 @@ describe('ClayConfig', function() {
|
|||||||
|
|
||||||
testCapabilities('gabbro', 3, 10, ['BW'], 0);
|
testCapabilities('gabbro', 3, 10, ['BW'], 0);
|
||||||
testCapabilities('gabbro', 3, 10, ['COLOR'], 1);
|
testCapabilities('gabbro', 3, 10, ['COLOR'], 1);
|
||||||
|
testCapabilities('gabbro', 3, 10, ['COMPASS'], 1);
|
||||||
testCapabilities('gabbro', 3, 10, ['MICROPHONE'], 1);
|
testCapabilities('gabbro', 3, 10, ['MICROPHONE'], 1);
|
||||||
|
testCapabilities('gabbro', 3, 10, ['RGB_BACKLIGHT'], 0);
|
||||||
testCapabilities('gabbro', 3, 10, ['SMARTSTRAP'], 0);
|
testCapabilities('gabbro', 3, 10, ['SMARTSTRAP'], 0);
|
||||||
testCapabilities('gabbro', 3, 10, ['SMARTSTRAP_POWER'], 0);
|
testCapabilities('gabbro', 3, 10, ['SMARTSTRAP_POWER'], 0);
|
||||||
|
testCapabilities('gabbro', 3, 10, ['SPEAKER'], 0);
|
||||||
|
testCapabilities('gabbro', 4, 10, ['TOUCH'], 1);
|
||||||
testCapabilities('gabbro', 3, 10, ['HEALTH'], 1);
|
testCapabilities('gabbro', 3, 10, ['HEALTH'], 1);
|
||||||
testCapabilities('gabbro', 3, 10, ['RECT'], 0);
|
testCapabilities('gabbro', 3, 10, ['RECT'], 0);
|
||||||
testCapabilities('gabbro', 3, 10, ['ROUND'], 1);
|
testCapabilities('gabbro', 3, 10, ['ROUND'], 1);
|
||||||
|
|||||||
@@ -161,13 +161,63 @@ describe('manipulators', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('val', function() {
|
describe('val', function() {
|
||||||
var type = 'input';
|
let stringInputType = {
|
||||||
testSetGet(type, 'test321');
|
type: 'input',
|
||||||
testSetGet(type, 1234, '1234');
|
serializeValueAs: 'string'
|
||||||
testDisable(type);
|
};
|
||||||
testEnable(type);
|
|
||||||
testShow(type);
|
let integerInputType = {
|
||||||
testHide(type);
|
type: 'input',
|
||||||
|
serializeValueAs: 'integer'
|
||||||
|
};
|
||||||
|
|
||||||
|
let stringSelectType = {
|
||||||
|
type: 'select',
|
||||||
|
defaultValue: 'value-1',
|
||||||
|
options: [
|
||||||
|
{ label: 'label 1', value: '1' },
|
||||||
|
{ label: 'label 2', value: '2' }],
|
||||||
|
serializeValueAs: 'string'
|
||||||
|
};
|
||||||
|
|
||||||
|
let integerSelectType = {
|
||||||
|
type: 'select',
|
||||||
|
defaultValue: 'value-1',
|
||||||
|
options: [
|
||||||
|
{ label: 'label 1', value: '1' },
|
||||||
|
{ label: 'label 2', value: '2' }],
|
||||||
|
serializeValueAs: 'integer'
|
||||||
|
};
|
||||||
|
|
||||||
|
testSetGet(stringInputType, 'test321');
|
||||||
|
testSetGet(stringInputType, 1234, '1234');
|
||||||
|
testSetGet(integerInputType, 'test321', 0);
|
||||||
|
testSetGet(integerInputType, 1234);
|
||||||
|
|
||||||
|
testSetGet(stringSelectType, '1');
|
||||||
|
testSetGet(stringSelectType, 2, '2');
|
||||||
|
testSetGet(integerSelectType, 1);
|
||||||
|
testSetGet(integerSelectType, '2', 2);
|
||||||
|
|
||||||
|
testDisable(stringInputType);
|
||||||
|
testDisable(integerInputType);
|
||||||
|
testDisable(stringSelectType);
|
||||||
|
testDisable(integerSelectType);
|
||||||
|
|
||||||
|
testEnable(stringInputType);
|
||||||
|
testEnable(integerInputType);
|
||||||
|
testEnable(stringSelectType);
|
||||||
|
testEnable(integerSelectType);
|
||||||
|
|
||||||
|
testHide(stringInputType);
|
||||||
|
testHide(integerInputType);
|
||||||
|
testHide(stringSelectType);
|
||||||
|
testHide(integerSelectType);
|
||||||
|
|
||||||
|
testShow(stringInputType);
|
||||||
|
testShow(integerInputType);
|
||||||
|
testShow(stringSelectType);
|
||||||
|
testShow(integerSelectType);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('slider', function() {
|
describe('slider', function() {
|
||||||
@@ -203,22 +253,54 @@ describe('manipulators', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('radiogroup', function() {
|
describe('radiogroup', function() {
|
||||||
var type = {
|
var stringType = {
|
||||||
type: 'radiogroup',
|
type: 'radiogroup',
|
||||||
clayId: 1,
|
clayId: 1,
|
||||||
options: [
|
options: [
|
||||||
{ label: '1', value: 'one' },
|
{ label: '1', value: 'one' },
|
||||||
{ label: '2', value: 'two' },
|
{ label: '2', value: 'two' },
|
||||||
{ label: '3', value: 'three "quote' }
|
{ label: '3', value: 'three "quote' },
|
||||||
]
|
{ label: '4', value: 4 },
|
||||||
|
{ label: '5', value: '5 with text after' },
|
||||||
|
{ label: '5', value: '6.5' }
|
||||||
|
],
|
||||||
|
serializeValueAs: 'string'
|
||||||
};
|
};
|
||||||
testSetGet(type, 'one');
|
|
||||||
testSetGet(type, 'two');
|
var integerType = {
|
||||||
testSetGet(type, 'three "quote');
|
type: 'radiogroup',
|
||||||
testDisable(type);
|
clayId: 1,
|
||||||
testEnable(type);
|
options: [
|
||||||
testShow(type);
|
{ label: '1', value: 'one' },
|
||||||
testHide(type);
|
{ label: '2', value: 'two' },
|
||||||
|
{ label: '3', value: 'three "quote' },
|
||||||
|
{ label: '4', value: 4 },
|
||||||
|
{ label: '5', value: '5 with text after' },
|
||||||
|
{ label: '5', value: '6.5' }
|
||||||
|
],
|
||||||
|
serializeValueAs: 'integer'
|
||||||
|
};
|
||||||
|
|
||||||
|
testSetGet(stringType, 'one');
|
||||||
|
testSetGet(stringType, 'two');
|
||||||
|
testSetGet(stringType, 'three "quote');
|
||||||
|
testSetGet(stringType, '4');
|
||||||
|
testSetGet(stringType, '5 with text after');
|
||||||
|
testSetGet(stringType, '6.5');
|
||||||
|
testSetGet(integerType, 'one', 0);
|
||||||
|
testSetGet(integerType, 'two', 0);
|
||||||
|
testSetGet(integerType, 'three "quote', 0);
|
||||||
|
testSetGet(integerType, 4, 4);
|
||||||
|
testSetGet(integerType, '5 with text after', 5);
|
||||||
|
testSetGet(integerType, '6.5', 6);
|
||||||
|
testDisable(stringType);
|
||||||
|
testDisable(integerType);
|
||||||
|
testEnable(stringType);
|
||||||
|
testEnable(integerType);
|
||||||
|
testShow(stringType);
|
||||||
|
testShow(integerType);
|
||||||
|
testHide(stringType);
|
||||||
|
testHide(integerType);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('checkboxgroup', function() {
|
describe('checkboxgroup', function() {
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
import Clay = require('../index');
|
||||||
|
|
||||||
|
// --- Exported types are accessible via the Clay namespace ---
|
||||||
|
|
||||||
|
const configItem: Clay.ClayConfigItem = {
|
||||||
|
type: 'input',
|
||||||
|
messageKey: 'name',
|
||||||
|
defaultValue: '',
|
||||||
|
label: 'Name',
|
||||||
|
attributes: { placeholder: 'Enter name' },
|
||||||
|
capabilities: ['COLOR'],
|
||||||
|
group: 'appearance',
|
||||||
|
};
|
||||||
|
|
||||||
|
const meta: Clay.ClayMeta = {
|
||||||
|
activeWatchInfo: {
|
||||||
|
platform: 'basalt',
|
||||||
|
model: 'qemu_platform_basalt',
|
||||||
|
language: 'en_US',
|
||||||
|
firmware: { major: 4, minor: 3, patch: 0, suffix: '' },
|
||||||
|
},
|
||||||
|
accountToken: 'abc',
|
||||||
|
watchToken: 'def',
|
||||||
|
userData: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const options: Clay.ClayOptions = {
|
||||||
|
autoHandleEvents: true,
|
||||||
|
userData: { foo: 'bar' },
|
||||||
|
};
|
||||||
|
|
||||||
|
const manipulator: Clay.ClayManipulator = {
|
||||||
|
get() { return this.$manipulatorTarget.get('value'); },
|
||||||
|
set(value) {
|
||||||
|
this.$manipulatorTarget.set('value', value);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
disable() { return this; },
|
||||||
|
enable() { return this; },
|
||||||
|
hide() { return this; },
|
||||||
|
show() { return this; },
|
||||||
|
};
|
||||||
|
|
||||||
|
const component: Clay.ClayComponent = {
|
||||||
|
name: 'my-component',
|
||||||
|
template: '<div></div>',
|
||||||
|
manipulator,
|
||||||
|
defaults: { label: 'Default' },
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Constructor ---
|
||||||
|
|
||||||
|
const clay = new Clay(
|
||||||
|
[configItem, { type: 'heading', defaultValue: 'My App' }],
|
||||||
|
function() {
|
||||||
|
// `this` is ClayConfig — verify event methods
|
||||||
|
const self: Clay.ClayConfig = this;
|
||||||
|
|
||||||
|
const handler = (..._args: unknown[]) => {};
|
||||||
|
this.on('AFTER_BUILD', handler);
|
||||||
|
this.off(handler);
|
||||||
|
this.trigger('AFTER_BUILD');
|
||||||
|
|
||||||
|
// Verify chaining returns the same type
|
||||||
|
this.on('BEFORE_BUILD', handler).off(handler);
|
||||||
|
|
||||||
|
// Verify EVENTS constants
|
||||||
|
const events: Clay.ClayConfigEvents = this.EVENTS;
|
||||||
|
const beforeBuild: 'BEFORE_BUILD' = events.BEFORE_BUILD;
|
||||||
|
const afterBuild: 'AFTER_BUILD' = events.AFTER_BUILD;
|
||||||
|
const beforeDestroy: 'BEFORE_DESTROY' = events.BEFORE_DESTROY;
|
||||||
|
const afterDestroy: 'AFTER_DESTROY' = events.AFTER_DESTROY;
|
||||||
|
|
||||||
|
// Verify build/destroy return ClayConfig for chaining
|
||||||
|
this.build().destroy().build();
|
||||||
|
|
||||||
|
// Verify item getters
|
||||||
|
const allItems: Clay.ClayItem[] = this.getAllItems();
|
||||||
|
const byKey: Clay.ClayItem = this.getItemByMessageKey('bg_color');
|
||||||
|
const byId: Clay.ClayItem = this.getItemById('my-id');
|
||||||
|
const byType: Clay.ClayItem[] = this.getItemsByType('color');
|
||||||
|
const byGroup: Clay.ClayItem[] = this.getItemsByGroup('appearance');
|
||||||
|
|
||||||
|
// Verify ClayItem properties
|
||||||
|
const item = byKey;
|
||||||
|
const itemId: string | null = item.id;
|
||||||
|
const itemMsgKey: string | null = item.messageKey;
|
||||||
|
const itemConfig: Clay.ClayConfigItem = item.config;
|
||||||
|
const $el: Clay.M = item.$element;
|
||||||
|
const $target: Clay.M = item.$manipulatorTarget;
|
||||||
|
|
||||||
|
// Verify ClayItem manipulator methods
|
||||||
|
const value: unknown = item.get();
|
||||||
|
const afterSet: Clay.ClayItem = item.set('new value');
|
||||||
|
const afterDisable: Clay.ClayItem = item.disable();
|
||||||
|
const afterEnable: Clay.ClayItem = item.enable();
|
||||||
|
const afterHide: Clay.ClayItem = item.hide();
|
||||||
|
const afterShow: Clay.ClayItem = item.show();
|
||||||
|
|
||||||
|
// Verify ClayItem event methods
|
||||||
|
item.on('change', handler).off(handler);
|
||||||
|
item.trigger('change');
|
||||||
|
|
||||||
|
// Verify ClayItem initialize
|
||||||
|
const afterInit: Clay.ClayItem = item.initialize(this);
|
||||||
|
|
||||||
|
// Verify serialize
|
||||||
|
const serialised: Record<string, { value: unknown; precision?: number }> =
|
||||||
|
this.serialize();
|
||||||
|
|
||||||
|
// Verify meta
|
||||||
|
const configMeta: Clay.ClayMeta = this.meta;
|
||||||
|
|
||||||
|
// Verify registerComponent on instance
|
||||||
|
const registered: boolean = this.registerComponent(component);
|
||||||
|
},
|
||||||
|
options
|
||||||
|
);
|
||||||
|
|
||||||
|
// Constructor with null customFn
|
||||||
|
const clay2 = new Clay([{ type: 'heading' }], null);
|
||||||
|
|
||||||
|
// Constructor with no options
|
||||||
|
const clay3 = new Clay([{ type: 'heading' }]);
|
||||||
|
|
||||||
|
// --- Instance properties ---
|
||||||
|
|
||||||
|
const config: Clay.ClayConfigItem[] = clay.config;
|
||||||
|
const version: string = clay.version;
|
||||||
|
const components: Record<string, Clay.ClayComponent> = clay.components;
|
||||||
|
const clayMeta: Clay.ClayMeta = clay.meta;
|
||||||
|
const customFn: (this: Clay.ClayConfig) => void = clay.customFn;
|
||||||
|
|
||||||
|
// --- Instance methods ---
|
||||||
|
|
||||||
|
clay.registerComponent(component);
|
||||||
|
|
||||||
|
// String manipulator name
|
||||||
|
clay.registerComponent({
|
||||||
|
name: 'another',
|
||||||
|
template: '<input>',
|
||||||
|
manipulator: 'val',
|
||||||
|
});
|
||||||
|
|
||||||
|
const url: string = clay.generateUrl();
|
||||||
|
const settings: Record<string, unknown> = clay.getSettings('{}');
|
||||||
|
const rawSettings: Record<string, unknown> = clay.getSettings('{}', false);
|
||||||
|
clay.setSettings('key', 'value');
|
||||||
|
clay.setSettings({ key: 'value' });
|
||||||
|
|
||||||
|
// --- Static methods ---
|
||||||
|
|
||||||
|
const uri: string = Clay.encodeDataUri('<html></html>');
|
||||||
|
const uriWithPrefix: string = Clay.encodeDataUri('<html></html>', 'http://example.com/#');
|
||||||
|
const prepared: number | string | (number | string)[] = Clay.prepareForAppMessage(42);
|
||||||
|
const appMsg: Record<number, number | string> =
|
||||||
|
Clay.prepareSettingsForAppMessage({ bg_color: { value: 255 } });
|
||||||
|
|
||||||
|
// --- M interface ---
|
||||||
|
|
||||||
|
function testM(el: Clay.M) {
|
||||||
|
const len: number = el.length;
|
||||||
|
const htmlEl: HTMLElement = el[0];
|
||||||
|
const added: Clay.M = el.add('<span>');
|
||||||
|
const afterSet: Clay.M = el.set('className', 'active');
|
||||||
|
const val: unknown = el.get('value');
|
||||||
|
const selected: Clay.M = el.select('.child');
|
||||||
|
el.on('click', () => {});
|
||||||
|
el.each((element: HTMLElement, index: number) => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- PebbleActiveWatchInfo ---
|
||||||
|
|
||||||
|
const watchInfo: Clay.PebbleActiveWatchInfo = {
|
||||||
|
platform: 'chalk',
|
||||||
|
model: 'qemu_platform_chalk',
|
||||||
|
language: 'en_US',
|
||||||
|
firmware: { major: 4, minor: 3, patch: 0, suffix: '' },
|
||||||
|
};
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2015",
|
||||||
|
"module": "node16",
|
||||||
|
"allowJs": true,
|
||||||
|
"declaration": true,
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"rootDir": ".",
|
||||||
|
"outDir": "./dist-types",
|
||||||
|
"strict": false,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"moduleResolution": "node16",
|
||||||
|
"typeRoots": ["./types", "./node_modules/@types"]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/scripts/lib/clay-config.js",
|
||||||
|
"src/scripts/lib/clay-events.js",
|
||||||
|
"src/scripts/lib/clay-item.js",
|
||||||
|
"src/scripts/lib/component-registry.js",
|
||||||
|
"src/scripts/lib/manipulators.js",
|
||||||
|
"src/scripts/lib/utils.js"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"test",
|
||||||
|
"dev",
|
||||||
|
"tmp",
|
||||||
|
"src/scripts/config-page.js",
|
||||||
|
"src/scripts/components",
|
||||||
|
"src/scripts/vendor",
|
||||||
|
"src/js"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2015",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node10",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"ignoreDeprecations": "6.0"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"test/type-checks.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
declare module './tmp/config-page.html' {
|
||||||
|
const html: string;
|
||||||
|
export = html;
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
declare module 'message_keys' {
|
||||||
|
const messageKeys: { [key: string]: number };
|
||||||
|
export = messageKeys;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user