[Resolved] Is it possible to fire ‘generate_element_display’ using wp.hooks?

Home Forums Support [Resolved] Is it possible to fire ‘generate_element_display’ using wp.hooks?

Home Forums Support Is it possible to fire ‘generate_element_display’ using wp.hooks?

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • #2174616
    Lewis

    Hi there,

    I know you can use generate_element_display to bypass the Display Rules, so we can enable or disable an Element under our own conditions. as per the doc’s (GP Doc’s Link).

    For Example;

    add_filter( 'generate_element_display', function( $display, $element_id ) {
        if ( 100 === $element_id && is_author( 'Tom' ) ) {
            $display = true;
        }
    
        return $display;
    }, 10, 2 );

    However, I would like to know if it is possible to fire this filter using js with the addFilter( 'hookName', 'namespace', callback, priority )? as per the Block Editor Handbook? (Block Editor Handbook Link to addFilter()).

    My reason for asking is I would like to fire a display filter based on a <select></select> element managed by javascript.

    If this is possible it might be worth noting the doc’s. πŸ™‚

    Thanks.

    #2174937
    Tom
    Lead Developer
    Lead Developer

    Hi there,

    Are you wanting to programmatically set the Display Rules in the editor based on another value? So it would actually alter the values in the Display Rules section?

    If so, this likely isn’t possible at the moment as the Display Rules section isn’t built in React/JS. Once we port it over to React, it will likely be possible to do something like this.

    Let me know πŸ™‚

    #2174955
    Lewis

    Hey Tom,

    Some more context might be useful, my bad.xD

    I’ve spent the last couple of days building a colour theme toggle for my site. You can see the fruits of my labour here (jsFiddle).

    I then went about creating some hooks using the elements feature, my goal here was to load the required css :root {} media query conditionally or vice versa load the various :root {} rules conditionally as it would be more appropriate.
    [url=https://ibb.co/QpHnV9x][img]https://i.ibb.co/PFW4yxV/Screenshot-2022-04-01-at-20-01-27.png[/img][/url]

    Most of my thoughts are just theories at the moment. I was hoping to call the hooks conditionally within my js switch case using the wp.hooks approach.

    David provided an awesome tid-bit here that sparked my curiosity as to whether I could achieve a toggle rather than an automatic switch.

    An exact example of what I’m trying to reproduce can be found here. (You can find the theme toggle in their footer.)

    There are a few different approaches I can likely still take but I don’t want to override GP’s colour settings by prefixing my css with h1.dark-mode {} I’d much rather go the var route as highlighted by David.

    #2175309
    David
    Staff
    Customer Support

    Hi there,

    i would do something like this:

    1. Create a JS script to toggle a class on button click:

    <script>
    var html = document.querySelector('html');
    var dmtoggle = document.querySelector('.dm-toggle');
    
    dmtoggle.onclick = function() {
        html.classList.toggle('dark-mode');
        dmtoggle.classList.toggle('active');
    }
    </script>

    2, add your button/toggle with the dm-toggle class eg.

    <button class="dm-toggle">Dark Mode</button>

    3. Now on click that should toggle the dark-mode class on the root HTML element. So your Darkmode CSS would be:

    :root.dark-mode {
        --contrast: var(--dm-contrast);
        --contrast-2: var(--dm-contrast-2);
        --contrast-3: var(--dm-contrast-3);
        --base: var(--dm-base);
        --base-2: var(--dm-base-2);
        --base-3: var(--dm-base-3);
        --accent: var(--dm-accent);
    }
    #2179091
    Lewis

    Hi David,

    I didn’t even think about prefixing the root via the HTML tag. Pure genius!πŸ‘Œ

    I hope you don’t mind but I tweaked your button version to a dropdown version. You can see the fruits of my labour here, bonus points, my solution uses local storage to remember a users previous set schema too! Feel free to tweak and distribute if you fancy it.

    Thanks again for the top notch support. πŸ‘

    #2179669
    David
    Staff
    Customer Support

    Thats awesome – i like your approach to the localStorage handling . very nice πŸ˜‰ Thanks for sharing that!

    #2494868
    Chris

    Hey there, just re-opening this thread.

    I’ve applied the JS

    <script>
    var html = document.querySelector('html');
    var dmtoggle = document.querySelector('.dm-toggle');
    
    dmtoggle.onclick = function() {
        html.classList.toggle('dark-mode');
        dmtoggle.classList.toggle('active');
    }
    </script>

    And applied the CSS

    :root.dark-mode {
        --contrast: var(--dm-contrast);
        --contrast-2: var(--dm-contrast-2);
        --contrast-3: var(--dm-contrast-3);
        --base: var(--dm-base);
        --base-2: var(--dm-base-2);
        --base-3: var(--dm-base-3);
        --accent: var(--dm-accent);
    }

    I’ve also added a CSS class of ‘dm-toggle’ to a button. The dark theme gets enabled on click, however when I load a new page it switches back to the standard theme. How can I modify the JS to retain the user’s selection of ‘dark-mode’ ???

    #2494935
    Chris

    I would like to replicate a similar dark-mode option such as this website – https://websiteipsum.com/

    #2495476
    David
    Staff
    Customer Support

    Did you see the link that Beaniie provided here:

    https://generatepress.com/forums/topic/is-it-possible-to-fire-generate_element_display-using-wp-hooks/#post-2179091

    As it has the localStorage JS required to remember the users decision

    #2496776
    Chris

    Hi David,

    Yes I’m trying to figure out how to implement that user’s solution – https://jsfiddle.net/Beaniie/opgy6Lu1/209/

    I’ve implemented it using WP hooks for the HTML and JS on my site, however I’m confused with the CSS that’s been supplied…

    body {
      padding: 0;
      margin: 0;
      font-family: sans-serif;
      font-weight: 300;
      background: var(--background-primary);
    }
    
    :root {
      /* system schema */
      --background-primary: #f8f8f8;
      --background-secondary: #c0c0c0;
      --border-primary: #808080;
      --text-primary: #000;
    
      /* light mode schema */
      --lm-background-primary: #f8f8f8;
      --lm-background-secondary: #c0c0c0;
      --lm-border-primary: #808080;
      --lm-text-primary: #000;
    
      /* dark mode schema */
      --dm-background-primary: #000;
      --dm-background-secondary: #101010;
      --dm-border-primary: #404040;
      --dm-text-primary: #fff;
    }
    
    /* automatic dark mode */
    @media (prefers-color-scheme: dark) {
      :root {
        /* dark mode schema */
        --background-primary: var(--dm-background-primary);
        --background-secondary: var(--dm-background-secondary);
        --border-primary: var(--dm-border-primary);
        --text-primary: var(--dm-text-primary);
      }
    }
    
    /* automatic dark mode */
    @media (prefers-color-scheme: light) {
      :root {
        /* dark mode schema */
        --background-primary: var(--lm-background-primary);
        --background-secondary: var(--lm-background-secondary);
        --border-primary: var(--lm-border-primary);
        --text-primary: var(--lm-text-primary);
      }
    }
    
    .box {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100vh;
      max-width: 400px;
      margin: 0 auto;
    }
    
    .box .inner {
      text-align: center;
      width: 500px;
      color: var(--text-primary);
      background: var(--background-secondary);
      padding: 1rem;
      border-radius: 4.33px;
      border: 1px dashed var(--border-primary);
    }
    
    .box .inner p {
      margin-bottom: 1rem;
    }
    
    .box .inner select {
      margin-bottom: 0.75rem;
    }

    How is it meant to target the selected light/dark schema based on the Javascript..

    document.addEventListener("DOMContentLoaded", function(event) {
      // Check for preference or previous setting.
      checkUserPreference();
    });
    
    // Get the select element.
    const selectEle = document.getElementById('selectSchema');
    
    // Watch the select element for change.
    selectEle.addEventListener('change', function() {
      themeSchemaSetting();
    });
    
    // Check for user preference.
    function checkUserPreference() {
    
      // Check to see if storage is set if not initialise.
      if (!localStorage.hasOwnProperty('currentSchema')) {
        const prefersDarkSchema = window.matchMedia("(prefers-color-scheme: dark)");
        const prefersLightSchema = window.matchMedia("(prefers-color-scheme: light)");
    
        // If user preference detected set system schema, else set light schema.
        if (prefersDarkSchema.matches || prefersLightSchema.matches) {
          selectEle.selectedIndex = 0; // Set system in select.
        } else {
          selectEle.selectedIndex = 2; // Set light in select.
        }
      }
      // Set the schema.
      themeSchemaSetting();
    }
    
    // Set the schema.
    function themeSchemaSetting(currentSchema) {
    
      // Set & retreive local storage.
      selectValue = selectEle.value;
      localStorage.setItem('currentSchema', selectValue);
      currentSchema = localStorage.getItem('currentSchema');
    
      // debug log
      console.log("Select Value:", selectValue);
      console.log("Storage Schema:", currentSchema);
    
      // set theme based on set storage
      switch (currentSchema) {
        case 'systemSchema':
          // set light schema.
          console.log("Theme is system.");
          break;
        case 'lightSchema':
          // set dark schema.
          console.log("Theme is Light.");
          break;
        case 'darkSchema':
          // let the system decide.
          console.log("Theme is Dark.");
          break;
        default:
          // default schema developer preference.
          console.log("Theme is default. (Light)");
      }
    }

    What modifications should be made to the CSS in order to operate properly?

    Any help is greatly appreciated..

    #2496780
    Chris

    I’ve also added the HTML for the toggle dropdown on my site on another hook element

    <div class="box">
      <div class="inner">
        <!-- css colour mode select -->
        <div class="theme-switcher">
          <label for="selectSchema">
            <div class="select_container">
    
              <!-- select element -->
              <select class="select select-small" id="selectSchema" aria-label="Change color theme">
                <option value="systemSchema">System</option>
                <option value="lightSchema">Light</option>
                <option value="darkSchema">Dark</option>
              </select>
    
            </div>
          </label>
        </div>
      </div>
    </div>
    #2496848
    Chris

    All good, I managed to get it to function correctly with this solution – https://dev.to/ananyaneogi/create-a-dark-light-mode-switch-with-css-variables-34l8

    #2497245
    David
    Staff
    Customer Support

    Glad to hear you got it working, and thanks for sharing the additional resource

    #darkmode options

Viewing 13 posts - 1 through 13 (of 13 total)
  • You must be logged in to reply to this topic.