@crewlethq/ui 0.82.0 → 0.83.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 +29 -1
- package/dist/AppShell/AccountRow.d.ts +6 -1
- package/dist/AppShell/AppShell.d.ts +15 -6
- package/dist/AppShell/index.d.ts +1 -1
- package/dist/AppShell/index.js +8 -5
- package/dist/AppShell/railMotion.d.ts +60 -0
- package/dist/AppShell/railShape.d.ts +5 -0
- package/dist/{AppShell-F7RID4P4.css → AppShell-U7D2MUUF.css} +177 -56
- package/dist/ArrangeList/index.js +3 -2
- package/dist/ArtifactBar/index.js +7 -5
- package/dist/ArtifactCard/index.js +2 -2
- package/dist/AuthLayout/index.js +3 -3
- package/dist/AvatarPicker/index.js +7 -6
- package/dist/BrandLockup/index.js +2 -2
- package/dist/Canvas/index.js +4 -2
- package/dist/CanvasBoard/index.js +6 -4
- package/dist/CanvasToolbar/index.js +5 -3
- package/dist/ChangeMark/index.js +4 -2
- package/dist/ChatThread/index.js +2 -2
- package/dist/CommandPalette/index.js +3 -2
- package/dist/CompactNav/index.js +2 -1
- package/dist/ContrastHelp/index.js +3 -2
- package/dist/DataGrid/index.js +2 -2
- package/dist/DataTable/index.js +4 -3
- package/dist/DataView/index.js +7 -6
- package/dist/DateTimePicker/index.js +3 -2
- package/dist/DeepWorkCard/index.js +2 -2
- package/dist/DocTabsEditor/index.js +5 -3
- package/dist/DockColumn/DockColumn.d.ts +68 -0
- package/dist/DockColumn/index.d.ts +3 -0
- package/dist/DockColumn/index.js +6 -0
- package/dist/DockColumn-SMJCXHS4.css +61 -0
- package/dist/{Editor-7EQWP3RN.js → Editor-5D5Z3LBQ.js} +3 -2
- package/dist/EmojiPicker/index.js +5 -3
- package/dist/FactList/index.js +4 -2
- package/dist/HuePicker/index.js +5 -4
- package/dist/LinkInterstitial/index.js +3 -2
- package/dist/ListInput/index.js +3 -2
- package/dist/MarkdownEditor/index.js +5 -4
- package/dist/MediaMatch/index.d.ts +1 -1
- package/dist/MediaMatch/index.js +1 -1
- package/dist/MediaMatch/useMediaMatch.d.ts +14 -0
- package/dist/Menu/index.js +2 -1
- package/dist/MergeConflicts/index.js +5 -4
- package/dist/MessageActions/index.js +6 -4
- package/dist/Modal/index.js +2 -1
- package/dist/OpenInAppCard/index.js +2 -2
- package/dist/Outline/index.js +2 -1
- package/dist/Popover/index.js +2 -1
- package/dist/Presence/index.d.ts +2 -0
- package/dist/Presence/index.js +4 -0
- package/dist/Presence/usePresence.d.ts +109 -0
- package/dist/ReactionBar/index.js +6 -4
- package/dist/RecordChip/index.js +3 -2
- package/dist/Reorder/index.js +2 -1
- package/dist/RichEditor/index.js +1 -1
- package/dist/SegmentedControl/index.js +4 -3
- package/dist/SetupWizard/index.js +2 -2
- package/dist/ShareDialog/index.js +4 -3
- package/dist/SheetColumnEditor/index.js +6 -5
- package/dist/SheetGrid/index.js +8 -6
- package/dist/SlideFilmstrip/index.js +5 -3
- package/dist/Switcher/index.js +5 -4
- package/dist/Tabs/index.js +3 -2
- package/dist/ThemeSwitcher/index.js +5 -4
- package/dist/TimeRangePicker/index.js +6 -5
- package/dist/TimeWindowPicker/index.js +3 -2
- package/dist/Tooltip/index.js +3 -1
- package/dist/TreeCanvas/index.js +6 -3
- package/dist/VersionCompare/index.js +5 -4
- package/dist/{chunk-KJR5X4II.js → chunk-22CU7V4J.js} +2 -2
- package/dist/{chunk-4RYELYWG.js → chunk-2SVQBQAD.js} +2 -2
- package/dist/{chunk-HQFOZJQ4.js → chunk-46FIBJCV.js} +4 -4
- package/dist/{chunk-LQRN2XZK.js → chunk-4DEKONVJ.js} +2 -2
- package/dist/chunk-5JPOFAVN.js +58 -0
- package/dist/{chunk-C7UHDM7Y.js → chunk-5V6GW6HK.js} +1 -1
- package/dist/{chunk-XGLMPPDW.js → chunk-7K6LVM5I.js} +1 -1
- package/dist/{chunk-FKAJBN6G.js → chunk-7M7WKYOV.js} +3 -3
- package/dist/{chunk-A5YKNRG6.js → chunk-7QCSISHM.js} +2 -1
- package/dist/{chunk-3QQIGMY3.js → chunk-7ZSEUO5Q.js} +6 -30
- package/dist/{chunk-57BFL323.js → chunk-ABRWL5FJ.js} +1 -1
- package/dist/{chunk-HFOTRZFU.js → chunk-AQNP3KQU.js} +2 -2
- package/dist/{chunk-N2T7Y5KR.js → chunk-AUSFKGKL.js} +1 -1
- package/dist/{chunk-GZVAZ3LL.js → chunk-AZYE7NR4.js} +1 -1
- package/dist/{chunk-6IOQWMYJ.js → chunk-BN5FEJL5.js} +1 -1
- package/dist/{chunk-MPVMB2DV.js → chunk-BVML4UVB.js} +3 -2
- package/dist/{chunk-XY4O2XMR.js → chunk-BXGBGYKH.js} +3 -3
- package/dist/{chunk-OAHRMR4U.js → chunk-C42XW5YP.js} +1 -1
- package/dist/{chunk-HA2PL7PA.js → chunk-DRFOTWJE.js} +1 -1
- package/dist/{chunk-SM4P2SHB.js → chunk-EC6EUIAD.js} +7 -4
- package/dist/{chunk-AMUXSJ2A.js → chunk-FPU7AA3X.js} +4 -15
- package/dist/{chunk-KLAVEJIO.js → chunk-GLKQHN7G.js} +1 -1
- package/dist/chunk-HTS5RJ7S.js +6 -0
- package/dist/{chunk-GP5TNTZH.js → chunk-ICE3D63E.js} +3 -5
- package/dist/{chunk-ISQANI6Q.js → chunk-JLOESTT2.js} +2 -1
- package/dist/{chunk-C75WZMXG.js → chunk-K6RWEQ6P.js} +1 -1
- package/dist/{chunk-GVPUCEWH.js → chunk-KXWJJWBD.js} +1 -1
- package/dist/chunk-L72URIHR.js +36 -0
- package/dist/{chunk-2TOGGCDM.js → chunk-LT44RL62.js} +2 -2
- package/dist/{chunk-HCUECVZ3.js → chunk-MVKUE4FI.js} +1 -1
- package/dist/{chunk-6YBBQAEM.js → chunk-MYAARF4Z.js} +1 -1
- package/dist/{chunk-SEKO6P3Y.js → chunk-NCUSI4ZU.js} +1 -1
- package/dist/chunk-PCAT2EFB.js +104 -0
- package/dist/{chunk-T4IEESXN.js → chunk-PGBKZSSQ.js} +87 -24
- package/dist/{chunk-TGCGLKD4.js → chunk-RBQRTGXX.js} +1 -1
- package/dist/{chunk-B3X4DHRB.js → chunk-RDIQB5ZE.js} +2 -2
- package/dist/{chunk-T7WESRZF.js → chunk-RO5JU6SN.js} +2 -2
- package/dist/{chunk-IUWP2LSE.js → chunk-SGMWLUYQ.js} +2 -2
- package/dist/{chunk-LSOR77RZ.js → chunk-SHH7UD5U.js} +1 -1
- package/dist/{chunk-JV6JM6W6.js → chunk-SNQ7PH3D.js} +1 -1
- package/dist/{chunk-MPYRC3GO.js → chunk-SPNTUQBV.js} +2 -2
- package/dist/{chunk-YM77TZ7Q.js → chunk-T3S3D4FC.js} +1 -1
- package/dist/{chunk-YOJAGKTS.js → chunk-TGGYSQRD.js} +3 -4
- package/dist/{chunk-2KJCUCVE.js → chunk-TQKQRS2J.js} +2 -2
- package/dist/{chunk-ONNXUS5Y.js → chunk-VB3FVKNI.js} +1 -1
- package/dist/{chunk-JHQGNFN3.js → chunk-VONEKR3J.js} +2 -2
- package/dist/{chunk-P6F3PE4V.js → chunk-WANKINXG.js} +2 -2
- package/dist/{chunk-PXLS6JKL.js → chunk-WMO722J2.js} +1 -1
- package/dist/{chunk-SYVQXMLO.js → chunk-XRWHDW6F.js} +4 -4
- package/dist/{chunk-WT3B76MG.js → chunk-XTJHMP3W.js} +1 -1
- package/dist/{chunk-RTPQDNW3.js → chunk-YJQXESOJ.js} +5 -1
- package/dist/{chunk-VGOWSOUA.js → chunk-YXKSUILG.js} +1 -1
- package/dist/{chunk-G6ZFSUIH.js → chunk-ZJVLGYE3.js} +2 -2
- package/dist/{chunk-BSAU7QRW.js → chunk-ZPTKAYJK.js} +1 -1
- package/dist/{chunk-XXDB6KPV.js → chunk-ZXXZESCD.js} +3 -4
- package/dist/generated/index.d.ts +2 -0
- package/dist/generated/index.js +97 -93
- package/dist/index.js +97 -93
- package/dist/styles.css +242 -57
- package/dist/utils/composedRef.d.ts +39 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +3 -1
- package/dist/utils/tokenMs.d.ts +6 -0
- package/package.json +5 -5
- package/dist/{chunk-IYI6HWKN.js → chunk-CV2LU2T2.js} +1 -1
- package/dist/{chunk-FVZPSTL2.js → chunk-G4EHZHKM.js} +1 -1
- package/dist/{chunk-FEJANUZK.js → chunk-KBSD476L.js} +0 -0
- package/dist/{chunk-2H6YDUR5.js → chunk-QM3432PH.js} +1 -1
- /package/dist/{chunk-KLWWNV25.js → chunk-REEZQCML.js} +0 -0
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ import { Button } from '@crewlethq/ui/Button'; // 8 KB of CSS, not 182 KB
|
|
|
53
53
|
| 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`) |
|
|
54
54
|
| Layout | `Container`, `Section`, `Card`, `TileGrid`, `ListDetail`, `AsideLayout`, `Tabs`, `Accordion`, `Disclosure`, `Outline` (with `useActiveHeading` and `scrollToHeading`), `TreeGrid` |
|
|
55
55
|
| Arranging a page | `ArrangeBoard`, `ArrangeGrid`, `ArrangeFrame` (with `useGridResize`), `ArrangeGroup`, `ArrangeList`, and the reorder hooks under them (`useReorder`, `useReorderLists`, `moveKey`) |
|
|
56
|
-
| Application shell | `AppShell` with `AppShell.Rail`, the compact rail (`rail="compact"`, the one fold control from `onRailChange`, and `useAppShell().rail` to pick the shape) and `fill="flush"`, the `aside` track and the `peek` slot (`useAppShellAside`, `useAppShellPeek`), `AppShell.ResizeHandle` (also `ResizeHandle`) and `useStoredWidth`, `SidePanel` and `SidePanelFrame`, `PeekRail` and `PeekHost` (with `PeekNeighbours`, `usePeekNeighbours`, `usePeekStep`, `peekClickHandler`, `peekRowActivation`), `SectionFrame` (with `SectionFrame.Nav` and `SectionFrame.Body`), `LockedLabel`, `AppShell.Topbar`, `AppShell.AccountRow` and `useAppShell`, `AuthLayout`, `SidebarNav` and `NavItem` (with `dense` lists, `unread` and `muted` rows and `collapsible` groups), `CompactNav` with `CompactNavItem`, `CompactNavGroup` and `CompactNavSeparator` (the rail folded to its marks, fed from the same places), `DirectoryList`, `BrandLockup`, `SearchTrigger`, `PageHeader`, `Toolbar`, `Stack`, `Inline`, `Spacer`, `AutoGrid`, `ErrorBoundary`, `useShortcut`, `useFullscreen`, `useIdle`, `useMediaMatch` |
|
|
56
|
+
| Application shell | `AppShell` with `AppShell.Rail`, the compact rail (`rail="compact"`, the one fold control from `onRailChange`, and `useAppShell().rail` to pick the shape) and `fill="flush"`, the `aside` track and the `peek` slot (`useAppShellAside`, `useAppShellPeek`), `AppShell.ResizeHandle` (also `ResizeHandle`) and `useStoredWidth`, `SidePanel` and `SidePanelFrame`, `PeekRail` and `PeekHost` (with `PeekNeighbours`, `usePeekNeighbours`, `usePeekStep`, `peekClickHandler`, `peekRowActivation`), `SectionFrame` (with `SectionFrame.Nav` and `SectionFrame.Body`), `DockColumn` and `usePresence`, `LockedLabel`, `AppShell.Topbar`, `AppShell.AccountRow` and `useAppShell`, `AuthLayout`, `SidebarNav` and `NavItem` (with `dense` lists, `unread` and `muted` rows and `collapsible` groups), `CompactNav` with `CompactNavItem`, `CompactNavGroup` and `CompactNavSeparator` (the rail folded to its marks, fed from the same places), `DirectoryList`, `BrandLockup`, `SearchTrigger`, `PageHeader`, `Toolbar`, `Stack`, `Inline`, `Spacer`, `AutoGrid`, `ErrorBoundary`, `useShortcut`, `useFullscreen`, `useIdle`, `useMediaMatch` |
|
|
57
57
|
| 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 |
|
|
58
58
|
| 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 |
|
|
59
59
|
| 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) |
|
|
@@ -205,6 +205,34 @@ places:
|
|
|
205
205
|
- A surface that pans or zooms dispatches `LAYER_REPOSITION_EVENT` on its host
|
|
206
206
|
when the content beneath it moves, and every panel anchored inside follows.
|
|
207
207
|
|
|
208
|
+
## Changes in 0.83.0
|
|
209
|
+
|
|
210
|
+
### The application rail
|
|
211
|
+
|
|
212
|
+
**The fold control is a plus and a minus in the rail's top left corner.** The chevron in the row under the rail's head is gone. In its place `AppShell` draws one control in the corner the head leaves empty, up and to the left of the brand's mark: a minus (`MinusGlyph`) while the rail is full, to make it smaller, and a plus (`PlusGlyph`) while it is compact, to open it. It is the same element in both shapes and never moves, so focus stays on it across a fold. It keeps its names ("Collapse the sidebar" and "Expand the sidebar", or `railFoldLabels`), `aria-controls`, `aria-keyshortcuts` and the keys in its tooltip, and now says `aria-expanded` (true while the rail is full). It stands at the target floor (`--size-target-min`, 24px) at every density, its ring is drawn inside its own box, and it is quiet until the rail is pointed at. Full, the search field keeps the nav's own columns, since nothing stands before it any more. Props are unchanged.
|
|
213
|
+
|
|
214
|
+
**The rail eases between its two shapes.** Its width moves on the slow step with the emphasized curve, the motion a `DockColumn` opens by, and what it holds keeps the width of the shape drawn, so the moving edge clips the rail's words rather than squeezing or rewrapping them, and the column under the edge never drifts. Folding, the full rail's middle, foot and status stay drawn and inert while its words fade out (focus inside them goes to the rail's first live control: the fold control, or the brand's link in the head, which stays live; with neither, the folded rail's first control once it is drawn), then the compact column fades in once the rail has moved; unfolding, the full rail is drawn at once and fades in while the edge uncovers it. The brand's mark and the fold control do not move or fade. Both shapes are a `usePresence` each, so the rail waits on the motion actually running on it, as a `DockColumn` does. `useAppShell().rail` reports the shape drawn, so it stays `full` until a fold has moved; the root's `data-rail-motion` (`fold`, `folded`, `unfold`, and `reverse` for a fold pressed again mid way, type `AppShellRailMotion`) names the phase under way. The words leave by a transition of their opacity, so a reversal brings them back from wherever their fade had reached rather than blinking them out and in; `usePresence` reports such a return as `returning`. Under reduced motion, and wherever nothing moves, the new shape is drawn at once. A change that arrives with the window crossing into the wide layout is drawn at once too. The rail's grid track is now `auto` and the rail takes `--crewlet-app-shell-rail` as its own width, which is still the one variable a host sets for a narrower rail. An aside column capped by the page's floor (`asideReserve`) now takes what the grid leaves it beside the rail's LIVE width, so it widens and narrows with the rail frame by frame, where a cap computed from the rail's variable jumped at both ends of a fold (story: `AppShellAside` Cap Follows A Folding Rail). While the rail moves the shell holds what it measures (the screen's width that `useScreenWidth` and `useScreenBelow` read, the scroller's gutter, the aside's width) and takes each once when the rail comes to rest, so no screen re-renders on every frame of a fold or changes shape mid way; a container query on the content column still follows every frame.
|
|
215
|
+
|
|
216
|
+
**In the compact rail the status has a row of its own under the brand's mark**, where the fold chevron stood, rather than at the top of the foot: the `AppShell.RailStatus` dot and count, centred, a small control step tall, before the places. It keeps its button, its name ("Engine serving, 2 alarms"), its popup attributes and its ref. A panel it opens now stands at the top of the rail, so open it below the status (`side="bottom"`) in both shapes. Full, it stays at the end of the head's line.
|
|
217
|
+
|
|
218
|
+
**The compact account face is centred on the tiles' line.** It took the full row's badge column and the step after it, which stood the face 4px left of the column's centre in a box 8px wider than the face. It now sits in a box of its own size, centred under the tiles. Hand the face at the tiles' height in the compact rail (`Avatar size="sm"`, 26px); the full row keeps `size="md"`.
|
|
219
|
+
|
|
220
|
+
**A place that waits on the reader takes the badge, whichever place it is.** `NavItem` and `CompactNavItem` draw a `badge` as the one filled accent pill, centred on the row's line and ending on the row's end inset, so a column of badges lines up down the rail; a `count` is the quiet figure. Nothing changed in how either is drawn: to show the reader's own work as the inbox is shown, pass `badge` rather than `count`. New stories: `AppShell` Fold Control In Both Shapes, `SidebarNav` Badges On The Rows About You, and `DockColumn` (Pinned Beside A Conversation, Unpinned, At The End).
|
|
221
|
+
|
|
222
|
+
### Columns that ease open and shut
|
|
223
|
+
|
|
224
|
+
**`usePresence` is new**: something kept drawn while it leaves. `usePresence(shown, ref, { transitions, animations, instant })` answers `present` (draw it), `leaving` (drawn only to finish leaving: make it `inert`) and `entering` (shown again, never on the first draw, while its motion runs: the window a stylesheet scopes an entrance to). It waits only for the surface's OWN motion (`MotionOwnership`), as it is actually running (`getAnimations()`), never for a duration written in code: the transitions on `ref`'s element itself (by property; any, if `transitions` is left out) and the keyframes it names in `animations`, wherever they run under it. A motion something else inside it runs (a meter filling, a badge arriving), a paused one and an endless one (a pulse) are never waited for, a motion replaced mid way is waited out in its turn, a reopen on the way out cancels the wait, and no wait outlasts the motion's own remaining time and a margin (the fast step), so a tab hidden mid motion still settles. Under `prefers-reduced-motion: reduce`, where nothing runs, where the Web Animations API is missing, and for a change the host marks `instant`, it goes straight through in the same commit, before any paint. `afterMotion(element, done, owned)` and `runningMotion(element, owned)` are the same wait for a host with its own state, `tokenMs(motion.duration.fast)` turns a motion token into milliseconds (Tooltip and CompactNav each kept a copy), `releaseFocus(container, target)` takes focus out of something about to turn inert (to the host's `target`, or off it). The reader's motion preference is now asked through one spelling of the query, **`REDUCED_MOTION_QUERY`**, with **`prefersReducedMotion(view)`** for a read outside render, both beside `useMediaMatch`; `ChatThread`, `Outline`, `useReorder` and `TreeCanvas` use them where each kept a copy of the string. The ui-tests helper `apps/ui-tests/src/motion.ts` (`driveMotion`, `settleMotion`, `preferReducedMotion`) starts and ends motion by hand in jsdom.
|
|
225
|
+
|
|
226
|
+
**`DockColumn` is new**: a column a host docks beside its content and takes away again, such as a list of rooms pinned beside a conversation. It stands in the host's own `auto` grid track (or as a flex item that does not grow) and eases its width between none and its panel's (`width`, px or any length) on the slow step with the emphasized curve, so the content beside it resizes frame by frame rather than jumping. The panel keeps its own width and is held to the edge that faces the content, so it slides in from the outer edge, and on close it stays drawn and `inert` until the column has closed over it; opened again on the way out, it is live where it is. Closed from inside (an Unpin in its own head), focus goes to `focusOnClose`, the control that docks it again, and is never left in the panel. `side` (`start`, the default, or `end`) places it, `divider` (on by default) draws the hairline on the edge that faces the content, and `--crewlet-dock-column-ground` gives the panel a ground. It is a plain column, not a landmark: what it holds names itself. Under reduced motion it simply is or is not. Types: `DockColumnProps`, `DockColumnSide`.
|
|
227
|
+
|
|
228
|
+
### React
|
|
229
|
+
|
|
230
|
+
**The package asks for React 19** (`react` and `react-dom` `>=19`, was `>=18`). The components already used what React 19 brought, `inert` as a boolean prop and `ref` as a plain prop of a function component and of an element (`ArrangeFrame`, `Tooltip`, `ListInput`, and now `DockColumn`, the folding rail and `Popover`), and under React 18 neither fails loudly: `inert` is dropped with a warning, so a panel on its way out stays focusable, and a ref read from props is undefined, so a trigger's own ref is lost. Every Crewlet application is on React 19. A suite holds the peer range to the source.
|
|
231
|
+
|
|
232
|
+
### Refs
|
|
233
|
+
|
|
234
|
+
**A trigger keeps its own ref across re-renders.** `Tooltip` cloned its trigger with a new ref callback on every render, so React took the element away from the trigger's own ref and gave it back in each commit, and a layout effect earlier in the tree read null while the control stood in the document (a `DockColumn` handing focus to a tooltip-wrapped Pin control as it closed). `Tooltip`, `Popover`, `Menu`'s trigger props and `Modal`'s frame now join their refs with **`useComposedRef(...refs)`** (new, with **`composeRefs`** for code outside a component and **`attachRef`** for one ref), one callback for any number of refs that is the same callback while they are the same and releases each the way React would. `Popover` also keeps the ref its trigger carried, which it used to replace.
|
|
235
|
+
|
|
208
236
|
## Changes in 0.82.0
|
|
209
237
|
|
|
210
238
|
### A conversation's messages
|
|
@@ -13,6 +13,9 @@ export interface AccountRowProps {
|
|
|
13
13
|
/**
|
|
14
14
|
* The reader's badge, drawn decorative: the name beside it says who it is.
|
|
15
15
|
* In a rail's foot the row is sized for a medium one (`size="md"`, 32px).
|
|
16
|
+
* In the compact rail the face stands among the compact places' tiles and
|
|
17
|
+
* takes their height, a small one (`size="sm"`, 26px), centred in the
|
|
18
|
+
* column as each tile is.
|
|
16
19
|
*/
|
|
17
20
|
avatar: ReactNode;
|
|
18
21
|
/** Who the reader is. */
|
|
@@ -73,6 +76,8 @@ export interface AccountRowProps {
|
|
|
73
76
|
* IN THE COMPACT RAIL THE ROW IS THE READER'S FACE (`compact`): the same link
|
|
74
77
|
* or menu button, holding the badge alone, named by the name and the detail
|
|
75
78
|
* as the full row is, and showing them in a tooltip, since a face says who
|
|
76
|
-
* it is only to somebody who already knows.
|
|
79
|
+
* it is only to somebody who already knows. The face is centred in the
|
|
80
|
+
* column on the line the tiles above it are centred on, and at their height
|
|
81
|
+
* when it is handed at the small step.
|
|
77
82
|
*/
|
|
78
83
|
export declare function AccountRow({ avatar, name, detail, href, menu, current, title, linkSuffix, actions, compact: compactProp, className, }: AccountRowProps): import("react").JSX.Element;
|
|
@@ -63,6 +63,7 @@ import { type AppShellRailShape } from './railShape.js';
|
|
|
63
63
|
export { useAppShellAside, useAppShellPeek } from './regions.js';
|
|
64
64
|
export type { AppShellAsideShape, AppShellPeekShape, AppShellRegionValue } from './regions.js';
|
|
65
65
|
export type { AppShellRailShape } from './railShape.js';
|
|
66
|
+
export type { AppShellRailMotion } from './railMotion.js';
|
|
66
67
|
/** The aside's resting width, in px, where the host names none. */
|
|
67
68
|
export declare const APP_SHELL_ASIDE_WIDTH = 420;
|
|
68
69
|
/** How the reader resizes the aside while it is a column. */
|
|
@@ -97,6 +98,8 @@ interface AppShellContextValue {
|
|
|
97
98
|
* The shape the rail is drawn in NOW: `compact` only where the host asked
|
|
98
99
|
* for it and the layout is wide, `full` in the drawer and everywhere else,
|
|
99
100
|
* so an application picks `CompactNav` or `SidebarNav` from this alone.
|
|
101
|
+
* While the rail folds it is still `full`, and it turns `compact` when the
|
|
102
|
+
* rail reaches the compact column (see `railMotion.ts`).
|
|
100
103
|
*/
|
|
101
104
|
rail: AppShellRailShape;
|
|
102
105
|
}
|
|
@@ -159,8 +162,10 @@ export interface AppShellProps extends Omit<HTMLAttributes<HTMLDivElement>, 'tit
|
|
|
159
162
|
rail?: AppShellRailShape | undefined;
|
|
160
163
|
/**
|
|
161
164
|
* Called with the other shape when the reader presses the fold control.
|
|
162
|
-
* Given, the shell draws THE fold control (never in the drawer)
|
|
163
|
-
*
|
|
165
|
+
* Given, the shell draws THE fold control (never in the drawer): a minus in
|
|
166
|
+
* the rail's top left corner while it is full, and a plus in the same place
|
|
167
|
+
* while it is compact. Keeping the choice, and binding a key to it, are the
|
|
168
|
+
* application's.
|
|
164
169
|
*/
|
|
165
170
|
onRailChange?: ((next: AppShellRailShape) => void) | undefined;
|
|
166
171
|
/**
|
|
@@ -248,7 +253,8 @@ export interface AppShellRailProps {
|
|
|
248
253
|
* A compact status at the end of the head's line, beside the name the head
|
|
249
254
|
* carries: an `<AppShell.RailStatus>`, the application's own state in a
|
|
250
255
|
* dot and a count. It takes its own width, so the name keeps the rest and
|
|
251
|
-
* truncates there, and it stands in the drawer's head the same way.
|
|
256
|
+
* truncates there, and it stands in the drawer's head the same way. In the
|
|
257
|
+
* compact rail it has a row of its own under the head's mark.
|
|
252
258
|
*/
|
|
253
259
|
status?: ReactNode;
|
|
254
260
|
/**
|
|
@@ -268,9 +274,12 @@ export interface AppShellRailProps {
|
|
|
268
274
|
* alone (the lockup shows its mark, over the column's centre, and keeps its
|
|
269
275
|
* name as the link's name and title); the field is not drawn, because a
|
|
270
276
|
* 76px column has no room for one and the application draws a Search tile
|
|
271
|
-
* among its `CompactNav` places instead; and the status stands
|
|
272
|
-
* the
|
|
273
|
-
* mark.
|
|
277
|
+
* among its `CompactNav` places instead; and the status stands in a row of
|
|
278
|
+
* its own under the mark, as its dot and count, since the head has no line
|
|
279
|
+
* left beside the mark. That row is the first thing under the head in the
|
|
280
|
+
* column, before the places, so the state a reader checks at a glance is
|
|
281
|
+
* where their eye starts. The middle and the foot are drawn as the
|
|
282
|
+
* application gives them.
|
|
274
283
|
*/
|
|
275
284
|
export declare function AppShellRail({ header, search, status, footer, className, children }: AppShellRailProps): import("react").JSX.Element;
|
|
276
285
|
/**
|
package/dist/AppShell/index.d.ts
CHANGED
|
@@ -9,4 +9,4 @@ export { useScreenBelow, useScreenWidth } from './screenWidth.js';
|
|
|
9
9
|
export type { StoredWidth, StoredWidthOptions, WidthStorage } from './storedWidth.js';
|
|
10
10
|
export { AccountRow } from './AccountRow.js';
|
|
11
11
|
export type { AccountRowMenu, AccountRowProps } from './AccountRow.js';
|
|
12
|
-
export type { ActionRailRowProps, ActionRailStatusProps, AppShellAsideResize, AppShellAsideShape, AppShellContextValue, AppShellPeekShape, AppShellProps, AppShellRailShape, AppShellRailProps, AppShellRailRowProps, AppShellRailStatusProps, AppShellRegionValue, AppShellToggleProps, AppShellTopbarProps, RailRowCount, StaticRailRowProps, StaticRailStatusProps, } from './AppShell.js';
|
|
12
|
+
export type { ActionRailRowProps, ActionRailStatusProps, AppShellAsideResize, AppShellAsideShape, AppShellContextValue, AppShellPeekShape, AppShellProps, AppShellRailMotion, AppShellRailShape, AppShellRailProps, AppShellRailRowProps, AppShellRailStatusProps, AppShellRegionValue, AppShellToggleProps, AppShellTopbarProps, RailRowCount, StaticRailRowProps, StaticRailStatusProps, } from './AppShell.js';
|
package/dist/AppShell/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
export { APP_SHELL_ASIDE_WIDTH, AccountRow, AppShell, AppShellRail, AppShellRailRow, AppShellRailStatus, AppShellToggle, AppShellTopbar, readStoredWidth, useAppShell, useScreenBelow, useScreenWidth, useStoredWidth } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
1
|
+
export { APP_SHELL_ASIDE_WIDTH, AccountRow, AppShell, AppShellRail, AppShellRailRow, AppShellRailStatus, AppShellToggle, AppShellTopbar, readStoredWidth, useAppShell, useScreenBelow, useScreenWidth, useStoredWidth } from '../chunk-PGBKZSSQ.js';
|
|
2
|
+
import '../chunk-PCAT2EFB.js';
|
|
3
|
+
import '../chunk-JLOESTT2.js';
|
|
4
|
+
import '../chunk-YJQXESOJ.js';
|
|
5
|
+
import '../chunk-7ZSEUO5Q.js';
|
|
6
|
+
import '../chunk-HTS5RJ7S.js';
|
|
7
|
+
import '../chunk-TGGYSQRD.js';
|
|
8
|
+
import '../chunk-L72URIHR.js';
|
|
6
9
|
export { RESIZE_HANDLE_LARGE_STEP, RESIZE_HANDLE_STEP, ResizeHandle, clampSize, useAppShellAside, useAppShellPeek } from '../chunk-PIYJNCN7.js';
|
|
7
10
|
import '../chunk-CMAZZY2I.js';
|
|
8
11
|
import '../chunk-DGXZ635L.js';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How the rail moves between its two shapes.
|
|
3
|
+
*
|
|
4
|
+
* THE STYLESHEET MOVES IT, THIS DECIDES THE ORDER. The rail's width eases
|
|
5
|
+
* between the full rail and the compact column (AppShell.css), and its
|
|
6
|
+
* content is laid out at the width of the shape drawn, clipped by the moving
|
|
7
|
+
* edge, so nothing in it rewraps at a width it will never rest at. What the
|
|
8
|
+
* stylesheet cannot decide is WHEN the content changes shape, because the
|
|
9
|
+
* application draws a different tree for each one:
|
|
10
|
+
*
|
|
11
|
+
* - UNFOLDING, the full rail is drawn at once, and the moving edge uncovers
|
|
12
|
+
* it while its words fade in (`unfold`).
|
|
13
|
+
* - FOLDING, the full rail stays drawn, inert, while the edge narrows over it
|
|
14
|
+
* and its words fade out (`fold`), and the compact column is drawn once the
|
|
15
|
+
* rail's motion has ended, fading in (`folded`). Drawn at once instead, the
|
|
16
|
+
* column would replace the words before the reader saw them go.
|
|
17
|
+
*
|
|
18
|
+
* ONE MECHANISM FOR EVERY COLUMN THAT EASES. Both shapes are a `usePresence`
|
|
19
|
+
* each, waiting on the motion actually running on the rail, as a
|
|
20
|
+
* `DockColumn` waits on its own: no duration is written again here, nothing
|
|
21
|
+
* waits under reduced motion, and where nothing moves the new shape is drawn
|
|
22
|
+
* in the same commit, before any paint.
|
|
23
|
+
*/
|
|
24
|
+
import { type RefObject } from 'react';
|
|
25
|
+
import type { AppShellRailShape } from './railShape.js';
|
|
26
|
+
/**
|
|
27
|
+
* Where a change of shape is: `fold` while the rail narrows over the full
|
|
28
|
+
* rail's fading words, `folded` while the compact column fades in after it,
|
|
29
|
+
* `unfold` while the rail widens and the full rail's words fade in, and
|
|
30
|
+
* `reverse` while a fold pressed again mid way widens the rail back and its
|
|
31
|
+
* words return from wherever their fade had reached.
|
|
32
|
+
*/
|
|
33
|
+
export type AppShellRailMotion = 'fold' | 'folded' | 'unfold' | 'reverse';
|
|
34
|
+
/**
|
|
35
|
+
* The rail's own motion, which a change of shape waits for: its width, on the
|
|
36
|
+
* rail itself, and the keyframes its words arrive by (AppShell.css), wherever
|
|
37
|
+
* they run inside it. Named, so that nothing else moving inside the rail (a
|
|
38
|
+
* meter filling, a badge arriving, a paused animation) holds a fold. The
|
|
39
|
+
* words LEAVE by a transition of their opacity, which a reversal turns back
|
|
40
|
+
* from where it is, and the rail's width outlasts it.
|
|
41
|
+
*/
|
|
42
|
+
export declare const RAIL_MOTION: {
|
|
43
|
+
readonly transitions: readonly ["width"];
|
|
44
|
+
readonly animations: readonly ["crewlet-app-shell-rail-unfold", "crewlet-app-shell-rail-settle"];
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* The shape to draw the rail's content in, the phase of the change under
|
|
48
|
+
* way, and whether the content drawn is only leaving (and so inert), for a
|
|
49
|
+
* rail whose chosen shape is `target`.
|
|
50
|
+
*
|
|
51
|
+
* `moves` is whether a change may animate at all: never in the drawer, where
|
|
52
|
+
* the rail is always the full list and a shape is not a width. A change that
|
|
53
|
+
* arrives WITH the window crossing into the wide layout does not animate
|
|
54
|
+
* either: the reader resized a window, they did not fold a rail.
|
|
55
|
+
*/
|
|
56
|
+
export declare function useRailMotion(target: AppShellRailShape, moves: boolean, rail: RefObject<HTMLElement | null>): {
|
|
57
|
+
drawn: AppShellRailShape;
|
|
58
|
+
motion: AppShellRailMotion | null;
|
|
59
|
+
leaving: boolean;
|
|
60
|
+
};
|
|
@@ -15,3 +15,8 @@ export type AppShellRailShape = 'full' | 'compact';
|
|
|
15
15
|
export declare const RailShapeContext: import("react").Context<AppShellRailShape>;
|
|
16
16
|
/** The shape the rail around this component is drawn in now: `full` outside a shell, and in the drawer. */
|
|
17
17
|
export declare function useRailShape(): AppShellRailShape;
|
|
18
|
+
/**
|
|
19
|
+
* Whether the rail's content is drawn only to finish leaving, while the rail
|
|
20
|
+
* folds over it (railMotion.ts): `AppShell.Rail` makes it inert then.
|
|
21
|
+
*/
|
|
22
|
+
export declare const RailLeavingContext: import("react").Context<boolean>;
|
|
@@ -27,30 +27,40 @@
|
|
|
27
27
|
--crewlet-app-shell-rail: var(--size-shell-rail);
|
|
28
28
|
--crewlet-app-shell-topbar: var(--size-shell-topbar);
|
|
29
29
|
/* What stands on the frame to the sheet's left: the rail's column, or
|
|
30
|
-
nothing where there is no rail or the rail is a drawer.
|
|
31
|
-
below subtracts it, so it is one name for both. */
|
|
30
|
+
nothing where there is no rail or the rail is a drawer. */
|
|
32
31
|
--crewlet-app-shell-beside: var(--crewlet-app-shell-rail);
|
|
33
|
-
/*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
/*
|
|
33
|
+
* THE ASIDE'S TRACK, while it is a column: the inset it is held off the
|
|
34
|
+
* window's edge by at least, and the panel's width and that inset at most.
|
|
35
|
+
* THE CAP IS THE GRID'S. The page's sheet takes the host's floor as its
|
|
36
|
+
* own track's minimum (`--crewlet-app-shell-aside-reserve`, the page's sheet
|
|
37
|
+
* with its own inset and hairlines), and the grid hands the aside what is
|
|
38
|
+
* left once the rail and that floor have theirs, up to its width. The rail's
|
|
39
|
+
* track is the rail's live width, so while the rail eases between its
|
|
40
|
+
* shapes the cap eases with it: a cap computed from the rail's VARIABLE
|
|
41
|
+
* named the shape drawn, and jumped at both ends of a fold. With no reserve
|
|
42
|
+
* the panel takes the width it was given, as far as the window holds it.
|
|
43
|
+
*/
|
|
44
|
+
--crewlet-app-shell-aside-track: minmax(
|
|
45
|
+
var(--size-shell-inset),
|
|
46
|
+
calc(var(--crewlet-app-shell-aside) + var(--size-shell-inset))
|
|
47
|
+
);
|
|
48
|
+
/* The page's floor beside an aside column, never more than the window
|
|
49
|
+
leaves it: on a window too narrow for the floor, the page gives way rather
|
|
50
|
+
than the shell growing past the window's edge. */
|
|
51
|
+
--crewlet-app-shell-sheet-floor: min(
|
|
52
|
+
var(--crewlet-app-shell-aside-reserve, 0px),
|
|
53
|
+
max(0px, 100% - var(--crewlet-app-shell-beside) - var(--size-shell-inset))
|
|
47
54
|
);
|
|
48
55
|
/* Where the drawer's veil sits while it is open. The shell replaces it with
|
|
49
56
|
the surface's own place in the layer band; this default only has to clear
|
|
50
57
|
the page chrome for the moment before that lands. */
|
|
51
58
|
--crewlet-app-shell-drawer-z: var(--z-index-overlay);
|
|
52
59
|
display: grid;
|
|
53
|
-
|
|
60
|
+
/* The rail's track is the rail's own width (`auto`), and the rail takes
|
|
61
|
+
`--crewlet-app-shell-rail` itself, so the track follows it while it eases
|
|
62
|
+
between its two shapes (see the rail's motion, below). */
|
|
63
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
54
64
|
/* One row, the viewport's height less nothing: the sheet's own margin is
|
|
55
65
|
what holds it off the frame's edges, and a row sized by its content would
|
|
56
66
|
let a tall screen push the sheet's bottom edge off the window. */
|
|
@@ -89,11 +99,11 @@
|
|
|
89
99
|
keeps its column and is only narrower, so nothing under the bar moves but
|
|
90
100
|
its end edge. */
|
|
91
101
|
.crewlet-app-shell[data-aside='column'] {
|
|
92
|
-
grid-template-columns: var(--crewlet-app-shell-
|
|
102
|
+
grid-template-columns: auto minmax(var(--crewlet-app-shell-sheet-floor), 1fr) var(--crewlet-app-shell-aside-track);
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
.crewlet-app-shell--no-rail[data-aside='column'] {
|
|
96
|
-
grid-template-columns: minmax(
|
|
106
|
+
grid-template-columns: minmax(var(--crewlet-app-shell-sheet-floor), 1fr) var(--crewlet-app-shell-aside-track);
|
|
97
107
|
}
|
|
98
108
|
|
|
99
109
|
/* The skip link, drawn only while it holds focus, over everything. */
|
|
@@ -139,14 +149,25 @@
|
|
|
139
149
|
position: relative;
|
|
140
150
|
display: flex;
|
|
141
151
|
flex-direction: column;
|
|
152
|
+
width: var(--crewlet-app-shell-rail);
|
|
142
153
|
min-height: 0;
|
|
143
154
|
min-width: 0;
|
|
155
|
+
/* THE MOVING EDGE CUTS WHAT IT PASSES. While the rail eases between its
|
|
156
|
+
shapes its content keeps the width of the shape drawn (below), and the
|
|
157
|
+
edge clips it rather than squeezing it. Across only: a ring or a badge
|
|
158
|
+
at a row's top or bottom is never cut. */
|
|
159
|
+
overflow-x: clip;
|
|
144
160
|
background: var(--color-surface-frame);
|
|
161
|
+
transition: width var(--motion-duration-slow) var(--motion-easing-emphasized);
|
|
145
162
|
}
|
|
146
163
|
|
|
164
|
+
/* THE CONTENT IS LAID OUT AT ITS SHAPE'S WIDTH, never at a width between the
|
|
165
|
+
two, so no word in the rail rewraps while it moves and nothing drifts with
|
|
166
|
+
the edge: the column stands still and the edge travels over it. */
|
|
147
167
|
.crewlet-app-shell__rail-inner {
|
|
148
168
|
display: flex;
|
|
149
169
|
flex-direction: column;
|
|
170
|
+
width: var(--crewlet-app-shell-rail);
|
|
150
171
|
min-height: 0;
|
|
151
172
|
height: 100%;
|
|
152
173
|
}
|
|
@@ -890,7 +911,7 @@
|
|
|
890
911
|
}
|
|
891
912
|
|
|
892
913
|
/*
|
|
893
|
-
* THE COMPACT RAIL: the same
|
|
914
|
+
* THE COMPACT RAIL: the same rail, narrowed to the compact column. One
|
|
894
915
|
* variable is the rail's width for the grid, the aside's cap and the drawer
|
|
895
916
|
* alike, so folding the rail is this one declaration. The shell writes the
|
|
896
917
|
* attribute only where the layout is wide: the drawer under the step is
|
|
@@ -901,21 +922,29 @@
|
|
|
901
922
|
}
|
|
902
923
|
|
|
903
924
|
/*
|
|
904
|
-
* THE FOLD CONTROL stands
|
|
905
|
-
*
|
|
906
|
-
*
|
|
907
|
-
*
|
|
908
|
-
*
|
|
925
|
+
* THE FOLD CONTROL stands in the rail's top left corner, in both shapes, so
|
|
926
|
+
* it never moves under the pointer that pressed it: a minus while the rail is
|
|
927
|
+
* full and a plus while it is compact. The corner is the square the head
|
|
928
|
+
* leaves empty up and to the left of the brand's mark, and the control is the
|
|
929
|
+
* target floor (`--size-target-min`), so it ends short of the mark on the
|
|
930
|
+
* compact column's centre at every density.
|
|
931
|
+
*
|
|
932
|
+
* Quiet until the rail is pointed at: the tertiary ink, which holds 3:1 on
|
|
933
|
+
* the frame, then the secondary, and the ghost's own primary under the
|
|
934
|
+
* pointer. Its ring is drawn inside its own box, because the corner it
|
|
935
|
+
* stands in is the window's, and a ring outside it would be cut there.
|
|
909
936
|
*/
|
|
910
937
|
.crewlet-app-shell__fold {
|
|
911
938
|
position: absolute;
|
|
912
|
-
top:
|
|
913
|
-
left:
|
|
939
|
+
top: 0;
|
|
940
|
+
left: 0;
|
|
914
941
|
z-index: 1;
|
|
915
942
|
display: inline-flex;
|
|
916
943
|
}
|
|
917
944
|
|
|
918
945
|
.crewlet-app-shell__fold > .crewlet-icon-btn {
|
|
946
|
+
width: var(--size-target-min);
|
|
947
|
+
height: var(--size-target-min);
|
|
919
948
|
color: var(--color-text-tertiary);
|
|
920
949
|
}
|
|
921
950
|
|
|
@@ -923,6 +952,10 @@
|
|
|
923
952
|
color: var(--color-text-secondary);
|
|
924
953
|
}
|
|
925
954
|
|
|
955
|
+
.crewlet-app-shell__fold > .crewlet-icon-btn:focus-visible {
|
|
956
|
+
outline-offset: var(--size-focus-ring-inset-offset);
|
|
957
|
+
}
|
|
958
|
+
|
|
926
959
|
/*
|
|
927
960
|
* THE MARK STANDS WHERE THE COMPACT RAIL'S DOES, in both shapes: centred over
|
|
928
961
|
* the compact column, in the head. Full, the name follows it; compact, the
|
|
@@ -939,30 +972,16 @@
|
|
|
939
972
|
}
|
|
940
973
|
|
|
941
974
|
/*
|
|
942
|
-
*
|
|
943
|
-
*
|
|
944
|
-
*
|
|
945
|
-
*
|
|
975
|
+
* COMPACT, THE STATUS HAS A ROW OF ITS OWN under the mark, a small control
|
|
976
|
+
* step tall, its dot and its count centred in the column: the first thing
|
|
977
|
+
* under the head, before the places, where the fold control stood before it
|
|
978
|
+
* moved to the corner.
|
|
946
979
|
*/
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
.crewlet-app-shell--foldable[data-rail='full'] .crewlet-app-shell__rail-search {
|
|
955
|
-
position: sticky;
|
|
956
|
-
top: 0;
|
|
957
|
-
z-index: 1;
|
|
958
|
-
padding-left: calc((var(--size-shell-rail-compact) + var(--size-control-sm)) / 2 + var(--spacing-2));
|
|
959
|
-
background: var(--color-surface-frame);
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
/* COMPACT, THE FOLD CONTROL HAS A ROW OF ITS OWN under the mark, which the
|
|
963
|
-
head leaves room for, and the column of tiles starts under it. */
|
|
964
|
-
.crewlet-app-shell--foldable[data-rail='compact'] .crewlet-app-shell__rail-head {
|
|
965
|
-
margin-bottom: var(--size-control-sm);
|
|
980
|
+
.crewlet-app-shell[data-rail='compact'] .crewlet-app-shell__rail-inner > .crewlet-app-shell__rail-status {
|
|
981
|
+
justify-content: center;
|
|
982
|
+
min-width: 0;
|
|
983
|
+
min-height: var(--size-control-sm);
|
|
984
|
+
margin: 0;
|
|
966
985
|
}
|
|
967
986
|
|
|
968
987
|
.crewlet-app-shell[data-rail='compact'] .crewlet-app-shell__rail-body {
|
|
@@ -972,7 +991,7 @@
|
|
|
972
991
|
|
|
973
992
|
/*
|
|
974
993
|
* The compact foot: what the full foot holds, centred in the column, a step
|
|
975
|
-
* apart:
|
|
994
|
+
* apart: a Settings tile, the reader's face.
|
|
976
995
|
*/
|
|
977
996
|
.crewlet-app-shell[data-rail='compact'] .crewlet-app-shell__rail-foot {
|
|
978
997
|
align-items: center;
|
|
@@ -984,10 +1003,85 @@
|
|
|
984
1003
|
align-self: stretch;
|
|
985
1004
|
}
|
|
986
1005
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1006
|
+
/*
|
|
1007
|
+
* THE COMPACT FACE IS CENTRED ON THE TILES' LINE. It gives up the full row's
|
|
1008
|
+
* badge column and the step after it (above): kept, the step stood the face
|
|
1009
|
+
* 4px left of the column's centre, in a box 8px wider than the face, so the
|
|
1010
|
+
* face sat off the line every tile above it is centred on.
|
|
1011
|
+
*/
|
|
1012
|
+
.crewlet-app-shell__rail-foot .crewlet-account-row--compact .crewlet-account-row__avatar {
|
|
1013
|
+
width: auto;
|
|
1014
|
+
margin-inline-end: 0;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/*
|
|
1018
|
+
* THE RAIL'S MOTION (railMotion.ts). The rail's width eases between the two
|
|
1019
|
+
* shapes on the slow step with the emphasized curve, the motion a
|
|
1020
|
+
* `DockColumn` opens and closes by, so a column of the frame and a column of
|
|
1021
|
+
* a screen move as one. What the rail holds keeps the width of the shape
|
|
1022
|
+
* drawn, so the moving edge clips the words rather than squeezing them.
|
|
1023
|
+
*
|
|
1024
|
+
* FOLDING, the full rail stays drawn, inert, while the edge narrows to the
|
|
1025
|
+
* compact column, and its words fade out on the base step; the compact column
|
|
1026
|
+
* is drawn when the rail's motion has ended, and fades in on the fast step.
|
|
1027
|
+
* UNFOLDING, the full rail is drawn at once and fades in while the edge
|
|
1028
|
+
* uncovers it. The brand's mark and the fold control are in the same place in
|
|
1029
|
+
* both shapes, so neither fades.
|
|
1030
|
+
*
|
|
1031
|
+
* THE WORDS LEAVE BY A TRANSITION and arrive by keyframes. A fold takes their
|
|
1032
|
+
* opacity to nothing; a fold pressed again mid way (`reverse`) declares
|
|
1033
|
+
* nothing of its own, so the same transition takes the opacity back from
|
|
1034
|
+
* wherever it had reached. Faded out by keyframes instead, a reversal could
|
|
1035
|
+
* only start an entrance from nothing, and the words blinked out and back.
|
|
1036
|
+
* The transition is declared only while the rail moves, so nothing else that
|
|
1037
|
+
* sets these parts' opacity is eased.
|
|
1038
|
+
*/
|
|
1039
|
+
.crewlet-app-shell[data-rail-motion='fold'] > .crewlet-app-shell__rail {
|
|
1040
|
+
width: var(--size-shell-rail-compact);
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
/* Two names for one entrance, so an unfold pressed while the compact column
|
|
1044
|
+
is still arriving starts the full rail's entrance afresh. */
|
|
1045
|
+
@keyframes crewlet-app-shell-rail-unfold {
|
|
1046
|
+
from {
|
|
1047
|
+
opacity: 0;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
@keyframes crewlet-app-shell-rail-settle {
|
|
1052
|
+
from {
|
|
1053
|
+
opacity: 0;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-body,
|
|
1058
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-foot,
|
|
1059
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-status,
|
|
1060
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-head .crewlet-brand__name,
|
|
1061
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-head .crewlet-brand__context {
|
|
1062
|
+
transition: opacity var(--motion-duration-base) var(--motion-easing-out);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
.crewlet-app-shell[data-rail-motion='fold'] .crewlet-app-shell__rail-body,
|
|
1066
|
+
.crewlet-app-shell[data-rail-motion='fold'] .crewlet-app-shell__rail-foot,
|
|
1067
|
+
.crewlet-app-shell[data-rail-motion='fold'] .crewlet-app-shell__rail-status,
|
|
1068
|
+
.crewlet-app-shell[data-rail-motion='fold'] .crewlet-app-shell__rail-head .crewlet-brand__name,
|
|
1069
|
+
.crewlet-app-shell[data-rail-motion='fold'] .crewlet-app-shell__rail-head .crewlet-brand__context {
|
|
1070
|
+
opacity: 0;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-body,
|
|
1074
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-foot,
|
|
1075
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-status,
|
|
1076
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-head .crewlet-brand__name,
|
|
1077
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-head .crewlet-brand__context {
|
|
1078
|
+
animation: crewlet-app-shell-rail-unfold var(--motion-duration-slow) var(--motion-easing-out);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
.crewlet-app-shell[data-rail-motion='folded'] .crewlet-app-shell__rail-body,
|
|
1082
|
+
.crewlet-app-shell[data-rail-motion='folded'] .crewlet-app-shell__rail-foot,
|
|
1083
|
+
.crewlet-app-shell[data-rail-motion='folded'] .crewlet-app-shell__rail-status {
|
|
1084
|
+
animation: crewlet-app-shell-rail-settle var(--motion-duration-fast) var(--motion-easing-out);
|
|
991
1085
|
}
|
|
992
1086
|
|
|
993
1087
|
@media (width < 1024px) {
|
|
@@ -1000,7 +1094,7 @@
|
|
|
1000
1094
|
step is still a column; the rail is a drawer here and takes no track. */
|
|
1001
1095
|
.crewlet-app-shell[data-aside='column'],
|
|
1002
1096
|
.crewlet-app-shell--no-rail[data-aside='column'] {
|
|
1003
|
-
grid-template-columns: minmax(
|
|
1097
|
+
grid-template-columns: minmax(var(--crewlet-app-shell-sheet-floor), 1fr) var(--crewlet-app-shell-aside-track);
|
|
1004
1098
|
}
|
|
1005
1099
|
|
|
1006
1100
|
.crewlet-app-shell--no-rail {
|
|
@@ -1065,6 +1159,12 @@
|
|
|
1065
1159
|
transition: transform var(--motion-duration-slow) var(--motion-easing-emphasized);
|
|
1066
1160
|
}
|
|
1067
1161
|
|
|
1162
|
+
/* The drawer never changes shape, and on a window narrower than the rail
|
|
1163
|
+
it is the window's width: its content fills it rather than being cut. */
|
|
1164
|
+
.crewlet-app-shell__rail-inner {
|
|
1165
|
+
width: auto;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1068
1168
|
.crewlet-app-shell__toggle {
|
|
1069
1169
|
display: inline-flex;
|
|
1070
1170
|
}
|
|
@@ -1099,6 +1199,27 @@
|
|
|
1099
1199
|
.crewlet-app-shell__aside[data-shape='sheet'] {
|
|
1100
1200
|
animation: none;
|
|
1101
1201
|
}
|
|
1202
|
+
|
|
1203
|
+
/* Under reduced motion the shell draws the new shape at once
|
|
1204
|
+
(`usePresence`), so no phase starts; these hold even if one did. */
|
|
1205
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-body,
|
|
1206
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-foot,
|
|
1207
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-status,
|
|
1208
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-head .crewlet-brand__name,
|
|
1209
|
+
.crewlet-app-shell[data-rail-motion] .crewlet-app-shell__rail-head .crewlet-brand__context {
|
|
1210
|
+
transition: none;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-body,
|
|
1214
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-foot,
|
|
1215
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-status,
|
|
1216
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-head .crewlet-brand__name,
|
|
1217
|
+
.crewlet-app-shell[data-rail-motion='unfold'] .crewlet-app-shell__rail-head .crewlet-brand__context,
|
|
1218
|
+
.crewlet-app-shell[data-rail-motion='folded'] .crewlet-app-shell__rail-body,
|
|
1219
|
+
.crewlet-app-shell[data-rail-motion='folded'] .crewlet-app-shell__rail-foot,
|
|
1220
|
+
.crewlet-app-shell[data-rail-motion='folded'] .crewlet-app-shell__rail-status {
|
|
1221
|
+
animation: none;
|
|
1222
|
+
}
|
|
1102
1223
|
}
|
|
1103
1224
|
|
|
1104
1225
|
/* ── the account row ───────────────────────────────────────────────────── */
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { ArrangeList, DEFAULT_ARRANGE_LABELS } from '../chunk-
|
|
1
|
+
export { ArrangeList, DEFAULT_ARRANGE_LABELS } from '../chunk-XTJHMP3W.js';
|
|
2
2
|
import '../chunk-3XDT5ZWL.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-BVML4UVB.js';
|
|
4
4
|
import '../chunk-YQ7Q52XU.js';
|
|
5
|
+
import '../chunk-YJQXESOJ.js';
|
|
5
6
|
import '../chunk-O7N6W52M.js';
|
|
6
7
|
import '../chunk-PGCLHYVP.js';
|
|
7
8
|
import '../chunk-TUEM2XIW.js';
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
export { ARTIFACT_BAR_LABELS, ArtifactBar, ArtifactVersionChip } from '../chunk-
|
|
1
|
+
export { ARTIFACT_BAR_LABELS, ArtifactBar, ArtifactVersionChip } from '../chunk-BXGBGYKH.js';
|
|
2
2
|
import '../chunk-36WK24AI.js';
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-AZYE7NR4.js';
|
|
4
|
+
import '../chunk-MVKUE4FI.js';
|
|
5
5
|
import '../chunk-EGMQURBR.js';
|
|
6
6
|
import '../chunk-CYQBDZ6M.js';
|
|
7
7
|
import '../chunk-AVL52EME.js';
|
|
8
8
|
import '../chunk-RSKW25Y5.js';
|
|
9
|
-
import '../chunk-
|
|
10
|
-
import '../chunk-
|
|
9
|
+
import '../chunk-7ZSEUO5Q.js';
|
|
10
|
+
import '../chunk-HTS5RJ7S.js';
|
|
11
|
+
import '../chunk-TGGYSQRD.js';
|
|
12
|
+
import '../chunk-L72URIHR.js';
|
|
11
13
|
import '../chunk-CMAZZY2I.js';
|
|
12
14
|
import '../chunk-DGXZ635L.js';
|
|
13
15
|
import '../chunk-XSPCITPN.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ArtifactCard, ArtifactCardSkeleton, ArtifactPreviewGlyph } from '../chunk-
|
|
1
|
+
export { ArtifactCard, ArtifactCardSkeleton, ArtifactPreviewGlyph } from '../chunk-QM3432PH.js';
|
|
2
2
|
import '../chunk-I4IUX3JF.js';
|
|
3
3
|
import '../chunk-HF5L56YQ.js';
|
|
4
4
|
import '../chunk-EJNJMHQG.js';
|
|
@@ -8,8 +8,8 @@ import '../chunk-AV2DXAEL.js';
|
|
|
8
8
|
import '../chunk-IRONPJB4.js';
|
|
9
9
|
import '../chunk-XZY6S3UC.js';
|
|
10
10
|
import '../chunk-ZB3E2Z4Y.js';
|
|
11
|
-
import '../chunk-DOY3KC6I.js';
|
|
12
11
|
import '../chunk-YQ7Q52XU.js';
|
|
12
|
+
import '../chunk-DOY3KC6I.js';
|
|
13
13
|
export { ARTIFACT_KINDS, ArtifactKindGlyph } from '../chunk-RSKW25Y5.js';
|
|
14
14
|
import '../chunk-O7N6W52M.js';
|
|
15
15
|
import '../chunk-PGCLHYVP.js';
|