Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(table): New table component #100

Merged
merged 6 commits into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions assets/css/output.css
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,9 @@
.shrink-0 {
flex-shrink: 0;
}
.caption-bottom {
caption-side: bottom;
}
.border-collapse {
border-collapse: collapse;
}
Expand Down Expand Up @@ -1376,6 +1379,9 @@
.text-left {
text-align: left;
}
.align-middle {
vertical-align: middle;
}
.text-2xl {
font-size: var(--text-2xl);
line-height: var(--tw-leading, var(--text-2xl--line-height));
Expand Down Expand Up @@ -1998,6 +2004,13 @@
}
}
}
.hover\:bg-muted\/50 {
&:hover {
@media (hover: hover) {
background-color: color-mix(in oklab, var(--muted) 50%, transparent);
}
}
}
.hover\:bg-primary\/90 {
&:hover {
@media (hover: hover) {
Expand Down Expand Up @@ -2380,6 +2393,18 @@
line-height: var(--leading-relaxed);
}
}
.\[\&_tr\]\:border-b {
& tr {
border-bottom-style: var(--tw-border-style);
border-bottom-width: 1px;
}
}
.\[\&_tr\:last-child\]\:border-0 {
& tr:last-child {
border-style: var(--tw-border-style);
border-width: 0px;
}
}
.\[\&\.htmx-request\]\:inline-flex {
&.htmx-request {
display: inline-flex;
Expand Down Expand Up @@ -2459,11 +2484,31 @@
}
}
}
.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0 {
&:has([role=checkbox]) {
padding-right: calc(var(--spacing) * 0);
}
}
.\[\&\:has\(svg\)\]\:pl-11 {
&:has(svg) {
padding-left: calc(var(--spacing) * 11);
}
}
.\[\&\:not\(\.bg-primary\)\]\:hover\:bg-muted {
&:not(.bg-primary) {
&:hover {
@media (hover: hover) {
background-color: var(--muted);
}
}
}
}
.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\] {
&>[role=checkbox] {
--tw-translate-y: 2px;
translate: var(--tw-translate-x) var(--tw-translate-y);
}
}
.open\:\[\&\>summary_svg\]\:rotate-180 {
&:is([open], :popover-open, :open) {
&>summary svg {
Expand Down Expand Up @@ -2492,11 +2537,28 @@
translate: var(--tw-translate-x) var(--tw-translate-y);
}
}
.\[\&\>tr\]\:last\:border-b-0 {
&>tr {
&:last-child {
border-bottom-style: var(--tw-border-style);
border-bottom-width: 0px;
}
}
}
.\[\&amp\;\.htmx-request\]\:inline-flex {
&.htmx-request {
display: inline-flex;
}
}
.\[\&amp\;\:not\(\.bg-primary\)\]\:hover\:bg-muted {
&:not(.bg-primary) {
&:hover {
@media (hover: hover) {
background-color: var(--muted);
}
}
}
}
}
:root {
--background: hsl(0 0% 100%);
Expand Down
1 change: 1 addition & 0 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func main() {
mux.Handle("GET /docs/components/skeleton", templ.Handler(pages.Skeleton()))
mux.Handle("GET /docs/components/slider", templ.Handler(pages.Slider()))
mux.Handle("GET /docs/components/spinner", templ.Handler(pages.Spinner()))
mux.Handle("GET /docs/components/table", templ.Handler(pages.Table()))
mux.Handle("GET /docs/components/tabs", templ.Handler(pages.Tabs()))
mux.Handle("GET /docs/components/textarea", templ.Handler(pages.Textarea()))
// mux.Handle("GET /docs/components/time-picker", templ.Handler(pages.TimePicker()))
Expand Down
137 changes: 137 additions & 0 deletions components/table.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package components

import "github.com/axzilla/templui/utils"

type TableProps struct {
ID string
Class string
Attributes templ.Attributes
}

type TableHeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}

type TableBodyProps struct {
ID string
Class string
Attributes templ.Attributes
}

type TableFooterProps struct {
ID string
Class string
Attributes templ.Attributes
}

type TableRowProps struct {
ID string
Class string
Attributes templ.Attributes
Selected bool
}

type TableHeadProps struct {
ID string
Class string
Attributes templ.Attributes
}

type TableCellProps struct {
ID string
Class string
Attributes templ.Attributes
}

type TableCaptionProps struct {
ID string
Class string
Attributes templ.Attributes
}

templ Table(props TableProps) {
<div class="relative w-full overflow-auto">
<table
id={ props.ID }
class={ utils.TwMerge("w-full caption-bottom text-sm", props.Class) }
{ props.Attributes... }
>
{ children... }
</table>
</div>
}

templ TableHeader(props TableHeaderProps) {
<thead
id={ props.ID }
class={ utils.TwMerge("[&_tr]:border-b", props.Class) }
{ props.Attributes... }
>
{ children... }
</thead>
}

templ TableBody(props TableBodyProps) {
<tbody
id={ props.ID }
class={ utils.TwMerge("[&_tr:last-child]:border-0", props.Class) }
{ props.Attributes... }
>
{ children... }
</tbody>
}

templ TableFooter(props TableFooterProps) {
<tfoot
id={ props.ID }
class={ utils.TwMerge("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", props.Class) }
{ props.Attributes... }
>
{ children... }
</tfoot>
}

templ TableRow(props TableRowProps) {
<tr
id={ props.ID }
class={
utils.TwMerge("border-b transition-colors hover:bg-muted/50", props.Class),
templ.KV("data-[state=selected]:bg-muted", props.Selected),
}
{ props.Attributes... }
>
{ children... }
</tr>
}

templ TableHead(props TableHeadProps) {
<th
id={ props.ID }
class={ utils.TwMerge("h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", props.Class) }
{ props.Attributes... }
>
{ children... }
</th>
}

templ TableCell(props TableCellProps) {
<td
id={ props.ID }
class={ utils.TwMerge("p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", props.Class) }
{ props.Attributes... }
>
{ children... }
</td>
}

templ TableCaption(props TableCaptionProps) {
<caption
id={ props.ID }
class={ utils.TwMerge("mt-4 text-sm text-muted-foreground", props.Class) }
{ props.Attributes... }
>
{ children... }
</caption>
}
Loading