Refactor widget library UI code

This commit is contained in:
2026-08-20 12:51:58 -07:00
parent 2b0300b075
commit 9b1ddf6dcc
2 changed files with 94 additions and 77 deletions
@@ -28,9 +28,10 @@ export function SettingsButton() {
const recipe = useRecipe({key: "glassTab"});
const tabStyles = recipe();
// Pull the glass container styles for the dropdown
// Pull the glass container styles for the dropdown and modal
const panelRecipe = useSlotRecipe({key: "glassPanel"});
const panelStyles = panelRecipe({layout: "dropdown"});
const modalStyles = panelRecipe({layout: "popover"});
const [isLibraryOpen, setIsLibraryOpen] = useState(false);
@@ -123,88 +124,104 @@ export function SettingsButton() {
<Move size={16} style={{ marginRight: '8px' }} /> Edit Layout
</Menu.Item>
<Menu.Separator my={1} borderColor="glassSeperator" />
<Menu.Separator my={1} borderColor={{base: "gray.200", _dark: "whiteAlpha.200"}}/>
<Menu.Item
onClick={() => setIsLibraryOpen(true)}
cursor="pointer"
_hover={{ WebkitTextStroke: "0.5px currentColor" }}
<Menu.Item
onClick={() => setIsLibraryOpen(true)}
cursor="pointer"
_hover={{
bg: {base: "rgba(0, 0, 0, 0.05)", _dark: "rgba(255, 255, 255, 0.1)"},
WebkitTextStroke: "0.5px currentColor"
}}
>
<LayoutGrid size={16} style={{marginRight: '8px'}}/> Widget Library
</Menu.Item>
</Menu.Content>
</Menu.Positioner>
</Menu.Root>
)}
{/* THE WIDGET LIBRARY MODAL (Controlled by isLibraryOpen) */}
<Dialog.Root
open={isLibraryOpen}
onOpenChange={(e) => setIsLibraryOpen(e.open)}
size="xl"
placement="center"
closeOnInteractOutside={true}
closeOnEscapeKeyDown={true}
>
<LayoutGrid size={16} style={{ marginRight: '8px' }} /> Widget Library
</Menu.Item>
</Menu.Content>
</Menu.Positioner>
</Menu.Root>
)}
{/* Soft blur can be added to the background behind the modal */}
{/*<Dialog.Backdrop bg="blackAlpha.100" backdropFilter="blur(2px)"/>*/}
<Dialog.Positioner>
{/* THE WIDGET LIBRARY MODAL (Controlled by isLibraryOpen) */}
<Dialog.Root
open={isLibraryOpen}
onOpenChange={(e) => setIsLibraryOpen(e.open)}
size="xl"
placement="center"
closeOnInteractOutside={true}
closeOnEscapeKeyDown={true}
>
<Dialog.Backdrop bg="blackAlpha.600"/>
<Dialog.Positioner>
<Dialog.Content bg="gray.50" borderRadius="xl" overflow="hidden" boxShadow="xl" maxW="800px">
<Dialog.Header bg="gray.800" color="white" py={4}>
<Dialog.Title fontSize="xl" fontWeight="bold">Add Dashboard Widgets</Dialog.Title>
</Dialog.Header>
<Dialog.Content css={modalStyles.root} overflow="hidden" maxW="800px" minH="800px" p={0}>
<Dialog.Body p={0}>
<Tabs.Root defaultValue={categories[0]} variant="enclosed" colorScheme="blue">
<Tabs.List bg="white" px={4} pt={4} borderBottom="1px solid" borderColor="gray.200">
{categories.map(cat => (
<Tabs.Trigger key={cat} value={cat} pb={2}>{cat}</Tabs.Trigger>
))}
</Tabs.List>
<Dialog.Header bg="transparent" color={{base: "gray.800", _dark: "white"}} py={4}
borderColor={{base: "gray.200", _dark: "whiteAlpha.200"}}>
<Dialog.Title fontSize="xl" fontWeight="bold">Widgets Shop</Dialog.Title>
</Dialog.Header>
{categories.map(cat => (
<Tabs.Content key={cat} value={cat} p={6}>
<Grid templateColumns="repeat(auto-fill, minmax(300px, 1fr))" gap={4}>
{categorizedWidgets[cat].map(widget => (
<Flex key={widget.id} direction="column" bg="white" p={4} borderRadius="md" border="1px solid"
borderColor="gray.200" boxShadow="sm">
<Text fontWeight="bold" fontSize="md" mb={1}>{widget.name}</Text>
<Text fontSize="sm" color="gray.500" mb={4} flex="1">{widget.description}</Text>
<Dialog.Body p={0}>
<Tabs.Root defaultValue={categories[0]} variant="enclosed" colorScheme="blue">
<Tabs.List bg="transparent" px={4} pt={4}
borderColor={{base: "gray.200", _dark: "whiteAlpha.200"}}>
{categories.map(cat => (
<Tabs.Trigger key={cat} value={cat} pb={2}
_selected={{color: "blue.500", borderColor: "blue.500"}}>{cat}</Tabs.Trigger>
))}
</Tabs.List>
<Box borderTop="1px solid" borderColor="gray.100" pt={3}>
<Text fontSize="xs" fontWeight="bold" color="gray.400" textTransform="uppercase" mb={2}>Add
to Grid:</Text>
<HStack gap={2} flexWrap="wrap">
{Object.keys(widget.allowedSizes).map(sizeKey => (
<Badge
key={sizeKey}
as="button"
onClick={() => handleAddWidget(widget.id, sizeKey)}
colorScheme="gray"
variant="subtle"
px={3}
py={1}
borderRadius="full"
cursor="pointer"
_hover={{bg: "blue.50", color: "blue.600", transform: "scale(1.05)"}}
transition="all 0.2s"
{categories.map(cat => (
<Tabs.Content key={cat} value={cat} p={6}>
<Grid templateColumns="repeat(auto-fill, minmax(300px, 1fr))" gap={4}>
{categorizedWidgets[cat].map(widget => (
<Flex
key={widget.id}
direction="column"
bg={{base: "rgba(255, 255, 255, 0.6)", _dark: "rgba(0, 0, 0, 0.2)"}}
p={4}
borderRadius="xl"
border="1px solid"
borderColor={{base: "rgba(255, 255, 255, 0.9)", _dark: "whiteAlpha.200"}}
boxShadow="sm"
>
<Plus size={12} style={{display: 'inline', marginRight: '4px'}}/>
{sizeKey.charAt(0).toUpperCase() + sizeKey.slice(1)}
</Badge>
<Text fontWeight="bold" fontSize="md" mb={1}>{widget.name}</Text>
<Text fontSize="sm" color="gray.500" mb={4} flex="1">{widget.description}</Text>
<Box borderTop="1px solid" borderColor={{base: "gray.200", _dark: "whiteAlpha.200"}}
pt={3}>
<Text fontSize="xs" fontWeight="bold" color="gray.400" textTransform="uppercase"
mb={2}>
Add to Grid:
</Text>
<HStack gap={2} flexWrap="wrap">
{Object.keys(widget.allowedSizes).map(sizeKey => (
<Box
key={sizeKey}
as="button"
css={tabStyles}
onClick={() => handleAddWidget(widget.id, sizeKey)}
color={{base: "blue.600", _dark: "blue.300"}}
>
<Plus size={16} style={{flexShrink: 0}}/>
<Box as="span">{sizeKey.charAt(0).toUpperCase() + sizeKey.slice(1)}</Box>
</Box>
))}
</HStack>
</Box>
</Flex>
))}
</HStack>
</Box>
</Flex>
))}
</Grid>
</Tabs.Content>
))}
</Tabs.Root>
</Dialog.Body>
<Dialog.CloseTrigger position="absolute" top={3} right={3} color="white"/>
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
</Grid>
</Tabs.Content>
))}
</Tabs.Root>
</Dialog.Body>
<Dialog.CloseTrigger position="absolute" top={3} right={3}
color={{base: "gray.500", _dark: "whiteAlpha.800"}}
_hover={{color: "red.400"}}/>
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
</>
);
}
+2 -2
View File
@@ -220,8 +220,8 @@ const glassPanelRecipe = defineSlotRecipe({
bg: { base: "rgba(255, 255, 255, 0.75)", _dark: "rgba(20, 22, 25, 0.8)" },
// OVERRIDES: Increase the blur just to smooth out any stubborn gridlines
backdropFilter: "blur(20px)",
WebkitBackdropFilter: "blur(20px)",
backdropFilter: "blur(15px)",
WebkitBackdropFilter: "blur(15px)",
}
}
}