working on toolbar section
This commit is contained in:
13
src/App.js
13
src/App.js
@@ -1,16 +1,17 @@
|
||||
import { useRef, useState } from 'react'
|
||||
|
||||
import { LayoutFilled, ProductFilled, CloudUploadOutlined } from "@ant-design/icons"
|
||||
import { DndContext, useSensors, useSensor, PointerSensor, closestCorners, DragOverlay, rectIntersection } from '@dnd-kit/core'
|
||||
import { snapCenterToCursor } from '@dnd-kit/modifiers'
|
||||
|
||||
import Sidebar from './sidebar/sidebar'
|
||||
import WidgetsContainer from './sidebar/widgetsContainer'
|
||||
import UploadsContainer from './sidebar/uploadsContainer'
|
||||
import Canvas from './canvas/canvas'
|
||||
import Header from './components/header'
|
||||
import { DndContext, useSensors, useSensor, PointerSensor, closestCorners, DragOverlay, rectIntersection } from '@dnd-kit/core'
|
||||
import { DraggableWidgetCard } from './components/cards'
|
||||
import Sidebar from './sidebar/sidebar'
|
||||
import UploadsContainer from './sidebar/uploadsContainer'
|
||||
import WidgetsContainer from './sidebar/widgetsContainer'
|
||||
|
||||
import Widget from './canvas/widgets/base'
|
||||
import { snapCenterToCursor } from '@dnd-kit/modifiers'
|
||||
import { DraggableWidgetCard } from './components/cards'
|
||||
|
||||
|
||||
function App() {
|
||||
|
||||
10
src/assets/background/dots.svg
Normal file
10
src/assets/background/dots.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg width="100%" height="100%">
|
||||
|
||||
<pattern id="pattern-circles" x="0" y="0" width="50" height="50" patternUnits="userSpaceOnUse" patternContentUnits="userSpaceOnUse">
|
||||
<circle id="pattern-circle" cx="10" cy="10" r="1.6257413380501518" fill="#000"></circle>
|
||||
</pattern>
|
||||
|
||||
<rect id="rect" x="0" y="0" width="100%" height="100%" fill="url(#pattern-circles)"></rect>
|
||||
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 387 B |
@@ -8,10 +8,17 @@ import { Button, Tooltip, Dropdown } from "antd"
|
||||
import Droppable from "../components/utils/droppable"
|
||||
import Widget from "./widgets/base"
|
||||
import Cursor from "./constants/cursor"
|
||||
import { UID } from "../utils/uid"
|
||||
import { removeDuplicateObjects } from "../utils/common"
|
||||
|
||||
import CanvasToolBar from "./toolbar"
|
||||
|
||||
import { UID } from "../utils/uid"
|
||||
import { removeDuplicateObjects } from "../utils/common"
|
||||
|
||||
// import {ReactComponent as DotsBackground} from "../assets/background/dots.svg"
|
||||
|
||||
import DotsBackground from "../assets/background/dots.svg"
|
||||
|
||||
// const DotsBackground = require("../assets/background/dots.svg")
|
||||
|
||||
const CanvasModes = {
|
||||
DEFAULT: 0,
|
||||
@@ -202,13 +209,10 @@ class Canvas extends React.Component {
|
||||
this.clearSelections()
|
||||
}
|
||||
|
||||
if (selectedWidget)
|
||||
|
||||
this.setState({
|
||||
selectedWidget: [selectedWidget]
|
||||
})
|
||||
if (selectedWidget){
|
||||
|
||||
this.setState({
|
||||
selectedWidget: [selectedWidget],
|
||||
contextMenuItems: [
|
||||
{
|
||||
key: "rename",
|
||||
@@ -223,6 +227,8 @@ class Canvas extends React.Component {
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -330,8 +336,13 @@ class Canvas extends React.Component {
|
||||
|
||||
setZoom(zoom, pos={x:0, y:0}){
|
||||
|
||||
// if (zoom < 0.5 || zoom > 2){
|
||||
// return
|
||||
// }
|
||||
|
||||
const { currentTranslate } = this.state
|
||||
|
||||
|
||||
// Calculate the new translation to zoom into the mouse position
|
||||
const offsetX = pos.x - (this.canvasContainerRef.current.clientWidth / 2 + currentTranslate.x)
|
||||
const offsetY = pos.y - (this.canvasContainerRef.current.clientHeight / 2 + currentTranslate.y)
|
||||
@@ -340,7 +351,7 @@ class Canvas extends React.Component {
|
||||
const newTranslateY = currentTranslate.y - offsetY * (zoom - this.state.zoom)
|
||||
|
||||
this.setState({
|
||||
zoom: zoom,
|
||||
zoom: Math.max(0.5, Math.min(zoom, 1.5)), // clamp between 0.5 and 1.5
|
||||
currentTranslate: {
|
||||
x: newTranslateX,
|
||||
y: newTranslateY
|
||||
@@ -440,17 +451,22 @@ class Canvas extends React.Component {
|
||||
const widgetIds = activeWidgets.map(widget => widget.__id)
|
||||
|
||||
for (let widgetId of widgetIds){
|
||||
console.log("removed: ", widgetId)
|
||||
|
||||
// this.widgetRefs[widgetId]?.current.remove()
|
||||
delete this.widgetRefs[widgetId]
|
||||
|
||||
this.setState((prevState) => ({
|
||||
widgets: prevState.widgets.filter(widget => widget.id !== widgetId)
|
||||
}))
|
||||
}), () => {
|
||||
|
||||
if (this._onWidgetListUpdated)
|
||||
this._onWidgetListUpdated(this.state.widgets)
|
||||
})
|
||||
// value.current?.remove()
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,19 +526,24 @@ class Canvas extends React.Component {
|
||||
<Button icon={<ReloadOutlined />} onClick={this.resetTransforms} />
|
||||
</Tooltip>
|
||||
<Tooltip title="Clear canvas">
|
||||
<Button icon={<CloseOutlined />} onClick={this.clearCanvas} />
|
||||
<Button danger icon={<DeleteOutlined />} onClick={this.clearCanvas} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<Droppable id="canvas-droppable" className="tw-w-full tw-h-full">
|
||||
<Dropdown trigger={['contextMenu']} mouseLeaveDelay={0} menu={{items: this.state.contextMenuItems, }}>
|
||||
<div className="tw-w-full tw-h-full tw-flex tw-relative tw-bg-black tw-overflow-hidden"
|
||||
<div className="dots-bg tw-w-full tw-h-full tw-flex tw-relative tw-bg-[#f2f2f2] tw-overflow-hidden"
|
||||
ref={this.canvasContainerRef}
|
||||
style={{transition: " transform 0.3s ease-in-out"}}
|
||||
style={{
|
||||
transition: " transform 0.3s ease-in-out",
|
||||
backgroundImage: `url('${DotsBackground}')`,
|
||||
backgroundSize: 'cover', // Ensure proper sizing if needed
|
||||
backgroundRepeat: 'no-repeat',
|
||||
}}
|
||||
>
|
||||
{/* Canvas */}
|
||||
<div data-canvas className="tw-w-full tw-h-full tw-absolute tw-top-0 tw-select-none
|
||||
t tw-bg-green-300"
|
||||
tw-bg-green-300"
|
||||
ref={this.canvasRef}>
|
||||
<div className="tw-relative tw-w-full tw-h-full">
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
const Tools = {
|
||||
INPUT: "input",
|
||||
NUMBER_INPUT: "number_input",
|
||||
SELECT_DROPDOWN: "select_dropdown",
|
||||
COLOR_PICKER: "color_picker",
|
||||
EVENT_HANDLER: "event_handler", // shows a event handler with all the possible function in the dropdown
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import { ColorPicker, Input } from "antd"
|
||||
import { ColorPicker, Input, InputNumber, Select } from "antd"
|
||||
|
||||
import { capitalize } from "../utils/common"
|
||||
import Tools from "./constants/tools.js"
|
||||
@@ -23,20 +23,106 @@ function CanvasToolBar({isOpen, activeWidget, setActiveWidget}){
|
||||
|
||||
|
||||
const handleWidgetNameChange = (e) => {
|
||||
activeWidget?.setWidgetName(e.target.value) // Update widget's internal state
|
||||
const updatedWidget = { ...activeWidget } // Create a shallow copy of the widget
|
||||
updatedWidget?.setWidgetName(e.target.value) // Update widget's internal state
|
||||
setActiveWidget(updatedWidget) // Update the state with the modified widget
|
||||
}
|
||||
|
||||
const handleChange = (attrPath, value, callback) => {
|
||||
// console.log("Value: ", attrPath, value)
|
||||
activeWidget?.setAttrValue(attrPath, value) // Update widget's internal state
|
||||
const updatedWidget = { ...activeWidget }
|
||||
|
||||
if (callback){
|
||||
callback(value)
|
||||
}
|
||||
|
||||
setActiveWidget(updatedWidget)
|
||||
}
|
||||
|
||||
|
||||
const renderWidgets = (obj, parentKey = "") => {
|
||||
return Object.entries(obj).map(([key, val], i) => {
|
||||
// console.log("parent key: ", parentKey)
|
||||
// Build a unique identifier for keys that handle nested structures
|
||||
const keyName = parentKey ? `${parentKey}.${key}` : key
|
||||
|
||||
// Check if the current value is an object and has a "tool" property
|
||||
if (typeof val === "object" && val.tool) {
|
||||
// Render widgets based on the tool type
|
||||
return (
|
||||
<div key={keyName} className="tw-flex tw-flex-col tw-gap-2">
|
||||
{
|
||||
parentKey ?
|
||||
<div className={`tw-text-sm tw-font-medium `}>{val.label}</div>
|
||||
:
|
||||
<div className="tw-text-lg tw-text-blue-700">{capitalize(key)}</div>
|
||||
}
|
||||
|
||||
{
|
||||
val.tool === Tools.NUMBER_INPUT && (
|
||||
<InputNumber
|
||||
defaultValue={val.value || 0}
|
||||
size="small"
|
||||
onChange={(value) => handleChange(keyName, value, val.onChange)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{
|
||||
val.tool === Tools.COLOR_PICKER && (
|
||||
<ColorPicker
|
||||
defaultValue={val.value || "#fff"}
|
||||
disabledAlpha
|
||||
arrow={false}
|
||||
size="middle"
|
||||
showText
|
||||
format="hex"
|
||||
placement="bottomRight"
|
||||
className="tw-w-fit !tw-min-w-[100px]"
|
||||
onChange={(value) => handleChange(keyName, value.toHexString(), val.onChange)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{
|
||||
val.tool === Tools.SELECT_DROPDOWN && (
|
||||
<Select
|
||||
options={val.options}
|
||||
showSearch
|
||||
value={val.value || ""}
|
||||
placeholder={`${val.label}`}
|
||||
onChange={(value) => handleChange(keyName, value, val.onChange)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
{/* Add more widget types here as needed */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// If the value is another nested object, recursively call renderWidgets
|
||||
if (typeof val === "object") {
|
||||
return (
|
||||
<div key={keyName} className="tw-flex tw-flex-col tw-gap-2">
|
||||
<div className="tw-text-lg tw-text-blue-700">{capitalize(key)}</div>
|
||||
{renderWidgets(val, keyName)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return null // Skip rendering for non-object types
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`tw-absolute tw-top-20 tw-right-5 tw-bg-white ${toolbarOpen ? "tw-w-[320px]": "tw-w-0"}
|
||||
tw-px-4 tw-p-2 tw-h-[600px] tw-rounded-md tw-z-20 tw-shadow-lg
|
||||
tw-transition-transform tw-duration-75
|
||||
tw-flex tw-flex-col
|
||||
tw-flex tw-flex-col tw-overflow-y-auto
|
||||
`}
|
||||
>
|
||||
|
||||
<h3 className="tw-text-2xl tw-text-center">
|
||||
<h3 className="tw-text-xl tw-text-center">
|
||||
{capitalize(`${activeWidget?.getWidgetType() || ""}`)}
|
||||
</h3>
|
||||
|
||||
@@ -48,25 +134,7 @@ function CanvasToolBar({isOpen, activeWidget, setActiveWidget}){
|
||||
</div>
|
||||
<hr />
|
||||
<div className="tw-flex tw-flex-col tw-gap-4">
|
||||
{
|
||||
Object.entries(activeWidget?.state?.attrs || {}).map(([key, value], i) => {
|
||||
console.log("valyes: ")
|
||||
return (
|
||||
<div className="tw-flex tw-flex-col tw-gap-1">
|
||||
<div className="tw-text-xl">{key}</div>
|
||||
{
|
||||
value?.backgroundColor?.tool === Tools.COLOR_PICKER &&
|
||||
<ColorPicker defaultValue={value?.backgroundColor?.value || "#fff"}
|
||||
disabledAlpha size="small" showText
|
||||
format="hex"
|
||||
placement="bottomRight"
|
||||
className="tw-w-fit"/>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
|
||||
})
|
||||
}
|
||||
{renderWidgets(activeWidget?.state?.attrs || {})}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -82,27 +82,53 @@ class Widget extends React.Component{
|
||||
resizing: false,
|
||||
resizeCorner: "",
|
||||
|
||||
pos: {x: 0, y: 0}, // used for outer styling
|
||||
size: {width: 100, height: 100}, // used for outer styling
|
||||
position: "absolute",
|
||||
|
||||
widgetStyling: {
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: 100,
|
||||
height: 100
|
||||
// use for widget's inner styling
|
||||
},
|
||||
|
||||
attrs: {
|
||||
styling: {
|
||||
backgroundColor: {
|
||||
label: "Background Color",
|
||||
tool: Tools.COLOR_PICKER, // the tool to display, can be either HTML ELement or a constant string
|
||||
value: "",
|
||||
onChange: (value) => this.setWidgetStyling("backgroundColor", value)
|
||||
},
|
||||
foregroundColor: {
|
||||
label: "Foreground Color",
|
||||
tool: Tools.COLOR_PICKER,
|
||||
value: ""
|
||||
value: "",
|
||||
},
|
||||
},
|
||||
layout: {
|
||||
label: "Layout",
|
||||
tool: Tools.SELECT_DROPDOWN, // the tool to display, can be either HTML ELement or a constant string
|
||||
value: "flex",
|
||||
options: [
|
||||
{value: "flex", label: "Flex"},
|
||||
{value: "grid", label: "Grid"},
|
||||
{value: "place", label: "Place"},
|
||||
],
|
||||
onChange: (value) => this.setWidgetStyling("backgroundColor", value)
|
||||
},
|
||||
size: {
|
||||
width: {
|
||||
label: "Width",
|
||||
tool: Tools.NUMBER_INPUT, // the tool to display, can be either HTML ELement or a constant string
|
||||
value: 100,
|
||||
// onChange: (value) => this.setS("backgroundColor", value)
|
||||
},
|
||||
height: {
|
||||
label: "Height",
|
||||
tool: Tools.NUMBER_INPUT, // the tool to display, can be either HTML ELement or a constant string
|
||||
value: 100,
|
||||
// onChange: (value) => this.setS("backgroundColor", value)
|
||||
},
|
||||
},
|
||||
layout: "show", // enables layout use "hide" to hide layout dropdown, takes the layout from this.layout
|
||||
events: {
|
||||
event1: {
|
||||
tool: Tools.EVENT_HANDLER,
|
||||
@@ -122,6 +148,7 @@ class Widget extends React.Component{
|
||||
|
||||
this.isSelected = this.isSelected.bind(this)
|
||||
this.setWidgetName = this.setWidgetName.bind(this)
|
||||
this.setAttrValue = this.setAttrValue.bind(this)
|
||||
|
||||
this.getPos = this.getPos.bind(this)
|
||||
this.setPos = this.setPos.bind(this)
|
||||
@@ -215,17 +242,19 @@ class Widget extends React.Component{
|
||||
// don't change position when resizing the widget
|
||||
return
|
||||
}
|
||||
this.setState({
|
||||
pos: {x, y}
|
||||
})
|
||||
|
||||
this.setState((prev) => ({
|
||||
// pos: {x: x, y: y}
|
||||
widgetStyling: {
|
||||
...prev.widgetStyling,
|
||||
left: x,
|
||||
top: y,
|
||||
}
|
||||
}))
|
||||
// this.setState((prev) => ({
|
||||
// // pos: {x: x, y: y}
|
||||
// widgetStyling: {
|
||||
// ...prev.widgetStyling,
|
||||
// left: x,
|
||||
// top: y,
|
||||
// }
|
||||
// }))
|
||||
|
||||
// console.log("POs: ", x, y)
|
||||
}
|
||||
|
||||
setParent(parentId){
|
||||
@@ -243,7 +272,7 @@ class Widget extends React.Component{
|
||||
}
|
||||
|
||||
getPos(){
|
||||
return {x: this.state.widgetStyling.left, y: this.state.widgetStyling.top}
|
||||
return this.state.pos
|
||||
}
|
||||
|
||||
getProps(){
|
||||
@@ -257,7 +286,7 @@ class Widget extends React.Component{
|
||||
getSize(){
|
||||
// const boundingRect = this.getBoundingRect()
|
||||
|
||||
return {width: this.state.widgetStyling.width, height: this.state.widgetStyling.height}
|
||||
return {width: this.state.size.width, height: this.state.size.height}
|
||||
}
|
||||
|
||||
getScaleAwareDimensions() {
|
||||
@@ -304,6 +333,31 @@ class Widget extends React.Component{
|
||||
return this.elementRef.current
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the key as a path, sets the value for the widget attribute
|
||||
* @param {string} path - path to the key, eg: styling.backgroundColor
|
||||
* @param {any} value
|
||||
*/
|
||||
setAttrValue(path, value){
|
||||
this.setState((prevState) => {
|
||||
// Split the path to access the nested property (e.g., "styling.backgroundColor")
|
||||
const keys = path.split('.')
|
||||
const lastKey = keys.pop()
|
||||
|
||||
// Traverse the state and update the nested value immutably
|
||||
let newAttrs = { ...prevState.attrs }
|
||||
let nestedObject = newAttrs
|
||||
|
||||
keys.forEach(key => {
|
||||
nestedObject[key] = { ...nestedObject[key] } // Ensure immutability
|
||||
nestedObject = nestedObject[key]
|
||||
})
|
||||
nestedObject[lastKey].value = value
|
||||
|
||||
return { attrs: newAttrs }
|
||||
})
|
||||
}
|
||||
|
||||
startResizing(corner, event) {
|
||||
event.stopPropagation()
|
||||
this.setState({ resizing: true, resizeCorner: corner })
|
||||
@@ -315,36 +369,54 @@ class Widget extends React.Component{
|
||||
})
|
||||
}
|
||||
|
||||
setWidgetName(name){
|
||||
|
||||
this.setState((prev) => ({
|
||||
widgetName: name.length > 0 ? name : prev.widgetName
|
||||
}))
|
||||
}
|
||||
|
||||
setWidgetStyling(key, value){
|
||||
|
||||
this.setState((prev) => ({
|
||||
widgetStyling: {
|
||||
...prev.widgetStyling,
|
||||
[key]: value
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
handleResize(event) {
|
||||
if (!this.state.resizing) return
|
||||
|
||||
const { resizeCorner, widgetStyling } = this.state
|
||||
const { resizeCorner, size, pos } = this.state
|
||||
const deltaX = event.movementX
|
||||
const deltaY = event.movementY
|
||||
|
||||
let newSize = { width: widgetStyling.width, height: widgetStyling.height }
|
||||
let newPos = { x: widgetStyling.left, y: widgetStyling.top }
|
||||
let newSize = { ...size }
|
||||
let newPos = { ...pos }
|
||||
|
||||
const {width: minWidth, height: minHeight} = this.minSize
|
||||
const {width: maxWidth, height: maxHeight} = this.maxSize
|
||||
console.log("resizing: ", deltaX, deltaY, event)
|
||||
// console.log("resizing: ", deltaX, deltaY, event)
|
||||
|
||||
switch (resizeCorner) {
|
||||
case "nw":
|
||||
newSize.width = Math.max(minWidth, Math.min(maxWidth, newSize.width - deltaX))
|
||||
newSize.height = Math.max(minHeight, Math.min(maxHeight, newSize.height - deltaY))
|
||||
newPos.x += (newSize.width !== widgetStyling.width) ? deltaX : 0
|
||||
newPos.y += (newSize.height !== widgetStyling.height) ? deltaY : 0
|
||||
newPos.x += (newSize.width !== size.width) ? deltaX : 0
|
||||
newPos.y += (newSize.height !== size.height) ? deltaY : 0
|
||||
break
|
||||
case "ne":
|
||||
newSize.width = Math.max(minWidth, Math.min(maxWidth, newSize.width + deltaX))
|
||||
newSize.height = Math.max(minHeight, Math.min(maxHeight, newSize.height - deltaY))
|
||||
newPos.y += (newSize.height !== widgetStyling.height) ? deltaY : 0
|
||||
newPos.y += (newSize.height !== size.height) ? deltaY : 0
|
||||
break
|
||||
case "sw":
|
||||
newSize.width = Math.max(minWidth, Math.min(maxWidth, newSize.width - deltaX))
|
||||
newSize.height = Math.max(minHeight, Math.min(maxHeight, newSize.height + deltaY))
|
||||
newPos.x += (newSize.width !== widgetStyling.width) ? deltaX : 0
|
||||
newPos.x += (newSize.width !== size.width) ? deltaX : 0
|
||||
break
|
||||
case "se":
|
||||
newSize.width = Math.max(minWidth, Math.min(maxWidth, newSize.width + deltaX))
|
||||
@@ -354,16 +426,7 @@ class Widget extends React.Component{
|
||||
break
|
||||
}
|
||||
|
||||
// this.setState({ size: newSize, pos: newPos })
|
||||
this.setState((prev) => ({
|
||||
widgetStyling: {
|
||||
...prev.widgetStyling,
|
||||
left: newPos.x,
|
||||
top: newPos.y,
|
||||
width: newSize.width,
|
||||
height: newSize.height,
|
||||
}
|
||||
}))
|
||||
this.setState({ size: newSize, pos: newPos })
|
||||
}
|
||||
|
||||
stopResizing() {
|
||||
@@ -385,28 +448,10 @@ class Widget extends React.Component{
|
||||
})
|
||||
}
|
||||
|
||||
setWidgetName(name){
|
||||
|
||||
this.setState((prev) => ({
|
||||
widgetName: name.length > 0 ? name : prev.widgetName
|
||||
}))
|
||||
}
|
||||
|
||||
setWidgetStyling(key, value){
|
||||
|
||||
this.setState((prev) => ({
|
||||
widgetStyling: {
|
||||
...prev.widgetStyling,
|
||||
[key]: value
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
renderContent(){
|
||||
// throw new NotImplementedError("render method has to be implemented")
|
||||
return (
|
||||
<div className="tw-w-full tw-h-full tw-bg-red-400">
|
||||
<div className="tw-w-full tw-h-full tw-rounded-md tw-bg-red-500" style={this.state.widgetStyling}>
|
||||
|
||||
</div>
|
||||
)
|
||||
@@ -421,15 +466,14 @@ class Widget extends React.Component{
|
||||
const widgetStyle = this.state.widgetStyling
|
||||
|
||||
|
||||
let style = {
|
||||
...widgetStyle,
|
||||
let outerStyle = {
|
||||
cursor: this.cursor,
|
||||
zIndex: this.state.zIndex,
|
||||
position: "absolute", // don't change this if it has to be movable on the canvas
|
||||
top: `${widgetStyle.top}px`,
|
||||
left: `${widgetStyle.left}px`,
|
||||
width: `${widgetStyle.width}px`,
|
||||
height: `${widgetStyle.height}px`,
|
||||
top: `${this.state.pos.y}px`,
|
||||
left: `${this.state.pos.x}px`,
|
||||
width: `${this.state.size.width}px`,
|
||||
height: `${this.state.size.height}px`,
|
||||
}
|
||||
|
||||
let selectionStyle = {
|
||||
@@ -442,8 +486,8 @@ class Widget extends React.Component{
|
||||
// console.log("selected: ", this.state.selected)
|
||||
return (
|
||||
|
||||
<div data-id={this.__id} ref={this.elementRef} className="tw-absolute tw-w-fit tw-h-fit"
|
||||
style={style}
|
||||
<div data-id={this.__id} ref={this.elementRef} className="tw-absolute tw-shadow-xl tw-w-fit tw-h-fit"
|
||||
style={outerStyle}
|
||||
>
|
||||
|
||||
{this.renderContent()}
|
||||
|
||||
@@ -11,6 +11,11 @@ body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.dots-bg{
|
||||
background-image: url("../assets/background/dots.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.input{
|
||||
border: 2px solid #e3e5e8;
|
||||
@@ -22,4 +27,4 @@ body {
|
||||
|
||||
.input:active, .input:focus, .input:focus-within{
|
||||
border-color: #60a5fa;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user