Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/stevdza-san/kotlinbootstrap
Use the official Bootstrap UI components with Kotlin and Compose HTML, to build a frontend on the web.
https://github.com/stevdza-san/kotlinbootstrap
bootstrap bootstrap5 compose-html frontend jetpack-compose kobweb kotlin web
Last synced: 9 days ago
JSON representation
Use the official Bootstrap UI components with Kotlin and Compose HTML, to build a frontend on the web.
- Host: GitHub
- URL: https://github.com/stevdza-san/kotlinbootstrap
- Owner: stevdza-san
- Created: 2023-08-23T06:20:40.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2024-09-04T05:52:29.000Z (2 months ago)
- Last Synced: 2024-10-15T04:22:57.579Z (24 days ago)
- Topics: bootstrap, bootstrap5, compose-html, frontend, jetpack-compose, kobweb, kotlin, web
- Language: Kotlin
- Homepage:
- Size: 21.5 MB
- Stars: 191
- Watchers: 5
- Forks: 11
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Kotlin Bootstrap
⚡Highly experimental library built on top of the Kobweb (Compose HTML framework). It allows you to use the official Bootstrap UI components with Kotlin and Jetpack Compose, to build a frontend on the web. You are required to use the kobweb framework, otherwise it won't work. At the moment, components are not yet fully customizable, but I'll work on it. ⚽ The goal is to release all bootstrap components, and only then work on it's customization furthermore. Silk UI layer which is included with Kobweb is not required for this library to work.## Available Components
- [Button](#button)
- [IconButton](#iconbutton)
- [Input](#input)
- [Dropdown](#dropdown)
- [TextArea](#textarea)
- [Checkbox](#checkbox)
- [RadioButton](#radiobutton)
- [Switch](#switch)
- [Alert](#alert)
- [Toast](#toast)
- [Modal](#modal)
- [Select](#select)
- [Range](#range)
- [Progress](#progress)
- [Spinner](#spinner)
- [Tooltip](#tooltip)
- [Collapse](#collapse)
- [Carousel](#carousel)
- [Breadcrumb](#breadcrumb)
- [Accordion](#accordion)
- [NavBar](#navbar)
- [Offcanvas](#offcanvas)
- [Badge](#badge)
- [CloseButton](#closebutton)
- [ColorPicker](#colorpicker)
- [FilePicker](#filepicker)
- [Pagination](#pagination)## Bootstrap Icons usage
- [Icons](#icons)## Install
Update a Project level `build.gradle.kts` file:```gradle
repositories {
..
maven(url = "https://jitpack.io")
}
```Update a `site` module `build.gradle.kts` file:
```gradle
kotlin {
sourceSets {
..
val jsMain by getting {
dependencies {
..
implementation("com.github.stevdza-san:KotlinBootstrap:0.1.5")
}
}
}
}
```## Button
A simple button usage:
```kotlin
BSButton(
text = "Sign in",
onClick = {}
)
```You can update your button state to loading, as well as specify the exact Loading Text (optional):
```kotlin
var buttonLoading by remember { mutableStateOf(false) }
BSButton(
text = "Sign in",
loading = buttonLoading,
loadingText = "Please wait...",
onClick = { buttonLoading = true }
)
```Add a Badge to your button:
```kotlin
BSButton(
text = "Shopping Cart",
badge = ButtonBadge(
text = "10"
),
onClick = {}
)
```Buttons with custom properties.
```kotlin
Column(modifier = Modifier.gap(20.px).fillMaxSize()) {
Row(modifier = Modifier.gap(12.px)) {
BSButton(
text = "Apply Now",
customization = ButtonCustomization(
color = Colors.White,
hoverColor = Colors.White,
backgroundColor = Colors.Black,
hoverBackgroundColor = rgba(0, 0, 0, 0.8),
fontFamily = "Space Grotesk"
),
onClick = {}
)
BSButton(
text = "Get Started",
customization = ButtonCustomization(
color = Colors.White,
hoverColor = Colors.White,
activeColor = Colors.WhiteSmoke,
borderColor = Colors.White,
hoverBorderColor = Colors.White,
activeBorderColor = rgb(168, 192, 255),
gradient = linearGradient(
from = rgb(168, 192, 255),
to = rgb(63, 43, 150),
dir = LinearGradient.Direction.ToTopRight
),
borderRadius = BSBorderRadius(all = 50.px),
horizontalPadding = 1.25.cssRem
),
onClick = {}
)
}
Row(modifier = Modifier.gap(12.px)) {
BSButton(
text = "Submit",
customization = ButtonCustomization(
color = Colors.White,
hoverColor = Colors.Wheat,
activeColor = Colors.White,
borderColor = Colors.White,
hoverBorderColor = Colors.Wheat,
activeBorderColor = Colors.White,
gradient = linearGradient(
from = rgb(188, 78, 156),
to = rgb(248, 7, 89),
dir = LinearGradient.Direction.ToTopRight
),
borderRadius = BSBorderRadius(topLeft = 20.px, bottomRight = 20.px),
fontFamily = "Rubik"
),
onClick = {}
)
}
}
```## IconButton
`BSIconButton` is a component used to display a Bootstrap Icon (`BSIcons`) inside a button. You can customize similar properties like with a regular `BSButton` as well.
A basic usage:```kotlin
Column(modifier = Modifier.gap(20.px).fillMaxSize()) {
Row(modifier = Modifier.gap(12.px)) {
BSIconButton(
icon = BSIcons.UPLOAD,
onClick = {}
)
BSIconButton(
icon = BSIcons.UPLOAD,
variant = ButtonVariant.PrimaryOutline,
onClick = {}
)
}
Row(modifier = Modifier.gap(12.px)) {
BSIconButton(
icon = BSIcons.ANDROID,
variant = ButtonVariant.Success,
onClick = {}
)
BSIconButton(
icon = BSIcons.ANDROID,
variant = ButtonVariant.SuccessOutline,
onClick = {}
)
}
}
```## Input
A simple usage with a placeholder:
```kotlin
var inputValue by remember { mutableStateOf("") }
BSInput(
value = inputValue,
placeholder = "Type here",
onValueChange = {
inputValue = it
}
)
```Floating style input field, where a label is animated:
```kotlin
BSInput(
value = inputValue,
label = "Email Address",
floating = true,
onValueChange = {}
)
```Positive validation style input field:
```kotlin
BSInput(
value = inputValue,
label = "Email Address",
placeholder = "Type here",
validation = InputValidation(
isValid = true
),
onValueChange = {}
)
```Negative validation style input field:
```kotlin
BSInput(
value = inputValue,
label = "Email Address",
placeholder = "Type here",
validation = InputValidation(
isInvalid = true
),
onValueChange = {}
)
```Disabled input field:
```kotlin
BSInput(
value = inputValue,
label = "Email Address",
placeholder = "Type here",
disabled = true,
onValueChange = {}
)
```Plain text input field:
```kotlin
BSInput(
value = inputValue,
label = "Email Address",
placeholder = "Type here",
plainText = true,
onValueChange = {}
)
```## Dropdown
Dropdown with a placeholder:
```kotlin
BSDropdown(
placeholder = "Select a Platform",
items = listOf("Android", "iOS", "Web"),
onItemSelect = { index, value -> }
)
```Dropdown with a dark background:
```kotlin
BSDropdown(
items = listOf("Android", "iOS", "Web"),
darkBackground = true,
onItemSelect = { index, value -> }
)
```Disabled Dropdown item:
```kotlin
BSDropdown(
items = listOf("Android", "iOS", "Web"),
disabledItems = listOf("iOS"),
onItemSelect = { index, value -> }
)
```## TextArea
Basic TextArea example with a label:
```kotlin
var value by remember { mutableStateOf("") }
BSTextArea(
value = value,
label = "Email Address",
placeholder = "Type here...",
onValueChange = { value = it }
)
```Floating TextArea:
```kotlin
var value by remember { mutableStateOf("") }
BSTextArea(
value = value,
label = "Email Address",
floating = true,
onValueChange = { value = it }
)
```## Checkbox
Basic Checkbox usage:
```kotlin
BSCheckbox(
label = "Kotlin",
onClick = {}
)
```Reversed order checkbox:
```kotlin
BSCheckbox(
label = "C++",
reverse = true,
onClick = {}
)
```Toggle button style checkbox:
```kotlin
BSCheckbox(
label = "Python",
toggleButton = true,
onClick = {}
)
```## RadioButton
Basic RadioButtonGroup usage:
```kotlin
BSRadioButtonGroup {
BSRadioButton(label = "Android", onClick = {})
BSRadioButton(label = "iOS", onClick = {})
BSRadioButton(label = "Web", onClick = {})
}
```RadioButtonGroup in a horizontal orientation:
```kotlin
BSRadioButtonGroup(inline = true) {
BSRadioButton(label = "Android", onClick = {})
BSRadioButton(label = "iOS", onClick = {})
BSRadioButton(label = "Web", onClick = {})
}
```ToggleButton style of a RadioButtonGroup:
```kotlin
BSRadioButtonGroup(toggleButton = true) {
BSRadioButton(label = "Android", onClick = {})
BSRadioButton(label = "iOS", onClick = {})
BSRadioButton(label = "Web", onClick = {})
}
```## Switch
Switch with a default checked state:
```kotlin
BSSwitch(
label = "Android",
defaultChecked = true,
onClick = {}
)
```Disabled Switch with a default unchecked state:
```kotlin
BSSwitch(
label = "Android",
disabled = true,
onClick = {}
)
```## Alert
Primary Style Alert with an Info icon and a bold text:
```kotlin
BSAlert(
message = "Visit my YouTube Channel: Stevdza-San",
icon = AlertIcon.Info,
bold = "Stevdza-San"
)
```Success Style Alert with a Checkmark icon and a link text:
```kotlin
BSAlert(
message = "You have successfully purchased a book!",
alertLink = Pair("book", "https://google.com"),
icon = AlertIcon.Checkmark,
style = AlertStyle.Success
)
```Dismissable Alert:
```kotlin
BSAlert(
message = "Dismissable Alert.",
dismissible = true,
style = AlertStyle.Dark
)
```## Toast
Even though a Toast component is not yet fully customizable, from this preview above you can see that there are different variations and styles that you can apply to it. For triggering a Toast component, you do need to call a special function `showToast(toastId)` and pass your toast id, in order to properly display it on the screen. Every Toast components needs to be wrapped inside the `BSToastGroup` composable. Also there's a `ToastPlacement` parameter available on `BSToastGroup` that you can use to modify a toast placement.
`BSToast` gets visible once you trigger a `showToast()` function:
```kotlin
BSToastGroup {
BSToast(
id = "toast",
title = "Welcome",
body = "Browse our website for more interesting products!",
onCloseClick = {}
)
}BSButton(
text = "Show Toast",
onClick = {
showToast("toast")
}
)
````BSToastBasic` which is not automatically dismissable, because it has `autoHide` parameter equal to false:
```kotlin
BSToastGroup {
BSToastBasic(
id = "toastBasic",
text = "Thank you for your feedback!",
style = ToastStyle.Dark,
autoHide = false,
closeButtonDark = false,
onCloseClick = {}
)
}
````BSToastAction` which contains additional positive/negative buttons:
```kotlin
BSToastGroup {
BSToastAction(
id = "toastAction2",
text = "Are you sure you want to delete 24 items?",
positiveButtonText = "Yes",
positiveButtonVariant = ButtonVariant.Primary,
negativeButtonVariant = ButtonVariant.Danger,
negativeButtonText = "Cancel",
style = ToastStyle.Dark,
onPositiveButtonClick = {},
onNegativeButtonClick = {}
)
}
```## Modal
`BSModal` component is not visible by default. If you want to show it on your page, then you need to call a modifier `showModalOnClick()` on a `BSButton` or any other clickable composable, and pass the ID of the modal itself. After you do that, just click the component that has that modifier, and your `BSModal` will appear.
A basic Modal usage:
```kotlin
BSModal(
id = "contactModal",
title = "Contact us",
body = {
Column {
BSInput(
modifier = Modifier
.fillMaxWidth()
.margin(bottom = 14.px),
value = "",
label = "Email Address",
placeholder = "Type here...",
onValueChange = {}
)
BSTextArea(
modifier = Modifier.fillMaxWidth(),
value = "",
label = "Message",
placeholder = "Type here...",
onValueChange = {}
)
}
},
positiveButtonText = "Send Message",
negativeButtonText = "Close",
onPositiveButtonClick = {},
onNegativeButtonClick = {}
)BSButton(
modifier = Modifier.showModalOnClick(id = "contactModal"),
text = "Trigger",
onClick = {}
)
```## Select
Select component's basic usage:
```kotlin
BSSelect(
items = listOf("Android", "iOS", "Web", "Desktop"),
placeholder = "Choose a Platform",
onItemSelected = { index, value -> }
)
```Floating style of a Select component:
```kotlin
BSSelect(
items = listOf("Android", "iOS", "Web", "Desktop"),
placeholder = "Choose a Platform",
floating = true,
onItemSelected = { index, value -> }
)
```## Range
Range's basic usage:
```kotlin
BSRange(
modifier = Modifier.width(300.px),
label = "Range (0-10)",
min = 0,
max = 10,
onSelect = {}
)
```## Progress
Basic Progress component usage:
```kotlin
BSProgress(percentage = 85.percent)
```Stripped style:
```kotlin
BSProgress(
percentage = 85.percent,
striped = true
)
```Animated Stripped style:
```kotlin
BSProgress(
percentage = 85.percent,
stripedAnimated = true
)
```## Spinner
Default Spinner style:
```kotlin
BSSpinner(variant = SpinnerVariant.Default)
```Grow Spinner style:
```kotlin
BSSpinner(variant = SpinnerVariant.DefaultGrow)
```## Tooltip
Before you can use and display a Tooltip, you need to initialize them by calling `initializeTooltips()` function:
```kotlin
LaunchedEffect(Unit) {
initializeTooltips()
}
```Usually, the content on top of which you want to add a tooltip, is specified as a content lambda of the `BSTooltip` composable:
```kotlin
BSTooltip(
text = "https://stevdza-san.com",
content = {
A(href = "https://stevdza-san.com") {
SpanText(text = "Online Courses")
}
}
)
```You can also change a direction of the tooltip, by using `TooltipDirection` parameter:
```kotlin
BSTooltip(
text = "https://stevdza-san.com",
direction = TooltipDirection.Right,
content = {
A(href = "https://stevdza-san.com") {
SpanText(text = "Online Courses")
}
}
)
```## Collapse
To make your button or any other clickable component as the one that triggers the `BSCollapse`, you need to add a `.showCollapse(id)` modifier and pass the `BSCollapse` id.
```kotlin
Column(
modifier = Modifier.width(400.px),
horizontalAlignment = Alignment.CenterHorizontally
) {
BSButton(
modifier = Modifier
.alignContent(AlignContent.Center)
.showCollapse(id = "collapse1"),
text = "FAQ",
onClick = {}
)
BSCollapse(id = "collapse1") {
Column(modifier = Modifier.margin(top = 14.px)) {
SpanText(
modifier = Modifier
.fontSize(18.px)
.fontWeight(FontWeight.Bold),
text = "1. How long does the course take to complete?"
)
SpanText(
text = """
The course is self-paced, so you can complete it at your own speed.
On average, most students finish the course in about 3-6 weeks,
depending on the time they can dedicate to learning.
""".trimIndent()
)
}
}
}
```## Carousel
A basic usage of Carousel component:
```kotlin
BSCarousel(
items = listOf(
CarouselItem(
image = "https://images.pexels.com/photos/2662116/pexels-photo-2662116.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
title = "Moraine Lake"
),
CarouselItem(
image = "https://images.pexels.com/photos/147411/italy-mountains-dawn-daybreak-147411.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
title = "Italy"
),
CarouselItem(
image = "https://images.pexels.com/photos/1166209/pexels-photo-1166209.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
title = "Lavender"
),
),
width = 900.px,
height = 500.px
)
```## Breadcrumb
You can specify and replace a default `divider` parameter to change a separator string, and also you can set a currently selected `BreadcrumbItem` as well.
```kotlin
BSBreadcrumb(
items = listOf(
BreadcrumbItem(
text = "Home",
href = "#"
),
BreadcrumbItem(
text = "Pricing",
href = "#"
),
BreadcrumbItem(
text = "Services",
href = "#"
),
BreadcrumbItem(
text = "About",
href = "#"
),
BreadcrumbItem(
text = "Contact us",
href = "#"
)
),
divider = ">",
currentItem = "About"
)
```## Accordion
You can customize it's `flush` parameter which will remove some borders and rounded corners to render accordions edge-to-edge with their parent container. `alwaysOpen` parameter will make accordion items stay open when another item is opened.
Basic Accordion example:
```kotlin
BSAccordion(
modifier = Modifier.width(300.px),
items = listOf(
AccordionItem(
title = "Step 01: Identify your goals",
content = { SpanText(text = "Body text here...") },
defaultOpened = true
),
AccordionItem(
title = "Step 02: Write your goals",
content = { SpanText(text = "Body text here...")}
),
AccordionItem(
title = "Step 03: Analysis",
content = { SpanText(text = "Body text here...")}
),
AccordionItem(
title = "Step 04: Objectives",
content = { SpanText(text = "Body text here...")}
)
)
)
```## NavBar
The NavBar typically appears at the top of the web page and contains various navigation elements such as links, buttons, dropdown menus, and branding elements like logos or site names. It adapts to different screen sizes and devices, making it ideal for responsive web design.
```kotlin
BSNavBar(
modifier = Modifier.fillMaxWidth(),
stickyTop = true,
itemsAlignment = Alignment.CenterHorizontally,
brand = NavBarBrand(
title = "KotlinBootstrap",
image = "https://getbootstrap.com/docs/5.3/assets/brand/bootstrap-logo.svg",
href = "#"
),
expand = NavBarExpand.LG,
backgroundStyle = BackgroundStyle.Dark,
items = listOf(
NavLink(
id = "homeLink",
title = "Home",
onClick = {
println("Index: $it Title: Home")
}
),
NavLink(
id = "servicesLink",
title = "Services",
onClick = {}
),
NavLink(
id = "pricingLink",
title = "Pricing",
onClick = {}
),
NavLink(
id = "aboutLink",
title = "About us",
onClick = {}
),
NavDropdown(
placeholder = "Language",
items = listOf(
NavDropdownItem(
id = "kotlinLanguage",
title = "Kotlin",
onClick = {
println("Index: $it Title: Kotlin")
}
),
NavDropdownItem(
id = "javaLanguage",
title = "Java",
onClick = {}
)
)
)
),
inputField = NavBarInputField(
placeholder = "Search",
value = "",
onValueChange = {}
),
button = NavBarButton(
text = "Search",
onClick = {}
)
)
```
You can add an extra parameter, to replace a default expandable menu with an `Offcanvas` side bar:
```kotlin
BSNavBar(
..
offcanvas = NavBarOffcanvas(
id = "myOffcanvas",
title = "KotlinBootstrap",
dark = true
)
..
)
```## Offcanvas
Offcanvas is used to create sidebar or panel that can slide in and out of the viewport. This component is often used to display additional content, navigation menus, or options without taking up the entire screen space.
```kotlin
val links = listOf("Home", "Pricing", "Services", "Contact us")
BSOffcanvas(
id = "myOffCanvas",
title = "Welcome!",
body = {
Column {
links.forEach { name ->
A(
attrs = Modifier
.margin(bottom = 16.px)
.textDecorationLine(TextDecorationLine.None)
.cursor(Cursor.Pointer)
.toAttrs()
) {
SpanText(name)
}
}
BSButton(
text = "Sign in",
onClick = {}
)
}
},
placement = OffcanvasPlacement.END
)Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
BSButton(
modifier = Modifier.showOffcanvasOnClick(id = "myOffCanvas"),
text = "Show",
onClick = {}
)
}
```## Badge
There are four different `BadgeVariant`'s: Straight, Regular, Rounded, Empty. You can customize the `BackgroundStyle` of the badge, a `fontFamily`, `fontSize`, and `fontWeight` as well.
```kotlin
Row(verticalAlignment = Alignment.CenterVertically) {
SpanText(
modifier = Modifier.margin(right = 8.px),
text = "Fitness Tracker"
)
BSBadge(
modifier = Modifier.margin(bottom = 8.px),
text = "New",
variant = BadgeVariant.Straight
)
}
```## CloseButton
A basic usage:
```kotlin
BSCloseButton()
```## ColorPicker
A basic usage:
```kotlin
BSColorPicker(onColorSelected = {})
```## FilePicker
FilePicker component provides a required lambda `onFileSelected`, that returns two strings. The first one represents a fileName, while the second one the actual file encoded in BASE_64 string.
A basic usage:
```kotlin
BSFileInput(
label = "Choose a file",
onFileSelected = { fileName, file -> }
)
```## Pagination
`BSPagination` component is used to divide long lists or tables into multiple pages, making it easier for users to navigate through the content.
A basic usage:
```kotlin
var currentPage by remember { mutableStateOf(1) }BSPagination(
pages = 15,
maxVisiblePages = 3,
currentPage = currentPage,
previousButton = PreviousButton(
onClick = { currentPage = it }
),
nextButton = NextButton(
onClick = { currentPage = it }
),
onPageClick = { currentPage = it }
)
```## Icons
There are over 2.000 icons available in a Bootstrap library. You can use a `BSIcons` object to access all icons. There's a `BSIcon` composable function that allows you to display those same icons as well. There's also a `BSIconButton` composable that displays an icon inside the button.Example *(Zoomed in)* icon, that represents one of the many vector icons in the library:
```kotlin
BSIcon(
icon = BSIcons.ANDROID,
size = 1.cssRem,
color = Colors.LightGreen
)
```