eidosui 0.4.0__py3-none-any.whl → 0.6.0__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.
- eidos/__init__.py +270 -0
- eidos/components/__init__.py +11 -0
- eidos/components/headers.py +16 -14
- eidos/components/navigation.py +44 -35
- eidos/components/table.py +84 -0
- eidos/components/tabs.py +140 -0
- eidos/css/styles.css +155 -0
- eidos/plugins/__init__.py +1 -1
- eidos/plugins/markdown/__init__.py +3 -3
- eidos/plugins/markdown/components.py +10 -22
- eidos/plugins/markdown/extensions/__init__.py +1 -1
- eidos/plugins/markdown/extensions/alerts.py +68 -78
- eidos/plugins/markdown/renderer.py +19 -24
- eidos/styles.py +58 -11
- eidos/tags.py +144 -86
- eidos/utils.py +42 -38
- eidosui-0.6.0.dist-info/METADATA +113 -0
- eidosui-0.6.0.dist-info/RECORD +25 -0
- eidosui-0.4.0.dist-info/METADATA +0 -127
- eidosui-0.4.0.dist-info/RECORD +0 -22
- {eidosui-0.4.0.dist-info → eidosui-0.6.0.dist-info}/WHEEL +0 -0
- {eidosui-0.4.0.dist-info → eidosui-0.6.0.dist-info}/licenses/LICENSE +0 -0
eidos/css/styles.css
CHANGED
@@ -339,6 +339,54 @@
|
|
339
339
|
margin: var(--space-xl) 0;
|
340
340
|
}
|
341
341
|
|
342
|
+
/* Table styles */
|
343
|
+
.eidos-table {
|
344
|
+
width: 100%;
|
345
|
+
border-collapse: collapse;
|
346
|
+
font-size: var(--font-size-base);
|
347
|
+
background-color: var(--color-background);
|
348
|
+
}
|
349
|
+
|
350
|
+
.eidos-thead {
|
351
|
+
background-color: var(--color-surface);
|
352
|
+
border-bottom: var(--border-2) solid var(--color-border);
|
353
|
+
}
|
354
|
+
|
355
|
+
.eidos-tbody {
|
356
|
+
background-color: var(--color-background);
|
357
|
+
}
|
358
|
+
|
359
|
+
.eidos-tfoot {
|
360
|
+
background-color: var(--color-surface);
|
361
|
+
border-top: var(--border-2) solid var(--color-border);
|
362
|
+
}
|
363
|
+
|
364
|
+
.eidos-tr {
|
365
|
+
border-bottom: var(--border) solid var(--color-border);
|
366
|
+
transition: background-color var(--transition-fast);
|
367
|
+
}
|
368
|
+
|
369
|
+
.eidos-tbody .eidos-tr:hover {
|
370
|
+
background-color: var(--color-surface);
|
371
|
+
}
|
372
|
+
|
373
|
+
.eidos-tbody .eidos-tr:last-child {
|
374
|
+
border-bottom: none;
|
375
|
+
}
|
376
|
+
|
377
|
+
.eidos-th {
|
378
|
+
padding: var(--space-sm) var(--space-md);
|
379
|
+
text-align: left;
|
380
|
+
font-weight: var(--font-weight-semibold);
|
381
|
+
color: var(--color-text);
|
382
|
+
}
|
383
|
+
|
384
|
+
.eidos-td {
|
385
|
+
padding: var(--space-sm) var(--space-md);
|
386
|
+
text-align: left;
|
387
|
+
color: var(--color-text);
|
388
|
+
}
|
389
|
+
|
342
390
|
/* Navigation base styles */
|
343
391
|
.eidos-navbar {
|
344
392
|
width: 100%;
|
@@ -427,4 +475,111 @@
|
|
427
475
|
transform: translateY(0);
|
428
476
|
opacity: 1;
|
429
477
|
}
|
478
|
+
}
|
479
|
+
|
480
|
+
/* List Styles */
|
481
|
+
.eidos-ul {
|
482
|
+
list-style-type: disc;
|
483
|
+
margin: var(--space-md) 0;
|
484
|
+
padding-left: var(--space-xl);
|
485
|
+
color: var(--color-text);
|
486
|
+
}
|
487
|
+
|
488
|
+
.eidos-ol {
|
489
|
+
list-style-type: decimal;
|
490
|
+
margin: var(--space-md) 0;
|
491
|
+
padding-left: var(--space-xl);
|
492
|
+
color: var(--color-text);
|
493
|
+
}
|
494
|
+
|
495
|
+
.eidos-li {
|
496
|
+
margin-bottom: var(--space-xs);
|
497
|
+
line-height: var(--line-height-relaxed);
|
498
|
+
}
|
499
|
+
|
500
|
+
/* Nested lists */
|
501
|
+
.eidos-ul .eidos-ul,
|
502
|
+
.eidos-ul .eidos-ol,
|
503
|
+
.eidos-ol .eidos-ul,
|
504
|
+
.eidos-ol .eidos-ol {
|
505
|
+
margin: var(--space-xs) 0;
|
506
|
+
}
|
507
|
+
|
508
|
+
/* Remove bottom margin from last list item */
|
509
|
+
.eidos-li:last-child {
|
510
|
+
margin-bottom: 0;
|
511
|
+
}
|
512
|
+
|
513
|
+
/* List item hover effect for interactive lists */
|
514
|
+
.eidos-li-interactive {
|
515
|
+
padding: var(--space-xs) var(--space-sm);
|
516
|
+
margin-left: calc(var(--space-xl) * -1);
|
517
|
+
margin-right: calc(var(--space-sm) * -1);
|
518
|
+
padding-left: var(--space-xl);
|
519
|
+
border-radius: var(--radius-sm);
|
520
|
+
transition: background-color var(--transition-fast);
|
521
|
+
cursor: pointer;
|
522
|
+
}
|
523
|
+
|
524
|
+
.eidos-li-interactive:hover {
|
525
|
+
background-color: var(--color-surface);
|
526
|
+
}
|
527
|
+
|
528
|
+
/* Tabs Component */
|
529
|
+
.eidos-tabs {
|
530
|
+
position: relative;
|
531
|
+
}
|
532
|
+
|
533
|
+
.eidos-tabs-list {
|
534
|
+
display: flex;
|
535
|
+
border-bottom: 1px solid var(--color-border);
|
536
|
+
overflow-x: auto;
|
537
|
+
scrollbar-width: thin;
|
538
|
+
-webkit-overflow-scrolling: touch;
|
539
|
+
}
|
540
|
+
|
541
|
+
.eidos-tab {
|
542
|
+
padding: var(--space-sm) var(--space-lg);
|
543
|
+
border-bottom: 2px solid transparent;
|
544
|
+
color: var(--color-text-muted);
|
545
|
+
text-decoration: none;
|
546
|
+
white-space: nowrap;
|
547
|
+
transition: all var(--transition-fast);
|
548
|
+
position: relative;
|
549
|
+
top: 1px;
|
550
|
+
}
|
551
|
+
|
552
|
+
.eidos-tab:hover {
|
553
|
+
color: var(--color-text);
|
554
|
+
}
|
555
|
+
|
556
|
+
.eidos-tab:focus {
|
557
|
+
outline: 2px solid var(--color-focus);
|
558
|
+
outline-offset: -2px;
|
559
|
+
}
|
560
|
+
|
561
|
+
.eidos-tab-active {
|
562
|
+
color: var(--color-primary);
|
563
|
+
border-bottom-color: var(--color-primary);
|
564
|
+
}
|
565
|
+
|
566
|
+
.eidos-tab-panel {
|
567
|
+
padding: var(--space-lg) 0;
|
568
|
+
display: none;
|
569
|
+
}
|
570
|
+
|
571
|
+
.eidos-tab-panel-active {
|
572
|
+
display: block;
|
573
|
+
}
|
574
|
+
|
575
|
+
/* HTMX-enhanced transitions */
|
576
|
+
.eidos-tabs.htmx-swapping .eidos-tab-panel {
|
577
|
+
opacity: 0;
|
578
|
+
transform: translateY(-4px);
|
579
|
+
}
|
580
|
+
|
581
|
+
.eidos-tabs.htmx-settling .eidos-tab-panel {
|
582
|
+
opacity: 1;
|
583
|
+
transform: translateY(0);
|
584
|
+
transition: opacity var(--transition-normal), transform var(--transition-normal);
|
430
585
|
}
|
eidos/plugins/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
# EidosUI plugins package
|
1
|
+
# EidosUI plugins package
|
@@ -5,10 +5,10 @@ EidosUI themes through CSS variables.
|
|
5
5
|
|
6
6
|
Basic usage:
|
7
7
|
from eidos.plugins.markdown import Markdown, MarkdownCSS
|
8
|
-
|
8
|
+
|
9
9
|
# In your document head
|
10
10
|
MarkdownCSS()
|
11
|
-
|
11
|
+
|
12
12
|
# In your content
|
13
13
|
Markdown("# Hello World\\n\\nThis is **markdown**!")
|
14
14
|
"""
|
@@ -18,4 +18,4 @@ from .renderer import MarkdownRenderer
|
|
18
18
|
|
19
19
|
__all__ = ["Markdown", "MarkdownCSS", "MarkdownRenderer"]
|
20
20
|
|
21
|
-
__version__ = "0.1.0"
|
21
|
+
__version__ = "0.1.0"
|
@@ -1,53 +1,41 @@
|
|
1
1
|
"""Markdown components for EidosUI"""
|
2
2
|
|
3
3
|
import air
|
4
|
-
from typing import Optional
|
5
|
-
from .renderer import MarkdownRenderer
|
6
4
|
|
5
|
+
from .renderer import MarkdownRenderer
|
7
6
|
|
8
7
|
# Global renderer instance for reuse
|
9
8
|
_renderer = MarkdownRenderer()
|
10
9
|
|
11
10
|
|
12
|
-
def Markdown(content: str, class_:
|
11
|
+
def Markdown(content: str, class_: str | None = None, **kwargs) -> air.Div:
|
13
12
|
"""Main markdown component that renders markdown content with theme integration.
|
14
|
-
|
13
|
+
|
15
14
|
Args:
|
16
15
|
content: Markdown text to render
|
17
16
|
class_: Additional CSS classes to apply
|
18
17
|
**kwargs: Additional attributes to pass to the wrapper div
|
19
|
-
|
18
|
+
|
20
19
|
Returns:
|
21
20
|
air.Div containing the rendered markdown HTML
|
22
21
|
"""
|
23
22
|
# Render the markdown content
|
24
23
|
html_content = _renderer.render(content)
|
25
|
-
|
26
|
-
|
27
|
-
if class_:
|
28
|
-
return air.Div(
|
29
|
-
air.RawHTML(html_content),
|
30
|
-
class_=class_,
|
31
|
-
**kwargs
|
32
|
-
)
|
33
|
-
else:
|
34
|
-
return air.Div(
|
35
|
-
air.RawHTML(html_content),
|
36
|
-
**kwargs
|
37
|
-
)
|
24
|
+
|
25
|
+
return air.Div(air.RawHTML(html_content), class_=class_, **kwargs)
|
38
26
|
|
39
27
|
|
40
28
|
def MarkdownCSS() -> air.Link:
|
41
29
|
"""Returns a link tag to include the markdown CSS.
|
42
|
-
|
30
|
+
|
43
31
|
This should be included in the head of your document to ensure
|
44
32
|
markdown styling is available.
|
45
|
-
|
33
|
+
|
46
34
|
Returns:
|
47
35
|
air.Link element pointing to the markdown CSS file
|
48
36
|
"""
|
49
37
|
return air.Link(
|
50
38
|
rel="stylesheet",
|
51
39
|
href="/eidos/plugins/markdown/css/markdown.css",
|
52
|
-
type="text/css"
|
53
|
-
)
|
40
|
+
type="text/css",
|
41
|
+
)
|
@@ -1 +1 @@
|
|
1
|
-
# Markdown plugin extensions
|
1
|
+
# Markdown plugin extensions
|
@@ -1,134 +1,124 @@
|
|
1
1
|
"""GitHub-style alerts extension for markdown"""
|
2
2
|
|
3
3
|
import re
|
4
|
-
from markdown.extensions import Extension
|
5
|
-
from markdown.blockprocessors import BlockProcessor
|
6
4
|
import xml.etree.ElementTree as etree
|
7
5
|
from xml.etree.ElementTree import SubElement
|
8
6
|
|
7
|
+
from markdown.blockprocessors import BlockProcessor
|
8
|
+
from markdown.extensions import Extension
|
9
|
+
|
9
10
|
|
10
11
|
class AlertBlockProcessor(BlockProcessor):
|
11
12
|
"""Process GitHub-style alert blocks"""
|
12
|
-
|
13
|
+
|
13
14
|
# Pattern to match > [!TYPE] at the start of a blockquote
|
14
|
-
RE_ALERT = re.compile(r
|
15
|
-
|
15
|
+
RE_ALERT = re.compile(r"^> \[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]", re.MULTILINE)
|
16
|
+
|
16
17
|
# Alert type configurations
|
17
18
|
ALERT_TYPES = {
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
"NOTE": {"class": "eidos-alert eidos-alert-info", "icon": "ℹ️", "title": "Note"},
|
20
|
+
"TIP": {
|
21
|
+
"class": "eidos-alert eidos-alert-success",
|
22
|
+
"icon": "💡",
|
23
|
+
"title": "Tip",
|
22
24
|
},
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
"IMPORTANT": {
|
26
|
+
"class": "eidos-alert eidos-alert-warning",
|
27
|
+
"icon": "❗",
|
28
|
+
"title": "Important",
|
27
29
|
},
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
"WARNING": {
|
31
|
+
"class": "eidos-alert eidos-alert-warning",
|
32
|
+
"icon": "⚠️",
|
33
|
+
"title": "Warning",
|
32
34
|
},
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
"CAUTION": {
|
36
|
+
"class": "eidos-alert eidos-alert-error",
|
37
|
+
"icon": "🔴",
|
38
|
+
"title": "Caution",
|
37
39
|
},
|
38
|
-
'CAUTION': {
|
39
|
-
'class': 'eidos-alert eidos-alert-error',
|
40
|
-
'icon': '🔴',
|
41
|
-
'title': 'Caution'
|
42
|
-
}
|
43
40
|
}
|
44
|
-
|
41
|
+
|
45
42
|
def test(self, parent, block):
|
46
43
|
"""Test if the block is a GitHub-style alert"""
|
47
44
|
return bool(self.RE_ALERT.match(block))
|
48
|
-
|
45
|
+
|
49
46
|
def run(self, parent, blocks):
|
50
47
|
"""Process the alert block"""
|
51
48
|
block = blocks.pop(0)
|
52
|
-
|
49
|
+
|
53
50
|
# Extract alert type
|
54
51
|
match = self.RE_ALERT.match(block)
|
55
52
|
if not match:
|
56
53
|
return False
|
57
|
-
|
54
|
+
|
58
55
|
alert_type = match.group(1)
|
59
|
-
alert_config = self.ALERT_TYPES.get(alert_type, self.ALERT_TYPES[
|
60
|
-
|
56
|
+
alert_config = self.ALERT_TYPES.get(alert_type, self.ALERT_TYPES["NOTE"])
|
57
|
+
|
61
58
|
# Create the alert container
|
62
|
-
alert_div = SubElement(parent,
|
63
|
-
alert_div.set(
|
64
|
-
|
59
|
+
alert_div = SubElement(parent, "div")
|
60
|
+
alert_div.set("class", alert_config["class"])
|
61
|
+
|
65
62
|
# Add the header with icon and title
|
66
|
-
header = SubElement(alert_div,
|
67
|
-
header.set(
|
68
|
-
|
69
|
-
icon_span = SubElement(header,
|
70
|
-
icon_span.set(
|
71
|
-
icon_span.text = alert_config[
|
72
|
-
|
73
|
-
title_span = SubElement(header,
|
74
|
-
title_span.set(
|
75
|
-
title_span.text = alert_config[
|
76
|
-
|
77
|
-
|
78
|
-
content_div
|
79
|
-
|
80
|
-
|
63
|
+
header = SubElement(alert_div, "div")
|
64
|
+
header.set("class", "eidos-alert-header")
|
65
|
+
|
66
|
+
icon_span = SubElement(header, "span")
|
67
|
+
icon_span.set("class", "eidos-alert-icon")
|
68
|
+
icon_span.text = alert_config["icon"]
|
69
|
+
|
70
|
+
title_span = SubElement(header, "span")
|
71
|
+
title_span.set("class", "eidos-alert-title")
|
72
|
+
title_span.text = alert_config["title"]
|
73
|
+
|
74
|
+
content_div = SubElement(alert_div, "div")
|
75
|
+
content_div.set("class", "eidos-alert-content")
|
76
|
+
|
81
77
|
# Remove the alert marker and process the remaining content
|
82
|
-
content = self.RE_ALERT.sub(
|
83
|
-
|
84
|
-
|
85
|
-
lines = content.split('\n')
|
78
|
+
content = self.RE_ALERT.sub("", block)
|
79
|
+
|
80
|
+
lines = content.split("\n")
|
86
81
|
processed_lines = []
|
87
|
-
|
82
|
+
|
88
83
|
for line in lines:
|
89
84
|
# Remove leading '>' from each line
|
90
|
-
if line.startswith(
|
85
|
+
if line.startswith(">"):
|
91
86
|
line = line[1:].lstrip()
|
92
87
|
processed_lines.append(line)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
88
|
+
|
89
|
+
content_text = "\n".join(processed_lines).strip()
|
90
|
+
|
97
91
|
# Parse the content as markdown
|
98
92
|
if content_text:
|
99
|
-
|
100
|
-
temp_element = etree.Element('div')
|
93
|
+
temp_element = etree.Element("div")
|
101
94
|
self.parser.parseBlocks(temp_element, [content_text])
|
102
|
-
|
103
|
-
# Move all children to our content div
|
95
|
+
|
104
96
|
for child in temp_element:
|
105
97
|
content_div.append(child)
|
106
|
-
|
107
|
-
# If no children were added, add the text directly
|
98
|
+
|
108
99
|
if len(content_div) == 0:
|
109
|
-
p = SubElement(content_div,
|
100
|
+
p = SubElement(content_div, "p")
|
110
101
|
p.text = content_text
|
111
|
-
|
102
|
+
|
112
103
|
# Continue processing subsequent blocks that might be part of the alert
|
113
|
-
while blocks and blocks[0].startswith(
|
104
|
+
while blocks and blocks[0].startswith(">"):
|
114
105
|
continuation = blocks.pop(0)
|
115
|
-
|
116
|
-
|
117
|
-
|
106
|
+
continuation_text = continuation[1:].lstrip() if continuation.startswith(">") else continuation
|
107
|
+
|
118
108
|
if continuation_text:
|
119
|
-
p = SubElement(content_div,
|
109
|
+
p = SubElement(content_div, "p")
|
120
110
|
p.text = continuation_text
|
121
|
-
|
111
|
+
|
122
112
|
return True
|
123
113
|
|
124
114
|
|
125
115
|
class AlertExtension(Extension):
|
126
116
|
"""Add GitHub-style alerts to markdown"""
|
127
|
-
|
117
|
+
|
128
118
|
def extendMarkdown(self, md):
|
129
119
|
"""Add the alert processor to the markdown instance"""
|
130
120
|
md.parser.blockprocessors.register(
|
131
121
|
AlertBlockProcessor(md.parser),
|
132
|
-
|
133
|
-
175 # Priority - process before blockquote
|
134
|
-
)
|
122
|
+
"github_alerts",
|
123
|
+
175, # Priority - process before blockquote
|
124
|
+
)
|
@@ -1,58 +1,53 @@
|
|
1
1
|
"""Core markdown rendering with theme integration"""
|
2
2
|
|
3
3
|
import markdown
|
4
|
-
|
4
|
+
|
5
5
|
from .extensions.alerts import AlertExtension
|
6
6
|
|
7
7
|
|
8
8
|
class MarkdownRenderer:
|
9
9
|
"""Core markdown rendering with theme integration"""
|
10
|
-
|
11
|
-
def __init__(self, extensions:
|
10
|
+
|
11
|
+
def __init__(self, extensions: list[str | markdown.Extension] | None = None):
|
12
12
|
"""Initialize the renderer with optional extensions.
|
13
|
-
|
13
|
+
|
14
14
|
Args:
|
15
15
|
extensions: List of markdown extension names or instances to enable
|
16
16
|
"""
|
17
17
|
self.extensions = extensions or []
|
18
18
|
# Add some useful default extensions
|
19
19
|
default_extensions = [
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
AlertExtension() #
|
20
|
+
"fenced_code",
|
21
|
+
"tables",
|
22
|
+
"nl2br",
|
23
|
+
"sane_lists",
|
24
|
+
AlertExtension(), # GitHub-style alerts
|
25
25
|
]
|
26
26
|
self.extensions.extend(default_extensions)
|
27
|
-
|
28
|
-
# Initialize the markdown processor
|
27
|
+
|
29
28
|
self.md = markdown.Markdown(extensions=self.extensions)
|
30
|
-
|
29
|
+
|
31
30
|
def render(self, markdown_text: str) -> str:
|
32
31
|
"""Convert markdown to themed HTML.
|
33
|
-
|
32
|
+
|
34
33
|
Args:
|
35
34
|
markdown_text: Raw markdown text to render
|
36
|
-
|
35
|
+
|
37
36
|
Returns:
|
38
37
|
HTML string wrapped with eidos-md class for styling
|
39
38
|
"""
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
# Convert markdown to HTML
|
39
|
+
self.md.reset() # TODO: this is a hack to clear the state of the markdown processor
|
40
|
+
|
44
41
|
html_content = self.md.convert(markdown_text)
|
45
|
-
|
46
|
-
# Wrap in a div with our markdown class for styling
|
42
|
+
|
47
43
|
return f'<div class="eidos-md">{html_content}</div>'
|
48
|
-
|
44
|
+
|
49
45
|
def add_extension(self, extension: str) -> None:
|
50
46
|
"""Add a markdown extension.
|
51
|
-
|
47
|
+
|
52
48
|
Args:
|
53
49
|
extension: Name of the markdown extension to add
|
54
50
|
"""
|
55
51
|
if extension not in self.extensions:
|
56
52
|
self.extensions.append(extension)
|
57
|
-
|
58
|
-
self.md = markdown.Markdown(extensions=self.extensions)
|
53
|
+
self.md = markdown.Markdown(extensions=self.extensions)
|
eidos/styles.py
CHANGED
@@ -6,16 +6,19 @@ Only includes classes that are actually defined in the CSS file.
|
|
6
6
|
|
7
7
|
from typing import Final
|
8
8
|
|
9
|
+
|
9
10
|
class Theme:
|
10
11
|
"""Theme-related CSS classes from styles.css."""
|
12
|
+
|
11
13
|
body: Final[str] = "eidos-body"
|
12
14
|
|
15
|
+
|
13
16
|
class Buttons:
|
14
17
|
"""Button-related CSS classes from styles.css."""
|
15
|
-
|
18
|
+
|
16
19
|
# Base button class (required for all buttons)
|
17
20
|
base: Final[str] = "eidos-btn"
|
18
|
-
|
21
|
+
|
19
22
|
# Button variants
|
20
23
|
primary: Final[str] = "eidos-btn-primary"
|
21
24
|
secondary: Final[str] = "eidos-btn-secondary"
|
@@ -25,6 +28,7 @@ class Buttons:
|
|
25
28
|
error: Final[str] = "eidos-btn-error"
|
26
29
|
cta: Final[str] = "eidos-btn-cta"
|
27
30
|
|
31
|
+
|
28
32
|
class Typography:
|
29
33
|
"""Typography-related CSS classes from styles.css."""
|
30
34
|
|
@@ -35,9 +39,7 @@ class Typography:
|
|
35
39
|
h5: Final[str] = "eidos-h5"
|
36
40
|
h6: Final[str] = "eidos-h6"
|
37
41
|
|
38
|
-
|
39
|
-
"""Semantic HTML element CSS classes from styles.css."""
|
40
|
-
|
42
|
+
|
41
43
|
# Text formatting
|
42
44
|
strong: Final[str] = "eidos-strong"
|
43
45
|
i: Final[str] = "eidos-i"
|
@@ -47,34 +49,79 @@ class Semantic:
|
|
47
49
|
var: Final[str] = "eidos-var"
|
48
50
|
mark: Final[str] = "eidos-mark"
|
49
51
|
time: Final[str] = "eidos-time"
|
50
|
-
|
52
|
+
|
51
53
|
# Code elements
|
52
54
|
code: Final[str] = "eidos-code"
|
53
55
|
pre: Final[str] = "eidos-pre"
|
54
56
|
kbd: Final[str] = "eidos-kbd"
|
55
57
|
samp: Final[str] = "eidos-samp"
|
56
|
-
|
58
|
+
|
57
59
|
# Structural elements
|
58
60
|
blockquote: Final[str] = "eidos-blockquote"
|
59
61
|
cite: Final[str] = "eidos-cite"
|
60
62
|
address: Final[str] = "eidos-address"
|
61
63
|
hr: Final[str] = "eidos-hr"
|
62
|
-
|
64
|
+
|
63
65
|
# Interactive elements
|
64
66
|
details: Final[str] = "eidos-details"
|
65
67
|
summary: Final[str] = "eidos-summary"
|
66
68
|
details_content: Final[str] = "eidos-details-content"
|
67
|
-
|
69
|
+
|
68
70
|
# Definition list
|
69
71
|
dl: Final[str] = "eidos-dl"
|
70
72
|
dt: Final[str] = "eidos-dt"
|
71
73
|
dd: Final[str] = "eidos-dd"
|
72
|
-
|
74
|
+
|
73
75
|
# Figure
|
74
76
|
figure: Final[str] = "eidos-figure"
|
75
77
|
figcaption: Final[str] = "eidos-figcaption"
|
76
78
|
|
79
|
+
|
80
|
+
class Lists:
|
81
|
+
"""List-related CSS classes from styles.css."""
|
82
|
+
|
83
|
+
ul: Final[str] = "eidos-ul"
|
84
|
+
ol: Final[str] = "eidos-ol"
|
85
|
+
li: Final[str] = "eidos-li"
|
86
|
+
li_interactive: Final[str] = "eidos-li-interactive"
|
87
|
+
|
88
|
+
|
89
|
+
class Tables:
|
90
|
+
"""Table-related CSS classes from styles.css."""
|
91
|
+
|
92
|
+
# Base table class
|
93
|
+
table: Final[str] = "eidos-table"
|
94
|
+
|
95
|
+
# Table sections
|
96
|
+
thead: Final[str] = "eidos-thead"
|
97
|
+
tbody: Final[str] = "eidos-tbody"
|
98
|
+
tfoot: Final[str] = "eidos-tfoot"
|
99
|
+
|
100
|
+
# Table elements
|
101
|
+
tr: Final[str] = "eidos-tr"
|
102
|
+
th: Final[str] = "eidos-th"
|
103
|
+
td: Final[str] = "eidos-td"
|
104
|
+
|
105
|
+
|
106
|
+
class Tabs:
|
107
|
+
"""Tab-related CSS classes from styles.css."""
|
108
|
+
|
109
|
+
# Container and structure
|
110
|
+
container: Final[str] = "eidos-tabs"
|
111
|
+
list: Final[str] = "eidos-tabs-list"
|
112
|
+
|
113
|
+
# Tab elements
|
114
|
+
tab: Final[str] = "eidos-tab"
|
115
|
+
tab_active: Final[str] = "eidos-tab-active"
|
116
|
+
|
117
|
+
# Panel elements
|
118
|
+
panel: Final[str] = "eidos-tab-panel"
|
119
|
+
panel_active: Final[str] = "eidos-tab-panel-active"
|
120
|
+
|
121
|
+
|
77
122
|
# Create singleton instance for easy access
|
78
123
|
buttons = Buttons()
|
79
124
|
typography = Typography()
|
80
|
-
|
125
|
+
tables = Tables()
|
126
|
+
lists = Lists()
|
127
|
+
tabs = Tabs()
|