Refactor components and improve commenting
Multiple Astro UI components such as sections, buttons, and modals have been refactored for better code efficiency and cleanliness. Inline comments have been enhanced to provide more context and explanation, improving understanding of components and their properties. Renamed TestimonialsSection2 to TestimonialsSectionAlt for better semantics.
This commit is contained in:
parent
8d43521b45
commit
e7b0e8ae74
8 changed files with 76 additions and 39 deletions
|
@ -1,13 +1,10 @@
|
||||||
---
|
---
|
||||||
// Variables for customization of the LoginModal Component
|
// Define constants for content
|
||||||
// Main heading
|
|
||||||
const title: string = "Fast-Track Your Projects";
|
const title: string = "Fast-Track Your Projects";
|
||||||
|
|
||||||
// Sub-heading text
|
|
||||||
const subTitle: string =
|
const subTitle: string =
|
||||||
"At ScrewFast, we ensure a swift start with instant account setup. Experience the speed of construction redefined.";
|
"At ScrewFast, we ensure a swift start with instant account setup. Experience the speed of construction redefined.";
|
||||||
|
|
||||||
/* TypeScript type for testimonials. */
|
// TypeScript type for testimonials
|
||||||
type Testimonial = {
|
type Testimonial = {
|
||||||
content: string;
|
content: string;
|
||||||
author: string;
|
author: string;
|
||||||
|
@ -15,7 +12,7 @@ type Testimonial = {
|
||||||
avatarSrc: string;
|
avatarSrc: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An array of testimonials, each being an object that conforms to the above `Testimonial` type. */
|
// An array of testimonials
|
||||||
const testimonials: Testimonial[] = [
|
const testimonials: Testimonial[] = [
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
|
@ -27,13 +24,13 @@ const testimonials: Testimonial[] = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/* TypeScript type for stats. */
|
// TypeScript type for stats.
|
||||||
type StatProps = {
|
type StatProps = {
|
||||||
count: string;
|
count: string;
|
||||||
description: string;
|
description: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An array of stats, each being an object that conforms to the above `StatProps` type. */
|
// An array of stats
|
||||||
const statistics: StatProps[] = [
|
const statistics: StatProps[] = [
|
||||||
{
|
{
|
||||||
count: "70k+",
|
count: "70k+",
|
||||||
|
@ -55,12 +52,15 @@ const statistics: StatProps[] = [
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full">
|
<div
|
||||||
|
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||||
|
>
|
||||||
|
<!-- Container for the testimonials -->
|
||||||
<div
|
<div
|
||||||
class="lg:grid lg:grid-cols-12 lg:items-center lg:justify-between lg:gap-16"
|
class="lg:grid lg:grid-cols-12 lg:items-center lg:justify-between lg:gap-16"
|
||||||
>
|
>
|
||||||
<div class="lg:col-span-5 lg:col-start-1">
|
<div class="lg:col-span-5 lg:col-start-1">
|
||||||
<!-- Title and description -->
|
<!-- Title and Subtitle -->
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
<h2
|
<h2
|
||||||
class="mb-2 text-3xl font-bold text-neutral-800 dark:text-neutral-200 lg:text-4xl"
|
class="mb-2 text-3xl font-bold text-neutral-800 dark:text-neutral-200 lg:text-4xl"
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
---
|
---
|
||||||
// Import the necessary dependencies from individual component files
|
// Import AvatarTestimonialSection component for use in this module
|
||||||
import AvatarTestimonialSection2 from "./ui/avatars/AvatarTestimonialSection2.astro";
|
import AvatarTestimonialSection from "./ui/avatars/AvatarTestimonialSection.astro";
|
||||||
|
|
||||||
// Variables for customization of the LoginModal Component
|
// Set title for the testimonial section
|
||||||
// Main heading
|
|
||||||
const title: string = "What Our Customers Say";
|
const title: string = "What Our Customers Say";
|
||||||
|
|
||||||
/* TypeScript type for product. */
|
// Type definition for each testimonial
|
||||||
type Testimonial = {
|
type Testimonial = {
|
||||||
content: string;
|
content: string;
|
||||||
author: string;
|
author: string;
|
||||||
|
@ -15,7 +14,9 @@ type Testimonial = {
|
||||||
avatarAlt: string;
|
avatarAlt: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Testimonial data that will be rendered in the component
|
||||||
const testimonials: Testimonial[] = [
|
const testimonials: Testimonial[] = [
|
||||||
|
// First testimonial data
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
" \"Since switching to ScrewFast's hardware tools, the efficiency on our construction sites has skyrocketed. The durability of the hex bolts and precision of the machine screws are simply unmatched. It's refreshing to work with a company that truly understands the daily demands of the industry.\" ",
|
" \"Since switching to ScrewFast's hardware tools, the efficiency on our construction sites has skyrocketed. The durability of the hex bolts and precision of the machine screws are simply unmatched. It's refreshing to work with a company that truly understands the daily demands of the industry.\" ",
|
||||||
|
@ -25,6 +26,7 @@ const testimonials: Testimonial[] = [
|
||||||
"https://images.unsplash.com/photo-1500648767791-00dcc994a43e?q=80&w=1374&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=facearea&facepad=2&w=320&h=320&q=80",
|
"https://images.unsplash.com/photo-1500648767791-00dcc994a43e?q=80&w=1374&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=facearea&facepad=2&w=320&h=320&q=80",
|
||||||
avatarAlt: "Image Description",
|
avatarAlt: "Image Description",
|
||||||
},
|
},
|
||||||
|
// Second testimonial data
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
" \"As an interior designer, I'm always looking for high-quality materials and tools that help bring my visions to life. ScrewFast's mixed screws assortment has been a game-changer for my projects, providing the perfect blend of quality and variety. The outstanding customer support was just the cherry on top!\" ",
|
" \"As an interior designer, I'm always looking for high-quality materials and tools that help bring my visions to life. ScrewFast's mixed screws assortment has been a game-changer for my projects, providing the perfect blend of quality and variety. The outstanding customer support was just the cherry on top!\" ",
|
||||||
|
@ -34,6 +36,7 @@ const testimonials: Testimonial[] = [
|
||||||
"https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=1376&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D8&auto=format&fit=facearea&facepad=2&w=320&h=320&q=80",
|
"https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=1376&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D8&auto=format&fit=facearea&facepad=2&w=320&h=320&q=80",
|
||||||
avatarAlt: "Image Description",
|
avatarAlt: "Image Description",
|
||||||
},
|
},
|
||||||
|
// Third testimonial data
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
" \"I’ve been a professional carpenter for over 15 years, and I can sincerely say that ScrewFast’s tap bolts and nuts are some of the best I've used. They grip like no other, and I have full confidence in every joint and fixture. Plus, the service is impeccable – they truly care about my project's success.\" ",
|
" \"I’ve been a professional carpenter for over 15 years, and I can sincerely say that ScrewFast’s tap bolts and nuts are some of the best I've used. They grip like no other, and I have full confidence in every joint and fixture. Plus, the service is impeccable – they truly care about my project's success.\" ",
|
||||||
|
@ -45,11 +48,12 @@ const testimonials: Testimonial[] = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
<!-- Main div that wraps the testimonials section -->
|
||||||
<div
|
<div
|
||||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||||
id="testimonials"
|
id="testimonials"
|
||||||
>
|
>
|
||||||
|
<!-- Title of the testimonials section -->
|
||||||
<div class="mb-6 w-3/4 max-w-2xl sm:mb-10 md:mb-16 lg:w-1/2">
|
<div class="mb-6 w-3/4 max-w-2xl sm:mb-10 md:mb-16 lg:w-1/2">
|
||||||
<h2
|
<h2
|
||||||
class="text-balance text-2xl font-bold text-neutral-800 dark:text-neutral-200 sm:text-3xl lg:text-4xl"
|
class="text-balance text-2xl font-bold text-neutral-800 dark:text-neutral-200 sm:text-3xl lg:text-4xl"
|
||||||
|
@ -59,11 +63,13 @@ const testimonials: Testimonial[] = [
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
|
<!-- Looping through each testimonial data and rendering it -->
|
||||||
{
|
{
|
||||||
testimonials.map((testimonial) => (
|
testimonials.map((testimonial) => (
|
||||||
<div class="flex h-auto">
|
<div class="flex h-auto">
|
||||||
<div class="flex flex-col rounded-xl bg-neutral-50 dark:bg-neutral-700">
|
<div class="flex flex-col rounded-xl bg-neutral-50 dark:bg-neutral-700">
|
||||||
<div class="flex-auto p-4 md:p-6">
|
<div class="flex-auto p-4 md:p-6">
|
||||||
|
<!-- Testimonial content -->
|
||||||
<p class="text-pretty text-base italic text-neutral-600 dark:text-neutral-300 md:text-lg">
|
<p class="text-pretty text-base italic text-neutral-600 dark:text-neutral-300 md:text-lg">
|
||||||
{testimonial.content}
|
{testimonial.content}
|
||||||
</p>
|
</p>
|
||||||
|
@ -71,7 +77,7 @@ const testimonials: Testimonial[] = [
|
||||||
|
|
||||||
<div class="rounded-b-xl bg-neutral-300/30 p-4 dark:bg-neutral-900/30 md:px-7">
|
<div class="rounded-b-xl bg-neutral-300/30 p-4 dark:bg-neutral-900/30 md:px-7">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<AvatarTestimonialSection2
|
<AvatarTestimonialSection
|
||||||
src={testimonial.avatarSrc}
|
src={testimonial.avatarSrc}
|
||||||
alt={testimonial.avatarAlt}
|
alt={testimonial.avatarAlt}
|
||||||
/>
|
/>
|
|
@ -1,9 +1,11 @@
|
||||||
|
<!-- Dark Theme Toggle Button --><!-- This button is shown when the light theme is active, and when clicked, it switches the theme to dark -->
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
aria-label="Dark Theme Toggle"
|
aria-label="Dark Theme Toggle"
|
||||||
class="hs-dark-mode group flex items-center font-medium text-neutral-600 outline-none ring-zinc-500 transition duration-300 hover:text-[#fa5a15] hs-dark-mode-active:hidden dark:text-neutral-400 dark:ring-zinc-200 dark:hover:text-[#fb713b] dark:focus:outline-none"
|
class="hs-dark-mode group flex items-center font-medium text-neutral-600 outline-none ring-zinc-500 transition duration-300 hover:text-[#fa5a15] hs-dark-mode-active:hidden dark:text-neutral-400 dark:ring-zinc-200 dark:hover:text-[#fb713b] dark:focus:outline-none"
|
||||||
data-hs-theme-click-value="dark"
|
data-hs-theme-click-value="dark"
|
||||||
>
|
>
|
||||||
|
<!-- The SVG displayed shows an abstract icon that represents the moon (dark theme) -->
|
||||||
<svg
|
<svg
|
||||||
class="h-4 w-4 flex-shrink-0"
|
class="h-4 w-4 flex-shrink-0"
|
||||||
width="24"
|
width="24"
|
||||||
|
@ -16,6 +18,8 @@
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path></svg
|
><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path></svg
|
||||||
>
|
>
|
||||||
|
<!-- Light Theme Toggle Button -->
|
||||||
|
<!-- This button is hidden by default and only appears when the dark theme is active, when clicked, it switches to the light theme -->
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -23,6 +27,7 @@
|
||||||
class="hs-dark-mode group hidden items-center font-medium text-neutral-600 outline-none ring-zinc-500 transition duration-300 hover:text-[#fa5a15] hs-dark-mode-active:block dark:text-neutral-400 dark:ring-zinc-200 dark:hover:text-[#fb713b] dark:focus:outline-none"
|
class="hs-dark-mode group hidden items-center font-medium text-neutral-600 outline-none ring-zinc-500 transition duration-300 hover:text-[#fa5a15] hs-dark-mode-active:block dark:text-neutral-400 dark:ring-zinc-200 dark:hover:text-[#fb713b] dark:focus:outline-none"
|
||||||
data-hs-theme-click-value="light"
|
data-hs-theme-click-value="light"
|
||||||
>
|
>
|
||||||
|
<!-- The SVG displayed shows a standard sun icon that stands for the light theme -->
|
||||||
<svg
|
<svg
|
||||||
class="h-4 w-4 flex-shrink-0"
|
class="h-4 w-4 flex-shrink-0"
|
||||||
width="24"
|
width="24"
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
---
|
---
|
||||||
|
// Extract the properties from Astro.props
|
||||||
const { title, subTitle } = Astro.props;
|
const { title, subTitle } = Astro.props;
|
||||||
|
// Define TypeScript interface for the properties
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
subTitle: string;
|
subTitle: string;
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<!-- Container for the title and subtitle -->
|
||||||
<div class="lg:pe-6 xl:pe-12">
|
<div class="lg:pe-6 xl:pe-12">
|
||||||
<p class="text-6xl font-bold leading-10 text-[#fa5a15] dark:text-[#fb713b]">
|
<p class="text-6xl font-bold leading-10 text-[#fa5a15] dark:text-[#fb713b]">
|
||||||
{title}
|
{title}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2 sm:mt-3 text-neutral-600 dark:text-neutral-400">{subTitle}</p>
|
<p class="mt-2 text-neutral-600 dark:text-neutral-400 sm:mt-3">{subTitle}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
---
|
---
|
||||||
|
// Extract the properties from Astro.props
|
||||||
const { title, subTitle } = Astro.props;
|
const { title, subTitle } = Astro.props;
|
||||||
|
// Define TypeScript interface for the properties
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
subTitle: string;
|
subTitle: string;
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<!-- Container for title and subtitle -->
|
||||||
<div>
|
<div>
|
||||||
<p class="text-3xl font-bold text-[#fa5a15] dark:text-[#fb713b]">{title}</p>
|
<p class="text-3xl font-bold text-[#fa5a15] dark:text-[#fb713b]">{title}</p>
|
||||||
<p class="mt-1 text-neutral-600 dark:text-neutral-400">{subTitle}</p>
|
<p class="mt-1 text-neutral-600 dark:text-neutral-400">{subTitle}</p>
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
---
|
---
|
||||||
|
// Import the Image component from astro:assets
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
|
|
||||||
|
// Destructure the component properties from Astro.props
|
||||||
const { id, aria, src, alt, first, second } = Astro.props;
|
const { id, aria, src, alt, first, second } = Astro.props;
|
||||||
|
|
||||||
|
// Define TypeScript interface for the properties
|
||||||
interface Props {
|
interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
aria: string;
|
aria: string;
|
||||||
|
@ -11,29 +14,35 @@ interface Props {
|
||||||
first?: boolean;
|
first?: boolean;
|
||||||
second?: boolean;
|
second?: boolean;
|
||||||
}
|
}
|
||||||
|
// Set class based on 'first' property
|
||||||
|
// If 'first' is present, show the tab content immediately
|
||||||
const firstClass = first ? "" : "hidden";
|
const firstClass = first ? "" : "hidden";
|
||||||
const secondClass = second ? "shadow-xl aspect-[5/4] bg-neutral-300 dark:bg-neutral-600 object-cover p-3 lg:aspect-auto shadow-neutral-200 rounded-xl dark:shadow-neutral-900/[.2]" :
|
// Set class based on 'second' property
|
||||||
"shadow-xl aspect-[3/2] object-cover lg:aspect-auto shadow-neutral-200 rounded-xl dark:shadow-neutral-900/[.2]";
|
// If 'second' is present, use an alternate style for the image
|
||||||
|
const secondClass = second
|
||||||
|
? "shadow-xl aspect-[5/4] bg-neutral-300 dark:bg-neutral-600 object-cover p-3 lg:aspect-auto shadow-neutral-200 rounded-xl dark:shadow-neutral-900/[.2]"
|
||||||
|
: "shadow-xl aspect-[3/2] object-cover lg:aspect-auto shadow-neutral-200 rounded-xl dark:shadow-neutral-900/[.2]";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
first: This prop should be set to true for the initial TabContent component in your list to ensure that it's visible when the page first loads. All subsequent TabContent components should omit this prop or set it to false.
|
first: This property should be set to true for the initial TabContent component
|
||||||
|
in your list to ensure that it's visible when the page first loads.
|
||||||
|
All subsequent TabContent components should omit this property or set it to false.
|
||||||
|
|
||||||
second: This prop allows to control changes in the look of the Image. If it is set to true, the Image will have different aspect ratio and background color. If this prop is not provided or is set to false, the Image will use default styling. You can enable this for any TabContent component you want to apply these changes to.
|
second: This property allows to control changes in the look of the Image.
|
||||||
|
If it is set to true, the Image will have different aspect ratio and background color.
|
||||||
|
If this property is not provided or is set to false, the Image will use default styling.
|
||||||
|
You can enable this for any TabContent component you want to apply these changes to.
|
||||||
|
|
||||||
Example:
|
This is the full example:
|
||||||
<TabContent id="" aria="" src="" alt="" first={true}/>
|
<TabContent id="" aria="" src="" alt="" first={true}/>
|
||||||
<TabContent id="" aria="" src="" alt="" second={true}/>
|
<TabContent id="" aria="" src="" alt="" second={true}/>
|
||||||
<TabContent id="" aria="" src="" alt="" />
|
<TabContent id="" aria="" src="" alt="" />
|
||||||
*/
|
*/
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<!-- Container for tab content that controls visibility and accessibility -->
|
||||||
id={id}
|
<div id={id} role="tabpanel" class={firstClass} aria-labelledby={aria}>
|
||||||
role="tabpanel"
|
<!-- Astro Image component to display the image with dynamic classes based on the 'second' property -->
|
||||||
class={firstClass}
|
|
||||||
aria-labelledby={aria}
|
|
||||||
>
|
|
||||||
<Image
|
<Image
|
||||||
src={src}
|
src={src}
|
||||||
alt={alt}
|
alt={alt}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
---
|
---
|
||||||
|
// Extract properties from Astro.props
|
||||||
const { aria, dataTab, id, heading, content, first } = Astro.props;
|
const { aria, dataTab, id, heading, content, first } = Astro.props;
|
||||||
|
|
||||||
|
// Define TypeScript interface for properties
|
||||||
interface Props {
|
interface Props {
|
||||||
dataTab: string;
|
dataTab: string;
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -9,10 +11,14 @@ interface Props {
|
||||||
content?: string;
|
content?: string;
|
||||||
first?: boolean;
|
first?: boolean;
|
||||||
}
|
}
|
||||||
const BUTTON_CLASS = "dark:hover:bg-neutral-700 rounded-xl p-4 text-start outline-none ring-zinc-500 transition duration-300 hover:bg-neutral-200 focus-visible:ring hs-tab-active:bg-neutral-50 hs-tab-active:shadow-md hs-tab-active:hover:border-transparent dark:ring-zinc-200 dark:focus:outline-none dark:hs-tab-active:bg-neutral-700/60 md:p-5"
|
// Define button classes
|
||||||
|
const BUTTON_CLASS =
|
||||||
|
"dark:hover:bg-neutral-700 rounded-xl p-4 text-start outline-none ring-zinc-500 transition duration-300 hover:bg-neutral-200 focus-visible:ring hs-tab-active:bg-neutral-50 hs-tab-active:shadow-md hs-tab-active:hover:border-transparent dark:ring-zinc-200 dark:focus:outline-none dark:hs-tab-active:bg-neutral-700/60 md:p-5";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
first: This prop should be set to true for the initial TabNav component in your list to ensure that it's visible when the page first loads. All subsequent TabNav components should omit this prop or set it to false.
|
first: This property should be set to true for the initial TabNav component in your list
|
||||||
|
to ensure that it's visible when the page first loads. All subsequent TabNav components
|
||||||
|
should omit this property or set it to false.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
<TabNav id="" dataTab="" aria="" heading="" paragraph="" first={true} />
|
<TabNav id="" dataTab="" aria="" heading="" paragraph="" first={true} />
|
||||||
|
@ -21,6 +27,7 @@ Example:
|
||||||
*/
|
*/
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<!-- Tab button with dynamic class based on 'first' property, id, tab data, and aria-controls -->
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class={`${first ? "active " : ""}${BUTTON_CLASS}`}
|
class={`${first ? "active " : ""}${BUTTON_CLASS}`}
|
||||||
|
@ -29,13 +36,17 @@ Example:
|
||||||
aria-controls={aria}
|
aria-controls={aria}
|
||||||
role="tab"
|
role="tab"
|
||||||
>
|
>
|
||||||
|
<!-- Slot for additional content -->
|
||||||
<span class="flex">
|
<span class="flex">
|
||||||
<slot />
|
<slot />
|
||||||
|
<!-- Container for the heading and content of the tab -->
|
||||||
<span class="ms-6 grow">
|
<span class="ms-6 grow">
|
||||||
|
<!-- Heading of the tab, changes color when active -->
|
||||||
<span
|
<span
|
||||||
class="block text-lg font-bold text-neutral-800 hs-tab-active:text-[#fa5a15] dark:text-neutral-200 dark:hs-tab-active:text-[#fb713b]"
|
class="block text-lg font-bold text-neutral-800 hs-tab-active:text-[#fa5a15] dark:text-neutral-200 dark:hs-tab-active:text-[#fb713b]"
|
||||||
>{heading}</span
|
>{heading}</span
|
||||||
>
|
>
|
||||||
|
<!-- Content of the tab, changes color when active -->
|
||||||
<span
|
<span
|
||||||
class="mt-1 block text-neutral-500 hs-tab-active:text-neutral-600 dark:text-neutral-400 dark:hs-tab-active:text-neutral-200"
|
class="mt-1 block text-neutral-500 hs-tab-active:text-neutral-600 dark:text-neutral-400 dark:hs-tab-active:text-neutral-200"
|
||||||
>{content}</span
|
>{content}</span
|
||||||
|
|
|
@ -16,4 +16,4 @@ interface Props {
|
||||||
rows="4"
|
rows="4"
|
||||||
class="block w-full rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-3 text-sm text-neutral-700 placeholder:text-neutral-500 focus:border-neutral-200 focus:outline-none focus:ring focus:ring-neutral-400 disabled:pointer-events-none disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-700/30 dark:text-neutral-300 dark:placeholder:text-neutral-400 dark:focus:ring-1"
|
class="block w-full rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-3 text-sm text-neutral-700 placeholder:text-neutral-500 focus:border-neutral-200 focus:outline-none focus:ring focus:ring-neutral-400 disabled:pointer-events-none disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-700/30 dark:text-neutral-300 dark:placeholder:text-neutral-400 dark:focus:ring-1"
|
||||||
placeholder={label}></textarea>
|
placeholder={label}></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue