├── .gitignore
├── screen-title
├── README.md
├── flutter.md
├── ios.md
├── react-native.md
├── android.md
└── xamarin.md
├── keyboard-order
├── README.md
├── xamarin.md
└── react-native.md
├── text-spacing
├── README.md
├── react-native.md
├── flutter.md
├── android.md
├── ios.md
└── xamarin.md
├── text-bold
├── xamarin.md
├── README.md
├── flutter.md
├── ios.md
├── react-native.md
└── android.md
├── LICENSE.md
├── accessibility-live-region
├── README.md
├── net-maui.md
├── flutter.md
├── react-native.md
├── xamarin.md
├── android.md
└── ios.md
├── accessibility-action
├── xamarin.md
├── README.md
├── react-native.md
└── flutter.md
├── accessibility-group
├── xamarin.md
├── README.md
├── react-native.md
├── flutter.md
└── ios.md
├── accessibility-modal
├── xamarin.md
├── README.md
├── ios.md
├── net-maui.md
├── react-native.md
├── android.md
└── flutter.md
├── screen-animations
├── xamarin.md
├── README.md
├── flutter.md
├── react-native.md
├── ios.md
└── android.md
├── text-truncation
├── README.md
├── react-native.md
├── xamarin.md
├── flutter.md
├── android.md
└── ios.md
├── accessibility-link
├── README.md
├── net-maui.md
└── react-native.md
├── text-element
├── react-native.md
├── android.md
├── xamarin.md
├── flutter.md
├── ios.md
└── README.md
├── screen-flashes
├── README.md
├── ios.md
├── android.md
├── react-native.md
├── flutter.md
└── xamarin.md
├── screen-labels
├── README.md
├── flutter.md
├── react-native.md
├── ios.md
├── android.md
└── xamarin.md
├── text-scale
├── README.md
├── android.md
├── net-maui.md
├── react-native.md
└── flutter.md
├── input-instructions
├── README.md
├── xamarin.md
├── flutter.md
├── ios.md
├── android.md
└── react-native.md
├── screen-headers
├── README.md
├── flutter.md
├── react-native.md
├── ios.md
├── android.md
└── xamarin.md
├── input-label
├── README.md
├── ios.md
├── flutter.md
├── react-native.md
└── xamarin.md
├── accessibility-language
├── net-maui.md
├── README.md
├── react-native.md
├── xamarin.md
├── flutter.md
└── android.md
├── screen-search
├── xamarin.md
├── react-native.md
├── flutter.md
├── README.md
├── ios.md
└── android.md
├── accessibility-name
├── flutter.md
├── react-native.md
├── ios.md
├── android.md
├── xamarin.md
├── README.md
└── net-maui.md
├── media-audio-control
├── README.md
├── xamarin.md
├── react-native.md
└── flutter.md
├── screen-contrast
├── android.md
├── README.md
├── flutter.md
├── xamarin.md
├── react-native.md
└── ios.md
├── accessibility-focusable
├── react-native.md
├── README.md
├── ios.md
├── xamarin.md
├── flutter.md
├── android.md
└── net-maui.md
├── input-content-type
├── README.md
└── xamarin.md
├── accessibility-label
├── react-native.md
├── README.md
├── xamarin.md
├── android.md
└── flutter.md
├── input-predictable
├── README.md
├── flutter.md
├── react-native.md
├── xamarin.md
├── ios.md
└── android.md
├── media-captions
├── xamarin.md
├── README.md
├── android.md
└── react-native.md
├── accessibility-announcement
├── README.md
├── flutter.md
├── react-native.md
├── xamarin.md
├── ios.md
└── android.md
├── input-cancellation
├── README.md
├── react-native.md
├── flutter.md
├── ios.md
├── android.md
└── xamarin.md
├── accessibility-hint
├── ios.md
├── react-native.md
├── flutter.md
├── README.md
├── android.md
├── xamarin.md
└── net-maui.md
├── input-errors
├── README.md
├── xamarin.md
├── ios.md
├── flutter.md
├── react-native.md
└── android.md
├── media-captions-live
├── xamarin.md
├── README.md
├── react-native.md
├── ios.md
└── flutter.md
├── keyboard-shortcuts
├── README.md
├── react-native.md
├── flutter.md
├── ios.md
└── android.md
├── element-position
├── flutter.md
├── ios.md
├── README.md
├── android.md
├── xamarin.md
└── react-native.md
├── text-localization
├── README.md
├── android.md
├── react-native.md
├── xamarin.md
└── ios.md
├── screen-reflow
├── README.md
├── react-native.md
├── flutter.md
├── android.md
├── ios.md
└── xamarin.md
├── accessibility-dialog
├── README.md
├── xamarin.md
├── net-maui.md
├── ios.md
├── react-native.md
├── flutter.md
└── android.md
├── accessibility-focus
├── README.md
├── android.md
├── flutter.md
├── xamarin.md
├── react-native.md
├── ios.md
└── net-maui.md
├── input-keyboard-type
├── README.md
└── react-native.md
├── linting
├── xamarin.md
├── ios.md
├── react-native.md
├── README.md
├── flutter.md
└── android.md
├── media-audio-description
├── xamarin.md
├── README.md
├── react-native.md
├── android.md
└── flutter.md
├── screen-skip
├── README.md
├── react-native.md
├── flutter.md
├── ios.md
├── xamarin.md
└── android.md
├── element-focus
├── README.md
├── react-native.md
├── xamarin.md
├── android.md
├── ios.md
└── flutter.md
├── input-gestures
├── README.md
├── xamarin.md
├── ios.md
├── flutter.md
├── android.md
└── react-native.md
├── input-motion
├── README.md
├── flutter.md
├── xamarin.md
├── react-native.md
├── ios.md
└── android.md
├── accessibility-state
├── xamarin.md
├── README.md
├── react-native.md
├── flutter.md
└── ios.md
├── screen-orientation
├── README.md
├── react-native.md
└── xamarin.md
├── accessibility-focus-indicator
├── react-native.md
├── README.md
├── ios.md
├── android.md
└── flutter.md
├── accessibility-order
├── README.md
├── ios.md
├── react-native.md
├── xamarin.md
└── android.md
├── accessibility-role
├── README.md
├── react-native.md
├── flutter.md
├── xamarin.md
└── ios.md
├── media-transcript
├── react-native.md
├── xamarin.md
├── README.md
├── android.md
├── flutter.md
└── ios.md
├── accessibility-value
├── README.md
├── react-native.md
├── ios.md
├── xamarin.md
├── net-maui.md
├── flutter.md
└── android.md
├── screen-dark-mode
├── README.md
├── ios.md
├── android.md
├── react-native.md
├── flutter.md
└── xamarin.md
├── element-identification
├── README.md
├── flutter.md
├── xamarin.md
├── ios.md
├── react-native.md
└── android.md
└── screen-timing
├── README.md
├── xamarin.md
├── ios.md
├── flutter.md
├── react-native.md
└── android.md
/.gitignore:
--------------------------------------------------------------------------------
1 | */.DS_STORE
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/screen-title/README.md:
--------------------------------------------------------------------------------
1 | # Screen title
2 |
3 | Each screen should have a descriptive title, which helps users with identifying the screen.
4 |
--------------------------------------------------------------------------------
/keyboard-order/README.md:
--------------------------------------------------------------------------------
1 | # Keyboard order
2 |
3 | By adjusting the keyboard order, you can provide a great experience for users that control their device using a hardware keyboard.
4 |
--------------------------------------------------------------------------------
/text-spacing/README.md:
--------------------------------------------------------------------------------
1 | # Text spacing
2 |
3 | Content should adapt to increased spacing between lines, words, letters, and paragraphs. This helps users with effectively reading text.
4 |
--------------------------------------------------------------------------------
/text-bold/xamarin.md:
--------------------------------------------------------------------------------
1 | # Bold text - Xamarin
2 |
3 | Xamarin does not expose a property which indicates a preference for bold text.
4 |
5 | ```xml
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | Unless otherwise indicated, content is licensed under the [CC BY-SA 4.0 license](./LICENSE.md) and code samples are licensed under the [MIT license](./LICENSE.md).
4 |
--------------------------------------------------------------------------------
/accessibility-live-region/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility live region
2 |
3 | A live region allows users of assistive technologies to receive updates whenever important information on the screen changes.
4 |
--------------------------------------------------------------------------------
/accessibility-action/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility action - Xamarin
2 |
3 | Xamarin does not have built-in support for adding accessibility actions.
4 |
5 | ```csharp
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-group/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility group - Xamarin
2 |
3 | Xamarin Forms does not have built-in support to group accessibility elements.
4 |
5 | ```csharp
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-modal/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility modal - Xamarin
2 |
3 | Xamarin Forms does not have built-in support to indicate an accessibility modal.
4 |
5 | ```xml
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-animations/xamarin.md:
--------------------------------------------------------------------------------
1 | # Reduced animations - Xamarin
2 |
3 | Xamarin does not expose a property which indicates a preference for reduced motion.
4 |
5 | ```xml
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/text-truncation/README.md:
--------------------------------------------------------------------------------
1 | # Text truncation
2 |
3 | Text should never get truncated in your app, even when users have enlarged their font size. Instead, apps should adapt the interface to the available space.
4 |
--------------------------------------------------------------------------------
/accessibility-link/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility link
2 |
3 | Links should be accessible for users of assistive technologies. When accessibility is not taken into account, users might not be able to find or activate links.
4 |
--------------------------------------------------------------------------------
/text-element/react-native.md:
--------------------------------------------------------------------------------
1 | # Text element - React Native
2 |
3 | With React Native, you should use [`Text`](https://reactnative.dev/docs/text) or an equivalent element to display text.
4 |
5 | ```jsx
6 | Appt
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-flashes/README.md:
--------------------------------------------------------------------------------
1 | # Frequent flashes
2 |
3 | Rapidly flashing images or views (more than three flashes per second) can cause seizures for some users. You need to make sure this is not the case when designing and developing an app.
4 |
--------------------------------------------------------------------------------
/screen-labels/README.md:
--------------------------------------------------------------------------------
1 | # Descriptive labels
2 |
3 | Screens should have descriptive labels, these help users recognize which purpose controls have. It is recommended to put distinguishing information at the beginning of your labels.
4 |
--------------------------------------------------------------------------------
/text-scale/README.md:
--------------------------------------------------------------------------------
1 | # Scale text
2 |
3 | Apps should scale text to the size specified by users in the system settings. This is especially important for visually impaired users because they might not be able to read the text otherwise.
4 |
--------------------------------------------------------------------------------
/input-instructions/README.md:
--------------------------------------------------------------------------------
1 | # Input instructions
2 |
3 | When a label might not describe the requested input sufficiently, you should add additional instructions. For example, if passwords are required to be at least 8 characters, indicate this to users.
4 |
--------------------------------------------------------------------------------
/screen-headers/README.md:
--------------------------------------------------------------------------------
1 | # Descriptive headers
2 |
3 | Screens should have descriptive headers, this helps users find specific content and orient themselves within your app. It is recommended to put distinguishing information at the beginning of your headers.
4 |
--------------------------------------------------------------------------------
/input-label/README.md:
--------------------------------------------------------------------------------
1 | # Input label
2 |
3 | Input fields should have labels so that users know what input data is expected. These labels should stay visible while users are entering data. A placeholder which disappears while entering data does not count as a label.
4 |
--------------------------------------------------------------------------------
/screen-labels/flutter.md:
--------------------------------------------------------------------------------
1 | # Descriptive labels - Flutter
2 |
3 | In Flutter, labels created with `Text` can be changed with the unnamed [`data`](https://api.flutter.dev/flutter/widgets/Text/data.html) property.
4 |
5 | ```dart
6 | Text('Descriptive label')
7 | ```
8 |
--------------------------------------------------------------------------------
/text-element/android.md:
--------------------------------------------------------------------------------
1 | # Text element - Android
2 |
3 | On Android, you should use a [`TextView`](https://developer.android.com/reference/android/widget/TextView) or an equivalent element to display text.
4 |
5 | ```xml
6 |
7 | ```
8 |
--------------------------------------------------------------------------------
/text-element/xamarin.md:
--------------------------------------------------------------------------------
1 | # Text element - Xamarin
2 |
3 | With Xamarin, you should use [`Label`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/label) or an equivalent element to display text.
4 |
5 | ```xml
6 |
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-language/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility language - .NET MAUI
2 |
3 | .NET MAUI does not have built-in support to indicate what language should be used by the assistive technologies when reading content.
4 |
5 | ```csharp
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-group/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility group
2 |
3 | It is easier and quicker for users of assistive technologies to interact with grouped elements. Grouping elements into a single control makes things clearer, simplifies interactions, and provides larger touch targets.
4 |
--------------------------------------------------------------------------------
/screen-search/xamarin.md:
--------------------------------------------------------------------------------
1 | # Search functionality - Xamarin
2 |
3 | In Xamarin, you could use a [`SearchBar`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/searchbar) to search for screens.
4 |
5 | ```xml
6 |
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-modal/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility modal
2 |
3 | A modal overlays the screen with additional content. Modals are usually indicated visually, e.g. by throwing a shadow on the content below it. Users of assistive technologies also need to know when content is part of a modal.
4 |
--------------------------------------------------------------------------------
/accessibility-name/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility name - Flutter
2 |
3 | In Flutter, the [`semanticsLabel`](https://api.flutter.dev/flutter/widgets/Text/semanticsLabel.html) property is used as accessibility name.
4 |
5 | ```dart
6 | Control(
7 | semanticsLabel: 'Appt'
8 | );
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-name/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility name - React Native
2 |
3 | In React Native, the [`accessibilityLabel`](https://reactnative.dev/docs/accessibility#accessibilitylabel) prop is used accessibility name.
4 |
5 | ```jsx
6 |
8 | ```
9 |
--------------------------------------------------------------------------------
/media-audio-control/README.md:
--------------------------------------------------------------------------------
1 | # Audio control
2 |
3 | Users should be able to control audio whenever it plays automatically. This includes being able to reduce the volume to zero. It's difficult to hear speech output of the screen reader users when other audio is playing at the same time.
4 |
--------------------------------------------------------------------------------
/screen-search/react-native.md:
--------------------------------------------------------------------------------
1 | # Search functionality - React Native
2 |
3 | In React Native, you could use a [`SearchBar`](https://reactnativeelements.com/docs/components/searchbar) to search for screens.
4 |
5 | ```jsx
6 |
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-name/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility name - iOS
2 |
3 | On iOS, [`accessibilityLabel`](https://developer.apple.com/documentation/uikit/uiaccessibilityelement/1619577-accessibilitylabel) property is used as accessibility name.
4 |
5 | ```swift
6 | element.accessibilityLabel = "Appt"
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-contrast/android.md:
--------------------------------------------------------------------------------
1 | # Contrast - Android
2 |
3 | On Android, you can use the [Accessibility Scanner app](https://developer.android.com/guide/topics/ui/accessibility/testing#accessibility-scanner) to detect contrast issues automatically.
4 |
5 | ```kotlin
6 | // No code required
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-focusable/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility focusable - React Native
2 |
3 | In React Native, the [`accessible`](https://reactnative.dev/docs/accessibility#accessible) property indicates whether assistive technologies can focus on an element.
4 |
5 | ```jsx
6 |
7 | ```
8 |
--------------------------------------------------------------------------------
/input-content-type/README.md:
--------------------------------------------------------------------------------
1 | # Input content type
2 |
3 | Setting the content type for input fields helps user entering data. For example, an e-mail address and password can be autofilled by a password manager. When the content type has not been set, this might not be possible to do automatically.
4 |
--------------------------------------------------------------------------------
/screen-labels/react-native.md:
--------------------------------------------------------------------------------
1 | # Descriptive labels - React Native
2 |
3 | In React Native, labels created by using [`Text`](https://reactnative.dev/docs/text) can be changed by using a [`state hook`](https://reactjs.org/docs/hooks-state.html).
4 |
5 | ```jsx
6 | Descriptive label
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-search/flutter.md:
--------------------------------------------------------------------------------
1 | # Search functionality - Flutter
2 |
3 | In Flutter, you could use a [`TextField`](https://api.flutter.dev/flutter/material/TextField-class.html) to search for screens.
4 |
5 | ```dart
6 | TextField(
7 | onChanged: (text) {
8 | // Search
9 | },
10 | ),
11 | ```
12 |
--------------------------------------------------------------------------------
/accessibility-label/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility label - React Native
2 |
3 | In React Native, you can set an accessibility label by using the [`accessibilityLabel`](https://reactnative.dev/docs/accessibility#accessibilitylabel) prop.
4 |
5 | ```jsx
6 |
8 | ```
9 |
--------------------------------------------------------------------------------
/accessibility-name/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility name - Android
2 |
3 | On Android, the [`contentDescription`](https://developer.android.com/reference/android/view/View.html#attr_android:contentDescription) property is used as accessibility name.
4 |
5 | ```kotlin
6 | element.contentDescription = "Appt"
7 | ```
8 |
--------------------------------------------------------------------------------
/input-predictable/README.md:
--------------------------------------------------------------------------------
1 | # Input predictable
2 |
3 | Whenever a user provides input, there should be no change of `context`. Example of changing context include, but are not limited to: automatically submitting data, opening a new screen or moving to another element. Input should have predictable effects.
4 |
--------------------------------------------------------------------------------
/media-captions/xamarin.md:
--------------------------------------------------------------------------------
1 | # Captions - Xamarin
2 |
3 | On Xamarin, you can use [`MediaElement`](https://docs.microsoft.com/en-us/xamarin/community-toolkit/views/mediaelement) to embed videos. Unfortunately, there is no built-in support to add captions.
4 |
5 | ```csharp
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/text-element/flutter.md:
--------------------------------------------------------------------------------
1 | # Text element - Flutter
2 |
3 | With Flutter, you should use [`Text`](https://api.flutter.dev/flutter/widgets/Text-class.html) or [`RichText`](https://api.flutter.dev/flutter/widgets/RichText-class.html) or an equivalent element to display text.
4 |
5 | ```dart
6 | Text('Appt')
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-announcement/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility announcement
2 |
3 | Users of assistive technologies should be made aware of important changes in content through accessibility announcements. What happens next depends on the active assistive technology. The screen reader for example, will read the message aloud.
4 |
--------------------------------------------------------------------------------
/accessibility-label/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility label
2 |
3 | An accessibility label helps users of assistive technologies to identify elements on the screen. The accessibility label is conveyed to assistive technologies. Accessibility labels are announced by the screen reader and presented visually by voice control.
4 |
--------------------------------------------------------------------------------
/input-cancellation/README.md:
--------------------------------------------------------------------------------
1 | # Input cancellation
2 |
3 | Users should be able to cancel accidental interaction. For example, when users accidentally touches the wrong button, they should be able to undo this and avoid performing an action. Accidental interaction is more common for people with various disabilities.
4 |
--------------------------------------------------------------------------------
/input-instructions/xamarin.md:
--------------------------------------------------------------------------------
1 | # Input instructions - Xamarin
2 |
3 | In Xamarin.Forms, we recommend using a [`Label`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/label) to display instructions.
4 |
5 | ```xml
6 |
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-hint/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility hint - iOS
2 |
3 | On iOS, you can use the [`accessibilityHint`](https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint) property to provide an accessibility hint.
4 |
5 | ```swift
6 | button.accessibilityHint = "Opens the Appt website"
7 | ```
8 |
--------------------------------------------------------------------------------
/input-errors/README.md:
--------------------------------------------------------------------------------
1 | # Input errors
2 |
3 | Users should be notified when they make input errors. Show a clear error message when data has been entered incorrectly. Furthermore, provide suggestions that help users to fix the error. It is important that error messages are also posted to users of assistive technologies.
4 |
--------------------------------------------------------------------------------
/media-captions-live/xamarin.md:
--------------------------------------------------------------------------------
1 | # Live captions - Xamarin
2 |
3 | On Xamarin, you can use [`MediaElement`](https://docs.microsoft.com/en-us/xamarin/community-toolkit/views/mediaelement) to embed videos. Unfortunately, there is no built-in support for live captions.
4 |
5 | ```xml
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-language/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility language
2 |
3 | When content is written in multiple languages, foreign words should ideally be indicated in their respective language. For example, you can indicate a French quote in a Dutch piece of content. This enables assistive technologies to use the right pronunciation.
4 |
--------------------------------------------------------------------------------
/keyboard-shortcuts/README.md:
--------------------------------------------------------------------------------
1 | # Keyboard shortcuts
2 |
3 | Most people operate their smartphones with touch, but some people use an external keyboard. Learning and using keyboard shortcuts can save you a lot of time. Shortcuts should always use a modifier key, such as `CTRL` or `CMD` to avoid clashing with system shortcuts.
4 |
--------------------------------------------------------------------------------
/screen-labels/ios.md:
--------------------------------------------------------------------------------
1 | # Descriptive labels - iOS
2 |
3 | On iOS, labels created with [`UILabel`](https://developer.apple.com/documentation/uikit/uilabel) can be changed with the [`text`](https://developer.apple.com/documentation/uikit/uilabel/1620538-text) property.
4 |
5 | ```swift
6 | label.text = "Descriptive label"
7 | ```
8 |
--------------------------------------------------------------------------------
/element-position/flutter.md:
--------------------------------------------------------------------------------
1 | # Element position - Flutter
2 |
3 | In Flutter, you should place your [`AppBar`](https://api.flutter.dev/flutter/material/AppBar-class.html) on the same position of your [`Scaffold`](https://api.flutter.dev/flutter/material/Scaffold-class.html).
4 |
5 | ```dart
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/media-captions-live/README.md:
--------------------------------------------------------------------------------
1 | # Live captions
2 |
3 | Captions should be provided in real-time to enable users to understand what is being said in live videos. The challenge with live captions is both organizational and technical. A captioner must be present who can provide live captions for the video by using suitable software.
4 |
--------------------------------------------------------------------------------
/screen-headers/flutter.md:
--------------------------------------------------------------------------------
1 | # Descriptive headers - Flutter
2 |
3 | In Flutter, headers created with `Text` can be changed with the unnamed [`data`](https://api.flutter.dev/flutter/widgets/Text/data.html) property.
4 |
5 | ```dart
6 | Semantics(
7 | header: true,
8 | child: Text('Descriptive header')
9 | );
10 | ```
11 |
--------------------------------------------------------------------------------
/text-localization/README.md:
--------------------------------------------------------------------------------
1 | # Localization
2 |
3 | Assistive technologies, such as the screen reader, use the locale for the pronunciation of utterances. It is important to explictly set a locale for your app. An incorrect locale leads to unclear pronunciation. Also, setting a locale can help with displaying characters correctly.
4 |
--------------------------------------------------------------------------------
/accessibility-hint/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility hint - React Native
2 |
3 | In React Native you can set an accessibility hint by using the [`accessibilityHint`](https://reactnative.dev/docs/accessibility#accessibilityhint) prop.
4 |
5 | ```jsx
6 |
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-modal/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility modal - iOS
2 |
3 | On iOS, you can indicate an accessibility modal by using the [`accessibilityViewIsModal`](https://developer.apple.com/documentation/objectivec/nsobject/1615089-accessibilityviewismodal) property.
4 |
5 | ```swift
6 | viewController.accessibilityViewIsModal = true
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-reflow/README.md:
--------------------------------------------------------------------------------
1 | # Reflow
2 |
3 | Content on the screen should reflow based on the users' preferences. In landscape mode, the vertical space is much smaller compared to portrait mode. And when users have enlarged their font size, text should not get truncated. Instead, apps should adapt the interface to the available space.
4 |
--------------------------------------------------------------------------------
/text-element/ios.md:
--------------------------------------------------------------------------------
1 | # Text element - iOS
2 |
3 | On iOS, you should use [`UILabel`](https://developer.apple.com/documentation/uikit/uilabel) or [`UITextView`](https://developer.apple.com/documentation/uikit/uitextview) or an equivalent element to display text.
4 |
5 | ```swift
6 | let label = UILabel()
7 | label.text = "Appt"
8 | ```
9 |
--------------------------------------------------------------------------------
/element-position/ios.md:
--------------------------------------------------------------------------------
1 | # Element position - iOS
2 |
3 | On iOS, you should place your [`UINavigationBar`](https://developer.apple.com/documentation/uikit/uinavigationbar) and [`UITabBar`](https://developer.apple.com/documentation/uikit/uitabbar) on the same position of each screen.
4 |
5 | ```swift
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/text-truncation/react-native.md:
--------------------------------------------------------------------------------
1 | # Text truncation - React Native
2 |
3 | In React Native, you can avoid text truncation by removing all instances of [`numberOfLines`](https://reactnative.dev/docs/text#numberoflines) from you rapp.
4 |
5 | ```jsx
6 |
7 | Avoid text truncation
8 |
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-dialog/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility dialog
2 |
3 | A dialog overlays the screen and offers one or more actions to proceed. Dialogs should always include a close button to make them accessible for users of assistive technologies. Furthermore, the focus of assistive technologies should be trapped inside the dialog while it's visible.
4 |
--------------------------------------------------------------------------------
/accessibility-focus/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus
2 |
3 | Sometimes you need to programmatically move the accessibility focus to a specific element. For example, when you present a modal, the assistive technology should move it's focus to it. Or when moving to a new screen, you might want assistive technologies to focus a specific element.
4 |
--------------------------------------------------------------------------------
/input-keyboard-type/README.md:
--------------------------------------------------------------------------------
1 | # Input keyboard type
2 |
3 | Setting the keyboard type for input fields helps user entering data. For example, if users need to enter a number, it helps to show a numeric keyboard. If users need to enter an e-mail address, it helps if the at-key (`@`) is shown. You should always set an appropriate keyboard type.
4 |
--------------------------------------------------------------------------------
/accessibility-focusable/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility focusable
2 |
3 | An element should indicate whether it should be focusable by assistive technologies or not. You can help users of assistive technologies by choosing which elements they can interact with. By keep unnecessary elements out of the accessibility tree, the user experience is improved.
4 |
--------------------------------------------------------------------------------
/linting/xamarin.md:
--------------------------------------------------------------------------------
1 | # Linting - Xamarin
2 |
3 | With Xamarin, you can can use a lint tool with `Xamarin.Android` projects. Set the property `AndroidLintEnabled` to true in your `.csproj`.
4 |
5 | Unfortunately, there is no built-in lint tool for `Xamarin.iOS` projects.
6 |
7 | ```xml
8 | true
9 | ```
10 |
--------------------------------------------------------------------------------
/media-audio-description/xamarin.md:
--------------------------------------------------------------------------------
1 | # Audio description - Xamarin
2 |
3 | On Xamarin, you can use [`MediaElement`](https://docs.microsoft.com/en-us/xamarin/community-toolkit/views/mediaelement) to embed videos. Unfortunately, there is no built-in support to switch to an audio description track.
4 |
5 | ```xml
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-skip/README.md:
--------------------------------------------------------------------------------
1 | # Skip content
2 |
3 | It can be helpful for users to skip repeated blocks of content. Most apps have content which appears on multiple screens. It takes longer for users of using assistive technologies to get navigate past repeated content. Adding the ability to skip past repeated content helps these users to navigate quicker.
4 |
--------------------------------------------------------------------------------
/text-bold/README.md:
--------------------------------------------------------------------------------
1 | # Bold text
2 |
3 | Apps should use bold text when users have indicated this as a preference in the system settings. Turning on bold text improves the contrast of the letters against the background, making the text easier to read. This is vital if you are visually impaired, but it can also be useful if you need reading glasses.
4 |
--------------------------------------------------------------------------------
/element-focus/README.md:
--------------------------------------------------------------------------------
1 | # Element focus change
2 |
3 | Whenever an element receives focus, it should not automatically trigger an event which changes `context`. Example of changing context include, but are not limited to: automatically submitting data, opening a new screen or moving to another element. Focus should only be moved deliberately by the user.
4 |
--------------------------------------------------------------------------------
/screen-headers/react-native.md:
--------------------------------------------------------------------------------
1 | # Descriptive headers - React Native
2 |
3 | In React Native, headers created by using [`Text`](https://reactnative.dev/docs/text) can be changed by using a [`state hook`](https://reactjs.org/docs/hooks-state.html).
4 |
5 | ```jsx
6 |
7 | Descriptive header
8 |
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-focusable/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility focusable - iOS
2 |
3 | On iOS, you can use the [`isAccessibilityElement`](https://developer.apple.com/documentation/objectivec/nsobject/1615141-isaccessibilityelement) property to indicate whether assistive technologies can focus on an element.
4 |
5 | ```swift
6 | element.isAccessibilityElement = false
7 | ```
8 |
--------------------------------------------------------------------------------
/input-gestures/README.md:
--------------------------------------------------------------------------------
1 | # Input gestures
2 |
3 | Gesture activated functionality should also be available without the use of gestures. Not everyone is able to make all gestures. For example, for users with limited mobility it might be difficult or impossible to make the 'pinch-to-zoom' gesture. You should provide buttons to zoom in and out as an alternative.
4 |
--------------------------------------------------------------------------------
/linting/ios.md:
--------------------------------------------------------------------------------
1 | # Linting - iOS
2 |
3 | On iOS you can use [`SwiftLint`](https://github.com/realm/SwiftLint) to improve the quality of your code.
4 |
5 | Avoid errors with automated testing. On iOS you can use the [XCTest framework](https://www.hackingwithswift.com/articles/148/xcode-ui-testing-cheat-sheet).
6 |
7 | ```swift
8 | swiftlint lint
9 | ```
10 |
--------------------------------------------------------------------------------
/screen-contrast/README.md:
--------------------------------------------------------------------------------
1 | # Contrast
2 |
3 | Apps should provide enough contrast between text and its background so that it can be read by people with moderately low vision. Furthermore, user interface components should also have enough contrast. Low contrast controls are more difficult to perceive, and may be completely missed by people with a visual impairment.
4 |
--------------------------------------------------------------------------------
/accessibility-name/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility name - Xamarin
2 |
3 | In Xamarin, the [`AutomationProperties.Name`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertiesname) property is used as accessibility name.
4 |
5 | ```xml
6 |
8 | ```
9 |
--------------------------------------------------------------------------------
/input-predictable/flutter.md:
--------------------------------------------------------------------------------
1 | # Input predictable - Flutter
2 |
3 | In Flutter, be careful when using [`onChanged`](https://api.flutter.dev/flutter/material/TextField/onChanged.html) callbacks. Do not trigger a change of context when text changes.
4 |
5 | ```dart
6 | TextField(
7 | onChanged: (text) {
8 | // Do not change context
9 | },
10 | ),
11 | ```
12 |
--------------------------------------------------------------------------------
/media-audio-description/README.md:
--------------------------------------------------------------------------------
1 | # Audio description
2 |
3 | Videos should include audio description when important visual details are shown which you cannot hear. Audio description is an additional sound track which describes these important visual details. This allows people who are blind or have difficulty processing visual information to understand the content.
4 |
--------------------------------------------------------------------------------
/screen-search/README.md:
--------------------------------------------------------------------------------
1 | # Search functionality
2 |
3 | Users might have difficulty finding a specific screen. For example, inside a banking app, there might be a setting for enabling contactless payments. Users likely need to navigate through multiple screens to reach before reaching this setting. It helps to offer search functionality to jump directly to this screen.
4 |
--------------------------------------------------------------------------------
/input-motion/README.md:
--------------------------------------------------------------------------------
1 | # Motion input
2 |
3 | Provide an alternative way for actions activated by motion, to allow everyone to use the functionality. For example, for users with limited hand function, shaking is not always possible. Also make it possible to disable actions activated by motion. For example, for users with spasms, these actions could be triggered accidentally.
4 |
--------------------------------------------------------------------------------
/screen-headers/ios.md:
--------------------------------------------------------------------------------
1 | # Descriptive headers - iOS
2 |
3 | On iOS, headers created with [`UILabel`](https://developer.apple.com/documentation/uikit/uilabel) can be changed with the [`text`](https://developer.apple.com/documentation/uikit/uilabel/1620538-text) property.
4 |
5 | ```swift
6 | header.text = "Descriptive header"
7 | header.accessibilityTraits = .header
8 | ```
9 |
--------------------------------------------------------------------------------
/screen-labels/android.md:
--------------------------------------------------------------------------------
1 | # Descriptive labels - Android
2 |
3 | On Android, labels created with [`TextView`](https://developer.android.com/reference/android/widget/TextView) can be changed with the [`setText`](https://developer.android.com/reference/android/widget/TextView#setText(java.lang.CharSequence)) method.
4 |
5 | ```kotlin
6 | label.text = "Descriptive label"
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-state/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility state - Xamarin
2 |
3 | Xamarin Forms does not have built-in support to indicate the accessibility state. By using [`Effects`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/effects/introduction) it is possible to implement platform specific behaviour.
4 |
5 | ```xml
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-orientation/README.md:
--------------------------------------------------------------------------------
1 | # Screen orientation
2 |
3 | Apps should adapt to the preferred display orientation of the user. Most apps restrict the screen to portrait orientation, but they should also support landscape orientation. Some users have their devices mounted in a fixed orientation (e.g. on the arm of a wheelchair). Therefore, apps need to support both orientations.
4 |
--------------------------------------------------------------------------------
/text-truncation/xamarin.md:
--------------------------------------------------------------------------------
1 | # Text truncation - Xamarin
2 |
3 | When using Xamarin.Forms, you can avoid text truncation by removing all instances of [`MaxLines`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.label.maxlines?view=xamarin-forms) from your app.
4 |
5 | ```xml
6 |
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-focus-indicator/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus indicator - React Native
2 |
3 | In React Native, you can adjust colors when an element receives focus. However, it's not possible to change the focus indicator of assistive technologies. Users can adjust their preferences in the system settings on Android and iOS.
4 |
5 | ```tsx
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/element-position/README.md:
--------------------------------------------------------------------------------
1 | # Element position
2 |
3 | Components that are repeated on multiple screens should have a consistent position. This helps users to become comfortable, and they will able to predict where they can find things on each screen. This helps users with cognitive limitations, users with low vision, users with intellectual disabilities, and also those who are blind.
4 |
--------------------------------------------------------------------------------
/accessibility-order/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility order
2 |
3 | Assistive technologies try to determine a logical accessibility order based on the placement and properties of the elements on the screen. In Left-to-Right languages, the order goes from top to bottom, from left to right. If this order is not optimal, you can override the accessibility order that assistive technologies follow.
4 |
--------------------------------------------------------------------------------
/screen-labels/xamarin.md:
--------------------------------------------------------------------------------
1 | # Descriptive labels - Xamarin
2 |
3 | In Xamarin, labels created by using [`Label`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.label?view=xamarin-forms) can be changed with the [`Text`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.label.textproperty?view=xamarin-forms) property.
4 |
5 | ```xml
6 |
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-search/ios.md:
--------------------------------------------------------------------------------
1 | # Search functionality - iOS
2 |
3 | On iOS, you could use a [`UISearchBar`](https://developer.apple.com/documentation/uikit/uisearchbar) to search for screens.
4 |
5 | ```swift
6 | extension SearchController: UISearchBarDelegate {
7 | func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
8 | // Search
9 | }
10 | }
11 | ```
12 |
--------------------------------------------------------------------------------
/accessibility-modal/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility modal - .NET MAUI
2 |
3 | .NET MAUI does not have built-in support to indicate an accessibility modal.
4 |
5 | .NET MAUI does not have built-in support to indicate to assistive technologies that the accessibility elements within the sibling views of the receiving view should be ignored.
6 |
7 | ```xml
8 | Not available, contribute!
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-modal/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility modal - React Native
2 |
3 | With React Native, you can use the [`accessibilityViewIsModal`](https://reactnative.dev/docs/accessibility#accessibilityviewismodal-ios) prop to mark an accessibility modal. This prop only works on iOS.
4 |
5 | ```jsx
6 |
7 | Appt
8 |
9 | ```
10 |
--------------------------------------------------------------------------------
/element-position/android.md:
--------------------------------------------------------------------------------
1 | # Element position - Android
2 |
3 | On Android, you should place your [`Toolbar`](https://developer.android.com/reference/android/widget/Toolbar) and [BottomNavigationView](https://developer.android.com/reference/com/google/android/material/bottomnavigation/BottomNavigationView) on the same position of each screen.
4 |
5 | ```kotlin
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-link/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility link - .NET MAUI
2 |
3 | .NET MAUI does not have built-in support to indicate content as a link.
4 |
5 | Generally it is more important to help users to understand what will happen when they perform an action on the accessibility element. In this case, an accessibility hint could be used.
6 |
7 | ```csharp
8 | Not available, contribute!
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-state/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility state
2 |
3 | An accessibility state helps users of assistive technologies to understand the state of elements on the screen. The state `selected` for example, indicates that an element has been selected. The screen reader announces the state of elements as it reads the screen. It is important to assign correct states of elements to avoid misunderstanding.
4 |
--------------------------------------------------------------------------------
/linting/react-native.md:
--------------------------------------------------------------------------------
1 | # Linting - React Native
2 |
3 | React Native ships a built-in linter named [`ESLint`](https://eslint.org/).
4 |
5 | If possible, always update React Native to the newest version.
6 |
7 | Avoid errors with automated testing. Follow the [Testing guide](https://reactnative.dev/docs/testing-overview) to get started.
8 |
9 | ```jsx
10 | npx eslint "project/**"
11 | ```
12 |
--------------------------------------------------------------------------------
/accessibility-action/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility action
2 |
3 | Accessibility actions provide alternative ways for users of assistive technologies to perform actions. For users of [switch control](https://appt.org/en/docs/ios/features/switch-control) it can be difficult to use drag-and-drop functionality. This functionality can be made more accessible by providing accessibility actions to move items up and down.
4 |
--------------------------------------------------------------------------------
/accessibility-live-region/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility live region - .NET MAUI
2 |
3 | .NET MAUI does not have built-in support to indicate an accessibility live region.
4 |
5 | By using [`Handlers`](https://learn.microsoft.com/en-us/dotnet/maui/user-interface/handlers/?view=net-maui-8.0) it is possible to implement platform specific behaviour.
6 |
7 | ```xml
8 | Not available, contribute!
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-role/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility role
2 |
3 | An accessibility role helps users of assistive technologies to understand the purpose of elements on the screen. The role `button` for example, indicates that an action will be performed on activation. The screen reader announces the role of elements as it reads the screen. It is important to assign correct roles to elements to avoid misunderstanding.
4 |
--------------------------------------------------------------------------------
/element-position/xamarin.md:
--------------------------------------------------------------------------------
1 | # Element position - Xamarin
2 |
3 | In Xamarin, you should always place your [`Toolbar`](https://learn.microsoft.com/en-us/xamarin/android/user-interface/controls/tool-bar/) and [`TabbedPage`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/navigation/tabbed-page) on the same position of each screen.
4 |
5 | ```csharp
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-animations/README.md:
--------------------------------------------------------------------------------
1 | # Reduced animations
2 |
3 | Content which conveys a sense of motion can be a barrier for users. Certain groups, particularly those with attention deficit disorders, find moving content distracting, making it difficult for them to concentrate on other parts of your app. You should provide functionality to pause, stop or hide content which moves, blinks or scrolls automatically.
4 |
--------------------------------------------------------------------------------
/accessibility-hint/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility hint - Flutter
2 |
3 | With Flutter, you can set an accessibility hint by using the [`hint`](https://api.flutter.dev/flutter/semantics/SemanticsProperties/hubt.html) property provided by the [`Semantics`](https://api.flutter.dev/flutter/widgets/Semantics-class.html) widget.
4 |
5 | ```dart
6 | Semantics(
7 | hint: 'Opens the Appt website'
8 | );
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-role/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility role - React Native
2 |
3 | In React Native you can use the [`accessibilityRole`](https://reactnative.dev/docs/accessibility#accessibilityrole) prop to set the accessibility role of an element. Available roles include `button`, `header`, `link` and `image`, among others.
4 |
5 | ```jsx
6 |
8 | ```
9 |
--------------------------------------------------------------------------------
/linting/README.md:
--------------------------------------------------------------------------------
1 | # Linting
2 |
3 | Linting is the process of running a tool which analyzes your code for potential errors. Generally, each problem detected by the tool is reported with a description message and a severity level. This allows you to quickly prioritize the critical improvements that need to be made. Everyone benefits from higher code quality, plus it improves the accuracy of assistive technologies.
4 |
--------------------------------------------------------------------------------
/media-transcript/react-native.md:
--------------------------------------------------------------------------------
1 | # Transcript - React Native
2 |
3 | In React Native, you can use [`Text`](https://reactnative.dev/docs/text) to display written text. Make sure to wrap the `Text` widget in a [`ScrollView`](https://reactnative.dev/docs/scrollview) to enable scrolling.
4 |
5 | ```jsx
6 |
7 |
8 | Appt transcript
9 |
10 |
11 | ```
12 |
--------------------------------------------------------------------------------
/accessibility-name/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility name
2 |
3 | All interactive elements must have an accessibility name. The accessibility name is used by assistive technologies to inform users about the ways to interact with your app.
4 |
5 | For apps, the `accessibility name` is usually equal to the `accessibility label`. See [accessibility label](accessibility-label.md) for more ways of setting an accessibility label.
6 |
--------------------------------------------------------------------------------
/screen-flashes/ios.md:
--------------------------------------------------------------------------------
1 | # Frequent flashes - iOS
2 |
3 | On iOS, flashing content often uses [`DispatchQueue`](https://developer.apple.com/documentation/dispatch/dispatchqueue). Check if this object is used to show more than three flashes per second.
4 |
5 | If your app contains any videos, also check if these contain more than three flashes per second.
6 |
7 | ```swift
8 | Not available, contribute!
9 | ```
10 |
--------------------------------------------------------------------------------
/screen-title/flutter.md:
--------------------------------------------------------------------------------
1 | # Screen title - Flutter
2 |
3 | In Flutter, we recommend using an [`AppBar`](https://api.flutter.dev/flutter/material/AppBar-class.html) with an appropriate [`title`](https://api.flutter.dev/flutter/material/AppBar/title.html) on each screen.
4 |
5 | ```dart
6 | Scaffold(
7 | appBar: AppBar(
8 | title: const Text('Appt homescreen'),
9 | ),
10 | body: ...
11 | );
12 | ```
13 |
--------------------------------------------------------------------------------
/input-predictable/react-native.md:
--------------------------------------------------------------------------------
1 | # Input predictable - React Native
2 |
3 | In React Native, be careful when using [`onChange`](https://reactnative.dev/docs/next/textinput#onchange) or [`onChangeText`](https://reactnative.dev/docs/textinput#onchangetext) callbacks. Do not trigger a change of context when text changes.
4 |
5 | ```jsx
6 |
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-focus-indicator/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus indicator
2 |
3 | Users should know which element has focus when using a keyboard or assistive technology. For example, you could show a rectangle around the focused element. Or you can adjust the colors whenever an element receives focus. Focus indicators can take many different forms. The focus indicator should remain visible while the element is in focused state.
4 |
--------------------------------------------------------------------------------
/accessibility-focusable/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility focusable - Xamarin
2 |
3 | In Xamarin, the [`IsInAccessibleTree`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertiesisinaccessibletree) property indicates whether assistive technologies can focus on an element.
4 |
5 | ```xml
6 |
8 | ```
9 |
--------------------------------------------------------------------------------
/accessibility-value/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility value
2 |
3 | An accessibility value helps users of assistive technologies to understand the value of elements on the screen. A slider should indicate the currently selected value, and ideally also it's minimum and maximum value. The screen reader announces the value of elements as it reads the screen. It is important to assign correct values to elements to avoid misunderstanding.
4 |
--------------------------------------------------------------------------------
/screen-headers/android.md:
--------------------------------------------------------------------------------
1 | # Descriptive headers - Android
2 |
3 | On Android, headers created with [`TextView`](https://developer.android.com/reference/android/widget/TextView) can be changed with the [`setText`](https://developer.android.com/reference/android/widget/TextView#setText(java.lang.CharSequence)) method.
4 |
5 | ```kotlin
6 | header.text = "Descriptive header"
7 | ViewCompat.setAccessibilityHeading(header, true)
8 | ```
9 |
--------------------------------------------------------------------------------
/text-element/README.md:
--------------------------------------------------------------------------------
1 | # Text element
2 |
3 | Always use text elements to display text, unless this is not possible due to styling, such as text logo's. Text elements give users the flexibility to adapt the size and font to their preference. The font size inside an image often scales to a limited extent, or not at all. Make sure not to constrain the height of text elements as it will cut off the text when font-scaling is applied.
4 |
--------------------------------------------------------------------------------
/screen-dark-mode/README.md:
--------------------------------------------------------------------------------
1 | # Dark mode
2 |
3 | Dark mode darkens background colours and provides a more comfortable viewing experience in low light. This is essential for many visually impaired people since a light background colour can be painful or even impossible to look at for an extended period of time. But also people who have problems with their concentration, for example due to a brain disorder, benefit greatly from dark mode.
4 |
--------------------------------------------------------------------------------
/screen-title/ios.md:
--------------------------------------------------------------------------------
1 | # Screen title - iOS
2 |
3 | On iOS, we recommend using a [`UINavigationController`](https://developer.apple.com/documentation/uikit/uinavigationcontroller) with an appropriate [`title`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621364-title) on each screen.
4 |
5 | ```swift
6 | override func viewDidLoad() {
7 | super.viewDidLoad()
8 | title = "Appt homescreen"
9 | }
10 | ```
11 |
--------------------------------------------------------------------------------
/text-bold/flutter.md:
--------------------------------------------------------------------------------
1 | # Bold text - Flutter
2 |
3 | With Flutter, the [`boldText`](https://api.flutter.dev/flutter/dart-ui/AccessibilityFeatures/boldText.html) property of [`AccessibilityFeatures`](https://api.flutter.dev/flutter/dart-ui/AccessibilityFeatures-class.html) can be used to check whether the user prefers bold text.
4 |
5 | ```dart
6 | if (window.accessibilityFeatures.boldText) {
7 | // Use bold text
8 | }
9 | ```
10 |
--------------------------------------------------------------------------------
/text-bold/ios.md:
--------------------------------------------------------------------------------
1 | # Bold text - iOS
2 |
3 | On iOS, the [`isBoldTextEnabled`](https://developer.apple.com/documentation/uikit/uiaccessibility/1615156-isboldtextenabled) property of [`UIAccessibility`](https://developer.apple.com/documentation/objectivec/nsobject/uiaccessibility) can be used to check whether the user prefers bold text.
4 |
5 | ```swift
6 | if UIAccessibility.isBoldTextEnabled {
7 | // Use bold text
8 | }
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-state/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility state - React Native
2 |
3 | In React Native you can use the [`accessibilityState`](https://reactnative.dev/docs/accessibility#accessibilitystate) prop to set the accessibility state of an element. Available roles include `disabled`, `selected`, `checked`, `busy` and `expanded`, among others.
4 |
5 | ```jsx
6 |
8 | ```
9 |
--------------------------------------------------------------------------------
/screen-contrast/flutter.md:
--------------------------------------------------------------------------------
1 | # Contrast - Flutter
2 |
3 | With Flutter, you can use the [Accessibility Scanner app](https://developer.android.com/guide/topics/ui/accessibility/testing#accessibility-scanner) and [Xcode's Accessibility Inspector](https://developer.apple.com/library/archive/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXTestingApps.html) to detect contrast issues automatically.
4 |
5 | ```dart
6 | // No code required
7 | ```
8 |
--------------------------------------------------------------------------------
/input-content-type/xamarin.md:
--------------------------------------------------------------------------------
1 | # Input content type - Xamarin
2 |
3 | Xamarin.Forms does not support content types for input fields. You can create your own [autofill effect](https://mikalaidaronin.info/blog/posts/xamarin-forms-password-autofill/). Unfortunately, the [pull request for adding it to XamarinCommunitToolkit](https://github.com/xamarin/XamarinCommunityToolkit/issues/702) has been closed.
4 |
5 | ```csharp
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-contrast/xamarin.md:
--------------------------------------------------------------------------------
1 | # Contrast - Xamarin
2 |
3 | With Xamarin, you can use the [Accessibility Scanner app](https://developer.android.com/guide/topics/ui/accessibility/testing#accessibility-scanner) and [Xcode's Accessibility Inspector](https://developer.apple.com/library/archive/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXTestingApps.html) to detect contrast issues automatically.
4 |
5 | ```csharp
6 | // No code required
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-headers/xamarin.md:
--------------------------------------------------------------------------------
1 | # Descriptive headers - Xamarin
2 |
3 | In Xamarin, headers created by using [`Label`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.label?view=xamarin-forms) can be changed with the [`Text`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.label.textproperty?view=xamarin-forms) property.
4 |
5 | ```xml
6 |
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-hint/README.md:
--------------------------------------------------------------------------------
1 | # Accessibility hint
2 |
3 | An accessibility hint helps users to understand what will happen after performing an action. Accessibility hints are announced by the screen reader. Keep in mind that users can turn off accessibility hints. You should therefore not rely on accessibility hints as the sole indicator of what happens. You should also avoid information duplication, e.g. avoid telling users that they can 'double tap to activate'.
4 |
--------------------------------------------------------------------------------
/media-captions/README.md:
--------------------------------------------------------------------------------
1 | # Captions
2 |
3 | Captions should be provided to enable users to understand what is being said in videos. Captions are a text based alternative for media, such as videos. The spoken dialogue and sound effects are displayed on screen as the video plays. Captions mostly benefit people who are deaf, hard of hearing, or deafblind. But captions are also useful to anyone who is temporarily unable to perceive sound, for example inside a library.
4 |
--------------------------------------------------------------------------------
/screen-contrast/react-native.md:
--------------------------------------------------------------------------------
1 | # Contrast - React Native
2 |
3 | With React Native, you can use the [Accessibility Scanner app](https://developer.android.com/guide/topics/ui/accessibility/testing#accessibility-scanner) and [Xcode's Accessibility Inspector](https://developer.apple.com/library/archive/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXTestingApps.html) to detect contrast issues automatically.
4 |
5 | ```jsx
6 | // No code required
7 | ```
8 |
--------------------------------------------------------------------------------
/element-position/react-native.md:
--------------------------------------------------------------------------------
1 | # Element position - React Native
2 |
3 | In React Native, you should always place your [`Headers`](https://reactnavigation.org/docs/headers/) and [`Tabs`](https://reactnavigation.org/docs/tab-based-navigation/) on the same position of each screen. We also recommend using [React Navigation](https://reactnative.dev/docs/navigation) to re-use navigation components on all of your screes.
4 |
5 | ```jsx
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-focusable/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility focusable - Flutter
2 |
3 | On Flutter, the [`focusable`](https://api.flutter.dev/flutter/semantics/SemanticsProperties/focusable.html) property of [`SemanticsProperties`](https://api.flutter.dev/flutter/semantics/SemanticsProperties-class.html) can be used to indicate whether assistive technologies can focus on an element.
4 |
5 | ```dart
6 | Semantics(
7 | focusable: false,
8 | child: Widget();
9 | );
10 | ```
11 |
--------------------------------------------------------------------------------
/element-identification/README.md:
--------------------------------------------------------------------------------
1 | # Element identification
2 |
3 | Functionality that is repeated on multiple screens should use consistent identification. Screen readers users rely heavily on their familiarity with functions that may appear on different screens. If identical functions have different labels on different screens, your app will be considerably more difficult to use. It may also be confusing and increase the cognitive load for people with cognitive limitations.
4 |
--------------------------------------------------------------------------------
/accessibility-announcement/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility announcement - Flutter
2 |
3 | With Flutter, you can post an accessibility message by using the [`SemanticsService`](https://api.flutter.dev/flutter/semantics/SemanticsService-class.html) object. Use the [`announce`](https://api.flutter.dev/flutter/semantics/SemanticsService/announce.html) method to post an accessibility announcement.
4 |
5 | ```dart
6 | SemanticsService.announce('Appt announcement', TextDirection.ltr);
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-hint/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility hint - Android
2 |
3 | On Android, you can use [`setHint`](https://developer.android.com/reference/android/widget/TextView#setHint(int)) to set a hint. Keep in mind that this `hint` is not only used for accessibility, but also shown visually in editable views.
4 |
5 | ```kotlin
6 | view.hint = "Opens the Appt website"
7 | ```
8 |
9 | ```xml
10 |
13 | ```
14 |
--------------------------------------------------------------------------------
/input-predictable/xamarin.md:
--------------------------------------------------------------------------------
1 | # Input predictable - Xamarin
2 |
3 | In Xamarin, be careful when using [`TextChanged`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.inputview.textchanged?view=xamarin-forms) callbacks. Do not trigger a change of context when text changes.
4 |
5 | ```csharp
6 | entry.TextChanged += OnEntryTextChanged;
7 |
8 | void OnEntryTextChanged(object sender, TextChangedEventArgs args)
9 | {
10 | // Do not change context
11 | }
12 | ```
13 |
--------------------------------------------------------------------------------
/accessibility-announcement/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility announcement - React Native
2 |
3 | In React Native, you can post an accessibility message by using the [`AccessibilityInfo`](https://reactnative.dev/docs/accessibilityinfo) API. Use the [`announceForAccessibility`](https://reactnative.dev/docs/accessibilityinfo#announceforaccessibility) method to post a message to assistive technologies.
4 |
5 | ```jsx
6 | AccessibilityInfo.announceForAccessibility('Appt announcement');
7 | ```
8 |
--------------------------------------------------------------------------------
/accessibility-order/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility order - iOS
2 |
3 | On iOS, you can use the [`accessibilityElements`](https://developer.apple.com/documentation/objectivec/nsobject/1615147-accessibilityelements) property to set the order for assistive technologies. Be careful using the `accessibilityElements` property, because any elements left out of the array cannot be reached with assistive technologies.
4 |
5 | ```swift
6 | view.accessibilityElements = [header, description, list]
7 | ```
8 |
--------------------------------------------------------------------------------
/element-focus/react-native.md:
--------------------------------------------------------------------------------
1 | # Element focus change - React Native
2 |
3 | In React Native, you can use the [`onFocus`](https://reactnative.dev/docs/next/textinput#onfocus) method to listen to focus changes. The method is called when the element receives focus.
4 |
5 | Be careful when the `onFocus` callback: do not trigger any context change because they might confuse users.
6 |
7 | ```jsx
8 | {
9 | // Do not change context
10 | }} />
11 | ```
12 |
--------------------------------------------------------------------------------
/screen-search/android.md:
--------------------------------------------------------------------------------
1 | # Search functionality - Android
2 |
3 | On Android, you could use a [`SearchView`](https://developer.android.com/reference/androidx/appcompat/widget/SearchView) to search for screens.
4 |
5 | ```kotlin
6 | searchView.setOnQueryTextListener(
7 | object : SearchView.OnQueryTextListener {
8 | override fun onQueryTextSubmit(query: String?): Boolean {
9 | // Search
10 | return false
11 | }
12 | }
13 | )
14 | ```
15 |
--------------------------------------------------------------------------------
/screen-timing/README.md:
--------------------------------------------------------------------------------
1 | # Adjustable timing
2 |
3 | Everyone, including people with disabilities, should have adequate time to interact with your app. People with disabilities may require more time to interact with your app. If certain functions are time-dependent, it will be difficult for some users to finish in time. If content is shown for a limited time, users might not finish reading in time. It should be possible for users to increase time limits, or ideally, disable all time limits.
4 |
--------------------------------------------------------------------------------
/accessibility-live-region/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility live region - Flutter
2 |
3 | On Flutter, the [`liveRegion`](https://api.flutter.dev/flutter/semantics/SemanticsConfiguration/liveRegion.html) property can be used in [`Semantics`](https://api.flutter.dev/flutter/widgets/Semantics-class.html) to indicate a live region. By default, the live region is `polite`: it queues announcements.
4 |
5 | ```dart
6 | Semantics(
7 | liveRegion: true,
8 | child: Text('Appt live region')
9 | );
10 | ```
11 |
--------------------------------------------------------------------------------
/media-audio-control/xamarin.md:
--------------------------------------------------------------------------------
1 | # Audio control - Xamarin
2 |
3 | In Xamarin apps you should always be able to control audio. You can use [`MediaElement`](https://docs.microsoft.com/en-us/xamarin/community-toolkit/views/mediaelement) to embed media. The `ShowsPlaybackControls` needs to be set to `True` to show controls for playing and pausing. The value is `False` by default.
4 |
5 | ```xml
6 |
8 | ```
9 |
--------------------------------------------------------------------------------
/media-transcript/xamarin.md:
--------------------------------------------------------------------------------
1 | # Transcript - Xamarin
2 |
3 | In Xamarin, you can use [`Label`](https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.label?view=xamarin-forms) to display written text. Make sure to wrap the `Label` widget in a [`ScrollView`](https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.scrollview?view=xamarin-forms) to enable scrolling.
4 |
5 | ```xml
6 |
7 |
8 |
9 | ```
10 |
--------------------------------------------------------------------------------
/screen-reflow/react-native.md:
--------------------------------------------------------------------------------
1 | # Reflow - React Native
2 |
3 | In React Native, your elements should be placed inside a scrollable layout, such as [`ScrollView`](https://reactnative.dev/docs/scrollview). If the elements don't fit, the view becomes scrollable over the vertical axis so the user can still reach them. Ideally scrolling is only necessary in one direction.
4 |
5 | ```jsx
6 |
7 |
8 | Content should scroll!
9 |
10 |
11 | ```
12 |
--------------------------------------------------------------------------------
/screen-animations/flutter.md:
--------------------------------------------------------------------------------
1 | # Reduced animations - Flutter
2 |
3 | With Flutter, you can use [`MediaQuery.of(context)`](https://api.flutter.dev/flutter/widgets/MediaQuery/of.html) to retrieve the value of [`disableAnimations`](https://api.flutter.dev/flutter/widgets/MediaQueryData/disableAnimations.html). If the value is `true`, you could choose to disable (non-essential) animations in your app.
4 |
5 | ```dart
6 | if (MediaQuery.of(this).disableAnimations) {
7 | // Disable animations
8 | }
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-hint/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility hint - Xamarin
2 |
3 | In Xamarin Forms you can set an accessibility hint by using the [`AutomationProperties.HelpText`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertieshelptext) property.
4 |
5 | ```xml
6 |
8 | ```
9 |
10 | ```csharp
11 | AutomationProperties.SetHelpText(button, "Opens the Appt website");
12 | ```
13 |
--------------------------------------------------------------------------------
/input-motion/flutter.md:
--------------------------------------------------------------------------------
1 | # Motion input - Flutter
2 |
3 | With Flutter, packages like [`sensors_plus`](https://pub.dev/packages/sensors_plus) can be used to detect movement.
4 |
5 | An event through sensors should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```dart
8 | import 'package:sensors_plus/sensors_plus.dart';
9 |
10 | accelerometerEvents.listen((AccelerometerEvent event) {
11 | // Provide alternative
12 | });
13 | ```
14 |
--------------------------------------------------------------------------------
/media-transcript/README.md:
--------------------------------------------------------------------------------
1 | # Transcript
2 |
3 | Videos should contain a transcript to allow users to read what is shown in media, such as a video or podcast.
4 |
5 | A basic transcript contains information needed to understand what is being said. This mostly benefits people who are deaf or hard of hearing, or have difficulty processing auditory information.
6 |
7 | A descriptive transcript also contains visual information to understand what is being shown. This mostly benefits people who are blind or visually impaired.
8 |
--------------------------------------------------------------------------------
/input-errors/xamarin.md:
--------------------------------------------------------------------------------
1 | # Input errors - Xamarin
2 |
3 | In Xamarin.Forms, we recommend using a [`Label`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/label) to display an error. The error message should also be posted to assistive technologies by using an [`accessibility announcement`](../Techniques/accessibility-announcement.md).
4 |
5 | ```xml
6 |
9 | ```
10 |
--------------------------------------------------------------------------------
/element-focus/xamarin.md:
--------------------------------------------------------------------------------
1 | # Element focus change - Xamarin
2 |
3 | In Xamarin.Forms, you can use the [`Focused`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.visualelement.focused?view=xamarin-forms) event to listen to focus changes. The method is called when the element receives focus.
4 |
5 | Be careful when the `Focused` callback: do not trigger any context change because they might confuse users.
6 |
7 | ```csharp
8 | Element.Focused += (sender, arguments) => {
9 | // Do not change context
10 | };
11 | ```
12 |
--------------------------------------------------------------------------------
/input-label/ios.md:
--------------------------------------------------------------------------------
1 | # Input label - iOS
2 |
3 | On iOS, there is no attribute to link a label to an input field. We recommend combining [`UILabel`](https://developer.apple.com/documentation/uikit/uilabel) with a [`UITextField`](https://developer.apple.com/documentation/uikit/uitextfield) or [`UITextView`](https://developer.apple.com/documentation/uikit/uitextview).
4 |
5 | Set the `accessibilityLabel` of the field to the text of the label.
6 |
7 | ```swift
8 | label.text = "Name"
9 | field.accessibilityLabel = label.text
10 | ```
11 |
--------------------------------------------------------------------------------
/accessibility-language/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility language - React Native
2 |
3 | In React Native, there is limited support to change the accessibility language. The [`accessibilityLanguage`](https://reactnative.dev/docs/text#accessibilitylanguage-ios) prop of [`Text`](https://reactnative.dev/docs/text) only works on iOS. Multiple `Text` elements can be combined to speak content in multiple languages.
4 |
5 | ```jsx
6 |
7 | Appt
8 | is an accessibility platform.
9 |
10 | ```
11 |
--------------------------------------------------------------------------------
/screen-animations/react-native.md:
--------------------------------------------------------------------------------
1 | # Reduced animations - React Native
2 |
3 | In React Native, you can use [`AccessibilityInfo`](https://reactnative.dev/docs/accessibilityinfo) to check get the value of [`isReduceMotionEnabled`](https://reactnative.dev/docs/accessibilityinfo#isreducemotionenabled). If the value is `true`, you could choose to disable (non-essential) animations in your app.
4 |
5 | ```jsx
6 | import { AccessibilityInfo } from "react-native";
7 |
8 | if (AccessibilityInfo.isReduceMotionEnabled()) {
9 | // Disable animations
10 | }
11 | ```
12 |
--------------------------------------------------------------------------------
/screen-title/react-native.md:
--------------------------------------------------------------------------------
1 | # Screen title - React Native
2 |
3 | In React Native, we recommend using [React Navigation](https://reactnative.dev/docs/navigation) with an appropriate [`title`](https://reactnavigation.org/docs/headers#setting-the-header-title) on each screen.
4 |
5 | ```jsx
6 | function StackScreen() {
7 | return (
8 |
9 |
14 |
15 | );
16 | }
17 | ```
18 |
--------------------------------------------------------------------------------
/linting/flutter.md:
--------------------------------------------------------------------------------
1 | # Linting - Flutter
2 |
3 | Flutter ships with a built-in linter named [`flutter_lints`](https://docs.flutter.dev/release/breaking-changes/flutter-lints-package). Run `flutter analyze .` in the root of a project to return all usages of deprecated code.
4 |
5 | If possible, always update Flutter to the newest version.
6 |
7 | Avoid errors with automated testing. Follow the [How to test a Flutter App - Codelab](https://codelabs.developers.google.com/codelabs/flutter-app-testing#0) to get started.
8 |
9 | ```dart
10 | flutter analyze .
11 | ```
12 |
--------------------------------------------------------------------------------
/screen-flashes/android.md:
--------------------------------------------------------------------------------
1 | # Frequent flashes - Android
2 |
3 | On Android, flashing content often uses [`Executors`](https://developer.android.com/reference/java/util/concurrent/Executors), [`Handler`](https://developer.android.com/reference/android/os/Handler), or [`Timer`](https://developer.android.com/reference/java/util/Timer). Check if these objects are used to show more than three flashes per second.
4 |
5 | If your app contains any videos, also check if these contain more than three flashes per second.
6 |
7 | ```kotlin
8 | Not available, contribute!
9 | ```
10 |
--------------------------------------------------------------------------------
/text-bold/react-native.md:
--------------------------------------------------------------------------------
1 | # Bold text - React Native
2 |
3 | On React Native, the [`isBoldTextEnabled()`](https://reactnative.dev/docs/next/accessibilityinfo#isboldtextenabled-ios) method of [`AccessibilityInfo`](https://reactnative.dev/docs/next/accessibilityinfo) can be used to check whether the user prefers bold text.
4 |
5 | Note: it only checks the preference on iOS. Android is not yet supported.
6 |
7 | ```jsx
8 | import { AccessibilityInfo } from "react-native";
9 |
10 | if (AccessibilityInfo.isBoldTextEnabled()) {
11 | // Use bold text
12 | }
13 | ```
14 |
--------------------------------------------------------------------------------
/accessibility-group/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility group - React Native
2 |
3 | In React Native, you can group elements together by using the [`accessible`](https://reactnative.dev/docs/accessibility#accessible) prop. An [`accessibilityLabel`](https://reactnative.dev/docs/accessibility#accessibilitylabel) should be set for grouped elements.
4 |
5 | Note: all touchable elements are accessible by default.
6 |
7 | ```jsx
8 |
9 | Appt
10 | is a platform for accessibility
11 |
12 | ```
13 |
--------------------------------------------------------------------------------
/input-cancellation/react-native.md:
--------------------------------------------------------------------------------
1 | # Input cancellation - React Native
2 |
3 | In React Native, be careful when using [`PressEvent`](https://reactnative.dev/docs/pressevent). Avoid using events like [`onPressIn`](https://reactnative.dev/docs/pressable#onpressin), because users will not be able to cancel their interaction. Use events like [`onPress`](https://reactnative.dev/docs/pressable#onpressin) instead, because these have built-in support for cancellation.
4 |
5 | ```jsx
6 | {
8 | // Use onPress instead
9 | }}
10 | />
11 | ```
12 |
--------------------------------------------------------------------------------
/input-label/flutter.md:
--------------------------------------------------------------------------------
1 | # Input label - Flutter
2 |
3 | In Flutter, there is no attribute to link a label to an input field. You can use an [`InputDecoration`](https://api.flutter.dev/flutter/material/InputDecoration-class.html) to show a label for a [`TextField`](https://api.flutter.dev/flutter/material/TextField-class.html). You need to provide a [`Text`](https://docs.flutter.dev/development/ui/widgets/text) widget for the `label` property.
4 |
5 | ```dart
6 | TextField(
7 | decoration: InputDecoration(
8 | label: Text('Name')
9 | ),
10 | );
11 | ```
12 |
--------------------------------------------------------------------------------
/input-predictable/ios.md:
--------------------------------------------------------------------------------
1 | # Input predictable - iOS
2 |
3 | With iOS, be careful when using [`UITextFieldDelegate`](https://developer.apple.com/documentation/uikit/uitextfielddelegate) methods. Do not trigger a change of context when text changes.
4 |
5 | ```swift
6 | extension ApptViewController: UITextFieldDelegate {
7 | func textField(_ textField: UITextField,
8 | shouldChangeCharactersIn range: NSRange,
9 | replacementString string: String) -> Bool {
10 | // Do not change context
11 | return true
12 | }
13 | }
14 | ```
15 |
--------------------------------------------------------------------------------
/screen-flashes/react-native.md:
--------------------------------------------------------------------------------
1 | # Frequent flashes - React Native
2 |
3 | In React Native, flashing content might be a result of using [`Animated`](https://reactnative.dev/docs/animated) or [`Timers`](https://reactnative.dev/docs/timers). By default, each animation will take 500 milliseconds. Make sure your animations does not result in more than three flashes per second.
4 |
5 | If your app contains any videos, also check if these contain more than three flashes per second.
6 |
7 | ```jsx
8 | setTimeout(() => {
9 | // Avoid three flashes per second
10 | }, 500);
11 | ```
12 |
--------------------------------------------------------------------------------
/element-identification/flutter.md:
--------------------------------------------------------------------------------
1 | # Element identification - Flutter
2 |
3 | In Flutter, you should create custom `Widgets` to re-use functionality on multiple screens.
4 |
5 | When using icons, use the search function of your `IDE` to check all instances. The icon should have the same `accessibility label` on each screen, and the functionality should also be the same.
6 |
7 | For example, when using a cross icon for closing a screen, make sure the label is 'Close' on all screens, and check that it always closes a screen.
8 |
9 | ```dart
10 | Not available, contribute!
11 | ```
12 |
--------------------------------------------------------------------------------
/element-identification/xamarin.md:
--------------------------------------------------------------------------------
1 | # Element identification - Xamarin
2 |
3 | In Xamarin, you should create custom `Views` to re-use functionality on multiple screens.
4 |
5 | When using icons, use the search function of your `IDE` to check all instances. The icon should have the same `accessibility label` on each screen, and the functionality should also be the same.
6 |
7 | For example, when using a cross icon for closing a screen, make sure the label is 'Close' on all screens, and check that it always closes a screen.
8 |
9 | ```csharp
10 | Not available, contribute!
11 | ```
12 |
--------------------------------------------------------------------------------
/input-instructions/flutter.md:
--------------------------------------------------------------------------------
1 | # Input instructions - Flutter
2 |
3 | In Flutter, you can use an [`InputDecoration`](https://api.flutter.dev/flutter/material/InputDecoration-class.html) to show instructions for a [`TextField`](https://api.flutter.dev/flutter/material/TextField-class.html). You need to provide a `string` for the [`helperText`](https://api.flutter.dev/flutter/material/InputDecoration/helperText.html) property.
4 |
5 | ```dart
6 | TextField(
7 | decoration: InputDecoration(
8 | helperText: 'Your password should be at least 8 characters.',
9 | ),
10 | );
11 | ```
12 |
--------------------------------------------------------------------------------
/accessibility-action/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility action - React Native
2 |
3 | In React Native, you can add [`accessibility actions`](https://reactnative.dev/docs/accessibility#accessibility-actions) using the `accessibilityActions` and `onAccessibilityAction` properties.
4 |
5 | ```jsx
6 | {
11 | if (event.nativeEvent.actionName === 'increment') {
12 | handleIncrement();
13 | }
14 | }}
15 | />
16 | ```
17 |
--------------------------------------------------------------------------------
/accessibility-language/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility language - Xamarin
2 |
3 | Unfortunately, Xamarin Forms does not have support for changing the accessibility language. When you use HTML such as `Appt` inside a [`Label`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/label), the [`lang`](https://www.w3schools.com/tags/att_global_lang.asp) attribute is not used. You can create a component with a custom renderer with native Android and iOS logic. If you have done this, please contribute code.
4 |
5 | ```csharp
6 | Not available, contribute!
7 | ```
8 |
--------------------------------------------------------------------------------
/screen-reflow/flutter.md:
--------------------------------------------------------------------------------
1 | # Reflow - Flutter
2 |
3 | In Flutter, all elements should be placed in a scalable widget, such as [`SingleChildScrollView`](https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html) or [`ListView`](https://api.flutter.dev/flutter/widgets/ListView-class.html). These widgets ensures that underlying widgets will become scrollable, in case they do not fit on the screen.
4 |
5 | ```dart
6 | SingleChildScrollView(
7 | child: Text(
8 | 'Content should scroll!',
9 | softWrap: true,
10 | overflow: TextOverflow.visible,
11 | ),
12 | )
13 | ```
14 |
--------------------------------------------------------------------------------
/accessibility-state/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility state - Flutter
2 |
3 | With Flutter, you can use [`Semantics`](https://api.flutter.dev/flutter/widgets/Semantics-class.html) to indicate the accessibility state. The [`Semantics constructor`](https://api.flutter.dev/flutter/widgets/Semantics/Semantics.html) contains all available options, such as `checked`, `enabled`, `hidden`, `selected` and `toggled`, among others.
4 |
5 | ```dart
6 | Semantics(
7 | checked: true,
8 | enabled: true,
9 | hidden: true,
10 | selected: true,
11 | toggled: true,
12 | child: Widget(...)
13 | );
14 | ```
15 |
--------------------------------------------------------------------------------
/screen-animations/ios.md:
--------------------------------------------------------------------------------
1 | # Reduced animations - iOS
2 |
3 | On iOS, you can read the [`UIAccessibility.isReduceMotionEnabled`](https://developer.apple.com/documentation/uikit/uiaccessibility/1615133-isreducemotionenabled) property. If the value is `true`, you could choose to disable (non-essential) animations in your app. You can do this, for example, with the [`setAnimationsEnabled`](https://developer.apple.com/documentation/uikit/uiview/1622420-setanimationsenabled) method.
4 |
5 | ```swift
6 | if UIAccessibility.isReduceMotionEnabled {
7 | UIView.setAnimationsEnabled(false)
8 | }
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-focus/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus - Android
2 |
3 | On Android, you can send an [`AccessibilityEvent`](https://developer.android.com/reference/android/view/accessibility/AccessibilityEvent) of the type [`TYPE_VIEW_FOCUSED`](https://developer.android.com/reference/android/view/accessibility/AccessibilityEvent#TYPE_VIEW_FOCUSED) to move the focus of assistive technologies to a specific view. The view must be focusable for this event to take effect.
4 |
5 | ```kotlin
6 | fun focus(view: View) {
7 | view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)
8 | }
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-live-region/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility live region - React Native
2 |
3 | On React Native, the [`accessibilityLiveRegion`](https://reactnative.dev/docs/accessibility#accessibilityliveregion-android) prop can be used to indicate a live region. The value can be set to `asssertive` to interrupt ongoing speech to for immediate announcements on change. The `polite` value can be used to queue announcements. The `none` value can be used to disable announcements on change.
4 |
5 | ```jsx
6 |
7 | Appt live region
8 |
9 | ```
10 |
--------------------------------------------------------------------------------
/text-scale/android.md:
--------------------------------------------------------------------------------
1 | # Scale text - Android
2 |
3 | On Android, you can use [Scale-independent Pixels](https://developer.android.com/guide/topics/resources/more-resources.html#Dimension) to scale text. This unit ensures that the user's preferences are taken into account when determining the font size. We recommend to define the [`textSize`](https://developer.android.com/reference/android/widget/TextView#attr_android:textSize) in your styles to make sure it's the same everywhere.
4 |
5 | ```xml
6 |
9 | ```
10 |
--------------------------------------------------------------------------------
/text-spacing/react-native.md:
--------------------------------------------------------------------------------
1 | # Text spacing - React Native
2 |
3 | React Native has a couple of attributes to adjust text spacing:
4 |
5 | - [`letterSpacing`](https://reactnative.dev/docs/text-style-props#letterspacing): set spacing between letters
6 | - [`lineHeight`](https://reactnative.dev/docs/text-style-props#lineheight): set spacing between lines
7 | - [`paddingVertical`](https://reactnative.dev/docs/layout-props#paddingvertical): set spacing between paragraphs
8 |
9 | ```jsx
10 | Appt
15 | ```
16 |
--------------------------------------------------------------------------------
/accessibility-order/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility order - React Native
2 |
3 | React Native does not have support for changing the focus order. You can use the [`accessible`](https://reactnative.dev/docs/accessibility#accessible) prop to indicate that a view should be focusable. The child elements get grouped together.
4 |
5 | More information about the lack of support for changing accessibility order can be found inside [Discussion 389](https://github.com/react-native-community/discussions-and-proposals/discussions/389) of the React Native Community.
6 |
7 | ```jsx
8 | Not available, contribute!
9 | ```
10 |
--------------------------------------------------------------------------------
/linting/android.md:
--------------------------------------------------------------------------------
1 | # Linting - Android
2 |
3 | On Android you can use [`AndroidLint`](https://developer.android.com/studio/write/lint) to improve the quality of your code.
4 |
5 | Check if you are using outdated code. In Android Studio you can check this by selecting the following menu options:
6 |
7 | 1. Kotlin
8 | 2. Migration
9 | 3. Usage of redundant or deprecated syntax or deprecated symbols
10 |
11 | Avoid errors with automated testing. Follow the [UI-testing guide for Android](https://developer.android.com/training/testing/ui-testing).
12 |
13 | ```kotlin
14 | /AndroidSDK/tools/lint /project
15 | ```
16 |
--------------------------------------------------------------------------------
/screen-skip/react-native.md:
--------------------------------------------------------------------------------
1 | # Skip content - React Native
2 |
3 | In React Native, skipping content is mostly relevant to [`TalkBack`](https://appt.org/en/docs/android/features/talkback) and [`VoiceOver`](https://appt.org/en/docs/ios/features/voiceover) users. Both screen readers include shortcuts which allows users to jump to content types, such as `headers` and `links`.
4 |
5 | Provide appropriate accessibility markup to your content by using [`accessibilityRole`](https://reactnative.dev/docs/accessibility#accessibilityrole).
6 |
7 | ```jsx
8 |
10 | ```
11 |
--------------------------------------------------------------------------------
/input-instructions/ios.md:
--------------------------------------------------------------------------------
1 | # Input instructions - iOS
2 |
3 | On iOS, we recommend using an [`UILabel`](https://developer.apple.com/documentation/uikit/uilabel) to indicate an error. The error message should also be posted to assistive technologies by using an [`accessibility announcement`](../Techniques/accessibility-announcement.md).
4 |
5 | You could also use a third party library to displaying instructions. Unfortunately, accessibility is often not considered in the implementations.
6 |
7 | ```swift
8 | helpLabel.isHidden = false
9 | helpLabel.text = "Your password should be at least 8 characters."
10 | ```
11 |
--------------------------------------------------------------------------------
/screen-title/android.md:
--------------------------------------------------------------------------------
1 | # Screen title - Android
2 |
3 | On Android, we recommend using a [`Toolbar`](https://developer.android.com/reference/androidx/appcompat/widget/Toolbar) with an appropriate [`title`](https://developer.android.com/reference/android/app/Activity.html#setTitle(java.lang.CharSequence)) on each screen.
4 |
5 | ```kotlin
6 | override fun onCreate(savedInstanceState: Bundle?) {
7 | super.onCreate(savedInstanceState)
8 | setContentView(R.layout.appt)
9 |
10 | val toolbar = findViewById(R.id.toolbar)
11 | setSupportActionBar(toolbar)
12 | title = "Appt homescreen"
13 | }
14 | ```
15 |
--------------------------------------------------------------------------------
/accessibility-focus/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus - Flutter
2 |
3 | Flutter does not have built-in support for changing accessibility focus. See [Flutter issue #59594](https://github.com/flutter/flutter/issues/59594) for more information.
4 |
5 | You could implement your own [`platform channels`](https://docs.flutter.dev/development/platform-integration/platform-channels) to call the native Android and iOS methods to move accessibility focus.
6 |
7 | Do not use `FocusNode` or `Semantics.focused`, these methods should only be used for keyboard or input focus.
8 |
9 | ```dart
10 | Not available, contribute!
11 | ```
12 |
--------------------------------------------------------------------------------
/accessibility-order/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility order - Xamarin
2 |
3 | Xamarin Forms supports changing the accessibility order through the [`TabIndex`](https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.visualelement.tabindex?view=xamarin-forms) property. The default value is 0. The lower the value, the higher the priority. For example, to reach the save button before reaching the cancel button, the cancel button's `TabIndex` needs to be higher than the save button.
4 |
5 | ```xml
6 |
7 |
8 |
9 | ```
10 |
--------------------------------------------------------------------------------
/input-cancellation/flutter.md:
--------------------------------------------------------------------------------
1 | # Input cancellation - Flutter
2 |
3 | On Flutter, be careful when using a [`GestureDetector`](https://api.flutter.dev/flutter/widgets/GestureDetector-class.html) Avoid using events such as `onDown`, like `onTapDown` and `onLongPressDown`, because users will not be able to cancel their interaction. Use `onAction` events such `onTap` or `onLongPress` instead, because these have built-in support for cancellation.
4 |
5 | ```dart
6 | @override
7 | Widget build(BuildContext context) {
8 | return new GestureDetector(
9 | onDown: ... // Use onTap instead
10 | );
11 | }
12 | ```
13 |
--------------------------------------------------------------------------------
/input-gestures/xamarin.md:
--------------------------------------------------------------------------------
1 | # Input gestures - Xamarin
2 |
3 | With Xamarin, it is common to detect gestures using one of the recognizers defined in [`Xamarin Forms Gestures`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/gestures/).
4 |
5 | A gesture should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```csharp
8 | var pinchGesture = new PinchGestureRecognizer();
9 | pinchGesture.PinchUpdated += (sender, event) => {
10 | // Provide alternative
11 | };
12 | view.GestureRecognizers.Add(pinchGesture);
13 | ```
14 |
--------------------------------------------------------------------------------
/screen-skip/flutter.md:
--------------------------------------------------------------------------------
1 | # Skip content - Flutter
2 |
3 | In Flutter, skipping content is mostly relevant to [`TalkBack`](https://appt.org/en/docs/android/features/talkback) and [`VoiceOver`](https://appt.org/en/docs/ios/features/voiceover) users. Both screen readers include shortcuts which allows users to jump to content types, such as `headers` and `links`.
4 |
5 | Provide appropriate accessibility markup to your content by using [`Semantics`](https://api.flutter.dev/flutter/widgets/Semantics-class.html).
6 |
7 | ```dart
8 | Semantics(
9 | header: true,
10 | link: true,
11 | child: Widget(...)
12 | );
13 | ```
14 |
--------------------------------------------------------------------------------
/text-truncation/flutter.md:
--------------------------------------------------------------------------------
1 | # Text truncation - Flutter
2 |
3 | In Flutter, you can avoid text truncation by removing all instances of [`maxLines`](https://api.flutter.dev/flutter/widgets/Text/maxLines.html) from your app. You should also set [`overflow`](https://api.flutter.dev/flutter/widgets/Text/overflow.html) to [`TextOverflow.visible`](https://api.flutter.dev/flutter/painting/TextOverflow.html#visible) where needed. Lastly, avoid using fixed values for any heights or widths.
4 |
5 | ```dart
6 | Text(
7 | 'Avoid text truncation',
8 | maxLines: REMOVE,
9 | overflow: TextOverflow.visible
10 | )
11 | ```
12 |
--------------------------------------------------------------------------------
/accessibility-announcement/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility announcement - Xamarin
2 |
3 | Xamarin Forms does not have built-in support for changing accessibility focus.
4 |
5 | The [`SemanticExtensions`](https://github.com/xamarin/XamarinCommunityToolkit/blob/main/src/CommunityToolkit/Xamarin.CommunityToolkit/Extensions/Semantic/SemanticExtensions.shared.cs) file inside the [`Xamarin.CommunityToolkit`](https://github.com/xamarin/XamarinCommunityToolkit) contains the `Announce` method. It posts an accessibility announcement on the native platform.
6 |
7 | ```csharp
8 | SemanticExtensions.Announce("Appt announcement");
9 | ```
10 |
--------------------------------------------------------------------------------
/accessibility-focus/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus - Xamarin
2 |
3 | Xamarin Forms does not have built-in support for changing accessibility focus.
4 |
5 | The [`SemanticExtensions`](https://github.com/xamarin/XamarinCommunityToolkit/blob/main/src/CommunityToolkit/Xamarin.CommunityToolkit/Extensions/Semantic/SemanticExtensions.shared.cs) file inside the [`Xamarin.CommunityToolkit`](https://github.com/xamarin/XamarinCommunityToolkit) contains the `SetSemanticFocus` method. It moves the accessibility focus to the given element on the native platform.
6 |
7 | ```csharp
8 | SemanticExtensions.SetSemanticFocus(element)
9 | ```
10 |
--------------------------------------------------------------------------------
/input-errors/ios.md:
--------------------------------------------------------------------------------
1 | # Input errors - iOS
2 |
3 | On iOS, we recommend using an [`UILabel`](https://developer.apple.com/documentation/uikit/uilabel) to indicate an error. The error message should also be posted to assistive technologies by using an [`accessibility announcement`](../Techniques/accessibility-announcement.md).
4 |
5 | You could also use a third party library to displaying instructions. Unfortunately, accessibility is often not considered in the implementations.
6 |
7 | ```swift
8 | errorLabel.isHidden = false
9 | errorLabel.text = "Invalid date, must be in the form DD/MM/YYYY, for example, 01/01/2000"
10 | ```
11 |
--------------------------------------------------------------------------------
/media-audio-control/react-native.md:
--------------------------------------------------------------------------------
1 | # Audio control - React Native
2 |
3 | In React Native apps you should always be able to control audio. A popular option for media is the [`react-native-video`](https://github.com/react-native-video/react-native-video/) package. You can use the [`audioOnly`](https://github.com/react-native-video/react-native-video/blob/master/API.md#audioonly) property to play audio files. The `react-native-video` package offers native controls for playing and pausing by default.
4 |
5 | ```jsx
6 |
10 | ```
11 |
--------------------------------------------------------------------------------
/screen-contrast/ios.md:
--------------------------------------------------------------------------------
1 | # Contrast - iOS
2 |
3 | On iOS, can use [Xcode's Accessibility Inspector](https://developer.apple.com/library/archive/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXTestingApps.html) to detect contrast issues automatically.
4 |
5 | You can also use the property [`accessibilityContrast`](https://developer.apple.com/documentation/uikit/uiaccessibilitycontrast) to check if the user has enabled increased contrast in the Accessibility settings of their device.
6 |
7 | ```swift
8 | if UITraitCollection.current.accessibilityContrast == .high {
9 | // High contrast logic
10 | }
11 | ```
12 |
--------------------------------------------------------------------------------
/screen-flashes/flutter.md:
--------------------------------------------------------------------------------
1 | # Frequent flashes - Flutter
2 |
3 | In Flutter, flashing content often uses widgets that change on changes from a [`Stream`](https://api.flutter.dev/flutter/dart-async/Stream-class.html). For example, this could happen by using a [`StreamBuilder`](https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html), and thus requesting a re-draw of certain parts of the screen. Check if these objects are used to show more than three flashes per second.
4 |
5 | If your app contains any videos, also check if these contain more than three flashes per second.
6 |
7 | ```dart
8 | Not available, contribute!
9 | ```
10 |
--------------------------------------------------------------------------------
/media-transcript/android.md:
--------------------------------------------------------------------------------
1 | # Transcript - Android
2 |
3 | On Android, you can use a [`TextView`](https://developer.android.com/reference/android/widget/TextView) to display written text. Don't forget to put it in a [ScrollView](https://developer.android.com/reference/android/widget/ScrollView), to make the text scrollable.
4 |
5 | ```xml
6 |
9 |
10 |
14 |
15 | ```
16 |
--------------------------------------------------------------------------------
/screen-flashes/xamarin.md:
--------------------------------------------------------------------------------
1 | # Frequent flashes - Xamarin
2 |
3 | In Xamarin.Forms, flashing content might be a result of using [`Timer`](https://learn.microsoft.com/en-us/dotnet/api/System.Threading.Timer?view=net-7.0) or [`ViewExtensions`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.viewextensions?view=xamarin-forms) for animations. By default, each animation will take 250 milliseconds. Make sure your animations does not result in more than three flashes per second.
4 |
5 | If your app contains any videos, also check if these contain more than three flashes per second.
6 |
7 | ```csharp
8 | Not available, contribute!
9 | ```
10 |
--------------------------------------------------------------------------------
/input-motion/xamarin.md:
--------------------------------------------------------------------------------
1 | # Motion input - Xamarin
2 |
3 | In Xamarin, the [`Accelerometer`](https://docs.microsoft.com/en-us/xamarin/essentials/accelerometer) class can be used to listen to changes in acceleration of the device in three-dimensional space.
4 |
5 | An event through acceleration should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```csharp
8 | Accelerometer.ReadingChanged += Accelerometer_ReadingChanged;
9 |
10 | void Accelerometer_ReadingChanged(object sender, AccelerometerChangedEventArgs e)
11 | {
12 | // Provide alternative
13 | }
14 | ```
15 |
--------------------------------------------------------------------------------
/media-captions-live/react-native.md:
--------------------------------------------------------------------------------
1 | # Live captions - React Native
2 |
3 | React Native does not have any out-of-the box packages which enable you to provide real-time captions for live audio or video streams.
4 |
5 | You can however embed a YouTube stream in your app and enable [Live Stream Captioning](https://support.google.com/youtube/thread/129769858/updates-to-captions-and-audio-features-on-youtube?hl=en).
6 |
7 | ```jsx
8 | import YoutubePlayer from "react-native-youtube-iframe";
9 |
10 |
16 | ```
17 |
--------------------------------------------------------------------------------
/accessibility-announcement/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility announcement - iOS
2 |
3 | On iOS, you post an accessibility message by using the [`UIAccessibility`](https://developer.apple.com/documentation/uikit/uiaccessibility) object. The [`post`](https://developer.apple.com/documentation/uikit/uiaccessibility/1615194-post) method can be used to post data to assistive technologies. Set the type to [`announcement`](https://developer.apple.com/documentation/uikit/uiaccessibility/notification/1620176-announcement) and supply a `string` argument to announce something.
4 |
5 | ```swift
6 | UIAccessibility.post(notification: .announcement, argument: "Appt announcement")
7 | ```
8 |
--------------------------------------------------------------------------------
/text-localization/android.md:
--------------------------------------------------------------------------------
1 | # Localization - Android
2 |
3 | On Android, you can use the [`createConfigurationContext`](https://developer.android.com/reference/android/content/Context#createConfigurationContext(android.content.res.Configuration)) method to load resources in the correct locale. This is especially important for users of screen readers.
4 |
5 | ```kotlin
6 | val locales = LocaleList.forLanguageTags("nl-NL")
7 | val configuration = baseContext.resources.configuration
8 | configuration.setLocales(locales)
9 | val context = createConfigurationContext(configuration)
10 |
11 | element.text = context.resources.getString(R.string.appt)
12 | ```
13 |
--------------------------------------------------------------------------------
/media-transcript/flutter.md:
--------------------------------------------------------------------------------
1 | # Transcript - Flutter
2 |
3 | With Flutter, you can use [`Text`](https://api.flutter.dev/flutter/widgets/Text-class.html) to display written text. Make sure to wrap the `Text` widget in a [`SingleChildScrollView`](https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html) and to set the overflow parameter to `TextOverflow.visible`. Also, the `softwrap` parameter needs to be set to true to prevent the text from overflowing outside its container.
4 |
5 | ```dart
6 | SingleChildScrollView(
7 | child: Text(
8 | 'Appt transcript',
9 | softWrap: true,
10 | overflow: TextOverflow.visible,
11 | ),
12 | )
13 | ```
14 |
--------------------------------------------------------------------------------
/accessibility-hint/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility hint - .NET MAUI
2 |
3 | In .NET MAUI, an accessibility hint is set by using the [`SemanticProperties.Hint`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.controls.semanticproperties.hintproperty?view=net-maui-8.0#microsoft-maui-controls-semanticproperties-hintproperty) property.
4 |
5 | ```xml
6 |
8 | ```
9 |
10 | **Warning:**
11 | The `Hint` property conflicts with the `Entry.Placeholder` property on Android, which both map to the same platform property. Therefore, setting a different Hint value to the Entry.Placeholder value isn't recommended.
--------------------------------------------------------------------------------
/accessibility-language/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility language - Flutter
2 |
3 | With Flutter, the `locale` parameter of [`Text`](https://api.flutter.dev/flutter/widgets/Text-class.html) or [`TextSpan`](https://api.flutter.dev/flutter/painting/TextSpan-class.html) can be used to specify the locale for a piece of text. Multiple `TextSpan` elements can be combined to speak content in multiple languages.
4 |
5 | ```dart
6 | /// Text implementation
7 | Text(
8 | 'Appt',
9 | locale: Locale.fromSubtags(languageCode: 'nl'),
10 | );
11 |
12 | /// TextSpan implementation
13 | TextSpan(
14 | text: 'Appt',
15 | locale: Locale.fromSubtags(languageCode: 'nl'),
16 | );
17 | ```
18 |
--------------------------------------------------------------------------------
/accessibility-role/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility role - Flutter
2 |
3 | For some widgets in Flutter, the role is assignd automatically. This happens, for example, with Flutter's buttons and text fields. If this is not the case, you can use [`Semantics`](https://api.flutter.dev/flutter/widgets/Semantics-class.html) to indicate a role. The [`Semantics constructor`](https://api.flutter.dev/flutter/widgets/Semantics/Semantics.html) contains all available options, such as `button`, `header`, `link` and `image`, among others.
4 |
5 | ```dart
6 | Semantics(
7 | button: true,
8 | header: true,
9 | link: true,
10 | image: true,
11 | child: Widget(...)
12 | );
13 | ```
14 |
--------------------------------------------------------------------------------
/input-motion/react-native.md:
--------------------------------------------------------------------------------
1 | # Motion input - React Native
2 |
3 | In React Native, packages like [`expo-sensors`](https://docs.expo.dev/versions/latest/sdk/sensors/) can be used to detect motion.
4 |
5 | An event through sensors should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```jsx
8 | import { Accelerometer } from 'expo-sensors';
9 |
10 | export default function App() {
11 | const _subscribe = () => {
12 | setSubscription(
13 | Accelerometer.addListener(accelerometerData => {
14 | // Provide alternative
15 | })
16 | );
17 | };
18 | }
19 | ```
20 |
--------------------------------------------------------------------------------
/screen-reflow/android.md:
--------------------------------------------------------------------------------
1 | # Reflow - Android
2 |
3 | On Android, all elements should be placed in a scrollable layout, such as a [`ScrollView`](https://developer.android.com/reference/android/widget/ScrollView) or [`RecyclerView`](https://developer.android.com/jetpack/androidx/releases/recyclerview). Never use fixed values for any heights or widths.
4 |
5 | ```xml
6 |
9 |
10 |
14 |
15 | ```
16 |
--------------------------------------------------------------------------------
/screen-reflow/ios.md:
--------------------------------------------------------------------------------
1 | # Reflow - iOS
2 |
3 | On iOS, all elements should be placed in a scrollable layout, such as [`UIScrollView`](https://developer.apple.com/documentation/uikit/uiscrollview), [`UITableView`](https://developer.apple.com/documentation/uikit/views_and_controls/table_views) or [`UICollectionView`](https://developer.apple.com/documentation/uikit/views_and_controls/collection_views). Never use fixed values for any heights or widths.
4 |
5 | ```swift
6 | let label = UILabel()
7 | label.text = "Content should scroll!"
8 |
9 | let view = UIView()
10 | view.addSubview(label)
11 |
12 | let scrollView = UIScrollView()
13 | scrollView.addSubview(view)
14 | ```
15 |
--------------------------------------------------------------------------------
/text-truncation/android.md:
--------------------------------------------------------------------------------
1 | # Text truncation - Android
2 |
3 | On Android, you can avoid text truncation by removing all instances of [`android:maxLines`](https://developer.android.com/reference/android/widget/TextView#attr_android:maxLines) from your app. You should also avoid using fixed values for any heights or widths and instead use [`wrap_content`](https://developer.android.com/reference/android/view/ViewGroup.LayoutParams#WRAP_CONTENT) where possible.
4 |
5 | ```xml
6 |
11 | ```
12 |
--------------------------------------------------------------------------------
/input-predictable/android.md:
--------------------------------------------------------------------------------
1 | # Input predictable - Android
2 |
3 | On Android, be careful when using [`TextWatcher`](https://developer.android.com/reference/android/text/TextWatcher) methods. Do not trigger a change of context when text changes.
4 |
5 | ```kotlin
6 | private val textWatcher = object : TextWatcher {
7 | override fun afterTextChanged(s: Editable?) {
8 | // Ignored
9 | }
10 |
11 | override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
12 | // Ignored
13 | }
14 |
15 | override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
16 | // Do not change context
17 | }
18 | }
19 | ```
20 |
--------------------------------------------------------------------------------
/accessibility-language/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility language - Android
2 |
3 | On Android, you can use [`LocaleSpan`](https://developer.android.com/reference/android/text/style/LocaleSpan) to speak content in a specific language. Multiple `LocaleSpan`'s can be embedded inside a [`SpannableString`](https://developer.android.com/reference/android/text/SpannableString) to speak content in multiple languages.
4 |
5 | ```kotlin
6 | val locale = Locale.forLanguageTag("nl-NL")
7 | val localeSpan = LocaleSpan(locale)
8 |
9 | val string = SpannableString("Appt")
10 | string.setSpan(localeSpan, 0, string.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
11 |
12 | element.setText(string)
13 | ```
14 |
--------------------------------------------------------------------------------
/accessibility-focusable/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility focusable - Android
2 |
3 | On Android, you can use the [`setImportantForAccessibility`](https://developer.android.com/reference/android/view/View#setImportantForAccessibility(int)) method to set whether assistive technologies can focus on an element. You can also set this property directly in XML by using the [`android:importantForAccessibility`](https://developer.android.com/reference/android/view/View#attr_android:importantForAccessibility) property.
4 |
5 | ```kotlin
6 | view.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
7 | ```
8 |
9 | ```xml
10 |
12 | ```
13 |
--------------------------------------------------------------------------------
/text-scale/net-maui.md:
--------------------------------------------------------------------------------
1 | # Scale text - .NET MAUI
2 |
3 | All controls that display text automatically apply font scaling. The scale is based on the font size preference set in the Android or iOS operating system.
4 |
5 | By default, .NET MAUI apps use the `Open Sans` font on each platform. However, this default can be changed by registering additional fonts in your app.
6 |
7 | You can find additional guidance in the [.NET MAUI fonts article](https://learn.microsoft.com/en-us/dotnet/maui/user-interface/fonts?view=net-maui-8.0).
8 |
9 | ```csharp
10 |
14 | ```
15 |
--------------------------------------------------------------------------------
/screen-orientation/react-native.md:
--------------------------------------------------------------------------------
1 | # Screen orientation - React Native
2 |
3 | In React Native, multiple screen orientations are enabled by default. Locking screen orientation is handled in native code:
4 |
5 | - For Android, remove instances of the `android:screenOrientation` attribute.
6 | - For iOS, check if 4 orientations have been added to `UISupportedInterfaceOrientations`.
7 |
8 | You can use the [`Dimensions`](https://reactnative.dev/docs/dimensions) API to listen to orientation changes.
9 |
10 | ```jsx
11 | Dimensions.addEventListener('change', () => {
12 | this.setState({
13 | orientation: Platform.isPortrait() ? 'portrait' : 'landscape'
14 | });
15 | });
16 | ```
17 |
--------------------------------------------------------------------------------
/accessibility-group/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility group - Flutter
2 |
3 | On Flutter, there are multiple types of semantics to group accessibility elements. The [`excludeSemantics`](https://api.flutter.dev/flutter/widgets/Semantics/excludeSemantics.html) property can be used to override the semantics of all children. You can achieve similar behavior by using [`BlockSemantics`](https://api.flutter.dev/flutter/widgets/BlockSemantics-class.html).
4 |
5 | ```dart
6 | Semantics(
7 | label: 'Appt group',
8 | excludeSemantics: true,
9 | child: Column(
10 | children: [
11 | Text('Appt'),
12 | Text('is a platform for accessibility')
13 | ]
14 | )
15 | );
16 | ```
17 |
--------------------------------------------------------------------------------
/element-focus/android.md:
--------------------------------------------------------------------------------
1 | # Element focus change - Android
2 |
3 | On Android, you can use an [`OnFocusChangeListener`](https://developer.android.com/reference/android/view/View.OnFocusChangeListener) to listen to focus changes. The [`onFocusChange`](https://developer.android.com/reference/android/view/View.OnFocusChangeListener#onFocusChange(android.view.View,%20boolean)) method is called when the element receives focus.
4 |
5 | Be careful when using the `onFocusChange` method: do not trigger any context change because they might confuse users.
6 |
7 | ```kotlin
8 | webView.setOnFocusChangeListener { view, focused ->
9 | if (focused) {
10 | // Do not change context
11 | }
12 | }
13 | ```
14 |
--------------------------------------------------------------------------------
/element-identification/ios.md:
--------------------------------------------------------------------------------
1 | # Element identification - iOS
2 |
3 | In iOS, you should create custom `Views` to re-use functionality on multiple screens.
4 |
5 | When using icons, use the search function of your `IDE` to check all instances. The icon should have the same `accessibility label` on each screen, and the functionality should also be the same.
6 |
7 | For example, when using a cross icon for closing a screen, make sure the label is 'Close' on all screens, and check that it always closes a screen.
8 |
9 | In Xcode you can use the shortcut `Cmd + Shift + F` on Mac, or `Ctrl + Shift + F` on Window to open the global `Find` function.
10 |
11 | ```swift
12 | Not available, contribute!
13 | ```
14 |
--------------------------------------------------------------------------------
/media-audio-description/react-native.md:
--------------------------------------------------------------------------------
1 | # Audio description - React Native
2 |
3 | On React Native, the [React-Native-Video](https://github.com/react-native-video/react-native-video) package has support for [switching audio tracks](https://github.com/react-native-video/react-native-video/blob/master/API.md#selectedaudiotrack). This allows you to offer users a way to switch to an audio description track.
4 |
5 | Note: The audio tracks must be encoded in the file, this is not something you add programmatically.
6 |
7 | ```jsx
8 | import Video from 'react-native-video';
9 |
10 |
16 | ```
17 |
--------------------------------------------------------------------------------
/text-truncation/ios.md:
--------------------------------------------------------------------------------
1 | # Text truncation - iOS
2 |
3 | On iOS, you can avoid text truncation by seting the [`numberOfLines`](https://developer.apple.com/documentation/uikit/uilabel/1620539-numberoflines/) property to `0` on your `UILabel`. You should also avoid using fixed values for any heights or widths and instead use [`constraints`](https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithConstraintsinInterfaceBuidler.html) and [`self-sizing`](https://developer.apple.com/documentation/uikit/uifont/creating_self-sizing_table_view_cells).
4 |
5 | ```swift
6 | let label = UILabel()
7 | label.text = "Avoid text truncation"
8 | label.numberOfLines = 0
9 | ```
10 |
--------------------------------------------------------------------------------
/input-keyboard-type/react-native.md:
--------------------------------------------------------------------------------
1 | # Input keyboard type - React Native
2 |
3 | In React Native, you can set a keyboard type by using the [`keyboardType`](https://reactnative.dev/docs/textinput#keyboardtype) property.
4 |
5 | The following values work across platforms:
6 |
7 | - `default`
8 | - `number-pad`
9 | - `decimal-pad`
10 | - `numeric`
11 | - `email-address`
12 | - `phone-pad`
13 | - `url`
14 |
15 | The following values work on iOS only:
16 |
17 | - `ascii-capable`
18 | - `numbers-and-punctuation`
19 | - `name-phone-pad`
20 | - `twitter`
21 | - `web-search`
22 |
23 | The following values work on Android only:
24 |
25 | - `visible-password`
26 |
27 | ```jsx
28 |
29 | ```
30 |
--------------------------------------------------------------------------------
/accessibility-modal/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility modal - Android
2 |
3 | On Android, there is no method to indicate an accessibility modal. However, you can can indicate an accessibility pane by using the [`setPaneTitle`](https://developer.android.com/reference/androidx/core/view/accessibility/AccessibilityNodeInfoCompat#setPaneTitle(java.lang.CharSequence)) method. `ViewCompat` also contains a convenience method: [`setAccessibilityPaneTitle`](https://developer.android.com/reference/androidx/core/view/ViewCompat#setAccessibilityPaneTitle(android.view.View,java.lang.CharSequence)). Please keep in mind that is focus is not trapped when a pane title has been set.
4 |
5 | ```kotlin
6 | ViewCompat.setAccessibilityPaneTitle(view, "Appt pane")
7 | ```
8 |
--------------------------------------------------------------------------------
/element-identification/react-native.md:
--------------------------------------------------------------------------------
1 | # Element identification - React Native
2 |
3 | In React Native, you should create custom `Components` to re-use functionality on multiple screens.
4 |
5 | When using icons, use the search function of your `IDE` to check all instances. The icon should have the same `accessibility label` on each screen, and the functionality should also be the same.
6 |
7 | For example, when using a cross icon for closing a screen, make sure the label is 'Close' on all screens, and check that it always closes a screen.
8 |
9 | ```jsx
10 | const CloseButton = () =>
13 |
16 |
17 | ```
18 |
--------------------------------------------------------------------------------
/input-cancellation/ios.md:
--------------------------------------------------------------------------------
1 | # Input cancellation - iOS
2 |
3 | On iOS, you should avoid using [`touchesBegan`](https://developer.apple.com/documentation/uikit/uiresponder/1621142-touchesbegan) or [`UIControlEventTouchDown`](https://developer.apple.com/documentation/uikit/uicontrolevents/uicontroleventtouchdown) because users will not be able to cancel their interaction. Actions should only be activated through `up` events. Use a [`UITapGestureRecognizer`](https://developer.apple.com/documentation/uikit/uitapgesturerecognizer) instead, because it has built-in support for cancellation.
4 |
5 | ```swift
6 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
7 | // Use UITapGestureRecognizer instead
8 | }
9 | ```
10 |
--------------------------------------------------------------------------------
/screen-skip/ios.md:
--------------------------------------------------------------------------------
1 | # Skip content - iOS
2 |
3 | On iOS, skipping content is mostly relevant to [`VoiceOver`](https://appt.org/en/docs/ios/features/voiceover) users. VoiceOver includes a `rotor` which allows users to jump to the following content types:
4 |
5 | - Headers
6 | - Links
7 | - Form Controls
8 | - Containers
9 | - Text
10 | - Lines
11 | - Characters
12 | - Words
13 |
14 | Jumping to `headers` and `links` is used most often.
15 |
16 | Provide appropriate accessibility markup to your content by using [`accessibilityTraits`](https://developer.apple.com/documentation/objectivec/nsobject/1615202-accessibilitytraits).
17 |
18 | ```swift
19 | header.accessibilityTraits = .header
20 | header.accessibilityTraits = .link
21 | ```
22 |
--------------------------------------------------------------------------------
/screen-skip/xamarin.md:
--------------------------------------------------------------------------------
1 | # Skip content - Xamarin
2 |
3 | In Xamarin, skipping content is mostly relevant to [`TalkBack`](https://appt.org/en/docs/android/features/talkback) and [`VoiceOver`](https://appt.org/en/docs/ios/features/voiceover) users. Both screen readers include shortcuts which allows users to jump to content types, such as `headers` and `links`.
4 |
5 | Provide appropriate accessibility markup to your content by using [`SemanticEffect`](https://github.com/xamarin/XamarinCommunityToolkit/blob/main/src/CommunityToolkit/Xamarin.CommunityToolkit/Effects/Semantic/SemanticEffect.shared.cs).
6 |
7 | ```csharp
8 |
11 | ```
12 |
--------------------------------------------------------------------------------
/text-bold/android.md:
--------------------------------------------------------------------------------
1 | # Bold text - Android
2 |
3 | Android 12 has added the [`fontWeightAdjustment`](https://developer.android.com/reference/android/content/res/Configuration#fontWeightAdjustment) property. The property returns an integer between `1` and `1000`, which indicates the current user preference for increasing font weight. The constant [`FontStyle.FONT_WEIGHT_BOLD`](https://developer.android.com/reference/android/graphics/fonts/FontStyle#FONT_WEIGHT_BOLD) has a value of `700`.
4 |
5 | ```kotlin
6 | fun Context.prefersBoldFont(): Boolean {
7 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
8 | return false
9 | }
10 | return resources.configuration.fontWeightAdjustment >= FontStyle.FONT_WEIGHT_BOLD
11 | }
12 | ```
13 |
--------------------------------------------------------------------------------
/input-gestures/ios.md:
--------------------------------------------------------------------------------
1 | # Input gestures - iOS
2 |
3 | On iOS, the [`UIGestureRecognizer`](https://developer.apple.com/documentation/uikit/uigesturerecognizer) and [`UIGestureRecognizerDelegate`](https://developer.apple.com/documentation/uikit/uigesturerecognizerdelegate) objects are a common way to detect gestures.
4 |
5 | A gesture should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```swift
8 | let gesture = UIPinchGestureRecognizer(
9 | target: self,
10 | action: #selector(onPinch(_:))
11 | )
12 | addGestureRecognizer(gesture)
13 |
14 | @objc private func onPinch(_ sender: UIPinchGestureRecognizer) {
15 | // Provide alternative
16 | }
17 | }
18 | ```
19 |
--------------------------------------------------------------------------------
/media-transcript/ios.md:
--------------------------------------------------------------------------------
1 | # Transcript - iOS
2 |
3 | On iOS, you can use [`UITextView`](https://developer.apple.com/documentation/uikit/uitextview) to present a transcript. A `UITextView` is scrollable by default. You can also choose to place one or more [`UILabel`](https://developer.apple.com/documentation/uikit/uilabel)'s in a [`UIScrollView`](https://developer.apple.com/documentation/uikit/uiscrollview).
4 |
5 | ```swift
6 | // Option 1
7 | let transcript = UITextView()
8 | transcript.text = "Appt transcript"
9 |
10 | // Option 2
11 | let transcript = UILabel()
12 | transcript.text = "Appt transcript"
13 |
14 | let view = UIView()
15 | view.addSubview(transcript)
16 |
17 | let scrollView = UIScrollView()
18 | scrollView.addSubview(view)
19 | ```
20 |
--------------------------------------------------------------------------------
/screen-dark-mode/ios.md:
--------------------------------------------------------------------------------
1 | # Dark mode - iOS
2 |
3 | On iOS, you can detect dark mode by checking if the [`userInterfaceStyle`](https://developer.apple.com/documentation/uikit/uitraitcollection/1651063-userinterfacestyle) has been set to [`.dark`](https://developer.apple.com/documentation/uikit/uiuserinterfacestyle/dark).
4 |
5 | You can provide dark mode resources to let iOS automatically use the right resources. For example, inside `Assets.xcassets` you can add a `Dark` version for colors and images.
6 |
7 | ```swift
8 | func isInDarkMode() -> Bool{
9 | if #available(iOS 12.0, *) {
10 | if UIScreen.main.traitCollection.userInterfaceStyle == .dark {
11 | return true
12 | }
13 | }
14 | return false
15 | }
16 | ```
17 |
--------------------------------------------------------------------------------
/element-focus/ios.md:
--------------------------------------------------------------------------------
1 | # Element focus change - iOS
2 |
3 | On iOS, you can use the [`UIAccessibilityFocus`](https://developer.apple.com/documentation/objectivec/nsobject/uiaccessibilityfocus) protocol to listen to focus changes. The [`accessibilityElementDidBecomeFocused`](https://developer.apple.com/documentation/objectivec/nsobject/1615183-accessibilityelementdidbecomefoc) method is called whenever an element receives focus.
4 |
5 | Be careful when using the `accessibilityElementDidBecomeFocused` method: do not trigger any context change because they might confuse users.
6 |
7 | ```swift
8 | class View: UIView {
9 |
10 | override open func accessibilityElementDidBecomeFocused() {
11 | // Do not change context
12 | }
13 | }
14 | ```
15 |
--------------------------------------------------------------------------------
/input-gestures/flutter.md:
--------------------------------------------------------------------------------
1 | # Input gestures - Flutter
2 |
3 | In Flutter, the [`GestureDetector`](https://api.flutter.dev/flutter/widgets/GestureDetector-class.html) class is a common way to detect gestures.
4 |
5 | A gesture should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```dart
8 | double _baseScaleFactor = 1;
9 | double _scaleFactor = 1;
10 |
11 | GestureDetector(
12 | onScaleStart: (details) {
13 | _baseScaleFactor = _scaleFactor;
14 | },
15 | onScaleUpdate: (details) {
16 | setState(() {
17 | _scaleFactor = _baseScaleFactor * details.scale;
18 | // Provide alternative
19 | });
20 | },
21 | child: ...
22 | ),
23 | );
24 | ```
25 |
--------------------------------------------------------------------------------
/accessibility-dialog/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility dialog - Xamarin
2 |
3 | In Xamarin Forms you can use the [`DisplayAlert`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.page.displayalert?view=xamarin-forms) method to show an alert. The last parameter of the method is the text of cancel button and it is required to supply it. Therefore, a cancel button is always shown! The focus of assistive technologies is automatically trapped inside the dialog while it's visible.
4 |
5 | ```csharp
6 | var accept = await App.Current.MainPage.DisplayAlert(
7 | "Confirm Appt membership?",
8 | "Your bank account will be billed.",
9 | "Proceed",
10 | "Cancel"
11 | );
12 |
13 | if (accept) {
14 | // Proceed
15 | } else {
16 | // Cancel
17 | }
18 | ```
19 |
--------------------------------------------------------------------------------
/media-audio-control/flutter.md:
--------------------------------------------------------------------------------
1 | # Audio control - Flutter
2 |
3 | In Flutter apps you should always be able to control audio. Two popular options for playing media are [`video_player`](https://pub.dev/packages/video_player) and [`just_audio`](https://pub.dev/packages/just_audio). Both packages have options for controlling audio through `play()` and `pause()` methods.
4 |
5 | ```dart
6 | final player = AudioPlayer();
7 | final duration = await player.setUrl('https://appt.org/audio.mp3');
8 |
9 | IconButton(
10 | icon: Icon(Icons.play_arrow),
11 | iconSize: 64.0,
12 | onPressed: await player.play(),
13 | );
14 |
15 | IconButton(
16 | icon: Icon(Icons.pause),
17 | iconSize: 64.0,
18 | onPressed: await player.pause(),
19 | );
20 | ```
21 |
--------------------------------------------------------------------------------
/keyboard-shortcuts/react-native.md:
--------------------------------------------------------------------------------
1 | # Keyboard shortcuts - React Native
2 |
3 | React Native does not support binding custom key events for shortcuts. The package [`react-native-keyevent`](https://github.com/kevinejohn/react-native-keyevent) allows you to capture external keyboard keys. However, it [only works on Android](https://github.com/kevinejohn/react-native-keyevent).
4 |
5 | ```jsx
6 | componentDidMount() {
7 | KeyEvent.onKeyMultipleListener((keyEvent) => {
8 | console.log(`onKeyMultiple keyCode: ${keyEvent.keyCode}`);
9 | console.log(`Action: ${keyEvent.action}`);
10 | console.log(`Characters: ${keyEvent.characters}`);
11 | });
12 | }
13 |
14 | componentWillUnmount() {
15 | KeyEvent.removeKeyMultipleListener();
16 | }
17 | ```
18 |
--------------------------------------------------------------------------------
/screen-reflow/xamarin.md:
--------------------------------------------------------------------------------
1 | # Reflow - Xamarin
2 |
3 | When using Xamarin.Forms, your elements should be placed inside a scrollable layout, such as:
4 |
5 | - [`ScrollView`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/scrollview): for static content
6 | - [`CollectionView`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/): for multi dimensional content
7 | - [`ListView`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/): for one dimensional content
8 | - [`WebView`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/webview): for web content
9 |
10 | ```xml
11 |
12 |
13 |
14 | ```
15 |
--------------------------------------------------------------------------------
/accessibility-focus/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus - React Native
2 |
3 | In React Native you can move accessibility focus by using the [`setAccessibilityFocus`](https://reactnative.dev/docs/accessibilityinfo#setaccessibilityfocus) method from the [`AccessibilityInfo class`](https://reactnative.dev/docs/accessibilityinfo). This method requires a `reactTag`, which you can find by calling the `findNodeHandle` method.
4 |
5 | ```tsx
6 | function Component() {
7 | const ref = useRef(null);
8 |
9 | function setFocus() {
10 | const reactTag = findNodeHandle(ref.current);
11 |
12 | if (reactTag) {
13 | AccessibilityInfo.setAccessibilityFocus(reactTag);
14 | }
15 | }
16 |
17 | return
18 | };
19 | ```
20 |
--------------------------------------------------------------------------------
/screen-dark-mode/android.md:
--------------------------------------------------------------------------------
1 | # Dark mode - Android
2 |
3 | On Android, you can detect dark mode by checking if the [`uiMode`](https://developer.android.com/reference/android/content/res/Configuration#uiMode) configuration contains [`UI_MODE_NIGHT_MASK`](https://developer.android.com/reference/android/content/res/Configuration#UI_MODE_NIGHT_MASK).
4 |
5 | By adding `-night` resources to your project you can let Android automatically pick the right resources. For example, add a `colors.xml` file inside a `values-night` folder to specify night mode colors.
6 |
7 | ```kotlin
8 | fun Context.isInNightMode(): Boolean {
9 | val nightModeFlags = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
10 | return nightModeFlags == Configuration.UI_MODE_NIGHT_YES
11 | }
12 | ```
13 |
--------------------------------------------------------------------------------
/screen-title/xamarin.md:
--------------------------------------------------------------------------------
1 | # Screen title - Xamarin
2 |
3 | With Xamarin Forms, we recommend setting an appropriate [`Title`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.page.title?view=xamarin-forms#xamarin-forms-page-title) for each [`ContentPage`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.contentpage?view=xamarin-forms).
4 |
5 | ```xml
6 |
11 |
12 | ...
13 |
14 |
15 | ```
16 |
17 | ```csharp
18 | public NewPage()
19 | {
20 | SetBinding(Page.TitleProperty, new Binding("Appt homescreen"));
21 | }
22 | ```
23 |
--------------------------------------------------------------------------------
/accessibility-value/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility value - React Native
2 |
3 | In React Native you can use the [`accessibilityValue`](https://reactnative.dev/docs/accessibility#accessibilityvalue) and [`accessibilityState`](https://reactnative.dev/docs/accessibility#accessibilitystate) props to set an accessibility value. The `accessibilityValue` indicates the current value of a component. You can indicate a range, using `min`, `max`, and `no`, or text using `text`. The `accessibilityState` indicates the current state of a component, for example `disabled` or `checked`.
4 |
5 | ```jsx
6 |
9 |
10 |
13 | ```
14 |
--------------------------------------------------------------------------------
/accessibility-role/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility role - Xamarin
2 |
3 | Xamarin Forms does not have built-in support for setting an accessibility role.
4 |
5 | By using [`Effects`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/effects/introduction) it is possible to implement platform specific behaviour.
6 |
7 | The [`SemanticEffect`](https://github.com/xamarin/XamarinCommunityToolkit/blob/main/src/CommunityToolkit/Xamarin.CommunityToolkit/Effects/Semantic/SemanticEffect.shared.cs) file inside the [`Xamarin.CommunityToolkit`](https://github.com/xamarin/XamarinCommunityToolkit) defines various methods to set accessibility roles.
8 |
9 | ```xml
10 |
13 | ```
14 |
--------------------------------------------------------------------------------
/input-label/react-native.md:
--------------------------------------------------------------------------------
1 | # Input label - React Native
2 |
3 | In React Native, there is no attribute to link a label to an input field. We recommend combining [`Text`](https://reactnative.dev/docs/text) with a [`TextInput`](https://reactnative.dev/docs/textinput) component.
4 |
5 | You can also use a package for displaying instructions, such as [React Native Paper](https://callstack.github.io/react-native-paper/index.html). This package includes a [`TextInput`](https://callstack.github.io/react-native-paper/docs/components/TextInput/) component with a `label` property.
6 |
7 | ```jsx
8 | import { TextInput } from 'react-native-paper';
9 |
10 | const InputWithLabelComponent = () => {
11 | return (
12 |
16 | );
17 | };
18 | ```
19 |
--------------------------------------------------------------------------------
/input-errors/flutter.md:
--------------------------------------------------------------------------------
1 | # Input errors - Flutter
2 |
3 | With Flutter, you can set an [`InputDecoration`](https://api.flutter.dev/flutter/material/InputDecoration-class.html) on a [`TextField`](https://api.flutter.dev/flutter/material/TextField-class.html) to indicate an error. Set the `errorText` property to the error message that should be displayed. To remove the error, set the `errorText` to `null`. The error message should also be posted to assistive technologies by using an [`accessibility announcement`](../Techniques/accessibility-announcement.md).
4 |
5 | ```dart
6 | bool _hasError = false;
7 |
8 | TextField(
9 | decoration: InputDecoration(
10 | labelText: 'Date of birth',
11 | helperText: _hasError ? 'Invalid date, must be in the form DD/MM/YYYY, for example, 01/01/2000' : null,
12 | ),
13 | );
14 | ```
15 |
--------------------------------------------------------------------------------
/accessibility-dialog/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility dialog - .NET MAUI
2 |
3 | In .NET MAUI you can use the [`DisplayAlert`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.controls.page.displayalert?view=net-maui-8.0) method to show an alert. The last parameter of the method is the text of cancel button and it is required to supply it. Therefore, a cancel button is always shown! The focus of assistive technologies is automatically trapped inside the dialog while it is visible.
4 |
5 | The code sample below shows how to show a dialog.
6 |
7 | ```csharp
8 | var accept = await App.Current.MainPage.DisplayAlert(
9 | "Confirm Appt membership?",
10 | "Your bank account will be billed.",
11 | "Proceed",
12 | "Cancel"
13 | );
14 |
15 | if (accept) {
16 | // Proceed
17 | } else {
18 | // Cancel
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/input-cancellation/android.md:
--------------------------------------------------------------------------------
1 | # Input cancellation - Android
2 |
3 | On Android, you should avoid using the [`ACTION_DOWN`](https://developer.android.com/reference/android/view/MotionEvent#ACTION_DOWN) event of [`OnTouchListener`](https://developer.android.com/reference/android/view/View.OnTouchListener), because users will not be able to cancel their interaction. Actions should only be activated through an [`ACTION_UP`](https://developer.android.com/reference/android/view/MotionEvent#ACTION_UP) event. Use an [`OnClickListener`](https://developer.android.com/reference/android/view/View.OnClickListener) instead, because it has built-in support for cancellation.
4 |
5 | ```kotlin
6 | webView.setOnTouchListener { _, event ->
7 | if (event == MotionEvent.ACTION_DOWN) {
8 | // Use OnClickListener instead
9 | }
10 | }
11 | ```
12 |
--------------------------------------------------------------------------------
/input-motion/ios.md:
--------------------------------------------------------------------------------
1 | # Motion input - iOS
2 |
3 | On iOS, it is common to use the [`motionEnded`](https://developer.apple.com/documentation/uikit/uiresponder/1621090-motionended) method to detect motion.
4 |
5 | A motion event should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```swift
8 | import UIKit
9 |
10 | class MotionController: UIViewController {
11 |
12 | override var canBecomeFirstResponder: Bool{
13 | return true
14 | }
15 |
16 | override func viewDidAppear(_ animated: Bool) {
17 | super.viewDidAppear(animated)
18 | becomeFirstResponder()
19 | }
20 |
21 | override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
22 | // Provide alternative
23 | }
24 | }
25 | ```
26 |
--------------------------------------------------------------------------------
/text-localization/react-native.md:
--------------------------------------------------------------------------------
1 | # Localization - React Native
2 |
3 | In React Native, there is no standard for loading resources in your desired language. Various packages are available to help you achieve this. You can use [expo-localization](https://docs.expo.dev/versions/latest/sdk/localization) in combination with [i18n-js](https://github.com/fnando/i18n-js) to get the device locale and set translations for your app.
4 |
5 | ```jsx
6 | import * as Localization from 'expo-localization';
7 | import i18n from 'i18n-js';
8 |
9 | // Set the key-value pairs for the different languages you want to support.
10 | i18n.translations = {
11 | en: { welcome: 'Appt accessibility' },
12 | nl: { welcome: 'Appt toegankelijkheid' },
13 | };
14 |
15 | // Set the locale once at the beginning of your app.
16 | i18n.locale = Localization.locale;
17 | ```
18 |
--------------------------------------------------------------------------------
/element-identification/android.md:
--------------------------------------------------------------------------------
1 | # Element identification - Android
2 |
3 | In Android, you should create custom `Views` to re-use functionality on multiple screens.
4 |
5 | When using icons, use the search function of your `IDE` to check all instances. The icon should have the same `accessibility label` on each screen, and the functionality should also be the same.
6 |
7 | For example, when using a cross icon for closing a screen, make sure the label is 'Close' on all screens, and check that it always closes a screen.
8 |
9 | In Android Studio, you can use the `Find Usages` option to check if resources are used on multiple screens. Go to your `drawable` folder, right click and select the `Find Usages` option. You can also use the shortcut `Option + F7` on Mac, or `Alt + F7` on Windows.
10 |
11 | ```kotlin
12 | Not available, contribute!
13 | ```
14 |
--------------------------------------------------------------------------------
/text-localization/xamarin.md:
--------------------------------------------------------------------------------
1 | # Localization - Xamarin
2 |
3 | With Xamarin, you can use [`CultureInfo`](https://docs.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo?view=net-6.0) to set a language. For more information, see [String and Image localization in Xamarin Forms](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/localization/text?pivots=windows).
4 |
5 | ```csharp
6 | using System.Globalization;
7 | using System.Threading;
8 |
9 | CultureInfo ci = CultureInfo.GetCultureInfo(DependencyService.Get().Language);
10 |
11 | CultureInfo.DefaultThreadCurrentCulture = ci;
12 | CultureInfo.DefaultThreadCurrentUICulture = ci;
13 | AppResources.Culture = ci;
14 | CultureInfo.CurrentUICulture = ci;
15 | Thread.CurrentThread.CurrentUICulture = ci;
16 | Thread.CurrentThread.CurrentCulture = ci;
17 | ```
18 |
--------------------------------------------------------------------------------
/input-instructions/android.md:
--------------------------------------------------------------------------------
1 | # Input instructions - Android
2 |
3 | On Android, you can use a [`TextView`](https://developer.android.com/reference/android/widget/TextView) to show instructions.
4 |
5 | You can also use a [`TextInputLayout`](https://developer.android.com/reference/com/google/android/material/textfield/TextInputLayout), which contains a [`setHelperText`](https://developer.android.com/reference/com/google/android/material/textfield/TextInputLayout#setHelperText(java.lang.CharSequence)) method to provide instructions. To show instructions, you need to set [`setHelperTextEnabled`](https://developer.android.com/reference/com/google/android/material/textfield/TextInputLayout#setHelperTextEnabled(boolean)) to `true`.
6 |
7 | ```kotlin
8 | input.setHelperTextEnabled(true)
9 | input.setHelperText("Your password should be at least 8 characters.")
10 | ```
11 |
--------------------------------------------------------------------------------
/accessibility-modal/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility modal - Flutter
2 |
3 | On Flutter, the [`ModelBarrier`](https://api.flutter.dev/flutter/widgets/ModalBarrier-class.html) class takes accessibility into account. The [`barrierDismissable`](https://api.flutter.dev/flutter/widgets/ModalRoute/barrierDismissible.html) and [`barrierLabel`](https://api.flutter.dev/flutter/widgets/ModalRoute/barrierLabel.html) are used by assistive technologies. When `barrierDismissable` is set to false, the focus of assistive technologies is trapped inside the modal. The value of `barrierLabel` is announced upon entering the modal.
4 |
5 | ```dart
6 | showDialog(
7 | context: context,
8 | barrierDismissible: false,
9 | barrierLabel: 'Label'
10 | builder: (context) {
11 | return SimpleDialog(
12 | title: Text('Appt')
13 | );
14 | },
15 | );
16 | ```
17 |
--------------------------------------------------------------------------------
/screen-timing/xamarin.md:
--------------------------------------------------------------------------------
1 | # Adjustable timing - Xamarin
2 |
3 | In Xamarin, the `SnackBar` view from the [`Xamarin.CommunityToolkit`](https://github.com/xamarin/XamarinCommunityToolkit) is often used to display temporary messages. The display duration might be too short for people to read or hear the message.
4 |
5 | When using `SnackBar`, set the `Duration` to `Int32.MaxValue`. Or, use [`DisplayAlert`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.page.displayalert?view=xamarin-forms) method to show an alert instead.
6 |
7 | Also make sure that the use of time limits, e.g. by using [`Timer`](https://learn.microsoft.com/en-us/dotnet/api/System.Threading.Timer?view=net-7.0), can be extended.
8 |
9 | ```csharp
10 | var result = await page.DisplaySnackBarAsync("Appt", "Close", async () =>
11 | { /* Action */ },
12 | Int32.MaxValue
13 | );
14 | ```
15 |
--------------------------------------------------------------------------------
/accessibility-group/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility group - iOS
2 |
3 | On iOS, you can group elements by setting [`isAccessibilityElement`](https://developer.apple.com/documentation/objectivec/nsobject/1615141-isaccessibilityelement) to `true` on the parent element. Don't forget to set an [`accessibilityLabel`](https://developer.apple.com/documentation/objectivec/nsobject/1615181-accessibilitylabel) for the group.
4 |
5 | Sometimes it can be useful to also the [`shouldGroupAccessibilityChildren`](https://developer.apple.com/documentation/objectivec/nsobject/1615143-shouldgroupaccessibilitychildren) property to group the accessibility elements that are children of the element, regardless of their positions on the screen.
6 |
7 | ```swift
8 | group.isAccessibilityElement = true
9 | group.shouldGroupAccessibilityChildren = true
10 | group.accessibilityLabel = "Appt group"
11 | ```
12 |
--------------------------------------------------------------------------------
/media-captions/android.md:
--------------------------------------------------------------------------------
1 | # Captions - Android
2 |
3 | On Android, captions can be added by using [`TimedText`](https://developer.android.com/reference/android/media/TimedText) inside a [`MediaPlayer`](https://developer.android.com/reference/android/media/MediaPlayer). The code example below shows a basic example.
4 |
5 | ```kotlin
6 | val player = MediaPlayer.create(this, R.raw.video)
7 | try {
8 | player.addTimedTextSource("/assets/appt.srt", MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP)
9 | player.trackInfo.forEachIndexed { index, trackInfo ->
10 | if (trackInfo.trackType == TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
11 | player.selectTrack(index)
12 | return@forEachIndexed
13 | }
14 | }
15 | player.setOnTimedTextListener(this)
16 | player.start()
17 | } catch (e: Exception) {
18 | e.printStackTrace()
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/media-captions/react-native.md:
--------------------------------------------------------------------------------
1 | # Captions - React Native
2 |
3 | In React Native, you can use the [React-Native-Video](https://github.com/react-native-video/react-native-video/blob/master/API.md#texttracks) package to add captions in `.vtt`, `.ttml` and `.srt` formats. It is advised to use `.vtt` as it is supported on both Android and iOS.
4 |
5 | ```jsx
6 | import { TextTrackType, Video } from 'react-native-video';
7 |
8 |
24 | ```
25 |
--------------------------------------------------------------------------------
/accessibility-focus/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus - iOS
2 |
3 | On iOS, you can use [`UIAccessibility`](https://developer.apple.com/documentation/objectivec/nsobject/uiaccessibility) to [`post`](https://developer.apple.com/documentation/uikit/uiaccessibility/1615194-post) a notification to move the focus of assistive technologies. Use [`screenChanged`](https://developer.apple.com/documentation/uikit/uiaccessibility/notification/1620198-screenchanged/) when a new view appears that occupies a major portion of the screen. Otherwise, use [`layoutChanged`](https://developer.apple.com/documentation/uikit/uiaccessibility/notification/1620186-layoutchanged) when the layout of current screen changes.
4 |
5 | ```swift
6 | func focus(_ view: UIView) {
7 | UIAccessibility.post(notification: .layoutChanged, argument: view)
8 | UIAccessibility.post(notification: .screenChanged, argument: view)
9 | }
10 | ```
11 |
--------------------------------------------------------------------------------
/keyboard-shortcuts/flutter.md:
--------------------------------------------------------------------------------
1 | # Keyboard shortcuts - Flutter
2 |
3 | With Flutter, you can use the [`RawKeyboard`](https://api.flutter.dev/flutter/services/RawKeyboard-class.html) listener to implement shortcuts in your app. The `RawKeyboard` listener yields a [`RawKeyUpEvent`](https://api.flutter.dev/flutter/services/RawKeyUpEvent-class.html) of a [`RawKeyDownEvent`](https://api.flutter.dev/flutter/services/RawKeyDownEvent-class.html). The `data` attribute has a `isModifierPressed()` method that can be used to determine whether a modifier key has been pressed.
4 |
5 | ```dart
6 | RawKeyboard.instance.addListener((keyEvent) {
7 | if (keyEvent is RawKeyUpEvent) {
8 | if (keyEvent.logicalKey == LogicalKeyboardKey.keyF &&
9 | keyEvent.data.isModifierPressed(ModifierKey.controlModifier)) {
10 | find();
11 | }
12 | }
13 | });
14 |
15 | void find() {
16 | // Logic
17 | }
18 | ```
19 |
--------------------------------------------------------------------------------
/accessibility-live-region/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility live region - Xamarin
2 |
3 | Xamarin Forms does not have built-in support to indicate an accessibility live region. By using [`Effects`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/effects/introduction) it is possible to implement platform specific behaviour. The [`A11YEffect`](https://github.com/appt-org/accessibility-code-examples/blob/main/Xamarin/en/A11yEffect.md), [`A11YEffect for Android`](https://github.com/appt-org/accessibility-code-examples/blob/main/Xamarin/en/A11yEffect_Android.md) and [`A11YEffect for iOS`](https://github.com/appt-org/accessibility-code-examples/blob/main/Xamarin/en/A11yEffect_iOS.md) files show how to implement an `effect` to replicate an accessibility live region.
4 |
5 | ```xml
6 |
8 | ```
9 |
--------------------------------------------------------------------------------
/screen-timing/ios.md:
--------------------------------------------------------------------------------
1 | # Adjustable timing - iOS
2 |
3 | On iOS, third-party code libraries are sometimes used to display a temporary message, also known as a `Toast`. The display duration might be too short for people to read or hear the message.
4 |
5 | We recommend showing messages by using an [`UIAlertController`](https://developer.apple.com/documentation/uikit/uialertcontroller). Don't forget to add a close button.
6 |
7 | Also check whether [`DispatchQueue`](https://developer.apple.com/documentation/dispatch/dispatchqueue) is used somewhere. If there are time limits, make sure they can be extended.
8 |
9 | ```swift
10 | let alert = UIAlertController(
11 | title: nil,
12 | message: "Appt",
13 | preferredStyle: .alert
14 | )
15 |
16 | alert.addAction(UIAlertAction(title: "Close", style: .default, handler: { action in
17 | // Close
18 | }))
19 |
20 | present(alert, animated: true)
21 | ```
22 |
--------------------------------------------------------------------------------
/accessibility-value/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility value - iOS
2 |
3 | On iOS, you can set an accessibility value with the [`accessibilityValue`](https://developer.apple.com/documentation/uikit/uiaccessibilityelement/1619583-accessibilityvalue) or [`accessibilityAttributedValue`](https://developer.apple.com/documentation/objectivec/nsobject/2866105-accessibilityattributedvalue/) property.
4 |
5 | When using the semantically correct element, you usually do not need to modify the `accessibilityValue`. For example, a [`UISwitch`](https://developer.apple.com/documentation/uikit/uiswitch) sets the `accessibilityValue` to `selected` or `not selected` and a [`UISlider`](https://developer.apple.com/documentation/uikit/uislider) sets the `accessibilityValue` to the current value. If the default value is incorrect or unclear, you can override the value manually.
6 |
7 | ```swift
8 | element.accessibilityValue = "Custom"
9 | ```
10 |
--------------------------------------------------------------------------------
/input-cancellation/xamarin.md:
--------------------------------------------------------------------------------
1 | # Input cancellation - Xamarin
2 |
3 | In Xamarin.Forms, be careful when building a [`CustomRenderer`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/) to detect touch events. Make sure not to use the down event for actions. For tap events, you should use [`TapGestureRecognizer`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.tapgesturerecognizer?view=xamarin-forms).
4 |
5 | ```csharp
6 | // Android CustomRenderer
7 | public override bool OnTouchEvent(MotionEvent event)
8 | {
9 | if (e.Action == MotionEventActions.Down)
10 | {
11 | // Don't use down event
12 | }
13 | return base.OnTouchEvent(event);
14 | }
15 |
16 | // iOS CustomRenderer
17 | public override void TouchesBegan(NSSet touches, UIEvent event)
18 | {
19 | // Don't use down event
20 | base.TouchesBegan(touches, event);
21 | }
22 | ```
23 |
--------------------------------------------------------------------------------
/media-audio-description/android.md:
--------------------------------------------------------------------------------
1 | # Audio description - Android
2 |
3 | As of Android 4.1, the [`MediaPlayer`](https://developer.android.com/reference/android/media/MediaPlayer) has support for multiple audio tracks. Use the [`selectTrack`](https://developer.android.com/reference/android/media/MediaPlayer#selectTrack(int)) method to select the correct audio track.
4 |
5 | The code example belows shows a basic implementation of selecting an audio description track embedded inside a video.
6 |
7 | ```kotlin
8 | val player = MediaPlayer.create(this, R.raw.video)
9 | try {
10 | player.trackInfo.forEachIndexed { index, trackInfo ->
11 | if (trackInfo.trackType == TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
12 | player.selectTrack(index)
13 | return@forEachIndexed
14 | }
15 | }
16 | player.start()
17 | } catch (e: Exception) {
18 | e.printStackTrace()
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/accessibility-action/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility action - Flutter
2 |
3 | With Flutter, you can use [`CustomSemanticsAction`](https://api.flutter.dev/flutter/semantics/CustomSemanticsAction/CustomSemanticsAction.html) to add custom actions for assistive technologies. To implement specific functionality for assistive technologies it is also possible to add `onTap`, `onLongPress` or other callbacks to the `Semantics` widget. When you do this, it is important to make sure the child nodes do not implement a touch listener, or to use `excludeSemantics` to ignore these with the assistive technologies.
4 |
5 | ```dart
6 | Semantics(
7 | customSemanticsActions: {
8 | CustomSemanticsAction(label: 'Increment'): _incrementCounter,
9 | },
10 | onTap: () {
11 | _incrementCounter
12 | },
13 | excludeSemantics: true,
14 | child: TextButton(...)
15 | );
16 | ```
17 |
--------------------------------------------------------------------------------
/input-gestures/android.md:
--------------------------------------------------------------------------------
1 | # Input gestures - Android
2 |
3 | On Android, the [`GestureDetector`](https://developer.android.com/reference/android/view/GestureDetector) and [`OnGestureListener`](https://developer.android.com/reference/android/view/GestureDetector.OnGestureListener) objects are a common way to detect gestures.
4 |
5 | A gesture should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```kotlin
8 | val scaleGestureDetector = ScaleGestureDetector(
9 | this,
10 | object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
11 | override fun onScale(detector: ScaleGestureDetector): Boolean {
12 | // Provide alternative
13 | return super.onScale(detector)
14 | }
15 | }
16 | )
17 |
18 | view.setOnTouchListener { _, event ->
19 | scaleGestureDetector.onTouchEvent(event)
20 | }
21 | ```
22 |
--------------------------------------------------------------------------------
/accessibility-focusable/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility focusable - .NET MAUI
2 |
3 | In .NET MAUI, the [`IsInAccessibleTree`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.controls.automationproperties.isinaccessibletreeproperty?view=net-maui-8.0#microsoft-maui-controls-automationproperties-isinaccessibletreeproperty) property indicates whether assistive technologies can focus on an element.
4 |
5 | Also, the [`ExcludedWithChildren`] (https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.controls.automationproperties.excludedwithchildrenproperty?view=net-maui-8.0#microsoft-maui-controls-automationproperties-excludedwithchildrenproperty) property determines if an element and its children can be focused by assistive technologies.
6 |
7 | ```xml
8 |
10 |
11 |
12 | ...
13 |
14 | ```
15 |
--------------------------------------------------------------------------------
/screen-dark-mode/react-native.md:
--------------------------------------------------------------------------------
1 | # Dark mode - React Native
2 |
3 | With React Native, you can detect dark mode by checking if the [`Appearance.getColorScheme()`](https://reactnative.dev/docs/appearance#getcolorscheme) method returns `dark`.
4 |
5 | When defining a [`ThemeProvider`](https://reactnativeelements.com/docs/customization/themprovider) you can return a different theme when dark mode is active.
6 |
7 | ```jsx
8 | import { useColorScheme } from 'react-native';
9 | import { ThemeProvider } from 'styled-components';
10 |
11 | const darkTheme = {
12 | primary: "#f967e9",
13 | };
14 |
15 | const lighTheme = {
16 | primary: "#cc00b9"
17 | };
18 |
19 | const App: React.FC = () => {
20 | const scheme = useColorScheme();
21 | return (
22 |
23 | {props.children}
24 |
25 | );
26 | }
27 |
28 | export default App;
29 | ```
30 |
--------------------------------------------------------------------------------
/screen-skip/android.md:
--------------------------------------------------------------------------------
1 | # Skip content - Android
2 |
3 | On Android, skipping content is mostly relevant to [`TalkBack`](https://appt.org/en/docs/android/features/talkback) users. TalkBack includes a `local context menu` which allows users to jump to the following content types:
4 |
5 | - Headings
6 | - Links
7 | - Controls
8 | - Text
9 | - Paragraphs
10 | - Lines
11 | - Characters
12 | - Words
13 |
14 | Jumping to `headings` and `links` is used most often.
15 |
16 | Provide appropriate accessibility markup to your content by using [`ViewCompat`](https://developer.android.com/reference/androidx/core/view/ViewCompat) and [`AccessibilityNodeInfoCompat`](https://developer.android.com/reference/androidx/core/view/accessibility/AccessibilityNodeInfoCompat).
17 |
18 | ```kotlin
19 | // Mark headings
20 | ViewCompat.setAccessibilityHeading(heading, true)
21 |
22 | // Mark links
23 | ViewCompat.enableAccessibleClickableSpanSupport(link)
24 | ```
25 |
--------------------------------------------------------------------------------
/accessibility-state/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility state - iOS
2 |
3 | On iOS, the [`accessibilityTraits`](https://developer.apple.com/documentation/objectivec/nsobject/1615202-accessibilitytraits) attribute can be used to indicate the accessibility state. The traits [`selected`](https://developer.apple.com/documentation/uikit/uiaccessibilitytraits/1620197-selected) and [`notEnabled`](https://developer.apple.com/documentation/uikit/uiaccessibilitytraits/1620208-notenabled) can be used to indicate the current state.
4 |
5 | If your state is not `selected` or `notEnabled`, we recommended using the [`accessibilityValue`](https://developer.apple.com/documentation/uikit/uiaccessibilityelement/1619583-accessibilityvalue) attribute to indicate the state.
6 |
7 | ```swift
8 | element.accessibilityTraits = .selected
9 | element.accessibilityTraits = .notEnabled
10 |
11 | element.accessibilityValue = "Expanded"
12 | element.accessibilityValue = "Collapsed"
13 | ```
14 |
--------------------------------------------------------------------------------
/input-instructions/react-native.md:
--------------------------------------------------------------------------------
1 | # Input instructions - React Native
2 |
3 | In React Native, there is no default component to combine an input field with a label. We recommend combining [`Text`](https://reactnative.dev/docs/text) with a [`TextInput`](https://reactnative.dev/docs/textinput) component.
4 |
5 | You can also use a package for displaying instructions, such as [React Native Paper](https://callstack.github.io/react-native-paper/index.html). This package includes a [`HelperText`](https://callstack.github.io/react-native-paper/docs/components/HelperText/) component which can be used for displaying instructions. The type should be set to `info` for instructions.
6 |
7 | ```jsx
8 | Your password should be at least 8 characters.
9 |
10 |
11 |
12 |
13 | Your password should be at least 8 characters.
14 |
15 |
16 | ```
17 |
--------------------------------------------------------------------------------
/text-spacing/flutter.md:
--------------------------------------------------------------------------------
1 | # Text spacing - Flutter
2 |
3 | With Flutter, it is possible to set spacing in text with [`TextStyle`](https://api.flutter.dev/flutter/painting/TextStyle-class.html). This can be done globally in the [`ThemeData`](https://api.flutter.dev/flutter/material/ThemeData-class.html) or within a [`Text`](https://api.flutter.dev/flutter/widgets/Text-class.html) via the `style` parameter.
4 |
5 | With the `TextStyle` class you can use the following attributes for spacing in the text:
6 |
7 | - [`height`](https://api.flutter.dev/flutter/painting/TextStyle/height.html): set spacing between lines.
8 | - [`letterSpacing`](https://api.flutter.dev/flutter/painting/TextStyle/letterSpacing.html): set extra spacing between letters.
9 | - [`wordSpacing`](https://api.flutter.dev/flutter/painting/TextStyle/wordSpacing.html): adds extra spacing to whitespace.
10 |
11 | ```dart
12 | TextStyle(
13 | height: 1.5,
14 | letterSpacing: 3.0,
15 | wordSpacing: 5.0
16 | );
17 | ```
18 |
--------------------------------------------------------------------------------
/accessibility-announcement/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility announcement - Android
2 |
3 | On Android, you can post an accessibility message by using the [`AccessibilityManager`](https://developer.android.com/reference/android/view/accessibility/AccessibilityManager) object. Create an [`AccessibilityEvent`](https://developer.android.com/reference/android/view/accessibility/AccessibilityEvent), set the type to [`AccessibilityEvent.TYPE_ANNOUNCEMENT`](https://developer.android.com/reference/android/view/accessibility/AccessibilityEvent#TYPE_ANNOUNCEMENT) and supply a message.
4 |
5 | ```kotlin
6 | val type = AccessibilityEventCompat.TYPE_ANNOUNCEMENT
7 |
8 | val event = AccessibilityEvent.obtain(type)
9 | event.text.add("Appt announcement")
10 | event.className = Context::class.java.name
11 | event.packageName = packageName
12 |
13 | val accessibilityManager = ContextCompat.getSystemService(this, AccessibilityManager::class.java)
14 | accessibilityManager?.sendAccessibilityEvent(event)
15 | ```
16 |
--------------------------------------------------------------------------------
/keyboard-order/xamarin.md:
--------------------------------------------------------------------------------
1 | # Keyboard order - Xamarin
2 |
3 | Xamarin Forms supports changing the keyboard order through the [`TabIndex`](https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.visualelement.tabindex?view=xamarin-forms) property. The default value is 0. The lower the value, the higher the priority.
4 |
5 | The [`IsTabStop`](https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.visualelement.istabstop?view=xamarin-forms) property can be used to exclude elements from tabbed navigation.
6 |
7 | Read more about [Keyboard Accessibility in Xamarin.Forms](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/keyboard).
8 |
9 | The code example below shows how exclude the label from receiving keyboard focus, and how to reach the save button before reaching the cancel button.
10 |
11 | ```xml
12 |
13 |
14 |
15 | ```
16 |
--------------------------------------------------------------------------------
/screen-dark-mode/flutter.md:
--------------------------------------------------------------------------------
1 | # Dark mode - Flutter
2 |
3 | With Flutter, you can detect dark mode by checking if the [`platformBrightness`](https://api.flutter.dev/flutter/widgets/MediaQueryData/platformBrightness.html) has been set to [`Brightness.dark`](https://api.flutter.dev/flutter/dart-ui/Brightness.html#values).
4 |
5 | When defining an `App`, you can define a `darkTheme` to letter Flutter automatically use dark mode resources.
6 |
7 | ```dart
8 | import 'dart:ui';
9 | import 'package:flutter/widgets.dart';
10 |
11 | /// Dark mode extension
12 | extension DarkMode on BuildContext {
13 | bool get isDarkMode {
14 | return MediaQuery.of(this).platformBrightness == Brightness.dark;
15 | }
16 | }
17 |
18 | /// Define dark theme
19 | MaterialApp(
20 | themeMode: ThemeMode.system,
21 | theme: ThemeData(
22 | brightness: Brightness.light,
23 | primaryColor: Colors.red,
24 | ),
25 | darkTheme: ThemeData(
26 | brightness: Brightness.dark,
27 | ),
28 | );
29 | ```
30 |
--------------------------------------------------------------------------------
/screen-animations/android.md:
--------------------------------------------------------------------------------
1 | # Reduced animations - Android
2 |
3 | On Android, you should provide buttons to pause, stop or hide content. You could use the [`ANIMATOR_DURATION_SCALE`](https://developer.android.com/reference/android/provider/Settings.Global#ANIMATOR_DURATION_SCALE) and/or [`TRANSITION_ANIMATION_SCALE`](https://developer.android.com/reference/android/provider/Settings.Global#TRANSITION_ANIMATION_SCALE) preferences to check if animations should be disabled. If either value is `zero`, you could choose to disable (non-essential) animations in your app.
4 |
5 | ```kotlin
6 | val duration = Settings.Global.getFloat(
7 | context.getContentResolver(),
8 | Settings.Global.ANIMATOR_DURATION_SCALE,
9 | 1f
10 | )
11 |
12 | val transition = Settings.Global.getFloat(
13 | context.getContentResolver(),
14 | Settings.Global.TRANSITION_ANIMATION_SCALE,
15 | 1f
16 | )
17 |
18 | if (duration == 0f || transition == 0f) {
19 | // Disable animations
20 | }
21 | ```
22 |
--------------------------------------------------------------------------------
/keyboard-order/react-native.md:
--------------------------------------------------------------------------------
1 | # Keyboard order - React Native
2 |
3 | React Native has implemented all Android keyboard focus properties.
4 |
5 | - [`nextFocusForward`](https://reactnative.dev/docs/view#nextfocusforward-android): specify the next element to move focus to
6 | - [`nextFocusUp`](https://reactnative.dev/docs/view#nextfocusup-android): specify which element should receive focus when navigating up
7 | - [`nextFocusDown`](https://reactnative.dev/docs/view#nextfocusdown-android): specify which element should receive focus when navigating down
8 | - [`nextFocusLeft`](https://reactnative.dev/docs/view#nextfocusleft-android): specify which element should receive focus when navigating left
9 | - [`nextFocusRight`](https://reactnative.dev/docs/view#nextfocusright-android): specify which element should receive focus when navigating right
10 |
11 | It seems that none of the iOS keyboard focus properties have been implemented by React Native.
12 |
13 | ```jsx
14 | Not available, contribute!
15 | ```
16 |
--------------------------------------------------------------------------------
/text-localization/ios.md:
--------------------------------------------------------------------------------
1 | # Localization - iOS
2 |
3 | On iOS, you can set the locale of an app via the [`CFBundleDevelopmentRegion`](http://cfbundledevelopmentregion) property. We suggest using `Base internationalization` to separate user-facing strings from `.storyboard` and `.xib files`. You can load a specific [`Bundle`](https://developer.apple.com/documentation/foundation/bundle) to load assets in the desired language.
4 |
5 | For more information, see [Adding Support for Languages and Regions](https://developer.apple.com/documentation/xcode/adding-support-for-languages-and-regions).
6 |
7 | ```swift
8 | extension String {
9 | func localized(_ language: String) -> String {
10 | guard let path = Bundle.main.path(forResource: language, ofType: "lproj"),
11 | let bundle = Bundle(path: path) else {
12 | return localized(Bundle.main)
13 | }
14 | return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "")
15 | }
16 | }
17 | ```
18 |
--------------------------------------------------------------------------------
/media-audio-description/flutter.md:
--------------------------------------------------------------------------------
1 | # Audio description - Flutter
2 |
3 | With Flutter, you can use [`better_player`](https://pub.dev/packages/better_player) to let users select different audio tracks.
4 |
5 | The code example belows shows a basic implementation of changing audio tracks.
6 |
7 | ```dart
8 | BetterPlayerController controller = BetterPlayerController(
9 | const BetterPlayerConfiguration(
10 | controlsConfiguration: BetterPlayerControlsConfiguration(
11 | enableAudioTracks: true,
12 | ),
13 | ),
14 | betterPlayerDataSource: BetterPlayerDataSource.file(
15 | 'assets/appt.mp4',
16 | useAsmsSubtitles: true,
17 | ),
18 | );
19 |
20 | void changeAudioTrack(int track) {
21 | if (controller.betterPlayerAsmsAudioTracks?[track] != null) {
22 | controller.setAudioTrack(controller.betterPlayerAsmsAudioTracks![track]);
23 | }
24 | }
25 |
26 | @override
27 | Widget build(BuildContext context) {
28 | return BetterPlayer(controller: controller);
29 | }
30 | ```
31 |
--------------------------------------------------------------------------------
/keyboard-shortcuts/ios.md:
--------------------------------------------------------------------------------
1 | # Keyboard shortcuts - iOS
2 |
3 | On iOS, the [`pressesBegan`](https://developer.apple.com/documentation/uikit/uiresponder/1621134-pressesbegan) and [`pressesEnded`](https://developer.apple.com/documentation/uikit/uiresponder/1621128-pressesended) can be used to activate shortcuts. But, you should use [`UIKeyCommand`](https://developer.apple.com/documentation/uikit/uikeycommand) to add keyboard shortcuts. By adding [`modifierFlags`](https://developer.apple.com/documentation/uikit/uikeymodifierflags) you can be sure that shortcuts are not activated by accident. An additional advantage is that `UIKeyCommand`-shortcuts are shown when long pressing the command key.
4 |
5 | ```swift
6 | let find = UIKeyCommand(
7 | input: "f",
8 | modifierFlags: .command,
9 | action: #selector(findContent),
10 | discoverabilityTitle: "Find"
11 | )
12 |
13 | override var keyCommands: [UIKeyCommand]? {
14 | return [find]
15 | }
16 |
17 | @objc private func find() {
18 | // Logic
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/screen-timing/flutter.md:
--------------------------------------------------------------------------------
1 | # Adjustable timing - Flutter
2 |
3 | In Flutter, a [`SnackBar`](https://api.flutter.dev/flutter/material/SnackBar-class.html) is often used display temporary messages. The display duration might be too short for people to read or hear the message.
4 |
5 | We recommend displaying messages by using an [`AlertDialog`](https://api.flutter.dev/flutter/material/AlertDialog-class.html). Or, when using a `Snackbar`, you can set the duration to "`infinite`". Don't forget to add a close button for both options.
6 |
7 | Also make sure that the use of time limits, e.g. by using [`Future.delayed()`](https://api.flutter.dev/flutter/dart-async/Future/Future.delayed.html), can be extended.
8 |
9 | ```dart
10 | ScaffoldMessenger.of(context).showSnackBar(SnackBar(
11 | duration: const Duration(days: 1),
12 | content: Text('Appt'),
13 | action: SnackBarAction(
14 | label: 'Close',
15 | onPressed: () {
16 | ScaffoldMessenger.of(context).hideCurrentSnackBar();
17 | },
18 | ),
19 | ));
20 | ```
21 |
--------------------------------------------------------------------------------
/accessibility-link/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility link - React Native
2 |
3 | In React Native, links should have their [`accessibilityRole`](https://reactnative.dev/docs/accessibility#accessibilityrole) set to `link`. You can use [`accessibilityLabel`](https://reactnative.dev/docs/accessibility#accessibilitylabel) or [`accessibilityHint`](https://reactnative.dev/docs/accessibility#accessibilityhint) to provide additional context.
4 |
5 | To create text links, you can embed a [`Text`](https://reactnative.dev/docs/text) component inside a [`Pressable`](https://reactnative.dev/docs/pressable) component.
6 |
7 | The [`Linking API`](https://reactnative.dev/docs/linking) can be used to open links.
8 |
9 | ```jsx
10 | {
12 | const supported = await Linking.canOpenURL(url);
13 | if (supported) {
14 | await Linking.openURL(url);
15 | }
16 | }}
17 | accessibilityRole="link"
18 | accessibilityLabel="Appt"
19 | accessibilityHint="External link"
20 | >
21 | Appt
22 |
23 | ```
24 |
--------------------------------------------------------------------------------
/input-errors/react-native.md:
--------------------------------------------------------------------------------
1 | # Input errors - React Native
2 |
3 | In React Native we recommend using a [`Text`](https://reactnative.dev/docs/text) component to display an error. The error message should also be posted to assistive technologies by using an [`accessibility announcement`](../Techniques/accessibility-announcement.md).
4 |
5 | You can also use a package for displaying errors, such as [React Native Paper](https://callstack.github.io/react-native-paper/index.html). This package includes a [`HelperText`](https://callstack.github.io/react-native-paper/docs/components/HelperText/) component which can be used for displaying errors. The type should be set to `error` for errors.
6 |
7 | ```jsx
8 | Invalid date, must be in the form DD/MM/YYYY, for example, 01/01/2000
9 |
10 |
11 |
12 |
13 | Invalid date, must be in the form DD/MM/YYYY, for example, 01/01/2000
14 |
15 |
16 | ```
17 |
--------------------------------------------------------------------------------
/text-scale/react-native.md:
--------------------------------------------------------------------------------
1 | # Scale text - React Native
2 |
3 | React Native automatically scales text depending on the font size preferences of the user settings. In addition, all dimensions in React Native are unitless, and represent density-independent pixels.
4 |
5 | Try to avoid using properties such as [`maxFontSizeMultiplier`](https://reactnative.dev/docs/text#maxfontsizemultiplier), [`allowFontScaling`](https://reactnative.dev/docs/text#allowfontscaling), [`adjustsFontSizeToFit`](https://reactnative.dev/docs/text#adjustsfontsizetofit) and [`numberOfLines`](https://reactnative.dev/docs/text#numberoflines). Using these properties may cause text to be unscalable or become inaccessible.
6 |
7 | When inheriting a project you may find previous developers have disabled font-scaling with the following code: `Text.defaultProps.allowFontScaling = false;`. This is accessibility anti-pattern and should be rolled back.
8 |
9 | The code example below shows how to have a scaling font size.
10 |
11 | ```jsx
12 |
13 | Appt
14 |
15 | ```
16 |
--------------------------------------------------------------------------------
/input-motion/android.md:
--------------------------------------------------------------------------------
1 | # Motion input - Android
2 |
3 | On Android, the [`SensorManager`](https://developer.android.com/reference/android/hardware/SensorManager) can be used in combination with [`SensorEventListener`](https://developer.android.com/reference/android/hardware/SensorEventListener) to detect movement.
4 |
5 | An event through sensors should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```kotlin
8 | class SensorActivity : AppCompatActivity(), SensorEventListener {
9 |
10 | override fun onCreate(savedInstanceState: Bundle?) {
11 | super.onCreate(savedInstanceState)
12 |
13 | val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
14 | val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
15 | sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL)
16 | }
17 |
18 | override fun onSensorChanged(event: SensorEvent?) {
19 | // Add alternative
20 | }
21 | }
22 | ```
23 |
--------------------------------------------------------------------------------
/accessibility-live-region/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility live region - Android
2 |
3 | On Android, a live region can be set by using the convience method [`setAccessibilityLiveRegion`](https://developer.android.com/reference/androidx/core/view/ViewCompat#setAccessibilityLiveRegion(android.view.View,int)) of [`ViewCompat`](https://developer.android.com/reference/androidx/core/view/ViewCompat). To interrupt ingoing speech, also known as being assertive, use [`ACCESSIBILITY_LIVE_REGION_ASSERTIVE`](https://developer.android.com/reference/kotlin/androidx/core/view/ViewCompat#ACCESSIBILITY_LIVE_REGION_ASSERTIVE()). To wait for ongoing speech, also known as being polite, use [`ACCESSIBILITY_LIVE_REGION_POLITE`](https://developer.android.com/reference/kotlin/androidx/core/view/ViewCompat#ACCESSIBILITY_LIVE_REGION_POLITE()).
4 |
5 | ```kotlin
6 | // Interrupt ongoing speech
7 | ViewCompat.setAccessibilityLiveRegion(view, ViewCompat.ACCESSIBILITY_LIVE_REGION_ASSERTIVE)
8 |
9 | // Wait for ongoing speech
10 | ViewCompat.setAccessibilityLiveRegion(view, ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE)
11 | ```
12 |
--------------------------------------------------------------------------------
/media-captions-live/ios.md:
--------------------------------------------------------------------------------
1 | # Live captions - iOS
2 |
3 | On iOS, [`AVPlayer`](https://developer.apple.com/documentation/avfoundation/avplayer) has built-in support for [live video](https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/using_avfoundation_to_play_and_persist_http_live_streams) with [captions](https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/adding_subtitles_and_alternative_audio_tracks). Users can [automatically turn on captions](https://support.apple.com/guide/iphone/subtitles-and-captions-iph3e2e23d1/ios) via System Preferences. The easiest way to stream a live video is through [`AVPlayerViewController`](https://developer.apple.com/documentation/avkit/avplayerviewcontroller).
4 |
5 | ```swift
6 | guard let url = URL(string: "https://appt.org/live-video") else {
7 | return
8 | }
9 | let player = AVPlayer(url: url)
10 |
11 | let playerViewController = AVPlayerViewController()
12 | playerViewController.player = player
13 |
14 | present(playerViewController, animated: true) {
15 | player.play()
16 | }
17 | ```
18 |
--------------------------------------------------------------------------------
/accessibility-dialog/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility dialog - iOS
2 |
3 | On iOS, you can [show alerts](https://developer.apple.com/design/human-interface-guidelines/ios/views/alerts/) by using [`UIAlertController`](https://developer.apple.com/documentation/uikit/uialertcontroller). Set the `style` to [`alert`](https://developer.apple.com/documentation/uikit/uialertcontroller/style/alert) to display a dialog. You should always add a close action in the [`cancel`](https://developer.apple.com/documentation/uikit/uialertaction/style/cancel) style. The focus of assistive technologies is automatically trapped inside the alert while it's visible.
4 |
5 | ```swift
6 | let alert = UIAlertController(
7 | title: "Confirm Appt membership?",
8 | message: "Your bank account will be billed.",
9 | preferredStyle: .alert
10 | )
11 |
12 | alert.addAction(UIAlertAction(title: "Proceed", style: .default, handler: { action in
13 | // Proceed
14 | }))
15 |
16 | alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { action in
17 | // Cancel
18 | }))
19 |
20 | present(alert, animated: true)
21 | ```
22 |
--------------------------------------------------------------------------------
/element-focus/flutter.md:
--------------------------------------------------------------------------------
1 | # Element focus change - Flutter
2 |
3 | In Flutter, you can use [`FocusNode`](https://api.flutter.dev/flutter/widgets/FocusNode-class.html) to listen to focus changes. The [`flutter_hooks`](https://pub.dev/packages/flutter_hooks) package includes a method named [`useFocusNode`](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useFocusNode.html) which makes it easier to listen to to focus changes.
4 |
5 | Be careful when using the `FocusNode` listener: do not trigger any context change because they might confuse users.
6 |
7 | ```dart
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_hooks/flutter_hooks.dart';
10 |
11 | class FocusWidget extends HookWidget {
12 | @override
13 | Widget build(BuildContext context) {
14 | final focusNode = useFocusNode();
15 | useEffect(() {
16 | focusNode.addListener(() {
17 | // Do not change context
18 | });
19 | return;
20 | }, [focusNode]);
21 |
22 | return TextField(focusNode: focusNode);
23 | }
24 | }
25 | ```
26 |
--------------------------------------------------------------------------------
/accessibility-dialog/react-native.md:
--------------------------------------------------------------------------------
1 | # Accessibility dialog - React Native
2 |
3 | In React Native, you can use [`Alert`](https://reactnative.dev/docs/alert) to show a dialog. On [Android](https://reactnative.dev/docs/alert#android) you can add a neutral, negative and positive button, this is based on the amount of buttons that are set. On iOS it's possible to set the [AlertButtonStyle](https://reactnative.dev/docs/alert#alertbuttonstyle-ios) for each button. You should always include a button to close the dialog. The focus of assistive technologies is automatically trapped inside the dialog while it's visible.
4 |
5 | ```jsx
6 | Alert.alert(
7 | "Confirm Appt membership?",
8 | "Your bank account will be billed.",
9 | [
10 | {
11 | text: "Cancel",
12 | onPress: () => {
13 | // Cancel
14 | },
15 | style: "cancel"
16 | },
17 | {
18 | text: "Proceed",
19 | onPress: () => {
20 | // Proceed
21 | },
22 | },
23 | ],
24 | {
25 | cancelable: true,
26 | onDismiss: () => console.log("Dismissed alert"),
27 | }
28 | );
29 | ```
30 |
--------------------------------------------------------------------------------
/screen-timing/react-native.md:
--------------------------------------------------------------------------------
1 | # Adjustable timing - React Native
2 |
3 | In React Native, the [`react-native-root-toast`](https://github.com/magicismight/react-native-root-toast) is often used to display temporary messages. The display duration might be too short for people to read or hear the message.
4 |
5 | We recommend use the `SnackBar` in `react-native-paper` instead. Set the `duration` to [`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) to keep it visible. Don't forget to add a close button.
6 |
7 | Also make sure that the use of time limits, e.g. by using [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout), can be extended.
8 |
9 | ```jsx
10 | import { Button, Snackbar } from 'react-native-paper';
11 |
12 | {
19 | // Close
20 | },
21 | }}>
22 | Appt
23 |
24 | ```
25 |
--------------------------------------------------------------------------------
/accessibility-focus/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus - .NET MAUI
2 |
3 | In .NET MAUI the [`SemanticExtensions`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.semanticextensions?view=net-maui-8.0) class contais the `SetSemanticFocus` method. It moves the accessibility focus to the given element on the native platform.
4 |
5 | The code sample below shows how to move the accessibility focus to a specific element.
6 |
7 | ```xml
8 |
14 |
17 |
18 |
21 |
22 | ```
23 |
24 | ```csharp
25 | private void SetSemanticFocus_Clicked(object sender, System.EventArgs e)
26 | {
27 | semanticFocusLbl.SetSemanticFocus();
28 | }
29 | ```
30 |
--------------------------------------------------------------------------------
/input-errors/android.md:
--------------------------------------------------------------------------------
1 | # Input errors - Android
2 |
3 | On Android, you can use a [`TextView`](https://developer.android.com/reference/android/widget/TextView) to show an error message. The error message should also be posted to assistive technologies by using an [`accessibility announcement`](../Techniques/accessibility-announcement.md).
4 |
5 | You can also use [`TextInputLayout`](https://developer.android.com/reference/com/google/android/material/textfield/TextInputLayout), which makes showing error messages easier. Set [`setErrorEnabled`](https://developer.android.com/reference/com/google/android/material/textfield/TextInputLayout#setErrorEnabled(boolean)) to `true` and then set the error message by using the [`setError`](https://developer.android.com/reference/com/google/android/material/textfield/TextInputLayout#seterror) method.
6 |
7 | ```kotlin
8 | textView.setVisibility(View.VISIBLE)
9 | textView.text = "Invalid date, must be in the form DD/MM/YYYY, for example, 01/01/2000"
10 |
11 | input.setErrorEnabled(true)
12 | input.setError("Invalid date, must be in the form DD/MM/YYYY, for example, 01/01/2000")
13 | ```
14 |
--------------------------------------------------------------------------------
/accessibility-focus-indicator/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus indicator - iOS
2 |
3 | On iOS, you can adjust colors when an element receives focus. However, it's not possible to change the focus indicator of assistive technologies. Users can adjust their preferences in the system settings of iOS.
4 |
5 | You can override the [`accessibilityElementDidBecomeFocused`](https://developer.apple.com/documentation/objectivec/nsobject/1615183-accessibilityelementdidbecomefoc) and [`accessibilityElementDidLoseFocus`](https://developer.apple.com/documentation/objectivec/nsobject/1615082-accessibilityelementdidlosefocus) methods to listen to focus state changes. By subclassing an element, you can change the colors based on the element state.
6 |
7 | The code sample below shows how to change the background color of a button on focus.
8 |
9 | ```swift
10 | class Button: UIButton {
11 |
12 | override open func accessibilityElementDidBecomeFocused() {
13 | backgroundColor = .focused
14 | }
15 |
16 | override open func accessibilityElementDidLoseFocus() {
17 | backgrounColor = .default
18 | }
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/screen-dark-mode/xamarin.md:
--------------------------------------------------------------------------------
1 | # Dark mode - Xamarin
2 |
3 | With Xamarin, you can detect dark mode by checking if the [`RequestedTheme`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.application.requestedtheme?view=xamarin-forms) property equals [`OSAppTheme.Dark`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.osapptheme?view=xamarin-forms#fields).
4 |
5 | In `XAML` you can use [`AppThemeBinding`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/xaml/markup-extensions/consuming#appthemebinding-markup-extension) to define different resources for dark mode.
6 |
7 | ```csharp
8 | using Xamarin.Essentials;
9 |
10 | OSAppTheme theme = Application.Current.RequestedTheme;
11 | if (theme == OSAppTheme.Dark) {
12 | // Dark mode
13 | }
14 | ```
15 |
16 | ```xml
17 |
18 |
19 |
21 |
22 |
23 |
24 | ```
25 |
--------------------------------------------------------------------------------
/accessibility-value/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility value - Xamarin
2 |
3 | Xamarin Forms elements such as [`Button`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/button) and [`Entry`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/entry) automatically include an accessibility value. When you make custom elements you have to set these properties yourself.
4 |
5 | However, there is no dedicated property to set an accessibility value. You can embed the value inside the label by using [`MultiBinding`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/multibinding) inside the [`AutomationProperties.Name`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertiesname) property.
6 |
7 | ```xml
8 |
16 | ```
17 |
--------------------------------------------------------------------------------
/accessibility-label/xamarin.md:
--------------------------------------------------------------------------------
1 | # Accessibility label - Xamarin
2 |
3 | In Xamarin Forms, you can set an accessibility label by using the [`AutomationProperties.Name`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertiesname) property.
4 |
5 | If another element is used to display the label, the [`AutomationProperties.LabeledBy`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertieslabeledby) property be used to link a label. Unfortunately, `LabeledBy` only works on Android.
6 |
7 | As an alternative, you can link a label by setting [`IsInAccessibleTree`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertiesisinaccessibletree) to `false` and setting [`AutomationProperties.Name`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertiesname) the `value` of the label.
8 |
9 | ```xml
10 |
12 | ```
13 |
--------------------------------------------------------------------------------
/accessibility-value/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility value - .NET MAUI
2 |
3 | .NET MAUI elements such as [`Button`](https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/button) and [`Entry`](https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/entry) automatically include an accessibility value. When you create custom elements you have to set these properties yourself.
4 |
5 | However, there is no dedicated property to set an accessibility value. You can embed the value inside the label by using [`MultiBinding`](https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/data-binding/multibinding) inside the [`SemanticProperties.Description`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.controls.semanticproperties.descriptionproperty#microsoft-maui-controls-semanticproperties-descriptionproperty) property.
6 |
7 | ```xml
8 |
16 | ```
17 |
--------------------------------------------------------------------------------
/accessibility-focus-indicator/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus indicator - Android
2 |
3 | On Android, you can adjust colors when an element receives focus. However, it's not possible to change the focus indicator of assistive technologies. Users can adjust their preferences in the system settings of Android.
4 |
5 | You can use a [`ColorStateList`](https://developer.android.com/guide/topics/resources/color-list-resource) to change colors based on the element state. An element moves into the [`state_focused`](https://developer.android.com/reference/android/graphics/drawable/StateListDrawable#attr_android:state_focused) whenever it receives focus.
6 |
7 | The code sample below shows how to change the background color of a button on focus.
8 |
9 | ```xml
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
21 | ```
22 |
--------------------------------------------------------------------------------
/accessibility-dialog/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility dialog - Flutter
2 |
3 | With Flutter, you can use [`SimpleDialog`](https://api.flutter.dev/flutter/material/SimpleDialog-class.html), [`AlertDialog`](https://api.flutter.dev/flutter/material/AlertDialog-class.html) or [`CupertinoAlertDialog`](https://api.flutter.dev/flutter/cupertino/CupertinoAlertDialog-class.html) to show alerts. An `AlertDialog` is styled liked an Android dialog. A `CupertinoAlertDialog` is styled like an iOS dialog. You should always supply a close action in the `actions` array. The focus of assistive technologies is automatically trapped inside the dialog while it's visible.
4 |
5 | ```dart
6 | showDialog(
7 | context: context,
8 | builder: (context) => AlertDialog(
9 | title: Text('Confirm Appt membership?'),
10 | content: Text('Your bank account will be billed.'),
11 | actions: [
12 | TextButton(
13 | onPressed: confirmTransaction,
14 | child: const Text('Proceed'),
15 | ),
16 | TextButton(
17 | onPressed: () => Navigator.pop(context),
18 | child: const Text('Cancel'),
19 | )
20 | ],
21 | ),
22 | );
23 | ```
24 |
--------------------------------------------------------------------------------
/accessibility-name/net-maui.md:
--------------------------------------------------------------------------------
1 | # Accessibility name - .NET MAUI
2 |
3 | In .NET MAUI, the [`SemanticProperties.Description`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.controls.semanticproperties.descriptionproperty#microsoft-maui-controls-semanticproperties-descriptionproperty) property is used as accessibility name.
4 |
5 | ```xml
6 |
8 | ```
9 |
10 | **Warning:**
11 |
12 | 1. Avoid setting the `Description` attached property on a `Label`. This will stop the `Text` property being spoken by the screen reader. This is because the visual text should ideally match the text read aloud by the screen reader.
13 | 2. Avoid setting the `Description` attached property on an `Entry` or `Editor` on Android. Doing so will stop TalkBack actions functioning. Instead, use the `Placeholder` property or the `Hint` attached property.
14 | 3. On iOS, if you set the `Description` property on any control that has children the screen reader will be unable to reach the children. This is because iOS doesn't provide accessibility features that allow the navigation from a parent element into a child element.
15 |
--------------------------------------------------------------------------------
/accessibility-order/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility order - Android
2 |
3 | On Android, you can set the accessibility order in XML, or modify the accessibility order in code. You can use the [`android:accessibilityTraversalAfter`](https://developer.android.com/reference/android/view/View#attr_android:accessibilityTraversalAfter) and [`android:accessibilityTraversalBefore`](accessibilityTraversalBefore) properties in XML. Or you can use the [`setAccessibilityTraversalBefore`](https://developer.android.com/reference/android/view/View#setAccessibilityTraversalBefore(int)) and [`setAccessibilityTraversalAfter`](https://developer.android.com/reference/android/view/View#setAccessibilityTraversalAfter(int)) methods in code.
4 |
5 | ```xml
6 |
8 |
11 |
14 | ```
15 |
16 | ```kotlin
17 | header.setAccessibilityTraversalBefore(R.id.description)
18 | list.setAccessibilityTraversalAfter(R.id.description)
19 | ```
20 |
--------------------------------------------------------------------------------
/keyboard-shortcuts/android.md:
--------------------------------------------------------------------------------
1 | # Keyboard shortcuts - Android
2 |
3 | On Android, you can use the [`dispatchKeyEvent`](https://developer.android.com/reference/android/view/View#dispatchKeyEvent(android.view.KeyEvent)) and [`onKeyUp`](https://developer.android.com/reference/android/app/Activity#onKeyUp(int,%20android.view.KeyEvent)) methods to activate shortcuts. Both methods give you a reference to a [`KeyEvent`](https://developer.android.com/reference/android/view/KeyEvent) object. Use the [`isShiftPressed`](https://developer.android.com/reference/android/view/KeyEvent#isShiftPressed()) or [`isCtrlPressed`](https://developer.android.com/reference/android/view/KeyEvent#isCtrlPressed()) method to make sure that shortcuts are not activated by accident.
4 |
5 | ```kotlin
6 | override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
7 | return when (keyCode) {
8 | KeyEvent.KEYCODE_F -> {
9 | if (event.isCtrlPressed) {
10 | find()
11 | true
12 | }
13 | }
14 | else -> super.onKeyUp(keyCode, event)
15 | }
16 | }
17 |
18 | private fun find() {
19 | // Logic
20 | }
21 | ```
22 |
--------------------------------------------------------------------------------
/text-spacing/android.md:
--------------------------------------------------------------------------------
1 | # Text spacing - Android
2 |
3 | On Android, you can use the following attribute to increase text spacing:
4 |
5 | - [`letterSpacing`](https://developer.android.com/reference/android/widget/TextView#attr_android:letterSpacing): set spacing between letters
6 | - [`lineHeight`](https://developer.android.com/reference/android/widget/TextView#attr_android:lineHeight): set spacing between lines
7 | - [`lineSpacingExtra`](https://developer.android.com/reference/android/widget/TextView#attr_android:lineSpacingExtra): increase spacing between lines
8 | - [`lineSpacingMultiplier`](https://developer.android.com/reference/android/widget/TextView#attr_android:lineSpacingMultiplier): multiply spacing between lines
9 | - [`marginBottom`](https://developer.android.com/reference/android/view/ViewGroup.MarginLayoutParams#attr_android:layout_marginBottom): set spacing between paragraphs
10 |
11 | ```xml
12 |
19 | ```
20 |
--------------------------------------------------------------------------------
/media-captions-live/flutter.md:
--------------------------------------------------------------------------------
1 | # Live captions - Flutter
2 |
3 | On Flutter, the [video_player](https://pub.dev/packages/video_player) package does not have support for captions in live videos. [Issue #50595](https://github.com/flutter/flutter/issues/50595) has been opened to request support.
4 |
5 | Other packages, like [better_player](https://pub.dev/packages/better_player), do have support for using captions on live video. The [better_player documentation](https://jhomlala.github.io/betterplayer/#/README) contains detailed information on how to do so.
6 |
7 | ```dart
8 | BetterPlayerController controller = BetterPlayerController(
9 | const BetterPlayerConfiguration(
10 | controlsConfiguration: BetterPlayerControlsConfiguration(
11 | enableAudioTracks: true,
12 | enableSubtitles: true,
13 | ),
14 | ),
15 | betterPlayerDataSource: BetterPlayerDataSource.network(
16 | 'https://appt.org/live-video',
17 | liveStream: true,
18 | useAsmsSubtitles: true,
19 | ),
20 | );
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return BetterPlayer(controller: controller);
25 | }
26 | ```
27 |
--------------------------------------------------------------------------------
/text-spacing/ios.md:
--------------------------------------------------------------------------------
1 | # Text spacing - iOS
2 |
3 | On iOS, you can use [`NSMutableParagraphStyle`](https://developer.apple.com/documentation/uikit/nsmutableparagraphstyle) for paragraphs:
4 |
5 | - [`lineSpacing`](https://developer.apple.com/documentation/uikit/nsmutableparagraphstyle/1528742-linespacing): set spacing between lines
6 | - [`lineHeightMultiple`](https://developer.apple.com/documentation/uikit/nsmutableparagraphstyle/1524596-lineheightmultiple): multiply distance between lines by a number
7 | - [`paragraphSpacing`](https://developer.apple.com/documentation/uikit/nsmutableparagraphstyle/1532528-paragraphspacing): set spacing between paragraphs
8 |
9 | To adjust the spacing between letters you can use the [`NSKernAttributeName`](https://developer.apple.com/documentation/uikit/nskernattributename) attribute.
10 |
11 | ```swift
12 | let style = NSMutableParagraphStyle()
13 | style.lineSpacing = 20
14 | style.lineHeightMultiple = 1.5
15 | style.paragraphSpacing = 20
16 |
17 | let attributedString = NSAttributedString(string: "Appt", attributes: [
18 | .paragraphStyle: style,
19 | .kern: 3.0
20 | ])
21 | element.attributedText = attributedString
22 | ```
23 |
--------------------------------------------------------------------------------
/accessibility-dialog/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility dialog - Android
2 |
3 | On Android, you can [show a dialog](https://developer.android.com/guide/topics/ui/dialogs) by using [`AlertDialog`](https://developer.android.com/reference/androidx/appcompat/app/AlertDialog), [`BottomSheetDialog`](https://developer.android.com/reference/com/google/android/material/bottomsheet/BottomSheetDialog) or [`DialogFragment`](https://developer.android.com/reference/androidx/fragment/app/DialogFragment). You should always add a close button by using the [`setNegativeButton`](https://developer.android.com/reference/androidx/appcompat/app/AlertDialog.Builder#setNegativeButton(int,android.content.DialogInterface.OnClickListener)) method. The focus of assistive technologies is automatically trapped inside the dialog while it's visible.
4 |
5 | ```kotlin
6 | val builder = AlertDialog.Builder(this)
7 | builder.setTitle("Confirm Appt membership?")
8 | builder.setMessage("Your bank account will be billed.")
9 |
10 | builder.setPositiveButton("Proceed") { dialog, which ->
11 | // Proceed
12 | }
13 |
14 | builder.setNegativeButton("Cancel") { dialog, which ->
15 | // Cancel
16 | }
17 |
18 | builder.show()
19 | ```
20 |
--------------------------------------------------------------------------------
/screen-orientation/xamarin.md:
--------------------------------------------------------------------------------
1 | # Screen orientation - Xamarin
2 |
3 | When using Xamarin.Forms, [device orientation](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/device-orientation) is set at the project level.
4 |
5 | - For Android: open `MainActivity.cs` and decorate the `MainActivity` class with `[Activity (ScreenOrientation = ScreenOrientation.FullUser)]`.
6 | - For iOS: open `Info.plist` and check all `Device Orientation` checkboxes.
7 |
8 | You can listen to orientation changes by using the [`DeviceDisplay`](https://learn.microsoft.com/en-us/xamarin/essentials/device-display?context=xamarin%2Fxamarin-forms&tabs=android) class included in [Xamarin.Essentials](https://learn.microsoft.com/en-us/xamarin/essentials/).
9 |
10 | ```csharp
11 | public class OrientationChanges
12 | {
13 | public OrientationChanges()
14 | {
15 | // Subscribe to changes of screen metrics
16 | DeviceDisplay.MainDisplayInfoChanged += OnMainDisplayInfoChanged;
17 | }
18 |
19 | void OnMainDisplayInfoChanged(object sender, DisplayInfoChangedEventArgs e)
20 | {
21 | // Process changes
22 | var displayInfo = e.DisplayInfo;
23 | }
24 | }
25 | ```
26 |
--------------------------------------------------------------------------------
/text-scale/flutter.md:
--------------------------------------------------------------------------------
1 | # Scale text - Flutter
2 |
3 | Flutter automatically scales the text on the screen to the text size set by the user. We recommend using [`ThemeData`](https://api.flutter.dev/flutter/material/ThemeData-class.html) to use the same text sizes and fonts everywhere.
4 |
5 | Try to avoid using the `textScaleFactor` property because it overrides the text scale factor preferred by the user. The default factor is `1.0`, but can go as high as `4.0` for some users. Restricting the number means that some users might not be able to read the text.
6 |
7 | There are valid use cases to restrict the `textScaleFactor` to a certain number. You can use [`MediaQuery`](https://api.flutter.dev/flutter/widgets/MediaQuery-class.html) to override the value globally. You can also override it for a single use case by using the property inside a [`Text`](https://api.flutter.dev/flutter/widgets/Text-class.html) widget.
8 |
9 | ```dart
10 | MediaQuery(
11 | data: MediaQuery.of(context).copyWith(
12 | textScaleFactor: 1.0, // Override scale for all widgets
13 | ),
14 | child: ...,
15 | );
16 |
17 | Text(
18 | 'Appt',
19 | textScaleFactor: 1.0, // Override scale for a single widget
20 | );
21 | ```
22 |
--------------------------------------------------------------------------------
/accessibility-value/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility value - Flutter
2 |
3 | With Flutter, you can set an accessibility value by using the `value` or `attributedValue` property of [`Semantics`](https://api.flutter.dev/flutter/widgets/Semantics/Semantics.html).
4 |
5 | When using the semantically correct element, you usually do not need to modify the accessibility value. For example, [`Slider`](https://api.flutter.dev/flutter/material/Slider-class.html), [`Switch`](https://api.flutter.dev/flutter/material/Switch-class.html) and [`CheckBox`](https://api.flutter.dev/flutter/material/Checkbox-class.html), and others automatically assign accessibiluty values.
6 |
7 | It is also possible to set an `increasedValue` and `decreasedValue` or `attributedDecreasedValue` and `attributedIncreasedValue` to indicate what the value will become when the user decreases or increases the value.
8 |
9 | Some widgets include additional methods, such as [`semanticFormatterCallback`](https://api.flutter.dev/flutter/material/Slider/semanticFormatterCallback.html).
10 |
11 | ```dart
12 | Semantics(
13 | value: 'Custom',
14 | increasedValue: 'Custom + 1',
15 | decreasedValue: 'Custom - 1',
16 | child: Widget(),
17 | );
18 | ```
19 |
--------------------------------------------------------------------------------
/accessibility-role/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility role - iOS
2 |
3 | On iOS, the [`accessibilityTraits`](https://developer.apple.com/documentation/objectivec/nsobject/1615202-accessibilitytraits) attribute is used to indicate an accessibility role. The [`UIAccessibilityTraits`](https://developer.apple.com/documentation/uikit/uiaccessibility/uiaccessibilitytraits) structure contains all options, such as [`header`](https://developer.apple.com/documentation/uikit/uiaccessibilitytraits/1620170-header), [`button`](https://developer.apple.com/documentation/uikit/uiaccessibility/uiaccessibilitytraits/1620194-button), [`link`](https://developer.apple.com/documentation/uikit/uiaccessibility/uiaccessibilitytraits/1620178-link) and [`image`](https://developer.apple.com/documentation/uikit/uiaccessibilitytraits/1620174-image), among others.
4 |
5 | You can also combine multiple traits. For example, for a selected button you can can pass both traits as an array: `[.button, .selected]`.
6 |
7 | ```swift
8 | element.accessibilityTraits = .button
9 | element.accessibilityTraits = .header
10 | element.accessibilityTraits = .link
11 | element.accessibilityTraits = .image
12 |
13 | element.accessibilityTraits = [.button, .selected]
14 | ```
15 |
--------------------------------------------------------------------------------
/accessibility-focus-indicator/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility focus indicator - Flutter
2 |
3 | In Flutter, you can adjust colors when an element receives focus. However, it's not possible to change the focus indicator of assistive technologies. Users can adjust their preferences in the system settings on Android and iOS.
4 |
5 | You can change colors based on [`MaterialState`](https://api.flutter.dev/flutter/material/MaterialState.html). For a button, you could add a [`ButtonStyle`](https://api.flutter.dev/flutter/material/ButtonStyle-class.html) to change the color when in [`.focused`](https://api.flutter.dev/flutter/material/MaterialState.html#focused) state.
6 |
7 | The code sample below shows how to change the background color of a button on focus.
8 |
9 | ```dart
10 | TextButton(
11 | style: ButtonStyle(
12 | backgroundColor: MaterialStateProperty.resolveWith(getColor),
13 | ),
14 | child: Text('Button'),
15 | );
16 |
17 | Color? getColor(Set states) {
18 | const Set interactiveStates = {
19 | MaterialState.focused,
20 | };
21 | if (states.any(interactiveStates.contains)) {
22 | return Colors.blue;
23 | }
24 | return Colors.red;
25 | }
26 | ```
27 |
--------------------------------------------------------------------------------
/accessibility-label/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility label - Android
2 |
3 | On Android, you can use the [`contentDescription`](https://developer.android.com/reference/android/view/View.html#attr_android:contentDescription) attribute to set an accessibility label.
4 |
5 | You can also pass any kind of [`Span`](https://developer.android.com/guide/topics/text/spans) for greater control over pronunciation. For example, you can set a language by using [`LocaleSpan`](https://developer.android.com/reference/android/text/style/LocaleSpan).
6 |
7 | If another element is used to display the label, you can link the label by using the [`labelFor`](https://developer.android.com/reference/android/view/View#setLabelFor(int)) attribute.
8 |
9 | ```kotlin
10 | // Set accessibility label
11 | element.contentDescription = "Appt"
12 |
13 | // Set accessibility label in Dutch language
14 | val locale = Locale.forLanguageTag("nl-NL")
15 | val localeSpan = LocaleSpan(locale)
16 |
17 | val string = SpannableString("Appt")
18 | string.setSpan(localeSpan, 0, string.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
19 |
20 | element.contentDescription = localeSpan
21 |
22 | // Link visual label to field
23 | textView.setLabelFor(R.id.editText)
24 | ```
25 |
--------------------------------------------------------------------------------
/accessibility-value/android.md:
--------------------------------------------------------------------------------
1 | # Accessibility value - Android
2 |
3 | Android has limited support to provide a dedicated accessibility value for assistive technologies. The [`AccessibilityNodeInfoCompat`](https://developer.android.com/reference/androidx/core/view/accessibility/AccessibilityNodeInfoCompat) object contains a couple of methods, such as the [`setChecked`](https://developer.android.com/reference/kotlin/androidx/core/view/accessibility/AccessibilityNodeInfoCompat#setchecked) method.
4 |
5 | Unfortunately the desired value is often not available. If your desired value is not included, you can append it to the [`contentDescription`](https://developer.android.com/reference/android/view/View.html#attr_android:contentDescription) attribute.
6 |
7 | ```kotlin
8 | ViewCompat.setAccessibilityDelegate(
9 | element,
10 | object : AccessibilityDelegateCompat() {
11 | override fun onInitializeAccessibilityNodeInfo(
12 | host: View,
13 | info: AccessibilityNodeInfoCompat
14 | ) {
15 | super.onInitializeAccessibilityNodeInfo(host, info)
16 | info.isChecked = true
17 | }
18 | }
19 | )
20 |
21 | element.contentDescription = "Name (Value)"
22 | ```
23 |
--------------------------------------------------------------------------------
/input-label/xamarin.md:
--------------------------------------------------------------------------------
1 | # Input label - Xamarin
2 |
3 | In Xamarin, you can use the [`AutomationProperties.LabeledBy`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertieslabeledby) property to link a label to an input field. However, `LabeledBy` only works on Android.
4 |
5 | You can also link a [`Label`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/label) to an [`Entry`](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/entry) by setting [`IsInAccessibleTree`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertiesisinaccessibletree) to `false` on the label, and setting [`AutomationProperties.Name`](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties#automationpropertiesname) property to the value of the label.
6 |
7 | ```xml
8 |
11 |
12 |
14 | ```
15 |
--------------------------------------------------------------------------------
/screen-timing/android.md:
--------------------------------------------------------------------------------
1 | # Adjustable timing - Android
2 |
3 | On Android, a [`Toast`](https://developer.android.com/reference/android/widget/Toast) is often used display temporary messages. The display duration might be too short for people to read or hear the message.
4 |
5 | We recommend displaying messages by using an [`AlertDialog`](https://developer.android.com/reference/androidx/appcompat/app/AlertDialog) or [`Snackbar`](https://developer.android.com/reference/com/google/android/material/snackbar/Snackbar) with the duration set to [`LENGTH_INDEFINITE`](https://developer.android.com/reference/com/google/android/material/snackbar/BaseTransientBottomBar#LENGTH_INDEFINITE). Don't forget to add a close button.
6 |
7 | Also check whether [`Executors`](https://developer.android.com/reference/java/util/concurrent/Executors), [`Handler`](https://developer.android.com/reference/android/os/Handler) or [`Timer`](https://developer.android.com/reference/java/util/Timer) are used somewhere. If there are any time limits, make sure they can be extended.
8 |
9 | ```kotlin
10 | val snackbar = Snackbar
11 | .make(view, "Appt", Snackbar.LENGTH_INDEFINITE)
12 | .setAction("Close") {
13 | // Close
14 | }
15 | snackbar.show()
16 | ```
17 |
--------------------------------------------------------------------------------
/accessibility-live-region/ios.md:
--------------------------------------------------------------------------------
1 | # Accessibility live region - iOS
2 |
3 | On iOS, the closest thing to live regions are elements with the [`updatesFrequently`](https://developer.apple.com/documentation/uikit/uiaccessibilitytraits/1620187-updatesfrequently) trait. When an element is focused, label and value changes are announced periodically.
4 |
5 | You can replicate a live region by posting accessibility announcements. To replicate 'polite' behavior, you can set [`accessibilitySpeechQueueAnnouncement`](https://developer.apple.com/documentation/foundation/nsattributedstring/key/2865770-accessibilityspeechqueueannounce) to `false`. To be 'asssertive', set the value to `true`.
6 |
7 | For even more advanced behavior, you can use act on [`announcementDidFinishNotification`](https://developer.apple.com/documentation/uikit/uiaccessibility/1620202-announcementdidfinishnotificatio) events.
8 |
9 | ```swift
10 | // Periodic announcements (only on focus!)
11 | element.accessibilityTraits = .updatesFrequently
12 |
13 | // Replicate live region
14 | let message = NSAttributedString(
15 | string: "Appt live region",
16 | attributes: [.accessibilitySpeechQueueAnnouncement: true]
17 | )
18 | UIAccessibility.post(notification: .announcement, argument: message)
19 | ```
20 |
--------------------------------------------------------------------------------
/text-spacing/xamarin.md:
--------------------------------------------------------------------------------
1 | # Text spacing - Xamarin
2 |
3 | Xamarin Forms has a couple of attributes to adjust text spacing:
4 |
5 | - [`CharacterSpacing`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.label.characterspacing?view=xamarin-forms): set spacing between characters.
6 | - [`LineHeight`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.label.lineheight?view=xamarin-forms): set spacing between lines.
7 | - [`Padding`](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.label.padding?view=xamarin-forms): set padding between paragraphs
8 |
9 | You can also make a `CustomRenderer` to use even more properties from native Android and iOS elements. For more information see:
10 |
11 | - [Xamarin Forms Custom Renderers](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/)
12 | - [Custom Renderer for Android](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/entry#creating-the-custom-renderer-on-android)
13 | - [Custom Renderer for iOS](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/entry#creating-the-custom-renderer-on-ios)
14 |
15 | ```xml
16 |
17 | ```
18 |
--------------------------------------------------------------------------------
/input-gestures/react-native.md:
--------------------------------------------------------------------------------
1 | # Input gestures - React Native
2 |
3 | In React Native, the [`Gesture Responder System`](https://reactnative.dev/docs/gesture-responder-system) is a common way to detect gestures.
4 |
5 | A gesture should not be the only way to trigger actions. Make sure to provide a second way, such as a button, to trigger the same action.
6 |
7 | ```jsx
8 | import { PinchGestureHandler, State } from 'react-native-gesture-handler'
9 |
10 | const PinchableView = () => {
11 | scale = new Animated.Value(1)
12 |
13 | onPinchEvent = Animated.event([{
14 | nativeEvent: { scale: this.scale }
15 | }], {
16 | useNativeDriver: true
17 | })
18 |
19 |
20 | onPinchStateChange = event => {
21 | if (event.nativeEvent.oldState === State.ACTIVE) {
22 | // Provide alternative
23 | Animated.spring(this.scale, {
24 | toValue: 1,
25 | useNativeDriver: true
26 | }).start()
27 | }
28 | }
29 |
30 | return (
31 |
34 |
37 |
38 | )
39 | }
40 | ```
41 |
--------------------------------------------------------------------------------
/accessibility-label/flutter.md:
--------------------------------------------------------------------------------
1 | # Accessibility label - Flutter
2 |
3 | In Flutter, the [`semanticsLabel`](https://api.flutter.dev/flutter/widgets/Text/semanticsLabel.html) property is used as accessibility name.
4 |
5 | You can also use the [`attributedLabel`](https://api.flutter.dev/flutter/semantics/SemanticsProperties/attributedLabel.html) property for greater control over pronunciation. For example, spell out each character with [`SpellOutStringAttribute`](https://api.flutter.dev/flutter/dart-ui/SpellOutStringAttribute-class.html) or set a language using [`LocaleStringAttribute`](https://api.flutter.dev/flutter/dart-ui/LocaleStringAttribute-class.html).
6 |
7 | For even more control, you can use the [`Semantics`](https://api.flutter.dev/flutter/widgets/Semantics-class.html) widget. For example, if you want to ignore the semantics of underlaying widgets, you can set the [`excludeSemantics`](https://api.flutter.dev/flutter/widgets/Semantics/excludeSemantics.html) attribute to `true`.
8 |
9 | ```dart
10 | Control(
11 | semanticsLabel: 'Appt'
12 | )
13 |
14 | Semantics(
15 | label: 'Appt',
16 | attributedLabel: AttributedString('Appt', attributes: [
17 | SpellOutStringAttribute(range: const TextRange(start: 0, end: 3))
18 | ]),
19 | excludeSemantics: true;
20 | );
21 | ```
22 |
--------------------------------------------------------------------------------