siesa-ui-kit 1.0.2 → 1.0.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/README.md +115 -115
- package/bin/install.cjs +502 -502
- package/bin/prepare-publish.cjs +28 -28
- package/bin/restore-folders.cjs +28 -28
- package/claude/agents/siesa-ui-kit-specialist.md +2445 -0
- package/claude/prompts/component-template.md +121 -0
- package/claude/prompts/siesa-ui-kit.md +28 -0
- package/claude/settings.local.json +67 -2
- package/dist/components/Button/icons.d.ts +6 -5
- package/dist/components/Button/icons.d.ts.map +1 -1
- package/dist/components/DropdownItemCollapsible/DropdownItemCollapsible.d.ts.map +1 -1
- package/dist/components/DropdownItemCollapsible/DropdownItemCollapsible.types.d.ts +21 -0
- package/dist/components/DropdownItemCollapsible/DropdownItemCollapsible.types.d.ts.map +1 -1
- package/dist/components/NavigationRailCommercial/NavigationRailCommercial.d.ts +122 -0
- package/dist/components/NavigationRailCommercial/NavigationRailCommercial.d.ts.map +1 -0
- package/dist/components/NavigationRailCommercial/NavigationRailCommercial.types.d.ts +139 -0
- package/dist/components/NavigationRailCommercial/NavigationRailCommercial.types.d.ts.map +1 -0
- package/dist/components/NavigationRailCommercial/icons.d.ts +33 -0
- package/dist/components/NavigationRailCommercial/icons.d.ts.map +1 -0
- package/dist/components/NavigationRailCommercial/index.d.ts +4 -0
- package/dist/components/NavigationRailCommercial/index.d.ts.map +1 -0
- package/dist/components/NavigationRailItem/NavigationRailItem.d.ts.map +1 -1
- package/dist/components/NavigationRailItem/NavigationRailItem.types.d.ts +7 -0
- package/dist/components/NavigationRailItem/NavigationRailItem.types.d.ts.map +1 -1
- package/dist/components/NavigationRailTypes/NavigationRailTypes.d.ts.map +1 -1
- package/dist/components/NavigationRailTypes/NavigationRailTypes.types.d.ts +41 -0
- package/dist/components/NavigationRailTypes/NavigationRailTypes.types.d.ts.map +1 -1
- package/dist/components/NavigationRailTypes/icons.d.ts +15 -29
- package/dist/components/NavigationRailTypes/icons.d.ts.map +1 -1
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/icons.d.ts +6 -2
- package/dist/components/Select/icons.d.ts.map +1 -1
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/siesa-ui-kit.cjs +404 -190
- package/dist/siesa-ui-kit.cjs.map +1 -1
- package/dist/siesa-ui-kit.mjs +6590 -1506
- package/dist/siesa-ui-kit.mjs.map +1 -1
- package/dist/views/LayoutCommercial/LayoutCommercial.d.ts +48 -0
- package/dist/views/LayoutCommercial/LayoutCommercial.d.ts.map +1 -0
- package/dist/views/LayoutCommercial/LayoutCommercial.types.d.ts +49 -0
- package/dist/views/LayoutCommercial/LayoutCommercial.types.d.ts.map +1 -0
- package/dist/views/LayoutCommercial/index.d.ts +3 -0
- package/dist/views/LayoutCommercial/index.d.ts.map +1 -0
- package/docs/icons.md +12 -31
- package/package.json +111 -110
- package/src/components/Avatar/Avatar.stories.tsx +494 -494
- package/src/components/Button/Button.stories.tsx +950 -950
- package/src/components/Button/Button.tsx +337 -337
- package/src/components/Button/Button.types.ts +180 -180
- package/src/components/Button/icons.tsx +23 -62
- package/src/components/DescriptionList/DescriptionList.stories.tsx +250 -250
- package/src/components/Divider/Divider.stories.tsx +263 -263
- package/src/components/DropdownItemCollapsible/DropdownItemCollapsible.stories.tsx +317 -317
- package/src/components/DropdownItemCollapsible/DropdownItemCollapsible.tsx +307 -287
- package/src/components/DropdownItemCollapsible/DropdownItemCollapsible.types.ts +136 -111
- package/src/components/DropdownItemCollapsible/README.md +264 -264
- package/src/components/DropdownItemCollapsible/icons.tsx +57 -57
- package/src/components/DropdownItemCollapsible/index.ts +12 -12
- package/src/components/DropdownItemHeading/DropdownItemHeading.stories.tsx +386 -386
- package/src/components/DropdownItemHeading/DropdownItemHeading.tsx +216 -216
- package/src/components/DropdownItemHeading/DropdownItemHeading.types.ts +93 -93
- package/src/components/DropdownItemHeading/README.md +573 -573
- package/src/components/DropdownItemHeading/icons.tsx +125 -125
- package/src/components/DropdownItemHeading/index.ts +3 -3
- package/src/components/Input/Input.stories.tsx +583 -583
- package/src/components/LoginView/LoginView.stories.tsx +148 -148
- package/src/components/LoginView/LoginView.tsx +426 -426
- package/src/components/LoginView/LoginView.types.ts +52 -52
- package/src/components/LoginView/README.md +396 -396
- package/src/components/LoginView/icons.tsx +85 -85
- package/src/components/LoginView/index.ts +3 -3
- package/src/components/Navbar/Navbar.stories.tsx +810 -810
- package/src/components/Navbar/Navbar.tsx +755 -755
- package/src/components/Navbar/Navbar.types.ts +219 -219
- package/src/components/Navbar/README.md +279 -279
- package/src/components/Navbar/index.ts +8 -8
- package/src/components/NavigationRailCommercial/NavigationRailCommercial.stories.tsx +464 -0
- package/src/components/NavigationRailCommercial/NavigationRailCommercial.tsx +301 -0
- package/src/components/NavigationRailCommercial/NavigationRailCommercial.types.ts +162 -0
- package/src/components/NavigationRailCommercial/README.md +251 -0
- package/src/components/NavigationRailCommercial/icons.tsx +54 -0
- package/src/components/NavigationRailCommercial/index.ts +6 -0
- package/src/components/NavigationRailItem/NavigationRailItem.stories.tsx +667 -667
- package/src/components/NavigationRailItem/NavigationRailItem.tsx +314 -313
- package/src/components/NavigationRailItem/NavigationRailItem.types.ts +175 -167
- package/src/components/NavigationRailItem/README.md +476 -476
- package/src/components/NavigationRailItem/index.ts +2 -2
- package/src/components/NavigationRailPanel/NavigationRailPanel.stories.tsx +462 -462
- package/src/components/NavigationRailPanel/NavigationRailPanel.tsx +332 -332
- package/src/components/NavigationRailPanel/NavigationRailPanel.types.ts +178 -178
- package/src/components/NavigationRailPanel/README.md +461 -461
- package/src/components/NavigationRailPanel/index.ts +6 -6
- package/src/components/NavigationRailTypes/NavigationRailTypes.stories.tsx +682 -528
- package/src/components/NavigationRailTypes/NavigationRailTypes.tsx +363 -378
- package/src/components/NavigationRailTypes/NavigationRailTypes.types.ts +178 -130
- package/src/components/NavigationRailTypes/README.md +573 -573
- package/src/components/NavigationRailTypes/icons.tsx +76 -141
- package/src/components/NavigationRailTypes/index.ts +7 -7
- package/src/components/Notification/Notification.stories.tsx +513 -513
- package/src/components/Notification/Notification.tsx +145 -145
- package/src/components/Notification/Notification.types.ts +142 -142
- package/src/components/Notification/README.md +409 -409
- package/src/components/POSConvention/POSConvention.stories.tsx +235 -235
- package/src/components/POSConvention/POSConvention.tsx +129 -129
- package/src/components/POSConvention/POSConvention.types.ts +38 -38
- package/src/components/POSConvention/README.md +123 -123
- package/src/components/POSConvention/icons.tsx +45 -45
- package/src/components/POSConvention/index.ts +3 -3
- package/src/components/POSLocationButton/POSLocationButton.stories.tsx +531 -531
- package/src/components/POSLocationButton/POSLocationButton.tsx +247 -247
- package/src/components/POSLocationButton/POSLocationButton.types.ts +87 -87
- package/src/components/POSLocationButton/README.md +253 -253
- package/src/components/POSLocationButton/icons.tsx +120 -120
- package/src/components/POSLocationButton/index.ts +14 -14
- package/src/components/POSNumberButton/POSNumberButton.stories.tsx +415 -415
- package/src/components/POSNumberButton/POSNumberButton.tsx +179 -179
- package/src/components/POSNumberButton/POSNumberButton.types.ts +51 -51
- package/src/components/POSNumberButton/README.md +321 -321
- package/src/components/POSNumberButton/index.ts +3 -3
- package/src/components/POSProductButton/POSProductButton.stories.tsx +318 -318
- package/src/components/POSProductCard/POSProductCard.stories.tsx +642 -642
- package/src/components/POSProductCard/POSProductCard.tsx +208 -208
- package/src/components/POSProductCard/POSProductCard.types.ts +76 -76
- package/src/components/POSProductCard/README.md +179 -179
- package/src/components/POSProductCard/icons.tsx +26 -26
- package/src/components/POSProductCard/index.ts +2 -2
- package/src/components/POSProductSidebarItems/POSProductSidebarItems.stories.tsx +753 -753
- package/src/components/POSProductSidebarItems/POSProductSidebarItems.tsx +332 -332
- package/src/components/POSProductSidebarItems/POSProductSidebarItems.types.ts +119 -119
- package/src/components/POSProductSidebarItems/README.md +198 -198
- package/src/components/POSProductSidebarItems/icons.tsx +21 -21
- package/src/components/POSProductSidebarItems/index.ts +3 -3
- package/src/components/POSTable/POSTable.stories.tsx +737 -737
- package/src/components/POSTable/POSTable.tsx +401 -401
- package/src/components/POSTable/README.md +286 -286
- package/src/components/Quantity/Quantity.stories.tsx +457 -457
- package/src/components/Radio/Radio.stories.tsx +523 -523
- package/src/components/Radio/Radio.tsx +1 -1
- package/src/components/Select/Select.stories.tsx +32 -0
- package/src/components/Select/Select.tsx +457 -454
- package/src/components/Select/icons.tsx +16 -41
- package/src/components/SignUpView/SignUpView.stories.tsx +129 -129
- package/src/components/SignUpView/SignUpView.tsx +503 -503
- package/src/components/SignUpView/SignUpView.types.ts +58 -58
- package/src/components/SignUpView/icons.tsx +71 -71
- package/src/components/SignUpView/index.ts +3 -3
- package/src/components/Switch/README.md +112 -112
- package/src/components/Switch/Switch.stories.tsx +550 -550
- package/src/components/Switch/Switch.tsx +246 -246
- package/src/components/Switch/Switch.types.ts +67 -67
- package/src/components/Table/Table.stories.tsx +805 -805
- package/src/components/Tabs/README.md +201 -201
- package/src/components/Tabs/Tabs.stories.tsx +580 -580
- package/src/components/Tabs/Tabs.tsx +356 -356
- package/src/components/Tabs/Tabs.types.ts +127 -127
- package/src/components/Tabs/icons.tsx +129 -129
- package/src/components/Tabs/index.ts +11 -11
- package/src/components/Textarea/Textarea.stories.tsx +535 -535
- package/src/index.ts +133 -102
- package/src/views/LayoutCommercial/LayoutCommercial.stories.tsx +374 -0
- package/src/views/LayoutCommercial/LayoutCommercial.tsx +125 -0
- package/src/views/LayoutCommercial/LayoutCommercial.types.ts +54 -0
- package/src/views/LayoutCommercial/README.md +286 -0
- package/src/views/LayoutCommercial/index.ts +2 -0
- package/src/views/ListView/ListView.stories.tsx +329 -329
- package/src/views/ListView/ListView.tsx +570 -570
- package/src/views/ListView/ListView.types.ts +211 -211
- package/src/views/ListView/icons.tsx +282 -282
- package/src/views/ListView/index.ts +11 -11
- package/src/views/LoginView/LoginView.tsx +426 -426
- package/src/views/ProductsView/ProductsView.stories.tsx +344 -344
- package/src/views/ProductsView/ProductsView.tsx +480 -480
- package/src/views/ProductsView/ProductsView.types.ts +238 -238
- package/src/views/ProductsView/README.md +312 -312
- package/src/views/ProductsView/icons.tsx +38 -38
- package/src/views/ProductsView/index.ts +8 -8
- package/src/views/RecoverPasswordView/RecoverPasswordView.tsx +376 -376
- package/src/views/SignUpView/SignUpView.tsx +503 -503
- package/src/views/TableLayoutView/README.md +268 -268
- package/src/views/TableLayoutView/TableLayoutView.stories.tsx +235 -235
- package/src/views/TableLayoutView/TableLayoutView.tsx +461 -461
- package/src/views/TableLayoutView/TableLayoutView.types.ts +209 -209
- package/src/views/TableLayoutView/icons.tsx +113 -113
- package/src/views/TableLayoutView/index.ts +6 -6
- package/storybook/main.ts +19 -19
- package/storybook/preview.tsx +84 -84
- package/storybook/vitest.setup.ts +6 -6
- package/tailwind.config.js +128 -128
|
@@ -1,332 +1,332 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import type { NavigationRailPanelProps } from './NavigationRailPanel.types';
|
|
3
|
-
import { DropdownItemHeading } from '../DropdownItemHeading';
|
|
4
|
-
import { DropdownItemCollapsible } from '../DropdownItemCollapsible';
|
|
5
|
-
import { Input } from '../Input';
|
|
6
|
-
import { Divider } from '../Divider/Divider';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Componente NavigationRailPanel del sistema de diseño Siesa
|
|
10
|
-
*
|
|
11
|
-
* Panel de navegación vertical (rail) que puede contener múltiples secciones
|
|
12
|
-
* de items, búsqueda y encabezados. Se usa típicamente en aplicaciones con
|
|
13
|
-
* navegación compleja que requieren una estructura jerárquica.
|
|
14
|
-
*
|
|
15
|
-
* **Estructura principal:**
|
|
16
|
-
* 1. Encabezado (DropdownItemHeading) - Opcional
|
|
17
|
-
* 2. Input de búsqueda - Opcional
|
|
18
|
-
* 3. Divisor - Siempre presente después de búsqueda/encabezado
|
|
19
|
-
* 4. Body con secciones de items:
|
|
20
|
-
* - Heading de sección (Paragraph/Tiny, content-tertiary)
|
|
21
|
-
* - Items colapsables (DropdownItemCollapsible) o simples
|
|
22
|
-
* - Divisor entre secciones
|
|
23
|
-
*
|
|
24
|
-
* **Dimensiones según Figma:**
|
|
25
|
-
* - Altura: Variable (por defecto 900px)
|
|
26
|
-
* - Ancho del panel: 248px (con padding 12px)
|
|
27
|
-
* - Ancho de contenido: 224px
|
|
28
|
-
* - Padding del panel: 12px
|
|
29
|
-
* - Padding del body: 12px
|
|
30
|
-
* - Border: 1px left (border-primary)
|
|
31
|
-
* - Border radius: 0px (es un panel recto)
|
|
32
|
-
*
|
|
33
|
-
* **Tipografía:**
|
|
34
|
-
* - Heading (DropdownItemHeading): Label/Small (14px Bold)
|
|
35
|
-
* - Section heading: Paragraph/Tiny (12px Regular) - content-tertiary
|
|
36
|
-
* - Items: Paragraph/Small (14px Regular)
|
|
37
|
-
*
|
|
38
|
-
* **Colores (Light Mode):**
|
|
39
|
-
* - Background: #ffffff (white)
|
|
40
|
-
* - Border: #e4e4e7 (border-primary)
|
|
41
|
-
* - Heading text: #18181b (content-primary)
|
|
42
|
-
* - Section heading: #71717a (content-tertiary)
|
|
43
|
-
* - Item text: #18181b (content-primary)
|
|
44
|
-
* - Icon color: #a1a1aa (content-secondary)
|
|
45
|
-
*
|
|
46
|
-
* **Colores (Dark Mode):**
|
|
47
|
-
* - Background: #18181b (dark bg)
|
|
48
|
-
* - Border: #3f3f46 (border-primary/dark)
|
|
49
|
-
* - Heading text: #fafafa (content-primary/dark)
|
|
50
|
-
* - Section heading: #a1a1aa (content-tertiary/dark)
|
|
51
|
-
* - Item text: #fafafa (content-primary/dark)
|
|
52
|
-
* - Icon color: #a1a1aa (content-secondary/dark)
|
|
53
|
-
*
|
|
54
|
-
* **Estados:**
|
|
55
|
-
* - Default: Sin interacción
|
|
56
|
-
* - Hover: Items con hover overlay sutil
|
|
57
|
-
* - Focus: Focus ring adaptativo
|
|
58
|
-
* - Disabled: Opacidad 50%
|
|
59
|
-
* - Active (items colapsables): Expanded state
|
|
60
|
-
*
|
|
61
|
-
* **Espaciado interno:**
|
|
62
|
-
* - Gap entre section heading e items: 0.5 (2px)
|
|
63
|
-
* - Gap entre items: 0.5 (2px)
|
|
64
|
-
* - Gap entre elemento y contenido: 3 (12px)
|
|
65
|
-
* - Padding vertical section heading: pt-3 pb-1 (12px top, 4px bottom)
|
|
66
|
-
* - Padding items: py-2 px-4 (8px vertical, 16px horizontal)
|
|
67
|
-
*
|
|
68
|
-
* **Scroll:**
|
|
69
|
-
* - El body es scrolleable verticalmente (overflow-y-auto)
|
|
70
|
-
* - El encabezado y búsqueda se mantienen fijos en el tope
|
|
71
|
-
*
|
|
72
|
-
* @see docs/colors.md - Sistema de colores
|
|
73
|
-
* @see docs/typography.md - Sistema tipográfico
|
|
74
|
-
* @see docs/spacing.md - Sistema de espaciado
|
|
75
|
-
* @see docs/shadows.md - Sistema de sombras
|
|
76
|
-
* @see ../DropdownItemHeading - Componente reutilizado para encabezado
|
|
77
|
-
* @see ../DropdownItemCollapsible - Componente reutilizado para items colapsables
|
|
78
|
-
* @see ../Input - Componente reutilizado para búsqueda
|
|
79
|
-
* @see ../Divider - Componente reutilizado para separadores
|
|
80
|
-
* @see https://www.figma.com/design/5XNqf2YTxvwemxwo1LMQ6j/Siesa-UI-Kit?node-id=6134-34415 - Diseño Figma
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```tsx
|
|
84
|
-
* // Ejemplo simple con secciones
|
|
85
|
-
* <NavigationRailPanel
|
|
86
|
-
* height={900}
|
|
87
|
-
* showHeading={true}
|
|
88
|
-
* heading={{
|
|
89
|
-
* label: 'Settings',
|
|
90
|
-
* description: 'Configure your preferences',
|
|
91
|
-
* iconName: 'cog-6-tooth',
|
|
92
|
-
* actionLabel: 'Clear',
|
|
93
|
-
* showAction: true,
|
|
94
|
-
* }}
|
|
95
|
-
* showSearch={true}
|
|
96
|
-
* search={{
|
|
97
|
-
* placeholder: 'Buscar módulo',
|
|
98
|
-
* }}
|
|
99
|
-
* sections={[
|
|
100
|
-
* {
|
|
101
|
-
* heading: 'Section 1',
|
|
102
|
-
* items: [
|
|
103
|
-
* { label: 'Item 1', isCollapsible: true, children: [...] },
|
|
104
|
-
* { label: 'Item 2', isCollapsible: false },
|
|
105
|
-
* ],
|
|
106
|
-
* },
|
|
107
|
-
* {
|
|
108
|
-
* heading: 'Section 2',
|
|
109
|
-
* items: [
|
|
110
|
-
* { label: 'Item 3' },
|
|
111
|
-
* ],
|
|
112
|
-
* },
|
|
113
|
-
* ]}
|
|
114
|
-
* />
|
|
115
|
-
*
|
|
116
|
-
* // Ejemplo con items simples sin secciones
|
|
117
|
-
* <NavigationRailPanel
|
|
118
|
-
* showHeading={false}
|
|
119
|
-
* showSearch={true}
|
|
120
|
-
* items={[
|
|
121
|
-
* { label: 'Dashboard', icon: <DashboardIcon /> },
|
|
122
|
-
* { label: 'Users', icon: <UserIcon /> },
|
|
123
|
-
* { label: 'Settings', icon: <SettingsIcon /> },
|
|
124
|
-
* ]}
|
|
125
|
-
* />
|
|
126
|
-
* ```
|
|
127
|
-
*/
|
|
128
|
-
export const NavigationRailPanel: React.FC<NavigationRailPanelProps> = ({
|
|
129
|
-
height = 900,
|
|
130
|
-
width = 248,
|
|
131
|
-
showHeading = true,
|
|
132
|
-
heading,
|
|
133
|
-
showSearch = true,
|
|
134
|
-
search,
|
|
135
|
-
sections,
|
|
136
|
-
items,
|
|
137
|
-
className = '',
|
|
138
|
-
panelClassName = '',
|
|
139
|
-
}) => {
|
|
140
|
-
const [searchValue, setSearchValue] = useState(search?.value || '');
|
|
141
|
-
|
|
142
|
-
const handleSearchChange = (value: string) => {
|
|
143
|
-
setSearchValue(value);
|
|
144
|
-
search?.onChange?.(value);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
// Construir clase de altura dinámicamente
|
|
148
|
-
const containerStyle = {
|
|
149
|
-
height: typeof height === 'number' ? `${height}px` : height,
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const panelStyle = {
|
|
153
|
-
width: typeof width === 'number' ? `${width}px` : width,
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
return (
|
|
157
|
-
<div
|
|
158
|
-
className={`flex items-start relative ${className}`}
|
|
159
|
-
style={containerStyle}
|
|
160
|
-
data-testid="navigation-rail-panel-container"
|
|
161
|
-
>
|
|
162
|
-
<div
|
|
163
|
-
className={`bg-bg-primary dark:bg-dark-bg-primary border-border-primary dark:border-dark-border-primary border-b-0 border-l border-r
|
|
164
|
-
style={panelStyle}
|
|
165
|
-
data-testid="navigation-rail-panel"
|
|
166
|
-
>
|
|
167
|
-
{/* Encabezado (DropdownItemHeading) */}
|
|
168
|
-
{showHeading && heading && (
|
|
169
|
-
<div className="flex flex-col items-start p-3 relative shrink-0 w-full">
|
|
170
|
-
<DropdownItemHeading
|
|
171
|
-
label={heading.label}
|
|
172
|
-
description={heading.description}
|
|
173
|
-
showDescription={heading.showDescription !== false}
|
|
174
|
-
iconName={heading.iconName}
|
|
175
|
-
showIcon={true}
|
|
176
|
-
actionLabel={heading.actionLabel}
|
|
177
|
-
showAction={heading.showAction}
|
|
178
|
-
onActionClick={heading.onActionClick}
|
|
179
|
-
className="w-full"
|
|
180
|
-
/>
|
|
181
|
-
</div>
|
|
182
|
-
)}
|
|
183
|
-
|
|
184
|
-
{/* Input de búsqueda */}
|
|
185
|
-
{showSearch && (
|
|
186
|
-
<div
|
|
187
|
-
className="flex flex-col items-start p-3 relative shrink-0 w-full"
|
|
188
|
-
data-testid="navigation-rail-search"
|
|
189
|
-
>
|
|
190
|
-
<Input
|
|
191
|
-
placeholder={search?.placeholder || 'Buscar módulo'}
|
|
192
|
-
value={searchValue}
|
|
193
|
-
onChange={(e) => handleSearchChange(e.target.value)}
|
|
194
|
-
className="w-full"
|
|
195
|
-
/>
|
|
196
|
-
</div>
|
|
197
|
-
)}
|
|
198
|
-
|
|
199
|
-
{/* Divisor */}
|
|
200
|
-
<Divider className="w-full" />
|
|
201
|
-
|
|
202
|
-
{/* Body con items */}
|
|
203
|
-
<div
|
|
204
|
-
className="flex flex-1 flex-col gap-0.5 items-start min-h-px min-w-px p-3 relative shrink-0 overflow-y-auto w-full"
|
|
205
|
-
data-testid="navigation-rail-body"
|
|
206
|
-
>
|
|
207
|
-
{/* Renderizar secciones */}
|
|
208
|
-
{sections && sections.length > 0
|
|
209
|
-
? sections.map((section, sectionIndex) => (
|
|
210
|
-
<div key={`section-${sectionIndex}`} className="w-full">
|
|
211
|
-
{/* Section Heading */}
|
|
212
|
-
{section.heading && (
|
|
213
|
-
<div
|
|
214
|
-
className="flex flex-col gap-0 items-start pb-1 pt-3 px-0 relative shrink-0 w-full"
|
|
215
|
-
data-testid={`section-heading-${sectionIndex}`}
|
|
216
|
-
>
|
|
217
|
-
<p className="font-['Inter:Regular',sans-serif] font-normal text-xs leading-4 not-italic relative shrink-0 text-content-tertiary dark:text-content-tertiary w-full whitespace-pre-wrap">
|
|
218
|
-
{section.heading}
|
|
219
|
-
</p>
|
|
220
|
-
</div>
|
|
221
|
-
)}
|
|
222
|
-
|
|
223
|
-
{/* Section Items */}
|
|
224
|
-
<div
|
|
225
|
-
className="flex flex-col gap-0.5 items-start relative shrink-0 w-full"
|
|
226
|
-
data-testid={`section-items-${sectionIndex}`}
|
|
227
|
-
>
|
|
228
|
-
{section.items.map((item, itemIndex) => (
|
|
229
|
-
<NavigationRailPanelItem
|
|
230
|
-
key={`item-${sectionIndex}-${itemIndex}`}
|
|
231
|
-
item={item}
|
|
232
|
-
/>
|
|
233
|
-
))}
|
|
234
|
-
</div>
|
|
235
|
-
|
|
236
|
-
{/* Section Divider */}
|
|
237
|
-
{section.showDivider !== false && sectionIndex < sections.length - 1 && (
|
|
238
|
-
<Divider className="mt-3 w-full" />
|
|
239
|
-
)}
|
|
240
|
-
</div>
|
|
241
|
-
))
|
|
242
|
-
: null}
|
|
243
|
-
|
|
244
|
-
{/* Renderizar items simples (sin secciones) */}
|
|
245
|
-
{items && items.length > 0 && !sections
|
|
246
|
-
? items.map((item, itemIndex) => (
|
|
247
|
-
<NavigationRailPanelItem
|
|
248
|
-
key={`item-${itemIndex}`}
|
|
249
|
-
item={item}
|
|
250
|
-
/>
|
|
251
|
-
))
|
|
252
|
-
: null}
|
|
253
|
-
</div>
|
|
254
|
-
</div>
|
|
255
|
-
</div>
|
|
256
|
-
);
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Componente interno para renderizar un item del NavigationRailPanel
|
|
261
|
-
* Puede ser un item simple o colapsable
|
|
262
|
-
*/
|
|
263
|
-
interface NavigationRailPanelItemComponentProps {
|
|
264
|
-
item: NonNullable<NavigationRailPanelProps['items']>[0];
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const NavigationRailPanelItem: React.FC<NavigationRailPanelItemComponentProps> = ({ item }) => {
|
|
268
|
-
if (item.isCollapsible) {
|
|
269
|
-
return (
|
|
270
|
-
<DropdownItemCollapsible
|
|
271
|
-
label={item.label}
|
|
272
|
-
icon={item.icon}
|
|
273
|
-
children={item.children}
|
|
274
|
-
defaultOpen={item.defaultOpen}
|
|
275
|
-
disabled={item.disabled}
|
|
276
|
-
onClick={item.onClick}
|
|
277
|
-
onOpenChange={item.onOpenChange}
|
|
278
|
-
className={item.className}
|
|
279
|
-
showDivider={false}
|
|
280
|
-
showHeading={false}
|
|
281
|
-
/>
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return (
|
|
286
|
-
<button
|
|
287
|
-
onClick={item.onClick}
|
|
288
|
-
disabled={item.disabled}
|
|
289
|
-
className={[
|
|
290
|
-
// Base
|
|
291
|
-
'flex items-center gap-3 px-4 py-2 w-full',
|
|
292
|
-
'rounded-lg cursor-pointer',
|
|
293
|
-
'transition-colors duration-150',
|
|
294
|
-
|
|
295
|
-
// Colores y estados (Light Mode)
|
|
296
|
-
!item.disabled && 'text-content-primary',
|
|
297
|
-
!item.disabled && 'hover:bg-primary-custom-100',
|
|
298
|
-
|
|
299
|
-
// Dark Mode
|
|
300
|
-
!item.disabled && 'dark:text-content-primary',
|
|
301
|
-
!item.disabled && 'dark:hover:bg-dark-bg-custom',
|
|
302
|
-
|
|
303
|
-
// Focus ring
|
|
304
|
-
!item.disabled && 'focus:outline-none',
|
|
305
|
-
!item.disabled && 'focus:ring-2',
|
|
306
|
-
!item.disabled && 'focus:ring-offset-2',
|
|
307
|
-
!item.disabled && 'focus:ring-primary-custom-400',
|
|
308
|
-
!item.disabled && 'focus:ring-offset-bg-primary',
|
|
309
|
-
!item.disabled && 'dark:focus:ring-offset-dark-bg-primary',
|
|
310
|
-
|
|
311
|
-
// Disabled
|
|
312
|
-
item.disabled && 'opacity-50',
|
|
313
|
-
item.disabled && 'cursor-not-allowed',
|
|
314
|
-
|
|
315
|
-
item.className,
|
|
316
|
-
]
|
|
317
|
-
.filter(Boolean)
|
|
318
|
-
.join(' ')}
|
|
319
|
-
data-testid={`navigation-rail-item-${item.label}`}
|
|
320
|
-
aria-disabled={item.disabled}
|
|
321
|
-
>
|
|
322
|
-
{item.icon && (
|
|
323
|
-
<div className="flex items-center justify-center w-4 h-4 shrink-0 text-content-secondary dark:text-content-secondary">
|
|
324
|
-
{item.icon}
|
|
325
|
-
</div>
|
|
326
|
-
)}
|
|
327
|
-
<p className="font-['Inter:Regular',sans-serif] text-sm font-normal leading-5 not-italic relative shrink-0 text-left">
|
|
328
|
-
{item.label}
|
|
329
|
-
</p>
|
|
330
|
-
</button>
|
|
331
|
-
);
|
|
332
|
-
};
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import type { NavigationRailPanelProps } from './NavigationRailPanel.types';
|
|
3
|
+
import { DropdownItemHeading } from '../DropdownItemHeading';
|
|
4
|
+
import { DropdownItemCollapsible } from '../DropdownItemCollapsible';
|
|
5
|
+
import { Input } from '../Input';
|
|
6
|
+
import { Divider } from '../Divider/Divider';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Componente NavigationRailPanel del sistema de diseño Siesa
|
|
10
|
+
*
|
|
11
|
+
* Panel de navegación vertical (rail) que puede contener múltiples secciones
|
|
12
|
+
* de items, búsqueda y encabezados. Se usa típicamente en aplicaciones con
|
|
13
|
+
* navegación compleja que requieren una estructura jerárquica.
|
|
14
|
+
*
|
|
15
|
+
* **Estructura principal:**
|
|
16
|
+
* 1. Encabezado (DropdownItemHeading) - Opcional
|
|
17
|
+
* 2. Input de búsqueda - Opcional
|
|
18
|
+
* 3. Divisor - Siempre presente después de búsqueda/encabezado
|
|
19
|
+
* 4. Body con secciones de items:
|
|
20
|
+
* - Heading de sección (Paragraph/Tiny, content-tertiary)
|
|
21
|
+
* - Items colapsables (DropdownItemCollapsible) o simples
|
|
22
|
+
* - Divisor entre secciones
|
|
23
|
+
*
|
|
24
|
+
* **Dimensiones según Figma:**
|
|
25
|
+
* - Altura: Variable (por defecto 900px)
|
|
26
|
+
* - Ancho del panel: 248px (con padding 12px)
|
|
27
|
+
* - Ancho de contenido: 224px
|
|
28
|
+
* - Padding del panel: 12px
|
|
29
|
+
* - Padding del body: 12px
|
|
30
|
+
* - Border: 1px left (border-primary)
|
|
31
|
+
* - Border radius: 0px (es un panel recto)
|
|
32
|
+
*
|
|
33
|
+
* **Tipografía:**
|
|
34
|
+
* - Heading (DropdownItemHeading): Label/Small (14px Bold)
|
|
35
|
+
* - Section heading: Paragraph/Tiny (12px Regular) - content-tertiary
|
|
36
|
+
* - Items: Paragraph/Small (14px Regular)
|
|
37
|
+
*
|
|
38
|
+
* **Colores (Light Mode):**
|
|
39
|
+
* - Background: #ffffff (white)
|
|
40
|
+
* - Border: #e4e4e7 (border-primary)
|
|
41
|
+
* - Heading text: #18181b (content-primary)
|
|
42
|
+
* - Section heading: #71717a (content-tertiary)
|
|
43
|
+
* - Item text: #18181b (content-primary)
|
|
44
|
+
* - Icon color: #a1a1aa (content-secondary)
|
|
45
|
+
*
|
|
46
|
+
* **Colores (Dark Mode):**
|
|
47
|
+
* - Background: #18181b (dark bg)
|
|
48
|
+
* - Border: #3f3f46 (border-primary/dark)
|
|
49
|
+
* - Heading text: #fafafa (content-primary/dark)
|
|
50
|
+
* - Section heading: #a1a1aa (content-tertiary/dark)
|
|
51
|
+
* - Item text: #fafafa (content-primary/dark)
|
|
52
|
+
* - Icon color: #a1a1aa (content-secondary/dark)
|
|
53
|
+
*
|
|
54
|
+
* **Estados:**
|
|
55
|
+
* - Default: Sin interacción
|
|
56
|
+
* - Hover: Items con hover overlay sutil
|
|
57
|
+
* - Focus: Focus ring adaptativo
|
|
58
|
+
* - Disabled: Opacidad 50%
|
|
59
|
+
* - Active (items colapsables): Expanded state
|
|
60
|
+
*
|
|
61
|
+
* **Espaciado interno:**
|
|
62
|
+
* - Gap entre section heading e items: 0.5 (2px)
|
|
63
|
+
* - Gap entre items: 0.5 (2px)
|
|
64
|
+
* - Gap entre elemento y contenido: 3 (12px)
|
|
65
|
+
* - Padding vertical section heading: pt-3 pb-1 (12px top, 4px bottom)
|
|
66
|
+
* - Padding items: py-2 px-4 (8px vertical, 16px horizontal)
|
|
67
|
+
*
|
|
68
|
+
* **Scroll:**
|
|
69
|
+
* - El body es scrolleable verticalmente (overflow-y-auto)
|
|
70
|
+
* - El encabezado y búsqueda se mantienen fijos en el tope
|
|
71
|
+
*
|
|
72
|
+
* @see docs/colors.md - Sistema de colores
|
|
73
|
+
* @see docs/typography.md - Sistema tipográfico
|
|
74
|
+
* @see docs/spacing.md - Sistema de espaciado
|
|
75
|
+
* @see docs/shadows.md - Sistema de sombras
|
|
76
|
+
* @see ../DropdownItemHeading - Componente reutilizado para encabezado
|
|
77
|
+
* @see ../DropdownItemCollapsible - Componente reutilizado para items colapsables
|
|
78
|
+
* @see ../Input - Componente reutilizado para búsqueda
|
|
79
|
+
* @see ../Divider - Componente reutilizado para separadores
|
|
80
|
+
* @see https://www.figma.com/design/5XNqf2YTxvwemxwo1LMQ6j/Siesa-UI-Kit?node-id=6134-34415 - Diseño Figma
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```tsx
|
|
84
|
+
* // Ejemplo simple con secciones
|
|
85
|
+
* <NavigationRailPanel
|
|
86
|
+
* height={900}
|
|
87
|
+
* showHeading={true}
|
|
88
|
+
* heading={{
|
|
89
|
+
* label: 'Settings',
|
|
90
|
+
* description: 'Configure your preferences',
|
|
91
|
+
* iconName: 'cog-6-tooth',
|
|
92
|
+
* actionLabel: 'Clear',
|
|
93
|
+
* showAction: true,
|
|
94
|
+
* }}
|
|
95
|
+
* showSearch={true}
|
|
96
|
+
* search={{
|
|
97
|
+
* placeholder: 'Buscar módulo',
|
|
98
|
+
* }}
|
|
99
|
+
* sections={[
|
|
100
|
+
* {
|
|
101
|
+
* heading: 'Section 1',
|
|
102
|
+
* items: [
|
|
103
|
+
* { label: 'Item 1', isCollapsible: true, children: [...] },
|
|
104
|
+
* { label: 'Item 2', isCollapsible: false },
|
|
105
|
+
* ],
|
|
106
|
+
* },
|
|
107
|
+
* {
|
|
108
|
+
* heading: 'Section 2',
|
|
109
|
+
* items: [
|
|
110
|
+
* { label: 'Item 3' },
|
|
111
|
+
* ],
|
|
112
|
+
* },
|
|
113
|
+
* ]}
|
|
114
|
+
* />
|
|
115
|
+
*
|
|
116
|
+
* // Ejemplo con items simples sin secciones
|
|
117
|
+
* <NavigationRailPanel
|
|
118
|
+
* showHeading={false}
|
|
119
|
+
* showSearch={true}
|
|
120
|
+
* items={[
|
|
121
|
+
* { label: 'Dashboard', icon: <DashboardIcon /> },
|
|
122
|
+
* { label: 'Users', icon: <UserIcon /> },
|
|
123
|
+
* { label: 'Settings', icon: <SettingsIcon /> },
|
|
124
|
+
* ]}
|
|
125
|
+
* />
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export const NavigationRailPanel: React.FC<NavigationRailPanelProps> = ({
|
|
129
|
+
height = 900,
|
|
130
|
+
width = 248,
|
|
131
|
+
showHeading = true,
|
|
132
|
+
heading,
|
|
133
|
+
showSearch = true,
|
|
134
|
+
search,
|
|
135
|
+
sections,
|
|
136
|
+
items,
|
|
137
|
+
className = '',
|
|
138
|
+
panelClassName = '',
|
|
139
|
+
}) => {
|
|
140
|
+
const [searchValue, setSearchValue] = useState(search?.value || '');
|
|
141
|
+
|
|
142
|
+
const handleSearchChange = (value: string) => {
|
|
143
|
+
setSearchValue(value);
|
|
144
|
+
search?.onChange?.(value);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Construir clase de altura dinámicamente
|
|
148
|
+
const containerStyle = {
|
|
149
|
+
height: typeof height === 'number' ? `${height}px` : height,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const panelStyle = {
|
|
153
|
+
width: typeof width === 'number' ? `${width}px` : width,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<div
|
|
158
|
+
className={`flex items-start relative ${className}`}
|
|
159
|
+
style={containerStyle}
|
|
160
|
+
data-testid="navigation-rail-panel-container"
|
|
161
|
+
>
|
|
162
|
+
<div
|
|
163
|
+
className={`bg-bg-primary dark:bg-dark-bg-primary border-border-primary dark:border-dark-border-primary border-b-0 border-l border-r border-solid border-t-0 flex flex-col h-full items-start overflow-clip relative shrink-0 ${panelClassName}`}
|
|
164
|
+
style={panelStyle}
|
|
165
|
+
data-testid="navigation-rail-panel"
|
|
166
|
+
>
|
|
167
|
+
{/* Encabezado (DropdownItemHeading) */}
|
|
168
|
+
{showHeading && heading && (
|
|
169
|
+
<div className="flex flex-col items-start p-3 relative shrink-0 w-full">
|
|
170
|
+
<DropdownItemHeading
|
|
171
|
+
label={heading.label}
|
|
172
|
+
description={heading.description}
|
|
173
|
+
showDescription={heading.showDescription !== false}
|
|
174
|
+
iconName={heading.iconName}
|
|
175
|
+
showIcon={true}
|
|
176
|
+
actionLabel={heading.actionLabel}
|
|
177
|
+
showAction={heading.showAction}
|
|
178
|
+
onActionClick={heading.onActionClick}
|
|
179
|
+
className="w-full"
|
|
180
|
+
/>
|
|
181
|
+
</div>
|
|
182
|
+
)}
|
|
183
|
+
|
|
184
|
+
{/* Input de búsqueda */}
|
|
185
|
+
{showSearch && (
|
|
186
|
+
<div
|
|
187
|
+
className="flex flex-col items-start p-3 relative shrink-0 w-full"
|
|
188
|
+
data-testid="navigation-rail-search"
|
|
189
|
+
>
|
|
190
|
+
<Input
|
|
191
|
+
placeholder={search?.placeholder || 'Buscar módulo'}
|
|
192
|
+
value={searchValue}
|
|
193
|
+
onChange={(e) => handleSearchChange(e.target.value)}
|
|
194
|
+
className="w-full"
|
|
195
|
+
/>
|
|
196
|
+
</div>
|
|
197
|
+
)}
|
|
198
|
+
|
|
199
|
+
{/* Divisor */}
|
|
200
|
+
<Divider className="w-full" />
|
|
201
|
+
|
|
202
|
+
{/* Body con items */}
|
|
203
|
+
<div
|
|
204
|
+
className="flex flex-1 flex-col gap-0.5 items-start min-h-px min-w-px p-3 relative shrink-0 overflow-y-auto w-full"
|
|
205
|
+
data-testid="navigation-rail-body"
|
|
206
|
+
>
|
|
207
|
+
{/* Renderizar secciones */}
|
|
208
|
+
{sections && sections.length > 0
|
|
209
|
+
? sections.map((section, sectionIndex) => (
|
|
210
|
+
<div key={`section-${sectionIndex}`} className="w-full">
|
|
211
|
+
{/* Section Heading */}
|
|
212
|
+
{section.heading && (
|
|
213
|
+
<div
|
|
214
|
+
className="flex flex-col gap-0 items-start pb-1 pt-3 px-0 relative shrink-0 w-full"
|
|
215
|
+
data-testid={`section-heading-${sectionIndex}`}
|
|
216
|
+
>
|
|
217
|
+
<p className="font-['Inter:Regular',sans-serif] font-normal text-xs leading-4 not-italic relative shrink-0 text-content-tertiary dark:text-content-tertiary w-full whitespace-pre-wrap">
|
|
218
|
+
{section.heading}
|
|
219
|
+
</p>
|
|
220
|
+
</div>
|
|
221
|
+
)}
|
|
222
|
+
|
|
223
|
+
{/* Section Items */}
|
|
224
|
+
<div
|
|
225
|
+
className="flex flex-col gap-0.5 items-start relative shrink-0 w-full"
|
|
226
|
+
data-testid={`section-items-${sectionIndex}`}
|
|
227
|
+
>
|
|
228
|
+
{section.items.map((item, itemIndex) => (
|
|
229
|
+
<NavigationRailPanelItem
|
|
230
|
+
key={`item-${sectionIndex}-${itemIndex}`}
|
|
231
|
+
item={item}
|
|
232
|
+
/>
|
|
233
|
+
))}
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
{/* Section Divider */}
|
|
237
|
+
{section.showDivider !== false && sectionIndex < sections.length - 1 && (
|
|
238
|
+
<Divider className="mt-3 w-full" />
|
|
239
|
+
)}
|
|
240
|
+
</div>
|
|
241
|
+
))
|
|
242
|
+
: null}
|
|
243
|
+
|
|
244
|
+
{/* Renderizar items simples (sin secciones) */}
|
|
245
|
+
{items && items.length > 0 && !sections
|
|
246
|
+
? items.map((item, itemIndex) => (
|
|
247
|
+
<NavigationRailPanelItem
|
|
248
|
+
key={`item-${itemIndex}`}
|
|
249
|
+
item={item}
|
|
250
|
+
/>
|
|
251
|
+
))
|
|
252
|
+
: null}
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
);
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Componente interno para renderizar un item del NavigationRailPanel
|
|
261
|
+
* Puede ser un item simple o colapsable
|
|
262
|
+
*/
|
|
263
|
+
interface NavigationRailPanelItemComponentProps {
|
|
264
|
+
item: NonNullable<NavigationRailPanelProps['items']>[0];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const NavigationRailPanelItem: React.FC<NavigationRailPanelItemComponentProps> = ({ item }) => {
|
|
268
|
+
if (item.isCollapsible) {
|
|
269
|
+
return (
|
|
270
|
+
<DropdownItemCollapsible
|
|
271
|
+
label={item.label}
|
|
272
|
+
icon={item.icon}
|
|
273
|
+
children={item.children}
|
|
274
|
+
defaultOpen={item.defaultOpen}
|
|
275
|
+
disabled={item.disabled}
|
|
276
|
+
onClick={item.onClick}
|
|
277
|
+
onOpenChange={item.onOpenChange}
|
|
278
|
+
className={item.className}
|
|
279
|
+
showDivider={false}
|
|
280
|
+
showHeading={false}
|
|
281
|
+
/>
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return (
|
|
286
|
+
<button
|
|
287
|
+
onClick={item.onClick}
|
|
288
|
+
disabled={item.disabled}
|
|
289
|
+
className={[
|
|
290
|
+
// Base
|
|
291
|
+
'flex items-center gap-3 px-4 py-2 w-full',
|
|
292
|
+
'rounded-lg cursor-pointer',
|
|
293
|
+
'transition-colors duration-150',
|
|
294
|
+
|
|
295
|
+
// Colores y estados (Light Mode)
|
|
296
|
+
!item.disabled && 'text-content-primary',
|
|
297
|
+
!item.disabled && 'hover:bg-primary-custom-100',
|
|
298
|
+
|
|
299
|
+
// Dark Mode
|
|
300
|
+
!item.disabled && 'dark:text-content-primary',
|
|
301
|
+
!item.disabled && 'dark:hover:bg-dark-bg-custom',
|
|
302
|
+
|
|
303
|
+
// Focus ring
|
|
304
|
+
!item.disabled && 'focus:outline-none',
|
|
305
|
+
!item.disabled && 'focus:ring-2',
|
|
306
|
+
!item.disabled && 'focus:ring-offset-2',
|
|
307
|
+
!item.disabled && 'focus:ring-primary-custom-400',
|
|
308
|
+
!item.disabled && 'focus:ring-offset-bg-primary',
|
|
309
|
+
!item.disabled && 'dark:focus:ring-offset-dark-bg-primary',
|
|
310
|
+
|
|
311
|
+
// Disabled
|
|
312
|
+
item.disabled && 'opacity-50',
|
|
313
|
+
item.disabled && 'cursor-not-allowed',
|
|
314
|
+
|
|
315
|
+
item.className,
|
|
316
|
+
]
|
|
317
|
+
.filter(Boolean)
|
|
318
|
+
.join(' ')}
|
|
319
|
+
data-testid={`navigation-rail-item-${item.label}`}
|
|
320
|
+
aria-disabled={item.disabled}
|
|
321
|
+
>
|
|
322
|
+
{item.icon && (
|
|
323
|
+
<div className="flex items-center justify-center w-4 h-4 shrink-0 text-content-secondary dark:text-content-secondary">
|
|
324
|
+
{item.icon}
|
|
325
|
+
</div>
|
|
326
|
+
)}
|
|
327
|
+
<p className="font-['Inter:Regular',sans-serif] text-sm font-normal leading-5 not-italic relative shrink-0 text-left">
|
|
328
|
+
{item.label}
|
|
329
|
+
</p>
|
|
330
|
+
</button>
|
|
331
|
+
);
|
|
332
|
+
};
|