Aller au contenu

Drawer

Un panneau qui glisse depuis le bord de l’écran. À utiliser pour les formulaires, détails ou panneaux de tâches.

import { Drawer } from 'asterui'

Drawer de base

Simple tiroir depuis le côté droit.

import { Drawer, Button } from 'asterui'
import { useState } from 'react'

function App() {
  const [open, setOpen] = useState(false)
  
  return (
      <Button color="primary" onClick={() => setOpen(true)}>
        Open Drawer
      </Button>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        title="Basic Drawer"
      >
        <p>Drawer content goes here.</p>
      </Drawer>
    )
}

export default App

Placement

Le tiroir peut glisser depuis n'importe quelle direction.

import { Drawer, Button, Space } from 'asterui'
import { useState } from 'react'

function App() {
  const [placement, setPlacement] = useState<'left' | 'right' | 'top' | 'bottom'>('right')
  const [open, setOpen] = useState(false)
  
  const showDrawer = (p: typeof placement) => {
    setPlacement(p)
    setOpen(true)
  }
  
  return (
      <Space direction="horizontal" size="sm" wrap>
        <Button onClick={() => showDrawer('left')}>Left</Button>
        <Button onClick={() => showDrawer('right')}>Right</Button>
        <Button onClick={() => showDrawer('top')}>Top</Button>
        <Button onClick={() => showDrawer('bottom')}>Bottom</Button>
      </Space>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        placement={placement}
        title={`${placement.charAt(0).toUpperCase() + placement.slice(1)} Drawer`}
      >
        <p>This drawer slides in from the {placement}.</p>
      </Drawer>
    )
}

export default App

Avec pied de page

Tiroir avec boutons d'action dans le pied de page.

import { Drawer, Button, Space } from 'asterui'
import { useState } from 'react'

function App() {
  const [open, setOpen] = useState(false)
  
  return (
      <Button color="primary" onClick={() => setOpen(true)}>
        Open Drawer
      </Button>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        title="Edit Profile"
        footer={
          <Space direction="horizontal" size="sm">
            <Button onClick={() => setOpen(false)}>Cancel</Button>
            <Button color="primary" onClick={() => setOpen(false)}>
              Save
            </Button>
          </Space>
        }
      >
        <p>Form content would go here...</p>
      </Drawer>
    )
}

export default App

Contenu d'en-tête supplémentaire

Tiroir avec actions supplémentaires dans l'en-tête.

import { Drawer, Button, Space } from 'asterui'
import { useState } from 'react'

function App() {
  const [open, setOpen] = useState(false)
  
  return (
      <Button color="primary" onClick={() => setOpen(true)}>
        Open Drawer
      </Button>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        title="User Details"
        extra={
          <Space size="xs">
            <Button size="sm" variant="ghost">Edit</Button>
            <Button size="sm" variant="ghost">Delete</Button>
          </Space>
        }
      >
        <p>User information displayed here.</p>
      </Drawer>
    )
}

export default App

Tailles prédéfinies

Tailles prédéfinies par défaut (378px) et grande (736px).

import { Drawer, Button, Space } from 'asterui'
import { useState } from 'react'

function App() {
  const [size, setSize] = useState<'default' | 'large'>('default')
  const [open, setOpen] = useState(false)
  
  const showDrawer = (s: typeof size) => {
    setSize(s)
    setOpen(true)
  }
  
  return (
      <Space direction="horizontal" size="sm">
        <Button onClick={() => showDrawer('default')}>Default (378px)</Button>
        <Button onClick={() => showDrawer('large')}>Large (736px)</Button>
      </Space>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        title={`${size.charAt(0).toUpperCase() + size.slice(1)} Drawer`}
        size={size}
      >
        <p>This drawer uses the {size} preset size.</p>
      </Drawer>
    )
}

export default App

État de chargement

Tiroir avec état de chargement squelette.

import { Drawer, Button } from 'asterui'
import { useState, useEffect } from 'react'

function App() {
  const [open, setOpen] = useState(false)
  const [loading, setLoading] = useState(true)
  
  useEffect(() => {
    if (open) {
      setLoading(true)
      const timer = setTimeout(() => setLoading(false), 1500)
      return () => clearTimeout(timer)
    }
  }, [open])
  
  return (
      <Button color="primary" onClick={() => setOpen(true)}>
        Load Data
      </Button>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        title="User Profile"
        loading={loading}
      >
        <div className="space-y-4">
          <p><strong>Name:</strong> John Doe</p>
          <p><strong>Email:</strong> john@example.com</p>
          <p><strong>Role:</strong> Administrator</p>
        </div>
      </Drawer>
    )
}

export default App

Tiroirs imbriqués

Plusieurs tiroirs avec comportement de poussée.

import { Drawer, Button } from 'asterui'
import { useState } from 'react'

function App() {
  const [open1, setOpen1] = useState(false)
  const [open2, setOpen2] = useState(false)
  
  return (
      <Button color="primary" onClick={() => setOpen1(true)}>
        Open First Drawer
      </Button>
      <Drawer
        open={open1}
        onClose={() => setOpen1(false)}
        title="First Drawer"
        push={{ distance: 180 }}
      >
        <p>This is the first drawer.</p>
        <Button color="secondary" onClick={() => setOpen2(true)}>
          Open Second Drawer
        </Button>
        <Drawer
          open={open2}
          onClose={() => setOpen2(false)}
          title="Second Drawer"
          width={400}
        >
          <p>This is a nested drawer.</p>
          <p>Notice how the first drawer pushed back.</p>
        </Drawer>
      </Drawer>
    )
}

export default App

Sans masque

Tiroir sans superposition d'arrière-plan.

import { Drawer, Button } from 'asterui'
import { useState } from 'react'

function App() {
  const [open, setOpen] = useState(false)
  
  return (
      <Button color="primary" onClick={() => setOpen(true)}>
        Open Drawer
      </Button>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        title="No Mask Drawer"
        mask={false}
      >
        <p>This drawer has no backdrop overlay.</p>
        <p>You can still interact with the page behind it.</p>
      </Drawer>
    )
}

export default App
PropriétéDescriptionTypeDéfaut
childrenContenu du tiroirReact.ReactNode-
openÉtat d’ouverture contrôlébooleanfalse
onCloseGestionnaire de fermeture(e?: React.MouseEvent | React.KeyboardEvent) => void-
afterOpenChangeRappel après la fin de l’animation d’ouverture/fermeture(open: boolean) => void-
titleTitre du tiroirReact.ReactNode-
placementPosition du tiroir'left' | 'right' | 'top' | 'bottom''right'
sizeTaille prédéfinie (378px ou 736px) ou nombre personnalisé'default' | 'large' | number'default'
widthLargeur personnalisée (remplace size pour gauche/droite)string | number-
heightHauteur personnalisée (remplace size pour haut/bas)string | number-
closableAfficher le bouton de fermeturebooleantrue
maskAfficher le masque de superpositionbooleantrue
maskClosableFermer au clic sur le masquebooleantrue
keyboardFermer à la touche ESCbooleantrue
footerContenu du pied de pageReact.ReactNode-
extraContenu supplémentaire dans l’en-tête (côté droit)React.ReactNode-
loadingAfficher le squelette de chargementbooleanfalse
destroyOnCloseDétruire le contenu à la fermeturebooleanfalse
forceRenderPré-rendre le contenu (garder dans le DOM lorsque fermé)booleanfalse
pushComportement de poussée du tiroir imbriquéboolean | { distance: number }{ distance: 180 }
zIndexz-index du tiroirnumber1000
classNameClasse CSS pour le panneau du tiroirstring-