- @components.Card(components.CardProps{Class: "w-[350px]"}) {
- @components.CardHeader() {
- @components.CardTitle() {
- Card Title
+
}
diff --git a/pkg/components/card.templ b/pkg/components/card.templ
index 41e5b02..7923214 100644
--- a/pkg/components/card.templ
+++ b/pkg/components/card.templ
@@ -2,63 +2,138 @@ package components
import "github.com/axzilla/goilerplate/pkg/utils"
+// CardImagePosition defines where the image should be placed in the card
+type CardImagePosition string
+
+const (
+ CardImageTop CardImagePosition = "top"
+ CardImageBottom CardImagePosition = "bottom"
+ CardImageLeft CardImagePosition = "left"
+ CardImageRight CardImagePosition = "right"
+)
+
type CardProps struct {
- // Class adds custom CSS classes
+ // Class specifies additional CSS classes to apply to the card.
+ // Default: "" (empty string)
Class string
- // Attributes for additional HTML attributes
+ // Attributes allows passing additional HTML attributes to the card element.
+ // Default: nil
Attributes templ.Attributes
+
+ // Horizontal enables horizontal layout for side images
+ // Default: false
+ Horizontal bool
}
-// Card renders a container component with consistent styling and structure.
+// Card renders a card component with consistent styling and structure.
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/card
//
// Props:
-// - Class: Additional CSS classes
-// - Attributes: Additional HTML attributes
+// - Class: Additional CSS classes to apply to the card. Default: "" (empty string)
+// - Attributes: Additional HTML attributes to apply to the card element. Default: nil
+// - Horizontal: Enables horizontal layout for side images. Default: false
templ Card(props CardProps) {
{ children... }
}
-// CardHeader renders the top section of the card
-// Typically contains title and description
+type CardImageProps struct {
+ // Src is the source URL of the image
+ Src string
+
+ // Alt is the alternative text for the image
+ Alt string
+
+ // Class allows adding custom classes to the image container
+ Class string
+
+ // AspectRatio sets the aspect ratio of the image (e.g., "16/9", "4/3", "1/1")
+ AspectRatio string
+
+ // Position determines the position of the image in the card
+ Position CardImagePosition
+
+ // Width sets the width for side images (e.g., "1/3", "1/2")
+ Width string
+}
+
+// getImageWidth returns the appropriate width class
+func getImageWidth(width string) string {
+ if width == "" {
+ return "w-1/3"
+ }
+ return "w-" + width
+}
+
+// CardImage renders an image section within the card
+templ CardImage(props CardImageProps) {
+
+}
+
+// CardHeader renders the header section of a card.
templ CardHeader() {
{ children... }
}
-// CardTitle renders the card's main heading
-// Uses h3 with consistent styling
+// CardTitle renders the title of a card.
templ CardTitle() {
-
{ children... }
}
-// CardContent renders the main card body section
-// Contains the primary content area
+// CardContent renders the main content area of a card.
templ CardContent() {
{ children... }
}
-// CardFooter renders the bottom section of the card
-// Typically contains actions or summary information
+// CardFooter renders the footer section of a card.
templ CardFooter() {
{ children... }
diff --git a/pkg/components/card_templ.go b/pkg/components/card_templ.go
index 0ec1966..8c009c3 100644
--- a/pkg/components/card_templ.go
+++ b/pkg/components/card_templ.go
@@ -10,20 +10,37 @@ import templruntime "github.com/a-h/templ/runtime"
import "github.com/axzilla/goilerplate/pkg/utils"
+// CardImagePosition defines where the image should be placed in the card
+type CardImagePosition string
+
+const (
+ CardImageTop CardImagePosition = "top"
+ CardImageBottom CardImagePosition = "bottom"
+ CardImageLeft CardImagePosition = "left"
+ CardImageRight CardImagePosition = "right"
+)
+
type CardProps struct {
- // Class adds custom CSS classes
+ // Class specifies additional CSS classes to apply to the card.
+ // Default: "" (empty string)
Class string
- // Attributes for additional HTML attributes
+ // Attributes allows passing additional HTML attributes to the card element.
+ // Default: nil
Attributes templ.Attributes
+
+ // Horizontal enables horizontal layout for side images
+ // Default: false
+ Horizontal bool
}
-// Card renders a container component with consistent styling and structure.
+// Card renders a card component with consistent styling and structure.
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/card
//
// Props:
-// - Class: Additional CSS classes
-// - Attributes: Additional HTML attributes
+// - Class: Additional CSS classes to apply to the card. Default: "" (empty string)
+// - Attributes: Additional HTML attributes to apply to the card element. Default: nil
+// - Horizontal: Enables horizontal layout for side images. Default: false
func Card(props CardProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
@@ -45,7 +62,13 @@ func Card(props CardProps) templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- var templ_7745c5c3_Var2 = []any{utils.TwMerge("rounded-lg border bg-card text-card-foreground shadow-sm", props.Class)}
+ var templ_7745c5c3_Var2 = []any{
+ utils.TwMerge(
+ "rounded-lg border bg-card text-card-foreground shadow-sm",
+ props.Class,
+ ),
+ templ.KV("flex overflow-hidden", props.Horizontal),
+ }
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@@ -87,9 +110,36 @@ func Card(props CardProps) templ.Component {
})
}
-// CardHeader renders the top section of the card
-// Typically contains title and description
-func CardHeader() templ.Component {
+type CardImageProps struct {
+ // Src is the source URL of the image
+ Src string
+
+ // Alt is the alternative text for the image
+ Alt string
+
+ // Class allows adding custom classes to the image container
+ Class string
+
+ // AspectRatio sets the aspect ratio of the image (e.g., "16/9", "4/3", "1/1")
+ AspectRatio string
+
+ // Position determines the position of the image in the card
+ Position CardImagePosition
+
+ // Width sets the width for side images (e.g., "1/3", "1/2")
+ Width string
+}
+
+// getImageWidth returns the appropriate width class
+func getImageWidth(width string) string {
+ if width == "" {
+ return "w-1/3"
+ }
+ return "w-" + width
+}
+
+// CardImage renders an image section within the card
+func CardImage(props CardImageProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -110,11 +160,121 @@ func CardHeader() templ.Component {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
+ var templ_7745c5c3_Var5 = []any{
+ utils.TwMerge(
+ "overflow-hidden",
+ props.Class,
+ ),
+ // Border radius based on position
+ templ.KV("rounded-t-lg", props.Position == CardImageTop),
+ templ.KV("rounded-b-lg", props.Position == CardImageBottom),
+ templ.KV("rounded-l-lg", props.Position == CardImageLeft),
+ templ.KV("rounded-r-lg", props.Position == CardImageRight),
+ // Width for side images
+ templ.KV("shrink-0", props.Position == CardImageLeft || props.Position == CardImageRight),
+ templ.KV(getImageWidth(props.Width), props.Position == CardImageLeft || props.Position == CardImageRight),
+ }
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
)
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return templ_7745c5c3_Err
+ })
+}
+
+// CardHeader renders the header section of a card.
+func CardHeader() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var10 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var10 == nil {
+ templ_7745c5c3_Var10 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templ_7745c5c3_Var4.Render(ctx, templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = templ_7745c5c3_Var10.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -126,8 +286,7 @@ func CardHeader() templ.Component {
})
}
-// CardTitle renders the card's main heading
-// Uses h3 with consistent styling
+// CardTitle renders the title of a card.
func CardTitle() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
@@ -144,16 +303,16 @@ func CardTitle() templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var5 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var5 == nil {
- templ_7745c5c3_Var5 = templ.NopComponent
+ templ_7745c5c3_Var11 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var11 == nil {
+ templ_7745c5c3_Var11 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = templ_7745c5c3_Var11.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -165,8 +324,7 @@ func CardTitle() templ.Component {
})
}
-// CardDescription renders secondary text below the title
-// Uses muted styling for visual hierarchy
+// CardDescription renders the description of a card.
func CardDescription() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
@@ -183,16 +341,16 @@ func CardDescription() templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var6 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var6 == nil {
- templ_7745c5c3_Var6 = templ.NopComponent
+ templ_7745c5c3_Var12 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var12 == nil {
+ templ_7745c5c3_Var12 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templ_7745c5c3_Var6.Render(ctx, templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = templ_7745c5c3_Var12.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -204,8 +362,7 @@ func CardDescription() templ.Component {
})
}
-// CardContent renders the main card body section
-// Contains the primary content area
+// CardContent renders the main content area of a card.
func CardContent() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
@@ -222,16 +379,16 @@ func CardContent() templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var7 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var7 == nil {
- templ_7745c5c3_Var7 = templ.NopComponent
+ templ_7745c5c3_Var13 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var13 == nil {
+ templ_7745c5c3_Var13 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templ_7745c5c3_Var7.Render(ctx, templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = templ_7745c5c3_Var13.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -243,8 +400,7 @@ func CardContent() templ.Component {
})
}
-// CardFooter renders the bottom section of the card
-// Typically contains actions or summary information
+// CardFooter renders the footer section of a card.
func CardFooter() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
@@ -261,16 +417,16 @@ func CardFooter() templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var8 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var8 == nil {
- templ_7745c5c3_Var8 = templ.NopComponent
+ templ_7745c5c3_Var14 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var14 == nil {
+ templ_7745c5c3_Var14 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templ_7745c5c3_Var8.Render(ctx, templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = templ_7745c5c3_Var14.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/pkg/styles/goilerplate.css b/pkg/styles/goilerplate.css
index ed55fd9..828519a 100644
--- a/pkg/styles/goilerplate.css
+++ b/pkg/styles/goilerplate.css
@@ -938,6 +938,10 @@ body {
flex-shrink: 1;
}
+.shrink-0 {
+ flex-shrink: 0;
+}
+
.-translate-x-1\/2 {
--tw-translate-x: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
@@ -1132,6 +1136,26 @@ body {
border-radius: calc(var(--radius) - 4px);
}
+.rounded-b-lg {
+ border-bottom-right-radius: var(--radius);
+ border-bottom-left-radius: var(--radius);
+}
+
+.rounded-l-lg {
+ border-top-left-radius: var(--radius);
+ border-bottom-left-radius: var(--radius);
+}
+
+.rounded-r-lg {
+ border-top-right-radius: var(--radius);
+ border-bottom-right-radius: var(--radius);
+}
+
+.rounded-t-lg {
+ border-top-left-radius: var(--radius);
+ border-top-right-radius: var(--radius);
+}
+
.border {
border-width: 1px;
}
@@ -1347,6 +1371,11 @@ body {
text-align: center;
}
+.text-2xl {
+ font-size: 1.5rem;
+ line-height: 2rem;
+}
+
.text-base {
font-size: 1rem;
line-height: 1.5rem;