refactor: table

This commit is contained in:
luoxiao 2024-06-06 10:53:04 +08:00
parent 3a097b166b
commit 902da02e30
7 changed files with 180 additions and 132 deletions

View file

@ -187,6 +187,10 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
value: "/components/tab-list".into(), value: "/components/tab-list".into(),
label: "Tab List".into(), label: "Tab List".into(),
}, },
MenuItemOption {
value: "/components/table".into(),
label: "Table".into(),
},
MenuItemOption { MenuItemOption {
value: "/components/tag".into(), value: "/components/tag".into(),
label: "Tag".into(), label: "Tag".into(),
@ -247,10 +251,6 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
value: "/components/image".into(), value: "/components/image".into(),
label: "Image".into(), label: "Image".into(),
}, },
MenuItemOption {
value: "/components/table".into(),
label: "Table".into(),
},
MenuItemOption { MenuItemOption {
value: "/components/anchor".into(), value: "/components/anchor".into(),
label: "Anchor".into(), label: "Anchor".into(),

View file

@ -3,25 +3,37 @@
```rust demo ```rust demo
view! { view! {
<Table> <Table>
<thead> <TableHeader>
<tr> <TableRow>
<th>"tag"</th> <TableHeaderCell>"Tag"</TableHeaderCell>
<th>"count"</th> <TableHeaderCell>"Count"</TableHeaderCell>
<th>"date"</th> <TableHeaderCell>"Date"</TableHeaderCell>
</tr> </TableRow>
</thead> </TableHeader>
<tbody> <TableBody>
<tr> <TableRow>
<td>"div"</td> <TableCell>
<td>"2"</td> <TableCellLayout>
<td>"2023-10-08"</td> "div"
</tr> </TableCellLayout>
<tr> </TableCell>
<td>"span"</td> <TableCell>
<td>"2"</td> <TableCellLayout>
<td>"2023-10-08"</td> "2"
</tr> </TableCellLayout>
</tbody> </TableCell>
<TableCell>
<TableCellLayout>
"2023-10-08"
</TableCellLayout>
</TableCell>
</TableRow>
<TableRow>
<TableCell>"span"</TableCell>
<TableCell>"2"</TableCell>
<TableCell>"2023-10-08"</TableCell>
</TableRow>
</TableBody>
</Table> </Table>
} }
``` ```

View file

@ -96,22 +96,22 @@ fn iter_nodes<'a>(
quote!( quote!(
<div class="demo-md-table-box"> <div class="demo-md-table-box">
<Table single_column=true> <Table>
<thead> <TableHeader>
#(#header_children)* #(#header_children)*
</thead> </TableHeader>
<tbody> <TableBody>
#(#children)* #(#children)*
</tbody> </TableBody>
</Table> </Table>
</div> </div>
) )
} }
NodeValue::TableRow(_) => { NodeValue::TableRow(_) => {
quote!( quote!(
<tr> <TableRow>
#(#children)* #(#children)*
</tr> </TableRow>
) )
} }
NodeValue::TableCell => { NodeValue::TableCell => {
@ -122,15 +122,15 @@ fn iter_nodes<'a>(
}; };
if is_header { if is_header {
quote!( quote!(
<th> <TableHeaderCell>
#(#children)* #(#children)*
</th> </TableHeaderCell>
) )
} else { } else {
quote!( quote!(
<td> <TableCell>
#(#children)* #(#children)*
</td> </TableCell>
) )
} }
} }

View file

@ -1,56 +1,81 @@
mod theme;
pub use theme::TableTheme;
use crate::{theme::use_theme, Theme};
use leptos::*; use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp}; use thaw_components::OptionComp;
use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn Table( pub fn Table(
#[prop(optional, into)] style: MaybeSignal<String>, #[prop(optional, into)] style: MaybeProp<String>,
#[prop(default=true.into(), into)] single_row: MaybeSignal<bool>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
#[prop(optional, into)] single_column: MaybeSignal<bool>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("table", include_str!("./table.css")); mount_style("table", include_str!("./table.css"));
let theme = use_theme(Theme::light);
let css_vars = create_memo(move |_| {
let mut css_vars = String::new();
theme.with(|theme| {
css_vars.push_str(&format!(
"--thaw-background-color: {};",
theme.table.background_color
));
css_vars.push_str(&format!(
"--thaw-background-color-striped: {};",
theme.table.background_color_striped
));
css_vars.push_str(&format!(
"--thaw-border-color: {};",
theme.table.border_color
));
css_vars.push_str(&format!(
"--thaw-border-radius: {};",
theme.common.border_radius
));
});
css_vars
});
view! { view! {
<table <table
class=class_list![ class=class_list!["thaw-table", class]
"thaw-table", ("thaw-table--single-row", move || single_row.get()), style=move || style.get()
("thaw-table--single-column", move || single_column.get()), class.map(| c | move ||
c.get())
]
style=move || format!("{}{}", css_vars.get(), style.get())
> >
{children()} {children()}
</table> </table>
} }
} }
#[component]
pub fn TableHeader(children: Children) -> impl IntoView {
view! {
<thead class="thaw-table-header">
{children()}
</thead>
}
}
#[component]
pub fn TableHeaderCell(#[prop(optional)] children: Option<Children>) -> impl IntoView {
view! {
<th class="thaw-table-header-cell">
<button class="thaw-table-header-cell__button" role="presentation">
<OptionComp value=children let:children>
{children()}
</OptionComp>
</button>
</th>
}
}
#[component]
pub fn TableBody(children: Children) -> impl IntoView {
view! {
<tbody class="thaw-table-body">
{children()}
</tbody>
}
}
#[component]
pub fn TableRow(children: Children) -> impl IntoView {
view! {
<tr class="thaw-table-row">
{children()}
</tr>
}
}
#[component]
pub fn TableCell(#[prop(optional)] children: Option<Children>) -> impl IntoView {
view! {
<td class="thaw-table-cell">
<OptionComp value=children let:children>
{children()}
</OptionComp>
</td>
}
}
#[component]
pub fn TableCellLayout(children: Children) -> impl IntoView {
view! {
<div class="thaw-table-cell-layout">
{children()}
</div>
}
}

View file

@ -1,39 +1,79 @@
.thaw-table { .thaw-table {
display: table;
table-layout: fixed;
vertical-align: middle;
border-collapse: collapse;
width: 100%; width: 100%;
border-collapse: separate; background-color: var(--colorSubtleBackground);
border-spacing: 0;
background-color: var(--thaw-background-color);
border: 1px solid var(--thaw-border-color);
border-radius: var(--thaw-border-radius);
} }
.thaw-table th { .thaw-table-header {
text-align: inherit; display: table-row-group;
background-color: var(--thaw-background-color-striped);
} }
.thaw-table td, .thaw-table-header-cell {
.thaw-table th { position: relative;
padding: 12px; display: table-cell;
border-right: 1px solid var(--thaw-border-color); vertical-align: middle;
border-bottom: 1px solid var(--thaw-border-color); font-weight: var(--fontWeightRegular);
padding: 0px var(--spacingHorizontalS);
} }
.thaw-table.thaw-table--single-row td, .thaw-table-header-cell__button {
.thaw-table.thaw-table--single-row th { position: relative;
border-right: none; display: flex;
} flex: 1 1 0px;
.thaw-table.thaw-table--single-column td { align-items: center;
border-bottom: none; gap: var(--spacingHorizontalXS);
} padding: 0px;
.thaw-table td:last-child, width: 100%;
.thaw-table th:last-child { height: 100%;
border-right: none; min-height: 32px;
text-align: unset;
font-family: inherit;
font-size: inherit;
line-height: normal;
color: inherit;
background-color: inherit;
box-sizing: content-box;
resize: horizontal;
overflow: visible;
outline-style: none;
border: none;
} }
.thaw-table tbody tr:last-child td { .thaw-table-body {
border-bottom: none; display: table-row-group;
} }
.thaw-table tr {
border-bottom: 1px solid var(--thaw-border-color); .thaw-table-row {
display: table-row;
box-sizing: border-box;
color: var(--colorNeutralForeground1);
border-bottom: var(--strokeWidthThin) solid var(--colorNeutralStroke2);
}
.thaw-table-body > .thaw-table-row:hover {
color: var(--colorNeutralForeground1Hover);
background-color: var(--colorSubtleBackgroundHover);
}
.thaw-table-body > .thaw-table-row:active {
color: var(--colorNeutralForeground1Pressed);
background-color: var(--colorSubtleBackgroundPressed);
}
.thaw-table-cell {
position: relative;
height: 44px;
display: table-cell;
vertical-align: middle;
padding: 0px var(--spacingHorizontalS);
}
.thaw-table-cell-layout {
display: flex;
flex: 1 1 0px;
align-items: center;
gap: var(--spacingHorizontalS);
} }

View file

@ -1,26 +0,0 @@
use crate::theme::ThemeMethod;
#[derive(Clone)]
pub struct TableTheme {
pub background_color: String,
pub background_color_striped: String,
pub border_color: String,
}
impl ThemeMethod for TableTheme {
fn light() -> Self {
Self {
background_color: "#fff".into(),
background_color_striped: "#fafafc".into(),
border_color: "#efeff5".into(),
}
}
fn dark() -> Self {
Self {
background_color: "#18181c".into(),
background_color_striped: "#26262a".into(),
border_color: "#2d2d30".into(),
}
}
}

View file

@ -6,7 +6,7 @@ use crate::{
mobile::{NavBarTheme, TabbarTheme}, mobile::{NavBarTheme, TabbarTheme},
AlertTheme, AnchorTheme, AutoCompleteTheme, BackTopTheme, CalendarTheme, ColorPickerTheme, AlertTheme, AnchorTheme, AutoCompleteTheme, BackTopTheme, CalendarTheme, ColorPickerTheme,
DatePickerTheme, InputTheme, MessageTheme, PopoverTheme, ProgressTheme, ScrollbarTheme, DatePickerTheme, InputTheme, MessageTheme, PopoverTheme, ProgressTheme, ScrollbarTheme,
SelectTheme, TableTheme, TimePickerTheme, UploadTheme, SelectTheme, TimePickerTheme, UploadTheme,
}; };
pub use color::ColorTheme; pub use color::ColorTheme;
use leptos::*; use leptos::*;
@ -22,7 +22,6 @@ pub struct Theme {
pub common: CommonTheme, pub common: CommonTheme,
pub color: ColorTheme, pub color: ColorTheme,
pub input: InputTheme, pub input: InputTheme,
pub table: TableTheme,
pub alert: AlertTheme, pub alert: AlertTheme,
pub message: MessageTheme, pub message: MessageTheme,
pub select: SelectTheme, pub select: SelectTheme,
@ -48,7 +47,6 @@ impl Theme {
common: CommonTheme::light(), common: CommonTheme::light(),
color: ColorTheme::light(), color: ColorTheme::light(),
input: InputTheme::light(), input: InputTheme::light(),
table: TableTheme::light(),
alert: AlertTheme::light(), alert: AlertTheme::light(),
message: MessageTheme::light(), message: MessageTheme::light(),
select: SelectTheme::light(), select: SelectTheme::light(),
@ -73,7 +71,6 @@ impl Theme {
common: CommonTheme::dark(), common: CommonTheme::dark(),
color: ColorTheme::dark(), color: ColorTheme::dark(),
input: InputTheme::dark(), input: InputTheme::dark(),
table: TableTheme::dark(),
alert: AlertTheme::dark(), alert: AlertTheme::dark(),
message: MessageTheme::dark(), message: MessageTheme::dark(),
select: SelectTheme::dark(), select: SelectTheme::dark(),