diff --git a/src/gwt/src/org/rstudio/core/client/a11y/A11y.java b/src/gwt/src/org/rstudio/core/client/a11y/A11y.java index a6d390b2c31..a74fadaf4bc 100644 --- a/src/gwt/src/org/rstudio/core/client/a11y/A11y.java +++ b/src/gwt/src/org/rstudio/core/client/a11y/A11y.java @@ -91,4 +91,13 @@ public static void setARIACurrent(Widget widget, String value) { setARIACurrent(widget.getElement(), value); } + + /** + * Make a widget hidden to screen readers. + * @param widget + */ + public static void setARIAHidden(Widget widget) + { + widget.getElement().setAttribute("aria-hidden", "true"); + } } diff --git a/src/gwt/src/org/rstudio/core/client/widget/FieldSetPanel.java b/src/gwt/src/org/rstudio/core/client/widget/FieldSetPanel.java index 5e014a78213..b647817333c 100644 --- a/src/gwt/src/org/rstudio/core/client/widget/FieldSetPanel.java +++ b/src/gwt/src/org/rstudio/core/client/widget/FieldSetPanel.java @@ -18,7 +18,9 @@ import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.HasOneWidget; +import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.SimplePanel; +import org.rstudio.core.client.a11y.A11y; import org.rstudio.core.client.theme.res.ThemeStyles; /** @@ -38,12 +40,29 @@ public FieldSetPanel(String legend, boolean visuallyHideLegend) legendElement_.setClassName(ThemeStyles.INSTANCE.visuallyHidden()); } } + + public FieldSetPanel(String legend) + { + this(legend, false); + } public FieldSetPanel() { this("", false); } + + /** + * @param externalLabel existing visual label for the radio buttons; text of that label + * will be applied to a hidden legend element for accessibility, and + * the label itself will be marked aria-hidden + */ + public FieldSetPanel(Label externalLabel) + { + this(externalLabel.getText(), true); + A11y.setARIAHidden(externalLabel); + } + public void setLegend(String legend) { legendElement_.setInnerText(legend); diff --git a/src/gwt/src/org/rstudio/core/client/widget/HorizontalRadioPanel.java b/src/gwt/src/org/rstudio/core/client/widget/HorizontalRadioPanel.java index 9bef0f197c5..8d048a9e294 100644 --- a/src/gwt/src/org/rstudio/core/client/widget/HorizontalRadioPanel.java +++ b/src/gwt/src/org/rstudio/core/client/widget/HorizontalRadioPanel.java @@ -15,6 +15,7 @@ package org.rstudio.core.client.widget; import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RadioButton; /** @@ -27,6 +28,17 @@ public HorizontalRadioPanel(String legend, boolean visuallyHideLegend) super(legend, visuallyHideLegend); super.add(panel_ = new HorizontalPanel()); } + + /** + * @param externalLabel existing visual label for the radio buttons; text of that label + * will be applied to a hidden legend element for accessibility, and + * the label itself will be marked aria-hidden + */ + public HorizontalRadioPanel(Label externalLabel) + { + super(externalLabel); + super.add(panel_ = new HorizontalPanel()); + } public void add(RadioButton w) { diff --git a/src/gwt/src/org/rstudio/core/client/widget/ModifyKeyboardShortcutsWidget.css b/src/gwt/src/org/rstudio/core/client/widget/ModifyKeyboardShortcutsWidget.css index 96927384a89..6b1637c8739 100644 --- a/src/gwt/src/org/rstudio/core/client/widget/ModifyKeyboardShortcutsWidget.css +++ b/src/gwt/src/org/rstudio/core/client/widget/ModifyKeyboardShortcutsWidget.css @@ -92,6 +92,13 @@ box-shadow: 0 0 4px #8BF; } +fieldset.showChoice { + float: left; + border: none; + padding: 0; + margin: 0; +} + .rstudio-themes-flat .dataGridWidget { background: #FFF; } diff --git a/src/gwt/src/org/rstudio/core/client/widget/ModifyKeyboardShortcutsWidget.java b/src/gwt/src/org/rstudio/core/client/widget/ModifyKeyboardShortcutsWidget.java index 247ede2b297..69ac367f2e1 100644 --- a/src/gwt/src/org/rstudio/core/client/widget/ModifyKeyboardShortcutsWidget.java +++ b/src/gwt/src/org/rstudio/core/client/widget/ModifyKeyboardShortcutsWidget.java @@ -981,10 +981,16 @@ public void onAttachOrDetach(AttachEvent event) Label radioLabel = new Label("Show:"); radioLabel.getElement().getStyle().setFloat(Style.Float.LEFT); radioLabel.getElement().getStyle().setMarginRight(8, Unit.PX); + headerPanel.add(radioLabel); - headerPanel.add(radioAll_); + FieldSetPanel showFieldsetPanel = new FieldSetPanel(radioLabel); + showFieldsetPanel.setStyleName(RES.dataGridStyle().showChoice()); + FlowPanel radioPanel = new FlowPanel(); + showFieldsetPanel.add(radioPanel); + headerPanel.add(showFieldsetPanel); + radioPanel.add(radioAll_); radioAll_.setValue(true); - headerPanel.add(radioCustomized_); + radioPanel.add(radioCustomized_); filterWidget_.getElement().getStyle().setFloat(Style.Float.LEFT); filterWidget_.getElement().getStyle().setMarginLeft(10, Unit.PX); @@ -1474,6 +1480,7 @@ public interface Styles extends RStudioDataGridStyle String conflictRow(); String shortcutInput(); String icon(); + String showChoice(); } private static final Resources RES = GWT.create(Resources.class); diff --git a/src/gwt/src/org/rstudio/core/client/widget/VerticalRadioPanel.java b/src/gwt/src/org/rstudio/core/client/widget/VerticalRadioPanel.java new file mode 100644 index 00000000000..3193fb03d3e --- /dev/null +++ b/src/gwt/src/org/rstudio/core/client/widget/VerticalRadioPanel.java @@ -0,0 +1,49 @@ +/* + * VerticalRadioPanel.java + * + * Copyright (C) 2009-19 by RStudio, Inc. + * + * Unless you have received this program directly from RStudio pursuant + * to the terms of a commercial license agreement with RStudio, then + * this program is licensed to you under the terms of version 3 of the + * GNU Affero General Public License. This program is distributed WITHOUT + * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the + * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. + * + */ +package org.rstudio.core.client.widget; + +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.RadioButton; +import com.google.gwt.user.client.ui.VerticalPanel; + +/** + * A VerticalPanel containing a group of radio buttons and a legend. + */ +public class VerticalRadioPanel extends FieldSetPanel +{ + public VerticalRadioPanel(String legend, boolean visuallyHideLegend) + { + super(legend, visuallyHideLegend); + super.add(panel_ = new VerticalPanel()); + } + + /** + * @param externalLabel existing visual label for the radio buttons; text of that label + * will be applied to a hidden legend element for accessibility, and + * the label itself will be marked aria-hidden + */ + public VerticalRadioPanel(Label externalLabel) + { + super(externalLabel); + super.add(panel_ = new VerticalPanel()); + } + + public void add(RadioButton w) + { + panel_.add(w); + } + + private VerticalPanel panel_; +} diff --git a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/NewShinyWebApplication.css b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/NewShinyWebApplication.css index df625c2b94a..53aca98e71b 100644 --- a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/NewShinyWebApplication.css +++ b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/NewShinyWebApplication.css @@ -14,7 +14,7 @@ } .invalidAppName { - background-color: #f2dede; + background-color: #f2dede; } .appNameTextBox { @@ -22,5 +22,11 @@ } .textBox, .textBox .gwt-TextBox { - padding-left: 4px; + padding-left: 4px; +} + +.shinyTypeGroup { + border: none; + margin: 0; + padding: 0; } \ No newline at end of file diff --git a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/NewShinyWebApplication.java b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/NewShinyWebApplication.java index 31de682cd25..b0ce7576fb0 100644 --- a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/NewShinyWebApplication.java +++ b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/NewShinyWebApplication.java @@ -26,6 +26,7 @@ import org.rstudio.core.client.widget.LayoutGrid; import org.rstudio.core.client.widget.ModalDialog; import org.rstudio.core.client.widget.OperationWithInput; +import org.rstudio.core.client.widget.VerticalRadioPanel; import org.rstudio.core.client.widget.VerticalSpacer; import org.rstudio.studio.client.RStudioGinjector; import org.rstudio.studio.client.common.GlobalDisplay; @@ -210,7 +211,8 @@ public NewShinyWebApplication(String caption, appTypeLabel_.addStyleName(RES.styles().label()); appTypeLabel_.getElement().getStyle().setMarginTop(2, Unit.PX); - VerticalPanel radioPanel = new VerticalPanel(); + VerticalRadioPanel radioPanel = new VerticalRadioPanel(appTypeLabel_); + radioPanel.setStylePrimaryName(RES.styles().shinyTypeGroup()); appTypeSingleFileButton_ = new RadioButton("shiny", "Single File (app.R)"); appTypeMultipleFileButton_ = new RadioButton("shiny", "Multiple File (ui.R/server.R)"); radioPanel.add(appTypeSingleFileButton_); @@ -364,6 +366,7 @@ public interface Styles extends CssResource String invalidAppName(); String appNameTextBox(); String textBox(); + String shinyTypeGroup(); } public interface Resources extends ClientBundle