ywana-core8 0.1.103 → 0.2.1
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/index.css +4941 -324
- package/dist/index.js +42338 -0
- package/dist/index.js.map +1 -0
- package/dist/index.modern.js +37458 -31678
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +39634 -34010
- package/dist/index.umd.js.map +1 -1
- package/package.json +26 -29
- package/src/Test.stories.jsx +28 -0
- package/src/desktop/Desktop.stories.jsx +110 -0
- package/src/desktop/WindowContext.js +135 -0
- package/src/desktop/WindowManager.js +355 -0
- package/src/desktop/desktop.css +55 -4
- package/src/desktop/desktop.js +312 -6
- package/src/desktop/index.js +7 -0
- package/src/desktop/window.css +229 -36
- package/src/desktop/window.js +254 -20
- package/src/desktop.backup/desktop.css +6 -0
- package/src/desktop.backup/desktop.js +13 -0
- package/src/desktop.backup/window.css +58 -0
- package/src/desktop.backup/window.js +27 -0
- package/src/html/Accordion.stories.jsx +178 -0
- package/src/html/Button.stories.jsx +175 -0
- package/src/html/Checkbox.stories.jsx +131 -0
- package/src/html/Chip.stories.jsx +189 -0
- package/src/html/Color.stories.jsx +234 -0
- package/src/html/Form.stories.jsx +271 -0
- package/src/html/Icon.stories.jsx +233 -0
- package/src/html/Progress.stories.jsx +247 -0
- package/src/html/Radio.stories.jsx +289 -0
- package/src/html/StyleTest.stories.jsx +81 -0
- package/src/html/Switch.stories.jsx +329 -0
- package/src/html/Tab.stories.jsx +239 -0
- package/src/html/Table.stories.jsx +188 -0
- package/src/html/Table2.stories.jsx +238 -0
- package/src/html/TextField2.stories.jsx +337 -0
- package/src/html/Tree.stories.jsx +285 -0
- package/src/html/accordion.example.js +0 -74
- package/src/html/accordion.js +1 -6
- package/src/html/button.js +2 -13
- package/src/html/checkbox.js +1 -9
- package/src/html/chip.js +2 -19
- package/src/html/color.js +1 -14
- package/src/html/form.js +4 -15
- package/src/html/header2.js +1 -12
- package/src/html/icon.js +1 -7
- package/src/html/index.js +1 -1
- package/src/html/list.js +1 -19
- package/src/html/menu.js +9 -5
- package/src/html/progress.js +5 -53
- package/src/html/property.js +9 -25
- package/src/html/radio.js +2 -16
- package/src/html/section.js +1 -6
- package/src/html/selector.js +2 -19
- package/src/html/switch.css +134 -100
- package/src/html/switch.example.js +46 -36
- package/src/html/switch.js +43 -192
- package/src/html/tab.js +3 -24
- package/src/html/text.js +1 -12
- package/src/html/textfield2.js +5 -42
- package/src/html/thumbnail.js +1 -12
- package/src/html/tokenfield.js +2 -21
- package/src/html/tree.js +3 -35
- package/src/index.js +1 -0
- package/__previewjs__/Wrapper.tsx +0 -14
- package/build-doc.sh +0 -10
- package/db/db.json +0 -89
- package/db/routes.json +0 -0
- package/dist/index.cjs +0 -36722
- package/dist/index.cjs.map +0 -1
- package/dist/index.css.map +0 -1
- package/doc/README.md +0 -196
- package/doc/evalulations/ACCORDION_EVALUATION.md +0 -583
- package/doc/evalulations/CHECKBOX_EVALUATION.md +0 -273
- package/doc/evalulations/CHIP_EVALUATION.md +0 -542
- package/doc/evalulations/COLOR_EVALUATION.md +0 -524
- package/doc/evalulations/COMPONENTS_EVALUATION.md +0 -477
- package/doc/evalulations/FORM_EVALUATION.md +0 -459
- package/doc/evalulations/HEADER_EVALUATION.md +0 -436
- package/doc/evalulations/ICON_EVALUATION.md +0 -254
- package/doc/evalulations/LIST_EVALUATION.md +0 -574
- package/doc/evalulations/PROGRESS_EVALUATION.md +0 -450
- package/doc/evalulations/RADIO_EVALUATION.md +0 -439
- package/doc/evalulations/RADIO_VISUAL_FIX.md +0 -183
- package/doc/evalulations/SECTION_IMPROVEMENTS.md +0 -153
- package/doc/evalulations/SWITCH_EVALUATION.md +0 -335
- package/doc/evalulations/SWITCH_VISUAL_FIX.md +0 -232
- package/doc/evalulations/TAB_EVALUATION.md +0 -626
- package/doc/evalulations/TEXTFIELD_EVALUATION.md +0 -747
- package/doc/evalulations/TOOLTIP_FIX.md +0 -157
- package/doc/evalulations/TREE_EVALUATION.md +0 -708
- package/doc/index.html +0 -0
- package/doc/package-lock.json +0 -17298
- package/doc/package.json +0 -34
- package/doc/public/index.html +0 -24
- package/doc/scripts/generate-examples.js +0 -129
- package/doc/src/App.css +0 -171
- package/doc/src/App.js +0 -114
- package/doc/src/components/ExamplePage.js +0 -129
- package/doc/src/components/WelcomePage.js +0 -84
- package/doc/src/index.css +0 -246
- package/doc/src/index.js +0 -17
- package/doc/src/theme.css +0 -256
- package/jest.config.js +0 -24
- package/preview.config.js +0 -38
- package/publish.sh +0 -6
- package/src/desktop/dektop.test.js +0 -11
- package/src/domain/CollectionAPI.test.js +0 -19
- package/src/domain/ContentEditor.test.js +0 -52
- package/src/domain2/CollectionAPI.test.js +0 -19
- package/src/domain2/CollectionContext.test.js +0 -71
- package/src/domain2/CollectionPage.test.js +0 -112
- package/src/domain2/DynamicForm.test.js +0 -47
- package/src/html/accordion.test.js +0 -37
- package/src/html/accordion.unit.test.js +0 -334
- package/src/html/button.example.new.js +0 -416
- package/src/html/button.test.js +0 -422
- package/src/html/checkbox.test.js +0 -285
- package/src/html/chip.test.js +0 -425
- package/src/html/color.example.js.backup +0 -527
- package/src/html/color.test.js +0 -377
- package/src/html/components.example.js.backup +0 -492
- package/src/html/components_enhanced.test.js +0 -581
- package/src/html/form.example.js.backup +0 -385
- package/src/html/form.test.js +0 -369
- package/src/html/header2.example.js.backup +0 -411
- package/src/html/header2.test.js +0 -377
- package/src/html/icon.example.js.backup +0 -268
- package/src/html/icon.test.js +0 -231
- package/src/html/label.test.js +0 -0
- package/src/html/list.example.js.backup +0 -404
- package/src/html/list.test.js +0 -383
- package/src/html/progress.example.js.backup +0 -424
- package/src/html/progress.test.js +0 -313
- package/src/html/property.example.js.backup +0 -553
- package/src/html/property.test.js +0 -371
- package/src/html/radio.example.js.backup +0 -389
- package/src/html/radio.test.js +0 -318
- package/src/html/section.example.js.backup +0 -99
- package/src/html/section.test.js +0 -131
- package/src/html/selector.test.js +0 -20
- package/src/html/switch.example.js.backup +0 -461
- package/src/html/switch.test.js +0 -355
- package/src/html/tab.example.js.backup +0 -446
- package/src/html/tab.test.js +0 -25
- package/src/html/tab_enhanced.test.js +0 -504
- package/src/html/table.test.js +0 -70
- package/src/html/table2.test.js +0 -582
- package/src/html/text.test.js +0 -15
- package/src/html/textfield.test.js +0 -51
- package/src/html/textfield2.example.js.backup +0 -1370
- package/src/html/textfield2.test.js +0 -950
- package/src/html/tokenfield.example.js.backup +0 -503
- package/src/html/tokenfield.test.js +0 -423
- package/src/html/tree.example.js.backup +0 -475
- package/src/html/tree.test.js +0 -43
- package/src/html/tree_enhanced.test.js +0 -495
- package/src/http/token.test.js +0 -50
- package/src/incubator/pdfViewer.js +0 -33
- package/src/incubator/wizard.test.js +0 -127
- package/src/site/site.test.js +0 -230
- package/src/site/view.test.js +0 -41
- package/src/widgets/calendar/Calendar.test.js +0 -28
- package/src/widgets/explorer/Explorer.test.js +0 -121
- package/src/widgets/ide/editor.test.js +0 -33
- package/src/widgets/kanban/Kanban.test.js +0 -78
- package/src/widgets/login/LoginBox.test.js +0 -12
- package/src/widgets/login/ResetPasswordBox.test.js +0 -34
- package/src/widgets/login/validations.test.js +0 -51
- package/src/widgets/planner/Planner.test.js +0 -60
- package/src/widgets/upload/Upload.test.js +0 -32
- package/table2.test.js +0 -454
@@ -0,0 +1,337 @@
|
|
1
|
+
import React, { useState } from 'react'
|
2
|
+
import { TextField2, TextArea2, PasswordField2, DropDown2, DateRange2 } from './textfield2'
|
3
|
+
|
4
|
+
export default {
|
5
|
+
title: 'HTML/TextField2',
|
6
|
+
component: TextField2,
|
7
|
+
parameters: {
|
8
|
+
docs: {
|
9
|
+
description: {
|
10
|
+
component: 'Enhanced TextField components with improved validation, accessibility, and features.'
|
11
|
+
}
|
12
|
+
}
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Basic TextField2 examples
|
18
|
+
*/
|
19
|
+
export const BasicTextFields = () => {
|
20
|
+
const [formData, setFormData] = useState({})
|
21
|
+
|
22
|
+
const handleFieldChange = (id, value) => {
|
23
|
+
setFormData(prev => ({
|
24
|
+
...prev,
|
25
|
+
[id]: value
|
26
|
+
}))
|
27
|
+
}
|
28
|
+
|
29
|
+
return (
|
30
|
+
<div style={{ padding: '20px' }}>
|
31
|
+
<h3>📝 TextField2 Básicos</h3>
|
32
|
+
|
33
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1rem' }}>
|
34
|
+
<div>
|
35
|
+
<h4>Estilo Normal</h4>
|
36
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
37
|
+
<TextField2
|
38
|
+
id="normalBasic"
|
39
|
+
label="Campo Básico"
|
40
|
+
placeholder="Placeholder text"
|
41
|
+
value={formData.normalBasic || ''}
|
42
|
+
onChange={handleFieldChange}
|
43
|
+
helperText="Campo normal básico"
|
44
|
+
/>
|
45
|
+
|
46
|
+
<TextField2
|
47
|
+
id="normalRequired"
|
48
|
+
label="Campo Requerido"
|
49
|
+
placeholder="Campo obligatorio"
|
50
|
+
value={formData.normalRequired || ''}
|
51
|
+
required={true}
|
52
|
+
onChange={handleFieldChange}
|
53
|
+
helperText="Campo requerido"
|
54
|
+
/>
|
55
|
+
</div>
|
56
|
+
</div>
|
57
|
+
|
58
|
+
<div>
|
59
|
+
<h4>Estilo Outlined</h4>
|
60
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
61
|
+
<TextField2
|
62
|
+
id="outlinedBasic"
|
63
|
+
label="Campo Outlined"
|
64
|
+
placeholder="Placeholder text"
|
65
|
+
value={formData.outlinedBasic || ''}
|
66
|
+
outlined={true}
|
67
|
+
onChange={handleFieldChange}
|
68
|
+
helperText="Campo outlined con borde"
|
69
|
+
/>
|
70
|
+
|
71
|
+
<TextField2
|
72
|
+
id="outlinedRequired"
|
73
|
+
label="Campo Requerido"
|
74
|
+
placeholder="Campo obligatorio"
|
75
|
+
value={formData.outlinedRequired || ''}
|
76
|
+
required={true}
|
77
|
+
outlined={true}
|
78
|
+
onChange={handleFieldChange}
|
79
|
+
helperText="Campo requerido outlined"
|
80
|
+
/>
|
81
|
+
</div>
|
82
|
+
</div>
|
83
|
+
</div>
|
84
|
+
</div>
|
85
|
+
)
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Different input types
|
90
|
+
*/
|
91
|
+
export const InputTypes = () => {
|
92
|
+
const [formData, setFormData] = useState({})
|
93
|
+
const [validationErrors, setValidationErrors] = useState({})
|
94
|
+
|
95
|
+
const handleFieldChange = (id, value) => {
|
96
|
+
setFormData(prev => ({
|
97
|
+
...prev,
|
98
|
+
[id]: value
|
99
|
+
}))
|
100
|
+
}
|
101
|
+
|
102
|
+
const handleValidation = (id, isValid, message) => {
|
103
|
+
setValidationErrors(prev => ({
|
104
|
+
...prev,
|
105
|
+
[id]: isValid ? null : message
|
106
|
+
}))
|
107
|
+
}
|
108
|
+
|
109
|
+
const validateEmail = (value) => {
|
110
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
111
|
+
return {
|
112
|
+
valid: emailRegex.test(value),
|
113
|
+
message: emailRegex.test(value) ? '' : 'Please enter a valid email address'
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
return (
|
118
|
+
<div style={{ padding: '20px' }}>
|
119
|
+
<h3>🔤 Tipos de Input</h3>
|
120
|
+
|
121
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1rem' }}>
|
122
|
+
<TextField2
|
123
|
+
id="textField"
|
124
|
+
type="text"
|
125
|
+
label="Texto"
|
126
|
+
placeholder="Ingresa texto"
|
127
|
+
value={formData.textField || ''}
|
128
|
+
onChange={handleFieldChange}
|
129
|
+
helperText="Tipo: text"
|
130
|
+
/>
|
131
|
+
|
132
|
+
<TextField2
|
133
|
+
id="emailField"
|
134
|
+
type="email"
|
135
|
+
label="Email"
|
136
|
+
placeholder="usuario@ejemplo.com"
|
137
|
+
value={formData.emailField || ''}
|
138
|
+
validation={validateEmail}
|
139
|
+
onChange={handleFieldChange}
|
140
|
+
onValidation={handleValidation}
|
141
|
+
helperText="Tipo: email con validación"
|
142
|
+
/>
|
143
|
+
|
144
|
+
<TextField2
|
145
|
+
id="numberField"
|
146
|
+
type="number"
|
147
|
+
label="Número"
|
148
|
+
placeholder="123"
|
149
|
+
value={formData.numberField || ''}
|
150
|
+
onChange={handleFieldChange}
|
151
|
+
helperText="Tipo: number"
|
152
|
+
/>
|
153
|
+
|
154
|
+
<TextField2
|
155
|
+
id="telField"
|
156
|
+
type="tel"
|
157
|
+
label="Teléfono"
|
158
|
+
placeholder="+1 (555) 123-4567"
|
159
|
+
value={formData.telField || ''}
|
160
|
+
onChange={handleFieldChange}
|
161
|
+
helperText="Tipo: tel"
|
162
|
+
/>
|
163
|
+
|
164
|
+
<TextField2
|
165
|
+
id="urlField"
|
166
|
+
type="url"
|
167
|
+
label="URL"
|
168
|
+
placeholder="https://ejemplo.com"
|
169
|
+
value={formData.urlField || ''}
|
170
|
+
onChange={handleFieldChange}
|
171
|
+
helperText="Tipo: url"
|
172
|
+
/>
|
173
|
+
|
174
|
+
<TextField2
|
175
|
+
id="dateField"
|
176
|
+
type="date"
|
177
|
+
label="Fecha"
|
178
|
+
value={formData.dateField || ''}
|
179
|
+
onChange={handleFieldChange}
|
180
|
+
helperText="Tipo: date"
|
181
|
+
/>
|
182
|
+
</div>
|
183
|
+
</div>
|
184
|
+
)
|
185
|
+
}
|
186
|
+
|
187
|
+
/**
|
188
|
+
* Specialized components
|
189
|
+
*/
|
190
|
+
export const SpecializedComponents = () => {
|
191
|
+
const [formData, setFormData] = useState({})
|
192
|
+
|
193
|
+
const handleFieldChange = (id, value) => {
|
194
|
+
setFormData(prev => ({
|
195
|
+
...prev,
|
196
|
+
[id]: value
|
197
|
+
}))
|
198
|
+
}
|
199
|
+
|
200
|
+
const dropdownOptions = [
|
201
|
+
{ value: 'option1', label: 'Opción 1' },
|
202
|
+
{ value: 'option2', label: 'Opción 2' },
|
203
|
+
{ value: 'option3', label: 'Opción 3' },
|
204
|
+
{ value: 'option4', label: 'Opción 4' }
|
205
|
+
]
|
206
|
+
|
207
|
+
return (
|
208
|
+
<div style={{ padding: '20px' }}>
|
209
|
+
<h3>🎯 Componentes Especializados</h3>
|
210
|
+
|
211
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
|
212
|
+
<div>
|
213
|
+
<h4>TextArea2</h4>
|
214
|
+
<TextArea2
|
215
|
+
id="textArea"
|
216
|
+
label="Descripción"
|
217
|
+
placeholder="Escribe una descripción detallada..."
|
218
|
+
value={formData.textArea || ''}
|
219
|
+
rows={4}
|
220
|
+
onChange={handleFieldChange}
|
221
|
+
helperText="Área de texto multilínea"
|
222
|
+
/>
|
223
|
+
</div>
|
224
|
+
|
225
|
+
<div>
|
226
|
+
<h4>PasswordField2</h4>
|
227
|
+
<PasswordField2
|
228
|
+
id="password"
|
229
|
+
label="Contraseña"
|
230
|
+
placeholder="Ingresa tu contraseña"
|
231
|
+
value={formData.password || ''}
|
232
|
+
onChange={handleFieldChange}
|
233
|
+
helperText="Campo de contraseña con toggle de visibilidad"
|
234
|
+
/>
|
235
|
+
</div>
|
236
|
+
|
237
|
+
<div>
|
238
|
+
<h4>DropDown2</h4>
|
239
|
+
<DropDown2
|
240
|
+
id="dropdown"
|
241
|
+
label="Selecciona una opción"
|
242
|
+
options={dropdownOptions}
|
243
|
+
value={formData.dropdown || ''}
|
244
|
+
onChange={handleFieldChange}
|
245
|
+
helperText="Dropdown con opciones"
|
246
|
+
/>
|
247
|
+
</div>
|
248
|
+
|
249
|
+
<div>
|
250
|
+
<h4>DateRange2</h4>
|
251
|
+
<DateRange2
|
252
|
+
id="dateRange"
|
253
|
+
label="Rango de fechas"
|
254
|
+
value={formData.dateRange || { start: '', end: '' }}
|
255
|
+
onChange={handleFieldChange}
|
256
|
+
helperText="Selector de rango de fechas"
|
257
|
+
/>
|
258
|
+
</div>
|
259
|
+
</div>
|
260
|
+
</div>
|
261
|
+
)
|
262
|
+
}
|
263
|
+
|
264
|
+
/**
|
265
|
+
* Field states
|
266
|
+
*/
|
267
|
+
export const FieldStates = () => {
|
268
|
+
const [formData, setFormData] = useState({
|
269
|
+
errorField: 'invalid-email',
|
270
|
+
disabledField: 'Campo deshabilitado',
|
271
|
+
readOnlyField: 'Campo de solo lectura'
|
272
|
+
})
|
273
|
+
|
274
|
+
const handleFieldChange = (id, value) => {
|
275
|
+
setFormData(prev => ({
|
276
|
+
...prev,
|
277
|
+
[id]: value
|
278
|
+
}))
|
279
|
+
}
|
280
|
+
|
281
|
+
return (
|
282
|
+
<div style={{ padding: '20px' }}>
|
283
|
+
<h3>🎭 Estados de Campos</h3>
|
284
|
+
|
285
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1rem' }}>
|
286
|
+
<TextField2
|
287
|
+
id="normalField"
|
288
|
+
label="Campo Normal"
|
289
|
+
placeholder="Estado normal"
|
290
|
+
value={formData.normalField || ''}
|
291
|
+
onChange={handleFieldChange}
|
292
|
+
helperText="Estado normal"
|
293
|
+
/>
|
294
|
+
|
295
|
+
<TextField2
|
296
|
+
id="errorField"
|
297
|
+
label="Campo con Error"
|
298
|
+
placeholder="Campo con error"
|
299
|
+
value={formData.errorField || ''}
|
300
|
+
error="Este campo contiene un error"
|
301
|
+
onChange={handleFieldChange}
|
302
|
+
helperText="Campo con estado de error"
|
303
|
+
/>
|
304
|
+
|
305
|
+
<TextField2
|
306
|
+
id="disabledField"
|
307
|
+
label="Campo Deshabilitado"
|
308
|
+
value={formData.disabledField}
|
309
|
+
disabled={true}
|
310
|
+
onChange={handleFieldChange}
|
311
|
+
helperText="Campo deshabilitado"
|
312
|
+
/>
|
313
|
+
|
314
|
+
<TextField2
|
315
|
+
id="readOnlyField"
|
316
|
+
label="Campo de Solo Lectura"
|
317
|
+
value={formData.readOnlyField}
|
318
|
+
readOnly={true}
|
319
|
+
onChange={handleFieldChange}
|
320
|
+
helperText="Campo de solo lectura"
|
321
|
+
/>
|
322
|
+
</div>
|
323
|
+
</div>
|
324
|
+
)
|
325
|
+
}
|
326
|
+
|
327
|
+
/**
|
328
|
+
* All examples combined
|
329
|
+
*/
|
330
|
+
export const AllExamples = () => (
|
331
|
+
<div>
|
332
|
+
<BasicTextFields />
|
333
|
+
<InputTypes />
|
334
|
+
<SpecializedComponents />
|
335
|
+
<FieldStates />
|
336
|
+
</div>
|
337
|
+
)
|
@@ -0,0 +1,285 @@
|
|
1
|
+
import React, { useState } from 'react'
|
2
|
+
import { Tree, TreeNode, TreeItem } from './tree'
|
3
|
+
|
4
|
+
export default {
|
5
|
+
title: 'HTML/Tree',
|
6
|
+
component: Tree,
|
7
|
+
parameters: {
|
8
|
+
docs: {
|
9
|
+
description: {
|
10
|
+
component: 'Tree components for hierarchical data display with support for selection, search, and drag & drop.'
|
11
|
+
}
|
12
|
+
}
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Basic Tree example
|
18
|
+
*/
|
19
|
+
export const BasicTree = () => {
|
20
|
+
const [selectedItem, setSelectedItem] = useState(null)
|
21
|
+
|
22
|
+
const handleSelect = (id) => {
|
23
|
+
setSelectedItem(id)
|
24
|
+
console.log('Selected:', id)
|
25
|
+
}
|
26
|
+
|
27
|
+
return (
|
28
|
+
<div style={{ padding: '20px' }}>
|
29
|
+
<h3>🌳 Tree Básico</h3>
|
30
|
+
<div style={{
|
31
|
+
background: '#fff',
|
32
|
+
border: '1px solid #ddd',
|
33
|
+
borderRadius: '8px',
|
34
|
+
overflow: 'hidden',
|
35
|
+
maxHeight: '400px'
|
36
|
+
}}>
|
37
|
+
<Tree>
|
38
|
+
<TreeNode id="root" label="Root Folder" icon="folder" open={true}>
|
39
|
+
<TreeNode id="documents" label="Documents" icon="folder">
|
40
|
+
<TreeItem
|
41
|
+
id="doc1"
|
42
|
+
label="Document 1.pdf"
|
43
|
+
icon="picture_as_pdf"
|
44
|
+
onSelect={handleSelect}
|
45
|
+
selected={selectedItem === 'doc1'}
|
46
|
+
/>
|
47
|
+
<TreeItem
|
48
|
+
id="doc2"
|
49
|
+
label="Document 2.docx"
|
50
|
+
icon="description"
|
51
|
+
onSelect={handleSelect}
|
52
|
+
selected={selectedItem === 'doc2'}
|
53
|
+
/>
|
54
|
+
</TreeNode>
|
55
|
+
<TreeNode id="images" label="Images" icon="folder" open={true}>
|
56
|
+
<TreeItem
|
57
|
+
id="img1"
|
58
|
+
label="Photo 1.jpg"
|
59
|
+
icon="image"
|
60
|
+
onSelect={handleSelect}
|
61
|
+
selected={selectedItem === 'img1'}
|
62
|
+
/>
|
63
|
+
<TreeItem
|
64
|
+
id="img2"
|
65
|
+
label="Photo 2.png"
|
66
|
+
icon="image"
|
67
|
+
onSelect={handleSelect}
|
68
|
+
selected={selectedItem === 'img2'}
|
69
|
+
/>
|
70
|
+
</TreeNode>
|
71
|
+
<TreeItem
|
72
|
+
id="readme"
|
73
|
+
label="README.md"
|
74
|
+
icon="description"
|
75
|
+
onSelect={handleSelect}
|
76
|
+
selected={selectedItem === 'readme'}
|
77
|
+
/>
|
78
|
+
</TreeNode>
|
79
|
+
</Tree>
|
80
|
+
</div>
|
81
|
+
{selectedItem && (
|
82
|
+
<div style={{
|
83
|
+
marginTop: '16px',
|
84
|
+
padding: '12px',
|
85
|
+
background: '#e3f2fd',
|
86
|
+
borderRadius: '4px',
|
87
|
+
border: '1px solid #1976d2'
|
88
|
+
}}>
|
89
|
+
<strong>Elemento seleccionado:</strong> {selectedItem}
|
90
|
+
</div>
|
91
|
+
)}
|
92
|
+
</div>
|
93
|
+
)
|
94
|
+
}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Tree with search
|
98
|
+
*/
|
99
|
+
export const SearchableTree = () => {
|
100
|
+
const [selectedItem, setSelectedItem] = useState(null)
|
101
|
+
|
102
|
+
const handleSelect = (id) => {
|
103
|
+
setSelectedItem(id)
|
104
|
+
}
|
105
|
+
|
106
|
+
return (
|
107
|
+
<div style={{ padding: '20px' }}>
|
108
|
+
<h3>🔍 Tree con Búsqueda</h3>
|
109
|
+
<div style={{
|
110
|
+
background: '#fff',
|
111
|
+
border: '1px solid #ddd',
|
112
|
+
borderRadius: '8px',
|
113
|
+
overflow: 'hidden',
|
114
|
+
maxHeight: '400px'
|
115
|
+
}}>
|
116
|
+
<Tree
|
117
|
+
searchable={true}
|
118
|
+
searchPlaceholder="Buscar archivos y carpetas..."
|
119
|
+
searchBy={['label']}
|
120
|
+
ariaLabel="Árbol de archivos con búsqueda"
|
121
|
+
>
|
122
|
+
<TreeNode id="projects" label="Projects" icon="work" open={true}>
|
123
|
+
<TreeNode id="project1" label="Website Project" icon="web" open={false}>
|
124
|
+
<TreeItem
|
125
|
+
id="index"
|
126
|
+
label="index.html"
|
127
|
+
icon="code"
|
128
|
+
onSelect={handleSelect}
|
129
|
+
selected={selectedItem === 'index'}
|
130
|
+
/>
|
131
|
+
<TreeItem
|
132
|
+
id="styles"
|
133
|
+
label="styles.css"
|
134
|
+
icon="palette"
|
135
|
+
onSelect={handleSelect}
|
136
|
+
selected={selectedItem === 'styles'}
|
137
|
+
/>
|
138
|
+
<TreeItem
|
139
|
+
id="script"
|
140
|
+
label="script.js"
|
141
|
+
icon="code"
|
142
|
+
onSelect={handleSelect}
|
143
|
+
selected={selectedItem === 'script'}
|
144
|
+
/>
|
145
|
+
</TreeNode>
|
146
|
+
<TreeNode id="project2" label="Mobile App" icon="phone_android" open={false}>
|
147
|
+
<TreeItem
|
148
|
+
id="main"
|
149
|
+
label="MainActivity.java"
|
150
|
+
icon="code"
|
151
|
+
onSelect={handleSelect}
|
152
|
+
selected={selectedItem === 'main'}
|
153
|
+
/>
|
154
|
+
<TreeItem
|
155
|
+
id="layout"
|
156
|
+
label="activity_main.xml"
|
157
|
+
icon="view_quilt"
|
158
|
+
onSelect={handleSelect}
|
159
|
+
selected={selectedItem === 'layout'}
|
160
|
+
/>
|
161
|
+
</TreeNode>
|
162
|
+
</TreeNode>
|
163
|
+
</Tree>
|
164
|
+
</div>
|
165
|
+
</div>
|
166
|
+
)
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Tree with checkboxes
|
171
|
+
*/
|
172
|
+
export const CheckableTree = () => {
|
173
|
+
const [checkedItems, setCheckedItems] = useState(['file1', 'file3'])
|
174
|
+
|
175
|
+
const handleCheck = (id, checked) => {
|
176
|
+
setCheckedItems(prev =>
|
177
|
+
checked
|
178
|
+
? [...prev, id]
|
179
|
+
: prev.filter(item => item !== id)
|
180
|
+
)
|
181
|
+
}
|
182
|
+
|
183
|
+
return (
|
184
|
+
<div style={{ padding: '20px' }}>
|
185
|
+
<h3>☑️ Tree con Checkboxes</h3>
|
186
|
+
<div style={{
|
187
|
+
background: '#fff',
|
188
|
+
border: '1px solid #ddd',
|
189
|
+
borderRadius: '8px',
|
190
|
+
overflow: 'hidden',
|
191
|
+
maxHeight: '400px'
|
192
|
+
}}>
|
193
|
+
<Tree>
|
194
|
+
<TreeNode id="backup" label="Backup Files" icon="backup" open={true}>
|
195
|
+
<TreeItem
|
196
|
+
id="file1"
|
197
|
+
label="config.json"
|
198
|
+
icon="settings"
|
199
|
+
checked={checkedItems.includes('file1')}
|
200
|
+
onCheck={handleCheck}
|
201
|
+
/>
|
202
|
+
<TreeItem
|
203
|
+
id="file2"
|
204
|
+
label="database.sql"
|
205
|
+
icon="storage"
|
206
|
+
checked={checkedItems.includes('file2')}
|
207
|
+
onCheck={handleCheck}
|
208
|
+
/>
|
209
|
+
<TreeItem
|
210
|
+
id="file3"
|
211
|
+
label="logs.txt"
|
212
|
+
icon="description"
|
213
|
+
checked={checkedItems.includes('file3')}
|
214
|
+
onCheck={handleCheck}
|
215
|
+
/>
|
216
|
+
</TreeNode>
|
217
|
+
</Tree>
|
218
|
+
</div>
|
219
|
+
{checkedItems.length > 0 && (
|
220
|
+
<div style={{
|
221
|
+
marginTop: '16px',
|
222
|
+
padding: '12px',
|
223
|
+
background: '#e8f5e8',
|
224
|
+
borderRadius: '4px',
|
225
|
+
border: '1px solid #4caf50'
|
226
|
+
}}>
|
227
|
+
<strong>Elementos seleccionados:</strong> {checkedItems.join(', ')}
|
228
|
+
</div>
|
229
|
+
)}
|
230
|
+
</div>
|
231
|
+
)
|
232
|
+
}
|
233
|
+
|
234
|
+
/**
|
235
|
+
* Empty tree
|
236
|
+
*/
|
237
|
+
export const EmptyTree = () => (
|
238
|
+
<div style={{ padding: '20px' }}>
|
239
|
+
<h3>📭 Tree Vacío</h3>
|
240
|
+
<div style={{
|
241
|
+
background: '#fff',
|
242
|
+
border: '1px solid #ddd',
|
243
|
+
borderRadius: '8px',
|
244
|
+
overflow: 'hidden',
|
245
|
+
minHeight: '200px'
|
246
|
+
}}>
|
247
|
+
<Tree
|
248
|
+
empty={true}
|
249
|
+
emptyMessage="No hay elementos para mostrar"
|
250
|
+
emptyIcon="folder_open"
|
251
|
+
/>
|
252
|
+
</div>
|
253
|
+
</div>
|
254
|
+
)
|
255
|
+
|
256
|
+
/**
|
257
|
+
* Loading tree
|
258
|
+
*/
|
259
|
+
export const LoadingTree = () => (
|
260
|
+
<div style={{ padding: '20px' }}>
|
261
|
+
<h3>⏳ Tree Cargando</h3>
|
262
|
+
<div style={{
|
263
|
+
background: '#fff',
|
264
|
+
border: '1px solid #ddd',
|
265
|
+
borderRadius: '8px',
|
266
|
+
overflow: 'hidden',
|
267
|
+
minHeight: '200px'
|
268
|
+
}}>
|
269
|
+
<Tree loading={true} />
|
270
|
+
</div>
|
271
|
+
</div>
|
272
|
+
)
|
273
|
+
|
274
|
+
/**
|
275
|
+
* All examples combined
|
276
|
+
*/
|
277
|
+
export const AllExamples = () => (
|
278
|
+
<div>
|
279
|
+
<BasicTree />
|
280
|
+
<SearchableTree />
|
281
|
+
<CheckableTree />
|
282
|
+
<EmptyTree />
|
283
|
+
<LoadingTree />
|
284
|
+
</div>
|
285
|
+
)
|