Saltar al contenido

Primeros pasos

GitHub

Puedes usar nuestro setup asistido por IA para instalar el plugin. Añade las skills de Capgo a tu herramienta de IA con el siguiente comando:

Ventana de terminal
npx skills add https://github.com/Cap-go/capgo-skills --skill capacitor-plugins

Luego usa el siguiente prompt:

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

Si prefieres la configuración manual, instala el plugin ejecutando estos comandos y sigue las instrucciones de cada plataforma:

  1. Instala el paquete

    Ventana de terminal
    bun add @capgo/capacitor-sheets
  2. Registra los web components

    import '@capgo/capacitor-sheets';
  3. Añade la configuración del viewport para safe areas

    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
  4. Renderiza un sheet

    <cap-sheet-trigger for="booking-sheet" action="present">Open route</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="route-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>
    .route-sheet {
    width: min(100%, 34em);
    padding: 0 1.25em 1.25em;
    }
  • Registrar componentes: import @capgo/capacitor-sheets una vez al bootstrap o los elementos no se actualizarán.
  • Ajuste de viewport: faltante viewport-fit=cover rompe el padding del safe area en teléfonos con notch.
  • Teclado: habilita la prevención de scroll al hacer focus documentada para inputs dentro de bottom sheets.

Los safe areas están habilitados por defecto mediante safe-area="auto". El viewport del sheet lee valores del entorno del navegador y variables fallback de Capacitor:

env(safe-area-inset-top)
env(safe-area-inset-bottom)
env(safe-area-inset-left)
env(safe-area-inset-right)
var(--safe-area-inset-top)
var(--safe-area-inset-bottom)
var(--safe-area-inset-left)
var(--safe-area-inset-right)

Elige los bordes protegidos por sheet:

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

Para apps con status bars o system bars superpuestas, mantén los plugins nativos que exponen los valores de inset correctos:

import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
plugins: {
StatusBar: {
overlaysWebView: true,
},
Keyboard: {
resize: 'body',
resizeOnFullScreen: true,
},
SystemBars: {
insetsHandling: 'css',
},
},
};
export default config;

El manejo del teclado se controla mediante native-focus-scroll-prevention, que por defecto es true. Desactívalo solo si tu app ya gestiona la evasión del teclado:

<cap-sheet native-focus-scroll-prevention="false"></cap-sheet>

Todos los helpers del framework configuran el mismo elemento personalizado. También puedes controlar un sheet directamente:

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

Escucha eventos para estados controlados, analytics o animaciones coordinadas:

sheet?.addEventListener('cap-sheet-presented-change', (event) => {
console.log(event.detail.presented);
});
sheet?.addEventListener('cap-sheet-active-detent-change', (event) => {
console.log(event.detail.activeDetent);
});
sheet?.addEventListener('cap-sheet-travel', (event) => {
console.log(event.detail.progress);
});
import { useEffect, useRef } from 'react';
import { setupSheet } from '@capgo/capacitor-sheets/react';
import '@capgo/capacitor-sheets';
export function BookingSheet() {
const sheetRef = useRef<HTMLElement>(null);
useEffect(() => {
if (!sheetRef.current) return;
return setupSheet(sheetRef.current, {
detents: ['18em', '32em'],
contentPlacement: 'bottom',
onPresentedChange: ({ presented }) => console.log({ presented }),
});
}, []);
return (
<cap-sheet id="booking-sheet" ref={sheetRef}>
<cap-sheet-trigger action="present">Open</cap-sheet-trigger>
<cap-sheet-view>
<cap-sheet-backdrop />
<cap-sheet-content>
<cap-sheet-handle />
<cap-sheet-title>React sheet</cap-sheet-title>
</cap-sheet-content>
</cap-sheet-view>
</cap-sheet>
);
}

Importar desde @capgo/capacitor-sheets/react también registra los tipos de JSX para los custom elements. Si TypeScript sigue reportando etiquetas desconocidas, añade un archivo de declaración en tu árbol de código fuente:

src/capgo-sheets.d.ts
import '@capgo/capacitor-sheets/react';
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue';
import { setupSheet } from '@capgo/capacitor-sheets/vue';
import '@capgo/capacitor-sheets';
const sheetRef = ref<HTMLElement | null>(null);
let cleanup: (() => void) | undefined;
onMounted(() => {
if (sheetRef.value) {
cleanup = setupSheet(sheetRef.value, {
detents: ['18em', '32em'],
contentPlacement: 'bottom',
});
}
});
onUnmounted(() => cleanup?.());
</script>
<template>
<cap-sheet id="booking-sheet" ref="sheetRef">
<cap-sheet-trigger action="present">Open</cap-sheet-trigger>
<cap-sheet-view>
<cap-sheet-backdrop />
<cap-sheet-content>
<cap-sheet-handle />
<cap-sheet-title>Vue sheet</cap-sheet-title>
</cap-sheet-content>
</cap-sheet-view>
</cap-sheet>
</template>
import { AfterViewInit, Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, ViewChild } from '@angular/core';
import { setupSheet } from '@capgo/capacitor-sheets/angular';
import '@capgo/capacitor-sheets';
@Component({
selector: 'app-root',
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `
<cap-sheet id="booking-sheet" #sheet>
<cap-sheet-trigger action="present">Open</cap-sheet-trigger>
<cap-sheet-view>
<cap-sheet-backdrop></cap-sheet-backdrop>
<cap-sheet-content>
<cap-sheet-handle></cap-sheet-handle>
<cap-sheet-title>Angular sheet</cap-sheet-title>
</cap-sheet-content>
</cap-sheet-view>
</cap-sheet>
`,
})
export class AppComponent implements AfterViewInit {
@ViewChild('sheet', { static: true }) sheet?: ElementRef<HTMLElement>;
ngAfterViewInit(): void {
if (this.sheet?.nativeElement) {
setupSheet(this.sheet.nativeElement, {
detents: ['18em', '32em'],
contentPlacement: 'bottom',
});
}
}
}
<script lang="ts">
import { sheet } from '@capgo/capacitor-sheets/svelte';
import '@capgo/capacitor-sheets';
</script>
<cap-sheet id="booking-sheet" use:sheet={{ detents: ['18em', '32em'], contentPlacement: 'bottom' }}>
<cap-sheet-trigger action="present">Open</cap-sheet-trigger>
<cap-sheet-view>
<cap-sheet-backdrop />
<cap-sheet-content>
<cap-sheet-handle />
<cap-sheet-title>Svelte sheet</cap-sheet-title>
</cap-sheet-content>
</cap-sheet-view>
</cap-sheet>
import { onCleanup, onMount } from 'solid-js';
import { setupSheet } from '@capgo/capacitor-sheets/solid';
import '@capgo/capacitor-sheets';
export function BookingSheet() {
let sheetEl!: HTMLElement;
onMount(() => {
const cleanup = setupSheet(sheetEl, {
detents: ['18em', '32em'],
contentPlacement: 'bottom',
});
onCleanup(cleanup);
});
return (
<cap-sheet id="booking-sheet" ref={sheetEl}>
<cap-sheet-trigger action="present">Open</cap-sheet-trigger>
<cap-sheet-view>
<cap-sheet-backdrop />
<cap-sheet-content>
<cap-sheet-handle />
<cap-sheet-title>Solid sheet</cap-sheet-title>
</cap-sheet-content>
</cap-sheet-view>
</cap-sheet>
);
}
ElementoPropósito
cap-sheetEstado de la Sheet, detents, gestos, comportamiento modal y eventos
cap-sheet-triggerAcciones declarativas de present, dismiss, toggle y step
cap-sheet-portalPortal de body opcional para capas de overlay
cap-sheet-viewViewport host fijo con safe-area y padding de teclado
cap-sheet-backdropBackdrop sincronizado con el progreso
cap-sheet-contentSuperficie de sheet accesible
cap-sheet-bleeding-backgroundExtensión de fondo para sheets con bordes redondeados
cap-sheet-handleHandle de detent arrastrable y accesible por teclado
cap-sheet-titleTítulo accesible
cap-sheet-descriptionDescripción accesible
cap-sheet-special-wrapperHook de composición para sheets, cards y lightboxes
cap-sheet-stackAgrupación de sheets apilados
cap-sheet-outletOutlet de progreso para efectos de profundidad y parallax
cap-scrollHelper de progreso de scroll
cap-fixedHelper de capa fija
cap-islandContenido relacionado con la isla flotante
cap-external-overlayContenido superpuesto gestionado fuera del árbol del sheet
OpciónAtributoPredeterminadoDescripción
contentPlacementcontent-placementbottomtop, bottom, left, right, o center
detentsdetentsningunoLongitudes CSS separadas por espacios como 18em 32em
safeAreasafe-areaautoBordes protegidos del safe-area
swipeswipetrueHabilitar gestos de puntero, toque, trackpad y rueda
swipeDismissalswipe-dismissaltruePermitir que los gestos cierren hasta un detent 0
inertOutsideinert-outsidetrueEvitar la interacción detrás de hojas modales
focusTrapfocus-traptrueMantener el foco del teclado dentro del sheet
closeOnOutsideClickclose-on-outside-clicktrueCerrar al hacer clic en el fondo o la vista
closeOnEscapeclose-on-escapetrueCerrar al presionar Escape
nativeFocusScrollPreventionnative-focus-scroll-preventiontrueMantener los inputs con foco visibles sobre el teclado
themeColorDimmingtheme-color-dimmingautoAtenuar el color del tema del WebView en modo modal
  • @capgo/capacitor-sheets
  • @capgo/capacitor-sheets/react
  • @capgo/capacitor-sheets/vue
  • @capgo/capacitor-sheets/angular
  • @capgo/capacitor-sheets/svelte
  • @capgo/capacitor-sheets/solid

Si estás usando Primeros pasos para planificar el trabajo con plugins nativos, conéctalo con Directorio de plugins de Capgo para el flujo de trabajo del producto en Capgo Plugin Directory, Plugins de Capacitor por Capgo para el detalle de implementación en los Plugins de Capacitor por Capgo, Añadir o actualizar plugins para el detalle de implementación en Agregar o actualizar plugins, Alternativas a plugins de Ionic Enterprise para el flujo de trabajo en Alternativas a plugins de Ionic Enterprise, y Native Builds de Capgo para el flujo de trabajo del producto en Capgo Native Builds.