@capgo/capacitor-sheets

中文文档
8.2.7发布于 2026/11/09MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 4.5万

Framework-agnostic swipeable sheets, drawers, dialogs, and scroll primitives for Capacitor apps

原始使用文档
文档目录17 节
  1. ➡️ Get started for free
  2. Usecase Demos
  3. Online Playgrounds
  4. Mobile Test App
  5. Features
  6. Usecase Coverage
  7. Installation
  8. Capacitor Setup
  9. Vanilla Usage
  10. Five Framework Examples
  11. React
  12. Vue
  13. Angular
  14. Svelte
  15. Solid
  16. API Surface
  17. Development

@capgo/capacitor-sheets

Capgo - Build Capacitor apps with AI, ship updates instantly

Capgo: push fixes to your Capacitor users in minutes, build signed iOS and Android apps without a Mac, and roll back in one click.

➡️ Get started for free

14-day unlimited free trial. No credit card required

🤖 Building with an AI coding agent? Install Capgo skills so Claude Code, Codex, Cursor, Copilot, or Gemini CLI know how to install and use @capgo/capacitor-sheets in your Capacitor app: npx skills add Cap-go/capgo-skills. Then ask your agent: "Add @capgo/capacitor-sheets to my Capacitor app and wire it up." Agent setup guides · Hosted MCP

Framework-agnostic sheets, drawers, dialogs, scroll helpers, and overlay primitives for Capacitor apps.

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.

Usecase Demos

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..

Long Sheet demo
Long Sheet
Sheet with Detent demo
Sheet with Detent
Sidebar demo
Sidebar
Bottom Sheet demo
Bottom Sheet
Sheet with Keyboard demo
Sheet with Keyboard
Toast demo
Toast
Detached Sheet demo
Detached Sheet
Page from Bottom demo
Page from Bottom
Top Sheet demo
Top Sheet
Sheet with Stacking demo
Sheet with Stacking
Sheet with Depth demo
Sheet with Depth
Parallax Page demo
Parallax Page
Page demo
Page
Lightbox demo
Lightbox
Persistent Sheet with Detent demo
Persistent Sheet with Detent
Card demo
Card

Online Playgrounds

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:

Mobile Test App

The repo includes a Capacitor app that wraps the React gallery so the sheets can be tested on real iOS and Android devices. The app id is app.capgo.capacitor.sheets. Capacitor 8 requires Node.js 22 or newer for local mobile commands.

npm run build:mobile
npx cap run ios
npx cap run android

Capgo OTA uploads use the same built gallery:

npx @capgo/cli@latest app add app.capgo.capacitor.sheets --name "Capgo Sheets"
npm run deploy:capgo:dev
npm run deploy:capgo

Create the Capgo app once before the first upload. GitHub Actions also include a Capgo deploy workflow. Tag builds deploy to production, alpha tags deploy to dev, and manual runs can choose either channel. Set CAPGO_TOKEN in repository secrets before running it.

Features

  • Framework agnostic custom elements: no React runtime dependency in the core package.
  • Bottom sheets, side drawers, top sheets, and centered dialogs through content-placement.
  • Detents with em, rem, dvh, lvh, svh, calc(), and other modern CSS lengths.
  • Touch, pointer, wheel, and trackpad gestures with dismissal, overshoot, and trap controls.
  • Modal behavior: focus trap, focus restore, Escape dismissal, outside-click dismissal, and inert outside content.
  • Capacitor safe-area defaults using env(safe-area-inset-*) plus Capacitor SystemBars --safe-area-inset-* fallbacks.
  • Keyboard-aware layout using visualViewport resize/scroll events and preventScroll focus behavior.
  • Overlay compatibility through cap-island and cap-external-overlay.
  • Stacking and outlet animation hooks for depth effects and coordinated page motion.
  • Scroll primitives with progress/distance helpers.
  • Theme color dimming for Capacitor WebViews and mobile browsers.
  • Modern CSS defaults authored with em-based sizing, with no design-system lock-in.

Usecase Coverage

UsecaseCapgo Sheets pattern
Long Sheetcap-sheet + cap-scroll or naturally scrolling cap-sheet-content
Sheet with Detentdetents="18em 32em" and stepTo() / cap-sheet-trigger action="step"
Sidebarcontent-placement="left" or content-placement="right"
Bottom Sheetdefault content-placement="bottom"
Sheet with Keyboardvisual viewport offset support via native-focus-scroll-prevention
Toastinert-outside="false", close-on-outside-click="false", focus-trap="false"
Detached Sheetrounded content with margins and cap-sheet-special-wrapper composition
Page from Bottomfull-height bottom sheet content
Top Sheetcontent-placement="top"
Sheet with Stackingcap-sheet-stack, stack depth variables, and stacking animation hooks
Sheet with Depthcap-sheet-outlet progress variables and travelAnimation
Parallax Pagecap-sheet-outlet + cap-scroll progress composition
Pagefull-viewport sheet content or side-entering content-placement
Lightboxcontent-placement="center" plus backdrop and media content
Persistent Sheet with Detentdefault-presented, swipe-dismissal="false", inert-outside="false", close-on-outside-click="false"
Cardcontent-placement="center" with compact content

Installation

You can use our AI-Assisted Setup to install the plugin. Add the Capgo skills to your AI tool using the following command:

npx skills add https://github.com/cap-go/capacitor-skills --skill capacitor-plugins

Then use the following prompt:

Use the `capacitor-plugins` skill from `cap-go/capacitor-skills` to install the `@capgo/capacitor-sheets` plugin in my project.

If you prefer Manual Setup, install the plugin by running the following commands and follow the platform-specific instructions below:

npm install @capgo/capacitor-sheets
npx cap sync

Capacitor Setup

Add viewport-fit=cover so iOS exposes safe-area insets to CSS:

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />

Safe areas are enabled by default. In auto, edge-attached sheets protect the attached edge and side edges while leaving the opposite edge available for fullscreen detents. 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:

<cap-sheet safe-area="none"></cap-sheet>
<cap-sheet safe-area="bottom left right"></cap-sheet>

Detached sheets can use Gorhom-style container spacing without CSS margins. Use detached for full edge rounding, top-inset / bottom-inset / left-inset / right-inset for one-off offsets, or containerOffset from framework setup helpers for per-edge offsets:

<cap-sheet detached bottom-inset="1rem" detents="18em" content-placement="bottom"></cap-sheet>
setupSheet(sheet, {
  detached: true,
  bottomInset: '1rem',
  containerOffset: { left: '1rem', right: '1rem' },
});

For Capacitor apps with overlay status/system bars, keep the platform plugins responsible for exposing correct insets:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  plugins: {
    StatusBar: {
      overlaysWebView: true,
    },
    Keyboard: {
      resize: 'body',
      resizeOnFullScreen: true,
    },
    SystemBars: {
      insetsHandling: 'css',
    },
  },
};

export default config;

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.

Vanilla Usage

<script type="module">
  import '@capgo/capacitor-sheets';
</script>

<cap-sheet-trigger for="booking-sheet" action="present">Open</cap-sheet-trigger>

<cap-sheet id="booking-sheet" detents="18em 32em" content-placement="bottom">
  <cap-sheet-portal>
    <cap-sheet-view>
      <cap-sheet-backdrop></cap-sheet-backdrop>
      <cap-sheet-content class="sheet">
        <cap-sheet-bleeding-background></cap-sheet-bleeding-background>
        <cap-sheet-handle></cap-sheet-handle>
        <cap-sheet-title>Evening route</cap-sheet-title>
        <cap-sheet-description>Choose a route and confirm pickup.</cap-sheet-description>
        <cap-sheet-trigger action="dismiss">Done</cap-sheet-trigger>
      </cap-sheet-content>
    </cap-sheet-view>
  </cap-sheet-portal>
</cap-sheet>
.sheet {
  width: min(100%, 34em);
  padding: 0 1.25em 1.25em;
}

Five Framework Examples

Full runnable examples live in:

  • examples/react-app
  • examples/vue-app
  • examples/angular-app
  • examples/svelte-app
  • examples/solid-app

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.

React

import { setupSheet } from '@capgo/capacitor-sheets/react';
import { useEffect, useRef } from 'react';
import '@capgo/capacitor-sheets';
import { mountUsecaseGallery } from '../../shared/usecase-gallery';

export function App() {
  const galleryRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!galleryRef.current) return;
    return mountUsecaseGallery(galleryRef.current, {
      framework: 'React',
      setupSheet,
    });
  }, []);

  return <div ref={galleryRef} />;
}

Vue

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue';
import { setupSheet } from '@capgo/capacitor-sheets/vue';
import '@capgo/capacitor-sheets';
import { mountUsecaseGallery } from '../../shared/usecase-gallery';

const galleryRef = ref<HTMLElement | null>(null);
let cleanup: (() => void) | undefined;

onMounted(() => {
  if (galleryRef.value) {
    cleanup = mountUsecaseGallery(galleryRef.value, {
      framework: 'Vue',
      setupSheet,
    });
  }
});

onUnmounted(() => cleanup?.());
</script>

<template>
  <div ref="galleryRef"></div>
</template>

Angular

import type { AfterViewInit, ElementRef, OnDestroy } from '@angular/core';
import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild } from '@angular/core';
import { setupSheet } from '@capgo/capacitor-sheets/angular';
import '@capgo/capacitor-sheets';
import { mountUsecaseGallery } from '../../../shared/usecase-gallery';

@Component({
  selector: 'app-root',
  standalone: true,
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `<div #gallery></div>`,
})
export class AppComponent implements AfterViewInit, OnDestroy {
  @ViewChild('gallery', { static: true }) gallery?: ElementRef<HTMLElement>;
  private cleanup?: () => void;

  ngAfterViewInit(): void {
    if (this.gallery?.nativeElement) {
      this.cleanup = mountUsecaseGallery(this.gallery.nativeElement, {
        framework: 'Angular',
        setupSheet,
      });
    }
  }

  ngOnDestroy(): void {
    this.cleanup?.();
  }
}

Svelte

<script lang="ts">
  import { onMount } from 'svelte'
  import { setupSheet } from '@capgo/capacitor-sheets/svelte'
  import '@capgo/capacitor-sheets'
  import { mountUsecaseGallery } from '../../shared/usecase-gallery'

  let gallery: HTMLDivElement

  onMount(() =>
    mountUsecaseGallery(gallery, {
      framework: 'Svelte',
      setupSheet,
    }),
  )
</script>

<div bind:this={gallery}></div>

Solid

import { onCleanup, onMount } from 'solid-js';
import { setupSheet } from '@capgo/capacitor-sheets/solid';
import '@capgo/capacitor-sheets';
import { mountUsecaseGallery } from '../../shared/usecase-gallery';

export function App() {
  let galleryEl!: HTMLDivElement;

  onMount(() => {
    const cleanup = mountUsecaseGallery(galleryEl, {
      framework: 'Solid',
      setupSheet,
    });
    onCleanup(cleanup);
  });

  return <div ref={galleryEl} />;
}

API Surface

Core elements:

  • cap-sheet: state, detents, placement, gestures, modal behavior, lifecycle events.
  • cap-sheet-trigger: declarative present, dismiss, toggle, and step actions.
  • cap-sheet-portal: optional body portal for overlay layering.
  • cap-sheet-view: viewport overlay host.
  • cap-sheet-backdrop: progress-synced modal backdrop.
  • cap-sheet-content: accessible sheet surface.
  • cap-sheet-bleeding-background: background extension for rounded edge sheets.
  • cap-sheet-handle: draggable and keyboard-accessible detent handle.
  • cap-sheet-title and cap-sheet-description: accessible naming.
  • cap-sheet-special-wrapper and cap-sheet-special-wrapper-content: composition hooks for detached sheets, cards, lightboxes, and custom page layouts.
  • cap-sheet-stack: groups sheets for stacked depth.
  • cap-sheet-outlet: receives sheet progress variables and optional travelAnimation.
  • cap-scroll and cap-scroll-content: scroll progress helpers.
  • cap-fixed, cap-island, cap-external-overlay, cap-visually-hidden, cap-auto-focus-target: composition and accessibility helpers.

Important events:

  • cap-sheet-presented-change
  • cap-sheet-active-detent-change
  • cap-sheet-travel
  • cap-sheet-travel-status-change
  • cap-sheet-travel-range-change
  • cap-sheet-drag-start
  • cap-sheet-drag-end
  • cap-scroll

Imperative methods on cap-sheet:

const sheet = document.querySelector('cap-sheet')!;
await sheet.present();
await sheet.dismiss();
await sheet.toggle();
await sheet.stepTo(2);
await sheet.step('down');

The public TypeScript API is documented with TSDoc in src/core/types.ts, and generated declarations are emitted during npm run build.

Development

npm install
npm run render:demos
npm run build
npm run dev:examples -- react vue svelte angular solid

In the Capgo monorepo, use bun and bunx for local commands.

版本与发布记录

@capgo/capacitor-sheets 共发布 25 个版本,首次发布于 2026/05/16;过去 12 个月发布了 25 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
8.2.7latest2026/11/09今天
8.2.62026/11/027 天前
8.2.52026/10/2614 天前
8.2.42026/10/1920 天前
8.2.32026/10/1921 天前
8.2.12026/10/1525 天前

关于 @capgo/capacitor-sheets 的常见问题

@capgo/capacitor-sheets 是什么?

Framework-agnostic swipeable sheets, drawers, dialogs, and scroll primitives for Capacitor apps

如何安装 @capgo/capacitor-sheets?

在项目目录运行 npm install @capgo/capacitor-sheets,或使用 pnpm add / yarn add / bun add。

@capgo/capacitor-sheets 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@capgo/capacitor-sheets 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@capgo/capacitor-sheets 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@capgo/capacitor-sheets 可以商用吗?

@capgo/capacitor-sheets 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@capgo/capacitor-sheets 的下载量有多少?

根据 npm 官方下载统计,@capgo/capacitor-sheets 在 2026/10/09 – 2026/11/07 这 30 天内被下载 44,586 次,日均约 1,486 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@capgo/capacitor-sheets 还在维护吗?

最新版本 8.2.7 发布于 2026/11/09(今天);至今共发布 25 个版本,其中过去 12 个月发布了 25 个;首次发布于 2026/05/16。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。