Skyroc Native UI

Radio

单选框,含分组、卡片与卡片组四个组件

单选框(Radio)用于在一组互斥选项中选择一个。包含四个组件:Radio 单项、RadioGroup 分组容器、RadioCard 卡片式单项、RadioGroupCard 数据驱动的卡片组。分组内的选中态由 RadioGroup 通过 context 统一持有,子项只声明 name

import { Radio, RadioCard, RadioGroup, RadioGroupCard } from '@skyroc/native-ui';

基础用法

单独使用时 Radio 自己维护选中态:非受控传 defaultChecked,受控传 checked + onCheckedChange

RadioBasic.tsx
Loading…
import { Radio } from '@skyroc/native-ui';
import { View } from 'react-native';

const RadioBasic = () => {
  return (
    <View className="gap-3 bg-background p-4">
      <Radio defaultChecked>默认选中</Radio>
      <Radio>未选中</Radio>
    </View>
  );
};

export { RadioBasic };

单选语义下,已选中的项再次点击不会取消,取消只能由外部改 value / checked

何时使用

  • 一组互斥选项,且选项数量少到可以全部平铺时使用;选项多请用 Picker
  • 需要「图标 + 标题 + 描述」的富选项(套餐、支付方式、网络类型)时用 RadioCard
  • 选项来自数据数组、不想手写 JSX 时用 RadioGroupCard
  • 可多选的场景请用 Checkbox,它与 Radio 的属性命名保持一致。

语义颜色

color 提供 8 种主题色,取值与全局 ThemeColor 一致。round 选中时是「同色描边 + 同色圆点」,square 选中时是「填充背景 + {color}-foreground 色的勾」。

颜色选中表现(round / square)语义
primaryborder-primary / bg-primary常规选择(默认)
destructiveborder-destructive / bg-destructive危险项
successborder-success / bg-success成功、推荐项
warningborder-warning / bg-warning需要注意的选项
infoborder-info / bg-info信息性选项
accentborder-accent / bg-accent强调色
carbonborder-carbon / bg-carbon中性深色
secondaryborder-secondary / bg-secondary次级、弱化选项
RadioColor.tsx
Loading…
import { Radio, RadioGroup } from '@skyroc/native-ui';
import type { ThemeColor } from '@skyroc/ui-types';
import { View } from 'react-native';

const COLORS: ThemeColor[] = ['primary', 'destructive', 'success', 'warning', 'info', 'accent', 'carbon', 'secondary'];

const RadioColor = () => {
  return (
    <View className="gap-4 bg-background p-4">
      {COLORS.map(c => (
        <RadioGroup
          color={c}
          defaultValue="a"
          direction="horizontal"
          key={c}
        >
          <Radio name="a">{c}</Radio>
          <Radio name="b">B</Radio>
        </RadioGroup>
      ))}
    </View>
  );
};

export { RadioColor };

未选中态与颜色无关,统一是 border-muted-foreground/50 的空心描边。

尺寸

size 同时决定外圈边长、内部指示器大小、标签字号与两者的间距:

尺寸外圈圆点(round)勾(square)标签字号间距
xs1469text-xs4
sm16811text-sm6
md201014text-base8
lg241216text-base10
xl281418text-base12
2xl321620text-lg14
RadioSize.tsx
Loading…
import { Radio } from '@skyroc/native-ui';
import { View } from 'react-native';

const SIZES = ['xs', 'sm', 'md', 'lg', 'xl', '2xl'] as const;

const RadioSize = () => {
  return (
    <View className="gap-3 bg-background p-4">
      {SIZES.map(s => (
        <Radio
          key={s}
          defaultChecked
          size={s}
        >
          {s}
        </Radio>
      ))}
    </View>
  );
};

export { RadioSize };

形状

shape 控制指示器形状:round 是圆形(默认),square 是圆角方形,选中态渲染成实心背景加一个勾 —— 与 Checkbox 的观感一致。

RadioShape.tsx
Loading…
import { Radio } from '@skyroc/native-ui';
import { View } from 'react-native';

const RadioShape = () => {
  return (
    <View className="gap-3 bg-background p-4">
      <Radio
        defaultChecked
        shape="round"
      >
        圆形(默认)
      </Radio>
      <Radio
        defaultChecked
        shape="square"
      >
        方形
      </Radio>
    </View>
  );
};

export { RadioShape };

指示器

iconSize 直接指定外圈边长(px),内部指示器按固定比例一起缩放:圆点为 iconSize × 0.5,勾为 iconSize × 0.7(四舍五入)。这样放大后比例不会失衡。checkedIcon 则完全替换选中态的默认圆点 / 勾,外圈仍保留。

RadioIndicator.tsx
Loading…
import Feather from '@expo/vector-icons/Feather';
import { Radio } from '@skyroc/native-ui';
import { View } from 'react-native';

const RadioIndicator = () => {
  return (
    <View className="gap-4 bg-background p-4">
      <Radio
        defaultChecked
        iconSize={28}
      >
        iconSize=28
      </Radio>
      <Radio
        defaultChecked
        checkedIcon={
          <Feather
            color="var(--primary)"
            name="star"
            size={18}
          />
        }
        iconSize={28}
      >
        自定义 checkedIcon
      </Radio>
    </View>
  );
};

export { RadioIndicator };

checkedIcon 的颜色不随 color 变化,需要自己在图标上指定。

禁用

disabled 可用于单项,也可用于 RadioGroup 整组。两者取并集 —— 组禁用时子项无法把自己反选为可用。禁用后整行降到 50% 不透明度,标签文字转为 text-muted-foreground

RadioDisabled.tsx
Loading…
import { Radio, RadioGroup } from '@skyroc/native-ui';
import { View } from 'react-native';

const RadioDisabled = () => {
  return (
    <View className="gap-3 bg-background p-4">
      <Radio disabled>Disabled</Radio>
      <Radio
        defaultChecked
        disabled
      >
        Disabled & Checked
      </Radio>
      <RadioGroup
        disabled
        defaultValue="a"
      >
        <Radio name="a">整组禁用:已选</Radio>
        <Radio name="b">整组禁用:未选</Radio>
      </RadioGroup>
    </View>
  );
};

export { RadioDisabled };

标签交互

labelPosition 决定标签在指示器的哪一侧(right 默认,left 时容器变为 flex-row-reverse)。标签本身是一块独立的可点区域,labelDisabled 可以把它关掉,只留指示器可点。

RadioLabelPosition.tsx
Loading…
import { Radio } from '@skyroc/native-ui';
import { View } from 'react-native';

const RadioLabelPosition = () => {
  return (
    <View className="gap-3 bg-background p-4">
      <Radio labelPosition="right">标签在右侧</Radio>
      <Radio labelPosition="left">标签在左侧</Radio>
      <Radio labelDisabled>标签不可点击,仅指示器可选</Radio>
    </View>
  );
};

export { RadioLabelPosition };

受控

单独使用时传 checked + onCheckedChange 即为受控。注意:位于 RadioGroup 内且传了 namechecked 会被忽略,选中态一律由组的 value 决定。

RadioControlled.tsx
Loading…
import { Button, Radio } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';

const RadioControlled = () => {
  const [controlled, setControlled] = useState(false);

  return (
    <View className="gap-3 bg-background p-4">
      <Radio
        checked={controlled}
        onCheckedChange={setControlled}
      >
        {controlled ? '已选中' : '未选中'}
      </Radio>
      <Button
        size="sm"
        onPress={() => setControlled(v => !v)}
      >
        切换选中状态
      </Button>
    </View>
  );
};

export { RadioControlled };

分组

RadioGroup 持有整组的选中值,子项用 name 声明自己的取值。受控传 value + onChange,非受控传 defaultValue

RadioGroupBasic.tsx
Loading…
import { Radio, RadioGroup, Text } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';

const FRUIT_ITEMS = [
  { label: '未指定(空字符串)', value: '' },
  { label: '苹果', value: 'apple' },
  { label: '橙子', value: 'orange' },
  { label: '香蕉', value: 'banana' }
];

const RadioGroupBasic = () => {
  const [groupValue, setGroupValue] = useState('apple');

  return (
    <View className="gap-3 bg-background p-4">
      <RadioGroup
        value={groupValue}
        onChange={setGroupValue}
      >
        {FRUIT_ITEMS.map(item => (
          <Radio
            key={item.value}
            name={item.value}
          >
            {item.label}
          </Radio>
        ))}
      </RadioGroup>
      <Text className="text-sm text-muted-foreground">当前值:{groupValue || "''"}</Text>
    </View>
  );
};

export { RadioGroupBasic };

未选中用 undefined 表示,空字符串是合法取值,可以作为「未指定」这类选项。子项在组内缺 name 会在开发环境告警,并退化成不参与互斥的独立单选框。

横向分组

direction="horizontal" 让子项横向排列并自动换行(flex-wrap)。间距同样跟随 size:横向 8 ~ 18,纵向 4 ~ 14。

RadioHorizontalGroup.tsx
Loading…
import { Radio, RadioGroup } from '@skyroc/native-ui';
import { View } from 'react-native';

const RadioHorizontalGroup = () => {
  return (
    <View className="bg-background p-4">
      <RadioGroup
        defaultValue="a"
        direction="horizontal"
      >
        <Radio name="a">A</Radio>
        <Radio name="b">B</Radio>
        <Radio name="c">C</Radio>
        <Radio name="d">D</Radio>
      </RadioGroup>
    </View>
  );
};

export { RadioHorizontalGroup };

分组样式下发

colorshapesizeiconSizelabelPositioncheckedIcondisabled 都可以在 RadioGroup 上统一设置,子项按「自身 prop > 组配置 > 默认值」的优先级取用。

RadioSquareGroup.tsx
Loading…
import { Radio, RadioGroup } from '@skyroc/native-ui';
import { View } from 'react-native';

const RadioSquareGroup = () => {
  return (
    <View className="bg-background p-4">
      <RadioGroup
        color="warning"
        defaultValue="x"
        shape="square"
      >
        <Radio name="x">X</Radio>
        <Radio name="y">Y</Radio>
        <Radio name="z">Z</Radio>
      </RadioGroup>
    </View>
  );
};

export { RadioSquareGroup };

样式覆盖

className 追加到根容器上,classNames 按 slot 细粒度覆盖;RadioGroupCard 的卡片由组件内部渲染,只能通过 itemClassNames 统一透传。

slot归属作用位置
rootRadio / RadioCard根容器(RadioViewRadioCardPressable
controlRadio包住指示器的可点区域
labelWrapperRadio包住标签的可点区域
labelRadio / RadioCard标签文字
indicatorRadio / RadioCard指示器外圈(边框、背景、形状)
dotRadio / RadioCardround 选中态的内圆点
indicatorIconRadio / RadioCardsquare 内置勾的 colorClassName,只接受 accent-*
contentRadioCard图标 + 文本的横向容器
iconRadioCard卡片图标的容器
textsRadioCard标题 + 描述的纵向容器
descriptionRadioCard描述文字
RadioStyles.tsx
Loading…
import { Radio, RadioGroupCard } from '@skyroc/native-ui';
import { View } from 'react-native';

const STYLE_ITEMS = [
  { description: '使用统一的卡片 slot 样式', label: '选项 A', value: 'a' },
  { description: '单项禁用状态仍然保留', disabled: true, label: '选项 B', value: 'b' }
];

const RadioStyles = () => {
  return (
    <View className="gap-4 bg-background p-4">
      <Radio
        className="rounded-xl bg-primary-50 p-3"
        classNames={{ dot: 'bg-success', indicator: 'border-success', label: 'font-semibold text-primary' }}
        defaultChecked
      >
        自定义单选项样式
      </Radio>
      <RadioGroupCard
        defaultValue="a"
        itemClassNames={{ label: 'text-primary', root: 'border-primary-200 bg-primary-50' }}
        items={STYLE_ITEMS}
      />
    </View>
  );
};

export { RadioStyles };

className 排在 classNames.root 之后参与合并,冲突时 className 优先。

自定义内容

RadiochildrenRadioCardlabel / description 都接受任意节点:传 string / number 时自动包一层 Text,传节点时原样渲染(此时 classNames.label 不再生效,样式自己控制)。

RadioCustomContent.tsx
Loading…
import Feather from '@expo/vector-icons/Feather';
import { Radio, RadioCard, Text } from '@skyroc/native-ui';
import { View } from 'react-native';

const RadioCustomContent = () => {
  return (
    <View className="gap-4 bg-background p-4">
      <Radio defaultChecked>
        <View className="flex-row items-center gap-2">
          <Text className="font-medium text-foreground">自定义标签</Text>
          <Text className="rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary">推荐</Text>
        </View>
      </Radio>
      <RadioCard
        defaultChecked
        description={<Text className="text-xs text-success">可用状态</Text>}
        icon={
          <Feather
            color="var(--primary)"
            name="zap"
            size={20}
          />
        }
        label={<Text className="font-semibold text-primary">自定义卡片内容</Text>}
      />
    </View>
  );
};

export { RadioCustomContent };

卡片

RadioCard 把图标、标题、描述组成一整块可点区域,radioPosition 决定指示器排在内容左侧还是右侧。它和 Radio 共用同一套指示器与选中逻辑,因此 color / shape / iconSize / checkedIcon 行为完全一致。

RadioCardBasic.tsx
Loading…
import Feather from '@expo/vector-icons/Feather';
import { RadioCard } from '@skyroc/native-ui';
import { View } from 'react-native';

const RadioCardBasic = () => {
  return (
    <View className="gap-3 bg-background p-4">
      <RadioCard
        color="primary"
        defaultChecked
        description="稳定且速度快"
        icon={
          <Feather
            color="var(--primary)"
            name="wifi"
            size={20}
          />
        }
        label="无线网络"
      />
      <RadioCard
        color="warning"
        description="使用移动数据"
        icon={
          <Feather
            color="var(--success)"
            name="smartphone"
            size={20}
          />
        }
        label="蜂窝网络"
        radioPosition="right"
        shape="square"
      />
      <RadioCard
        color="success"
        description="设备连接不可用"
        disabled
        icon={
          <Feather
            color="var(--muted-foreground)"
            name="bluetooth"
            size={20}
          />
        }
        label="蓝牙"
      />
    </View>
  );
};

export { RadioCardBasic };

RadioCard 的标题与描述字号是固定的(text-sm / text-xs),size 在卡片上只影响指示器大小。

卡片组

RadioGroupCardRadioGroup + RadioCard 的数据驱动封装:用 items 一次声明整组卡片,选中态与互斥逻辑完全复用 RadioGroupContext

RadioCardGroup.tsx
Loading…
import Feather from '@expo/vector-icons/Feather';
import { RadioGroupCard, Text } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';

const CARD_ITEMS = [
  {
    description: '稳定且速度快',
    icon: (
      <Feather
        color="var(--primary)"
        name="wifi"
        size={20}
      />
    ),
    label: '无线网络',
    value: 'wifi'
  },
  {
    description: '使用移动数据',
    icon: (
      <Feather
        color="var(--success)"
        name="smartphone"
        size={20}
      />
    ),
    label: '蜂窝网络',
    value: 'cellular'
  },
  {
    description: '直连附近设备',
    icon: (
      <Feather
        color="var(--info)"
        name="bluetooth"
        size={20}
      />
    ),
    label: '蓝牙',
    value: 'bluetooth'
  }
];

const RadioCardGroup = () => {
  const [cardGroupValue, setCardGroupValue] = useState('wifi');

  return (
    <View className="gap-3 bg-background p-4">
      <RadioGroupCard
        color="info"
        items={CARD_ITEMS}
        radioPosition="right"
        value={cardGroupValue}
        onChange={setCardGroupValue}
      />
      <Text className="text-sm text-muted-foreground">当前值:{cardGroupValue}</Text>
    </View>
  );
};

export { RadioCardGroup };

热区与无障碍

  • Radio 的指示器带 hitSlop={4},标签是第二块独立热区,小尺寸下不需要业务侧再包一层 Pressable
  • RadioCard 整张卡片即热区,按下时整体降到 90% 不透明度。
  • 组件目前没有设置 accessibilityRole / accessibilityState,也不透传 RN 的无障碍属性,读屏器只会朗读标签文本、不播报选中状态。需要完整读屏语义时,暂时只能在外层自行包裹带 accessibilityRole="radio" 的容器。

API

Radio

属性说明类型默认值
checked受控选中态;位于 RadioGroup 内且传了 name 时被忽略boolean-
defaultChecked非受控初始选中态booleanfalse
onCheckedChange选中回调,分组内同样触发;已选中项再次点击不触发(checked: boolean) => void-
name分组内的唯一标识,位于 RadioGroup 内时必填,缺失会在开发环境告警string | number-
color主题色,缺省时取组配置,再缺省为 primary'primary' | 'destructive' | 'success' | 'warning' | 'info' | 'accent' | 'carbon' | 'secondary''primary'
size尺寸预设,同时决定外圈边长、内部指示器、标签字号与间距;缺省时取组配置'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'
shape指示器形状,缺省时取组配置'round' | 'square''round'
iconSize外圈边长(px),内部圆点按 0.5 倍、勾按 0.7 倍等比缩放;缺省时取组配置number-
labelPosition标签相对指示器的位置,缺省时取组配置'left' | 'right''right'
labelDisabled只有指示器可点,标签点击不触发选中booleanfalse
disabled禁用,与组级 disabled 取并集booleanfalse
children标签内容,string / number 会被自动包裹为 TextReactNode-
checkedIcon选中态自定义图标,替换默认的圆点 / 勾ReactNode-
className根容器类名,合并在 classNames.root 之后string-
classNames各 slot 的类名覆盖,见「样式覆盖」一节SlotClassNames<RadioSlots>-
ref根容器 View 的 ref,用于 measure / 滚动定位Ref<View>-

RadioGroup

属性说明类型默认值
children*子项,通常为 Radio 或 RadioCardReactNode-
value受控选中值string | number-
defaultValue非受控初始选中值,缺省表示未选中string | number-
onChange选中值变化回调(value: string | number) => void-
direction排列方向,horizontal 会自动换行'horizontal' | 'vertical''vertical'
disabled禁用整组,子项无法反选为可用booleanfalse
color下发给所有子项的主题色'primary' | 'destructive' | 'success' | 'warning' | 'info' | 'accent' | 'carbon' | 'secondary'-
size下发给所有子项的尺寸,同时决定子项之间的间距'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'
shape下发给所有子项的指示器形状'round' | 'square'-
iconSize下发给所有子项的外圈边长(px)number-
labelPosition下发给所有子项的标签位置'left' | 'right'-
checkedIcon下发给所有子项的选中态自定义图标ReactNode-
className分组容器类名string-
ref分组容器 View 的 refRef<View>-

RadioCard

属性说明类型默认值
label标题,string / number 会被自动包裹为 TextReactNode-
description描述文字,显示在标题下方ReactNode-
icon卡片图标,显示在文本之前ReactNode-
radioPosition指示器相对卡片内容的位置'left' | 'right''left'
checked受控选中态;位于 RadioGroup 内且传了 name 时被忽略boolean-
defaultChecked非受控初始选中态booleanfalse
onCheckedChange选中回调(checked: boolean) => void-
name分组内的唯一标识,位于 RadioGroup 内时必填string | number-
color主题色,缺省时取组配置,再缺省为 primary'primary' | 'destructive' | 'success' | 'warning' | 'info' | 'accent' | 'carbon' | 'secondary''primary'
size尺寸预设,在卡片上只影响指示器大小;缺省时取组配置'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'
shape指示器形状,缺省时取组配置'round' | 'square''round'
iconSize外圈边长(px),内部指示器等比缩放number-
checkedIcon选中态自定义图标ReactNode-
disabled禁用,与组级 disabled 取并集booleanfalse
className卡片容器类名,合并在 classNames.root 之后string-
classNames各 slot 的类名覆盖,见「样式覆盖」一节SlotClassNames<RadioCardSlots>-
ref卡片根容器(Pressable)的 refRef<View>-

RadioGroupCard

属性说明类型默认值
items*卡片数据源RadioGroupCardItem[]-
value受控选中值string | number-
defaultValue非受控初始选中值string | number-
onChange选中值变化回调(value: string | number) => void-
radioPosition指示器相对卡片内容的位置,应用于所有卡片'left' | 'right''left'
direction排列方向,horizontal 会自动换行'horizontal' | 'vertical''vertical'
disabled禁用整组booleanfalse
color下发给所有卡片的主题色'primary' | 'destructive' | 'success' | 'warning' | 'info' | 'accent' | 'carbon' | 'secondary'-
size下发给所有卡片的尺寸,同时决定卡片之间的间距'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'
shape下发给所有卡片的指示器形状'round' | 'square'-
iconSize下发给所有卡片的外圈边长(px)number-
checkedIcon下发给所有卡片的选中态自定义图标ReactNode-
className分组容器类名string-
itemClassNames统一覆盖每张卡片的 slot 类名,卡片由组件内部渲染,只能从这里透传SlotClassNames<RadioCardSlots>-
ref分组容器 View 的 refRef<View>-

类型

import type {
  RadioCardProps,
  RadioCardSlots,
  RadioGroupCardItem,
  RadioGroupCardProps,
  RadioGroupContextValue,
  RadioGroupDirection,
  RadioGroupProps,
  RadioIndicatorSlots,
  RadioLabelPosition,
  RadioPosition,
  RadioProps,
  RadioShape,
  RadioSide,
  RadioSizes,
  RadioSlots,
  RadioValue
} from '@skyroc/native-ui';

RadioValue

分组内 name / value 的取值范围,RadioGroup 对它做泛型化以配合 useState<string> 的写法。

string | number

RadioShape

指示器形状,round 为圆形,square 为圆角方形。

'round' | 'square'

RadioSide

横向位置,RadioLabelPosition 与 RadioPosition 都是它的别名。

'left' | 'right'

RadioLabelPosition

标签相对指示器的位置,等价于 RadioSide。

'left' | 'right'

RadioPosition

卡片中指示器相对内容的位置,等价于 RadioSide。

'left' | 'right'

RadioGroupDirection

RadioGroup 的排列方向,horizontal 会自动换行。

'horizontal' | 'vertical'

RadioSlots

Radio 可通过 classNames 覆盖的 slot 名称。

'control' | 'dot' | 'indicator' | 'indicatorIcon' | 'label' | 'labelWrapper' | 'root'

RadioCardSlots

RadioCard 可通过 classNames 覆盖的 slot 名称。

'content' | 'description' | 'dot' | 'icon' | 'indicator' | 'indicatorIcon' | 'label' | 'root' | 'texts'

RadioIndicatorSlots

指示器相关的 slot 名称,Radio 与 RadioCard 共用这三个键。

'dot' | 'indicator' | 'indicatorIcon'

SlotClassNames

classNames 的取值形态:把 slot 名映射到类名,每个 slot 都可选。本页用到的 slot 见 RadioSlots / RadioCardSlots。

Partial<Record<Slots, string>>

RadioGroupCardItem

RadioGroupCard 的单条数据。

字段类型说明
value*string | number唯一标识,对应组的选中值。
label*ReactNode标题。
descriptionReactNode描述文本。
iconReactNode卡片图标。
disabledboolean是否禁用该项。

RadioSizes

解析后的像素尺寸,由 size 预设或 iconSize 推导。

字段类型说明
control*number外圈容器边长(px)。
dot*numberround 选中态圆点边长(px)。
innerIcon*numbersquare 选中态勾选图标边长(px)。

RadioGroupContextValue

RadioGroup 通过 context 下发给子项的配置与选中态操作,一般不需要直接使用。

字段类型说明
isChecked*(name: string | number) => boolean判断某个 name 是否被选中。
select*(name: string | number) => void选中某个 name。
color'primary' | 'destructive' | 'success' | 'warning' | 'info' | 'accent' | 'carbon' | 'secondary'组级主题色。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'组级尺寸预设。
shapeRadioShape组级指示器形状。
iconSizenumber组级外圈边长(px)。
labelPositionRadioLabelPosition组级标签位置。
checkedIconReactNode组级选中态自定义图标。
disabledboolean整组是否禁用。

包内还导出了 radioVariants / radioGroupVariants / radioCardVariantsresolveRadioSizes,以及三张尺寸映射表 RADIO_SIZE_CONTROL_MAP / RADIO_SIZE_DOT_MAP / RADIO_SIZE_INNER_ICON_MAP