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

Checkbox #716

Merged
merged 27 commits into from
Jun 21, 2021
Merged

Checkbox #716

merged 27 commits into from
Jun 21, 2021

Conversation

tamasane97
Copy link
Contributor

@tamasane97 tamasane97 commented Jun 3, 2021

Platforms Impacted

  • iOS
  • macOS
  • win32 (Office)
  • windows
  • android
  • web

Description of changes

  1. Checkbox redlines are matched with vNext in individual platforms.

    • Added platform-wise SVGs for checkmark.
    • Made use of Icon as a slot for checkmark. Created a new optional slot checkmarkIcon. Made previous checkmark slot optional. Enabled checkmarkIcon on supported platforms (android,ios,macos,web)
    • Added platform-wise margin/padding settings in the theme (Default settings are for web).
    • Added checkmarkColor, checkboxBackground, checkboxBackgroundDisabled, checkboxBorderColor tokens to the theme
    • Created Checkbox.settings.old to support win32, windows as SVG checkmark is not enabled on them.
  2. Icon

    • Allowed usage of color from style prop in renderSvg(). This allows to target checkmarkColor on Icon slot.
    • Used processColor to convert string to color for macos.
  3. Theme-wise changes (iOS, macOS, Android)

    • Added component settings.
    • Added theme token values.

Verification

Android iOS
android-checkbox ios-checkbox

macOS
macos-checkbox

Web
web-checkbox

Pull request checklist

This PR has considered (when applicable):

  • Automated Tests
  • Documentation and examples
  • Keyboard Accessibility
  • Voiceover
  • Internationalization and Right-to-left Layouts

packages/components/Checkbox/package.json Outdated Show resolved Hide resolved
Comment on lines 3 to 11

export const checkboxSelectActionLabel = 'Toggle the Checkbox';

export const settings: IComposeSettings<ICheckboxType> = [
{
tokens: {
borderColor: 'menuItemText',
color: 'menuItemText',
backgroundColor: 'menuBackground',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is win32 specific, would it be appropriate to make this settings.win32.ts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

windows too !

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. I don't really like the name "old" here.. but I get why you're doing it. I think I'd rather it just be ".windows" and for .win32 you just import the windows settings. Or "settingsWithoutSVG" to make it more descriptive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. That makes more sense!

packages/components/Checkbox/src/Checkbox.types.ts Outdated Show resolved Hide resolved
Comment on lines 58 to 60
// The svg color can be set using either style.color or iconProps.color, where style.color is preferred in case both are set.
const getColor = (color1: Color, color2: Color) => (color1 === undefined ? color2 : color1);
const color = getColor((style as any).color, iconProps.color);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like there's an immutable style merge function that we have that does the same ish thing. I'll defer to @FalseLobster

Copy link
Contributor Author

@tamasane97 tamasane97 Jun 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is made to supply the color prop of <SvgUri /> which is used as fill value in the SVG. I didn't know how we could target a theme-token to a prop. For all the usages in the repo, the theme-tokens are merged into styles.
So made this to have an override for the checkmark color using style. (and any future requirements of overriding SVG icon colors using style)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's info on mergeStyles, which might be what you're thinking of: https://github.com/microsoft/fluentui-react-native/tree/3c0f5496f0daeb748c6b2daac8d0465a1d58a672/packages/framework/merge-props. There's also a README on immutableMerge: https://github.com/microsoft/fluentui-react-native/tree/3c0f5496f0daeb748c6b2daac8d0465a1d58a672/packages/framework/immutable-merge. Both work on objects, while the color prop is a string/PlatformColor, so it's a bit overkill here.

As a suggestion, the code could be simplified to const color = style.color ? style.color : iconProps.color without defining getColor.

Comment on lines +424 to +428

checkboxBackground: fluentApple.communicationBlue,
checkboxBackgroundDisabled: fluentApple.surfacePrimary,
checkboxBorderColor: fluentApple.gray600,
checkmarkColor: fluentApple.iconOnAccent,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for updating the apple platform as well =) Did you also get these colors from Figma?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. Used the matching tokens with the same values as in Figma.

Comment on lines +442 to +445

checkboxBackground: ColorValue;
checkboxBackgroundDisabled: ColorValue;
checkmarkColor: ColorValue;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these names match the fluentui-token-pipeline names? Also FYI @rurikoaraki since she's working on that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh didn't check that :/

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if they match up so it's easier to integrate but if they aren't in the pipeline yet, then that's fine!

@Saadnajmi
Copy link
Collaborator

Normally I'd say we should make a new experimental-checkbox package that uses the new framework but it seems @JasonVMo already has a PR that just updates the normal component to the new framework but it hasn't moved in months https://github.com/microsoft/fluentui-react-native/pull/502/files

Should we... just do that now too?

@@ -21,8 +21,10 @@ export const lightnessOptions = [
{ label: 'Dark', value: 'dark' },
];

const defaultAsThemeName = ['android', 'ios', 'macos', 'web'].includes(Platform.OS as string);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be easier to inverse this and just say "if win32, then Office?" :D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! Making this change.

Comment on lines 3 to 11

export const checkboxSelectActionLabel = 'Toggle the Checkbox';

export const settings: IComposeSettings<ICheckboxType> = [
{
tokens: {
borderColor: 'menuItemText',
color: 'menuItemText',
backgroundColor: 'menuBackground',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. I don't really like the name "old" here.. but I get why you're doing it. I think I'd rather it just be ".windows" and for .win32 you just import the windows settings. Or "settingsWithoutSVG" to make it more descriptive.

Comment on lines +442 to +445

checkboxBackground: ColorValue;
checkboxBackgroundDisabled: ColorValue;
checkmarkColor: ColorValue;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if they match up so it's easier to integrate but if they aren't in the pipeline yet, then that's fine!

Comment on lines +91 to +92
checkmark?: ITextProps;
checkmarkIcon?: IconProps;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we still combine these slots into one? or is that not feasible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think they can be merged, by introducing Platform.select() for the slot. But that would remove the strict check for the supplied props to the slot. Should I do that?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we intentionally don't want the API to differ greatly between platforms. which is why I like the optional slots. I was more thinking about how the image in the button could be a font, PNG, or SVG, yet there's only one slot it goes to and I was wondering if we could mimick that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The font icons in button are based on codepoint in a ttf file. Making that change here would unnecessarily complicate things. Also it would become tedious to keep track for different platforms. Keeping these separate with the hope that once SVG support comes to windows, we can have a single checkmark.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, if it's much more complex to have them together, keeping separate makes sense! Thanks for the explanation =)

@@ -22,7 +22,7 @@ export const lightnessOptions = [
];

export class TesterThemeReference extends ThemeReference {
private _themeName: ThemeNames = 'Office';
private _themeName: ThemeNames = Platform.OS == ('win32' as any) ? 'Office' : 'Default';
Copy link
Collaborator

@rurikoaraki rurikoaraki Jun 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh this was a mistake commit on my part - you can change it back to default for everyone. Sorry about that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I was going to ask about that :D

Copy link
Collaborator

@Saadnajmi Saadnajmi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my only concern is if we can merge the colors using some merge styles method in FURN. (This comment #716 (comment)).

I'll defer to @rurikoaraki or @samuelfreiberg if they know how to do that though

Comment on lines 1 to 6
export * from './Checkbox.settings.old';
import { IComposeSettings } from '@uifabricshared/foundation-compose';
import { checkboxName, ICheckboxType } from './Checkbox.types';

export const checkboxSelectActionLabel = 'Toggle the Checkbox';

export const settings: IComposeSettings<ICheckboxType> = [
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment in the file that the settings differ because windows doesn't support SVG yet

@PPatBoyd
Copy link
Contributor

PPatBoyd commented Jun 8, 2021

Are the current screenshots accurate? I may be off base but a couple look a little off with regards to relative size or alignment. Does android, ios, and/or macos do pixel dithering?
Alignment of inscribed elements raises some interesting issues with scaling -- if layout rounding occurs, it can throw off alignment. There's a couple ways to deal with it, can you share the goal visual?

@tamasane97
Copy link
Contributor Author

@PPatBoyd, I am not sure about pixel dithering issue happening or not. But here are the goal visuals.

Android iOS macOS
android-checkbox-goal ios-checkbox-goal macos-checkbox-goal

@PPatBoyd
Copy link
Contributor

PPatBoyd commented Jun 8, 2021

@PPatBoyd, I am not sure about pixel dithering issue happening or not. But here are the goal visuals.

Android iOS macOS
android-checkbox-goal ios-checkbox-goal macos-checkbox-goal

thanks for sharing these! Specifically per-platform the iOS checks appear to be smaller than expected (primarily dimensions but also thickness), macOS appears misaligned (top of check is close to the edges), and Android appears to also have misalignment (a pixel or so low), there's a faint white visual that may just be artifacting but I don't expect so, and maybe the check is a little off I can't quite tell for sure? There isn't the full compare set but it's roughly similar between circular and rounded square (circular being a little more apparent for some). Is the web visual a separate React fluentui impl or a react-native-web projection?

All of that said I might be misled by screenshots not properly representing reality, do correct me if I'm misinterpreting :)

These are really really nitpicky comments, but it doesn't take much for these specific controls to have a noticeable deviation from ideal. There are also implications from DPI scaling (Android caring more than iOS/macOS with more DPI scaling values) and text scaling (if either do relational sizing to text) that can exacerbate these issues or shift them into variations -- if you can take some time to compare with each scaling (in isolation and combination) that would be great so we understand the scope of each platform's issues / requirements. There are potential avenues around / tradeoff decisions / mitigations, but those also aren't necessarily cross-platform compatible... which is rough 😬

@tamasane97 tamasane97 merged commit e6f8635 into microsoft:master Jun 21, 2021
@@ -65,16 +65,20 @@ function renderSvg(iconProps: IconProps) {
? '#FFFFFF'
: '#000000';

// The svg color can be set using either style.color or iconProps.color, where style.color is preferred in case both are set.
const colorString = (style as any).color !== undefined ? (style as any).color : iconColor;
const color = (Platform.OS == 'macos' ? processColor(colorString as ColorValue) : colorString) as Color;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally missed this earlier, but I have found that calling processColor directly is a bug. Depending on the order of calls, it can swap RGBA bits into ARGB, which renders the wrong color. also, of the reason we're doing this only for macOS is because macOS uses PlatformColor, converting to a string won't do anything since platformColors cannot be represented as strings. We should make a follow-up here to remove this logic.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we made sure that the iconProps color is always a string until we support ColorValue objects on rn-svg. I can find the PR / code where me made that change if we're curious.
But basically you should never pass an SVG a ColorValue for a color because ColorValue could be an object like a PlatformColor. Instead, pass it the icon color bc we made sure that should be a string I think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Saadnajmi so we've made the change in rn-svg but haven't pulled it into here? Agreed we should not be calling processColor and just passing through ColorValue

Copy link
Collaborator

@Saadnajmi Saadnajmi Jun 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, RN-SVG doesn't support ColorValue at all because it predates RN 0.63 and hasn't been updated to support it yet.
@rurikoaraki and I talked about it some when she added support for PlatformColor in our theme definition, and we made sure to keep tokens that apply to SVGs (basically Icons) to only be strings and not ColorValues.

A followup (for me or whoever gets there first) is to update RN-SVG to support ColorValue. There's an open PR that adds support for PlatformColor, but it's not very extensible to out of tree platforms

Copy link
Collaborator

@Saadnajmi Saadnajmi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment about icon color is a change we should follow up on.

@samuelfreiberg
Copy link
Contributor

It seems this PR broke Checkbox focus on Win32/Windows. It also changed some of the default Win32 styling. We need to change a lot within this PR, including the structure of the Checkbox.settings files. Let's chat when you can @tamasane

@harrieshin
Copy link
Collaborator

technically most of the time on iOS client should NOT use checkbox for iOS because it doesn't follow Apple Human Interface guideline. only time checkbox is kinda allowed is when user is selected a cell from a tableview(list). How can we actually stop clients from abusing this control?

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

Successfully merging this pull request may close these issues.

6 participants