marcj / css-element-queries

CSS Element-Queries aka Container Queries. High-speed element dimension/media queries in valid css.
http://marcj.github.io/css-element-queries/
MIT License
4.27k stars 487 forks source link

can't import properly in typescript #263

Closed gregveres closed 4 years ago

gregveres commented 5 years ago

what import statement do we need to get ResizeSensor imported into typescript when using the ResizeSensor.d.ts file that comes with the package?

When I use import ResizeSensor from 'css-element-queries/src/ResizeSensor';

the TS compiler translates: new ResizeSensor(element, cb); to new ResizeSensor_1.default(element, cb)

I have tried all the forms of import I know about but I haven't been able to get TS to generate the proper call.

Any suggestions? Thanks

gregveres commented 5 years ago

OK. I think that the ResizeSensor.d.ts is wrong. I could not find an import statement coupled with a new statement for the class that would work. So I started reading this section of the typescript documentation: Declaration Files

specifically this page has a section on how to build a definition file for a UMD modules (which I believe ResizeSensor is).

It shows that the client code should look like this:

var x = require("bar"); // Note: using 'new' operator on the imported variable var y = new x("hello");

And that the definition file should follow the module-class.d.ts template.

most of the existing ResizeSensor.d.ts file follows that template, except for the final export. Right now the final export is:

export default ResizeSensor;

but it should be

export = ResizeSensor

Once I changed the file to use the export = line, I was able to get TS to generate the correct code to call the constructor for ResizeSensor.

Could we get a new version with that changed? I am not really setup to create a PR, or I would do that.

gregveres commented 5 years ago

I am back again. Importing this into TS is messy.

I am sure that there is some combination of TS options that allow the supplied defintion file to properly import the module and use it from TS. I don't know what they are though.

What I provided above works great when the TS options are:

with these options you have to use export = ResizeSensor in the .d.ts file and you import with: import ResizeSensor = require('...');

but due to some other features I want to use, I had to change my TS options to:

with these options, I had to go back to the supplied .d.ts file (with the export default ResizeSensor) and modify it to export the class. Here is my the .d.ts file I am using now:

export declare type ResizeSensorCallback = (size: { width: number; height: number; }) => void;

export declare class ResizeSensor {
    constructor(element: Element | Element[], callback: ResizeSensorCallback);
    detach(callback?: ResizeSensorCallback): void;
    reset(): void;

    static detach(element: Element | Element[], callback?: ResizeSensorCallback): void;
    static reset(element: Element | Element[]): void;
}

export default ResizeSensor;

But I also had to modify the source code slightly to get the module to return an object that TS was expecting.

I had to change the final return statement to return an object with ResizeSensor in it rather than return the function. It now looks like:

return {
    ResizeSensor
};

I should also mention that I am using webpack to bundle this up as that might be changing the import handling in some way I am unaware of. But with this source modification and the supplied .d.ts file, I am now able to do this:

import { ResizeSensor } from 'Libs/css-element-queries/ResizeSensor';
let sensor = new ResizeSensor($container[0], determineBounds);

What happens in the underlying JS code is that the module that is imported now contains an object with the ResizeSensor constructor function in it. The new ResizeSensor call is converted into module.ResizeSensor(), which is why the return needed to be an object rather than the actual function.

I suspect this messes up use in the global space so I am not suggesting a change in any way. I am just recording this so somebody else running into the issue can benefit from my effort.

I guess if you did change the return as I pointed out above, you could keep the existing CommonJS and global variable behaviour by changing the UMD template to look like this:

(function (root, factory) {
    if (typeof define === "function" && define.amd) {
        define([], factory);
    } else if (typeof exports === "object") {
        module.exports = factory().ResizeSensor;
    } else {
        root.ResizeSensor = factory().ResizeSensor;
    }
binu101 commented 5 years ago

My temp fix for now is just require the JS source file:

const sensor = require('css-element-queries/src/ResizeSensor.js');

// setup the sensor
this.sensor = new sensor(this.element.nativeElement, (event: ResizeSensorEvent) => {});

But I would like to see the d.ts file updated to properly use the TS definition.

marcj commented 5 years ago

Works here fine using import { ResizeSensor } from 'css-element-queries';.

https://github.com/vdolek/angular-resize-event/blob/6e2a58a6305005e093d682d0dec2bc9995c3ade4/projects/angular-resize-event/src/lib/resized.directive.ts#L2

stephenlautier commented 5 years ago

@marcj its used there but it doesnt mean its working fine. Typings for css-element-queries doesnt seem to be working fine.

After installing this to an almost empty project this is what i get

image

Just skimming at this project typings, it doesnt seems to be exported correctly, should be quite easy to fix if you would like a PR

marcj commented 5 years ago

Sure, woud love to get one👍

Sent from my iPhone

On 8. May 2019, at 14:21, Stephen Lautier notifications@github.com wrote:

@marcj its used there but it doesnt mean its working fine. Typings for css-element-queries doesnt seem to be working fine.

After installing this to an almost empty project this is what i get

Just skimming at this project typings, it doesnt seems to be exported correctly, should be quite easy to fix if you would like a PR

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

stephenlautier commented 5 years ago

PR https://github.com/marcj/css-element-queries/pull/266