@capgo/capacitor-sheets 8.0.2

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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +437 -0
  3. package/dist/angular/index.d.mts +114 -0
  4. package/dist/angular/index.d.ts +114 -0
  5. package/dist/angular/index.js +1890 -0
  6. package/dist/angular/index.js.map +1 -0
  7. package/dist/angular/index.mjs +1863 -0
  8. package/dist/angular/index.mjs.map +1 -0
  9. package/dist/chunk-LAUTMWR7.mjs +261 -0
  10. package/dist/chunk-LAUTMWR7.mjs.map +1 -0
  11. package/dist/chunk-YBLI7KN6.mjs +1629 -0
  12. package/dist/chunk-YBLI7KN6.mjs.map +1 -0
  13. package/dist/components-4JACDCD4.mjs +48 -0
  14. package/dist/components-4JACDCD4.mjs.map +1 -0
  15. package/dist/index.d.mts +513 -0
  16. package/dist/index.d.ts +513 -0
  17. package/dist/index.js +2069 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/index.mjs +70 -0
  20. package/dist/index.mjs.map +1 -0
  21. package/dist/react/index.d.mts +240 -0
  22. package/dist/react/index.d.ts +240 -0
  23. package/dist/react/index.js +1900 -0
  24. package/dist/react/index.js.map +1 -0
  25. package/dist/react/index.mjs +1871 -0
  26. package/dist/react/index.mjs.map +1 -0
  27. package/dist/solid/index.d.mts +114 -0
  28. package/dist/solid/index.d.ts +114 -0
  29. package/dist/solid/index.js +1890 -0
  30. package/dist/solid/index.js.map +1 -0
  31. package/dist/solid/index.mjs +1863 -0
  32. package/dist/solid/index.mjs.map +1 -0
  33. package/dist/styles-ZKNWSPZR.mjs +9 -0
  34. package/dist/styles-ZKNWSPZR.mjs.map +1 -0
  35. package/dist/svelte/index.d.mts +121 -0
  36. package/dist/svelte/index.d.ts +121 -0
  37. package/dist/svelte/index.js +1904 -0
  38. package/dist/svelte/index.js.map +1 -0
  39. package/dist/svelte/index.mjs +1876 -0
  40. package/dist/svelte/index.mjs.map +1 -0
  41. package/dist/vue/index.d.mts +114 -0
  42. package/dist/vue/index.d.ts +114 -0
  43. package/dist/vue/index.js +1890 -0
  44. package/dist/vue/index.js.map +1 -0
  45. package/dist/vue/index.mjs +1863 -0
  46. package/dist/vue/index.mjs.map +1 -0
  47. package/docs/demos/bottom-sheet.webp +0 -0
  48. package/docs/demos/card.webp +0 -0
  49. package/docs/demos/detached-sheet.webp +0 -0
  50. package/docs/demos/lightbox.webp +0 -0
  51. package/docs/demos/long-sheet.webp +0 -0
  52. package/docs/demos/page-from-bottom.webp +0 -0
  53. package/docs/demos/page.webp +0 -0
  54. package/docs/demos/parallax-page.webp +0 -0
  55. package/docs/demos/persistent-sheet-with-detent.webp +0 -0
  56. package/docs/demos/sheet-with-depth.webp +0 -0
  57. package/docs/demos/sheet-with-detent.webp +0 -0
  58. package/docs/demos/sheet-with-keyboard.webp +0 -0
  59. package/docs/demos/sheet-with-stacking.webp +0 -0
  60. package/docs/demos/sidebar.webp +0 -0
  61. package/docs/demos/toast.webp +0 -0
  62. package/docs/demos/top-sheet.webp +0 -0
  63. package/package.json +162 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Capgo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,437 @@
1
+ # @capgo/capacitor-sheets
2
+
3
+ <a href="https://capgo.app/">
4
+ <img
5
+ src="https://capgo.app/readme-banner.svg?repo=Cap-go/capacitor-sheets"
6
+ alt="Capgo - Instant updates for Capacitor"
7
+ />
8
+ </a>
9
+
10
+ Framework-agnostic sheets, drawers, dialogs, scroll helpers, and overlay primitives for Capacitor apps.
11
+
12
+ This package is inspired by the public Silk feature surface, but it is not a wrapper around Silk and does not include Silk source code. It uses platform web APIs and custom elements so the same primitives work in React, Vue, Angular, Svelte, Solid, or plain TypeScript.
13
+
14
+ ## Usecase Demos
15
+
16
+ Each usecase has its own animated WebP demo. These match the public Silk-style example set: long sheets, detents, sidebars, bottom/top sheets, keyboard-aware sheets, toasts, detached sheets, full pages, stacking, depth, parallax, lightboxes, persistent detents, and cards.
17
+
18
+ <table>
19
+ <tr>
20
+ <td>
21
+ <img src="./docs/demos/long-sheet.webp" alt="Long Sheet demo" />
22
+ <br />
23
+ <strong>Long Sheet</strong>
24
+ </td>
25
+ <td>
26
+ <img src="./docs/demos/sheet-with-detent.webp" alt="Sheet with Detent demo" />
27
+ <br />
28
+ <strong>Sheet with Detent</strong>
29
+ </td>
30
+ </tr>
31
+ <tr>
32
+ <td>
33
+ <img src="./docs/demos/sidebar.webp" alt="Sidebar demo" />
34
+ <br />
35
+ <strong>Sidebar</strong>
36
+ </td>
37
+ <td>
38
+ <img src="./docs/demos/bottom-sheet.webp" alt="Bottom Sheet demo" />
39
+ <br />
40
+ <strong>Bottom Sheet</strong>
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <td>
45
+ <img src="./docs/demos/sheet-with-keyboard.webp" alt="Sheet with Keyboard demo" />
46
+ <br />
47
+ <strong>Sheet with Keyboard</strong>
48
+ </td>
49
+ <td>
50
+ <img src="./docs/demos/toast.webp" alt="Toast demo" />
51
+ <br />
52
+ <strong>Toast</strong>
53
+ </td>
54
+ </tr>
55
+ <tr>
56
+ <td>
57
+ <img src="./docs/demos/detached-sheet.webp" alt="Detached Sheet demo" />
58
+ <br />
59
+ <strong>Detached Sheet</strong>
60
+ </td>
61
+ <td>
62
+ <img src="./docs/demos/page-from-bottom.webp" alt="Page from Bottom demo" />
63
+ <br />
64
+ <strong>Page from Bottom</strong>
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <td>
69
+ <img src="./docs/demos/top-sheet.webp" alt="Top Sheet demo" />
70
+ <br />
71
+ <strong>Top Sheet</strong>
72
+ </td>
73
+ <td>
74
+ <img src="./docs/demos/sheet-with-stacking.webp" alt="Sheet with Stacking demo" />
75
+ <br />
76
+ <strong>Sheet with Stacking</strong>
77
+ </td>
78
+ </tr>
79
+ <tr>
80
+ <td>
81
+ <img src="./docs/demos/sheet-with-depth.webp" alt="Sheet with Depth demo" />
82
+ <br />
83
+ <strong>Sheet with Depth</strong>
84
+ </td>
85
+ <td>
86
+ <img src="./docs/demos/parallax-page.webp" alt="Parallax Page demo" />
87
+ <br />
88
+ <strong>Parallax Page</strong>
89
+ </td>
90
+ </tr>
91
+ <tr>
92
+ <td>
93
+ <img src="./docs/demos/page.webp" alt="Page demo" />
94
+ <br />
95
+ <strong>Page</strong>
96
+ </td>
97
+ <td>
98
+ <img src="./docs/demos/lightbox.webp" alt="Lightbox demo" />
99
+ <br />
100
+ <strong>Lightbox</strong>
101
+ </td>
102
+ </tr>
103
+ <tr>
104
+ <td>
105
+ <img src="./docs/demos/persistent-sheet-with-detent.webp" alt="Persistent Sheet with Detent demo" />
106
+ <br />
107
+ <strong>Persistent Sheet with Detent</strong>
108
+ </td>
109
+ <td>
110
+ <img src="./docs/demos/card.webp" alt="Card demo" />
111
+ <br />
112
+ <strong>Card</strong>
113
+ </td>
114
+ </tr>
115
+ </table>
116
+
117
+ ## Online Playgrounds
118
+
119
+ Each framework example opens the same 16-usecase gallery, so StackBlitz is useful for testing the full surface instead of a single smoke-test sheet:
120
+
121
+ - [React playground](https://stackblitz.com/github/Cap-go/capacitor-sheets?file=examples/react-app/src/main.tsx&startScript=stackblitz-react)
122
+ - [Vue playground](https://stackblitz.com/github/Cap-go/capacitor-sheets?file=examples/vue-app/src/App.vue&startScript=stackblitz-vue)
123
+ - [Angular playground](https://stackblitz.com/github/Cap-go/capacitor-sheets?file=examples/angular-app/src/app/app.component.ts&startScript=stackblitz-angular)
124
+ - [Svelte playground](https://stackblitz.com/github/Cap-go/capacitor-sheets?file=examples/svelte-app/src/App.svelte&startScript=stackblitz-svelte)
125
+ - [Solid playground](https://stackblitz.com/github/Cap-go/capacitor-sheets?file=examples/solid-app/src/main.tsx&startScript=stackblitz-solid)
126
+
127
+ ## Features
128
+
129
+ - **Framework agnostic** custom elements: no React runtime dependency in the core package.
130
+ - **Bottom sheets, side drawers, top sheets, and centered dialogs** through `content-placement`.
131
+ - **Detents** with `em`, `rem`, `dvh`, `lvh`, `svh`, `calc()`, and other modern CSS lengths.
132
+ - **Touch, pointer, wheel, and trackpad gestures** with dismissal, overshoot, and trap controls.
133
+ - **Modal behavior**: focus trap, focus restore, Escape dismissal, outside-click dismissal, and inert outside content.
134
+ - **Capacitor safe-area defaults** using `env(safe-area-inset-*)` plus Capacitor SystemBars `--safe-area-inset-*` fallbacks.
135
+ - **Keyboard-aware layout** using `visualViewport` resize/scroll events and `preventScroll` focus behavior.
136
+ - **Overlay compatibility** through `cap-island` and `cap-external-overlay`.
137
+ - **Stacking and outlet animation hooks** for depth effects and coordinated page motion.
138
+ - **Scroll primitives** with progress/distance helpers.
139
+ - **Theme color dimming** for Capacitor WebViews and mobile browsers.
140
+ - **Modern CSS defaults** authored with `em`-based sizing, with no design-system lock-in.
141
+
142
+ ## Usecase Coverage
143
+
144
+ | Usecase | Capgo Sheets pattern |
145
+ | ---------------------------- | --------------------------------------------------------------------------------------------------------- |
146
+ | Long Sheet | `cap-sheet` + `cap-scroll` or naturally scrolling `cap-sheet-content` |
147
+ | Sheet with Detent | `detents="18em 32em"` and `stepTo()` / `cap-sheet-trigger action="step"` |
148
+ | Sidebar | `content-placement="left"` or `content-placement="right"` |
149
+ | Bottom Sheet | default `content-placement="bottom"` |
150
+ | Sheet with Keyboard | visual viewport offset support via `native-focus-scroll-prevention` |
151
+ | Toast | `inert-outside="false"`, `close-on-outside-click="false"`, `focus-trap="false"` |
152
+ | Detached Sheet | rounded content with margins and `cap-sheet-special-wrapper` composition |
153
+ | Page from Bottom | full-height bottom sheet content |
154
+ | Top Sheet | `content-placement="top"` |
155
+ | Sheet with Stacking | `cap-sheet-stack`, stack depth variables, and stacking animation hooks |
156
+ | Sheet with Depth | `cap-sheet-outlet` progress variables and `travelAnimation` |
157
+ | Parallax Page | `cap-sheet-outlet` + `cap-scroll` progress composition |
158
+ | Page | full-viewport sheet content or side-entering `content-placement` |
159
+ | Lightbox | `content-placement="center"` plus backdrop and media content |
160
+ | Persistent Sheet with Detent | `default-presented`, `swipe-dismissal="false"`, `inert-outside="false"`, `close-on-outside-click="false"` |
161
+ | Card | `content-placement="center"` with compact content |
162
+
163
+ ## Installation
164
+
165
+ ```bash
166
+ npm install @capgo/capacitor-sheets
167
+ npx cap sync
168
+ ```
169
+
170
+ ## Capacitor Setup
171
+
172
+ Add `viewport-fit=cover` so iOS exposes safe-area insets to CSS:
173
+
174
+ ```html
175
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
176
+ ```
177
+
178
+ Safe areas are enabled by default. `cap-sheet-view` reads standard `env(safe-area-inset-*)` values and Capacitor SystemBars fallback variables such as `--safe-area-inset-bottom`, then applies them to the sheet viewport in `em`-based layout. You can opt out or choose edges per sheet:
179
+
180
+ ```text
181
+ <cap-sheet safe-area="none"></cap-sheet>
182
+ <cap-sheet safe-area="bottom left right"></cap-sheet>
183
+ ```
184
+
185
+ For Capacitor apps with overlay status/system bars, keep the platform plugins responsible for exposing correct insets:
186
+
187
+ ```ts
188
+ import type { CapacitorConfig } from '@capacitor/cli';
189
+
190
+ const config: CapacitorConfig = {
191
+ plugins: {
192
+ StatusBar: {
193
+ overlaysWebView: true,
194
+ },
195
+ Keyboard: {
196
+ resize: 'body',
197
+ resizeOnFullScreen: true,
198
+ },
199
+ SystemBars: {
200
+ insetsHandling: 'css',
201
+ },
202
+ },
203
+ };
204
+
205
+ export default config;
206
+ ```
207
+
208
+ Keyboard handling is on by default through `native-focus-scroll-prevention`. It listens to `visualViewport` changes, keeps focused controls visible above the keyboard, and restores the sheet offset when the keyboard closes.
209
+
210
+ ## Vanilla Usage
211
+
212
+ ```html
213
+ <script type="module">
214
+ import '@capgo/capacitor-sheets';
215
+ </script>
216
+
217
+ <cap-sheet-trigger for="booking-sheet" action="present">Open</cap-sheet-trigger>
218
+
219
+ <cap-sheet id="booking-sheet" detents="18em 32em" content-placement="bottom">
220
+ <cap-sheet-portal>
221
+ <cap-sheet-view>
222
+ <cap-sheet-backdrop></cap-sheet-backdrop>
223
+ <cap-sheet-content class="sheet">
224
+ <cap-sheet-bleeding-background></cap-sheet-bleeding-background>
225
+ <cap-sheet-handle></cap-sheet-handle>
226
+ <cap-sheet-title>Evening route</cap-sheet-title>
227
+ <cap-sheet-description>Choose a route and confirm pickup.</cap-sheet-description>
228
+ <cap-sheet-trigger action="dismiss">Done</cap-sheet-trigger>
229
+ </cap-sheet-content>
230
+ </cap-sheet-view>
231
+ </cap-sheet-portal>
232
+ </cap-sheet>
233
+ ```
234
+
235
+ ```css
236
+ .sheet {
237
+ width: min(100%, 34em);
238
+ padding: 0 1.25em 1.25em;
239
+ }
240
+ ```
241
+
242
+ ## Five Framework Examples
243
+
244
+ Full runnable examples live in:
245
+
246
+ - `examples/react-app`
247
+ - `examples/vue-app`
248
+ - `examples/angular-app`
249
+ - `examples/svelte-app`
250
+ - `examples/solid-app`
251
+
252
+ All five apps mount the shared usecase gallery from `examples/shared/usecase-gallery.ts`. That gallery covers Long Sheet, Sheet with Detent, Sidebar, Bottom Sheet, Sheet with Keyboard, Toast, Detached Sheet, Page from Bottom, Top Sheet, Sheet with Stacking, Sheet with Depth, Parallax Page, Page, Lightbox, Persistent Sheet with Detent, and Card.
253
+
254
+ ### React
255
+
256
+ ```tsx
257
+ import { setupSheet } from '@capgo/capacitor-sheets/react';
258
+ import { useEffect, useRef } from 'react';
259
+ import '@capgo/capacitor-sheets';
260
+ import { mountUsecaseGallery } from '../../shared/usecase-gallery';
261
+
262
+ export function App() {
263
+ const galleryRef = useRef<HTMLDivElement>(null);
264
+
265
+ useEffect(() => {
266
+ if (!galleryRef.current) return;
267
+ return mountUsecaseGallery(galleryRef.current, {
268
+ framework: 'React',
269
+ setupSheet,
270
+ });
271
+ }, []);
272
+
273
+ return <div ref={galleryRef} />;
274
+ }
275
+ ```
276
+
277
+ ### Vue
278
+
279
+ ```vue
280
+ <script setup lang="ts">
281
+ import { onMounted, onUnmounted, ref } from 'vue';
282
+ import { setupSheet } from '@capgo/capacitor-sheets/vue';
283
+ import '@capgo/capacitor-sheets';
284
+ import { mountUsecaseGallery } from '../../shared/usecase-gallery';
285
+
286
+ const galleryRef = ref<HTMLElement | null>(null);
287
+ let cleanup: (() => void) | undefined;
288
+
289
+ onMounted(() => {
290
+ if (galleryRef.value) {
291
+ cleanup = mountUsecaseGallery(galleryRef.value, {
292
+ framework: 'Vue',
293
+ setupSheet,
294
+ });
295
+ }
296
+ });
297
+
298
+ onUnmounted(() => cleanup?.());
299
+ </script>
300
+
301
+ <template>
302
+ <div ref="galleryRef"></div>
303
+ </template>
304
+ ```
305
+
306
+ ### Angular
307
+
308
+ ```ts
309
+ import type { AfterViewInit, ElementRef, OnDestroy } from '@angular/core';
310
+ import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild } from '@angular/core';
311
+ import { setupSheet } from '@capgo/capacitor-sheets/angular';
312
+ import '@capgo/capacitor-sheets';
313
+ import { mountUsecaseGallery } from '../../../shared/usecase-gallery';
314
+
315
+ @Component({
316
+ selector: 'app-root',
317
+ standalone: true,
318
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
319
+ template: `<div #gallery></div>`,
320
+ })
321
+ export class AppComponent implements AfterViewInit, OnDestroy {
322
+ @ViewChild('gallery', { static: true }) gallery?: ElementRef<HTMLElement>;
323
+ private cleanup?: () => void;
324
+
325
+ ngAfterViewInit(): void {
326
+ if (this.gallery?.nativeElement) {
327
+ this.cleanup = mountUsecaseGallery(this.gallery.nativeElement, {
328
+ framework: 'Angular',
329
+ setupSheet,
330
+ });
331
+ }
332
+ }
333
+
334
+ ngOnDestroy(): void {
335
+ this.cleanup?.();
336
+ }
337
+ }
338
+ ```
339
+
340
+ ### Svelte
341
+
342
+ ```svelte
343
+ <script lang="ts">
344
+ import { onMount } from 'svelte'
345
+ import { setupSheet } from '@capgo/capacitor-sheets/svelte'
346
+ import '@capgo/capacitor-sheets'
347
+ import { mountUsecaseGallery } from '../../shared/usecase-gallery'
348
+
349
+ let gallery: HTMLDivElement
350
+
351
+ onMount(() =>
352
+ mountUsecaseGallery(gallery, {
353
+ framework: 'Svelte',
354
+ setupSheet,
355
+ }),
356
+ )
357
+ </script>
358
+
359
+ <div bind:this={gallery}></div>
360
+ ```
361
+
362
+ ### Solid
363
+
364
+ ```tsx
365
+ import { onCleanup, onMount } from 'solid-js';
366
+ import { setupSheet } from '@capgo/capacitor-sheets/solid';
367
+ import '@capgo/capacitor-sheets';
368
+ import { mountUsecaseGallery } from '../../shared/usecase-gallery';
369
+
370
+ export function App() {
371
+ let galleryEl!: HTMLDivElement;
372
+
373
+ onMount(() => {
374
+ const cleanup = mountUsecaseGallery(galleryEl, {
375
+ framework: 'Solid',
376
+ setupSheet,
377
+ });
378
+ onCleanup(cleanup);
379
+ });
380
+
381
+ return <div ref={galleryEl} />;
382
+ }
383
+ ```
384
+
385
+ ## API Surface
386
+
387
+ Core elements:
388
+
389
+ - `cap-sheet`: state, detents, placement, gestures, modal behavior, lifecycle events.
390
+ - `cap-sheet-trigger`: declarative present, dismiss, toggle, and step actions.
391
+ - `cap-sheet-portal`: optional body portal for overlay layering.
392
+ - `cap-sheet-view`: viewport overlay host.
393
+ - `cap-sheet-backdrop`: progress-synced modal backdrop.
394
+ - `cap-sheet-content`: accessible sheet surface.
395
+ - `cap-sheet-bleeding-background`: background extension for rounded edge sheets.
396
+ - `cap-sheet-handle`: draggable and keyboard-accessible detent handle.
397
+ - `cap-sheet-title` and `cap-sheet-description`: accessible naming.
398
+ - `cap-sheet-special-wrapper` and `cap-sheet-special-wrapper-content`: composition hooks for detached sheets, cards, lightboxes, and custom page layouts.
399
+ - `cap-sheet-stack`: groups sheets for stacked depth.
400
+ - `cap-sheet-outlet`: receives sheet progress variables and optional `travelAnimation`.
401
+ - `cap-scroll` and `cap-scroll-content`: scroll progress helpers.
402
+ - `cap-fixed`, `cap-island`, `cap-external-overlay`, `cap-visually-hidden`, `cap-auto-focus-target`: composition and accessibility helpers.
403
+
404
+ Important events:
405
+
406
+ - `cap-sheet-presented-change`
407
+ - `cap-sheet-active-detent-change`
408
+ - `cap-sheet-travel`
409
+ - `cap-sheet-travel-status-change`
410
+ - `cap-sheet-travel-range-change`
411
+ - `cap-sheet-drag-start`
412
+ - `cap-sheet-drag-end`
413
+ - `cap-scroll`
414
+
415
+ Imperative methods on `cap-sheet`:
416
+
417
+ ```ts
418
+ const sheet = document.querySelector('cap-sheet')!;
419
+ await sheet.present();
420
+ await sheet.dismiss();
421
+ await sheet.toggle();
422
+ await sheet.stepTo(2);
423
+ await sheet.step('down');
424
+ ```
425
+
426
+ The public TypeScript API is documented with TSDoc in `src/core/types.ts`, and generated declarations are emitted during `npm run build`.
427
+
428
+ ## Development
429
+
430
+ ```bash
431
+ npm install
432
+ npm run render:demos
433
+ npm run build
434
+ npm run dev:examples -- react vue svelte angular solid
435
+ ```
436
+
437
+ In the Capgo monorepo, use `bun` and `bunx` for local commands.
@@ -0,0 +1,114 @@
1
+ /** Placement of the sheet content inside the viewport. */
2
+ type SheetPlacement = 'top' | 'bottom' | 'left' | 'right' | 'center';
3
+ /** Swipe track used when the content can be dismissed from an edge. */
4
+ type SheetTrack = Exclude<SheetPlacement, 'center'>;
5
+ /** Viewport edges protected by safe-area insets. */
6
+ type SheetSafeAreaEdge = 'top' | 'bottom' | 'left' | 'right';
7
+ /** Safe-area behavior for Capacitor WebViews and mobile browsers. */
8
+ type SheetSafeAreaMode = boolean | 'auto' | 'none' | SheetSafeAreaEdge[];
9
+ /** Runtime travel state emitted by sheet lifecycle events. */
10
+ type SheetTravelStatus = 'idle' | 'entering' | 'exiting' | 'dragging' | 'settling';
11
+ /** Built-in animation presets tuned for mobile WebViews. */
12
+ type SheetAnimationPreset = 'gentle' | 'smooth' | 'snappy';
13
+ /** Easing string accepted by the Web Animations API. */
14
+ type SheetEasing = 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | string;
15
+ /** Animation options for programmatic present, dismiss, and detent steps. */
16
+ interface SheetAnimationSettings {
17
+ /** Named preset. Defaults to `smooth`. */
18
+ preset?: SheetAnimationPreset;
19
+ /** Duration in milliseconds. Ignored when `skip` is true. */
20
+ duration?: number;
21
+ /** CSS easing used by WAAPI. */
22
+ easing?: SheetEasing;
23
+ /** Skip the animation and snap to the final state. */
24
+ skip?: boolean | 'auto';
25
+ /** For dual-track sheets, select the track used by this programmatic movement. */
26
+ track?: SheetTrack;
27
+ /** Keep content fixed while related outlets/backdrops animate. */
28
+ contentMove?: boolean;
29
+ }
30
+ /** Options accepted by the `<cap-sheet>` custom element and setup helpers. */
31
+ interface SheetOptions {
32
+ /** Unique component id used by `for` attributes. */
33
+ componentId?: string;
34
+ /** Sheet stack id. Use the closest `<cap-sheet-stack>` when omitted. */
35
+ stack?: string;
36
+ /** Initial uncontrolled presentation state. */
37
+ defaultPresented?: boolean;
38
+ /** Controlled presentation state. */
39
+ presented?: boolean;
40
+ /** Initial detent index for uncontrolled sheets. */
41
+ defaultActiveDetent?: number;
42
+ /** Controlled detent index. */
43
+ activeDetent?: number;
44
+ /** Intermediate detents between dismissed `0` and fully presented `n`. */
45
+ detents?: string | string[];
46
+ /** WAI-ARIA role applied to `<cap-sheet-view>`. */
47
+ sheetRole?: 'dialog' | 'alertdialog' | 'status' | string;
48
+ /** Where content sits when fully presented. */
49
+ contentPlacement?: SheetPlacement;
50
+ /** Safe-area edges protected by the sheet viewport. Defaults to `auto`. */
51
+ safeArea?: SheetSafeAreaMode;
52
+ /** Edge tracks that can dismiss the sheet. */
53
+ tracks?: SheetTrack | SheetTrack[];
54
+ /** Enables pointer, touch, trackpad, and wheel travel gestures. */
55
+ swipe?: boolean;
56
+ /** Allows swiping to detent `0` and dismissing. */
57
+ swipeDismissal?: boolean;
58
+ /** Allows a soft overshoot past the end detents. */
59
+ swipeOvershoot?: boolean;
60
+ /** Prevents gestures from escaping to page scroll while the sheet can travel. */
61
+ swipeTrap?: boolean;
62
+ /** Prevents interaction outside the sheet view while presented. */
63
+ inertOutside?: boolean;
64
+ /** Blocks OS edge navigation conflicts near the travel edge when possible. */
65
+ nativeEdgeSwipePrevention?: boolean;
66
+ /** Keeps focused inputs visible while the visual viewport changes. */
67
+ nativeFocusScrollPrevention?: boolean;
68
+ /** Dismiss when clicking outside the sheet content. */
69
+ closeOnOutsideClick?: boolean;
70
+ /** Dismiss when pressing Escape. */
71
+ closeOnEscape?: boolean;
72
+ /** Keep keyboard focus inside the sheet view while modal. */
73
+ focusTrap?: boolean;
74
+ /** Restore focus to the trigger when dismissed. */
75
+ restoreFocus?: boolean;
76
+ /** Blend the page theme color with the backdrop color. */
77
+ themeColorDimming?: false | 'auto';
78
+ /** Animation settings used when presenting. */
79
+ enteringAnimationSettings?: SheetAnimationSettings;
80
+ /** Animation settings used when dismissing. */
81
+ exitingAnimationSettings?: SheetAnimationSettings;
82
+ /** Animation settings used when stepping between detents. */
83
+ steppingAnimationSettings?: SheetAnimationSettings;
84
+ }
85
+ /** Detail emitted by presentation state changes. */
86
+ interface SheetPresentedChangeEvent {
87
+ presented: boolean;
88
+ source: 'programmatic' | 'trigger' | 'gesture' | 'escape' | 'outside';
89
+ }
90
+ /** Detail emitted by detent state changes. */
91
+ interface SheetActiveDetentChangeEvent {
92
+ activeDetent: number;
93
+ previousActiveDetent: number;
94
+ }
95
+ /** Detail emitted continuously while the sheet travels. */
96
+ interface SheetTravelEvent {
97
+ /** Current normalized travel progress from dismissed `0` to fully presented `1`. */
98
+ progress: number;
99
+ /** Active detent index nearest to the current travel position. */
100
+ activeDetent: number;
101
+ /** Current offset from the presented position, in em. */
102
+ offset: number;
103
+ /** Current travel status. */
104
+ status: SheetTravelStatus;
105
+ }
106
+
107
+ /** Configure a `<cap-sheet>` element from Angular `ngAfterViewInit`. */
108
+ declare function setupSheet(element: HTMLElement, options?: Partial<SheetOptions> & {
109
+ onPresentedChange?: (event: SheetPresentedChangeEvent) => void;
110
+ onActiveDetentChange?: (event: SheetActiveDetentChangeEvent) => void;
111
+ onTravel?: (event: SheetTravelEvent) => void;
112
+ }): () => void;
113
+
114
+ export { type SheetActiveDetentChangeEvent, type SheetOptions, type SheetPresentedChangeEvent, type SheetSafeAreaEdge, type SheetSafeAreaMode, type SheetTravelEvent, setupSheet };
@@ -0,0 +1,114 @@
1
+ /** Placement of the sheet content inside the viewport. */
2
+ type SheetPlacement = 'top' | 'bottom' | 'left' | 'right' | 'center';
3
+ /** Swipe track used when the content can be dismissed from an edge. */
4
+ type SheetTrack = Exclude<SheetPlacement, 'center'>;
5
+ /** Viewport edges protected by safe-area insets. */
6
+ type SheetSafeAreaEdge = 'top' | 'bottom' | 'left' | 'right';
7
+ /** Safe-area behavior for Capacitor WebViews and mobile browsers. */
8
+ type SheetSafeAreaMode = boolean | 'auto' | 'none' | SheetSafeAreaEdge[];
9
+ /** Runtime travel state emitted by sheet lifecycle events. */
10
+ type SheetTravelStatus = 'idle' | 'entering' | 'exiting' | 'dragging' | 'settling';
11
+ /** Built-in animation presets tuned for mobile WebViews. */
12
+ type SheetAnimationPreset = 'gentle' | 'smooth' | 'snappy';
13
+ /** Easing string accepted by the Web Animations API. */
14
+ type SheetEasing = 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | string;
15
+ /** Animation options for programmatic present, dismiss, and detent steps. */
16
+ interface SheetAnimationSettings {
17
+ /** Named preset. Defaults to `smooth`. */
18
+ preset?: SheetAnimationPreset;
19
+ /** Duration in milliseconds. Ignored when `skip` is true. */
20
+ duration?: number;
21
+ /** CSS easing used by WAAPI. */
22
+ easing?: SheetEasing;
23
+ /** Skip the animation and snap to the final state. */
24
+ skip?: boolean | 'auto';
25
+ /** For dual-track sheets, select the track used by this programmatic movement. */
26
+ track?: SheetTrack;
27
+ /** Keep content fixed while related outlets/backdrops animate. */
28
+ contentMove?: boolean;
29
+ }
30
+ /** Options accepted by the `<cap-sheet>` custom element and setup helpers. */
31
+ interface SheetOptions {
32
+ /** Unique component id used by `for` attributes. */
33
+ componentId?: string;
34
+ /** Sheet stack id. Use the closest `<cap-sheet-stack>` when omitted. */
35
+ stack?: string;
36
+ /** Initial uncontrolled presentation state. */
37
+ defaultPresented?: boolean;
38
+ /** Controlled presentation state. */
39
+ presented?: boolean;
40
+ /** Initial detent index for uncontrolled sheets. */
41
+ defaultActiveDetent?: number;
42
+ /** Controlled detent index. */
43
+ activeDetent?: number;
44
+ /** Intermediate detents between dismissed `0` and fully presented `n`. */
45
+ detents?: string | string[];
46
+ /** WAI-ARIA role applied to `<cap-sheet-view>`. */
47
+ sheetRole?: 'dialog' | 'alertdialog' | 'status' | string;
48
+ /** Where content sits when fully presented. */
49
+ contentPlacement?: SheetPlacement;
50
+ /** Safe-area edges protected by the sheet viewport. Defaults to `auto`. */
51
+ safeArea?: SheetSafeAreaMode;
52
+ /** Edge tracks that can dismiss the sheet. */
53
+ tracks?: SheetTrack | SheetTrack[];
54
+ /** Enables pointer, touch, trackpad, and wheel travel gestures. */
55
+ swipe?: boolean;
56
+ /** Allows swiping to detent `0` and dismissing. */
57
+ swipeDismissal?: boolean;
58
+ /** Allows a soft overshoot past the end detents. */
59
+ swipeOvershoot?: boolean;
60
+ /** Prevents gestures from escaping to page scroll while the sheet can travel. */
61
+ swipeTrap?: boolean;
62
+ /** Prevents interaction outside the sheet view while presented. */
63
+ inertOutside?: boolean;
64
+ /** Blocks OS edge navigation conflicts near the travel edge when possible. */
65
+ nativeEdgeSwipePrevention?: boolean;
66
+ /** Keeps focused inputs visible while the visual viewport changes. */
67
+ nativeFocusScrollPrevention?: boolean;
68
+ /** Dismiss when clicking outside the sheet content. */
69
+ closeOnOutsideClick?: boolean;
70
+ /** Dismiss when pressing Escape. */
71
+ closeOnEscape?: boolean;
72
+ /** Keep keyboard focus inside the sheet view while modal. */
73
+ focusTrap?: boolean;
74
+ /** Restore focus to the trigger when dismissed. */
75
+ restoreFocus?: boolean;
76
+ /** Blend the page theme color with the backdrop color. */
77
+ themeColorDimming?: false | 'auto';
78
+ /** Animation settings used when presenting. */
79
+ enteringAnimationSettings?: SheetAnimationSettings;
80
+ /** Animation settings used when dismissing. */
81
+ exitingAnimationSettings?: SheetAnimationSettings;
82
+ /** Animation settings used when stepping between detents. */
83
+ steppingAnimationSettings?: SheetAnimationSettings;
84
+ }
85
+ /** Detail emitted by presentation state changes. */
86
+ interface SheetPresentedChangeEvent {
87
+ presented: boolean;
88
+ source: 'programmatic' | 'trigger' | 'gesture' | 'escape' | 'outside';
89
+ }
90
+ /** Detail emitted by detent state changes. */
91
+ interface SheetActiveDetentChangeEvent {
92
+ activeDetent: number;
93
+ previousActiveDetent: number;
94
+ }
95
+ /** Detail emitted continuously while the sheet travels. */
96
+ interface SheetTravelEvent {
97
+ /** Current normalized travel progress from dismissed `0` to fully presented `1`. */
98
+ progress: number;
99
+ /** Active detent index nearest to the current travel position. */
100
+ activeDetent: number;
101
+ /** Current offset from the presented position, in em. */
102
+ offset: number;
103
+ /** Current travel status. */
104
+ status: SheetTravelStatus;
105
+ }
106
+
107
+ /** Configure a `<cap-sheet>` element from Angular `ngAfterViewInit`. */
108
+ declare function setupSheet(element: HTMLElement, options?: Partial<SheetOptions> & {
109
+ onPresentedChange?: (event: SheetPresentedChangeEvent) => void;
110
+ onActiveDetentChange?: (event: SheetActiveDetentChangeEvent) => void;
111
+ onTravel?: (event: SheetTravelEvent) => void;
112
+ }): () => void;
113
+
114
+ export { type SheetActiveDetentChangeEvent, type SheetOptions, type SheetPresentedChangeEvent, type SheetSafeAreaEdge, type SheetSafeAreaMode, type SheetTravelEvent, setupSheet };