@adamosuiteservices/ui 2.13.2 → 2.13.4
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.
- package/dist/components/ui/slider/slider.d.ts +5 -2
- package/dist/slider.cjs +7 -8
- package/dist/slider.js +192 -178
- package/dist/styles.css +1 -1
- package/docs/AI-GUIDE.md +321 -321
- package/docs/components/layout/sidebar.md +399 -399
- package/docs/components/layout/toaster.md +436 -436
- package/docs/components/ui/accordion-rounded.md +584 -584
- package/docs/components/ui/accordion.md +269 -269
- package/docs/components/ui/calendar.md +1159 -1159
- package/docs/components/ui/card.md +1455 -1455
- package/docs/components/ui/checkbox.md +292 -292
- package/docs/components/ui/collapsible.md +323 -323
- package/docs/components/ui/dialog.md +628 -628
- package/docs/components/ui/field.md +706 -706
- package/docs/components/ui/hover-card.md +446 -446
- package/docs/components/ui/kbd.md +434 -434
- package/docs/components/ui/label.md +359 -359
- package/docs/components/ui/pagination.md +650 -650
- package/docs/components/ui/popover.md +536 -536
- package/docs/components/ui/progress.md +182 -182
- package/docs/components/ui/radio-group.md +311 -311
- package/docs/components/ui/separator.md +214 -214
- package/docs/components/ui/sheet.md +174 -174
- package/docs/components/ui/skeleton.md +140 -140
- package/docs/components/ui/slider.md +460 -341
- package/docs/components/ui/spinner.md +170 -170
- package/docs/components/ui/switch.md +408 -408
- package/docs/components/ui/tabs-underline.md +106 -106
- package/docs/components/ui/tabs.md +122 -122
- package/docs/components/ui/textarea.md +243 -243
- package/docs/components/ui/toggle.md +237 -237
- package/docs/components/ui/tooltip.md +317 -317
- package/docs/components/ui/typography.md +320 -320
- package/package.json +1 -1
|
@@ -1,399 +1,399 @@
|
|
|
1
|
-
# Sidebar Component
|
|
2
|
-
|
|
3
|
-
## Descripción
|
|
4
|
-
|
|
5
|
-
El componente `Sidebar` es un layout component que proporciona navegación lateral responsive. En desktop muestra un sidebar fijo lateral, mientras que en mobile se convierte automáticamente en un menú Sheet desplegable con icono hamburguesa.
|
|
6
|
-
|
|
7
|
-
## Importación
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
import {
|
|
11
|
-
Sidebar,
|
|
12
|
-
SidebarContent,
|
|
13
|
-
SidebarInset,
|
|
14
|
-
SidebarTopBar,
|
|
15
|
-
SidebarTrigger,
|
|
16
|
-
SidebarHeader,
|
|
17
|
-
SidebarFooter,
|
|
18
|
-
SidebarMenu,
|
|
19
|
-
SidebarMenuItem,
|
|
20
|
-
} from "@adamosuiteservices/ui/sidebar";
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**Nota**: Si usas `SidebarMenuItem` con `asChild`, también puedes importar componentes de navegación:
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
import { Link } from "react-router-dom"; // o Next.js Link
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Uso Básico
|
|
30
|
-
|
|
31
|
-
```tsx
|
|
32
|
-
<Sidebar>
|
|
33
|
-
<SidebarContent>
|
|
34
|
-
<SidebarHeader className="adm:items-center">
|
|
35
|
-
{/* Logo o título */}
|
|
36
|
-
</SidebarHeader>
|
|
37
|
-
|
|
38
|
-
<SidebarMenu>
|
|
39
|
-
<SidebarMenuItem>
|
|
40
|
-
<Icon symbol="home" /> Dashboard
|
|
41
|
-
</SidebarMenuItem>
|
|
42
|
-
<SidebarMenuItem>
|
|
43
|
-
<Icon symbol="folder" /> Projects
|
|
44
|
-
</SidebarMenuItem>
|
|
45
|
-
<SidebarMenuItem>
|
|
46
|
-
<Icon symbol="settings" /> Settings
|
|
47
|
-
</SidebarMenuItem>
|
|
48
|
-
</SidebarMenu>
|
|
49
|
-
|
|
50
|
-
<SidebarFooter>
|
|
51
|
-
<SidebarMenuItem>
|
|
52
|
-
<Icon symbol="account_circle" /> Profile
|
|
53
|
-
</SidebarMenuItem>
|
|
54
|
-
</SidebarFooter>
|
|
55
|
-
</SidebarContent>
|
|
56
|
-
|
|
57
|
-
<SidebarInset>
|
|
58
|
-
<SidebarTopBar>
|
|
59
|
-
<h1 className="adm:text-lg adm:font-semibold">Dashboard</h1>
|
|
60
|
-
<SidebarTrigger />
|
|
61
|
-
</SidebarTopBar>
|
|
62
|
-
{/* Contenido principal */}
|
|
63
|
-
</SidebarInset>
|
|
64
|
-
</Sidebar>
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Componentes
|
|
68
|
-
|
|
69
|
-
### Sidebar (Root)
|
|
70
|
-
|
|
71
|
-
Contenedor principal con context provider.
|
|
72
|
-
|
|
73
|
-
### SidebarContent
|
|
74
|
-
|
|
75
|
-
Contenido del sidebar con Portal para posicionamiento fijo.
|
|
76
|
-
|
|
77
|
-
### SidebarInset
|
|
78
|
-
|
|
79
|
-
Contenedor para el contenido principal que se ajusta al sidebar.
|
|
80
|
-
|
|
81
|
-
### SidebarTopBar
|
|
82
|
-
|
|
83
|
-
Barra superior sticky para el contenido principal, ideal para incluir el trigger del sidebar y el título de la página.
|
|
84
|
-
|
|
85
|
-
### SidebarTrigger
|
|
86
|
-
|
|
87
|
-
Botón hamburguesa que abre/cierra el sidebar en mobile. Automáticamente oculto en desktop (xl+).
|
|
88
|
-
|
|
89
|
-
### SidebarHeader
|
|
90
|
-
|
|
91
|
-
Sección superior del sidebar.
|
|
92
|
-
|
|
93
|
-
### SidebarFooter
|
|
94
|
-
|
|
95
|
-
Sección inferior del sidebar.
|
|
96
|
-
|
|
97
|
-
### SidebarMenu
|
|
98
|
-
|
|
99
|
-
Contenedor para items de menú con scroll.
|
|
100
|
-
|
|
101
|
-
### SidebarMenuItem
|
|
102
|
-
|
|
103
|
-
Item individual del menú con hover effects.
|
|
104
|
-
|
|
105
|
-
## Responsive
|
|
106
|
-
|
|
107
|
-
- **Desktop (xl+)**: Sidebar fijo lateral (256px de ancho)
|
|
108
|
-
- **Mobile**: Sidebar en Sheet (modal lateral)
|
|
109
|
-
- Incluye icono hamburguesa automático en mobile
|
|
110
|
-
|
|
111
|
-
## Props
|
|
112
|
-
|
|
113
|
-
### Sidebar
|
|
114
|
-
|
|
115
|
-
| Prop | Tipo | Descripción |
|
|
116
|
-
| -------- | ----------- | --------------------------------------------------- |
|
|
117
|
-
| children | `ReactNode` | Contenido del sidebar (debe incluir SidebarContent) |
|
|
118
|
-
|
|
119
|
-
### SidebarContent
|
|
120
|
-
|
|
121
|
-
| Prop | Tipo | Descripción |
|
|
122
|
-
| --------- | ----------------------- | ------------------------------------- |
|
|
123
|
-
| className | `string` | Clases adicionales para el contenedor |
|
|
124
|
-
| children | `ReactNode` | Contenido del sidebar |
|
|
125
|
-
| ...props | `ComponentProps<"div">` | Props nativas de div |
|
|
126
|
-
|
|
127
|
-
### SidebarInset
|
|
128
|
-
|
|
129
|
-
| Prop | Tipo | Descripción |
|
|
130
|
-
| --------- | ----------------------- | ------------------------------------ |
|
|
131
|
-
| className | `string` | Clases adicionales |
|
|
132
|
-
| children | `ReactNode` | Contenido principal de la aplicación |
|
|
133
|
-
| ...props | `ComponentProps<"div">` | Props nativas de div |
|
|
134
|
-
|
|
135
|
-
### SidebarTopBar
|
|
136
|
-
|
|
137
|
-
| Prop | Tipo | Descripción |
|
|
138
|
-
| --------- | ----------------------- | ------------------------------------------------- |
|
|
139
|
-
| className | `string` | Clases adicionales |
|
|
140
|
-
| children | `ReactNode` | Contenido de la barra (trigger, título, acciones) |
|
|
141
|
-
| ...props | `ComponentProps<"div">` | Props nativas de div |
|
|
142
|
-
|
|
143
|
-
**Estilos por defecto**: sticky, top-0, flex, gap-2, items-center, justify-between, bg-background, p-4, border-b
|
|
144
|
-
|
|
145
|
-
### SidebarTrigger
|
|
146
|
-
|
|
147
|
-
| Prop | Tipo | Descripción |
|
|
148
|
-
| --------- | -------------------------- | ----------------------- |
|
|
149
|
-
| className | `string` | Clases adicionales |
|
|
150
|
-
| ...props | `ComponentProps<"button">` | Props nativas de button |
|
|
151
|
-
|
|
152
|
-
**Comportamiento**: Oculto automáticamente en desktop (xl:hidden). Incluye icono menu de Material Symbols.
|
|
153
|
-
|
|
154
|
-
### SidebarHeader
|
|
155
|
-
|
|
156
|
-
| Prop | Tipo | Descripción |
|
|
157
|
-
| --------- | -------------------------- | ----------------------------------- |
|
|
158
|
-
| className | `string` | Clases adicionales |
|
|
159
|
-
| children | `ReactNode` | Contenido del header (logo, título) |
|
|
160
|
-
| ...props | `ComponentProps<"header">` | Props nativas de header |
|
|
161
|
-
|
|
162
|
-
### SidebarFooter
|
|
163
|
-
|
|
164
|
-
| Prop | Tipo | Descripción |
|
|
165
|
-
| --------- | -------------------------- | -------------------------------------- |
|
|
166
|
-
| className | `string` | Clases adicionales |
|
|
167
|
-
| children | `ReactNode` | Contenido del footer (usuario, logout) |
|
|
168
|
-
| ...props | `ComponentProps<"footer">` | Props nativas de footer |
|
|
169
|
-
|
|
170
|
-
### SidebarMenu
|
|
171
|
-
|
|
172
|
-
| Prop | Tipo | Descripción |
|
|
173
|
-
| --------- | ----------------------- | -------------------------------- |
|
|
174
|
-
| className | `string` | Clases adicionales |
|
|
175
|
-
| children | `ReactNode` | Items del menú (SidebarMenuItem) |
|
|
176
|
-
| ...props | `ComponentProps<"div">` | Props nativas de div |
|
|
177
|
-
|
|
178
|
-
### SidebarMenuItem
|
|
179
|
-
|
|
180
|
-
| Prop | Tipo | Default | Descripción |
|
|
181
|
-
| --------- | -------------------------- | ------- | ----------------------------------------------------------- |
|
|
182
|
-
| asChild | `boolean` | `false` | Si es true, renderiza el hijo directo en lugar de un button |
|
|
183
|
-
| className | `string` | - | Clases adicionales |
|
|
184
|
-
| ...props | `ComponentProps<"button">` | - | Props nativas de button |
|
|
185
|
-
|
|
186
|
-
## Características Principales
|
|
187
|
-
|
|
188
|
-
- **Responsive automático**: Desktop muestra sidebar fijo, mobile usa Sheet con hamburger
|
|
189
|
-
- **Auto-manejo del height**: Previene layout shifts al calcular altura automáticamente
|
|
190
|
-
- **Breakpoint xl (1280px)**: Usa `useMediaQuery` para detectar el cambio
|
|
191
|
-
- **Portal rendering**: Usa Radix Portal para z-index correcto
|
|
192
|
-
- **Sheet integration**: Integración nativa con componente Sheet para mobile
|
|
193
|
-
- **Accesibilidad**: Incluye VisuallyHidden para screen readers
|
|
194
|
-
- **Sticky positioning**: Sidebar fijo en desktop con scroll independiente del contenido
|
|
195
|
-
|
|
196
|
-
## Ejemplo Completo
|
|
197
|
-
|
|
198
|
-
```tsx
|
|
199
|
-
import {
|
|
200
|
-
Sidebar,
|
|
201
|
-
SidebarContent,
|
|
202
|
-
SidebarFooter,
|
|
203
|
-
SidebarHeader,
|
|
204
|
-
SidebarInset,
|
|
205
|
-
SidebarMenu,
|
|
206
|
-
SidebarMenuItem,
|
|
207
|
-
SidebarTopBar,
|
|
208
|
-
SidebarTrigger,
|
|
209
|
-
} from "@adamosuiteservices/ui/sidebar";
|
|
210
|
-
import { Icon } from "@adamosuiteservices/ui/icon";
|
|
211
|
-
|
|
212
|
-
export default function AppLayout() {
|
|
213
|
-
return (
|
|
214
|
-
<Sidebar>
|
|
215
|
-
<SidebarContent>
|
|
216
|
-
<SidebarHeader className="adm:items-center">
|
|
217
|
-
<Logo />
|
|
218
|
-
</SidebarHeader>
|
|
219
|
-
|
|
220
|
-
<SidebarMenu>
|
|
221
|
-
<SidebarMenuItem>
|
|
222
|
-
<Icon symbol="home" /> Dashboard
|
|
223
|
-
</SidebarMenuItem>
|
|
224
|
-
<SidebarMenuItem>
|
|
225
|
-
<Icon symbol="folder" /> Projects
|
|
226
|
-
</SidebarMenuItem>
|
|
227
|
-
<SidebarMenuItem>
|
|
228
|
-
<Icon symbol="settings" /> Settings
|
|
229
|
-
</SidebarMenuItem>
|
|
230
|
-
</SidebarMenu>
|
|
231
|
-
|
|
232
|
-
<SidebarFooter>
|
|
233
|
-
<SidebarMenuItem>
|
|
234
|
-
<Icon symbol="account_circle" /> Profile
|
|
235
|
-
</SidebarMenuItem>
|
|
236
|
-
</SidebarFooter>
|
|
237
|
-
</SidebarContent>
|
|
238
|
-
|
|
239
|
-
<SidebarInset>
|
|
240
|
-
<SidebarTopBar>
|
|
241
|
-
<h1 className="adm:text-lg adm:font-semibold">Dashboard</h1>
|
|
242
|
-
<SidebarTrigger />
|
|
243
|
-
</SidebarTopBar>
|
|
244
|
-
<main className="adm:p-6">{/* Tu contenido aquí */}</main>
|
|
245
|
-
</SidebarInset>
|
|
246
|
-
</Sidebar>
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
## Hook Personalizado
|
|
252
|
-
|
|
253
|
-
### useSidebarContext()
|
|
254
|
-
|
|
255
|
-
Hook para acceder al contexto del Sidebar desde componentes hijos.
|
|
256
|
-
|
|
257
|
-
```tsx
|
|
258
|
-
import { useSidebarContext } from "@adamosuiteservices/ui/sidebar";
|
|
259
|
-
|
|
260
|
-
function CustomSidebarComponent() {
|
|
261
|
-
const { isXl, sidebarHeight, sheetOpen, setSheetOpen } = useSidebarContext();
|
|
262
|
-
|
|
263
|
-
return (
|
|
264
|
-
<div>
|
|
265
|
-
{isXl ? "Desktop" : "Mobile"}
|
|
266
|
-
<span>Height: {sidebarHeight}</span>
|
|
267
|
-
<button onClick={() => setSheetOpen(!sheetOpen)}>Toggle Sidebar</button>
|
|
268
|
-
</div>
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
**Retorna**:
|
|
274
|
-
| Propiedad | Tipo | Descripción |
|
|
275
|
-
|-----------|------|-------------|
|
|
276
|
-
| isXl | `boolean` | True si el viewport es >= 1280px |
|
|
277
|
-
| sidebarHeight | `string` | Altura calculada del sidebar ("auto" en desktop, px en mobile) |
|
|
278
|
-
| setSidebarHeight | `Dispatch<SetStateAction<string>>` | Setter para actualizar la altura |
|
|
279
|
-
| sheetOpen | `boolean` | Estado del Sheet en mobile (abierto/cerrado) |
|
|
280
|
-
| setSheetOpen | `Dispatch<SetStateAction<boolean>>` | Setter para controlar el estado del Sheet |
|
|
281
|
-
|
|
282
|
-
**Nota**: Este hook debe usarse dentro de un componente que sea hijo de `<Sidebar>`.
|
|
283
|
-
|
|
284
|
-
## Ejemplos Adicionales
|
|
285
|
-
|
|
286
|
-
### Items Básicos con Iconos
|
|
287
|
-
|
|
288
|
-
El ejemplo principal muestra el uso más simple - items como buttons con iconos:
|
|
289
|
-
|
|
290
|
-
```tsx
|
|
291
|
-
<SidebarMenu>
|
|
292
|
-
<SidebarMenuItem>
|
|
293
|
-
<Icon symbol="home" /> Dashboard
|
|
294
|
-
</SidebarMenuItem>
|
|
295
|
-
<SidebarMenuItem>
|
|
296
|
-
<Icon symbol="folder" /> Projects
|
|
297
|
-
</SidebarMenuItem>
|
|
298
|
-
<SidebarMenuItem>
|
|
299
|
-
<Icon symbol="settings" /> Settings
|
|
300
|
-
</SidebarMenuItem>
|
|
301
|
-
</SidebarMenu>
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
### Con React Router (usando asChild)
|
|
305
|
-
|
|
306
|
-
```tsx
|
|
307
|
-
import { Link } from "react-router-dom";
|
|
308
|
-
|
|
309
|
-
<SidebarMenu>
|
|
310
|
-
<SidebarMenuItem asChild>
|
|
311
|
-
<Link to="/dashboard">
|
|
312
|
-
<Icon symbol="home" /> Dashboard
|
|
313
|
-
</Link>
|
|
314
|
-
</SidebarMenuItem>
|
|
315
|
-
<SidebarMenuItem asChild>
|
|
316
|
-
<Link to="/settings">
|
|
317
|
-
<Icon symbol="settings" /> Settings
|
|
318
|
-
</Link>
|
|
319
|
-
</SidebarMenuItem>
|
|
320
|
-
</SidebarMenu>;
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
### Con Next.js (usando asChild)
|
|
324
|
-
|
|
325
|
-
```tsx
|
|
326
|
-
import Link from "next/link";
|
|
327
|
-
|
|
328
|
-
<SidebarMenu>
|
|
329
|
-
<SidebarMenuItem asChild>
|
|
330
|
-
<Link href="/dashboard">
|
|
331
|
-
<Icon symbol="home" /> Dashboard
|
|
332
|
-
</Link>
|
|
333
|
-
</SidebarMenuItem>
|
|
334
|
-
</SidebarMenu>;
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
### Estados Activos
|
|
338
|
-
|
|
339
|
-
```tsx
|
|
340
|
-
const pathname = usePathname(); // Next.js o similar
|
|
341
|
-
|
|
342
|
-
<SidebarMenu>
|
|
343
|
-
<SidebarMenuItem
|
|
344
|
-
className={pathname === "/dashboard" ? "adm:bg-white/20" : ""}
|
|
345
|
-
>
|
|
346
|
-
<Icon symbol="home" /> Dashboard
|
|
347
|
-
</SidebarMenuItem>
|
|
348
|
-
<SidebarMenuItem
|
|
349
|
-
className={pathname === "/settings" ? "adm:bg-white/20" : ""}
|
|
350
|
-
>
|
|
351
|
-
<Icon symbol="settings" /> Settings
|
|
352
|
-
</SidebarMenuItem>
|
|
353
|
-
</SidebarMenu>;
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
### Personalización de Colores
|
|
357
|
-
|
|
358
|
-
El sidebar usa variables CSS de tema. Puedes personalizarlas:
|
|
359
|
-
|
|
360
|
-
```css
|
|
361
|
-
:root {
|
|
362
|
-
--sidebar-primary: 220 13% 18%;
|
|
363
|
-
--sidebar-primary-foreground: 210 20% 98%;
|
|
364
|
-
}
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
## Notas de Implementación
|
|
368
|
-
|
|
369
|
-
- El componente usa internamente las clases con prefijo `adm:` para evitar conflictos de estilos
|
|
370
|
-
- `SidebarContent` usa Portal de Radix para renderizar en el top level del DOM
|
|
371
|
-
- El cambio responsive ocurre automáticamente en el breakpoint xl (1280px)
|
|
372
|
-
- En mobile, el Sheet se abre desde la izquierda
|
|
373
|
-
- `SidebarMenuItem` tiene hover effects y padding predefinidos
|
|
374
|
-
- `SidebarMenu` incluye scroll automático si el contenido excede la altura
|
|
375
|
-
- Los componentes usan `data-slot` attributes para debugging y testing:
|
|
376
|
-
- `sidebar` - Contenedor root
|
|
377
|
-
- `sidebar-content` - Contenido principal del sidebar
|
|
378
|
-
- `sidebar-trigger` - Botón hamburguesa para mobile
|
|
379
|
-
- `sidebar-inset` - Contenedor del contenido principal
|
|
380
|
-
- `sidebar-top-bar` - Barra superior (si se usa)
|
|
381
|
-
- `sidebar-header` - Header del sidebar
|
|
382
|
-
- `sidebar-footer` - Footer del sidebar
|
|
383
|
-
- `sidebar-menu` - Contenedor de items del menú
|
|
384
|
-
- `sidebar-menu-item` - Item individual del menú
|
|
385
|
-
|
|
386
|
-
## Accesibilidad
|
|
387
|
-
|
|
388
|
-
- ✅ El Sheet en mobile incluye SheetTitle y SheetDescription (ocultos visualmente)
|
|
389
|
-
- ✅ Navegación por teclado soportada en todos los items
|
|
390
|
-
- ✅ Focus visible en items del menú
|
|
391
|
-
- ✅ Semántica HTML correcta (nav, header, footer)
|
|
392
|
-
- ✅ ARIA labels automáticos en el Sheet trigger
|
|
393
|
-
|
|
394
|
-
## Referencias
|
|
395
|
-
|
|
396
|
-
- Similar a shadcn/ui Sidebar pattern
|
|
397
|
-
- Usa Radix UI Portal para rendering
|
|
398
|
-
- Usa Radix UI Sheet para modal mobile
|
|
399
|
-
- Implementa useMediaQuery de @uidotdev/usehooks
|
|
1
|
+
# Sidebar Component
|
|
2
|
+
|
|
3
|
+
## Descripción
|
|
4
|
+
|
|
5
|
+
El componente `Sidebar` es un layout component que proporciona navegación lateral responsive. En desktop muestra un sidebar fijo lateral, mientras que en mobile se convierte automáticamente en un menú Sheet desplegable con icono hamburguesa.
|
|
6
|
+
|
|
7
|
+
## Importación
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import {
|
|
11
|
+
Sidebar,
|
|
12
|
+
SidebarContent,
|
|
13
|
+
SidebarInset,
|
|
14
|
+
SidebarTopBar,
|
|
15
|
+
SidebarTrigger,
|
|
16
|
+
SidebarHeader,
|
|
17
|
+
SidebarFooter,
|
|
18
|
+
SidebarMenu,
|
|
19
|
+
SidebarMenuItem,
|
|
20
|
+
} from "@adamosuiteservices/ui/sidebar";
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Nota**: Si usas `SidebarMenuItem` con `asChild`, también puedes importar componentes de navegación:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { Link } from "react-router-dom"; // o Next.js Link
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Uso Básico
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<Sidebar>
|
|
33
|
+
<SidebarContent>
|
|
34
|
+
<SidebarHeader className="adm:items-center">
|
|
35
|
+
{/* Logo o título */}
|
|
36
|
+
</SidebarHeader>
|
|
37
|
+
|
|
38
|
+
<SidebarMenu>
|
|
39
|
+
<SidebarMenuItem>
|
|
40
|
+
<Icon symbol="home" /> Dashboard
|
|
41
|
+
</SidebarMenuItem>
|
|
42
|
+
<SidebarMenuItem>
|
|
43
|
+
<Icon symbol="folder" /> Projects
|
|
44
|
+
</SidebarMenuItem>
|
|
45
|
+
<SidebarMenuItem>
|
|
46
|
+
<Icon symbol="settings" /> Settings
|
|
47
|
+
</SidebarMenuItem>
|
|
48
|
+
</SidebarMenu>
|
|
49
|
+
|
|
50
|
+
<SidebarFooter>
|
|
51
|
+
<SidebarMenuItem>
|
|
52
|
+
<Icon symbol="account_circle" /> Profile
|
|
53
|
+
</SidebarMenuItem>
|
|
54
|
+
</SidebarFooter>
|
|
55
|
+
</SidebarContent>
|
|
56
|
+
|
|
57
|
+
<SidebarInset>
|
|
58
|
+
<SidebarTopBar>
|
|
59
|
+
<h1 className="adm:text-lg adm:font-semibold">Dashboard</h1>
|
|
60
|
+
<SidebarTrigger />
|
|
61
|
+
</SidebarTopBar>
|
|
62
|
+
{/* Contenido principal */}
|
|
63
|
+
</SidebarInset>
|
|
64
|
+
</Sidebar>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Componentes
|
|
68
|
+
|
|
69
|
+
### Sidebar (Root)
|
|
70
|
+
|
|
71
|
+
Contenedor principal con context provider.
|
|
72
|
+
|
|
73
|
+
### SidebarContent
|
|
74
|
+
|
|
75
|
+
Contenido del sidebar con Portal para posicionamiento fijo.
|
|
76
|
+
|
|
77
|
+
### SidebarInset
|
|
78
|
+
|
|
79
|
+
Contenedor para el contenido principal que se ajusta al sidebar.
|
|
80
|
+
|
|
81
|
+
### SidebarTopBar
|
|
82
|
+
|
|
83
|
+
Barra superior sticky para el contenido principal, ideal para incluir el trigger del sidebar y el título de la página.
|
|
84
|
+
|
|
85
|
+
### SidebarTrigger
|
|
86
|
+
|
|
87
|
+
Botón hamburguesa que abre/cierra el sidebar en mobile. Automáticamente oculto en desktop (xl+).
|
|
88
|
+
|
|
89
|
+
### SidebarHeader
|
|
90
|
+
|
|
91
|
+
Sección superior del sidebar.
|
|
92
|
+
|
|
93
|
+
### SidebarFooter
|
|
94
|
+
|
|
95
|
+
Sección inferior del sidebar.
|
|
96
|
+
|
|
97
|
+
### SidebarMenu
|
|
98
|
+
|
|
99
|
+
Contenedor para items de menú con scroll.
|
|
100
|
+
|
|
101
|
+
### SidebarMenuItem
|
|
102
|
+
|
|
103
|
+
Item individual del menú con hover effects.
|
|
104
|
+
|
|
105
|
+
## Responsive
|
|
106
|
+
|
|
107
|
+
- **Desktop (xl+)**: Sidebar fijo lateral (256px de ancho)
|
|
108
|
+
- **Mobile**: Sidebar en Sheet (modal lateral)
|
|
109
|
+
- Incluye icono hamburguesa automático en mobile
|
|
110
|
+
|
|
111
|
+
## Props
|
|
112
|
+
|
|
113
|
+
### Sidebar
|
|
114
|
+
|
|
115
|
+
| Prop | Tipo | Descripción |
|
|
116
|
+
| -------- | ----------- | --------------------------------------------------- |
|
|
117
|
+
| children | `ReactNode` | Contenido del sidebar (debe incluir SidebarContent) |
|
|
118
|
+
|
|
119
|
+
### SidebarContent
|
|
120
|
+
|
|
121
|
+
| Prop | Tipo | Descripción |
|
|
122
|
+
| --------- | ----------------------- | ------------------------------------- |
|
|
123
|
+
| className | `string` | Clases adicionales para el contenedor |
|
|
124
|
+
| children | `ReactNode` | Contenido del sidebar |
|
|
125
|
+
| ...props | `ComponentProps<"div">` | Props nativas de div |
|
|
126
|
+
|
|
127
|
+
### SidebarInset
|
|
128
|
+
|
|
129
|
+
| Prop | Tipo | Descripción |
|
|
130
|
+
| --------- | ----------------------- | ------------------------------------ |
|
|
131
|
+
| className | `string` | Clases adicionales |
|
|
132
|
+
| children | `ReactNode` | Contenido principal de la aplicación |
|
|
133
|
+
| ...props | `ComponentProps<"div">` | Props nativas de div |
|
|
134
|
+
|
|
135
|
+
### SidebarTopBar
|
|
136
|
+
|
|
137
|
+
| Prop | Tipo | Descripción |
|
|
138
|
+
| --------- | ----------------------- | ------------------------------------------------- |
|
|
139
|
+
| className | `string` | Clases adicionales |
|
|
140
|
+
| children | `ReactNode` | Contenido de la barra (trigger, título, acciones) |
|
|
141
|
+
| ...props | `ComponentProps<"div">` | Props nativas de div |
|
|
142
|
+
|
|
143
|
+
**Estilos por defecto**: sticky, top-0, flex, gap-2, items-center, justify-between, bg-background, p-4, border-b
|
|
144
|
+
|
|
145
|
+
### SidebarTrigger
|
|
146
|
+
|
|
147
|
+
| Prop | Tipo | Descripción |
|
|
148
|
+
| --------- | -------------------------- | ----------------------- |
|
|
149
|
+
| className | `string` | Clases adicionales |
|
|
150
|
+
| ...props | `ComponentProps<"button">` | Props nativas de button |
|
|
151
|
+
|
|
152
|
+
**Comportamiento**: Oculto automáticamente en desktop (xl:hidden). Incluye icono menu de Material Symbols.
|
|
153
|
+
|
|
154
|
+
### SidebarHeader
|
|
155
|
+
|
|
156
|
+
| Prop | Tipo | Descripción |
|
|
157
|
+
| --------- | -------------------------- | ----------------------------------- |
|
|
158
|
+
| className | `string` | Clases adicionales |
|
|
159
|
+
| children | `ReactNode` | Contenido del header (logo, título) |
|
|
160
|
+
| ...props | `ComponentProps<"header">` | Props nativas de header |
|
|
161
|
+
|
|
162
|
+
### SidebarFooter
|
|
163
|
+
|
|
164
|
+
| Prop | Tipo | Descripción |
|
|
165
|
+
| --------- | -------------------------- | -------------------------------------- |
|
|
166
|
+
| className | `string` | Clases adicionales |
|
|
167
|
+
| children | `ReactNode` | Contenido del footer (usuario, logout) |
|
|
168
|
+
| ...props | `ComponentProps<"footer">` | Props nativas de footer |
|
|
169
|
+
|
|
170
|
+
### SidebarMenu
|
|
171
|
+
|
|
172
|
+
| Prop | Tipo | Descripción |
|
|
173
|
+
| --------- | ----------------------- | -------------------------------- |
|
|
174
|
+
| className | `string` | Clases adicionales |
|
|
175
|
+
| children | `ReactNode` | Items del menú (SidebarMenuItem) |
|
|
176
|
+
| ...props | `ComponentProps<"div">` | Props nativas de div |
|
|
177
|
+
|
|
178
|
+
### SidebarMenuItem
|
|
179
|
+
|
|
180
|
+
| Prop | Tipo | Default | Descripción |
|
|
181
|
+
| --------- | -------------------------- | ------- | ----------------------------------------------------------- |
|
|
182
|
+
| asChild | `boolean` | `false` | Si es true, renderiza el hijo directo en lugar de un button |
|
|
183
|
+
| className | `string` | - | Clases adicionales |
|
|
184
|
+
| ...props | `ComponentProps<"button">` | - | Props nativas de button |
|
|
185
|
+
|
|
186
|
+
## Características Principales
|
|
187
|
+
|
|
188
|
+
- **Responsive automático**: Desktop muestra sidebar fijo, mobile usa Sheet con hamburger
|
|
189
|
+
- **Auto-manejo del height**: Previene layout shifts al calcular altura automáticamente
|
|
190
|
+
- **Breakpoint xl (1280px)**: Usa `useMediaQuery` para detectar el cambio
|
|
191
|
+
- **Portal rendering**: Usa Radix Portal para z-index correcto
|
|
192
|
+
- **Sheet integration**: Integración nativa con componente Sheet para mobile
|
|
193
|
+
- **Accesibilidad**: Incluye VisuallyHidden para screen readers
|
|
194
|
+
- **Sticky positioning**: Sidebar fijo en desktop con scroll independiente del contenido
|
|
195
|
+
|
|
196
|
+
## Ejemplo Completo
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
import {
|
|
200
|
+
Sidebar,
|
|
201
|
+
SidebarContent,
|
|
202
|
+
SidebarFooter,
|
|
203
|
+
SidebarHeader,
|
|
204
|
+
SidebarInset,
|
|
205
|
+
SidebarMenu,
|
|
206
|
+
SidebarMenuItem,
|
|
207
|
+
SidebarTopBar,
|
|
208
|
+
SidebarTrigger,
|
|
209
|
+
} from "@adamosuiteservices/ui/sidebar";
|
|
210
|
+
import { Icon } from "@adamosuiteservices/ui/icon";
|
|
211
|
+
|
|
212
|
+
export default function AppLayout() {
|
|
213
|
+
return (
|
|
214
|
+
<Sidebar>
|
|
215
|
+
<SidebarContent>
|
|
216
|
+
<SidebarHeader className="adm:items-center">
|
|
217
|
+
<Logo />
|
|
218
|
+
</SidebarHeader>
|
|
219
|
+
|
|
220
|
+
<SidebarMenu>
|
|
221
|
+
<SidebarMenuItem>
|
|
222
|
+
<Icon symbol="home" /> Dashboard
|
|
223
|
+
</SidebarMenuItem>
|
|
224
|
+
<SidebarMenuItem>
|
|
225
|
+
<Icon symbol="folder" /> Projects
|
|
226
|
+
</SidebarMenuItem>
|
|
227
|
+
<SidebarMenuItem>
|
|
228
|
+
<Icon symbol="settings" /> Settings
|
|
229
|
+
</SidebarMenuItem>
|
|
230
|
+
</SidebarMenu>
|
|
231
|
+
|
|
232
|
+
<SidebarFooter>
|
|
233
|
+
<SidebarMenuItem>
|
|
234
|
+
<Icon symbol="account_circle" /> Profile
|
|
235
|
+
</SidebarMenuItem>
|
|
236
|
+
</SidebarFooter>
|
|
237
|
+
</SidebarContent>
|
|
238
|
+
|
|
239
|
+
<SidebarInset>
|
|
240
|
+
<SidebarTopBar>
|
|
241
|
+
<h1 className="adm:text-lg adm:font-semibold">Dashboard</h1>
|
|
242
|
+
<SidebarTrigger />
|
|
243
|
+
</SidebarTopBar>
|
|
244
|
+
<main className="adm:p-6">{/* Tu contenido aquí */}</main>
|
|
245
|
+
</SidebarInset>
|
|
246
|
+
</Sidebar>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Hook Personalizado
|
|
252
|
+
|
|
253
|
+
### useSidebarContext()
|
|
254
|
+
|
|
255
|
+
Hook para acceder al contexto del Sidebar desde componentes hijos.
|
|
256
|
+
|
|
257
|
+
```tsx
|
|
258
|
+
import { useSidebarContext } from "@adamosuiteservices/ui/sidebar";
|
|
259
|
+
|
|
260
|
+
function CustomSidebarComponent() {
|
|
261
|
+
const { isXl, sidebarHeight, sheetOpen, setSheetOpen } = useSidebarContext();
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
<div>
|
|
265
|
+
{isXl ? "Desktop" : "Mobile"}
|
|
266
|
+
<span>Height: {sidebarHeight}</span>
|
|
267
|
+
<button onClick={() => setSheetOpen(!sheetOpen)}>Toggle Sidebar</button>
|
|
268
|
+
</div>
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Retorna**:
|
|
274
|
+
| Propiedad | Tipo | Descripción |
|
|
275
|
+
|-----------|------|-------------|
|
|
276
|
+
| isXl | `boolean` | True si el viewport es >= 1280px |
|
|
277
|
+
| sidebarHeight | `string` | Altura calculada del sidebar ("auto" en desktop, px en mobile) |
|
|
278
|
+
| setSidebarHeight | `Dispatch<SetStateAction<string>>` | Setter para actualizar la altura |
|
|
279
|
+
| sheetOpen | `boolean` | Estado del Sheet en mobile (abierto/cerrado) |
|
|
280
|
+
| setSheetOpen | `Dispatch<SetStateAction<boolean>>` | Setter para controlar el estado del Sheet |
|
|
281
|
+
|
|
282
|
+
**Nota**: Este hook debe usarse dentro de un componente que sea hijo de `<Sidebar>`.
|
|
283
|
+
|
|
284
|
+
## Ejemplos Adicionales
|
|
285
|
+
|
|
286
|
+
### Items Básicos con Iconos
|
|
287
|
+
|
|
288
|
+
El ejemplo principal muestra el uso más simple - items como buttons con iconos:
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
<SidebarMenu>
|
|
292
|
+
<SidebarMenuItem>
|
|
293
|
+
<Icon symbol="home" /> Dashboard
|
|
294
|
+
</SidebarMenuItem>
|
|
295
|
+
<SidebarMenuItem>
|
|
296
|
+
<Icon symbol="folder" /> Projects
|
|
297
|
+
</SidebarMenuItem>
|
|
298
|
+
<SidebarMenuItem>
|
|
299
|
+
<Icon symbol="settings" /> Settings
|
|
300
|
+
</SidebarMenuItem>
|
|
301
|
+
</SidebarMenu>
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Con React Router (usando asChild)
|
|
305
|
+
|
|
306
|
+
```tsx
|
|
307
|
+
import { Link } from "react-router-dom";
|
|
308
|
+
|
|
309
|
+
<SidebarMenu>
|
|
310
|
+
<SidebarMenuItem asChild>
|
|
311
|
+
<Link to="/dashboard">
|
|
312
|
+
<Icon symbol="home" /> Dashboard
|
|
313
|
+
</Link>
|
|
314
|
+
</SidebarMenuItem>
|
|
315
|
+
<SidebarMenuItem asChild>
|
|
316
|
+
<Link to="/settings">
|
|
317
|
+
<Icon symbol="settings" /> Settings
|
|
318
|
+
</Link>
|
|
319
|
+
</SidebarMenuItem>
|
|
320
|
+
</SidebarMenu>;
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Con Next.js (usando asChild)
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
import Link from "next/link";
|
|
327
|
+
|
|
328
|
+
<SidebarMenu>
|
|
329
|
+
<SidebarMenuItem asChild>
|
|
330
|
+
<Link href="/dashboard">
|
|
331
|
+
<Icon symbol="home" /> Dashboard
|
|
332
|
+
</Link>
|
|
333
|
+
</SidebarMenuItem>
|
|
334
|
+
</SidebarMenu>;
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Estados Activos
|
|
338
|
+
|
|
339
|
+
```tsx
|
|
340
|
+
const pathname = usePathname(); // Next.js o similar
|
|
341
|
+
|
|
342
|
+
<SidebarMenu>
|
|
343
|
+
<SidebarMenuItem
|
|
344
|
+
className={pathname === "/dashboard" ? "adm:bg-white/20" : ""}
|
|
345
|
+
>
|
|
346
|
+
<Icon symbol="home" /> Dashboard
|
|
347
|
+
</SidebarMenuItem>
|
|
348
|
+
<SidebarMenuItem
|
|
349
|
+
className={pathname === "/settings" ? "adm:bg-white/20" : ""}
|
|
350
|
+
>
|
|
351
|
+
<Icon symbol="settings" /> Settings
|
|
352
|
+
</SidebarMenuItem>
|
|
353
|
+
</SidebarMenu>;
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Personalización de Colores
|
|
357
|
+
|
|
358
|
+
El sidebar usa variables CSS de tema. Puedes personalizarlas:
|
|
359
|
+
|
|
360
|
+
```css
|
|
361
|
+
:root {
|
|
362
|
+
--sidebar-primary: 220 13% 18%;
|
|
363
|
+
--sidebar-primary-foreground: 210 20% 98%;
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Notas de Implementación
|
|
368
|
+
|
|
369
|
+
- El componente usa internamente las clases con prefijo `adm:` para evitar conflictos de estilos
|
|
370
|
+
- `SidebarContent` usa Portal de Radix para renderizar en el top level del DOM
|
|
371
|
+
- El cambio responsive ocurre automáticamente en el breakpoint xl (1280px)
|
|
372
|
+
- En mobile, el Sheet se abre desde la izquierda
|
|
373
|
+
- `SidebarMenuItem` tiene hover effects y padding predefinidos
|
|
374
|
+
- `SidebarMenu` incluye scroll automático si el contenido excede la altura
|
|
375
|
+
- Los componentes usan `data-slot` attributes para debugging y testing:
|
|
376
|
+
- `sidebar` - Contenedor root
|
|
377
|
+
- `sidebar-content` - Contenido principal del sidebar
|
|
378
|
+
- `sidebar-trigger` - Botón hamburguesa para mobile
|
|
379
|
+
- `sidebar-inset` - Contenedor del contenido principal
|
|
380
|
+
- `sidebar-top-bar` - Barra superior (si se usa)
|
|
381
|
+
- `sidebar-header` - Header del sidebar
|
|
382
|
+
- `sidebar-footer` - Footer del sidebar
|
|
383
|
+
- `sidebar-menu` - Contenedor de items del menú
|
|
384
|
+
- `sidebar-menu-item` - Item individual del menú
|
|
385
|
+
|
|
386
|
+
## Accesibilidad
|
|
387
|
+
|
|
388
|
+
- ✅ El Sheet en mobile incluye SheetTitle y SheetDescription (ocultos visualmente)
|
|
389
|
+
- ✅ Navegación por teclado soportada en todos los items
|
|
390
|
+
- ✅ Focus visible en items del menú
|
|
391
|
+
- ✅ Semántica HTML correcta (nav, header, footer)
|
|
392
|
+
- ✅ ARIA labels automáticos en el Sheet trigger
|
|
393
|
+
|
|
394
|
+
## Referencias
|
|
395
|
+
|
|
396
|
+
- Similar a shadcn/ui Sidebar pattern
|
|
397
|
+
- Usa Radix UI Portal para rendering
|
|
398
|
+
- Usa Radix UI Sheet para modal mobile
|
|
399
|
+
- Implementa useMediaQuery de @uidotdev/usehooks
|