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

Add internal text to switch component #3327

Merged
merged 15 commits into from
Feb 6, 2019
43 changes: 40 additions & 3 deletions packages/core/src/components/forms/_controls.scss
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ $control-indicator-spacing: $pt-grid-size !default;
$switch-indicator-margin: 2px !default;
$switch-indicator-size: calc(1em - #{$switch-indicator-margin * 2});

$switch-indicator-text-font-size: 0.6em; //@KEVINNG MAKE THIS RIGHT
$switch-indicator-text-line-height: 1.7em; //@KEVINNG MAKE THIS RIGHT
$switch-indicator-text-outside-margin: 0.75em; //@KEVINNG MAKE THIS RIGHT
$switch-indicator-text-inside-margin: 1.75em; //@KEVINNG MAKE THIS RIGHT
giladgray marked this conversation as resolved.
Show resolved Hide resolved

$switch-background-color: rgba($gray4, 0.5) !default;
$switch-background-color-hover: rgba($gray2, 0.5) !default;
$switch-background-color-active: rgba($gray1, 0.5) !default;
Expand Down Expand Up @@ -350,7 +355,8 @@ $control-indicator-spacing: $pt-grid-size !default;
// override default button styles, never have a box-shadow here.
// stylelint-disable-next-line declaration-no-important
box-shadow: none !important;
width: $switch-width;
width: auto;
min-width: $switch-width;
transition: background-color $pt-transition-duration $pt-transition-ease;

&::before {
Expand All @@ -367,8 +373,8 @@ $control-indicator-spacing: $pt-grid-size !default;
}

input:checked ~ .#{$ns}-control-indicator::before {
// 1em is size of indicator
left: $switch-width - 1em;
right: 0;
left: auto;
giladgray marked this conversation as resolved.
Show resolved Hide resolved
}

&.#{$ns}-large {
Expand Down Expand Up @@ -401,6 +407,37 @@ $control-indicator-spacing: $pt-grid-size !default;
box-shadow: inset $dark-button-box-shadow;
}
}

.#{$ns}-control-indicator-child {
text-align: center;
font-size: $switch-indicator-text-font-size;

&.#{$ns}-switch-active-text {
visibility: hidden;
margin-right: $switch-indicator-text-inside-margin;
margin-left: $switch-indicator-text-outside-margin;
line-height: 0;
}

&.#{$ns}-switch-inactive-text {
visibility: visible;
margin-right: $switch-indicator-text-outside-margin;
margin-left: $switch-indicator-text-inside-margin;
line-height: $switch-indicator-text-line-height;
}
}

input:checked ~ .#{$ns}-control-indicator {
.#{$ns}-switch-active-text {
visibility: visible;
line-height: $switch-indicator-text-line-height;
}

.#{$ns}-switch-inactive-text {
visibility: hidden;
line-height: 0;
}
}
}

.#{$ns}-dark & {
Expand Down
40 changes: 36 additions & 4 deletions packages/core/src/components/forms/controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export interface IControlProps extends IProps, HTMLInputProps {
interface IControlInternalProps extends IControlProps {
type: "checkbox" | "radio";
typeClassName: string;
indicatorChildren?: React.ReactNode[];
giladgray marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand All @@ -92,6 +93,7 @@ const Control: React.SFC<IControlInternalProps> = ({
alignIndicator,
children,
className,
indicatorChildren,
inline,
inputRef,
label,
Expand All @@ -117,7 +119,7 @@ const Control: React.SFC<IControlInternalProps> = ({
return (
<TagName className={classes} style={style}>
<input {...htmlProps} ref={inputRef} type={type} />
<span className={Classes.CONTROL_INDICATOR} />
<span className={Classes.CONTROL_INDICATOR}>{indicatorChildren}</span>
{label}
{labelElement}
{children}
Expand All @@ -129,13 +131,43 @@ const Control: React.SFC<IControlInternalProps> = ({
// Switch
//

export interface ISwitchProps extends IControlProps {}
export interface ISwitchProps extends IControlProps {
/**
* String to display within the switch control component when the switch is active ("on").
giladgray marked this conversation as resolved.
Show resolved Hide resolved
*/
internalTextActive?: string;
giladgray marked this conversation as resolved.
Show resolved Hide resolved

/**
* String to display within the switch control component when the switch is inactive ("off").
*/
internalTextInactive?: string;
giladgray marked this conversation as resolved.
Show resolved Hide resolved
}

export class Switch extends React.PureComponent<ISwitchProps> {
public static displayName = `${DISPLAYNAME_PREFIX}.Switch`;

private switchText = [
giladgray marked this conversation as resolved.
Show resolved Hide resolved
<div
key={`${Classes.SWITCH}-active-text`}
className={classNames(`${Classes.CONTROL_INDICATOR}-child`, `${Classes.SWITCH}-active-text`)}
>
{this.props.internalTextActive}
</div>,
<div
key={`${Classes.SWITCH}-inactive-text`}
className={classNames(`${Classes.CONTROL_INDICATOR}-child`, `${Classes.SWITCH}-inactive-text`)}
giladgray marked this conversation as resolved.
Show resolved Hide resolved
>
{this.props.internalTextInactive}
</div>,
];
public render() {
return <Control {...this.props} type="checkbox" typeClassName={Classes.SWITCH} />;
return (
<Control
{...this.props}
type="checkbox"
typeClassName={Classes.SWITCH}
indicatorChildren={this.switchText}
/>
);
}
}

Expand Down
11 changes: 10 additions & 1 deletion packages/core/test/controls/controlsTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,16 @@ describe("Controls:", () => {
});
});

controlsTests(Switch, "checkbox", Classes.SWITCH);
controlsTests(Switch, "checkbox", Classes.SWITCH, () => {
describe("internal text", () => {
const switchWithText = mount(
<Switch internalTextActive="Active Text" internalTextInactive="Inactive Text" />,
);
it("renders internal text", () => {
giladgray marked this conversation as resolved.
Show resolved Hide resolved
assert.equal(switchWithText.find(`.${Classes.SWITCH}-active-text`).text(), "Active Text");
});
});
});

controlsTests(Radio, "radio", Classes.RADIO);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export class SwitchExample extends CheckboxExample {
<Switch {...this.state} labelElement={<strong>Enabled</strong>} />
<Switch {...this.state} labelElement={<em>Public</em>} />
<Switch {...this.state} labelElement={<u>Cooperative</u>} defaultChecked={true} />
<Switch
{...this.state}
labelElement={"Containing Text"}
internalTextActive="activeText"
internalTextInactive="inactiveText"
/>
</div>
<small style={{ width: "100%", textAlign: "center" }}>
This example uses <Code>labelElement</Code> to demonstrate JSX labels.
Expand Down