diff options
| author | HyunWoo Lee <l2hyunwoo@gmail.com> | 2025-12-22 16:36:28 +0300 |
|---|---|---|
| committer | HyunWoo Lee <l2hyunwoo@gmail.com> | 2025-12-22 16:36:28 +0300 |
| commit | 316bc5790f697c65a6c8fa6912321c1862edfa22 (patch) | |
| tree | 2a01f6fc63fe651213a85087a868a31e3b6df42b /docs/src/wasmJsMain | |
| parent | 6d819215724b528836550c7a70a850cb84a01394 (diff) | |
| download | colorpicker-compose-316bc5790f697c65a6c8fa6912321c1862edfa22.tar.xz | |
style: add docs slidebar
Diffstat (limited to 'docs/src/wasmJsMain')
| -rw-r--r-- | docs/src/wasmJsMain/kotlin/docs/component/DocsSidebar.kt | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/docs/src/wasmJsMain/kotlin/docs/component/DocsSidebar.kt b/docs/src/wasmJsMain/kotlin/docs/component/DocsSidebar.kt new file mode 100644 index 0000000..07e364f --- /dev/null +++ b/docs/src/wasmJsMain/kotlin/docs/component/DocsSidebar.kt @@ -0,0 +1,324 @@ +/* + * Designed and developed by 2022 skydoves (Jaewoong Eum) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package docs.component + +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.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Book +import androidx.compose.material.icons.filled.Code +import androidx.compose.material.icons.filled.DarkMode +import androidx.compose.material.icons.filled.Home +import androidx.compose.material.icons.filled.LightMode +import androidx.compose.material.icons.filled.Palette +import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalUriHandler +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import docs.navigation.DocsRoute +import docs.theme.DocsTheme + +@Composable +fun DocsSidebar( + currentRoute: DocsRoute, + onNavigate: (DocsRoute) -> Unit, + isDarkTheme: Boolean, + onToggleTheme: () -> Unit, + primaryColor: Color, + onOpenColorPicker: () -> Unit, + modifier: Modifier = Modifier, +) { + val uriHandler = LocalUriHandler.current + + Column( + modifier = modifier + .width(260.dp) + .fillMaxHeight() + .background(DocsTheme.colors.sidebarBackground) + .padding(vertical = 16.dp), + ) { + Column( + modifier = Modifier + .weight(1f) + .verticalScroll(rememberScrollState()), + ) { + // Logo/Header + SidebarHeader(onNavigate = onNavigate) + + Spacer(modifier = Modifier.height(24.dp)) + + // Home + SidebarItem( + route = DocsRoute.Home, + icon = Icons.Default.Home, + isSelected = currentRoute == DocsRoute.Home, + onClick = { onNavigate(DocsRoute.Home) }, + ) + + Spacer(modifier = Modifier.height(16.dp)) + HorizontalDivider(color = DocsTheme.colors.divider, thickness = 1.dp) + Spacer(modifier = Modifier.height(16.dp)) + + // Guide Section + SidebarSection( + title = "Guide", + icon = Icons.Default.Book, + ) + DocsRoute.guideRoutes.forEach { route -> + SidebarItem( + route = route, + isSelected = currentRoute == route, + onClick = { onNavigate(route) }, + indented = true, + ) + } + + Spacer(modifier = Modifier.height(16.dp)) + HorizontalDivider(color = DocsTheme.colors.divider, thickness = 1.dp) + Spacer(modifier = Modifier.height(16.dp)) + + // API Reference Section + SidebarSection( + title = "API Reference", + icon = Icons.Default.Code, + ) + DocsRoute.apiRoutes.forEach { route -> + SidebarItem( + route = route, + isSelected = currentRoute == route, + onClick = { onNavigate(route) }, + indented = true, + ) + } + + Spacer(modifier = Modifier.height(16.dp)) + HorizontalDivider(color = DocsTheme.colors.divider, thickness = 1.dp) + Spacer(modifier = Modifier.height(16.dp)) + + // Playground + SidebarItem( + route = DocsRoute.Playground, + icon = Icons.Default.PlayArrow, + isSelected = currentRoute == DocsRoute.Playground, + onClick = { onNavigate(DocsRoute.Playground) }, + ) + } + + // Bottom section with Theme toggle, Color picker, and GitHub button + HorizontalDivider(color = DocsTheme.colors.divider, thickness = 1.dp) + Spacer(modifier = Modifier.height(12.dp)) + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + // Theme toggle button + IconButton( + onClick = onToggleTheme, + modifier = Modifier + .size(40.dp) + .clip(CircleShape) + .background(DocsTheme.colors.surfaceVariant), + ) { + Icon( + imageVector = if (isDarkTheme) Icons.Default.LightMode else Icons.Default.DarkMode, + contentDescription = if (isDarkTheme) "Switch to Light Mode" else "Switch to Dark Mode", + tint = DocsTheme.colors.onSurface, + modifier = Modifier.size(20.dp), + ) + } + + // Theme color picker button + Box( + modifier = Modifier + .size(40.dp) + .clip(CircleShape) + .background(DocsTheme.colors.surfaceVariant) + .clickable(onClick = onOpenColorPicker), + contentAlignment = Alignment.Center, + ) { + Box( + modifier = Modifier + .size(24.dp) + .clip(CircleShape) + .background(primaryColor), + ) + } + + // GitHub button + Box( + modifier = Modifier + .weight(1f) + .height(40.dp) + .clip(RoundedCornerShape(8.dp)) + .background(DocsTheme.colors.surfaceVariant) + .clickable { uriHandler.openUri("https://github.com/skydoves/colorpicker-compose") } + .padding(horizontal = 12.dp), + contentAlignment = Alignment.Center, + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + ) { + Icon( + imageVector = Icons.Default.Code, + contentDescription = "GitHub", + tint = DocsTheme.colors.onSurface, + modifier = Modifier.size(18.dp), + ) + Spacer(modifier = Modifier.width(8.dp)) + Text( + text = "GitHub", + style = DocsTheme.typography.bodySmall, + color = DocsTheme.colors.onSurface, + fontWeight = FontWeight.Medium, + ) + } + } + } + } +} + +@Composable +private fun SidebarHeader(onNavigate: (DocsRoute) -> Unit) { + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { onNavigate(DocsRoute.Home) } + .padding(horizontal = 16.dp, vertical = 8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = Icons.Default.Palette, + contentDescription = "ColorPicker", + tint = DocsTheme.colors.primary, + modifier = Modifier.size(32.dp), + ) + Spacer(modifier = Modifier.width(12.dp)) + Text( + text = "ColorPicker", + style = DocsTheme.typography.h2, + color = DocsTheme.colors.onSurface, + ) + } +} + +@Composable +private fun SidebarSection(title: String, icon: ImageVector) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = icon, + contentDescription = null, + tint = DocsTheme.colors.onSurfaceVariant, + modifier = Modifier.size(18.dp), + ) + Spacer(modifier = Modifier.width(8.dp)) + Text( + text = title, + fontSize = 12.sp, + fontWeight = FontWeight.SemiBold, + color = DocsTheme.colors.onSurfaceVariant, + letterSpacing = 0.5.sp, + ) + } +} + +@Composable +private fun SidebarItem( + route: DocsRoute, + isSelected: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, + icon: ImageVector? = null, + indented: Boolean = false, +) { + val backgroundColor = when { + isSelected -> DocsTheme.colors.sidebarActive + else -> DocsTheme.colors.sidebarBackground + } + + val textColor = when { + isSelected -> DocsTheme.colors.primary + else -> DocsTheme.colors.onSurface + } + + Box( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 8.dp, vertical = 2.dp) + .clip(RoundedCornerShape(8.dp)) + .background(backgroundColor) + .clickable(onClick = onClick) + .padding( + start = if (indented) 32.dp else 16.dp, + end = 16.dp, + top = 10.dp, + bottom = 10.dp, + ), + ) { + Row(verticalAlignment = Alignment.CenterVertically) { + if (icon != null) { + Icon( + imageVector = icon, + contentDescription = null, + tint = textColor, + modifier = Modifier.size(20.dp), + ) + Spacer(modifier = Modifier.width(12.dp)) + } + Text( + text = route.title, + style = DocsTheme.typography.bodySmall, + color = textColor, + fontWeight = if (isSelected) FontWeight.Medium else FontWeight.Normal, + ) + } + } +} |
