@glennjong/pixel-window 0.1.4 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +36 -1
- package/dist/index.d.ts +36 -1
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,38 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
declare const PixelWindow: ({ style, stroke, frame, background, pixel, children, }: {
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
pixel?: number;
|
|
8
|
+
stroke?: string;
|
|
9
|
+
frame?: string;
|
|
10
|
+
background?: string;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
13
|
+
declare const FreePixelWindow: ({ name, children, pixel, stroke, frame, background, position: initialPosition, style, minWidth, minHeight, onChange, }: {
|
|
14
|
+
name?: string;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
pixel?: number;
|
|
17
|
+
stroke?: string;
|
|
18
|
+
frame?: string;
|
|
19
|
+
background?: string;
|
|
20
|
+
position?: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
};
|
|
24
|
+
style?: React.CSSProperties;
|
|
25
|
+
minWidth?: number;
|
|
26
|
+
minHeight?: number;
|
|
27
|
+
onChange?: (position: {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
}, size: {
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
}) => void;
|
|
34
|
+
}) => react.ReactPortal;
|
|
35
|
+
|
|
1
36
|
declare function getFrame({ size, stroke, frame, background }: {
|
|
2
37
|
size: number;
|
|
3
38
|
stroke: string;
|
|
@@ -8,4 +43,4 @@ declare const frame: string;
|
|
|
8
43
|
declare const checkbox: string;
|
|
9
44
|
declare const checkboxLight: string;
|
|
10
45
|
|
|
11
|
-
export { checkbox, checkboxLight, frame, getFrame };
|
|
46
|
+
export { FreePixelWindow, PixelWindow, checkbox, checkboxLight, frame, getFrame };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,38 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
declare const PixelWindow: ({ style, stroke, frame, background, pixel, children, }: {
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
pixel?: number;
|
|
8
|
+
stroke?: string;
|
|
9
|
+
frame?: string;
|
|
10
|
+
background?: string;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
13
|
+
declare const FreePixelWindow: ({ name, children, pixel, stroke, frame, background, position: initialPosition, style, minWidth, minHeight, onChange, }: {
|
|
14
|
+
name?: string;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
pixel?: number;
|
|
17
|
+
stroke?: string;
|
|
18
|
+
frame?: string;
|
|
19
|
+
background?: string;
|
|
20
|
+
position?: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
};
|
|
24
|
+
style?: React.CSSProperties;
|
|
25
|
+
minWidth?: number;
|
|
26
|
+
minHeight?: number;
|
|
27
|
+
onChange?: (position: {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
}, size: {
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
}) => void;
|
|
34
|
+
}) => react.ReactPortal;
|
|
35
|
+
|
|
1
36
|
declare function getFrame({ size, stroke, frame, background }: {
|
|
2
37
|
size: number;
|
|
3
38
|
stroke: string;
|
|
@@ -8,4 +43,4 @@ declare const frame: string;
|
|
|
8
43
|
declare const checkbox: string;
|
|
9
44
|
declare const checkboxLight: string;
|
|
10
45
|
|
|
11
|
-
export { checkbox, checkboxLight, frame, getFrame };
|
|
46
|
+
export { FreePixelWindow, PixelWindow, checkbox, checkboxLight, frame, getFrame };
|
package/dist/index.js
CHANGED
|
@@ -56,7 +56,7 @@ var checkboxLight = getCheckbox({
|
|
|
56
56
|
color: "#000"
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
// src/
|
|
59
|
+
// src/PixelWindow.tsx
|
|
60
60
|
var import_react = require("react");
|
|
61
61
|
var import_react_dom = require("react-dom");
|
|
62
62
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -105,7 +105,8 @@ var FreePixelWindow = ({
|
|
|
105
105
|
position: initialPosition = { x: 100, y: 100 },
|
|
106
106
|
style,
|
|
107
107
|
minWidth = 120,
|
|
108
|
-
minHeight = 100
|
|
108
|
+
minHeight = 100,
|
|
109
|
+
onChange
|
|
109
110
|
}) => {
|
|
110
111
|
const [position, setPosition] = (0, import_react.useState)(() => {
|
|
111
112
|
if (name) {
|
|
@@ -122,6 +123,11 @@ var FreePixelWindow = ({
|
|
|
122
123
|
const [isResizing, setIsResizing] = (0, import_react.useState)(false);
|
|
123
124
|
const [dragStart, setDragStart] = (0, import_react.useState)({ x: 0, y: 0 });
|
|
124
125
|
const [resizeStart, setResizeStart] = (0, import_react.useState)({ width: 0, height: 0, mouseX: 0, mouseY: 0 });
|
|
126
|
+
(0, import_react.useEffect)(() => {
|
|
127
|
+
if (onChange) {
|
|
128
|
+
onChange(position, size);
|
|
129
|
+
}
|
|
130
|
+
}, [position, size, onChange]);
|
|
125
131
|
(0, import_react.useEffect)(() => {
|
|
126
132
|
if (name) {
|
|
127
133
|
localStorage.setItem(`${name}-position`, JSON.stringify(position));
|
|
@@ -213,6 +219,8 @@ var FreePixelWindow = ({
|
|
|
213
219
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
|
|
214
220
|
padding: `${pixel}px`,
|
|
215
221
|
paddingTop: 0,
|
|
222
|
+
height: `calc(100% - ${pixel}px)`,
|
|
223
|
+
boxSizing: "border-box",
|
|
216
224
|
...style
|
|
217
225
|
}, children }),
|
|
218
226
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/frame.ts","../src/index.tsx"],"sourcesContent":["export * from './index';\nexport * from './frame';\n","export function getFrame({ size, stroke, frame, background }: { size: number; stroke: string; frame: string; background: string }): string {\n const height = size; // Assuming square frames\n const svg = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{{size}}\" height=\"{{height}}\" viewBox=\"0 0 12 12\"><path fill=\"{{stroke}}\" d=\"M2 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9zM1 1h1v1H1z\"/><path fill=\"{{frame}}\" d=\"M2 1h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{stroke}}\" d=\"M10 1h1v1h-1zM0 2h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 2h1v1H1zm1 0h1v1H2z\"/><path fill=\"{{stroke}}\" d=\"M3 2h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{frame}}\" d=\"M9 2h1v1H9zm1 0h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 2h1v1h-1zM0 3h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 3h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 3h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 3h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 3h1v1h-1zM0 4h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 4h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 4h1v1H2zm1 0h1v1H3z\"/><path fill=\"{{background}}\" d=\"M4 4h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7z\"/><path fill=\"{{stroke}}\" d=\"M8 4h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 4h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 4h1v1h-1zM0 5h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 5h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 5h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 5h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 5h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 5h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 5h1v1h-1zM0 6h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 6h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 6h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 6h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 6h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 6h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 6h1v1h-1zM0 7h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 7h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 7h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 7h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 7h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 7h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 7h1v1h-1zM0 8h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 8h1v1H1zm1 0h1v1H2z\"/><path fill=\"{{stroke}}\" d=\"M3 8h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{frame}}\" d=\"M9 8h1v1H9zm1 0h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 8h1v1h-1zM0 9h1v1H0zm1 0h1v1H1z\"/><path fill=\"{{frame}}\" d=\"M2 9h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{stroke}}\" d=\"M10 9h1v1h-1zm-9 1h1v1H1zm1 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9zm1 0h1v1h-1zm-8 1h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/></svg>'\n .replace(/\\{\\{size\\}\\}/g, size.toString())\n .replace(/\\{\\{height\\}\\}/g, height.toString())\n .replace(/\\{\\{stroke\\}\\}/g, stroke)\n .replace(/\\{\\{frame\\}\\}/g, frame)\n .replace(/\\{\\{background\\}\\}/g, background);\n\n // Encode SVG to Base64 safely\n const encodedSvg = encodeURIComponent(svg)\n .replace(/%([0-9A-F]{2})/g, (_, p1) => String.fromCharCode(parseInt(p1, 16)));\n\n return `data:image/svg+xml;base64,${btoa(encodedSvg)}`;\n}\n\nfunction getCheckbox({ size, color }: { size: number; color: string }) {\n const svg = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{{width}}\" height=\"{{height}}\" viewBox=\"0 0 12 6\"><rect width=\"1\" height=\"1\" x=\"1\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"4\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"7\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"8\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"9\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"10\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"1\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"4\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"7\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"8\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"9\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"10\" y=\"5\" fill=\"{{color}}\"></rect></svg>'\n .replace(/\\{\\{width\\}\\}/g, (size*2).toString())\n .replace(/\\{\\{height\\}\\}/g, size.toString())\n .replace(/\\{\\{color\\}\\}/g, color)\n \n const encodedSvg = encodeURIComponent(svg)\n .replace(/%([0-9A-F]{2})/g, (_, p1) => String.fromCharCode(parseInt(p1, 16)))\n .replace(/#/g, '%23');\n\n return `data:image/svg+xml;base64,${btoa(encodedSvg)}`;\n\n}\n\nexport const frame = getFrame({\n size: 160,\n stroke: '#000',\n frame: '#333',\n background: '#DDD',\n});\n\nexport const checkbox = getCheckbox({\n size: 12,\n color: '#000',\n});\nexport const checkboxLight = getCheckbox({\n size: 12,\n color: '#000',\n});\n","import { getFrame } from './frame';\nimport { useCallback, useEffect, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport const PixelWindow = ({\n style = {},\n stroke = '#000',\n frame = '#333',\n background = '#DDD',\n pixel = 160,\n children,\n}: {\n style?: React.CSSProperties,\n pixel?: number,\n stroke?: string\n frame?: string\n background?: string\n children: ReactNode;\n}) => {\n\n const pixelFrame = getFrame({\n size: pixel,\n stroke,\n frame,\n background,\n });\n\n\n return (\n <div\n className=\"window\"\n style={{\n width: '100%',\n height: '100%',\n borderImage: `url(${pixelFrame})`,\n borderImageSlice: '49% 49% fill',\n borderImageWidth: `${pixel}px`,\n }}\n >\n <div style={{ padding: `${pixel}px`}}>\n <div\n style={{ boxSizing: 'border-box', ...style }}\n >\n {children}\n </div>\n </div>\n </div>\n );\n};\n\nexport const FreePixelWindow = ({\n name,\n children,\n pixel = 16,\n stroke = '#000',\n frame = '#333',\n background = '#DDD',\n position: initialPosition = { x: 100, y: 100 },\n style,\n minWidth = 120,\n minHeight = 100,\n}: {\n name?: string;\n children: ReactNode;\n pixel?: number;\n stroke?: string;\n frame?: string;\n background?: string;\n position?: { x: number; y: number };\n style?: React.CSSProperties;\n minWidth?: number;\n minHeight?: number;\n}) => {\n\n const [position, setPosition] = useState(() => {\n if (name) {\n const savedPosition = localStorage.getItem(`${name}-position`);\n return savedPosition ? JSON.parse(savedPosition) : initialPosition;\n }\n return initialPosition;\n });\n\n const [size, setSize] = useState(() => {\n const savedSize = localStorage.getItem(`${name}-size`);\n return savedSize ? JSON.parse(savedSize) : { width: 300, height: 200 };\n });\n\n const [isDragging, setIsDragging] = useState(false);\n const [isResizing, setIsResizing] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [resizeStart, setResizeStart] = useState({ width: 0, height: 0, mouseX: 0, mouseY: 0 });\n\n useEffect(() => {\n if (name) {\n localStorage.setItem(`${name}-position`, JSON.stringify(position));\n localStorage.setItem(`${name}-size`, JSON.stringify(size));\n\n }\n }, [name, position, size]);\n\n const handleMouseMove = useCallback((e: MouseEvent) => {\n if (isDragging) {\n setPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n });\n } else if (isResizing) {\n const deltaX = e.clientX - resizeStart.mouseX;\n const deltaY = e.clientY - resizeStart.mouseY;\n\n setSize({\n width: Math.max(resizeStart.width + deltaX, minWidth),\n height: Math.max(resizeStart.height + deltaY, minHeight),\n });\n }\n }, [isDragging, isResizing, dragStart, resizeStart, minWidth, minHeight]);\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n setIsResizing(false);\n }, []);\n\n useEffect(() => {\n if (isDragging || isResizing) {\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n } else {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n }\n\n return () => {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n };\n }, [isDragging, isResizing, handleMouseMove, handleMouseUp]);\n\n const handleMouseDown = (e: React.MouseEvent) => {\n setIsDragging(true);\n setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });\n };\n\n const handleResizeStart = (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsResizing(true);\n setResizeStart({\n width: size.width,\n height: size.height,\n mouseX: e.clientX,\n mouseY: e.clientY,\n });\n };\n\n const pixelFrame = getFrame({\n size: pixel,\n stroke,\n frame,\n background,\n });\n\n return createPortal(\n <div\n style={{\n position: 'absolute',\n overflow: 'hidden',\n resize: 'none',\n top: position.y,\n left: position.x,\n width: size.width,\n height: size.height,\n borderImage: `url(${pixelFrame})`,\n borderImageSlice: '49% 49% fill',\n borderImageWidth: `${pixel}px`,\n }}\n onMouseUp={handleMouseUp}\n >\n <div \n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n style={{\n height: `${pixel}px`,\n cursor: \"grab\",\n userSelect: \"none\"\n }}\n ></div>\n <div style={{\n padding: `${pixel}px`,\n paddingTop: 0,\n ...style\n }}>{children}</div>\n <div\n onMouseDown={handleResizeStart}\n style={{\n position: 'absolute',\n width: `${pixel}px`,\n height: `${pixel}px`,\n cursor: 'se-resize',\n bottom: 0,\n right: 0,\n }}\n ></div>\n </div>,\n document.body\n );\n};\n"],"mappings":"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","names":["frame","frame"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/frame.ts","../src/PixelWindow.tsx"],"sourcesContent":["export * from './PixelWindow';\nexport * from './frame';","export function getFrame({ size, stroke, frame, background }: { size: number; stroke: string; frame: string; background: string }): string {\n const height = size; // Assuming square frames\n const svg = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{{size}}\" height=\"{{height}}\" viewBox=\"0 0 12 12\"><path fill=\"{{stroke}}\" d=\"M2 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9zM1 1h1v1H1z\"/><path fill=\"{{frame}}\" d=\"M2 1h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{stroke}}\" d=\"M10 1h1v1h-1zM0 2h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 2h1v1H1zm1 0h1v1H2z\"/><path fill=\"{{stroke}}\" d=\"M3 2h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{frame}}\" d=\"M9 2h1v1H9zm1 0h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 2h1v1h-1zM0 3h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 3h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 3h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 3h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 3h1v1h-1zM0 4h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 4h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 4h1v1H2zm1 0h1v1H3z\"/><path fill=\"{{background}}\" d=\"M4 4h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7z\"/><path fill=\"{{stroke}}\" d=\"M8 4h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 4h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 4h1v1h-1zM0 5h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 5h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 5h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 5h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 5h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 5h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 5h1v1h-1zM0 6h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 6h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 6h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 6h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 6h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 6h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 6h1v1h-1zM0 7h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 7h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 7h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 7h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 7h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 7h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 7h1v1h-1zM0 8h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 8h1v1H1zm1 0h1v1H2z\"/><path fill=\"{{stroke}}\" d=\"M3 8h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{frame}}\" d=\"M9 8h1v1H9zm1 0h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 8h1v1h-1zM0 9h1v1H0zm1 0h1v1H1z\"/><path fill=\"{{frame}}\" d=\"M2 9h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{stroke}}\" d=\"M10 9h1v1h-1zm-9 1h1v1H1zm1 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9zm1 0h1v1h-1zm-8 1h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/></svg>'\n .replace(/\\{\\{size\\}\\}/g, size.toString())\n .replace(/\\{\\{height\\}\\}/g, height.toString())\n .replace(/\\{\\{stroke\\}\\}/g, stroke)\n .replace(/\\{\\{frame\\}\\}/g, frame)\n .replace(/\\{\\{background\\}\\}/g, background);\n\n // Encode SVG to Base64 safely\n const encodedSvg = encodeURIComponent(svg)\n .replace(/%([0-9A-F]{2})/g, (_, p1) => String.fromCharCode(parseInt(p1, 16)));\n\n return `data:image/svg+xml;base64,${btoa(encodedSvg)}`;\n}\n\nfunction getCheckbox({ size, color }: { size: number; color: string }) {\n const svg = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{{width}}\" height=\"{{height}}\" viewBox=\"0 0 12 6\"><rect width=\"1\" height=\"1\" x=\"1\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"4\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"7\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"8\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"9\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"10\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"1\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"4\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"7\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"8\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"9\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"10\" y=\"5\" fill=\"{{color}}\"></rect></svg>'\n .replace(/\\{\\{width\\}\\}/g, (size*2).toString())\n .replace(/\\{\\{height\\}\\}/g, size.toString())\n .replace(/\\{\\{color\\}\\}/g, color)\n \n const encodedSvg = encodeURIComponent(svg)\n .replace(/%([0-9A-F]{2})/g, (_, p1) => String.fromCharCode(parseInt(p1, 16)))\n .replace(/#/g, '%23');\n\n return `data:image/svg+xml;base64,${btoa(encodedSvg)}`;\n\n}\n\nexport const frame = getFrame({\n size: 160,\n stroke: '#000',\n frame: '#333',\n background: '#DDD',\n});\n\nexport const checkbox = getCheckbox({\n size: 12,\n color: '#000',\n});\nexport const checkboxLight = getCheckbox({\n size: 12,\n color: '#000',\n});\n","import { getFrame } from './frame';\nimport { useCallback, useEffect, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport const PixelWindow = ({\n style = {},\n stroke = '#000',\n frame = '#333',\n background = '#DDD',\n pixel = 160,\n children,\n}: {\n style?: React.CSSProperties,\n pixel?: number,\n stroke?: string\n frame?: string\n background?: string\n children: ReactNode;\n}) => {\n\n const pixelFrame = getFrame({\n size: pixel,\n stroke,\n frame,\n background,\n });\n\n return (\n <div\n className=\"window\"\n style={{\n width: '100%',\n height: '100%',\n borderImage: `url(${pixelFrame})`,\n borderImageSlice: '49% 49% fill',\n borderImageWidth: `${pixel}px`,\n }}\n >\n <div style={{ padding: `${pixel}px`}}>\n <div\n style={{ boxSizing: 'border-box', ...style }}\n >\n {children}\n </div>\n </div>\n </div>\n );\n};\n\nexport const FreePixelWindow = ({\n name,\n children,\n pixel = 16,\n stroke = '#000',\n frame = '#333',\n background = '#DDD',\n position: initialPosition = { x: 100, y: 100 },\n style,\n minWidth = 120,\n minHeight = 100,\n onChange,\n}: {\n name?: string;\n children: ReactNode;\n pixel?: number;\n stroke?: string;\n frame?: string;\n background?: string;\n position?: { x: number; y: number };\n style?: React.CSSProperties;\n minWidth?: number;\n minHeight?: number;\n onChange?: (position: { x: number; y: number }, size: { width: number; height: number }) => void;\n}) => {\n\n const [position, setPosition] = useState(() => {\n if (name) {\n const savedPosition = localStorage.getItem(`${name}-position`);\n return savedPosition ? JSON.parse(savedPosition) : initialPosition;\n }\n return initialPosition;\n });\n\n const [size, setSize] = useState(() => {\n const savedSize = localStorage.getItem(`${name}-size`);\n return savedSize ? JSON.parse(savedSize) : { width: 300, height: 200 };\n });\n\n const [isDragging, setIsDragging] = useState(false);\n const [isResizing, setIsResizing] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [resizeStart, setResizeStart] = useState({ width: 0, height: 0, mouseX: 0, mouseY: 0 });\n\n useEffect(() => {\n if (onChange) {\n onChange(position, size);\n }\n }, [position, size, onChange]);\n\n useEffect(() => {\n if (name) {\n localStorage.setItem(`${name}-position`, JSON.stringify(position));\n localStorage.setItem(`${name}-size`, JSON.stringify(size));\n }\n }, [name, position, size]);\n\n const handleMouseMove = useCallback((e: MouseEvent) => {\n if (isDragging) {\n setPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n });\n } else if (isResizing) {\n const deltaX = e.clientX - resizeStart.mouseX;\n const deltaY = e.clientY - resizeStart.mouseY;\n\n setSize({\n width: Math.max(resizeStart.width + deltaX, minWidth),\n height: Math.max(resizeStart.height + deltaY, minHeight),\n });\n }\n }, [isDragging, isResizing, dragStart, resizeStart, minWidth, minHeight]);\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n setIsResizing(false);\n }, []);\n\n useEffect(() => {\n if (isDragging || isResizing) {\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n } else {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n }\n\n return () => {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n };\n }, [isDragging, isResizing, handleMouseMove, handleMouseUp]);\n\n const handleMouseDown = (e: React.MouseEvent) => {\n setIsDragging(true);\n setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });\n };\n\n const handleResizeStart = (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsResizing(true);\n setResizeStart({\n width: size.width,\n height: size.height,\n mouseX: e.clientX,\n mouseY: e.clientY,\n });\n };\n\n const pixelFrame = getFrame({\n size: pixel,\n stroke,\n frame,\n background,\n });\n\n return createPortal(\n <div\n style={{\n position: 'absolute',\n overflow: 'hidden',\n resize: 'none',\n top: position.y,\n left: position.x,\n width: size.width,\n height: size.height,\n borderImage: `url(${pixelFrame})`,\n borderImageSlice: '49% 49% fill',\n borderImageWidth: `${pixel}px`,\n }}\n onMouseUp={handleMouseUp}\n >\n <div \n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n style={{\n height: `${pixel}px`,\n cursor: \"grab\",\n userSelect: \"none\"\n }}\n ></div>\n <div style={{\n padding: `${pixel}px`,\n paddingTop: 0,\n height: `calc(100% - ${pixel}px)`,\n boxSizing: 'border-box',\n ...style\n }}>{children}</div>\n <div\n onMouseDown={handleResizeStart}\n style={{\n position: 'absolute',\n width: `${pixel}px`,\n height: `${pixel}px`,\n cursor: 'se-resize',\n bottom: 0,\n right: 0,\n }}\n ></div>\n </div>,\n document.body\n );\n};\n"],"mappings":"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","names":["frame","frame"]}
|
package/dist/index.mjs
CHANGED
|
@@ -25,7 +25,7 @@ var checkboxLight = getCheckbox({
|
|
|
25
25
|
color: "#000"
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
// src/
|
|
28
|
+
// src/PixelWindow.tsx
|
|
29
29
|
import { useCallback, useEffect, useState } from "react";
|
|
30
30
|
import { createPortal } from "react-dom";
|
|
31
31
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -74,7 +74,8 @@ var FreePixelWindow = ({
|
|
|
74
74
|
position: initialPosition = { x: 100, y: 100 },
|
|
75
75
|
style,
|
|
76
76
|
minWidth = 120,
|
|
77
|
-
minHeight = 100
|
|
77
|
+
minHeight = 100,
|
|
78
|
+
onChange
|
|
78
79
|
}) => {
|
|
79
80
|
const [position, setPosition] = useState(() => {
|
|
80
81
|
if (name) {
|
|
@@ -91,6 +92,11 @@ var FreePixelWindow = ({
|
|
|
91
92
|
const [isResizing, setIsResizing] = useState(false);
|
|
92
93
|
const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
|
|
93
94
|
const [resizeStart, setResizeStart] = useState({ width: 0, height: 0, mouseX: 0, mouseY: 0 });
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
if (onChange) {
|
|
97
|
+
onChange(position, size);
|
|
98
|
+
}
|
|
99
|
+
}, [position, size, onChange]);
|
|
94
100
|
useEffect(() => {
|
|
95
101
|
if (name) {
|
|
96
102
|
localStorage.setItem(`${name}-position`, JSON.stringify(position));
|
|
@@ -182,6 +188,8 @@ var FreePixelWindow = ({
|
|
|
182
188
|
/* @__PURE__ */ jsx("div", { style: {
|
|
183
189
|
padding: `${pixel}px`,
|
|
184
190
|
paddingTop: 0,
|
|
191
|
+
height: `calc(100% - ${pixel}px)`,
|
|
192
|
+
boxSizing: "border-box",
|
|
185
193
|
...style
|
|
186
194
|
}, children }),
|
|
187
195
|
/* @__PURE__ */ jsx(
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/frame.ts","../src/index.tsx"],"sourcesContent":["export function getFrame({ size, stroke, frame, background }: { size: number; stroke: string; frame: string; background: string }): string {\n const height = size; // Assuming square frames\n const svg = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{{size}}\" height=\"{{height}}\" viewBox=\"0 0 12 12\"><path fill=\"{{stroke}}\" d=\"M2 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9zM1 1h1v1H1z\"/><path fill=\"{{frame}}\" d=\"M2 1h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{stroke}}\" d=\"M10 1h1v1h-1zM0 2h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 2h1v1H1zm1 0h1v1H2z\"/><path fill=\"{{stroke}}\" d=\"M3 2h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{frame}}\" d=\"M9 2h1v1H9zm1 0h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 2h1v1h-1zM0 3h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 3h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 3h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 3h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 3h1v1h-1zM0 4h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 4h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 4h1v1H2zm1 0h1v1H3z\"/><path fill=\"{{background}}\" d=\"M4 4h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7z\"/><path fill=\"{{stroke}}\" d=\"M8 4h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 4h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 4h1v1h-1zM0 5h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 5h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 5h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 5h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 5h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 5h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 5h1v1h-1zM0 6h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 6h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 6h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 6h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 6h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 6h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 6h1v1h-1zM0 7h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 7h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 7h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 7h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 7h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 7h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 7h1v1h-1zM0 8h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 8h1v1H1zm1 0h1v1H2z\"/><path fill=\"{{stroke}}\" d=\"M3 8h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{frame}}\" d=\"M9 8h1v1H9zm1 0h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 8h1v1h-1zM0 9h1v1H0zm1 0h1v1H1z\"/><path fill=\"{{frame}}\" d=\"M2 9h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{stroke}}\" d=\"M10 9h1v1h-1zm-9 1h1v1H1zm1 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9zm1 0h1v1h-1zm-8 1h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/></svg>'\n .replace(/\\{\\{size\\}\\}/g, size.toString())\n .replace(/\\{\\{height\\}\\}/g, height.toString())\n .replace(/\\{\\{stroke\\}\\}/g, stroke)\n .replace(/\\{\\{frame\\}\\}/g, frame)\n .replace(/\\{\\{background\\}\\}/g, background);\n\n // Encode SVG to Base64 safely\n const encodedSvg = encodeURIComponent(svg)\n .replace(/%([0-9A-F]{2})/g, (_, p1) => String.fromCharCode(parseInt(p1, 16)));\n\n return `data:image/svg+xml;base64,${btoa(encodedSvg)}`;\n}\n\nfunction getCheckbox({ size, color }: { size: number; color: string }) {\n const svg = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{{width}}\" height=\"{{height}}\" viewBox=\"0 0 12 6\"><rect width=\"1\" height=\"1\" x=\"1\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"4\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"7\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"8\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"9\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"10\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"1\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"4\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"7\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"8\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"9\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"10\" y=\"5\" fill=\"{{color}}\"></rect></svg>'\n .replace(/\\{\\{width\\}\\}/g, (size*2).toString())\n .replace(/\\{\\{height\\}\\}/g, size.toString())\n .replace(/\\{\\{color\\}\\}/g, color)\n \n const encodedSvg = encodeURIComponent(svg)\n .replace(/%([0-9A-F]{2})/g, (_, p1) => String.fromCharCode(parseInt(p1, 16)))\n .replace(/#/g, '%23');\n\n return `data:image/svg+xml;base64,${btoa(encodedSvg)}`;\n\n}\n\nexport const frame = getFrame({\n size: 160,\n stroke: '#000',\n frame: '#333',\n background: '#DDD',\n});\n\nexport const checkbox = getCheckbox({\n size: 12,\n color: '#000',\n});\nexport const checkboxLight = getCheckbox({\n size: 12,\n color: '#000',\n});\n","import { getFrame } from './frame';\nimport { useCallback, useEffect, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport const PixelWindow = ({\n style = {},\n stroke = '#000',\n frame = '#333',\n background = '#DDD',\n pixel = 160,\n children,\n}: {\n style?: React.CSSProperties,\n pixel?: number,\n stroke?: string\n frame?: string\n background?: string\n children: ReactNode;\n}) => {\n\n const pixelFrame = getFrame({\n size: pixel,\n stroke,\n frame,\n background,\n });\n\n\n return (\n <div\n className=\"window\"\n style={{\n width: '100%',\n height: '100%',\n borderImage: `url(${pixelFrame})`,\n borderImageSlice: '49% 49% fill',\n borderImageWidth: `${pixel}px`,\n }}\n >\n <div style={{ padding: `${pixel}px`}}>\n <div\n style={{ boxSizing: 'border-box', ...style }}\n >\n {children}\n </div>\n </div>\n </div>\n );\n};\n\nexport const FreePixelWindow = ({\n name,\n children,\n pixel = 16,\n stroke = '#000',\n frame = '#333',\n background = '#DDD',\n position: initialPosition = { x: 100, y: 100 },\n style,\n minWidth = 120,\n minHeight = 100,\n}: {\n name?: string;\n children: ReactNode;\n pixel?: number;\n stroke?: string;\n frame?: string;\n background?: string;\n position?: { x: number; y: number };\n style?: React.CSSProperties;\n minWidth?: number;\n minHeight?: number;\n}) => {\n\n const [position, setPosition] = useState(() => {\n if (name) {\n const savedPosition = localStorage.getItem(`${name}-position`);\n return savedPosition ? JSON.parse(savedPosition) : initialPosition;\n }\n return initialPosition;\n });\n\n const [size, setSize] = useState(() => {\n const savedSize = localStorage.getItem(`${name}-size`);\n return savedSize ? JSON.parse(savedSize) : { width: 300, height: 200 };\n });\n\n const [isDragging, setIsDragging] = useState(false);\n const [isResizing, setIsResizing] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [resizeStart, setResizeStart] = useState({ width: 0, height: 0, mouseX: 0, mouseY: 0 });\n\n useEffect(() => {\n if (name) {\n localStorage.setItem(`${name}-position`, JSON.stringify(position));\n localStorage.setItem(`${name}-size`, JSON.stringify(size));\n\n }\n }, [name, position, size]);\n\n const handleMouseMove = useCallback((e: MouseEvent) => {\n if (isDragging) {\n setPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n });\n } else if (isResizing) {\n const deltaX = e.clientX - resizeStart.mouseX;\n const deltaY = e.clientY - resizeStart.mouseY;\n\n setSize({\n width: Math.max(resizeStart.width + deltaX, minWidth),\n height: Math.max(resizeStart.height + deltaY, minHeight),\n });\n }\n }, [isDragging, isResizing, dragStart, resizeStart, minWidth, minHeight]);\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n setIsResizing(false);\n }, []);\n\n useEffect(() => {\n if (isDragging || isResizing) {\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n } else {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n }\n\n return () => {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n };\n }, [isDragging, isResizing, handleMouseMove, handleMouseUp]);\n\n const handleMouseDown = (e: React.MouseEvent) => {\n setIsDragging(true);\n setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });\n };\n\n const handleResizeStart = (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsResizing(true);\n setResizeStart({\n width: size.width,\n height: size.height,\n mouseX: e.clientX,\n mouseY: e.clientY,\n });\n };\n\n const pixelFrame = getFrame({\n size: pixel,\n stroke,\n frame,\n background,\n });\n\n return createPortal(\n <div\n style={{\n position: 'absolute',\n overflow: 'hidden',\n resize: 'none',\n top: position.y,\n left: position.x,\n width: size.width,\n height: size.height,\n borderImage: `url(${pixelFrame})`,\n borderImageSlice: '49% 49% fill',\n borderImageWidth: `${pixel}px`,\n }}\n onMouseUp={handleMouseUp}\n >\n <div \n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n style={{\n height: `${pixel}px`,\n cursor: \"grab\",\n userSelect: \"none\"\n }}\n ></div>\n <div style={{\n padding: `${pixel}px`,\n paddingTop: 0,\n ...style\n }}>{children}</div>\n <div\n onMouseDown={handleResizeStart}\n style={{\n position: 'absolute',\n width: `${pixel}px`,\n height: `${pixel}px`,\n cursor: 'se-resize',\n bottom: 0,\n right: 0,\n }}\n ></div>\n </div>,\n document.body\n );\n};\n"],"mappings":";AAAO,SAAS,SAAS,EAAE,MAAM,QAAQ,OAAAA,QAAO,WAAW,GAAgF;AACzI,QAAM,SAAS;AACf,QAAM,MAAM,0vFACT,QAAQ,iBAAiB,KAAK,SAAS,CAAC,EACxC,QAAQ,mBAAmB,OAAO,SAAS,CAAC,EAC5C,QAAQ,mBAAmB,MAAM,EACjC,QAAQ,kBAAkBA,MAAK,EAC/B,QAAQ,uBAAuB,UAAU;AAG5C,QAAM,aAAa,mBAAmB,GAAG,EACtC,QAAQ,mBAAmB,CAAC,GAAG,OAAO,OAAO,aAAa,SAAS,IAAI,EAAE,CAAC,CAAC;AAE9E,SAAO,6BAA6B,KAAK,UAAU,CAAC;AACtD;AAEA,SAAS,YAAY,EAAE,MAAM,MAAM,GAAoC;AACrE,QAAM,MAAM,40EACT,QAAQ,mBAAmB,OAAK,GAAG,SAAS,CAAC,EAC7C,QAAQ,mBAAmB,KAAK,SAAS,CAAC,EAC1C,QAAQ,kBAAkB,KAAK;AAElC,QAAM,aAAa,mBAAmB,GAAG,EACtC,QAAQ,mBAAmB,CAAC,GAAG,OAAO,OAAO,aAAa,SAAS,IAAI,EAAE,CAAC,CAAC,EAC3E,QAAQ,MAAM,KAAK;AAEtB,SAAO,6BAA6B,KAAK,UAAU,CAAC;AAEtD;AAEO,IAAM,QAAQ,SAAS;AAAA,EAC5B,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,YAAY;AACd,CAAC;AAEM,IAAM,WAAW,YAAY;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AACT,CAAC;AACM,IAAM,gBAAgB,YAAY;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AACT,CAAC;;;AC3CD,SAAS,aAAa,WAAW,gBAAgC;AACjE,SAAS,oBAAoB;AAsCrB,cAyHJ,YAzHI;AApCD,IAAM,cAAc,CAAC;AAAA,EAC1B,QAAQ,CAAC;AAAA,EACT,SAAS;AAAA,EACT,OAAAC,SAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AAAA,EACR;AACF,MAOM;AAEJ,QAAM,aAAa,SAAS;AAAA,IAC1B,MAAM;AAAA,IACN;AAAA,IACA,OAAAA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa,OAAO,UAAU;AAAA,QAC9B,kBAAkB;AAAA,QAClB,kBAAkB,GAAG,KAAK;AAAA,MAC5B;AAAA,MAEA,8BAAC,SAAI,OAAO,EAAE,SAAS,GAAG,KAAK,KAAI,GACjC;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,EAAE,WAAW,cAAc,GAAG,MAAM;AAAA,UAE1C;AAAA;AAAA,MACH,GACF;AAAA;AAAA,EACF;AAEJ;AAEO,IAAM,kBAAkB,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAAA,SAAQ;AAAA,EACR,aAAa;AAAA,EACb,UAAU,kBAAkB,EAAE,GAAG,KAAK,GAAG,IAAI;AAAA,EAC7C;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AACd,MAWM;AAEJ,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,MAAM;AAC7C,QAAI,MAAM;AACR,YAAM,gBAAgB,aAAa,QAAQ,GAAG,IAAI,WAAW;AAC7D,aAAO,gBAAgB,KAAK,MAAM,aAAa,IAAI;AAAA,IACrD;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,MAAM;AACrC,UAAM,YAAY,aAAa,QAAQ,GAAG,IAAI,OAAO;AACrD,WAAO,YAAY,KAAK,MAAM,SAAS,IAAI,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,EACvE,CAAC;AAED,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACzD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC;AAE5F,YAAU,MAAM;AACd,QAAI,MAAM;AACR,mBAAa,QAAQ,GAAG,IAAI,aAAa,KAAK,UAAU,QAAQ,CAAC;AACjE,mBAAa,QAAQ,GAAG,IAAI,SAAS,KAAK,UAAU,IAAI,CAAC;AAAA,IAE3D;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,IAAI,CAAC;AAEzB,QAAM,kBAAkB,YAAY,CAAC,MAAkB;AACrD,QAAI,YAAY;AACd,kBAAY;AAAA,QACV,GAAG,EAAE,UAAU,UAAU;AAAA,QACzB,GAAG,EAAE,UAAU,UAAU;AAAA,MAC3B,CAAC;AAAA,IACH,WAAW,YAAY;AACrB,YAAM,SAAS,EAAE,UAAU,YAAY;AACvC,YAAM,SAAS,EAAE,UAAU,YAAY;AAEvC,cAAQ;AAAA,QACN,OAAO,KAAK,IAAI,YAAY,QAAQ,QAAQ,QAAQ;AAAA,QACpD,QAAQ,KAAK,IAAI,YAAY,SAAS,QAAQ,SAAS;AAAA,MACzD,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,YAAY,YAAY,WAAW,aAAa,UAAU,SAAS,CAAC;AAExE,QAAM,gBAAgB,YAAY,MAAM;AACtC,kBAAc,KAAK;AACnB,kBAAc,KAAK;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,cAAc,YAAY;AAC5B,aAAO,iBAAiB,aAAa,eAAe;AACpD,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,OAAO;AACL,aAAO,oBAAoB,aAAa,eAAe;AACvD,aAAO,oBAAoB,WAAW,aAAa;AAAA,IACrD;AAEA,WAAO,MAAM;AACX,aAAO,oBAAoB,aAAa,eAAe;AACvD,aAAO,oBAAoB,WAAW,aAAa;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,YAAY,YAAY,iBAAiB,aAAa,CAAC;AAE3D,QAAM,kBAAkB,CAAC,MAAwB;AAC/C,kBAAc,IAAI;AAClB,iBAAa,EAAE,GAAG,EAAE,UAAU,SAAS,GAAG,GAAG,EAAE,UAAU,SAAS,EAAE,CAAC;AAAA,EACvE;AAEA,QAAM,oBAAoB,CAAC,MAAwB;AACjD,MAAE,gBAAgB;AAClB,kBAAc,IAAI;AAClB,mBAAe;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,QAAQ,EAAE;AAAA,MACV,QAAQ,EAAE;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,SAAS;AAAA,IAC1B,MAAM;AAAA,IACN;AAAA,IACA,OAAAA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,KAAK,SAAS;AAAA,UACd,MAAM,SAAS;AAAA,UACf,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,UACb,aAAa,OAAO,UAAU;AAAA,UAC9B,kBAAkB;AAAA,UAClB,kBAAkB,GAAG,KAAK;AAAA,QAC5B;AAAA,QACA,WAAW;AAAA,QAEX;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,aAAa;AAAA,cACb,WAAW;AAAA,cACX,OAAO;AAAA,gBACL,QAAQ,GAAG,KAAK;AAAA,gBAChB,QAAQ;AAAA,gBACR,YAAY;AAAA,cACd;AAAA;AAAA,UACD;AAAA,UACD,oBAAC,SAAI,OAAO;AAAA,YACV,SAAS,GAAG,KAAK;AAAA,YACjB,YAAY;AAAA,YACZ,GAAG;AAAA,UACL,GAAI,UAAS;AAAA,UACb;AAAA,YAAC;AAAA;AAAA,cACC,aAAa;AAAA,cACb,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,OAAO,GAAG,KAAK;AAAA,gBACf,QAAQ,GAAG,KAAK;AAAA,gBAChB,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,OAAO;AAAA,cACT;AAAA;AAAA,UACD;AAAA;AAAA;AAAA,IACH;AAAA,IACA,SAAS;AAAA,EACX;AACF;","names":["frame","frame"]}
|
|
1
|
+
{"version":3,"sources":["../src/frame.ts","../src/PixelWindow.tsx"],"sourcesContent":["export function getFrame({ size, stroke, frame, background }: { size: number; stroke: string; frame: string; background: string }): string {\n const height = size; // Assuming square frames\n const svg = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{{size}}\" height=\"{{height}}\" viewBox=\"0 0 12 12\"><path fill=\"{{stroke}}\" d=\"M2 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9zM1 1h1v1H1z\"/><path fill=\"{{frame}}\" d=\"M2 1h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{stroke}}\" d=\"M10 1h1v1h-1zM0 2h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 2h1v1H1zm1 0h1v1H2z\"/><path fill=\"{{stroke}}\" d=\"M3 2h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{frame}}\" d=\"M9 2h1v1H9zm1 0h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 2h1v1h-1zM0 3h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 3h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 3h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 3h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 3h1v1h-1zM0 4h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 4h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 4h1v1H2zm1 0h1v1H3z\"/><path fill=\"{{background}}\" d=\"M4 4h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7z\"/><path fill=\"{{stroke}}\" d=\"M8 4h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 4h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 4h1v1h-1zM0 5h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 5h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 5h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 5h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 5h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 5h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 5h1v1h-1zM0 6h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 6h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 6h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 6h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 6h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 6h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 6h1v1h-1zM0 7h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 7h1v1H1z\"/><path fill=\"{{stroke}}\" d=\"M2 7h1v1H2z\"/><path fill=\"{{background}}\" d=\"M3 7h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{stroke}}\" d=\"M9 7h1v1H9z\"/><path fill=\"{{frame}}\" d=\"M10 7h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 7h1v1h-1zM0 8h1v1H0z\"/><path fill=\"{{frame}}\" d=\"M1 8h1v1H1zm1 0h1v1H2z\"/><path fill=\"{{stroke}}\" d=\"M3 8h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8z\"/><path fill=\"{{frame}}\" d=\"M9 8h1v1H9zm1 0h1v1h-1z\"/><path fill=\"{{stroke}}\" d=\"M11 8h1v1h-1zM0 9h1v1H0zm1 0h1v1H1z\"/><path fill=\"{{frame}}\" d=\"M2 9h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/><path fill=\"{{stroke}}\" d=\"M10 9h1v1h-1zm-9 1h1v1H1zm1 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9zm1 0h1v1h-1zm-8 1h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7zm1 0h1v1H8zm1 0h1v1H9z\"/></svg>'\n .replace(/\\{\\{size\\}\\}/g, size.toString())\n .replace(/\\{\\{height\\}\\}/g, height.toString())\n .replace(/\\{\\{stroke\\}\\}/g, stroke)\n .replace(/\\{\\{frame\\}\\}/g, frame)\n .replace(/\\{\\{background\\}\\}/g, background);\n\n // Encode SVG to Base64 safely\n const encodedSvg = encodeURIComponent(svg)\n .replace(/%([0-9A-F]{2})/g, (_, p1) => String.fromCharCode(parseInt(p1, 16)));\n\n return `data:image/svg+xml;base64,${btoa(encodedSvg)}`;\n}\n\nfunction getCheckbox({ size, color }: { size: number; color: string }) {\n const svg = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{{width}}\" height=\"{{height}}\" viewBox=\"0 0 12 6\"><rect width=\"1\" height=\"1\" x=\"1\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"4\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"7\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"8\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"9\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"10\" y=\"0\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"1\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"2\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"3\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"0\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"5\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"6\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"11\" y=\"4\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"1\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"2\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"3\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"4\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"7\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"8\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"9\" y=\"5\" fill=\"{{color}}\"></rect><rect width=\"1\" height=\"1\" x=\"10\" y=\"5\" fill=\"{{color}}\"></rect></svg>'\n .replace(/\\{\\{width\\}\\}/g, (size*2).toString())\n .replace(/\\{\\{height\\}\\}/g, size.toString())\n .replace(/\\{\\{color\\}\\}/g, color)\n \n const encodedSvg = encodeURIComponent(svg)\n .replace(/%([0-9A-F]{2})/g, (_, p1) => String.fromCharCode(parseInt(p1, 16)))\n .replace(/#/g, '%23');\n\n return `data:image/svg+xml;base64,${btoa(encodedSvg)}`;\n\n}\n\nexport const frame = getFrame({\n size: 160,\n stroke: '#000',\n frame: '#333',\n background: '#DDD',\n});\n\nexport const checkbox = getCheckbox({\n size: 12,\n color: '#000',\n});\nexport const checkboxLight = getCheckbox({\n size: 12,\n color: '#000',\n});\n","import { getFrame } from './frame';\nimport { useCallback, useEffect, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport const PixelWindow = ({\n style = {},\n stroke = '#000',\n frame = '#333',\n background = '#DDD',\n pixel = 160,\n children,\n}: {\n style?: React.CSSProperties,\n pixel?: number,\n stroke?: string\n frame?: string\n background?: string\n children: ReactNode;\n}) => {\n\n const pixelFrame = getFrame({\n size: pixel,\n stroke,\n frame,\n background,\n });\n\n return (\n <div\n className=\"window\"\n style={{\n width: '100%',\n height: '100%',\n borderImage: `url(${pixelFrame})`,\n borderImageSlice: '49% 49% fill',\n borderImageWidth: `${pixel}px`,\n }}\n >\n <div style={{ padding: `${pixel}px`}}>\n <div\n style={{ boxSizing: 'border-box', ...style }}\n >\n {children}\n </div>\n </div>\n </div>\n );\n};\n\nexport const FreePixelWindow = ({\n name,\n children,\n pixel = 16,\n stroke = '#000',\n frame = '#333',\n background = '#DDD',\n position: initialPosition = { x: 100, y: 100 },\n style,\n minWidth = 120,\n minHeight = 100,\n onChange,\n}: {\n name?: string;\n children: ReactNode;\n pixel?: number;\n stroke?: string;\n frame?: string;\n background?: string;\n position?: { x: number; y: number };\n style?: React.CSSProperties;\n minWidth?: number;\n minHeight?: number;\n onChange?: (position: { x: number; y: number }, size: { width: number; height: number }) => void;\n}) => {\n\n const [position, setPosition] = useState(() => {\n if (name) {\n const savedPosition = localStorage.getItem(`${name}-position`);\n return savedPosition ? JSON.parse(savedPosition) : initialPosition;\n }\n return initialPosition;\n });\n\n const [size, setSize] = useState(() => {\n const savedSize = localStorage.getItem(`${name}-size`);\n return savedSize ? JSON.parse(savedSize) : { width: 300, height: 200 };\n });\n\n const [isDragging, setIsDragging] = useState(false);\n const [isResizing, setIsResizing] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [resizeStart, setResizeStart] = useState({ width: 0, height: 0, mouseX: 0, mouseY: 0 });\n\n useEffect(() => {\n if (onChange) {\n onChange(position, size);\n }\n }, [position, size, onChange]);\n\n useEffect(() => {\n if (name) {\n localStorage.setItem(`${name}-position`, JSON.stringify(position));\n localStorage.setItem(`${name}-size`, JSON.stringify(size));\n }\n }, [name, position, size]);\n\n const handleMouseMove = useCallback((e: MouseEvent) => {\n if (isDragging) {\n setPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n });\n } else if (isResizing) {\n const deltaX = e.clientX - resizeStart.mouseX;\n const deltaY = e.clientY - resizeStart.mouseY;\n\n setSize({\n width: Math.max(resizeStart.width + deltaX, minWidth),\n height: Math.max(resizeStart.height + deltaY, minHeight),\n });\n }\n }, [isDragging, isResizing, dragStart, resizeStart, minWidth, minHeight]);\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n setIsResizing(false);\n }, []);\n\n useEffect(() => {\n if (isDragging || isResizing) {\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n } else {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n }\n\n return () => {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n };\n }, [isDragging, isResizing, handleMouseMove, handleMouseUp]);\n\n const handleMouseDown = (e: React.MouseEvent) => {\n setIsDragging(true);\n setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });\n };\n\n const handleResizeStart = (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsResizing(true);\n setResizeStart({\n width: size.width,\n height: size.height,\n mouseX: e.clientX,\n mouseY: e.clientY,\n });\n };\n\n const pixelFrame = getFrame({\n size: pixel,\n stroke,\n frame,\n background,\n });\n\n return createPortal(\n <div\n style={{\n position: 'absolute',\n overflow: 'hidden',\n resize: 'none',\n top: position.y,\n left: position.x,\n width: size.width,\n height: size.height,\n borderImage: `url(${pixelFrame})`,\n borderImageSlice: '49% 49% fill',\n borderImageWidth: `${pixel}px`,\n }}\n onMouseUp={handleMouseUp}\n >\n <div \n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n style={{\n height: `${pixel}px`,\n cursor: \"grab\",\n userSelect: \"none\"\n }}\n ></div>\n <div style={{\n padding: `${pixel}px`,\n paddingTop: 0,\n height: `calc(100% - ${pixel}px)`,\n boxSizing: 'border-box',\n ...style\n }}>{children}</div>\n <div\n onMouseDown={handleResizeStart}\n style={{\n position: 'absolute',\n width: `${pixel}px`,\n height: `${pixel}px`,\n cursor: 'se-resize',\n bottom: 0,\n right: 0,\n }}\n ></div>\n </div>,\n document.body\n );\n};\n"],"mappings":"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","names":["frame","frame"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glennjong/pixel-window",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
8
10
|
"exports": {
|
|
9
11
|
".": {
|
|
10
12
|
"import": "./dist/index.mjs",
|