beautified the widget

the widgets now don't shrink past the size of the header. The canvas in the widget is scrollable and the scroller is pretty. The resizing arrow button at the bottom of the widget stays at the bottom (this is because only the canvas can scroll now).
This commit is contained in:
2025-07-23 13:44:24 -07:00
parent 7c29b2a14c
commit 1f1eced159
5 changed files with 45 additions and 19 deletions
+20 -2
View File
@@ -21,9 +21,27 @@ function App() {
}
.react-resizable-handle-se {
position: sticky;
right: 0;
position: absolute;
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;
}
`}
/>
@@ -5,14 +5,14 @@ export default function Widget({ title }) {
const styles = recipe();
return (
<chakra.div className="react-resizable-handle-se">
<>
<chakra.div css={styles.header} className="widget-handle" >
{title}
</chakra.div>
<chakra.div css={styles.canvas} >
This is the widget content - drag or resize me!
</chakra.div>
This is their widget content - drag or resize me!
</chakra.div>
</>
);
}
@@ -5,19 +5,19 @@
import { useState } from 'react';
import GridLayout, { WidthProvider } from 'react-grid-layout';
import Widget from '../Widget.jsx';
import { useSlotRecipe, chakra } from '@chakra-ui/react';
import { useSlotRecipe, chakra, Flex } from '@chakra-ui/react';
export default function WidgetCanvas() {
// Define widgets initial position and size
// TODO Add dynamic adding/deleting of widgets via options button
const recipe = useSlotRecipe({ key: "widget" });
const styles = recipe();
const ResponsiveGridLayout = WidthProvider(GridLayout);
const styles = recipe(); // using root recipe for widget below
const ResponsiveGridLayout = WidthProvider(GridLayout); // canvas width now adjusts to window size
const [layout, setLayout] = useState([
{ i: 'myWidget1', x: 0, y: 0, w: 3, h: 3, minH: 3, static: false },
{ i: 'myWidget2', x: 3, y: 0, w: 3, h: 3, minH: 3, static: false },
{ i: 'myWidget3', x: 6, 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: '1', x: 3, y: 0, w: 3, h: 3, minH: 3, minW: 1, static: false },
{ i: '2', x: 6, y: 0, w: 3, h: 3, minH: 3, minW: 1, static: false }
]);
const onLayoutChange = (newLayout) => {
@@ -49,9 +49,10 @@ export default function WidgetCanvas() {
onDragStop={handleDragStop}
>
{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" />
</chakra.div>
</Flex>
))}
</ResponsiveGridLayout>
</chakra.div>
@@ -60,6 +60,7 @@ export const Users = createIcon({
export default function Sidebar() {
const [isOpen, setIsOpen] = useState(true);
// this list of btns will come from the db (not every usr will have access to admin)
const buttons = [
{icon: PushPin, name: "Dashboard"},
{icon: Globe, name: "Global Map"},
+12 -6
View File
@@ -53,22 +53,30 @@ const widgetRecipe = defineSlotRecipe({
slots: ["root", "header", "canvas"],
base: {
root: {
flexDirection: "column",
gap: "1",
position: "relative",
bg: "base100",
borderRadius: "md",
p: "1",
paddingBottom: "2",
border: "1px solid",
borderColor: "{base300}",
textAlign: "center",
overflow: "auto"
height: "100%"
},
header: {
bg: "base100",
bg: "base200",
cursor: "move",
borderRadius: "md"
borderRadius: "sm",
whiteSpace: "nowrap"
},
canvas: {
flex: "1 1 auto",
bg: "base100",
cursor: "default"
cursor: "default",
borderRadius: "md",
overflow: "auto",
}
}
});
@@ -99,8 +107,6 @@ const config = defineConfig({
},
},
recipes: {
// sidebar: sidebarRecipe,
// sidebarBTN: sidebarBtnRecipe,
header: headerRecipe,
canvas: canvasRecipe,
},