@crewlethq/ui 0.42.0 → 0.44.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/README.md +24 -2
- package/dist/AgentHandoffPanel/index.js +2 -2
- package/dist/CatalogTile/CatalogTile.d.ts +12 -1
- package/dist/CatalogTile/index.d.ts +1 -1
- package/dist/CatalogTile/index.js +1 -1
- package/dist/{CatalogTile-XL4XLFUH.css → CatalogTile-VPSLCKJE.css} +55 -0
- package/dist/CommentThread/index.js +2 -2
- package/dist/DirectoryList/DirectoryList.d.ts +60 -0
- package/dist/DirectoryList/index.d.ts +3 -0
- package/dist/DirectoryList/index.js +3 -0
- package/dist/DirectoryList-7OXXN47X.css +149 -0
- package/dist/ListDetail/ListDetail.d.ts +27 -0
- package/dist/ListDetail/index.d.ts +3 -0
- package/dist/ListDetail/index.js +2 -0
- package/dist/ListDetail-ALKU5VJW.css +53 -0
- package/dist/ObjectHeader/ObjectHeader.d.ts +7 -1
- package/dist/ObjectHeader/index.js +1 -1
- package/dist/{ObjectHeader-ZOS22FKX.css → ObjectHeader-DNQWRGUK.css} +50 -0
- package/dist/PropertyList/index.js +2 -2
- package/dist/Section/Section.d.ts +6 -0
- package/dist/Section/index.js +1 -1
- package/dist/{Section-O5AHGSOG.css → Section-M7SG6NP2.css} +14 -0
- package/dist/chunk-4AA6WPQU.js +39 -0
- package/dist/{chunk-PCT47E7O.js → chunk-5GNA4RKP.js} +36 -1
- package/dist/{chunk-ODOJJGXH.js → chunk-HFQBMEEH.js} +18 -2
- package/dist/{chunk-T6MXORP5.js → chunk-JGCDFMXN.js} +1 -1
- package/dist/{chunk-3TFDQLW3.js → chunk-JQ7IFSF6.js} +1 -1
- package/dist/{chunk-BO7Q6JP6.js → chunk-N3SHQ3VU.js} +1 -1
- package/dist/chunk-R5RCGD7N.js +12 -0
- package/dist/generated/index.d.ts +2 -0
- package/dist/generated/index.js +31 -29
- package/dist/index.js +31 -29
- package/dist/styles.css +330 -3
- package/package.json +3 -3
- package/dist/{chunk-AGNZIT3Z.js → chunk-NVMZQ3Y4.js} +1 -1
- /package/dist/{chunk-S3QTFUJX.js → chunk-VXCT6L3F.js} +0 -0
package/README.md
CHANGED
|
@@ -50,9 +50,9 @@ import { Button } from '@crewlethq/ui/Button'; // 8 KB of CSS, not 182 KB
|
|
|
50
50
|
| Charts | `Legend`, `BarList`, `StackedBar`, `StackedColumns`, `ActivityStrip`, `TimeSeries`, `Sparkline`, the reading layer they share (`ChartTooltip`, `useChartHover`), and the ramp (`DATA_COLORS`, `DATA_COLOR_OTHER`, `dataColor`) |
|
|
51
51
|
| Marks | `Count`, `StatusDot`, `EmptyValue`, `VisuallyHidden` |
|
|
52
52
|
| Hooks and seams | `useModalLayer`, `usePopupLayer`, `LayerHost`, `useListbox`, `useOptionKeys`, `useHighlightRest` and `HIGHLIGHT_REST_MS`, `useClipboard`, `useDownload`, `downloadText`, `downloadBlob`, `safeFilename`, `toCsv`, `elementToPng` and `ElementToPngError`, `useOutcome`, `useAnnouncer`, `useNow`, `formatRelative`, `HeadingLevelProvider`, `cx`, the node hues (`NODE_HUES`, `NODE_HUE_NAMES`, `isNodeHue`) |
|
|
53
|
-
| Layout | `Container`, `Section`, `Card`, `TileGrid`, `Tabs`, `Accordion`, `Disclosure`, `Outline` (with `useActiveHeading` and `scrollToHeading`), `TreeGrid` |
|
|
53
|
+
| Layout | `Container`, `Section`, `Card`, `TileGrid`, `ListDetail`, `Tabs`, `Accordion`, `Disclosure`, `Outline` (with `useActiveHeading` and `scrollToHeading`), `TreeGrid` |
|
|
54
54
|
| Arranging a page | `ArrangeBoard`, `ArrangeGrid`, `ArrangeFrame` (with `useGridResize`), `ArrangeGroup`, `ArrangeList`, and the reorder hooks under them (`useReorder`, `useReorderLists`, `moveKey`) |
|
|
55
|
-
| Application shell | `AppShell` with `AppShell.Rail`, `SectionFrame` (with `SectionFrame.Nav` and `SectionFrame.Body`), `LockedLabel`, `AppShell.Topbar`, `AppShell.AccountRow` and `useAppShell`, `AuthLayout`, `SidebarNav` and `NavItem`, `BrandLockup`, `SearchTrigger`, `PageHeader`, `Toolbar`, `Stack`, `Inline`, `Spacer`, `AutoGrid`, `ErrorBoundary`, `useShortcut`, `useFullscreen`, `useIdle`, `useMediaMatch` |
|
|
55
|
+
| Application shell | `AppShell` with `AppShell.Rail`, `SectionFrame` (with `SectionFrame.Nav` and `SectionFrame.Body`), `LockedLabel`, `AppShell.Topbar`, `AppShell.AccountRow` and `useAppShell`, `AuthLayout`, `SidebarNav` and `NavItem`, `DirectoryList`, `BrandLockup`, `SearchTrigger`, `PageHeader`, `Toolbar`, `Stack`, `Inline`, `Spacer`, `AutoGrid`, `ErrorBoundary`, `useShortcut`, `useFullscreen`, `useIdle`, `useMediaMatch` |
|
|
56
56
|
| Preferences | `ThemeToggle`, `ThemeSwitcher`, `DensitySwitcher`, `ThemeGallery`, `ThemeSwatch`, `useThemePreference`, `useDensityPreference`, `useSystemTheme`, `resolveTheme`, `applyStoredPreferences`, and the framework-free `applyTheme`, `applyPalette`, `applyDensity` with `THEME_PREFERENCES`, `DENSITY_PREFERENCES` and their guards |
|
|
57
57
|
| Artifacts | `SandboxedFrame` (with `SandboxedFramePlaceholder` and `SandboxedFrameNotice`), `LinkInterstitial` and `openExternal`, `VersionTimeline`, `ShareDialog` with the role ladder (`ARTIFACT_ROLES`, `SHAREABLE_ROLES`, `roleAtLeast`), `PrincipalPicker`, `Principal` and `PrincipalAvatar`, `ArtifactCard`, `ArtifactKindGlyph` and `ArtifactPreviewGlyph` (the preview a card draws with no cover, for a cover with nothing to draw), `ArtifactBar` and `ArtifactVersionChip` (an open artifact's one slim bar), `ArtifactPanel` and `ArtifactWorkspace` (the panels it opens beside or over the artifact), `CanvasBoard` (a design's artboards and notes on a `Canvas`, with the visibility budget `liveBoards`), `CanvasToolbar` (a canvas's tool palette, with `toolForKey`), `LayersList` (the list of a canvas's items beside it, marked by the canvas's selection), `CanvasSchematic` (a design's cover, drawn from its boards' frames), `AccessDeniedCard`, `ArtifactIcon` (with `artifactIconGlyph` and `ARTIFACT_ICON_WORDS`), the native gallery covers (`DocCover`, `SheetCover`, `DashboardCover`), `MergeConflicts`, the dashboard pieces (`WidgetFrame`, `DatasetSource` and `DatasetSourceList`), and `FrameProtocol` (the wire between a host page and an embedded artifact, with no React in it), `ArtifactNameCell` and `ArtifactAccessLabel` (with `ArtifactAccessGlyph`) for a list of artifacts |
|
|
58
58
|
| Sheets | `SheetGrid`, the cells on their own (`CheckboxCell`, `TextCell`, `LongTextCell`, `NumberCell`, `SelectCell`, `MultiSelectCell`, `PersonCell`, `StatusCell`, `DateCell`, `UrlCell`, `RatingCell`, and `SheetCell` for any type), `ChangeMark`, and `SheetModel` (every rule a sheet is drawn from, with no React in it: values, parsing, the keyboard model, TSV, the pending edits of D23) |
|
|
@@ -204,6 +204,28 @@ places:
|
|
|
204
204
|
- A surface that pans or zooms dispatches `LAYER_REPOSITION_EVENT` on its host
|
|
205
205
|
when the content beneath it moves, and every panel anchored inside follows.
|
|
206
206
|
|
|
207
|
+
## Changes in 0.44.0
|
|
208
|
+
|
|
209
|
+
The pieces of the engine's Company › Integrations home, a summary of what a company has in use beside the directory of everything it could.
|
|
210
|
+
|
|
211
|
+
**`DirectoryList` lines stand at the rail's row step**: each line is exactly `--size-nav-row` (30px) in the rail's compact type, its mark at the glyph step (16px, `md`), its `hint` inline after the label in the quiet ink, giving way before the label in a narrow column, and its state held inside the row, so no line stands taller than the rest. Groups stand one small step (`--spacing-3`) apart.
|
|
212
|
+
|
|
213
|
+
**`CatalogTile` takes `density="compact"`**, a summary's tile at about half the height: the mark, the name, its state, its fact (`meta`) and the one action on the header line, and the sentence on one line under it, cut to fit with the whole of it in its title. The default, `comfortable`, is unchanged.
|
|
214
|
+
|
|
215
|
+
**`Section` takes `spacing="tight"`**: one small step (`--spacing-2`) between a heading and what it introduces, titled or not. A heading may carry the kit's `Count` of what is under it (`title={<>In use <Count value={4} /></>}`).
|
|
216
|
+
|
|
217
|
+
## Changes in 0.43.0
|
|
218
|
+
|
|
219
|
+
The parts of the engine's Company › Integrations page, a directory of everything a company works in beside the detail of the one chosen.
|
|
220
|
+
|
|
221
|
+
**`DirectoryList` is a directory in named groups**: each line a link to the item's own page with its mark, its label, a quieter hint under it (`hint`, the app a product belongs to) and its state where it has one (`status`, a status dot or a pill), the chosen line `aria-current="page"` on the selected ground. It is a navigation landmark of lists under headings (`headingLevel`), and it fills the height it is given: the groups scroll on their own and the `foot` holds the bottom of the column, one small step under them with one hairline above it, for one fact about the whole list such as an address.
|
|
222
|
+
|
|
223
|
+
**`ListDetail` lays a list beside the detail of what is chosen in it**, each scrolling on its own in the height it is given (an application shell's `fill`), the list column `--crewlet-list-detail-list` wide (17rem by default) with a hairline between the two. Below 640px it is one pane, the one `showing` names (`list` or `detail`), on a page that scrolls as any other.
|
|
224
|
+
|
|
225
|
+
**`ObjectHeader` takes a `mark`**: the object's own mark, drawn on a plate the catalogue tile's well at one and a half rows, beside the column the rest of the header keeps (a row at `size="peek"` and on a phone). A header without one is unchanged.
|
|
226
|
+
|
|
227
|
+
**`@crewlethq/icons` adds `ProductMark`**, the marks of the services built into Crewlet (`works`, `knowledge`, `chat`) beside `VendorMark`, with `soon` for a product that has not shipped, drawn hollow rather than grey. See the icons README.
|
|
228
|
+
|
|
207
229
|
## Changes in 0.42.0
|
|
208
230
|
|
|
209
231
|
**`IconButtonLink` is an icon-only link** drawn as an `IconButton`: a place reached by its glyph, such as Settings beside the reader's own row in a rail's foot. It is a real anchor (`href`), named and titled by its `label`, and `current` marks the page the reader is on with `aria-current="page"` and a nav row's selected treatment, the lifted ground inside the default hairline, drawn on the square's own transparent boundary so nothing moves; its ring then covers that edge.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from '../chunk-
|
|
1
|
+
export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from '../chunk-N3SHQ3VU.js';
|
|
2
2
|
import '../chunk-AUQPBL4O.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-JQ7IFSF6.js';
|
|
4
4
|
import '../chunk-OGXHZHRX.js';
|
|
5
5
|
import '../chunk-7CXGSS7D.js';
|
|
6
6
|
import '../chunk-NBDN5JZV.js';
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
2
|
import { type HeadingLevel } from '../utils/headingLevel.js';
|
|
3
3
|
export type CatalogTileElement = 'article' | 'li' | 'div';
|
|
4
|
+
/**
|
|
5
|
+
* How much room a tile takes. `comfortable` (the default) is the catalogue's
|
|
6
|
+
* tile: a mark well, a name with its state under it, a reserved two-line
|
|
7
|
+
* sentence and a ruled foot. `compact` is a summary's: one header line (the
|
|
8
|
+
* mark, the name, its state and the fact, then the action at its end) over
|
|
9
|
+
* one line of sentence, about half the height, for a page that lists what is
|
|
10
|
+
* already in use rather than offers a choice.
|
|
11
|
+
*/
|
|
12
|
+
export type CatalogTileDensity = 'comfortable' | 'compact';
|
|
4
13
|
export interface CatalogTileProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
5
14
|
/** The element the tile is: an `li` in a `TileGrid as="ul"`. */
|
|
6
15
|
as?: CatalogTileElement | undefined;
|
|
@@ -33,6 +42,8 @@ export interface CatalogTileProps extends Omit<HTMLAttributes<HTMLElement>, 'tit
|
|
|
33
42
|
* strength, because a tile not yet set up is the one a reader came to set up.
|
|
34
43
|
*/
|
|
35
44
|
quiet?: boolean | undefined;
|
|
45
|
+
/** How much room the tile takes; see [CatalogTileDensity]. */
|
|
46
|
+
density?: CatalogTileDensity | undefined;
|
|
36
47
|
}
|
|
37
48
|
/**
|
|
38
49
|
* One entry in a catalogue: its mark, its name, its state when it has one, a
|
|
@@ -44,4 +55,4 @@ export interface CatalogTileProps extends Omit<HTMLAttributes<HTMLElement>, 'tit
|
|
|
44
55
|
* action draws no foot at all, since a rule with nothing under it reads as a
|
|
45
56
|
* missing control.
|
|
46
57
|
*/
|
|
47
|
-
export declare function CatalogTile({ as: Element, mark, title, headingLevel, status, description, meta, action, quiet, className, ...rest }: CatalogTileProps): import("react").JSX.Element;
|
|
58
|
+
export declare function CatalogTile({ as: Element, mark, title, headingLevel, status, description, meta, action, quiet, density, className, ...rest }: CatalogTileProps): import("react").JSX.Element;
|
|
@@ -133,3 +133,58 @@
|
|
|
133
133
|
min-height: 0;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
/*
|
|
138
|
+
* COMPACT: a summary's tile, about half the comfortable one's height. One
|
|
139
|
+
* header line holds the mark (the row step's well, 28px), the name, its state
|
|
140
|
+
* and its fact, and the action at the end; the sentence is one line under it,
|
|
141
|
+
* aligned to the name, cut to fit. No reserve and no foot, because a summary
|
|
142
|
+
* has no row of feet to line up.
|
|
143
|
+
*/
|
|
144
|
+
.crewlet-catalog-tile--compact {
|
|
145
|
+
gap: var(--spacing-1);
|
|
146
|
+
padding: var(--spacing-3);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.crewlet-catalog-tile--compact .crewlet-catalog-tile__head {
|
|
150
|
+
align-items: center;
|
|
151
|
+
gap: var(--spacing-2);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.crewlet-catalog-tile--compact .crewlet-catalog-tile__mark {
|
|
155
|
+
width: var(--size-row-sm);
|
|
156
|
+
height: var(--size-row-sm);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.crewlet-catalog-tile--compact .crewlet-catalog-tile__title {
|
|
160
|
+
flex: 1 1 auto;
|
|
161
|
+
flex-direction: row;
|
|
162
|
+
align-items: center;
|
|
163
|
+
gap: var(--spacing-2);
|
|
164
|
+
padding-top: 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.crewlet-catalog-tile--compact .crewlet-catalog-tile__name {
|
|
168
|
+
flex: 0 1 auto;
|
|
169
|
+
min-width: 0;
|
|
170
|
+
overflow: hidden;
|
|
171
|
+
text-overflow: ellipsis;
|
|
172
|
+
white-space: nowrap;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.crewlet-catalog-tile--compact .crewlet-catalog-tile__status {
|
|
176
|
+
flex: none;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.crewlet-catalog-tile--compact .crewlet-catalog-tile__meta {
|
|
180
|
+
flex: 0 1 auto;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.crewlet-catalog-tile--compact .crewlet-catalog-tile__description {
|
|
184
|
+
flex: none;
|
|
185
|
+
min-height: 0;
|
|
186
|
+
padding-left: calc(var(--size-row-sm) + var(--spacing-2));
|
|
187
|
+
overflow: hidden;
|
|
188
|
+
text-overflow: ellipsis;
|
|
189
|
+
white-space: nowrap;
|
|
190
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { COMMENT_THREAD_LABELS, CommentThread } from '../chunk-
|
|
1
|
+
export { COMMENT_THREAD_LABELS, CommentThread } from '../chunk-NVMZQ3Y4.js';
|
|
2
|
+
import '../chunk-PWG3VHRQ.js';
|
|
2
3
|
import '../chunk-CI3VPIJN.js';
|
|
3
4
|
import '../chunk-3CZ7XAVY.js';
|
|
4
5
|
import '../chunk-EUCC37WY.js';
|
|
5
6
|
import '../chunk-5AQBPHZD.js';
|
|
6
7
|
import '../chunk-PZKHBB7D.js';
|
|
7
|
-
import '../chunk-PWG3VHRQ.js';
|
|
8
8
|
import '../chunk-7CXGSS7D.js';
|
|
9
9
|
import '../chunk-ZI5G5RS7.js';
|
|
10
10
|
import '../chunk-SMBKXWML.js';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type MouseEventHandler, type ReactNode } from 'react';
|
|
2
|
+
import { type HeadingLevel } from '../utils/headingLevel.js';
|
|
3
|
+
export interface DirectoryItem {
|
|
4
|
+
/** Unique within the list. */
|
|
5
|
+
key: string;
|
|
6
|
+
/** Where the line goes: the item's own page. */
|
|
7
|
+
href: string;
|
|
8
|
+
/**
|
|
9
|
+
* The item's mark: a vendor's, a product's, at the glyph step (16px, `md`).
|
|
10
|
+
* Decorative, since the label names it.
|
|
11
|
+
*/
|
|
12
|
+
mark?: ReactNode;
|
|
13
|
+
label: ReactNode;
|
|
14
|
+
/** A quieter word after the label, on its line: the app a product belongs to. */
|
|
15
|
+
hint?: ReactNode;
|
|
16
|
+
/** The item's state where it has one: a status dot and word, or a pill. */
|
|
17
|
+
status?: ReactNode;
|
|
18
|
+
/** The item the page is showing. */
|
|
19
|
+
selected?: boolean | undefined;
|
|
20
|
+
/** For an application that routes in place of the browser. */
|
|
21
|
+
onClick?: MouseEventHandler<HTMLAnchorElement> | undefined;
|
|
22
|
+
}
|
|
23
|
+
export interface DirectoryGroup {
|
|
24
|
+
/** Unique within the list. */
|
|
25
|
+
key: string;
|
|
26
|
+
label: ReactNode;
|
|
27
|
+
items: readonly DirectoryItem[];
|
|
28
|
+
}
|
|
29
|
+
export interface DirectoryListProps {
|
|
30
|
+
/** What the list is, for a screen reader's landmark: "Integrations". */
|
|
31
|
+
label: string;
|
|
32
|
+
groups: readonly DirectoryGroup[];
|
|
33
|
+
/**
|
|
34
|
+
* One quiet fact that belongs to the whole list, held at its foot: it stays
|
|
35
|
+
* at the bottom of the column while the groups scroll above it.
|
|
36
|
+
*/
|
|
37
|
+
foot?: ReactNode;
|
|
38
|
+
/** The level of each group's heading; the level the list stands at by default. */
|
|
39
|
+
headingLevel?: HeadingLevel | undefined;
|
|
40
|
+
className?: string | undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A directory: everything of one kind, in named groups, each line a link to
|
|
44
|
+
* the item's own page, beside which a page shows the one chosen.
|
|
45
|
+
*
|
|
46
|
+
* A NAVIGATION LANDMARK of lists under headings, so a screen reader can jump
|
|
47
|
+
* group to group and is told how many lines each holds. The chosen line is
|
|
48
|
+
* `aria-current="page"` and drawn on the selected ground. A line carries its
|
|
49
|
+
* mark, its label (and a quieter hint after it) and its state where it has
|
|
50
|
+
* one; a line with no state says nothing rather than "none". A LINE STANDS
|
|
51
|
+
* AT THE RAIL'S ROW STEP (30px), in the rail's compact type, because a
|
|
52
|
+
* directory is navigation beside the page as the rail is beside the app.
|
|
53
|
+
*
|
|
54
|
+
* IT FILLS THE HEIGHT IT IS GIVEN. The groups take the room and scroll on
|
|
55
|
+
* their own when they outgrow it, and the foot holds the bottom, one small
|
|
56
|
+
* step under them, so a fact about the whole list (an address, a count) is in
|
|
57
|
+
* the same place however long the list is. Placed in a column of a page that
|
|
58
|
+
* scrolls as a whole, it is as tall as its lines and the foot ends it.
|
|
59
|
+
*/
|
|
60
|
+
export declare function DirectoryList({ label, groups, foot, headingLevel, className }: DirectoryListProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* DirectoryList: named groups of links, each line a mark, a label and a state,
|
|
3
|
+
* and one foot that holds the bottom (DirectoryList.tsx).
|
|
4
|
+
*
|
|
5
|
+
* NO FRAME OF ITS OWN. The list draws on the column it is placed in, its lines
|
|
6
|
+
* on the hover and selected grounds alone, so it never makes a box inside a
|
|
7
|
+
* box; the foot's hairline is the one rule it draws.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
.crewlet-directory {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
gap: var(--spacing-2);
|
|
14
|
+
min-width: 0;
|
|
15
|
+
min-height: 0;
|
|
16
|
+
height: 100%;
|
|
17
|
+
font-family: var(--font-family-sans);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* The groups take the room and scroll on their own, so the foot stays put. */
|
|
21
|
+
.crewlet-directory__groups {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex: 1 1 auto;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
/* One small step between groups, so a heading reads as the head of the lines
|
|
26
|
+
under it rather than a band between two runs of them. */
|
|
27
|
+
gap: var(--spacing-3);
|
|
28
|
+
min-height: 0;
|
|
29
|
+
overflow-y: auto;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.crewlet-directory__group {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
gap: var(--spacing-2);
|
|
36
|
+
min-width: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.crewlet-directory__heading {
|
|
40
|
+
margin: 0;
|
|
41
|
+
padding: 0 var(--spacing-2);
|
|
42
|
+
font-size: var(--font-size-xs);
|
|
43
|
+
font-weight: var(--font-weight-semibold);
|
|
44
|
+
letter-spacing: 0.04em;
|
|
45
|
+
text-transform: uppercase;
|
|
46
|
+
color: var(--color-text-tertiary);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.crewlet-directory__items {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
gap: 2px;
|
|
53
|
+
margin: 0;
|
|
54
|
+
padding: 0;
|
|
55
|
+
list-style: none;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
* THE RAIL'S ROW STEP, 30px (--size-nav-row): a directory is navigation beside
|
|
60
|
+
* the page as the rail is beside the app, so its lines stand at the rail's
|
|
61
|
+
* height and in its compact type. Everything a line says fits that one line:
|
|
62
|
+
* a mark the size of the rail's glyph box, the hint inline after the label,
|
|
63
|
+
* and the state compact at the end.
|
|
64
|
+
*/
|
|
65
|
+
.crewlet-directory__item {
|
|
66
|
+
display: grid;
|
|
67
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: var(--spacing-2);
|
|
70
|
+
height: var(--size-nav-row);
|
|
71
|
+
padding: 0 var(--spacing-2);
|
|
72
|
+
border-radius: var(--radius-md);
|
|
73
|
+
color: var(--color-text-primary);
|
|
74
|
+
font-size: var(--font-size-compact);
|
|
75
|
+
line-height: var(--font-line-height-tight);
|
|
76
|
+
text-decoration: none;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.crewlet-directory__item:hover {
|
|
80
|
+
background: var(--color-surface-hover);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.crewlet-directory__item--selected,
|
|
84
|
+
.crewlet-directory__item--selected:hover {
|
|
85
|
+
background: var(--color-surface-selected);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.crewlet-directory__item:focus-visible {
|
|
89
|
+
outline: 2px solid var(--color-focus);
|
|
90
|
+
outline-offset: 1px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* The box takes its mark, as the rail's glyph box does: a mark at the glyph's
|
|
94
|
+
own step (16px, `md`) sits in the row with room to spare. */
|
|
95
|
+
.crewlet-directory__mark {
|
|
96
|
+
display: inline-flex;
|
|
97
|
+
flex: none;
|
|
98
|
+
align-items: center;
|
|
99
|
+
justify-content: center;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* ONE LINE: the label, then the hint after it in the quiet ink. The hint gives
|
|
103
|
+
way first, so a narrow column cuts "Atlassian" before it cuts "Confluence". */
|
|
104
|
+
.crewlet-directory__text {
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: baseline;
|
|
107
|
+
gap: var(--spacing-1);
|
|
108
|
+
min-width: 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.crewlet-directory__label {
|
|
112
|
+
flex: 0 0 auto;
|
|
113
|
+
max-width: 100%;
|
|
114
|
+
min-width: 0;
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
font-weight: var(--font-weight-medium);
|
|
117
|
+
text-overflow: ellipsis;
|
|
118
|
+
white-space: nowrap;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.crewlet-directory__hint {
|
|
122
|
+
flex: 0 1 auto;
|
|
123
|
+
min-width: 0;
|
|
124
|
+
overflow: hidden;
|
|
125
|
+
font-size: var(--font-size-xs);
|
|
126
|
+
color: var(--color-text-tertiary);
|
|
127
|
+
text-overflow: ellipsis;
|
|
128
|
+
white-space: nowrap;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* THE STATE IS COMPACT: a pill or a dot and its word in the small step, held
|
|
132
|
+
inside the row so a state never makes one line taller than the rest. */
|
|
133
|
+
.crewlet-directory__status {
|
|
134
|
+
display: inline-flex;
|
|
135
|
+
flex: none;
|
|
136
|
+
align-items: center;
|
|
137
|
+
max-height: calc(var(--size-nav-row) - var(--spacing-2));
|
|
138
|
+
font-size: var(--font-size-xs);
|
|
139
|
+
line-height: 1;
|
|
140
|
+
color: var(--color-text-secondary);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* The foot: one small step under the groups, at the bottom of the column. */
|
|
144
|
+
.crewlet-directory__foot {
|
|
145
|
+
flex: none;
|
|
146
|
+
min-width: 0;
|
|
147
|
+
padding: var(--spacing-2) var(--spacing-2) 0;
|
|
148
|
+
border-top: 1px solid var(--color-border-default);
|
|
149
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export type ListDetailPane = 'list' | 'detail';
|
|
3
|
+
export interface ListDetailProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
4
|
+
/** The list column: a `DirectoryList`, an inbox. */
|
|
5
|
+
list: ReactNode;
|
|
6
|
+
/** The chosen item's detail. */
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Which pane a phone shows, where the two are one column: the list until
|
|
10
|
+
* something is chosen, then the detail. Wider, both are always shown.
|
|
11
|
+
*/
|
|
12
|
+
showing?: ListDetailPane | undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A list beside the detail of what is chosen in it, each scrolling on its own.
|
|
16
|
+
*
|
|
17
|
+
* IT FILLS THE HEIGHT IT IS GIVEN, so place it in a box of the window's
|
|
18
|
+
* height (an application shell's `fill`): the list column holds its place
|
|
19
|
+
* while the detail scrolls, and a list that grows scrolls inside its own
|
|
20
|
+
* column. The list column is `--crewlet-list-detail-list` wide (17rem by
|
|
21
|
+
* default), with a hairline between the two.
|
|
22
|
+
*
|
|
23
|
+
* BELOW 640px IT IS ONE PANE, the one `showing` names, as tall as its content
|
|
24
|
+
* on a page that scrolls as any other: a phone has no room for two columns,
|
|
25
|
+
* and the application gives its detail a way back to the list.
|
|
26
|
+
*/
|
|
27
|
+
export declare function ListDetail({ list, children, showing, className, ...rest }: ListDetailProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ListDetail: a list beside the detail of what is chosen in it, each scrolling
|
|
3
|
+
* on its own in the height it is given, one pane on a phone (ListDetail.tsx).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
.crewlet-list-detail {
|
|
7
|
+
display: grid;
|
|
8
|
+
flex: 1 1 auto;
|
|
9
|
+
grid-template-columns: var(--crewlet-list-detail-list, 17rem) minmax(0, 1fr);
|
|
10
|
+
gap: var(--spacing-8);
|
|
11
|
+
height: 100%;
|
|
12
|
+
min-width: 0;
|
|
13
|
+
min-height: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.crewlet-list-detail__list {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
min-width: 0;
|
|
20
|
+
min-height: 0;
|
|
21
|
+
padding-right: var(--spacing-6);
|
|
22
|
+
border-right: 1px solid var(--color-border-default);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.crewlet-list-detail__detail {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
gap: var(--spacing-5);
|
|
29
|
+
min-width: 0;
|
|
30
|
+
min-height: 0;
|
|
31
|
+
overflow-y: auto;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@media (width < 640px) {
|
|
35
|
+
.crewlet-list-detail {
|
|
36
|
+
grid-template-columns: minmax(0, 1fr);
|
|
37
|
+
height: auto;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.crewlet-list-detail__list {
|
|
41
|
+
padding-right: 0;
|
|
42
|
+
border-right: 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.crewlet-list-detail__detail {
|
|
46
|
+
overflow: visible;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.crewlet-list-detail--showing-list .crewlet-list-detail__detail,
|
|
50
|
+
.crewlet-list-detail--showing-detail .crewlet-list-detail__list {
|
|
51
|
+
display: none;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -96,6 +96,12 @@ export interface ObjectHeaderProps {
|
|
|
96
96
|
kind: ReactNode;
|
|
97
97
|
/** A glyph beside the kind. A component, not a name. */
|
|
98
98
|
icon?: ReactNode;
|
|
99
|
+
/**
|
|
100
|
+
* The object's own mark, drawn large on a plate beside everything else: a
|
|
101
|
+
* vendor's or a product's mark on an integration's page. Decorative, since
|
|
102
|
+
* the title names the object; a header without one keeps its one column.
|
|
103
|
+
*/
|
|
104
|
+
mark?: ReactNode;
|
|
99
105
|
/** The key, handle or id, in the mono face. */
|
|
100
106
|
identifier?: ReactNode;
|
|
101
107
|
/**
|
|
@@ -141,4 +147,4 @@ export interface ObjectHeaderProps {
|
|
|
141
147
|
* the actions wrap onto a line of their own instead of each giving up a few
|
|
142
148
|
* characters.
|
|
143
149
|
*/
|
|
144
|
-
export declare function ObjectHeader({ kind, icon, identifier, within, title, status, facts, description, actions, size, className, }: ObjectHeaderProps): import("react").JSX.Element;
|
|
150
|
+
export declare function ObjectHeader({ kind, icon, mark, identifier, within, title, status, facts, description, actions, size, className, }: ObjectHeaderProps): import("react").JSX.Element;
|
|
@@ -18,6 +18,56 @@
|
|
|
18
18
|
padding: var(--spacing-3) 0 var(--spacing-2);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
/*
|
|
22
|
+
* A MARKED HEADER: the object's own mark on a plate, the catalogue tile's well
|
|
23
|
+
* at one and a half rows, beside the column the rest of the header keeps. The
|
|
24
|
+
* plate is the one box in the header, so the mark reads as the object's face
|
|
25
|
+
* rather than as one more glyph in the eyebrow.
|
|
26
|
+
*/
|
|
27
|
+
.crewlet-object-header--marked {
|
|
28
|
+
flex-direction: row;
|
|
29
|
+
align-items: flex-start;
|
|
30
|
+
gap: var(--spacing-4);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.crewlet-object-header__mark {
|
|
34
|
+
display: inline-flex;
|
|
35
|
+
flex: none;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
width: calc(var(--size-row-lg) * 1.5);
|
|
39
|
+
height: calc(var(--size-row-lg) * 1.5);
|
|
40
|
+
border-radius: var(--radius-lg);
|
|
41
|
+
background: var(--color-surface-elevated);
|
|
42
|
+
border: 1px solid var(--color-border-default);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.crewlet-object-header--peek .crewlet-object-header__mark {
|
|
46
|
+
width: var(--size-row-lg);
|
|
47
|
+
height: var(--size-row-lg);
|
|
48
|
+
border-radius: var(--radius-md);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.crewlet-object-header__body {
|
|
52
|
+
display: flex;
|
|
53
|
+
flex: 1 1 auto;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
gap: var(--spacing-1);
|
|
56
|
+
min-width: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@media (width < 640px) {
|
|
60
|
+
.crewlet-object-header--marked {
|
|
61
|
+
gap: var(--spacing-3);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.crewlet-object-header--marked .crewlet-object-header__mark {
|
|
65
|
+
width: var(--size-row-lg);
|
|
66
|
+
height: var(--size-row-lg);
|
|
67
|
+
border-radius: var(--radius-md);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
21
71
|
.crewlet-object-header__eyebrow {
|
|
22
72
|
display: flex;
|
|
23
73
|
align-items: center;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { PropertyList } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { PropertyList } from '../chunk-JGCDFMXN.js';
|
|
2
|
+
import '../chunk-HFQBMEEH.js';
|
|
3
3
|
import '../chunk-FBSEJO2C.js';
|
|
4
4
|
import '../chunk-MFS6F2P7.js';
|
|
5
5
|
import '../chunk-EUCC37WY.js';
|
|
@@ -9,6 +9,12 @@ export type SectionSpacing =
|
|
|
9
9
|
* marketing band between each pair of panels puts one panel per viewport.
|
|
10
10
|
*/
|
|
11
11
|
| 'compact'
|
|
12
|
+
/**
|
|
13
|
+
* The console band at its tightest: one small step between the heading and
|
|
14
|
+
* what it introduces, for a summary whose sections stand close, as a list's
|
|
15
|
+
* group headings do.
|
|
16
|
+
*/
|
|
17
|
+
| 'tight'
|
|
12
18
|
/** A marketing band. State one: a page of them is a deliberate page. */
|
|
13
19
|
| 'sm' | 'md' | 'lg';
|
|
14
20
|
export type SectionElement = 'section' | 'div' | 'header' | 'footer' | 'article';
|
package/dist/Section/index.js
CHANGED
|
@@ -23,6 +23,14 @@
|
|
|
23
23
|
padding-block: 0;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/* The console band at its tightest: a group heading's step to what it names. */
|
|
27
|
+
.crewlet-section--tight {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
gap: var(--spacing-2);
|
|
31
|
+
padding-block: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
.crewlet-section--sm {
|
|
27
35
|
padding-block: var(--spacing-9);
|
|
28
36
|
}
|
|
@@ -106,6 +114,12 @@
|
|
|
106
114
|
gap: var(--spacing-3);
|
|
107
115
|
}
|
|
108
116
|
|
|
117
|
+
/* A tight band keeps its one small step with a title too: the titled column's
|
|
118
|
+
gap would otherwise win, being later in the sheet. */
|
|
119
|
+
.crewlet-section--tight.crewlet-section--titled {
|
|
120
|
+
gap: var(--spacing-2);
|
|
121
|
+
}
|
|
122
|
+
|
|
109
123
|
@media (max-width: 768px) {
|
|
110
124
|
.crewlet-section--sm {
|
|
111
125
|
padding-block: var(--spacing-7);
|