[{"data":1,"prerenderedAt":2053},["ShallowReactive",2],{"article-/topics/design/data-table-component-design-guide":3,"related-design":632,"content-query-nV8SkuIdp1":1573},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":12,"image":18,"imageQuery":19,"pexelsPhotoId":20,"pexelsUrl":21,"featured":6,"readingTime":22,"body":23,"_type":626,"_id":627,"_source":628,"_file":629,"_stem":630,"_extension":631},"/topics/design/data-table-component-design-guide","design",false,"","数据表格组件设计指南：排序、筛选、批量操作和状态反馈怎么统一","数据表格最难的不是渲染行列，而是交互密度下的一致性。本文围绕排序、筛选、批量操作、空态加载态和性能边界，给出适合后台与 SaaS 产品的表格组件设计指南。","2026-04-14","HTMLPAGE 团队",[13,14,15,16,17],"Data Table","Design System","SaaS UI","UX","Component Design","/images/topics/design/data-table-component-design-guide.jpg","analytics dashboard data table interface on computer screen",27141316,"https://www.pexels.com/photo/options-on-device-screen-27141316/",14,{"type":24,"children":25,"toc":613},"root",[26,34,39,44,74,81,86,111,116,139,145,150,237,242,248,253,258,281,286,292,297,302,320,325,343,348,354,359,364,393,398,404,409,434,439,457,462,480,485,490,503,508,526,531,536,574,579,584,589],{"type":27,"tag":28,"props":29,"children":30},"element","p",{},[31],{"type":32,"value":33},"text","很多后台系统的复杂度，最后都会集中体现在表格里。",{"type":27,"tag":28,"props":35,"children":36},{},[37],{"type":32,"value":38},"用户既要看数据，又要筛选、排序、分页、批量操作，还希望状态反馈清楚、滚动顺畅、权限逻辑一致。于是数据表格很容易变成一个“什么都想承载”的超级组件。",{"type":27,"tag":28,"props":40,"children":41},{},[42],{"type":32,"value":43},"真正难的地方不是把表格渲染出来，而是让高密度操作依然清晰、稳定、可预测。",{"type":27,"tag":28,"props":45,"children":46},{},[47,49,56,58,64,66,72],{"type":32,"value":48},"如果你想先补数据展示层的基础能力，可以搭配 ",{"type":27,"tag":50,"props":51,"children":53},"a",{"href":52},"/topics/design/data-display-component-guide",[54],{"type":32,"value":55},"数据展示组件设计完整指南",{"type":32,"value":57},"、",{"type":27,"tag":50,"props":59,"children":61},{"href":60},"/topics/frontend/search-optimization-guide",[62],{"type":32,"value":63},"搜索功能优化技巧",{"type":32,"value":65}," 和 ",{"type":27,"tag":50,"props":67,"children":69},{"href":68},"/topics/performance/large-list-rendering-guide",[70],{"type":32,"value":71},"大列表渲染性能方案",{"type":32,"value":73}," 一起看。",{"type":27,"tag":75,"props":76,"children":78},"h2",{"id":77},"数据表格先解决的不是美观而是任务路径",[79],{"type":32,"value":80},"数据表格先解决的不是美观，而是任务路径",{"type":27,"tag":28,"props":82,"children":83},{},[84],{"type":32,"value":85},"一个成熟的数据表格，通常承载 4 类任务：",{"type":27,"tag":87,"props":88,"children":89},"ul",{},[90,96,101,106],{"type":27,"tag":91,"props":92,"children":93},"li",{},[94],{"type":32,"value":95},"浏览与对比",{"type":27,"tag":91,"props":97,"children":98},{},[99],{"type":32,"value":100},"搜索与筛选",{"type":27,"tag":91,"props":102,"children":103},{},[104],{"type":32,"value":105},"批量操作",{"type":27,"tag":91,"props":107,"children":108},{},[109],{"type":32,"value":110},"定位异常与处理结果",{"type":27,"tag":28,"props":112,"children":113},{},[114],{"type":32,"value":115},"所以设计表格时，不能只问“列怎么排”，还要问：",{"type":27,"tag":87,"props":117,"children":118},{},[119,124,129,134],{"type":27,"tag":91,"props":120,"children":121},{},[122],{"type":32,"value":123},"用户最常做的是找数据、比数据，还是改数据",{"type":27,"tag":91,"props":125,"children":126},{},[127],{"type":32,"value":128},"哪些列必须始终可见",{"type":27,"tag":91,"props":130,"children":131},{},[132],{"type":32,"value":133},"批量操作是高频还是低频",{"type":27,"tag":91,"props":135,"children":136},{},[137],{"type":32,"value":138},"用户遇到空结果、加载中、权限不足时会发生什么",{"type":27,"tag":75,"props":140,"children":142},{"id":141},"列设计要先定优先级再谈宽度",[143],{"type":32,"value":144},"列设计要先定优先级，再谈宽度",{"type":27,"tag":28,"props":146,"children":147},{},[148],{"type":32,"value":149},"更稳的做法是把列分成三层：",{"type":27,"tag":151,"props":152,"children":153},"table",{},[154,178],{"type":27,"tag":155,"props":156,"children":157},"thead",{},[158],{"type":27,"tag":159,"props":160,"children":161},"tr",{},[162,168,173],{"type":27,"tag":163,"props":164,"children":165},"th",{},[166],{"type":32,"value":167},"层级",{"type":27,"tag":163,"props":169,"children":170},{},[171],{"type":32,"value":172},"作用",{"type":27,"tag":163,"props":174,"children":175},{},[176],{"type":32,"value":177},"例子",{"type":27,"tag":179,"props":180,"children":181},"tbody",{},[182,201,219],{"type":27,"tag":159,"props":183,"children":184},{},[185,191,196],{"type":27,"tag":186,"props":187,"children":188},"td",{},[189],{"type":32,"value":190},"核心列",{"type":27,"tag":186,"props":192,"children":193},{},[194],{"type":32,"value":195},"决定用户是否能快速定位对象",{"type":27,"tag":186,"props":197,"children":198},{},[199],{"type":32,"value":200},"名称、状态、更新时间",{"type":27,"tag":159,"props":202,"children":203},{},[204,209,214],{"type":27,"tag":186,"props":205,"children":206},{},[207],{"type":32,"value":208},"辅助列",{"type":27,"tag":186,"props":210,"children":211},{},[212],{"type":32,"value":213},"帮用户判断和比较",{"type":27,"tag":186,"props":215,"children":216},{},[217],{"type":32,"value":218},"分类、负责人、渠道",{"type":27,"tag":159,"props":220,"children":221},{},[222,227,232],{"type":27,"tag":186,"props":223,"children":224},{},[225],{"type":32,"value":226},"次级列",{"type":27,"tag":186,"props":228,"children":229},{},[230],{"type":32,"value":231},"只有特定场景才会看",{"type":27,"tag":186,"props":233,"children":234},{},[235],{"type":32,"value":236},"备注、来源、内部编号",{"type":27,"tag":28,"props":238,"children":239},{},[240],{"type":32,"value":241},"当屏幕空间不足时，优先保留核心列，而不是让每一列都平均受损。",{"type":27,"tag":75,"props":243,"children":245},{"id":244},"排序和筛选必须让用户知道当前表格为什么长这样",[246],{"type":32,"value":247},"排序和筛选必须让用户知道“当前表格为什么长这样”",{"type":27,"tag":28,"props":249,"children":250},{},[251],{"type":32,"value":252},"最糟糕的表格体验之一，是用户做完筛选和排序后，不知道当前数据集合是怎么被处理出来的。",{"type":27,"tag":28,"props":254,"children":255},{},[256],{"type":32,"value":257},"建议规范里至少明确：",{"type":27,"tag":87,"props":259,"children":260},{},[261,266,271,276],{"type":27,"tag":91,"props":262,"children":263},{},[264],{"type":32,"value":265},"当前排序字段和方向始终可见",{"type":27,"tag":91,"props":267,"children":268},{},[269],{"type":32,"value":270},"当前筛选条件在表格上方有摘要",{"type":27,"tag":91,"props":272,"children":273},{},[274],{"type":32,"value":275},"重置筛选动作足够明显",{"type":27,"tag":91,"props":277,"children":278},{},[279],{"type":32,"value":280},"批量操作前，能准确知道“当前选中的是哪一批数据”",{"type":27,"tag":28,"props":282,"children":283},{},[284],{"type":32,"value":285},"这类信息如果不显式呈现，用户很容易把“表格行为不可预测”误认为系统出错。",{"type":27,"tag":75,"props":287,"children":289},{"id":288},"批量操作区不要默认常驻而要和风险等级匹配",[290],{"type":32,"value":291},"批量操作区不要默认常驻，而要和风险等级匹配",{"type":27,"tag":28,"props":293,"children":294},{},[295],{"type":32,"value":296},"对高频后台来说，批量操作很重要，但它不该永远抢占界面。",{"type":27,"tag":28,"props":298,"children":299},{},[300],{"type":32,"value":301},"一个更合理的规则是：",{"type":27,"tag":87,"props":303,"children":304},{},[305,310,315],{"type":27,"tag":91,"props":306,"children":307},{},[308],{"type":32,"value":309},"默认隐藏批量操作区",{"type":27,"tag":91,"props":311,"children":312},{},[313],{"type":32,"value":314},"只有当用户选中行后才显示",{"type":27,"tag":91,"props":316,"children":317},{},[318],{"type":32,"value":319},"危险操作必须展示影响数量与不可逆说明",{"type":27,"tag":28,"props":321,"children":322},{},[323],{"type":32,"value":324},"例如“批量删除 32 条记录”，应同时告诉用户：",{"type":27,"tag":87,"props":326,"children":327},{},[328,333,338],{"type":27,"tag":91,"props":329,"children":330},{},[331],{"type":32,"value":332},"当前选中数量",{"type":27,"tag":91,"props":334,"children":335},{},[336],{"type":32,"value":337},"是否可恢复",{"type":27,"tag":91,"props":339,"children":340},{},[341],{"type":32,"value":342},"是否影响下游对象",{"type":27,"tag":28,"props":344,"children":345},{},[346],{"type":32,"value":347},"批量操作不是按钮堆叠，而是风险沟通。",{"type":27,"tag":75,"props":349,"children":351},{"id":350},"空态加载态错误态必须从一开始就设计",[352],{"type":32,"value":353},"空态、加载态、错误态必须从一开始就设计",{"type":27,"tag":28,"props":355,"children":356},{},[357],{"type":32,"value":358},"很多表格组件只有“有数据时”的设计稿，结果一到真实业务就暴露问题。",{"type":27,"tag":28,"props":360,"children":361},{},[362],{"type":32,"value":363},"建议至少定义 5 类状态：",{"type":27,"tag":365,"props":366,"children":367},"ol",{},[368,373,378,383,388],{"type":27,"tag":91,"props":369,"children":370},{},[371],{"type":32,"value":372},"首次加载",{"type":27,"tag":91,"props":374,"children":375},{},[376],{"type":32,"value":377},"有数据成功态",{"type":27,"tag":91,"props":379,"children":380},{},[381],{"type":32,"value":382},"空数据态",{"type":27,"tag":91,"props":384,"children":385},{},[386],{"type":32,"value":387},"筛选后无结果态",{"type":27,"tag":91,"props":389,"children":390},{},[391],{"type":32,"value":392},"请求失败态",{"type":27,"tag":28,"props":394,"children":395},{},[396],{"type":32,"value":397},"其中最容易被忽略的是“筛选后无结果”和“系统错误”。这两种场景给用户的动作建议完全不同，不能共用一套提示。",{"type":27,"tag":75,"props":399,"children":401},{"id":400},"失败案例把所有复杂能力都塞进一个-datatable",[402],{"type":32,"value":403},"失败案例：把所有复杂能力都塞进一个 DataTable",{"type":27,"tag":28,"props":405,"children":406},{},[407],{"type":32,"value":408},"一个典型翻车场景是：",{"type":27,"tag":87,"props":410,"children":411},{},[412,424,429],{"type":27,"tag":91,"props":413,"children":414},{},[415,417],{"type":32,"value":416},"所有业务线都复用同一个 ",{"type":27,"tag":418,"props":419,"children":421},"code",{"className":420},[],[422],{"type":32,"value":423},"DataTable",{"type":27,"tag":91,"props":425,"children":426},{},[427],{"type":32,"value":428},"组件同时支持本地排序、服务端排序、无限滚动、行编辑、树表格、拖拽、内嵌表单",{"type":27,"tag":91,"props":430,"children":431},{},[432],{"type":32,"value":433},"文档越写越长，但调用方越来越难配对",{"type":27,"tag":28,"props":435,"children":436},{},[437],{"type":32,"value":438},"最后结果通常是：",{"type":27,"tag":87,"props":440,"children":441},{},[442,447,452],{"type":27,"tag":91,"props":443,"children":444},{},[445],{"type":32,"value":446},"小需求也得接很多复杂参数",{"type":27,"tag":91,"props":448,"children":449},{},[450],{"type":32,"value":451},"测试范围失控",{"type":27,"tag":91,"props":453,"children":454},{},[455],{"type":32,"value":456},"组件维护者不敢改核心逻辑",{"type":27,"tag":28,"props":458,"children":459},{},[460],{"type":32,"value":461},"更稳的方式是把能力拆层：",{"type":27,"tag":87,"props":463,"children":464},{},[465,470,475],{"type":27,"tag":91,"props":466,"children":467},{},[468],{"type":32,"value":469},"基础表格：列渲染、选择、空态、分页",{"type":27,"tag":91,"props":471,"children":472},{},[473],{"type":32,"value":474},"扩展模块：筛选栏、批量操作栏、列设置",{"type":27,"tag":91,"props":476,"children":477},{},[478],{"type":32,"value":479},"业务组合：订单表、用户表、审核表各自封装",{"type":27,"tag":75,"props":481,"children":483},{"id":482},"表格组件要和性能策略一起设计",[484],{"type":32,"value":482},{"type":27,"tag":28,"props":486,"children":487},{},[488],{"type":32,"value":489},"表格只从设计视角看，很容易忽略两个现实：",{"type":27,"tag":87,"props":491,"children":492},{},[493,498],{"type":27,"tag":91,"props":494,"children":495},{},[496],{"type":32,"value":497},"数据量会持续膨胀",{"type":27,"tag":91,"props":499,"children":500},{},[501],{"type":32,"value":502},"用户会在弱网和低性能设备上使用",{"type":27,"tag":28,"props":504,"children":505},{},[506],{"type":32,"value":507},"因此规范里至少要明确：",{"type":27,"tag":87,"props":509,"children":510},{},[511,516,521],{"type":27,"tag":91,"props":512,"children":513},{},[514],{"type":32,"value":515},"什么时候启用虚拟滚动",{"type":27,"tag":91,"props":517,"children":518},{},[519],{"type":32,"value":520},"哪些列不允许放高开销渲染逻辑",{"type":27,"tag":91,"props":522,"children":523},{},[524],{"type":32,"value":525},"行展开、内嵌图表、实时刷新是否有上限",{"type":27,"tag":28,"props":527,"children":528},{},[529],{"type":32,"value":530},"如果这些边界不写进组件设计，最后会变成“视觉上支持，性能上崩溃”。",{"type":27,"tag":75,"props":532,"children":534},{"id":533},"一份可直接复用的检查清单",[535],{"type":32,"value":533},{"type":27,"tag":87,"props":537,"children":538},{},[539,544,549,554,559,564,569],{"type":27,"tag":91,"props":540,"children":541},{},[542],{"type":32,"value":543},"是否明确区分核心列、辅助列、次级列",{"type":27,"tag":91,"props":545,"children":546},{},[547],{"type":32,"value":548},"排序和筛选结果是否可见、可解释、可一键重置",{"type":27,"tag":91,"props":550,"children":551},{},[552],{"type":32,"value":553},"批量操作是否只在选中后出现，并清楚传达风险",{"type":27,"tag":91,"props":555,"children":556},{},[557],{"type":32,"value":558},"是否定义加载态、空态、无结果态、错误态",{"type":27,"tag":91,"props":560,"children":561},{},[562],{"type":32,"value":563},"是否为高数据量场景预留虚拟滚动或服务端分页策略",{"type":27,"tag":91,"props":565,"children":566},{},[567],{"type":32,"value":568},"组件 API 是否分清基础能力和业务扩展能力",{"type":27,"tag":91,"props":570,"children":571},{},[572],{"type":32,"value":573},"危险操作是否有确认与影响范围提示",{"type":27,"tag":75,"props":575,"children":577},{"id":576},"总结",[578],{"type":32,"value":576},{"type":27,"tag":28,"props":580,"children":581},{},[582],{"type":32,"value":583},"数据表格的成熟度，不体现在列数有多少，而体现在高密度交互下是否仍然清晰、稳定、可解释。先把任务路径、状态设计、风险沟通和性能边界写清楚，表格组件才会真正可复用。",{"type":27,"tag":28,"props":585,"children":586},{},[587],{"type":32,"value":588},"进一步阅读：",{"type":27,"tag":87,"props":590,"children":591},{},[592,599,606],{"type":27,"tag":91,"props":593,"children":594},{},[595],{"type":27,"tag":50,"props":596,"children":597},{"href":52},[598],{"type":32,"value":55},{"type":27,"tag":91,"props":600,"children":601},{},[602],{"type":27,"tag":50,"props":603,"children":604},{"href":68},[605],{"type":32,"value":71},{"type":27,"tag":91,"props":607,"children":608},{},[609],{"type":27,"tag":50,"props":610,"children":611},{"href":60},[612],{"type":32,"value":63},{"title":7,"searchDepth":614,"depth":614,"links":615},3,[616,618,619,620,621,622,623,624,625],{"id":77,"depth":617,"text":80},2,{"id":141,"depth":617,"text":144},{"id":244,"depth":617,"text":247},{"id":288,"depth":617,"text":291},{"id":350,"depth":617,"text":353},{"id":400,"depth":617,"text":403},{"id":482,"depth":617,"text":482},{"id":533,"depth":617,"text":533},{"id":576,"depth":617,"text":576},"markdown","content:topics:design:data-table-component-design-guide.md","content","topics/design/data-table-component-design-guide.md","topics/design/data-table-component-design-guide","md",[633,992,1294],{"_path":634,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":635,"description":636,"keywords":637,"image":643,"author":11,"date":644,"readingTime":645,"topic":5,"body":646,"_type":626,"_id":989,"_source":628,"_file":990,"_stem":991,"_extension":631},"/topics/design/button-component-design","按钮组件设计详解","学习按钮样式、交互状态、无障碍性和最佳实践",[638,639,640,641,642],"按钮设计","Button Component","交互状态","UI 组件","用户体验","/images/topics/button-design.jpg","2025-12-08",18,{"type":24,"children":647,"toc":971},[648,652,657,662,669,681,687,696,702,711,715,721,732,738,747,753,762,767,776,781,792,797,806,811,824,858,869,912,917],{"type":27,"tag":75,"props":649,"children":650},{"id":635},[651],{"type":32,"value":635},{"type":27,"tag":28,"props":653,"children":654},{},[655],{"type":32,"value":656},"按钮是 UI 中最重要的交互元素。优秀的按钮设计能够指导用户行为。",{"type":27,"tag":75,"props":658,"children":660},{"id":659},"按钮类型",[661],{"type":32,"value":659},{"type":27,"tag":663,"props":664,"children":666},"h3",{"id":665},"primary-button主按钮",[667],{"type":32,"value":668},"Primary Button（主按钮）",{"type":27,"tag":670,"props":671,"children":676},"pre",{"className":672,"code":674,"language":675,"meta":7},[673],"language-css",".btn-primary {\n  background-color: #0066cc;\n  color: #ffffff;\n  padding: 12px 24px;\n  border: none;\n  border-radius: 4px;\n  font-weight: 600;\n  font-size: 16px;\n  cursor: pointer;\n  transition: all 0.2s ease;\n}\n\n.btn-primary:hover {\n  background-color: #0052a3;\n  box-shadow: 0 4px 12px rgba(0, 102, 204, 0.2);\n}\n\n.btn-primary:active {\n  background-color: #003d7a;\n  transform: scale(0.98);\n}\n\n.btn-primary:disabled {\n  background-color: #cccccc;\n  cursor: not-allowed;\n  opacity: 0.6;\n}\n","css",[677],{"type":27,"tag":418,"props":678,"children":679},{"__ignoreMap":7},[680],{"type":32,"value":674},{"type":27,"tag":663,"props":682,"children":684},{"id":683},"secondary-button次按钮",[685],{"type":32,"value":686},"Secondary Button（次按钮）",{"type":27,"tag":670,"props":688,"children":691},{"className":689,"code":690,"language":675,"meta":7},[673],".btn-secondary {\n  background-color: transparent;\n  color: #0066cc;\n  border: 2px solid #0066cc;\n  padding: 10px 22px;\n  border-radius: 4px;\n  font-weight: 600;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.btn-secondary:hover {\n  background-color: rgba(0, 102, 204, 0.1);\n}\n\n.btn-secondary:active {\n  background-color: rgba(0, 102, 204, 0.2);\n}\n",[692],{"type":27,"tag":418,"props":693,"children":694},{"__ignoreMap":7},[695],{"type":32,"value":690},{"type":27,"tag":663,"props":697,"children":699},{"id":698},"danger-button危险按钮",[700],{"type":32,"value":701},"Danger Button（危险按钮）",{"type":27,"tag":670,"props":703,"children":706},{"className":704,"code":705,"language":675,"meta":7},[673],".btn-danger {\n  background-color: #cc0000;\n  color: #ffffff;\n  padding: 12px 24px;\n  border-radius: 4px;\n  cursor: pointer;\n  font-weight: 600;\n}\n\n.btn-danger:hover {\n  background-color: #990000;\n  box-shadow: 0 4px 12px rgba(204, 0, 0, 0.2);\n}\n",[707],{"type":27,"tag":418,"props":708,"children":709},{"__ignoreMap":7},[710],{"type":32,"value":705},{"type":27,"tag":75,"props":712,"children":713},{"id":640},[714],{"type":32,"value":640},{"type":27,"tag":663,"props":716,"children":718},{"id":717},"loading-状态",[719],{"type":32,"value":720},"Loading 状态",{"type":27,"tag":670,"props":722,"children":727},{"className":723,"code":725,"language":726,"meta":7},[724],"language-jsx","import { useState } from 'react';\n\nfunction Button({ children, onClick, loading, ...props }) {\n  const [isLoading, setIsLoading] = useState(false);\n  \n  const handleClick = async () => {\n    setIsLoading(true);\n    try {\n      await onClick();\n    } finally {\n      setIsLoading(false);\n    }\n  };\n  \n  return (\n    \u003Cbutton\n      onClick={handleClick}\n      disabled={isLoading || loading}\n      aria-busy={isLoading || loading}\n      {...props}\n    >\n      {isLoading ? (\n        \u003C>\n          \u003Cspan className=\"spinner\" aria-hidden=\"true\">\u003C/span>\n          {children}\n        \u003C/>\n      ) : (\n        children\n      )}\n    \u003C/button>\n  );\n}\n","jsx",[728],{"type":27,"tag":418,"props":729,"children":730},{"__ignoreMap":7},[731],{"type":32,"value":725},{"type":27,"tag":663,"props":733,"children":735},{"id":734},"disabled-状态",[736],{"type":32,"value":737},"Disabled 状态",{"type":27,"tag":670,"props":739,"children":742},{"className":740,"code":741,"language":675,"meta":7},[673],".btn:disabled {\n  opacity: 0.5;\n  cursor: not-allowed;\n  background-color: #cccccc;\n  color: #999999;\n}\n\n/* 禁用状态下隐藏指针光标 */\n.btn:disabled:hover {\n  box-shadow: none;\n  transform: none;\n}\n",[743],{"type":27,"tag":418,"props":744,"children":745},{"__ignoreMap":7},[746],{"type":32,"value":741},{"type":27,"tag":663,"props":748,"children":750},{"id":749},"focus-状态",[751],{"type":32,"value":752},"Focus 状态",{"type":27,"tag":670,"props":754,"children":757},{"className":755,"code":756,"language":675,"meta":7},[673],".btn:focus {\n  outline: none;\n  box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1),\n              0 0 0 5px #0066cc;\n}\n\n/* 键盘导航焦点 */\n.btn:focus-visible {\n  outline: 2px solid #0066cc;\n  outline-offset: 2px;\n}\n",[758],{"type":27,"tag":418,"props":759,"children":760},{"__ignoreMap":7},[761],{"type":32,"value":756},{"type":27,"tag":75,"props":763,"children":765},{"id":764},"按钮大小",[766],{"type":32,"value":764},{"type":27,"tag":670,"props":768,"children":771},{"className":769,"code":770,"language":675,"meta":7},[673],"/* 小按钮 */\n.btn-sm {\n  padding: 6px 12px;\n  font-size: 12px;\n  min-height: 32px;\n  min-width: 32px;\n}\n\n/* 中等按钮（默认） */\n.btn-md {\n  padding: 12px 24px;\n  font-size: 16px;\n  min-height: 44px;\n  min-width: 44px;\n}\n\n/* 大按钮 */\n.btn-lg {\n  padding: 16px 32px;\n  font-size: 18px;\n  min-height: 56px;\n  min-width: 56px;\n}\n\n/* 全宽按钮 */\n.btn-block {\n  width: 100%;\n  display: block;\n}\n",[772],{"type":27,"tag":418,"props":773,"children":774},{"__ignoreMap":7},[775],{"type":32,"value":770},{"type":27,"tag":75,"props":777,"children":779},{"id":778},"无障碍性",[780],{"type":32,"value":778},{"type":27,"tag":670,"props":782,"children":787},{"className":783,"code":785,"language":786,"meta":7},[784],"language-html","\u003C!-- 语义正确 -->\n\u003Cbutton type=\"submit\" aria-label=\"提交表单\">\n  提交\n\u003C/button>\n\n\u003C!-- 加载状态 -->\n\u003Cbutton aria-busy=\"true\" disabled>\n  \u003Cspan aria-hidden=\"true\" class=\"spinner\">\u003C/span>\n  加载中...\n\u003C/button>\n\n\u003C!-- 图标按钮 -->\n\u003Cbutton aria-label=\"关闭\">\n  \u003Csvg aria-hidden=\"true\" width=\"24\" height=\"24\">\n    \u003Cline x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n    \u003Cline x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n  \u003C/svg>\n\u003C/button>\n\n\u003C!-- 切换按钮 -->\n\u003Cbutton aria-pressed=\"false\" aria-label=\"点赞\">\n  ♥\n\u003C/button>\n","html",[788],{"type":27,"tag":418,"props":789,"children":790},{"__ignoreMap":7},[791],{"type":32,"value":785},{"type":27,"tag":75,"props":793,"children":795},{"id":794},"完整组件示例",[796],{"type":32,"value":794},{"type":27,"tag":670,"props":798,"children":801},{"className":799,"code":800,"language":726,"meta":7},[724],"const Button = React.forwardRef((\n  {\n    children,\n    variant = 'primary',\n    size = 'md',\n    loading = false,\n    disabled = false,\n    icon,\n    className,\n    ...props\n  },\n  ref\n) => {\n  return (\n    \u003Cbutton\n      ref={ref}\n      className={`btn btn-${variant} btn-${size} ${className}`}\n      disabled={disabled || loading}\n      aria-busy={loading}\n      {...props}\n    >\n      {icon && \u003Cspan className=\"btn-icon\" aria-hidden=\"true\">{icon}\u003C/span>}\n      {loading ? (\n        \u003C>\n          \u003Cspan className=\"spinner\" aria-hidden=\"true\">\u003C/span>\n          {children}\n        \u003C/>\n      ) : (\n        children\n      )}\n    \u003C/button>\n  );\n});\n\nButton.displayName = 'Button';\n",[802],{"type":27,"tag":418,"props":803,"children":804},{"__ignoreMap":7},[805],{"type":32,"value":800},{"type":27,"tag":75,"props":807,"children":809},{"id":808},"最佳实践",[810],{"type":32,"value":808},{"type":27,"tag":28,"props":812,"children":813},{},[814,816,822],{"type":32,"value":815},"✅ ",{"type":27,"tag":817,"props":818,"children":819},"strong",{},[820],{"type":32,"value":821},"应该做的事",{"type":32,"value":823},":",{"type":27,"tag":87,"props":825,"children":826},{},[827,832,837,848,853],{"type":27,"tag":91,"props":828,"children":829},{},[830],{"type":32,"value":831},"最小触摸目标 44x44px",{"type":27,"tag":91,"props":833,"children":834},{},[835],{"type":32,"value":836},"清晰的视觉反馈",{"type":27,"tag":91,"props":838,"children":839},{},[840,842],{"type":32,"value":841},"使用语义 HTML ",{"type":27,"tag":418,"props":843,"children":845},{"className":844},[],[846],{"type":32,"value":847},"\u003Cbutton>",{"type":27,"tag":91,"props":849,"children":850},{},[851],{"type":32,"value":852},"提供加载状态反馈",{"type":27,"tag":91,"props":854,"children":855},{},[856],{"type":32,"value":857},"支持键盘导航",{"type":27,"tag":28,"props":859,"children":860},{},[861,863,868],{"type":32,"value":862},"❌ ",{"type":27,"tag":817,"props":864,"children":865},{},[866],{"type":32,"value":867},"不应该做的事",{"type":32,"value":823},{"type":27,"tag":87,"props":870,"children":871},{},[872,885,890,895,900],{"type":27,"tag":91,"props":873,"children":874},{},[875,877,883],{"type":32,"value":876},"使用 ",{"type":27,"tag":418,"props":878,"children":880},{"className":879},[],[881],{"type":32,"value":882},"\u003Cdiv>",{"type":32,"value":884}," 模拟按钮",{"type":27,"tag":91,"props":886,"children":887},{},[888],{"type":32,"value":889},"隐藏焦点指示器",{"type":27,"tag":91,"props":891,"children":892},{},[893],{"type":32,"value":894},"过多的按钮样式",{"type":27,"tag":91,"props":896,"children":897},{},[898],{"type":32,"value":899},"忽视禁用状态",{"type":27,"tag":91,"props":901,"children":902},{},[903,904,910],{"type":32,"value":876},{"type":27,"tag":418,"props":905,"children":907},{"className":906},[],[908],{"type":32,"value":909},"\u003Ca>",{"type":32,"value":911}," 代替按钮",{"type":27,"tag":75,"props":913,"children":915},{"id":914},"测试清单",[916],{"type":32,"value":914},{"type":27,"tag":87,"props":918,"children":921},{"className":919},[920],"contains-task-list",[922,935,944,953,962],{"type":27,"tag":91,"props":923,"children":926},{"className":924},[925],"task-list-item",[927,933],{"type":27,"tag":928,"props":929,"children":932},"input",{"disabled":930,"type":931},true,"checkbox",[],{"type":32,"value":934}," 在各种浏览器中测试",{"type":27,"tag":91,"props":936,"children":938},{"className":937},[925],[939,942],{"type":27,"tag":928,"props":940,"children":941},{"disabled":930,"type":931},[],{"type":32,"value":943}," 验证键盘导航",{"type":27,"tag":91,"props":945,"children":947},{"className":946},[925],[948,951],{"type":27,"tag":928,"props":949,"children":950},{"disabled":930,"type":931},[],{"type":32,"value":952}," 检查色彩对比度",{"type":27,"tag":91,"props":954,"children":956},{"className":955},[925],[957,960],{"type":27,"tag":928,"props":958,"children":959},{"disabled":930,"type":931},[],{"type":32,"value":961}," 测试触摸设备",{"type":27,"tag":91,"props":963,"children":965},{"className":964},[925],[966,969],{"type":27,"tag":928,"props":967,"children":968},{"disabled":930,"type":931},[],{"type":32,"value":970}," 屏幕阅读器兼容性",{"title":7,"searchDepth":614,"depth":614,"links":972},[973,974,979,984,985,986,987,988],{"id":635,"depth":617,"text":635},{"id":659,"depth":617,"text":659,"children":975},[976,977,978],{"id":665,"depth":614,"text":668},{"id":683,"depth":614,"text":686},{"id":698,"depth":614,"text":701},{"id":640,"depth":617,"text":640,"children":980},[981,982,983],{"id":717,"depth":614,"text":720},{"id":734,"depth":614,"text":737},{"id":749,"depth":614,"text":752},{"id":764,"depth":617,"text":764},{"id":778,"depth":617,"text":778},{"id":794,"depth":617,"text":794},{"id":808,"depth":617,"text":808},{"id":914,"depth":617,"text":914},"content:topics:design:button-component-design.md","topics/design/button-component-design.md","topics/design/button-component-design",{"_path":993,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":994,"description":995,"keywords":996,"image":1001,"author":11,"date":644,"readingTime":1002,"topic":5,"body":1003,"_type":626,"_id":1291,"_source":628,"_file":1292,"_stem":1293,"_extension":631},"/topics/design/dark-mode-design","暗黑模式设计完整方案","学习暗黑模式实现、色彩方案、对比度管理和最佳实践",[997,998,999,1000,642],"暗黑模式","Dark Mode","色彩系统","CSS 变量","/images/topics/dark-mode-design.jpg",20,{"type":24,"children":1004,"toc":1274},[1005,1009,1014,1019,1025,1034,1040,1049,1054,1060,1069,1075,1086,1092,1101,1106,1115,1120,1129,1134,1143,1147,1156,1184,1193,1221,1225],{"type":27,"tag":75,"props":1006,"children":1007},{"id":994},[1008],{"type":32,"value":994},{"type":27,"tag":28,"props":1010,"children":1011},{},[1012],{"type":32,"value":1013},"暗黑模式已成为现代应用的标准功能。它能够减少眼睛疲劳、节省电池、改善用户体验。",{"type":27,"tag":75,"props":1015,"children":1017},{"id":1016},"核心色彩系统",[1018],{"type":32,"value":1016},{"type":27,"tag":663,"props":1020,"children":1022},{"id":1021},"light-mode-配色",[1023],{"type":32,"value":1024},"Light Mode 配色",{"type":27,"tag":670,"props":1026,"children":1029},{"className":1027,"code":1028,"language":675,"meta":7},[673],":root {\n  /* Light Mode */\n  --bg-primary: #ffffff;\n  --bg-secondary: #f5f5f5;\n  --bg-tertiary: #efefef;\n  \n  --text-primary: #1a1a1a;\n  --text-secondary: #666666;\n  --text-tertiary: #999999;\n  \n  --border-color: #e0e0e0;\n  --divider-color: #f0f0f0;\n}\n",[1030],{"type":27,"tag":418,"props":1031,"children":1032},{"__ignoreMap":7},[1033],{"type":32,"value":1028},{"type":27,"tag":663,"props":1035,"children":1037},{"id":1036},"dark-mode-配色",[1038],{"type":32,"value":1039},"Dark Mode 配色",{"type":27,"tag":670,"props":1041,"children":1044},{"className":1042,"code":1043,"language":675,"meta":7},[673],"@media (prefers-color-scheme: dark) {\n  :root {\n    /* Dark Mode */\n    --bg-primary: #1a1a1a;\n    --bg-secondary: #2d2d2d;\n    --bg-tertiary: #3a3a3a;\n    \n    --text-primary: #ffffff;\n    --text-secondary: #e0e0e0;\n    --text-tertiary: #a0a0a0;\n    \n    --border-color: #404040;\n    --divider-color: #2a2a2a;\n  }\n}\n",[1045],{"type":27,"tag":418,"props":1046,"children":1047},{"__ignoreMap":7},[1048],{"type":32,"value":1043},{"type":27,"tag":75,"props":1050,"children":1052},{"id":1051},"实现方案",[1053],{"type":32,"value":1051},{"type":27,"tag":663,"props":1055,"children":1057},{"id":1056},"方案-1prefers-color-scheme",[1058],{"type":32,"value":1059},"方案 1：prefers-color-scheme",{"type":27,"tag":670,"props":1061,"children":1064},{"className":1062,"code":1063,"language":675,"meta":7},[673],"/* 自动跟随系统设置 */\n@media (prefers-color-scheme: light) {\n  :root {\n    --bg: #fff;\n    --text: #000;\n  }\n}\n\n@media (prefers-color-scheme: dark) {\n  :root {\n    --bg: #1a1a1a;\n    --text: #fff;\n  }\n}\n\nbody {\n  background: var(--bg);\n  color: var(--text);\n}\n",[1065],{"type":27,"tag":418,"props":1066,"children":1067},{"__ignoreMap":7},[1068],{"type":32,"value":1063},{"type":27,"tag":663,"props":1070,"children":1072},{"id":1071},"方案-2javascript-切换",[1073],{"type":32,"value":1074},"方案 2：JavaScript 切换",{"type":27,"tag":670,"props":1076,"children":1081},{"className":1077,"code":1079,"language":1080,"meta":7},[1078],"language-javascript","// 检测和切换暗黑模式\nfunction initDarkMode() {\n  const isDark = localStorage.getItem('darkMode') === 'true' ||\n                 window.matchMedia('(prefers-color-scheme: dark)').matches;\n  \n  if (isDark) {\n    document.documentElement.setAttribute('data-theme', 'dark');\n  }\n}\n\nfunction toggleDarkMode() {\n  const isDark = document.documentElement.getAttribute('data-theme') === 'dark';\n  const newTheme = isDark ? 'light' : 'dark';\n  \n  document.documentElement.setAttribute('data-theme', newTheme);\n  localStorage.setItem('darkMode', newTheme === 'dark');\n}\n\n// CSS 应用\nhtml[data-theme='light'] {\n  color-scheme: light;\n}\n\nhtml[data-theme='dark'] {\n  color-scheme: dark;\n}\n","javascript",[1082],{"type":27,"tag":418,"props":1083,"children":1084},{"__ignoreMap":7},[1085],{"type":32,"value":1079},{"type":27,"tag":663,"props":1087,"children":1089},{"id":1088},"方案-3css-variables-javascript",[1090],{"type":32,"value":1091},"方案 3：CSS Variables + JavaScript",{"type":27,"tag":670,"props":1093,"children":1096},{"className":1094,"code":1095,"language":1080,"meta":7},[1078],"const themes = {\n  light: {\n    '--bg-primary': '#ffffff',\n    '--text-primary': '#000000',\n    '--accent': '#0066cc',\n    '--border': '#e0e0e0',\n  },\n  dark: {\n    '--bg-primary': '#1a1a1a',\n    '--text-primary': '#ffffff',\n    '--accent': '#4da3ff',\n    '--border': '#404040',\n  },\n};\n\nfunction applyTheme(themeName) {\n  const theme = themes[themeName];\n  Object.entries(theme).forEach(([key, value]) => {\n    document.documentElement.style.setProperty(key, value);\n  });\n  localStorage.setItem('theme', themeName);\n}\n",[1097],{"type":27,"tag":418,"props":1098,"children":1099},{"__ignoreMap":7},[1100],{"type":32,"value":1095},{"type":27,"tag":75,"props":1102,"children":1104},{"id":1103},"对比度管理",[1105],{"type":32,"value":1103},{"type":27,"tag":670,"props":1107,"children":1110},{"className":1108,"code":1109,"language":675,"meta":7},[673],"/* Light Mode 对比度 */\n:root {\n  --contrast-high: #000000;     /* 21:1 */\n  --contrast-medium: #333333;   /* 12.6:1 */\n  --contrast-low: #666666;      /* 5.1:1 */\n}\n\n/* Dark Mode 对比度 */\n@media (prefers-color-scheme: dark) {\n  :root {\n    --contrast-high: #ffffff;    /* 21:1 */\n    --contrast-medium: #e0e0e0;  /* 11.6:1 */\n    --contrast-low: #a0a0a0;     /* 4.5:1 */\n  }\n}\n\n/* 应用对比度 */\n.text-primary { color: var(--contrast-high); }\n.text-secondary { color: var(--contrast-medium); }\n.text-tertiary { color: var(--contrast-low); }\n",[1111],{"type":27,"tag":418,"props":1112,"children":1113},{"__ignoreMap":7},[1114],{"type":32,"value":1109},{"type":27,"tag":75,"props":1116,"children":1118},{"id":1117},"图片和图表处理",[1119],{"type":32,"value":1117},{"type":27,"tag":670,"props":1121,"children":1124},{"className":1122,"code":1123,"language":786,"meta":7},[784],"\u003C!-- 针对不同主题的图片 -->\n\u003Cpicture>\n  \u003Csource \n    media=\"(prefers-color-scheme: dark)\" \n    srcset=\"chart-dark.svg\"\n  />\n  \u003Cimg src=\"chart-light.svg\" alt=\"图表\" />\n\u003C/picture>\n\n\u003C!-- SVG 颜色适配 -->\n\u003Csvg class=\"icon\">\n  \u003Ccircle cx=\"50\" cy=\"50\" r=\"40\" fill=\"currentColor\" />\n\u003C/svg>\n\n\u003Cstyle>\n  .icon {\n    color: var(--text-primary);\n  }\n\u003C/style>\n",[1125],{"type":27,"tag":418,"props":1126,"children":1127},{"__ignoreMap":7},[1128],{"type":32,"value":1123},{"type":27,"tag":75,"props":1130,"children":1132},{"id":1131},"完整示例",[1133],{"type":32,"value":1131},{"type":27,"tag":670,"props":1135,"children":1138},{"className":1136,"code":1137,"language":726,"meta":7},[724],"import { useState, useEffect } from 'react';\n\nfunction ThemeProvider({ children }) {\n  const [theme, setTheme] = useState('light');\n  const [mounted, setMounted] = useState(false);\n  \n  useEffect(() => {\n    setMounted(true);\n    \n    // 获取保存的主题或系统偏好\n    const savedTheme = localStorage.getItem('theme');\n    const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches \n      ? 'dark' \n      : 'light';\n    \n    const initialTheme = savedTheme || systemTheme;\n    setTheme(initialTheme);\n    document.documentElement.setAttribute('data-theme', initialTheme);\n  }, []);\n  \n  const toggleTheme = () => {\n    const newTheme = theme === 'light' ? 'dark' : 'light';\n    setTheme(newTheme);\n    localStorage.setItem('theme', newTheme);\n    document.documentElement.setAttribute('data-theme', newTheme);\n  };\n  \n  // 防止闪烁\n  if (!mounted) {\n    return null;\n  }\n  \n  return (\n    \u003CThemeContext.Provider value={{ theme, toggleTheme }}>\n      {children}\n      \u003CThemeToggle theme={theme} onChange={toggleTheme} />\n    \u003C/ThemeContext.Provider>\n  );\n}\n\nfunction ThemeToggle({ theme, onChange }) {\n  return (\n    \u003Cbutton \n      onClick={onChange}\n      aria-label={`切换到${theme === 'light' ? '暗黑' : '亮色'}模式`}\n    >\n      {theme === 'light' ? '🌙' : '☀️'}\n    \u003C/button>\n  );\n}\n",[1139],{"type":27,"tag":418,"props":1140,"children":1141},{"__ignoreMap":7},[1142],{"type":32,"value":1137},{"type":27,"tag":75,"props":1144,"children":1145},{"id":808},[1146],{"type":32,"value":808},{"type":27,"tag":28,"props":1148,"children":1149},{},[1150,1151,1155],{"type":32,"value":815},{"type":27,"tag":817,"props":1152,"children":1153},{},[1154],{"type":32,"value":821},{"type":32,"value":823},{"type":27,"tag":87,"props":1157,"children":1158},{},[1159,1164,1169,1174,1179],{"type":27,"tag":91,"props":1160,"children":1161},{},[1162],{"type":32,"value":1163},"支持系统偏好",{"type":27,"tag":91,"props":1165,"children":1166},{},[1167],{"type":32,"value":1168},"提供手动切换选项",{"type":27,"tag":91,"props":1170,"children":1171},{},[1172],{"type":32,"value":1173},"确保足够的对比度",{"type":27,"tag":91,"props":1175,"children":1176},{},[1177],{"type":32,"value":1178},"优化图片和图表",{"type":27,"tag":91,"props":1180,"children":1181},{},[1182],{"type":32,"value":1183},"防止加载闪烁",{"type":27,"tag":28,"props":1185,"children":1186},{},[1187,1188,1192],{"type":32,"value":862},{"type":27,"tag":817,"props":1189,"children":1190},{},[1191],{"type":32,"value":867},{"type":32,"value":823},{"type":27,"tag":87,"props":1194,"children":1195},{},[1196,1201,1206,1211,1216],{"type":27,"tag":91,"props":1197,"children":1198},{},[1199],{"type":32,"value":1200},"强制单一模式",{"type":27,"tag":91,"props":1202,"children":1203},{},[1204],{"type":32,"value":1205},"忽视性能影响",{"type":27,"tag":91,"props":1207,"children":1208},{},[1209],{"type":32,"value":1210},"使用相同的颜色",{"type":27,"tag":91,"props":1212,"children":1213},{},[1214],{"type":32,"value":1215},"忘记保存用户偏好",{"type":27,"tag":91,"props":1217,"children":1218},{},[1219],{"type":32,"value":1220},"过度使用深色背景",{"type":27,"tag":75,"props":1222,"children":1223},{"id":914},[1224],{"type":32,"value":914},{"type":27,"tag":87,"props":1226,"children":1228},{"className":1227},[920],[1229,1238,1247,1256,1265],{"type":27,"tag":91,"props":1230,"children":1232},{"className":1231},[925],[1233,1236],{"type":27,"tag":928,"props":1234,"children":1235},{"disabled":930,"type":931},[],{"type":32,"value":1237}," 在浅色和深色模式下测试所有页面",{"type":27,"tag":91,"props":1239,"children":1241},{"className":1240},[925],[1242,1245],{"type":27,"tag":928,"props":1243,"children":1244},{"disabled":930,"type":931},[],{"type":32,"value":1246}," 检查颜色对比度符合 WCAG 标准",{"type":27,"tag":91,"props":1248,"children":1250},{"className":1249},[925],[1251,1254],{"type":27,"tag":928,"props":1252,"children":1253},{"disabled":930,"type":931},[],{"type":32,"value":1255}," 验证图片和图表在两种模式下清晰",{"type":27,"tag":91,"props":1257,"children":1259},{"className":1258},[925],[1260,1263],{"type":27,"tag":928,"props":1261,"children":1262},{"disabled":930,"type":931},[],{"type":32,"value":1264}," 测试主题切换的平滑性",{"type":27,"tag":91,"props":1266,"children":1268},{"className":1267},[925],[1269,1272],{"type":27,"tag":928,"props":1270,"children":1271},{"disabled":930,"type":931},[],{"type":32,"value":1273}," 检查用户偏好是否被保存",{"title":7,"searchDepth":614,"depth":614,"links":1275},[1276,1277,1281,1286,1287,1288,1289,1290],{"id":994,"depth":617,"text":994},{"id":1016,"depth":617,"text":1016,"children":1278},[1279,1280],{"id":1021,"depth":614,"text":1024},{"id":1036,"depth":614,"text":1039},{"id":1051,"depth":617,"text":1051,"children":1282},[1283,1284,1285],{"id":1056,"depth":614,"text":1059},{"id":1071,"depth":614,"text":1074},{"id":1088,"depth":614,"text":1091},{"id":1103,"depth":617,"text":1103},{"id":1117,"depth":617,"text":1117},{"id":1131,"depth":617,"text":1131},{"id":808,"depth":617,"text":808},{"id":914,"depth":617,"text":914},"content:topics:design:dark-mode-design.md","topics/design/dark-mode-design.md","topics/design/dark-mode-design",{"_path":1295,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1296,"description":1297,"keywords":1298,"image":1303,"author":1304,"date":644,"readingTime":1002,"topic":5,"body":1305,"_type":626,"_id":1570,"_source":628,"_file":1571,"_stem":1572,"_extension":631},"/topics/design/form-controls-design","表单控件设计规范","学习输入框、选择框、复选框等表单控件的设计和实现",[1299,1300,1301,1302,642],"表单设计","Form Controls","输入框","验证反馈","/images/topics/form-controls-design.jpg","AI Content Team",{"type":24,"children":1306,"toc":1556},[1307,1311,1316,1321,1326,1335,1340,1349,1353,1362,1367,1376,1381,1390,1395,1404,1409,1418,1422,1431,1457,1466,1494,1498],{"type":27,"tag":75,"props":1308,"children":1309},{"id":1296},[1310],{"type":32,"value":1296},{"type":27,"tag":28,"props":1312,"children":1313},{},[1314],{"type":32,"value":1315},"优秀的表单设计能够提高用户完成率和满意度。",{"type":27,"tag":75,"props":1317,"children":1319},{"id":1318},"输入框设计",[1320],{"type":32,"value":1318},{"type":27,"tag":663,"props":1322,"children":1324},{"id":1323},"基础文本输入",[1325],{"type":32,"value":1323},{"type":27,"tag":670,"props":1327,"children":1330},{"className":1328,"code":1329,"language":675,"meta":7},[673],".input {\n  width: 100%;\n  padding: 12px 16px;\n  font-size: 16px;\n  border: 2px solid #e0e0e0;\n  border-radius: 4px;\n  font-family: inherit;\n  transition: border-color 0.2s;\n}\n\n.input:hover {\n  border-color: #bdbdbd;\n}\n\n.input:focus {\n  outline: none;\n  border-color: #0066cc;\n  box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);\n}\n\n.input:disabled {\n  background-color: #f5f5f5;\n  color: #999999;\n  cursor: not-allowed;\n}\n\n.input.error {\n  border-color: #cc0000;\n}\n\n.input.success {\n  border-color: #00cc00;\n}\n",[1331],{"type":27,"tag":418,"props":1332,"children":1333},{"__ignoreMap":7},[1334],{"type":32,"value":1329},{"type":27,"tag":663,"props":1336,"children":1338},{"id":1337},"标签和提示",[1339],{"type":32,"value":1337},{"type":27,"tag":670,"props":1341,"children":1344},{"className":1342,"code":1343,"language":786,"meta":7},[784],"\u003Cdiv class=\"form-group\">\n  \u003Clabel for=\"email\" class=\"form-label\">\n    邮箱地址 \u003Cspan class=\"required\">*\u003C/span>\n  \u003C/label>\n  \u003Cinput\n    id=\"email\"\n    type=\"email\"\n    placeholder=\"user@example.com\"\n    class=\"input\"\n    aria-describedby=\"email-hint\"\n  />\n  \u003Cp id=\"email-hint\" class=\"form-hint\">\n    我们永远不会分享你的邮箱\n  \u003C/p>\n\u003C/div>\n",[1345],{"type":27,"tag":418,"props":1346,"children":1347},{"__ignoreMap":7},[1348],{"type":32,"value":1343},{"type":27,"tag":75,"props":1350,"children":1351},{"id":1302},[1352],{"type":32,"value":1302},{"type":27,"tag":670,"props":1354,"children":1357},{"className":1355,"code":1356,"language":726,"meta":7},[724],"function FormInput({ label, error, success, helperText, value, onChange, ...props }) {\n  return (\n    \u003Cdiv className=\"form-group\">\n      \u003Clabel className=\"form-label\">{label}\u003C/label>\n      \u003Cinput\n        className={`input ${\n          error ? 'error' : success ? 'success' : ''\n        }`}\n        value={value}\n        onChange={onChange}\n        {...props}\n      />\n      {error && (\n        \u003Cp className=\"form-error\" role=\"alert\">\n          {error}\n        \u003C/p>\n      )}\n      {success && (\n        \u003Cp className=\"form-success\">\n          ✓ {success}\n        \u003C/p>\n      )}\n      {helperText && (\n        \u003Cp className=\"form-hint\">{helperText}\u003C/p>\n      )}\n    \u003C/div>\n  );\n}\n",[1358],{"type":27,"tag":418,"props":1359,"children":1360},{"__ignoreMap":7},[1361],{"type":32,"value":1356},{"type":27,"tag":75,"props":1363,"children":1365},{"id":1364},"选择框设计",[1366],{"type":32,"value":1364},{"type":27,"tag":670,"props":1368,"children":1371},{"className":1369,"code":1370,"language":675,"meta":7},[673],".select {\n  appearance: none;\n  width: 100%;\n  padding: 12px 16px;\n  border: 2px solid #e0e0e0;\n  border-radius: 4px;\n  background-image: url('data:image/svg+xml;...');\n  background-repeat: no-repeat;\n  background-position: right 12px center;\n  padding-right: 40px;\n  font-size: 16px;\n  cursor: pointer;\n}\n\n.select:hover {\n  border-color: #bdbdbd;\n}\n\n.select:focus {\n  outline: none;\n  border-color: #0066cc;\n  box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);\n}\n",[1372],{"type":27,"tag":418,"props":1373,"children":1374},{"__ignoreMap":7},[1375],{"type":32,"value":1370},{"type":27,"tag":75,"props":1377,"children":1379},{"id":1378},"复选框和单选按钮",[1380],{"type":32,"value":1378},{"type":27,"tag":670,"props":1382,"children":1385},{"className":1383,"code":1384,"language":675,"meta":7},[673],".checkbox-group {\n  display: flex;\n  gap: 12px;\n  align-items: center;\n}\n\n.checkbox-input {\n  width: 20px;\n  height: 20px;\n  cursor: pointer;\n  accent-color: #0066cc;\n}\n\n.checkbox-label {\n  cursor: pointer;\n  user-select: none;\n}\n\n/* 自定义复选框 */\n.custom-checkbox {\n  appearance: none;\n  width: 20px;\n  height: 20px;\n  border: 2px solid #e0e0e0;\n  border-radius: 4px;\n  cursor: pointer;\n  background-color: white;\n  transition: all 0.2s;\n}\n\n.custom-checkbox:checked {\n  background-color: #0066cc;\n  border-color: #0066cc;\n  background-image: url('data:image/svg+xml;...');\n}\n\n.custom-checkbox:focus {\n  box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);\n}\n",[1386],{"type":27,"tag":418,"props":1387,"children":1388},{"__ignoreMap":7},[1389],{"type":32,"value":1384},{"type":27,"tag":75,"props":1391,"children":1393},{"id":1392},"文本区域",[1394],{"type":32,"value":1392},{"type":27,"tag":670,"props":1396,"children":1399},{"className":1397,"code":1398,"language":675,"meta":7},[673],".textarea {\n  width: 100%;\n  min-height: 120px;\n  padding: 12px 16px;\n  border: 2px solid #e0e0e0;\n  border-radius: 4px;\n  font-family: inherit;\n  font-size: 16px;\n  resize: vertical;\n  transition: border-color 0.2s;\n}\n\n.textarea:focus {\n  outline: none;\n  border-color: #0066cc;\n  box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);\n}\n",[1400],{"type":27,"tag":418,"props":1401,"children":1402},{"__ignoreMap":7},[1403],{"type":32,"value":1398},{"type":27,"tag":75,"props":1405,"children":1407},{"id":1406},"完整表单示例",[1408],{"type":32,"value":1406},{"type":27,"tag":670,"props":1410,"children":1413},{"className":1411,"code":1412,"language":726,"meta":7},[724],"function SignupForm() {\n  const [formData, setFormData] = useState({\n    name: '',\n    email: '',\n    password: '',\n    confirmPassword: '',\n    subscribe: false,\n    terms: false,\n  });\n  \n  const [errors, setErrors] = useState({});\n  const [touched, setTouched] = useState({});\n  const [submitted, setSubmitted] = useState(false);\n  \n  const handleChange = (e) => {\n    const { name, value, type, checked } = e.target;\n    setFormData(prev => ({\n      ...prev,\n      [name]: type === 'checkbox' ? checked : value,\n    }));\n    \n    // 实时验证\n    if (touched[name]) {\n      validateField(name, type === 'checkbox' ? checked : value);\n    }\n  };\n  \n  const handleBlur = (e) => {\n    const { name } = e.target;\n    setTouched(prev => ({ ...prev, [name]: true }));\n    validateField(name, formData[name]);\n  };\n  \n  const validateField = (name, value) => {\n    const newErrors = { ...errors };\n    \n    switch (name) {\n      case 'name':\n        if (!value) newErrors.name = '名字不能为空';\n        else delete newErrors.name;\n        break;\n      case 'email':\n        if (!value) newErrors.email = '邮箱不能为空';\n        else if (!/^[^\\\\s@]+@[^\\\\s@]+\\\\.[^\\\\s@]+$/.test(value)) {\n          newErrors.email = '请输入有效的邮箱';\n        } else {\n          delete newErrors.email;\n        }\n        break;\n      case 'password':\n        if (!value) newErrors.password = '密码不能为空';\n        else if (value.length \u003C 8) newErrors.password = '密码至少 8 位';\n        else delete newErrors.password;\n        break;\n      case 'confirmPassword':\n        if (value !== formData.password) {\n          newErrors.confirmPassword = '两次密码输入不一致';\n        } else {\n          delete newErrors.confirmPassword;\n        }\n        break;\n      case 'terms':\n        if (!value) newErrors.terms = '必须同意服务条款';\n        else delete newErrors.terms;\n        break;\n      default:\n        break;\n    }\n    \n    setErrors(newErrors);\n  };\n  \n  const validate = () => {\n    const newErrors = {};\n    \n    if (!formData.name) newErrors.name = '名字不能为空';\n    if (!formData.email) newErrors.email = '邮箱不能为空';\n    if (formData.password.length \u003C 8) newErrors.password = '密码至少 8 位';\n    if (formData.password !== formData.confirmPassword) {\n      newErrors.confirmPassword = '两次密码输入不一致';\n    }\n    if (!formData.terms) newErrors.terms = '必须同意服务条款';\n    \n    return newErrors;\n  };\n  \n  const handleSubmit = async (e) => {\n    e.preventDefault();\n    \n    // 标记所有字段已触碰\n    setTouched({\n      name: true,\n      email: true,\n      password: true,\n      confirmPassword: true,\n      terms: true,\n    });\n    \n    const newErrors = validate();\n    \n    if (Object.keys(newErrors).length === 0) {\n      setSubmitted(true);\n      // 提交表单\n      console.log('Form submitted:', formData);\n      // 重置表单\n      setFormData({\n        name: '',\n        email: '',\n        password: '',\n        confirmPassword: '',\n        subscribe: false,\n        terms: false,\n      });\n    } else {\n      setErrors(newErrors);\n    }\n  };\n  \n  return (\n    \u003Cform onSubmit={handleSubmit} noValidate>\n      {submitted && (\n        \u003Cdiv className=\"form-success-message\" role=\"alert\">\n          注册成功！\n        \u003C/div>\n      )}\n      \n      \u003CFormInput\n        label=\"姓名\"\n        name=\"name\"\n        value={formData.name}\n        onChange={handleChange}\n        onBlur={handleBlur}\n        error={touched.name && errors.name}\n        helperText=\"请输入你的全名\"\n      />\n      \n      \u003CFormInput\n        label=\"邮箱\"\n        name=\"email\"\n        type=\"email\"\n        value={formData.email}\n        onChange={handleChange}\n        onBlur={handleBlur}\n        error={touched.email && errors.email}\n      />\n      \n      \u003CFormInput\n        label=\"密码\"\n        name=\"password\"\n        type=\"password\"\n        value={formData.password}\n        onChange={handleChange}\n        onBlur={handleBlur}\n        error={touched.password && errors.password}\n        helperText=\"至少 8 个字符\"\n      />\n      \n      \u003CFormInput\n        label=\"确认密码\"\n        name=\"confirmPassword\"\n        type=\"password\"\n        value={formData.confirmPassword}\n        onChange={handleChange}\n        onBlur={handleBlur}\n        error={touched.confirmPassword && errors.confirmPassword}\n      />\n      \n      \u003Cdiv className=\"form-group\">\n        \u003Clabel className=\"checkbox-label\">\n          \u003Cinput\n            type=\"checkbox\"\n            name=\"subscribe\"\n            checked={formData.subscribe}\n            onChange={handleChange}\n            className=\"checkbox-input\"\n          />\n          订阅我们的新闻通讯\n        \u003C/label>\n      \u003C/div>\n      \n      \u003Cdiv className=\"form-group\">\n        \u003Clabel className=\"checkbox-label\">\n          \u003Cinput\n            type=\"checkbox\"\n            name=\"terms\"\n            checked={formData.terms}\n            onChange={handleChange}\n            onBlur={handleBlur}\n            className=\"checkbox-input\"\n          />\n          我同意\n          \u003Ca href=\"/terms\" target=\"_blank\" rel=\"noopener noreferrer\">\n            服务条款\n          \u003C/a>\n          和\n          \u003Ca href=\"/privacy\" target=\"_blank\" rel=\"noopener noreferrer\">\n            隐私政策\n          \u003C/a>\n        \u003C/label>\n        {touched.terms && errors.terms && (\n          \u003Cp className=\"form-error\">{errors.terms}\u003C/p>\n        )}\n      \u003C/div>\n      \n      \u003Cbutton type=\"submit\" className=\"btn btn-primary btn-block\">\n        注册\n      \u003C/button>\n    \u003C/form>\n  );\n}\n",[1414],{"type":27,"tag":418,"props":1415,"children":1416},{"__ignoreMap":7},[1417],{"type":32,"value":1412},{"type":27,"tag":75,"props":1419,"children":1420},{"id":808},[1421],{"type":32,"value":808},{"type":27,"tag":28,"props":1423,"children":1424},{},[1425,1426,1430],{"type":32,"value":815},{"type":27,"tag":817,"props":1427,"children":1428},{},[1429],{"type":32,"value":821},{"type":32,"value":823},{"type":27,"tag":87,"props":1432,"children":1433},{},[1434,1439,1444,1449,1453],{"type":27,"tag":91,"props":1435,"children":1436},{},[1437],{"type":32,"value":1438},"使用正确的输入类型",{"type":27,"tag":91,"props":1440,"children":1441},{},[1442],{"type":32,"value":1443},"提供实时验证反馈",{"type":27,"tag":91,"props":1445,"children":1446},{},[1447],{"type":32,"value":1448},"清晰的标签和提示",{"type":27,"tag":91,"props":1450,"children":1451},{},[1452],{"type":32,"value":831},{"type":27,"tag":91,"props":1454,"children":1455},{},[1456],{"type":32,"value":857},{"type":27,"tag":28,"props":1458,"children":1459},{},[1460,1461,1465],{"type":32,"value":862},{"type":27,"tag":817,"props":1462,"children":1463},{},[1464],{"type":32,"value":867},{"type":32,"value":823},{"type":27,"tag":87,"props":1467,"children":1468},{},[1469,1474,1479,1484,1489],{"type":27,"tag":91,"props":1470,"children":1471},{},[1472],{"type":32,"value":1473},"隐藏标签",{"type":27,"tag":91,"props":1475,"children":1476},{},[1477],{"type":32,"value":1478},"过度使用占位符",{"type":27,"tag":91,"props":1480,"children":1481},{},[1482],{"type":32,"value":1483},"验证后立即提交",{"type":27,"tag":91,"props":1485,"children":1486},{},[1487],{"type":32,"value":1488},"忽视无障碍性",{"type":27,"tag":91,"props":1490,"children":1491},{},[1492],{"type":32,"value":1493},"复杂的验证规则",{"type":27,"tag":75,"props":1495,"children":1496},{"id":914},[1497],{"type":32,"value":914},{"type":27,"tag":87,"props":1499,"children":1501},{"className":1500},[920],[1502,1511,1520,1529,1538,1547],{"type":27,"tag":91,"props":1503,"children":1505},{"className":1504},[925],[1506,1509],{"type":27,"tag":928,"props":1507,"children":1508},{"disabled":930,"type":931},[],{"type":32,"value":1510}," 所有控件都可用键盘导航",{"type":27,"tag":91,"props":1512,"children":1514},{"className":1513},[925],[1515,1518],{"type":27,"tag":928,"props":1516,"children":1517},{"disabled":930,"type":931},[],{"type":32,"value":1519}," 标签与输入框关联",{"type":27,"tag":91,"props":1521,"children":1523},{"className":1522},[925],[1524,1527],{"type":27,"tag":928,"props":1525,"children":1526},{"disabled":930,"type":931},[],{"type":32,"value":1528}," 验证消息清晰",{"type":27,"tag":91,"props":1530,"children":1532},{"className":1531},[925],[1533,1536],{"type":27,"tag":928,"props":1534,"children":1535},{"disabled":930,"type":931},[],{"type":32,"value":1537}," 色彩对比度足够",{"type":27,"tag":91,"props":1539,"children":1541},{"className":1540},[925],[1542,1545],{"type":27,"tag":928,"props":1543,"children":1544},{"disabled":930,"type":931},[],{"type":32,"value":1546}," 屏幕阅读器兼容",{"type":27,"tag":91,"props":1548,"children":1550},{"className":1549},[925],[1551,1554],{"type":27,"tag":928,"props":1552,"children":1553},{"disabled":930,"type":931},[],{"type":32,"value":1555}," 移动设备测试",{"title":7,"searchDepth":614,"depth":614,"links":1557},[1558,1559,1563,1564,1565,1566,1567,1568,1569],{"id":1296,"depth":617,"text":1296},{"id":1318,"depth":617,"text":1318,"children":1560},[1561,1562],{"id":1323,"depth":614,"text":1323},{"id":1337,"depth":614,"text":1337},{"id":1302,"depth":617,"text":1302},{"id":1364,"depth":617,"text":1364},{"id":1378,"depth":617,"text":1378},{"id":1392,"depth":617,"text":1392},{"id":1406,"depth":617,"text":1406},{"id":808,"depth":617,"text":808},{"id":914,"depth":617,"text":914},"content:topics:design:form-controls-design.md","topics/design/form-controls-design.md","topics/design/form-controls-design",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":1574,"image":18,"imageQuery":19,"pexelsPhotoId":20,"pexelsUrl":21,"featured":6,"readingTime":22,"body":1575,"_type":626,"_id":627,"_source":628,"_file":629,"_stem":630,"_extension":631},[13,14,15,16,17],{"type":24,"children":1576,"toc":2042},[1577,1581,1585,1589,1608,1612,1616,1635,1639,1658,1662,1666,1735,1739,1743,1747,1751,1770,1774,1778,1782,1786,1801,1805,1820,1824,1828,1832,1836,1859,1863,1867,1871,1891,1895,1910,1914,1929,1933,1937,1948,1952,1967,1971,1975,2006,2010,2014,2018],{"type":27,"tag":28,"props":1578,"children":1579},{},[1580],{"type":32,"value":33},{"type":27,"tag":28,"props":1582,"children":1583},{},[1584],{"type":32,"value":38},{"type":27,"tag":28,"props":1586,"children":1587},{},[1588],{"type":32,"value":43},{"type":27,"tag":28,"props":1590,"children":1591},{},[1592,1593,1597,1598,1602,1603,1607],{"type":32,"value":48},{"type":27,"tag":50,"props":1594,"children":1595},{"href":52},[1596],{"type":32,"value":55},{"type":32,"value":57},{"type":27,"tag":50,"props":1599,"children":1600},{"href":60},[1601],{"type":32,"value":63},{"type":32,"value":65},{"type":27,"tag":50,"props":1604,"children":1605},{"href":68},[1606],{"type":32,"value":71},{"type":32,"value":73},{"type":27,"tag":75,"props":1609,"children":1610},{"id":77},[1611],{"type":32,"value":80},{"type":27,"tag":28,"props":1613,"children":1614},{},[1615],{"type":32,"value":85},{"type":27,"tag":87,"props":1617,"children":1618},{},[1619,1623,1627,1631],{"type":27,"tag":91,"props":1620,"children":1621},{},[1622],{"type":32,"value":95},{"type":27,"tag":91,"props":1624,"children":1625},{},[1626],{"type":32,"value":100},{"type":27,"tag":91,"props":1628,"children":1629},{},[1630],{"type":32,"value":105},{"type":27,"tag":91,"props":1632,"children":1633},{},[1634],{"type":32,"value":110},{"type":27,"tag":28,"props":1636,"children":1637},{},[1638],{"type":32,"value":115},{"type":27,"tag":87,"props":1640,"children":1641},{},[1642,1646,1650,1654],{"type":27,"tag":91,"props":1643,"children":1644},{},[1645],{"type":32,"value":123},{"type":27,"tag":91,"props":1647,"children":1648},{},[1649],{"type":32,"value":128},{"type":27,"tag":91,"props":1651,"children":1652},{},[1653],{"type":32,"value":133},{"type":27,"tag":91,"props":1655,"children":1656},{},[1657],{"type":32,"value":138},{"type":27,"tag":75,"props":1659,"children":1660},{"id":141},[1661],{"type":32,"value":144},{"type":27,"tag":28,"props":1663,"children":1664},{},[1665],{"type":32,"value":149},{"type":27,"tag":151,"props":1667,"children":1668},{},[1669,1687],{"type":27,"tag":155,"props":1670,"children":1671},{},[1672],{"type":27,"tag":159,"props":1673,"children":1674},{},[1675,1679,1683],{"type":27,"tag":163,"props":1676,"children":1677},{},[1678],{"type":32,"value":167},{"type":27,"tag":163,"props":1680,"children":1681},{},[1682],{"type":32,"value":172},{"type":27,"tag":163,"props":1684,"children":1685},{},[1686],{"type":32,"value":177},{"type":27,"tag":179,"props":1688,"children":1689},{},[1690,1705,1720],{"type":27,"tag":159,"props":1691,"children":1692},{},[1693,1697,1701],{"type":27,"tag":186,"props":1694,"children":1695},{},[1696],{"type":32,"value":190},{"type":27,"tag":186,"props":1698,"children":1699},{},[1700],{"type":32,"value":195},{"type":27,"tag":186,"props":1702,"children":1703},{},[1704],{"type":32,"value":200},{"type":27,"tag":159,"props":1706,"children":1707},{},[1708,1712,1716],{"type":27,"tag":186,"props":1709,"children":1710},{},[1711],{"type":32,"value":208},{"type":27,"tag":186,"props":1713,"children":1714},{},[1715],{"type":32,"value":213},{"type":27,"tag":186,"props":1717,"children":1718},{},[1719],{"type":32,"value":218},{"type":27,"tag":159,"props":1721,"children":1722},{},[1723,1727,1731],{"type":27,"tag":186,"props":1724,"children":1725},{},[1726],{"type":32,"value":226},{"type":27,"tag":186,"props":1728,"children":1729},{},[1730],{"type":32,"value":231},{"type":27,"tag":186,"props":1732,"children":1733},{},[1734],{"type":32,"value":236},{"type":27,"tag":28,"props":1736,"children":1737},{},[1738],{"type":32,"value":241},{"type":27,"tag":75,"props":1740,"children":1741},{"id":244},[1742],{"type":32,"value":247},{"type":27,"tag":28,"props":1744,"children":1745},{},[1746],{"type":32,"value":252},{"type":27,"tag":28,"props":1748,"children":1749},{},[1750],{"type":32,"value":257},{"type":27,"tag":87,"props":1752,"children":1753},{},[1754,1758,1762,1766],{"type":27,"tag":91,"props":1755,"children":1756},{},[1757],{"type":32,"value":265},{"type":27,"tag":91,"props":1759,"children":1760},{},[1761],{"type":32,"value":270},{"type":27,"tag":91,"props":1763,"children":1764},{},[1765],{"type":32,"value":275},{"type":27,"tag":91,"props":1767,"children":1768},{},[1769],{"type":32,"value":280},{"type":27,"tag":28,"props":1771,"children":1772},{},[1773],{"type":32,"value":285},{"type":27,"tag":75,"props":1775,"children":1776},{"id":288},[1777],{"type":32,"value":291},{"type":27,"tag":28,"props":1779,"children":1780},{},[1781],{"type":32,"value":296},{"type":27,"tag":28,"props":1783,"children":1784},{},[1785],{"type":32,"value":301},{"type":27,"tag":87,"props":1787,"children":1788},{},[1789,1793,1797],{"type":27,"tag":91,"props":1790,"children":1791},{},[1792],{"type":32,"value":309},{"type":27,"tag":91,"props":1794,"children":1795},{},[1796],{"type":32,"value":314},{"type":27,"tag":91,"props":1798,"children":1799},{},[1800],{"type":32,"value":319},{"type":27,"tag":28,"props":1802,"children":1803},{},[1804],{"type":32,"value":324},{"type":27,"tag":87,"props":1806,"children":1807},{},[1808,1812,1816],{"type":27,"tag":91,"props":1809,"children":1810},{},[1811],{"type":32,"value":332},{"type":27,"tag":91,"props":1813,"children":1814},{},[1815],{"type":32,"value":337},{"type":27,"tag":91,"props":1817,"children":1818},{},[1819],{"type":32,"value":342},{"type":27,"tag":28,"props":1821,"children":1822},{},[1823],{"type":32,"value":347},{"type":27,"tag":75,"props":1825,"children":1826},{"id":350},[1827],{"type":32,"value":353},{"type":27,"tag":28,"props":1829,"children":1830},{},[1831],{"type":32,"value":358},{"type":27,"tag":28,"props":1833,"children":1834},{},[1835],{"type":32,"value":363},{"type":27,"tag":365,"props":1837,"children":1838},{},[1839,1843,1847,1851,1855],{"type":27,"tag":91,"props":1840,"children":1841},{},[1842],{"type":32,"value":372},{"type":27,"tag":91,"props":1844,"children":1845},{},[1846],{"type":32,"value":377},{"type":27,"tag":91,"props":1848,"children":1849},{},[1850],{"type":32,"value":382},{"type":27,"tag":91,"props":1852,"children":1853},{},[1854],{"type":32,"value":387},{"type":27,"tag":91,"props":1856,"children":1857},{},[1858],{"type":32,"value":392},{"type":27,"tag":28,"props":1860,"children":1861},{},[1862],{"type":32,"value":397},{"type":27,"tag":75,"props":1864,"children":1865},{"id":400},[1866],{"type":32,"value":403},{"type":27,"tag":28,"props":1868,"children":1869},{},[1870],{"type":32,"value":408},{"type":27,"tag":87,"props":1872,"children":1873},{},[1874,1883,1887],{"type":27,"tag":91,"props":1875,"children":1876},{},[1877,1878],{"type":32,"value":416},{"type":27,"tag":418,"props":1879,"children":1881},{"className":1880},[],[1882],{"type":32,"value":423},{"type":27,"tag":91,"props":1884,"children":1885},{},[1886],{"type":32,"value":428},{"type":27,"tag":91,"props":1888,"children":1889},{},[1890],{"type":32,"value":433},{"type":27,"tag":28,"props":1892,"children":1893},{},[1894],{"type":32,"value":438},{"type":27,"tag":87,"props":1896,"children":1897},{},[1898,1902,1906],{"type":27,"tag":91,"props":1899,"children":1900},{},[1901],{"type":32,"value":446},{"type":27,"tag":91,"props":1903,"children":1904},{},[1905],{"type":32,"value":451},{"type":27,"tag":91,"props":1907,"children":1908},{},[1909],{"type":32,"value":456},{"type":27,"tag":28,"props":1911,"children":1912},{},[1913],{"type":32,"value":461},{"type":27,"tag":87,"props":1915,"children":1916},{},[1917,1921,1925],{"type":27,"tag":91,"props":1918,"children":1919},{},[1920],{"type":32,"value":469},{"type":27,"tag":91,"props":1922,"children":1923},{},[1924],{"type":32,"value":474},{"type":27,"tag":91,"props":1926,"children":1927},{},[1928],{"type":32,"value":479},{"type":27,"tag":75,"props":1930,"children":1931},{"id":482},[1932],{"type":32,"value":482},{"type":27,"tag":28,"props":1934,"children":1935},{},[1936],{"type":32,"value":489},{"type":27,"tag":87,"props":1938,"children":1939},{},[1940,1944],{"type":27,"tag":91,"props":1941,"children":1942},{},[1943],{"type":32,"value":497},{"type":27,"tag":91,"props":1945,"children":1946},{},[1947],{"type":32,"value":502},{"type":27,"tag":28,"props":1949,"children":1950},{},[1951],{"type":32,"value":507},{"type":27,"tag":87,"props":1953,"children":1954},{},[1955,1959,1963],{"type":27,"tag":91,"props":1956,"children":1957},{},[1958],{"type":32,"value":515},{"type":27,"tag":91,"props":1960,"children":1961},{},[1962],{"type":32,"value":520},{"type":27,"tag":91,"props":1964,"children":1965},{},[1966],{"type":32,"value":525},{"type":27,"tag":28,"props":1968,"children":1969},{},[1970],{"type":32,"value":530},{"type":27,"tag":75,"props":1972,"children":1973},{"id":533},[1974],{"type":32,"value":533},{"type":27,"tag":87,"props":1976,"children":1977},{},[1978,1982,1986,1990,1994,1998,2002],{"type":27,"tag":91,"props":1979,"children":1980},{},[1981],{"type":32,"value":543},{"type":27,"tag":91,"props":1983,"children":1984},{},[1985],{"type":32,"value":548},{"type":27,"tag":91,"props":1987,"children":1988},{},[1989],{"type":32,"value":553},{"type":27,"tag":91,"props":1991,"children":1992},{},[1993],{"type":32,"value":558},{"type":27,"tag":91,"props":1995,"children":1996},{},[1997],{"type":32,"value":563},{"type":27,"tag":91,"props":1999,"children":2000},{},[2001],{"type":32,"value":568},{"type":27,"tag":91,"props":2003,"children":2004},{},[2005],{"type":32,"value":573},{"type":27,"tag":75,"props":2007,"children":2008},{"id":576},[2009],{"type":32,"value":576},{"type":27,"tag":28,"props":2011,"children":2012},{},[2013],{"type":32,"value":583},{"type":27,"tag":28,"props":2015,"children":2016},{},[2017],{"type":32,"value":588},{"type":27,"tag":87,"props":2019,"children":2020},{},[2021,2028,2035],{"type":27,"tag":91,"props":2022,"children":2023},{},[2024],{"type":27,"tag":50,"props":2025,"children":2026},{"href":52},[2027],{"type":32,"value":55},{"type":27,"tag":91,"props":2029,"children":2030},{},[2031],{"type":27,"tag":50,"props":2032,"children":2033},{"href":68},[2034],{"type":32,"value":71},{"type":27,"tag":91,"props":2036,"children":2037},{},[2038],{"type":27,"tag":50,"props":2039,"children":2040},{"href":60},[2041],{"type":32,"value":63},{"title":7,"searchDepth":614,"depth":614,"links":2043},[2044,2045,2046,2047,2048,2049,2050,2051,2052],{"id":77,"depth":617,"text":80},{"id":141,"depth":617,"text":144},{"id":244,"depth":617,"text":247},{"id":288,"depth":617,"text":291},{"id":350,"depth":617,"text":353},{"id":400,"depth":617,"text":403},{"id":482,"depth":617,"text":482},{"id":533,"depth":617,"text":533},{"id":576,"depth":617,"text":576},1776174409597]