Define composition locals for configuring color / font tokens specific to widget picker.
This is so, launcher can map it to existing resource tokens enabling launchers to easily override resources. Within picker module, we define a default implementation using material tokens that can be used as reference for which colors are ideal for specific picker tokens. Bug: 408283627 Flag: EXEMPT independent module Test: See demo Change-Id: I9c3a6118942114d5a8481f05a6710d8161d56bd7
This commit is contained in:
1 parent
9e604fbe6e
commit
7423dafef0
4 files changed
+412
No files matched your search
@@ -120,6 +120,23 @@ android_library {
|
||||
],
|
||||
}
|
||||
|
||||
android_library {
|
||||
name: "widget_picker_ui_theme",
|
||||
sdk_version: "current",
|
||||
min_sdk_version: min_launcher3_sdk_version,
|
||||
srcs: [
|
||||
"src/com/android/launcher3/widgetpicker/ui/theme/WidgetPickerTheme.kt",
|
||||
"src/com/android/launcher3/widgetpicker/ui/theme/WidgetPickerColors.kt",
|
||||
"src/com/android/launcher3/widgetpicker/ui/theme/WidgetPickerTextStyles.kt",
|
||||
],
|
||||
static_libs: [
|
||||
"androidx.compose.foundation_foundation",
|
||||
"androidx.compose.runtime_runtime",
|
||||
"androidx.compose.ui_ui",
|
||||
"androidx.compose.material3_material3",
|
||||
],
|
||||
}
|
||||
|
||||
android_library {
|
||||
name: "widget_picker_ui_components",
|
||||
sdk_version: "current",
|
||||
@@ -146,6 +163,7 @@ android_library {
|
||||
],
|
||||
static_libs: [
|
||||
"widget_picker_event_listeners",
|
||||
"widget_picker_ui_theme",
|
||||
"widget_picker_ui_data_types",
|
||||
"androidx.compose.foundation_foundation",
|
||||
"androidx.compose.foundation_foundation-layout",
|
||||
@@ -194,6 +212,7 @@ android_library {
|
||||
"src/com/android/launcher3/widgetpicker/ui/fullcatalog/screens/search/SearchScreenViewModel.kt",
|
||||
],
|
||||
static_libs: [
|
||||
"widget_picker_ui_theme",
|
||||
"widget_picker_ui_components",
|
||||
"widget_picker_event_listeners",
|
||||
"widget_picker_ui_data_types",
|
||||
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3.widgetpicker.ui.theme
|
||||
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
/**
|
||||
* Color tokens corresponding to specific UI elements in widget picker.
|
||||
*
|
||||
* @param sheetBackground background color of the widget picker bottom sheet.
|
||||
* @param dragHandle color of the drag handle shown in the widget picker bottom sheet.
|
||||
* @param sheetTitle color of the title of entire bottom sheet
|
||||
* @param sheetDescription color of long description displayed below the title of the bottom sheet.
|
||||
*
|
||||
* @param expandCollapseIndicatorIcon color of the expand collapse button shown in the expandable
|
||||
* list of apps in the single pane view of the widget picker.
|
||||
* @param expandCollapseIndicatorBackground background color shown below the
|
||||
* [expandCollapseIndicatorIcon]
|
||||
* @param expandableListItemsBackground background color of the expandable list of widget apps shown
|
||||
* in the single pane view of widget picker.
|
||||
* @param selectedListHeaderBackground background color of a widget app header that's selected
|
||||
* (in left pane of two pane picker view).
|
||||
* @param unselectedListHeaderBackground background color of a widget app headers that's not
|
||||
* selected (in left pane of two pane picker view).
|
||||
* @param widgetsContainerBackground background color of the container that displays widgets.
|
||||
* @param featuredHeaderLeadingIconBackground background color of the leading icon of the featured
|
||||
* widgets header (in left pane of two pane picker view).
|
||||
* @param featuredHeaderLeadingIcon color of the leading icon of the featured widgets header (in
|
||||
* left pane of two pane picker view).
|
||||
* @param listHeaderTitle color of the title text of widget app headers (in left pane of two pane
|
||||
* picker view).
|
||||
* @param listHeaderSubTitle color of the subtitle text of widget app headers (in left pane of two
|
||||
* pane picker view).
|
||||
*
|
||||
* @param placeholderAppIcon base color of the placeholder (without alpha) shown while app icon
|
||||
* isn't loaded yet.
|
||||
*
|
||||
* @param widgetLabel color of the text showing widget's label below its preview.
|
||||
* @param widgetSpanText color of text showing the dimensions of the widget.
|
||||
* @param widgetDescription color of the text showing the long description of the widget.
|
||||
* @param addButtonContent color of the text / icon shown within the add button shown for a widget.
|
||||
* @param addButtonBackground background color of the add button shown for a widget.
|
||||
*
|
||||
* @param widgetPlaceholderBackground background color of the placeholder shown while a widget's
|
||||
* preview isn't loaded yet.
|
||||
* @param widgetPlaceholderContent color of the content (e.g. loading spinner) shown over the
|
||||
* [widgetPlaceholderBackground]
|
||||
*
|
||||
* @param toolbarBackground color of the background of the floating toolbar that shows the tabs.
|
||||
* @param toolbarTabSelectedBackground background color of a selected tab (personal / work
|
||||
* / browse / featured) in a floating toolbar.
|
||||
* @param toolbarTabUnSelectedBackground background color of an unselected tab (personal / work
|
||||
* / browse / featured) in a floating toolbar.
|
||||
* @param toolbarTabContent color of the text and icons in a tab within a floating toolbar.
|
||||
*
|
||||
* @param searchBarBackground background color of the search bar.
|
||||
* @param searchBarPlaceholderText color of the placeholder text shown in the search bar.
|
||||
* @param searchBarText color of the text that use types in the search bar.
|
||||
* @param searchBarSearchIcon color of the search icon shown leading the text in search bar.
|
||||
* @param searchBarBackButtonIcon color of the icon in the back button shown in place of
|
||||
* [searchBarSearchIcon] when user is in search mode.
|
||||
* @param searchBarCloseButtonIcon color of close icon button shown trailing in the search bar when
|
||||
* user has typed some text.
|
||||
* @param searchBarCursor color of the cursor in the search bar
|
||||
*/
|
||||
data class WidgetPickerColors(
|
||||
// Titled bottom sheet
|
||||
val sheetBackground: Color,
|
||||
val dragHandle: Color,
|
||||
val sheetTitle: Color,
|
||||
val sheetDescription: Color,
|
||||
|
||||
// Expand collapse list
|
||||
val expandableListItemsBackground: Color,
|
||||
val selectedListHeaderBackground: Color,
|
||||
val unselectedListHeaderBackground: Color,
|
||||
val featuredHeaderLeadingIconBackground: Color,
|
||||
val featuredHeaderLeadingIcon: Color,
|
||||
val listHeaderTitle: Color,
|
||||
val listHeaderSubTitle: Color,
|
||||
// trailing indicator
|
||||
val expandCollapseIndicatorIcon: Color,
|
||||
val expandCollapseIndicatorBackground: Color,
|
||||
|
||||
// Widgets container
|
||||
val widgetsContainerBackground: Color,
|
||||
|
||||
// App icon
|
||||
val placeholderAppIcon: Color,
|
||||
|
||||
// Widget details
|
||||
val widgetLabel: Color,
|
||||
val widgetSpanText: Color,
|
||||
val widgetDescription: Color,
|
||||
val addButtonContent: Color,
|
||||
val addButtonBackground: Color,
|
||||
|
||||
// Widget preview
|
||||
val widgetPlaceholderBackground: Color,
|
||||
val widgetPlaceholderContent: Color,
|
||||
|
||||
// Floating toolbar
|
||||
val toolbarBackground: Color,
|
||||
val toolbarTabSelectedBackground: Color,
|
||||
val toolbarTabUnSelectedBackground: Color,
|
||||
val toolbarTabContent: Color,
|
||||
|
||||
// Search bar
|
||||
val searchBarBackground: Color,
|
||||
val searchBarPlaceholderText: Color,
|
||||
val searchBarText: Color,
|
||||
val searchBarSearchIcon: Color,
|
||||
val searchBarClearButtonIcon: Color,
|
||||
val searchBarBackButtonIcon: Color,
|
||||
val searchBarCursor: Color,
|
||||
)
|
||||
|
||||
/**
|
||||
* Composition local for [WidgetPickerColors].
|
||||
*
|
||||
* This is used by the [WidgetPickerTheme] to access [WidgetPickerColors] within a composable that's
|
||||
* part of the widget picker. It enables the host to map the widget picker colors different system
|
||||
* tokens than default.
|
||||
*/
|
||||
val LocalWidgetPickerColors = staticCompositionLocalOf<WidgetPickerColors> {
|
||||
throw IllegalStateException(
|
||||
"No WidgetPickerColors configured. Make sure to use WidgetPickerTheme in your top level "
|
||||
+ "Composable."
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Default colors that can either be used as is in host theme or used a reference to define your own
|
||||
* [LocalWidgetPickerColors].
|
||||
*/
|
||||
@Composable
|
||||
fun defaultWidgetPickerColors() =
|
||||
WidgetPickerColors(
|
||||
// Titled bottom sheet
|
||||
sheetBackground = MaterialTheme.colorScheme.surfaceContainer,
|
||||
dragHandle = MaterialTheme.colorScheme.outline,
|
||||
sheetTitle = MaterialTheme.colorScheme.onSurface,
|
||||
sheetDescription = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
|
||||
// Leading icon toolbar tab
|
||||
toolbarBackground = MaterialTheme.colorScheme.surfaceBright,
|
||||
toolbarTabSelectedBackground = MaterialTheme.colorScheme.secondaryContainer,
|
||||
toolbarTabUnSelectedBackground = Color.Transparent,
|
||||
toolbarTabContent = MaterialTheme.colorScheme.onSecondaryContainer,
|
||||
|
||||
// Expand collapse list
|
||||
expandableListItemsBackground = MaterialTheme.colorScheme.surfaceBright,
|
||||
selectedListHeaderBackground = MaterialTheme.colorScheme.secondaryContainer,
|
||||
unselectedListHeaderBackground = Color.Transparent,
|
||||
widgetsContainerBackground = MaterialTheme.colorScheme.surfaceBright,
|
||||
featuredHeaderLeadingIconBackground = MaterialTheme.colorScheme.surfaceBright,
|
||||
featuredHeaderLeadingIcon = MaterialTheme.colorScheme.primary,
|
||||
listHeaderTitle = MaterialTheme.colorScheme.onSurface,
|
||||
listHeaderSubTitle = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
// trailing indicator
|
||||
expandCollapseIndicatorIcon = MaterialTheme.colorScheme.onSecondaryContainer,
|
||||
expandCollapseIndicatorBackground = MaterialTheme.colorScheme.secondaryContainer,
|
||||
|
||||
// App icon
|
||||
placeholderAppIcon = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.2f),
|
||||
|
||||
// Widget details
|
||||
widgetLabel = MaterialTheme.colorScheme.onSurface,
|
||||
widgetSpanText = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
widgetDescription = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
addButtonBackground = MaterialTheme.colorScheme.primary,
|
||||
addButtonContent = MaterialTheme.colorScheme.onPrimary,
|
||||
|
||||
// Widget preview
|
||||
widgetPlaceholderBackground = MaterialTheme.colorScheme.secondaryContainer,
|
||||
widgetPlaceholderContent = MaterialTheme.colorScheme.onSecondaryContainer,
|
||||
|
||||
// Search bar
|
||||
searchBarBackground = MaterialTheme.colorScheme.surfaceBright,
|
||||
searchBarPlaceholderText = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
searchBarText = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
searchBarSearchIcon = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
searchBarBackButtonIcon = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
searchBarClearButtonIcon = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
searchBarCursor = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3.widgetpicker.ui.theme
|
||||
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
/**
|
||||
* [TextStyle]s for specific text elements within the widget picker.
|
||||
*
|
||||
* @param sheetTitle style for the title of entire bottom sheet
|
||||
* @param sheetDescription style for the long description displayed below the [sheetTitle].
|
||||
* @param selectedListHeaderTitle style for the label of widget app that's currently expanded /
|
||||
* selected in the list of widget apps.
|
||||
* @param unSelectedListHeaderTitle style for the label of widget's app that's currently collapsed /
|
||||
* not-selected in the list of widget apps.
|
||||
* @param selectedListHeaderSubTitle style for the sub-title text shown below the
|
||||
* [selectedListHeaderTitle] for the widget app that's currently expanded / selected in the list
|
||||
* of widget apps.
|
||||
* @param unSelectedListHeaderSubTitle style for the sub-title text shown below the
|
||||
* [unSelectedListHeaderTitle] for the widget app that's collapsed / un-selected in the list of
|
||||
* widget apps.
|
||||
* @param widgetLabel style for the text showing widget's label below its preview.
|
||||
* @param widgetSpanText style for the text showing the dimensions of the widget.
|
||||
* @param widgetDescription style for the text showing the long description of the widget.
|
||||
* @param addWidgetButtonLabel style for the "add" text on the button shown to add the widget.
|
||||
* @param toolbarTabLabel style for the text shown on each tab within the floating toolbar (e.g.
|
||||
* personal, work, browse, featured).
|
||||
* @param searchBarPlaceholderText style of the text shown as placeholder when user hasn't typed
|
||||
* anything in searchbar.
|
||||
* @param searchBarText style of the text that user types in the search bar.
|
||||
*/
|
||||
data class WidgetPickerTextStyles(
|
||||
// Titled bottom sheet
|
||||
val sheetTitle: TextStyle,
|
||||
val sheetDescription: TextStyle,
|
||||
|
||||
// Expandable list
|
||||
val selectedListHeaderTitle: TextStyle,
|
||||
val unSelectedListHeaderTitle: TextStyle,
|
||||
val selectedListHeaderSubTitle: TextStyle,
|
||||
val unSelectedListHeaderSubTitle: TextStyle,
|
||||
|
||||
// Widget details
|
||||
val widgetLabel: TextStyle,
|
||||
val widgetSpanText: TextStyle,
|
||||
val widgetDescription: TextStyle,
|
||||
val addWidgetButtonLabel: TextStyle,
|
||||
val toolbarTabLabel: TextStyle,
|
||||
|
||||
// Search bar
|
||||
val searchBarPlaceholderText: TextStyle,
|
||||
val searchBarText: TextStyle,
|
||||
)
|
||||
|
||||
/**
|
||||
* Composition local for [WidgetPickerTextStyles].
|
||||
*
|
||||
* This used by the [WidgetPickerTheme] to access [WidgetPickerTextStyles] within a composable
|
||||
* that's part of the widget picker. It enables the host to map the widget picker text styles
|
||||
* different values than the default.
|
||||
*/
|
||||
val LocalWidgetPickerTextStyles =
|
||||
staticCompositionLocalOf<WidgetPickerTextStyles> {
|
||||
throw IllegalStateException(
|
||||
"No WidgetPickerTextStyles configured. Make sure to use WidgetPickerTheme " +
|
||||
"in your top level Composable."
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Default [TextStyle]s that can either be used as-is in host theme or used a reference when
|
||||
* defining your own [LocalWidgetPickerTextStyles].
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun defaultWidgetPickerTextStyles() =
|
||||
WidgetPickerTextStyles(
|
||||
// Titled bottom sheet
|
||||
sheetTitle = MaterialTheme.typography.headlineSmallEmphasized,
|
||||
sheetDescription = MaterialTheme.typography.bodyMedium,
|
||||
|
||||
// Expandable list
|
||||
selectedListHeaderTitle =
|
||||
MaterialTheme.typography.titleMediumEmphasized.copy(fontWeight = FontWeight.Medium),
|
||||
unSelectedListHeaderTitle =
|
||||
MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Normal),
|
||||
selectedListHeaderSubTitle =
|
||||
MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.Medium),
|
||||
unSelectedListHeaderSubTitle =
|
||||
MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.Normal),
|
||||
|
||||
// Widget details
|
||||
widgetLabel = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.Medium),
|
||||
widgetSpanText = MaterialTheme.typography.labelLarge,
|
||||
widgetDescription = MaterialTheme.typography.labelMedium,
|
||||
addWidgetButtonLabel = MaterialTheme.typography.labelLarge,
|
||||
|
||||
// Floating toolbar
|
||||
toolbarTabLabel = MaterialTheme.typography.labelLarge,
|
||||
|
||||
// Search bar
|
||||
searchBarPlaceholderText =
|
||||
MaterialTheme.typography.bodyLarge.copy(
|
||||
fontSize = 20.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
),
|
||||
searchBarText =
|
||||
MaterialTheme.typography.bodyLarge.copy(
|
||||
fontSize = 20.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
),
|
||||
)
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3.widgetpicker.ui.theme
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
|
||||
/**
|
||||
* Custom theme providing tokens necessary for the widget picker UI.
|
||||
*
|
||||
* Provide this wrapping the compose view that hosts the widget picker.
|
||||
* Note: The app theme should be at top level prior to applying this theme.
|
||||
*/
|
||||
@Composable
|
||||
fun WidgetPickerTheme(
|
||||
colors: WidgetPickerColors = defaultWidgetPickerColors(),
|
||||
textStyles: WidgetPickerTextStyles = defaultWidgetPickerTextStyles(),
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalWidgetPickerColors provides colors,
|
||||
LocalWidgetPickerTextStyles provides textStyles,
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains functions to access the current theme values provided at the call site's position in the
|
||||
* hierarchy.
|
||||
*/
|
||||
object WidgetPickerTheme {
|
||||
/** Retrieves the current [WidgetPickerColors] at the call site's position in the hierarchy. */
|
||||
val colors: WidgetPickerColors
|
||||
@Composable @ReadOnlyComposable get() = LocalWidgetPickerColors.current
|
||||
|
||||
/**
|
||||
* Retrieves the current [WidgetPickerTextStyles] at the call site's position in the
|
||||
* hierarchy.
|
||||
*/
|
||||
val typography: WidgetPickerTextStyles
|
||||
@Composable @ReadOnlyComposable get() = LocalWidgetPickerTextStyles.current
|
||||
}
|
||||
Reference in new issue
Block a user