Table of Contents
- Installation
- Apply Tailwind CSS utility classes
- Beautified the Card Layout
- Github Repositories
- Resources
Styling is actually the easiest part of the this exercise.
The steps are generally the same in the frameworks.
- Installed tailwindcss and DaisyUI
- Added DaisyUI plugin in a css file
- Copied the the card layout to the template
- Replaced the static text with profile values
- Replaced custom CSS classes with the equivalent tailwindcss utility classes
Installation
Vue 3 and SvelteKit
npm install tailwindcss@latest @tailwindcss/vite@latest daisyui@latest
Add tailwind CSS to vite
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [tailwindcss(), ...other plugins...],
});
Enable daisyUI plugin in css
@import "tailwindcss";
@plugin "daisyui";
Angular 20 application
npm install daisyui@latest tailwindcss@latest @tailwindcss/postcss@latest postcss@latest --force
Configuration file
// .postcssrc.json
{
"plugins": {
"@tailwindcss/postcss": {}
}
}
Enable DaisyUI plugin in CSS
// src/style.css
@import "tailwindcss";
@plugin "daisyui";
Apply Tailwind CSS utility classes
In the GithubProfileList component, the CSS utility classes can be applied to the header.
<div class="p-[0.75rem] col-span-full text-center">
<h1 class="text-3xl">Github Profile List (Angular Ver.)</h1>
</div>
The header
class can be removed from the style sheet.
Moreover, the CSS grid layout can be styled by the utility classes
Vue 3 Application
In the template of the App
Component
<div class="grid grid-cols-2 pt-0 pb-0 pl-[2rem] pr-[2rem]">
<GithubProfileList :usernames="usernames" />
</div>
SvelteKit Application
// +layout.svelte
<div id="app" class="grid grid-cols-2 pt-0 pb-0 pl-[2rem] pr-[2rem]">
{@render children()}
</div>
Angular 20 application
In the @Component
decorator of the AppComponent
, the styles
property is modified
In order to use @apply
in a CSS class, I must apply @reference
to include the src/styles.css
file without duplication.
styles: `
@reference "../../../styles.css";
:host {
@apply grid grid-cols-2 pt-0 pb-0 pl-[2rem] pr-[2rem]
}
`,
The Grid layout is applied successfully in all frameworks
Beautified the Card Layout
The CSS styles are the same in the examples but the frameworks has different syntaxes in control flow and interpolation.
Vue 3 Application
// GithubProfileCard.vue
<div class="card card-side bg-base-100 shadow-sm" v-if="profile">
<figure class="basis-[30%] grow shrink">
<img :src="profile.avatar_url" :alt="profile.name" />
</figure>
<div class="card-body basis-[70%] grow shrink">
<h2 class="card-title">{{ profile.login }}</h2>
<p>Name: {{ profile.name }}</p>
<p>Bio: {{ profile.bio || 'N/A' }}</p>
<p>Followers: {{ profile.followers }}</p>
<p>Following: {{ profile.following }}</p>
<p>Public Repos: {{ profile.public_repos }}</p>
<div class="card-actions justify-end">
<button class="btn btn-primary">
<a :href="profile.html_url" target="_blank" rel="noopener noreferrer">
<span class="text-white">View Profile</span>
</a>
</button>
</div>
</div>
</div>
<div v-else-if="error">Error: {{ error }}</div>
SvelteKit Application
// github-profile-card.svelte
<div>
{#if profile}
<div class="card card-side bg-base-100 shadow-sm">
<figure class="basis-[30%] grow shrink">
<img src={profile.avatar_url} alt={profile.name} />
</figure>
<div class="card-body basis-[70%] grow shrink">
<h2 class="card-title">{ profile.login }</h2>
<p>Name: { profile.name }</p>
<p>Bio: { profile.bio || 'N/A' }</p>
<p>Followers: { profile.followers }</p>
<p>Following: { profile.following }</p>
<p>Public Repos: { profile.public_repos }</p>
<div class="card-actions justify-end">
<button class="btn btn-primary">
<a href={profile.html_url} target="_blank" rel="noopener noreferrer">
<span class="text-white">View Profile</span>
</a>
</button>
</div>
</div>
</div>
{:else if error}
<div>
<p>Error: {error}</p>
</div>
{/if}
</div>
Angular 20 Application
@let status = profileResource.status();
@if (status === 'loading') {
<p>Loading profile...</p>
} @else if (status === 'error') {
<p>Error loading profile: {{ error() }}</p>
} @else {
@if (profile(); as profile) {
<div class="card card-side bg-base-100 shadow-sm" v-if="profile">
<figure class="basis-[30%] grow shrink">
<img [src]="profile.avatar_url" [alt]="profile.name" />
</figure>
<div class="card-body basis-[70%] grow shrink">
<h2 class="card-title">{{ profile.login }}</h2>
<p>Name: {{ profile.name }}</p>
<p>Bio: {{ profile.bio || 'N/A' }}</p>
<p>Followers: {{ profile.followers }}</p>
<p>Following: {{ profile.following }}</p>
<p>Public Repos: {{ profile.public_repos }}</p>
<div class="card-actions justify-end">
<button class="btn btn-primary">
<a [href]="profile.html_url" target="_blank" rel="noopener noreferrer">
<span class="text-white">View Profile</span>
</a>
</button>
</div>
</div>
</div>
} @else if (error()) {
@let message = error();
<div>Error: {{ message }}</div>
}
}
html
Github Repositories
- Vue 3: https://github.com/railsstudent/vue-github-profile
- Svelte 5: https://github.com/railsstudent/svelte-github-profile
- Angular 20: https://github.com/railsstudent/angular-github-profile
Top comments (0)