diff --git a/frontend/src/metabase/admin/people/components/GroupSelect.jsx b/frontend/src/metabase/admin/people/components/GroupSelect.jsx index e92435ef8fdabb1962dd60072e1d38c5cdde7e36..60885db80c560b9ac28b322a846e07c3ae47caba 100644 --- a/frontend/src/metabase/admin/people/components/GroupSelect.jsx +++ b/frontend/src/metabase/admin/people/components/GroupSelect.jsx @@ -12,7 +12,10 @@ const GroupOption = ({ group, selectedGroups = {}, onGroupChange }) => { return ( <div className={cx("GroupOption flex align-center p1 px2", { "cursor-pointer": !disabled })} onClick={() => !disabled && onGroupChange(group, !selected) }> <span className={cx("pr1", getGroupColor(group), { disabled })}> - <CheckBox checked={selected} borderColor="currentColor" size={18} /> + <CheckBox + checked={selected} + size={18} + /> </span> {group.name} </div> diff --git a/frontend/src/metabase/admin/people/components/UserGroupSelect.jsx b/frontend/src/metabase/admin/people/components/UserGroupSelect.jsx index b8e835c5b9426b60a90a541d2ae380c7b2063d86..40c8e115b4442c3c59e1e1bd5ae87b3cd6ea76c0 100644 --- a/frontend/src/metabase/admin/people/components/UserGroupSelect.jsx +++ b/frontend/src/metabase/admin/people/components/UserGroupSelect.jsx @@ -14,7 +14,10 @@ import GroupSummary from "./GroupSummary.jsx"; const GroupOption = ({ name, color, selected, disabled, onChange }) => <div className={cx("flex align-center p1 px2", { "cursor-pointer": !disabled })} onClick={() => !disabled && onChange(!selected) }> <span className={cx("pr1", color, { disabled })}> - <CheckBox checked={selected} borderColor="currentColor" size={18} /> + <CheckBox + checked={selected} + size={18} + /> </span> {name} </div> diff --git a/frontend/src/metabase/components/CheckBox.info.js b/frontend/src/metabase/components/CheckBox.info.js index be9711d551258d1266898a28feaf373b1c35899f..aaec2b7213dac14c16024de4ca6a95c77ad8c37a 100644 --- a/frontend/src/metabase/components/CheckBox.info.js +++ b/frontend/src/metabase/components/CheckBox.info.js @@ -8,7 +8,10 @@ A standard checkbox. `; export const examples = { - "off": <CheckBox />, - "on": <CheckBox checked />, - "on inverted": <CheckBox style={{ color: "#509EE3" }} invertChecked checked /> + "Default - Off": <CheckBox />, + "On - Default blue": <CheckBox checked />, + "Purple": <CheckBox checked color='purple' />, + "Yellow": <CheckBox checked color='yellow' />, + "Red": <CheckBox checked color='red' />, + "Green": <CheckBox checked color='green' />, }; diff --git a/frontend/src/metabase/components/CheckBox.jsx b/frontend/src/metabase/components/CheckBox.jsx index d215052027bd764feb8d3a3ab2b567a258e71330..fc225a8c640a135807b2a4bb3c94c7d34b8ad107 100644 --- a/frontend/src/metabase/components/CheckBox.jsx +++ b/frontend/src/metabase/components/CheckBox.jsx @@ -1,20 +1,22 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; -import Icon from "metabase/components/Icon.jsx"; +import Icon from "metabase/components/Icon"; -import cx from "classnames"; +import { normal as defaultColors } from "metabase/lib/colors"; export default class CheckBox extends Component { static propTypes = { checked: PropTypes.bool, - onChange: PropTypes.func + onChange: PropTypes.func.isRequired, + color: PropTypes.oneOf(defaultColors), + size: PropTypes.number, // TODO - this should probably be a concrete set of options + padding: PropTypes.number// TODO - the component should pad itself properly based on the size }; static defaultProps = { size: 16, padding: 2, - borderColor: "#ddd", - checkColor: "currentColor" + color: 'blue' }; onClick() { @@ -25,21 +27,31 @@ export default class CheckBox extends Component { } render() { - const { checked, size, padding, borderColor, checkColor, className, invertChecked, style } = this.props; + const { + checked, + color, + padding, + size, + } = this.props; + + const themeColor = defaultColors[color]; + const checkboxStyle = { width: size, height: size, - backgroundColor: (invertChecked && checked) ? checkColor : "white", - border: (invertChecked && checked) ? ("2px solid " + checkColor) : ("2px solid " + borderColor), - borderRadius: 4, - display: "flex", - alignItems: "center", - justifyContent: "center", + backgroundColor: checked ? themeColor : "white", + border: `2px solid ${ checked ? themeColor : '#ddd' }`, }; return ( - <div style={style} className={cx("cursor-pointer", className)} onClick={() => this.onClick()}> - <div style={checkboxStyle}> - { checked ? <Icon style={{ color: invertChecked ? "white" : checkColor }} name="check" size={size - padding * 2} /> : null } + <div className="cursor-pointer" onClick={() => this.onClick()}> + <div style={checkboxStyle} className="flex align-center justify-center rounded"> + { checked && ( + <Icon + style={{ color: checked ? 'white' : themeColor }} + name="check" + size={size - padding * 2} + /> + )} </div> </div> ) diff --git a/frontend/src/metabase/components/StackedCheckBox.info.js b/frontend/src/metabase/components/StackedCheckBox.info.js index 69a97375d36ae330d907dc25c0ed6f90a39fa0ca..433c096e213c6d7dd417381b7a5201ad7c2430a5 100644 --- a/frontend/src/metabase/components/StackedCheckBox.info.js +++ b/frontend/src/metabase/components/StackedCheckBox.info.js @@ -8,7 +8,7 @@ A stacked checkbox, representing "all" items. `; export const examples = { - "off": <StackedCheckBox />, - "on": <StackedCheckBox checked />, - "on inverted": <StackedCheckBox style={{ color: "#509EE3" }} invertChecked checked /> + "Off - Default": <StackedCheckBox />, + "Checked": <StackedCheckBox checked />, + "Checked with color": <StackedCheckBox checked color='purple' />, }; diff --git a/frontend/src/metabase/components/StackedCheckBox.jsx b/frontend/src/metabase/components/StackedCheckBox.jsx index 0332500ed3045a0edf069d2f80b68b3d51d1fd82..1567dfd9e8ddc2504f97ad709083f78009b50336 100644 --- a/frontend/src/metabase/components/StackedCheckBox.jsx +++ b/frontend/src/metabase/components/StackedCheckBox.jsx @@ -1,11 +1,21 @@ import React from "react"; - import CheckBox from "metabase/components/CheckBox.jsx"; +const OFFSET = 4; + const StackedCheckBox = (props) => - <span className={props.className} style={{ ...props.style, position: "relative" }}> - <CheckBox {...props} className={null} style={{ position: "absolute", top: -3, left: 3, zIndex: -1 }} /> - <CheckBox {...props} className={null} style={{}} /> - </span> + <div className="relative"> + <span + className="absolute" + style={{ + top: -OFFSET, + left: OFFSET, + zIndex: -1 + }} + > + <CheckBox {...props} /> + </span> + <CheckBox {...props} /> + </div> export default StackedCheckBox; diff --git a/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap b/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap index ecd542cc21ab2618366225fc7e38c539440603d6..a815f23cff41b4a3cdb6f87754c79987796a649e 100644 --- a/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap +++ b/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap @@ -55,22 +55,18 @@ exports[`Button should render "with an icon" correctly 1`] = ` </button> `; -exports[`CheckBox should render "off" correctly 1`] = ` +exports[`CheckBox should render "Default - Off" correctly 1`] = ` <div className="cursor-pointer" onClick={[Function]} - style={undefined} > <div + className="flex align-center justify-center rounded" style={ Object { - "alignItems": "center", "backgroundColor": "white", "border": "2px solid #ddd", - "borderRadius": 4, - "display": "flex", "height": 16, - "justifyContent": "center", "width": 16, } } @@ -78,26 +74,18 @@ exports[`CheckBox should render "off" correctly 1`] = ` </div> `; -exports[`CheckBox should render "on inverted" correctly 1`] = ` +exports[`CheckBox should render "Green" correctly 1`] = ` <div className="cursor-pointer" onClick={[Function]} - style={ - Object { - "color": "#509EE3", - } - } > <div + className="flex align-center justify-center rounded" style={ Object { - "alignItems": "center", - "backgroundColor": "currentColor", - "border": "2px solid currentColor", - "borderRadius": 4, - "display": "flex", + "backgroundColor": "#9CC177", + "border": "2px solid #9CC177", "height": 16, - "justifyContent": "center", "width": 16, } } @@ -124,22 +112,18 @@ exports[`CheckBox should render "on inverted" correctly 1`] = ` </div> `; -exports[`CheckBox should render "on" correctly 1`] = ` +exports[`CheckBox should render "On - Default blue" correctly 1`] = ` <div className="cursor-pointer" onClick={[Function]} - style={undefined} > <div + className="flex align-center justify-center rounded" style={ Object { - "alignItems": "center", - "backgroundColor": "white", - "border": "2px solid #ddd", - "borderRadius": 4, - "display": "flex", + "backgroundColor": "#509EE3", + "border": "2px solid #509EE3", "height": 16, - "justifyContent": "center", "width": 16, } } @@ -152,7 +136,7 @@ exports[`CheckBox should render "on" correctly 1`] = ` size={12} style={ Object { - "color": "currentColor", + "color": "white", } } viewBox="0 0 32 32" @@ -166,136 +150,181 @@ exports[`CheckBox should render "on" correctly 1`] = ` </div> `; -exports[`StackedCheckBox should render "off" correctly 1`] = ` -<span - className={undefined} - style={ - Object { - "position": "relative", - } - } +exports[`CheckBox should render "Purple" correctly 1`] = ` +<div + className="cursor-pointer" + onClick={[Function]} > <div - className="cursor-pointer" - onClick={[Function]} + className="flex align-center justify-center rounded" style={ Object { - "left": 3, - "position": "absolute", - "top": -3, - "zIndex": -1, + "backgroundColor": "#A989C5", + "border": "2px solid #A989C5", + "height": 16, + "width": 16, } } > - <div + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} style={ Object { - "alignItems": "center", - "backgroundColor": "white", - "border": "2px solid #ddd", - "borderRadius": 4, - "display": "flex", - "height": 16, - "justifyContent": "center", - "width": 16, + "color": "white", } } - /> + viewBox="0 0 32 32" + width={12} + > + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " + /> + </svg> </div> +</div> +`; + +exports[`CheckBox should render "Red" correctly 1`] = ` +<div + className="cursor-pointer" + onClick={[Function]} +> <div - className="cursor-pointer" - onClick={[Function]} - style={Object {}} + className="flex align-center justify-center rounded" + style={ + Object { + "backgroundColor": "#EF8C8C", + "border": "2px solid #EF8C8C", + "height": 16, + "width": 16, + } + } > - <div + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} style={ Object { - "alignItems": "center", - "backgroundColor": "white", - "border": "2px solid #ddd", - "borderRadius": 4, - "display": "flex", - "height": 16, - "justifyContent": "center", - "width": 16, + "color": "white", } } - /> + viewBox="0 0 32 32" + width={12} + > + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " + /> + </svg> </div> -</span> +</div> `; -exports[`StackedCheckBox should render "on inverted" correctly 1`] = ` -<span - className={undefined} - style={ - Object { - "color": "#509EE3", - "position": "relative", - } - } +exports[`CheckBox should render "Yellow" correctly 1`] = ` +<div + className="cursor-pointer" + onClick={[Function]} > <div - className="cursor-pointer" - onClick={[Function]} + className="flex align-center justify-center rounded" style={ Object { - "left": 3, - "position": "absolute", - "top": -3, - "zIndex": -1, + "backgroundColor": "#f9d45c", + "border": "2px solid #f9d45c", + "height": 16, + "width": 16, } } > - <div + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} style={ Object { - "alignItems": "center", - "backgroundColor": "currentColor", - "border": "2px solid currentColor", - "borderRadius": 4, - "display": "flex", - "height": 16, - "justifyContent": "center", - "width": 16, + "color": "white", } } + viewBox="0 0 32 32" + width={12} > - <svg - className="Icon Icon-check" - fill="currentcolor" - height={12} - name="check" - size={12} + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " + /> + </svg> + </div> +</div> +`; + +exports[`StackedCheckBox should render "Checked with color" correctly 1`] = ` +<div + className="relative" +> + <span + className="absolute" + style={ + Object { + "left": 4, + "top": -4, + "zIndex": -1, + } + } + > + <div + className="cursor-pointer" + onClick={[Function]} + > + <div + className="flex align-center justify-center rounded" style={ Object { - "color": "white", + "backgroundColor": "#A989C5", + "border": "2px solid #A989C5", + "height": 16, + "width": 16, } } - viewBox="0 0 32 32" - width={12} > - <path - d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " - /> - </svg> + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} + style={ + Object { + "color": "white", + } + } + viewBox="0 0 32 32" + width={12} + > + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " + /> + </svg> + </div> </div> - </div> + </span> <div className="cursor-pointer" onClick={[Function]} - style={Object {}} > <div + className="flex align-center justify-center rounded" style={ Object { - "alignItems": "center", - "backgroundColor": "currentColor", - "border": "2px solid currentColor", - "borderRadius": 4, - "display": "flex", + "backgroundColor": "#A989C5", + "border": "2px solid #A989C5", "height": 16, - "justifyContent": "center", "width": 16, } } @@ -320,40 +349,70 @@ exports[`StackedCheckBox should render "on inverted" correctly 1`] = ` </svg> </div> </div> -</span> +</div> `; -exports[`StackedCheckBox should render "on" correctly 1`] = ` -<span - className={undefined} - style={ - Object { - "position": "relative", - } - } +exports[`StackedCheckBox should render "Checked" correctly 1`] = ` +<div + className="relative" > - <div - className="cursor-pointer" - onClick={[Function]} + <span + className="absolute" style={ Object { - "left": 3, - "position": "absolute", - "top": -3, + "left": 4, + "top": -4, "zIndex": -1, } } > <div + className="cursor-pointer" + onClick={[Function]} + > + <div + className="flex align-center justify-center rounded" + style={ + Object { + "backgroundColor": "#509EE3", + "border": "2px solid #509EE3", + "height": 16, + "width": 16, + } + } + > + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} + style={ + Object { + "color": "white", + } + } + viewBox="0 0 32 32" + width={12} + > + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " + /> + </svg> + </div> + </div> + </span> + <div + className="cursor-pointer" + onClick={[Function]} + > + <div + className="flex align-center justify-center rounded" style={ Object { - "alignItems": "center", - "backgroundColor": "white", - "border": "2px solid #ddd", - "borderRadius": 4, - "display": "flex", + "backgroundColor": "#509EE3", + "border": "2px solid #509EE3", "height": 16, - "justifyContent": "center", "width": 16, } } @@ -366,7 +425,7 @@ exports[`StackedCheckBox should render "on" correctly 1`] = ` size={12} style={ Object { - "color": "currentColor", + "color": "white", } } viewBox="0 0 32 32" @@ -378,46 +437,57 @@ exports[`StackedCheckBox should render "on" correctly 1`] = ` </svg> </div> </div> +</div> +`; + +exports[`StackedCheckBox should render "Off - Default" correctly 1`] = ` +<div + className="relative" +> + <span + className="absolute" + style={ + Object { + "left": 4, + "top": -4, + "zIndex": -1, + } + } + > + <div + className="cursor-pointer" + onClick={[Function]} + > + <div + className="flex align-center justify-center rounded" + style={ + Object { + "backgroundColor": "white", + "border": "2px solid #ddd", + "height": 16, + "width": 16, + } + } + /> + </div> + </span> <div className="cursor-pointer" onClick={[Function]} - style={Object {}} > <div + className="flex align-center justify-center rounded" style={ Object { - "alignItems": "center", "backgroundColor": "white", "border": "2px solid #ddd", - "borderRadius": 4, - "display": "flex", "height": 16, - "justifyContent": "center", "width": 16, } } - > - <svg - className="Icon Icon-check" - fill="currentcolor" - height={12} - name="check" - size={12} - style={ - Object { - "color": "currentColor", - } - } - viewBox="0 0 32 32" - width={12} - > - <path - d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " - /> - </svg> - </div> + /> </div> -</span> +</div> `; exports[`Toggle should render "off" correctly 1`] = ` diff --git a/frontend/src/metabase/questions/components/ActionHeader.jsx b/frontend/src/metabase/questions/components/ActionHeader.jsx index a0eb0cea3e13c5b3c2f265158ebbaab2374e0411..ad1c6ea6e22d1860b20fda498867c40a959da470 100644 --- a/frontend/src/metabase/questions/components/ActionHeader.jsx +++ b/frontend/src/metabase/questions/components/ActionHeader.jsx @@ -14,13 +14,14 @@ import LabelPopover from "../containers/LabelPopover.jsx"; const ActionHeader = ({ visibleCount, selectedCount, allAreSelected, sectionIsArchive, setAllSelected, setArchived, labels }) => <div className={S.actionHeader}> <Tooltip tooltip={"Select all " + visibleCount} isEnabled={!allAreSelected}> - <StackedCheckBox - checked={allAreSelected} - className="ml1" - onChange={(e) => setAllSelected(e.target.checked)} - size={20} padding={3} borderColor="currentColor" - invertChecked - /> + <span className="ml1"> + <StackedCheckBox + checked={allAreSelected} + onChange={e => setAllSelected(e.target.checked)} + size={20} + padding={3} + /> + </span> </Tooltip> <span className={S.selectedCount}> {selectedCount} selected diff --git a/frontend/src/metabase/questions/components/Item.jsx b/frontend/src/metabase/questions/components/Item.jsx index 93e4450e306d2101a5215889dfa9962e17ac1d4e..28266b96e969c28aba247a1c0a91e4aaf7081fd7 100644 --- a/frontend/src/metabase/questions/components/Item.jsx +++ b/frontend/src/metabase/questions/components/Item.jsx @@ -36,19 +36,18 @@ const Item = ({ /> } { setItemSelected && - <CheckBox - className={cx( - "cursor-pointer absolute top left", - { "visible text-brand": selected }, - { "hover-child text-brand-hover text-light-blue transition-color": !selected } - )} - checked={selected} - onChange={(e) => setItemSelected({ [id]: e.target.checked })} - size={ITEM_ICON_SIZE} - padding={3} - borderColor="currentColor" - invertChecked - /> + <span className={cx( + "absolute top left", + { "visible": selected }, + { "hover-child": !selected } + )}> + <CheckBox + checked={selected} + onChange={e => setItemSelected({ [id]: e.target.checked })} + size={ITEM_ICON_SIZE} + padding={3} + /> + </span> } </div> <ItemBody diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingOrderedFields.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingOrderedFields.jsx index 4c9df5db752a42dd18ccd311e3c0ad5f014318c7..da61ad4455eab56327c50355187b36ae22a67fd5 100644 --- a/frontend/src/metabase/visualizations/components/settings/ChartSettingOrderedFields.jsx +++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingOrderedFields.jsx @@ -56,7 +56,10 @@ export default class ChartSettingOrderedFields extends Component { outline="list" > <div className={cx("flex align-center p1", { "text-grey-2": !item.enabled })} > - <CheckBox checked={item.enabled} className={cx("text-brand", { "text-grey-2": !item.enabled })} onChange={(e) => this.setEnabled(i, e.target.checked)} invertChecked /> + <CheckBox + checked={item.enabled} + onChange={e => this.setEnabled(i, e.target.checked)} + /> <span className="ml1 h4">{columnNames[item.name]}</span> <Icon className="flex-align-right text-grey-2 mr1 cursor-pointer" name="grabber" width={14} height={14}/> </div>