Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 3 additions & 39 deletions app/components/Settings/Toggle.client.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,51 +54,15 @@ const id = useId()
{{ label }}
</span>
<input
role="switch"
switch
type="checkbox"
:id="id"
v-model="checked"
class="toggle appearance-none h-6 w-11 rounded-full border border-fg relative shrink-0 bg-fg/50 transition-colors duration-200 ease-in-out checked:bg-fg [@media(hover:hover)]:hover:bg-fg/60 [@media(hover:hover)]:checked:hover:(bg-fg/80 after:opacity-50) focus-visible:(outline-2 outline-accent outline-offset-2) before:(content-[''] absolute h-5 w-5 top-px start-px rounded-full bg-bg transition-transform duration-200 ease-in-out) checked:before:translate-x-[20px] rtl:checked:before:-translate-x-[20px] after:(content-[''] absolute h-3.5 w-3.5 top-[4px] start-[4px] i-lucide:check bg-fg opacity-0 transition-all duration-200 ease-in-out) checked:after:opacity-100 checked:after:translate-x-[20px] rtl:checked:after:-translate-x-[20px]"
style="grid-area: toggle; justify-self: end"
class="shrink-0 focus-visible:(outline-2 outline-accent outline-offset-2)"
style="grid-area: toggle; justify-self: end; accent-color: var(--accent)"
/>
</label>
<p v-if="description" class="text-sm text-fg-muted mt-2">
{{ description }}
</p>
</template>

<style scoped>
/* Support forced colors */
@media (forced-colors: active) {
.toggle {
background: Canvas;
border-color: CanvasText;
}

.toggle:checked {
background: Highlight;
border-color: CanvasText;
}

.toggle::before {
background-color: CanvasText;
}

.toggle:checked::before {
background-color: Canvas;
}

.toggle::after {
background-color: Highlight;
}
}

@media (prefers-reduced-motion: reduce) {
.toggle,
.toggle::before,
.toggle::after {
transition: none !important;
animation: none !important;
}
}
</style>
26 changes: 26 additions & 0 deletions app/plugins/input-switch-polyfill.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export default defineNuxtPlugin(async () => {
if (!('switch' in HTMLInputElement.prototype)) {
// @ts-expect-error input-switch-polyfill ships no types; imported for its side effect only
await import('input-switch-polyfill')

// The polyfill reads `accent-color` once at upgrade time and freezes the
// resolved color as `--switch-accent` in each element's inline style.
// Re-sync whenever the accent or color-mode changes so switches react live.
const syncSwitchAccent = () => {

Check warning on line 9 in app/plugins/input-switch-polyfill.client.ts

View workflow job for this annotation

GitHub Actions / 🤖 Autofix code

eslint-plugin-unicorn(consistent-function-scoping)

Function `syncSwitchAccent` does not capture any variables from its parent scope

Check warning on line 9 in app/plugins/input-switch-polyfill.client.ts

View workflow job for this annotation

GitHub Actions / 🔠 Lint project

eslint-plugin-unicorn(consistent-function-scoping)

Function `syncSwitchAccent` does not capture any variables from its parent scope
const switches = document.querySelectorAll<HTMLInputElement>('input.switch')
const [first] = switches
if (!first) return
// All switches share the same cascade; read from the first one.
const color = getComputedStyle(first).getPropertyValue('accent-color').trim()
if (!color || color === 'auto') return
for (const el of switches) {
el.style.setProperty('--switch-accent', color)
}
}

new MutationObserver(syncSwitchAccent).observe(document.documentElement, {
attributes: true,
attributeFilter: ['style', 'class'],
})
Comment on lines +9 to +24

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does the input-switch-polyfill npm package automatically detect and upgrade input[switch] elements added to the DOM after initial load, or only elements present at import time?

💡 Result:

The input-switch-polyfill package does not appear to automatically detect and upgrade input[switch] elements added to the DOM after the initial page load [1][2]. The polyfill is designed to progressively enhance existing checkbox elements that utilize the switch attribute [1][3]. It functions by applying styles and managing accessibility roles for elements present when the polyfill is initialized [3][2]. Documentation and implementation patterns for the package focus on initial conditional loading to prevent a Flash of Unstyled Content (FOUC), rather than observing dynamic DOM mutations [1][2]. There is no evidence in the project's documentation or source code structure of a MutationObserver or similar mechanism to monitor for dynamically injected elements [2][4][5][6][7][8].

Citations:


Re-sync on mount: syncSwitchAccent() only runs on html style/class mutations, so switches mounted later can miss --switch-accent until an unrelated mutation occurs. Call it once after import, or watch childList changes too.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/plugins/input-switch-polyfill.client.ts` around lines 9 - 24, The
syncSwitchAccent logic only runs on html style/class mutations, so newly mounted
input.switch elements can miss --switch-accent until something else changes.
Update the input-switch-polyfill.client.ts plugin so syncSwitchAccent is invoked
once immediately after setup (on import/mount) and/or extend the
MutationObserver on document.documentElement to also watch childList changes so
late-added switches are resynced.

}
})
2 changes: 1 addition & 1 deletion nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default defineNuxtConfig({
storageKey: 'npmx-color-mode',
},

css: ['~/assets/main.css'],
css: ['~/assets/main.css', 'input-switch-polyfill/input-switch-polyfill.css'],

runtimeConfig: {
sessionPassword: '',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"focus-trap": "^8.0.0",
"gray-matter": "4.0.3",
"hls.js": "1.6.16",
"input-switch-polyfill": "1.12.0",
"ipaddr.js": "2.3.0",
"marked": "18.0.0",
"module-replacements": "3.0.0",
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading