Installation
How to install dependencies and structure your app.
Unlike the official shadcn/ui for React, where the components can be added by cli, here we need to just add a dependency in build.gradle to add all of them.
Automatic Installation
Create a new project
Use the Kobweb CLI to create a new project from template.
kobweb create shadcn-kobweb --repo https://github.com/dead8309/shadcn-kotlin-templates
That's it. You can now run the site through kobweb run
Manual Installation
Create a new project
Use the Kobweb CLI to create a new project.
kobweb create app
Add tailwind-kt Plugin
Apply tailwind-kt plugin to add Tailwind CSS support to your project.
plugins {
id("io.github.dead8309.tailwind-kt").version("$latest_version")
}
kotlin {
// Place it below `configAsKobwebApplication()`
setupTailwindProject()
}
Run the site through kobeweb cli once so tailwind-kt can generate all the necessary files
kobweb run
Add shadcn-kotlin dependency
Add shadcn-kotlin library which adds all the components to your project.
implementation("io.github.dead8309:shadcn-kotlin:1.0.0")
Add babel dependencies
implementation(devNpm("@babel/core","7.22.5"))
implementation(devNpm("babel-loader","9.1.2"))
implementation(devNpm("@babel/preset-react","7.22.5"))
implementation(devNpm("@babel/preset-env","7.22.5"))
implementation(devNpm("@babel/preset-typescript","7.22.5"))
This will fix the webpack loader issues
Configure tailwind.config.js
This is what this project's tailwind.config.js file looks like:
const { fontFamily } = require("tailwindcss/defaultTheme")
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class","[data-theme='dark']"],
content: [
"**/*.{html,js}",
"../../node_modules/@lshay/ui/dist/components/**/*.jsx",
"../../node_modules/@lshay/ui/dist/components/**/*.js",
],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
borderRadius: {
lg: `var(--radius)`,
md: `calc(var(--radius) - 2px)`,
sm: "calc(var(--radius) - 4px)",
},
fontFamily: {
sans: ["Inter", ...fontFamily.sans],
},
keyframes: {
"accordion-down": {
from: { height: 0 },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: 0 },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [require("tailwindcss-animate")],
}
Feel free to add or modify as needed to suit your project.
Configure Styles
Add the following to your src/jsMain/resources/globals.css file.
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap");
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 47.4% 11.2%;
--card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 100% 50%;
--destructive-foreground: 210 40% 98%;
--ring: 215 20.2% 65.1%;
--radius: 0.5rem;
}
[data-theme='dark'] {
--background: 224 71% 4%;
--foreground: 213 31% 91%;
--muted: 223 47% 11%;
--muted-foreground: 215.4 16.3% 56.9%;
--popover: 224 71% 4%;
--popover-foreground: 215 20.2% 65.1%;
--card: 224 71% 4%;
--card-foreground: 213 31% 91%;
--border: 216 34% 17%;
--input: 216 34% 17%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 1.2%;
--secondary: 222.2 47.4% 11.2%;
--secondary-foreground: 210 40% 98%;
--accent: 216 34% 17%;
--accent-foreground: 210 40% 98%;
--destructive: 0 63% 31%;
--destructive-foreground: 210 40% 98%;
--ring: 216 34% 17%;
--radius: 0.5rem;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
}
Import styles to your app
Add the following in your PageLayout composable.
@Composable
fun PageLayout(
content: @Composable() -> Unit
) {
kotlinext.js.require("./globals.css")
// rest contents goes here
}
Configure Babel Loader
Create a file babel-loader.config.js in your webpack.config.d folder
Add the following contents to the file
config.module.rules.push({
test: /\.(js|jsx|ts|tsx)$/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
]
},
},
});
That's it. You can now use shadcn components in your project.