|
| 1 | +# Contributing to Compose-Fluent-UI |
| 2 | + |
| 3 | +Hello and welcome! 🎉 |
| 4 | + |
| 5 | +**Our project components are designed using the [Windows UI Kit Figma guidelines](https://www.figma.com/community/file/1440832812269040007/windows-ui-kit). Therefore, the layout and style of the components must strictly adhere to this design guide. Additionally, the components showcased in the Gallery should align as closely as possible with this design guide.** |
| 6 | + |
| 7 | +We are thrilled to have you considering contributing to Compose-Fluent-UI. Contributions are what make the open-source community such an incredible place to learn, inspire, and create. Here are some guidelines to help you get started: |
| 8 | + |
| 9 | +## Getting Started |
| 10 | + |
| 11 | +- **Fork this repository**: Click on the "Fork" button at the top right of this page. This will create a copy of the repository in your account. |
| 12 | +- **Select the Dev branch**: Choose the `dev` branch as your base branch. |
| 13 | +- **Create a new branch**: Create a new branch from `dev` for your feature or bug fix using `git checkout -b your-branch-name`. |
| 14 | +- **Base all development work on your new branch**: Ensure that all your development work is committed to the branch you just created from `dev`. |
| 15 | + |
| 16 | +## Developing Components |
| 17 | + |
| 18 | +- **Create the source code**: In the `fluent/components` directory, create the source code for the component that corresponds to the Windows UI Kit. |
| 19 | +```Kotlin |
| 20 | +// Button.kt |
| 21 | +package io.github.composefluent.components |
| 22 | +``` |
| 23 | +- **Handle internal classes**: If your component involves internal classes that may be used by other components (such as `OverflowRow`), create the relevant classes in the appropriate package (e.g., `/layout`). |
| 24 | +```Kotlin |
| 25 | +// OverflowRow.kt |
| 26 | +package io.github.composefluent.layout.overflow |
| 27 | + |
| 28 | +@Composable |
| 29 | +internal fun OverflowRow( |
| 30 | + modifier: Modifier = Modifier, |
| 31 | + overflow: OverflowPosition = OverflowPosition.End, |
| 32 | + state: OverflowRowState = rememberOverflowRowState(), |
| 33 | + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, |
| 34 | + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, |
| 35 | + overflowAction: @Composable OverflowActionScope.() -> Unit = {}, |
| 36 | + contentPadding: PaddingValues = PaddingValues(), |
| 37 | + alwaysShowOverflowAction: Boolean = false, |
| 38 | + content: OverflowRowScope.() -> Unit |
| 39 | +) |
| 40 | +``` |
| 41 | +- **Adhere to guidelines**: When developing, strictly follow the Windows UI Kit for layout, typography, and color. |
| 42 | +- **Include TODOs for animations**: If your component involves animations and you're unsure of the specific parameters to use, add a `TODO` note. |
| 43 | + |
| 44 | +## Testing and Showcasing Components |
| 45 | + |
| 46 | +The Gallery app uses KSP and KotlinPoet to automatically generate a navigation tree and Kotlin example source code. Below are the steps to add a component example page in the Gallery: |
| 47 | + |
| 48 | +1. **Create [YourComponent]Screen.kt**: In the package corresponding to the component group, create a `[YourComponent]Screen.kt` file. |
| 49 | +```Kotlin |
| 50 | +// ButtonScreen.kt |
| 51 | +package io.github.composefluent.gallery.screen.basicinput |
| 52 | +``` |
| 53 | +2. **Create a method with @Component annotation**: Create a method named `[YourComponent]Screen` and annotate it with `@Component`, providing the relevant `description` and `index`. |
| 54 | +```Kotlin |
| 55 | +// ButtonScreen.kt |
| 56 | +@Component(index = 0, description = "A control that responds to user input") |
| 57 | +@Composable |
| 58 | +fun ButtonScreen() { |
| 59 | + |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +3. **Use GalleryPage method**: In this method, use the `GalleryPage` method to create a uniform component example page layout. The `GalleryPage` method takes `componentPath` and `galleryPath` as parameters, which are provided by the `FluentSourceFile` and `ComponentPagePath` classes generated by KSP, indicating the source code path of the component and the corresponding Gallery example code path. |
| 64 | +```Kotlin |
| 65 | +// ButtonScreen.kt |
| 66 | +@Component(index = 0, description = "A control that responds to user input") |
| 67 | +@Composable |
| 68 | +fun ButtonScreen() { |
| 69 | + GalleryPage( |
| 70 | + componentPath = FluentSourceFile.Button, |
| 71 | + galleryPath = ComponentPagePath.ButtonScreen, |
| 72 | + ) { |
| 73 | + // Sample sections. |
| 74 | + } |
| 75 | +} |
| 76 | +``` |
| 77 | +4. **Use Section method in GalleryPage**: Within `GalleryPage`, use the `Section` method for each component example. The `Section` method provides `output` and `options` parameters for adjusting options and display output. The `sourceCode` parameter should be the global variable generated by the `@Sample` annotation (which contains the component source code). |
| 78 | +```Kotlin |
| 79 | +// ButtonScreen.kt |
| 80 | +@Component(index = 0, description = "A control that responds to user input") |
| 81 | +@Composable |
| 82 | +fun ButtonScreen() { |
| 83 | + GalleryPage( |
| 84 | + componentPath = FluentSourceFile.Button, |
| 85 | + galleryPath = ComponentPagePath.ButtonScreen, |
| 86 | + ) { |
| 87 | + val clickTextContent = remember { mutableStateOf("") } |
| 88 | + val buttonEnabled = remember { mutableStateOf(true) } |
| 89 | + Section( |
| 90 | + title = "A simple Button with text content.", |
| 91 | + content = { |
| 92 | + ButtonSample(enabled = buttonEnabled.value) { clickTextContent.value = "You clicked: Button 1" } |
| 93 | + }, |
| 94 | + output = { |
| 95 | + if (clickTextContent.value.isNotBlank()) { |
| 96 | + Text(clickTextContent.value) |
| 97 | + } |
| 98 | + }, |
| 99 | + options = { |
| 100 | + CheckBox( |
| 101 | + checked = !buttonEnabled.value, |
| 102 | + onCheckStateChange = { buttonEnabled.value = !it }, |
| 103 | + label = "Disable button" |
| 104 | + ) |
| 105 | + }, |
| 106 | + sourceCode = sourceCodeOfButtonSample |
| 107 | + ) |
| 108 | + } |
| 109 | +} |
| 110 | +``` |
| 111 | +5. **Create an example**: In the `[YourComponent]Screen.kt` file, add a new method named `[YourComponentCase]Sample` with a private visibility modifier, and annotate this method with `@Sample`. This will generate a global variable `sourceCodeOf[YourComponentCase]Sample`, which should be assigned to the `sourceCode` parameter in the corresponding `Section`. |
| 112 | +```Kotlin |
| 113 | +//ButtonScreen.kt |
| 114 | +@Sample |
| 115 | +@Composable |
| 116 | +private fun ButtonSample(enabled: Boolean = true, onClick: () -> Unit) { |
| 117 | + Button(disabled = !enabled, onClick = onClick) { |
| 118 | + Text("Standard Compose Button") |
| 119 | + } |
| 120 | +} |
| 121 | +``` |
| 122 | +6. **Add new groups if needed**: If you cannot find the appropriate group for the component, add a new group in the `ComponentGroupInfo` object, following the format of the existing groups. After adding the group, place the Screen file in the corresponding package. |
| 123 | +```Kotlin |
| 124 | +// ComponentGrupInfo.kt |
| 125 | +package io.github.composefluent.gallery.component |
| 126 | + |
| 127 | +object ComponentGroupInfo { |
| 128 | + prival const val screenPackage: String = "io.github.composefluent.gallery.screen" |
| 129 | + |
| 130 | + // Basic Input is group name, ChckboxChecked is icon, packageMap is the component screens under this group were placed, like ButtonScreen |
| 131 | + @ComponentGroup("CheckboxChecked", index = 2, packageMap = "$screenPackage.basicinput") |
| 132 | + const val BasicInput = "Basic input" |
| 133 | + |
| 134 | + //other groups |
| 135 | + //.... |
| 136 | +} |
| 137 | +``` |
| 138 | + |
| 139 | +7. At the end, you should see the component example page you've created in the Gallery, ready for demonstration and testing. |
| 140 | + |
| 141 | + |
| 142 | +8. **Debugging components with scale mode if needed**: If you need to debug your component with scale mode, you can test it in `TestComponentScreen`. Navigate to this test page in the Gallery app through `Settings > Test Component`. |
| 143 | + |
| 144 | + |
| 145 | +## Need Help? |
| 146 | + |
| 147 | +If you have any questions or need assistance, feel free to open an issue or reach out to the maintainers. We’re here to help! |
| 148 | + |
| 149 | +Thank you for considering contributing to **Compose-Fluent-UI**. We can’t wait to see what you’ll create! |
0 commit comments