Skip to content
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
45 changes: 13 additions & 32 deletions apps/website/content/docs/grid/components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ and popup menus. Choose the customization level that matches your task:
| Replace a control while keeping the grid's behavior | The [`components` prop](#replacing-a-component) |
| Build a different editor, such as a date-range picker | Column [`renderEditor`](/docs/grid/editing#custom-editors) |

The kit is exported from `@pretable/react`. For the default appearance, load
the `@pretable/ui` skin as described in [Getting started](/docs).
The kit is exported from `@pretable/react`. These examples assume you have
imported an `@pretable/ui` theme and the grid skin once at your app’s entry point,
as shown in [Import the styles](/docs#import-the-styles). Each preview has a
Code tab with the complete component source.

## Replacing a component

Expand Down Expand Up @@ -111,6 +113,8 @@ which the built-in controls emit as `data-pretable-site`.
A labelled action. `variant="ghost"` (the default) uses a hover tint;
`variant="link"` uses plain accent text. Other props are native button props.

<Example id="kit-button" />

| Prop | Type | Meaning |
| --------- | ------------------- | ----------------------------- |
| `variant` | `"ghost" \| "link"` | Appearance; defaults to ghost |
Expand All @@ -121,6 +125,8 @@ A labelled action. `variant="ghost"` (the default) uses a hover tint;
An icon-only action. Supply its icon as children and a nonempty `aria-label`
describing the action, such as `Next month`. The label is required by its type.

<Example id="kit-icon-button" />

| Prop | Type | Meaning |
| ------------ | -------------- | ------------------------ |
| `aria-label` | `string` | Required accessible name |
Expand All @@ -132,20 +138,7 @@ A controlled select-only combobox with a button trigger and a portalled
listbox. It differs from the [editable enum editor](/docs/grid/editing#enums),
which accepts typed queries in a text field.

```tsx
import { PretableSelect } from "@pretable/react";

<PretableSelect
aria-label="Filter operator"
options={[
{ value: "contains", label: "Contains" },
{ value: "equals", label: "Equals" },
{ value: "regex", label: "Matches regex", disabled: true },
]}
value={operator}
onChange={setOperator}
/>;
```
<Example id="kit-select" />

| Prop | Type | Meaning |
| ------------ | --------------------------------- | -------------------------------------------------------------------------------------------------- |
Expand Down Expand Up @@ -181,14 +174,7 @@ closed when options are added again.
only `site` and the `data-pretable-text-input` styling hook. Debouncing, parsing,
and commit behavior belong to the caller.

```tsx
<PretableTextInput
aria-label="Filter value"
type="date"
value={value}
onChange={(event) => setValue(event.target.value)}
/>
```
<Example id="kit-text-input" />

| Prop | Type | Meaning |
| ------ | -------------- | ------------------------------------------------------- |
Expand All @@ -201,6 +187,8 @@ contract as TextInput. It emits `data-pretable-textarea`. The multiline editor
handles auto-grow and commit keys; the shared control forwards native props
such as `rows`, `value`, and `onChange`.

<Example id="kit-textarea" />

| Prop | Type | Meaning |
| ------ | -------------- | ---------------------------------------------------------- |
| `site` | `PretableSite` | Placement name; other props are native textarea attributes |
Expand All @@ -210,14 +198,7 @@ such as `rows`, `value`, and `onChange`.
A controlled `<button role="checkbox">` with `aria-checked` set to `true`,
`false`, or `mixed`. Space and Enter activate it through the native click.

```tsx
import { PretableCheckbox } from "@pretable/react";

<label>
<PretableCheckbox checked={hideGrouped} onCheckedChange={setHideGrouped} />
Hide grouped columns
</label>;
```
<Example id="kit-checkbox" />

| Prop | Type | Meaning |
| ----------------- | ------------------------- | --------------------------------------------------------- |
Expand Down
37 changes: 37 additions & 0 deletions apps/website/content/examples/kit-button/SavedViewActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"use client";

import { PretableButton } from "@pretable/react";
import { useState } from "react";

export function SavedViewActions() {
const [applied, setApplied] = useState(false);

return (
<div style={{ padding: 20, fontSize: 13 }}>
<p style={{ margin: "0 0 16px" }}>
Apply the saved “Open orders” view, then reset to all orders.
</p>
<div style={{ display: "flex", alignItems: "center", gap: 16 }}>
<PretableButton
variant="ghost"
site="saved-view-apply"
disabled={applied}
onClick={() => setApplied(true)}
>
Apply saved view
</PretableButton>
<PretableButton
variant="link"
site="saved-view-reset"
disabled={!applied}
onClick={() => setApplied(false)}
>
Reset view
</PretableButton>
</div>
<p role="status" style={{ margin: "16px 0 0" }}>
Current view: {applied ? "Open orders" : "All orders"}
</p>
</div>
);
}
5 changes: 5 additions & 0 deletions apps/website/content/examples/kit-button/demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { SavedViewActions } from "./SavedViewActions";

export default function Demo() {
return <SavedViewActions />;
}
9 changes: 9 additions & 0 deletions apps/website/content/examples/kit-button/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineExample } from "../../../lib/docs/examples/define";

export default defineExample({
title: "Saved view actions",
description:
"Apply a saved view with a ghost button, then reset it with a link button. Disabled states prevent repeating the current action.",
files: ["SavedViewActions.tsx"],
height: 200,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"use client";

import { PretableCheckbox } from "@pretable/react";
import { useState } from "react";

const projects = ["Atlas", "Beacon", "Cedar"];

export function CheckboxSelectionExample() {
const [selected, setSelected] = useState<string[]>(["Atlas"]);
const allChecked =
selected.length === projects.length
? true
: selected.length === 0
? false
: "mixed";

return (
<div style={{ padding: 20, maxWidth: 360, fontSize: 13 }}>
<label
style={{
display: "flex",
alignItems: "center",
gap: 8,
marginBottom: 12,
}}
>
<PretableCheckbox
checked={allChecked}
onCheckedChange={(checked) =>
setSelected(checked ? [...projects] : [])
}
/>
Select all projects
</label>
<div style={{ display: "grid", gap: 10 }}>
{projects.map((project) => (
<label
key={project}
style={{ display: "flex", alignItems: "center", gap: 8 }}
>
<PretableCheckbox
checked={selected.includes(project)}
onCheckedChange={(checked) =>
setSelected((current) =>
checked
? [...current, project]
: current.filter((name) => name !== project),
)
}
/>
{project}
</label>
))}
</div>
<p role="status" style={{ margin: "12px 0 0" }}>
{selected.length} of {projects.length} selected
</p>
</div>
);
}
5 changes: 5 additions & 0 deletions apps/website/content/examples/kit-checkbox/demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { CheckboxSelectionExample } from "./CheckboxSelectionExample";

export default function Demo() {
return <CheckboxSelectionExample />;
}
9 changes: 9 additions & 0 deletions apps/website/content/examples/kit-checkbox/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineExample } from "../../../lib/docs/examples/define";

export default defineExample({
title: "Select projects",
description:
"Controlled checkboxes share a selected-project list. Select all starts mixed, selects every project on activation, then clears the list on the next activation.",
files: ["CheckboxSelectionExample.tsx"],
height: 240,
});
43 changes: 43 additions & 0 deletions apps/website/content/examples/kit-icon-button/PinViewButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use client";

import { PretableIconButton } from "@pretable/react";
import { useState } from "react";

export function PinViewButton() {
const [pinned, setPinned] = useState(false);

return (
<div style={{ padding: 20, fontSize: 13 }}>
<p style={{ margin: "0 0 16px" }}>
Pin “Open orders” for quick access. Use Enter or Space on the button.
</p>
<div style={{ display: "flex", alignItems: "center", gap: 12 }}>
<PretableIconButton
aria-label="Pin view"
aria-pressed={pinned}
site="saved-view-pin"
onClick={() => setPinned((value) => !value)}
>
<svg
aria-hidden="true"
width="16"
height="16"
viewBox="0 0 24 24"
fill={pinned ? "currentColor" : "none"}
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M8 3h8l-1 6 4 4v2H5v-2l4-4-1-6Z" />
<path d="M12 15v6" />
</svg>
</PretableIconButton>
<span>Open orders</span>
</div>
<p role="status" style={{ margin: "16px 0 0" }}>
{pinned ? "View pinned to quick access." : "View is not pinned."}
</p>
</div>
);
}
5 changes: 5 additions & 0 deletions apps/website/content/examples/kit-icon-button/demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { PinViewButton } from "./PinViewButton";

export default function Demo() {
return <PinViewButton />;
}
9 changes: 9 additions & 0 deletions apps/website/content/examples/kit-icon-button/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineExample } from "../../../lib/docs/examples/define";

export default defineExample({
title: "Pin a view",
description:
"Toggle a view’s pinned state with an icon-only button. The accessible name stays the same while aria-pressed and a visible status report the change.",
files: ["PinViewButton.tsx"],
height: 200,
});
61 changes: 61 additions & 0 deletions apps/website/content/examples/kit-select/SelectSortExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client";

import { PretableSelect, type PretableSelectOption } from "@pretable/react";
import { useId, useState } from "react";

const projects = [
{ name: "Atlas", updated: 1 },
{ name: "Beacon", updated: 3 },
{ name: "Cedar", updated: 2 },
];

const options: readonly PretableSelectOption[] = [
{ value: "ascending", label: "Name: A–Z" },
{ value: "manual", label: "Manual order (unavailable)", disabled: true },
{ value: "descending", label: "Name: Z–A" },
{
value: "recent",
label: (
<span>
Recently updated <small>(newest first)</small>
</span>
),
// Rich labels need plain text for keyboard typeahead.
textValue: "Recently updated",
},
];

export function SelectSortExample() {
const selectId = useId();
const [sort, setSort] = useState("ascending");
const sortedProjects = [...projects].sort((a, b) =>
sort === "recent"
? b.updated - a.updated
: sort === "descending"
? b.name.localeCompare(a.name)
: a.name.localeCompare(b.name),
);

return (
<div style={{ padding: 20, maxWidth: 360, fontSize: 13 }}>
<label htmlFor={selectId} style={{ display: "block", marginBottom: 8 }}>
Sort projects
</label>
<PretableSelect
id={selectId}
aria-label="Sort projects"
options={options}
value={sort}
onChange={setSort}
/>
<ol
aria-label="Projects"
style={{ margin: "16px 0 0", paddingLeft: 24, display: "grid", gap: 6 }}
>
{sortedProjects.map((project) => (
<li key={project.name}>{project.name}</li>
))}
</ol>
</div>
);
}
5 changes: 5 additions & 0 deletions apps/website/content/examples/kit-select/demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { SelectSortExample } from "./SelectSortExample";

export default function Demo() {
return <SelectSortExample />;
}
9 changes: 9 additions & 0 deletions apps/website/content/examples/kit-select/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineExample } from "../../../lib/docs/examples/define";

export default defineExample({
title: "Sort a project list",
description:
"A controlled Select reorders projects. Open it with ArrowDown, skip the disabled option, or type R to find the rich Recently updated label through textValue.",
files: ["SelectSortExample.tsx"],
height: 240,
});
Loading