[{"data":1,"prerenderedAt":2458},["ShallowReactive",2],{"page-\u002Fcomponents\u002F状态机驱动的ui组件库arkui":3},{"id":4,"title":5,"body":6,"description":12,"extension":2443,"meta":2444,"navigation":282,"path":2454,"seo":2455,"stem":2456,"__hash__":2457},"content\u002Fcomponents\u002F状态机驱动的ui组件库arkui.md","状态机驱动的ui组件库arkui",{"type":7,"value":8,"toc":2438},"minimark",[9,13,16,19,22,29,45,66,70,76,79,116,123,155,186,189,192,195,210,213,428,431,453,653,660,683,1208,1211,1214,1245,1276,1299,1388,1391,1405,1410,1529,1542,1547,1662,1674,1679,1818,1828,1857,1870,2166,2176,2434],[10,11,12],"p",{},"Ark UI 引入了 Zag.js 状态机、跨框架 API 一致性、复合组件设计等概念，是一个全新的架构范式，不仅是组件库，更是一种管理复杂交互逻辑的底层思维，因此，单开一个笔记用于记载。",[10,14,15],{},"虽然这套逻辑和视觉状态机非常类似，就是说VSM，视觉状态管理，WPF早就实现了很多，已经玩过了，但是架构层级和职责边界上有着根本区别。这点稍微留意。",[10,17,18],{},"我们知道WPF里VSM的核心是ControlTemplate结合使用的，比如Normal、MouseOver、Pressed、Focusd状态，表现为负责视觉表现层的切换，控件的内部逻辑触发状态改变的时候，VSM负责用Storyboard去播放不同动画或者改变属性。但是VSM是强绑定在WPF\u002FXAML引擎内部的，对于复杂键盘导航、屏幕阅读器无障碍、焦点陷阱等行为逻辑，需要开发者在后台写cs代码处理。",[10,20,21],{},"zag.js的设计来源于XState，它不仅管理视觉，核心是管理行为和交互的契约。它管理的是一个纯粹逻辑状态机，定义这个状态下按下Escape会发生什么，按下ArrowDown焦点应该去哪等等。它本身没有DOM，也不关动画，只是导出一个核心状态对象，当前的状态以data-state、data-docus这种Data属性的形式喂给HTML DOM，剩下的交给CSS去渲染。",[10,23,24],{},[25,26],"img",{"alt":27,"src":28},"","https:\u002F\u002Fark-ui.com\u002Fimages\u002Farchitecture_dark.svg",[10,30,31,32,36,37,40,41,44],{},"ArkUI通过数据属性来提供语义标签，比如 ",[33,34,35],"code",{},"data-scope=\"accordion\""," 表示这是手风琴组件，",[33,38,39],{},"data-part=\"item\""," 表示这是其中的列表项。这就让样式层可以在不依赖具体的 HTML 结构（比如 ",[33,42,43],{},"div > ul > li","）的情况下精准定位。",[10,46,47,53,54,57,58,61,62,65],{},[48,49,50],"strong",{},[33,51,52],{},"data-state","：这是状态机直接映射到 DOM 上的结果。Zag.js 内部状态机算出当前是 ",[33,55,56],{},"open"," 还是 ",[33,59,60],{},"closed","，就会直接反映为 ",[33,63,64],{},"data-state=\"open\"","。",[67,68,69],"h2",{"id":69},"组件组合",[10,71,72,73],{},"它解决了传统组件库一个非常恶心的痛点：",[48,74,75],{},"组件库自带的 HTML 标签太死板，但如果你自己写标签，又会丢失组件库内置的交互逻辑。",[10,77,78],{},"asChild是一个很好用的属性，如果你想用一个弹窗触发器，你必须要用库提供的标签：",[80,81,85],"pre",{"className":82,"code":83,"language":84,"meta":27,"style":27},"language-vue shiki shiki-themes github-light github-dark","\u003CPopover.Trigger>打开\u003C\u002FPopover.Trigger>\n\u003C!-- 渲染出来可能是 \u003Cbutton>打开\u003C\u002Fbutton> -->\n","vue",[33,86,87,110],{"__ignoreMap":27},[88,89,92,96,100,103,107],"span",{"class":90,"line":91},"line",1,[88,93,95],{"class":94},"sVt8B","\u003C",[88,97,99],{"class":98},"s9eBZ","Popover",[88,101,102],{"class":94},".",[88,104,106],{"class":105},"sScJk","Trigger",[88,108,109],{"class":94},">打开\u003C\u002FPopover.Trigger>\n",[88,111,113],{"class":90,"line":112},2,[88,114,115],{"class":94},"\u003C!-- 渲染出来可能是 \u003Cbutton>打开\u003C\u002Fbutton> -->\n",[10,117,118,119,122],{},"但如果你想要一个带有特殊路由跳转（如 ",[33,120,121],{},"\u003CRouterLink>","）或者复杂样式的自定义按钮，这套标签就不够用了。这时候可以用asChild：",[80,124,126],{"className":82,"code":125,"language":84,"meta":27,"style":27},"\u003CPopover.Trigger asChild>\n  \u003CMyCustomButton>打开\u003C\u002FMyCustomButton>\n\u003C\u002FPopover.Trigger>\n",[33,127,128,144,149],{"__ignoreMap":27},[88,129,130,132,134,136,138,141],{"class":90,"line":91},[88,131,95],{"class":94},[88,133,99],{"class":98},[88,135,102],{"class":94},[88,137,106],{"class":105},[88,139,140],{"class":105}," asChild",[88,142,143],{"class":94},">\n",[88,145,146],{"class":90,"line":112},[88,147,148],{"class":94},"  \u003CMyCustomButton>打开\u003C\u002FMyCustomButton>\n",[88,150,152],{"class":90,"line":151},3,[88,153,154],{"class":94},"\u003C\u002FPopover.Trigger>\n",[10,156,157,158,161,162,165,166,169,170,173,174,177,178,185],{},"加上 ",[33,159,160],{},"asChild"," 后，",[33,163,164],{},"Popover.Trigger"," 自己",[48,167,168],{},"不会渲染任何 DOM 元素","。它会把它内部包含的所有交互逻辑（",[33,171,172],{},"onClick"," 事件、",[33,175,176],{},"aria-expanded"," 等无障碍属性、键盘焦点管理）作为 Props，",[48,179,180,181,184],{},"全部注入到你提供的 ",[33,182,183],{},"\u003CMyCustomButton>"," 上",",这不仅避免了多余的 DOM 嵌套，还让你百分百掌握了 DOM 结构和样式控制权。",[10,187,188],{},"官方文档里还提到了ark.span、ark.div，这些本身就是普通的标签，但是它们支持了asChild属性，当他嵌套a标签时候，ark会把自身属性直接合并给a，最终渲染出纯粹的a标签，这样就打破了组件库强加的标签限制，让你能在任何标签上复刻Ark UI的强大交互和可访问支持。",[67,190,191],{"id":191},"组件状态的控制",[10,193,194],{},"之前我们聊zag.js的时候，知道它管理复杂交互逻辑，但是作为开发者，当组件状态发生变化的时候，我们怎么去读取它，或者怎么从外部干预它。ArkUI提供了三种方案来应对不同业务的场景。",[10,196,197,198,201,202,205,206,209],{},"一种是使用Rendser Props，v-slot或者子函数，直接获取当前状态，适用于你只需要在当前组件内部，根据状态条件渲染一小块UI。官方文档里解析了，在 ",[33,199,200],{},"\u003CAvatar.Root>"," 内部，用 ",[33,203,204],{},"\u003CAvatar.Context v-slot=\"avatar\">"," 拿到 ",[33,207,208],{},"loaded"," 状态。如果图片加载完了显示 \"PA\"，没加载完显示 \"Loading\"。",[10,211,212],{},"如下：",[80,214,216],{"className":82,"code":215,"language":84,"meta":27,"style":27},"\u003Cscript setup lang=\"ts\">\nimport { Avatar } from '@ark-ui\u002Fvue\u002Favatar'\nimport styles from '.\u002Favatar.module.css'\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CAvatar.Root :class=\"styles.Root\">\n    \u003CAvatar.Context v-slot=\"avatar\">\n      \u003CAvatar.Fallback :class=\"styles.Fallback\">\n        {{ avatar.loaded ? 'PA' : 'Loading' }}\n      \u003C\u002FAvatar.Fallback>\n    \u003C\u002FAvatar.Context>\n    \u003CAvatar.Image :class=\"styles.Image\" src=\"https:\u002F\u002Fi.pravatar.cc\u002F300?u=a\" alt=\"avatar\" \u002F>\n  \u003C\u002FAvatar.Root>\n\u003C\u002Ftemplate>\n",[33,217,218,240,255,267,277,284,294,313,332,350,356,366,376,409,419],{"__ignoreMap":27},[88,219,220,222,225,228,231,234,238],{"class":90,"line":91},[88,221,95],{"class":94},[88,223,224],{"class":98},"script",[88,226,227],{"class":105}," setup",[88,229,230],{"class":105}," lang",[88,232,233],{"class":94},"=",[88,235,237],{"class":236},"sZZnC","\"ts\"",[88,239,143],{"class":94},[88,241,242,246,249,252],{"class":90,"line":112},[88,243,245],{"class":244},"szBVR","import",[88,247,248],{"class":94}," { Avatar } ",[88,250,251],{"class":244},"from",[88,253,254],{"class":236}," '@ark-ui\u002Fvue\u002Favatar'\n",[88,256,257,259,262,264],{"class":90,"line":151},[88,258,245],{"class":244},[88,260,261],{"class":94}," styles ",[88,263,251],{"class":244},[88,265,266],{"class":236}," '.\u002Favatar.module.css'\n",[88,268,270,273,275],{"class":90,"line":269},4,[88,271,272],{"class":94},"\u003C\u002F",[88,274,224],{"class":98},[88,276,143],{"class":94},[88,278,280],{"class":90,"line":279},5,[88,281,283],{"emptyLinePlaceholder":282},true,"\n",[88,285,287,289,292],{"class":90,"line":286},6,[88,288,95],{"class":94},[88,290,291],{"class":98},"template",[88,293,143],{"class":94},[88,295,297,300,303,306,308,311],{"class":90,"line":296},7,[88,298,299],{"class":94},"  \u003C",[88,301,302],{"class":98},"Avatar.Root",[88,304,305],{"class":105}," :class",[88,307,233],{"class":94},[88,309,310],{"class":236},"\"styles.Root\"",[88,312,143],{"class":94},[88,314,316,319,322,325,327,330],{"class":90,"line":315},8,[88,317,318],{"class":94},"    \u003C",[88,320,321],{"class":98},"Avatar.Context",[88,323,324],{"class":105}," v-slot",[88,326,233],{"class":94},[88,328,329],{"class":236},"\"avatar\"",[88,331,143],{"class":94},[88,333,335,338,341,343,345,348],{"class":90,"line":334},9,[88,336,337],{"class":94},"      \u003C",[88,339,340],{"class":98},"Avatar.Fallback",[88,342,305],{"class":105},[88,344,233],{"class":94},[88,346,347],{"class":236},"\"styles.Fallback\"",[88,349,143],{"class":94},[88,351,353],{"class":90,"line":352},10,[88,354,355],{"class":94},"        {{ avatar.loaded ? 'PA' : 'Loading' }}\n",[88,357,359,362,364],{"class":90,"line":358},11,[88,360,361],{"class":94},"      \u003C\u002F",[88,363,340],{"class":98},[88,365,143],{"class":94},[88,367,369,372,374],{"class":90,"line":368},12,[88,370,371],{"class":94},"    \u003C\u002F",[88,373,321],{"class":98},[88,375,143],{"class":94},[88,377,379,381,384,386,388,391,394,396,399,402,404,406],{"class":90,"line":378},13,[88,380,318],{"class":94},[88,382,383],{"class":98},"Avatar.Image",[88,385,305],{"class":105},[88,387,233],{"class":94},[88,389,390],{"class":236},"\"styles.Image\"",[88,392,393],{"class":105}," src",[88,395,233],{"class":94},[88,397,398],{"class":236},"\"https:\u002F\u002Fi.pravatar.cc\u002F300?u=a\"",[88,400,401],{"class":105}," alt",[88,403,233],{"class":94},[88,405,329],{"class":236},[88,407,408],{"class":94}," \u002F>\n",[88,410,412,415,417],{"class":90,"line":411},14,[88,413,414],{"class":94},"  \u003C\u002F",[88,416,302],{"class":98},[88,418,143],{"class":94},[88,420,422,424,426],{"class":90,"line":421},15,[88,423,272],{"class":94},[88,425,291],{"class":98},[88,427,143],{"class":94},[10,429,430],{},"这像是一个局部的“监控探头”。缺点是会在 DOM 外层包一层 Context 组件，稍微有些嵌套感。",[10,432,433,434,437,438,441,442,445,446,205,449,452],{},"另一种是ARKUI导入useDialogContext或者useMenuContext等Hooks，在任意深度的子组件里调用，如果你想抽离出一个自定义的子组件，并且想要让他有改变父组件状态的能力，就可以使用这。",[48,435,436],{},"文档示例解析","：你写了一个 ",[33,439,440],{},"\u003CCustomCloseButton \u002F>","，把它放在 ",[33,443,444],{},"\u003CDialog.Content>"," 里面。在这个自定义按钮里，调用 ",[33,447,448],{},"useDialogContext()",[33,450,451],{},"dialog.setOpen(false)","。点击就能关闭弹窗。",[80,454,458],{"className":455,"code":456,"language":457,"meta":27,"style":27},"language-jsx shiki shiki-themes github-light github-dark","import { Dialog, useDialogContext } from '@ark-ui\u002Freact\u002Fdialog'\n\nfunction CustomCloseButton() {\n  const dialog = useDialogContext()\n  return \u003Cbutton onClick={() => dialog.setOpen(false)}>Close ({dialog.open ? 'open' : 'closed'})\u003C\u002Fbutton>\n}\n\nexport const Demo = () => (\n  \u003CDialog.Root>\n    \u003CDialog.Trigger>Open\u003C\u002FDialog.Trigger>\n    \u003CDialog.Content>\n      \u003CCustomCloseButton \u002F>\n    \u003C\u002FDialog.Content>\n  \u003C\u002FDialog.Root>\n)\n","jsx",[33,459,460,472,476,487,505,561,566,570,591,600,614,623,632,640,648],{"__ignoreMap":27},[88,461,462,464,467,469],{"class":90,"line":91},[88,463,245],{"class":244},[88,465,466],{"class":94}," { Dialog, useDialogContext } ",[88,468,251],{"class":244},[88,470,471],{"class":236}," '@ark-ui\u002Freact\u002Fdialog'\n",[88,473,474],{"class":90,"line":112},[88,475,283],{"emptyLinePlaceholder":282},[88,477,478,481,484],{"class":90,"line":151},[88,479,480],{"class":244},"function",[88,482,483],{"class":105}," CustomCloseButton",[88,485,486],{"class":94},"() {\n",[88,488,489,492,496,499,502],{"class":90,"line":269},[88,490,491],{"class":244},"  const",[88,493,495],{"class":494},"sj4cs"," dialog",[88,497,498],{"class":244}," =",[88,500,501],{"class":105}," useDialogContext",[88,503,504],{"class":94},"()\n",[88,506,507,510,513,516,519,521,524,527,530,533,536,539,542,545,548,551,554,557,559],{"class":90,"line":279},[88,508,509],{"class":244},"  return",[88,511,512],{"class":94}," \u003C",[88,514,515],{"class":98},"button",[88,517,518],{"class":105}," onClick",[88,520,233],{"class":244},[88,522,523],{"class":94},"{() ",[88,525,526],{"class":244},"=>",[88,528,529],{"class":94}," dialog.",[88,531,532],{"class":105},"setOpen",[88,534,535],{"class":94},"(",[88,537,538],{"class":494},"false",[88,540,541],{"class":94},")}>Close ({dialog.open ",[88,543,544],{"class":244},"?",[88,546,547],{"class":236}," 'open'",[88,549,550],{"class":244}," :",[88,552,553],{"class":236}," 'closed'",[88,555,556],{"class":94},"})\u003C\u002F",[88,558,515],{"class":98},[88,560,143],{"class":94},[88,562,563],{"class":90,"line":286},[88,564,565],{"class":94},"}\n",[88,567,568],{"class":90,"line":296},[88,569,283],{"emptyLinePlaceholder":282},[88,571,572,575,578,581,583,586,588],{"class":90,"line":315},[88,573,574],{"class":244},"export",[88,576,577],{"class":244}," const",[88,579,580],{"class":105}," Demo",[88,582,498],{"class":244},[88,584,585],{"class":94}," () ",[88,587,526],{"class":244},[88,589,590],{"class":94}," (\n",[88,592,593,595,598],{"class":90,"line":334},[88,594,299],{"class":94},[88,596,597],{"class":494},"Dialog.Root",[88,599,143],{"class":94},[88,601,602,604,607,610,612],{"class":90,"line":352},[88,603,318],{"class":94},[88,605,606],{"class":494},"Dialog.Trigger",[88,608,609],{"class":94},">Open\u003C\u002F",[88,611,606],{"class":494},[88,613,143],{"class":94},[88,615,616,618,621],{"class":90,"line":358},[88,617,318],{"class":94},[88,619,620],{"class":494},"Dialog.Content",[88,622,143],{"class":94},[88,624,625,627,630],{"class":90,"line":368},[88,626,337],{"class":94},[88,628,629],{"class":494},"CustomCloseButton",[88,631,408],{"class":94},[88,633,634,636,638],{"class":90,"line":378},[88,635,371],{"class":94},[88,637,620],{"class":494},[88,639,143],{"class":94},[88,641,642,644,646],{"class":90,"line":411},[88,643,414],{"class":94},[88,645,597],{"class":494},[88,647,143],{"class":94},[88,649,650],{"class":90,"line":421},[88,651,652],{"class":94},")\n",[10,654,655,656,659],{},"这是最推荐的做法。它彻底消灭了繁琐的 Render Props 嵌套（即不需要再写 ",[33,657,658],{},"v-slot","），代码更干净。只要在 Context 树内，任何后代组件都能调用它。",[10,661,662,663,666,667,670,671,674,675,678,679,682],{},"还有一种模式，用 ",[33,664,665],{},"useAccordion()","（或 ",[33,668,669],{},"useDialog()","）在组件树",[48,672,673],{},"外部","初始化状态，然后用 ",[33,676,677],{},"\u003CAccordion.RootProvider>"," 替换掉原本的 ",[33,680,681],{},"\u003CAccordion.Root>","，将刚刚的状态实例传进去。如果你需要从外部比如pinia中读取，甚至直接修改这个组件的状态，就可以使用：",[80,684,686],{"className":82,"code":685,"language":84,"meta":27,"style":27},"\u003Cscript setup lang=\"ts\">\nimport { Accordion, useAccordion } from '@ark-ui\u002Fvue\u002Faccordion'\nimport { ChevronDownIcon } from 'lucide-vue-next'\nimport styles from '.\u002Faccordion.module.css'\n\nconst items = [\n  {\n    value: 'ark-ui',\n    title: 'What is Ark UI?',\n    content: 'A headless component library for building accessible web apps.',\n  },\n  {\n    value: 'getting-started',\n    title: 'How to get started?',\n    content: 'Install the package and import the components you need.',\n  },\n  {\n    value: 'maintainers',\n    title: 'Who maintains this project?',\n    content: 'Ark UI is maintained by the Chakra UI team.',\n  },\n]\n\nconst accordion = useAccordion({\n  multiple: true,\n  defaultValue: ['ark-ui'],\n})\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"stack\">\n    \u003Coutput>Value: {{ JSON.stringify(accordion.value) }}\u003C\u002Foutput>\n\n    \u003CAccordion.RootProvider :class=\"styles.Root\" :value=\"accordion\">\n      \u003CAccordion.Item v-for=\"item in items\" :key=\"item.value\" :class=\"styles.Item\" :value=\"item.value\">\n        \u003CAccordion.ItemTrigger :class=\"styles.ItemTrigger\">\n          {{ item.title }}\n          \u003CAccordion.ItemIndicator :class=\"styles.ItemIndicator\">\n            \u003CChevronDownIcon \u002F>\n          \u003C\u002FAccordion.ItemIndicator>\n        \u003C\u002FAccordion.ItemTrigger>\n        \u003CAccordion.ItemContent :class=\"styles.ItemContent\">\n          \u003Cdiv :class=\"styles.ItemBody\">{{ item.content }}\u003C\u002Fdiv>\n        \u003C\u002FAccordion.ItemContent>\n      \u003C\u002FAccordion.Item>\n    \u003C\u002FAccordion.RootProvider>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[33,687,688,704,716,728,739,743,756,761,772,782,792,797,801,810,819,828,833,838,848,858,868,873,879,884,900,911,922,928,937,942,951,969,984,989,1013,1052,1070,1076,1094,1105,1115,1125,1142,1163,1172,1181,1190,1199],{"__ignoreMap":27},[88,689,690,692,694,696,698,700,702],{"class":90,"line":91},[88,691,95],{"class":94},[88,693,224],{"class":98},[88,695,227],{"class":105},[88,697,230],{"class":105},[88,699,233],{"class":94},[88,701,237],{"class":236},[88,703,143],{"class":94},[88,705,706,708,711,713],{"class":90,"line":112},[88,707,245],{"class":244},[88,709,710],{"class":94}," { Accordion, useAccordion } ",[88,712,251],{"class":244},[88,714,715],{"class":236}," '@ark-ui\u002Fvue\u002Faccordion'\n",[88,717,718,720,723,725],{"class":90,"line":151},[88,719,245],{"class":244},[88,721,722],{"class":94}," { ChevronDownIcon } ",[88,724,251],{"class":244},[88,726,727],{"class":236}," 'lucide-vue-next'\n",[88,729,730,732,734,736],{"class":90,"line":269},[88,731,245],{"class":244},[88,733,261],{"class":94},[88,735,251],{"class":244},[88,737,738],{"class":236}," '.\u002Faccordion.module.css'\n",[88,740,741],{"class":90,"line":279},[88,742,283],{"emptyLinePlaceholder":282},[88,744,745,748,751,753],{"class":90,"line":286},[88,746,747],{"class":244},"const",[88,749,750],{"class":494}," items",[88,752,498],{"class":244},[88,754,755],{"class":94}," [\n",[88,757,758],{"class":90,"line":296},[88,759,760],{"class":94},"  {\n",[88,762,763,766,769],{"class":90,"line":315},[88,764,765],{"class":94},"    value: ",[88,767,768],{"class":236},"'ark-ui'",[88,770,771],{"class":94},",\n",[88,773,774,777,780],{"class":90,"line":334},[88,775,776],{"class":94},"    title: ",[88,778,779],{"class":236},"'What is Ark UI?'",[88,781,771],{"class":94},[88,783,784,787,790],{"class":90,"line":352},[88,785,786],{"class":94},"    content: ",[88,788,789],{"class":236},"'A headless component library for building accessible web apps.'",[88,791,771],{"class":94},[88,793,794],{"class":90,"line":358},[88,795,796],{"class":94},"  },\n",[88,798,799],{"class":90,"line":368},[88,800,760],{"class":94},[88,802,803,805,808],{"class":90,"line":378},[88,804,765],{"class":94},[88,806,807],{"class":236},"'getting-started'",[88,809,771],{"class":94},[88,811,812,814,817],{"class":90,"line":411},[88,813,776],{"class":94},[88,815,816],{"class":236},"'How to get started?'",[88,818,771],{"class":94},[88,820,821,823,826],{"class":90,"line":421},[88,822,786],{"class":94},[88,824,825],{"class":236},"'Install the package and import the components you need.'",[88,827,771],{"class":94},[88,829,831],{"class":90,"line":830},16,[88,832,796],{"class":94},[88,834,836],{"class":90,"line":835},17,[88,837,760],{"class":94},[88,839,841,843,846],{"class":90,"line":840},18,[88,842,765],{"class":94},[88,844,845],{"class":236},"'maintainers'",[88,847,771],{"class":94},[88,849,851,853,856],{"class":90,"line":850},19,[88,852,776],{"class":94},[88,854,855],{"class":236},"'Who maintains this project?'",[88,857,771],{"class":94},[88,859,861,863,866],{"class":90,"line":860},20,[88,862,786],{"class":94},[88,864,865],{"class":236},"'Ark UI is maintained by the Chakra UI team.'",[88,867,771],{"class":94},[88,869,871],{"class":90,"line":870},21,[88,872,796],{"class":94},[88,874,876],{"class":90,"line":875},22,[88,877,878],{"class":94},"]\n",[88,880,882],{"class":90,"line":881},23,[88,883,283],{"emptyLinePlaceholder":282},[88,885,887,889,892,894,897],{"class":90,"line":886},24,[88,888,747],{"class":244},[88,890,891],{"class":494}," accordion",[88,893,498],{"class":244},[88,895,896],{"class":105}," useAccordion",[88,898,899],{"class":94},"({\n",[88,901,903,906,909],{"class":90,"line":902},25,[88,904,905],{"class":94},"  multiple: ",[88,907,908],{"class":494},"true",[88,910,771],{"class":94},[88,912,914,917,919],{"class":90,"line":913},26,[88,915,916],{"class":94},"  defaultValue: [",[88,918,768],{"class":236},[88,920,921],{"class":94},"],\n",[88,923,925],{"class":90,"line":924},27,[88,926,927],{"class":94},"})\n",[88,929,931,933,935],{"class":90,"line":930},28,[88,932,272],{"class":94},[88,934,224],{"class":98},[88,936,143],{"class":94},[88,938,940],{"class":90,"line":939},29,[88,941,283],{"emptyLinePlaceholder":282},[88,943,945,947,949],{"class":90,"line":944},30,[88,946,95],{"class":94},[88,948,291],{"class":98},[88,950,143],{"class":94},[88,952,954,956,959,962,964,967],{"class":90,"line":953},31,[88,955,299],{"class":94},[88,957,958],{"class":98},"div",[88,960,961],{"class":105}," class",[88,963,233],{"class":94},[88,965,966],{"class":236},"\"stack\"",[88,968,143],{"class":94},[88,970,972,974,977,980,982],{"class":90,"line":971},32,[88,973,318],{"class":94},[88,975,976],{"class":98},"output",[88,978,979],{"class":94},">Value: {{ JSON.stringify(accordion.value) }}\u003C\u002F",[88,981,976],{"class":98},[88,983,143],{"class":94},[88,985,987],{"class":90,"line":986},33,[88,988,283],{"emptyLinePlaceholder":282},[88,990,992,994,997,999,1001,1003,1006,1008,1011],{"class":90,"line":991},34,[88,993,318],{"class":94},[88,995,996],{"class":98},"Accordion.RootProvider",[88,998,305],{"class":105},[88,1000,233],{"class":94},[88,1002,310],{"class":236},[88,1004,1005],{"class":105}," :value",[88,1007,233],{"class":94},[88,1009,1010],{"class":236},"\"accordion\"",[88,1012,143],{"class":94},[88,1014,1016,1018,1021,1024,1026,1029,1032,1034,1037,1039,1041,1044,1046,1048,1050],{"class":90,"line":1015},35,[88,1017,337],{"class":94},[88,1019,1020],{"class":98},"Accordion.Item",[88,1022,1023],{"class":105}," v-for",[88,1025,233],{"class":94},[88,1027,1028],{"class":236},"\"item in items\"",[88,1030,1031],{"class":105}," :key",[88,1033,233],{"class":94},[88,1035,1036],{"class":236},"\"item.value\"",[88,1038,305],{"class":105},[88,1040,233],{"class":94},[88,1042,1043],{"class":236},"\"styles.Item\"",[88,1045,1005],{"class":105},[88,1047,233],{"class":94},[88,1049,1036],{"class":236},[88,1051,143],{"class":94},[88,1053,1055,1058,1061,1063,1065,1068],{"class":90,"line":1054},36,[88,1056,1057],{"class":94},"        \u003C",[88,1059,1060],{"class":98},"Accordion.ItemTrigger",[88,1062,305],{"class":105},[88,1064,233],{"class":94},[88,1066,1067],{"class":236},"\"styles.ItemTrigger\"",[88,1069,143],{"class":94},[88,1071,1073],{"class":90,"line":1072},37,[88,1074,1075],{"class":94},"          {{ item.title }}\n",[88,1077,1079,1082,1085,1087,1089,1092],{"class":90,"line":1078},38,[88,1080,1081],{"class":94},"          \u003C",[88,1083,1084],{"class":98},"Accordion.ItemIndicator",[88,1086,305],{"class":105},[88,1088,233],{"class":94},[88,1090,1091],{"class":236},"\"styles.ItemIndicator\"",[88,1093,143],{"class":94},[88,1095,1097,1100,1103],{"class":90,"line":1096},39,[88,1098,1099],{"class":94},"            \u003C",[88,1101,1102],{"class":98},"ChevronDownIcon",[88,1104,408],{"class":94},[88,1106,1108,1111,1113],{"class":90,"line":1107},40,[88,1109,1110],{"class":94},"          \u003C\u002F",[88,1112,1084],{"class":98},[88,1114,143],{"class":94},[88,1116,1118,1121,1123],{"class":90,"line":1117},41,[88,1119,1120],{"class":94},"        \u003C\u002F",[88,1122,1060],{"class":98},[88,1124,143],{"class":94},[88,1126,1128,1130,1133,1135,1137,1140],{"class":90,"line":1127},42,[88,1129,1057],{"class":94},[88,1131,1132],{"class":98},"Accordion.ItemContent",[88,1134,305],{"class":105},[88,1136,233],{"class":94},[88,1138,1139],{"class":236},"\"styles.ItemContent\"",[88,1141,143],{"class":94},[88,1143,1145,1147,1149,1151,1153,1156,1159,1161],{"class":90,"line":1144},43,[88,1146,1081],{"class":94},[88,1148,958],{"class":98},[88,1150,305],{"class":105},[88,1152,233],{"class":94},[88,1154,1155],{"class":236},"\"styles.ItemBody\"",[88,1157,1158],{"class":94},">{{ item.content }}\u003C\u002F",[88,1160,958],{"class":98},[88,1162,143],{"class":94},[88,1164,1166,1168,1170],{"class":90,"line":1165},44,[88,1167,1120],{"class":94},[88,1169,1132],{"class":98},[88,1171,143],{"class":94},[88,1173,1175,1177,1179],{"class":90,"line":1174},45,[88,1176,361],{"class":94},[88,1178,1020],{"class":98},[88,1180,143],{"class":94},[88,1182,1184,1186,1188],{"class":90,"line":1183},46,[88,1185,371],{"class":94},[88,1187,996],{"class":98},[88,1189,143],{"class":94},[88,1191,1193,1195,1197],{"class":90,"line":1192},47,[88,1194,414],{"class":94},[88,1196,958],{"class":98},[88,1198,143],{"class":94},[88,1200,1202,1204,1206],{"class":90,"line":1201},48,[88,1203,272],{"class":94},[88,1205,291],{"class":98},[88,1207,143],{"class":94},[67,1209,1210],{"id":1210},"表单部分",[10,1212,1213],{},"表单一直是前端开发中最繁琐的部分：既有复杂的交互校验，又面临极其严苛的无障碍（A11y）要求，还要和第三方的状态管理库（如 React Hook Form）做集成。",[10,1215,1216,1217,1220,1221,1224,1225,1227,1228,1230,1231,1234,1235,1234,1238,1241,1242,65],{},"在传统 UI 中，如果一个表单项被禁用了（",[33,1218,1219],{},"disabled","）或校验失败了（",[33,1222,1223],{},"invalid","），你需要把 ",[33,1226,1219],{}," 或 ",[33,1229,1223],{}," 属性传递给内部的 ",[33,1232,1233],{},"Label","、",[33,1236,1237],{},"Input",[33,1239,1240],{},"HelperText"," 甚至 ",[33,1243,1244],{},"ErrorText",[10,1246,1247,1248,1251,1252,1255,1256,1259,1260,1275],{},"Ark UI 通过 ",[33,1249,1250],{},"Field.Root"," 解决了这个问题。只要你把任何 Ark 组件（哪怕是复杂的 ",[33,1253,1254],{},"NumberInput","）放在 ",[33,1257,1258],{},"\u003CField.Root disabled>"," 里，",[48,1261,1262,1263,1234,1265,1234,1267,1270,1271,1274],{},"内部的组件会自动通过 Context 继承 ",[33,1264,1219],{},[33,1266,1223],{},[33,1268,1269],{},"required"," 和 ",[33,1272,1273],{},"readOnly"," 状态","。你不需要手动下发 props，这极大地减少了样板代码。",[1277,1278,1279],"blockquote",{},[10,1280,1281,1282,1285,1286,1288,1289,1291,1292,1291,1294,1270,1296,1298],{},"在 Ark UI 中，各种表单组件可以通过上下文自动与 ",[33,1283,1284],{},"Field"," 集成。当这些组件被嵌套在 ",[33,1287,1250],{}," 内部时，它们会自动继承 ",[33,1290,1219],{}," 、 ",[33,1293,1223],{},[33,1295,1269],{},[33,1297,1273],{}," 的状态。",[80,1300,1304],{"className":1301,"code":1302,"language":1303,"meta":27,"style":27},"language-ts shiki shiki-themes github-light github-dark","import { Field } from '@ark-ui\u002Freact\u002Ffield'\nimport { NumberInput } from '@ark-ui\u002Freact\u002Fnumber-input'\n\nconst Demo = () => (\n  \u003CField.Root disabled>\n    \u003CNumberInput.Root \u002F> {\u002F* NumberInput will be disabled *\u002F}\n  \u003C\u002FField.Root>\n)\n","ts",[33,1305,1306,1318,1330,1334,1348,1357,1376,1384],{"__ignoreMap":27},[88,1307,1308,1310,1313,1315],{"class":90,"line":91},[88,1309,245],{"class":244},[88,1311,1312],{"class":94}," { Field } ",[88,1314,251],{"class":244},[88,1316,1317],{"class":236}," '@ark-ui\u002Freact\u002Ffield'\n",[88,1319,1320,1322,1325,1327],{"class":90,"line":112},[88,1321,245],{"class":244},[88,1323,1324],{"class":94}," { NumberInput } ",[88,1326,251],{"class":244},[88,1328,1329],{"class":236}," '@ark-ui\u002Freact\u002Fnumber-input'\n",[88,1331,1332],{"class":90,"line":151},[88,1333,283],{"emptyLinePlaceholder":282},[88,1335,1336,1338,1340,1342,1344,1346],{"class":90,"line":269},[88,1337,747],{"class":244},[88,1339,580],{"class":105},[88,1341,498],{"class":244},[88,1343,585],{"class":94},[88,1345,526],{"class":244},[88,1347,590],{"class":94},[88,1349,1350,1352,1355],{"class":90,"line":279},[88,1351,299],{"class":244},[88,1353,1354],{"class":94},"Field.Root disabled",[88,1356,143],{"class":244},[88,1358,1359,1361,1364,1367,1370,1374],{"class":90,"line":286},[88,1360,318],{"class":244},[88,1362,1363],{"class":94},"NumberInput.Root ",[88,1365,1366],{"class":244},"\u002F>",[88,1368,1369],{"class":94}," {",[88,1371,1373],{"class":1372},"sJ8bj","\u002F* NumberInput will be disabled *\u002F",[88,1375,565],{"class":94},[88,1377,1378,1380,1382],{"class":90,"line":296},[88,1379,414],{"class":244},[88,1381,1250],{"class":94},[88,1383,143],{"class":244},[88,1385,1386],{"class":90,"line":315},[88,1387,652],{"class":94},[10,1389,1390],{},"在构建可访问的表单时，需要确保这些表单具有正确的标签和描述：",[10,1392,1393,1396,1397,1400,1401,1404],{},[33,1394,1395],{},"Field.Label"," ：用于为输入框提供一个可访问的标签。",[33,1398,1399],{},"Field.HelperText"," ：用于提供关于输入的额外说明。这些组件通过 ",[33,1402,1403],{},"aria-describedby"," 属性自动与输入元素关联起来。",[1277,1406,1407],{},[10,1408,1409],{},"最佳实践：确保标签是可见的（而不是仅作为占位符使用），这样屏幕阅读器能够正常读取这些标签内容。",[80,1411,1413],{"className":1301,"code":1412,"language":1303,"meta":27,"style":27},"import { Field } from '@ark-ui\u002Freact\u002Ffield'\n\nconst Demo = () => (\n  \u003Cform>\n    \u003CField.Root>\n      \u003CField.Label>Username\u003C\u002FField.Label>\n      \u003CField.Input placeholder=\"Enter your username\" \u002F>\n      \u003CField.HelperText>This will be your public display name.\u003C\u002FField.HelperText>\n    \u003C\u002FField.Root>\n  \u003C\u002Fform>\n)\n",[33,1414,1415,1425,1429,1443,1452,1460,1478,1492,1509,1517,1525],{"__ignoreMap":27},[88,1416,1417,1419,1421,1423],{"class":90,"line":91},[88,1418,245],{"class":244},[88,1420,1312],{"class":94},[88,1422,251],{"class":244},[88,1424,1317],{"class":236},[88,1426,1427],{"class":90,"line":112},[88,1428,283],{"emptyLinePlaceholder":282},[88,1430,1431,1433,1435,1437,1439,1441],{"class":90,"line":151},[88,1432,747],{"class":244},[88,1434,580],{"class":105},[88,1436,498],{"class":244},[88,1438,585],{"class":94},[88,1440,526],{"class":244},[88,1442,590],{"class":94},[88,1444,1445,1447,1450],{"class":90,"line":269},[88,1446,299],{"class":94},[88,1448,1449],{"class":105},"form",[88,1451,143],{"class":94},[88,1453,1454,1456,1458],{"class":90,"line":279},[88,1455,318],{"class":244},[88,1457,1250],{"class":94},[88,1459,143],{"class":244},[88,1461,1462,1464,1466,1469,1472,1474,1476],{"class":90,"line":286},[88,1463,337],{"class":244},[88,1465,1395],{"class":94},[88,1467,1468],{"class":244},">",[88,1470,1471],{"class":94},"Username",[88,1473,272],{"class":244},[88,1475,1395],{"class":94},[88,1477,143],{"class":244},[88,1479,1480,1482,1485,1487,1490],{"class":90,"line":296},[88,1481,337],{"class":244},[88,1483,1484],{"class":94},"Field.Input placeholder",[88,1486,233],{"class":244},[88,1488,1489],{"class":236},"\"Enter your username\"",[88,1491,408],{"class":244},[88,1493,1494,1496,1498,1500,1503,1505,1507],{"class":90,"line":315},[88,1495,337],{"class":244},[88,1497,1399],{"class":94},[88,1499,1468],{"class":244},[88,1501,1502],{"class":94},"This will be your public display name.",[88,1504,272],{"class":244},[88,1506,1399],{"class":94},[88,1508,143],{"class":244},[88,1510,1511,1513,1515],{"class":90,"line":334},[88,1512,371],{"class":244},[88,1514,1250],{"class":94},[88,1516,143],{"class":244},[88,1518,1519,1521,1523],{"class":90,"line":352},[88,1520,414],{"class":244},[88,1522,1449],{"class":94},[88,1524,143],{"class":244},[88,1526,1527],{"class":90,"line":358},[88,1528,652],{"class":94},[10,1530,1531,1532,1535,1536,1538,1539,1541],{},"当输入内容无效时，可以使用 ",[33,1533,1534],{},"Field.ErrorText"," 组件来显示错误信息，并将 ",[33,1537,1223],{}," 属性传递给 ",[33,1540,1250],{}," 组件。",[1277,1543,1544],{},[10,1545,1546],{},"最佳实践：务必提供清晰、具体的错误信息，使得这些信息易于理解和修复。",[80,1548,1550],{"className":1301,"code":1549,"language":1303,"meta":27,"style":27},"import { Field } from '@ark-ui\u002Freact\u002Ffield'\n\nconst Demo = () => (\n  \u003Cform>\n    \u003CField.Root invalid>\n      \u003CField.Label>Username\u003C\u002FField.Label>\n      \u003CField.Input placeholder=\"Enter your username\" \u002F>\n      \u003CField.ErrorText>Username is required.\u003C\u002FField.ErrorText>\n    \u003C\u002FField.Root>\n  \u003C\u002Fform>\n)\n",[33,1551,1552,1562,1566,1580,1588,1597,1613,1625,1642,1650,1658],{"__ignoreMap":27},[88,1553,1554,1556,1558,1560],{"class":90,"line":91},[88,1555,245],{"class":244},[88,1557,1312],{"class":94},[88,1559,251],{"class":244},[88,1561,1317],{"class":236},[88,1563,1564],{"class":90,"line":112},[88,1565,283],{"emptyLinePlaceholder":282},[88,1567,1568,1570,1572,1574,1576,1578],{"class":90,"line":151},[88,1569,747],{"class":244},[88,1571,580],{"class":105},[88,1573,498],{"class":244},[88,1575,585],{"class":94},[88,1577,526],{"class":244},[88,1579,590],{"class":94},[88,1581,1582,1584,1586],{"class":90,"line":269},[88,1583,299],{"class":94},[88,1585,1449],{"class":105},[88,1587,143],{"class":94},[88,1589,1590,1592,1595],{"class":90,"line":279},[88,1591,318],{"class":244},[88,1593,1594],{"class":94},"Field.Root invalid",[88,1596,143],{"class":244},[88,1598,1599,1601,1603,1605,1607,1609,1611],{"class":90,"line":286},[88,1600,337],{"class":244},[88,1602,1395],{"class":94},[88,1604,1468],{"class":244},[88,1606,1471],{"class":94},[88,1608,272],{"class":244},[88,1610,1395],{"class":94},[88,1612,143],{"class":244},[88,1614,1615,1617,1619,1621,1623],{"class":90,"line":296},[88,1616,337],{"class":244},[88,1618,1484],{"class":94},[88,1620,233],{"class":244},[88,1622,1489],{"class":236},[88,1624,408],{"class":244},[88,1626,1627,1629,1631,1633,1636,1638,1640],{"class":90,"line":315},[88,1628,337],{"class":244},[88,1630,1534],{"class":94},[88,1632,1468],{"class":244},[88,1634,1635],{"class":94},"Username is required.",[88,1637,272],{"class":244},[88,1639,1534],{"class":94},[88,1641,143],{"class":244},[88,1643,1644,1646,1648],{"class":90,"line":334},[88,1645,371],{"class":244},[88,1647,1250],{"class":94},[88,1649,143],{"class":244},[88,1651,1652,1654,1656],{"class":90,"line":352},[88,1653,414],{"class":244},[88,1655,1449],{"class":94},[88,1657,143],{"class":244},[88,1659,1660],{"class":90,"line":358},[88,1661,652],{"class":94},[10,1663,1664,1665,1538,1667,1669,1670,1673],{},"如果某个字段是必填项，可以将 ",[33,1666,1269],{},[33,1668,1250],{}," 组件。或者，也可以使用 ",[33,1671,1672],{},"Field.RequiredIndicator"," 组件来标识该字段为必填项。",[1277,1675,1676],{},[10,1677,1678],{},"最佳实践：不要仅通过颜色来指示所需的状态。",[80,1680,1682],{"className":1301,"code":1681,"language":1303,"meta":27,"style":27},"import { Field } from '@ark-ui\u002Freact\u002Ffield'\n\nexport const Demo = () => (\n  \u003Cform>\n    \u003CField.Root required>\n      \u003CField.Label>\n        Username\n        \u003CField.RequiredIndicator>(required)\u003C\u002FField.RequiredIndicator>\n      \u003C\u002FField.Label>\n      \u003CField.Input placeholder=\"Enter your username\" \u002F>\n      \u003CField.ErrorText>Username is required.\u003C\u002FField.ErrorText>\n    \u003C\u002FField.Root>\n  \u003C\u002Fform>\n)\n",[33,1683,1684,1694,1698,1714,1722,1731,1739,1745,1762,1770,1782,1798,1806,1814],{"__ignoreMap":27},[88,1685,1686,1688,1690,1692],{"class":90,"line":91},[88,1687,245],{"class":244},[88,1689,1312],{"class":94},[88,1691,251],{"class":244},[88,1693,1317],{"class":236},[88,1695,1696],{"class":90,"line":112},[88,1697,283],{"emptyLinePlaceholder":282},[88,1699,1700,1702,1704,1706,1708,1710,1712],{"class":90,"line":151},[88,1701,574],{"class":244},[88,1703,577],{"class":244},[88,1705,580],{"class":105},[88,1707,498],{"class":244},[88,1709,585],{"class":94},[88,1711,526],{"class":244},[88,1713,590],{"class":94},[88,1715,1716,1718,1720],{"class":90,"line":269},[88,1717,299],{"class":94},[88,1719,1449],{"class":105},[88,1721,143],{"class":94},[88,1723,1724,1726,1729],{"class":90,"line":279},[88,1725,318],{"class":244},[88,1727,1728],{"class":94},"Field.Root required",[88,1730,143],{"class":244},[88,1732,1733,1735,1737],{"class":90,"line":286},[88,1734,337],{"class":244},[88,1736,1395],{"class":94},[88,1738,143],{"class":244},[88,1740,1741],{"class":90,"line":296},[88,1742,1744],{"class":1743},"s4XuR","        Username\n",[88,1746,1747,1749,1751,1753,1756,1758,1760],{"class":90,"line":315},[88,1748,1057],{"class":244},[88,1750,1672],{"class":94},[88,1752,1468],{"class":244},[88,1754,1755],{"class":94},"(required)",[88,1757,272],{"class":244},[88,1759,1672],{"class":94},[88,1761,143],{"class":244},[88,1763,1764,1766,1768],{"class":90,"line":334},[88,1765,361],{"class":244},[88,1767,1395],{"class":94},[88,1769,143],{"class":244},[88,1771,1772,1774,1776,1778,1780],{"class":90,"line":352},[88,1773,337],{"class":244},[88,1775,1484],{"class":94},[88,1777,233],{"class":244},[88,1779,1489],{"class":236},[88,1781,408],{"class":244},[88,1783,1784,1786,1788,1790,1792,1794,1796],{"class":90,"line":358},[88,1785,337],{"class":244},[88,1787,1534],{"class":94},[88,1789,1468],{"class":244},[88,1791,1635],{"class":94},[88,1793,272],{"class":244},[88,1795,1534],{"class":94},[88,1797,143],{"class":244},[88,1799,1800,1802,1804],{"class":90,"line":368},[88,1801,371],{"class":244},[88,1803,1250],{"class":94},[88,1805,143],{"class":244},[88,1807,1808,1810,1812],{"class":90,"line":378},[88,1809,414],{"class":244},[88,1811,1449],{"class":94},[88,1813,143],{"class":244},[88,1815,1816],{"class":90,"line":411},[88,1817,652],{"class":94},[10,1819,1820,1821,1823,1824,1827],{},"如果某个字段是可选的，可以在 ",[33,1822,1672],{}," 组件上使用 ",[33,1825,1826],{},"fallback"," 属性来表示。",[80,1829,1833],{"className":1830,"code":1831,"language":1832,"meta":27,"style":27},"language-html shiki shiki-themes github-light github-dark","\u003CField.RequiredIndicator fallback=\"Optional\">(required)\u003C\u002FField.RequiredIndicator>\n","html",[33,1834,1835],{"__ignoreMap":27},[88,1836,1837,1839,1842,1845,1847,1850,1853,1855],{"class":90,"line":91},[88,1838,95],{"class":94},[88,1840,1672],{"class":1841},"s7hpK",[88,1843,1844],{"class":105}," fallback",[88,1846,233],{"class":94},[88,1848,1849],{"class":236},"\"Optional\"",[88,1851,1852],{"class":94},">(required)\u003C\u002F",[88,1854,1672],{"class":1841},[88,1856,143],{"class":94},[10,1858,1859,1860,1291,1863,1270,1866,1869],{},"Field 支持原生 HTML 表单控件，包括 ",[33,1861,1862],{},"input",[33,1864,1865],{},"textarea",[33,1867,1868],{},"select"," ：",[80,1871,1873],{"className":455,"code":1872,"language":457,"meta":27,"style":27},"import { Field } from '@ark-ui\u002Freact\u002Ffield'\n\nconst Demo = () => (\n  \u003Cform>\n    {\u002F* Input *\u002F}\n    \u003CField.Root>\n      \u003CField.Label>Email\u003C\u002FField.Label>\n      \u003CField.Input type=\"email\" placeholder=\"you@example.com\" \u002F>\n    \u003C\u002FField.Root>\n\n    {\u002F* Textarea *\u002F}\n    \u003CField.Root>\n      \u003CField.Label>Bio\u003C\u002FField.Label>\n      \u003CField.Textarea placeholder=\"Tell us about yourself\" \u002F>\n    \u003C\u002FField.Root>\n\n    {\u002F* Select *\u002F}\n    \u003CField.Root>\n      \u003CField.Label>Country\u003C\u002FField.Label>\n      \u003CField.Select>\n        \u003Coption value=\"us\">United States\u003C\u002Foption>\n        \u003Coption value=\"uk\">United Kingdom\u003C\u002Foption>\n        \u003Coption value=\"de\">Germany\u003C\u002Foption>\n      \u003C\u002FField.Select>\n    \u003C\u002FField.Root>\n  \u003C\u002Fform>\n)\n",[33,1874,1875,1885,1889,1903,1911,1921,1929,1942,1967,1975,1979,1988,1996,2009,2025,2033,2037,2046,2054,2067,2076,2098,2118,2138,2146,2154,2162],{"__ignoreMap":27},[88,1876,1877,1879,1881,1883],{"class":90,"line":91},[88,1878,245],{"class":244},[88,1880,1312],{"class":94},[88,1882,251],{"class":244},[88,1884,1317],{"class":236},[88,1886,1887],{"class":90,"line":112},[88,1888,283],{"emptyLinePlaceholder":282},[88,1890,1891,1893,1895,1897,1899,1901],{"class":90,"line":151},[88,1892,747],{"class":244},[88,1894,580],{"class":105},[88,1896,498],{"class":244},[88,1898,585],{"class":94},[88,1900,526],{"class":244},[88,1902,590],{"class":94},[88,1904,1905,1907,1909],{"class":90,"line":269},[88,1906,299],{"class":94},[88,1908,1449],{"class":98},[88,1910,143],{"class":94},[88,1912,1913,1916,1919],{"class":90,"line":279},[88,1914,1915],{"class":94},"    {",[88,1917,1918],{"class":1372},"\u002F* Input *\u002F",[88,1920,565],{"class":94},[88,1922,1923,1925,1927],{"class":90,"line":286},[88,1924,318],{"class":94},[88,1926,1250],{"class":494},[88,1928,143],{"class":94},[88,1930,1931,1933,1935,1938,1940],{"class":90,"line":296},[88,1932,337],{"class":94},[88,1934,1395],{"class":494},[88,1936,1937],{"class":94},">Email\u003C\u002F",[88,1939,1395],{"class":494},[88,1941,143],{"class":94},[88,1943,1944,1946,1949,1952,1954,1957,1960,1962,1965],{"class":90,"line":315},[88,1945,337],{"class":94},[88,1947,1948],{"class":494},"Field.Input",[88,1950,1951],{"class":105}," type",[88,1953,233],{"class":244},[88,1955,1956],{"class":236},"\"email\"",[88,1958,1959],{"class":105}," placeholder",[88,1961,233],{"class":244},[88,1963,1964],{"class":236},"\"you@example.com\"",[88,1966,408],{"class":94},[88,1968,1969,1971,1973],{"class":90,"line":334},[88,1970,371],{"class":94},[88,1972,1250],{"class":494},[88,1974,143],{"class":94},[88,1976,1977],{"class":90,"line":352},[88,1978,283],{"emptyLinePlaceholder":282},[88,1980,1981,1983,1986],{"class":90,"line":358},[88,1982,1915],{"class":94},[88,1984,1985],{"class":1372},"\u002F* Textarea *\u002F",[88,1987,565],{"class":94},[88,1989,1990,1992,1994],{"class":90,"line":368},[88,1991,318],{"class":94},[88,1993,1250],{"class":494},[88,1995,143],{"class":94},[88,1997,1998,2000,2002,2005,2007],{"class":90,"line":378},[88,1999,337],{"class":94},[88,2001,1395],{"class":494},[88,2003,2004],{"class":94},">Bio\u003C\u002F",[88,2006,1395],{"class":494},[88,2008,143],{"class":94},[88,2010,2011,2013,2016,2018,2020,2023],{"class":90,"line":411},[88,2012,337],{"class":94},[88,2014,2015],{"class":494},"Field.Textarea",[88,2017,1959],{"class":105},[88,2019,233],{"class":244},[88,2021,2022],{"class":236},"\"Tell us about yourself\"",[88,2024,408],{"class":94},[88,2026,2027,2029,2031],{"class":90,"line":421},[88,2028,371],{"class":94},[88,2030,1250],{"class":494},[88,2032,143],{"class":94},[88,2034,2035],{"class":90,"line":830},[88,2036,283],{"emptyLinePlaceholder":282},[88,2038,2039,2041,2044],{"class":90,"line":835},[88,2040,1915],{"class":94},[88,2042,2043],{"class":1372},"\u002F* Select *\u002F",[88,2045,565],{"class":94},[88,2047,2048,2050,2052],{"class":90,"line":840},[88,2049,318],{"class":94},[88,2051,1250],{"class":494},[88,2053,143],{"class":94},[88,2055,2056,2058,2060,2063,2065],{"class":90,"line":850},[88,2057,337],{"class":94},[88,2059,1395],{"class":494},[88,2061,2062],{"class":94},">Country\u003C\u002F",[88,2064,1395],{"class":494},[88,2066,143],{"class":94},[88,2068,2069,2071,2074],{"class":90,"line":860},[88,2070,337],{"class":94},[88,2072,2073],{"class":494},"Field.Select",[88,2075,143],{"class":94},[88,2077,2078,2080,2083,2086,2088,2091,2094,2096],{"class":90,"line":870},[88,2079,1057],{"class":94},[88,2081,2082],{"class":98},"option",[88,2084,2085],{"class":105}," value",[88,2087,233],{"class":244},[88,2089,2090],{"class":236},"\"us\"",[88,2092,2093],{"class":94},">United States\u003C\u002F",[88,2095,2082],{"class":98},[88,2097,143],{"class":94},[88,2099,2100,2102,2104,2106,2108,2111,2114,2116],{"class":90,"line":875},[88,2101,1057],{"class":94},[88,2103,2082],{"class":98},[88,2105,2085],{"class":105},[88,2107,233],{"class":244},[88,2109,2110],{"class":236},"\"uk\"",[88,2112,2113],{"class":94},">United Kingdom\u003C\u002F",[88,2115,2082],{"class":98},[88,2117,143],{"class":94},[88,2119,2120,2122,2124,2126,2128,2131,2134,2136],{"class":90,"line":881},[88,2121,1057],{"class":94},[88,2123,2082],{"class":98},[88,2125,2085],{"class":105},[88,2127,233],{"class":244},[88,2129,2130],{"class":236},"\"de\"",[88,2132,2133],{"class":94},">Germany\u003C\u002F",[88,2135,2082],{"class":98},[88,2137,143],{"class":94},[88,2139,2140,2142,2144],{"class":90,"line":886},[88,2141,361],{"class":94},[88,2143,2073],{"class":494},[88,2145,143],{"class":94},[88,2147,2148,2150,2152],{"class":90,"line":902},[88,2149,371],{"class":94},[88,2151,1250],{"class":494},[88,2153,143],{"class":94},[88,2155,2156,2158,2160],{"class":90,"line":913},[88,2157,414],{"class":94},[88,2159,1449],{"class":98},[88,2161,143],{"class":94},[88,2163,2164],{"class":90,"line":924},[88,2165,652],{"class":94},[10,2167,2168,2169,2171,2172,2175],{},"当在表单或组件中有一系列字段，且这些字段包含多个 ",[33,2170,1862],{}," 元素时，可以使用 ",[33,2173,2174],{},"Fieldset"," 组件将它们组合在一起。常见的使用场景包括：复选框组、单选框组、输入框与选择框的组合使用等。",[80,2177,2179],{"className":455,"code":2178,"language":457,"meta":27,"style":27},"import { Fieldset } from '@ark-ui\u002Freact\u002Ffieldset'\nimport { Checkbox } from '@ark-ui\u002Freact\u002Fcheckbox'\nimport { CheckIcon } from 'lucide-react'\n\nconst items = [\n  { label: 'React', value: 'react' },\n  { label: 'Solid', value: 'solid' },\n  { label: 'Vue', value: 'vue' },\n  { label: 'Svelte', value: 'svelte' },\n]\n\nconst Demo = () => (\n  \u003CFieldset.Root>\n    \u003CFieldset.Legend>Frameworks\u003C\u002FFieldset.Legend>\n    \u003CCheckbox.Group name=\"framework\">\n      {items.map((item) => (\n        \u003CCheckbox.Root value={item.value} key={item.value} \u002F>\n      ))}\n    \u003C\u002FCheckbox.Group>\n    \u003CFieldset.HelperText>Choose your preferred frameworks\u003C\u002FFieldset.HelperText>\n  \u003C\u002FFieldset.Root>\n)\n",[33,2180,2181,2193,2205,2217,2221,2231,2248,2262,2276,2290,2294,2298,2312,2321,2335,2352,2373,2395,2400,2408,2422,2430],{"__ignoreMap":27},[88,2182,2183,2185,2188,2190],{"class":90,"line":91},[88,2184,245],{"class":244},[88,2186,2187],{"class":94}," { Fieldset } ",[88,2189,251],{"class":244},[88,2191,2192],{"class":236}," '@ark-ui\u002Freact\u002Ffieldset'\n",[88,2194,2195,2197,2200,2202],{"class":90,"line":112},[88,2196,245],{"class":244},[88,2198,2199],{"class":94}," { Checkbox } ",[88,2201,251],{"class":244},[88,2203,2204],{"class":236}," '@ark-ui\u002Freact\u002Fcheckbox'\n",[88,2206,2207,2209,2212,2214],{"class":90,"line":151},[88,2208,245],{"class":244},[88,2210,2211],{"class":94}," { CheckIcon } ",[88,2213,251],{"class":244},[88,2215,2216],{"class":236}," 'lucide-react'\n",[88,2218,2219],{"class":90,"line":269},[88,2220,283],{"emptyLinePlaceholder":282},[88,2222,2223,2225,2227,2229],{"class":90,"line":279},[88,2224,747],{"class":244},[88,2226,750],{"class":494},[88,2228,498],{"class":244},[88,2230,755],{"class":94},[88,2232,2233,2236,2239,2242,2245],{"class":90,"line":286},[88,2234,2235],{"class":94},"  { label: ",[88,2237,2238],{"class":236},"'React'",[88,2240,2241],{"class":94},", value: ",[88,2243,2244],{"class":236},"'react'",[88,2246,2247],{"class":94}," },\n",[88,2249,2250,2252,2255,2257,2260],{"class":90,"line":296},[88,2251,2235],{"class":94},[88,2253,2254],{"class":236},"'Solid'",[88,2256,2241],{"class":94},[88,2258,2259],{"class":236},"'solid'",[88,2261,2247],{"class":94},[88,2263,2264,2266,2269,2271,2274],{"class":90,"line":315},[88,2265,2235],{"class":94},[88,2267,2268],{"class":236},"'Vue'",[88,2270,2241],{"class":94},[88,2272,2273],{"class":236},"'vue'",[88,2275,2247],{"class":94},[88,2277,2278,2280,2283,2285,2288],{"class":90,"line":334},[88,2279,2235],{"class":94},[88,2281,2282],{"class":236},"'Svelte'",[88,2284,2241],{"class":94},[88,2286,2287],{"class":236},"'svelte'",[88,2289,2247],{"class":94},[88,2291,2292],{"class":90,"line":352},[88,2293,878],{"class":94},[88,2295,2296],{"class":90,"line":358},[88,2297,283],{"emptyLinePlaceholder":282},[88,2299,2300,2302,2304,2306,2308,2310],{"class":90,"line":368},[88,2301,747],{"class":244},[88,2303,580],{"class":105},[88,2305,498],{"class":244},[88,2307,585],{"class":94},[88,2309,526],{"class":244},[88,2311,590],{"class":94},[88,2313,2314,2316,2319],{"class":90,"line":378},[88,2315,299],{"class":94},[88,2317,2318],{"class":494},"Fieldset.Root",[88,2320,143],{"class":94},[88,2322,2323,2325,2328,2331,2333],{"class":90,"line":411},[88,2324,318],{"class":94},[88,2326,2327],{"class":494},"Fieldset.Legend",[88,2329,2330],{"class":94},">Frameworks\u003C\u002F",[88,2332,2327],{"class":494},[88,2334,143],{"class":94},[88,2336,2337,2339,2342,2345,2347,2350],{"class":90,"line":421},[88,2338,318],{"class":94},[88,2340,2341],{"class":494},"Checkbox.Group",[88,2343,2344],{"class":105}," name",[88,2346,233],{"class":244},[88,2348,2349],{"class":236},"\"framework\"",[88,2351,143],{"class":94},[88,2353,2354,2357,2360,2363,2366,2369,2371],{"class":90,"line":830},[88,2355,2356],{"class":94},"      {items.",[88,2358,2359],{"class":105},"map",[88,2361,2362],{"class":94},"((",[88,2364,2365],{"class":1743},"item",[88,2367,2368],{"class":94},") ",[88,2370,526],{"class":244},[88,2372,590],{"class":94},[88,2374,2375,2377,2380,2382,2384,2387,2390,2392],{"class":90,"line":835},[88,2376,1057],{"class":94},[88,2378,2379],{"class":494},"Checkbox.Root",[88,2381,2085],{"class":105},[88,2383,233],{"class":244},[88,2385,2386],{"class":94},"{item.value} ",[88,2388,2389],{"class":105},"key",[88,2391,233],{"class":244},[88,2393,2394],{"class":94},"{item.value} \u002F>\n",[88,2396,2397],{"class":90,"line":840},[88,2398,2399],{"class":94},"      ))}\n",[88,2401,2402,2404,2406],{"class":90,"line":850},[88,2403,371],{"class":94},[88,2405,2341],{"class":494},[88,2407,143],{"class":94},[88,2409,2410,2412,2415,2418,2420],{"class":90,"line":860},[88,2411,318],{"class":94},[88,2413,2414],{"class":494},"Fieldset.HelperText",[88,2416,2417],{"class":94},">Choose your preferred frameworks\u003C\u002F",[88,2419,2414],{"class":494},[88,2421,143],{"class":94},[88,2423,2424,2426,2428],{"class":90,"line":870},[88,2425,414],{"class":94},[88,2427,2318],{"class":494},[88,2429,143],{"class":94},[88,2431,2432],{"class":90,"line":875},[88,2433,652],{"class":94},[2435,2436,2437],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":27,"searchDepth":112,"depth":112,"links":2439},[2440,2441,2442],{"id":69,"depth":112,"text":69},{"id":191,"depth":112,"text":191},{"id":1210,"depth":112,"text":1210},"md",{"date":2445,"tags":2446},"2026-12-07",[2447,84,2448,2449,2450,2451,2452,2453],"components","react","arkui","svelte","solid","nuxt","nextjs","\u002Fcomponents\u002F状态机驱动的ui组件库arkui",{"description":12},"components\u002F状态机驱动的ui组件库arkui","IdxO2V2xOfjjW4UZxH6AkB_e5De57sDBg9E5_sID-JI",1793064663366]