@monabbous/slidebox 0.0.7 → 1.1.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 CHANGED
@@ -1,55 +1,215 @@
1
- # Slidebox
2
- ![Example](https://i.imgur.com/yyRPh0R.gif)
3
- ## [Example (click me)](https://htmlpreview.github.io/?https://github.com/monabbous/slidebox/blob/master/examples/simple.html)
4
- As you can see in the example above, this slidebox is easy to configure with these two css properties, `color` and `font-size`.
5
-
6
- ### Quick Setup
7
- Include in your html
8
-
9
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"/>
10
- <link rel="stylesheet" href="https://unpkg.com/@monabbous/slidebox@0.0.3/dist/css/slidebox.css"/>
11
-
12
- Add the `slidebox` class
13
-
14
- <input style="font-size: 24px" type="checkbox" class="slidebox">
15
-
16
- ## Installation (Sass)
17
- #### 1. Font Awesome
18
- First you must include **[Font Awesome](https://fontawesome.com)** in your project (Preferable Font Awesome 5).
19
- #### 2. Slidebox
20
-
21
- Using `Sass` with `NPM` just install with
22
-
23
- npm i @monabbous/slidebox
24
-
25
- Then include in your sass style file
26
-
27
- @import '~@monabbous/slidebox';
28
-
29
- ## Usage
30
- Simply in your checkbox element add the slidebox class.
31
-
32
- <input type="checkbox" class="slidebox">
33
-
34
- ### Custom Style
35
- Just like the Example, you can modify the color and the size of the checkbox.
36
-
37
- <input style="font-size: 24px" type="checkbox" class="slidebox">
38
-
39
- Make sure when modifying the color to add class `dark` when using a dark color, and `light` when using a light color.
40
-
41
- <!-- dark color -->
42
- <input style="color:#040491" type="checkbox" class="slidebox dark">
43
-
44
- <!-- light color -->
45
- <input style="color:#a8a8ff" type="checkbox" class="slidebox light">
46
-
47
- You can also invert the visible output of the slide box, where the value of the checkbox is the opposite of how it is shown.
48
-
49
- <input type="checkbox" class="slidebox inverted">
50
-
51
- ### Changing the default Configuration
52
-
53
- $slideboxColorDefaultColor: blue;
54
- $slideboxClassPrefix: 'nabbous-';
55
- @import '~@monabbous/slidebox';
1
+ # Slidebox
2
+
3
+ An elastic CSS switch built on a native checkbox. No JavaScript, extra elements, or runtime dependencies required.
4
+
5
+ ![Slidebox switch animation](assets/slidebox-demo.webp)
6
+
7
+ [Try the playground](https://htmlpreview.github.io/?https://github.com/monabbous/slidebox/blob/main/index.html) · [npm](https://www.npmjs.com/package/@monabbous/slidebox)
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ npm install @monabbous/slidebox
13
+ ```
14
+
15
+ Choose **one** integration below: CSS, Sass, Less, or Tailwind. You don't need to import the plain CSS when using a mixin or the Tailwind plugin.
16
+
17
+ ## Plain CSS
18
+
19
+ Import the stylesheet through your bundler:
20
+
21
+ ```js
22
+ import "@monabbous/slidebox/dist/css/slidebox.css";
23
+ ```
24
+
25
+ Add the class to a checkbox and give it an accessible label:
26
+
27
+ ```html
28
+ <label>
29
+ <input class="slidebox" type="checkbox" role="switch" name="notifications">
30
+ Enable notifications
31
+ </label>
32
+ ```
33
+
34
+ Use normal checkbox attributes: `checked`, `disabled`, `required`, `name`, and `value`. Read or change its state with your framework's normal checkbox binding. `role="switch"` is optional; omit it for checkbox semantics.
35
+
36
+ ### Set defaults and override individual switches
37
+
38
+ Public custom properties inherit, so you can set site-wide defaults on `:root`, section defaults on a parent, or overrides on a single input:
39
+
40
+ ```css
41
+ :root {
42
+ color-scheme: light dark;
43
+ --slidebox-size: 24px;
44
+ --slidebox-on: #7c3aed;
45
+ --slidebox-duration: 250ms;
46
+ }
47
+
48
+ .settings {
49
+ --slidebox-width: 2.4;
50
+ }
51
+
52
+ .slidebox.compact {
53
+ --slidebox-size: 18px;
54
+ --slidebox-spacing: 0.25;
55
+ }
56
+ ```
57
+
58
+ `color-scheme: light dark` lets the system colors follow the user's theme. Use `light` or `dark` to force a scheme.
59
+
60
+ ## Controls
61
+
62
+ The same names work as CSS properties (`--slidebox-NAME`), Sass map keys, Less arguments (`@NAME`), and Tailwind plugin options/utilities.
63
+
64
+ | Control | Default | Meaning |
65
+ | --- | --- | --- |
66
+ | `size` | `54px` | Switch height; width and thumb geometry scale with it. Use a CSS length. |
67
+ | `width` | `2` | Track width divided by height. Use a unitless number greater than 1. |
68
+ | `spacing` | `.33` | Space around the thumb as a fraction of the height. Use a number from 0 to less than 1. |
69
+ | `deform` | `.1` | Elastic press deformation and motion delay ratio. Use a number from 0 to less than 1; 0 removes the deformation. |
70
+ | `duration` | `200ms` | Animation duration, including a time unit. |
71
+ | `easing` | `ease-in-out` | Any CSS timing function, including `cubic-bezier()` and `linear()`. |
72
+ | `track` | `Field` | Track background color. |
73
+ | `border` | `ButtonBorder` | Track border color. |
74
+ | `off` | `FieldText` | Unchecked thumb color. |
75
+ | `on` | System accent, when supported | Checked thumb color; falls back to `light-dark(#0b75ff, SelectedItem)`. |
76
+
77
+ Custom colors do not override forced-colors accessibility mode. Reduced-motion users get effectively instant transitions. Logical margins support both LTR and RTL layouts. Keep the browser's focus outline, or provide a visible `:focus-visible` style yourself.
78
+
79
+ ## Sass mixin
80
+
81
+ Use Dart Sass's module system. Configure shared defaults with `$defaults`, then override any control per mixin call:
82
+
83
+ ```scss
84
+ @use "@monabbous/slidebox/scss/mixins" as slidebox with (
85
+ $defaults: (
86
+ size: 24px,
87
+ on: #7c3aed,
88
+ duration: 250ms
89
+ )
90
+ );
91
+
92
+ .toggle {
93
+ @include slidebox.slidebox();
94
+ }
95
+
96
+ .toggle-large {
97
+ @include slidebox.slidebox((size: 36px, width: 2.5));
98
+ }
99
+ ```
100
+
101
+ ```html
102
+ <label><input class="toggle" type="checkbox"> Enable notifications</label>
103
+ ```
104
+
105
+ Importing the mixin does not emit CSS until you include it. Configure the module once, before any other module loads it. Your Sass bundler must resolve npm imports (with the Sass CLI, add `--load-path=node_modules`).
106
+
107
+ For the ready-made `.slidebox` class instead of a mixin:
108
+
109
+ ```scss
110
+ @use "@monabbous/slidebox/scss/slidebox";
111
+ ```
112
+
113
+ ## Less mixin
114
+
115
+ Import the mixin, then use named arguments. Create a wrapper mixin for project defaults:
116
+
117
+ ```less
118
+ @import "@monabbous/slidebox/less/slidebox.less";
119
+
120
+ .app-switch(@size: 24px; @on: #7c3aed; @duration: 250ms) {
121
+ .slidebox(@size: @size; @on: @on; @duration: @duration);
122
+ }
123
+
124
+ .toggle { .app-switch(); }
125
+ .toggle-large { .app-switch(@size: 36px); }
126
+ .toggle-wide { .slidebox(@size: 24px; @width: 2.5; @spacing: 0.25); }
127
+ ```
128
+
129
+ The import emits no CSS on its own. Use semicolons between arguments, especially when passing timing functions containing commas. Your Less bundler must resolve npm imports; with the Less CLI, add `--include-path=node_modules`.
130
+
131
+ ## Tailwind CSS
132
+
133
+ The plugin is included in the same npm package and supports Tailwind v3.4 and v4. Install Tailwind separately using its normal setup.
134
+
135
+ ### Tailwind v4
136
+
137
+ Register the plugin in your Tailwind stylesheet. The options block sets project defaults; omit it to keep Slidebox's defaults:
138
+
139
+ ```css
140
+ @import "tailwindcss";
141
+ @plugin "@monabbous/slidebox/tailwind/index.cjs" {
142
+ size: 24px;
143
+ on: #7c3aed;
144
+ duration: 250ms;
145
+ }
146
+ ```
147
+
148
+ ### Tailwind v3
149
+
150
+ Register it in `tailwind.config.cjs`:
151
+
152
+ ```js
153
+ module.exports = {
154
+ content: ["./src/**/*.{html,js,ts,jsx,tsx,vue,svelte}"],
155
+ plugins: [
156
+ require("@monabbous/slidebox/tailwind/index.cjs")({
157
+ size: "24px",
158
+ on: "#7c3aed",
159
+ duration: "250ms",
160
+ }),
161
+ ],
162
+ };
163
+ ```
164
+
165
+ ### Utilities and overrides
166
+
167
+ Add `slidebox` for the component, then control it with `slidebox-NAME-[VALUE]` utilities:
168
+
169
+ ```html
170
+ <label>
171
+ <input
172
+ type="checkbox"
173
+ class="slidebox slidebox-size-[28px] slidebox-width-[2.5] slidebox-spacing-[0.25] slidebox-deform-[0.15] slidebox-duration-[300ms] slidebox-on-violet-600 dark:slidebox-on-violet-400"
174
+ >
175
+ Enable notifications
176
+ </label>
177
+ ```
178
+
179
+ - All controls accept arbitrary values: `slidebox-track-[#222]`, `slidebox-easing-[cubic-bezier(0.4,0,0.2,1)]`, etc.
180
+ - `track`, `border`, `off`, and `on` expose your Tailwind color palette, such as `slidebox-on-emerald-500`.
181
+ - `duration` and `easing` also expose Tailwind's transition theme, such as `slidebox-duration-300` and `slidebox-easing-linear`.
182
+ - Variants work normally: `md:slidebox-size-[32px]`, `hover:slidebox-on-emerald-600`, etc.
183
+ - Use `slidebox-size-*` rather than `h-*` to resize: thumb geometry uses the switch's font size.
184
+ - Keep complete class names in source; dynamically assembled class strings may not be detected by Tailwind.
185
+
186
+ In v3, add named presets under `theme.extend.slidebox`:
187
+
188
+ ```js
189
+ theme: {
190
+ extend: {
191
+ slidebox: {
192
+ size: { compact: "18px", comfortable: "28px" },
193
+ width: { wide: "2.5" },
194
+ },
195
+ },
196
+ },
197
+ // Now use slidebox-size-compact or slidebox-width-wide.
198
+ ```
199
+
200
+ CSS custom properties work with every integration. Avoid setting a control both through plugin/mixin defaults and an inherited variable: a value assigned directly to the switch wins over inheritance. Use a utility or a selector targeting that switch to override it.
201
+
202
+ ## Development
203
+
204
+ ```sh
205
+ npm ci
206
+ npm run build
207
+ npm test
208
+ npm pack --dry-run
209
+ ```
210
+
211
+ The build extracts component rules from `style.css` and generates CSS, Sass, Less, and Tailwind rules. Tests compile both mixins and the plugin with Tailwind v3 and v4. The lab itself is plain HTML/CSS/JavaScript; serve the repository with `python3 -m http.server 8080` and open `http://localhost:8080`.
212
+
213
+ Releases use the manual [Publish to npm](.github/workflows/publish-npm.yml) workflow on `main`, with npm trusted publishing through the `production` environment. Choose a version bump for a new release, or enable `publish_existing_version` to retry the current version without a bump or new tag.
214
+
215
+ The original implementation is preserved in [`legacy/`](legacy/).
@@ -1,208 +1,58 @@
1
- @charset "UTF-8";
2
- input[type=checkbox].slidebox {
3
- -webkit-appearance: none !important;
4
- -moz-appearance: none !important;
5
- -ms-appearance: none !important;
6
- -o-appearance: none !important;
7
- appearance: none !important;
8
- height: auto;
9
- width: auto;
10
- line-height: 0px;
11
- position: relative;
12
- color: #282727;
13
- outline: 0 !important;
1
+ .slidebox {
2
+ --_container-width-ratio: var(--slidebox-width, 2);
3
+ --_thumb-spacing-ratio: var(--slidebox-spacing, .33);
4
+ --_deform: var(--slidebox-deform, .1);
5
+ --_duration: var(--slidebox-duration, 200ms);
6
+ --_easing-function: var(--slidebox-easing, ease-in-out);
7
+ --_track: var(--slidebox-track, Field);
8
+ --_border: var(--slidebox-border, ButtonBorder);
9
+ --_off: var(--slidebox-off, FieldText);
10
+ --_on: var(--slidebox-on, var(--_accent, light-dark(#0b75ff, SelectedItem)));
11
+ appearance: none;
12
+ -webkit-appearance: none;
13
+ box-sizing: border-box;
14
+ display: inline-flex;
15
+ align-items: center;
16
+ justify-content: center;
17
+ width: calc(1em * var(--_container-width-ratio));
18
+ height: 1em;
19
+ font-size: var(--slidebox-size, 54px);
20
+ padding: 0;
21
+ border: 1px solid var(--_border);
22
+ border-radius: 100vw;
23
+ background: var(--_track);
14
24
  cursor: pointer;
15
- padding: 0 0.4em;
16
- font-size: 1em;
17
- transform-origin: center center;
18
25
  }
19
- input[type=checkbox].slidebox:focus::after {
20
- outline: auto 5px -webkit-focus-ring-color;
26
+ @supports (color: AccentColor) {
27
+ .slidebox { --_accent: AccentColor; }
21
28
  }
22
- input[type=checkbox].slidebox::before {
23
- direction: ltr;
24
- position: absolute;
25
- content: "";
26
- font-weight: 900;
27
- font-family: "Font Awesome 5 Free";
29
+ .slidebox::after {
30
+ --_start: 0; --_end: 1;
31
+ content: "";
28
32
  display: block;
29
- letter-spacing: -0.8em;
30
- margin-left: 0.4em;
31
- left: 50%;
32
- top: 50%;
33
- transform-origin: center center;
34
- -webkit-transform: translate(-50%, -50%) scale(0.8);
35
- transform: translate(-50%, -50%) scale(0.8);
36
- width: 3.2em;
33
+ flex: 1 1 auto;
34
+ min-width: 0;
35
+ width: calc((1 - var(--_thumb-spacing-ratio)) * 1em);
36
+ height: calc((1 - var(--_thumb-spacing-ratio)) * 1em);
37
+ margin-block: calc(var(--_thumb-spacing-ratio) * .5em);
38
+ margin-inline-start: calc((1em * var(--_container-width-ratio) - 1em) * var(--_start) + var(--_thumb-spacing-ratio) * .5em);
39
+ margin-inline-end: calc((1em * var(--_container-width-ratio) - 1em) * var(--_end) + var(--_thumb-spacing-ratio) * .5em);
40
+ border-radius: inherit;
41
+ background: var(--_off);
42
+ transition: background var(--_duration) var(--_easing-function), margin-inline-start var(--_duration) var(--_easing-function), margin-inline-end var(--_duration) var(--_easing-function);
43
+ transition-delay: 0s, 0s, calc(var(--_duration) * var(--_deform));
44
+ }
45
+ .slidebox:checked::after {
46
+ --_start: 1; --_end: 0;
47
+ background: var(--_on);
48
+ transition-delay: 0s, calc(var(--_duration) * var(--_deform)), 0s;
49
+ }
50
+ .slidebox:not(:checked):active::after { --_end: calc(1 - var(--_deform)); }
51
+ .slidebox:checked:active::after { --_start: calc(1 - var(--_deform)); }
52
+ .slidebox:disabled { cursor: not-allowed; opacity: .5; }
53
+ @media (forced-colors: active) {
54
+ .slidebox { --_track: Field; --_border: ButtonBorder; --_off: FieldText; --_on: Highlight; }
55
+ }
56
+ @media (prefers-reduced-motion: reduce) {
57
+ .slidebox::after { transition-duration: .01ms; transition-delay: 0ms; }
37
58
  }
38
- input[type=checkbox].slidebox::after {
39
- line-height: 1em;
40
- position: relative;
41
- content: "";
42
- font-weight: 900;
43
- padding: 0.4em;
44
- font-family: "Font Awesome 5 Free";
45
- display: block;
46
- transform-origin: center center;
47
- animation-duration: 0.2s;
48
- animation-timing-function: cubic-bezier(0.68, -0.6, 0.32, 1.6);
49
- animation-fill-mode: forwards;
50
- filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.5));
51
- }
52
- input[type=checkbox].slidebox::before, input[type=checkbox].slidebox::after {
53
- transition: color 0.2s ease-in-out;
54
- }
55
- :not([dir=rtl]) input[type=checkbox].slidebox:not(.inverted)::after {
56
- animation-name: slideboxToRight;
57
- }
58
-
59
- [dir=rtl] input[type=checkbox].slidebox:not(.inverted)::after {
60
- animation-name: slideboxToLeft;
61
- }
62
-
63
- input[type=checkbox].slidebox:not(.inverted).dark::before {
64
- color: #b2b2b2;
65
- }
66
- input[type=checkbox].slidebox:not(.inverted).dark::after {
67
- color: #e6e6e6;
68
- }
69
- input[type=checkbox].slidebox:not(.inverted).dark::after {
70
- filter: brightness(130%) drop-shadow(0 0 4px rgba(0, 0, 0, 0.5));
71
- }
72
- input[type=checkbox].slidebox:not(.inverted).light::before {
73
- color: white;
74
- }
75
- input[type=checkbox].slidebox:not(.inverted).light::after {
76
- color: white;
77
- }
78
- input[type=checkbox].slidebox:not(.inverted).light::before {
79
- filter: brightness(70%);
80
- }
81
- input[type=checkbox].slidebox:not(.inverted)::before {
82
- color: #b2b2b2;
83
- }
84
- input[type=checkbox].slidebox:not(.inverted)::after {
85
- color: #e6e6e6;
86
- }
87
- input[type=checkbox].slidebox:not(.inverted)::after {
88
- filter: brightness(130%) drop-shadow(0 0 4px rgba(0, 0, 0, 0.5));
89
- }
90
- input[type=checkbox].slidebox:not(.inverted):checked::before, input[type=checkbox].slidebox:not(.inverted):checked::after {
91
- color: inherit;
92
- }
93
- :not([dir=rtl]) input[type=checkbox].slidebox:not(.inverted):checked::after {
94
- animation-name: slideboxToLeft;
95
- }
96
-
97
- [dir=rtl] input[type=checkbox].slidebox:not(.inverted):checked::after {
98
- animation-name: slideboxToRight;
99
- }
100
-
101
- :not([dir=rtl]) input[type=checkbox].slidebox:not(.inverted):active:checked::after {
102
- -webkit-transform: translateX(calc(-50% + 0.4em)) scale(1.1) !important;
103
- transform: translateX(calc(-50% + 0.4em)) scale(1.1) !important;
104
- }
105
-
106
- [dir=rtl] input[type=checkbox].slidebox:not(.inverted):active:checked::after {
107
- -webkit-transform: translateX(calc(50% - 0.4em)) scale(1.1) !important;
108
- transform: translateX(calc(50% - 0.4em)) scale(1.1) !important;
109
- }
110
-
111
- :not([dir=rtl]) input[type=checkbox].slidebox:not(.inverted):active:not(:checked)::after {
112
- -webkit-transform: translateX(calc(50% - 0.4em)) scale(1.1) !important;
113
- transform: translateX(calc(50% - 0.4em)) scale(1.1) !important;
114
- }
115
-
116
- [dir=rtl] input[type=checkbox].slidebox:not(.inverted):active:not(:checked)::after {
117
- -webkit-transform: translateX(calc(-50% + 0.4em)) scale(1.1) !important;
118
- transform: translateX(calc(-50% + 0.4em)) scale(1.1) !important;
119
- }
120
-
121
- input[type=checkbox].slidebox.inverted::before, input[type=checkbox].slidebox.inverted::after {
122
- color: inherit;
123
- }
124
- :not([dir=rtl]) input[type=checkbox].slidebox.inverted::after {
125
- animation-name: slideboxToLeft;
126
- }
127
-
128
- [dir=rtl] input[type=checkbox].slidebox.inverted::after {
129
- animation-name: slideboxToRight;
130
- }
131
-
132
- input[type=checkbox].slidebox.inverted.dark::after {
133
- filter: brightness(130%) drop-shadow(0 0 4px rgba(0, 0, 0, 0.5));
134
- }
135
- input[type=checkbox].slidebox.inverted.light::before {
136
- filter: brightness(70%);
137
- }
138
- input[type=checkbox].slidebox.inverted::after {
139
- filter: brightness(130%) drop-shadow(0 0 4px rgba(0, 0, 0, 0.5));
140
- }
141
- :not([dir=rtl]) input[type=checkbox].slidebox.inverted:checked::after {
142
- animation-name: slideboxToRight;
143
- }
144
-
145
- [dir=rtl] input[type=checkbox].slidebox.inverted:checked::after {
146
- animation-name: slideboxToLeft;
147
- }
148
-
149
- input[type=checkbox].slidebox.inverted:checked.dark::before {
150
- color: #b2b2b2;
151
- }
152
- input[type=checkbox].slidebox.inverted:checked.dark::after {
153
- color: #e6e6e6;
154
- }
155
- input[type=checkbox].slidebox.inverted:checked.light::before {
156
- color: white;
157
- }
158
- input[type=checkbox].slidebox.inverted:checked.light::after {
159
- color: white;
160
- }
161
- input[type=checkbox].slidebox.inverted:checked::before {
162
- color: #b2b2b2;
163
- }
164
- input[type=checkbox].slidebox.inverted:checked::after {
165
- color: #e6e6e6;
166
- }
167
- :not([dir=rtl]) input[type=checkbox].slidebox.inverted:active:checked::after {
168
- -webkit-transform: translateX(calc(50% - 0.4em)) scale(1.1) !important;
169
- transform: translateX(calc(50% - 0.4em)) scale(1.1) !important;
170
- }
171
-
172
- [dir=rtl] input[type=checkbox].slidebox.inverted:active:checked::after {
173
- -webkit-transform: translateX(calc(-50% + 0.4em)) scale(1.1) !important;
174
- transform: translateX(calc(-50% + 0.4em)) scale(1.1) !important;
175
- }
176
-
177
- :not([dir=rtl]) input[type=checkbox].slidebox.inverted:active:not(:checked)::after {
178
- -webkit-transform: translateX(calc(-50% + 0.4em)) scale(1.1) !important;
179
- transform: translateX(calc(-50% + 0.4em)) scale(1.1) !important;
180
- }
181
-
182
- [dir=rtl] input[type=checkbox].slidebox.inverted:active:not(:checked)::after {
183
- -webkit-transform: translateX(calc(50% - 0.4em)) scale(1.1) !important;
184
- transform: translateX(calc(50% - 0.4em)) scale(1.1) !important;
185
- }
186
-
187
- @keyframes slideboxToLeft {
188
- from {
189
- -webkit-transform: translateX(calc(50% - 0.4em));
190
- transform: translateX(calc(50% - 0.4em));
191
- }
192
- to {
193
- -webkit-transform: translateX(calc(-50% + 0.4em));
194
- transform: translateX(calc(-50% + 0.4em));
195
- }
196
- }
197
- @keyframes slideboxToRight {
198
- from {
199
- -webkit-transform: translateX(calc(-50% + 0.4em));
200
- transform: translateX(calc(-50% + 0.4em));
201
- }
202
- to {
203
- -webkit-transform: translateX(calc(50% - 0.4em));
204
- transform: translateX(calc(50% - 0.4em));
205
- }
206
- }
207
-
208
- /*# sourceMappingURL=slidebox.css.map */
@@ -0,0 +1,74 @@
1
+ // Generated by scripts/build.mjs.
2
+ .slidebox-option(@name; @value) when not (@value = false) {
3
+ --slidebox-@{name}: @value;
4
+ }
5
+ .slidebox(@width: false; @spacing: false; @deform: false; @duration: false; @easing: false; @track: false; @border: false; @off: false; @on: false; @size: false) {
6
+ .slidebox-option(width; @width);
7
+ .slidebox-option(spacing; @spacing);
8
+ .slidebox-option(deform; @deform);
9
+ .slidebox-option(duration; @duration);
10
+ .slidebox-option(easing; @easing);
11
+ .slidebox-option(track; @track);
12
+ .slidebox-option(border; @border);
13
+ .slidebox-option(off; @off);
14
+ .slidebox-option(on; @on);
15
+ .slidebox-option(size; @size);
16
+ & {
17
+ --_container-width-ratio: var(--slidebox-width, 2);
18
+ --_thumb-spacing-ratio: var(--slidebox-spacing, .33);
19
+ --_deform: var(--slidebox-deform, .1);
20
+ --_duration: var(--slidebox-duration, 200ms);
21
+ --_easing-function: var(--slidebox-easing, ease-in-out);
22
+ --_track: var(--slidebox-track, Field);
23
+ --_border: var(--slidebox-border, ButtonBorder);
24
+ --_off: var(--slidebox-off, FieldText);
25
+ --_on: var(--slidebox-on, var(--_accent, light-dark(#0b75ff, SelectedItem)));
26
+ appearance: none;
27
+ -webkit-appearance: none;
28
+ box-sizing: border-box;
29
+ display: inline-flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+ width: calc(1em * var(--_container-width-ratio));
33
+ height: 1em;
34
+ font-size: var(--slidebox-size, 54px);
35
+ padding: 0;
36
+ border: 1px solid var(--_border);
37
+ border-radius: 100vw;
38
+ background: var(--_track);
39
+ cursor: pointer;
40
+ }
41
+ @supports (color: AccentColor) {
42
+ & { --_accent: AccentColor; }
43
+ }
44
+ &::after {
45
+ --_start: 0; --_end: 1;
46
+ content: "";
47
+ display: block;
48
+ flex: 1 1 auto;
49
+ min-width: 0;
50
+ width: calc((1 - var(--_thumb-spacing-ratio)) * 1em);
51
+ height: calc((1 - var(--_thumb-spacing-ratio)) * 1em);
52
+ margin-block: calc(var(--_thumb-spacing-ratio) * .5em);
53
+ margin-inline-start: calc((1em * var(--_container-width-ratio) - 1em) * var(--_start) + var(--_thumb-spacing-ratio) * .5em);
54
+ margin-inline-end: calc((1em * var(--_container-width-ratio) - 1em) * var(--_end) + var(--_thumb-spacing-ratio) * .5em);
55
+ border-radius: inherit;
56
+ background: var(--_off);
57
+ transition: background var(--_duration) var(--_easing-function), margin-inline-start var(--_duration) var(--_easing-function), margin-inline-end var(--_duration) var(--_easing-function);
58
+ transition-delay: 0s, 0s, calc(var(--_duration) * var(--_deform));
59
+ }
60
+ &:checked::after {
61
+ --_start: 1; --_end: 0;
62
+ background: var(--_on);
63
+ transition-delay: 0s, calc(var(--_duration) * var(--_deform)), 0s;
64
+ }
65
+ &:not(:checked):active::after { --_end: calc(1 - var(--_deform)); }
66
+ &:checked:active::after { --_start: calc(1 - var(--_deform)); }
67
+ &:disabled { cursor: not-allowed; opacity: .5; }
68
+ @media (forced-colors: active) {
69
+ & { --_track: Field; --_border: ButtonBorder; --_off: FieldText; --_on: Highlight; }
70
+ }
71
+ @media (prefers-reduced-motion: reduce) {
72
+ &::after { transition-duration: .01ms; transition-delay: 0ms; }
73
+ }
74
+ }
package/package.json CHANGED
@@ -1,30 +1,57 @@
1
1
  {
2
2
  "name": "@monabbous/slidebox",
3
- "version": "0.0.7",
4
- "style": "dist/css/slidebox.css",
5
- "sass": "scss/slidebox.scss",
6
- "keywords": [
7
- "scss",
8
- "switch",
9
- "toggle",
10
- "button",
11
- "css",
12
- "simple",
13
- "style",
14
- "slidebox",
15
- "checkbox"
3
+ "version": "1.1.0",
4
+ "description": "Elastic, system-color-aware CSS checkbox switch.",
5
+ "license": "ISC",
6
+ "style": "./dist/css/slidebox.css",
7
+ "sass": "./scss/slidebox.scss",
8
+ "less": "./less/slidebox.less",
9
+ "files": [
10
+ "dist/css/slidebox.css",
11
+ "scss/",
12
+ "less/",
13
+ "tailwind/"
16
14
  ],
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "peerDependencies": {
19
+ "tailwindcss": ">=3.4.0 <5"
20
+ },
21
+ "peerDependenciesMeta": {
22
+ "tailwindcss": {
23
+ "optional": true
24
+ }
25
+ },
17
26
  "repository": {
18
27
  "type": "git",
19
- "url": "https://github.com/monabbous/slidebox.git"
28
+ "url": "git+https://github.com/monabbous/slidebox.git"
29
+ },
30
+ "homepage": "https://github.com/monabbous/slidebox#readme",
31
+ "bugs": {
32
+ "url": "https://github.com/monabbous/slidebox/issues"
20
33
  },
21
34
  "scripts": {
22
- "build": "sass scss/slidebox.scss dist/css/slidebox.css",
23
- "watch": "sass scss/slidebox.scss dist/css/slidebox.css --watch"
35
+ "build": "node scripts/build.mjs",
36
+ "test": "node --test tests/*.test.mjs",
37
+ "prepack": "npm run build"
24
38
  },
25
- "author": "Mohamed Nabous <mohamed.nabbous@gmail.com>",
26
- "license": "ISC",
39
+ "keywords": [
40
+ "slidebox",
41
+ "switch",
42
+ "toggle",
43
+ "checkbox",
44
+ "css",
45
+ "scss",
46
+ "elastic",
47
+ "system-colors"
48
+ ],
27
49
  "devDependencies": {
28
- "sass": "^1.28.0"
50
+ "@tailwindcss/node": "^4.3.3",
51
+ "less": "^4.9.1",
52
+ "postcss": "^8.5.32",
53
+ "sass": "^1.107.1",
54
+ "tailwindcss": "^3.4.19",
55
+ "tailwindcss-v4": "npm:tailwindcss@^4.3.3"
29
56
  }
30
57
  }
@@ -0,0 +1,68 @@
1
+ // Generated by scripts/build.mjs.
2
+ @use "sass:map";
3
+
4
+ $defaults: () !default;
5
+
6
+ @mixin slidebox($options: ()) {
7
+ @each $name, $value in map.merge($defaults, $options) {
8
+ --slidebox-#{$name}: #{$value};
9
+ }
10
+ & {
11
+ --_container-width-ratio: var(--slidebox-width, 2);
12
+ --_thumb-spacing-ratio: var(--slidebox-spacing, .33);
13
+ --_deform: var(--slidebox-deform, .1);
14
+ --_duration: var(--slidebox-duration, 200ms);
15
+ --_easing-function: var(--slidebox-easing, ease-in-out);
16
+ --_track: var(--slidebox-track, Field);
17
+ --_border: var(--slidebox-border, ButtonBorder);
18
+ --_off: var(--slidebox-off, FieldText);
19
+ --_on: var(--slidebox-on, var(--_accent, light-dark(#0b75ff, SelectedItem)));
20
+ appearance: none;
21
+ -webkit-appearance: none;
22
+ box-sizing: border-box;
23
+ display: inline-flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ width: calc(1em * var(--_container-width-ratio));
27
+ height: 1em;
28
+ font-size: var(--slidebox-size, 54px);
29
+ padding: 0;
30
+ border: 1px solid var(--_border);
31
+ border-radius: 100vw;
32
+ background: var(--_track);
33
+ cursor: pointer;
34
+ }
35
+ @supports (color: AccentColor) {
36
+ & { --_accent: AccentColor; }
37
+ }
38
+ &::after {
39
+ --_start: 0; --_end: 1;
40
+ content: "";
41
+ display: block;
42
+ flex: 1 1 auto;
43
+ min-width: 0;
44
+ width: calc((1 - var(--_thumb-spacing-ratio)) * 1em);
45
+ height: calc((1 - var(--_thumb-spacing-ratio)) * 1em);
46
+ margin-block: calc(var(--_thumb-spacing-ratio) * .5em);
47
+ margin-inline-start: calc((1em * var(--_container-width-ratio) - 1em) * var(--_start) + var(--_thumb-spacing-ratio) * .5em);
48
+ margin-inline-end: calc((1em * var(--_container-width-ratio) - 1em) * var(--_end) + var(--_thumb-spacing-ratio) * .5em);
49
+ border-radius: inherit;
50
+ background: var(--_off);
51
+ transition: background var(--_duration) var(--_easing-function), margin-inline-start var(--_duration) var(--_easing-function), margin-inline-end var(--_duration) var(--_easing-function);
52
+ transition-delay: 0s, 0s, calc(var(--_duration) * var(--_deform));
53
+ }
54
+ &:checked::after {
55
+ --_start: 1; --_end: 0;
56
+ background: var(--_on);
57
+ transition-delay: 0s, calc(var(--_duration) * var(--_deform)), 0s;
58
+ }
59
+ &:not(:checked):active::after { --_end: calc(1 - var(--_deform)); }
60
+ &:checked:active::after { --_start: calc(1 - var(--_deform)); }
61
+ &:disabled { cursor: not-allowed; opacity: .5; }
62
+ @media (forced-colors: active) {
63
+ & { --_track: Field; --_border: ButtonBorder; --_off: FieldText; --_on: Highlight; }
64
+ }
65
+ @media (prefers-reduced-motion: reduce) {
66
+ &::after { transition-duration: .01ms; transition-delay: 0ms; }
67
+ }
68
+ }
@@ -1,268 +1,2 @@
1
- $slideboxColorDefaultColor: #282727 !default;
2
- $slideboxClassPrefix: '' !default;
3
-
4
- $spacing: 0.8em;
5
-
6
- $slideboxShadowFilter: drop-shadow(0 0 4px rgba(black, 0.5));
7
-
8
- $isLight: lightness($slideboxColorDefaultColor) - lightness(darken($slideboxColorDefaultColor, 30%)) > 20;
9
-
10
- @mixin dark-filters() {
11
-
12
- &::after {
13
- filter: brightness(130%) $slideboxShadowFilter;
14
- }
15
- }
16
-
17
- @mixin dark-colors() {
18
- &::before {
19
- color: lighten(grey, 19.5%);
20
- }
21
-
22
- &::after {
23
- color: lighten(grey, 40%);
24
- }
25
- }
26
-
27
- @mixin light-filters() {
28
- &::before {
29
- filter: brightness(70%);
30
- }
31
- }
32
-
33
- @mixin light-colors() {
34
- &::before {
35
- color: lighten(grey, 50%);
36
- }
37
-
38
- &::after {
39
- color: lighten(grey, 70%);
40
- }
41
- }
42
-
43
- @mixin slideboxRight($extraTransform: null) {
44
- -webkit-transform: translateX(calc(50% - #{$spacing / 2})) $extraTransform;
45
- transform: translateX(calc(50% - #{$spacing / 2})) $extraTransform;
46
- }
47
-
48
-
49
- @mixin slideboxLeft($extraTransform: null) {
50
- -webkit-transform: translateX(calc(-50% + #{$spacing / 2})) $extraTransform;
51
- transform: translateX(calc(-50% + #{$spacing / 2})) $extraTransform;
52
- }
53
-
54
-
55
- @mixin slideboxStart($extraTransform: null) {
56
- @at-root :not([dir=rtl]) & {
57
- @include slideboxLeft($extraTransform);
58
- }
59
- @at-root [dir=rtl] & {
60
- @include slideboxRight($extraTransform);
61
- }
62
- }
63
-
64
- @mixin slideboxEnd($extraTransform: null) {
65
- @at-root :not([dir=rtl]) & {
66
- @include slideboxRight($extraTransform);
67
- }
68
- @at-root [dir=rtl] & {
69
- @include slideboxLeft($extraTransform);
70
- }
71
- }
72
-
73
-
74
-
75
- @mixin slideboxToStartAnimation() {
76
- @at-root :not([dir=rtl]) & {
77
- animation-name: slideboxToLeft;
78
- }
79
- @at-root [dir=rtl] & {
80
- animation-name: slideboxToRight;
81
- }
82
- }
83
-
84
- @mixin slideboxToEndAnimation() {
85
- @at-root :not([dir=rtl]) & {
86
- animation-name: slideboxToRight;
87
- }
88
- @at-root [dir=rtl] & {
89
- animation-name: slideboxToLeft;
90
- }
91
- }
92
-
93
- input[type=checkbox].#{$slideboxClassPrefix}slidebox {
94
- -webkit-appearance: none !important;
95
- -moz-appearance: none !important;
96
- -ms-appearance: none !important;
97
- -o-appearance: none !important;
98
- appearance: none !important;
99
- height: auto;
100
- width: auto;
101
- line-height: 0px;
102
- position: relative;
103
- color: $slideboxColorDefaultColor;
104
- outline: 0 !important;
105
- cursor: pointer;
106
- padding: 0 #{$spacing / 2};
107
- font-size: 1em;
108
- transform-origin: center center;
109
-
110
- &:focus::after {
111
- outline: auto 5px -webkit-focus-ring-color;
112
- }
113
-
114
- &::before {
115
- direction: ltr;
116
- position: absolute;
117
- content: '\f111\f111\f111\f111\f111\f111\f111';
118
- font-weight: 900;
119
- font-family: 'Font Awesome 5 Free';
120
- display: block;
121
- letter-spacing: -$spacing;
122
- margin-left: $spacing * 0.5;
123
- left: 50%;
124
- top: 50%;
125
- transform-origin: center center;
126
- -webkit-transform: translate(-50%, -50%) scale(0.8);
127
- transform: translate(-50%, -50%) scale(0.8);
128
- width: #{$spacing * 4};
129
- }
130
-
131
- &::after {
132
- line-height: 1em;
133
- position: relative;
134
- content: '\f111';
135
- font-weight: 900;
136
- padding: #{$spacing / 2};
137
- font-family: 'Font Awesome 5 Free';
138
- display: block;
139
- transform-origin: center center;
140
- animation-duration: 0.2s;
141
- animation-timing-function: cubic-bezier(0.68, -0.6, 0.32, 1.6);
142
- animation-fill-mode: forwards;
143
- filter: $slideboxShadowFilter;
144
- }
145
-
146
- &::before, &::after {
147
- transition: color 0.2s ease-in-out;
148
- }
149
-
150
- &:not(.inverted) {
151
- &::after {
152
- @include slideboxToEndAnimation;
153
- }
154
-
155
- &.dark {
156
- @include dark-colors;
157
- @include dark-filters;
158
- }
159
-
160
- &.light {
161
- @include light-colors;
162
- @include light-filters;
163
- }
164
-
165
- @if ($isLight) {
166
- @include light-colors;
167
- @include light-filters;
168
- } @else {
169
- @include dark-colors;
170
- @include dark-filters;
171
- }
172
-
173
- &:checked {
174
- &::before, &::after {
175
- color: inherit;
176
- }
177
-
178
- &::after {
179
- @include slideboxToStartAnimation;
180
- }
181
- }
182
-
183
- &:active {
184
- &:checked::after {
185
- @include slideboxStart(scale(1.1) !important);
186
- }
187
-
188
- &:not(:checked)::after {
189
- @include slideboxEnd(scale(1.1) !important);
190
- }
191
- }
192
- }
193
-
194
-
195
- &.inverted {
196
- &::before, &::after {
197
- color: inherit;
198
- }
199
-
200
- &::after {
201
- @include slideboxToStartAnimation;
202
- }
203
-
204
- &.dark {
205
- @include dark-filters;
206
- }
207
-
208
- &.light {
209
- @include light-filters;
210
- }
211
-
212
- @if ($isLight) {
213
- @include light-filters;
214
- } @else {
215
- @include dark-filters;
216
- }
217
-
218
- &:checked {
219
- &::after {
220
- @include slideboxToEndAnimation;
221
- }
222
-
223
- &.dark {
224
- @include dark-colors;
225
- }
226
-
227
- &.light {
228
- @include light-colors;
229
- }
230
-
231
- @if ($isLight) {
232
- @include light-colors;
233
- } @else {
234
- @include dark-colors;
235
- }
236
-
237
- }
238
-
239
- &:active {
240
- &:checked::after {
241
- @include slideboxEnd(scale(1.1) !important);
242
- }
243
-
244
- &:not(:checked)::after {
245
- @include slideboxStart(scale(1.1) !important);
246
- }
247
- }
248
- }
249
-
250
- }
251
-
252
- @keyframes slideboxToLeft {
253
- from {
254
- @include slideboxRight;
255
- }
256
- to {
257
- @include slideboxLeft;
258
- }
259
- }
260
-
261
- @keyframes slideboxToRight {
262
- from {
263
- @include slideboxLeft;
264
- }
265
- to {
266
- @include slideboxRight;
267
- }
268
- }
1
+ @use "mixins";
2
+ .slidebox { @include mixins.slidebox(); }
@@ -0,0 +1,28 @@
1
+ const plugin = require("tailwindcss/plugin");
2
+ const rules = require("./rules.json");
3
+
4
+ function flatten(colors, prefix = "") {
5
+ return Object.fromEntries(Object.entries(colors).flatMap(([key, value]) => {
6
+ const name = key === "DEFAULT" ? prefix : [prefix, key].filter(Boolean).join("-");
7
+ return typeof value === "object" && value !== null
8
+ ? Object.entries(flatten(value, name)) : [[name, value]];
9
+ }));
10
+ }
11
+
12
+ module.exports = plugin.withOptions((defaults = {}) => ({ addUtilities, matchUtilities, theme }) => {
13
+ const controls = ["size", "width", "spacing", "deform", "duration", "easing", "track", "border", "off", "on"];
14
+ for (const key of Object.keys(defaults)) {
15
+ if (!controls.includes(key)) throw new Error(`Unknown Slidebox control: ${key}`);
16
+ }
17
+ addUtilities({ ".slidebox": {
18
+ ...Object.fromEntries(Object.entries(defaults).map(([key, value]) => [`--slidebox-${key}`, String(value)])),
19
+ ...rules,
20
+ } });
21
+ for (const key of controls) {
22
+ let values = theme(`slidebox.${key}`, {});
23
+ if (["track", "border", "off", "on"].includes(key)) values = { ...flatten(theme("colors", {})), ...values };
24
+ if (key === "duration") values = { ...theme("transitionDuration", {}), ...values };
25
+ if (key === "easing") values = { ...theme("transitionTimingFunction", {}), ...values };
26
+ matchUtilities({ [`slidebox-${key}`]: value => ({ [`--slidebox-${key}`]: value }) }, { values });
27
+ }
28
+ });
@@ -0,0 +1,77 @@
1
+ {
2
+ "--_container-width-ratio": "var(--slidebox-width, 2)",
3
+ "--_thumb-spacing-ratio": "var(--slidebox-spacing, .33)",
4
+ "--_deform": "var(--slidebox-deform, .1)",
5
+ "--_duration": "var(--slidebox-duration, 200ms)",
6
+ "--_easing-function": "var(--slidebox-easing, ease-in-out)",
7
+ "--_track": "var(--slidebox-track, Field)",
8
+ "--_border": "var(--slidebox-border, ButtonBorder)",
9
+ "--_off": "var(--slidebox-off, FieldText)",
10
+ "--_on": "var(--slidebox-on, var(--_accent, light-dark(#0b75ff, SelectedItem)))",
11
+ "appearance": "none",
12
+ "-webkit-appearance": "none",
13
+ "box-sizing": "border-box",
14
+ "display": "inline-flex",
15
+ "align-items": "center",
16
+ "justify-content": "center",
17
+ "width": "calc(1em * var(--_container-width-ratio))",
18
+ "height": "1em",
19
+ "font-size": "var(--slidebox-size, 54px)",
20
+ "padding": "0",
21
+ "border": "1px solid var(--_border)",
22
+ "border-radius": "100vw",
23
+ "background": "var(--_track)",
24
+ "cursor": "pointer",
25
+ "@supports (color: AccentColor)": {
26
+ "&": {
27
+ "--_accent": "AccentColor"
28
+ }
29
+ },
30
+ "&::after": {
31
+ "--_start": "0",
32
+ "--_end": "1",
33
+ "content": "\"\"",
34
+ "display": "block",
35
+ "flex": "1 1 auto",
36
+ "min-width": "0",
37
+ "width": "calc((1 - var(--_thumb-spacing-ratio)) * 1em)",
38
+ "height": "calc((1 - var(--_thumb-spacing-ratio)) * 1em)",
39
+ "margin-block": "calc(var(--_thumb-spacing-ratio) * .5em)",
40
+ "margin-inline-start": "calc((1em * var(--_container-width-ratio) - 1em) * var(--_start) + var(--_thumb-spacing-ratio) * .5em)",
41
+ "margin-inline-end": "calc((1em * var(--_container-width-ratio) - 1em) * var(--_end) + var(--_thumb-spacing-ratio) * .5em)",
42
+ "border-radius": "inherit",
43
+ "background": "var(--_off)",
44
+ "transition": "background var(--_duration) var(--_easing-function), margin-inline-start var(--_duration) var(--_easing-function), margin-inline-end var(--_duration) var(--_easing-function)",
45
+ "transition-delay": "0s, 0s, calc(var(--_duration) * var(--_deform))"
46
+ },
47
+ "&:checked::after": {
48
+ "--_start": "1",
49
+ "--_end": "0",
50
+ "background": "var(--_on)",
51
+ "transition-delay": "0s, calc(var(--_duration) * var(--_deform)), 0s"
52
+ },
53
+ "&:not(:checked):active::after": {
54
+ "--_end": "calc(1 - var(--_deform))"
55
+ },
56
+ "&:checked:active::after": {
57
+ "--_start": "calc(1 - var(--_deform))"
58
+ },
59
+ "&:disabled": {
60
+ "cursor": "not-allowed",
61
+ "opacity": ".5"
62
+ },
63
+ "@media (forced-colors: active)": {
64
+ "&": {
65
+ "--_track": "Field",
66
+ "--_border": "ButtonBorder",
67
+ "--_off": "FieldText",
68
+ "--_on": "Highlight"
69
+ }
70
+ },
71
+ "@media (prefers-reduced-motion: reduce)": {
72
+ "&::after": {
73
+ "transition-duration": ".01ms",
74
+ "transition-delay": "0ms"
75
+ }
76
+ }
77
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sourceRoot":"","sources":["../../scss/slidebox.scss"],"names":[],"mappings":";AA4FA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OAtG0B;EAuG1B;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,QAzImB;;AA4IrB;EACE;;AA9DO;EACP;;;AAEO;EACP;;;AAvEF;EACE;;AAGF;EACE;;AAXF;EACE;;AAqBF;EACE;;AAGF;EACE;;AAXF;EACE;;AAXF;EACE;;AAGF;EACE;;AAXF;EACE;;AAiKE;EACE;;AAnGG;EACP;;;AAEO;EACP;;;AAxBO;EANT;EACA;;;AAQS;EAfT;EACA;;;AAoBS;EArBT;EACA;;;AAuBS;EAlBT;EACA;;;AAiJE;EACE;;AAzHK;EACP;;;AAEO;EACP;;;AApEF;EACE;;AAeF;EACE;;AAjBF;EACE;;AAwEO;EACP;;;AAEO;EACP;;;AAvEF;EACE;;AAGF;EACE;;AAWF;EACE;;AAGF;EACE;;AArBF;EACE;;AAGF;EACE;;AA0CO;EArBT;EACA;;;AAuBS;EAlBT;EACA;;;AAKS;EANT;EACA;;;AAQS;EAfT;EACA;;;AA+MF;EACE;IAjNA;IACA;;EAmNA;IA9MA;IACA;;;AAkNF;EACE;IApNA;IACA;;EAsNA;IA7NA;IACA","file":"slidebox.css"}
@@ -1,41 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport"
6
- content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
7
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
8
- <title>@monabbous/slidebox Simple Example</title>
9
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"
10
- integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA=="
11
- crossorigin="anonymous"/>
12
- <link rel="stylesheet" href="https://unpkg.com/@monabbous/slidebox@0.0.7/dist/css/slidebox.css"/>
13
- <style>
14
- body {
15
- font-family: "Source Code Pro", "SF Mono", Monaco, Inconsolata, "Fira Mono", "Droid Sans Mono", monospace, monospace;
16
- }
17
- </style>
18
- </head>
19
- <body>
20
- <h2>Default Slidebox</h2>
21
- <div style="font-size: 2rem">
22
- <input type="checkbox" class="slidebox">
23
- <input type="checkbox" checked class="slidebox">
24
- </div>
25
- <h2>Custom Dark Color Slidebox</h2>
26
- <div style="font-size: 2rem">
27
- <input style="color:#040491" type="checkbox" class="slidebox dark">
28
- <input style="color:#040491" type="checkbox" checked class="slidebox dark">
29
- </div>
30
- <h2>Custom Light Color Slidebox</h2>
31
- <div style="font-size: 2rem">
32
- <input style="color:#a8a8ff" type="checkbox" class="slidebox light">
33
- <input style="color:#a8a8ff" type="checkbox" checked class="slidebox light">
34
- </div>
35
- <h2>Inverted Slidebox</h2>
36
- <div style="font-size: 2rem">
37
- <input type="checkbox" class="slidebox inverted">
38
- <input type="checkbox" checked class="slidebox inverted">
39
- </div>
40
- </body>
41
- </html>