ywana-core8 0.2.5 → 0.2.8
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.css +1134 -54
- package/dist/index.js +293 -90
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +293 -90
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +293 -90
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/desktop/ApplicationMenu.css +153 -54
- package/src/desktop/ApplicationMenu.js +75 -69
- package/src/desktop/Desktop.stories.jsx +256 -11
- package/src/desktop/WindowContext.js +4 -0
- package/src/desktop/WindowManager.js +54 -9
- package/src/desktop/desktop-linux.css +287 -0
- package/src/desktop/desktop-macos.css +317 -0
- package/src/desktop/desktop-windows.css +244 -0
- package/src/desktop/desktop.css +30 -0
- package/src/desktop/desktop.js +107 -67
- package/src/desktop/window.css +98 -0
- package/src/desktop/window.js +172 -4
- package/src/html/button.css +5 -0
- package/src/html/button.js +2 -1
package/src/desktop/window.js
CHANGED
@@ -25,14 +25,21 @@ export const Window = ({
|
|
25
25
|
const headerRef = useRef(null)
|
26
26
|
|
27
27
|
// Get window data from WindowManager
|
28
|
-
const { getWindow, updateWindowPosition, closeWindow, minimizeWindow, maximizeWindow, focusWindow } = useWindows()
|
28
|
+
const { getWindow, updateWindowPosition, updateWindowSize, closeWindow, minimizeWindow, maximizeWindow, focusWindow } = useWindows()
|
29
29
|
const windowData = getWindow(id)
|
30
|
-
|
30
|
+
|
31
31
|
// Local state for dragging
|
32
32
|
const [isDragging, setIsDragging] = useState(false)
|
33
33
|
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 })
|
34
34
|
const [dragStartPosition, setDragStartPosition] = useState({ x: 0, y: 0 })
|
35
35
|
|
36
|
+
// Local state for resizing
|
37
|
+
const [isResizing, setIsResizing] = useState(false)
|
38
|
+
const [resizeDirection, setResizeDirection] = useState('')
|
39
|
+
const [resizeStartSize, setResizeStartSize] = useState({ width: 0, height: 0 })
|
40
|
+
const [resizeStartPosition, setResizeStartPosition] = useState({ x: 0, y: 0 })
|
41
|
+
const [resizeStartMouse, setResizeStartMouse] = useState({ x: 0, y: 0 })
|
42
|
+
|
36
43
|
// If window doesn't exist in WindowManager, don't render
|
37
44
|
if (!windowData) {
|
38
45
|
return null
|
@@ -123,14 +130,119 @@ export const Window = ({
|
|
123
130
|
updateWindowPosition(id, finalPosition)
|
124
131
|
}
|
125
132
|
|
126
|
-
//
|
133
|
+
// Handle resize start
|
134
|
+
const handleResizeStart = (e, direction) => {
|
135
|
+
if (!resizable || maximized) return
|
136
|
+
|
137
|
+
e.preventDefault()
|
138
|
+
e.stopPropagation()
|
139
|
+
|
140
|
+
setIsResizing(true)
|
141
|
+
setResizeDirection(direction)
|
142
|
+
setResizeStartSize(size)
|
143
|
+
setResizeStartPosition(position)
|
144
|
+
setResizeStartMouse({ x: e.clientX, y: e.clientY })
|
145
|
+
|
146
|
+
// Focus window
|
147
|
+
focusWindow(id)
|
148
|
+
}
|
149
|
+
|
150
|
+
// Handle resize move
|
151
|
+
const handleResizeMove = (e) => {
|
152
|
+
if (!isResizing) return
|
153
|
+
|
154
|
+
e.preventDefault()
|
155
|
+
|
156
|
+
const deltaX = e.clientX - resizeStartMouse.x
|
157
|
+
const deltaY = e.clientY - resizeStartMouse.y
|
158
|
+
|
159
|
+
let newSize = { ...resizeStartSize }
|
160
|
+
let newPosition = { ...resizeStartPosition }
|
161
|
+
|
162
|
+
// Calculate new size and position based on resize direction
|
163
|
+
switch (resizeDirection) {
|
164
|
+
case 'n': // North
|
165
|
+
newSize.height = Math.max(150, resizeStartSize.height - deltaY)
|
166
|
+
newPosition.y = resizeStartPosition.y + (resizeStartSize.height - newSize.height)
|
167
|
+
break
|
168
|
+
case 's': // South
|
169
|
+
newSize.height = Math.max(150, resizeStartSize.height + deltaY)
|
170
|
+
break
|
171
|
+
case 'e': // East
|
172
|
+
newSize.width = Math.max(200, resizeStartSize.width + deltaX)
|
173
|
+
break
|
174
|
+
case 'w': // West
|
175
|
+
newSize.width = Math.max(200, resizeStartSize.width - deltaX)
|
176
|
+
newPosition.x = resizeStartPosition.x + (resizeStartSize.width - newSize.width)
|
177
|
+
break
|
178
|
+
case 'ne': // Northeast
|
179
|
+
newSize.width = Math.max(200, resizeStartSize.width + deltaX)
|
180
|
+
newSize.height = Math.max(150, resizeStartSize.height - deltaY)
|
181
|
+
newPosition.y = resizeStartPosition.y + (resizeStartSize.height - newSize.height)
|
182
|
+
break
|
183
|
+
case 'nw': // Northwest
|
184
|
+
newSize.width = Math.max(200, resizeStartSize.width - deltaX)
|
185
|
+
newSize.height = Math.max(150, resizeStartSize.height - deltaY)
|
186
|
+
newPosition.x = resizeStartPosition.x + (resizeStartSize.width - newSize.width)
|
187
|
+
newPosition.y = resizeStartPosition.y + (resizeStartSize.height - newSize.height)
|
188
|
+
break
|
189
|
+
case 'se': // Southeast
|
190
|
+
newSize.width = Math.max(200, resizeStartSize.width + deltaX)
|
191
|
+
newSize.height = Math.max(150, resizeStartSize.height + deltaY)
|
192
|
+
break
|
193
|
+
case 'sw': // Southwest
|
194
|
+
newSize.width = Math.max(200, resizeStartSize.width - deltaX)
|
195
|
+
newSize.height = Math.max(150, resizeStartSize.height + deltaY)
|
196
|
+
newPosition.x = resizeStartPosition.x + (resizeStartSize.width - newSize.width)
|
197
|
+
break
|
198
|
+
}
|
199
|
+
|
200
|
+
// Apply changes visually
|
201
|
+
if (windowRef.current) {
|
202
|
+
windowRef.current.style.width = `${newSize.width}px`
|
203
|
+
windowRef.current.style.height = `${newSize.height}px`
|
204
|
+
windowRef.current.style.left = `${newPosition.x}px`
|
205
|
+
windowRef.current.style.top = `${newPosition.y}px`
|
206
|
+
}
|
207
|
+
}
|
208
|
+
|
209
|
+
// Handle resize end
|
210
|
+
const handleResizeEnd = () => {
|
211
|
+
if (!isResizing) return
|
212
|
+
|
213
|
+
setIsResizing(false)
|
214
|
+
setResizeDirection('')
|
215
|
+
|
216
|
+
// Get final size and position
|
217
|
+
const desktopContainer = windowRef.current?.parentElement
|
218
|
+
if (!desktopContainer) return
|
219
|
+
|
220
|
+
const windowRect = windowRef.current.getBoundingClientRect()
|
221
|
+
const desktopRect = desktopContainer.getBoundingClientRect()
|
222
|
+
|
223
|
+
const finalSize = {
|
224
|
+
width: windowRect.width,
|
225
|
+
height: windowRect.height
|
226
|
+
}
|
227
|
+
|
228
|
+
const finalPosition = {
|
229
|
+
x: windowRect.left - desktopRect.left,
|
230
|
+
y: windowRect.top - desktopRect.top
|
231
|
+
}
|
232
|
+
|
233
|
+
// Update WindowManager
|
234
|
+
updateWindowSize(id, finalSize)
|
235
|
+
updateWindowPosition(id, finalPosition)
|
236
|
+
}
|
237
|
+
|
238
|
+
// Setup drag and resize event listeners
|
127
239
|
useEffect(() => {
|
128
240
|
if (isDragging) {
|
129
241
|
document.addEventListener('mousemove', handleMouseMove)
|
130
242
|
document.addEventListener('mouseup', handleMouseUp)
|
131
243
|
document.body.style.userSelect = 'none'
|
132
244
|
document.body.style.cursor = 'move'
|
133
|
-
|
245
|
+
|
134
246
|
return () => {
|
135
247
|
document.removeEventListener('mousemove', handleMouseMove)
|
136
248
|
document.removeEventListener('mouseup', handleMouseUp)
|
@@ -140,6 +252,20 @@ export const Window = ({
|
|
140
252
|
}
|
141
253
|
}, [isDragging])
|
142
254
|
|
255
|
+
useEffect(() => {
|
256
|
+
if (isResizing) {
|
257
|
+
document.addEventListener('mousemove', handleResizeMove)
|
258
|
+
document.addEventListener('mouseup', handleResizeEnd)
|
259
|
+
document.body.style.userSelect = 'none'
|
260
|
+
|
261
|
+
return () => {
|
262
|
+
document.removeEventListener('mousemove', handleResizeMove)
|
263
|
+
document.removeEventListener('mouseup', handleResizeEnd)
|
264
|
+
document.body.style.userSelect = ''
|
265
|
+
}
|
266
|
+
}
|
267
|
+
}, [isResizing])
|
268
|
+
|
143
269
|
// Window control handlers
|
144
270
|
const handleMinimize = (e) => {
|
145
271
|
e.stopPropagation()
|
@@ -182,6 +308,7 @@ export const Window = ({
|
|
182
308
|
'window',
|
183
309
|
maximized && 'window--maximized',
|
184
310
|
isDragging && 'window--dragging',
|
311
|
+
isResizing && 'window--resizing',
|
185
312
|
className
|
186
313
|
].filter(Boolean).join(' ')
|
187
314
|
|
@@ -257,6 +384,47 @@ export const Window = ({
|
|
257
384
|
{statusBar}
|
258
385
|
</div>
|
259
386
|
)}
|
387
|
+
|
388
|
+
{/* Resize Handles */}
|
389
|
+
{resizable && !maximized && (
|
390
|
+
<>
|
391
|
+
{/* Edge handles */}
|
392
|
+
<div
|
393
|
+
className="window__resize-handle window__resize-handle--n"
|
394
|
+
onMouseDown={(e) => handleResizeStart(e, 'n')}
|
395
|
+
/>
|
396
|
+
<div
|
397
|
+
className="window__resize-handle window__resize-handle--s"
|
398
|
+
onMouseDown={(e) => handleResizeStart(e, 's')}
|
399
|
+
/>
|
400
|
+
<div
|
401
|
+
className="window__resize-handle window__resize-handle--e"
|
402
|
+
onMouseDown={(e) => handleResizeStart(e, 'e')}
|
403
|
+
/>
|
404
|
+
<div
|
405
|
+
className="window__resize-handle window__resize-handle--w"
|
406
|
+
onMouseDown={(e) => handleResizeStart(e, 'w')}
|
407
|
+
/>
|
408
|
+
|
409
|
+
{/* Corner handles */}
|
410
|
+
<div
|
411
|
+
className="window__resize-handle window__resize-handle--ne"
|
412
|
+
onMouseDown={(e) => handleResizeStart(e, 'ne')}
|
413
|
+
/>
|
414
|
+
<div
|
415
|
+
className="window__resize-handle window__resize-handle--nw"
|
416
|
+
onMouseDown={(e) => handleResizeStart(e, 'nw')}
|
417
|
+
/>
|
418
|
+
<div
|
419
|
+
className="window__resize-handle window__resize-handle--se"
|
420
|
+
onMouseDown={(e) => handleResizeStart(e, 'se')}
|
421
|
+
/>
|
422
|
+
<div
|
423
|
+
className="window__resize-handle window__resize-handle--sw"
|
424
|
+
onMouseDown={(e) => handleResizeStart(e, 'sw')}
|
425
|
+
/>
|
426
|
+
</>
|
427
|
+
)}
|
260
428
|
</div>
|
261
429
|
)
|
262
430
|
}
|
package/src/html/button.css
CHANGED
package/src/html/button.js
CHANGED
@@ -111,7 +111,8 @@ export const Button = (props) => {
|
|
111
111
|
icon: loading ? 'hourglass_empty' : icon,
|
112
112
|
size: size === 'small' ? 'small' : size === 'large' ? 'normal' : 'small',
|
113
113
|
disabled: disabled || loading,
|
114
|
-
className: loading ? 'loading-icon' : ''
|
114
|
+
className: loading ? 'loading-icon' : '',
|
115
|
+
eventPropagation: true, // Allow click events to bubble up to button
|
115
116
|
}
|
116
117
|
|
117
118
|
return (
|