{"record":{"id":"cbfcb34000fa64ea","repo":"shadcn-ui/ui","slug":"usedrawer-must-be-used-within-a-drawer-cbfcb3","errorCode":null,"errorMessage":"useDrawer must be used within a Drawer.","messagePattern":"useDrawer must be used within a Drawer\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/v4/registry/bases/base/ui/drawer.tsx","lineNumber":21,"sourceCode":"import * as React from \"react\"\nimport { Drawer as DrawerPrimitive } from \"@base-ui/react/drawer\"\n\nimport { cn } from \"@/registry/bases/base/lib/utils\"\n\ntype DrawerContextProps = {\n  hasSnapPoints: boolean\n  modal: DrawerPrimitive.Root.Props[\"modal\"]\n  showSwipeHandle: boolean\n  swipeDirection: NonNullable<DrawerPrimitive.Root.Props[\"swipeDirection\"]>\n}\n\nconst DrawerContext = React.createContext<DrawerContextProps | null>(null)\n\nfunction useDrawer() {\n  const context = React.useContext(DrawerContext)\n\n  if (!context) {\n    throw new Error(\"useDrawer must be used within a Drawer.\")\n  }\n\n  return context\n}\n\nfunction Drawer({\n  modal = true,\n  showSwipeHandle = false,\n  snapPoints,\n  swipeDirection = \"down\",\n  ...props\n}: DrawerPrimitive.Root.Props & {\n  showSwipeHandle?: boolean\n}) {\n  const hasSnapPoints = snapPoints != null && snapPoints.length > 0\n  const contextValue = React.useMemo(\n    () => ({ hasSnapPoints, modal, showSwipeHandle, swipeDirection }),\n    [hasSnapPoints, modal, showSwipeHandle, swipeDirection]","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/apps/v4/registry/bases/base/ui/drawer.tsx#L3-L39","documentation":"Identical contract to [153] but in the `base` style registry. `useDrawer` reads `DrawerContext`; drawer parts rendered outside `<Drawer>` throw so behavior props are never null.","triggerScenarios":"Mounting `<DrawerContent />` / `<DrawerTrigger />` outside `<Drawer>` when importing from the `base` style.","commonSituations":"Using the `base` style and splitting drawer markup; portal-detached content; tests of individual parts.","solutions":["Keep all Drawer sub-parts inside `<Drawer>` from the `base` style import path.","Ensure portals keep the React subtree under `<Drawer>`.","Decorate tests/stories with `<Drawer>`."],"exampleFix":"// before\n<DrawerTrigger>Open</DrawerTrigger>\n<Drawer>\n  <DrawerContent />\n</Drawer>\n\n// after\n<Drawer>\n  <DrawerTrigger>Open</DrawerTrigger>\n  <DrawerContent />\n</Drawer>","handlingStrategy":"type-guard","validationCode":"render(<Drawer><DrawerTrigger>Open</DrawerTrigger><DrawerContent>...</DrawerContent></Drawer>) // base style imports","typeGuard":"import React from \"react\"\nimport { DrawerContext } from \"@/registry/bases/base/ui/drawer\"\nconst insideDrawer = () => React.useContext(DrawerContext) != null","tryCatchPattern":"try { useDrawer() } catch (e) { if (e.message.includes(\"Drawer.\")) {/*nest inside Drawer*/} throw e }","preventionTips":["Mount base-style Drawer parts under <Drawer>.","Keep portal React subtrees under <Drawer>.","Add the base-style <Drawer> to story/test decorators."],"tags":["react","context","hooks","shadcn","drawer","base-style"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}