# # ARIA

This section mainly includes how to quickly use the built-in features of the UIExtension framework to achieve accessibility, as well as the introduction of the related tools. If you want to learn more about ARIA's technical specifications and best practices, you can refer to the following addresses:

- https://www.w3.org/WAI/standards-guidelines/aria/
  (opens new window)
- https://www.w3.org/TR/wai-aria-practices-1.1/
  (opens new window)
- https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA
  (opens new window)

## # How to use UIExtension to enable accessibility

When initializing PDFUI, we need to load the `aria` add-on:

    new UIExtension.PDFUI({
        addons: [
            // .... other Add-on
            'path/to/lib/uix-addons/aria/addon.info.json' // Make sure that aria is loaded last.
        ]
        // ... other options
    })

If the plugins in your app are loaded via allInOne.js, it has already contained `aria`, then you don't need to load it additionally:

    new UIExtension.PDFUI({
        addons: 'path/to/lib/uix-addons/allInOne.js'
        // ... other options
    })

For more information about how to load add-on, you can refer to Here.

## # The built-in components in UIExtension

### # `aria-label` attribute

After specifying the `text` or `label` parameter for the built-in components, the `aria-label` attribute will be added to the generated DOM node automatically. You can click `run` button to run the demo, and then use a screen reader to see the effect:

    <html>
        <template id="layout-template">
            <webpdf>
                <div>
                    <div>
                        <gtab text="XButton" group="aria-tab" body="tab1-body" active></gtab>
                        <gtab text="Dropdown" group="aria-tab" body="tab2-body"></gtab>
                        <gtab text="Slider" group="aria-tab" body="tab3-body"></gtab>
                        <gtab text="Ribbon button" group="aria-tab" body="tab4-body"></gtab>
                    </div>
                    <div name="tab1-body">
                        <xbutton text="button"></xbutton>
                    </div>
                    <div name="tab2-body">
                        <dropdown text="Dropdown" style="width: 8em" separate="false">
                            <xbutton text="Dropdown item 1"></xbutton>
                            <xbutton text="Dropdown item 2"></xbutton>
                        </dropdown>
                    </div>
                    <div name="tab3-body">
                        <slider min="0" max="100" step="1" label="Slider label"></slider>
                    </div>
                    <div name="tab4-body">
                        <ribbon-button text="Ribbon button"></ribbon-button>
                    </div>
                </div>
                <div class="fv__ui-body">
                    <viewer></viewer>
                </div>
            </webpdf>
        </template>
    </html>
    <script>
        var CustomAppearance = UIExtension.appearances.Appearance.extend({
            getLayoutTemplate: function() {
                return document.getElementById('layout-template').innerHTML;
            },
            disableAll: function(){}
        });
        var libPath = window.top.location.origin + '/lib';
        var pdfui = new UIExtension.PDFUI({
            viewerOptions: {
                libPath: libPath,
                jr: {
                    licenseSN: licenseSN,
                    licenseKey: licenseKey
                }
            },
            renderTo: document.body,
            appearance: CustomAppearance,
            addons: libPath + '/uix-addons/allInOne.js'
        });
    </script>

    {
        "iframeOptions": {
            "style": "height: 300px"
        }
    }

## # Visually hidden content

In some scenarios, we need to provide content which should be visually hidden, but remain accessible to assistive technologies such as screen readers, the content can be styled using the `.fv__ui-aria-sr-only` class. This can provide useful information or cues for visually impaired users, for example, sometimes we can use different colors to indicate different types of information, such as dangers and warnings, in that case we need to add additional text content to inform visually impaired users of what type of the information.

    <p class="text-danger">
        <span class="fv__ui-aria-sr-only">Danger:</span>
        This action is not reversible.
    </p>

## # aria directive

### # `@aria:attr` directive

This directive is used to set the attribute which is at the beginning of `aria-`. The directive is written as `@aria:attr.${aria-property-name}`. `aria-property-name` can be referred to Here
(opens new window), the value of the parameter is an executable expression:

    <html>
        <template id="layout-template">
            <webpdf>
                <div @var.value="50">
                    <input @aria:attr.valuemax="1" @aria:attr.valuemin="0" @aria:attr.valuenow="value + '%'">
                    <!--Result:
                        <input aria-valuemax="1" aria-valuemin="0" aria-valuenow="50%" ...>
                    -->

                    <!-- source text -->
                    <input @aria:attr.label="'source text'">
                    <!--Result:
                        <input aria-label="source text" ...>
                    -->

                    <!-- I18n key -->
                    <input @aria:attr.label="'aria:labels.gotopage'|i18n">
                    <!--Result:
                        <input aria-label="Set page" ...>
                    -->
                </div>
                <div class="fv__ui-body">
                    <viewer></viewer>
                </div>
            </webpdf>
        </template>
    </html>
    <script>
        var CustomAppearance = UIExtension.appearances.Appearance.extend({
            getLayoutTemplate: function() {
                return document.getElementById('layout-template').innerHTML;
            },
            disableAll: function(){}
        });
        var libPath = window.top.location.origin + '/lib';
        var pdfui = new UIExtension.PDFUI({
            viewerOptions: {
                libPath: libPath,
                jr: {
                    licenseSN: licenseSN,
                    licenseKey: licenseKey
                }
            },
            renderTo: document.body,
            appearance: CustomAppearance,
            addons: libPath + '/uix-addons/allInOne.js'
        });
    </script>

    {
        "iframeOptions": {
            "style": "height: 300px"
        }
    }

### # `@aria:label` directive

This directive is used to set the `aria-label`
(opens new window) attribute, and the directive value is i18n entry.

    <html>
        <template id="layout-template">
            <webpdf>
                <div>
                    <group-list>
                        <group>
                            <input @aria:label="aria:labels.gotopage" placeholder="@aria:label=&quot;aria:labels.gotopage&quot;">
                            <!--Result:
                                <input aria-label="Set page" ...>
                            -->

                            <!-- It is equivalent to: -->
                            <input @aria:attr.label="'aria:labels.gotopage'|i18n" placeholder="@aria:attr.label=&quot;'aria:labels.gotopage'|i18n&quot;">
                            <!--Result:
                                <input aria-label="Set page" ...>
                            -->

                            <!-- source text -->
                            <input @aria:label="source text" placeholder="@aria:label=&quot;source text&quot;">
                            <!--Result:
                                <input aria-label="source text" ...>
                            -->
                            <!-- It is equivalent to: -->
                            <input @aria:attr.label="'source text'" placeholder="@aria:attr.label=&quot;'source text'&quot;">
                            <!--Result:
                                <input aria-label="source text" ...>
                            -->
                        </group>
                    </group-list>
                    <group-list>
                        <group>
                            <!-- It can set attributes at a location specified by the dropdown component -->
                            <!-- Set aria-label on the drop-down arrow -->
                            <dropdown @aria:label.caret="Toggle Dropdown" text="@aria:label.caret"></dropdown>
                        </group>
                        <group>
                            <!-- Set aria-label on icons -->
                            <dropdown icon-class="fv__icon-toolbar-hand" @aria:label.icon="Click dropdown icon" text="@aria:label.icon"></dropdown>
                        </group>
                        <group>
                            <!-- Set aria-label on the input box -->
                            <dropdown
                                editable
                                @aria:label.editor="Click dropdown icon"
                                selected="1"
                                text="@aria:label.editor"
                            >
                                <dropdown-item>Item 2</dropdown-item>
                                <dropdown-item>Item 3</dropdown-item>
                                <dropdown-item>Item 1</dropdown-item>
                            </dropdown>
                        </group>
                        <group>
                            <!-- Set the aria-label of the list -->
                            <dropdown @aria:label.list="Items" text="@aria:label.list" separate="false">
                                <dropdown-item>Item 1</dropdown-item>
                                <dropdown-item>Item 2</dropdown-item>
                                <dropdown-item>Item 3</dropdown-item>
                            </dropdown>
                        </group>
                    </group-list>
                </div>
                <div class="fv__ui-body">
                    <viewer></viewer>
                </div>
            </webpdf>
        </template>
    </html>
    <script>
        var CustomAppearance = UIExtension.appearances.Appearance.extend({
            getLayoutTemplate: function() {
                return document.getElementById('layout-template').innerHTML;
            },
            disableAll: function(){}
        });
        var libPath = window.top.location.origin + '/lib';
        var pdfui = new UIExtension.PDFUI({
            viewerOptions: {
                libPath: libPath,
                jr: {
                    licenseSN: licenseSN,
                    licenseKey: licenseKey
                }
            },
            renderTo: document.body,
            appearance: CustomAppearance,
            addons: libPath + '/uix-addons/allInOne.js'
        });
    </script>
    <style>
        input {
            width: 20em;
        }
        .fv__ui-dropdown {
            width: auto;
        }
    </style>

    {
        "iframeOptions": {
            "style": "height: 300px"
        }
    }

### # `@aria:labelledby` directive

`@aria:labelledby` directive is used to generate the `aria-labelledby` attribute. The directive value is using the selector syntax of UIExtension rather than the element's id. This is because the `aria-labelledby` attribute needs to be associated with another element via id, and id may cause global conflicts, so handwriting id to index elements is not recommended. The selector syntax of this directive can avoid this problem.

For more information about the `aria-labelledby` attribute, please refer to Here
(opens new window).

    <html>
        <template id="layout-template">
            <webpdf>
                <div>
                    <span>Field</span>
                    <!-- This is just for demonstration -->
                    <span name="a-colon">:</span>
                    <input type="text" @aria:labelledby="::parent()::childAt(0),a-colon">
                </div>
                <div class="fv__ui-body">
                    <viewer></viewer>
                </div>
            </webpdf>
        </template>
    </html>
    <script>
        var CustomAppearance = UIExtension.appearances.Appearance.extend({
            getLayoutTemplate: function() {
                return document.getElementById('layout-template').innerHTML;
            },
            disableAll: function(){}
        });
        var libPath = window.top.location.origin + '/lib';
        var pdfui = new UIExtension.PDFUI({
            viewerOptions: {
                libPath: libPath,
                jr: {
                    licenseSN: licenseSN,
                    licenseKey: licenseKey
                }
            },
            renderTo: document.body,
            appearance: CustomAppearance,
            addons: libPath + '/uix-addons/allInOne.js'
        });
    </script>
    <style>
        input {
            width: 20em;
        }
        .fv__ui-dropdown {
            width: auto;
        }
    </style>

    {
        "iframeOptions": {
            "style": "height: 300px"
        }
    }

In the above example, `@aria:labelledby="::parent()::childAt(0),,a-colon"` specifies the id of the two span components before `<input>` as label. For more information about the selector syntax, please refer to Here.

### # `@aria:describedby` directive

The usage and principle of the `@aria:describedby` directive are basically the same as `@aria:labelledby`, so we will not repeat it here.

For more information about `aria-describedby`, please refer to Here
(opens new window).

    <html>
        <template id="layout-template">
            <webpdf>
                <div>
                    <span>Field:</span>
                    <input type="text" @aria:labelledby="::parent()::childAt(0)" @aria:describedby="::nextSiblings(),more-description">
                    <span class="fv__ui-aria-sr-only">
                        Description of text input.
                    </span>
                    <span class="fv__ui-aria-sr-only" name="more-description">
                        More description of text input.
                    </span>
                </div>
                <div class="fv__ui-body">
                    <viewer></viewer>
                </div>
            </webpdf>
        </template>
    </html>
    <script>
        var CustomAppearance = UIExtension.appearances.Appearance.extend({
            getLayoutTemplate: function() {
                return document.getElementById('layout-template').innerHTML;
            },
            disableAll: function(){}
        });
        var libPath = window.top.location.origin + '/lib';
        var pdfui = new UIExtension.PDFUI({
            viewerOptions: {
                libPath: libPath,
                jr: {
                    licenseSN: licenseSN,
                    licenseKey: licenseKey
                }
            },
            renderTo: document.body,
            appearance: CustomAppearance,
            addons: libPath + '/uix-addons/allInOne.js'
        });
    </script>
    <style>
        input {
            width: 20em;
        }
        .fv__ui-dropdown {
            width: auto;
        }
    </style>

    {
        "iframeOptions": {
            "style": "height: 300px"
        }
    }

### # `@aria:rel` directive

In ARIA specification, in addition to `aria-labelledby` and `aria-describedby`, there are also many attributes that need to be associated with other elements. `@aria:rel` directive encapsulates these commonly used attributes:

- `aria-activedescendant`
  (opens new window), this directive is written as: `aria:rel.activedescendant="selecor,..."`
- `aria-flowto`
  (opens new window), this directive is written as: `aria:rel.flowto="selecor,..."`
- `aria-owns`
  (opens new window), this directive is written as: `aria:rel.owns="selecor,..."`
- `aria-controls`
  (opens new window), this directive is written as: `aria:rel.controls="selecor,..."`

### # `@aria:circular-focus` directive

This directive is used to control the focus of elements within the components and implement the loop jump function. It is typically used for pop-ups, or a separate UI area.

Refer to the following example and click `run` button to run it.

    <html>
        <template id="layout-template">
            <webpdf>
                <div>
                    <group-list>
                        <group>
                            <xbutton>button 1</xbutton>
                            <xbutton>button 2</xbutton>
                            <xbutton>button 3</xbutton>
                        </group>
                        <group @aria:circular-focus>
                            <xbutton @tooltip tooltip-title="Press 'Shift + Tab' will switch focus to 'button 6' instead of 'button 3'">button 4</xbutton>
                            <xbutton>button 5</xbutton>
                            <xbutton @tooltip tooltip-title="Press 'Tab' will switch focus to 'button 4' instead of 'button 7'">button 6</xbutton>
                        </group>
                        <group>
                            <xbutton>button 7</xbutton>
                        </group>
                    </group-list>
                </div>
                <div class="fv__ui-body">
                    <viewer></viewer>
                </div>
            </webpdf>
        </template>
    </html>
    <script>
        var CustomAppearance = UIExtension.appearances.Appearance.extend({
            getLayoutTemplate: function() {
                return document.getElementById('layout-template').innerHTML;
            },
            disableAll: function(){}
        });
        var libPath = window.top.location.origin + '/lib';
        var pdfui = new UIExtension.PDFUI({
            viewerOptions: {
                libPath: libPath,
                jr: {
                    licenseSN: licenseSN,
                    licenseKey: licenseKey
                }
            },
            renderTo: document.body,
            appearance: CustomAppearance,
            addons: libPath + '/uix-addons/allInOne.js'
        });
    </script>
    <style>
        input {
            width: 20em;
        }
        .fv__ui-dropdown {
            width: auto;
        }
    </style>

    {
        "iframeOptions": {
            "style": "height: 300px"
        }
    }