Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Idea/v9] Redesign the plugin system #411

Open
idiotWu opened this issue Nov 1, 2021 Discussed in #393 · 0 comments
Open

[Idea/v9] Redesign the plugin system #411

idiotWu opened this issue Nov 1, 2021 Discussed in #393 · 0 comments
Assignees
Labels
accepted Feature requests that have been accepted. idea plugin system
Projects
Milestone

Comments

@idiotWu
Copy link
Owner

idiotWu commented Nov 1, 2021

Discussed in #393

Originally posted by idiotWu October 19, 2021

Motivation

The plugin system in smooth-scrollbar@8 is great, but it lacks flexibility due to the declarative configurations. For example, the following code is quite common when using the overscroll plugin:

// enable the plugin globally
Scrollbar.use(OverscrollPlugin);

// turn it on
const s1 = Scrollbar.init(elem, {
  plugins: {
    overscroll: {
      effect: 'bounce',
      // add scrolling listener
      onScroll(position) {
        // do something
      },
    },
  },
});

// turn it off on another scrollbar
const s2 = Scrollbar.init(anotherElem, {
  plugins: {
    overscroll: false,
  },
});

// switch the overscroll effect on the first scrollbar
s1.updatePluginOptions('overscroll', {
  effect: 'glow',
});

So far so good, huh? But what if we want to turn off the overscroll plugin on s1? Or if we want to add more listeners to the plugin? The current design just doesn't allow you to do so.

// turn of the plugin? ❌
s1.updatePluginOptions('overscroll', false); 

// add more listeners? ❌
s1.updatePluginOptions('overscroll', {
  onScroll() {
    // ...
  },
}); 

Besides, the current plugin system requires you to add a static member pluginName to identify the plugin, otherwise you can not change the plugin options later:

class MyPlugin extends ScrollbarPlugin {
  // why should I do this stupid stuff???
  static pluginName = 'myPlugin';
}

Proposal

In the next major release, I'd like to redesign the plugin system so that we can use it more programmatically. Instead of passing a bunch of options, we can use the new operator to construct plugins, for example:

// init the plugin
const overscrollPlugin = new OverscrollPlugin({
  effect: 'bounce',
});

// init the scrollbar (we may also remove the unnecessary `Scrollbar.init()` method in the next version)
const scrollbar = new Scrollbar(elem, {
  plugins: [overscrollPlugin, /* others... */]
});

// attach listeners
overscrollPlugin.addListener((position) => {
  // do something
});

// switch overscroll effect
overscrollPlugin.setEffect('glow');

// disable the plugin...
overscrollPlugin.disable();

// ...and re-enable it
overscrollPlugin.enable();

Interface

class ScrollbarPlugin {
  enabled = true;

  #scrollbar: Scrollbar;

  // will be called when scrollbar initializes
  init(s: Scrollbar) {
    this.#scrollbar = s;
  }

  enable() {
    this.enabled = true;
  }

  disable() {
    this.enabled = false;
  }

  onInit() {}
  onDestroy() {}

  onUpdate() {}
  onRender(remainMomentum: Vec2) {}

  transformDelta(delta: Vec2, evt: Event): Vec2 {
    return { ...delta };
  }
}
@idiotWu idiotWu added plugin system idea accepted Feature requests that have been accepted. labels Nov 1, 2021
@idiotWu idiotWu added this to the v9 milestone Nov 1, 2021
@idiotWu idiotWu self-assigned this Nov 1, 2021
@idiotWu idiotWu added this to IDEA in v9 Nov 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted Feature requests that have been accepted. idea plugin system
Projects
v9
IDEA
Development

No branches or pull requests

1 participant