Skip to content

Commit

Permalink
feat: add all shape attrs, search by attr
Browse files Browse the repository at this point in the history
  • Loading branch information
maitrungduc1410 committed Jun 23, 2023
1 parent 0cb87f1 commit 0055fc3
Show file tree
Hide file tree
Showing 9 changed files with 378 additions and 169 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@ To Develop the extension:
- Run `yarn install` or `npm install`
- Run `yarn dev` (for Chrome/Edge) or `yarn dev:firefox` for Firefox

Next drag `dist` folder to the following for the browser you're using:
After that, a `dist` folder will be generated, next based on your browser do the following
- Chrome: open `chrome://extensions/` and drag `dist` folder there
- Edge: open `edge://extensions/` and drag `dist` folder there
- Firefox: open `about:debugging#/runtime/this-firefox` > Load Temporary Add > Select any file in the `dist` folder

- Chrome: `chrome://extensions/`
- Edge: `edge://extensions/`
- Firefox: `about:debugging#/runtime/this-firefox` > Load Temporary Add > Select any file in the `dist` folder

> Note: for Firefox, to make background script + popup page work on load, right click the Konva extension icon on browser bar -> Always allow....
> Note: for Firefox, to make background script + popup page work on load, right click the Konva extension icon on browser bar -> select "Always allow....""
# Build
To build project for publish, run `yarn build` (for Chrome/Edge) or `yarn build:firefox` for Firefox
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "konva-inspector",
"version": "0.0.11",
"version": "0.0.12",
"description": "Devtools for your Konva App",
"license": "MIT",
"repository": {
Expand Down
202 changes: 118 additions & 84 deletions src/pages/panel/components/Attributes.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React from "react";
import React, { useState } from "react";
import { bridge } from "..";
import CopyToClipboard from "./CopyToClipboard";
import { IAttr } from "./constants";
import DownArrow from "./DownArrow";
import RightArrow from "./RightArrow";

interface IProps {
attrSearch: string;
title: string;
nodeAttrs: Record<string, any>;
attrs: IAttr[];
Expand All @@ -12,21 +15,40 @@ interface IProps {
}

export default function Attributes({
attrSearch,
title,
nodeAttrs,
attrs,
custom,
updateAttr,
}: IProps) {
const [expanded, setExpanded] = useState<boolean>(true);

const copyToClipBoard = () => {
bridge(
`window.copy(window.__KONVA_DEVTOOLS_GLOBAL_HOOK__ && window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.selection.selected().attrs)`
);
};

const renderArrow = () => {
return (
<div
className="expand-collapse-toggle"
onClick={() => setExpanded((v) => !v)}
>
{expanded ? <DownArrow /> : <RightArrow />}
</div>
);
};

const filteredAttrs = attrs.filter((item) =>
item.name.toLowerCase().startsWith(attrSearch.toLowerCase())
);

return (
<div className="attributes">
<div className="header-row">
{renderArrow()}
<div className="header">{title}</div>
<button
className="button"
Expand All @@ -38,91 +60,103 @@ export default function Attributes({
</span>
</button>
</div>
<div className="attr-list">
{attrs.map((item) => {
let input;
{expanded && (
<div className="attr-list">
{filteredAttrs.map((item) => {
let input;

switch (item.type) {
case "boolean": {
input = (
<input
type="checkbox"
checked={
nodeAttrs[item.name] === undefined
? item.defaultValue !== undefined
? item.defaultValue
: true
: nodeAttrs[item.name]
}
onChange={(e) => updateAttr(item.name, e.target.checked)}
/>
);
break;
}
case "number": {
input = (
<input
value={
nodeAttrs[item.name] !== undefined
? nodeAttrs[item.name]
: ""
}
type="number"
placeholder="<default>"
onChange={(e) =>
updateAttr(
item.name,
isNaN(e.target.valueAsNumber)
? null // JSON.stringify will not preserve undefined, so we have to use null here
: e.target.valueAsNumber
)
}
min={item.min}
/>
);
break;
}
case "json": {
input = (
<textarea
value={
nodeAttrs[item.name] !== undefined
? JSON.stringify(nodeAttrs[item.name])
: ""
}
placeholder="<default>"
onChange={(e) =>
updateAttr(item.name, JSON.parse(e.target.value))
}
/>
);
break;
switch (item.type) {
case "boolean": {
input = (
<input
type="checkbox"
checked={
nodeAttrs[item.name] === undefined
? item.defaultValue !== undefined
? item.defaultValue
: true
: nodeAttrs[item.name]
}
onChange={(e) => updateAttr(item.name, e.target.checked)}
/>
);
break;
}
case "number": {
input = (
<input
value={
nodeAttrs[item.name] !== undefined
? nodeAttrs[item.name]
: ""
}
type="number"
placeholder="<default>"
onChange={(e) =>
updateAttr(
item.name,
isNaN(e.target.valueAsNumber)
? null // JSON.stringify will not preserve undefined, so we have to use null here
: e.target.valueAsNumber
)
}
min={item.min}
/>
);
break;
}
case "json": {
input = (
<textarea
value={
nodeAttrs[item.name] !== undefined
? JSON.stringify(nodeAttrs[item.name])
: ""
}
placeholder="<default>"
onChange={(e) =>
updateAttr(item.name, JSON.parse(e.target.value))
}
/>
);
break;
}
default: {
input = (
<input
value={
nodeAttrs[item.name] !== undefined
? nodeAttrs[item.name]
: ""
}
type="text"
placeholder="<default>"
onChange={(e) => updateAttr(item.name, e.target.value)}
/>
);
}
}
default: {
input = (
<input
value={
nodeAttrs[item.name] !== undefined
? nodeAttrs[item.name]
: ""
}
type="text"
placeholder="<default>"
onChange={(e) => updateAttr(item.name, e.target.value)}
/>
);
}
}
return (
<div className="attr-item" key={item.name}>
<span className={`item-name ${custom ? "key-name" : ""}`}>
{item.name}:
</span>
{input}
</div>
);
})}
</div>
return (
<div className="attr-item" key={item.name}>
<span className={`item-name ${custom ? "key-name" : ""}`}>
{attrSearch.length ? (
<>
<mark className="current-highlight">
{item.name.slice(0, attrSearch.length)}
</mark>
<span>{item.name.slice(attrSearch.length)}</span>
</>
) : (
<>{item.name}</>
)}
:
</span>
{input}
</div>
);
})}
</div>
)}
</div>
);
}
33 changes: 28 additions & 5 deletions src/pages/panel/components/InspectedElement.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useEffect, useState } from "react";
import { bridge } from "..";
import { OutlineNode } from "../types";
import { ATTRS, SHAPE_ATTRS, SHAPE_CUSTOM_ATTRS } from "./constants";
import { NODE_ATTRS, SHAPE_ATTRS, SHAPE_CUSTOM_ATTRS } from "./constants";
import Attributes from "./Attributes";
import SearchIcon from "./SearchIcon";

interface IProps {
selectedNode: OutlineNode | null;
Expand All @@ -12,6 +13,7 @@ export default function InspectedElement({ selectedNode }: IProps) {
// we create a state to store attrs to provide smooth update when we change attrs
// otherwise if rely on "selectedNode" interval to update will make it looks laggy
const [nodeAttrs, setNodeAttrs] = useState<Record<string, any>>({});
const [attrSearch, setAttrSearch] = useState<string>("");

useEffect(() => {
if (selectedNode) {
Expand All @@ -35,8 +37,6 @@ export default function InspectedElement({ selectedNode }: IProps) {
}));
};

const attrs = selectedNode?.isShape ? SHAPE_ATTRS : ATTRS;

return (
<>
<div className="title-row">
Expand All @@ -48,11 +48,23 @@ export default function InspectedElement({ selectedNode }: IProps) {
</>
)}
</div>
{selectedNode && (
<div className="search-input-item">
<SearchIcon />
<input
className="input"
placeholder="Search attributes..."
value={attrSearch}
onChange={(e) => setAttrSearch(e.target.value)}
/>
</div>
)}
<div className="inspected-element-data">
{selectedNode && (
<>
{SHAPE_CUSTOM_ATTRS[selectedNode.className] && (
<Attributes
attrSearch={attrSearch}
title={`${selectedNode.className} Attributes`}
attrs={SHAPE_CUSTOM_ATTRS[selectedNode.className]}
nodeAttrs={nodeAttrs}
Expand All @@ -61,9 +73,20 @@ export default function InspectedElement({ selectedNode }: IProps) {
/>
)}

{selectedNode?.isShape && (
<Attributes
attrSearch={attrSearch}
title="Shape Attributes"
attrs={SHAPE_ATTRS}
nodeAttrs={nodeAttrs}
updateAttr={updateAttr}
/>
)}

<Attributes
title="Attributes"
attrs={attrs}
attrSearch={attrSearch}
title="Node Attributes"
attrs={NODE_ATTRS}
nodeAttrs={nodeAttrs}
updateAttr={updateAttr}
/>
Expand Down
Loading

0 comments on commit 0055fc3

Please sign in to comment.