mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 21:27:06 +04:00
Add .datagrid-horizontal and .datagrid-cols-{n} classes, more datagrid examples (#3247)
This commit is contained in:
1 parent
a1b46ae15e
commit
ace9a4f123
9 files changed
+651
-26
No files matched your search
@@ -3,8 +3,6 @@
|
|||||||
callout-note
|
callout-note
|
||||||
clipboard-feedback
|
clipboard-feedback
|
||||||
clipboard-label
|
clipboard-label
|
||||||
datagrid-content
|
|
||||||
datagrid-item
|
|
||||||
datatable
|
datatable
|
||||||
docs-classnames
|
docs-classnames
|
||||||
docs-page-lead
|
docs-page-lead
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@tabler/core": minor
|
||||||
|
"@tabler/preview": minor
|
||||||
|
"@tabler/docs": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Added `.datagrid-horizontal` and `.datagrid-cols-{n}` classes and more datagrid examples and docs.
|
||||||
@@ -1357,6 +1357,8 @@ $btn-close-white-filter: invert(1) grayscale(100%) brightness(200%) !default; //
|
|||||||
$datagrid-padding: 1.5rem !default;
|
$datagrid-padding: 1.5rem !default;
|
||||||
$datagrid-item-width: 15rem !default;
|
$datagrid-item-width: 15rem !default;
|
||||||
$datagrid-title-margin-bottom: 0.25rem !default;
|
$datagrid-title-margin-bottom: 0.25rem !default;
|
||||||
|
$datagrid-title-width: 10rem !default;
|
||||||
|
$datagrid-columns: 4 !default;
|
||||||
// scss-docs-end datagrid-variables
|
// scss-docs-end datagrid-variables
|
||||||
|
|
||||||
// Empty
|
// Empty
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
--datagrid-padding: #{$datagrid-padding};
|
--datagrid-padding: #{$datagrid-padding};
|
||||||
--datagrid-item-width: #{$datagrid-item-width};
|
--datagrid-item-width: #{$datagrid-item-width};
|
||||||
--datagrid-title-margin-bottom: #{$datagrid-title-margin-bottom};
|
--datagrid-title-margin-bottom: #{$datagrid-title-margin-bottom};
|
||||||
|
--datagrid-title-width: #{$datagrid-title-width};
|
||||||
// scss-docs-end datagrid-css-vars
|
// scss-docs-end datagrid-css-vars
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -20,3 +21,26 @@
|
|||||||
@include subheader();
|
@include subheader();
|
||||||
margin-bottom: var(--datagrid-title-margin-bottom);
|
margin-bottom: var(--datagrid-title-margin-bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.datagrid-content {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datagrid-horizontal {
|
||||||
|
--datagrid-title-margin-bottom: 0;
|
||||||
|
|
||||||
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
|
||||||
|
.datagrid-item {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: var(--datagrid-title-width) 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@for $i from 1 through $datagrid-columns {
|
||||||
|
.datagrid-cols-#{$i} {
|
||||||
|
grid-template-columns: repeat(#{$i}, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
title: Data grid
|
title: Data grid
|
||||||
summary: Use the data grid component to display detailed information about your product. The data is displayed as a column of items consisting of a title and content.
|
summary: Use the data grid component to display detailed information about your product. The data is displayed as a column of items consisting of a title and content.
|
||||||
description: Display labeled data in a compact datagrid - a responsive list of title and content pairs, ideal for detail panels and summaries.
|
description: Display labeled data in a compact datagrid - a responsive list of title and content pairs, ideal for detail panels and summaries.
|
||||||
related: [/ui/components/table]
|
related: [/ui/components/table, /ui/plugins/clipboard]
|
||||||
source: core/scss/ui/_datagrid.scss
|
source: core/scss/ui/_datagrid.scss
|
||||||
css-vars: datagrid
|
css-vars: datagrid
|
||||||
classnames:
|
classnames:
|
||||||
@@ -10,8 +10,18 @@ classnames:
|
|||||||
- class: datagrid
|
- class: datagrid
|
||||||
desc: Container element, a responsive grid of label and value pairs
|
desc: Container element, a responsive grid of label and value pairs
|
||||||
part:
|
part:
|
||||||
|
- class: datagrid-item
|
||||||
|
desc: One label and value pair
|
||||||
- class: datagrid-title
|
- class: datagrid-title
|
||||||
desc: Label above a value
|
desc: Label of a value, styled as a subheader
|
||||||
|
- class: datagrid-content
|
||||||
|
desc: Value of the pair, with the margin reset so a dd fits
|
||||||
|
modifier:
|
||||||
|
- class: datagrid-cols-{n}
|
||||||
|
desc: Fixed number of columns, from 1 to 4
|
||||||
|
direction:
|
||||||
|
- class: datagrid-horizontal
|
||||||
|
desc: Puts the label beside the value and shows one pair per row
|
||||||
---
|
---
|
||||||
import Example from '@components/Example.astro';
|
import Example from '@components/Example.astro';
|
||||||
import Icon from '@ui/Icon.astro'
|
import Icon from '@ui/Icon.astro'
|
||||||
@@ -116,14 +126,264 @@ A value is a plain container, so it takes anything: text, [avatars](/ui/componen
|
|||||||
</div>
|
</div>
|
||||||
</Example>
|
</Example>
|
||||||
|
|
||||||
|
## Horizontal
|
||||||
|
|
||||||
|
Add the `.datagrid-horizontal` class to put the label beside the value. Each pair takes a full row, which is easy to scan when the values are long.
|
||||||
|
|
||||||
|
<Example>
|
||||||
|
<div class="datagrid datagrid-horizontal">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Plan</div>
|
||||||
|
<div class="datagrid-content">Business</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Status</div>
|
||||||
|
<div class="datagrid-content"><span class="status status-green">Active</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Address</div>
|
||||||
|
<div class="datagrid-content">44 Harbor Street, Portland, OR 97209, United States</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Example>
|
||||||
|
|
||||||
|
Set `--tblr-datagrid-title-width` to change the width of the label column. Add a `.datagrid-cols-{n}` class to show several pairs in a row.
|
||||||
|
|
||||||
|
<Example>
|
||||||
|
<div class="datagrid datagrid-horizontal datagrid-cols-2" style="--tblr-datagrid-title-width: 5rem">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">CPU</div>
|
||||||
|
<div class="datagrid-content">8 cores</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Memory</div>
|
||||||
|
<div class="datagrid-content">32 GB</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Storage</div>
|
||||||
|
<div class="datagrid-content">512 GB</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Region</div>
|
||||||
|
<div class="datagrid-content">eu-central</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Example>
|
||||||
|
|
||||||
## Column width
|
## Column width
|
||||||
|
|
||||||
Columns are generated with `auto-fit`, so the item width decides how many fit in a row. Set the two custom properties on the `.datagrid` element to change the layout:
|
Columns are generated with `auto-fit`, so the item width decides how many fit in a row. Set the custom properties on the `.datagrid` element to change the layout:
|
||||||
|
|
||||||
| Variable | Description | Default |
|
| Variable | Description | Default |
|
||||||
|------------------------------|--------------------------------|----------|
|
|------------------------------|--------------------------------------|----------|
|
||||||
| `--tblr-datagrid-item-width` | Width of the datagrid item | `15rem` |
|
| `--tblr-datagrid-item-width` | Minimum width of a column | `15rem` |
|
||||||
| `--tblr-datagrid-padding` | Gap between the datagrid items | `1.5rem` |
|
| `--tblr-datagrid-padding` | Gap between the items | `1.5rem` |
|
||||||
|
| `--tblr-datagrid-title-width`| Label column in a horizontal datagrid| `10rem` |
|
||||||
|
|
||||||
|
Use a lower item width for short values, such as numbers or single words. More columns then fit in a row.
|
||||||
|
|
||||||
|
<Example>
|
||||||
|
<div class="datagrid" style="--tblr-datagrid-item-width: 7rem">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">CPU</div>
|
||||||
|
<div class="datagrid-content">8 cores</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Memory</div>
|
||||||
|
<div class="datagrid-content">32 GB</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Storage</div>
|
||||||
|
<div class="datagrid-content">512 GB</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Region</div>
|
||||||
|
<div class="datagrid-content">eu-central</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Uptime</div>
|
||||||
|
<div class="datagrid-content">99.98%</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Backups</div>
|
||||||
|
<div class="datagrid-content">Daily</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Example>
|
||||||
|
|
||||||
|
### Fixed number of columns
|
||||||
|
|
||||||
|
Add a `.datagrid-cols-{n}` class to keep the same number of columns at any container width. The classes go from `.datagrid-cols-1` to `.datagrid-cols-4`. The item width is ignored then.
|
||||||
|
|
||||||
|
<Example>
|
||||||
|
<div class="datagrid datagrid-cols-2">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Order</div>
|
||||||
|
<div class="datagrid-content">#48213</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Status</div>
|
||||||
|
<div class="datagrid-content"><span class="badge bg-green-lt">Paid</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Placed</div>
|
||||||
|
<div class="datagrid-content">September 12, 2026</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Total</div>
|
||||||
|
<div class="datagrid-content"><strong>$248.00</strong></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Example>
|
||||||
|
|
||||||
|
A single column works well in a narrow sidebar or an offcanvas.
|
||||||
|
|
||||||
|
<Example>
|
||||||
|
<div class="datagrid datagrid-cols-1">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Email</div>
|
||||||
|
<div class="datagrid-content"><a href="#">billing@tabler.io</a></div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Shipping address</div>
|
||||||
|
<div class="datagrid-content">44 Harbor Street, Portland, OR 97209, United States</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Notes</div>
|
||||||
|
<div class="datagrid-content text-secondary">Not set</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Example>
|
||||||
|
|
||||||
|
### Gap
|
||||||
|
|
||||||
|
Lower `--tblr-datagrid-padding` to make a dense datagrid. The same value is used between columns and between rows.
|
||||||
|
|
||||||
|
<Example>
|
||||||
|
<div class="datagrid" style="--tblr-datagrid-item-width: 7rem; --tblr-datagrid-padding: 0.75rem">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">CPU</div>
|
||||||
|
<div class="datagrid-content">8 cores</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Memory</div>
|
||||||
|
<div class="datagrid-content">32 GB</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Storage</div>
|
||||||
|
<div class="datagrid-content">512 GB</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Region</div>
|
||||||
|
<div class="datagrid-content">eu-central</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Uptime</div>
|
||||||
|
<div class="datagrid-content">99.98%</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Backups</div>
|
||||||
|
<div class="datagrid-content">Daily</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Example>
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Inside a card
|
||||||
|
|
||||||
|
A datagrid has no border or background of its own. Put it in a [card](/ui/components/card) to build a detail panel. The card header holds the title and the footer holds the actions.
|
||||||
|
|
||||||
|
<Example bg="surface-secondary">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Domain details</h3>
|
||||||
|
<div class="card-actions">
|
||||||
|
<a href="#" class="btn btn-sm"><Icon name="pencil" /> Edit</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="datagrid" style="--tblr-datagrid-item-width: 12rem">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Domain</div>
|
||||||
|
<div class="datagrid-content"><a href="#">tabler.io</a></div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Registrar</div>
|
||||||
|
<div class="datagrid-content">Third Party</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">SSL certificate</div>
|
||||||
|
<div class="datagrid-content"><Icon name="lock" class="text-green" inline /> Valid until May 2, 2027</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Expiration date</div>
|
||||||
|
<div class="datagrid-content">–</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer text-end">
|
||||||
|
<button type="button" class="btn btn-primary">Renew domain</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Example>
|
||||||
|
|
||||||
|
### Statuses and progress
|
||||||
|
|
||||||
|
Show the state of a resource with a [status](/ui/components/status), a [badge](/ui/components/badge) or a [progress bar](/ui/components/progress).
|
||||||
|
|
||||||
|
<Example>
|
||||||
|
<div class="datagrid">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">State</div>
|
||||||
|
<div class="datagrid-content"><span class="status status-green">Running</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Environment</div>
|
||||||
|
<div class="datagrid-content"><span class="badge bg-blue-lt">Production</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Disk usage</div>
|
||||||
|
<div class="datagrid-content">
|
||||||
|
<div class="mb-1">68%</div>
|
||||||
|
<div class="progress progress-sm">
|
||||||
|
<div class="progress-bar" style="width: 68%" role="progressbar" aria-valuenow="68" aria-valuemin="0" aria-valuemax="100" aria-label="68% used"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Example>
|
||||||
|
|
||||||
|
### Values to copy
|
||||||
|
|
||||||
|
Add a [clipboard](/ui/plugins/clipboard) button next to a value that users copy, such as an API key. Point `data-bs-target` at the element with the value and give the button an `aria-label` that names it.
|
||||||
|
|
||||||
|
<Example>
|
||||||
|
<div class="datagrid datagrid-cols-1">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Client ID</div>
|
||||||
|
<div class="datagrid-content d-flex align-items-center gap-2">
|
||||||
|
<code id="datagrid-client-id">tblr_live_8f3a2c91d7e4</code>
|
||||||
|
<button type="button" class="btn btn-sm btn-icon btn-action" data-bs-toggle="clipboard" data-bs-target="#datagrid-client-id" aria-label="Copy the client ID">
|
||||||
|
<Icon name="clipboard" class="clipboard-label" />
|
||||||
|
<Icon name="check" class="clipboard-feedback text-green" />
|
||||||
|
<span class="clipboard-feedback visually-hidden">Copied</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">Webhook URL</div>
|
||||||
|
<div class="datagrid-content d-flex align-items-center gap-2">
|
||||||
|
<code id="datagrid-webhook-url">https://example.com/hooks/tabler</code>
|
||||||
|
<button type="button" class="btn btn-sm btn-icon btn-action" data-bs-toggle="clipboard" data-bs-target="#datagrid-webhook-url" aria-label="Copy the webhook URL">
|
||||||
|
<Icon name="clipboard" class="clipboard-label" />
|
||||||
|
<Icon name="check" class="clipboard-feedback text-green" />
|
||||||
|
<span class="clipboard-feedback visually-hidden">Copied</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Example>
|
||||||
|
|
||||||
## Accessibility
|
## Accessibility
|
||||||
|
|
||||||
@@ -138,11 +398,11 @@ The pairs are only visually connected, so tell assistive tech how they belong to
|
|||||||
<dl class="datagrid">
|
<dl class="datagrid">
|
||||||
<div class="datagrid-item">
|
<div class="datagrid-item">
|
||||||
<dt class="datagrid-title">Registrar</dt>
|
<dt class="datagrid-title">Registrar</dt>
|
||||||
<dd class="datagrid-content mb-0">Third Party</dd>
|
<dd class="datagrid-content">Third Party</dd>
|
||||||
</div>
|
</div>
|
||||||
<div class="datagrid-item">
|
<div class="datagrid-item">
|
||||||
<dt class="datagrid-title">Expiration date</dt>
|
<dt class="datagrid-title">Expiration date</dt>
|
||||||
<dd class="datagrid-content mb-0">–</dd>
|
<dd class="datagrid-content">–</dd>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
</Example>
|
</Example>
|
||||||
@@ -3,17 +3,271 @@ import DefaultLayout from '@shared/layouts/DefaultLayout.astro'
|
|||||||
import Card from '@ui/Card.astro'
|
import Card from '@ui/Card.astro'
|
||||||
import CardHeader from '@ui/CardHeader.astro'
|
import CardHeader from '@ui/CardHeader.astro'
|
||||||
import CardBody from '@ui/CardBody.astro'
|
import CardBody from '@ui/CardBody.astro'
|
||||||
import Datagrid from '@shared/components/parts/Datagrid.astro'
|
import CardFooter from '@ui/CardFooter.astro'
|
||||||
|
import CardTitle from '@ui/CardTitle.astro'
|
||||||
|
import CardSubtitle from '@ui/CardSubtitle.astro'
|
||||||
|
import CardActions from '@ui/CardActions.astro'
|
||||||
|
import Avatar from '@ui/Avatar.astro'
|
||||||
|
import Badge from '@ui/Badge.astro'
|
||||||
|
import Button from '@ui/Button.astro'
|
||||||
|
import ButtonList from '@ui/ButtonList.astro'
|
||||||
|
import Icon from '@ui/Icon.astro'
|
||||||
|
import Progress from '@ui/Progress.astro'
|
||||||
|
import Datagrid from '@ui/Datagrid.astro'
|
||||||
|
import DatagridItem from '@ui/DatagridItem.astro'
|
||||||
|
import DatagridDemo from '@shared/components/parts/Datagrid.astro'
|
||||||
import DocsLink from '@ui/DocsLink.astro'
|
import DocsLink from '@ui/DocsLink.astro'
|
||||||
|
import { people } from '@shared/lib/people'
|
||||||
|
import { requireIndex } from '@shared/lib/array'
|
||||||
|
|
||||||
|
const customer = requireIndex(people, 2)
|
||||||
|
const owner = requireIndex(people, 4)
|
||||||
---
|
---
|
||||||
|
|
||||||
<DefaultLayout title="Data grid" pageMenu="base.datagrid" description="A data grid lays out label/value pairs in a compact, aligned grid.">
|
<DefaultLayout title="Data grid" pageMenu="base.datagrid" description="A data grid lays out label/value pairs in a compact, aligned grid.">
|
||||||
<DocsLink slot="page-header-actions" path="/ui/components/datagrid" />
|
<DocsLink slot="page-header-actions" path="/ui/components/datagrid" />
|
||||||
|
|
||||||
<Card>
|
<div class="row row-cards">
|
||||||
<CardHeader title="Base info" />
|
<div class="col-12">
|
||||||
<CardBody>
|
<Card>
|
||||||
<Datagrid />
|
<CardHeader title="Base info" />
|
||||||
</CardBody>
|
<CardBody>
|
||||||
</Card>
|
<DatagridDemo />
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Basic</CardTitle>
|
||||||
|
<CardSubtitle>A <code>.datagrid</code> with plain text values.</CardSubtitle>
|
||||||
|
<Datagrid>
|
||||||
|
<DatagridItem title="Plan">Business</DatagridItem>
|
||||||
|
<DatagridItem title="Billing period">Monthly</DatagridItem>
|
||||||
|
<DatagridItem title="Next invoice">October 18, 2026</DatagridItem>
|
||||||
|
<DatagridItem title="Seats">8 of 10 used</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Description list</CardTitle>
|
||||||
|
<CardSubtitle>Use <code>dl</code>, <code>dt</code> and <code>dd</code> so screen readers announce the pairs.</CardSubtitle>
|
||||||
|
<Datagrid as="dl">
|
||||||
|
<DatagridItem list title="Company">Tabler Ltd.</DatagridItem>
|
||||||
|
<DatagridItem list title="Tax ID">EU123456789</DatagridItem>
|
||||||
|
<DatagridItem list title="Billing email">billing@tabler.io</DatagridItem>
|
||||||
|
<DatagridItem list title="Country">Poland</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Narrow columns</CardTitle>
|
||||||
|
<CardSubtitle>Lower <code>--tblr-datagrid-item-width</code> to fit more columns in a row.</CardSubtitle>
|
||||||
|
<Datagrid itemWidth="7rem">
|
||||||
|
<DatagridItem title="CPU">8 cores</DatagridItem>
|
||||||
|
<DatagridItem title="Memory">32 GB</DatagridItem>
|
||||||
|
<DatagridItem title="Storage">512 GB</DatagridItem>
|
||||||
|
<DatagridItem title="Region">eu-central</DatagridItem>
|
||||||
|
<DatagridItem title="Uptime">99.98%</DatagridItem>
|
||||||
|
<DatagridItem title="Backups">Daily</DatagridItem>
|
||||||
|
<DatagridItem title="IPv6">Enabled</DatagridItem>
|
||||||
|
<DatagridItem title="Port">3306</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Compact gap</CardTitle>
|
||||||
|
<CardSubtitle>Lower <code>--tblr-datagrid-padding</code> to bring the items closer together.</CardSubtitle>
|
||||||
|
<Datagrid itemWidth="7rem" gap="0.75rem">
|
||||||
|
<DatagridItem title="CPU">8 cores</DatagridItem>
|
||||||
|
<DatagridItem title="Memory">32 GB</DatagridItem>
|
||||||
|
<DatagridItem title="Storage">512 GB</DatagridItem>
|
||||||
|
<DatagridItem title="Region">eu-central</DatagridItem>
|
||||||
|
<DatagridItem title="Uptime">99.98%</DatagridItem>
|
||||||
|
<DatagridItem title="Backups">Daily</DatagridItem>
|
||||||
|
<DatagridItem title="IPv6">Enabled</DatagridItem>
|
||||||
|
<DatagridItem title="Port">3306</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Horizontal</CardTitle>
|
||||||
|
<CardSubtitle>Add <code>.datagrid-horizontal</code> to put the label beside the value.</CardSubtitle>
|
||||||
|
<Datagrid variant="horizontal" gap="1rem">
|
||||||
|
<DatagridItem title="Plan">Business</DatagridItem>
|
||||||
|
<DatagridItem title="Status"><span class="status status-green">Active</span></DatagridItem>
|
||||||
|
<DatagridItem title="Next invoice">October 18, 2026</DatagridItem>
|
||||||
|
<DatagridItem title="Address">44 Harbor Street, Portland, OR 97209, United States</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Horizontal in columns</CardTitle>
|
||||||
|
<CardSubtitle>Add <code>.datagrid-cols-2</code> and lower <code>--tblr-datagrid-title-width</code> to fit two pairs in a row.</CardSubtitle>
|
||||||
|
<Datagrid variant="horizontal" columns={2} titleWidth="5rem" gap="1rem">
|
||||||
|
<DatagridItem title="CPU">8 cores</DatagridItem>
|
||||||
|
<DatagridItem title="Memory">32 GB</DatagridItem>
|
||||||
|
<DatagridItem title="Storage">512 GB</DatagridItem>
|
||||||
|
<DatagridItem title="Region">eu-central</DatagridItem>
|
||||||
|
<DatagridItem title="Uptime">99.98%</DatagridItem>
|
||||||
|
<DatagridItem title="Backups">Daily</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 col-lg-4">
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Single column</CardTitle>
|
||||||
|
<CardSubtitle>Add <code>.datagrid-cols-1</code> to stack the items.</CardSubtitle>
|
||||||
|
<Datagrid columns={1} gap="1rem">
|
||||||
|
<DatagridItem title="Customer">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<Avatar person={customer} size="xs" class="me-2" />
|
||||||
|
{customer.full_name}
|
||||||
|
</div>
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Email"><a href="#">{customer.email}</a></DatagridItem>
|
||||||
|
<DatagridItem title="Shipping address">44 Harbor Street, Portland, OR 97209, United States</DatagridItem>
|
||||||
|
<DatagridItem title="Notes"><span class="text-secondary">Not set</span></DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 col-lg-4">
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Two columns</CardTitle>
|
||||||
|
<CardSubtitle>Add <code>.datagrid-cols-2</code> to keep two columns at any width.</CardSubtitle>
|
||||||
|
<Datagrid columns={2} gap="1rem">
|
||||||
|
<DatagridItem title="Order">#48213</DatagridItem>
|
||||||
|
<DatagridItem title="Status"><Badge color="green" light text="Paid" /></DatagridItem>
|
||||||
|
<DatagridItem title="Placed">September 12, 2026</DatagridItem>
|
||||||
|
<DatagridItem title="Delivery">September 16, 2026</DatagridItem>
|
||||||
|
<DatagridItem title="Items">3</DatagridItem>
|
||||||
|
<DatagridItem title="Total"><strong>$248.00</strong></DatagridItem>
|
||||||
|
<DatagridItem title="Payment">Visa ending 4242</DatagridItem>
|
||||||
|
<DatagridItem title="Carrier">DHL Express</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 col-lg-4">
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Statuses and progress</CardTitle>
|
||||||
|
<CardSubtitle>A value can hold a status, a badge or a progress bar.</CardSubtitle>
|
||||||
|
<Datagrid columns={2} gap="1rem">
|
||||||
|
<DatagridItem title="State"><span class="status status-green">Running</span></DatagridItem>
|
||||||
|
<DatagridItem title="Health"><span class="status status-yellow">Degraded</span></DatagridItem>
|
||||||
|
<DatagridItem title="Environment"><Badge color="blue" light text="Production" /></DatagridItem>
|
||||||
|
<DatagridItem title="Version"><code>v1.6.1</code></DatagridItem>
|
||||||
|
<DatagridItem title="Disk usage">
|
||||||
|
<div class="mb-1">68%</div>
|
||||||
|
<Progress value={68} size="sm" />
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Memory usage">
|
||||||
|
<div class="mb-1">41%</div>
|
||||||
|
<Progress value={41} size="sm" color="green" />
|
||||||
|
</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<Card>
|
||||||
|
<CardHeader title="Domain details">
|
||||||
|
<CardActions>
|
||||||
|
<Button text="Edit" icon="pencil" size="sm" />
|
||||||
|
</CardActions>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<Datagrid itemWidth="12rem">
|
||||||
|
<DatagridItem title="Domain"><a href="#">tabler.io <Icon name="external-link" inline /></a></DatagridItem>
|
||||||
|
<DatagridItem title="Registrar">Third Party</DatagridItem>
|
||||||
|
<DatagridItem title="SSL certificate">
|
||||||
|
<Icon name="lock" color="green" inline />
|
||||||
|
Valid until May 2, 2027
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Auto renew">
|
||||||
|
<label class="form-check form-switch mb-0">
|
||||||
|
<input class="form-check-input" type="checkbox" checked />
|
||||||
|
<span class="form-check-label">Enabled</span>
|
||||||
|
</label>
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Owner">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<Avatar person={owner} size="xs" class="me-2" />
|
||||||
|
{owner.full_name}
|
||||||
|
</div>
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Expiration date">–</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
<CardFooter>
|
||||||
|
<ButtonList class="justify-content-end">
|
||||||
|
<Button text="Transfer" variant="ghost" color="secondary" />
|
||||||
|
<Button text="Renew domain" color="primary" />
|
||||||
|
</ButtonList>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<Card>
|
||||||
|
<CardHeader title="API credentials" />
|
||||||
|
<CardBody>
|
||||||
|
<CardSubtitle>Add a <code>data-bs-toggle="clipboard"</code> button to let users copy a value.</CardSubtitle>
|
||||||
|
<Datagrid columns={1} gap="1rem">
|
||||||
|
<DatagridItem title="Client ID">
|
||||||
|
<div class="d-flex align-items-center gap-2">
|
||||||
|
<code id="datagrid-client-id" class="text-truncate">tblr_live_8f3a2c91d7e4</code>
|
||||||
|
<button type="button" class="btn btn-sm btn-icon btn-action" data-bs-toggle="clipboard" data-bs-target="#datagrid-client-id" aria-label="Copy the client ID">
|
||||||
|
<Icon name="clipboard" class="clipboard-label" />
|
||||||
|
<Icon name="check" class="clipboard-feedback text-green" />
|
||||||
|
<span class="clipboard-feedback visually-hidden">Copied</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Webhook URL">
|
||||||
|
<div class="d-flex align-items-center gap-2">
|
||||||
|
<code id="datagrid-webhook-url" class="text-truncate">https://example.com/hooks/tabler</code>
|
||||||
|
<button type="button" class="btn btn-sm btn-icon btn-action" data-bs-toggle="clipboard" data-bs-target="#datagrid-webhook-url" aria-label="Copy the webhook URL">
|
||||||
|
<Icon name="clipboard" class="clipboard-label" />
|
||||||
|
<Icon name="check" class="clipboard-feedback text-green" />
|
||||||
|
<span class="clipboard-feedback visually-hidden">Copied</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Last used">2 hours ago</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</DefaultLayout>
|
</DefaultLayout>
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
// Datagrid in its natural place: the details panel of a domain in a hosting
|
||||||
|
// dashboard. The values mix plain text, a status, an avatar, an icon and a
|
||||||
|
// progress bar, so the picture shows that a value can hold any content.
|
||||||
|
import ScreenshotLayout from '../layouts/ScreenshotLayout.astro'
|
||||||
|
import Card from '@ui/Card.astro'
|
||||||
|
import CardHeader from '@ui/CardHeader.astro'
|
||||||
|
import CardBody from '@ui/CardBody.astro'
|
||||||
|
import CardActions from '@ui/CardActions.astro'
|
||||||
|
import Avatar from '@ui/Avatar.astro'
|
||||||
|
import Badge from '@ui/Badge.astro'
|
||||||
|
import Button from '@ui/Button.astro'
|
||||||
|
import Icon from '@ui/Icon.astro'
|
||||||
|
import Progress from '@ui/Progress.astro'
|
||||||
|
import Datagrid from '@ui/Datagrid.astro'
|
||||||
|
import DatagridItem from '@ui/DatagridItem.astro'
|
||||||
|
import { people } from '@shared/lib/people'
|
||||||
|
import { requireIndex } from '@shared/lib/array'
|
||||||
|
|
||||||
|
const owner = requireIndex(people, 4)
|
||||||
|
---
|
||||||
|
|
||||||
|
<ScreenshotLayout title="Data grid" columns={2}>
|
||||||
|
<Card>
|
||||||
|
<CardHeader title="Domain details">
|
||||||
|
<CardActions>
|
||||||
|
<Button text="Edit" icon="pencil" size="sm" />
|
||||||
|
</CardActions>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody class="p-4">
|
||||||
|
<Datagrid columns={3}>
|
||||||
|
<DatagridItem title="Domain">tabler.io</DatagridItem>
|
||||||
|
<DatagridItem title="Registrar">Third Party</DatagridItem>
|
||||||
|
<DatagridItem title="Edge network">
|
||||||
|
<span class="status status-green">Active</span>
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Owner">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<Avatar person={owner} size="xs" class="me-2" />
|
||||||
|
{owner.full_name}
|
||||||
|
</div>
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Environment">
|
||||||
|
<Badge color="blue" light text="Production" />
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Port number">3306</DatagridItem>
|
||||||
|
<DatagridItem title="SSL certificate">
|
||||||
|
<Icon name="lock" color="green" inline />
|
||||||
|
Valid
|
||||||
|
</DatagridItem>
|
||||||
|
<DatagridItem title="Expiration date">May 2, 2027</DatagridItem>
|
||||||
|
<DatagridItem title="Disk usage">
|
||||||
|
<div class="mb-1">68%</div>
|
||||||
|
<Progress value={68} size="sm" />
|
||||||
|
</DatagridItem>
|
||||||
|
</Datagrid>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</ScreenshotLayout>
|
||||||
@@ -1,13 +1,29 @@
|
|||||||
---
|
---
|
||||||
// Data grid container (.datagrid); holds DatagridItem children.
|
// Data grid container (.datagrid); holds DatagridItem children.
|
||||||
|
|
||||||
interface Props {
|
type PolymorphicProps = { as?: 'div' | 'dl' }
|
||||||
|
|
||||||
|
interface Props extends PolymorphicProps {
|
||||||
|
/** core/scss/ui/_datagrid.scss `.datagrid-horizontal`: label beside the value, one pair per row */
|
||||||
|
variant?: 'horizontal' | undefined
|
||||||
|
/** `.datagrid-cols-{n}`: a fixed number of columns instead of as many as fit */
|
||||||
|
columns?: 1 | 2 | 3 | 4 | undefined
|
||||||
|
/** sets --tblr-datagrid-item-width, the minimum width of a column (e.g. `10rem`) */
|
||||||
|
itemWidth?: string | undefined
|
||||||
|
/** sets --tblr-datagrid-padding, the gap between items (e.g. `1rem`) */
|
||||||
|
gap?: string | undefined
|
||||||
|
/** sets --tblr-datagrid-title-width, the label column of the horizontal variant (e.g. `8rem`) */
|
||||||
|
titleWidth?: string | undefined
|
||||||
class?: string
|
class?: string
|
||||||
|
/** remaining attributes (id, data-*, aria-*, …) are forwarded to the root element */
|
||||||
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
const { class: className } = Astro.props
|
const { as: Tag = 'div', variant, columns, itemWidth, gap, titleWidth, class: className, ...rest }: Props = Astro.props
|
||||||
|
|
||||||
|
const style = [itemWidth && `--tblr-datagrid-item-width: ${itemWidth}`, gap && `--tblr-datagrid-padding: ${gap}`, titleWidth && `--tblr-datagrid-title-width: ${titleWidth}`].filter(Boolean).join('; ')
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class:list={['datagrid', className]}>
|
<Tag class:list={['datagrid', variant && `datagrid-${variant}`, columns && `datagrid-cols-${columns}`, className]} style={style || undefined} {...rest}>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</Tag>
|
||||||
@@ -3,15 +3,20 @@
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string
|
title: string
|
||||||
|
/** renders dt/dd instead of divs, for an item inside `<Datagrid as="dl">` */
|
||||||
|
list?: boolean
|
||||||
class?: string
|
class?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title, class: className } = Astro.props
|
const { title, list = false, class: className } = Astro.props
|
||||||
|
|
||||||
|
const TitleTag = list ? 'dt' : 'div'
|
||||||
|
const ContentTag = list ? 'dd' : 'div'
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class:list={['datagrid-item', className]}>
|
<div class:list={['datagrid-item', className]}>
|
||||||
<div class="datagrid-title">{title}</div>
|
<TitleTag class="datagrid-title">{title}</TitleTag>
|
||||||
<div class="datagrid-content">
|
<ContentTag class="datagrid-content">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</ContentTag>
|
||||||
</div>
|
</div>
|
||||||
Reference in new issue
Block a user