[{"data":1,"prerenderedAt":2905},["ShallowReactive",2],{"article-/topics/design/data-display-component-guide":3,"related-design":1089,"content-query-ixu8WePV7b":2026},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"image":11,"head":12,"body":17,"_type":1083,"_id":1084,"_source":1085,"_file":1086,"_stem":1087,"_extension":1088},"/topics/design/data-display-component-guide","design",false,"","数据展示组件设计完整指南","深入解析表格、列表、卡片、图表等数据展示组件的设计原则与实现方案，构建高效直观的数据可视化界面","2026-01-01","/images/topics/design/data-display-component.jpg",{"meta":13},[14],{"name":15,"content":16},"keywords","数据展示组件,表格组件,列表组件,卡片组件,数据可视化,组件设计,UI设计",{"type":18,"children":19,"toc":1050},"root",[20,27,33,38,43,219,224,229,235,240,253,258,263,472,483,488,493,502,522,530,548,556,579,588,593,598,603,608,617,622,627,636,641,646,651,660,665,670,679,684,689,698,703,708,717,722,727,736,741,746,751,760,765,774,779,785,790,823,829,834,845,851,952,958,981,986,991,1045],{"type":21,"tag":22,"props":23,"children":24},"element","h2",{"id":8},[25],{"type":26,"value":8},"text",{"type":21,"tag":28,"props":29,"children":30},"p",{},[31],{"type":26,"value":32},"数据展示是用户界面中最核心的功能之一。无论是后台管理系统的数据表格，还是电商平台的商品列表，优秀的数据展示组件能够让用户快速理解信息、高效完成操作。本文将系统讲解各类数据展示组件的设计原则与实现方案。",{"type":21,"tag":22,"props":34,"children":36},{"id":35},"数据展示组件分类",[37],{"type":26,"value":35},{"type":21,"tag":28,"props":39,"children":40},{},[41],{"type":26,"value":42},"根据数据特征和使用场景，数据展示组件可分为以下几类：",{"type":21,"tag":44,"props":45,"children":46},"table",{},[47,76],{"type":21,"tag":48,"props":49,"children":50},"thead",{},[51],{"type":21,"tag":52,"props":53,"children":54},"tr",{},[55,61,66,71],{"type":21,"tag":56,"props":57,"children":58},"th",{},[59],{"type":26,"value":60},"组件类型",{"type":21,"tag":56,"props":62,"children":63},{},[64],{"type":26,"value":65},"适用场景",{"type":21,"tag":56,"props":67,"children":68},{},[69],{"type":26,"value":70},"数据特点",{"type":21,"tag":56,"props":72,"children":73},{},[74],{"type":26,"value":75},"典型应用",{"type":21,"tag":77,"props":78,"children":79},"tbody",{},[80,104,127,150,173,196],{"type":21,"tag":52,"props":81,"children":82},{},[83,89,94,99],{"type":21,"tag":84,"props":85,"children":86},"td",{},[87],{"type":26,"value":88},"表格 Table",{"type":21,"tag":84,"props":90,"children":91},{},[92],{"type":26,"value":93},"多维度对比",{"type":21,"tag":84,"props":95,"children":96},{},[97],{"type":26,"value":98},"结构化、规整",{"type":21,"tag":84,"props":100,"children":101},{},[102],{"type":26,"value":103},"后台管理、报表",{"type":21,"tag":52,"props":105,"children":106},{},[107,112,117,122],{"type":21,"tag":84,"props":108,"children":109},{},[110],{"type":26,"value":111},"列表 List",{"type":21,"tag":84,"props":113,"children":114},{},[115],{"type":26,"value":116},"线性浏览",{"type":21,"tag":84,"props":118,"children":119},{},[120],{"type":26,"value":121},"单维度、有序",{"type":21,"tag":84,"props":123,"children":124},{},[125],{"type":26,"value":126},"消息列表、动态流",{"type":21,"tag":52,"props":128,"children":129},{},[130,135,140,145],{"type":21,"tag":84,"props":131,"children":132},{},[133],{"type":26,"value":134},"卡片 Card",{"type":21,"tag":84,"props":136,"children":137},{},[138],{"type":26,"value":139},"信息聚合",{"type":21,"tag":84,"props":141,"children":142},{},[143],{"type":26,"value":144},"多元素组合",{"type":21,"tag":84,"props":146,"children":147},{},[148],{"type":26,"value":149},"商品展示、项目面板",{"type":21,"tag":52,"props":151,"children":152},{},[153,158,163,168],{"type":21,"tag":84,"props":154,"children":155},{},[156],{"type":26,"value":157},"描述列表",{"type":21,"tag":84,"props":159,"children":160},{},[161],{"type":26,"value":162},"详情展示",{"type":21,"tag":84,"props":164,"children":165},{},[166],{"type":26,"value":167},"键值对形式",{"type":21,"tag":84,"props":169,"children":170},{},[171],{"type":26,"value":172},"订单详情、用户信息",{"type":21,"tag":52,"props":174,"children":175},{},[176,181,186,191],{"type":21,"tag":84,"props":177,"children":178},{},[179],{"type":26,"value":180},"统计数值",{"type":21,"tag":84,"props":182,"children":183},{},[184],{"type":26,"value":185},"核心指标",{"type":21,"tag":84,"props":187,"children":188},{},[189],{"type":26,"value":190},"单一数值",{"type":21,"tag":84,"props":192,"children":193},{},[194],{"type":26,"value":195},"数据大屏、仪表盘",{"type":21,"tag":52,"props":197,"children":198},{},[199,204,209,214],{"type":21,"tag":84,"props":200,"children":201},{},[202],{"type":26,"value":203},"时间线",{"type":21,"tag":84,"props":205,"children":206},{},[207],{"type":26,"value":208},"时序事件",{"type":21,"tag":84,"props":210,"children":211},{},[212],{"type":26,"value":213},"时间相关",{"type":21,"tag":84,"props":215,"children":216},{},[217],{"type":26,"value":218},"物流跟踪、操作日志",{"type":21,"tag":22,"props":220,"children":222},{"id":221},"表格组件设计",[223],{"type":26,"value":221},{"type":21,"tag":28,"props":225,"children":226},{},[227],{"type":26,"value":228},"表格是展示结构化数据最常用的方式，设计时需要平衡信息密度与可读性。",{"type":21,"tag":230,"props":231,"children":233},"h3",{"id":232},"表格基础结构",[234],{"type":26,"value":232},{"type":21,"tag":28,"props":236,"children":237},{},[238],{"type":26,"value":239},"一个完整的表格组件应包含以下元素：",{"type":21,"tag":241,"props":242,"children":247},"pre",{"className":243,"code":245,"language":246,"meta":7},[244],"language-vue","\u003Ctemplate>\n  \u003Cdiv class=\"data-table\">\n    \u003C!-- 表格工具栏：搜索、筛选、操作按钮 -->\n    \u003Cdiv class=\"table-toolbar\">\n      \u003Cdiv class=\"toolbar-left\">\n        \u003Cslot name=\"toolbar-left\">\n          \u003CSearchInput v-model=\"searchQuery\" placeholder=\"搜索...\" />\n        \u003C/slot>\n      \u003C/div>\n      \u003Cdiv class=\"toolbar-right\">\n        \u003Cslot name=\"toolbar-right\">\n          \u003CButton @click=\"handleExport\">导出\u003C/Button>\n          \u003CButton type=\"primary\" @click=\"handleAdd\">新增\u003C/Button>\n        \u003C/slot>\n      \u003C/div>\n    \u003C/div>\n    \n    \u003C!-- 表格主体 -->\n    \u003Ctable class=\"table-main\">\n      \u003Cthead>\n        \u003Ctr>\n          \u003Cth v-if=\"selectable\" class=\"col-checkbox\">\n            \u003CCheckbox \n              :checked=\"isAllSelected\" \n              :indeterminate=\"isPartialSelected\"\n              @change=\"toggleSelectAll\" \n            />\n          \u003C/th>\n          \u003Cth \n            v-for=\"column in columns\" \n            :key=\"column.key\"\n            :class=\"getColumnClass(column)\"\n            :style=\"getColumnStyle(column)\"\n            @click=\"handleSort(column)\"\n          >\n            \u003Cspan class=\"th-content\">\n              {{ column.title }}\n              \u003CSortIcon v-if=\"column.sortable\" :direction=\"getSortDirection(column)\" />\n            \u003C/span>\n          \u003C/th>\n          \u003Cth v-if=\"hasActions\" class=\"col-actions\">操作\u003C/th>\n        \u003C/tr>\n      \u003C/thead>\n      \u003Ctbody>\n        \u003Ctr \n          v-for=\"(row, index) in displayData\" \n          :key=\"getRowKey(row, index)\"\n          :class=\"{ 'row-selected': isRowSelected(row) }\"\n        >\n          \u003Ctd v-if=\"selectable\" class=\"col-checkbox\">\n            \u003CCheckbox :checked=\"isRowSelected(row)\" @change=\"toggleRowSelect(row)\" />\n          \u003C/td>\n          \u003Ctd v-for=\"column in columns\" :key=\"column.key\" :class=\"column.align\">\n            \u003Cslot :name=\"column.key\" :row=\"row\" :value=\"getCellValue(row, column)\">\n              {{ formatCellValue(row, column) }}\n            \u003C/slot>\n          \u003C/td>\n          \u003Ctd v-if=\"hasActions\" class=\"col-actions\">\n            \u003Cslot name=\"actions\" :row=\"row\" :index=\"index\" />\n          \u003C/td>\n        \u003C/tr>\n      \u003C/tbody>\n    \u003C/table>\n    \n    \u003C!-- 分页控件 -->\n    \u003Cdiv class=\"table-pagination\">\n      \u003CPagination \n        v-model:current=\"currentPage\"\n        v-model:pageSize=\"pageSize\"\n        :total=\"total\"\n        show-size-changer\n        show-quick-jumper\n      />\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n","vue",[248],{"type":21,"tag":249,"props":250,"children":251},"code",{"__ignoreMap":7},[252],{"type":26,"value":245},{"type":21,"tag":230,"props":254,"children":256},{"id":255},"列宽度设计原则",[257],{"type":26,"value":255},{"type":21,"tag":28,"props":259,"children":260},{},[261],{"type":26,"value":262},"表格列宽设计直接影响可读性，应遵循以下原则：",{"type":21,"tag":44,"props":264,"children":265},{},[266,292],{"type":21,"tag":48,"props":267,"children":268},{},[269],{"type":21,"tag":52,"props":270,"children":271},{},[272,277,282,287],{"type":21,"tag":56,"props":273,"children":274},{},[275],{"type":26,"value":276},"内容类型",{"type":21,"tag":56,"props":278,"children":279},{},[280],{"type":26,"value":281},"推荐宽度",{"type":21,"tag":56,"props":283,"children":284},{},[285],{"type":26,"value":286},"对齐方式",{"type":21,"tag":56,"props":288,"children":289},{},[290],{"type":26,"value":291},"说明",{"type":21,"tag":77,"props":293,"children":294},{},[295,318,339,361,384,407,429,451],{"type":21,"tag":52,"props":296,"children":297},{},[298,303,308,313],{"type":21,"tag":84,"props":299,"children":300},{},[301],{"type":26,"value":302},"序号/ID",{"type":21,"tag":84,"props":304,"children":305},{},[306],{"type":26,"value":307},"60-80px",{"type":21,"tag":84,"props":309,"children":310},{},[311],{"type":26,"value":312},"居中",{"type":21,"tag":84,"props":314,"children":315},{},[316],{"type":26,"value":317},"固定宽度",{"type":21,"tag":52,"props":319,"children":320},{},[321,326,331,335],{"type":21,"tag":84,"props":322,"children":323},{},[324],{"type":26,"value":325},"复选框",{"type":21,"tag":84,"props":327,"children":328},{},[329],{"type":26,"value":330},"50px",{"type":21,"tag":84,"props":332,"children":333},{},[334],{"type":26,"value":312},{"type":21,"tag":84,"props":336,"children":337},{},[338],{"type":26,"value":317},{"type":21,"tag":52,"props":340,"children":341},{},[342,347,352,356],{"type":21,"tag":84,"props":343,"children":344},{},[345],{"type":26,"value":346},"状态标签",{"type":21,"tag":84,"props":348,"children":349},{},[350],{"type":26,"value":351},"80-120px",{"type":21,"tag":84,"props":353,"children":354},{},[355],{"type":26,"value":312},{"type":21,"tag":84,"props":357,"children":358},{},[359],{"type":26,"value":360},"根据标签长度",{"type":21,"tag":52,"props":362,"children":363},{},[364,369,374,379],{"type":21,"tag":84,"props":365,"children":366},{},[367],{"type":26,"value":368},"日期时间",{"type":21,"tag":84,"props":370,"children":371},{},[372],{"type":26,"value":373},"140-180px",{"type":21,"tag":84,"props":375,"children":376},{},[377],{"type":26,"value":378},"居左",{"type":21,"tag":84,"props":380,"children":381},{},[382],{"type":26,"value":383},"根据格式决定",{"type":21,"tag":52,"props":385,"children":386},{},[387,392,397,402],{"type":21,"tag":84,"props":388,"children":389},{},[390],{"type":26,"value":391},"金额数字",{"type":21,"tag":84,"props":393,"children":394},{},[395],{"type":26,"value":396},"100-140px",{"type":21,"tag":84,"props":398,"children":399},{},[400],{"type":26,"value":401},"居右",{"type":21,"tag":84,"props":403,"children":404},{},[405],{"type":26,"value":406},"便于对比",{"type":21,"tag":52,"props":408,"children":409},{},[410,415,420,424],{"type":21,"tag":84,"props":411,"children":412},{},[413],{"type":26,"value":414},"名称文本",{"type":21,"tag":84,"props":416,"children":417},{},[418],{"type":26,"value":419},"150-250px",{"type":21,"tag":84,"props":421,"children":422},{},[423],{"type":26,"value":378},{"type":21,"tag":84,"props":425,"children":426},{},[427],{"type":26,"value":428},"可伸缩",{"type":21,"tag":52,"props":430,"children":431},{},[432,437,442,446],{"type":21,"tag":84,"props":433,"children":434},{},[435],{"type":26,"value":436},"描述长文本",{"type":21,"tag":84,"props":438,"children":439},{},[440],{"type":26,"value":441},"自适应",{"type":21,"tag":84,"props":443,"children":444},{},[445],{"type":26,"value":378},{"type":21,"tag":84,"props":447,"children":448},{},[449],{"type":26,"value":450},"占据剩余空间",{"type":21,"tag":52,"props":452,"children":453},{},[454,459,464,468],{"type":21,"tag":84,"props":455,"children":456},{},[457],{"type":26,"value":458},"操作按钮",{"type":21,"tag":84,"props":460,"children":461},{},[462],{"type":26,"value":463},"根据按钮数量",{"type":21,"tag":84,"props":465,"children":466},{},[467],{"type":26,"value":312},{"type":21,"tag":84,"props":469,"children":470},{},[471],{"type":26,"value":317},{"type":21,"tag":241,"props":473,"children":478},{"className":474,"code":476,"language":477,"meta":7},[475],"language-typescript","// 列宽度计算逻辑\ninterface ColumnConfig {\n  key: string\n  title: string\n  width?: number | string      // 固定宽度\n  minWidth?: number            // 最小宽度\n  maxWidth?: number            // 最大宽度\n  flex?: number                // 弹性比例\n  fixed?: 'left' | 'right'     // 固定列\n}\n\nfunction calculateColumnWidths(columns: ColumnConfig[], containerWidth: number) {\n  // 1. 计算固定宽度列占用的空间\n  const fixedWidth = columns\n    .filter(col => col.width)\n    .reduce((sum, col) => sum + parseWidth(col.width), 0)\n  \n  // 2. 剩余空间分配给弹性列\n  const flexColumns = columns.filter(col => !col.width && col.flex)\n  const totalFlex = flexColumns.reduce((sum, col) => sum + (col.flex || 1), 0)\n  const remainingWidth = containerWidth - fixedWidth\n  \n  // 3. 按比例分配宽度，同时尊重最小/最大宽度限制\n  return columns.map(col => {\n    if (col.width) return parseWidth(col.width)\n    \n    const flexWidth = (remainingWidth * (col.flex || 1)) / totalFlex\n    return Math.min(\n      Math.max(flexWidth, col.minWidth || 80),\n      col.maxWidth || Infinity\n    )\n  })\n}\n","typescript",[479],{"type":21,"tag":249,"props":480,"children":481},{"__ignoreMap":7},[482],{"type":26,"value":476},{"type":21,"tag":230,"props":484,"children":486},{"id":485},"表格交互设计",[487],{"type":26,"value":485},{"type":21,"tag":28,"props":489,"children":490},{},[491],{"type":26,"value":492},"表格的交互设计应该直观且高效：",{"type":21,"tag":28,"props":494,"children":495},{},[496],{"type":21,"tag":497,"props":498,"children":499},"strong",{},[500],{"type":26,"value":501},"1. 排序交互",{"type":21,"tag":503,"props":504,"children":505},"ul",{},[506,512,517],{"type":21,"tag":507,"props":508,"children":509},"li",{},[510],{"type":26,"value":511},"点击表头触发排序",{"type":21,"tag":507,"props":513,"children":514},{},[515],{"type":26,"value":516},"支持升序、降序、取消排序三种状态循环",{"type":21,"tag":507,"props":518,"children":519},{},[520],{"type":26,"value":521},"多列排序时显示排序优先级",{"type":21,"tag":28,"props":523,"children":524},{},[525],{"type":21,"tag":497,"props":526,"children":527},{},[528],{"type":26,"value":529},"2. 筛选交互",{"type":21,"tag":503,"props":531,"children":532},{},[533,538,543],{"type":21,"tag":507,"props":534,"children":535},{},[536],{"type":26,"value":537},"列头筛选图标点击弹出筛选面板",{"type":21,"tag":507,"props":539,"children":540},{},[541],{"type":26,"value":542},"支持多选、范围筛选、搜索筛选",{"type":21,"tag":507,"props":544,"children":545},{},[546],{"type":26,"value":547},"筛选激活时图标高亮提示",{"type":21,"tag":28,"props":549,"children":550},{},[551],{"type":21,"tag":497,"props":552,"children":553},{},[554],{"type":26,"value":555},"3. 行选择交互",{"type":21,"tag":503,"props":557,"children":558},{},[559,564,569,574],{"type":21,"tag":507,"props":560,"children":561},{},[562],{"type":26,"value":563},"点击复选框选择单行",{"type":21,"tag":507,"props":565,"children":566},{},[567],{"type":26,"value":568},"表头复选框控制全选/取消",{"type":21,"tag":507,"props":570,"children":571},{},[572],{"type":26,"value":573},"部分选中时显示不确定状态",{"type":21,"tag":507,"props":575,"children":576},{},[577],{"type":26,"value":578},"支持 Shift + 点击进行范围选择",{"type":21,"tag":241,"props":580,"children":583},{"className":581,"code":582,"language":477,"meta":7},[475],"// 范围选择实现\nfunction handleRowSelect(row: DataRow, event: MouseEvent) {\n  if (event.shiftKey && lastSelectedIndex !== null) {\n    // Shift + 点击：选择范围内所有行\n    const currentIndex = data.value.indexOf(row)\n    const [start, end] = [lastSelectedIndex, currentIndex].sort((a, b) => a - b)\n    \n    for (let i = start; i \u003C= end; i++) {\n      selectedRows.add(getRowKey(data.value[i]))\n    }\n  } else {\n    // 普通点击：切换单行选择状态\n    toggleRowSelect(row)\n    lastSelectedIndex = data.value.indexOf(row)\n  }\n}\n",[584],{"type":21,"tag":249,"props":585,"children":586},{"__ignoreMap":7},[587],{"type":26,"value":582},{"type":21,"tag":22,"props":589,"children":591},{"id":590},"列表组件设计",[592],{"type":26,"value":590},{"type":21,"tag":28,"props":594,"children":595},{},[596],{"type":26,"value":597},"列表适合展示线性数据，常见于内容流、消息列表等场景。",{"type":21,"tag":230,"props":599,"children":601},{"id":600},"列表项结构设计",[602],{"type":26,"value":600},{"type":21,"tag":28,"props":604,"children":605},{},[606],{"type":26,"value":607},"一个通用的列表项应包含以下区域：",{"type":21,"tag":241,"props":609,"children":612},{"className":610,"code":611,"language":246,"meta":7},[244],"\u003Ctemplate>\n  \u003Cdiv class=\"list-item\" :class=\"{ 'list-item--clickable': clickable }\">\n    \u003C!-- 前置区域：头像、图标或选择框 -->\n    \u003Cdiv class=\"list-item__prefix\">\n      \u003Cslot name=\"prefix\">\n        \u003CAvatar v-if=\"avatar\" :src=\"avatar\" :size=\"avatarSize\" />\n        \u003CIcon v-else-if=\"icon\" :name=\"icon\" />\n      \u003C/slot>\n    \u003C/div>\n    \n    \u003C!-- 主内容区域 -->\n    \u003Cdiv class=\"list-item__content\">\n      \u003Cdiv class=\"list-item__header\">\n        \u003Cspan class=\"list-item__title\">{{ title }}\u003C/span>\n        \u003Cspan v-if=\"extra\" class=\"list-item__extra\">{{ extra }}\u003C/span>\n      \u003C/div>\n      \u003Cdiv v-if=\"description\" class=\"list-item__description\">\n        {{ description }}\n      \u003C/div>\n      \u003Cdiv v-if=\"$slots.footer\" class=\"list-item__footer\">\n        \u003Cslot name=\"footer\" />\n      \u003C/div>\n    \u003C/div>\n    \n    \u003C!-- 后置区域：操作按钮、箭头 -->\n    \u003Cdiv class=\"list-item__suffix\">\n      \u003Cslot name=\"suffix\">\n        \u003CIcon v-if=\"showArrow\" name=\"chevron-right\" class=\"list-item__arrow\" />\n      \u003C/slot>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cstyle scoped>\n.list-item {\n  display: flex;\n  align-items: flex-start;\n  padding: var(--spacing-md) var(--spacing-lg);\n  border-bottom: 1px solid var(--color-border);\n  transition: background-color 0.2s;\n}\n\n.list-item--clickable {\n  cursor: pointer;\n}\n\n.list-item--clickable:hover {\n  background-color: var(--color-bg-hover);\n}\n\n.list-item__prefix {\n  flex-shrink: 0;\n  margin-right: var(--spacing-md);\n}\n\n.list-item__content {\n  flex: 1;\n  min-width: 0;  /* 确保文本能够正确截断 */\n}\n\n.list-item__header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n}\n\n.list-item__title {\n  font-weight: 500;\n  color: var(--color-text-primary);\n}\n\n.list-item__description {\n  margin-top: var(--spacing-xs);\n  font-size: var(--font-size-sm);\n  color: var(--color-text-secondary);\n  line-height: 1.5;\n}\n\n.list-item__suffix {\n  flex-shrink: 0;\n  margin-left: var(--spacing-md);\n  display: flex;\n  align-items: center;\n}\n\u003C/style>\n",[613],{"type":21,"tag":249,"props":614,"children":615},{"__ignoreMap":7},[616],{"type":26,"value":611},{"type":21,"tag":230,"props":618,"children":620},{"id":619},"列表分组与分隔",[621],{"type":26,"value":619},{"type":21,"tag":28,"props":623,"children":624},{},[625],{"type":26,"value":626},"当列表数据较多时，合理的分组能帮助用户快速定位：",{"type":21,"tag":241,"props":628,"children":631},{"className":629,"code":630,"language":246,"meta":7},[244],"\u003Ctemplate>\n  \u003Cdiv class=\"grouped-list\">\n    \u003Ctemplate v-for=\"(group, index) in groupedData\" :key=\"group.key\">\n      \u003C!-- 分组标题：吸顶效果 -->\n      \u003Cdiv class=\"list-group-header\" :class=\"{ 'is-sticky': stickyHeader }\">\n        \u003Cspan class=\"group-title\">{{ group.title }}\u003C/span>\n        \u003Cspan class=\"group-count\">{{ group.items.length }}\u003C/span>\n      \u003C/div>\n      \n      \u003C!-- 分组内容 -->\n      \u003Cdiv class=\"list-group-body\">\n        \u003CListItem \n          v-for=\"item in group.items\" \n          :key=\"item.id\" \n          v-bind=\"item\"\n          @click=\"handleItemClick(item)\"\n        />\n      \u003C/div>\n      \n      \u003C!-- 分组间隔 -->\n      \u003Cdiv v-if=\"index \u003C groupedData.length - 1\" class=\"list-group-divider\" />\n    \u003C/template>\n  \u003C/div>\n\u003C/template>\n",[632],{"type":21,"tag":249,"props":633,"children":634},{"__ignoreMap":7},[635],{"type":26,"value":630},{"type":21,"tag":22,"props":637,"children":639},{"id":638},"卡片组件设计",[640],{"type":26,"value":638},{"type":21,"tag":28,"props":642,"children":643},{},[644],{"type":26,"value":645},"卡片是一种将相关信息聚合在一起的容器组件，适合展示多元素组合的内容。",{"type":21,"tag":230,"props":647,"children":649},{"id":648},"卡片布局模式",[650],{"type":26,"value":648},{"type":21,"tag":241,"props":652,"children":655},{"className":653,"code":654,"language":246,"meta":7},[244],"\u003Ctemplate>\n  \u003Cdiv class=\"card\" :class=\"[`card--${variant}`, { 'card--hoverable': hoverable }]\">\n    \u003C!-- 卡片封面图 -->\n    \u003Cdiv v-if=\"cover\" class=\"card__cover\">\n      \u003Cimg :src=\"cover\" :alt=\"title\" loading=\"lazy\" />\n      \u003Cdiv v-if=\"badge\" class=\"card__badge\">{{ badge }}\u003C/div>\n    \u003C/div>\n    \n    \u003C!-- 卡片头部 -->\n    \u003Cdiv v-if=\"$slots.header || title\" class=\"card__header\">\n      \u003Cslot name=\"header\">\n        \u003Cdiv class=\"card__title-wrapper\">\n          \u003CAvatar v-if=\"avatar\" :src=\"avatar\" size=\"small\" />\n          \u003Cdiv class=\"card__title-content\">\n            \u003Ch3 class=\"card__title\">{{ title }}\u003C/h3>\n            \u003Cspan v-if=\"subtitle\" class=\"card__subtitle\">{{ subtitle }}\u003C/span>\n          \u003C/div>\n        \u003C/div>\n        \u003Cdiv v-if=\"$slots.extra\" class=\"card__extra\">\n          \u003Cslot name=\"extra\" />\n        \u003C/div>\n      \u003C/slot>\n    \u003C/div>\n    \n    \u003C!-- 卡片主体 -->\n    \u003Cdiv class=\"card__body\">\n      \u003Cslot />\n    \u003C/div>\n    \n    \u003C!-- 卡片底部 -->\n    \u003Cdiv v-if=\"$slots.footer || actions\" class=\"card__footer\">\n      \u003Cslot name=\"footer\">\n        \u003Cdiv class=\"card__actions\">\n          \u003CButton \n            v-for=\"action in actions\" \n            :key=\"action.key\"\n            :type=\"action.type || 'text'\"\n            @click=\"handleAction(action)\"\n          >\n            \u003CIcon v-if=\"action.icon\" :name=\"action.icon\" />\n            {{ action.label }}\n          \u003C/Button>\n        \u003C/div>\n      \u003C/slot>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n",[656],{"type":21,"tag":249,"props":657,"children":658},{"__ignoreMap":7},[659],{"type":26,"value":654},{"type":21,"tag":230,"props":661,"children":663},{"id":662},"卡片网格布局",[664],{"type":26,"value":662},{"type":21,"tag":28,"props":666,"children":667},{},[668],{"type":26,"value":669},"卡片通常以网格形式排列，需要考虑响应式适配：",{"type":21,"tag":241,"props":671,"children":674},{"className":672,"code":673,"language":246,"meta":7},[244],"\u003Ctemplate>\n  \u003Cdiv \n    class=\"card-grid\" \n    :style=\"{ \n      '--min-card-width': `${minCardWidth}px`,\n      '--grid-gap': `${gap}px`\n    }\"\n  >\n    \u003CCard \n      v-for=\"item in items\" \n      :key=\"item.id\"\n      :title=\"item.title\"\n      :cover=\"item.cover\"\n      :description=\"item.description\"\n    />\n  \u003C/div>\n\u003C/template>\n\n\u003Cstyle scoped>\n.card-grid {\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(var(--min-card-width), 1fr));\n  gap: var(--grid-gap);\n}\n\n/* 响应式断点调整 */\n@media (max-width: 640px) {\n  .card-grid {\n    grid-template-columns: 1fr;  /* 小屏幕单列显示 */\n  }\n}\n\u003C/style>\n",[675],{"type":21,"tag":249,"props":676,"children":677},{"__ignoreMap":7},[678],{"type":26,"value":673},{"type":21,"tag":22,"props":680,"children":682},{"id":681},"描述列表组件",[683],{"type":26,"value":681},{"type":21,"tag":28,"props":685,"children":686},{},[687],{"type":26,"value":688},"描述列表用于展示详情信息，适合订单详情、用户资料等场景。",{"type":21,"tag":241,"props":690,"children":693},{"className":691,"code":692,"language":246,"meta":7},[244],"\u003Ctemplate>\n  \u003Cdiv class=\"descriptions\" :class=\"`descriptions--${layout}`\">\n    \u003Cdiv \n      v-for=\"item in items\" \n      :key=\"item.key\"\n      class=\"descriptions__item\"\n      :style=\"{ gridColumn: `span ${item.span || 1}` }\"\n    >\n      \u003Cdt class=\"descriptions__label\">\n        {{ item.label }}\n        \u003CTooltip v-if=\"item.tooltip\" :content=\"item.tooltip\">\n          \u003CIcon name=\"info-circle\" class=\"label-icon\" />\n        \u003C/Tooltip>\n      \u003C/dt>\n      \u003Cdd class=\"descriptions__content\">\n        \u003Cslot :name=\"item.key\" :item=\"item\">\n          \u003Ctemplate v-if=\"item.type === 'status'\">\n            \u003CStatusTag :status=\"item.value\" />\n          \u003C/template>\n          \u003Ctemplate v-else-if=\"item.type === 'link'\">\n            \u003Ca :href=\"item.href\" target=\"_blank\">{{ item.value }}\u003C/a>\n          \u003C/template>\n          \u003Ctemplate v-else-if=\"item.type === 'copy'\">\n            {{ item.value }}\n            \u003CCopyButton :text=\"item.value\" />\n          \u003C/template>\n          \u003Ctemplate v-else>\n            {{ item.value || item.emptyText || '-' }}\n          \u003C/template>\n        \u003C/slot>\n      \u003C/dd>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cstyle scoped>\n.descriptions--horizontal {\n  display: grid;\n  grid-template-columns: repeat(var(--columns, 3), 1fr);\n  gap: var(--spacing-md) var(--spacing-lg);\n}\n\n.descriptions--vertical .descriptions__item {\n  display: flex;\n  flex-direction: column;\n}\n\n.descriptions__label {\n  color: var(--color-text-secondary);\n  font-size: var(--font-size-sm);\n  margin-bottom: var(--spacing-xs);\n}\n\n.descriptions__content {\n  color: var(--color-text-primary);\n  word-break: break-word;\n}\n\u003C/style>\n",[694],{"type":21,"tag":249,"props":695,"children":696},{"__ignoreMap":7},[697],{"type":26,"value":692},{"type":21,"tag":22,"props":699,"children":701},{"id":700},"统计数值组件",[702],{"type":26,"value":700},{"type":21,"tag":28,"props":704,"children":705},{},[706],{"type":26,"value":707},"统计数值组件用于突出展示核心指标，常见于数据大屏和仪表盘。",{"type":21,"tag":241,"props":709,"children":712},{"className":710,"code":711,"language":246,"meta":7},[244],"\u003Ctemplate>\n  \u003Cdiv class=\"statistic\" :class=\"{ 'statistic--with-trend': trend }\">\n    \u003Cdiv class=\"statistic__header\">\n      \u003Cspan class=\"statistic__title\">{{ title }}\u003C/span>\n      \u003CTooltip v-if=\"tooltip\" :content=\"tooltip\">\n        \u003CIcon name=\"question-circle\" class=\"statistic__help\" />\n      \u003C/Tooltip>\n    \u003C/div>\n    \n    \u003Cdiv class=\"statistic__body\">\n      \u003C!-- 数值显示：支持动画效果 -->\n      \u003Cspan class=\"statistic__value\">\n        \u003Cspan v-if=\"prefix\" class=\"statistic__prefix\">{{ prefix }}\u003C/span>\n        \u003CAnimatedNumber \n          :value=\"value\" \n          :precision=\"precision\"\n          :duration=\"animationDuration\"\n        />\n        \u003Cspan v-if=\"suffix\" class=\"statistic__suffix\">{{ suffix }}\u003C/span>\n      \u003C/span>\n      \n      \u003C!-- 趋势指示 -->\n      \u003Cdiv v-if=\"trend\" class=\"statistic__trend\" :class=\"`trend--${trendDirection}`\">\n        \u003CIcon :name=\"trendDirection === 'up' ? 'arrow-up' : 'arrow-down'\" />\n        \u003Cspan>{{ Math.abs(trend) }}%\u003C/span>\n      \u003C/div>\n    \u003C/div>\n    \n    \u003C!-- 对比说明 -->\n    \u003Cdiv v-if=\"comparison\" class=\"statistic__comparison\">\n      较{{ comparisonLabel }}{{ trendDirection === 'up' ? '增长' : '下降' }}\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst props = defineProps\u003C{\n  title: string\n  value: number\n  prefix?: string\n  suffix?: string\n  precision?: number\n  trend?: number\n  comparison?: string\n  tooltip?: string\n  animationDuration?: number\n}>()\n\nconst trendDirection = computed(() => {\n  if (!props.trend) return null\n  return props.trend > 0 ? 'up' : 'down'\n})\n\nconst comparisonLabel = computed(() => props.comparison || '上期')\n\u003C/script>\n",[713],{"type":21,"tag":249,"props":714,"children":715},{"__ignoreMap":7},[716],{"type":26,"value":711},{"type":21,"tag":22,"props":718,"children":720},{"id":719},"时间线组件",[721],{"type":26,"value":719},{"type":21,"tag":28,"props":723,"children":724},{},[725],{"type":26,"value":726},"时间线用于展示按时间排序的事件序列。",{"type":21,"tag":241,"props":728,"children":731},{"className":729,"code":730,"language":246,"meta":7},[244],"\u003Ctemplate>\n  \u003Cdiv class=\"timeline\" :class=\"[`timeline--${mode}`, { 'timeline--alternate': alternate }]\">\n    \u003Cdiv \n      v-for=\"(item, index) in items\" \n      :key=\"item.key || index\"\n      class=\"timeline__item\"\n      :class=\"{ 'timeline__item--last': index === items.length - 1 }\"\n    >\n      \u003C!-- 时间点标记 -->\n      \u003Cdiv class=\"timeline__dot\">\n        \u003Cslot name=\"dot\" :item=\"item\">\n          \u003Cdiv \n            class=\"dot-inner\" \n            :class=\"`dot--${item.status || 'default'}`\"\n            :style=\"{ backgroundColor: item.color }\"\n          >\n            \u003CIcon v-if=\"item.icon\" :name=\"item.icon\" />\n          \u003C/div>\n        \u003C/slot>\n      \u003C/div>\n      \n      \u003C!-- 连接线 -->\n      \u003Cdiv v-if=\"index \u003C items.length - 1\" class=\"timeline__line\" />\n      \n      \u003C!-- 时间线内容 -->\n      \u003Cdiv class=\"timeline__content\">\n        \u003Cdiv v-if=\"item.label\" class=\"timeline__label\">{{ item.label }}\u003C/div>\n        \u003Cdiv class=\"timeline__card\">\n          \u003Ch4 v-if=\"item.title\" class=\"timeline__title\">{{ item.title }}\u003C/h4>\n          \u003Cp v-if=\"item.description\" class=\"timeline__description\">\n            {{ item.description }}\n          \u003C/p>\n          \u003Cslot :name=\"`item-${index}`\" :item=\"item\" />\n        \u003C/div>\n      \u003C/div>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n",[732],{"type":21,"tag":249,"props":733,"children":734},{"__ignoreMap":7},[735],{"type":26,"value":730},{"type":21,"tag":22,"props":737,"children":739},{"id":738},"空状态与加载状态",[740],{"type":26,"value":738},{"type":21,"tag":28,"props":742,"children":743},{},[744],{"type":26,"value":745},"数据展示组件需要妥善处理空状态和加载状态。",{"type":21,"tag":230,"props":747,"children":749},{"id":748},"空状态设计",[750],{"type":26,"value":748},{"type":21,"tag":241,"props":752,"children":755},{"className":753,"code":754,"language":246,"meta":7},[244],"\u003Ctemplate>\n  \u003Cdiv class=\"empty-state\" :class=\"`empty-state--${size}`\">\n    \u003Cdiv class=\"empty-state__image\">\n      \u003Cslot name=\"image\">\n        \u003Cimg :src=\"image || defaultImage\" :alt=\"title\" />\n      \u003C/slot>\n    \u003C/div>\n    \u003Ch3 class=\"empty-state__title\">{{ title || '暂无数据' }}\u003C/h3>\n    \u003Cp v-if=\"description\" class=\"empty-state__description\">{{ description }}\u003C/p>\n    \u003Cdiv v-if=\"$slots.action\" class=\"empty-state__action\">\n      \u003Cslot name=\"action\" />\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n",[756],{"type":21,"tag":249,"props":757,"children":758},{"__ignoreMap":7},[759],{"type":26,"value":754},{"type":21,"tag":230,"props":761,"children":763},{"id":762},"骨架屏设计",[764],{"type":26,"value":762},{"type":21,"tag":241,"props":766,"children":769},{"className":767,"code":768,"language":246,"meta":7},[244],"\u003Ctemplate>\n  \u003Cdiv class=\"skeleton-table\">\n    \u003C!-- 表格骨架 -->\n    \u003Cdiv class=\"skeleton-row skeleton-header\">\n      \u003Cdiv v-for=\"n in columns\" :key=\"n\" class=\"skeleton-cell\" />\n    \u003C/div>\n    \u003Cdiv v-for=\"r in rows\" :key=\"r\" class=\"skeleton-row\">\n      \u003Cdiv \n        v-for=\"c in columns\" \n        :key=\"c\" \n        class=\"skeleton-cell\"\n        :style=\"{ width: getRandomWidth() }\"\n      />\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cstyle scoped>\n.skeleton-cell {\n  height: 16px;\n  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);\n  background-size: 200% 100%;\n  animation: skeleton-loading 1.5s infinite;\n  border-radius: 4px;\n}\n\n@keyframes skeleton-loading {\n  0% { background-position: 200% 0; }\n  100% { background-position: -200% 0; }\n}\n\u003C/style>\n",[770],{"type":21,"tag":249,"props":771,"children":772},{"__ignoreMap":7},[773],{"type":26,"value":768},{"type":21,"tag":22,"props":775,"children":777},{"id":776},"设计最佳实践",[778],{"type":26,"value":776},{"type":21,"tag":230,"props":780,"children":782},{"id":781},"_1-信息层次",[783],{"type":26,"value":784},"1. 信息层次",{"type":21,"tag":28,"props":786,"children":787},{},[788],{"type":26,"value":789},"遵循视觉层次原则，确保最重要的信息最突出：",{"type":21,"tag":503,"props":791,"children":792},{},[793,803,813],{"type":21,"tag":507,"props":794,"children":795},{},[796,801],{"type":21,"tag":497,"props":797,"children":798},{},[799],{"type":26,"value":800},"主要信息",{"type":26,"value":802},"：使用较大字号、深色文字",{"type":21,"tag":507,"props":804,"children":805},{},[806,811],{"type":21,"tag":497,"props":807,"children":808},{},[809],{"type":26,"value":810},"次要信息",{"type":26,"value":812},"：使用较小字号、灰色文字",{"type":21,"tag":507,"props":814,"children":815},{},[816,821],{"type":21,"tag":497,"props":817,"children":818},{},[819],{"type":26,"value":820},"辅助信息",{"type":26,"value":822},"：使用最小字号、浅灰色文字",{"type":21,"tag":230,"props":824,"children":826},{"id":825},"_2-间距一致性",[827],{"type":26,"value":828},"2. 间距一致性",{"type":21,"tag":28,"props":830,"children":831},{},[832],{"type":26,"value":833},"使用统一的间距系统：",{"type":21,"tag":241,"props":835,"children":840},{"className":836,"code":838,"language":839,"meta":7},[837],"language-css",":root {\n  --spacing-xs: 4px;\n  --spacing-sm: 8px;\n  --spacing-md: 16px;\n  --spacing-lg: 24px;\n  --spacing-xl: 32px;\n}\n","css",[841],{"type":21,"tag":249,"props":842,"children":843},{"__ignoreMap":7},[844],{"type":26,"value":838},{"type":21,"tag":230,"props":846,"children":848},{"id":847},"_3-响应式适配",[849],{"type":26,"value":850},"3. 响应式适配",{"type":21,"tag":44,"props":852,"children":853},{},[854,880],{"type":21,"tag":48,"props":855,"children":856},{},[857],{"type":21,"tag":52,"props":858,"children":859},{},[860,865,870,875],{"type":21,"tag":56,"props":861,"children":862},{},[863],{"type":26,"value":864},"断点",{"type":21,"tag":56,"props":866,"children":867},{},[868],{"type":26,"value":869},"表格策略",{"type":21,"tag":56,"props":871,"children":872},{},[873],{"type":26,"value":874},"卡片策略",{"type":21,"tag":56,"props":876,"children":877},{},[878],{"type":26,"value":879},"列表策略",{"type":21,"tag":77,"props":881,"children":882},{},[883,906,929],{"type":21,"tag":52,"props":884,"children":885},{},[886,891,896,901],{"type":21,"tag":84,"props":887,"children":888},{},[889],{"type":26,"value":890},"桌面端",{"type":21,"tag":84,"props":892,"children":893},{},[894],{"type":26,"value":895},"完整表格",{"type":21,"tag":84,"props":897,"children":898},{},[899],{"type":26,"value":900},"4列网格",{"type":21,"tag":84,"props":902,"children":903},{},[904],{"type":26,"value":905},"完整信息",{"type":21,"tag":52,"props":907,"children":908},{},[909,914,919,924],{"type":21,"tag":84,"props":910,"children":911},{},[912],{"type":26,"value":913},"平板端",{"type":21,"tag":84,"props":915,"children":916},{},[917],{"type":26,"value":918},"隐藏次要列",{"type":21,"tag":84,"props":920,"children":921},{},[922],{"type":26,"value":923},"2-3列网格",{"type":21,"tag":84,"props":925,"children":926},{},[927],{"type":26,"value":928},"压缩次要信息",{"type":21,"tag":52,"props":930,"children":931},{},[932,937,942,947],{"type":21,"tag":84,"props":933,"children":934},{},[935],{"type":26,"value":936},"移动端",{"type":21,"tag":84,"props":938,"children":939},{},[940],{"type":26,"value":941},"卡片式列表",{"type":21,"tag":84,"props":943,"children":944},{},[945],{"type":26,"value":946},"单列",{"type":21,"tag":84,"props":948,"children":949},{},[950],{"type":26,"value":951},"仅显示关键信息",{"type":21,"tag":230,"props":953,"children":955},{"id":954},"_4-交互反馈",[956],{"type":26,"value":957},"4. 交互反馈",{"type":21,"tag":503,"props":959,"children":960},{},[961,966,971,976],{"type":21,"tag":507,"props":962,"children":963},{},[964],{"type":26,"value":965},"悬停时提供视觉反馈（背景色变化）",{"type":21,"tag":507,"props":967,"children":968},{},[969],{"type":26,"value":970},"可点击元素显示光标变化",{"type":21,"tag":507,"props":972,"children":973},{},[974],{"type":26,"value":975},"操作完成后提供成功/失败提示",{"type":21,"tag":507,"props":977,"children":978},{},[979],{"type":26,"value":980},"加载过程中显示进度指示",{"type":21,"tag":22,"props":982,"children":984},{"id":983},"总结",[985],{"type":26,"value":983},{"type":21,"tag":28,"props":987,"children":988},{},[989],{"type":26,"value":990},"优秀的数据展示组件设计需要关注：",{"type":21,"tag":992,"props":993,"children":994},"ol",{},[995,1005,1015,1025,1035],{"type":21,"tag":507,"props":996,"children":997},{},[998,1003],{"type":21,"tag":497,"props":999,"children":1000},{},[1001],{"type":26,"value":1002},"选择合适的组件类型",{"type":26,"value":1004},"：根据数据特点和用户场景选择",{"type":21,"tag":507,"props":1006,"children":1007},{},[1008,1013],{"type":21,"tag":497,"props":1009,"children":1010},{},[1011],{"type":26,"value":1012},"信息结构清晰",{"type":26,"value":1014},"：建立明确的视觉层次",{"type":21,"tag":507,"props":1016,"children":1017},{},[1018,1023],{"type":21,"tag":497,"props":1019,"children":1020},{},[1021],{"type":26,"value":1022},"交互设计直观",{"type":26,"value":1024},"：让用户操作符合直觉",{"type":21,"tag":507,"props":1026,"children":1027},{},[1028,1033],{"type":21,"tag":497,"props":1029,"children":1030},{},[1031],{"type":26,"value":1032},"状态处理完善",{"type":26,"value":1034},"：覆盖加载、空状态、错误状态",{"type":21,"tag":507,"props":1036,"children":1037},{},[1038,1043],{"type":21,"tag":497,"props":1039,"children":1040},{},[1041],{"type":26,"value":1042},"响应式适配",{"type":26,"value":1044},"：确保各端体验一致",{"type":21,"tag":28,"props":1046,"children":1047},{},[1048],{"type":26,"value":1049},"通过系统化的设计思考，我们可以构建出既美观又实用的数据展示界面。",{"title":7,"searchDepth":1051,"depth":1051,"links":1052},3,[1053,1055,1056,1061,1065,1069,1070,1071,1072,1076,1082],{"id":8,"depth":1054,"text":8},2,{"id":35,"depth":1054,"text":35},{"id":221,"depth":1054,"text":221,"children":1057},[1058,1059,1060],{"id":232,"depth":1051,"text":232},{"id":255,"depth":1051,"text":255},{"id":485,"depth":1051,"text":485},{"id":590,"depth":1054,"text":590,"children":1062},[1063,1064],{"id":600,"depth":1051,"text":600},{"id":619,"depth":1051,"text":619},{"id":638,"depth":1054,"text":638,"children":1066},[1067,1068],{"id":648,"depth":1051,"text":648},{"id":662,"depth":1051,"text":662},{"id":681,"depth":1054,"text":681},{"id":700,"depth":1054,"text":700},{"id":719,"depth":1054,"text":719},{"id":738,"depth":1054,"text":738,"children":1073},[1074,1075],{"id":748,"depth":1051,"text":748},{"id":762,"depth":1051,"text":762},{"id":776,"depth":1054,"text":776,"children":1077},[1078,1079,1080,1081],{"id":781,"depth":1051,"text":784},{"id":825,"depth":1051,"text":828},{"id":847,"depth":1051,"text":850},{"id":954,"depth":1051,"text":957},{"id":983,"depth":1054,"text":983},"markdown","content:topics:design:data-display-component-guide.md","content","topics/design/data-display-component-guide.md","topics/design/data-display-component-guide","md",[1090,1445,1747],{"_path":1091,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1092,"description":1093,"keywords":1094,"image":1100,"author":1101,"date":1102,"readingTime":1103,"topic":5,"body":1104,"_type":1083,"_id":1442,"_source":1085,"_file":1443,"_stem":1444,"_extension":1088},"/topics/design/button-component-design","按钮组件设计详解","学习按钮样式、交互状态、无障碍性和最佳实践",[1095,1096,1097,1098,1099],"按钮设计","Button Component","交互状态","UI 组件","用户体验","/images/topics/button-design.jpg","HTMLPAGE 团队","2025-12-08",18,{"type":18,"children":1105,"toc":1424},[1106,1110,1115,1120,1126,1135,1141,1150,1156,1165,1169,1175,1186,1192,1201,1207,1216,1221,1230,1235,1246,1251,1260,1265,1277,1311,1322,1365,1370],{"type":21,"tag":22,"props":1107,"children":1108},{"id":1092},[1109],{"type":26,"value":1092},{"type":21,"tag":28,"props":1111,"children":1112},{},[1113],{"type":26,"value":1114},"按钮是 UI 中最重要的交互元素。优秀的按钮设计能够指导用户行为。",{"type":21,"tag":22,"props":1116,"children":1118},{"id":1117},"按钮类型",[1119],{"type":26,"value":1117},{"type":21,"tag":230,"props":1121,"children":1123},{"id":1122},"primary-button主按钮",[1124],{"type":26,"value":1125},"Primary Button（主按钮）",{"type":21,"tag":241,"props":1127,"children":1130},{"className":1128,"code":1129,"language":839,"meta":7},[837],".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",[1131],{"type":21,"tag":249,"props":1132,"children":1133},{"__ignoreMap":7},[1134],{"type":26,"value":1129},{"type":21,"tag":230,"props":1136,"children":1138},{"id":1137},"secondary-button次按钮",[1139],{"type":26,"value":1140},"Secondary Button（次按钮）",{"type":21,"tag":241,"props":1142,"children":1145},{"className":1143,"code":1144,"language":839,"meta":7},[837],".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",[1146],{"type":21,"tag":249,"props":1147,"children":1148},{"__ignoreMap":7},[1149],{"type":26,"value":1144},{"type":21,"tag":230,"props":1151,"children":1153},{"id":1152},"danger-button危险按钮",[1154],{"type":26,"value":1155},"Danger Button（危险按钮）",{"type":21,"tag":241,"props":1157,"children":1160},{"className":1158,"code":1159,"language":839,"meta":7},[837],".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",[1161],{"type":21,"tag":249,"props":1162,"children":1163},{"__ignoreMap":7},[1164],{"type":26,"value":1159},{"type":21,"tag":22,"props":1166,"children":1167},{"id":1097},[1168],{"type":26,"value":1097},{"type":21,"tag":230,"props":1170,"children":1172},{"id":1171},"loading-状态",[1173],{"type":26,"value":1174},"Loading 状态",{"type":21,"tag":241,"props":1176,"children":1181},{"className":1177,"code":1179,"language":1180,"meta":7},[1178],"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",[1182],{"type":21,"tag":249,"props":1183,"children":1184},{"__ignoreMap":7},[1185],{"type":26,"value":1179},{"type":21,"tag":230,"props":1187,"children":1189},{"id":1188},"disabled-状态",[1190],{"type":26,"value":1191},"Disabled 状态",{"type":21,"tag":241,"props":1193,"children":1196},{"className":1194,"code":1195,"language":839,"meta":7},[837],".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",[1197],{"type":21,"tag":249,"props":1198,"children":1199},{"__ignoreMap":7},[1200],{"type":26,"value":1195},{"type":21,"tag":230,"props":1202,"children":1204},{"id":1203},"focus-状态",[1205],{"type":26,"value":1206},"Focus 状态",{"type":21,"tag":241,"props":1208,"children":1211},{"className":1209,"code":1210,"language":839,"meta":7},[837],".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",[1212],{"type":21,"tag":249,"props":1213,"children":1214},{"__ignoreMap":7},[1215],{"type":26,"value":1210},{"type":21,"tag":22,"props":1217,"children":1219},{"id":1218},"按钮大小",[1220],{"type":26,"value":1218},{"type":21,"tag":241,"props":1222,"children":1225},{"className":1223,"code":1224,"language":839,"meta":7},[837],"/* 小按钮 */\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",[1226],{"type":21,"tag":249,"props":1227,"children":1228},{"__ignoreMap":7},[1229],{"type":26,"value":1224},{"type":21,"tag":22,"props":1231,"children":1233},{"id":1232},"无障碍性",[1234],{"type":26,"value":1232},{"type":21,"tag":241,"props":1236,"children":1241},{"className":1237,"code":1239,"language":1240,"meta":7},[1238],"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",[1242],{"type":21,"tag":249,"props":1243,"children":1244},{"__ignoreMap":7},[1245],{"type":26,"value":1239},{"type":21,"tag":22,"props":1247,"children":1249},{"id":1248},"完整组件示例",[1250],{"type":26,"value":1248},{"type":21,"tag":241,"props":1252,"children":1255},{"className":1253,"code":1254,"language":1180,"meta":7},[1178],"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",[1256],{"type":21,"tag":249,"props":1257,"children":1258},{"__ignoreMap":7},[1259],{"type":26,"value":1254},{"type":21,"tag":22,"props":1261,"children":1263},{"id":1262},"最佳实践",[1264],{"type":26,"value":1262},{"type":21,"tag":28,"props":1266,"children":1267},{},[1268,1270,1275],{"type":26,"value":1269},"✅ ",{"type":21,"tag":497,"props":1271,"children":1272},{},[1273],{"type":26,"value":1274},"应该做的事",{"type":26,"value":1276},":",{"type":21,"tag":503,"props":1278,"children":1279},{},[1280,1285,1290,1301,1306],{"type":21,"tag":507,"props":1281,"children":1282},{},[1283],{"type":26,"value":1284},"最小触摸目标 44x44px",{"type":21,"tag":507,"props":1286,"children":1287},{},[1288],{"type":26,"value":1289},"清晰的视觉反馈",{"type":21,"tag":507,"props":1291,"children":1292},{},[1293,1295],{"type":26,"value":1294},"使用语义 HTML ",{"type":21,"tag":249,"props":1296,"children":1298},{"className":1297},[],[1299],{"type":26,"value":1300},"\u003Cbutton>",{"type":21,"tag":507,"props":1302,"children":1303},{},[1304],{"type":26,"value":1305},"提供加载状态反馈",{"type":21,"tag":507,"props":1307,"children":1308},{},[1309],{"type":26,"value":1310},"支持键盘导航",{"type":21,"tag":28,"props":1312,"children":1313},{},[1314,1316,1321],{"type":26,"value":1315},"❌ ",{"type":21,"tag":497,"props":1317,"children":1318},{},[1319],{"type":26,"value":1320},"不应该做的事",{"type":26,"value":1276},{"type":21,"tag":503,"props":1323,"children":1324},{},[1325,1338,1343,1348,1353],{"type":21,"tag":507,"props":1326,"children":1327},{},[1328,1330,1336],{"type":26,"value":1329},"使用 ",{"type":21,"tag":249,"props":1331,"children":1333},{"className":1332},[],[1334],{"type":26,"value":1335},"\u003Cdiv>",{"type":26,"value":1337}," 模拟按钮",{"type":21,"tag":507,"props":1339,"children":1340},{},[1341],{"type":26,"value":1342},"隐藏焦点指示器",{"type":21,"tag":507,"props":1344,"children":1345},{},[1346],{"type":26,"value":1347},"过多的按钮样式",{"type":21,"tag":507,"props":1349,"children":1350},{},[1351],{"type":26,"value":1352},"忽视禁用状态",{"type":21,"tag":507,"props":1354,"children":1355},{},[1356,1357,1363],{"type":26,"value":1329},{"type":21,"tag":249,"props":1358,"children":1360},{"className":1359},[],[1361],{"type":26,"value":1362},"\u003Ca>",{"type":26,"value":1364}," 代替按钮",{"type":21,"tag":22,"props":1366,"children":1368},{"id":1367},"测试清单",[1369],{"type":26,"value":1367},{"type":21,"tag":503,"props":1371,"children":1374},{"className":1372},[1373],"contains-task-list",[1375,1388,1397,1406,1415],{"type":21,"tag":507,"props":1376,"children":1379},{"className":1377},[1378],"task-list-item",[1380,1386],{"type":21,"tag":1381,"props":1382,"children":1385},"input",{"disabled":1383,"type":1384},true,"checkbox",[],{"type":26,"value":1387}," 在各种浏览器中测试",{"type":21,"tag":507,"props":1389,"children":1391},{"className":1390},[1378],[1392,1395],{"type":21,"tag":1381,"props":1393,"children":1394},{"disabled":1383,"type":1384},[],{"type":26,"value":1396}," 验证键盘导航",{"type":21,"tag":507,"props":1398,"children":1400},{"className":1399},[1378],[1401,1404],{"type":21,"tag":1381,"props":1402,"children":1403},{"disabled":1383,"type":1384},[],{"type":26,"value":1405}," 检查色彩对比度",{"type":21,"tag":507,"props":1407,"children":1409},{"className":1408},[1378],[1410,1413],{"type":21,"tag":1381,"props":1411,"children":1412},{"disabled":1383,"type":1384},[],{"type":26,"value":1414}," 测试触摸设备",{"type":21,"tag":507,"props":1416,"children":1418},{"className":1417},[1378],[1419,1422],{"type":21,"tag":1381,"props":1420,"children":1421},{"disabled":1383,"type":1384},[],{"type":26,"value":1423}," 屏幕阅读器兼容性",{"title":7,"searchDepth":1051,"depth":1051,"links":1425},[1426,1427,1432,1437,1438,1439,1440,1441],{"id":1092,"depth":1054,"text":1092},{"id":1117,"depth":1054,"text":1117,"children":1428},[1429,1430,1431],{"id":1122,"depth":1051,"text":1125},{"id":1137,"depth":1051,"text":1140},{"id":1152,"depth":1051,"text":1155},{"id":1097,"depth":1054,"text":1097,"children":1433},[1434,1435,1436],{"id":1171,"depth":1051,"text":1174},{"id":1188,"depth":1051,"text":1191},{"id":1203,"depth":1051,"text":1206},{"id":1218,"depth":1054,"text":1218},{"id":1232,"depth":1054,"text":1232},{"id":1248,"depth":1054,"text":1248},{"id":1262,"depth":1054,"text":1262},{"id":1367,"depth":1054,"text":1367},"content:topics:design:button-component-design.md","topics/design/button-component-design.md","topics/design/button-component-design",{"_path":1446,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1447,"description":1448,"keywords":1449,"image":1454,"author":1101,"date":1102,"readingTime":1455,"topic":5,"body":1456,"_type":1083,"_id":1744,"_source":1085,"_file":1745,"_stem":1746,"_extension":1088},"/topics/design/dark-mode-design","暗黑模式设计完整方案","学习暗黑模式实现、色彩方案、对比度管理和最佳实践",[1450,1451,1452,1453,1099],"暗黑模式","Dark Mode","色彩系统","CSS 变量","/images/topics/dark-mode-design.jpg",20,{"type":18,"children":1457,"toc":1727},[1458,1462,1467,1472,1478,1487,1493,1502,1507,1513,1522,1528,1539,1545,1554,1559,1568,1573,1582,1587,1596,1600,1609,1637,1646,1674,1678],{"type":21,"tag":22,"props":1459,"children":1460},{"id":1447},[1461],{"type":26,"value":1447},{"type":21,"tag":28,"props":1463,"children":1464},{},[1465],{"type":26,"value":1466},"暗黑模式已成为现代应用的标准功能。它能够减少眼睛疲劳、节省电池、改善用户体验。",{"type":21,"tag":22,"props":1468,"children":1470},{"id":1469},"核心色彩系统",[1471],{"type":26,"value":1469},{"type":21,"tag":230,"props":1473,"children":1475},{"id":1474},"light-mode-配色",[1476],{"type":26,"value":1477},"Light Mode 配色",{"type":21,"tag":241,"props":1479,"children":1482},{"className":1480,"code":1481,"language":839,"meta":7},[837],":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",[1483],{"type":21,"tag":249,"props":1484,"children":1485},{"__ignoreMap":7},[1486],{"type":26,"value":1481},{"type":21,"tag":230,"props":1488,"children":1490},{"id":1489},"dark-mode-配色",[1491],{"type":26,"value":1492},"Dark Mode 配色",{"type":21,"tag":241,"props":1494,"children":1497},{"className":1495,"code":1496,"language":839,"meta":7},[837],"@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",[1498],{"type":21,"tag":249,"props":1499,"children":1500},{"__ignoreMap":7},[1501],{"type":26,"value":1496},{"type":21,"tag":22,"props":1503,"children":1505},{"id":1504},"实现方案",[1506],{"type":26,"value":1504},{"type":21,"tag":230,"props":1508,"children":1510},{"id":1509},"方案-1prefers-color-scheme",[1511],{"type":26,"value":1512},"方案 1：prefers-color-scheme",{"type":21,"tag":241,"props":1514,"children":1517},{"className":1515,"code":1516,"language":839,"meta":7},[837],"/* 自动跟随系统设置 */\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",[1518],{"type":21,"tag":249,"props":1519,"children":1520},{"__ignoreMap":7},[1521],{"type":26,"value":1516},{"type":21,"tag":230,"props":1523,"children":1525},{"id":1524},"方案-2javascript-切换",[1526],{"type":26,"value":1527},"方案 2：JavaScript 切换",{"type":21,"tag":241,"props":1529,"children":1534},{"className":1530,"code":1532,"language":1533,"meta":7},[1531],"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",[1535],{"type":21,"tag":249,"props":1536,"children":1537},{"__ignoreMap":7},[1538],{"type":26,"value":1532},{"type":21,"tag":230,"props":1540,"children":1542},{"id":1541},"方案-3css-variables-javascript",[1543],{"type":26,"value":1544},"方案 3：CSS Variables + JavaScript",{"type":21,"tag":241,"props":1546,"children":1549},{"className":1547,"code":1548,"language":1533,"meta":7},[1531],"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",[1550],{"type":21,"tag":249,"props":1551,"children":1552},{"__ignoreMap":7},[1553],{"type":26,"value":1548},{"type":21,"tag":22,"props":1555,"children":1557},{"id":1556},"对比度管理",[1558],{"type":26,"value":1556},{"type":21,"tag":241,"props":1560,"children":1563},{"className":1561,"code":1562,"language":839,"meta":7},[837],"/* 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",[1564],{"type":21,"tag":249,"props":1565,"children":1566},{"__ignoreMap":7},[1567],{"type":26,"value":1562},{"type":21,"tag":22,"props":1569,"children":1571},{"id":1570},"图片和图表处理",[1572],{"type":26,"value":1570},{"type":21,"tag":241,"props":1574,"children":1577},{"className":1575,"code":1576,"language":1240,"meta":7},[1238],"\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",[1578],{"type":21,"tag":249,"props":1579,"children":1580},{"__ignoreMap":7},[1581],{"type":26,"value":1576},{"type":21,"tag":22,"props":1583,"children":1585},{"id":1584},"完整示例",[1586],{"type":26,"value":1584},{"type":21,"tag":241,"props":1588,"children":1591},{"className":1589,"code":1590,"language":1180,"meta":7},[1178],"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",[1592],{"type":21,"tag":249,"props":1593,"children":1594},{"__ignoreMap":7},[1595],{"type":26,"value":1590},{"type":21,"tag":22,"props":1597,"children":1598},{"id":1262},[1599],{"type":26,"value":1262},{"type":21,"tag":28,"props":1601,"children":1602},{},[1603,1604,1608],{"type":26,"value":1269},{"type":21,"tag":497,"props":1605,"children":1606},{},[1607],{"type":26,"value":1274},{"type":26,"value":1276},{"type":21,"tag":503,"props":1610,"children":1611},{},[1612,1617,1622,1627,1632],{"type":21,"tag":507,"props":1613,"children":1614},{},[1615],{"type":26,"value":1616},"支持系统偏好",{"type":21,"tag":507,"props":1618,"children":1619},{},[1620],{"type":26,"value":1621},"提供手动切换选项",{"type":21,"tag":507,"props":1623,"children":1624},{},[1625],{"type":26,"value":1626},"确保足够的对比度",{"type":21,"tag":507,"props":1628,"children":1629},{},[1630],{"type":26,"value":1631},"优化图片和图表",{"type":21,"tag":507,"props":1633,"children":1634},{},[1635],{"type":26,"value":1636},"防止加载闪烁",{"type":21,"tag":28,"props":1638,"children":1639},{},[1640,1641,1645],{"type":26,"value":1315},{"type":21,"tag":497,"props":1642,"children":1643},{},[1644],{"type":26,"value":1320},{"type":26,"value":1276},{"type":21,"tag":503,"props":1647,"children":1648},{},[1649,1654,1659,1664,1669],{"type":21,"tag":507,"props":1650,"children":1651},{},[1652],{"type":26,"value":1653},"强制单一模式",{"type":21,"tag":507,"props":1655,"children":1656},{},[1657],{"type":26,"value":1658},"忽视性能影响",{"type":21,"tag":507,"props":1660,"children":1661},{},[1662],{"type":26,"value":1663},"使用相同的颜色",{"type":21,"tag":507,"props":1665,"children":1666},{},[1667],{"type":26,"value":1668},"忘记保存用户偏好",{"type":21,"tag":507,"props":1670,"children":1671},{},[1672],{"type":26,"value":1673},"过度使用深色背景",{"type":21,"tag":22,"props":1675,"children":1676},{"id":1367},[1677],{"type":26,"value":1367},{"type":21,"tag":503,"props":1679,"children":1681},{"className":1680},[1373],[1682,1691,1700,1709,1718],{"type":21,"tag":507,"props":1683,"children":1685},{"className":1684},[1378],[1686,1689],{"type":21,"tag":1381,"props":1687,"children":1688},{"disabled":1383,"type":1384},[],{"type":26,"value":1690}," 在浅色和深色模式下测试所有页面",{"type":21,"tag":507,"props":1692,"children":1694},{"className":1693},[1378],[1695,1698],{"type":21,"tag":1381,"props":1696,"children":1697},{"disabled":1383,"type":1384},[],{"type":26,"value":1699}," 检查颜色对比度符合 WCAG 标准",{"type":21,"tag":507,"props":1701,"children":1703},{"className":1702},[1378],[1704,1707],{"type":21,"tag":1381,"props":1705,"children":1706},{"disabled":1383,"type":1384},[],{"type":26,"value":1708}," 验证图片和图表在两种模式下清晰",{"type":21,"tag":507,"props":1710,"children":1712},{"className":1711},[1378],[1713,1716],{"type":21,"tag":1381,"props":1714,"children":1715},{"disabled":1383,"type":1384},[],{"type":26,"value":1717}," 测试主题切换的平滑性",{"type":21,"tag":507,"props":1719,"children":1721},{"className":1720},[1378],[1722,1725],{"type":21,"tag":1381,"props":1723,"children":1724},{"disabled":1383,"type":1384},[],{"type":26,"value":1726}," 检查用户偏好是否被保存",{"title":7,"searchDepth":1051,"depth":1051,"links":1728},[1729,1730,1734,1739,1740,1741,1742,1743],{"id":1447,"depth":1054,"text":1447},{"id":1469,"depth":1054,"text":1469,"children":1731},[1732,1733],{"id":1474,"depth":1051,"text":1477},{"id":1489,"depth":1051,"text":1492},{"id":1504,"depth":1054,"text":1504,"children":1735},[1736,1737,1738],{"id":1509,"depth":1051,"text":1512},{"id":1524,"depth":1051,"text":1527},{"id":1541,"depth":1051,"text":1544},{"id":1556,"depth":1054,"text":1556},{"id":1570,"depth":1054,"text":1570},{"id":1584,"depth":1054,"text":1584},{"id":1262,"depth":1054,"text":1262},{"id":1367,"depth":1054,"text":1367},"content:topics:design:dark-mode-design.md","topics/design/dark-mode-design.md","topics/design/dark-mode-design",{"_path":1748,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1749,"description":1750,"keywords":1751,"image":1756,"author":1757,"date":1102,"readingTime":1455,"topic":5,"body":1758,"_type":1083,"_id":2023,"_source":1085,"_file":2024,"_stem":2025,"_extension":1088},"/topics/design/form-controls-design","表单控件设计规范","学习输入框、选择框、复选框等表单控件的设计和实现",[1752,1753,1754,1755,1099],"表单设计","Form Controls","输入框","验证反馈","/images/topics/form-controls-design.jpg","AI Content Team",{"type":18,"children":1759,"toc":2009},[1760,1764,1769,1774,1779,1788,1793,1802,1806,1815,1820,1829,1834,1843,1848,1857,1862,1871,1875,1884,1910,1919,1947,1951],{"type":21,"tag":22,"props":1761,"children":1762},{"id":1749},[1763],{"type":26,"value":1749},{"type":21,"tag":28,"props":1765,"children":1766},{},[1767],{"type":26,"value":1768},"优秀的表单设计能够提高用户完成率和满意度。",{"type":21,"tag":22,"props":1770,"children":1772},{"id":1771},"输入框设计",[1773],{"type":26,"value":1771},{"type":21,"tag":230,"props":1775,"children":1777},{"id":1776},"基础文本输入",[1778],{"type":26,"value":1776},{"type":21,"tag":241,"props":1780,"children":1783},{"className":1781,"code":1782,"language":839,"meta":7},[837],".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",[1784],{"type":21,"tag":249,"props":1785,"children":1786},{"__ignoreMap":7},[1787],{"type":26,"value":1782},{"type":21,"tag":230,"props":1789,"children":1791},{"id":1790},"标签和提示",[1792],{"type":26,"value":1790},{"type":21,"tag":241,"props":1794,"children":1797},{"className":1795,"code":1796,"language":1240,"meta":7},[1238],"\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",[1798],{"type":21,"tag":249,"props":1799,"children":1800},{"__ignoreMap":7},[1801],{"type":26,"value":1796},{"type":21,"tag":22,"props":1803,"children":1804},{"id":1755},[1805],{"type":26,"value":1755},{"type":21,"tag":241,"props":1807,"children":1810},{"className":1808,"code":1809,"language":1180,"meta":7},[1178],"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",[1811],{"type":21,"tag":249,"props":1812,"children":1813},{"__ignoreMap":7},[1814],{"type":26,"value":1809},{"type":21,"tag":22,"props":1816,"children":1818},{"id":1817},"选择框设计",[1819],{"type":26,"value":1817},{"type":21,"tag":241,"props":1821,"children":1824},{"className":1822,"code":1823,"language":839,"meta":7},[837],".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",[1825],{"type":21,"tag":249,"props":1826,"children":1827},{"__ignoreMap":7},[1828],{"type":26,"value":1823},{"type":21,"tag":22,"props":1830,"children":1832},{"id":1831},"复选框和单选按钮",[1833],{"type":26,"value":1831},{"type":21,"tag":241,"props":1835,"children":1838},{"className":1836,"code":1837,"language":839,"meta":7},[837],".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",[1839],{"type":21,"tag":249,"props":1840,"children":1841},{"__ignoreMap":7},[1842],{"type":26,"value":1837},{"type":21,"tag":22,"props":1844,"children":1846},{"id":1845},"文本区域",[1847],{"type":26,"value":1845},{"type":21,"tag":241,"props":1849,"children":1852},{"className":1850,"code":1851,"language":839,"meta":7},[837],".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",[1853],{"type":21,"tag":249,"props":1854,"children":1855},{"__ignoreMap":7},[1856],{"type":26,"value":1851},{"type":21,"tag":22,"props":1858,"children":1860},{"id":1859},"完整表单示例",[1861],{"type":26,"value":1859},{"type":21,"tag":241,"props":1863,"children":1866},{"className":1864,"code":1865,"language":1180,"meta":7},[1178],"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",[1867],{"type":21,"tag":249,"props":1868,"children":1869},{"__ignoreMap":7},[1870],{"type":26,"value":1865},{"type":21,"tag":22,"props":1872,"children":1873},{"id":1262},[1874],{"type":26,"value":1262},{"type":21,"tag":28,"props":1876,"children":1877},{},[1878,1879,1883],{"type":26,"value":1269},{"type":21,"tag":497,"props":1880,"children":1881},{},[1882],{"type":26,"value":1274},{"type":26,"value":1276},{"type":21,"tag":503,"props":1885,"children":1886},{},[1887,1892,1897,1902,1906],{"type":21,"tag":507,"props":1888,"children":1889},{},[1890],{"type":26,"value":1891},"使用正确的输入类型",{"type":21,"tag":507,"props":1893,"children":1894},{},[1895],{"type":26,"value":1896},"提供实时验证反馈",{"type":21,"tag":507,"props":1898,"children":1899},{},[1900],{"type":26,"value":1901},"清晰的标签和提示",{"type":21,"tag":507,"props":1903,"children":1904},{},[1905],{"type":26,"value":1284},{"type":21,"tag":507,"props":1907,"children":1908},{},[1909],{"type":26,"value":1310},{"type":21,"tag":28,"props":1911,"children":1912},{},[1913,1914,1918],{"type":26,"value":1315},{"type":21,"tag":497,"props":1915,"children":1916},{},[1917],{"type":26,"value":1320},{"type":26,"value":1276},{"type":21,"tag":503,"props":1920,"children":1921},{},[1922,1927,1932,1937,1942],{"type":21,"tag":507,"props":1923,"children":1924},{},[1925],{"type":26,"value":1926},"隐藏标签",{"type":21,"tag":507,"props":1928,"children":1929},{},[1930],{"type":26,"value":1931},"过度使用占位符",{"type":21,"tag":507,"props":1933,"children":1934},{},[1935],{"type":26,"value":1936},"验证后立即提交",{"type":21,"tag":507,"props":1938,"children":1939},{},[1940],{"type":26,"value":1941},"忽视无障碍性",{"type":21,"tag":507,"props":1943,"children":1944},{},[1945],{"type":26,"value":1946},"复杂的验证规则",{"type":21,"tag":22,"props":1948,"children":1949},{"id":1367},[1950],{"type":26,"value":1367},{"type":21,"tag":503,"props":1952,"children":1954},{"className":1953},[1373],[1955,1964,1973,1982,1991,2000],{"type":21,"tag":507,"props":1956,"children":1958},{"className":1957},[1378],[1959,1962],{"type":21,"tag":1381,"props":1960,"children":1961},{"disabled":1383,"type":1384},[],{"type":26,"value":1963}," 所有控件都可用键盘导航",{"type":21,"tag":507,"props":1965,"children":1967},{"className":1966},[1378],[1968,1971],{"type":21,"tag":1381,"props":1969,"children":1970},{"disabled":1383,"type":1384},[],{"type":26,"value":1972}," 标签与输入框关联",{"type":21,"tag":507,"props":1974,"children":1976},{"className":1975},[1378],[1977,1980],{"type":21,"tag":1381,"props":1978,"children":1979},{"disabled":1383,"type":1384},[],{"type":26,"value":1981}," 验证消息清晰",{"type":21,"tag":507,"props":1983,"children":1985},{"className":1984},[1378],[1986,1989],{"type":21,"tag":1381,"props":1987,"children":1988},{"disabled":1383,"type":1384},[],{"type":26,"value":1990}," 色彩对比度足够",{"type":21,"tag":507,"props":1992,"children":1994},{"className":1993},[1378],[1995,1998],{"type":21,"tag":1381,"props":1996,"children":1997},{"disabled":1383,"type":1384},[],{"type":26,"value":1999}," 屏幕阅读器兼容",{"type":21,"tag":507,"props":2001,"children":2003},{"className":2002},[1378],[2004,2007],{"type":21,"tag":1381,"props":2005,"children":2006},{"disabled":1383,"type":1384},[],{"type":26,"value":2008}," 移动设备测试",{"title":7,"searchDepth":1051,"depth":1051,"links":2010},[2011,2012,2016,2017,2018,2019,2020,2021,2022],{"id":1749,"depth":1054,"text":1749},{"id":1771,"depth":1054,"text":1771,"children":2013},[2014,2015],{"id":1776,"depth":1051,"text":1776},{"id":1790,"depth":1051,"text":1790},{"id":1755,"depth":1054,"text":1755},{"id":1817,"depth":1054,"text":1817},{"id":1831,"depth":1054,"text":1831},{"id":1845,"depth":1054,"text":1845},{"id":1859,"depth":1054,"text":1859},{"id":1262,"depth":1054,"text":1262},{"id":1367,"depth":1054,"text":1367},"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,"image":11,"head":2027,"body":2030,"_type":1083,"_id":1084,"_source":1085,"_file":1086,"_stem":1087,"_extension":1088},{"meta":2028},[2029],{"name":15,"content":16},{"type":18,"children":2031,"toc":2874},[2032,2036,2040,2044,2048,2190,2194,2198,2202,2206,2214,2218,2222,2402,2410,2414,2418,2425,2440,2447,2462,2469,2488,2496,2500,2504,2508,2512,2520,2524,2528,2536,2540,2544,2548,2556,2560,2564,2572,2576,2580,2588,2592,2596,2604,2608,2612,2620,2624,2628,2632,2640,2644,2652,2656,2660,2664,2691,2695,2699,2707,2711,2796,2800,2819,2823,2827,2870],{"type":21,"tag":22,"props":2033,"children":2034},{"id":8},[2035],{"type":26,"value":8},{"type":21,"tag":28,"props":2037,"children":2038},{},[2039],{"type":26,"value":32},{"type":21,"tag":22,"props":2041,"children":2042},{"id":35},[2043],{"type":26,"value":35},{"type":21,"tag":28,"props":2045,"children":2046},{},[2047],{"type":26,"value":42},{"type":21,"tag":44,"props":2049,"children":2050},{},[2051,2073],{"type":21,"tag":48,"props":2052,"children":2053},{},[2054],{"type":21,"tag":52,"props":2055,"children":2056},{},[2057,2061,2065,2069],{"type":21,"tag":56,"props":2058,"children":2059},{},[2060],{"type":26,"value":60},{"type":21,"tag":56,"props":2062,"children":2063},{},[2064],{"type":26,"value":65},{"type":21,"tag":56,"props":2066,"children":2067},{},[2068],{"type":26,"value":70},{"type":21,"tag":56,"props":2070,"children":2071},{},[2072],{"type":26,"value":75},{"type":21,"tag":77,"props":2074,"children":2075},{},[2076,2095,2114,2133,2152,2171],{"type":21,"tag":52,"props":2077,"children":2078},{},[2079,2083,2087,2091],{"type":21,"tag":84,"props":2080,"children":2081},{},[2082],{"type":26,"value":88},{"type":21,"tag":84,"props":2084,"children":2085},{},[2086],{"type":26,"value":93},{"type":21,"tag":84,"props":2088,"children":2089},{},[2090],{"type":26,"value":98},{"type":21,"tag":84,"props":2092,"children":2093},{},[2094],{"type":26,"value":103},{"type":21,"tag":52,"props":2096,"children":2097},{},[2098,2102,2106,2110],{"type":21,"tag":84,"props":2099,"children":2100},{},[2101],{"type":26,"value":111},{"type":21,"tag":84,"props":2103,"children":2104},{},[2105],{"type":26,"value":116},{"type":21,"tag":84,"props":2107,"children":2108},{},[2109],{"type":26,"value":121},{"type":21,"tag":84,"props":2111,"children":2112},{},[2113],{"type":26,"value":126},{"type":21,"tag":52,"props":2115,"children":2116},{},[2117,2121,2125,2129],{"type":21,"tag":84,"props":2118,"children":2119},{},[2120],{"type":26,"value":134},{"type":21,"tag":84,"props":2122,"children":2123},{},[2124],{"type":26,"value":139},{"type":21,"tag":84,"props":2126,"children":2127},{},[2128],{"type":26,"value":144},{"type":21,"tag":84,"props":2130,"children":2131},{},[2132],{"type":26,"value":149},{"type":21,"tag":52,"props":2134,"children":2135},{},[2136,2140,2144,2148],{"type":21,"tag":84,"props":2137,"children":2138},{},[2139],{"type":26,"value":157},{"type":21,"tag":84,"props":2141,"children":2142},{},[2143],{"type":26,"value":162},{"type":21,"tag":84,"props":2145,"children":2146},{},[2147],{"type":26,"value":167},{"type":21,"tag":84,"props":2149,"children":2150},{},[2151],{"type":26,"value":172},{"type":21,"tag":52,"props":2153,"children":2154},{},[2155,2159,2163,2167],{"type":21,"tag":84,"props":2156,"children":2157},{},[2158],{"type":26,"value":180},{"type":21,"tag":84,"props":2160,"children":2161},{},[2162],{"type":26,"value":185},{"type":21,"tag":84,"props":2164,"children":2165},{},[2166],{"type":26,"value":190},{"type":21,"tag":84,"props":2168,"children":2169},{},[2170],{"type":26,"value":195},{"type":21,"tag":52,"props":2172,"children":2173},{},[2174,2178,2182,2186],{"type":21,"tag":84,"props":2175,"children":2176},{},[2177],{"type":26,"value":203},{"type":21,"tag":84,"props":2179,"children":2180},{},[2181],{"type":26,"value":208},{"type":21,"tag":84,"props":2183,"children":2184},{},[2185],{"type":26,"value":213},{"type":21,"tag":84,"props":2187,"children":2188},{},[2189],{"type":26,"value":218},{"type":21,"tag":22,"props":2191,"children":2192},{"id":221},[2193],{"type":26,"value":221},{"type":21,"tag":28,"props":2195,"children":2196},{},[2197],{"type":26,"value":228},{"type":21,"tag":230,"props":2199,"children":2200},{"id":232},[2201],{"type":26,"value":232},{"type":21,"tag":28,"props":2203,"children":2204},{},[2205],{"type":26,"value":239},{"type":21,"tag":241,"props":2207,"children":2209},{"className":2208,"code":245,"language":246,"meta":7},[244],[2210],{"type":21,"tag":249,"props":2211,"children":2212},{"__ignoreMap":7},[2213],{"type":26,"value":245},{"type":21,"tag":230,"props":2215,"children":2216},{"id":255},[2217],{"type":26,"value":255},{"type":21,"tag":28,"props":2219,"children":2220},{},[2221],{"type":26,"value":262},{"type":21,"tag":44,"props":2223,"children":2224},{},[2225,2247],{"type":21,"tag":48,"props":2226,"children":2227},{},[2228],{"type":21,"tag":52,"props":2229,"children":2230},{},[2231,2235,2239,2243],{"type":21,"tag":56,"props":2232,"children":2233},{},[2234],{"type":26,"value":276},{"type":21,"tag":56,"props":2236,"children":2237},{},[2238],{"type":26,"value":281},{"type":21,"tag":56,"props":2240,"children":2241},{},[2242],{"type":26,"value":286},{"type":21,"tag":56,"props":2244,"children":2245},{},[2246],{"type":26,"value":291},{"type":21,"tag":77,"props":2248,"children":2249},{},[2250,2269,2288,2307,2326,2345,2364,2383],{"type":21,"tag":52,"props":2251,"children":2252},{},[2253,2257,2261,2265],{"type":21,"tag":84,"props":2254,"children":2255},{},[2256],{"type":26,"value":302},{"type":21,"tag":84,"props":2258,"children":2259},{},[2260],{"type":26,"value":307},{"type":21,"tag":84,"props":2262,"children":2263},{},[2264],{"type":26,"value":312},{"type":21,"tag":84,"props":2266,"children":2267},{},[2268],{"type":26,"value":317},{"type":21,"tag":52,"props":2270,"children":2271},{},[2272,2276,2280,2284],{"type":21,"tag":84,"props":2273,"children":2274},{},[2275],{"type":26,"value":325},{"type":21,"tag":84,"props":2277,"children":2278},{},[2279],{"type":26,"value":330},{"type":21,"tag":84,"props":2281,"children":2282},{},[2283],{"type":26,"value":312},{"type":21,"tag":84,"props":2285,"children":2286},{},[2287],{"type":26,"value":317},{"type":21,"tag":52,"props":2289,"children":2290},{},[2291,2295,2299,2303],{"type":21,"tag":84,"props":2292,"children":2293},{},[2294],{"type":26,"value":346},{"type":21,"tag":84,"props":2296,"children":2297},{},[2298],{"type":26,"value":351},{"type":21,"tag":84,"props":2300,"children":2301},{},[2302],{"type":26,"value":312},{"type":21,"tag":84,"props":2304,"children":2305},{},[2306],{"type":26,"value":360},{"type":21,"tag":52,"props":2308,"children":2309},{},[2310,2314,2318,2322],{"type":21,"tag":84,"props":2311,"children":2312},{},[2313],{"type":26,"value":368},{"type":21,"tag":84,"props":2315,"children":2316},{},[2317],{"type":26,"value":373},{"type":21,"tag":84,"props":2319,"children":2320},{},[2321],{"type":26,"value":378},{"type":21,"tag":84,"props":2323,"children":2324},{},[2325],{"type":26,"value":383},{"type":21,"tag":52,"props":2327,"children":2328},{},[2329,2333,2337,2341],{"type":21,"tag":84,"props":2330,"children":2331},{},[2332],{"type":26,"value":391},{"type":21,"tag":84,"props":2334,"children":2335},{},[2336],{"type":26,"value":396},{"type":21,"tag":84,"props":2338,"children":2339},{},[2340],{"type":26,"value":401},{"type":21,"tag":84,"props":2342,"children":2343},{},[2344],{"type":26,"value":406},{"type":21,"tag":52,"props":2346,"children":2347},{},[2348,2352,2356,2360],{"type":21,"tag":84,"props":2349,"children":2350},{},[2351],{"type":26,"value":414},{"type":21,"tag":84,"props":2353,"children":2354},{},[2355],{"type":26,"value":419},{"type":21,"tag":84,"props":2357,"children":2358},{},[2359],{"type":26,"value":378},{"type":21,"tag":84,"props":2361,"children":2362},{},[2363],{"type":26,"value":428},{"type":21,"tag":52,"props":2365,"children":2366},{},[2367,2371,2375,2379],{"type":21,"tag":84,"props":2368,"children":2369},{},[2370],{"type":26,"value":436},{"type":21,"tag":84,"props":2372,"children":2373},{},[2374],{"type":26,"value":441},{"type":21,"tag":84,"props":2376,"children":2377},{},[2378],{"type":26,"value":378},{"type":21,"tag":84,"props":2380,"children":2381},{},[2382],{"type":26,"value":450},{"type":21,"tag":52,"props":2384,"children":2385},{},[2386,2390,2394,2398],{"type":21,"tag":84,"props":2387,"children":2388},{},[2389],{"type":26,"value":458},{"type":21,"tag":84,"props":2391,"children":2392},{},[2393],{"type":26,"value":463},{"type":21,"tag":84,"props":2395,"children":2396},{},[2397],{"type":26,"value":312},{"type":21,"tag":84,"props":2399,"children":2400},{},[2401],{"type":26,"value":317},{"type":21,"tag":241,"props":2403,"children":2405},{"className":2404,"code":476,"language":477,"meta":7},[475],[2406],{"type":21,"tag":249,"props":2407,"children":2408},{"__ignoreMap":7},[2409],{"type":26,"value":476},{"type":21,"tag":230,"props":2411,"children":2412},{"id":485},[2413],{"type":26,"value":485},{"type":21,"tag":28,"props":2415,"children":2416},{},[2417],{"type":26,"value":492},{"type":21,"tag":28,"props":2419,"children":2420},{},[2421],{"type":21,"tag":497,"props":2422,"children":2423},{},[2424],{"type":26,"value":501},{"type":21,"tag":503,"props":2426,"children":2427},{},[2428,2432,2436],{"type":21,"tag":507,"props":2429,"children":2430},{},[2431],{"type":26,"value":511},{"type":21,"tag":507,"props":2433,"children":2434},{},[2435],{"type":26,"value":516},{"type":21,"tag":507,"props":2437,"children":2438},{},[2439],{"type":26,"value":521},{"type":21,"tag":28,"props":2441,"children":2442},{},[2443],{"type":21,"tag":497,"props":2444,"children":2445},{},[2446],{"type":26,"value":529},{"type":21,"tag":503,"props":2448,"children":2449},{},[2450,2454,2458],{"type":21,"tag":507,"props":2451,"children":2452},{},[2453],{"type":26,"value":537},{"type":21,"tag":507,"props":2455,"children":2456},{},[2457],{"type":26,"value":542},{"type":21,"tag":507,"props":2459,"children":2460},{},[2461],{"type":26,"value":547},{"type":21,"tag":28,"props":2463,"children":2464},{},[2465],{"type":21,"tag":497,"props":2466,"children":2467},{},[2468],{"type":26,"value":555},{"type":21,"tag":503,"props":2470,"children":2471},{},[2472,2476,2480,2484],{"type":21,"tag":507,"props":2473,"children":2474},{},[2475],{"type":26,"value":563},{"type":21,"tag":507,"props":2477,"children":2478},{},[2479],{"type":26,"value":568},{"type":21,"tag":507,"props":2481,"children":2482},{},[2483],{"type":26,"value":573},{"type":21,"tag":507,"props":2485,"children":2486},{},[2487],{"type":26,"value":578},{"type":21,"tag":241,"props":2489,"children":2491},{"className":2490,"code":582,"language":477,"meta":7},[475],[2492],{"type":21,"tag":249,"props":2493,"children":2494},{"__ignoreMap":7},[2495],{"type":26,"value":582},{"type":21,"tag":22,"props":2497,"children":2498},{"id":590},[2499],{"type":26,"value":590},{"type":21,"tag":28,"props":2501,"children":2502},{},[2503],{"type":26,"value":597},{"type":21,"tag":230,"props":2505,"children":2506},{"id":600},[2507],{"type":26,"value":600},{"type":21,"tag":28,"props":2509,"children":2510},{},[2511],{"type":26,"value":607},{"type":21,"tag":241,"props":2513,"children":2515},{"className":2514,"code":611,"language":246,"meta":7},[244],[2516],{"type":21,"tag":249,"props":2517,"children":2518},{"__ignoreMap":7},[2519],{"type":26,"value":611},{"type":21,"tag":230,"props":2521,"children":2522},{"id":619},[2523],{"type":26,"value":619},{"type":21,"tag":28,"props":2525,"children":2526},{},[2527],{"type":26,"value":626},{"type":21,"tag":241,"props":2529,"children":2531},{"className":2530,"code":630,"language":246,"meta":7},[244],[2532],{"type":21,"tag":249,"props":2533,"children":2534},{"__ignoreMap":7},[2535],{"type":26,"value":630},{"type":21,"tag":22,"props":2537,"children":2538},{"id":638},[2539],{"type":26,"value":638},{"type":21,"tag":28,"props":2541,"children":2542},{},[2543],{"type":26,"value":645},{"type":21,"tag":230,"props":2545,"children":2546},{"id":648},[2547],{"type":26,"value":648},{"type":21,"tag":241,"props":2549,"children":2551},{"className":2550,"code":654,"language":246,"meta":7},[244],[2552],{"type":21,"tag":249,"props":2553,"children":2554},{"__ignoreMap":7},[2555],{"type":26,"value":654},{"type":21,"tag":230,"props":2557,"children":2558},{"id":662},[2559],{"type":26,"value":662},{"type":21,"tag":28,"props":2561,"children":2562},{},[2563],{"type":26,"value":669},{"type":21,"tag":241,"props":2565,"children":2567},{"className":2566,"code":673,"language":246,"meta":7},[244],[2568],{"type":21,"tag":249,"props":2569,"children":2570},{"__ignoreMap":7},[2571],{"type":26,"value":673},{"type":21,"tag":22,"props":2573,"children":2574},{"id":681},[2575],{"type":26,"value":681},{"type":21,"tag":28,"props":2577,"children":2578},{},[2579],{"type":26,"value":688},{"type":21,"tag":241,"props":2581,"children":2583},{"className":2582,"code":692,"language":246,"meta":7},[244],[2584],{"type":21,"tag":249,"props":2585,"children":2586},{"__ignoreMap":7},[2587],{"type":26,"value":692},{"type":21,"tag":22,"props":2589,"children":2590},{"id":700},[2591],{"type":26,"value":700},{"type":21,"tag":28,"props":2593,"children":2594},{},[2595],{"type":26,"value":707},{"type":21,"tag":241,"props":2597,"children":2599},{"className":2598,"code":711,"language":246,"meta":7},[244],[2600],{"type":21,"tag":249,"props":2601,"children":2602},{"__ignoreMap":7},[2603],{"type":26,"value":711},{"type":21,"tag":22,"props":2605,"children":2606},{"id":719},[2607],{"type":26,"value":719},{"type":21,"tag":28,"props":2609,"children":2610},{},[2611],{"type":26,"value":726},{"type":21,"tag":241,"props":2613,"children":2615},{"className":2614,"code":730,"language":246,"meta":7},[244],[2616],{"type":21,"tag":249,"props":2617,"children":2618},{"__ignoreMap":7},[2619],{"type":26,"value":730},{"type":21,"tag":22,"props":2621,"children":2622},{"id":738},[2623],{"type":26,"value":738},{"type":21,"tag":28,"props":2625,"children":2626},{},[2627],{"type":26,"value":745},{"type":21,"tag":230,"props":2629,"children":2630},{"id":748},[2631],{"type":26,"value":748},{"type":21,"tag":241,"props":2633,"children":2635},{"className":2634,"code":754,"language":246,"meta":7},[244],[2636],{"type":21,"tag":249,"props":2637,"children":2638},{"__ignoreMap":7},[2639],{"type":26,"value":754},{"type":21,"tag":230,"props":2641,"children":2642},{"id":762},[2643],{"type":26,"value":762},{"type":21,"tag":241,"props":2645,"children":2647},{"className":2646,"code":768,"language":246,"meta":7},[244],[2648],{"type":21,"tag":249,"props":2649,"children":2650},{"__ignoreMap":7},[2651],{"type":26,"value":768},{"type":21,"tag":22,"props":2653,"children":2654},{"id":776},[2655],{"type":26,"value":776},{"type":21,"tag":230,"props":2657,"children":2658},{"id":781},[2659],{"type":26,"value":784},{"type":21,"tag":28,"props":2661,"children":2662},{},[2663],{"type":26,"value":789},{"type":21,"tag":503,"props":2665,"children":2666},{},[2667,2675,2683],{"type":21,"tag":507,"props":2668,"children":2669},{},[2670,2674],{"type":21,"tag":497,"props":2671,"children":2672},{},[2673],{"type":26,"value":800},{"type":26,"value":802},{"type":21,"tag":507,"props":2676,"children":2677},{},[2678,2682],{"type":21,"tag":497,"props":2679,"children":2680},{},[2681],{"type":26,"value":810},{"type":26,"value":812},{"type":21,"tag":507,"props":2684,"children":2685},{},[2686,2690],{"type":21,"tag":497,"props":2687,"children":2688},{},[2689],{"type":26,"value":820},{"type":26,"value":822},{"type":21,"tag":230,"props":2692,"children":2693},{"id":825},[2694],{"type":26,"value":828},{"type":21,"tag":28,"props":2696,"children":2697},{},[2698],{"type":26,"value":833},{"type":21,"tag":241,"props":2700,"children":2702},{"className":2701,"code":838,"language":839,"meta":7},[837],[2703],{"type":21,"tag":249,"props":2704,"children":2705},{"__ignoreMap":7},[2706],{"type":26,"value":838},{"type":21,"tag":230,"props":2708,"children":2709},{"id":847},[2710],{"type":26,"value":850},{"type":21,"tag":44,"props":2712,"children":2713},{},[2714,2736],{"type":21,"tag":48,"props":2715,"children":2716},{},[2717],{"type":21,"tag":52,"props":2718,"children":2719},{},[2720,2724,2728,2732],{"type":21,"tag":56,"props":2721,"children":2722},{},[2723],{"type":26,"value":864},{"type":21,"tag":56,"props":2725,"children":2726},{},[2727],{"type":26,"value":869},{"type":21,"tag":56,"props":2729,"children":2730},{},[2731],{"type":26,"value":874},{"type":21,"tag":56,"props":2733,"children":2734},{},[2735],{"type":26,"value":879},{"type":21,"tag":77,"props":2737,"children":2738},{},[2739,2758,2777],{"type":21,"tag":52,"props":2740,"children":2741},{},[2742,2746,2750,2754],{"type":21,"tag":84,"props":2743,"children":2744},{},[2745],{"type":26,"value":890},{"type":21,"tag":84,"props":2747,"children":2748},{},[2749],{"type":26,"value":895},{"type":21,"tag":84,"props":2751,"children":2752},{},[2753],{"type":26,"value":900},{"type":21,"tag":84,"props":2755,"children":2756},{},[2757],{"type":26,"value":905},{"type":21,"tag":52,"props":2759,"children":2760},{},[2761,2765,2769,2773],{"type":21,"tag":84,"props":2762,"children":2763},{},[2764],{"type":26,"value":913},{"type":21,"tag":84,"props":2766,"children":2767},{},[2768],{"type":26,"value":918},{"type":21,"tag":84,"props":2770,"children":2771},{},[2772],{"type":26,"value":923},{"type":21,"tag":84,"props":2774,"children":2775},{},[2776],{"type":26,"value":928},{"type":21,"tag":52,"props":2778,"children":2779},{},[2780,2784,2788,2792],{"type":21,"tag":84,"props":2781,"children":2782},{},[2783],{"type":26,"value":936},{"type":21,"tag":84,"props":2785,"children":2786},{},[2787],{"type":26,"value":941},{"type":21,"tag":84,"props":2789,"children":2790},{},[2791],{"type":26,"value":946},{"type":21,"tag":84,"props":2793,"children":2794},{},[2795],{"type":26,"value":951},{"type":21,"tag":230,"props":2797,"children":2798},{"id":954},[2799],{"type":26,"value":957},{"type":21,"tag":503,"props":2801,"children":2802},{},[2803,2807,2811,2815],{"type":21,"tag":507,"props":2804,"children":2805},{},[2806],{"type":26,"value":965},{"type":21,"tag":507,"props":2808,"children":2809},{},[2810],{"type":26,"value":970},{"type":21,"tag":507,"props":2812,"children":2813},{},[2814],{"type":26,"value":975},{"type":21,"tag":507,"props":2816,"children":2817},{},[2818],{"type":26,"value":980},{"type":21,"tag":22,"props":2820,"children":2821},{"id":983},[2822],{"type":26,"value":983},{"type":21,"tag":28,"props":2824,"children":2825},{},[2826],{"type":26,"value":990},{"type":21,"tag":992,"props":2828,"children":2829},{},[2830,2838,2846,2854,2862],{"type":21,"tag":507,"props":2831,"children":2832},{},[2833,2837],{"type":21,"tag":497,"props":2834,"children":2835},{},[2836],{"type":26,"value":1002},{"type":26,"value":1004},{"type":21,"tag":507,"props":2839,"children":2840},{},[2841,2845],{"type":21,"tag":497,"props":2842,"children":2843},{},[2844],{"type":26,"value":1012},{"type":26,"value":1014},{"type":21,"tag":507,"props":2847,"children":2848},{},[2849,2853],{"type":21,"tag":497,"props":2850,"children":2851},{},[2852],{"type":26,"value":1022},{"type":26,"value":1024},{"type":21,"tag":507,"props":2855,"children":2856},{},[2857,2861],{"type":21,"tag":497,"props":2858,"children":2859},{},[2860],{"type":26,"value":1032},{"type":26,"value":1034},{"type":21,"tag":507,"props":2863,"children":2864},{},[2865,2869],{"type":21,"tag":497,"props":2866,"children":2867},{},[2868],{"type":26,"value":1042},{"type":26,"value":1044},{"type":21,"tag":28,"props":2871,"children":2872},{},[2873],{"type":26,"value":1049},{"title":7,"searchDepth":1051,"depth":1051,"links":2875},[2876,2877,2878,2883,2887,2891,2892,2893,2894,2898,2904],{"id":8,"depth":1054,"text":8},{"id":35,"depth":1054,"text":35},{"id":221,"depth":1054,"text":221,"children":2879},[2880,2881,2882],{"id":232,"depth":1051,"text":232},{"id":255,"depth":1051,"text":255},{"id":485,"depth":1051,"text":485},{"id":590,"depth":1054,"text":590,"children":2884},[2885,2886],{"id":600,"depth":1051,"text":600},{"id":619,"depth":1051,"text":619},{"id":638,"depth":1054,"text":638,"children":2888},[2889,2890],{"id":648,"depth":1051,"text":648},{"id":662,"depth":1051,"text":662},{"id":681,"depth":1054,"text":681},{"id":700,"depth":1054,"text":700},{"id":719,"depth":1054,"text":719},{"id":738,"depth":1054,"text":738,"children":2895},[2896,2897],{"id":748,"depth":1051,"text":748},{"id":762,"depth":1051,"text":762},{"id":776,"depth":1054,"text":776,"children":2899},[2900,2901,2902,2903],{"id":781,"depth":1051,"text":784},{"id":825,"depth":1051,"text":828},{"id":847,"depth":1051,"text":850},{"id":954,"depth":1051,"text":957},{"id":983,"depth":1054,"text":983},1778574590642]