npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@daviduo/vue-bottom-sheet

v1.0.5

Published

Un componente Vue 3 BottomSheet trascinabile e reattivo

Readme

Vue Bottom Sheet Component ([@daviduo/vue-bottom-sheet])

Un componente Vue 3 altamente configurabile per creare "bottom sheet" (pannelli a comparsa dal basso) interattivi e trascinabili, comunemente usati nelle interfacce mobile. Supporta stati di snap (peek, middle, full), gestione del trascinamento, e l'inclusione di link rapidi nello stato "peek".

Questo componente è progettato per integrarsi in progetti che utilizzano Tailwind CSS.

Caratteristiche

  • Tre stati di snap: Completamente chiuso (peek), parzialmente aperto (middle), e completamente aperto (full).
  • Altezza Peek Dinamica: L'altezza dello stato "peek" si adatta automaticamente per mostrare l'handle e, opzionalmente, una sezione di "Quick Links".
  • Interazione Intuitiva: Supporta il trascinamento per cambiare stato e il click sull'handle o sull'overlay.
  • Sincronizzazione v-model: Controlla lo stato aperto/chiuso del pannello.
  • Quick Links: Mostra una sezione di link rapidi personalizzabili quando il pannello è nello stato "peek".
  • Eventi Dettagliati: Emette eventi per cambiamenti di stato e interazioni.
  • Slot per Contenuto: Permette di inserire contenuto personalizzato nel corpo del pannello.
  • Design Responsivo: Nasconde il componente su schermi grandi (lg: e superiori) per impostazione predefinita (tramite classi Tailwind).

Prerequisiti

  • Vue 3.x
  • Vue Router 4.x (utilizzato internamente per useRoute e per i router-link nei quick links)
  • Tailwind CSS: Il componente utilizza classi di utilità Tailwind per lo stile. Assicurati che Tailwind CSS sia installato e configurato nel tuo progetto.

Installazione

Puoi installare il pacchetto usando npm o yarn:

npm install @daviduo/vue-bottom-sheet
# oppure
yarn add @daviduo/vue-bottom-sheet

Utilizzo

Puoi registrare il componente globalmente come plugin Vue o importarlo direttamente nei tuoi componenti.

1. Registrazione Globale (Plugin)

Nel tuo file main.js (o main.ts):

import { createApp } from 'vue';
import App from './App.vue';
import BottomSheetPlugin from '@daviduo/vue-bottom-sheet';

const app = createApp(App);

app.use(BottomSheetPlugin);
// Puoi anche passare opzioni, ad esempio per un nome componente personalizzato:
// app.use(BottomSheetPlugin, { componentName: 'MyCustomSheet' });

app.mount('#app');

Ora puoi usare <BottomSheet> (o <MyCustomSheet>) in qualsiasi template del tuo progetto.

Nota importante per utenti CommonJS/UMD:

A causa della coesistenza di esportazioni nominate (BottomSheet) e di una esportazione default (il plugin stesso) nel pacchetto, quando si utilizza require() o si carica il pacchetto tramite un tag <script> (UMD), l'oggetto plugin necessario per app.use() deve essere accessibile tramite la proprietà .default.

Quindi, per registrare il plugin globalmente in questi ambienti, dovresti fare così:

  • Con require (CommonJS):

    const { createApp } = require('vue'); 
    const App = require('./App.vue');     
    const BottomSheetPlugin = require('@daviduo/vue-bottom-sheet').default; // <-- .default
    
    const app = createApp(App);
    app.use(BottomSheetPlugin);
    app.mount('#app');
  • Con UMD:

    const app = Vue.createApp(App);
    app.use(window.VueBottomSheet.default); // <-- .default
    app.mount('#app');

2. Importazione Diretta

Puoi importare il componente BottomSheet direttamente dove ti serve:

<script setup>
import { ref } from 'vue';
import { BottomSheet } from '@daviduo/vue-bottom-sheet'; // O il nome del tuo pacchetto
// Se il tuo pacchetto esporta anche CSS separato:
// import '@daviduo/vue-bottom-sheet/dist/style.css';

const isSheetOpen = ref(false);
const myQuickLinks = ref({
  section1: {
    items: [
      { name: 'Home', to: { name: 'home' }, icon: 'HomeIconComponent', current: true },
      { name: 'External', href: 'https://example.com', icon: 'LinkIconComponent' },
    ]
  }
});

const handleSheetStateChange = (newState, position) => {
  console.log(`Sheet state changed to: ${newState} at ${position}vh`);
};
</script>

<template>
  <div>
    <button @click="isSheetOpen = !isSheetOpen">
      {{ isSheetOpen ? 'Chiudi Sheet' : 'Apri Sheet' }}
    </button>

    <BottomSheet
      v-model="isSheetOpen"
      :middle-y="40"
      :full-y="10"
      :quick-links="myQuickLinks"
      @state-change="handleSheetStateChange"
      @handle-click="() => console.log('Handle cliccato!')"
    >
      <div class="p-4">
        <h2>Contenuto del Bottom Sheet</h2>
        <p>Questo è il contenuto che appare quando il pannello è aperto (middle o full).</p>
        <p>Puoi mettere qui qualsiasi markup Vue.</p>
        <div style="height: 500px; background: #eee; margin-top: 20px; padding: 10px;">
          Contenuto scrollabile...
        </div>
      </div>
    </BottomSheet>
  </div>
</template>

Nota sugli Icon Component: Nei quickLinks, la proprietà icon si aspetta un componente Vue importato e registrato (o una stringa che Vue può risolvere in un componente globale). Assicurati che questi componenti icona siano disponibili nel contesto del tuo progetto. Se usi librerie come Heroicons, dovrai importarle.

Esempio con Heroicons (ipotetico HomeIconComponent):

// Potrebbe essere nel tuo <script setup> o importato globalmente
import { HomeIcon as HomeIconComponent } from '@heroicons/vue/24/outline';

API

Props

| Prop | Tipo | Default | Descrizione | | :----------- | :------ | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | modelValue | Boolean | false | Controlla lo stato aperto (true = middleY o fullY) o chiuso (false = peekTranslateY) del pannello. Usato con v-model. | | middleY | Number | 50 | La posizione verticale (in % vh dalla cima dello schermo) per lo stato "middle". Un valore più basso significa più in alto. | | fullY | Number | 5 | La posizione verticale (in % vh dalla cima dello schermo) per lo stato "full". Un valore più basso significa più in alto. | | quickLinks | Object | null | Un oggetto che definisce i link da mostrare nello stato "peek". Vedi la struttura dell'oggetto qui sotto. Se null o vuoto, la sezione quick links non viene renderizzata. |

Struttura dell'Oggetto quickLinks

L'oggetto quickLinks è strutturato per sezioni, ognuna contenente item.

{
  // Chiave della sezione (es. 'section1', 'navigation', etc.)
  "uniqueSectionKey": {
    "items": [
      {
        // "name": "Label (non usato nel template attuale, ma utile per debug)",
        "href": "https://external.url", // Per link esterni <a href="...">
        "icon": YourIconComponent, // Componente Vue per l'icona
        "iconProps": { class: "custom-icon-class" }, // Props opzionali da passare al componente icona
        "current": false // Flag per stile attivo (se applicabile dal tuo CSS e dal componente icona)
      },
      {
        // "name": "Internal Page",
        "to": { name: "routeName" }, // o "/path", per vue-router <router-link>
        "icon": AnotherIconComponent,
        // "iconProps": { ... },
        // "current": true // Gestito automaticamente da <router-link> se non specificato qui
      }
      // ... altri item
    ]
  }
  // ... altre sezioni
}

Eventi

| Evento | Payload | Descrizione | | :------------------ | :-------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | update:modelValue | Boolean (isOpen) | Emesso quando lo stato del pannello (aperto/chiuso) cambia a seguito di interazione utente, per supportare v-model. | | state-change | String (newStateName), Number (newY) | Emesso quando il pannello transita a un nuovo stato (peek, middle, full). Il payload include il nome del nuovo stato e la sua posizione translateY in vh. | | handle-click | void | Emesso quando l'handle viene cliccato (non trascinato). Tipicamente, questo apre il pannello allo stato middleY se era in stato peek. |

Slot

| Nome | Descrizione | | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------------- | | default | Il contenuto principale del bottom sheet, visualizzato quando il pannello è negli stati middle o full. Questo slot riceve lo spazio rimanente. |

Dipendenza da Tailwind CSS

Questo componente richiede che Tailwind CSS sia installato e configurato nel progetto che lo utilizza. Le classi di utilità di Tailwind (fixed, bg-white, rounded-t-xl, flex, lg:hidden, ecc.) sono usate direttamente nel template del componente. Senza Tailwind, il componente non avrà lo stile corretto.

Assicurati che il content path nel tuo tailwind.config.js includa i file del componente se lo stai importando dai node_modules (questo è particolarmente rilevante se le classi Tailwind non vengono rilevate correttamente):

// tailwind.config.js
module.exports = {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}",
    "./node_modules/@daviduo/vue-bottom-sheet/dist/*.{js,vue}", 
    // ...
  ],
  // ...
};

Peer Dependencies

Questo pacchetto elenca vue (>=3.2.0) e vue-router (>=4.0.0) come peerDependencies. Ciò significa che sei responsabile di installare queste dipendenze nel tuo progetto.

npm install vue@^3.2.0 vue-router@^4.0.0
# oppure
yarn add vue@^3.2.0 vue-router@^4.0.0

Contribuire

I contributi sono benvenuti! Si prega di aprire una issue o una pull request nel repository GitHub.

Licenza

MIT