@devfellowship/components 3.5.0 → 3.5.1

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.cjs CHANGED
@@ -9179,9 +9179,9 @@ function RoadmapLegendView({ legend, testIdPrefix = "roadmap" }) {
9179
9179
 
9180
9180
  // src/components/organisms/roadmap/RoadmapNode.tsx
9181
9181
  var import_jsx_runtime66 = require("react/jsx-runtime");
9182
- var nodeVariants = (0, import_class_variance_authority14.cva)("relative flex min-w-0 flex-col justify-center rounded-[var(--radius)] border-2 px-2 py-3 text-center text-xs leading-normal md:px-4 md:text-base text-[var(--c-roadmap-node-fg)]", {
9182
+ var nodeVariants = (0, import_class_variance_authority14.cva)("relative flex min-w-0 flex-col justify-center rounded-[var(--radius)] border-2 px-1 py-3 text-center text-[length:var(--c-roadmap-font,12px)] leading-normal text-[var(--c-roadmap-node-fg)]", {
9183
9183
  variants: {
9184
- kind: { topic: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", subtopic: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", button: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", label: "border-transparent bg-transparent", title: "border-transparent bg-transparent font-semibold md:text-[28px]", paragraph: "text-left border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", legend: "border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]" },
9184
+ kind: { topic: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", subtopic: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", button: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", label: "border-transparent bg-transparent", title: "border-transparent bg-transparent font-semibold text-[length:var(--c-roadmap-title-font,18px)]", paragraph: "text-left border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", legend: "border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]" },
9185
9185
  state: { todo: "", done: "[--c-roadmap-node-bg:var(--c-roadmap-done-bg)] [--c-roadmap-node-fg:var(--c-roadmap-done-fg)]", learning: "[--c-roadmap-node-bg:var(--c-roadmap-learning-bg)] [--c-roadmap-node-fg:var(--c-roadmap-learning-fg)]", skipped: "[--c-roadmap-node-bg:var(--c-roadmap-skipped-bg)] [--c-roadmap-node-fg:var(--c-roadmap-skipped-fg)]", locked: "opacity-60" }
9186
9186
  }
9187
9187
  });
@@ -9194,7 +9194,7 @@ function RoadmapNodeView({ node, state, badge, testIdPrefix, onNodeClick, onActi
9194
9194
  const Box = wholeBox && node.href ? "a" : wholeBox && onNodeClick ? "button" : "div";
9195
9195
  const primary = Box !== "div" ? label : node.href && !locked ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("a", { href: node.href, className: interactiveClass, onClick: () => onNodeClick?.(node), children: label }) : onNodeClick && !locked ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("button", { type: "button", className: interactiveClass, onClick: () => onNodeClick(node), children: label }) : label;
9196
9196
  const icon = node.icon ?? (badge ? { name: badge.icon ?? "check", side: "right", tone: badge.tone } : void 0);
9197
- return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { style: toneStyle(nodeTone), className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(Box, { style: { borderColor: node.kind === "title" || node.kind === "label" ? "transparent" : "var(--c-roadmap-border)" }, "data-roadmap-node-box": node.id, href: Box === "a" ? node.href : void 0, type: Box === "button" ? "button" : void 0, onClick: Box !== "div" ? () => onNodeClick?.(node) : void 0, className: `${nodeVariants({ kind: node.kind, state })} w-full ${Box !== "div" ? focusClass : ""}`, "aria-disabled": locked || void 0, title: node.kind === "topic" || node.kind === "subtopic" ? node.description : void 0, children: [
9197
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { style: toneStyle(nodeTone), className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(Box, { style: { borderColor: node.kind === "title" || node.kind === "label" ? "transparent" : "var(--c-roadmap-border)" }, "data-roadmap-node-box": node.id, href: Box === "a" ? node.href : void 0, type: Box === "button" ? "button" : void 0, onClick: Box !== "div" ? () => onNodeClick?.(node) : void 0, className: `${nodeVariants({ kind: node.kind, state })} w-full ${icon ? icon.side === "left" ? "pl-3" : "pr-3" : ""} ${Box !== "div" ? focusClass : ""}`, "aria-disabled": locked || void 0, title: node.kind === "topic" || node.kind === "subtopic" ? node.description : void 0, children: [
9198
9198
  icon && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(RoadmapBadge, { name: icon.name, tone: icon.tone ?? nodeTone, label: badge?.label ?? icon.name, className: `absolute top-1/2 -translate-y-1/2 ${icon.side === "left" ? "left-0 -translate-x-1/2" : "right-0 translate-x-1/2"}` }),
9199
9199
  primary,
9200
9200
  node.description && node.kind === "paragraph" && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("p", { className: "mt-2 [overflow-wrap:anywhere]", children: node.description }),
@@ -9259,7 +9259,7 @@ function Edge({ edge, path, instance, prefix }) {
9259
9259
  strokeLinecap: "round",
9260
9260
  strokeLinejoin: "round",
9261
9261
  strokeDasharray: style === "solid" ? void 0 : style === "dotted" ? "0.8 4" : "0.8 8",
9262
- className: "[stroke-width:2px] md:[stroke-width:3px]",
9262
+ className: "[stroke-width:var(--c-roadmap-edge-width,2px)]",
9263
9263
  markerStart: arrow === "both" ? `url(#${marker})` : void 0,
9264
9264
  markerEnd: arrow !== "none" ? `url(#${marker})` : void 0
9265
9265
  }
@@ -9336,20 +9336,26 @@ function RoadmapEdgeLayer({ containerRef, document: documentModel, testIdPrefix,
9336
9336
  fonts?.removeEventListener("loadingdone", schedule);
9337
9337
  };
9338
9338
  }, [containerRef, documentModel, debugPerf]);
9339
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("svg", { "data-testid": `${testIdPrefix}-edges`, "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-[1] h-full w-full overflow-visible", children: measured.map((item) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Edge, { ...item, instance, prefix: testIdPrefix }, item.edge.id)) });
9339
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("svg", { "data-testid": `${testIdPrefix}-edges`, "aria-hidden": "true", className: "pointer-events-none print:hidden absolute inset-0 z-[1] h-full w-full overflow-visible", children: measured.map((item) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Edge, { ...item, instance, prefix: testIdPrefix }, item.edge.id)) });
9340
9340
  }
9341
9341
 
9342
9342
  // src/components/organisms/roadmap/Roadmap.tsx
9343
9343
  var import_jsx_runtime69 = require("react/jsx-runtime");
9344
- function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction, testIdPrefix = "roadmap", className = "", ariaLabel, debugPerf }) {
9344
+ function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction, testIdPrefix = "roadmap", className = "", ariaLabel, debugPerf, collapseEmptyColumns = true }) {
9345
9345
  const gridRef = (0, import_react8.useRef)(null);
9346
9346
  const { placements } = (0, import_react8.useMemo)(() => placeNodes(document2), [document2]);
9347
+ const used = (0, import_react8.useMemo)(() => columnsUsed({ nodes: document2.nodes.filter((node) => !((node.span ?? 1) === 3 && (node.kind === "title" || node.kind === "label"))) }), [document2]);
9348
+ const weights = ["left", "center", "right"].map((column, index) => !collapseEmptyColumns || used.length === 0 || used.includes(column) ? index === 1 ? 1.25 : 1 : 0);
9349
+ const gridStyle = {
9350
+ gridTemplateColumns: weights.map((weight) => `minmax(0, ${weight}fr)`).join(" "),
9351
+ ...weights.filter(Boolean).length === 1 ? { columnGap: 0 } : {}
9352
+ };
9347
9353
  const badges = (0, import_react8.useMemo)(() => new Map(document2.legend?.entries.map((entry) => [entry.id, entry])), [document2.legend]);
9348
9354
  const legendPlacement = document2.legend ? resolveLegendPlacement(document2.legend) : void 0;
9349
9355
  const legend = document2.legend && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(RoadmapLegendView, { legend: document2.legend, testIdPrefix });
9350
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("section", { "data-testid": testIdPrefix, "aria-label": ariaLabel ?? document2.title ?? "Roadmap", className: `min-w-0 bg-[var(--c-roadmap-surface)] p-3 text-[var(--c-roadmap-neutral-fg)] ${className}`, children: [
9356
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("section", { "data-testid": testIdPrefix, "aria-label": ariaLabel ?? document2.title ?? "Roadmap", style: { containerType: "inline-size", containerName: "roadmap" }, className: `mx-auto w-full max-w-[1120px] min-w-0 bg-[var(--c-roadmap-surface)] text-[var(--c-roadmap-neutral-fg)] ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "dfl-roadmap-body min-w-0 p-[var(--c-roadmap-padding)]", children: [
9351
9357
  legendPlacement === "top" && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "mb-6", children: legend }),
9352
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { ref: gridRef, "data-roadmap-grid": "", "data-testid": `${testIdPrefix}-grid`, role: "list", "aria-label": "Roadmap nodes", className: "relative isolate grid min-w-0 grid-cols-3 items-center gap-x-3 gap-y-2 md:gap-x-8", children: [
9358
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { ref: gridRef, "data-roadmap-grid": "", "data-testid": `${testIdPrefix}-grid`, role: "list", "aria-label": "Roadmap nodes", style: gridStyle, className: "relative isolate grid min-w-0 grid-cols-3 items-center gap-x-[var(--c-roadmap-column-gap)] gap-y-2", children: [
9353
9359
  /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(RoadmapEdgeLayer, { containerRef: gridRef, document: document2, testIdPrefix, debugPerf }),
9354
9360
  document2.groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(RoadmapGroupView, { group, testIdPrefix }, group.id)),
9355
9361
  placements.map(({ node, row, column }) => {
@@ -9363,7 +9369,7 @@ function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction
9363
9369
  "data-roadmap-node": node.id,
9364
9370
  "data-state": resolvedState,
9365
9371
  style: { gridColumn: `${column.start} / span ${column.span}`, gridRow: `${row.start} / span 1` },
9366
- className: "relative z-10 min-w-0 px-2 py-2",
9372
+ className: `relative z-10 min-w-0 py-2 ${node.icon || node.badge ? node.icon?.side === "left" ? "pl-3 pr-1" : "pl-1 pr-3" : "px-1"}`,
9367
9373
  children: node.kind === "legend" ? legendPlacement === "inline" ? legend : null : renderNode ? renderNode(node, resolvedState) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(RoadmapNodeView, { node, state: resolvedState, badge: node.badge ? badges.get(node.badge) : void 0, onNodeClick, onAction, testIdPrefix })
9368
9374
  },
9369
9375
  node.id
@@ -9371,7 +9377,7 @@ function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction
9371
9377
  })
9372
9378
  ] }),
9373
9379
  legendPlacement === "bottom" && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "mt-6", children: legend })
9374
- ] });
9380
+ ] }) });
9375
9381
  }
9376
9382
 
9377
9383
  // src/hooks/use-iframe-auth.ts
package/dist/index.d.cts CHANGED
@@ -3269,11 +3269,13 @@ interface RoadmapProps {
3269
3269
  onNodeClick?: (node: RoadmapNode) => void;
3270
3270
  onAction?: (actionId: string, node: RoadmapNode) => void;
3271
3271
  debugPerf?: boolean;
3272
+ /** Collapse unused lanes; full-width headings do not reserve empty side tracks. */
3273
+ collapseEmptyColumns?: boolean;
3272
3274
  testIdPrefix?: string;
3273
3275
  className?: string;
3274
3276
  ariaLabel?: string;
3275
3277
  }
3276
3278
  /** Dark-only, ordinary document scroll. The JSON owns placement; CSS owns the pixels. */
3277
- declare function Roadmap({ document, state, renderNode, onNodeClick, onAction, testIdPrefix, className, ariaLabel, debugPerf }: RoadmapProps): React__default.JSX.Element;
3279
+ declare function Roadmap({ document, state, renderNode, onNodeClick, onAction, testIdPrefix, className, ariaLabel, debugPerf, collapseEmptyColumns }: RoadmapProps): React__default.JSX.Element;
3278
3280
 
3279
3281
  export { ALLOWED_ORIGINS, AVATAR_MEMBER_PALETTE_SIZE, Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, type AlertDialogActionProps, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppNavbar, type AppNavbarProps, AppSidebar, type AppSidebarProps, AspectRatio, Avatar, AvatarFallback, AvatarGroup, AvatarImage, type AvatarSize, AvatarStatus, type AvatarStatusValue, type AvatarTone, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, type BreadcrumbEntry, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, CarouselDots, CarouselItem, CarouselNext, CarouselPrevious, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent, CollapsibleHeader, CollapsibleItem, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DEFAULT_EDGE_ARROW, DEFAULT_EDGE_ROUTE, DEFAULT_EDGE_STYLE, DEFAULT_GROUP_TONE, DEFAULT_LEGEND_PLACEMENT, DEFAULT_NAME_COL_WIDTH, DEFAULT_NODE_SPAN, DEFAULT_NODE_STATE, type DflIframeMessage, type DflNavigateMessage, type DflReadyMessage, DflRemote, type DflRemoteProps, type DflResizeMessage, type DflSetTokenMessage, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Gantt, type GanttDependency, type GanttMilestone, type GanttProps, type GanttStage, HoverCard, HoverCardContent, HoverCardTrigger, IconButton, type IconButtonProps, IframeAware, type IframeAwareProps, IframeContext, type IframeContextValue, type IframeMessageType, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Kbd, type KbdProps, Label, LoginPage, type LoginPageProps, LoginScreen, type LoginScreenProps, MEMBER_PALETTE_SIZE, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NODE_KIND_DEFAULT_TONE, type NavGroup, type NavItem, type NavbarUserInfo, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, type OTPStatus, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PasswordInput, type PasswordInputProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, type ProgressProps, ProtectedRoute, type ProtectedRouteProps, PublishDrawer, type PublishDrawerProps, type PublishDrawerSupabase, type PublishResult, type PublishStatus, type PublisherAccount, ROADMAP_ARROWS, ROADMAP_COLUMNS, ROADMAP_EDGE_LABEL_MAX, ROADMAP_EDGE_ROUTES, ROADMAP_EDGE_STYLES, ROADMAP_LABEL_MAX, ROADMAP_LEGEND_PLACEMENTS, ROADMAP_NODE_ID_PATTERN, ROADMAP_NODE_KINDS, ROADMAP_NODE_STATES, ROADMAP_TONES, RadioGroup, RadioGroupItem, RadioGroupRow, ResizableHandle, ResizablePanel, ResizablePanelGroup, Roadmap, type RoadmapAction, type RoadmapArrow, type RoadmapColumn, type RoadmapDocument, type RoadmapEdge, type RoadmapEdgeRoute, type RoadmapEdgeStyle, type RoadmapGroup, type RoadmapGroupRange, type RoadmapIcon, type RoadmapLegend, type RoadmapLegendEntry, type RoadmapLegendPlacement, type RoadmapLink, type RoadmapNode, type RoadmapNodeKind, type RoadmapNodeState, type RoadmapOverlap, type RoadmapPlacement, type RoadmapProps, type RoadmapStateOverlay, type RoadmapTone, ScrollArea, type ScrollAreaScrollbars, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SeparatorWithLabel, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, SonnerToaster, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, Toast, ToastAction, type ToastActionElement, ToastClose, type ToastComponentProps, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserAvatar, type UserAvatarProps, type UserInfo, UserMenu, type UserMenuItem, type UserMenuProps, avatarMemberColor, badgeVariants, barGridColumn, buttonVariants, clampPct, columnIndex, columnsCovered, columnsUsed, filterPublishableAccounts, firstFreeRow, getInitials, gridColumnFor, groupColumnRuns, groupRanges, iconButtonVariants, isAllowedOrigin, kbdVariants, labelVariants, maxRowOf, memberHueIndex, memberHueVar, navigationMenuTriggerStyle, nodesByRow, parseRoadmapDocument, parseRoadmapStateOverlay, parseTags, placeNodes, resolveEdgeArrow, resolveEdgeRoute, resolveEdgeStyle, resolveGroupColumns, resolveGroupTone, resolveLegendPlacement, resolveNameColWidth, resolveNodeSpan, resolveNodeState, resolveNodeTone, resolveWeekCount, resolveWeekLabels, roadmapActionSchema, roadmapDocumentSchema, roadmapEdgeSchema, roadmapGroupSchema, roadmapIconSchema, roadmapLegendEntrySchema, roadmapLegendSchema, roadmapLinkSchema, roadmapNodeSchema, roadmapNodeStateSchema, roadmapStateOverlaySchema, roadmapStateSchema, rowsOf, safeParseRoadmapDocument, safeParseRoadmapStateOverlay, stageProgress, toggleVariants, useFormField, useSidebar, validateNoOverlap, validatePublishForm };
package/dist/index.d.ts CHANGED
@@ -3269,11 +3269,13 @@ interface RoadmapProps {
3269
3269
  onNodeClick?: (node: RoadmapNode) => void;
3270
3270
  onAction?: (actionId: string, node: RoadmapNode) => void;
3271
3271
  debugPerf?: boolean;
3272
+ /** Collapse unused lanes; full-width headings do not reserve empty side tracks. */
3273
+ collapseEmptyColumns?: boolean;
3272
3274
  testIdPrefix?: string;
3273
3275
  className?: string;
3274
3276
  ariaLabel?: string;
3275
3277
  }
3276
3278
  /** Dark-only, ordinary document scroll. The JSON owns placement; CSS owns the pixels. */
3277
- declare function Roadmap({ document, state, renderNode, onNodeClick, onAction, testIdPrefix, className, ariaLabel, debugPerf }: RoadmapProps): React__default.JSX.Element;
3279
+ declare function Roadmap({ document, state, renderNode, onNodeClick, onAction, testIdPrefix, className, ariaLabel, debugPerf, collapseEmptyColumns }: RoadmapProps): React__default.JSX.Element;
3278
3280
 
3279
3281
  export { ALLOWED_ORIGINS, AVATAR_MEMBER_PALETTE_SIZE, Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, type AlertDialogActionProps, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppNavbar, type AppNavbarProps, AppSidebar, type AppSidebarProps, AspectRatio, Avatar, AvatarFallback, AvatarGroup, AvatarImage, type AvatarSize, AvatarStatus, type AvatarStatusValue, type AvatarTone, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, type BreadcrumbEntry, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, CarouselDots, CarouselItem, CarouselNext, CarouselPrevious, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent, CollapsibleHeader, CollapsibleItem, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DEFAULT_EDGE_ARROW, DEFAULT_EDGE_ROUTE, DEFAULT_EDGE_STYLE, DEFAULT_GROUP_TONE, DEFAULT_LEGEND_PLACEMENT, DEFAULT_NAME_COL_WIDTH, DEFAULT_NODE_SPAN, DEFAULT_NODE_STATE, type DflIframeMessage, type DflNavigateMessage, type DflReadyMessage, DflRemote, type DflRemoteProps, type DflResizeMessage, type DflSetTokenMessage, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Gantt, type GanttDependency, type GanttMilestone, type GanttProps, type GanttStage, HoverCard, HoverCardContent, HoverCardTrigger, IconButton, type IconButtonProps, IframeAware, type IframeAwareProps, IframeContext, type IframeContextValue, type IframeMessageType, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Kbd, type KbdProps, Label, LoginPage, type LoginPageProps, LoginScreen, type LoginScreenProps, MEMBER_PALETTE_SIZE, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NODE_KIND_DEFAULT_TONE, type NavGroup, type NavItem, type NavbarUserInfo, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, type OTPStatus, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PasswordInput, type PasswordInputProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, type ProgressProps, ProtectedRoute, type ProtectedRouteProps, PublishDrawer, type PublishDrawerProps, type PublishDrawerSupabase, type PublishResult, type PublishStatus, type PublisherAccount, ROADMAP_ARROWS, ROADMAP_COLUMNS, ROADMAP_EDGE_LABEL_MAX, ROADMAP_EDGE_ROUTES, ROADMAP_EDGE_STYLES, ROADMAP_LABEL_MAX, ROADMAP_LEGEND_PLACEMENTS, ROADMAP_NODE_ID_PATTERN, ROADMAP_NODE_KINDS, ROADMAP_NODE_STATES, ROADMAP_TONES, RadioGroup, RadioGroupItem, RadioGroupRow, ResizableHandle, ResizablePanel, ResizablePanelGroup, Roadmap, type RoadmapAction, type RoadmapArrow, type RoadmapColumn, type RoadmapDocument, type RoadmapEdge, type RoadmapEdgeRoute, type RoadmapEdgeStyle, type RoadmapGroup, type RoadmapGroupRange, type RoadmapIcon, type RoadmapLegend, type RoadmapLegendEntry, type RoadmapLegendPlacement, type RoadmapLink, type RoadmapNode, type RoadmapNodeKind, type RoadmapNodeState, type RoadmapOverlap, type RoadmapPlacement, type RoadmapProps, type RoadmapStateOverlay, type RoadmapTone, ScrollArea, type ScrollAreaScrollbars, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SeparatorWithLabel, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, SonnerToaster, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, Toast, ToastAction, type ToastActionElement, ToastClose, type ToastComponentProps, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserAvatar, type UserAvatarProps, type UserInfo, UserMenu, type UserMenuItem, type UserMenuProps, avatarMemberColor, badgeVariants, barGridColumn, buttonVariants, clampPct, columnIndex, columnsCovered, columnsUsed, filterPublishableAccounts, firstFreeRow, getInitials, gridColumnFor, groupColumnRuns, groupRanges, iconButtonVariants, isAllowedOrigin, kbdVariants, labelVariants, maxRowOf, memberHueIndex, memberHueVar, navigationMenuTriggerStyle, nodesByRow, parseRoadmapDocument, parseRoadmapStateOverlay, parseTags, placeNodes, resolveEdgeArrow, resolveEdgeRoute, resolveEdgeStyle, resolveGroupColumns, resolveGroupTone, resolveLegendPlacement, resolveNameColWidth, resolveNodeSpan, resolveNodeState, resolveNodeTone, resolveWeekCount, resolveWeekLabels, roadmapActionSchema, roadmapDocumentSchema, roadmapEdgeSchema, roadmapGroupSchema, roadmapIconSchema, roadmapLegendEntrySchema, roadmapLegendSchema, roadmapLinkSchema, roadmapNodeSchema, roadmapNodeStateSchema, roadmapStateOverlaySchema, roadmapStateSchema, rowsOf, safeParseRoadmapDocument, safeParseRoadmapStateOverlay, stageProgress, toggleVariants, useFormField, useSidebar, validateNoOverlap, validatePublishForm };
package/dist/index.js CHANGED
@@ -8790,9 +8790,9 @@ function RoadmapLegendView({ legend, testIdPrefix = "roadmap" }) {
8790
8790
 
8791
8791
  // src/components/organisms/roadmap/RoadmapNode.tsx
8792
8792
  import { jsx as jsx66, jsxs as jsxs41 } from "react/jsx-runtime";
8793
- var nodeVariants = cva14("relative flex min-w-0 flex-col justify-center rounded-[var(--radius)] border-2 px-2 py-3 text-center text-xs leading-normal md:px-4 md:text-base text-[var(--c-roadmap-node-fg)]", {
8793
+ var nodeVariants = cva14("relative flex min-w-0 flex-col justify-center rounded-[var(--radius)] border-2 px-1 py-3 text-center text-[length:var(--c-roadmap-font,12px)] leading-normal text-[var(--c-roadmap-node-fg)]", {
8794
8794
  variants: {
8795
- kind: { topic: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", subtopic: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", button: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", label: "border-transparent bg-transparent", title: "border-transparent bg-transparent font-semibold md:text-[28px]", paragraph: "text-left border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", legend: "border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]" },
8795
+ kind: { topic: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", subtopic: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", button: "min-h-[49px] border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", label: "border-transparent bg-transparent", title: "border-transparent bg-transparent font-semibold text-[length:var(--c-roadmap-title-font,18px)]", paragraph: "text-left border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]", legend: "border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)]" },
8796
8796
  state: { todo: "", done: "[--c-roadmap-node-bg:var(--c-roadmap-done-bg)] [--c-roadmap-node-fg:var(--c-roadmap-done-fg)]", learning: "[--c-roadmap-node-bg:var(--c-roadmap-learning-bg)] [--c-roadmap-node-fg:var(--c-roadmap-learning-fg)]", skipped: "[--c-roadmap-node-bg:var(--c-roadmap-skipped-bg)] [--c-roadmap-node-fg:var(--c-roadmap-skipped-fg)]", locked: "opacity-60" }
8797
8797
  }
8798
8798
  });
@@ -8805,7 +8805,7 @@ function RoadmapNodeView({ node, state, badge, testIdPrefix, onNodeClick, onActi
8805
8805
  const Box = wholeBox && node.href ? "a" : wholeBox && onNodeClick ? "button" : "div";
8806
8806
  const primary = Box !== "div" ? label : node.href && !locked ? /* @__PURE__ */ jsx66("a", { href: node.href, className: interactiveClass, onClick: () => onNodeClick?.(node), children: label }) : onNodeClick && !locked ? /* @__PURE__ */ jsx66("button", { type: "button", className: interactiveClass, onClick: () => onNodeClick(node), children: label }) : label;
8807
8807
  const icon = node.icon ?? (badge ? { name: badge.icon ?? "check", side: "right", tone: badge.tone } : void 0);
8808
- return /* @__PURE__ */ jsx66("div", { style: toneStyle(nodeTone), className: "min-w-0", children: /* @__PURE__ */ jsxs41(Box, { style: { borderColor: node.kind === "title" || node.kind === "label" ? "transparent" : "var(--c-roadmap-border)" }, "data-roadmap-node-box": node.id, href: Box === "a" ? node.href : void 0, type: Box === "button" ? "button" : void 0, onClick: Box !== "div" ? () => onNodeClick?.(node) : void 0, className: `${nodeVariants({ kind: node.kind, state })} w-full ${Box !== "div" ? focusClass : ""}`, "aria-disabled": locked || void 0, title: node.kind === "topic" || node.kind === "subtopic" ? node.description : void 0, children: [
8808
+ return /* @__PURE__ */ jsx66("div", { style: toneStyle(nodeTone), className: "min-w-0", children: /* @__PURE__ */ jsxs41(Box, { style: { borderColor: node.kind === "title" || node.kind === "label" ? "transparent" : "var(--c-roadmap-border)" }, "data-roadmap-node-box": node.id, href: Box === "a" ? node.href : void 0, type: Box === "button" ? "button" : void 0, onClick: Box !== "div" ? () => onNodeClick?.(node) : void 0, className: `${nodeVariants({ kind: node.kind, state })} w-full ${icon ? icon.side === "left" ? "pl-3" : "pr-3" : ""} ${Box !== "div" ? focusClass : ""}`, "aria-disabled": locked || void 0, title: node.kind === "topic" || node.kind === "subtopic" ? node.description : void 0, children: [
8809
8809
  icon && /* @__PURE__ */ jsx66(RoadmapBadge, { name: icon.name, tone: icon.tone ?? nodeTone, label: badge?.label ?? icon.name, className: `absolute top-1/2 -translate-y-1/2 ${icon.side === "left" ? "left-0 -translate-x-1/2" : "right-0 translate-x-1/2"}` }),
8810
8810
  primary,
8811
8811
  node.description && node.kind === "paragraph" && /* @__PURE__ */ jsx66("p", { className: "mt-2 [overflow-wrap:anywhere]", children: node.description }),
@@ -8870,7 +8870,7 @@ function Edge({ edge, path, instance, prefix }) {
8870
8870
  strokeLinecap: "round",
8871
8871
  strokeLinejoin: "round",
8872
8872
  strokeDasharray: style === "solid" ? void 0 : style === "dotted" ? "0.8 4" : "0.8 8",
8873
- className: "[stroke-width:2px] md:[stroke-width:3px]",
8873
+ className: "[stroke-width:var(--c-roadmap-edge-width,2px)]",
8874
8874
  markerStart: arrow === "both" ? `url(#${marker})` : void 0,
8875
8875
  markerEnd: arrow !== "none" ? `url(#${marker})` : void 0
8876
8876
  }
@@ -8947,20 +8947,26 @@ function RoadmapEdgeLayer({ containerRef, document: documentModel, testIdPrefix,
8947
8947
  fonts?.removeEventListener("loadingdone", schedule);
8948
8948
  };
8949
8949
  }, [containerRef, documentModel, debugPerf]);
8950
- return /* @__PURE__ */ jsx68("svg", { "data-testid": `${testIdPrefix}-edges`, "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-[1] h-full w-full overflow-visible", children: measured.map((item) => /* @__PURE__ */ jsx68(Edge, { ...item, instance, prefix: testIdPrefix }, item.edge.id)) });
8950
+ return /* @__PURE__ */ jsx68("svg", { "data-testid": `${testIdPrefix}-edges`, "aria-hidden": "true", className: "pointer-events-none print:hidden absolute inset-0 z-[1] h-full w-full overflow-visible", children: measured.map((item) => /* @__PURE__ */ jsx68(Edge, { ...item, instance, prefix: testIdPrefix }, item.edge.id)) });
8951
8951
  }
8952
8952
 
8953
8953
  // src/components/organisms/roadmap/Roadmap.tsx
8954
8954
  import { jsx as jsx69, jsxs as jsxs44 } from "react/jsx-runtime";
8955
- function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction, testIdPrefix = "roadmap", className = "", ariaLabel, debugPerf }) {
8955
+ function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction, testIdPrefix = "roadmap", className = "", ariaLabel, debugPerf, collapseEmptyColumns = true }) {
8956
8956
  const gridRef = useRef6(null);
8957
8957
  const { placements } = useMemo5(() => placeNodes(document2), [document2]);
8958
+ const used = useMemo5(() => columnsUsed({ nodes: document2.nodes.filter((node) => !((node.span ?? 1) === 3 && (node.kind === "title" || node.kind === "label"))) }), [document2]);
8959
+ const weights = ["left", "center", "right"].map((column, index) => !collapseEmptyColumns || used.length === 0 || used.includes(column) ? index === 1 ? 1.25 : 1 : 0);
8960
+ const gridStyle = {
8961
+ gridTemplateColumns: weights.map((weight) => `minmax(0, ${weight}fr)`).join(" "),
8962
+ ...weights.filter(Boolean).length === 1 ? { columnGap: 0 } : {}
8963
+ };
8958
8964
  const badges = useMemo5(() => new Map(document2.legend?.entries.map((entry) => [entry.id, entry])), [document2.legend]);
8959
8965
  const legendPlacement = document2.legend ? resolveLegendPlacement(document2.legend) : void 0;
8960
8966
  const legend = document2.legend && /* @__PURE__ */ jsx69(RoadmapLegendView, { legend: document2.legend, testIdPrefix });
8961
- return /* @__PURE__ */ jsxs44("section", { "data-testid": testIdPrefix, "aria-label": ariaLabel ?? document2.title ?? "Roadmap", className: `min-w-0 bg-[var(--c-roadmap-surface)] p-3 text-[var(--c-roadmap-neutral-fg)] ${className}`, children: [
8967
+ return /* @__PURE__ */ jsx69("section", { "data-testid": testIdPrefix, "aria-label": ariaLabel ?? document2.title ?? "Roadmap", style: { containerType: "inline-size", containerName: "roadmap" }, className: `mx-auto w-full max-w-[1120px] min-w-0 bg-[var(--c-roadmap-surface)] text-[var(--c-roadmap-neutral-fg)] ${className}`, children: /* @__PURE__ */ jsxs44("div", { className: "dfl-roadmap-body min-w-0 p-[var(--c-roadmap-padding)]", children: [
8962
8968
  legendPlacement === "top" && /* @__PURE__ */ jsx69("div", { className: "mb-6", children: legend }),
8963
- /* @__PURE__ */ jsxs44("div", { ref: gridRef, "data-roadmap-grid": "", "data-testid": `${testIdPrefix}-grid`, role: "list", "aria-label": "Roadmap nodes", className: "relative isolate grid min-w-0 grid-cols-3 items-center gap-x-3 gap-y-2 md:gap-x-8", children: [
8969
+ /* @__PURE__ */ jsxs44("div", { ref: gridRef, "data-roadmap-grid": "", "data-testid": `${testIdPrefix}-grid`, role: "list", "aria-label": "Roadmap nodes", style: gridStyle, className: "relative isolate grid min-w-0 grid-cols-3 items-center gap-x-[var(--c-roadmap-column-gap)] gap-y-2", children: [
8964
8970
  /* @__PURE__ */ jsx69(RoadmapEdgeLayer, { containerRef: gridRef, document: document2, testIdPrefix, debugPerf }),
8965
8971
  document2.groups.map((group) => /* @__PURE__ */ jsx69(RoadmapGroupView, { group, testIdPrefix }, group.id)),
8966
8972
  placements.map(({ node, row, column }) => {
@@ -8974,7 +8980,7 @@ function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction
8974
8980
  "data-roadmap-node": node.id,
8975
8981
  "data-state": resolvedState,
8976
8982
  style: { gridColumn: `${column.start} / span ${column.span}`, gridRow: `${row.start} / span 1` },
8977
- className: "relative z-10 min-w-0 px-2 py-2",
8983
+ className: `relative z-10 min-w-0 py-2 ${node.icon || node.badge ? node.icon?.side === "left" ? "pl-3 pr-1" : "pl-1 pr-3" : "px-1"}`,
8978
8984
  children: node.kind === "legend" ? legendPlacement === "inline" ? legend : null : renderNode ? renderNode(node, resolvedState) : /* @__PURE__ */ jsx69(RoadmapNodeView, { node, state: resolvedState, badge: node.badge ? badges.get(node.badge) : void 0, onNodeClick, onAction, testIdPrefix })
8979
8985
  },
8980
8986
  node.id
@@ -8982,7 +8988,7 @@ function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction
8982
8988
  })
8983
8989
  ] }),
8984
8990
  legendPlacement === "bottom" && /* @__PURE__ */ jsx69("div", { className: "mt-6", children: legend })
8985
- ] });
8991
+ ] }) });
8986
8992
  }
8987
8993
 
8988
8994
  // src/hooks/use-iframe-auth.ts
@@ -56,3 +56,32 @@ body {
56
56
  .dark {
57
57
  /* All tokens already render dark at :root. Intentionally empty. */
58
58
  }
59
+
60
+ /* Roadmap sizes follow container width, including narrow embedded panels.
61
+ * Plain CSS supports Tailwind 3 and 4. Row spacing remains compact:
62
+ * 8px gap + two 8px node insets = 24px between node borders. */
63
+ .dfl-roadmap-body {
64
+ --c-roadmap-edge-width: 2px;
65
+ --c-roadmap-font: 12px;
66
+ --c-roadmap-title-font: 18px;
67
+ --c-roadmap-column-gap: 8px;
68
+ --c-roadmap-padding: 8px;
69
+ }
70
+ @container roadmap (min-width: 360px) {
71
+ .dfl-roadmap-body { --c-roadmap-padding: 12px; }
72
+ }
73
+ @container roadmap (min-width: 390px) {
74
+ .dfl-roadmap-body { --c-roadmap-font: 13px; --c-roadmap-title-font: 20px; --c-roadmap-column-gap: 12px; }
75
+ }
76
+ @container roadmap (min-width: 768px) {
77
+ .dfl-roadmap-body { --c-roadmap-edge-width: 3px; --c-roadmap-font: 15px; --c-roadmap-title-font: 22px; --c-roadmap-column-gap: 24px; --c-roadmap-padding: 16px; }
78
+ }
79
+ @container roadmap (min-width: 1024px) {
80
+ .dfl-roadmap-body { --c-roadmap-font: 17px; --c-roadmap-title-font: 24px; --c-roadmap-column-gap: 32px; --c-roadmap-padding: 24px; }
81
+ }
82
+ /* The map stops at 1120px; the outer viewport selects the wide rhythm. */
83
+ @media (min-width: 1280px) {
84
+ @container roadmap (min-width: 1120px) {
85
+ .dfl-roadmap-body { --c-roadmap-title-font: 28px; --c-roadmap-column-gap: 48px; }
86
+ }
87
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devfellowship/components",
3
- "version": "3.5.0",
3
+ "version": "3.5.1",
4
4
  "description": "DFL Design System — UI components, hooks, utils and providers",
5
5
  "type": "module",
6
6
  "sideEffects": [