Restrict icon/label separator spacing to actionButton() (#4247)

* Follow up to #4242: Restrict icon/label separator spacing to actionButton()

* `yarn build` (GitHub Actions)

* Add spacing only when both icon and label are truthy

* Update snapshot

* `yarn build` (GitHub Actions)

* Slightly more readable JS

* `yarn build` (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
This commit is contained in:
Carson Sievert
2025-06-26 19:12:13 -05:00
committed by GitHub
parent f237de559d
commit 3ea4c8eb1d
9 changed files with 38 additions and 31 deletions

View File

@@ -93,7 +93,10 @@ get_action_children <- function(label, icon) {
# minimize the chance of breaking existing code.
tagList(
icon,
tags$span(class = "shiny-icon-separator"),
tags$span(
class = "shiny-icon-separator",
class = if (length(label) > 0) "shiny-icon-spacer"
),
label
)
} else {

View File

@@ -1137,8 +1137,7 @@
// srcts/src/bindings/input/actionbutton.ts
var import_jquery7 = __toESM(require_jquery());
var iconSeparatorClass = "shiny-icon-separator";
var iconSeparatorHTML = `<span class='${iconSeparatorClass}'></span>`;
var iconSeparatorClasses = ["shiny-icon-separator", "shiny-icon-spacer"];
var ActionButtonInputBinding = class extends InputBinding {
find(scope) {
return (0, import_jquery7.default)(scope).find(".action-button");
@@ -1181,7 +1180,8 @@
deps.push(...data.icon.deps);
}
if (icon.trim()) {
icon = icon + iconSeparatorHTML;
const separatorClasses = label.trim() ? iconSeparatorClasses.join(" ") : iconSeparatorClasses[0];
icon += `<span class='${separatorClasses}'></span>`;
}
await renderContent(el, { html: icon + label, deps });
}
@@ -1201,7 +1201,7 @@
const nodeContents = nodes.map(
(node) => node instanceof Element ? node.outerHTML : node.textContent
);
const separator = el.querySelector(`.${iconSeparatorClass}`);
const separator = el.querySelector(`.${iconSeparatorClasses[0]}`);
if (!separator) {
return { icon: "", label: nodeContents.join("") };
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -463,7 +463,7 @@ textarea.textarea-autoresize.form-control {
}
}
.shiny-icon-separator {
button.action-button > .shiny-icon-spacer {
padding-right: 0.5ch;
}

View File

@@ -10,9 +10,8 @@ type ActionButtonReceiveMessageData = {
disabled?: boolean;
};
// Needs to mirror shiny:::icon_separator()'s markup.
const iconSeparatorClass = "shiny-icon-separator";
const iconSeparatorHTML = `<span class='${iconSeparatorClass}'></span>`;
// Mirror the classes in the CSS/R markup generation for action buttons.
const iconSeparatorClasses = ["shiny-icon-separator", "shiny-icon-spacer"];
class ActionButtonInputBinding extends InputBinding {
find(scope: HTMLElement): JQuery<HTMLElement> {
@@ -65,8 +64,13 @@ class ActionButtonInputBinding extends InputBinding {
deps.push(...data.icon.deps);
}
// Always add the separator when icon is present, but spacing is only needed
// when both icon and label are present.
if (icon.trim()) {
icon = icon + iconSeparatorHTML;
const separatorClasses = label.trim()
? iconSeparatorClasses.join(" ")
: iconSeparatorClasses[0];
icon += `<span class='${separatorClasses}'></span>`;
}
await renderContent(el, { html: icon + label, deps });
@@ -93,7 +97,7 @@ class ActionButtonInputBinding extends InputBinding {
);
// Query the separator element
const separator = el.querySelector(`.${iconSeparatorClass}`);
const separator = el.querySelector(`.${iconSeparatorClasses[0]}`);
// No separator found, so the entire contents are the label.
if (!separator) {

View File

@@ -12,7 +12,7 @@
Output
<button id="foo" type="button" class="btn btn-default action-button">
<i class="far fa-star" role="presentation" aria-label="star icon"></i>
<span class="shiny-icon-separator"></span>
<span class="shiny-icon-separator shiny-icon-spacer"></span>
Click me
</button>