svelte-toggle-switch 2.0.0 → 2.2.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.
@@ -0,0 +1,10 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm run check:*)",
5
+ "Bash(git commit:*)",
6
+ "Bash(git add:*)",
7
+ "Bash(git tag:*)"
8
+ ]
9
+ }
10
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,115 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [2.2.0] - 2026-01-06
9
+
10
+ ### Added
11
+ - **Dark Mode Support**:
12
+ - `darkMode` prop with `true`, `false`, or `'auto'` options
13
+ - Auto-detection of system theme using `prefers-color-scheme` media query
14
+ - Dynamic theme switching with real-time event listeners
15
+ - Dark color variants for all 9 color schemes (blue, green, red, purple, orange, pink, yellow, indigo, teal)
16
+ - Dark mode aware label and helper text colors
17
+ - **Gradient Colors**:
18
+ - `gradient` prop to enable gradient backgrounds
19
+ - 5 built-in gradient presets: sunset, ocean, forest, berry, fire
20
+ - `gradientPreset` prop to select from presets or use custom
21
+ - `customGradient` prop for custom CSS gradient support
22
+ - Gradient support across all design variants (slider, inner, modern, material, multi)
23
+ - **Touch Gesture Support**:
24
+ - `swipeToToggle` prop to enable swipe-to-toggle on mobile
25
+ - Touch event handlers (touchstart, touchmove, touchend)
26
+ - `swipeThreshold` prop to customize swipe distance (default 50px)
27
+ - Visual feedback with dragging state showing thumb following finger
28
+ - RTL-aware swipe direction handling
29
+ - **RTL (Right-to-Left) Support**:
30
+ - `dir` prop with `'ltr'`, `'rtl'`, or `'auto'` options
31
+ - Auto-detection of document text direction
32
+ - Mirrored animations and transforms for RTL layouts
33
+ - Touch gesture direction adjustment for RTL
34
+ - Full support for Arabic, Hebrew, Persian, and other RTL languages
35
+ - **Demo Application Enhancements**:
36
+ - Dedicated v2.2.0 features showcase section
37
+ - 15+ interactive examples for new features
38
+ - Beautiful gradient-themed feature highlight section
39
+ - Mobile-friendly responsive design updates
40
+
41
+ ### Changed
42
+ - Updated all design variants to support gradient backgrounds
43
+ - Enhanced CSS transforms to work correctly in RTL layouts
44
+ - Improved animation performance for touch interactions
45
+ - Updated demo application footer with v2.2.0 version information
46
+
47
+ ### Technical
48
+ - Added SSR-safe window and document checks for all new features
49
+ - Implemented reactive color determination with dark mode awareness
50
+ - Added CSS custom properties for drag offset in touch gestures
51
+ - Enhanced CSS with 200+ new lines for feature support
52
+ - Maintained full backward compatibility with v2.1.0
53
+
54
+ ## [2.1.0] - 2026-01-02
55
+
56
+ ### Added
57
+ - **Event Dispatchers**: Added `on:change`, `on:focus`, and `on:blur` event handlers for better integration with frameworks and form libraries
58
+ - **Custom Text Labels**: New `onText` and `offText` props to customize the text displayed in the inner design (default: "ON"/"OFF")
59
+ - **Form Validation Support**:
60
+ - `helperText` prop - Display helper text below the switch
61
+ - `errorText` prop - Display error message when validation fails
62
+ - `required` prop - Mark the switch as required
63
+ - `error` prop - Show error state with red styling
64
+ - `name` prop - Form field name for submission
65
+ - **New Color Schemes**: Added `yellow`, `indigo`, and `teal` color schemes (now 9 total color schemes)
66
+ - **Enhanced Accessibility**:
67
+ - `tabIndex` prop for custom keyboard navigation order
68
+ - `aria-required` and `aria-invalid` attributes for form validation
69
+ - Improved screen reader support with helper text announcements
70
+ - **Demo Application**: Comprehensive SvelteKit demo with interactive playground at svelte-toggle-switch.ishansasika.dev
71
+ - Live preview with all props
72
+ - Real-time code generation
73
+ - 15+ quick example presets
74
+ - Icon picker with 10+ preset icons
75
+ - Complete documentation
76
+
77
+ ### Changed
78
+ - Updated component to dispatch custom events with detailed payload
79
+ - Multi-select now dispatches change events properly
80
+ - Helper text and error text display dynamically below all switch designs
81
+ - Error state now includes visual border color change
82
+
83
+ ### Fixed
84
+ - Multi-select change events now trigger correctly
85
+ - Focus and blur events properly propagate
86
+ - ARIA attributes correctly reference helper text for screen readers
87
+
88
+ ## [2.0.0] - 2025-12-14
89
+
90
+ ### Added
91
+ - Complete rewrite with TypeScript support
92
+ - 5 design variants (slider/ios, inner, modern, material, multi)
93
+ - 6 color schemes (blue, green, red, purple, orange, pink)
94
+ - 5 size variants (xs, sm, md, lg, xl)
95
+ - Custom icon support with showIcons, onIcon, and offIcon props
96
+ - Comprehensive accessibility with ARIA attributes
97
+ - Loading and disabled states
98
+ - Shadow and outline visual effects
99
+ - Customizable animations (duration and easing)
100
+ - Label positioning (left/right)
101
+ - Multi-option mode with radio group styling
102
+
103
+ ### Breaking Changes
104
+ - Migrated from Svelte 4 to Svelte 5 with runes support
105
+ - Component props now use TypeScript types
106
+ - Removed deprecated v1.x props
107
+
108
+ ## [1.0.0] - 2022-05-29
109
+
110
+ ### Added
111
+ - Initial release
112
+ - Basic toggle switch functionality
113
+ - iOS-style design
114
+ - ON/OFF states
115
+ - Simple customization options
package/README.md CHANGED
@@ -5,7 +5,7 @@ A comprehensive, accessible, and highly customizable toggle switch component for
5
5
  ## Features
6
6
 
7
7
  ✨ **5 Design Variants**: Slider (iOS), Inner, Modern, Material, and Multi-option\
8
- 🎨 **Multiple Color Schemes**: 6 built-in schemes + custom colors\
8
+ 🎨 **Multiple Color Schemes**: 9 built-in schemes + custom colors\
9
9
  📏 **5 Size Options**: From extra small to extra large\
10
10
  ♿ **Fully Accessible**: ARIA attributes, keyboard navigation, screen reader support\
11
11
  🔄 **State Management**: Disabled, loading, and read-only states\
@@ -13,6 +13,10 @@ A comprehensive, accessible, and highly customizable toggle switch component for
13
13
  ⚡ **Smooth Animations**: Customizable duration and easing\
14
14
  📦 **TypeScript**: Full TypeScript support with proper types\
15
15
  🎭 **Flexible Styling**: Shadow, outline, and label positioning options\
16
+ 🌙 **Dark Mode Support**: Auto-detect system theme or manual control (v2.2.0)\
17
+ 🌈 **Gradient Colors**: 5 beautiful gradient presets + custom gradients (v2.2.0)\
18
+ 👆 **Touch Gestures**: Swipe to toggle on mobile devices (v2.2.0)\
19
+ 🌐 **RTL Support**: Full right-to-left language support (v2.2.0)\
16
20
  🚀 **Modern Stack**: Built with Svelte 5, Vite 6, and TypeScript 5
17
21
 
18
22
  ## Installation
@@ -44,6 +48,88 @@ pnpm add svelte-toggle-switch
44
48
  <Switch bind:value={enabled} label="Enable notifications" />
45
49
  ```
46
50
 
51
+ ## New in v2.2.0
52
+
53
+ ### 🌙 Dark Mode Support
54
+
55
+ Automatically adapt to system theme or manually control dark mode colors.
56
+
57
+ ```svelte
58
+ <!-- Auto-detect system theme -->
59
+ <Switch bind:value={enabled} darkMode="auto" label="Notifications" />
60
+
61
+ <!-- Always use dark mode -->
62
+ <Switch bind:value={enabled} darkMode={true} label="Wi-Fi" />
63
+
64
+ <!-- Combine with gradients -->
65
+ <Switch
66
+ bind:value={enabled}
67
+ darkMode={true}
68
+ gradient={true}
69
+ gradientPreset="berry"
70
+ label="Premium mode"
71
+ />
72
+ ```
73
+
74
+ ### 🌈 Gradient Colors
75
+
76
+ Add beautiful gradient backgrounds with built-in presets or custom gradients.
77
+
78
+ ```svelte
79
+ <!-- Built-in gradient presets -->
80
+ <Switch bind:value={enabled} gradient={true} gradientPreset="sunset" />
81
+ <Switch bind:value={enabled} gradient={true} gradientPreset="ocean" />
82
+ <Switch bind:value={enabled} gradient={true} gradientPreset="forest" />
83
+ <Switch bind:value={enabled} gradient={true} gradientPreset="berry" />
84
+ <Switch bind:value={enabled} gradient={true} gradientPreset="fire" />
85
+
86
+ <!-- Custom gradient -->
87
+ <Switch
88
+ bind:value={enabled}
89
+ gradient={true}
90
+ gradientPreset="custom"
91
+ customGradient="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
92
+ />
93
+ ```
94
+
95
+ ### 👆 Touch Gesture Support
96
+
97
+ Enable swipe-to-toggle for mobile-friendly interactions.
98
+
99
+ ```svelte
100
+ <!-- Enable swipe to toggle -->
101
+ <Switch bind:value={enabled} swipeToToggle={true} label="Notifications" />
102
+
103
+ <!-- Custom swipe threshold -->
104
+ <Switch
105
+ bind:value={enabled}
106
+ swipeToToggle={true}
107
+ swipeThreshold={30}
108
+ label="Quick toggle"
109
+ />
110
+ ```
111
+
112
+ ### 🌐 RTL (Right-to-Left) Support
113
+
114
+ Full support for Arabic, Hebrew, Persian, and other RTL languages.
115
+
116
+ ```svelte
117
+ <!-- Manual RTL direction -->
118
+ <Switch bind:value={enabled} dir="rtl" label="إعدادات" />
119
+
120
+ <!-- Auto-detect direction -->
121
+ <Switch bind:value={enabled} dir="auto" label="Settings" />
122
+
123
+ <!-- RTL with icons -->
124
+ <Switch
125
+ bind:value={enabled}
126
+ dir="rtl"
127
+ design="modern"
128
+ showIcons={true}
129
+ label="مزامنة"
130
+ />
131
+ ```
132
+
47
133
  ## Design Variants
48
134
 
49
135
  ### Slider (iOS Style)
@@ -246,6 +332,13 @@ Add custom icons to your toggles.
246
332
  | `rounded` | `boolean` | `true` | Use rounded corners (inner design) |
247
333
  | `shadow` | `boolean` | `false` | Add box shadow |
248
334
  | `outline` | `boolean` | `false` | Add border outline |
335
+ | `darkMode` | `boolean \| 'auto'` | `false` | Dark mode: `true`, `false`, or `'auto'` to detect system theme (v2.2.0) |
336
+ | `gradient` | `boolean` | `false` | Enable gradient colors (v2.2.0) |
337
+ | `gradientPreset` | `'sunset' \| 'ocean' \| 'forest' \| 'berry' \| 'fire' \| 'custom'` | `'sunset'` | Gradient preset (v2.2.0) |
338
+ | `customGradient` | `string` | `''` | Custom CSS gradient when `gradientPreset='custom'` (v2.2.0) |
339
+ | `swipeToToggle` | `boolean` | `false` | Enable swipe gesture to toggle (mobile) (v2.2.0) |
340
+ | `swipeThreshold` | `number` | `50` | Swipe distance in pixels to trigger toggle (v2.2.0) |
341
+ | `dir` | `'ltr' \| 'rtl' \| 'auto'` | `'auto'` | Text direction for RTL support (v2.2.0) |
249
342
 
250
343
  ## Accessibility
251
344
 
@@ -375,7 +468,27 @@ MIT © [Ishan Karunaratne](https://github.com/ishansasika)
375
468
 
376
469
  ## Changelog
377
470
 
378
- ### Version 2.0.0 (Latest)
471
+ ### Version 2.2.0 (Latest)
472
+
473
+ **New Features** - Enhanced mobile experience and theming:
474
+
475
+ - 🌙 **Dark Mode Support**: Auto-detect system theme or manual control
476
+ - 🌈 **Gradient Colors**: 5 beautiful gradient presets + custom gradients
477
+ - 👆 **Touch Gestures**: Swipe to toggle on mobile devices
478
+ - 🌐 **RTL Support**: Full right-to-left language support for international users
479
+ - 🎨 Dark color variants for all 9 color schemes
480
+ - ⚡ Optimized animations for touch interactions
481
+
482
+ ### Version 2.1.0
483
+
484
+ **Form Integration & Events**:
485
+
486
+ - 📤 Event dispatchers (`on:change`, `on:focus`, `on:blur`)
487
+ - 📝 Form validation support (helperText, errorText, required, error props)
488
+ - 🎨 Added 3 new color schemes (yellow, indigo, teal)
489
+ - ♿ Enhanced accessibility with form validation states
490
+
491
+ ### Version 2.0.0
379
492
 
380
493
  **Major Rewrite** - Complete redesign with modern features:
381
494
 
Binary file
@@ -0,0 +1 @@
1
+ :root{--active-color: #007AFF;--off-color: #E5E7EB;--animation-duration: .3s;--animation-easing: ease-in-out}.switch-container.svelte-128hqhb{display:inline-flex;align-items:center;gap:.75em;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif}.switch-container.disabled.svelte-128hqhb{opacity:.5;cursor:not-allowed}.switch-container.readonly.svelte-128hqhb{cursor:default}.switch-container.dark.svelte-128hqhb .switch-label:where(.svelte-128hqhb){color:#e5e7eb}.switch-label.svelte-128hqhb{-webkit-user-select:none;user-select:none;font-size:1em;color:#374151;transition:color var(--animation-duration) var(--animation-easing)}.switch-helper-text.svelte-128hqhb{display:block;font-size:.875em;color:#6b7280;margin-top:.375em;line-height:1.4}.switch-helper-text.error-text.svelte-128hqhb{color:#ef4444}.switch.svelte-128hqhb{position:relative;border:none;cursor:pointer;transition:all var(--animation-duration) var(--animation-easing);font-family:inherit}.switch.svelte-128hqhb:disabled{cursor:not-allowed}.switch.svelte-128hqhb:focus-visible{outline:2px solid var(--active-color);outline-offset:2px}.switch.shadow.svelte-128hqhb{box-shadow:0 2px 4px #0000001a}.switch.outline.svelte-128hqhb{border:1px solid #D1D5DB}.switch.error.svelte-128hqhb{border-color:#ef4444}.switch.error.svelte-128hqhb:focus-visible{outline-color:#ef4444}.switch--inner.svelte-128hqhb{padding:.4em .8em;background-color:var(--off-color);color:#6b7280;font-weight:500;font-size:.875em;min-width:4em;border-radius:.25em}.switch--inner.rounded.svelte-128hqhb{border-radius:.5em}.switch--inner.checked.svelte-128hqhb{background-color:var(--active-color);color:#fff}.switch--inner.checked.gradient.svelte-128hqhb{background:var(--active-color)}.switch--inner.svelte-128hqhb .switch-text:where(.svelte-128hqhb){display:block;-webkit-user-select:none;user-select:none;pointer-events:none}.switch--slider.svelte-128hqhb{padding:0;background:transparent;width:3.5em;height:2em}.switch-track.svelte-128hqhb{position:relative;display:block;width:100%;height:100%;background-color:var(--off-color);border-radius:1em;transition:background-color var(--animation-duration) var(--animation-easing)}.switch--slider.checked.svelte-128hqhb .switch-track:where(.svelte-128hqhb){background-color:var(--active-color)}.switch--slider.checked.gradient.svelte-128hqhb .switch-track:where(.svelte-128hqhb){background:var(--active-color)}.switch-thumb.svelte-128hqhb{position:absolute;top:.15em;left:.15em;width:1.7em;height:1.7em;background-color:#fff;border-radius:50%;transition:transform var(--animation-duration) var(--animation-easing);box-shadow:0 2px 4px #0003;display:flex;align-items:center;justify-content:center}.switch--slider.checked.svelte-128hqhb .switch-thumb:where(.svelte-128hqhb){transform:translate(1.5em)}.switch-thumb.dragging.svelte-128hqhb{transition:none;transform:translate(calc(var(--drag-offset, 0px)))}.switch--slider.checked.svelte-128hqhb .switch-thumb.dragging:where(.svelte-128hqhb){transform:translate(calc(1.5em + var(--drag-offset, 0px)))}.switch--slider.rtl.checked.svelte-128hqhb .switch-thumb:where(.svelte-128hqhb){transform:translate(-1.5em)}.switch--slider.rtl.checked.svelte-128hqhb .switch-thumb.dragging:where(.svelte-128hqhb){transform:translate(calc(-1.5em + var(--drag-offset, 0px)))}.switch-icon.svelte-128hqhb{font-size:.75em;-webkit-user-select:none;user-select:none}.switch--modern.svelte-128hqhb{padding:0;background:transparent;width:4em;height:2.2em}.switch--modern.svelte-128hqhb .switch-track:where(.svelte-128hqhb){border-radius:1.1em}.switch-thumb-modern.svelte-128hqhb{position:absolute;top:.2em;left:.2em;width:1.8em;height:1.8em;background-color:#fff;border-radius:50%;transition:transform var(--animation-duration) var(--animation-easing),background-color var(--animation-duration) var(--animation-easing);box-shadow:0 2px 8px #00000026;display:flex;align-items:center;justify-content:center}.switch--modern.checked.svelte-128hqhb .switch-thumb-modern:where(.svelte-128hqhb){transform:translate(1.8em)}.switch-thumb-modern.dragging.svelte-128hqhb{transition:none;transform:translate(calc(var(--drag-offset, 0px)))}.switch--modern.checked.svelte-128hqhb .switch-thumb-modern.dragging:where(.svelte-128hqhb){transform:translate(calc(1.8em + var(--drag-offset, 0px)))}.switch--modern.rtl.checked.svelte-128hqhb .switch-thumb-modern:where(.svelte-128hqhb){transform:translate(-1.8em)}.switch--modern.rtl.checked.svelte-128hqhb .switch-thumb-modern.dragging:where(.svelte-128hqhb){transform:translate(calc(-1.8em + var(--drag-offset, 0px)))}.switch--modern.checked.gradient.svelte-128hqhb .switch-track:where(.svelte-128hqhb){background:var(--active-color)}.track-icons.svelte-128hqhb{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:space-between;padding:0 .5em;pointer-events:none}.track-icon.svelte-128hqhb{font-size:.7em;color:#fff;opacity:0;transition:opacity var(--animation-duration) var(--animation-easing)}.switch--modern.checked.svelte-128hqhb .track-icon--on:where(.svelte-128hqhb){opacity:1}.switch--modern.svelte-128hqhb:not(.checked) .track-icon--off:where(.svelte-128hqhb){opacity:.7}.switch-icon-modern.svelte-128hqhb{font-size:.8em;-webkit-user-select:none;user-select:none;color:var(--active-color)}.switch--material.svelte-128hqhb{padding:0;background:transparent;width:3.5em;height:1.5em}.switch-track-material.svelte-128hqhb{position:relative;display:block;width:100%;height:100%;background-color:var(--off-color);border-radius:.75em;transition:background-color var(--animation-duration) var(--animation-easing)}.switch--material.checked.svelte-128hqhb .switch-track-material:where(.svelte-128hqhb){background-color:var(--active-color);opacity:.5}.switch-thumb-material.svelte-128hqhb{position:absolute;top:50%;left:0;transform:translateY(-50%);width:1.5em;height:1.5em;background-color:#fafafa;border-radius:50%;transition:transform var(--animation-duration) var(--animation-easing),background-color var(--animation-duration) var(--animation-easing);box-shadow:0 2px 4px #0000004d;display:flex;align-items:center;justify-content:center}.switch--material.checked.svelte-128hqhb .switch-thumb-material:where(.svelte-128hqhb){transform:translateY(-50%) translate(2em);background-color:var(--active-color)}.switch-thumb-material.dragging.svelte-128hqhb{transition:none;transform:translateY(-50%) translate(calc(var(--drag-offset, 0px)))}.switch--material.checked.svelte-128hqhb .switch-thumb-material.dragging:where(.svelte-128hqhb){transform:translateY(-50%) translate(calc(2em + var(--drag-offset, 0px)))}.switch--material.rtl.checked.svelte-128hqhb .switch-thumb-material:where(.svelte-128hqhb){transform:translateY(-50%) translate(-2em)}.switch--material.rtl.checked.svelte-128hqhb .switch-thumb-material.dragging:where(.svelte-128hqhb){transform:translateY(-50%) translate(calc(-2em + var(--drag-offset, 0px)))}.switch--material.checked.gradient.svelte-128hqhb .switch-thumb-material:where(.svelte-128hqhb){background:var(--active-color)}.switch-container--multi.svelte-128hqhb{display:block}.switch-multi.svelte-128hqhb{display:inline-block}.switch-multi-legend.svelte-128hqhb{font-size:.9em;color:#374151;margin-bottom:.5em;font-weight:500}.switch-multi-options.svelte-128hqhb{display:inline-flex;background-color:var(--off-color);border-radius:.5em;padding:.25em;position:relative}.switch-multi-options.shadow.svelte-128hqhb{box-shadow:0 2px 4px #0000001a}.switch-multi-options.outline.svelte-128hqhb{border:1px solid #D1D5DB}.switch-multi-input.svelte-128hqhb{position:absolute;opacity:0;pointer-events:none}.switch-multi-label.svelte-128hqhb{position:relative;padding:.5em 1.2em;border-radius:.375em;cursor:pointer;-webkit-user-select:none;user-select:none;transition:all var(--animation-duration) var(--animation-easing);font-size:.875em;font-weight:500;color:#6b7280;z-index:1}.switch-multi-label.first.svelte-128hqhb{margin-left:0}.switch-multi-label.last.svelte-128hqhb{margin-right:0}.switch-multi-input.svelte-128hqhb:checked+.switch-multi-label:where(.svelte-128hqhb){background-color:var(--active-color);color:#fff;box-shadow:0 1px 3px #0000001a}.switch-multi-options.gradient.svelte-128hqhb .switch-multi-input:where(.svelte-128hqhb):checked+.switch-multi-label:where(.svelte-128hqhb){background:var(--active-color)}.switch-multi-input.svelte-128hqhb:focus-visible+.switch-multi-label:where(.svelte-128hqhb){outline:2px solid var(--active-color);outline-offset:2px}.switch-multi-input.svelte-128hqhb:disabled+.switch-multi-label:where(.svelte-128hqhb){cursor:not-allowed;opacity:.5}.spinner.svelte-128hqhb,.spinner-small.svelte-128hqhb{display:inline-block;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:svelte-128hqhb-spin .6s linear infinite}.spinner.svelte-128hqhb{width:1em;height:1em}.spinner-small.svelte-128hqhb{width:.8em;height:.8em;border-width:1.5px}@keyframes svelte-128hqhb-spin{to{transform:rotate(360deg)}}.switch.svelte-128hqhb:not(:disabled):hover{opacity:.9}.switch-multi-label.svelte-128hqhb:hover{background-color:#0000000d}.switch-multi-input.svelte-128hqhb:checked+.switch-multi-label:where(.svelte-128hqhb):hover{background-color:var(--active-color);opacity:.9}