Skip to content
Draft
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
1 change: 1 addition & 0 deletions preview/src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,5 @@ examples!(
toggle,
toolbar,
tooltip,
table,
);
7 changes: 7 additions & 0 deletions preview/src/components/table/component.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "table",
"description": "A data table component with filtering, sorting, column visibility, row selection, and pagination.",
"authors": ["Fakhir"],
"exclude": ["variants", "docs.md", "component.json"],
"styled": true
}
9 changes: 9 additions & 0 deletions preview/src/components/table/component.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use dioxus::prelude::*;

#[component]
pub fn DemoWithStyles() -> Element {
rsx! {
document::Link { rel: "stylesheet", href: asset!("./style.css") }
super::variants::main::Demo {}
}
}
28 changes: 28 additions & 0 deletions preview/src/components/table/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
The Table component displays structured data with support for filtering, column visibility toggling, row selection, sortable columns, and pagination.

## Component Structure

```rust
// The Demo component renders a fully functional data table
Demo {}
```

## Features

- **Filter**: Type in the search box to filter rows by email in real time.
- **Column Visibility**: Click the "Columns" button to show or hide the Status, Email, and Amount columns.
- **Row Selection**: Use the checkboxes to select individual rows or all rows at once.
- **Sorting**: Click the Email column header to toggle ascending/descending sort order.
- **Row Actions**: Click the `···` button on any row to open a context menu with actions like "Copy payment ID", "View customer", and "View payment details".
- **Pagination**: Previous and Next buttons are shown in the footer along with a selected row count.

## Data Structure

```rust
struct Payment {
id: usize,
status: &'static str, // "Success" | "Processing" | "Failed"
email: &'static str,
amount: &'static str,
}
```
3 changes: 3 additions & 0 deletions preview/src/components/table/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod variants;
mod component;
pub use component::Demo;
308 changes: 308 additions & 0 deletions preview/src/components/table/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
.dx-table-wrapper {
background-color: var(--background, #1a1a1a);
border: 1px solid var(--border-color, #2e2e2e);
border-radius: 0.75rem;
overflow: hidden;
font-family: inherit;
color: var(--foreground, #e5e5e5);
}

.dx-table-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.875rem 1rem;
gap: 0.75rem;
}

.dx-table-filter {
flex: 1;
max-width: 20rem;
padding: 0.4rem 0.75rem;
border: 1px solid var(--border-color, #3a3a3a);
border-radius: 0.375rem;
background-color: transparent;
color: var(--foreground, #e5e5e5);
font-size: 0.875rem;
outline: none;
transition: border-color 150ms;
}

.dx-table-filter::placeholder {
color: var(--foreground-muted, #6b7280);
}

.dx-table-filter:focus {
border-color: var(--border-focus, #6b7280);
}

.dx-columns-btn {
display: flex;
align-items: center;
gap: 0.3rem;
padding: 0.4rem 0.875rem;
border: 1px solid var(--border-color, #3a3a3a);
border-radius: 0.375rem;
background-color: transparent;
color: var(--foreground, #e5e5e5);
font-size: 0.875rem;
cursor: pointer;
white-space: nowrap;
transition: background-color 150ms;
}

.dx-columns-btn:hover {
background-color: var(--background-hover, #2a2a2a);
}

.dx-chevron {
font-size: 0.75rem;
opacity: 0.7;
}

.dx-table-container {
overflow-x: auto;
border-top: 1px solid var(--border-color, #2e2e2e);
}

.dx-table {
width: 100%;
border-collapse: collapse;
font-size: 0.875rem;
}

.dx-table thead tr {
border-bottom: 1px solid var(--border-color, #2e2e2e);
}

.dx-table th {
padding: 0.6rem 0.75rem;
text-align: left;
font-weight: 600;
font-size: 0.8rem;
color: var(--foreground, #e5e5e5);
white-space: nowrap;
}

.dx-table td {
padding: 0.65rem 0.75rem;
border-bottom: 1px solid var(--border-color, #222222);
color: var(--foreground-muted, #a1a1aa);
}

.dx-table tbody tr:last-child td {
border-bottom: none;
}

.dx-row:hover td {
background-color: var(--background-hover, #222222);
}

.dx-row-selected td {
background-color: var(--background-selected, #1e2a1e);
}

/* .dx-checkbox {
width: 1rem;
height: 1rem;
accent-color: var(--foreground, #e5e5e5);
cursor: pointer;
} */

.dx-checkbox {
width: 1rem;
height: 1rem;
accent-color: var(--foreground, #e5e5e5);
cursor: pointer;
appearance: none;
-webkit-appearance: none;
border: 1.5px solid #6b7280;
border-radius: 0.2rem;
background-color: transparent;
position: relative;
transition: all 150ms;
}

.dx-checkbox:checked {
background-color: #ffffff;
border-color: #ffffff;
}

.dx-checkbox:checked::after {
content: "";
position: absolute;
left: 50%;
top: 45%;
width: 0.3rem;
height: 0.55rem;
border: 2.5px solid #000000;
border-top: none;
border-left: none;
transform: translate(-50%, -50%) rotate(45deg);
}

.dx-sort-btn {
background: none;
border: none;
color: var(--foreground, #e5e5e5);
font-size: 0.8rem;
font-weight: 600;
cursor: pointer;
padding: 0;
display: inline-flex;
align-items: center;
gap: 0.25rem;
}

.dx-col-amount {
text-align: right !important;
font-variant-numeric: tabular-nums;
color: var(--foreground, #e5e5e5) !important;
}

.dx-badge {
display: inline-flex;
align-items: center;
padding: 0.2rem 0.6rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 500;
}

.dx-badge-success {
background-color: transparent;
color: var(--foreground-muted, #a1a1aa);
}

.dx-badge-processing {
background-color: transparent;
color: var(--foreground-muted, #a1a1aa);
}

.dx-badge-failed {
background-color: transparent;
color: var(--foreground-muted, #a1a1aa);
}

.dx-action-btn {
background: none;
border: none;
color: var(--foreground-muted, #6b7280);
cursor: pointer;
font-size: 1rem;
padding: 0 0.25rem;
letter-spacing: 0.05em;
transition: color 150ms;
}

.dx-action-btn:hover {
color: var(--foreground, #e5e5e5);
}

.dx-table-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1rem;
border-top: 1px solid var(--border-color, #2e2e2e);
}

.dx-footer-info {
font-size: 0.8rem;
color: var(--foreground-muted, #6b7280);
}

.dx-pagination-buttons {
display: flex;
gap: 0.5rem;
}

.dx-pagination-button {
padding: 0.3rem 0.875rem;
border: 1px solid var(--border-color, #3a3a3a);
border-radius: 0.375rem;
font-size: 0.8rem;
background-color: transparent;
color: var(--foreground, #e5e5e5);
cursor: pointer;
transition: background-color 150ms;
}

.dx-pagination-button:hover {
background-color: var(--background-hover, #2a2a2a);
}

/* Action Menu (Dropdown) */
.dx-action-menu {
position: absolute;
top: 100%;
right: 0;
margin-top: 0.25rem;
background-color: var(--background, #1a1a1a);
border: 1px solid var(--border-color, #2e2e2e);
border-radius: 0.5rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
min-width: 150px;
z-index: 20;
overflow: hidden;
}

.dx-action-menu button {
display: block;
width: 100%;
text-align: left;
padding: 0.5rem 1rem;
background: none;
border: none;
color: var(--foreground, #e5e5e5);
font-size: 0.8rem;
cursor: pointer;
transition: background-color 0.15s;
white-space: nowrap;
}

.dx-action-menu button:hover {
background-color: var(--background-hover, #2a2a2a);
}

/* Overlay to close menu when clicking outside */
.dx-menu-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
}
/* Columns dropdown */
.dx-columns-menu {
position: absolute;
right: 0;
top: calc(100% + 0.25rem);
z-index: 50;
background-color: var(--background, #1a1a1a);
border: 1px solid var(--border-color, #2e2e2e);
border-radius: 0.5rem;
padding: 0.5rem;
min-width: 10rem;
display: flex;
flex-direction: column;
gap: 0.25rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}

.dx-columns-item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.35rem 0.5rem;
border-radius: 0.25rem;
cursor: pointer;
font-size: 0.875rem;
color: var(--foreground, #e5e5e5);
transition: background-color 150ms;
}

.dx-columns-item:hover {
background-color: var(--background-hover, #2a2a2a);
}
Loading