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