jelgblad / angular2-masonry

https://github.com/desandro/masonry module for Angular2
101 stars 48 forks source link

Support for other frameworks that only system js #5

Closed Naliath closed 8 years ago

Naliath commented 8 years ago

It seems completely reliant on systemjs atm. It would be much more community friendly if a more neutral approach was taken

xeor commented 8 years ago

I'm getting this error when trying to load this using webpac. @Naliath any luck on a solution?

WARNING in ./~/angular2-masonry/angular2-masonry.js
Cannot find source file 'angular2-masonry.ts': Error: Cannot resolve 'file' or 'directory' ./angular2-masonry.ts in /.../node_modules/angular2-masonry

WARNING in ./~/angular2-masonry/index.js
Cannot find source file 'index.ts': Error: Cannot resolve 'file' or 'directory' ./index.ts in /.../node_modules/angular2-masonry

I wonder if maybe https://webpack.github.io/docs/configuration.html#resolve-alias could be a solution here. But I haven't gotten it to work yet..

Naliath commented 8 years ago

I did not bother trying to get the npm package to work after my initial issue and pulled in the source and included that (I was already working in ts so no need to add anything extra to my webpack settings). Unfortunately the angular directives in this package dit not help my situation and seemed to be buggy. So I went back to directly accessing Masonry.

The issue I was hoping to fix was my angular directives are changing the content of their cards and as a result I need to let masonry know that the height is changed and as a result it might need to reorder the cards so they don't overlap. So far I have not found a clean overarching way to handle this so now I simply have a Masonry service that has an initialize method that gets called from my app component. The components that subsequently change the card content include this service and then trigger the relayout (or whatever it's called) on the masonry object wrapped in the service.

xeor commented 8 years ago

Thanks for the update @Naliath . I'll probably going with the source as well then :) I saw the index.ts file, and it's a little annoying it isn't bundled in the npm. I'm glad you got it to work, at least the basics.

I don't think your solution is that bad, while we wait for "thinks" to mature.. It would be painful in angular 1 tho..

Naliath commented 8 years ago

Still trying to figure out a way for angular to send me an event based on a dom change in a generic way. Basically what I need is if the card is resized trigger and event so I can relayout the whole UI. Unfortunately from what I have been reading there is no such thing in javascript

jelgblad commented 8 years ago

Hi! I haven't tried this with any other framework/module loader than SystemJS. The reason for that is simply because the project I'm currently working on that uses angular2-masonry is built on SystemJS. The typescript is compiled to CommonJS, so it should be compatible with most loaders. @xeor is your issue that webpack needs the .ts-source?

I will of course try to make it as community compatible as possible, when I get the time to do so!

xeor commented 8 years ago

@jelgblad Based on what @Naliath said, I think that is all thats needed. It was complaining a lot about a missing index.ts file. I havent gottent the time to try it out yet tho..

xeor commented 8 years ago

@jelgblad looks like copying in all the .ts files solved the problem, working on next problem now getting it to find masonry-layout plugin.. @Naliath did you have a solution here? Or did you do everything from source not using this library at all?

xeor commented 8 years ago

Strange.. I can get a little bit further with some webpack magic, but I am stuck at the same problem as https://forums.meteor.com/t/unable-to-resolve-masonry-in-meteor-1-3/24606

The error

ERROR in ./~/masonry-layout/dist/masonry.pkgd.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./item in /.../node_modules/masonry-layout/dist
 @ ./~/masonry-layout/dist/masonry.pkgd.js 1351:6-23

The relavant webpack config to get there;

module.exports = {
  resolve: {
    alias: {
      'masonry-layout': 'masonry-layout/dist/masonry.pkgd.js',
    },
  },
  module: {
    loaders: [
      {
        test: /masonry-layout/,
        loader: 'imports?define=>false&this=>window'
      }
    ]
  }
}

Any ideas?

Naliath commented 8 years ago

I did this, created a masonry-layout.d.ts:

interface MasonryFactory {
    new (options?: MasonryOptions): Masonry;
    new (selector: string, options?: MasonryOptions): Masonry;
}

interface Masonry {
    masonry?(): void;
    masonry?(callback: string, handler: any): void;

    // Layout
    layout?(): void;
    layoutItems?(items: Array<any>, isStill?: boolean): void;
    stamp?(elements: Array<any>): void;
    unstamp?(elements: Array<any>): void;

    // Add and Remove Items
    appended?(elements: Array<any>): void;
    prepended?(elements: Array<any>): void;
    addItems?(elements: Array<any>): void;
    remove?(elements: Array<any>): void;

    // Events
    on?(callback: string, handler: any): void;
    off?(callback: string, handler: any): void;
    once?(callback: string, handler: any): void;

    // Utilities
    reloadItems?(): void;
    destroy?(): void;
    getItemElements?(): Array<any>;
    data?(element: Element): Masonry;
}

interface MasonryOptions {
    // Layout
    itemSelector?: string;
    columnWidth?: any;
    percentPosition?: boolean;
    gutter?: any;
    stamp?: string;
    fitWidth?: boolean;
    originLeft?: boolean;
    originTop?: boolean;

    // Setup
    containerStyle?: Object;
    transitionDuration?: any;
    resize?: boolean;
    initLayout?: boolean;
}

and a require like so: var Masonry = require('masonry-layout') as MasonryFactory;

Naliath commented 8 years ago

seems like some typescript / webpack resolution issues, it's funny how some libraries have so many issues and others just work

jelgblad commented 8 years ago

@xeor @Naliath I've published a new version (0.0.20) on npm that includes all the source .ts-files. This should solve part of your problem. I'll have to get into webpack before i can help you with the second part I think...

Naliath commented 8 years ago

I ended up using my own implementation against the base library. Needed more controle for change detection, currently using http://marcj.github.io/css-element-queries/ : ResizeSensor to monitor my bricks for changes, might be an interesting feature to add to your library (could be enabled with a parameter or something).

xeor commented 8 years ago

@jelgblad thanks! 👍

I have a couple of other problems with my codebase atm (updated too many npm packages at the same time :( ), but I will report back if I figure out a good way on problem 2.

xeor commented 8 years ago

This is driving me nuts...

I have posted an issue on the upstream masonry repo, and a question on stackoverflow... Hope we can find an elegant solution.

xeor commented 8 years ago

@jelgblad If I change the masonry.ts file like;

//import * as masonry from 'masonry-layout';
var Masonry = require('masonry-layout');

and used this to initialize it;

//this._msnry = new masonry.default(this._element.nativeElement, this.options);
this._msnry = new Masonry(this._element.nativeElement, this.options);

it works... Any reason you changed this out? Any way it can autodetect what it needs?

zaikin-andrew commented 8 years ago

Thanks for update to rc5. What about this question? @xeor's method works.

jelgblad commented 8 years ago

@zaikin-andrew In 0.1.0 I removed the .default and it seems to work. I don't remember exactly why i included it... About other framework/bundlers i really don't know what's needed. It's written with typescript module-syntax, so the compiler should compile to whatever typescript-supported module loader you want.

zaikin-andrew commented 8 years ago

I use angular-cli with webpack and have an issue.

ERROR in [default] ...project/node_modules/angular2-masonry/src/masonry.ts:3:25 Cannot find module 'masonry-layout'.

Probably the problem is that masonry-layout has not .d.ts file.

If I change

//import * as masonry from 'masonry-layout'; to var masonry = require('masonry-layout');

I have this one: Module not found: Error: Can't resolve './masonry_options' The reason is wrong "_". import { MasonryOptions } from './masonry_options'; move to import { MasonryOptions } from './masonry-options'; and it works well.

jelgblad commented 8 years ago

@zaikin-andrew OK! I got the same error when i tried webpack. import * as masonry from 'masonry-layout'; actually transpiles to var masonry = require('masonry-layout'); so its should work anyway. But i really don't know how webpack works...

masonry_options is a typo. I'll fix it and publish a new release in a few minutes.

jelgblad commented 8 years ago

I think https://github.com/jelgblad/angular2-masonry/commit/8400247a2811151bfe3b94881b804827594c789e will do the trick. Try to update to 0.1.1, i got it to work with webpack.

zaikin-andrew commented 8 years ago

@jelgblad Thank you so much! It works fine :)