chunk-032-font-size.js

I’ll build this as a standalone advanced font-size controller chunk for RX Theme: CSS-variable based, accessible controls, localStorage memory, responsive scaling, keyboard shortcuts, and safe WordPress-friendly behavior.

My dear friend, for this file:

assets/static-js/static-chunks-js/chunk-032-font-size.js

you can use it as an advanced RX Theme font-size system. It will support:

Global font scale, article font scale, accessibility buttons, keyboard shortcuts, localStorage saving, CSS variables, reset system, responsive limits, WordPress body class support, and automatic UI creation.

/*!
 * RX Theme - Chunk 032 Font Size Controller
 * File: assets/static-js/static-chunks-js/chunk-032-font-size.js
 * Version: 1.0.0
 * Author: RxHarun
 *
 * Purpose:
 * Advanced font-size accessibility system for RX Theme.
 */

(function () {
  'use strict';

  /**
   * ------------------------------------------------------------
   * RX Font Size Config
   * ------------------------------------------------------------
   */
  const RX_FONT_SIZE_CONFIG = {
    storageKey: 'rx_theme_font_size_settings_v1',

    selectors: {
      root: document.documentElement,
      body: document.body,
      article: '.entry-content, .post-content, .rx-article-content, article',
      readableText:
        'p, li, blockquote, dd, dt, figcaption, .entry-content, .post-content, .rx-article-content',
      headings: 'h1, h2, h3, h4, h5, h6',
      ignore:
        '.rx-font-size-panel, .rx-font-size-panel *, script, style, noscript, svg, canvas',
    },

    cssVars: {
      globalScale: '--rx-font-global-scale',
      articleScale: '--rx-font-article-scale',
      lineHeightScale: '--rx-line-height-scale',
      letterSpacingScale: '--rx-letter-spacing-scale',
    },

    defaults: {
      globalScale: 1,
      articleScale: 1,
      lineHeightScale: 1,
      letterSpacingScale: 0,
      mode: 'normal',
      panelEnabled: true,
    },

    limits: {
      min: 0.85,
      max: 1.35,
      articleMin: 0.9,
      articleMax: 1.5,
      step: 0.05,
    },

    classes: {
      initialized: 'rx-font-size-ready',
      large: 'rx-font-large',
      extraLarge: 'rx-font-extra-large',
      small: 'rx-font-small',
      readingMode: 'rx-reading-font-mode',
      dyslexiaMode: 'rx-dyslexia-friendly-mode',
    },

    keyboard: {
      increase: '+',
      decrease: '-',
      reset: '0',
    },
  };

  /**
   * ------------------------------------------------------------
   * Safe Helper Functions
   * ------------------------------------------------------------
   */
  const RXFontSizeHelper = {
    clamp(value, min, max) {
      return Math.min(Math.max(value, min), max);
    },

    round(value) {
      return Math.round(value * 100) / 100;
    },

    isElement(value) {
      return value instanceof Element || value instanceof HTMLDocument;
    },

    getStorage() {
      try {
        const raw = localStorage.getItem(RX_FONT_SIZE_CONFIG.storageKey);
        if (!raw) return null;
        return JSON.parse(raw);
      } catch (error) {
        return null;
      }
    },

    setStorage(data) {
      try {
        localStorage.setItem(
          RX_FONT_SIZE_CONFIG.storageKey,
          JSON.stringify(data)
        );
      } catch (error) {
        // localStorage may be blocked. Silently fail.
      }
    },

    removeStorage() {
      try {
        localStorage.removeItem(RX_FONT_SIZE_CONFIG.storageKey);
      } catch (error) {
        // Silently fail.
      }
    },

    createElement(tag, className, text) {
      const el = document.createElement(tag);

      if (className) {
        el.className = className;
      }

      if (typeof text === 'string') {
        el.textContent = text;
      }

      return el;
    },

    debounce(callback, delay) {
      let timer = null;

      return function debouncedFunction() {
        const context = this;
        const args = arguments;

        clearTimeout(timer);

        timer = setTimeout(function () {
          callback.apply(context, args);
        }, delay);
      };
    },

    prefersReducedMotion() {
      return window.matchMedia &&
        window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    },
  };

  /**
   * ------------------------------------------------------------
   * Main RX Font Size Controller
   * ------------------------------------------------------------
   */
  const RXFontSizeController = {
    state: {
      globalScale: RX_FONT_SIZE_CONFIG.defaults.globalScale,
      articleScale: RX_FONT_SIZE_CONFIG.defaults.articleScale,
      lineHeightScale: RX_FONT_SIZE_CONFIG.defaults.lineHeightScale,
      letterSpacingScale: RX_FONT_SIZE_CONFIG.defaults.letterSpacingScale,
      mode: RX_FONT_SIZE_CONFIG.defaults.mode,
      panelEnabled: RX_FONT_SIZE_CONFIG.defaults.panelEnabled,
      initialized: false,
    },

    init() {
      if (this.state.initialized) return;

      this.loadSavedSettings();
      this.injectBaseStyles();
      this.applySettings();
      this.createPanel();
      this.bindEvents();
      this.observeDynamicContent();

      document.documentElement.classList.add(
        RX_FONT_SIZE_CONFIG.classes.initialized
      );

      this.state.initialized = true;

      window.RXFontSizeController = this;
    },

    loadSavedSettings() {
      const saved = RXFontSizeHelper.getStorage();

      if (!saved || typeof saved !== 'object') {
        return;
      }

      this.state.globalScale =
        typeof saved.globalScale === 'number'
          ? RXFontSizeHelper.clamp(
              saved.globalScale,
              RX_FONT_SIZE_CONFIG.limits.min,
              RX_FONT_SIZE_CONFIG.limits.max
            )
          : RX_FONT_SIZE_CONFIG.defaults.globalScale;

      this.state.articleScale =
        typeof saved.articleScale === 'number'
          ? RXFontSizeHelper.clamp(
              saved.articleScale,
              RX_FONT_SIZE_CONFIG.limits.articleMin,
              RX_FONT_SIZE_CONFIG.limits.articleMax
            )
          : RX_FONT_SIZE_CONFIG.defaults.articleScale;

      this.state.lineHeightScale =
        typeof saved.lineHeightScale === 'number'
          ? RXFontSizeHelper.clamp(saved.lineHeightScale, 0.95, 1.25)
          : RX_FONT_SIZE_CONFIG.defaults.lineHeightScale;

      this.state.letterSpacingScale =
        typeof saved.letterSpacingScale === 'number'
          ? RXFontSizeHelper.clamp(saved.letterSpacingScale, 0, 0.08)
          : RX_FONT_SIZE_CONFIG.defaults.letterSpacingScale;

      this.state.mode =
        typeof saved.mode === 'string'
          ? saved.mode
          : RX_FONT_SIZE_CONFIG.defaults.mode;

      this.state.panelEnabled =
        typeof saved.panelEnabled === 'boolean'
          ? saved.panelEnabled
          : RX_FONT_SIZE_CONFIG.defaults.panelEnabled;
    },

    saveSettings() {
      RXFontSizeHelper.setStorage({
        globalScale: this.state.globalScale,
        articleScale: this.state.articleScale,
        lineHeightScale: this.state.lineHeightScale,
        letterSpacingScale: this.state.letterSpacingScale,
        mode: this.state.mode,
        panelEnabled: this.state.panelEnabled,
      });
    },

    applySettings() {
      const root = RX_FONT_SIZE_CONFIG.selectors.root;
      const body = RX_FONT_SIZE_CONFIG.selectors.body;

      root.style.setProperty(
        RX_FONT_SIZE_CONFIG.cssVars.globalScale,
        String(this.state.globalScale)
      );

      root.style.setProperty(
        RX_FONT_SIZE_CONFIG.cssVars.articleScale,
        String(this.state.articleScale)
      );

      root.style.setProperty(
        RX_FONT_SIZE_CONFIG.cssVars.lineHeightScale,
        String(this.state.lineHeightScale)
      );

      root.style.setProperty(
        RX_FONT_SIZE_CONFIG.cssVars.letterSpacingScale,
        `${this.state.letterSpacingScale}em`
      );

      body.classList.remove(
        RX_FONT_SIZE_CONFIG.classes.small,
        RX_FONT_SIZE_CONFIG.classes.large,
        RX_FONT_SIZE_CONFIG.classes.extraLarge,
        RX_FONT_SIZE_CONFIG.classes.readingMode,
        RX_FONT_SIZE_CONFIG.classes.dyslexiaMode
      );

      if (this.state.globalScale < 1) {
        body.classList.add(RX_FONT_SIZE_CONFIG.classes.small);
      }

      if (this.state.globalScale >= 1.1) {
        body.classList.add(RX_FONT_SIZE_CONFIG.classes.large);
      }

      if (this.state.globalScale >= 1.25) {
        body.classList.add(RX_FONT_SIZE_CONFIG.classes.extraLarge);
      }

      if (this.state.mode === 'reading') {
        body.classList.add(RX_FONT_SIZE_CONFIG.classes.readingMode);
      }

      if (this.state.mode === 'dyslexia') {
        body.classList.add(RX_FONT_SIZE_CONFIG.classes.dyslexiaMode);
      }

      this.updatePanelStatus();
      this.saveSettings();

      window.dispatchEvent(
        new CustomEvent('rxFontSizeChanged', {
          detail: {
            globalScale: this.state.globalScale,
            articleScale: this.state.articleScale,
            lineHeightScale: this.state.lineHeightScale,
            letterSpacingScale: this.state.letterSpacingScale,
            mode: this.state.mode,
          },
        })
      );
    },

    injectBaseStyles() {
      if (document.getElementById('rx-font-size-dynamic-style')) {
        return;
      }

      const style = document.createElement('style');
      style.id = 'rx-font-size-dynamic-style';

      style.textContent = `
        :root {
          --rx-font-global-scale: 1;
          --rx-font-article-scale: 1;
          --rx-line-height-scale: 1;
          --rx-letter-spacing-scale: 0em;
        }

        html.rx-font-size-ready body {
          font-size: calc(100% * var(--rx-font-global-scale));
        }

        html.rx-font-size-ready .entry-content,
        html.rx-font-size-ready .post-content,
        html.rx-font-size-ready .rx-article-content,
        html.rx-font-size-ready article {
          font-size: calc(1rem * var(--rx-article-scale));
          line-height: calc(1.65 * var(--rx-line-height-scale));
          letter-spacing: var(--rx-letter-spacing-scale);
        }

        html.rx-font-size-ready .entry-content p,
        html.rx-font-size-ready .post-content p,
        html.rx-font-size-ready .rx-article-content p,
        html.rx-font-size-ready article p,
        html.rx-font-size-ready .entry-content li,
        html.rx-font-size-ready .post-content li,
        html.rx-font-size-ready .rx-article-content li,
        html.rx-font-size-ready article li {
          line-height: calc(1.7 * var(--rx-line-height-scale));
          letter-spacing: var(--rx-letter-spacing-scale);
        }

        body.rx-reading-font-mode .entry-content,
        body.rx-reading-font-mode .post-content,
        body.rx-reading-font-mode .rx-article-content,
        body.rx-reading-font-mode article {
          max-width: 760px;
          margin-left: auto;
          margin-right: auto;
        }

        body.rx-dyslexia-friendly-mode .entry-content,
        body.rx-dyslexia-friendly-mode .post-content,
        body.rx-dyslexia-friendly-mode .rx-article-content,
        body.rx-dyslexia-friendly-mode article {
          letter-spacing: 0.04em;
          word-spacing: 0.08em;
          line-height: 1.85;
        }

        .rx-font-size-panel {
          position: fixed;
          right: 18px;
          bottom: 18px;
          z-index: 99998;
          display: flex;
          flex-direction: column;
          gap: 8px;
          width: 210px;
          padding: 12px;
          border-radius: 16px;
          background: rgba(255, 255, 255, 0.96);
          color: #111827;
          border: 1px solid rgba(15, 23, 42, 0.12);
          box-shadow: 0 12px 35px rgba(15, 23, 42, 0.18);
          font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
          font-size: 14px;
          line-height: 1.4;
          backdrop-filter: blur(12px);
        }

        .rx-font-size-panel[hidden] {
          display: none !important;
        }

        .rx-font-size-panel__title {
          font-weight: 700;
          font-size: 14px;
          margin: 0 0 4px;
        }

        .rx-font-size-panel__row {
          display: flex;
          gap: 6px;
          align-items: center;
          justify-content: space-between;
        }

        .rx-font-size-panel__button {
          appearance: none;
          border: 1px solid rgba(15, 23, 42, 0.16);
          background: #f8fafc;
          color: #0f172a;
          border-radius: 10px;
          padding: 7px 9px;
          min-width: 38px;
          font-weight: 700;
          cursor: pointer;
          transition: transform 0.18s ease, background 0.18s ease;
        }

        .rx-font-size-panel__button:hover {
          background: #e5e7eb;
          transform: translateY(-1px);
        }

        .rx-font-size-panel__button:focus-visible {
          outline: 3px solid rgba(37, 99, 235, 0.35);
          outline-offset: 2px;
        }

        .rx-font-size-panel__button.is-active {
          background: #0f172a;
          color: #ffffff;
        }

        .rx-font-size-panel__value {
          min-width: 48px;
          text-align: center;
          font-weight: 700;
          color: #334155;
        }

        .rx-font-size-panel__range {
          width: 100%;
        }

        .rx-font-size-panel__small {
          font-size: 12px;
          color: #475569;
        }

        .rx-font-size-panel__toggle {
          position: fixed;
          right: 18px;
          bottom: 18px;
          z-index: 99999;
          width: 46px;
          height: 46px;
          border-radius: 999px;
          border: 1px solid rgba(15, 23, 42, 0.16);
          background: #0f172a;
          color: #ffffff;
          font-weight: 800;
          cursor: pointer;
          box-shadow: 0 10px 25px rgba(15, 23, 42, 0.25);
        }

        .rx-font-size-panel:not([hidden]) + .rx-font-size-panel__toggle {
          bottom: 250px;
        }

        @media (prefers-color-scheme: dark) {
          .rx-font-size-panel {
            background: rgba(15, 23, 42, 0.96);
            color: #f8fafc;
            border-color: rgba(255, 255, 255, 0.16);
          }

          .rx-font-size-panel__button {
            background: #1e293b;
            color: #f8fafc;
            border-color: rgba(255, 255, 255, 0.16);
          }

          .rx-font-size-panel__button:hover {
            background: #334155;
          }

          .rx-font-size-panel__value,
          .rx-font-size-panel__small {
            color: #cbd5e1;
          }
        }

        @media (max-width: 600px) {
          .rx-font-size-panel {
            left: 12px;
            right: 12px;
            bottom: 12px;
            width: auto;
          }

          .rx-font-size-panel__toggle {
            right: 12px;
            bottom: 12px;
          }

          .rx-font-size-panel:not([hidden]) + .rx-font-size-panel__toggle {
            bottom: 250px;
          }
        }

        @media (prefers-reduced-motion: reduce) {
          .rx-font-size-panel__button {
            transition: none;
          }

          .rx-font-size-panel__button:hover {
            transform: none;
          }
        }

        @media print {
          .rx-font-size-panel,
          .rx-font-size-panel__toggle {
            display: none !important;
          }
        }
      `;

      document.head.appendChild(style);
    },

    createPanel() {
      if (document.querySelector('.rx-font-size-panel')) {
        return;
      }

      const panel = RXFontSizeHelper.createElement(
        'div',
        'rx-font-size-panel'
      );

      panel.setAttribute('role', 'region');
      panel.setAttribute('aria-label', 'Font size accessibility controls');

      if (!this.state.panelEnabled) {
        panel.hidden = true;
      }

      const title = RXFontSizeHelper.createElement(
        'p',
        'rx-font-size-panel__title',
        'Reading Font Size'
      );

      const globalRow = RXFontSizeHelper.createElement(
        'div',
        'rx-font-size-panel__row'
      );

      const decreaseButton = this.createButton('A-', 'Decrease global font size');
      decreaseButton.dataset.rxFontAction = 'decrease-global';

      const globalValue = RXFontSizeHelper.createElement(
        'span',
        'rx-font-size-panel__value'
      );
      globalValue.dataset.rxFontValue = 'global';

      const increaseButton = this.createButton('A+', 'Increase global font size');
      increaseButton.dataset.rxFontAction = 'increase-global';

      globalRow.appendChild(decreaseButton);
      globalRow.appendChild(globalValue);
      globalRow.appendChild(increaseButton);

      const articleRow = RXFontSizeHelper.createElement(
        'div',
        'rx-font-size-panel__row'
      );

      const articleDecrease = this.createButton(
        'Text-',
        'Decrease article font size'
      );
      articleDecrease.dataset.rxFontAction = 'decrease-article';

      const articleValue = RXFontSizeHelper.createElement(
        'span',
        'rx-font-size-panel__value'
      );
      articleValue.dataset.rxFontValue = 'article';

      const articleIncrease = this.createButton(
        'Text+',
        'Increase article font size'
      );
      articleIncrease.dataset.rxFontAction = 'increase-article';

      articleRow.appendChild(articleDecrease);
      articleRow.appendChild(articleValue);
      articleRow.appendChild(articleIncrease);

      const modeRow = RXFontSizeHelper.createElement(
        'div',
        'rx-font-size-panel__row'
      );

      const normalButton = this.createButton('Normal', 'Normal reading mode');
      normalButton.dataset.rxFontAction = 'mode-normal';

      const readingButton = this.createButton('Reader', 'Comfort reading mode');
      readingButton.dataset.rxFontAction = 'mode-reading';

      const dyslexiaButton = this.createButton(
        'Wide',
        'Wide spacing reading mode'
      );
      dyslexiaButton.dataset.rxFontAction = 'mode-dyslexia';

      modeRow.appendChild(normalButton);
      modeRow.appendChild(readingButton);
      modeRow.appendChild(dyslexiaButton);

      const lineRow = RXFontSizeHelper.createElement(
        'div',
        'rx-font-size-panel__row'
      );

      const lineDecrease = this.createButton('LH-', 'Decrease line height');
      lineDecrease.dataset.rxFontAction = 'decrease-line-height';

      const lineValue = RXFontSizeHelper.createElement(
        'span',
        'rx-font-size-panel__value'
      );
      lineValue.dataset.rxFontValue = 'lineHeight';

      const lineIncrease = this.createButton('LH+', 'Increase line height');
      lineIncrease.dataset.rxFontAction = 'increase-line-height';

      lineRow.appendChild(lineDecrease);
      lineRow.appendChild(lineValue);
      lineRow.appendChild(lineIncrease);

      const resetRow = RXFontSizeHelper.createElement(
        'div',
        'rx-font-size-panel__row'
      );

      const resetButton = this.createButton('Reset', 'Reset font size settings');
      resetButton.dataset.rxFontAction = 'reset';

      const closeButton = this.createButton('Hide', 'Hide font size panel');
      closeButton.dataset.rxFontAction = 'hide-panel';

      resetRow.appendChild(resetButton);
      resetRow.appendChild(closeButton);

      const help = RXFontSizeHelper.createElement(
        'p',
        'rx-font-size-panel__small',
        'Shortcut: Alt + + / Alt + - / Alt + 0'
      );

      panel.appendChild(title);
      panel.appendChild(globalRow);
      panel.appendChild(articleRow);
      panel.appendChild(lineRow);
      panel.appendChild(modeRow);
      panel.appendChild(resetRow);
      panel.appendChild(help);

      const toggle = RXFontSizeHelper.createElement(
        'button',
        'rx-font-size-panel__toggle',
        'A'
      );

      toggle.type = 'button';
      toggle.setAttribute('aria-label', 'Toggle font size controls');
      toggle.dataset.rxFontAction = 'toggle-panel';

      document.body.appendChild(panel);
      document.body.appendChild(toggle);

      this.updatePanelStatus();
    },

    createButton(text, label) {
      const button = RXFontSizeHelper.createElement(
        'button',
        'rx-font-size-panel__button',
        text
      );

      button.type = 'button';
      button.setAttribute('aria-label', label);

      return button;
    },

    bindEvents() {
      document.addEventListener('click', (event) => {
        const button = event.target.closest('[data-rx-font-action]');

        if (!button) {
          return;
        }

        const action = button.dataset.rxFontAction;
        this.handleAction(action);
      });

      document.addEventListener('keydown', (event) => {
        this.handleKeyboard(event);
      });

      window.addEventListener(
        'resize',
        RXFontSizeHelper.debounce(() => {
          this.applyResponsiveSafety();
        }, 200)
      );

      window.addEventListener('rxThemeResetAccessibility', () => {
        this.reset();
      });
    },

    handleAction(action) {
      switch (action) {
        case 'increase-global':
          this.increaseGlobal();
          break;

        case 'decrease-global':
          this.decreaseGlobal();
          break;

        case 'increase-article':
          this.increaseArticle();
          break;

        case 'decrease-article':
          this.decreaseArticle();
          break;

        case 'increase-line-height':
          this.increaseLineHeight();
          break;

        case 'decrease-line-height':
          this.decreaseLineHeight();
          break;

        case 'mode-normal':
          this.setMode('normal');
          break;

        case 'mode-reading':
          this.setMode('reading');
          break;

        case 'mode-dyslexia':
          this.setMode('dyslexia');
          break;

        case 'reset':
          this.reset();
          break;

        case 'hide-panel':
          this.hidePanel();
          break;

        case 'toggle-panel':
          this.togglePanel();
          break;

        default:
          break;
      }
    },

    handleKeyboard(event) {
      if (!event.altKey) {
        return;
      }

      const key = event.key;

      if (key === '+' || key === '=') {
        event.preventDefault();
        this.increaseGlobal();
      }

      if (key === '-' || key === '_') {
        event.preventDefault();
        this.decreaseGlobal();
      }

      if (key === '0') {
        event.preventDefault();
        this.reset();
      }
    },

    increaseGlobal() {
      this.state.globalScale = RXFontSizeHelper.round(
        RXFontSizeHelper.clamp(
          this.state.globalScale + RX_FONT_SIZE_CONFIG.limits.step,
          RX_FONT_SIZE_CONFIG.limits.min,
          RX_FONT_SIZE_CONFIG.limits.max
        )
      );

      this.applySettings();
    },

    decreaseGlobal() {
      this.state.globalScale = RXFontSizeHelper.round(
        RXFontSizeHelper.clamp(
          this.state.globalScale - RX_FONT_SIZE_CONFIG.limits.step,
          RX_FONT_SIZE_CONFIG.limits.min,
          RX_FONT_SIZE_CONFIG.limits.max
        )
      );

      this.applySettings();
    },

    increaseArticle() {
      this.state.articleScale = RXFontSizeHelper.round(
        RXFontSizeHelper.clamp(
          this.state.articleScale + RX_FONT_SIZE_CONFIG.limits.step,
          RX_FONT_SIZE_CONFIG.limits.articleMin,
          RX_FONT_SIZE_CONFIG.limits.articleMax
        )
      );

      this.applySettings();
    },

    decreaseArticle() {
      this.state.articleScale = RXFontSizeHelper.round(
        RXFontSizeHelper.clamp(
          this.state.articleScale - RX_FONT_SIZE_CONFIG.limits.step,
          RX_FONT_SIZE_CONFIG.limits.articleMin,
          RX_FONT_SIZE_CONFIG.limits.articleMax
        )
      );

      this.applySettings();
    },

    increaseLineHeight() {
      this.state.lineHeightScale = RXFontSizeHelper.round(
        RXFontSizeHelper.clamp(this.state.lineHeightScale + 0.05, 0.95, 1.25)
      );

      this.applySettings();
    },

    decreaseLineHeight() {
      this.state.lineHeightScale = RXFontSizeHelper.round(
        RXFontSizeHelper.clamp(this.state.lineHeightScale - 0.05, 0.95, 1.25)
      );

      this.applySettings();
    },

    setMode(mode) {
      const allowedModes = ['normal', 'reading', 'dyslexia'];

      if (!allowedModes.includes(mode)) {
        mode = 'normal';
      }

      this.state.mode = mode;

      if (mode === 'dyslexia') {
        this.state.letterSpacingScale = 0.04;
        this.state.lineHeightScale = Math.max(this.state.lineHeightScale, 1.12);
      }

      if (mode === 'normal') {
        this.state.letterSpacingScale = 0;
      }

      this.applySettings();
    },

    reset() {
      this.state.globalScale = RX_FONT_SIZE_CONFIG.defaults.globalScale;
      this.state.articleScale = RX_FONT_SIZE_CONFIG.defaults.articleScale;
      this.state.lineHeightScale = RX_FONT_SIZE_CONFIG.defaults.lineHeightScale;
      this.state.letterSpacingScale =
        RX_FONT_SIZE_CONFIG.defaults.letterSpacingScale;
      this.state.mode = RX_FONT_SIZE_CONFIG.defaults.mode;
      this.state.panelEnabled = RX_FONT_SIZE_CONFIG.defaults.panelEnabled;

      RXFontSizeHelper.removeStorage();
      this.applySettings();
      this.showPanel();
    },

    hidePanel() {
      const panel = document.querySelector('.rx-font-size-panel');

      if (panel) {
        panel.hidden = true;
      }

      this.state.panelEnabled = false;
      this.saveSettings();
    },

    showPanel() {
      const panel = document.querySelector('.rx-font-size-panel');

      if (panel) {
        panel.hidden = false;
      }

      this.state.panelEnabled = true;
      this.saveSettings();
    },

    togglePanel() {
      const panel = document.querySelector('.rx-font-size-panel');

      if (!panel) {
        return;
      }

      if (panel.hidden) {
        this.showPanel();
      } else {
        this.hidePanel();
      }
    },

    updatePanelStatus() {
      const globalValue = document.querySelector('[data-rx-font-value="global"]');
      const articleValue = document.querySelector(
        '[data-rx-font-value="article"]'
      );
      const lineValue = document.querySelector(
        '[data-rx-font-value="lineHeight"]'
      );

      if (globalValue) {
        globalValue.textContent = `${Math.round(this.state.globalScale * 100)}%`;
      }

      if (articleValue) {
        articleValue.textContent = `${Math.round(
          this.state.articleScale * 100
        )}%`;
      }

      if (lineValue) {
        lineValue.textContent = `${Math.round(
          this.state.lineHeightScale * 100
        )}%`;
      }

      const modeButtons = document.querySelectorAll(
        '[data-rx-font-action^="mode-"]'
      );

      modeButtons.forEach((button) => {
        button.classList.remove('is-active');

        if (button.dataset.rxFontAction === `mode-${this.state.mode}`) {
          button.classList.add('is-active');
        }
      });
    },

    applyResponsiveSafety() {
      const viewportWidth = window.innerWidth;

      if (viewportWidth < 360 && this.state.globalScale > 1.2) {
        this.state.globalScale = 1.2;
        this.applySettings();
      }
    },

    observeDynamicContent() {
      if (!('MutationObserver' in window)) {
        return;
      }

      const observer = new MutationObserver(
        RXFontSizeHelper.debounce(() => {
          this.refreshReadableContent();
        }, 150)
      );

      observer.observe(document.body, {
        childList: true,
        subtree: true,
      });
    },

    refreshReadableContent() {
      const articleSelectors = RX_FONT_SIZE_CONFIG.selectors.article;
      const articles = document.querySelectorAll(articleSelectors);

      articles.forEach((article) => {
        if (!RXFontSizeHelper.isElement(article)) {
          return;
        }

        article.dataset.rxFontSizeObserved = 'true';
      });
    },

    /**
     * Public API
     * Example:
     * window.RXFontSizeController.setGlobalScale(1.15);
     */
    setGlobalScale(value) {
      if (typeof value !== 'number') {
        return;
      }

      this.state.globalScale = RXFontSizeHelper.round(
        RXFontSizeHelper.clamp(
          value,
          RX_FONT_SIZE_CONFIG.limits.min,
          RX_FONT_SIZE_CONFIG.limits.max
        )
      );

      this.applySettings();
    },

    setArticleScale(value) {
      if (typeof value !== 'number') {
        return;
      }

      this.state.articleScale = RXFontSizeHelper.round(
        RXFontSizeHelper.clamp(
          value,
          RX_FONT_SIZE_CONFIG.limits.articleMin,
          RX_FONT_SIZE_CONFIG.limits.articleMax
        )
      );

      this.applySettings();
    },

    getSettings() {
      return {
        globalScale: this.state.globalScale,
        articleScale: this.state.articleScale,
        lineHeightScale: this.state.lineHeightScale,
        letterSpacingScale: this.state.letterSpacingScale,
        mode: this.state.mode,
        panelEnabled: this.state.panelEnabled,
      };
    },
  };

  /**
   * ------------------------------------------------------------
   * Init Safely
   * ------------------------------------------------------------
   */
  function rxInitFontSizeController() {
    if (!document.body) {
      return;
    }

    RXFontSizeController.init();
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', rxInitFontSizeController);
  } else {
    rxInitFontSizeController();
  }
})();

How to enqueue this file in RX Theme

In your functions.php or better in:

inc/core/enqueue.php

add:

function rx_theme_enqueue_font_size_chunk() {
    wp_enqueue_script(
        'rx-font-size-chunk',
        get_template_directory_uri() . '/assets/static-js/static-chunks-js/chunk-032-font-size.js',
        array(),
        wp_get_theme()->get( 'Version' ),
        true
    );
}
add_action( 'wp_enqueue_scripts', 'rx_theme_enqueue_font_size_chunk' );

Best naming idea

Your file name is already good:

chunk-032-font-size.js

For advanced RX Theme, this is even more clear:

chunk-032-accessibility-font-size.js

But if you already created many chunks by number, keep your current name. It is clean and understandable.

Leave a Reply

Your email address will not be published. Required fields are marked *