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

feat(elements|ino-switch): support icons #724

Merged
merged 25 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7057d19
chore: publish v7.1.1
janivo Aug 19, 2022
806fdf4
style(elements|ino-switch): update design (#697)
TobiasHeimGalindo Aug 19, 2022
596ff31
fix:resolve merge conflicts
TobiasHeimGalindo Aug 23, 2022
6ff8cda
refactor: remove color-scheme from ino-switch
TobiasHeimGalindo Aug 30, 2022
37e1938
chore: auto-generated
TobiasHeimGalindo Aug 30, 2022
6ec1bab
refactor: remove theme selector
TobiasHeimGalindo Sep 2, 2022
21618c2
refactor: use new-theme and fix the height of the switch
TobiasHeimGalindo Sep 5, 2022
3976643
refactor: naming and remove ino-range exclusive color in new theme
TobiasHeimGalindo Sep 5, 2022
d1ae6e1
feat: add icon prop displaying two icons for the ino-switch
TobiasHeimGalindo Sep 6, 2022
4f02b19
chore: auto-generated
TobiasHeimGalindo Sep 6, 2022
097e967
chore: auto-generated
TobiasHeimGalindo Sep 6, 2022
f853c5a
Merge branch 'master' of https://github.com/inovex/elements
TobiasHeimGalindo Sep 6, 2022
9c78aa1
feat: attempt at second handle hover
TobiasHeimGalindo Sep 7, 2022
2c2876f
Merge branch 'master' of https://github.com/inovex/elements
TobiasHeimGalindo Sep 8, 2022
ba050cb
refactor: add 2 icon props
TobiasHeimGalindo Sep 8, 2022
023800b
chore: auto-generated
TobiasHeimGalindo Sep 8, 2022
7cf45d6
Merge branch 'master' of https://github.com/inovex/elements
TobiasHeimGalindo Oct 13, 2022
a70680e
feat: add custom disabled style for switch icons
TobiasHeimGalindo Oct 13, 2022
f9cc240
feat: add custom hover state
TobiasHeimGalindo Oct 14, 2022
8979050
Merge branch 'master' of https://github.com/inovex/elements
TobiasHeimGalindo Oct 14, 2022
29d96c5
chore: resolve merge conflicts
TobiasHeimGalindo Oct 14, 2022
15d6850
chore: auto-generated
TobiasHeimGalindo Oct 14, 2022
9c0998a
refactor: scss theme colors naming
TobiasHeimGalindo Oct 14, 2022
b4720dd
refactor: use slots to enable icon toggle mode
janivo Oct 18, 2022
168c237
refactor: remove unused scss classes
TobiasHeimGalindo Oct 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 159 additions & 61 deletions packages/elements/src/components/ino-switch/ino-switch.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
@use '@material/switch';
@use '@material/switch/styles';
@use 'base/new-theme' as theme;


@use 'base/theme' as old-theme;

@mixin set-track-border-color {
.mdc-switch__track {
Expand All @@ -13,90 +12,189 @@
}
}


// general styles
ino-switch {
display: flex;
align-items: center;
gap: 10px;

&:not(.ino-switch-disabled) .mdc-switch {
cursor: pointer;
}

&.ino-switch-disabled .mdc-switch {
cursor: default;
pointer-events: none;
}

.mdc-switch__ripple {
display: none;
}
}


// default switch styles
ino-switch.ino-switch__default {

height: 22px;

@include switch.theme(
(
selected-handle-color: white,
selected-hover-handle-color: white,
selected-focus-handle-color: white,
selected-pressed-handle-color: white,
disabled-selected-handle-color: theme.$n-6,
selected-track-color: theme.$primary,
selected-hover-track-color: theme.$primary,
selected-focus-track-color: theme.$primary,
selected-pressed-track-color: theme.$primary,
unselected-focus-track-color: theme.$n-5,
unselected-hover-track-color: theme.$n-5,
disabled-selected-track-color: transparent,
)
(
selected-handle-color: white,
selected-hover-handle-color: white,
selected-focus-handle-color: white,
selected-pressed-handle-color: white,
selected-track-color: theme.$primary,
selected-hover-track-color: theme.$primary,
selected-focus-track-color: theme.$primary,
selected-pressed-track-color: theme.$primary,
unselected-focus-track-color: theme.$n-5,
unselected-hover-track-color: theme.$n-5,
track-height: 20px,
track-width: 36px,
track-shape: 18px,
handle-height: 16px,
handle-width: 16px,
handle-shape: 14px,
selected-icon-size: 10px,
unselected-icon-size: 10px,
handle-surface-color: white,
unselected-handle-color: white,
unselected-track-color: theme.$n-6,
unselected-hover-handle-color: white,
unselected-focus-handle-color: white,
unselected-pressed-handle-color: white,
disabled-selected-handle-color: theme.$n-6,
disabled-selected-track-color: transparent,
disabled-unselected-track-color: transparent,
disabled-unselected-handle-color: theme.$n-6,
disabled-track-opacity: 1,
disabled-handle-opacity: 1,
)
);

.mdc-switch--selected:focus,
.mdc-switch--unselected:focus {
@include set-track-border-color;
}

.mdc-switch {
&--selected {
.mdc-switch__handle {
margin-left: -2px;
}
&--selected .mdc-switch__handle {
margin-left: -2px;
}
&--unselected {
.mdc-switch__handle {
margin-left: 2px;
}

&--unselected .mdc-switch__handle {
margin-left: 2px;
}
}

// custom disabled state styling
.mdc-switch:disabled {
.mdc-switch__track {
opacity: 1;
&:disabled .mdc-switch__track {
border: 2px solid theme.$n-6;
margin: -1.5px;
}
.mdc-switch__handle::after {
opacity: 1;
}
}
}

ino-switch {
$disabled-color: #F3F3F5;

// icon toggle switch styles
ino-switch.ino-switch__icon-toggle .mdc-switch {
display: flex;
gap: 10px;
align-items: center;
height: 30px;
cursor: pointer;
justify-content: center;
height: 36px;
width: 104px;

&.ino-switch-disabled {
cursor: default;
pointer-events: none;
.switch-icon {
display: flex;
justify-content: center;
align-items: center;
height: 28px;
width: 48px;
color: theme.$n-3;
fill: theme.$n-3;

ino-icon {
--icon-width: 20px;
--icon-height: 20px;
--icon-color: #{theme.$n-3};
}

&--selected ino-icon {
--icon-color: #{old-theme.color(primary, dark)};
color: old-theme.color(primary, dark);
fill: old-theme.color(primary, dark);
}

&--unselected::after {
content: '';
position: absolute;
top: 0;
left: 0;
background-color: transparent;
transition: background-color 300ms linear;
width: 100%;
height: 100%;
border-radius: 32px;
z-index: -1;
}
}

&:hover .switch-icon--unselected::after {
background-color: theme.$n-7;
}

// set basic styles, DOES NOT SUPPORT CSS-VARS
@include switch.theme(
(
track-height: 20px,
track-width: 36px,
track-shape: 18px,
handle-height: 16px,
handle-width: 16px,
handle-shape: 14px,
selected-icon-size: 10px,
unselected-icon-size: 10px,
handle-surface-color: white,
unselected-handle-color: white,
unselected-track-color: theme.$n-6,
disabled-unselected-handle-color: theme.$n-6,
disabled-unselected-track-color: transparent,
unselected-hover-handle-color: white,
unselected-focus-handle-color: white,
unselected-pressed-handle-color: white,
)
(
selected-handle-color: white,
selected-hover-handle-color: white,
selected-focus-handle-color: white,
selected-pressed-handle-color: white,
selected-track-color: theme.$n-7,
selected-hover-track-color: theme.$n-6,
selected-focus-track-color: theme.$n-6,
selected-pressed-track-color: theme.$n-6,
track-height: 36px,
track-width: 104px,
track-shape: 18px,
handle-height: 28px,
handle-width: 48px,
handle-shape: 14px,
selected-icon-size: 20px,
unselected-icon-size: 20px,
handle-surface-color: white,
unselected-handle-color: white,
unselected-track-color: theme.$n-7,
unselected-focus-track-color: theme.$n-6,
unselected-hover-track-color: theme.$n-6,
disabled-selected-track-color: transparent,
disabled-selected-handle-color: white,
disabled-unselected-handle-color: white,
disabled-unselected-track-color: $disabled-color,
disabled-track-opacity: 1,
unselected-hover-handle-color: white,
unselected-focus-handle-color: white,
unselected-pressed-handle-color: white,
)
);

// hide ripple effect
.mdc-switch__ripple {
display: none;
&.mdc-switch {
.mdc-switch__track {
position: absolute;
}

&--selected .mdc-switch__handle {
margin-left: -4px;
}

&--unselected .mdc-switch__handle {
margin-left: 4px;
}
}
}

ino-switch.ino-switch-disabled.ino-switch__icon-toggle .switch-icon--selected ino-icon {
--icon-color: #{theme.$n-4};
color: theme.$n-4;
fill: theme.$n-4;
}
83 changes: 69 additions & 14 deletions packages/elements/src/components/ino-switch/ino-switch.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import {MDCSwitch} from '@material/switch';
import {Component, ComponentInterface, Element, Event, EventEmitter, h, Host, Prop, Watch,} from '@stencil/core';
import { MDCSwitch } from '@material/switch';
import {
Component,
ComponentInterface,
Element,
Event,
EventEmitter,
h,
Host,
Prop,
Watch,
} from '@stencil/core';
import classNames from 'classnames';

import {generateUniqueId} from '../../util/component-utils';
import {renderHiddenInput} from '../../util/helpers';
import { generateUniqueId, hasSlotContent } from '../../util/component-utils';
import { renderHiddenInput } from '../../util/helpers';

/**
* @slot default - Label of the switch
Expand Down Expand Up @@ -45,9 +55,17 @@ export class Switch implements ComponentInterface {
*/
@Prop() name?: string;


componentDidLoad() {
this.mdcSwitch = new MDCSwitch(this.mdcSwitchEl);

const hasLeadingSlot = hasSlotContent(this.el, 'leading');
const hasTrailingSlot = hasSlotContent(this.el, 'trailing');

if (hasLeadingSlot != hasTrailingSlot) {
console.error(
'[ino-switch] Two icons (leading & trailing) are required in order to use the icon switch.'
);
}
}

disconnectedCallback() {
Expand All @@ -62,50 +80,87 @@ export class Switch implements ComponentInterface {
private handleChange = (e: MouseEvent) => {
e.stopPropagation();

if(this.disabled) return;
if (this.disabled) return;

this.checkedChange.emit(!this.checked);
};

render() {
const {el, name, disabled} = this;
const { el, name, disabled } = this;

const hiddenInput = renderHiddenInput(el, name, '', disabled);
hiddenInput.checked = this.checked;

const hasLeadingSlot = hasSlotContent(this.el, 'leading');
const hasTrailingSlot = hasSlotContent(this.el, 'trailing');

const hostClasses = classNames(
'ino-switch',
hasLeadingSlot || hasTrailingSlot
? 'ino-switch__icon-toggle'
: 'ino-switch__default',
{
'ino-switch-disabled': this.disabled
'ino-switch-disabled': this.disabled,
'ino-switch-icon-disabled': this.disabled,
}
);

const switchClasses = classNames(
'mdc-switch',
this.checked ? 'mdc-switch--selected' : 'mdc-switch--unselected',
{
'mdc-switch': true,
'ino-switch__icon-toggle': hasLeadingSlot && hasTrailingSlot,
}
);

const iconClasses = classNames('mdc-switch__icons', 'switch-icon');

const leadingIconClasses = classNames(
iconClasses,
!this.checked ? 'switch-icon--selected' : 'switch-icon--unselected'
);

const trailingIconClasses = classNames(
iconClasses,
this.checked ? 'switch-icon--selected' : 'switch-icon--unselected'
);

return (
<Host class={hostClasses} checked={this.checked} disabled={this.disabled} onClick={this.handleChange}>
<Host
class={hostClasses}
checked={this.checked}
disabled={this.disabled}
onClick={this.handleChange}
>
<button
id={this.switchId}
ref={el => this.mdcSwitchEl = el}
ref={(el) => (this.mdcSwitchEl = el)}
class={switchClasses}
disabled={this.disabled}
type="button"
role="switch"
aria-checked={this.checked}

>
<div class="mdc-switch__track"/>
{hasLeadingSlot && (
<span class={leadingIconClasses}>
<slot name={'leading'} />
</span>
)}
<div class="mdc-switch__track" />
<div class="mdc-switch__handle-track">
<div class="mdc-switch__handle">
<div class="mdc-switch__ripple"/>
<div class="mdc-switch__ripple" />
</div>
</div>
{hasTrailingSlot && (
<span class={trailingIconClasses}>
<slot name={'trailing'} />
</span>
)}
</button>
<label htmlFor={this.switchId} onClick={(e) => e.stopPropagation()}>
<slot/>
<slot />
</label>
</Host>
);
Expand Down
Loading