Skip to content

Commit

Permalink
Add UIAccessibilityCustomAction for Chip deletion.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 616255618
  • Loading branch information
CGRect authored and material-automation committed Mar 15, 2024
1 parent dafe9b9 commit 45fd468
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* Name for ChipField custom accessibility action that deletes a Chip. */
"ChipFieldAccessibilityActionDelete" = "Delete";
60 changes: 60 additions & 0 deletions components/Chips/src/MDCChipField.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
NSString *const MDCChipDelimiterSpace = @" ";
NSString *const MDCChipFieldDidSetTextNotification = @"MDCChipFieldDidSetTextNotification";

/** Key for name of ChipField custom accessibility action that deletes a Chip. */
static NSString *const kAccessibilityActionDeleteNameKey = @"ChipFieldAccessibilityActionDelete";
/** The name of the accessibility table for localizations. */
static NSString *const kLocalizationAccessibilityTableName = @"Chips";
/** The name of the bundle. */
static NSString *const kBundle = @"Chips.bundle";

static const CGFloat MDCChipFieldDefaultFontSize = 14;
static const CGFloat MDCChipFieldHorizontalInset = 15;
static const CGFloat MDCChipFieldVerticalInset = 8;
Expand Down Expand Up @@ -111,6 +118,7 @@ - (void)setAttributedText:(NSAttributedString *)attributedText {
@end

@interface MDCChipField () <MDCChipFieldTextFieldDelegate, UITextFieldDelegate>
@property(nullable, nonatomic, copy) NSString *accessibilityActionDeleteChipName;
@end

@implementation MDCChipField {
Expand Down Expand Up @@ -174,6 +182,8 @@ - (void)commonMDCChipFieldInit {
_contentEdgeInsets = MDCChipFieldDefaultContentEdgeInsets;
_showPlaceholderWithChips = YES;
_chipHeight = 32;

[self configureLocalizedAccessibilityActionName];
}

- (void)layoutSubviews {
Expand Down Expand Up @@ -335,7 +345,31 @@ - (void)addChip:(MDCChipView *)chip {
// themselves rather than using |chipField:shouldAddChip| to prevent chips from being added.
if (self.showChipsDeleteButton) {
[self addClearButtonToChip:chip];

// Set Chip's accessibilityTraits to `UIAccessibilityTraitNone` if there is a `clearButton`.
// A11y compliance is handled by a UIAccessibilityCustomAction.
chip.accessibilityTraits = UIAccessibilityTraitNone;

__weak __typeof__(self) weakSelf = self;
__weak MDCChipView *weakChip = chip;

UIAccessibilityCustomActionHandler actionHandler =
^BOOL(UIAccessibilityCustomAction *__unused customAction) {
__typeof__(self) strongSelf = weakSelf;
MDCChipView *strongChip = weakChip;
if (strongSelf) {
[strongSelf removeChip:strongChip];
}
return YES;
};

UIAccessibilityCustomAction *action =
[[UIAccessibilityCustomAction alloc] initWithName:_accessibilityActionDeleteChipName
actionHandler:actionHandler];

chip.accessibilityCustomActions = @[ action ];
}

[_chips addObject:chip];
[self addChipSubview:chip];
if ([self.delegate respondsToSelector:@selector(chipField:didAddChip:)]) {
Expand Down Expand Up @@ -775,4 +809,30 @@ - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[self setNeedsLayout];
}

// Sets the localized accessibility action name for deleting a Chip.
- (void)configureLocalizedAccessibilityActionName {
NSBundle *resourceBundle = [[self class] bundle];
_accessibilityActionDeleteChipName =
[resourceBundle localizedStringForKey:kAccessibilityActionDeleteNameKey
value:@"Delete"
table:kLocalizationAccessibilityTableName];
}

#pragma mark - Resource Bundle

+ (NSBundle *)bundle {
static NSBundle *bundle = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
bundle = [NSBundle bundleWithPath:[self bundlePathWithName:kBundle]];
});

return bundle;
}

+ (NSString *)bundlePathWithName:(NSString *)bundleName {
NSBundle *bundle = [NSBundle bundleForClass:[MDCChipField class]];
NSString *resourcePath = [(nil == bundle ? [NSBundle mainBundle] : bundle) resourcePath];
return [resourcePath stringByAppendingPathComponent:bundleName];
}
@end

0 comments on commit 45fd468

Please sign in to comment.