@oxy.so/bloom 2.11.0 → 2.12.1
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/docs/app-shell.mdx +90 -4
- package/docs/content-panel.mdx +65 -19
- package/docs/date-picker.mdx +80 -2
- package/docs/listing-card.mdx +54 -0
- package/docs/rating.mdx +52 -2
- package/docs/stay-search.mdx +38 -0
- package/lib/commonjs/app-shell/AppShell.js +121 -5
- package/lib/commonjs/app-shell/AppShell.js.map +1 -1
- package/lib/commonjs/app-shell/layout.js +10 -5
- package/lib/commonjs/app-shell/layout.js.map +1 -1
- package/lib/commonjs/content-panel/ContentPanel.js +8 -2
- package/lib/commonjs/content-panel/ContentPanel.js.map +1 -1
- package/lib/commonjs/content-panel/ContentPanel.web.js +38 -25
- package/lib/commonjs/content-panel/ContentPanel.web.js.map +1 -1
- package/lib/commonjs/date-picker/TimeField.js +175 -0
- package/lib/commonjs/date-picker/TimeField.js.map +1 -0
- package/lib/commonjs/date-picker/index.js +7 -0
- package/lib/commonjs/date-picker/index.js.map +1 -1
- package/lib/commonjs/date-picker/time.js +160 -0
- package/lib/commonjs/date-picker/time.js.map +1 -0
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +7 -0
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/listing-card/ListingCard.js +34 -1
- package/lib/commonjs/listing-card/ListingCard.js.map +1 -1
- package/lib/commonjs/listing-card/WishlistCard.js +50 -8
- package/lib/commonjs/listing-card/WishlistCard.js.map +1 -1
- package/lib/commonjs/listing-card/shared.js +23 -1
- package/lib/commonjs/listing-card/shared.js.map +1 -1
- package/lib/commonjs/message-bubble/MessageBubble.js +16 -1
- package/lib/commonjs/message-bubble/MessageBubble.js.map +1 -1
- package/lib/commonjs/rating/RatingInput.js +218 -0
- package/lib/commonjs/rating/RatingInput.js.map +1 -0
- package/lib/commonjs/rating/index.js +7 -0
- package/lib/commonjs/rating/index.js.map +1 -1
- package/lib/commonjs/stay-search/DestinationSuggestions.js +46 -9
- package/lib/commonjs/stay-search/DestinationSuggestions.js.map +1 -1
- package/lib/commonjs/stay-search/GuestPicker.js +9 -0
- package/lib/commonjs/stay-search/GuestPicker.js.map +1 -1
- package/lib/commonjs/track-list/parts.js +0 -13
- package/lib/commonjs/track-list/parts.js.map +1 -1
- package/lib/module/app-shell/AppShell.js +121 -5
- package/lib/module/app-shell/AppShell.js.map +1 -1
- package/lib/module/app-shell/layout.js +10 -5
- package/lib/module/app-shell/layout.js.map +1 -1
- package/lib/module/content-panel/ContentPanel.js +8 -2
- package/lib/module/content-panel/ContentPanel.js.map +1 -1
- package/lib/module/content-panel/ContentPanel.web.js +38 -25
- package/lib/module/content-panel/ContentPanel.web.js.map +1 -1
- package/lib/module/date-picker/TimeField.js +170 -0
- package/lib/module/date-picker/TimeField.js.map +1 -0
- package/lib/module/date-picker/index.js +3 -0
- package/lib/module/date-picker/index.js.map +1 -1
- package/lib/module/date-picker/time.js +151 -0
- package/lib/module/date-picker/time.js.map +1 -0
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +1 -1
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/listing-card/ListingCard.js +34 -1
- package/lib/module/listing-card/ListingCard.js.map +1 -1
- package/lib/module/listing-card/WishlistCard.js +50 -8
- package/lib/module/listing-card/WishlistCard.js.map +1 -1
- package/lib/module/listing-card/shared.js +22 -0
- package/lib/module/listing-card/shared.js.map +1 -1
- package/lib/module/message-bubble/MessageBubble.js +16 -1
- package/lib/module/message-bubble/MessageBubble.js.map +1 -1
- package/lib/module/rating/RatingInput.js +212 -0
- package/lib/module/rating/RatingInput.js.map +1 -0
- package/lib/module/rating/index.js +1 -0
- package/lib/module/rating/index.js.map +1 -1
- package/lib/module/stay-search/DestinationSuggestions.js +45 -9
- package/lib/module/stay-search/DestinationSuggestions.js.map +1 -1
- package/lib/module/stay-search/GuestPicker.js +9 -0
- package/lib/module/stay-search/GuestPicker.js.map +1 -1
- package/lib/module/track-list/parts.js +1 -14
- package/lib/module/track-list/parts.js.map +1 -1
- package/lib/typescript/commonjs/app-shell/AppShell.d.ts.map +1 -1
- package/lib/typescript/commonjs/app-shell/layout.d.ts +5 -4
- package/lib/typescript/commonjs/app-shell/layout.d.ts.map +1 -1
- package/lib/typescript/commonjs/app-shell/types.d.ts +12 -2
- package/lib/typescript/commonjs/app-shell/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/content-panel/ContentPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/content-panel/ContentPanel.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/content-panel/types.d.ts +53 -42
- package/lib/typescript/commonjs/content-panel/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/TimeField.d.ts +6 -0
- package/lib/typescript/commonjs/date-picker/TimeField.d.ts.map +1 -0
- package/lib/typescript/commonjs/date-picker/index.d.ts +2 -1
- package/lib/typescript/commonjs/date-picker/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/time.d.ts +56 -0
- package/lib/typescript/commonjs/date-picker/time.d.ts.map +1 -0
- package/lib/typescript/commonjs/date-picker/types.d.ts +49 -3
- package/lib/typescript/commonjs/date-picker/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -2
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +2 -2
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/listing-card/ListingCard.d.ts.map +1 -1
- package/lib/typescript/commonjs/listing-card/WishlistCard.d.ts +1 -1
- package/lib/typescript/commonjs/listing-card/WishlistCard.d.ts.map +1 -1
- package/lib/typescript/commonjs/listing-card/shared.d.ts +8 -1
- package/lib/typescript/commonjs/listing-card/shared.d.ts.map +1 -1
- package/lib/typescript/commonjs/listing-card/types.d.ts +37 -0
- package/lib/typescript/commonjs/listing-card/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/message-bubble/MessageBubble.d.ts.map +1 -1
- package/lib/typescript/commonjs/rating/RatingInput.d.ts +8 -0
- package/lib/typescript/commonjs/rating/RatingInput.d.ts.map +1 -0
- package/lib/typescript/commonjs/rating/index.d.ts +2 -1
- package/lib/typescript/commonjs/rating/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/rating/types.d.ts +31 -0
- package/lib/typescript/commonjs/rating/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/stay-search/DestinationSuggestions.d.ts +8 -0
- package/lib/typescript/commonjs/stay-search/DestinationSuggestions.d.ts.map +1 -1
- package/lib/typescript/commonjs/stay-search/GuestPicker.d.ts +6 -1
- package/lib/typescript/commonjs/stay-search/GuestPicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/stay-search/types.d.ts +20 -0
- package/lib/typescript/commonjs/stay-search/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/track-list/parts.d.ts.map +1 -1
- package/lib/typescript/module/app-shell/AppShell.d.ts.map +1 -1
- package/lib/typescript/module/app-shell/layout.d.ts +5 -4
- package/lib/typescript/module/app-shell/layout.d.ts.map +1 -1
- package/lib/typescript/module/app-shell/types.d.ts +12 -2
- package/lib/typescript/module/app-shell/types.d.ts.map +1 -1
- package/lib/typescript/module/content-panel/ContentPanel.d.ts.map +1 -1
- package/lib/typescript/module/content-panel/ContentPanel.web.d.ts.map +1 -1
- package/lib/typescript/module/content-panel/types.d.ts +53 -42
- package/lib/typescript/module/content-panel/types.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/TimeField.d.ts +6 -0
- package/lib/typescript/module/date-picker/TimeField.d.ts.map +1 -0
- package/lib/typescript/module/date-picker/index.d.ts +2 -1
- package/lib/typescript/module/date-picker/index.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/time.d.ts +56 -0
- package/lib/typescript/module/date-picker/time.d.ts.map +1 -0
- package/lib/typescript/module/date-picker/types.d.ts +49 -3
- package/lib/typescript/module/date-picker/types.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +2 -2
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +2 -2
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/listing-card/ListingCard.d.ts.map +1 -1
- package/lib/typescript/module/listing-card/WishlistCard.d.ts +1 -1
- package/lib/typescript/module/listing-card/WishlistCard.d.ts.map +1 -1
- package/lib/typescript/module/listing-card/shared.d.ts +8 -1
- package/lib/typescript/module/listing-card/shared.d.ts.map +1 -1
- package/lib/typescript/module/listing-card/types.d.ts +37 -0
- package/lib/typescript/module/listing-card/types.d.ts.map +1 -1
- package/lib/typescript/module/message-bubble/MessageBubble.d.ts.map +1 -1
- package/lib/typescript/module/rating/RatingInput.d.ts +8 -0
- package/lib/typescript/module/rating/RatingInput.d.ts.map +1 -0
- package/lib/typescript/module/rating/index.d.ts +2 -1
- package/lib/typescript/module/rating/index.d.ts.map +1 -1
- package/lib/typescript/module/rating/types.d.ts +31 -0
- package/lib/typescript/module/rating/types.d.ts.map +1 -1
- package/lib/typescript/module/stay-search/DestinationSuggestions.d.ts +8 -0
- package/lib/typescript/module/stay-search/DestinationSuggestions.d.ts.map +1 -1
- package/lib/typescript/module/stay-search/GuestPicker.d.ts +6 -1
- package/lib/typescript/module/stay-search/GuestPicker.d.ts.map +1 -1
- package/lib/typescript/module/stay-search/types.d.ts +20 -0
- package/lib/typescript/module/stay-search/types.d.ts.map +1 -1
- package/lib/typescript/module/track-list/parts.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/app-shell/AppShell.tsx +91 -4
- package/src/app-shell/layout.ts +10 -5
- package/src/app-shell/types.ts +12 -2
- package/src/content-panel/ContentPanel.tsx +8 -2
- package/src/content-panel/ContentPanel.web.tsx +39 -25
- package/src/content-panel/types.ts +50 -42
- package/src/date-picker/TimeField.tsx +162 -0
- package/src/date-picker/index.ts +6 -0
- package/src/date-picker/time.ts +158 -0
- package/src/date-picker/types.ts +52 -3
- package/src/index.ts +9 -2
- package/src/index.web.ts +9 -2
- package/src/listing-card/ListingCard.tsx +34 -1
- package/src/listing-card/WishlistCard.tsx +42 -6
- package/src/listing-card/shared.ts +22 -0
- package/src/listing-card/types.ts +37 -0
- package/src/message-bubble/MessageBubble.tsx +21 -1
- package/src/rating/RatingInput.tsx +214 -0
- package/src/rating/index.ts +9 -1
- package/src/rating/types.ts +33 -0
- package/src/stay-search/DestinationSuggestions.tsx +48 -9
- package/src/stay-search/GuestPicker.tsx +9 -0
- package/src/stay-search/types.ts +20 -0
- package/src/track-list/parts.tsx +1 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/stay-search/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5F,6FAA6F;AAC7F,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErD,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,sBAAsB,EAAE,MAAM,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC,0EAA0E;IAC1E,qBAAqB,EAAE,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,KAAK,IAAI,CAAC;IACnE,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACtC,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sFAAsF;IACtF,IAAI,CAAC,EAAE,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/stay-search/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../../../src/track-list/parts.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../../../src/track-list/parts.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AACvD,OAAO,EAAe,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAcvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEjE,qEAAqE;AACrE,UAAU,oBAAoB;IAC5B,IAAI,EAAE,kBAAkB,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iGAAiG;IACjG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,YAAY,CAAC,eAAe,CAAC,CAAC;IAChD,iBAAiB,CAAC,EAAE,QAAQ,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EAAE,IAAI,EACV,kBAAkB,EAClB,OAAO,EACP,QAAgB,EAChB,OAAO,EACP,WAAW,EACX,KAAU,EACV,MAAM,EACN,iBAAiB,EAAE,KAAK,EACxB,GAAG,IAAI,EACR,EAAE,oBAAoB,2CA6BtB;AAED,8EAA8E;AAC9E,eAAO,MAAM,UAAU;YAMb,MAAM;UACR,MAAM;YACJ,MAAM;aACL,OAAO;EAgChB,CAAC;AAEH,sHAAsH;AACtH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,MAAM,GACP,EAAE;IACD,KAAK,EAAE,KAAK,CAAC,aAAa,GAAG,WAAW,CAAC,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,2CAiCA"}
|
package/package.json
CHANGED
|
@@ -179,11 +179,15 @@ const AppShellComponent: React.FC<AppShellProps> = ({
|
|
|
179
179
|
*/
|
|
180
180
|
const drawerStyle = variant === 'dashboard' ? drawer : 'overlay';
|
|
181
181
|
const centred = variant === 'feed' || variant === 'focus';
|
|
182
|
+
const canvas = variant === 'canvas';
|
|
182
183
|
// `focus` is a single column by definition and `split` has its `info` pane
|
|
183
184
|
// instead, so neither takes an aside in EITHER position — beside or stacked.
|
|
184
185
|
const hasAside = aside != null && variant !== 'focus' && variant !== 'split';
|
|
185
186
|
const asideBeside = hasAside && width >= breakpointPx(asideFrom);
|
|
186
|
-
|
|
187
|
+
// A canvas has no scrolling column to stack an aside into — the screen IS the
|
|
188
|
+
// canvas — so below `asideFrom` the aside is dropped whatever `asideCollapse`
|
|
189
|
+
// says, rather than being rendered where nothing can reach it.
|
|
190
|
+
const asideStacked = hasAside && !asideBeside && asideCollapse === 'stack' && !canvas;
|
|
187
191
|
|
|
188
192
|
const reducedMotion = useReducedMotion();
|
|
189
193
|
const [open, setOpen] = useControllableState<boolean>({
|
|
@@ -451,6 +455,16 @@ const AppShellComponent: React.FC<AppShellProps> = ({
|
|
|
451
455
|
);
|
|
452
456
|
}
|
|
453
457
|
|
|
458
|
+
// A `panel` only FILLS when the shell was ASKED to bound it — `fixed` or
|
|
459
|
+
// `container`. With document scroll the page itself is the scroller and there
|
|
460
|
+
// is no height to fill, so the panel keeps growing with its content (and the
|
|
461
|
+
// frame is its own box, which is what stops it drifting under scroll).
|
|
462
|
+
//
|
|
463
|
+
// The test is the PROP, not the resolved mode: native resolves `document` to
|
|
464
|
+
// `container` because it has no document, and a page that asked for document
|
|
465
|
+
// scroll still wants its header to travel with the content there.
|
|
466
|
+
const panelFills = panel === true && scroll !== 'document' && mode !== 'document';
|
|
467
|
+
|
|
454
468
|
// ---- the page region, per variant ---------------------------------------
|
|
455
469
|
/** `feed` / `focus`: a fixed reading column, centred in what the nav leaves. */
|
|
456
470
|
const centredBody = (
|
|
@@ -480,6 +494,33 @@ const AppShellComponent: React.FC<AppShellProps> = ({
|
|
|
480
494
|
doc ? null : { alignSelf: 'stretch' },
|
|
481
495
|
]}
|
|
482
496
|
>
|
|
497
|
+
{panelFills ? (
|
|
498
|
+
// A panel in a BOUNDED shell is the height of the screen and scrolls
|
|
499
|
+
// its own content: that is what makes it read as a panel — it reaches
|
|
500
|
+
// the bottom and closes there, like the rail beside it — instead of
|
|
501
|
+
// an open-ended column whose bottom edge is somewhere past the fold.
|
|
502
|
+
// The header is pinned inside it and only the routed content moves.
|
|
503
|
+
<ContentPanel
|
|
504
|
+
framedFrom={framedFrom}
|
|
505
|
+
fill
|
|
506
|
+
// The panel's box already IS the visible area here, so the frame is
|
|
507
|
+
// that box — no viewport maths, nothing to line up.
|
|
508
|
+
overlaySizing="panel"
|
|
509
|
+
surfaceStyle={{ flexGrow: 1, flexShrink: 1, flexBasis: 'auto', minHeight: 0 }}
|
|
510
|
+
contentStyle={{ flexGrow: 1, flexShrink: 1, flexBasis: 'auto', minHeight: 0 }}
|
|
511
|
+
>
|
|
512
|
+
<View style={{ flex: 1, minHeight: 0, padding: gutter, gap: 16 }}>
|
|
513
|
+
{headerNode}
|
|
514
|
+
<ScrollView
|
|
515
|
+
testID={testID ? `${testID}-page` : undefined}
|
|
516
|
+
style={{ flex: 1, minHeight: 0 }}
|
|
517
|
+
contentContainerStyle={{ gap: 16, paddingBottom: contentReserve }}
|
|
518
|
+
>
|
|
519
|
+
{children}
|
|
520
|
+
</ScrollView>
|
|
521
|
+
</View>
|
|
522
|
+
</ContentPanel>
|
|
523
|
+
) : (
|
|
483
524
|
<Scroller
|
|
484
525
|
mode={mode}
|
|
485
526
|
testID={testID ? `${testID}-page` : undefined}
|
|
@@ -489,6 +530,11 @@ const AppShellComponent: React.FC<AppShellProps> = ({
|
|
|
489
530
|
{panel ? (
|
|
490
531
|
<ContentPanel
|
|
491
532
|
framedFrom={framedFrom}
|
|
533
|
+
// The sticky frame is pinned at the shell's OWN gutter, which is
|
|
534
|
+
// exactly where the panel starts. Left at the 8px default it
|
|
535
|
+
// would sit 8px above the panel's real top edge and snap down on
|
|
536
|
+
// the first scroll — the panel appearing to breathe.
|
|
537
|
+
overlayInset={gutter}
|
|
492
538
|
// The panel's own `flex-1` (basis 0) would collapse to nothing in
|
|
493
539
|
// a document-flow column, which has no free space to distribute.
|
|
494
540
|
surfaceStyle={{ flexGrow: 1, flexShrink: 1, flexBasis: 'auto' }}
|
|
@@ -515,6 +561,7 @@ const AppShellComponent: React.FC<AppShellProps> = ({
|
|
|
515
561
|
)}
|
|
516
562
|
{asideStacked ? <View testID={testID ? `${testID}-aside` : undefined}>{aside}</View> : null}
|
|
517
563
|
</Scroller>
|
|
564
|
+
)}
|
|
518
565
|
</View>
|
|
519
566
|
{asideColumn({})}
|
|
520
567
|
</View>
|
|
@@ -574,7 +621,40 @@ const AppShellComponent: React.FC<AppShellProps> = ({
|
|
|
574
621
|
</>
|
|
575
622
|
);
|
|
576
623
|
|
|
577
|
-
|
|
624
|
+
/**
|
|
625
|
+
* `canvas`: the content IS the screen. One area, edge to edge — no reading
|
|
626
|
+
* column, no max width, no padding — with the header (if any) above it in
|
|
627
|
+
* flow, because a toolbar over a map belongs to the map. The `topBar`,
|
|
628
|
+
* `bottomBar`, `floatingAction` and `overlay` slots float over it as they do
|
|
629
|
+
* everywhere else, which is how a canvas gets its chrome without the canvas
|
|
630
|
+
* giving up its area.
|
|
631
|
+
*
|
|
632
|
+
* The shell's own padding moves OUT of the row and onto the regions here
|
|
633
|
+
* (below), so the nav is still a card with a gutter around it while the
|
|
634
|
+
* canvas runs to the window's edge. No negative margins: each region states
|
|
635
|
+
* its own inset.
|
|
636
|
+
*/
|
|
637
|
+
const canvasBody = (
|
|
638
|
+
<>
|
|
639
|
+
<View
|
|
640
|
+
testID={testID ? `${testID}-page` : undefined}
|
|
641
|
+
style={{ flex: 1, minWidth: 0, minHeight: 0, backgroundColor: background }}
|
|
642
|
+
>
|
|
643
|
+
{headerNode}
|
|
644
|
+
<View style={{ flex: 1, minHeight: 0, minWidth: 0 }}>{children}</View>
|
|
645
|
+
</View>
|
|
646
|
+
{asideColumn(canvas ? { padding: gutter, paddingLeft: 0 } : {})}
|
|
647
|
+
</>
|
|
648
|
+
);
|
|
649
|
+
|
|
650
|
+
const body =
|
|
651
|
+
variant === 'split'
|
|
652
|
+
? splitBody
|
|
653
|
+
: canvas
|
|
654
|
+
? canvasBody
|
|
655
|
+
: centred
|
|
656
|
+
? centredBody
|
|
657
|
+
: dashboardBody;
|
|
578
658
|
|
|
579
659
|
// A DOCKED nav is flush to the window: it takes the shell's whole height and
|
|
580
660
|
// its own hairline is the separator, so the shell gives up its left and
|
|
@@ -586,6 +666,11 @@ const AppShellComponent: React.FC<AppShellProps> = ({
|
|
|
586
666
|
<View style={stickyRail(dockedNav ? 0 : gutter)}>
|
|
587
667
|
<Sidebar {...flowSidebar} />
|
|
588
668
|
</View>
|
|
669
|
+
) : canvas && !dockedNav ? (
|
|
670
|
+
// The canvas row has no padding of its own, so the nav states its.
|
|
671
|
+
<View style={{ padding: gutter, paddingRight: 0, flexShrink: 0 }}>
|
|
672
|
+
<Sidebar {...flowSidebar} />
|
|
673
|
+
</View>
|
|
589
674
|
) : (
|
|
590
675
|
<Sidebar {...flowSidebar} />
|
|
591
676
|
)
|
|
@@ -615,8 +700,10 @@ const AppShellComponent: React.FC<AppShellProps> = ({
|
|
|
615
700
|
|
|
616
701
|
const rowStyle: WebCssStyle = {
|
|
617
702
|
flexDirection: 'row',
|
|
618
|
-
gap: dockedNav ? 0 : columnGap,
|
|
619
|
-
padding
|
|
703
|
+
gap: dockedNav || canvas ? 0 : columnGap,
|
|
704
|
+
// A canvas runs to the window's edge, so the row keeps no padding at all
|
|
705
|
+
// and each region carries its own (the nav below, the aside in `canvasBody`).
|
|
706
|
+
padding: canvas ? 0 : gutter,
|
|
620
707
|
...(dockedNav ? { paddingLeft: 0, paddingTop: 0, paddingBottom: 0 } : null),
|
|
621
708
|
backgroundColor: background,
|
|
622
709
|
};
|
package/src/app-shell/layout.ts
CHANGED
|
@@ -19,13 +19,18 @@ export type ScrollMode = 'document' | 'container' | 'fixed';
|
|
|
19
19
|
* Which frame a shell actually gets.
|
|
20
20
|
*
|
|
21
21
|
* Native has no document, so `document` falls back to `container` there.
|
|
22
|
-
* `split`
|
|
23
|
-
* only expressible inside a bounded box
|
|
24
|
-
* one pane growing the page and the others pinned to
|
|
25
|
-
*
|
|
22
|
+
* `split` and `canvas` are the other reductions: a split's panes each own their
|
|
23
|
+
* scrolling, which is only expressible inside a bounded box (a document-
|
|
24
|
+
* scrolling split would have one pane growing the page and the others pinned to
|
|
25
|
+
* nothing), and a canvas is the viewport itself. Both resolve `document` to
|
|
26
|
+
* `fixed` (one screen) and honour `container` as-is.
|
|
26
27
|
*/
|
|
27
28
|
export function resolveScrollMode(variant: AppShellVariant, scroll: AppShellScroll): ScrollMode {
|
|
28
|
-
|
|
29
|
+
// `split` and `canvas` are the two shapes that cannot grow a document: a
|
|
30
|
+
// split's panes each own their scrolling, and a canvas IS the viewport (a map
|
|
31
|
+
// that grew the page would pan the page instead of the map). Both honour
|
|
32
|
+
// `container` for a shell embedded in a bounded box.
|
|
33
|
+
if (variant === 'split' || variant === 'canvas') return scroll === 'container' ? 'container' : 'fixed';
|
|
29
34
|
if (scroll === 'document' && Platform.OS !== 'web') return 'container';
|
|
30
35
|
return scroll;
|
|
31
36
|
}
|
package/src/app-shell/types.ts
CHANGED
|
@@ -32,8 +32,14 @@ export type AppShellDrawer = 'overlay' | 'reveal';
|
|
|
32
32
|
* - `focus` — a single centred column of `contentWidth` and NO nav: sign-in,
|
|
33
33
|
* onboarding, a reader. It keeps the header, `topBar`, `bottomBar` and
|
|
34
34
|
* `floatingAction` slots, so a sign-up flow still gets its footer CTA.
|
|
35
|
+
* - `canvas` — the content is the SCREEN: one edge-to-edge area with no reading
|
|
36
|
+
* column, no max width and no padding, exactly one viewport tall, and the
|
|
37
|
+
* chrome floats over it. A map, a board, an editor, a photo viewer. Each
|
|
38
|
+
* region keeps its own inset (the nav is still a card with a gutter around
|
|
39
|
+
* it) so only the canvas runs to the edge. Like `split`, it never scrolls the
|
|
40
|
+
* document — the canvas owns its own panning and zooming.
|
|
35
41
|
*/
|
|
36
|
-
export type AppShellVariant = 'dashboard' | 'feed' | 'split' | 'focus';
|
|
42
|
+
export type AppShellVariant = 'dashboard' | 'feed' | 'split' | 'focus' | 'canvas';
|
|
37
43
|
|
|
38
44
|
/** Which single pane a `split` shell shows below `splitFrom`. */
|
|
39
45
|
export type AppShellPane = 'list' | 'detail' | 'info';
|
|
@@ -108,7 +114,11 @@ export interface AppShellProps {
|
|
|
108
114
|
asideWidth?: number;
|
|
109
115
|
/** The breakpoint the aside sits beside the content from. Defaults to `xl` (1280). */
|
|
110
116
|
asideFrom?: AppShellBreakpoint;
|
|
111
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* Below `asideFrom`: `stack` (default) renders it after the content, `hidden`
|
|
119
|
+
* drops it. `canvas` always drops it — the screen is the canvas, so there is
|
|
120
|
+
* no column underneath to stack into.
|
|
121
|
+
*/
|
|
112
122
|
asideCollapse?: 'stack' | 'hidden';
|
|
113
123
|
children?: ReactNode;
|
|
114
124
|
/** The content column's max width. Defaults to 1300. */
|
|
@@ -71,6 +71,7 @@ const ContentPanelComponent: React.FC<ContentPanelProps> = ({
|
|
|
71
71
|
children,
|
|
72
72
|
framed,
|
|
73
73
|
framedFrom = 768,
|
|
74
|
+
fill = false,
|
|
74
75
|
surfaceClassName,
|
|
75
76
|
surfaceStyle,
|
|
76
77
|
surfaceColor,
|
|
@@ -97,7 +98,7 @@ const ContentPanelComponent: React.FC<ContentPanelProps> = ({
|
|
|
97
98
|
: framed
|
|
98
99
|
? 'flex-1 overflow-hidden rounded-radius-28 border border-border'
|
|
99
100
|
: 'flex-1';
|
|
100
|
-
const surfaceClass = [surfaceBase, surfaceClassName ?? 'bg-card'].join(' ');
|
|
101
|
+
const surfaceClass = [surfaceBase, fill ? 'min-h-0' : '', surfaceClassName ?? 'bg-card'].filter(Boolean).join(' ');
|
|
101
102
|
// Native has no overlays: the surface itself carries the edge. `none` drops
|
|
102
103
|
// both, `border` keeps the class-drawn hairline, `elevated` adds the lift.
|
|
103
104
|
const chromeStyle =
|
|
@@ -106,7 +107,12 @@ const ContentPanelComponent: React.FC<ContentPanelProps> = ({
|
|
|
106
107
|
: shadow || panelChrome
|
|
107
108
|
? { boxShadow: shadow ?? panelChrome?.shadow }
|
|
108
109
|
: null;
|
|
109
|
-
|
|
110
|
+
// `fill` is the panel's own height contract, and on native it is already
|
|
111
|
+
// met: both boxes are `flex: 1`, so in a bounded parent the panel reaches the
|
|
112
|
+
// bottom and a list inside it scrolls within it. What the prop adds here is
|
|
113
|
+
// `min-h-0`, so a tall child cannot push the panel past the box it was given
|
|
114
|
+
// — the same automatic-minimum-size trap as on web.
|
|
115
|
+
const contentClass = ['flex-1', fill ? 'min-h-0' : '', contentClassName].filter(Boolean).join(' ');
|
|
110
116
|
|
|
111
117
|
return (
|
|
112
118
|
<ContentPanelNestingContext.Provider value={true}>
|
|
@@ -148,6 +148,7 @@ const ContentPanelComponent: React.FC<ContentPanelProps> = ({
|
|
|
148
148
|
children,
|
|
149
149
|
framed,
|
|
150
150
|
framedFrom = 768,
|
|
151
|
+
fill = false,
|
|
151
152
|
surfaceClassName,
|
|
152
153
|
surfaceStyle,
|
|
153
154
|
surfaceColor,
|
|
@@ -157,8 +158,8 @@ const ContentPanelComponent: React.FC<ContentPanelProps> = ({
|
|
|
157
158
|
chrome = 'elevated',
|
|
158
159
|
shadow,
|
|
159
160
|
maskColor,
|
|
160
|
-
overlaySizing = '
|
|
161
|
-
|
|
161
|
+
overlaySizing = 'viewport',
|
|
162
|
+
overlayInset,
|
|
162
163
|
}) => {
|
|
163
164
|
// Dev-only invariant — must run unconditionally (before deriving any
|
|
164
165
|
// mode-specific branch) so the hook order stays stable (rules of hooks).
|
|
@@ -194,6 +195,15 @@ const ContentPanelComponent: React.FC<ContentPanelProps> = ({
|
|
|
194
195
|
: framed
|
|
195
196
|
? 'flex-1 rounded-radius-28 web:overflow-x-clip'
|
|
196
197
|
: 'flex-1';
|
|
198
|
+
// `fill`: the panel takes the height its parent gives it and the CONTENT
|
|
199
|
+
// scrolls inside. `min-h-0` on both boxes is the whole trick — a flex child's
|
|
200
|
+
// automatic minimum size is its content, so without it the panel grows past
|
|
201
|
+
// the box it was told to fit and the scroller never gets a height to scroll
|
|
202
|
+
// against. The overflow goes on the content wrapper, never the surface: the
|
|
203
|
+
// surface is what the frame and the mask are drawn to, and a scrolling
|
|
204
|
+
// surface would scroll the edge with it.
|
|
205
|
+
const fillSurface = fill ? 'min-h-0' : '';
|
|
206
|
+
const fillContent = fill ? 'min-h-0 web:[overflow-y:auto]' : '';
|
|
197
207
|
// `overlaySizing="panel"`: the surface becomes a single-cell CSS Grid so the
|
|
198
208
|
// overlays and the content wrapper below can all be placed in that ONE cell
|
|
199
209
|
// (`web:[grid-area:1/1]`) and each fill it exactly — `minmax(0,1fr)` (not
|
|
@@ -204,32 +214,36 @@ const ContentPanelComponent: React.FC<ContentPanelProps> = ({
|
|
|
204
214
|
const gridStackClass = boundToPanel
|
|
205
215
|
? 'web:grid web:[grid-template-columns:minmax(0,1fr)] web:[grid-template-rows:minmax(0,1fr)]'
|
|
206
216
|
: '';
|
|
207
|
-
const surfaceClass = [surfaceBase, gridStackClass, surfaceClassName ?? 'bg-card'].filter(Boolean).join(' ');
|
|
208
|
-
const contentClass = [contentBase, boundToPanel ? 'web:[grid-area:1/1]' : '', contentClassName]
|
|
217
|
+
const surfaceClass = [surfaceBase, fillSurface, gridStackClass, surfaceClassName ?? 'bg-card'].filter(Boolean).join(' ');
|
|
218
|
+
const contentClass = [contentBase, fillContent, boundToPanel ? 'web:[grid-area:1/1]' : '', contentClassName]
|
|
209
219
|
.filter(Boolean)
|
|
210
220
|
.join(' ');
|
|
211
221
|
|
|
212
|
-
//
|
|
213
|
-
//
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
//
|
|
219
|
-
// has no such constraint.
|
|
220
|
-
// panel
|
|
221
|
-
//
|
|
222
|
+
// The viewport-mode overlays are sized and positioned from literal Tailwind
|
|
223
|
+
// classes (`top-2`, `h-[calc(100dvh-16px)]`, the matching negative
|
|
224
|
+
// `margin-bottom`) because those values are constants known at build time.
|
|
225
|
+
// An INSET is a runtime number — a shell's gutter, a measured header — which
|
|
226
|
+
// a Tailwind arbitrary class cannot express (content-scanning needs the
|
|
227
|
+
// literal string in source, not a value computed later), so a non-default
|
|
228
|
+
// inset shifts the same three properties through inline `style` instead,
|
|
229
|
+
// which has no such constraint. The default (8/8) leaves the classes standing
|
|
230
|
+
// alone, and `panel` mode ignores the inset entirely — that mode already
|
|
231
|
+
// starts at the panel's own box.
|
|
232
|
+
//
|
|
222
233
|
// RN's `ViewStyle.height`/`marginBottom` types only accept a number or a
|
|
223
|
-
// `${number}%` string
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
//
|
|
227
|
-
|
|
228
|
-
const
|
|
234
|
+
// `${number}%` string, not an arbitrary CSS `calc()`, because most of that
|
|
235
|
+
// type is shared with native where `calc()` does not exist. This file is
|
|
236
|
+
// web-only, where it is a real value react-native-web passes straight
|
|
237
|
+
// through.
|
|
238
|
+
const insetTop = typeof overlayInset === 'number' ? overlayInset : (overlayInset?.top ?? PANEL_TOP_INSET);
|
|
239
|
+
const insetBottom =
|
|
240
|
+
typeof overlayInset === 'number' ? overlayInset : (overlayInset?.bottom ?? PANEL_BOTTOM_INSET);
|
|
241
|
+
const customInset = insetTop !== PANEL_TOP_INSET || insetBottom !== PANEL_BOTTOM_INSET;
|
|
242
|
+
const insetStyle = !boundToPanel && customInset
|
|
229
243
|
? ({
|
|
230
|
-
top:
|
|
231
|
-
height: `calc(100dvh - ${
|
|
232
|
-
marginBottom: `calc(-100dvh + ${
|
|
244
|
+
top: insetTop,
|
|
245
|
+
height: `calc(100dvh - ${insetTop + insetBottom}px)`,
|
|
246
|
+
marginBottom: `calc(-100dvh + ${insetTop + insetBottom}px)`,
|
|
233
247
|
} as unknown as ViewStyle)
|
|
234
248
|
: undefined;
|
|
235
249
|
|
|
@@ -261,7 +275,7 @@ const ContentPanelComponent: React.FC<ContentPanelProps> = ({
|
|
|
261
275
|
? `web:sticky web:top-2 z-30 h-[calc(100dvh-16px)] w-full rounded-radius-28 ${bp.overlayHidden} web:[margin-bottom:calc(-100dvh+16px)] web:[clip-path:inset(-12px)]`
|
|
262
276
|
: 'web:sticky web:top-2 z-30 h-[calc(100dvh-16px)] w-full rounded-radius-28 web:[margin-bottom:calc(-100dvh+16px)] web:[clip-path:inset(-12px)]'
|
|
263
277
|
}
|
|
264
|
-
style={{ ...
|
|
278
|
+
style={{ ...insetStyle, boxShadow: `0 0 0 ${GUTTER_MASK_SPREAD}px ${maskColor ?? colors.background}` }}
|
|
265
279
|
/>
|
|
266
280
|
)}
|
|
267
281
|
{/* (2) Border-frame overlay — one continuous rounded border, above all.
|
|
@@ -274,7 +288,7 @@ const ContentPanelComponent: React.FC<ContentPanelProps> = ({
|
|
|
274
288
|
// The shadow rides the SAME element as the hairline, so the lift and
|
|
275
289
|
// the edge can never disagree about where the panel ends. It paints
|
|
276
290
|
// outward, into the gutter the page background shows.
|
|
277
|
-
style={[
|
|
291
|
+
style={[insetStyle, chrome === 'elevated' && (shadow || panelChrome)
|
|
278
292
|
? { boxShadow: shadow ?? panelChrome?.shadow }
|
|
279
293
|
: null]}
|
|
280
294
|
className={
|
|
@@ -52,6 +52,28 @@ export interface ContentPanelProps {
|
|
|
52
52
|
* For an app that wants its own elevation without giving up the hairline.
|
|
53
53
|
*/
|
|
54
54
|
shadow?: string;
|
|
55
|
+
/**
|
|
56
|
+
* The panel is the HEIGHT OF THE SPACE IT IS GIVEN, and its content scrolls
|
|
57
|
+
* inside it — instead of the panel growing with its content while the page
|
|
58
|
+
* scrolls underneath.
|
|
59
|
+
*
|
|
60
|
+
* This is what makes a framed column read as a panel: it reaches the bottom
|
|
61
|
+
* of the screen and closes there, the way the rail beside it does. Without
|
|
62
|
+
* it, a feed taller than the window gives a panel whose top edge you see and
|
|
63
|
+
* whose bottom edge is somewhere past the fold — an open-ended column, not a
|
|
64
|
+
* surface.
|
|
65
|
+
*
|
|
66
|
+
* It needs a parent that BOUNDS it (a flex column with a real height): an
|
|
67
|
+
* `AppShell` with `scroll="fixed"` or `scroll="container"`, or any screen
|
|
68
|
+
* that is `flex: 1`. In a document-scrolled page there is no height to fill
|
|
69
|
+
* and the panel keeps growing with its content — that page wants
|
|
70
|
+
* `scroll="document"`, not this prop.
|
|
71
|
+
*
|
|
72
|
+
* On web the content wrapper becomes the scroller. On native the panel and
|
|
73
|
+
* its content are already `flex: 1`, so a `FlatList`/`ScrollView` inside
|
|
74
|
+
* fills the panel and scrolls within it.
|
|
75
|
+
*/
|
|
76
|
+
fill?: boolean;
|
|
55
77
|
/** Override the surface background utility (defaults to `bg-card`). */
|
|
56
78
|
surfaceClassName?: string;
|
|
57
79
|
surfaceStyle?: StyleProp<ViewStyle>;
|
|
@@ -89,52 +111,38 @@ export interface ContentPanelProps {
|
|
|
89
111
|
*/
|
|
90
112
|
maskColor?: string;
|
|
91
113
|
/**
|
|
92
|
-
* How the WEB overlays (bleed-mask
|
|
93
|
-
* native (there are no overlays to size).
|
|
94
|
-
* - `'viewport'` (DEFAULT) — sized to the dynamic viewport height (`100dvh`)
|
|
95
|
-
* and `position: sticky`-pinned, so they read as a constant frame around
|
|
96
|
-
* the visible slice of a panel whose own DOM height can exceed one screen
|
|
97
|
-
* — the document-scroll case (e.g. a feed whose page grows with content).
|
|
98
|
-
* Requires the panel to sit in a document that actually scrolls; see
|
|
99
|
-
* `ContentPanel.web.tsx`'s doc comment.
|
|
100
|
-
* - `'panel'` — sized to the panel's own real box via CSS Grid layer-
|
|
101
|
-
* stacking (the overlays and the content wrapper all occupy the same
|
|
102
|
-
* grid cell) instead of viewport math. The right mode for a consumer
|
|
103
|
-
* whose own shell already bounds the panel's height (no document
|
|
104
|
-
* scroll — a fixed app shell with its own internal scroll containers),
|
|
105
|
-
* where anything the consumer places outside the panel (e.g. a header
|
|
106
|
-
* above it) must never be overlapped by an overlay sized to the whole
|
|
107
|
-
* viewport.
|
|
108
|
-
*/
|
|
109
|
-
/**
|
|
110
|
-
* DEFAULT `'panel'`. The edge describes the panel's OWN box, so it scrolls
|
|
111
|
-
* with the content like any other border: on a page taller than the screen
|
|
112
|
-
* you see the two side edges while scrolling and the rounded corners at the
|
|
113
|
-
* ends, which is what a long framed column looks like.
|
|
114
|
+
* How the WEB overlays (the bleed-mask and the border frame) size themselves.
|
|
115
|
+
* No-op on native (there are no overlays to size).
|
|
114
116
|
*
|
|
115
|
-
* `'viewport'`
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
117
|
+
* - `'viewport'` (DEFAULT) — the frame is a SCREEN-TALL sticky rectangle:
|
|
118
|
+
* `100dvh` minus the insets, pinned at `overlayInset`. The panel's own box
|
|
119
|
+
* grows with its content and the document scrolls it, while the edge stays
|
|
120
|
+
* where the screen is — so the panel reads as a surface that occupies the
|
|
121
|
+
* window from top to bottom and the content moves inside it. This is the
|
|
122
|
+
* mode for a page that scrolls the document.
|
|
123
|
+
* - `'panel'` — the overlays are the panel's OWN box, through CSS Grid
|
|
124
|
+
* layer-stacking (the overlays and the content wrapper share one grid
|
|
125
|
+
* cell). The right mode when the panel's box already IS the visible area
|
|
126
|
+
* (`fill`, inside a shell that bounds it) or when something the consumer
|
|
127
|
+
* placed outside the panel — a header above it — must never be painted
|
|
128
|
+
* over by an overlay sized to the whole viewport.
|
|
121
129
|
*/
|
|
122
130
|
overlaySizing?: 'viewport' | 'panel';
|
|
123
131
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
132
|
+
* The gap between the VIEWPORT's edge and the sticky frame, in `'viewport'`
|
|
133
|
+
* mode. Default 8.
|
|
134
|
+
*
|
|
135
|
+
* **It must equal the distance from the top of the screen to the panel's own
|
|
136
|
+
* top edge.** Sticky positioning leaves an element at its static position
|
|
137
|
+
* until scrolling would push it past the inset — so a panel that starts 16px
|
|
138
|
+
* down the page with an 8px inset draws its frame at 16, then SNAPS it to 8
|
|
139
|
+
* on the first scroll. That 8px jump is the whole bug, and it reads as the
|
|
140
|
+
* panel breathing. A shell passes its own gutter here.
|
|
129
141
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* where the panel visually starts without moving the panel's own DOM
|
|
135
|
-
* position, so the overlays would still read from viewport 0 and paint
|
|
136
|
-
* over that chrome. This shifts their `top` down and shrinks their height
|
|
137
|
-
* by the same amount, so they begin exactly where the panel visually does.
|
|
142
|
+
* Takes a pair when the top and the bottom differ — persistent chrome above
|
|
143
|
+
* the panel (a sticky header the consumer keeps outside it) shifts where the
|
|
144
|
+
* panel visually starts without moving its DOM position, so the frame has to
|
|
145
|
+
* start lower without also ending higher.
|
|
138
146
|
*/
|
|
139
|
-
|
|
147
|
+
overlayInset?: number | { top: number; bottom: number };
|
|
140
148
|
}
|