@crewlethq/ui 0.28.0 → 0.30.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 +45 -4
- package/dist/AccessDeniedCard/index.js +3 -3
- package/dist/Accordion/index.js +3 -3
- package/dist/AppShell/index.js +1 -1
- package/dist/{AppShell-APHZKJYH.css → AppShell-GCM4TDVY.css} +4 -1
- package/dist/ArtifactBar/ArtifactBar.d.ts +143 -0
- package/dist/ArtifactBar/index.d.ts +3 -0
- package/dist/ArtifactBar/index.js +25 -0
- package/dist/ArtifactBar-IBWB5POL.css +358 -0
- package/dist/ArtifactCard/index.js +3 -3
- package/dist/ArtifactCover/index.js +5 -5
- package/dist/ArtifactIcon/index.js +4 -4
- package/dist/ArtifactPanel/ArtifactPanel.d.ts +81 -0
- package/dist/ArtifactPanel/index.d.ts +3 -0
- package/dist/ArtifactPanel/index.js +5 -0
- package/dist/ArtifactPanel-YFXT5O77.css +132 -0
- package/dist/AuthLayout/index.js +3 -3
- package/dist/AvatarPicker/index.js +4 -4
- package/dist/Card/index.js +2 -2
- package/dist/ChangeMark/index.js +1 -1
- package/dist/CommandPalette/index.js +3 -3
- package/dist/CommentThread/index.js +5 -5
- package/dist/Composer/index.js +2 -2
- package/dist/DataView/index.js +4 -4
- package/dist/Disclosure/index.js +3 -3
- package/dist/Document/Document.d.ts +8 -1
- package/dist/Document/index.js +1 -1
- package/dist/{Document-PQGXJHB7.css → Document-G3YTZIUL.css} +71 -0
- package/dist/EditingStatus/EditingStatus.d.ts +25 -0
- package/dist/EditingStatus/index.d.ts +3 -0
- package/dist/EditingStatus/index.js +2 -0
- package/dist/EditingStatus-NFADEPSX.css +53 -0
- package/dist/Editor-YZ7KG2RD.js +2099 -0
- package/dist/HuePicker/index.js +2 -2
- package/dist/ListInput/index.js +2 -2
- package/dist/Markdown/grammar.d.ts +170 -0
- package/dist/Markdown/index.d.ts +2 -0
- package/dist/Markdown/index.js +1 -0
- package/dist/MarkdownEditor/index.js +1 -1
- package/dist/PeopleRail/PeopleRail.d.ts +8 -1
- package/dist/PeopleRail/index.js +1 -1
- package/dist/{PeopleRail-R64WVOSH.css → PeopleRail-SZGHZXVT.css} +8 -0
- package/dist/RichEditor/Editor.d.ts +17 -0
- package/dist/RichEditor/RichEditor.d.ts +26 -0
- package/dist/RichEditor/codec.d.ts +78 -0
- package/dist/RichEditor/commands.d.ts +89 -0
- package/dist/RichEditor/index.d.ts +4 -0
- package/dist/RichEditor/index.js +8 -0
- package/dist/RichEditor/keys.d.ts +16 -0
- package/dist/RichEditor/nodeviews.d.ts +60 -0
- package/dist/RichEditor/paste.d.ts +47 -0
- package/dist/RichEditor/plugins.d.ts +49 -0
- package/dist/RichEditor/roundtrip.d.ts +14 -0
- package/dist/RichEditor/schema.d.ts +23 -0
- package/dist/RichEditor/types.d.ts +140 -0
- package/dist/RichEditor-NPD2KAPS.css +419 -0
- package/dist/RichEditorMarkdown/index.d.ts +1 -0
- package/dist/RichEditorMarkdown/index.js +3 -0
- package/dist/SheetGrid/index.js +1 -1
- package/dist/ThemeSwitcher/index.js +1 -1
- package/dist/VersionCompare/index.js +2 -2
- package/dist/chunk-3DPIU2Q7.js +28 -0
- package/dist/{chunk-V2Z24W2Z.js → chunk-4JUKWWUD.js} +1 -1
- package/dist/{chunk-MQEEQVG6.js → chunk-6AH2XJ3Q.js} +2 -2
- package/dist/chunk-A4E5YLXO.js +85 -0
- package/dist/{chunk-WENCSQ47.js → chunk-EBNI36UQ.js} +1 -1
- package/dist/{chunk-6J35F334.js → chunk-GOSQXEZU.js} +1 -1
- package/dist/{chunk-M2VJGNCD.js → chunk-GR55WT4R.js} +3 -3
- package/dist/chunk-I3BSQUKN.js +121 -0
- package/dist/chunk-IDBHX5SR.js +12 -0
- package/dist/{chunk-WI6K5M5X.js → chunk-M3LUNN7F.js} +1 -1
- package/dist/{chunk-S4RCG44T.js → chunk-MICH6QSJ.js} +1 -1
- package/dist/chunk-QMBP23BL.js +347 -0
- package/dist/{chunk-G2AVKPSL.js → chunk-RIAZM6L3.js} +1 -1
- package/dist/chunk-SKOYC2CF.js +288 -0
- package/dist/{chunk-PRNX5AFE.js → chunk-TGYDROIB.js} +1 -1
- package/dist/{chunk-G3EEUNZQ.js → chunk-UB7TJEKZ.js} +1 -1
- package/dist/chunk-UQHKFF2N.js +106 -0
- package/dist/{chunk-WHZFDS62.js → chunk-VDPJGP4Q.js} +1 -1
- package/dist/chunk-VOX3YRFO.js +76 -0
- package/dist/chunk-YFW4MTK4.js +749 -0
- package/dist/generated/index.d.ts +6 -0
- package/dist/generated/index.js +83 -75
- package/dist/index.js +83 -75
- package/dist/styles.css +8849 -7793
- package/package.json +13 -3
- package/dist/chunk-FVLCTCMV.js +0 -96
- package/dist/{chunk-RIEDQSA4.js → chunk-7DZDSSJS.js} +1 -1
- package/dist/{chunk-YZCJ63JF.js → chunk-ACA27MZH.js} +1 -1
- package/dist/{chunk-ENJUPIND.js → chunk-FZVJDJFN.js} +1 -1
- package/dist/{chunk-SGIQCI6Y.js → chunk-LIXSV5YI.js} +1 -1
- package/dist/{chunk-NWW4IQJU.js → chunk-OC46246T.js} +0 -0
- package/dist/{chunk-VOMYRJV5.js → chunk-RODMM35O.js} +2 -2
- package/dist/{chunk-HCKJGBQH.js → chunk-VVRL27HM.js} +1 -1
- package/dist/{chunk-D5JZN3ML.js → chunk-Z6VW6CXX.js} +1 -1
package/README.md
CHANGED
|
@@ -41,11 +41,11 @@ import { Button } from '@crewlethq/ui/Button'; // 8 KB of CSS, not 182 KB
|
|
|
41
41
|
| Area | Components |
|
|
42
42
|
| ---- | ---------- |
|
|
43
43
|
| Actions | `Button` and `ButtonLink` (variants `primary`, `secondary`, `outline`, `ghost`, `accent`, `danger`; sizes `small`, `medium`, `large`; shapes `square`, `pill`), `IconButton`, `Menu`, `Link`, `Copyable`, `CopyButton`, `DownloadButton`, `Kbd` |
|
|
44
|
-
| Content and text | `Text` (the eight registers and `inherit`), `Prose`, `Document` and `DocumentTitle`, `Highlight`, `InlineCode`, `List` and `ListItem`, `DescriptionList`, `Timeline`, `RelativeTime`, `Note`, `Divider` |
|
|
45
|
-
| Forms | `Input`, `Textarea`, `Label`, `FormField`, `FormRow`, `Checkbox`, `CheckboxGroup`, `ConfirmField`, `Select`, `Tag`, `TagsInput`, `DateTimePicker`, `TimeWindowPicker`, `ImageUpload`, `CharacterPicker`, `HuePicker`, `AvatarPicker`, `FactList`, `ChoiceList`, `Composer`, `MarkdownEditor` |
|
|
44
|
+
| Content and text | `Text` (the eight registers and `inherit`), `Prose`, `Document` and `DocumentTitle`, the Markdown grammar (`parseMarkdown`, `parseMarkdownSpans`, `markdownInline`, `safeHref` and the line readers, with no React in it), `Highlight`, `InlineCode`, `List` and `ListItem`, `DescriptionList`, `Timeline`, `RelativeTime`, `Note`, `Divider` |
|
|
45
|
+
| Forms | `Input`, `Textarea`, `Label`, `FormField`, `FormRow`, `Checkbox`, `CheckboxGroup`, `ConfirmField`, `Select`, `Tag`, `TagsInput`, `DateTimePicker`, `TimeWindowPicker`, `ImageUpload`, `CharacterPicker`, `HuePicker`, `AvatarPicker`, `FactList`, `ChoiceList`, `Composer`, `MarkdownEditor`, `RichEditor` (with `preloadRichEditor`, and the round trip `roundTripMarkdown` and `canonicalMarkdown` from `@crewlethq/ui/RichEditorMarkdown`) |
|
|
46
46
|
| Data display | `DataTable`, `CopyableCell`, `Table`, the read-only table cells (`TableKeyCell`, `TableNumberCell`, `TableDateCell`, `TableEntityCell`, `TableStatusCell`, `TableTagsCell`, `TableTextCell`), `StatCard`, `Meter`, `SegmentedMeter`, `Stepper`, `PricingCard`, `Avatar`, `AvatarStack`, `EntityChip`, `CodeBlock`, `QrCode`, `ObjectHeader`, `FactLine`, `SetByLine`, `Skeleton`, `Eyebrow`, `StatGroup`, `PinTile`, `IconTile` |
|
|
47
47
|
| List screens | `DataView`, and its parts on their own: `DataViewToolbar`, `FilterAxisBar`, `FilterAxisChip`, plus the filter model (`filterDefsFromColumns`, `applyColumnFilters`, `filterPredicate`, `blankFilterValue`) |
|
|
48
|
-
| Feedback and overlays | `Callout`, `ConflictNote`, `Toaster`, `Modal` (with `variant="sheet"`), `ConfirmModal`, `CommandPalette`, `Tooltip`, `Popover`, `Announcer` |
|
|
48
|
+
| Feedback and overlays | `Callout`, `ConflictNote`, `EditingStatus`, `Toaster`, `Modal` (with `variant="sheet"`), `ConfirmModal`, `CommandPalette`, `Tooltip`, `Popover`, `Announcer` |
|
|
49
49
|
| Documents and review | `DiffView` and `DiffSummary` with the line diff they draw (`diffLines`, `diffStat`, `collapseDiff`, `firstChangedLines`, `splitLines`, `MAX_DIFF_LINES`, with no React in it), `DiffList`, `VersionCompare`, `CommentThread` |
|
|
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` |
|
|
@@ -54,7 +54,7 @@ import { Button } from '@crewlethq/ui/Button'; // 8 KB of CSS, not 182 KB
|
|
|
54
54
|
| Arranging a page | `ArrangeBoard`, `ArrangeGrid`, `ArrangeFrame` (with `useGridResize`), `ArrangeGroup`, `ArrangeList`, and the reorder hooks under them (`useReorder`, `useReorderLists`, `moveKey`) |
|
|
55
55
|
| Application shell | `AppShell` with `AppShell.Rail`, `AppShell.Topbar`, `AppShell.AccountRow` and `useAppShell`, `AuthLayout`, `SidebarNav` and `NavItem`, `BrandLockup`, `SearchTrigger`, `PageHeader`, `Toolbar`, `Stack`, `Inline`, `Spacer`, `AutoGrid`, `ErrorBoundary`, `useShortcut`, `useFullscreen` |
|
|
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
|
-
| Artifacts | `SandboxedFrame`, `LinkInterstitial` and `openExternal`, `VersionTimeline`, `ShareDialog` with the role ladder (`ARTIFACT_ROLES`, `SHAREABLE_ROLES`, `roleAtLeast`), `PrincipalPicker`, `Principal` and `PrincipalAvatar`, `ArtifactCard` and `ArtifactKindGlyph`, `CanvasBoard` (a design's artboards and notes on a `Canvas`, with the visibility budget `liveBoards`), `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) |
|
|
57
|
+
| Artifacts | `SandboxedFrame`, `LinkInterstitial` and `openExternal`, `VersionTimeline`, `ShareDialog` with the role ladder (`ARTIFACT_ROLES`, `SHAREABLE_ROLES`, `roleAtLeast`), `PrincipalPicker`, `Principal` and `PrincipalAvatar`, `ArtifactCard` and `ArtifactKindGlyph`, `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`), `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) |
|
|
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) |
|
|
59
59
|
| Presence | `PresenceStack`, `PresenceRing` and `presenceHueClass`, `CursorFlag`, `LiveCursor`, `FollowBanner`, `PeopleRail` (with `peopleRailKey`), and `PresenceModel` (the roster order, one entry per person, the session hues from `PRESENCE_HUES`, with no React in it) |
|
|
60
60
|
| Presentations | `SlideStage` (a slide laid out at 1920 by 1080 and scaled to its box, with `SLIDE_WIDTH` and `SLIDE_HEIGHT`), `useSlideKeys` (the keys a show and a clicker send), `SlideFilmstrip`, `SlideGrid`, `SlideCompare` (with `SLIDE_COMPARE_LABELS`), `PresenterView` (with `formatStopwatch`) |
|
|
@@ -204,6 +204,47 @@ 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.30.0
|
|
208
|
+
|
|
209
|
+
**`RichEditor` edits Markdown in place, as the document it reads as.** The editable element is set by `Document`, so a page looks the same while it is edited as when it is read, and there is no separate preview. It is built on ProseMirror and loaded lazily: the component is a shell that fetches the editor's code with `import()` the first time one is drawn, so a screen that only reads pays for none of it, and `preloadRichEditor()` starts that fetch from a press that is about to open an editor.
|
|
210
|
+
|
|
211
|
+
- **Blocks**: headings, bulleted, numbered and task lists, quotes, callouts, code blocks with their language, tables, links, pictures and dividers.
|
|
212
|
+
- **A slash menu**: type `/` at the start of a line or after a space, filter by name, move with the arrows and choose with Enter. An application adds entries of its own (`commands`), each opening a panel it draws ("Link to a page").
|
|
213
|
+
- **A selection toolbar**: heading levels, bold, italic, strikethrough, inline code and a link, reached from the keyboard with Alt+F10.
|
|
214
|
+
- **Markdown typed as Markdown** becomes the block or the format it spells (`# `, `- `, `1. `, `[ ] `, `> `, three backticks and a language, `---`, `**bold**`, `*em*`, `~~struck~~`, `` `code` ``, `[text](address)`), and Backspace right after gives back what was typed. The shortcuts are the ones every editor shares, and Command or Control with Enter is the caller's `onSubmit`.
|
|
215
|
+
- **A paste of Markdown or HTML converts cleanly, under Trusted Types.** ProseMirror reads pasted HTML by assigning it to `innerHTML` behind a pass-through policy of its own, which a page enforcing `trusted-types 'none'` refuses and a page allowing it should not want. The editor takes paste and drop itself and reads HTML with a tokenizer that builds elements one by one in an inert document, keeping only the elements and attributes it has a meaning for, and copy writes Markdown as the plain text.
|
|
216
|
+
- **A load and a save with no edit change no byte.** Every top-level block remembers the lines it was read from and is written back as them until it is edited; a changed block is written in the spelling it was read with (its bullet, its fence, `*` or `_`), checked by reading it back. `@crewlethq/ui/RichEditorMarkdown` exports the round trip (`roundTripMarkdown`, `canonicalMarkdown`) for an application to hold its own bodies to.
|
|
217
|
+
|
|
218
|
+
**The Markdown grammar is part of the package** (`parseMarkdown`, `parseMarkdownSpans`, `markdownInline`, `safeHref`, `markdownHeadingOf`, `markdownFenceOf`, `markdownClosesFence`), so an application's renderer and `RichEditor` read a body by one grammar and cannot disagree about it. It reads what the Crewlet engine's renderer read, plus three things that renderer did not: backslash escapes (`\*` is an asterisk), an escaped pipe inside a table cell, and a link label holding an escaped bracket. It also reads **callouts** in GitHub's alert syntax, `> [!NOTE]`, `> [!TIP]`, `> [!IMPORTANT]`, `> [!WARNING]` and `> [!CAUTION]`.
|
|
219
|
+
|
|
220
|
+
**`Document` sets a callout and a cell aligned by `data-align`.** A renderer emits an element with `data-callout="<tone>"`, the tone's name in an element with `data-callout-label` and the blocks in one with `data-callout-body`; each tone is drawn from the same three steps `Callout` paints with.
|
|
221
|
+
|
|
222
|
+
**`EditingStatus` says a page is being edited**: "Editing", and an accent dot with "Unsaved changes" once anything differs from what was opened (or "Saving" while a save is in flight), announced politely. It sits in a page bar beside the caller's own Cancel and Save, and on a phone the words fold away behind the dot.
|
|
223
|
+
|
|
224
|
+
**`@crewlethq/icons` carries the editor's glyphs**: `heading-1`, `type`, `strikethrough`, `text-quote`, `square-code`, `unlink`, and `text-align-start`, `text-align-center` and `text-align-end`.
|
|
225
|
+
|
|
226
|
+
What to change: nothing. An application that renders Markdown itself may read it through `parseMarkdown` and `markdownInline` instead, and draws a callout by the shape above.
|
|
227
|
+
|
|
228
|
+
## Changes in 0.29.0
|
|
229
|
+
|
|
230
|
+
0.29.0 adds the chrome an open artifact sits in: one slim bar over the artifact, and one panel at its side, so a host can give the artifact the screen and open everything else on demand.
|
|
231
|
+
|
|
232
|
+
**`ArtifactBar`** is the bar, the height of a large row. At its start, the way back (`back`, a link), the kind's glyph (the artifact's own `icon` word where it has one), the title as the heading (renamed in place where `onRename` is given: Enter takes it, Escape puts it back without reaching anything under the field, leaving the field takes it, and a sentence `onRename` answers keeps the field open and says it), and the `version` slot. In its middle, the kind's views (`modes`, one segmented choice, centred while both sides have room). At its end, `presence`, the kind's tools (`kindTools`), every artifact's tools (`tools`) and More (`menu`). A tool is data, not an element (a label, a glyph, its `keys`, `pressed`, a `badge`, `disabledReason`), because the bar draws each one twice: as an icon button with its name and keys in a tooltip and as `aria-keyshortcuts`, and as a row of More. It folds by its own width, a container query: under 860px the presence stack goes (a tool's `badge` comes back in its place), under 720px a `labelled` tool keeps only its glyph, and under 640px the views and every unlabelled tool fold into More as rows with their keys, and the kind's glyph gives the title its room. Both arrangements are drawn and the stylesheet shows one. `renaming` and `onRenamingChange` start a rename from elsewhere (a Rename row); `pending` stands a placeholder in for a title still being read; `as="div"` sits it inside a host's own banner.
|
|
233
|
+
|
|
234
|
+
**`ArtifactVersionChip`** is the version on show as a quiet chip beside the title that opens a menu of versions (`items`, so the host decides which and what else the menu offers). An older version than `latest` reads `v2 of 3` in the accent, so history never passes for the present.
|
|
235
|
+
|
|
236
|
+
**`ArtifactPanel`** is a panel at the artifact's side: a complementary region named by its heading, a head with its title, optional `actions`, an expand toggle where `onExpandedChange` is given, and Close, then a body that scrolls under the head. Opening moves focus to the heading unless `focusOnOpen` is false (a panel a link opened); closing with focus inside hands focus back to whatever held it before; Escape from anywhere inside closes it, unless something inside answered the press first. Its body starts headings at level 3, so a `Section` inside it nests under the panel's title. Sizes `sm`, `md` and `lg` rest at 20, 25 and 36rem.
|
|
237
|
+
|
|
238
|
+
**`ArtifactWorkspace`** lays the artifact's body and its one panel side by side: the panel is a column where the workspace holds two useful columns (960px), slides over the body's end edge under that, and is the whole screen under 640px. `expanded` gives the panel the whole workspace, with the body kept mounted behind it. The body scrolls itself; `bodyRef`, `bodyClassName` and `bodyLabel` are for the host's own listeners, styles and region name.
|
|
239
|
+
|
|
240
|
+
**`PeopleRail` takes `variant="plain"`**: its list alone, with no border, heading or close, for a host that already frames and names it, such as an `ArtifactPanel`.
|
|
241
|
+
|
|
242
|
+
**`AppShell` reserves no scrollbar gutter on a `fill` screen.** Its main never scrolls there, so the reserved gutter was a dead strip down the screen's end edge, which an artifact drawn edge to edge showed as a band beside it.
|
|
243
|
+
|
|
244
|
+
What to change:
|
|
245
|
+
|
|
246
|
+
- Nothing for an existing host. A `fill` screen's content column is the gutter's width wider than before.
|
|
247
|
+
|
|
207
248
|
## Changes in 0.28.0
|
|
208
249
|
|
|
209
250
|
**`ArrangeGrid`** is the page grid a board's blocks stand on: equal columns (twelve unless `columns` says otherwise), the board's own gap, each `ArrangeFrame` spanning the columns it names. A frame writes `grid-column: span N`, which only a grid parent reads, so frames placed straight in an `ArrangeBoard` stacked at full width; every board now lays its blocks on this one grid rather than on a grid of its own. `ArrangeGroup`'s body is the same grid inside the group, so a block is one width on the page and in a group, and while the page is arranged the grid opens its rows a step for each block's toolbar.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { ACCESS_DENIED_REASONS, AccessDeniedCard } from '../chunk-
|
|
1
|
+
export { ACCESS_DENIED_REASONS, AccessDeniedCard } from '../chunk-UB7TJEKZ.js';
|
|
2
2
|
import '../chunk-RA2ULG6H.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-ACA27MZH.js';
|
|
4
4
|
import '../chunk-AV2DXAEL.js';
|
|
5
|
-
import '../chunk-PQADV6P6.js';
|
|
6
5
|
import '../chunk-BHHIIK3M.js';
|
|
6
|
+
import '../chunk-PQADV6P6.js';
|
|
7
7
|
import '../chunk-BZFWDIV6.js';
|
|
8
8
|
import '../chunk-ODEQTPFM.js';
|
package/dist/Accordion/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { Accordion, AccordionItem } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-PQADV6P6.js';
|
|
1
|
+
export { Accordion, AccordionItem } from '../chunk-RIAZM6L3.js';
|
|
2
|
+
import '../chunk-FZVJDJFN.js';
|
|
4
3
|
import '../chunk-BHHIIK3M.js';
|
|
4
|
+
import '../chunk-PQADV6P6.js';
|
|
5
5
|
import '../chunk-BZFWDIV6.js';
|
|
6
6
|
import '../chunk-ODEQTPFM.js';
|
package/dist/AppShell/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AccountRow, AppShell, AppShellRail, AppShellRailRow, AppShellToggle, AppShellTopbar, useAppShell } from '../chunk-
|
|
1
|
+
export { AccountRow, AppShell, AppShellRail, AppShellRailRow, AppShellToggle, AppShellTopbar, useAppShell } from '../chunk-EBNI36UQ.js';
|
|
2
2
|
import '../chunk-IG75YMUN.js';
|
|
3
3
|
import '../chunk-2HIOJ4YZ.js';
|
|
4
4
|
import '../chunk-HMPFGIWM.js';
|
|
@@ -489,9 +489,12 @@
|
|
|
489
489
|
}
|
|
490
490
|
|
|
491
491
|
/* A screen that draws to the bottom of the window: the scroller stops
|
|
492
|
-
scrolling and the content column takes the height that is left.
|
|
492
|
+
scrolling and the content column takes the height that is left. It
|
|
493
|
+
reserves no scrollbar gutter either, since nothing in it scrolls: the
|
|
494
|
+
reserved strip was a dead band down the screen's end edge. */
|
|
493
495
|
.crewlet-app-shell--fill .crewlet-app-shell__main {
|
|
494
496
|
overflow: hidden;
|
|
497
|
+
scrollbar-gutter: auto;
|
|
495
498
|
}
|
|
496
499
|
|
|
497
500
|
.crewlet-app-shell--fill .crewlet-app-shell__content {
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { ArtifactKind } from '../ArtifactCard/index.js';
|
|
3
|
+
import { type MenuEntry } from '../Menu/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* One control at the bar's end: a panel it opens, or an action it runs.
|
|
6
|
+
*
|
|
7
|
+
* A TOOL IS DATA, NOT AN ELEMENT, because the bar draws each one twice: as an
|
|
8
|
+
* icon button while the bar has room, and as a row of the More menu once it
|
|
9
|
+
* does not. An element could only ever be drawn in one of the two.
|
|
10
|
+
*/
|
|
11
|
+
export interface ArtifactBarTool {
|
|
12
|
+
key: string;
|
|
13
|
+
/** What it does, in words: the button's name, its tooltip and its menu row. */
|
|
14
|
+
label: string;
|
|
15
|
+
/** A glyph from @crewlethq/icons/glyphs. */
|
|
16
|
+
icon: ReactNode;
|
|
17
|
+
onSelect: () => void;
|
|
18
|
+
/** A panel it opens is open: drawn pressed, and said to be. */
|
|
19
|
+
pressed?: boolean | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* The shortcut, as the keys it is pressed with (`['h']`, `['Mod', 'k']`).
|
|
22
|
+
* Drawn in the tooltip and the menu row and set as `aria-keyshortcuts`;
|
|
23
|
+
* binding it is the caller's.
|
|
24
|
+
*/
|
|
25
|
+
keys?: readonly string[] | undefined;
|
|
26
|
+
/** A small figure on the glyph: how many people are here. Say it in `label` too. */
|
|
27
|
+
badge?: string | number | undefined;
|
|
28
|
+
/** Unavailable, and why. The control stays drawn and says it. */
|
|
29
|
+
disabledReason?: string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Drawn with its word beside the glyph while the bar is wide, and kept in
|
|
32
|
+
* the bar as a glyph when it is not, rather than folded into More: Share,
|
|
33
|
+
* or a kind's primary action such as a doc's Edit.
|
|
34
|
+
*/
|
|
35
|
+
labelled?: boolean | undefined;
|
|
36
|
+
}
|
|
37
|
+
/** The ways a kind draws itself, as one choice: a deck's Edit, Grid and Present. */
|
|
38
|
+
export interface ArtifactBarModes {
|
|
39
|
+
/** Names the group: "View". */
|
|
40
|
+
label: string;
|
|
41
|
+
value: string;
|
|
42
|
+
options: readonly {
|
|
43
|
+
value: string;
|
|
44
|
+
label: string;
|
|
45
|
+
icon?: ReactNode;
|
|
46
|
+
}[];
|
|
47
|
+
onValueChange: (value: string) => void;
|
|
48
|
+
}
|
|
49
|
+
export interface ArtifactBarLabels {
|
|
50
|
+
/** The More menu's name. */
|
|
51
|
+
more: (title: string) => string;
|
|
52
|
+
/** Said after the title's own name when it can be renamed by pressing it. */
|
|
53
|
+
renameHint: string;
|
|
54
|
+
/** The title field's name while renaming. */
|
|
55
|
+
titleField: string;
|
|
56
|
+
/** What an empty title is told. */
|
|
57
|
+
emptyTitle: string;
|
|
58
|
+
}
|
|
59
|
+
export declare const ARTIFACT_BAR_LABELS: ArtifactBarLabels;
|
|
60
|
+
export interface ArtifactBarProps {
|
|
61
|
+
title: string;
|
|
62
|
+
kind: ArtifactKind;
|
|
63
|
+
/** The artifact's own icon word; its kind's glyph where it has none. */
|
|
64
|
+
icon?: string | null | undefined;
|
|
65
|
+
/** What the kind is called, said with the glyph: "Slides". */
|
|
66
|
+
kindLabel: string;
|
|
67
|
+
/** The way back to where the reader came from, as a link. */
|
|
68
|
+
back?: {
|
|
69
|
+
href: string;
|
|
70
|
+
label: string;
|
|
71
|
+
} | undefined;
|
|
72
|
+
/** Before everything, such as an application shell's navigation toggle. */
|
|
73
|
+
start?: ReactNode;
|
|
74
|
+
/**
|
|
75
|
+
* Renames in place. Left out, the title is read only. It answers what went
|
|
76
|
+
* wrong, in a sentence, to keep the field open and say it; or nothing when
|
|
77
|
+
* the new title was taken.
|
|
78
|
+
*/
|
|
79
|
+
onRename?: ((title: string) => Promise<string | null | undefined | void> | string | null | undefined | void) | undefined;
|
|
80
|
+
/** Whether the title is being renamed now; controlled, for a Rename row elsewhere. */
|
|
81
|
+
renaming?: boolean | undefined;
|
|
82
|
+
onRenamingChange?: ((renaming: boolean) => void) | undefined;
|
|
83
|
+
/** Beside the title: the version chip ([ArtifactVersionChip]). */
|
|
84
|
+
version?: ReactNode;
|
|
85
|
+
/** The kind's views, drawn in the middle of the bar. */
|
|
86
|
+
modes?: ArtifactBarModes | undefined;
|
|
87
|
+
/** Who else is here, such as a presence stack. Folded away first on a narrower bar. */
|
|
88
|
+
presence?: ReactNode;
|
|
89
|
+
/** The kind's own controls, before the panels: a doc's Edit. */
|
|
90
|
+
kindTools?: readonly ArtifactBarTool[] | undefined;
|
|
91
|
+
/** The panels and actions every artifact has: details, history, people, share. */
|
|
92
|
+
tools?: readonly ArtifactBarTool[] | undefined;
|
|
93
|
+
/** The More menu's own rows. The tools that fold on a narrow bar are added above them. */
|
|
94
|
+
menu?: readonly MenuEntry[] | undefined;
|
|
95
|
+
/** `header` stands as the page's banner; `div` sits inside a host's own. */
|
|
96
|
+
as?: 'header' | 'div' | undefined;
|
|
97
|
+
/** The title's heading level: 1 where the bar is the page's own head. */
|
|
98
|
+
headingLevel?: 1 | 2 | 3 | undefined;
|
|
99
|
+
/** The title is still being read: a placeholder stands in its place. */
|
|
100
|
+
pending?: boolean | undefined;
|
|
101
|
+
labels?: Partial<ArtifactBarLabels> | undefined;
|
|
102
|
+
className?: string | undefined;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The one slim bar an open artifact sits under, so the artifact keeps the
|
|
106
|
+
* rest of the screen.
|
|
107
|
+
*
|
|
108
|
+
* WHAT IT HOLDS, IN THE ORDER A READER SCANS IT: the way back, what the
|
|
109
|
+
* artifact is (its glyph and its title, renamed in place by whoever may), the
|
|
110
|
+
* version on show, then the kind's own views in the middle, and at the end
|
|
111
|
+
* who else is here, the kind's tools, the panels every artifact has, Share
|
|
112
|
+
* and More. Everything past the title opens on demand: a panel, a menu or a
|
|
113
|
+
* dialog, never a second row of chrome.
|
|
114
|
+
*
|
|
115
|
+
* IT FOLDS BY ITS OWN WIDTH, a container query rather than the window's, since
|
|
116
|
+
* a sidebar or a panel beside it is what decides its room. Narrower than a
|
|
117
|
+
* laptop's sheet the presence stack goes, then the labelled tools' words;
|
|
118
|
+
* narrower than a phone's two panes, the views and every tool but the
|
|
119
|
+
* labelled ones fold into More, where each is a row with its shortcut, and
|
|
120
|
+
* the kind's glyph gives the title its room. Both arrangements are drawn and
|
|
121
|
+
* the stylesheet shows one, so no control is ever in two places a reader can
|
|
122
|
+
* see at once and nothing is measured in script.
|
|
123
|
+
*/
|
|
124
|
+
export declare function ArtifactBar({ title, kind, icon, kindLabel, back, start, onRename, renaming, onRenamingChange, version, modes, presence, kindTools, tools, menu, as, headingLevel, pending, labels, className, }: ArtifactBarProps): import("react").JSX.Element;
|
|
125
|
+
export interface ArtifactVersionChipProps {
|
|
126
|
+
/** The version on show. */
|
|
127
|
+
version: number;
|
|
128
|
+
/** The newest version. */
|
|
129
|
+
latest: number;
|
|
130
|
+
/** The versions to pick from, newest first, and what else the menu offers. */
|
|
131
|
+
items: readonly MenuEntry[];
|
|
132
|
+
/** Names the menu. */
|
|
133
|
+
label?: string | undefined;
|
|
134
|
+
/** The chip's words: `v3`, or `v2 of 3` for an older one. */
|
|
135
|
+
format?: ((version: number, latest: number) => string) | undefined;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The version on show, as a quiet chip beside the title that opens the
|
|
139
|
+
* versions. An older version than the newest says so in the chip itself and
|
|
140
|
+
* takes the accent, so a reader looking at history cannot mistake it for
|
|
141
|
+
* what everyone else sees.
|
|
142
|
+
*/
|
|
143
|
+
export declare function ArtifactVersionChip({ version, latest, items, label, format, }: ArtifactVersionChipProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export { ARTIFACT_BAR_LABELS, ArtifactBar, ArtifactVersionChip } from '../chunk-QMBP23BL.js';
|
|
2
|
+
import '../chunk-FQCLKD7U.js';
|
|
3
|
+
import '../chunk-SMBKXWML.js';
|
|
4
|
+
import '../chunk-QWOPX2MN.js';
|
|
5
|
+
import '../chunk-RCQXUT5K.js';
|
|
6
|
+
import '../chunk-HJEVSQN6.js';
|
|
7
|
+
import '../chunk-RKKO7QHH.js';
|
|
8
|
+
import '../chunk-4JUKWWUD.js';
|
|
9
|
+
import '../chunk-GOSQXEZU.js';
|
|
10
|
+
import '../chunk-4KP4RC3O.js';
|
|
11
|
+
import '../chunk-3CZ7XAVY.js';
|
|
12
|
+
import '../chunk-EUCC37WY.js';
|
|
13
|
+
import '../chunk-UAN5NE7M.js';
|
|
14
|
+
import '../chunk-5OM447RW.js';
|
|
15
|
+
import '../chunk-ACA27MZH.js';
|
|
16
|
+
import '../chunk-AV2DXAEL.js';
|
|
17
|
+
import '../chunk-BHHIIK3M.js';
|
|
18
|
+
import '../chunk-PQADV6P6.js';
|
|
19
|
+
import '../chunk-2HIOJ4YZ.js';
|
|
20
|
+
import '../chunk-HMPFGIWM.js';
|
|
21
|
+
import '../chunk-R25RGPUB.js';
|
|
22
|
+
import '../chunk-OG6CL3EB.js';
|
|
23
|
+
import '../chunk-4FQT6ZAY.js';
|
|
24
|
+
import '../chunk-BZFWDIV6.js';
|
|
25
|
+
import '../chunk-ODEQTPFM.js';
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* One row, one hairline under it, the height of a large row. The lead (the
|
|
3
|
+
* way back, the glyph, the title, the version) takes what the end leaves it
|
|
4
|
+
* and the title is what gives way, ellipsised; the views sit between the two,
|
|
5
|
+
* centred while both sides have room, because the lead and the end each grow
|
|
6
|
+
* from a zero basis and the end never shrinks below its controls.
|
|
7
|
+
*
|
|
8
|
+
* Three widths of its OWN fold it (a container query, since a sidebar or a
|
|
9
|
+
* panel beside it decides its room, not the window): under a laptop sheet's
|
|
10
|
+
* width the presence stack goes (the People control still counts who is
|
|
11
|
+
* here), then the labelled tools' words, and under a phone's two panes the
|
|
12
|
+
* views, the unlabelled tools and the kind's glyph fold away, the first two
|
|
13
|
+
* into More.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
.crewlet-artifact-bar {
|
|
17
|
+
container: crewlet-artifact-bar / inline-size;
|
|
18
|
+
display: block;
|
|
19
|
+
min-width: 0;
|
|
20
|
+
background: var(--color-surface-background);
|
|
21
|
+
border-bottom: 1px solid var(--color-border-default);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.crewlet-artifact-bar__row {
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
gap: var(--spacing-3);
|
|
28
|
+
height: var(--size-row-lg);
|
|
29
|
+
padding: 0 var(--spacing-3);
|
|
30
|
+
min-width: 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.crewlet-artifact-bar__lead {
|
|
34
|
+
display: flex;
|
|
35
|
+
flex: 1 1 0;
|
|
36
|
+
align-items: center;
|
|
37
|
+
gap: var(--spacing-1);
|
|
38
|
+
min-width: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.crewlet-artifact-bar__end {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex: none;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: flex-end;
|
|
46
|
+
gap: var(--spacing-2);
|
|
47
|
+
margin-inline-start: auto;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* WITH VIEWS TO CENTRE, the end grows from zero as the lead does, so the two
|
|
51
|
+
sides stay equal while there is room and the views sit in the middle; the
|
|
52
|
+
end never shrinks below its controls, so it is the title that gives way. */
|
|
53
|
+
.crewlet-artifact-bar__row--centred .crewlet-artifact-bar__end {
|
|
54
|
+
flex: 1 0 0;
|
|
55
|
+
min-width: max-content;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.crewlet-artifact-bar__modes {
|
|
59
|
+
display: flex;
|
|
60
|
+
flex: none;
|
|
61
|
+
align-items: center;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.crewlet-artifact-bar__glyph {
|
|
65
|
+
display: inline-flex;
|
|
66
|
+
flex: none;
|
|
67
|
+
align-items: center;
|
|
68
|
+
justify-content: center;
|
|
69
|
+
width: var(--size-control-sm);
|
|
70
|
+
height: var(--size-control-sm);
|
|
71
|
+
color: var(--color-text-secondary);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* THE TITLE. Read only, it is text; renamable, its words are a button drawn
|
|
75
|
+
as text that answers the pointer with the hover ground, as a field would. */
|
|
76
|
+
.crewlet-artifact-bar__title {
|
|
77
|
+
position: relative;
|
|
78
|
+
display: flex;
|
|
79
|
+
min-width: 0;
|
|
80
|
+
margin: 0;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
color: var(--color-text-primary);
|
|
83
|
+
font-family: var(--font-family-sans);
|
|
84
|
+
font-size: var(--font-size-sm);
|
|
85
|
+
font-weight: var(--font-weight-semibold);
|
|
86
|
+
letter-spacing: var(--font-letter-spacing-tight);
|
|
87
|
+
line-height: var(--font-line-height-snug);
|
|
88
|
+
text-overflow: ellipsis;
|
|
89
|
+
white-space: nowrap;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.crewlet-artifact-bar__title--editing {
|
|
93
|
+
overflow: visible;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.crewlet-artifact-bar__rename {
|
|
97
|
+
min-width: 0;
|
|
98
|
+
max-width: 100%;
|
|
99
|
+
margin: 0;
|
|
100
|
+
padding: var(--spacing-1) var(--spacing-2);
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
border: 0;
|
|
103
|
+
border-radius: var(--radius-sm);
|
|
104
|
+
background: transparent;
|
|
105
|
+
color: inherit;
|
|
106
|
+
font: inherit;
|
|
107
|
+
letter-spacing: inherit;
|
|
108
|
+
text-align: start;
|
|
109
|
+
text-overflow: ellipsis;
|
|
110
|
+
white-space: nowrap;
|
|
111
|
+
cursor: text;
|
|
112
|
+
transition: background-color var(--motion-duration-fast) var(--motion-easing-default);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.crewlet-artifact-bar__rename:hover {
|
|
116
|
+
background: var(--color-surface-hover);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.crewlet-artifact-bar__rename:focus-visible {
|
|
120
|
+
outline: 2px solid var(--color-focus);
|
|
121
|
+
outline-offset: var(--size-focus-ring-inset-offset);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* The field is as wide as what is typed in it: the grid cell is sized by a
|
|
125
|
+
hidden copy of the text, and the field fills that cell. */
|
|
126
|
+
.crewlet-artifact-bar__sizer {
|
|
127
|
+
display: inline-grid;
|
|
128
|
+
min-width: 0;
|
|
129
|
+
max-width: 100%;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.crewlet-artifact-bar__sizer::after {
|
|
133
|
+
content: attr(data-value) ' ';
|
|
134
|
+
visibility: hidden;
|
|
135
|
+
grid-area: 1 / 1;
|
|
136
|
+
padding: var(--spacing-1) var(--spacing-2);
|
|
137
|
+
overflow: hidden;
|
|
138
|
+
white-space: pre;
|
|
139
|
+
font: inherit;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.crewlet-artifact-bar__field {
|
|
143
|
+
grid-area: 1 / 1;
|
|
144
|
+
min-width: 0;
|
|
145
|
+
width: 100%;
|
|
146
|
+
margin: 0;
|
|
147
|
+
padding: calc(var(--spacing-1) - 1px) calc(var(--spacing-2) - 1px);
|
|
148
|
+
border: 1px solid var(--color-border-control);
|
|
149
|
+
border-radius: var(--radius-sm);
|
|
150
|
+
background: var(--color-surface-elevated);
|
|
151
|
+
color: var(--color-text-primary);
|
|
152
|
+
font: inherit;
|
|
153
|
+
letter-spacing: inherit;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.crewlet-artifact-bar__field:focus {
|
|
157
|
+
outline: 2px solid var(--color-focus);
|
|
158
|
+
outline-offset: var(--size-focus-ring-inset-offset);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.crewlet-artifact-bar__field[aria-invalid='true'] {
|
|
162
|
+
border-color: var(--color-feedback-danger);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.crewlet-artifact-bar__error {
|
|
166
|
+
position: absolute;
|
|
167
|
+
top: calc(100% + var(--spacing-1));
|
|
168
|
+
left: 0;
|
|
169
|
+
z-index: var(--z-index-dropdown);
|
|
170
|
+
padding: var(--spacing-1) var(--spacing-2);
|
|
171
|
+
border: 1px solid var(--color-border-default);
|
|
172
|
+
border-radius: var(--radius-sm);
|
|
173
|
+
background: var(--color-surface-elevated);
|
|
174
|
+
box-shadow: var(--shadow-md);
|
|
175
|
+
color: var(--color-feedback-danger-ink);
|
|
176
|
+
font-size: var(--font-size-xs);
|
|
177
|
+
font-weight: var(--font-weight-regular);
|
|
178
|
+
white-space: nowrap;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.crewlet-artifact-bar__placeholder {
|
|
182
|
+
display: block;
|
|
183
|
+
flex: 0 1 12rem;
|
|
184
|
+
height: var(--font-size-sm);
|
|
185
|
+
border-radius: var(--radius-sm);
|
|
186
|
+
background: var(--color-surface-subtle);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.crewlet-artifact-bar__version {
|
|
190
|
+
display: inline-flex;
|
|
191
|
+
flex: none;
|
|
192
|
+
margin-inline-start: var(--spacing-1);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.crewlet-artifact-bar__presence {
|
|
196
|
+
display: inline-flex;
|
|
197
|
+
align-items: center;
|
|
198
|
+
margin-inline-end: var(--spacing-1);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.crewlet-artifact-bar__tools {
|
|
202
|
+
display: inline-flex;
|
|
203
|
+
align-items: center;
|
|
204
|
+
gap: var(--spacing-1);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.crewlet-artifact-bar__tool {
|
|
208
|
+
position: relative;
|
|
209
|
+
display: inline-flex;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* A figure on the glyph's corner, inside the button's own box so it never
|
|
213
|
+
reaches past the bar's edge. */
|
|
214
|
+
.crewlet-artifact-bar__badge {
|
|
215
|
+
position: absolute;
|
|
216
|
+
top: calc(-1 * var(--spacing-1));
|
|
217
|
+
right: calc(-1 * var(--spacing-1));
|
|
218
|
+
min-width: var(--spacing-4);
|
|
219
|
+
height: var(--spacing-4);
|
|
220
|
+
padding: 0 var(--spacing-1);
|
|
221
|
+
border-radius: var(--radius-pill);
|
|
222
|
+
background: var(--color-brand-accent);
|
|
223
|
+
color: var(--color-text-on-accent);
|
|
224
|
+
font-size: var(--font-size-2xs);
|
|
225
|
+
font-weight: var(--font-weight-semibold);
|
|
226
|
+
font-variant-numeric: tabular-nums;
|
|
227
|
+
line-height: var(--spacing-4);
|
|
228
|
+
text-align: center;
|
|
229
|
+
pointer-events: none;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* WHILE THE PRESENCE STACK IS DRAWN it says who is here, so a tool's figure
|
|
233
|
+
saying the same is not drawn beside it; it comes back where the stack
|
|
234
|
+
folds away. */
|
|
235
|
+
.crewlet-artifact-bar--present .crewlet-artifact-bar__badge {
|
|
236
|
+
display: none;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* A rule between two groups of tools: the kind's, then every artifact's. */
|
|
240
|
+
.crewlet-artifact-bar__rule {
|
|
241
|
+
width: 1px;
|
|
242
|
+
height: var(--spacing-4);
|
|
243
|
+
margin: 0 var(--spacing-1);
|
|
244
|
+
background: var(--color-border-default);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.crewlet-artifact-bar__tip {
|
|
248
|
+
display: inline-flex;
|
|
249
|
+
align-items: center;
|
|
250
|
+
gap: var(--spacing-2);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* Both arrangements are drawn; the bar's width says which one shows. */
|
|
254
|
+
.crewlet-artifact-bar__narrow,
|
|
255
|
+
.crewlet-artifact-bar__tight {
|
|
256
|
+
display: none;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.crewlet-artifact-bar__wide,
|
|
260
|
+
.crewlet-artifact-bar__roomy {
|
|
261
|
+
display: inline-flex;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@container crewlet-artifact-bar (width < 860px) {
|
|
265
|
+
.crewlet-artifact-bar__presence {
|
|
266
|
+
display: none;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.crewlet-artifact-bar--present .crewlet-artifact-bar__badge {
|
|
270
|
+
display: block;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@container crewlet-artifact-bar (width < 720px) {
|
|
275
|
+
.crewlet-artifact-bar__roomy {
|
|
276
|
+
display: none;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.crewlet-artifact-bar__tight {
|
|
280
|
+
display: inline-flex;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
@container crewlet-artifact-bar (width < 640px) {
|
|
285
|
+
.crewlet-artifact-bar__row {
|
|
286
|
+
gap: var(--spacing-1);
|
|
287
|
+
padding: 0 var(--spacing-2);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* The title has the row's room before the kind's glyph does: the glyph
|
|
291
|
+
says again what the title already names. */
|
|
292
|
+
.crewlet-artifact-bar__wide,
|
|
293
|
+
.crewlet-artifact-bar__glyph {
|
|
294
|
+
display: none;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.crewlet-artifact-bar__narrow {
|
|
298
|
+
display: inline-flex;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* The views have folded, so there is nothing to centre: the title takes
|
|
302
|
+
the room. */
|
|
303
|
+
.crewlet-artifact-bar__row--centred .crewlet-artifact-bar__end {
|
|
304
|
+
flex: none;
|
|
305
|
+
min-width: 0;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/*
|
|
310
|
+
* THE VERSION CHIP: quiet at rest, the hover ground under the pointer, and
|
|
311
|
+
* the accent's soft ground while an older version than the newest is on
|
|
312
|
+
* show, so history never passes for the present.
|
|
313
|
+
*/
|
|
314
|
+
.crewlet-version-chip {
|
|
315
|
+
display: inline-flex;
|
|
316
|
+
align-items: center;
|
|
317
|
+
gap: var(--spacing-1);
|
|
318
|
+
height: var(--size-target-min);
|
|
319
|
+
padding: 0 var(--spacing-2);
|
|
320
|
+
border: 0;
|
|
321
|
+
border-radius: var(--radius-pill);
|
|
322
|
+
background: var(--color-surface-subtle);
|
|
323
|
+
color: var(--color-text-secondary);
|
|
324
|
+
font-family: var(--font-family-sans);
|
|
325
|
+
font-size: var(--font-size-xs);
|
|
326
|
+
font-weight: var(--font-weight-medium);
|
|
327
|
+
font-variant-numeric: tabular-nums;
|
|
328
|
+
white-space: nowrap;
|
|
329
|
+
cursor: pointer;
|
|
330
|
+
transition: background-color var(--motion-duration-fast) var(--motion-easing-default);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.crewlet-version-chip:hover {
|
|
334
|
+
background: var(--color-surface-hover);
|
|
335
|
+
color: var(--color-text-primary);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.crewlet-version-chip:focus-visible {
|
|
339
|
+
outline: 2px solid var(--color-focus);
|
|
340
|
+
outline-offset: var(--size-focus-ring-inset-offset);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.crewlet-version-chip--older {
|
|
344
|
+
background: var(--color-brand-accent-soft);
|
|
345
|
+
color: var(--color-brand-accent-ink);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.crewlet-version-chip--older:hover {
|
|
349
|
+
background: var(--color-brand-accent-soft-strong);
|
|
350
|
+
color: var(--color-brand-accent-ink);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
@media (prefers-reduced-motion: reduce) {
|
|
354
|
+
.crewlet-artifact-bar__rename,
|
|
355
|
+
.crewlet-version-chip {
|
|
356
|
+
transition: none;
|
|
357
|
+
}
|
|
358
|
+
}
|