@nysds/nys-toggle 1.13.1 → 1.15.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/dist/index.d.ts +1 -0
- package/dist/nys-toggle.d.ts +87 -0
- package/dist/nys-toggle.figma.d.ts +1 -0
- package/dist/nys-toggle.js +51 -34
- package/dist/nys-toggle.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./nys-toggle";
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
/**
|
|
3
|
+
* A toggle switch for binary settings with immediate effect. Form-associated via ElementInternals.
|
|
4
|
+
*
|
|
5
|
+
* Use when changing a setting takes effect immediately (e.g., dark mode, notifications).
|
|
6
|
+
* For binary choices in forms that submit later, use `nys-checkbox` instead.
|
|
7
|
+
*
|
|
8
|
+
* @summary Toggle switch for binary settings with immediate effect.
|
|
9
|
+
* @element nys-toggle
|
|
10
|
+
*
|
|
11
|
+
* @slot description - Custom HTML description content.
|
|
12
|
+
*
|
|
13
|
+
* @fires nys-change - Fired when toggle state changes. Detail: `{id, checked}`.
|
|
14
|
+
* @fires nys-focus - Fired when toggle gains focus.
|
|
15
|
+
* @fires nys-blur - Fired when toggle loses focus.
|
|
16
|
+
*
|
|
17
|
+
* @example Basic toggle
|
|
18
|
+
* ```html
|
|
19
|
+
* <nys-toggle label="Enable notifications" name="notifications"></nys-toggle>
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example Dark mode toggle
|
|
23
|
+
* ```html
|
|
24
|
+
* <nys-toggle label="Dark mode" description="Adjust display for low light" checked></nys-toggle>
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class NysToggle extends LitElement {
|
|
28
|
+
static styles: import("lit").CSSResult;
|
|
29
|
+
static shadowRootOptions: {
|
|
30
|
+
delegatesFocus: boolean;
|
|
31
|
+
clonable?: boolean;
|
|
32
|
+
customElementRegistry?: CustomElementRegistry;
|
|
33
|
+
mode: ShadowRootMode;
|
|
34
|
+
serializable?: boolean;
|
|
35
|
+
slotAssignment?: SlotAssignmentMode;
|
|
36
|
+
};
|
|
37
|
+
/** Unique identifier. Auto-generated if not provided. */
|
|
38
|
+
id: string;
|
|
39
|
+
/** Name for form submission. */
|
|
40
|
+
name: string;
|
|
41
|
+
/** Value submitted when toggle is on. */
|
|
42
|
+
value: string;
|
|
43
|
+
/** Visible label text. */
|
|
44
|
+
label: string;
|
|
45
|
+
/** Helper text below label. Use slot for custom HTML. */
|
|
46
|
+
description: string;
|
|
47
|
+
/** Form `id` to associate with. */
|
|
48
|
+
form: string | null;
|
|
49
|
+
/** Whether toggle is on. */
|
|
50
|
+
checked: boolean;
|
|
51
|
+
/** Prevents interaction. */
|
|
52
|
+
disabled: boolean;
|
|
53
|
+
/** Hides check/close icon inside toggle knob. */
|
|
54
|
+
noIcon: boolean;
|
|
55
|
+
/** Adjusts colors for dark backgrounds. */
|
|
56
|
+
inverted: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Toggle size: `sm` or `md` (default).
|
|
59
|
+
* @default "md"
|
|
60
|
+
*/
|
|
61
|
+
size: "sm" | "md";
|
|
62
|
+
private _internals;
|
|
63
|
+
/**
|
|
64
|
+
* Lifecycle methods
|
|
65
|
+
* --------------------------------------------------------------------------
|
|
66
|
+
*/
|
|
67
|
+
static formAssociated: boolean;
|
|
68
|
+
constructor();
|
|
69
|
+
connectedCallback(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Form Integration
|
|
72
|
+
* --------------------------------------------------------------------------
|
|
73
|
+
*/
|
|
74
|
+
updated(changedProperties: Map<string, any>): void;
|
|
75
|
+
formResetCallback(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Event Handlers
|
|
78
|
+
* --------------------------------------------------------------------------
|
|
79
|
+
*/
|
|
80
|
+
private _emitChangeEvent;
|
|
81
|
+
private _handleFocus;
|
|
82
|
+
private _handleBlur;
|
|
83
|
+
private _handleClick;
|
|
84
|
+
private _handleSliderClick;
|
|
85
|
+
private _handleKeyDown;
|
|
86
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
87
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/nys-toggle.js
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
import { LitElement as h, unsafeCSS as y, html as
|
|
1
|
+
import { LitElement as h, unsafeCSS as y, html as i } from "lit";
|
|
2
2
|
import { property as t } from "lit/decorators.js";
|
|
3
|
-
import { ifDefined as
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import { ifDefined as g } from "lit/directives/if-defined.js";
|
|
4
|
+
/*!
|
|
5
|
+
* █▄ █ █ █ █▀▀▀█ █▀▀▄ █▀▀▀█
|
|
6
|
+
* █ █ █ █▄▄▄█ ▀▀▀▄▄ █ █ ▀▀▀▄▄
|
|
7
|
+
* █ ▀█ █ █▄▄▄█ █▄▄▀ █▄▄▄█
|
|
8
|
+
*
|
|
9
|
+
* Toggle Component
|
|
10
|
+
* Part of the New York State Design System
|
|
11
|
+
* Repository: https://github.com/its-hcd/nysds
|
|
12
|
+
* License: MIT
|
|
13
|
+
*/
|
|
14
|
+
const u = ':host{--_nys-toggle-width: var(--nys-font-size-8xl, 44px);--_nys-toggle-height: var(--nys-size-300, 24px);--_nys-toggle-border-radius: var(--nys-radius-round, 1776px);--_nys-toggle-border-width: var(--nys-border-width-md, 2px);--_nys-toggle-size--knob: var(--nys-font-size-lg, 18px);--_nys-toggle-margin--knob: calc( (var(--_nys-toggle-height) - var(--_nys-toggle-size--knob)) / 2 );--_nys-toggle-transform--translateX: calc( var(--_nys-toggle-width) - var(--_nys-toggle-size--knob) - var( --_nys-toggle-margin--knob ) - 2px );--_nys-toggle-gap: var(--nys-space-150, 12px);--_nys-toggle-transition-duration: .3s;--_nys-toggle-outline-color: var(--nys-color-focus, #004dd1);--_nys-toggle-outline-width: var(--nys-border-width-md, 2px);--_nys-toggle-background-color: var(--nys-color-neutral-500, #797c7f);--_nys-toggle-background-color--disabled: var( --nys-color-neutral-100, #d0d0ce );--_nys-toggle-background-color--checked: var(--nys-color-theme, #154973);--_nys-toggle-background-color--hover: var(--nys-color-neutral-600, #62666a);--_nys-toggle-background-color--active: var(--nys-color-neutral-700, #4a4d4f);--_nys-toggle-background-color--checked--hover: var( --nys-color-theme-strong, #0e324f );--_nys-toggle-background-color--checked--active: var( --nys-color-theme-stronger, #081b2b );--_nys-toggle-color-ink-reverse: var(--nys-color-ink-reverse, #ffffff);--_nys-toggle-color--disabled: var(--nys-color-neutral-500, #797c7f)}.nys-toggle__content{display:flex;gap:var(--_nys-toggle-gap)}.nys-toggle__content nys-label{--_nys-label-font-weight: var(--nys-font-weight-regular, 400)}.nys-toggle__content:has(input:disabled) nys-label{--_nys-label-color: var(--_nys-toggle-color--disabled);cursor:not-allowed}.nys-toggle__toggle{position:relative;display:inline-block;width:var(--_nys-toggle-width);min-width:var(--_nys-toggle-width);max-width:var(--_nys-toggle-width);height:var(--_nys-toggle-height);min-height:var(--_nys-toggle-height);max-height:var(--_nys-toggle-height)}.nys-toggle__toggle input{opacity:0;width:0;height:0}.nys-toggle__toggle input:checked+.slider{background-color:var(--_nys-toggle-background-color--checked)}.nys-toggle__toggle input:checked+.slider:hover{background-color:var(--_nys-toggle-background-color--checked--hover)}.nys-toggle__toggle input:checked+.slider:hover .knob .toggle-icon{color:var(--_nys-toggle-background-color--checked--hover)}.nys-toggle__toggle input:checked+.slider .knob{transform:translate(var(--_nys-toggle-transform--translateX))}.nys-toggle__toggle input:checked+.slider .knob .toggle-icon{color:var(--_nys-toggle-background-color--checked)}.nys-toggle__toggle input:active:not(:disabled)+.slider{background-color:var(--_nys-toggle-background-color--active);outline:solid var(--_nys-toggle-outline-width) var(--_nys-toggle-outline-color)}.nys-toggle__toggle input:active:not(:disabled)+.slider .knob .toggle-icon{color:var(--_nys-toggle-background-color--active)}.nys-toggle__toggle input:active:not(:disabled)+.slider:checked{background-color:var(--_nys-toggle-background-color--checked--active)}.nys-toggle__toggle input:active:not(:disabled)+.slider:checked .knob .toggle-icon{color:var(--_nys-toggle-background-color--checked--active)}.nys-toggle__toggle input:focus+.slider{outline:solid var(--_nys-toggle-outline-width) var(--_nys-toggle-outline-color)}.nys-toggle__toggle input:disabled+.slider{background-color:var(--_nys-toggle-background-color--disabled);cursor:not-allowed}.nys-toggle__toggle input:disabled+.slider:hover{background-color:var(--_nys-toggle-background-color--disabled)}.nys-toggle__toggle input:disabled+.slider .knob .toggle-icon{color:var(--_nys-toggle-background-color--disabled)}.slider{position:absolute;cursor:pointer;border-radius:var(--_nys-toggle-border-radius);outline-offset:var(--_nys-toggle-border-width);width:var(--_nys-toggle-width);inset:0;background-color:var(--_nys-toggle-background-color);display:flex;align-items:center}.slider:hover{background-color:var(--_nys-toggle-background-color--hover)}.slider:hover .knob .toggle-icon{color:var(--_nys-toggle-background-color--hover)}.knob{content:"";height:var(--_nys-toggle-size--knob);width:var(--_nys-toggle-size--knob);margin:var(--_nys-toggle-margin--knob);border-radius:var(--nys-radius-round, 1776px);background-color:var(--_nys-toggle-color-ink-reverse);transition:all var(--_nys-toggle-transition-duration) cubic-bezier(.27,.2,.25,1.51);overflow:hidden;display:flex;align-items:center;justify-content:center}.toggle-icon{position:absolute;color:var(--_nys-toggle-background-color)}:host([size=sm]){--_nys-toggle-width: var(--nys-size-450, 36px);--_nys-toggle-height: var(--nys-size-250, 20px);--_nys-toggle-size--knob: var(--nys-size-200, 16px);--_nys-toggle-gap: var(--nys-space-100, 8px)}:host([size=sm]) .toggle-icon{font-size:var(--nys-font-size-body-xs, 12px)}@supports not (font-size: 1cap){:host([size=sm]) .toggle-icon{font-size:var(--nys-font-size-body-xs, 12px)}}:host([size=md]){--_nys-toggle-width: var(--nys-size-550, 44px);--_nys-toggle-height: var(--nys-size-300, 24px);--_nys-toggle-size--knob: var(--nys-size-250, 20px)}:host([size=md]) .toggle-icon{font-size:var(--nys-font-size-body-sm, 14px)}@supports not (font-size: 1cap){:host([size=md]) .toggle-icon{font-size:calc(var(--nys-font-size-body-sm, 14px) - 1px)}}@media(prefers-reduced-motion:reduce){:host{--toggle-transition-duration: 0s}}';
|
|
15
|
+
var v = Object.defineProperty, s = (a, o, c, p) => {
|
|
16
|
+
for (var n = void 0, r = a.length - 1, d; r >= 0; r--)
|
|
17
|
+
(d = a[r]) && (n = d(o, c, n) || n);
|
|
18
|
+
return n && v(o, c, n), n;
|
|
9
19
|
};
|
|
10
20
|
let _ = 0;
|
|
11
|
-
const
|
|
21
|
+
const l = class l extends h {
|
|
12
22
|
// allows use of elementInternals' API
|
|
13
23
|
constructor() {
|
|
14
24
|
super(), this.id = "", this.name = "", this.value = "", this.label = "", this.description = "", this.form = null, this.checked = !1, this.disabled = !1, this.noIcon = !1, this.inverted = !1, this.size = "md", this._internals = this.attachInternals();
|
|
@@ -49,37 +59,40 @@ const r = class r extends h {
|
|
|
49
59
|
_handleBlur() {
|
|
50
60
|
this.dispatchEvent(new Event("nys-blur"));
|
|
51
61
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
_handleClick() {
|
|
63
|
+
this.disabled || (this.checked = !this.checked, this._emitChangeEvent());
|
|
64
|
+
}
|
|
65
|
+
_handleSliderClick(o) {
|
|
66
|
+
o.stopPropagation(), this._handleClick();
|
|
55
67
|
}
|
|
56
68
|
_handleKeyDown(o) {
|
|
57
69
|
!this.disabled && (o.key === " " || o.key === "Enter") && (o.preventDefault(), this.checked = !this.checked, this._emitChangeEvent());
|
|
58
70
|
}
|
|
59
71
|
render() {
|
|
60
|
-
return
|
|
61
|
-
<
|
|
72
|
+
return i`
|
|
73
|
+
<div class="nys-toggle">
|
|
62
74
|
<div class="nys-toggle__content">
|
|
63
75
|
<div class="nys-toggle__toggle">
|
|
64
76
|
<input
|
|
77
|
+
id=${this.id}
|
|
65
78
|
type="checkbox"
|
|
66
|
-
name="${
|
|
79
|
+
name="${g(this.name ? this.name : void 0)}"
|
|
67
80
|
.value=${this.value}
|
|
68
|
-
form=${
|
|
81
|
+
form=${g(this.form || void 0)}
|
|
69
82
|
.checked=${this.checked}
|
|
70
83
|
?disabled=${this.disabled}
|
|
71
84
|
role="switch"
|
|
72
85
|
aria-checked="${this.checked ? "true" : "false"}"
|
|
73
86
|
aria-disabled="${this.disabled ? "true" : "false"}"
|
|
74
87
|
aria-label="${this.label || "Toggle switch"}"
|
|
75
|
-
@
|
|
88
|
+
@click=${this._handleClick}
|
|
76
89
|
@focus=${this._handleFocus}
|
|
77
90
|
@blur=${this._handleBlur}
|
|
78
91
|
@keydown=${this._handleKeyDown}
|
|
79
92
|
/>
|
|
80
|
-
<span class="slider">
|
|
93
|
+
<span class="slider" @click=${this._handleSliderClick}>
|
|
81
94
|
<div class="knob">
|
|
82
|
-
${this.noIcon ? "" :
|
|
95
|
+
${this.noIcon ? "" : i`<nys-icon
|
|
83
96
|
class="toggle-icon"
|
|
84
97
|
name="${this.checked ? "check" : "close"}"
|
|
85
98
|
size="2xl"
|
|
@@ -87,9 +100,10 @@ const r = class r extends h {
|
|
|
87
100
|
</div>
|
|
88
101
|
</span>
|
|
89
102
|
</div>
|
|
90
|
-
${this.label &&
|
|
103
|
+
${this.label && i`<nys-label
|
|
104
|
+
for=${this.id}
|
|
91
105
|
label=${this.label}
|
|
92
|
-
description=${
|
|
106
|
+
description=${g(this.description || void 0)}
|
|
93
107
|
?inverted=${this.inverted}
|
|
94
108
|
>
|
|
95
109
|
<slot name="description" slot="description"
|
|
@@ -97,43 +111,46 @@ const r = class r extends h {
|
|
|
97
111
|
>
|
|
98
112
|
</nys-label> `}
|
|
99
113
|
</div>
|
|
100
|
-
</
|
|
114
|
+
</div>
|
|
101
115
|
`;
|
|
102
116
|
}
|
|
103
117
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
118
|
+
l.styles = y(u), l.shadowRootOptions = {
|
|
119
|
+
...h.shadowRootOptions,
|
|
120
|
+
delegatesFocus: !0
|
|
121
|
+
}, l.formAssociated = !0;
|
|
122
|
+
let e = l;
|
|
123
|
+
s([
|
|
107
124
|
t({ type: String, reflect: !0 })
|
|
108
125
|
], e.prototype, "id");
|
|
109
|
-
|
|
126
|
+
s([
|
|
110
127
|
t({ type: String, reflect: !0 })
|
|
111
128
|
], e.prototype, "name");
|
|
112
|
-
|
|
129
|
+
s([
|
|
113
130
|
t({ type: String })
|
|
114
131
|
], e.prototype, "value");
|
|
115
|
-
|
|
132
|
+
s([
|
|
116
133
|
t({ type: String })
|
|
117
134
|
], e.prototype, "label");
|
|
118
|
-
|
|
135
|
+
s([
|
|
119
136
|
t({ type: String })
|
|
120
137
|
], e.prototype, "description");
|
|
121
|
-
|
|
138
|
+
s([
|
|
122
139
|
t({ type: String, reflect: !0 })
|
|
123
140
|
], e.prototype, "form");
|
|
124
|
-
|
|
141
|
+
s([
|
|
125
142
|
t({ type: Boolean, reflect: !0 })
|
|
126
143
|
], e.prototype, "checked");
|
|
127
|
-
|
|
144
|
+
s([
|
|
128
145
|
t({ type: Boolean, reflect: !0 })
|
|
129
146
|
], e.prototype, "disabled");
|
|
130
|
-
|
|
147
|
+
s([
|
|
131
148
|
t({ type: Boolean })
|
|
132
149
|
], e.prototype, "noIcon");
|
|
133
|
-
|
|
150
|
+
s([
|
|
134
151
|
t({ type: Boolean, reflect: !0 })
|
|
135
152
|
], e.prototype, "inverted");
|
|
136
|
-
|
|
153
|
+
s([
|
|
137
154
|
t({ type: String, reflect: !0 })
|
|
138
155
|
], e.prototype, "size");
|
|
139
156
|
customElements.get("nys-toggle") || customElements.define("nys-toggle", e);
|
package/dist/nys-toggle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nys-toggle.js","sources":["../src/nys-toggle.ts"],"sourcesContent":["import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-toggle.scss?inline\";\n\nlet toggleIdCounter = 0;\n\n/**\n * A toggle switch for binary settings with immediate effect. Form-associated via ElementInternals.\n *\n * Use when changing a setting takes effect immediately (e.g., dark mode, notifications).\n * For binary choices in forms that submit later, use `nys-checkbox` instead.\n *\n * @summary Toggle switch for binary settings with immediate effect.\n * @element nys-toggle\n *\n * @slot description - Custom HTML description content.\n *\n * @fires nys-change - Fired when toggle state changes. Detail: `{id, checked}`.\n * @fires nys-focus - Fired when toggle gains focus.\n * @fires nys-blur - Fired when toggle loses focus.\n *\n * @example Basic toggle\n * ```html\n * <nys-toggle label=\"Enable notifications\" name=\"notifications\"></nys-toggle>\n * ```\n *\n * @example Dark mode toggle\n * ```html\n * <nys-toggle label=\"Dark mode\" description=\"Adjust display for low light\" checked></nys-toggle>\n * ```\n */\n\nexport class NysToggle extends LitElement {\n static styles = unsafeCSS(styles);\n\n /** Unique identifier. Auto-generated if not provided. */\n @property({ type: String, reflect: true }) id = \"\";\n\n /** Name for form submission. */\n @property({ type: String, reflect: true }) name = \"\";\n\n /** Value submitted when toggle is on. */\n @property({ type: String }) value = \"\";\n\n /** Visible label text. */\n @property({ type: String }) label = \"\";\n\n /** Helper text below label. Use slot for custom HTML. */\n @property({ type: String }) description = \"\";\n\n /** Form `id` to associate with. */\n @property({ type: String, reflect: true }) form: string | null = null;\n\n /** Whether toggle is on. */\n @property({ type: Boolean, reflect: true }) checked = false;\n\n /** Prevents interaction. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Hides check/close icon inside toggle knob. */\n @property({ type: Boolean }) noIcon = false;\n\n /** Adjusts colors for dark backgrounds. */\n @property({ type: Boolean, reflect: true }) inverted = false;\n\n /**\n * Toggle size: `sm` or `md` (default).\n * @default \"md\"\n */\n @property({ type: String, reflect: true }) size: \"sm\" | \"md\" = \"md\";\n\n private _internals: ElementInternals;\n\n /**\n * Lifecycle methods\n * --------------------------------------------------------------------------\n */\n\n static formAssociated = true; // allows use of elementInternals' API\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // Generate a unique ID if one is not provided\n connectedCallback() {\n super.connectedCallback();\n if (!this.id) {\n this.id = `nys-toggle-${Date.now()}-${toggleIdCounter++}`;\n }\n }\n\n /**\n * Form Integration\n * --------------------------------------------------------------------------\n */\n\n // Update the internals whenever `checked` or `value` changes.\n updated(changedProperties: Map<string, any>) {\n if (changedProperties.has(\"checked\") || changedProperties.has(\"value\")) {\n this._internals.setFormValue(this.checked ? this.value : null);\n }\n }\n\n public formResetCallback() {\n this.checked = false;\n\n this._internals.setFormValue(this.checked ? this.value : null);\n\n // Re-render UI\n this.requestUpdate();\n }\n\n /**\n * Event Handlers\n * --------------------------------------------------------------------------\n */\n\n private _emitChangeEvent() {\n this.dispatchEvent(\n new CustomEvent(\"nys-change\", {\n detail: { id: this.id, checked: this.checked },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // Handle focus event\n private _handleFocus() {\n this.dispatchEvent(new Event(\"nys-focus\"));\n }\n\n // Handle blur event\n private _handleBlur() {\n this.dispatchEvent(new Event(\"nys-blur\"));\n }\n\n private _handleChange(e: Event) {\n const { checked } = e.target as HTMLInputElement;\n this.checked = checked;\n this._emitChangeEvent();\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n if (!this.disabled && (event.key === \" \" || event.key === \"Enter\")) {\n event.preventDefault();\n\n // Manually toggle the checked state\n this.checked = !this.checked;\n\n this._emitChangeEvent();\n }\n }\n\n render() {\n return html`\n <label class=\"nys-toggle\">\n <div class=\"nys-toggle__content\">\n <div class=\"nys-toggle__toggle\">\n <input\n type=\"checkbox\"\n name=\"${ifDefined(this.name ? this.name : undefined)}\"\n .value=${this.value}\n form=${ifDefined(this.form || undefined)}\n .checked=${this.checked}\n ?disabled=${this.disabled}\n role=\"switch\"\n aria-checked=\"${this.checked ? \"true\" : \"false\"}\"\n aria-disabled=\"${this.disabled ? \"true\" : \"false\"}\"\n aria-label=\"${this.label || \"Toggle switch\"}\"\n @change=${this._handleChange}\n @focus=${this._handleFocus}\n @blur=${this._handleBlur}\n @keydown=${this._handleKeyDown}\n />\n <span class=\"slider\">\n <div class=\"knob\">\n ${this.noIcon\n ? \"\"\n : html`<nys-icon\n class=\"toggle-icon\"\n name=\"${this.checked ? \"check\" : \"close\"}\"\n size=\"2xl\"\n ></nys-icon>`}\n </div>\n </span>\n </div>\n ${this.label &&\n html`<nys-label\n label=${this.label}\n description=${ifDefined(this.description || undefined)}\n ?inverted=${this.inverted}\n >\n <slot name=\"description\" slot=\"description\"\n >${this.description}</slot\n >\n </nys-label> `}\n </div>\n </label>\n `;\n }\n}\n\nif (!customElements.get(\"nys-toggle\")) {\n customElements.define(\"nys-toggle\", NysToggle);\n}\n"],"names":["toggleIdCounter","_NysToggle","LitElement","changedProperties","e","checked","event","html","ifDefined","unsafeCSS","styles","NysToggle","__decorateClass","property"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nys-toggle.js","sources":["../src/nys-toggle.ts"],"sourcesContent":["import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-toggle.scss?inline\";\n\nlet toggleIdCounter = 0;\n\n/**\n * A toggle switch for binary settings with immediate effect. Form-associated via ElementInternals.\n *\n * Use when changing a setting takes effect immediately (e.g., dark mode, notifications).\n * For binary choices in forms that submit later, use `nys-checkbox` instead.\n *\n * @summary Toggle switch for binary settings with immediate effect.\n * @element nys-toggle\n *\n * @slot description - Custom HTML description content.\n *\n * @fires nys-change - Fired when toggle state changes. Detail: `{id, checked}`.\n * @fires nys-focus - Fired when toggle gains focus.\n * @fires nys-blur - Fired when toggle loses focus.\n *\n * @example Basic toggle\n * ```html\n * <nys-toggle label=\"Enable notifications\" name=\"notifications\"></nys-toggle>\n * ```\n *\n * @example Dark mode toggle\n * ```html\n * <nys-toggle label=\"Dark mode\" description=\"Adjust display for low light\" checked></nys-toggle>\n * ```\n */\n\nexport class NysToggle extends LitElement {\n static styles = unsafeCSS(styles);\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n /** Unique identifier. Auto-generated if not provided. */\n @property({ type: String, reflect: true }) id = \"\";\n\n /** Name for form submission. */\n @property({ type: String, reflect: true }) name = \"\";\n\n /** Value submitted when toggle is on. */\n @property({ type: String }) value = \"\";\n\n /** Visible label text. */\n @property({ type: String }) label = \"\";\n\n /** Helper text below label. Use slot for custom HTML. */\n @property({ type: String }) description = \"\";\n\n /** Form `id` to associate with. */\n @property({ type: String, reflect: true }) form: string | null = null;\n\n /** Whether toggle is on. */\n @property({ type: Boolean, reflect: true }) checked = false;\n\n /** Prevents interaction. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Hides check/close icon inside toggle knob. */\n @property({ type: Boolean }) noIcon = false;\n\n /** Adjusts colors for dark backgrounds. */\n @property({ type: Boolean, reflect: true }) inverted = false;\n\n /**\n * Toggle size: `sm` or `md` (default).\n * @default \"md\"\n */\n @property({ type: String, reflect: true }) size: \"sm\" | \"md\" = \"md\";\n\n private _internals: ElementInternals;\n\n /**\n * Lifecycle methods\n * --------------------------------------------------------------------------\n */\n\n static formAssociated = true; // allows use of elementInternals' API\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // Generate a unique ID if one is not provided\n connectedCallback() {\n super.connectedCallback();\n if (!this.id) {\n this.id = `nys-toggle-${Date.now()}-${toggleIdCounter++}`;\n }\n }\n\n /**\n * Form Integration\n * --------------------------------------------------------------------------\n */\n\n // Update the internals whenever `checked` or `value` changes.\n updated(changedProperties: Map<string, any>) {\n if (changedProperties.has(\"checked\") || changedProperties.has(\"value\")) {\n this._internals.setFormValue(this.checked ? this.value : null);\n }\n }\n\n public formResetCallback() {\n this.checked = false;\n\n this._internals.setFormValue(this.checked ? this.value : null);\n\n // Re-render UI\n this.requestUpdate();\n }\n\n /**\n * Event Handlers\n * --------------------------------------------------------------------------\n */\n\n private _emitChangeEvent() {\n this.dispatchEvent(\n new CustomEvent(\"nys-change\", {\n detail: { id: this.id, checked: this.checked },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // Handle focus event\n private _handleFocus() {\n this.dispatchEvent(new Event(\"nys-focus\"));\n }\n\n // Handle blur event\n private _handleBlur() {\n this.dispatchEvent(new Event(\"nys-blur\"));\n }\n\n private _handleClick() {\n if (this.disabled) return;\n this.checked = !this.checked;\n this._emitChangeEvent();\n }\n\n private _handleSliderClick(e: Event) {\n e.stopPropagation();\n this._handleClick();\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n if (!this.disabled && (event.key === \" \" || event.key === \"Enter\")) {\n event.preventDefault();\n\n // Manually toggle the checked state\n this.checked = !this.checked;\n\n this._emitChangeEvent();\n }\n }\n\n render() {\n return html`\n <div class=\"nys-toggle\">\n <div class=\"nys-toggle__content\">\n <div class=\"nys-toggle__toggle\">\n <input\n id=${this.id}\n type=\"checkbox\"\n name=\"${ifDefined(this.name ? this.name : undefined)}\"\n .value=${this.value}\n form=${ifDefined(this.form || undefined)}\n .checked=${this.checked}\n ?disabled=${this.disabled}\n role=\"switch\"\n aria-checked=\"${this.checked ? \"true\" : \"false\"}\"\n aria-disabled=\"${this.disabled ? \"true\" : \"false\"}\"\n aria-label=\"${this.label || \"Toggle switch\"}\"\n @click=${this._handleClick}\n @focus=${this._handleFocus}\n @blur=${this._handleBlur}\n @keydown=${this._handleKeyDown}\n />\n <span class=\"slider\" @click=${this._handleSliderClick}>\n <div class=\"knob\">\n ${this.noIcon\n ? \"\"\n : html`<nys-icon\n class=\"toggle-icon\"\n name=\"${this.checked ? \"check\" : \"close\"}\"\n size=\"2xl\"\n ></nys-icon>`}\n </div>\n </span>\n </div>\n ${this.label &&\n html`<nys-label\n for=${this.id}\n label=${this.label}\n description=${ifDefined(this.description || undefined)}\n ?inverted=${this.inverted}\n >\n <slot name=\"description\" slot=\"description\"\n >${this.description}</slot\n >\n </nys-label> `}\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"nys-toggle\")) {\n customElements.define(\"nys-toggle\", NysToggle);\n}\n"],"names":["toggleIdCounter","_NysToggle","LitElement","changedProperties","e","event","html","ifDefined","unsafeCSS","styles","NysToggle","__decorateClass","property"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nysds/nys-toggle",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "The Toggle component from the NYS Design System.",
|
|
5
5
|
"module": "dist/nys-toggle.js",
|
|
6
6
|
"exports": {
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"lit-analyze": "lit-analyzer '**/*.ts'"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@nysds/nys-icon": "^1.
|
|
25
|
+
"@nysds/nys-icon": "^1.15.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"lit": "^3.3.1",
|
|
29
29
|
"typescript": "^5.9.3",
|
|
30
|
-
"vite": "^7.1
|
|
30
|
+
"vite": "^7.3.1"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
|
33
33
|
"new-york-state",
|