@twoux/ui 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +61 -0
- package/LICENSES/Apache-2.0.txt +202 -0
- package/NOTICE.md +64 -0
- package/SHADCN-DIFF.md +228 -0
- package/agent/AGENTS.md +358 -0
- package/agent/docs-md/accessibility.md +49 -0
- package/agent/docs-md/action-catalogue.md +81 -0
- package/agent/docs-md/actions.md +74 -0
- package/agent/docs-md/agent-activity-log.md +70 -0
- package/agent/docs-md/agent-permissions.md +82 -0
- package/agent/docs-md/agent-run.md +90 -0
- package/agent/docs-md/agents-on-behalf.md +74 -0
- package/agent/docs-md/ai-column.md +85 -0
- package/agent/docs-md/ai-origin-label.md +70 -0
- package/agent/docs-md/announcing-features.md +73 -0
- package/agent/docs-md/answer-actions.md +81 -0
- package/agent/docs-md/app-shell.md +114 -0
- package/agent/docs-md/artifact-card.md +89 -0
- package/agent/docs-md/ask-on-screen.md +72 -0
- package/agent/docs-md/assistant-page.md +100 -0
- package/agent/docs-md/assistant-panel.md +142 -0
- package/agent/docs-md/avatar.md +82 -0
- package/agent/docs-md/banner.md +106 -0
- package/agent/docs-md/board.md +163 -0
- package/agent/docs-md/breadcrumb.md +89 -0
- package/agent/docs-md/breakdown-table.md +97 -0
- package/agent/docs-md/bulk-action-bar.md +112 -0
- package/agent/docs-md/button.md +293 -0
- package/agent/docs-md/card.md +115 -0
- package/agent/docs-md/change-list.md +99 -0
- package/agent/docs-md/change-request.md +166 -0
- package/agent/docs-md/chart-area.md +87 -0
- package/agent/docs-md/chart-bar.md +100 -0
- package/agent/docs-md/chart-box-plot.md +88 -0
- package/agent/docs-md/chart-bullet.md +89 -0
- package/agent/docs-md/chart-candlestick.md +112 -0
- package/agent/docs-md/chart-card-line.md +120 -0
- package/agent/docs-md/chart-donut.md +90 -0
- package/agent/docs-md/chart-drill-down.md +72 -0
- package/agent/docs-md/chart-funnel.md +71 -0
- package/agent/docs-md/chart-heatmap.md +76 -0
- package/agent/docs-md/chart-histogram.md +81 -0
- package/agent/docs-md/chart-map.md +165 -0
- package/agent/docs-md/chart-mixed.md +88 -0
- package/agent/docs-md/chart-price.md +92 -0
- package/agent/docs-md/chart-radial-bars.md +109 -0
- package/agent/docs-md/chart-radial-lines.md +111 -0
- package/agent/docs-md/chart-sankey.md +104 -0
- package/agent/docs-md/chart-scatter.md +87 -0
- package/agent/docs-md/chart-share-bar.md +89 -0
- package/agent/docs-md/chart-treemap.md +98 -0
- package/agent/docs-md/chart-waterfall.md +93 -0
- package/agent/docs-md/checkbox.md +131 -0
- package/agent/docs-md/choosing-selection-control.md +71 -0
- package/agent/docs-md/citations-sources.md +79 -0
- package/agent/docs-md/citing-sources.md +63 -0
- package/agent/docs-md/clarify-before-acting.md +69 -0
- package/agent/docs-md/clarifying-question.md +92 -0
- package/agent/docs-md/code-block.md +174 -0
- package/agent/docs-md/colours.md +87 -0
- package/agent/docs-md/columns-menu.md +140 -0
- package/agent/docs-md/combobox.md +161 -0
- package/agent/docs-md/command-palette.md +126 -0
- package/agent/docs-md/confidence-note.md +87 -0
- package/agent/docs-md/configurable-dashboard.md +76 -0
- package/agent/docs-md/confirmation-dialog.md +93 -0
- package/agent/docs-md/connected-tools.md +80 -0
- package/agent/docs-md/connector-picker.md +127 -0
- package/agent/docs-md/consistency.md +53 -0
- package/agent/docs-md/content-density.md +61 -0
- package/agent/docs-md/conversation-history.md +78 -0
- package/agent/docs-md/create-record.md +80 -0
- package/agent/docs-md/csv-import.md +88 -0
- package/agent/docs-md/dashboard-items.md +78 -0
- package/agent/docs-md/data-export.md +61 -0
- package/agent/docs-md/data-grid.md +137 -0
- package/agent/docs-md/data-vis-colours.md +76 -0
- package/agent/docs-md/data-visualisation.md +76 -0
- package/agent/docs-md/date-picker.md +178 -0
- package/agent/docs-md/delete-record.md +75 -0
- package/agent/docs-md/dense-table.md +495 -0
- package/agent/docs-md/design-tokens.md +53 -0
- package/agent/docs-md/disabled-read-only.md +75 -0
- package/agent/docs-md/drag-and-drop.md +74 -0
- package/agent/docs-md/dropdown-menu.md +137 -0
- package/agent/docs-md/edit-record.md +73 -0
- package/agent/docs-md/empty-loading-error.md +78 -0
- package/agent/docs-md/empty-state.md +128 -0
- package/agent/docs-md/error-messages.md +75 -0
- package/agent/docs-md/error-state.md +123 -0
- package/agent/docs-md/export-menu.md +86 -0
- package/agent/docs-md/feedback-prompt.md +88 -0
- package/agent/docs-md/field-mapping.md +78 -0
- package/agent/docs-md/file-drop.md +110 -0
- package/agent/docs-md/filter-bar.md +138 -0
- package/agent/docs-md/filter-panel.md +103 -0
- package/agent/docs-md/filtering-search.md +79 -0
- package/agent/docs-md/follow-ups-starters.md +79 -0
- package/agent/docs-md/form-validation.md +95 -0
- package/agent/docs-md/generated-columns.md +65 -0
- package/agent/docs-md/generated-drafts-files.md +71 -0
- package/agent/docs-md/grouped-list.md +89 -0
- package/agent/docs-md/guide-cue.md +170 -0
- package/agent/docs-md/help-panel.md +103 -0
- package/agent/docs-md/help-system.md +74 -0
- package/agent/docs-md/iconography.md +49 -0
- package/agent/docs-md/inbox.md +108 -0
- package/agent/docs-md/inline-editing-validation.md +80 -0
- package/agent/docs-md/inline-input-in-answer.md +70 -0
- package/agent/docs-md/items-palette.md +116 -0
- package/agent/docs-md/keyboard-model.md +47 -0
- package/agent/docs-md/keyboard-navigation.md +68 -0
- package/agent/docs-md/keyboard-shortcut-hint.md +87 -0
- package/agent/docs-md/keyboard-shortcut-sheet.md +90 -0
- package/agent/docs-md/labelling-ai-output.md +66 -0
- package/agent/docs-md/layout.md +47 -0
- package/agent/docs-md/list-table.md +254 -0
- package/agent/docs-md/loading-skeleton.md +91 -0
- package/agent/docs-md/managing-agents.md +71 -0
- package/agent/docs-md/message-composer.md +105 -0
- package/agent/docs-md/migrating.md +49 -0
- package/agent/docs-md/motion.md +93 -0
- package/agent/docs-md/navigation.md +76 -0
- package/agent/docs-md/notification-channels.md +65 -0
- package/agent/docs-md/notifications-decision.md +100 -0
- package/agent/docs-md/onboarding-step.md +114 -0
- package/agent/docs-md/order-book.md +108 -0
- package/agent/docs-md/page-header.md +96 -0
- package/agent/docs-md/pagination.md +88 -0
- package/agent/docs-md/pane-layout.md +105 -0
- package/agent/docs-md/period-comparison.md +66 -0
- package/agent/docs-md/plan-card.md +120 -0
- package/agent/docs-md/popover-rules.md +88 -0
- package/agent/docs-md/prompt-editor.md +90 -0
- package/agent/docs-md/propose-apply.md +65 -0
- package/agent/docs-md/provider-logo.md +97 -0
- package/agent/docs-md/radio.md +83 -0
- package/agent/docs-md/ranked-list.md +102 -0
- package/agent/docs-md/reasoning-progress.md +72 -0
- package/agent/docs-md/record-detail.md +71 -0
- package/agent/docs-md/regenerating-answers.md +70 -0
- package/agent/docs-md/run-status-bar.md +94 -0
- package/agent/docs-md/saved-tasks-schedules.md +63 -0
- package/agent/docs-md/saved-views.md +149 -0
- package/agent/docs-md/saving-views.md +68 -0
- package/agent/docs-md/scheduler.md +258 -0
- package/agent/docs-md/secondary-panels.md +72 -0
- package/agent/docs-md/segmented-control.md +88 -0
- package/agent/docs-md/selection-bulk-actions.md +70 -0
- package/agent/docs-md/separator.md +75 -0
- package/agent/docs-md/setup-checklist.md +92 -0
- package/agent/docs-md/shape-elevation.md +55 -0
- package/agent/docs-md/sheet-grid.md +211 -0
- package/agent/docs-md/side-panel.md +134 -0
- package/agent/docs-md/sign-in.md +114 -0
- package/agent/docs-md/spacing.md +55 -0
- package/agent/docs-md/split-button.md +100 -0
- package/agent/docs-md/stat-compare.md +82 -0
- package/agent/docs-md/static-dashboard.md +75 -0
- package/agent/docs-md/status-badge.md +140 -0
- package/agent/docs-md/step-card.md +75 -0
- package/agent/docs-md/stepper.md +92 -0
- package/agent/docs-md/suggested-changes.md +91 -0
- package/agent/docs-md/switch.md +78 -0
- package/agent/docs-md/table-settings.md +81 -0
- package/agent/docs-md/tabs.md +85 -0
- package/agent/docs-md/tag-input.md +108 -0
- package/agent/docs-md/tag.md +79 -0
- package/agent/docs-md/task-builder.md +87 -0
- package/agent/docs-md/team-instructions.md +72 -0
- package/agent/docs-md/templates-gallery.md +85 -0
- package/agent/docs-md/text-input.md +160 -0
- package/agent/docs-md/thinking-steps.md +89 -0
- package/agent/docs-md/timeline.md +189 -0
- package/agent/docs-md/timestamp.md +84 -0
- package/agent/docs-md/timestamps.md +70 -0
- package/agent/docs-md/toast.md +117 -0
- package/agent/docs-md/tooltip.md +90 -0
- package/agent/docs-md/typography.md +62 -0
- package/agent/docs-md/undo-destructive.md +66 -0
- package/agent/docs-md/unsaved-changes.md +71 -0
- package/agent/docs-md/usage-meter.md +80 -0
- package/agent/docs-md/user-feedback.md +71 -0
- package/agent/docs-md/voice-and-tone.md +60 -0
- package/agent/docs-md/why-choice.md +93 -0
- package/agent/docs-md/workspace-onboarding.md +74 -0
- package/agent/docs-md/writing.md +48 -0
- package/agent/llms-full.txt +18369 -0
- package/agent/llms.txt +198 -0
- package/agent/skills/twoux-audit/SKILL.md +49 -0
- package/agent/skills/twoux-build/SKILL.md +39 -0
- package/agent/skills/twoux-design/SKILL.md +54 -0
- package/agent/skills/twoux-write/SKILL.md +32 -0
- package/bin/check.mjs +123 -0
- package/bin/docs.mjs +24 -0
- package/bin/guard.mjs +27 -0
- package/bin/init.mjs +113 -0
- package/bin/knowledge.mjs +87 -0
- package/bin/mcp.mjs +116 -0
- package/bin/theme.mjs +168 -0
- package/bin/twoux.mjs +25 -0
- package/package.json +80 -3
- package/registry/jobs.json +1028 -0
- package/registry/palette.json +770 -0
- package/registry/rules.json +913 -0
- package/src/components/agent-review.tsx +364 -0
- package/src/components/ai-basics.tsx +212 -0
- package/src/components/ai-work.tsx +304 -0
- package/src/components/ai.tsx +227 -0
- package/src/components/alert-dialog.tsx +203 -0
- package/src/components/alert.tsx +86 -0
- package/src/components/avatar.tsx +114 -0
- package/src/components/badge.tsx +59 -0
- package/src/components/board.tsx +397 -0
- package/src/components/breadcrumb.tsx +114 -0
- package/src/components/button-group.tsx +90 -0
- package/src/components/button.tsx +109 -0
- package/src/components/calendar.tsx +247 -0
- package/src/components/card.tsx +102 -0
- package/src/components/chart-map.tsx +336 -0
- package/src/components/charts-more.tsx +1331 -0
- package/src/components/charts-radial.tsx +328 -0
- package/src/components/charts.tsx +390 -0
- package/src/components/checkbox.tsx +40 -0
- package/src/components/code.tsx +139 -0
- package/src/components/collapsible.tsx +37 -0
- package/src/components/combobox.tsx +339 -0
- package/src/components/command-extras.tsx +11 -0
- package/src/components/command.tsx +196 -0
- package/src/components/data-grid.tsx +213 -0
- package/src/components/data-table.tsx +334 -0
- package/src/components/data-views.tsx +740 -0
- package/src/components/date-picker.tsx +686 -0
- package/src/components/dense-table.tsx +207 -0
- package/src/components/dialog.tsx +162 -0
- package/src/components/dropdown-menu.tsx +264 -0
- package/src/components/empty.tsx +114 -0
- package/src/components/feedback-prompt.tsx +80 -0
- package/src/components/field.tsx +254 -0
- package/src/components/fields.tsx +112 -0
- package/src/components/flow.tsx +840 -0
- package/src/components/guide-cue.tsx +273 -0
- package/src/components/inbox.tsx +113 -0
- package/src/components/input-group.tsx +176 -0
- package/src/components/input.tsx +26 -0
- package/src/components/kbd.tsx +34 -0
- package/src/components/label.tsx +27 -0
- package/src/components/labels.tsx +176 -0
- package/src/components/motion.tsx +136 -0
- package/src/components/onboarding.tsx +454 -0
- package/src/components/order-book.tsx +185 -0
- package/src/components/pane-layout.tsx +417 -0
- package/src/components/popover.tsx +96 -0
- package/src/components/provider-logos.data.ts +49 -0
- package/src/components/radio-group.tsx +52 -0
- package/src/components/scheduler.tsx +997 -0
- package/src/components/segmented-control.tsx +28 -0
- package/src/components/select.tsx +195 -0
- package/src/components/separator.tsx +31 -0
- package/src/components/sheet.tsx +148 -0
- package/src/components/shell.tsx +426 -0
- package/src/components/shortcut-sheet.tsx +83 -0
- package/src/components/skeleton.tsx +18 -0
- package/src/components/sonner.tsx +107 -0
- package/src/components/spinner.tsx +13 -0
- package/src/components/split-button.tsx +58 -0
- package/src/components/stepper.tsx +78 -0
- package/src/components/switch.tsx +43 -0
- package/src/components/table.tsx +126 -0
- package/src/components/tabs.tsx +118 -0
- package/src/components/tag-input.tsx +253 -0
- package/src/components/textarea.tsx +21 -0
- package/src/components/theme.tsx +80 -0
- package/src/components/timeline.tsx +408 -0
- package/src/components/toggle-group.tsx +87 -0
- package/src/components/toggle.tsx +54 -0
- package/src/components/tooltip.tsx +65 -0
- package/src/components/workspace-actions.tsx +294 -0
- package/src/components/workspace-import.tsx +465 -0
- package/src/components/workspace.tsx +1884 -0
- package/src/index.ts +80 -0
- package/src/lib/active-indicator.tsx +53 -0
- package/src/lib/chart-kit.tsx +72 -0
- package/src/lib/cn.ts +6 -0
- package/src/lib/shortcuts.tsx +61 -0
- package/src/lib/workspace.tsx +10 -0
- package/src/shadcn/alert-dialog.tsx +196 -0
- package/src/shadcn/alert.tsx +65 -0
- package/src/shadcn/avatar.tsx +108 -0
- package/src/shadcn/badge.tsx +47 -0
- package/src/shadcn/breadcrumb.tsx +108 -0
- package/src/shadcn/button-group.tsx +83 -0
- package/src/shadcn/button.tsx +63 -0
- package/src/shadcn/calendar.tsx +220 -0
- package/src/shadcn/card.tsx +91 -0
- package/src/shadcn/checkbox.tsx +31 -0
- package/src/shadcn/collapsible.tsx +33 -0
- package/src/shadcn/command.tsx +184 -0
- package/src/shadcn/dialog.tsx +158 -0
- package/src/shadcn/dropdown-menu.tsx +256 -0
- package/src/shadcn/empty.tsx +103 -0
- package/src/shadcn/field.tsx +248 -0
- package/src/shadcn/input-group.tsx +170 -0
- package/src/shadcn/input.tsx +20 -0
- package/src/shadcn/kbd.tsx +28 -0
- package/src/shadcn/label.tsx +23 -0
- package/src/shadcn/popover.tsx +88 -0
- package/src/shadcn/radio-group.tsx +44 -0
- package/src/shadcn/select.tsx +189 -0
- package/src/shadcn/separator.tsx +27 -0
- package/src/shadcn/sheet.tsx +142 -0
- package/src/shadcn/skeleton.tsx +13 -0
- package/src/shadcn/sonner.tsx +40 -0
- package/src/shadcn/switch.tsx +34 -0
- package/src/shadcn/table.tsx +115 -0
- package/src/shadcn/tabs.tsx +90 -0
- package/src/shadcn/textarea.tsx +17 -0
- package/src/shadcn/toggle-group.tsx +83 -0
- package/src/shadcn/toggle.tsx +46 -0
- package/src/shadcn/tooltip.tsx +56 -0
- package/src/styles/palette.css +127 -0
- package/src/styles/theme.css +35 -0
- package/src/styles/twoux.css +236 -0
- package/theme.json +14 -0
- package/README.md +0 -3
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Items palette
|
|
2
|
+
|
|
3
|
+
A searchable list, in a side panel beside a configurable dashboard, of the items a person can add, each with a title, a short description, its type and an Add to dashboard button.
|
|
4
|
+
|
|
5
|
+
Kind: component · Group: Data visualisation · Status: built, import from @twoux/ui
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
- With a configurable dashboard, to add items that are not on the board yet.
|
|
10
|
+
- As the place removed items return to, so people can add them back.
|
|
11
|
+
- When new item types ship, so people find them without a layout being changed for them.
|
|
12
|
+
|
|
13
|
+
## When not to use
|
|
14
|
+
|
|
15
|
+
- On a static dashboard. There is nothing to add.
|
|
16
|
+
- To pick records or templates. Use the command palette or the templates gallery.
|
|
17
|
+
- To change what an item on the board shows. Use Preferences in that item's menu.
|
|
18
|
+
|
|
19
|
+
## Structure
|
|
20
|
+
|
|
21
|
+
1. Panel header: "Add items", item count and close
|
|
22
|
+
2. Search field that filters by title and description
|
|
23
|
+
3. Palette item: drag handle, title, one-line description, type tag (Chart, List, Key metrics), Add to dashboard button
|
|
24
|
+
4. Zero results: message with Clear search
|
|
25
|
+
5. Empty palette: "All items are on your dashboard"
|
|
26
|
+
|
|
27
|
+
## Guidelines
|
|
28
|
+
|
|
29
|
+
- List only items that are not on the board. When one is added it leaves the palette; when it is removed it comes back.
|
|
30
|
+
- Palette items describe; they do not preview. No live numbers, charts or menus, only title, description and type.
|
|
31
|
+
- Every palette item has an Add to dashboard button as well as its drag handle. The button adds the item at the end of the board in its default size. Keyboard users add with the button, then place the item with the board's own keyboard move; there is no separate keyboard drag from the palette.
|
|
32
|
+
- While dragging, the palette item takes the shape of its default size on the board and shows a drop preview.
|
|
33
|
+
- Add search once there are more than about ten items, and show a zero results message with Clear search.
|
|
34
|
+
- The panel pushes the board, stays open while people add several items, and closes with Esc or Add items again.
|
|
35
|
+
|
|
36
|
+
## Content
|
|
37
|
+
|
|
38
|
+
- Descriptions say what the item answers: "Applications per week for the last 12 weeks, compared with the previous period."
|
|
39
|
+
- Type tags use one word or two: Chart, List, Key metrics, Links, Alerts.
|
|
40
|
+
- Zero results: "No items match \"cost\"." with Clear search.
|
|
41
|
+
|
|
42
|
+
## Accessibility
|
|
43
|
+
|
|
44
|
+
- The panel is a complementary region labelled "Add items"; focus moves to its search field when it opens and returns to Add items when it closes.
|
|
45
|
+
- Add to dashboard is named with the item: "Add Applications this week to dashboard".
|
|
46
|
+
- After an add, announce "Applications this week added to the end of the dashboard" and keep focus in the palette on the next item.
|
|
47
|
+
- Dragging from the palette is never required; the button covers the same result with a single action.
|
|
48
|
+
|
|
49
|
+
## Keyboard
|
|
50
|
+
|
|
51
|
+
| Keys | Action |
|
|
52
|
+
|---|---|
|
|
53
|
+
| Tab / Shift+Tab | Move between search, palette items and their Add buttons |
|
|
54
|
+
| Enter (Add button) | Add the item to the end of the board |
|
|
55
|
+
| Esc | Cancel a pick-up, or close the panel |
|
|
56
|
+
| Then, on the board | Use the new item's handle (Enter, arrows, Enter) or its menu to move it |
|
|
57
|
+
|
|
58
|
+
## Examples
|
|
59
|
+
|
|
60
|
+
### add-items
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { Board, BoardItem, type BoardItemData, Button, ItemsPalette, type PaletteItem, SidePanel, StatCompare, toast } from "@twoux/ui";
|
|
64
|
+
import { Plus } from "lucide-react";
|
|
65
|
+
import { useState } from "react";
|
|
66
|
+
|
|
67
|
+
export const meta = { title: "Add items to a dashboard", description: "The palette lists only what isn't on the board. Add puts an item at the end in its default size; drag drops it where you let go. Removing an item returns it to the palette.", order: 1 };
|
|
68
|
+
|
|
69
|
+
const CATALOGUE: PaletteItem[] = [
|
|
70
|
+
{ id: "apps", title: "Applications this month", description: "Total applications and change against last month", type: "Key metrics" },
|
|
71
|
+
{ id: "tth", title: "Median time to hire", description: "Days from opening a listing to an accepted offer", type: "Key metrics" },
|
|
72
|
+
{ id: "accept", title: "Offer acceptance", description: "Share of offers accepted this quarter", type: "Key metrics" },
|
|
73
|
+
{ id: "closing", title: "Closing this week", description: "Listings that close in the next 7 days", type: "List" },
|
|
74
|
+
];
|
|
75
|
+
const VALUES: Record<string, [string, string, string, boolean]> = { apps: ["595", "+12%", "October", true], tth: ["23 days", "-4 days", "last quarter", true], accept: ["71%", "-6 pts", "last quarter", false] };
|
|
76
|
+
|
|
77
|
+
export default function Example() {
|
|
78
|
+
const [items, setItems] = useState<BoardItemData[]>([{ id: "apps", title: "Applications this month" }]);
|
|
79
|
+
const [open, setOpen] = useState(true);
|
|
80
|
+
const palette = CATALOGUE.filter((c) => !items.some((i) => i.id === c.id));
|
|
81
|
+
const add = (id: string, at = items.length) => {
|
|
82
|
+
const c = CATALOGUE.find((x) => x.id === id);
|
|
83
|
+
if (!c) return;
|
|
84
|
+
setItems((x) => { const n = [...x]; n.splice(at, 0, { id, title: c.title }); return n; });
|
|
85
|
+
toast.success(`Added ${c.title}`);
|
|
86
|
+
};
|
|
87
|
+
return (
|
|
88
|
+
<div className="flex h-104 w-full overflow-hidden rounded-sm border border-line bg-bg">
|
|
89
|
+
<div className="min-w-0 flex-1 overflow-auto p-3">
|
|
90
|
+
<div className="mb-2 flex justify-end"><Button variant="outline" size="sm" onClick={() => setOpen(true)}><Plus />Add items</Button></div>
|
|
91
|
+
<Board
|
|
92
|
+
items={items}
|
|
93
|
+
onItemsChange={setItems}
|
|
94
|
+
onAddFromPalette={add}
|
|
95
|
+
empty={<p className="rounded-sm border border-dashed border-line-strong p-8 text-center text-base text-ink-2">Drag an item here, or use Add.</p>}
|
|
96
|
+
renderItem={(it) => (
|
|
97
|
+
<BoardItem id={it.id} header={it.title}>
|
|
98
|
+
{VALUES[it.id] ? <StatCompare label="" value={VALUES[it.id][0]} change={VALUES[it.id][1]} period={VALUES[it.id][2]} good={VALUES[it.id][3]} /> : <p className="text-sm text-ink-2">Frontend Engineer · Fri 21 Nov</p>}
|
|
99
|
+
</BoardItem>
|
|
100
|
+
)}
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
<SidePanel open={open} onOpenChange={setOpen} label="Add items" title="Add items" meta={`${palette.length} available`}>
|
|
104
|
+
<ItemsPalette items={palette} onAdd={(id) => add(id)} />
|
|
105
|
+
</SidePanel>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Related
|
|
112
|
+
|
|
113
|
+
- Board and board item
|
|
114
|
+
- Configurable dashboard
|
|
115
|
+
- Dashboard items
|
|
116
|
+
- Side panel (drawer)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Keyboard model
|
|
2
|
+
|
|
3
|
+
TwoUX is built to be driven from the keyboard. ⌘K runs any command, ⌘J opens the assistant, ? shows every shortcut, J and K move through lists, and Esc always closes the innermost layer first.
|
|
4
|
+
|
|
5
|
+
Kind: foundation · Group: Key principles
|
|
6
|
+
|
|
7
|
+
## Principles
|
|
8
|
+
|
|
9
|
+
- Shortcuts are accelerators, not the only path. Everything is also reachable by Tab and by the command menu. APG: do not use shortcuts as a substitute for navigation.
|
|
10
|
+
- Few, mnemonic, and familiar. APG warns that too many shortcuts add cognitive load and recommends mnemonics and known conventions.
|
|
11
|
+
- Discoverable. Shortcuts are shown in tooltips, menus and buttons as keycaps, so people learn them where they already look.
|
|
12
|
+
- Can be turned off. Single-key shortcuts have a switch; ⌘ shortcuts stay on.
|
|
13
|
+
|
|
14
|
+
## Guidelines
|
|
15
|
+
|
|
16
|
+
- Global: ⌘K command menu; ⌘J ask the assistant; ? shortcut sheet; / search this view; G then L go to listings; G then P go to pipeline; ⌘Z undo last action.
|
|
17
|
+
- Lists: J next row, K previous row, X select, ⇧J extend selection, ↵ open in side panel, ⇧↵ open as full page, ⇧P toggle side by side.
|
|
18
|
+
- Actions on the current row or selection: C new listing, E edit, F add filter, T extend 30 days, D duplicate, ⇧E export, ⇧V columns.
|
|
19
|
+
- Destructive actions need Shift: ⇧C close listing. Shift keeps a stray keypress from doing harm, and the toast offers Undo.
|
|
20
|
+
- Inside popovers, menus and the command menu: ↑ and ↓ move, ↵ chooses, Tab changes scope or moves, Esc closes.
|
|
21
|
+
- Esc order, innermost first: 1. open popover or menu; 2. assistant sub-menus and history; 3. the assistant panel; 4. the side panel; 5. clear the row selection. One press closes one layer, and focus returns to what opened it.
|
|
22
|
+
- No browser or OS conflicts: avoid ⌘ plus a single key that the browser owns (find, refresh, bookmarks) and modifier combinations with Tab, Enter, Space or Escape.
|
|
23
|
+
- Single-key shortcuts are ignored while focus is in a text field.
|
|
24
|
+
|
|
25
|
+
## Accessibility
|
|
26
|
+
|
|
27
|
+
- 2.1.4: single-character shortcuts can be turned off in the shortcut sheet ('Turn off if you use a screen reader or voice control').
|
|
28
|
+
- All functionality is available through the keyboard, with or without shortcuts.
|
|
29
|
+
- J and K move a visible focus or active-row indicator and scroll the row into view.
|
|
30
|
+
- The focused row stays visible when the side panel or bulk bar is open.
|
|
31
|
+
|
|
32
|
+
## Do
|
|
33
|
+
|
|
34
|
+
- Show the keycap in the button or tooltip for any action that has a shortcut.
|
|
35
|
+
- Add new shortcuts to the shortcut sheet and the command menu at the same time.
|
|
36
|
+
|
|
37
|
+
## Don't
|
|
38
|
+
|
|
39
|
+
- Do not bind a destructive action to a single unshifted key.
|
|
40
|
+
- Do not override ⌘S, ⌘F, ⌘L or ⌘R.
|
|
41
|
+
- Do not make Esc close more than one layer at a time.
|
|
42
|
+
|
|
43
|
+
## Related
|
|
44
|
+
|
|
45
|
+
- Accessibility
|
|
46
|
+
- Consistency
|
|
47
|
+
- Layout
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Keyboard-first navigation
|
|
2
|
+
|
|
3
|
+
Every action has a key shown on its button. J/K move, Enter opens, Esc steps back one layer at a time, ⌘K runs anything, ⌘J asks the assistant.
|
|
4
|
+
|
|
5
|
+
Kind: pattern · Group: Patterns: general
|
|
6
|
+
|
|
7
|
+
**Problem:** Power users triage hundreds of rows a day. If shortcuts differ per screen, or Esc sometimes closes a panel and sometimes clears a selection, people stop trusting the keyboard.
|
|
8
|
+
|
|
9
|
+
**Solution:** One keyboard model across TwoUX: the same keys mean the same thing everywhere, shortcuts are shown on buttons, ? opens the full list, and single-key shortcuts can be turned off.
|
|
10
|
+
|
|
11
|
+
**Built from:** Command palette (⌘K), Shortcut sheet (?), Keyboard shortcut hint, List table, Side panel (drawer), Assistant side panel, Inbox (triage)
|
|
12
|
+
|
|
13
|
+
## How it works
|
|
14
|
+
|
|
15
|
+
1. J and K move the row focus; X selects; ⇧J extends the selection.
|
|
16
|
+
2. Enter opens the focused row in the side panel; ⇧↵ opens the full page.
|
|
17
|
+
3. Esc closes the top-most layer only, in this order: open menu or popover, then text field edit, then dialog, then side panel, then selection.
|
|
18
|
+
4. ⌘K opens the command palette: actions on the current selection first, then Go to. ↑↓ move, ↵ runs, Tab changes scope.
|
|
19
|
+
5. ⌘J opens the assistant with the current selection and filters as context.
|
|
20
|
+
6. ? opens the shortcut sheet, which also holds the switch for single-key shortcuts.
|
|
21
|
+
|
|
22
|
+
## When to use
|
|
23
|
+
|
|
24
|
+
- On every screen. A new action is not finished until it has a key, a place in ⌘K and a hint on its button.
|
|
25
|
+
|
|
26
|
+
## When not to use
|
|
27
|
+
|
|
28
|
+
- Don't add single-key shortcuts inside text fields or the composer; there the keys type text.
|
|
29
|
+
- Don't make a shortcut the only path to an action; every action is also a visible control.
|
|
30
|
+
|
|
31
|
+
## Guidelines
|
|
32
|
+
|
|
33
|
+
- Show the shortcut on the button or menu item itself so people learn it by using the product.
|
|
34
|
+
- Keep the set small and mnemonic: C create, E edit, F filter, T extend, D duplicate.
|
|
35
|
+
- Avoid ⌘ plus a single key that the browser or OS owns, except deliberate, well-used ones such as ⌘K.
|
|
36
|
+
- Single-key shortcuts can be turned off; ⌘ shortcuts stay on.
|
|
37
|
+
- Focus is always visible and never lost to the page body when a row or panel disappears.
|
|
38
|
+
- Use the same keys as tools people already know (J/K, ⌘K) instead of inventing new ones.
|
|
39
|
+
|
|
40
|
+
## Content
|
|
41
|
+
|
|
42
|
+
- Hints use symbols: ⌘K, ⇧↵, Esc. Shown in a muted key cap after the label.
|
|
43
|
+
- The shortcut sheet groups keys by Navigate, Table and Act.
|
|
44
|
+
|
|
45
|
+
## Accessibility
|
|
46
|
+
|
|
47
|
+
- Everything works by keyboard alone.
|
|
48
|
+
- Lists use roving tabindex so Tab enters and leaves a list in one step and arrows move inside it.
|
|
49
|
+
- Single-character shortcuts can be turned off for screen reader and voice control users.
|
|
50
|
+
- Closing a layer returns focus to the element that opened it.
|
|
51
|
+
|
|
52
|
+
## Do
|
|
53
|
+
|
|
54
|
+
- Do keep Esc's order the same on every screen.
|
|
55
|
+
- Do list every shortcut in ? and in ⌘K.
|
|
56
|
+
|
|
57
|
+
## Don't
|
|
58
|
+
|
|
59
|
+
- Don't let one Esc press close two layers.
|
|
60
|
+
- Don't reuse a key for different actions on different pages.
|
|
61
|
+
|
|
62
|
+
## Related
|
|
63
|
+
|
|
64
|
+
- Record detail: side panel, overlay or full page
|
|
65
|
+
- Selection and bulk actions
|
|
66
|
+
- Ask about what's on screen
|
|
67
|
+
- Command palette (⌘K)
|
|
68
|
+
- Shortcut sheet (?)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Keyboard shortcut hint
|
|
2
|
+
|
|
3
|
+
Prints the key or keys that run an action, on its button, menu item or tooltip, so people learn shortcuts by using the product.
|
|
4
|
+
|
|
5
|
+
Kind: component · Group: Actions and inputs · Status: built, import from @twoux/ui
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
- On buttons and menu items whose action has a shortcut: Try again R, Edit E.
|
|
10
|
+
- In tooltips of icon-only buttons.
|
|
11
|
+
- In the command palette, the ? shortcut sheet and footers that list navigation keys.
|
|
12
|
+
|
|
13
|
+
## When not to use
|
|
14
|
+
|
|
15
|
+
- For shortcuts that do not work in the current context. Leave the hint out.
|
|
16
|
+
- As the only way to reach an action. Every shortcut duplicates a visible control.
|
|
17
|
+
- Inside body text as decoration. Use plain text such as press Esc.
|
|
18
|
+
|
|
19
|
+
## Structure
|
|
20
|
+
|
|
21
|
+
1. Key cap (18px, mono 10.5px)
|
|
22
|
+
2. Further key caps for chords or sequences
|
|
23
|
+
|
|
24
|
+
## Guidelines
|
|
25
|
+
|
|
26
|
+
- Key cap is 18px high, 4px radius, 2px bottom border, grey surface. On buttons it shrinks to 16px and sits after the label.
|
|
27
|
+
- On primary buttons the cap is translucent white so it keeps contrast on primary.
|
|
28
|
+
- Chords show keys side by side (⌘ K); sequences show them in order (G then L).
|
|
29
|
+
- Render ⌘ on Mac and Ctrl elsewhere.
|
|
30
|
+
- Reserve shortcuts for frequent actions; keep them to one or two keys and never override copy, paste or undo.
|
|
31
|
+
|
|
32
|
+
## Content
|
|
33
|
+
|
|
34
|
+
- Use symbols for modifiers and capitals for letters: ⌘, ⇧, ↵, Esc, E.
|
|
35
|
+
- Use mnemonic keys: E for Edit, C for Create, F for Filter.
|
|
36
|
+
- The same action keeps the same key everywhere.
|
|
37
|
+
|
|
38
|
+
## Accessibility
|
|
39
|
+
|
|
40
|
+
- Single-key shortcuts (J, K, X, E, /) can be turned off in the shortcut sheet; ⌘ shortcuts stay on.
|
|
41
|
+
- Shortcuts avoid keys used by screen readers, such as Caps Lock and Insert combinations.
|
|
42
|
+
- The hint is visual. The full list is in the ? sheet so assistive technology users can find it.
|
|
43
|
+
- Every action also works by Tab and Enter.
|
|
44
|
+
- Key cap text has at least 4.5:1 contrast on its background.
|
|
45
|
+
|
|
46
|
+
## Keyboard
|
|
47
|
+
|
|
48
|
+
| Keys | Action |
|
|
49
|
+
|---|---|
|
|
50
|
+
| ⌘K | Open the command palette |
|
|
51
|
+
| ? | Open the shortcut sheet |
|
|
52
|
+
| G then L | Go to listings |
|
|
53
|
+
| J / K | Next or previous row |
|
|
54
|
+
| C | New listing |
|
|
55
|
+
| E | Edit |
|
|
56
|
+
|
|
57
|
+
## Examples
|
|
58
|
+
|
|
59
|
+
### keys
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { Kbd } from "@twoux/ui";
|
|
63
|
+
|
|
64
|
+
export const meta = {
|
|
65
|
+
title: "Keys",
|
|
66
|
+
description: "One Kbd per key. Use symbols for modifiers: ⌘ ⇧ ⌥ ↵.",
|
|
67
|
+
order: 1,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default function Example() {
|
|
71
|
+
return (
|
|
72
|
+
<dl className="grid grid-cols-[auto_1fr] items-center gap-x-6 gap-y-2">
|
|
73
|
+
<dd className="flex gap-0.5"><Kbd>⌘</Kbd><Kbd>K</Kbd></dd><dt className="text-ink-2">Search or run a command</dt>
|
|
74
|
+
<dd className="flex gap-0.5"><Kbd>J</Kbd><Kbd>K</Kbd></dd><dt className="text-ink-2">Next and previous row</dt>
|
|
75
|
+
<dd className="flex gap-0.5"><Kbd>⇧</Kbd><Kbd>H</Kbd></dd><dt className="text-ink-2">Snooze</dt>
|
|
76
|
+
<dd className="flex gap-0.5"><Kbd>Esc</Kbd></dd><dt className="text-ink-2">Close</dt>
|
|
77
|
+
</dl>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Related
|
|
83
|
+
|
|
84
|
+
- Button
|
|
85
|
+
- Dropdown menu
|
|
86
|
+
- Tooltip
|
|
87
|
+
- Switch
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Shortcut sheet (?)
|
|
2
|
+
|
|
3
|
+
A panel listing every shortcut by task, opened with ?, which also holds the switch to turn single-key shortcuts off.
|
|
4
|
+
|
|
5
|
+
Kind: component · Group: Navigation · Status: built, import from @twoux/ui
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
- Reference for people who want to learn the faster path after using the visible controls.
|
|
10
|
+
- The single place to turn single-key shortcuts off.
|
|
11
|
+
- Supporting expert users who already rely on shortcuts and want the full list in one view.
|
|
12
|
+
|
|
13
|
+
## When not to use
|
|
14
|
+
|
|
15
|
+
- As the main way to discover shortcuts. Show each key on its button, menu item and palette row.
|
|
16
|
+
- Searching for an action to run. Use the Command palette.
|
|
17
|
+
|
|
18
|
+
## Structure
|
|
19
|
+
|
|
20
|
+
1. Toggle: Single-key shortcuts, with the note "Turn off if you use a screen reader or voice control. ⌘ shortcuts stay on."
|
|
21
|
+
2. Group: Navigate (⌘K, G L, G P, /)
|
|
22
|
+
3. Group: Table (J K, X, ⇧J, ↵)
|
|
23
|
+
4. Group: Act (C, E, F, ⌘Z)
|
|
24
|
+
5. Each row: action name left, key caps right
|
|
25
|
+
|
|
26
|
+
## Guidelines
|
|
27
|
+
|
|
28
|
+
- Opens with ? from anywhere outside a text field, and from the Help menu.
|
|
29
|
+
- Group shortcuts by task, a handful per group, so the sheet can be scanned.
|
|
30
|
+
- Single-key shortcuts (C, E, F, J, K, X, R, G sequences) can be turned off; ⌘ shortcuts stay on.
|
|
31
|
+
- Single-key shortcuts never fire while focus is in a text input.
|
|
32
|
+
- Avoid keys that clash with the browser, the operating system or screen readers, and never override copy, paste or save.
|
|
33
|
+
- Prefer one or two letters with a mnemonic (C create, E edit, F filter) over stacked modifiers.
|
|
34
|
+
|
|
35
|
+
## Content
|
|
36
|
+
|
|
37
|
+
- Action names match the button labels they belong to.
|
|
38
|
+
- Show keys as the symbols printed on the keyboard (⌘, ⇧, ↵) and give the Windows equivalent.
|
|
39
|
+
- The off switch says who it is for in plain words.
|
|
40
|
+
|
|
41
|
+
## Accessibility
|
|
42
|
+
|
|
43
|
+
- Meets 2.1.4 Character Key Shortcuts by letting people turn single-key shortcuts off.
|
|
44
|
+
- Every shortcut is an extra route; the same action is reachable by Tab and Enter (2.1.1).
|
|
45
|
+
- Shown as a modal dialog with a heading; Esc closes it and focus returns (2.4.3).
|
|
46
|
+
- The toggle is a real switch with its state exposed (4.1.2).
|
|
47
|
+
|
|
48
|
+
## Keyboard
|
|
49
|
+
|
|
50
|
+
| Keys | Action |
|
|
51
|
+
|---|---|
|
|
52
|
+
| ? | Open the shortcut sheet |
|
|
53
|
+
| Esc | Close it |
|
|
54
|
+
| Tab | Reach the single-key shortcut switch |
|
|
55
|
+
|
|
56
|
+
## Examples
|
|
57
|
+
|
|
58
|
+
### sheet
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { Button, ShortcutSheet } from "@twoux/ui";
|
|
62
|
+
import { useState } from "react";
|
|
63
|
+
|
|
64
|
+
export const meta = { title: "Every shortcut, by task", description: "Press ? anywhere outside a text field. The switch at the top turns single-key shortcuts off for screen reader and voice control users; ⌘ shortcuts stay on.", order: 1 };
|
|
65
|
+
|
|
66
|
+
export default function Example() {
|
|
67
|
+
const [single, setSingle] = useState(true);
|
|
68
|
+
return (
|
|
69
|
+
<div className="grid justify-items-start gap-2">
|
|
70
|
+
<Button variant="outline" onClick={() => document.dispatchEvent(new KeyboardEvent("keydown", { key: "?" }))}>Show shortcuts (?)</Button>
|
|
71
|
+
<span className="text-sm text-ink-2">Single-key shortcuts are {single ? "on" : "off"}.</span>
|
|
72
|
+
<ShortcutSheet
|
|
73
|
+
singleKeys={single}
|
|
74
|
+
onSingleKeysChange={setSingle}
|
|
75
|
+
groups={[
|
|
76
|
+
{ title: "Navigate", items: [{ keys: ["⌘", "K"], action: "Search or run a command" }, { keys: ["G", "L"], action: "Go to Listings" }, { keys: ["G", "I"], action: "Go to Inbox" }, { keys: ["/"], action: "Search this list" }] },
|
|
77
|
+
{ title: "Table", items: [{ keys: ["J"], action: "Next row" }, { keys: ["K"], action: "Previous row" }, { keys: ["X"], action: "Select row" }, { keys: ["↵"], action: "Open in side panel" }] },
|
|
78
|
+
{ title: "Act", items: [{ keys: ["C"], action: "New listing" }, { keys: ["F"], action: "Add a filter" }, { keys: ["⌘", "Z"], action: "Undo" }] },
|
|
79
|
+
]}
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Related
|
|
87
|
+
|
|
88
|
+
- Command palette (⌘K)
|
|
89
|
+
- App shell and sidebar navigation
|
|
90
|
+
- Page header
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Labelling AI output
|
|
2
|
+
|
|
3
|
+
Mark generated content with one small origin mark next to it. No AI colour, no sparkle on every button, no "AI-powered" copy.
|
|
4
|
+
|
|
5
|
+
Kind: pattern · Group: Patterns: AI
|
|
6
|
+
|
|
7
|
+
**Problem:** People need to know which values a model wrote before they rely on them. But products that colour and sparkle every AI feature teach people to ignore the marks, and each team styles them differently.
|
|
8
|
+
|
|
9
|
+
**Solution:** Generated content carries the origin mark and a line such as "Assistant · from your workspace data". Generated cells get the mark and a faint neutral tint and show when they were written. Buttons that start AI work look like every other button.
|
|
10
|
+
|
|
11
|
+
**Built from:** AI origin label, AI column, Assistant side panel, Suggested changes, Export menu, Colours
|
|
12
|
+
|
|
13
|
+
## How it works
|
|
14
|
+
|
|
15
|
+
1. Put the origin mark next to the generated output itself: under an answer, in a generated column header, on a drafted field.
|
|
16
|
+
2. When a whole group is generated, label the group header once instead of every item.
|
|
17
|
+
3. Say what produced it and from what: "Assistant · from your workspace data".
|
|
18
|
+
4. When a person edits a generated value, it becomes theirs and the mark goes; the original stays in history.
|
|
19
|
+
5. Exports name generated columns so they are never mistaken for real data.
|
|
20
|
+
|
|
21
|
+
## When to use
|
|
22
|
+
|
|
23
|
+
- For any value, text or chart the assistant or an agent produced that a person has not yet edited.
|
|
24
|
+
|
|
25
|
+
## When not to use
|
|
26
|
+
|
|
27
|
+
- On buttons and entry points. Name the action instead ("Ask", "Suggest titles").
|
|
28
|
+
- For non-generative automation such as rules or sorting.
|
|
29
|
+
|
|
30
|
+
## Guidelines
|
|
31
|
+
|
|
32
|
+
- One mark, used only for generated output, never as decoration.
|
|
33
|
+
- No separate AI colour. The tint on generated cells is a neutral surface so status and data colours keep their meaning.
|
|
34
|
+
- Label the action, not the technology: "Summarised from 12 notes" beats "AI-generated".
|
|
35
|
+
- Pair the mark with a way to see why: hovering it shows the sources and when it was written.
|
|
36
|
+
- Feedback (good, bad) sits under every answer next to the mark.
|
|
37
|
+
- The origin label is only for generative output. Rule-based automation (auto-close on expiry, duplicate detection) says what rule did it instead: "Closed automatically on 6 Dec".
|
|
38
|
+
- The more control an action hands over, the clearer its label before it runs: "Runs as Listings checker · changes need approval" on a scheduled task.
|
|
39
|
+
- If the whole surface is the assistant, don't repeat the mark on every part. The answer row carries it once.
|
|
40
|
+
|
|
41
|
+
## Content
|
|
42
|
+
|
|
43
|
+
- Use "Assistant" as the name. Avoid "magic", "smart" and "AI-powered".
|
|
44
|
+
- Mark text is short: "Assistant · 2 min ago".
|
|
45
|
+
|
|
46
|
+
## Accessibility
|
|
47
|
+
|
|
48
|
+
- The mark has a text label for screen readers ("Written by Assistant"); it is not only an icon or a tint.
|
|
49
|
+
- The tint meets contrast for the text on it.
|
|
50
|
+
|
|
51
|
+
## Do
|
|
52
|
+
|
|
53
|
+
- Do label generated output close to where it appears.
|
|
54
|
+
- Do remove the mark once a person has edited the value.
|
|
55
|
+
|
|
56
|
+
## Don't
|
|
57
|
+
|
|
58
|
+
- Don't give AI features their own colour or gradient.
|
|
59
|
+
- Don't add a sparkle to every button that calls a model.
|
|
60
|
+
|
|
61
|
+
## Related
|
|
62
|
+
|
|
63
|
+
- Citing sources
|
|
64
|
+
- Generated table columns and enrichment
|
|
65
|
+
- Ask about what's on screen
|
|
66
|
+
- AI origin label
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Layout
|
|
2
|
+
|
|
3
|
+
One app shell for the whole product: a 224px side navigation on the grey --bg, and an inset white canvas where the work happens. Record details open in a side panel that overlays by default and can push the list aside. Below 860px the shell collapses to one column.
|
|
4
|
+
|
|
5
|
+
Kind: foundation · Group: Visual foundation
|
|
6
|
+
|
|
7
|
+
## Principles
|
|
8
|
+
|
|
9
|
+
- One shell, every screen. A product uses only one app layout; TwoUX has one, so navigation never moves.
|
|
10
|
+
- Familiar beats novel. A left nav with a central canvas is the layout people already know from other work tools.
|
|
11
|
+
- Keep the list in view. Opening a record should not lose the user's place in the list; a split view shows item details next to the collection.
|
|
12
|
+
- Design for widths, not devices. Don't design for specific screen sizes or devices.
|
|
13
|
+
|
|
14
|
+
## Guidelines
|
|
15
|
+
|
|
16
|
+
- Shell: .app is a two-column grid, side nav 224px and canvas 1fr, on --bg. The canvas is --surface with 8px margin, a 1px --line border and --r-lg corners, so the work area reads as one sheet inset in the chrome.
|
|
17
|
+
- Canvas anatomy, top to bottom: a 44px top bar (breadcrumb, Ask ⌘J, command search ⌘K), the page header (h1 at --t-2xl and up to two actions), then content. Repeated across every view in the same order.
|
|
18
|
+
- Side panel, overlay (default): 440px, slides over the right of the canvas, below the top bar. Use it to peek at a record while moving through the list with J and K. It suits tables with few important columns.
|
|
19
|
+
- Side panel, push (side by side, ⇧P): the page gets a right margin so the list and panel sit together without overlap. Use it when comparing a record with its neighbours or when the hidden columns matter. People can change the panel position, and TwoUX remembers the choice.
|
|
20
|
+
- Full page (Open, ⇧↵): for editing and long reading. Modal dialogs are only for short, blocking decisions such as confirming a close.
|
|
21
|
+
- Breakpoints: at 860px and below the side nav hides and grids go to one column; at 1100px and above wide dashboard tiles may span two columns. Components also use 560, 640 and 760px; these should be folded into the two shell breakpoints.
|
|
22
|
+
- Reading width: AI answers and long descriptions are capped near 80 characters even on wide canvases.
|
|
23
|
+
|
|
24
|
+
## Accessibility
|
|
25
|
+
|
|
26
|
+
- An overlay panel must not entirely cover the focused element; when a row behind the panel has focus, scroll it clear or switch to push.
|
|
27
|
+
- At 320 CSS px wide the page reflows to one column; data tables may scroll inside their own container.
|
|
28
|
+
- Navigation keeps the same relative order on every page.
|
|
29
|
+
- Moving focus into the panel on open and back to the row on close keeps focus order meaningful.
|
|
30
|
+
|
|
31
|
+
## Do
|
|
32
|
+
|
|
33
|
+
- Use the shell component for every route, including settings and the assistant.
|
|
34
|
+
- Open records in the side panel from lists; open them as a page from links elsewhere.
|
|
35
|
+
|
|
36
|
+
## Don't
|
|
37
|
+
|
|
38
|
+
- Do not build a second layout for one feature.
|
|
39
|
+
- Do not use a modal to show record details.
|
|
40
|
+
- Do not let an overlay panel cover the selected row.
|
|
41
|
+
|
|
42
|
+
## Related
|
|
43
|
+
|
|
44
|
+
- Content density
|
|
45
|
+
- Keyboard model
|
|
46
|
+
- Shape and elevation
|
|
47
|
+
- Spacing
|