Переглянути джерело

feat: improve toggle button layout and responsiveness

Sv443 1 рік тому
батько
коміт
ee70c17e8b
4 змінених файлів з 54 додано та 43 видалено
  1. 2 0
      .gitignore
  2. 31 31
      src/components/toggle.css
  3. 15 6
      src/components/toggle.ts
  4. 6 6
      src/tools/post-build.ts

+ 2 - 0
.gitignore

@@ -1,6 +1,8 @@
 .env
 test.js
 test.ts
+test.html
+test.css
 
 node_modules/
 dist/*.map

+ 31 - 31
src/components/toggle.css

@@ -1,8 +1,12 @@
+/* #MARKER toggle */
+
 .bytm-toggle-wrapper {
   --toggle-height: 24px;
   --toggle-width: 48px;
+  --toggle-knob-offset: 4px;
   --toggle-color-on: var(--bytm-dialog-accent-col, #4595c7);
   --toggle-color-off: #707070;
+  --toggle-knob-color: #f5f5f5;
 
   display: flex;
   align-items: center;
@@ -11,55 +15,51 @@
 .bytm-toggle-wrapper .bytm-toggle-label {
   cursor: pointer;
   font-size: 1.5rem;
-  padding: 5px 10px;
+  padding: 3px 12px;
 }
 
 /* sauce: https://danklammer.com/articles/simple-css-toggle-switch/ */
 
 .bytm-toggle {
+  display: flex;
+  align-items: center;
+}
+
+.bytm-toggle input {
   appearance: none;
+  display: inline-block;
   width: var(--toggle-width);
   height: var(--toggle-height);
-  display: inline-block;
   position: relative;
   border-radius: 50px;
-  margin: 0px;
   overflow: hidden;
   outline: none;
   border: none;
+  margin: 0;
+  padding: var(--toggle-knob-offset);
   cursor: pointer;
   background-color: var(--toggle-color-off);
-  transition: background-color ease 0.2s;
+  transition: justify-content 0.2s ease, background-color 0.2s ease;
 }
 
-.bytm-toggle:before {
-  content: " ";
-  cursor: pointer;
-  display: block;
-  position: absolute;
-  z-index: 2;
-  width: calc(var(--toggle-height) - 4px);
-  height: calc(var(--toggle-height) - 4px);
-  background: #fff;
-  border-radius: 50%;
-  font: 10px/28px Helvetica;
-  text-transform: uppercase;
-  font-weight: bold;
-  text-indent: -22px;
-  word-spacing: 37px;
-  color: #fff;
-  left: 2px;
-  top: 2px;
-  text-shadow: -1px -1px rgba(0,0,0,0.15);
-  white-space: nowrap;
-  box-shadow: 0 1px 2px rgba(0,0,0,0.2);
-  transition: all ease 0.2s;
-}
-
-.bytm-toggle:checked {
+.bytm-toggle input[data-toggled="true"] {
   background-color: var(--toggle-color-on);
 }
 
-.bytm-toggle:checked:before {
-  left: calc(var(--toggle-width) - 22px);
+.bytm-toggle input .bytm-toggle-knob {
+  --toggle-knob-calc-width: calc(var(--toggle-height) - (var(--toggle-knob-offset) * 2));
+  --toggle-knob-calc-height: calc(var(--toggle-height) - (var(--toggle-knob-offset) * 2));
+  width: var(--toggle-knob-calc-width);
+  height: var(--toggle-knob-calc-height);
+  background-color: var(--toggle-knob-color);
+  border-radius: 50%;
+  position: absolute;
+  top: 50%;
+  transform: translateY(-50%);
+  left: var(--toggle-knob-offset);
+  transition: left 0.2s ease;
 }
+
+.bytm-toggle input[data-toggled="true"] .bytm-toggle-knob {
+  left: calc(var(--toggle-width) - var(--toggle-knob-offset) - var(--toggle-knob-calc-width));
+}

+ 15 - 6
src/components/toggle.ts

@@ -17,14 +17,13 @@ export interface ToggleProps {
 export async function createToggle({
   onChange,
   initialValue = false,
-  id = randomId(8, 24),
+  id = randomId(8, 26),
   labelPos = "left",
 }: ToggleProps) {
   const wrapperEl = document.createElement("div");
   wrapperEl.classList.add("bytm-toggle-wrapper", "bytm-no-select");
   wrapperEl.role = "switch";
   wrapperEl.tabIndex = 0;
-  wrapperEl.ariaValueText = t(`toggled_${initialValue ? "on" : "off"}`);
 
   const labelEl = labelPos !== "off" && document.createElement("label");
   if(labelEl) {
@@ -34,21 +33,28 @@ export async function createToggle({
       labelEl.htmlFor = `bytm-toggle-${id}`;
   }
 
+  const toggleWrapperEl = document.createElement("div");
+  toggleWrapperEl.classList.add("bytm-toggle");
+  toggleWrapperEl.tabIndex = -1;
+
   const toggleEl = document.createElement("input");
-  toggleEl.classList.add("bytm-toggle");
   toggleEl.type = "checkbox";
   toggleEl.checked = initialValue;
+  toggleEl.dataset.toggled = String(Boolean(initialValue));
   toggleEl.tabIndex = -1;
   if(id)
     toggleEl.id = `bytm-toggle-${id}`;
 
+  const toggleKnobEl = document.createElement("div");
+  toggleKnobEl.classList.add("bytm-toggle-knob");
+  toggleKnobEl.innerHTML = " ";
+
   const toggleElClicked = (e: Event) => {
     e.preventDefault();
     e.stopPropagation();
 
     onChange(toggleEl.checked);
-    if(labelEl)
-      labelEl.textContent = wrapperEl.ariaValueText = t(`toggled_${toggleEl.checked ? "on" : "off"}`);
+    toggleEl.dataset.toggled = String(Boolean(toggleEl.checked));
   };
 
   toggleEl.addEventListener("change", toggleElClicked);
@@ -59,8 +65,11 @@ export async function createToggle({
     }
   });
 
+  toggleEl.appendChild(toggleKnobEl);
+  toggleWrapperEl.appendChild(toggleEl);
+
   labelEl && labelPos === "left" && wrapperEl.appendChild(labelEl);
-  wrapperEl.appendChild(toggleEl);
+  wrapperEl.appendChild(toggleWrapperEl);
   labelEl && labelPos === "right" && wrapperEl.appendChild(labelEl);
 
   return wrapperEl;

+ 6 - 6
src/tools/post-build.ts

@@ -23,6 +23,12 @@ type RequireObjPkg = {
   path?: string;
 };
 
+type BuildStats = {
+  sizeKiB: number;
+  mode: string;
+  timestamp: number;
+};
+
 const buildTs = Date.now();
 /** Used to force the browser and userscript extension to refresh resources */
 const buildUuid = randomUUID();
@@ -61,12 +67,6 @@ const scriptUrl = (() => {
 /** Whether to trigger the bell sound in some terminals when the code has finished compiling */
 const ringBell = Boolean(env.RING_BELL && (env.RING_BELL.length > 0 && env.RING_BELL.trim().toLowerCase() === "true"));
 
-type BuildStats = {
-  sizeKiB: number;
-  mode: string;
-  timestamp: number;
-};
-
 /** Directives that are only added in dev mode */
 const devDirectives = mode === "development" ? `\
 // @grant             GM.registerMenuCommand