This commit is contained in:
mishramayank1 2023-01-16 20:11:23 +05:30 коммит произвёл mishramayank1
Родитель 1fdbe1c8d1
Коммит a4b74347f1
26 изменённых файлов: 951 добавлений и 78 удалений

Просмотреть файл

@ -27,49 +27,51 @@
</activity>
<!-- Demo activities -->
<activity android:name="com.microsoft.fluentuidemo.demos.ActionBarLayoutActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2AppBarLayoutActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2AvatarActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2AvatarCarouselActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2AvatarGroupActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2BadgeActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2BasicInputsActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2BasicControlsActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2BottomSheetActivity" />
<activity
android:name="com.microsoft.fluentuidemo.demos.V2ContextualCommandBarActivity"
android:windowSoftInputMode="adjustResize" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2DrawerActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2ListItemActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2PersonaActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2PersonaChipActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2PersonaListActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2ProgressActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2SearchBarActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:windowSoftInputMode="adjustResize" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2SegmentedControlActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2TabBarActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.ActionBarLayoutActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.AppBarLayoutActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.AvatarViewActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.AvatarGroupViewActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.BasicInputsActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2AvatarActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2AvatarCarouselActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2AvatarGroupActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2BasicInputsActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2BasicControlsActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.BottomNavigationActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.BottomSheetActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.CalendarViewActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.ContextualCommandBarActivity" />
<activity
android:name="com.microsoft.fluentuidemo.demos.V2ContextualCommandBarActivity"
android:windowSoftInputMode="adjustResize" />
<activity android:name="com.microsoft.fluentuidemo.demos.DateTimePickerActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.DrawerActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2DrawerActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.ListItemViewActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2ListItemActivity" />
<activity
android:name="com.microsoft.fluentuidemo.demos.PeoplePickerViewActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:windowSoftInputMode="adjustResize" />
<activity android:name="com.microsoft.fluentuidemo.demos.PersistentBottomSheetActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2BottomSheetActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.PersonaChipViewActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2PersonaChipActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.PersonaListViewActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2PersonaListActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.PersonaViewActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2PersonaActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.PopupMenuActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.ProgressActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2ProgressActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.SnackbarActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2SegmentedControlActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.V2SearchBarActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:windowSoftInputMode="adjustResize" />
<activity android:name="com.microsoft.fluentuidemo.demos.TabLayoutActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.TemplateViewActivity" />
<activity android:name="com.microsoft.fluentuidemo.demos.TooltipActivity" />

Просмотреть файл

@ -9,42 +9,44 @@ import com.microsoft.fluentuidemo.demos.*
import java.util.*
import kotlin.reflect.KClass
const val V2AVATAR = "V2 Avatar"
const val V2AVATAR_CAROUSEL = "V2 Avatar Carousel"
const val V2AVATAR_GROUP = "V2 Avatar Group"
const val V2Badge = "V2 Badge"
const val V2BASIC_CONTROLS = "V2 Basic Controls"
const val V2BASIC_INPUTS = "V2 Basic Inputs"
const val V2BOTTOM_SHEET = "V2 BottomSheet"
const val V2CONTEXTUAL_COMMAND_BAR = "V2 ContextualCommandBar"
const val V2DRAWER = "V2 Drawer"
const val V2LIST_ITEM = "V2 ListItem"
const val V2PERSONA = "V2 Persona"
const val V2PERSONA_CHIP = "V2 PersonaChip"
const val V2PERSONA_LIST = "V2 PersonaList"
const val V2PROGRESS = "V2 Progress"
const val V2SEARCHBAR = "V2 SearchBar"
const val V2SEGMENTED_CONTROL = "V2 SegmentedControl"
const val V2TABBAR = "V2 TabBar"
const val ACTION_BAR_LAYOUT = "ActionBarLayout"
const val APP_BAR_LAYOUT = "AppBarLayout"
const val V2APP_BAR_LAYOUT = "V2 AppBarLayout"
const val AVATAR_VIEW = "AvatarView"
const val AVATAR_GROUP_VIEW = "AvatarGroupView"
const val BASIC_INPUTS = "Basic Inputs"
const val V2AVATAR = "V2 Avatar"
const val V2AVATAR_CAROUSEL = "V2 Avatar Carousel"
const val V2AVATAR_GROUP = "V2 Avatar Group"
const val V2BASIC_INPUTS = "V2 Basic Inputs"
const val V2BASIC_CONTROLS = "V2 Basic Controls"
const val BOTTOM_NAVIGATION = "BottomNavigation"
const val BOTTOM_SHEET = "BottomSheet"
const val CALENDAR_VIEW = "CalendarView"
const val CONTEXTUAL_COMMAND_BAR = "ContextualCommandBar"
const val V2CONTEXTUAL_COMMAND_BAR = "V2 ContextualCommandBar"
const val DATE_TIME_PICKER = "DateTimePicker"
const val DRAWER = "Drawer"
const val V2DRAWER = "V2 Drawer"
const val LIST_ITEM_VIEW = "ListItemView"
const val V2LIST_ITEM = "V2 ListItem"
const val PEOPLE_PICKER_VIEW = "PeoplePickerView"
const val PERSISTENT_BOTTOM_SHEET = "PersistentBottomSheet"
const val V2BOTTOM_SHEET = "V2 BottomSheet"
const val PERSONA_CHIP_VIEW = "PersonaChipView"
const val V2PERSONA_CHIP = "V2 PersonaChip"
const val PERSONA_LIST_VIEW = "PersonaListView"
const val V2PERSONA_LIST = "V2 PersonaList"
const val PERSONA_VIEW = "PersonaView"
const val V2PERSONA = "V2 Persona"
const val POPUP_MENU = "PopupMenu"
const val PROGRESS = "Progress"
const val V2PROGRESS = "V2 Progress"
const val SNACKBAR = "Snackbar"
const val V2SEGMENTED_CONTROL = "V2 SegmentedControl"
const val V2SEARCHBAR = "V2 SearchBar"
const val TAB_LAYOUT = "TabLayout"
const val TEMPLATE_VIEW = "TemplateView"
const val TOOLTIP = "Tooltip"
@ -55,6 +57,7 @@ val DEMOS = arrayListOf(
Demo(V2AVATAR, V2AvatarActivity::class),
Demo(V2AVATAR_CAROUSEL, V2AvatarCarouselActivity::class),
Demo(V2AVATAR_GROUP, V2AvatarGroupActivity::class),
Demo(V2Badge, V2BadgeActivity::class),
Demo(V2BASIC_INPUTS, V2BasicInputsActivity::class),
Demo(V2BASIC_CONTROLS, V2BasicControlsActivity::class),
Demo(V2BOTTOM_SHEET, V2BottomSheetActivity::class),
@ -67,6 +70,7 @@ val DEMOS = arrayListOf(
Demo(V2PROGRESS, V2ProgressActivity::class),
Demo(V2SEARCHBAR, V2SearchBarActivity::class),
Demo(V2SEGMENTED_CONTROL, V2SegmentedControlActivity::class),
Demo(V2TABBAR, V2TabBarActivity::class),
Demo(ACTION_BAR_LAYOUT, ActionBarLayoutActivity::class),
Demo(APP_BAR_LAYOUT, AppBarLayoutActivity::class),
Demo(AVATAR_VIEW, AvatarViewActivity::class),

Просмотреть файл

@ -0,0 +1,111 @@
package com.microsoft.fluentuidemo.demos
import android.os.Bundle
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.unit.dp
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.ThemeMode
import com.microsoft.fluentui.theme.token.AliasTokens
import com.microsoft.fluentui.theme.token.controlTokens.BadgeType
import com.microsoft.fluentui.tokenized.notification.Badge
import com.microsoft.fluentuidemo.DemoActivity
import com.microsoft.fluentuidemo.R
class V2BadgeActivity : DemoActivity() {
override val contentLayoutId: Int
get() = R.layout.v2_activity_compose
override val contentNeedsScrollableContainer: Boolean
get() = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val composeHere = findViewById<ComposeView>(R.id.compose_here)
composeHere.setContent {
FluentTheme {
val title1Font =
FluentTheme.aliasTokens.typography[AliasTokens.TypographyTokens.Title1]
val title2Font =
FluentTheme.aliasTokens.typography[AliasTokens.TypographyTokens.Title2]
Column(Modifier.background(Color.Gray)) {
Text(
text = resources.getString(R.string.badge_notification_badge),
fontWeight = title1Font.weight,
fontSize = title1Font.fontSize.size,
lineHeight = title1Font.fontSize.lineHeight,
color = FluentTheme.aliasTokens.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.Foreground1].value(),
modifier = Modifier.padding(8.dp)
)
Row(Modifier.padding(16.dp)) {
Text(
text = resources.getString(R.string.badge_notification_dot),
fontWeight = title2Font.weight,
fontSize = title2Font.fontSize.size,
lineHeight = title2Font.fontSize.lineHeight,
color = FluentTheme.aliasTokens.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.Foreground1].value()
)
Badge()
}
Row(Modifier.padding(16.dp)) {
Text(
text = resources.getString(R.string.badge_notification_character),
fontWeight = title2Font.weight,
fontSize = title2Font.fontSize.size,
lineHeight = title2Font.fontSize.lineHeight,
color = FluentTheme.aliasTokens.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.Foreground1].value()
)
Spacer(modifier = Modifier.width(8.dp))
Badge("1", badgeType = BadgeType.Character)
Spacer(modifier = Modifier.width(8.dp))
Badge("2", badgeType = BadgeType.Character)
Spacer(modifier = Modifier.width(8.dp))
Badge("8", badgeType = BadgeType.Character)
Spacer(modifier = Modifier.width(8.dp))
Badge("12", badgeType = BadgeType.Character)
Spacer(modifier = Modifier.width(8.dp))
Badge("123", badgeType = BadgeType.Character)
Spacer(modifier = Modifier.width(8.dp))
Badge("12345678910", badgeType = BadgeType.Character)
Spacer(modifier = Modifier.width(8.dp))
Badge("Badge", badgeType = BadgeType.Character)
}
Row(Modifier.padding(16.dp)) {
Text(
text = "List",
fontWeight = title2Font.weight,
fontSize = title2Font.fontSize.size,
lineHeight = title2Font.fontSize.lineHeight,
color = FluentTheme.aliasTokens.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.Foreground1].value(
themeMode = ThemeMode.Auto
)
)
Spacer(modifier = Modifier.width(8.dp))
Badge("1", badgeType = BadgeType.List)
Spacer(modifier = Modifier.width(8.dp))
Badge("2", badgeType = BadgeType.List)
Spacer(modifier = Modifier.width(8.dp))
Badge("8", badgeType = BadgeType.List)
Spacer(modifier = Modifier.width(8.dp))
Badge("12", badgeType = BadgeType.List)
Spacer(modifier = Modifier.width(8.dp))
Badge("123", badgeType = BadgeType.List)
Spacer(modifier = Modifier.width(8.dp))
Badge("12345678910", badgeType = BadgeType.List)
Spacer(modifier = Modifier.width(8.dp))
Badge("Badge", badgeType = BadgeType.List)
}
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,215 @@
package com.microsoft.fluentuidemo.demos
import android.content.Context
import android.os.Bundle
import android.widget.Toast
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.outlined.*
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.unit.dp
import com.microsoft.fluentui.theme.AppThemeController
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.ThemeMode
import com.microsoft.fluentui.theme.token.AliasTokens
import com.microsoft.fluentui.theme.token.controlTokens.BadgeType
import com.microsoft.fluentui.theme.token.controlTokens.ButtonSize
import com.microsoft.fluentui.theme.token.controlTokens.ButtonStyle
import com.microsoft.fluentui.theme.token.controlTokens.TabTextAlignment
import com.microsoft.fluentui.tokenized.controls.Button
import com.microsoft.fluentui.tokenized.controls.RadioButton
import com.microsoft.fluentui.tokenized.listitem.ListItem
import com.microsoft.fluentui.tokenized.navigation.TabBar
import com.microsoft.fluentui.tokenized.navigation.TabData
import com.microsoft.fluentui.tokenized.notification.Badge
import com.microsoft.fluentuidemo.DemoActivity
import com.microsoft.fluentuidemo.R
class V2TabBarActivity : DemoActivity() {
override val contentLayoutId: Int
get() = R.layout.v2_activity_compose
override val contentNeedsScrollableContainer: Boolean
get() = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val composeHere = findViewById<ComposeView>(R.id.compose_here)
val context = this
composeHere.setContent {
var selectedIndex by rememberSaveable { mutableStateOf(0) }
val tabDataList = arrayListOf(
TabData(
title = resources.getString(R.string.tabBar_home),
icon = Icons.Outlined.Home,
selectedIcon = Icons.Filled.Home,
onClick = {
invokeToast(resources.getString(R.string.tabBar_home), context)
Toast.makeText(context, "Home Tab Clicked", Toast.LENGTH_SHORT).show()
selectedIndex = 0
},
badge = { Badge() }
),
TabData(
title = resources.getString(R.string.tabBar_mail),
icon = Icons.Outlined.Email,
selectedIcon = Icons.Filled.Email,
onClick = {
invokeToast(resources.getString(R.string.tabBar_mail), context)
selectedIndex = 1
},
badge = { Badge("123+", badgeType = BadgeType.Character) }
),
TabData(
title = resources.getString(R.string.tabBar_settings),
icon = Icons.Outlined.Settings,
selectedIcon = Icons.Filled.Settings,
onClick = {
invokeToast(resources.getString(R.string.tabBar_settings), context)
selectedIndex = 2
}
),
TabData(
title = resources.getString(R.string.tabBar_notification),
icon = Icons.Outlined.Notifications,
selectedIcon = Icons.Filled.Notifications,
onClick = {
invokeToast(resources.getString(R.string.tabBar_notification), context)
selectedIndex = 3
},
badge = { Badge("10", badgeType = BadgeType.Character) }
),
TabData(
title = resources.getString(R.string.tabBar_more),
icon = Icons.Outlined.List,
selectedIcon = Icons.Filled.List,
onClick = {
invokeToast(resources.getString(R.string.tabBar_more), context)
selectedIndex = 4
},
badge = { Badge() }
)
)
FluentTheme {
val content = listOf(0, 1, 2)
var selectedOption by rememberSaveable { mutableStateOf(content[0]) }
var tabTextAlignment by rememberSaveable { mutableStateOf(TabTextAlignment.VERTICAL) }
var tabItemsCount by rememberSaveable { mutableStateOf(5) }
Column {
ListItem.Header(title = resources.getString(R.string.tabBar_text_alignment))
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(10.dp),
) {
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = resources.getString(R.string.tabBar_vertical),
modifier = Modifier.weight(1F),
color = AppThemeController.aliasTokens.value!!.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.Foreground1].value(
themeMode = ThemeMode.Auto
)
)
RadioButton(
selected = (selectedOption == content[0]),
onClick = {
selectedOption = content[0]
tabTextAlignment = TabTextAlignment.VERTICAL
}
)
}
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = resources.getString(R.string.tabBar_horizontal),
modifier = Modifier.weight(1F),
color = AppThemeController.aliasTokens.value!!.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.Foreground1].value(
themeMode = ThemeMode.Auto
)
)
RadioButton(
selected = (selectedOption == content[1]),
onClick = {
selectedOption = content[1]
tabTextAlignment = TabTextAlignment.HORIZONTAL
}
)
}
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = resources.getString(R.string.tabBar_no_text),
modifier = Modifier.weight(1F),
color = AppThemeController.aliasTokens.value!!.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.Foreground1].value(
themeMode = ThemeMode.Auto
)
)
RadioButton(
selected = (selectedOption == content[2]),
onClick = {
selectedOption = content[2]
tabTextAlignment = TabTextAlignment.NO_TEXT
}
)
}
}
ListItem.Header(title = resources.getString(R.string.tabBar_tab_items),
trailingAccessoryView =
{
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Button(
style = ButtonStyle.Button,
size = ButtonSize.Medium,
text = "+",
enabled = tabItemsCount < 5,
onClick = { tabItemsCount++ })
Button(
style = ButtonStyle.Button,
size = ButtonSize.Medium,
text = "-",
enabled = tabItemsCount > 1,
onClick = { tabItemsCount-- })
}
}
)
}
Column(verticalArrangement = Arrangement.Bottom) {
TabBar(
tabDataList = tabDataList.take(tabItemsCount),
selectedIndex = selectedIndex,
tabTextAlignment = tabTextAlignment
)
}
}
}
}
private fun invokeToast(string: String, context: Context) {
Toast.makeText(context, "$string Tab Clicked", Toast.LENGTH_SHORT).show()
}
}

Просмотреть файл

@ -101,6 +101,13 @@
<!-- UI label denoting the avatar view clicked action performed by the user at a specific index-->
<string name="avatar_group_avatar_clicked">AvatarView at index %d clicked</string>
<!--Badge-->
<!--UI Labels -->
<string name="badge_notification_badge">Notification Badge</string>
<string name="badge_notification_dot">Dot</string>
<string name="badge_notification_list">List</string>
<string name="badge_notification_character">Character</string>
<!--BottomNavigation-->
<!--UI Labels -->
<string name="bottom_navigation_menu_item_photos">Photos</string>
@ -643,6 +650,19 @@
<!-- UI Text denoting Danger style snackbar -->
<string name="snackbar_headline_danger_style">Danger style</string>
<!-- TabBar-->
<!-- UI labels -->
<string name="tabBar_home">Home</string>
<string name="tabBar_mail">Mail</string>
<string name="tabBar_settings">Settings</string>
<string name="tabBar_notification">Notification</string>
<string name="tabBar_more">More</string>
<string name="tabBar_text_alignment">Text Alignment</string>
<string name="tabBar_vertical">Vertical</string>
<string name="tabBar_horizontal">Horizontal</string>
<string name="tabBar_no_text">No Text</string>
<string name="tabBar_tab_items">Tab Items</string>
<!--TemplateView-->
<!-- UI labels and descriptions -->
<string name="cell_sample_title">Title</string>

Просмотреть файл

@ -37,6 +37,7 @@ dependencies {
api project(':fluentui_icons')
api project(':fluentui_listitem')
api project(':fluentui_menus')
api project(':fluentui_notification')
api project(':fluentui_others')
api project(':fluentui_peoplepicker')
api project(':fluentui_persona')

Просмотреть файл

@ -26,6 +26,7 @@ project.ext.fluentui_peoplepicker_versionid = '0.0.25'
project.ext.fluentui_persona_versionid = '0.1.4'
project.ext.fluentui_progress_versionid = '0.1.1'
project.ext.fluentui_icons_versionid = '0.1.2'
project.ext.fluentui_notification_versionid = '0.1.0'
project.ext.FluentUI_versionid = '0.1.15'
project.ext.fluentui_calendar_version_code = 25
project.ext.fluentui_controls_version_code = 8
@ -42,6 +43,7 @@ project.ext.fluentui_peoplepicker_version_code = 25
project.ext.fluentui_persona_version_code = 30
project.ext.fluentui_progress_version_code = 26
project.ext.fluentui_icons_version_code = 3
project.ext.fluentui_notification_version_code = 1
project.ext.FluentUI_version_code = 50
project.ext.license_type = 'MIT License'
project.ext.license_url = 'https://github.com/microsoft/fluentui-android/blob/master/LICENSE'

Просмотреть файл

@ -19,6 +19,7 @@ class ControlTokens {
Avatar,
AvatarCarousel,
AvatarGroup,
Badge,
BottomSheet,
Button,
CheckBox,
@ -38,6 +39,8 @@ class ControlTokens {
SearchBarPersonaChip,
SearchBar,
Shimmer,
TabBar,
TabBarTabItem,
TabItem,
ToggleSwitch
}
@ -49,6 +52,7 @@ class ControlTokens {
ControlType.Avatar -> AvatarTokens()
ControlType.AvatarCarousel -> AvatarCarouselTokens()
ControlType.AvatarGroup -> AvatarGroupTokens()
ControlType.Badge -> BadgeTokens()
ControlType.BottomSheet -> BottomSheetTokens()
ControlType.Button -> ButtonTokens()
ControlType.CheckBox -> CheckBoxTokens()
@ -68,6 +72,8 @@ class ControlTokens {
ControlType.SearchBarPersonaChip -> SearchBarPersonaChipTokens()
ControlType.SearchBar -> SearchBarTokens()
ControlType.Shimmer -> ShimmerTokens()
ControlType.TabBar -> TabBarTokens()
ControlType.TabBarTabItem -> TabBarTabItemsTokens()
ControlType.TabItem -> TabItemTokens()
ControlType.ToggleSwitch -> ToggleSwitchTokens()
}

Просмотреть файл

@ -0,0 +1,65 @@
package com.microsoft.fluentui.theme.token.controlTokens
import android.os.Parcelable
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.token.*
import kotlinx.parcelize.Parcelize
enum class BadgeType {
Character,
List
}
class BadgeInfo(val type: BadgeType) : ControlInfo
@Parcelize
open class BadgeTokens : ControlToken, Parcelable {
@Composable
open fun backgroundColor(badgeInfo: BadgeInfo): Color {
return FluentTheme.aliasTokens.errorAndStatusColor[AliasTokens.ErrorAndStatusColorTokens.DangerBackground2].value()
}
@Composable
open fun textColor(badgeInfo: BadgeInfo): Color {
return FluentTheme.aliasTokens.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.ForegroundLightStatic].value()
}
@Composable
open fun typography(badgeInfo: BadgeInfo): FontInfo {
return when (badgeInfo.type) {
BadgeType.Character -> FluentTheme.aliasTokens.typography[AliasTokens.TypographyTokens.Caption2]
BadgeType.List -> FluentTheme.aliasTokens.typography[AliasTokens.TypographyTokens.Caption1Strong]
}
}
@Composable
open fun padding(badgeInfo: BadgeInfo): PaddingValues {
return when (badgeInfo.type) {
BadgeType.Character -> PaddingValues(
horizontal = GlobalTokens.size(GlobalTokens.SizeTokens.Size60) + borderStroke(
badgeInfo
).width
)
BadgeType.List -> PaddingValues(
start = GlobalTokens.size(GlobalTokens.SizeTokens.Size80) + borderStroke(badgeInfo).width,
end = GlobalTokens.size(GlobalTokens.SizeTokens.Size80) + borderStroke(badgeInfo).width,
top = 3.dp + borderStroke(badgeInfo).width,
bottom = 3.dp + borderStroke(badgeInfo).width
)
}
}
@Composable
open fun borderStroke(badgeInfo: BadgeInfo): BorderStroke {
return BorderStroke(
GlobalTokens.strokeWidth(GlobalTokens.StrokeWidthTokens.StrokeWidth20),
FluentTheme.aliasTokens.neutralStrokeColor[AliasTokens.NeutralStrokeColorTokens.StrokeFocus1].value()
)
}
}

Просмотреть файл

@ -0,0 +1,33 @@
package com.microsoft.fluentui.theme.token.controlTokens
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.token.AliasTokens
import com.microsoft.fluentui.theme.token.StateColor
import kotlinx.parcelize.Parcelize
@Parcelize
open class TabBarTabItemsTokens : TabItemTokens() {
@Composable
override fun backgroundColor(tabItemInfo: TabItemInfo): Color {
return FluentTheme.aliasTokens.neutralBackgroundColor[AliasTokens.NeutralBackgroundColorTokens.Background1].value()
}
@Composable
override fun iconColor(tabItemInfo: TabItemInfo): StateColor {
return StateColor(
rest = FluentTheme.aliasTokens.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.Foreground2].value(),
selected = FluentTheme.aliasTokens.brandForegroundColor[AliasTokens.BrandForegroundColorTokens.BrandForeground1].value()
)
}
@Composable
override fun textColor(tabItemInfo: TabItemInfo): StateColor {
return StateColor(
rest = FluentTheme.aliasTokens.neutralForegroundColor[AliasTokens.NeutralForegroundColorTokens.Foreground2].value(),
selected = FluentTheme.aliasTokens.brandForegroundColor[AliasTokens.BrandForegroundColorTokens.BrandForeground1].value()
)
}
}

Просмотреть файл

@ -0,0 +1,28 @@
package com.microsoft.fluentui.theme.token.controlTokens
import android.os.Parcelable
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.token.AliasTokens
import com.microsoft.fluentui.theme.token.ControlInfo
import com.microsoft.fluentui.theme.token.ControlToken
import com.microsoft.fluentui.theme.token.GlobalTokens
import kotlinx.parcelize.Parcelize
class TabBarInfo : ControlInfo
@Parcelize
open class TabBarTokens : ControlToken, Parcelable {
@Composable
open fun topBorderColor(tabBarInfo: TabBarInfo): Color {
return FluentTheme.aliasTokens.neutralStrokeColor[AliasTokens.NeutralStrokeColorTokens.Stroke2].value()
}
@Composable
open fun topBorderWidth(tabBarInfo: TabBarInfo): Dp {
return GlobalTokens.strokeWidth(GlobalTokens.StrokeWidthTokens.StrokeWidth05)
}
}

Просмотреть файл

@ -30,7 +30,7 @@ open class TabItemTokens : ControlToken, Parcelable {
}
@Composable
open fun background(tabItemInfo: TabItemInfo): Color {
open fun backgroundColor(tabItemInfo: TabItemInfo): Color {
return FluentTheme.aliasTokens.neutralBackgroundColor[AliasTokens.NeutralBackgroundColorTokens.Background1].value(
FluentTheme.themeMode
)

Просмотреть файл

@ -59,7 +59,7 @@ dependencies {
implementation("androidx.compose.material:material:$composeVersion")
implementation("androidx.compose.runtime:runtime:$composeVersion")
implementation("androidx.compose.ui:ui:$composeVersion")
implementation "androidx.constraintlayout:constraintlayout-compose:$constraintLayoutComposeVersion"
}
task sourceJar(type: Jar) {

Просмотреть файл

@ -31,7 +31,7 @@ data class ItemData(
var enabled: Boolean = true,
var onClick: () -> Unit,
var accessory: @Composable (() -> Unit)? = null,
var icon: ImageVector? = null
var icon: ImageVector
)
// marker interface
@ -174,7 +174,7 @@ class ListContentBuilder {
Layout(
modifier = Modifier
.background(
token.background(
token.backgroundColor(
TabItemInfo(
TabTextAlignment.VERTICAL,
FluentStyle.Brand
@ -250,7 +250,7 @@ class ListContentBuilder {
LazyRow(
state = rowLazyListState, modifier = Modifier
.background(
token.background(
token.backgroundColor(
TabItemInfo(
TabTextAlignment.VERTICAL,
FluentStyle.Brand

Просмотреть файл

@ -786,7 +786,7 @@ object ListItem {
.focusable(false)
) {
Row(
modifier
Modifier
.fillMaxWidth()
.heightIn(min = cellHeight)
.background(backgroundColor)
@ -811,7 +811,7 @@ object ListItem {
if (accessoryTextTitle != null) {
Text(text = accessoryTextTitle,
modifier
Modifier
.padding(end = horizontalPadding, bottom = verticalPadding)
.clickable(
role = Role.Button,

Просмотреть файл

@ -14,9 +14,15 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ChainStyle
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.token.ControlTokens
import com.microsoft.fluentui.theme.token.FluentStyle
@ -39,13 +45,14 @@ fun getTabItemInfo(): TabItemInfo {
}
@Composable
internal fun TabItem(
fun TabItem(
title: String,
modifier: Modifier = Modifier,
icon: ImageVector? = null,
icon: ImageVector,
style: FluentStyle = FluentStyle.Neutral,
textAlignment: TabTextAlignment = TabTextAlignment.VERTICAL,
enabled: Boolean = true,
selected: Boolean = false,
fixedWidth: Boolean = false,
onClick: () -> Unit,
accessory: (@Composable () -> Unit)?,
@ -60,18 +67,20 @@ internal fun TabItem(
LocalTabItemTokens provides token,
LocalTabItemInfo provides TabItemInfo(textAlignment, style)
) {
val textColor = getTabItemTokens().textColor(tabItemInfo = getTabItemInfo()).getColorByState(
enabled = enabled,
selected = false,
interactionSource = interactionSource
)
val iconColor = getTabItemTokens().iconColor(tabItemInfo = getTabItemInfo()).getColorByState(
enabled = enabled,
selected = false,
interactionSource = interactionSource
)
val textColor =
getTabItemTokens().textColor(tabItemInfo = getTabItemInfo()).getColorByState(
enabled = enabled,
selected = selected,
interactionSource = interactionSource
)
val iconColor =
getTabItemTokens().iconColor(tabItemInfo = getTabItemInfo()).getColorByState(
enabled = enabled,
selected = selected,
interactionSource = interactionSource
)
val backgroundColor = getTabItemTokens().background(tabItemInfo = getTabItemInfo())
val backgroundColor = getTabItemTokens().backgroundColor(tabItemInfo = getTabItemInfo())
val rippleColor = getTabItemTokens().rippleColor(tabItemInfo = getTabItemInfo())
val clickableModifier = Modifier
@ -90,41 +99,115 @@ internal fun TabItem(
Modifier
}
val iconContent: @Composable () -> Unit = {
Box(
contentAlignment = Alignment.Center
) {
if (icon != null) {
Icon(
imageVector = icon,
modifier = Modifier.height(if (textAlignment == TabTextAlignment.NO_TEXT) 28.dp else 24.dp),
contentDescription = if (textAlignment == TabTextAlignment.NO_TEXT) title else null,
tint = iconColor
)
}
if (accessory != null) {
accessory()
}
}
Icon(
imageVector = icon,
modifier = Modifier.size(if (textAlignment == TabTextAlignment.NO_TEXT) 28.dp else 24.dp),
contentDescription = if (textAlignment == TabTextAlignment.NO_TEXT) title else null,
tint = iconColor
)
}
if (textAlignment == TabTextAlignment.HORIZONTAL) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
ConstraintLayout(
modifier = modifier
.then(clickableModifier)
.background(backgroundColor)
.padding(top = 8.dp, start = 4.dp, bottom = 4.dp, end = 8.dp)
.then(widthModifier)
) {
iconContent()
Spacer(modifier = Modifier.width(2.dp))
)
{
val (iconConstrain, textConstrain, badgeConstrain) = createRefs()
Box(modifier = Modifier.constrainAs(iconConstrain) {
start.linkTo(parent.start)
end.linkTo(textConstrain.start)
}
) {
iconContent()
}
Text(
text = title,
modifier = Modifier
.constrainAs(textConstrain) {
start.linkTo(iconConstrain.end)
end.linkTo(badgeConstrain.start)
width = Dimension.preferredWrapContent
}
.padding(start = 8.dp),
color = textColor,
textAlign = TextAlign.Justify
textAlign = TextAlign.Center,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
if (accessory != null) {
Box(modifier = Modifier
.constrainAs(badgeConstrain) {
start.linkTo(textConstrain.end)
end.linkTo(parent.end)
}
) {
accessory()
}
}
createHorizontalChain(
iconConstrain,
textConstrain,
badgeConstrain,
chainStyle = ChainStyle.Packed
)
}
} else {
val badgeWithIcon: @Composable () -> Unit = {
Layout(
{
Box(
modifier = Modifier.layoutId("anchor"),
contentAlignment = Alignment.Center
) {
iconContent()
}
Box(modifier = Modifier.layoutId("badge")) {
if (accessory != null)
accessory()
}
}
) { measurables, constraints ->
val badgePlaceable = measurables.first { it.layoutId == "badge" }.measure(
// Measure with loose constraints for height as we don't want the text to take up more
// space than it needs.
constraints.copy(minHeight = 0)
)
val anchorPlaceable =
measurables.first { it.layoutId == "anchor" }.measure(constraints)
// Use the width of the badge to infer whether it has any content (based on radius used
// in [Badge]) and determine its horizontal offset.
val hasContent = badgePlaceable.width > 16.dp.roundToPx()
val contentOffset = if (hasContent) -2.dp.roundToPx() else 0
val badgeHorizontalOffset = -anchorPlaceable.width / 2 + contentOffset
val badgeVerticalOffset = (-4).dp
val totalWidth = anchorPlaceable.width
val totalHeight = anchorPlaceable.height
layout(
totalWidth,
totalHeight
) {
anchorPlaceable.placeRelative(0, 0)
val badgeX = anchorPlaceable.width + badgeHorizontalOffset
val badgeY = badgeVerticalOffset.roundToPx()
badgePlaceable.placeRelative(badgeX, badgeY)
}
}
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
@ -134,7 +217,7 @@ internal fun TabItem(
.padding(top = 8.dp, start = 8.dp, bottom = 4.dp, end = 8.dp)
.then(widthModifier)
) {
iconContent()
badgeWithIcon()
if (textAlignment == TabTextAlignment.VERTICAL) {
Spacer(modifier = Modifier.height(2.dp))
Text(

1
fluentui_notification/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
/build

Просмотреть файл

@ -0,0 +1,71 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply from: '../config.gradle'
apply from: '../publish.gradle'
android {
compileSdkVersion constants.compileSdkVersion
defaultConfig {
minSdkVersion constants.minSdkVersion
targetSdkVersion constants.targetSdkVersion
versionCode project.ext.fluentui_notification_version_code
versionName project.ext.fluentui_notification_versionid
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
lintOptions {
abortOnError false
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
productFlavors {
}
kotlinOptions {
jvmTarget = '1.8'
useIR = true
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion composeVersion
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':fluentui_core')
implementation 'androidx.core:core-ktx:1.7.0'
implementation("androidx.compose.foundation:foundation:$composeVersion")
implementation("androidx.compose.material:material:$composeVersion")
implementation("androidx.compose.runtime:runtime:$composeVersion")
implementation("androidx.compose.ui:ui:$composeVersion")
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
task sourceJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier "sources"
}
project.afterEvaluate {
project.ext.publishingFunc('fluentui_notification')
}

Просмотреть файл

21
fluentui_notification/proguard-rules.pro поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) Microsoft Corporation. All rights reserved.
~ Licensed under the MIT License.
-->
<manifest
package="com.microsoft.fluentui.notification" />

Просмотреть файл

@ -0,0 +1,113 @@
package com.microsoft.fluentui.tokenized.notification
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.drawscope.Fill
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.PlatformTextStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.token.ControlTokens
import com.microsoft.fluentui.theme.token.controlTokens.BadgeInfo
import com.microsoft.fluentui.theme.token.controlTokens.BadgeTokens
import com.microsoft.fluentui.theme.token.controlTokens.BadgeType
import com.microsoft.fluentui.util.dpToPx
val LocalBadgeInfo = compositionLocalOf { BadgeInfo(BadgeType.Character) }
val LocalBadgeToken = compositionLocalOf { BadgeTokens() }
@Composable
fun getBadgeInfo(): BadgeInfo {
return LocalBadgeInfo.current
}
@Composable
fun getBadgeTokens(): BadgeTokens {
return LocalBadgeToken.current
}
@OptIn(ExperimentalTextApi::class)
@Composable
fun Badge(
text: String? = null,
modifier: Modifier = Modifier,
badgeType: BadgeType = BadgeType.List,
badgeTokens: BadgeTokens? = null
) {
val token = badgeTokens
?: FluentTheme.controlTokens.tokens[ControlTokens.ControlType.Badge] as BadgeTokens
CompositionLocalProvider(
LocalBadgeToken provides token,
LocalBadgeInfo provides BadgeInfo(badgeType)
) {
val background = getBadgeTokens().backgroundColor(badgeInfo = getBadgeInfo())
val borderStroke = getBadgeTokens().borderStroke(badgeInfo = getBadgeInfo())
if (text.isNullOrEmpty()) {
Box(
modifier = modifier
.defaultMinSize(16.dp, 16.dp)
) {
Canvas(
modifier = Modifier
.padding(start = 5.dp, end = 3.dp, top = 3.dp, bottom = 5.dp)
.sizeIn(minWidth = 8.dp, minHeight = 8.dp)
) {
drawCircle(
brush = borderStroke.brush,
radius = dpToPx(borderStroke.width + 4.dp)
)
drawCircle(
color = background,
style = Fill,
radius = dpToPx(4.dp)
)
}
}
} else {
val textColor = getBadgeTokens().textColor(badgeInfo = getBadgeInfo())
val typography = getBadgeTokens().typography(badgeInfo = getBadgeInfo())
val paddingValues = getBadgeTokens().padding(badgeInfo = getBadgeInfo())
Row(
modifier
.requiredHeight(if (badgeType == BadgeType.Character) 20.dp else 27.dp)
.border(borderStroke.width, borderStroke.brush, CircleShape)
.padding(0.5.dp) //TODO to check fix for https://issuetracker.google.com/issues/228985905
.background(background, CircleShape)
.clip(RoundedCornerShape(100.dp)),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
text,
modifier = Modifier.padding(paddingValues),
style = LocalTextStyle.current.merge(
TextStyle(
color = textColor,
lineHeight = typography.fontSize.lineHeight,
fontSize = typography.fontSize.size,
fontWeight = typography.weight,
platformStyle = PlatformTextStyle(
includeFontPadding = false
)
)
)
)
}
}
}
}

Просмотреть файл

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

Просмотреть файл

@ -45,6 +45,7 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':fluentui_core')
implementation project(':fluentui_icons')
implementation project(':fluentui_listitem')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "androidx.appcompat:appcompat:$appCompatVersion"
implementation "com.google.android.material:material:$materialVersion"

Просмотреть файл

@ -0,0 +1,85 @@
package com.microsoft.fluentui.tokenized.navigation
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.token.ControlTokens
import com.microsoft.fluentui.theme.token.controlTokens.*
import com.microsoft.fluentui.tokenized.tabItem.TabItem
data class TabData(
var title: String,
var icon: ImageVector,
var selectedIcon: ImageVector = icon,
var selected: Boolean = false,
var onClick: () -> Unit,
var badge: @Composable (() -> Unit)? = null
)
val LocalTabBarInfo = compositionLocalOf { TabBarInfo() }
val LocalTabBarToken = compositionLocalOf { TabBarTokens() }
@Composable
fun getTabBarInfo(): TabBarInfo {
return LocalTabBarInfo.current
}
@Composable
fun getTabBarToken(): TabBarTokens {
return LocalTabBarToken.current
}
@Composable
fun TabBar(
tabDataList: List<TabData>,
modifier: Modifier = Modifier,
selectedIndex: Int = 0,
tabTextAlignment: TabTextAlignment = TabTextAlignment.VERTICAL,
tabItemTokens: TabBarTabItemsTokens? = null,
tabBarTokens: TabBarTokens? = null
) {
val token = tabBarTokens
?: FluentTheme.controlTokens.tokens[ControlTokens.ControlType.TabBar] as TabBarTokens
CompositionLocalProvider(
LocalTabBarToken provides token
) {
Column {
Box(
modifier
.fillMaxWidth()
.height(getTabBarToken().topBorderWidth(tabBarInfo = getTabBarInfo()))
.background(color = getTabBarToken().topBorderColor(tabBarInfo = getTabBarInfo()))
)
Row(
modifier = modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
) {
tabDataList.forEachIndexed { index, tabData ->
tabData.selected = index == selectedIndex
TabItem(
title = tabData.title,
modifier = Modifier
.fillMaxWidth()
.weight(1F),
icon = if (tabData.selected) tabData.selectedIcon else tabData.icon,
textAlignment = tabTextAlignment,
selected = tabData.selected,
onClick = tabData.onClick,
accessory = tabData.badge,
tabItemTokens = tabItemTokens
?: FluentTheme.controlTokens.tokens[ControlTokens.ControlType.TabBarTabItem] as TabItemTokens
)
}
}
}
}
}

Просмотреть файл

@ -15,3 +15,4 @@ include ':FluentUI'
include ':fluentui_ccb'
include ':fluentui_controls'
include ':fluentui_icons'
include ':fluentui_notification'