Merge branch 'add/widgets/theme' into 'main'

beautified the widget

See merge request vkuchenik/website-framework!22
This commit is contained in:
2025-07-23 21:31:54 +00:00
5 changed files with 77 additions and 53 deletions
@@ -5,14 +5,14 @@ export default function Widget({ title }) {
const styles = recipe(); const styles = recipe();
return ( return (
<chakra.div className="react-resizable-handle-se"> <>
<chakra.div css={styles.header} className="widget-handle" > <chakra.div css={styles.header} className="widget-handle" >
{title} {title}
</chakra.div> </chakra.div>
<chakra.div css={styles.canvas} > <chakra.div css={styles.canvas} >
This is the widget content - drag or resize me! This is their widget content - drag or resize me!
</chakra.div>
</chakra.div> </chakra.div>
</>
); );
} }
@@ -5,19 +5,19 @@
import { useState } from 'react'; import { useState } from 'react';
import GridLayout, { WidthProvider } from 'react-grid-layout'; import GridLayout, { WidthProvider } from 'react-grid-layout';
import Widget from '../Widget.jsx'; import Widget from '../Widget.jsx';
import { useSlotRecipe, chakra } from '@chakra-ui/react'; import { useSlotRecipe, chakra, Flex } from '@chakra-ui/react';
export default function WidgetCanvas() { export default function WidgetCanvas() {
// Define widgets initial position and size // Define widgets initial position and size
// TODO Add dynamic adding/deleting of widgets via options button // TODO Add dynamic adding/deleting of widgets via options button
const recipe = useSlotRecipe({ key: "widget" }); const recipe = useSlotRecipe({ key: "widget" });
const styles = recipe(); const styles = recipe(); // using root recipe for widget below
const ResponsiveGridLayout = WidthProvider(GridLayout); const ResponsiveGridLayout = WidthProvider(GridLayout); // canvas width now adjusts to window size
const [layout, setLayout] = useState([ const [layout, setLayout] = useState([
{ i: 'myWidget1', x: 0, y: 0, w: 3, h: 3, minH: 3, static: false }, { i: '0', x: 0, y: 0, w: 3, h: 3, minH: 3, minW: 1, static: false },
{ i: 'myWidget2', x: 3, y: 0, w: 3, h: 3, minH: 3, static: false }, { i: '1', x: 3, y: 0, w: 3, h: 3, minH: 3, minW: 1, static: false },
{ i: 'myWidget3', x: 6, y: 0, w: 3, h: 3, minH: 3, static: false } { i: '2', x: 6, y: 0, w: 3, h: 3, minH: 3, minW: 1, static: false }
]); ]);
const onLayoutChange = (newLayout) => { const onLayoutChange = (newLayout) => {
@@ -49,9 +49,10 @@ export default function WidgetCanvas() {
onDragStop={handleDragStop} onDragStop={handleDragStop}
> >
{layout.map((item) => ( {layout.map((item) => (
<chakra.div key={item.i} css={styles.root} > // this flex wrapper allows the widget to shrink down to the header size, no less
<Flex key={item.i} css={styles.root} height="100%" >
<Widget title="VDAP Widget" /> <Widget title="VDAP Widget" />
</chakra.div> </Flex>
))} ))}
</ResponsiveGridLayout> </ResponsiveGridLayout>
</chakra.div> </chakra.div>
+22 -6
View File
@@ -25,9 +25,27 @@ export default function Dashboard() {
} }
.react-resizable-handle-se { .react-resizable-handle-se {
position: sticky; position: absolute;
right: 0;
bottom: 0; bottom: 0;
z-index: 1;
border-radius: 5px;
}
* {
scrollbar-width: thin; /* Firefox */
scrollbar-color: #a0aec0 transparent; /* Firefox */
}
/* Chrome, Edge, Safari */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-thumb {
background-color: rgba(100, 100, 100, 0.4);
border-radius: 4px;
}
::-webkit-scrollbar-track {
background: transparent;
} }
`} `}
/> />
@@ -41,14 +59,12 @@ export default function Dashboard() {
<Header /> <Header />
</GridItem> </GridItem>
<GridItem colSpan={1}> <GridItem colSpan={1}>
<Sidebar onChangeView={ setView } /> <Sidebar />
</GridItem> </GridItem>
<GridItem colSpan={1} width="100%"> <GridItem colSpan={1} width="100%">
<Canvas view={ view }/> <Canvas />
</GridItem> </GridItem>
</Grid> </Grid>
</> </>
); );
} }
@@ -61,6 +61,7 @@ export default function Sidebar({ onChangeView }) {
const [isOpen, setIsOpen] = useState(true); const [isOpen, setIsOpen] = useState(true);
const [activeButton, setActiveButton] = useState(0) const [activeButton, setActiveButton] = useState(0)
// this list of btns will come from the db (not every usr will have access to admin)
const buttons = [ const buttons = [
{icon: PushPin, name: "Dashboard", view: "widget"}, {icon: PushPin, name: "Dashboard", view: "widget"},
{icon: Globe, name: "Global Map", view: "global"}, {icon: Globe, name: "Global Map", view: "global"},
+12 -6
View File
@@ -53,22 +53,30 @@ const widgetRecipe = defineSlotRecipe({
slots: ["root", "header", "canvas"], slots: ["root", "header", "canvas"],
base: { base: {
root: { root: {
flexDirection: "column",
gap: "1",
position: "relative",
bg: "base100", bg: "base100",
borderRadius: "md", borderRadius: "md",
p: "1", p: "1",
paddingBottom: "2",
border: "1px solid", border: "1px solid",
borderColor: "{base300}", borderColor: "{base300}",
textAlign: "center", textAlign: "center",
overflow: "auto" height: "100%"
}, },
header: { header: {
bg: "base100", bg: "base200",
cursor: "move", cursor: "move",
borderRadius: "md" borderRadius: "sm",
whiteSpace: "nowrap"
}, },
canvas: { canvas: {
flex: "1 1 auto",
bg: "base100", bg: "base100",
cursor: "default" cursor: "default",
borderRadius: "md",
overflow: "auto",
} }
} }
}); });
@@ -99,8 +107,6 @@ const config = defineConfig({
}, },
}, },
recipes: { recipes: {
// sidebar: sidebarRecipe,
// sidebarBTN: sidebarBtnRecipe,
header: headerRecipe, header: headerRecipe,
canvas: canvasRecipe, canvas: canvasRecipe,
}, },