[{"data":1,"prerenderedAt":1786},["ShallowReactive",2],{"article-/topics/design/web-design-workflow-wireframe-visual-handoff-guide":3,"related-design":488,"content-query-lbjAhzzndd":1430},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":12,"image":17,"imageQuery":18,"pexelsPhotoId":19,"pexelsUrl":20,"featured":6,"readingTime":21,"body":22,"_type":482,"_id":483,"_source":484,"_file":485,"_stem":486,"_extension":487},"/topics/design/web-design-workflow-wireframe-visual-handoff-guide","design",false,"","网页设计流程怎么推进：需求澄清、线框、视觉稿到上线验收的最小闭环","很多网页设计项目不是卡在设计本身，而是流程顺序不对：还没对齐目标就进视觉，线框没定就开始争颜色，上线前才发现移动端和表单问题。本文把网页设计流程拆成最小闭环，讲清每一步该锁什么。","2026-05-19","HTMLPAGE 团队",[13,14,15,16],"网页设计","网站设计","设计流程","设计交付","/images/articles/web-design-workflow-wireframe-visual-handoff-guide-featured.jpg","web design workflow wireframe handoff checklist desk",38519,"https://www.pexels.com/photo/ipad-on-macbook-pro-beside-apple-magic-mouse-38519/",16,{"type":23,"children":24,"toc":470},"root",[25,33,38,43,80,87,192,197,203,208,213,238,243,249,254,259,282,287,293,298,321,326,331,337,342,347,370,375,381,386,391,396,402,407,430,435,441,446,465],{"type":26,"tag":27,"props":28,"children":29},"element","p",{},[30],{"type":31,"value":32},"text","很多网页设计项目表面上是在“做视觉”，实际上卡住的地方却更早。需求刚说了一半，团队就已经开始找参考图；线框还没定，评审却在讨论颜色和字体；视觉稿看起来已经不错，到了上线前又发现文案没锁、移动端断版、表单和埋点没人验。于是每一轮都像在推进项目，真正的决定却总在下一轮被推翻。",{"type":26,"tag":27,"props":34,"children":35},{},[36],{"type":31,"value":37},"这类问题最常被解释成“沟通不够”或“流程太重”。但大多数时候，问题不是流程多，而是顺序错。网页设计流程最怕的不是步骤多一层，而是该前置的判断被拖到后面，该后置的细节又被提前争论。顺序一乱，返工就会顺着整条链往后传。",{"type":26,"tag":27,"props":39,"children":40},{},[41],{"type":31,"value":42},"所以这篇文章不打算把网页设计流程写成大公司 SOP，而是只保留最小可执行闭环：需求澄清、线框、视觉稿、上线验收。每一步到底该锁什么、不该在这一步争什么，才是让项目往前走而不是原地打转的关键。",{"type":26,"tag":27,"props":44,"children":45},{},[46,48,55,57,63,64,70,72,78],{"type":31,"value":47},"建议搭配 ",{"type":26,"tag":49,"props":50,"children":52},"a",{"href":51},"/topics/design/web-design-proposal-goals-structure-visual-direction",[53],{"type":31,"value":54},"网页设计方案怎么写",{"type":31,"value":56},"、",{"type":26,"tag":49,"props":58,"children":60},{"href":59},"/topics/design/page-design-requirements-communication-guide",[61],{"type":31,"value":62},"页面设计需求怎么沟通",{"type":31,"value":56},{"type":26,"tag":49,"props":65,"children":67},{"href":66},"/topics/practical-tips/online-webpage-design-collaboration-handoff",[68],{"type":31,"value":69},"在线网页与页面设计协作怎么落地",{"type":31,"value":71}," 和 ",{"type":26,"tag":49,"props":73,"children":75},{"href":74},"/topics/practical-tips/website-launch-preflight-checklist",[76],{"type":31,"value":77},"网站上线前检查清单",{"type":31,"value":79}," 一起看。",{"type":26,"tag":81,"props":82,"children":84},"h2",{"id":83},"先给结论网页设计流程不是四步走完而是四步各自锁一个关键决定",[85],{"type":31,"value":86},"先给结论：网页设计流程不是四步走完，而是四步各自锁一个关键决定",{"type":26,"tag":88,"props":89,"children":90},"table",{},[91,115],{"type":26,"tag":92,"props":93,"children":94},"thead",{},[95],{"type":26,"tag":96,"props":97,"children":98},"tr",{},[99,105,110],{"type":26,"tag":100,"props":101,"children":102},"th",{},[103],{"type":31,"value":104},"阶段",{"type":26,"tag":100,"props":106,"children":107},{},[108],{"type":31,"value":109},"这一阶段必须锁住什么",{"type":26,"tag":100,"props":111,"children":112},{},[113],{"type":31,"value":114},"太早讨论会浪费什么",{"type":26,"tag":116,"props":117,"children":118},"tbody",{},[119,138,156,174],{"type":26,"tag":96,"props":120,"children":121},{},[122,128,133],{"type":26,"tag":123,"props":124,"children":125},"td",{},[126],{"type":31,"value":127},"需求澄清",{"type":26,"tag":123,"props":129,"children":130},{},[131],{"type":31,"value":132},"目标、受众、页面任务、边界条件",{"type":26,"tag":123,"props":134,"children":135},{},[136],{"type":31,"value":137},"太早谈风格，方向会反复摇摆",{"type":26,"tag":96,"props":139,"children":140},{},[141,146,151],{"type":26,"tag":123,"props":142,"children":143},{},[144],{"type":31,"value":145},"线框",{"type":26,"tag":123,"props":147,"children":148},{},[149],{"type":31,"value":150},"信息顺序、模块骨架、CTA 路径",{"type":26,"tag":123,"props":152,"children":153},{},[154],{"type":31,"value":155},"太早做高保真，会在结构上返工",{"type":26,"tag":96,"props":157,"children":158},{},[159,164,169],{"type":26,"tag":123,"props":160,"children":161},{},[162],{"type":31,"value":163},"视觉稿",{"type":26,"tag":123,"props":165,"children":166},{},[167],{"type":31,"value":168},"视觉变量、组件表现、品牌语气",{"type":26,"tag":123,"props":170,"children":171},{},[172],{"type":31,"value":173},"太早抠像素，团队忽略真实内容",{"type":26,"tag":96,"props":175,"children":176},{},[177,182,187],{"type":26,"tag":123,"props":178,"children":179},{},[180],{"type":31,"value":181},"上线验收",{"type":26,"tag":123,"props":183,"children":184},{},[185],{"type":31,"value":186},"响应式、文案、表单、SEO、埋点",{"type":26,"tag":123,"props":188,"children":189},{},[190],{"type":31,"value":191},"太晚检查可用性，会把设计问题带到线上",{"type":26,"tag":27,"props":193,"children":194},{},[195],{"type":31,"value":196},"这四步一旦被压缩成“需求提一下 -> 出图 -> 上线”，大多数项目都会把本来能前置解决的问题留到后面爆出来。",{"type":26,"tag":81,"props":198,"children":200},{"id":199},"需求澄清阶段先锁方向不要先锁风格",[201],{"type":31,"value":202},"需求澄清阶段先锁方向，不要先锁风格",{"type":26,"tag":27,"props":204,"children":205},{},[206],{"type":31,"value":207},"网页设计流程里最被低估的一步，就是需求澄清。因为它通常不产出好看的视觉稿，所以团队会本能地想跳过它。但真正决定后续顺不顺的，往往就是这一步有没有把方向说清。",{"type":26,"tag":27,"props":209,"children":210},{},[211],{"type":31,"value":212},"需求澄清至少应该回答：",{"type":26,"tag":214,"props":215,"children":216},"ul",{},[217,223,228,233],{"type":26,"tag":218,"props":219,"children":220},"li",{},[221],{"type":31,"value":222},"页面主要服务什么动作",{"type":26,"tag":218,"props":224,"children":225},{},[226],{"type":31,"value":227},"主受众是谁，他们最先关心什么",{"type":26,"tag":218,"props":229,"children":230},{},[231],{"type":31,"value":232},"这页是偏获客、偏品牌，还是偏解释",{"type":26,"tag":218,"props":234,"children":235},{},[236],{"type":31,"value":237},"哪些内容、功能、时间和角色边界已经确定",{"type":26,"tag":27,"props":239,"children":240},{},[241],{"type":31,"value":242},"只要这些问题还没说清，后面哪怕很快出图，也只是更快把歧义可视化。设计师越认真，返工时越痛。",{"type":26,"tag":81,"props":244,"children":246},{"id":245},"线框阶段的任务是定结构不是做丑一点的视觉稿",[247],{"type":31,"value":248},"线框阶段的任务是定结构，不是做“丑一点的视觉稿”",{"type":26,"tag":27,"props":250,"children":251},{},[252],{"type":31,"value":253},"很多团队会误解线框，觉得它只是正式设计前的过渡图。于是线框阶段要么被跳过，要么做成一种低保真但依然在讨论风格的半成品。这样做的结果，是线框没有真正承担它该做的事：把结构顺序先定下来。",{"type":26,"tag":27,"props":255,"children":256},{},[257],{"type":31,"value":258},"线框最应该确认的是：",{"type":26,"tag":214,"props":260,"children":261},{},[262,267,272,277],{"type":26,"tag":218,"props":263,"children":264},{},[265],{"type":31,"value":266},"首屏先说什么",{"type":26,"tag":218,"props":268,"children":269},{},[270],{"type":31,"value":271},"哪些模块必须保留，哪些是可选",{"type":26,"tag":218,"props":273,"children":274},{},[275],{"type":31,"value":276},"证据应该插在什么位置",{"type":26,"tag":218,"props":278,"children":279},{},[280],{"type":31,"value":281},"CTA 主路径和次路径如何分层",{"type":26,"tag":27,"props":283,"children":284},{},[285],{"type":31,"value":286},"如果这一步能定住，视觉稿就不需要再承担结构争论。反过来，如果线框阶段只是在走流程，团队到高保真稿时还会继续改模块顺序、删增页面段落，返工成本会立刻变高。",{"type":26,"tag":81,"props":288,"children":290},{"id":289},"视觉稿阶段要定变量和体验不要替前两步背锅",[291],{"type":31,"value":292},"视觉稿阶段要定变量和体验，不要替前两步背锅",{"type":26,"tag":27,"props":294,"children":295},{},[296],{"type":31,"value":297},"视觉稿真正有价值的部分，不是“更精细”，而是把品牌语气、层级节奏、组件表现和页面气质稳定下来。也就是说，视觉稿阶段应该重点讨论：",{"type":26,"tag":214,"props":299,"children":300},{},[301,306,311,316],{"type":26,"tag":218,"props":302,"children":303},{},[304],{"type":31,"value":305},"标题、正文、按钮和辅助信息的层级关系",{"type":26,"tag":218,"props":307,"children":308},{},[309],{"type":31,"value":310},"图片、颜色、留白和卡片节奏是否统一",{"type":26,"tag":218,"props":312,"children":313},{},[314],{"type":31,"value":315},"哪些组件是页面核心表达，哪些只是辅助容器",{"type":26,"tag":218,"props":317,"children":318},{},[319],{"type":31,"value":320},"桌面端与移动端的阅读路径是否一致",{"type":26,"tag":27,"props":322,"children":323},{},[324],{"type":31,"value":325},"如果到了这一步，团队还在争首页先放品牌故事还是先放解决方案，说明前面不是做得不够美，而是线框和需求没锁住。",{"type":26,"tag":27,"props":327,"children":328},{},[329],{"type":31,"value":330},"视觉稿阶段最浪费的事，就是让设计团队一边解决风格，一边补前两步留下的结构债。",{"type":26,"tag":81,"props":332,"children":334},{"id":333},"上线验收不是技术收尾而是设计流程的一部分",[335],{"type":31,"value":336},"上线验收不是技术收尾，而是设计流程的一部分",{"type":26,"tag":27,"props":338,"children":339},{},[340],{"type":31,"value":341},"很多网页设计项目在视觉稿通过后，会默认“设计已经完成”，后面的事情都是开发或运营问题。现实里，最容易毁掉一版设计的，往往就是这一步被忽略。移动端折行、图片裁切、表单状态、按钮文案、SEO 标题、埋点缺失，这些都不是纯技术细节，而是会直接改变页面体验和转化结果的设计问题。",{"type":26,"tag":27,"props":343,"children":344},{},[345],{"type":31,"value":346},"所以最小上线验收至少要检查：",{"type":26,"tag":214,"props":348,"children":349},{},[350,355,360,365],{"type":26,"tag":218,"props":351,"children":352},{},[353],{"type":31,"value":354},"首屏和核心模块在移动端是否仍然顺畅",{"type":26,"tag":218,"props":356,"children":357},{},[358],{"type":31,"value":359},"标题、按钮、表单和错误提示是否与设计意图一致",{"type":26,"tag":218,"props":361,"children":362},{},[363],{"type":31,"value":364},"真实文案替换后是否打破排版节奏",{"type":26,"tag":218,"props":366,"children":367},{},[368],{"type":31,"value":369},"页面有没有把 SEO、表单、埋点这些关键动作带上线",{"type":26,"tag":27,"props":371,"children":372},{},[373],{"type":31,"value":374},"如果上线验收被当成“最后看一眼”，设计流程其实还没有真正闭环。",{"type":26,"tag":81,"props":376,"children":378},{"id":377},"失败案例跳过线框结果三轮视觉稿都在改同一件事",[379],{"type":31,"value":380},"失败案例：跳过线框，结果三轮视觉稿都在改同一件事",{"type":26,"tag":27,"props":382,"children":383},{},[384],{"type":31,"value":385},"某团队做一版产品官网改版，时间很紧，于是决定“先直接出视觉，线框可以边做边调”。设计师很快做出一版高保真首屏和几个关键模块，看起来已经接近正式上线。第一次评审时，业务团队提出首页应该先讲行业场景；第二次评审时，销售团队又觉得案例应该更早出现；第三次时，市场团队认为 CTA 应该分成“咨询”和“下载方案”两条路径。",{"type":26,"tag":27,"props":387,"children":388},{},[389],{"type":31,"value":390},"这三个反馈都不是新问题，它们本来都属于线框阶段该定的结构判断。因为前面没定，后面每轮视觉稿都在为同一类问题返工。表面看是在改设计，实际上一直在补流程顺序的债。",{"type":26,"tag":27,"props":392,"children":393},{},[394],{"type":31,"value":395},"后来团队回退一步，先把线框定住，再重新出视觉稿。视觉轮次反而明显变少。不是因为设计变简单了，而是因为该在哪一步解决什么，终于被放回了正确位置。",{"type":26,"tag":81,"props":397,"children":399},{"id":398},"什么时候流程可以轻一点什么时候一定不能省",[400],{"type":31,"value":401},"什么时候流程可以轻一点，什么时候一定不能省",{"type":26,"tag":27,"props":403,"children":404},{},[405],{"type":31,"value":406},"并不是所有网页设计项目都要完整跑满四步。如果只是单次短期活动页、内容简单、决策链很短，需求澄清和线框可以压缩，视觉和验收也可以更轻。但只要出现下面这些情况，流程最好不要省：",{"type":26,"tag":214,"props":408,"children":409},{},[410,415,420,425],{"type":26,"tag":218,"props":411,"children":412},{},[413],{"type":31,"value":414},"首页、解决方案页、案例页同时改动",{"type":26,"tag":218,"props":416,"children":417},{},[418],{"type":31,"value":419},"多个角色会参与反馈和拍板",{"type":26,"tag":218,"props":421,"children":422},{},[423],{"type":31,"value":424},"页面涉及表单、SEO、投放或长期内容沉淀",{"type":26,"tag":218,"props":426,"children":427},{},[428],{"type":31,"value":429},"后续还会复用组件或继续扩展内页",{"type":26,"tag":27,"props":431,"children":432},{},[433],{"type":31,"value":434},"流程是否需要完整，不取决于页面看起来大不大，而取决于返工代价高不高。",{"type":26,"tag":81,"props":436,"children":438},{"id":437},"先做什么先把下一次评审按阶段重新分工",[439],{"type":31,"value":440},"先做什么：先把下一次评审按阶段重新分工",{"type":26,"tag":27,"props":442,"children":443},{},[444],{"type":31,"value":445},"如果你正在带一个网页设计项目，最值得先做的三件事是：",{"type":26,"tag":447,"props":448,"children":449},"ol",{},[450,455,460],{"type":26,"tag":218,"props":451,"children":452},{},[453],{"type":31,"value":454},"把当前讨论内容归回阶段，看它到底属于需求、线框、视觉还是验收。",{"type":26,"tag":218,"props":456,"children":457},{},[458],{"type":31,"value":459},"任何一轮评审只解决一个阶段的主问题，不让结构、风格、上线细节同时混在一起。",{"type":26,"tag":218,"props":461,"children":462},{},[463],{"type":31,"value":464},"在进入下一阶段前，明确写下“这一步已经锁住了什么”。",{"type":26,"tag":27,"props":466,"children":467},{},[468],{"type":31,"value":469},"网页设计流程真正高效的时候，不是每一步都很重，而是每一步都知道自己在锁什么。只要需求澄清、线框、视觉稿和上线验收各自承担该承担的决定，项目才会从“每一轮都在改”变成“每一轮都在往前”。",{"title":7,"searchDepth":471,"depth":471,"links":472},3,[473,475,476,477,478,479,480,481],{"id":83,"depth":474,"text":86},2,{"id":199,"depth":474,"text":202},{"id":245,"depth":474,"text":248},{"id":289,"depth":474,"text":292},{"id":333,"depth":474,"text":336},{"id":377,"depth":474,"text":380},{"id":398,"depth":474,"text":401},{"id":437,"depth":474,"text":440},"markdown","content:topics:design:web-design-workflow-wireframe-visual-handoff-guide.md","content","topics/design/web-design-workflow-wireframe-visual-handoff-guide.md","topics/design/web-design-workflow-wireframe-visual-handoff-guide","md",[489,849,1151],{"_path":490,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":491,"description":492,"keywords":493,"image":499,"author":11,"date":500,"readingTime":501,"topic":5,"body":502,"_type":482,"_id":846,"_source":484,"_file":847,"_stem":848,"_extension":487},"/topics/design/button-component-design","按钮组件设计详解","学习按钮样式、交互状态、无障碍性和最佳实践",[494,495,496,497,498],"按钮设计","Button Component","交互状态","UI 组件","用户体验","/images/topics/button-design.jpg","2025-12-08",18,{"type":23,"children":503,"toc":828},[504,508,513,518,525,538,544,553,559,568,572,578,589,595,604,610,619,624,633,638,649,654,663,668,681,715,726,769,774],{"type":26,"tag":81,"props":505,"children":506},{"id":491},[507],{"type":31,"value":491},{"type":26,"tag":27,"props":509,"children":510},{},[511],{"type":31,"value":512},"按钮是 UI 中最重要的交互元素。优秀的按钮设计能够指导用户行为。",{"type":26,"tag":81,"props":514,"children":516},{"id":515},"按钮类型",[517],{"type":31,"value":515},{"type":26,"tag":519,"props":520,"children":522},"h3",{"id":521},"primary-button主按钮",[523],{"type":31,"value":524},"Primary Button（主按钮）",{"type":26,"tag":526,"props":527,"children":532},"pre",{"className":528,"code":530,"language":531,"meta":7},[529],"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",[533],{"type":26,"tag":534,"props":535,"children":536},"code",{"__ignoreMap":7},[537],{"type":31,"value":530},{"type":26,"tag":519,"props":539,"children":541},{"id":540},"secondary-button次按钮",[542],{"type":31,"value":543},"Secondary Button（次按钮）",{"type":26,"tag":526,"props":545,"children":548},{"className":546,"code":547,"language":531,"meta":7},[529],".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",[549],{"type":26,"tag":534,"props":550,"children":551},{"__ignoreMap":7},[552],{"type":31,"value":547},{"type":26,"tag":519,"props":554,"children":556},{"id":555},"danger-button危险按钮",[557],{"type":31,"value":558},"Danger Button（危险按钮）",{"type":26,"tag":526,"props":560,"children":563},{"className":561,"code":562,"language":531,"meta":7},[529],".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",[564],{"type":26,"tag":534,"props":565,"children":566},{"__ignoreMap":7},[567],{"type":31,"value":562},{"type":26,"tag":81,"props":569,"children":570},{"id":496},[571],{"type":31,"value":496},{"type":26,"tag":519,"props":573,"children":575},{"id":574},"loading-状态",[576],{"type":31,"value":577},"Loading 状态",{"type":26,"tag":526,"props":579,"children":584},{"className":580,"code":582,"language":583,"meta":7},[581],"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",[585],{"type":26,"tag":534,"props":586,"children":587},{"__ignoreMap":7},[588],{"type":31,"value":582},{"type":26,"tag":519,"props":590,"children":592},{"id":591},"disabled-状态",[593],{"type":31,"value":594},"Disabled 状态",{"type":26,"tag":526,"props":596,"children":599},{"className":597,"code":598,"language":531,"meta":7},[529],".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",[600],{"type":26,"tag":534,"props":601,"children":602},{"__ignoreMap":7},[603],{"type":31,"value":598},{"type":26,"tag":519,"props":605,"children":607},{"id":606},"focus-状态",[608],{"type":31,"value":609},"Focus 状态",{"type":26,"tag":526,"props":611,"children":614},{"className":612,"code":613,"language":531,"meta":7},[529],".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",[615],{"type":26,"tag":534,"props":616,"children":617},{"__ignoreMap":7},[618],{"type":31,"value":613},{"type":26,"tag":81,"props":620,"children":622},{"id":621},"按钮大小",[623],{"type":31,"value":621},{"type":26,"tag":526,"props":625,"children":628},{"className":626,"code":627,"language":531,"meta":7},[529],"/* 小按钮 */\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",[629],{"type":26,"tag":534,"props":630,"children":631},{"__ignoreMap":7},[632],{"type":31,"value":627},{"type":26,"tag":81,"props":634,"children":636},{"id":635},"无障碍性",[637],{"type":31,"value":635},{"type":26,"tag":526,"props":639,"children":644},{"className":640,"code":642,"language":643,"meta":7},[641],"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",[645],{"type":26,"tag":534,"props":646,"children":647},{"__ignoreMap":7},[648],{"type":31,"value":642},{"type":26,"tag":81,"props":650,"children":652},{"id":651},"完整组件示例",[653],{"type":31,"value":651},{"type":26,"tag":526,"props":655,"children":658},{"className":656,"code":657,"language":583,"meta":7},[581],"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",[659],{"type":26,"tag":534,"props":660,"children":661},{"__ignoreMap":7},[662],{"type":31,"value":657},{"type":26,"tag":81,"props":664,"children":666},{"id":665},"最佳实践",[667],{"type":31,"value":665},{"type":26,"tag":27,"props":669,"children":670},{},[671,673,679],{"type":31,"value":672},"✅ ",{"type":26,"tag":674,"props":675,"children":676},"strong",{},[677],{"type":31,"value":678},"应该做的事",{"type":31,"value":680},":",{"type":26,"tag":214,"props":682,"children":683},{},[684,689,694,705,710],{"type":26,"tag":218,"props":685,"children":686},{},[687],{"type":31,"value":688},"最小触摸目标 44x44px",{"type":26,"tag":218,"props":690,"children":691},{},[692],{"type":31,"value":693},"清晰的视觉反馈",{"type":26,"tag":218,"props":695,"children":696},{},[697,699],{"type":31,"value":698},"使用语义 HTML ",{"type":26,"tag":534,"props":700,"children":702},{"className":701},[],[703],{"type":31,"value":704},"\u003Cbutton>",{"type":26,"tag":218,"props":706,"children":707},{},[708],{"type":31,"value":709},"提供加载状态反馈",{"type":26,"tag":218,"props":711,"children":712},{},[713],{"type":31,"value":714},"支持键盘导航",{"type":26,"tag":27,"props":716,"children":717},{},[718,720,725],{"type":31,"value":719},"❌ ",{"type":26,"tag":674,"props":721,"children":722},{},[723],{"type":31,"value":724},"不应该做的事",{"type":31,"value":680},{"type":26,"tag":214,"props":727,"children":728},{},[729,742,747,752,757],{"type":26,"tag":218,"props":730,"children":731},{},[732,734,740],{"type":31,"value":733},"使用 ",{"type":26,"tag":534,"props":735,"children":737},{"className":736},[],[738],{"type":31,"value":739},"\u003Cdiv>",{"type":31,"value":741}," 模拟按钮",{"type":26,"tag":218,"props":743,"children":744},{},[745],{"type":31,"value":746},"隐藏焦点指示器",{"type":26,"tag":218,"props":748,"children":749},{},[750],{"type":31,"value":751},"过多的按钮样式",{"type":26,"tag":218,"props":753,"children":754},{},[755],{"type":31,"value":756},"忽视禁用状态",{"type":26,"tag":218,"props":758,"children":759},{},[760,761,767],{"type":31,"value":733},{"type":26,"tag":534,"props":762,"children":764},{"className":763},[],[765],{"type":31,"value":766},"\u003Ca>",{"type":31,"value":768}," 代替按钮",{"type":26,"tag":81,"props":770,"children":772},{"id":771},"测试清单",[773],{"type":31,"value":771},{"type":26,"tag":214,"props":775,"children":778},{"className":776},[777],"contains-task-list",[779,792,801,810,819],{"type":26,"tag":218,"props":780,"children":783},{"className":781},[782],"task-list-item",[784,790],{"type":26,"tag":785,"props":786,"children":789},"input",{"disabled":787,"type":788},true,"checkbox",[],{"type":31,"value":791}," 在各种浏览器中测试",{"type":26,"tag":218,"props":793,"children":795},{"className":794},[782],[796,799],{"type":26,"tag":785,"props":797,"children":798},{"disabled":787,"type":788},[],{"type":31,"value":800}," 验证键盘导航",{"type":26,"tag":218,"props":802,"children":804},{"className":803},[782],[805,808],{"type":26,"tag":785,"props":806,"children":807},{"disabled":787,"type":788},[],{"type":31,"value":809}," 检查色彩对比度",{"type":26,"tag":218,"props":811,"children":813},{"className":812},[782],[814,817],{"type":26,"tag":785,"props":815,"children":816},{"disabled":787,"type":788},[],{"type":31,"value":818}," 测试触摸设备",{"type":26,"tag":218,"props":820,"children":822},{"className":821},[782],[823,826],{"type":26,"tag":785,"props":824,"children":825},{"disabled":787,"type":788},[],{"type":31,"value":827}," 屏幕阅读器兼容性",{"title":7,"searchDepth":471,"depth":471,"links":829},[830,831,836,841,842,843,844,845],{"id":491,"depth":474,"text":491},{"id":515,"depth":474,"text":515,"children":832},[833,834,835],{"id":521,"depth":471,"text":524},{"id":540,"depth":471,"text":543},{"id":555,"depth":471,"text":558},{"id":496,"depth":474,"text":496,"children":837},[838,839,840],{"id":574,"depth":471,"text":577},{"id":591,"depth":471,"text":594},{"id":606,"depth":471,"text":609},{"id":621,"depth":474,"text":621},{"id":635,"depth":474,"text":635},{"id":651,"depth":474,"text":651},{"id":665,"depth":474,"text":665},{"id":771,"depth":474,"text":771},"content:topics:design:button-component-design.md","topics/design/button-component-design.md","topics/design/button-component-design",{"_path":850,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":851,"description":852,"keywords":853,"image":858,"author":11,"date":500,"readingTime":859,"topic":5,"body":860,"_type":482,"_id":1148,"_source":484,"_file":1149,"_stem":1150,"_extension":487},"/topics/design/dark-mode-design","暗黑模式设计完整方案","学习暗黑模式实现、色彩方案、对比度管理和最佳实践",[854,855,856,857,498],"暗黑模式","Dark Mode","色彩系统","CSS 变量","/images/topics/dark-mode-design.jpg",20,{"type":23,"children":861,"toc":1131},[862,866,871,876,882,891,897,906,911,917,926,932,943,949,958,963,972,977,986,991,1000,1004,1013,1041,1050,1078,1082],{"type":26,"tag":81,"props":863,"children":864},{"id":851},[865],{"type":31,"value":851},{"type":26,"tag":27,"props":867,"children":868},{},[869],{"type":31,"value":870},"暗黑模式已成为现代应用的标准功能。它能够减少眼睛疲劳、节省电池、改善用户体验。",{"type":26,"tag":81,"props":872,"children":874},{"id":873},"核心色彩系统",[875],{"type":31,"value":873},{"type":26,"tag":519,"props":877,"children":879},{"id":878},"light-mode-配色",[880],{"type":31,"value":881},"Light Mode 配色",{"type":26,"tag":526,"props":883,"children":886},{"className":884,"code":885,"language":531,"meta":7},[529],":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",[887],{"type":26,"tag":534,"props":888,"children":889},{"__ignoreMap":7},[890],{"type":31,"value":885},{"type":26,"tag":519,"props":892,"children":894},{"id":893},"dark-mode-配色",[895],{"type":31,"value":896},"Dark Mode 配色",{"type":26,"tag":526,"props":898,"children":901},{"className":899,"code":900,"language":531,"meta":7},[529],"@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",[902],{"type":26,"tag":534,"props":903,"children":904},{"__ignoreMap":7},[905],{"type":31,"value":900},{"type":26,"tag":81,"props":907,"children":909},{"id":908},"实现方案",[910],{"type":31,"value":908},{"type":26,"tag":519,"props":912,"children":914},{"id":913},"方案-1prefers-color-scheme",[915],{"type":31,"value":916},"方案 1：prefers-color-scheme",{"type":26,"tag":526,"props":918,"children":921},{"className":919,"code":920,"language":531,"meta":7},[529],"/* 自动跟随系统设置 */\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",[922],{"type":26,"tag":534,"props":923,"children":924},{"__ignoreMap":7},[925],{"type":31,"value":920},{"type":26,"tag":519,"props":927,"children":929},{"id":928},"方案-2javascript-切换",[930],{"type":31,"value":931},"方案 2：JavaScript 切换",{"type":26,"tag":526,"props":933,"children":938},{"className":934,"code":936,"language":937,"meta":7},[935],"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",[939],{"type":26,"tag":534,"props":940,"children":941},{"__ignoreMap":7},[942],{"type":31,"value":936},{"type":26,"tag":519,"props":944,"children":946},{"id":945},"方案-3css-variables-javascript",[947],{"type":31,"value":948},"方案 3：CSS Variables + JavaScript",{"type":26,"tag":526,"props":950,"children":953},{"className":951,"code":952,"language":937,"meta":7},[935],"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",[954],{"type":26,"tag":534,"props":955,"children":956},{"__ignoreMap":7},[957],{"type":31,"value":952},{"type":26,"tag":81,"props":959,"children":961},{"id":960},"对比度管理",[962],{"type":31,"value":960},{"type":26,"tag":526,"props":964,"children":967},{"className":965,"code":966,"language":531,"meta":7},[529],"/* 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",[968],{"type":26,"tag":534,"props":969,"children":970},{"__ignoreMap":7},[971],{"type":31,"value":966},{"type":26,"tag":81,"props":973,"children":975},{"id":974},"图片和图表处理",[976],{"type":31,"value":974},{"type":26,"tag":526,"props":978,"children":981},{"className":979,"code":980,"language":643,"meta":7},[641],"\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",[982],{"type":26,"tag":534,"props":983,"children":984},{"__ignoreMap":7},[985],{"type":31,"value":980},{"type":26,"tag":81,"props":987,"children":989},{"id":988},"完整示例",[990],{"type":31,"value":988},{"type":26,"tag":526,"props":992,"children":995},{"className":993,"code":994,"language":583,"meta":7},[581],"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",[996],{"type":26,"tag":534,"props":997,"children":998},{"__ignoreMap":7},[999],{"type":31,"value":994},{"type":26,"tag":81,"props":1001,"children":1002},{"id":665},[1003],{"type":31,"value":665},{"type":26,"tag":27,"props":1005,"children":1006},{},[1007,1008,1012],{"type":31,"value":672},{"type":26,"tag":674,"props":1009,"children":1010},{},[1011],{"type":31,"value":678},{"type":31,"value":680},{"type":26,"tag":214,"props":1014,"children":1015},{},[1016,1021,1026,1031,1036],{"type":26,"tag":218,"props":1017,"children":1018},{},[1019],{"type":31,"value":1020},"支持系统偏好",{"type":26,"tag":218,"props":1022,"children":1023},{},[1024],{"type":31,"value":1025},"提供手动切换选项",{"type":26,"tag":218,"props":1027,"children":1028},{},[1029],{"type":31,"value":1030},"确保足够的对比度",{"type":26,"tag":218,"props":1032,"children":1033},{},[1034],{"type":31,"value":1035},"优化图片和图表",{"type":26,"tag":218,"props":1037,"children":1038},{},[1039],{"type":31,"value":1040},"防止加载闪烁",{"type":26,"tag":27,"props":1042,"children":1043},{},[1044,1045,1049],{"type":31,"value":719},{"type":26,"tag":674,"props":1046,"children":1047},{},[1048],{"type":31,"value":724},{"type":31,"value":680},{"type":26,"tag":214,"props":1051,"children":1052},{},[1053,1058,1063,1068,1073],{"type":26,"tag":218,"props":1054,"children":1055},{},[1056],{"type":31,"value":1057},"强制单一模式",{"type":26,"tag":218,"props":1059,"children":1060},{},[1061],{"type":31,"value":1062},"忽视性能影响",{"type":26,"tag":218,"props":1064,"children":1065},{},[1066],{"type":31,"value":1067},"使用相同的颜色",{"type":26,"tag":218,"props":1069,"children":1070},{},[1071],{"type":31,"value":1072},"忘记保存用户偏好",{"type":26,"tag":218,"props":1074,"children":1075},{},[1076],{"type":31,"value":1077},"过度使用深色背景",{"type":26,"tag":81,"props":1079,"children":1080},{"id":771},[1081],{"type":31,"value":771},{"type":26,"tag":214,"props":1083,"children":1085},{"className":1084},[777],[1086,1095,1104,1113,1122],{"type":26,"tag":218,"props":1087,"children":1089},{"className":1088},[782],[1090,1093],{"type":26,"tag":785,"props":1091,"children":1092},{"disabled":787,"type":788},[],{"type":31,"value":1094}," 在浅色和深色模式下测试所有页面",{"type":26,"tag":218,"props":1096,"children":1098},{"className":1097},[782],[1099,1102],{"type":26,"tag":785,"props":1100,"children":1101},{"disabled":787,"type":788},[],{"type":31,"value":1103}," 检查颜色对比度符合 WCAG 标准",{"type":26,"tag":218,"props":1105,"children":1107},{"className":1106},[782],[1108,1111],{"type":26,"tag":785,"props":1109,"children":1110},{"disabled":787,"type":788},[],{"type":31,"value":1112}," 验证图片和图表在两种模式下清晰",{"type":26,"tag":218,"props":1114,"children":1116},{"className":1115},[782],[1117,1120],{"type":26,"tag":785,"props":1118,"children":1119},{"disabled":787,"type":788},[],{"type":31,"value":1121}," 测试主题切换的平滑性",{"type":26,"tag":218,"props":1123,"children":1125},{"className":1124},[782],[1126,1129],{"type":26,"tag":785,"props":1127,"children":1128},{"disabled":787,"type":788},[],{"type":31,"value":1130}," 检查用户偏好是否被保存",{"title":7,"searchDepth":471,"depth":471,"links":1132},[1133,1134,1138,1143,1144,1145,1146,1147],{"id":851,"depth":474,"text":851},{"id":873,"depth":474,"text":873,"children":1135},[1136,1137],{"id":878,"depth":471,"text":881},{"id":893,"depth":471,"text":896},{"id":908,"depth":474,"text":908,"children":1139},[1140,1141,1142],{"id":913,"depth":471,"text":916},{"id":928,"depth":471,"text":931},{"id":945,"depth":471,"text":948},{"id":960,"depth":474,"text":960},{"id":974,"depth":474,"text":974},{"id":988,"depth":474,"text":988},{"id":665,"depth":474,"text":665},{"id":771,"depth":474,"text":771},"content:topics:design:dark-mode-design.md","topics/design/dark-mode-design.md","topics/design/dark-mode-design",{"_path":1152,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1153,"description":1154,"keywords":1155,"image":1160,"author":1161,"date":500,"readingTime":859,"topic":5,"body":1162,"_type":482,"_id":1427,"_source":484,"_file":1428,"_stem":1429,"_extension":487},"/topics/design/form-controls-design","表单控件设计规范","学习输入框、选择框、复选框等表单控件的设计和实现",[1156,1157,1158,1159,498],"表单设计","Form Controls","输入框","验证反馈","/images/topics/form-controls-design.jpg","AI Content Team",{"type":23,"children":1163,"toc":1413},[1164,1168,1173,1178,1183,1192,1197,1206,1210,1219,1224,1233,1238,1247,1252,1261,1266,1275,1279,1288,1314,1323,1351,1355],{"type":26,"tag":81,"props":1165,"children":1166},{"id":1153},[1167],{"type":31,"value":1153},{"type":26,"tag":27,"props":1169,"children":1170},{},[1171],{"type":31,"value":1172},"优秀的表单设计能够提高用户完成率和满意度。",{"type":26,"tag":81,"props":1174,"children":1176},{"id":1175},"输入框设计",[1177],{"type":31,"value":1175},{"type":26,"tag":519,"props":1179,"children":1181},{"id":1180},"基础文本输入",[1182],{"type":31,"value":1180},{"type":26,"tag":526,"props":1184,"children":1187},{"className":1185,"code":1186,"language":531,"meta":7},[529],".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",[1188],{"type":26,"tag":534,"props":1189,"children":1190},{"__ignoreMap":7},[1191],{"type":31,"value":1186},{"type":26,"tag":519,"props":1193,"children":1195},{"id":1194},"标签和提示",[1196],{"type":31,"value":1194},{"type":26,"tag":526,"props":1198,"children":1201},{"className":1199,"code":1200,"language":643,"meta":7},[641],"\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",[1202],{"type":26,"tag":534,"props":1203,"children":1204},{"__ignoreMap":7},[1205],{"type":31,"value":1200},{"type":26,"tag":81,"props":1207,"children":1208},{"id":1159},[1209],{"type":31,"value":1159},{"type":26,"tag":526,"props":1211,"children":1214},{"className":1212,"code":1213,"language":583,"meta":7},[581],"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",[1215],{"type":26,"tag":534,"props":1216,"children":1217},{"__ignoreMap":7},[1218],{"type":31,"value":1213},{"type":26,"tag":81,"props":1220,"children":1222},{"id":1221},"选择框设计",[1223],{"type":31,"value":1221},{"type":26,"tag":526,"props":1225,"children":1228},{"className":1226,"code":1227,"language":531,"meta":7},[529],".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",[1229],{"type":26,"tag":534,"props":1230,"children":1231},{"__ignoreMap":7},[1232],{"type":31,"value":1227},{"type":26,"tag":81,"props":1234,"children":1236},{"id":1235},"复选框和单选按钮",[1237],{"type":31,"value":1235},{"type":26,"tag":526,"props":1239,"children":1242},{"className":1240,"code":1241,"language":531,"meta":7},[529],".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",[1243],{"type":26,"tag":534,"props":1244,"children":1245},{"__ignoreMap":7},[1246],{"type":31,"value":1241},{"type":26,"tag":81,"props":1248,"children":1250},{"id":1249},"文本区域",[1251],{"type":31,"value":1249},{"type":26,"tag":526,"props":1253,"children":1256},{"className":1254,"code":1255,"language":531,"meta":7},[529],".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",[1257],{"type":26,"tag":534,"props":1258,"children":1259},{"__ignoreMap":7},[1260],{"type":31,"value":1255},{"type":26,"tag":81,"props":1262,"children":1264},{"id":1263},"完整表单示例",[1265],{"type":31,"value":1263},{"type":26,"tag":526,"props":1267,"children":1270},{"className":1268,"code":1269,"language":583,"meta":7},[581],"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",[1271],{"type":26,"tag":534,"props":1272,"children":1273},{"__ignoreMap":7},[1274],{"type":31,"value":1269},{"type":26,"tag":81,"props":1276,"children":1277},{"id":665},[1278],{"type":31,"value":665},{"type":26,"tag":27,"props":1280,"children":1281},{},[1282,1283,1287],{"type":31,"value":672},{"type":26,"tag":674,"props":1284,"children":1285},{},[1286],{"type":31,"value":678},{"type":31,"value":680},{"type":26,"tag":214,"props":1289,"children":1290},{},[1291,1296,1301,1306,1310],{"type":26,"tag":218,"props":1292,"children":1293},{},[1294],{"type":31,"value":1295},"使用正确的输入类型",{"type":26,"tag":218,"props":1297,"children":1298},{},[1299],{"type":31,"value":1300},"提供实时验证反馈",{"type":26,"tag":218,"props":1302,"children":1303},{},[1304],{"type":31,"value":1305},"清晰的标签和提示",{"type":26,"tag":218,"props":1307,"children":1308},{},[1309],{"type":31,"value":688},{"type":26,"tag":218,"props":1311,"children":1312},{},[1313],{"type":31,"value":714},{"type":26,"tag":27,"props":1315,"children":1316},{},[1317,1318,1322],{"type":31,"value":719},{"type":26,"tag":674,"props":1319,"children":1320},{},[1321],{"type":31,"value":724},{"type":31,"value":680},{"type":26,"tag":214,"props":1324,"children":1325},{},[1326,1331,1336,1341,1346],{"type":26,"tag":218,"props":1327,"children":1328},{},[1329],{"type":31,"value":1330},"隐藏标签",{"type":26,"tag":218,"props":1332,"children":1333},{},[1334],{"type":31,"value":1335},"过度使用占位符",{"type":26,"tag":218,"props":1337,"children":1338},{},[1339],{"type":31,"value":1340},"验证后立即提交",{"type":26,"tag":218,"props":1342,"children":1343},{},[1344],{"type":31,"value":1345},"忽视无障碍性",{"type":26,"tag":218,"props":1347,"children":1348},{},[1349],{"type":31,"value":1350},"复杂的验证规则",{"type":26,"tag":81,"props":1352,"children":1353},{"id":771},[1354],{"type":31,"value":771},{"type":26,"tag":214,"props":1356,"children":1358},{"className":1357},[777],[1359,1368,1377,1386,1395,1404],{"type":26,"tag":218,"props":1360,"children":1362},{"className":1361},[782],[1363,1366],{"type":26,"tag":785,"props":1364,"children":1365},{"disabled":787,"type":788},[],{"type":31,"value":1367}," 所有控件都可用键盘导航",{"type":26,"tag":218,"props":1369,"children":1371},{"className":1370},[782],[1372,1375],{"type":26,"tag":785,"props":1373,"children":1374},{"disabled":787,"type":788},[],{"type":31,"value":1376}," 标签与输入框关联",{"type":26,"tag":218,"props":1378,"children":1380},{"className":1379},[782],[1381,1384],{"type":26,"tag":785,"props":1382,"children":1383},{"disabled":787,"type":788},[],{"type":31,"value":1385}," 验证消息清晰",{"type":26,"tag":218,"props":1387,"children":1389},{"className":1388},[782],[1390,1393],{"type":26,"tag":785,"props":1391,"children":1392},{"disabled":787,"type":788},[],{"type":31,"value":1394}," 色彩对比度足够",{"type":26,"tag":218,"props":1396,"children":1398},{"className":1397},[782],[1399,1402],{"type":26,"tag":785,"props":1400,"children":1401},{"disabled":787,"type":788},[],{"type":31,"value":1403}," 屏幕阅读器兼容",{"type":26,"tag":218,"props":1405,"children":1407},{"className":1406},[782],[1408,1411],{"type":26,"tag":785,"props":1409,"children":1410},{"disabled":787,"type":788},[],{"type":31,"value":1412}," 移动设备测试",{"title":7,"searchDepth":471,"depth":471,"links":1414},[1415,1416,1420,1421,1422,1423,1424,1425,1426],{"id":1153,"depth":474,"text":1153},{"id":1175,"depth":474,"text":1175,"children":1417},[1418,1419],{"id":1180,"depth":471,"text":1180},{"id":1194,"depth":471,"text":1194},{"id":1159,"depth":474,"text":1159},{"id":1221,"depth":474,"text":1221},{"id":1235,"depth":474,"text":1235},{"id":1249,"depth":474,"text":1249},{"id":1263,"depth":474,"text":1263},{"id":665,"depth":474,"text":665},{"id":771,"depth":474,"text":771},"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":1431,"image":17,"imageQuery":18,"pexelsPhotoId":19,"pexelsUrl":20,"featured":6,"readingTime":21,"body":1432,"_type":482,"_id":483,"_source":484,"_file":485,"_stem":486,"_extension":487},[13,14,15,16],{"type":23,"children":1433,"toc":1776},[1434,1438,1442,1446,1470,1474,1558,1562,1566,1570,1574,1593,1597,1601,1605,1609,1628,1632,1636,1640,1659,1663,1667,1671,1675,1679,1698,1702,1706,1710,1714,1718,1722,1726,1745,1749,1753,1757,1772],{"type":26,"tag":27,"props":1435,"children":1436},{},[1437],{"type":31,"value":32},{"type":26,"tag":27,"props":1439,"children":1440},{},[1441],{"type":31,"value":37},{"type":26,"tag":27,"props":1443,"children":1444},{},[1445],{"type":31,"value":42},{"type":26,"tag":27,"props":1447,"children":1448},{},[1449,1450,1454,1455,1459,1460,1464,1465,1469],{"type":31,"value":47},{"type":26,"tag":49,"props":1451,"children":1452},{"href":51},[1453],{"type":31,"value":54},{"type":31,"value":56},{"type":26,"tag":49,"props":1456,"children":1457},{"href":59},[1458],{"type":31,"value":62},{"type":31,"value":56},{"type":26,"tag":49,"props":1461,"children":1462},{"href":66},[1463],{"type":31,"value":69},{"type":31,"value":71},{"type":26,"tag":49,"props":1466,"children":1467},{"href":74},[1468],{"type":31,"value":77},{"type":31,"value":79},{"type":26,"tag":81,"props":1471,"children":1472},{"id":83},[1473],{"type":31,"value":86},{"type":26,"tag":88,"props":1475,"children":1476},{},[1477,1495],{"type":26,"tag":92,"props":1478,"children":1479},{},[1480],{"type":26,"tag":96,"props":1481,"children":1482},{},[1483,1487,1491],{"type":26,"tag":100,"props":1484,"children":1485},{},[1486],{"type":31,"value":104},{"type":26,"tag":100,"props":1488,"children":1489},{},[1490],{"type":31,"value":109},{"type":26,"tag":100,"props":1492,"children":1493},{},[1494],{"type":31,"value":114},{"type":26,"tag":116,"props":1496,"children":1497},{},[1498,1513,1528,1543],{"type":26,"tag":96,"props":1499,"children":1500},{},[1501,1505,1509],{"type":26,"tag":123,"props":1502,"children":1503},{},[1504],{"type":31,"value":127},{"type":26,"tag":123,"props":1506,"children":1507},{},[1508],{"type":31,"value":132},{"type":26,"tag":123,"props":1510,"children":1511},{},[1512],{"type":31,"value":137},{"type":26,"tag":96,"props":1514,"children":1515},{},[1516,1520,1524],{"type":26,"tag":123,"props":1517,"children":1518},{},[1519],{"type":31,"value":145},{"type":26,"tag":123,"props":1521,"children":1522},{},[1523],{"type":31,"value":150},{"type":26,"tag":123,"props":1525,"children":1526},{},[1527],{"type":31,"value":155},{"type":26,"tag":96,"props":1529,"children":1530},{},[1531,1535,1539],{"type":26,"tag":123,"props":1532,"children":1533},{},[1534],{"type":31,"value":163},{"type":26,"tag":123,"props":1536,"children":1537},{},[1538],{"type":31,"value":168},{"type":26,"tag":123,"props":1540,"children":1541},{},[1542],{"type":31,"value":173},{"type":26,"tag":96,"props":1544,"children":1545},{},[1546,1550,1554],{"type":26,"tag":123,"props":1547,"children":1548},{},[1549],{"type":31,"value":181},{"type":26,"tag":123,"props":1551,"children":1552},{},[1553],{"type":31,"value":186},{"type":26,"tag":123,"props":1555,"children":1556},{},[1557],{"type":31,"value":191},{"type":26,"tag":27,"props":1559,"children":1560},{},[1561],{"type":31,"value":196},{"type":26,"tag":81,"props":1563,"children":1564},{"id":199},[1565],{"type":31,"value":202},{"type":26,"tag":27,"props":1567,"children":1568},{},[1569],{"type":31,"value":207},{"type":26,"tag":27,"props":1571,"children":1572},{},[1573],{"type":31,"value":212},{"type":26,"tag":214,"props":1575,"children":1576},{},[1577,1581,1585,1589],{"type":26,"tag":218,"props":1578,"children":1579},{},[1580],{"type":31,"value":222},{"type":26,"tag":218,"props":1582,"children":1583},{},[1584],{"type":31,"value":227},{"type":26,"tag":218,"props":1586,"children":1587},{},[1588],{"type":31,"value":232},{"type":26,"tag":218,"props":1590,"children":1591},{},[1592],{"type":31,"value":237},{"type":26,"tag":27,"props":1594,"children":1595},{},[1596],{"type":31,"value":242},{"type":26,"tag":81,"props":1598,"children":1599},{"id":245},[1600],{"type":31,"value":248},{"type":26,"tag":27,"props":1602,"children":1603},{},[1604],{"type":31,"value":253},{"type":26,"tag":27,"props":1606,"children":1607},{},[1608],{"type":31,"value":258},{"type":26,"tag":214,"props":1610,"children":1611},{},[1612,1616,1620,1624],{"type":26,"tag":218,"props":1613,"children":1614},{},[1615],{"type":31,"value":266},{"type":26,"tag":218,"props":1617,"children":1618},{},[1619],{"type":31,"value":271},{"type":26,"tag":218,"props":1621,"children":1622},{},[1623],{"type":31,"value":276},{"type":26,"tag":218,"props":1625,"children":1626},{},[1627],{"type":31,"value":281},{"type":26,"tag":27,"props":1629,"children":1630},{},[1631],{"type":31,"value":286},{"type":26,"tag":81,"props":1633,"children":1634},{"id":289},[1635],{"type":31,"value":292},{"type":26,"tag":27,"props":1637,"children":1638},{},[1639],{"type":31,"value":297},{"type":26,"tag":214,"props":1641,"children":1642},{},[1643,1647,1651,1655],{"type":26,"tag":218,"props":1644,"children":1645},{},[1646],{"type":31,"value":305},{"type":26,"tag":218,"props":1648,"children":1649},{},[1650],{"type":31,"value":310},{"type":26,"tag":218,"props":1652,"children":1653},{},[1654],{"type":31,"value":315},{"type":26,"tag":218,"props":1656,"children":1657},{},[1658],{"type":31,"value":320},{"type":26,"tag":27,"props":1660,"children":1661},{},[1662],{"type":31,"value":325},{"type":26,"tag":27,"props":1664,"children":1665},{},[1666],{"type":31,"value":330},{"type":26,"tag":81,"props":1668,"children":1669},{"id":333},[1670],{"type":31,"value":336},{"type":26,"tag":27,"props":1672,"children":1673},{},[1674],{"type":31,"value":341},{"type":26,"tag":27,"props":1676,"children":1677},{},[1678],{"type":31,"value":346},{"type":26,"tag":214,"props":1680,"children":1681},{},[1682,1686,1690,1694],{"type":26,"tag":218,"props":1683,"children":1684},{},[1685],{"type":31,"value":354},{"type":26,"tag":218,"props":1687,"children":1688},{},[1689],{"type":31,"value":359},{"type":26,"tag":218,"props":1691,"children":1692},{},[1693],{"type":31,"value":364},{"type":26,"tag":218,"props":1695,"children":1696},{},[1697],{"type":31,"value":369},{"type":26,"tag":27,"props":1699,"children":1700},{},[1701],{"type":31,"value":374},{"type":26,"tag":81,"props":1703,"children":1704},{"id":377},[1705],{"type":31,"value":380},{"type":26,"tag":27,"props":1707,"children":1708},{},[1709],{"type":31,"value":385},{"type":26,"tag":27,"props":1711,"children":1712},{},[1713],{"type":31,"value":390},{"type":26,"tag":27,"props":1715,"children":1716},{},[1717],{"type":31,"value":395},{"type":26,"tag":81,"props":1719,"children":1720},{"id":398},[1721],{"type":31,"value":401},{"type":26,"tag":27,"props":1723,"children":1724},{},[1725],{"type":31,"value":406},{"type":26,"tag":214,"props":1727,"children":1728},{},[1729,1733,1737,1741],{"type":26,"tag":218,"props":1730,"children":1731},{},[1732],{"type":31,"value":414},{"type":26,"tag":218,"props":1734,"children":1735},{},[1736],{"type":31,"value":419},{"type":26,"tag":218,"props":1738,"children":1739},{},[1740],{"type":31,"value":424},{"type":26,"tag":218,"props":1742,"children":1743},{},[1744],{"type":31,"value":429},{"type":26,"tag":27,"props":1746,"children":1747},{},[1748],{"type":31,"value":434},{"type":26,"tag":81,"props":1750,"children":1751},{"id":437},[1752],{"type":31,"value":440},{"type":26,"tag":27,"props":1754,"children":1755},{},[1756],{"type":31,"value":445},{"type":26,"tag":447,"props":1758,"children":1759},{},[1760,1764,1768],{"type":26,"tag":218,"props":1761,"children":1762},{},[1763],{"type":31,"value":454},{"type":26,"tag":218,"props":1765,"children":1766},{},[1767],{"type":31,"value":459},{"type":26,"tag":218,"props":1769,"children":1770},{},[1771],{"type":31,"value":464},{"type":26,"tag":27,"props":1773,"children":1774},{},[1775],{"type":31,"value":469},{"title":7,"searchDepth":471,"depth":471,"links":1777},[1778,1779,1780,1781,1782,1783,1784,1785],{"id":83,"depth":474,"text":86},{"id":199,"depth":474,"text":202},{"id":245,"depth":474,"text":248},{"id":289,"depth":474,"text":292},{"id":333,"depth":474,"text":336},{"id":377,"depth":474,"text":380},{"id":398,"depth":474,"text":401},{"id":437,"depth":474,"text":440},1779260404903]