Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 96b8192408 | |||
| 1aa34d2640 |
@@ -0,0 +1,33 @@
|
|||||||
|
.toggle {
|
||||||
|
background-color: var(--nds-disabled);
|
||||||
|
border-radius: var(--nds-radius-full);
|
||||||
|
padding: var(--nds-spacing-2xs);
|
||||||
|
width: 50px;
|
||||||
|
height: 25px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: left;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 160ms ease;
|
||||||
|
position: relative;
|
||||||
|
&-switch {
|
||||||
|
color: var(--nds-text);
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
background-color: var(--nds-text);
|
||||||
|
border-radius: var(--nds-radius-full);
|
||||||
|
position: absolute;
|
||||||
|
left: var(--nds-spacing-2xs);
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
transition: left 160ms ease, background-color 160ms ease, transform 160ms ease;
|
||||||
|
}
|
||||||
|
&-active {
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
background-color: var(--nds-primary);
|
||||||
|
.toggle-switch {
|
||||||
|
left: calc(100% - var(--nds-spacing-2xs) - 15px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
export interface Props {
|
||||||
|
checked?: boolean;
|
||||||
|
name?: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { checked = false, name = 'toggle', id} = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<toggle-switch data-checked={checked} data-name={name} id={id}>
|
||||||
|
<div class="toggle">
|
||||||
|
<div class="toggle-switch"></div>
|
||||||
|
</div>
|
||||||
|
</toggle-switch>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
class ToggleSwitch extends HTMLElement {
|
||||||
|
private _checked: boolean = false;
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this._checked = this.dataset.checked === 'true';
|
||||||
|
this.updateUI();
|
||||||
|
|
||||||
|
this.querySelector('.toggle')?.addEventListener('click', () => {
|
||||||
|
this.toggle();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle() {
|
||||||
|
this._checked = !this._checked;
|
||||||
|
this.updateUI();
|
||||||
|
|
||||||
|
this.dispatchEvent(new CustomEvent('change', {
|
||||||
|
detail: { checked: this._checked, name: this.dataset.name },
|
||||||
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
set checked(value: boolean) {
|
||||||
|
this._checked = value;
|
||||||
|
this.updateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
get checked() {
|
||||||
|
return this._checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateUI() {
|
||||||
|
this.dataset.checked = String(this._checked);
|
||||||
|
this.querySelector('.toggle')?.classList.toggle('toggle-active', this._checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('toggle-switch', ToggleSwitch);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@use './_toggle.scss';
|
||||||
|
</style>
|
||||||
@@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
export * from './Icons/index.ts';
|
export * from './Icons/index.ts';
|
||||||
export { default as Notification } from './Notifications/notification.astro';
|
export { default as Notification } from './Notifications/notification.astro';
|
||||||
|
export { default as Toggle } from './Toggle/toggle.astro';
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from '../layouts/Layout.astro';
|
import Layout from '../layouts/Layout.astro';
|
||||||
|
import Toggle from '../components/Toggle/toggle.astro';
|
||||||
import {
|
import {
|
||||||
Arrow2Icon, BinIcon, BurgerIcon, CalendarIcon, CheckIcon, CloseIcon,
|
Arrow2Icon, BinIcon, BurgerIcon, CalendarIcon, CheckIcon, CloseIcon,
|
||||||
CodeIcon, CubeIcon, DownloadIcon, FilterIcon, HelpIcon, HomeIcon,
|
CodeIcon, CubeIcon, DownloadIcon, FilterIcon, HelpIcon, HomeIcon,
|
||||||
@@ -8,11 +9,20 @@ import {
|
|||||||
UploadIcon,
|
UploadIcon,
|
||||||
} from '../components/Icons/index.ts';
|
} from '../components/Icons/index.ts';
|
||||||
import Notification from '../components/Notifications/notification.astro';
|
import Notification from '../components/Notifications/notification.astro';
|
||||||
|
|
||||||
|
const initialChecked = false;
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
<main>
|
<main>
|
||||||
<h1>Nova Design System</h1>
|
<h1>Nova Design System</h1>
|
||||||
|
<section>
|
||||||
|
<h2>Toggle</h2>
|
||||||
|
<div style="display: flex; flex-direction: column; gap: var(--nds-spacing-md);">
|
||||||
|
<Toggle data-checked={initialChecked} data-name="notifications" id="my-toggle" />
|
||||||
|
<p id="toggle-state">State: {initialChecked ? 'Checked' : 'Unchecked'}</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h2>Notifications — Error / Warning / Success / Info</h2>
|
<h2>Notifications — Error / Warning / Success / Info</h2>
|
||||||
<div style="max-width: 400px; display: flex; flex-direction: column; gap: var(--nds-spacing-md);">
|
<div style="max-width: 400px; display: flex; flex-direction: column; gap: var(--nds-spacing-md);">
|
||||||
@@ -182,6 +192,19 @@ import Notification from '../components/Notifications/notification.astro';
|
|||||||
</main>
|
</main>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const toggle = document.getElementById('my-toggle') as any;
|
||||||
|
const stateLabel = document.getElementById('toggle-state');
|
||||||
|
|
||||||
|
toggle?.addEventListener('change', (e: CustomEvent) => {
|
||||||
|
const { checked, name } = e.detail;
|
||||||
|
|
||||||
|
if (stateLabel) {
|
||||||
|
stateLabel.textContent = `State: ${checked ? 'Checked' : 'Unchecked'}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|||||||
Reference in New Issue
Block a user