diff --git a/frontend/src/app/config.cljs b/frontend/src/app/config.cljs index 58d702f8b..72bbb4d00 100644 --- a/frontend/src/app/config.cljs +++ b/frontend/src/app/config.cljs @@ -110,7 +110,7 @@ (def privacy-policy-uri (obj/get global "penpotPrivacyPolicyURI" "https://penpot.app/privacy")) (def flex-help-uri (obj/get global "penpotGridHelpURI" "https://help.penpot.app/user-guide/flexible-layouts/")) (def grid-help-uri (obj/get global "penpotGridHelpURI" "https://help.penpot.app/user-guide/flexible-layouts/")) -(def plugins-list-uri (obj/get global "penpotPluginsListUri" "https://penpot-docs-plugins.pages.dev/technical-guide/plugins/getting-started/#examples")) +(def plugins-list-uri (obj/get global "penpotPluginsListUri" "https://penpot-docs-plugins.pages.dev/plugins/getting-started/#examples")) (defn- normalize-uri [uri-str] diff --git a/frontend/src/app/plugins/api.cljs b/frontend/src/app/plugins/api.cljs index cefacb0af..a7f52d164 100644 --- a/frontend/src/app/plugins/api.cljs +++ b/frontend/src/app/plugins/api.cljs @@ -227,7 +227,7 @@ ids (into #{} (map #(obj/get % "$id")) shapes)] (st/emit! (dwg/ungroup-shapes ids))))) - (createFrame + (createBoard [_] (create-shape $plugin :frame)) diff --git a/frontend/src/app/plugins/format.cljs b/frontend/src/app/plugins/format.cljs index b734decad..fce9ea6b4 100644 --- a/frontend/src/app/plugins/format.cljs +++ b/frontend/src/app/plugins/format.cljs @@ -31,14 +31,22 @@ "mixed" value)) -;; export type PenpotPoint = { x: number; y: number }; +;; export type Point = { x: number; y: number }; (defn format-point [{:keys [x y] :as point}] (when (some? point) (obj/without-empty #js {:x x :y y}))) -;;export type PenpotBounds = { +(defn shape-type + [type] + (case type + :frame "board" + :rect "rectangle" + :circle "ellipse" + (d/name type))) + +;;export type Bounds = { ;; x: number; ;; y: number; ;; width: number; @@ -50,7 +58,7 @@ (obj/without-empty #js {:x x :y y :width width :height height}))) -;; export interface PenpotColorShapeInfoEntry { +;; export interface ColorShapeInfoEntry { ;; readonly property: string; ;; readonly index?: number; ;; readonly shapeId: string; @@ -63,7 +71,7 @@ :index index :shapeId (dm/str shape-id)}))) -;; export type PenpotGradient = { +;; export type Gradient = { ;; type: 'linear' | 'radial'; ;; startX: number; ;; startY: number; @@ -89,7 +97,7 @@ :width width :stops (format-array format-stop stops)}))) -;; export type PenpotImageData = { +;; export type ImageData = { ;; name?: string; ;; width: number; ;; height: number; @@ -108,7 +116,7 @@ :id (format-id id) :keepAspectRatio keep-aspect-ratio}))) -;; export interface PenpotColor { +;; export interface Color { ;; id?: string; ;; name?: string; ;; path?: string; @@ -116,8 +124,8 @@ ;; opacity?: number; ;; refId?: string; ;; refFile?: string; -;; gradient?: PenpotGradient; -;; image?: PenpotImageData; +;; gradient?: Gradient; +;; image?: ImageData; ;; } (defn format-color [{:keys [id name path color opacity ref-id ref-file gradient image] :as color-data}] @@ -133,7 +141,7 @@ :gradient (format-gradient gradient) :image (format-image image)}))) -;; PenpotColor & PenpotColorShapeInfo +;; Color & ColorShapeInfo (defn format-color-result [[color attrs]] (let [shapes-info (apply array (map format-shape-info attrs)) @@ -142,7 +150,7 @@ color)) -;; export interface PenpotShadow { +;; export interface Shadow { ;; id?: string; ;; style?: 'drop-shadow' | 'inner-shadow'; ;; offsetX?: number; @@ -150,7 +158,7 @@ ;; blur?: number; ;; spread?: number; ;; hidden?: boolean; -;; color?: PenpotColor; +;; color?: Color; ;; } (defn format-shadow [{:keys [id style offset-x offset-y blur spread hidden color] :as shadow}] @@ -170,13 +178,13 @@ (when (some? shadows) (format-array format-shadow shadows))) -;;export interface PenpotFill { +;;export interface Fill { ;; fillColor?: string; ;; fillOpacity?: number; -;; fillColorGradient?: PenpotGradient; +;; fillColorGradient?: Gradient; ;; fillColorRefFile?: string; ;; fillColorRefId?: string; -;; fillImage?: PenpotImageData; +;; fillImage?: ImageData; ;;} (defn format-fill [{:keys [fill-color fill-opacity fill-color-gradient fill-color-ref-file fill-color-ref-id fill-image] :as fill}] @@ -201,7 +209,7 @@ (some? fills) (format-array format-fill fills))) -;; export interface PenpotStroke { +;; export interface Stroke { ;; strokeColor?: string; ;; strokeColorRefFile?: string; ;; strokeColorRefId?: string; @@ -209,9 +217,9 @@ ;; strokeStyle?: 'solid' | 'dotted' | 'dashed' | 'mixed' | 'none' | 'svg'; ;; strokeWidth?: number; ;; strokeAlignment?: 'center' | 'inner' | 'outer'; -;; strokeCapStart?: PenpotStrokeCap; -;; strokeCapEnd?: PenpotStrokeCap; -;; strokeColorGradient?: PenpotGradient; +;; strokeCapStart?: StrokeCap; +;; strokeCapEnd?: StrokeCap; +;; strokeColorGradient?: Gradient; ;; } (defn format-stroke [{:keys [stroke-color stroke-color-ref-file stroke-color-ref-id @@ -236,7 +244,7 @@ (when (some? strokes) (format-array format-stroke strokes))) -;; export interface PenpotBlur { +;; export interface Blur { ;; id?: string; ;; type?: 'layer-blur'; ;; value?: number; @@ -251,7 +259,7 @@ :value value :hidden hidden}))) -;; export interface PenpotExport { +;; export interface Export { ;; type: 'png' | 'jpeg' | 'svg' | 'pdf'; ;; scale: number; ;; suffix: string; @@ -269,7 +277,7 @@ (when (some? exports) (format-array format-export exports))) -;; export interface PenpotFrameGuideColumnParams { +;; export interface GuideColumnParams { ;; color: { color: string; opacity: number }; ;; type?: 'stretch' | 'left' | 'center' | 'right'; ;; size?: number; @@ -288,10 +296,10 @@ :itemLength item-length :gutter gutter}))) -;; export interface PenpotFrameGuideColumn { +;; export interface GuideColumn { ;; type: 'column'; ;; display: boolean; -;; params: PenpotFrameGuideColumnParams; +;; params: GuideColumnParams; ;; } (defn format-frame-guide-column [{:keys [type display params] :as guide}] @@ -301,10 +309,10 @@ :display display :params (format-frame-guide-column-params params)}))) -;; export interface PenpotFrameGuideRow { +;; export interface GuideRow { ;; type: 'row'; ;; display: boolean; -;; params: PenpotFrameGuideColumnParams; +;; params: GuideColumnParams; ;; } (defn format-frame-guide-row [{:keys [type display params] :as guide}] @@ -314,7 +322,7 @@ :display display :params (format-frame-guide-column-params params)}))) -;;export interface PenpotFrameGuideSquareParams { +;;export interface GuideSquareParams { ;; color: { color: string; opacity: number }; ;; size?: number; ;;} @@ -325,10 +333,10 @@ #js {:color (format-color color) :size size}))) -;; export interface PenpotFrameGuideSquare { +;; export interface GuideSquare { ;; type: 'square'; ;; display: boolean; -;; params: PenpotFrameGuideSquareParams; +;; params: GuideSquareParams; ;; } (defn format-frame-guide-square @@ -352,7 +360,7 @@ (when (some? guides) (format-array format-frame-guide guides))) -;;interface PenpotPathCommand { +;;interface PathCommand { ;; command: ;; | 'M' | 'move-to' ;; | 'Z' | 'close-path' @@ -407,10 +415,10 @@ (when (some? content) (format-array format-command content))) -;; export type PenpotTrackType = 'flex' | 'fixed' | 'percent' | 'auto'; +;; export type TrackType = 'flex' | 'fixed' | 'percent' | 'auto'; ;; -;; export interface PenpotTrack { -;; type: PenpotTrackType; +;; export interface Track { +;; type: TrackType; ;; value: number | null; ;; } (defn format-track @@ -426,13 +434,13 @@ (format-array format-track tracks))) -;; export interface PenpotDissolve { +;; export interface Dissolve { ;; type: 'dissolve'; ;; duration: number; ;; easing?: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out'; ;; } ;; -;; export interface PenpotSlide { +;; export interface Slide { ;; type: 'slide'; ;; way: 'in' | 'out'; ;; direction?: @@ -445,7 +453,7 @@ ;; easing?: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out'; ;; } ;; -;; export interface PenpotPush { +;; export interface Push { ;; type: 'push'; ;; direction?: ;; | 'right' @@ -457,7 +465,7 @@ ;; easing?: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out'; ;; } ;; -;; export type PenpotAnimation = PenpotDissolve | PenpotSlide | PenpotPush; +;; export type Animation = Dissolve | Slide | Push; (defn format-animation [animation] @@ -485,24 +493,24 @@ :easing (format-key (:easing animation))} nil)))) -;;export type PenpotAction = -;; | PenpotNavigateTo -;; | PenpotOpenOverlay -;; | PenpotToggleOverlay -;; | PenpotCloseOverlay -;; | PenpotPreviousScreen -;; | PenpotOpenUrl; +;;export type Action = +;; | NavigateTo +;; | OpenOverlay +;; | ToggleOverlay +;; | CloseOverlay +;; | PreviousScreen +;; | OpenUrl; ;; -;;export interface PenpotNavigateTo { +;;export interface NavigateTo { ;; type: 'navigate-to'; -;; destination: PenpotFrame; +;; destination: Board; ;; preserveScrollPosition?: boolean; -;; animation: PenpotAnimation; +;; animation: Animation; ;;} ;; -;;export interface PenpotOverlayAction { -;; destination: PenpotFrame; -;; relativeTo?: PenpotShape; +;;export interface OverlayAction { +;; destination: Board; +;; relativeTo?: Shape; ;; position?: ;; | 'manual' ;; | 'center' @@ -512,31 +520,31 @@ ;; | 'bottom-left' ;; | 'bottom-right' ;; | 'bottom-center'; -;; manualPositionLocation?: PenpotPoint; +;; manualPositionLocation?: Point; ;; closeWhenClickOutside?: boolean; ;; addBackgroundOverlay?: boolean; -;; animation: PenpotAnimation; +;; animation: Animation; ;;} ;; -;;export interface PenpotOpenOverlay extends PenpotOverlayAction { +;;export interface OpenOverlay extends OverlayAction { ;; type: 'open-overlay'; ;;} ;; -;;export interface PenpotToggleOverlay extends PenpotOverlayAction { +;;export interface ToggleOverlay extends OverlayAction { ;; type: 'toggle-overlay'; ;;} ;; -;;export interface PenpotCloseOverlay { +;;export interface CloseOverlay { ;; type: 'close-overlay'; -;; destination?: PenpotFrame; -;; animation: PenpotAnimation; +;; destination?: Board; +;; animation: Animation; ;;} ;; -;;export interface PenpotPreviousScreen { +;;export interface PreviousScreen { ;; type: 'previous-screen'; ;;} ;; -;;export interface PenpotOpenUrl { +;;export interface OpenUrl { ;; type: 'open-url'; ;; url: string; ;;} diff --git a/frontend/src/app/plugins/parser.cljs b/frontend/src/app/plugins/parser.cljs index 460c21b1e..119c71bd3 100644 --- a/frontend/src/app/plugins/parser.cljs +++ b/frontend/src/app/plugins/parser.cljs @@ -29,17 +29,26 @@ {:x (obj/get point "x") :y (obj/get point "y")})) +(defn parse-shape-type + [type] + (case type + "board" :frame + "boolean" :bool + "rectangle" :rect + "ellipse" :circle + (parse-keyword type))) + ;; { ;; name?: string; ;; nameLike?: string; ;; type?: -;; | 'frame' +;; | 'board' ;; | 'group' -;; | 'bool' -;; | 'rect' +;; | 'boolean' +;; | 'rectangle' ;; | 'path' ;; | 'text' -;; | 'circle' +;; | 'ellipse' ;; | 'svg-raw' ;; | 'image'; ;; } @@ -49,9 +58,9 @@ (d/without-nils {:name (obj/get criteria "name") :name-like (obj/get criteria "nameLike") - :type (-> (obj/get criteria "type") parse-keyword)}))) + :type (-> (obj/get criteria "type") parse-shape-type)}))) -;;export type PenpotImageData = { +;;export type ImageData = { ;; name?: string; ;; width: number; ;; height: number; @@ -70,7 +79,7 @@ :mtype (obj/get image-data "mtype") :keep-aspect-ratio (obj/get image-data "keepApectRatio")}))) -;; export type PenpotGradient = { +;; export type Gradient = { ;; type: 'linear' | 'radial'; ;; startX: number; ;; startY: number; @@ -100,7 +109,7 @@ :stops (->> (obj/get gradient "stops") (mapv parse-gradient-stop))}))) -;; export interface PenpotColor { +;; export interface Color { ;; id?: string; ;; name?: string; ;; path?: string; @@ -108,8 +117,8 @@ ;; opacity?: number; ;; refId?: string; ;; refFile?: string; -;; gradient?: PenpotGradient; -;; image?: PenpotImageData; +;; gradient?: Gradient; +;; image?: ImageData; ;; } (defn parse-color [^js color] @@ -125,7 +134,7 @@ :gradient (-> (obj/get color "gradient") parse-gradient) :image (-> (obj/get color "image") parse-image-data)}))) -;; export interface PenpotShadow { +;; export interface Shadow { ;; id?: string; ;; style?: 'drop-shadow' | 'inner-shadow'; ;; offsetX?: number; @@ -133,7 +142,7 @@ ;; blur?: number; ;; spread?: number; ;; hidden?: boolean; -;; color?: PenpotColor; +;; color?: Color; ;; } (defn parse-shadow [^js shadow] @@ -153,13 +162,13 @@ (when (some? shadows) (into [] (map parse-shadow) shadows))) -;;export interface PenpotFill { +;;export interface Fill { ;; fillColor?: string; ;; fillOpacity?: number; -;; fillColorGradient?: PenpotGradient; +;; fillColorGradient?: Gradient; ;; fillColorRefFile?: string; ;; fillColorRefId?: string; -;; fillImage?: PenpotImageData; +;; fillImage?: ImageData; ;;} (defn parse-fill [^js fill] @@ -177,7 +186,7 @@ (when (some? fills) (into [] (map parse-fill) fills))) -;; export interface PenpotStroke { +;; export interface Stroke { ;; strokeColor?: string; ;; strokeColorRefFile?: string; ;; strokeColorRefId?: string; @@ -185,9 +194,9 @@ ;; strokeStyle?: 'solid' | 'dotted' | 'dashed' | 'mixed' | 'none' | 'svg'; ;; strokeWidth?: number; ;; strokeAlignment?: 'center' | 'inner' | 'outer'; -;; strokeCapStart?: PenpotStrokeCap; -;; strokeCapEnd?: PenpotStrokeCap; -;; strokeColorGradient?: PenpotGradient; +;; strokeCapStart?: StrokeCap; +;; strokeCapEnd?: StrokeCap; +;; strokeColorGradient?: Gradient; ;; } (defn parse-stroke [^js stroke] @@ -209,7 +218,7 @@ (when (some? strokes) (into [] (map parse-stroke) strokes))) -;; export interface PenpotBlur { +;; export interface Blur { ;; id?: string; ;; type?: 'layer-blur'; ;; value?: number; @@ -225,7 +234,7 @@ :hidden (obj/get blur "hidden")}))) -;; export interface PenpotExport { +;; export interface Export { ;; type: 'png' | 'jpeg' | 'svg' | 'pdf'; ;; scale: number; ;; suffix: string; @@ -243,7 +252,7 @@ (when (some? exports) (into [] (map parse-export) exports))) -;; export interface PenpotFrameGuideColumnParams { +;; export interface GuideColumnParams { ;; color: { color: string; opacity: number }; ;; type?: 'stretch' | 'left' | 'center' | 'right'; ;; size?: number; @@ -262,10 +271,10 @@ :item-length (obj/get params "itemLength") :gutter (obj/get params "gutter")}))) -;; export interface PenpotFrameGuideColumn { +;; export interface GuideColumn { ;; type: 'column'; ;; display: boolean; -;; params: PenpotFrameGuideColumnParams; +;; params: GuideColumnParams; ;; } (defn parse-frame-guide-column [^js guide] @@ -275,10 +284,10 @@ :display (obj/get guide "display") :params (-> (obj/get guide "params") parse-frame-guide-column-params)}))) -;; export interface PenpotFrameGuideRow { +;; export interface GuideRow { ;; type: 'row'; ;; display: boolean; -;; params: PenpotFrameGuideColumnParams; +;; params: GuideColumnParams; ;; } (defn parse-frame-guide-row @@ -289,7 +298,7 @@ :display (obj/get guide "display") :params (-> (obj/get guide "params") parse-frame-guide-column-params)}))) -;;export interface PenpotFrameGuideSquareParams { +;;export interface GuideSquareParams { ;; color: { color: string; opacity: number }; ;; size?: number; ;;} @@ -300,10 +309,10 @@ {:color (-> (obj/get params "color") parse-color) :size (obj/get params "size")}))) -;; export interface PenpotFrameGuideSquare { +;; export interface GuideSquare { ;; type: 'square'; ;; display: boolean; -;; params: PenpotFrameGuideSquareParams; +;; params: GuideSquareParams; ;; } (defn parse-frame-guide-square [^js guide] @@ -331,7 +340,7 @@ (when (some? guides) (into [] (map parse-frame-guide) guides))) -;;interface PenpotPathCommand { +;;interface PathCommand { ;; command: ;; | 'M' | 'move-to' ;; | 'Z' | 'close-path' @@ -401,13 +410,13 @@ (when (some? content) (into [] (map parse-command) content))) -;; export interface PenpotDissolve { +;; export interface Dissolve { ;; type: 'dissolve'; ;; duration: number; ;; easing?: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out'; ;; } ;; -;; export interface PenpotSlide { +;; export interface Slide { ;; type: 'slide'; ;; way: 'in' | 'out'; ;; direction?: @@ -420,7 +429,7 @@ ;; easing?: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out'; ;; } ;; -;; export interface PenpotPush { +;; export interface Push { ;; type: 'push'; ;; direction?: ;; | 'right' @@ -432,7 +441,7 @@ ;; easing?: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out'; ;; } ;; -;; export type PenpotAnimation = PenpotDissolve | PenpotSlide | PenpotPush; +;; export type Animation = Dissolve | Slide | Push; (defn parse-animation [^js animation] @@ -461,24 +470,24 @@ nil))))) -;;export type PenpotAction = -;; | PenpotNavigateTo -;; | PenpotOpenOverlay -;; | PenpotToggleOverlay -;; | PenpotCloseOverlay -;; | PenpotPreviousScreen -;; | PenpotOpenUrl; +;;export type Action = +;; | NavigateTo +;; | OpenOverlay +;; | ToggleOverlay +;; | CloseOverlay +;; | PreviousScreen +;; | OpenUrl; ;; -;;export interface PenpotNavigateTo { +;;export interface NavigateTo { ;; type: 'navigate-to'; -;; destination: PenpotFrame; +;; destination: Board; ;; preserveScrollPosition?: boolean; -;; animation: PenpotAnimation; +;; animation: Animation; ;;} ;; -;;export interface PenpotOverlayAction { -;; destination: PenpotFrame; -;; relativeTo?: PenpotShape; +;;export interface OverlayAction { +;; destination: Board; +;; relativeTo?: Shape; ;; position?: ;; | 'manual' ;; | 'center' @@ -488,31 +497,31 @@ ;; | 'bottom-left' ;; | 'bottom-right' ;; | 'bottom-center'; -;; manualPositionLocation?: PenpotPoint; +;; manualPositionLocation?: Point; ;; closeWhenClickOutside?: boolean; ;; addBackgroundOverlay?: boolean; -;; animation: PenpotAnimation; +;; animation: Animation; ;;} ;; -;;export interface PenpotOpenOverlay extends PenpotOverlayAction { +;;export interface OpenOverlay extends OverlayAction { ;; type: 'open-overlay'; ;;} ;; -;;export interface PenpotToggleOverlay extends PenpotOverlayAction { +;;export interface ToggleOverlay extends OverlayAction { ;; type: 'toggle-overlay'; ;;} ;; -;;export interface PenpotCloseOverlay { +;;export interface CloseOverlay { ;; type: 'close-overlay'; -;; destination?: PenpotFrame; -;; animation: PenpotAnimation; +;; destination?: Board; +;; animation: Animation; ;;} ;; -;;export interface PenpotPreviousScreen { +;;export interface PreviousScreen { ;; type: 'previous-screen'; ;;} ;; -;;export interface PenpotOpenUrl { +;;export interface OpenUrl { ;; type: 'open-url'; ;; url: string; ;;} diff --git a/frontend/src/app/plugins/shape.cljs b/frontend/src/app/plugins/shape.cljs index a6a1730be..f853116e6 100644 --- a/frontend/src/app/plugins/shape.cljs +++ b/frontend/src/app/plugins/shape.cljs @@ -605,7 +605,7 @@ :get #(-> % u/proxy->shape :id str)} {:name "type" - :get #(-> % u/proxy->shape :type d/name)} + :get #(-> % u/proxy->shape :type format/shape-type)} {:name "name" :get #(-> % u/proxy->shape :name) @@ -656,6 +656,21 @@ (let [id (obj/get self "$id")] (st/emit! (dwsh/update-shapes [id] #(assoc % :hidden value))))))} + {:name "visible" + :get #(-> % u/proxy->shape :hidden boolean not) + :set + (fn [self value] + (cond + (not (boolean? value)) + (u/display-not-valid :visible value) + + (not (r/check-permission plugin-id "content:write")) + (u/display-not-valid :visible "Plugin doesn't have 'content:write' permission") + + :else + (let [id (obj/get self "$id")] + (st/emit! (dwsh/update-shapes [id] #(assoc % :hidden (not value)))))))} + {:name "proportionLock" :get #(-> % u/proxy->shape :proportion-lock boolean) :set @@ -972,7 +987,7 @@ parent-y (:y parent)] (st/emit! (dw/update-position id {:y (+ parent-y value)})))))} - {:name "frameX" + {:name "boardX" :get (fn [self] (let [shape (u/proxy->shape self) frame-id (:parent-id shape) @@ -995,7 +1010,7 @@ frame-x (:x frame)] (st/emit! (dw/update-position id {:x (+ frame-x value)})))))} - {:name "frameY" + {:name "boardY" :get (fn [self] (let [shape (u/proxy->shape self) frame-id (:parent-id shape) diff --git a/frontend/test/frontend_tests/plugins/context_shapes_test.cljs b/frontend/test/frontend_tests/plugins/context_shapes_test.cljs index af6638b82..9a67f4a18 100644 --- a/frontend/test/frontend_tests/plugins/context_shapes_test.cljs +++ b/frontend/test/frontend_tests/plugins/context_shapes_test.cljs @@ -223,22 +223,22 @@ (t/is (= (-> (. shape -strokes) (aget 0) (aget "strokeWidth")) 5)))) (t/testing "Relative properties" - (let [frame (.createFrame context)] - (set! (.-x frame) 100) - (set! (.-y frame) 200) - (t/is (= (.-x frame) 100)) - (t/is (= (.-y frame) 200)) - (.appendChild frame shape) + (let [board (.createBoard context)] + (set! (.-x board) 100) + (set! (.-y board) 200) + (t/is (= (.-x board) 100)) + (t/is (= (.-y board) 200)) + (.appendChild board shape) - (t/testing " - frameX" - (set! (.-frameX shape) 10) - (t/is (m/close? (.-frameX shape) 10)) + (t/testing " - boardX" + (set! (.-boardX shape) 10) + (t/is (m/close? (.-boardX shape) 10)) (t/is (m/close? (.-x shape) 110)) (t/is (m/close? (get-in @store (get-shape-path :x)) 110))) - (t/testing " - frameY" - (set! (.-frameY shape) 20) - (t/is (m/close? (.-frameY shape) 20)) + (t/testing " - boardY" + (set! (.-boardY shape) 20) + (t/is (m/close? (.-boardY shape) 20)) (t/is (m/close? (.-y shape) 220)) (t/is (m/close? (get-in @store (get-shape-path :y)) 220)))