reflex-docgen 0.9.0a1__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.
- reflex_docgen/__init__.py +33 -0
- reflex_docgen/_class.py +345 -0
- reflex_docgen/_component.py +151 -0
- reflex_docgen/markdown/__init__.py +57 -0
- reflex_docgen/markdown/_parser.py +403 -0
- reflex_docgen/markdown/_types.py +326 -0
- reflex_docgen/markdown/transformer/__init__.py +13 -0
- reflex_docgen/markdown/transformer/_base.py +414 -0
- reflex_docgen/markdown/transformer/_markdown.py +189 -0
- reflex_docgen/py.typed +0 -0
- reflex_docgen-0.9.0a1.dist-info/METADATA +19 -0
- reflex_docgen-0.9.0a1.dist-info/RECORD +14 -0
- reflex_docgen-0.9.0a1.dist-info/WHEEL +4 -0
- reflex_docgen-0.9.0a1.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Module for generating documentation for Reflex components and classes."""
|
|
2
|
+
|
|
3
|
+
from reflex_docgen import markdown as markdown
|
|
4
|
+
from reflex_docgen._class import ClassDocumentation as ClassDocumentation
|
|
5
|
+
from reflex_docgen._class import FieldDocumentation as FieldDocumentation
|
|
6
|
+
from reflex_docgen._class import MethodDocumentation as MethodDocumentation
|
|
7
|
+
from reflex_docgen._class import (
|
|
8
|
+
generate_class_documentation as generate_class_documentation,
|
|
9
|
+
)
|
|
10
|
+
from reflex_docgen._component import ComponentDocumentation as ComponentDocumentation
|
|
11
|
+
from reflex_docgen._component import (
|
|
12
|
+
EventHandlerDocumentation as EventHandlerDocumentation,
|
|
13
|
+
)
|
|
14
|
+
from reflex_docgen._component import PropDocumentation as PropDocumentation
|
|
15
|
+
from reflex_docgen._component import generate_documentation as generate_documentation
|
|
16
|
+
from reflex_docgen._component import (
|
|
17
|
+
get_component_event_handlers as get_component_event_handlers,
|
|
18
|
+
)
|
|
19
|
+
from reflex_docgen._component import get_component_props as get_component_props
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"ClassDocumentation",
|
|
23
|
+
"ComponentDocumentation",
|
|
24
|
+
"EventHandlerDocumentation",
|
|
25
|
+
"FieldDocumentation",
|
|
26
|
+
"MethodDocumentation",
|
|
27
|
+
"PropDocumentation",
|
|
28
|
+
"generate_class_documentation",
|
|
29
|
+
"generate_documentation",
|
|
30
|
+
"get_component_event_handlers",
|
|
31
|
+
"get_component_props",
|
|
32
|
+
"markdown",
|
|
33
|
+
]
|
reflex_docgen/_class.py
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
"""Generate documentation for arbitrary Python classes."""
|
|
2
|
+
|
|
3
|
+
import dataclasses
|
|
4
|
+
import inspect
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Any, get_args, get_type_hints
|
|
7
|
+
|
|
8
|
+
from reflex_base.vars.base import BaseStateMeta
|
|
9
|
+
from typing_inspection.introspection import AnnotationSource, inspect_annotation
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
13
|
+
class FieldDocumentation:
|
|
14
|
+
"""Hold information about a class field.
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
name: The name of the field.
|
|
18
|
+
type: The resolved type of the field.
|
|
19
|
+
type_display: Human-readable type string (no Var wrapper). Uses __name__ for simple types, str() for generics.
|
|
20
|
+
description: The description extracted from the class docstring or field.doc.
|
|
21
|
+
default: The repr() of the default value, or None if no default.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
name: str
|
|
25
|
+
|
|
26
|
+
type: Any
|
|
27
|
+
|
|
28
|
+
type_display: str
|
|
29
|
+
|
|
30
|
+
description: str | None
|
|
31
|
+
|
|
32
|
+
default: str | None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
36
|
+
class MethodDocumentation:
|
|
37
|
+
"""Hold information about a class method.
|
|
38
|
+
|
|
39
|
+
Attributes:
|
|
40
|
+
name: The name of the method.
|
|
41
|
+
signature: The string representation of the method signature.
|
|
42
|
+
description: The docstring, truncated before 'Args:' or 'Returns:' sections.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
name: str
|
|
46
|
+
|
|
47
|
+
signature: str
|
|
48
|
+
|
|
49
|
+
description: str | None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
53
|
+
class ClassDocumentation:
|
|
54
|
+
"""Documentation for an arbitrary Python class.
|
|
55
|
+
|
|
56
|
+
Attributes:
|
|
57
|
+
name: The fully qualified name (module.qualname) of the class.
|
|
58
|
+
description: The cleaned docstring of the class.
|
|
59
|
+
fields: Instance fields (from dataclass fields or rx.State __fields__).
|
|
60
|
+
class_fields: Class variables (from __class_vars__ on rx.Base subclasses).
|
|
61
|
+
methods: Public methods that have docstrings.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
name: str
|
|
65
|
+
|
|
66
|
+
description: str | None
|
|
67
|
+
|
|
68
|
+
fields: tuple[FieldDocumentation, ...] = ()
|
|
69
|
+
|
|
70
|
+
class_fields: tuple[FieldDocumentation, ...] = ()
|
|
71
|
+
|
|
72
|
+
methods: tuple[MethodDocumentation, ...] = ()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _parse_docstring_attributes(cls: type) -> dict[str, str]:
|
|
76
|
+
"""Parse an Attributes section from a class docstring using griffe.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
cls: The class whose docstring to parse.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
A mapping from attribute name to description string.
|
|
83
|
+
"""
|
|
84
|
+
from griffe import Docstring, Parser # provided by griffelib
|
|
85
|
+
|
|
86
|
+
doc = cls.__doc__
|
|
87
|
+
if not doc:
|
|
88
|
+
return {}
|
|
89
|
+
|
|
90
|
+
parsed = Docstring(inspect.cleandoc(doc)).parse(Parser.auto)
|
|
91
|
+
return {
|
|
92
|
+
attr.name: attr.description
|
|
93
|
+
for section in parsed
|
|
94
|
+
if section.kind.value == "attributes"
|
|
95
|
+
for attr in section.value
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _type_display(type_: Any) -> str:
|
|
100
|
+
"""Return a human-readable type string.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
type_: The type to display.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
A human-readable type string.
|
|
107
|
+
"""
|
|
108
|
+
if get_args(type_):
|
|
109
|
+
return str(type_)
|
|
110
|
+
return getattr(type_, "__name__", str(type_))
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _extract_field_doc(hint: Any, field_doc: str | None) -> tuple[Any, str | None]:
|
|
114
|
+
"""Extract the unwrapped type and description from a type hint.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
hint: The type hint.
|
|
118
|
+
field_doc: The field.doc attribute value.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
A tuple of (unwrapped_type, description).
|
|
122
|
+
"""
|
|
123
|
+
inspected = inspect_annotation(hint, annotation_source=AnnotationSource.ANY)
|
|
124
|
+
return inspected.type, field_doc
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _build_field_documentation(
|
|
128
|
+
name: str,
|
|
129
|
+
hint: Any,
|
|
130
|
+
field_doc: str | None,
|
|
131
|
+
default_value: str | None,
|
|
132
|
+
docstring_desc: str | None = None,
|
|
133
|
+
) -> FieldDocumentation | None:
|
|
134
|
+
"""Build a FieldDocumentation from field info, or None if private.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
name: The field name.
|
|
138
|
+
hint: The type hint.
|
|
139
|
+
field_doc: The field.doc attribute value.
|
|
140
|
+
default_value: The repr'd default value, or None.
|
|
141
|
+
docstring_desc: Description from the class docstring Attributes section (fallback).
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
A FieldDocumentation, or None if the field should be skipped.
|
|
145
|
+
"""
|
|
146
|
+
if name.startswith("_"):
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
unwrapped_type, description = _extract_field_doc(hint, field_doc)
|
|
150
|
+
|
|
151
|
+
# Fall back to docstring Attributes section if no description found.
|
|
152
|
+
if description is None and docstring_desc is not None:
|
|
153
|
+
description = docstring_desc
|
|
154
|
+
|
|
155
|
+
if description is not None and "PRIVATE" in description:
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
return FieldDocumentation(
|
|
159
|
+
name=name,
|
|
160
|
+
type=unwrapped_type,
|
|
161
|
+
type_display=_type_display(unwrapped_type),
|
|
162
|
+
description=description,
|
|
163
|
+
default=default_value,
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _get_dataclass_fields(cls: type) -> tuple[FieldDocumentation, ...]:
|
|
168
|
+
"""Extract fields from a dataclass.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
cls: The dataclass to extract fields from.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
A tuple of FieldDocumentation objects.
|
|
175
|
+
"""
|
|
176
|
+
hints = get_type_hints(cls, include_extras=True)
|
|
177
|
+
docstring_attrs = _parse_docstring_attributes(cls)
|
|
178
|
+
result = []
|
|
179
|
+
for f in dataclasses.fields(cls):
|
|
180
|
+
hint = hints.get(f.name, f.type)
|
|
181
|
+
field_doc = getattr(f, "doc", None)
|
|
182
|
+
|
|
183
|
+
if f.default is not dataclasses.MISSING:
|
|
184
|
+
default_str = repr(f.default)
|
|
185
|
+
elif f.default_factory is not dataclasses.MISSING:
|
|
186
|
+
default_str = repr(f.default_factory)
|
|
187
|
+
else:
|
|
188
|
+
default_str = None
|
|
189
|
+
|
|
190
|
+
doc = _build_field_documentation(
|
|
191
|
+
f.name, hint, field_doc, default_str, docstring_attrs.get(f.name)
|
|
192
|
+
)
|
|
193
|
+
if doc is not None:
|
|
194
|
+
result.append(doc)
|
|
195
|
+
|
|
196
|
+
return tuple(result)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _get_state_fields(cls: BaseStateMeta) -> tuple[FieldDocumentation, ...]:
|
|
200
|
+
"""Extract instance fields from an rx.State subclass via __fields__.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
cls: The class to extract fields from.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
A tuple of FieldDocumentation objects.
|
|
207
|
+
"""
|
|
208
|
+
hints = get_type_hints(cls, include_extras=True)
|
|
209
|
+
docstring_attrs = _parse_docstring_attributes(cls)
|
|
210
|
+
fields_dict = cls.__fields__
|
|
211
|
+
result = []
|
|
212
|
+
for name, field in fields_dict.items():
|
|
213
|
+
hint = hints.get(name, field.outer_type_)
|
|
214
|
+
|
|
215
|
+
if field.default is not dataclasses.MISSING:
|
|
216
|
+
default_str = repr(field.default)
|
|
217
|
+
elif field.default_factory is not None:
|
|
218
|
+
default_str = repr(field.default_factory)
|
|
219
|
+
else:
|
|
220
|
+
default_str = None
|
|
221
|
+
|
|
222
|
+
doc = _build_field_documentation(
|
|
223
|
+
name, hint, None, default_str, docstring_attrs.get(name)
|
|
224
|
+
)
|
|
225
|
+
if doc is not None:
|
|
226
|
+
result.append(doc)
|
|
227
|
+
|
|
228
|
+
return tuple(result)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def _get_class_vars(cls: type) -> tuple[FieldDocumentation, ...]:
|
|
232
|
+
"""Extract class variables from __class_vars__.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
cls: The class to extract class variables from.
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
A tuple of FieldDocumentation objects.
|
|
239
|
+
"""
|
|
240
|
+
class_vars = getattr(cls, "__class_vars__", None)
|
|
241
|
+
if not class_vars:
|
|
242
|
+
return ()
|
|
243
|
+
|
|
244
|
+
hints = get_type_hints(cls, include_extras=True)
|
|
245
|
+
docstring_attrs = _parse_docstring_attributes(cls)
|
|
246
|
+
result = []
|
|
247
|
+
for name in class_vars:
|
|
248
|
+
hint = hints.get(name, type(None))
|
|
249
|
+
doc = _build_field_documentation(
|
|
250
|
+
name, hint, None, None, docstring_attrs.get(name)
|
|
251
|
+
)
|
|
252
|
+
if doc is not None:
|
|
253
|
+
result.append(doc)
|
|
254
|
+
|
|
255
|
+
return tuple(result)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _get_methods(cls: type) -> tuple[MethodDocumentation, ...]:
|
|
259
|
+
"""Extract public documented methods from a class.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
cls: The class to extract methods from.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
A tuple of MethodDocumentation objects.
|
|
266
|
+
"""
|
|
267
|
+
result = []
|
|
268
|
+
for name, obj in cls.__dict__.items():
|
|
269
|
+
if name.startswith("_") or name == "Config":
|
|
270
|
+
continue
|
|
271
|
+
|
|
272
|
+
fn = obj
|
|
273
|
+
if isinstance(obj, (classmethod, staticmethod)):
|
|
274
|
+
fn = obj.__func__
|
|
275
|
+
|
|
276
|
+
if not callable(fn):
|
|
277
|
+
continue
|
|
278
|
+
|
|
279
|
+
docstring = getattr(fn, "__doc__", None)
|
|
280
|
+
if not docstring:
|
|
281
|
+
continue
|
|
282
|
+
|
|
283
|
+
# Truncate docstring before Args: or Returns:
|
|
284
|
+
for marker in ("Args:", "Returns:"):
|
|
285
|
+
idx = docstring.find(marker)
|
|
286
|
+
if idx != -1:
|
|
287
|
+
docstring = docstring[:idx]
|
|
288
|
+
break
|
|
289
|
+
docstring = docstring.strip() or None
|
|
290
|
+
|
|
291
|
+
try:
|
|
292
|
+
sig = str(inspect.signature(fn))
|
|
293
|
+
except (ValueError, TypeError):
|
|
294
|
+
sig = "(...)"
|
|
295
|
+
|
|
296
|
+
result.append(
|
|
297
|
+
MethodDocumentation(
|
|
298
|
+
name=name,
|
|
299
|
+
signature=sig,
|
|
300
|
+
description=docstring,
|
|
301
|
+
)
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
return tuple(result)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def generate_class_documentation(cls: type) -> ClassDocumentation:
|
|
308
|
+
"""Generate documentation for an arbitrary Python class.
|
|
309
|
+
|
|
310
|
+
Supports dataclasses, rx.State subclasses, and other classes (methods only).
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
cls: The class to generate documentation for.
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
The generated documentation for the class.
|
|
317
|
+
"""
|
|
318
|
+
try:
|
|
319
|
+
description = inspect.cleandoc(cls.__doc__) if cls.__doc__ else None
|
|
320
|
+
|
|
321
|
+
if dataclasses.is_dataclass(cls):
|
|
322
|
+
fields = _get_dataclass_fields(cls)
|
|
323
|
+
elif isinstance(cls, BaseStateMeta):
|
|
324
|
+
fields = _get_state_fields(cls)
|
|
325
|
+
else:
|
|
326
|
+
fields = ()
|
|
327
|
+
|
|
328
|
+
class_fields = _get_class_vars(cls)
|
|
329
|
+
methods = _get_methods(cls)
|
|
330
|
+
|
|
331
|
+
return ClassDocumentation(
|
|
332
|
+
name=f"{cls.__module__}.{cls.__qualname__}",
|
|
333
|
+
description=description,
|
|
334
|
+
fields=fields,
|
|
335
|
+
class_fields=class_fields,
|
|
336
|
+
methods=methods,
|
|
337
|
+
)
|
|
338
|
+
except Exception as e:
|
|
339
|
+
import sys
|
|
340
|
+
|
|
341
|
+
if sys.version_info >= (3, 11):
|
|
342
|
+
e.add_note(
|
|
343
|
+
f"Error generating documentation for class {cls.__module__}.{cls.__qualname__}"
|
|
344
|
+
)
|
|
345
|
+
raise
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""Generate documentation for Reflex components."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from reflex_base.components.component import DEFAULT_TRIGGERS_AND_DESC, Component
|
|
7
|
+
from reflex_base.event import EventHandler
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
11
|
+
class PropDocumentation:
|
|
12
|
+
"""Hold information about a prop.
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
name: The name of the prop.
|
|
16
|
+
type: The type of the prop.
|
|
17
|
+
description: The description of the prop.
|
|
18
|
+
default_value: The default value of the prop.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
name: str
|
|
22
|
+
|
|
23
|
+
type: Any
|
|
24
|
+
|
|
25
|
+
description: str | None
|
|
26
|
+
|
|
27
|
+
default_value: str | None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
31
|
+
class EventHandlerDocumentation:
|
|
32
|
+
"""Hold information about an event handler.
|
|
33
|
+
|
|
34
|
+
Attributes:
|
|
35
|
+
name: The name of the event handler.
|
|
36
|
+
description: The description of the event handler.
|
|
37
|
+
is_inherited: Whether the event handler is inherited from DEFAULT_TRIGGERS.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
name: str
|
|
41
|
+
|
|
42
|
+
description: str | None
|
|
43
|
+
|
|
44
|
+
is_inherited: bool
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
48
|
+
class ComponentDocumentation:
|
|
49
|
+
"""Documentation for a Reflex component.
|
|
50
|
+
|
|
51
|
+
Attributes:
|
|
52
|
+
name: The name of the component.
|
|
53
|
+
description: The docstring of the component class.
|
|
54
|
+
props: The list of props for the component.
|
|
55
|
+
event_handlers: The list of event handlers for the component.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
name: str
|
|
59
|
+
description: str | None = None
|
|
60
|
+
props: tuple[PropDocumentation, ...] = ()
|
|
61
|
+
event_handlers: tuple[EventHandlerDocumentation, ...] = ()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_component_props(
|
|
65
|
+
component_cls: type[Component],
|
|
66
|
+
) -> tuple[PropDocumentation, ...]:
|
|
67
|
+
"""Get the props for a Reflex component.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
component_cls: The component class to get the props for.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
The props for the component.
|
|
74
|
+
"""
|
|
75
|
+
props = component_cls.get_js_fields()
|
|
76
|
+
|
|
77
|
+
result = []
|
|
78
|
+
for prop_name, component_field in props.items():
|
|
79
|
+
if component_field.type_origin is EventHandler:
|
|
80
|
+
continue
|
|
81
|
+
doc = component_field.doc
|
|
82
|
+
default_value = None
|
|
83
|
+
|
|
84
|
+
# If the field has a doc attribute, use it as the description.
|
|
85
|
+
if doc is not None:
|
|
86
|
+
for default_indicator in ["Defaults to", "Default:"]:
|
|
87
|
+
if default_indicator in doc:
|
|
88
|
+
doc, default_value = doc.split(default_indicator, maxsplit=1)
|
|
89
|
+
default_value = default_value.strip().rstrip(".")
|
|
90
|
+
doc = doc.strip().rstrip(".")
|
|
91
|
+
break
|
|
92
|
+
|
|
93
|
+
result.append(
|
|
94
|
+
PropDocumentation(
|
|
95
|
+
name=prop_name,
|
|
96
|
+
type=component_field.type_,
|
|
97
|
+
description=doc.rstrip(".") + "." if doc else None,
|
|
98
|
+
default_value=default_value,
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return tuple(result)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def get_component_event_handlers(
|
|
106
|
+
component_cls: type[Component],
|
|
107
|
+
) -> tuple[EventHandlerDocumentation, ...]:
|
|
108
|
+
"""Get the event handlers for a Reflex component.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
component_cls: The component class to get the event handlers for.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
The event handlers for the component.
|
|
115
|
+
"""
|
|
116
|
+
event_triggers = component_cls.get_event_triggers()
|
|
117
|
+
fields = component_cls.get_fields()
|
|
118
|
+
|
|
119
|
+
return tuple(
|
|
120
|
+
EventHandlerDocumentation(
|
|
121
|
+
name=name,
|
|
122
|
+
description=(
|
|
123
|
+
field.doc.rstrip(".") + "."
|
|
124
|
+
if (field := fields.get(name)) is not None and field.doc
|
|
125
|
+
else (
|
|
126
|
+
DEFAULT_TRIGGERS_AND_DESC[name].description
|
|
127
|
+
if name in DEFAULT_TRIGGERS_AND_DESC
|
|
128
|
+
else None
|
|
129
|
+
)
|
|
130
|
+
),
|
|
131
|
+
is_inherited=name in DEFAULT_TRIGGERS_AND_DESC,
|
|
132
|
+
)
|
|
133
|
+
for name in event_triggers
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def generate_documentation(component_cls: type[Component]) -> ComponentDocumentation:
|
|
138
|
+
"""Generate documentation for a Reflex component.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
component_cls: The component class to generate documentation for.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
The generated documentation for the component.
|
|
145
|
+
"""
|
|
146
|
+
return ComponentDocumentation(
|
|
147
|
+
name=component_cls.__name__,
|
|
148
|
+
description=component_cls.__doc__,
|
|
149
|
+
props=get_component_props(component_cls),
|
|
150
|
+
event_handlers=get_component_event_handlers(component_cls),
|
|
151
|
+
)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Markdown parsing and types for Reflex documentation."""
|
|
2
|
+
|
|
3
|
+
from reflex_docgen.markdown import transformer as transformer
|
|
4
|
+
from reflex_docgen.markdown._parser import parse_document as parse_document
|
|
5
|
+
from reflex_docgen.markdown._types import Block as Block
|
|
6
|
+
from reflex_docgen.markdown._types import BoldSpan as BoldSpan
|
|
7
|
+
from reflex_docgen.markdown._types import CodeBlock as CodeBlock
|
|
8
|
+
from reflex_docgen.markdown._types import CodeSpan as CodeSpan
|
|
9
|
+
from reflex_docgen.markdown._types import ComponentPreview as ComponentPreview
|
|
10
|
+
from reflex_docgen.markdown._types import DirectiveBlock as DirectiveBlock
|
|
11
|
+
from reflex_docgen.markdown._types import Document as Document
|
|
12
|
+
from reflex_docgen.markdown._types import FrontMatter as FrontMatter
|
|
13
|
+
from reflex_docgen.markdown._types import HeadingBlock as HeadingBlock
|
|
14
|
+
from reflex_docgen.markdown._types import ImageSpan as ImageSpan
|
|
15
|
+
from reflex_docgen.markdown._types import ItalicSpan as ItalicSpan
|
|
16
|
+
from reflex_docgen.markdown._types import LineBreakSpan as LineBreakSpan
|
|
17
|
+
from reflex_docgen.markdown._types import LinkSpan as LinkSpan
|
|
18
|
+
from reflex_docgen.markdown._types import ListBlock as ListBlock
|
|
19
|
+
from reflex_docgen.markdown._types import ListItem as ListItem
|
|
20
|
+
from reflex_docgen.markdown._types import QuoteBlock as QuoteBlock
|
|
21
|
+
from reflex_docgen.markdown._types import Span as Span
|
|
22
|
+
from reflex_docgen.markdown._types import StrikethroughSpan as StrikethroughSpan
|
|
23
|
+
from reflex_docgen.markdown._types import TableBlock as TableBlock
|
|
24
|
+
from reflex_docgen.markdown._types import TableCell as TableCell
|
|
25
|
+
from reflex_docgen.markdown._types import TableRow as TableRow
|
|
26
|
+
from reflex_docgen.markdown._types import TextBlock as TextBlock
|
|
27
|
+
from reflex_docgen.markdown._types import TextSpan as TextSpan
|
|
28
|
+
from reflex_docgen.markdown._types import ThematicBreakBlock as ThematicBreakBlock
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"Block",
|
|
32
|
+
"BoldSpan",
|
|
33
|
+
"CodeBlock",
|
|
34
|
+
"CodeSpan",
|
|
35
|
+
"ComponentPreview",
|
|
36
|
+
"DirectiveBlock",
|
|
37
|
+
"Document",
|
|
38
|
+
"FrontMatter",
|
|
39
|
+
"HeadingBlock",
|
|
40
|
+
"ImageSpan",
|
|
41
|
+
"ItalicSpan",
|
|
42
|
+
"LineBreakSpan",
|
|
43
|
+
"LinkSpan",
|
|
44
|
+
"ListBlock",
|
|
45
|
+
"ListItem",
|
|
46
|
+
"QuoteBlock",
|
|
47
|
+
"Span",
|
|
48
|
+
"StrikethroughSpan",
|
|
49
|
+
"TableBlock",
|
|
50
|
+
"TableCell",
|
|
51
|
+
"TableRow",
|
|
52
|
+
"TextBlock",
|
|
53
|
+
"TextSpan",
|
|
54
|
+
"ThematicBreakBlock",
|
|
55
|
+
"parse_document",
|
|
56
|
+
"transformer",
|
|
57
|
+
]
|