1"use strict";(globalThis.webpackChunkmy_website=globalThis.webpackChunkmy_website||[]).push([[9949],{96183(e,t,o){o.r(t),o.d(t,{assets:()=>X,contentTitle:()=>W,default:()=>$,frontMatter:()=>U,metadata:()=>r,toc:()=>Z});const r=JSON.parse('{"id":"components/radio-group","title":"Radio Group","description":"A set of checkable buttons\u2014known as radio buttons\u2014where no more than one of the buttons can be checked at a time.","source":"@site/docs/components/radio-group.mdx","sourceDirName":"components","slug":"/components/radio-group","permalink":"/docs/components/radio-group","draft":false,"unlisted":false,"editUrl":"https://github.com/stacks-network/stacks-design-system/tree/main/docs/components/radio-group.mdx","tags":[],"version":"current","sidebarPosition":17,"frontMatter":{"sidebar_position":17,"title":"Radio Group","description":"A set of checkable buttons\u2014known as radio buttons\u2014where no more than one of the buttons can be checked at a time."},"sidebar":"docsSidebar","previous":{"title":"Popover","permalink":"/docs/components/popover"},"next":{"title":"Select","permalink":"/docs/components/select"}}');var n=o(74848),i=o(28453),s=o(96540),a=o(32338),d=o(91071),l=o(62133),c=o(20078),u=o(76278),p=o(81351),h=o(71427),f=o(31769),m=o(85357),b=o(7971),x="Radio",[v,j]=(0,l.A)(x),[g,w]=v(x),R=s.forwardRef((e,t)=>{const{__scopeRadio:o,name:r,checked:i=!1,required:l,disabled:u,value:p="on",onCheck:h,form:f,...m}=e,[b,x]=s.useState(null),v=(0,d.s)(t,e=>x(e)),j=s.useRef(!1),w=!b||(f||!!b.closest("form"));return(0,n.jsxs)(g,{scope:o,checked:i,disabled:u,children:[(0,n.jsx)(c.sG.button,{type:"button",role:"radio","aria-checked":i,"data-state":A(i),"data-disabled":u?"":void 0,disabled:u,value:p,...m,ref:v,onClick:(0,a.mK)(e.onClick,e=>{i||h?.(),w&&(j.current=e.isPropagationStopped(),j.current||e.stopPropagation())})}),w&&(0,n.jsx)(N,{control:b,bubbles:!j.current,name:r,value:p,checked:i,required:l,disabled:u,form:f,style:{transform:"translateX(-100%)"}})]})});R.displayName=x;var y="RadioIndicator",k=s.forwardRef((e,t)=>{const{__scopeRadio:o,forceMount:r,...i}=e,s=w(y,o);return(0,n.jsx)(b.C,{present:r||s.checked,children:(0,n.jsx)(c.sG.span,{"data-state":A(s.checked),"data-disabled":s.disabled?"":void 0,...i,ref:t})})});k.displayName=y;var N=s.forwardRef(({__scopeRadio:e,control:t,checked:o,bubbles:r=!0,...i},a)=>{const l=s.useRef(null),u=(0,d.s)(l,a),p=(0,m.Z)(o),h=(0,f.X)(t);return s.useEffect(()=>{const e=l.current;if(!e)return;const t=window.HTMLInputElement.prototype,n=Object.getOwnPropertyDescriptor(t,"checked").set;if(p!==o&&n){const t=new Event("click",{bubbles:r});n.call(e,o),e.dispatchEvent(t)}},[p,o,r]),(0,n.jsx)(c.sG.input,{type:"radio","aria-hidden":!0,defaultChecked:o,...i,tabIndex:-1,ref:u,style:{...i.style,...h,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});function A(e){return e?"checked":"unchecked"}N.displayName="RadioBubbleInput";var G=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"],F="RadioGroup",[I,S]=(0,l.A)(F,[u.RG,j]),C=(0,u.RG)(),E=j(),[T,_]=I(F),D=s.forwardRef((e,t)=>{const{__scopeRadioGroup:o,name:r,defaultValue:i,value:s,required:a=!1,disabled:d=!1,orientation:l,dir:f,loop:m=!0,onValueChange:b,...x}=e,v=C(o),j=(0,h.jH)(f),[g,w]=(0,p.i)({prop:s,defaultProp:i??null,onChange:b,caller:F});return(0,n.jsx)(T,{scope:o,name:r,required:a,disabled:d,value:g,onValueChange:w,children:(0,n.jsx)(u.bL,{asChild:!0,...v,orientation:l,dir:j,loop:m,children:(0,n.jsx)(c.sG.div,{role:"radiogroup","aria-required":a,"aria-orientation":l,"data-disabled":d?"":void 0,dir:j,...x,ref:t})})})});D.displayName=F;var L="RadioGroupItem",K=s.forwardRef((e,t)=>{const{__scopeRadioGroup:o,disabled:r,...i}=e,l=_(L,o),c=l.disabled||r,p=C(o),h=E(o),f=s.useRef(null),m=(0,d.s)(t,f),b=l.value===i.value,x=s.useRef(!1);return s.useEffect(()=>{const e=e=>{G.includes(e.key)&&(x.current=!0)},t=()=>x.current=!1;return document.addEventListener("keydown",e),document.addEventListener("keyup",t),()=>{document.removeEventListener("keydown",e),document.removeEventListener("keyup",t)}},[]),(0,n.jsx)(u.q7,{asChild:!0,...p,focusable:!c,active:b,children:(0,n.jsx)(R,{disabled:c,required:l.required,
1checked:b,...h,...i,name:l.name,ref:m,onCheck:()=>l.onValueChange(i.value),onKeyDown:(0,a.mK)(e=>{"Enter"===e.key&&e.preventDefault()}),onFocus:(0,a.mK)(i.onFocus,()=>{x.current&&f.current?.click()})})})});K.displayName=L;var P=s.forwardRef((e,t)=>{const{__scopeRadioGroup:o,...r}=e,i=E(o);return(0,n.jsx)(k,{...i,...r,ref:t})});P.displayName="RadioGroupIndicator";var q=D,M=K,V=P,B=o(68100);const z=s.forwardRef(({className:e,...t},o)=>(0,n.jsx)(q,{className:(0,B.cn)("grid gap-3",e),...t,ref:o}));z.displayName=q.displayName;const H=s.forwardRef(({className:e,...t},o)=>(0,n.jsx)(M,{ref:o,className:(0,B.cn)("stacks-radio-item aspect-square h-[18px] w-[18px] rounded-full text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",e),...t,children:(0,n.jsx)(V,{className:"flex items-center justify-center",children:(0,n.jsx)("div",{className:"h-2.5 w-2.5 rounded-full bg-primary"})})}));H.displayName=M.displayName;var O=o(20196);const U={sidebar_position:17,title:"Radio Group",description:"A set of checkable buttons\u2014known as radio buttons\u2014where no more than one of the buttons can be checked at a time."},W="Radio Group",X={},Z=[{value:"Disabled",id:"disabled",level:2},{value:"API Reference",id:"api-reference",level:2},{value:"Accessibility",id:"accessibility",level:2}];function J(e){const t={code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"radio-group",children:"Radio Group"})}),"\n",(0,n.jsx)(t.p,{children:"A set of checkable buttons\u2014known as radio buttons\u2014where no more than one of the buttons can be checked at a time."}),"\n",(0,n.jsx)(O.e,{children:(0,n.jsxs)(z,{defaultValue:"option-2",children:[(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsx)(H,{value:"option-1",id:"option-1"}),(0,n.jsx)("label",{htmlFor:"option-1",className:"text-sm font-medium text-foreground cursor-pointer",children:"Label"})]}),(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsx)(H,{value:"option-2",id:"option-2"}),(0,n.jsx)("label",{htmlFor:"option-2",className:"text-sm font-medium text-foreground cursor-pointer",children:"Label"})]}),(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsx)(H,{value:"option-3",id:"option-3"}),(0,n.jsx)("label",{htmlFor:"option-3",className:"text-sm font-medium text-foreground cursor-pointer",children:"Label"})]})]})}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-tsx",children:'import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"\n\n<RadioGroup defaultValue="option-2">\n <div className="flex items-center gap-3">\n <RadioGroupItem value="option-1" id="option-1" />\n <label htmlFor="option-1">Label</label>\n </div>\n <div className="flex items-center gap-3">\n <RadioGroupItem value="option-2" id="option-2" />\n <label htmlFor="option-2">Label</label>\n </div>\n <div className="flex items-center gap-3">\n <RadioGroupItem value="option-3" id="option-3" />\n <label htmlFor="option-3">Label</label>\n </div>\n</RadioGroup>\n'})}),"\n",(0,n.jsx)(t.h2,{id:"disabled",children:"Disabled"}),"\n",(0,n.jsx)(t.p,{children:"Radio items can be individually disabled to prevent interaction."}),"\n",(0,n.jsx)(O.e,{children:(0,n.jsxs)(z,{defaultValue:"option-1",children:[(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsx)(H,{value:"option-1",id:"disabled-1"}),(0,n.jsx)("label",{htmlFor:"disabled-1",className:"text-sm font-medium text-foreground cursor-pointer",children:"Available"})]}),(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsx)(H,{value:"option-2",id:"disabled-2",disabled:!0}),(0,n.jsx)("label",{htmlFor:"disabled-2",className:"text-sm font-medium text-muted-foreground cursor-not-allowed",children:"Disabled"})]}),(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsx)(H,{value:"option-3",id:"disabled-3"}),(0,n.jsx)("label",{htmlFor:"disabled-3",className:"text-sm font-medium text-foreground cursor-pointer",children:"Available"})]})]})}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-tsx",children:'<RadioGroup defaultValue="option-1">\n <div className="flex items-center gap-3">\n <RadioGroupItem value="option-1" id="disabled-1" />\n <label htmlFor="disabled-1">Available</label>\n </div>\n <div className="flex items-center gap-3">\n <RadioGroupItem value="option-2" id="disabled-2" disabled />\n <label htmlFor="disabled-2">Disabled</label>\n </div>\n <div className="flex items-center gap-3">\n <RadioGroupItem value="option-3" id="disabled-3" />\n <label htmlFor="disabled-3">Available</label>\n </div>\n</RadioGroup>\n'})}),"\n",(0,n.jsx)(t.h2,{id:"api-reference",children:"API Reference"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Prop"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"Default"}),(0,n.jsx)(t.th,{children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"defaultValue"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"string"})}),(0,n.jsx)(t.td,{children:"\u2014"}),(0,n.jsx)(t.td,{children:"The value of the radio item that should be checked by default"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"value"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"string"})}),(0,n.jsx)(t.td,{children:"\u2014"}),(0,n.jsx)(t.td,{children:"The controlled value of the radio item to check"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"onValueChange"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"(value: string) => void"})}),(0,n.jsx)(t.td,{children:"\u2014"}),(0,n.jsx)(t.td,{children:"Callback when the value changes"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"disabled"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"boolean"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{children:"When true, prevents the user from interacting with radio items"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"orientation"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:'"horizontal" | "vertical"'})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:'"vertical"'})}),(0,n.jsx)(t.td,{children:"The orientation of the radio group"})]})]})]}),"\n",(0,n.jsx)(t.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,n.jsx)(t.p,{children:"The Radio Group component follows WAI-ARIA radio group patterns:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Uses ",(0,n.jsx)(t.code,{children:'role="radiogroup"'})," on the container"]}),"\n",(0,n.jsxs)(t.li,{children:["Each radio button uses ",(0,n.jsx)(t.code,{children:'role="radio"'})," with proper ",(0,n.jsx)(t.code,{children:"aria-checked"})," state"]}),"\n",(0,n.jsx)(t.li,{children:"Supports keyboard navigation (Arrow keys to move between items, Space to select)"}),"\n",(0,n.jsx)(t.li,{children:"Focus management follows roving tabindex pattern"}),"\n",(0,n.jsxs)(t.li,{children:["Labels are associated via ",(0,n.jsx)(t.code,{children:"htmlFor"})," / ",(0,n.jsx)(t.code,{children:"id"})," pairing"]}),"\n"]})]})}function $(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(J,{...e})}):J(e)}},71427(e,t,o){o.d(t,{jH:()=>i});var r=o(96540),n=(o(74848),r.createContext(void 0));function i(e){const t=r.useContext(n);return e||t||"ltr"}},18723(e,t,o){var r;o.d(t,{B:()=>d});var n=o(96540),i=o(88200),s=(r||(r=o.t(n,2)))[" useId ".trim().toString()]||(()=>{}),a=0;
1function d(e){const[t,o]=n.useState(s());return(0,i.N)(()=>{e||o(e=>e??String(a++))},[e]),e||(t?`radix-${t}`:"")}},76278(e,t,o){o.d(t,{RG:()=>w,bL:()=>S,q7:()=>C});var r=o(96540),n=o(32338),i=o(88657),s=o(91071),a=o(62133),d=o(18723),l=o(20078),c=o(10263),u=o(81351),p=o(71427),h=o(74848),f="rovingFocusGroup.onEntryFocus",m={bubbles:!1,cancelable:!0},b="RovingFocusGroup",[x,v,j]=(0,i.N)(b),[g,w]=(0,a.A)(b,[j]),[R,y]=g(b),k=r.forwardRef((e,t)=>(0,h.jsx)(x.Provider,{scope:e.__scopeRovingFocusGroup,children:(0,h.jsx)(x.Slot,{scope:e.__scopeRovingFocusGroup,children:(0,h.jsx)(N,{...e,ref:t})})}));k.displayName=b;var N=r.forwardRef((e,t)=>{const{__scopeRovingFocusGroup:o,orientation:i,loop:a=!1,dir:d,currentTabStopId:x,defaultCurrentTabStopId:j,onCurrentTabStopIdChange:g,onEntryFocus:w,preventScrollOnEntryFocus:y=!1,...k}=e,N=r.useRef(null),A=(0,s.s)(t,N),G=(0,p.jH)(d),[F,S]=(0,u.i)({prop:x,defaultProp:j??null,onChange:g,caller:b}),[C,E]=r.useState(!1),T=(0,c.c)(w),_=v(o),D=r.useRef(!1),[L,K]=r.useState(0);return r.useEffect(()=>{const e=N.current;if(e)return e.addEventListener(f,T),()=>e.removeEventListener(f,T)},[T]),(0,h.jsx)(R,{scope:o,orientation:i,dir:G,loop:a,currentTabStopId:F,onItemFocus:r.useCallback(e=>S(e),[S]),onItemShiftTab:r.useCallback(()=>E(!0),[]),onFocusableItemAdd:r.useCallback(()=>K(e=>e+1),[]),onFocusableItemRemove:r.useCallback(()=>K(e=>e-1),[]),children:(0,h.jsx)(l.sG.div,{tabIndex:C||0===L?-1:0,"data-orientation":i,...k,ref:A,style:{outline:"none",...e.style},onMouseDown:(0,n.mK)(e.onMouseDown,()=>{D.current=!0}),onFocus:(0,n.mK)(e.onFocus,e=>{const t=!D.current;if(e.target===e.currentTarget&&t&&!C){const t=new CustomEvent(f,m);if(e.currentTarget.dispatchEvent(t),!t.defaultPrevented){const e=_().filter(e=>e.focusable);I([e.find(e=>e.active),e.find(e=>e.id===F),...e].filter(Boolean).map(e=>e.ref.current),y)}}D.current=!1}),onBlur:(0,n.mK)(e.onBlur,()=>E(!1))})})}),A="RovingFocusGroupItem",G=r.forwardRef((e,t)=>{const{__scopeRovingFocusGroup:o,focusable:i=!0,active:s=!1,tabStopId:a,children:c,...u}=e,p=(0,d.B)(),f=a||p,m=y(A,o),b=m.currentTabStopId===f,j=v(o),{onFocusableItemAdd:g,onFocusableItemRemove:w,currentTabStopId:R}=m;return r.useEffect(()=>{if(i)return g(),()=>w()},[i,g,w]),(0,h.jsx)(x.ItemSlot,{scope:o,id:f,focusable:i,active:s,children:(0,h.jsx)(l.sG.span,{tabIndex:b?0:-1,"data-orientation":m.orientation,...u,ref:t,onMouseDown:(0,n.mK)(e.onMouseDown,e=>{i?m.onItemFocus(f):e.preventDefault()}),onFocus:(0,n.mK)(e.onFocus,()=>m.onItemFocus(f)),onKeyDown:(0,n.mK)(e.onKeyDown,e=>{if("Tab"===e.key&&e.shiftKey)return void m.onItemShiftTab();if(e.target!==e.currentTarget)return;const t=function(e,t,o){const r=function(e,t){return"rtl"!==t?e:"ArrowLeft"===e?"ArrowRight":"ArrowRight"===e?"ArrowLeft":e}(e.key,o);return"vertical"===t&&["ArrowLeft","ArrowRight"].includes(r)||"horizontal"===t&&["ArrowUp","ArrowDown"].includes(r)?void 0:F[r]}(e,m.orientation,m.dir);if(void 0!==t){if(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey)return;e.preventDefault();let n=j().filter(e=>e.focusable).map(e=>e.ref.current);if("last"===t)n.reverse();else if("prev"===t||"next"===t){"prev"===t&&n.reverse();const i=n.indexOf(e.currentTarget);n=m.loop?(r=i+1,(o=n).map((e,t)=>o[(r+t)%o.length])):n.slice(i+1)}setTimeout(()=>I(n))}var o,r}),children:"function"==typeof c?c({isCurrentTabStop:b,hasTabStop:null!=R}):c})})});G.displayName=A;var F={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function I(e,t=!1){const o=document.activeElement;for(const r of e){if(r===o)return;if(r.focus({preventScroll:t}),document.activeElement!==o)return}}var S=k,C=G},10263(e,t,o){o.d(t,{c:()=>n});var r=o(96540);function n(e){const t=r.useRef(e);return r.useEffect(()=>{t.current=e}),r.useMemo(()=>(...e)=>t.current?.(...e),[])}},85357(e,t,o){o.d(t,{Z:()=>n});var r=o(96540);function n(e){const t=r.useRef({value:e,previous:e});return r.useMemo(()=>(t.current.value!==e&&(t.current.previous=t.current.value,t.current.value=e),t.current.previous),[e])}},31769(e,t,o){o.d(t,{X:()=>i});var r=o(96540),n=o(88200);
vendor: 462 bytes, line 1
1function i(e){const[t,o]=r.useState(void 0);return(0,n.N)(()=>{if(e){o({width:e.offsetWidth,height:e.offsetHeight});const t=new ResizeObserver(t=>{if(!Array.isArray(t))return;if(!t.length)return;const r=t[0];let n,i;if("borderBoxSize"in r){const e=r.borderBoxSize,t=Array.isArray(e)?e[0]:e;n=t.inlineSize,i=t.blockSize}else n=e.offsetWidth,i=e.offsetHeight;o({width:n,height:i})});return t.observe(e,{box:"border-box"}),()=>t.unobserve(e)}o(void 0)},[e]),t}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.