Skip to content

Commit

Permalink
merge(11): inject css into head; no css file
Browse files Browse the repository at this point in the history
feat: inline css
  • Loading branch information
vladdeSV authored Jul 19, 2024
2 parents 5af0e5e + 772dfb1 commit e82e710
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 26 deletions.
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"trailingComma": "es5",
"tabWidth": 4,
"semi": false,
"singleQuote": true,
"printWidth": 99999,
"arrowParens": "avoid"
}
3 changes: 3 additions & 0 deletions .zed/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"tab_size": 4
}
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@
If your web application has a million (or just a couple) checkboxes aligned neatly, then this is for you. Easy to integrate with minimal added lines of code.

Simply “click-and-drag” over checkboxes to enable or disable them in a flash. [Try it now](https://vladdesv.github.io/checkswipe/) and transform your web forms with unparalleled speed and simplicity!
```html
<script src=/js/checkswipe.js defer onload=checkswipe()></script>
```

Simply “click-and-drag” over specified checkboxes to enable or disable them in a flash. [Try it now](https://vladdesv.github.io/checkswipe/) and transform your web forms with unparalleled speed and simplicity!

```html
<div data-checkswipe>
<input type="checkbox" />
<input type="checkbox" />
</div>
```

> [!NOTE]
> Does not support touchscreens. Sorry!
66 changes: 48 additions & 18 deletions checkswipe.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
/**
* @param {HTMLElement} [parent]
* @param {HTMLInputElement} [checkbox]
*/
function checkswipe(parent, checkbox) {

function checkswipe() {
/**
* @param {HTMLInputElement} checkbox
* @param {HTMLElement} parent
Expand All @@ -15,7 +10,7 @@ function checkswipe(parent, checkbox) {
}

if (parent.parentElement?.closest('[data-checkswipe]') || parent.querySelector('[data-checkswipe]')) {
console.error('checkswipe: invalid structure for', parent,'; nested `data-checkswipe` elements are not allowed.')
console.error('checkswipe: invalid structure for', parent, '; nested `data-checkswipe` elements are not allowed.')
return
}

Expand Down Expand Up @@ -75,7 +70,7 @@ function checkswipe(parent, checkbox) {
}
})

checkbox.addEventListener('click', (event) => {
checkbox.addEventListener('click', event => {
if (event instanceof MouseEvent && event.detail > 0) {
event.preventDefault()
}
Expand All @@ -92,7 +87,7 @@ function checkswipe(parent, checkbox) {
}

if (group.parentElement?.closest('[data-checkswipe]') || group.querySelector('[data-checkswipe]')) {
console.error('checkswipe: invalid structure for', group,'; nested `data-checkswipe` elements are not allowed.')
console.error('checkswipe: invalid structure for', group, '; nested `data-checkswipe` elements are not allowed.')
return
}

Expand All @@ -106,15 +101,50 @@ function checkswipe(parent, checkbox) {
checkboxes.forEach(checkbox => attachSingle(checkbox, group))
}

if (!parent && !checkbox) {
const groups = document.querySelectorAll('[data-checkswipe]')
groups.forEach(group => attachGroup(group))
} else if (parent && !checkbox) {
attachGroup(parent)
} else if (parent && checkbox) {
attachSingle(checkbox, parent)
} else {
console.error('checkswipe: parameter `parent` cannot be missing if `checkbox` is provided.')
if (typeof checkswipe.inject === 'function') {
checkswipe.inject()
}

const groups = document.querySelectorAll('[data-checkswipe]')
groups.forEach(group => attachGroup(group))

checkswipe.on = attachGroup
}

checkswipe.inject = function (nonce) {
// nuclear option >:)
checkswipe.inject = undefined

if (document.querySelector('head>style#checkswipe-injected')) {
console.warn('checkswipe: injected styles already exists, skipping injection of style...')
return
}

let style = document.createElement('style')
style.id = 'checkswipe-injected'
if (typeof nonce === 'string') {
style.setAttribute('nonce', nonce)
}

style.textContent = `
:root {
/* checkswipe defaults */
--checkswipe-scale: 1.3;
--checkswipe-delay: 0.1s;
--checkswipe-duration: 0.1s;
--checkswipe-easing: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
[data-checkswipe]:not([data-checkswipe-specify]) input[type=checkbox],
[data-checkswipe][data-checkswipe-specify] input[type=checkbox][data-checkswipe-use] {
transition: transform var(--checkswipe-duration) var(--checkswipe-easing) var(--checkswipe-delay);
}
[data-checkswipe]:not([data-checkswipe='']):not([data-checkswipe-specify]) input[type=checkbox],
[data-checkswipe][data-checkswipe-specify]:not([data-checkswipe='']) input[type=checkbox][data-checkswipe-use] {
transform: scale(var(--checkswipe-scale));
}
`

document.head.appendChild(style)
}
20 changes: 13 additions & 7 deletions website/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

<!-- only things related to checkswipe -->
<script defer src=checkswipe.js onload=checkswipe()></script>
<link rel=stylesheet href=checkswipe.css>
</head>

<body>
Expand All @@ -34,7 +33,7 @@
</svg>
</aside>
<hgroup>
<h1>Checkswipe.js <code class=version>v2.1</code></h1>
<h1>Checkswipe.js <code class=version>v3.0</code></h1>
<p><i>"Click-and-drag" over HTML checkboxes</i></p>
</hgroup>
</header>
Expand All @@ -60,8 +59,8 @@ <h2>Try it</h2>
</form>

<h2>Get it</h2>
<p>Import the library with these two lines:</p>
<pre><code>&lt;<span class=kw>script</span> <span class=attr>defer</span> <span class=attr>src</span>=<span class=v>/js/checkswipe.js</span> <span class=attr>onload</span>=<span class=fn>checkswipe</span>()&gt;&lt;/<span class=kw>script</span>&gt;<br>&lt;<span class=kw>link</span> <span class=attr>rel</span>=<span class=v>stylesheet</span> <span class=attr>href</span>=<span class=v>/css/checkswipe.css</span>&gt;</code></pre>
<p>Import the library with this line of code:</p>
<pre><code>&lt;<span class=kw>script</span> <span class=attr>src</span>=<span class=v>/js/checkswipe.js</span> <span class=attr>defer</span> <span class=attr>onload</span>=<span class=fn>checkswipe</span>()&gt;&lt;/<span class=kw>script</span>&gt;</code></pre>
<p>Add the attribute <code><span class=attr>data-checkswipe</span></code> to any group.</p>
<pre><code>&lt;<span class=kw>fieldset</span> <mark><span class=attr>data-checkswipe</span></mark>&gt;<br> &lt;<span class=kw>input</span> <span class=attr>type</span>=<span class=v>checkbox</span>&gt;<br> &lt;<span class=kw>input</span> <span class=attr>type</span>=<span class=v>checkbox</span>&gt;<br>&lt;/<span class=kw>fieldset</span>&gt;</code></pre>
<p>See the <a href=https://github.com/vladdeSV/checkswipe/releases/latest>latest release</a> and the <a href=https://github.com/vladdeSV/checkswipe>source code</a> on GitHub.</p>
Expand Down Expand Up @@ -132,10 +131,17 @@ <h2>Use it</h2>
</ol>

<aside>
<p>Checkswipe can be manually applied to any element, or specific checkboxes:</p>
<pre><code><span class=fn>checkswipe</span>() <span class=comment>// all <span class=attr>[data-checkswipe]</span> on page</span><br><span class=fn>checkswipe</span>(group) <span class=comment>// eg. checkswipe(myDiv)</span><br><span class=fn>checkswipe</span>(group, checkbox) <span class=comment>// eg. checkswipe(myDiv, checkbox)</span></code></pre>
<p>Checkswipe.js can be manually applied to any element:</p>
<pre><code>checkswipe.<span class=fn>on</span>(group) <span class=comment>// eg. checkswipe.on(myDiv)</span></code></pre>
</aside>

<h3>Content Security Policy</h3>
<p>Checkswipe.js initally injects a <code>&lt;<span class=kw>style</span> <span class=attr>id</span>=<span class=v>checkswipe-injected</span>&gt;</code> into the document's <code>&lt;<span class=kw>head</span>&gt;</code> for animations. If your website has a restrictive <abbr title="content security policy">CSP</abbr>, you can either:</p>
<ol style="list-style: lower-alpha;">
<li>manually inject the styles with the nonce before running the function <pre><code>&lt;<span class=kw>script</span><span class=attr>onload</span>=<span class=v>'</span><span>checkswipe</span>.<span class=fn>inject</span>(<span class=v>"mynonce"</span>);<span class=fn>checkswipe</span>()<span class=v>'</span>></code></pre></li>
<li>manually copy-and-paste the styling and put it your own CSS files, and remove the injection method <pre><code>&lt;<span class=kw>script</span><span class=attr>onload</span>=<span class=v>'</span><span>checkswipe</span>.<span class=p>inject</span>=<span class=n>undefined</span>;<span class=fn>checkswipe</span>()<span class=v>'</span>></code></pre></li>
</ol>

<h2>Love it?</h2>
<p>If this little project made you smile, send me a virtual coffee – it boosts my ego.</p>
<p><a href=https://www.buymeacoffee.com/vladde><img src=buymeacoffee.png alt='Buy Me A Coffee' width=217 height=60></a></p>
Expand All @@ -144,7 +150,7 @@ <h2>How it works</h2>
<p><code><span class=fn>checkswipe</span>()</code> looks for every <code>&lt;<span class=kw><i>element</i></span>&gt;</code> with the attribute <code><span class=attr>data-checkswipe</span></code>, and attaches a listener to each checkbox inside.</p>
<p>Each <code>&lt;<span class=kw><i>element</i></span>&gt;</code> is independent, and only checkboxes within them can be swiped.</p>
<p>Intentionally only activates when pressing and dragging over checkboxes – does not affect labels and their text.</p>
<p>Checkboxes growing larger is pure and simple <abbr title='cascading style sheets'>CSS</abbr>, and is not required – but recommended.</p>
<p>Checkboxes growing larger is pure and simple CSS, and is not required – but recommended.</p>
<p>Very self-contained. Only the group and its checkboxes within are affected. At worst, on a <code>mousedown</code> event, a temporary self-removing <code>mouseup</code> handler is applied to the page to detect when the user releases the mouse button.</p>
<p>Note: Each <code>&lt;<span class=kw>input</span> <span class=attr>type</span>=<span class=v>checkbox</span>&gt;</code> gets event listeners – adding or replacing checkboxes requires to re-run code for those checkboxes.</p>

Expand Down
12 changes: 12 additions & 0 deletions website/the.style.css
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,24 @@ code {
& .v {
color: #00a66e;
}

& .p {
color: #59c1ff;
}

& .n {
color: #d2a6ff
}

& .comment {
color: #767676;
}
}

hgroup > :is(h1, p) {
margin: 0;
}

/* logo animation */
#logo-demo {
position: relative;
Expand Down

0 comments on commit e82e710

Please sign in to comment.