dars-framework 1.2.3__py3-none-any.whl

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.
Files changed (118) hide show
  1. dars/__init__.py +0 -0
  2. dars/all.py +69 -0
  3. dars/cli/__init__.py +0 -0
  4. dars/cli/doctor/__init__.py +1 -0
  5. dars/cli/doctor/detect.py +154 -0
  6. dars/cli/doctor/doctor.py +176 -0
  7. dars/cli/doctor/installers.py +100 -0
  8. dars/cli/doctor/persist.py +62 -0
  9. dars/cli/doctor/preflight.py +33 -0
  10. dars/cli/doctor/ui.py +54 -0
  11. dars/cli/hot_reload.py +33 -0
  12. dars/cli/main.py +1107 -0
  13. dars/cli/preview.py +448 -0
  14. dars/cli/translations.py +531 -0
  15. dars/components/__init__.py +0 -0
  16. dars/components/advanced/__init__.py +8 -0
  17. dars/components/advanced/accordion.py +26 -0
  18. dars/components/advanced/card.py +33 -0
  19. dars/components/advanced/modal.py +45 -0
  20. dars/components/advanced/navbar.py +44 -0
  21. dars/components/advanced/table.py +25 -0
  22. dars/components/advanced/tabs.py +31 -0
  23. dars/components/basic/__init__.py +34 -0
  24. dars/components/basic/button.py +55 -0
  25. dars/components/basic/checkbox.py +35 -0
  26. dars/components/basic/container.py +29 -0
  27. dars/components/basic/datepicker.py +139 -0
  28. dars/components/basic/image.py +36 -0
  29. dars/components/basic/input.py +57 -0
  30. dars/components/basic/link.py +31 -0
  31. dars/components/basic/markdown.py +86 -0
  32. dars/components/basic/page.py +20 -0
  33. dars/components/basic/progressbar.py +18 -0
  34. dars/components/basic/radiobutton.py +35 -0
  35. dars/components/basic/select.py +82 -0
  36. dars/components/basic/slider.py +63 -0
  37. dars/components/basic/spinner.py +12 -0
  38. dars/components/basic/text.py +23 -0
  39. dars/components/basic/textarea.py +46 -0
  40. dars/components/basic/tooltip.py +19 -0
  41. dars/components/layout/__init__.py +0 -0
  42. dars/components/layout/anchor.py +13 -0
  43. dars/components/layout/flex.py +26 -0
  44. dars/components/layout/grid.py +45 -0
  45. dars/config.py +134 -0
  46. dars/core/__init__.py +0 -0
  47. dars/core/app.py +957 -0
  48. dars/core/component.py +284 -0
  49. dars/core/events.py +102 -0
  50. dars/core/js_bridge.py +99 -0
  51. dars/core/properties.py +127 -0
  52. dars/core/state.py +309 -0
  53. dars/dars_tests/apps_test/health_check.py +56 -0
  54. dars/dars_tests/run_tests.py +275 -0
  55. dars/dars_tests/tests/test_advanced_components.py +69 -0
  56. dars/dars_tests/tests/test_basic_components.py +88 -0
  57. dars/dars_tests/tests/test_core_and_cli.py +17 -0
  58. dars/dars_tests/tests/test_layout_components.py +58 -0
  59. dars/dars_tests/tests/test_version_check.py +21 -0
  60. dars/docs/__init__.py +0 -0
  61. dars/docs/app.md +290 -0
  62. dars/docs/cli.md +80 -0
  63. dars/docs/components.md +1679 -0
  64. dars/docs/custom_components.md +30 -0
  65. dars/docs/events.md +45 -0
  66. dars/docs/exporters.md +162 -0
  67. dars/docs/getting_started.md +79 -0
  68. dars/docs/index.md +18 -0
  69. dars/docs/scripts.md +593 -0
  70. dars/docs/state_management.md +57 -0
  71. dars/exporters/__init__.py +0 -0
  72. dars/exporters/base.py +96 -0
  73. dars/exporters/web/OLD/html_css_js_OLD4.py +1538 -0
  74. dars/exporters/web/OLD/html_css_js_old.py +1406 -0
  75. dars/exporters/web/OLD/html_css_js_old2.py +1406 -0
  76. dars/exporters/web/__init__.py +0 -0
  77. dars/exporters/web/html_css_js.py +2675 -0
  78. dars/exporters/web/vdom.py +251 -0
  79. dars/js_lib.py +206 -0
  80. dars/scripts/__init__.py +0 -0
  81. dars/scripts/dscript.py +26 -0
  82. dars/scripts/script.py +39 -0
  83. dars/security.py +195 -0
  84. dars/templates/__init__.py +0 -0
  85. dars/templates/__pycache__/__init__.cpython-311.pyc +0 -0
  86. dars/templates/examples/README.md +4 -0
  87. dars/templates/examples/__pycache__/dynamic_event_demo.cpython-311.pyc +0 -0
  88. dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +275 -0
  89. dars/templates/examples/advanced/SimpleDashboard/dashboard.py +437 -0
  90. dars/templates/examples/advanced/SimpleModermWeb/modern_web_app.py +452 -0
  91. dars/templates/examples/advanced/VariousComponents/all_components_demo.py +87 -0
  92. dars/templates/examples/advanced/__init__.py +0 -0
  93. dars/templates/examples/advanced/dState/state_mods_demo.py +68 -0
  94. dars/templates/examples/basic/Forms/form_components.py +516 -0
  95. dars/templates/examples/basic/Forms/simple_form.py +379 -0
  96. dars/templates/examples/basic/HelloWorld/hello_world.py +56 -0
  97. dars/templates/examples/basic/Layouts/flex_layout_responsive.py +13 -0
  98. dars/templates/examples/basic/Layouts/grid_layout_responsive.py +12 -0
  99. dars/templates/examples/basic/Layouts/layout_multipage_demo.py +23 -0
  100. dars/templates/examples/basic/Multipage/multipage_example.py +67 -0
  101. dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
  102. dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
  103. dars/templates/examples/basic/PWA/pwa_custom_icons.py +33 -0
  104. dars/templates/examples/basic/__init__.py +0 -0
  105. dars/templates/examples/demo/__pycache__/complete_app.cpython-311.pyc +0 -0
  106. dars/templates/examples/demo/complete_app.py +21 -0
  107. dars/templates/examples/markdown/MarkdownTemplate/README.md +159 -0
  108. dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +21 -0
  109. dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +1 -0
  110. dars/templates/examples/markdown/__init__.py +0 -0
  111. dars/templates/html/__init__.py +0 -0
  112. dars/version.py +2 -0
  113. dars_framework-1.2.3.dist-info/METADATA +15 -0
  114. dars_framework-1.2.3.dist-info/RECORD +118 -0
  115. dars_framework-1.2.3.dist-info/WHEEL +5 -0
  116. dars_framework-1.2.3.dist-info/entry_points.txt +2 -0
  117. dars_framework-1.2.3.dist-info/licenses/LICENSE +21 -0
  118. dars_framework-1.2.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1679 @@
1
+ The documentstion of dars is moving to the documentation official website please visit https://ztamdev.github.io/Dars-Framework/documentation.html because this documents will be deprecated in some time...
2
+
3
+ # Dars - Components Documentation
4
+
5
+ ---
6
+
7
+ ## Barrel Import
8
+
9
+ You can now import all main components and modules with a single line:
10
+
11
+ ```python
12
+ from dars.all import *
13
+ ```
14
+
15
+ This simplifies integration and improves the developer experience.
16
+ > But if you crate your own components it can cause conflicts with names of your components and built in components if they have the same name.
17
+
18
+ ---
19
+
20
+ ## Introduction to Components
21
+
22
+ Components are the fundamental elements of Dars that represent UI elements. Each component encapsulates its appearance, behavior, and state, allowing you to create complex interfaces by composing simple elements.
23
+
24
+ To learn how to create your own custom components, refer to the documentation in [Custom Components](#custom-components-in-dars-framework).
25
+
26
+ ## Event Handling with dScript
27
+
28
+ Dars provides a powerful way to handle user interactions through the `dScript` class. You can attach event handlers to interactive components like `Button` and `Input` to create dynamic and responsive user interfaces.
29
+
30
+ For a complete list of available event types and how to use them, refer to the documentation in [Events](#events-in-dars).
31
+
32
+ ### Basic Usage
33
+
34
+ ```python
35
+ from dars.scripts.dscript import dScript
36
+
37
+ # Button with click handler
38
+ button = Button(
39
+ text="Click me",
40
+ on_click=dScript("""
41
+ function handleClick(event) {
42
+ alert('Button was clicked!');
43
+ // Access the button element
44
+ const button = event.target;
45
+ // Toggle a class on click
46
+ button.classList.toggle('clicked');
47
+ }
48
+ """)
49
+ )
50
+
51
+ # Input with change handler
52
+ input_field = Input(
53
+ placeholder="Type something...",
54
+ on_change=dScript("""
55
+ function handleChange(event) {
56
+ console.log('Input value changed to:', event.target.value);
57
+ // Add validation or other logic here
58
+ if (event.target.value.length < 3) {
59
+ event.target.style.borderColor = 'red';
60
+ } else {
61
+ event.target.style.borderColor = 'green';
62
+ }
63
+ }
64
+ """
65
+ )
66
+ ```
67
+
68
+ ### Available Events
69
+
70
+ | Component | Event | Description |
71
+ |-----------|-------|-------------|
72
+ | `Button` | `on_click` | Triggered when the button is clicked |
73
+ | `Button` | `on_double_click` | Triggered on double click |
74
+ | `Button` | `on_mouse_enter` | Triggered when mouse enters the button |
75
+ | `Button` | `on_mouse_leave` | Triggered when mouse leaves the button |
76
+ | `Input` | `on_change` | Triggered when input value changes |
77
+ | `Input` | `on_key_up` | Triggered when a key is released |
78
+ | `Input` | `on_key_down` | Triggered when a key is pressed |
79
+
80
+ ### Best Practices
81
+
82
+ 1. **Use Named Functions**: Makes debugging easier and allows reusing the same function for multiple events.
83
+ 2. **Keep Handlers Small**: Move complex logic to separate functions in your JavaScript code.
84
+ 3. **Access Event Object**: The event object provides useful properties like `target`, `keyCode`, etc.
85
+ 4. **Return `false`** to prevent default behavior when needed.
86
+
87
+ ---
88
+
89
+ ### Quick Access
90
+
91
+ - [Base Component Class](#base-component-class)
92
+ - [Component Search](#component-search-and-modification)
93
+ - [Page](#page)
94
+ - [Text](#text)
95
+ - [Button](#button)
96
+ - [Input](#input)
97
+ - [Container](#container)
98
+ - [Markdown](#markdown)
99
+ - [Image](#image)
100
+ - [Link](#link)
101
+ - [Textarea](#textarea)
102
+ - [Checkbox](#checkbox)
103
+ - [RadioButton](#radiobutton)
104
+ - [Select](#select)
105
+ - [Slider](#slider)
106
+ - [ProgressBar](#progressBar)
107
+ - [Tooltip](#tooltip)
108
+ - [DatePicker](#datepicker)
109
+ - [Card](#card)
110
+ - [Modal](#modal)
111
+ - [Navbar](#navbar)
112
+ - [Accordion](#accordion)
113
+ - [Tabs](#tabs)
114
+ - [Table](#table)
115
+ - [Layout Components](#layout-components)
116
+ - [GridLayout](#gridlayout)
117
+ - [FlexLayout](#flexlayout)
118
+ - [LayoutBase](#layoutbase)
119
+ - [AnchorPoint](#anchorpoint)
120
+
121
+ ---
122
+
123
+ ## Base Component Class
124
+
125
+ All components in Dars inherit from the base `Component` class, which provides common functionality:
126
+
127
+ ```python
128
+ from dars.core.component import Component
129
+
130
+ class Component(ABC):
131
+ def __init__(self, **props):
132
+ self.props = props
133
+ self.children = []
134
+ self.parent = None
135
+ self.id = props.get("id")
136
+ self.class_name = props.get("class_name")
137
+ self.style = props.get("style", {})
138
+ self.events = {}
139
+ ```
140
+
141
+ ### Common Properties
142
+
143
+ All components support these basic properties:
144
+
145
+ - **id**: Unique component identifier
146
+ - **class_name**: CSS class for additional styles
147
+ - **style**: Dictionary of CSS styles
148
+ - **children**: List of child components (for containers)
149
+
150
+ ### Component-Search-and-Modification
151
+
152
+ All components include a powerful search and modification system through the `find()` method. This allows you to search for components in the component tree and modify their attributes using a fluent interface.
153
+
154
+ #### Basic Search
155
+
156
+ ```python
157
+ # Find by ID
158
+ component.find(id="search-button")
159
+
160
+ # Find by CSS class
161
+ component.find(class_name="primary-button")
162
+
163
+ # Find by component type
164
+ component.find(type="Button") # or type=Button
165
+
166
+ # Find using a custom predicate
167
+ component.find(predicate=lambda c: "welcome" in c.text.lower())
168
+ ```
169
+
170
+ #### Chained Searches
171
+
172
+ You can chain multiple `find()` calls to search within the results of previous searches:
173
+
174
+ ```python
175
+ # Find a container and then search within it
176
+ component.find(id="main-container")\
177
+ .find(type="Text")\
178
+ .attr(text="New text")
179
+
180
+ # Multiple levels of search
181
+ component.find(class_name="section")\
182
+ .find(type="Container")\
183
+ .find(id="special-text")\
184
+ .attr(text="Modified text")
185
+ ```
186
+
187
+ #### Modifying Components
188
+
189
+ Use the `attr()` method to modify the found components:
190
+
191
+ ```python
192
+ # Modify styles
193
+ component.find(type="Button").attr(
194
+ style={"background-color": "red", "color": "white"}
195
+ )
196
+
197
+ # Modify class names
198
+ component.find(class_name="btn").attr(
199
+ class_name="btn primary"
200
+ )
201
+
202
+ # Modify component-specific attributes
203
+ component.find(type="Text").attr(
204
+ text="New content"
205
+ )
206
+
207
+ # Multiple modifications at once
208
+ component.find(type="Input").attr(
209
+ placeholder="Type here...",
210
+ style={"padding": "10px"},
211
+ class_name="modern-input"
212
+ )
213
+ ```
214
+
215
+ #### Getting Results
216
+
217
+ ```python
218
+ # Get all matched components
219
+ components = component.find(type="Button").get()
220
+
221
+ # Get only the first match
222
+ first_button = component.find(type="Button").first()
223
+ ```
224
+
225
+ #### Search Parameters
226
+
227
+ | Parameter | Type | Description | Example |
228
+ |-----------|------|-------------|---------|
229
+ | `id` | str | Search by component ID | `find(id="search-btn")` |
230
+ | `class_name` | str | Search by CSS class | `find(class_name="primary")` |
231
+ | `type` | str/Type | Search by component type | `find(type="Button")` or `find(type=Button)` |
232
+ | `predicate` | Callable | Custom search function | `find(predicate=lambda c: len(c.children) > 0)` |
233
+
234
+ ### Page
235
+
236
+ The `Page` component represents the root of a multipage app. It can contain other components and scripts specific to that page.
237
+
238
+ #### Syntax
239
+
240
+ ```python
241
+ from dars.components.basic import Page, Text, Button
242
+ from dars.scripts.script import InlineScript
243
+ page = Page(
244
+ Text("Bienvenido!"),
245
+ Button("Click aquí", id="btn-demo")
246
+ )
247
+ # Añadir script JS solo a esta página
248
+ page.add_script(InlineScript("""
249
+ document.addEventListener('DOMContentLoaded', function() {
250
+ var btn = document.getElementById('btn-demo');
251
+ if (btn) btn.onclick = () => alert('¡Botón de esta página!');
252
+ });
253
+ """))
254
+ ```
255
+
256
+ Use `Page` as the root of each page in the multipage system. Allows passing children directly as arguments and JS scripts per page.
257
+
258
+ #### Properties
259
+
260
+ | Property | Type | Description |
261
+ |-------------|--------|-----------------------------------------------------|
262
+ | `children` | list | List of child components |
263
+ | `anchors` | dict | Optional anchor points for child placement |
264
+
265
+ #### Page Scripts System
266
+
267
+ The new page scripts system allows assigning scripts to specific pages instead of globally:
268
+
269
+ * **Adding Scripts**:
270
+ Use the `add_script()` method on a page instance.
271
+
272
+ ```python
273
+ from dars.scripts.dscript import dScript
274
+
275
+ index.add_script(
276
+ dScript(code="console.log('Hello world')")
277
+ )
278
+ ```
279
+
280
+ ### Text
281
+
282
+ The `Text` component displays static or dynamic text.
283
+
284
+ #### Syntax
285
+
286
+ ```python
287
+ from dars.components.basic.text import Text
288
+
289
+ text = Text(
290
+ text="Contenido del text",
291
+ id="mi-text",
292
+ class_name="text-principal",
293
+ style={
294
+ "font-size": "16px",
295
+ "color": "#333",
296
+ "font-weight": "bold"
297
+ }
298
+ )
299
+ ```
300
+
301
+ #### Properties
302
+
303
+ | Property | Type | Description | Example |
304
+ |-----------|------|-------------|---------|
305
+ | `text` | str | Text content | `"Hello world"` |
306
+ | `id` | str | Unique identifier | `"title-primary"` |
307
+ | `class_name` | str | CSS class | `"text-highlight"` |
308
+ | `style` | dict | CSS styles | `{"color": "red"}` |
309
+
310
+ #### Common Styles
311
+
312
+ ```python
313
+ # Título principal
314
+ title = Text(
315
+ text="Título Principal",
316
+ style={
317
+ "font-size": "32px",
318
+ "font-weight": "bold",
319
+ "color": "#2c3e50",
320
+ "margin-bottom": "20px",
321
+ "text-align": "center"
322
+ }
323
+ )
324
+
325
+ # Párrafo de contenido
326
+ paragraph = Text(
327
+ text="Este es un párrafo de ejemplo con contenido descriptivo.",
328
+ style={
329
+ "font-size": "16px",
330
+ "line-height": "1.6",
331
+ "color": "#34495e",
332
+ "margin-bottom": "15px"
333
+ }
334
+ )
335
+
336
+ # Texto pequeño
337
+ note = Text(
338
+ text="Nota: Esta información es importante.",
339
+ style={
340
+ "font-size": "12px",
341
+ "color": "#7f8c8d",
342
+ "font-style": "italic"
343
+ }
344
+ )
345
+ ```
346
+
347
+ ### Button
348
+
349
+ The `Button` component creates interactive buttons that can execute actions.
350
+
351
+ #### Syntax
352
+
353
+ ```python
354
+ from dars.components.basic.button import Button
355
+
356
+ boton = Button(
357
+ text="Hacer clic",
358
+ button_type="button", # "button", "submit", "reset"
359
+ disabled=False,
360
+ on_click=dScript("""
361
+ function handleClick() {
362
+ alert('Button clicked!');
363
+ }
364
+ """)
365
+ style={
366
+ "background-color": "#3498db",
367
+ "color": "white",
368
+ "padding": "10px 20px",
369
+ "border": "none",
370
+ "border-radius": "4px"
371
+ }
372
+ )
373
+ ```
374
+
375
+ #### Properties
376
+
377
+ | Property | Type | Description | Values |
378
+ |-----------|------|-------------|---------|
379
+ | `text` | str | Button text | `"Enviar"` |
380
+ | `button_type` | str | Button type | `"button"`, `"submit"`, `"reset"` |
381
+ | `disabled` | bool | Si está deshabilitado | `True`, `False` |
382
+ | `on_click` | dScript | Click handler | `dScript("function() { ... }")` |
383
+ | `on_double_click` | dScript | Double click handler | `dScript("function() { ... }")` |
384
+ | `on_mouse_enter` | dScript | Mouse enter handler | `dScript("function() { ... }")` |
385
+ | `on_mouse_leave` | dScript | Mouse leave handler | `dScript("function() { ... }")` |
386
+ | `on_key_up` | dScript | Key up handler | `dScript("function(e) { ... }")` |
387
+ | `on_key_down` | dScript | Key down handler | `dScript("function(e) { ... }")` |
388
+
389
+ #### Button Examples
390
+
391
+ ```python
392
+ # Primary Button
393
+ primary_button = Button(
394
+ text="Acción Principal",
395
+ style={
396
+ "background-color": "#007bff",
397
+ "color": "white",
398
+ "padding": "12px 24px",
399
+ "border": "none",
400
+ "border-radius": "6px",
401
+ "font-size": "16px",
402
+ "font-weight": "500",
403
+ "cursor": "pointer",
404
+ "transition": "background-color 0.3s"
405
+ }
406
+ )
407
+
408
+ # Secondary Button
409
+ secondary_button = Button(
410
+ text="Cancelar",
411
+ style={
412
+ "background-color": "transparent",
413
+ "color": "#6c757d",
414
+ "padding": "12px 24px",
415
+ "border": "1px solid #6c757d",
416
+ "border-radius": "6px",
417
+ "font-size": "16px",
418
+ "cursor": "pointer"
419
+ }
420
+ )
421
+
422
+ # Danger Button
423
+ delete_button = Button(
424
+ text="Eliminar",
425
+ style={
426
+ "background-color": "#dc3545",
427
+ "color": "white",
428
+ "padding": "8px 16px",
429
+ "border": "none",
430
+ "border-radius": "4px",
431
+ "font-size": "14px"
432
+ }
433
+ )
434
+
435
+ # Disabled Button
436
+ disabled_button = Button(
437
+ text="No disponible",
438
+ disabled=True,
439
+ style={
440
+ "background-color": "#e9ecef",
441
+ "color": "#6c757d",
442
+ "padding": "10px 20px",
443
+ "border": "none",
444
+ "border-radius": "4px",
445
+ "cursor": "not-allowed"
446
+ }
447
+ )
448
+ ```
449
+
450
+ ### Input
451
+
452
+ The `Input` component allows user data entry.
453
+
454
+ #### Syntax
455
+
456
+ ```python
457
+ from dars.components.basic.input import Input
458
+
459
+ entrada = Input(
460
+ value="Valor inicial",
461
+ placeholder="Escribe aquí...",
462
+ input_type="text", # "text", "password", "email", "number", etc.
463
+ disabled=False,
464
+ readonly=False,
465
+ required=False,
466
+ max_length=100,
467
+ on_change=dScript("""
468
+ function handleChange(event) {
469
+ console.log('Input changed:', event.target.value);
470
+ }
471
+ """)
472
+ style={
473
+ "width": "300px",
474
+ "padding": "10px",
475
+ "border": "1px solid #ddd",
476
+ "border-radius": "4px"
477
+ }
478
+ )
479
+ ```
480
+
481
+ #### Properties
482
+
483
+ | Property | Type | Description | Values |
484
+ |-----------|------|-------------|---------|
485
+ | `value` | str | Initial value | `"text"` |
486
+ | `placeholder` | str | Help text | `"Ingresa tu name"` |
487
+ | `input_type` | str | Tipo de entrada | `"text"`, `"password"`, `"email"`, `"number"` |
488
+ | `disabled` | bool | Si está deshabilitado | `True`, `False` |
489
+ | `readonly` | bool | Solo lectura | `True`, `False` |
490
+ | `required` | bool | Campo obligatorio | `True`, `False` |
491
+ | `on_change` | dScript | Change handler | `dScript("function(e) { ... }")` |
492
+ | `on_key_up` | dScript | Key up handler | `dScript("function(e) { ... }")` |
493
+ | `on_key_down` | dScript | Key down handler | `dScript("function(e) { ... }")` |
494
+ | `max_length` | int | Longitud máxima | `50` |
495
+ | `min_length` | int | Longitud mínima | `3` |
496
+ | `pattern` | str | Validation pattern | `"[0-9]+"` |
497
+
498
+ #### Input Types
499
+
500
+ ```python
501
+ # Basic text input
502
+ name = Input(
503
+ placeholder="Ingresa tu name",
504
+ input_type="text",
505
+ required=True,
506
+ style={
507
+ "width": "100%",
508
+ "padding": "12px",
509
+ "border": "2px solid #e1e5e9",
510
+ "border-radius": "8px",
511
+ "font-size": "16px"
512
+ }
513
+ )
514
+
515
+ # Email input
516
+ email = Input(
517
+ placeholder="tu@email.com",
518
+ input_type="email",
519
+ required=True,
520
+ style={
521
+ "width": "100%",
522
+ "padding": "12px",
523
+ "border": "2px solid #e1e5e9",
524
+ "border-radius": "8px"
525
+ }
526
+ )
527
+
528
+ # Password input
529
+ password = Input(
530
+ placeholder="Contraseña",
531
+ input_type="password",
532
+ required=True,
533
+ min_length=8,
534
+ style={
535
+ "width": "100%",
536
+ "padding": "12px",
537
+ "border": "2px solid #e1e5e9",
538
+ "border-radius": "8px"
539
+ }
540
+ )
541
+
542
+ # Numeric input
543
+ edad = Input(
544
+ placeholder="Edad",
545
+ input_type="number",
546
+ style={
547
+ "width": "100px",
548
+ "padding": "8px",
549
+ "border": "1px solid #ccc",
550
+ "border-radius": "4px",
551
+ "text-align": "center"
552
+ }
553
+ )
554
+
555
+ # Search input
556
+ busqueda = Input(
557
+ placeholder="Buscar...",
558
+ input_type="search",
559
+ style={
560
+ "width": "300px",
561
+ "padding": "10px 15px",
562
+ "border": "1px solid #ddd",
563
+ "border-radius": "20px",
564
+ "background-color": "#f8f9fa"
565
+ }
566
+ )
567
+ ```
568
+
569
+ ### Container
570
+
571
+ The `Container` component is a container that can hold other components. It supports multiple ways to add child components.
572
+
573
+ #### Syntax
574
+
575
+ ```python
576
+ from dars.components.basic.container import Container
577
+
578
+ # Method 1: Pass components as arguments
579
+ container = Container(
580
+ Text("Hello"),
581
+ Button("Click me"),
582
+ style={
583
+ "display": "flex",
584
+ "flex-direction": "column",
585
+ "padding": "20px",
586
+ "background-color": "#f8f9fa"
587
+ }
588
+ )
589
+
590
+ # Method 2: Use additional_children parameter
591
+ components = [Text("Hello"), Button("Click me")]
592
+ container = Container(
593
+ additional_children=components,
594
+ style={
595
+ "display": "flex",
596
+ "flex-direction": "column",
597
+ "padding": "20px",
598
+ "background-color": "#f8f9fa"
599
+ }
600
+ )
601
+
602
+ # Method 3: Add children after creation
603
+ container = Container(style={
604
+ "display": "flex",
605
+ "flex-direction": "column",
606
+ "padding": "20px",
607
+ "background-color": "#f8f9fa"
608
+ })
609
+ container.add_child(Text("Hello"))
610
+ container.add_child(Button("Click me"))
611
+ ```
612
+
613
+ #### Properties
614
+
615
+ | Property | Type | Description |
616
+ |-----------|------|-------------|
617
+ | `children` | tuple | Components passed as positional arguments |
618
+ | `additional_children` | list | Optional list of additional components |
619
+
620
+ #### Container Layouts
621
+
622
+ ```python
623
+ # Vertical layout (column)
624
+ columna = Container(
625
+ style={
626
+ "display": "flex",
627
+ "flex-direction": "column",
628
+ "gap": "15px",
629
+ "padding": "20px"
630
+ }
631
+ )
632
+
633
+ # Horizontal layout (row)
634
+ fila = Container(
635
+ style={
636
+ "display": "flex",
637
+ "flex-direction": "row",
638
+ "gap": "20px",
639
+ "align-items": "center"
640
+ }
641
+ )
642
+
643
+ # Layout centrado
644
+ centrado = Container(
645
+ style={
646
+ "display": "flex",
647
+ "justify-content": "center",
648
+ "align-items": "center",
649
+ "min-height": "100vh",
650
+ "background-color": "#f0f2f5"
651
+ }
652
+ )
653
+
654
+ # Card/Tarjeta
655
+ tarjeta = Container(
656
+ style={
657
+ "background-color": "white",
658
+ "border-radius": "12px",
659
+ "padding": "24px",
660
+ "box-shadow": "0 2px 10px rgba(0,0,0,0.1)",
661
+ "max-width": "400px",
662
+ "margin": "20px auto"
663
+ }
664
+ )
665
+
666
+ # Sidebar
667
+ sidebar = Container(
668
+ style={
669
+ "width": "250px",
670
+ "height": "100vh",
671
+ "background-color": "#2c3e50",
672
+ "padding": "20px",
673
+ "position": "fixed",
674
+ "left": "0",
675
+ "top": "0"
676
+ }
677
+ )
678
+ ```
679
+
680
+ # Markdown
681
+
682
+ The `Markdown` component allows you to render markdown content directly in your Dars applications, converting markdown syntax to beautiful HTML with proper styling.
683
+
684
+ ## Syntax
685
+
686
+ ```python
687
+ from dars.components.basic.markdown import Markdown
688
+
689
+ # From string content
690
+ markdown_component = Markdown(
691
+ content="# Welcome\nThis is **markdown** content",
692
+ id="my-markdown",
693
+ class_name="custom-markdown",
694
+ style={"padding": "20px"}
695
+ )
696
+
697
+ # From file
698
+ markdown_from_file = Markdown(
699
+ file_path="README.md",
700
+ id="documentation",
701
+ dark_theme=True
702
+ )
703
+ ```
704
+
705
+ ## Properties
706
+
707
+ | Property | Type | Description | Example |
708
+ |-----------|------|-------------|---------|
709
+ | `content` | str | Markdown content as string | `"# Heading"` |
710
+ | `file_path` | str | Path to a markdown file | `"docs/intro.md"` |
711
+ | `dark_theme` | bool | Enable dark theme styling | `True` |
712
+ | `id` | str | Component ID | `"markdown-content"` |
713
+ | `class_name` | str | CSS class | `"markdown-body"` |
714
+ | `style` | dict | CSS styles | `{"fontSize": "16px"}` |
715
+
716
+ ## Methods
717
+
718
+ | Method | Description | Example |
719
+ |--------|-------------|---------|
720
+ | `update_content(new_content=None, new_file_path=None)` | Update markdown content | `markdown_component.update_content(new_content="# New")` |
721
+ | `set_dark_theme(enabled=True)` | Enable/disable dark theme | `markdown_component.set_dark_theme(True)` |
722
+
723
+ ## Examples
724
+
725
+ ```python
726
+ # Simple markdown from string
727
+ simple_md = Markdown(
728
+ content="# Hello\nThis is a **markdown** example",
729
+ style={"maxWidth": "800px", "margin": "0 auto"}
730
+ )
731
+
732
+ # Load from file with dark theme
733
+ docs_md = Markdown(
734
+ file_path="documentation.md",
735
+ dark_theme=True,
736
+ class_name="docs-content"
737
+ )
738
+
739
+ # Update content dynamically
740
+ simple_md.update_content(new_content="# Updated\nNew content here")
741
+ ```
742
+
743
+ ## Dependencies
744
+
745
+ The Markdown component requires the `markdown2` library. Included with the framework.
746
+
747
+ ## Supported Markdown Features
748
+
749
+ - Headers (`#`, `##`, `###`)
750
+ - **Bold** and *italic* text
751
+ - Lists (ordered and unordered)
752
+ - [Links](https://github.com/ZtaMDev/Dars-Framework)
753
+ - `Inline code` and code blocks
754
+ - Tables
755
+ - Blockquotes
756
+ - Images
757
+ - Horizontal rules
758
+
759
+ ## Styling
760
+
761
+ The Markdown component includes comprehensive default styling for both light and dark themes:
762
+
763
+ ```python
764
+ # Light theme (default)
765
+ markdown_light = Markdown(content="# Light theme")
766
+
767
+ # Dark theme
768
+ markdown_dark = Markdown(
769
+ content="# Dark theme",
770
+ dark_theme=True,
771
+ style={"padding": "20px", "borderRadius": "8px"}
772
+ )
773
+ ```
774
+
775
+ ## Best Practices
776
+
777
+ 1. Use file paths for large documentation content
778
+ 2. Enable dark theme for better readability in low-light environments
779
+ 3. Combine with layout components for responsive designs
780
+ 4. Use the update methods for dynamic content changes
781
+
782
+ ## Integration Example
783
+
784
+ ```python
785
+ from dars.core.app import App
786
+ from dars.components.basic.markdown import Markdown
787
+ from dars.components.basic.container import Container
788
+
789
+ app = App(title="Documentation Viewer")
790
+
791
+ # Load documentation from file
792
+ docs = Markdown(
793
+ file_path="README.md",
794
+ dark_theme=True,
795
+ class_name="documentation",
796
+ style={
797
+ "maxWidth": "800px",
798
+ "margin": "0 auto",
799
+ "padding": "40px",
800
+ "lineHeight": "1.6"
801
+ }
802
+ )
803
+
804
+ app.set_root(Container(children=[docs]))
805
+ ```
806
+
807
+ This component is perfect for creating documentation pages, blog posts, content management systems, and any application that needs to display formatted text content.
808
+
809
+ ### Image
810
+
811
+ The `Image` component displays images.
812
+
813
+ #### Syntax
814
+
815
+ ```python
816
+ from dars.components.basic.image import Image
817
+
818
+ image = Image(
819
+ src="path/to/your/image.jpg",
820
+ alt="Descripción de la image",
821
+ width="300px",
822
+ height="200px",
823
+ class_name="responsive-img",
824
+ style={
825
+ "border-radius": "8px",
826
+ "box-shadow": "0 4px 8px rgba(0,0,0,0.1)"
827
+ }
828
+ )
829
+ ```
830
+
831
+ #### Properties
832
+
833
+ | Property | Type | Description | Example |
834
+ |-----------|------|-------------|---------|
835
+ | `src` | str | Image path | `"images/logo.png"` |
836
+ | `alt` | str | Alternative text | `"Logo of the company"` |
837
+ | `width` | str | Ancho de la image (CSS) | `"100%"`, `"200px"` |
838
+ | `height` | str | Alto de la image (CSS) | `"auto"`, `"150px"` |
839
+
840
+ ### Link
841
+
842
+ The `Link` component creates navigation links.
843
+
844
+ #### Syntax
845
+
846
+ ```python
847
+ from dars.components.basic.link import Link
848
+
849
+ link = Link(
850
+ text="Visitar Google",
851
+ href="https://www.google.com",
852
+ target="_blank", # Abre en una nueva pestaña
853
+ class_name="external-link",
854
+ style={
855
+ "color": "#007bff",
856
+ "text-decoration": "none",
857
+ "font-weight": "bold"
858
+ }
859
+ )
860
+ ```
861
+
862
+ #### Properties
863
+
864
+ | Property | Type | Description | Values |
865
+ |-----------|------|-------------|---------|
866
+ | `text` | str | Link text | `"Ir a la página"` |
867
+ | `href` | str | URL of destination | `"/about"`, `"https://example.com"` |
868
+ | `target` | str | Dónde abrir el link | `"_self"` (misma pestaña), `"_blank"` (nueva pestaña) |
869
+
870
+ ### Textarea
871
+
872
+ The `Textarea` component allows for multi-line text input.
873
+
874
+ #### Syntax
875
+
876
+ ```python
877
+ from dars.components.basic.textarea import Textarea
878
+
879
+ area_text = Textarea(
880
+ value="Texto inicial",
881
+ placeholder="Escribe tu mensaje aquí...",
882
+ rows=5,
883
+ cols=40,
884
+ disabled=False,
885
+ readonly=False,
886
+ required=True,
887
+ max_length=500,
888
+ class_name="comment-box",
889
+ style={
890
+ "width": "100%",
891
+ "padding": "10px",
892
+ "border": "1px solid #ccc",
893
+ "border-radius": "5px"
894
+ }
895
+ )
896
+ ```
897
+
898
+ #### Properties
899
+
900
+ | Property | Type | Description | Values |
901
+ |-----------|------|-------------|---------|
902
+ | `value` | str | Initial value | `""` |
903
+ | `placeholder` | str | Help text | `"Escribe aquí..."` |
904
+ | `rows` | int | Número de filas visibles | `4` |
905
+ | `cols` | int | Número de columnas visibles | `50` |
906
+ | `disabled` | bool | Si está deshabilitado | `True`, `False` |
907
+ | `readonly` | bool | Solo lectura | `True`, `False` |
908
+ | `required` | bool | Campo obligatorio | `True`, `False` |
909
+ | `max_length` | int | Longitud máxima | `500` |
910
+
911
+ ---
912
+
913
+ ---
914
+
915
+ ### ProgressBar
916
+
917
+ The `ProgressBar` component visually displays progress for a task, such as loading or completion percentage.
918
+
919
+ #### Syntax
920
+
921
+ ```python
922
+ from dars.components.basic.progressbar import ProgressBar
923
+
924
+ progress = ProgressBar(value=40, max_value=100)
925
+ ```
926
+
927
+ #### Properties
928
+
929
+ | Property | Type | Description |
930
+ |-------------|------|-----------------------------------|
931
+ | `value` | int | Current progress value |
932
+ | `max_value` | int | Maximum value (default: 100) |
933
+
934
+ #### Example
935
+
936
+ ```python
937
+ progress = ProgressBar(value=75, max_value=100)
938
+ ```
939
+
940
+ ---
941
+
942
+ ### Tooltip
943
+
944
+ The `Tooltip` component displays a tooltip when hovering over a child component.
945
+
946
+ #### Syntax
947
+
948
+ ```python
949
+ from dars.components.basic.tooltip import Tooltip
950
+ from dars.components.basic.button import Button
951
+
952
+ tooltip = Tooltip(
953
+ text="More info",
954
+ child=Button(text="Hover me")
955
+ )
956
+ ```
957
+
958
+ #### Properties
959
+
960
+ | Property | Type | Description |
961
+ |------------|-----------|-----------------------------------------|
962
+ | `text` | str | Tooltip text |
963
+ | `child` | Component | Component to wrap |
964
+ | `position` | str | Tooltip position (e.g., "top") |
965
+
966
+ #### Example
967
+
968
+ ```python
969
+ tooltip = Tooltip(text="Help", child=Button(text="?"))
970
+ ```
971
+
972
+ ---
973
+
974
+ ### Accordion
975
+
976
+ The `Accordion` component creates a vertically stacked set of expandable/collapsible panels for organizing content.
977
+
978
+ #### Syntax
979
+
980
+ ```python
981
+ from dars.components.advanced.accordion import Accordion
982
+
983
+ accordion = Accordion(
984
+ items=[
985
+ {"title": "Section 1", "content": "Content for section 1"},
986
+ {"title": "Section 2", "content": "Content for section 2"}
987
+ ],
988
+ allow_multiple=False
989
+ )
990
+ ```
991
+
992
+ #### Properties
993
+
994
+ | Property | Type | Description |
995
+ |------------------|---------|-----------------------------------------------------|
996
+ | `items` | list | List of dicts with `title` and `content` |
997
+ | `allow_multiple` | bool | Allow multiple sections open at once |
998
+
999
+ #### Example
1000
+
1001
+ ```python
1002
+ accordion = Accordion(
1003
+ items=[
1004
+ {"title": "FAQ 1", "content": "Answer 1"},
1005
+ {"title": "FAQ 2", "content": "Answer 2"}
1006
+ ]
1007
+ )
1008
+ ```
1009
+
1010
+ ---
1011
+
1012
+ ### Tabs
1013
+
1014
+ The `Tabs` component allows navigation between different views or content panels.
1015
+
1016
+ > **New in 1.0.5:** The exporter now recursively detects Tabs at any nesting level (including inside containers, panels, or multipage apps) for `minimum_logic` and JS injection. You can safely nest Tabs in any structure and the export will work as expected.
1017
+
1018
+
1019
+ #### Syntax
1020
+
1021
+ ```python
1022
+ from dars.components.advanced.tabs import Tabs
1023
+
1024
+ tabs = Tabs(
1025
+ tabs=[
1026
+ {"label": "Tab 1", "content": "Content 1"},
1027
+ {"label": "Tab 2", "content": "Content 2"}
1028
+ ],
1029
+ default_index=0
1030
+ )
1031
+ ```
1032
+
1033
+ #### Properties
1034
+
1035
+ | Property | Type | Description |
1036
+ |-----------------|------|------------------------------------------|
1037
+ | `tabs` | list | List of dicts with `label` and `content` |
1038
+ | `default_index` | int | Index of the initially selected tab |
1039
+
1040
+ #### Example
1041
+
1042
+ ```python
1043
+ tabs = Tabs(
1044
+ tabs=[
1045
+ {"label": "Overview", "content": "Main content"},
1046
+ {"label": "Details", "content": "Detailed info"}
1047
+ ],
1048
+ default_index=0
1049
+ )
1050
+ ```
1051
+
1052
+ ---
1053
+
1054
+ ### Table
1055
+
1056
+ The `Table` component displays tabular data with rows and columns.
1057
+
1058
+ #### Syntax
1059
+
1060
+ ```python
1061
+ from dars.components.advanced.table import Table
1062
+
1063
+ table = Table(
1064
+ columns=["Name", "Age", "Country"],
1065
+ data=[
1066
+ ["Alice", 30, "USA"],
1067
+ ["Bob", 25, "UK"]
1068
+ ]
1069
+ )
1070
+ ```
1071
+
1072
+ #### Properties
1073
+
1074
+ | Property | Type | Description |
1075
+ |------------|--------|-----------------------------------|
1076
+ | `columns` | list | List of column headers |
1077
+ | `data` | list | List of rows (each a list/tuple) |
1078
+
1079
+ #### Example
1080
+
1081
+ ```python
1082
+ table = Table(
1083
+ columns=["Product", "Price"],
1084
+ data=[
1085
+ ["Book", "$10"],
1086
+ ["Pen", "$2"]
1087
+ ]
1088
+ )
1089
+ ```
1090
+
1091
+ ---
1092
+
1093
+ ## Layout Components
1094
+
1095
+ ### GridLayout
1096
+
1097
+ The `GridLayout` component provides a responsive grid-based layout with customizable rows, columns, gaps, and anchor points for precise positioning of children.
1098
+
1099
+ #### Syntax
1100
+
1101
+ ```python
1102
+ from dars.components.layout.grid import GridLayout
1103
+ from dars.components.basic.text import Text
1104
+
1105
+ grid = GridLayout(
1106
+ rows=2,
1107
+ cols=2,
1108
+ gap="24px",
1109
+ children=[
1110
+ Text("Top Left"),
1111
+ Text("Top Right"),
1112
+ Text("Bottom Left"),
1113
+ Text("Bottom Right")
1114
+ ]
1115
+ )
1116
+ ```
1117
+
1118
+ #### Properties
1119
+
1120
+ | Property | Type | Description |
1121
+ |------------|--------|---------------------------------------------|
1122
+ | `rows` | int | Number of grid rows |
1123
+ | `cols` | int | Number of grid columns |
1124
+ | `gap` | str | Gap between grid cells (e.g., "16px") |
1125
+ | `children` | list | List of child components |
1126
+ | `anchors` | dict | Optional anchor points for child placement |
1127
+
1128
+ #### Example
1129
+
1130
+ ```python
1131
+ grid = GridLayout(
1132
+ rows=3,
1133
+ cols=2,
1134
+ gap="16px",
1135
+ children=[Text(f"Cell {i}") for i in range(6)]
1136
+ )
1137
+ ```
1138
+
1139
+ ---
1140
+
1141
+ ### FlexLayout
1142
+
1143
+ The `FlexLayout` component provides a responsive flexbox layout, supporting direction, wrap, alignment, and gap between children. Useful for row/column layouts.
1144
+
1145
+ #### Syntax
1146
+
1147
+ ```python
1148
+ from dars.components.layout.flex import FlexLayout
1149
+ from dars.components.basic.button import Button
1150
+
1151
+ flex = FlexLayout(
1152
+ direction="row",
1153
+ justify="space-between",
1154
+ align="center",
1155
+ gap="12px",
1156
+ children=[Button("A"), Button("B"), Button("C")]
1157
+ )
1158
+ ```
1159
+
1160
+ #### Properties
1161
+
1162
+ | Property | Type | Description |
1163
+ |-------------|--------|-----------------------------------------------------|
1164
+ | `direction` | str | Flex direction: "row" or "column" |
1165
+ | `wrap` | str | Flex wrap: "wrap" or "nowrap" |
1166
+ | `justify` | str | Justify content: e.g., "flex-start", "center" |
1167
+ | `align` | str | Align items: e.g., "stretch", "center" |
1168
+ | `gap` | str | Gap between children (e.g., "16px") |
1169
+ | `children` | list | List of child components |
1170
+ | `anchors` | dict | Optional anchor points for child placement |
1171
+
1172
+ #### Example
1173
+
1174
+ ```python
1175
+ flex = FlexLayout(
1176
+ direction="column",
1177
+ gap="24px",
1178
+ children=[Button("Save"), Button("Cancel")]
1179
+ )
1180
+ ```
1181
+
1182
+ ---
1183
+
1184
+ ### LayoutBase
1185
+
1186
+ The `LayoutBase` component is the base class for all layout components. It allows adding children and anchor/positioning info. You typically use `FlexLayout` or `GridLayout` directly.
1187
+
1188
+ #### Syntax
1189
+
1190
+ ```python
1191
+ from dars.components.layout.grid import LayoutBase
1192
+ from dars.components.basic.text import Text
1193
+
1194
+ layout = LayoutBase(
1195
+ children=[Text("Item 1"), Text("Item 2")],
1196
+ anchors={}
1197
+ )
1198
+ ```
1199
+
1200
+ #### Properties
1201
+
1202
+ | Property | Type | Description |
1203
+ |-------------|--------|--------------------------------|
1204
+ | `children` | list | List of child components |
1205
+ | `anchors` | dict | Anchor/positioning information |
1206
+
1207
+ ---
1208
+
1209
+ ### AnchorPoint
1210
+
1211
+ The `AnchorPoint` class represents an anchor or alignment point for a child in a layout (e.g., top, left, right, bottom, center, percent, or px).
1212
+
1213
+ #### Syntax
1214
+
1215
+ ```python
1216
+ from dars.components.layout.anchor import AnchorPoint
1217
+
1218
+ anchor = AnchorPoint(x="left", y="top", name="top-left")
1219
+ ```
1220
+
1221
+ #### Properties
1222
+
1223
+ | Property | Type | Description |
1224
+ |----------|------|--------------------------------------------------|
1225
+ | `x` | str | Horizontal alignment (e.g., "left", "center") |
1226
+ | `y` | str | Vertical alignment (e.g., "top", "center") |
1227
+ | `name` | str | Optional semantic name for the anchor |
1228
+
1229
+ #### Example
1230
+
1231
+ ```python
1232
+ anchor = AnchorPoint(x="50%", y="50%", name="center")
1233
+ ```
1234
+
1235
+ ---
1236
+
1237
+ ### Card
1238
+
1239
+ The `Card` component is a styled container to group related content, such as a title and other components.
1240
+
1241
+ #### Syntax
1242
+
1243
+ ```python
1244
+ from dars.components.basic.card import Card
1245
+ from dars.components.basic.text import Text
1246
+ from dars.components.basic.button import Button
1247
+
1248
+ my_card = Card(
1249
+ title="Título de la Tarjeta",
1250
+ children=[
1251
+ Text("Este es el contenido de la tarjeta."),
1252
+ Button("Ver más")
1253
+ ],
1254
+ class_name="product-card",
1255
+ style={
1256
+ "background-color": "#ffffff",
1257
+ "border": "1px solid #e0e0e0",
1258
+ "border-radius": "10px",
1259
+ "padding": "20px",
1260
+ "box-shadow": "0 4px 8px rgba(0,0,0,0.05)"
1261
+ }
1262
+ )
1263
+ ```
1264
+
1265
+ #### Properties
1266
+
1267
+ | Property | Type | Description |
1268
+ |-----------|------|-------------|
1269
+ | `title` | str | Card title |
1270
+ | `children` | list | List of child components |
1271
+
1272
+ #### Example
1273
+
1274
+ ```python
1275
+ my_card = Card(
1276
+ title="Título de la Tarjeta",
1277
+ children=[
1278
+ Text("Este es el contenido de la tarjeta."),
1279
+ Button("Ver más")
1280
+ ],
1281
+ class_name="product-card",
1282
+ style={
1283
+ "background-color": "#ffffff",
1284
+ "border": "1px solid #e0e0e0",
1285
+ "border-radius": "10px",
1286
+ "padding": "20px",
1287
+ "box-shadow": "0 4px 8px rgba(0,0,0,0.05)"
1288
+ }
1289
+ )
1290
+ ```
1291
+
1292
+ ---
1293
+
1294
+ ### Modal
1295
+
1296
+ The `Modal` component creates an overlay window that appears on top of the main page content.
1297
+
1298
+ > **New in 1.0.5:** Modal is now exported as hidden by default (`hidden` attribute and `dars-modal-hidden` class) if `is_open=False`, preventing any visual flicker on page load, even if CSS/JS loads slowly.
1299
+
1300
+ #### Syntax
1301
+
1302
+ ```python
1303
+ from dars.components.advanced.modal import Modal
1304
+ from dars.components.basic.text import Text
1305
+ from dars.components.basic.button import Button
1306
+
1307
+ my_modal = Modal(
1308
+ title="Welcome to the Modal",
1309
+ is_open=False, # Now hidden from the very first render
1310
+ children=[
1311
+ Text("This is your modal content."),
1312
+ Button("Close")
1313
+ ],
1314
+ class_name="welcome-modal",
1315
+ style={
1316
+ "background-color": "rgba(0, 0, 0, 0.7)" # Overlay style
1317
+ }
1318
+ )
1319
+ ```
1320
+
1321
+ #### Properties
1322
+
1323
+ | Property | Type | Description |
1324
+ |------------|------|------------------------------------------------------------|
1325
+ | `title` | str | Modal title |
1326
+ | `is_open` | bool | Controls modal visibility (`True` to show, `False` to hide). If `False`, modal is hidden from exported HTML. |
1327
+ | `children` | list | List of child components |
1328
+
1329
+ #### Updated Example
1330
+
1331
+ ```python
1332
+ my_modal = Modal(
1333
+ title="Welcome to the Modal",
1334
+ is_open=False, # Hidden from the very first render
1335
+ children=[
1336
+ Text("This is your modal content."),
1337
+ Button("Close")
1338
+ ],
1339
+ class_name="welcome-modal",
1340
+ style={
1341
+ "background-color": "rgba(0, 0, 0, 0.7)"
1342
+ }
1343
+ )
1344
+ ```
1345
+
1346
+ > **Note:** The exporter now recursively detects advanced components (Tabs, Accordion, Modal, Card) at any nesting level, including inside multipage apps, and applies `minimum_logic` robustly.
1347
+
1348
+ ---
1349
+
1350
+ ### Navbar
1351
+
1352
+ The `Navbar` component creates a navigation bar, commonly used at the top of pages.
1353
+
1354
+ #### Syntax
1355
+
1356
+ ```python
1357
+ from dars.components.advanced.navbar import Navbar
1358
+ from dars.components.basic.link import Link
1359
+
1360
+ my_navbar = Navbar(
1361
+ brand="Mi App",
1362
+ children=[
1363
+ Link("Inicio", "/"),
1364
+ Link("Acerca de", "/about"),
1365
+ Link("Contacto", "/contact")
1366
+ ],
1367
+ class_name="main-nav",
1368
+ style={
1369
+ "background-color": "#333",
1370
+ "color": "white",
1371
+ "padding": "15px 20px"
1372
+ }
1373
+ )
1374
+ ```
1375
+
1376
+ #### Properties
1377
+
1378
+ | Property | Type | Description |
1379
+ |-----------|------|-------------|
1380
+ | `brand` | str | Texto o componente para la marca/logo de la navegación |
1381
+ | `children` | list | List of child components (navigation items, usually `Link`s) |
1382
+
1383
+ ## Additional Components
1384
+
1385
+ ### Checkbox
1386
+
1387
+ The `Checkbox` component allows users to select options.
1388
+
1389
+ #### Syntax
1390
+
1391
+ ```python
1392
+ from dars.components.basic.checkbox import Checkbox
1393
+
1394
+ mi_checkbox = Checkbox(
1395
+ label="Acepto términos",
1396
+ checked=True,
1397
+ style={
1398
+ "margin": "10px"
1399
+ }
1400
+ )
1401
+ ```
1402
+
1403
+ #### Properties
1404
+
1405
+ | Property | Type | Description | Values |
1406
+ |-----------|------|-------------|---------|
1407
+ | `label` | str | Texto de la etiqueta | `"Acepto términos"` |
1408
+ | `checked` | bool | Estado de selección | `True`, `False` |
1409
+
1410
+ ### RadioButton
1411
+
1412
+ The `RadioButton` component allows users to select one option from a group of options.
1413
+
1414
+ #### Syntax
1415
+
1416
+ ```python
1417
+ from dars.components.basic.radio_button import RadioButton
1418
+
1419
+ mi_radio_button = RadioButton(
1420
+ label="Opción A",
1421
+ name="grupo1",
1422
+ checked=False,
1423
+ style={
1424
+ "margin": "10px"
1425
+ }
1426
+ )
1427
+ ```
1428
+
1429
+ #### Properties
1430
+
1431
+ | Property | Type | Description | Values |
1432
+ |-----------|------|-------------|---------|
1433
+ | `label` | str | Texto de la etiqueta | `"Opción A"` |
1434
+ | `name` | str | Nombre del grupo de radio buttons | `"grupo1"` |
1435
+ | `checked` | bool | Estado de selección | `True`, `False` |
1436
+
1437
+ ### Select
1438
+
1439
+ The `Select` component allows users to select one option from a group of options.
1440
+
1441
+ #### Syntax
1442
+
1443
+ ```python
1444
+ from dars.components.basic.select import Select
1445
+
1446
+ mi_select = Select(
1447
+ options=["Uno", "Dos", "Tres"],
1448
+ value="Dos",
1449
+ style={
1450
+ "width": "200px",
1451
+ "padding": "10px",
1452
+ "border": "1px solid #ccc"
1453
+ }
1454
+ )
1455
+ ```
1456
+
1457
+ #### Properties
1458
+
1459
+ | Property | Type | Description | Values |
1460
+ |-----------|------|-------------|---------|
1461
+ | `options` | list | List of options | `["Uno", "Dos", "Tres"]` |
1462
+ | `value` | str | Selected value | `"Dos"` |
1463
+
1464
+ ### Slider
1465
+
1466
+ The `Slider` component allows users to select a value within a range.
1467
+
1468
+ #### Syntax
1469
+
1470
+ ```python
1471
+ from dars.components.basic.slider import Slider
1472
+
1473
+ mi_slider = Slider(
1474
+ min_value=0,
1475
+ max_value=100,
1476
+ value=50,
1477
+ show_value=True,
1478
+ style={
1479
+ "width": "200px",
1480
+ "padding": "10px"
1481
+ }
1482
+ )
1483
+ ```
1484
+
1485
+ #### Properties
1486
+
1487
+ | Property | Type | Description | Values |
1488
+ |-----------|------|-------------|---------|
1489
+ | `min_value` | int | Minimum value | `0` |
1490
+ | `max_value` | int | Maximum value | `100` |
1491
+ | `value` | int | Valor selectado | `50` |
1492
+ | `show_value` | bool | Mostrar el valor selectado | `True`, `False` |
1493
+
1494
+
1495
+ ### DatePicker
1496
+
1497
+ The `DatePicker` component allows users to select a date.
1498
+
1499
+ #### Syntax
1500
+
1501
+ ```python
1502
+ from dars.components.basic.date_picker import DatePicker
1503
+
1504
+ mi_date_picker = DatePicker(
1505
+ value="2025-08-06",
1506
+ style={
1507
+ "width": "200px",
1508
+ "padding": "10px",
1509
+ "border": "1px solid #ccc"
1510
+ }
1511
+ )
1512
+ ```
1513
+
1514
+ #### Properties
1515
+
1516
+ | Property | Type | Description | Values |
1517
+ |-----------|------|-------------|---------|
1518
+ | `value` | str | Selected date | `"2025-08-06"` |
1519
+
1520
+ ## Styling System
1521
+
1522
+ ### Supported Style Properties
1523
+
1524
+ Dars supports most standard CSS properties:
1525
+
1526
+ #### Dimensions
1527
+ - `width`, `height`
1528
+ - `min-width`, `min-height`
1529
+ - `max-width`, `max-height`
1530
+
1531
+ #### Spacing
1532
+ - `margin`, `margin-top`, `margin-right`, `margin-bottom`, `margin-left`
1533
+ - `padding`, `padding-top`, `padding-right`, `padding-bottom`, `padding-left`
1534
+
1535
+ #### Colors
1536
+ - `background-color`
1537
+ - `color`
1538
+ - `border-color`
1539
+
1540
+ #### Typography
1541
+ - `font-size`, `font-family`, `font-weight`, `font-style`
1542
+ - `text-align`, `text-decoration`, `line-height`
1543
+
1544
+ #### Borders
1545
+ - `border`, `border-width`, `border-style`, `border-radius`
1546
+
1547
+ #### Layout
1548
+ - `display`, `position`
1549
+ - `top`, `right`, `bottom`, `left`, `z-index`
1550
+
1551
+ #### Flexbox
1552
+ - `flex-direction`, `flex-wrap`
1553
+ - `justify-content`, `align-items`, `align-content`
1554
+ - `flex`, `flex-grow`, `flex-shrink`, `flex-basis`
1555
+
1556
+ #### Grid
1557
+ - `grid-template-columns`, `grid-template-rows`
1558
+ - `grid-gap`, `grid-column`, `grid-row`
1559
+
1560
+ #### Effects
1561
+ - `opacity`, `box-shadow`, `transform`, `transition`
1562
+
1563
+ ### Advanced Style Examples
1564
+
1565
+ ```python
1566
+ # Gradiente de fondo
1567
+ gradiente = Container(
1568
+ style={
1569
+ "background": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
1570
+ "min-height": "100vh",
1571
+ "display": "flex",
1572
+ "align-items": "center",
1573
+ "justify-content": "center"
1574
+ }
1575
+ )
1576
+
1577
+ # Animación de hover (para web)
1578
+ boton_animado = Button(
1579
+ text="Hover me",
1580
+ style={
1581
+ "background-color": "#3498db",
1582
+ "color": "white",
1583
+ "padding": "15px 30px",
1584
+ "border": "none",
1585
+ "border-radius": "8px",
1586
+ "transition": "all 0.3s ease",
1587
+ "transform": "translateY(0)",
1588
+ "box-shadow": "0 4px 15px rgba(52, 152, 219, 0.3)"
1589
+ }
1590
+ )
1591
+
1592
+ # Layout de grid
1593
+ grid_container = Container(
1594
+ style={
1595
+ "display": "grid",
1596
+ "grid-template-columns": "repeat(auto-fit, minmax(250px, 1fr))",
1597
+ "grid-gap": "20px",
1598
+ "padding": "20px"
1599
+ }
1600
+ )
1601
+
1602
+ # Responsive design
1603
+ responsive_container = Container(
1604
+ style={
1605
+ "width": "100%",
1606
+ "max-width": "1200px",
1607
+ "margin": "0 auto",
1608
+ "padding": "0 20px"
1609
+ }
1610
+ )
1611
+ ```
1612
+
1613
+
1614
+
1615
+ ## Best Practices
1616
+
1617
+ ### Component Organization
1618
+
1619
+ ```python
1620
+ def create_header():
1621
+ return Container(
1622
+ children=[
1623
+ Text("My Application", style={"font-size": "24px", "font-weight": "bold"}),
1624
+ Text("Descriptive subtitle", style={"color": "#666"})
1625
+ ],
1626
+ style={
1627
+ "padding": "20px",
1628
+ "background-color": "#f8f9fa",
1629
+ "border-bottom": "1px solid #dee2e6"
1630
+ }
1631
+ )
1632
+
1633
+ def create_form():
1634
+ return Container(
1635
+ children=[
1636
+ Text("Contact Form", style={"font-size": "20px", "margin-bottom": "20px"}),
1637
+ Input(placeholder="Name", style={"margin-bottom": "10px"}),
1638
+ Input(placeholder="Email", input_type="email", style={"margin-bottom": "10px"}),
1639
+ Button("Send", style={"background-color": "#007bff", "color": "white"})
1640
+ ],
1641
+ style={
1642
+ "max-width": "400px",
1643
+ "margin": "20px auto",
1644
+ "padding": "20px"
1645
+ }
1646
+ )
1647
+ ```
1648
+
1649
+ ### Style Reuse
1650
+
1651
+ ```python
1652
+ # Define common styles
1653
+ BASE_BUTTON_STYLES = {
1654
+ "padding": "10px 20px",
1655
+ "border": "none",
1656
+ "border-radius": "4px",
1657
+ "font-size": "14px",
1658
+ "cursor": "pointer"
1659
+ }
1660
+
1661
+ PRIMARY_BUTTON_STYLES = {
1662
+ **BASE_BUTTON_STYLES,
1663
+ "background-color": "#007bff",
1664
+ "color": "white"
1665
+ }
1666
+
1667
+ SECONDARY_BUTTON_STYLES = {
1668
+ **BASE_BUTTON_STYLES,
1669
+ "background-color": "#6c757d",
1670
+ "color": "white"
1671
+ }
1672
+
1673
+ # Use in components
1674
+ cancel_button = Button("Cancelar", style=SECONDARY_BUTTON_STYLES)
1675
+ save_button = Button("Guardar", style=PRIMARY_BUTTON_STYLES)
1676
+ ```
1677
+
1678
+ Components provide a solid foundation for creating modern and responsive user interfaces that can be exported to multiple platforms while maintaining consistency and functionality.
1679
+