From c699997cdd122d09a03ca2187538b35c16d9d42a Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Tue, 23 Sep 2025 15:04:59 -0700 Subject: [PATCH 01/11] add hook --- src/react/hooks.ts | 13 +++++++++++++ src/types.ts | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/src/react/hooks.ts b/src/react/hooks.ts index 7981771..50e1a40 100644 --- a/src/react/hooks.ts +++ b/src/react/hooks.ts @@ -8,6 +8,7 @@ import { WorkbookElementData, WorkbookSelection, WorkbookVariable, + PluginStyle, } from '../types'; import { deepEqual } from '../utils/deepEqual'; @@ -246,3 +247,15 @@ export function useActionEffect(configId: string, effect: () => void) { return client.config.registerEffect(configId, effectRef.current); }, [client, configId, effect]); } + +/** + * React hook for accessing plugin style properties + * @returns {PluginStyle} Style properties + */ +export function usePluginStyle(): PluginStyle { + const client = useConfig(); + + return { + backgroundColor: client?.backgroundColor, + }; +} diff --git a/src/types.ts b/src/types.ts index a05c74c..cd7c557 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,6 +2,13 @@ export type ScalarType = 'boolean' | 'datetime' | 'number' | 'integer' | 'text'; export type PrimitiveType = ScalarType | 'variant' | 'link'; export type ValueType = PrimitiveType | 'error'; +/** + * Style properties that can be configured through the plugin format panel + */ +export interface PluginStyle { + backgroundColor?: string; +} + /** * All mutable workbook control variable types */ From 0f65af6d27635bc7fb733a66c3fd8dcd6313b4da Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Wed, 24 Sep 2025 19:08:28 -0700 Subject: [PATCH 02/11] add request color --- src/client/initialize.ts | 32 +++++++++++++++++++++++++++++++ src/react/hooks.ts | 21 +++++++++++++------- src/types.ts | 41 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 7 deletions(-) diff --git a/src/client/initialize.ts b/src/client/initialize.ts index a025bd3..a55274f 100644 --- a/src/client/initialize.ts +++ b/src/client/initialize.ts @@ -37,6 +37,11 @@ export function initialize(): PluginInstance { emit('config', pluginConfig.config ?? {}); }); + on('wb:plugin:style:update', (styleColors: any) => { + pluginConfig.styleColors = styleColors; + emit('style', styleColors); + }); + // send initialize event void execPromise( 'wb:plugin:init', @@ -223,6 +228,33 @@ export function initialize(): PluginInstance { void execPromise('wb:plugin:element:fetch-more', configId); }, }, + + // Style management functions for hooks + style: { + /** + * Subscribe to style updates + * @param callback Function to call when style updates + * @returns Unsubscriber function + */ + subscribe(callback: (style: any) => void) { + on('style', callback); + return () => off('style', callback); + }, + + /** + * Request current style from workbook + * @returns Promise with current style + */ + async getStyle() { + try { + return await execPromise('wb:plugin:style:get'); + } catch (error) { + // Return default style if request fails + return { backgroundColor: 'transparent' }; + } + }, + }, + destroy() { Object.keys(listeners).forEach(event => delete listeners[event]); window.removeEventListener('message', listener, false); diff --git a/src/react/hooks.ts b/src/react/hooks.ts index 50e1a40..8c40fa2 100644 --- a/src/react/hooks.ts +++ b/src/react/hooks.ts @@ -249,13 +249,20 @@ export function useActionEffect(configId: string, effect: () => void) { } /** - * React hook for accessing plugin style properties - * @returns {PluginStyle} Style properties + * React hook for accessing plugin style with live updates via PostMessage + * @returns {PluginStyle | undefined} Style properties from the workbook if available */ -export function usePluginStyle(): PluginStyle { - const client = useConfig(); +export function usePluginStyle(): PluginStyle | undefined { + const client = usePlugin(); + const [style, setStyle] = useState(undefined); + + useEffect(() => { + const unsubscribe = client.style.subscribe(setStyle); + // Request initial style data on mount + void client.style.getStyle().then(setStyle); + + return unsubscribe; + }, [client]); - return { - backgroundColor: client?.backgroundColor, - }; + return style; } diff --git a/src/types.ts b/src/types.ts index cd7c557..3dc96ab 100644 --- a/src/types.ts +++ b/src/types.ts @@ -27,9 +27,19 @@ export interface PluginConfig { id: string; config: T; screenshot: boolean; + // styleColors: PluginStyle; [key: string]: any; } +// /** +// * Style colors available to plugins +// * @typedef {object} PluginStyle +// * @property {string} backgroundColor Background color set from workbook +// */ +// export interface PluginStyle { +// backgroundColor: string; +// } + /** * @typedef {object} WorkbookVariable * @property {string} name Name of control variable within workbook @@ -196,6 +206,19 @@ export type CustomPluginConfigOptions = export interface PluginInstance { sigmaEnv: 'author' | 'viewer' | 'explorer'; + // /** + // * Plugin style colors from the workbook + // * @returns {PluginStyle | undefined} Style colors if available + // */ + // styleColors?: PluginStyle | undefined; + + // /** + // * Listen to style color changes + // * @param {Function} callback Function to call when style colors change + // * @returns {Function} Unsubscriber function + // */ + // onStyleChange(callback: (styleColors: PluginStyle) => void): () => void; + config: { /** * Getter for entire Plugin Config @@ -355,6 +378,24 @@ export interface PluginInstance { fetchMoreElementData(configId: string): void; }; + /** + * Style management for plugins + */ + style: { + /** + * Subscribe to style updates + * @param callback Function to call when style updates + * @returns Unsubscriber function + */ + subscribe(callback: (style: PluginStyle) => void): () => void; + + /** + * Request current style from workbook + * @returns Promise with current style + */ + getStyle(): Promise; + }; + /** * Destroys plugin instance and removes all subscribers */ From a32953b6e349a527608ffbe122a2e531642f938f Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Thu, 25 Sep 2025 01:06:41 -0700 Subject: [PATCH 03/11] add request style --- src/client/initialize.ts | 26 +++++--------------------- src/react/hooks.ts | 6 ++---- src/types.ts | 19 +------------------ 3 files changed, 8 insertions(+), 43 deletions(-) diff --git a/src/client/initialize.ts b/src/client/initialize.ts index a55274f..5c2ee5f 100644 --- a/src/client/initialize.ts +++ b/src/client/initialize.ts @@ -37,9 +37,8 @@ export function initialize(): PluginInstance { emit('config', pluginConfig.config ?? {}); }); - on('wb:plugin:style:update', (styleColors: any) => { - pluginConfig.styleColors = styleColors; - emit('style', styleColors); + on('wb:plugin:style:update', (style: any) => { + emit('style', style); }); // send initialize event @@ -229,29 +228,14 @@ export function initialize(): PluginInstance { }, }, - // Style management functions for hooks style: { - /** - * Subscribe to style updates - * @param callback Function to call when style updates - * @returns Unsubscriber function - */ - subscribe(callback: (style: any) => void) { + subscribeToStyle(callback: (style: any) => void) { on('style', callback); return () => off('style', callback); }, - /** - * Request current style from workbook - * @returns Promise with current style - */ - async getStyle() { - try { - return await execPromise('wb:plugin:style:get'); - } catch (error) { - // Return default style if request fails - return { backgroundColor: 'transparent' }; - } + getStyle() { + return execPromise('wb:plugin:style:get'); }, }, diff --git a/src/react/hooks.ts b/src/react/hooks.ts index 8c40fa2..65f1f73 100644 --- a/src/react/hooks.ts +++ b/src/react/hooks.ts @@ -257,11 +257,9 @@ export function usePluginStyle(): PluginStyle | undefined { const [style, setStyle] = useState(undefined); useEffect(() => { - const unsubscribe = client.style.subscribe(setStyle); - // Request initial style data on mount + // Request initial style data on mount and subscribe to updates void client.style.getStyle().then(setStyle); - - return unsubscribe; + return client.style.subscribeToStyle(setStyle); }, [client]); return style; diff --git a/src/types.ts b/src/types.ts index 3dc96ab..a32bed9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -27,7 +27,6 @@ export interface PluginConfig { id: string; config: T; screenshot: boolean; - // styleColors: PluginStyle; [key: string]: any; } @@ -206,19 +205,6 @@ export type CustomPluginConfigOptions = export interface PluginInstance { sigmaEnv: 'author' | 'viewer' | 'explorer'; - // /** - // * Plugin style colors from the workbook - // * @returns {PluginStyle | undefined} Style colors if available - // */ - // styleColors?: PluginStyle | undefined; - - // /** - // * Listen to style color changes - // * @param {Function} callback Function to call when style colors change - // * @returns {Function} Unsubscriber function - // */ - // onStyleChange(callback: (styleColors: PluginStyle) => void): () => void; - config: { /** * Getter for entire Plugin Config @@ -378,16 +364,13 @@ export interface PluginInstance { fetchMoreElementData(configId: string): void; }; - /** - * Style management for plugins - */ style: { /** * Subscribe to style updates * @param callback Function to call when style updates * @returns Unsubscriber function */ - subscribe(callback: (style: PluginStyle) => void): () => void; + subscribeToStyle(callback: (style: PluginStyle) => void): () => void; /** * Request current style from workbook From d40864d0c3ed79cb47bf2cfa66fb04f99dbcad8e Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Thu, 25 Sep 2025 11:27:44 -0700 Subject: [PATCH 04/11] cleanup --- src/client/initialize.ts | 8 ++------ src/react/hooks.ts | 2 +- src/types.ts | 23 ++++++++--------------- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/client/initialize.ts b/src/client/initialize.ts index 5c2ee5f..4d6c66d 100644 --- a/src/client/initialize.ts +++ b/src/client/initialize.ts @@ -37,10 +37,6 @@ export function initialize(): PluginInstance { emit('config', pluginConfig.config ?? {}); }); - on('wb:plugin:style:update', (style: any) => { - emit('style', style); - }); - // send initialize event void execPromise( 'wb:plugin:init', @@ -230,8 +226,8 @@ export function initialize(): PluginInstance { style: { subscribeToStyle(callback: (style: any) => void) { - on('style', callback); - return () => off('style', callback); + on('wb:plugin:style:update', callback); + return () => off('wb:plugin:style:update', callback); }, getStyle() { diff --git a/src/react/hooks.ts b/src/react/hooks.ts index 65f1f73..9a941cf 100644 --- a/src/react/hooks.ts +++ b/src/react/hooks.ts @@ -249,7 +249,7 @@ export function useActionEffect(configId: string, effect: () => void) { } /** - * React hook for accessing plugin style with live updates via PostMessage + * React hook for accessing plugin style with live updates * @returns {PluginStyle | undefined} Style properties from the workbook if available */ export function usePluginStyle(): PluginStyle | undefined { diff --git a/src/types.ts b/src/types.ts index a32bed9..d22fc7c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,13 +2,6 @@ export type ScalarType = 'boolean' | 'datetime' | 'number' | 'integer' | 'text'; export type PrimitiveType = ScalarType | 'variant' | 'link'; export type ValueType = PrimitiveType | 'error'; -/** - * Style properties that can be configured through the plugin format panel - */ -export interface PluginStyle { - backgroundColor?: string; -} - /** * All mutable workbook control variable types */ @@ -30,14 +23,14 @@ export interface PluginConfig { [key: string]: any; } -// /** -// * Style colors available to plugins -// * @typedef {object} PluginStyle -// * @property {string} backgroundColor Background color set from workbook -// */ -// export interface PluginStyle { -// backgroundColor: string; -// } +/** + * Style colors available to plugins + * @typedef {object} PluginStyle + * @property {string} backgroundColor Background color set from workbook if any + */ +export interface PluginStyle { + backgroundColor?: string; +} /** * @typedef {object} WorkbookVariable From f764549e5101b78590b9a1cc30eb63dfbf8479fe Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Fri, 26 Sep 2025 12:47:51 -0700 Subject: [PATCH 05/11] remove getter for style from slate --- src/client/initialize.ts | 4 ---- src/react/hooks.ts | 2 -- src/types.ts | 6 ------ 3 files changed, 12 deletions(-) diff --git a/src/client/initialize.ts b/src/client/initialize.ts index 4d6c66d..6ae6008 100644 --- a/src/client/initialize.ts +++ b/src/client/initialize.ts @@ -229,10 +229,6 @@ export function initialize(): PluginInstance { on('wb:plugin:style:update', callback); return () => off('wb:plugin:style:update', callback); }, - - getStyle() { - return execPromise('wb:plugin:style:get'); - }, }, destroy() { diff --git a/src/react/hooks.ts b/src/react/hooks.ts index 9a941cf..3bb7dac 100644 --- a/src/react/hooks.ts +++ b/src/react/hooks.ts @@ -257,8 +257,6 @@ export function usePluginStyle(): PluginStyle | undefined { const [style, setStyle] = useState(undefined); useEffect(() => { - // Request initial style data on mount and subscribe to updates - void client.style.getStyle().then(setStyle); return client.style.subscribeToStyle(setStyle); }, [client]); diff --git a/src/types.ts b/src/types.ts index d22fc7c..fe0ab4d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -364,12 +364,6 @@ export interface PluginInstance { * @returns Unsubscriber function */ subscribeToStyle(callback: (style: PluginStyle) => void): () => void; - - /** - * Request current style from workbook - * @returns Promise with current style - */ - getStyle(): Promise; }; /** From bbc211c5d478b11d9e010c742de68fd4d16dfcf1 Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Fri, 26 Sep 2025 15:20:13 -0700 Subject: [PATCH 06/11] Revert "remove getter for style from slate" This reverts commit f764549e5101b78590b9a1cc30eb63dfbf8479fe. --- src/client/initialize.ts | 4 ++++ src/react/hooks.ts | 2 ++ src/types.ts | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/src/client/initialize.ts b/src/client/initialize.ts index 6ae6008..4d6c66d 100644 --- a/src/client/initialize.ts +++ b/src/client/initialize.ts @@ -229,6 +229,10 @@ export function initialize(): PluginInstance { on('wb:plugin:style:update', callback); return () => off('wb:plugin:style:update', callback); }, + + getStyle() { + return execPromise('wb:plugin:style:get'); + }, }, destroy() { diff --git a/src/react/hooks.ts b/src/react/hooks.ts index 3bb7dac..9a941cf 100644 --- a/src/react/hooks.ts +++ b/src/react/hooks.ts @@ -257,6 +257,8 @@ export function usePluginStyle(): PluginStyle | undefined { const [style, setStyle] = useState(undefined); useEffect(() => { + // Request initial style data on mount and subscribe to updates + void client.style.getStyle().then(setStyle); return client.style.subscribeToStyle(setStyle); }, [client]); diff --git a/src/types.ts b/src/types.ts index fe0ab4d..d22fc7c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -364,6 +364,12 @@ export interface PluginInstance { * @returns Unsubscriber function */ subscribeToStyle(callback: (style: PluginStyle) => void): () => void; + + /** + * Request current style from workbook + * @returns Promise with current style + */ + getStyle(): Promise; }; /** From 77fcfe069e8500503983c9650ff5107e848dc4db Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Mon, 29 Sep 2025 20:02:51 -0700 Subject: [PATCH 07/11] make backgroundColor not optional --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index d22fc7c..3e8a845 100644 --- a/src/types.ts +++ b/src/types.ts @@ -29,7 +29,7 @@ export interface PluginConfig { * @property {string} backgroundColor Background color set from workbook if any */ export interface PluginStyle { - backgroundColor?: string; + backgroundColor: string; } /** From 2c34bde365bdea8d5d04a7ae4cec3082a37f1a68 Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Mon, 29 Sep 2025 20:04:53 -0700 Subject: [PATCH 08/11] small fix --- src/react/hooks.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/react/hooks.ts b/src/react/hooks.ts index 9a941cf..1f8c33d 100644 --- a/src/react/hooks.ts +++ b/src/react/hooks.ts @@ -254,11 +254,11 @@ export function useActionEffect(configId: string, effect: () => void) { */ export function usePluginStyle(): PluginStyle | undefined { const client = usePlugin(); - const [style, setStyle] = useState(undefined); + const [style, setStyle] = useState(); useEffect(() => { // Request initial style data on mount and subscribe to updates - void client.style.getStyle().then(setStyle); + void client.style.getStyle().then(response => setStyle(response)); return client.style.subscribeToStyle(setStyle); }, [client]); From f20085b3da148ba48906e8717fdd34fcc33dce1c Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Wed, 1 Oct 2025 16:58:56 -0700 Subject: [PATCH 09/11] better method name --- src/client/initialize.ts | 2 +- src/react/hooks.ts | 2 +- src/types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/initialize.ts b/src/client/initialize.ts index 4d6c66d..b7d5f8b 100644 --- a/src/client/initialize.ts +++ b/src/client/initialize.ts @@ -225,7 +225,7 @@ export function initialize(): PluginInstance { }, style: { - subscribeToStyle(callback: (style: any) => void) { + subscribe(callback: (style: any) => void) { on('wb:plugin:style:update', callback); return () => off('wb:plugin:style:update', callback); }, diff --git a/src/react/hooks.ts b/src/react/hooks.ts index 1f8c33d..a3cb81f 100644 --- a/src/react/hooks.ts +++ b/src/react/hooks.ts @@ -259,7 +259,7 @@ export function usePluginStyle(): PluginStyle | undefined { useEffect(() => { // Request initial style data on mount and subscribe to updates void client.style.getStyle().then(response => setStyle(response)); - return client.style.subscribeToStyle(setStyle); + return client.style.subscribe(setStyle); }, [client]); return style; diff --git a/src/types.ts b/src/types.ts index 3e8a845..f7b0547 100644 --- a/src/types.ts +++ b/src/types.ts @@ -363,7 +363,7 @@ export interface PluginInstance { * @param callback Function to call when style updates * @returns Unsubscriber function */ - subscribeToStyle(callback: (style: PluginStyle) => void): () => void; + subscribe(callback: (style: PluginStyle) => void): () => void; /** * Request current style from workbook From 0b3da6b83a73bc08c0154f8049005d0344663837 Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Thu, 2 Oct 2025 11:02:11 -0700 Subject: [PATCH 10/11] refactor getstyle to get --- src/client/initialize.ts | 2 +- src/react/hooks.ts | 2 +- src/types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/initialize.ts b/src/client/initialize.ts index b7d5f8b..88855d4 100644 --- a/src/client/initialize.ts +++ b/src/client/initialize.ts @@ -230,7 +230,7 @@ export function initialize(): PluginInstance { return () => off('wb:plugin:style:update', callback); }, - getStyle() { + get() { return execPromise('wb:plugin:style:get'); }, }, diff --git a/src/react/hooks.ts b/src/react/hooks.ts index a3cb81f..ad22321 100644 --- a/src/react/hooks.ts +++ b/src/react/hooks.ts @@ -258,7 +258,7 @@ export function usePluginStyle(): PluginStyle | undefined { useEffect(() => { // Request initial style data on mount and subscribe to updates - void client.style.getStyle().then(response => setStyle(response)); + void client.style.get().then(response => setStyle(response)); return client.style.subscribe(setStyle); }, [client]); diff --git a/src/types.ts b/src/types.ts index f7b0547..8548e29 100644 --- a/src/types.ts +++ b/src/types.ts @@ -369,7 +369,7 @@ export interface PluginInstance { * Request current style from workbook * @returns Promise with current style */ - getStyle(): Promise; + get(): Promise; }; /** From 13985df052179b7e1f4c11b4cb617400c42fdfff Mon Sep 17 00:00:00 2001 From: Alison Lai Date: Mon, 6 Oct 2025 14:26:17 -0700 Subject: [PATCH 11/11] change subscribe callback type to PluginStyle --- src/client/initialize.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/initialize.ts b/src/client/initialize.ts index 88855d4..3a50b50 100644 --- a/src/client/initialize.ts +++ b/src/client/initialize.ts @@ -3,6 +3,7 @@ import { PluginConfig, PluginInstance, PluginMessageResponse, + PluginStyle, WorkbookSelection, WorkbookVariable, } from '../types'; @@ -225,7 +226,7 @@ export function initialize(): PluginInstance { }, style: { - subscribe(callback: (style: any) => void) { + subscribe(callback: (style: PluginStyle) => void) { on('wb:plugin:style:update', callback); return () => off('wb:plugin:style:update', callback); },