react-sticky-canvas 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # react-sticky-canvas
2
+
3
+ Draggable, minimal sticky notes for React. Highly customizable, mobile-friendly, and lightweight.
4
+
5
+ ## Features
6
+
7
+ - 🖱️ **Draggable**: Drag and drop anywhere on the canvas.
8
+ - 📱 **Mobile Friendly**: Supports touch events and custom mobile positioning.
9
+ - 🔒 **Lockable**: Lock notes in place.
10
+ - 🛠️ **Debug Mode**: Easily see coordinates and rotation.
11
+ - 💾 **Auto-save**: Positions are automatically persisted to `localStorage`.
12
+ - 🎨 **Customizable**: Supply your own content or use the simple text default.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install react-sticky-canvas motion
18
+ ```
19
+
20
+ *Note: `motion` (Framer Motion) is a required dependency.*
21
+
22
+ ## Usage
23
+
24
+ ### Simple Example
25
+
26
+ ```tsx
27
+ import { StickyCanvas } from 'react-sticky-canvas';
28
+
29
+ const notes = [
30
+ {
31
+ id: 'note-1',
32
+ text: 'Hello World!',
33
+ color: 'yellow',
34
+ initialX: 100,
35
+ initialY: 100,
36
+ initialRotation: 5,
37
+ },
38
+ {
39
+ id: 'note-2',
40
+ text: 'Drag me!',
41
+ color: 'green',
42
+ initialX: 300,
43
+ initialY: 150,
44
+ }
45
+ ];
46
+
47
+ function App() {
48
+ return (
49
+ <div className="relative min-h-screen">
50
+ <StickyCanvas notes={notes} />
51
+ </div>
52
+ );
53
+ }
54
+ ```
55
+
56
+ ### Advanced Usage with Custom Content
57
+
58
+ ```tsx
59
+ import { StickyCanvas, StickyNote } from 'react-sticky-canvas';
60
+
61
+ function CustomApp() {
62
+ return (
63
+ <StickyCanvas debug>
64
+ <StickyNote
65
+ id="custom-1"
66
+ color="pink"
67
+ initialX={200}
68
+ initialY={200}
69
+ width={200}
70
+ height={200}
71
+ >
72
+ <div className="custom-content">
73
+ <h3>Custom Note</h3>
74
+ <p>You can put any JSX here!</p>
75
+ </div>
76
+ </StickyNote>
77
+ </StickyCanvas>
78
+ );
79
+ }
80
+ ```
81
+
82
+ ## Props
83
+
84
+ ### StickyCanvas
85
+
86
+ | Prop | Type | Default | Description |
87
+ | --- | --- | --- | --- |
88
+ | `notes` | `StickyNoteConfig[]` | `[]` | Array of note configurations. |
89
+ | `zIndex` | `number` | `9998` | Z-index of the canvas container. |
90
+ | `debug` | `boolean` | `false` | Enable debug mode for all notes. |
91
+ | `className` | `string` | `''` | Custom class for the container. |
92
+
93
+ ### StickyNote
94
+
95
+ | Prop | Type | Default | Description |
96
+ | --- | --- | --- | --- |
97
+ | `id` | `string` | **Required** | Unique identifier for the note (used for localStorage). |
98
+ | `text` | `string` | `undefined` | Simple text content. |
99
+ | `content` | `ReactNode` | `undefined` | Custom JSX content (overrides text). |
100
+ | `color` | `StickyNoteColor` | `'yellow'` | Note background color. |
101
+ | `initialX` | `number` | **Required** | Starting X position. |
102
+ | `initialY` | `number` | **Required** | Starting Y position. |
103
+ | `initialRotation` | `number` | `0` | Starting rotation in degrees. |
104
+ | `width` | `number` | `120` | Note width. |
105
+ | `height` | `number` | `120` | Note height. |
106
+ | `locked` | `boolean` | `false` | If true, the note cannot be dragged. |
107
+ | `showDebug` | `boolean` | `false` | Show debug info for this specific note. |
108
+
109
+ ## License
110
+
111
+ MIT
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+
3
+ type StickyNoteColor = 'yellow' | 'green' | 'pink' | 'blue' | 'purple' | 'orange';
4
+ interface StickyNotePosition {
5
+ x: number;
6
+ y: number;
7
+ rotation: number;
8
+ }
9
+ interface StickyNoteProps {
10
+ id: string;
11
+ text?: string;
12
+ content?: React.ReactNode;
13
+ color: StickyNoteColor;
14
+ initialX: number;
15
+ initialY: number;
16
+ initialRotation?: number;
17
+ width?: number;
18
+ height?: number;
19
+ mobileWidth?: number;
20
+ mobileHeight?: number;
21
+ mobileX?: number;
22
+ mobileY?: number;
23
+ delay?: number;
24
+ onPositionChange?: (id: string, x: number, y: number) => void;
25
+ showDebug?: boolean;
26
+ locked?: boolean;
27
+ className?: string;
28
+ }
29
+ interface StickyNoteConfig extends StickyNoteProps {
30
+ }
31
+ interface StickyCanvasProps {
32
+ notes?: StickyNoteConfig[];
33
+ children?: React.ReactNode;
34
+ zIndex?: number;
35
+ debug?: boolean;
36
+ className?: string;
37
+ style?: React.CSSProperties;
38
+ }
39
+
40
+ declare const StickyCanvas: React.FC<StickyCanvasProps>;
41
+
42
+ declare const StickyNote: React.FC<StickyNoteProps>;
43
+
44
+ export { StickyCanvas, type StickyCanvasProps, StickyNote, type StickyNoteColor, type StickyNoteConfig, type StickyNotePosition, type StickyNoteProps, StickyCanvas as default };
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+
3
+ type StickyNoteColor = 'yellow' | 'green' | 'pink' | 'blue' | 'purple' | 'orange';
4
+ interface StickyNotePosition {
5
+ x: number;
6
+ y: number;
7
+ rotation: number;
8
+ }
9
+ interface StickyNoteProps {
10
+ id: string;
11
+ text?: string;
12
+ content?: React.ReactNode;
13
+ color: StickyNoteColor;
14
+ initialX: number;
15
+ initialY: number;
16
+ initialRotation?: number;
17
+ width?: number;
18
+ height?: number;
19
+ mobileWidth?: number;
20
+ mobileHeight?: number;
21
+ mobileX?: number;
22
+ mobileY?: number;
23
+ delay?: number;
24
+ onPositionChange?: (id: string, x: number, y: number) => void;
25
+ showDebug?: boolean;
26
+ locked?: boolean;
27
+ className?: string;
28
+ }
29
+ interface StickyNoteConfig extends StickyNoteProps {
30
+ }
31
+ interface StickyCanvasProps {
32
+ notes?: StickyNoteConfig[];
33
+ children?: React.ReactNode;
34
+ zIndex?: number;
35
+ debug?: boolean;
36
+ className?: string;
37
+ style?: React.CSSProperties;
38
+ }
39
+
40
+ declare const StickyCanvas: React.FC<StickyCanvasProps>;
41
+
42
+ declare const StickyNote: React.FC<StickyNoteProps>;
43
+
44
+ export { StickyCanvas, type StickyCanvasProps, StickyNote, type StickyNoteColor, type StickyNoteConfig, type StickyNotePosition, type StickyNoteProps, StickyCanvas as default };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var O=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ne=Object.prototype.hasOwnProperty;var ie=(i,r)=>{for(var f in r)O(i,f,{get:r[f],enumerable:!0})},se=(i,r,f,p)=>{if(r&&typeof r=="object"||typeof r=="function")for(let d of oe(r))!ne.call(i,d)&&d!==f&&O(i,d,{get:()=>r[d],enumerable:!(p=te(r,d))||p.enumerable});return i};var re=i=>se(O({},"__esModule",{value:!0}),i);var de={};ie(de,{StickyCanvas:()=>k,StickyNote:()=>P,default:()=>ce});module.exports=re(de);var F=require("react");var t=require("react"),A=require("motion/react"),s=require("react/jsx-runtime"),ae={yellow:"#FBFF94",green:"#B8FFC6",pink:"#FFCDD5",blue:"#94E6FF",purple:"#CDA3FF",orange:"#FFE5A3"},P=({id:i,text:r,content:f,color:p,initialX:d,initialY:h,initialRotation:x=0,width:b=120,height:a=120,mobileWidth:v,mobileHeight:y,mobileX:m,mobileY:w,delay:W=0,onPositionChange:z,showDebug:J=!1,locked:c=!1,className:q=""})=>{let[E,K]=(0,t.useState)(!1),[o,S]=(0,t.useState)({x:d,y:h,rotation:x}),[u,X]=(0,t.useState)(!1),[H,U]=(0,t.useState)({x:0,y:0}),[j,Y]=(0,t.useState)(!1);(0,t.useEffect)(()=>{let e=()=>{if(typeof window>"u")return;let n=window.innerWidth<768;K(n),n&&(m!==void 0||w!==void 0)?S(l=>({...l,x:m!==void 0?m:l.x,y:w!==void 0?w:l.y})):n||S(l=>({...l,x:d,y:h}))};return e(),window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[d,h,m,w]),(0,t.useEffect)(()=>{if(typeof window>"u")return;let e=localStorage.getItem(`sticky-note-${i}`);if(e)try{let n=JSON.parse(e);S(n)}catch{}},[i]),(0,t.useEffect)(()=>{typeof window>"u"||u||(localStorage.setItem(`sticky-note-${i}`,JSON.stringify(o)),z?.(i,o.x,o.y))},[o,u,i,z]);let M=(0,t.useCallback)((e,n)=>{if(c)return;let l=window.scrollX||window.pageXOffset,$=window.scrollY||window.pageYOffset,I=e+l,N=n+$;X(!0),U({x:I-o.x,y:N-o.y})},[o,c]),G=(0,t.useCallback)(e=>{c||(e.preventDefault(),M(e.clientX,e.clientY))},[M,c]),Q=(0,t.useCallback)(e=>{if(c)return;let n=e.touches[0];n&&M(n.clientX,n.clientY)},[M,c]),C=(0,t.useCallback)((e,n)=>{if(!u||c)return;let l=window.scrollX||window.pageXOffset,$=window.scrollY||window.pageYOffset,I=e+l,N=n+$;S(ee=>({...ee,x:I-H.x,y:N-H.y}))},[u,H,c]),D=(0,t.useCallback)(e=>{C(e.clientX,e.clientY)},[C]),R=(0,t.useCallback)(e=>{if(!u)return;let n=e.touches[0];n&&C(n.clientX,n.clientY)},[u,C]),g=(0,t.useCallback)(()=>{X(!1)},[]);(0,t.useEffect)(()=>{if(u)return window.addEventListener("mousemove",D),window.addEventListener("mouseup",g),window.addEventListener("touchmove",R,{passive:!1}),window.addEventListener("touchend",g),()=>{window.removeEventListener("mousemove",D),window.removeEventListener("mouseup",g),window.removeEventListener("touchmove",R),window.removeEventListener("touchend",g)}},[u,D,g,R]);let V=j&&!u&&!c?o.rotation+(p==="green"?8:-5):o.rotation,Z=f||(0,s.jsx)("p",{style:{fontSize:E?"14px":"18px",fontWeight:500,lineHeight:"1.2",textAlign:"center",margin:0,fontFamily:"inherit"},children:r}),_=E&&v!==void 0?v:b,T=E&&y!==void 0?y:a;return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(A.motion.div,{className:`sticky-note ${q}`,style:{position:"absolute",pointerEvents:"auto",cursor:c?"default":"move",touchAction:"none",backgroundColor:ae[p],left:`${o.x}px`,top:`${o.y}px`,width:`${_}px`,height:`${T}px`,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 4px 10px rgba(150, 150, 180, 0.3), 0 2px 4px rgba(100, 100, 120, 0.2)",borderRadius:"0px",padding:E?"8px":"12px",zIndex:u?1e3:1},initial:{opacity:0,scale:.5,rotate:o.rotation-20,y:50},animate:{opacity:1,scale:1,rotate:u?o.rotation:V,x:0,y:0},transition:{type:"spring",stiffness:200,damping:15,delay:W},whileHover:c?{}:{scale:1.05,transition:{duration:.2}},onMouseDown:G,onTouchStart:Q,onMouseEnter:()=>Y(!0),onMouseLeave:()=>Y(!1),children:(0,s.jsx)("div",{style:{height:"100%",width:"100%",display:"flex",alignItems:"center",justifyItems:"center"},children:Z})}),J&&(0,s.jsxs)("div",{style:{position:"absolute",pointerEvents:"none",zIndex:1e4,backgroundColor:"rgba(0,0,0,0.8)",color:"white",fontSize:"10px",fontFamily:"monospace",padding:"4px 8px",borderRadius:"4px",boxShadow:"0 2px 4px rgba(0,0,0,0.2)",whiteSpace:"nowrap",left:`${o.x}px`,top:`${o.y+T+5}px`},children:[(0,s.jsxs)("div",{style:{fontWeight:"bold",marginBottom:"2px"},children:["ID: ",i]}),(0,s.jsxs)("div",{children:["X: ",Math.round(o.x)]}),(0,s.jsxs)("div",{children:["Y: ",Math.round(o.y)]}),(0,s.jsxs)("div",{children:["Rot: ",Math.round(o.rotation),"\xB0"]}),c&&(0,s.jsx)("div",{style:{color:"#ff4d4d"},children:"LOCKED"})]})]})},B=P;var L=require("react/jsx-runtime"),k=({notes:i,children:r,zIndex:f=9998,debug:p=!1,className:d="",style:h={}})=>{let[x,b]=(0,F.useState)(0);return(0,F.useEffect)(()=>{if(typeof window>"u")return;let a=()=>{let m=document.querySelector("main");if(m)b(m.scrollHeight);else{let w=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight);b(w)}},v=setTimeout(a,100);a();let y=new MutationObserver(a);return y.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class"]}),window.addEventListener("resize",a),()=>{clearTimeout(v),y.disconnect(),window.removeEventListener("resize",a)}},[]),(0,L.jsxs)("div",{className:`sticky-canvas-container ${d}`,style:{position:"absolute",left:0,top:0,width:"100%",height:x>0?`${x}px`:"100vh",zIndex:f,minHeight:"100vh",pointerEvents:"none",...h},children:[i&&i.map((a,v)=>(0,L.jsx)(B,{...a,delay:a.delay??v*.1,showDebug:p||a.showDebug},a.id)),r]})};var ce=k;0&&(module.exports={StickyCanvas,StickyNote});
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/StickyCanvas.tsx","../src/StickyNote.tsx"],"sourcesContent":["export * from './StickyCanvas';\r\nexport * from './StickyNote';\r\nexport * from './types';\r\n\r\n// Default export could be StickyCanvas for convenience\r\nimport { StickyCanvas } from './StickyCanvas';\r\nexport default StickyCanvas;\r\n","\"use client\";\r\n\r\nimport React, { useEffect, useState } from 'react';\r\nimport { StickyCanvasProps } from './types';\r\nimport StickyNote from './StickyNote';\r\n\r\nexport const StickyCanvas: React.FC<StickyCanvasProps> = ({\r\n notes,\r\n children,\r\n zIndex = 9998,\r\n debug = false,\r\n className = '',\r\n style = {},\r\n}) => {\r\n const [containerHeight, setContainerHeight] = useState<number>(0);\r\n\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const updateHeight = () => {\r\n const main = document.querySelector('main');\r\n if (main) {\r\n setContainerHeight(main.scrollHeight);\r\n } else {\r\n const docHeight = Math.max(\r\n document.body.scrollHeight,\r\n document.body.offsetHeight,\r\n document.documentElement.clientHeight,\r\n document.documentElement.scrollHeight,\r\n document.documentElement.offsetHeight\r\n );\r\n setContainerHeight(docHeight);\r\n }\r\n };\r\n\r\n const timeoutId = setTimeout(updateHeight, 100);\r\n updateHeight();\r\n\r\n const observer = new MutationObserver(updateHeight);\r\n observer.observe(document.body, {\r\n childList: true,\r\n subtree: true,\r\n attributes: true,\r\n attributeFilter: ['style', 'class'],\r\n });\r\n\r\n window.addEventListener('resize', updateHeight);\r\n\r\n return () => {\r\n clearTimeout(timeoutId);\r\n observer.disconnect();\r\n window.removeEventListener('resize', updateHeight);\r\n };\r\n }, []);\r\n\r\n return (\r\n <div\r\n className={`sticky-canvas-container ${className}`}\r\n style={{\r\n position: 'absolute',\r\n left: 0,\r\n top: 0,\r\n width: '100%',\r\n height: containerHeight > 0 ? `${containerHeight}px` : '100vh',\r\n zIndex,\r\n minHeight: '100vh',\r\n pointerEvents: 'none',\r\n ...style,\r\n }}\r\n >\r\n {notes && notes.map((note, index) => (\r\n <StickyNote\r\n key={note.id}\r\n {...note}\r\n delay={note.delay ?? index * 0.1}\r\n showDebug={debug || note.showDebug}\r\n />\r\n ))}\r\n {children}\r\n </div>\r\n );\r\n};\r\n\r\nexport default StickyCanvas;\r\n","\"use client\";\r\n\r\nimport React, { useState, useEffect, useCallback } from 'react';\r\nimport { motion } from 'motion/react';\r\nimport { StickyNoteProps, StickyNoteColor } from './types';\r\n\r\nconst colorClasses: Record<StickyNoteColor, string> = {\r\n yellow: '#FBFF94',\r\n green: '#B8FFC6',\r\n pink: '#FFCDD5',\r\n blue: '#94E6FF',\r\n purple: '#CDA3FF',\r\n orange: '#FFE5A3',\r\n};\r\n\r\nexport const StickyNote: React.FC<StickyNoteProps> = ({\r\n id,\r\n text,\r\n content,\r\n color,\r\n initialX,\r\n initialY,\r\n initialRotation = 0,\r\n width = 120,\r\n height = 120,\r\n mobileWidth,\r\n mobileHeight,\r\n mobileX,\r\n mobileY,\r\n delay = 0,\r\n onPositionChange,\r\n showDebug = false,\r\n locked = false,\r\n className = '',\r\n}) => {\r\n const [isMobile, setIsMobile] = useState(false);\r\n const [position, setPosition] = useState<{ x: number; y: number; rotation: number }>({\r\n x: initialX,\r\n y: initialY,\r\n rotation: initialRotation,\r\n });\r\n const [dragging, setDragging] = useState(false);\r\n const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });\r\n const [hovered, setHovered] = useState(false);\r\n\r\n // Detect mobile and adjust initial position\r\n useEffect(() => {\r\n const checkMobile = () => {\r\n if (typeof window === 'undefined') return;\r\n const mobile = window.innerWidth < 768;\r\n setIsMobile(mobile);\r\n\r\n if (mobile && (mobileX !== undefined || mobileY !== undefined)) {\r\n setPosition(prev => ({\r\n ...prev,\r\n x: mobileX !== undefined ? mobileX : prev.x,\r\n y: mobileY !== undefined ? mobileY : prev.y,\r\n }));\r\n } else if (!mobile) {\r\n setPosition(prev => ({\r\n ...prev,\r\n x: initialX,\r\n y: initialY,\r\n }));\r\n }\r\n };\r\n\r\n checkMobile();\r\n window.addEventListener('resize', checkMobile);\r\n return () => window.removeEventListener('resize', checkMobile);\r\n }, [initialX, initialY, mobileX, mobileY]);\r\n\r\n // Load position from localStorage on mount\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n const saved = localStorage.getItem(`sticky-note-${id}`);\r\n if (saved) {\r\n try {\r\n const parsed = JSON.parse(saved);\r\n setPosition(parsed);\r\n } catch (e) {\r\n // Invalid saved data, use initial position\r\n }\r\n }\r\n }, [id]);\r\n\r\n // Save position to localStorage when it changes\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n if (!dragging) {\r\n localStorage.setItem(`sticky-note-${id}`, JSON.stringify(position));\r\n onPositionChange?.(id, position.x, position.y);\r\n }\r\n }, [position, dragging, id, onPositionChange]);\r\n\r\n const handleStart = useCallback((clientX: number, clientY: number) => {\r\n if (locked) return;\r\n\r\n const scrollX = window.scrollX || window.pageXOffset;\r\n const scrollY = window.scrollY || window.pageYOffset;\r\n const pageX = clientX + scrollX;\r\n const pageY = clientY + scrollY;\r\n\r\n setDragging(true);\r\n setDragOffset({\r\n x: pageX - position.x,\r\n y: pageY - position.y,\r\n });\r\n }, [position, locked]);\r\n\r\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\r\n if (locked) return;\r\n e.preventDefault();\r\n handleStart(e.clientX, e.clientY);\r\n }, [handleStart, locked]);\r\n\r\n const handleTouchStart = useCallback((e: React.TouchEvent) => {\r\n if (locked) return;\r\n const touch = e.touches[0];\r\n if (touch) {\r\n handleStart(touch.clientX, touch.clientY);\r\n }\r\n }, [handleStart, locked]);\r\n\r\n const handleMove = useCallback((clientX: number, clientY: number) => {\r\n if (!dragging || locked) return;\r\n\r\n const scrollX = window.scrollX || window.pageXOffset;\r\n const scrollY = window.scrollY || window.pageYOffset;\r\n const pageX = clientX + scrollX;\r\n const pageY = clientY + scrollY;\r\n\r\n setPosition((prev) => ({\r\n ...prev,\r\n x: pageX - dragOffset.x,\r\n y: pageY - dragOffset.y,\r\n }));\r\n }, [dragging, dragOffset, locked]);\r\n\r\n const handleMouseMove = useCallback((e: MouseEvent) => {\r\n handleMove(e.clientX, e.clientY);\r\n }, [handleMove]);\r\n\r\n const handleTouchMove = useCallback((e: TouchEvent) => {\r\n if (!dragging) return;\r\n const touch = e.touches[0];\r\n if (touch) {\r\n handleMove(touch.clientX, touch.clientY);\r\n }\r\n }, [dragging, handleMove]);\r\n\r\n const handleMouseUp = useCallback(() => {\r\n setDragging(false);\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (dragging) {\r\n window.addEventListener('mousemove', handleMouseMove);\r\n window.addEventListener('mouseup', handleMouseUp);\r\n window.addEventListener('touchmove', handleTouchMove, { passive: false });\r\n window.addEventListener('touchend', handleMouseUp);\r\n return () => {\r\n window.removeEventListener('mousemove', handleMouseMove);\r\n window.removeEventListener('mouseup', handleMouseUp);\r\n window.removeEventListener('touchmove', handleTouchMove);\r\n window.removeEventListener('touchend', handleMouseUp);\r\n };\r\n }\r\n }, [dragging, handleMouseMove, handleMouseUp, handleTouchMove]);\r\n\r\n const hoverRotation = hovered && !dragging && !locked ? position.rotation + (color === 'green' ? 8 : -5) : position.rotation;\r\n\r\n const displayContent = content || (\r\n <p style={{\r\n fontSize: isMobile ? '14px' : '18px',\r\n fontWeight: 500,\r\n lineHeight: '1.2',\r\n textAlign: 'center',\r\n margin: 0,\r\n fontFamily: 'inherit'\r\n }}>\r\n {text}\r\n </p>\r\n );\r\n\r\n const noteWidth = isMobile && mobileWidth !== undefined ? mobileWidth : width;\r\n const noteHeight = isMobile && mobileHeight !== undefined ? mobileHeight : height;\r\n\r\n return (\r\n <>\r\n <motion.div\r\n className={`sticky-note ${className}`}\r\n style={{\r\n position: 'absolute',\r\n pointerEvents: 'auto',\r\n cursor: locked ? 'default' : 'move',\r\n touchAction: 'none',\r\n backgroundColor: colorClasses[color],\r\n left: `${position.x}px`,\r\n top: `${position.y}px`,\r\n width: `${noteWidth}px`,\r\n height: `${noteHeight}px`,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n boxShadow: '0 4px 10px rgba(150, 150, 180, 0.3), 0 2px 4px rgba(100, 100, 120, 0.2)',\r\n borderRadius: '0px',\r\n padding: isMobile ? '8px' : '12px',\r\n zIndex: dragging ? 1000 : 1,\r\n }}\r\n initial={{\r\n opacity: 0,\r\n scale: 0.5,\r\n rotate: position.rotation - 20,\r\n y: 50\r\n }}\r\n animate={{\r\n opacity: 1,\r\n scale: 1,\r\n rotate: dragging ? position.rotation : hoverRotation,\r\n x: 0, // motion handles left/top via style but we can animate these too if we wanted\r\n y: 0\r\n }}\r\n transition={{\r\n type: \"spring\",\r\n stiffness: 200,\r\n damping: 15,\r\n delay,\r\n }}\r\n whileHover={!locked ? {\r\n scale: 1.05,\r\n transition: { duration: 0.2 }\r\n } : {}}\r\n onMouseDown={handleMouseDown}\r\n onTouchStart={handleTouchStart}\r\n onMouseEnter={() => setHovered(true)}\r\n onMouseLeave={() => setHovered(false)}\r\n >\r\n <div style={{ height: '100%', width: '100%', display: 'flex', alignItems: 'center', justifyItems: 'center' }}>\r\n {displayContent}\r\n </div>\r\n </motion.div>\r\n\r\n {showDebug && (\r\n <div\r\n style={{\r\n position: 'absolute',\r\n pointerEvents: 'none',\r\n zIndex: 10000,\r\n backgroundColor: 'rgba(0,0,0,0.8)',\r\n color: 'white',\r\n fontSize: '10px',\r\n fontFamily: 'monospace',\r\n padding: '4px 8px',\r\n borderRadius: '4px',\r\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)',\r\n whiteSpace: 'nowrap',\r\n left: `${position.x}px`,\r\n top: `${position.y + noteHeight + 5}px`,\r\n }}\r\n >\r\n <div style={{ fontWeight: 'bold', marginBottom: '2px' }}>ID: {id}</div>\r\n <div>X: {Math.round(position.x)}</div>\r\n <div>Y: {Math.round(position.y)}</div>\r\n <div>Rot: {Math.round(position.rotation)}°</div>\r\n {locked && <div style={{ color: '#ff4d4d' }}>LOCKED</div>}\r\n </div>\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nexport default StickyNote;\r\n"],"mappings":"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","names":["index_exports","__export","StickyCanvas","StickyNote","index_default","__toCommonJS","import_react","import_react","import_jsx_runtime","colorClasses","StickyNote","id","text","content","color","initialX","initialY","initialRotation","width","height","mobileWidth","mobileHeight","mobileX","mobileY","delay","onPositionChange","showDebug","locked","className","isMobile","setIsMobile","position","setPosition","dragging","setDragging","dragOffset","setDragOffset","hovered","setHovered","checkMobile","mobile","prev","saved","parsed","handleStart","clientX","clientY","scrollX","scrollY","pageX","pageY","handleMouseDown","handleTouchStart","touch","handleMove","handleMouseMove","handleTouchMove","handleMouseUp","hoverRotation","displayContent","noteWidth","noteHeight","StickyNote_default","import_jsx_runtime","StickyCanvas","notes","children","zIndex","debug","className","style","containerHeight","setContainerHeight","updateHeight","main","docHeight","timeoutId","observer","note","index","StickyNote_default","index_default","StickyCanvas"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{useEffect as ne,useState as ie}from"react";import{useState as h,useEffect as C,useCallback as d}from"react";import{motion as _}from"motion/react";import{Fragment as oe,jsx as F,jsxs as f}from"react/jsx-runtime";var ee={yellow:"#FBFF94",green:"#B8FFC6",pink:"#FFCDD5",blue:"#94E6FF",purple:"#CDA3FF",orange:"#FFE5A3"},te=({id:r,text:L,content:H,color:y,initialX:p,initialY:m,initialRotation:g=0,width:x=120,height:n=120,mobileWidth:u,mobileHeight:v,mobileX:c,mobileY:l,delay:P=0,onPositionChange:k,showDebug:B=!1,locked:i=!1,className:W=""})=>{let[b,J]=h(!1),[t,E]=h({x:p,y:m,rotation:g}),[s,z]=h(!1),[D,q]=h({x:0,y:0}),[K,X]=h(!1);C(()=>{let e=()=>{if(typeof window>"u")return;let o=window.innerWidth<768;J(o),o&&(c!==void 0||l!==void 0)?E(a=>({...a,x:c!==void 0?c:a.x,y:l!==void 0?l:a.y})):o||E(a=>({...a,x:p,y:m}))};return e(),window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[p,m,c,l]),C(()=>{if(typeof window>"u")return;let e=localStorage.getItem(`sticky-note-${r}`);if(e)try{let o=JSON.parse(e);E(o)}catch{}},[r]),C(()=>{typeof window>"u"||s||(localStorage.setItem(`sticky-note-${r}`,JSON.stringify(t)),k?.(r,t.x,t.y))},[t,s,r,k]);let S=d((e,o)=>{if(i)return;let a=window.scrollX||window.pageXOffset,I=window.scrollY||window.pageYOffset,N=e+a,O=o+I;z(!0),q({x:N-t.x,y:O-t.y})},[t,i]),U=d(e=>{i||(e.preventDefault(),S(e.clientX,e.clientY))},[S,i]),j=d(e=>{if(i)return;let o=e.touches[0];o&&S(o.clientX,o.clientY)},[S,i]),M=d((e,o)=>{if(!s||i)return;let a=window.scrollX||window.pageXOffset,I=window.scrollY||window.pageYOffset,N=e+a,O=o+I;E(Z=>({...Z,x:N-D.x,y:O-D.y}))},[s,D,i]),R=d(e=>{M(e.clientX,e.clientY)},[M]),$=d(e=>{if(!s)return;let o=e.touches[0];o&&M(o.clientX,o.clientY)},[s,M]),w=d(()=>{z(!1)},[]);C(()=>{if(s)return window.addEventListener("mousemove",R),window.addEventListener("mouseup",w),window.addEventListener("touchmove",$,{passive:!1}),window.addEventListener("touchend",w),()=>{window.removeEventListener("mousemove",R),window.removeEventListener("mouseup",w),window.removeEventListener("touchmove",$),window.removeEventListener("touchend",w)}},[s,R,w,$]);let G=K&&!s&&!i?t.rotation+(y==="green"?8:-5):t.rotation,Q=H||F("p",{style:{fontSize:b?"14px":"18px",fontWeight:500,lineHeight:"1.2",textAlign:"center",margin:0,fontFamily:"inherit"},children:L}),V=b&&u!==void 0?u:x,Y=b&&v!==void 0?v:n;return f(oe,{children:[F(_.div,{className:`sticky-note ${W}`,style:{position:"absolute",pointerEvents:"auto",cursor:i?"default":"move",touchAction:"none",backgroundColor:ee[y],left:`${t.x}px`,top:`${t.y}px`,width:`${V}px`,height:`${Y}px`,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 4px 10px rgba(150, 150, 180, 0.3), 0 2px 4px rgba(100, 100, 120, 0.2)",borderRadius:"0px",padding:b?"8px":"12px",zIndex:s?1e3:1},initial:{opacity:0,scale:.5,rotate:t.rotation-20,y:50},animate:{opacity:1,scale:1,rotate:s?t.rotation:G,x:0,y:0},transition:{type:"spring",stiffness:200,damping:15,delay:P},whileHover:i?{}:{scale:1.05,transition:{duration:.2}},onMouseDown:U,onTouchStart:j,onMouseEnter:()=>X(!0),onMouseLeave:()=>X(!1),children:F("div",{style:{height:"100%",width:"100%",display:"flex",alignItems:"center",justifyItems:"center"},children:Q})}),B&&f("div",{style:{position:"absolute",pointerEvents:"none",zIndex:1e4,backgroundColor:"rgba(0,0,0,0.8)",color:"white",fontSize:"10px",fontFamily:"monospace",padding:"4px 8px",borderRadius:"4px",boxShadow:"0 2px 4px rgba(0,0,0,0.2)",whiteSpace:"nowrap",left:`${t.x}px`,top:`${t.y+Y+5}px`},children:[f("div",{style:{fontWeight:"bold",marginBottom:"2px"},children:["ID: ",r]}),f("div",{children:["X: ",Math.round(t.x)]}),f("div",{children:["Y: ",Math.round(t.y)]}),f("div",{children:["Rot: ",Math.round(t.rotation),"\xB0"]}),i&&F("div",{style:{color:"#ff4d4d"},children:"LOCKED"})]})]})},T=te;import{jsx as se,jsxs as re}from"react/jsx-runtime";var A=({notes:r,children:L,zIndex:H=9998,debug:y=!1,className:p="",style:m={}})=>{let[g,x]=ie(0);return ne(()=>{if(typeof window>"u")return;let n=()=>{let c=document.querySelector("main");if(c)x(c.scrollHeight);else{let l=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight);x(l)}},u=setTimeout(n,100);n();let v=new MutationObserver(n);return v.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class"]}),window.addEventListener("resize",n),()=>{clearTimeout(u),v.disconnect(),window.removeEventListener("resize",n)}},[]),re("div",{className:`sticky-canvas-container ${p}`,style:{position:"absolute",left:0,top:0,width:"100%",height:g>0?`${g}px`:"100vh",zIndex:H,minHeight:"100vh",pointerEvents:"none",...m},children:[r&&r.map((n,u)=>se(T,{...n,delay:n.delay??u*.1,showDebug:y||n.showDebug},n.id)),L]})};var ye=A;export{A as StickyCanvas,te as StickyNote,ye as default};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/StickyCanvas.tsx","../src/StickyNote.tsx","../src/index.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport React, { useEffect, useState } from 'react';\r\nimport { StickyCanvasProps } from './types';\r\nimport StickyNote from './StickyNote';\r\n\r\nexport const StickyCanvas: React.FC<StickyCanvasProps> = ({\r\n notes,\r\n children,\r\n zIndex = 9998,\r\n debug = false,\r\n className = '',\r\n style = {},\r\n}) => {\r\n const [containerHeight, setContainerHeight] = useState<number>(0);\r\n\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const updateHeight = () => {\r\n const main = document.querySelector('main');\r\n if (main) {\r\n setContainerHeight(main.scrollHeight);\r\n } else {\r\n const docHeight = Math.max(\r\n document.body.scrollHeight,\r\n document.body.offsetHeight,\r\n document.documentElement.clientHeight,\r\n document.documentElement.scrollHeight,\r\n document.documentElement.offsetHeight\r\n );\r\n setContainerHeight(docHeight);\r\n }\r\n };\r\n\r\n const timeoutId = setTimeout(updateHeight, 100);\r\n updateHeight();\r\n\r\n const observer = new MutationObserver(updateHeight);\r\n observer.observe(document.body, {\r\n childList: true,\r\n subtree: true,\r\n attributes: true,\r\n attributeFilter: ['style', 'class'],\r\n });\r\n\r\n window.addEventListener('resize', updateHeight);\r\n\r\n return () => {\r\n clearTimeout(timeoutId);\r\n observer.disconnect();\r\n window.removeEventListener('resize', updateHeight);\r\n };\r\n }, []);\r\n\r\n return (\r\n <div\r\n className={`sticky-canvas-container ${className}`}\r\n style={{\r\n position: 'absolute',\r\n left: 0,\r\n top: 0,\r\n width: '100%',\r\n height: containerHeight > 0 ? `${containerHeight}px` : '100vh',\r\n zIndex,\r\n minHeight: '100vh',\r\n pointerEvents: 'none',\r\n ...style,\r\n }}\r\n >\r\n {notes && notes.map((note, index) => (\r\n <StickyNote\r\n key={note.id}\r\n {...note}\r\n delay={note.delay ?? index * 0.1}\r\n showDebug={debug || note.showDebug}\r\n />\r\n ))}\r\n {children}\r\n </div>\r\n );\r\n};\r\n\r\nexport default StickyCanvas;\r\n","\"use client\";\r\n\r\nimport React, { useState, useEffect, useCallback } from 'react';\r\nimport { motion } from 'motion/react';\r\nimport { StickyNoteProps, StickyNoteColor } from './types';\r\n\r\nconst colorClasses: Record<StickyNoteColor, string> = {\r\n yellow: '#FBFF94',\r\n green: '#B8FFC6',\r\n pink: '#FFCDD5',\r\n blue: '#94E6FF',\r\n purple: '#CDA3FF',\r\n orange: '#FFE5A3',\r\n};\r\n\r\nexport const StickyNote: React.FC<StickyNoteProps> = ({\r\n id,\r\n text,\r\n content,\r\n color,\r\n initialX,\r\n initialY,\r\n initialRotation = 0,\r\n width = 120,\r\n height = 120,\r\n mobileWidth,\r\n mobileHeight,\r\n mobileX,\r\n mobileY,\r\n delay = 0,\r\n onPositionChange,\r\n showDebug = false,\r\n locked = false,\r\n className = '',\r\n}) => {\r\n const [isMobile, setIsMobile] = useState(false);\r\n const [position, setPosition] = useState<{ x: number; y: number; rotation: number }>({\r\n x: initialX,\r\n y: initialY,\r\n rotation: initialRotation,\r\n });\r\n const [dragging, setDragging] = useState(false);\r\n const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });\r\n const [hovered, setHovered] = useState(false);\r\n\r\n // Detect mobile and adjust initial position\r\n useEffect(() => {\r\n const checkMobile = () => {\r\n if (typeof window === 'undefined') return;\r\n const mobile = window.innerWidth < 768;\r\n setIsMobile(mobile);\r\n\r\n if (mobile && (mobileX !== undefined || mobileY !== undefined)) {\r\n setPosition(prev => ({\r\n ...prev,\r\n x: mobileX !== undefined ? mobileX : prev.x,\r\n y: mobileY !== undefined ? mobileY : prev.y,\r\n }));\r\n } else if (!mobile) {\r\n setPosition(prev => ({\r\n ...prev,\r\n x: initialX,\r\n y: initialY,\r\n }));\r\n }\r\n };\r\n\r\n checkMobile();\r\n window.addEventListener('resize', checkMobile);\r\n return () => window.removeEventListener('resize', checkMobile);\r\n }, [initialX, initialY, mobileX, mobileY]);\r\n\r\n // Load position from localStorage on mount\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n const saved = localStorage.getItem(`sticky-note-${id}`);\r\n if (saved) {\r\n try {\r\n const parsed = JSON.parse(saved);\r\n setPosition(parsed);\r\n } catch (e) {\r\n // Invalid saved data, use initial position\r\n }\r\n }\r\n }, [id]);\r\n\r\n // Save position to localStorage when it changes\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n if (!dragging) {\r\n localStorage.setItem(`sticky-note-${id}`, JSON.stringify(position));\r\n onPositionChange?.(id, position.x, position.y);\r\n }\r\n }, [position, dragging, id, onPositionChange]);\r\n\r\n const handleStart = useCallback((clientX: number, clientY: number) => {\r\n if (locked) return;\r\n\r\n const scrollX = window.scrollX || window.pageXOffset;\r\n const scrollY = window.scrollY || window.pageYOffset;\r\n const pageX = clientX + scrollX;\r\n const pageY = clientY + scrollY;\r\n\r\n setDragging(true);\r\n setDragOffset({\r\n x: pageX - position.x,\r\n y: pageY - position.y,\r\n });\r\n }, [position, locked]);\r\n\r\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\r\n if (locked) return;\r\n e.preventDefault();\r\n handleStart(e.clientX, e.clientY);\r\n }, [handleStart, locked]);\r\n\r\n const handleTouchStart = useCallback((e: React.TouchEvent) => {\r\n if (locked) return;\r\n const touch = e.touches[0];\r\n if (touch) {\r\n handleStart(touch.clientX, touch.clientY);\r\n }\r\n }, [handleStart, locked]);\r\n\r\n const handleMove = useCallback((clientX: number, clientY: number) => {\r\n if (!dragging || locked) return;\r\n\r\n const scrollX = window.scrollX || window.pageXOffset;\r\n const scrollY = window.scrollY || window.pageYOffset;\r\n const pageX = clientX + scrollX;\r\n const pageY = clientY + scrollY;\r\n\r\n setPosition((prev) => ({\r\n ...prev,\r\n x: pageX - dragOffset.x,\r\n y: pageY - dragOffset.y,\r\n }));\r\n }, [dragging, dragOffset, locked]);\r\n\r\n const handleMouseMove = useCallback((e: MouseEvent) => {\r\n handleMove(e.clientX, e.clientY);\r\n }, [handleMove]);\r\n\r\n const handleTouchMove = useCallback((e: TouchEvent) => {\r\n if (!dragging) return;\r\n const touch = e.touches[0];\r\n if (touch) {\r\n handleMove(touch.clientX, touch.clientY);\r\n }\r\n }, [dragging, handleMove]);\r\n\r\n const handleMouseUp = useCallback(() => {\r\n setDragging(false);\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (dragging) {\r\n window.addEventListener('mousemove', handleMouseMove);\r\n window.addEventListener('mouseup', handleMouseUp);\r\n window.addEventListener('touchmove', handleTouchMove, { passive: false });\r\n window.addEventListener('touchend', handleMouseUp);\r\n return () => {\r\n window.removeEventListener('mousemove', handleMouseMove);\r\n window.removeEventListener('mouseup', handleMouseUp);\r\n window.removeEventListener('touchmove', handleTouchMove);\r\n window.removeEventListener('touchend', handleMouseUp);\r\n };\r\n }\r\n }, [dragging, handleMouseMove, handleMouseUp, handleTouchMove]);\r\n\r\n const hoverRotation = hovered && !dragging && !locked ? position.rotation + (color === 'green' ? 8 : -5) : position.rotation;\r\n\r\n const displayContent = content || (\r\n <p style={{\r\n fontSize: isMobile ? '14px' : '18px',\r\n fontWeight: 500,\r\n lineHeight: '1.2',\r\n textAlign: 'center',\r\n margin: 0,\r\n fontFamily: 'inherit'\r\n }}>\r\n {text}\r\n </p>\r\n );\r\n\r\n const noteWidth = isMobile && mobileWidth !== undefined ? mobileWidth : width;\r\n const noteHeight = isMobile && mobileHeight !== undefined ? mobileHeight : height;\r\n\r\n return (\r\n <>\r\n <motion.div\r\n className={`sticky-note ${className}`}\r\n style={{\r\n position: 'absolute',\r\n pointerEvents: 'auto',\r\n cursor: locked ? 'default' : 'move',\r\n touchAction: 'none',\r\n backgroundColor: colorClasses[color],\r\n left: `${position.x}px`,\r\n top: `${position.y}px`,\r\n width: `${noteWidth}px`,\r\n height: `${noteHeight}px`,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n boxShadow: '0 4px 10px rgba(150, 150, 180, 0.3), 0 2px 4px rgba(100, 100, 120, 0.2)',\r\n borderRadius: '0px',\r\n padding: isMobile ? '8px' : '12px',\r\n zIndex: dragging ? 1000 : 1,\r\n }}\r\n initial={{\r\n opacity: 0,\r\n scale: 0.5,\r\n rotate: position.rotation - 20,\r\n y: 50\r\n }}\r\n animate={{\r\n opacity: 1,\r\n scale: 1,\r\n rotate: dragging ? position.rotation : hoverRotation,\r\n x: 0, // motion handles left/top via style but we can animate these too if we wanted\r\n y: 0\r\n }}\r\n transition={{\r\n type: \"spring\",\r\n stiffness: 200,\r\n damping: 15,\r\n delay,\r\n }}\r\n whileHover={!locked ? {\r\n scale: 1.05,\r\n transition: { duration: 0.2 }\r\n } : {}}\r\n onMouseDown={handleMouseDown}\r\n onTouchStart={handleTouchStart}\r\n onMouseEnter={() => setHovered(true)}\r\n onMouseLeave={() => setHovered(false)}\r\n >\r\n <div style={{ height: '100%', width: '100%', display: 'flex', alignItems: 'center', justifyItems: 'center' }}>\r\n {displayContent}\r\n </div>\r\n </motion.div>\r\n\r\n {showDebug && (\r\n <div\r\n style={{\r\n position: 'absolute',\r\n pointerEvents: 'none',\r\n zIndex: 10000,\r\n backgroundColor: 'rgba(0,0,0,0.8)',\r\n color: 'white',\r\n fontSize: '10px',\r\n fontFamily: 'monospace',\r\n padding: '4px 8px',\r\n borderRadius: '4px',\r\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)',\r\n whiteSpace: 'nowrap',\r\n left: `${position.x}px`,\r\n top: `${position.y + noteHeight + 5}px`,\r\n }}\r\n >\r\n <div style={{ fontWeight: 'bold', marginBottom: '2px' }}>ID: {id}</div>\r\n <div>X: {Math.round(position.x)}</div>\r\n <div>Y: {Math.round(position.y)}</div>\r\n <div>Rot: {Math.round(position.rotation)}°</div>\r\n {locked && <div style={{ color: '#ff4d4d' }}>LOCKED</div>}\r\n </div>\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nexport default StickyNote;\r\n","export * from './StickyCanvas';\r\nexport * from './StickyNote';\r\nexport * from './types';\r\n\r\n// Default export could be StickyCanvas for convenience\r\nimport { StickyCanvas } from './StickyCanvas';\r\nexport default StickyCanvas;\r\n"],"mappings":"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","names":["useEffect","useState","useState","useEffect","useCallback","motion","Fragment","jsx","jsxs","colorClasses","StickyNote","id","text","content","color","initialX","initialY","initialRotation","width","height","mobileWidth","mobileHeight","mobileX","mobileY","delay","onPositionChange","showDebug","locked","className","isMobile","setIsMobile","position","setPosition","dragging","setDragging","dragOffset","setDragOffset","hovered","setHovered","checkMobile","mobile","prev","saved","parsed","handleStart","clientX","clientY","scrollX","scrollY","pageX","pageY","handleMouseDown","handleTouchStart","touch","handleMove","handleMouseMove","handleTouchMove","handleMouseUp","hoverRotation","displayContent","noteWidth","noteHeight","StickyNote_default","jsx","jsxs","StickyCanvas","notes","children","zIndex","debug","className","style","containerHeight","setContainerHeight","useState","useEffect","updateHeight","main","docHeight","timeoutId","observer","note","index","StickyNote_default","index_default","StickyCanvas"]}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "react-sticky-canvas",
3
+ "version": "0.1.0",
4
+ "description": "Draggable minimal sticky notes for React",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "peerDependencies": {
12
+ "react": ">=18",
13
+ "react-dom": ">=18",
14
+ "motion": ">=11"
15
+ },
16
+ "devDependencies": {
17
+ "@types/react": "^18.0.0",
18
+ "@types/react-dom": "^18.0.0",
19
+ "motion": "^11.15.0",
20
+ "tsup": "^8.0.0",
21
+ "typescript": "^5.0.0"
22
+ },
23
+ "dependencies": {},
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "publish:npm": "npm publish",
27
+ "dev": "tsup --watch"
28
+ }
29
+ }