1
0
dinhlongviolin1 1 сар өмнө
parent
commit
4d8121700f

+ 4 - 2
frontend/taipy-gui/base/src/app.ts

@@ -319,8 +319,9 @@ export class TaipyApp {
         canvasDomElement: HTMLElement,
         canvasDomElement: HTMLElement,
         canvasEditModeCanvas?: HTMLElement,
         canvasEditModeCanvas?: HTMLElement,
         propertyEditorElement?: HTMLElement,
         propertyEditorElement?: HTMLElement,
+        styleHandler?: (id: string, styles: Record<string, unknown>) => void,
     ) {
     ) {
-        this.elementManager.init(canvasDomElement, canvasEditModeCanvas, propertyEditorElement);
+        this.elementManager.init(canvasDomElement, canvasEditModeCanvas, propertyEditorElement, styleHandler);
     }
     }
 
 
     addElement2Canvas(
     addElement2Canvas(
@@ -329,8 +330,9 @@ export class TaipyApp {
         rootId: string,
         rootId: string,
         wrapper: CanvasRenderConfig["wrapper"],
         wrapper: CanvasRenderConfig["wrapper"],
         properties: Element["properties"] | undefined = undefined,
         properties: Element["properties"] | undefined = undefined,
+        styles: Element["styles"] | undefined = undefined,
     ) {
     ) {
-        this.elementManager.addElement(type, id, rootId, wrapper, properties);
+        this.elementManager.addElement(type, id, rootId, wrapper, properties, styles);
     }
     }
 
 
     setCanvasEditMode(bool: boolean) {
     setCanvasEditMode(bool: boolean) {

+ 10 - 1
frontend/taipy-gui/base/src/components/Taipy/TaipyElement.tsx

@@ -6,7 +6,7 @@ import JsxParser from "react-jsx-parser";
 import { PageContext, TaipyContext } from "../../../../src/context/taipyContext";
 import { PageContext, TaipyContext } from "../../../../src/context/taipyContext";
 import { Element, ElementActionEnum } from "../../element/elementManager";
 import { Element, ElementActionEnum } from "../../element/elementManager";
 import useStore, { getElementAction } from "../../store";
 import useStore, { getElementAction } from "../../store";
-import { getJsx } from "./utils";
+import { getJsx, getTaipyElementId } from "./utils";
 import { emptyArray } from "../../../../src/utils";
 import { emptyArray } from "../../../../src/utils";
 import ErrorFallback from "../../../../src/utils/ErrorBoundary";
 import ErrorFallback from "../../../../src/utils/ErrorBoundary";
 import { getRegisteredComponents } from "../../../../src/components/Taipy";
 import { getRegisteredComponents } from "../../../../src/components/Taipy";
@@ -23,6 +23,7 @@ const TaipyElement = (props: TaipyElementProps) => {
     const [module, setModule] = useState<string>("");
     const [module, setModule] = useState<string>("");
     const [jsx, setJsx] = useState<string>("");
     const [jsx, setJsx] = useState<string>("");
     const app = useStore((state) => state.app);
     const app = useStore((state) => state.app);
+    const styleHandler = useStore((state) => state.styleHandler);
     const prevElement = useRef(props.element);
     const prevElement = useRef(props.element);
 
 
     const renderConfig = useMemo(
     const renderConfig = useMemo(
@@ -76,6 +77,14 @@ const TaipyElement = (props: TaipyElementProps) => {
         };
         };
     }, [props.element, app, props.editMode]);
     }, [props.element, app, props.editMode]);
 
 
+    useEffect(() => {
+        const potentialElementId = getTaipyElementId(props.element.id, props.editMode);
+        document.getElementById(potentialElementId) &&
+            styleHandler &&
+            props.element.styles &&
+            styleHandler(potentialElementId, props.element.styles);
+    }, [pageState.jsx, props.element.id, props.editMode, props.element.styles, styleHandler]);
+
     return renderConfig ? (
     return renderConfig ? (
         createPortal(
         createPortal(
             <PageContext.Provider value={pageState}>
             <PageContext.Provider value={pageState}>

+ 5 - 1
frontend/taipy-gui/base/src/components/Taipy/utils.ts

@@ -2,9 +2,13 @@ import axios from "axios";
 import { TaipyApp } from "../../app";
 import { TaipyApp } from "../../app";
 import { Element } from "../../element/elementManager";
 import { Element } from "../../element/elementManager";
 
 
+export const getTaipyElementId = (id: Element["id"], editMode: boolean): string => {
+    return id + "-el" + (editMode ? "" : "-active");
+};
+
 export const getJsx = async (taipyApp: TaipyApp, element: Element, editMode: boolean): Promise<string> => {
 export const getJsx = async (taipyApp: TaipyApp, element: Element, editMode: boolean): Promise<string> => {
     try {
     try {
-        const id = element.id + "-el" + (editMode ? "" : "-active");
+        const id = getTaipyElementId(element.id, editMode);
         const result = await axios.post<{ jsx: string }>(
         const result = await axios.post<{ jsx: string }>(
             `${taipyApp.getBaseUrl()}taipy-element-jsx?client_id=${taipyApp.clientId}`,
             `${taipyApp.getBaseUrl()}taipy-element-jsx?client_id=${taipyApp.clientId}`,
             {
             {

+ 28 - 4
frontend/taipy-gui/base/src/element/elementManager.ts

@@ -12,6 +12,7 @@ export interface Element {
     type: string;
     type: string;
     id: string;
     id: string;
     properties?: Record<string, unknown>;
     properties?: Record<string, unknown>;
+    styles?: Record<string, unknown>;
     renderConfig?: CanvasRenderConfig;
     renderConfig?: CanvasRenderConfig;
     editModeRenderConfig?: CanvasRenderConfig;
     editModeRenderConfig?: CanvasRenderConfig;
 }
 }
@@ -38,7 +39,13 @@ export class ElementManager {
         this.#canvas = new TaipyCanvas(taipyApp);
         this.#canvas = new TaipyCanvas(taipyApp);
     }
     }
 
 
-    init(canvasDomElement: HTMLElement, canvasEditModeCanvas?: HTMLElement, propertyEditorElement?: HTMLElement) {
+    init(
+        canvasDomElement: HTMLElement,
+        canvasEditModeCanvas?: HTMLElement,
+        propertyEditorElement?: HTMLElement,
+        styleHandler?: (id: string, styles: Record<string, unknown>) => void,
+    ) {
+        getStore().setStyleHandler(styleHandler);
         this.#canvas.init(canvasDomElement, canvasEditModeCanvas, propertyEditorElement);
         this.#canvas.init(canvasDomElement, canvasEditModeCanvas, propertyEditorElement);
     }
     }
 
 
@@ -60,10 +67,14 @@ export class ElementManager {
         rootId: string,
         rootId: string,
         wrapper: CanvasRenderConfig["wrapper"],
         wrapper: CanvasRenderConfig["wrapper"],
         properties: Element["properties"] | undefined = undefined,
         properties: Element["properties"] | undefined = undefined,
+        styles: Element["styles"] | undefined = undefined,
     ) {
     ) {
         if (properties === undefined) {
         if (properties === undefined) {
             properties = {};
             properties = {};
         }
         }
+        if (styles === undefined) {
+            styles = {};
+        }
         const root = document.getElementById(rootId);
         const root = document.getElementById(rootId);
         if (!root) {
         if (!root) {
             console.error(`Root element with id '${rootId}' not found!`);
             console.error(`Root element with id '${rootId}' not found!`);
@@ -74,11 +85,16 @@ export class ElementManager {
         };
         };
         // add element if not existed
         // add element if not existed
         if (!isElementExisted(id)) {
         if (!isElementExisted(id)) {
-            getStore().addElementAction({ action: ElementActionEnum.Add, id, payload: properties });
+            getStore().addElementAction({
+                action: ElementActionEnum.Add,
+                id,
+                payload: { properties, styles },
+            });
             getStore().addElement({
             getStore().addElement({
                 type,
                 type,
                 id,
                 id,
                 properties,
                 properties,
+                styles,
                 ...renderConfig,
                 ...renderConfig,
             });
             });
             return;
             return;
@@ -88,8 +104,16 @@ export class ElementManager {
             ...getStore().elements.find((element) => element.id === id)?.properties,
             ...getStore().elements.find((element) => element.id === id)?.properties,
             ...properties,
             ...properties,
         };
         };
-        getStore().addElementAction({ action: ElementActionEnum.Add, id, payload: editedProperties });
-        getStore().editElement(id, { ...renderConfig, properties: editedProperties });
+        const editedStyles = {
+            ...getStore().elements.find((element) => element.id === id)?.styles,
+            ...styles,
+        };
+        getStore().addElementAction({
+            action: ElementActionEnum.Add,
+            id,
+            payload: { properties: editedProperties, styles: editedStyles },
+        });
+        getStore().editElement(id, { ...renderConfig, properties: editedProperties, styles: editedStyles });
     }
     }
 
 
     modifyElement(id: string, elementProperties: Record<string, unknown>) {
     modifyElement(id: string, elementProperties: Record<string, unknown>) {

+ 10 - 1
frontend/taipy-gui/base/src/packaging/taipy-gui-base.d.ts

@@ -99,6 +99,7 @@ export interface Element {
     type: string;
     type: string;
     id: string;
     id: string;
     properties?: Record<string, unknown>;
     properties?: Record<string, unknown>;
+    styles?: Record<string, unknown>;
     renderConfig?: CanvasRenderConfig;
     renderConfig?: CanvasRenderConfig;
     editModeRenderConfig?: CanvasRenderConfig;
     editModeRenderConfig?: CanvasRenderConfig;
 }
 }
@@ -117,7 +118,12 @@ declare class ElementManager {
     #private;
     #private;
     taipyApp: TaipyApp;
     taipyApp: TaipyApp;
     constructor(taipyApp: TaipyApp);
     constructor(taipyApp: TaipyApp);
-    init(canvasDomElement: HTMLElement, canvasEditModeCanvas?: HTMLElement, propertyEditorElement?: HTMLElement): void;
+    init(
+        canvasDomElement: HTMLElement,
+        canvasEditModeCanvas?: HTMLElement,
+        propertyEditorElement?: HTMLElement,
+        styleHandler?: (id: string, styles: Record<string, unknown>) => void,
+    ): void;
     setEditMode(editMode: boolean): void;
     setEditMode(editMode: boolean): void;
     addElement(
     addElement(
         type: string,
         type: string,
@@ -125,6 +131,7 @@ declare class ElementManager {
         rootId: string,
         rootId: string,
         wrapper: CanvasRenderConfig["wrapper"],
         wrapper: CanvasRenderConfig["wrapper"],
         properties?: Element["properties"] | undefined,
         properties?: Element["properties"] | undefined,
+        styles?: Element["styles"] | undefined,
     ): void;
     ): void;
     modifyElement(id: string, elementProperties: Record<string, unknown>): void;
     modifyElement(id: string, elementProperties: Record<string, unknown>): void;
     modifyElementProperties(id: string, payload: Record<string, unknown>): void;
     modifyElementProperties(id: string, payload: Record<string, unknown>): void;
@@ -215,6 +222,7 @@ export declare class TaipyApp {
         canvasDomElement: HTMLElement,
         canvasDomElement: HTMLElement,
         canvasEditModeCanvas?: HTMLElement,
         canvasEditModeCanvas?: HTMLElement,
         propertyEditorElement?: HTMLElement,
         propertyEditorElement?: HTMLElement,
+        styleHandler?: (id: string, styles: Record<string, unknown>) => void,
     ): void;
     ): void;
     addElement2Canvas(
     addElement2Canvas(
         type: string,
         type: string,
@@ -222,6 +230,7 @@ export declare class TaipyApp {
         rootId: string,
         rootId: string,
         wrapper: CanvasRenderConfig["wrapper"],
         wrapper: CanvasRenderConfig["wrapper"],
         properties?: Element["properties"] | undefined,
         properties?: Element["properties"] | undefined,
+        styles?: Element["styles"] | undefined,
     ): void;
     ): void;
     setCanvasEditMode(bool: boolean): void;
     setCanvasEditMode(bool: boolean): void;
     modifyElement(id: string, modifiedRecord: Record<string, unknown>): void;
     modifyElement(id: string, modifiedRecord: Record<string, unknown>): void;

+ 5 - 0
frontend/taipy-gui/base/src/store.ts

@@ -8,6 +8,7 @@ interface TaipyGuiBaseState {
     elements: Element[];
     elements: Element[];
     elementActions: ElementAction[];
     elementActions: ElementAction[];
     selectedElement?: Element;
     selectedElement?: Element;
+    styleHandler?: (id: string, styles: Record<string, unknown>) => void;
     setEditMode: (newEditMode: boolean) => void;
     setEditMode: (newEditMode: boolean) => void;
     setApp: (newApp: TaipyApp) => void;
     setApp: (newApp: TaipyApp) => void;
     addElement: (newElement: Element) => void;
     addElement: (newElement: Element) => void;
@@ -17,6 +18,7 @@ interface TaipyGuiBaseState {
     addElementAction: (action: ElementAction) => void;
     addElementAction: (action: ElementAction) => void;
     deleteElementAction: (action: ElementAction) => void;
     deleteElementAction: (action: ElementAction) => void;
     setSelectedElement: (action: Element | undefined) => void;
     setSelectedElement: (action: Element | undefined) => void;
+    setStyleHandler: (styleHandler?: (id: string, styles: Record<string, unknown>) => void) => void;
 }
 }
 
 
 export const useStore = create<TaipyGuiBaseState>()((set) => ({
 export const useStore = create<TaipyGuiBaseState>()((set) => ({
@@ -25,6 +27,7 @@ export const useStore = create<TaipyGuiBaseState>()((set) => ({
     elements: [],
     elements: [],
     elementActions: [],
     elementActions: [],
     selectedElement: undefined,
     selectedElement: undefined,
+    styleHandler: undefined,
     setEditMode: (newEditMode: boolean) => set(() => ({ editMode: newEditMode })),
     setEditMode: (newEditMode: boolean) => set(() => ({ editMode: newEditMode })),
     setApp: (newApp: TaipyApp) => set(() => ({ app: newApp })),
     setApp: (newApp: TaipyApp) => set(() => ({ app: newApp })),
     addElement: (newElement: Element) => set((state) => ({ elements: [...state.elements, newElement] })),
     addElement: (newElement: Element) => set((state) => ({ elements: [...state.elements, newElement] })),
@@ -41,6 +44,8 @@ export const useStore = create<TaipyGuiBaseState>()((set) => ({
     deleteElementAction: (action: ElementAction) =>
     deleteElementAction: (action: ElementAction) =>
         set((state) => ({ elementActions: state.elementActions.filter((a) => a !== action) })),
         set((state) => ({ elementActions: state.elementActions.filter((a) => a !== action) })),
     setSelectedElement: (element: Element | undefined) => set(() => ({ selectedElement: element })),
     setSelectedElement: (element: Element | undefined) => set(() => ({ selectedElement: element })),
+    setStyleHandler: (styleHandler?: (id: string, styles: Record<string, unknown>) => void) =>
+        set(() => ({ styleHandler })),
 }));
 }));
 
 
 export const getStore = () => useStore.getState();
 export const getStore = () => useStore.getState();