From 3c74836362e4b14f7ad81368cd422337c9e2a1a5 Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Tue, 5 Aug 2025 00:14:32 +0000 Subject: [PATCH 01/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- ARIA/apg/index/index.md | 21 +- .../examples/quantity-spinbutton.md | 478 ++++++++++++++++++ .../patterns/spinbutton/spinbutton-pattern.md | 2 +- _external/aria-practices | 2 +- .../coverage-and-quality/prop-coverage.csv | 20 +- .../coverage-and-quality/role-coverage.csv | 6 +- .../examples/css/quantity-spinbutton.css | 130 +++++ .../examples/js/quantity-spinbutton.js | 95 ++++ 8 files changed, 730 insertions(+), 24 deletions(-) create mode 100644 ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md create mode 100644 content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css create mode 100644 content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js diff --git a/ARIA/apg/index/index.md b/ARIA/apg/index/index.md index aa4ff463c..9c0e27900 100644 --- a/ARIA/apg/index/index.md +++ b/ARIA/apg/index/index.md @@ -214,7 +214,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Listbox with Grouped Options
  • Editor Menubar (HC)
  • Color Viewer Slider (HC)
  • -
  • Date Picker Spin Button
  • Switch Using HTML Button (HC)
  • File Directory Treeview Using Computed Properties
  • File Directory Treeview Using Declared Properties
  • @@ -241,6 +240,10 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); + + log + Quantity Spin Button + main Main Landmark @@ -409,7 +412,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); spinbutton @@ -583,6 +586,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Actions Menu Button Using aria-activedescendant (HC)
  • Actions Menu Button Using element.focus() (HC)
  • Navigation Menu Button (HC)
  • +
  • Quantity Spin Button
  • Tabs with Automatic Activation (HC)
  • Tabs with Manual Activation (HC)
  • Toolbar
  • @@ -620,6 +624,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); @@ -684,7 +689,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • Quantity Spin Button
  • Switch Using HTML Button (HC)
  • Switch Using HTML Checkbox Input (HC)
  • Switch (HC)
  • @@ -710,7 +715,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Navigation Menubar (HC)
  • Rating Radio Group (HC)
  • Horizontal Multi-Thumb Slider (HC)
  • -
  • Date Picker Spin Button
  • Table
  • Toolbar
  • Treegrid Email Inbox
  • @@ -749,7 +753,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • Switch Using HTML Button (HC)
  • Tabs with Automatic Activation (HC)
  • Tabs with Manual Activation (HC)
  • @@ -783,6 +786,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Auto-Rotating Image Carousel with Tabs for Slide Control (HC)
  • Date Picker Combobox (HC)
  • Date Picker Dialog (HC)
  • +
  • Quantity Spin Button
  • @@ -908,7 +912,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • Quantity Spin Button
  • Toolbar
  • @@ -923,7 +927,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • Quantity Spin Button
  • Toolbar
  • @@ -938,7 +942,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • Quantity Spin Button
  • Toolbar
  • @@ -950,7 +954,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • Toolbar
  • diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md new file mode 100644 index 000000000..041bd122e --- /dev/null +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -0,0 +1,478 @@ +--- +# This file was generated by scripts/pre-build/library/formatForJekyll.js +title: "Quantity Spin Button Example" +ref: /ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton/ + +github: + repository: w3c/aria-practices + branch: main + path: content/patterns/spinbutton/examples/quantity-spinbutton.html +feedbackmail: public-aria-practices@w3.org +permalink: /ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton/ + +sidebar: true + +footer: " " + +# Context here: https://github.com/w3c/wai-aria-practices/issues/31 +type_of_guidance: APG + +lang: en +--- + + +Quantity Spin Button Example + + + + + + + + + + + + + + + + + + +
    + +

    Read This First

    +
    + + The code in this example is not intended for production environments. + Before using it for any purpose, read this to understand why. + +

    This is an illustrative example of one way of using ARIA that conforms with the ARIA specification.

    + +
    + + +
    + + +
    +

    About This Example

    + +

    + The following example uses the Spin Button Pattern to implement three quantity inputs. +

    +

    Similar examples include:

    +
      +
    • Toolbar Example: A toolbar that contains a spin button for setting font size.
    • +
    +
    + +
    +
    +

    Example

    +
    + +
    +
    +
    + Guests +
    +
    + +
    + + + +
    + + +
    +
    + +
    + + + +
    + +
    +
    + +
    + + + +
    + +
    +
    +
    +
    +
    + +
    + +
    +

    Accessibility Features

    +
      +
    • + The element with role spinbutton allows text input, for + users who prefer to enter a value directly. +
    • +
    • + The spin button input and its adjacent buttons are visually + presented as a singular form field containing an editable value, an + increase operation, and a decrease operation. +
    • +
    • + When either the spin button input or its adjacent buttons have + received focus, a single visual focus indicator encompasses all + three, reinforcing the relationship between then. +
    • +
    • + For users who have not set a preference for reduced motion, the + focus indicator appears with subtle animation to draw attention. +
    • +
    • + The increase and decrease buttons: +
        +
      • + Are generously sized for ease of use. +
      • +
      • + Are adjacent to the spin button input so they can be accessed by + users of touch-based and voice-based assistive technologies. +
      • +
      • + Are labeled with the title attribute, providing a + human-friendly representation of the plus and minus characters + for users of voice control and touch screen. The + title attribute also presents a tooltip on hover, + clarifying the meaning of each button’s icon. +
      • +
      • + Use an invisible live region to announce the updated value to + when pressed. The live region empties its contents after 3 + seconds to avoid leaving stale content in the document. +
      • +
      • + Are excluded from the page Tab sequence with + tabindex="-1" because they are redundant with the + arrow key support provided to keyboard users. +
      • +
      • + Can be activated with voice control by speaking a command such + as Click add adult. +
      • +
      +
    • +
    • + When forced colors are enabled, system + color keywords are used to ensure visibility and sufficient + contrast for the spin button’s content and interactive states. +
    • +
    +
    + +
    +

    Keyboard Support

    +

    The spin buttons provide the following keyboard support described in the Spin Button Pattern.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    KeyFunction
    Down ArrowDecreases value by 1.
    Up ArrowIncreases value by 1.
    HomeDecreases to minimum value.
    EndIncreases to maximum value.
    +
    + +
    +

    Role, Property, State, and Tabindex Attributes

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    RoleAttributeElementUsage
    spinbuttoninput[type="text"]Identifies the input[type="text"] element as a spin button.
    aria-valuenow="NUMBER"input[type="text"] +
      +
    • Indicates the current numeric value of the spin button.
    • +
    • Updated by JavaScript as users change the value of the spin button.
    • +
    +
    aria-valuemin="NUMBER"input[type="text"]Indicates the minimum allowed value for the spin button.
    aria-valuemax="NUMBER"input[type="text"] +
      +
    • Indicates the maximum allowed value for the spin button.
    • +
    • For the Day spin button, this property is updated based on the value of the Month spin button.
    • +
    +
    title="NAME_STRING"buttonDefines the accessible name for each increase and decrease button (Remove adult, Add adult, Remove kid, Add kid, Remove animal, and Add animal).
    + aria-controls="ID_REF" + buttonIdentifies the element whose value will be modified when the button is activated.
    tabindex="-1"buttonRemoves the decrease and increase buttons from the page Tab sequence while keeping them focusable so they can be accessed with touch-based and voice-based assistive technologies.
    aria-disabled="true"buttonSet when the minimum or maximum value has been reached to inform assistive technologies that the button has been disabled.
    aria-disabled="false"buttonSet when the value is greater than the minimum value or lesser than the maximum value.
    aria-hidden="true"spanFor assistive technology users, hides the visible minus and plus characters in the decrease and increase buttons since they are symbolic of the superior button labels provided by the title attribute.
    logoutputIdentifies the invisible output element as a log.
    + aria-live="polite" + + output + +
      +
    • Triggers a screen reader announcement of the output element’s updated content at the next graceful opportunity.
    • +
    • When either the increase or decrease button is pressed, the current value of the spin button is injected into the output element.
    • +
    • In keeping with the log role of the output, its contents are emptied 3 seconds after injection.
    • +
    +
    +
    + +
    +

    JavaScript and CSS Source Code

    + +
    + +
    +

    HTML Source Code

    +

    To copy the following HTML code, please open it in CodePen.

    + +
    + + +
    +
    + +
    + + diff --git a/ARIA/apg/patterns/spinbutton/spinbutton-pattern.md b/ARIA/apg/patterns/spinbutton/spinbutton-pattern.md index 836aebcce..d1838856c 100644 --- a/ARIA/apg/patterns/spinbutton/spinbutton-pattern.md +++ b/ARIA/apg/patterns/spinbutton/spinbutton-pattern.md @@ -79,7 +79,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');

    Example

    -

    Date Picker Spin Button Example: Illustrates a date picker made from three spin buttons for day, month, and year.

    +

    Quantity Spin Button Example: A set of three spin buttons to collect the quantities of adults, children, and animals for a hotel reservation.

    diff --git a/_external/aria-practices b/_external/aria-practices index 219f52615..2bce4d058 160000 --- a/_external/aria-practices +++ b/_external/aria-practices @@ -1 +1 @@ -Subproject commit 219f52615d93e94787420af37be029a3d40ccd7d +Subproject commit 2bce4d0585e9a950248115ee1e73ffc2f1a79109 diff --git a/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv b/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv index 64c42b359..796218971 100644 --- a/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv +++ b/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv @@ -7,24 +7,24 @@ "aria-colcount","1","1","Guidance: Using aria-colcount and aria-colindex","Example: Data Grid" "aria-colindex","3","1","Guidance: Using aria-colcount and aria-colindex","Guidance: Using aria-colindex When Column Indices Are Contiguous","Guidance: Using aria-colindex When Column Indices Are Not Contiguous","Example: Data Grid" "aria-colspan","1","0","Guidance: Defining cell spans using aria-colspan and aria-rowspan" -"aria-controls","0","22","Example: Accordion","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Checkbox (Mixed-State)","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Disclosure (Show/Hide) Card","Example: Disclosure (Show/Hide) for Answers to Frequently Asked Questions","Example: Disclosure (Show/Hide) for Image Description","Example: Disclosure Navigation Menu with Top-Level Links","Example: Disclosure Navigation Menu","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: Toolbar" +"aria-controls","0","23","Example: Accordion","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Checkbox (Mixed-State)","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Disclosure (Show/Hide) Card","Example: Disclosure (Show/Hide) for Answers to Frequently Asked Questions","Example: Disclosure (Show/Hide) for Image Description","Example: Disclosure Navigation Menu with Top-Level Links","Example: Disclosure Navigation Menu","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Quantity Spin Button","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: Toolbar" "aria-current","0","5","Example: Breadcrumb","Example: Disclosure Navigation Menu with Top-Level Links","Example: Disclosure Navigation Menu","Example: Navigation Menubar","Example: Navigation Treeview" "aria-describedby","1","6","Guidance: Describing by referencing content with aria-describedby","Example: Alert Dialog","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Table" "aria-details","0","0" -"aria-disabled","0","3","Example: Alert Dialog","Example: Editor Menubar","Example: Toolbar" +"aria-disabled","0","4","Example: Alert Dialog","Example: Editor Menubar","Example: Quantity Spin Button","Example: Toolbar" "aria-dropeffect","0","0" "aria-errormessage","0","0" "aria-expanded","0","23","Example: Accordion","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Disclosure (Show/Hide) Card","Example: Disclosure (Show/Hide) for Answers to Frequently Asked Questions","Example: Disclosure (Show/Hide) for Image Description","Example: Disclosure Navigation Menu with Top-Level Links","Example: Disclosure Navigation Menu","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Editor Menubar","Example: Navigation Menubar","Example: Toolbar","Example: Treegrid Email Inbox","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview" "aria-flowto","0","0" "aria-grabbed","0","0" "aria-haspopup","0","9","Example: Date Picker Combobox","Example: Editable Combobox with Grid Popup","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Editor Menubar","Example: Navigation Menubar","Example: Toolbar" -"aria-hidden","0","16","Example: Button (IDL Version)","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Editor Menubar","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Date Picker Spin Button","Example: Switch Using HTML Button","Example: Switch Using HTML Checkbox Input","Example: Switch","Example: Sortable Table","Example: Toolbar" +"aria-hidden","0","16","Example: Button (IDL Version)","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Editor Menubar","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Quantity Spin Button","Example: Switch Using HTML Button","Example: Switch Using HTML Checkbox Input","Example: Switch","Example: Sortable Table","Example: Toolbar" "aria-invalid","0","0" "aria-keyshortcuts","0","0" -"aria-label","1","18","Guidance: Naming with a String Attribute Via aria-label","Example: Breadcrumb","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Link","Example: Editor Menubar","Example: Navigation Menubar","Example: Rating Radio Group","Example: Horizontal Multi-Thumb Slider","Example: Date Picker Spin Button","Example: Table","Example: Toolbar","Example: Treegrid Email Inbox","Example: Navigation Treeview" -"aria-labelledby","1","41","Guidance: Naming with Referenced Content Via aria-labelledby","Example: Accordion","Example: Alert Dialog","Example: Checkbox (Two State)","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Data Grid","Example: Layout Grid","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Navigation Menubar","Example: Meter","Example: Radio Group Using aria-activedescendant","Example: Rating Radio Group","Example: Radio Group Using Roving tabindex","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Date Picker Spin Button","Example: Switch Using HTML Button","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview","Example: Complementary Landmark","Example: Form Landmark","Example: Main Landmark","Example: Navigation Landmark","Example: Region Landmark","Example: Search Landmark" +"aria-label","1","17","Guidance: Naming with a String Attribute Via aria-label","Example: Breadcrumb","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Link","Example: Editor Menubar","Example: Navigation Menubar","Example: Rating Radio Group","Example: Horizontal Multi-Thumb Slider","Example: Table","Example: Toolbar","Example: Treegrid Email Inbox","Example: Navigation Treeview" +"aria-labelledby","1","40","Guidance: Naming with Referenced Content Via aria-labelledby","Example: Accordion","Example: Alert Dialog","Example: Checkbox (Two State)","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Data Grid","Example: Layout Grid","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Navigation Menubar","Example: Meter","Example: Radio Group Using aria-activedescendant","Example: Rating Radio Group","Example: Radio Group Using Roving tabindex","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Switch Using HTML Button","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview","Example: Complementary Landmark","Example: Form Landmark","Example: Main Landmark","Example: Navigation Landmark","Example: Region Landmark","Example: Search Landmark" "aria-level","0","2","Example: Treegrid Email Inbox","Example: File Directory Treeview Using Declared Properties" -"aria-live","0","5","Example: Alert","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Date Picker Combobox","Example: Date Picker Dialog" +"aria-live","0","6","Example: Alert","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Quantity Spin Button" "aria-modal","0","4","Example: Alert Dialog","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Modal Dialog" "aria-multiline","0","0" "aria-multiselectable","0","1","Example: Listboxes with Rearrangeable Options" @@ -43,7 +43,7 @@ "aria-selected","0","17","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Date Picker Dialog","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties" "aria-setsize","0","3","Example: Infinite Scrolling Feed","Example: Treegrid Email Inbox","Example: File Directory Treeview Using Declared Properties" "aria-sort","1","2","Guidance: Indicating sort order with aria-sort","Example: Data Grid","Example: Sortable Table" -"aria-valuemax","1","8","Guidance: Using aria-valuemin, aria-valuemax and aria-valuenow","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Date Picker Spin Button","Example: Toolbar" -"aria-valuemin","0","8","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Date Picker Spin Button","Example: Toolbar" -"aria-valuenow","1","8","Guidance: Using aria-valuemin, aria-valuemax and aria-valuenow","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Date Picker Spin Button","Example: Toolbar" -"aria-valuetext","1","5","Guidance: Using aria-valuetext","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Date Picker Spin Button","Example: Toolbar" +"aria-valuemax","1","8","Guidance: Using aria-valuemin, aria-valuemax and aria-valuenow","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Quantity Spin Button","Example: Toolbar" +"aria-valuemin","0","8","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Quantity Spin Button","Example: Toolbar" +"aria-valuenow","1","8","Guidance: Using aria-valuemin, aria-valuemax and aria-valuenow","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Quantity Spin Button","Example: Toolbar" +"aria-valuetext","1","4","Guidance: Using aria-valuetext","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Toolbar" diff --git a/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv b/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv index e760c3cb2..e3b4213d8 100644 --- a/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv +++ b/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv @@ -25,7 +25,7 @@ "generic","0","0" "grid","3","5","Guidance: Grid Popup Keyboard Interaction","Guidance: Grid (Interactive Tabular Data and Layout Containers) Pattern","Guidance: Grid and Table Properties","Example: Date Picker Combobox","Example: Editable Combobox with Grid Popup","Example: Date Picker Dialog","Example: Data Grid","Example: Layout Grid" "gridcell","0","3","Example: Editable Combobox with Grid Popup","Example: Layout Grid","Example: Treegrid Email Inbox" -"group","2","10","Guidance: Radio Group Pattern","Guidance: For Radio Group Contained in a Toolbar","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Checkbox (Two State)","Example: Listbox with Grouped Options","Example: Editor Menubar","Example: Color Viewer Slider","Example: Date Picker Spin Button","Example: Switch Using HTML Button","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview" +"group","2","9","Guidance: Radio Group Pattern","Guidance: For Radio Group Contained in a Toolbar","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Checkbox (Two State)","Example: Listbox with Grouped Options","Example: Editor Menubar","Example: Color Viewer Slider","Example: Switch Using HTML Button","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview" "heading","0","0" "img","0","0" "input","0","0" @@ -34,7 +34,7 @@ "list","0","0" "listbox","2","8","Guidance: Listbox Popup Keyboard Interaction","Guidance: Listbox Pattern","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Select-Only Combobox","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox" "listitem","0","0" -"log","0","0" +"log","0","1","Example: Quantity Spin Button" "main","1","1","Guidance: Main","Example: Main Landmark" "marquee","0","0" "math","0","0" @@ -62,7 +62,7 @@ "searchbox","0","0" "separator","0","1","Example: Editor Menubar" "slider","2","5","Guidance: Slider (Multi-Thumb) Pattern","Guidance: Slider Pattern","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider" -"spinbutton","1","2","Guidance: Spinbutton Pattern","Example: Date Picker Spin Button","Example: Toolbar" +"spinbutton","1","2","Guidance: Spinbutton Pattern","Example: Quantity Spin Button","Example: Toolbar" "status","0","0" "switch","1","3","Guidance: Switch Pattern","Example: Switch Using HTML Button","Example: Switch Using HTML Checkbox Input","Example: Switch" "tab","1","4","Guidance: Keyboard Navigation Between Components (The Tab Sequence)","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation" diff --git a/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css b/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css new file mode 100644 index 000000000..d09b86474 --- /dev/null +++ b/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css @@ -0,0 +1,130 @@ +.spinners { + --length-s: 0.25rem; + --length-m: 0.5rem; + --color-field-background: white; + --color-button-background-idle: color-mix(in srgb, ghostwhite, darkblue 10%); + --color-button-background-hover: color-mix(in srgb, ghostwhite, darkblue 20%); + --color-interactive-focus: var(--wai-green, #005a6a); + --transition-duration-snappy: 0; + --transition-duration-leisurely: 0; + + @media (prefers-reduced-motion: no-preference) and (forced-colors: none) { + --transition-duration-snappy: 0.15s; + --transition-duration-leisurely: 0.5s; + } + + @media (forced-colors: active) { + --color-interactive-focus: Highlight; + } + + display: inline-flex; + font-family: system-ui, sans-serif; + line-height: 1.4; + padding: 1rem; + background-color: color-mix(in srgb, ghostwhite, darkblue 1%); + border: 1px solid color-mix(in srgb, ghostwhite, darkblue 10%); + border-radius: 0.5rem; + + *, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; + } + + .visually-hidden { + border: 0; + clip: rect(0 0 0 0); + height: auto; + margin: 0; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + white-space: nowrap; + } + + fieldset { + padding: 0.5rem; + border: 1px solid transparent; + } + + legend { + font-size: 1.2rem; + font-weight: bold; + margin-block-end: 1rem; + } + + .fields { + display: flex; + flex-wrap: wrap; + gap: 2ch; + } + + .field { + display: flex; + flex-direction: column; + gap: 0.5rem; + + label { + font-size: 1.2rem; + } + } + + .spinner { + display: flex; + flex-wrap: wrap; + gap: 0; + max-inline-size: calc(100vw - 6.4rem); + font-size: 1.4rem; + border: 1px solid color-mix(in srgb, ghostwhite, darkblue 60%); + border-radius: 0.25rem; + padding: 0.125em; + background-color: var(--color-field-background); + outline: 0 solid transparent; + outline-offset: 0; + transition: + outline-offset var(--transition-duration-snappy) ease, + outline-width var(--transition-duration-snappy) ease, + outline-color var(--transition-duration-snappy) ease, + border-color var(--transition-duration-snappy) ease; + + &:focus-within { + outline: var(--length-s) solid var(--color-interactive-focus); + outline-offset: var(--length-s); + } + + input, button { + font: inherit; + font-weight: bold; + color: inherit; + border: none; + background: transparent; + padding: 0.25em 0.5em; + margin: 0; + outline: none; + } + + [role="spinbutton"] { + text-align: center; + min-inline-size: 4ch; + max-inline-size: fit-content; + field-sizing: content; + font-variant-numeric: tabular-nums; + } + + button { + min-inline-size: 3ch; + background-color: var(--color-button-background-idle); + + &:hover { + background-color: var(--color-button-background-hover); + } + + &[aria-disabled="true"] { + opacity: 0.25; + background-color: transparent; + cursor: not-allowed; + } + } + } +} diff --git a/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js new file mode 100644 index 000000000..9159f2b38 --- /dev/null +++ b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js @@ -0,0 +1,95 @@ +/* + * This content is licensed according to the W3C Software License at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * + * File: quantity-spinbutton.js + */ + +'use strict'; + +class SpinButton { + constructor(el) { + this.el = el; + this.id = el.id; + this.controls = Array.from(document.querySelectorAll(`button[aria-controls="${this.id}"]`)); + this.output = document.querySelector(`output[for="${this.id}"]`); + this.timer = null; + this.setBounds(); + el.addEventListener('input', () => this.setValue(el.value)); + el.addEventListener('blur', () => this.setValue(el.value, true)); + el.addEventListener('keydown', e => this.handleKey(e)); + this.controls.forEach(btn => btn.addEventListener('click', () => this.handleClick(btn))); + this.setValue(el.value); + } + + clamp(n) { + return Math.min(Math.max(n, this.min), this.max); + } + + parseValue(raw) { + const s = String(raw).trim(); + if (!s) return null; + const n = parseInt(s.replace(/[^\d-]/g, ''), 10); + return isNaN(n) ? null : n; + } + + setBounds() { + const el = this.el; + this.hasMin = el.hasAttribute('aria-valuemin'); + this.hasMax = el.hasAttribute('aria-valuemax'); + this.min = this.hasMin ? +el.getAttribute('aria-valuemin') : Number.MIN_SAFE_INTEGER; + this.max = this.hasMax ? +el.getAttribute('aria-valuemax') : Number.MAX_SAFE_INTEGER; + } + + setValue(raw, onBlur = false) { + let val = typeof raw === 'number' ? raw : this.parseValue(raw); + val = (val === null) ? ((onBlur && this.hasMin) ? this.min : '') : this.clamp(val); + this.el.value = val; + this.el.setAttribute('aria-valuenow', val); + this.updateButtonStates(); + } + + updateButtonStates() { + const val = +this.el.value; + this.controls.forEach(btn => { + const op = btn.getAttribute('data-spinbutton-operation'); + btn.setAttribute('aria-disabled', + (op === 'decrement' ? val <= this.min : val >= this.max) ? 'true' : 'false' + ); + }); + } + + announce() { + if (!this.output) return; + this.output.textContent = this.el.value; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.output.textContent = ''; + this.timer = null; + }, 3000); + } + + handleKey(e) { + let v = +this.el.value || 0; + if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { + e.preventDefault(); + this.setValue(v + (e.key === 'ArrowUp' ? 1 : -1)); + } else if (e.key === 'Home') { + e.preventDefault(); + this.setValue(this.min); + } else if (e.key === 'End') { + e.preventDefault(); + this.setValue(this.max); + } + } + + handleClick(btn) { + const dir = btn.getAttribute('data-spinbutton-operation') === 'decrement' ? -1 : 1; + this.setValue((+this.el.value || 0) + dir); + this.announce(); + } +} + +window.addEventListener('load', () => + document.querySelectorAll('[role="spinbutton"]').forEach(el => new SpinButton(el)) +); From ac87b8364594aaf9ad9c25b6a5b03874bc5abd5d Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Tue, 5 Aug 2025 00:29:58 +0000 Subject: [PATCH 02/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- .../patterns/spinbutton/examples/quantity-spinbutton.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md index 041bd122e..1246041cc 100644 --- a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -12,7 +12,7 @@ permalink: /ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton/ sidebar: true -footer: " " +footer: " " # Context here: https://github.com/w3c/wai-aria-practices/issues/31 type_of_guidance: APG @@ -136,11 +136,11 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); type="text" size="4" inputmode="numeric" - autocorrect="off" autocomplete="off" spellcheck="false" aria-valuemin="1" aria-valuemax="8" + aria-valuenow="1" value="1" > - - +
    - +
    - +
    @@ -248,7 +252,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • The spin button input and its adjacent buttons are visually presented as a singular form field containing an editable value, an - increase operation, and a decrease operation. + increment button, and a + decrement button.
  • When either the spin button input or its adjacent buttons have @@ -260,7 +265,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); focus indicator appears with subtle animation to draw attention.
  • - The increase and decrease buttons: + The increment and decrement buttons:
    • Are generously sized for ease of use. @@ -327,6 +332,15 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); End Increases to maximum value. + + Standard single line text editing keys + +
        +
      • Keys used for cursor movement and text manipulation, such as Delete and Shift + Right Arrow.
      • +
      • An HTML input with type="text" is used for the spin button so the browser will provide platform-specific editing keys.
      • +
      + +
  • @@ -370,18 +384,13 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); aria-valuemax="NUMBER" input[type="text"] - - - + Indicates the maximum allowed value for the spin button. title="NAME_STRING" button - Defines the accessible name for each increase and decrease button (Remove adult, Add adult, Remove kid, Add kid, Remove animal, and Add animal). + Defines the accessible name for each increment and decrement button (Remove adult, Add adult, Remove kid, Add kid, Remove animal, and Add animal). @@ -395,15 +404,15 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); tabindex="-1" button - Removes the decrease and increase buttons from the page Tab sequence while keeping them focusable so they can be accessed with touch-based and voice-based assistive technologies. + Removes the increment and decrement buttons from the page Tab sequence while keeping them focusable so they can be accessed with touch-based and voice-based assistive technologies. - + aria-disabled="true" button Set when the minimum or maximum value has been reached to inform assistive technologies that the button has been disabled. - + aria-disabled="false" button @@ -413,27 +422,18 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); aria-hidden="true" span - For assistive technology users, hides the visible minus and plus characters in the decrease and increase buttons since they are symbolic of the superior button labels provided by the title attribute. - - - log - - output - Identifies the invisible output element as a log. + For assistive technology users, hides the visible minus and plus characters in the increment and decrement buttons since they are symbolic of the superior button labels provided by the title attribute. - + + status - - aria-live="polite" - - - output - + div diff --git a/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv b/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv index 796218971..19db885b0 100644 --- a/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv +++ b/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv @@ -18,13 +18,13 @@ "aria-flowto","0","0" "aria-grabbed","0","0" "aria-haspopup","0","9","Example: Date Picker Combobox","Example: Editable Combobox with Grid Popup","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Editor Menubar","Example: Navigation Menubar","Example: Toolbar" -"aria-hidden","0","16","Example: Button (IDL Version)","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Editor Menubar","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Quantity Spin Button","Example: Switch Using HTML Button","Example: Switch Using HTML Checkbox Input","Example: Switch","Example: Sortable Table","Example: Toolbar" +"aria-hidden","0","17","Example: Button (IDL Version)","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Editor Menubar","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: (Deprecated) Date Picker Spin Button","Example: Quantity Spin Button","Example: Switch Using HTML Button","Example: Switch Using HTML Checkbox Input","Example: Switch","Example: Sortable Table","Example: Toolbar" "aria-invalid","0","0" "aria-keyshortcuts","0","0" -"aria-label","1","17","Guidance: Naming with a String Attribute Via aria-label","Example: Breadcrumb","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Link","Example: Editor Menubar","Example: Navigation Menubar","Example: Rating Radio Group","Example: Horizontal Multi-Thumb Slider","Example: Table","Example: Toolbar","Example: Treegrid Email Inbox","Example: Navigation Treeview" -"aria-labelledby","1","40","Guidance: Naming with Referenced Content Via aria-labelledby","Example: Accordion","Example: Alert Dialog","Example: Checkbox (Two State)","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Data Grid","Example: Layout Grid","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Navigation Menubar","Example: Meter","Example: Radio Group Using aria-activedescendant","Example: Rating Radio Group","Example: Radio Group Using Roving tabindex","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Switch Using HTML Button","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview","Example: Complementary Landmark","Example: Form Landmark","Example: Main Landmark","Example: Navigation Landmark","Example: Region Landmark","Example: Search Landmark" +"aria-label","1","18","Guidance: Naming with a String Attribute Via aria-label","Example: Breadcrumb","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Link","Example: Editor Menubar","Example: Navigation Menubar","Example: Rating Radio Group","Example: Horizontal Multi-Thumb Slider","Example: (Deprecated) Date Picker Spin Button","Example: Table","Example: Toolbar","Example: Treegrid Email Inbox","Example: Navigation Treeview" +"aria-labelledby","1","41","Guidance: Naming with Referenced Content Via aria-labelledby","Example: Accordion","Example: Alert Dialog","Example: Checkbox (Two State)","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Data Grid","Example: Layout Grid","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Navigation Menubar","Example: Meter","Example: Radio Group Using aria-activedescendant","Example: Rating Radio Group","Example: Radio Group Using Roving tabindex","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: (Deprecated) Date Picker Spin Button","Example: Switch Using HTML Button","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview","Example: Complementary Landmark","Example: Form Landmark","Example: Main Landmark","Example: Navigation Landmark","Example: Region Landmark","Example: Search Landmark" "aria-level","0","2","Example: Treegrid Email Inbox","Example: File Directory Treeview Using Declared Properties" -"aria-live","0","6","Example: Alert","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Quantity Spin Button" +"aria-live","0","5","Example: Alert","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Date Picker Combobox","Example: Date Picker Dialog" "aria-modal","0","4","Example: Alert Dialog","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Modal Dialog" "aria-multiline","0","0" "aria-multiselectable","0","1","Example: Listboxes with Rearrangeable Options" @@ -43,7 +43,7 @@ "aria-selected","0","17","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Date Picker Dialog","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties" "aria-setsize","0","3","Example: Infinite Scrolling Feed","Example: Treegrid Email Inbox","Example: File Directory Treeview Using Declared Properties" "aria-sort","1","2","Guidance: Indicating sort order with aria-sort","Example: Data Grid","Example: Sortable Table" -"aria-valuemax","1","8","Guidance: Using aria-valuemin, aria-valuemax and aria-valuenow","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Quantity Spin Button","Example: Toolbar" -"aria-valuemin","0","8","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Quantity Spin Button","Example: Toolbar" -"aria-valuenow","1","8","Guidance: Using aria-valuemin, aria-valuemax and aria-valuenow","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Quantity Spin Button","Example: Toolbar" -"aria-valuetext","1","4","Guidance: Using aria-valuetext","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Toolbar" +"aria-valuemax","1","9","Guidance: Using aria-valuemin, aria-valuemax and aria-valuenow","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: (Deprecated) Date Picker Spin Button","Example: Quantity Spin Button","Example: Toolbar" +"aria-valuemin","0","9","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: (Deprecated) Date Picker Spin Button","Example: Quantity Spin Button","Example: Toolbar" +"aria-valuenow","1","9","Guidance: Using aria-valuemin, aria-valuemax and aria-valuenow","Example: Meter","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: (Deprecated) Date Picker Spin Button","Example: Quantity Spin Button","Example: Toolbar" +"aria-valuetext","1","5","Guidance: Using aria-valuetext","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: (Deprecated) Date Picker Spin Button","Example: Toolbar" diff --git a/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv b/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv index e3b4213d8..9a74b8c4f 100644 --- a/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv +++ b/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv @@ -25,7 +25,7 @@ "generic","0","0" "grid","3","5","Guidance: Grid Popup Keyboard Interaction","Guidance: Grid (Interactive Tabular Data and Layout Containers) Pattern","Guidance: Grid and Table Properties","Example: Date Picker Combobox","Example: Editable Combobox with Grid Popup","Example: Date Picker Dialog","Example: Data Grid","Example: Layout Grid" "gridcell","0","3","Example: Editable Combobox with Grid Popup","Example: Layout Grid","Example: Treegrid Email Inbox" -"group","2","9","Guidance: Radio Group Pattern","Guidance: For Radio Group Contained in a Toolbar","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Checkbox (Two State)","Example: Listbox with Grouped Options","Example: Editor Menubar","Example: Color Viewer Slider","Example: Switch Using HTML Button","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview" +"group","2","10","Guidance: Radio Group Pattern","Guidance: For Radio Group Contained in a Toolbar","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Checkbox (Two State)","Example: Listbox with Grouped Options","Example: Editor Menubar","Example: Color Viewer Slider","Example: (Deprecated) Date Picker Spin Button","Example: Switch Using HTML Button","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview" "heading","0","0" "img","0","0" "input","0","0" @@ -34,7 +34,7 @@ "list","0","0" "listbox","2","8","Guidance: Listbox Popup Keyboard Interaction","Guidance: Listbox Pattern","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Select-Only Combobox","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox" "listitem","0","0" -"log","0","1","Example: Quantity Spin Button" +"log","0","0" "main","1","1","Guidance: Main","Example: Main Landmark" "marquee","0","0" "math","0","0" @@ -62,8 +62,8 @@ "searchbox","0","0" "separator","0","1","Example: Editor Menubar" "slider","2","5","Guidance: Slider (Multi-Thumb) Pattern","Guidance: Slider Pattern","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider" -"spinbutton","1","2","Guidance: Spinbutton Pattern","Example: Quantity Spin Button","Example: Toolbar" -"status","0","0" +"spinbutton","1","3","Guidance: Spinbutton Pattern","Example: (Deprecated) Date Picker Spin Button","Example: Quantity Spin Button","Example: Toolbar" +"status","0","1","Example: Quantity Spin Button" "switch","1","3","Guidance: Switch Pattern","Example: Switch Using HTML Button","Example: Switch Using HTML Checkbox Input","Example: Switch" "tab","1","4","Guidance: Keyboard Navigation Between Components (The Tab Sequence)","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation" "table","2","1","Guidance: Table Pattern","Guidance: Grid and Table Properties","Example: Table" diff --git a/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js index 7bc1ba31e..381a5e295 100644 --- a/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js +++ b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js @@ -14,7 +14,7 @@ class SpinButton { this.controls = Array.from( document.querySelectorAll(`button[aria-controls="${this.id}"]`) ); - this.output = document.querySelector(`output[for="${this.id}"]`); + this.status = document.querySelector(`[role="status"][for="${this.id}"]`); this.timer = null; this.setBounds(); el.addEventListener('input', () => this.setValue(el.value)); @@ -72,13 +72,13 @@ class SpinButton { } announce() { - if (!this.output) return; - this.output.textContent = this.el.value; + if (!this.status) return; + this.status.textContent = this.el.value; clearTimeout(this.timer); this.timer = setTimeout(() => { - this.output.textContent = ''; + this.status.textContent = ''; this.timer = null; - }, 3000); + }, this.status.dataset.selfDestruct || 1000); } handleKey(e) { From c8db31137e9372ff076c01bfe92197e4d923ca5c Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Fri, 8 Aug 2025 06:20:07 +0000 Subject: [PATCH 09/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- ARIA/apg/index/index.md | 4 --- .../examples/quantity-spinbutton.md | 27 +++++++++---------- .../coverage-and-quality/role-coverage.csv | 2 +- .../examples/js/quantity-spinbutton.js | 10 +++---- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/ARIA/apg/index/index.md b/ARIA/apg/index/index.md index 65c87eb4e..19f5c2bdd 100644 --- a/ARIA/apg/index/index.md +++ b/ARIA/apg/index/index.md @@ -415,10 +415,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); - - status - Quantity Spin Button - switch diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md index 999896ff5..7fdadeb36 100644 --- a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -152,10 +152,9 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); -
    + class="visually-hidden">
    -
    + class="visually-hidden">
    -
    + class="visually-hidden"> @@ -424,15 +421,15 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); span For assistive technology users, hides the visible minus and plus characters in the increment and decrement buttons since they are symbolic of the superior button labels provided by the title attribute. - - status + - div + + output diff --git a/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv b/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv index 9a74b8c4f..8b06bb226 100644 --- a/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv +++ b/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv @@ -63,7 +63,7 @@ "separator","0","1","Example: Editor Menubar" "slider","2","5","Guidance: Slider (Multi-Thumb) Pattern","Guidance: Slider Pattern","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider" "spinbutton","1","3","Guidance: Spinbutton Pattern","Example: (Deprecated) Date Picker Spin Button","Example: Quantity Spin Button","Example: Toolbar" -"status","0","1","Example: Quantity Spin Button" +"status","0","0" "switch","1","3","Guidance: Switch Pattern","Example: Switch Using HTML Button","Example: Switch Using HTML Checkbox Input","Example: Switch" "tab","1","4","Guidance: Keyboard Navigation Between Components (The Tab Sequence)","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation" "table","2","1","Guidance: Table Pattern","Guidance: Grid and Table Properties","Example: Table" diff --git a/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js index 381a5e295..85c54354e 100644 --- a/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js +++ b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js @@ -14,7 +14,7 @@ class SpinButton { this.controls = Array.from( document.querySelectorAll(`button[aria-controls="${this.id}"]`) ); - this.status = document.querySelector(`[role="status"][for="${this.id}"]`); + this.output = document.querySelector(`output[for="${this.id}"]`); this.timer = null; this.setBounds(); el.addEventListener('input', () => this.setValue(el.value)); @@ -72,13 +72,13 @@ class SpinButton { } announce() { - if (!this.status) return; - this.status.textContent = this.el.value; + if (!this.output) return; + this.output.textContent = this.el.value; clearTimeout(this.timer); this.timer = setTimeout(() => { - this.status.textContent = ''; + this.output.textContent = ''; this.timer = null; - }, this.status.dataset.selfDestruct || 1000); + }, this.output.dataset.selfDestruct || 1000); } handleKey(e) { From e2d27dcb0d75325a0fbd0db9d034d99f722a1038 Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Sat, 9 Aug 2025 01:22:26 +0000 Subject: [PATCH 10/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- .../spinbutton/examples/quantity-spinbutton.md | 2 +- .../spinbutton/examples/css/quantity-spinbutton.css | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md index 7fdadeb36..b45344289 100644 --- a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -12,7 +12,7 @@ permalink: /ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton/ sidebar: true -footer: " " +footer: " " # Context here: https://github.com/w3c/wai-aria-practices/issues/31 type_of_guidance: APG diff --git a/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css b/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css index a9fbba55c..c9af4f4df 100644 --- a/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css +++ b/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css @@ -25,7 +25,9 @@ border: 1px solid color-mix(in srgb, ghostwhite, darkblue 10%); border-radius: 0.5rem; - *, *::before, *::after { + *, + *::before, + *::after { box-sizing: border-box; margin: 0; padding: 0; @@ -93,7 +95,8 @@ outline-offset: var(--length-s); } - input, button { + input, + button { appearance: none; font: inherit; font-weight: bold; @@ -113,7 +116,9 @@ field-sizing: content; font-variant-numeric: tabular-nums; - &, &:hover, &:focus { + &, + &:hover, + &:focus { border: none; } } From 3c47a76f2ff497c7797a6ffa8d70b2cdb448e6c3 Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Wed, 10 Sep 2025 16:59:55 +0000 Subject: [PATCH 11/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- .../coverage-and-quality-report.md | 81 ++++++++++++++----- ARIA/apg/index/index.md | 9 +++ .../examples/datepicker-spinbuttons.md | 13 ++- .../examples/quantity-spinbutton.md | 38 +++++++-- .../coverage-and-quality/prop-coverage.csv | 6 +- .../examples/css/quantity-spinbutton.css | 26 +++++- .../examples/js/quantity-spinbutton.js | 55 ++++++++++--- 7 files changed, 179 insertions(+), 49 deletions(-) diff --git a/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md b/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md index 2967c5d59..e1378e739 100644 --- a/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md +++ b/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md @@ -69,7 +69,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    -

    Page last updated: August 12, 2025

    +

    Page last updated: September 9, 2025

    About These Reports

    @@ -108,8 +108,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar');

  • Roles with no Guidance or Examples (28)
  • Roles with at Least One Guidance or Example (12)
  • Roles with More than One Guidance or Example (38)
  • -
  • Properties and States with no Examples (12)
  • -
  • Properties and States with One Examples (8)
  • +
  • Properties and States with no Examples (10)
  • +
  • Properties and States with One Examples (10)
  • Properties and States with More than One Example (28)
  • Example Coding Practices
  • @@ -420,7 +420,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Listbox with Grouped Options
  • Editor Menubar (HC)
  • Color Viewer Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • (Deprecated) Date Picker Spin Button
  • Switch Using HTML Button (HC)
  • File Directory Treeview Using Computed Properties
  • File Directory Treeview Using Declared Properties
  • @@ -680,7 +680,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); Spinbutton Pattern @@ -779,15 +780,13 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    -

    Properties and States with No Guidance or Examples (12)

    +

    Properties and States with No Guidance or Examples (10)

    NOTE: The HC abbreviation means example has High Contrast support.
    • aria-details
    • aria-dropeffect
    • -
    • aria-errormessage
    • aria-flowto
    • aria-grabbed
    • -
    • aria-invalid
    • aria-keyshortcuts
    • aria-multiline
    • aria-placeholder
    • @@ -797,7 +796,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    -

    Properties and States with at Least One Guidance or Example (8)

    +

    Properties and States with at Least One Guidance or Example (10)

    NOTE: The HC abbreviation means example has High Contrast support.
    @@ -833,6 +832,18 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); + + + + + + + + + + @@ -952,6 +963,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Actions Menu Button Using aria-activedescendant (HC)
  • Actions Menu Button Using element.focus() (HC)
  • Navigation Menu Button (HC)
  • +
  • Quantity Spin Button
  • Experimental Tabs with Action Buttons (HC)
  • Tabs with Automatic Activation (HC)
  • Tabs with Manual Activation (HC)
  • @@ -981,6 +993,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Date Picker Dialog (HC)
  • Modal Dialog
  • Infinite Scrolling Feed
  • +
  • Quantity Spin Button
  • Table
  • @@ -991,6 +1004,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); @@ -1055,7 +1069,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • (Deprecated) Date Picker Spin Button
  • +
  • Quantity Spin Button
  • Switch Using HTML Button (HC)
  • Switch Using HTML Checkbox Input (HC)
  • Switch (HC)
  • @@ -1082,7 +1097,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Navigation Menubar (HC)
  • Rating Radio Group (HC)
  • Horizontal Multi-Thumb Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • (Deprecated) Date Picker Spin Button
  • Table
  • Toolbar
  • Treegrid Email Inbox
  • @@ -1122,7 +1137,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • (Deprecated) Date Picker Spin Button
  • Switch Using HTML Button (HC)
  • Experimental Tabs with Action Buttons (HC)
  • Tabs with Automatic Activation (HC)
  • @@ -1275,7 +1290,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • (Deprecated) Date Picker Spin Button
  • +
  • Quantity Spin Button
  • Toolbar
  • @@ -1290,7 +1306,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • (Deprecated) Date Picker Spin Button
  • +
  • Quantity Spin Button
  • Toolbar
  • @@ -1306,7 +1323,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • (Deprecated) Date Picker Spin Button
  • +
  • Quantity Spin Button
  • Toolbar
  • @@ -1319,7 +1337,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Rating Slider (HC)
  • Media Seek Slider (HC)
  • Vertical Temperature Slider (HC)
  • -
  • Date Picker Spin Button
  • +
  • (Deprecated) Date Picker Spin Button
  • Toolbar
  • @@ -1335,7 +1353,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); - + @@ -1347,7 +1365,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); - + @@ -1364,7 +1382,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); - + @@ -2011,7 +2029,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); - + @@ -2023,6 +2041,19 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); + + + + + + + + + + + + + @@ -2509,13 +2540,21 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); - + + + + + + + + + diff --git a/ARIA/apg/index/index.md b/ARIA/apg/index/index.md index 19f5c2bdd..b2d0d71ea 100644 --- a/ARIA/apg/index/index.md +++ b/ARIA/apg/index/index.md @@ -612,6 +612,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Date Picker Dialog (HC)
  • Modal Dialog
  • Infinite Scrolling Feed
  • +
  • Quantity Spin Button
  • Table
  • @@ -627,6 +628,10 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -409,12 +439,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); - - - - - - diff --git a/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv b/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv index 19db885b0..de1cc7fd8 100644 --- a/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv +++ b/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv @@ -9,17 +9,17 @@ "aria-colspan","1","0","Guidance: Defining cell spans using aria-colspan and aria-rowspan" "aria-controls","0","23","Example: Accordion","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Checkbox (Mixed-State)","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Disclosure (Show/Hide) Card","Example: Disclosure (Show/Hide) for Answers to Frequently Asked Questions","Example: Disclosure (Show/Hide) for Image Description","Example: Disclosure Navigation Menu with Top-Level Links","Example: Disclosure Navigation Menu","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Quantity Spin Button","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: Toolbar" "aria-current","0","5","Example: Breadcrumb","Example: Disclosure Navigation Menu with Top-Level Links","Example: Disclosure Navigation Menu","Example: Navigation Menubar","Example: Navigation Treeview" -"aria-describedby","1","6","Guidance: Describing by referencing content with aria-describedby","Example: Alert Dialog","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Table" +"aria-describedby","1","7","Guidance: Describing by referencing content with aria-describedby","Example: Alert Dialog","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Quantity Spin Button","Example: Table" "aria-details","0","0" "aria-disabled","0","4","Example: Alert Dialog","Example: Editor Menubar","Example: Quantity Spin Button","Example: Toolbar" "aria-dropeffect","0","0" -"aria-errormessage","0","0" +"aria-errormessage","0","1","Example: Quantity Spin Button" "aria-expanded","0","23","Example: Accordion","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Disclosure (Show/Hide) Card","Example: Disclosure (Show/Hide) for Answers to Frequently Asked Questions","Example: Disclosure (Show/Hide) for Image Description","Example: Disclosure Navigation Menu with Top-Level Links","Example: Disclosure Navigation Menu","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Editor Menubar","Example: Navigation Menubar","Example: Toolbar","Example: Treegrid Email Inbox","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview" "aria-flowto","0","0" "aria-grabbed","0","0" "aria-haspopup","0","9","Example: Date Picker Combobox","Example: Editable Combobox with Grid Popup","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Editor Menubar","Example: Navigation Menubar","Example: Toolbar" "aria-hidden","0","17","Example: Button (IDL Version)","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Editor Menubar","Example: Horizontal Multi-Thumb Slider","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: (Deprecated) Date Picker Spin Button","Example: Quantity Spin Button","Example: Switch Using HTML Button","Example: Switch Using HTML Checkbox Input","Example: Switch","Example: Sortable Table","Example: Toolbar" -"aria-invalid","0","0" +"aria-invalid","0","1","Example: Quantity Spin Button" "aria-keyshortcuts","0","0" "aria-label","1","18","Guidance: Naming with a String Attribute Via aria-label","Example: Breadcrumb","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Link","Example: Editor Menubar","Example: Navigation Menubar","Example: Rating Radio Group","Example: Horizontal Multi-Thumb Slider","Example: (Deprecated) Date Picker Spin Button","Example: Table","Example: Toolbar","Example: Treegrid Email Inbox","Example: Navigation Treeview" "aria-labelledby","1","41","Guidance: Naming with Referenced Content Via aria-labelledby","Example: Accordion","Example: Alert Dialog","Example: Checkbox (Two State)","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Data Grid","Example: Layout Grid","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Navigation Menubar","Example: Meter","Example: Radio Group Using aria-activedescendant","Example: Rating Radio Group","Example: Radio Group Using Roving tabindex","Example: Color Viewer Slider","Example: Rating Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: (Deprecated) Date Picker Spin Button","Example: Switch Using HTML Button","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: File Directory Treeview Using Computed Properties","Example: File Directory Treeview Using Declared Properties","Example: Navigation Treeview","Example: Complementary Landmark","Example: Form Landmark","Example: Main Landmark","Example: Navigation Landmark","Example: Region Landmark","Example: Search Landmark" diff --git a/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css b/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css index c9af4f4df..f5aa0388e 100644 --- a/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css +++ b/content-assets/wai-aria-practices/patterns/spinbutton/examples/css/quantity-spinbutton.css @@ -65,11 +65,29 @@ .spinner-field { display: flex; flex-direction: column; + align-items: start; gap: 0.5rem; label { font-size: 1.2rem; } + + small { + font-size: 1rem; + } + + [id^="error"] { + color: crimson; + } + + [id^="error"], + &:has([aria-invalid="true"]) [id^="help"] { + display: none; + } + + &:has([aria-invalid="true"]) [id^="error"] { + display: block; + } } .spinner { @@ -95,6 +113,10 @@ outline-offset: var(--length-s); } + &:has([aria-invalid="true"]) { + border-color: crimson; + } + input, button { appearance: none; @@ -111,9 +133,7 @@ [role="spinbutton"] { text-align: center; - min-inline-size: 4ch; - max-inline-size: fit-content; - field-sizing: content; + min-inline-size: 6ch; font-variant-numeric: tabular-nums; &, diff --git a/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js index 85c54354e..23ee0f200 100644 --- a/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js +++ b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js @@ -17,8 +17,12 @@ class SpinButton { this.output = document.querySelector(`output[for="${this.id}"]`); this.timer = null; this.setBounds(); - el.addEventListener('input', () => this.setValue(el.value)); - el.addEventListener('blur', () => this.setValue(el.value, true)); + el.addEventListener('input', () => this.setValue(el.value, true)); + el.addEventListener('blur', () => { + if (el.value === '' && this.hasMin) { + this.setValue(this.min, true); + } + }); el.addEventListener('keydown', (e) => this.handleKey(e)); this.controls.forEach((btn) => btn.addEventListener('click', () => this.handleClick(btn)) @@ -49,12 +53,40 @@ class SpinButton { : Number.MAX_SAFE_INTEGER; } - setValue(raw, onBlur = false) { + isValid(val) { + if (val === '' || val === null) return true; + const numVal = +val; + return !( + (this.hasMin && numVal < this.min) || + (this.hasMax && numVal > this.max) + ); + } + + snapValue(val, currentVal) { + let result = val; + + if (this.hasMin) result = Math.max(result, this.min); + if (this.hasMax) result = Math.min(result, this.max); + if ( + (result < currentVal && val > currentVal) || + (result > currentVal && val < currentVal) + ) { + return currentVal; + } + return result; + } + + setValue(raw, fromInput = false) { let val = typeof raw === 'number' ? raw : this.parseValue(raw); - val = - val === null ? (onBlur && this.hasMin ? this.min : '') : this.clamp(val); + + if (!fromInput) { + const currentVal = +this.el.value || 0; + val = this.snapValue(val, currentVal); + } + this.el.value = val; - this.el.setAttribute('aria-valuenow', val); + this.el.ariaValueNow = val; + this.el.ariaInvalid = !this.isValid(val) ? true : null; this.updateButtonStates(); } @@ -62,12 +94,11 @@ class SpinButton { const val = +this.el.value; this.controls.forEach((btn) => { const op = btn.getAttribute('data-spinbutton-operation'); - btn.setAttribute( - 'aria-disabled', - (op === 'decrement' ? val <= this.min : val >= this.max) - ? 'true' - : 'false' - ); + btn.ariaDisabled = ( + op === 'decrement' ? val <= this.min : val >= this.max + ) + ? true + : null; }); } From 6a5d635f8572d1bd45f49089fe11078e1a110bc3 Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Wed, 10 Sep 2025 19:46:09 +0000 Subject: [PATCH 12/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- .../examples/quantity-spinbutton.md | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md index b34af150a..9d72cc9de 100644 --- a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -12,7 +12,7 @@ permalink: /ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton/ sidebar: true -footer: " " +footer: " " # Context here: https://github.com/w3c/wai-aria-practices/issues/31 type_of_guidance: APG @@ -311,6 +311,26 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); color keywords are used to ensure visibility and sufficient contrast for the spin button’s content and interactive states. +
  • + Each spin button’s minimum and maximum values are conveyed in help + text that is associated with aria-describedby. +
  • +
  • + When a user inputs an invalid value: +
      +
    • + The spin button is visually styled to indicate an error state. +
    • +
    • + aria-invalid="true" is added to the input to inform + assistive technologies of the invalid state. +
    • +
    • + An error message is displayed and associated with + aria-errormessage. +
    • +
    +
  • From fd3fcfcabb63a483aef9348379e23ecb8518b9f9 Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Wed, 10 Sep 2025 20:20:46 +0000 Subject: [PATCH 13/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- .../patterns/spinbutton/examples/js/quantity-spinbutton.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js index 23ee0f200..5a1013d16 100644 --- a/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js +++ b/content-assets/wai-aria-practices/patterns/spinbutton/examples/js/quantity-spinbutton.js @@ -86,7 +86,7 @@ class SpinButton { this.el.value = val; this.el.ariaValueNow = val; - this.el.ariaInvalid = !this.isValid(val) ? true : null; + this.el.ariaInvalid = !this.isValid(val) ? 'true' : null; this.updateButtonStates(); } @@ -97,7 +97,7 @@ class SpinButton { btn.ariaDisabled = ( op === 'decrement' ? val <= this.min : val >= this.max ) - ? true + ? 'true' : null; }); } From 2ad8f86409f4dd46646100981c3430a565673b33 Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Tue, 16 Sep 2025 18:02:32 +0000 Subject: [PATCH 14/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- ARIA/apg/patterns/grid/grid-pattern.md | 2 +- .../examples/quantity-spinbutton.md | 6 +- .../keyboard-interface-practice.md | 68 ++++++++----------- 3 files changed, 33 insertions(+), 43 deletions(-) diff --git a/ARIA/apg/patterns/grid/grid-pattern.md b/ARIA/apg/patterns/grid/grid-pattern.md index c3aecbc38..52b603e28 100644 --- a/ARIA/apg/patterns/grid/grid-pattern.md +++ b/ARIA/apg/patterns/grid/grid-pattern.md @@ -389,7 +389,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); Otherwise, passes the key event to the focused widget.
  • - Left Arrow or Up Arrow: If the cell contains multiple widgets, moves focus to the previous widget inside the cell, optionally wrapping to the last widget if focus is on the first widget. + Left Arrow or Up Arrow: If the cell contains multiple widgets, moves focus to the previous widget inside the cell, optionally wrapping to the first widget if focus is on the last widget. Otherwise, passes the key event to the focused widget.
  • diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md index 9d72cc9de..f43bb0648 100644 --- a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -12,7 +12,7 @@ permalink: /ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton/ sidebar: true -footer: " " +footer: " " # Context here: https://github.com/w3c/wai-aria-practices/issues/31 type_of_guidance: APG @@ -260,14 +260,14 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • The spin button input and its adjacent buttons are visually - presented as a singular form field containing an editable value, an + presented as a single form field containing an editable value, an increment button, and a decrement button.
  • When either the spin button input or its adjacent buttons have received focus, a single visual focus indicator encompasses all - three, reinforcing the relationship between then. + three, reinforcing the relationship between them.
  • For users who have not set a preference for reduced motion, the diff --git a/ARIA/apg/practices/keyboard-interface/keyboard-interface-practice.md b/ARIA/apg/practices/keyboard-interface/keyboard-interface-practice.md index 5dce2e941..9f56f807d 100644 --- a/ARIA/apg/practices/keyboard-interface/keyboard-interface-practice.md +++ b/ARIA/apg/practices/keyboard-interface/keyboard-interface-practice.md @@ -261,10 +261,10 @@ if (enableSidebar) document.body.classList.add('has-sidebar');

    - The HTML tabindex - and SVG2 tabindex + The HTML tabindex + and SVG2 tabindex attributes can be used to add and remove elements from the tab sequence. - The value of tabindex can also influence the order of the tab sequence, although authors are strongly advised not to use tabindex for that purpose. + The value of tabindex can also influence the order of the tab sequence, although authors are strongly advised not to use tabindex for that purpose.

    @@ -279,23 +279,23 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); The most robust method of manipulating the order of the tab sequence while also maintaining alignment with the reading order that is currently available in all browsers is rearranging elements in the DOM.

    -

    The values of the tabindex attribute have the following effects.

    +

    The values of the tabindex attribute have the following effects.

    -
    tabindex is not present or does not have a valid value
    +
    tabindex is not present or does not have a valid value
    The element has its default focus behavior. In HTML, only form controls and anchors with an HREF attribute are included in the tab sequence.
    -
    tabindex="0"
    +
    tabindex="0"
    The element is included in the tab sequence based on its position in the DOM.
    -
    tabindex="-1"
    +
    tabindex="-1"
    The element is not included in the tab sequence but is focusable with element.focus().
    -
    tabindex="X" where X is an integer in the range 1 <= X <= 32767
    +
    tabindex="X" where X is an integer in the range 1 <= X <= 32767
    Authors are strongly advised NOT to use these values. - The element is placed in the tab sequence based on the value of tabindex. - Elements with a tabindex value of 0 and elements that are focusable by default will be in the sequence after elements with a tabindex value of 1 or greater. + The element is placed in the tab sequence based on the value of tabindex. + Elements with a tabindex value of 0 and elements that are focusable by default will be in the sequence after elements with a tabindex value of 1 or greater.
    @@ -334,14 +334,14 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • -

    The following sections explain two strategies for managing focus inside composite elements: creating a roving tabindex and using the aria-activedescendant property.

    +

    The following sections explain two strategies for managing focus inside composite elements: creating a roving tabindex and using the aria-activedescendant property.

    -

    Managing Focus Within Components Using a Roving tabindex

    +

    Managing Focus Within Components Using a Roving tabindex

    - When using roving tabindex to manage focus in a composite UI component, the element that is to be included in the tab sequence has tabindex="0" and all other focusable elements contained in the composite have tabindex="-1". - The algorithm for the roving tabindex strategy is as follows. + When using roving tabindex to manage focus in a composite UI component, the element that is to be included in the tab sequence has tabindex of "0" and all other focusable elements contained in the composite have tabindex of "-1". + The algorithm for the roving tabindex strategy is as follows.

      @@ -362,29 +362,29 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    -

    One benefit of using roving tabindex rather than aria-activedescendant to manage focus is that the user agent will scroll the newly focused element into view.

    +

    One benefit of using roving tabindex rather than aria-activedescendant to manage focus is that the user agent will scroll the newly focused element into view.

    -

    Managing Focus in Composites Using aria-activedescendant

    +

    Managing Focus in Composites Using aria-activedescendant

    - If a component container has an ARIA role that supports the aria-activedescendant property, it is not necessary to manipulate the tabindex attribute and move DOM focus among focusable elements within the container. + If a component container has an ARIA role that supports the aria-activedescendant property, it is not necessary to manipulate the tabindex attribute and move DOM focus among focusable elements within the container. Instead, only the container element needs to be included in the tab sequence. - When the container has DOM focus, the value of aria-activedescendant on the container tells assistive technologies which element is active within the widget. - Assistive technologies will consider the element referred to as active to be the focused element even though DOM focus is on the element that has the aria-activedescendant property. - And, when the value of aria-activedescendant is changed, assistive technologies will receive focus change events equivalent to those received when DOM focus actually moves. + When the container has DOM focus, the value of aria-activedescendant on the container tells assistive technologies which element is active within the widget. + Assistive technologies will consider the element referred to as active to be the focused element even though DOM focus is on the element that has the aria-activedescendant property. + And, when the value of aria-activedescendant is changed, assistive technologies will receive focus change events equivalent to those received when DOM focus actually moves.

    -

    The steps for using the aria-activedescendant method of managing focus are as follows.

    +

    The steps for using the aria-activedescendant method of managing focus are as follows.

    • - When the container element that has a role that supports aria-activedescendant is loaded or created, ensure that: + When the container element that has a role that supports aria-activedescendant is loaded or created, ensure that:
        -
      • The container element is included in the tab sequence as described in Keyboard Navigation Between Components or is a focusable element of a composite that implements a roving tabindex.
      • +
      • The container element is included in the tab sequence as described in Keyboard Navigation Between Components or is a focusable element of a composite that implements a roving tabindex.
      • - It has aria-activedescendant="IDREF" where IDREF is the id of the element within the container that should be identified as active when the widget receives focus. + It has aria-activedescendant="IDREF" where IDREF is the ID of the element within the container that should be identified as active when the widget receives focus. The referenced element needs to meet the DOM relationship requirements described below.
      @@ -393,25 +393,25 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    • When the composite widget contains focus and the user presses a navigation key that moves focus within the widget, such as an arrow key:
        -
      • Change the value of aria-activedescendant on the container to refer to the element that should be reported to assistive technologies as active.
      • +
      • Change the value of aria-activedescendant on the container to refer to the element that should be reported to assistive technologies as active.
      • Move the visual focus indicator and, if necessary, scrolled the active element into view.
    • - If the design calls for a specific element to be focused the next time a user moves focus into the composite with Tab or Shift+Tab, check if aria-activedescendant is referring to that target element when the container loses focus. - If it is not, set aria-activedescendant to refer to the target element. + If the design calls for a specific element to be focused the next time a user moves focus into the composite with Tab or Shift + Tab, check if aria-activedescendant is referring to that target element when the container loses focus. + If it is not, set aria-activedescendant to refer to the target element.

    - The specification for aria-activedescendant places important restrictions on the DOM relationship between the focused element that has the aria-activedescendant attribute and the element referenced as active by the value of the attribute. + The specification for aria-activedescendant places important restrictions on the DOM relationship between the focused element that has the aria-activedescendant attribute and the element referenced as active by the value of the attribute. One of the following three conditions must be met.

    1. The element referenced as active is a DOM descendant of the focused referencing element.
    2. The focused referencing element has a value specified for the aria-owns property that includes the ID of the element referenced as active.
    3. - The focused referencing element has role of combobox, textbox, or searchbox and has aria-controls property referring to an element with a role that supports aria-activedescendant and either: + The focused referencing element has role of combobox, textbox, or searchbox and has aria-controls property referring to an element with a role that supports aria-activedescendant and either:
      1. The element referenced as active is a descendant of the controlled element.
      2. The controlled element has a value specified for the aria-owns property that includes the ID of the element referenced as active.
      3. @@ -419,16 +419,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    - -
    -

    Note

    -

    This guidance focuses specifically on keyboard interaction. However, authors must of course also consider pointer interactions, such as mouse clicks - and touchscreen taps. When a component is clicked/tapped, - authors should take the same steps to set the correct tabindex or aria-activedescendant for the element, - in the same way that they would for keyboard navigation. Otherwise, this could lead to a confusing experience for users that switch between pointer - and keyboard navigation, as it will lead to a mismatch.

    -
    -
    From b521864fdc9ff107db8503ab82adbf582574fa9d Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Tue, 16 Sep 2025 18:03:55 +0000 Subject: [PATCH 15/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md | 4 ++-- _external/aria-practices | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md index f43bb0648..4e2f3f73a 100644 --- a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -286,12 +286,12 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Are labeled with the title attribute, providing a human-friendly representation of the plus and minus characters - for users of voice control and touch screen. The + for users of touch-based and voice-based assistive technologies. The title attribute also presents a tooltip on hover, clarifying the meaning of each button’s icon.
  • - Use an invisible live region to announce the updated value to + Use an invisible live region to announce the updated value when pressed. The live region empties its contents after 3 seconds to avoid leaving stale content in the document.
  • diff --git a/_external/aria-practices b/_external/aria-practices index 2bce4d058..bddd0413e 160000 --- a/_external/aria-practices +++ b/_external/aria-practices @@ -1 +1 @@ -Subproject commit 2bce4d0585e9a950248115ee1e73ffc2f1a79109 +Subproject commit bddd0413e805f818bcca8a97e7ecd3d050ac3a8f From a3286aef8813dfe668105b90373689724d376547 Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Tue, 16 Sep 2025 18:04:37 +0000 Subject: [PATCH 16/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- ARIA/apg/patterns/grid/grid-pattern.md | 2 +- .../examples/quantity-spinbutton.md | 2 +- .../keyboard-interface-practice.md | 68 +++++++++++-------- _external/aria-practices | 2 +- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/ARIA/apg/patterns/grid/grid-pattern.md b/ARIA/apg/patterns/grid/grid-pattern.md index 52b603e28..c3aecbc38 100644 --- a/ARIA/apg/patterns/grid/grid-pattern.md +++ b/ARIA/apg/patterns/grid/grid-pattern.md @@ -389,7 +389,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); Otherwise, passes the key event to the focused widget.
  • - Left Arrow or Up Arrow: If the cell contains multiple widgets, moves focus to the previous widget inside the cell, optionally wrapping to the first widget if focus is on the last widget. + Left Arrow or Up Arrow: If the cell contains multiple widgets, moves focus to the previous widget inside the cell, optionally wrapping to the last widget if focus is on the first widget. Otherwise, passes the key event to the focused widget.
  • diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md index 4e2f3f73a..06de32d61 100644 --- a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -327,7 +327,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • An error message is displayed and associated with - aria-errormessage. + the input using aria-errormessage.
  • diff --git a/ARIA/apg/practices/keyboard-interface/keyboard-interface-practice.md b/ARIA/apg/practices/keyboard-interface/keyboard-interface-practice.md index 9f56f807d..5dce2e941 100644 --- a/ARIA/apg/practices/keyboard-interface/keyboard-interface-practice.md +++ b/ARIA/apg/practices/keyboard-interface/keyboard-interface-practice.md @@ -261,10 +261,10 @@ if (enableSidebar) document.body.classList.add('has-sidebar');

    - The HTML tabindex - and SVG2 tabindex + The HTML tabindex + and SVG2 tabindex attributes can be used to add and remove elements from the tab sequence. - The value of tabindex can also influence the order of the tab sequence, although authors are strongly advised not to use tabindex for that purpose. + The value of tabindex can also influence the order of the tab sequence, although authors are strongly advised not to use tabindex for that purpose.

    @@ -279,23 +279,23 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); The most robust method of manipulating the order of the tab sequence while also maintaining alignment with the reading order that is currently available in all browsers is rearranging elements in the DOM.

    -

    The values of the tabindex attribute have the following effects.

    +

    The values of the tabindex attribute have the following effects.

    -
    tabindex is not present or does not have a valid value
    +
    tabindex is not present or does not have a valid value
    The element has its default focus behavior. In HTML, only form controls and anchors with an HREF attribute are included in the tab sequence.
    -
    tabindex="0"
    +
    tabindex="0"
    The element is included in the tab sequence based on its position in the DOM.
    -
    tabindex="-1"
    +
    tabindex="-1"
    The element is not included in the tab sequence but is focusable with element.focus().
    -
    tabindex="X" where X is an integer in the range 1 <= X <= 32767
    +
    tabindex="X" where X is an integer in the range 1 <= X <= 32767
    Authors are strongly advised NOT to use these values. - The element is placed in the tab sequence based on the value of tabindex. - Elements with a tabindex value of 0 and elements that are focusable by default will be in the sequence after elements with a tabindex value of 1 or greater. + The element is placed in the tab sequence based on the value of tabindex. + Elements with a tabindex value of 0 and elements that are focusable by default will be in the sequence after elements with a tabindex value of 1 or greater.
    @@ -334,14 +334,14 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); -

    The following sections explain two strategies for managing focus inside composite elements: creating a roving tabindex and using the aria-activedescendant property.

    +

    The following sections explain two strategies for managing focus inside composite elements: creating a roving tabindex and using the aria-activedescendant property.

    -

    Managing Focus Within Components Using a Roving tabindex

    +

    Managing Focus Within Components Using a Roving tabindex

    - When using roving tabindex to manage focus in a composite UI component, the element that is to be included in the tab sequence has tabindex of "0" and all other focusable elements contained in the composite have tabindex of "-1". - The algorithm for the roving tabindex strategy is as follows. + When using roving tabindex to manage focus in a composite UI component, the element that is to be included in the tab sequence has tabindex="0" and all other focusable elements contained in the composite have tabindex="-1". + The algorithm for the roving tabindex strategy is as follows.

      @@ -362,29 +362,29 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    -

    One benefit of using roving tabindex rather than aria-activedescendant to manage focus is that the user agent will scroll the newly focused element into view.

    +

    One benefit of using roving tabindex rather than aria-activedescendant to manage focus is that the user agent will scroll the newly focused element into view.

    -

    Managing Focus in Composites Using aria-activedescendant

    +

    Managing Focus in Composites Using aria-activedescendant

    - If a component container has an ARIA role that supports the aria-activedescendant property, it is not necessary to manipulate the tabindex attribute and move DOM focus among focusable elements within the container. + If a component container has an ARIA role that supports the aria-activedescendant property, it is not necessary to manipulate the tabindex attribute and move DOM focus among focusable elements within the container. Instead, only the container element needs to be included in the tab sequence. - When the container has DOM focus, the value of aria-activedescendant on the container tells assistive technologies which element is active within the widget. - Assistive technologies will consider the element referred to as active to be the focused element even though DOM focus is on the element that has the aria-activedescendant property. - And, when the value of aria-activedescendant is changed, assistive technologies will receive focus change events equivalent to those received when DOM focus actually moves. + When the container has DOM focus, the value of aria-activedescendant on the container tells assistive technologies which element is active within the widget. + Assistive technologies will consider the element referred to as active to be the focused element even though DOM focus is on the element that has the aria-activedescendant property. + And, when the value of aria-activedescendant is changed, assistive technologies will receive focus change events equivalent to those received when DOM focus actually moves.

    -

    The steps for using the aria-activedescendant method of managing focus are as follows.

    +

    The steps for using the aria-activedescendant method of managing focus are as follows.

    • - When the container element that has a role that supports aria-activedescendant is loaded or created, ensure that: + When the container element that has a role that supports aria-activedescendant is loaded or created, ensure that:
        -
      • The container element is included in the tab sequence as described in Keyboard Navigation Between Components or is a focusable element of a composite that implements a roving tabindex.
      • +
      • The container element is included in the tab sequence as described in Keyboard Navigation Between Components or is a focusable element of a composite that implements a roving tabindex.
      • - It has aria-activedescendant="IDREF" where IDREF is the ID of the element within the container that should be identified as active when the widget receives focus. + It has aria-activedescendant="IDREF" where IDREF is the id of the element within the container that should be identified as active when the widget receives focus. The referenced element needs to meet the DOM relationship requirements described below.
      @@ -393,25 +393,25 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    • When the composite widget contains focus and the user presses a navigation key that moves focus within the widget, such as an arrow key:
        -
      • Change the value of aria-activedescendant on the container to refer to the element that should be reported to assistive technologies as active.
      • +
      • Change the value of aria-activedescendant on the container to refer to the element that should be reported to assistive technologies as active.
      • Move the visual focus indicator and, if necessary, scrolled the active element into view.
    • - If the design calls for a specific element to be focused the next time a user moves focus into the composite with Tab or Shift + Tab, check if aria-activedescendant is referring to that target element when the container loses focus. - If it is not, set aria-activedescendant to refer to the target element. + If the design calls for a specific element to be focused the next time a user moves focus into the composite with Tab or Shift+Tab, check if aria-activedescendant is referring to that target element when the container loses focus. + If it is not, set aria-activedescendant to refer to the target element.

    - The specification for aria-activedescendant places important restrictions on the DOM relationship between the focused element that has the aria-activedescendant attribute and the element referenced as active by the value of the attribute. + The specification for aria-activedescendant places important restrictions on the DOM relationship between the focused element that has the aria-activedescendant attribute and the element referenced as active by the value of the attribute. One of the following three conditions must be met.

    1. The element referenced as active is a DOM descendant of the focused referencing element.
    2. The focused referencing element has a value specified for the aria-owns property that includes the ID of the element referenced as active.
    3. - The focused referencing element has role of combobox, textbox, or searchbox and has aria-controls property referring to an element with a role that supports aria-activedescendant and either: + The focused referencing element has role of combobox, textbox, or searchbox and has aria-controls property referring to an element with a role that supports aria-activedescendant and either:
      1. The element referenced as active is a descendant of the controlled element.
      2. The controlled element has a value specified for the aria-owns property that includes the ID of the element referenced as active.
      3. @@ -419,6 +419,16 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    + +
    +

    Note

    +

    This guidance focuses specifically on keyboard interaction. However, authors must of course also consider pointer interactions, such as mouse clicks + and touchscreen taps. When a component is clicked/tapped, + authors should take the same steps to set the correct tabindex or aria-activedescendant for the element, + in the same way that they would for keyboard navigation. Otherwise, this could lead to a confusing experience for users that switch between pointer + and keyboard navigation, as it will lead to a mismatch.

    +
    +
    diff --git a/_external/aria-practices b/_external/aria-practices index bddd0413e..397b14df3 160000 --- a/_external/aria-practices +++ b/_external/aria-practices @@ -1 +1 @@ -Subproject commit bddd0413e805f818bcca8a97e7ecd3d050ac3a8f +Subproject commit 397b14df3e54f463be3bbdfb9aa1e76e8d7f4283 From 9fd1f8eb91d080b24d3c2c41daf58a376b13676e Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Tue, 16 Sep 2025 18:07:45 +0000 Subject: [PATCH 17/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- .../about/coverage-and-quality/coverage-and-quality-report.md | 3 ++- _external/aria-practices | 2 +- .../about/coverage-and-quality/role-coverage.csv | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md b/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md index e1378e739..99c4c6d6c 100644 --- a/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md +++ b/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md @@ -69,7 +69,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    -

    Page last updated: September 9, 2025

    +

    Page last updated: September 16, 2025

    About These Reports

    @@ -575,6 +575,7 @@ if (enableSidebar) document.body.classList.add('has-sidebar');

  • Note
  • Note
  • Note
  • +
  • Note
  • Note
  • diff --git a/_external/aria-practices b/_external/aria-practices index 397b14df3..a90d84860 160000 --- a/_external/aria-practices +++ b/_external/aria-practices @@ -1 +1 @@ -Subproject commit 397b14df3e54f463be3bbdfb9aa1e76e8d7f4283 +Subproject commit a90d84860aca691b6120cd964b31ed189f73e692 diff --git a/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv b/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv index 8b06bb226..c9c7ed7d2 100644 --- a/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv +++ b/content-assets/wai-aria-practices/about/coverage-and-quality/role-coverage.csv @@ -46,7 +46,7 @@ "meter","2","1","Guidance: Meter Pattern","Guidance: Range properties with meter","Example: Meter" "navigation","5","3","Guidance: Fundamental Keyboard Navigation Conventions","Guidance: Keyboard Navigation Between Components (The Tab Sequence)","Guidance: Keyboard Navigation Inside Components","Guidance: Ensure Basic Access Via Navigation","Guidance: Navigation","Example: Navigation Menubar","Example: Navigation Treeview","Example: Navigation Landmark" "none","0","7","Example: Navigation Menu Button","Example: Navigation Menubar","Example: Rating Radio Group","Example: Horizontal Multi-Thumb Slider","Example: Media Seek Slider","Example: Vertical Temperature Slider","Example: Navigation Treeview" -"note","37","0","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note" +"note","38","0","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note","Guidance: Note" "option","0","8","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Select-Only Combobox","Example: (Deprecated) Collapsible Dropdown Listbox","Example: Listbox with Grouped Options","Example: Listboxes with Rearrangeable Options","Example: Scrollable Listbox" "paragraph","0","0" "presentation","5","0","Guidance: Hiding Semantics with the presentation Role","Guidance: Common Uses of Role presentation","Guidance: Effects of Role presentation","Guidance: Conditions That Cause Role presentation to be Ignored","Guidance: Example Demonstrating Effects of the presentation Role" From ae398808bc03e0c3bfb9907e039d165ecf82a874 Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Tue, 16 Sep 2025 19:46:57 +0000 Subject: [PATCH 18/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- .../coverage-and-quality-report.md | 5 ++--- ARIA/apg/index/index.md | 1 - .../examples/quantity-spinbutton.md | 21 +++++++++---------- _external/aria-practices | 2 +- .../coverage-and-quality/prop-coverage.csv | 2 +- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md b/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md index 99c4c6d6c..2f77fff56 100644 --- a/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md +++ b/ARIA/apg/about/coverage-and-quality/coverage-and-quality-report.md @@ -994,7 +994,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Date Picker Dialog (HC)
  • Modal Dialog
  • Infinite Scrolling Feed
  • -
  • Quantity Spin Button
  • Table
  • @@ -2051,8 +2050,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    - - + + diff --git a/ARIA/apg/index/index.md b/ARIA/apg/index/index.md index b2d0d71ea..d24e8f300 100644 --- a/ARIA/apg/index/index.md +++ b/ARIA/apg/index/index.md @@ -612,7 +612,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • Date Picker Dialog (HC)
  • Modal Dialog
  • Infinite Scrolling Feed
  • -
  • Quantity Spin Button
  • Table
  • diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md index 06de32d61..f89f9570e 100644 --- a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -132,7 +132,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • - Each spin button’s minimum and maximum values are conveyed in help - text that is associated with aria-describedby. + Each spin button’s minimum and maximum values are programmatically + defined with aria-valuemin and + aria-valuemax, enabling assistive technologies to + convey that information to users in a predictable manner. +
  • +
  • + The minimum and maximum values are also visually expressed with + adjacent help text, but is purposefully not associated using + aria-describedby since the same information is already + programmatically defined.
  • When a user inputs an invalid value: @@ -415,12 +420,6 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
  • - - - - - - diff --git a/_external/aria-practices b/_external/aria-practices index a90d84860..a6afbd398 160000 --- a/_external/aria-practices +++ b/_external/aria-practices @@ -1 +1 @@ -Subproject commit a90d84860aca691b6120cd964b31ed189f73e692 +Subproject commit a6afbd3987328ab83ea2f98c2b3badbd9b2379c8 diff --git a/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv b/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv index de1cc7fd8..64f66b6c9 100644 --- a/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv +++ b/content-assets/wai-aria-practices/about/coverage-and-quality/prop-coverage.csv @@ -9,7 +9,7 @@ "aria-colspan","1","0","Guidance: Defining cell spans using aria-colspan and aria-rowspan" "aria-controls","0","23","Example: Accordion","Example: Auto-Rotating Image Carousel with Buttons for Slide Control","Example: Auto-Rotating Image Carousel with Tabs for Slide Control","Example: Checkbox (Mixed-State)","Example: Editable Combobox With Both List and Inline Autocomplete","Example: Editable Combobox With List Autocomplete","Example: Editable Combobox without Autocomplete","Example: Date Picker Combobox","Example: Select-Only Combobox","Example: Editable Combobox with Grid Popup","Example: Disclosure (Show/Hide) Card","Example: Disclosure (Show/Hide) for Answers to Frequently Asked Questions","Example: Disclosure (Show/Hide) for Image Description","Example: Disclosure Navigation Menu with Top-Level Links","Example: Disclosure Navigation Menu","Example: Actions Menu Button Using aria-activedescendant","Example: Actions Menu Button Using element.focus()","Example: Navigation Menu Button","Example: Quantity Spin Button","Example: Experimental Tabs with Action Buttons","Example: Tabs with Automatic Activation","Example: Tabs with Manual Activation","Example: Toolbar" "aria-current","0","5","Example: Breadcrumb","Example: Disclosure Navigation Menu with Top-Level Links","Example: Disclosure Navigation Menu","Example: Navigation Menubar","Example: Navigation Treeview" -"aria-describedby","1","7","Guidance: Describing by referencing content with aria-describedby","Example: Alert Dialog","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Quantity Spin Button","Example: Table" +"aria-describedby","1","6","Guidance: Describing by referencing content with aria-describedby","Example: Alert Dialog","Example: Date Picker Combobox","Example: Date Picker Dialog","Example: Modal Dialog","Example: Infinite Scrolling Feed","Example: Table" "aria-details","0","0" "aria-disabled","0","4","Example: Alert Dialog","Example: Editor Menubar","Example: Quantity Spin Button","Example: Toolbar" "aria-dropeffect","0","0" From a7f2e9b3f1531bba1b86d2bf535ff6adbf2b149a Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Wed, 17 Sep 2025 15:29:52 +0000 Subject: [PATCH 19/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- _external/aria-practices | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_external/aria-practices b/_external/aria-practices index a6afbd398..aa25a2aa2 160000 --- a/_external/aria-practices +++ b/_external/aria-practices @@ -1 +1 @@ -Subproject commit a6afbd3987328ab83ea2f98c2b3badbd9b2379c8 +Subproject commit aa25a2aa2cdd19d4c4c7257b55e5af65dd5a3427 From c391b724c177efcc5814e9addb057492b24a6ed3 Mon Sep 17 00:00:00 2001 From: w3cgruntbot Date: Thu, 18 Sep 2025 01:20:55 +0000 Subject: [PATCH 20/20] chore: Update branch with latest `spinbutton-redesign` changes and submodule updates --- _external/aria-practices | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_external/aria-practices b/_external/aria-practices index aa25a2aa2..67f73a138 160000 --- a/_external/aria-practices +++ b/_external/aria-practices @@ -1 +1 @@ -Subproject commit aa25a2aa2cdd19d4c4c7257b55e5af65dd5a3427 +Subproject commit 67f73a138e9a9f5fedcf2e6d99ebcfe4f814e561
    aria-errormessageQuantity Spin Button +
    aria-invalidQuantity Spin Button +
    aria-multiselectable
    Total Examples6263
    High Contrast Documentation
    Uses forced-colors media query34
    Uses currentColor value
    Use Class3738
    Use Prototype
    Date Picker Spin Button(Deprecated) Date Picker Spin Button prototype Yes 7
    Quantity Spin Buttonclassexample1199
    Switch Using HTML Button classYes
    Date Picker Spin Button(Deprecated) Date Picker Spin Button Yes Yes
    Quantity Spin ButtonYes
    Switch Using HTML Button Yes
    aria-errormessageQuantity Spin Button
    aria-expanded @@ -697,6 +702,10 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    aria-invalidQuantity Spin Button
    aria-label diff --git a/ARIA/apg/patterns/spinbutton/examples/datepicker-spinbuttons.md b/ARIA/apg/patterns/spinbutton/examples/datepicker-spinbuttons.md index 9b3ddc07b..9cf5a7d65 100644 --- a/ARIA/apg/patterns/spinbutton/examples/datepicker-spinbuttons.md +++ b/ARIA/apg/patterns/spinbutton/examples/datepicker-spinbuttons.md @@ -1,6 +1,6 @@ --- # This file was generated by scripts/pre-build/library/formatForJekyll.js -title: "Date Picker Spin Button Example" +title: "(Deprecated) Date Picker Spin Button Example" ref: /ARIA/apg/patterns/spinbutton/examples/datepicker-spinbuttons/ github: @@ -12,7 +12,7 @@ permalink: /ARIA/apg/patterns/spinbutton/examples/datepicker-spinbuttons/ sidebar: true -footer: " " +footer: " " # Context here: https://github.com/w3c/wai-aria-practices/issues/31 type_of_guidance: APG @@ -21,7 +21,7 @@ lang: en --- -Date Picker Spin Button Example +(Deprecated) Date Picker Spin Button Example @@ -99,6 +99,13 @@ if (enableSidebar) document.body.classList.add('has-sidebar');

    About This Example

    +
    +

    Deprecation Warning

    +

    + This pattern has been deprecated, and will be removed in a future version of the ARIA Authoring Practices. + The Quantity Spin Button should be used as an alternative to this pattern. +

    +

    The following example uses the Spin Button Pattern to implement a date picker. diff --git a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md index b45344289..b34af150a 100644 --- a/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md +++ b/ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton.md @@ -12,7 +12,7 @@ permalink: /ARIA/apg/patterns/spinbutton/examples/quantity-spinbutton/ sidebar: true -footer: "

    " +footer: " " # Context here: https://github.com/w3c/wai-aria-practices/issues/31 type_of_guidance: APG @@ -132,6 +132,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); + + Must be between 1 and 8 + 1 to 8 @@ -170,6 +174,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); + + Must be between 0 and 8 + 0 to 8 @@ -208,6 +216,8 @@ if (enableSidebar) document.body.classList.add('has-sidebar'); + + Must be between 0 and 12 + 0 to 12 @@ -383,6 +395,24 @@ if (enableSidebar) document.body.classList.add('has-sidebar');
    input[type="text"] Indicates the maximum allowed value for the spin button.
    aria-describedby="ID_REF"input[type="text"]Identifies the element that provides help text for the spin button.
    aria-invalid="true"input[type="text"]Indicates that the current value is invalid.
    aria-errormessage="ID_REF"input[type="text"]Identifies the element that provides an error message for the spin button.
    title="NAME_STRING"button Set when the minimum or maximum value has been reached to inform assistive technologies that the button has been disabled.
    aria-disabled="false"buttonSet when the value is greater than the minimum value or lesser than the maximum value.
    aria-hidden="true"example 1 19988
    input[type="text"] Indicates the maximum allowed value for the spin button.
    aria-describedby="ID_REF"input[type="text"]Identifies the element that provides help text for the spin button.
    aria-invalid="true"