@oprt/react 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 +21 -0
- package/README.md +105 -2
- package/dist/ActionStatus/ActionStatus.js +104 -0
- package/dist/ActionStatus/ActionStatus.manifest.js +64 -0
- package/dist/ActionStatus/index.js +7 -0
- package/dist/Alert/Alert.js +86 -0
- package/dist/Alert/Alert.manifest.js +36 -0
- package/dist/Alert/index.js +7 -0
- package/dist/AppShell/AppShell.js +103 -0
- package/dist/AppShell/AppShell.manifest.js +66 -0
- package/dist/AppShell/index.js +9 -0
- package/dist/AttachmentPreview/AttachmentPreview.js +145 -0
- package/dist/AttachmentPreview/AttachmentPreview.manifest.js +42 -0
- package/dist/AttachmentPreview/index.js +9 -0
- package/dist/Avatar/Avatar.js +87 -0
- package/dist/Avatar/Avatar.manifest.js +25 -0
- package/dist/Avatar/index.js +7 -0
- package/dist/Badge/Badge.js +124 -0
- package/dist/Badge/Badge.manifest.js +41 -0
- package/dist/Badge/index.js +7 -0
- package/dist/Breadcrumb/Breadcrumb.js +64 -0
- package/dist/Breadcrumb/Breadcrumb.manifest.js +28 -0
- package/dist/Breadcrumb/index.js +7 -0
- package/dist/BulkActionBar/BulkActionBar.js +145 -0
- package/dist/BulkActionBar/BulkActionBar.manifest.js +46 -0
- package/dist/BulkActionBar/index.js +9 -0
- package/dist/BulkActionBar/selection.js +44 -0
- package/dist/BulkResults/BulkResults.js +269 -0
- package/dist/BulkResults/BulkResults.manifest.js +45 -0
- package/dist/BulkResults/index.js +7 -0
- package/dist/Button/Button.js +170 -0
- package/dist/Button/Button.manifest.js +36 -0
- package/dist/Button/index.js +7 -0
- package/dist/ButtonGroup/ButtonGroup.js +60 -0
- package/dist/ButtonGroup/ButtonGroup.manifest.js +22 -0
- package/dist/ButtonGroup/index.js +7 -0
- package/dist/Calendar/Calendar.js +106 -0
- package/dist/Calendar/Calendar.manifest.js +32 -0
- package/dist/Calendar/index.js +7 -0
- package/dist/Card/Card.js +70 -0
- package/dist/Card/Card.manifest.js +57 -0
- package/dist/Card/index.js +16 -0
- package/dist/Chart/Chart.js +1200 -0
- package/dist/Chart/Chart.manifest.js +110 -0
- package/dist/Chart/ChartControls.js +190 -0
- package/dist/Chart/geometry.js +217 -0
- package/dist/Chart/index.js +9 -0
- package/dist/Checkbox/Checkbox.js +166 -0
- package/dist/Checkbox/Checkbox.manifest.js +38 -0
- package/dist/Checkbox/index.js +7 -0
- package/dist/Collapsible/Collapsible.js +177 -0
- package/dist/Collapsible/Collapsible.manifest.js +54 -0
- package/dist/Collapsible/index.js +12 -0
- package/dist/CollectionState/CollectionState.js +68 -0
- package/dist/CollectionState/CollectionState.manifest.js +44 -0
- package/dist/CollectionState/index.js +7 -0
- package/dist/ComboBox/ComboBox.js +221 -0
- package/dist/ComboBox/ComboBox.manifest.js +87 -0
- package/dist/ComboBox/index.js +7 -0
- package/dist/CommandPalette/CommandPalette.js +276 -0
- package/dist/CommandPalette/CommandPalette.manifest.js +24 -0
- package/dist/CommandPalette/index.js +7 -0
- package/dist/ConfirmDialog/ConfirmDialog.js +84 -0
- package/dist/ConfirmDialog/ConfirmDialog.manifest.js +32 -0
- package/dist/ConfirmDialog/index.js +7 -0
- package/dist/ContextMenu/ContextMenu.js +192 -0
- package/dist/ContextMenu/ContextMenu.manifest.js +41 -0
- package/dist/ContextMenu/index.js +7 -0
- package/dist/CoordinateInput/CoordinateInput.js +141 -0
- package/dist/CoordinateInput/CoordinateInput.manifest.js +36 -0
- package/dist/CoordinateInput/index.js +9 -0
- package/dist/CopyButton/CopyButton.js +110 -0
- package/dist/CopyButton/CopyButton.manifest.js +35 -0
- package/dist/CopyButton/index.js +7 -0
- package/dist/DataGrid/DataGrid.js +459 -0
- package/dist/DataGrid/DataGrid.manifest.js +135 -0
- package/dist/DataGrid/PageControls.js +41 -0
- package/dist/DataGrid/index.js +9 -0
- package/dist/DataTable/DataTable.js +375 -0
- package/dist/DataTable/DataTable.manifest.js +86 -0
- package/dist/DataTable/index.js +9 -0
- package/dist/DataTable/sort.js +45 -0
- package/dist/DataTable/useScrollsSideways.js +61 -0
- package/dist/DataTable/useTableWindow.js +185 -0
- package/dist/DatePicker/DatePicker.js +187 -0
- package/dist/DatePicker/DatePicker.manifest.js +40 -0
- package/dist/DatePicker/index.js +7 -0
- package/dist/DateRangePicker/DateRangePicker.js +156 -0
- package/dist/DateRangePicker/DateRangePicker.manifest.js +41 -0
- package/dist/DateRangePicker/index.js +7 -0
- package/dist/DateTimePicker/DateTimePicker.js +213 -0
- package/dist/DateTimePicker/DateTimePicker.manifest.js +44 -0
- package/dist/DateTimePicker/index.js +7 -0
- package/dist/DescriptionList/DescriptionList.js +93 -0
- package/dist/DescriptionList/DescriptionList.manifest.js +40 -0
- package/dist/DescriptionList/index.js +9 -0
- package/dist/Dialog/Dialog.js +214 -0
- package/dist/Dialog/Dialog.manifest.js +31 -0
- package/dist/Dialog/index.js +7 -0
- package/dist/Divider/Divider.js +64 -0
- package/dist/Divider/Divider.manifest.js +21 -0
- package/dist/Divider/index.js +7 -0
- package/dist/DropdownMenu/DropdownMenu.js +170 -0
- package/dist/DropdownMenu/DropdownMenu.manifest.js +82 -0
- package/dist/DropdownMenu/index.js +16 -0
- package/dist/EntityPreview/EntityPreview.js +82 -0
- package/dist/EntityPreview/EntityPreview.manifest.js +43 -0
- package/dist/EntityPreview/index.js +7 -0
- package/dist/EventTimeline/EventTimeline.js +249 -0
- package/dist/EventTimeline/EventTimeline.manifest.js +57 -0
- package/dist/EventTimeline/index.js +7 -0
- package/dist/Field/Field.js +81 -0
- package/dist/Field/Field.manifest.js +32 -0
- package/dist/Field/index.js +9 -0
- package/dist/FileUpload/FileUpload.js +215 -0
- package/dist/FileUpload/FileUpload.manifest.js +48 -0
- package/dist/FileUpload/index.js +7 -0
- package/dist/FilterBar/FilterBar.js +173 -0
- package/dist/FilterBar/FilterBar.manifest.js +49 -0
- package/dist/FilterBar/index.js +7 -0
- package/dist/FormErrorSummary/FormErrorSummary.js +70 -0
- package/dist/FormErrorSummary/FormErrorSummary.manifest.js +29 -0
- package/dist/FormErrorSummary/index.js +9 -0
- package/dist/FormSection/FormSection.js +51 -0
- package/dist/FormSection/FormSection.manifest.js +30 -0
- package/dist/FormSection/index.js +7 -0
- package/dist/InlineEdit/InlineEdit.js +261 -0
- package/dist/InlineEdit/InlineEdit.manifest.js +40 -0
- package/dist/InlineEdit/index.js +7 -0
- package/dist/Input/Input.js +126 -0
- package/dist/Input/Input.manifest.js +49 -0
- package/dist/Input/index.js +7 -0
- package/dist/Inspector/Inspector.js +63 -0
- package/dist/Inspector/Inspector.manifest.js +35 -0
- package/dist/Inspector/index.js +7 -0
- package/dist/JobStatus/JobStatus.js +118 -0
- package/dist/JobStatus/JobStatus.manifest.js +53 -0
- package/dist/JobStatus/index.js +7 -0
- package/dist/LayerControl/LayerControl.js +199 -0
- package/dist/LayerControl/LayerControl.manifest.js +34 -0
- package/dist/LayerControl/index.js +7 -0
- package/dist/Link/Link.js +83 -0
- package/dist/Link/Link.manifest.js +37 -0
- package/dist/Link/index.js +7 -0
- package/dist/MapControls/MapControls.js +122 -0
- package/dist/MapControls/MapControls.manifest.js +31 -0
- package/dist/MapControls/index.js +7 -0
- package/dist/MapLegend/MapLegend.js +89 -0
- package/dist/MapLegend/MapLegend.manifest.js +29 -0
- package/dist/MapLegend/index.js +7 -0
- package/dist/MapScale/MapScale.js +96 -0
- package/dist/MapScale/MapScale.manifest.js +31 -0
- package/dist/MapScale/index.js +7 -0
- package/dist/MediaFrame/MediaFrame.js +113 -0
- package/dist/MediaFrame/MediaFrame.manifest.js +57 -0
- package/dist/MediaFrame/index.js +7 -0
- package/dist/MultiSelect/MultiSelect.js +113 -0
- package/dist/MultiSelect/MultiSelect.manifest.js +51 -0
- package/dist/MultiSelect/index.js +7 -0
- package/dist/NumberInput/NumberInput.js +210 -0
- package/dist/NumberInput/NumberInput.manifest.js +56 -0
- package/dist/NumberInput/index.js +7 -0
- package/dist/OperationalStatus/OperationalStatus.js +89 -0
- package/dist/OperationalStatus/OperationalStatus.manifest.js +39 -0
- package/dist/OperationalStatus/index.js +9 -0
- package/dist/PlaybackControls/PlaybackControls.js +289 -0
- package/dist/PlaybackControls/PlaybackControls.manifest.js +85 -0
- package/dist/PlaybackControls/index.js +7 -0
- package/dist/Popover/Popover.js +302 -0
- package/dist/Popover/Popover.manifest.js +50 -0
- package/dist/Popover/index.js +7 -0
- package/dist/Progress/Progress.js +132 -0
- package/dist/Progress/Progress.manifest.js +30 -0
- package/dist/Progress/index.js +7 -0
- package/dist/PropertyFilter/PropertyFilter.js +306 -0
- package/dist/PropertyFilter/PropertyFilter.manifest.js +32 -0
- package/dist/PropertyFilter/index.js +11 -0
- package/dist/PropertyFilter/tokenError.js +17 -0
- package/dist/RadioGroup/RadioGroup.js +143 -0
- package/dist/RadioGroup/RadioGroup.manifest.js +44 -0
- package/dist/RadioGroup/index.js +9 -0
- package/dist/Select/Select.js +219 -0
- package/dist/Select/Select.manifest.js +77 -0
- package/dist/Select/index.js +9 -0
- package/dist/Sidebar/Sidebar.js +146 -0
- package/dist/Sidebar/Sidebar.manifest.js +72 -0
- package/dist/Sidebar/index.js +18 -0
- package/dist/Skeleton/Skeleton.js +76 -0
- package/dist/Skeleton/Skeleton.manifest.js +30 -0
- package/dist/Skeleton/index.js +7 -0
- package/dist/Slider/Slider.js +246 -0
- package/dist/Slider/Slider.manifest.js +56 -0
- package/dist/Slider/index.js +7 -0
- package/dist/Sparkline/Sparkline.js +135 -0
- package/dist/Sparkline/Sparkline.manifest.js +37 -0
- package/dist/Sparkline/index.js +7 -0
- package/dist/SplitPane/SplitPane.js +316 -0
- package/dist/SplitPane/SplitPane.manifest.js +79 -0
- package/dist/SplitPane/index.js +7 -0
- package/dist/StatCard/StatCard.js +163 -0
- package/dist/StatCard/StatCard.manifest.js +45 -0
- package/dist/StatCard/index.js +7 -0
- package/dist/Tabs/Tabs.js +181 -0
- package/dist/Tabs/Tabs.manifest.js +72 -0
- package/dist/Tabs/index.js +16 -0
- package/dist/Tabs/useTabsIndicator.js +71 -0
- package/dist/Tabs/useTabsScroll.js +123 -0
- package/dist/TagGroup/TagGroup.js +142 -0
- package/dist/TagGroup/TagGroup.manifest.js +35 -0
- package/dist/TagGroup/index.js +7 -0
- package/dist/Textarea/Textarea.js +68 -0
- package/dist/Textarea/Textarea.manifest.js +25 -0
- package/dist/Textarea/index.js +7 -0
- package/dist/TimeField/TimeField.js +118 -0
- package/dist/TimeField/TimeField.manifest.js +42 -0
- package/dist/TimeField/index.js +7 -0
- package/dist/TimeRange/TimeRange.js +184 -0
- package/dist/TimeRange/TimeRange.manifest.js +48 -0
- package/dist/TimeRange/index.js +9 -0
- package/dist/Toast/Toast.js +188 -0
- package/dist/Toast/Toast.manifest.js +77 -0
- package/dist/Toast/index.js +9 -0
- package/dist/Toggle/Toggle.js +154 -0
- package/dist/Toggle/Toggle.manifest.js +54 -0
- package/dist/Toggle/index.js +7 -0
- package/dist/Toolbar/Toolbar.js +86 -0
- package/dist/Toolbar/Toolbar.manifest.js +70 -0
- package/dist/Toolbar/index.js +12 -0
- package/dist/Tooltip/Tooltip.js +122 -0
- package/dist/Tooltip/Tooltip.manifest.js +27 -0
- package/dist/Tooltip/index.js +7 -0
- package/dist/TreeView/TreeView.js +129 -0
- package/dist/TreeView/TreeView.manifest.js +56 -0
- package/dist/TreeView/index.js +7 -0
- package/dist/UploadQueue/UploadQueue.js +296 -0
- package/dist/UploadQueue/UploadQueue.manifest.js +34 -0
- package/dist/UploadQueue/index.js +7 -0
- package/dist/_internal/MotionPopover.js +113 -0
- package/dist/_internal/aria.js +40 -0
- package/dist/_internal/bytes.js +18 -0
- package/dist/_internal/controlStyles.js +26 -0
- package/dist/_internal/date.js +179 -0
- package/dist/_internal/devValidate.js +51 -0
- package/dist/_internal/fieldIds.js +50 -0
- package/dist/_internal/hydration.js +74 -0
- package/dist/_internal/manifest-entry.js +0 -0
- package/dist/_internal/mergeRefs.js +68 -0
- package/dist/_internal/motion.js +138 -0
- package/dist/_internal/navigationLandmark.js +13 -0
- package/dist/_internal/numberText.js +176 -0
- package/dist/_internal/overlay.js +53 -0
- package/dist/_internal/segmentField.js +125 -0
- package/dist/_internal/suggestions.js +20 -0
- package/dist/_internal/timestamp.js +25 -0
- package/dist/_internal/unavailable.js +13 -0
- package/dist/_internal/useActionFocus.js +27 -0
- package/dist/_internal/useElementWidth.js +37 -0
- package/dist/_internal/useIsMounted.js +18 -0
- package/dist/_internal/useIsomorphicLayoutEffect.js +8 -0
- package/dist/_internal/useRestoreFocusOnRemoval.js +57 -0
- package/dist/index.cjs +17811 -0
- package/dist/index.d.cts +2330 -0
- package/dist/index.d.ts +2330 -0
- package/dist/index.js +407 -0
- package/dist/version.js +8 -0
- package/package.json +80 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OPERATOR contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,106 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @oprt/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React components for operational interfaces: command, control and industrial software. Part of
|
|
4
|
+
the [OPERATOR design system](https://oprt.dev).
|
|
5
|
+
|
|
6
|
+
75 component families, from Button and DataGrid to OperationalStatus, Inspector and MapControls,
|
|
7
|
+
with interactive behavior from React Aria. Every component is dark, square-cornered and keyboard
|
|
8
|
+
operable, and spells its status out instead of relying on color alone, so dense, fast-changing
|
|
9
|
+
screens stay readable.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pnpm add @oprt/react @oprt/tokens
|
|
15
|
+
pnpm add -D @oprt/tailwind tailwindcss@^4.3.3
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
React 18 or later and React DOM are peer dependencies. The components are styled with Tailwind
|
|
19
|
+
CSS 4 and the OPERATOR plugin. Set Tailwind up the way your framework does, then add the plugin
|
|
20
|
+
and the components to the stylesheet where Tailwind is imported:
|
|
21
|
+
|
|
22
|
+
```css
|
|
23
|
+
/* app/globals.css */
|
|
24
|
+
@import "tailwindcss";
|
|
25
|
+
@plugin "@oprt/tailwind";
|
|
26
|
+
/* The components ship as compiled JavaScript, which Tailwind does not scan on its own. The path is
|
|
27
|
+
relative to this file; without it the components render unstyled. */
|
|
28
|
+
@source "../node_modules/@oprt/react/dist";
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Import the tokens once at the application root, before that stylesheet:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import "@oprt/tokens";
|
|
35
|
+
import "./globals.css";
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Load the tokens from JavaScript or a `<link>`, not with an `@import` inside the Tailwind
|
|
39
|
+
stylesheet: the Tailwind CLI inlines an imported file without rewriting its font URLs, and the
|
|
40
|
+
bundled fonts would not load. Inside Tailwind Typography's `prose`, wrap components in an element
|
|
41
|
+
with the `not-prose` class.
|
|
42
|
+
|
|
43
|
+
## Use
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import { Badge, Button, Field, Input } from "@oprt/react";
|
|
47
|
+
|
|
48
|
+
export function Handover() {
|
|
49
|
+
return (
|
|
50
|
+
<form>
|
|
51
|
+
<Field label="Callsign" required>
|
|
52
|
+
<Input placeholder="RAVEN 2" />
|
|
53
|
+
</Field>
|
|
54
|
+
<Badge variant="warning">Stale</Badge>
|
|
55
|
+
<Button type="submit">Acknowledge</Button>
|
|
56
|
+
</form>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Every component's page at [oprt.dev/docs/components](https://oprt.dev/docs/components) shows its
|
|
62
|
+
variants live, with its props, its accessibility behavior and its manifest entry. Six complete
|
|
63
|
+
working screens are at [oprt.dev](https://oprt.dev).
|
|
64
|
+
|
|
65
|
+
## What's included
|
|
66
|
+
|
|
67
|
+
- **Actions and inputs:** Button, ButtonGroup, CopyButton, Field, Input, Textarea, NumberInput,
|
|
68
|
+
CoordinateInput, Checkbox, RadioGroup, Toggle, Slider, Select, ComboBox, MultiSelect, TagGroup,
|
|
69
|
+
InlineEdit, FormSection, FormErrorSummary
|
|
70
|
+
- **Dates and times:** Calendar, DatePicker, DateRangePicker, DateTimePicker, TimeField, TimeRange
|
|
71
|
+
- **Data:** DataTable, DataGrid, Chart, Sparkline, StatCard, EventTimeline, DescriptionList,
|
|
72
|
+
FilterBar, PropertyFilter
|
|
73
|
+
- **Status and feedback:** Badge, Alert, Toast, Progress, Skeleton, OperationalStatus,
|
|
74
|
+
ActionStatus, JobStatus, CollectionState
|
|
75
|
+
- **Bulk work and files:** BulkActionBar, BulkResults, FileUpload, UploadQueue, AttachmentPreview
|
|
76
|
+
- **Layout and navigation:** AppShell, Sidebar, SplitPane, Tabs, Breadcrumb, Toolbar, Collapsible,
|
|
77
|
+
TreeView, Card, Divider, Link, Avatar
|
|
78
|
+
- **Overlays and inspection:** Dialog, ConfirmDialog, Popover, Tooltip, DropdownMenu, ContextMenu,
|
|
79
|
+
CommandPalette, Inspector, EntityPreview
|
|
80
|
+
- **Maps and media:** MapControls, LayerControl, MapLegend, MapScale, MediaFrame, PlaybackControls
|
|
81
|
+
|
|
82
|
+
Motion is tactile and quick. Turn it off for one component with `motion="none"`; the system's
|
|
83
|
+
reduced-motion setting turns it off everywhere.
|
|
84
|
+
|
|
85
|
+
## Server Components and bundle size
|
|
86
|
+
|
|
87
|
+
Each module is its own file, and only the modules that need the browser are marked
|
|
88
|
+
`"use client"`. An app pays only for what it imports, and a Server Component can import the
|
|
89
|
+
manifest entries and data helpers from the package root. ES modules and CommonJS are both
|
|
90
|
+
included.
|
|
91
|
+
|
|
92
|
+
## For coding agents
|
|
93
|
+
|
|
94
|
+
Each family exports its manifest entry (`ButtonManifest`, `DataGridManifest` and so on). In
|
|
95
|
+
development, an invalid option value logs a structured `INVALID_PROP_VALUE` error with the valid
|
|
96
|
+
values and a suggestion; production builds leave it out. For the whole contract, give an agent
|
|
97
|
+
[`@oprt/manifest`](https://www.npmjs.com/package/@oprt/manifest)'s `components.json`,
|
|
98
|
+
or use [`@oprt/cli`](https://www.npmjs.com/package/@oprt/cli) to write the agent's
|
|
99
|
+
instructions and check its code. See [oprt.dev/docs/agents](https://oprt.dev/docs/agents).
|
|
100
|
+
|
|
101
|
+
To own the code instead of installing it, the CLI copies any component, with everything it
|
|
102
|
+
depends on, into your project: `npx @oprt/cli add button`.
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT. The OPERATOR fonts in `@oprt/tokens` are under the SIL Open Font License 1.1.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/ActionStatus/ActionStatus.tsx
|
|
4
|
+
import { forwardRef } from "react";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
import clsx from "clsx";
|
|
7
|
+
import { Badge } from "../Badge/Badge.js";
|
|
8
|
+
import { Button } from "../Button/Button.js";
|
|
9
|
+
import { useActionFocus } from "../_internal/useActionFocus.js";
|
|
10
|
+
import { devValidate } from "../_internal/devValidate.js";
|
|
11
|
+
import { ActionStatusManifest } from "./ActionStatus.manifest.js";
|
|
12
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
var statusStyles = cva(
|
|
14
|
+
"flex min-w-0 flex-col gap-2u border border-oprt-border p-2u font-sans text-oprt-base normal-case text-oprt-text outline-hidden focus-visible:shadow-oprt-focus"
|
|
15
|
+
);
|
|
16
|
+
var variants = {
|
|
17
|
+
submitted: "info",
|
|
18
|
+
accepted: "info",
|
|
19
|
+
rejected: "error",
|
|
20
|
+
"in-progress": "info",
|
|
21
|
+
complete: "success",
|
|
22
|
+
partial: "warning",
|
|
23
|
+
failed: "error",
|
|
24
|
+
timeout: "warning",
|
|
25
|
+
queued: "info",
|
|
26
|
+
running: "info",
|
|
27
|
+
"cancel-requested": "info",
|
|
28
|
+
canceled: "neutral"
|
|
29
|
+
};
|
|
30
|
+
function ActionStatusLine({
|
|
31
|
+
state,
|
|
32
|
+
label,
|
|
33
|
+
message,
|
|
34
|
+
requestId,
|
|
35
|
+
children
|
|
36
|
+
}) {
|
|
37
|
+
return /* @__PURE__ */ jsxs(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
role: "status",
|
|
41
|
+
"aria-live": "polite",
|
|
42
|
+
"aria-atomic": "true",
|
|
43
|
+
className: "flex min-w-0 flex-col gap-1u",
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 oprt-wrap-anywhere font-medium uppercase tracking-oprt-caps", children: label }),
|
|
46
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Badge, { variant: variants[state], indicator: "dot", children: state }) }),
|
|
47
|
+
requestId && /* @__PURE__ */ jsxs("span", { className: "min-w-0 oprt-wrap-anywhere font-mono", children: [
|
|
48
|
+
"Request: ",
|
|
49
|
+
requestId
|
|
50
|
+
] }),
|
|
51
|
+
message && /* @__PURE__ */ jsx("p", { className: "m-0 min-w-0 oprt-wrap-anywhere", children: message }),
|
|
52
|
+
children
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
var ActionStatus = forwardRef((allProps, ref) => {
|
|
58
|
+
const {
|
|
59
|
+
state,
|
|
60
|
+
label,
|
|
61
|
+
message,
|
|
62
|
+
requestId,
|
|
63
|
+
onRetry,
|
|
64
|
+
onCancel,
|
|
65
|
+
retryLabel = "Retry",
|
|
66
|
+
cancelLabel = "Cancel",
|
|
67
|
+
disabled = false,
|
|
68
|
+
className,
|
|
69
|
+
onFocusCapture,
|
|
70
|
+
onBlurCapture,
|
|
71
|
+
...props
|
|
72
|
+
} = allProps;
|
|
73
|
+
const focus = useActionFocus(ref, { onFocusCapture, onBlurCapture });
|
|
74
|
+
if (process.env.NODE_ENV !== "production") {
|
|
75
|
+
devValidate("ActionStatus", ActionStatusManifest.ActionStatus.props, { ...allProps });
|
|
76
|
+
}
|
|
77
|
+
return (
|
|
78
|
+
// The result is a group named by its label, so the place focus moves to is announced by name,
|
|
79
|
+
// as JobStatus's region is. A role or name the caller gives wins.
|
|
80
|
+
/* @__PURE__ */ jsxs(
|
|
81
|
+
"div",
|
|
82
|
+
{
|
|
83
|
+
tabIndex: -1,
|
|
84
|
+
role: "group",
|
|
85
|
+
"aria-label": label,
|
|
86
|
+
...props,
|
|
87
|
+
...focus,
|
|
88
|
+
className: clsx(statusStyles(), className),
|
|
89
|
+
children: [
|
|
90
|
+
/* @__PURE__ */ jsx(ActionStatusLine, { state, label, message, requestId }),
|
|
91
|
+
(onRetry || onCancel) && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1u", children: [
|
|
92
|
+
onRetry && /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", disabled, onClick: onRetry, children: retryLabel }),
|
|
93
|
+
onCancel && /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", disabled, onClick: onCancel, children: cancelLabel })
|
|
94
|
+
] })
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
ActionStatus.displayName = "ActionStatus";
|
|
101
|
+
export {
|
|
102
|
+
ActionStatus,
|
|
103
|
+
ActionStatusLine
|
|
104
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// src/ActionStatus/ActionStatus.manifest.ts
|
|
2
|
+
var ActionStatusManifest = {
|
|
3
|
+
ActionStatus: {
|
|
4
|
+
description: "Stateless authoritative action outcome display with optional application-supported recovery callbacks. When the focused recovery is withdrawn or disabled, focus moves to the result, a group named by its label. Long text wraps.",
|
|
5
|
+
props: {
|
|
6
|
+
state: {
|
|
7
|
+
type: "enum",
|
|
8
|
+
values: [
|
|
9
|
+
"submitted",
|
|
10
|
+
"accepted",
|
|
11
|
+
"rejected",
|
|
12
|
+
"in-progress",
|
|
13
|
+
"complete",
|
|
14
|
+
"partial",
|
|
15
|
+
"failed",
|
|
16
|
+
"timeout",
|
|
17
|
+
"queued",
|
|
18
|
+
"running",
|
|
19
|
+
"cancel-requested",
|
|
20
|
+
"canceled"
|
|
21
|
+
],
|
|
22
|
+
required: true,
|
|
23
|
+
description: "Authoritative application-supplied lifecycle state. Timeout does not imply rejection or completion. A cancel request does not establish cancellation; a supplied complete result can still follow cancel-requested."
|
|
24
|
+
},
|
|
25
|
+
label: {
|
|
26
|
+
type: "string",
|
|
27
|
+
required: true
|
|
28
|
+
},
|
|
29
|
+
message: {
|
|
30
|
+
type: "string"
|
|
31
|
+
},
|
|
32
|
+
requestId: {
|
|
33
|
+
type: "string"
|
|
34
|
+
},
|
|
35
|
+
onRetry: {
|
|
36
|
+
type: "function",
|
|
37
|
+
description: "Render Retry only when retry is supported. Does not change state."
|
|
38
|
+
},
|
|
39
|
+
onCancel: {
|
|
40
|
+
type: "function",
|
|
41
|
+
description: "Render Cancel only when cancellation is supported. Does not change state."
|
|
42
|
+
},
|
|
43
|
+
retryLabel: {
|
|
44
|
+
type: "string",
|
|
45
|
+
default: "Retry"
|
|
46
|
+
},
|
|
47
|
+
cancelLabel: {
|
|
48
|
+
type: "string",
|
|
49
|
+
default: "Cancel"
|
|
50
|
+
},
|
|
51
|
+
disabled: {
|
|
52
|
+
type: "boolean",
|
|
53
|
+
default: false,
|
|
54
|
+
description: "Disables recovery actions without hiding supplied outcomes."
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
composable_with: ["Inspector", "Alert", "AppShell"],
|
|
58
|
+
never_inside: ["Button"],
|
|
59
|
+
example: '<ActionStatus state={result.state} label="Refresh source" message={result.message} requestId={result.id} onRetry={canRetry ? retry : undefined} />'
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
export {
|
|
63
|
+
ActionStatusManifest
|
|
64
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/Alert/Alert.tsx
|
|
4
|
+
import { Info, CheckCircle, AlertTriangle, XCircle, X } from "@oprt/icons";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
import { forwardRef } from "react";
|
|
7
|
+
import clsx from "clsx";
|
|
8
|
+
import { AlertManifest } from "./Alert.manifest.js";
|
|
9
|
+
import { devValidate } from "../_internal/devValidate.js";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
var ICONS = {
|
|
12
|
+
info: Info,
|
|
13
|
+
success: CheckCircle,
|
|
14
|
+
warning: AlertTriangle,
|
|
15
|
+
error: XCircle
|
|
16
|
+
};
|
|
17
|
+
var containerStyles = cva(
|
|
18
|
+
"flex gap-2u px-3u py-2u bg-oprt-surface-1 border border-oprt-border border-l-2 font-sans",
|
|
19
|
+
{
|
|
20
|
+
variants: {
|
|
21
|
+
variant: {
|
|
22
|
+
info: "border-l-oprt-info",
|
|
23
|
+
success: "border-l-oprt-success",
|
|
24
|
+
warning: "border-l-oprt-warning",
|
|
25
|
+
error: "border-l-oprt-error"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
var accentStyles = cva("", {
|
|
31
|
+
variants: {
|
|
32
|
+
variant: {
|
|
33
|
+
info: "text-oprt-info",
|
|
34
|
+
success: "text-oprt-success",
|
|
35
|
+
warning: "text-oprt-warning",
|
|
36
|
+
error: "text-oprt-error"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
var Alert = forwardRef((allProps, ref) => {
|
|
41
|
+
const {
|
|
42
|
+
className,
|
|
43
|
+
variant,
|
|
44
|
+
title,
|
|
45
|
+
dismissible = false,
|
|
46
|
+
onDismiss,
|
|
47
|
+
children,
|
|
48
|
+
...props
|
|
49
|
+
} = allProps;
|
|
50
|
+
const role = variant === "error" || variant === "warning" ? "alert" : "status";
|
|
51
|
+
const Icon = ICONS[variant];
|
|
52
|
+
const hasBody = children != null && typeof children !== "boolean" && children !== "";
|
|
53
|
+
if (process.env.NODE_ENV !== "production") {
|
|
54
|
+
devValidate("Alert", AlertManifest.Alert.props, allProps);
|
|
55
|
+
}
|
|
56
|
+
return /* @__PURE__ */ jsxs("div", { ref, role, className: clsx(containerStyles({ variant }), className), ...props, children: [
|
|
57
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: clsx("shrink-0", accentStyles({ variant })), children: /* @__PURE__ */ jsx(Icon, { size: 16 }) }),
|
|
58
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1u oprt-wrap-anywhere", children: [
|
|
59
|
+
title && /* @__PURE__ */ jsx(
|
|
60
|
+
"p",
|
|
61
|
+
{
|
|
62
|
+
className: clsx(
|
|
63
|
+
"m-0 text-oprt-sm uppercase tracking-oprt-sm",
|
|
64
|
+
accentStyles({ variant })
|
|
65
|
+
),
|
|
66
|
+
children: title
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
hasBody && /* @__PURE__ */ jsx("div", { className: "text-oprt-base normal-case text-oprt-text", children })
|
|
70
|
+
] }),
|
|
71
|
+
dismissible && /* @__PURE__ */ jsx(
|
|
72
|
+
"button",
|
|
73
|
+
{
|
|
74
|
+
type: "button",
|
|
75
|
+
"aria-label": "Dismiss",
|
|
76
|
+
onClick: onDismiss,
|
|
77
|
+
className: "inline-flex items-center justify-center shrink-0 h-oprt-sm w-3u border border-transparent text-oprt-text-dim transition-colors duration-oprt-fast hover:text-oprt-text focus-visible:border-oprt-border-focus focus-visible:shadow-oprt-focus focus-visible:outline-hidden",
|
|
78
|
+
children: /* @__PURE__ */ jsx(X, { size: 12 })
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
] });
|
|
82
|
+
});
|
|
83
|
+
Alert.displayName = "Alert";
|
|
84
|
+
export {
|
|
85
|
+
Alert
|
|
86
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/Alert/Alert.manifest.ts
|
|
2
|
+
var AlertManifest = {
|
|
3
|
+
Alert: {
|
|
4
|
+
description: "Inline status message with a severity icon, semantic left-edge accent, optional title, and optional dismiss control.",
|
|
5
|
+
props: {
|
|
6
|
+
variant: {
|
|
7
|
+
type: "enum",
|
|
8
|
+
values: ["info", "success", "warning", "error"],
|
|
9
|
+
required: true,
|
|
10
|
+
description: "Severity. Drives icon, accent color, and ARIA role (error/warning = alert, info/success = status)."
|
|
11
|
+
},
|
|
12
|
+
title: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "Optional uppercase heading shown above the description."
|
|
15
|
+
},
|
|
16
|
+
dismissible: {
|
|
17
|
+
type: "boolean",
|
|
18
|
+
default: false,
|
|
19
|
+
description: "Render a trailing Dismiss button that calls onDismiss."
|
|
20
|
+
},
|
|
21
|
+
onDismiss: {
|
|
22
|
+
type: "function",
|
|
23
|
+
description: "Called when the Dismiss button is activated."
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
slots: {
|
|
27
|
+
children: { type: "any", required: false }
|
|
28
|
+
},
|
|
29
|
+
composable_with: ["Card", "CardBody"],
|
|
30
|
+
never_inside: ["Alert", "Button", "Badge"],
|
|
31
|
+
example: '<Alert variant="error" title="LINK LOST">Telemetry stream dropped.</Alert>'
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
export {
|
|
35
|
+
AlertManifest
|
|
36
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/AppShell/AppShell.tsx
|
|
4
|
+
import { forwardRef, useId } from "react";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
import clsx from "clsx";
|
|
7
|
+
import { Badge } from "../Badge/Badge.js";
|
|
8
|
+
import { devValidate } from "../_internal/devValidate.js";
|
|
9
|
+
import { InsideNavigationLandmarkProvider } from "../_internal/navigationLandmark.js";
|
|
10
|
+
import { formatUtcTimestamp, isValidTimestamp } from "../_internal/timestamp.js";
|
|
11
|
+
import { AppShellManifest } from "./AppShell.manifest.js";
|
|
12
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
var shellStyles = cva(
|
|
14
|
+
"@container flex w-full min-w-0 flex-col border border-oprt-border bg-oprt-surface-1 font-sans text-oprt-base normal-case text-oprt-text"
|
|
15
|
+
);
|
|
16
|
+
var connectionVariants = {
|
|
17
|
+
connected: "success",
|
|
18
|
+
connecting: "warning",
|
|
19
|
+
reconnecting: "warning",
|
|
20
|
+
offline: "warning",
|
|
21
|
+
unknown: "neutral"
|
|
22
|
+
};
|
|
23
|
+
function connectionVariant(connection) {
|
|
24
|
+
return Object.prototype.hasOwnProperty.call(connectionVariants, connection) ? connectionVariants[connection] : "neutral";
|
|
25
|
+
}
|
|
26
|
+
var AppShell = forwardRef(
|
|
27
|
+
({
|
|
28
|
+
title = "Workspace",
|
|
29
|
+
identity,
|
|
30
|
+
mode = "live",
|
|
31
|
+
connection = "unknown",
|
|
32
|
+
time,
|
|
33
|
+
markings,
|
|
34
|
+
navigation,
|
|
35
|
+
toolbar,
|
|
36
|
+
footer,
|
|
37
|
+
children,
|
|
38
|
+
className,
|
|
39
|
+
...props
|
|
40
|
+
}, ref) => {
|
|
41
|
+
const id = useId();
|
|
42
|
+
if (process.env.NODE_ENV !== "production") {
|
|
43
|
+
devValidate("AppShell", AppShellManifest.AppShell.props, { mode, connection });
|
|
44
|
+
}
|
|
45
|
+
const shown = isValidTimestamp(time) ? formatUtcTimestamp(time) : null;
|
|
46
|
+
const isoTime = isValidTimestamp(time) ? new Date(time).toISOString() : null;
|
|
47
|
+
const split = shown?.indexOf(" ") ?? -1;
|
|
48
|
+
return /* @__PURE__ */ jsxs(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
...props,
|
|
52
|
+
ref,
|
|
53
|
+
role: "region",
|
|
54
|
+
"aria-labelledby": id,
|
|
55
|
+
className: clsx(shellStyles(), className),
|
|
56
|
+
children: [
|
|
57
|
+
markings && /* @__PURE__ */ jsx("div", { className: "border-b border-oprt-border bg-oprt-surface-2 px-2u py-1u text-center font-medium uppercase tracking-oprt-caps oprt-wrap-anywhere", children: markings }),
|
|
58
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2u border-b border-oprt-border p-2u", children: [
|
|
59
|
+
/* @__PURE__ */ jsx(
|
|
60
|
+
"h2",
|
|
61
|
+
{
|
|
62
|
+
id,
|
|
63
|
+
className: "m-0 min-w-0 text-oprt-md font-medium uppercase tracking-oprt-caps oprt-wrap-anywhere",
|
|
64
|
+
children: title
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2u", children: [
|
|
68
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 normal-case oprt-wrap-anywhere", children: identity }),
|
|
69
|
+
/* @__PURE__ */ jsx(Badge, { variant: mode === "live" ? "info" : "neutral", indicator: "dot", children: mode }),
|
|
70
|
+
/* @__PURE__ */ jsx(Badge, { variant: connectionVariant(connection), indicator: "dot", children: connection }),
|
|
71
|
+
isoTime && shown ? (
|
|
72
|
+
// The date and the time wrap apart; neither breaks inside, so "UTC" stays with the
|
|
73
|
+
// time.
|
|
74
|
+
/* @__PURE__ */ jsxs("time", { className: "font-mono", dateTime: isoTime, children: [
|
|
75
|
+
/* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: shown.slice(0, split) }),
|
|
76
|
+
" ",
|
|
77
|
+
/* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: shown.slice(split + 1) })
|
|
78
|
+
] })
|
|
79
|
+
) : /* @__PURE__ */ jsx("span", { children: "Time unknown" })
|
|
80
|
+
] })
|
|
81
|
+
] }),
|
|
82
|
+
toolbar && /* @__PURE__ */ jsx("div", { className: "border-b border-oprt-border p-2u", children: toolbar }),
|
|
83
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col @oprt-lg:flex-row", children: [
|
|
84
|
+
navigation && /* @__PURE__ */ jsx(
|
|
85
|
+
"nav",
|
|
86
|
+
{
|
|
87
|
+
"aria-label": `${title} navigation`,
|
|
88
|
+
className: "min-w-0 max-h-40u overflow-y-auto border-b border-oprt-border p-2u @oprt-lg:max-h-none @oprt-lg:basis-1/4 @oprt-lg:overflow-visible @oprt-lg:border-b-0 @oprt-lg:border-r",
|
|
89
|
+
children: /* @__PURE__ */ jsx(InsideNavigationLandmarkProvider, { value: true, children: navigation })
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 break-words p-2u", children })
|
|
93
|
+
] }),
|
|
94
|
+
footer && /* @__PURE__ */ jsx("div", { className: "min-w-0 break-words border-t border-oprt-border p-2u", children: footer })
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
AppShell.displayName = "AppShell";
|
|
101
|
+
export {
|
|
102
|
+
AppShell
|
|
103
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// src/AppShell/AppShell.manifest.ts
|
|
2
|
+
var AppShellManifest = {
|
|
3
|
+
AppShell: {
|
|
4
|
+
description: "In-page operational workspace with explicit identity, mode, connection, UTC reference time, and caller-supplied markings.",
|
|
5
|
+
props: {
|
|
6
|
+
identity: {
|
|
7
|
+
type: "string",
|
|
8
|
+
required: true,
|
|
9
|
+
description: "Application-supplied user or role identity; displayed verbatim."
|
|
10
|
+
},
|
|
11
|
+
title: {
|
|
12
|
+
type: "string",
|
|
13
|
+
default: "Workspace"
|
|
14
|
+
},
|
|
15
|
+
mode: {
|
|
16
|
+
type: "enum",
|
|
17
|
+
values: ["live", "paused", "replay", "training"],
|
|
18
|
+
default: "live",
|
|
19
|
+
description: "Presentation context. Does not connect to services or freeze data itself."
|
|
20
|
+
},
|
|
21
|
+
connection: {
|
|
22
|
+
type: "enum",
|
|
23
|
+
values: ["connected", "connecting", "reconnecting", "offline", "unknown"],
|
|
24
|
+
default: "unknown"
|
|
25
|
+
},
|
|
26
|
+
time: {
|
|
27
|
+
type: "number",
|
|
28
|
+
description: "Supplied reference time in epoch milliseconds, shown as YYYY-MM-DD HH:MM:SS UTC. Missing, null or invalid renders Time unknown; no running clock."
|
|
29
|
+
},
|
|
30
|
+
markings: {
|
|
31
|
+
type: "node",
|
|
32
|
+
description: "Caller-supplied policy/training markings. No classification is inferred."
|
|
33
|
+
},
|
|
34
|
+
navigation: {
|
|
35
|
+
type: "node",
|
|
36
|
+
description: `Navigation slot, usually a Sidebar, before the content in reading order. Beside the content when the shell is at least 640px wide (the shell's own width, not the window's); above it when narrower, capped at about eight rows and scrolling inside its named navigation landmark. The slot is the one navigation landmark, named from the title ("<title> navigation"); a Sidebar inside it adds no landmark of its own.`
|
|
37
|
+
},
|
|
38
|
+
toolbar: {
|
|
39
|
+
type: "node",
|
|
40
|
+
description: "Toolbar slot under the header; it grows with a toolbar that wraps onto more rows."
|
|
41
|
+
},
|
|
42
|
+
footer: {
|
|
43
|
+
type: "node"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
slots: {
|
|
47
|
+
children: {
|
|
48
|
+
type: "ReactNode",
|
|
49
|
+
required: true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
composable_with: [
|
|
53
|
+
"Sidebar",
|
|
54
|
+
"Inspector",
|
|
55
|
+
"TreeView",
|
|
56
|
+
"OperationalStatus",
|
|
57
|
+
"TimeRange",
|
|
58
|
+
"DataGrid"
|
|
59
|
+
],
|
|
60
|
+
never_inside: ["Button"],
|
|
61
|
+
example: '<AppShell identity="Exercise analyst" mode="training" connection="offline" markings="EXERCISE" time={referenceTime}><DataGrid columns={columns} data={rows} getRowId={(row) => row.id} /></AppShell>'
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
export {
|
|
65
|
+
AppShellManifest
|
|
66
|
+
};
|