This commit is contained in:
Stefan Pejcic
2024-05-08 19:52:27 +02:00
parent 9c8d080b57
commit 80303fadd5
2509 changed files with 0 additions and 594172 deletions

View File

@@ -1,11 +0,0 @@
node_modules
.DS_Store
test
jest.config.js
**/*.spec.ts
**/*.spec.tsx
**/*.test.ts
**/*.test.tsx
tsup.config.ts
tsconfig.test.json
tsconfig.declarations.json

View File

@@ -1,220 +0,0 @@
# @refinedev/devtools
## 1.1.30
### Patch Changes
- Updated dependencies [[`fda3494215`](https://github.com/refinedev/refine/commit/fda349421509197b5a2be225bd3794adb2a7925c)]:
- @refinedev/cli@2.16.22
## 1.1.29
### Patch Changes
- [#5425](https://github.com/refinedev/refine/pull/5425) [`190af9fce2`](https://github.com/refinedev/refine/commit/190af9fce292bc46b169e3e121be6bf1c2a939a5) Thanks [@aliemir](https://github.com/aliemir)! - Updated `@refinedev/core` peer dependencies to latest (`^4.46.1`)
- Updated dependencies [[`190af9fce2`](https://github.com/refinedev/refine/commit/190af9fce292bc46b169e3e121be6bf1c2a939a5)]:
- @refinedev/cli@2.16.21
## 1.1.28
### Patch Changes
- Updated dependencies [[`1b031a2c19`](https://github.com/refinedev/refine/commit/1b031a2c19126ec1c01a85ecfbc794dc82480776), [`1b031a2c19`](https://github.com/refinedev/refine/commit/1b031a2c19126ec1c01a85ecfbc794dc82480776)]:
- @refinedev/devtools-server@1.1.22
- @refinedev/cli@2.16.20
## 1.1.27
### Patch Changes
- Updated dependencies [[`714841da4b24`](https://github.com/refinedev/refine/commit/714841da4b24ef0b392eb9cbb7320cb3be122292)]:
- @refinedev/cli@2.16.19
## 1.1.26
### Patch Changes
- Updated dependencies [[`404f16a947f3`](https://github.com/refinedev/refine/commit/404f16a947f330aad494f11545022684133bf2d0)]:
- @refinedev/cli@2.16.18
## 1.1.25
### Patch Changes
- Updated dependencies [[`97d5d9c98b28`](https://github.com/refinedev/refine/commit/97d5d9c98b28a1d69cada0a746202f82bec45622)]:
- @refinedev/cli@2.16.17
## 1.1.24
### Patch Changes
- Updated dependencies []:
- @refinedev/devtools-server@1.1.21
- @refinedev/cli@2.16.16
## 1.1.23
### Patch Changes
- Updated dependencies [[`72f9f608f42`](https://github.com/refinedev/refine/commit/72f9f608f4205cf4f3266068326d029546cd9f88), [`72f9f608f42`](https://github.com/refinedev/refine/commit/72f9f608f4205cf4f3266068326d029546cd9f88)]:
- @refinedev/devtools-server@1.1.20
- @refinedev/cli@2.16.15
## 1.1.22
### Patch Changes
- Updated dependencies []:
- @refinedev/devtools-server@1.1.19
- @refinedev/cli@2.16.14
## 1.1.21
### Patch Changes
- Updated dependencies []:
- @refinedev/devtools-server@1.1.18
- @refinedev/cli@2.16.13
## 1.1.20
### Patch Changes
- Updated dependencies [[`2bd813f62bf`](https://github.com/refinedev/refine/commit/2bd813f62bf55eb1be55ffe5b2c1c7079d7a93f0), [`b5f93f60f1d`](https://github.com/refinedev/refine/commit/b5f93f60f1d9d7ed105cf50512b090337a4dde2d), [`38f2a9b2e71`](https://github.com/refinedev/refine/commit/38f2a9b2e7149ad3d5e5c2780e05ddde0285ac3c)]:
- @refinedev/devtools-server@1.1.17
- @refinedev/cli@2.16.12
## 1.1.19
### Patch Changes
- Updated dependencies [[`2bd813f62bf`](https://github.com/refinedev/refine/commit/2bd813f62bf55eb1be55ffe5b2c1c7079d7a93f0), [`b5f93f60f1d`](https://github.com/refinedev/refine/commit/b5f93f60f1d9d7ed105cf50512b090337a4dde2d), [`38f2a9b2e71`](https://github.com/refinedev/refine/commit/38f2a9b2e7149ad3d5e5c2780e05ddde0285ac3c)]:
- @refinedev/devtools-server@1.1.16
- @refinedev/cli@2.16.11
## 1.1.18
### Patch Changes
- Updated dependencies [[`be419eb31bc`](https://github.com/refinedev/refine/commit/be419eb31bc7b7a3934f39bcfcbaaa0b9db60be8)]:
- @refinedev/devtools-server@1.1.15
- @refinedev/cli@2.16.10
## 1.1.17
### Patch Changes
- Updated dependencies [[`be419eb31bc`](https://github.com/refinedev/refine/commit/be419eb31bc7b7a3934f39bcfcbaaa0b9db60be8)]:
- @refinedev/devtools-server@1.1.14
- @refinedev/cli@2.16.9
## 1.1.16
### Patch Changes
- Updated dependencies [[`78117485899`](https://github.com/refinedev/refine/commit/781174858992bb1d077069d2858a37b44344879e)]:
- @refinedev/devtools-server@1.1.13
- @refinedev/cli@2.16.8
## 1.1.15
### Patch Changes
- Updated dependencies [[`78117485899`](https://github.com/refinedev/refine/commit/781174858992bb1d077069d2858a37b44344879e)]:
- @refinedev/devtools-server@1.1.12
- @refinedev/cli@2.16.7
## 1.1.14
### Patch Changes
- [#5127](https://github.com/refinedev/refine/pull/5127) [`4f89ca46ac4`](https://github.com/refinedev/refine/commit/4f89ca46ac4af5c1eddf842bddd3d981f0e47556) Thanks [@aliemir](https://github.com/aliemir)! - Update panel and pin positioning for rounded numbers to avoid subpixel blurry rendering
## 1.1.13
### Patch Changes
- [#5127](https://github.com/refinedev/refine/pull/5127) [`4f89ca46ac4`](https://github.com/refinedev/refine/commit/4f89ca46ac4af5c1eddf842bddd3d981f0e47556) Thanks [@aliemir](https://github.com/aliemir)! - Update panel and pin positioning for rounded numbers to avoid subpixel blurry rendering
## 1.1.12
### Patch Changes
- [#5082](https://github.com/refinedev/refine/pull/5082) [`61366ebd866`](https://github.com/refinedev/refine/commit/61366ebd86694328fe5a7f4dcf322db3c43bbc9d) Thanks [@aliemir](https://github.com/aliemir)! - Fixed the server/client mismatch error due to `<DevtoolsPanel />` component.
- Updated dependencies [[`61366ebd866`](https://github.com/refinedev/refine/commit/61366ebd86694328fe5a7f4dcf322db3c43bbc9d), [`6c40a720140`](https://github.com/refinedev/refine/commit/6c40a720140a8fe7141033a282500d354b1e621f)]:
- @refinedev/devtools-server@1.1.11
- @refinedev/cli@2.16.6
## 1.1.11
### Patch Changes
- [#5082](https://github.com/refinedev/refine/pull/5082) [`61366ebd866`](https://github.com/refinedev/refine/commit/61366ebd86694328fe5a7f4dcf322db3c43bbc9d) Thanks [@aliemir](https://github.com/aliemir)! - Fixed the server/client mismatch error due to `<DevtoolsPanel />` component.
- Updated dependencies [[`61366ebd866`](https://github.com/refinedev/refine/commit/61366ebd86694328fe5a7f4dcf322db3c43bbc9d), [`6c40a720140`](https://github.com/refinedev/refine/commit/6c40a720140a8fe7141033a282500d354b1e621f)]:
- @refinedev/devtools-server@1.1.10
- @refinedev/cli@2.16.5
## 1.1.10
### Patch Changes
- [#26](https://github.com/TheRakeshPurohit/refine/pull/26) [`7533e541739`](https://github.com/refinedev/refine/commit/7533e541739faadffb763feef8739ac46f62bd17) Thanks [@pull](https://github.com/apps/pull)! - Use the proper devtools url coming from the websocket handshake rather than using the hardcoded port.
- Updated dependencies [[`7533e541739`](https://github.com/refinedev/refine/commit/7533e541739faadffb763feef8739ac46f62bd17), [`7533e541739`](https://github.com/refinedev/refine/commit/7533e541739faadffb763feef8739ac46f62bd17)]:
- @refinedev/cli@2.16.4
- @refinedev/devtools-server@1.1.9
## 1.1.9
### Patch Changes
- [#5056](https://github.com/refinedev/refine/pull/5056) [`1fa531ebe89`](https://github.com/refinedev/refine/commit/1fa531ebe89bdab2af0dd57db121e2c0e72d44e8) Thanks [@aliemir](https://github.com/aliemir)! - Use the proper devtools url coming from the websocket handshake rather than using the hardcoded port.
- Updated dependencies [[`68f24d5b596`](https://github.com/refinedev/refine/commit/68f24d5b596eaf1b5b1690c7a57baf3e93fcf42b), [`1fa531ebe89`](https://github.com/refinedev/refine/commit/1fa531ebe89bdab2af0dd57db121e2c0e72d44e8)]:
- @refinedev/cli@2.16.3
- @refinedev/devtools-server@1.1.8
## 1.1.8
### Patch Changes
- [#5056](https://github.com/refinedev/refine/pull/5056) [`1fa531ebe89`](https://github.com/refinedev/refine/commit/1fa531ebe89bdab2af0dd57db121e2c0e72d44e8) Thanks [@aliemir](https://github.com/aliemir)! - Use the proper devtools url coming from the websocket handshake rather than using the hardcoded port.
- Updated dependencies [[`68f24d5b596`](https://github.com/refinedev/refine/commit/68f24d5b596eaf1b5b1690c7a57baf3e93fcf42b), [`1fa531ebe89`](https://github.com/refinedev/refine/commit/1fa531ebe89bdab2af0dd57db121e2c0e72d44e8)]:
- @refinedev/cli@2.16.2
- @refinedev/devtools-server@1.1.7
![refine devtools](https://github.com/refinedev/refine/assets/1110414/15ed6907-d0c8-4213-9024-2f6b0a09968f)
## 1.0.0
### Major Changes
- [#4960](https://github.com/refinedev/refine/pull/4960) [`d8e464fa2c4`](https://github.com/refinedev/refine/commit/d8e464fa2c461d0fd60050cf18247758ecdc42e3) Thanks [@aliemir](https://github.com/aliemir)! - Initial beta release of refine devtools.🎉
We're releasing refine devtools in beta. refine devtools is designed to help you debug and develop your refine apps. It will be a collection of features including monitoring queries and mutations, testing out inferencer generated codes, adding and updating refine packages from the UI and more. 🤯
## Usage
Install latest version of `@refinedev/cli`:
```bash
npm install @refinedev/cli@latest
```
> 🚨 If you don't have `@refinedev/cli` installed already, you can follow the [installation guide](https://refine.dev/docs/packages/documentation/cli/#how-to-add-to-an-existing-project) to add it to your project.
Install `@refinedev/devtools` with `@refinedev/cli`
```bash
npm run refine devtools init
```
![devtools-install](https://github.com/refinedev/refine/assets/23058882/7d7341cc-1edd-4cf3-b330-1796c6a8afc5)
Ta-da! 🎉 Everything is ready now, you can use the refine devtools in your project! 🕶
> Devtools only works in development mode and have no overhead on production builds. You don't need to do anything special to exclude DevTools from your bundle.

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 Refine Dev Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,39 +0,0 @@
<div align="center" style="margin: 30px;">
<a href="https://refine.dev">
<img alt="refine logo" src="https://refine.ams3.cdn.digitaloceanspaces.com/readme/refine-readme-banner.png">
</a>
</div>
<br/>
<div align="center">refine is an open-source, headless React framework for developers building enterprise web applications.
It eliminates repetitive tasks in CRUD operations and provides industry-standard solutions for critical project components like **authentication**, **access control**, **routing**, **networking**, **state management**, and **i18n**.
</div>
---
![refine devtools](https://github.com/refinedev/refine/assets/1110414/15ed6907-d0c8-4213-9024-2f6b0a09968f)
We're releasing refine devtools in beta. refine devtools is designed to help you debug and develop your refine apps. It will be a collection of features including monitoring queries and mutations, testing out inferencer generated codes, adding and updating refine packages from the UI and more. 🤯
## Usage
Install latest version of `@refinedev/cli`:
```bash
npm install @refinedev/cli@latest
```
Install `@refinedev/devtools` with `@refinedev/cli`
```bash
npm run refine devtools init
```
> 🚨 If you don't have `@refinedev/cli` installed already, you can follow the [installation guide](https://refine.dev/docs/packages/documentation/cli/#how-to-add-to-an-existing-project) to add it to your project.
![devtools-install](https://github.com/refinedev/refine/assets/23058882/7d7341cc-1edd-4cf3-b330-1796c6a8afc5)
Ta-da! 🎉 Everything is ready now, you can use the refine devtools in your project! 🕶
> Devtools only works in development mode and have no overhead on production builds. You don't need to do anything special to exclude DevTools from your bundle.

View File

@@ -1,15 +0,0 @@
module.exports = {
preset: "ts-jest",
rootDir: "./",
displayName: "react-hook-form",
testPathIgnorePatterns: ["<rootDir>/node_modules/", "<rootDir>/dist/"],
testEnvironment: "jsdom",
transform: {
"^.+\\.tsx?$": [
"ts-jest",
{
tsconfig: "<rootDir>/tsconfig.test.json",
},
],
},
};

View File

@@ -1,62 +0,0 @@
{
"version": "1.1.30",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"private": false,
"sideEffects": false,
"files": [
"dist",
"src"
],
"engines": {
"node": ">=10"
},
"scripts": {
"start": "tsup --watch --format esm,cjs,iife --legacy-output",
"build": "tsup --format esm,cjs,iife --minify --legacy-output",
"test": "jest --passWithNoTests --runInBand",
"prepare": "npm run build"
},
"name": "@refinedev/devtools",
"description": "refine devtools offers a set of features from monitoring to quickly prototyping a UI.",
"author": "refine",
"module": "dist/esm/index.js",
"dependencies": {
"@aliemir/dom-to-fiber-utils": "^0.4.0",
"@refinedev/devtools-shared": "1.1.2",
"error-stack-parser": "^2.1.4",
"lodash-es": "^4.17.21",
"lodash": "^4.17.21"
},
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0",
"@types/react": "^17.0.0 || ^18.0.0",
"@types/react-dom": "^17.0.0 || ^18.0.0",
"@refinedev/devtools-server": "1.1.22",
"@refinedev/cli": "2.16.22",
"@refinedev/core": "^4.46.1"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@esbuild-plugins/node-resolve": "^0.1.4",
"@types/jest": "^29.2.4",
"@types/lodash": "^4.14.171",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
"react-router-dom": "^6.8.1",
"ts-jest": "^29.0.3",
"tslib": "^2.3.1",
"tsup": "^6.7.0"
},
"repository": {
"type": "git",
"url": "https://github.com/refinedev/refine.git",
"directory": "packages/devtools"
},
"gitHead": "829f5a516f98c06f666d6be3e6e6099c75c07719",
"publishConfig": {
"access": "public"
}
}

View File

@@ -1,63 +0,0 @@
import React from "react";
import { DevtoolsSelector } from "./devtools-selector";
import { DevtoolsIcon } from "./icons/devtools-icon";
import { SelectorButtonIcon } from "./icons/selector-button";
type Props = {
onClick?: () => void;
groupHover?: boolean;
onSelectorHighlight: (name: string) => void;
onSelectorOpen: () => void;
};
export const DevtoolsPin = ({
onClick,
onSelectorHighlight,
onSelectorOpen,
}: Props) => {
const [hover, setHover] = React.useState(false);
return (
<div
onMouseOver={() => setHover(true)}
onMouseOut={() => setHover(false)}
style={{
position: "relative",
userSelect: "none",
WebkitUserSelect: "none",
background: "none",
border: "none",
padding: 0,
paddingRight: "1px",
margin: 0,
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: "pointer",
color: hover ? "#0FBDBD" : "#6C7793",
transition: "color 0.1s ease-in-out",
}}
onClick={onClick}
>
<DevtoolsIcon />
<DevtoolsSelector
style={{
position: "absolute",
top: 5,
right: 18,
width: "16px",
height: "16px",
}}
icon={
<SelectorButtonIcon
width={16}
height={16}
style={{ pointerEvents: "none" }}
/>
}
onSelectorOpen={onSelectorOpen}
onHighlight={onSelectorHighlight}
/>
</div>
);
};

View File

@@ -1,112 +0,0 @@
import React from "react";
import { createPortal } from "react-dom";
import { useSelector } from "src/utilities/use-selector";
import { SelectorBox } from "./selector-box";
import { SelectorHint } from "./selector-hint";
type Props = {
onSelectorOpen: () => void;
onHighlight: (name: string) => void;
icon?: React.ReactNode;
style?: React.CSSProperties;
};
export const DevtoolsSelector = ({
onSelectorOpen,
onHighlight,
icon,
style,
}: Props) => {
const [hover, setHover] = React.useState(false);
const [active, setActive] = React.useState(false);
const { rect, name } = useSelector(active);
const [selectorBoxRoot, setSelectorBoxRoot] =
React.useState<HTMLElement | null>(null);
React.useEffect(() => {
if (!selectorBoxRoot) {
const element = document.createElement("div");
element.id = "selector-box-root";
document.body.appendChild(element);
setSelectorBoxRoot(element);
}
}, []);
React.useEffect(() => {
if (active) {
document.body.style.cursor = "crosshair";
} else {
document.body.style.cursor = "default";
}
}, [active]);
React.useEffect(() => {
const onMouseClick = (e: MouseEvent) => {
if (!active) return;
if (!name) return;
e?.preventDefault();
e?.stopPropagation();
e.stopImmediatePropagation();
onHighlight(name);
setActive(false);
};
if (active) {
document.addEventListener("click", onMouseClick, {
capture: true,
});
return () => {
document.removeEventListener("click", onMouseClick, {
capture: true,
});
};
}
return () => 0;
}, [name, onHighlight, active]);
React.useEffect(() => {
if (active) {
onSelectorOpen();
}
}, [active, onSelectorOpen]);
return (
<div style={style}>
<div
role="button"
title="Element Selector"
onMouseOver={() => setHover(true)}
onMouseOut={() => setHover(false)}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
(document?.activeElement as HTMLElement)?.blur();
setActive((active) => !active);
}}
style={{
padding: 0,
margin: 0,
height: "100%",
width: "100%",
transform: hover ? "rotate(180deg)" : "rotate(0deg)",
transition: "transform 0.2s ease-in-out",
}}
>
{icon}
</div>
<SelectorHint active={active} />
{active &&
selectorBoxRoot &&
createPortal(
<SelectorBox {...rect} name={name} />,
selectorBoxRoot,
)}
</div>
);
};

View File

@@ -1,33 +0,0 @@
import * as React from "react";
import { SVGProps } from "react";
export const ArrowUnionIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={16}
height={16}
viewBox="0 0 16 16"
fill="none"
{...props}
>
<path
fill="#303450"
stroke="url(#arrow-union-icon)"
d="M.5 8.495V15.5h15V8.495a4.5 4.5 0 0 1-3.816-2.483L9.341 1.33c-.553-1.105-2.13-1.105-2.683 0L4.317 6.012A4.5 4.5 0 0 1 .5 8.495Z"
/>
<defs>
<linearGradient
id="arrow-union-icon"
x1={8}
x2={8}
y1={0}
y2={10}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#474E6B" />
<stop offset={0.9} stopColor="#474E6B" />
<stop offset={0.901} stopColor="#474E6B" stopOpacity={0} />
</linearGradient>
</defs>
</svg>
);

View File

@@ -1,35 +0,0 @@
import * as React from "react";
import { SVGProps } from "react";
export const DevtoolsIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={157}
height={25}
viewBox="0 0 157 25"
fill="none"
{...props}
>
<g>
<path fill="#1D1E30" d="M17 1h123v24H17z" />
<path
fill="#1D1E30"
d="M6.265 9.205A12 12 0 0 1 17.649 1H25v24H1L6.265 9.205ZM150.735 9.205A12 12 0 0 0 139.351 1H132v24h24l-5.265-15.795Z"
/>
<path
fill="currentColor"
d="M25 14.333A1.333 1.333 0 1 1 25 17a1.333 1.333 0 0 1 0-2.667Z"
/>
<path
fill="currentColor"
fillRule="evenodd"
d="M23.211 20.578a4 4 0 0 0 3.578 0l4-2A4 4 0 0 0 33 15v-4a4 4 0 0 0-2.211-3.578l-4-2a4 4 0 0 0-3.578 0l-4 2A4 4 0 0 0 17 11v4a4 4 0 0 0 2.211 3.578l4 2Zm-.878-4.911a2.667 2.667 0 0 0 5.334 0v-5.334a2.667 2.667 0 0 0-5.334 0v5.334Z"
clipRule="evenodd"
/>
<path
fill="#CFD7E2"
d="M42.152 17a.287.287 0 0 1-.192-.072.287.287 0 0 1-.072-.192V9.032c0-.072.024-.132.072-.18a.264.264 0 0 1 .192-.084h4.2c.288 0 .56.056.816.168a2.135 2.135 0 0 1 1.14 1.128c.112.256.168.532.168.828v3.984c0 .296-.056.572-.168.828a2.135 2.135 0 0 1-1.14 1.128 2.014 2.014 0 0 1-.816.168h-4.2Zm1.38-1.644h2.82a.455.455 0 0 0 .336-.132.497.497 0 0 0 .132-.348v-3.984a.455.455 0 0 0-.132-.336.436.436 0 0 0-.336-.144h-2.82v4.944Zm13.18-5.196a.244.244 0 0 1-.253.252h-4.44v1.656h4.02c.072 0 .132.024.18.072a.227.227 0 0 1 .084.18v1.128a.264.264 0 0 1-.084.192.244.244 0 0 1-.18.072h-4.02v1.644h4.44c.072 0 .132.028.18.084a.244.244 0 0 1 .072.18v1.116a.287.287 0 0 1-.072.192.244.244 0 0 1-.18.072h-5.832a.244.244 0 0 1-.18-.072.287.287 0 0 1-.072-.192V9.032c0-.072.024-.132.072-.18a.227.227 0 0 1 .18-.084h5.832c.072 0 .132.028.18.084a.244.244 0 0 1 .072.18v1.128ZM63.014 17h-2.232a.387.387 0 0 1-.216-.072.356.356 0 0 1-.144-.168l-1.716-4.296a.853.853 0 0 1-.072-.24 1.783 1.783 0 0 1-.024-.264V9.032c0-.072.024-.132.072-.18a.227.227 0 0 1 .18-.084h1.128c.072 0 .132.028.18.084a.227.227 0 0 1 .084.18v2.616c0 .072.008.156.024.252s.04.176.072.24l1.284 3.216h.528l1.284-3.216a.853.853 0 0 0 .072-.24c.016-.096.024-.18.024-.252V9.032c0-.072.024-.132.072-.18a.264.264 0 0 1 .192-.084h1.128c.072 0 .132.028.18.084a.244.244 0 0 1 .072.18v2.928c0 .072-.008.16-.024.264a.853.853 0 0 1-.072.24l-1.716 4.296a.356.356 0 0 1-.144.168.387.387 0 0 1-.216.072ZM73.29 8.768c.072 0 .132.028.18.084a.227.227 0 0 1 .084.18v1.128a.227.227 0 0 1-.084.18.244.244 0 0 1-.18.072h-2.208v6.324a.264.264 0 0 1-.084.192.244.244 0 0 1-.18.072H69.69a.244.244 0 0 1-.18-.072.287.287 0 0 1-.072-.192v-6.324H67.23a.287.287 0 0 1-.192-.072.244.244 0 0 1-.072-.18V9.032c0-.072.024-.132.072-.18a.264.264 0 0 1 .192-.084h6.06Zm6.507.012c.296 0 .572.056.828.168a2.171 2.171 0 0 1 1.128 1.128c.112.256.168.528.168.816v3.996c0 .288-.056.56-.168.816a2.171 2.171 0 0 1-1.128 1.128 2.043 2.043 0 0 1-.828.168h-2.34c-.296 0-.572-.056-.828-.168a2.171 2.171 0 0 1-1.128-1.128 2.014 2.014 0 0 1-.168-.816v-3.996c0-.288.056-.56.168-.816a2.171 2.171 0 0 1 1.128-1.128c.256-.112.532-.168.828-.168h2.34Zm.48 2.112a.436.436 0 0 0-.144-.336.455.455 0 0 0-.336-.132h-2.34a.497.497 0 0 0-.348.132.455.455 0 0 0-.132.336v3.996c0 .136.044.248.132.336a.497.497 0 0 0 .348.132h2.34a.455.455 0 0 0 .336-.132.436.436 0 0 0 .144-.336v-3.996Zm7.888-2.112c.295 0 .572.056.828.168a2.171 2.171 0 0 1 1.128 1.128c.112.256.168.528.168.816v3.996c0 .288-.056.56-.168.816a2.171 2.171 0 0 1-1.128 1.128 2.043 2.043 0 0 1-.828.168h-2.34c-.297 0-.573-.056-.829-.168a2.171 2.171 0 0 1-1.127-1.128 2.014 2.014 0 0 1-.168-.816v-3.996c0-.288.056-.56.168-.816a2.171 2.171 0 0 1 1.127-1.128c.257-.112.532-.168.829-.168h2.34Zm.48 2.112a.436.436 0 0 0-.144-.336.455.455 0 0 0-.337-.132h-2.34a.497.497 0 0 0-.347.132.455.455 0 0 0-.133.336v3.996c0 .136.044.248.133.336a.497.497 0 0 0 .347.132h2.34a.455.455 0 0 0 .337-.132.436.436 0 0 0 .143-.336v-3.996ZM98.294 17H92.68a.287.287 0 0 1-.192-.072.287.287 0 0 1-.072-.192V9.032c0-.072.024-.132.072-.18a.264.264 0 0 1 .192-.084h1.116c.072 0 .132.028.18.084a.227.227 0 0 1 .084.18v6.324h4.236c.072 0 .132.028.18.084a.244.244 0 0 1 .072.18v1.116a.287.287 0 0 1-.072.192.244.244 0 0 1-.18.072Zm7.336-5.76a.287.287 0 0 1-.192-.072.287.287 0 0 1-.072-.192v-.084a.455.455 0 0 0-.132-.336.436.436 0 0 0-.336-.144h-2.352a.46.46 0 0 0-.336.144.455.455 0 0 0-.132.336v.696c0 .136.044.252.132.348a.482.482 0 0 0 .336.132h2.352c.288 0 .56.056.816.168a2.171 2.171 0 0 1 1.128 1.128c.112.256.168.528.168.816v.696c0 .296-.056.572-.168.828a2.171 2.171 0 0 1-1.128 1.128 2.014 2.014 0 0 1-.816.168h-2.352c-.288 0-.56-.056-.816-.168a2.171 2.171 0 0 1-1.128-1.128 2.043 2.043 0 0 1-.168-.828v-.084c0-.072.024-.132.072-.18a.264.264 0 0 1 .192-.084h1.116c.072 0 .132.028.18.084a.227.227 0 0 1 .084.18v.084c0 .136.044.252.132.348a.482.482 0 0 0 .336.132h2.352a.455.455 0 0 0 .336-.132.497.497 0 0 0 .132-.348v-.696a.455.455 0 0 0-.132-.336.455.455 0 0 0-.336-.132h-2.352c-.288 0-.56-.056-.816-.168a2.171 2.171 0 0 1-1.128-1.128 2.099 2.099 0 0 1-.168-.828v-.696c0-.296.056-.572.168-.828a2.171 2.171 0 0 1 1.128-1.128c.256-.112.528-.168.816-.168h2.352c.288 0 .56.056.816.168a2.171 2.171 0 0 1 1.128 1.128c.112.256.168.532.168.828v.084a.287.287 0 0 1-.072.192.244.244 0 0 1-.18.072h-1.128Z"
/>
</g>
</svg>
);

View File

@@ -1,27 +0,0 @@
import React from "react";
export const ResizeHandleIcon = (props: React.SVGProps<SVGSVGElement>) => (
<svg
width={10}
height={26}
viewBox="0 0 10 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<rect x={0.5} y={0.5} width={9} height={25} rx={4.5} fill="#1D1E30" />
<path
d="M7 5C7 6.10457 6.10457 7 5 7C3.89543 7 3 6.10457 3 5C3 3.89543 3.89543 3 5 3C6.10457 3 7 3.89543 7 5Z"
fill="#303450"
/>
<path
d="M7 13C7 14.1046 6.10457 15 5 15C3.89543 15 3 14.1046 3 13C3 11.8954 3.89543 11 5 11C6.10457 11 7 11.8954 7 13Z"
fill="#303450"
/>
<path
d="M7 21C7 22.1046 6.10457 23 5 23C3.89543 23 3 22.1046 3 21C3 19.8954 3.89543 19 5 19C6.10457 19 7 19.8954 7 21Z"
fill="#303450"
/>
<rect x={0.5} y={0.5} width={9} height={25} rx={4.5} stroke="#303450" />
</svg>
);

View File

@@ -1,19 +0,0 @@
import React from "react";
export const SelectorButtonIcon = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={16}
height={16}
viewBox="0 0 16 16"
fill="none"
{...props}
>
<path
fill="#0FBDBD"
fillRule="evenodd"
d="M9 1a1 1 0 0 0-2 0v2.1A5.006 5.006 0 0 0 3.1 7H1a1 1 0 0 0 0 2h2.1A5.006 5.006 0 0 0 7 12.9V15a1 1 0 1 0 2 0v-2.1A5.006 5.006 0 0 0 12.9 9H15a1 1 0 1 0 0-2h-2.1A5.006 5.006 0 0 0 9 3.1V1Zm2 7a3 3 0 1 0-6 0 3 3 0 0 0 6 0Z"
clipRule="evenodd"
/>
</svg>
);

View File

@@ -1,283 +0,0 @@
import React from "react";
import { Placement } from "src/interfaces/placement";
import {
getDefaultPanelSize,
getMaxPanelHeight,
getMaxPanelWidth,
getPanelPosition,
getPanelToggleTransforms,
MIN_PANEL_HEIGHT,
MIN_PANEL_WIDTH,
roundToEven,
} from "src/utilities";
import { ResizeHandleIcon } from "./icons/resize-handle-icon";
type Props = {
placement: Placement;
defaultWidth?: number;
minWidth?: number;
maxWidth?: number;
defaultHeight?: number;
minHeight?: number;
maxHeight?: number;
children: ({ resizing }: { resizing: string | null }) => React.ReactNode;
onResize?: (width: number, height: number) => void;
visible?: boolean;
};
export const ResizablePane = ({ placement, visible, children }: Props) => {
const [hover, setHover] = React.useState(false);
const [resizing, setResizing] = React.useState<
"lx" | "rx" | "ty" | "by" | null
>(null);
const [resizePosition, setResizePosition] = React.useState<{
x: number;
y: number;
} | null>(null);
const [panelSize, setPanelSize] = React.useState<
Record<"width" | "height", number>
>(() => {
const defaultSize = getDefaultPanelSize(placement);
return {
width: roundToEven(defaultSize.width),
height: roundToEven(defaultSize.height),
};
});
React.useEffect(() => {
const handleResize = () => {
setPanelSize((p) => {
const defaultSize = getDefaultPanelSize(placement, p);
return {
width: roundToEven(defaultSize.width),
height: roundToEven(defaultSize.height),
};
});
};
handleResize();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, [placement]);
React.useEffect(() => {
const handleMouseUp = () => {
setResizing(null);
};
if (resizing !== null) {
window.addEventListener("mouseup", handleMouseUp);
return () => {
window.removeEventListener("mouseup", handleMouseUp);
};
}
return;
}, [resizing]);
React.useEffect(() => {
const currentCursor = document.body.style.cursor;
if (resizing?.includes("x")) {
document.body.style.cursor = "col-resize";
} else if (resizing?.includes("y")) {
document.body.style.cursor = "row-resize";
}
return () => {
document.body.style.cursor = currentCursor;
};
}, [resizing]);
React.useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (resizing?.[1] === "x") {
const diff = e.clientX - (resizePosition?.x ?? e.clientX);
const newWidth =
panelSize.width + (resizing === "lx" ? -diff : diff) * 2;
setPanelSize((p) => ({
...p,
width: roundToEven(
Math.min(
getMaxPanelWidth(placement),
Math.max(MIN_PANEL_WIDTH, newWidth),
),
),
}));
} else if (resizing?.[1] === "y") {
const diff = e.clientY - (resizePosition?.y ?? e.clientY);
const newHeight =
panelSize.height + (resizing === "ty" ? -diff : diff) * 1;
setPanelSize((p) => ({
...p,
height: roundToEven(
Math.min(
getMaxPanelHeight(placement),
Math.max(MIN_PANEL_HEIGHT, newHeight),
),
),
}));
}
};
if (resizing !== null) {
window.addEventListener("mousemove", handleMouseMove);
return () => {
window.removeEventListener("mousemove", handleMouseMove);
};
}
return;
}, [resizing, placement]);
return (
<div
style={{
position: "absolute",
borderRadius: "8px",
boxShadow: "0 0 10px rgba(0, 0, 0, 0.5)",
border: "1px solid rgba(0, 0, 0, 0.5)",
transitionProperty: "transform, opacity",
transitionTimingFunction: "ease-in-out",
transitionDuration: "0.2s",
...getPanelPosition(placement),
opacity: visible ? 1 : 0,
transform: `${
getPanelPosition(placement).transform
} ${getPanelToggleTransforms(visible ?? false)}`,
...panelSize,
}}
onMouseEnter={() => {
setHover(true);
}}
onMouseLeave={() => {
setHover(false);
}}
>
{children({ resizing })}
{/* */}
<React.Fragment>
<div
style={{
position: "absolute",
left: 0,
top: "50%",
width: "10px",
height: "26px",
transform: "translateY(-13px) translateX(-5px)",
cursor: "col-resize",
transition: "opacity ease-in-out 0.2s",
pointerEvents: hover || resizing ? "auto" : "none",
opacity: hover || resizing ? 1 : 0,
}}
onMouseDown={(event) => {
setResizing("lx");
setResizePosition({
x: event.clientX,
y: event.clientY,
});
event.preventDefault();
}}
>
<ResizeHandleIcon />
</div>
<div
style={{
position: "absolute",
right: 0,
top: "50%",
width: "10px",
height: "26px",
transform: `translateY(-13px) translateX(5px)`,
cursor: "col-resize",
transition: "opacity ease-in-out 0.2s",
pointerEvents: hover || resizing ? "auto" : "none",
opacity: hover || resizing ? 1 : 0,
}}
onMouseDown={(event) => {
setResizing("rx");
setResizePosition({
x: event.clientX,
y: event.clientY,
});
event.preventDefault();
}}
>
<ResizeHandleIcon />
</div>
<div
style={{
position: "absolute",
left: "50%",
top: 0,
width: "26px",
height: "10px",
transform: "translateY(-5px) translateX(-13px)",
cursor: "row-resize",
transition: "opacity ease-in-out 0.2s",
pointerEvents: hover || resizing ? "auto" : "none",
opacity: hover || resizing ? 1 : 0,
}}
onMouseDown={(event) => {
setResizing("ty");
setResizePosition({
x: event.clientX,
y: event.clientY,
});
event.preventDefault();
}}
>
<ResizeHandleIcon
style={{
transform: "rotate(90deg)",
transformOrigin: "13px 13px",
}}
/>
</div>
<div
style={{
position: "absolute",
left: "50%",
bottom: 0,
width: "26px",
height: "10px",
transform: "translateY(5px) translateX(-13px)",
cursor: "row-resize",
transition: "opacity ease-in-out 0.2s",
pointerEvents: hover || resizing ? "auto" : "none",
opacity: hover || resizing ? 1 : 0,
}}
onMouseDown={(event) => {
setResizing("by");
setResizePosition({
x: event.clientX,
y: event.clientY,
});
event.preventDefault();
}}
>
<ResizeHandleIcon
style={{
transform: "rotate(90deg)",
transformOrigin: "13px 13px",
}}
/>
</div>
</React.Fragment>
</div>
);
};

View File

@@ -1,107 +0,0 @@
import React from "react";
import { ArrowUnionIcon } from "./icons/arrow-union-icon";
const Y_OFFSET = 38;
const X_OFFSET = 7;
export const SelectorBox = ({
width,
height,
x,
y,
name,
}: {
width: number;
height: number;
x: number;
y: number;
name: string;
}) => {
const namePosition =
y > Y_OFFSET ? "top" : height > 3 * Y_OFFSET ? "inset" : "bottom";
const outlinePosition = x > X_OFFSET && y > X_OFFSET ? "outside" : "inside";
return (
<div
id="selector-box"
style={{
pointerEvents: "none",
position: "fixed",
opacity: name ? 1 : 0,
transitionProperty: "width, height, transform, opacity",
transitionDuration: "0.15s",
transitionTimingFunction: "ease-out",
border: "1.5px solid #47EBEB",
borderRadius: "4px",
background: "rgba(37,160,160, 0.25)",
backdropFilter: "sepia(30%) hue-rotate(180deg)",
zIndex: 99998,
...(outlinePosition === "outside"
? {
left: -6,
top: -6,
width: width + 10,
height: height + 10,
transform: `translate(${x}px, ${y}px)`,
}
: {
left: 0,
top: 0,
width: width - 10,
height: height - 20,
transform: `translate(${x + 4}px, ${y + 4}px)`,
}),
}}
>
<div
style={{
position: "absolute",
left: "-1.5px",
background: "#303450",
border: "1px solid #474E6B",
borderRadius: "4px",
padding: "8px 12px",
fontSize: "12px",
lineHeight: "16px",
fontWeight: 400,
color: "#ffffff",
display: name ? "block" : "none",
...(namePosition === "top" && {
top: "-38px",
}),
...(namePosition === "bottom" && {
bottom: "-38px",
}),
...(namePosition === "inset" && {
top: "4px",
left: "8px",
}),
}}
>
{name}
<ArrowUnionIcon
style={{
position: "absolute",
left: "30%",
...(namePosition === "top" && {
transform: "translateX(-50%) rotate(180deg)",
bottom: "-9px",
}),
...(namePosition === "bottom" && {
transform: "translateX(-50%) ",
top: "-9px",
}),
...(namePosition === "inset" && {
transform: "translateX(-50%) rotate(-90deg)",
top: "8px",
left: "-1px",
}),
display: name ? "block" : "none",
}}
/>
</div>
</div>
);
};

View File

@@ -1,57 +0,0 @@
import React from "react";
export const SelectorHint = ({ active }: { active: boolean }) => {
return (
<div
style={{
color: "white",
pointerEvents: "none",
position: "absolute",
left: "calc(-50% - 144px - 14px)",
top: "-36px",
width: "max-content",
borderRadius: "8px",
backgroundColor: "#40414A",
opacity: active ? 1 : 0,
transitionDuration: "0.2s",
transitionProperty: "transform,opacity",
transitionTimingFunction: "ease-in-out",
padding: "8px",
fontSize: "12px",
lineHeight: "12px",
fontWeight: 400,
textShadow:
"0 0 2px #1D1E30, 1px 0 2px #1D1E30, -1px 0 2px #1D1E30, 0 1px 2px #1D1E30, 0 -1px 2px #1D1E30",
}}
>
<kbd
style={{
marginLeft: "4px",
padding: "2px 4px",
borderRadius: "2px",
background: "#1D1E30",
color: "#CFD7E2",
border: "none",
textShadow: "none",
}}
>
shift
</kbd>{" "}
to move to parent.
<kbd
style={{
marginLeft: "4px",
padding: "2px 4px",
borderRadius: "2px",
background: "#1D1E30",
color: "#CFD7E2",
border: "none",
textShadow: "none",
}}
>
space
</kbd>{" "}
to highlight in monitor.
</div>
);
};

View File

@@ -1 +0,0 @@
declare const __DEV_CONDITION__: string;

View File

@@ -1,2 +0,0 @@
export { DevtoolsPanel } from "./panel";
export { DevtoolsProvider } from "./provider";

View File

@@ -1 +0,0 @@
export type Placement = "bottom" | "left" | "right" | "top";

View File

@@ -1,116 +0,0 @@
import React from "react";
import { DevtoolsPin } from "./components/devtools-pin";
import { ResizablePane } from "./components/resizable-pane";
import {
DevToolsContext,
DevtoolsEvent,
send,
} from "@refinedev/devtools-shared";
import { Placement } from "./interfaces/placement";
export const DevtoolsPanel =
__DEV_CONDITION__ !== "development"
? () => null
: () => {
const [browser, setBrowser] = React.useState<boolean>(false);
const [visible, setVisible] = React.useState(false);
const [placement] = React.useState<Placement>("bottom");
const { devtoolsUrl, ws } = React.useContext(DevToolsContext);
const [width, setWidth] = React.useState<number>(0);
const onSelectorHighlight = React.useCallback(
(name: string) => {
if (ws) {
send(
ws,
DevtoolsEvent.DEVTOOLS_HIGHLIGHT_IN_MONITOR,
{
name,
},
);
}
setVisible(true);
},
[ws],
);
const onSelectorOpen = React.useCallback(() => {
setVisible(false);
}, []);
React.useEffect(() => {
if (typeof window !== "undefined") {
setBrowser(true);
}
}, []);
React.useEffect(() => {
if (browser) {
// set width by window size dynamically
setWidth(window.innerWidth);
const onResize = () => {
setWidth(window.innerWidth);
};
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}
return () => undefined;
}, [browser]);
if (!browser) {
return null;
}
return (
<div
style={{
position: "fixed",
left: `${Math.round(width / 2)}px`,
transform: "translateX(-50%)",
bottom: 0,
zIndex: 99999,
}}
>
<DevtoolsPin
onClick={() => setVisible((v) => !v)}
onSelectorHighlight={onSelectorHighlight}
onSelectorOpen={onSelectorOpen}
/>
<ResizablePane visible={visible} placement={placement}>
{({ resizing }) => (
<iframe
allow="clipboard-write;"
src={devtoolsUrl}
srcDoc={
devtoolsUrl
? undefined
: `
<html style="height:100%;padding:0;margin:0;">
<body style="display:flex;justify-content:center;height:100%;padding:24px;margin:0;align-items:center;box-sizing:border-box;">
<h1 style="font-family:ui-monospace,monospace;color:#CFD7E2;text-align:center;">Could not connect to the devtools server</h1>
</body>
</html>
`
}
style={{
width: "100%",
height: "100%",
border: "none",
borderRadius: "7px",
pointerEvents: resizing ? "none" : "auto",
background: "#14141F",
}}
/>
)}
</ResizablePane>
</div>
);
};

View File

@@ -1,11 +0,0 @@
import React from "react";
import { DevToolsContextProvider } from "@refinedev/devtools-shared";
export const DevtoolsProvider =
__DEV_CONDITION__ !== "development"
? ({ children }: React.PropsWithChildren) => children as any
: ({ children }: React.PropsWithChildren) => {
return (
<DevToolsContextProvider>{children}</DevToolsContextProvider>
);
};

View File

@@ -1,124 +0,0 @@
import { Placement } from "src/interfaces/placement";
export const getPanelToggleTransforms = (visible: boolean) => {
return visible ? "scaleX(1) translateY(0)" : `scaleX(0) translateY(25vw)`;
};
export const SIZE = 50;
export const BUFFER = 10;
const PREFERRED_DEFAULT_WIDTH = () =>
typeof window !== "undefined" ? window.innerWidth * 0.7 : 1440 * 0.7; // 70% of window width
const PREFERRED_DEFAULT_HEIGHT = () =>
typeof window !== "undefined" ? window.innerHeight * 0.7 : 900 * 0.7; // 70% of window height
export const MIN_PANEL_WIDTH = 640;
export const MIN_PANEL_HEIGHT = 360;
export const getPinButtonTransform = (hover?: boolean) => {
return `translateY(${hover ? "0" : "50%"})`;
};
export const getPanelPosition = (placement: Placement) => {
switch (placement) {
case "left":
return {
left: `calc(${SIZE}px + ${BUFFER}px)`,
top: "50%",
transform: "translateY(-50%)",
};
case "right":
return {
right: `calc(${SIZE}px + ${BUFFER}px)`,
top: "50%",
transform: "translateY(-50%)",
};
case "top":
return {
left: "50%",
top: `calc(${SIZE}px + ${BUFFER}px)`,
transform: "translateX(-50%)",
};
default:
case "bottom":
return {
left: "50%",
bottom: `calc(${SIZE}px + ${BUFFER}px)`,
transform: "translateX(-50%)",
};
}
};
export const getMaxPanelWidth = (placement: Placement) => {
switch (placement) {
case "left":
case "right":
return (
-BUFFER -
SIZE -
BUFFER +
(typeof window !== "undefined" ? window.innerWidth : 1440) -
BUFFER
);
case "top":
case "bottom":
return (
-BUFFER +
(typeof window !== "undefined" ? window.innerWidth : 1440) -
BUFFER
);
}
};
export const getMaxPanelHeight = (placement: Placement) => {
switch (placement) {
case "left":
case "right":
return (
-BUFFER +
(typeof window !== "undefined" ? window.innerHeight : 900) -
BUFFER
);
case "top":
case "bottom":
return (
-BUFFER -
SIZE -
BUFFER +
(typeof window !== "undefined" ? window.innerHeight : 900) -
BUFFER
);
}
};
export const getDefaultPanelSize = (
placement: Placement,
preferredSize?: { width: number; height: number },
): { width: number; height: number } => {
const defaultPreferred = {
width: PREFERRED_DEFAULT_WIDTH(),
height: PREFERRED_DEFAULT_HEIGHT(),
};
const maxPanelWidth = getMaxPanelWidth(placement);
const maxPanelHeight = getMaxPanelHeight(placement);
const width = Math.min(
maxPanelWidth,
(preferredSize ?? defaultPreferred).width,
);
const height = Math.min(
maxPanelHeight,
(preferredSize ?? defaultPreferred).height,
);
return {
width: width,
height: height,
};
};
export const roundToEven = (num: number) => {
const rounded = Math.round(num);
return rounded % 2 === 0 ? rounded : rounded + 1;
};

View File

@@ -1,259 +0,0 @@
import {
getElementFromFiber,
getFiberFromElement,
getFirstFiberHasName,
getFirstStateNodeFiber,
getNameFromFiber,
getParentOfFiber,
} from "@aliemir/dom-to-fiber-utils";
import { DevToolsContext } from "@refinedev/devtools-shared";
import debounce from "lodash/debounce";
import React from "react";
type Fiber = Exclude<ReturnType<typeof getFiberFromElement>, null>;
export const useSelector = (active: boolean) => {
const { devtoolsUrl } = React.useContext(DevToolsContext);
const [traceItems, setTraceItems] = React.useState<string[]>([]);
React.useEffect(() => {
if (active) {
fetch(
`${
devtoolsUrl ?? "http://localhost:5001"
}/api/unique-trace-items`,
).then((res) =>
res
.json()
.then((data: { data: string[] }) =>
setTraceItems(data.data),
),
);
}
}, [active, devtoolsUrl]);
const [selectedFiber, setSelectedFiber] = React.useState<{
stateNode: Fiber | null;
nameFiber: Fiber | null;
}>({
stateNode: null,
nameFiber: null,
});
const [activeFiber, setActiveFiber] = React.useState<{
stateNode: Fiber | null;
nameFiber: Fiber | null;
derived?: boolean;
}>({
stateNode: null,
nameFiber: null,
derived: false,
});
React.useEffect(() => {
if (active) {
return () => {
setSelectedFiber({
stateNode: null,
nameFiber: null,
});
setActiveFiber({
stateNode: null,
nameFiber: null,
derived: false,
});
};
}
return () => 0;
}, [active]);
const selectAppropriateFiber = React.useCallback(
(start: Fiber | null) => {
let fiber = start;
let firstParentOfNodeWithName: Fiber | null;
let fiberWithStateNode: Fiber | null;
let acceptedName = false;
while (!acceptedName && fiber) {
// Get the first fiber node that has a name (look up the tree)
firstParentOfNodeWithName = getFirstFiberHasName(fiber);
// Get the first fiber node that has a state node (look up the tree)
fiberWithStateNode = getFirstStateNodeFiber(
firstParentOfNodeWithName,
);
acceptedName = traceItems.includes(
getNameFromFiber(firstParentOfNodeWithName) ?? "",
);
if (!acceptedName) {
fiber = getParentOfFiber(fiber);
}
}
if (fiberWithStateNode && firstParentOfNodeWithName) {
return {
stateNode: fiberWithStateNode,
nameFiber: firstParentOfNodeWithName,
};
} else {
return {
stateNode: null,
nameFiber: null,
};
}
},
[traceItems],
);
const pickFiber = React.useCallback(
(target: HTMLElement) => {
const fiber = getFiberFromElement(target);
setSelectedFiber(selectAppropriateFiber(fiber));
return;
},
[traceItems],
);
React.useEffect(() => {
if (
activeFiber.stateNode !== selectedFiber.stateNode ||
activeFiber.nameFiber !== selectedFiber.nameFiber
) {
setActiveFiber({
stateNode: selectedFiber.stateNode,
nameFiber: selectedFiber.nameFiber,
derived: false,
});
}
}, [selectedFiber]);
const previousValues = React.useRef<{
rect: {
width: number;
height: number;
x: number;
y: number;
};
name: string;
}>({
rect: {
width: 0,
height: 0,
x: 0,
y: 0,
},
name: "",
});
const { rect, name } = React.useMemo(() => {
if (!active) {
return {
rect: {
width: 0,
height: 0,
x: 0,
y: 0,
},
name: "",
};
}
if (activeFiber.stateNode || activeFiber.nameFiber) {
// Get the element from the fiber with a state node
const element = activeFiber.stateNode
? getElementFromFiber(activeFiber.stateNode)
: null;
// Get the name of the fiber node with a name
const fiberName = activeFiber.nameFiber
? getNameFromFiber(activeFiber.nameFiber)
: null;
if (!element) {
return {
rect: previousValues.current.rect,
name: fiberName ?? previousValues.current.name,
};
}
const bounding = element.getBoundingClientRect?.();
if (!bounding) {
return {
rect: previousValues.current.rect,
name: fiberName ?? previousValues.current.name,
};
}
return {
rect: {
width: bounding.width,
height: bounding.height,
x: bounding.left,
y: bounding.top,
},
name: fiberName ?? previousValues.current.name,
};
}
return previousValues.current;
}, [activeFiber, active]);
previousValues.current = {
rect,
name,
};
React.useEffect(() => {
if (active) {
const listener = (e: KeyboardEvent) => {
// if user presses shift, toggle the derived state and set the active fiber to the parent
if (e.key === "Shift" && activeFiber.stateNode) {
e.stopPropagation();
e.preventDefault();
const parent = getParentOfFiber(activeFiber.nameFiber);
const fibers = selectAppropriateFiber(parent);
if (fibers.nameFiber && fibers.stateNode) {
setActiveFiber({
...fibers,
derived: true,
});
return;
}
}
};
document.addEventListener("keydown", listener);
return () => document.removeEventListener("keydown", listener);
}
return () => 0;
}, [activeFiber, active]);
React.useEffect(() => {
if (active) {
let previousTarget: HTMLElement | null = null;
const listener = debounce((e: MouseEvent) => {
if (e?.target) {
if (previousTarget === e.target) {
return;
}
pickFiber(e.target as HTMLElement);
previousTarget = e.target as HTMLElement;
}
}, 50);
document.addEventListener("mousemove", listener);
return () => document.removeEventListener("mousemove", listener);
} else {
return () => 0;
}
}, [active, pickFiber]);
return {
rect,
name,
};
};

View File

@@ -1,22 +0,0 @@
{
"extends": "./tsconfig.json",
"exclude": [
"node_modules",
"dist",
"test",
"../test/**/*",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
"**/*.test.tsx"
],
"compilerOptions": {
"outDir": "dist",
"declarationDir": "dist",
"declaration": true,
"emitDeclarationOnly": true,
"noEmit": false,
"declarationMap": true,
"paths": {}
}
}

View File

@@ -1,13 +0,0 @@
{
"include": ["src", "types"],
"extends": "../../tsconfig.build.json",
"compilerOptions": {
"types": ["node", "jest", "@testing-library/jest-dom"],
"rootDir": "./src",
"baseUrl": ".",
"paths": {
"@test/*": ["test/*"],
"@test": ["test"]
}
}
}

View File

@@ -1,9 +0,0 @@
{
"extends": "./tsconfig.json",
"include": ["test", "src"],
"compilerOptions": {
"rootDir": ".",
"types": ["node", "jest", "@testing-library/jest-dom"],
"typeRoots": ["../../node_modules/@types", "src"]
}
}

View File

@@ -1,30 +0,0 @@
import { defineConfig } from "tsup";
import { NodeResolvePlugin } from "@esbuild-plugins/node-resolve";
export default defineConfig({
entry: ["src/index.ts"],
splitting: false,
sourcemap: true,
clean: false,
platform: "browser",
esbuildOptions: (options) => {
options.define = {
...options.define,
__DEV_CONDITION__: "process.env.NODE_ENV",
};
},
esbuildPlugins: [
NodeResolvePlugin({
extensions: [".js", "ts", "tsx", "jsx"],
onResolved: (resolved) => {
if (resolved.includes("node_modules")) {
return {
external: true,
};
}
return resolved;
},
}),
],
onSuccess: "tsc --project tsconfig.declarations.json",
});