KotlinBootstrap
Use the official Bootstrap UI components with Kotlin and Compose HTML, to build a frontend on the web.
Install / Use
/learn @stevdza-san/KotlinBootstrapREADME
<p align="center">
<a href="#">
<img src="/ASSETS/logo.svg" alt="Kotlin-Bootstrap logo" width="200" height="165">
</a>
</p>
<h3 align="center">Kotlin Bootstrap</h3>
<p>
⚡Highly experimental library built on top of the <a href="https://github.com/varabyte/kobweb" target="_blank" rel="noopener noreferrer">Kobweb</a> (Compose HTML framework). It allows you to use the official <a href="https://getbootstrap.com/" target="_blank" rel="noopener noreferrer">Bootstrap</a> 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.
</p>
Available Components
- Button
- IconButton
- Input
- Dropdown
- TextArea
- Checkbox
- RadioButton
- Switch
- Alert
- Toast
- Modal
- Select
- Range
- Progress
- Spinner
- Tooltip
- Collapse
- Carousel
- Breadcrumb
- Accordion
- NavBar
- Offcanvas
- Badge
- CloseButton
- ColorPicker
- FilePicker
- Pagination
Bootstrap Icons usage
Install
Update a Project level build.gradle.kts file:
repositories {
..
maven(url = "https://jitpack.io")
}
Update a site module build.gradle.kts file:
kotlin {
sourceSets {
..
val jsMain by getting {
dependencies {
..
implementation("com.github.stevdza-san:KotlinBootstrap:0.1.6")
}
}
}
}
Button
<p> <img src="/ASSETS/buttons.png" alt="Buttons Preview" width="812"> </p> <p> <img src="/ASSETS/loadingButton.gif?raw=true" width="268"/> <img src="/ASSETS/loadingButtonText.gif?raw=true" width="268"/> <img src="/ASSETS/badgeButton.gif?raw=true" width="268"/> </p> <p>A simple button usage:</p>BSButton(
text = "Sign in",
onClick = {}
)
<p>You can update your button state to loading, as well as specify the exact Loading Text <em>(optional)</em>:</p>
var buttonLoading by remember { mutableStateOf(false) }
BSButton(
text = "Sign in",
loading = buttonLoading,
loadingText = "Please wait...",
onClick = { buttonLoading = true }
)
<p>Add a Badge to your button:</p>
BSButton(
text = "Shopping Cart",
badge = ButtonBadge(
text = "10"
),
onClick = {}
)
<p>Buttons with custom properties.</p>
<p>
<img src="/ASSETS/custombuttons.gif?raw=true" alt="CustomButtons Preview" width="812">
</p>
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
<p> <img src="/ASSETS/iconbutton.gif?raw=true" alt="IconButtons Preview"> </p>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:
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
<p> <img src="/ASSETS/inputs.gif?raw=true" alt="Inputs Preview" width="360"> </p> <p>A simple usage with a placeholder:</p>var inputValue by remember { mutableStateOf("") }
BSInput(
value = inputValue,
placeholder = "Type here",
onValueChange = {
inputValue = it
}
)
<p>Floating style input field, where a label is animated:</p>
BSInput(
value = inputValue,
label = "Email Address",
floating = true,
onValueChange = {}
)
<p>Positive validation style input field:</p>
BSInput(
value = inputValue,
label = "Email Address",
placeholder = "Type here",
validation = InputValidation(
isValid = true
),
onValueChange = {}
)
<p>Negative validation style input field:</p>
BSInput(
value = inputValue,
label = "Email Address",
placeholder = "Type here",
validation = InputValidation(
isInvalid = true
),
onValueChange = {}
)
<p>Disabled input field:</p>
BSInput(
value = inputValue,
label = "Email Address",
placeholder = "Type here",
disabled = true,
onValueChange = {}
)
<p>Plain text input field:</p>
BSInput(
value = inputValue,
label = "Email Address",
placeholder = "Type here",
plainText = true,
onValueChange = {}
)
Dropdown
<p> <img src="/ASSETS/dropdowns.png" alt="Dropdown Preview" width="812"> </p> <p> <img src="/ASSETS/placeholderDropdown.gif?raw=true" width="268"/> <img src="/ASSETS/darkBackgroundDropdown.gif?raw=true" width="268"/> <img src="/ASSETS/disabledDropdown.gif?raw=true" width="268"/> </p> <p>Dropdown with a placeholder:</p>BSDropdown(
placeholder = "Select a Platform",
items = listOf("Android", "iOS", "Web"),
onItemSelect = { index, value -> }
)
<p>Dropdown with a dark background:</p>
BSDropdown(
items = listOf("Android", "iOS", "Web"),
darkBackground = true,
onItemSelect = { index, value -> }
)
<p>Disabled Dropdown item:</p>
BSDropdown(
items = listOf("Android", "iOS", "Web"),
disabledItems = listOf("iOS"),
onItemSelect = { index, value -> }
)
TextArea
<p> <img src="/ASSETS/textarea.gif?raw=true" alt="TextArea Preview" width="460"> </p> <p>Basic TextArea example with a label:</p>var value by remember { mutableStateOf("") }
BSTextArea(
value = value,
label = "Email Address",
placeholder = "Type here...",
onValueChange = { value = it }
)
<p>Floating TextArea:</p>
var value by remember { mutableStateOf("") }
BSTextArea(
value = value,
label = "Email Address",
floating = true,
onValueChange = { value = it }
)
Checkbox
<p> <img src="/ASSETS/checkboxes.gif?raw=true" alt="Checkboxes Preview" width="280"> </p> <p>Basic Checkbox usage:</p>BSCheckbox(
label = "Kotlin",
onClick = {}
)
<p>Reversed order checkbox:</p>
BSCheckbox(
label = "C++",
reverse = true,
onClick = {}
)
<p>Toggle button style checkbox:</p>
BSCheckbox(
label = "Python",
toggleButton = true,
onClick = {}
)
RadioButton
<p> <img src="/ASSETS/radiobuttons.gif?raw=true" alt="RadioButtons Preview"> </p> <p>Basic RadioButtonGroup usage:</p>BSRadioButtonGroup {
BSRadioButton(label = "Android", onClick = {})
BSRadioButton(label = "iOS", onClick = {})
BSRadioButton(label = "Web", onClick = {})
}
<p>RadioButtonGroup in a horizontal orientation:</p>
BSRadioButtonGroup(inline = true) {
BSRadioButton(label = "Android", onClick = {})
BSRadioButton(label = "iOS", onClick = {})
BSRadioButton(label = "Web", onClick = {})
}
<p>ToggleButton style of a RadioButtonGroup:</p>
BSRadioButtonGroup(toggleButton = true) {
BSRadioButton(label = "Android", onCl
