diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index fde75540..16873750 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -35,6 +35,9 @@ jobs: ./gradlew :miuix:dokkaGenerate mkdir -p ./docs/public/dokka mv ./miuix/build/dokka/html/* ./docs/public/dokka + ./gradlew :docs:demo:jsBrowserDistribution + mkdir -p ./docs/public/compose + mv ./miuix/docs/demo/build/dist/js/productionExecutable/* ./docs/public/compose cd ./docs yarn install yarn docs:build diff --git a/.gitignore b/.gitignore index 5d63d9d4..3d8005e3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ docs/node_modules docs/.vitepress/dist docs/.vitepress/cache docs/public/dokka +docs/public/compose diff --git a/docs/components/basiccomponent.md b/docs/components/basiccomponent.md index f032378b..a96c3078 100644 --- a/docs/components/basiccomponent.md +++ b/docs/components/basiccomponent.md @@ -4,6 +4,10 @@ This project builds upon it to provide some extended components, enabling developers to quickly create UI components that conform to design specifications. See the usage of [Extended Components](../components/#extended-components) for details. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/button.md b/docs/components/button.md index 3908a238..ea548669 100644 --- a/docs/components/button.md +++ b/docs/components/button.md @@ -2,6 +2,10 @@ `Button` is a basic interactive component in Miuix, used to trigger actions or events. It provides multiple style options, including primary buttons, secondary buttons, and text buttons. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/card.md b/docs/components/card.md index 61a073cc..fb15ab63 100644 --- a/docs/components/card.md +++ b/docs/components/card.md @@ -2,6 +2,10 @@ `Card` is a basic container component in Miuix, used to hold related content and actions. It provides a card container with Miuix style, suitable for scenarios such as information display and content grouping. Supports both static display and interactive modes. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/checkbox.md b/docs/components/checkbox.md index 5bfe69d1..4ea1ac6d 100644 --- a/docs/components/checkbox.md +++ b/docs/components/checkbox.md @@ -2,6 +2,10 @@ `CheckBox` is a basic selection component in Miuix, used for toggling between checked and unchecked states. It provides an interactive selection control with animation effects, suitable for multiple selection scenarios and enabling/disabling configuration items. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/colorpicker.md b/docs/components/colorpicker.md index a0a50bce..f04d97aa 100644 --- a/docs/components/colorpicker.md +++ b/docs/components/colorpicker.md @@ -2,6 +2,10 @@ `ColorPicker` is a color selection component in Miuix that allows users to pick colors by adjusting hue, saturation, brightness, and transparency. The component provides an intuitive slider interface with haptic feedback and real-time color preview. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/divider.md b/docs/components/divider.md index dbbf2e34..14797b50 100644 --- a/docs/components/divider.md +++ b/docs/components/divider.md @@ -2,6 +2,10 @@ `Divider` is a basic layout component in Miuix used to separate content in lists and layouts. It provides both horizontal and vertical divider styles. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/floatingactionbutton.md b/docs/components/floatingactionbutton.md index 76b0b39d..76e79eb1 100644 --- a/docs/components/floatingactionbutton.md +++ b/docs/components/floatingactionbutton.md @@ -4,6 +4,10 @@ This component is typically used in conjunction with the `Scaffold` component to maintain consistent layout and behavior across different pages in the application. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/floatingtoolbar.md b/docs/components/floatingtoolbar.md index ebded4a7..5284dc29 100644 --- a/docs/components/floatingtoolbar.md +++ b/docs/components/floatingtoolbar.md @@ -4,6 +4,10 @@ This component is usually used in conjunction with `Scaffold`, placed in a specific position on the page to provide quick actions or display information. +
+ +
+ ## Import ```kotlin @@ -18,7 +22,10 @@ import top.yukonga.miuix.kmp.basic.ToolbarPosition // Used for Scaffold Scaffold( floatingToolbar = { FloatingToolbar { - Row { // or Column + Row( + modifier = Modifier.padding(8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { // or Column IconButton(onClick = { /* Action 1 */ }) { Icon(MiuixIcons.Useful.Edit, contentDescription = "Edit") } @@ -70,7 +77,10 @@ FloatingToolbar( outSidePadding = PaddingValues(24.dp), showDivider = false ) { - Row(modifier = Modifier.padding(horizontal = 8.dp)) { + Row( + modifier = Modifier.padding(8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { // or Column IconButton(onClick = { /* Action 1 */ }) { Icon(MiuixIcons.Useful.Edit, contentDescription = "Edit", tint = MiuixTheme.colorScheme.onPrimaryContainer) } @@ -85,7 +95,10 @@ FloatingToolbar( ```kotlin FloatingToolbar { - Column(modifier = Modifier.padding(vertical = 8.dp)) { + Column( + modifier = Modifier.padding(vertical = 8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { IconButton(onClick = { /* Action 1 */ }) { Icon(MiuixIcons.Useful.Edit, contentDescription = "Edit") } diff --git a/docs/components/icon.md b/docs/components/icon.md index edc91afc..dcecb532 100644 --- a/docs/components/icon.md +++ b/docs/components/icon.md @@ -4,6 +4,10 @@ To follow night mode or theme changes, you need to actively use the `tint` property of the `Icon` component to set the icon color, commonly using `MiuixTheme.colorScheme.onBackground`. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/iconbutton.md b/docs/components/iconbutton.md index 8401a48e..e4b0f33c 100644 --- a/docs/components/iconbutton.md +++ b/docs/components/iconbutton.md @@ -2,6 +2,10 @@ `IconButton` is a button component in Miuix used for providing auxiliary interaction points. They are typically used in scenarios that require compact buttons, such as toolbars or image lists. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/listpopup.md b/docs/components/listpopup.md index 67966756..c3fb87a6 100644 --- a/docs/components/listpopup.md +++ b/docs/components/listpopup.md @@ -2,6 +2,10 @@ `ListPopup` is a popup list component in Miuix used to display a popup menu with multiple options. It provides a lightweight, floating temporary list suitable for various dropdown menus, context menus, and similar scenarios. +
+ +
+ ::: warning `ListPopup` must be used within a `Scaffold` component! ::: @@ -18,7 +22,7 @@ import top.yukonga.miuix.kmp.basic.ListPopupColumn The ListPopup component can be used to create simple dropdown menus: ```kotlin -var showPopup = remember { mutableStateOf(false) } +val showPopup = remember { mutableStateOf(false) } var selectedIndex by remember { mutableStateOf(0) } val items = listOf("Option 1", "Option 2", "Option 3") @@ -26,6 +30,7 @@ Scaffold { Box { TextButton( text = "Click to show menu", + alignment = PopupPositionProvider.Align.Left, onClick = { showPopup.value = true } ) ListPopup( diff --git a/docs/components/navigationbar.md b/docs/components/navigationbar.md index 0c8e42d0..19136a6c 100644 --- a/docs/components/navigationbar.md +++ b/docs/components/navigationbar.md @@ -6,6 +6,10 @@ These components are typically used in conjunction with the `Scaffold` component to maintain consistent layout and behavior across different pages in the application. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/progressindicator.md b/docs/components/progressindicator.md index 8a282eb0..f2a36bf6 100644 --- a/docs/components/progressindicator.md +++ b/docs/components/progressindicator.md @@ -2,6 +2,10 @@ `ProgressIndicator` is a progress indication component in Miuix used to display the progress status of operations. It provides three styles: linear progress bar, circular progress indicator, and infinite spinning indicator, suitable for different loading and progress display scenarios. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/pulltorefresh.md b/docs/components/pulltorefresh.md index ef0867a5..0015a13b 100644 --- a/docs/components/pulltorefresh.md +++ b/docs/components/pulltorefresh.md @@ -2,6 +2,12 @@ `PullToRefresh` is a pull-to-refresh component in Miuix that provides refresh functionality for lists and other scrollable content. It features an animated interactive refresh indicator suitable for various scenarios where data refresh is needed. +::: warning +This component is only available in touch-enabled scenes and does not work well in the Web build target! +::: + +For a demonstration, see the DropDown page of the Miuix Example. + ## Import ```kotlin diff --git a/docs/components/scaffold.md b/docs/components/scaffold.md index 3e7c3323..b4c1a336 100644 --- a/docs/components/scaffold.md +++ b/docs/components/scaffold.md @@ -2,6 +2,10 @@ `Scaffold` is a scaffolding component in Miuix used to implement basic design layout structures. It provides the fundamental framework for application interfaces, including containers for top bars, bottom bars, floating action buttons, and other elements. +
+ +
+ ::: warning The Scaffold component provides a suitable container for cross-platform popup windows. Components such as `SuperDialog`, `SuperDropdown`, `SuperSpinner`, and `ListPopup` are all implemented based on this and therefore need to be wrapped by this component. ::: diff --git a/docs/components/searchbar.md b/docs/components/searchbar.md index 3699fbcf..d68c07fb 100644 --- a/docs/components/searchbar.md +++ b/docs/components/searchbar.md @@ -2,6 +2,10 @@ `SearchBar` is a component in Miuix used for user search input. It provides an intuitive and easy-to-use search interface with support for expanded/collapsed state switching and search suggestions display. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/slider.md b/docs/components/slider.md index e7e29138..95068e73 100644 --- a/docs/components/slider.md +++ b/docs/components/slider.md @@ -2,6 +2,10 @@ `Slider` is a basic interactive component in Miuix used for selecting values within a continuous range. Users can adjust values by dragging the slider, making it suitable for scenarios such as volume adjustment, brightness control, and progress display. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/smalltitle.md b/docs/components/smalltitle.md index 77aeb23f..277e13a4 100644 --- a/docs/components/smalltitle.md +++ b/docs/components/smalltitle.md @@ -2,6 +2,10 @@ `SmallTitle` is a basic title component in Miuix used to create small-sized title text. It follows Miuix's design style with preset font size, weight, and padding. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/superarrow.md b/docs/components/superarrow.md index 5dfe6569..4fbbb41c 100644 --- a/docs/components/superarrow.md +++ b/docs/components/superarrow.md @@ -2,6 +2,10 @@ `SuperArrow` is a directional indicator component in Miuix, typically used for navigation or displaying additional content. It provides a title, summary, and right arrow icon with click interaction support, commonly used in settings, menu items, or list items. +
+ +
+ ## Import ```kotlin @@ -47,7 +51,7 @@ SuperArrow( SuperArrow supports controlling the hold-down state through the `holdDownState` parameter, typically used for visual feedback when displaying popup dialogs: ```kotlin -var showDialog = remember { mutableStateOf(false) } +val showDialog = remember { mutableStateOf(false) } Scaffold { SuperArrow( @@ -137,7 +141,7 @@ SuperArrow( ### Using with Dialog ```kotlin -var showDialog = remember { mutableStateOf(false) } +val showDialog = remember { mutableStateOf(false) } var language by remember { mutableStateOf("Simplified Chinese") } Scaffold { diff --git a/docs/components/supercheckbox.md b/docs/components/supercheckbox.md index 01738636..f22d4581 100644 --- a/docs/components/supercheckbox.md +++ b/docs/components/supercheckbox.md @@ -2,6 +2,10 @@ `SuperCheckbox` is a checkbox component in Miuix that provides a title, summary, and checkbox control. It supports click interactions and is commonly used in multi-select settings and selection lists. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/superdialog.md b/docs/components/superdialog.md index 07875f2d..9fb6e784 100644 --- a/docs/components/superdialog.md +++ b/docs/components/superdialog.md @@ -2,6 +2,10 @@ `SuperDialog` is a dialog component in Miuix used to display important information, collect user input, or confirm user actions. The dialog appears above the current interface and supports custom styles and content layouts. +
+ +
+ ::: warning `SuperDialog` must be used within a `Scaffold` component! ::: diff --git a/docs/components/superdropdown.md b/docs/components/superdropdown.md index e5b2bdcd..0da6f4ac 100644 --- a/docs/components/superdropdown.md +++ b/docs/components/superdropdown.md @@ -2,6 +2,10 @@ `SuperDropdown` is a dropdown menu component in Miuix that provides a title, summary, and a list of dropdown options. It supports click interaction and is commonly used in option settings and list selections. +
+ +
+ ::: warning `SuperDropdown` must be used within a `Scaffold` component! ::: diff --git a/docs/components/superspinner.md b/docs/components/superspinner.md index 2dc87cc0..4deecb2b 100644 --- a/docs/components/superspinner.md +++ b/docs/components/superspinner.md @@ -2,6 +2,10 @@ `SuperSpinner` is a dropdown selector component in Miuix that provides titles, summaries, and a list of options with icons and text. It supports click interaction and various display modes, commonly used in option settings with visual aids. This component is similar to `SuperDropdown` but offers richer functionality and interaction experience. +
+ +
+ ::: warning `SuperSpinner` must be used within a `Scaffold` component! ::: diff --git a/docs/components/superswitch.md b/docs/components/superswitch.md index 6ca0c31f..28af505d 100644 --- a/docs/components/superswitch.md +++ b/docs/components/superswitch.md @@ -2,6 +2,10 @@ `SuperSwitch` is a switch component in Miuix that provides a title, summary, and a switch control on the right. It supports click interaction and is commonly used in settings items and preference toggles. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/surface.md b/docs/components/surface.md index ab68dfce..226e977a 100644 --- a/docs/components/surface.md +++ b/docs/components/surface.md @@ -2,6 +2,10 @@ `Surface` is a foundational container component in Miuix, used to provide consistent background and border effects for application content, offering a unified visual foundation for interface elements. It supports simple custom styles. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/switch.md b/docs/components/switch.md index d2c6ac0a..a21c3f77 100644 --- a/docs/components/switch.md +++ b/docs/components/switch.md @@ -2,6 +2,10 @@ `Switch` is a basic toggle component in Miuix used to switch between two states. It provides an interactive switch control with animation effects, suitable for enabling and disabling settings. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/tabrow.md b/docs/components/tabrow.md index d5ba8846..51400125 100644 --- a/docs/components/tabrow.md +++ b/docs/components/tabrow.md @@ -2,6 +2,10 @@ `TabRow` is a navigation component in Miuix used to create horizontally scrollable tabs. It provides two variants: standard style and contour style, suitable for content categorization and navigation scenarios. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/text.md b/docs/components/text.md index ec97fe83..1fceaccd 100644 --- a/docs/components/text.md +++ b/docs/components/text.md @@ -2,6 +2,10 @@ `Text` component is a basic text component in Miuix, used to display text content. It supports customizing various text styles, alignment, and decoration effects. +
+ +
+ ## Import ```kotlin @@ -57,7 +61,7 @@ Text( Text( text = "Secondary Text", - color = MiuixTheme.colorScheme.onSurfaceVariant + color = MiuixTheme.colorScheme.onSurfaceContainerVariant ) ``` diff --git a/docs/components/textfield.md b/docs/components/textfield.md index dd0e2450..401ae8c0 100644 --- a/docs/components/textfield.md +++ b/docs/components/textfield.md @@ -2,6 +2,10 @@ `TextField` is a basic input component in Miuix for receiving text input from users. The component provides rich customization options, supporting label animations, leading and trailing icons, and other features. +
+ +
+ ## Import ```kotlin diff --git a/docs/components/topappbar.md b/docs/components/topappbar.md index 898f79b1..35c53a0e 100644 --- a/docs/components/topappbar.md +++ b/docs/components/topappbar.md @@ -4,6 +4,10 @@ This component is typically used in conjunction with the `Scaffold` component to maintain consistent layout and behavior across different pages in the application. +
+ +
+ ## Import ```kotlin @@ -47,7 +51,7 @@ Scaffold( largeTitle = "Large Title", // If not specified, title value will be used navigationIcon = { IconButton(onClick = { /* Handle click event */ }) { - Icon(MiuixIcons.Basic.ArrowLeft, contentDescription = "Back") + Icon(MiuixIcons.Useful.Back, contentDescription = "Back") } }, actions = { @@ -83,7 +87,7 @@ Scaffold( // If you want to add the overscroll effect, please add it before the scroll behavior .overScrollVertical() // Bind TopAppBar scroll behavior - .nestedScroll(topAppBarScrollBehavior.nestedScrollConnection), + .nestedScroll(scrollBehavior.nestedScrollConnection), contentPadding = PaddingValues(top = paddingValues.calculateTopPadding()) ) { // List content diff --git a/docs/demo/build.gradle.kts b/docs/demo/build.gradle.kts new file mode 100644 index 00000000..197f9bd0 --- /dev/null +++ b/docs/demo/build.gradle.kts @@ -0,0 +1,41 @@ +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension + +plugins { + alias(libs.plugins.compose.compiler) + alias(libs.plugins.jetbrains.compose) + alias(libs.plugins.kotlin.multiplatform) +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(21) +} + +kotlin { + jvmToolchain(21) + + js(IR) { + browser { + outputModuleName = "demo" + commonWebpackConfig { + outputFileName = "demo.js" + } + } + binaries.executable() + } + + sourceSets { + commonMain.dependencies { + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.ui) + implementation(compose.components.resources) + implementation("org.jetbrains.androidx.navigation:navigation-compose:2.9.0-beta01") + implementation(project(":miuix")) + } + } +} + +rootProject.plugins.withType { + rootProject.the().lockFileDirectory = rootProject.file("docs/demo").resolve("kotlin-js-store") +} diff --git a/docs/demo/src/commonMain/kotlin/BasicComponentDemo.kt b/docs/demo/src/commonMain/kotlin/BasicComponentDemo.kt new file mode 100644 index 00000000..38ff405e --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/BasicComponentDemo.kt @@ -0,0 +1,69 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.BasicComponent +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.Icon +import top.yukonga.miuix.kmp.icon.MiuixIcons +import top.yukonga.miuix.kmp.icon.icons.useful.Personal +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun BasicComponentDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Card { + BasicComponent( + title = "BasicComponent", + summary = "Without onClick" + ) + BasicComponent( + title = "Wi-Fi", + summary = "Connected to MIUI-WiFi", + onClick = { /* Handle click event */ } + ) + BasicComponent( + title = "Nickname", + summary = "A brief introduction", + leftAction = { + Icon( + modifier = Modifier.padding(end = 16.dp), + imageVector = MiuixIcons.Useful.Personal, + contentDescription = "Avatar Icon", + tint = MiuixTheme.colorScheme.onBackground + ) + }, + onClick = { /* Handle click event */ } + ) + BasicComponent( + title = "Mobile Network", + summary = "SIM card not inserted", + enabled = false + ) + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/ButtonDemo.kt b/docs/demo/src/commonMain/kotlin/ButtonDemo.kt new file mode 100644 index 00000000..20b13811 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/ButtonDemo.kt @@ -0,0 +1,112 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Button +import top.yukonga.miuix.kmp.basic.ButtonDefaults +import top.yukonga.miuix.kmp.basic.Icon +import top.yukonga.miuix.kmp.basic.Text +import top.yukonga.miuix.kmp.basic.TextButton +import top.yukonga.miuix.kmp.icon.MiuixIcons +import top.yukonga.miuix.kmp.icon.icons.useful.Like +import top.yukonga.miuix.kmp.icon.icons.useful.Personal +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun ButtonDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var buttonText1 by remember { mutableStateOf("Button") } + var buttonText2 by remember { mutableStateOf("TextButton") } + var clickCount1 by remember { mutableStateOf(0) } + var clickCount2 by remember { mutableStateOf(0) } + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + Button( + onClick = { + clickCount1++ + buttonText1 = "Button: $clickCount1" + } + ) { + Icon( + imageVector = MiuixIcons.Useful.Like, + contentDescription = null, + tint = Color.Unspecified, + modifier = Modifier.size(24.dp) + ) + Text( + text = buttonText1, + style = MiuixTheme.textStyles.button, + modifier = Modifier.padding(start = 8.dp) + ) + } + TextButton( + text = buttonText2, + onClick = { + clickCount2++ + buttonText2 = "TextButton: $clickCount2" + }, + colors = ButtonDefaults.textButtonColorsPrimary() + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + Button( + enabled = false, + onClick = {}, + colors = ButtonDefaults.buttonColorsPrimary() + ) { + Icon( + imageVector = MiuixIcons.Useful.Personal, + contentDescription = null, + tint = MiuixTheme.colorScheme.disabledOnSecondaryVariant, + modifier = Modifier.size(24.dp) + ) + Text( + text = "Disabled Button", + style = MiuixTheme.textStyles.button, + color = MiuixTheme.colorScheme.disabledOnSecondaryVariant, + modifier = Modifier.padding(start = 8.dp) + ) + } + TextButton( + text = "Disabled TextButton", + enabled = false, + onClick = {} + ) + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/CardDemo.kt b/docs/demo/src/commonMain/kotlin/CardDemo.kt new file mode 100644 index 00000000..f2c7706d --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/CardDemo.kt @@ -0,0 +1,106 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.Text +import top.yukonga.miuix.kmp.theme.MiuixTheme +import top.yukonga.miuix.kmp.utils.PressFeedbackType + +@Composable +fun CardDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 12.dp), + color = MiuixTheme.colorScheme.primaryVariant, + insideMargin = PaddingValues(16.dp), + ) { + Text( + color = MiuixTheme.colorScheme.onPrimary, + text = "Card", + fontSize = 19.sp, + fontWeight = FontWeight.SemiBold + ) + Text( + color = MiuixTheme.colorScheme.onPrimaryVariant, + text = "This is a Card", + fontSize = 17.sp, + fontWeight = FontWeight.Normal + ) + } + Row( + modifier = Modifier + .padding(horizontal = 12.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + Card( + modifier = Modifier.weight(1f), + insideMargin = PaddingValues(16.dp), + pressFeedbackType = PressFeedbackType.Sink, + showIndication = true, + onClick = { }, + content = { + Text( + color = MiuixTheme.colorScheme.onSurface, + text = "Card", + fontSize = 18.sp, + fontWeight = FontWeight.Medium + ) + Text( + color = MiuixTheme.colorScheme.onSurfaceVariantSummary, + text = "PressFeedback: Sink\nShowIndication: true", + style = MiuixTheme.textStyles.paragraph + ) + } + ) + Card( + modifier = Modifier.weight(1f), + insideMargin = PaddingValues(16.dp), + pressFeedbackType = PressFeedbackType.Tilt, + content = { + Text( + color = MiuixTheme.colorScheme.onSurface, + text = "Card", + fontSize = 18.sp, + fontWeight = FontWeight.Medium + ) + Text( + color = MiuixTheme.colorScheme.onSurfaceVariantSummary, + text = "PressFeedback: Tilt\nShowIndication: false", + style = MiuixTheme.textStyles.paragraph + ) + } + ) + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/CheckboxDemo.kt b/docs/demo/src/commonMain/kotlin/CheckboxDemo.kt new file mode 100644 index 00000000..f5a4fc4d --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/CheckboxDemo.kt @@ -0,0 +1,64 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Checkbox + +@Composable +fun CheckboxDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var checkbox1 by remember { mutableStateOf(false) } + var checkbox2 by remember { mutableStateOf(true) } + Row( + horizontalArrangement = Arrangement.spacedBy(32.dp), + ) { + Checkbox( + checked = checkbox1, + onCheckedChange = { checkbox1 = it } + ) + Checkbox( + checked = checkbox2, + onCheckedChange = { checkbox2 = it } + ) + Checkbox( + checked = false, + onCheckedChange = { }, + enabled = false + ) + Checkbox( + checked = true, + onCheckedChange = { }, + enabled = false + ) + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/ColorPickerDemo.kt b/docs/demo/src/commonMain/kotlin/ColorPickerDemo.kt new file mode 100644 index 00000000..8b22bf32 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/ColorPickerDemo.kt @@ -0,0 +1,48 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.ColorPicker +import top.yukonga.miuix.kmp.basic.SliderDefaults +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun ColorPickerDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + val miuixColor = MiuixTheme.colorScheme.primary + var selectedColor by remember { mutableStateOf(miuixColor) } + ColorPicker( + initialColor = selectedColor, + onColorChanged = { selectedColor = it }, + hapticEffect = SliderDefaults.SliderHapticEffect.Step + ) + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/Demo.kt b/docs/demo/src/commonMain/kotlin/Demo.kt new file mode 100644 index 00000000..0cd10926 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/Demo.kt @@ -0,0 +1,116 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import top.yukonga.miuix.kmp.basic.ButtonDefaults +import top.yukonga.miuix.kmp.basic.TextButton +import top.yukonga.miuix.kmp.theme.MiuixTheme +import top.yukonga.miuix.kmp.theme.darkColorScheme +import top.yukonga.miuix.kmp.theme.lightColorScheme + +@Composable +fun Demo(demoId: String? = null) { + MiuixTheme( + colors = if (isSystemInDarkTheme()) darkColorScheme() else lightColorScheme() + ) { + if (demoId == null) { + DemoSelection() + } else { + availableComponents.first { it.id == demoId }.demo() + } + } +} + +private data class AvailableComponent(val name: String, val id: String, val demo: @Composable () -> Unit) + +private val availableComponents = listOf( + AvailableComponent("Scaffold", "scaffold") { ScaffoldDemo() }, + AvailableComponent("Surface", "surface") { SurfaceDemo() }, + AvailableComponent("TopAppBar", "topAppBar") { TopAppBarDemo() }, + AvailableComponent("NavigationBar", "navigationBar") { NavigationBarDemo() }, + AvailableComponent("TabRow", "tabRow") { TabRowDemo() }, + AvailableComponent("Card", "card") { CardDemo() }, + AvailableComponent("BasicComponent", "basicComponent") { BasicComponentDemo() }, + AvailableComponent("Button", "button") { ButtonDemo() }, + AvailableComponent("IconButton", "iconButton") { IconButtonDemo() }, + AvailableComponent("Text", "text") { TextDemo() }, + AvailableComponent("SmallTitle", "smallTitle") { SmallTitleDemo() }, + AvailableComponent("TextField", "textField") { TextFieldDemo() }, + AvailableComponent("Switch", "switch") { SwitchDemo() }, + AvailableComponent("Checkbox", "checkbox") { CheckboxDemo() }, + AvailableComponent("Slider", "slider") { SliderDemo() }, + AvailableComponent("ProgressIndicator", "progressIndicator") { ProgressIndicatorDemo() }, + AvailableComponent("Icon", "icon") { IconDemo() }, + AvailableComponent("FloatingActionButton", "floatingActionButton") { FloatingActionButtonDemo() }, + AvailableComponent("FloatingToolbar", "floatingToolbar") { FloatingToolbarDemo() }, + AvailableComponent("Divider", "divider") { DividerDemo() }, + AvailableComponent("PullToRefresh", "pullToRefresh") { PullToRefreshDemo() }, + AvailableComponent("SearchBar", "searchBar") { SearchBarDemo() }, + AvailableComponent("ColorPicker", "colorPicker") { ColorPickerDemo() }, + AvailableComponent("ListPopup", "listPopup") { ListPopupDemo() }, + AvailableComponent("SuperArrow", "superArrow") { SuperArrowDemo() }, + AvailableComponent("SuperSwitch", "superSwitch") { SuperSwitchDemo() }, + AvailableComponent("SuperCheckbox", "superCheckbox") { SuperCheckboxDemo() }, + AvailableComponent("SuperDropdown", "superDropdown") { SuperDropdownDemo() }, + AvailableComponent("SuperSpinner", "superSpinner") { SuperSpinnerDemo() }, + AvailableComponent("SuperDialog", "superDialog") { SuperDialogDemo() }, +) + +@Composable +private fun DemoSelection() { + val navController = rememberNavController() + NavHost( + navController = navController, + startDestination = "home" + ) { + composable("home") { + Box( + modifier = Modifier + .fillMaxSize() + .background(MiuixTheme.colorScheme.background), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .verticalScroll(rememberScrollState()) + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + availableComponents.forEach { demo -> + TextButton( + text = demo.name, + onClick = { navController.navigate(demo.id) }, + modifier = Modifier.fillMaxWidth(), + colors = ButtonDefaults.textButtonColorsPrimary() + ) + } + } + } + } + + availableComponents.forEach { component -> + composable(component.id) { + Column { + component.demo() + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/DividerDemo.kt b/docs/demo/src/commonMain/kotlin/DividerDemo.kt new file mode 100644 index 00000000..61a50acc --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/DividerDemo.kt @@ -0,0 +1,88 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.HorizontalDivider +import top.yukonga.miuix.kmp.basic.Text +import top.yukonga.miuix.kmp.basic.VerticalDivider + +@Composable +fun DividerDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(32.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Card( + modifier = Modifier.weight(0.5f), + insideMargin = PaddingValues(16.dp) + ) { + Text( + text = "Content Above", + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center + ) + HorizontalDivider( + modifier = Modifier.padding(vertical = 8.dp), + ) + Text( + text = "Content Below", + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center + ) + } + Card( + modifier = Modifier.weight(0.5f), + insideMargin = PaddingValues(16.dp) + ) { + Row( + modifier = Modifier.height(IntrinsicSize.Min) + ) { + Text( + text = "Left Content", + modifier = Modifier.weight(1f), + textAlign = TextAlign.Center + ) + VerticalDivider( + modifier = Modifier.padding(horizontal = 8.dp), + ) + Text( + text = "Right Content", + modifier = Modifier.weight(1f), + textAlign = TextAlign.Center + ) + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/FloatingActionButtonDemo.kt b/docs/demo/src/commonMain/kotlin/FloatingActionButtonDemo.kt new file mode 100644 index 00000000..036925aa --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/FloatingActionButtonDemo.kt @@ -0,0 +1,108 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.FabPosition +import top.yukonga.miuix.kmp.basic.FloatingActionButton +import top.yukonga.miuix.kmp.basic.Icon +import top.yukonga.miuix.kmp.basic.Scaffold +import top.yukonga.miuix.kmp.extra.SuperArrow +import top.yukonga.miuix.kmp.icon.MiuixIcons +import top.yukonga.miuix.kmp.icon.icons.useful.SelectAll + +@Composable +fun FloatingActionButtonDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + Card( + modifier = Modifier.weight(0.5f) + ) { + Scaffold( + floatingActionButton = { + FloatingActionButton( + onClick = { + // Handle FAB click + } + ) { + Icon( + imageVector = MiuixIcons.Useful.SelectAll, + contentDescription = "SelectAll", + tint = Color.White + ) + } + } + ) { paddingValues -> + LazyColumn( + contentPadding = PaddingValues(top = paddingValues.calculateTopPadding()) + ) { + items(100) { + SuperArrow( + title = "Something" + ) + } + } + } + } + Card( + modifier = Modifier.weight(0.5f) + ) { + Scaffold( + floatingActionButton = { + FloatingActionButton( + onClick = { + // Handle FAB click + } + ) { + Icon( + imageVector = MiuixIcons.Useful.SelectAll, + contentDescription = "SelectAll", + tint = Color.White + ) + } + }, + floatingActionButtonPosition = FabPosition.Center + ) { paddingValues -> + LazyColumn( + contentPadding = PaddingValues(top = paddingValues.calculateTopPadding()) + ) { + items(100) { + SuperArrow( + title = "Something" + ) + } + } + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/FloatingToolbarDemo.kt b/docs/demo/src/commonMain/kotlin/FloatingToolbarDemo.kt new file mode 100644 index 00000000..095aff6e --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/FloatingToolbarDemo.kt @@ -0,0 +1,114 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.FloatingToolbar +import top.yukonga.miuix.kmp.basic.Icon +import top.yukonga.miuix.kmp.basic.IconButton +import top.yukonga.miuix.kmp.basic.Scaffold +import top.yukonga.miuix.kmp.basic.ToolbarPosition +import top.yukonga.miuix.kmp.extra.SuperArrow +import top.yukonga.miuix.kmp.icon.MiuixIcons +import top.yukonga.miuix.kmp.icon.icons.useful.Delete +import top.yukonga.miuix.kmp.icon.icons.useful.Edit + +@Composable +fun FloatingToolbarDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + Card( + modifier = Modifier.weight(0.5f) + ) { + Scaffold( + floatingToolbar = { + FloatingToolbar { + Row( + modifier = Modifier.padding(8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { // or Column + IconButton(onClick = { /* Action 1 */ }) { + Icon(MiuixIcons.Useful.Edit, contentDescription = "Edit") + } + IconButton(onClick = { /* Action 2 */ }) { + Icon(MiuixIcons.Useful.Delete, contentDescription = "Delete") + } + } + } + } + ) { paddingValues -> + LazyColumn( + contentPadding = PaddingValues(top = paddingValues.calculateTopPadding()) + ) { + items(100) { + SuperArrow( + title = "Something" + ) + } + } + } + } + Card( + modifier = Modifier.weight(0.5f) + ) { + Scaffold( + floatingToolbar = { + FloatingToolbar { + Row( + modifier = Modifier.padding(8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { // or Column + IconButton(onClick = { /* Action 1 */ }) { + Icon(MiuixIcons.Useful.Edit, contentDescription = "Edit") + } + IconButton(onClick = { /* Action 2 */ }) { + Icon(MiuixIcons.Useful.Delete, contentDescription = "Delete") + } + } + } + }, + floatingToolbarPosition = ToolbarPosition.BottomEnd + ) { paddingValues -> + LazyColumn( + contentPadding = PaddingValues(top = paddingValues.calculateTopPadding()) + ) { + items(100) { + SuperArrow( + title = "Something" + ) + } + } + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/IconButtonDemo.kt b/docs/demo/src/commonMain/kotlin/IconButtonDemo.kt new file mode 100644 index 00000000..216a46c9 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/IconButtonDemo.kt @@ -0,0 +1,92 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.Icon +import top.yukonga.miuix.kmp.basic.IconButton +import top.yukonga.miuix.kmp.icon.MiuixIcons +import top.yukonga.miuix.kmp.icon.icons.useful.ImmersionMore +import top.yukonga.miuix.kmp.icon.icons.useful.Like +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun IconButtonDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Card( + insideMargin = PaddingValues(16.dp) + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(32.dp), + ) { + IconButton( + modifier = Modifier, + onClick = {} + ) { + Icon( + imageVector = MiuixIcons.Useful.ImmersionMore, + tint = MiuixTheme.colorScheme.onBackground, + contentDescription = "More" + ) + } + IconButton( + modifier = Modifier, + onClick = {} + ) { + Icon( + imageVector = MiuixIcons.Useful.Like, + contentDescription = "Like" + ) + } + IconButton( + modifier = Modifier, + onClick = {}, + enabled = false + ) { + Icon( + imageVector = MiuixIcons.Useful.ImmersionMore, + tint = MiuixTheme.colorScheme.disabledOnSecondaryVariant, + contentDescription = "More" + ) + } + IconButton( + modifier = Modifier, + onClick = {}, + enabled = false + ) { + Icon( + imageVector = MiuixIcons.Useful.Like, + tint = MiuixTheme.colorScheme.disabledOnSecondaryVariant, + contentDescription = "Like" + ) + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/IconDemo.kt b/docs/demo/src/commonMain/kotlin/IconDemo.kt new file mode 100644 index 00000000..5cc635be --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/IconDemo.kt @@ -0,0 +1,72 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.Icon +import top.yukonga.miuix.kmp.icon.MiuixIcons +import top.yukonga.miuix.kmp.icon.icons.useful.Edit +import top.yukonga.miuix.kmp.icon.icons.useful.Personal +import top.yukonga.miuix.kmp.icon.icons.useful.Rename +import top.yukonga.miuix.kmp.icon.icons.useful.Settings +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun IconDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Card( + insideMargin = PaddingValues(16.dp) + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(32.dp), + ) { + Icon( + imageVector = MiuixIcons.Useful.Personal, + contentDescription = "Personal", + tint = MiuixTheme.colorScheme.onBackground + ) + Icon( + imageVector = MiuixIcons.Useful.Settings, + contentDescription = "Settings", + tint = MiuixTheme.colorScheme.onBackground + ) + Icon( + imageVector = MiuixIcons.Useful.Edit, + contentDescription = "Blue Edit", + tint = Color.Blue + ) + Icon( + imageVector = MiuixIcons.Useful.Rename, + contentDescription = "Green Rename", + tint = Color.Green + ) + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/ListPopupDemo.kt b/docs/demo/src/commonMain/kotlin/ListPopupDemo.kt new file mode 100644 index 00000000..aa35e0e0 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/ListPopupDemo.kt @@ -0,0 +1,68 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.ListPopup +import top.yukonga.miuix.kmp.basic.ListPopupColumn +import top.yukonga.miuix.kmp.basic.PopupPositionProvider +import top.yukonga.miuix.kmp.basic.Scaffold +import top.yukonga.miuix.kmp.basic.TextButton +import top.yukonga.miuix.kmp.extra.DropdownImpl + +@Composable +fun ListPopupDemo() { + Scaffold { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + val showPopup = remember { mutableStateOf(false) } + var selectedIndex by remember { mutableStateOf(0) } + val items = listOf("Option 1", "Option 2", "Option 3") + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.TopCenter + ) { + Box { + TextButton( + text = "Click to show menu", + onClick = { showPopup.value = true }, + modifier = Modifier.padding(top = 16.dp) + ) + ListPopup( + show = showPopup, + alignment = PopupPositionProvider.Align.Left, + onDismissRequest = { showPopup.value = false } // Close the popup menu + ) { + ListPopupColumn { + items.forEachIndexed { index, string -> + DropdownImpl( + text = string, + optionSize = items.size, + isSelected = selectedIndex == index, + onSelectedIndexChange = { + selectedIndex = index + showPopup.value = false // Close the popup menu + }, + index = index + ) + } + } + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/NavigationBarDemo.kt b/docs/demo/src/commonMain/kotlin/NavigationBarDemo.kt new file mode 100644 index 00000000..39fe2246 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/NavigationBarDemo.kt @@ -0,0 +1,114 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.FloatingNavigationBar +import top.yukonga.miuix.kmp.basic.FloatingNavigationBarMode +import top.yukonga.miuix.kmp.basic.NavigationBar +import top.yukonga.miuix.kmp.basic.NavigationItem +import top.yukonga.miuix.kmp.basic.Scaffold +import top.yukonga.miuix.kmp.basic.Text +import top.yukonga.miuix.kmp.icon.MiuixIcons +import top.yukonga.miuix.kmp.icon.icons.useful.NavigatorSwitch +import top.yukonga.miuix.kmp.icon.icons.useful.Personal +import top.yukonga.miuix.kmp.icon.icons.useful.Settings +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun NavigationBarDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + val pages = listOf("Home", "Profile", "Settings") + val items = listOf( + NavigationItem("Home", MiuixIcons.Useful.NavigatorSwitch), + NavigationItem("Profile", MiuixIcons.Useful.Personal), + NavigationItem("Settings", MiuixIcons.Useful.Settings) + ) + var selectedIndex1 by remember { mutableStateOf(0) } + var selectedIndex2 by remember { mutableStateOf(0) } + Card( + modifier = Modifier.weight(0.5f) + ) { + Scaffold( + bottomBar = { + NavigationBar( + items = items, + selected = selectedIndex1, + onClick = { selectedIndex1 = it } + ) + } + ) { paddingValues -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues), + contentAlignment = Alignment.Center + ) { + Text( + text = "Current: ${pages[selectedIndex1]}", + style = MiuixTheme.textStyles.title1 + ) + } + } + } + Card( + modifier = Modifier.weight(0.5f) + ) { + Scaffold( + bottomBar = { + FloatingNavigationBar( + items = items, + selected = selectedIndex2, + onClick = { selectedIndex2 = it }, + mode = FloatingNavigationBarMode.IconOnly // Show icons only + ) + } + ) { paddingValues -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues), + contentAlignment = Alignment.Center + ) { + Text( + text = "Current: ${pages[selectedIndex2]}", + style = MiuixTheme.textStyles.title1 + ) + } + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/ProgressIndicatorDemo.kt b/docs/demo/src/commonMain/kotlin/ProgressIndicatorDemo.kt new file mode 100644 index 00000000..070a345b --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/ProgressIndicatorDemo.kt @@ -0,0 +1,80 @@ +import androidx.compose.animation.core.RepeatMode +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.tween +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.CircularProgressIndicator +import top.yukonga.miuix.kmp.basic.InfiniteProgressIndicator +import top.yukonga.miuix.kmp.basic.LinearProgressIndicator + +@Composable +fun ProgressIndicatorDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + val progressValues = listOf(0.0f, 0.25f, 0.5f, 0.75f, 1.0f, null) + val animatedProgressValue by rememberInfiniteTransition().animateFloat( + initialValue = 0f, + targetValue = 1f, + animationSpec = infiniteRepeatable( + animation = tween(1000), + repeatMode = RepeatMode.Reverse + ) + ) + LinearProgressIndicator( + progress = animatedProgressValue, + modifier = Modifier + ) + progressValues.forEach { progressValue -> + LinearProgressIndicator( + progress = progressValue, + modifier = Modifier + ) + } + FlowRow( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly, + ) { + CircularProgressIndicator( + progress = animatedProgressValue + ) + progressValues.forEach { progressValue -> + CircularProgressIndicator( + progress = progressValue + ) + } + InfiniteProgressIndicator( + modifier = Modifier + .align(alignment = Alignment.CenterVertically) + ) + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/PullToRefreshDemo.kt b/docs/demo/src/commonMain/kotlin/PullToRefreshDemo.kt new file mode 100644 index 00000000..fb2ed2fc --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/PullToRefreshDemo.kt @@ -0,0 +1,79 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.delay +import top.yukonga.miuix.kmp.basic.BasicComponent +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.PullToRefresh +import top.yukonga.miuix.kmp.basic.rememberPullToRefreshState +import top.yukonga.miuix.kmp.utils.getWindowSize +import top.yukonga.miuix.kmp.utils.overScrollVertical + +@Composable +fun PullToRefreshDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + val pullToRefreshState = rememberPullToRefreshState() + + var ii by remember { mutableStateOf(1) } + + LaunchedEffect(pullToRefreshState.isRefreshing) { + if (pullToRefreshState.isRefreshing) { + delay(300) + pullToRefreshState.completeRefreshing { ii ++ } + } + } + + PullToRefresh( + pullToRefreshState = pullToRefreshState, + ) { + LazyColumn( + modifier = Modifier + .overScrollVertical() + .height(getWindowSize().height.dp), + overscrollEffect = null + ) { + item { + Card { + for (i in 0 until ii) { + BasicComponent( + title = "Component $i" + ) + } + } + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/ScaffoldDemo.kt b/docs/demo/src/commonMain/kotlin/ScaffoldDemo.kt new file mode 100644 index 00000000..d3583be7 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/ScaffoldDemo.kt @@ -0,0 +1,99 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.FloatingActionButton +import top.yukonga.miuix.kmp.basic.Icon +import top.yukonga.miuix.kmp.basic.NavigationBar +import top.yukonga.miuix.kmp.basic.NavigationItem +import top.yukonga.miuix.kmp.basic.Scaffold +import top.yukonga.miuix.kmp.basic.SmallTopAppBar +import top.yukonga.miuix.kmp.basic.Text +import top.yukonga.miuix.kmp.icon.MiuixIcons +import top.yukonga.miuix.kmp.icon.icons.useful.NavigatorSwitch +import top.yukonga.miuix.kmp.icon.icons.useful.Personal +import top.yukonga.miuix.kmp.icon.icons.useful.Settings +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun ScaffoldDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + val pages = listOf("Home", "Profile", "Settings") + val items = listOf( + NavigationItem("Home", MiuixIcons.Useful.NavigatorSwitch), + NavigationItem("Profile", MiuixIcons.Useful.Personal), + NavigationItem("Settings", MiuixIcons.Useful.Settings) + ) + var selectedIndex by remember { mutableStateOf(0) } + Card { + Scaffold( + topBar = { + SmallTopAppBar( + title = "SmallTopAppBar" + ) + }, + bottomBar = { + NavigationBar( + items = items, + selected = selectedIndex, + onClick = { selectedIndex = it } + ) + }, + floatingActionButton = { + FloatingActionButton( + onClick = { + // Handle FAB click + } + ) { + Icon( + imageVector = MiuixIcons.Useful.Personal, + contentDescription = "Personal", + tint = Color.White + ) + } + } + ) { paddingValues -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues), + contentAlignment = Alignment.Center + ) { + Text( + text = "Current: ${pages[selectedIndex]}", + style = MiuixTheme.textStyles.title1 + ) + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SearchBarDemo.kt b/docs/demo/src/commonMain/kotlin/SearchBarDemo.kt new file mode 100644 index 00000000..748f9d08 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SearchBarDemo.kt @@ -0,0 +1,93 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.BasicComponent +import top.yukonga.miuix.kmp.basic.BasicComponentDefaults +import top.yukonga.miuix.kmp.basic.InputField +import top.yukonga.miuix.kmp.basic.SearchBar +import top.yukonga.miuix.kmp.basic.Text +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun SearchBarDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var searchValue by remember { mutableStateOf("") } + var expanded by remember { mutableStateOf(false) } + SearchBar( + inputField = { + InputField( + query = searchValue, + onQueryChange = { searchValue = it }, + onSearch = { expanded = false }, + expanded = expanded, + onExpandedChange = { expanded = it }, + label = "Search" + ) + }, + outsideRightAction = { + Text( + modifier = Modifier + .clickable( + interactionSource = null, + indication = null + ) { + expanded = false + searchValue = "" + }, + text = "Cancel", + color = MiuixTheme.colorScheme.primary + ) + }, + expanded = expanded, + onExpandedChange = { expanded = it } + ) { + Column( + Modifier.fillMaxSize() + ) { + repeat(4) { idx -> + val resultText = "Suggestion $idx" + BasicComponent( + title = resultText, + titleColor = BasicComponentDefaults.titleColor(Color.White), + modifier = Modifier + .fillMaxWidth(), + onClick = { + searchValue = resultText + expanded = false + } + ) + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SliderDemo.kt b/docs/demo/src/commonMain/kotlin/SliderDemo.kt new file mode 100644 index 00000000..497127d6 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SliderDemo.kt @@ -0,0 +1,50 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Slider + +@Composable +fun SliderDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var slider1 by remember { mutableStateOf(0.5f) } + var slider2 by remember { mutableStateOf(0.7f) } + Slider( + progress = slider1, + onProgressChange = { slider1 = it } + ) + Slider( + progress = slider2, + onProgressChange = { slider2 = it }, + enabled = false + ) + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SmallTitleDemo.kt b/docs/demo/src/commonMain/kotlin/SmallTitleDemo.kt new file mode 100644 index 00000000..d38a3656 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SmallTitleDemo.kt @@ -0,0 +1,57 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.SmallTitle +import top.yukonga.miuix.kmp.basic.Surface +import top.yukonga.miuix.kmp.basic.Text + +@Composable +fun SmallTitleDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Card { + Surface { + Column { + SmallTitle( + text = "Small Title" + ) + Card( + modifier = Modifier + .padding(horizontal = 12.dp) + .padding(bottom = 12.dp), + insideMargin = PaddingValues(16.dp) + ) { + Text("This is a card with a Text inside it.") + } + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SuperArrowDemo.kt b/docs/demo/src/commonMain/kotlin/SuperArrowDemo.kt new file mode 100644 index 00000000..04dd8691 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SuperArrowDemo.kt @@ -0,0 +1,59 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.extra.SuperArrow + +@Composable +fun SuperArrowDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Card { + SuperArrow( + title = "Setting Item", + onClick = { /* Handle click event */ } + ) + SuperArrow( + title = "Wireless Network", + summary = "Connected to WIFI-HOME", + onClick = { /* Handle click event */ } + ) + SuperArrow( + title = "Disabled Item", + summary = "This item is currently unavailable", + enabled = false, + onClick = { /* Won't be triggered */ } + ) + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SuperCheckboxDemo.kt b/docs/demo/src/commonMain/kotlin/SuperCheckboxDemo.kt new file mode 100644 index 00000000..93f29817 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SuperCheckboxDemo.kt @@ -0,0 +1,72 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.extra.CheckboxLocation +import top.yukonga.miuix.kmp.extra.SuperCheckbox + +@Composable +fun SuperCheckboxDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var isChecked by remember { mutableStateOf(false) } + var rightChecked by remember { mutableStateOf(false) } + var notificationsEnabled by remember { mutableStateOf(false) } + + Card { + SuperCheckbox( + title = "Checkbox Option", + checked = isChecked, + onCheckedChange = { isChecked = it } + ) + SuperCheckbox( + title = "Notifications", + summary = "Receive push notifications from the app", + checked = notificationsEnabled, + onCheckedChange = { notificationsEnabled = it } + ) + SuperCheckbox( + title = "Right Checkbox", + summary = "Checkbox is on the right side", + checked = rightChecked, + onCheckedChange = { rightChecked = it }, + checkboxLocation = CheckboxLocation.Right + ) + SuperCheckbox( + title = "Disabled Checkbox", + summary = "This checkbox is currently unavailable", + checked = true, + onCheckedChange = {}, + enabled = false + ) + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SuperDialogDemo.kt b/docs/demo/src/commonMain/kotlin/SuperDialogDemo.kt new file mode 100644 index 00000000..d435aca6 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SuperDialogDemo.kt @@ -0,0 +1,61 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.Scaffold +import top.yukonga.miuix.kmp.basic.TextButton +import top.yukonga.miuix.kmp.extra.SuperDialog + +@Composable +fun SuperDialogDemo() { + Scaffold { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + val showDialog = remember { mutableStateOf(false) } + Card { + TextButton( + text = "Show a Dialog", + onClick = { showDialog.value = true } + ) + SuperDialog( + title = "Dialog Title", + summary = "This is a basic dialog example that can contain various content.", + show = showDialog, + onDismissRequest = { showDialog.value = false } // Close dialog + ) { + TextButton( + text = "Confirm", + onClick = { showDialog.value = false }, // Close dialog + modifier = Modifier.fillMaxWidth() + ) + } + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SuperDropdownDemo.kt b/docs/demo/src/commonMain/kotlin/SuperDropdownDemo.kt new file mode 100644 index 00000000..54d55c83 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SuperDropdownDemo.kt @@ -0,0 +1,81 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.Scaffold +import top.yukonga.miuix.kmp.extra.DropDownMode +import top.yukonga.miuix.kmp.extra.SuperDropdown + +@Composable +fun SuperDropdownDemo() { + Scaffold { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var selectedIndex1 by remember { mutableStateOf(0) } + val options1 = listOf("Option 1", "Option 2", "Option 3") + var selectedIndex2 by remember { mutableStateOf(0) } + val options2 = listOf("Chinese", "English", "Japanese") + var selectedIndex3 by remember { mutableStateOf(0) } + val options3 = listOf("Option 1", "Option 2", "Option 3") + + Card { + SuperDropdown( + title = "Dropdown Menu", + items = options1, + selectedIndex = selectedIndex1, + onSelectedIndexChange = { selectedIndex1 = it } + ) + SuperDropdown( + title = "Language Settings", + summary = "Choose your preferred language", + items = options2, + selectedIndex = selectedIndex2, + onSelectedIndexChange = { selectedIndex2 = it } + ) + SuperDropdown( + title = "Always on Right Mode", + items = options3, + selectedIndex = selectedIndex3, + onSelectedIndexChange = { selectedIndex3 = it }, + mode = DropDownMode.AlwaysOnRight + ) + SuperDropdown( + title = "Disabled Dropdown", + summary = "This dropdown menu is currently unavailable", + items = listOf("Option 1"), + selectedIndex = 0, + onSelectedIndexChange = {}, + enabled = false + ) + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SuperSpinnerDemo.kt b/docs/demo/src/commonMain/kotlin/SuperSpinnerDemo.kt new file mode 100644 index 00000000..29eb92d6 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SuperSpinnerDemo.kt @@ -0,0 +1,132 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.CornerRadius +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.Icon +import top.yukonga.miuix.kmp.basic.Scaffold +import top.yukonga.miuix.kmp.extra.SpinnerEntry +import top.yukonga.miuix.kmp.extra.SpinnerMode +import top.yukonga.miuix.kmp.extra.SuperSpinner + +@Composable +fun SuperSpinnerDemo() { + Scaffold { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var selectedIndex1 by remember { mutableStateOf(0) } + val options1 = listOf( + SpinnerEntry(title = "Option 1"), + SpinnerEntry(title = "Option 2"), + SpinnerEntry(title = "Option 3"), + ) + var selectedIndex2 by remember { mutableStateOf(0) } + val options2 = listOf( + SpinnerEntry( + icon = { Icon(RoundedRectanglePainter(), "Icon", Modifier.padding(end = 12.dp), Color(0xFFFF5B29)) }, + title = "Red Theme", + summary = "Vibrant red" + ), + SpinnerEntry( + icon = { Icon(RoundedRectanglePainter(), "Icon", Modifier.padding(end = 12.dp), Color(0xFF3482FF)) }, + title = "Blue Theme", + summary = "Calm blue" + ), + SpinnerEntry( + icon = { Icon(RoundedRectanglePainter(), "Icon", Modifier.padding(end = 12.dp), Color(0xFF36D167)) }, + title = "Green Theme", + summary = "Fresh green" + ), + SpinnerEntry( + icon = { Icon(RoundedRectanglePainter(), "Icon", Modifier.padding(end = 12.dp), Color(0xFFFFB21D)) }, + title = "Yellow Theme", + summary = "Bright yellow" + ) + ) + var selectedIndex3 by remember { mutableStateOf(0) } + val options3 = listOf( + SpinnerEntry(title = "Option 1"), + SpinnerEntry(title = "Option 2"), + SpinnerEntry(title = "Option 3") + ) + + Card { + SuperSpinner( + title = "Dropdown Selector", + items = options1, + selectedIndex = selectedIndex1, + onSelectedIndexChange = { selectedIndex1 = it } + ) + SuperSpinner( + title = "Function Selection", + summary = "Choose the action you want to perform", + items = options2, + selectedIndex = selectedIndex2, + onSelectedIndexChange = { selectedIndex2 = it } + ) + SuperSpinner( + title = "Always on Right Mode", + items = options3, + selectedIndex = selectedIndex3, + onSelectedIndexChange = { selectedIndex3 = it }, + mode = SpinnerMode.AlwaysOnRight // Always on right mode + ) + SuperSpinner( + title = "Disabled Selector", + summary = "This selector is currently unavailable", + items = listOf(SpinnerEntry(title = "Option 1")), + selectedIndex = 0, + onSelectedIndexChange = {}, + enabled = false + ) + } + } + } + } +} + +// Create a rounded rectangle Painter +class RoundedRectanglePainter( + private val cornerRadius: Dp = 6.dp +) : Painter() { + override val intrinsicSize = Size.Unspecified + + override fun DrawScope.onDraw() { + drawRoundRect( + color = Color.White, + size = Size(size.width, size.height), + cornerRadius = CornerRadius(cornerRadius.toPx(), cornerRadius.toPx()) + ) + } +} \ No newline at end of file diff --git a/docs/demo/src/commonMain/kotlin/SuperSwitchDemo.kt b/docs/demo/src/commonMain/kotlin/SuperSwitchDemo.kt new file mode 100644 index 00000000..3f7228c7 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SuperSwitchDemo.kt @@ -0,0 +1,65 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.extra.SuperSwitch + +@Composable +fun SuperSwitchDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var isChecked by remember { mutableStateOf(false) } + var wifiEnabled by remember { mutableStateOf(false) } + + Card( + modifier = Modifier.weight(0.5f) + ) { + SuperSwitch( + title = "Switch Option", + checked = isChecked, + onCheckedChange = { isChecked = it } + ) + SuperSwitch( + title = "WiFi", + summary = "Turn on to connect to wireless networks", + checked = wifiEnabled, + onCheckedChange = { wifiEnabled = it } + ) + SuperSwitch( + title = "Disabled Switch", + summary = "This switch is currently unavailable", + checked = true, + onCheckedChange = {}, + enabled = false + ) + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SurfaceDemo.kt b/docs/demo/src/commonMain/kotlin/SurfaceDemo.kt new file mode 100644 index 00000000..810c2373 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SurfaceDemo.kt @@ -0,0 +1,58 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Surface +import top.yukonga.miuix.kmp.basic.Text +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun SurfaceDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Surface( + modifier = Modifier + .size(height = 200.dp, width = 400.dp) + .padding(16.dp), + color = MiuixTheme.colorScheme.background, + shape = RoundedCornerShape(16.dp), + shadowElevation = 4.dp + ) { + Text( + text = "Surface Example\n\n" + + "Size: height = 200.dp, width = 400.dp\n" + + "color: MiuixTheme.colorScheme.background\n" + + "shape: RoundedCornerShape(16.dp)\n" + + "shadowElevation: 4.dp\n" + + "isSystemInDarkTheme: ${isSystemInDarkTheme()}", + modifier = Modifier.padding(16.dp).fillMaxSize() + ) + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/SwitchDemo.kt b/docs/demo/src/commonMain/kotlin/SwitchDemo.kt new file mode 100644 index 00000000..a7222248 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/SwitchDemo.kt @@ -0,0 +1,64 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Switch + +@Composable +fun SwitchDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var switch1 by remember { mutableStateOf(false) } + var switch2 by remember { mutableStateOf(true) } + Row( + horizontalArrangement = Arrangement.spacedBy(32.dp), + ) { + Switch( + checked = switch1, + onCheckedChange = { switch1 = it } + ) + Switch( + checked = switch2, + onCheckedChange = { switch2 = it } + ) + Switch( + checked = false, + onCheckedChange = { }, + enabled = false + ) + Switch( + checked = true, + onCheckedChange = { }, + enabled = false + ) + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/TabRowDemo.kt b/docs/demo/src/commonMain/kotlin/TabRowDemo.kt new file mode 100644 index 00000000..aee995b1 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/TabRowDemo.kt @@ -0,0 +1,56 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.TabRow +import top.yukonga.miuix.kmp.basic.TabRowWithContour + +@Composable +fun TabRowDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + val tabs1 = listOf("Recommended", "Following", "Popular", "Featured") + var selectedTabIndex1 by remember { mutableStateOf(0) } + + TabRow( + tabs = tabs1, + selectedTabIndex = selectedTabIndex1, + onTabSelected = { selectedTabIndex1 = it } + ) + val tabs2 = listOf("All", "Photos", "Videos", "Documents") + var selectedTabIndex2 by remember { mutableStateOf(0) } + + TabRowWithContour( + tabs = tabs2, + selectedTabIndex = selectedTabIndex2, + onTabSelected = { selectedTabIndex2 = it } + ) + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/TextDemo.kt b/docs/demo/src/commonMain/kotlin/TextDemo.kt new file mode 100644 index 00000000..11e89657 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/TextDemo.kt @@ -0,0 +1,86 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.Text +import top.yukonga.miuix.kmp.theme.MiuixTheme + +@Composable +fun TextDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Card( + modifier = Modifier.weight(0.5f), + insideMargin = PaddingValues(16.dp) + ) { + Text( + text = "Title Text", + style = MiuixTheme.textStyles.headline1, + modifier = Modifier.padding(bottom = 16.dp) + ) + Text( + text = "Subtitle Text", + style = MiuixTheme.textStyles.subtitle, + modifier = Modifier.padding(bottom = 16.dp) + ) + Text( + text = "Summary Text", + style = MiuixTheme.textStyles.body2, + modifier = Modifier.padding(bottom = 16.dp) + ) + Text( + text = "Main Text", + style = MiuixTheme.textStyles.main, + modifier = Modifier.padding(bottom = 16.dp) + ) + Text( + text = "Primary Color Text", + color = MiuixTheme.colorScheme.primary, + modifier = Modifier.padding(bottom = 16.dp) + ) + Text( + text = "Secondary Text", + color = MiuixTheme.colorScheme.onSurfaceContainerVariant + ) + } + Card( + modifier = Modifier.weight(0.5f), + insideMargin = PaddingValues(16.dp) + ) { + Text( + text = "Early in the day it was whispered that we should sail in a boat, only thou and I, and never a soul in the world would know of this our pilgrimage to no country and to no end." + ) + } + } + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/TextFieldDemo.kt b/docs/demo/src/commonMain/kotlin/TextFieldDemo.kt new file mode 100644 index 00000000..1dcefe11 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/TextFieldDemo.kt @@ -0,0 +1,67 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.TextField + +@Composable +fun TextFieldDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + var text1 by remember { mutableStateOf("") } + var text2 by remember { mutableStateOf("") } + var text3 by remember { mutableStateOf("This is read-only content") } + + TextField( + value = text1, + onValueChange = { text1 = it }, + label = "Username" + ) + + TextField( + value = text2, + onValueChange = { text2 = it }, + label = "Please enter content", + useLabelAsPlaceholder = true + ) + TextField( + value = "", + onValueChange = { }, + label = "Disabled Input Field", + enabled = false + ) + TextField( + value = text3, + onValueChange = { text3 = it }, + label = "Read-Only Input Field", + readOnly = true + ) + } + } +} diff --git a/docs/demo/src/commonMain/kotlin/TopAppBarDemo.kt b/docs/demo/src/commonMain/kotlin/TopAppBarDemo.kt new file mode 100644 index 00000000..71f96eb1 --- /dev/null +++ b/docs/demo/src/commonMain/kotlin/TopAppBarDemo.kt @@ -0,0 +1,163 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.unit.dp +import top.yukonga.miuix.kmp.basic.Card +import top.yukonga.miuix.kmp.basic.Icon +import top.yukonga.miuix.kmp.basic.IconButton +import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior +import top.yukonga.miuix.kmp.basic.Scaffold +import top.yukonga.miuix.kmp.basic.SmallTopAppBar +import top.yukonga.miuix.kmp.basic.TopAppBar +import top.yukonga.miuix.kmp.extra.SuperArrow +import top.yukonga.miuix.kmp.icon.MiuixIcons +import top.yukonga.miuix.kmp.icon.icons.useful.Back +import top.yukonga.miuix.kmp.icon.icons.useful.More + +@Composable +fun TopAppBarDemo() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient(listOf(Color(0xfff77062), Color(0xfffe5196)))), + contentAlignment = Alignment.Center + ) { + Column( + Modifier + .padding(16.dp) + .widthIn(max = 600.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + Card( + modifier = Modifier.weight(0.5f) + ) { + val scrollBehavior = MiuixScrollBehavior() + Scaffold( + topBar = { + TopAppBar( + title = "Title", + largeTitle = "Large Title", // If not specified, title value will be used + scrollBehavior = scrollBehavior, + navigationIcon = { + IconButton( + onClick = { /* Handle click event */ }, + modifier = Modifier.padding(start = 16.dp) + ) { + Icon( + MiuixIcons.Useful.Back, + contentDescription = "Back" + ) + } + }, + actions = { + IconButton( + onClick = { /* Handle click event */ }, + modifier = Modifier.padding(end = 16.dp) + ) { + Icon( + MiuixIcons.Useful.More, + contentDescription = "More" + ) + } + } + ) + } + ) { paddingValues -> + LazyColumn( + modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), + contentPadding = PaddingValues(top = paddingValues.calculateTopPadding()) + ) { + item { + Spacer(Modifier.height(8.dp)) + } + items(100) { + Card( + modifier = Modifier + .padding(horizontal = 16.dp) + .padding(bottom = 8.dp) + ) { + SuperArrow( + title = "Something" + ) + } + } + } + } + } + Card( + modifier = Modifier.weight(0.5f) + ) { + Scaffold( + topBar = { + SmallTopAppBar( + title = "Title", + navigationIcon = { + IconButton( + onClick = { /* Handle click event */ }, + modifier = Modifier.padding(start = 16.dp) + ) { + Icon( + MiuixIcons.Useful.Back, + contentDescription = "Back" + ) + } + }, + actions = { + IconButton( + onClick = { /* Handle click event */ }, + modifier = Modifier.padding(end = 16.dp) + ) { + Icon( + MiuixIcons.Useful.More, + contentDescription = "More" + ) + } + } + ) + } + ) { paddingValues -> + LazyColumn( + contentPadding = PaddingValues(top = paddingValues.calculateTopPadding()) + ) { + item { + Spacer(Modifier.height(8.dp)) + } + items(100) { + Card( + modifier = Modifier + .padding(horizontal = 16.dp) + .padding(bottom = 8.dp) + ) { + SuperArrow( + title = "Something" + ) + } + } + } + } + } + } + } + } +} diff --git a/docs/demo/src/jsMain/kotlin/Main.js.kt b/docs/demo/src/jsMain/kotlin/Main.js.kt new file mode 100644 index 00000000..89fd8b3d --- /dev/null +++ b/docs/demo/src/jsMain/kotlin/Main.js.kt @@ -0,0 +1,16 @@ +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.window.CanvasBasedWindow +import kotlinx.browser.document +import org.jetbrains.skiko.wasm.onWasmReady +import org.w3c.dom.url.URLSearchParams + +@OptIn(ExperimentalComposeUiApi::class) +fun main() { + val iFrameParams = URLSearchParams(document.location?.search) + val id = iFrameParams.get("id") + onWasmReady { + CanvasBasedWindow(canvasElementId = "ComposeTarget") { + Demo(demoId = id) + } + } +} \ No newline at end of file diff --git a/docs/demo/src/jsMain/resources/index.html b/docs/demo/src/jsMain/resources/index.html new file mode 100644 index 00000000..f8f3d6d9 --- /dev/null +++ b/docs/demo/src/jsMain/resources/index.html @@ -0,0 +1,40 @@ + + + + + + Demo + + + + + + + + + + \ No newline at end of file diff --git a/docs/package.json b/docs/package.json index a468091c..7bf451ea 100644 --- a/docs/package.json +++ b/docs/package.json @@ -2,7 +2,7 @@ "license": "Apache-2.0", "devDependencies": { "vitepress": "^1.6.3", - "vue": "^3.5.13" + "vue": "^3.5.16" }, "scripts": { "docs:dev": "vitepress dev --host", @@ -12,5 +12,8 @@ "dependencies": { "medium-zoom": "^1.1.0" }, + "resolutions": { + "vite": "npm:rolldown-vite@latest" + }, "type": "module" -} +} \ No newline at end of file diff --git a/docs/zh_CN/components/basiccomponent.md b/docs/zh_CN/components/basiccomponent.md index 58f043c4..bff8d0d1 100644 --- a/docs/zh_CN/components/basiccomponent.md +++ b/docs/zh_CN/components/basiccomponent.md @@ -4,6 +4,10 @@ 本项目以此为基础提供了一些扩展组件,方便开发者快速构建符合设计规范的 UI 组件,详见[扩展组件](../components/#扩展组件)的使用。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/button.md b/docs/zh_CN/components/button.md index 6365713f..b6ee9344 100644 --- a/docs/zh_CN/components/button.md +++ b/docs/zh_CN/components/button.md @@ -2,6 +2,10 @@ `Button` 是 Miuix 中的基础交互组件,用于触发操作或事件。提供了多种风格选择,包括主要按钮、次要按钮和文本按钮。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/card.md b/docs/zh_CN/components/card.md index 6f2e8657..ff415e3c 100644 --- a/docs/zh_CN/components/card.md +++ b/docs/zh_CN/components/card.md @@ -2,6 +2,10 @@ `Card` 是 Miuix 中的基础容器组件,用于承载相关内容和操作。它提供了具有 Miuix 风格的卡片容器,适用于信息展示、内容分组等场景。支持静态显示和交互式两种模式。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/checkbox.md b/docs/zh_CN/components/checkbox.md index e203cbe4..2d9835cb 100644 --- a/docs/zh_CN/components/checkbox.md +++ b/docs/zh_CN/components/checkbox.md @@ -2,6 +2,10 @@ `CheckBox` 是 Miuix 中的基础选择组件,用于在选中与未选中状态间切换。它提供了具有动画效果的交互式选择控件,适用于多选场景和配置项的启用与禁用。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/colorpicker.md b/docs/zh_CN/components/colorpicker.md index 41d506ef..4150777e 100644 --- a/docs/zh_CN/components/colorpicker.md +++ b/docs/zh_CN/components/colorpicker.md @@ -2,6 +2,10 @@ `ColorPicker` 是 Miuix 中的颜色选择组件,允许用户通过调整色相、饱和度、明度和透明度来选择颜色。组件提供了直观的滑块界面,支持触觉反馈和实时颜色预览。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/divider.md b/docs/zh_CN/components/divider.md index 0845b3e9..0f4f2531 100644 --- a/docs/zh_CN/components/divider.md +++ b/docs/zh_CN/components/divider.md @@ -2,6 +2,10 @@ `Divider` 是 Miuix 中的基础布局组件,用于在列表和布局中分隔内容。提供了水平分割线和垂直分割线两种形式。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/floatingactionbutton.md b/docs/zh_CN/components/floatingactionbutton.md index 3e0d3aa3..a64395f6 100644 --- a/docs/zh_CN/components/floatingactionbutton.md +++ b/docs/zh_CN/components/floatingactionbutton.md @@ -4,6 +4,10 @@ 此组件通常与 `Scaffold` 组件结合使用,以便在应用程序的不同页面中保持一致的布局和行为。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/floatingtoolbar.md b/docs/zh_CN/components/floatingtoolbar.md index 9ef28c9b..f9e51dfc 100644 --- a/docs/zh_CN/components/floatingtoolbar.md +++ b/docs/zh_CN/components/floatingtoolbar.md @@ -4,6 +4,10 @@ 此组件通常与 `Scaffold` 结合使用,放置在页面的特定位置,提供快捷操作或信息展示。 +
+ +
+ ## 引入 ```kotlin @@ -18,7 +22,10 @@ import top.yukonga.miuix.kmp.basic.ToolbarPosition // 用于 Scaffold Scaffold( floatingToolbar = { FloatingToolbar { - Row { // 或 Column + Row( + modifier = Modifier.padding(8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { // 或 Column IconButton(onClick = { /* 操作 1 */ }) { Icon(MiuixIcons.Useful.Edit, contentDescription = "编辑") } @@ -70,7 +77,10 @@ FloatingToolbar( outSidePadding = PaddingValues(24.dp), showDivider = false ) { - Row(modifier = Modifier.padding(horizontal = 8.dp)) { + Row( + modifier = Modifier.padding(8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { // 或 Column IconButton(onClick = { /* 操作 1 */ }) { Icon(MiuixIcons.Useful.Edit, contentDescription = "编辑", tint = MiuixTheme.colorScheme.onPrimaryContainer) } @@ -85,7 +95,10 @@ FloatingToolbar( ```kotlin FloatingToolbar { - Column(modifier = Modifier.padding(vertical = 8.dp)) { + Column( + modifier = Modifier.padding(vertical = 8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { IconButton(onClick = { /* 操作 1 */ }) { Icon(MiuixIcons.Useful.Edit, contentDescription = "编辑") } diff --git a/docs/zh_CN/components/icon.md b/docs/zh_CN/components/icon.md index 2f6df3e1..8369a072 100644 --- a/docs/zh_CN/components/icon.md +++ b/docs/zh_CN/components/icon.md @@ -4,6 +4,10 @@ 如果要跟随夜间模式或主题变化,需主动使用 `Icon` 组件的 `tint` 属性来设置图标的颜色,常用颜色为 `MiuixTheme.colorScheme.onBackground`。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/iconbutton.md b/docs/zh_CN/components/iconbutton.md index ce88e03d..387b40fc 100644 --- a/docs/zh_CN/components/iconbutton.md +++ b/docs/zh_CN/components/iconbutton.md @@ -2,6 +2,10 @@ `IconButton` 是 Miuix 中的图标按钮组件,用于提供辅助操作的交互点。它们通常用于需要紧凑按钮的场景,如工具栏或图片列表中。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/listpopup.md b/docs/zh_CN/components/listpopup.md index 36f9dbc9..e2e13314 100644 --- a/docs/zh_CN/components/listpopup.md +++ b/docs/zh_CN/components/listpopup.md @@ -2,6 +2,10 @@ `ListPopup` 是 Miuix 中的弹出列表组件,用于显示一个包含多个选项的弹出菜单。它提供了一个轻量级的、悬浮在界面上的临时列表,适用于各种下拉菜单、上下文菜单等场景。 +
+ +
+ ::: warning 注意 `ListPopup` 需要在 `Scaffold` 组件内使用! ::: @@ -18,7 +22,7 @@ import top.yukonga.miuix.kmp.basic.ListPopupColumn ListPopup 组件可以用于创建简单的下拉菜单: ```kotlin -var showPopup = remember { mutableStateOf(false) } +val showPopup = remember { mutableStateOf(false) } var selectedIndex by remember { mutableStateOf(0) } val items = listOf("选项 1", "选项 2", "选项 3") @@ -30,6 +34,7 @@ Scaffold { ) ListPopup( show = showPopup, + alignment = PopupPositionProvider.Align.Left, onDismissRequest = { showPopup.value = false } // 关闭弹出菜单 ) { ListPopupColumn { diff --git a/docs/zh_CN/components/navigationbar.md b/docs/zh_CN/components/navigationbar.md index eb2d04ad..0b73b5f0 100644 --- a/docs/zh_CN/components/navigationbar.md +++ b/docs/zh_CN/components/navigationbar.md @@ -6,6 +6,10 @@ 这些组件通常与 `Scaffold` 组件结合使用,以便在应用程序的不同页面中保持一致的布局和行为。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/progressindicator.md b/docs/zh_CN/components/progressindicator.md index 94694394..0f65fce2 100644 --- a/docs/zh_CN/components/progressindicator.md +++ b/docs/zh_CN/components/progressindicator.md @@ -2,6 +2,10 @@ `ProgressIndicator` 是 Miuix 中的进度指示组件,用于展示操作的进度状态。提供了线性进度条、环形进度条和无限旋转指示器三种样式,适用于不同场景下的加载和进度展示需求。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/pulltorefresh.md b/docs/zh_CN/components/pulltorefresh.md index 2965552b..4a930de5 100644 --- a/docs/zh_CN/components/pulltorefresh.md +++ b/docs/zh_CN/components/pulltorefresh.md @@ -2,6 +2,12 @@ `PullToRefresh` 是 Miuix 中的下拉刷新组件,可为列表和其他可滚动内容提供刷新功能。它提供了具有动画效果的交互式刷新指示器,适用于需要刷新数据的各种场景。 +::: warning 注意 +该组件只适用于支持触控的场景,并且在网页构建目标中工作不佳! +::: + +如需演示,请查看 Miuix Example 的 DropDown 页。 + ## 引入 ```kotlin diff --git a/docs/zh_CN/components/scaffold.md b/docs/zh_CN/components/scaffold.md index e0e14aba..5891dd1b 100644 --- a/docs/zh_CN/components/scaffold.md +++ b/docs/zh_CN/components/scaffold.md @@ -2,6 +2,10 @@ `Scaffold` 是 Miuix 中的脚手架组件,用于实现基本设计视觉布局结构。它提供了应用程序界面的基本框架,包括顶部栏、底部栏、悬浮按钮等元素的容器。 +
+ +
+ ::: warning 注意 Scaffold 组件为跨平台提供了一个合适的弹出窗口的容器。`SuperDialog`、`SuperDropdown`、`SuperSpinner`、`ListPopup` 等组件都基于此实现弹出窗口,因此都需要被该组件包裹。 ::: diff --git a/docs/zh_CN/components/searchbar.md b/docs/zh_CN/components/searchbar.md index 927cee88..ea5df711 100644 --- a/docs/zh_CN/components/searchbar.md +++ b/docs/zh_CN/components/searchbar.md @@ -2,6 +2,10 @@ `SearchBar` 是 Miuix 中用于用户输入搜索内容的组件。它提供了一个直观且易用的搜索界面,支持展开/收起状态切换以及搜索建议展示。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/slider.md b/docs/zh_CN/components/slider.md index 88823dfc..57193346 100644 --- a/docs/zh_CN/components/slider.md +++ b/docs/zh_CN/components/slider.md @@ -2,6 +2,10 @@ `Slider` 是 Miuix 中的基础交互组件,用于在连续的数值范围内进行选择。用户可以通过拖动滑块来调整值,适用于诸如音量调节、亮度控制、进度显示等场景。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/smalltitle.md b/docs/zh_CN/components/smalltitle.md index 83efde4e..0c6cc21d 100644 --- a/docs/zh_CN/components/smalltitle.md +++ b/docs/zh_CN/components/smalltitle.md @@ -2,6 +2,10 @@ `SmallTitle` 是 Miuix 中的基础小标题组件,用于快速创建小型标题文本。采用 Miuix 的设计风格,具有预设的字体大小、字重和内边距。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/superarrow.md b/docs/zh_CN/components/superarrow.md index 3dd98fe0..81968e2f 100644 --- a/docs/zh_CN/components/superarrow.md +++ b/docs/zh_CN/components/superarrow.md @@ -2,6 +2,10 @@ `SuperArrow` 是 Miuix 中的箭头指示组件,通常用于导航或展示更多内容。提供了标题、摘要和右侧箭头图标,支持点击交互,常用于设置项、菜单项或列表项中。 +
+ +
+ ## 引入 ```kotlin @@ -47,7 +51,7 @@ SuperArrow( SuperArrow 支持通过 `holdDownState` 参数控制按下状态,通常用于显示弹出对话框时的视觉反馈: ```kotlin -var showDialog = remember { mutableStateOf(false) } +val showDialog = remember { mutableStateOf(false) } Scaffold { SuperArrow( @@ -137,7 +141,7 @@ SuperArrow( ### 结合对话框使用 ```kotlin -var showDialog = remember { mutableStateOf(false) } +val showDialog = remember { mutableStateOf(false) } var language by remember { mutableStateOf("简体中文") } Scaffold { diff --git a/docs/zh_CN/components/supercheckbox.md b/docs/zh_CN/components/supercheckbox.md index ab0005bf..e76bd778 100644 --- a/docs/zh_CN/components/supercheckbox.md +++ b/docs/zh_CN/components/supercheckbox.md @@ -2,6 +2,10 @@ `SuperCheckbox` 是 Miuix 中的复选框组件,提供了标题、摘要和复选框控件,支持点击交互,常用于多选项设置和选择列表中。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/superdialog.md b/docs/zh_CN/components/superdialog.md index 7ead3165..6aba3059 100644 --- a/docs/zh_CN/components/superdialog.md +++ b/docs/zh_CN/components/superdialog.md @@ -2,6 +2,10 @@ `SuperDialog` 是 Miuix 中的对话框组件,用于显示重要信息、收集用户输入或确认用户操作。对话框会在当前界面上层显示,并支持自定义样式和内容布局。 +
+ +
+ ::: warning 注意 `SuperDialog` 需要在 `Scaffold` 组件内使用! ::: diff --git a/docs/zh_CN/components/superdropdown.md b/docs/zh_CN/components/superdropdown.md index d5437a03..90bb26c3 100644 --- a/docs/zh_CN/components/superdropdown.md +++ b/docs/zh_CN/components/superdropdown.md @@ -2,6 +2,10 @@ `SuperDropdown` 是 Miuix 中的下拉菜单组件,提供了标题、摘要和下拉选项列表,支持点击交互,常用于选项设置和列表选择中。 +
+ +
+ ::: warning 注意 `SuperDropdown` 需要在 `Scaffold` 组件内使用! ::: diff --git a/docs/zh_CN/components/superspinner.md b/docs/zh_CN/components/superspinner.md index cb671c6d..e9495f1f 100644 --- a/docs/zh_CN/components/superspinner.md +++ b/docs/zh_CN/components/superspinner.md @@ -2,6 +2,10 @@ `SuperSpinner` 是 Miuix 中的下拉选择器组件,提供了标题、摘要和带有图标、文本的选项列表,支持点击交互和多种显示模式,常用于具有视觉辅助的选项设置中。该组件与 `SuperDropdown` 组件类似,但提供更丰富的功能和交互体验。 +
+ +
+ ::: warning 注意 `SuperSpinner` 需要在 `Scaffold` 组件内使用! ::: diff --git a/docs/zh_CN/components/superswitch.md b/docs/zh_CN/components/superswitch.md index 342f0825..0478e93b 100644 --- a/docs/zh_CN/components/superswitch.md +++ b/docs/zh_CN/components/superswitch.md @@ -2,6 +2,10 @@ `SuperSwitch` 是 Miuix 中的开关组件,提供了标题、摘要和右侧开关控件,支持点击交互,常用于设置项和偏好切换中。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/surface.md b/docs/zh_CN/components/surface.md index 3078fabf..3e052c12 100644 --- a/docs/zh_CN/components/surface.md +++ b/docs/zh_CN/components/surface.md @@ -2,6 +2,10 @@ `Surface` 是 Miuix 中的基础容器组件,用于为应用内容提供一致的背景和边框效果,为界面元素提供统一的视觉基础。支持一些简单的自定义样式。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/switch.md b/docs/zh_CN/components/switch.md index b55ded7d..e5c9ce34 100644 --- a/docs/zh_CN/components/switch.md +++ b/docs/zh_CN/components/switch.md @@ -2,6 +2,10 @@ `Switch` 是 Miuix 中的基础切换组件,用于在两种状态之间进行切换。它提供了具有动画效果的交互式开关控件,适用于设置项的启用与禁用场景。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/tabrow.md b/docs/zh_CN/components/tabrow.md index f9b9460b..457f6642 100644 --- a/docs/zh_CN/components/tabrow.md +++ b/docs/zh_CN/components/tabrow.md @@ -2,6 +2,10 @@ `TabRow` 是 Miuix 中的导航组件,用于创建可横向滚动的标签页。提供了标准样式和带轮廓(Contour)样式两种变体,适用于内容分类和导航场景。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/text.md b/docs/zh_CN/components/text.md index cff30a5e..eeb1bf0e 100644 --- a/docs/zh_CN/components/text.md +++ b/docs/zh_CN/components/text.md @@ -2,6 +2,10 @@ `Text` 组件是 Miuix 中的基础文本组件,用于显示文字内容。支持自定义各种文本样式、对齐方式和装饰效果。 +
+ +
+ ## 引入 ```kotlin @@ -57,7 +61,7 @@ Text( Text( text = "次要文本", - color = MiuixTheme.colorScheme.onSurfaceVariant + color = MiuixTheme.colorScheme.onSurfaceContainerVariant ) ``` diff --git a/docs/zh_CN/components/textfield.md b/docs/zh_CN/components/textfield.md index f8139f95..51e06db5 100644 --- a/docs/zh_CN/components/textfield.md +++ b/docs/zh_CN/components/textfield.md @@ -2,6 +2,10 @@ `TextField` 是 Miuix 中的基础输入组件,用于接收用户的文本输入。组件提供了丰富的自定义选项,支持标签动画、前置和后置图标等功能。 +
+ +
+ ## 引入 ```kotlin diff --git a/docs/zh_CN/components/topappbar.md b/docs/zh_CN/components/topappbar.md index 0215bd78..f6ebf835 100644 --- a/docs/zh_CN/components/topappbar.md +++ b/docs/zh_CN/components/topappbar.md @@ -4,6 +4,10 @@ 此组件通常与 `Scaffold` 组件结合使用,以便在应用程序的不同页面中保持一致的布局和行为。 +
+ +
+ ## 引入 ```kotlin @@ -47,7 +51,7 @@ Scaffold( largeTitle = "大标题", // 如果不指定,将使用 title 的值 navigationIcon = { IconButton(onClick = { /* 处理点击事件 */ }) { - Icon(MiuixIcons.Basic.ArrowLeft, contentDescription = "返回") + Icon(MiuixIcons.Useful.Back, contentDescription = "返回") } }, actions = { @@ -83,7 +87,7 @@ Scaffold( // 如需添加越界回弹效果,则应在绑定滚动行为之前添加 .overScrollVertical() // 绑定 TopAppBar 滚动事件 - .nestedScroll(topAppBarScrollBehavior.nestedScrollConnection), + .nestedScroll(scrollBehavior.nestedScrollConnection), contentPadding = PaddingValues(top = paddingValues.calculateTopPadding()) ) { // 列表内容 diff --git a/example/build.gradle.kts b/example/build.gradle.kts index 09a0ad22..09e2f09a 100644 --- a/example/build.gradle.kts +++ b/example/build.gradle.kts @@ -4,8 +4,11 @@ @file:Suppress("UnstableApiUsage") import com.android.build.gradle.internal.api.BaseVariantOutputImpl +import org.gradle.kotlin.dsl.withType import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension import java.util.Properties plugins { @@ -192,6 +195,10 @@ compose.desktop { } } +rootProject.plugins.withType { + rootProject.the().lockFileDirectory = rootProject.file("example").resolve("kotlin-js-store") +} + spotless { kotlin { target("src/**/*.kt") diff --git a/example/src/commonMain/kotlin/SecondPage.kt b/example/src/commonMain/kotlin/SecondPage.kt index 09d85fea..21d08596 100644 --- a/example/src/commonMain/kotlin/SecondPage.kt +++ b/example/src/commonMain/kotlin/SecondPage.kt @@ -32,25 +32,20 @@ fun SecondPage( scrollEndHaptic: Boolean ) { val pullToRefreshState = rememberPullToRefreshState() - var isRefreshing by remember { mutableStateOf(false) } val dropdownOptions = listOf("Option 1", "Option 2", "Option 3", "Option 4") val dropdownSelectedOption = remember { mutableStateOf(0) } - var ii = remember { mutableStateOf(8) } + var ii by remember { mutableStateOf(8) } LaunchedEffect(pullToRefreshState.isRefreshing) { if (pullToRefreshState.isRefreshing) { - isRefreshing = true delay(300) - pullToRefreshState.completeRefreshing { - isRefreshing = false - } + pullToRefreshState.completeRefreshing { ii += 4 } } } PullToRefresh( pullToRefreshState = pullToRefreshState, - onRefresh = { ii.value += 4 }, contentPadding = PaddingValues(top = padding.calculateTopPadding()) ) { LazyColumn( @@ -68,7 +63,7 @@ fun SecondPage( Card( modifier = Modifier.padding(12.dp) ) { - for (i in 0 until ii.value) { + for (i in 0 until ii) { SuperDropdown( title = "Dropdown ${i + 1}", items = dropdownOptions, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 703c77b1..67cc8372 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] android-gradle-plugin = "8.10.1" androidx-activity-compose = "1.10.1" -androidx-window = "1.3.0" +androidx-window = "1.4.0" androidx-graphics-shapes = "1.0.0-alpha06" compose-plugin = "1.8.1" dokka = "2.0.0" diff --git a/miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/NavigationBar.kt b/miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/NavigationBar.kt index 02933d08..28648b6d 100644 --- a/miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/NavigationBar.kt +++ b/miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/NavigationBar.kt @@ -228,9 +228,11 @@ fun FloatingNavigationBar( val bottomPaddingValue = when (platformValue) { Platform.IOS -> 8.dp Platform.Android -> { - val navBarBottomPadding = WindowInsets.navigationBars.only(WindowInsetsSides.Bottom).asPaddingValues().calculateBottomPadding() + val navBarBottomPadding = + WindowInsets.navigationBars.only(WindowInsetsSides.Bottom).asPaddingValues().calculateBottomPadding() if (navBarBottomPadding != 0.dp) 8.dp + navBarBottomPadding else 36.dp } + else -> 36.dp } @@ -346,63 +348,69 @@ fun FloatingNavigationBar( horizontalAlignment = CenterHorizontally ) { val imageColorFilter = remember(tint) { ColorFilter.tint(tint) } - if (mode == FloatingNavigationBarMode.IconAndText) { - Image( - modifier = Modifier.padding(top = 6.dp).size(24.dp), - imageVector = item.icon, - contentDescription = item.label, - colorFilter = imageColorFilter - ) - Box( - modifier = Modifier.padding(bottom = 6.dp), - contentAlignment = Alignment.Center - ) { - // Invisible text for layout calculation (always bold) - Text( - modifier = Modifier.alpha(0f), - text = item.label, - textAlign = TextAlign.Center, - fontSize = 12.sp, - fontWeight = FontWeight.Bold // Always bold for layout - ) - // Visible text - Text( - text = item.label, - color = tint, - textAlign = TextAlign.Center, - fontSize = 12.sp, - fontWeight = fontWeight + when (mode) { + FloatingNavigationBarMode.IconAndText -> { + Image( + modifier = Modifier.padding(top = 6.dp).size(24.dp), + imageVector = item.icon, + contentDescription = item.label, + colorFilter = imageColorFilter ) + Box( + modifier = Modifier.padding(bottom = 6.dp), + contentAlignment = Alignment.Center + ) { + // Invisible text for layout calculation (always bold) + Text( + modifier = Modifier.alpha(0f), + text = item.label, + textAlign = TextAlign.Center, + fontSize = 12.sp, + fontWeight = FontWeight.Bold // Always bold for layout + ) + // Visible text + Text( + text = item.label, + color = tint, + textAlign = TextAlign.Center, + fontSize = 12.sp, + fontWeight = fontWeight + ) + } } - } else if (mode == FloatingNavigationBarMode.TextOnly) { - Box( - modifier = Modifier.padding(vertical = 16.dp, horizontal = 2.dp), - contentAlignment = Alignment.Center - ) { - // Invisible text for layout calculation - Text( - modifier = Modifier.alpha(0f), - text = item.label, - textAlign = TextAlign.Center, - fontSize = 14.sp, - fontWeight = FontWeight.Bold // Always bold for layout - ) - // Visible text - Text( - text = item.label, - color = tint, - textAlign = TextAlign.Center, - fontSize = 14.sp, - fontWeight = fontWeight + + FloatingNavigationBarMode.TextOnly -> { + Box( + modifier = Modifier.padding(vertical = 16.dp, horizontal = 2.dp), + contentAlignment = Alignment.Center + ) { + // Invisible text for layout calculation + Text( + modifier = Modifier.alpha(0f), + text = item.label, + textAlign = TextAlign.Center, + fontSize = 14.sp, + fontWeight = FontWeight.Bold // Always bold for layout + ) + // Visible text + Text( + text = item.label, + color = tint, + textAlign = TextAlign.Center, + fontSize = 14.sp, + fontWeight = fontWeight + ) + } + } + + else -> { + Image( + modifier = Modifier.padding(vertical = 10.dp, horizontal = 10.dp).size(28.dp), + imageVector = item.icon, + contentDescription = item.label, + colorFilter = imageColorFilter ) } - } else { - Image( - modifier = Modifier.padding(vertical = 10.dp, horizontal = 10.dp).size(28.dp), - imageVector = item.icon, - contentDescription = item.label, - colorFilter = imageColorFilter - ) } } } diff --git a/miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/utils/MiuixPopupUtils.kt b/miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/utils/MiuixPopupUtils.kt index d6ca6f7f..97b3dbe6 100644 --- a/miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/utils/MiuixPopupUtils.kt +++ b/miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/utils/MiuixPopupUtils.kt @@ -162,7 +162,7 @@ class MiuixPopupUtils { dimExitTransition: ExitTransition? = null, content: (@Composable () -> Unit)? = null, ) { - if (visible.value == false) return + if (!visible.value) return if (content == null) { if (visible.value) visible.value = false return @@ -208,7 +208,7 @@ class MiuixPopupUtils { transformOrigin: (() -> TransformOrigin) = { TransformOrigin.Center }, content: (@Composable () -> Unit)? = null, ) { - if (visible.value == false) return + if (!visible.value) return if (content == null) { if (visible.value) visible.value = false return diff --git a/settings.gradle.kts b/settings.gradle.kts index 2812c3a5..9a45149b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -43,4 +43,7 @@ android { } rootProject.name = "miuix" -include(":miuix", ":example") + +include(":miuix") +include(":example") +include(":docs:demo")