From dc2cb954806310a78527859fbf44791919c3eb4e Mon Sep 17 00:00:00 2001 From: Aneesha Kommineni Date: Mon, 13 Jan 2020 12:53:05 -0800 Subject: [PATCH 1/5] Updating the readme to point to latest spec --- .github/CONTRIBUTING.md | 1 + .../src/components/Checkbox/README.md | 389 +----------------- 2 files changed, 2 insertions(+), 388 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a51e49094d..f134436405 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -3,6 +3,7 @@ + - [Getting started](#getting-started) - [Useful Commands](#useful-commands) - [Workflow](#workflow) diff --git a/packages/playground/src/components/Checkbox/README.md b/packages/playground/src/components/Checkbox/README.md index 04d9cb1a14..a20e459d8c 100644 --- a/packages/playground/src/components/Checkbox/README.md +++ b/packages/playground/src/components/Checkbox/README.md @@ -1,388 +1 @@ -# Checkbox component specification - -The `Checkbox` component allows a user to choose between two mutually exclusive options. - -## Related variant considerations - -- Toggle: should be a separate component because it has different anatomy & warrants unique themability. - -- Indeterminate/Tri State: should support groups with hierarchical checkboxes where the parent checkbox can be in a mixed state if its children checkboxes aren't all checked (and if they are all checked, then the parent is checked; same if they are all unchecked, then the parent is unchecked). - -## Reference implementations - -https://codesandbox.io/s/checkboxes-ggpx1 - -Note about the Fluent UI example: there's some weirdness with how the theme providers are interacting with each other, the Fluent UI checkbox's styling is messing up as a result. - -Fabric Checkbox [docs](https://developer.microsoft.com/en-us/fabric#/controls/web/Checkbox) - -Fluent UI Checkbox [docs](https://microsoft.github.io/fluent-ui-react/components/checkbox/definition) - -Material UI Checkbox [docs](https://material-ui.com/components/checkboxes/) - -BaseUI Checkbox [docs](https://baseweb.design/components/Checkbox/) - -Chakra Checkbox [docs](https://chakra-ui.com/Checkbox) - -Cabon Checkbox [docs](https://www.carbondesignsystem.com/components/checkbox/code) - -AntD Checkbox [docs](https://ant.design/components/Checkbox/) - -FastDNA Checkbox [docs](https://explore.fast.design/components/Checkbox) - - -## Props - -> TODO: Consult the prop wizard to derive consistently defined props. - -| Name | Type | Default value | -| ---- | ---- | ------------- | - - -### Recommended props - -| Name | Type | -| -------------- | ----------------------------------------------------------- | -| ariaDescribedBy | string | -| ariaLabel | string | -| ariaLabelledBy | string | -| as | React.ElementType | -| checked | boolean | -| className | string | -| defaultChecked | boolean | -| defaultIndeterminate | boolean | -| disabled | boolean | -| indeterminate | boolean | -| label | string | -| name | string | -| onChange | (ev: Event, value: boolean) => void | -| vertical | boolean | - -Note: rtl, styles, and theme come from compose or the ThemeProvider. And name has been added to support checkbox in form scenarios. - -Removing the following two props because the ARIA spec dictates role='checkbox' doesn't need aria-posinset and aria-setsize. These are only valid for role='option' which is only in the case the checkbox is a part of a listbox, which is not something we need to account for in the base component API. If the user does need to provide these two props, slotProps could be used to apply additional props to any slot. - -| Name | Concern | -| ------------------------------------- | ----------------------------------------------------------------- | -| ariaPositionInset | if checkbox is in a set, should be up to the user to provide a11y | -| ariaSetSize | same as above | - -### Fabric Checkbox props - -https://developer.microsoft.com/en-us/fabric#/controls/web/checkbox - - -| Name | Type | Notes | -| -------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------| -| ariaLabel | string | | -| ariaDescribedBy | string | | -| ariaLabelledBy | string | | -| ariaPositionInset | number | | -| ariaSetSize | number | | -| boxSide | 'start' or 'end' | default 'start' | -| checked | boolean | | -| checkmarkIconProps | IIconProps | | -| className | string | | -| componentRef | IRefObject | | -| defaultChecked | boolean | | -| defaultIndeterminate | boolean | | -| disabled | boolean | | -| indeterminate | boolean | | -| inputProps | React.ButtonHTMLAttributes| | -| keytipProps | IKpeytipProps | | -| label | string | | -| onChange | (ev, checked) => void | | -| onRenderLabel | IRenderFunction | | -| styles | IStyleFunctionOrObject| | -| theme | ITheme | | - -### Fluent UI Checkbox props - - -| Name | Type | Notes | -| -------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------| -| animation | AnimationProp | | -| as | React.ElementType | default type is "div" | -| className | string | | -| content | ReactNode | | -| design | ComponentDesign | | -| disableAnimations | boolean | default false | -| overwrite | boolean | default false | -| renderer | Renderer | | -| rtl | boolean | default false | -| styles | ComponentSlotStyle | | -| target | Document | | -| theme | ThemeInput | | -| variables | any | | - -### Differences of Fabric/Fluent UI to resolve - -| Name | Type | Notes | -| -------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------| -| animation | AnimationProp | | -| disableAnimations | boolean | default false | -| overwrite | boolean | default false | -| renderer | Renderer | | -| variables | any | | -| target | Document | | -| content | ReactNode | | -| ariaPositionInSet | number | if checkbox is in a set, should be up to the user to provide a11y | -| ariaSetSize | number | | - -### Conversion process from Fabric 7 to Fluent UI Checkbox - -Props being changed: - -Some props, like style & className, should always go into the root or to the applicable element like name into the box element (replacing input). -Data-attributes will be spread using slotProps. - -Props being removed: - -ariaPoisitionInSet and ariaSetSize - when writing parent component, user should set these on the checkbox. -animations: remnant pattern of semantic UI, don't need animations for checkbox theming -defaultChecked: overloading with checked - can just set default value of checked. - -## Slots - -| Name | Considerations | -| --------- | ------------------------------------------------------ | -| root | label | -| input | actual checkbox element - what gets checked/unchecked | -| icon | visual checkmark, sideways if indeterminate | -| box | wraps input & icon - what actual gets the styling | - -## DOM structure - -General considerations: - -Only use as toggle between two mutually exclusive options (binary) or in a group with shared context to offer multiple options. - -Uncontrolled vs. controlled: implemented in the prototype already through useControlledState React hook. -Indeterminate state: When children checkboxes aren't checked, don't check parent checkbox. - -Could consider supporting an invalid state/error state but this might just be supported via styling that's passed in by the user and done through compose. - -### Recommended DOM - -```html - -``` - -### Fabric Checkbox example DOM - -```html -
- - -
-``` - -### Fluent UI Checkbox example DOM - -```html - -``` -### MUI Checkbox example DOM - -```html - -``` - -### Behaviors - -Aria spec: https://www.w3.org/TR/wai-aria-practices-1.1/#checkbox -https://www.w3.org/TR/wai-aria-practices/#checkbox - -Fluent UI HIG: https://microsoft.sharepoint-df.com/:w:/t/OPGUXLeads/EbBiGJ-gLPFGszdhSxb8X5IBFik0ax7wZLJc8FlDXOwDYA?e=Cy4Er3 - -### Disabled state - -Use `aria-disabled`. Screenreaders should let users know of the existence of the checkbox but it should be read-only. Ignore all events & no change to `checked` value allowed. - -### Checked state - -`aria-checked` indicates whether element is checked (`true`) or unchecked (`false`) but can also be `mixed` which represents a tri-state (indeterminate) input in a situation with a group of other elements that have a mixture of checked and unchecked values. - -### Indeterminate state - -Mixed state checkbox represents a checkbox that can support a partially checked state. If none of the checkboxes in a set are checked, the mixed state checkbox isn't checked (and if all are checked then so is the mixed state) but if the set contains a mix of checked and unchecked boxes, then the tri-state is appropriate so `aria-checked` will be set to `mixed`. Here's an example: https://www.w3.org/TR/wai-aria-practices/examples/checkbox/checkbox-2/checkbox-2.html - - -### Focus indicators - -Focus indicators should not show in mouse or touch interaction; they should only appear when keyboard tabbing/directional keystrokes are pressed, and should disappear when mouse/touch interactions occur. - -### Keyboarding -| Key | Description | -| --------- | -------------------------------------------------------------------- | -| Tab | Moves keyboard focus to the checkbox. | -| Space | Toggles checkbox between checked and unchecked states. | - -### Mouse input - -- `mouseenter` should change the styling of checkbox to hovered state (preview what it looks like to be toggled but not full styling - checkmark, but not background color for example as in current Fabric 7 checkbox). -- `mouseleave` should change the styling of checkbox back to non-hovered state (so remove the preview of checked state) -- `mousedown` toggle state -- `mouseup` apply styling of new state - -### Touch - -Same behavior as above except no preview of toggled state through hover. - -### Screenreader accessibility: - -#### `root`: - -- should render the native element using the `as` prop, defaulting to `div` -- should mix in native props expected for the element type defined in `as`. - -Input slot: role should be set to `checkbox` -A visible label referenced by the value of `aria-labelledby` (id of element containing the label) set on the element with role `checkbox`. -If there's additional static text representing that is descriptive, `aria-describedby` should be set to id of element containing the description. -`aria-label` set on the element with role `checkbox`. - -### Accessibility concerns for the user - -`aria-label`, `aria-labelledby`: Describe what is the purpose of the checkbox, latter points to id of element with former. - -### Themability and customization - -Both Fluent and Teams themes and other custom themes will be made with compose and the design tokens specified below. Screenshots of themed variants will be posted here soon after that work is done like the example code below. - -The `Checkbox` uses `react-texture` to provide a recomposable implementation that has no runtime performance penalties. The `BaseCheckbox` implementation can be used to provide new `slots` and default `props`: - -```tsx -const FooCheckbox = BaseCheckbox.compose({ - tokens: {}, - styles: {}, - slots: {} -}); - -render() { - - This renders as a checkbox - -} -``` - -### Composition - -1 per slot -1 per state, tagged on root - -### Component design tokens - -> Tokens represent the general look and feel of the various visual slots. Tokens feed into the styling at the right times in the right slot. -> -> Regarding naming conventions, use a camelCased name following this format: -> `{slot}{property}{state (or none for default)}`. For example: `labelSizeHovered`. -> -> Common property names: `size`, `background`, `color`, `borderRadius` -> -> Common states: `hovered`, `pressed`, `focused`, `checked`, `checkedHovered`, `disabled` - -| Name | Considerations | -| ------------------ | -------------- | -| boxBorderColor | | -| boxBorderRadius | | -| boxBorderWidth | | -| boxColor | | -| boxColorDisabled | | -| boxColorFocused | | -| boxColorHovered | | -| boxColorPressed | | -| boxSize | | -| labelColor | | -| labelColorDisabled | | -| labelColorFocused | | -| labelColorHovered | | -| labelColorPressed | | -| labelSize | | -| iconColor | | -| iconColorDisabled | | -| iconColorFocused | | -| iconColorHovered | | -| iconColorPressed | | -| iconSize | | - -NOTE! Fluent UI does not follow this convention. Their Checkbox currently uses these tokens: - -``` -background: string -disabledBackground: string -disabledBackgroundChecked: string -toggleBackground: string -toggleBorderColor: string -toggleIndicatorColor: string -toggleIndicatorSize: string -checkedBackground: string -checkedBorderColor: string -checkedBackgroundHover: string -checkedIndicatorColor: string -checkboxCheckedColor: string -checkboxToggleCheckedBackground: string -disabledToggleBackground: string -gap: string -borderColor: string -borderColorHover: string -checkboxColor: string -checkboxToggleCheckedBorderColor: string -checkedTextColor: string -disabledColor: string -disabledBorderColor: string -disabledToggleBorderColor: string -disabledCheckboxColor: string -disabledToggleIndicatorColor: string -disabledCheckedIndicatorColor: string -textColor: string -textColorHover: string -indicatorColor: string -``` -## Considerations for different screen sizes - -Won't really look or behave differently in context of different phone/tablet/desktop sizes - as in different sizes would not cause this component to look or behave differently. - -## Use cases - -The `Checkbox` component may be used within a `Form` component by providing the name prop to indicate the name of the input element to be fed into the form action. Example: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox - -## Compatibility with other libraries - -> TODO: If this component represents a selected value, how will that be used in an HTML form? Is there a code example to illustrate? - -> TODO: Is it possible this component could be rendered in a focus zone? If so, should the focus model change in that case? +Most update spec for the new Fluent Checkbox is in the specs [folder](https://github.com/microsoft/fluent-ui-react/blob/master/specs/Checkbox.md). \ No newline at end of file From 4a847a76c8f3960ee7e19e73b56f411c118169ee Mon Sep 17 00:00:00 2001 From: Aneesha Kommineni Date: Tue, 14 Jan 2020 13:48:07 -0800 Subject: [PATCH 2/5] Adding indeterminate and defaultIndeterminate props --- .../src/components/Checkbox/Checkbox.tsx | 25 +++++++++++++------ packages/react/src/utils/htmlPropsUtils.tsx | 4 +++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/react/src/components/Checkbox/Checkbox.tsx b/packages/react/src/components/Checkbox/Checkbox.tsx index 8ae819f263..31e57005cb 100644 --- a/packages/react/src/components/Checkbox/Checkbox.tsx +++ b/packages/react/src/components/Checkbox/Checkbox.tsx @@ -33,6 +33,12 @@ export interface CheckboxProps extends UIComponentProps, ChildrenComponentProps /** A checkbox's checked state can be controlled. */ checked?: SupportedIntrinsicInputProps['checked'] + /** A checkbox can be indetermiante by default - uncontrolled state. */ + defaultIndeterminate?: SupportedIntrinsicInputProps['defaultIndeterminate'] + + /** A checkbox's indeterminate state can be controlled. */ + indeterminate?: SupportedIntrinsicInputProps['indeterminate'] + /** A checkbox can appear disabled and be unable to change states. */ disabled?: SupportedIntrinsicInputProps['disabled'] @@ -65,6 +71,7 @@ export interface CheckboxProps extends UIComponentProps, ChildrenComponentProps export interface CheckboxState { checked: CheckboxProps['checked'] + indeterminate: CheckboxProps['indeterminate'] } class Checkbox extends AutoControlledComponent, CheckboxState> { @@ -82,8 +89,10 @@ class Checkbox extends AutoControlledComponent, Checkb }), checked: PropTypes.bool, defaultChecked: PropTypes.bool, + defaultIndeterminate: PropTypes.bool, disabled: PropTypes.bool, icon: customPropTypes.itemShorthandWithoutJSX, + indeterminate: customPropTypes.itemShorthandWithoutJSX, label: customPropTypes.itemShorthand, labelPosition: PropTypes.oneOf(['start', 'end']), onChange: PropTypes.func, @@ -107,30 +116,30 @@ class Checkbox extends AutoControlledComponent, Checkb } getInitialAutoControlledState(): CheckboxState { - return { checked: false } + return { checked: false, indeterminate: false } } handleChange = (e: React.ChangeEvent) => { // Checkbox component doesn't present any `input` component in markup, however all of our // components should handle events transparently. - const { disabled } = this.props + const { disabled, indeterminate } = this.props const checked = !this.state.checked if (!disabled) { - this.setState({ checked }) - _.invoke(this.props, 'onChange', e, { ...this.props, checked }) + this.setState({ checked, indeterminate }) + _.invoke(this.props, 'onChange', e, { ...this.props, checked, indeterminate }) } } handleClick = (e: React.MouseEvent | React.KeyboardEvent) => { - const { disabled } = this.props + const { disabled, indeterminate } = this.props const checked = !this.state.checked if (!disabled) { - this.setState({ checked }) + this.setState({ checked, indeterminate }) - _.invoke(this.props, 'onClick', e, { ...this.props, checked }) - _.invoke(this.props, 'onChange', e, { ...this.props, checked }) + _.invoke(this.props, 'onClick', e, { ...this.props, checked, indeterminate }) + _.invoke(this.props, 'onChange', e, { ...this.props, checked, indeterminate }) } } diff --git a/packages/react/src/utils/htmlPropsUtils.tsx b/packages/react/src/utils/htmlPropsUtils.tsx index 432d7d43e5..1740821320 100644 --- a/packages/react/src/utils/htmlPropsUtils.tsx +++ b/packages/react/src/utils/htmlPropsUtils.tsx @@ -55,9 +55,11 @@ export type HtmlInputAttrs = | 'autoCorrect' | 'autoFocus' | 'checked' + | 'defaultIndeterminate' | 'disabled' | 'form' | 'id' + | 'indeterminate' | 'list' | 'max' | 'maxLength' @@ -92,9 +94,11 @@ export const htmlInputAttrs: HtmlInputAttrs[] = [ 'autoCorrect', 'autoFocus', 'checked', + 'defaultIndeterminate', 'disabled', 'form', 'id', + 'indeterminate', 'list', 'max', 'maxLength', From 05220a4ea8fe1e64133f013e78807b830536b72d Mon Sep 17 00:00:00 2001 From: Aneesha Kommineni Date: Wed, 15 Jan 2020 00:52:06 -0800 Subject: [PATCH 3/5] example --- .../CheckboxExampleIndeterminate.shorthand.tsx | 12 ++++++++++++ .../examples/components/Checkbox/States/index.tsx | 5 +++++ 2 files changed, 17 insertions(+) create mode 100644 docs/src/examples/components/Checkbox/States/CheckboxExampleIndeterminate.shorthand.tsx diff --git a/docs/src/examples/components/Checkbox/States/CheckboxExampleIndeterminate.shorthand.tsx b/docs/src/examples/components/Checkbox/States/CheckboxExampleIndeterminate.shorthand.tsx new file mode 100644 index 0000000000..a0724a3572 --- /dev/null +++ b/docs/src/examples/components/Checkbox/States/CheckboxExampleIndeterminate.shorthand.tsx @@ -0,0 +1,12 @@ +import { Checkbox } from '@fluentui/react' +import * as React from 'react' + +const CheckboxExampleIndeterminate = () => { + return ( + <> + + + ) +} + +export default CheckboxExampleIndeterminate diff --git a/docs/src/examples/components/Checkbox/States/index.tsx b/docs/src/examples/components/Checkbox/States/index.tsx index bcc90bd532..239c950fd9 100644 --- a/docs/src/examples/components/Checkbox/States/index.tsx +++ b/docs/src/examples/components/Checkbox/States/index.tsx @@ -15,6 +15,11 @@ const States = () => ( description="A checkbox can be read-only and unable to change states." examplePath="components/Checkbox/States/CheckboxExampleDisabled" /> + ) From 341398230732aad97d9ce962c500f0185e251cc4 Mon Sep 17 00:00:00 2001 From: Aneesha Kommineni Date: Wed, 15 Jan 2020 01:00:07 -0800 Subject: [PATCH 4/5] indeterminate in onchange and onclick --- packages/react/src/components/Checkbox/Checkbox.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/react/src/components/Checkbox/Checkbox.tsx b/packages/react/src/components/Checkbox/Checkbox.tsx index 31e57005cb..cf00596278 100644 --- a/packages/react/src/components/Checkbox/Checkbox.tsx +++ b/packages/react/src/components/Checkbox/Checkbox.tsx @@ -124,22 +124,24 @@ class Checkbox extends AutoControlledComponent, Checkb // components should handle events transparently. const { disabled, indeterminate } = this.props const checked = !this.state.checked + const isIndeterminate = !this.state.indeterminate if (!disabled) { this.setState({ checked, indeterminate }) - _.invoke(this.props, 'onChange', e, { ...this.props, checked, indeterminate }) + _.invoke(this.props, 'onChange', e, { ...this.props, checked, isIndeterminate }) } } handleClick = (e: React.MouseEvent | React.KeyboardEvent) => { const { disabled, indeterminate } = this.props const checked = !this.state.checked + const isIndeterminate = !this.state.indeterminate if (!disabled) { this.setState({ checked, indeterminate }) - _.invoke(this.props, 'onClick', e, { ...this.props, checked, indeterminate }) - _.invoke(this.props, 'onChange', e, { ...this.props, checked, indeterminate }) + _.invoke(this.props, 'onClick', e, { ...this.props, checked, isIndeterminate }) + _.invoke(this.props, 'onChange', e, { ...this.props, checked, isIndeterminate }) } } From f1054bbc2e6012c60b839ed9f6fc8422dbc8a6d0 Mon Sep 17 00:00:00 2001 From: Aneesha Kommineni Date: Thu, 16 Jan 2020 00:56:17 -0800 Subject: [PATCH 5/5] responding to feedback, got aria-checked to have mixed value, etc --- .../behaviors/Checkbox/checkboxBehavior.ts | 4 ++- .../src/components/Checkbox/Checkbox.tsx | 28 ++++++++++++++----- .../components/Checkbox/checkboxStyles.ts | 7 +++++ .../components/Checkbox/checkboxVariables.ts | 1 + 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/packages/accessibility/src/behaviors/Checkbox/checkboxBehavior.ts b/packages/accessibility/src/behaviors/Checkbox/checkboxBehavior.ts index c19a674928..7cc3e5f493 100644 --- a/packages/accessibility/src/behaviors/Checkbox/checkboxBehavior.ts +++ b/packages/accessibility/src/behaviors/Checkbox/checkboxBehavior.ts @@ -13,7 +13,7 @@ import { IS_FOCUSABLE_ATTRIBUTE } from '../../attributes' const checkboxBehavior: Accessibility = props => ({ attributes: { root: { - 'aria-checked': !!props.checked, + 'aria-checked': props.indeterminate ? 'mixed' : props.checked ? 'true' : 'false', 'aria-disabled': props.disabled, role: 'checkbox', tabIndex: 0, @@ -36,4 +36,6 @@ type CheckboxBehaviorProps = { checked: boolean /** If the checkbox is in disabled state. */ disabled?: boolean + /** If the checkbox is in indetermiante state. */ + indeterminate?: boolean } diff --git a/packages/react/src/components/Checkbox/Checkbox.tsx b/packages/react/src/components/Checkbox/Checkbox.tsx index cf00596278..fe52d9ba1d 100644 --- a/packages/react/src/components/Checkbox/Checkbox.tsx +++ b/packages/react/src/components/Checkbox/Checkbox.tsx @@ -92,7 +92,7 @@ class Checkbox extends AutoControlledComponent, Checkb defaultIndeterminate: PropTypes.bool, disabled: PropTypes.bool, icon: customPropTypes.itemShorthandWithoutJSX, - indeterminate: customPropTypes.itemShorthandWithoutJSX, + indeterminate: PropTypes.bool, label: customPropTypes.itemShorthand, labelPosition: PropTypes.oneOf(['start', 'end']), onChange: PropTypes.func, @@ -124,24 +124,34 @@ class Checkbox extends AutoControlledComponent, Checkb // components should handle events transparently. const { disabled, indeterminate } = this.props const checked = !this.state.checked - const isIndeterminate = !this.state.indeterminate if (!disabled) { this.setState({ checked, indeterminate }) - _.invoke(this.props, 'onChange', e, { ...this.props, checked, isIndeterminate }) + _.invoke(this.props, 'onChange', e, { + ...this.props, + checked, + indetermiante: !this.state.indeterminate, + }) } } handleClick = (e: React.MouseEvent | React.KeyboardEvent) => { const { disabled, indeterminate } = this.props const checked = !this.state.checked - const isIndeterminate = !this.state.indeterminate if (!disabled) { this.setState({ checked, indeterminate }) - _.invoke(this.props, 'onClick', e, { ...this.props, checked, isIndeterminate }) - _.invoke(this.props, 'onChange', e, { ...this.props, checked, isIndeterminate }) + _.invoke(this.props, 'onClick', e, { + ...this.props, + checked, + indetermiante: !this.state.indeterminate, + }) + _.invoke(this.props, 'onChange', e, { + ...this.props, + checked, + indetermiante: !this.state.indeterminate, + }) } } @@ -175,7 +185,11 @@ class Checkbox extends AutoControlledComponent, Checkb outline: toggle && !this.state.checked, size: toggle ? 'medium' : 'smaller', className: Checkbox.slotClassNames.indicator, - name: toggle ? 'icon-circle' : 'icon-checkmark', + name: toggle + ? 'icon-circle' + : this.state.indeterminate + ? 'icon-square' + : 'icon-checkmark', styles: toggle ? styles.toggle : styles.checkbox, }), })} diff --git a/packages/react/src/themes/teams/components/Checkbox/checkboxStyles.ts b/packages/react/src/themes/teams/components/Checkbox/checkboxStyles.ts index 55249efc44..165a9ce349 100644 --- a/packages/react/src/themes/teams/components/Checkbox/checkboxStyles.ts +++ b/packages/react/src/themes/teams/components/Checkbox/checkboxStyles.ts @@ -84,6 +84,13 @@ const checkboxStyles: ComponentSlotStylesPrepared< background: v.disabledBackgroundChecked, borderColor: 'transparent', }), + + // TODO: in the case of indeterminate, set icon-square + // to be smaller on all sides inside the larger input box. + // ...(p.indeterminate && { + // boxSizing: 'border-box', + // flexShrink: 0, + // }), }), toggle: ({ props: p, variables: v }): ICSSInJSStyle => ({ diff --git a/packages/react/src/themes/teams/components/Checkbox/checkboxVariables.ts b/packages/react/src/themes/teams/components/Checkbox/checkboxVariables.ts index d1c9342c8d..da0456b8a5 100644 --- a/packages/react/src/themes/teams/components/Checkbox/checkboxVariables.ts +++ b/packages/react/src/themes/teams/components/Checkbox/checkboxVariables.ts @@ -122,4 +122,5 @@ export default (siteVars: any): CheckboxVariables => ({ 'colorScheme.default.foregroundDisabled', defaultValue, ), + // TODO: add variables for indeterminate state. })