Material 3 Expressive実装例 : Icon button

Material 3 Expressive の実装例の紹介シリーズです。
今回は Icon button を紹介します。
(`androidx.compose.material3:material3:1.4.0-alpha15` 時点での内容になります。)

## Material 3 Expressive での変更点

- スタイルや Shape の多様化
  - デフォルトと toggle
  - Filled、Tonal、Outlined、Standard のスタイル
  - Round と Square の Shape
  - 押下時の Shape のモーション
  - Extra small、Small、Medium、Large、Extra large のサイズ
  - Narrow、Default、Wide の横幅のバリエーション

https://m3.material.io/components/icon-buttons/overview

## 実装

### 押下時の Shape アニメーション

`IconButtonDefaults.shapes()` を Icon button の `shapes` に設定します。

```kotlin
FilledIconButton(
    onClick = {},
    shapes = IconButtonDefaults.shapes()
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/0a31cbeb-699e-4f0d-a632-d869f480627b.gif" width="300px" />



### Round と Square の Shape

Icon button の `shape` が未設定もしくは `IconButtonDefaults.smallRoundShape` を設定すると Round、`IconButtonDefaults.smallSquareShape` を設定すると Square になります。

```kotlin
// Round
FilledIconButton(
    onClick = {},
    shape = IconButtonDefaults.smallRoundShape
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}

// Square
FilledIconButton(
    onClick = {},
    shape = IconButtonDefaults.smallSquareShape
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/eaa585e4-8210-4947-b4a3-a15cdb11bf97.png" width="300px" />

### Filled、Tonal、Outlined、Standard のスタイル

```kotlin
// Filled
FilledIconButton(
    onClick = {},
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}

// Tonal
FilledTonalIconButton(
    onClick = {},
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}

// Outlined
OutlinedIconButton(
    onClick = {}
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}

// Standard
 IconButton(
    onClick = {}
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/2a51cc59-0e33-46b1-8404-4ad9d813fd50.png" width="300px" />


### Toggle 

Standard を除くそれぞれのスタイルに対して Toggle icon button が用意されています。

```kotlin
// Filled
FilledIconToggleButton(
    checked = checked,
    onCheckedChange = { checked = it },
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}

// Tonal
FilledTonalIconToggleButton(
    checked = checked,
    onCheckedChange = { checked = it },
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}

// Outlined
OutlinedIconToggleButton(
    checked = checked,
    onCheckedChange = { checked = it },
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit"
    )
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/22d7b741-adf5-4395-a8c5-f3608102acc8.png" width="300px" />

(左側が `checked = false`)


### Extra small、Small、Medium、Large、Extra large のサイズ

デフォルトでない Small 以外の Icon button のサイズが標準で用意されています。  
Icon button の Shape、Size とアイコン自体のサイズをそれぞれ設定する必要があります。

```kotlin
// Extra small
FilledIconButton(
    onClick = {　},
    shape = IconButtonDefaults.extraSmallRoundShape,
    modifier = Modifier
        .minimumInteractiveComponentSize()
        .size(IconButtonDefaults.extraSmallContainerSize())
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit",
        modifier = Modifier.size(IconButtonDefaults.extraSmallIconSize)
    )
}

// Small
FilledIconButton(
    onClick = { },
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit",
    )
}

// Medium
FilledIconButton(
    onClick = { },
    shape = IconButtonDefaults.mediumRoundShape,
    modifier = Modifier
        .size(IconButtonDefaults.mediumContainerSize())
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit",
        modifier = Modifier.size(IconButtonDefaults.mediumIconSize)
    )
}

// Large
FilledIconButton(
    onClick = { },
    shape = IconButtonDefaults.largeRoundShape,
    modifier = Modifier
        .size(IconButtonDefaults.largeContainerSize())
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit",
        modifier = Modifier.size(IconButtonDefaults.extraSmallIconSize)
    )
}

// Extra large
FilledIconButton(
    onClick = { },
    shape = IconButtonDefaults.extraLargeRoundShape,
    modifier = Modifier
        .size(IconButtonDefaults.extraLargeContainerSize())
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit",
        modifier = Modifier.size(IconButtonDefaults.extraLargeIconSize)
    )
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/3d7e58da-6a97-45ec-a0a1-6fc3a57340d0.png" width="300px" />

### 横幅のバリエーション

`IconButtonDefaults#XXXContainerSize` の引数である `IconButtonWidthOption` を変更することで、Narrow、Default、Wide の横幅のバリエーションを変更することができます。

```kotlin
// Narrow
FilledIconButton(
    onClick = {},
    modifier = Modifier
        .size(IconButtonDefaults.mediumContainerSize(IconButtonDefaults.IconButtonWidthOption.Narrow))
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit",
    )
}

// Default
FilledIconButton(
    onClick = {},
    modifier = Modifier
        .size(IconButtonDefaults.mediumContainerSize(IconButtonDefaults.IconButtonWidthOption.Uniform))
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit",
    )
}

// Wide
FilledIconButton(
    onClick = {},
    modifier = Modifier
        .size(IconButtonDefaults.mediumContainerSize(IconButtonDefaults.IconButtonWidthOption.Wide))
) {
    Icon(
        painterResource(R.drawable.ic_edit),
        contentDescription = "Edit",
    )
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/0477c236-4668-4c7b-ab5e-d4deb1654392.png" width="300px" />