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

Vue 3? #16

Open
hykilpikonna opened this issue Nov 12, 2021 · 6 comments
Open

Vue 3? #16

hykilpikonna opened this issue Nov 12, 2021 · 6 comments

Comments

@hykilpikonna
Copy link

When will this update to vue 3? And for typescript support?

@reinerBa
Copy link
Owner

You can code a pull request :)

@reinerBa
Copy link
Owner

@hykilpikonna I am working on it. Why do you don't tell me that i only need on script for ts support...
like described here https://stackoverflow.com/a/58066522/6355502 with some addition from the help site https://www.typescriptlang.org/docs/handbook/compiler-options.html

@hykilpikonna
Copy link
Author

@hykilpikonna I am working on it. Why do you don't tell me that i only need on script for ts support... like described here https://stackoverflow.com/a/58066522/6355502 with some addition from the help site https://www.typescriptlang.org/docs/handbook/compiler-options.html

Thank you so much!

Sorry, I didn't know you can generate TS declarations with a script.

@reinerBa
Copy link
Owner

The IDE gives warnings only because there is no d.ts file. Now i have generated a d.ts file which exports a function full of any-types and the warning pasts away lol .

The most plugins authors create new repositories for there plugins when they change them to be vu3-compatible. I want to serve both versions with one package. That makes the thing so complex.

@reinerBa
Copy link
Owner

@hykilpikonna Here is the first prototype that works with vue3 54e18ee

@trajano
Copy link

trajano commented Apr 6, 2023

I did a simplistic one based on your code, except I had more complicated logic for determining the size so I made it a function

import { App, ObjectDirective } from "vue";
import { RectToClass } from "./RectToClass";
import { PluginOptions } from "./PluginOptions";
export type { RectToClass };
const updateClassesForElement = (
  element: Element,
  rect: DOMRect,
  elToFunctionMap: Map<Element, RectToClass>,
  possibleClasses: string[]
) => {
  const fn = elToFunctionMap.get(element);
  if (!fn) {
    throw new Error(
      `The element id=${element.id} does not have a rect to class function asssociated.`
    );
  }
  const responsiveClass = fn(rect);
  if (responsiveClass !== null) {
    element.classList.add(responsiveClass);
  }
  possibleClasses
    .filter((c) => c !== responsiveClass)
    .forEach((c) => element.classList.remove(c));
};
export default {
  install: (app: App, options: PluginOptions) => {
    const elToFunctionMap = new Map<Element, RectToClass>();

    const resizeObserver = new ResizeObserver((entries) => {
      entries
        .filter((entry) => elToFunctionMap.has(entry.target))
        .forEach((entry) => {
          const element = entry.target;
          const rect = entry.contentRect;
          updateClassesForElement(
            element,
            rect,
            elToFunctionMap,
            options.classes
          );
        });
    });
    const vResponsive: ObjectDirective<Element, RectToClass> = {
      mounted: (el, binding) => {
        // reregister hook after update
        elToFunctionMap.set(el, binding.value);
        updateClassesForElement(
          el,
          el.getBoundingClientRect(),
          elToFunctionMap,
          options.classes
        );
        resizeObserver.observe(el);
      },
      beforeUpdate: (el) => {
        // deregister the element before update
        resizeObserver.unobserve(el);
      },
      updated: (el, binding) => {
        // reregister hook after update
        elToFunctionMap.set(el, binding.value);
        updateClassesForElement(
          el,
          el.getBoundingClientRect(),
          elToFunctionMap,
          options.classes
        );
        resizeObserver.observe(el);
      },
      beforeUnmount: (el) => {
        // deregister the element before unmount
        resizeObserver.unobserve(el);
        elToFunctionMap.delete(el);
      },
    };

    app.directive("responsive", vResponsive);
    app.mixin({
      beforeUnmount: () => {
        resizeObserver.disconnect();
      },
    });
  },
};
export interface PluginOptions {
    /**
     * List of classes that would be applied.
     */
    classes: string[];
}
export type RectToClass = (rect: DOMRect) => string | null;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants