|
16 | 16 | def component_button( |
17 | 17 | app, |
18 | 18 | context, |
19 | | - content="", |
20 | | - title="", |
21 | | - icon="", |
22 | | - image="", |
23 | | - url="", |
24 | | - onclick="", |
25 | | - button_id="", |
26 | | - label_for="", |
27 | | - id="", |
28 | | - tooltip_placement="", |
| 19 | + content=None, |
| 20 | + title=None, |
| 21 | + icon=None, |
| 22 | + image=None, |
| 23 | + outline=None, |
| 24 | + id=None, |
| 25 | + tooltip_placement=None, |
| 26 | + url=None, |
| 27 | + onclick=None, |
| 28 | + button_id=None, |
| 29 | + label_for=None, |
29 | 30 | attributes={}, |
30 | 31 | classes=[], |
31 | 32 | ): |
| 33 | + """Render a clickable button. |
| 34 | +
|
| 35 | + There are three possible actions that will be triggered, |
| 36 | + corresponding to different kwargs having values. |
| 37 | +
|
| 38 | + Meta Parameters |
| 39 | + --------------- |
| 40 | + app: An instance of sphinx.Application |
| 41 | + context: A Sphinx build context dictionary |
| 42 | +
|
| 43 | + General parameters |
| 44 | + ------------------ |
| 45 | + content: Content to populate inside the button. |
| 46 | + title: A tooltip / accessibility-friendly title. |
| 47 | + icon: A tiny square icon. A set of FontAwesome icon classes, or path to an image. |
| 48 | + image: A larger image of any aspect ratio. A path to a local or remote image. |
| 49 | + button_id: The ID to be added to this button. |
| 50 | + outline: Whether to outline the button. |
| 51 | + tooltip_placement: Whether the tooltip will be to the left, right, top, or bottom. |
| 52 | + attributes: A dictionary of any key:val attributes to add to the button. |
| 53 | + classes: A list of CSS classes to add to the button. |
| 54 | +
|
| 55 | + Action-specific parameters |
| 56 | + -------------------------- |
| 57 | + url: The URL to which a button will direct when clicked. |
| 58 | + onclick: JavaScript that will be called when a person clicks. |
| 59 | + label_for: The input this label should trigger when clicked (button is a label). |
| 60 | + """ |
| 61 | + # Set up attributes and classes that will be used to create HTML attributes at end |
32 | 62 | attributes = attributes.copy() |
33 | | - attributes.update({"type": "button", "class": ["btn", "icon-button"]}) |
34 | | - attributes["class"].extend(classes.copy()) |
| 63 | + attributes.update({"type": "button"}) |
| 64 | + |
| 65 | + # Update classes with custom added ones |
| 66 | + default_classes = ["btn", "icon-button"] |
| 67 | + if classes: |
| 68 | + if isinstance(classes, str): |
| 69 | + classes = [classes] |
| 70 | + else: |
| 71 | + classes = [] |
| 72 | + classes.extend(default_classes) |
| 73 | + |
| 74 | + # Give an outline if desired. |
| 75 | + if outline: |
| 76 | + classes.append("btn-outline") |
| 77 | + |
| 78 | + # Checks for proper arguments |
35 | 79 | btn_content = "" |
36 | 80 | if url and onclick: |
37 | 81 | raise Exception("Button component cannot have both url and onclick specified.") |
@@ -62,33 +106,23 @@ def component_button( |
62 | 106 | """ |
63 | 107 |
|
64 | 108 | if not content: |
65 | | - attributes["class"].append("icon-button-no-content") |
| 109 | + classes.append("icon-button-no-content") |
66 | 110 | else: |
67 | | - btn_content += content |
| 111 | + btn_content += f'<span class="btn__content-container">{content}</span>' |
68 | 112 |
|
69 | 113 | if button_id: |
70 | 114 | attributes["id"] = button_id |
71 | 115 |
|
72 | | - attributes["aria-label"] = title |
73 | | - |
74 | | - # Handle tooltips |
75 | | - title = context["translate"](title) |
76 | | - tooltip_placement = "bottom" if not tooltip_placement else tooltip_placement |
77 | | - |
78 | | - # If we're already using data-toggle, wrap the button content in a span. |
79 | | - # This lets us use another data-toggle. |
80 | | - if "data-toggle" in attributes: |
81 | | - btn_content = f""" |
82 | | - <span data-toggle="tooltip" data-placement="{tooltip_placement}" title="{title}"> |
83 | | - {btn_content} |
84 | | - </span> |
85 | | - """ # noqa |
86 | | - else: |
| 116 | + # Handle tooltips if a title is given |
| 117 | + if title: |
| 118 | + title = context["translate"](title) |
| 119 | + tooltip_placement = "bottom" if not tooltip_placement else tooltip_placement |
| 120 | + attributes["aria-label"] = title |
87 | 121 | attributes["data-placement"] = tooltip_placement |
88 | 122 | attributes["title"] = title |
89 | 123 |
|
90 | 124 | # Convert all the options for the button into a string of HTML attributes |
91 | | - attributes["class"] = " ".join(attributes["class"]) |
| 125 | + attributes["class"] = " ".join(classes) |
92 | 126 | attributes_str = " ".join([f'{key}="{val}"' for key, val in attributes.items()]) |
93 | 127 |
|
94 | 128 | # Generate the button HTML |
@@ -163,13 +197,17 @@ def component_dropdown( |
163 | 197 | dropdown_id = "menu-dropdown-" |
164 | 198 | dropdown_id += hashlib.md5(dropdown_items.encode("utf-8")).hexdigest()[:5] |
165 | 199 |
|
166 | | - # Generate the button HTML |
| 200 | + # Generate the dropdown button HTML |
167 | 201 | dropdown_attributes = { |
168 | 202 | "data-toggle": "dropdown", |
169 | 203 | "aria-haspopup": "true", |
170 | 204 | "aria-expanded": "false", |
171 | 205 | "type": "button", |
172 | 206 | } |
| 207 | + if "title" in kwargs: |
| 208 | + SPHINX_LOGGER.warn("Cannot use title / tooltip with dropdown menu. Removing.") |
| 209 | + kwargs.pop("title") |
| 210 | + |
173 | 211 | html_button = component_button( |
174 | 212 | app, |
175 | 213 | context, |
|
0 commit comments