Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Primitives] - Create a Text widget #2

Open
matthew-carroll opened this issue Oct 21, 2023 · 16 comments
Open

[Primitives] - Create a Text widget #2

matthew-carroll opened this issue Oct 21, 2023 · 16 comments
Assignees

Comments

@matthew-carroll
Copy link
Contributor

matthew-carroll commented Oct 21, 2023

Create a widget that matches Swift UI's Text view.

Swift UI Docs: https://developer.apple.com/documentation/swiftui/text

@matthew-carroll
Copy link
Contributor Author

@Maatteogekko @vincevargadev - Can you two take a look at the API design at the bottom of the Wiki for Text?

I've described an API that I think should cover the bases for Accessibility and Localization. Can you look for any holes in that API?

@Maatteogekko
Copy link
Collaborator

Maatteogekko commented Jan 30, 2024

The Localization part seems fine. Just a couple of considerations.
I don't understand why LocalizedStringResource has locale required.
I think bundle won't be useful in the context of flutter apps, but better to keep it and remove it later, when more thought has gone into it.

Another thing. I noticed there is no property for LocalizedStringKey. In swiftUI it is needed to make string variables discoverable to Xcode's automatic localizable strings discovery. Were you aware of this?
Proper support for this mechanism may be outside the scope of the swift_ui package though. What do you think?

@matthew-carroll
Copy link
Contributor Author

@Maatteogekko

I don't understand why LocalizedStringResource has locale required.

Is there a purpose for a LocalizedStringResource if it doesn't have a locale? Isn't the locale what makes it "localized"?

Another thing. I noticed there is no property for LocalizedStringKey

Can you specify where exactly you expected that to appear in the API?

@Maatteogekko
Copy link
Collaborator

Is there a purpose for a LocalizedStringResource if it doesn't have a locale...

Sure, but I expect it to be optional. If not provided it should be resolved at runtime, from the context of the Text widget.

LocalizedStringKey makes sense to include only if we plan on implementing an automatic way to extract localizable strings from code, like Xcode does.

@matthew-carroll
Copy link
Contributor Author

@Maatteogekko - But what's the purpose of a LocalizedStringResource without a locale? Why wouldn't you just pass a regular String if you don't want to specify a Locale? In other words, what's the actual use-case for a LocalizedStringResource without a Locale?

@Maatteogekko
Copy link
Collaborator

To bundle all the localization parameters for the Text widget in a single object. This is a use case that the SwiftUI API allows, so I think it's important to include.

@matthew-carroll
Copy link
Contributor Author

The locale property doesn't seem to be nullable: https://developer.apple.com/documentation/foundation/localizedstringresource/3988424-locale

@Maatteogekko
Copy link
Collaborator

@matthew-carroll
Copy link
Contributor Author

Ok, so .current is a Locale and that's set as the locale when none is provided. Does Flutter have a definition for the "current locale"?

@Maatteogekko
Copy link
Collaborator

There is WidgetsBinding.instance.platformDispatcher.locale

@vincevargadev
Copy link
Collaborator

The proposed text accessibility configuration looks good, the only thing I might do differently are the nullability of the TextAccessibility and its fields. I'll write up a proposal this weekend.

@matthew-carroll
Copy link
Contributor Author

@vincevargadev do we need a whole proposal for that? It sounds like there's just one category of issue there. Can you describe why you'd change the nullability? Can you also specify which fields?

@vincevargadev
Copy link
Collaborator

vincevargadev commented Feb 12, 2024

This is what I'd propose:

class TextAccessibility {
    const TextAccessibility({/*...*/});

    /// This could either default to `speechAdjustedPitch = 1`,
    /// or we "do nothing" by default with a `speechAdjustedPitch = null`.
    final double speechAdjustedPitch;
    
    /// Punctuation needs to handle three states:
    /// * "default" punctuation with `null` to let VoiceOver decide based on context
    /// * on and off with `true` and `false
    final bool? speechAlwaysIncludesPunctuation;

    /// Doesn't need to be nullable as the default behavior matches the
    /// `speechSpellsOutCharacters = false` case.
    final bool speechSpellsOutCharacters;

    /// Make it nullable, as it's optional and not needed in most cases.
    final AccessibilityHeading? accessibilityHeading;

    /// Make it nullable, as it's optional and not needed in most cases.
    final Set<AccessibilityTrait>? accessibilityTraits;

    /// Make it nullable, as by default, the text content is spoken by VoiceOver,
    /// and `accessibilityLabel` is only needed if the text content needs to be overridden.
    final String? accessibilityLabel;
    
    // DIRECTION: Include equality override to avoid needless widget rebuilds
}

@vincevargadev
Copy link
Collaborator

vincevargadev commented Feb 12, 2024

I opened a PR #20 tldr: Text accessibility labels can be localized, and we should handle that case, too.

Do you have any suggestions, @Maatteogekko, about how to handle this case?

If I see it right, we need to handle two cases for the accessibility label (either translated or not):

class TextAccessibility {
    /// Make it nullable, as by default, the text content is spoken by VoiceOver,
    /// and `accessibilityLabel` is only needed if the text content needs to be overridden.
    final AccessibilityLabel? accessibilityLabel;
}

// A couple of ways to represent it internally, so I only specify the constructors for clarity.
class AccessibilityLabel {
  AccessibilityLabel.verbatim(String value);
  AccessibilityLabel.localized(String value);
  /// ...
}

@Maatteogekko
Copy link
Collaborator

@vincevargadev the most important thing is to keep it consistent with the Text specification.

AccessibilityLabel(this.localizedAccessibilityLabelKey);
AccessibilityLabel.verbatim(String text)

I admit that localizedAccessibilityLabelKey is a bit too verbose.

@matthew-carroll
Copy link
Contributor Author

As mentioned, consistency with existing Swift UI APIs is one of the most important things. We want to avoid developers needing to remember the "Flutter" version of the same capability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants