@justeattakeaway/pie-switch 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -0
- package/declaration.d.ts +9 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.js +226 -0
- package/dist/react.d.ts +76 -0
- package/dist/react.js +74 -0
- package/package.json +40 -0
- package/src/defs.ts +38 -0
- package/src/index.ts +125 -0
- package/src/switch.scss +148 -0
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img align="center" src="../../../readme_image.png" height="200" alt="">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/@justeattakeaway/pie-switch">
|
|
7
|
+
<img alt="GitHub Workflow Status" src="https://img.shields.io/npm/v/@justeattakeaway/pie-switch.svg">
|
|
8
|
+
</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
# Table of Contents
|
|
12
|
+
|
|
13
|
+
1. [Introduction](#pie-switch)
|
|
14
|
+
2. [Installation](#installation)
|
|
15
|
+
3. [Importing the component](#importing-the-component)
|
|
16
|
+
4. [Peer Dependencies](#peer-dependencies)
|
|
17
|
+
5. [Props](#props)
|
|
18
|
+
6. [Contributing](#contributing)
|
|
19
|
+
|
|
20
|
+
## pie-switch
|
|
21
|
+
|
|
22
|
+
`pie-switch` is a Web Component built using the Lit library.
|
|
23
|
+
|
|
24
|
+
This component can be easily integrated into various frontend frameworks and customized through a set of properties.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
To install `pie-switch` in your application, run the following on your command line:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# npm
|
|
33
|
+
$ npm i @justeattakeaway/pie-switch
|
|
34
|
+
|
|
35
|
+
# yarn
|
|
36
|
+
$ yarn add @justeattakeaway/pie-switch
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For full information on using PIE components as part of an application, check out the [Getting Started Guide](https://github.com/justeattakeaway/pie/wiki/Getting-started-with-PIE-Web-Components).
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Importing the component
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
// default
|
|
46
|
+
import { PieSwitch } from '@justeattakeaway/pie-switch';
|
|
47
|
+
|
|
48
|
+
// react
|
|
49
|
+
import { PieSwitch } from '@justeattakeaway/pie-switch/dist/react';
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## Peer Dependencies
|
|
54
|
+
|
|
55
|
+
> [!IMPORTANT]
|
|
56
|
+
> When using `pie-switch`, you will also need to include a couple of dependencies to ensure the component renders as expected. See [the PIE Wiki](https://github.com/justeattakeaway/pie/wiki/Getting-started-with-PIE-Web-Components#expected-dependencies) for more information and how to include these in your application.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Props
|
|
60
|
+
|
|
61
|
+
| Property | Type | Default | Description |
|
|
62
|
+
|---|---|---|---|
|
|
63
|
+
| isChecked | `Boolean` | false | Indicates whether the switch is on or off |
|
|
64
|
+
| isDisabled | `Boolean` | false | Indicates whether the switch is disabled or not |
|
|
65
|
+
| aria | `Object` | `undefined` | An object representing the aria labels `label` & `describedBy` that can be used on the switch;
|
|
66
|
+
|
|
67
|
+
In your markup or JSX, you can then use these to set the properties for the `pie-switch` component:
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<!-- Native HTML -->
|
|
71
|
+
<pie-switch></pie-switch>
|
|
72
|
+
|
|
73
|
+
<!-- JSX -->
|
|
74
|
+
<PieSwitch></PieSwitch>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Contributing
|
|
78
|
+
|
|
79
|
+
Check out our [contributing guide](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide) for more information on [local development](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide#local-development) and how to run specific [component tests](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide#testing).
|
package/declaration.d.ts
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { CSSResult } from 'lit';
|
|
2
|
+
import type { LitElement } from 'lit';
|
|
3
|
+
import type { TemplateResult } from 'lit';
|
|
4
|
+
|
|
5
|
+
export declare type AriaProps = {
|
|
6
|
+
label?: string;
|
|
7
|
+
describedBy?: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export declare type LabelPlacement = typeof labelPlacements[number];
|
|
11
|
+
|
|
12
|
+
export declare const labelPlacements: readonly ["leading", "trailing"];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Event name for when the switch checked state is changed.
|
|
16
|
+
*
|
|
17
|
+
* @constant
|
|
18
|
+
*/
|
|
19
|
+
export declare const ON_SWITCH_CHANGED_EVENT = "pie-switch-changed";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @tagname pie-switch
|
|
23
|
+
* @event {CustomEvent} pie-switch-changed - when the switch checked state is changed.
|
|
24
|
+
*/
|
|
25
|
+
export declare class PieSwitch extends PieSwitch_base implements SwitchProps {
|
|
26
|
+
label?: string;
|
|
27
|
+
labelPlacement: SwitchProps['labelPlacement'];
|
|
28
|
+
aria: AriaProps;
|
|
29
|
+
isChecked: boolean;
|
|
30
|
+
isDisabled: boolean;
|
|
31
|
+
static styles: CSSResult;
|
|
32
|
+
onChange(event: Event): void;
|
|
33
|
+
/**
|
|
34
|
+
* Renders the label for a switch if provided.
|
|
35
|
+
* if invalid value is passed, nothing gets rendered
|
|
36
|
+
*
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
private renderSwitchLabel;
|
|
40
|
+
render(): TemplateResult<1>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
declare const PieSwitch_base: (new (...args: any[]) => {
|
|
44
|
+
isRTL: boolean;
|
|
45
|
+
}) & typeof LitElement;
|
|
46
|
+
|
|
47
|
+
export declare interface SwitchProps {
|
|
48
|
+
/**
|
|
49
|
+
* The ARIA labels used for the switch.
|
|
50
|
+
*/
|
|
51
|
+
aria?: AriaProps;
|
|
52
|
+
/**
|
|
53
|
+
* Same as the HTML checked attribute - indicates whether the switch is on or off
|
|
54
|
+
*/
|
|
55
|
+
isChecked?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Same as the HTML checked attribute - indicates whether the switch disabled or not
|
|
58
|
+
*/
|
|
59
|
+
isDisabled?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* The label value of the component
|
|
62
|
+
*/
|
|
63
|
+
label?: string;
|
|
64
|
+
/**
|
|
65
|
+
* The placement of the label such as leading or trailing
|
|
66
|
+
*/
|
|
67
|
+
labelPlacement?: LabelPlacement;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { isServer as z, css as I, LitElement as f, html as d, unsafeCSS as P, nothing as l } from "lit";
|
|
2
|
+
import { property as n, query as E } from "lit/decorators.js";
|
|
3
|
+
const _ = (c) => {
|
|
4
|
+
class e extends c {
|
|
5
|
+
/**
|
|
6
|
+
* A getter to determine whether the text direction is right-to-left (RTL).
|
|
7
|
+
* If the `dir` property is present on the component, it will be used to determine the text direction.
|
|
8
|
+
* If running on the client-side (not SSR) and the `dir` property is not present, the text direction will be inferred
|
|
9
|
+
* from the document's root element. This inference is not available during SSR.
|
|
10
|
+
* In all other cases, it will return `false`, indicating a left-to-right (LTR) text direction.
|
|
11
|
+
*
|
|
12
|
+
* @returns {boolean} - Returns `true` if the text direction is RTL, otherwise `false`.
|
|
13
|
+
*/
|
|
14
|
+
get isRTL() {
|
|
15
|
+
return this.dir ? this.dir === "rtl" : !z && !this.dir ? document.documentElement.getAttribute("dir") === "rtl" : !1;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return e;
|
|
19
|
+
}, L = (c, e, t) => function(i, s) {
|
|
20
|
+
const o = `#${s}`;
|
|
21
|
+
Object.defineProperty(i, s, {
|
|
22
|
+
get() {
|
|
23
|
+
return this[o];
|
|
24
|
+
},
|
|
25
|
+
set(h) {
|
|
26
|
+
const C = this[o];
|
|
27
|
+
e.includes(h) ? this[o] = h : (console.error(
|
|
28
|
+
`<${c}> Invalid value "${h}" provided for property "${s}".`,
|
|
29
|
+
`Must be one of: ${e.join(" | ")}.`,
|
|
30
|
+
`Falling back to default value: "${t}"`
|
|
31
|
+
), this[o] = t), this.requestUpdate(s, C);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
function S(c, e) {
|
|
36
|
+
customElements.get(c) ? console.warn(`PIE Web Component: "${c}" has already been defined. Please ensure the component is only being defined once in your application.`) : customElements.define(c, e);
|
|
37
|
+
}
|
|
38
|
+
const T = `*,*:before,*:after{box-sizing:border-box;cursor:inherit}.c-switch-wrapper{display:inline-flex;align-items:center;gap:var(--dt-spacing-b);font-family:var(--dt-font-body-l-family);cursor:pointer}.c-switch-wrapper[isDisabled]{cursor:not-allowed}.c-switch{--switch-bg-color: var(--dt-color-interactive-form);--switch-bg-color--checked: var(--dt-color-interactive-brand);--switch-bg-color--disabled: var(--dt-color-disabled-01);--switch-width: 48px;--switch-height: 24px;--switch-control-size: 20px;--switch-padding: 2px;--switch-radius: var(--dt-radius-rounded-e);--switch-translation: calc(var(--switch-width) - var(--switch-control-size) - 2 * var(--switch-padding));position:relative;display:flex;width:var(--switch-width);height:var(--switch-height);flex-shrink:0;padding:var(--switch-padding);border-radius:var(--switch-radius);background-color:var(--switch-bg-color)}@media (prefers-reduced-motion: no-preference){.c-switch{transition:background-color .15s cubic-bezier(.4,0,.9,1) 0s}}.c-switch:hover{background-color:hsl(var(--dt-color-interactive-form-h),var(--dt-color-interactive-form-s),calc(var(--dt-color-interactive-form-l) - var(--dt-color-hover-01)))}.c-switch:focus,.c-switch:focus-within{background-color:var(--switch-bg-color);box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer)}.c-switch:active{background-color:hsl(var(--dt-color-interactive-form-h),var(--dt-color-interactive-form-s),calc(var(--dt-color-interactive-form-l) - var(--dt-color-active-01)))}.c-switch[isChecked]{background-color:var(--switch-bg-color--checked)}@media (prefers-reduced-motion: no-preference){.c-switch[isChecked]{transition:background-color .15s cubic-bezier(.4,0,.9,1) 0s}}.c-switch[isChecked]:hover{background-color:hsl(var(--dt-color-interactive-brand-h),var(--dt-color-interactive-brand-s),calc(var(--dt-color-interactive-brand-l) - var(--dt-color-hover-01)))}.c-switch[isChecked]:focus,.c-switch[isChecked]:focus-within{background-color:var(--switch-bg-color--checked)}.c-switch[isChecked]:active{background-color:hsl(var(--dt-color-interactive-brand-h),var(--dt-color-interactive-brand-s),calc(var(--dt-color-interactive-brand-l) - var(--dt-color-active-01)))}[isDisabled] .c-switch{background-color:var(--switch-bg-color--disabled);pointer-events:none}.c-switch-input{appearance:none;margin:0}.c-switch-input:disabled{background-color:transparent}.c-switch-control{position:absolute;left:2px;width:var(--switch-control-size);height:var(--switch-control-size);border-radius:var(--switch-radius);background-color:var(--dt-color-interactive-light);padding:var(--switch-padding)}@media (prefers-reduced-motion: no-preference){.c-switch-control{transition:transform .15s cubic-bezier(.4,0,.9,1) 0s}}.c-switch-input:checked+.c-switch-control{transform:translate(var(--switch-translation))}@media (prefers-reduced-motion: no-preference){.c-switch-input:checked+.c-switch-control{transition:transform .15s cubic-bezier(.4,0,.9,1) 0s}}.c-switch-input:checked+.c-switch-control .c-pieIcon--check{color:var(--switch-bg-color--checked)}@media (prefers-reduced-motion: no-preference){.c-switch-input:checked+.c-switch-control .c-pieIcon--check{transition:color .15s cubic-bezier(.4,0,.9,1) 0s}}.c-switch-input:disabled~.c-switch-control{color:var(--switch-bg-color--disabled)}.c-switch-input:disabled~.c-switch-control .c-pieIcon--check{color:var(--switch-bg-color--disabled)}@media (prefers-reduced-motion: no-preference){.c-switch-input:disabled~.c-switch-control .c-pieIcon--check{transition:color .15s cubic-bezier(.4,0,.9,1) 0s}}.c-switch-description{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}.c-switch-wrapper[isRTL] .c-switch-control{position:absolute;left:initial;right:2px}.c-switch-wrapper[isRTL] .c-switch-input:checked+.c-switch-control{transform:translate(calc(-1 * var(--switch-translation)))}@media (prefers-reduced-motion: no-preference){.c-switch-wrapper[isRTL] .c-switch-input:checked+.c-switch-control{transition:transform .15s cubic-bezier(.4,0,.9,1) 0s}}
|
|
39
|
+
`, O = ["leading", "trailing"], j = "pie-switch-changed";
|
|
40
|
+
function D(c, e) {
|
|
41
|
+
customElements.get(c) ? console.warn(`PIE Web Component: "${c}" has already been defined. Please ensure the component is only being defined once in your application.`) : customElements.define(c, e);
|
|
42
|
+
}
|
|
43
|
+
const b = {
|
|
44
|
+
xs: 16,
|
|
45
|
+
s: 20,
|
|
46
|
+
m: 24,
|
|
47
|
+
l: 28,
|
|
48
|
+
xl: 32,
|
|
49
|
+
xxl: 40
|
|
50
|
+
}, m = Object.keys(b), k = "xs", y = 8, w = 32;
|
|
51
|
+
function R(c, e, t) {
|
|
52
|
+
const r = parseInt(c, 10), i = r % t === 0;
|
|
53
|
+
return r >= e && i;
|
|
54
|
+
}
|
|
55
|
+
const x = {
|
|
56
|
+
large: (c) => R(c, w, y),
|
|
57
|
+
regular: (c) => m.includes(c)
|
|
58
|
+
};
|
|
59
|
+
function A(c) {
|
|
60
|
+
const e = x.large(c);
|
|
61
|
+
return { isValid: e, size: e ? c : w };
|
|
62
|
+
}
|
|
63
|
+
function B(c) {
|
|
64
|
+
const e = x.regular(c), t = e ? b[c] : b[k];
|
|
65
|
+
return { isValid: e, size: t };
|
|
66
|
+
}
|
|
67
|
+
const g = (c, e, t, r) => {
|
|
68
|
+
const i = c.endsWith("Large") || c.endsWith("-large");
|
|
69
|
+
let s, o;
|
|
70
|
+
if (t) {
|
|
71
|
+
if ({ isValid: s, size: o } = i ? A(t) : B(t), !s) {
|
|
72
|
+
const h = i ? `Invalid prop "size" value supplied to "${r}". The prop value should be a number equal or greater than ${w} and multiple of ${y}.` : `Invalid prop "size" value supplied to "${r}". The prop value should be one of the following values: ${m.join(", ")}.`;
|
|
73
|
+
console.error(h);
|
|
74
|
+
}
|
|
75
|
+
} else
|
|
76
|
+
o = i ? w : b[k];
|
|
77
|
+
return {
|
|
78
|
+
class: [c, e].filter(Boolean).join(" "),
|
|
79
|
+
width: o,
|
|
80
|
+
height: o
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
var V = Object.defineProperty, W = Object.getOwnPropertyDescriptor, v = (c, e, t, r) => {
|
|
84
|
+
for (var i = r > 1 ? void 0 : r ? W(e, t) : e, s = c.length - 1, o; s >= 0; s--)
|
|
85
|
+
(o = c[s]) && (i = (r ? o(e, t, i) : o(i)) || i);
|
|
86
|
+
return r && i && V(e, t, i), i;
|
|
87
|
+
};
|
|
88
|
+
const q = "icon-check";
|
|
89
|
+
class p extends f {
|
|
90
|
+
constructor() {
|
|
91
|
+
super(...arguments), this.size = "xs", this.class = "c-pieIcon c-pieIcon--check";
|
|
92
|
+
}
|
|
93
|
+
connectedCallback() {
|
|
94
|
+
var e, t, r;
|
|
95
|
+
if (super.connectedCallback(), ((e = this._svg) == null ? void 0 : e.getAttribute("width")) === null) {
|
|
96
|
+
const i = g("c-pieIcon c-pieIcon--check", "", null, "IconCheck");
|
|
97
|
+
(t = this._svg) == null || t.setAttribute("width", i.width), (r = this._svg) == null || r.setAttribute("height", i.height);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
updated(e) {
|
|
101
|
+
var t, r;
|
|
102
|
+
let i;
|
|
103
|
+
e.has("size") && (i = g("c-pieIcon c-pieIcon--check", "", this.size, "IconCheck"), (t = this._svg) == null || t.setAttribute("width", i.width), (r = this._svg) == null || r.setAttribute("height", i.height));
|
|
104
|
+
}
|
|
105
|
+
render() {
|
|
106
|
+
return d`<svg xmlns="http://www.w3.org/2000/svg" role="presentation" focusable="false" fill="currentColor" viewBox="0 0 16 16" class="c-pieIcon c-pieIcon--check"><path d="M5.865 12.489a1.217 1.217 0 0 1-.875-.385L1.875 8.656l.98-.875 3.028 3.369 7.253-7.822.963.875-7.35 7.875a1.216 1.216 0 0 1-.875.385l-.009.026Z"></path></svg>`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
p.styles = I`
|
|
110
|
+
:host-context(pie-icon-button) svg,
|
|
111
|
+
:host-context(pie-button) svg {
|
|
112
|
+
display: block;
|
|
113
|
+
width: var(--btn-icon-size);
|
|
114
|
+
height: var(--btn-icon-size);
|
|
115
|
+
}
|
|
116
|
+
`;
|
|
117
|
+
v([
|
|
118
|
+
n({ type: String, reflect: !0 })
|
|
119
|
+
], p.prototype, "size", 2);
|
|
120
|
+
v([
|
|
121
|
+
n({ type: String, reflect: !0 })
|
|
122
|
+
], p.prototype, "class", 2);
|
|
123
|
+
v([
|
|
124
|
+
E("svg")
|
|
125
|
+
], p.prototype, "_svg", 2);
|
|
126
|
+
D(q, p);
|
|
127
|
+
var M = Object.defineProperty, N = Object.getOwnPropertyDescriptor, u = (c, e, t, r) => {
|
|
128
|
+
for (var i = r > 1 ? void 0 : r ? N(e, t) : e, s = c.length - 1, o; s >= 0; s--)
|
|
129
|
+
(o = c[s]) && (i = (r ? o(e, t, i) : o(i)) || i);
|
|
130
|
+
return r && i && M(e, t, i), i;
|
|
131
|
+
};
|
|
132
|
+
const $ = "pie-switch";
|
|
133
|
+
class a extends _(f) {
|
|
134
|
+
constructor() {
|
|
135
|
+
super(...arguments), this.labelPlacement = "leading", this.isChecked = !1, this.isDisabled = !1;
|
|
136
|
+
}
|
|
137
|
+
onChange(e) {
|
|
138
|
+
const { checked: t } = e == null ? void 0 : e.currentTarget;
|
|
139
|
+
this.isChecked = t;
|
|
140
|
+
const r = new CustomEvent(
|
|
141
|
+
j,
|
|
142
|
+
{
|
|
143
|
+
bubbles: !0,
|
|
144
|
+
composed: !0,
|
|
145
|
+
detail: this.isChecked
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
this.dispatchEvent(r);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Renders the label for a switch if provided.
|
|
152
|
+
* if invalid value is passed, nothing gets rendered
|
|
153
|
+
*
|
|
154
|
+
* @private
|
|
155
|
+
*/
|
|
156
|
+
renderSwitchLabel() {
|
|
157
|
+
const { label: e, labelPlacement: t } = this;
|
|
158
|
+
return e ? d`
|
|
159
|
+
<label
|
|
160
|
+
for="switch"
|
|
161
|
+
data-test-id="switch-label-${t}">
|
|
162
|
+
${e}
|
|
163
|
+
</label>` : d``;
|
|
164
|
+
}
|
|
165
|
+
render() {
|
|
166
|
+
const {
|
|
167
|
+
labelPlacement: e,
|
|
168
|
+
aria: t,
|
|
169
|
+
isChecked: r,
|
|
170
|
+
isDisabled: i,
|
|
171
|
+
isRTL: s
|
|
172
|
+
} = this, o = "switch-description";
|
|
173
|
+
return d`
|
|
174
|
+
<div
|
|
175
|
+
class="c-switch-wrapper"
|
|
176
|
+
?isRTL=${s}
|
|
177
|
+
?isDisabled=${i}>
|
|
178
|
+
${e === "leading" ? this.renderSwitchLabel() : l}
|
|
179
|
+
<label
|
|
180
|
+
data-test-id="switch-component"
|
|
181
|
+
class="c-switch"
|
|
182
|
+
?isChecked=${r}>
|
|
183
|
+
<input
|
|
184
|
+
id="switch"
|
|
185
|
+
data-test-id="switch-input"
|
|
186
|
+
role="switch"
|
|
187
|
+
type="checkbox"
|
|
188
|
+
class="c-switch-input"
|
|
189
|
+
.checked="${r}"
|
|
190
|
+
.disabled="${i}"
|
|
191
|
+
@change="${this.onChange}"
|
|
192
|
+
aria-label="${(t == null ? void 0 : t.label) || l}"
|
|
193
|
+
aria-describedby="${t != null && t.describedBy ? o : l}">
|
|
194
|
+
<div class="c-switch-control">
|
|
195
|
+
${r ? d`<icon-check></icon-check>` : l}
|
|
196
|
+
</div>
|
|
197
|
+
</label>
|
|
198
|
+
${t != null && t.describedBy ? d`<div id="${o}" data-test-id="${o}" class="c-switch-description">${t == null ? void 0 : t.describedBy}</div>` : l}
|
|
199
|
+
${e === "trailing" ? this.renderSwitchLabel() : l}
|
|
200
|
+
</div>
|
|
201
|
+
`;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
a.styles = P(T);
|
|
205
|
+
u([
|
|
206
|
+
n({ type: String })
|
|
207
|
+
], a.prototype, "label", 2);
|
|
208
|
+
u([
|
|
209
|
+
n({ type: String }),
|
|
210
|
+
L($, O, "leading")
|
|
211
|
+
], a.prototype, "labelPlacement", 2);
|
|
212
|
+
u([
|
|
213
|
+
n({ type: Object })
|
|
214
|
+
], a.prototype, "aria", 2);
|
|
215
|
+
u([
|
|
216
|
+
n({ type: Boolean, reflect: !0 })
|
|
217
|
+
], a.prototype, "isChecked", 2);
|
|
218
|
+
u([
|
|
219
|
+
n({ type: Boolean, reflect: !0 })
|
|
220
|
+
], a.prototype, "isDisabled", 2);
|
|
221
|
+
S($, a);
|
|
222
|
+
export {
|
|
223
|
+
j as ON_SWITCH_CHANGED_EVENT,
|
|
224
|
+
a as PieSwitch,
|
|
225
|
+
O as labelPlacements
|
|
226
|
+
};
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { CSSResult } from 'lit';
|
|
2
|
+
import type { EventName } from '@lit-labs/react';
|
|
3
|
+
import type { LitElement } from 'lit';
|
|
4
|
+
import type { ReactWebComponent } from '@lit-labs/react';
|
|
5
|
+
import type { TemplateResult } from 'lit';
|
|
6
|
+
|
|
7
|
+
export declare type AriaProps = {
|
|
8
|
+
label?: string;
|
|
9
|
+
describedBy?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export declare type LabelPlacement = typeof labelPlacements[number];
|
|
13
|
+
|
|
14
|
+
export declare const labelPlacements: readonly ["leading", "trailing"];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Event name for when the switch checked state is changed.
|
|
18
|
+
*
|
|
19
|
+
* @constant
|
|
20
|
+
*/
|
|
21
|
+
export declare const ON_SWITCH_CHANGED_EVENT = "pie-switch-changed";
|
|
22
|
+
|
|
23
|
+
export declare const PieSwitch: ReactWebComponent<PieSwitch_2, {
|
|
24
|
+
onPieSwitchChanged: EventName<CustomEvent<any>>;
|
|
25
|
+
}>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @tagname pie-switch
|
|
29
|
+
* @event {CustomEvent} pie-switch-changed - when the switch checked state is changed.
|
|
30
|
+
*/
|
|
31
|
+
declare class PieSwitch_2 extends PieSwitch_base implements SwitchProps {
|
|
32
|
+
label?: string;
|
|
33
|
+
labelPlacement: SwitchProps['labelPlacement'];
|
|
34
|
+
aria: AriaProps;
|
|
35
|
+
isChecked: boolean;
|
|
36
|
+
isDisabled: boolean;
|
|
37
|
+
static styles: CSSResult;
|
|
38
|
+
onChange(event: Event): void;
|
|
39
|
+
/**
|
|
40
|
+
* Renders the label for a switch if provided.
|
|
41
|
+
* if invalid value is passed, nothing gets rendered
|
|
42
|
+
*
|
|
43
|
+
* @private
|
|
44
|
+
*/
|
|
45
|
+
private renderSwitchLabel;
|
|
46
|
+
render(): TemplateResult<1>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
declare const PieSwitch_base: (new (...args: any[]) => {
|
|
50
|
+
isRTL: boolean;
|
|
51
|
+
}) & typeof LitElement;
|
|
52
|
+
|
|
53
|
+
export declare interface SwitchProps {
|
|
54
|
+
/**
|
|
55
|
+
* The ARIA labels used for the switch.
|
|
56
|
+
*/
|
|
57
|
+
aria?: AriaProps;
|
|
58
|
+
/**
|
|
59
|
+
* Same as the HTML checked attribute - indicates whether the switch is on or off
|
|
60
|
+
*/
|
|
61
|
+
isChecked?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Same as the HTML checked attribute - indicates whether the switch disabled or not
|
|
64
|
+
*/
|
|
65
|
+
isDisabled?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* The label value of the component
|
|
68
|
+
*/
|
|
69
|
+
label?: string;
|
|
70
|
+
/**
|
|
71
|
+
* The placement of the label such as leading or trailing
|
|
72
|
+
*/
|
|
73
|
+
labelPlacement?: LabelPlacement;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { }
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as S from "react";
|
|
2
|
+
import { PieSwitch as g } from "./index.js";
|
|
3
|
+
import { ON_SWITCH_CHANGED_EVENT as L, labelPlacements as O } from "./index.js";
|
|
4
|
+
import "lit";
|
|
5
|
+
import "lit/decorators.js";
|
|
6
|
+
/**
|
|
7
|
+
* @license
|
|
8
|
+
* Copyright 2018 Google LLC
|
|
9
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
10
|
+
*/
|
|
11
|
+
const C = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), E = /* @__PURE__ */ new WeakMap(), P = (h, l, d, m, p) => {
|
|
12
|
+
const n = p == null ? void 0 : p[l];
|
|
13
|
+
n === void 0 || d === m ? d == null && l in HTMLElement.prototype ? h.removeAttribute(l) : h[l] = d : ((s, t, u) => {
|
|
14
|
+
let o = E.get(s);
|
|
15
|
+
o === void 0 && E.set(s, o = /* @__PURE__ */ new Map());
|
|
16
|
+
let a = o.get(t);
|
|
17
|
+
u !== void 0 ? a === void 0 ? (o.set(t, a = { handleEvent: u }), s.addEventListener(t, a)) : a.handleEvent = u : a !== void 0 && (o.delete(t), s.removeEventListener(t, a));
|
|
18
|
+
})(h, n, d);
|
|
19
|
+
};
|
|
20
|
+
function _(h = window.React, l, d, m, p) {
|
|
21
|
+
let n, s, t;
|
|
22
|
+
if (l === void 0) {
|
|
23
|
+
const r = h;
|
|
24
|
+
({ tagName: s, elementClass: t, events: m, displayName: p } = r), n = r.react;
|
|
25
|
+
} else
|
|
26
|
+
n = h, t = d, s = l;
|
|
27
|
+
const u = n.Component, o = n.createElement, a = new Set(Object.keys(m ?? {}));
|
|
28
|
+
class f extends u {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments), this.o = null;
|
|
31
|
+
}
|
|
32
|
+
t(e) {
|
|
33
|
+
if (this.o !== null)
|
|
34
|
+
for (const v in this.i)
|
|
35
|
+
P(this.o, v, this.props[v], e ? e[v] : void 0, m);
|
|
36
|
+
}
|
|
37
|
+
componentDidMount() {
|
|
38
|
+
this.t();
|
|
39
|
+
}
|
|
40
|
+
componentDidUpdate(e) {
|
|
41
|
+
this.t(e);
|
|
42
|
+
}
|
|
43
|
+
render() {
|
|
44
|
+
const { _$Gl: e, ...v } = this.props;
|
|
45
|
+
this.h !== e && (this.u = (i) => {
|
|
46
|
+
e !== null && ((c, y) => {
|
|
47
|
+
typeof c == "function" ? c(y) : c.current = y;
|
|
48
|
+
})(e, i), this.o = i, this.h = e;
|
|
49
|
+
}), this.i = {};
|
|
50
|
+
const w = { ref: this.u };
|
|
51
|
+
for (const [i, c] of Object.entries(v))
|
|
52
|
+
C.has(i) ? w[i === "className" ? "class" : i] = c : a.has(i) || i in t.prototype ? this.i[i] = c : w[i] = c;
|
|
53
|
+
return o(s, w);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
f.displayName = p ?? t.name;
|
|
57
|
+
const N = n.forwardRef((r, e) => o(f, { ...r, _$Gl: e }, r == null ? void 0 : r.children));
|
|
58
|
+
return N.displayName = f.displayName, N;
|
|
59
|
+
}
|
|
60
|
+
const D = _({
|
|
61
|
+
displayName: "PieSwitch",
|
|
62
|
+
elementClass: g,
|
|
63
|
+
react: S,
|
|
64
|
+
tagName: "pie-switch",
|
|
65
|
+
events: {
|
|
66
|
+
onPieSwitchChanged: "pie-switch-changed"
|
|
67
|
+
// when the switch checked state is changed.
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
export {
|
|
71
|
+
L as ON_SWITCH_CHANGED_EVENT,
|
|
72
|
+
D as PieSwitch,
|
|
73
|
+
O as labelPlacements
|
|
74
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@justeattakeaway/pie-switch",
|
|
3
|
+
"description": "PIE Design System Switch built using Web Components",
|
|
4
|
+
"version": "0.16.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"src",
|
|
11
|
+
"dist",
|
|
12
|
+
"**/*.d.ts"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "yarn build:wrapper pie-switch && run -T vite build",
|
|
16
|
+
"lint:scripts": "run -T eslint .",
|
|
17
|
+
"lint:scripts:fix": "yarn lint:scripts --fix",
|
|
18
|
+
"lint:style": "run -T stylelint ./src/**/*.{css,scss}",
|
|
19
|
+
"lint:style:fix": "yarn lint:style --fix",
|
|
20
|
+
"watch": "run -T vite build --watch",
|
|
21
|
+
"test": "echo \"Error: no test specified\" && exit 0",
|
|
22
|
+
"test:ci": "yarn test",
|
|
23
|
+
"test:browsers": "npx playwright test -c ./playwright-lit.config.ts",
|
|
24
|
+
"test:browsers:ci": "yarn test:browsers",
|
|
25
|
+
"test:visual": "run -T cross-env-shell PERCY_TOKEN=${PERCY_TOKEN_PIE_SWITCH} percy exec --allowed-hostname cloudfront.net -- npx playwright test -c ./playwright-lit-visual.config.ts",
|
|
26
|
+
"test:visual:ci": "yarn test:visual"
|
|
27
|
+
},
|
|
28
|
+
"author": "Just Eat Takeaway.com - Design System Team",
|
|
29
|
+
"license": "Apache-2.0",
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@justeattakeaway/pie-components-config": "0.4.0",
|
|
32
|
+
"@justeattakeaway/pie-icons-webc": "0.11.1"
|
|
33
|
+
},
|
|
34
|
+
"volta": {
|
|
35
|
+
"extends": "../../../package.json"
|
|
36
|
+
},
|
|
37
|
+
"sideEffects": [
|
|
38
|
+
"dist/*.js"
|
|
39
|
+
]
|
|
40
|
+
}
|
package/src/defs.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const labelPlacements = ['leading', 'trailing'] as const;
|
|
2
|
+
|
|
3
|
+
export type LabelPlacement = typeof labelPlacements[number];
|
|
4
|
+
|
|
5
|
+
export type AriaProps = {
|
|
6
|
+
label?: string,
|
|
7
|
+
describedBy?: string
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export interface SwitchProps {
|
|
11
|
+
/**
|
|
12
|
+
* The ARIA labels used for the switch.
|
|
13
|
+
*/
|
|
14
|
+
aria?: AriaProps;
|
|
15
|
+
/**
|
|
16
|
+
* Same as the HTML checked attribute - indicates whether the switch is on or off
|
|
17
|
+
*/
|
|
18
|
+
isChecked?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Same as the HTML checked attribute - indicates whether the switch disabled or not
|
|
21
|
+
*/
|
|
22
|
+
isDisabled?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The label value of the component
|
|
25
|
+
*/
|
|
26
|
+
label?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The placement of the label such as leading or trailing
|
|
29
|
+
*/
|
|
30
|
+
labelPlacement?: LabelPlacement;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Event name for when the switch checked state is changed.
|
|
35
|
+
*
|
|
36
|
+
* @constant
|
|
37
|
+
*/
|
|
38
|
+
export const ON_SWITCH_CHANGED_EVENT = 'pie-switch-changed';
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LitElement, html, unsafeCSS, nothing, TemplateResult,
|
|
3
|
+
} from 'lit';
|
|
4
|
+
import { property } from 'lit/decorators.js';
|
|
5
|
+
import { RtlMixin, validPropertyValues, defineCustomElement } from '@justeattakeaway/pie-webc-core';
|
|
6
|
+
import styles from './switch.scss?inline';
|
|
7
|
+
import {
|
|
8
|
+
SwitchProps, ON_SWITCH_CHANGED_EVENT, AriaProps, labelPlacements,
|
|
9
|
+
} from './defs';
|
|
10
|
+
import '@justeattakeaway/pie-icons-webc/IconCheck';
|
|
11
|
+
|
|
12
|
+
// Valid values available to consumers
|
|
13
|
+
export * from './defs';
|
|
14
|
+
|
|
15
|
+
const componentSelector = 'pie-switch';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @tagname pie-switch
|
|
19
|
+
* @event {CustomEvent} pie-switch-changed - when the switch checked state is changed.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export class PieSwitch extends RtlMixin(LitElement) implements SwitchProps {
|
|
23
|
+
@property({ type: String })
|
|
24
|
+
public label?: string;
|
|
25
|
+
|
|
26
|
+
@property({ type: String })
|
|
27
|
+
@validPropertyValues(componentSelector, labelPlacements, 'leading')
|
|
28
|
+
public labelPlacement: SwitchProps['labelPlacement'] = 'leading';
|
|
29
|
+
|
|
30
|
+
@property({ type: Object })
|
|
31
|
+
public aria!: AriaProps;
|
|
32
|
+
|
|
33
|
+
@property({ type: Boolean, reflect: true })
|
|
34
|
+
public isChecked = false;
|
|
35
|
+
|
|
36
|
+
@property({ type: Boolean, reflect: true })
|
|
37
|
+
public isDisabled = false;
|
|
38
|
+
|
|
39
|
+
static styles = unsafeCSS(styles);
|
|
40
|
+
|
|
41
|
+
onChange (event: Event) {
|
|
42
|
+
const { checked } = event?.currentTarget as HTMLInputElement;
|
|
43
|
+
this.isChecked = checked;
|
|
44
|
+
const changedEvent = new CustomEvent(
|
|
45
|
+
ON_SWITCH_CHANGED_EVENT,
|
|
46
|
+
{
|
|
47
|
+
bubbles: true,
|
|
48
|
+
composed: true,
|
|
49
|
+
detail: this.isChecked,
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
this.dispatchEvent(changedEvent);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Renders the label for a switch if provided.
|
|
57
|
+
* if invalid value is passed, nothing gets rendered
|
|
58
|
+
*
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
private renderSwitchLabel (): TemplateResult {
|
|
62
|
+
const { label, labelPlacement } = this;
|
|
63
|
+
|
|
64
|
+
if (label) {
|
|
65
|
+
return html`
|
|
66
|
+
<label
|
|
67
|
+
for="switch"
|
|
68
|
+
data-test-id="switch-label-${labelPlacement}">
|
|
69
|
+
${label}
|
|
70
|
+
</label>`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return html``;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
render () {
|
|
77
|
+
const {
|
|
78
|
+
labelPlacement,
|
|
79
|
+
aria,
|
|
80
|
+
isChecked,
|
|
81
|
+
isDisabled,
|
|
82
|
+
isRTL,
|
|
83
|
+
} = this;
|
|
84
|
+
|
|
85
|
+
const switchId = 'switch-description';
|
|
86
|
+
|
|
87
|
+
return html`
|
|
88
|
+
<div
|
|
89
|
+
class="c-switch-wrapper"
|
|
90
|
+
?isRTL=${isRTL}
|
|
91
|
+
?isDisabled=${isDisabled}>
|
|
92
|
+
${labelPlacement === 'leading' ? this.renderSwitchLabel() : nothing}
|
|
93
|
+
<label
|
|
94
|
+
data-test-id="switch-component"
|
|
95
|
+
class="c-switch"
|
|
96
|
+
?isChecked=${isChecked}>
|
|
97
|
+
<input
|
|
98
|
+
id="switch"
|
|
99
|
+
data-test-id="switch-input"
|
|
100
|
+
role="switch"
|
|
101
|
+
type="checkbox"
|
|
102
|
+
class="c-switch-input"
|
|
103
|
+
.checked="${isChecked}"
|
|
104
|
+
.disabled="${isDisabled}"
|
|
105
|
+
@change="${this.onChange}"
|
|
106
|
+
aria-label="${aria?.label || nothing}"
|
|
107
|
+
aria-describedby="${aria?.describedBy ? switchId : nothing}">
|
|
108
|
+
<div class="c-switch-control">
|
|
109
|
+
${isChecked ? html`<icon-check></icon-check>` : nothing}
|
|
110
|
+
</div>
|
|
111
|
+
</label>
|
|
112
|
+
${aria?.describedBy ? html`<div id="${switchId}" data-test-id="${switchId}" class="c-switch-description">${aria?.describedBy}</div>` : nothing}
|
|
113
|
+
${labelPlacement === 'trailing' ? this.renderSwitchLabel() : nothing}
|
|
114
|
+
</div>
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
defineCustomElement(componentSelector, PieSwitch);
|
|
120
|
+
|
|
121
|
+
declare global {
|
|
122
|
+
interface HTMLElementTagNameMap {
|
|
123
|
+
[componentSelector]: PieSwitch;
|
|
124
|
+
}
|
|
125
|
+
}
|
package/src/switch.scss
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
@use '@justeat/pie-design-tokens/dist/jet.scss' as dt;
|
|
2
|
+
|
|
3
|
+
@mixin switch-transition($property) {
|
|
4
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
5
|
+
transition: $property 0.15s cubic-bezier(0.4, 0, 0.9, 1) 0s;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
*,
|
|
10
|
+
*:before,
|
|
11
|
+
*:after {
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
cursor: inherit;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.c-switch-wrapper {
|
|
17
|
+
display: inline-flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: var(--dt-spacing-b);
|
|
20
|
+
font-family: var(--dt-font-body-l-family);
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
|
|
23
|
+
&[isDisabled] {
|
|
24
|
+
cursor: not-allowed;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.c-switch {
|
|
29
|
+
--switch-bg-color: var(--dt-color-interactive-form);
|
|
30
|
+
--switch-bg-color--checked: var(--dt-color-interactive-brand);
|
|
31
|
+
--switch-bg-color--disabled: var(--dt-color-disabled-01);
|
|
32
|
+
--switch-width: 48px;
|
|
33
|
+
--switch-height: 24px;
|
|
34
|
+
--switch-control-size: 20px;
|
|
35
|
+
--switch-padding: 2px;
|
|
36
|
+
--switch-radius: var(--dt-radius-rounded-e);
|
|
37
|
+
--switch-translation: calc(var(--switch-width) - var(--switch-control-size) - 2 * var(--switch-padding));
|
|
38
|
+
|
|
39
|
+
position: relative;
|
|
40
|
+
display: flex;
|
|
41
|
+
width: var(--switch-width);
|
|
42
|
+
height: var(--switch-height);
|
|
43
|
+
flex-shrink: 0;
|
|
44
|
+
padding: var(--switch-padding);
|
|
45
|
+
border-radius: var(--switch-radius);
|
|
46
|
+
background-color: var(--switch-bg-color);
|
|
47
|
+
|
|
48
|
+
@include switch-transition(background-color);
|
|
49
|
+
|
|
50
|
+
&:hover {
|
|
51
|
+
background-color: hsl(var(--dt-color-interactive-form-h), var(--dt-color-interactive-form-s), calc(var(--dt-color-interactive-form-l) - var(--dt-color-hover-01)));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&:focus,
|
|
55
|
+
&:focus-within {
|
|
56
|
+
background-color: var(--switch-bg-color);
|
|
57
|
+
box-shadow: 0 0 0 2px var(--dt-color-focus-inner), 0 0 0 4px var(--dt-color-focus-outer);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
&:active {
|
|
61
|
+
background-color: hsl(var(--dt-color-interactive-form-h), var(--dt-color-interactive-form-s), calc(var(--dt-color-interactive-form-l) - var(--dt-color-active-01)));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&[isChecked] {
|
|
65
|
+
@include switch-transition(background-color);
|
|
66
|
+
background-color: var(--switch-bg-color--checked);
|
|
67
|
+
|
|
68
|
+
&:hover {
|
|
69
|
+
background-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) - var(--dt-color-hover-01)));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
&:focus,
|
|
73
|
+
&:focus-within {
|
|
74
|
+
background-color: var(--switch-bg-color--checked);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
&:active {
|
|
78
|
+
background-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) - var(--dt-color-active-01)));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
[isDisabled] & {
|
|
83
|
+
background-color: var(--switch-bg-color--disabled);
|
|
84
|
+
pointer-events: none;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.c-switch-input {
|
|
89
|
+
appearance: none;
|
|
90
|
+
margin: 0;
|
|
91
|
+
|
|
92
|
+
&:disabled {
|
|
93
|
+
background-color: transparent;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.c-switch-control {
|
|
98
|
+
position: absolute;
|
|
99
|
+
left: 2px;
|
|
100
|
+
@include switch-transition(transform);
|
|
101
|
+
width: var(--switch-control-size);
|
|
102
|
+
height: var(--switch-control-size);
|
|
103
|
+
border-radius: var(--switch-radius);
|
|
104
|
+
background-color: var(--dt-color-interactive-light);
|
|
105
|
+
padding: var(--switch-padding);
|
|
106
|
+
|
|
107
|
+
.c-switch-input:checked + & {
|
|
108
|
+
@include switch-transition(transform);
|
|
109
|
+
transform: translateX(var(--switch-translation));
|
|
110
|
+
|
|
111
|
+
.c-pieIcon--check {
|
|
112
|
+
@include switch-transition(color);
|
|
113
|
+
color: var(--switch-bg-color--checked);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.c-switch-input:disabled ~ & {
|
|
118
|
+
color: var(--switch-bg-color--disabled);
|
|
119
|
+
|
|
120
|
+
.c-pieIcon--check {
|
|
121
|
+
@include switch-transition(color);
|
|
122
|
+
color: var(--switch-bg-color--disabled);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// The description is only required for screen readers so we need to visually hide the description
|
|
128
|
+
.c-switch-description {
|
|
129
|
+
position: absolute;
|
|
130
|
+
left: -9999px;
|
|
131
|
+
top: auto;
|
|
132
|
+
width: 1px;
|
|
133
|
+
height: 1px;
|
|
134
|
+
overflow: hidden;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.c-switch-wrapper[isRTL] {
|
|
138
|
+
.c-switch-control {
|
|
139
|
+
position: absolute;
|
|
140
|
+
left: initial;
|
|
141
|
+
right: 2px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.c-switch-input:checked + .c-switch-control {
|
|
145
|
+
@include switch-transition(transform);
|
|
146
|
+
transform: translateX(calc(-1 * var(--switch-translation)));
|
|
147
|
+
}
|
|
148
|
+
}
|